blob: d084758b746d070df5ca4d20f2b8a542e88d226d [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 }
Veerendranath Jakkamfc5b7d22022-04-15 02:12:12 +05301292
1293 dut->dhcp_client_running = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001294#endif /* __linux__ */
1295}
1296
1297
1298static int start_dhcp_client(struct sigma_dut *dut, const char *ifname)
1299{
1300#ifdef __linux__
1301 char buf[200];
1302
1303#ifdef ANDROID
Purushottam Kushwaha46d64262016-08-23 17:57:53 +05301304 if (access("/system/bin/dhcpcd", F_OK) != -1) {
1305 snprintf(buf, sizeof(buf),
1306 "/system/bin/dhcpcd -b %s", ifname);
1307 } else if (access("/system/bin/dhcptool", F_OK) != -1) {
1308 snprintf(buf, sizeof(buf), "/system/bin/dhcptool %s &", ifname);
Ankita Bajaj8454e5d2019-04-05 16:04:55 +05301309 } else if (access("/vendor/bin/dhcpcd", F_OK) != -1) {
1310 snprintf(buf, sizeof(buf), "/vendor/bin/dhcpcd -b %s", ifname);
1311 } else if (access("/vendor/bin/dhcptool", F_OK) != -1) {
1312 snprintf(buf, sizeof(buf), "/vendor/bin/dhcptool %s", ifname);
Purushottam Kushwaha46d64262016-08-23 17:57:53 +05301313 } else {
1314 sigma_dut_print(dut, DUT_MSG_ERROR,
1315 "DHCP client program missing");
1316 return 0;
1317 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001318#else /* ANDROID */
1319 snprintf(buf, sizeof(buf),
1320 "dhclient -nw -pf /var/run/dhclient-%s.pid %s",
1321 ifname, ifname);
1322#endif /* ANDROID */
1323 sigma_dut_print(dut, DUT_MSG_INFO, "Start DHCP client: %s", buf);
1324 if (system(buf) != 0) {
1325 snprintf(buf, sizeof(buf), "dhcpcd -t 0 %s &", ifname);
1326 if (system(buf) != 0) {
1327 sigma_dut_print(dut, DUT_MSG_INFO,
1328 "Failed to start DHCP client");
1329#ifndef ANDROID
1330 return -1;
1331#endif /* ANDROID */
1332 }
1333 }
Veerendranath Jakkamfc5b7d22022-04-15 02:12:12 +05301334
1335 dut->dhcp_client_running = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001336#endif /* __linux__ */
1337
1338 return 0;
1339}
1340
1341
1342static int clear_ip_addr(struct sigma_dut *dut, const char *ifname)
1343{
1344#ifdef __linux__
1345 char buf[200];
1346
1347 snprintf(buf, sizeof(buf), "ip addr flush dev %s", ifname);
1348 if (system(buf) != 0) {
1349 sigma_dut_print(dut, DUT_MSG_INFO,
1350 "Failed to clear IP addresses");
1351 return -1;
1352 }
1353#endif /* __linux__ */
1354
1355 return 0;
1356}
1357
1358
1359#ifdef ANDROID
1360static int add_ipv6_rule(struct sigma_dut *dut, const char *ifname)
1361{
1362 char cmd[200], *result, *pos;
1363 FILE *fp;
Pradeep Reddy POTTETIf58a1fe2016-10-13 17:22:03 +05301364 int tableid;
1365 size_t len, result_len = 1000;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001366
1367 snprintf(cmd, sizeof(cmd), "ip -6 route list table all | grep %s",
1368 ifname);
1369 fp = popen(cmd, "r");
1370 if (fp == NULL)
1371 return -1;
1372
1373 result = malloc(result_len);
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05301374 if (result == NULL) {
1375 fclose(fp);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001376 return -1;
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05301377 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001378
Pradeep Reddy POTTETIf58a1fe2016-10-13 17:22:03 +05301379 len = fread(result, 1, result_len - 1, fp);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001380 fclose(fp);
1381
1382 if (len == 0) {
1383 free(result);
1384 return -1;
1385 }
Pradeep Reddy POTTETIf58a1fe2016-10-13 17:22:03 +05301386 result[len] = '\0';
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001387
1388 pos = strstr(result, "table ");
1389 if (pos == NULL) {
1390 free(result);
1391 return -1;
1392 }
1393
1394 pos += strlen("table ");
1395 tableid = atoi(pos);
1396 if (tableid != 0) {
1397 if (system("ip -6 rule del prio 22000") != 0) {
1398 /* ignore any error */
1399 }
1400 snprintf(cmd, sizeof(cmd),
1401 "ip -6 rule add from all lookup %d prio 22000",
1402 tableid);
1403 if (system(cmd) != 0) {
1404 sigma_dut_print(dut, DUT_MSG_INFO,
1405 "Failed to run %s", cmd);
1406 free(result);
1407 return -1;
1408 }
1409 } else {
1410 sigma_dut_print(dut, DUT_MSG_INFO,
1411 "No Valid Table Id found %s", pos);
1412 free(result);
1413 return -1;
1414 }
1415 free(result);
1416
1417 return 0;
1418}
1419#endif /* ANDROID */
1420
1421
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301422int set_ipv4_addr(struct sigma_dut *dut, const char *ifname,
1423 const char *ip, const char *mask)
1424{
1425 char buf[200];
1426
1427 snprintf(buf, sizeof(buf), "ifconfig %s %s netmask %s",
1428 ifname, ip, mask);
1429 return system(buf) == 0;
1430}
1431
1432
1433int set_ipv4_gw(struct sigma_dut *dut, const char *gw)
1434{
1435 char buf[200];
1436
1437 if (!is_ip_addr(gw)) {
1438 sigma_dut_print(dut, DUT_MSG_DEBUG, "Invalid gw addr - %s", gw);
1439 return -1;
1440 }
1441
1442 snprintf(buf, sizeof(buf), "route add default gw %s", gw);
1443 if (!dut->no_ip_addr_set && system(buf) != 0) {
1444 snprintf(buf, sizeof(buf), "ip ro re default via %s",
1445 gw);
1446 if (system(buf) != 0)
1447 return 0;
1448 }
1449
1450 return 1;
1451}
1452
1453
Jouni Malinenf7222712019-06-13 01:50:21 +03001454static enum sigma_cmd_result cmd_sta_set_ip_config(struct sigma_dut *dut,
1455 struct sigma_conn *conn,
1456 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001457{
1458 const char *intf = get_param(cmd, "Interface");
1459 const char *ifname;
1460 char buf[200];
1461 const char *val, *ip, *mask, *gw;
1462 int type = 1;
1463
1464 if (intf == NULL)
1465 return -1;
1466
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001467 if (strcmp(intf, get_main_ifname(dut)) == 0)
1468 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001469 else
1470 ifname = intf;
1471
1472 if (if_nametoindex(ifname) == 0) {
1473 send_resp(dut, conn, SIGMA_ERROR,
1474 "ErrorCode,Unknown interface");
1475 return 0;
1476 }
1477
1478 val = get_param(cmd, "Type");
1479 if (val) {
1480 type = atoi(val);
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301481 if (type < 1 || type > 3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001482 send_resp(dut, conn, SIGMA_ERROR,
1483 "ErrorCode,Unsupported address type");
1484 return 0;
1485 }
1486 }
1487
1488 dut->last_set_ip_config_ipv6 = 0;
1489
1490 val = get_param(cmd, "dhcp");
1491 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "true") == 0)) {
1492 static_ip_file(0, NULL, NULL, NULL);
1493#ifdef __linux__
1494 if (type == 2) {
1495 dut->last_set_ip_config_ipv6 = 1;
1496 sigma_dut_print(dut, DUT_MSG_INFO, "Using IPv6 "
1497 "stateless address autoconfiguration");
1498#ifdef ANDROID
Hu Wang8fd144d2021-12-29 17:07:45 +08001499 snprintf(buf, sizeof(buf),
1500 "sysctl net.ipv6.conf.%s.disable_ipv6=0",
1501 ifname);
1502 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
1503 if (system(buf) != 0) {
1504 sigma_dut_print(dut, DUT_MSG_DEBUG,
1505 "Failed to enable IPv6 address");
1506 }
1507
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001508 /*
1509 * This sleep is required as the assignment in case of
1510 * Android is taking time and is done by the kernel.
1511 * The subsequent ping for IPv6 is impacting HS20 test
1512 * case.
1513 */
1514 sleep(2);
1515 add_ipv6_rule(dut, intf);
1516#endif /* ANDROID */
1517 /* Assume this happens by default */
1518 return 1;
1519 }
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301520 if (type != 3) {
1521 kill_dhcp_client(dut, ifname);
1522 if (start_dhcp_client(dut, ifname) < 0)
1523 return -2;
1524 } else {
1525 sigma_dut_print(dut, DUT_MSG_DEBUG,
1526 "Using FILS HLP DHCPv4 Rapid Commit");
1527 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001528
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001529 return 1;
1530#endif /* __linux__ */
1531 return -2;
1532 }
1533
1534 ip = get_param(cmd, "ip");
Pradeep Reddy POTTETIb18c5652016-01-18 12:45:37 +05301535 if (!ip) {
1536 send_resp(dut, conn, SIGMA_INVALID,
1537 "ErrorCode,Missing IP address");
1538 return 0;
1539 }
1540
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001541 mask = get_param(cmd, "mask");
Pradeep Reddy POTTETIb18c5652016-01-18 12:45:37 +05301542 if (!mask) {
1543 send_resp(dut, conn, SIGMA_INVALID,
1544 "ErrorCode,Missing subnet mask");
1545 return 0;
1546 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001547
1548 if (type == 2) {
1549 int net = atoi(mask);
1550
1551 if ((net < 0 && net > 64) || !is_ipv6_addr(ip))
1552 return -1;
1553
1554 if (dut->no_ip_addr_set) {
1555 snprintf(buf, sizeof(buf),
1556 "sysctl net.ipv6.conf.%s.disable_ipv6=1",
1557 ifname);
1558 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
1559 if (system(buf) != 0) {
1560 sigma_dut_print(dut, DUT_MSG_DEBUG,
1561 "Failed to disable IPv6 address before association");
1562 }
1563 } else {
Veerendranath Jakkam176181c2020-05-16 00:19:21 +05301564 if (set_ipv6_addr(dut, ip, mask, ifname) != 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001565 send_resp(dut, conn, SIGMA_ERROR,
1566 "ErrorCode,Failed to set IPv6 address");
1567 return 0;
1568 }
1569 }
1570
1571 dut->last_set_ip_config_ipv6 = 1;
1572 static_ip_file(6, ip, mask, NULL);
1573 return 1;
1574 } else if (type == 1) {
Pradeep Reddy POTTETIb18c5652016-01-18 12:45:37 +05301575 if (!is_ip_addr(ip) || !is_ip_addr(mask))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001576 return -1;
1577 }
1578
1579 kill_dhcp_client(dut, ifname);
1580
1581 if (!dut->no_ip_addr_set) {
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301582 if (!set_ipv4_addr(dut, ifname, ip, mask)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001583 send_resp(dut, conn, SIGMA_ERROR,
1584 "ErrorCode,Failed to set IP address");
1585 return 0;
1586 }
1587 }
1588
1589 gw = get_param(cmd, "defaultGateway");
1590 if (gw) {
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301591 if (set_ipv4_gw(dut, gw) < 1) {
1592 send_resp(dut, conn, SIGMA_ERROR,
1593 "ErrorCode,Failed to set default gateway");
1594 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001595 }
1596 }
1597
1598 val = get_param(cmd, "primary-dns");
1599 if (val) {
Vinita S. Maloo069e8d42021-04-29 13:15:08 +05301600#ifdef ANDROID
Shivani Baranwal31182012021-12-07 21:11:13 +05301601 char dns_cmd[200];
1602 int len;
1603 char dnsmasq[100];
1604
1605 kill_pid(dut, concat_sigma_tmpdir(dut, "/sigma_dut-dnsmasq.pid",
1606 dnsmasq, sizeof(dnsmasq)));
1607
1608 len = snprintf(dns_cmd, sizeof(dns_cmd),
1609 "/system/bin/dnsmasq -uroot --no-resolv -S%s -x/%s", val,
1610 dnsmasq);
1611 if (len < 0 || len >= sizeof(dns_cmd))
1612 return ERROR_SEND_STATUS;
1613 sigma_dut_print(dut, DUT_MSG_DEBUG, "Running %s", dns_cmd);
1614 if (system(dns_cmd) != 0) {
1615 send_resp(dut, conn, SIGMA_ERROR,
1616 "ErrorCode,Failed to set primary-dns");
1617 return STATUS_SENT_ERROR;
1618 }
Vinita S. Maloo069e8d42021-04-29 13:15:08 +05301619#else /* ANDROID */
1620 char dns_cmd[200];
1621 int len;
1622
1623 if (system("sed -i '/nameserver/d' /etc/resolv.conf") != 0) {
1624 sigma_dut_print(dut, DUT_MSG_ERROR,
1625 "Failed to clear nameserver entries in /etc/resolv.conf");
1626 return ERROR_SEND_STATUS;
1627 }
1628
1629 len = snprintf(dns_cmd, sizeof(dns_cmd),
1630 "sed -i '1 i nameserver %s' /etc/resolv.conf", val);
1631 if (len < 0 || len >= sizeof(dns_cmd))
1632 return ERROR_SEND_STATUS;
1633
1634 sigma_dut_print(dut, DUT_MSG_DEBUG, "Running %s", dns_cmd);
1635 if (system(dns_cmd) != 0) {
1636 send_resp(dut, conn, SIGMA_ERROR,
1637 "ErrorCode,Failed to set primary-dns");
1638 return STATUS_SENT_ERROR;
1639 }
1640#endif /* ANDROID */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001641 }
1642
1643 val = get_param(cmd, "secondary-dns");
1644 if (val) {
1645 /* TODO */
1646 sigma_dut_print(dut, DUT_MSG_INFO, "Ignored secondary-dns %s "
1647 "setting", val);
1648 }
1649
1650 static_ip_file(4, ip, mask, gw);
1651
1652 return 1;
1653}
1654
1655
Jouni Malinenf7222712019-06-13 01:50:21 +03001656static enum sigma_cmd_result cmd_sta_get_info(struct sigma_dut *dut,
1657 struct sigma_conn *conn,
1658 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001659{
1660 /* const char *intf = get_param(cmd, "Interface"); */
1661 /* TODO: could report more details here */
1662 send_resp(dut, conn, SIGMA_COMPLETE, "vendor,Atheros");
1663 return 0;
1664}
1665
1666
Jouni Malinenf7222712019-06-13 01:50:21 +03001667static enum sigma_cmd_result cmd_sta_get_mac_address(struct sigma_dut *dut,
1668 struct sigma_conn *conn,
1669 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001670{
1671 /* const char *intf = get_param(cmd, "Interface"); */
1672 char addr[20], resp[50];
1673
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05301674 if (dut->dev_role == DEVROLE_STA_CFON)
1675 return sta_cfon_get_mac_address(dut, conn, cmd);
1676
Jouni Malinen9540e012019-11-05 17:08:42 +02001677 start_sta_mode(dut);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001678 if (get_wpa_status(get_station_ifname(dut), "address",
1679 addr, sizeof(addr)) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001680 return -2;
1681
1682 snprintf(resp, sizeof(resp), "mac,%s", addr);
1683 send_resp(dut, conn, SIGMA_COMPLETE, resp);
1684 return 0;
1685}
1686
1687
Jouni Malinenf7222712019-06-13 01:50:21 +03001688static enum sigma_cmd_result cmd_sta_is_connected(struct sigma_dut *dut,
1689 struct sigma_conn *conn,
1690 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001691{
1692 /* const char *intf = get_param(cmd, "Interface"); */
1693 int connected = 0;
1694 char result[32];
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001695 if (get_wpa_status(get_station_ifname(dut), "wpa_state", result,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001696 sizeof(result)) < 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001697 sigma_dut_print(dut, DUT_MSG_INFO,
1698 "Could not get interface %s status",
1699 get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001700 return -2;
1701 }
1702
1703 sigma_dut_print(dut, DUT_MSG_DEBUG, "wpa_state=%s", result);
1704 if (strncmp(result, "COMPLETED", 9) == 0)
1705 connected = 1;
1706
1707 if (connected)
1708 send_resp(dut, conn, SIGMA_COMPLETE, "connected,1");
1709 else
1710 send_resp(dut, conn, SIGMA_COMPLETE, "connected,0");
1711
1712 return 0;
1713}
1714
1715
Jouni Malinenf7222712019-06-13 01:50:21 +03001716static enum sigma_cmd_result
1717cmd_sta_verify_ip_connection(struct sigma_dut *dut, struct sigma_conn *conn,
1718 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001719{
1720 /* const char *intf = get_param(cmd, "Interface"); */
1721 const char *dst, *timeout;
1722 int wait_time = 90;
1723 char buf[100];
1724 int res;
1725
1726 dst = get_param(cmd, "destination");
1727 if (dst == NULL || !is_ip_addr(dst))
1728 return -1;
1729
1730 timeout = get_param(cmd, "timeout");
1731 if (timeout) {
1732 wait_time = atoi(timeout);
1733 if (wait_time < 1)
1734 wait_time = 1;
1735 }
1736
1737 /* TODO: force renewal of IP lease if DHCP is enabled */
1738
1739 snprintf(buf, sizeof(buf), "ping %s -c 3 -W %d", dst, wait_time);
1740 res = system(buf);
1741 sigma_dut_print(dut, DUT_MSG_DEBUG, "ping returned: %d", res);
1742 if (res == 0)
1743 send_resp(dut, conn, SIGMA_COMPLETE, "connected,1");
1744 else if (res == 256)
1745 send_resp(dut, conn, SIGMA_COMPLETE, "connected,0");
1746 else
1747 return -2;
1748
1749 return 0;
1750}
1751
1752
Jouni Malinenf7222712019-06-13 01:50:21 +03001753static enum sigma_cmd_result cmd_sta_get_bssid(struct sigma_dut *dut,
1754 struct sigma_conn *conn,
1755 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001756{
1757 /* const char *intf = get_param(cmd, "Interface"); */
1758 char bssid[20], resp[50];
1759
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001760 if (get_wpa_status(get_station_ifname(dut), "bssid",
1761 bssid, sizeof(bssid)) < 0)
Peng Xub8fc5cc2017-05-10 17:27:28 -07001762 strlcpy(bssid, "00:00:00:00:00:00", sizeof(bssid));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001763
1764 snprintf(resp, sizeof(resp), "bssid,%s", bssid);
1765 send_resp(dut, conn, SIGMA_COMPLETE, resp);
1766 return 0;
1767}
1768
1769
1770#ifdef __SAMSUNG__
1771static int add_use_network(const char *ifname)
1772{
1773 char buf[100];
1774
1775 snprintf(buf, sizeof(buf), "USE_NETWORK ON");
1776 wpa_command(ifname, buf);
1777 return 0;
1778}
1779#endif /* __SAMSUNG__ */
1780
1781
1782static int add_network_common(struct sigma_dut *dut, struct sigma_conn *conn,
1783 const char *ifname, struct sigma_cmd *cmd)
1784{
1785 const char *ssid = get_param(cmd, "ssid");
1786 int id;
1787 const char *val;
1788
1789 if (ssid == NULL)
1790 return -1;
1791
1792 start_sta_mode(dut);
1793
1794#ifdef __SAMSUNG__
1795 add_use_network(ifname);
1796#endif /* __SAMSUNG__ */
1797
1798 id = add_network(ifname);
1799 if (id < 0)
1800 return -2;
1801 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding network %d", id);
1802
1803 if (set_network_quoted(ifname, id, "ssid", ssid) < 0)
1804 return -2;
1805
1806 dut->infra_network_id = id;
1807 snprintf(dut->infra_ssid, sizeof(dut->infra_ssid), "%s", ssid);
1808
1809 val = get_param(cmd, "program");
1810 if (!val)
1811 val = get_param(cmd, "prog");
1812 if (val && strcasecmp(val, "hs2") == 0) {
1813 char buf[100];
1814 snprintf(buf, sizeof(buf), "ENABLE_NETWORK %d no-connect", id);
1815 wpa_command(ifname, buf);
1816
1817 val = get_param(cmd, "prefer");
1818 if (val && atoi(val) > 0)
1819 set_network(ifname, id, "priority", "1");
1820 }
1821
1822 return id;
1823}
1824
1825
Jouni Malinenf7222712019-06-13 01:50:21 +03001826static enum sigma_cmd_result cmd_sta_set_encryption(struct sigma_dut *dut,
1827 struct sigma_conn *conn,
1828 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001829{
1830 const char *intf = get_param(cmd, "Interface");
1831 const char *ssid = get_param(cmd, "ssid");
1832 const char *type = get_param(cmd, "encpType");
1833 const char *ifname;
1834 char buf[200];
1835 int id;
1836
1837 if (intf == NULL || ssid == NULL)
1838 return -1;
1839
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001840 if (strcmp(intf, get_main_ifname(dut)) == 0)
1841 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001842 else
1843 ifname = intf;
1844
1845 id = add_network_common(dut, conn, ifname, cmd);
1846 if (id < 0)
1847 return id;
1848
1849 if (set_network(ifname, id, "key_mgmt", "NONE") < 0)
1850 return -2;
1851
1852 if (type && strcasecmp(type, "wep") == 0) {
1853 const char *val;
1854 int i;
1855
1856 val = get_param(cmd, "activeKey");
1857 if (val) {
1858 int keyid;
1859 keyid = atoi(val);
1860 if (keyid < 1 || keyid > 4)
1861 return -1;
1862 snprintf(buf, sizeof(buf), "%d", keyid - 1);
1863 if (set_network(ifname, id, "wep_tx_keyidx", buf) < 0)
1864 return -2;
1865 }
1866
1867 for (i = 0; i < 4; i++) {
1868 snprintf(buf, sizeof(buf), "key%d", i + 1);
1869 val = get_param(cmd, buf);
1870 if (val == NULL)
1871 continue;
1872 snprintf(buf, sizeof(buf), "wep_key%d", i);
1873 if (set_network(ifname, id, buf, val) < 0)
1874 return -2;
1875 }
1876 }
1877
1878 return 1;
1879}
1880
1881
Jouni Malinene4fde732019-03-25 22:29:37 +02001882static int set_akm_suites(struct sigma_dut *dut, const char *ifname,
1883 int id, const char *val)
1884{
1885 char key_mgmt[200], *end, *pos;
1886 const char *in_pos = val;
1887
Jouni Malinen8179fee2019-03-28 03:19:47 +02001888 dut->akm_values = 0;
Jouni Malinene4fde732019-03-25 22:29:37 +02001889 pos = key_mgmt;
1890 end = pos + sizeof(key_mgmt);
1891 while (*in_pos) {
1892 int res, akm = atoi(in_pos);
1893 const char *str;
1894
Jouni Malinen8179fee2019-03-28 03:19:47 +02001895 if (akm >= 0 && akm < 32)
1896 dut->akm_values |= 1 << akm;
1897
Jouni Malinene4fde732019-03-25 22:29:37 +02001898 switch (akm) {
1899 case AKM_WPA_EAP:
1900 str = "WPA-EAP";
1901 break;
1902 case AKM_WPA_PSK:
1903 str = "WPA-PSK";
1904 break;
1905 case AKM_FT_EAP:
1906 str = "FT-EAP";
1907 break;
1908 case AKM_FT_PSK:
1909 str = "FT-PSK";
1910 break;
1911 case AKM_EAP_SHA256:
1912 str = "WPA-EAP-SHA256";
1913 break;
1914 case AKM_PSK_SHA256:
1915 str = "WPA-PSK-SHA256";
1916 break;
1917 case AKM_SAE:
1918 str = "SAE";
1919 break;
1920 case AKM_FT_SAE:
1921 str = "FT-SAE";
1922 break;
1923 case AKM_SUITE_B:
1924 str = "WPA-EAP-SUITE-B-192";
1925 break;
1926 case AKM_FT_SUITE_B:
1927 str = "FT-EAP-SHA384";
1928 break;
1929 case AKM_FILS_SHA256:
1930 str = "FILS-SHA256";
1931 break;
1932 case AKM_FILS_SHA384:
1933 str = "FILS-SHA384";
1934 break;
1935 case AKM_FT_FILS_SHA256:
1936 str = "FT-FILS-SHA256";
1937 break;
1938 case AKM_FT_FILS_SHA384:
1939 str = "FT-FILS-SHA384";
1940 break;
1941 default:
1942 sigma_dut_print(dut, DUT_MSG_ERROR,
1943 "Unsupported AKMSuitetype %d", akm);
1944 return -1;
1945 }
1946
1947 res = snprintf(pos, end - pos, "%s%s",
1948 pos == key_mgmt ? "" : " ", str);
1949 if (res < 0 || res >= end - pos)
1950 return -1;
1951 pos += res;
1952
1953 in_pos = strchr(in_pos, ';');
1954 if (!in_pos)
1955 break;
1956 while (*in_pos == ';')
1957 in_pos++;
1958 }
1959 sigma_dut_print(dut, DUT_MSG_DEBUG, "AKMSuiteType %s --> %s",
1960 val, key_mgmt);
1961 return set_network(ifname, id, "key_mgmt", key_mgmt);
1962}
1963
1964
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001965static int set_wpa_common(struct sigma_dut *dut, struct sigma_conn *conn,
1966 const char *ifname, struct sigma_cmd *cmd)
1967{
1968 const char *val;
1969 int id;
Jouni Malinenad395a22017-09-01 21:13:46 +03001970 int cipher_set = 0;
Jouni Malinen47dcc952017-10-09 16:43:24 +03001971 int owe;
Sunil Duttc75a1e62018-01-11 20:47:50 +05301972 int suite_b = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001973
1974 id = add_network_common(dut, conn, ifname, cmd);
1975 if (id < 0)
1976 return id;
1977
Jouni Malinen47dcc952017-10-09 16:43:24 +03001978 val = get_param(cmd, "Type");
1979 owe = val && strcasecmp(val, "OWE") == 0;
1980
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001981 val = get_param(cmd, "keyMgmtType");
Jouni Malinen47dcc952017-10-09 16:43:24 +03001982 if (!val && owe)
1983 val = "OWE";
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001984 if (val == NULL) {
Jouni Malinene4fde732019-03-25 22:29:37 +02001985 /* keyMgmtType is being replaced with AKMSuiteType, so ignore
1986 * this missing parameter and assume proto=WPA2. */
1987 if (set_network(ifname, id, "proto", "WPA2") < 0)
1988 return ERROR_SEND_STATUS;
1989 } else if (strcasecmp(val, "wpa") == 0 ||
1990 strcasecmp(val, "wpa-psk") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001991 if (set_network(ifname, id, "proto", "WPA") < 0)
1992 return -2;
1993 } else if (strcasecmp(val, "wpa2") == 0 ||
1994 strcasecmp(val, "wpa2-psk") == 0 ||
1995 strcasecmp(val, "wpa2-ft") == 0 ||
1996 strcasecmp(val, "wpa2-sha256") == 0) {
1997 if (set_network(ifname, id, "proto", "WPA2") < 0)
1998 return -2;
Pradeep Reddy POTTETI6d04b3b2016-11-15 14:51:26 +05301999 } else if (strcasecmp(val, "wpa2-wpa-psk") == 0 ||
2000 strcasecmp(val, "wpa2-wpa-ent") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002001 if (set_network(ifname, id, "proto", "WPA WPA2") < 0)
2002 return -2;
Jouni Malinenad395a22017-09-01 21:13:46 +03002003 } else if (strcasecmp(val, "SuiteB") == 0) {
Sunil Duttc75a1e62018-01-11 20:47:50 +05302004 suite_b = 1;
Jouni Malinenad395a22017-09-01 21:13:46 +03002005 if (set_network(ifname, id, "proto", "WPA2") < 0)
2006 return -2;
Jouni Malinen47dcc952017-10-09 16:43:24 +03002007 } else if (strcasecmp(val, "OWE") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002008 } else {
2009 send_resp(dut, conn, SIGMA_INVALID, "errorCode,Unrecognized keyMgmtType value");
2010 return 0;
2011 }
2012
2013 val = get_param(cmd, "encpType");
Jouni Malinenad395a22017-09-01 21:13:46 +03002014 if (val) {
2015 cipher_set = 1;
2016 if (strcasecmp(val, "tkip") == 0) {
2017 if (set_network(ifname, id, "pairwise", "TKIP") < 0)
2018 return -2;
2019 } else if (strcasecmp(val, "aes-ccmp") == 0) {
2020 if (set_network(ifname, id, "pairwise", "CCMP") < 0)
2021 return -2;
2022 } else if (strcasecmp(val, "aes-ccmp-tkip") == 0) {
2023 if (set_network(ifname, id, "pairwise",
2024 "CCMP TKIP") < 0)
2025 return -2;
2026 } else if (strcasecmp(val, "aes-gcmp") == 0) {
2027 if (set_network(ifname, id, "pairwise", "GCMP") < 0)
2028 return -2;
2029 if (set_network(ifname, id, "group", "GCMP") < 0)
2030 return -2;
2031 } else {
2032 send_resp(dut, conn, SIGMA_ERROR,
2033 "errorCode,Unrecognized encpType value");
2034 return 0;
2035 }
2036 }
2037
2038 val = get_param(cmd, "PairwiseCipher");
2039 if (val) {
2040 cipher_set = 1;
2041 /* TODO: Support space separated list */
2042 if (strcasecmp(val, "AES-GCMP-256") == 0) {
2043 if (set_network(ifname, id, "pairwise", "GCMP-256") < 0)
2044 return -2;
2045 } else if (strcasecmp(val, "AES-CCMP-256") == 0) {
2046 if (set_network(ifname, id, "pairwise",
2047 "CCMP-256") < 0)
2048 return -2;
2049 } else if (strcasecmp(val, "AES-GCMP-128") == 0) {
2050 if (set_network(ifname, id, "pairwise", "GCMP") < 0)
2051 return -2;
2052 } else if (strcasecmp(val, "AES-CCMP-128") == 0) {
2053 if (set_network(ifname, id, "pairwise", "CCMP") < 0)
2054 return -2;
2055 } else {
2056 send_resp(dut, conn, SIGMA_ERROR,
2057 "errorCode,Unrecognized PairwiseCipher value");
2058 return 0;
2059 }
2060 }
2061
Jouni Malinen47dcc952017-10-09 16:43:24 +03002062 if (!cipher_set && !owe) {
Jouni Malinenad395a22017-09-01 21:13:46 +03002063 send_resp(dut, conn, SIGMA_ERROR,
2064 "errorCode,Missing encpType and PairwiseCipher");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002065 return 0;
2066 }
Jouni Malinenad395a22017-09-01 21:13:46 +03002067
2068 val = get_param(cmd, "GroupCipher");
2069 if (val) {
2070 if (strcasecmp(val, "AES-GCMP-256") == 0) {
2071 if (set_network(ifname, id, "group", "GCMP-256") < 0)
2072 return -2;
2073 } else if (strcasecmp(val, "AES-CCMP-256") == 0) {
2074 if (set_network(ifname, id, "group", "CCMP-256") < 0)
2075 return -2;
2076 } else if (strcasecmp(val, "AES-GCMP-128") == 0) {
2077 if (set_network(ifname, id, "group", "GCMP") < 0)
2078 return -2;
2079 } else if (strcasecmp(val, "AES-CCMP-128") == 0) {
2080 if (set_network(ifname, id, "group", "CCMP") < 0)
2081 return -2;
2082 } else {
2083 send_resp(dut, conn, SIGMA_ERROR,
2084 "errorCode,Unrecognized GroupCipher value");
2085 return 0;
2086 }
2087 }
2088
Jouni Malinen7b239522017-09-14 21:37:18 +03002089 val = get_param(cmd, "GroupMgntCipher");
Jouni Malinenad395a22017-09-01 21:13:46 +03002090 if (val) {
Jouni Malinene8898cb2017-09-26 17:55:26 +03002091 const char *cipher;
2092
2093 if (strcasecmp(val, "BIP-GMAC-256") == 0) {
2094 cipher = "BIP-GMAC-256";
2095 } else if (strcasecmp(val, "BIP-CMAC-256") == 0) {
2096 cipher = "BIP-CMAC-256";
2097 } else if (strcasecmp(val, "BIP-GMAC-128") == 0) {
2098 cipher = "BIP-GMAC-128";
2099 } else if (strcasecmp(val, "BIP-CMAC-128") == 0) {
2100 cipher = "AES-128-CMAC";
2101 } else {
2102 send_resp(dut, conn, SIGMA_INVALID,
2103 "errorCode,Unsupported GroupMgntCipher");
2104 return 0;
2105 }
2106 if (set_network(ifname, id, "group_mgmt", cipher) < 0) {
2107 send_resp(dut, conn, SIGMA_INVALID,
2108 "errorCode,Failed to set GroupMgntCipher");
2109 return 0;
2110 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002111 }
2112
Jouni Malinene4fde732019-03-25 22:29:37 +02002113 val = get_param(cmd, "AKMSuiteType");
2114 if (val && set_akm_suites(dut, ifname, id, val) < 0)
2115 return ERROR_SEND_STATUS;
2116
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002117 dut->sta_pmf = STA_PMF_DISABLED;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302118
2119 if (dut->program == PROGRAM_OCE) {
2120 dut->sta_pmf = STA_PMF_OPTIONAL;
2121 if (set_network(ifname, id, "ieee80211w", "1") < 0)
2122 return -2;
2123 }
2124
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002125 val = get_param(cmd, "PMF");
2126 if (val) {
2127 if (strcasecmp(val, "Required") == 0 ||
2128 strcasecmp(val, "Forced_Required") == 0) {
2129 dut->sta_pmf = STA_PMF_REQUIRED;
2130 if (set_network(ifname, id, "ieee80211w", "2") < 0)
2131 return -2;
2132 } else if (strcasecmp(val, "Optional") == 0) {
2133 dut->sta_pmf = STA_PMF_OPTIONAL;
2134 if (set_network(ifname, id, "ieee80211w", "1") < 0)
2135 return -2;
2136 } else if (strcasecmp(val, "Disabled") == 0 ||
Kiran Kumar Lokere07da3b22018-12-16 22:42:49 -08002137 strcasecmp(val, "Disable") == 0 ||
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002138 strcasecmp(val, "Forced_Disabled") == 0) {
2139 dut->sta_pmf = STA_PMF_DISABLED;
2140 } else {
2141 send_resp(dut, conn, SIGMA_INVALID, "errorCode,Unrecognized PMF value");
2142 return 0;
2143 }
Sunil Duttc75a1e62018-01-11 20:47:50 +05302144 } else if (owe || suite_b) {
Jouni Malinen1287cd72018-01-04 17:08:01 +02002145 dut->sta_pmf = STA_PMF_REQUIRED;
2146 if (set_network(ifname, id, "ieee80211w", "2") < 0)
2147 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002148 }
2149
Jouni Malinen0165c7f2020-03-26 11:51:58 +02002150 val = get_param(cmd, "BeaconProtection");
Veerendranath Jakkamc1f71b62021-01-23 03:09:51 +05302151 if (val)
2152 dut->beacon_prot = atoi(val);
2153 if (dut->beacon_prot && set_network(ifname, id, "beacon_prot", "1") < 0)
Jouni Malinen0165c7f2020-03-26 11:51:58 +02002154 return ERROR_SEND_STATUS;
2155
Veerendranath Jakkam54fd51c2020-12-21 01:36:04 +05302156 if (dut->ocvc && set_network(ifname, id, "ocv", "1") < 0)
2157 return ERROR_SEND_STATUS;
2158
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002159 return id;
2160}
2161
2162
Veerendranath Jakkamca239592021-10-11 20:48:00 +05302163static int wcn_set_ignore_h2e_rsnxe(struct sigma_dut *dut, const char *intf,
2164 uint8_t cfg)
2165{
2166#ifdef NL80211_SUPPORT
2167 return wcn_wifi_test_config_set_u8(
2168 dut, intf,
2169 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_IGNORE_H2E_RSNXE, cfg);
2170#else /* NL80211_SUPPORT */
2171 sigma_dut_print(dut, DUT_MSG_ERROR,
2172 "Ignore SAE H2E requirement mismatch can't be set without NL80211_SUPPORT defined");
2173 return -1;
2174#endif /* NL80211_SUPPORT */
2175}
2176
2177
Jouni Malinenf7222712019-06-13 01:50:21 +03002178static enum sigma_cmd_result cmd_sta_set_psk(struct sigma_dut *dut,
2179 struct sigma_conn *conn,
2180 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002181{
2182 const char *intf = get_param(cmd, "Interface");
Jouni Malinen992a81e2017-08-22 13:57:47 +03002183 const char *type = get_param(cmd, "Type");
Jouni Malinen1287cd72018-01-04 17:08:01 +02002184 const char *pmf = get_param(cmd, "PMF");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002185 const char *network_mode = get_param(cmd, "network_mode");
Jouni Malinene4fde732019-03-25 22:29:37 +02002186 const char *akm = get_param(cmd, "AKMSuiteType");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002187 const char *ifname, *val, *alg;
2188 int id;
Jouni Malinen4b3769d2019-10-10 16:20:29 +03002189 char buf[50];
Jouni Malinen11e55212019-11-22 21:46:59 +02002190 int sae_pwe = -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002191
2192 if (intf == NULL)
2193 return -1;
2194
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002195 if (strcmp(intf, get_main_ifname(dut)) == 0)
2196 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002197 else
2198 ifname = intf;
2199
2200 id = set_wpa_common(dut, conn, ifname, cmd);
2201 if (id < 0)
2202 return id;
2203
2204 val = get_param(cmd, "keyMgmtType");
2205 alg = get_param(cmd, "micAlg");
2206
Jouni Malinen992a81e2017-08-22 13:57:47 +03002207 if (type && strcasecmp(type, "SAE") == 0) {
Jouni Malinene4fde732019-03-25 22:29:37 +02002208 if (!akm && val && strcasecmp(val, "wpa2-ft") == 0) {
Jouni Malinen992a81e2017-08-22 13:57:47 +03002209 if (set_network(ifname, id, "key_mgmt", "FT-SAE") < 0)
2210 return -2;
Jouni Malinene4fde732019-03-25 22:29:37 +02002211 } else if (!akm) {
Jouni Malinen992a81e2017-08-22 13:57:47 +03002212 if (set_network(ifname, id, "key_mgmt", "SAE") < 0)
2213 return -2;
2214 }
2215 if (wpa_command(ifname, "SET sae_groups ") != 0) {
2216 sigma_dut_print(dut, DUT_MSG_ERROR,
2217 "Failed to clear sae_groups to default");
2218 return -2;
2219 }
Jouni Malinen1287cd72018-01-04 17:08:01 +02002220 if (!pmf) {
2221 dut->sta_pmf = STA_PMF_REQUIRED;
2222 if (set_network(ifname, id, "ieee80211w", "2") < 0)
2223 return -2;
2224 }
Jouni Malinen0ab50f42017-08-31 01:34:59 +03002225 } else if (type && strcasecmp(type, "PSK-SAE") == 0) {
2226 if (val && strcasecmp(val, "wpa2-ft") == 0) {
2227 if (set_network(ifname, id, "key_mgmt",
2228 "FT-SAE FT-PSK") < 0)
2229 return -2;
Jouni Malinen3b73d872019-06-12 03:13:25 +03002230 } else if (!akm) {
Jouni Malinen0ab50f42017-08-31 01:34:59 +03002231 if (set_network(ifname, id, "key_mgmt",
2232 "SAE WPA-PSK") < 0)
2233 return -2;
2234 }
2235 if (wpa_command(ifname, "SET sae_groups ") != 0) {
2236 sigma_dut_print(dut, DUT_MSG_ERROR,
2237 "Failed to clear sae_groups to default");
2238 return -2;
2239 }
Jouni Malinen1287cd72018-01-04 17:08:01 +02002240 if (!pmf) {
2241 dut->sta_pmf = STA_PMF_OPTIONAL;
2242 if (set_network(ifname, id, "ieee80211w", "1") < 0)
2243 return -2;
2244 }
Jouni Malinen992a81e2017-08-22 13:57:47 +03002245 } else if (alg && strcasecmp(alg, "SHA-256") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002246 if (set_network(ifname, id, "key_mgmt", "WPA-PSK-SHA256") < 0)
2247 return -2;
2248 } else if (alg && strcasecmp(alg, "SHA-1") == 0) {
2249 if (set_network(ifname, id, "key_mgmt", "WPA-PSK") < 0)
2250 return -2;
Ashwini Patil6dbf7b02017-03-20 13:42:11 +05302251 } else if (val && strcasecmp(val, "wpa2-ft") == 0) {
2252 if (set_network(ifname, id, "key_mgmt", "FT-PSK") < 0)
2253 return -2;
Jouni Malinen3b73d872019-06-12 03:13:25 +03002254 } else if (!akm &&
2255 ((val && strcasecmp(val, "wpa2-sha256") == 0) ||
2256 dut->sta_pmf == STA_PMF_REQUIRED)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002257 if (set_network(ifname, id, "key_mgmt",
2258 "WPA-PSK WPA-PSK-SHA256") < 0)
2259 return -2;
Jouni Malinen77ff3f02019-03-28 03:45:40 +02002260 } else if (!akm && dut->sta_pmf == STA_PMF_OPTIONAL) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002261 if (set_network(ifname, id, "key_mgmt",
2262 "WPA-PSK WPA-PSK-SHA256") < 0)
2263 return -2;
Jouni Malinen77ff3f02019-03-28 03:45:40 +02002264 } else if (!akm) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002265 if (set_network(ifname, id, "key_mgmt", "WPA-PSK") < 0)
2266 return -2;
2267 }
2268
2269 val = get_param(cmd, "passPhrase");
2270 if (val == NULL)
2271 return -1;
Jouni Malinen2126f422017-10-11 23:24:33 +03002272 if (type && strcasecmp(type, "SAE") == 0) {
2273 if (set_network_quoted(ifname, id, "sae_password", val) < 0)
2274 return -2;
2275 } else {
2276 if (set_network_quoted(ifname, id, "psk", val) < 0)
2277 return -2;
2278 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002279
Jouni Malinen78d10c42019-03-25 22:34:32 +02002280 val = get_param(cmd, "PasswordId");
2281 if (val && set_network_quoted(ifname, id, "sae_password_id", val) < 0)
2282 return ERROR_SEND_STATUS;
2283
Jouni Malinen992a81e2017-08-22 13:57:47 +03002284 val = get_param(cmd, "ECGroupID");
2285 if (val) {
Jouni Malinenb54f0df2019-12-12 01:57:29 +02002286 snprintf(buf, sizeof(buf), "SET sae_groups %s", val);
Jouni Malinen992a81e2017-08-22 13:57:47 +03002287 if (wpa_command(ifname, buf) != 0) {
2288 sigma_dut_print(dut, DUT_MSG_ERROR,
2289 "Failed to clear sae_groups");
2290 return -2;
2291 }
2292 }
2293
Jouni Malinen68143132017-09-02 02:34:08 +03002294 val = get_param(cmd, "InvalidSAEElement");
2295 if (val) {
2296 free(dut->sae_commit_override);
2297 dut->sae_commit_override = strdup(val);
2298 }
2299
Jouni Malinen4b3769d2019-10-10 16:20:29 +03002300 val = get_param(cmd, "PMKID_Include");
2301 if (val) {
2302 snprintf(buf, sizeof(buf), "SET sae_pmkid_in_assoc %d",
2303 get_enable_disable(val));
2304 wpa_command(intf, buf);
2305 }
2306
Jouni Malineneeb43d32019-12-06 17:40:07 +02002307 val = get_param(cmd, "IgnoreH2E_RSNXE_BSSMemSel");
2308 if (val) {
2309 snprintf(buf, sizeof(buf), "SET ignore_sae_h2e_only %d",
2310 get_enable_disable(val));
2311 wpa_command(intf, buf);
Veerendranath Jakkamca239592021-10-11 20:48:00 +05302312 if (get_driver_type(dut) == DRIVER_WCN)
2313 wcn_set_ignore_h2e_rsnxe(dut, intf,
2314 get_enable_disable(val));
Jouni Malineneeb43d32019-12-06 17:40:07 +02002315 }
2316
Jouni Malinenf2348d22019-12-07 11:52:55 +02002317 val = get_param(cmd, "ECGroupID_RGE");
2318 if (val) {
2319 snprintf(buf, sizeof(buf), "SET extra_sae_rejected_groups %s",
2320 val);
2321 wpa_command(intf, buf);
2322 }
2323
Jouni Malinen99e55022019-12-07 13:59:41 +02002324 val = get_param(cmd, "RSNXE_Content");
2325 if (val) {
2326 const char *param;
2327
2328 if (strncasecmp(val, "AssocReq:", 9) == 0) {
2329 val += 9;
2330 param = "rsnxe_override_assoc";
2331 } else if (strncasecmp(val, "EapolM2:", 8) == 0) {
2332 val += 8;
2333 param = "rsnxe_override_eapol";
2334 } else {
2335 send_resp(dut, conn, SIGMA_ERROR,
2336 "errorCode,Unsupported RSNXE_Content value");
2337 return STATUS_SENT_ERROR;
2338 }
2339 snprintf(buf, sizeof(buf), "SET %s %s", param, val);
2340 wpa_command(intf, buf);
2341 }
2342
Jouni Malinen11e55212019-11-22 21:46:59 +02002343 val = get_param(cmd, "sae_pwe");
2344 if (val) {
2345 if (strcasecmp(val, "h2e") == 0) {
2346 dut->sae_pwe = SAE_PWE_H2E;
Jouni Malinen7244a412019-12-07 11:54:10 +02002347 } else if (strcasecmp(val, "loop") == 0 ||
2348 strcasecmp(val, "looping") == 0) {
Jouni Malinen11e55212019-11-22 21:46:59 +02002349 dut->sae_pwe = SAE_PWE_LOOP;
2350 } else {
2351 send_resp(dut, conn, SIGMA_ERROR,
2352 "errorCode,Unsupported sae_pwe value");
2353 return STATUS_SENT_ERROR;
2354 }
2355 }
Vinita S. Maloo6d7454f2020-04-02 15:03:26 +05302356
2357 val = get_param(cmd, "Clear_RSNXE");
2358 if (val && strcmp(val, "1") == 0 &&
2359 (wpa_command(intf, "SET rsnxe_override_assoc ") ||
2360 wpa_command(intf, "SET rsnxe_override_eapol "))) {
2361 send_resp(dut, conn, SIGMA_ERROR,
2362 "errorCode,Failed to clear RSNXE");
Jouni Malinenb11498c2020-08-03 11:05:53 +03002363 return STATUS_SENT_ERROR;
Vinita S. Maloo6d7454f2020-04-02 15:03:26 +05302364 }
2365
Jouni Malinenc0078772020-03-04 21:23:16 +02002366 if (dut->sae_pwe == SAE_PWE_LOOP && get_param(cmd, "PasswordId"))
2367 sae_pwe = 3;
2368 else if (dut->sae_pwe == SAE_PWE_LOOP)
Jouni Malinen11e55212019-11-22 21:46:59 +02002369 sae_pwe = 0;
2370 else if (dut->sae_pwe == SAE_PWE_H2E)
2371 sae_pwe = 1;
2372 else if (dut->sae_h2e_default)
2373 sae_pwe = 2;
2374 snprintf(buf, sizeof(buf), "SET sae_pwe %d", sae_pwe);
2375 if (sae_pwe >= 0 && wpa_command(ifname, buf) != 0)
2376 return ERROR_SEND_STATUS;
2377
Veerendranath Jakkam0316be12020-06-23 20:11:41 +05302378 val = get_param(cmd, "sae_pk");
2379 if (val && strcmp(val, "0") == 0 &&
2380 set_network(ifname, id, "sae_pk", "2") < 0)
2381 return ERROR_SEND_STATUS;
2382
Veerendranath Jakkama9177042020-08-10 00:14:03 +05302383 val = get_param(cmd, "sae_pk_only");
2384 if (val && strcmp(val, "1") == 0 &&
2385 set_network(ifname, id, "sae_pk", "1") < 0)
2386 return ERROR_SEND_STATUS;
2387
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002388 if (dut->program == PROGRAM_60GHZ && network_mode &&
2389 strcasecmp(network_mode, "PBSS") == 0 &&
2390 set_network(ifname, id, "pbss", "1") < 0)
2391 return -2;
2392
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002393 return 1;
2394}
2395
2396
Jouni Malinen8ac93452019-08-14 15:19:13 +03002397static enum sigma_cmd_result set_trust_root_system(struct sigma_dut *dut,
2398 struct sigma_conn *conn,
2399 const char *ifname, int id)
2400{
2401 char buf[200];
2402
2403 snprintf(buf, sizeof(buf), "%s/certs", sigma_cert_path);
2404 if (!file_exists(buf))
2405 strlcpy(buf, "/system/etc/security/cacerts", sizeof(buf));
2406 if (!file_exists(buf))
2407 strlcpy(buf, "/etc/ssl/certs", sizeof(buf));
2408 if (!file_exists(buf)) {
2409 char msg[300];
2410
2411 snprintf(msg, sizeof(msg),
2412 "ErrorCode,trustedRootCA system store (%s) not found",
2413 buf);
2414 send_resp(dut, conn, SIGMA_ERROR, msg);
2415 return STATUS_SENT_ERROR;
2416 }
2417
2418 if (set_network_quoted(ifname, id, "ca_path", buf) < 0)
2419 return ERROR_SEND_STATUS;
2420
2421 return SUCCESS_SEND_STATUS;
2422}
2423
2424
2425static enum sigma_cmd_result set_trust_root(struct sigma_dut *dut,
2426 struct sigma_conn *conn,
2427 const char *ifname, int id,
2428 const char *val)
2429{
2430 char buf[200];
2431#ifdef ANDROID
2432 unsigned char kvalue[KEYSTORE_MESSAGE_SIZE];
2433 int length;
2434#endif /* ANDROID */
2435
2436 if (strcmp(val, "DEFAULT") == 0)
2437 return set_trust_root_system(dut, conn, ifname, id);
2438
2439#ifdef ANDROID
2440 snprintf(buf, sizeof(buf), "CACERT_%s", val);
2441 length = android_keystore_get(ANDROID_KEYSTORE_GET, buf, kvalue);
2442 if (length > 0) {
2443 sigma_dut_print(dut, DUT_MSG_INFO, "Use Android keystore [%s]",
2444 buf);
2445 snprintf(buf, sizeof(buf), "keystore://CACERT_%s", val);
2446 goto ca_cert_selected;
2447 }
2448#endif /* ANDROID */
2449
2450 snprintf(buf, sizeof(buf), "%s/%s", sigma_cert_path, val);
2451#ifdef __linux__
2452 if (!file_exists(buf)) {
2453 char msg[300];
2454
2455 snprintf(msg, sizeof(msg),
2456 "ErrorCode,trustedRootCA file (%s) not found", buf);
2457 send_resp(dut, conn, SIGMA_ERROR, msg);
2458 return STATUS_SENT_ERROR;
2459 }
2460#endif /* __linux__ */
2461#ifdef ANDROID
2462ca_cert_selected:
2463#endif /* ANDROID */
2464 if (set_network_quoted(ifname, id, "ca_cert", buf) < 0)
2465 return ERROR_SEND_STATUS;
2466
2467 return SUCCESS_SEND_STATUS;
2468}
2469
2470
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002471static int set_eap_common(struct sigma_dut *dut, struct sigma_conn *conn,
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302472 const char *ifname, int username_identity,
2473 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002474{
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002475 const char *val, *alg, *akm, *trust_root, *domain, *domain_suffix;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002476 int id;
Jouni Malinen53264f62019-05-03 13:04:40 +03002477 char buf[200], buf2[300];
Jouni Malinen8179fee2019-03-28 03:19:47 +02002478 int erp = 0;
Jouni Malinen8ac93452019-08-14 15:19:13 +03002479 enum sigma_cmd_result res;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002480
2481 id = set_wpa_common(dut, conn, ifname, cmd);
2482 if (id < 0)
2483 return id;
2484
2485 val = get_param(cmd, "keyMgmtType");
2486 alg = get_param(cmd, "micAlg");
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302487 akm = get_param(cmd, "AKMSuiteType");
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002488 trust_root = get_param(cmd, "trustedRootCA");
2489 domain = get_param(cmd, "Domain");
2490 domain_suffix = get_param(cmd, "DomainSuffix");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002491
Jouni Malinenad395a22017-09-01 21:13:46 +03002492 if (val && strcasecmp(val, "SuiteB") == 0) {
2493 if (set_network(ifname, id, "key_mgmt", "WPA-EAP-SUITE-B-192") <
2494 0)
2495 return -2;
2496 } else if (alg && strcasecmp(alg, "SHA-256") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002497 if (set_network(ifname, id, "key_mgmt", "WPA-EAP-SHA256") < 0)
2498 return -2;
2499 } else if (alg && strcasecmp(alg, "SHA-1") == 0) {
2500 if (set_network(ifname, id, "key_mgmt", "WPA-EAP") < 0)
2501 return -2;
2502 } else if (val && strcasecmp(val, "wpa2-ft") == 0) {
2503 if (set_network(ifname, id, "key_mgmt", "FT-EAP") < 0)
2504 return -2;
Jouni Malinend6a9d692019-03-28 03:01:24 +02002505 } else if (!akm &&
2506 ((val && strcasecmp(val, "wpa2-sha256") == 0) ||
2507 dut->sta_pmf == STA_PMF_REQUIRED)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002508 if (set_network(ifname, id, "key_mgmt",
2509 "WPA-EAP WPA-EAP-SHA256") < 0)
2510 return -2;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302511 } else if (akm && atoi(akm) == 14) {
2512 if (dut->sta_pmf == STA_PMF_OPTIONAL ||
2513 dut->sta_pmf == STA_PMF_REQUIRED) {
2514 if (set_network(ifname, id, "key_mgmt",
2515 "WPA-EAP-SHA256 FILS-SHA256") < 0)
2516 return -2;
2517 } else {
2518 if (set_network(ifname, id, "key_mgmt",
2519 "WPA-EAP FILS-SHA256") < 0)
2520 return -2;
2521 }
2522
Jouni Malinen8179fee2019-03-28 03:19:47 +02002523 erp = 1;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302524 } else if (akm && atoi(akm) == 15) {
2525 if (dut->sta_pmf == STA_PMF_OPTIONAL ||
2526 dut->sta_pmf == STA_PMF_REQUIRED) {
2527 if (set_network(ifname, id, "key_mgmt",
2528 "WPA-EAP-SHA256 FILS-SHA384") < 0)
2529 return -2;
2530 } else {
2531 if (set_network(ifname, id, "key_mgmt",
2532 "WPA-EAP FILS-SHA384") < 0)
2533 return -2;
2534 }
2535
Jouni Malinen8179fee2019-03-28 03:19:47 +02002536 erp = 1;
Jouni Malinend6a9d692019-03-28 03:01:24 +02002537 } else if (!akm && dut->sta_pmf == STA_PMF_OPTIONAL) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002538 if (set_network(ifname, id, "key_mgmt",
2539 "WPA-EAP WPA-EAP-SHA256") < 0)
2540 return -2;
Jouni Malinend6a9d692019-03-28 03:01:24 +02002541 } else if (!akm) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002542 if (set_network(ifname, id, "key_mgmt", "WPA-EAP") < 0)
2543 return -2;
2544 }
2545
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002546 if (trust_root) {
2547 if (strcmp(trust_root, "DEFAULT") == 0 && !domain &&
2548 !domain_suffix) {
2549 send_resp(dut, conn, SIGMA_ERROR,
2550 "errorCode,trustRootCA DEFAULT used without specifying Domain or DomainSuffix");
2551 return STATUS_SENT_ERROR;
2552 }
2553 res = set_trust_root(dut, conn, ifname, id, trust_root);
Jouni Malinen8ac93452019-08-14 15:19:13 +03002554 if (res != SUCCESS_SEND_STATUS)
2555 return res;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002556 }
2557
Jouni Malinen53264f62019-05-03 13:04:40 +03002558 val = get_param(cmd, "ServerCert");
2559 if (val) {
2560 FILE *f;
2561 char *result = NULL, *pos;
2562
2563 snprintf(buf, sizeof(buf), "%s/%s.sha256", sigma_cert_path,
2564 val);
2565 f = fopen(buf, "r");
2566 if (f) {
2567 result = fgets(buf, sizeof(buf), f);
2568 fclose(f);
2569 }
2570 if (!result) {
2571 snprintf(buf2, sizeof(buf2),
2572 "ErrorCode,ServerCert hash could not be read from %s",
2573 buf);
2574 send_resp(dut, conn, SIGMA_ERROR, buf2);
2575 return STATUS_SENT_ERROR;
2576 }
2577 pos = strchr(buf, '\n');
2578 if (pos)
2579 *pos = '\0';
Jouni Malinen0572a742020-10-08 13:53:25 +03002580 pos = strchr(buf, '\r');
2581 if (pos)
2582 *pos = '\0';
Jouni Malinen53264f62019-05-03 13:04:40 +03002583 snprintf(buf2, sizeof(buf2), "hash://server/sha256/%s", buf);
2584 if (set_network_quoted(ifname, id, "ca_cert", buf2) < 0)
2585 return ERROR_SEND_STATUS;
Jouni Malinen29108dc2019-06-13 23:42:11 +03002586
2587 snprintf(buf, sizeof(buf), "%s/%s.tod", sigma_cert_path, val);
2588 if (file_exists(buf)) {
2589 sigma_dut_print(dut, DUT_MSG_DEBUG,
2590 "TOD policy enabled for the configured ServerCert hash");
2591 dut->sta_tod_policy = 1;
2592 }
Jouni Malinen53264f62019-05-03 13:04:40 +03002593 }
2594
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002595 if (domain &&
2596 set_network_quoted(ifname, id, "domain_match", domain) < 0)
Jouni Malinen96f84b02019-05-03 12:32:56 +03002597 return ERROR_SEND_STATUS;
2598
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002599 if (domain_suffix &&
2600 set_network_quoted(ifname, id, "domain_suffix_match",
2601 domain_suffix) < 0)
Jouni Malinen96f84b02019-05-03 12:32:56 +03002602 return ERROR_SEND_STATUS;
2603
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302604 if (username_identity) {
2605 val = get_param(cmd, "username");
2606 if (val) {
2607 if (set_network_quoted(ifname, id, "identity", val) < 0)
2608 return -2;
2609 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002610
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302611 val = get_param(cmd, "password");
2612 if (val) {
2613 if (set_network_quoted(ifname, id, "password", val) < 0)
2614 return -2;
2615 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002616 }
2617
Jouni Malinen8179fee2019-03-28 03:19:47 +02002618 if (dut->akm_values &
2619 ((1 << AKM_FILS_SHA256) |
2620 (1 << AKM_FILS_SHA384) |
2621 (1 << AKM_FT_FILS_SHA256) |
2622 (1 << AKM_FT_FILS_SHA384)))
2623 erp = 1;
2624 if (erp && set_network(ifname, id, "erp", "1") < 0)
2625 return ERROR_SEND_STATUS;
2626
Jouni Malinen134fe3c2019-06-12 04:16:49 +03002627 dut->sta_associate_wait_connect = 1;
2628
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002629 return id;
2630}
2631
2632
Jouni Malinen5eabb2a2017-10-03 18:17:30 +03002633static int set_tls_cipher(const char *ifname, int id, const char *cipher)
2634{
2635 const char *val;
2636
2637 if (!cipher)
2638 return 0;
2639
2640 if (strcasecmp(cipher, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384") == 0)
2641 val = "ECDHE-ECDSA-AES256-GCM-SHA384";
2642 else if (strcasecmp(cipher,
2643 "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384") == 0)
2644 val = "ECDHE-RSA-AES256-GCM-SHA384";
2645 else if (strcasecmp(cipher, "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384") == 0)
2646 val = "DHE-RSA-AES256-GCM-SHA384";
2647 else if (strcasecmp(cipher,
2648 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256") == 0)
2649 val = "ECDHE-ECDSA-AES128-GCM-SHA256";
2650 else
2651 return -1;
2652
2653 /* Need to clear phase1="tls_suiteb=1" to allow cipher enforcement */
2654 set_network_quoted(ifname, id, "phase1", "");
2655
2656 return set_network_quoted(ifname, id, "openssl_ciphers", val);
2657}
2658
2659
Jouni Malinenf7222712019-06-13 01:50:21 +03002660static enum sigma_cmd_result cmd_sta_set_eaptls(struct sigma_dut *dut,
2661 struct sigma_conn *conn,
2662 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002663{
2664 const char *intf = get_param(cmd, "Interface");
2665 const char *ifname, *val;
2666 int id;
2667 char buf[200];
2668#ifdef ANDROID
2669 unsigned char kvalue[KEYSTORE_MESSAGE_SIZE];
2670 int length;
2671 int jb_or_newer = 0;
2672 char prop[PROPERTY_VALUE_MAX];
2673#endif /* ANDROID */
2674
2675 if (intf == NULL)
2676 return -1;
2677
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002678 if (strcmp(intf, get_main_ifname(dut)) == 0)
2679 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002680 else
2681 ifname = intf;
2682
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302683 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002684 if (id < 0)
2685 return id;
2686
2687 if (set_network(ifname, id, "eap", "TLS") < 0)
2688 return -2;
2689
Pradeep Reddy POTTETI9f6c2132016-05-05 16:28:19 +05302690 if (!get_param(cmd, "username") &&
2691 set_network_quoted(ifname, id, "identity",
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002692 "wifi-user@wifilabs.local") < 0)
2693 return -2;
2694
2695 val = get_param(cmd, "clientCertificate");
2696 if (val == NULL)
2697 return -1;
2698#ifdef ANDROID
2699 snprintf(buf, sizeof(buf), "USRPKEY_%s", val);
2700 length = android_keystore_get(ANDROID_KEYSTORE_GET, buf, kvalue);
2701 if (length < 0) {
2702 /*
2703 * JB started reporting keystore type mismatches, so retry with
2704 * the GET_PUBKEY command if the generic GET fails.
2705 */
2706 length = android_keystore_get(ANDROID_KEYSTORE_GET_PUBKEY,
2707 buf, kvalue);
2708 }
2709
2710 if (property_get("ro.build.version.release", prop, NULL) != 0) {
2711 sigma_dut_print(dut, DUT_MSG_DEBUG, "Android release %s", prop);
2712 if (strncmp(prop, "4.0", 3) != 0)
2713 jb_or_newer = 1;
2714 } else
2715 jb_or_newer = 1; /* assume newer */
2716
2717 if (jb_or_newer && length > 0) {
2718 sigma_dut_print(dut, DUT_MSG_INFO,
2719 "Use Android keystore [%s]", buf);
2720 if (set_network(ifname, id, "engine", "1") < 0)
2721 return -2;
2722 if (set_network_quoted(ifname, id, "engine_id", "keystore") < 0)
2723 return -2;
2724 snprintf(buf, sizeof(buf), "USRPKEY_%s", val);
2725 if (set_network_quoted(ifname, id, "key_id", buf) < 0)
2726 return -2;
2727 snprintf(buf, sizeof(buf), "keystore://USRCERT_%s", val);
2728 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
2729 return -2;
2730 return 1;
2731 } else if (length > 0) {
2732 sigma_dut_print(dut, DUT_MSG_INFO,
2733 "Use Android keystore [%s]", buf);
2734 snprintf(buf, sizeof(buf), "keystore://USRPKEY_%s", val);
2735 if (set_network_quoted(ifname, id, "private_key", buf) < 0)
2736 return -2;
2737 snprintf(buf, sizeof(buf), "keystore://USRCERT_%s", val);
2738 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
2739 return -2;
2740 return 1;
2741 }
2742#endif /* ANDROID */
2743
2744 snprintf(buf, sizeof(buf), "%s/%s", sigma_cert_path, val);
2745#ifdef __linux__
2746 if (!file_exists(buf)) {
2747 char msg[300];
2748 snprintf(msg, sizeof(msg), "ErrorCode,clientCertificate file "
2749 "(%s) not found", buf);
2750 send_resp(dut, conn, SIGMA_ERROR, msg);
2751 return -3;
2752 }
2753#endif /* __linux__ */
2754 if (set_network_quoted(ifname, id, "private_key", buf) < 0)
2755 return -2;
2756 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
2757 return -2;
2758
2759 if (set_network_quoted(ifname, id, "private_key_passwd", "wifi") < 0)
2760 return -2;
2761
Jouni Malinen5eabb2a2017-10-03 18:17:30 +03002762 val = get_param(cmd, "keyMgmtType");
2763 if (val && strcasecmp(val, "SuiteB") == 0) {
2764 val = get_param(cmd, "CertType");
2765 if (val && strcasecmp(val, "RSA") == 0) {
2766 if (set_network_quoted(ifname, id, "phase1",
2767 "tls_suiteb=1") < 0)
2768 return -2;
2769 } else {
2770 if (set_network_quoted(ifname, id, "openssl_ciphers",
2771 "SUITEB192") < 0)
2772 return -2;
2773 }
2774
2775 val = get_param(cmd, "TLSCipher");
2776 if (set_tls_cipher(ifname, id, val) < 0) {
2777 send_resp(dut, conn, SIGMA_ERROR,
2778 "ErrorCode,Unsupported TLSCipher value");
2779 return -3;
2780 }
2781 }
2782
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002783 return 1;
2784}
2785
2786
Jouni Malinenf7222712019-06-13 01:50:21 +03002787static enum sigma_cmd_result cmd_sta_set_eapttls(struct sigma_dut *dut,
2788 struct sigma_conn *conn,
2789 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002790{
2791 const char *intf = get_param(cmd, "Interface");
2792 const char *ifname;
2793 int id;
2794
2795 if (intf == NULL)
2796 return -1;
2797
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002798 if (strcmp(intf, get_main_ifname(dut)) == 0)
2799 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002800 else
2801 ifname = intf;
2802
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302803 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002804 if (id < 0)
2805 return id;
2806
2807 if (set_network(ifname, id, "eap", "TTLS") < 0) {
2808 send_resp(dut, conn, SIGMA_ERROR,
2809 "errorCode,Failed to set TTLS method");
2810 return 0;
2811 }
2812
2813 if (set_network_quoted(ifname, id, "phase2", "auth=MSCHAPV2") < 0) {
2814 send_resp(dut, conn, SIGMA_ERROR,
2815 "errorCode,Failed to set MSCHAPv2 for TTLS Phase 2");
2816 return 0;
2817 }
2818
2819 return 1;
2820}
2821
2822
Jouni Malinenf7222712019-06-13 01:50:21 +03002823static enum sigma_cmd_result cmd_sta_set_eapsim(struct sigma_dut *dut,
2824 struct sigma_conn *conn,
2825 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002826{
2827 const char *intf = get_param(cmd, "Interface");
2828 const char *ifname;
2829 int id;
2830
2831 if (intf == NULL)
2832 return -1;
2833
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002834 if (strcmp(intf, get_main_ifname(dut)) == 0)
2835 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002836 else
2837 ifname = intf;
2838
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302839 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002840 if (id < 0)
2841 return id;
2842
2843 if (set_network(ifname, id, "eap", "SIM") < 0)
2844 return -2;
2845
2846 return 1;
2847}
2848
2849
Jouni Malinenf7222712019-06-13 01:50:21 +03002850static enum sigma_cmd_result cmd_sta_set_peap(struct sigma_dut *dut,
2851 struct sigma_conn *conn,
2852 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002853{
2854 const char *intf = get_param(cmd, "Interface");
2855 const char *ifname, *val;
2856 int id;
2857 char buf[100];
2858
2859 if (intf == NULL)
2860 return -1;
2861
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002862 if (strcmp(intf, get_main_ifname(dut)) == 0)
2863 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002864 else
2865 ifname = intf;
2866
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302867 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002868 if (id < 0)
2869 return id;
2870
2871 if (set_network(ifname, id, "eap", "PEAP") < 0)
2872 return -2;
2873
2874 val = get_param(cmd, "innerEAP");
2875 if (val) {
2876 if (strcasecmp(val, "MSCHAPv2") == 0) {
2877 if (set_network_quoted(ifname, id, "phase2",
2878 "auth=MSCHAPV2") < 0)
2879 return -2;
2880 } else if (strcasecmp(val, "GTC") == 0) {
2881 if (set_network_quoted(ifname, id, "phase2",
2882 "auth=GTC") < 0)
2883 return -2;
2884 } else
2885 return -1;
2886 }
2887
2888 val = get_param(cmd, "peapVersion");
2889 if (val) {
2890 int ver = atoi(val);
2891 if (ver < 0 || ver > 1)
2892 return -1;
2893 snprintf(buf, sizeof(buf), "peapver=%d", ver);
2894 if (set_network_quoted(ifname, id, "phase1", buf) < 0)
2895 return -2;
2896 }
2897
2898 return 1;
2899}
2900
2901
Jouni Malinenf7222712019-06-13 01:50:21 +03002902static enum sigma_cmd_result cmd_sta_set_eapfast(struct sigma_dut *dut,
2903 struct sigma_conn *conn,
2904 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002905{
2906 const char *intf = get_param(cmd, "Interface");
2907 const char *ifname, *val;
2908 int id;
2909 char buf[100];
2910
2911 if (intf == NULL)
2912 return -1;
2913
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002914 if (strcmp(intf, get_main_ifname(dut)) == 0)
2915 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002916 else
2917 ifname = intf;
2918
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302919 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002920 if (id < 0)
2921 return id;
2922
2923 if (set_network(ifname, id, "eap", "FAST") < 0)
2924 return -2;
2925
2926 val = get_param(cmd, "innerEAP");
2927 if (val) {
2928 if (strcasecmp(val, "MSCHAPV2") == 0) {
2929 if (set_network_quoted(ifname, id, "phase2",
2930 "auth=MSCHAPV2") < 0)
2931 return -2;
2932 } else if (strcasecmp(val, "GTC") == 0) {
2933 if (set_network_quoted(ifname, id, "phase2",
2934 "auth=GTC") < 0)
2935 return -2;
2936 } else
2937 return -1;
2938 }
2939
2940 val = get_param(cmd, "validateServer");
2941 if (val) {
2942 /* TODO */
2943 sigma_dut_print(dut, DUT_MSG_INFO, "Ignored EAP-FAST "
2944 "validateServer=%s", val);
2945 }
2946
2947 val = get_param(cmd, "pacFile");
2948 if (val) {
2949 snprintf(buf, sizeof(buf), "blob://%s", val);
2950 if (set_network_quoted(ifname, id, "pac_file", buf) < 0)
2951 return -2;
2952 }
2953
2954 if (set_network_quoted(ifname, id, "phase1", "fast_provisioning=2") <
2955 0)
2956 return -2;
2957
2958 return 1;
2959}
2960
2961
Jouni Malinenf7222712019-06-13 01:50:21 +03002962static enum sigma_cmd_result cmd_sta_set_eapaka(struct sigma_dut *dut,
2963 struct sigma_conn *conn,
2964 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002965{
2966 const char *intf = get_param(cmd, "Interface");
Purushottam Kushwahacdd8cb12019-10-04 11:33:59 +05302967 const char *username = get_param(cmd, "Username");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002968 const char *ifname;
2969 int id;
2970
2971 if (intf == NULL)
2972 return -1;
2973
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002974 if (strcmp(intf, get_main_ifname(dut)) == 0)
2975 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002976 else
2977 ifname = intf;
2978
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302979 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002980 if (id < 0)
2981 return id;
2982
Purushottam Kushwahacdd8cb12019-10-04 11:33:59 +05302983 /* RFC 5448: EAP-AKA' MUST use the leading character "6" (ASCII 36
2984 * hexadecimal).
2985 */
2986 if (username && username[0] == '6') {
2987 if (set_network(ifname, id, "eap", "AKA'") < 0)
2988 return -2;
2989 } else if (set_network(ifname, id, "eap", "AKA") < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002990 return -2;
Purushottam Kushwahacdd8cb12019-10-04 11:33:59 +05302991 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002992
2993 return 1;
2994}
2995
2996
Jouni Malinenf7222712019-06-13 01:50:21 +03002997static enum sigma_cmd_result cmd_sta_set_eapakaprime(struct sigma_dut *dut,
2998 struct sigma_conn *conn,
2999 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003000{
3001 const char *intf = get_param(cmd, "Interface");
3002 const char *ifname;
3003 int id;
3004
3005 if (intf == NULL)
3006 return -1;
3007
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003008 if (strcmp(intf, get_main_ifname(dut)) == 0)
3009 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003010 else
3011 ifname = intf;
3012
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05303013 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003014 if (id < 0)
3015 return id;
3016
3017 if (set_network(ifname, id, "eap", "AKA'") < 0)
3018 return -2;
3019
3020 return 1;
3021}
3022
3023
3024static int sta_set_open(struct sigma_dut *dut, struct sigma_conn *conn,
3025 struct sigma_cmd *cmd)
3026{
3027 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02003028 const char *network_mode = get_param(cmd, "network_mode");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003029 const char *ifname;
3030 int id;
3031
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003032 if (strcmp(intf, get_main_ifname(dut)) == 0)
3033 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003034 else
3035 ifname = intf;
3036
3037 id = add_network_common(dut, conn, ifname, cmd);
3038 if (id < 0)
3039 return id;
3040
3041 if (set_network(ifname, id, "key_mgmt", "NONE") < 0)
3042 return -2;
3043
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02003044 if (dut->program == PROGRAM_60GHZ && network_mode &&
3045 strcasecmp(network_mode, "PBSS") == 0 &&
3046 set_network(ifname, id, "pbss", "1") < 0)
3047 return -2;
3048
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003049 return 1;
3050}
3051
3052
Jouni Malinen8e3f8812020-10-05 10:02:03 +03003053static enum sigma_cmd_result sta_set_owe(struct sigma_dut *dut,
3054 struct sigma_conn *conn,
3055 struct sigma_cmd *cmd)
Jouni Malinen47dcc952017-10-09 16:43:24 +03003056{
3057 const char *intf = get_param(cmd, "Interface");
3058 const char *ifname, *val;
3059 int id;
3060
3061 if (intf == NULL)
Jouni Malinen8e3f8812020-10-05 10:02:03 +03003062 return INVALID_SEND_STATUS;
Jouni Malinen47dcc952017-10-09 16:43:24 +03003063
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003064 if (strcmp(intf, get_main_ifname(dut)) == 0)
3065 ifname = get_station_ifname(dut);
Jouni Malinen47dcc952017-10-09 16:43:24 +03003066 else
3067 ifname = intf;
3068
3069 id = set_wpa_common(dut, conn, ifname, cmd);
3070 if (id < 0)
3071 return id;
3072
3073 if (set_network(ifname, id, "key_mgmt", "OWE") < 0)
Jouni Malinen8e3f8812020-10-05 10:02:03 +03003074 return ERROR_SEND_STATUS;
Jouni Malinen47dcc952017-10-09 16:43:24 +03003075
Hu Wangdd5eed22020-07-16 12:18:03 +08003076 if (dut->owe_ptk_workaround &&
3077 set_network(ifname, id, "owe_ptk_workaround", "1") < 0) {
3078 sigma_dut_print(dut, DUT_MSG_ERROR,
3079 "Failed to set owe_ptk_workaround to 1");
Jouni Malinen8e3f8812020-10-05 10:02:03 +03003080 return ERROR_SEND_STATUS;
Hu Wangdd5eed22020-07-16 12:18:03 +08003081 }
3082
Jouni Malinen47dcc952017-10-09 16:43:24 +03003083 val = get_param(cmd, "ECGroupID");
Jouni Malinenfac9cad2017-10-10 18:35:55 +03003084 if (val && strcmp(val, "0") == 0) {
3085 if (wpa_command(ifname,
3086 "VENDOR_ELEM_ADD 13 ff23200000783590fb7440e03d5b3b33911f86affdcc6b4411b707846ac4ff08ddc8831ccd") != 0) {
3087 sigma_dut_print(dut, DUT_MSG_ERROR,
3088 "Failed to set OWE DH Param element override");
Jouni Malinen8e3f8812020-10-05 10:02:03 +03003089 return ERROR_SEND_STATUS;
Jouni Malinenfac9cad2017-10-10 18:35:55 +03003090 }
Hu Wangdd5eed22020-07-16 12:18:03 +08003091 } else if (val && set_network(ifname, id, "owe_group", val) < 0) {
Jouni Malinen47dcc952017-10-09 16:43:24 +03003092 sigma_dut_print(dut, DUT_MSG_ERROR,
Hu Wang6010ce72020-03-05 19:33:53 +08003093 "Failed to set owe_group");
Jouni Malinen8e3f8812020-10-05 10:02:03 +03003094 return ERROR_SEND_STATUS;
Jouni Malinen47dcc952017-10-09 16:43:24 +03003095 }
3096
Jouni Malinen8e3f8812020-10-05 10:02:03 +03003097 return SUCCESS_SEND_STATUS;
Jouni Malinen47dcc952017-10-09 16:43:24 +03003098}
3099
3100
Jouni Malinenf7222712019-06-13 01:50:21 +03003101static enum sigma_cmd_result cmd_sta_set_security(struct sigma_dut *dut,
3102 struct sigma_conn *conn,
3103 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003104{
3105 const char *type = get_param(cmd, "Type");
3106
3107 if (type == NULL) {
3108 send_resp(dut, conn, SIGMA_ERROR,
3109 "ErrorCode,Missing Type argument");
3110 return 0;
3111 }
3112
3113 if (strcasecmp(type, "OPEN") == 0)
3114 return sta_set_open(dut, conn, cmd);
Jouni Malinen47dcc952017-10-09 16:43:24 +03003115 if (strcasecmp(type, "OWE") == 0)
3116 return sta_set_owe(dut, conn, cmd);
Jouni Malinen992a81e2017-08-22 13:57:47 +03003117 if (strcasecmp(type, "PSK") == 0 ||
Jouni Malinen0ab50f42017-08-31 01:34:59 +03003118 strcasecmp(type, "PSK-SAE") == 0 ||
Jouni Malinen992a81e2017-08-22 13:57:47 +03003119 strcasecmp(type, "SAE") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003120 return cmd_sta_set_psk(dut, conn, cmd);
3121 if (strcasecmp(type, "EAPTLS") == 0)
3122 return cmd_sta_set_eaptls(dut, conn, cmd);
3123 if (strcasecmp(type, "EAPTTLS") == 0)
3124 return cmd_sta_set_eapttls(dut, conn, cmd);
3125 if (strcasecmp(type, "EAPPEAP") == 0)
3126 return cmd_sta_set_peap(dut, conn, cmd);
3127 if (strcasecmp(type, "EAPSIM") == 0)
3128 return cmd_sta_set_eapsim(dut, conn, cmd);
3129 if (strcasecmp(type, "EAPFAST") == 0)
3130 return cmd_sta_set_eapfast(dut, conn, cmd);
3131 if (strcasecmp(type, "EAPAKA") == 0)
3132 return cmd_sta_set_eapaka(dut, conn, cmd);
3133 if (strcasecmp(type, "EAPAKAPRIME") == 0)
3134 return cmd_sta_set_eapakaprime(dut, conn, cmd);
Amarnath Hullur Subramanyam81b11cd2018-01-30 19:07:17 -08003135 if (strcasecmp(type, "wep") == 0)
3136 return cmd_sta_set_encryption(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003137
3138 send_resp(dut, conn, SIGMA_ERROR,
3139 "ErrorCode,Unsupported Type value");
3140 return 0;
3141}
3142
3143
3144int ath6kl_client_uapsd(struct sigma_dut *dut, const char *intf, int uapsd)
3145{
3146#ifdef __linux__
3147 /* special handling for ath6kl */
3148 char path[128], fname[128], *pos;
3149 ssize_t res;
3150 FILE *f;
3151
Jouni Malinene39cd562019-05-29 23:39:56 +03003152 res = snprintf(fname, sizeof(fname), "/sys/class/net/%s/phy80211",
3153 intf);
3154 if (res < 0 || res >= sizeof(fname))
3155 return 0;
3156 res = readlink(fname, path, sizeof(path));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003157 if (res < 0)
3158 return 0; /* not ath6kl */
3159
3160 if (res >= (int) sizeof(path))
3161 res = sizeof(path) - 1;
3162 path[res] = '\0';
3163 pos = strrchr(path, '/');
3164 if (pos == NULL)
3165 pos = path;
3166 else
3167 pos++;
Jouni Malinen77dda642020-01-07 11:21:55 +02003168 res = snprintf(fname, sizeof(fname),
3169 "/sys/kernel/debug/ieee80211/%s/ath6kl/"
3170 "create_qos", pos);
3171 if (res < 0 || res >= sizeof(fname) || !file_exists(fname))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003172 return 0; /* not ath6kl */
3173
3174 if (uapsd) {
3175 f = fopen(fname, "w");
3176 if (f == NULL)
3177 return -1;
3178
3179 sigma_dut_print(dut, DUT_MSG_DEBUG, "Use ath6kl create_qos");
3180 fprintf(f, "4 2 2 1 2 9999999 9999999 9999999 7777777 0 4 "
3181 "45000 200 56789000 56789000 5678900 0 0 9999999 "
3182 "20000 0\n");
3183 fclose(f);
3184 } else {
Jouni Malinen77dda642020-01-07 11:21:55 +02003185 res = snprintf(fname, sizeof(fname),
3186 "/sys/kernel/debug/ieee80211/%s/ath6kl/"
3187 "delete_qos", pos);
3188 if (res < 0 || res >= sizeof(fname))
3189 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003190
3191 f = fopen(fname, "w");
3192 if (f == NULL)
3193 return -1;
3194
3195 sigma_dut_print(dut, DUT_MSG_DEBUG, "Use ath6kl delete_qos");
3196 fprintf(f, "2 4\n");
3197 fclose(f);
3198 }
3199#endif /* __linux__ */
3200
3201 return 0;
3202}
3203
3204
Jouni Malinenf7222712019-06-13 01:50:21 +03003205static enum sigma_cmd_result cmd_sta_set_uapsd(struct sigma_dut *dut,
3206 struct sigma_conn *conn,
3207 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003208{
3209 const char *intf = get_param(cmd, "Interface");
3210 /* const char *ssid = get_param(cmd, "ssid"); */
3211 const char *val;
3212 int max_sp_len = 4;
3213 int ac_be = 1, ac_bk = 1, ac_vi = 1, ac_vo = 1;
3214 char buf[100];
3215 int ret1, ret2;
3216
3217 val = get_param(cmd, "maxSPLength");
3218 if (val) {
3219 max_sp_len = atoi(val);
3220 if (max_sp_len != 0 && max_sp_len != 1 && max_sp_len != 2 &&
3221 max_sp_len != 4)
3222 return -1;
3223 }
3224
3225 val = get_param(cmd, "acBE");
3226 if (val)
3227 ac_be = atoi(val);
3228
3229 val = get_param(cmd, "acBK");
3230 if (val)
3231 ac_bk = atoi(val);
3232
3233 val = get_param(cmd, "acVI");
3234 if (val)
3235 ac_vi = atoi(val);
3236
3237 val = get_param(cmd, "acVO");
3238 if (val)
3239 ac_vo = atoi(val);
3240
3241 dut->client_uapsd = ac_be || ac_bk || ac_vi || ac_vo;
3242
3243 snprintf(buf, sizeof(buf), "P2P_SET client_apsd %d,%d,%d,%d;%d",
3244 ac_be, ac_bk, ac_vi, ac_vo, max_sp_len);
3245 ret1 = wpa_command(intf, buf);
3246
3247 snprintf(buf, sizeof(buf), "SET uapsd %d,%d,%d,%d;%d",
3248 ac_be, ac_bk, ac_vi, ac_vo, max_sp_len);
3249 ret2 = wpa_command(intf, buf);
3250
3251 if (ret1 && ret2) {
3252 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to set client mode "
3253 "UAPSD parameters.");
3254 return -2;
3255 }
3256
3257 if (ath6kl_client_uapsd(dut, intf, dut->client_uapsd) < 0) {
3258 send_resp(dut, conn, SIGMA_ERROR,
3259 "ErrorCode,Failed to set ath6kl QoS parameters");
3260 return 0;
3261 }
3262
3263 return 1;
3264}
3265
3266
Jouni Malinenf7222712019-06-13 01:50:21 +03003267static enum sigma_cmd_result cmd_sta_set_wmm(struct sigma_dut *dut,
3268 struct sigma_conn *conn,
3269 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003270{
3271 char buf[1000];
3272 const char *intf = get_param(cmd, "Interface");
3273 const char *grp = get_param(cmd, "Group");
3274 const char *act = get_param(cmd, "Action");
3275 const char *tid = get_param(cmd, "Tid");
3276 const char *dir = get_param(cmd, "Direction");
3277 const char *psb = get_param(cmd, "Psb");
3278 const char *up = get_param(cmd, "Up");
3279 const char *fixed = get_param(cmd, "Fixed");
3280 const char *size = get_param(cmd, "Size");
3281 const char *msize = get_param(cmd, "Maxsize");
3282 const char *minsi = get_param(cmd, "Min_srvc_intrvl");
3283 const char *maxsi = get_param(cmd, "Max_srvc_intrvl");
3284 const char *inact = get_param(cmd, "Inactivity");
3285 const char *sus = get_param(cmd, "Suspension");
3286 const char *mindr = get_param(cmd, "Mindatarate");
3287 const char *meandr = get_param(cmd, "Meandatarate");
3288 const char *peakdr = get_param(cmd, "Peakdatarate");
3289 const char *phyrate = get_param(cmd, "Phyrate");
3290 const char *burstsize = get_param(cmd, "Burstsize");
3291 const char *sba = get_param(cmd, "Sba");
3292 int direction;
3293 int handle;
Peng Xu93319622017-10-04 17:58:16 -07003294 float sba_fv = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003295 int fixed_int;
3296 int psb_ts;
3297
3298 if (intf == NULL || grp == NULL || act == NULL )
3299 return -1;
3300
3301 if (strcasecmp(act, "addts") == 0) {
3302 if (tid == NULL || dir == NULL || psb == NULL ||
3303 up == NULL || fixed == NULL || size == NULL)
3304 return -1;
3305
3306 /*
3307 * Note: Sigma CAPI spec lists uplink, downlink, and bidi as the
3308 * possible values, but WMM-AC and V-E test scripts use "UP,
3309 * "DOWN", and "BIDI".
3310 */
3311 if (strcasecmp(dir, "uplink") == 0 ||
3312 strcasecmp(dir, "up") == 0) {
3313 direction = 0;
3314 } else if (strcasecmp(dir, "downlink") == 0 ||
3315 strcasecmp(dir, "down") == 0) {
3316 direction = 1;
3317 } else if (strcasecmp(dir, "bidi") == 0) {
3318 direction = 2;
3319 } else {
3320 sigma_dut_print(dut, DUT_MSG_ERROR,
3321 "Direction %s not supported", dir);
3322 return -1;
3323 }
3324
3325 if (strcasecmp(psb, "legacy") == 0) {
3326 psb_ts = 0;
3327 } else if (strcasecmp(psb, "uapsd") == 0) {
3328 psb_ts = 1;
3329 } else {
3330 sigma_dut_print(dut, DUT_MSG_ERROR,
3331 "PSB %s not supported", psb);
3332 return -1;
3333 }
3334
3335 if (atoi(tid) < 0 || atoi(tid) > 7) {
3336 sigma_dut_print(dut, DUT_MSG_ERROR,
3337 "TID %s not supported", tid);
3338 return -1;
3339 }
3340
3341 if (strcasecmp(fixed, "true") == 0) {
3342 fixed_int = 1;
3343 } else {
3344 fixed_int = 0;
3345 }
3346
Peng Xu93319622017-10-04 17:58:16 -07003347 if (sba)
3348 sba_fv = atof(sba);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003349
3350 dut->dialog_token++;
3351 handle = 7000 + dut->dialog_token;
3352
3353 /*
3354 * size: convert to hex
3355 * maxsi: convert to hex
3356 * mindr: convert to hex
3357 * meandr: convert to hex
3358 * peakdr: convert to hex
3359 * burstsize: convert to hex
3360 * phyrate: convert to hex
3361 * sba: convert to hex with modification
3362 * minsi: convert to integer
3363 * sus: convert to integer
3364 * inact: convert to integer
3365 * maxsi: convert to integer
3366 */
3367
3368 /*
3369 * The Nominal MSDU Size field is 2 octets long and contains an
3370 * unsigned integer that specifies the nominal size, in octets,
3371 * of MSDUs belonging to the traffic under this traffic
3372 * specification and is defined in Figure 16. If the Fixed
3373 * subfield is set to 1, then the size of the MSDU is fixed and
3374 * is indicated by the Size Subfield. If the Fixed subfield is
3375 * set to 0, then the size of the MSDU might not be fixed and
3376 * the Size indicates the nominal MSDU size.
3377 *
3378 * The Surplus Bandwidth Allowance Factor field is 2 octets long
3379 * and specifies the excess allocation of time (and bandwidth)
3380 * over and above the stated rates required to transport an MSDU
3381 * belonging to the traffic in this TSPEC. This field is
3382 * represented as an unsigned binary number with an implicit
3383 * binary point after the leftmost 3 bits. For example, an SBA
3384 * of 1.75 is represented as 0x3800. This field is included to
3385 * account for retransmissions. As such, the value of this field
3386 * must be greater than unity.
3387 */
3388
3389 snprintf(buf, sizeof(buf),
3390 "iwpriv %s addTspec %d %s %d %d %s 0x%X"
3391 " 0x%X 0x%X 0x%X"
3392 " 0x%X 0x%X 0x%X"
3393 " 0x%X %d %d %d %d"
3394 " %d %d",
3395 intf, handle, tid, direction, psb_ts, up,
3396 (unsigned int) ((fixed_int << 15) | atoi(size)),
3397 msize ? atoi(msize) : 0,
3398 mindr ? atoi(mindr) : 0,
3399 meandr ? atoi(meandr) : 0,
3400 peakdr ? atoi(peakdr) : 0,
3401 burstsize ? atoi(burstsize) : 0,
3402 phyrate ? atoi(phyrate) : 0,
3403 sba ? ((unsigned int) (((int) sba_fv << 13) |
3404 (int)((sba_fv - (int) sba_fv) *
3405 8192))) : 0,
3406 minsi ? atoi(minsi) : 0,
3407 sus ? atoi(sus) : 0,
3408 0, 0,
3409 inact ? atoi(inact) : 0,
3410 maxsi ? atoi(maxsi) : 0);
3411
3412 if (system(buf) != 0) {
3413 sigma_dut_print(dut, DUT_MSG_ERROR,
3414 "iwpriv addtspec request failed");
3415 send_resp(dut, conn, SIGMA_ERROR,
3416 "errorCode,Failed to execute addTspec command");
3417 return 0;
3418 }
3419
3420 sigma_dut_print(dut, DUT_MSG_INFO,
3421 "iwpriv addtspec request send");
3422
3423 /* Mapping handle to a TID */
3424 dut->tid_to_handle[atoi(tid)] = handle;
3425 } else if (strcasecmp(act, "delts") == 0) {
3426 if (tid == NULL)
3427 return -1;
3428
3429 if (atoi(tid) < 0 || atoi(tid) > 7) {
3430 sigma_dut_print(dut, DUT_MSG_ERROR,
3431 "TID %s not supported", tid);
3432 send_resp(dut, conn, SIGMA_ERROR,
3433 "errorCode,Unsupported TID");
3434 return 0;
3435 }
3436
3437 handle = dut->tid_to_handle[atoi(tid)];
3438
3439 if (handle < 7000 || handle > 7255) {
3440 /* Invalid handle ie no mapping for that TID */
3441 sigma_dut_print(dut, DUT_MSG_ERROR,
3442 "handle-> %d not found", handle);
3443 }
3444
3445 snprintf(buf, sizeof(buf), "iwpriv %s delTspec %d",
3446 intf, handle);
3447
3448 if (system(buf) != 0) {
3449 sigma_dut_print(dut, DUT_MSG_ERROR,
3450 "iwpriv deltspec request failed");
3451 send_resp(dut, conn, SIGMA_ERROR,
3452 "errorCode,Failed to execute delTspec command");
3453 return 0;
3454 }
3455
3456 sigma_dut_print(dut, DUT_MSG_INFO,
3457 "iwpriv deltspec request send");
3458
3459 dut->tid_to_handle[atoi(tid)] = 0;
3460 } else {
3461 sigma_dut_print(dut, DUT_MSG_ERROR,
3462 "Action type %s not supported", act);
3463 send_resp(dut, conn, SIGMA_ERROR,
3464 "errorCode,Unsupported Action");
3465 return 0;
3466 }
3467
3468 return 1;
3469}
3470
3471
vamsi krishna52e16f92017-08-29 12:37:34 +05303472static int find_network(struct sigma_dut *dut, const char *ssid)
3473{
3474 char list[4096];
3475 char *pos;
3476
3477 sigma_dut_print(dut, DUT_MSG_DEBUG,
3478 "Search for profile based on SSID: '%s'", ssid);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003479 if (wpa_command_resp(get_station_ifname(dut), "LIST_NETWORKS",
vamsi krishna52e16f92017-08-29 12:37:34 +05303480 list, sizeof(list)) < 0)
3481 return -1;
3482 pos = strstr(list, ssid);
3483 if (!pos || pos == list || pos[-1] != '\t' || pos[strlen(ssid)] != '\t')
3484 return -1;
3485
3486 while (pos > list && pos[-1] != '\n')
3487 pos--;
3488 dut->infra_network_id = atoi(pos);
3489 snprintf(dut->infra_ssid, sizeof(dut->infra_ssid), "%s", ssid);
3490 return 0;
3491}
3492
3493
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05303494/**
3495 * enum qca_sta_helper_config_params - This helper enum defines the config
3496 * parameters which can be delivered to sta.
3497 */
3498enum qca_sta_helper_config_params {
3499 /* For the attribute QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE */
3500 STA_SET_RSNIE,
3501
3502 /* For the attribute QCA_WLAN_VENDOR_ATTR_CONFIG_LDPC */
3503 STA_SET_LDPC,
3504
3505 /* For the attribute QCA_WLAN_VENDOR_ATTR_CONFIG_TX_STBC */
3506 STA_SET_TX_STBC,
3507
3508 /* For the attribute QCA_WLAN_VENDOR_ATTR_CONFIG_RX_STBC */
3509 STA_SET_RX_STBC,
3510
3511 /* For the attribute QCA_WLAN_VENDOR_ATTR_CONFIG_TX_MSDU_AGGREGATION */
3512 STA_SET_TX_MSDU,
3513
3514 /* For the attribute QCA_WLAN_VENDOR_ATTR_CONFIG_RX_MSDU_AGGREGATION */
3515 STA_SET_RX_MSDU,
Shivani Baranwal2a572842021-09-16 12:27:15 +05303516
3517 /* For the attribute QCA_WLAN_VENDOR_ATTR_CONFIG_CHANNEL_WIDTH */
3518 STA_SET_CHAN_WIDTH,
Shivani Baranwal7aa48602021-09-29 10:53:38 +05303519
3520 /* For the attribute QCA_WLAN_VENDOR_ATTR_CONFIG_FT_OVER_DS */
3521 STA_SET_FT_DS,
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05303522};
3523
3524
3525static int sta_config_params(struct sigma_dut *dut, const char *intf,
3526 enum qca_sta_helper_config_params config_cmd,
3527 int value)
Sunil Dutt44595082018-02-12 19:41:45 +05303528{
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05303529#ifdef NL80211_SUPPORT
Sunil Dutt44595082018-02-12 19:41:45 +05303530 struct nl_msg *msg;
3531 int ret;
3532 struct nlattr *params;
3533 int ifindex;
3534
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05303535 ifindex = if_nametoindex(intf);
3536 if (ifindex == 0) {
3537 sigma_dut_print(dut, DUT_MSG_ERROR,
3538 "%s: Interface %s does not exist",
3539 __func__, intf);
3540 return -1;
3541 }
3542
Sunil Dutt44595082018-02-12 19:41:45 +05303543 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
3544 NL80211_CMD_VENDOR)) ||
3545 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
3546 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
3547 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
3548 QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION) ||
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05303549 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)))
3550 goto fail;
3551
3552 switch (config_cmd) {
3553 case STA_SET_RSNIE:
3554 if (nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE, value))
3555 goto fail;
3556 break;
3557 case STA_SET_LDPC:
3558 if (nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_LDPC, value))
3559 goto fail;
3560 break;
3561 case STA_SET_TX_STBC:
3562 if (nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TX_STBC, value))
3563 goto fail;
3564 break;
3565 case STA_SET_RX_STBC:
3566 if (nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_RX_STBC, value))
3567 goto fail;
3568 break;
3569 case STA_SET_TX_MSDU:
3570 if (nla_put_u8(msg,
3571 QCA_WLAN_VENDOR_ATTR_CONFIG_TX_MSDU_AGGREGATION,
3572 value))
3573 goto fail;
3574 break;
3575 case STA_SET_RX_MSDU:
3576 if (nla_put_u8(msg,
3577 QCA_WLAN_VENDOR_ATTR_CONFIG_RX_MSDU_AGGREGATION,
3578 value))
3579 goto fail;
3580 break;
Shivani Baranwal2a572842021-09-16 12:27:15 +05303581 case STA_SET_CHAN_WIDTH:
3582 if (nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_CHANNEL_WIDTH,
3583 value))
3584 goto fail;
3585 break;
Shivani Baranwal7aa48602021-09-29 10:53:38 +05303586 case STA_SET_FT_DS:
3587 if (nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_FT_OVER_DS,
3588 value))
3589 goto fail;
3590 break;
Sunil Dutt44595082018-02-12 19:41:45 +05303591 }
3592 nla_nest_end(msg, params);
3593
3594 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
3595 if (ret) {
3596 sigma_dut_print(dut, DUT_MSG_ERROR,
3597 "%s: err in send_and_recv_msgs, ret=%d",
3598 __func__, ret);
3599 return ret;
3600 }
3601
3602 return 0;
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05303603
3604fail:
3605 sigma_dut_print(dut, DUT_MSG_ERROR,
3606 "%s: err in adding vendor_cmd and vendor_data",
3607 __func__);
3608 nlmsg_free(msg);
Sunil Dutt44595082018-02-12 19:41:45 +05303609#endif /* NL80211_SUPPORT */
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05303610 return -1;
3611}
Sunil Dutt44595082018-02-12 19:41:45 +05303612
3613
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05303614void free_dscp_policy_table(struct sigma_dut *dut)
3615{
3616 struct dscp_policy_data *dscp_policy;
3617
3618 while (dut->dscp_policy_table) {
3619 dscp_policy = dut->dscp_policy_table;
3620 dut->dscp_policy_table = dscp_policy->next;
3621 free(dscp_policy);
3622 }
3623}
3624
3625
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05303626static char * protocol_to_str(int proto)
3627{
3628 switch (proto) {
3629 case 6:
3630 return "tcp";
3631 case 17:
3632 return "udp";
3633 case 50:
3634 return "esp";
3635 default:
3636 return "unknown";
3637 }
3638}
3639
3640
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05303641static int delete_nft_table(struct sigma_dut *dut, const char *table,
3642 const char *ip_type)
3643{
3644 int res;
3645 char cmd[200];
3646
3647 res = snprintf(cmd, sizeof(cmd), "nft delete table %s %s_%s", ip_type,
3648 table, ip_type);
3649 if (snprintf_error(sizeof(cmd), res)) {
3650 sigma_dut_print(dut, DUT_MSG_ERROR,
3651 "Failed to create delete table command");
3652 return -1;
3653 }
3654
3655 if (system(cmd) != 0) {
3656 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to run %s", cmd);
3657 return -1;
3658 }
3659
3660 return 0;
3661}
3662
3663
3664static int remove_nft_rule(struct sigma_dut *dut, int policy_id,
3665 enum ip_version ip_ver)
3666{
3667 int res;
3668 char table[50];
3669
3670 res = snprintf(table, sizeof(table), "wifi_%s_dscp_policy_%d",
3671 dut->station_ifname, policy_id);
3672 if (snprintf_error(sizeof(table), res)) {
3673 sigma_dut_print(dut, DUT_MSG_INFO,
3674 "Failed to create table name for policy %d",
3675 policy_id);
3676 return -1;
3677 }
3678
3679
3680 if (ip_ver == IPV6)
3681 return delete_nft_table(dut, table, "ip6");
3682 else
3683 return delete_nft_table(dut, table, "ip");
3684}
3685
3686
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05303687static int remove_iptable_rule(struct sigma_dut *dut,
3688 struct dscp_policy_data *dscp_policy)
3689{
3690 char ip_cmd[1000];
3691 char *pos;
3692 int ret, len;
3693 enum ip_version ip_ver = dscp_policy->ip_version;
3694
3695 pos = ip_cmd;
3696 len = sizeof(ip_cmd);
3697
3698 ret = snprintf(pos, len,
Shivani Baranwalbf2b5212021-12-08 16:38:23 +05303699 "%s -t mangle -D OUTPUT -o %s",
3700#ifdef ANDROID
3701 ip_ver == IPV6 ? "/system/bin/ip6tables" : "/system/bin/iptables",
3702#else /* ANDROID */
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05303703 ip_ver == IPV6 ? "ip6tables" : "iptables",
Shivani Baranwalbf2b5212021-12-08 16:38:23 +05303704#endif /* ANDROID */
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05303705 dut->station_ifname);
3706 if (snprintf_error(len, ret)) {
3707 sigma_dut_print(dut, DUT_MSG_INFO,
3708 "Failed to create delete iptables command %s",
3709 ip_cmd);
3710 return -1;
3711 }
3712
3713 pos += ret;
3714 len -= ret;
3715
3716 if (strlen(dscp_policy->src_ip)) {
3717 ret = snprintf(pos, len, " -s %s", dscp_policy->src_ip);
3718 if (snprintf_error(len, ret)) {
3719 sigma_dut_print(dut, DUT_MSG_INFO,
3720 "Error in adding src_ip %s in delete command",
3721 dscp_policy->src_ip);
3722 return -1;
3723 }
3724 pos += ret;
3725 len -= ret;
3726 }
3727
3728 if (strlen(dscp_policy->dst_ip)) {
3729 ret = snprintf(pos, len, " -d %s",
3730 dscp_policy->dst_ip);
3731 if (snprintf_error(len, ret)) {
3732 sigma_dut_print(dut, DUT_MSG_INFO,
3733 "Error in adding dst_ip %s in delete cmd",
3734 dscp_policy->dst_ip);
3735 return -1;
3736 }
3737 pos += ret;
3738 len -= ret;
3739 }
3740
3741 if (dscp_policy->src_port || dscp_policy->dst_port ||
3742 (dscp_policy->start_port && dscp_policy->end_port)) {
3743 ret = snprintf(pos, len, " -p %s",
3744 protocol_to_str(dscp_policy->protocol));
3745 if (snprintf_error(len, ret)) {
3746 sigma_dut_print(dut, DUT_MSG_INFO,
3747 "Error in adding protocol %d in delete command",
3748 dscp_policy->protocol);
3749 return -1;
3750 }
3751 pos += ret;
3752 len -= ret;
3753 }
3754
3755 if (dscp_policy->src_port) {
3756 ret = snprintf(pos, len, " --sport %d",
3757 dscp_policy->src_port);
3758 if (snprintf_error(len, ret)) {
3759 sigma_dut_print(dut, DUT_MSG_INFO,
3760 "Error in adding src_port %d in delete command",
3761 dscp_policy->src_port);
3762 return -1;
3763 }
3764 pos += ret;
3765 len -= ret;
3766 }
3767
3768 if (dscp_policy->dst_port) {
3769 ret = snprintf(pos, len, " --dport %d",
3770 dscp_policy->dst_port);
3771 if (snprintf_error(len, ret)) {
3772 sigma_dut_print(dut, DUT_MSG_INFO,
3773 "Error in adding dst_port %d in delete command",
3774 dscp_policy->dst_port);
3775 return -1;
3776 }
3777 pos += ret;
3778 len -= ret;
3779 }
3780
3781 if (dscp_policy->start_port && dscp_policy->end_port) {
3782 ret = snprintf(pos, len, " --match multiport --dports %d:%d",
3783 dscp_policy->start_port,
3784 dscp_policy->end_port);
3785 if (snprintf_error(len, ret)) {
3786 sigma_dut_print(dut, DUT_MSG_INFO,
3787 "Error in adding start:end port %d:%d in delete command",
3788 dscp_policy->start_port,
3789 dscp_policy->end_port);
3790 return -1;
3791 }
3792 pos += ret;
3793 len -= ret;
3794 }
3795
3796 ret = snprintf(pos, len, " -j DSCP --set-dscp 0x%0x",
3797 dscp_policy->dscp);
3798 if (snprintf_error(len, ret)) {
3799 sigma_dut_print(dut, DUT_MSG_INFO,
3800 "Error in adding dscp %0x in delete command",
3801 dscp_policy->dscp);
3802 return -1;
3803 }
3804 ret = system(ip_cmd);
3805 sigma_dut_print(dut, DUT_MSG_DEBUG, "iptables rule: %s err: %d",
3806 ip_cmd, ret);
3807
3808 return ret;
3809}
3810
3811
3812static int remove_dscp_policy_rule(struct sigma_dut *dut,
3813 struct dscp_policy_data *dscp_policy)
3814{
3815 return dut->dscp_use_iptables ? remove_iptable_rule(dut, dscp_policy) :
3816 remove_nft_rule(dut, dscp_policy->policy_id,
3817 dscp_policy->ip_version);
3818}
3819
3820
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05303821static int create_nft_table(struct sigma_dut *dut, int policy_id,
3822 const char *table_name, enum ip_version ip_ver)
3823{
3824 char cmd[200];
3825 int res;
3826
3827 res = snprintf(cmd, sizeof(cmd), "nft add table %s %s",
3828 ip_ver == IPV6 ? "ip6" : "ip", table_name);
3829 if (snprintf_error(sizeof(cmd), res)) {
3830 sigma_dut_print(dut, DUT_MSG_INFO,
3831 "Failed to add rule to create table for policy id %d",
3832 policy_id);
3833 return -1;
3834 }
3835
3836 if (system(cmd) != 0) {
3837 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to run %s", cmd);
3838 return -1;
3839 }
3840
3841 res = snprintf(cmd, sizeof(cmd),
3842 "nft add chain %s %s OUTPUT { type filter hook output priority 0 \\; }",
3843 ip_ver == IPV6 ? "ip6" : "ip", table_name);
3844 if (snprintf_error(sizeof(cmd), res)) {
3845 sigma_dut_print(dut, DUT_MSG_INFO,
3846 "Failed to add rule to create chain for table = %s",
3847 table_name);
3848 return -1;
3849 }
3850
3851 if (system(cmd) != 0) {
3852 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to run %s", cmd);
3853 return -1;
3854 }
3855
3856 return 0;
3857}
3858
3859
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05303860static int remove_dscp_policy(struct sigma_dut *dut, u8 policy_id)
3861{
3862 struct dscp_policy_data *dscp_policy = dut->dscp_policy_table;
3863 struct dscp_policy_data *prev = NULL;
3864
3865 while (dscp_policy) {
3866 if (dscp_policy->policy_id == policy_id)
3867 break;
3868
3869 prev = dscp_policy;
3870 dscp_policy = dscp_policy->next;
3871 }
3872
3873 /*
3874 * Consider remove request for a policy id which does not exist as
3875 * success.
3876 */
3877 if (!dscp_policy)
3878 return 0;
3879
3880 if (strlen(dscp_policy->domain_name) == 0 &&
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05303881 remove_dscp_policy_rule(dut, dscp_policy))
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05303882 return -1;
3883
3884 if (prev)
3885 prev->next = dscp_policy->next;
3886 else
3887 dut->dscp_policy_table = dscp_policy->next;
3888
3889 free(dscp_policy);
3890 return 0;
3891}
3892
3893
3894static int add_nft_rule(struct sigma_dut *dut,
3895 struct dscp_policy_data *dscp_policy)
3896{
3897 char nft_cmd[1000], ip[4], table_name[100];
3898 char *pos;
3899 int ret, len, policy_id = dscp_policy->policy_id;
3900 enum ip_version ip_ver = dscp_policy->ip_version;
3901
3902 if (ip_ver == IPV6)
3903 strlcpy(ip, "ip6", sizeof(ip));
3904 else
3905 strlcpy(ip, "ip", sizeof(ip));
3906
3907 ret = snprintf(table_name, sizeof(table_name),
3908 "wifi_%s_dscp_policy_%d_%s",
3909 dut->station_ifname, policy_id, ip);
3910 if (snprintf_error(sizeof(table_name), ret))
3911 return -1;
3912
3913 if (create_nft_table(dut, policy_id, table_name, ip_ver)) {
3914 sigma_dut_print(dut, DUT_MSG_INFO,
3915 "Failed to create nft table");
3916 return -1;
3917 }
3918
3919 pos = nft_cmd;
3920 len = sizeof(nft_cmd);
3921
3922 ret = snprintf(pos, len,
3923 "nft add rule %s %s OUTPUT oifname \"%s\"",
3924 ip, table_name, dut->station_ifname);
3925 if (snprintf_error(len, ret)) {
3926 sigma_dut_print(dut, DUT_MSG_INFO,
3927 "Failed to create nft cmd %s", nft_cmd);
3928 return -1;
3929 }
3930
3931 pos += ret;
3932 len -= ret;
3933
3934 if (strlen(dscp_policy->src_ip)) {
3935 ret = snprintf(pos, len, " %s saddr %s", ip,
3936 dscp_policy->src_ip);
3937 if (snprintf_error(len, ret))
3938 return -1;
3939
3940 pos += ret;
3941 len -= ret;
3942 }
3943
3944 if (strlen(dscp_policy->dst_ip)) {
3945 ret = snprintf(pos, len, " %s daddr %s", ip,
3946 dscp_policy->dst_ip);
3947 if (snprintf_error(len, ret))
3948 return -1;
3949
3950 pos += ret;
3951 len -= ret;
3952 }
3953
3954 if (dscp_policy->src_port) {
3955 ret = snprintf(pos, len, " %s sport %d",
3956 protocol_to_str(dscp_policy->protocol),
3957 dscp_policy->src_port);
3958 if (snprintf_error(len, ret))
3959 return -1;
3960
3961 pos += ret;
3962 len -= ret;
3963 }
3964
3965 if (dscp_policy->dst_port) {
3966 ret = snprintf(pos, len, " %s dport %d",
3967 protocol_to_str(dscp_policy->protocol),
3968 dscp_policy->dst_port);
3969 if (snprintf_error(len, ret))
3970 return -1;
3971
3972 pos += ret;
3973 len -= ret;
3974 }
3975
3976 if (dscp_policy->start_port && dscp_policy->end_port) {
3977 ret = snprintf(pos, len, " %s dport %d-%d",
3978 protocol_to_str(dscp_policy->protocol),
3979 dscp_policy->start_port,
3980 dscp_policy->end_port);
3981 if (snprintf_error(len, ret))
3982 return -1;
3983
3984 pos += ret;
3985 len -= ret;
3986 }
3987
3988 ret = snprintf(pos, len, " counter %s dscp set 0x%0x", ip,
3989 dscp_policy->dscp);
3990 if (snprintf_error(len, ret))
3991 return -1;
3992
3993 ret = system(nft_cmd);
3994 sigma_dut_print(dut, DUT_MSG_INFO, "nft rule: %s err: %d",
3995 nft_cmd, ret);
3996
3997 return ret;
3998}
3999
4000
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304001static int add_iptable_rule(struct sigma_dut *dut,
4002 struct dscp_policy_data *dscp_policy)
4003{
4004 char ip_cmd[1000];
4005 char *pos;
4006 int ret, len;
4007 enum ip_version ip_ver = dscp_policy->ip_version;
4008 struct dscp_policy_data *active_policy = dut->dscp_policy_table;
4009 int ipv4_rule_num = 1, ipv6_rule_num = 1;
4010
4011 pos = ip_cmd;
4012 len = sizeof(ip_cmd);
4013
4014 /*
4015 * DSCP target in the mangle table doesn't stop processing of rules
4016 * so to make sure the most granular rule is applied last, add the new
4017 * rules in granularity increasing order.
4018 */
4019 while (active_policy) {
4020 /*
4021 * Domain name rules are managed in sigma_dut thus don't count
4022 * them while counting the number of active rules.
4023 */
4024 if (strlen(active_policy->domain_name)) {
4025 active_policy = active_policy->next;
4026 continue;
4027 }
4028
4029 if (active_policy->granularity_score >
4030 dscp_policy->granularity_score)
4031 break;
4032
4033 if (active_policy->ip_version == IPV6)
4034 ipv6_rule_num++;
4035 else
4036 ipv4_rule_num++;
4037
4038 active_policy = active_policy->next;
4039 }
4040
4041 ret = snprintf(pos, len,
Shivani Baranwalbf2b5212021-12-08 16:38:23 +05304042 "%s -t mangle -I OUTPUT %d -o %s",
4043#ifdef ANDROID
4044 ip_ver == IPV6 ? "/system/bin/ip6tables" : "/system/bin/iptables",
4045#else /* ANDROID */
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304046 ip_ver == IPV6 ? "ip6tables" : "iptables",
Shivani Baranwalbf2b5212021-12-08 16:38:23 +05304047#endif /* ANDROID */
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304048 ip_ver == IPV6 ? ipv6_rule_num : ipv4_rule_num,
4049 dut->station_ifname);
4050 if (snprintf_error(len, ret)) {
4051 sigma_dut_print(dut, DUT_MSG_INFO,
4052 "Failed to create iptables command %s", ip_cmd);
4053 return -1;
4054 }
4055
4056 pos += ret;
4057 len -= ret;
4058
4059 if (strlen(dscp_policy->src_ip)) {
4060 ret = snprintf(pos, len, " -s %s", dscp_policy->src_ip);
4061 if (snprintf_error(len, ret)) {
4062 sigma_dut_print(dut, DUT_MSG_INFO,
4063 "Error in adding src_ip %s",
4064 dscp_policy->src_ip);
4065 return -1;
4066 }
4067 pos += ret;
4068 len -= ret;
4069 }
4070
4071 if (strlen(dscp_policy->dst_ip)) {
4072 ret = snprintf(pos, len, " -d %s", dscp_policy->dst_ip);
4073 if (snprintf_error(len, ret)) {
4074 sigma_dut_print(dut, DUT_MSG_INFO,
4075 "Error in adding dst_ip %s",
4076 dscp_policy->dst_ip);
4077 return -1;
4078 }
4079 pos += ret;
4080 len -= ret;
4081 }
4082
4083 if (dscp_policy->src_port || dscp_policy->dst_port ||
4084 (dscp_policy->start_port && dscp_policy->end_port)) {
4085 ret = snprintf(pos, len, " -p %s",
4086 protocol_to_str(dscp_policy->protocol));
4087 if (snprintf_error(len, ret)) {
4088 sigma_dut_print(dut, DUT_MSG_INFO,
4089 "Error in adding protocol %d in add command",
4090 dscp_policy->protocol);
4091 return -1;
4092 }
4093 pos += ret;
4094 len -= ret;
4095 }
4096
4097 if (dscp_policy->src_port) {
4098 ret = snprintf(pos, len, " --sport %d", dscp_policy->src_port);
4099 if (snprintf_error(len, ret)) {
4100 sigma_dut_print(dut, DUT_MSG_INFO,
4101 "Error in adding src_port %d",
4102 dscp_policy->src_port);
4103 return -1;
4104 }
4105 pos += ret;
4106 len -= ret;
4107 }
4108
4109 if (dscp_policy->dst_port) {
4110 ret = snprintf(pos, len, " --dport %d", dscp_policy->dst_port);
4111 if (snprintf_error(len, ret)) {
4112 sigma_dut_print(dut, DUT_MSG_INFO,
4113 "Error in adding dst_port %d",
4114 dscp_policy->dst_port);
4115 return -1;
4116 }
4117 pos += ret;
4118 len -= ret;
4119 }
4120
4121 if (dscp_policy->start_port && dscp_policy->end_port) {
4122 ret = snprintf(pos, len, " --match multiport --dports %d:%d",
4123 dscp_policy->start_port, dscp_policy->end_port);
4124 if (snprintf_error(len, ret)) {
4125 sigma_dut_print(dut, DUT_MSG_INFO,
4126 "Error in adding start:end port %d:%d",
4127 dscp_policy->start_port,
4128 dscp_policy->end_port);
4129 return -1;
4130 }
4131 pos += ret;
4132 len -= ret;
4133 }
4134
4135 ret = snprintf(pos, len, " -j DSCP --set-dscp 0x%0x",
4136 dscp_policy->dscp);
4137 if (snprintf_error(len, ret)) {
4138 sigma_dut_print(dut, DUT_MSG_INFO,
4139 "Error in adding dscp %0x", dscp_policy->dscp);
4140 return -1;
4141 }
4142 ret = system(ip_cmd);
4143 sigma_dut_print(dut, DUT_MSG_DEBUG, "iptables rule: %s err: %d",
4144 ip_cmd, ret);
4145
4146 return ret;
4147}
4148
4149
4150static int add_dscp_policy_rule(struct sigma_dut *dut,
4151 struct dscp_policy_data *dscp_policy)
4152{
4153 return dut->dscp_use_iptables ? add_iptable_rule(dut, dscp_policy) :
4154 add_nft_rule(dut, dscp_policy);
4155}
4156
4157
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304158static void clear_all_dscp_policies(struct sigma_dut *dut)
4159{
4160 free_dscp_policy_table(dut);
4161
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304162 if (dut->dscp_use_iptables) {
Shivani Baranwalbf2b5212021-12-08 16:38:23 +05304163#ifdef ANDROID
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304164 if (system("/system/bin/iptables -t mangle -F && /system/bin/iptables -t mangle -X") != 0 ||
Shivani Baranwalbf2b5212021-12-08 16:38:23 +05304165 system("/system/bin/ip6tables -t mangle -F && /system/bin/ip6tables -t mangle -X") != 0)
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304166 sigma_dut_print(dut, DUT_MSG_ERROR,
4167 "iptables: Failed to flush DSCP policy");
Shivani Baranwalbf2b5212021-12-08 16:38:23 +05304168#else /* ANDROID */
4169 if (system("iptables -t mangle -F && iptables -t mangle -X") != 0 ||
4170 system("ip6tables -t mangle -F && ip6tables -t mangle -X") != 0)
4171 sigma_dut_print(dut, DUT_MSG_ERROR,
4172 "iptables: Failed to flush DSCP policy");
4173#endif /* ANDROID */
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304174 } else {
4175 if (system("nft flush ruleset") != 0)
4176 sigma_dut_print(dut, DUT_MSG_ERROR,
4177 "nftables: Failed to flush DSCP policy");
4178 }
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304179}
4180
4181
4182static int send_dscp_response(struct sigma_dut *dut,
4183 struct dscp_policy_status *status_list,
4184 int num_status)
4185{
4186 int rem_len, ret;
4187 char buf[200] = "", *pos, cmd[256];
4188
4189 pos = buf;
4190 rem_len = sizeof(buf);
4191
4192 ret = snprintf(pos, rem_len, " solicited");
4193 if (snprintf_error(rem_len, ret)) {
4194 sigma_dut_print(dut, DUT_MSG_ERROR,
4195 "Failed to write DSCP policy response command");
4196 return -1;
4197 }
4198 pos += ret;
4199 rem_len -= ret;
4200
4201 for (int i = 0; i < num_status; i++) {
4202 ret = snprintf(pos, rem_len, " policy_id=%d status=%d",
4203 status_list[i].id, status_list[i].status);
4204 if (snprintf_error(rem_len, ret)) {
4205 sigma_dut_print(dut, DUT_MSG_ERROR,
4206 "Failed to wite DSCP policy response");
4207 return -1;
4208 }
4209
4210 pos += ret;
4211 rem_len -= ret;
4212 }
4213
4214 ret = snprintf(cmd, sizeof(cmd), "DSCP_RESP%s", buf);
4215 if (snprintf_error(sizeof(cmd), ret)) {
4216 sigma_dut_print(dut, DUT_MSG_ERROR,
4217 "Failed to create DSCP Policy Response frame");
4218 return -1;
4219 }
4220
4221 if (wpa_command(dut->station_ifname, cmd) != 0) {
4222 sigma_dut_print(dut, DUT_MSG_ERROR,
4223 "Failed to send DSCP Policy Response frame");
4224 return -1;
4225 }
4226
4227 sigma_dut_print(dut, DUT_MSG_DEBUG,
4228 "DSCP Policy Response frame sent: %s", cmd);
4229 return 0;
4230}
4231
4232
4233#ifdef ANDROID
4234static void thread_cancel_handler(int sig)
4235{
4236 if (sig == SIGUSR1)
4237 pthread_exit(0);
4238}
4239#endif /* ANDROID */
4240
4241
4242static void * mon_dscp_policies(void *ptr)
4243{
4244 struct sigma_dut *dut = ptr;
4245 int ret, policy_id;
4246 struct wpa_ctrl *ctrl;
4247 char buf[4096], *pos, *end;
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304248 struct dscp_policy_data *policy = NULL, *current_policy, *prev_policy;
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304249 struct dscp_policy_status status_list[10];
4250 int num_status = 0;
4251 const char *events[] = {
4252 "CTRL-EVENT-DISCONNECTED",
4253 "CTRL-EVENT-DSCP-POLICY",
4254 NULL
4255 };
4256#ifdef ANDROID
4257 struct sigaction actions;
4258#endif /* ANDROID */
4259
4260 ctrl = open_wpa_mon(get_station_ifname(dut));
4261 if (!ctrl) {
4262 sigma_dut_print(dut, DUT_MSG_ERROR,
4263 "Failed to open wpa_supplicant monitor connection");
4264 return NULL;
4265 }
4266
4267#ifdef ANDROID
4268 memset(&actions, 0, sizeof(actions));
4269 sigemptyset(&actions.sa_mask);
4270 actions.sa_flags = 0;
4271 actions.sa_handler = thread_cancel_handler;
4272 if (sigaction(SIGUSR1, &actions, NULL) == -1) {
4273 sigma_dut_print(dut, DUT_MSG_ERROR,
4274 "Failed to register exit handler for %s",
4275 __func__);
4276 wpa_ctrl_detach(ctrl);
4277 wpa_ctrl_close(ctrl);
4278 return NULL;
4279 }
4280#endif /* ANDROID */
4281
4282 while (1) {
4283 ret = get_wpa_cli_events_timeout(dut, ctrl, events,
4284 buf, sizeof(buf), 0);
4285
4286 if (ret || strlen(buf) == 0) {
4287 sigma_dut_print(dut, DUT_MSG_INFO,
4288 "Did not receive any event");
4289 continue;
4290 }
4291
4292 if (strstr(buf, "CTRL-EVENT-DISCONNECTED")) {
4293 clear_all_dscp_policies(dut);
4294 break;
4295 }
4296
4297 if (strstr(buf, "request_start")) {
4298 num_status = 0;
4299 if (strstr(buf, "clear_all"))
4300 clear_all_dscp_policies(dut);
4301 continue;
4302 }
4303
4304 if (strstr(buf, "request_end")) {
4305 send_dscp_response(dut, status_list, num_status);
4306 continue;
4307 }
4308
4309 if (!strstr(buf, "add") && !strstr(buf, "remove") &&
4310 !strstr(buf, "reject")) {
4311 sigma_dut_print(dut, DUT_MSG_DEBUG, "Ignore event: %s",
4312 buf);
4313 continue;
4314 }
4315
4316 pos = strstr(buf, "policy_id=");
4317 if (!pos) {
4318 sigma_dut_print(dut, DUT_MSG_INFO,
4319 "Policy id not present");
4320 continue;
4321 }
4322 policy_id = atoi(pos + 10);
4323
4324 if (num_status >= ARRAY_SIZE(status_list)) {
4325 sigma_dut_print(dut, DUT_MSG_INFO,
4326 "Max policies allowed per DSCP request reached. Drop policy id %d request",
4327 policy_id);
4328 continue;
4329 }
4330 status_list[num_status].id = policy_id;
4331
Veerendranath Jakkama16cdc82021-09-12 16:44:22 +05304332 if (dut->reject_dscp_policies) {
4333 status_list[num_status].status =
4334 dut->dscp_reject_resp_code;
4335 num_status++;
4336 continue;
4337 }
4338
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304339 if (strstr(buf, "reject"))
4340 goto reject;
4341
4342 /*
4343 * In case of "add" also if policy with same policy id exist it
4344 * shall be removed. So always call remove_dscp_policy().
4345 */
4346 if (remove_dscp_policy(dut, policy_id))
4347 goto reject;
4348
4349 if (strstr(buf, "remove"))
4350 goto success;
4351
4352 policy = malloc(sizeof(*policy));
4353 if (!policy)
4354 goto reject;
4355
4356 memset(policy, 0, sizeof(*policy));
4357
4358 policy->policy_id = policy_id;
4359
4360 pos = strstr(buf, "dscp=");
4361 if (!pos) {
4362 sigma_dut_print(dut, DUT_MSG_ERROR,
4363 "DSCP info not present");
4364 goto reject;
4365 }
4366 policy->dscp = atoi(pos + 5);
4367
4368 pos = strstr(buf, "ip_version=");
4369 if (!pos) {
4370 sigma_dut_print(dut, DUT_MSG_ERROR,
4371 "IP version info not present");
4372 goto reject;
4373 }
4374 policy->ip_version = atoi(pos + 11);
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304375 if (policy->ip_version)
4376 policy->granularity_score++;
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304377
4378 pos = strstr(buf, "domain_name=");
4379 if (pos) {
4380 pos += 12;
4381 end = strchr(pos, ' ');
4382 if (!end)
4383 end = pos + strlen(pos);
4384
4385 if (end - pos >= (int) sizeof(policy->domain_name))
4386 goto reject;
4387
4388 memcpy(policy->domain_name, pos, end - pos);
4389 policy->domain_name[end - pos] = '\0';
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304390 policy->granularity_score++;
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304391 }
4392
4393 pos = strstr(buf, "start_port=");
4394 if (pos) {
4395 pos += 11;
4396 policy->start_port = atoi(pos);
4397 }
4398
4399 pos = strstr(buf, "end_port=");
4400 if (pos) {
4401 pos += 9;
4402 policy->end_port = atoi(pos);
4403 }
4404
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304405 if (policy->start_port && policy->end_port)
4406 policy->granularity_score++;
4407
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304408 pos = strstr(buf, "src_ip=");
4409 if (pos) {
4410 pos += 7;
4411 end = strchr(pos, ' ');
4412 if (!end)
4413 end = pos + strlen(pos);
4414
4415 if (end - pos >= (int) sizeof(policy->src_ip))
4416 goto reject;
4417
4418 memcpy(policy->src_ip, pos, end - pos);
4419 policy->src_ip[end - pos] = '\0';
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304420 policy->granularity_score++;
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304421 }
4422
4423 pos = strstr(buf, "dst_ip=");
4424 if (pos) {
4425 pos += 7;
4426 end = strchr(pos, ' ');
4427 if (!end)
4428 end = pos + strlen(pos);
4429
4430 if (end - pos >= (int) sizeof(policy->dst_ip))
4431 goto reject;
4432
4433 memcpy(policy->dst_ip, pos, end - pos);
4434 policy->dst_ip[end - pos] = '\0';
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304435 policy->granularity_score++;
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304436 }
4437
4438 pos = strstr(buf, "src_port=");
4439 if (pos) {
4440 pos += 9;
4441 policy->src_port = atoi(pos);
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304442 policy->granularity_score++;
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304443 }
4444
4445 pos = strstr(buf, "dst_port=");
4446 if (pos) {
4447 pos += 9;
4448 policy->dst_port = atoi(pos);
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304449 policy->granularity_score++;
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304450 }
4451
4452 pos = strstr(buf, "protocol=");
4453 if (pos) {
4454 pos += 9;
4455 policy->protocol = atoi(pos);
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304456 policy->granularity_score++;
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304457 }
4458
4459 /*
4460 * Skip adding nft rules for doman name policies.
4461 * Domain name rules are applied in sigma_dut itself.
4462 */
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304463 if (!strlen(policy->domain_name) &&
4464 add_dscp_policy_rule(dut, policy))
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304465 goto reject;
4466
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304467 /*
4468 * Add the new policy in policy table in granularity increasing
4469 * order.
4470 */
4471 current_policy = dut->dscp_policy_table;
4472 prev_policy = NULL;
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304473
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304474 while (current_policy) {
4475 if (current_policy->granularity_score >
4476 policy->granularity_score)
4477 break;
4478
4479 prev_policy = current_policy;
4480 current_policy = current_policy->next;
4481 }
4482
4483 if (prev_policy)
4484 prev_policy->next = policy;
4485 else
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304486 dut->dscp_policy_table = policy;
4487
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304488 policy->next = current_policy;
4489
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304490success:
4491 status_list[num_status].status = DSCP_POLICY_SUCCESS;
4492 num_status++;
4493 policy = NULL;
4494 continue;
4495reject:
4496 status_list[num_status].status = DSCP_POLICY_REJECT;
4497 num_status++;
4498 free(policy);
4499 policy = NULL;
4500 }
4501
4502 free_dscp_policy_table(dut);
4503 wpa_ctrl_detach(ctrl);
4504 wpa_ctrl_close(ctrl);
4505
4506 pthread_exit(0);
4507 return NULL;
4508}
4509
4510
4511static void start_dscp_policy_mon_thread(struct sigma_dut *dut)
4512{
4513 /* Create event thread */
4514 pthread_create(&dut->dscp_policy_mon_thread, NULL, &mon_dscp_policies,
4515 (void *) dut);
4516}
4517
4518
4519void stop_dscp_policy_mon_thread(struct sigma_dut *dut)
4520{
4521 if (dut->dscp_policy_mon_thread) {
4522#ifdef ANDROID
4523 /* pthread_cancel not supported in Android */
4524 pthread_kill(dut->dscp_policy_mon_thread, SIGUSR1);
4525#else /* ANDROID */
4526 pthread_cancel(dut->dscp_policy_mon_thread);
4527#endif /* ANDROID */
4528 dut->dscp_policy_mon_thread = 0;
4529 }
4530}
4531
4532
Jouni Malinenf7222712019-06-13 01:50:21 +03004533static enum sigma_cmd_result cmd_sta_associate(struct sigma_dut *dut,
4534 struct sigma_conn *conn,
4535 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004536{
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05304537#ifdef NL80211_SUPPORT
4538 const char *intf = get_param(cmd, "Interface");
4539#endif /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004540 const char *ssid = get_param(cmd, "ssid");
4541 const char *wps_param = get_param(cmd, "WPS");
4542 const char *bssid = get_param(cmd, "bssid");
Jouni Malinen46a19b62017-06-23 14:31:27 +03004543 const char *chan = get_param(cmd, "channel");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02004544 const char *network_mode = get_param(cmd, "network_mode");
Veerendranath Jakkama082e342020-05-16 00:19:21 +05304545 const char *ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004546 int wps = 0;
Jouni Malinen3c367e82017-06-23 17:01:47 +03004547 char buf[1000], extra[50];
Jouni Malinen134fe3c2019-06-12 04:16:49 +03004548 int e;
4549 enum sigma_cmd_result ret = SUCCESS_SEND_STATUS;
4550 struct wpa_ctrl *ctrl = NULL;
4551 int num_network_not_found = 0;
4552 int num_disconnected = 0;
4553 int tod = -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004554
4555 if (ssid == NULL)
4556 return -1;
4557
Jouni Malinen37d5c692019-08-19 16:56:55 +03004558 dut->server_cert_tod = 0;
4559
Jouni Malinen3c367e82017-06-23 17:01:47 +03004560 if (dut->rsne_override) {
Sunil Dutt44595082018-02-12 19:41:45 +05304561#ifdef NL80211_SUPPORT
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004562 if (get_driver_type(dut) == DRIVER_WCN) {
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05304563 sta_config_params(dut, intf, STA_SET_RSNIE, 1);
Sunil Dutt44595082018-02-12 19:41:45 +05304564 dut->config_rsnie = 1;
4565 }
4566#endif /* NL80211_SUPPORT */
Jouni Malinen3c367e82017-06-23 17:01:47 +03004567 snprintf(buf, sizeof(buf), "TEST_ASSOC_IE %s",
4568 dut->rsne_override);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004569 if (wpa_command(get_station_ifname(dut), buf) < 0) {
Jouni Malinen3c367e82017-06-23 17:01:47 +03004570 send_resp(dut, conn, SIGMA_ERROR,
4571 "ErrorCode,Failed to set DEV_CONFIGURE_IE RSNE override");
4572 return 0;
4573 }
4574 }
4575
Jouni Malinen68143132017-09-02 02:34:08 +03004576 if (dut->sae_commit_override) {
4577 snprintf(buf, sizeof(buf), "SET sae_commit_override %s",
4578 dut->sae_commit_override);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004579 if (wpa_command(get_station_ifname(dut), buf) < 0) {
Jouni Malinen68143132017-09-02 02:34:08 +03004580 send_resp(dut, conn, SIGMA_ERROR,
4581 "ErrorCode,Failed to set SAE commit override");
4582 return 0;
4583 }
4584 }
Ankita Bajaj1bde7942018-01-09 19:15:01 +05304585#ifdef ANDROID
4586 if (dut->fils_hlp)
4587 process_fils_hlp(dut);
4588#endif /* ANDROID */
Jouni Malinen68143132017-09-02 02:34:08 +03004589
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004590 if (wps_param &&
4591 (strcmp(wps_param, "1") == 0 || strcasecmp(wps_param, "On") == 0))
4592 wps = 1;
4593
4594 if (wps) {
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02004595 if (dut->program == PROGRAM_60GHZ && network_mode &&
4596 strcasecmp(network_mode, "PBSS") == 0 &&
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004597 set_network(get_station_ifname(dut), dut->infra_network_id,
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02004598 "pbss", "1") < 0)
4599 return -2;
4600
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004601 if (dut->wps_method == WFA_CS_WPS_NOT_READY) {
4602 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,WPS "
4603 "parameters not yet set");
4604 return 0;
4605 }
4606 if (dut->wps_method == WFA_CS_WPS_PBC) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004607 if (wpa_command(get_station_ifname(dut), "WPS_PBC") < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004608 return -2;
4609 } else {
4610 snprintf(buf, sizeof(buf), "WPS_PIN any %s",
4611 dut->wps_pin);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004612 if (wpa_command(get_station_ifname(dut), buf) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004613 return -2;
4614 }
4615 } else {
vamsi krishna52e16f92017-08-29 12:37:34 +05304616 if (strcmp(ssid, dut->infra_ssid) == 0) {
4617 sigma_dut_print(dut, DUT_MSG_DEBUG,
4618 "sta_associate for the most recently added network");
4619 } else if (find_network(dut, ssid) < 0) {
4620 sigma_dut_print(dut, DUT_MSG_DEBUG,
4621 "sta_associate for a previously stored network profile");
4622 send_resp(dut, conn, SIGMA_ERROR,
4623 "ErrorCode,Profile not found");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004624 return 0;
4625 }
4626
4627 if (bssid &&
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004628 set_network(get_station_ifname(dut), dut->infra_network_id,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004629 "bssid", bssid) < 0) {
4630 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
4631 "Invalid bssid argument");
4632 return 0;
4633 }
4634
Veerendranath Jakkama082e342020-05-16 00:19:21 +05304635 if ((dut->program == PROGRAM_WPA3 &&
4636 dut->sta_associate_wait_connect) ||
Veerendranath Jakkamfc5b7d22022-04-15 02:12:12 +05304637 dut->program == PROGRAM_QM ||
4638 (dut->dhcp_client_running && dut->client_privacy)) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004639 ctrl = open_wpa_mon(get_station_ifname(dut));
Jouni Malinen134fe3c2019-06-12 04:16:49 +03004640 if (!ctrl)
4641 return ERROR_SEND_STATUS;
4642 }
4643
Jouni Malinen46a19b62017-06-23 14:31:27 +03004644 extra[0] = '\0';
4645 if (chan)
4646 snprintf(extra, sizeof(extra), " freq=%u",
Alexei Avshalom Lazar093569f2018-11-13 14:08:17 +02004647 channel_to_freq(dut, atoi(chan)));
Jouni Malinen46a19b62017-06-23 14:31:27 +03004648 snprintf(buf, sizeof(buf), "SELECT_NETWORK %d%s",
4649 dut->infra_network_id, extra);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004650 if (wpa_command(get_station_ifname(dut), buf) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004651 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to select "
4652 "network id %d on %s",
4653 dut->infra_network_id,
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004654 get_station_ifname(dut));
Jouni Malinen134fe3c2019-06-12 04:16:49 +03004655 ret = ERROR_SEND_STATUS;
4656 goto done;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004657 }
4658 }
4659
Jouni Malinen134fe3c2019-06-12 04:16:49 +03004660 if (!ctrl)
4661 return SUCCESS_SEND_STATUS;
4662
4663 /* Wait for connection result to be able to store server certificate
4664 * hash for trust root override testing
4665 * (dev_exec_action,ServerCertTrust). */
4666
4667 for (e = 0; e < 20; e++) {
4668 const char *events[] = {
4669 "CTRL-EVENT-EAP-PEER-CERT",
4670 "CTRL-EVENT-EAP-TLS-CERT-ERROR",
4671 "CTRL-EVENT-DISCONNECTED",
4672 "CTRL-EVENT-CONNECTED",
4673 "CTRL-EVENT-NETWORK-NOT-FOUND",
4674 NULL
4675 };
4676 char buf[1024];
4677 int res;
4678
4679 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
4680 if (res < 0) {
Jouni Malinenf1f16642019-11-15 21:19:04 +02004681 send_resp(dut, conn, SIGMA_COMPLETE,
4682 "Result,Association did not complete");
Jouni Malinen134fe3c2019-06-12 04:16:49 +03004683 ret = STATUS_SENT_ERROR;
4684 break;
4685 }
4686 sigma_dut_print(dut, DUT_MSG_DEBUG, "Connection event: %s",
4687 buf);
4688
4689 if (strstr(buf, "CTRL-EVENT-EAP-PEER-CERT") &&
4690 strstr(buf, " depth=0")) {
4691 char *pos = strstr(buf, " hash=");
4692
4693 if (pos) {
4694 char *end;
4695
Jouni Malinen34b19cb2019-08-16 16:37:17 +03004696 if (strstr(buf, " tod=1"))
4697 tod = 1;
4698 else if (strstr(buf, " tod=2"))
4699 tod = 2;
4700 else
4701 tod = 0;
Jouni Malinen134fe3c2019-06-12 04:16:49 +03004702 sigma_dut_print(dut, DUT_MSG_DEBUG,
4703 "Server certificate TOD policy: %d",
4704 tod);
Jouni Malinen37d5c692019-08-19 16:56:55 +03004705 dut->server_cert_tod = tod;
Jouni Malinen134fe3c2019-06-12 04:16:49 +03004706
4707 pos += 6;
4708 end = strchr(pos, ' ');
4709 if (end)
4710 *end = '\0';
4711 strlcpy(dut->server_cert_hash, pos,
4712 sizeof(dut->server_cert_hash));
4713 sigma_dut_print(dut, DUT_MSG_DEBUG,
4714 "Server certificate hash: %s",
4715 dut->server_cert_hash);
4716 }
4717 }
4718
4719 if (strstr(buf, "CTRL-EVENT-EAP-TLS-CERT-ERROR")) {
4720 send_resp(dut, conn, SIGMA_COMPLETE,
4721 "Result,TLS server certificate validation failed");
4722 ret = STATUS_SENT_ERROR;
4723 break;
4724 }
4725
4726 if (strstr(buf, "CTRL-EVENT-NETWORK-NOT-FOUND")) {
4727 num_network_not_found++;
4728
4729 if (num_network_not_found > 2) {
4730 send_resp(dut, conn, SIGMA_COMPLETE,
4731 "Result,Network not found");
4732 ret = STATUS_SENT_ERROR;
4733 break;
4734 }
4735 }
4736
4737 if (strstr(buf, "CTRL-EVENT-DISCONNECTED")) {
4738 num_disconnected++;
4739
4740 if (num_disconnected > 2) {
4741 send_resp(dut, conn, SIGMA_COMPLETE,
4742 "Result,Connection failed");
4743 ret = STATUS_SENT_ERROR;
4744 break;
4745 }
4746 }
4747
4748 if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
Veerendranath Jakkamfc5b7d22022-04-15 02:12:12 +05304749 if (dut->dhcp_client_running && dut->client_privacy) {
4750 /*
4751 * Interface MAC address will be changed by
4752 * wpa_supplicant before connection attempt when
4753 * client privacy enabled. Restart DHCP client
4754 * to make sure DHCP frames use the correct
4755 * source MAC address.
4756 * */
4757 kill_dhcp_client(dut, ifname);
4758 if (start_dhcp_client(dut, ifname) < 0) {
4759 send_resp(dut, conn, SIGMA_COMPLETE,
4760 "Result,DHCP client start failed");
4761 ret = STATUS_SENT_ERROR;
4762 break;
4763 }
4764 }
Jouni Malinen134fe3c2019-06-12 04:16:49 +03004765 if (tod >= 0) {
4766 sigma_dut_print(dut, DUT_MSG_DEBUG,
4767 "Network profile TOD policy update: %d -> %d",
4768 dut->sta_tod_policy, tod);
4769 dut->sta_tod_policy = tod;
4770 }
Veerendranath Jakkama082e342020-05-16 00:19:21 +05304771 if (dut->program == PROGRAM_QM) {
4772 unsigned char iface_mac_addr[ETH_ALEN];
4773 char ipv6[100];
4774
4775 if (get_hwaddr(ifname, iface_mac_addr) < 0) {
4776 sigma_dut_print(dut, DUT_MSG_ERROR,
4777 "%s: get_hwaddr %s failed",
4778 __func__, ifname);
4779 ret = ERROR_SEND_STATUS;
4780 break;
4781 }
4782
4783 convert_mac_addr_to_ipv6_lladdr(iface_mac_addr,
4784 ipv6,
4785 sizeof(ipv6));
4786
4787 if (set_ipv6_addr(dut, ipv6, "64", ifname) !=
4788 0) {
4789 ret = ERROR_SEND_STATUS;
4790 break;
4791 }
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304792 start_dscp_policy_mon_thread(dut);
Veerendranath Jakkama082e342020-05-16 00:19:21 +05304793 }
Jouni Malinen134fe3c2019-06-12 04:16:49 +03004794 break;
4795 }
4796 }
4797done:
4798 if (ctrl) {
4799 wpa_ctrl_detach(ctrl);
4800 wpa_ctrl_close(ctrl);
4801 }
4802 return ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004803}
4804
4805
4806static int run_hs20_osu(struct sigma_dut *dut, const char *params)
4807{
4808 char buf[500], cmd[200];
4809 int res;
4810
4811 /* Use hs20-osu-client file at the current dir, if found; otherwise use
4812 * default path */
4813 res = snprintf(cmd, sizeof(cmd),
4814 "%s -w \"%s\" -r hs20-osu-client.res %s%s -dddKt -f Logs/hs20-osu-client.txt",
4815 file_exists("./hs20-osu-client") ?
4816 "./hs20-osu-client" : "hs20-osu-client",
4817 sigma_wpas_ctrl,
4818 dut->summary_log ? "-s " : "",
4819 dut->summary_log ? dut->summary_log : "");
4820 if (res < 0 || res >= (int) sizeof(cmd))
4821 return -1;
4822
4823 res = snprintf(buf, sizeof(buf), "%s %s", cmd, params);
4824 if (res < 0 || res >= (int) sizeof(buf))
4825 return -1;
4826 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
4827
4828 if (system(buf) != 0) {
4829 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to run: %s", buf);
4830 return -1;
4831 }
4832 sigma_dut_print(dut, DUT_MSG_DEBUG,
4833 "Completed hs20-osu-client operation");
4834
4835 return 0;
4836}
4837
4838
4839static int download_ppsmo(struct sigma_dut *dut,
4840 struct sigma_conn *conn,
4841 const char *intf,
4842 struct sigma_cmd *cmd)
4843{
4844 const char *name, *path, *val;
4845 char url[500], buf[600], fbuf[100];
4846 char *fqdn = NULL;
4847
4848 name = get_param(cmd, "FileName");
4849 path = get_param(cmd, "FilePath");
4850 if (name == NULL || path == NULL)
4851 return -1;
4852
4853 if (strcasecmp(path, "VendorSpecific") == 0) {
4854 snprintf(url, sizeof(url), "PPS/%s", name);
4855 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured PPS MO "
4856 "from the device (%s)", url);
4857 if (!file_exists(url)) {
4858 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
4859 "PPS MO file does not exist");
4860 return 0;
4861 }
4862 snprintf(buf, sizeof(buf), "cp %s pps-tnds.xml", url);
4863 if (system(buf) != 0) {
4864 send_resp(dut, conn, SIGMA_ERROR,
4865 "errorCode,Failed to copy PPS MO");
4866 return 0;
4867 }
4868 } else if (strncasecmp(path, "http:", 5) != 0 &&
4869 strncasecmp(path, "https:", 6) != 0) {
4870 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
4871 "Unsupported FilePath value");
4872 return 0;
4873 } else {
4874 snprintf(url, sizeof(url), "%s/%s", path, name);
4875 sigma_dut_print(dut, DUT_MSG_INFO, "Downloading PPS MO from %s",
4876 url);
4877 snprintf(buf, sizeof(buf), "wget -T 10 -t 3 -O pps-tnds.xml '%s'", url);
4878 remove("pps-tnds.xml");
4879 if (system(buf) != 0) {
4880 send_resp(dut, conn, SIGMA_ERROR,
4881 "errorCode,Failed to download PPS MO");
4882 return 0;
4883 }
4884 }
4885
4886 if (run_hs20_osu(dut, "from_tnds pps-tnds.xml pps.xml") < 0) {
4887 send_resp(dut, conn, SIGMA_ERROR,
4888 "errorCode,Failed to parse downloaded PPSMO");
4889 return 0;
4890 }
4891 unlink("pps-tnds.xml");
4892
4893 val = get_param(cmd, "managementTreeURI");
4894 if (val) {
4895 const char *pos, *end;
4896 sigma_dut_print(dut, DUT_MSG_DEBUG, "managementTreeURI: %s",
4897 val);
4898 if (strncmp(val, "./Wi-Fi/", 8) != 0) {
4899 send_resp(dut, conn, SIGMA_ERROR,
4900 "errorCode,Invalid managementTreeURI prefix");
4901 return 0;
4902 }
4903 pos = val + 8;
4904 end = strchr(pos, '/');
4905 if (end == NULL ||
4906 strcmp(end, "/PerProviderSubscription") != 0) {
4907 send_resp(dut, conn, SIGMA_ERROR,
4908 "errorCode,Invalid managementTreeURI postfix");
4909 return 0;
4910 }
4911 if (end - pos >= (int) sizeof(fbuf)) {
4912 send_resp(dut, conn, SIGMA_ERROR,
4913 "errorCode,Too long FQDN in managementTreeURI");
4914 return 0;
4915 }
4916 memcpy(fbuf, pos, end - pos);
4917 fbuf[end - pos] = '\0';
4918 fqdn = fbuf;
4919 sigma_dut_print(dut, DUT_MSG_INFO,
4920 "FQDN from managementTreeURI: %s", fqdn);
4921 } else if (run_hs20_osu(dut, "get_fqdn pps.xml") == 0) {
4922 FILE *f = fopen("pps-fqdn", "r");
4923 if (f) {
4924 if (fgets(fbuf, sizeof(fbuf), f)) {
4925 fbuf[sizeof(fbuf) - 1] = '\0';
4926 fqdn = fbuf;
4927 sigma_dut_print(dut, DUT_MSG_DEBUG,
4928 "Use FQDN %s", fqdn);
4929 }
4930 fclose(f);
4931 }
4932 }
4933
4934 if (fqdn == NULL) {
4935 send_resp(dut, conn, SIGMA_ERROR,
4936 "errorCode,No FQDN specified");
4937 return 0;
4938 }
4939
4940 mkdir("SP", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
4941 snprintf(buf, sizeof(buf), "SP/%s", fqdn);
4942 mkdir(buf, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
4943
4944 snprintf(buf, sizeof(buf), "SP/%s/pps.xml", fqdn);
4945 if (rename("pps.xml", buf) < 0) {
4946 send_resp(dut, conn, SIGMA_ERROR,
4947 "errorCode,Could not move PPS MO");
4948 return 0;
4949 }
4950
4951 if (strcasecmp(path, "VendorSpecific") == 0) {
4952 snprintf(buf, sizeof(buf), "cp Certs/ca.pem SP/%s/ca.pem",
4953 fqdn);
4954 if (system(buf)) {
4955 send_resp(dut, conn, SIGMA_ERROR,
4956 "errorCode,Failed to copy OSU CA cert");
4957 return 0;
4958 }
4959
4960 snprintf(buf, sizeof(buf),
4961 "cp Certs/aaa-ca.pem SP/%s/aaa-ca.pem",
4962 fqdn);
4963 if (system(buf)) {
4964 send_resp(dut, conn, SIGMA_ERROR,
4965 "errorCode,Failed to copy AAA CA cert");
4966 return 0;
4967 }
4968 } else {
4969 snprintf(buf, sizeof(buf),
4970 "dl_osu_ca SP/%s/pps.xml SP/%s/ca.pem",
4971 fqdn, fqdn);
4972 if (run_hs20_osu(dut, buf) < 0) {
4973 send_resp(dut, conn, SIGMA_ERROR,
4974 "errorCode,Failed to download OSU CA cert");
4975 return 0;
4976 }
4977
4978 snprintf(buf, sizeof(buf),
4979 "dl_aaa_ca SP/%s/pps.xml SP/%s/aaa-ca.pem",
4980 fqdn, fqdn);
4981 if (run_hs20_osu(dut, buf) < 0) {
4982 sigma_dut_print(dut, DUT_MSG_INFO,
4983 "Failed to download AAA CA cert");
4984 }
4985 }
4986
4987 if (file_exists("next-client-cert.pem")) {
4988 snprintf(buf, sizeof(buf), "SP/%s/client-cert.pem", fqdn);
4989 if (rename("next-client-cert.pem", buf) < 0) {
4990 send_resp(dut, conn, SIGMA_ERROR,
4991 "errorCode,Could not move client certificate");
4992 return 0;
4993 }
4994 }
4995
4996 if (file_exists("next-client-key.pem")) {
4997 snprintf(buf, sizeof(buf), "SP/%s/client-key.pem", fqdn);
4998 if (rename("next-client-key.pem", buf) < 0) {
4999 send_resp(dut, conn, SIGMA_ERROR,
5000 "errorCode,Could not move client key");
5001 return 0;
5002 }
5003 }
5004
5005 snprintf(buf, sizeof(buf), "set_pps SP/%s/pps.xml", fqdn);
5006 if (run_hs20_osu(dut, buf) < 0) {
5007 send_resp(dut, conn, SIGMA_ERROR,
5008 "errorCode,Failed to configure credential from "
5009 "PPSMO");
5010 return 0;
5011 }
5012
5013 return 1;
5014}
5015
5016
5017static int download_cert(struct sigma_dut *dut,
5018 struct sigma_conn *conn,
5019 const char *intf,
5020 struct sigma_cmd *cmd)
5021{
5022 const char *name, *path;
5023 char url[500], buf[600];
5024
5025 name = get_param(cmd, "FileName");
5026 path = get_param(cmd, "FilePath");
5027 if (name == NULL || path == NULL)
5028 return -1;
5029
5030 if (strcasecmp(path, "VendorSpecific") == 0) {
5031 snprintf(url, sizeof(url), "Certs/%s-cert.pem", name);
5032 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured client "
5033 "certificate from the device (%s)", url);
5034 if (!file_exists(url)) {
5035 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
5036 "certificate file does not exist");
5037 return 0;
5038 }
5039 snprintf(buf, sizeof(buf), "cp %s next-client-cert.pem", url);
5040 if (system(buf) != 0) {
5041 send_resp(dut, conn, SIGMA_ERROR,
5042 "errorCode,Failed to copy client "
5043 "certificate");
5044 return 0;
5045 }
5046
5047 snprintf(url, sizeof(url), "Certs/%s-key.pem", name);
5048 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured client "
5049 "private key from the device (%s)", url);
5050 if (!file_exists(url)) {
5051 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
5052 "private key file does not exist");
5053 return 0;
5054 }
5055 snprintf(buf, sizeof(buf), "cp %s next-client-key.pem", url);
5056 if (system(buf) != 0) {
5057 send_resp(dut, conn, SIGMA_ERROR,
5058 "errorCode,Failed to copy client key");
5059 return 0;
5060 }
5061 } else if (strncasecmp(path, "http:", 5) != 0 &&
5062 strncasecmp(path, "https:", 6) != 0) {
5063 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
5064 "Unsupported FilePath value");
5065 return 0;
5066 } else {
5067 snprintf(url, sizeof(url), "%s/%s.pem", path, name);
5068 sigma_dut_print(dut, DUT_MSG_INFO, "Downloading client "
5069 "certificate/key from %s", url);
5070 snprintf(buf, sizeof(buf),
5071 "wget -T 10 -t 3 -O next-client-cert.pem '%s'", url);
5072 if (system(buf) != 0) {
5073 send_resp(dut, conn, SIGMA_ERROR,
5074 "errorCode,Failed to download client "
5075 "certificate");
5076 return 0;
5077 }
5078
5079 if (system("cp next-client-cert.pem next-client-key.pem") != 0)
5080 {
5081 send_resp(dut, conn, SIGMA_ERROR,
5082 "errorCode,Failed to copy client key");
5083 return 0;
5084 }
5085 }
5086
5087 return 1;
5088}
5089
5090
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02005091static int cmd_sta_preset_testparameters_60ghz(struct sigma_dut *dut,
5092 struct sigma_conn *conn,
5093 struct sigma_cmd *cmd)
5094{
5095 const char *val;
5096 const char *intf = get_param(cmd, "interface");
5097
5098 if (!intf)
5099 return -1;
5100
5101 val = get_param(cmd, "WscIEFragment");
5102 if (val && strcasecmp(val, "enable") == 0) {
5103 sigma_dut_print(dut, DUT_MSG_DEBUG,
5104 "Enable WSC IE fragmentation");
5105
5106 dut->wsc_fragment = 1;
5107 /* set long attributes to force fragmentation */
5108 if (wpa_command(intf, "SET device_name "
5109 WPS_LONG_DEVICE_NAME) < 0)
5110 return -2;
5111 if (wpa_command(intf, "SET manufacturer "
5112 WPS_LONG_MANUFACTURER) < 0)
5113 return -2;
5114 if (wpa_command(intf, "SET model_name "
5115 WPS_LONG_MODEL_NAME) < 0)
5116 return -2;
5117 if (wpa_command(intf, "SET model_number "
5118 WPS_LONG_MODEL_NUMBER) < 0)
5119 return -2;
5120 if (wpa_command(intf, "SET serial_number "
5121 WPS_LONG_SERIAL_NUMBER) < 0)
5122 return -2;
5123 }
5124
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02005125 val = get_param(cmd, "RSN_IE");
5126 if (val) {
5127 if (strcasecmp(val, "disable") == 0)
5128 dut->force_rsn_ie = FORCE_RSN_IE_REMOVE;
5129 else if (strcasecmp(val, "enable") == 0)
5130 dut->force_rsn_ie = FORCE_RSN_IE_ADD;
5131 }
5132
Alexei Avshalom Lazar744ae8a2019-01-31 17:26:46 +02005133 val = get_param(cmd, "WpsVersion");
5134 if (val)
5135 dut->wps_forced_version = get_wps_forced_version(dut, val);
5136
Alexei Avshalom Lazar2eccf4d2019-01-31 10:03:59 +02005137 val = get_param(cmd, "WscEAPFragment");
5138 if (val && strcasecmp(val, "enable") == 0)
5139 dut->eap_fragment = 1;
5140
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02005141 return 1;
5142}
5143
5144
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005145static int cmd_sta_preset_testparameters_hs2_r2(struct sigma_dut *dut,
5146 struct sigma_conn *conn,
5147 const char *intf,
5148 struct sigma_cmd *cmd)
5149{
5150 const char *val;
5151
5152 val = get_param(cmd, "FileType");
5153 if (val && strcasecmp(val, "PPSMO") == 0)
5154 return download_ppsmo(dut, conn, intf, cmd);
5155 if (val && strcasecmp(val, "CERT") == 0)
5156 return download_cert(dut, conn, intf, cmd);
5157 if (val) {
5158 send_resp(dut, conn, SIGMA_ERROR,
5159 "ErrorCode,Unsupported FileType");
5160 return 0;
5161 }
5162
5163 return 1;
5164}
5165
5166
Ankita Bajaja2cb5672017-10-25 16:08:28 +05305167static int cmd_sta_preset_testparameters_oce(struct sigma_dut *dut,
5168 struct sigma_conn *conn,
5169 const char *intf,
5170 struct sigma_cmd *cmd)
5171{
5172 const char *val;
Ankita Bajaj1bde7942018-01-09 19:15:01 +05305173 char buf[1000];
5174 char text[20];
5175 unsigned char addr[ETH_ALEN];
Ankita Bajaja2cb5672017-10-25 16:08:28 +05305176
5177 val = get_param(cmd, "OCESupport");
5178 if (val && strcasecmp(val, "Disable") == 0) {
5179 if (wpa_command(intf, "SET oce 0") < 0) {
5180 send_resp(dut, conn, SIGMA_ERROR,
5181 "ErrorCode,Failed to disable OCE");
5182 return 0;
5183 }
5184 } else if (val && strcasecmp(val, "Enable") == 0) {
5185 if (wpa_command(intf, "SET oce 1") < 0) {
5186 send_resp(dut, conn, SIGMA_ERROR,
5187 "ErrorCode,Failed to enable OCE");
5188 return 0;
5189 }
5190 }
5191
vamsi krishnaa2799492017-12-05 14:28:01 +05305192 val = get_param(cmd, "FILScap");
5193 if (val && (atoi(val) == 1)) {
5194 if (wpa_command(intf, "SET disable_fils 0") < 0) {
5195 send_resp(dut, conn, SIGMA_ERROR,
5196 "ErrorCode,Failed to enable FILS");
5197 return 0;
5198 }
5199 } else if (val && (atoi(val) == 0)) {
5200 if (wpa_command(intf, "SET disable_fils 1") < 0) {
5201 send_resp(dut, conn, SIGMA_ERROR,
5202 "ErrorCode,Failed to disable FILS");
5203 return 0;
5204 }
5205 }
5206
Ankita Bajaj1bde7942018-01-09 19:15:01 +05305207 val = get_param(cmd, "FILSHLP");
5208 if (val && strcasecmp(val, "Enable") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005209 if (get_wpa_status(get_station_ifname(dut), "address", text,
Ankita Bajaj1bde7942018-01-09 19:15:01 +05305210 sizeof(text)) < 0)
5211 return -2;
5212 hwaddr_aton(text, addr);
5213 snprintf(buf, sizeof(buf),
5214 "FILS_HLP_REQ_ADD ff:ff:ff:ff:ff:ff "
5215 "080045100140000040004011399e00000000ffffffff00440043"
5216 "012cb30001010600fd4f46410000000000000000000000000000"
5217 "000000000000"
5218 "%02x%02x%02x%02x%02x%02x"
5219 "0000000000000000000000000000000000000000000000000000"
5220 "0000000000000000000000000000000000000000000000000000"
5221 "0000000000000000000000000000000000000000000000000000"
5222 "0000000000000000000000000000000000000000000000000000"
5223 "0000000000000000000000000000000000000000000000000000"
5224 "0000000000000000000000000000000000000000000000000000"
5225 "0000000000000000000000000000000000000000000000000000"
5226 "0000000000000000000000000000000000000000638253633501"
5227 "013d0701000af549d29b390205dc3c12616e64726f69642d6468"
5228 "63702d382e302e30370a0103060f1a1c333a3b2b5000ff00",
5229 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
5230 if (wpa_command(intf, buf)) {
5231 send_resp(dut, conn, SIGMA_ERROR,
5232 "ErrorCode,Failed to add HLP");
5233 return 0;
5234 }
5235 dut->fils_hlp = 1;
5236 }
5237
Ankita Bajaja2cb5672017-10-25 16:08:28 +05305238 return 1;
5239}
5240
5241
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005242static void ath_sta_set_noack(struct sigma_dut *dut, const char *intf,
5243 const char *val)
5244{
5245 int counter = 0;
5246 char token[50];
5247 char *result;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05305248 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005249
Peng Xub8fc5cc2017-05-10 17:27:28 -07005250 strlcpy(token, val, sizeof(token));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005251 token[sizeof(token) - 1] = '\0';
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05305252 result = strtok_r(token, ":", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005253 while (result) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005254 if (strcmp(result, "disable") == 0)
5255 run_iwpriv(dut, intf, "noackpolicy %d 1 0", counter);
5256 else
5257 run_iwpriv(dut, intf, "noackpolicy %d 1 1", counter);
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05305258 result = strtok_r(NULL, ":", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005259 counter++;
5260 }
5261}
5262
5263
5264static void ath_sta_set_rts(struct sigma_dut *dut, const char *intf,
5265 const char *val)
5266{
5267 char buf[100];
5268
5269 snprintf(buf, sizeof(buf), "iwconfig %s rts %s", intf, val);
5270 if (system(buf) != 0) {
5271 sigma_dut_print(dut, DUT_MSG_ERROR, "iwconfig RTS failed");
5272 }
5273}
5274
5275
5276static void ath_sta_set_wmm(struct sigma_dut *dut, const char *intf,
5277 const char *val)
5278{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005279 if (strcasecmp(val, "off") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005280 run_iwpriv(dut, intf, "wmm 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005281 }
5282}
5283
5284
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08005285static int wcn_sta_set_wmm(struct sigma_dut *dut, const char *intf,
5286 const char *val)
5287{
5288#ifdef NL80211_SUPPORT
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08005289 int wmmenable = 1;
5290
5291 if (val &&
5292 (strcasecmp(val, "off") == 0 || strcmp(val, "0") == 0))
5293 wmmenable = 0;
5294
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05305295 return wcn_wifi_test_config_set_u8(
5296 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WMM_ENABLE,
5297 wmmenable);
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08005298#else /* NL80211_SUPPORT */
5299 sigma_dut_print(dut, DUT_MSG_ERROR,
5300 "WMM cannot be changed without NL80211_SUPPORT defined");
5301 return -1;
5302#endif /* NL80211_SUPPORT */
5303}
5304
5305
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005306static void ath_sta_set_sgi(struct sigma_dut *dut, const char *intf,
5307 const char *val)
5308{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005309 int sgi20;
5310
5311 sgi20 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
5312
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005313 run_iwpriv(dut, intf, "shortgi %d", sgi20);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005314}
5315
5316
5317static void ath_sta_set_11nrates(struct sigma_dut *dut, const char *intf,
5318 const char *val)
5319{
Pradeep Reddy POTTETI67376b72016-10-25 20:08:17 +05305320 int rate_code, v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005321
5322 /* Disable Tx Beam forming when using a fixed rate */
5323 ath_disable_txbf(dut, intf);
5324
Pradeep Reddy POTTETI67376b72016-10-25 20:08:17 +05305325 v = atoi(val);
5326 if (v < 0 || v > 32) {
5327 sigma_dut_print(dut, DUT_MSG_ERROR,
5328 "Invalid Fixed MCS rate: %d", v);
5329 return;
5330 }
5331 rate_code = 0x80 + v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005332
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005333 run_iwpriv(dut, intf, "set11NRates 0x%x", rate_code);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005334
5335 /* Channel width gets messed up, fix this */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005336 run_iwpriv(dut, intf, "chwidth %d", dut->chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005337}
5338
5339
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08005340static void iwpriv_sta_set_amsdu(struct sigma_dut *dut, const char *intf,
5341 const char *val)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005342{
5343 char buf[60];
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05305344 int ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005345
5346 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)
5347 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 2", intf);
5348 else
5349 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 1", intf);
5350
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05305351 ret = system(buf);
5352#ifdef NL80211_SUPPORT
5353 if (ret) {
5354 int value = (strcasecmp(val, "Enable") == 0) ? 2 : 1;
5355
5356 ret = sta_config_params(dut, intf, STA_SET_TX_MSDU, value);
5357 ret |= sta_config_params(dut, intf, STA_SET_RX_MSDU, value);
5358 }
5359#endif /* NL80211_SUPPORT */
5360 if (ret)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005361 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv amsdu failed");
5362}
5363
5364
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07005365static int iwpriv_sta_set_ampdu(struct sigma_dut *dut, const char *intf,
5366 int ampdu)
5367{
5368 char buf[60];
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08005369 int maxaggregation = 63;
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07005370
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08005371 if (ampdu)
5372 ampdu = maxaggregation;
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07005373 snprintf(buf, sizeof(buf), "iwpriv %s ampdu %d", intf, ampdu);
5374 if (system(buf) != 0) {
5375 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv ampdu failed");
5376 return -1;
5377 }
5378
5379 return 0;
5380}
5381
5382
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005383static void ath_sta_set_stbc(struct sigma_dut *dut, const char *intf,
5384 const char *val)
5385{
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005386 run_iwpriv(dut, intf, "tx_stbc %s", val);
5387 run_iwpriv(dut, intf, "rx_stbc %s", val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005388}
5389
5390
5391static int wcn_sta_set_cts_width(struct sigma_dut *dut, const char *intf,
5392 const char *val)
5393{
5394 char buf[60];
5395
Peng Xucc317ed2017-05-18 16:44:37 -07005396 if (strcmp(val, "160") == 0) {
5397 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 5", intf);
5398 } else if (strcmp(val, "80") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005399 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 3", intf);
5400 } else if (strcmp(val, "40") == 0) {
5401 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 2", intf);
5402 } else if (strcmp(val, "20") == 0) {
5403 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 1", intf);
5404 } else if (strcasecmp(val, "Auto") == 0) {
5405 buf[0] = '\0';
5406 } else {
5407 sigma_dut_print(dut, DUT_MSG_ERROR,
5408 "WIDTH/CTS_WIDTH value not supported");
5409 return -1;
5410 }
5411
5412 if (buf[0] != '\0' && system(buf) != 0) {
5413 sigma_dut_print(dut, DUT_MSG_ERROR,
5414 "Failed to set WIDTH/CTS_WIDTH");
5415 return -1;
5416 }
5417
5418 return 0;
5419}
5420
5421
5422int ath_set_width(struct sigma_dut *dut, struct sigma_conn *conn,
5423 const char *intf, const char *val)
5424{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005425 if (strcasecmp(val, "Auto") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005426 run_iwpriv(dut, intf, "chwidth 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005427 dut->chwidth = 0;
5428 } else if (strcasecmp(val, "20") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005429 run_iwpriv(dut, intf, "chwidth 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005430 dut->chwidth = 0;
5431 } else if (strcasecmp(val, "40") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005432 run_iwpriv(dut, intf, "chwidth 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005433 dut->chwidth = 1;
5434 } else if (strcasecmp(val, "80") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005435 run_iwpriv(dut, intf, "chwidth 2");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005436 dut->chwidth = 2;
5437 } else if (strcasecmp(val, "160") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005438 run_iwpriv(dut, intf, "chwidth 3");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005439 dut->chwidth = 3;
5440 } else {
5441 send_resp(dut, conn, SIGMA_ERROR,
5442 "ErrorCode,WIDTH not supported");
5443 return -1;
5444 }
5445
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005446 return 0;
5447}
5448
5449
5450static int wcn_sta_set_sp_stream(struct sigma_dut *dut, const char *intf,
5451 const char *val)
5452{
5453 char buf[60];
Arif Hussainac6c5112018-05-25 17:34:00 -07005454 int sta_nss;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005455
Amarnath Hullur Subramanyamd5374fa2018-02-25 19:00:24 -08005456 if (strcmp(val, "1SS") == 0 || strcmp(val, "1") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005457 snprintf(buf, sizeof(buf), "iwpriv %s nss 1", intf);
Arif Hussainac6c5112018-05-25 17:34:00 -07005458 sta_nss = 1;
Amarnath Hullur Subramanyamd5374fa2018-02-25 19:00:24 -08005459 } else if (strcmp(val, "2SS") == 0 || strcmp(val, "2") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005460 snprintf(buf, sizeof(buf), "iwpriv %s nss 2", intf);
Arif Hussainac6c5112018-05-25 17:34:00 -07005461 sta_nss = 2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005462 } else {
5463 sigma_dut_print(dut, DUT_MSG_ERROR,
5464 "SP_STREAM value not supported");
5465 return -1;
5466 }
5467
5468 if (system(buf) != 0) {
5469 sigma_dut_print(dut, DUT_MSG_ERROR,
5470 "Failed to set SP_STREAM");
5471 return -1;
5472 }
5473
Arif Hussainac6c5112018-05-25 17:34:00 -07005474 dut->sta_nss = sta_nss;
5475
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005476 return 0;
5477}
5478
5479
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05305480static void wcn_sta_set_stbc(struct sigma_dut *dut, const char *intf,
5481 const char *val)
5482{
5483 char buf[60];
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05305484 int ret;
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05305485
5486 snprintf(buf, sizeof(buf), "iwpriv %s tx_stbc %s", intf, val);
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05305487 ret = system(buf);
5488#ifdef NL80211_SUPPORT
5489 if (ret)
5490 ret = sta_config_params(dut, intf, STA_SET_TX_STBC,
5491 strcmp(val, "0") == 0 ? 0 : 1);
5492#endif /* NL80211_SUPPORT */
5493 if (ret)
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05305494 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv tx_stbc failed");
5495
5496 snprintf(buf, sizeof(buf), "iwpriv %s rx_stbc %s", intf, val);
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05305497 ret = system(buf);
5498#ifdef NL80211_SUPPORT
5499 if (ret)
5500 ret = sta_config_params(dut, intf, STA_SET_RX_STBC,
5501 strcmp(val, "0") == 0 ? 0 : 1);
5502#endif /* NL80211_SUPPORT */
5503 if (ret)
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05305504 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv rx_stbc failed");
5505}
5506
5507
Ashwini Patil68d02cd2017-01-10 15:39:16 +05305508static int mbo_set_cellular_data_capa(struct sigma_dut *dut,
5509 struct sigma_conn *conn,
5510 const char *intf, int capa)
5511{
5512 char buf[32];
5513
5514 if (capa > 0 && capa < 4) {
5515 snprintf(buf, sizeof(buf), "SET mbo_cell_capa %d", capa);
5516 if (wpa_command(intf, buf) < 0) {
5517 send_resp(dut, conn, SIGMA_ERROR,
5518 "ErrorCode, Failed to set cellular data capability");
5519 return 0;
5520 }
5521 return 1;
5522 }
5523
5524 sigma_dut_print(dut, DUT_MSG_ERROR,
5525 "Invalid Cellular data capability: %d", capa);
5526 send_resp(dut, conn, SIGMA_INVALID,
5527 "ErrorCode,Invalid cellular data capability");
5528 return 0;
5529}
5530
5531
Ashwini Patil9183fdb2017-04-13 16:58:25 +05305532static int mbo_set_roaming(struct sigma_dut *dut, struct sigma_conn *conn,
5533 const char *intf, const char *val)
5534{
5535 if (strcasecmp(val, "Disable") == 0) {
5536 if (wpa_command(intf, "SET roaming 0") < 0) {
5537 send_resp(dut, conn, SIGMA_ERROR,
5538 "ErrorCode,Failed to disable roaming");
5539 return 0;
5540 }
5541 return 1;
5542 }
5543
5544 if (strcasecmp(val, "Enable") == 0) {
5545 if (wpa_command(intf, "SET roaming 1") < 0) {
5546 send_resp(dut, conn, SIGMA_ERROR,
5547 "ErrorCode,Failed to enable roaming");
5548 return 0;
5549 }
5550 return 1;
5551 }
5552
5553 sigma_dut_print(dut, DUT_MSG_ERROR,
5554 "Invalid value provided for roaming: %s", val);
5555 send_resp(dut, conn, SIGMA_INVALID,
5556 "ErrorCode,Unknown value provided for Roaming");
5557 return 0;
5558}
5559
5560
Ashwini Patila75de5a2017-04-13 16:35:05 +05305561static int mbo_set_assoc_disallow(struct sigma_dut *dut,
5562 struct sigma_conn *conn,
5563 const char *intf, const char *val)
5564{
5565 if (strcasecmp(val, "Disable") == 0) {
5566 if (wpa_command(intf, "SET ignore_assoc_disallow 1") < 0) {
5567 send_resp(dut, conn, SIGMA_ERROR,
5568 "ErrorCode,Failed to disable Assoc_disallow");
5569 return 0;
5570 }
5571 return 1;
5572 }
5573
5574 if (strcasecmp(val, "Enable") == 0) {
5575 if (wpa_command(intf, "SET ignore_assoc_disallow 0") < 0) {
5576 send_resp(dut, conn, SIGMA_ERROR,
5577 "ErrorCode,Failed to enable Assoc_disallow");
5578 return 0;
5579 }
5580 return 1;
5581 }
5582
5583 sigma_dut_print(dut, DUT_MSG_ERROR,
5584 "Invalid value provided for Assoc_disallow: %s", val);
5585 send_resp(dut, conn, SIGMA_INVALID,
5586 "ErrorCode,Unknown value provided for Assoc_disallow");
5587 return 0;
5588}
5589
5590
Ashwini Patilc63161e2017-04-13 16:30:23 +05305591static int mbo_set_bss_trans_req(struct sigma_dut *dut, struct sigma_conn *conn,
5592 const char *intf, const char *val)
5593{
5594 if (strcasecmp(val, "Reject") == 0) {
5595 if (wpa_command(intf, "SET reject_btm_req_reason 1") < 0) {
5596 send_resp(dut, conn, SIGMA_ERROR,
5597 "ErrorCode,Failed to Reject BTM Request");
5598 return 0;
5599 }
5600 return 1;
5601 }
5602
5603 if (strcasecmp(val, "Accept") == 0) {
5604 if (wpa_command(intf, "SET reject_btm_req_reason 0") < 0) {
5605 send_resp(dut, conn, SIGMA_ERROR,
5606 "ErrorCode,Failed to Accept BTM Request");
5607 return 0;
5608 }
5609 return 1;
5610 }
5611
5612 sigma_dut_print(dut, DUT_MSG_ERROR,
5613 "Invalid value provided for BSS_Transition: %s", val);
5614 send_resp(dut, conn, SIGMA_INVALID,
5615 "ErrorCode,Unknown value provided for BSS_Transition");
5616 return 0;
5617}
5618
5619
Ashwini Patil00402582017-04-13 12:29:39 +05305620static int mbo_set_non_pref_ch_list(struct sigma_dut *dut,
5621 struct sigma_conn *conn,
5622 const char *intf,
5623 struct sigma_cmd *cmd)
5624{
5625 const char *ch, *pref, *op_class, *reason;
5626 char buf[120];
5627 int len, ret;
5628
5629 pref = get_param(cmd, "Ch_Pref");
5630 if (!pref)
5631 return 1;
5632
5633 if (strcasecmp(pref, "clear") == 0) {
5634 free(dut->non_pref_ch_list);
5635 dut->non_pref_ch_list = NULL;
5636 } else {
5637 op_class = get_param(cmd, "Ch_Op_Class");
5638 if (!op_class) {
5639 send_resp(dut, conn, SIGMA_INVALID,
5640 "ErrorCode,Ch_Op_Class not provided");
5641 return 0;
5642 }
5643
5644 ch = get_param(cmd, "Ch_Pref_Num");
5645 if (!ch) {
5646 send_resp(dut, conn, SIGMA_INVALID,
5647 "ErrorCode,Ch_Pref_Num not provided");
5648 return 0;
5649 }
5650
5651 reason = get_param(cmd, "Ch_Reason_Code");
5652 if (!reason) {
5653 send_resp(dut, conn, SIGMA_INVALID,
5654 "ErrorCode,Ch_Reason_Code not provided");
5655 return 0;
5656 }
5657
5658 if (!dut->non_pref_ch_list) {
5659 dut->non_pref_ch_list =
5660 calloc(1, NON_PREF_CH_LIST_SIZE);
5661 if (!dut->non_pref_ch_list) {
5662 send_resp(dut, conn, SIGMA_ERROR,
5663 "ErrorCode,Failed to allocate memory for non_pref_ch_list");
5664 return 0;
5665 }
5666 }
5667 len = strlen(dut->non_pref_ch_list);
5668 ret = snprintf(dut->non_pref_ch_list + len,
5669 NON_PREF_CH_LIST_SIZE - len,
5670 " %s:%s:%s:%s", op_class, ch, pref, reason);
5671 if (ret > 0 && ret < NON_PREF_CH_LIST_SIZE - len) {
5672 sigma_dut_print(dut, DUT_MSG_DEBUG, "non_pref_list: %s",
5673 dut->non_pref_ch_list);
5674 } else {
5675 sigma_dut_print(dut, DUT_MSG_ERROR,
5676 "snprintf failed for non_pref_list, ret = %d",
5677 ret);
5678 send_resp(dut, conn, SIGMA_ERROR,
5679 "ErrorCode,snprintf failed");
5680 free(dut->non_pref_ch_list);
5681 dut->non_pref_ch_list = NULL;
5682 return 0;
5683 }
5684 }
5685
5686 ret = snprintf(buf, sizeof(buf), "SET non_pref_chan%s",
5687 dut->non_pref_ch_list ? dut->non_pref_ch_list : " ");
5688 if (ret < 0 || ret >= (int) sizeof(buf)) {
5689 sigma_dut_print(dut, DUT_MSG_DEBUG,
5690 "snprintf failed for set non_pref_chan, ret: %d",
5691 ret);
5692 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,snprint failed");
5693 return 0;
5694 }
5695
5696 if (wpa_command(intf, buf) < 0) {
5697 send_resp(dut, conn, SIGMA_ERROR,
5698 "ErrorCode,Failed to set non-preferred channel list");
5699 return 0;
5700 }
5701
5702 return 1;
5703}
5704
5705
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08005706#ifdef NL80211_SUPPORT
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08005707
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08005708static int sta_set_he_htc_supp(struct sigma_dut *dut, const char *intf,
5709 uint8_t cfg)
5710{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05305711 return wcn_wifi_test_config_set_u8(
5712 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_HTC_HE_SUPP,
5713 cfg);
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08005714}
5715
5716
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08005717static int sta_set_he_fragmentation(struct sigma_dut *dut, const char *intf,
5718 enum he_fragmentation_val frag)
5719{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05305720 return wcn_wifi_test_config_set_u8(
5721 dut, intf,
5722 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_FRAGMENTATION, frag);
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08005723}
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08005724
5725
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -08005726int wcn_set_he_ltf(struct sigma_dut *dut, const char *intf,
5727 enum qca_wlan_he_ltf_cfg ltf)
Subhani Shaik8e7a3052018-04-24 14:03:00 -07005728{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05305729 return wcn_wifi_test_config_set_u8(
5730 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_LTF, ltf);
Subhani Shaik8e7a3052018-04-24 14:03:00 -07005731}
5732
5733
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08005734static int nlvendor_sta_set_noack(struct sigma_dut *dut, const char *intf,
5735 int noack, enum qca_wlan_ac_type ac)
5736{
5737 struct nl_msg *msg;
5738 int ret = 0;
5739 struct nlattr *params;
5740 int ifindex;
5741
5742 ifindex = if_nametoindex(intf);
5743 if (ifindex == 0) {
5744 sigma_dut_print(dut, DUT_MSG_ERROR,
5745 "%s: Index for interface %s failed",
5746 __func__, intf);
5747 return -1;
5748 }
5749
5750 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
5751 NL80211_CMD_VENDOR)) ||
5752 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
5753 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
5754 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
5755 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
5756 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
5757 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_NO_ACK,
5758 noack) ||
5759 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_NO_ACK_AC,
5760 ac)) {
5761 sigma_dut_print(dut, DUT_MSG_ERROR,
5762 "%s: err in adding vendor_cmd and vendor_data",
5763 __func__);
5764 nlmsg_free(msg);
5765 return -1;
5766 }
5767 nla_nest_end(msg, params);
5768
5769 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5770 if (ret) {
5771 sigma_dut_print(dut, DUT_MSG_ERROR,
5772 "%s: err in send_and_recv_msgs, ret=%d",
5773 __func__, ret);
5774 }
5775 return ret;
5776}
5777
5778
5779static void wcn_sta_set_noack(struct sigma_dut *dut, const char *intf,
5780 const char *val)
5781{
5782 int noack, ret;
5783 char token[100];
5784 char *result;
5785 char *saveptr;
5786 enum qca_wlan_ac_type ac = QCA_WLAN_AC_BE;
5787
5788 strlcpy(token, val, sizeof(token));
5789 token[sizeof(token) - 1] = '\0';
5790 result = strtok_r(token, ":", &saveptr);
5791 while (result) {
5792 noack = strcasecmp(result, "Disable") != 0;
5793 ret = nlvendor_sta_set_noack(dut, intf, noack, ac);
5794 if (ret) {
5795 sigma_dut_print(dut, DUT_MSG_ERROR,
5796 "nlvendor_sta_set_noack failed for ac:%d, ret:%d",
5797 ac, ret);
5798 }
5799 result = strtok_r(NULL, ":", &saveptr);
5800 ac++;
5801 }
5802}
5803
Vinita S. Maloo7462e812020-05-22 15:16:04 +05305804
5805static int nlvendor_sta_set_phymode(struct sigma_dut *dut, const char *intf,
5806 enum qca_wlan_vendor_phy_mode val)
5807{
5808 struct nl_msg *msg;
5809 struct nlattr *params;
5810 int ifindex, ret;
5811
5812 ifindex = if_nametoindex(intf);
5813 if (ifindex == 0) {
5814 sigma_dut_print(dut, DUT_MSG_ERROR,
5815 "%s: Index for interface %s not found",
5816 __func__, intf);
5817 return -1;
5818 }
5819
5820 msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
5821 NL80211_CMD_VENDOR);
5822 if (!msg) {
5823 sigma_dut_print(dut, DUT_MSG_ERROR,
5824 "%s: err in adding vendor_cmd", __func__);
5825 return -1;
5826 }
5827
5828 if (nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
5829 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
5830 QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION)) {
5831 sigma_dut_print(dut, DUT_MSG_ERROR,
5832 "%s: err in adding vendor_attr", __func__);
5833 nlmsg_free(msg);
5834 return -1;
5835 }
5836
5837 params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
5838 if (!params || nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_PHY_MODE,
5839 val)) {
5840 sigma_dut_print(dut, DUT_MSG_ERROR,
5841 "%s: err in adding vendor_data", __func__);
5842 nlmsg_free(msg);
5843 return -1;
5844 }
5845
5846 nla_nest_end(msg, params);
5847 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5848 if (ret) {
5849 sigma_dut_print(dut, DUT_MSG_ERROR,
5850 "%s: err in send_and_recv_msgs, ret=%d (%s)",
5851 __func__, ret, strerror(-ret));
5852 return ret;
5853 }
5854
5855 return 0;
5856}
5857
5858
5859static enum qca_wlan_vendor_phy_mode get_qca_vendor_phymode(const char *val)
5860{
5861 if (strcmp(val, "11a") == 0) {
5862 /* IEEE80211_MODE_11A */
5863 return QCA_WLAN_VENDOR_PHY_MODE_11A;
5864 }
5865
5866 if (strcmp(val, "11g") == 0) {
5867 /* IEEE80211_MODE_11G */
5868 return QCA_WLAN_VENDOR_PHY_MODE_11G;
5869 }
5870
5871 if (strcmp(val, "11b") == 0) {
5872 /* IEEE80211_MODE_11B */
5873 return QCA_WLAN_VENDOR_PHY_MODE_11B;
5874 }
5875
5876 if (strcmp(val, "11n") == 0 ||
5877 strcmp(val, "11nl") == 0 ||
5878 strcmp(val, "11nl(nabg)") == 0) {
5879 /* IEEE80211_MODE_11AGN */
5880 return QCA_WLAN_VENDOR_PHY_MODE_11AGN;
5881 }
5882
5883 if (strcmp(val, "11ng") == 0) {
5884 /* IEEE80211_MODE_11NG_HT40 */
5885 return QCA_WLAN_VENDOR_PHY_MODE_11NG_HT40;
5886 }
5887
5888 if (strcmp(val, "AC") == 0 ||
5889 strcasecmp(val, "11AC") == 0) {
5890 /* IEEE80211_MODE_11AC_VHT80 */
5891 return QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT80;
5892 }
5893
5894 if (strcmp(val, "11na") == 0 ||
5895 strcasecmp(val, "11an") == 0) {
5896 /* IEEE80211_MODE_11NA_HT40 */
5897 return QCA_WLAN_VENDOR_PHY_MODE_11NA_HT40;
5898 }
5899
5900 if (strcmp(val, "11ax") == 0 ||
5901 strcmp(val, "auto") == 0) {
5902 /* IEEE80211_MODE_AUTO */
5903 return QCA_WLAN_VENDOR_PHY_MODE_AUTO;
5904 }
5905
5906 return -1;
5907}
5908
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08005909#endif /* NL80211_SUPPORT */
5910
5911
Vinita S. Maloo13a5cf72020-05-22 14:45:06 +05305912static int get_phymode(const char *val)
5913{
5914 if (strcmp(val, "11a") == 0)
5915 return 1; /* IEEE80211_MODE_11A */
5916 if (strcmp(val, "11g") == 0)
5917 return 3; /* IEEE80211_MODE_11G */
5918 if (strcmp(val, "11b") == 0)
5919 return 2; /* IEEE80211_MODE_11B */
5920 if (strcmp(val, "11n") == 0 ||
5921 strcmp(val, "11nl") == 0 ||
5922 strcmp(val, "11nl(nabg)") == 0)
5923 return 22; /* IEEE80211_MODE_11AGN */
5924 if (strcmp(val, "11ng") == 0)
5925 return 13; /* IEEE80211_MODE_11NG_HT40 */
5926 if (strcmp(val, "AC") == 0 ||
5927 strcasecmp(val, "11AC") == 0)
5928 return 19; /* IEEE80211_MODE_11AC_VHT80 */
5929 if (strcmp(val, "11na") == 0 ||
5930 strcasecmp(val, "11an") == 0)
5931 return 14; /* IEEE80211_MODE_11NA_HT40 */
5932 if (strcmp(val, "11ax") == 0 ||
5933 strcmp(val, "auto") == 0)
5934 return 0; /* IEEE80211_MODE_AUTO */
5935 return -1;
5936}
5937
5938
5939static void sta_set_phymode(struct sigma_dut *dut, const char *intf,
5940 const char *val)
5941{
5942 char buf[100];
5943 int len, phymode;
Vinita S. Maloo7462e812020-05-22 15:16:04 +05305944#ifdef NL80211_SUPPORT
5945 enum qca_wlan_vendor_phy_mode qca_phymode;
5946
5947 qca_phymode = get_qca_vendor_phymode(val);
5948 if (qca_phymode == -1) {
5949 sigma_dut_print(dut, DUT_MSG_DEBUG,
5950 "Ignoring mode change for mode: %s",
5951 val);
5952 return;
5953 }
5954
5955 if (nlvendor_sta_set_phymode(dut, intf, qca_phymode) == 0)
5956 return;
5957#endif /* NL80211_SUPPORT */
Vinita S. Maloo13a5cf72020-05-22 14:45:06 +05305958
5959 phymode = get_phymode(val);
5960 if (phymode == -1) {
5961 sigma_dut_print(dut, DUT_MSG_DEBUG,
5962 "Ignoring mode change for mode: %s",
5963 val);
5964 return;
5965 }
5966
5967 len = snprintf(buf, sizeof(buf), "iwpriv %s setphymode %d", intf,
5968 phymode);
5969 if (len < 0 || len >= sizeof(buf)) {
5970 sigma_dut_print(dut, DUT_MSG_ERROR,
5971 "Failed to set phymode");
5972 return;
5973 }
5974
5975 if (system(buf) != 0)
5976 sigma_dut_print(dut, DUT_MSG_ERROR,
5977 "iwpriv setting of phymode failed");
5978}
5979
5980
Jouni Malinenf7222712019-06-13 01:50:21 +03005981static enum sigma_cmd_result
5982cmd_sta_preset_testparameters(struct sigma_dut *dut, struct sigma_conn *conn,
5983 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005984{
5985 const char *intf = get_param(cmd, "Interface");
5986 const char *val;
5987
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03005988 val = get_param(cmd, "FT_DS");
5989 if (val) {
Veerendranath Jakkam19cc24c2022-03-28 18:47:03 +05305990 int sta_ft_ds;
5991
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03005992 if (strcasecmp(val, "Enable") == 0) {
Veerendranath Jakkam19cc24c2022-03-28 18:47:03 +05305993 sta_ft_ds = 1;
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03005994 } else if (strcasecmp(val, "Disable") == 0) {
Veerendranath Jakkam19cc24c2022-03-28 18:47:03 +05305995 sta_ft_ds = 0;
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03005996 } else {
5997 send_resp(dut, conn, SIGMA_ERROR,
5998 "errorCode,Unsupported value for FT_DS");
5999 return STATUS_SENT_ERROR;
6000 }
Veerendranath Jakkam19cc24c2022-03-28 18:47:03 +05306001
6002 if (dut->sta_ft_ds != sta_ft_ds &&
6003 get_driver_type(dut) == DRIVER_WCN &&
Shivani Baranwal7aa48602021-09-29 10:53:38 +05306004 sta_config_params(dut, intf, STA_SET_FT_DS,
Veerendranath Jakkam19cc24c2022-03-28 18:47:03 +05306005 sta_ft_ds) != 0) {
Shivani Baranwal7aa48602021-09-29 10:53:38 +05306006 send_resp(dut, conn, SIGMA_ERROR,
6007 "errorCode,Failed to enable/disable FT_DS");
6008 return STATUS_SENT_ERROR;
6009 }
Veerendranath Jakkam19cc24c2022-03-28 18:47:03 +05306010
6011 dut->sta_ft_ds = sta_ft_ds;
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006012 }
6013
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006014 val = get_param(cmd, "Program");
Jouni Malinen1f6ae642018-06-07 23:56:13 +03006015 if (val && (strcasecmp(val, "HS2-R2") == 0 ||
Jouni Malinen9a742ff2022-01-27 00:43:14 +02006016 strcasecmp(val, "HS2-R3") == 0 ||
6017 strcasecmp(val, "HS2-R4") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006018 return cmd_sta_preset_testparameters_hs2_r2(dut, conn, intf,
6019 cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006020
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07006021 if (val && strcasecmp(val, "LOC") == 0)
6022 return loc_cmd_sta_preset_testparameters(dut, conn, cmd);
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02006023 if (val && strcasecmp(val, "60GHZ") == 0) {
6024 val = get_param(cmd, "WPS");
6025 if (val && strcasecmp(val, "disable") == 0) {
6026 dut->wps_disable = 1;
6027 sigma_dut_print(dut, DUT_MSG_INFO, "WPS disabled");
6028 } else {
6029 /* wps_disable can have other value from the previous
6030 * test, so make sure it has the correct value.
6031 */
6032 dut->wps_disable = 0;
6033 }
6034
6035 val = get_param(cmd, "P2P");
6036 if (val && strcasecmp(val, "disable") == 0)
6037 sigma_dut_print(dut, DUT_MSG_INFO, "P2P disabled");
6038 }
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07006039
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02006040 if (dut->program == PROGRAM_WPS && dut->band == WPS_BAND_60G)
6041 return cmd_sta_preset_testparameters_60ghz(dut, conn, cmd);
6042
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006043#ifdef ANDROID_NAN
6044 if (val && strcasecmp(val, "NAN") == 0)
6045 return nan_cmd_sta_preset_testparameters(dut, conn, cmd);
6046#endif /* ANDROID_NAN */
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07006047#ifdef MIRACAST
6048 if (val && (strcasecmp(val, "WFD") == 0 ||
6049 strcasecmp(val, "DisplayR2") == 0))
6050 return miracast_preset_testparameters(dut, conn, cmd);
6051#endif /* MIRACAST */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006052
Kiran Kumar Lokeredd086642020-06-04 00:29:26 -07006053 if (val &&
6054 (strcasecmp(val, "MBO") == 0 || strcasecmp(val, "HE") == 0)) {
Ashwini Patil68d02cd2017-01-10 15:39:16 +05306055 val = get_param(cmd, "Cellular_Data_Cap");
6056 if (val &&
6057 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
6058 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +05306059
6060 val = get_param(cmd, "Ch_Pref");
6061 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
6062 return 0;
6063
Ashwini Patilc63161e2017-04-13 16:30:23 +05306064 val = get_param(cmd, "BSS_Transition");
6065 if (val && mbo_set_bss_trans_req(dut, conn, intf, val) == 0)
6066 return 0;
6067
Ashwini Patila75de5a2017-04-13 16:35:05 +05306068 val = get_param(cmd, "Assoc_Disallow");
6069 if (val && mbo_set_assoc_disallow(dut, conn, intf, val) == 0)
6070 return 0;
6071
Ashwini Patil9183fdb2017-04-13 16:58:25 +05306072 val = get_param(cmd, "Roaming");
6073 if (val && mbo_set_roaming(dut, conn, intf, val) == 0)
6074 return 0;
6075
Ashwini Patil68d02cd2017-01-10 15:39:16 +05306076 return 1;
6077 }
6078
Ankita Bajaja2cb5672017-10-25 16:08:28 +05306079 if (val && strcasecmp(val, "OCE") == 0)
6080 return cmd_sta_preset_testparameters_oce(dut, conn, intf, cmd);
6081
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006082#if 0
6083 val = get_param(cmd, "Supplicant");
6084 if (val && strcasecmp(val, "Default") != 0) {
6085 send_resp(dut, conn, SIGMA_ERROR,
6086 "ErrorCode,Only default(Vendor) supplicant "
6087 "supported");
6088 return 0;
6089 }
6090#endif
6091
6092 val = get_param(cmd, "RTS");
6093 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006094 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006095 case DRIVER_ATHEROS:
6096 ath_sta_set_rts(dut, intf, val);
6097 break;
6098 default:
6099#if 0
6100 send_resp(dut, conn, SIGMA_ERROR,
6101 "ErrorCode,Setting RTS not supported");
6102 return 0;
6103#else
6104 sigma_dut_print(dut, DUT_MSG_DEBUG,
6105 "Setting RTS not supported");
6106 break;
6107#endif
6108 }
6109 }
6110
6111#if 0
6112 val = get_param(cmd, "FRGMNT");
6113 if (val) {
6114 /* TODO */
6115 send_resp(dut, conn, SIGMA_ERROR,
6116 "ErrorCode,Setting FRGMNT not supported");
6117 return 0;
6118 }
6119#endif
6120
6121#if 0
6122 val = get_param(cmd, "Preamble");
6123 if (val) {
6124 /* TODO: Long/Short */
6125 send_resp(dut, conn, SIGMA_ERROR,
6126 "ErrorCode,Setting Preamble not supported");
6127 return 0;
6128 }
6129#endif
6130
6131 val = get_param(cmd, "Mode");
6132 if (val) {
6133 if (strcmp(val, "11b") == 0 ||
6134 strcmp(val, "11g") == 0 ||
6135 strcmp(val, "11a") == 0 ||
6136 strcmp(val, "11n") == 0 ||
6137 strcmp(val, "11ng") == 0 ||
6138 strcmp(val, "11nl") == 0 ||
6139 strcmp(val, "11nl(nabg)") == 0 ||
6140 strcmp(val, "AC") == 0 ||
6141 strcmp(val, "11AC") == 0 ||
6142 strcmp(val, "11ac") == 0 ||
6143 strcmp(val, "11na") == 0 ||
Amarnath Hullur Subramanyamb0db2712018-01-30 19:40:35 -08006144 strcmp(val, "11an") == 0 ||
6145 strcmp(val, "11ax") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006146 /* STA supports all modes by default */
6147 } else {
6148 send_resp(dut, conn, SIGMA_ERROR,
6149 "ErrorCode,Setting Mode not supported");
6150 return 0;
6151 }
Amarnath Hullur Subramanyam97d0e532018-01-31 02:53:02 -08006152
6153 /* Change the mode only in case of testbed for HE program
6154 * and for 11a and 11g modes only. */
6155 if (dut->program == PROGRAM_HE &&
6156 dut->device_type == STA_testbed) {
Vinita S. Maloo13a5cf72020-05-22 14:45:06 +05306157 sta_set_phymode(dut, intf, val);
Amarnath Hullur Subramanyam97d0e532018-01-31 02:53:02 -08006158 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006159 }
6160
6161 val = get_param(cmd, "wmm");
6162 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006163 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006164 case DRIVER_ATHEROS:
6165 ath_sta_set_wmm(dut, intf, val);
6166 break;
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08006167 case DRIVER_WCN:
6168 wcn_sta_set_wmm(dut, intf, val);
6169 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006170 default:
6171 sigma_dut_print(dut, DUT_MSG_DEBUG,
6172 "Setting wmm not supported");
6173 break;
6174 }
6175 }
6176
6177 val = get_param(cmd, "Powersave");
6178 if (val) {
6179 if (strcmp(val, "0") == 0 || strcasecmp(val, "off") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006180 if (get_driver_type(dut) == DRIVER_WCN) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +05306181 if (set_power_save_wcn(dut, intf, 2) < 0)
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08006182 return 0;
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08006183 }
6184
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006185 if (wpa_command(get_station_ifname(dut),
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006186 "P2P_SET ps 0") < 0)
6187 return -2;
6188 /* Make sure test modes are disabled */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006189 wpa_command(get_station_ifname(dut), "P2P_SET ps 98");
6190 wpa_command(get_station_ifname(dut), "P2P_SET ps 96");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006191 } else if (strcmp(val, "1") == 0 ||
6192 strcasecmp(val, "PSPoll") == 0 ||
6193 strcasecmp(val, "on") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006194 if (get_driver_type(dut) == DRIVER_WCN) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +05306195 if (set_power_save_wcn(dut, intf, 1) < 0)
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08006196 return 0;
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08006197 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006198 /* Disable default power save mode */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006199 wpa_command(get_station_ifname(dut), "P2P_SET ps 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006200 /* Enable PS-Poll test mode */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006201 if (wpa_command(get_station_ifname(dut),
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006202 "P2P_SET ps 97") < 0 ||
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006203 wpa_command(get_station_ifname(dut),
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006204 "P2P_SET ps 99") < 0)
6205 return -2;
6206 } else if (strcmp(val, "2") == 0 ||
6207 strcasecmp(val, "Fast") == 0) {
6208 /* TODO */
6209 send_resp(dut, conn, SIGMA_ERROR,
6210 "ErrorCode,Powersave=Fast not supported");
6211 return 0;
6212 } else if (strcmp(val, "3") == 0 ||
6213 strcasecmp(val, "PSNonPoll") == 0) {
6214 /* Make sure test modes are disabled */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006215 wpa_command(get_station_ifname(dut), "P2P_SET ps 98");
6216 wpa_command(get_station_ifname(dut), "P2P_SET ps 96");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006217
6218 /* Enable default power save mode */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006219 if (wpa_command(get_station_ifname(dut),
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006220 "P2P_SET ps 1") < 0)
6221 return -2;
6222 } else
6223 return -1;
6224 }
6225
6226 val = get_param(cmd, "NoAck");
6227 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006228 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006229 case DRIVER_ATHEROS:
6230 ath_sta_set_noack(dut, intf, val);
6231 break;
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08006232#ifdef NL80211_SUPPORT
6233 case DRIVER_WCN:
6234 wcn_sta_set_noack(dut, intf, val);
6235 break;
6236#endif /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006237 default:
6238 send_resp(dut, conn, SIGMA_ERROR,
6239 "ErrorCode,Setting NoAck not supported");
6240 return 0;
6241 }
6242 }
6243
6244 val = get_param(cmd, "IgnoreChswitchProhibit");
6245 if (val) {
6246 /* TODO: Enabled/disabled */
6247 if (strcasecmp(val, "Enabled") == 0) {
6248 send_resp(dut, conn, SIGMA_ERROR,
6249 "ErrorCode,Enabling IgnoreChswitchProhibit "
6250 "not supported");
6251 return 0;
6252 }
6253 }
6254
6255 val = get_param(cmd, "TDLS");
6256 if (val) {
6257 if (strcasecmp(val, "Disabled") == 0) {
6258 if (wpa_command(intf, "SET tdls_disabled 1")) {
6259 send_resp(dut, conn, SIGMA_ERROR,
6260 "ErrorCode,Failed to disable TDLS");
6261 return 0;
6262 }
6263 } else if (strcasecmp(val, "Enabled") == 0) {
6264 if (wpa_command(intf, "SET tdls_disabled 0")) {
6265 send_resp(dut, conn, SIGMA_ERROR,
6266 "ErrorCode,Failed to enable TDLS");
6267 return 0;
6268 }
6269 } else {
6270 send_resp(dut, conn, SIGMA_ERROR,
6271 "ErrorCode,Unsupported TDLS value");
6272 return 0;
6273 }
6274 }
6275
6276 val = get_param(cmd, "TDLSmode");
6277 if (val) {
6278 if (strcasecmp(val, "Default") == 0) {
6279 wpa_command(intf, "SET tdls_testing 0");
6280 } else if (strcasecmp(val, "APProhibit") == 0) {
6281 if (wpa_command(intf, "SET tdls_testing 0x400")) {
6282 send_resp(dut, conn, SIGMA_ERROR,
6283 "ErrorCode,Failed to enable ignore "
6284 "APProhibit TDLS mode");
6285 return 0;
6286 }
6287 } else if (strcasecmp(val, "HiLoMac") == 0) {
6288 /* STA should respond with TDLS setup req for a TDLS
6289 * setup req */
6290 if (wpa_command(intf, "SET tdls_testing 0x80")) {
6291 send_resp(dut, conn, SIGMA_ERROR,
6292 "ErrorCode,Failed to enable HiLoMac "
6293 "TDLS mode");
6294 return 0;
6295 }
6296 } else if (strcasecmp(val, "WeakSecurity") == 0) {
6297 /*
6298 * Since all security modes are enabled by default when
6299 * Sigma control is used, there is no need to do
6300 * anything here.
6301 */
6302 } else if (strcasecmp(val, "ExistLink") == 0) {
6303 /*
6304 * Since we allow new TDLS Setup Request even if there
6305 * is an existing link, nothing needs to be done for
6306 * this.
6307 */
6308 } else {
6309 /* TODO:
6310 * ExistLink: STA should send TDLS setup req even if
6311 * direct link already exists
6312 */
6313 send_resp(dut, conn, SIGMA_ERROR,
6314 "ErrorCode,Unsupported TDLSmode value");
6315 return 0;
6316 }
6317 }
6318
6319 val = get_param(cmd, "FakePubKey");
6320 if (val && atoi(val) && wpa_command(intf, "SET wps_corrupt_pkhash 1")) {
6321 send_resp(dut, conn, SIGMA_ERROR,
6322 "ErrorCode,Failed to enable FakePubKey");
6323 return 0;
6324 }
6325
Amarnath Hullur Subramanyamae1042b2018-02-22 21:52:52 -08006326#ifdef NL80211_SUPPORT
6327 val = get_param(cmd, "FrgmntSupport");
6328 if (val) {
6329 if (strcasecmp(val, "Enable") == 0) {
6330 if (sta_set_he_fragmentation(dut, intf,
6331 HE_FRAG_LEVEL1)) {
6332 send_resp(dut, conn, SIGMA_ERROR,
6333 "ErrorCode,Failed to enable HE Fragmentation");
6334 return 0;
6335 }
6336 } else if (strcasecmp(val, "Disable") == 0) {
6337 if (sta_set_he_fragmentation(dut, intf,
6338 HE_FRAG_DISABLE)) {
6339 send_resp(dut, conn, SIGMA_ERROR,
6340 "ErrorCode,Failed to disable HE Fragmentation");
6341 return 0;
6342 }
6343 }
6344 }
6345#endif /* NL80211_SUPPORT */
6346
Vinita S. Maloo8a4779c2020-06-22 19:32:37 +05306347 val = get_param(cmd, "IncludeMSCSDescriptor");
6348 if (val && strcasecmp(val, "1") == 0) {
6349 char buf[128];
6350 int len;
6351
6352 len = snprintf(buf, sizeof(buf),
Veerendranath Jakkam62cde372020-08-19 18:03:06 +05306353 "MSCS add up_bitmap=F0 up_limit=7 stream_timeout=60000 frame_classifier=045F%032x",
Vinita S. Maloo8a4779c2020-06-22 19:32:37 +05306354 0);
6355
6356 if (len < 0 || len >= sizeof(buf)) {
6357 sigma_dut_print(dut, DUT_MSG_ERROR,
6358 "Failed to build MSCS Descriptor IE");
6359 return ERROR_SEND_STATUS;
6360 }
6361
6362 if (wpa_command(intf, buf) != 0) {
6363 send_resp(dut, conn, SIGMA_ERROR,
6364 "ErrorCode,Failed to include MSCS descriptor");
6365 return STATUS_SENT_ERROR;
6366 }
6367 }
6368
Vinita S. Maloo2287f142021-02-01 16:17:09 +05306369 val = get_param(cmd, "SCSSupport");
6370 if (val) {
6371 char buf[30];
6372 int disable_scs, len;
6373
6374 if (strcasecmp(val, "Enable") == 0) {
6375 disable_scs = 0;
6376 } else if (strcasecmp(val, "Disable") == 0) {
6377 disable_scs = 1;
6378 } else {
6379 sigma_dut_print(dut, DUT_MSG_ERROR,
6380 "Invalid SCSsupport parameter");
6381 return INVALID_SEND_STATUS;
6382 }
6383
Shivani Baranwalebde8f62021-10-19 12:26:02 +05306384 if (disable_scs || dut->prev_disable_scs_support) {
6385 len = snprintf(buf, sizeof(buf),
6386 "SET disable_scs_support %d",
6387 disable_scs);
6388 if (len < 0 || len >= sizeof(buf) ||
6389 wpa_command(intf, buf) != 0) {
6390 send_resp(dut, conn, SIGMA_ERROR,
6391 "ErrorCode,Failed to update SCS support");
6392 return STATUS_SENT_ERROR;
6393 }
6394 dut->prev_disable_scs_support = disable_scs;
Vinita S. Maloo2287f142021-02-01 16:17:09 +05306395 }
6396 }
6397
Vinita S. Maloo83dee552021-04-12 16:47:47 +05306398 val = get_param(cmd, "MSCSSupport");
6399 if (val) {
6400 char buf[30];
6401 int disable_mscs, len;
6402
6403 if (strcasecmp(val, "Enable") == 0) {
6404 disable_mscs = 0;
6405 } else if (strcasecmp(val, "Disable") == 0) {
6406 disable_mscs = 1;
6407 } else {
6408 sigma_dut_print(dut, DUT_MSG_ERROR,
6409 "Invalid MSCSsupport parameter");
6410 return INVALID_SEND_STATUS;
6411 }
6412
Shivani Baranwalebde8f62021-10-19 12:26:02 +05306413 if (disable_mscs || dut->prev_disable_mscs_support) {
6414 len = snprintf(buf, sizeof(buf),
6415 "SET disable_mscs_support %d",
6416 disable_mscs);
6417 if (len < 0 || len >= sizeof(buf) ||
6418 wpa_command(intf, buf) != 0) {
6419 send_resp(dut, conn, SIGMA_ERROR,
6420 "ErrorCode,Failed to update MSCS support");
6421 return STATUS_SENT_ERROR;
6422 }
6423 dut->prev_disable_mscs_support = disable_mscs;
Vinita S. Maloo83dee552021-04-12 16:47:47 +05306424 }
6425 }
6426
Veerendranath Jakkama16cdc82021-09-12 16:44:22 +05306427 val = get_param(cmd, "DSCPPolicyCapability");
6428 if (val) {
6429 char buf[35];
6430 int len;
6431
6432 if (strcasecmp(val, "Enable") == 0) {
6433 len = snprintf(buf, sizeof(buf),
6434 "SET enable_dscp_policy_capa 1");
6435 } else if (strcasecmp(val, "Disable") == 0) {
6436 len = snprintf(buf, sizeof(buf),
6437 "SET enable_dscp_policy_capa 0");
6438 } else {
6439 sigma_dut_print(dut, DUT_MSG_ERROR,
6440 "Invalid DSCP policy parameter");
6441 return INVALID_SEND_STATUS;
6442 }
6443
6444 if (len < 0 || len >= sizeof(buf) ||
6445 wpa_command(intf, buf) != 0) {
6446 send_resp(dut, conn, SIGMA_ERROR,
6447 "ErrorCode,Failed to update DSCP policy capability");
6448 return STATUS_SENT_ERROR;
6449 }
6450 }
6451
6452 val = get_param(cmd, "DSCPPolicyRespParams");
6453 if (val) {
6454 if (strcasecmp(val, "RejectAll") == 0) {
6455 dut->reject_dscp_policies = 1;
6456 dut->dscp_reject_resp_code = DSCP_POLICY_REJECT;
6457 } else if (strcasecmp(val, "AcceptAll") == 0) {
6458 dut->reject_dscp_policies = 0;
6459 }
6460 }
6461
6462 val = get_param(cmd, "DSCPPolicyResp_StatusCode");
6463 if (val)
6464 dut->dscp_reject_resp_code = atoi(val);
6465
Veerendranath Jakkamf6c8ab52022-03-10 05:43:02 -08006466 val = get_param(cmd, "Deauth_Reconnect_Policy");
6467 if (val) {
6468 char buf[35];
6469 int len;
6470
6471 if (strcasecmp(val, "0") == 0) {
6472 len = snprintf(buf, sizeof(buf),
6473 "STA_AUTOCONNECT %d",
6474 dut->autoconnect_default);
6475 } else if (strcasecmp(val, "1") == 0) {
6476 len = snprintf(buf, sizeof(buf),
6477 "STA_AUTOCONNECT 0");
6478 } else if (strcasecmp(val, "2") == 0) {
6479 len = snprintf(buf, sizeof(buf),
6480 "STA_AUTOCONNECT 1");
6481 } else {
6482 sigma_dut_print(dut, DUT_MSG_ERROR,
6483 "Invalid Deauth_Reconnect_Policy");
6484 return INVALID_SEND_STATUS;
6485 }
6486
6487 if (len < 0 || len >= sizeof(buf) ||
6488 wpa_command(intf, buf) != 0) {
6489 send_resp(dut, conn, SIGMA_ERROR,
6490 "ErrorCode,Failed to update Deauth_Reconnect_Policy");
6491 return STATUS_SENT_ERROR;
6492 }
6493 }
6494
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006495 return 1;
6496}
6497
6498
6499static const char * ath_get_radio_name(const char *radio_name)
6500{
6501 if (radio_name == NULL)
6502 return "wifi0";
6503 if (strcmp(radio_name, "wifi1") == 0)
6504 return "wifi1";
6505 if (strcmp(radio_name, "wifi2") == 0)
6506 return "wifi2";
6507 return "wifi0";
6508}
6509
6510
6511static void ath_sta_set_txsp_stream(struct sigma_dut *dut, const char *intf,
6512 const char *val)
6513{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006514 unsigned int vht_mcsmap = 0;
6515 int txchainmask = 0;
6516 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
6517
6518 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
6519 if (dut->testbed_flag_txsp == 1) {
6520 vht_mcsmap = 0xfffc;
6521 dut->testbed_flag_txsp = 0;
6522 } else {
6523 vht_mcsmap = 0xfffe;
6524 }
6525 txchainmask = 1;
6526 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
6527 if (dut->testbed_flag_txsp == 1) {
6528 vht_mcsmap = 0xfff0;
6529 dut->testbed_flag_txsp = 0;
6530 } else {
6531 vht_mcsmap = 0xfffa;
6532 }
6533 txchainmask = 3;
6534 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
6535 if (dut->testbed_flag_txsp == 1) {
6536 vht_mcsmap = 0xffc0;
6537 dut->testbed_flag_txsp = 0;
6538 } else {
6539 vht_mcsmap = 0xffea;
6540 }
6541 txchainmask = 7;
6542 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
6543 if (dut->testbed_flag_txsp == 1) {
6544 vht_mcsmap = 0xff00;
6545 dut->testbed_flag_txsp = 0;
6546 } else {
6547 vht_mcsmap = 0xffaa;
6548 }
6549 txchainmask = 15;
6550 } else {
6551 if (dut->testbed_flag_txsp == 1) {
6552 vht_mcsmap = 0xffc0;
6553 dut->testbed_flag_txsp = 0;
6554 } else {
6555 vht_mcsmap = 0xffea;
6556 }
6557 }
6558
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006559 if (txchainmask)
6560 run_iwpriv(dut, basedev, "txchainmask %d", txchainmask);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006561
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006562 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006563}
6564
6565
6566static void ath_sta_set_rxsp_stream(struct sigma_dut *dut, const char *intf,
6567 const char *val)
6568{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006569 unsigned int vht_mcsmap = 0;
6570 int rxchainmask = 0;
6571 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
6572
6573 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
6574 if (dut->testbed_flag_rxsp == 1) {
6575 vht_mcsmap = 0xfffc;
6576 dut->testbed_flag_rxsp = 0;
6577 } else {
6578 vht_mcsmap = 0xfffe;
6579 }
6580 rxchainmask = 1;
6581 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
6582 if (dut->testbed_flag_rxsp == 1) {
6583 vht_mcsmap = 0xfff0;
6584 dut->testbed_flag_rxsp = 0;
6585 } else {
6586 vht_mcsmap = 0xfffa;
6587 }
6588 rxchainmask = 3;
6589 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
6590 if (dut->testbed_flag_rxsp == 1) {
6591 vht_mcsmap = 0xffc0;
6592 dut->testbed_flag_rxsp = 0;
6593 } else {
6594 vht_mcsmap = 0xffea;
6595 }
6596 rxchainmask = 7;
6597 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
6598 if (dut->testbed_flag_rxsp == 1) {
6599 vht_mcsmap = 0xff00;
6600 dut->testbed_flag_rxsp = 0;
6601 } else {
6602 vht_mcsmap = 0xffaa;
6603 }
6604 rxchainmask = 15;
6605 } else {
6606 if (dut->testbed_flag_rxsp == 1) {
6607 vht_mcsmap = 0xffc0;
6608 dut->testbed_flag_rxsp = 0;
6609 } else {
6610 vht_mcsmap = 0xffea;
6611 }
6612 }
6613
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006614 if (rxchainmask)
6615 run_iwpriv(dut, basedev, "rxchainmask %d", rxchainmask);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006616
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006617 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006618}
6619
6620
6621void ath_set_zero_crc(struct sigma_dut *dut, const char *val)
6622{
6623 if (strcasecmp(val, "enable") == 0) {
6624 if (system("athdiag --set --address=0x2a204 --and=0xbfffffff")
6625 != 0) {
6626 sigma_dut_print(dut, DUT_MSG_ERROR,
6627 "Disable BB_VHTSIGB_CRC_CALC failed");
6628 }
6629
6630 if (system("athdiag --set --address=0x2a204 --or=0x80000000")
6631 != 0) {
6632 sigma_dut_print(dut, DUT_MSG_ERROR,
6633 "Enable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
6634 }
6635 } else {
6636 if (system("athdiag --set --address=0x2a204 --and=0x7fffffff")
6637 != 0) {
6638 sigma_dut_print(dut, DUT_MSG_ERROR,
6639 "Disable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
6640 }
6641
6642 if (system("athdiag --set --address=0x2a204 --or=0x40000000")
6643 != 0) {
6644 sigma_dut_print(dut, DUT_MSG_ERROR,
6645 "Enable BB_VHTSIGB_CRC_CALC failed");
6646 }
6647 }
6648}
6649
6650
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08006651static int wcn_sta_set_width(struct sigma_dut *dut, const char *intf,
6652 const char *val)
6653{
6654 char buf[60];
6655
Shivani Baranwal2a572842021-09-16 12:27:15 +05306656#ifdef NL80211_SUPPORT
6657 enum nl80211_chan_width qca_channel_width;
6658
6659 if (strcmp(val, "20") == 0) {
6660 qca_channel_width = NL80211_CHAN_WIDTH_20;
6661 dut->chwidth = 0;
6662 } else if (strcmp(val, "40") == 0) {
6663 qca_channel_width = NL80211_CHAN_WIDTH_40;
6664 dut->chwidth = 1;
6665 } else if (strcmp(val, "80") == 0) {
6666 qca_channel_width = NL80211_CHAN_WIDTH_80;
6667 dut->chwidth = 2;
6668 } else if (strcmp(val, "160") == 0) {
6669 qca_channel_width = NL80211_CHAN_WIDTH_160;
6670 dut->chwidth = 3;
6671 } else if (strcasecmp(val, "Auto") == 0) {
6672 return 0;
6673 } else {
6674 sigma_dut_print(dut, DUT_MSG_ERROR, "WIDTH %s not supported",
6675 val);
6676 return -1;
6677 }
6678 if (sta_config_params(dut, intf, STA_SET_CHAN_WIDTH,
6679 qca_channel_width) == 0)
6680 return 0;
6681#endif /* NL80211_SUPPORT */
6682
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08006683 if (strcmp(val, "20") == 0) {
6684 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 0", intf);
6685 dut->chwidth = 0;
6686 } else if (strcmp(val, "40") == 0) {
6687 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 1", intf);
6688 dut->chwidth = 1;
6689 } else if (strcmp(val, "80") == 0) {
6690 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 2", intf);
6691 dut->chwidth = 2;
Sunil Duttb1cccac2018-05-22 21:03:12 +05306692 } else if (strcasecmp(val, "Auto") == 0) {
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08006693 buf[0] = '\0';
6694 } else {
6695 sigma_dut_print(dut, DUT_MSG_ERROR, "WIDTH %s not supported",
6696 val);
6697 return -1;
6698 }
6699
6700 if (buf[0] != '\0' && system(buf) != 0) {
6701 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv chwidth failed");
6702 return -1;
6703 }
6704
6705 return 0;
6706}
6707
6708
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006709static int nlvendor_sta_set_addba_reject(struct sigma_dut *dut,
6710 const char *intf, int addbareject)
6711{
6712#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05306713 return wcn_wifi_test_config_set_u8(
6714 dut, intf,
6715 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ACCEPT_ADDBA_REQ,
6716 !addbareject);
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006717#else /* NL80211_SUPPORT */
6718 sigma_dut_print(dut, DUT_MSG_ERROR,
6719 "ADDBA_REJECT cannot be set without NL80211_SUPPORT defined");
6720 return -1;
6721#endif /* NL80211_SUPPORT */
6722}
6723
6724
6725static int sta_set_addba_reject(struct sigma_dut *dut, const char *intf,
6726 int addbareject)
6727{
6728 int ret;
6729
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006730 switch (get_driver_type(dut)) {
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006731 case DRIVER_WCN:
6732 ret = nlvendor_sta_set_addba_reject(dut, intf, addbareject);
6733 if (ret) {
6734 sigma_dut_print(dut, DUT_MSG_ERROR,
6735 "nlvendor_sta_set_addba_reject failed, ret:%d",
6736 ret);
6737 return ret;
6738 }
6739 break;
6740 default:
6741 sigma_dut_print(dut, DUT_MSG_ERROR,
6742 "errorCode,Unsupported ADDBA_REJECT with the current driver");
6743 ret = -1;
6744 break;
6745 }
6746
6747 return ret;
6748}
6749
6750
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08006751static int nlvendor_config_send_addba(struct sigma_dut *dut, const char *intf,
6752 int enable)
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08006753{
6754#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05306755 return wcn_wifi_test_config_set_u8(
6756 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_SEND_ADDBA_REQ,
6757 enable);
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08006758#else /* NL80211_SUPPORT */
6759 sigma_dut_print(dut, DUT_MSG_ERROR,
6760 "Disable addba not possible without NL80211_SUPPORT defined");
6761 return -1;
6762#endif /* NL80211_SUPPORT */
6763}
6764
6765
Veerendranath Jakkamadcd6202019-04-17 12:32:21 +05306766#ifdef NL80211_SUPPORT
6767static int nl80211_sta_set_rts(struct sigma_dut *dut, const char *intf, int val)
6768{
6769 struct nl_msg *msg;
6770 int ret = 0;
6771 int ifindex;
6772
6773 ifindex = if_nametoindex(intf);
6774 if (ifindex == 0) {
6775 sigma_dut_print(dut, DUT_MSG_ERROR,
6776 "%s: Index for interface %s failed",
6777 __func__, intf);
6778 return -1;
6779 }
6780
6781 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6782 NL80211_CMD_SET_WIPHY)) ||
6783 nla_put_u32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD, val)) {
6784 sigma_dut_print(dut, DUT_MSG_ERROR,
6785 "%s: err in adding RTS threshold",
6786 __func__);
6787 nlmsg_free(msg);
6788 return -1;
6789 }
6790
6791 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6792 if (ret) {
6793 sigma_dut_print(dut, DUT_MSG_ERROR,
6794 "%s: err in send_and_recv_msgs, ret=%d",
6795 __func__, ret);
6796 }
6797 return ret;
6798}
6799#endif /* NL80211_SUPPORT */
6800
6801
6802static int sta_set_rts(struct sigma_dut *dut, const char *intf, int val)
6803{
6804 char buf[100];
6805
6806#ifdef NL80211_SUPPORT
6807 if (nl80211_sta_set_rts(dut, intf, val) == 0)
6808 return 0;
6809 sigma_dut_print(dut, DUT_MSG_DEBUG,
6810 "Fall back to using iwconfig for setting RTS threshold");
6811#endif /* NL80211_SUPPORT */
6812
6813 snprintf(buf, sizeof(buf), "iwconfig %s rts %d", intf, val);
6814 if (system(buf) != 0) {
6815 sigma_dut_print(dut, DUT_MSG_ERROR,
6816 "Failed to set RTS threshold %d", val);
6817 return -1;
6818 }
6819 return 0;
6820}
6821
6822
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006823static enum sigma_cmd_result
6824cmd_sta_set_wireless_common(const char *intf, struct sigma_dut *dut,
6825 struct sigma_conn *conn, struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006826{
6827 const char *val;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006828 int ampdu = -1, addbareject = -1;
Jouni Malinen3aa72862019-05-29 23:14:51 +03006829 char buf[128];
6830 int res;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006831
6832 val = get_param(cmd, "40_INTOLERANT");
6833 if (val) {
6834 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
6835 /* TODO: iwpriv ht40intol through wpa_supplicant */
6836 send_resp(dut, conn, SIGMA_ERROR,
6837 "ErrorCode,40_INTOLERANT not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006838 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006839 }
6840 }
6841
6842 val = get_param(cmd, "ADDBA_REJECT");
6843 if (val) {
6844 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
6845 /* reject any ADDBA with status "decline" */
6846 ampdu = 0;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006847 addbareject = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006848 } else {
6849 /* accept ADDBA */
6850 ampdu = 1;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006851 addbareject = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006852 }
6853 }
6854
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006855 if (addbareject >= 0 &&
6856 sta_set_addba_reject(dut, intf, addbareject) < 0) {
6857 send_resp(dut, conn, SIGMA_ERROR,
6858 "ErrorCode,set addba_reject failed");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006859 return STATUS_SENT_ERROR;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006860 }
6861
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006862 val = get_param(cmd, "AMPDU");
6863 if (val) {
6864 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
6865 /* enable AMPDU Aggregation */
6866 if (ampdu == 0) {
6867 send_resp(dut, conn, SIGMA_ERROR,
6868 "ErrorCode,Mismatch in "
6869 "addba_reject/ampdu - "
6870 "not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006871 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006872 }
6873 ampdu = 1;
6874 } else {
6875 /* disable AMPDU Aggregation */
6876 if (ampdu == 1) {
6877 send_resp(dut, conn, SIGMA_ERROR,
6878 "ErrorCode,Mismatch in "
6879 "addba_reject/ampdu - "
6880 "not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006881 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006882 }
6883 ampdu = 0;
6884 }
6885 }
6886
6887 if (ampdu >= 0) {
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08006888 int ret;
6889
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006890 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s A-MPDU aggregation",
6891 ampdu ? "Enabling" : "Disabling");
6892 snprintf(buf, sizeof(buf), "SET ampdu %d", ampdu);
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07006893 if (wpa_command(intf, buf) < 0 &&
6894 iwpriv_sta_set_ampdu(dut, intf, ampdu) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006895 send_resp(dut, conn, SIGMA_ERROR,
6896 "ErrorCode,set aggr failed");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006897 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006898 }
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08006899
6900 if (ampdu == 0) {
6901 /* Disable sending of addba using nl vendor command */
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08006902 ret = nlvendor_config_send_addba(dut, intf, 0);
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08006903 if (ret) {
6904 sigma_dut_print(dut, DUT_MSG_ERROR,
6905 "Failed to disable addba, ret:%d",
6906 ret);
6907 }
6908 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006909 }
6910
6911 val = get_param(cmd, "AMSDU");
6912 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006913 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006914 case DRIVER_ATHEROS:
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08006915 case DRIVER_WCN:
6916 iwpriv_sta_set_amsdu(dut, intf, val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006917 break;
6918 default:
6919 if (strcmp(val, "1") == 0 ||
6920 strcasecmp(val, "Enable") == 0) {
6921 /* Enable AMSDU Aggregation */
6922 send_resp(dut, conn, SIGMA_ERROR,
6923 "ErrorCode,AMSDU aggregation not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006924 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006925 }
6926 break;
6927 }
6928 }
6929
6930 val = get_param(cmd, "STBC_RX");
6931 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006932 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006933 case DRIVER_ATHEROS:
6934 ath_sta_set_stbc(dut, intf, val);
6935 break;
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05306936 case DRIVER_WCN:
6937 wcn_sta_set_stbc(dut, intf, val);
6938 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006939 default:
6940 send_resp(dut, conn, SIGMA_ERROR,
6941 "ErrorCode,STBC_RX not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006942 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006943 }
6944 }
6945
6946 val = get_param(cmd, "WIDTH");
6947 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006948 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006949 case DRIVER_WCN:
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08006950 if (wcn_sta_set_width(dut, intf, val) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006951 send_resp(dut, conn, SIGMA_ERROR,
6952 "ErrorCode,Failed to set WIDTH");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006953 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006954 }
6955 break;
6956 case DRIVER_ATHEROS:
6957 if (ath_set_width(dut, conn, intf, val) < 0)
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006958 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006959 break;
6960 default:
6961 sigma_dut_print(dut, DUT_MSG_ERROR,
6962 "Setting WIDTH not supported");
6963 break;
6964 }
6965 }
6966
6967 val = get_param(cmd, "SMPS");
6968 if (val) {
6969 /* TODO: Dynamic/0, Static/1, No Limit/2 */
6970 send_resp(dut, conn, SIGMA_ERROR,
6971 "ErrorCode,SMPS not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006972 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006973 }
6974
6975 val = get_param(cmd, "TXSP_STREAM");
6976 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006977 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006978 case DRIVER_WCN:
6979 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
6980 send_resp(dut, conn, SIGMA_ERROR,
6981 "ErrorCode,Failed to set TXSP_STREAM");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006982 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006983 }
6984 break;
6985 case DRIVER_ATHEROS:
6986 ath_sta_set_txsp_stream(dut, intf, val);
6987 break;
6988 default:
6989 sigma_dut_print(dut, DUT_MSG_ERROR,
6990 "Setting TXSP_STREAM not supported");
6991 break;
6992 }
6993 }
6994
6995 val = get_param(cmd, "RXSP_STREAM");
6996 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006997 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006998 case DRIVER_WCN:
6999 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
7000 send_resp(dut, conn, SIGMA_ERROR,
7001 "ErrorCode,Failed to set RXSP_STREAM");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03007002 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007003 }
7004 break;
7005 case DRIVER_ATHEROS:
7006 ath_sta_set_rxsp_stream(dut, intf, val);
7007 break;
7008 default:
7009 sigma_dut_print(dut, DUT_MSG_ERROR,
7010 "Setting RXSP_STREAM not supported");
7011 break;
7012 }
7013 }
7014
7015 val = get_param(cmd, "DYN_BW_SGNL");
7016 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007017 switch (get_driver_type(dut)) {
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08007018 case DRIVER_WCN:
Peng Xuc59afd32016-11-21 15:01:11 -08007019 if (strcasecmp(val, "enable") == 0) {
7020 snprintf(buf, sizeof(buf),
7021 "iwpriv %s cwmenable 1", intf);
7022 if (system(buf) != 0) {
7023 sigma_dut_print(dut, DUT_MSG_ERROR,
7024 "iwpriv cwmenable 1 failed");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03007025 return ERROR_SEND_STATUS;
Peng Xuc59afd32016-11-21 15:01:11 -08007026 }
7027 } else if (strcasecmp(val, "disable") == 0) {
7028 snprintf(buf, sizeof(buf),
7029 "iwpriv %s cwmenable 0", intf);
7030 if (system(buf) != 0) {
7031 sigma_dut_print(dut, DUT_MSG_ERROR,
7032 "iwpriv cwmenable 0 failed");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03007033 return ERROR_SEND_STATUS;
Peng Xuc59afd32016-11-21 15:01:11 -08007034 }
7035 } else {
7036 sigma_dut_print(dut, DUT_MSG_ERROR,
7037 "Unsupported DYN_BW_SGL");
7038 }
7039
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007040 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 3", intf);
7041 if (system(buf) != 0) {
7042 sigma_dut_print(dut, DUT_MSG_ERROR,
7043 "Failed to set cts_cbw in DYN_BW_SGNL");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03007044 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007045 }
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08007046 break;
7047 case DRIVER_ATHEROS:
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -07007048 novap_reset(dut, intf, 1);
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08007049 ath_config_dyn_bw_sig(dut, intf, val);
7050 break;
7051 default:
7052 sigma_dut_print(dut, DUT_MSG_ERROR,
7053 "Failed to set DYN_BW_SGNL");
7054 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007055 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007056 }
7057
7058 val = get_param(cmd, "RTS_FORCE");
7059 if (val) {
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -07007060 novap_reset(dut, intf, 1);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007061 if (strcasecmp(val, "Enable") == 0) {
Veerendranath Jakkamadcd6202019-04-17 12:32:21 +05307062 if (sta_set_rts(dut, intf, 64) != 0) {
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02007063 sigma_dut_print(dut, DUT_MSG_ERROR,
7064 "Failed to set RTS_FORCE 64");
7065 }
Jouni Malinen3aa72862019-05-29 23:14:51 +03007066 res = snprintf(buf, sizeof(buf),
7067 "wifitool %s beeliner_fw_test 100 1",
7068 intf);
7069 if (res < 0 || res >= sizeof(buf) || system(buf) != 0) {
priyadharshini gowthaman270870e2015-12-09 10:10:23 -08007070 sigma_dut_print(dut, DUT_MSG_ERROR,
7071 "wifitool beeliner_fw_test 100 1 failed");
7072 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007073 } else if (strcasecmp(val, "Disable") == 0) {
Veerendranath Jakkamadcd6202019-04-17 12:32:21 +05307074 if (sta_set_rts(dut, intf, 2347) != 0) {
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02007075 sigma_dut_print(dut, DUT_MSG_ERROR,
7076 "Failed to set RTS_FORCE 2347");
7077 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007078 } else {
7079 send_resp(dut, conn, SIGMA_ERROR,
7080 "ErrorCode,RTS_FORCE value not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03007081 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007082 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007083 }
7084
7085 val = get_param(cmd, "CTS_WIDTH");
7086 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007087 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007088 case DRIVER_WCN:
7089 if (wcn_sta_set_cts_width(dut, intf, val) < 0) {
7090 send_resp(dut, conn, SIGMA_ERROR,
7091 "ErrorCode,Failed to set CTS_WIDTH");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03007092 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007093 }
7094 break;
7095 case DRIVER_ATHEROS:
7096 ath_set_cts_width(dut, intf, val);
7097 break;
7098 default:
7099 sigma_dut_print(dut, DUT_MSG_ERROR,
7100 "Setting CTS_WIDTH not supported");
7101 break;
7102 }
7103 }
7104
7105 val = get_param(cmd, "BW_SGNL");
7106 if (val) {
7107 if (strcasecmp(val, "Enable") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07007108 run_iwpriv(dut, intf, "cwmenable 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007109 } else if (strcasecmp(val, "Disable") == 0) {
7110 /* TODO: Disable */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007111 } else {
7112 send_resp(dut, conn, SIGMA_ERROR,
7113 "ErrorCode,BW_SGNL value not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03007114 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007115 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007116 }
7117
7118 val = get_param(cmd, "Band");
7119 if (val) {
7120 if (strcmp(val, "2.4") == 0 || strcmp(val, "5") == 0) {
7121 /* STA supports all bands by default */
7122 } else {
7123 send_resp(dut, conn, SIGMA_ERROR,
7124 "ErrorCode,Unsupported Band");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03007125 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007126 }
7127 }
7128
7129 val = get_param(cmd, "zero_crc");
7130 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007131 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007132 case DRIVER_ATHEROS:
7133 ath_set_zero_crc(dut, val);
7134 break;
7135 default:
7136 break;
7137 }
7138 }
7139
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03007140 return SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007141}
7142
7143
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02007144static int sta_set_force_mcs(struct sigma_dut *dut, int force, int mcs)
7145{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007146 switch (get_driver_type(dut)) {
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02007147#ifdef __linux__
7148 case DRIVER_WIL6210:
7149 return wil6210_set_force_mcs(dut, force, mcs);
7150#endif /* __linux__ */
7151 default:
7152 sigma_dut_print(dut, DUT_MSG_ERROR,
7153 "Unsupported sta_set_force_mcs with the current driver");
7154 return -1;
7155 }
7156}
7157
7158
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02007159static int sta_60g_force_rsn_ie(struct sigma_dut *dut, int state)
7160{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007161 switch (get_driver_type(dut)) {
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02007162#ifdef __linux__
7163 case DRIVER_WIL6210:
7164 return wil6210_force_rsn_ie(dut, state);
7165#endif /* __linux__ */
7166 default:
7167 sigma_dut_print(dut, DUT_MSG_ERROR,
7168 "Unsupported sta_60g_force_rsn_ie with the current driver");
7169 return -1;
7170 }
7171}
7172
7173
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007174static int sta_set_60g_common(struct sigma_dut *dut, struct sigma_conn *conn,
7175 struct sigma_cmd *cmd)
7176{
7177 const char *val;
7178 char buf[100];
7179
7180 val = get_param(cmd, "MSDUSize");
7181 if (val) {
7182 int mtu;
7183
7184 dut->amsdu_size = atoi(val);
7185 if (dut->amsdu_size > IEEE80211_MAX_DATA_LEN_DMG ||
7186 dut->amsdu_size < IEEE80211_SNAP_LEN_DMG) {
7187 sigma_dut_print(dut, DUT_MSG_ERROR,
7188 "MSDUSize %d is above max %d or below min %d",
7189 dut->amsdu_size,
7190 IEEE80211_MAX_DATA_LEN_DMG,
7191 IEEE80211_SNAP_LEN_DMG);
7192 dut->amsdu_size = 0;
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007193 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007194 }
7195
7196 mtu = dut->amsdu_size - IEEE80211_SNAP_LEN_DMG;
7197 sigma_dut_print(dut, DUT_MSG_DEBUG,
7198 "Setting amsdu_size to %d", mtu);
7199 snprintf(buf, sizeof(buf), "ifconfig %s mtu %d",
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007200 get_station_ifname(dut), mtu);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007201
7202 if (system(buf) != 0) {
7203 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
7204 buf);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007205 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007206 }
7207 }
7208
7209 val = get_param(cmd, "BAckRcvBuf");
7210 if (val) {
7211 dut->back_rcv_buf = atoi(val);
7212 if (dut->back_rcv_buf == 0) {
7213 sigma_dut_print(dut, DUT_MSG_ERROR,
7214 "Failed to convert %s or value is 0",
7215 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007216 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007217 }
7218
7219 sigma_dut_print(dut, DUT_MSG_DEBUG,
7220 "Setting BAckRcvBuf to %s", val);
7221 }
7222
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02007223 val = get_param(cmd, "MCS_FixedRate");
7224 if (val) {
7225 if (sta_set_force_mcs(dut, 1, atoi(val))) {
7226 sigma_dut_print(dut, DUT_MSG_ERROR,
7227 "Failed to force MCS");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007228 return ERROR_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02007229 }
7230 }
7231
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007232 return SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007233}
7234
7235
7236static int sta_pcp_start(struct sigma_dut *dut, struct sigma_conn *conn,
7237 struct sigma_cmd *cmd)
7238{
7239 int net_id;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007240 const char *ifname;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007241 const char *val;
7242 char buf[100];
7243
7244 dut->mode = SIGMA_MODE_STATION;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007245 ifname = get_main_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007246 if (wpa_command(ifname, "PING") != 0) {
7247 sigma_dut_print(dut, DUT_MSG_ERROR, "Supplicant not running");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007248 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007249 }
7250
7251 wpa_command(ifname, "FLUSH");
7252 net_id = add_network_common(dut, conn, ifname, cmd);
7253 if (net_id < 0) {
7254 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add network");
7255 return net_id;
7256 }
7257
7258 /* TODO: mode=2 for the AP; in the future, replace for mode PCP */
7259 if (set_network(ifname, net_id, "mode", "2") < 0) {
7260 sigma_dut_print(dut, DUT_MSG_ERROR,
7261 "Failed to set supplicant network mode");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007262 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007263 }
7264
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02007265 if (set_network(ifname, net_id, "pbss", "1") < 0)
7266 return -2;
7267
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007268 sigma_dut_print(dut, DUT_MSG_DEBUG,
Alexei Avshalom Lazarfd9f1352018-11-13 14:07:58 +02007269 "Supplicant set network with mode 2. network_id %d",
7270 net_id);
7271
7272 if (set_network(ifname, net_id, "wps_disabled", "0") < 0) {
7273 sigma_dut_print(dut, DUT_MSG_INFO,
7274 "Failed to set supplicant to WPS ENABLE");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007275 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarfd9f1352018-11-13 14:07:58 +02007276 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007277
7278 val = get_param(cmd, "Security");
7279 if (val && strcasecmp(val, "OPEN") == 0) {
7280 dut->ap_key_mgmt = AP_OPEN;
7281 if (set_network(ifname, net_id, "key_mgmt", "NONE") < 0) {
7282 sigma_dut_print(dut, DUT_MSG_ERROR,
7283 "Failed to set supplicant to %s security",
7284 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007285 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007286 }
7287 } else if (val && strcasecmp(val, "WPA2-PSK") == 0) {
7288 dut->ap_key_mgmt = AP_WPA2_PSK;
7289 if (set_network(ifname, net_id, "key_mgmt", "WPA-PSK") < 0) {
7290 sigma_dut_print(dut, DUT_MSG_ERROR,
7291 "Failed to set supplicant to %s security",
7292 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007293 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007294 }
7295
7296 if (set_network(ifname, net_id, "proto", "RSN") < 0) {
7297 sigma_dut_print(dut, DUT_MSG_ERROR,
7298 "Failed to set supplicant to proto RSN");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007299 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007300 }
7301 } else if (val) {
7302 sigma_dut_print(dut, DUT_MSG_ERROR,
7303 "Requested Security %s is not supported on 60GHz",
7304 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007305 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007306 }
7307
7308 val = get_param(cmd, "Encrypt");
7309 if (val && strcasecmp(val, "AES-GCMP") == 0) {
7310 if (set_network(ifname, net_id, "pairwise", "GCMP") < 0) {
7311 sigma_dut_print(dut, DUT_MSG_ERROR,
7312 "Failed to set supplicant to pairwise GCMP");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007313 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007314 }
7315 if (set_network(ifname, net_id, "group", "GCMP") < 0) {
7316 sigma_dut_print(dut, DUT_MSG_ERROR,
7317 "Failed to set supplicant to group GCMP");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007318 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007319 }
7320 } else if (val) {
7321 sigma_dut_print(dut, DUT_MSG_ERROR,
7322 "Requested Encrypt %s is not supported on 60 GHz",
7323 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007324 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007325 }
7326
7327 val = get_param(cmd, "PSK");
7328 if (val && set_network_quoted(ifname, net_id, "psk", val) < 0) {
7329 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set psk %s",
7330 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007331 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007332 }
7333
7334 /* Convert 60G channel to freq */
7335 switch (dut->ap_channel) {
7336 case 1:
7337 val = "58320";
7338 break;
7339 case 2:
7340 val = "60480";
7341 break;
7342 case 3:
7343 val = "62640";
7344 break;
7345 default:
7346 sigma_dut_print(dut, DUT_MSG_ERROR,
7347 "Failed to configure channel %d. Not supported",
7348 dut->ap_channel);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007349 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007350 }
7351
7352 if (set_network(ifname, net_id, "frequency", val) < 0) {
7353 sigma_dut_print(dut, DUT_MSG_ERROR,
7354 "Failed to set supplicant network frequency");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007355 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007356 }
7357
Alexei Avshalom Lazar2eccf4d2019-01-31 10:03:59 +02007358 if (dut->eap_fragment) {
7359 sigma_dut_print(dut, DUT_MSG_DEBUG,
7360 "Set EAP fragment size to 128 bytes.");
7361 if (set_network(ifname, net_id, "fragment_size", "128") < 0)
7362 return ERROR_SEND_STATUS;
7363 }
7364
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007365 sigma_dut_print(dut, DUT_MSG_DEBUG,
7366 "Supplicant set network with frequency");
7367
7368 snprintf(buf, sizeof(buf), "SELECT_NETWORK %d", net_id);
7369 if (wpa_command(ifname, buf) < 0) {
7370 sigma_dut_print(dut, DUT_MSG_INFO,
7371 "Failed to select network id %d on %s",
7372 net_id, ifname);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007373 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007374 }
7375
7376 sigma_dut_print(dut, DUT_MSG_DEBUG, "Selected network");
7377
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007378 return SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007379}
7380
7381
Lior David67543f52017-01-03 19:04:22 +02007382static int wil6210_set_abft_len(struct sigma_dut *dut, int abft_len)
7383{
7384 char buf[128], fname[128];
7385 FILE *f;
Jouni Malinen3aa72862019-05-29 23:14:51 +03007386 int res;
Lior David67543f52017-01-03 19:04:22 +02007387
7388 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
7389 sigma_dut_print(dut, DUT_MSG_ERROR,
7390 "failed to get wil6210 debugfs dir");
7391 return -1;
7392 }
7393
Jouni Malinen3aa72862019-05-29 23:14:51 +03007394 res = snprintf(fname, sizeof(fname), "%s/abft_len", buf);
7395 if (res < 0 || res >= sizeof(fname))
7396 return -1;
Lior David67543f52017-01-03 19:04:22 +02007397 f = fopen(fname, "w");
7398 if (!f) {
7399 sigma_dut_print(dut, DUT_MSG_ERROR,
7400 "failed to open: %s", fname);
7401 return -1;
7402 }
7403
7404 fprintf(f, "%d\n", abft_len);
7405 fclose(f);
7406
7407 return 0;
7408}
7409
7410
Alexei Avshalom Lazar49498b82019-01-31 15:16:32 +02007411int sta_set_60g_abft_len(struct sigma_dut *dut, struct sigma_conn *conn,
7412 int abft_len)
Lior David67543f52017-01-03 19:04:22 +02007413{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007414 switch (get_driver_type(dut)) {
Lior David67543f52017-01-03 19:04:22 +02007415 case DRIVER_WIL6210:
7416 return wil6210_set_abft_len(dut, abft_len);
7417 default:
7418 sigma_dut_print(dut, DUT_MSG_ERROR,
7419 "set abft_len not supported");
7420 return -1;
7421 }
7422}
7423
7424
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007425static int sta_set_60g_pcp(struct sigma_dut *dut, struct sigma_conn *conn,
7426 struct sigma_cmd *cmd)
7427{
7428 const char *val;
Lior David67543f52017-01-03 19:04:22 +02007429 unsigned int abft_len = 1; /* default is one slot */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007430
7431 if (dut->dev_role != DEVROLE_PCP) {
7432 send_resp(dut, conn, SIGMA_INVALID,
7433 "ErrorCode,Invalid DevRole");
7434 return 0;
7435 }
7436
7437 val = get_param(cmd, "SSID");
7438 if (val) {
7439 if (strlen(val) > sizeof(dut->ap_ssid) - 1) {
7440 send_resp(dut, conn, SIGMA_INVALID,
7441 "ErrorCode,Invalid SSID");
7442 return -1;
7443 }
7444
Peng Xub8fc5cc2017-05-10 17:27:28 -07007445 strlcpy(dut->ap_ssid, val, sizeof(dut->ap_ssid));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007446 }
7447
7448 val = get_param(cmd, "CHANNEL");
7449 if (val) {
7450 const char *pos;
7451
7452 dut->ap_channel = atoi(val);
7453 pos = strchr(val, ';');
7454 if (pos) {
7455 pos++;
7456 dut->ap_channel_1 = atoi(pos);
7457 }
7458 }
7459
7460 switch (dut->ap_channel) {
7461 case 1:
7462 case 2:
7463 case 3:
7464 break;
7465 default:
7466 sigma_dut_print(dut, DUT_MSG_ERROR,
7467 "Channel %d is not supported", dut->ap_channel);
7468 send_resp(dut, conn, SIGMA_ERROR,
7469 "Requested channel is not supported");
7470 return -1;
7471 }
7472
7473 val = get_param(cmd, "BCNINT");
7474 if (val)
7475 dut->ap_bcnint = atoi(val);
7476
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007477 val = get_param(cmd, "AllocType");
7478 if (val) {
7479 send_resp(dut, conn, SIGMA_ERROR,
7480 "ErrorCode,AllocType is not supported yet");
7481 return -1;
7482 }
7483
7484 val = get_param(cmd, "PercentBI");
7485 if (val) {
7486 send_resp(dut, conn, SIGMA_ERROR,
7487 "ErrorCode,PercentBI is not supported yet");
7488 return -1;
7489 }
7490
7491 val = get_param(cmd, "CBAPOnly");
7492 if (val) {
7493 send_resp(dut, conn, SIGMA_ERROR,
7494 "ErrorCode,CBAPOnly is not supported yet");
7495 return -1;
7496 }
7497
7498 val = get_param(cmd, "AMPDU");
7499 if (val) {
7500 if (strcasecmp(val, "Enable") == 0)
7501 dut->ap_ampdu = 1;
7502 else if (strcasecmp(val, "Disable") == 0)
7503 dut->ap_ampdu = 2;
7504 else {
7505 send_resp(dut, conn, SIGMA_ERROR,
7506 "ErrorCode,AMPDU value is not Enable nor Disabled");
7507 return -1;
7508 }
7509 }
7510
7511 val = get_param(cmd, "AMSDU");
7512 if (val) {
7513 if (strcasecmp(val, "Enable") == 0)
7514 dut->ap_amsdu = 1;
7515 else if (strcasecmp(val, "Disable") == 0)
7516 dut->ap_amsdu = 2;
7517 }
7518
7519 val = get_param(cmd, "NumMSDU");
7520 if (val) {
7521 send_resp(dut, conn, SIGMA_ERROR,
7522 "ErrorCode, NumMSDU is not supported yet");
7523 return -1;
7524 }
7525
7526 val = get_param(cmd, "ABFTLRang");
7527 if (val) {
7528 sigma_dut_print(dut, DUT_MSG_DEBUG,
Lior David67543f52017-01-03 19:04:22 +02007529 "ABFTLRang parameter %s", val);
7530 if (strcmp(val, "Gt1") == 0)
7531 abft_len = 2; /* 2 slots in this case */
7532 }
7533
7534 if (sta_set_60g_abft_len(dut, conn, abft_len)) {
7535 send_resp(dut, conn, SIGMA_ERROR,
7536 "ErrorCode, Can't set ABFT length");
7537 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007538 }
7539
7540 if (sta_pcp_start(dut, conn, cmd) < 0) {
7541 send_resp(dut, conn, SIGMA_ERROR,
7542 "ErrorCode, Can't start PCP role");
7543 return -1;
7544 }
7545
7546 return sta_set_60g_common(dut, conn, cmd);
7547}
7548
7549
7550static int sta_set_60g_sta(struct sigma_dut *dut, struct sigma_conn *conn,
7551 struct sigma_cmd *cmd)
7552{
7553 const char *val = get_param(cmd, "DiscoveryMode");
7554
7555 if (dut->dev_role != DEVROLE_STA) {
7556 send_resp(dut, conn, SIGMA_INVALID,
7557 "ErrorCode,Invalid DevRole");
7558 return 0;
7559 }
7560
7561 if (val) {
7562 sigma_dut_print(dut, DUT_MSG_DEBUG, "Discovery: %s", val);
7563 /* Ignore Discovery mode till Driver expose API. */
7564#if 0
7565 if (strcasecmp(val, "1") == 0) {
7566 send_resp(dut, conn, SIGMA_INVALID,
7567 "ErrorCode,DiscoveryMode 1 not supported");
7568 return 0;
7569 }
7570
7571 if (strcasecmp(val, "0") == 0) {
7572 /* OK */
7573 } else {
7574 send_resp(dut, conn, SIGMA_INVALID,
7575 "ErrorCode,DiscoveryMode not supported");
7576 return 0;
7577 }
7578#endif
7579 }
7580
7581 if (start_sta_mode(dut) != 0)
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007582 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007583 return sta_set_60g_common(dut, conn, cmd);
7584}
7585
7586
Jouni Malinenf7222712019-06-13 01:50:21 +03007587static enum sigma_cmd_result cmd_sta_disconnect(struct sigma_dut *dut,
7588 struct sigma_conn *conn,
7589 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007590{
7591 const char *intf = get_param(cmd, "Interface");
Jouni Malinened77e672018-01-10 16:45:13 +02007592 const char *val = get_param(cmd, "maintain_profile");
vamsi krishnad605c422017-09-20 14:56:31 +05307593
Jouni Malinened77e672018-01-10 16:45:13 +02007594 if (dut->program == PROGRAM_OCE ||
Amarnath Hullur Subramanyamebeda9e2018-01-31 03:21:48 -08007595 dut->program == PROGRAM_HE ||
Jouni Malinened77e672018-01-10 16:45:13 +02007596 (val && atoi(val) == 1)) {
vamsi krishnad605c422017-09-20 14:56:31 +05307597 wpa_command(intf, "DISCONNECT");
7598 return 1;
7599 }
7600
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007601 disconnect_station(dut);
7602 /* Try to ignore old scan results to avoid HS 2.0R2 test case failures
7603 * due to cached results. */
7604 wpa_command(intf, "SET ignore_old_scan_res 1");
7605 wpa_command(intf, "BSS_FLUSH");
7606 return 1;
7607}
7608
7609
Jouni Malinenf7222712019-06-13 01:50:21 +03007610static enum sigma_cmd_result cmd_sta_reassoc(struct sigma_dut *dut,
7611 struct sigma_conn *conn,
7612 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007613{
7614 const char *intf = get_param(cmd, "Interface");
7615 const char *bssid = get_param(cmd, "bssid");
7616 const char *val = get_param(cmd, "CHANNEL");
Kiran Kumar Lokere94a86b52020-06-03 23:25:19 -07007617 const char *freq_val = get_param(cmd, "ChnlFreq");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007618 struct wpa_ctrl *ctrl;
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05307619 char buf[1000];
Sunil Duttd30ce092018-01-11 23:56:29 +05307620 char result[32];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007621 int res;
7622 int chan = 0;
Kiran Kumar Lokere94a86b52020-06-03 23:25:19 -07007623 int freq = 0;
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007624 enum sigma_cmd_result status = STATUS_SENT;
Sunil Duttd30ce092018-01-11 23:56:29 +05307625 int fastreassoc = 1;
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007626 int ft_ds = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007627
7628 if (bssid == NULL) {
7629 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing bssid "
7630 "argument");
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007631 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007632 }
7633
7634 if (val)
7635 chan = atoi(val);
7636
Kiran Kumar Lokere94a86b52020-06-03 23:25:19 -07007637 if (freq_val)
7638 freq = atoi(freq_val);
7639
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007640 if (wifi_chip_type != DRIVER_WCN && wifi_chip_type != DRIVER_AR6003) {
7641 /* The current network may be from sta_associate or
7642 * sta_hs2_associate
7643 */
7644 if (set_network(intf, dut->infra_network_id, "bssid", bssid) <
7645 0 ||
7646 set_network(intf, 0, "bssid", bssid) < 0)
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007647 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007648 }
7649
7650 ctrl = open_wpa_mon(intf);
7651 if (ctrl == NULL) {
7652 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
7653 "wpa_supplicant monitor connection");
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007654 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007655 }
7656
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007657 if (get_wpa_status(get_station_ifname(dut), "wpa_state", result,
Sunil Duttd30ce092018-01-11 23:56:29 +05307658 sizeof(result)) < 0 ||
7659 strncmp(result, "COMPLETED", 9) != 0) {
7660 sigma_dut_print(dut, DUT_MSG_DEBUG,
7661 "sta_reassoc: Not connected");
7662 fastreassoc = 0;
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007663 } else if (dut->sta_ft_ds) {
7664 sigma_dut_print(dut, DUT_MSG_DEBUG,
7665 "sta_reassoc: Use FT-over-DS");
7666 ft_ds = 1;
Sunil Duttd30ce092018-01-11 23:56:29 +05307667 }
7668
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05307669 if (dut->rsne_override) {
7670#ifdef NL80211_SUPPORT
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007671 if (get_driver_type(dut) == DRIVER_WCN &&
7672 dut->config_rsnie == 0) {
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05307673 sta_config_params(dut, intf, STA_SET_RSNIE, 1);
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05307674 dut->config_rsnie = 1;
7675 }
7676#endif /* NL80211_SUPPORT */
7677 snprintf(buf, sizeof(buf), "TEST_ASSOC_IE %s",
7678 dut->rsne_override);
7679 if (wpa_command(intf, buf) < 0) {
7680 send_resp(dut, conn, SIGMA_ERROR,
7681 "ErrorCode,Failed to set DEV_CONFIGURE_IE RSNE override");
7682 return 0;
7683 }
7684 }
7685
Shivani Baranwal7aa48602021-09-29 10:53:38 +05307686 if (ft_ds && get_driver_type(dut) != DRIVER_WCN) {
Kiran Kumar Lokere94a86b52020-06-03 23:25:19 -07007687 if (chan || freq) {
7688 if (!freq)
7689 freq = channel_to_freq(dut, chan);
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007690 if (!freq) {
7691 sigma_dut_print(dut, DUT_MSG_ERROR,
7692 "Invalid channel number provided: %d",
7693 chan);
7694 send_resp(dut, conn, SIGMA_INVALID,
7695 "ErrorCode,Invalid channel number");
7696 goto close_mon_conn;
7697 }
7698 res = snprintf(buf, sizeof(buf),
7699 "SCAN TYPE=ONLY freq=%d", freq);
7700 } else {
7701 res = snprintf(buf, sizeof(buf), "SCAN TYPE=ONLY");
7702 }
7703 if (res < 0 || res >= (int) sizeof(buf)) {
7704 send_resp(dut, conn, SIGMA_ERROR,
7705 "ErrorCode,snprintf failed");
7706 goto close_mon_conn;
7707 }
7708 if (wpa_command(intf, buf) < 0) {
7709 sigma_dut_print(dut, DUT_MSG_INFO,
7710 "Failed to start scan");
7711 send_resp(dut, conn, SIGMA_ERROR,
7712 "ErrorCode,scan failed");
7713 goto close_mon_conn;
7714 }
7715
7716 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
7717 buf, sizeof(buf));
7718 if (res < 0) {
7719 sigma_dut_print(dut, DUT_MSG_INFO,
7720 "Scan did not complete");
7721 send_resp(dut, conn, SIGMA_ERROR,
7722 "ErrorCode,scan did not complete");
7723 goto close_mon_conn;
7724 }
7725
7726 res = snprintf(buf, sizeof(buf), "FT_DS %s", bssid);
7727 if (res > 0 && res < (int) sizeof(buf))
7728 res = wpa_command(intf, buf);
7729
7730 if (res < 0 || res >= (int) sizeof(buf)) {
7731 send_resp(dut, conn, SIGMA_ERROR,
7732 "errorCode,FT_DS command failed");
7733 status = STATUS_SENT_ERROR;
7734 goto close_mon_conn;
7735 }
7736 } else if (wifi_chip_type == DRIVER_WCN && fastreassoc) {
Kiran Kumar Lokere94a86b52020-06-03 23:25:19 -07007737 if (chan || freq) {
7738 if (!freq)
7739 freq = channel_to_freq(dut, chan);
Ashwini Patil4c8158f2017-05-25 12:49:21 +05307740 if (!freq) {
7741 sigma_dut_print(dut, DUT_MSG_ERROR,
7742 "Invalid channel number provided: %d",
7743 chan);
7744 send_resp(dut, conn, SIGMA_INVALID,
7745 "ErrorCode,Invalid channel number");
7746 goto close_mon_conn;
7747 }
7748 res = snprintf(buf, sizeof(buf),
7749 "SCAN TYPE=ONLY freq=%d", freq);
7750 } else {
7751 res = snprintf(buf, sizeof(buf), "SCAN TYPE=ONLY");
7752 }
7753 if (res < 0 || res >= (int) sizeof(buf)) {
7754 send_resp(dut, conn, SIGMA_ERROR,
7755 "ErrorCode,snprintf failed");
7756 goto close_mon_conn;
7757 }
7758 if (wpa_command(intf, buf) < 0) {
7759 sigma_dut_print(dut, DUT_MSG_INFO,
7760 "Failed to start scan");
7761 send_resp(dut, conn, SIGMA_ERROR,
7762 "ErrorCode,scan failed");
7763 goto close_mon_conn;
7764 }
7765
7766 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
7767 buf, sizeof(buf));
7768 if (res < 0) {
7769 sigma_dut_print(dut, DUT_MSG_INFO,
7770 "Scan did not complete");
7771 send_resp(dut, conn, SIGMA_ERROR,
7772 "ErrorCode,scan did not complete");
7773 goto close_mon_conn;
7774 }
7775
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007776 if (set_network(intf, dut->infra_network_id, "bssid", "any")
7777 < 0) {
7778 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
7779 "bssid to any during FASTREASSOC");
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007780 status = ERROR_SEND_STATUS;
Ashwini Patil467efef2017-05-25 12:18:27 +05307781 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007782 }
Vinita Maloo54b78cf2020-03-30 12:18:19 +05307783 res = snprintf(buf, sizeof(buf), "FASTREASSOC %s %d",
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007784 bssid, chan);
Vinita Maloo54b78cf2020-03-30 12:18:19 +05307785 if (res < 0 || res >= (int) sizeof(buf) ||
7786 wcn_driver_cmd(intf, buf) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007787 send_resp(dut, conn, SIGMA_ERROR,
Vinita Maloo54b78cf2020-03-30 12:18:19 +05307788 "errorCode,Failed to run FASTREASSOC");
Ashwini Patil467efef2017-05-25 12:18:27 +05307789 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007790 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007791 sigma_dut_print(dut, DUT_MSG_INFO,
7792 "sta_reassoc: Run %s successful", buf);
7793 } else if (wpa_command(intf, "REASSOCIATE")) {
7794 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
7795 "request reassociation");
Ashwini Patil467efef2017-05-25 12:18:27 +05307796 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007797 }
7798
7799 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
7800 buf, sizeof(buf));
Ashwini Patil467efef2017-05-25 12:18:27 +05307801 if (res < 0) {
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007802 send_resp(dut, conn, SIGMA_ERROR,
7803 "errorCode,Connection did not complete");
7804 status = STATUS_SENT_ERROR;
Ashwini Patil467efef2017-05-25 12:18:27 +05307805 goto close_mon_conn;
7806 }
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007807 status = SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007808
Ashwini Patil467efef2017-05-25 12:18:27 +05307809close_mon_conn:
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007810 wpa_ctrl_detach(ctrl);
7811 wpa_ctrl_close(ctrl);
Ashwini Patil467efef2017-05-25 12:18:27 +05307812 return status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007813}
7814
7815
7816static void hs2_clear_credentials(const char *intf)
7817{
7818 wpa_command(intf, "REMOVE_CRED all");
7819}
7820
7821
Lior Davidcc88b562017-01-03 18:52:09 +02007822#ifdef __linux__
7823static int wil6210_get_aid(struct sigma_dut *dut, const char *bssid,
7824 unsigned int *aid)
7825{
Lior David0fe101e2017-03-09 16:09:50 +02007826 const char *pattern = "AID[ \t]+([0-9]+)";
Lior Davidcc88b562017-01-03 18:52:09 +02007827
Lior David0fe101e2017-03-09 16:09:50 +02007828 return wil6210_get_sta_info_field(dut, bssid, pattern, aid);
Lior Davidcc88b562017-01-03 18:52:09 +02007829}
7830#endif /* __linux__ */
7831
7832
7833static int sta_get_aid_60g(struct sigma_dut *dut, const char *bssid,
7834 unsigned int *aid)
7835{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007836 switch (get_driver_type(dut)) {
Lior Davidcc88b562017-01-03 18:52:09 +02007837#ifdef __linux__
7838 case DRIVER_WIL6210:
7839 return wil6210_get_aid(dut, bssid, aid);
7840#endif /* __linux__ */
7841 default:
7842 sigma_dut_print(dut, DUT_MSG_ERROR, "get AID not supported");
7843 return -1;
7844 }
7845}
7846
7847
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007848static int sta_get_parameter_60g(struct sigma_dut *dut, struct sigma_conn *conn,
7849 struct sigma_cmd *cmd)
7850{
7851 char buf[MAX_CMD_LEN];
7852 char bss_list[MAX_CMD_LEN];
7853 const char *parameter = get_param(cmd, "Parameter");
7854
7855 if (parameter == NULL)
7856 return -1;
7857
Lior Davidcc88b562017-01-03 18:52:09 +02007858 if (strcasecmp(parameter, "AID") == 0) {
7859 unsigned int aid = 0;
7860 char bssid[20];
7861
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007862 if (get_wpa_status(get_station_ifname(dut), "bssid",
Lior Davidcc88b562017-01-03 18:52:09 +02007863 bssid, sizeof(bssid)) < 0) {
7864 sigma_dut_print(dut, DUT_MSG_ERROR,
7865 "could not get bssid");
7866 return -2;
7867 }
7868
7869 if (sta_get_aid_60g(dut, bssid, &aid))
7870 return -2;
7871
7872 snprintf(buf, sizeof(buf), "aid,%d", aid);
7873 sigma_dut_print(dut, DUT_MSG_INFO, "%s", buf);
7874 send_resp(dut, conn, SIGMA_COMPLETE, buf);
7875 return 0;
7876 }
7877
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007878 if (strcasecmp(parameter, "DiscoveredDevList") == 0) {
7879 char *bss_line;
7880 char *bss_id = NULL;
7881 const char *ifname = get_param(cmd, "Interface");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307882 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007883
7884 if (ifname == NULL) {
7885 sigma_dut_print(dut, DUT_MSG_INFO,
7886 "For get DiscoveredDevList need Interface name.");
7887 return -1;
7888 }
7889
7890 /*
7891 * Use "BSS RANGE=ALL MASK=0x2" which provides a list
7892 * of BSSIDs in "bssid=<BSSID>\n"
7893 */
7894 if (wpa_command_resp(ifname, "BSS RANGE=ALL MASK=0x2",
7895 bss_list,
7896 sizeof(bss_list)) < 0) {
7897 sigma_dut_print(dut, DUT_MSG_ERROR,
7898 "Failed to get bss list");
7899 return -1;
7900 }
7901
7902 sigma_dut_print(dut, DUT_MSG_DEBUG,
7903 "bss list for ifname:%s is:%s",
7904 ifname, bss_list);
7905
7906 snprintf(buf, sizeof(buf), "DeviceList");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307907 bss_line = strtok_r(bss_list, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007908 while (bss_line) {
7909 if (sscanf(bss_line, "bssid=%ms", &bss_id) > 0 &&
7910 bss_id) {
7911 int len;
7912
7913 len = snprintf(buf + strlen(buf),
7914 sizeof(buf) - strlen(buf),
7915 ",%s", bss_id);
7916 free(bss_id);
7917 bss_id = NULL;
7918 if (len < 0) {
7919 sigma_dut_print(dut,
7920 DUT_MSG_ERROR,
7921 "Failed to read BSSID");
7922 send_resp(dut, conn, SIGMA_ERROR,
7923 "ErrorCode,Failed to read BSS ID");
7924 return 0;
7925 }
7926
7927 if ((size_t) len >= sizeof(buf) - strlen(buf)) {
7928 sigma_dut_print(dut,
7929 DUT_MSG_ERROR,
7930 "Response buf too small for list");
7931 send_resp(dut, conn,
7932 SIGMA_ERROR,
7933 "ErrorCode,Response buf too small for list");
7934 return 0;
7935 }
7936 }
7937
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307938 bss_line = strtok_r(NULL, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007939 }
7940
7941 sigma_dut_print(dut, DUT_MSG_INFO, "DiscoveredDevList is %s",
7942 buf);
7943 send_resp(dut, conn, SIGMA_COMPLETE, buf);
7944 return 0;
7945 }
7946
7947 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
7948 return 0;
7949}
7950
7951
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07007952static int sta_get_parameter_he(struct sigma_dut *dut, struct sigma_conn *conn,
7953 struct sigma_cmd *cmd)
7954{
7955 char buf[MAX_CMD_LEN];
7956 const char *parameter = get_param(cmd, "Parameter");
7957
7958 if (!parameter)
7959 return -1;
7960
7961 if (strcasecmp(parameter, "RSSI") == 0) {
7962 char rssi[10];
7963
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007964 if (get_wpa_signal_poll(dut, get_station_ifname(dut), "RSSI",
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07007965 rssi, sizeof(rssi)) < 0) {
7966 sigma_dut_print(dut, DUT_MSG_ERROR,
7967 "Could not get RSSI");
7968 return -2;
7969 }
7970
7971 snprintf(buf, sizeof(buf), "rssi,%s", rssi);
7972 sigma_dut_print(dut, DUT_MSG_INFO, "RSSI %s", buf);
7973 send_resp(dut, conn, SIGMA_COMPLETE, buf);
7974 return 0;
7975 }
7976
7977 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
7978 return 0;
7979}
7980
7981
Veerendranath Jakkamd0ad6ef2020-05-21 17:09:26 +05307982#ifdef NL80211_SUPPORT
7983
7984struct station_info {
7985 uint64_t filled;
7986 uint32_t beacon_mic_error_count;
7987 uint32_t beacon_replay_count;
7988};
7989
7990
7991static int qca_get_sta_info_handler(struct nl_msg *msg, void *arg)
7992{
7993 struct nlattr *tb[NL80211_ATTR_MAX + 1];
7994 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
7995 struct station_info *data = arg;
7996 struct nlattr *info[QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAX + 1];
7997 static struct nla_policy info_policy[
7998 QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAX + 1] = {
7999 [QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_MIC_ERROR_COUNT] = {
8000 .type = NLA_U32
8001 },
8002 [QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT] = {
8003 .type = NLA_U32
8004 },
8005 };
8006
8007 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
8008 genlmsg_attrlen(gnlh, 0), NULL);
8009
8010 if (!tb[NL80211_ATTR_VENDOR_DATA])
8011 return NL_SKIP;
8012
8013 if (nla_parse_nested(info, QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAX,
8014 tb[NL80211_ATTR_VENDOR_DATA], info_policy)) {
8015 return NL_SKIP;
8016 }
8017
8018 if (info[QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_MIC_ERROR_COUNT]) {
8019 data->filled |=
8020 BIT_ULL(QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_MIC_ERROR_COUNT);
8021 data->beacon_mic_error_count =
8022 nla_get_u32(info[QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_MIC_ERROR_COUNT]);
8023 }
8024
8025 if (info[QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT]) {
8026 data->filled |=
8027 BIT_ULL(QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT);
8028 data->beacon_replay_count =
8029 nla_get_u32(info[QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT]);
8030 }
8031
8032 return NL_SKIP;
8033}
8034
8035
8036static int qca_nl80211_get_sta_info(struct sigma_dut *dut, const char *intf,
8037 struct station_info *sta_data)
8038{
8039 struct nl_msg *msg;
8040 int ifindex, ret;
8041
8042 ifindex = if_nametoindex(intf);
8043 if (ifindex == 0) {
8044 sigma_dut_print(dut, DUT_MSG_ERROR,
8045 "%s: Index for interface %s not found",
8046 __func__, intf);
8047 return -1;
8048 }
8049
8050 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8051 NL80211_CMD_VENDOR)) ||
8052 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
8053 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
8054 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
8055 QCA_NL80211_VENDOR_SUBCMD_GET_STA_INFO)) {
8056 sigma_dut_print(dut, DUT_MSG_ERROR,
8057 "%s: err in adding vendor_cmd", __func__);
8058 nlmsg_free(msg);
8059 return -1;
8060 }
8061
8062 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg,
8063 qca_get_sta_info_handler, sta_data);
8064 if (ret) {
8065 sigma_dut_print(dut, DUT_MSG_ERROR,
8066 "%s: err in send_and_recv_msgs, ret=%d",
8067 __func__, ret);
8068 }
8069 return ret;
8070}
8071#endif /* NL80211_SUPPORT */
8072
8073
8074static int get_bip_mic_error_count(struct sigma_dut *dut,
8075 const char *ifname,
8076 unsigned int *count)
8077{
8078#ifdef NL80211_SUPPORT
8079 struct station_info sta_data;
8080#endif /* NL80211_SUPPORT */
8081
8082 if (get_driver_type(dut) != DRIVER_WCN) {
8083 sigma_dut_print(dut, DUT_MSG_ERROR,
8084 "BIP MIC error count not supported");
8085 return -1;
8086 }
8087
8088#ifdef NL80211_SUPPORT
8089 if (qca_nl80211_get_sta_info(dut, ifname, &sta_data) != 0 ||
8090 !(sta_data.filled &
8091 BIT_ULL(QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_MIC_ERROR_COUNT))) {
8092 sigma_dut_print(dut, DUT_MSG_ERROR,
8093 "BIP MIC error count fetching failed");
8094 return -1;
8095 }
8096
8097 *count = sta_data.beacon_mic_error_count;
8098 return 0;
8099#else /* NL80211_SUPPORT */
8100 sigma_dut_print(dut, DUT_MSG_ERROR,
8101 "BIP MIC error count cannot be fetched without NL80211_SUPPORT defined");
8102 return -1;
8103#endif /* NL80211_SUPPORT */
8104}
8105
8106
8107static int get_cmac_replay_count(struct sigma_dut *dut, const char *ifname,
8108 unsigned int *count)
8109{
8110#ifdef NL80211_SUPPORT
8111 struct station_info sta_data;
8112#endif /* NL80211_SUPPORT */
8113
8114 if (get_driver_type(dut) != DRIVER_WCN) {
8115 sigma_dut_print(dut, DUT_MSG_ERROR,
8116 "CMAC reply count not supported");
8117 return -1;
8118 }
8119
8120#ifdef NL80211_SUPPORT
8121 if (qca_nl80211_get_sta_info(dut, ifname, &sta_data) != 0 ||
8122 !(sta_data.filled &
8123 BIT_ULL(QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT))) {
8124 sigma_dut_print(dut, DUT_MSG_ERROR,
8125 "CMAC replay count fetching failed");
8126 return -1;
8127 }
8128
8129 *count = sta_data.beacon_replay_count;
8130 return 0;
8131#else /* NL80211_SUPPORT */
8132 sigma_dut_print(dut, DUT_MSG_ERROR,
8133 "CMAC replay count cannot be fetched without NL80211_SUPPORT defined");
8134 return -1;
8135#endif /* NL80211_SUPPORT */
8136}
8137
8138
8139static enum sigma_cmd_result sta_get_parameter_wpa3(struct sigma_dut *dut,
8140 struct sigma_conn *conn,
8141 struct sigma_cmd *cmd)
8142{
8143 char buf[MAX_CMD_LEN];
8144 const char *ifname = get_param(cmd, "interface");
8145 const char *parameter = get_param(cmd, "Parameter");
8146 unsigned int val;
8147
8148 if (!ifname || !parameter)
8149 return INVALID_SEND_STATUS;
8150
8151 if (strcasecmp(parameter, "BIPMICErrors") == 0) {
8152 if (get_bip_mic_error_count(dut, ifname, &val)) {
8153 send_resp(dut, conn, SIGMA_ERROR,
8154 "ErrorCode,Failed to get BIPMICErrors");
8155 return STATUS_SENT_ERROR;
8156 }
8157 snprintf(buf, sizeof(buf), "BIPMICErrors,%d", val);
8158 sigma_dut_print(dut, DUT_MSG_INFO, "BIPMICErrors %s", buf);
8159 send_resp(dut, conn, SIGMA_COMPLETE, buf);
8160 return STATUS_SENT;
8161 }
8162
8163 if (strcasecmp(parameter, "CMACReplays") == 0) {
8164 if (get_cmac_replay_count(dut, ifname, &val)) {
8165 send_resp(dut, conn, SIGMA_ERROR,
8166 "ErrorCode,Failed to get CMACReplays");
8167 return STATUS_SENT_ERROR;
8168 }
8169 snprintf(buf, sizeof(buf), "CMACReplays,%d", val);
8170 sigma_dut_print(dut, DUT_MSG_INFO, "CMACReplays %s", buf);
8171 send_resp(dut, conn, SIGMA_COMPLETE, buf);
8172 return STATUS_SENT;
8173 }
8174
8175 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
8176 return STATUS_SENT_ERROR;
8177}
8178
8179
Jouni Malinenca0abd32020-02-09 20:18:10 +02008180static enum sigma_cmd_result sta_get_pmk(struct sigma_dut *dut,
8181 struct sigma_conn *conn,
8182 struct sigma_cmd *cmd)
8183{
8184 const char *intf = get_param(cmd, "Interface");
8185 char buf[4096], bssid[20], resp[200], *pos, *tmp;
8186
8187 snprintf(buf, sizeof(buf), "PMKSA_GET %d", dut->infra_network_id);
8188 if (wpa_command_resp(intf, buf, buf, sizeof(buf)) < 0 ||
8189 strncmp(buf, "UNKNOWN COMMAND", 15) == 0) {
8190 send_resp(dut, conn, SIGMA_ERROR,
8191 "ErrorCode,PMKSA_GET not supported");
8192 return STATUS_SENT_ERROR;
8193 }
8194
8195 if (strncmp(buf, "FAIL", 4) == 0 ||
8196 get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0) {
8197 send_resp(dut, conn, SIGMA_ERROR,
8198 "ErrorCode,Could not find current network");
8199 return STATUS_SENT_ERROR;
8200 }
8201
8202 pos = buf;
8203 while (pos) {
8204 if (strncmp(pos, bssid, 17) == 0) {
8205 pos = strchr(pos, ' ');
8206 if (!pos)
Mohammad Asaad Akram956bfc32020-04-08 16:26:18 +05308207 break;
Jouni Malinenca0abd32020-02-09 20:18:10 +02008208 pos++;
8209 pos = strchr(pos, ' ');
8210 if (!pos)
Mohammad Asaad Akram956bfc32020-04-08 16:26:18 +05308211 break;
Jouni Malinenca0abd32020-02-09 20:18:10 +02008212 pos++;
8213 tmp = strchr(pos, ' ');
8214 if (!tmp)
Mohammad Asaad Akram956bfc32020-04-08 16:26:18 +05308215 break;
Jouni Malinenca0abd32020-02-09 20:18:10 +02008216 *tmp = '\0';
8217 break;
8218 }
Jouni Malinenca0abd32020-02-09 20:18:10 +02008219 pos = strchr(pos, '\n');
8220 if (pos)
8221 pos++;
8222 }
8223
8224 if (!pos) {
8225 send_resp(dut, conn, SIGMA_ERROR,
8226 "ErrorCode,PMK not available");
8227 return STATUS_SENT_ERROR;
8228 }
8229
8230 snprintf(resp, sizeof(resp), "PMK,%s", pos);
8231 send_resp(dut, conn, SIGMA_COMPLETE, resp);
8232 return STATUS_SENT;
8233}
8234
8235
Jouni Malinenf7222712019-06-13 01:50:21 +03008236static enum sigma_cmd_result cmd_sta_get_parameter(struct sigma_dut *dut,
8237 struct sigma_conn *conn,
8238 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008239{
8240 const char *program = get_param(cmd, "Program");
Jouni Malinenca0abd32020-02-09 20:18:10 +02008241 const char *parameter = get_param(cmd, "Parameter");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008242
Jouni Malinenca0abd32020-02-09 20:18:10 +02008243 if (!parameter)
8244 return INVALID_SEND_STATUS;
8245
8246 if (strcasecmp(parameter, "PMK") == 0)
8247 return sta_get_pmk(dut, conn, cmd);
8248
8249 if (!program)
8250 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008251
8252 if (strcasecmp(program, "P2PNFC") == 0)
8253 return p2p_cmd_sta_get_parameter(dut, conn, cmd);
8254
8255 if (strcasecmp(program, "60ghz") == 0)
8256 return sta_get_parameter_60g(dut, conn, cmd);
8257
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07008258 if (strcasecmp(program, "he") == 0)
8259 return sta_get_parameter_he(dut, conn, cmd);
8260
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008261#ifdef ANDROID_NAN
8262 if (strcasecmp(program, "NAN") == 0)
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07008263 return nan_cmd_sta_get_parameter(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008264#endif /* ANDROID_NAN */
8265
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07008266#ifdef MIRACAST
8267 if (strcasecmp(program, "WFD") == 0 ||
8268 strcasecmp(program, "DisplayR2") == 0)
8269 return miracast_cmd_sta_get_parameter(dut, conn, cmd);
8270#endif /* MIRACAST */
Veerendranath Jakkamd0ad6ef2020-05-21 17:09:26 +05308271 if (strcasecmp(program, "WPA3") == 0)
8272 return sta_get_parameter_wpa3(dut, conn, cmd);
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07008273
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008274 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
8275 return 0;
8276}
8277
8278
8279static void sta_reset_default_ath(struct sigma_dut *dut, const char *intf,
8280 const char *type)
8281{
8282 char buf[100];
8283
8284 if (dut->program == PROGRAM_VHT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008285 run_iwpriv(dut, intf, "chwidth 2");
8286 run_iwpriv(dut, intf, "mode 11ACVHT80");
8287 run_iwpriv(dut, intf, "vhtmcs -1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008288 }
8289
8290 if (dut->program == PROGRAM_HT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008291 run_iwpriv(dut, intf, "chwidth 0");
8292 run_iwpriv(dut, intf, "mode 11naht40");
8293 run_iwpriv(dut, intf, "set11NRates 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008294 }
8295
8296 if (dut->program == PROGRAM_VHT || dut->program == PROGRAM_HT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008297 run_iwpriv(dut, intf, "powersave 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008298
8299 /* Reset CTS width */
8300 snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 54 0",
8301 intf);
8302 if (system(buf) != 0) {
8303 sigma_dut_print(dut, DUT_MSG_ERROR,
8304 "wifitool %s beeliner_fw_test 54 0 failed",
8305 intf);
8306 }
8307
8308 /* Enable Dynamic Bandwidth signalling by default */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008309 run_iwpriv(dut, intf, "cwmenable 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008310
8311 snprintf(buf, sizeof(buf), "iwconfig %s rts 2347", intf);
8312 if (system(buf) != 0) {
8313 sigma_dut_print(dut, DUT_MSG_ERROR,
8314 "iwpriv rts failed");
8315 }
8316 }
8317
8318 if (type && strcasecmp(type, "Testbed") == 0) {
8319 dut->testbed_flag_txsp = 1;
8320 dut->testbed_flag_rxsp = 1;
8321 /* STA has to set spatial stream to 2 per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008322 run_iwpriv(dut, intf, "vht_mcsmap 0xfff0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008323
8324 /* Disable LDPC per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008325 run_iwpriv(dut, intf, "ldpc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008326
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008327 run_iwpriv(dut, intf, "amsdu 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008328
8329 /* TODO: Disable STBC 2x1 transmit and receive */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008330 run_iwpriv(dut, intf, "tx_stbc 0");
8331 run_iwpriv(dut, intf, "rx_stbc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008332
8333 /* STA has to disable Short GI per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008334 run_iwpriv(dut, intf, "shortgi 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008335 }
8336
8337 if (type && strcasecmp(type, "DUT") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008338 run_iwpriv(dut, intf, "nss 3");
Arif Hussainac6c5112018-05-25 17:34:00 -07008339 dut->sta_nss = 3;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008340
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008341 run_iwpriv(dut, intf, "shortgi 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008342 }
8343}
8344
8345
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08008346#ifdef NL80211_SUPPORT
8347static int sta_set_he_mcs(struct sigma_dut *dut, const char *intf,
8348 enum he_mcs_config mcs)
8349{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308350 return wcn_wifi_test_config_set_u8(
8351 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MCS, mcs);
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08008352}
8353#endif /* NL80211_SUPPORT */
8354
8355
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07008356static int sta_set_action_tx_in_he_tb_ppdu(struct sigma_dut *dut,
8357 const char *intf, int enable)
8358{
8359#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308360 return wcn_wifi_test_config_set_u8(
8361 dut, intf,
8362 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_ACTION_TX_TB_PPDU,
8363 enable);
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07008364#else /* NL80211_SUPPORT */
8365 sigma_dut_print(dut, DUT_MSG_ERROR,
8366 "HE action Tx TB PPDU cannot be set without NL80211_SUPPORT defined");
8367 return -1;
8368#endif /* NL80211_SUPPORT */
8369}
8370
8371
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08008372static int sta_set_heconfig_and_wep_tkip(struct sigma_dut *dut,
8373 const char *intf, int enable)
8374{
8375#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308376 return wcn_wifi_test_config_set_u8(
8377 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WEP_TKIP_IN_HE,
8378 enable);
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08008379#else /* NL80211_SUPPORT */
8380 sigma_dut_print(dut, DUT_MSG_ERROR,
8381 "HE config enablement cannot be changed without NL80211_SUPPORT defined");
8382 return -1;
8383#endif /* NL80211_SUPPORT */
8384}
8385
8386
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08008387#ifdef NL80211_SUPPORT
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08008388
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08008389static int sta_set_he_testbed_def(struct sigma_dut *dut,
8390 const char *intf, int cfg)
8391{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308392 return wcn_wifi_test_config_set_u8(
8393 dut, intf,
8394 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_SET_HE_TESTBED_DEFAULTS,
8395 cfg);
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08008396}
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08008397
8398
8399static int sta_set_2g_vht_supp(struct sigma_dut *dut, const char *intf, int cfg)
8400{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308401 return wcn_wifi_test_config_set_u8(
8402 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_2G_VHT,
8403 cfg);
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08008404}
8405
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08008406#endif /* NL80211_SUPPORT */
8407
8408
Qiwei Caib6806972020-01-15 13:52:11 +08008409int sta_set_addba_buf_size(struct sigma_dut *dut,
8410 const char *intf, int bufsize)
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08008411{
8412#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308413 return wcn_wifi_test_config_set_u16(
8414 dut, intf,
8415 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE, bufsize);
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08008416#else /* NL80211_SUPPORT */
8417 sigma_dut_print(dut, DUT_MSG_ERROR,
8418 "AddBA bufsize cannot be changed without NL80211_SUPPORT defined");
8419 return -1;
8420#endif /* NL80211_SUPPORT */
8421}
8422
8423
Kiran Kumar Lokere69d89952021-08-08 23:41:46 -07008424static int sta_set_scan_unicast_probe(struct sigma_dut *dut,
8425 const char *intf, int val)
8426{
8427#ifdef NL80211_SUPPORT
8428 return wcn_wifi_test_config_set_u8(
8429 dut, intf,
8430 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_USE_BSSID_IN_PROBE_REQ_RA,
8431 val);
8432#else /* NL80211_SUPPORT */
8433 sigma_dut_print(dut, DUT_MSG_ERROR,
8434 "Unicast RA in Probe Request frame cannot be set without NL80211_SUPPORT defined");
8435 return -1;
8436#endif /* NL80211_SUPPORT */
8437}
8438
8439
Kiran Kumar Lokere09dbcef2021-08-09 00:01:41 -07008440static int sta_set_rx_ctrl_multi_bss(struct sigma_dut *dut, const char *intf,
8441 int enable)
8442{
8443#ifdef NL80211_SUPPORT
8444 return wcn_wifi_test_config_set_u8(
8445 dut, intf,
8446 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_RX_CTRL_FRAME_TO_MBSS,
8447 enable);
8448#else /* NL80211_SUPPORT */
8449 sigma_dut_print(dut, DUT_MSG_ERROR,
8450 "Rx ctrl frame to Multi-BSS cannot be changed without NL80211_SUPPORT defined");
8451 return -1;
8452#endif /* NL80211_SUPPORT */
8453}
8454
8455
8456static int sta_set_bcast_twt_support(struct sigma_dut *dut, const char *intf,
8457 int enable)
8458{
8459#ifdef NL80211_SUPPORT
8460 return wcn_wifi_test_config_set_u8(
8461 dut, intf,
8462 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BCAST_TWT_SUPPORT,
8463 enable);
8464#else /* NL80211_SUPPORT */
8465 sigma_dut_print(dut, DUT_MSG_ERROR,
8466 "BCAST TWT cannot be changed without NL80211_SUPPORT defined");
8467 return -1;
8468#endif /* NL80211_SUPPORT */
8469}
8470
8471
Arif Hussain8d5b27b2018-05-14 14:31:03 -07008472static int sta_set_tx_beamformee(struct sigma_dut *dut, const char *intf,
8473 int enable)
8474{
8475#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308476 return wcn_wifi_test_config_set_u8(
8477 dut, intf,
8478 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_TX_BEAMFORMEE,
8479 enable);
Arif Hussain8d5b27b2018-05-14 14:31:03 -07008480#else /* NL80211_SUPPORT */
8481 sigma_dut_print(dut, DUT_MSG_ERROR,
8482 "tx beamformee cannot be changed without NL80211_SUPPORT defined");
8483 return -1;
8484#endif /* NL80211_SUPPORT */
8485}
8486
8487
Arif Hussain9765f7d2018-07-03 08:28:26 -07008488static int sta_set_beamformee_sts(struct sigma_dut *dut, const char *intf,
8489 int val)
8490{
8491#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308492 return wcn_wifi_test_config_set_u8(
8493 dut, intf,
8494 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_BEAMFORMEE_NSTS,
8495 val);
Arif Hussain9765f7d2018-07-03 08:28:26 -07008496#else /* NL80211_SUPPORT */
8497 sigma_dut_print(dut, DUT_MSG_ERROR,
8498 "beamformee sts cannot be changed without NL80211_SUPPORT defined");
8499 return -1;
8500#endif /* NL80211_SUPPORT */
8501}
8502
8503
Arif Hussain68d23f52018-07-11 13:39:08 -07008504#ifdef NL80211_SUPPORT
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07008505static int sta_set_mac_padding_duration(struct sigma_dut *dut, const char *intf,
8506 enum qca_wlan_he_mac_padding_dur val)
8507{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308508 return wcn_wifi_test_config_set_u8(
8509 dut, intf,
8510 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MAC_PADDING_DUR, val);
Arif Hussain68d23f52018-07-11 13:39:08 -07008511}
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07008512#endif /* NL80211_SUPPORT */
Arif Hussain68d23f52018-07-11 13:39:08 -07008513
8514
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07008515static int sta_set_tx_su_ppdu_cfg(struct sigma_dut *dut, const char *intf,
8516 int val)
8517{
8518#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308519 return wcn_wifi_test_config_set_u8(
8520 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_SUPPDU,
8521 val);
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07008522#else /* NL80211_SUPPORT */
8523 sigma_dut_print(dut, DUT_MSG_ERROR,
8524 "Tx SU PPDU cannot be set without NL80211_SUPPORT defined");
8525 return -1;
8526#endif /* NL80211_SUPPORT */
8527}
8528
8529
Kiran Kumar Lokere54b72522021-04-01 00:22:44 -07008530static int sta_set_mgmt_data_tx_disable_cfg(struct sigma_dut *dut,
8531 const char *intf, int val)
8532{
8533#ifdef NL80211_SUPPORT
8534 return wcn_wifi_test_config_set_u8(
8535 dut, intf,
8536 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_DISABLE_DATA_MGMT_RSP_TX,
8537 val);
8538#else /* NL80211_SUPPORT */
8539 sigma_dut_print(dut, DUT_MSG_ERROR,
8540 "Tx disable config cannot be set without NL80211_SUPPORT defined");
8541 return -1;
8542#endif /* NL80211_SUPPORT */
8543}
8544
8545
Kiran Kumar Lokere1809da12021-06-24 00:45:38 -07008546static int sta_set_keep_alive_data_cfg(struct sigma_dut *dut, const char *intf,
8547 int val)
8548{
8549#ifdef NL80211_SUPPORT
8550 return wcn_wifi_test_config_set_u8(
8551 dut, intf,
8552 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_KEEP_ALIVE_FRAME_TYPE,
8553 val);
8554#else /* NL80211_SUPPORT */
8555 sigma_dut_print(dut, DUT_MSG_ERROR,
8556 "Keep alive data type cannot be set without NL80211_SUPPORT defined");
8557 return -1;
8558#endif /* NL80211_SUPPORT */
8559}
8560
8561
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07008562#ifdef NL80211_SUPPORT
8563static int sta_set_he_om_ctrl_reset(struct sigma_dut *dut, const char *intf)
8564{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308565 return wcn_wifi_test_config_set_flag(
8566 dut, intf,
8567 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_CLEAR_HE_OM_CTRL_CONFIG);
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07008568}
8569#endif /* NL80211_SUPPORT */
8570
8571
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07008572static int sta_set_mu_edca_override(struct sigma_dut *dut, const char *intf,
8573 int val)
8574{
8575#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308576 return wcn_wifi_test_config_set_u8(
8577 dut, intf,
8578 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_OVERRIDE_MU_EDCA, val);
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07008579#else /* NL80211_SUPPORT */
8580 sigma_dut_print(dut, DUT_MSG_ERROR,
8581 "MU EDCA override cannot be changed without NL80211_SUPPORT defined");
8582 return -1;
8583#endif /* NL80211_SUPPORT */
8584}
8585
8586
Kiran Kumar Lokerefa7c7b92021-08-09 00:50:55 -07008587static int sta_set_er_su_ppdu_type_tx(struct sigma_dut *dut, const char *intf,
8588 int val)
8589{
8590#ifdef NL80211_SUPPORT
8591 return wcn_wifi_test_config_set_u8(
8592 dut, intf,
8593 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ER_SU_PPDU_TYPE, val);
8594#else /* NL80211_SUPPORT */
8595 sigma_dut_print(dut, DUT_MSG_ERROR,
8596 "ER-SU PPDU type cannot be set without NL80211_SUPPORT defined");
8597 return -1;
8598#endif /* NL80211_SUPPORT */
8599}
8600
8601
8602static int sta_set_ru_242_tone_tx(struct sigma_dut *dut, const char *intf,
8603 int val)
8604{
8605#ifdef NL80211_SUPPORT
8606 return wcn_wifi_test_config_set_u8(
8607 dut, intf,
8608 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_RU_242_TONE_TX, val);
8609#else /* NL80211_SUPPORT */
8610 sigma_dut_print(dut, DUT_MSG_ERROR,
8611 "RU 242 tone cannot be set without NL80211_SUPPORT defined");
8612 return -1;
8613#endif /* NL80211_SUPPORT */
8614}
8615
8616
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07008617static int sta_set_om_ctrl_supp(struct sigma_dut *dut, const char *intf,
8618 int val)
8619{
8620#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308621 return wcn_wifi_test_config_set_u8(
8622 dut, intf,
8623 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OM_CTRL_SUPP, val);
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07008624#else /* NL80211_SUPPORT */
8625 sigma_dut_print(dut, DUT_MSG_ERROR,
8626 "HE OM ctrl cannot be changed without NL80211_SUPPORT defined");
8627 return -1;
8628#endif /* NL80211_SUPPORT */
8629}
8630
8631
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07008632#ifdef NL80211_SUPPORT
8633
8634struct features_info {
8635 unsigned char flags[8];
8636 size_t flags_len;
8637};
8638
8639static int features_info_handler(struct nl_msg *msg, void *arg)
8640{
8641 struct nlattr *tb[NL80211_ATTR_MAX + 1];
8642 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
8643 struct features_info *info = arg;
8644 struct nlattr *nl_vend, *attr;
8645
8646 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
8647 genlmsg_attrlen(gnlh, 0), NULL);
8648
8649 nl_vend = tb[NL80211_ATTR_VENDOR_DATA];
8650 if (nl_vend) {
8651 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_MAX + 1];
8652
8653 nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_MAX,
8654 nla_data(nl_vend), nla_len(nl_vend), NULL);
8655
8656 attr = tb_vendor[QCA_WLAN_VENDOR_ATTR_FEATURE_FLAGS];
8657 if (attr) {
8658 int len = nla_len(attr);
8659
Vamsi Krishna79a91132021-08-16 21:40:22 +05308660 if (info && len <= sizeof(info->flags)) {
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07008661 memcpy(info->flags, nla_data(attr), len);
8662 info->flags_len = len;
8663 }
8664 }
8665 }
8666
8667 return NL_SKIP;
8668}
8669
8670
8671static int check_feature(enum qca_wlan_vendor_features feature,
8672 struct features_info *info)
8673{
8674 size_t idx = feature / 8;
8675
Vamsi Krishna79a91132021-08-16 21:40:22 +05308676 if (!info)
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07008677 return 0;
8678
8679 return (idx < info->flags_len) &&
8680 (info->flags[idx] & BIT(feature % 8));
8681}
8682
8683#endif /* NL80211_SUPPORT */
8684
8685
8686static void sta_get_twt_feature_async_supp(struct sigma_dut *dut,
8687 const char *intf)
8688{
8689#ifdef NL80211_SUPPORT
8690 struct nl_msg *msg;
8691 struct features_info info = { 0 };
8692 int ifindex, ret;
8693
8694 ifindex = if_nametoindex(intf);
8695 if (ifindex == 0) {
8696 sigma_dut_print(dut, DUT_MSG_ERROR,
8697 "%s: Index for interface %s failed",
8698 __func__, intf);
8699 return;
8700 }
8701
8702 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8703 NL80211_CMD_VENDOR)) ||
8704 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
8705 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
8706 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
8707 QCA_NL80211_VENDOR_SUBCMD_GET_FEATURES)) {
8708 sigma_dut_print(dut, DUT_MSG_ERROR,
8709 "%s: err in adding vendor_cmd and vendor_data",
8710 __func__);
8711 nlmsg_free(msg);
8712 return;
8713 }
8714
8715 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, features_info_handler,
8716 &info);
8717 if (ret) {
8718 sigma_dut_print(dut, DUT_MSG_ERROR,
8719 "%s: err in send_and_recv_msgs, ret=%d",
8720 __func__, ret);
8721 return;
8722 }
8723
8724 if (check_feature(QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT, &info))
8725 dut->sta_async_twt_supp = 1;
8726 else
8727 dut->sta_async_twt_supp = 0;
8728
8729 sigma_dut_print(dut, DUT_MSG_DEBUG,
8730 "%s: sta_async_twt_supp %d",
8731 __func__, dut->sta_async_twt_supp);
8732#else /* NL80211_SUPPORT */
8733 sigma_dut_print(dut, DUT_MSG_INFO,
8734 "TWT async supp get cannot be done without NL80211_SUPPORT defined");
8735 dut->sta_async_twt_supp = 0;
8736#endif /* NL80211_SUPPORT */
8737}
8738
8739
Arif Hussain480d5f42019-03-12 14:40:42 -07008740static int sta_set_twt_req_support(struct sigma_dut *dut, const char *intf,
8741 int val)
8742{
8743#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308744 return wcn_wifi_test_config_set_u8(
8745 dut, intf,
8746 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TWT_REQ_SUPPORT, val);
Arif Hussain480d5f42019-03-12 14:40:42 -07008747#else /* NL80211_SUPPORT */
8748 sigma_dut_print(dut, DUT_MSG_ERROR,
8749 "TWT Request cannot be changed without NL80211_SUPPORT defined");
8750 return -1;
8751#endif /* NL80211_SUPPORT */
8752}
8753
8754
Kiran Kumar Lokere4f2d4b02021-04-01 00:07:39 -07008755static int sta_set_bss_max_idle_period(struct sigma_dut *dut, const char *intf,
8756 int val)
8757{
8758#ifdef NL80211_SUPPORT
8759 return wcn_wifi_test_config_set_u16(
8760 dut, intf,
8761 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BSS_MAX_IDLE_PERIOD, val);
8762#else /* NL80211_SUPPORT */
8763 sigma_dut_print(dut, DUT_MSG_ERROR,
8764 "BSS max idle period cannot be set without NL80211_SUPPORT defined");
8765 return -1;
8766#endif /* NL80211_SUPPORT */
8767}
8768
8769
Kiran Kumar Lokere07ad92b2021-08-09 00:27:14 -07008770static int sta_set_bss_max_idle_support(struct sigma_dut *dut, const char *intf,
8771 int val)
8772{
8773#ifdef NL80211_SUPPORT
8774 return wcn_wifi_test_config_set_u8(
8775 dut, intf,
8776 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BSS_MAX_IDLE_PERIOD_ENABLE,
8777 val);
8778#else /* NL80211_SUPPORT */
8779 sigma_dut_print(dut, DUT_MSG_ERROR,
8780 "BSS max idle support cannot be set without NL80211_SUPPORT defined");
8781 return -1;
8782#endif /* NL80211_SUPPORT */
8783}
8784
8785
Srinivas Girigowda0525e292020-11-12 13:28:21 -08008786static int sta_set_fullbw_ulmumimo(struct sigma_dut *dut, const char *intf,
8787 int val)
8788{
8789#ifdef NL80211_SUPPORT
8790 return wcn_wifi_test_config_set_u8(
8791 dut, intf,
8792 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_FULL_BW_UL_MU_MIMO, val);
8793#else /* NL80211_SUPPORT */
8794 sigma_dut_print(dut, DUT_MSG_ERROR,
8795 "Full BW UL MU MIMO cannot be changed without NL80211_SUPPORT defined");
8796 return -1;
8797#endif /* NL80211_SUPPORT */
8798}
8799
8800
Kiran Kumar Lokered0ec5ed2021-04-01 00:15:04 -07008801static int sta_set_punctured_preamble_rx(struct sigma_dut *dut,
8802 const char *intf, int val)
8803{
8804#ifdef NL80211_SUPPORT
8805 return wcn_wifi_test_config_set_u8(
8806 dut, intf,
8807 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_PUNCTURED_PREAMBLE_RX,
8808 val);
8809#else /* NL80211_SUPPORT */
8810 sigma_dut_print(dut, DUT_MSG_ERROR,
8811 "Punctured preamble Rx cannot be set without NL80211_SUPPORT defined");
8812 return -1;
8813#endif /* NL80211_SUPPORT */
8814}
8815
8816
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -08008817int wcn_set_he_gi(struct sigma_dut *dut, const char *intf, u8 gi_val)
8818{
8819 #ifdef NL80211_SUPPORT
8820 struct nlattr *attr;
8821 struct nlattr *attr1;
8822 int ifindex, ret;
8823 struct nl_msg *msg;
8824
8825 ifindex = if_nametoindex(intf);
8826 if (ifindex == 0) {
8827 sigma_dut_print(dut, DUT_MSG_ERROR,
8828 "%s: Index for interface %s failed",
8829 __func__, intf);
8830 return -1;
8831 }
8832
8833 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8834 NL80211_CMD_SET_TX_BITRATE_MASK)) ||
8835 !(attr = nla_nest_start(msg, NL80211_ATTR_TX_RATES))) {
8836 sigma_dut_print(dut, DUT_MSG_ERROR,
8837 "%s: NL80211_CMD_SET_TX_BITRATE_MASK msg failed",
8838 __func__);
8839 nlmsg_free(msg);
8840 return -1;
8841 }
8842
8843 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s: Setting HE GI %d",
8844 __func__, gi_val);
8845
8846 attr1 = nla_nest_start(msg, NL80211_BAND_2GHZ);
8847 if (!attr1) {
8848 sigma_dut_print(dut, DUT_MSG_ERROR,
8849 "%s: Netlink nest start failed for NL80211_BAND_2GHZ",
8850 __func__);
8851 nlmsg_free(msg);
8852 return -1;
8853 }
8854 nla_put_u8(msg, NL80211_TXRATE_HE_GI, gi_val);
8855 nla_nest_end(msg, attr1);
8856
8857 attr1 = nla_nest_start(msg, NL80211_BAND_5GHZ);
8858 if (!attr1) {
8859 sigma_dut_print(dut, DUT_MSG_ERROR,
8860 "%s: Netlink nest start failed for NL80211_BAND_5GHZ",
8861 __func__);
8862 nlmsg_free(msg);
8863 return -1;
8864 }
8865 nla_put_u8(msg, NL80211_TXRATE_HE_GI, gi_val);
8866 nla_nest_end(msg, attr1);
8867
8868 nla_nest_end(msg, attr);
8869 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
8870 if (ret) {
8871 sigma_dut_print(dut, DUT_MSG_ERROR,
8872 "%s: send_and_recv_msgs failed, ret=%d",
8873 __func__, ret);
8874 }
8875 return ret;
8876#else /* NL80211_SUPPORT */
8877 return -1;
8878#endif /* NL80211_SUPPORT */
8879}
8880
8881
8882static int sta_set_vht_gi(struct sigma_dut *dut, const char *intf, u8 gi_val)
8883{
8884 #ifdef NL80211_SUPPORT
8885 struct nlattr *attr;
8886 struct nlattr *attr1;
8887 int ifindex, ret;
8888 struct nl_msg *msg;
8889
8890 ifindex = if_nametoindex(intf);
8891 if (ifindex == 0) {
8892 sigma_dut_print(dut, DUT_MSG_ERROR,
8893 "%s: Index for interface %s failed",
8894 __func__, intf);
8895 return -1;
8896 }
8897
8898 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8899 NL80211_CMD_SET_TX_BITRATE_MASK)) ||
8900 !(attr = nla_nest_start(msg, NL80211_ATTR_TX_RATES))) {
8901 sigma_dut_print(dut, DUT_MSG_ERROR,
8902 "%s: NL80211_CMD_SET_TX_BITRATE_MASK msg failed",
8903 __func__);
8904 nlmsg_free(msg);
8905 return -1;
8906 }
8907
8908 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s: Setting VHT GI %d",
8909 __func__, gi_val);
8910
8911 attr1 = nla_nest_start(msg, NL80211_BAND_2GHZ);
8912 if (!attr1) {
8913 sigma_dut_print(dut, DUT_MSG_ERROR,
8914 "%s: Netlink nest start failed for NL80211_BAND_2GHZ",
8915 __func__);
8916 nlmsg_free(msg);
8917 return -1;
8918 }
8919 nla_put_u8(msg, NL80211_TXRATE_GI, gi_val);
8920 nla_nest_end(msg, attr1);
8921
8922 attr1 = nla_nest_start(msg, NL80211_BAND_5GHZ);
8923 if (!attr1) {
8924 sigma_dut_print(dut, DUT_MSG_ERROR,
8925 "%s: Netlink nest start failed for NL80211_BAND_5GHZ",
8926 __func__);
8927 nlmsg_free(msg);
8928 return -1;
8929 }
8930 nla_put_u8(msg, NL80211_TXRATE_GI, gi_val);
8931 nla_nest_end(msg, attr1);
8932 nla_nest_end(msg, attr);
8933
8934 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
8935 if (ret) {
8936 sigma_dut_print(dut, DUT_MSG_ERROR,
8937 "%s: send_and_recv_msgs failed, ret=%d",
8938 __func__, ret);
8939 }
8940 return ret;
8941#else /* NL80211_SUPPORT */
8942 return -1;
8943#endif /* NL80211_SUPPORT */
8944}
8945
8946
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08008947static void sta_reset_default_wcn(struct sigma_dut *dut, const char *intf,
8948 const char *type)
8949{
8950 char buf[60];
8951
8952 if (dut->program == PROGRAM_HE) {
8953 /* resetting phymode to auto in case of HE program */
Vinita S. Maloo13a5cf72020-05-22 14:45:06 +05308954 sta_set_phymode(dut, intf, "auto");
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08008955
Amarnath Hullur Subramanyam9cecb502018-04-25 13:26:30 -07008956 /* reset the rate to Auto rate */
8957 snprintf(buf, sizeof(buf), "iwpriv %s set_11ax_rate 0xff",
8958 intf);
8959 if (system(buf) != 0) {
8960 sigma_dut_print(dut, DUT_MSG_ERROR,
8961 "iwpriv %s set_11ax_rate 0xff failed",
8962 intf);
8963 }
8964
Kiran Kumar Lokere86cfe3a2018-06-01 11:55:15 -07008965 /* reset the LDPC setting */
8966 snprintf(buf, sizeof(buf), "iwpriv %s ldpc 1", intf);
8967 if (system(buf) != 0) {
8968 sigma_dut_print(dut, DUT_MSG_ERROR,
8969 "iwpriv %s ldpc 1 failed", intf);
8970 }
8971
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08008972 /* reset the power save setting */
Vinita S. Malooa8b62722020-04-23 01:45:41 +05308973 set_power_save_wcn(dut, intf, 2);
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08008974
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08008975 /* remove all network profiles */
8976 remove_wpa_networks(intf);
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08008977
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08008978 /* Configure ADDBA Req/Rsp buffer size to be 64 */
8979 sta_set_addba_buf_size(dut, intf, 64);
8980
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07008981 if (dut->sta_async_twt_supp == -1)
8982 sta_get_twt_feature_async_supp(dut, intf);
8983
Kiran Kumar Lokere69d89952021-08-08 23:41:46 -07008984 sta_set_scan_unicast_probe(dut, intf, 0);
8985
Amarnath Hullur Subramanyam5f32d572018-03-02 00:02:33 -08008986#ifdef NL80211_SUPPORT
Kiran Kumar Lokere94829ce2022-01-20 10:49:08 -08008987 nl80211_close_event_sock(dut);
8988
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08008989 /* Reset the device HE capabilities to its default supported
8990 * configuration. */
8991 sta_set_he_testbed_def(dut, intf, 0);
8992
Amarnath Hullur Subramanyam5f32d572018-03-02 00:02:33 -08008993 /* Disable noackpolicy for all AC */
8994 if (nlvendor_sta_set_noack(dut, intf, 0, QCA_WLAN_AC_ALL)) {
8995 sigma_dut_print(dut, DUT_MSG_ERROR,
8996 "Disable of noackpolicy for all AC failed");
8997 }
8998#endif /* NL80211_SUPPORT */
8999
Amarnath Hullur Subramanyamb1724a52018-03-07 14:31:46 -08009000 /* Enable WMM by default */
9001 if (wcn_sta_set_wmm(dut, intf, "on")) {
9002 sigma_dut_print(dut, DUT_MSG_ERROR,
9003 "Enable of WMM in sta_reset_default_wcn failed");
9004 }
9005
9006 /* Disable ADDBA_REJECT by default */
9007 if (nlvendor_sta_set_addba_reject(dut, intf, 0)) {
9008 sigma_dut_print(dut, DUT_MSG_ERROR,
9009 "Disable of addba_reject in sta_reset_default_wcn failed");
9010 }
9011
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08009012 /* Enable sending of ADDBA by default */
9013 if (nlvendor_config_send_addba(dut, intf, 1)) {
9014 sigma_dut_print(dut, DUT_MSG_ERROR,
9015 "Enable sending of ADDBA in sta_reset_default_wcn failed");
9016 }
9017
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08009018 /* Enable AMPDU by default */
9019 iwpriv_sta_set_ampdu(dut, intf, 1);
9020
Subhani Shaik8e7a3052018-04-24 14:03:00 -07009021#ifdef NL80211_SUPPORT
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -08009022 if (wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_AUTO)) {
Subhani Shaik8e7a3052018-04-24 14:03:00 -07009023 sigma_dut_print(dut, DUT_MSG_ERROR,
9024 "Set LTF config to default in sta_reset_default_wcn failed");
9025 }
Arif Hussain9765f7d2018-07-03 08:28:26 -07009026
Kiran Kumar Lokerebad51122018-12-12 19:03:36 -08009027 /* set the beamformee NSTS(maximum number of
9028 * space-time streams) to default DUT config
9029 */
9030 if (sta_set_beamformee_sts(dut, intf, 7)) {
Arif Hussain9765f7d2018-07-03 08:28:26 -07009031 sigma_dut_print(dut, DUT_MSG_ERROR,
9032 "Failed to set BeamformeeSTS");
9033 }
Arif Hussain68d23f52018-07-11 13:39:08 -07009034
Kiran Kumar Lokere54b72522021-04-01 00:22:44 -07009035 if (sta_set_mgmt_data_tx_disable_cfg(dut, intf, 0)) {
9036 sigma_dut_print(dut, DUT_MSG_ERROR,
9037 "Failed to reset mgmt/data Tx disable config");
9038 }
9039
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07009040 if (sta_set_mac_padding_duration(
9041 dut, intf,
9042 QCA_WLAN_HE_NO_ADDITIONAL_PROCESS_TIME)) {
Arif Hussain68d23f52018-07-11 13:39:08 -07009043 sigma_dut_print(dut, DUT_MSG_ERROR,
9044 "Failed to set MAC padding duration");
9045 }
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07009046
9047 if (sta_set_mu_edca_override(dut, intf, 0)) {
9048 sigma_dut_print(dut, DUT_MSG_ERROR,
9049 "ErrorCode,Failed to set MU EDCA override disable");
9050 }
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07009051
Kiran Kumar Lokerefa7c7b92021-08-09 00:50:55 -07009052 if (sta_set_ru_242_tone_tx(dut, intf, 0)) {
9053 sigma_dut_print(dut, DUT_MSG_ERROR,
9054 "Failed to set RU 242 tone Tx");
9055 }
9056
9057 if (sta_set_er_su_ppdu_type_tx(dut, intf, 0)) {
9058 sigma_dut_print(dut, DUT_MSG_ERROR,
9059 "Failed to set ER-SU PPDU type Tx");
9060 }
9061
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07009062 if (sta_set_om_ctrl_supp(dut, intf, 1)) {
9063 sigma_dut_print(dut, DUT_MSG_ERROR,
9064 "Failed to set OM ctrl supp");
9065 }
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07009066
9067 if (sta_set_tx_su_ppdu_cfg(dut, intf, 1)) {
9068 sigma_dut_print(dut, DUT_MSG_ERROR,
9069 "Failed to set Tx SU PPDU enable");
9070 }
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07009071
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07009072 if (sta_set_action_tx_in_he_tb_ppdu(dut, intf, 0)) {
9073 sigma_dut_print(dut, DUT_MSG_ERROR,
9074 "failed to send TB PPDU Tx cfg");
9075 }
9076
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07009077 if (sta_set_he_om_ctrl_reset(dut, intf)) {
9078 sigma_dut_print(dut, DUT_MSG_ERROR,
9079 "Failed to set OM ctrl reset");
9080 }
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08009081
9082 /* +HTC-HE support default on */
9083 if (sta_set_he_htc_supp(dut, intf, 1)) {
9084 sigma_dut_print(dut, DUT_MSG_ERROR,
9085 "Setting of +HTC-HE support failed");
9086 }
Subhani Shaik8e7a3052018-04-24 14:03:00 -07009087#endif /* NL80211_SUPPORT */
9088
Arif Hussain8d5b27b2018-05-14 14:31:03 -07009089 if (sta_set_tx_beamformee(dut, intf, 1)) {
9090 sigma_dut_print(dut, DUT_MSG_ERROR,
9091 "Set tx beamformee enable by default in sta_reset_default_wcn failed");
9092 }
9093
Kiran Kumar Lokereb55ff442020-07-15 00:20:40 -07009094 wpa_command(intf, "SET oce 1");
9095
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08009096 /* Set nss to 1 and MCS 0-7 in case of testbed */
9097 if (type && strcasecmp(type, "Testbed") == 0) {
9098#ifdef NL80211_SUPPORT
9099 int ret;
9100#endif /* NL80211_SUPPORT */
9101
Kiran Kumar Lokereb55ff442020-07-15 00:20:40 -07009102 wpa_command(intf, "SET oce 0");
9103
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08009104 snprintf(buf, sizeof(buf), "iwpriv %s nss 1", intf);
9105 if (system(buf) != 0) {
9106 sigma_dut_print(dut, DUT_MSG_ERROR,
9107 "iwpriv %s nss failed", intf);
9108 }
9109
9110#ifdef NL80211_SUPPORT
9111 ret = sta_set_he_mcs(dut, intf, HE_80_MCS0_7);
9112 if (ret) {
9113 sigma_dut_print(dut, DUT_MSG_ERROR,
9114 "Setting of MCS failed, ret:%d",
9115 ret);
9116 }
9117#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyamc67621d2018-02-04 23:18:01 -08009118
9119 /* Disable STBC as default */
9120 wcn_sta_set_stbc(dut, intf, "0");
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08009121
9122 /* Disable AMSDU as default */
9123 iwpriv_sta_set_amsdu(dut, intf, "0");
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08009124
9125#ifdef NL80211_SUPPORT
9126 /* HE fragmentation default off */
9127 if (sta_set_he_fragmentation(dut, intf,
9128 HE_FRAG_DISABLE)) {
9129 sigma_dut_print(dut, DUT_MSG_ERROR,
9130 "Setting of HE fragmentation failed");
9131 }
Kiran Kumar Lokerebad51122018-12-12 19:03:36 -08009132
9133 /* set the beamformee NSTS(maximum number of
9134 * space-time streams) to default testbed config
9135 */
9136 if (sta_set_beamformee_sts(dut, intf, 3)) {
9137 sigma_dut_print(dut, DUT_MSG_ERROR,
9138 "Failed to set BeamformeeSTS");
9139 }
9140
Kiran Kumar Lokered0ec5ed2021-04-01 00:15:04 -07009141 if (sta_set_punctured_preamble_rx(dut, intf, 0)) {
9142 sigma_dut_print(dut, DUT_MSG_ERROR,
9143 "Failed to reset PreamblePunctRx support");
9144 }
9145
Kiran Kumar Lokere727687f2021-06-24 00:35:49 -07009146 if (sta_set_bss_max_idle_period(dut, intf, 0)) {
9147 sigma_dut_print(dut, DUT_MSG_ERROR,
9148 "Failed to reset BSS max idle period");
9149 }
9150
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08009151 /* +HTC-HE support default off */
9152 if (sta_set_he_htc_supp(dut, intf, 0)) {
9153 sigma_dut_print(dut, DUT_MSG_ERROR,
9154 "Setting of +HTC-HE support failed");
9155 }
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08009156
9157 /* Set device HE capabilities to testbed default
9158 * configuration. */
9159 if (sta_set_he_testbed_def(dut, intf, 1)) {
9160 sigma_dut_print(dut, DUT_MSG_DEBUG,
9161 "Failed to set HE defaults");
9162 }
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08009163
9164 /* Disable VHT support in 2.4 GHz for testbed */
9165 sta_set_2g_vht_supp(dut, intf, 0);
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08009166#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08009167
9168 /* Enable WEP/TKIP with HE capability in testbed */
9169 if (sta_set_heconfig_and_wep_tkip(dut, intf, 1)) {
9170 sigma_dut_print(dut, DUT_MSG_ERROR,
9171 "Enabling HE config with WEP/TKIP failed");
9172 }
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08009173 }
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08009174
9175 /* Defaults in case of DUT */
9176 if (type && strcasecmp(type, "DUT") == 0) {
Arif Hussaind48fcc72018-05-01 18:34:18 -07009177 /* Enable STBC by default */
9178 wcn_sta_set_stbc(dut, intf, "1");
9179
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08009180 /* set nss to 2 */
9181 snprintf(buf, sizeof(buf), "iwpriv %s nss 2", intf);
9182 if (system(buf) != 0) {
9183 sigma_dut_print(dut, DUT_MSG_ERROR,
9184 "iwpriv %s nss 2 failed", intf);
9185 }
Arif Hussainac6c5112018-05-25 17:34:00 -07009186 dut->sta_nss = 2;
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08009187
9188#ifdef NL80211_SUPPORT
Arif Hussainae239842018-05-01 18:20:05 -07009189 /* Set HE_MCS to 0-11 */
9190 if (sta_set_he_mcs(dut, intf, HE_80_MCS0_11)) {
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08009191 sigma_dut_print(dut, DUT_MSG_ERROR,
9192 "Setting of MCS failed");
9193 }
9194#endif /* NL80211_SUPPORT */
9195
9196 /* Disable WEP/TKIP with HE capability in DUT */
9197 if (sta_set_heconfig_and_wep_tkip(dut, intf, 0)) {
9198 sigma_dut_print(dut, DUT_MSG_ERROR,
9199 "Enabling HE config with WEP/TKIP failed");
9200 }
9201 }
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08009202 }
9203}
9204
9205
Veerendranath Jakkam47867202020-12-21 01:53:52 +05309206static int sta_set_client_privacy(struct sigma_dut *dut,
9207 struct sigma_conn *conn, const char *intf,
9208 int enable)
9209{
9210 if (enable &&
9211 (wpa_command(intf, "SET mac_addr 1") < 0 ||
9212 wpa_command(intf, "SET rand_addr_lifetime 1") < 0 ||
Veerendranath Jakkam39fd5c42020-12-21 02:02:21 +05309213 (wpa_command(intf, "MAC_RAND_SCAN enable=1 all") < 0 &&
9214 wpa_command(intf, "SET preassoc_mac_addr 1") < 0) ||
Veerendranath Jakkam47867202020-12-21 01:53:52 +05309215 wpa_command(intf, "SET gas_rand_mac_addr 1") < 0 ||
9216 wpa_command(intf, "SET gas_rand_addr_lifetime 1") < 0))
9217 return -1;
9218
9219 if (!enable &&
9220 (wpa_command(intf, "SET mac_addr 0") < 0 ||
Veerendranath Jakkam39fd5c42020-12-21 02:02:21 +05309221 (wpa_command(intf, "MAC_RAND_SCAN enable=0 all") < 0 &&
9222 wpa_command(intf, "SET preassoc_mac_addr 0") < 0) ||
Veerendranath Jakkam47867202020-12-21 01:53:52 +05309223 wpa_command(intf, "SET gas_rand_mac_addr 0") < 0))
9224 return -1;
9225
9226 dut->client_privacy = enable;
9227 return 0;
9228}
9229
9230
Jouni Malinenf7222712019-06-13 01:50:21 +03009231static enum sigma_cmd_result cmd_sta_reset_default(struct sigma_dut *dut,
9232 struct sigma_conn *conn,
9233 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009234{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009235 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02009236 const char *band = get_param(cmd, "band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009237 const char *type;
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07009238 const char *program = get_param(cmd, "program");
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05309239 const char *dev_role = get_param(cmd, "DevRole");
Veerendranath Jakkamc1f71b62021-01-23 03:09:51 +05309240 char resp[20];
Veerendranath Jakkamea7f0692021-08-11 19:13:12 +05309241 char buf[100];
Veerendranath Jakkamc1f71b62021-01-23 03:09:51 +05309242 int ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009243
Shivani Baranwal31182012021-12-07 21:11:13 +05309244#ifdef ANDROID
9245 kill_pid(dut, concat_sigma_tmpdir(dut, "/sigma_dut-dnsmasq.pid",
9246 buf, sizeof(buf)));
9247#endif /* ANDROID */
9248
Jouni Malinenb21f0542019-11-04 17:53:38 +02009249 if (dut->station_ifname_2g &&
9250 strcmp(dut->station_ifname_2g, intf) == 0)
9251 dut->use_5g = 0;
9252 else if (dut->station_ifname_5g &&
9253 strcmp(dut->station_ifname_5g, intf) == 0)
9254 dut->use_5g = 1;
9255
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07009256 if (!program)
9257 program = get_param(cmd, "prog");
9258 dut->program = sigma_program_to_enum(program);
Vinita S. Maloof7a2cbf2020-11-18 19:29:44 +05309259
9260 if (dut->program == PROGRAM_WFD && dut->user_config_timeout)
9261 dut->default_timeout = dut->user_config_timeout;
9262
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009263 dut->device_type = STA_unknown;
9264 type = get_param(cmd, "type");
9265 if (type && strcasecmp(type, "Testbed") == 0)
9266 dut->device_type = STA_testbed;
9267 if (type && strcasecmp(type, "DUT") == 0)
9268 dut->device_type = STA_dut;
9269
9270 if (dut->program == PROGRAM_TDLS) {
9271 /* Clear TDLS testing mode */
9272 wpa_command(intf, "SET tdls_disabled 0");
9273 wpa_command(intf, "SET tdls_testing 0");
9274 dut->no_tpk_expiration = 0;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009275 if (get_driver_type(dut) == DRIVER_WCN) {
Pradeep Reddy POTTETI8ce2a232016-10-28 12:17:32 +05309276 /* Enable the WCN driver in TDLS Explicit trigger mode
9277 */
9278 wpa_command(intf, "SET tdls_external_control 0");
9279 wpa_command(intf, "SET tdls_trigger_control 0");
9280 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009281 }
9282
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07009283#ifdef MIRACAST
9284 if (dut->program == PROGRAM_WFD ||
9285 dut->program == PROGRAM_DISPLAYR2)
9286 miracast_sta_reset_default(dut, conn, cmd);
9287#endif /* MIRACAST */
9288
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009289 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009290 case DRIVER_ATHEROS:
9291 sta_reset_default_ath(dut, intf, type);
9292 break;
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08009293 case DRIVER_WCN:
9294 sta_reset_default_wcn(dut, intf, type);
9295 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009296 default:
9297 break;
9298 }
9299
9300#ifdef ANDROID_NAN
9301 if (dut->program == PROGRAM_NAN)
9302 nan_cmd_sta_reset_default(dut, conn, cmd);
9303#endif /* ANDROID_NAN */
9304
Vinay Gannevaram3b9fdd32019-06-14 17:55:44 +05309305 if (dut->program == PROGRAM_LOC &&
9306 lowi_cmd_sta_reset_default(dut, conn, cmd) < 0)
9307 return ERROR_SEND_STATUS;
9308
Jouni Malinen9a742ff2022-01-27 00:43:14 +02009309 if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3 ||
9310 dut->program == PROGRAM_HS2_R4) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009311 unlink("SP/wi-fi.org/pps.xml");
9312 if (system("rm -r SP/*") != 0) {
9313 }
9314 unlink("next-client-cert.pem");
9315 unlink("next-client-key.pem");
9316 }
9317
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02009318 /* For WPS program of the 60 GHz band the band type needs to be saved */
9319 if (dut->program == PROGRAM_WPS) {
9320 if (band && strcasecmp(band, "60GHz") == 0) {
9321 dut->band = WPS_BAND_60G;
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02009322 /* For 60 GHz enable WPS for WPS TCs */
9323 dut->wps_disable = 0;
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02009324 } else {
9325 dut->band = WPS_BAND_NON_60G;
9326 }
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02009327 } else if (dut->program == PROGRAM_60GHZ) {
9328 /* For 60 GHz MAC/PHY TCs WPS must be disabled */
9329 dut->wps_disable = 1;
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02009330 }
9331
Alexei Avshalom Lazar157ba062018-12-23 16:15:26 +02009332 if (is_60g_sigma_dut(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009333 const char *dev_role = get_param(cmd, "DevRole");
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02009334 char buf[256];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009335
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02009336 sigma_dut_print(dut, DUT_MSG_INFO,
9337 "WPS 60 GHz program, wps_disable = %d",
9338 dut->wps_disable);
9339
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009340 if (!dev_role) {
9341 send_resp(dut, conn, SIGMA_ERROR,
9342 "errorCode,Missing DevRole argument");
9343 return 0;
9344 }
9345
9346 if (strcasecmp(dev_role, "STA") == 0)
9347 dut->dev_role = DEVROLE_STA;
9348 else if (strcasecmp(dev_role, "PCP") == 0)
9349 dut->dev_role = DEVROLE_PCP;
9350 else {
9351 send_resp(dut, conn, SIGMA_ERROR,
9352 "errorCode,Unknown DevRole");
9353 return 0;
9354 }
9355
9356 if (dut->device_type == STA_unknown) {
9357 sigma_dut_print(dut, DUT_MSG_ERROR,
9358 "Device type is not STA testbed or DUT");
9359 send_resp(dut, conn, SIGMA_ERROR,
9360 "errorCode,Unknown device type");
9361 return 0;
9362 }
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02009363
9364 sigma_dut_print(dut, DUT_MSG_DEBUG,
9365 "Setting msdu_size to MAX: 7912");
9366 snprintf(buf, sizeof(buf), "ifconfig %s mtu 7912",
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009367 get_station_ifname(dut));
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02009368
9369 if (system(buf) != 0) {
9370 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
9371 buf);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02009372 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02009373 }
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02009374
9375 if (sta_set_force_mcs(dut, 0, 1)) {
9376 sigma_dut_print(dut, DUT_MSG_ERROR,
9377 "Failed to reset force MCS");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02009378 return ERROR_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02009379 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009380 }
9381
9382 wpa_command(intf, "WPS_ER_STOP");
9383 wpa_command(intf, "FLUSH");
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05309384 wpa_command(intf, "ERP_FLUSH");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009385 wpa_command(intf, "SET radio_disabled 0");
9386
Alexei Avshalom Lazar744ae8a2019-01-31 17:26:46 +02009387 dut->wps_forced_version = 0;
9388
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02009389 if (dut->wsc_fragment) {
9390 dut->wsc_fragment = 0;
9391 wpa_command(intf, "SET device_name Test client");
9392 wpa_command(intf, "SET manufacturer ");
9393 wpa_command(intf, "SET model_name ");
9394 wpa_command(intf, "SET model_number ");
9395 wpa_command(intf, "SET serial_number ");
9396 }
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02009397 if (is_60g_sigma_dut(dut) && dut->force_rsn_ie) {
9398 dut->force_rsn_ie = FORCE_RSN_IE_NONE;
9399 sta_60g_force_rsn_ie(dut, FORCE_RSN_IE_NONE);
9400 }
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02009401
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009402 if (dut->tmp_mac_addr && dut->set_macaddr) {
9403 dut->tmp_mac_addr = 0;
9404 if (system(dut->set_macaddr) != 0) {
9405 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to clear "
9406 "temporary MAC address");
9407 }
9408 }
9409
9410 set_ps(intf, dut, 0);
9411
Jouni Malinenba630452018-06-22 11:49:59 +03009412 if (dut->program == PROGRAM_HS2 || dut->program == PROGRAM_HS2_R2 ||
Jouni Malinen9a742ff2022-01-27 00:43:14 +02009413 dut->program == PROGRAM_HS2_R3 || dut->program == PROGRAM_HS2_R4) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009414 wpa_command(intf, "SET interworking 1");
9415 wpa_command(intf, "SET hs20 1");
9416 }
9417
Deepak Dhamdhere0fe0e452017-12-18 14:52:09 -08009418 if (dut->program == PROGRAM_HS2_R2 ||
Jouni Malinenba630452018-06-22 11:49:59 +03009419 dut->program == PROGRAM_HS2_R3 ||
Jouni Malinen9a742ff2022-01-27 00:43:14 +02009420 dut->program == PROGRAM_HS2_R4 ||
Deepak Dhamdhere0fe0e452017-12-18 14:52:09 -08009421 dut->program == PROGRAM_OCE) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009422 wpa_command(intf, "SET pmf 1");
9423 } else {
9424 wpa_command(intf, "SET pmf 0");
9425 }
9426
9427 hs2_clear_credentials(intf);
9428 wpa_command(intf, "SET hessid 00:00:00:00:00:00");
9429 wpa_command(intf, "SET access_network_type 15");
9430
9431 static_ip_file(0, NULL, NULL, NULL);
9432 kill_dhcp_client(dut, intf);
9433 clear_ip_addr(dut, intf);
9434
9435 dut->er_oper_performed = 0;
9436 dut->er_oper_bssid[0] = '\0';
9437
priyadharshini gowthamanad6cbba2016-10-04 10:39:58 -07009438 if (dut->program == PROGRAM_LOC) {
9439 /* Disable Interworking by default */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009440 wpa_command(get_station_ifname(dut), "SET interworking 0");
priyadharshini gowthamanad6cbba2016-10-04 10:39:58 -07009441 }
9442
Kiran Kumar Lokeredd086642020-06-04 00:29:26 -07009443 if (dut->program == PROGRAM_MBO || dut->program == PROGRAM_HE) {
Ashwini Patil00402582017-04-13 12:29:39 +05309444 free(dut->non_pref_ch_list);
9445 dut->non_pref_ch_list = NULL;
Ashwini Patil5acd7382017-04-13 15:55:04 +05309446 free(dut->btm_query_cand_list);
9447 dut->btm_query_cand_list = NULL;
Ashwini Patilc63161e2017-04-13 16:30:23 +05309448 wpa_command(intf, "SET reject_btm_req_reason 0");
Ashwini Patila75de5a2017-04-13 16:35:05 +05309449 wpa_command(intf, "SET ignore_assoc_disallow 0");
Ashwini Patild174f2c2017-04-13 16:49:46 +05309450 wpa_command(intf, "SET gas_address3 0");
Ashwini Patil9183fdb2017-04-13 16:58:25 +05309451 wpa_command(intf, "SET roaming 1");
Ankita Bajaj1d974552018-09-18 16:56:44 +05309452 wpa_command(intf, "SET interworking 1");
Ashwini Patil00402582017-04-13 12:29:39 +05309453 }
9454
Jouni Malinen3c367e82017-06-23 17:01:47 +03009455 free(dut->rsne_override);
9456 dut->rsne_override = NULL;
9457
Jouni Malinen68143132017-09-02 02:34:08 +03009458 free(dut->sae_commit_override);
9459 dut->sae_commit_override = NULL;
Jouni Malinen4b3769d2019-10-10 16:20:29 +03009460 wpa_command(intf, "SET sae_pmkid_in_assoc 0");
Jouni Malinen11e55212019-11-22 21:46:59 +02009461 dut->sae_pwe = SAE_PWE_DEFAULT;
Jouni Malinen68143132017-09-02 02:34:08 +03009462
Jouni Malinen134fe3c2019-06-12 04:16:49 +03009463 dut->sta_associate_wait_connect = 0;
9464 dut->server_cert_hash[0] = '\0';
Jouni Malinen37d5c692019-08-19 16:56:55 +03009465 dut->server_cert_tod = 0;
Jouni Malinen134fe3c2019-06-12 04:16:49 +03009466 dut->sta_tod_policy = 0;
9467
Jouni Malinend86e5822017-08-29 03:55:32 +03009468 dut->dpp_conf_id = -1;
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02009469 free(dut->dpp_peer_uri);
9470 dut->dpp_peer_uri = NULL;
Jouni Malinen63d50412017-11-24 11:55:38 +02009471 dut->dpp_local_bootstrap = -1;
Jouni Malinen5011fb52017-12-05 21:00:15 +02009472 wpa_command(intf, "SET dpp_config_processing 2");
Jouni Malinen90776b12020-05-04 15:34:46 +03009473 wpa_command(intf, "SET dpp_mud_url ");
Jouni Malinen29a63f42022-04-13 22:08:47 +03009474 dpp_mdns_stop(dut);
Jouni Malinend86e5822017-08-29 03:55:32 +03009475
Jouni Malinenfac9cad2017-10-10 18:35:55 +03009476 wpa_command(intf, "VENDOR_ELEM_REMOVE 13 *");
9477
vamsi krishnaa2799492017-12-05 14:28:01 +05309478 if (dut->program == PROGRAM_OCE) {
Ankita Bajaja2cb5672017-10-25 16:08:28 +05309479 wpa_command(intf, "SET oce 1");
vamsi krishnaa2799492017-12-05 14:28:01 +05309480 wpa_command(intf, "SET disable_fils 0");
Ankita Bajaj1bde7942018-01-09 19:15:01 +05309481 wpa_command(intf, "FILS_HLP_REQ_FLUSH");
9482 dut->fils_hlp = 0;
9483#ifdef ANDROID
9484 hlp_thread_cleanup(dut);
9485#endif /* ANDROID */
vamsi krishnaa2799492017-12-05 14:28:01 +05309486 }
Ankita Bajaja2cb5672017-10-25 16:08:28 +05309487
Veerendranath Jakkamea7f0692021-08-11 19:13:12 +05309488 if (dut->program == PROGRAM_QM) {
Vamsi Krishnaf642d6a2020-03-27 12:33:14 +05309489 wpa_command(intf, "SET interworking 1");
Veerendranath Jakkama16cdc82021-09-12 16:44:22 +05309490 wpa_command(intf, "SET enable_dscp_policy_capa 1");
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +05309491 dut->qm_domain_name[0] = '\0';
Veerendranath Jakkama16cdc82021-09-12 16:44:22 +05309492 dut->reject_dscp_policies = 0;
Veerendranath Jakkam1bf1bd62021-09-12 16:35:55 +05309493 dut->num_dscp_status = 0;
Veerendranath Jakkamea7f0692021-08-11 19:13:12 +05309494 snprintf(buf, sizeof(buf),
9495 "ip -6 route replace fe80::/64 dev %s table local",
9496 intf);
9497 if (system(buf) != 0)
9498 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to run: %s",
9499 buf);
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05309500
9501 stop_dscp_policy_mon_thread(dut);
9502 clear_all_dscp_policies(dut);
Veerendranath Jakkamea7f0692021-08-11 19:13:12 +05309503 }
Vamsi Krishnaf642d6a2020-03-27 12:33:14 +05309504
Jouni Malinen8179fee2019-03-28 03:19:47 +02009505 dut->akm_values = 0;
Shivani Baranwal7aa48602021-09-29 10:53:38 +05309506
9507#ifdef NL80211_SUPPORT
9508 if (get_driver_type(dut) == DRIVER_WCN)
9509 sta_config_params(dut, intf, STA_SET_FT_DS, 0);
9510#endif /* NL80211_SUPPORT */
9511
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03009512 dut->sta_ft_ds = 0;
Jouni Malinen8179fee2019-03-28 03:19:47 +02009513
Sunil Dutt076081f2018-02-05 19:45:50 +05309514#ifdef NL80211_SUPPORT
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009515 if (get_driver_type(dut) == DRIVER_WCN &&
Sunil Dutt44595082018-02-12 19:41:45 +05309516 dut->config_rsnie == 1) {
9517 dut->config_rsnie = 0;
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05309518 sta_config_params(dut, intf, STA_SET_RSNIE, 0);
Sunil Dutt076081f2018-02-05 19:45:50 +05309519 }
9520#endif /* NL80211_SUPPORT */
9521
Sunil Duttfebf8a82018-02-09 18:50:13 +05309522 if (dev_role && strcasecmp(dev_role, "STA-CFON") == 0) {
9523 dut->dev_role = DEVROLE_STA_CFON;
9524 return sta_cfon_reset_default(dut, conn, cmd);
9525 }
9526
Jouni Malinen439352d2018-09-13 03:42:23 +03009527 wpa_command(intf, "SET setband AUTO");
9528
Veerendranath Jakkamc1f71b62021-01-23 03:09:51 +05309529 ret = wpa_command_resp(intf, "GET_CAPABILITY ocv", resp, sizeof(resp));
9530 dut->ocvc = ret == 0 && strncmp(resp, "supported", 9) == 0;
9531
9532 ret = wpa_command_resp(intf, "GET_CAPABILITY beacon_prot", resp,
9533 sizeof(resp));
9534 dut->beacon_prot = ret == 0 && strncmp(resp, "supported", 9) == 0;
9535
Veerendranath Jakkam47867202020-12-21 01:53:52 +05309536 if (sta_set_client_privacy(dut, conn, intf,
9537 dut->program == PROGRAM_WPA3 &&
9538 dut->device_type == STA_dut &&
9539 dut->client_privacy_default)) {
9540 sigma_dut_print(dut, DUT_MSG_ERROR,
9541 "Failed to set client privacy functionality");
9542 /* sta_reset_default command is not really supposed to fail,
9543 * so allow this to continue. */
9544 }
9545
Veerendranath Jakkamca239592021-10-11 20:48:00 +05309546 if (get_driver_type(dut) == DRIVER_WCN)
9547 wcn_set_ignore_h2e_rsnxe(dut, intf, 0);
9548
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +05309549 dut->saquery_oci_freq = 0;
Shivani Baranwalebde8f62021-10-19 12:26:02 +05309550 dut->prev_disable_scs_support = 0;
9551 dut->prev_disable_mscs_support = 0;
Vamsi Krishnac1633d22020-05-06 18:31:21 +05309552
Veerendranath Jakkamf6c8ab52022-03-10 05:43:02 -08009553 if (dut->autoconnect_default)
9554 wpa_command(intf, "STA_AUTOCONNECT 1");
9555 else
9556 wpa_command(intf, "STA_AUTOCONNECT 0");
9557
Sunil Duttfebf8a82018-02-09 18:50:13 +05309558 if (dut->program != PROGRAM_VHT)
9559 return cmd_sta_p2p_reset(dut, conn, cmd);
9560
Priyadharshini Gowthamana7dfd492015-11-09 14:34:08 -08009561 return 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009562}
9563
9564
Jouni Malinenf7222712019-06-13 01:50:21 +03009565static enum sigma_cmd_result cmd_sta_get_events(struct sigma_dut *dut,
9566 struct sigma_conn *conn,
9567 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009568{
9569 const char *program = get_param(cmd, "Program");
9570
9571 if (program == NULL)
9572 return -1;
9573#ifdef ANDROID_NAN
9574 if (strcasecmp(program, "NAN") == 0)
9575 return nan_cmd_sta_get_events(dut, conn, cmd);
9576#endif /* ANDROID_NAN */
9577 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
9578 return 0;
9579}
9580
9581
Jouni Malinen82905202018-04-29 17:20:10 +03009582static int sta_exec_action_url(struct sigma_dut *dut, struct sigma_conn *conn,
9583 struct sigma_cmd *cmd)
9584{
9585 const char *url = get_param(cmd, "url");
9586 const char *method = get_param(cmd, "method");
9587 pid_t pid;
9588 int status;
9589
9590 if (!url || !method)
9591 return -1;
9592
9593 /* TODO: Add support for method,post */
9594 if (strcasecmp(method, "get") != 0) {
9595 send_resp(dut, conn, SIGMA_ERROR,
9596 "ErrorCode,Unsupported method");
9597 return 0;
9598 }
9599
9600 pid = fork();
9601 if (pid < 0) {
9602 perror("fork");
9603 return -1;
9604 }
9605
9606 if (pid == 0) {
9607 char * argv[5] = { "wget", "-O", "/dev/null",
9608 (char *) url, NULL };
9609
9610 execv("/usr/bin/wget", argv);
9611 perror("execv");
9612 exit(0);
9613 return -1;
9614 }
9615
9616 if (waitpid(pid, &status, 0) < 0) {
9617 perror("waitpid");
9618 return -1;
9619 }
9620
9621 if (WIFEXITED(status)) {
9622 const char *errmsg;
9623
9624 if (WEXITSTATUS(status) == 0)
9625 return 1;
9626 sigma_dut_print(dut, DUT_MSG_INFO, "wget exit status %d",
9627 WEXITSTATUS(status));
9628 switch (WEXITSTATUS(status)) {
9629 case 4:
9630 errmsg = "errmsg,Network failure";
9631 break;
9632 case 8:
9633 errmsg = "errmsg,Server issued an error response";
9634 break;
9635 default:
9636 errmsg = "errmsg,Unknown failure from wget";
9637 break;
9638 }
9639 send_resp(dut, conn, SIGMA_ERROR, errmsg);
9640 return 0;
9641 }
9642
9643 send_resp(dut, conn, SIGMA_ERROR, "errmsg,Unknown failure");
9644 return 0;
9645}
9646
9647
Jouni Malinenf7222712019-06-13 01:50:21 +03009648static enum sigma_cmd_result cmd_sta_exec_action(struct sigma_dut *dut,
9649 struct sigma_conn *conn,
9650 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009651{
9652 const char *program = get_param(cmd, "Prog");
9653
Jouni Malinen82905202018-04-29 17:20:10 +03009654 if (program && !get_param(cmd, "interface"))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009655 return -1;
9656#ifdef ANDROID_NAN
Jouni Malinen82905202018-04-29 17:20:10 +03009657 if (program && strcasecmp(program, "NAN") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009658 return nan_cmd_sta_exec_action(dut, conn, cmd);
9659#endif /* ANDROID_NAN */
Jouni Malinen82905202018-04-29 17:20:10 +03009660
9661 if (program && strcasecmp(program, "Loc") == 0)
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07009662 return loc_cmd_sta_exec_action(dut, conn, cmd);
Jouni Malinen82905202018-04-29 17:20:10 +03009663
9664 if (get_param(cmd, "url"))
9665 return sta_exec_action_url(dut, conn, cmd);
9666
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009667 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
9668 return 0;
9669}
9670
9671
Jouni Malinenf7222712019-06-13 01:50:21 +03009672static enum sigma_cmd_result cmd_sta_set_11n(struct sigma_dut *dut,
9673 struct sigma_conn *conn,
9674 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009675{
9676 const char *intf = get_param(cmd, "Interface");
9677 const char *val, *mcs32, *rate;
9678
9679 val = get_param(cmd, "GREENFIELD");
9680 if (val) {
9681 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
9682 /* Enable GD */
9683 send_resp(dut, conn, SIGMA_ERROR,
9684 "ErrorCode,GF not supported");
9685 return 0;
9686 }
9687 }
9688
9689 val = get_param(cmd, "SGI20");
9690 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009691 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009692 case DRIVER_ATHEROS:
9693 ath_sta_set_sgi(dut, intf, val);
9694 break;
9695 default:
9696 send_resp(dut, conn, SIGMA_ERROR,
9697 "ErrorCode,SGI20 not supported");
9698 return 0;
9699 }
9700 }
9701
9702 mcs32 = get_param(cmd, "MCS32"); /* HT Duplicate Mode Enable/Disable */
9703 rate = get_param(cmd, "MCS_FIXEDRATE"); /* Fixed MCS rate (0..31) */
9704 if (mcs32 && rate) {
9705 /* TODO */
9706 send_resp(dut, conn, SIGMA_ERROR,
9707 "ErrorCode,MCS32,MCS_FIXEDRATE not supported");
9708 return 0;
9709 } else if (mcs32 && !rate) {
9710 /* TODO */
9711 send_resp(dut, conn, SIGMA_ERROR,
9712 "ErrorCode,MCS32 not supported");
9713 return 0;
9714 } else if (!mcs32 && rate) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009715 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009716 case DRIVER_ATHEROS:
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -07009717 novap_reset(dut, intf, 1);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009718 ath_sta_set_11nrates(dut, intf, rate);
9719 break;
9720 default:
9721 send_resp(dut, conn, SIGMA_ERROR,
9722 "ErrorCode,MCS32_FIXEDRATE not supported");
9723 return 0;
9724 }
9725 }
9726
9727 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
9728}
9729
9730
Arif Hussain7b47d2d2018-05-09 10:44:02 -07009731static void cmd_set_max_he_mcs(struct sigma_dut *dut, const char *intf,
9732 int mcs_config)
9733{
9734#ifdef NL80211_SUPPORT
9735 int ret;
9736
9737 switch (mcs_config) {
9738 case HE_80_MCS0_7:
9739 case HE_80_MCS0_9:
9740 case HE_80_MCS0_11:
9741 ret = sta_set_he_mcs(dut, intf, mcs_config);
9742 if (ret) {
9743 sigma_dut_print(dut, DUT_MSG_ERROR,
9744 "cmd_set_max_he_mcs: Setting of MCS:%d failed, ret:%d",
9745 mcs_config, ret);
9746 }
9747 break;
9748 default:
9749 sigma_dut_print(dut, DUT_MSG_ERROR,
9750 "cmd_set_max_he_mcs: Invalid mcs %d",
9751 mcs_config);
9752 break;
9753 }
9754#else /* NL80211_SUPPORT */
9755 sigma_dut_print(dut, DUT_MSG_ERROR,
9756 "max HE MCS cannot be changed without NL80211_SUPPORT defined");
9757#endif /* NL80211_SUPPORT */
9758}
9759
9760
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07009761struct wait_event {
9762 struct sigma_dut *dut;
9763 int cmd;
9764 unsigned int twt_op;
9765};
9766
9767#ifdef NL80211_SUPPORT
9768
9769static int twt_event_handler(struct nl_msg *msg, void *arg)
9770{
9771 struct wait_event *wait = arg;
9772 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
9773 struct nlattr *tb[NL80211_ATTR_MAX + 1];
9774 uint32_t subcmd;
9775 uint8_t *data = NULL;
9776 size_t len = 0;
9777 struct nlattr *twt_rsp[QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_MAX + 1];
9778 struct nlattr *twt_status[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX + 1];
9779 int cmd_id;
9780 unsigned char val;
9781
9782 if (!wait)
9783 return NL_SKIP;
9784
9785 if (gnlh->cmd != NL80211_CMD_VENDOR) {
9786 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9787 "%s: NL cmd is not vendor %d", __func__,
9788 gnlh->cmd);
9789 return NL_SKIP;
9790 }
9791
9792 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
9793 genlmsg_attrlen(gnlh, 0), NULL);
9794
9795 if (!tb[NL80211_ATTR_VENDOR_ID] || !tb[NL80211_ATTR_VENDOR_SUBCMD]) {
9796 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9797 "%s: vendor ID not found", __func__);
9798 return NL_SKIP;
9799 }
9800 subcmd = nla_get_u32(tb[NL80211_ATTR_VENDOR_SUBCMD]);
9801
9802 if (subcmd != QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) {
9803 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9804 "%s: Not a TWT_cmd %d", __func__, subcmd);
9805 return NL_SKIP;
9806 }
9807 if (tb[NL80211_ATTR_VENDOR_DATA]) {
9808 data = nla_data(tb[NL80211_ATTR_VENDOR_DATA]);
9809 len = nla_len(tb[NL80211_ATTR_VENDOR_DATA]);
9810 } else {
9811 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9812 "%s: vendor data not present", __func__);
9813 return NL_SKIP;
9814 }
9815 if (!data || !len) {
9816 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9817 "Invalid vendor data or len");
9818 return NL_SKIP;
9819 }
9820 sigma_dut_print(wait->dut, DUT_MSG_DEBUG,
9821 "event data len %ld", len);
9822 hex_dump(wait->dut, data, len);
9823 if (nla_parse(twt_rsp, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_MAX,
9824 (struct nlattr *) data, len, NULL)) {
9825 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9826 "vendor data parse error");
9827 return NL_SKIP;
9828 }
9829
9830 val = nla_get_u8(twt_rsp[QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION]);
9831 if (val != wait->twt_op) {
9832 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9833 "Invalid TWT operation, expected %d, rcvd %d",
9834 wait->twt_op, val);
9835 return NL_SKIP;
9836 }
9837 if (nla_parse_nested(twt_status, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX,
9838 twt_rsp[QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS],
9839 NULL)) {
9840 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9841 "nla_parse failed for TWT event");
9842 return NL_SKIP;
9843 }
9844
9845 cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_STATUS;
9846 if (!twt_status[cmd_id]) {
9847 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9848 "%s TWT resp status missing", __func__);
9849 wait->cmd = -1;
9850 } else {
9851 val = nla_get_u8(twt_status[cmd_id]);
9852 if (val != QCA_WLAN_VENDOR_TWT_STATUS_OK) {
9853 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9854 "%s TWT resp status %d", __func__, val);
9855 wait->cmd = -1;
9856 } else {
9857 wait->cmd = 1;
9858 }
9859 }
9860
9861 return NL_SKIP;
9862}
9863
9864
9865static int wait_on_nl_socket(struct nl_sock *sock, struct sigma_dut *dut,
9866 unsigned int timeout)
9867{
9868 fd_set read_fd_set;
9869 int retval;
9870 int sock_fd;
9871 struct timeval time_out;
9872
9873 time_out.tv_sec = timeout;
9874 time_out.tv_usec = 0;
9875
9876 FD_ZERO(&read_fd_set);
9877
9878 if (!sock)
9879 return -1;
9880
9881 sock_fd = nl_socket_get_fd(sock);
9882 FD_SET(sock_fd, &read_fd_set);
9883
9884 retval = select(sock_fd + 1, &read_fd_set, NULL, NULL, &time_out);
9885
9886 if (retval == 0)
9887 sigma_dut_print(dut, DUT_MSG_ERROR,
9888 "%s: TWT event response timedout", __func__);
9889
9890 if (retval < 0)
9891 sigma_dut_print(dut, DUT_MSG_ERROR, "%s:no NL msgs, ret=%d",
9892 __func__, retval);
9893
9894 return retval;
9895}
9896
9897
9898#define TWT_ASYNC_EVENT_WAIT_TIME_SEC 6
9899
9900static int twt_async_event_wait(struct sigma_dut *dut, unsigned int twt_op)
9901{
Kiran Kumar Lokere94829ce2022-01-20 10:49:08 -08009902 struct nl_cb *cb = NULL;
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07009903 int err_code = 0, select_retval = 0;
9904 struct wait_event wait_info;
9905
Kiran Kumar Lokere94829ce2022-01-20 10:49:08 -08009906 if (dut->nl_ctx->event_sock)
9907 cb = nl_socket_get_cb(dut->nl_ctx->event_sock);
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07009908 if (!cb) {
9909 sigma_dut_print(dut, DUT_MSG_ERROR,
9910 "event callback not found");
9911 return ERROR_SEND_STATUS;
9912 }
9913
9914 wait_info.cmd = 0;
9915 wait_info.dut = dut;
9916 wait_info.twt_op = twt_op;
9917
9918 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, twt_event_handler, &wait_info);
9919
9920 while (!wait_info.cmd) {
9921 select_retval = wait_on_nl_socket(
9922 dut->nl_ctx->event_sock, dut,
9923 TWT_ASYNC_EVENT_WAIT_TIME_SEC);
9924
9925 if (select_retval > 0) {
9926 err_code = nl_recvmsgs(dut->nl_ctx->event_sock, cb);
9927 if (err_code < 0) {
9928 sigma_dut_print(dut, DUT_MSG_ERROR,
9929 "%s: nl rcv failed, err_code %d",
9930 __func__, err_code);
9931 break;
9932 }
9933 } else {
9934 sigma_dut_print(dut, DUT_MSG_ERROR,
9935 "%s: wait on socket failed %d",
9936 __func__, select_retval);
9937 err_code = 1;
9938 break;
9939 }
9940
9941 }
9942 nl_cb_put(cb);
9943
9944 if (wait_info.cmd < 0)
9945 err_code = 1;
9946
9947 sigma_dut_print(dut, DUT_MSG_DEBUG,
9948 "%s: rcvd cmd %d, err_code %d, s_ret %d",
9949 __func__, wait_info.cmd, err_code, select_retval);
9950
9951 return err_code;
9952}
9953
9954#endif /* NL80211_SUPPORT */
9955
9956
Srinivas Girigowda6707f032020-10-26 15:24:46 -07009957static int sta_twt_send_suspend(struct sigma_dut *dut, struct sigma_conn *conn,
9958 struct sigma_cmd *cmd)
9959{
9960#ifdef NL80211_SUPPORT
9961 struct nlattr *attr, *attr1;
9962 struct nl_msg *msg;
9963 int ifindex, ret;
9964 const char *intf = get_param(cmd, "Interface");
9965
9966 ifindex = if_nametoindex(intf);
9967 if (ifindex == 0) {
9968 sigma_dut_print(dut, DUT_MSG_ERROR,
9969 "%s: Index for interface %s failed",
9970 __func__, intf);
9971 return ERROR_SEND_STATUS;
9972 }
9973
9974 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
9975 NL80211_CMD_VENDOR)) ||
9976 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
9977 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
9978 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
9979 QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
9980 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
9981 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
9982 QCA_WLAN_TWT_SUSPEND) ||
9983 !(attr1 = nla_nest_start(msg,
Kiran Kumar Lokere7ede00c2021-08-09 00:59:52 -07009984 QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS))) {
Srinivas Girigowda6707f032020-10-26 15:24:46 -07009985 sigma_dut_print(dut, DUT_MSG_ERROR,
9986 "%s: err in adding vendor_cmd and vendor_data",
9987 __func__);
9988 nlmsg_free(msg);
9989 return ERROR_SEND_STATUS;
9990 }
9991 nla_nest_end(msg, attr1);
9992 nla_nest_end(msg, attr);
9993
9994 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
9995 if (ret) {
9996 sigma_dut_print(dut, DUT_MSG_ERROR,
9997 "%s: err in send_and_recv_msgs, ret=%d",
9998 __func__, ret);
9999 }
10000
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -070010001 if (!dut->sta_async_twt_supp)
10002 return ret;
10003
10004 return twt_async_event_wait(dut, QCA_WLAN_TWT_SUSPEND);
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010005#else /* NL80211_SUPPORT */
10006 sigma_dut_print(dut, DUT_MSG_ERROR,
10007 "TWT suspend cannot be done without NL80211_SUPPORT defined");
10008 return ERROR_SEND_STATUS;
10009#endif /* NL80211_SUPPORT */
10010}
10011
10012
10013static int sta_twt_send_nudge(struct sigma_dut *dut, struct sigma_conn *conn,
10014 struct sigma_cmd *cmd,
10015 unsigned int suspend_duration)
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 next_twt_size = 1;
10023
10024 ifindex = if_nametoindex(intf);
10025 if (ifindex == 0) {
10026 sigma_dut_print(dut, DUT_MSG_ERROR,
10027 "%s: Index for interface %s failed",
10028 __func__, intf);
10029 return ERROR_SEND_STATUS;
10030 }
10031
10032 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
10033 NL80211_CMD_VENDOR)) ||
10034 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
10035 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
10036 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
10037 QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
10038 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
10039 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
10040 QCA_WLAN_TWT_NUDGE) ||
10041 !(attr1 = nla_nest_start(msg,
10042 QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS)) ||
10043 (suspend_duration &&
10044 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_WAKE_TIME,
10045 suspend_duration)) ||
10046 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_NEXT_TWT_SIZE,
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010047 next_twt_size) ||
10048 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_FLOW_ID, 0)) {
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010049 sigma_dut_print(dut, DUT_MSG_ERROR,
10050 "%s: err in adding vendor_cmd and vendor_data",
10051 __func__);
10052 nlmsg_free(msg);
10053 return ERROR_SEND_STATUS;
10054 }
10055 nla_nest_end(msg, attr1);
10056 nla_nest_end(msg, attr);
10057
10058 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
10059 if (ret) {
10060 sigma_dut_print(dut, DUT_MSG_ERROR,
10061 "%s: err in send_and_recv_msgs, ret=%d",
10062 __func__, ret);
10063 }
10064
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -070010065 if (!dut->sta_async_twt_supp)
10066 return ret;
10067
10068 return twt_async_event_wait(dut, QCA_WLAN_TWT_NUDGE);
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010069#else /* NL80211_SUPPORT */
10070 sigma_dut_print(dut, DUT_MSG_ERROR,
10071 "TWT suspend cannot be done without NL80211_SUPPORT defined");
10072 return ERROR_SEND_STATUS;
10073#endif /* NL80211_SUPPORT */
10074}
10075
10076
10077static int sta_twt_suspend_or_nudge(struct sigma_dut *dut,
10078 struct sigma_conn *conn,
10079 struct sigma_cmd *cmd)
10080{
10081 const char *val;
10082
10083 val = get_param(cmd, "TWT_SuspendDuration");
10084 if (val) {
10085 unsigned int suspend_duration;
10086
10087 suspend_duration = atoi(val);
10088 suspend_duration = suspend_duration * 1000 * 1000;
10089 return sta_twt_send_nudge(dut, conn, cmd, suspend_duration);
10090 }
10091
10092 return sta_twt_send_suspend(dut, conn, cmd);
10093}
10094
10095
10096static int sta_twt_resume(struct sigma_dut *dut, struct sigma_conn *conn,
10097 struct sigma_cmd *cmd)
10098{
10099#ifdef NL80211_SUPPORT
10100 struct nlattr *attr, *attr1;
10101 struct nl_msg *msg;
10102 int ifindex, ret;
10103 const char *intf = get_param(cmd, "Interface");
10104 int next2_twt_size = 1;
10105 unsigned int resume_duration = 0;
10106 const char *val;
10107
10108 ifindex = if_nametoindex(intf);
10109 if (ifindex == 0) {
10110 sigma_dut_print(dut, DUT_MSG_ERROR,
10111 "%s: Index for interface %s failed",
10112 __func__, intf);
10113 return ERROR_SEND_STATUS;
10114 }
10115
10116 val = get_param(cmd, "TWT_ResumeDuration");
10117 if (val) {
10118 resume_duration = atoi(val);
10119 resume_duration = resume_duration * 1000 * 1000;
10120 }
10121
10122 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
10123 NL80211_CMD_VENDOR)) ||
10124 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
10125 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
10126 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
10127 QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
10128 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
10129 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
10130 QCA_WLAN_TWT_RESUME) ||
10131 !(attr1 = nla_nest_start(msg,
10132 QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS)) ||
10133 (resume_duration &&
10134 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_RESUME_NEXT2_TWT,
10135 resume_duration)) ||
10136 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_RESUME_NEXT_TWT_SIZE,
10137 next2_twt_size)) {
10138 sigma_dut_print(dut, DUT_MSG_ERROR,
10139 "%s: err in adding vendor_cmd and vendor_data",
10140 __func__);
10141 nlmsg_free(msg);
10142 return ERROR_SEND_STATUS;
10143 }
10144 nla_nest_end(msg, attr1);
10145 nla_nest_end(msg, attr);
10146
10147 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
10148 if (ret) {
10149 sigma_dut_print(dut, DUT_MSG_ERROR,
10150 "%s: err in send_and_recv_msgs, ret=%d",
10151 __func__, ret);
10152 }
10153
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -070010154 if (!dut->sta_async_twt_supp)
10155 return ret;
10156
10157 return twt_async_event_wait(dut, QCA_WLAN_TWT_RESUME);
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010158#else /* NL80211_SUPPORT */
10159 sigma_dut_print(dut, DUT_MSG_ERROR,
10160 "TWT resume cannot be done without NL80211_SUPPORT defined");
10161 return ERROR_SEND_STATUS;
10162#endif /* NL80211_SUPPORT */
10163}
10164
10165
Kiran Kumar Lokerebd396102020-04-27 12:01:09 -070010166#define TWT_REQUEST_CMD 0
10167#define TWT_SUGGEST_CMD 1
10168#define TWT_DEMAND_CMD 2
10169
Arif Hussain480d5f42019-03-12 14:40:42 -070010170static int sta_twt_request(struct sigma_dut *dut, struct sigma_conn *conn,
10171 struct sigma_cmd *cmd)
10172{
10173#ifdef NL80211_SUPPORT
10174 struct nlattr *params;
10175 struct nlattr *attr;
Arif Hussain480d5f42019-03-12 14:40:42 -070010176 struct nl_msg *msg;
10177 int ifindex, ret;
10178 const char *val;
10179 const char *intf = get_param(cmd, "Interface");
10180 int wake_interval_exp = 10, nominal_min_wake_dur = 255,
10181 wake_interval_mantissa = 512;
10182 int flow_type = 0, twt_trigger = 0, target_wake_time = 0,
Kiran Kumar Lokerebd396102020-04-27 12:01:09 -070010183 protection = 0, cmd_type = QCA_WLAN_VENDOR_TWT_SETUP_SUGGEST;
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010184 int bcast_twt = 0;
10185 int bcast_twt_id = 0, bcast_twt_recommdn = 0, bcast_twt_persis = 0;
Arif Hussain480d5f42019-03-12 14:40:42 -070010186
10187 ifindex = if_nametoindex(intf);
10188 if (ifindex == 0) {
10189 sigma_dut_print(dut, DUT_MSG_ERROR,
10190 "%s: Index for interface %s failed",
10191 __func__, intf);
10192 return -1;
10193 }
10194
10195 val = get_param(cmd, "FlowType");
10196 if (val) {
10197 flow_type = atoi(val);
10198 if (flow_type != 0 && flow_type != 1) {
10199 sigma_dut_print(dut, DUT_MSG_ERROR,
10200 "TWT: Invalid FlowType %d", flow_type);
10201 return -1;
10202 }
10203 }
10204
10205 val = get_param(cmd, "TWT_Trigger");
10206 if (val) {
10207 twt_trigger = atoi(val);
10208 if (twt_trigger != 0 && twt_trigger != 1) {
10209 sigma_dut_print(dut, DUT_MSG_ERROR,
10210 "TWT: Invalid TWT_Trigger %d",
10211 twt_trigger);
10212 return -1;
10213 }
10214 }
10215
10216 val = get_param(cmd, "Protection");
10217 if (val) {
10218 protection = atoi(val);
10219 if (protection != 0 && protection != 1) {
10220 sigma_dut_print(dut, DUT_MSG_ERROR,
10221 "TWT: Invalid Protection %d",
10222 protection);
10223 return -1;
10224 }
10225 }
10226
Kiran Kumar Lokerebd396102020-04-27 12:01:09 -070010227 val = get_param(cmd, "SetupCommand");
10228 if (val) {
10229 cmd_type = atoi(val);
10230 if (cmd_type == TWT_REQUEST_CMD)
10231 cmd_type = QCA_WLAN_VENDOR_TWT_SETUP_REQUEST;
10232 else if (cmd_type == TWT_SUGGEST_CMD)
10233 cmd_type = QCA_WLAN_VENDOR_TWT_SETUP_SUGGEST;
10234 else if (cmd_type == TWT_DEMAND_CMD)
10235 cmd_type = QCA_WLAN_VENDOR_TWT_SETUP_DEMAND;
10236 else
10237 sigma_dut_print(dut, DUT_MSG_ERROR,
10238 "Default suggest is used for cmd %d",
10239 cmd_type);
10240 }
10241
Arif Hussain480d5f42019-03-12 14:40:42 -070010242 val = get_param(cmd, "TargetWakeTime");
10243 if (val)
10244 target_wake_time = atoi(val);
10245
10246 val = get_param(cmd, "WakeIntervalMantissa");
10247 if (val)
10248 wake_interval_mantissa = atoi(val);
10249
10250 val = get_param(cmd, "WakeIntervalExp");
10251 if (val)
10252 wake_interval_exp = atoi(val);
10253
10254 val = get_param(cmd, "NominalMinWakeDur");
10255 if (val)
10256 nominal_min_wake_dur = atoi(val);
10257
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010258 val = get_param(cmd, "BTWT_ID");
10259 if (val) {
10260 bcast_twt_id = atoi(val);
10261 bcast_twt = 1;
10262 }
10263
10264 val = get_param(cmd, "BTWT_Persistence");
10265 if (val) {
10266 bcast_twt_persis = atoi(val);
10267 bcast_twt = 1;
10268 }
10269
10270 val = get_param(cmd, "BTWT_Recommendation");
10271 if (val) {
10272 bcast_twt_recommdn = atoi(val);
10273 bcast_twt = 1;
10274 }
10275
10276 if (bcast_twt)
10277 sigma_dut_print(dut, DUT_MSG_DEBUG,
10278 "BCAST_TWT: ID %d, RECOMM %d, PERSIS %d",
10279 bcast_twt_id, bcast_twt_recommdn,
10280 bcast_twt_persis);
10281
Arif Hussain480d5f42019-03-12 14:40:42 -070010282 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
10283 NL80211_CMD_VENDOR)) ||
10284 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
10285 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
10286 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010287 QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010288 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010289 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
10290 QCA_WLAN_TWT_SET) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010291 !(params = nla_nest_start(
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010292 msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS)) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010293 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_EXP,
10294 wake_interval_exp) ||
Kiran Kumar Lokerebd396102020-04-27 12:01:09 -070010295 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_REQ_TYPE, cmd_type) ||
Kiran Kumar Lokere2cffae52019-09-26 18:44:15 -070010296 (twt_trigger &&
10297 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TRIGGER)) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010298 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE,
10299 flow_type) ||
Kiran Kumar Lokere2cffae52019-09-26 18:44:15 -070010300 (protection &&
10301 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_PROTECTION)) ||
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010302 (bcast_twt &&
10303 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST)) ||
10304 (bcast_twt &&
10305 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_ID,
10306 bcast_twt_id)) ||
10307 (bcast_twt &&
10308 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_PERSISTENCE,
10309 bcast_twt_persis)) ||
10310 (bcast_twt &&
10311 nla_put_u8(msg,
10312 QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_RECOMMENDATION,
10313 bcast_twt_recommdn)) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010314 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME,
10315 target_wake_time) ||
10316 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_DURATION,
10317 nominal_min_wake_dur) ||
10318 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_MANTISSA,
10319 wake_interval_mantissa)) {
10320 sigma_dut_print(dut, DUT_MSG_ERROR,
10321 "%s: err in adding vendor_cmd and vendor_data",
10322 __func__);
10323 nlmsg_free(msg);
10324 return -1;
10325 }
Arif Hussain480d5f42019-03-12 14:40:42 -070010326 nla_nest_end(msg, params);
10327 nla_nest_end(msg, attr);
10328
10329 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
10330 if (ret) {
10331 sigma_dut_print(dut, DUT_MSG_ERROR,
10332 "%s: err in send_and_recv_msgs, ret=%d",
10333 __func__, ret);
10334 }
10335
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -070010336 if (!dut->sta_async_twt_supp)
10337 return ret;
10338
10339 return twt_async_event_wait(dut, QCA_WLAN_TWT_SET);
Arif Hussain480d5f42019-03-12 14:40:42 -070010340#else /* NL80211_SUPPORT */
10341 sigma_dut_print(dut, DUT_MSG_ERROR,
10342 "TWT request cannot be done without NL80211_SUPPORT defined");
10343 return -1;
10344#endif /* NL80211_SUPPORT */
10345}
10346
10347
10348static int sta_twt_teardown(struct sigma_dut *dut, struct sigma_conn *conn,
10349 struct sigma_cmd *cmd)
10350{
10351 #ifdef NL80211_SUPPORT
10352 struct nlattr *params;
10353 struct nlattr *attr;
Arif Hussain480d5f42019-03-12 14:40:42 -070010354 int ifindex, ret;
10355 struct nl_msg *msg;
10356 const char *intf = get_param(cmd, "Interface");
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010357 int bcast_twt = 0;
10358 int bcast_twt_id = 0;
10359 const char *val;
Arif Hussain480d5f42019-03-12 14:40:42 -070010360
10361 ifindex = if_nametoindex(intf);
10362 if (ifindex == 0) {
10363 sigma_dut_print(dut, DUT_MSG_ERROR,
10364 "%s: Index for interface %s failed",
10365 __func__, intf);
10366 return -1;
10367 }
10368
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010369 val = get_param(cmd, "BTWT_ID");
10370 if (val) {
10371 bcast_twt_id = atoi(val);
10372 bcast_twt = 1;
10373 }
10374
Arif Hussain480d5f42019-03-12 14:40:42 -070010375 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
10376 NL80211_CMD_VENDOR)) ||
10377 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
10378 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
10379 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010380 QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010381 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010382 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
10383 QCA_WLAN_TWT_TERMINATE) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010384 !(params = nla_nest_start(
10385 msg,
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010386 QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS)) ||
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010387 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE, 0) ||
10388 (bcast_twt &&
10389 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST)) ||
10390 (bcast_twt &&
10391 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_ID,
10392 bcast_twt_id))) {
Arif Hussain480d5f42019-03-12 14:40:42 -070010393 sigma_dut_print(dut, DUT_MSG_ERROR,
10394 "%s: err in adding vendor_cmd and vendor_data",
10395 __func__);
10396 nlmsg_free(msg);
10397 return -1;
10398 }
Arif Hussain480d5f42019-03-12 14:40:42 -070010399 nla_nest_end(msg, params);
10400 nla_nest_end(msg, attr);
10401
10402 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
10403 if (ret) {
10404 sigma_dut_print(dut, DUT_MSG_ERROR,
10405 "%s: err in send_and_recv_msgs, ret=%d",
10406 __func__, ret);
10407 }
10408
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -070010409 if (!dut->sta_async_twt_supp)
10410 return ret;
10411
10412 return twt_async_event_wait(dut, QCA_WLAN_TWT_TERMINATE);
Arif Hussain480d5f42019-03-12 14:40:42 -070010413#else /* NL80211_SUPPORT */
10414 sigma_dut_print(dut, DUT_MSG_ERROR,
10415 "TWT teardown cannot be done without NL80211_SUPPORT defined");
10416 return -1;
10417#endif /* NL80211_SUPPORT */
10418}
10419
10420
Kiran Kumar Lokere50eb2cd2018-12-18 18:31:28 -080010421static int sta_transmit_omi(struct sigma_dut *dut, struct sigma_conn *conn,
10422 struct sigma_cmd *cmd)
10423{
10424#ifdef NL80211_SUPPORT
10425 struct nlattr *params;
10426 struct nlattr *attr;
10427 struct nlattr *attr1;
10428 struct nl_msg *msg;
10429 int ifindex, ret;
10430 const char *val;
10431 const char *intf = get_param(cmd, "Interface");
10432 uint8_t rx_nss = 0xFF, ch_bw = 0xFF, tx_nsts = 0xFF, ulmu_dis = 0,
10433 ulmu_data_dis = 0;
10434
10435 ifindex = if_nametoindex(intf);
10436 if (ifindex == 0) {
10437 sigma_dut_print(dut, DUT_MSG_ERROR,
10438 "%s: Index for interface %s failed",
10439 __func__, intf);
10440 return -1;
10441 }
10442 val = get_param(cmd, "OMCtrl_RxNSS");
10443 if (val)
10444 rx_nss = atoi(val);
10445
10446 val = get_param(cmd, "OMCtrl_ChnlWidth");
10447 if (val)
10448 ch_bw = atoi(val);
10449
10450 val = get_param(cmd, "OMCtrl_ULMUDisable");
10451 if (val)
10452 ulmu_dis = atoi(val);
10453
10454 val = get_param(cmd, "OMCtrl_TxNSTS");
10455 if (val)
10456 tx_nsts = atoi(val);
10457
10458 val = get_param(cmd, "OMCtrl_ULMUDataDisable");
10459 if (val)
10460 ulmu_data_dis = atoi(val);
10461
10462 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
10463 NL80211_CMD_VENDOR)) ||
10464 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
10465 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
10466 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
10467 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
10468 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
10469 !(params = nla_nest_start(
10470 msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OMI_TX)) ||
10471 !(attr1 = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
10472 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_RX_NSS, rx_nss) ||
10473 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_CH_BW, ch_bw) ||
10474 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_TX_NSTS, tx_nsts) ||
10475 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DATA_DISABLE,
10476 ulmu_data_dis) ||
10477 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DISABLE,
10478 ulmu_dis)) {
10479 sigma_dut_print(dut, DUT_MSG_ERROR,
10480 "%s: err in adding vendor_cmd and vendor_data",
10481 __func__);
10482 nlmsg_free(msg);
10483 return -1;
10484 }
10485 nla_nest_end(msg, attr1);
10486 nla_nest_end(msg, params);
10487 nla_nest_end(msg, attr);
10488
10489 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
10490 if (ret) {
10491 sigma_dut_print(dut, DUT_MSG_ERROR,
10492 "%s: err in send_and_recv_msgs, ret=%d",
10493 __func__, ret);
10494 }
10495
10496 return ret;
10497#else /* NL80211_SUPPORT */
10498 sigma_dut_print(dut, DUT_MSG_ERROR,
10499 "OMI TX cannot be processed without NL80211_SUPPORT defined");
10500 return -1;
10501#endif /* NL80211_SUPPORT */
10502}
10503
10504
Jouni Malinen224e3902021-06-09 16:41:27 +030010505static enum sigma_cmd_result
10506cmd_sta_set_wireless_vht(struct sigma_dut *dut, struct sigma_conn *conn,
10507 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010508{
10509 const char *intf = get_param(cmd, "Interface");
10510 const char *val;
Arif Hussaina37e9552018-06-20 17:05:59 -070010511 const char *program;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010512 int tkip = -1;
10513 int wep = -1;
Mohammad Asaad Akram50848402020-05-28 14:10:24 +053010514 int iwpriv_status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010515
Arif Hussaina37e9552018-06-20 17:05:59 -070010516 program = get_param(cmd, "Program");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010517 val = get_param(cmd, "SGI80");
10518 if (val) {
10519 int sgi80;
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080010520 enum nl80211_txrate_gi gi_val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010521
10522 sgi80 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080010523 if (sgi80)
10524 gi_val = NL80211_TXRATE_FORCE_LGI;
10525 else
10526 gi_val = NL80211_TXRATE_FORCE_SGI;
10527 if (sta_set_vht_gi(dut, intf, (u8) gi_val)) {
10528 sigma_dut_print(dut, DUT_MSG_INFO,
10529 "sta_set_vht_gi failed, using iwpriv");
10530 run_iwpriv(dut, intf, "shortgi %d", sgi80);
10531 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010532 }
10533
10534 val = get_param(cmd, "TxBF");
10535 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010536 switch (get_driver_type(dut)) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010537 case DRIVER_WCN:
10538 if (sta_set_tx_beamformee(dut, intf, 1)) {
10539 send_resp(dut, conn, SIGMA_ERROR,
10540 "ErrorCode,Failed to set TX beamformee enable");
Jouni Malinen224e3902021-06-09 16:41:27 +030010541 return STATUS_SENT_ERROR;
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010542 }
10543 break;
10544 case DRIVER_ATHEROS:
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010545 if (run_iwpriv(dut, intf, "vhtsubfee 1") < 0) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010546 send_resp(dut, conn, SIGMA_ERROR,
10547 "ErrorCode,Setting vhtsubfee failed");
Jouni Malinen224e3902021-06-09 16:41:27 +030010548 return STATUS_SENT_ERROR;
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010549 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010550 if (run_iwpriv(dut, intf, "vhtsubfer 1") < 0) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010551 send_resp(dut, conn, SIGMA_ERROR,
10552 "ErrorCode,Setting vhtsubfer failed");
Jouni Malinen224e3902021-06-09 16:41:27 +030010553 return STATUS_SENT_ERROR;
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010554 }
10555 break;
10556 default:
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010557 sigma_dut_print(dut, DUT_MSG_ERROR,
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010558 "Unsupported driver type");
10559 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010560 }
10561 }
10562
10563 val = get_param(cmd, "MU_TxBF");
10564 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010565 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010566 case DRIVER_ATHEROS:
10567 ath_sta_set_txsp_stream(dut, intf, "1SS");
10568 ath_sta_set_rxsp_stream(dut, intf, "1SS");
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010569 run_iwpriv(dut, intf, "vhtmubfee 1");
10570 run_iwpriv(dut, intf, "vhtmubfer 1");
Sunil Duttae9e5d12018-06-29 11:50:47 +053010571 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010572 case DRIVER_WCN:
10573 if (wcn_sta_set_sp_stream(dut, intf, "1SS") < 0) {
10574 send_resp(dut, conn, SIGMA_ERROR,
10575 "ErrorCode,Failed to set RX/TXSP_STREAM");
Jouni Malinen224e3902021-06-09 16:41:27 +030010576 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010577 }
Sunil Duttae9e5d12018-06-29 11:50:47 +053010578 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010579 default:
10580 sigma_dut_print(dut, DUT_MSG_ERROR,
10581 "Setting SP_STREAM not supported");
10582 break;
10583 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010584 }
10585
10586 val = get_param(cmd, "LDPC");
10587 if (val) {
10588 int ldpc;
10589
10590 ldpc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
Mohammad Asaad Akram50848402020-05-28 14:10:24 +053010591 iwpriv_status = run_iwpriv(dut, intf, "ldpc %d", ldpc);
10592 if (iwpriv_status)
10593 sta_config_params(dut, intf, STA_SET_LDPC, ldpc);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010594 }
10595
Amarnath Hullur Subramanyam7bae60e2018-01-31 03:46:50 -080010596 val = get_param(cmd, "BCC");
10597 if (val) {
10598 int bcc;
10599
10600 bcc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
10601 /* use LDPC iwpriv itself to set bcc coding, bcc coding
10602 * is mutually exclusive to bcc */
Mohammad Asaad Akram50848402020-05-28 14:10:24 +053010603 iwpriv_status = run_iwpriv(dut, intf, "ldpc %d", !bcc);
10604 if (iwpriv_status)
10605 sta_config_params(dut, intf, STA_SET_LDPC, !bcc);
Amarnath Hullur Subramanyam7bae60e2018-01-31 03:46:50 -080010606 }
10607
Arif Hussain7b47d2d2018-05-09 10:44:02 -070010608 val = get_param(cmd, "MaxHE-MCS_1SS_RxMapLTE80");
10609 if (val && dut->sta_nss == 1)
10610 cmd_set_max_he_mcs(dut, intf, atoi(val));
10611
10612 val = get_param(cmd, "MaxHE-MCS_2SS_RxMapLTE80");
10613 if (val && dut->sta_nss == 2)
10614 cmd_set_max_he_mcs(dut, intf, atoi(val));
10615
Arif Hussainac6c5112018-05-25 17:34:00 -070010616 val = get_param(cmd, "MCS_FixedRate");
10617 if (val) {
10618#ifdef NL80211_SUPPORT
10619 int mcs, ratecode = 0;
10620 enum he_mcs_config mcs_config;
10621 int ret;
Jouni Malinenb9b671d2019-04-26 13:23:17 +030010622 char buf[60];
Arif Hussainac6c5112018-05-25 17:34:00 -070010623
10624 ratecode = (0x07 & dut->sta_nss) << 5;
10625 mcs = atoi(val);
10626 /* Add the MCS to the ratecode */
10627 if (mcs >= 0 && mcs <= 11) {
10628 ratecode += mcs;
10629 if (dut->device_type == STA_testbed &&
10630 mcs > 7 && mcs <= 11) {
10631 if (mcs <= 9)
10632 mcs_config = HE_80_MCS0_9;
10633 else
10634 mcs_config = HE_80_MCS0_11;
10635 ret = sta_set_he_mcs(dut, intf, mcs_config);
10636 if (ret) {
10637 sigma_dut_print(dut, DUT_MSG_ERROR,
10638 "MCS_FixedRate: mcs setting failed, mcs:%d, mcs_config %d, ret:%d",
10639 mcs, mcs_config, ret);
10640 }
10641 }
10642 snprintf(buf, sizeof(buf),
10643 "iwpriv %s set_11ax_rate 0x%03x",
10644 intf, ratecode);
10645 if (system(buf) != 0) {
10646 sigma_dut_print(dut, DUT_MSG_ERROR,
10647 "MCS_FixedRate: iwpriv setting of 11ax rates 0x%03x failed",
10648 ratecode);
10649 }
10650 } else {
10651 sigma_dut_print(dut, DUT_MSG_ERROR,
10652 "MCS_FixedRate: HE MCS %d not supported",
10653 mcs);
10654 }
10655#else /* NL80211_SUPPORT */
10656 sigma_dut_print(dut, DUT_MSG_ERROR,
10657 "MCS_FixedRate cannot be changed without NL80211_SUPPORT defined");
10658#endif /* NL80211_SUPPORT */
10659 }
10660
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010661 val = get_param(cmd, "opt_md_notif_ie");
10662 if (val) {
10663 char *result = NULL;
10664 char delim[] = ";";
10665 char token[30];
10666 int value, config_val = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010667 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010668
Peng Xub8fc5cc2017-05-10 17:27:28 -070010669 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010670 result = strtok_r(token, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010671
10672 /* Extract the NSS information */
10673 if (result) {
10674 value = atoi(result);
10675 switch (value) {
10676 case 1:
10677 config_val = 1;
10678 break;
10679 case 2:
10680 config_val = 3;
10681 break;
10682 case 3:
10683 config_val = 7;
10684 break;
10685 case 4:
10686 config_val = 15;
10687 break;
10688 default:
10689 config_val = 3;
10690 break;
10691 }
10692
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010693 run_iwpriv(dut, intf, "rxchainmask %d", config_val);
10694 run_iwpriv(dut, intf, "txchainmask %d", config_val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010695
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010696 }
10697
10698 /* Extract the channel width information */
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010699 result = strtok_r(NULL, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010700 if (result) {
10701 value = atoi(result);
10702 switch (value) {
10703 case 20:
10704 config_val = 0;
10705 break;
10706 case 40:
10707 config_val = 1;
10708 break;
10709 case 80:
10710 config_val = 2;
10711 break;
10712 case 160:
10713 config_val = 3;
10714 break;
10715 default:
10716 config_val = 2;
10717 break;
10718 }
10719
10720 dut->chwidth = config_val;
10721
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010722 run_iwpriv(dut, intf, "chwidth %d", config_val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010723 }
10724
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010725 run_iwpriv(dut, intf, "opmode_notify 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010726 }
10727
10728 val = get_param(cmd, "nss_mcs_cap");
10729 if (val) {
10730 int nss, mcs;
10731 char token[20];
10732 char *result = NULL;
10733 unsigned int vht_mcsmap = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010734 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010735
Peng Xub8fc5cc2017-05-10 17:27:28 -070010736 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010737 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +053010738 if (!result) {
10739 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -070010740 "NSS not specified");
10741 send_resp(dut, conn, SIGMA_ERROR,
10742 "errorCode,NSS not specified");
Jouni Malinen224e3902021-06-09 16:41:27 +030010743 return STATUS_SENT_ERROR;
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +053010744 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010745 nss = atoi(result);
10746
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010747 run_iwpriv(dut, intf, "nss %d", nss);
Arif Hussainac6c5112018-05-25 17:34:00 -070010748 dut->sta_nss = nss;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010749
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010750 result = strtok_r(NULL, ";", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010751 if (result == NULL) {
10752 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -070010753 "MCS not specified");
10754 send_resp(dut, conn, SIGMA_ERROR,
10755 "errorCode,MCS not specified");
Jouni Malinen224e3902021-06-09 16:41:27 +030010756 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010757 }
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010758 result = strtok_r(result, "-", &saveptr);
10759 result = strtok_r(NULL, "-", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +053010760 if (!result) {
10761 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -070010762 "MCS not specified");
10763 send_resp(dut, conn, SIGMA_ERROR,
10764 "errorCode,MCS not specified");
Jouni Malinen224e3902021-06-09 16:41:27 +030010765 return STATUS_SENT_ERROR;
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +053010766 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010767 mcs = atoi(result);
10768
Arif Hussaina37e9552018-06-20 17:05:59 -070010769 if (program && strcasecmp(program, "HE") == 0) {
10770#ifdef NL80211_SUPPORT
10771 enum he_mcs_config mcs_config;
10772 int ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010773
Arif Hussaina37e9552018-06-20 17:05:59 -070010774 if (mcs >= 0 && mcs <= 7) {
10775 mcs_config = HE_80_MCS0_7;
10776 } else if (mcs > 7 && mcs <= 9) {
10777 mcs_config = HE_80_MCS0_9;
10778 } else if (mcs > 9 && mcs <= 11) {
10779 mcs_config = HE_80_MCS0_11;
10780 } else {
10781 sigma_dut_print(dut, DUT_MSG_ERROR,
10782 "nss_mcs_cap: HE: Invalid mcs: %d",
10783 mcs);
10784 send_resp(dut, conn, SIGMA_ERROR,
10785 "errorCode,Invalid MCS");
Jouni Malinen224e3902021-06-09 16:41:27 +030010786 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010787 }
Arif Hussaina37e9552018-06-20 17:05:59 -070010788
10789 ret = sta_set_he_mcs(dut, intf, mcs_config);
10790 if (ret) {
10791 sigma_dut_print(dut, DUT_MSG_ERROR,
10792 "nss_mcs_cap: HE: Setting of MCS failed, mcs_config: %d, ret: %d",
10793 mcs_config, ret);
10794 send_resp(dut, conn, SIGMA_ERROR,
10795 "errorCode,Failed to set MCS");
Jouni Malinen224e3902021-06-09 16:41:27 +030010796 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010797 }
Arif Hussaina37e9552018-06-20 17:05:59 -070010798#else /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010799 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -070010800 "nss_mcs_cap: HE: MCS cannot be changed without NL80211_SUPPORT defined");
10801#endif /* NL80211_SUPPORT */
10802 } else {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010803 run_iwpriv(dut, intf, "vhtmcs %d", mcs);
Arif Hussaina37e9552018-06-20 17:05:59 -070010804
10805 switch (nss) {
10806 case 1:
10807 switch (mcs) {
10808 case 7:
10809 vht_mcsmap = 0xfffc;
10810 break;
10811 case 8:
10812 vht_mcsmap = 0xfffd;
10813 break;
10814 case 9:
10815 vht_mcsmap = 0xfffe;
10816 break;
10817 default:
10818 vht_mcsmap = 0xfffe;
10819 break;
10820 }
10821 break;
10822 case 2:
10823 switch (mcs) {
10824 case 7:
10825 vht_mcsmap = 0xfff0;
10826 break;
10827 case 8:
10828 vht_mcsmap = 0xfff5;
10829 break;
10830 case 9:
10831 vht_mcsmap = 0xfffa;
10832 break;
10833 default:
10834 vht_mcsmap = 0xfffa;
10835 break;
10836 }
10837 break;
10838 case 3:
10839 switch (mcs) {
10840 case 7:
10841 vht_mcsmap = 0xffc0;
10842 break;
10843 case 8:
10844 vht_mcsmap = 0xffd5;
10845 break;
10846 case 9:
10847 vht_mcsmap = 0xffea;
10848 break;
10849 default:
10850 vht_mcsmap = 0xffea;
10851 break;
10852 }
10853 break;
10854 default:
10855 vht_mcsmap = 0xffea;
10856 break;
10857 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010858 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010859 }
10860 }
10861
10862 /* UNSUPPORTED: val = get_param(cmd, "Tx_lgi_rate"); */
10863
10864 val = get_param(cmd, "Vht_tkip");
10865 if (val)
10866 tkip = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
10867
10868 val = get_param(cmd, "Vht_wep");
10869 if (val)
10870 wep = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
10871
10872 if (tkip != -1 || wep != -1) {
10873 if ((tkip == 1 && wep != 0) || (wep == 1 && tkip != 0)) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010874 run_iwpriv(dut, intf, "htweptkip 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010875 } else if ((tkip == 0 && wep != 1) || (wep == 0 && tkip != 1)) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010876 run_iwpriv(dut, intf, "htweptkip 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010877 } else {
Jouni Malinen224e3902021-06-09 16:41:27 +030010878 send_resp(dut, conn, SIGMA_ERROR,
10879 "ErrorCode,mixed mode of VHT TKIP/WEP not supported");
10880 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010881 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010882 }
10883
Kiran Kumar Lokere09dbcef2021-08-09 00:01:41 -070010884 val = get_param(cmd, "TWTSchedSTASupport");
10885 if (val) {
10886 int set_val;
10887
10888 switch (get_driver_type(dut)) {
10889 case DRIVER_WCN:
10890 if (strcasecmp(val, "Enable") == 0) {
10891 set_val = 1;
10892 } else if (strcasecmp(val, "Disable") == 0) {
10893 set_val = 0;
10894 } else {
10895 send_resp(dut, conn, SIGMA_ERROR,
10896 "ErrorCode,Invalid TWTSchedSTASupport");
10897 return STATUS_SENT_ERROR;
10898 }
10899
10900 if (sta_set_bcast_twt_support(dut, intf, set_val)) {
10901 send_resp(dut, conn, SIGMA_ERROR,
10902 "ErrorCode,Failed to set TWTSchedSTASupport");
10903 return STATUS_SENT_ERROR;
10904 }
10905 break;
10906 default:
10907 sigma_dut_print(dut, DUT_MSG_ERROR,
10908 "Setting TWTSchedSTASupport not supported");
10909 break;
10910 }
10911 }
10912
10913 val = get_param(cmd, "MBSSID_RxCtrl");
10914 if (val) {
10915 int set_val;
10916
10917 switch (get_driver_type(dut)) {
10918 case DRIVER_WCN:
10919 if (strcasecmp(val, "Enable") == 0) {
10920 set_val = 1;
10921 } else if (strcasecmp(val, "Disable") == 0) {
10922 set_val = 0;
10923 } else {
10924 send_resp(dut, conn, SIGMA_ERROR,
10925 "ErrorCode,Invalid MBSSID_RxCtrl");
10926 return STATUS_SENT_ERROR;
10927 }
10928
10929 if (sta_set_rx_ctrl_multi_bss(dut, intf, set_val)) {
10930 send_resp(dut, conn, SIGMA_ERROR,
10931 "ErrorCode,Failed to set MBSSID_RxCtrl");
10932 return STATUS_SENT_ERROR;
10933 }
10934 break;
10935 default:
10936 sigma_dut_print(dut, DUT_MSG_ERROR,
10937 "Setting MBSSID_RxCtrl not supported");
10938 break;
10939 }
10940 }
10941
Arif Hussain55f00da2018-07-03 08:28:26 -070010942 val = get_param(cmd, "txBandwidth");
10943 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010944 switch (get_driver_type(dut)) {
Arif Hussain55f00da2018-07-03 08:28:26 -070010945 case DRIVER_WCN:
10946 if (wcn_sta_set_width(dut, intf, val) < 0) {
10947 send_resp(dut, conn, SIGMA_ERROR,
10948 "ErrorCode,Failed to set txBandwidth");
Jouni Malinen224e3902021-06-09 16:41:27 +030010949 return STATUS_SENT_ERROR;
Arif Hussain55f00da2018-07-03 08:28:26 -070010950 }
10951 break;
10952 case DRIVER_ATHEROS:
10953 if (ath_set_width(dut, conn, intf, val) < 0) {
10954 send_resp(dut, conn, SIGMA_ERROR,
10955 "ErrorCode,Failed to set txBandwidth");
Jouni Malinen224e3902021-06-09 16:41:27 +030010956 return STATUS_SENT_ERROR;
Arif Hussain55f00da2018-07-03 08:28:26 -070010957 }
10958 break;
10959 default:
10960 sigma_dut_print(dut, DUT_MSG_ERROR,
10961 "Setting txBandwidth not supported");
10962 break;
10963 }
10964 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010965
Arif Hussain9765f7d2018-07-03 08:28:26 -070010966 val = get_param(cmd, "BeamformeeSTS");
10967 if (val) {
Kiran Kumar Lokerebc89d432018-07-10 12:20:13 -070010968 if (sta_set_tx_beamformee(dut, intf, 1)) {
10969 send_resp(dut, conn, SIGMA_ERROR,
10970 "ErrorCode,Failed to set TX beamformee enable");
Jouni Malinen224e3902021-06-09 16:41:27 +030010971 return STATUS_SENT_ERROR;
Kiran Kumar Lokerebc89d432018-07-10 12:20:13 -070010972 }
10973
Arif Hussain9765f7d2018-07-03 08:28:26 -070010974 if (sta_set_beamformee_sts(dut, intf, atoi(val))) {
10975 send_resp(dut, conn, SIGMA_ERROR,
10976 "ErrorCode,Failed to set BeamformeeSTS");
Jouni Malinen224e3902021-06-09 16:41:27 +030010977 return STATUS_SENT_ERROR;
Arif Hussain9765f7d2018-07-03 08:28:26 -070010978 }
10979 }
10980
Arif Hussain68d23f52018-07-11 13:39:08 -070010981 val = get_param(cmd, "Trig_MAC_Padding_Dur");
10982 if (val) {
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -070010983#ifdef NL80211_SUPPORT
10984 enum qca_wlan_he_mac_padding_dur set_val;
10985
10986 switch (atoi(val)) {
10987 case 16:
10988 set_val = QCA_WLAN_HE_16US_OF_PROCESS_TIME;
10989 break;
10990 case 8:
10991 set_val = QCA_WLAN_HE_8US_OF_PROCESS_TIME;
10992 break;
10993 default:
10994 set_val = QCA_WLAN_HE_NO_ADDITIONAL_PROCESS_TIME;
10995 break;
10996 }
10997 if (sta_set_mac_padding_duration(dut, intf, set_val)) {
Arif Hussain68d23f52018-07-11 13:39:08 -070010998 send_resp(dut, conn, SIGMA_ERROR,
10999 "ErrorCode,Failed to set MAC padding duration");
Jouni Malinen224e3902021-06-09 16:41:27 +030011000 return STATUS_SENT_ERROR;
Arif Hussain68d23f52018-07-11 13:39:08 -070011001 }
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -070011002#else /* NL80211_SUPPORT */
11003 sigma_dut_print(dut, DUT_MSG_ERROR,
11004 "MAC padding duration cannot be changed without NL80211_SUPPORT defined");
11005#endif /* NL80211_SUPPORT */
Arif Hussain68d23f52018-07-11 13:39:08 -070011006 }
11007
Arif Hussain480d5f42019-03-12 14:40:42 -070011008 val = get_param(cmd, "TWT_ReqSupport");
11009 if (val) {
11010 int set_val;
11011
11012 if (strcasecmp(val, "Enable") == 0) {
11013 set_val = 1;
11014 } else if (strcasecmp(val, "Disable") == 0) {
11015 set_val = 0;
11016 } else {
11017 send_resp(dut, conn, SIGMA_ERROR,
11018 "ErrorCode,Invalid TWT_ReqSupport");
Jouni Malinen224e3902021-06-09 16:41:27 +030011019 return STATUS_SENT_ERROR;
Arif Hussain480d5f42019-03-12 14:40:42 -070011020 }
11021
11022 if (sta_set_twt_req_support(dut, intf, set_val)) {
11023 sigma_dut_print(dut, DUT_MSG_ERROR,
11024 "Failed to set TWT req support %d",
11025 set_val);
11026 send_resp(dut, conn, SIGMA_ERROR,
11027 "ErrorCode,Failed to set TWT_ReqSupport");
Jouni Malinen224e3902021-06-09 16:41:27 +030011028 return STATUS_SENT_ERROR;
Arif Hussain480d5f42019-03-12 14:40:42 -070011029 }
11030 }
11031
Kiran Kumar Lokered0ec5ed2021-04-01 00:15:04 -070011032 val = get_param(cmd, "PreamblePunctRx");
11033 if (val && get_driver_type(dut) == DRIVER_WCN) {
11034 int set_val;
11035
11036 if (strcasecmp(val, "Enable") == 0) {
11037 set_val = 1;
11038 } else if (strcasecmp(val, "Disable") == 0) {
11039 set_val = 0;
11040 } else {
11041 send_resp(dut, conn, SIGMA_ERROR,
11042 "ErrorCode,Invalid PreamblePunctRx");
11043 return STATUS_SENT_ERROR;
11044 }
11045
11046 if (sta_set_punctured_preamble_rx(dut, intf, set_val)) {
11047 sigma_dut_print(dut, DUT_MSG_ERROR,
11048 "Failed to set PreamblePunctRx support %d",
11049 set_val);
11050 send_resp(dut, conn, SIGMA_ERROR,
11051 "ErrorCode,Failed to set PreamblePunctRx");
11052 return STATUS_SENT_ERROR;
11053 }
11054 }
11055
Srinivas Girigowda0525e292020-11-12 13:28:21 -080011056 val = get_param(cmd, "FullBW_ULMUMIMO");
11057 if (val) {
11058 int set_val;
11059
11060 if (strcasecmp(val, "Enable") == 0) {
11061 set_val = 1;
11062 } else if (strcasecmp(val, "Disable") == 0) {
11063 set_val = 0;
11064 } else {
11065 send_resp(dut, conn, SIGMA_ERROR,
11066 "ErrorCode,Invalid FullBW_ULMUMIMO");
11067 return STATUS_SENT_ERROR;
11068 }
11069
11070 if (sta_set_fullbw_ulmumimo(dut, intf, set_val)) {
11071 sigma_dut_print(dut, DUT_MSG_ERROR,
11072 "Failed to set FullBW_ULMUMIMO %d",
11073 set_val);
11074 send_resp(dut, conn, SIGMA_ERROR,
11075 "ErrorCode,Failed to set FullBW_ULMUMIMO");
11076 return STATUS_SENT_ERROR;
11077 }
11078 }
11079
Srinivas Girigowda6707f032020-10-26 15:24:46 -070011080 val = get_param(cmd, "TWTInfoFrameTx");
11081 if (val) {
11082 if (strcasecmp(val, "Enable") == 0) {
11083 /* No-op */
11084 } else if (strcasecmp(val, "Disable") == 0) {
11085 /* No-op */
11086 } else {
11087 send_resp(dut, conn, SIGMA_ERROR,
11088 "ErrorCode,Invalid TWTInfoFrameTx");
11089 return STATUS_SENT_ERROR;
11090 }
11091 }
11092
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -070011093 val = get_param(cmd, "MU_EDCA");
11094 if (val && (strcasecmp(val, "Override") == 0)) {
11095 if (sta_set_mu_edca_override(dut, intf, 1)) {
11096 send_resp(dut, conn, SIGMA_ERROR,
11097 "ErrorCode,Failed to set MU EDCA override");
Jouni Malinen224e3902021-06-09 16:41:27 +030011098 return STATUS_SENT_ERROR;
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -070011099 }
11100 }
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -070011101
Kiran Kumar Lokerefa7c7b92021-08-09 00:50:55 -070011102 val = get_param(cmd, "PPDUTxType");
11103 if (val && strcasecmp(val, "ER-SU") == 0) {
11104 if (sta_set_er_su_ppdu_type_tx(dut, intf, 1)) {
11105 send_resp(dut, conn, SIGMA_ERROR,
11106 "ErrorCode,Failed to set ER-SU PPDU type Tx");
11107 return STATUS_SENT_ERROR;
11108 }
11109 }
11110
11111 val = get_param(cmd, "RUAllocTone");
11112 if (val && strcasecmp(val, "242") == 0) {
11113 if (sta_set_ru_242_tone_tx(dut, intf, 1)) {
11114 send_resp(dut, conn, SIGMA_ERROR,
11115 "ErrorCode,Failed to set RU 242 tone Tx");
11116 return STATUS_SENT_ERROR;
11117 }
11118 }
11119
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -070011120 val = get_param(cmd, "OMControl");
11121 if (val) {
11122 int set_val = 1;
11123
11124 if (strcasecmp(val, "Enable") == 0)
11125 set_val = 1;
11126 else if (strcasecmp(val, "Disable") == 0)
11127 set_val = 0;
11128
11129 if (sta_set_om_ctrl_supp(dut, intf, set_val)) {
11130 send_resp(dut, conn, SIGMA_ERROR,
11131 "ErrorCode,Failed to set OM ctrl supp");
Jouni Malinen224e3902021-06-09 16:41:27 +030011132 return STATUS_SENT_ERROR;
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -070011133 }
11134 }
11135
Kiran Kumar Lokere4f2d4b02021-04-01 00:07:39 -070011136 val = get_param(cmd, "BSSMaxIdlePeriod");
11137 if (val && sta_set_bss_max_idle_period(dut, intf, atoi(val))) {
11138 send_resp(dut, conn, SIGMA_ERROR,
11139 "ErrorCode,Failed to set BSS max idle period");
11140 return STATUS_SENT_ERROR;
11141 }
11142
Kiran Kumar Lokere07ad92b2021-08-09 00:27:14 -070011143 val = get_param(cmd, "BSS_max_idle");
11144 if (val) {
11145 int set_val = 0;
11146
11147 if (strcasecmp(val, "Enable") == 0)
11148 set_val = 1;
11149 else if (strcasecmp(val, "Disable") == 0)
11150 set_val = 0;
11151 if (sta_set_bss_max_idle_support(dut, intf, set_val)) {
11152 send_resp(dut, conn, SIGMA_ERROR,
11153 "ErrorCode,Failed to set BSS max idle support");
11154 return STATUS_SENT_ERROR;
11155 }
11156 }
11157
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -070011158 val = get_param(cmd, "ADDBAResp_BufSize");
11159 if (val) {
11160 int buf_size;
11161
11162 if (strcasecmp(val, "gt64") == 0)
11163 buf_size = 256;
11164 else
11165 buf_size = 64;
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011166 if (get_driver_type(dut) == DRIVER_WCN &&
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -070011167 sta_set_addba_buf_size(dut, intf, buf_size)) {
11168 send_resp(dut, conn, SIGMA_ERROR,
11169 "ErrorCode,set addbaresp_buff_size failed");
Jouni Malinen224e3902021-06-09 16:41:27 +030011170 return STATUS_SENT_ERROR;
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -070011171 }
11172 }
11173
11174 val = get_param(cmd, "ADDBAReq_BufSize");
11175 if (val) {
11176 int buf_size;
11177
11178 if (strcasecmp(val, "gt64") == 0)
11179 buf_size = 256;
11180 else
11181 buf_size = 64;
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011182 if (get_driver_type(dut) == DRIVER_WCN &&
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -070011183 sta_set_addba_buf_size(dut, intf, buf_size)) {
11184 send_resp(dut, conn, SIGMA_ERROR,
11185 "ErrorCode,set addbareq_buff_size failed");
Jouni Malinen224e3902021-06-09 16:41:27 +030011186 return STATUS_SENT_ERROR;
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -070011187 }
11188 }
11189
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011190 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
11191}
11192
11193
11194static int sta_set_wireless_60g(struct sigma_dut *dut,
11195 struct sigma_conn *conn,
11196 struct sigma_cmd *cmd)
11197{
11198 const char *dev_role = get_param(cmd, "DevRole");
11199
11200 if (!dev_role) {
11201 send_resp(dut, conn, SIGMA_INVALID,
11202 "ErrorCode,DevRole not specified");
11203 return 0;
11204 }
11205
11206 if (strcasecmp(dev_role, "PCP") == 0)
11207 return sta_set_60g_pcp(dut, conn, cmd);
11208 if (strcasecmp(dev_role, "STA") == 0)
11209 return sta_set_60g_sta(dut, conn, cmd);
11210 send_resp(dut, conn, SIGMA_INVALID,
11211 "ErrorCode,DevRole not supported");
11212 return 0;
11213}
11214
11215
Ankita Bajaj0d5825b2017-10-25 16:20:17 +053011216static int sta_set_wireless_oce(struct sigma_dut *dut, struct sigma_conn *conn,
11217 struct sigma_cmd *cmd)
11218{
11219 int status;
11220 const char *intf = get_param(cmd, "Interface");
11221 const char *val = get_param(cmd, "DevRole");
11222
11223 if (val && strcasecmp(val, "STA-CFON") == 0) {
11224 status = sta_cfon_set_wireless(dut, conn, cmd);
11225 if (status)
11226 return status;
11227 }
11228 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
11229}
11230
11231
Jouni Malinen67433fc2020-06-26 22:50:33 +030011232static enum sigma_cmd_result
11233sta_set_wireless_wpa3(struct sigma_dut *dut, struct sigma_conn *conn,
11234 struct sigma_cmd *cmd)
Vamsi Krishnac1633d22020-05-06 18:31:21 +053011235{
11236 const char *intf = get_param(cmd, "Interface");
11237 const char *val;
11238
11239 val = get_param(cmd, "ocvc");
11240 if (val)
11241 dut->ocvc = atoi(val);
11242
Jouni Malinen67433fc2020-06-26 22:50:33 +030011243 val = get_param(cmd, "ClientPrivacy");
Veerendranath Jakkam47867202020-12-21 01:53:52 +053011244 if (val && dut->client_privacy != atoi(val) &&
11245 sta_set_client_privacy(dut, conn, intf, atoi(val))) {
11246 send_resp(dut, conn, SIGMA_ERROR,
11247 "errorCode,Failed to configure random MAC address use");
11248 return STATUS_SENT_ERROR;
Jouni Malinen67433fc2020-06-26 22:50:33 +030011249 }
11250
Veerendranath Jakkam9ce2b642022-02-28 18:49:25 +053011251 val = get_param(cmd, "GKH_G2_Tx");
11252 if (val) {
11253 char buf[50];
11254
11255 snprintf(buf, sizeof(buf), "SET disable_eapol_g2_tx %d",
11256 strcasecmp(val, "disable") == 0);
11257
11258 if (wpa_command(intf, buf) < 0) {
11259 send_resp(dut, conn, SIGMA_ERROR,
11260 "errorCode,Failed to enable/disable G2 transmit");
11261 return STATUS_SENT_ERROR;
11262 }
11263 }
11264
Vamsi Krishnac1633d22020-05-06 18:31:21 +053011265 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
11266}
11267
11268
Jouni Malinenf7222712019-06-13 01:50:21 +030011269static enum sigma_cmd_result cmd_sta_set_wireless(struct sigma_dut *dut,
11270 struct sigma_conn *conn,
11271 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011272{
11273 const char *val;
11274
11275 val = get_param(cmd, "Program");
Veerendranath Jakkam9ce2b642022-02-28 18:49:25 +053011276 if (!val)
11277 val = get_param(cmd, "Prog");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011278 if (val) {
11279 if (strcasecmp(val, "11n") == 0)
11280 return cmd_sta_set_11n(dut, conn, cmd);
Amarnath Hullur Subramanyam4f860292018-01-31 03:49:35 -080011281 if (strcasecmp(val, "VHT") == 0 || strcasecmp(val, "HE") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011282 return cmd_sta_set_wireless_vht(dut, conn, cmd);
11283 if (strcasecmp(val, "60ghz") == 0)
11284 return sta_set_wireless_60g(dut, conn, cmd);
Ankita Bajaj0d5825b2017-10-25 16:20:17 +053011285 if (strcasecmp(val, "OCE") == 0)
11286 return sta_set_wireless_oce(dut, conn, cmd);
Alexei Avshalom Lazar66bb9972018-12-18 16:01:43 +020011287 /* sta_set_wireless in WPS program is only used for 60G */
11288 if (is_60g_sigma_dut(dut))
11289 return sta_set_wireless_60g(dut, conn, cmd);
Vamsi Krishnac1633d22020-05-06 18:31:21 +053011290 if (strcasecmp(val, "WPA3") == 0)
11291 return sta_set_wireless_wpa3(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011292 send_resp(dut, conn, SIGMA_ERROR,
11293 "ErrorCode,Program value not supported");
11294 } else {
11295 send_resp(dut, conn, SIGMA_ERROR,
11296 "ErrorCode,Program argument not available");
11297 }
11298
11299 return 0;
11300}
11301
11302
11303static void ath_sta_inject_frame(struct sigma_dut *dut, const char *intf,
11304 int tid)
11305{
11306 char buf[100];
11307 int tid_to_dscp [] = { 0x00, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0 };
11308
Pradeep Reddy POTTETId31d1322016-10-13 17:22:03 +053011309 if (tid < 0 ||
11310 tid >= (int) (sizeof(tid_to_dscp) / sizeof(tid_to_dscp[0]))) {
11311 sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported TID: %d", tid);
11312 return;
11313 }
11314
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011315 /*
11316 * Two ways to ensure that addba request with a
11317 * non zero TID could be sent out. EV 117296
11318 */
11319 snprintf(buf, sizeof(buf),
11320 "ping -c 8 -Q %d `arp -a | grep wlan0 | awk '{print $2}' | tr -d '()'`",
11321 tid);
11322 if (system(buf) != 0) {
11323 sigma_dut_print(dut, DUT_MSG_ERROR,
11324 "Ping did not send out");
11325 }
11326
11327 snprintf(buf, sizeof(buf),
11328 "iwconfig %s | grep Access | awk '{print $6}' > %s",
11329 intf, VI_QOS_TMP_FILE);
11330 if (system(buf) != 0)
11331 return;
11332
11333 snprintf(buf, sizeof(buf),
11334 "ifconfig %s | grep HWaddr | cut -b 39-56 >> %s",
11335 intf, VI_QOS_TMP_FILE);
11336 if (system(buf) != 0)
11337 sigma_dut_print(dut, DUT_MSG_ERROR, "HWaddr matching failed");
11338
11339 snprintf(buf,sizeof(buf), "sed -n '3,$p' %s >> %s",
11340 VI_QOS_REFFILE, VI_QOS_TMP_FILE);
11341 if (system(buf) != 0) {
11342 sigma_dut_print(dut, DUT_MSG_ERROR,
11343 "VI_QOS_TEMP_FILE generation error failed");
11344 }
11345 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
11346 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
11347 if (system(buf) != 0) {
11348 sigma_dut_print(dut, DUT_MSG_ERROR,
11349 "VI_QOS_FILE generation failed");
11350 }
11351
11352 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
11353 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
11354 if (system(buf) != 0) {
11355 sigma_dut_print(dut, DUT_MSG_ERROR,
11356 "VI_QOS_FILE generation failed");
11357 }
11358
11359 snprintf(buf, sizeof(buf), "ethinject %s %s", intf, VI_QOS_FILE);
11360 if (system(buf) != 0) {
11361 }
11362}
11363
11364
11365static int ath_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
11366 struct sigma_cmd *cmd)
11367{
11368 const char *intf = get_param(cmd, "Interface");
11369 const char *val;
11370 int tid = 0;
11371 char buf[100];
11372
11373 val = get_param(cmd, "TID");
11374 if (val) {
11375 tid = atoi(val);
11376 if (tid)
11377 ath_sta_inject_frame(dut, intf, tid);
11378 }
11379
11380 /* Command sequence for ADDBA request on Peregrine based devices */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011381 run_iwpriv(dut, intf, "setaddbaoper 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011382
11383 snprintf(buf, sizeof(buf), "wifitool %s senddelba 1 %d 1 4", intf, tid);
11384 if (system(buf) != 0) {
11385 sigma_dut_print(dut, DUT_MSG_ERROR,
11386 "wifitool senddelba failed");
11387 }
11388
11389 snprintf(buf, sizeof(buf), "wifitool %s sendaddba 1 %d 64", intf, tid);
11390 if (system(buf) != 0) {
11391 sigma_dut_print(dut, DUT_MSG_ERROR,
11392 "wifitool sendaddba failed");
11393 }
11394
11395 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
11396
11397 return 1;
11398}
11399
11400
Lior David9981b512017-01-20 13:16:40 +020011401#ifdef __linux__
11402
11403static int wil6210_send_addba(struct sigma_dut *dut, const char *dest_mac,
11404 int agg_size)
11405{
11406 char dir[128], buf[128];
11407 FILE *f;
11408 regex_t re;
11409 regmatch_t m[2];
Jouni Malinen3aa72862019-05-29 23:14:51 +030011410 int rc, ret = -1, vring_id, found, res;
Lior David9981b512017-01-20 13:16:40 +020011411
11412 if (wil6210_get_debugfs_dir(dut, dir, sizeof(dir))) {
11413 sigma_dut_print(dut, DUT_MSG_ERROR,
11414 "failed to get wil6210 debugfs dir");
11415 return -1;
11416 }
11417
Jouni Malinen3aa72862019-05-29 23:14:51 +030011418 res = snprintf(buf, sizeof(buf), "%s/vrings", dir);
11419 if (res < 0 || res >= sizeof(buf))
11420 return -1;
Lior David9981b512017-01-20 13:16:40 +020011421 f = fopen(buf, "r");
11422 if (!f) {
11423 sigma_dut_print(dut, DUT_MSG_ERROR, "failed to open: %s", buf);
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +020011424 /* newer wil6210 driver renamed file to "rings" */
Jouni Malinen3aa72862019-05-29 23:14:51 +030011425 res = snprintf(buf, sizeof(buf), "%s/rings", dir);
11426 if (res < 0 || res >= sizeof(buf))
11427 return -1;
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +020011428 f = fopen(buf, "r");
11429 if (!f) {
11430 sigma_dut_print(dut, DUT_MSG_ERROR,
11431 "failed to open: %s", buf);
11432 return -1;
11433 }
Lior David9981b512017-01-20 13:16:40 +020011434 }
11435
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +020011436 /* can be either VRING tx... or RING... */
11437 if (regcomp(&re, "RING tx_[ \t]*([0-9]+)", REG_EXTENDED)) {
Lior David9981b512017-01-20 13:16:40 +020011438 sigma_dut_print(dut, DUT_MSG_ERROR, "regcomp failed");
11439 goto out;
11440 }
11441
11442 /* find TX VRING for the mac address */
11443 found = 0;
11444 while (fgets(buf, sizeof(buf), f)) {
11445 if (strcasestr(buf, dest_mac)) {
11446 found = 1;
11447 break;
11448 }
11449 }
11450
11451 if (!found) {
11452 sigma_dut_print(dut, DUT_MSG_ERROR,
11453 "no TX VRING for %s", dest_mac);
11454 goto out;
11455 }
11456
11457 /* extract VRING ID, "VRING tx_<id> = {" */
11458 if (!fgets(buf, sizeof(buf), f)) {
11459 sigma_dut_print(dut, DUT_MSG_ERROR,
11460 "no VRING start line for %s", dest_mac);
11461 goto out;
11462 }
11463
11464 rc = regexec(&re, buf, 2, m, 0);
11465 regfree(&re);
11466 if (rc || m[1].rm_so < 0) {
11467 sigma_dut_print(dut, DUT_MSG_ERROR,
11468 "no VRING TX ID for %s", dest_mac);
11469 goto out;
11470 }
11471 buf[m[1].rm_eo] = 0;
11472 vring_id = atoi(&buf[m[1].rm_so]);
11473
11474 /* send the addba command */
11475 fclose(f);
Jouni Malinen3aa72862019-05-29 23:14:51 +030011476 res = snprintf(buf, sizeof(buf), "%s/back", dir);
11477 if (res < 0 || res >= sizeof(buf))
11478 return -1;
Lior David9981b512017-01-20 13:16:40 +020011479 f = fopen(buf, "w");
11480 if (!f) {
11481 sigma_dut_print(dut, DUT_MSG_ERROR,
11482 "failed to open: %s", buf);
11483 return -1;
11484 }
11485
11486 fprintf(f, "add %d %d\n", vring_id, agg_size);
11487
11488 ret = 0;
11489
11490out:
11491 fclose(f);
11492
11493 return ret;
11494}
11495
11496
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +020011497int send_addba_60g(struct sigma_dut *dut, struct sigma_conn *conn,
11498 struct sigma_cmd *cmd, const char *mac_param)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011499{
11500 const char *val;
11501 int tid = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011502
11503 val = get_param(cmd, "TID");
11504 if (val) {
11505 tid = atoi(val);
11506 if (tid != 0) {
11507 sigma_dut_print(dut, DUT_MSG_ERROR,
11508 "Ignore TID %d for send_addba use TID 0 for 60g since only 0 required on TX",
11509 tid);
11510 }
11511 }
11512
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +020011513 val = get_param(cmd, mac_param);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011514 if (!val) {
11515 sigma_dut_print(dut, DUT_MSG_ERROR,
11516 "Currently not supporting addba for 60G without Dest_mac");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020011517 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011518 }
11519
Lior David9981b512017-01-20 13:16:40 +020011520 if (wil6210_send_addba(dut, val, dut->back_rcv_buf))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011521 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011522
11523 return 1;
11524}
11525
Lior David9981b512017-01-20 13:16:40 +020011526#endif /* __linux__ */
11527
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011528
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011529static int wcn_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
11530 struct sigma_cmd *cmd)
11531{
11532#ifdef NL80211_SUPPORT
11533 const char *intf = get_param(cmd, "Interface");
11534 const char *val;
11535 int tid = -1;
11536 int bufsize = 64;
11537 struct nl_msg *msg;
11538 int ret = 0;
11539 struct nlattr *params;
11540 int ifindex;
11541
11542 val = get_param(cmd, "TID");
11543 if (val)
11544 tid = atoi(val);
11545
11546 if (tid == -1) {
11547 send_resp(dut, conn, SIGMA_ERROR,
11548 "ErrorCode,sta_send_addba tid invalid");
11549 return 0;
11550 }
11551
11552 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
11553
11554 ifindex = if_nametoindex(intf);
11555 if (ifindex == 0) {
11556 sigma_dut_print(dut, DUT_MSG_ERROR,
11557 "%s: Index for interface %s failed",
11558 __func__, intf);
11559 send_resp(dut, conn, SIGMA_ERROR,
11560 "ErrorCode,sta_send_addba interface invalid");
11561 return 0;
11562 }
11563
11564 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
11565 NL80211_CMD_VENDOR)) ||
11566 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
11567 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
11568 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
11569 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
11570 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
11571 nla_put_u8(msg,
11572 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADD_DEL_BA_SESSION,
11573 QCA_WLAN_ADD_BA) ||
11574 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BA_TID,
11575 tid) ||
Kiran Kumar Lokere26e27582018-08-01 16:18:34 -070011576 nla_put_u16(msg,
11577 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE,
11578 bufsize)) {
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011579 sigma_dut_print(dut, DUT_MSG_ERROR,
11580 "%s: err in adding vendor_cmd and vendor_data",
11581 __func__);
11582 nlmsg_free(msg);
11583 send_resp(dut, conn, SIGMA_ERROR,
11584 "ErrorCode,sta_send_addba err in adding vendor_cmd and vendor_data");
11585 return 0;
11586 }
11587 nla_nest_end(msg, params);
11588
11589 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
11590 if (ret) {
11591 sigma_dut_print(dut, DUT_MSG_ERROR,
11592 "%s: err in send_and_recv_msgs, ret=%d",
11593 __func__, ret);
Sunil Dutt30605592018-05-04 20:35:50 +053011594 if (ret == -EOPNOTSUPP)
11595 return 1;
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011596 send_resp(dut, conn, SIGMA_ERROR,
11597 "ErrorCode,sta_send_addba err in send_and_recv_msgs");
11598 return 0;
11599 }
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011600#else /* NL80211_SUPPORT */
11601 sigma_dut_print(dut, DUT_MSG_ERROR,
11602 "sta_send_addba not supported without NL80211_SUPPORT defined");
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011603#endif /* NL80211_SUPPORT */
Sunil Dutt30605592018-05-04 20:35:50 +053011604
11605 return 1;
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011606}
11607
11608
Jouni Malinenf7222712019-06-13 01:50:21 +030011609static enum sigma_cmd_result cmd_sta_send_addba(struct sigma_dut *dut,
11610 struct sigma_conn *conn,
11611 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011612{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011613 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011614 case DRIVER_ATHEROS:
11615 return ath_sta_send_addba(dut, conn, cmd);
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011616 case DRIVER_WCN:
11617 return wcn_sta_send_addba(dut, conn, cmd);
Lior David9981b512017-01-20 13:16:40 +020011618#ifdef __linux__
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011619 case DRIVER_WIL6210:
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +020011620 return send_addba_60g(dut, conn, cmd, "Dest_mac");
Lior David9981b512017-01-20 13:16:40 +020011621#endif /* __linux__ */
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011622 default:
11623 /*
11624 * There is no driver specific implementation for other drivers.
11625 * Ignore the command and report COMPLETE since the following
11626 * throughput test operation will end up sending ADDBA anyway.
11627 */
11628 return 1;
11629 }
11630}
11631
11632
11633int inject_eth_frame(int s, const void *data, size_t len,
11634 unsigned short ethtype, char *dst, char *src)
11635{
11636 struct iovec iov[4] = {
11637 {
11638 .iov_base = dst,
11639 .iov_len = ETH_ALEN,
11640 },
11641 {
11642 .iov_base = src,
11643 .iov_len = ETH_ALEN,
11644 },
11645 {
11646 .iov_base = &ethtype,
11647 .iov_len = sizeof(unsigned short),
11648 },
11649 {
11650 .iov_base = (void *) data,
11651 .iov_len = len,
11652 }
11653 };
11654 struct msghdr msg = {
11655 .msg_name = NULL,
11656 .msg_namelen = 0,
11657 .msg_iov = iov,
11658 .msg_iovlen = 4,
11659 .msg_control = NULL,
11660 .msg_controllen = 0,
11661 .msg_flags = 0,
11662 };
11663
11664 return sendmsg(s, &msg, 0);
11665}
11666
11667#if defined(__linux__) || defined(__QNXNTO__)
11668
11669int inject_frame(int s, const void *data, size_t len, int encrypt)
11670{
11671#define IEEE80211_RADIOTAP_F_WEP 0x04
11672#define IEEE80211_RADIOTAP_F_FRAG 0x08
11673 unsigned char rtap_hdr[] = {
11674 0x00, 0x00, /* radiotap version */
11675 0x0e, 0x00, /* radiotap length */
11676 0x02, 0xc0, 0x00, 0x00, /* bmap: flags, tx and rx flags */
11677 IEEE80211_RADIOTAP_F_FRAG, /* F_FRAG (fragment if required) */
11678 0x00, /* padding */
11679 0x00, 0x00, /* RX and TX flags to indicate that */
11680 0x00, 0x00, /* this is the injected frame directly */
11681 };
11682 struct iovec iov[2] = {
11683 {
11684 .iov_base = &rtap_hdr,
11685 .iov_len = sizeof(rtap_hdr),
11686 },
11687 {
11688 .iov_base = (void *) data,
11689 .iov_len = len,
11690 }
11691 };
11692 struct msghdr msg = {
11693 .msg_name = NULL,
11694 .msg_namelen = 0,
11695 .msg_iov = iov,
11696 .msg_iovlen = 2,
11697 .msg_control = NULL,
11698 .msg_controllen = 0,
11699 .msg_flags = 0,
11700 };
11701
11702 if (encrypt)
11703 rtap_hdr[8] |= IEEE80211_RADIOTAP_F_WEP;
11704
11705 return sendmsg(s, &msg, 0);
11706}
11707
11708
11709int open_monitor(const char *ifname)
11710{
11711#ifdef __QNXNTO__
11712 struct sockaddr_dl ll;
11713 int s;
11714
11715 memset(&ll, 0, sizeof(ll));
11716 ll.sdl_family = AF_LINK;
11717 ll.sdl_index = if_nametoindex(ifname);
11718 if (ll.sdl_index == 0) {
11719 perror("if_nametoindex");
11720 return -1;
11721 }
11722 s = socket(PF_INET, SOCK_RAW, 0);
11723#else /* __QNXNTO__ */
11724 struct sockaddr_ll ll;
11725 int s;
11726
11727 memset(&ll, 0, sizeof(ll));
11728 ll.sll_family = AF_PACKET;
11729 ll.sll_ifindex = if_nametoindex(ifname);
11730 if (ll.sll_ifindex == 0) {
11731 perror("if_nametoindex");
11732 return -1;
11733 }
11734 s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
11735#endif /* __QNXNTO__ */
11736 if (s < 0) {
11737 perror("socket[PF_PACKET,SOCK_RAW]");
11738 return -1;
11739 }
11740
11741 if (bind(s, (struct sockaddr *) &ll, sizeof(ll)) < 0) {
11742 perror("monitor socket bind");
11743 close(s);
11744 return -1;
11745 }
11746
11747 return s;
11748}
11749
11750
11751static int hex2num(char c)
11752{
11753 if (c >= '0' && c <= '9')
11754 return c - '0';
11755 if (c >= 'a' && c <= 'f')
11756 return c - 'a' + 10;
11757 if (c >= 'A' && c <= 'F')
11758 return c - 'A' + 10;
11759 return -1;
11760}
11761
11762
11763int hwaddr_aton(const char *txt, unsigned char *addr)
11764{
11765 int i;
11766
11767 for (i = 0; i < 6; i++) {
11768 int a, b;
11769
11770 a = hex2num(*txt++);
11771 if (a < 0)
11772 return -1;
11773 b = hex2num(*txt++);
11774 if (b < 0)
11775 return -1;
11776 *addr++ = (a << 4) | b;
11777 if (i < 5 && *txt++ != ':')
11778 return -1;
11779 }
11780
11781 return 0;
11782}
11783
11784#endif /* defined(__linux__) || defined(__QNXNTO__) */
11785
Veerendranath Jakkam49774122020-07-05 09:52:18 +053011786
11787#ifdef NL80211_SUPPORT
11788static int nl80211_send_frame_cmd(struct sigma_dut *dut, const char *intf,
11789 const u8 *data, size_t data_len, int freq)
11790{
11791 struct nl_msg *msg;
11792 int ret = 0;
11793 int ifindex;
11794
11795 ifindex = if_nametoindex(intf);
11796 if (ifindex == 0) {
11797 sigma_dut_print(dut, DUT_MSG_ERROR,
11798 "%s: Index for interface %s failed",
11799 __func__, intf);
11800 return -1;
11801 }
11802
11803 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
11804 NL80211_CMD_FRAME)) ||
11805 (freq && nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq)) ||
11806 nla_put(msg, NL80211_ATTR_FRAME, data_len, data)) {
11807 sigma_dut_print(dut, DUT_MSG_ERROR,
11808 "%s: Error in adding NL80211_CMD_FRAME",
11809 __func__);
11810 nlmsg_free(msg);
11811 return -1;
11812 }
11813
11814 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
11815 if (ret) {
11816 sigma_dut_print(dut, DUT_MSG_ERROR,
11817 "nl80211: Frame command failed: ret=%d (%s) req=%u",
11818 ret, strerror(-ret), freq);
11819 return -1;
11820 }
11821
11822 return 0;
11823}
11824#endif /* NL80211_SUPPORT */
11825
11826
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011827enum send_frame_type {
11828 DISASSOC, DEAUTH, SAQUERY, AUTH, ASSOCREQ, REASSOCREQ, DLS_REQ
11829};
11830enum send_frame_protection {
11831 CORRECT_KEY, INCORRECT_KEY, UNPROTECTED
11832};
11833
11834
11835static int sta_inject_frame(struct sigma_dut *dut, struct sigma_conn *conn,
Veerendranath Jakkam49774122020-07-05 09:52:18 +053011836 const char *intf, enum send_frame_type frame,
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011837 enum send_frame_protection protected,
Veerendranath Jakkam49774122020-07-05 09:52:18 +053011838 const char *dest, int use_monitor)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011839{
11840#ifdef __linux__
11841 unsigned char buf[1000], *pos;
11842 int s, res;
11843 char bssid[20], addr[20];
11844 char result[32], ssid[100];
11845 size_t ssid_len;
11846
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011847 if (get_wpa_status(get_station_ifname(dut), "wpa_state", result,
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011848 sizeof(result)) < 0 ||
11849 strncmp(result, "COMPLETED", 9) != 0) {
11850 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Not connected");
11851 return 0;
11852 }
11853
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011854 if (get_wpa_status(get_station_ifname(dut), "bssid",
11855 bssid, sizeof(bssid)) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011856 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
11857 "current BSSID");
11858 return 0;
11859 }
11860
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011861 if (get_wpa_status(get_station_ifname(dut), "address",
11862 addr, sizeof(addr)) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011863 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
11864 "own MAC address");
11865 return 0;
11866 }
11867
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011868 if (get_wpa_status(get_station_ifname(dut), "ssid", ssid, sizeof(ssid))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011869 < 0) {
11870 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
11871 "current SSID");
11872 return 0;
11873 }
11874 ssid_len = strlen(ssid);
11875
11876 pos = buf;
11877
11878 /* Frame Control */
11879 switch (frame) {
11880 case DISASSOC:
11881 *pos++ = 0xa0;
11882 break;
11883 case DEAUTH:
11884 *pos++ = 0xc0;
11885 break;
11886 case SAQUERY:
11887 *pos++ = 0xd0;
11888 break;
11889 case AUTH:
11890 *pos++ = 0xb0;
11891 break;
11892 case ASSOCREQ:
11893 *pos++ = 0x00;
11894 break;
11895 case REASSOCREQ:
11896 *pos++ = 0x20;
11897 break;
11898 case DLS_REQ:
11899 *pos++ = 0xd0;
11900 break;
11901 }
11902
11903 if (protected == INCORRECT_KEY)
11904 *pos++ = 0x40; /* Set Protected field to 1 */
11905 else
11906 *pos++ = 0x00;
11907
11908 /* Duration */
11909 *pos++ = 0x00;
11910 *pos++ = 0x00;
11911
11912 /* addr1 = DA (current AP) */
11913 hwaddr_aton(bssid, pos);
11914 pos += 6;
11915 /* addr2 = SA (own address) */
11916 hwaddr_aton(addr, pos);
11917 pos += 6;
11918 /* addr3 = BSSID (current AP) */
11919 hwaddr_aton(bssid, pos);
11920 pos += 6;
11921
11922 /* Seq# (to be filled by driver/mac80211) */
11923 *pos++ = 0x00;
11924 *pos++ = 0x00;
11925
11926 if (protected == INCORRECT_KEY) {
11927 /* CCMP parameters */
11928 memcpy(pos, "\x61\x01\x00\x20\x00\x10\x00\x00", 8);
11929 pos += 8;
11930 }
11931
11932 if (protected == INCORRECT_KEY) {
11933 switch (frame) {
11934 case DEAUTH:
11935 /* Reason code (encrypted) */
11936 memcpy(pos, "\xa7\x39", 2);
11937 pos += 2;
11938 break;
11939 case DISASSOC:
11940 /* Reason code (encrypted) */
11941 memcpy(pos, "\xa7\x39", 2);
11942 pos += 2;
11943 break;
11944 case SAQUERY:
11945 /* Category|Action|TransID (encrypted) */
11946 memcpy(pos, "\x6f\xbd\xe9\x4d", 4);
11947 pos += 4;
11948 break;
11949 default:
11950 return -1;
11951 }
11952
11953 /* CCMP MIC */
11954 memcpy(pos, "\xc8\xd8\x3b\x06\x5d\xb7\x25\x68", 8);
11955 pos += 8;
11956 } else {
11957 switch (frame) {
11958 case DEAUTH:
11959 /* reason code = 8 */
11960 *pos++ = 0x08;
11961 *pos++ = 0x00;
11962 break;
11963 case DISASSOC:
11964 /* reason code = 8 */
11965 *pos++ = 0x08;
11966 *pos++ = 0x00;
11967 break;
11968 case SAQUERY:
11969 /* Category - SA Query */
11970 *pos++ = 0x08;
11971 /* SA query Action - Request */
11972 *pos++ = 0x00;
11973 /* Transaction ID */
11974 *pos++ = 0x12;
11975 *pos++ = 0x34;
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +053011976 if (dut->saquery_oci_freq) {
11977 /* OCI IE - Extended ID */
11978 *pos++ = 0xFF;
11979 *pos++ = 0x04;
11980 *pos++ = 0x36;
11981 /* Operating Class */
11982 *pos++ = 0x74;
11983 /* Primary Channel */
11984 *pos++ = freq_to_channel(dut->saquery_oci_freq);
11985 /* Frequency Segment 1 Channel Number */
11986 *pos++ = 0x00;
11987 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011988 break;
11989 case AUTH:
11990 /* Auth Alg (Open) */
11991 *pos++ = 0x00;
11992 *pos++ = 0x00;
11993 /* Seq# */
11994 *pos++ = 0x01;
11995 *pos++ = 0x00;
11996 /* Status code */
11997 *pos++ = 0x00;
11998 *pos++ = 0x00;
11999 break;
12000 case ASSOCREQ:
12001 /* Capability Information */
12002 *pos++ = 0x31;
12003 *pos++ = 0x04;
12004 /* Listen Interval */
12005 *pos++ = 0x0a;
12006 *pos++ = 0x00;
12007 /* SSID */
12008 *pos++ = 0x00;
12009 *pos++ = ssid_len;
12010 memcpy(pos, ssid, ssid_len);
12011 pos += ssid_len;
12012 /* Supported Rates */
12013 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
12014 10);
12015 pos += 10;
12016 /* Extended Supported Rates */
12017 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
12018 pos += 6;
12019 /* RSN */
12020 memcpy(pos, "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00"
12021 "\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x02\xc0"
12022 "\x00\x00\x00\x00\x0f\xac\x06", 28);
12023 pos += 28;
12024 break;
12025 case REASSOCREQ:
12026 /* Capability Information */
12027 *pos++ = 0x31;
12028 *pos++ = 0x04;
12029 /* Listen Interval */
12030 *pos++ = 0x0a;
12031 *pos++ = 0x00;
12032 /* Current AP */
12033 hwaddr_aton(bssid, pos);
12034 pos += 6;
12035 /* SSID */
12036 *pos++ = 0x00;
12037 *pos++ = ssid_len;
12038 memcpy(pos, ssid, ssid_len);
12039 pos += ssid_len;
12040 /* Supported Rates */
12041 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
12042 10);
12043 pos += 10;
12044 /* Extended Supported Rates */
12045 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
12046 pos += 6;
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +053012047 /* RSNE - Group and Pairwise ciphers */
12048 memcpy(pos,
12049 "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04",
12050 14);
12051 pos += 14;
12052 /* RSNE - AKM Suite count */
12053 *pos++ = 0x01;
12054 *pos++ = 0x00;
12055 /* RSNE - AKM Suites */
12056 if (dut->program == PROGRAM_WPA3)
12057 memcpy(pos, "\x00\x0f\xac\x08", 4);
12058 else
12059 memcpy(pos, "\x00\x0f\xac\x02", 4);
12060 pos += 4;
12061 /* RSNE - Capabilities */
12062 *pos++ = 0xc0;
12063 if (dut->ocvc)
12064 *pos++ = 0x40;
12065 else
12066 *pos++ = 0x00;
12067 /* RSNE - PMKID list and Group Management Ciphers */
12068 memcpy(pos, "\x00\x00\x00\x0f\xac\x06", 6);
12069 pos += 6;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012070 break;
12071 case DLS_REQ:
12072 /* Category - DLS */
12073 *pos++ = 0x02;
12074 /* DLS Action - Request */
12075 *pos++ = 0x00;
12076 /* Destination MACAddress */
12077 if (dest)
12078 hwaddr_aton(dest, pos);
12079 else
12080 memset(pos, 0, 6);
12081 pos += 6;
12082 /* Source MACAddress */
12083 hwaddr_aton(addr, pos);
12084 pos += 6;
12085 /* Capability Information */
12086 *pos++ = 0x10; /* Privacy */
12087 *pos++ = 0x06; /* QoS */
12088 /* DLS Timeout Value */
12089 *pos++ = 0x00;
12090 *pos++ = 0x01;
12091 /* Supported rates */
12092 *pos++ = 0x01;
12093 *pos++ = 0x08;
12094 *pos++ = 0x0c; /* 6 Mbps */
12095 *pos++ = 0x12; /* 9 Mbps */
12096 *pos++ = 0x18; /* 12 Mbps */
12097 *pos++ = 0x24; /* 18 Mbps */
12098 *pos++ = 0x30; /* 24 Mbps */
12099 *pos++ = 0x48; /* 36 Mbps */
12100 *pos++ = 0x60; /* 48 Mbps */
12101 *pos++ = 0x6c; /* 54 Mbps */
12102 /* TODO: Extended Supported Rates */
12103 /* TODO: HT Capabilities */
12104 break;
12105 }
12106 }
12107
Veerendranath Jakkam49774122020-07-05 09:52:18 +053012108 if (use_monitor) {
12109 s = open_monitor("sigmadut");
12110 if (s < 0) {
12111 send_resp(dut, conn, SIGMA_ERROR,
12112 "errorCode,Failed to open monitor socket");
12113 return 0;
12114 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012115
Veerendranath Jakkam49774122020-07-05 09:52:18 +053012116 res = inject_frame(s, buf, pos - buf, protected == CORRECT_KEY);
12117 if (res < 0) {
12118 send_resp(dut, conn, SIGMA_ERROR,
12119 "errorCode,Failed to inject frame");
12120 close(s);
12121 return 0;
12122 }
12123 if (res < pos - buf) {
12124 send_resp(dut, conn, SIGMA_ERROR,
12125 "errorCode,Only partial frame sent");
12126 close(s);
12127 return 0;
12128 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012129
Veerendranath Jakkam49774122020-07-05 09:52:18 +053012130 close(s);
12131 } else {
12132#ifdef NL80211_SUPPORT
12133 int freq;
12134 char freq_str[10];
12135
12136 if (get_wpa_status(get_station_ifname(dut), "freq",
12137 freq_str, sizeof(freq_str)) < 0) {
12138 send_resp(dut, conn, SIGMA_ERROR,
12139 "errorCode,Could not get current operating frequency");
12140 return 0;
12141 }
12142 freq = atoi(freq_str);
12143
12144 if (nl80211_send_frame_cmd(dut, intf, buf, pos - buf, freq)) {
12145 send_resp(dut, conn, SIGMA_ERROR,
12146 "errorCode,Failed to inject frame");
12147 return 0;
12148 }
12149#else /* NL80211_SUPPORT */
12150 send_resp(dut, conn, SIGMA_ERROR,
12151 "errorCode,Failed to inject frame (no NL80211_SUPPORT)");
12152 return 0;
12153#endif /* NL80211_SUPPORT */
12154 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012155
12156 return 1;
12157#else /* __linux__ */
12158 send_resp(dut, conn, SIGMA_ERROR, "errorCode,sta_send_frame not "
12159 "yet supported");
12160 return 0;
12161#endif /* __linux__ */
12162}
12163
12164
12165static int cmd_sta_send_frame_tdls(struct sigma_dut *dut,
12166 struct sigma_conn *conn,
12167 struct sigma_cmd *cmd)
12168{
12169 const char *intf = get_param(cmd, "Interface");
12170 const char *sta, *val;
12171 unsigned char addr[ETH_ALEN];
12172 char buf[100];
12173
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +030012174 if (!intf)
12175 return -1;
12176
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012177 sta = get_param(cmd, "peer");
12178 if (sta == NULL)
12179 sta = get_param(cmd, "station");
12180 if (sta == NULL) {
12181 send_resp(dut, conn, SIGMA_ERROR,
12182 "ErrorCode,Missing peer address");
12183 return 0;
12184 }
12185 if (hwaddr_aton(sta, addr) < 0) {
12186 send_resp(dut, conn, SIGMA_ERROR,
12187 "ErrorCode,Invalid peer address");
12188 return 0;
12189 }
12190
12191 val = get_param(cmd, "type");
12192 if (val == NULL)
12193 return -1;
12194
12195 if (strcasecmp(val, "DISCOVERY") == 0) {
12196 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", sta);
12197 if (wpa_command(intf, buf) < 0) {
12198 send_resp(dut, conn, SIGMA_ERROR,
12199 "ErrorCode,Failed to send TDLS discovery");
12200 return 0;
12201 }
12202 return 1;
12203 }
12204
12205 if (strcasecmp(val, "SETUP") == 0) {
12206 int status = 0, timeout = 0;
12207
12208 val = get_param(cmd, "Status");
12209 if (val)
12210 status = atoi(val);
12211
12212 val = get_param(cmd, "Timeout");
12213 if (val)
12214 timeout = atoi(val);
12215
12216 if (status != 0 && status != 37) {
12217 send_resp(dut, conn, SIGMA_ERROR,
12218 "ErrorCode,Unsupported status value");
12219 return 0;
12220 }
12221
12222 if (timeout != 0 && timeout != 301) {
12223 send_resp(dut, conn, SIGMA_ERROR,
12224 "ErrorCode,Unsupported timeout value");
12225 return 0;
12226 }
12227
12228 if (status && timeout) {
12229 send_resp(dut, conn, SIGMA_ERROR,
12230 "ErrorCode,Unsupported timeout+status "
12231 "combination");
12232 return 0;
12233 }
12234
12235 if (status == 37 &&
12236 wpa_command(intf, "SET tdls_testing 0x200")) {
12237 send_resp(dut, conn, SIGMA_ERROR,
12238 "ErrorCode,Failed to enable "
12239 "decline setup response test mode");
12240 return 0;
12241 }
12242
12243 if (timeout == 301) {
12244 int res;
12245 if (dut->no_tpk_expiration)
12246 res = wpa_command(intf,
12247 "SET tdls_testing 0x108");
12248 else
12249 res = wpa_command(intf,
12250 "SET tdls_testing 0x8");
12251 if (res) {
12252 send_resp(dut, conn, SIGMA_ERROR,
12253 "ErrorCode,Failed to set short TPK "
12254 "lifetime");
12255 return 0;
12256 }
12257 }
12258
12259 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", sta);
12260 if (wpa_command(intf, buf) < 0) {
12261 send_resp(dut, conn, SIGMA_ERROR,
12262 "ErrorCode,Failed to send TDLS setup");
12263 return 0;
12264 }
12265 return 1;
12266 }
12267
12268 if (strcasecmp(val, "TEARDOWN") == 0) {
12269 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", sta);
12270 if (wpa_command(intf, buf) < 0) {
12271 send_resp(dut, conn, SIGMA_ERROR,
12272 "ErrorCode,Failed to send TDLS teardown");
12273 return 0;
12274 }
12275 return 1;
12276 }
12277
12278 send_resp(dut, conn, SIGMA_ERROR,
12279 "ErrorCode,Unsupported TDLS frame");
12280 return 0;
12281}
12282
12283
12284static int sta_ap_known(const char *ifname, const char *bssid)
12285{
12286 char buf[4096];
12287
Jouni Malinendd32f192018-09-15 02:55:19 +030012288 snprintf(buf, sizeof(buf), "BSS MASK=1 %s", bssid);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012289 if (wpa_command_resp(ifname, buf, buf, sizeof(buf)) < 0)
12290 return 0;
12291 if (strncmp(buf, "id=", 3) != 0)
12292 return 0;
12293 return 1;
12294}
12295
12296
12297static int sta_scan_ap(struct sigma_dut *dut, const char *ifname,
12298 const char *bssid)
12299{
12300 int res;
12301 struct wpa_ctrl *ctrl;
12302 char buf[256];
12303
12304 if (sta_ap_known(ifname, bssid))
12305 return 0;
12306 sigma_dut_print(dut, DUT_MSG_DEBUG,
12307 "AP not in BSS table - start scan");
12308
12309 ctrl = open_wpa_mon(ifname);
12310 if (ctrl == NULL) {
12311 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
12312 "wpa_supplicant monitor connection");
12313 return -1;
12314 }
12315
12316 if (wpa_command(ifname, "SCAN") < 0) {
12317 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to start scan");
12318 wpa_ctrl_detach(ctrl);
12319 wpa_ctrl_close(ctrl);
12320 return -1;
12321 }
12322
12323 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
12324 buf, sizeof(buf));
12325
12326 wpa_ctrl_detach(ctrl);
12327 wpa_ctrl_close(ctrl);
12328
12329 if (res < 0) {
12330 sigma_dut_print(dut, DUT_MSG_INFO, "Scan did not complete");
12331 return -1;
12332 }
12333
12334 if (sta_ap_known(ifname, bssid))
12335 return 0;
12336 sigma_dut_print(dut, DUT_MSG_INFO, "AP not in BSS table");
12337 return -1;
12338}
12339
12340
12341static int cmd_sta_send_frame_hs2_neighadv(struct sigma_dut *dut,
12342 struct sigma_conn *conn,
12343 struct sigma_cmd *cmd,
12344 const char *intf)
12345{
12346 char buf[200];
12347
12348 snprintf(buf, sizeof(buf), "ndsend 2001:DB8::1 %s", intf);
12349 if (system(buf) != 0) {
12350 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Failed to run "
12351 "ndsend");
12352 return 0;
12353 }
12354
12355 return 1;
12356}
12357
12358
12359static int cmd_sta_send_frame_hs2_neighsolreq(struct sigma_dut *dut,
12360 struct sigma_conn *conn,
12361 struct sigma_cmd *cmd,
12362 const char *intf)
12363{
12364 char buf[200];
12365 const char *ip = get_param(cmd, "SenderIP");
12366
Peng Xu26b356d2017-10-04 17:58:16 -070012367 if (!ip)
12368 return 0;
12369
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012370 snprintf(buf, sizeof(buf), "ndisc6 -nm %s %s -r 4", ip, intf);
12371 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
12372 if (system(buf) == 0) {
12373 sigma_dut_print(dut, DUT_MSG_INFO,
12374 "Neighbor Solicitation got a response "
12375 "for %s@%s", ip, intf);
12376 }
12377
12378 return 1;
12379}
12380
12381
12382static int cmd_sta_send_frame_hs2_arpprobe(struct sigma_dut *dut,
12383 struct sigma_conn *conn,
12384 struct sigma_cmd *cmd,
12385 const char *ifname)
12386{
12387 char buf[200];
12388 const char *ip = get_param(cmd, "SenderIP");
12389
12390 if (ip == NULL) {
12391 send_resp(dut, conn, SIGMA_ERROR,
12392 "ErrorCode,Missing SenderIP parameter");
12393 return 0;
12394 }
12395 snprintf(buf, sizeof(buf), "arping -I %s -D %s -c 4", ifname, ip);
12396 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
12397 if (system(buf) != 0) {
12398 sigma_dut_print(dut, DUT_MSG_INFO, "arping DAD got a response "
12399 "for %s@%s", ip, ifname);
12400 }
12401
12402 return 1;
12403}
12404
12405
12406static int cmd_sta_send_frame_hs2_arpannounce(struct sigma_dut *dut,
12407 struct sigma_conn *conn,
12408 struct sigma_cmd *cmd,
12409 const char *ifname)
12410{
12411 char buf[200];
12412 char ip[16];
12413 int s;
Peng Xub3756882017-10-04 14:39:09 -070012414 struct ifreq ifr;
12415 struct sockaddr_in saddr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012416
12417 s = socket(PF_INET, SOCK_DGRAM, 0);
Peng Xub3756882017-10-04 14:39:09 -070012418 if (s < 0) {
12419 perror("socket");
12420 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012421 }
12422
Peng Xub3756882017-10-04 14:39:09 -070012423 memset(&ifr, 0, sizeof(ifr));
12424 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
12425 if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
12426 sigma_dut_print(dut, DUT_MSG_INFO,
12427 "Failed to get %s IP address: %s",
12428 ifname, strerror(errno));
12429 close(s);
12430 return -1;
12431 }
12432 close(s);
12433
12434 memcpy(&saddr, &ifr.ifr_addr, sizeof(struct sockaddr_in));
12435 strlcpy(ip, inet_ntoa(saddr.sin_addr), sizeof(ip));
12436
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012437 snprintf(buf, sizeof(buf), "arping -I %s -s %s %s -c 4", ifname, ip,
12438 ip);
12439 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
12440 if (system(buf) != 0) {
12441 }
12442
12443 return 1;
12444}
12445
12446
12447static int cmd_sta_send_frame_hs2_arpreply(struct sigma_dut *dut,
12448 struct sigma_conn *conn,
12449 struct sigma_cmd *cmd,
12450 const char *ifname)
12451{
12452 char buf[200], addr[20];
12453 char dst[ETH_ALEN], src[ETH_ALEN];
12454 short ethtype = htons(ETH_P_ARP);
12455 char *pos;
12456 int s, res;
12457 const char *val;
12458 struct sockaddr_in taddr;
12459
12460 val = get_param(cmd, "dest");
12461 if (val)
12462 hwaddr_aton(val, (unsigned char *) dst);
12463
12464 val = get_param(cmd, "DestIP");
12465 if (val)
12466 inet_aton(val, &taddr.sin_addr);
Peng Xu151c9e12017-10-04 14:39:09 -070012467 else
12468 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012469
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012470 if (get_wpa_status(get_station_ifname(dut), "address", addr,
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012471 sizeof(addr)) < 0)
12472 return -2;
12473 hwaddr_aton(addr, (unsigned char *) src);
12474
12475 pos = buf;
12476 *pos++ = 0x00;
12477 *pos++ = 0x01;
12478 *pos++ = 0x08;
12479 *pos++ = 0x00;
12480 *pos++ = 0x06;
12481 *pos++ = 0x04;
12482 *pos++ = 0x00;
12483 *pos++ = 0x02;
12484 memcpy(pos, src, ETH_ALEN);
12485 pos += ETH_ALEN;
12486 memcpy(pos, &taddr.sin_addr, 4);
12487 pos += 4;
12488 memcpy(pos, dst, ETH_ALEN);
12489 pos += ETH_ALEN;
12490 memcpy(pos, &taddr.sin_addr, 4);
12491 pos += 4;
12492
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012493 s = open_monitor(get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012494 if (s < 0) {
12495 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
12496 "monitor socket");
12497 return 0;
12498 }
12499
12500 res = inject_eth_frame(s, buf, pos - buf, ethtype, dst, src);
12501 if (res < 0) {
12502 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
12503 "inject frame");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +053012504 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012505 return 0;
12506 }
12507
12508 close(s);
12509
12510 return 1;
12511}
12512
12513
12514static int cmd_sta_send_frame_hs2_dls_req(struct sigma_dut *dut,
12515 struct sigma_conn *conn,
12516 struct sigma_cmd *cmd,
12517 const char *intf, const char *dest)
12518{
12519 char buf[100];
12520
12521 if (if_nametoindex("sigmadut") == 0) {
12522 snprintf(buf, sizeof(buf),
12523 "iw dev %s interface add sigmadut type monitor",
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012524 get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012525 if (system(buf) != 0 ||
12526 if_nametoindex("sigmadut") == 0) {
12527 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
12528 "monitor interface with '%s'", buf);
12529 return -2;
12530 }
12531 }
12532
12533 if (system("ifconfig sigmadut up") != 0) {
12534 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
12535 "monitor interface up");
12536 return -2;
12537 }
12538
Veerendranath Jakkam49774122020-07-05 09:52:18 +053012539 return sta_inject_frame(dut, conn, intf, DLS_REQ, UNPROTECTED, dest, 1);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012540}
12541
12542
12543static int cmd_sta_send_frame_hs2(struct sigma_dut *dut,
12544 struct sigma_conn *conn,
12545 struct sigma_cmd *cmd)
12546{
12547 const char *intf = get_param(cmd, "Interface");
12548 const char *dest = get_param(cmd, "Dest");
12549 const char *type = get_param(cmd, "FrameName");
12550 const char *val;
12551 char buf[200], *pos, *end;
12552 int count, count2;
12553
12554 if (type == NULL)
12555 type = get_param(cmd, "Type");
12556
12557 if (intf == NULL || dest == NULL || type == NULL)
12558 return -1;
12559
12560 if (strcasecmp(type, "NeighAdv") == 0)
12561 return cmd_sta_send_frame_hs2_neighadv(dut, conn, cmd, intf);
12562
12563 if (strcasecmp(type, "NeighSolicitReq") == 0)
12564 return cmd_sta_send_frame_hs2_neighsolreq(dut, conn, cmd, intf);
12565
12566 if (strcasecmp(type, "ARPProbe") == 0)
12567 return cmd_sta_send_frame_hs2_arpprobe(dut, conn, cmd, intf);
12568
12569 if (strcasecmp(type, "ARPAnnounce") == 0)
12570 return cmd_sta_send_frame_hs2_arpannounce(dut, conn, cmd, intf);
12571
12572 if (strcasecmp(type, "ARPReply") == 0)
12573 return cmd_sta_send_frame_hs2_arpreply(dut, conn, cmd, intf);
12574
12575 if (strcasecmp(type, "DLS-request") == 0 ||
12576 strcasecmp(type, "DLSrequest") == 0)
12577 return cmd_sta_send_frame_hs2_dls_req(dut, conn, cmd, intf,
12578 dest);
12579
12580 if (strcasecmp(type, "ANQPQuery") != 0 &&
12581 strcasecmp(type, "Query") != 0) {
12582 send_resp(dut, conn, SIGMA_ERROR,
12583 "ErrorCode,Unsupported HS 2.0 send frame type");
12584 return 0;
12585 }
12586
12587 if (sta_scan_ap(dut, intf, dest) < 0) {
12588 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not find "
12589 "the requested AP");
12590 return 0;
12591 }
12592
12593 pos = buf;
12594 end = buf + sizeof(buf);
12595 count = 0;
12596 pos += snprintf(pos, end - pos, "ANQP_GET %s ", dest);
12597
12598 val = get_param(cmd, "ANQP_CAP_LIST");
12599 if (val && atoi(val)) {
12600 pos += snprintf(pos, end - pos, "%s257", count > 0 ? "," : "");
12601 count++;
12602 }
12603
12604 val = get_param(cmd, "VENUE_NAME");
12605 if (val && atoi(val)) {
12606 pos += snprintf(pos, end - pos, "%s258", count > 0 ? "," : "");
12607 count++;
12608 }
12609
12610 val = get_param(cmd, "NETWORK_AUTH_TYPE");
12611 if (val && atoi(val)) {
12612 pos += snprintf(pos, end - pos, "%s260", count > 0 ? "," : "");
12613 count++;
12614 }
12615
12616 val = get_param(cmd, "ROAMING_CONS");
12617 if (val && atoi(val)) {
12618 pos += snprintf(pos, end - pos, "%s261", count > 0 ? "," : "");
12619 count++;
12620 }
12621
12622 val = get_param(cmd, "IP_ADDR_TYPE_AVAILABILITY");
12623 if (val && atoi(val)) {
12624 pos += snprintf(pos, end - pos, "%s262", count > 0 ? "," : "");
12625 count++;
12626 }
12627
12628 val = get_param(cmd, "NAI_REALM_LIST");
12629 if (val && atoi(val)) {
12630 pos += snprintf(pos, end - pos, "%s263", count > 0 ? "," : "");
12631 count++;
12632 }
12633
12634 val = get_param(cmd, "3GPP_INFO");
12635 if (val && atoi(val)) {
12636 pos += snprintf(pos, end - pos, "%s264", count > 0 ? "," : "");
12637 count++;
12638 }
12639
12640 val = get_param(cmd, "DOMAIN_LIST");
12641 if (val && atoi(val)) {
12642 pos += snprintf(pos, end - pos, "%s268", count > 0 ? "," : "");
12643 count++;
12644 }
12645
Jouni Malinen34cf9532018-04-29 19:26:33 +030012646 val = get_param(cmd, "Venue_URL");
12647 if (val && atoi(val)) {
12648 pos += snprintf(pos, end - pos, "%s277", count > 0 ? "," : "");
12649 count++;
12650 }
12651
Jouni Malinend3bca5d2018-04-29 17:25:23 +030012652 val = get_param(cmd, "Advice_Of_Charge");
12653 if (val && atoi(val)) {
12654 pos += snprintf(pos, end - pos, "%s278", count > 0 ? "," : "");
12655 count++;
12656 }
12657
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012658 if (count && wpa_command(intf, buf)) {
12659 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,ANQP_GET failed");
12660 return 0;
12661 }
12662
12663 pos = buf;
12664 end = buf + sizeof(buf);
12665 count2 = 0;
12666 pos += snprintf(pos, end - pos, "HS20_ANQP_GET %s ", dest);
12667
12668 val = get_param(cmd, "HS_CAP_LIST");
12669 if (val && atoi(val)) {
12670 pos += snprintf(pos, end - pos, "%s2", count2 > 0 ? "," : "");
12671 count2++;
12672 }
12673
12674 val = get_param(cmd, "OPER_NAME");
12675 if (val && atoi(val)) {
12676 pos += snprintf(pos, end - pos, "%s3", count2 > 0 ? "," : "");
12677 count2++;
12678 }
12679
12680 val = get_param(cmd, "WAN_METRICS");
12681 if (!val)
12682 val = get_param(cmd, "WAN_MAT");
12683 if (!val)
12684 val = get_param(cmd, "WAN_MET");
12685 if (val && atoi(val)) {
12686 pos += snprintf(pos, end - pos, "%s4", count2 > 0 ? "," : "");
12687 count2++;
12688 }
12689
12690 val = get_param(cmd, "CONNECTION_CAPABILITY");
12691 if (val && atoi(val)) {
12692 pos += snprintf(pos, end - pos, "%s5", count2 > 0 ? "," : "");
12693 count2++;
12694 }
12695
12696 val = get_param(cmd, "OP_CLASS");
12697 if (val && atoi(val)) {
12698 pos += snprintf(pos, end - pos, "%s7", count2 > 0 ? "," : "");
12699 count2++;
12700 }
12701
12702 val = get_param(cmd, "OSU_PROVIDER_LIST");
12703 if (val && atoi(val)) {
12704 pos += snprintf(pos, end - pos, "%s8", count2 > 0 ? "," : "");
12705 count2++;
12706 }
12707
Jouni Malinenf67afec2018-04-29 19:24:58 +030012708 val = get_param(cmd, "OPER_ICON_METADATA");
12709 if (!val)
12710 val = get_param(cmd, "OPERATOR_ICON_METADATA");
12711 if (val && atoi(val)) {
12712 pos += snprintf(pos, end - pos, "%s12", count2 > 0 ? "," : "");
12713 count2++;
12714 }
12715
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012716 if (count && count2) {
12717 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before sending out "
12718 "second query");
12719 sleep(1);
12720 }
12721
12722 if (count2 && wpa_command(intf, buf)) {
12723 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,HS20_ANQP_GET "
12724 "failed");
12725 return 0;
12726 }
12727
12728 val = get_param(cmd, "NAI_HOME_REALM_LIST");
12729 if (val) {
12730 if (count || count2) {
12731 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
12732 "sending out second query");
12733 sleep(1);
12734 }
12735
12736 if (strcmp(val, "1") == 0)
12737 val = "mail.example.com";
12738 snprintf(buf, end - pos,
12739 "HS20_GET_NAI_HOME_REALM_LIST %s realm=%s",
12740 dest, val);
12741 if (wpa_command(intf, buf)) {
12742 send_resp(dut, conn, SIGMA_ERROR,
12743 "ErrorCode,HS20_GET_NAI_HOME_REALM_LIST "
12744 "failed");
12745 return 0;
12746 }
12747 }
12748
12749 val = get_param(cmd, "ICON_REQUEST");
12750 if (val) {
12751 if (count || count2) {
12752 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
12753 "sending out second query");
12754 sleep(1);
12755 }
12756
12757 snprintf(buf, end - pos,
12758 "HS20_ICON_REQUEST %s %s", dest, val);
12759 if (wpa_command(intf, buf)) {
12760 send_resp(dut, conn, SIGMA_ERROR,
12761 "ErrorCode,HS20_ICON_REQUEST failed");
12762 return 0;
12763 }
12764 }
12765
12766 return 1;
12767}
12768
12769
12770static int ath_sta_send_frame_vht(struct sigma_dut *dut,
12771 struct sigma_conn *conn,
12772 struct sigma_cmd *cmd)
12773{
12774 const char *val;
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012775 const char *ifname;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012776 int chwidth, nss;
12777
12778 val = get_param(cmd, "framename");
12779 if (!val)
12780 return -1;
12781 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
12782
12783 /* Command sequence to generate Op mode notification */
12784 if (val && strcasecmp(val, "Op_md_notif_frm") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012785 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012786
12787 /* Disable STBC */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070012788 run_iwpriv(dut, ifname, "tx_stbc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012789
12790 /* Extract Channel width */
12791 val = get_param(cmd, "Channel_width");
12792 if (val) {
12793 switch (atoi(val)) {
12794 case 20:
12795 chwidth = 0;
12796 break;
12797 case 40:
12798 chwidth = 1;
12799 break;
12800 case 80:
12801 chwidth = 2;
12802 break;
12803 case 160:
12804 chwidth = 3;
12805 break;
12806 default:
12807 chwidth = 2;
12808 break;
12809 }
12810
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070012811 run_iwpriv(dut, ifname, "chwidth %d", chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012812 }
12813
12814 /* Extract NSS */
12815 val = get_param(cmd, "NSS");
12816 if (val) {
12817 switch (atoi(val)) {
12818 case 1:
12819 nss = 1;
12820 break;
12821 case 2:
12822 nss = 3;
12823 break;
12824 case 3:
12825 nss = 7;
12826 break;
12827 default:
12828 /* We do not support NSS > 3 */
12829 nss = 3;
12830 break;
12831 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070012832 run_iwpriv(dut, ifname, "rxchainmask %d", nss);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012833 }
12834
12835 /* Opmode notify */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070012836 run_iwpriv(dut, ifname, "opmode_notify 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012837 }
12838
12839 return 1;
12840}
12841
12842
Kiran Kumar Lokere00d74412020-07-23 13:26:51 -070012843static int wcn_sta_set_pmf_config(struct sigma_dut *dut, const char *intf,
12844 enum send_frame_protection protected)
12845{
12846#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +053012847 return wcn_wifi_test_config_set_u8(
12848 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_PMF_PROTECTION,
12849 protected);
Kiran Kumar Lokere00d74412020-07-23 13:26:51 -070012850#else /* NL80211_SUPPORT */
12851 sigma_dut_print(dut, DUT_MSG_ERROR,
12852 "PMF config cannot be set without NL80211_SUPPORT defined");
12853 return -1;
12854#endif /* NL80211_SUPPORT */
12855}
12856
12857
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012858static int cmd_sta_send_frame_vht(struct sigma_dut *dut,
12859 struct sigma_conn *conn,
12860 struct sigma_cmd *cmd)
12861{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012862 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012863 case DRIVER_ATHEROS:
12864 return ath_sta_send_frame_vht(dut, conn, cmd);
12865 default:
12866 send_resp(dut, conn, SIGMA_ERROR,
12867 "errorCode,Unsupported sta_set_frame(VHT) with the current driver");
12868 return 0;
12869 }
12870}
12871
12872
Kiran Kumar Lokerec2c3b412020-07-23 13:51:27 -070012873static int wcn_sta_send_disassoc(struct sigma_dut *dut, const char *intf)
12874{
12875#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +053012876 return wcn_wifi_test_config_set_flag(
12877 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_DISASSOC_TX);
Kiran Kumar Lokerec2c3b412020-07-23 13:51:27 -070012878#else /* NL80211_SUPPORT */
12879 sigma_dut_print(dut, DUT_MSG_ERROR,
12880 "Disassoc Tx cannot be done without NL80211_SUPPORT defined");
12881 return -1;
12882#endif /* NL80211_SUPPORT */
12883}
12884
12885
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012886static int wcn_sta_send_frame_he(struct sigma_dut *dut, struct sigma_conn *conn,
12887 struct sigma_cmd *cmd)
12888{
12889 const char *val;
12890 const char *intf = get_param(cmd, "Interface");
Kiran Kumar Lokere00d74412020-07-23 13:26:51 -070012891 enum send_frame_protection protected;
12892 const char *pmf;
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012893
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +030012894 if (!intf)
12895 return -1;
12896
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012897 val = get_param(cmd, "framename");
12898 if (!val)
12899 return -1;
12900 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
12901
Kiran Kumar Lokere00d74412020-07-23 13:26:51 -070012902 pmf = get_param(cmd, "PMFProtected");
12903 if (!pmf)
12904 pmf = get_param(cmd, "Protected");
12905 if (pmf) {
12906 if (strcasecmp(pmf, "Correct-key") == 0 ||
12907 strcasecmp(pmf, "CorrectKey") == 0) {
12908 protected = CORRECT_KEY;
12909 } else if (strcasecmp(pmf, "IncorrectKey") == 0) {
12910 protected = INCORRECT_KEY;
12911 } else if (strcasecmp(pmf, "Unprotected") == 0) {
12912 protected = UNPROTECTED;
12913 } else {
12914 send_resp(dut, conn, SIGMA_ERROR,
12915 "errorCode,Unsupported PMFProtected");
12916 return STATUS_SENT_ERROR;
12917 }
12918 sigma_dut_print(dut, DUT_MSG_DEBUG, "Config PMF protection %d",
12919 protected);
12920 wcn_sta_set_pmf_config(dut, intf, protected);
12921 }
12922
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012923 /* Command sequence to generate Op mode notification */
12924 if (val && strcasecmp(val, "action") == 0) {
12925 val = get_param(cmd, "PPDUTxType");
12926 if (val && strcasecmp(val, "TB") == 0) {
12927 if (sta_set_action_tx_in_he_tb_ppdu(dut, intf, 1)) {
12928 sigma_dut_print(dut, DUT_MSG_ERROR,
12929 "failed to send TB PPDU Tx cfg");
12930 send_resp(dut, conn, SIGMA_ERROR,
12931 "ErrorCode,set TB PPDU Tx cfg failed");
12932 return 0;
12933 }
12934 return 1;
12935 }
12936
12937 sigma_dut_print(dut, DUT_MSG_ERROR,
12938 "Action Tx type is not defined");
Kiran Kumar Lokerec2c3b412020-07-23 13:51:27 -070012939
12940 return SUCCESS_SEND_STATUS;
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012941 }
12942
Kiran Kumar Lokerec2c3b412020-07-23 13:51:27 -070012943 if (strcasecmp(val, "disassoc") == 0)
12944 wcn_sta_send_disassoc(dut, intf);
12945
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012946 return 1;
12947}
12948
12949
12950static int cmd_sta_send_frame_he(struct sigma_dut *dut,
12951 struct sigma_conn *conn,
12952 struct sigma_cmd *cmd)
12953{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012954 switch (get_driver_type(dut)) {
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012955 case DRIVER_WCN:
12956 return wcn_sta_send_frame_he(dut, conn, cmd);
12957 default:
12958 send_resp(dut, conn, SIGMA_ERROR,
12959 "errorCode,Unsupported sta_set_frame(HE) with the current driver");
12960 return 0;
12961 }
12962}
12963
12964
Lior David0fe101e2017-03-09 16:09:50 +020012965#ifdef __linux__
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030012966
12967static int
12968wil6210_send_p2p_frame_60g(struct sigma_dut *dut, struct sigma_cmd *cmd,
12969 const char *frame_name, const char *dest_mac)
12970{
12971 int isprobereq = strcasecmp(frame_name, "probereq") == 0;
12972 const char *ssid = get_param(cmd, "ssid");
12973 const char *countstr = get_param(cmd, "count");
12974 const char *channelstr = get_param(cmd, "channel");
12975 const char *group_id = get_param(cmd, "groupid");
12976 const char *client_id = get_param(cmd, "clientmac");
12977 int count, channel, freq, i;
12978 const char *fname;
12979 char frame[1024], src_mac[20], group_id_attr[25],
12980 device_macstr[3 * ETH_ALEN], client_mac[ETH_ALEN];
12981 const char *group_ssid;
12982 const int group_ssid_prefix_len = 9;
12983 struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *) frame;
12984 size_t framelen = sizeof(frame);
12985 struct template_frame_tag tags[2];
12986 size_t tags_total = ARRAY_SIZE(tags);
12987 int tag_index, len, dst_len;
12988
12989 if (!countstr || !channelstr) {
12990 sigma_dut_print(dut, DUT_MSG_ERROR,
12991 "Missing argument: count, channel");
12992 return -1;
12993 }
12994 if (isprobereq && !ssid) {
12995 sigma_dut_print(dut, DUT_MSG_ERROR,
12996 "Missing argument: ssid");
12997 return -1;
12998 }
12999 if (!isprobereq && (!group_id || !client_id)) {
13000 sigma_dut_print(dut, DUT_MSG_ERROR,
13001 "Missing argument: group_id, client_id");
13002 return -1;
13003 }
13004
13005 count = atoi(countstr);
13006 channel = atoi(channelstr);
13007 freq = channel_to_freq(dut, channel);
13008
13009 if (!freq) {
13010 sigma_dut_print(dut, DUT_MSG_ERROR,
13011 "invalid channel: %s", channelstr);
13012 return -1;
13013 }
13014
13015 if (isprobereq) {
13016 if (strcasecmp(ssid, "wildcard") == 0) {
13017 fname = "probe_req_wildcard.txt";
13018 } else if (strcasecmp(ssid, "P2P_Wildcard") == 0) {
13019 fname = "probe_req_P2P_Wildcard.txt";
13020 } else {
13021 sigma_dut_print(dut, DUT_MSG_ERROR,
13022 "invalid probe request type");
13023 return -1;
13024 }
13025 } else {
13026 fname = "P2P_device_discovery_req.txt";
13027 }
13028
13029 if (parse_template_frame_file(dut, fname, frame, &framelen,
13030 tags, &tags_total)) {
13031 sigma_dut_print(dut, DUT_MSG_ERROR,
13032 "invalid frame template: %s", fname);
13033 return -1;
13034 }
13035
Jouni Malinen016ae6c2019-11-04 17:00:01 +020013036 if (get_wpa_status(get_station_ifname(dut), "address",
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030013037 src_mac, sizeof(src_mac)) < 0 ||
13038 parse_mac_address(dut, src_mac, &hdr->addr2[0]) ||
13039 parse_mac_address(dut, dest_mac, &hdr->addr1[0]))
13040 return -1;
13041 /* Use wildcard BSSID, since we are in PBSS */
13042 memset(&hdr->addr3, 0xFF, ETH_ALEN);
13043
13044 if (!isprobereq) {
13045 tag_index = find_template_frame_tag(tags, tags_total, 1);
13046 if (tag_index < 0) {
13047 sigma_dut_print(dut, DUT_MSG_ERROR,
13048 "can't find device id attribute");
13049 return -1;
13050 }
13051 if (parse_mac_address(dut, client_id,
13052 (unsigned char *) client_mac)) {
13053 sigma_dut_print(dut, DUT_MSG_ERROR,
13054 "invalid client_id: %s", client_id);
13055 return -1;
13056 }
13057 if (replace_p2p_attribute(dut, &frame[tags[tag_index].offset],
13058 framelen - tags[tag_index].offset,
13059 IEEE80211_P2P_ATTR_DEVICE_ID,
13060 client_mac, ETH_ALEN)) {
13061 sigma_dut_print(dut, DUT_MSG_ERROR,
13062 "fail to replace device id attribute");
13063 return -1;
13064 }
13065
13066 /*
13067 * group_id arg contains device MAC address followed by
13068 * space and SSID (DIRECT-somessid).
13069 * group id attribute contains device address (6 bytes)
13070 * followed by SSID prefix DIRECT-XX (9 bytes)
13071 */
13072 if (strlen(group_id) < sizeof(device_macstr)) {
13073 sigma_dut_print(dut, DUT_MSG_ERROR,
13074 "group_id arg too short");
13075 return -1;
13076 }
13077 memcpy(device_macstr, group_id, sizeof(device_macstr));
13078 device_macstr[sizeof(device_macstr) - 1] = '\0';
13079 if (parse_mac_address(dut, device_macstr,
13080 (unsigned char *) group_id_attr)) {
13081 sigma_dut_print(dut, DUT_MSG_ERROR,
13082 "fail to parse device address from group_id");
13083 return -1;
13084 }
13085 group_ssid = strchr(group_id, ' ');
13086 if (!group_ssid) {
13087 sigma_dut_print(dut, DUT_MSG_ERROR,
13088 "invalid group_id arg, no ssid");
13089 return -1;
13090 }
13091 group_ssid++;
13092 len = strlen(group_ssid);
13093 if (len < group_ssid_prefix_len) {
13094 sigma_dut_print(dut, DUT_MSG_ERROR,
13095 "group_id SSID too short");
13096 return -1;
13097 }
13098 dst_len = sizeof(group_id_attr) - ETH_ALEN;
13099 if (len > dst_len) {
13100 sigma_dut_print(dut, DUT_MSG_ERROR,
13101 "group_id SSID (%s) too long",
13102 group_ssid);
13103 return -1;
13104 }
13105
13106 memcpy(group_id_attr + ETH_ALEN, group_ssid, len);
13107 tag_index = find_template_frame_tag(tags, tags_total, 2);
13108 if (tag_index < 0) {
13109 sigma_dut_print(dut, DUT_MSG_ERROR,
13110 "can't find group id attribute");
13111 return -1;
13112 }
13113 if (replace_p2p_attribute(dut, &frame[tags[tag_index].offset],
13114 framelen - tags[tag_index].offset,
13115 IEEE80211_P2P_ATTR_GROUP_ID,
13116 group_id_attr,
13117 sizeof(group_id_attr))) {
13118 sigma_dut_print(dut, DUT_MSG_ERROR,
13119 "fail to replace group id attribute");
13120 return -1;
13121 }
13122 }
13123
13124 for (i = 0; i < count; i++) {
13125 if (wil6210_transmit_frame(dut, freq,
13126 WIL_TRANSMIT_FRAME_DEFAULT_ROC,
13127 frame, framelen)) {
13128 sigma_dut_print(dut, DUT_MSG_ERROR,
13129 "fail to transmit probe request frame");
13130 return -1;
13131 }
13132 }
13133
13134 return 0;
13135}
13136
13137
Lior David0fe101e2017-03-09 16:09:50 +020013138int wil6210_send_frame_60g(struct sigma_dut *dut, struct sigma_conn *conn,
13139 struct sigma_cmd *cmd)
13140{
13141 const char *frame_name = get_param(cmd, "framename");
13142 const char *mac = get_param(cmd, "dest_mac");
13143
13144 if (!frame_name || !mac) {
13145 sigma_dut_print(dut, DUT_MSG_ERROR,
13146 "framename and dest_mac must be provided");
13147 return -1;
13148 }
13149
13150 if (strcasecmp(frame_name, "brp") == 0) {
13151 const char *l_rx = get_param(cmd, "L-RX");
13152 int l_rx_i;
13153
13154 if (!l_rx) {
13155 sigma_dut_print(dut, DUT_MSG_ERROR,
13156 "L-RX must be provided");
13157 return -1;
13158 }
13159 l_rx_i = atoi(l_rx);
13160
13161 sigma_dut_print(dut, DUT_MSG_INFO,
13162 "dev_send_frame: BRP-RX, dest_mac %s, L-RX %s",
13163 mac, l_rx);
13164 if (l_rx_i != 16) {
13165 sigma_dut_print(dut, DUT_MSG_ERROR,
13166 "unsupported L-RX: %s", l_rx);
13167 return -1;
13168 }
13169
13170 if (wil6210_send_brp_rx(dut, mac, l_rx_i))
13171 return -1;
13172 } else if (strcasecmp(frame_name, "ssw") == 0) {
13173 sigma_dut_print(dut, DUT_MSG_INFO,
13174 "dev_send_frame: SLS, dest_mac %s", mac);
13175 if (wil6210_send_sls(dut, mac))
13176 return -1;
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030013177 } else if ((strcasecmp(frame_name, "probereq") == 0) ||
13178 (strcasecmp(frame_name, "devdiscreq") == 0)) {
13179 sigma_dut_print(dut, DUT_MSG_INFO,
13180 "dev_send_frame: %s, dest_mac %s", frame_name,
13181 mac);
13182 if (wil6210_send_p2p_frame_60g(dut, cmd, frame_name, mac))
13183 return -1;
Lior David0fe101e2017-03-09 16:09:50 +020013184 } else {
13185 sigma_dut_print(dut, DUT_MSG_ERROR,
13186 "unsupported frame type: %s", frame_name);
13187 return -1;
13188 }
13189
13190 return 1;
13191}
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030013192
Lior David0fe101e2017-03-09 16:09:50 +020013193#endif /* __linux__ */
13194
13195
13196static int cmd_sta_send_frame_60g(struct sigma_dut *dut,
13197 struct sigma_conn *conn,
13198 struct sigma_cmd *cmd)
13199{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020013200 switch (get_driver_type(dut)) {
Lior David0fe101e2017-03-09 16:09:50 +020013201#ifdef __linux__
13202 case DRIVER_WIL6210:
13203 return wil6210_send_frame_60g(dut, conn, cmd);
13204#endif /* __linux__ */
13205 default:
13206 send_resp(dut, conn, SIGMA_ERROR,
13207 "errorCode,Unsupported sta_set_frame(60G) with the current driver");
13208 return 0;
13209 }
13210}
13211
13212
Ashwini Patildb59b3c2017-04-13 15:19:23 +053013213static int mbo_send_anqp_query(struct sigma_dut *dut, struct sigma_conn *conn,
13214 const char *intf, struct sigma_cmd *cmd)
13215{
13216 const char *val, *addr;
13217 char buf[100];
13218
13219 addr = get_param(cmd, "DestMac");
13220 if (!addr) {
13221 send_resp(dut, conn, SIGMA_INVALID,
13222 "ErrorCode,AP MAC address is missing");
13223 return 0;
13224 }
13225
13226 val = get_param(cmd, "ANQPQuery_ID");
13227 if (!val) {
13228 send_resp(dut, conn, SIGMA_INVALID,
13229 "ErrorCode,Missing ANQPQuery_ID");
13230 return 0;
13231 }
13232
13233 if (strcasecmp(val, "NeighborReportReq") == 0) {
13234 snprintf(buf, sizeof(buf), "ANQP_GET %s 272", addr);
13235 } else if (strcasecmp(val, "QueryListWithCellPref") == 0) {
13236 snprintf(buf, sizeof(buf), "ANQP_GET %s 272,mbo:2", addr);
13237 } else {
13238 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid ANQPQuery_ID: %s",
13239 val);
13240 send_resp(dut, conn, SIGMA_INVALID,
13241 "ErrorCode,Invalid ANQPQuery_ID");
13242 return 0;
13243 }
13244
Ashwini Patild174f2c2017-04-13 16:49:46 +053013245 /* Set gas_address3 field to IEEE 802.11-2012 standard compliant form
13246 * (Address3 = Wildcard BSSID when sent to not-associated AP;
13247 * if associated, AP BSSID).
13248 */
13249 if (wpa_command(intf, "SET gas_address3 1") < 0) {
13250 send_resp(dut, conn, SIGMA_ERROR,
13251 "ErrorCode,Failed to set gas_address3");
13252 return 0;
13253 }
13254
Ashwini Patildb59b3c2017-04-13 15:19:23 +053013255 if (wpa_command(intf, buf) < 0) {
13256 send_resp(dut, conn, SIGMA_ERROR,
13257 "ErrorCode,Failed to send ANQP query");
13258 return 0;
13259 }
13260
13261 return 1;
13262}
13263
13264
13265static int mbo_cmd_sta_send_frame(struct sigma_dut *dut,
13266 struct sigma_conn *conn,
13267 const char *intf,
13268 struct sigma_cmd *cmd)
13269{
13270 const char *val = get_param(cmd, "FrameName");
13271
13272 if (val && strcasecmp(val, "ANQPQuery") == 0)
13273 return mbo_send_anqp_query(dut, conn, intf, cmd);
13274
13275 return 2;
13276}
13277
13278
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +053013279static enum sigma_cmd_result cmd_sta_send_frame_wpa3(struct sigma_dut *dut,
13280 struct sigma_conn *conn,
13281 const char *intf,
13282 struct sigma_cmd *cmd)
13283{
13284 const char *val = get_param(cmd, "framename");
13285
13286 if (!val)
13287 return INVALID_SEND_STATUS;
13288
13289 if (strcasecmp(val, "SAQueryReq") == 0) {
13290 val = get_param(cmd, "OCIChannel");
13291
13292 if (!val) {
13293 send_resp(dut, conn, SIGMA_ERROR,
13294 "errorCode,OCIChannel not present");
13295 return STATUS_SENT_ERROR;
13296 }
13297
13298 dut->saquery_oci_freq = channel_to_freq(dut, atoi(val));
13299 if (!dut->saquery_oci_freq) {
13300 send_resp(dut, conn, SIGMA_ERROR,
13301 "errorCode,Invalid OCIChannel number");
13302 return STATUS_SENT_ERROR;
13303 }
13304
13305 return sta_inject_frame(dut, conn, intf, SAQUERY, CORRECT_KEY,
13306 NULL, 0);
13307 }
13308
13309 if (strcasecmp(val, "reassocreq") == 0)
13310 return sta_inject_frame(dut, conn, intf, REASSOCREQ,
13311 CORRECT_KEY, NULL, 0);
13312
Veerendranath9f81dfb2020-08-10 01:21:29 -070013313 if (strcasecmp(val, "ANQPQuery") == 0) {
13314 char buf[50];
13315 const char *dest = get_param(cmd, "DestMac");
13316 const char *chan = get_param(cmd, "channel");
Veerendranath Jakkam78862fc2020-11-19 21:23:27 +053013317 const char *freq_str = get_param(cmd, "ChnlFreq");
Veerendranath9f81dfb2020-08-10 01:21:29 -070013318 int len, freq;
13319
Veerendranath Jakkam78862fc2020-11-19 21:23:27 +053013320 if (freq_str)
13321 freq = atoi(freq_str);
13322 else
13323 freq = chan ? channel_to_freq(dut, atoi(chan)) : 0;
13324
Veerendranath9f81dfb2020-08-10 01:21:29 -070013325 if (!dest || !freq)
13326 return INVALID_SEND_STATUS;
13327
13328 len = snprintf(buf, sizeof(buf), "ANQP_GET %s freq=%d 257",
13329 dest, freq);
13330 if (len < 0 || len >= sizeof(buf)) {
13331 sigma_dut_print(dut, DUT_MSG_ERROR,
13332 "Failed to allocate buf");
13333 return ERROR_SEND_STATUS;
13334 }
13335
13336 if (wpa_command(intf, buf) != 0) {
13337 send_resp(dut, conn, SIGMA_ERROR,
13338 "ErrorCode,Failed to send ANQP Query frame");
13339 return STATUS_SENT_ERROR;
13340 }
13341
13342 sigma_dut_print(dut, DUT_MSG_DEBUG,
13343 "ANQP Query sent: %s", buf);
13344
13345 return SUCCESS_SEND_STATUS;
13346 }
13347
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +053013348 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported framename");
13349 return STATUS_SENT_ERROR;
13350}
13351
13352
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013353static int
13354get_type4_frame_classifier(struct sigma_dut *dut, struct sigma_cmd *cmd,
13355 char *pos, int rem_len, int num_of_scs_desc,
13356 int num_of_tclas_elem)
13357{
13358 const char *val;
13359 int ipv6;
13360 int len, total_len = 0;
13361
13362 val = get_param_fmt(cmd, "TCLASElem_Version_%d_%d", num_of_scs_desc,
13363 num_of_tclas_elem);
13364 if (!val) {
13365 sigma_dut_print(dut, DUT_MSG_ERROR, "%s: ip_version empty",
13366 __func__);
13367 return -1;
13368 }
13369
13370 if (strcmp(val, "6") == 0) {
13371 ipv6 = 1;
13372 } else if (strcmp(val, "4") == 0) {
13373 ipv6 = 0;
13374 } else {
13375 sigma_dut_print(dut, DUT_MSG_ERROR, "%s: ip_version invalid",
13376 __func__);
13377 return -1;
13378 }
13379
13380 len = snprintf(pos, rem_len, " ip_version=%s", ipv6 ? "ipv6" : "ipv4");
13381 if (len < 0 || len >= rem_len)
13382 return -1;
13383
13384 pos += len;
13385 rem_len -= len;
13386 total_len += len;
13387
13388 val = get_param_fmt(cmd, "TCLASElem_SourceIPAddr_%d_%d",
13389 num_of_scs_desc, num_of_tclas_elem);
13390 if (val) {
13391 len = snprintf(pos, rem_len, " src_ip=%s", val);
13392 if (len < 0 || len >= rem_len)
13393 return -1;
13394
13395 pos += len;
13396 rem_len -= len;
13397 total_len += len;
13398 }
13399
13400 val = get_param_fmt(cmd, "TCLASElem_DestinationIPAddr_%d_%d",
13401 num_of_scs_desc, num_of_tclas_elem);
13402 if (val) {
13403 len = snprintf(pos, rem_len, " dst_ip=%s", val);
13404 if (len < 0 || len >= rem_len)
13405 return -1;
13406
13407 pos += len;
13408 rem_len -= len;
13409 total_len += len;
13410 }
13411
13412 val = get_param_fmt(cmd, "TCLASElem_SourcePort_%d_%d", num_of_scs_desc,
13413 num_of_tclas_elem);
13414 if (val) {
13415 len = snprintf(pos, rem_len, " src_port=%s", val);
13416 if (len < 0 || len >= rem_len)
13417 return -1;
13418
13419 pos += len;
13420 rem_len -= len;
13421 total_len += len;
13422 }
13423
13424 val = get_param_fmt(cmd, "TCLASElem_DestinationPort_%d_%d",
13425 num_of_scs_desc, num_of_tclas_elem);
13426 if (val) {
13427 len = snprintf(pos, rem_len, " dst_port=%s", val);
13428 if (len < 0 || len >= rem_len)
13429 return -1;
13430
13431 pos += len;
13432 rem_len -= len;
13433 total_len += len;
13434 }
13435
13436 val = get_param_fmt(cmd, "TCLASElem_DSCP_%d_%d", num_of_scs_desc,
13437 num_of_tclas_elem);
13438 if (val) {
13439 len = snprintf(pos, rem_len, " dscp=%s", val);
13440 if (len < 0 || len >= rem_len)
13441 return -1;
13442
13443 pos += len;
13444 rem_len -= len;
13445 total_len += len;
13446 }
13447
13448 val = get_param_fmt(cmd, "TCLASElem_ProtocolNxtHeader_%d_%d",
13449 num_of_scs_desc, num_of_tclas_elem);
13450 if (val) {
13451 char *prot;
13452
13453 switch (atoi(val)) {
13454 case 17:
13455 prot = "udp";
13456 break;
13457 case 6:
13458 prot = "tcp";
13459 break;
13460 case 50:
13461 prot = "esp";
13462 break;
13463 default:
13464 sigma_dut_print(dut, DUT_MSG_ERROR,
13465 "Invalid protocol %d", atoi(val));
13466 return -1;
13467 }
13468
13469 if (ipv6)
13470 len = snprintf(pos, rem_len, " next_header=%s", prot);
13471 else
13472 len = snprintf(pos, rem_len, " protocol=%s", prot);
13473 if (len < 0 || len >= rem_len)
13474 return -1;
13475
13476 pos += len;
13477 rem_len -= len;
13478 total_len += len;
13479 }
13480
13481 return total_len;
13482}
13483
13484
13485static int
13486get_type10_frame_classifier(struct sigma_dut *dut, struct sigma_cmd *cmd,
13487 char *pos, int rem_len, int num_of_scs_desc,
13488 int num_of_tclas_elem)
13489{
13490 const char *val;
13491 int len, total_len = 0;
13492
13493 val = get_param_fmt(cmd, "TCLASElem_ProtoInstance_%d_%d",
13494 num_of_scs_desc, num_of_tclas_elem);
13495 if (val) {
13496 len = snprintf(pos, rem_len, " prot_instance=%s",
13497 val);
13498 if (len < 0 || len >= rem_len)
13499 return -1;
13500
13501 pos += len;
13502 rem_len -= len;
13503 total_len += len;
13504 }
13505
13506 val = get_param_fmt(cmd, "TCLASElem_ProtoNumNextHeader_%d_%d",
13507 num_of_scs_desc, num_of_tclas_elem);
13508 if (val) {
13509 char *prot;
13510
13511 switch (atoi(val)) {
13512 case 17:
13513 prot = "udp";
13514 break;
13515 case 6:
13516 prot = "tcp";
13517 break;
13518 case 50:
13519 prot = "esp";
13520 break;
13521 default:
13522 sigma_dut_print(dut, DUT_MSG_ERROR,
13523 "Invalid protocol %d",
13524 atoi(val));
13525 return -1;
13526 }
13527
13528 len = snprintf(pos, rem_len, " prot_number=%s", prot);
13529 if (len < 0 || len >= rem_len)
13530 return -1;
13531
13532 pos += len;
13533 rem_len -= len;
13534 total_len += len;
13535 }
13536
13537 val = get_param_fmt(cmd, "TCLASElem_FilterValue_%d_%d",
13538 num_of_scs_desc, num_of_tclas_elem);
13539 if (val) {
13540 len = snprintf(pos, rem_len, " filter_value=%s", (val + 2));
13541 if (len < 0 || len >= rem_len)
13542 return -1;
13543
13544 pos += len;
13545 rem_len -= len;
13546 total_len += len;
13547 }
13548
13549 val = get_param_fmt(cmd, "TCLASElem_FilterMask_%d_%d", num_of_scs_desc,
13550 num_of_tclas_elem);
13551 if (val && strlen(val) >= 2) {
13552 len = snprintf(pos, rem_len, " filter_mask=%s", val + 2);
13553 if (len < 0 || len >= rem_len)
13554 return -1;
13555
13556 pos += len;
13557 rem_len -= len;
13558 total_len += len;
13559 }
13560
13561 return total_len;
13562}
13563
13564
13565static enum sigma_cmd_result
13566cmd_sta_send_frame_scs(struct sigma_dut *dut, struct sigma_conn *conn,
13567 const char *intf, struct sigma_cmd *cmd)
13568{
13569 char buf[4096], *pos;
13570 const char *val, *scs_id, *classifier_type;
13571 int len, rem_len, total_bytes;
13572 int num_of_scs_desc = 0, num_of_tclas_elem = 0;
13573
13574 scs_id = get_param(cmd, "SCSDescrElem_SCSID_1");
13575 if (!scs_id) {
13576 sigma_dut_print(dut, DUT_MSG_ERROR, "SCS ID empty");
13577 return INVALID_SEND_STATUS;
13578 }
13579
13580 rem_len = sizeof(buf);
13581 pos = buf;
13582
13583 len = snprintf(buf, sizeof(buf), "SCS");
13584 if (len < 0 || len > rem_len)
13585 goto fail;
13586
13587 pos += len;
13588 rem_len -= len;
13589
13590 while (scs_id) {
13591 num_of_scs_desc++;
13592
13593 val = get_param_fmt(cmd, "SCSDescrElem_RequestType_%d",
13594 num_of_scs_desc);
13595 if (!val)
13596 return INVALID_SEND_STATUS;
13597
13598 if (strcasecmp(val, "Add") == 0) {
13599 len = snprintf(pos, rem_len, " scs_id=%s add",
13600 scs_id);
13601 } else if (strcasecmp(val, "Change") == 0) {
13602 len = snprintf(pos, rem_len, " scs_id=%s change",
13603 scs_id);
13604 } else if (strcasecmp(val, "Remove") == 0) {
13605 len = snprintf(pos, rem_len, " scs_id=%s remove",
13606 scs_id);
13607 if (len < 0 || len >= rem_len)
13608 goto fail;
13609
13610 pos += len;
13611 rem_len -= len;
13612 goto scs_desc_end;
13613 } else {
13614 sigma_dut_print(dut, DUT_MSG_ERROR,
13615 "%s: request type - %s is invalid",
13616 __func__, val);
13617 return INVALID_SEND_STATUS;
13618 }
13619
13620 if (len < 0 || len >= rem_len)
13621 goto fail;
13622
13623 pos += len;
13624 rem_len -= len;
13625
13626 val = get_param_fmt(cmd, "IntraAccessCatElem_UP_%d",
13627 num_of_scs_desc);
13628 if (!val) {
13629 sigma_dut_print(dut, DUT_MSG_ERROR,
13630 "IntraAccess Priority empty");
13631 return INVALID_SEND_STATUS;
13632 }
13633
13634 len = snprintf(pos, rem_len, " scs_up=%s", val);
13635 if (len < 0 || len >= rem_len)
13636 goto fail;
13637
13638 pos += len;
13639 rem_len -= len;
13640
13641 classifier_type = get_param_fmt(cmd,
13642 "TCLASElem_ClassifierType_%d_1",
13643 num_of_scs_desc);
13644 if (!classifier_type) {
13645 sigma_dut_print(dut, DUT_MSG_ERROR,
13646 "classifier type missing");
13647 return INVALID_SEND_STATUS;
13648 }
13649
13650 while (classifier_type) {
13651 num_of_tclas_elem++;
13652
13653 len = snprintf(pos, rem_len, " classifier_type=%s",
13654 classifier_type);
13655 if (len < 0 || len >= rem_len)
13656 goto fail;
13657
13658 pos += len;
13659 rem_len -= len;
13660
13661 if (strcmp(classifier_type, "10") == 0) {
13662 total_bytes = get_type10_frame_classifier(
13663 dut, cmd, pos, rem_len,
13664 num_of_scs_desc,
13665 num_of_tclas_elem);
13666 } else if (strcmp(classifier_type, "4") == 0) {
13667 total_bytes = get_type4_frame_classifier(
13668 dut, cmd, pos, rem_len,
13669 num_of_scs_desc,
13670 num_of_tclas_elem);
13671 } else {
13672 sigma_dut_print(dut, DUT_MSG_ERROR,
13673 "classifier_type invalid");
13674 goto fail;
13675 }
13676
13677 if (total_bytes < 0)
13678 goto fail;
13679
13680 pos += total_bytes;
13681 rem_len -= total_bytes;
13682
13683 classifier_type = get_param_fmt(
13684 cmd, "TCLASElem_ClassifierType_%d_%d",
13685 num_of_scs_desc, num_of_tclas_elem + 1);
13686 }
13687
13688 if (num_of_tclas_elem > 1) {
13689 val = get_param_fmt(cmd,
13690 "TCLASProcessingElem_Processing_%d",
13691 num_of_scs_desc);
13692 if (!val) {
13693 sigma_dut_print(dut, DUT_MSG_ERROR,
13694 "Tclas_processing element %d empty",
13695 num_of_scs_desc);
13696 goto fail;
13697 }
13698
13699 len = snprintf(pos, rem_len,
13700 " tclas_processing=%s", val);
13701 if (len < 0 || len >= rem_len)
13702 goto fail;
13703
13704 pos += len;
13705 rem_len -= len;
13706 }
13707scs_desc_end:
13708 num_of_tclas_elem = 0;
13709 scs_id = get_param_fmt(cmd, "SCSDescrElem_SCSID_%d",
13710 num_of_scs_desc + 1);
13711 }
13712
13713 if (wpa_command(intf, buf) != 0) {
13714 send_resp(dut, conn, SIGMA_ERROR,
13715 "ErrorCode,Failed to send SCS frame request");
13716 return STATUS_SENT_ERROR;
13717 }
13718
13719 sigma_dut_print(dut, DUT_MSG_DEBUG,
13720 "SCS frame request sent: %s", buf);
13721
13722 return SUCCESS_SEND_STATUS;
13723fail:
13724 sigma_dut_print(dut, DUT_MSG_ERROR,
13725 "Failed to create SCS frame request");
13726 return ERROR_SEND_STATUS;
13727}
13728
13729
Vinita S. Malooee9e7e92020-04-28 16:26:50 +053013730static enum sigma_cmd_result
13731cmd_sta_send_frame_mscs(struct sigma_dut *dut, struct sigma_conn *conn,
13732 const char *intf, struct sigma_cmd *cmd)
13733{
13734 char buf[128], *pos;
13735 const char *val, *classifier_type = "04", *type;
13736 int len, rem_len;
13737 u8 up_bitmap;
13738
Vinita S. Malooee9e7e92020-04-28 16:26:50 +053013739 type = get_param(cmd, "Request_Type");
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013740 if (!type) {
Vinita S. Malooee9e7e92020-04-28 16:26:50 +053013741 sigma_dut_print(dut, DUT_MSG_ERROR,
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013742 "%s: type not valid", __func__);
Vinita S. Malooee9e7e92020-04-28 16:26:50 +053013743 return INVALID_SEND_STATUS;
13744 }
13745
13746 rem_len = sizeof(buf);
13747 pos = buf;
13748 if (strcasecmp(type, "add") == 0) {
13749 len = snprintf(pos, rem_len, "MSCS add");
13750 } else if (strcasecmp(type, "update") == 0) {
13751 len = snprintf(pos, rem_len, "MSCS change");
13752 } else if (strcasecmp(type, "remove") == 0) {
13753 if (wpa_command(intf, "MSCS remove") != 0) {
13754 send_resp(dut, conn, SIGMA_ERROR,
13755 "ErrorCode,Failed to send MSCS frame req");
13756 return STATUS_SENT_ERROR;
13757 }
13758 return SUCCESS_SEND_STATUS;
13759 } else {
13760 sigma_dut_print(dut, DUT_MSG_ERROR,
13761 "%s: request type invalid", __func__);
13762 return INVALID_SEND_STATUS;
13763 }
13764
13765 if (len < 0 || len >= rem_len)
13766 goto fail;
13767
13768 pos += len;
13769 rem_len -= len;
13770
13771 val = get_param(cmd, "User_Priority_Bitmap");
13772 if (!val) {
13773 sigma_dut_print(dut, DUT_MSG_ERROR,
13774 "%s: user priority bitmap empty", __func__);
13775 return INVALID_SEND_STATUS;
13776 }
13777
13778 switch (atoi(val)) {
13779 case 0:
13780 up_bitmap = 0x00;
13781 break;
13782 case 1:
13783 up_bitmap = 0xF0;
13784 break;
13785 case 2:
13786 up_bitmap = 0xF6;
13787 break;
13788 default:
13789 sigma_dut_print(dut, DUT_MSG_ERROR,
13790 "%s: Unknown User_Priority_Bitmap value %d",
13791 __func__, atoi(val));
13792 return INVALID_SEND_STATUS;
13793 }
13794
13795 len = snprintf(pos, rem_len, " up_bitmap=%02x", up_bitmap);
13796 if (len < 0 || len >= rem_len)
13797 goto fail;
13798
13799 pos += len;
13800 rem_len -= len;
13801
13802 val = get_param(cmd, "User_Priority_Limit");
13803 if (!val) {
13804 sigma_dut_print(dut, DUT_MSG_ERROR,
13805 "%s: invalid user priority limit", __func__);
13806 return INVALID_SEND_STATUS;
13807 }
13808
13809 len = snprintf(pos, rem_len, " up_limit=%s", val);
13810 if (len < 0 || len >= rem_len)
13811 goto fail;
13812
13813 pos += len;
13814 rem_len -= len;
13815
13816 val = get_param(cmd, "Stream_Timeout");
13817 if (!val)
13818 val = get_param(cmd, "Stream_Timtout");
13819 if (!val) {
13820 sigma_dut_print(dut, DUT_MSG_ERROR,
13821 "%s: invalid stream timeout", __func__);
13822 return INVALID_SEND_STATUS;
13823 }
13824
13825 len = snprintf(pos, rem_len, " stream_timeout=%s", val);
13826 if (len < 0 || len >= rem_len)
13827 goto fail;
13828
13829 pos += len;
13830 rem_len -= len;
13831
13832 val = get_param(cmd, "TCLAS_Mask");
13833 if (!val) {
13834 sigma_dut_print(dut, DUT_MSG_ERROR,
13835 "%s: invalid tclas mask", __func__);
13836 return INVALID_SEND_STATUS;
13837 }
13838
13839 len = snprintf(pos, rem_len, " frame_classifier=%s%lx%032x",
13840 classifier_type, strtol(val, NULL, 2), 0);
13841 if (len < 0 || len >= rem_len)
13842 goto fail;
13843
13844 if (wpa_command(intf, buf) != 0) {
13845 send_resp(dut, conn, SIGMA_ERROR,
13846 "ErrorCode,Failed to send MSCS frame req");
13847 return STATUS_SENT_ERROR;
13848 }
13849
13850 sigma_dut_print(dut, DUT_MSG_DEBUG,
13851 "MSCS frame request sent: %s", buf);
13852
13853 return SUCCESS_SEND_STATUS;
13854fail:
13855 sigma_dut_print(dut, DUT_MSG_ERROR,
13856 "Failed to create MSCS frame req");
13857 return ERROR_SEND_STATUS;
13858}
13859
13860
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013861static enum sigma_cmd_result
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053013862cmd_sta_send_frame_dscp_query(struct sigma_dut *dut, struct sigma_conn *conn,
13863 const char *intf, struct sigma_cmd *cmd)
13864{
13865 char buf[150], *pos;
13866 const char *val;
13867 int len, rem_len;
13868
13869 rem_len = sizeof(buf);
13870 pos = buf;
13871
13872 len = snprintf(pos, rem_len, "DSCP_QUERY");
13873 if (len < 0 || len >= rem_len)
13874 goto fail;
13875
13876 pos += len;
13877 rem_len -= len;
13878
13879 val = get_param(cmd, "Wildcard");
13880 if (val && strcasecmp(val, "Yes") == 0) {
13881 len = snprintf(pos, rem_len, " wildcard");
13882 if (len < 0 || len >= rem_len)
13883 goto fail;
13884 } else if (strlen(dut->qm_domain_name)) {
13885 len = snprintf(pos, rem_len, " domain_name=%s",
13886 dut->qm_domain_name);
13887 if (len < 0 || len >= rem_len)
13888 goto fail;
13889 } else {
13890 sigma_dut_print(dut, DUT_MSG_ERROR,
13891 "Invalid DSCP Query configuration");
13892 return INVALID_SEND_STATUS;
13893 }
13894
13895 if (wpa_command(intf, buf) != 0) {
13896 send_resp(dut, conn, SIGMA_ERROR,
13897 "ErrorCode,Failed to send DSCP policy query frame");
13898 return STATUS_SENT_ERROR;
13899 }
13900
13901 sigma_dut_print(dut, DUT_MSG_DEBUG,
13902 "DSCP policy query frame sent: %s", buf);
13903 return SUCCESS_SEND_STATUS;
13904fail:
13905 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to send DSCP query");
13906 return ERROR_SEND_STATUS;
13907}
13908
13909
13910static enum sigma_cmd_result
Veerendranath Jakkam1bf1bd62021-09-12 16:35:55 +053013911cmd_sta_send_frame_dscp_response(struct sigma_dut *dut, struct sigma_conn *conn,
13912 const char *intf, struct sigma_cmd *cmd)
13913{
13914 char buf[256], *pos, *item, *list, *saveptr;
13915 const char *val;
13916 int len, rem_len;
13917
13918 pos = buf;
13919 rem_len = sizeof(buf);
13920
13921 len = snprintf(pos, rem_len, "DSCP_RESP");
13922 if (snprintf_error(rem_len, len)) {
13923 sigma_dut_print(dut, DUT_MSG_ERROR,
13924 "Failed to create DSCP Policy Response command");
13925 return ERROR_SEND_STATUS;
13926 }
13927
13928 pos += len;
13929 rem_len -= len;
13930
13931 val = get_param(cmd, "PolicyID_List");
13932 if (!val) {
13933 sigma_dut_print(dut, DUT_MSG_ERROR,
13934 "DSCP policy ID list missing");
13935 return INVALID_SEND_STATUS;
13936 }
13937
13938 list = strdup(val);
13939 if (!list)
13940 return ERROR_SEND_STATUS;
13941
13942 item = strtok_r(list, "_", &saveptr);
13943 while (item) {
13944 unsigned int i;
13945 int policy_id = atoi(item);
13946
13947 for (i = 0; i < dut->num_dscp_status; i++)
13948 if (dut->dscp_status[i].id == policy_id)
13949 break;
13950
13951 if (i == dut->num_dscp_status) {
13952 free(list);
13953 send_resp(dut, conn, SIGMA_ERROR,
13954 "ErrorCode,DSCP policy id not found in status list");
13955 return STATUS_SENT_ERROR;
13956 }
13957
13958 len = snprintf(pos, rem_len, " policy_id=%d status=%d",
13959 policy_id, dut->dscp_status[i].status);
13960 if (snprintf_error(rem_len, len)) {
13961 free(list);
13962 sigma_dut_print(dut, DUT_MSG_ERROR,
13963 "Failed to write DSCP policy list");
13964 return ERROR_SEND_STATUS;
13965 }
13966
13967 pos += len;
13968 rem_len -= len;
13969
13970 if (dut->dscp_status[i].status)
13971 remove_dscp_policy(dut, policy_id);
13972
13973 item = strtok_r(NULL, "_", &saveptr);
13974 }
13975
13976 free(list);
13977
13978 if (wpa_command(intf, buf) != 0) {
13979 send_resp(dut, conn, SIGMA_ERROR,
13980 "ErrorCode,Failed to send DSCP Policy Response frame");
13981 return STATUS_SENT_ERROR;
13982 }
13983
13984 sigma_dut_print(dut, DUT_MSG_DEBUG,
13985 "DSCP Policy Response frame sent: %s", buf);
13986 return SUCCESS_SEND_STATUS;
13987}
13988
13989
13990static enum sigma_cmd_result
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013991cmd_sta_send_frame_qm(struct sigma_dut *dut, struct sigma_conn *conn,
13992 const char *intf, struct sigma_cmd *cmd)
13993{
13994 const char *val;
13995
13996 val = get_param(cmd, "FrameName");
13997 if (val) {
13998 if (strcasecmp(val, "MSCSReq") == 0)
13999 return cmd_sta_send_frame_mscs(dut, conn, intf, cmd);
14000 if (strcasecmp(val, "SCSReq") == 0)
14001 return cmd_sta_send_frame_scs(dut, conn, intf, cmd);
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053014002 if (strcasecmp(val, "DSCPPolicyQuery") == 0)
14003 return cmd_sta_send_frame_dscp_query(dut, conn, intf,
14004 cmd);
Veerendranath Jakkam1bf1bd62021-09-12 16:35:55 +053014005 if (strcasecmp(val, "DSCPPolicyResponse") == 0)
14006 return cmd_sta_send_frame_dscp_response(dut, conn, intf,
14007 cmd);
Vinita S. Malooca85fd22021-01-15 02:54:34 +053014008
14009 sigma_dut_print(dut, DUT_MSG_ERROR,
14010 "%s: frame name - %s is invalid",
14011 __func__, val);
14012 }
14013
14014 return INVALID_SEND_STATUS;
14015}
14016
14017
Jouni Malinenf7222712019-06-13 01:50:21 +030014018enum sigma_cmd_result cmd_sta_send_frame(struct sigma_dut *dut,
14019 struct sigma_conn *conn,
14020 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014021{
14022 const char *intf = get_param(cmd, "Interface");
14023 const char *val;
14024 enum send_frame_type frame;
14025 enum send_frame_protection protected;
14026 char buf[100];
14027 unsigned char addr[ETH_ALEN];
14028 int res;
14029
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +030014030 if (!intf)
14031 return -1;
14032
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014033 val = get_param(cmd, "program");
14034 if (val == NULL)
14035 val = get_param(cmd, "frame");
14036 if (val && strcasecmp(val, "TDLS") == 0)
14037 return cmd_sta_send_frame_tdls(dut, conn, cmd);
14038 if (val && (strcasecmp(val, "HS2") == 0 ||
Jouni Malinen1f6ae642018-06-07 23:56:13 +030014039 strcasecmp(val, "HS2-R2") == 0 ||
Jouni Malinen9a742ff2022-01-27 00:43:14 +020014040 strcasecmp(val, "HS2-R3") == 0 ||
14041 strcasecmp(val, "HS2-R4") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014042 return cmd_sta_send_frame_hs2(dut, conn, cmd);
14043 if (val && strcasecmp(val, "VHT") == 0)
14044 return cmd_sta_send_frame_vht(dut, conn, cmd);
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070014045 if (val && strcasecmp(val, "HE") == 0)
14046 return cmd_sta_send_frame_he(dut, conn, cmd);
priyadharshini gowthamand66913a2016-07-29 15:11:17 -070014047 if (val && strcasecmp(val, "LOC") == 0)
14048 return loc_cmd_sta_send_frame(dut, conn, cmd);
Lior David0fe101e2017-03-09 16:09:50 +020014049 if (val && strcasecmp(val, "60GHz") == 0)
14050 return cmd_sta_send_frame_60g(dut, conn, cmd);
Ashwini Patildb59b3c2017-04-13 15:19:23 +053014051 if (val && strcasecmp(val, "MBO") == 0) {
14052 res = mbo_cmd_sta_send_frame(dut, conn, intf, cmd);
14053 if (res != 2)
14054 return res;
14055 }
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +053014056 if (val && strcasecmp(val, "WPA3") == 0)
14057 return cmd_sta_send_frame_wpa3(dut, conn, intf, cmd);
Vinita S. Malooee9e7e92020-04-28 16:26:50 +053014058 if (val && strcasecmp(val, "QM") == 0)
Vinita S. Malooca85fd22021-01-15 02:54:34 +053014059 return cmd_sta_send_frame_qm(dut, conn, intf, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014060
14061 val = get_param(cmd, "TD_DISC");
14062 if (val) {
14063 if (hwaddr_aton(val, addr) < 0)
14064 return -1;
14065 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", val);
14066 if (wpa_command(intf, buf) < 0) {
14067 send_resp(dut, conn, SIGMA_ERROR,
14068 "ErrorCode,Failed to send TDLS discovery");
14069 return 0;
14070 }
14071 return 1;
14072 }
14073
14074 val = get_param(cmd, "TD_Setup");
14075 if (val) {
14076 if (hwaddr_aton(val, addr) < 0)
14077 return -1;
14078 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", val);
14079 if (wpa_command(intf, buf) < 0) {
14080 send_resp(dut, conn, SIGMA_ERROR,
14081 "ErrorCode,Failed to start TDLS setup");
14082 return 0;
14083 }
14084 return 1;
14085 }
14086
14087 val = get_param(cmd, "TD_TearDown");
14088 if (val) {
14089 if (hwaddr_aton(val, addr) < 0)
14090 return -1;
14091 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", val);
14092 if (wpa_command(intf, buf) < 0) {
14093 send_resp(dut, conn, SIGMA_ERROR,
14094 "ErrorCode,Failed to tear down TDLS link");
14095 return 0;
14096 }
14097 return 1;
14098 }
14099
14100 val = get_param(cmd, "TD_ChannelSwitch");
14101 if (val) {
14102 /* TODO */
14103 send_resp(dut, conn, SIGMA_ERROR,
14104 "ErrorCode,TD_ChannelSwitch not yet supported");
14105 return 0;
14106 }
14107
14108 val = get_param(cmd, "TD_NF");
14109 if (val) {
14110 /* TODO */
14111 send_resp(dut, conn, SIGMA_ERROR,
14112 "ErrorCode,TD_NF not yet supported");
14113 return 0;
14114 }
14115
14116 val = get_param(cmd, "PMFFrameType");
14117 if (val == NULL)
14118 val = get_param(cmd, "FrameName");
14119 if (val == NULL)
14120 val = get_param(cmd, "Type");
14121 if (val == NULL)
14122 return -1;
14123 if (strcasecmp(val, "disassoc") == 0)
14124 frame = DISASSOC;
14125 else if (strcasecmp(val, "deauth") == 0)
14126 frame = DEAUTH;
14127 else if (strcasecmp(val, "saquery") == 0)
14128 frame = SAQUERY;
14129 else if (strcasecmp(val, "auth") == 0)
14130 frame = AUTH;
14131 else if (strcasecmp(val, "assocreq") == 0)
14132 frame = ASSOCREQ;
14133 else if (strcasecmp(val, "reassocreq") == 0)
14134 frame = REASSOCREQ;
14135 else if (strcasecmp(val, "neigreq") == 0) {
14136 sigma_dut_print(dut, DUT_MSG_INFO, "Got neighbor request");
14137
14138 val = get_param(cmd, "ssid");
14139 if (val == NULL)
14140 return -1;
14141
14142 res = send_neighbor_request(dut, intf, val);
14143 if (res) {
14144 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
14145 "Failed to send neighbor report request");
14146 return 0;
14147 }
14148
14149 return 1;
Ashwini Patil5acd7382017-04-13 15:55:04 +053014150 } else if (strcasecmp(val, "transmgmtquery") == 0 ||
14151 strcasecmp(val, "BTMQuery") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014152 sigma_dut_print(dut, DUT_MSG_DEBUG,
14153 "Got Transition Management Query");
14154
Ashwini Patil5acd7382017-04-13 15:55:04 +053014155 res = send_trans_mgmt_query(dut, intf, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014156 if (res) {
14157 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
14158 "Failed to send Transition Management Query");
14159 return 0;
14160 }
14161
14162 return 1;
14163 } else {
14164 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
14165 "PMFFrameType");
14166 return 0;
14167 }
14168
14169 val = get_param(cmd, "PMFProtected");
14170 if (val == NULL)
14171 val = get_param(cmd, "Protected");
14172 if (val == NULL)
14173 return -1;
14174 if (strcasecmp(val, "Correct-key") == 0 ||
14175 strcasecmp(val, "CorrectKey") == 0)
14176 protected = CORRECT_KEY;
14177 else if (strcasecmp(val, "IncorrectKey") == 0)
14178 protected = INCORRECT_KEY;
14179 else if (strcasecmp(val, "Unprotected") == 0)
14180 protected = UNPROTECTED;
14181 else {
14182 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
14183 "PMFProtected");
14184 return 0;
14185 }
14186
14187 if (protected != UNPROTECTED &&
14188 (frame == AUTH || frame == ASSOCREQ || frame == REASSOCREQ)) {
14189 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Impossible "
14190 "PMFProtected for auth/assocreq/reassocreq");
14191 return 0;
14192 }
14193
14194 if (if_nametoindex("sigmadut") == 0) {
14195 snprintf(buf, sizeof(buf),
14196 "iw dev %s interface add sigmadut type monitor",
Jouni Malinen016ae6c2019-11-04 17:00:01 +020014197 get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014198 if (system(buf) != 0 ||
14199 if_nametoindex("sigmadut") == 0) {
14200 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
14201 "monitor interface with '%s'", buf);
14202 return -2;
14203 }
14204 }
14205
14206 if (system("ifconfig sigmadut up") != 0) {
14207 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
14208 "monitor interface up");
14209 return -2;
14210 }
14211
Veerendranath Jakkam49774122020-07-05 09:52:18 +053014212 return sta_inject_frame(dut, conn, intf, frame, protected, NULL, 1);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014213}
14214
14215
14216static int cmd_sta_set_parameter_hs2(struct sigma_dut *dut,
14217 struct sigma_conn *conn,
14218 struct sigma_cmd *cmd,
14219 const char *ifname)
14220{
14221 char buf[200];
14222 const char *val;
14223
14224 val = get_param(cmd, "ClearARP");
14225 if (val && atoi(val) == 1) {
14226 snprintf(buf, sizeof(buf), "ip neigh flush dev %s", ifname);
14227 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14228 if (system(buf) != 0) {
14229 send_resp(dut, conn, SIGMA_ERROR,
14230 "errorCode,Failed to clear ARP cache");
14231 return 0;
14232 }
14233 }
14234
14235 return 1;
14236}
14237
14238
14239int cmd_sta_set_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
14240 struct sigma_cmd *cmd)
14241{
14242 const char *intf = get_param(cmd, "Interface");
14243 const char *val;
14244
14245 if (intf == NULL)
14246 return -1;
14247
14248 val = get_param(cmd, "program");
14249 if (val && (strcasecmp(val, "HS2") == 0 ||
Jouni Malinen1f6ae642018-06-07 23:56:13 +030014250 strcasecmp(val, "HS2-R2") == 0 ||
Jouni Malinen9a742ff2022-01-27 00:43:14 +020014251 strcasecmp(val, "HS2-R3") == 0 ||
14252 strcasecmp(val, "HS2-R4") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014253 return cmd_sta_set_parameter_hs2(dut, conn, cmd, intf);
14254
14255 return -1;
14256}
14257
14258
Jouni Malinenf7222712019-06-13 01:50:21 +030014259static enum sigma_cmd_result cmd_sta_set_macaddr(struct sigma_dut *dut,
14260 struct sigma_conn *conn,
14261 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014262{
14263 const char *intf = get_param(cmd, "Interface");
14264 const char *mac = get_param(cmd, "MAC");
14265
14266 if (intf == NULL || mac == NULL)
14267 return -1;
14268
14269 sigma_dut_print(dut, DUT_MSG_INFO, "Change local MAC address for "
14270 "interface %s to %s", intf, mac);
14271
14272 if (dut->set_macaddr) {
14273 char buf[128];
14274 int res;
14275 if (strcasecmp(mac, "default") == 0) {
14276 res = snprintf(buf, sizeof(buf), "%s",
14277 dut->set_macaddr);
14278 dut->tmp_mac_addr = 0;
14279 } else {
14280 res = snprintf(buf, sizeof(buf), "%s %s",
14281 dut->set_macaddr, mac);
14282 dut->tmp_mac_addr = 1;
14283 }
14284 if (res < 0 || res >= (int) sizeof(buf))
14285 return -1;
14286 if (system(buf) != 0) {
14287 send_resp(dut, conn, SIGMA_ERROR,
14288 "errorCode,Failed to set MAC "
14289 "address");
14290 return 0;
14291 }
14292 return 1;
14293 }
14294
14295 if (strcasecmp(mac, "default") == 0)
14296 return 1;
14297
14298 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
14299 "command");
14300 return 0;
14301}
14302
14303
14304static int iwpriv_tdlsoffchnmode(struct sigma_dut *dut,
14305 struct sigma_conn *conn, const char *intf,
14306 int val)
14307{
14308 char buf[200];
14309 int res;
14310
14311 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchnmode %d",
14312 intf, val);
14313 if (res < 0 || res >= (int) sizeof(buf))
14314 return -1;
14315 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14316 if (system(buf) != 0) {
14317 send_resp(dut, conn, SIGMA_ERROR,
14318 "errorCode,Failed to configure offchannel mode");
14319 return 0;
14320 }
14321
14322 return 1;
14323}
14324
14325
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014326static int off_chan_val(enum sec_ch_offset off)
14327{
14328 switch (off) {
14329 case SEC_CH_NO:
14330 return 0;
14331 case SEC_CH_40ABOVE:
14332 return 40;
14333 case SEC_CH_40BELOW:
14334 return -40;
14335 }
14336
14337 return 0;
14338}
14339
14340
14341static int iwpriv_set_offchan(struct sigma_dut *dut, struct sigma_conn *conn,
14342 const char *intf, int off_ch_num,
14343 enum sec_ch_offset sec)
14344{
14345 char buf[200];
14346 int res;
14347
14348 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchan %d",
14349 intf, off_ch_num);
14350 if (res < 0 || res >= (int) sizeof(buf))
14351 return -1;
14352 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14353 if (system(buf) != 0) {
14354 send_resp(dut, conn, SIGMA_ERROR,
14355 "errorCode,Failed to set offchan");
14356 return 0;
14357 }
14358
14359 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsecchnoffst %d",
14360 intf, off_chan_val(sec));
14361 if (res < 0 || res >= (int) sizeof(buf))
14362 return -1;
14363 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14364 if (system(buf) != 0) {
14365 send_resp(dut, conn, SIGMA_ERROR,
14366 "errorCode,Failed to set sec chan offset");
14367 return 0;
14368 }
14369
14370 return 1;
14371}
14372
14373
14374static int tdls_set_offchannel_offset(struct sigma_dut *dut,
14375 struct sigma_conn *conn,
14376 const char *intf, int off_ch_num,
14377 enum sec_ch_offset sec)
14378{
14379 char buf[200];
14380 int res;
14381
14382 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNEL %d",
14383 off_ch_num);
14384 if (res < 0 || res >= (int) sizeof(buf))
14385 return -1;
14386 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14387
14388 if (wpa_command(intf, buf) < 0) {
14389 send_resp(dut, conn, SIGMA_ERROR,
14390 "ErrorCode,Failed to set offchan");
14391 return 0;
14392 }
14393 res = snprintf(buf, sizeof(buf), "DRIVER TDLSSECONDARYCHANNELOFFSET %d",
14394 off_chan_val(sec));
14395 if (res < 0 || res >= (int) sizeof(buf))
14396 return -1;
14397
14398 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14399
14400 if (wpa_command(intf, buf) < 0) {
14401 send_resp(dut, conn, SIGMA_ERROR,
14402 "ErrorCode,Failed to set sec chan offset");
14403 return 0;
14404 }
14405
14406 return 1;
14407}
14408
14409
14410static int tdls_set_offchannel_mode(struct sigma_dut *dut,
14411 struct sigma_conn *conn,
14412 const char *intf, int val)
14413{
14414 char buf[200];
14415 int res;
14416
14417 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNELMODE %d",
14418 val);
14419 if (res < 0 || res >= (int) sizeof(buf))
14420 return -1;
14421 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14422
14423 if (wpa_command(intf, buf) < 0) {
14424 send_resp(dut, conn, SIGMA_ERROR,
14425 "ErrorCode,Failed to configure offchannel mode");
14426 return 0;
14427 }
14428
14429 return 1;
14430}
14431
14432
14433static int cmd_sta_set_rfeature_tdls(const char *intf, struct sigma_dut *dut,
14434 struct sigma_conn *conn,
14435 struct sigma_cmd *cmd)
14436{
14437 const char *val;
14438 enum {
14439 CHSM_NOT_SET,
14440 CHSM_ENABLE,
14441 CHSM_DISABLE,
14442 CHSM_REJREQ,
14443 CHSM_UNSOLRESP
14444 } chsm = CHSM_NOT_SET;
14445 int off_ch_num = -1;
14446 enum sec_ch_offset sec_ch = SEC_CH_NO;
14447 int res;
14448
14449 val = get_param(cmd, "Uapsd");
14450 if (val) {
14451 char buf[100];
14452 if (strcasecmp(val, "Enable") == 0)
14453 snprintf(buf, sizeof(buf), "SET ps 99");
14454 else if (strcasecmp(val, "Disable") == 0)
14455 snprintf(buf, sizeof(buf), "SET ps 98");
14456 else {
14457 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
14458 "Unsupported uapsd parameter value");
14459 return 0;
14460 }
14461 if (wpa_command(intf, buf)) {
14462 send_resp(dut, conn, SIGMA_ERROR,
14463 "ErrorCode,Failed to change U-APSD "
14464 "powersave mode");
14465 return 0;
14466 }
14467 }
14468
14469 val = get_param(cmd, "TPKTIMER");
14470 if (val && strcasecmp(val, "DISABLE") == 0) {
14471 if (wpa_command(intf, "SET tdls_testing 0x100")) {
14472 send_resp(dut, conn, SIGMA_ERROR,
14473 "ErrorCode,Failed to enable no TPK "
14474 "expiration test mode");
14475 return 0;
14476 }
14477 dut->no_tpk_expiration = 1;
14478 }
14479
14480 val = get_param(cmd, "ChSwitchMode");
14481 if (val) {
14482 if (strcasecmp(val, "Enable") == 0 ||
14483 strcasecmp(val, "Initiate") == 0)
14484 chsm = CHSM_ENABLE;
14485 else if (strcasecmp(val, "Disable") == 0 ||
14486 strcasecmp(val, "passive") == 0)
14487 chsm = CHSM_DISABLE;
14488 else if (strcasecmp(val, "RejReq") == 0)
14489 chsm = CHSM_REJREQ;
14490 else if (strcasecmp(val, "UnSolResp") == 0)
14491 chsm = CHSM_UNSOLRESP;
14492 else {
14493 send_resp(dut, conn, SIGMA_ERROR,
14494 "ErrorCode,Unknown ChSwitchMode value");
14495 return 0;
14496 }
14497 }
14498
14499 val = get_param(cmd, "OffChNum");
14500 if (val) {
14501 off_ch_num = atoi(val);
14502 if (off_ch_num == 0) {
14503 send_resp(dut, conn, SIGMA_ERROR,
14504 "ErrorCode,Invalid OffChNum");
14505 return 0;
14506 }
14507 }
14508
14509 val = get_param(cmd, "SecChOffset");
14510 if (val) {
14511 if (strcmp(val, "20") == 0)
14512 sec_ch = SEC_CH_NO;
14513 else if (strcasecmp(val, "40above") == 0)
14514 sec_ch = SEC_CH_40ABOVE;
14515 else if (strcasecmp(val, "40below") == 0)
14516 sec_ch = SEC_CH_40BELOW;
14517 else {
14518 send_resp(dut, conn, SIGMA_ERROR,
14519 "ErrorCode,Unknown SecChOffset value");
14520 return 0;
14521 }
14522 }
14523
14524 if (chsm == CHSM_NOT_SET) {
14525 /* no offchannel changes requested */
14526 return 1;
14527 }
14528
Jouni Malinen016ae6c2019-11-04 17:00:01 +020014529 if (strcmp(intf, get_main_ifname(dut)) != 0 &&
14530 strcmp(intf, get_station_ifname(dut)) != 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014531 send_resp(dut, conn, SIGMA_ERROR,
14532 "ErrorCode,Unknown interface");
14533 return 0;
14534 }
14535
14536 switch (chsm) {
14537 case CHSM_NOT_SET:
Jouni Malinen280f5ba2016-08-29 21:33:10 +030014538 res = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014539 break;
14540 case CHSM_ENABLE:
14541 if (off_ch_num < 0) {
14542 send_resp(dut, conn, SIGMA_ERROR,
14543 "ErrorCode,Missing OffChNum argument");
14544 return 0;
14545 }
14546 if (wifi_chip_type == DRIVER_WCN) {
14547 res = tdls_set_offchannel_offset(dut, conn, intf,
14548 off_ch_num, sec_ch);
14549 } else {
14550 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
14551 sec_ch);
14552 }
14553 if (res != 1)
14554 return res;
14555 if (wifi_chip_type == DRIVER_WCN)
14556 res = tdls_set_offchannel_mode(dut, conn, intf, 1);
14557 else
14558 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 1);
14559 break;
14560 case CHSM_DISABLE:
14561 if (wifi_chip_type == DRIVER_WCN)
14562 res = tdls_set_offchannel_mode(dut, conn, intf, 2);
14563 else
14564 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 2);
14565 break;
14566 case CHSM_REJREQ:
14567 if (wifi_chip_type == DRIVER_WCN)
14568 res = tdls_set_offchannel_mode(dut, conn, intf, 3);
14569 else
14570 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 3);
14571 break;
14572 case CHSM_UNSOLRESP:
14573 if (off_ch_num < 0) {
14574 send_resp(dut, conn, SIGMA_ERROR,
14575 "ErrorCode,Missing OffChNum argument");
14576 return 0;
14577 }
14578 if (wifi_chip_type == DRIVER_WCN) {
14579 res = tdls_set_offchannel_offset(dut, conn, intf,
14580 off_ch_num, sec_ch);
14581 } else {
14582 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
14583 sec_ch);
14584 }
14585 if (res != 1)
14586 return res;
14587 if (wifi_chip_type == DRIVER_WCN)
14588 res = tdls_set_offchannel_mode(dut, conn, intf, 4);
14589 else
14590 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 4);
14591 break;
14592 }
14593
14594 return res;
14595}
14596
14597
14598static int ath_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
14599 struct sigma_conn *conn,
14600 struct sigma_cmd *cmd)
14601{
14602 const char *val;
Srikanth Marepalli5415acf2018-08-27 12:53:11 +053014603 char *token = NULL, *result;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014604
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -070014605 novap_reset(dut, intf, 1);
priyadharshini gowthamane5e25172015-12-08 14:53:48 -080014606
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014607 val = get_param(cmd, "nss_mcs_opt");
14608 if (val) {
14609 /* String (nss_operating_mode; mcs_operating_mode) */
14610 int nss, mcs;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053014611 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014612
14613 token = strdup(val);
14614 if (!token)
14615 return 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053014616 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +053014617 if (!result) {
14618 sigma_dut_print(dut, DUT_MSG_ERROR,
14619 "VHT NSS not specified");
14620 goto failed;
14621 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014622 if (strcasecmp(result, "def") != 0) {
14623 nss = atoi(result);
14624 if (nss == 4)
14625 ath_disable_txbf(dut, intf);
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070014626 if (run_iwpriv(dut, intf, "nss %d", nss) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014627 goto failed;
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070014628
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014629 }
14630
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053014631 result = strtok_r(NULL, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +053014632 if (!result) {
14633 sigma_dut_print(dut, DUT_MSG_ERROR,
14634 "VHT MCS not specified");
14635 goto failed;
14636 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014637 if (strcasecmp(result, "def") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070014638 if (run_iwpriv(dut, intf, "set11NRates 0") < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014639 goto failed;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014640 } else {
14641 mcs = atoi(result);
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070014642 if (run_iwpriv(dut, intf, "vhtmcs %d", mcs) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014643 goto failed;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014644 }
14645 /* Channel width gets messed up, fix this */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070014646 run_iwpriv(dut, intf, "chwidth %d", dut->chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014647 }
14648
Srikanth Marepalli5415acf2018-08-27 12:53:11 +053014649 free(token);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014650 return 1;
14651failed:
14652 free(token);
14653 return 0;
14654}
14655
14656
14657static int cmd_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
14658 struct sigma_conn *conn,
14659 struct sigma_cmd *cmd)
14660{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020014661 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014662 case DRIVER_ATHEROS:
14663 return ath_sta_set_rfeature_vht(intf, dut, conn, cmd);
14664 default:
14665 send_resp(dut, conn, SIGMA_ERROR,
14666 "errorCode,Unsupported sta_set_rfeature(VHT) with the current driver");
14667 return 0;
14668 }
14669}
14670
14671
Jouni Malinen1702fe32021-06-08 19:08:01 +030014672static enum sigma_cmd_result
14673wcn_sta_set_rfeature_he(const char *intf, struct sigma_dut *dut,
14674 struct sigma_conn *conn, struct sigma_cmd *cmd)
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014675{
14676 const char *val;
14677 char *token = NULL, *result;
14678 char buf[60];
14679
14680 val = get_param(cmd, "nss_mcs_opt");
14681 if (val) {
14682 /* String (nss_operating_mode; mcs_operating_mode) */
14683 int nss, mcs, ratecode;
14684 char *saveptr;
14685
14686 token = strdup(val);
14687 if (!token)
Jouni Malinen1702fe32021-06-08 19:08:01 +030014688 return ERROR_SEND_STATUS;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014689
14690 result = strtok_r(token, ";", &saveptr);
14691 if (!result) {
14692 sigma_dut_print(dut, DUT_MSG_ERROR,
14693 "HE NSS not specified");
14694 goto failed;
14695 }
14696 nss = 1;
14697 if (strcasecmp(result, "def") != 0)
14698 nss = atoi(result);
14699
14700 result = strtok_r(NULL, ";", &saveptr);
14701 if (!result) {
14702 sigma_dut_print(dut, DUT_MSG_ERROR,
14703 "HE MCS not specified");
14704 goto failed;
14705 }
14706 mcs = 7;
14707 if (strcasecmp(result, "def") != 0)
14708 mcs = atoi(result);
14709
Arif Hussain557bf412018-05-25 17:29:36 -070014710 ratecode = 0x20; /* for nss:1 MCS 0 */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014711 if (nss == 2) {
Arif Hussain557bf412018-05-25 17:29:36 -070014712 ratecode = 0x40; /* for nss:2 MCS 0 */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014713 } else if (nss > 2) {
14714 sigma_dut_print(dut, DUT_MSG_ERROR,
14715 "HE NSS %d not supported", nss);
14716 goto failed;
14717 }
14718
Arif Hussain557bf412018-05-25 17:29:36 -070014719 snprintf(buf, sizeof(buf), "iwpriv %s nss %d", intf, nss);
14720 if (system(buf) != 0) {
14721 sigma_dut_print(dut, DUT_MSG_ERROR,
14722 "nss_mcs_opt: iwpriv %s nss %d failed",
14723 intf, nss);
14724 goto failed;
14725 }
Arif Hussainac6c5112018-05-25 17:34:00 -070014726 dut->sta_nss = nss;
Arif Hussain557bf412018-05-25 17:29:36 -070014727
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014728 /* Add the MCS to the ratecode */
14729 if (mcs >= 0 && mcs <= 11) {
14730 ratecode += mcs;
Arif Hussain557bf412018-05-25 17:29:36 -070014731#ifdef NL80211_SUPPORT
14732 if (dut->device_type == STA_testbed) {
14733 enum he_mcs_config mcs_config;
14734 int ret;
14735
14736 if (mcs <= 7)
14737 mcs_config = HE_80_MCS0_7;
14738 else if (mcs <= 9)
14739 mcs_config = HE_80_MCS0_9;
14740 else
14741 mcs_config = HE_80_MCS0_11;
14742 ret = sta_set_he_mcs(dut, intf, mcs_config);
14743 if (ret) {
14744 sigma_dut_print(dut, DUT_MSG_ERROR,
14745 "nss_mcs_opt: mcs setting failed, mcs:%d, mcs_config %d, ret:%d",
14746 mcs, mcs_config, ret);
14747 goto failed;
14748 }
14749 }
14750#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014751 } else {
14752 sigma_dut_print(dut, DUT_MSG_ERROR,
14753 "HE MCS %d not supported", mcs);
14754 goto failed;
14755 }
14756 snprintf(buf, sizeof(buf), "iwpriv %s set_11ax_rate 0x%03x",
14757 intf, ratecode);
14758 if (system(buf) != 0) {
14759 sigma_dut_print(dut, DUT_MSG_ERROR,
14760 "iwpriv setting of 11ax rates failed");
14761 goto failed;
14762 }
14763 free(token);
14764 }
14765
14766 val = get_param(cmd, "GI");
14767 if (val) {
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080014768 int fix_rate_sgi;
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080014769 u8 he_gi_val = 0;
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080014770
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014771 if (strcmp(val, "0.8") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070014772 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 9", intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080014773 fix_rate_sgi = 1;
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080014774 he_gi_val = NL80211_RATE_INFO_HE_GI_0_8;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014775 } else if (strcmp(val, "1.6") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070014776 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 10",
14777 intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080014778 fix_rate_sgi = 2;
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080014779 he_gi_val = NL80211_RATE_INFO_HE_GI_1_6;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014780 } else if (strcmp(val, "3.2") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070014781 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 11",
14782 intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080014783 fix_rate_sgi = 3;
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080014784 he_gi_val = NL80211_RATE_INFO_HE_GI_3_2;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014785 } else {
14786 send_resp(dut, conn, SIGMA_ERROR,
14787 "errorCode,GI value not supported");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014788 return STATUS_SENT_ERROR;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014789 }
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080014790 if (wcn_set_he_gi(dut, intf, he_gi_val)) {
14791 sigma_dut_print(dut, DUT_MSG_INFO,
14792 "wcn_set_he_gi failed, using iwpriv");
14793 if (system(buf) != 0) {
14794 send_resp(dut, conn, SIGMA_ERROR,
14795 "errorCode,Failed to set shortgi");
14796 return STATUS_SENT_ERROR;
14797 }
14798 snprintf(buf, sizeof(buf), "iwpriv %s shortgi %d",
14799 intf, fix_rate_sgi);
14800 if (system(buf) != 0) {
14801 send_resp(dut, conn, SIGMA_ERROR,
14802 "errorCode,Failed to set fix rate shortgi");
14803 return STATUS_SENT_ERROR;
14804 }
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080014805 }
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014806 }
14807
Subhani Shaik8e7a3052018-04-24 14:03:00 -070014808 val = get_param(cmd, "LTF");
14809 if (val) {
14810#ifdef NL80211_SUPPORT
14811 if (strcmp(val, "3.2") == 0) {
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -080014812 wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_1X);
Subhani Shaik8e7a3052018-04-24 14:03:00 -070014813 } if (strcmp(val, "6.4") == 0) {
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -080014814 wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_2X);
Subhani Shaik8e7a3052018-04-24 14:03:00 -070014815 } else if (strcmp(val, "12.8") == 0) {
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -080014816 wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_4X);
Subhani Shaik8e7a3052018-04-24 14:03:00 -070014817 } else {
14818 send_resp(dut, conn, SIGMA_ERROR,
14819 "errorCode, LTF value not supported");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014820 return STATUS_SENT_ERROR;
Subhani Shaik8e7a3052018-04-24 14:03:00 -070014821 }
14822#else /* NL80211_SUPPORT */
14823 sigma_dut_print(dut, DUT_MSG_ERROR,
14824 "LTF cannot be set without NL80211_SUPPORT defined");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014825 return ERROR_SEND_STATUS;
Subhani Shaik8e7a3052018-04-24 14:03:00 -070014826#endif /* NL80211_SUPPORT */
14827 }
14828
Kiran Kumar Lokere1809da12021-06-24 00:45:38 -070014829 val = get_param(cmd, "KeepAlive");
14830 if (val) {
14831 int set_val = QCA_WLAN_KEEP_ALIVE_DEFAULT;
14832
14833 if (strcasecmp(val, "Data") == 0)
14834 set_val = QCA_WLAN_KEEP_ALIVE_DATA;
14835 else if (strcasecmp(val, "Mgmt") == 0)
14836 set_val = QCA_WLAN_KEEP_ALIVE_MGMT;
14837
14838 if (sta_set_keep_alive_data_cfg(dut, intf, set_val)) {
14839 send_resp(dut, conn, SIGMA_ERROR,
14840 "ErrorCode,Failed to set keep alive type config");
14841 return STATUS_SENT_ERROR;
14842 }
14843 }
14844
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -070014845 val = get_param(cmd, "TxSUPPDU");
14846 if (val) {
14847 int set_val = 1;
14848
14849 if (strcasecmp(val, "Enable") == 0)
14850 set_val = 1;
14851 else if (strcasecmp(val, "Disable") == 0)
14852 set_val = 0;
14853
14854 if (sta_set_tx_su_ppdu_cfg(dut, intf, set_val)) {
14855 send_resp(dut, conn, SIGMA_ERROR,
14856 "ErrorCode,Failed to set Tx SU PPDU config");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014857 return STATUS_SENT_ERROR;
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -070014858 }
14859 }
14860
Kiran Kumar Lokere54b72522021-04-01 00:22:44 -070014861 val = get_param(cmd, "Mgmt_Data_TX_Resp_Frame");
14862 if (val) {
14863 int set_val = 0;
14864
14865 if (strcasecmp(val, "Enable") == 0)
14866 set_val = 0;
14867 else if (strcasecmp(val, "Disable") == 0)
14868 set_val = 1;
14869
14870 if (sta_set_mgmt_data_tx_disable_cfg(dut, intf, set_val)) {
14871 send_resp(dut, conn, SIGMA_ERROR,
14872 "ErrorCode,Failed to set mgmt/data Tx disable config");
14873 return STATUS_SENT_ERROR;
14874 }
14875 }
14876
Arif Hussain480d5f42019-03-12 14:40:42 -070014877 val = get_param(cmd, "TWT_Setup");
14878 if (val) {
Kiran Kumar Lokere94829ce2022-01-20 10:49:08 -080014879#ifdef NL80211_SUPPORT
14880 if (dut->sta_async_twt_supp && nl80211_open_event_sock(dut))
14881 sigma_dut_print(dut, DUT_MSG_ERROR,
14882 "Failed to open nl80211 event socket");
14883#endif /* NL80211_SUPPORT */
Arif Hussain480d5f42019-03-12 14:40:42 -070014884 if (strcasecmp(val, "Request") == 0) {
Kiran Kumar Lokereafac46a2021-11-29 14:03:20 -080014885 if (set_power_save_wcn(dut, intf, 1) < 0)
14886 sigma_dut_print(dut, DUT_MSG_ERROR,
14887 "Failed to enable power save");
Arif Hussain480d5f42019-03-12 14:40:42 -070014888 if (sta_twt_request(dut, conn, cmd)) {
14889 send_resp(dut, conn, SIGMA_ERROR,
Srinivas Girigowda6707f032020-10-26 15:24:46 -070014890 "ErrorCode,TWT setup failed");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014891 return STATUS_SENT_ERROR;
Arif Hussain480d5f42019-03-12 14:40:42 -070014892 }
14893 } else if (strcasecmp(val, "Teardown") == 0) {
14894 if (sta_twt_teardown(dut, conn, cmd)) {
14895 send_resp(dut, conn, SIGMA_ERROR,
Srinivas Girigowda6707f032020-10-26 15:24:46 -070014896 "ErrorCode,TWT teardown failed");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014897 return STATUS_SENT_ERROR;
Arif Hussain480d5f42019-03-12 14:40:42 -070014898 }
14899 }
14900 }
14901
Srinivas Girigowda6707f032020-10-26 15:24:46 -070014902 val = get_param(cmd, "TWT_Operation");
14903 if (val) {
Kiran Kumar Lokere94829ce2022-01-20 10:49:08 -080014904#ifdef NL80211_SUPPORT
14905 if (dut->sta_async_twt_supp && nl80211_open_event_sock(dut))
14906 sigma_dut_print(dut, DUT_MSG_ERROR,
14907 "Failed to open nl80211 event socket");
14908#endif /* NL80211_SUPPORT */
Srinivas Girigowda6707f032020-10-26 15:24:46 -070014909 if (strcasecmp(val, "Suspend") == 0) {
14910 if (sta_twt_suspend_or_nudge(dut, conn, cmd)) {
14911 send_resp(dut, conn, SIGMA_ERROR,
14912 "ErrorCode,TWT suspend failed");
14913 return STATUS_SENT_ERROR;
14914 }
14915 } else if (strcasecmp(val, "Resume") == 0) {
14916 if (sta_twt_resume(dut, conn, cmd)) {
14917 send_resp(dut, conn, SIGMA_ERROR,
14918 "ErrorCode,TWT resume failed");
14919 return STATUS_SENT_ERROR;
14920 }
14921 }
14922 }
14923
Kiran Kumar Lokere50eb2cd2018-12-18 18:31:28 -080014924 val = get_param(cmd, "transmitOMI");
14925 if (val && sta_transmit_omi(dut, conn, cmd)) {
14926 send_resp(dut, conn, SIGMA_ERROR,
14927 "ErrorCode,sta_transmit_omi failed");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014928 return STATUS_SENT_ERROR;
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -070014929 }
14930
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080014931 val = get_param(cmd, "Powersave");
14932 if (val) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014933 int ps;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080014934
14935 if (strcasecmp(val, "off") == 0) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014936 ps = 2;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080014937 } else if (strcasecmp(val, "on") == 0) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014938 ps = 1;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080014939 } else {
14940 sigma_dut_print(dut, DUT_MSG_ERROR,
14941 "Unsupported Powersave value '%s'",
14942 val);
Jouni Malinen1702fe32021-06-08 19:08:01 +030014943 return INVALID_SEND_STATUS;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080014944 }
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014945 if (set_power_save_wcn(dut, intf, ps) < 0)
Jouni Malinen1702fe32021-06-08 19:08:01 +030014946 return ERROR_SEND_STATUS;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080014947 }
14948
Kiran Kumar Lokere2c4b7ce2019-01-30 12:02:28 -080014949 val = get_param(cmd, "MU_EDCA");
14950 if (val) {
14951 if (strcasecmp(val, "Override") == 0) {
14952 if (sta_set_mu_edca_override(dut, intf, 1)) {
14953 send_resp(dut, conn, SIGMA_ERROR,
14954 "errorCode,MU EDCA override set failed");
14955 return STATUS_SENT;
14956 }
14957 } else if (strcasecmp(val, "Disable") == 0) {
14958 if (sta_set_mu_edca_override(dut, intf, 0)) {
14959 send_resp(dut, conn, SIGMA_ERROR,
14960 "errorCode,MU EDCA override disable failed");
14961 return STATUS_SENT;
14962 }
14963 }
14964 }
14965
Kiran Kumar Lokerefa7c7b92021-08-09 00:50:55 -070014966 val = get_param(cmd, "RUAllocTone");
14967 if (val && strcasecmp(val, "242") == 0) {
14968 if (sta_set_ru_242_tone_tx(dut, intf, 1)) {
14969 send_resp(dut, conn, SIGMA_ERROR,
14970 "ErrorCode,Failed to set RU 242 tone Tx");
14971 return STATUS_SENT_ERROR;
14972 }
14973 }
14974
14975 val = get_param(cmd, "PPDUTxType");
14976 if (val && strcasecmp(val, "ER-SU") == 0) {
14977 if (sta_set_er_su_ppdu_type_tx(dut, intf, 1)) {
14978 send_resp(dut, conn, SIGMA_ERROR,
14979 "ErrorCode,Failed to set ER-SU PPDU type Tx");
14980 return STATUS_SENT_ERROR;
14981 }
14982 }
14983
Kiran Kumar Lokeredd086642020-06-04 00:29:26 -070014984 val = get_param(cmd, "Ch_Pref");
14985 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
14986 return STATUS_SENT;
14987
14988 val = get_param(cmd, "Cellular_Data_Cap");
14989 if (val && mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
14990 return STATUS_SENT;
14991
Jouni Malinen1702fe32021-06-08 19:08:01 +030014992 return SUCCESS_SEND_STATUS;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014993
14994failed:
14995 free(token);
Jouni Malinen1702fe32021-06-08 19:08:01 +030014996 return ERROR_SEND_STATUS;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014997}
14998
14999
Jouni Malinen1702fe32021-06-08 19:08:01 +030015000static enum sigma_cmd_result
15001cmd_sta_set_rfeature_he(const char *intf, struct sigma_dut *dut,
15002 struct sigma_conn *conn, struct sigma_cmd *cmd)
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080015003{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020015004 switch (get_driver_type(dut)) {
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080015005 case DRIVER_WCN:
15006 return wcn_sta_set_rfeature_he(intf, dut, conn, cmd);
15007 default:
15008 send_resp(dut, conn, SIGMA_ERROR,
15009 "errorCode,Unsupported sta_set_rfeature(HE) with the current driver");
Jouni Malinen1702fe32021-06-08 19:08:01 +030015010 return STATUS_SENT_ERROR;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080015011 }
15012}
15013
15014
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080015015static int cmd_sta_set_power_save_he(const char *intf, struct sigma_dut *dut,
15016 struct sigma_conn *conn,
15017 struct sigma_cmd *cmd)
15018{
15019 const char *val;
15020
15021 val = get_param(cmd, "powersave");
15022 if (val) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053015023 int ps;
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080015024
15025 if (strcasecmp(val, "off") == 0) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053015026 ps = 2;
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080015027 } else if (strcasecmp(val, "on") == 0) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053015028 ps = 1;
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080015029 } else {
15030 sigma_dut_print(dut, DUT_MSG_ERROR,
15031 "Unsupported power save config");
15032 return -1;
15033 }
Vinita S. Malooa8b62722020-04-23 01:45:41 +053015034 if (set_power_save_wcn(dut, intf, ps) < 0)
15035 return 0;
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080015036 return 1;
15037 }
15038
15039 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported command");
15040
15041 return 0;
15042}
15043
15044
Ashwini Patil5acd7382017-04-13 15:55:04 +053015045static int btm_query_candidate_list(struct sigma_dut *dut,
15046 struct sigma_conn *conn,
15047 struct sigma_cmd *cmd)
15048{
15049 const char *bssid, *info, *op_class, *ch, *phy_type, *pref;
15050 int len, ret;
15051 char buf[10];
15052
15053 /*
15054 * Neighbor Report elements format:
15055 * neighbor=<BSSID>,<BSSID Information>,<Operating Class>,
15056 * <Channel Number>,<PHY Type>[,<hexdump of Optional Subelements>]
15057 * eg: neighbor=aa:bb:cc:dd:ee:ff,17,81,6,1,030101
15058 */
15059
15060 bssid = get_param(cmd, "Nebor_BSSID");
15061 if (!bssid) {
15062 send_resp(dut, conn, SIGMA_INVALID,
15063 "errorCode,Nebor_BSSID is missing");
15064 return 0;
15065 }
15066
15067 info = get_param(cmd, "Nebor_Bssid_Info");
15068 if (!info) {
15069 sigma_dut_print(dut, DUT_MSG_INFO,
15070 "Using default value for Nebor_Bssid_Info: %s",
15071 DEFAULT_NEIGHBOR_BSSID_INFO);
15072 info = DEFAULT_NEIGHBOR_BSSID_INFO;
15073 }
15074
15075 op_class = get_param(cmd, "Nebor_Op_Class");
15076 if (!op_class) {
15077 send_resp(dut, conn, SIGMA_INVALID,
15078 "errorCode,Nebor_Op_Class is missing");
15079 return 0;
15080 }
15081
15082 ch = get_param(cmd, "Nebor_Op_Ch");
15083 if (!ch) {
15084 send_resp(dut, conn, SIGMA_INVALID,
15085 "errorCode,Nebor_Op_Ch is missing");
15086 return 0;
15087 }
15088
15089 phy_type = get_param(cmd, "Nebor_Phy_Type");
15090 if (!phy_type) {
15091 sigma_dut_print(dut, DUT_MSG_INFO,
15092 "Using default value for Nebor_Phy_Type: %s",
15093 DEFAULT_NEIGHBOR_PHY_TYPE);
15094 phy_type = DEFAULT_NEIGHBOR_PHY_TYPE;
15095 }
15096
15097 /* Parse optional subelements */
15098 buf[0] = '\0';
15099 pref = get_param(cmd, "Nebor_Pref");
15100 if (pref) {
15101 /* hexdump for preferrence subelement */
15102 ret = snprintf(buf, sizeof(buf), ",0301%02x", atoi(pref));
15103 if (ret < 0 || ret >= (int) sizeof(buf)) {
15104 sigma_dut_print(dut, DUT_MSG_ERROR,
15105 "snprintf failed for optional subelement ret: %d",
15106 ret);
15107 send_resp(dut, conn, SIGMA_ERROR,
15108 "errorCode,snprintf failed for subelement");
15109 return 0;
15110 }
15111 }
15112
15113 if (!dut->btm_query_cand_list) {
15114 dut->btm_query_cand_list = calloc(1, NEIGHBOR_REPORT_SIZE);
15115 if (!dut->btm_query_cand_list) {
15116 send_resp(dut, conn, SIGMA_ERROR,
15117 "errorCode,Failed to allocate memory for btm_query_cand_list");
15118 return 0;
15119 }
15120 }
15121
15122 len = strlen(dut->btm_query_cand_list);
15123 ret = snprintf(dut->btm_query_cand_list + len,
15124 NEIGHBOR_REPORT_SIZE - len, " neighbor=%s,%s,%s,%s,%s%s",
15125 bssid, info, op_class, ch, phy_type, buf);
15126 if (ret < 0 || ret >= NEIGHBOR_REPORT_SIZE - len) {
15127 sigma_dut_print(dut, DUT_MSG_ERROR,
15128 "snprintf failed for neighbor report list ret: %d",
15129 ret);
15130 send_resp(dut, conn, SIGMA_ERROR,
15131 "errorCode,snprintf failed for neighbor report");
15132 free(dut->btm_query_cand_list);
15133 dut->btm_query_cand_list = NULL;
15134 return 0;
15135 }
15136
15137 return 1;
15138}
15139
15140
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020015141int sta_extract_60g_ese(struct sigma_dut *dut, struct sigma_cmd *cmd,
15142 struct sigma_ese_alloc *allocs, int *allocs_size)
15143{
15144 int max_count = *allocs_size;
15145 int count = 0, i;
15146 const char *val;
15147
15148 do {
15149 val = get_param_indexed(cmd, "AllocID", count);
15150 if (val)
15151 count++;
15152 } while (val);
15153
15154 if (count == 0 || count > max_count) {
15155 sigma_dut_print(dut, DUT_MSG_ERROR,
15156 "Invalid number of allocations(%d)", count);
15157 return -1;
15158 }
15159
15160 for (i = 0; i < count; i++) {
15161 val = get_param_indexed(cmd, "PercentBI", i);
15162 if (!val) {
15163 sigma_dut_print(dut, DUT_MSG_ERROR,
15164 "Missing PercentBI parameter at index %d",
15165 i);
15166 return -1;
15167 }
15168 allocs[i].percent_bi = atoi(val);
15169
15170 val = get_param_indexed(cmd, "SrcAID", i);
15171 if (val)
15172 allocs[i].src_aid = strtol(val, NULL, 0);
15173 else
15174 allocs[i].src_aid = ESE_BCAST_AID;
15175
15176 val = get_param_indexed(cmd, "DestAID", i);
15177 if (val)
15178 allocs[i].dst_aid = strtol(val, NULL, 0);
15179 else
15180 allocs[i].dst_aid = ESE_BCAST_AID;
15181
15182 allocs[i].type = ESE_CBAP;
15183 sigma_dut_print(dut, DUT_MSG_INFO,
15184 "Alloc %d PercentBI %d SrcAID %d DstAID %d",
15185 i, allocs[i].percent_bi, allocs[i].src_aid,
15186 allocs[i].dst_aid);
15187 }
15188
15189 *allocs_size = count;
15190 return 0;
15191}
15192
15193
15194static int sta_set_60g_ese(struct sigma_dut *dut, int count,
15195 struct sigma_ese_alloc *allocs)
15196{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020015197 switch (get_driver_type(dut)) {
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020015198#ifdef __linux__
15199 case DRIVER_WIL6210:
15200 if (wil6210_set_ese(dut, count, allocs))
15201 return -1;
15202 return 1;
15203#endif /* __linux__ */
15204 default:
15205 sigma_dut_print(dut, DUT_MSG_ERROR,
15206 "Unsupported sta_set_60g_ese with the current driver");
15207 return -1;
15208 }
15209}
15210
15211
15212static int cmd_sta_set_rfeature_60g(const char *intf, struct sigma_dut *dut,
15213 struct sigma_conn *conn,
15214 struct sigma_cmd *cmd)
15215{
15216 const char *val;
15217
15218 val = get_param(cmd, "ExtSchIE");
15219 if (val && !strcasecmp(val, "Enable")) {
15220 struct sigma_ese_alloc allocs[MAX_ESE_ALLOCS];
15221 int count = MAX_ESE_ALLOCS;
15222
15223 if (sta_extract_60g_ese(dut, cmd, allocs, &count))
15224 return -1;
15225 return sta_set_60g_ese(dut, count, allocs);
15226 }
15227
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +020015228 val = get_param(cmd, "MCS_FixedRate");
15229 if (val) {
15230 int sta_mcs = atoi(val);
15231
15232 sigma_dut_print(dut, DUT_MSG_INFO, "Force STA MCS to %d",
15233 sta_mcs);
15234 wil6210_set_force_mcs(dut, 1, sta_mcs);
15235
Jouni Malinen0e29cf22019-02-19 01:13:21 +020015236 return SUCCESS_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +020015237 }
15238
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020015239 send_resp(dut, conn, SIGMA_ERROR,
15240 "errorCode,Invalid sta_set_rfeature(60G)");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020015241 return STATUS_SENT;
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020015242}
15243
15244
Veerendranath Jakkam76a845c2020-07-14 13:19:40 +053015245static int wcn_sta_override_oci(struct sigma_dut *dut, const char *intf,
15246 const char *oci_frametype, uint32_t oci_freq)
15247{
15248#ifdef NL80211_SUPPORT
15249 struct nl_msg *msg;
15250 int ret = 0;
15251 struct nlattr *params;
15252 struct nlattr *attr;
15253 int ifindex;
15254 u8 frame_type;
15255
15256 ifindex = if_nametoindex(intf);
15257 if (ifindex == 0) {
15258 sigma_dut_print(dut, DUT_MSG_ERROR,
15259 "%s: Index for interface %s failed",
15260 __func__, intf);
15261 return -1;
15262 }
15263
15264 if (strcasecmp(oci_frametype, "SAQueryReq") == 0) {
15265 frame_type = QCA_WLAN_VENDOR_OCI_OVERRIDE_FRAME_SA_QUERY_REQ;
15266 } else if (strcasecmp(oci_frametype, "SAQueryResp") == 0) {
15267 frame_type = QCA_WLAN_VENDOR_OCI_OVERRIDE_FRAME_SA_QUERY_RESP;
15268 } else if (strcasecmp(oci_frametype, "Reassocreq") == 0) {
15269 frame_type = QCA_WLAN_VENDOR_OCI_OVERRIDE_FRAME_FT_REASSOC_REQ;
15270 } else {
15271 sigma_dut_print(dut, DUT_MSG_ERROR, "%s: Unknown frametype %s",
15272 __func__, oci_frametype);
15273 return -1;
15274 }
15275
15276
15277 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
15278 NL80211_CMD_VENDOR)) ||
15279 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
15280 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
15281 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
15282 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
15283 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
15284 !(params = nla_nest_start(
15285 msg,
15286 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_OCI_OVERRIDE)) ||
15287 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_OCI_OVERRIDE_FRAME_TYPE,
15288 frame_type) ||
15289 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_OCI_OVERRIDE_FREQUENCY,
15290 oci_freq)) {
15291 sigma_dut_print(dut, DUT_MSG_ERROR,
15292 "%s: err in adding vendor_cmd and vendor_data",
15293 __func__);
15294 nlmsg_free(msg);
15295 return -1;
15296 }
15297 nla_nest_end(msg, params);
15298 nla_nest_end(msg, attr);
15299
15300 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
15301 if (ret) {
15302 sigma_dut_print(dut, DUT_MSG_ERROR,
15303 "%s: err in send_and_recv_msgs, ret=%d",
15304 __func__, ret);
15305 }
15306 return ret;
15307#else /* NL80211_SUPPORT */
15308 sigma_dut_print(dut, DUT_MSG_ERROR,
15309 "OCI override not possible without NL80211_SUPPORT defined");
15310 return -1;
15311#endif /* NL80211_SUPPORT */
15312}
15313
15314
Veerendranath Jakkam50d5c782020-07-22 01:59:01 +053015315static int wcn_sta_ignore_csa(struct sigma_dut *dut, const char *intf,
15316 uint8_t ignore_csa)
15317{
15318#ifdef NL80211_SUPPORT
15319 return wcn_wifi_test_config_set_u8(
15320 dut, intf,
15321 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_IGNORE_CSA, ignore_csa);
15322#else /* NL80211_SUPPORT */
15323 sigma_dut_print(dut, DUT_MSG_ERROR,
15324 "IgnoreCSA can't be set without NL80211_SUPPORT defined");
15325 return -1;
15326#endif /* NL80211_SUPPORT */
15327}
15328
15329
Veerendranath Jakkamc771fac2020-07-22 01:32:56 +053015330static int wcn_sta_set_rsnxe_used(struct sigma_dut *dut, const char *intf,
15331 uint8_t rsnxe_used)
15332{
15333#ifdef NL80211_SUPPORT
15334 return wcn_wifi_test_config_set_u8(
15335 dut, intf,
15336 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_FT_REASSOCREQ_RSNXE_USED,
15337 rsnxe_used);
15338#else /* NL80211_SUPPORT */
15339 sigma_dut_print(dut, DUT_MSG_ERROR,
15340 "RSNXE_Used can't be set without NL80211_SUPPORT defined");
15341 return -1;
15342#endif /* NL80211_SUPPORT */
15343}
15344
15345
Veerendranath Jakkam1e1e5fd2020-09-10 07:12:37 +053015346static int wcn_sta_ignore_sa_query_timeout(struct sigma_dut *dut,
15347 const char *intf,
15348 uint8_t ignore_sa_query_timeout)
15349{
15350#ifdef NL80211_SUPPORT
15351 return wcn_wifi_test_config_set_u8(
15352 dut, intf,
15353 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_IGNORE_SA_QUERY_TIMEOUT,
15354 ignore_sa_query_timeout);
15355#else /* NL80211_SUPPORT */
15356 sigma_dut_print(dut, DUT_MSG_ERROR,
15357 "Ignore SA Query timeout can't be set without NL80211_SUPPORT defined");
15358 return -1;
15359#endif /* NL80211_SUPPORT */
15360}
15361
15362
Jouni Malinen6250cb02020-04-15 13:54:45 +030015363static enum sigma_cmd_result
15364cmd_sta_set_rfeature_wpa3(const char *intf, struct sigma_dut *dut,
15365 struct sigma_conn *conn,
15366 struct sigma_cmd *cmd)
15367{
Vamsi Krishnad29bc762020-05-08 23:23:30 +053015368 const char *val, *oci_chan, *oci_frametype;
Jouni Malinen6250cb02020-04-15 13:54:45 +030015369
Veerendranath Jakkam30bf9072020-04-16 14:37:57 +053015370 val = get_param(cmd, "ReassocReq_RSNXE_Used");
Jouni Malinen6250cb02020-04-15 13:54:45 +030015371 if (val && atoi(val) == 1) {
Veerendranath Jakkamc771fac2020-07-22 01:32:56 +053015372 if (wifi_chip_type == DRIVER_WCN) {
15373 if (wcn_sta_set_rsnxe_used(dut, intf, 1)) {
15374 send_resp(dut, conn, SIGMA_ERROR,
15375 "errorCode,Failed to set ft_rsnxe_used");
15376 return STATUS_SENT_ERROR;
15377 }
15378 return SUCCESS_SEND_STATUS;
15379 } else if (wpa_command(intf, "SET ft_rsnxe_used 1") < 0) {
Jouni Malinen6250cb02020-04-15 13:54:45 +030015380 send_resp(dut, conn, SIGMA_ERROR,
15381 "errorCode,Failed to set ft_rsnxe_used");
15382 return STATUS_SENT_ERROR;
15383 }
15384 return SUCCESS_SEND_STATUS;
15385 }
Vamsi Krishnad29bc762020-05-08 23:23:30 +053015386
15387 oci_chan = get_param(cmd, "OCIChannel");
15388 oci_frametype = get_param(cmd, "OCIFrameType");
15389 if (oci_chan && oci_frametype) {
15390 unsigned int oci_freq = channel_to_freq(dut, atoi(oci_chan));
15391 char buf[100];
15392
15393 if (!oci_freq) {
15394 send_resp(dut, conn, SIGMA_ERROR,
15395 "errorCode,Invalid OCIChannel number");
15396 return STATUS_SENT_ERROR;
15397 }
15398
Veerendranath Jakkam76a845c2020-07-14 13:19:40 +053015399 if (wifi_chip_type == DRIVER_WCN &&
15400 (strcasecmp(oci_frametype, "SAQueryReq") == 0 ||
15401 strcasecmp(oci_frametype, "SAQueryResp") == 0 ||
15402 strcasecmp(oci_frametype, "Reassocreq") == 0)) {
15403 if (wcn_sta_override_oci(dut, intf, oci_frametype,
15404 oci_freq)) {
15405 send_resp(dut, conn, SIGMA_ERROR,
15406 "errorCode,Failed to override OCI");
15407 return STATUS_SENT_ERROR;
15408 }
15409 return SUCCESS_SEND_STATUS;
15410 }
15411
Vamsi Krishnad29bc762020-05-08 23:23:30 +053015412 if (strcasecmp(oci_frametype, "eapolM2") == 0) {
15413 snprintf(buf, sizeof(buf),
15414 "SET oci_freq_override_eapol %d", oci_freq);
15415 } else if (strcasecmp(oci_frametype, "SAQueryReq") == 0) {
15416 snprintf(buf, sizeof(buf),
15417 "SET oci_freq_override_saquery_req %d",
15418 oci_freq);
15419 } else if (strcasecmp(oci_frametype, "SAQueryResp") == 0) {
15420 snprintf(buf, sizeof(buf),
15421 "SET oci_freq_override_saquery_resp %d",
15422 oci_freq);
Veerendranath Jakkam76a845c2020-07-14 13:19:40 +053015423 } else if (strcasecmp(oci_frametype, "GrpKeyM2") == 0) {
15424 snprintf(buf, sizeof(buf),
15425 "SET oci_freq_override_eapol_g2 %d",
15426 oci_freq);
15427 } else if (strcasecmp(oci_frametype, "Reassocreq") == 0) {
15428 snprintf(buf, sizeof(buf),
15429 "SET oci_freq_override_ft_assoc %d",
15430 oci_freq);
Vamsi Krishnad29bc762020-05-08 23:23:30 +053015431 } else {
15432 send_resp(dut, conn, SIGMA_ERROR,
15433 "errorCode,Unsupported OCIFrameType");
15434 return STATUS_SENT_ERROR;
15435 }
15436 if (wpa_command(intf, buf) < 0) {
15437 send_resp(dut, conn, SIGMA_ERROR,
15438 "errorCode,Failed to set oci_freq_override");
15439 return STATUS_SENT_ERROR;
15440 }
15441 return SUCCESS_SEND_STATUS;
15442 }
15443
Veerendranath Jakkam50d5c782020-07-22 01:59:01 +053015444 val = get_param(cmd, "IgnoreCSA");
15445 if (val && atoi(val) == 1) {
15446 if (wifi_chip_type == DRIVER_WCN) {
15447 if (wcn_sta_ignore_csa(dut, intf, 1)) {
15448 send_resp(dut, conn, SIGMA_ERROR,
15449 "errorCode,Failed to set ignore CSA");
15450 return STATUS_SENT_ERROR;
15451 }
15452 return SUCCESS_SEND_STATUS;
15453 }
15454 }
15455
Veerendranath Jakkam1e1e5fd2020-09-10 07:12:37 +053015456 val = get_param(cmd, "Deauth_Per_SAQueryResp");
15457 if (val && atoi(val) == 0) {
15458 if (wifi_chip_type == DRIVER_WCN) {
15459 if (wcn_sta_ignore_sa_query_timeout(dut, intf, 1)) {
15460 send_resp(dut, conn, SIGMA_ERROR,
15461 "errorCode,Failed to set ignore SA Query timeout");
15462 return STATUS_SENT_ERROR;
15463 }
15464 return SUCCESS_SEND_STATUS;
15465 }
15466 }
15467
Jouni Malinen6250cb02020-04-15 13:54:45 +030015468 send_resp(dut, conn, SIGMA_ERROR,
15469 "errorCode,Unsupported WPA3 rfeature");
15470 return STATUS_SENT_ERROR;
15471}
15472
15473
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053015474static enum sigma_cmd_result
15475cmd_sta_set_rfeature_qm(const char *intf, struct sigma_dut *dut,
15476 struct sigma_conn *conn, struct sigma_cmd *cmd)
15477{
15478 const char *val;
15479
15480 val = get_param(cmd, "DomainName_Domain");
15481 if (val) {
15482 if (strlen(val) >= sizeof(dut->qm_domain_name))
15483 return ERROR_SEND_STATUS;
15484
15485 strlcpy(dut->qm_domain_name, val, sizeof(dut->qm_domain_name));
15486 return SUCCESS_SEND_STATUS;
15487 }
15488
Veerendranath Jakkam1bf1bd62021-09-12 16:35:55 +053015489 val = get_param(cmd, "DSCPPolicy_PolicyID");
15490 if (val) {
15491 unsigned int i;
15492 int policy_id = atoi(val);
15493
15494 val = get_param(cmd, "DSCPPolicy_RequestType");
15495
15496 if (!policy_id || !val)
15497 return INVALID_SEND_STATUS;
15498
15499 if (dut->num_dscp_status >= ARRAY_SIZE(dut->dscp_status)) {
15500 send_resp(dut, conn, SIGMA_ERROR,
15501 "errorCode,DSCP status list full");
15502 return STATUS_SENT_ERROR;
15503 }
15504
15505 for (i = 0; i < dut->num_dscp_status; i++)
15506 if (dut->dscp_status[i].id == policy_id)
15507 break;
15508
15509 /* New policy configured */
15510 if (i == dut->num_dscp_status) {
15511 dut->dscp_status[i].id = policy_id;
15512 dut->num_dscp_status++;
15513 }
15514
15515 dut->dscp_status[i].status = strcasecmp(val, "Remove") ?
15516 DSCP_POLICY_SUCCESS : DSCP_POLICY_REJECT;
15517
15518 return SUCCESS_SEND_STATUS;
15519 }
15520
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053015521 send_resp(dut, conn, SIGMA_ERROR,
15522 "errorCode,Unsupported QM rfeature");
15523 return STATUS_SENT_ERROR;
15524}
15525
15526
Jouni Malinenf7222712019-06-13 01:50:21 +030015527static enum sigma_cmd_result cmd_sta_set_rfeature(struct sigma_dut *dut,
15528 struct sigma_conn *conn,
15529 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015530{
15531 const char *intf = get_param(cmd, "Interface");
15532 const char *prog = get_param(cmd, "Prog");
Ashwini Patil68d02cd2017-01-10 15:39:16 +053015533 const char *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015534
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053015535 if (!prog)
15536 prog = get_param(cmd, "Program");
15537
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015538 if (intf == NULL || prog == NULL)
15539 return -1;
15540
Ashwini Patil5acd7382017-04-13 15:55:04 +053015541 /* BSS Transition candidate list for BTM query */
15542 val = get_param(cmd, "Nebor_BSSID");
15543 if (val && btm_query_candidate_list(dut, conn, cmd) == 0)
15544 return 0;
15545
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015546 if (strcasecmp(prog, "TDLS") == 0)
15547 return cmd_sta_set_rfeature_tdls(intf, dut, conn, cmd);
15548
15549 if (strcasecmp(prog, "VHT") == 0)
15550 return cmd_sta_set_rfeature_vht(intf, dut, conn, cmd);
15551
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080015552 if (strcasecmp(prog, "HE") == 0)
15553 return cmd_sta_set_rfeature_he(intf, dut, conn, cmd);
15554
Ashwini Patil68d02cd2017-01-10 15:39:16 +053015555 if (strcasecmp(prog, "MBO") == 0) {
15556 val = get_param(cmd, "Cellular_Data_Cap");
15557 if (val &&
15558 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
15559 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +053015560
15561 val = get_param(cmd, "Ch_Pref");
15562 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
15563 return 0;
15564
Ashwini Patil68d02cd2017-01-10 15:39:16 +053015565 return 1;
15566 }
15567
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020015568 if (strcasecmp(prog, "60GHz") == 0)
15569 return cmd_sta_set_rfeature_60g(intf, dut, conn, cmd);
15570
Jouni Malinen6250cb02020-04-15 13:54:45 +030015571 if (strcasecmp(prog, "WPA3") == 0)
15572 return cmd_sta_set_rfeature_wpa3(intf, dut, conn, cmd);
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053015573 if (strcasecmp(prog, "QM") == 0)
15574 return cmd_sta_set_rfeature_qm(intf, dut, conn, cmd);
Jouni Malinen6250cb02020-04-15 13:54:45 +030015575
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015576 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported Prog");
15577 return 0;
15578}
15579
15580
Jouni Malinenf7222712019-06-13 01:50:21 +030015581static enum sigma_cmd_result cmd_sta_set_radio(struct sigma_dut *dut,
15582 struct sigma_conn *conn,
15583 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015584{
15585 const char *intf = get_param(cmd, "Interface");
15586 const char *mode = get_param(cmd, "Mode");
15587 int res;
15588
15589 if (intf == NULL || mode == NULL)
15590 return -1;
15591
15592 if (strcasecmp(mode, "On") == 0)
15593 res = wpa_command(intf, "SET radio_disabled 0");
15594 else if (strcasecmp(mode, "Off") == 0)
15595 res = wpa_command(intf, "SET radio_disabled 1");
15596 else
15597 return -1;
15598
15599 if (res) {
15600 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
15601 "radio mode");
15602 return 0;
15603 }
15604
15605 return 1;
15606}
15607
15608
Jouni Malinenf7222712019-06-13 01:50:21 +030015609static enum sigma_cmd_result cmd_sta_set_pwrsave(struct sigma_dut *dut,
15610 struct sigma_conn *conn,
15611 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015612{
15613 const char *intf = get_param(cmd, "Interface");
15614 const char *mode = get_param(cmd, "Mode");
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020015615 const char *prog = get_param(cmd, "program");
15616 const char *powersave = get_param(cmd, "powersave");
15617 int res = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015618
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020015619 if (intf == NULL)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015620 return -1;
15621
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020015622 if (prog && strcasecmp(prog, "60GHz") == 0) {
15623 /*
15624 * The CAPI mode parameter does not exist in 60G
15625 * unscheduled PS.
15626 */
Hu Wang5dc3ff12019-06-14 15:14:26 +080015627 if (powersave && strcasecmp(powersave, "unscheduled") == 0)
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020015628 res = set_ps(intf, dut, 1);
Jouni Malinen016ae6c2019-11-04 17:00:01 +020015629 } else if (prog && get_driver_type(dut) == DRIVER_WCN &&
Alexei Avshalom Lazar2f6fdb42019-02-04 14:16:08 +020015630 strcasecmp(prog, "HE") == 0) {
15631 return cmd_sta_set_power_save_he(intf, dut, conn, cmd);
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020015632 } else {
15633 if (mode == NULL)
15634 return -1;
15635
15636 if (strcasecmp(mode, "On") == 0)
15637 res = set_ps(intf, dut, 1);
15638 else if (strcasecmp(mode, "Off") == 0)
15639 res = set_ps(intf, dut, 0);
15640 else
15641 return -1;
15642 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015643
15644 if (res) {
15645 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
15646 "power save mode");
15647 return 0;
15648 }
15649
15650 return 1;
15651}
15652
15653
Jouni Malinenf7222712019-06-13 01:50:21 +030015654static enum sigma_cmd_result cmd_sta_bssid_pool(struct sigma_dut *dut,
15655 struct sigma_conn *conn,
15656 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015657{
15658 const char *intf = get_param(cmd, "Interface");
15659 const char *val, *bssid;
15660 int res;
15661 char *buf;
15662 size_t buf_len;
15663
15664 val = get_param(cmd, "BSSID_FILTER");
15665 if (val == NULL)
15666 return -1;
15667
15668 bssid = get_param(cmd, "BSSID_List");
15669 if (atoi(val) == 0 || bssid == NULL) {
15670 /* Disable BSSID filter */
15671 if (wpa_command(intf, "SET bssid_filter ")) {
15672 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed "
15673 "to disable BSSID filter");
15674 return 0;
15675 }
15676
15677 return 1;
15678 }
15679
15680 buf_len = 100 + strlen(bssid);
15681 buf = malloc(buf_len);
15682 if (buf == NULL)
15683 return -1;
15684
15685 snprintf(buf, buf_len, "SET bssid_filter %s", bssid);
15686 res = wpa_command(intf, buf);
15687 free(buf);
15688 if (res) {
15689 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to enable "
15690 "BSSID filter");
15691 return 0;
15692 }
15693
15694 return 1;
15695}
15696
15697
Jouni Malinenf7222712019-06-13 01:50:21 +030015698static enum sigma_cmd_result cmd_sta_reset_parm(struct sigma_dut *dut,
15699 struct sigma_conn *conn,
15700 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015701{
15702 const char *intf = get_param(cmd, "Interface");
15703 const char *val;
15704
15705 /* TODO: ARP */
15706
15707 val = get_param(cmd, "HS2_CACHE_PROFILE");
15708 if (val && strcasecmp(val, "All") == 0)
15709 hs2_clear_credentials(intf);
15710
15711 return 1;
15712}
15713
15714
Jouni Malinenf7222712019-06-13 01:50:21 +030015715static enum sigma_cmd_result cmd_sta_get_key(struct sigma_dut *dut,
15716 struct sigma_conn *conn,
15717 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015718{
15719 const char *intf = get_param(cmd, "Interface");
15720 const char *key_type = get_param(cmd, "KeyType");
15721 char buf[100], resp[200];
15722
15723 if (key_type == NULL)
15724 return -1;
15725
15726 if (strcasecmp(key_type, "GTK") == 0) {
15727 if (wpa_command_resp(intf, "GET gtk", buf, sizeof(buf)) < 0 ||
15728 strncmp(buf, "FAIL", 4) == 0) {
15729 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
15730 "not fetch current GTK");
15731 return 0;
15732 }
15733 snprintf(resp, sizeof(resp), "KeyValue,%s", buf);
15734 send_resp(dut, conn, SIGMA_COMPLETE, resp);
15735 return 0;
15736 } else {
15737 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
15738 "KeyType");
15739 return 0;
15740 }
15741
15742 return 1;
15743}
15744
15745
15746static int hs2_set_policy(struct sigma_dut *dut)
15747{
15748#ifdef ANDROID
15749 system("ip rule del prio 23000");
15750 if (system("ip rule add from all lookup main prio 23000") != 0) {
15751 sigma_dut_print(dut, DUT_MSG_ERROR,
15752 "Failed to run:ip rule add from all lookup main prio");
15753 return -1;
15754 }
15755 if (system("ip route flush cache") != 0) {
15756 sigma_dut_print(dut, DUT_MSG_ERROR,
15757 "Failed to run ip route flush cache");
15758 return -1;
15759 }
15760 return 1;
15761#else /* ANDROID */
15762 return 0;
15763#endif /* ANDROID */
15764}
15765
15766
Jouni Malinenf7222712019-06-13 01:50:21 +030015767static enum sigma_cmd_result cmd_sta_hs2_associate(struct sigma_dut *dut,
15768 struct sigma_conn *conn,
15769 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015770{
15771 const char *intf = get_param(cmd, "Interface");
15772 const char *val = get_param(cmd, "Ignore_blacklist");
Jouni Malinen439352d2018-09-13 03:42:23 +030015773 const char *band = get_param(cmd, "Band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015774 struct wpa_ctrl *ctrl;
Jouni Malinen3aa72862019-05-29 23:14:51 +030015775 int res, r;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015776 char bssid[20], ssid[40], resp[100], buf[100], blacklisted[100];
15777 int tries = 0;
15778 int ignore_blacklist = 0;
15779 const char *events[] = {
15780 "CTRL-EVENT-CONNECTED",
15781 "INTERWORKING-BLACKLISTED",
15782 "INTERWORKING-NO-MATCH",
15783 NULL
15784 };
15785
15786 start_sta_mode(dut);
15787
Jouni Malinen439352d2018-09-13 03:42:23 +030015788 if (band) {
15789 if (strcmp(band, "2.4") == 0) {
15790 wpa_command(intf, "SET setband 2G");
15791 } else if (strcmp(band, "5") == 0) {
15792 wpa_command(intf, "SET setband 5G");
15793 } else {
15794 send_resp(dut, conn, SIGMA_ERROR,
15795 "errorCode,Unsupported band");
15796 return 0;
15797 }
15798 }
15799
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015800 blacklisted[0] = '\0';
15801 if (val && atoi(val))
15802 ignore_blacklist = 1;
15803
15804try_again:
15805 ctrl = open_wpa_mon(intf);
15806 if (ctrl == NULL) {
15807 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
15808 "wpa_supplicant monitor connection");
15809 return -2;
15810 }
15811
15812 tries++;
15813 if (wpa_command(intf, "INTERWORKING_SELECT auto")) {
15814 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start "
15815 "Interworking connection");
15816 wpa_ctrl_detach(ctrl);
15817 wpa_ctrl_close(ctrl);
15818 return 0;
15819 }
15820
15821 buf[0] = '\0';
15822 while (1) {
15823 char *pos;
15824 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
15825 pos = strstr(buf, "INTERWORKING-BLACKLISTED");
15826 if (!pos)
15827 break;
15828 pos += 25;
15829 sigma_dut_print(dut, DUT_MSG_DEBUG, "Found blacklisted AP: %s",
15830 pos);
15831 if (!blacklisted[0])
15832 memcpy(blacklisted, pos, strlen(pos) + 1);
15833 }
15834
15835 if (ignore_blacklist && blacklisted[0]) {
15836 char *end;
15837 end = strchr(blacklisted, ' ');
15838 if (end)
15839 *end = '\0';
15840 sigma_dut_print(dut, DUT_MSG_DEBUG, "Try to connect to a blacklisted network: %s",
15841 blacklisted);
Jouni Malinen3aa72862019-05-29 23:14:51 +030015842 r = snprintf(buf, sizeof(buf), "INTERWORKING_CONNECT %s",
15843 blacklisted);
15844 if (r < 0 || r >= sizeof(buf) || wpa_command(intf, buf)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015845 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start Interworking connection to blacklisted network");
15846 wpa_ctrl_detach(ctrl);
15847 wpa_ctrl_close(ctrl);
15848 return 0;
15849 }
15850 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
15851 buf, sizeof(buf));
15852 }
15853
15854 wpa_ctrl_detach(ctrl);
15855 wpa_ctrl_close(ctrl);
15856
15857 if (res < 0) {
15858 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
15859 "connect");
15860 return 0;
15861 }
15862
15863 if (strstr(buf, "INTERWORKING-NO-MATCH") ||
15864 strstr(buf, "INTERWORKING-BLACKLISTED")) {
15865 if (tries < 2) {
15866 sigma_dut_print(dut, DUT_MSG_INFO, "No match found - try again to verify no APs were missed in the scan");
15867 goto try_again;
15868 }
15869 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,No network with "
15870 "matching credentials found");
15871 return 0;
15872 }
15873
15874 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
15875 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
15876 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
15877 "get current BSSID/SSID");
15878 return 0;
15879 }
15880
15881 snprintf(resp, sizeof(resp), "SSID,%s,BSSID,%s", ssid, bssid);
15882 send_resp(dut, conn, SIGMA_COMPLETE, resp);
15883 hs2_set_policy(dut);
15884 return 0;
15885}
15886
15887
Jouni Malinenf7222712019-06-13 01:50:21 +030015888static enum sigma_cmd_result cmd_sta_hs2_venue_info(struct sigma_dut *dut,
15889 struct sigma_conn *conn,
15890 struct sigma_cmd *cmd)
Jouni Malinenb639f1c2018-09-13 02:39:46 +030015891{
15892 const char *intf = get_param(cmd, "Interface");
15893 const char *display = get_param(cmd, "Display");
15894 struct wpa_ctrl *ctrl;
15895 char buf[300], params[400], *pos;
15896 char bssid[20];
15897 int info_avail = 0;
15898 unsigned int old_timeout;
15899 int res;
Jouni Malinen960aa7c2022-01-27 00:25:10 +020015900 const char *events[] = { "RX-VENUE-URL", "ANQP-QUERY-DONE", NULL };
Jouni Malinenb639f1c2018-09-13 02:39:46 +030015901
15902 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0) {
15903 send_resp(dut, conn, SIGMA_ERROR,
15904 "ErrorCode,Could not get current BSSID");
15905 return 0;
15906 }
15907 ctrl = open_wpa_mon(intf);
15908 if (!ctrl) {
15909 sigma_dut_print(dut, DUT_MSG_ERROR,
15910 "Failed to open wpa_supplicant monitor connection");
15911 return -2;
15912 }
15913
15914 snprintf(buf, sizeof(buf), "ANQP_GET %s 277", bssid);
15915 wpa_command(intf, buf);
15916
15917 res = get_wpa_cli_event(dut, ctrl, "GAS-QUERY-DONE", buf, sizeof(buf));
15918 if (res < 0) {
15919 send_resp(dut, conn, SIGMA_ERROR,
15920 "ErrorCode,Could not complete GAS query");
15921 goto fail;
15922 }
15923
15924 old_timeout = dut->default_timeout;
15925 dut->default_timeout = 2;
Jouni Malinen960aa7c2022-01-27 00:25:10 +020015926 for (;;) {
15927 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
15928 if (res < 0)
15929 break;
15930 if (strstr(buf, "ANQP-QUERY-DONE") != NULL) {
15931 res = -1;
15932 break;
15933 }
15934 pos = strchr(buf, ' ');
15935 if (!pos)
15936 continue;
15937 pos++;
15938 pos = strchr(pos, ' ');
15939 if (!pos)
15940 continue;
15941 pos++;
15942
15943 if (strncmp(pos, "https://", 8) == 0)
15944 break;
15945
15946 sigma_dut_print(dut, DUT_MSG_DEBUG,
15947 "Ignore non-HTTPS venue URL: %s", pos);
15948 }
Jouni Malinenb639f1c2018-09-13 02:39:46 +030015949 dut->default_timeout = old_timeout;
15950 if (res < 0)
15951 goto done;
Jouni Malinenb639f1c2018-09-13 02:39:46 +030015952 info_avail = 1;
15953 snprintf(params, sizeof(params), "browser %s", pos);
15954
15955 if (display && strcasecmp(display, "Yes") == 0) {
15956 pid_t pid;
15957
15958 pid = fork();
15959 if (pid < 0) {
15960 perror("fork");
15961 return -1;
15962 }
15963
15964 if (pid == 0) {
15965 run_hs20_osu(dut, params);
15966 exit(0);
15967 }
15968 }
15969
15970done:
15971 snprintf(buf, sizeof(buf), "Info_available,%s",
15972 info_avail ? "Yes" : "No");
15973 send_resp(dut, conn, SIGMA_COMPLETE, buf);
15974fail:
15975 wpa_ctrl_detach(ctrl);
15976 wpa_ctrl_close(ctrl);
15977 return 0;
15978}
15979
15980
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015981static int sta_add_credential_uname_pwd(struct sigma_dut *dut,
15982 struct sigma_conn *conn,
15983 const char *ifname,
15984 struct sigma_cmd *cmd)
15985{
15986 const char *val;
15987 int id;
15988
15989 id = add_cred(ifname);
15990 if (id < 0)
15991 return -2;
15992 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
15993
15994 val = get_param(cmd, "prefer");
15995 if (val && atoi(val) > 0)
15996 set_cred(ifname, id, "priority", "1");
15997
15998 val = get_param(cmd, "REALM");
15999 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
16000 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
16001 "realm");
16002 return 0;
16003 }
16004
16005 val = get_param(cmd, "HOME_FQDN");
16006 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
16007 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
16008 "home_fqdn");
16009 return 0;
16010 }
16011
16012 val = get_param(cmd, "Username");
16013 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
16014 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
16015 "username");
16016 return 0;
16017 }
16018
16019 val = get_param(cmd, "Password");
16020 if (val && set_cred_quoted(ifname, id, "password", val) < 0) {
16021 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
16022 "password");
16023 return 0;
16024 }
16025
16026 val = get_param(cmd, "ROOT_CA");
16027 if (val) {
16028 char fname[200];
16029 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
16030#ifdef __linux__
16031 if (!file_exists(fname)) {
16032 char msg[300];
16033 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
16034 "file (%s) not found", fname);
16035 send_resp(dut, conn, SIGMA_ERROR, msg);
16036 return 0;
16037 }
16038#endif /* __linux__ */
16039 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
16040 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
16041 "not set root CA");
16042 return 0;
16043 }
16044 }
16045
16046 return 1;
16047}
16048
16049
16050static int update_devdetail_imsi(struct sigma_dut *dut, const char *imsi)
16051{
16052 FILE *in, *out;
16053 char buf[500];
16054 int found = 0;
16055
16056 in = fopen("devdetail.xml", "r");
16057 if (in == NULL)
16058 return -1;
16059 out = fopen("devdetail.xml.tmp", "w");
16060 if (out == NULL) {
16061 fclose(in);
16062 return -1;
16063 }
16064
16065 while (fgets(buf, sizeof(buf), in)) {
16066 char *pos = strstr(buf, "<IMSI>");
16067 if (pos) {
16068 sigma_dut_print(dut, DUT_MSG_INFO, "Updated DevDetail IMSI to %s",
16069 imsi);
16070 pos += 6;
16071 *pos = '\0';
16072 fprintf(out, "%s%s</IMSI>\n", buf, imsi);
16073 found++;
16074 } else {
16075 fprintf(out, "%s", buf);
16076 }
16077 }
16078
16079 fclose(out);
16080 fclose(in);
16081 if (found)
16082 rename("devdetail.xml.tmp", "devdetail.xml");
16083 else
16084 unlink("devdetail.xml.tmp");
16085
16086 return 0;
16087}
16088
16089
16090static int sta_add_credential_sim(struct sigma_dut *dut,
16091 struct sigma_conn *conn,
16092 const char *ifname, struct sigma_cmd *cmd)
16093{
16094 const char *val, *imsi = NULL;
16095 int id;
16096 char buf[200];
16097 int res;
16098 const char *pos;
16099 size_t mnc_len;
16100 char plmn_mcc[4];
16101 char plmn_mnc[4];
16102
16103 id = add_cred(ifname);
16104 if (id < 0)
16105 return -2;
16106 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
16107
16108 val = get_param(cmd, "prefer");
16109 if (val && atoi(val) > 0)
16110 set_cred(ifname, id, "priority", "1");
16111
16112 val = get_param(cmd, "PLMN_MCC");
16113 if (val == NULL) {
16114 send_resp(dut, conn, SIGMA_ERROR,
16115 "errorCode,Missing PLMN_MCC");
16116 return 0;
16117 }
16118 if (strlen(val) != 3) {
16119 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MCC");
16120 return 0;
16121 }
16122 snprintf(plmn_mcc, sizeof(plmn_mcc), "%s", val);
16123
16124 val = get_param(cmd, "PLMN_MNC");
16125 if (val == NULL) {
16126 send_resp(dut, conn, SIGMA_ERROR,
16127 "errorCode,Missing PLMN_MNC");
16128 return 0;
16129 }
16130 if (strlen(val) != 2 && strlen(val) != 3) {
16131 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MNC");
16132 return 0;
16133 }
16134 snprintf(plmn_mnc, sizeof(plmn_mnc), "%s", val);
16135
16136 val = get_param(cmd, "IMSI");
16137 if (val == NULL) {
16138 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing SIM "
16139 "IMSI");
16140 return 0;
16141 }
16142
16143 imsi = pos = val;
16144
16145 if (strncmp(plmn_mcc, pos, 3) != 0) {
16146 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MCC mismatch");
16147 return 0;
16148 }
16149 pos += 3;
16150
16151 mnc_len = strlen(plmn_mnc);
16152 if (mnc_len < 2) {
16153 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC not set");
16154 return 0;
16155 }
16156
16157 if (strncmp(plmn_mnc, pos, mnc_len) != 0) {
16158 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC mismatch");
16159 return 0;
16160 }
16161 pos += mnc_len;
16162
16163 res = snprintf(buf, sizeof(buf), "%s%s-%s",plmn_mcc, plmn_mnc, pos);
16164 if (res < 0 || res >= (int) sizeof(buf))
16165 return -1;
16166 if (set_cred_quoted(ifname, id, "imsi", buf) < 0) {
16167 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
16168 "not set IMSI");
16169 return 0;
16170 }
16171
16172 val = get_param(cmd, "Password");
16173 if (val && set_cred_quoted(ifname, id, "milenage", val) < 0) {
16174 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
16175 "not set password");
16176 return 0;
16177 }
16178
Jouni Malinen9a742ff2022-01-27 00:43:14 +020016179 if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3 ||
16180 dut->program == PROGRAM_HS2_R4) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016181 /*
16182 * Set provisioning_sp for the test cases where SIM/USIM
16183 * provisioning is used.
16184 */
16185 if (val && set_cred_quoted(ifname, id, "provisioning_sp",
16186 "wi-fi.org") < 0) {
16187 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
16188 "not set provisioning_sp");
16189 return 0;
16190 }
16191
16192 update_devdetail_imsi(dut, imsi);
16193 }
16194
16195 return 1;
16196}
16197
16198
16199static int sta_add_credential_cert(struct sigma_dut *dut,
16200 struct sigma_conn *conn,
16201 const char *ifname,
16202 struct sigma_cmd *cmd)
16203{
16204 const char *val;
16205 int id;
16206
16207 id = add_cred(ifname);
16208 if (id < 0)
16209 return -2;
16210 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
16211
16212 val = get_param(cmd, "prefer");
16213 if (val && atoi(val) > 0)
16214 set_cred(ifname, id, "priority", "1");
16215
16216 val = get_param(cmd, "REALM");
16217 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
16218 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
16219 "realm");
16220 return 0;
16221 }
16222
16223 val = get_param(cmd, "HOME_FQDN");
16224 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
16225 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
16226 "home_fqdn");
16227 return 0;
16228 }
16229
16230 val = get_param(cmd, "Username");
16231 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
16232 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
16233 "username");
16234 return 0;
16235 }
16236
16237 val = get_param(cmd, "clientCertificate");
16238 if (val) {
16239 char fname[200];
16240 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
16241#ifdef __linux__
16242 if (!file_exists(fname)) {
16243 char msg[300];
16244 snprintf(msg, sizeof(msg),
16245 "ErrorCode,clientCertificate "
16246 "file (%s) not found", fname);
16247 send_resp(dut, conn, SIGMA_ERROR, msg);
16248 return 0;
16249 }
16250#endif /* __linux__ */
16251 if (set_cred_quoted(ifname, id, "client_cert", fname) < 0) {
16252 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
16253 "not set client_cert");
16254 return 0;
16255 }
16256 if (set_cred_quoted(ifname, id, "private_key", fname) < 0) {
16257 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
16258 "not set private_key");
16259 return 0;
16260 }
16261 }
16262
16263 val = get_param(cmd, "ROOT_CA");
16264 if (val) {
16265 char fname[200];
16266 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
16267#ifdef __linux__
16268 if (!file_exists(fname)) {
16269 char msg[300];
16270 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
16271 "file (%s) not found", fname);
16272 send_resp(dut, conn, SIGMA_ERROR, msg);
16273 return 0;
16274 }
16275#endif /* __linux__ */
16276 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
16277 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
16278 "not set root CA");
16279 return 0;
16280 }
16281 }
16282
16283 return 1;
16284}
16285
16286
Jouni Malinenf7222712019-06-13 01:50:21 +030016287static enum sigma_cmd_result cmd_sta_add_credential(struct sigma_dut *dut,
16288 struct sigma_conn *conn,
16289 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016290{
16291 const char *intf = get_param(cmd, "Interface");
16292 const char *type;
16293
16294 start_sta_mode(dut);
16295
16296 type = get_param(cmd, "Type");
16297 if (!type)
16298 return -1;
16299
16300 if (strcasecmp(type, "uname_pwd") == 0)
16301 return sta_add_credential_uname_pwd(dut, conn, intf, cmd);
16302
16303 if (strcasecmp(type, "sim") == 0)
16304 return sta_add_credential_sim(dut, conn, intf, cmd);
16305
16306 if (strcasecmp(type, "cert") == 0)
16307 return sta_add_credential_cert(dut, conn, intf, cmd);
16308
16309 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported credential "
16310 "type");
16311 return 0;
16312}
16313
16314
Jouni Malinenf7222712019-06-13 01:50:21 +030016315static enum sigma_cmd_result cmd_sta_scan(struct sigma_dut *dut,
16316 struct sigma_conn *conn,
16317 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016318{
16319 const char *intf = get_param(cmd, "Interface");
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016320 const char *val, *bssid, *ssid, *scan_freq, *short_ssid;
Veerendranathdc581b52020-08-10 03:29:08 -070016321 char buf[4096], scan_res[20];
vamsi krishna89ad8c62017-09-19 12:51:18 +053016322 char ssid_hex[65];
Kiran Kumar Lokere3399af22020-03-04 16:31:56 -080016323 int wildcard_ssid = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016324 int res;
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016325 enum sigma_cmd_result status;
Jouni Malinen228a2fc2020-06-22 23:37:45 +030016326 struct wpa_ctrl *ctrl = NULL;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016327
Jouni Malinen8c1abeb2019-11-06 18:48:34 +020016328 start_sta_mode(dut);
16329
Arif Hussain66a4af02019-02-07 15:04:51 -080016330 val = get_param(cmd, "GetParameter");
16331 if (val && strcmp(val, "SSID_BSSID") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020016332 if (get_wpa_ssid_bssid(dut, get_station_ifname(dut),
Arif Hussain66a4af02019-02-07 15:04:51 -080016333 buf, sizeof(buf)) < 0) {
16334 sigma_dut_print(dut, DUT_MSG_ERROR,
16335 "Could not get ssid bssid");
16336 return ERROR_SEND_STATUS;
16337 }
16338
16339 sigma_dut_print(dut, DUT_MSG_INFO, "%s", buf);
16340 send_resp(dut, conn, SIGMA_COMPLETE, buf);
16341 return STATUS_SENT;
16342 }
16343
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016344 val = get_param(cmd, "HESSID");
16345 if (val) {
16346 res = snprintf(buf, sizeof(buf), "SET hessid %s", val);
16347 if (res < 0 || res >= (int) sizeof(buf))
16348 return -1;
16349 wpa_command(intf, buf);
16350 }
16351
16352 val = get_param(cmd, "ACCS_NET_TYPE");
16353 if (val) {
16354 res = snprintf(buf, sizeof(buf), "SET access_network_type %s",
16355 val);
16356 if (res < 0 || res >= (int) sizeof(buf))
16357 return -1;
16358 wpa_command(intf, buf);
16359 }
16360
Kiran Kumar Lokere69d89952021-08-08 23:41:46 -070016361 if (get_param(cmd, "RxMac"))
16362 sta_set_scan_unicast_probe(dut, intf, 1);
16363
vamsi krishna89ad8c62017-09-19 12:51:18 +053016364 bssid = get_param(cmd, "Bssid");
16365 ssid = get_param(cmd, "Ssid");
Kiran Kumar Lokere69d89952021-08-08 23:41:46 -070016366 if (!bssid)
16367 bssid = get_param(cmd, "RxMac");
vamsi krishna89ad8c62017-09-19 12:51:18 +053016368
Kiran Kumar Lokere3399af22020-03-04 16:31:56 -080016369 if (ssid && strcasecmp(ssid, "ZeroLength") == 0 &&
16370 dut->device_type == STA_testbed) {
16371 ssid = NULL;
16372 wildcard_ssid = 1;
16373 }
16374
vamsi krishna89ad8c62017-09-19 12:51:18 +053016375 if (ssid) {
16376 if (2 * strlen(ssid) >= sizeof(ssid_hex)) {
16377 send_resp(dut, conn, SIGMA_ERROR,
16378 "ErrorCode,Too long SSID");
16379 return 0;
16380 }
16381 ascii2hexstr(ssid, ssid_hex);
16382 }
16383
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016384 short_ssid = get_param(cmd, "ShortSSID");
16385 if (short_ssid) {
16386 uint32_t short_ssid_hex;
16387
16388 short_ssid_hex = strtoul(short_ssid, NULL, 16);
16389 short_ssid_hex = ((short_ssid_hex & 0xFF) << 24) |
16390 (((short_ssid_hex >> 8) & 0xFF) << 16) |
16391 (((short_ssid_hex >> 16) & 0xFF) << 8) |
16392 ((short_ssid_hex >> 24) & 0xFF);
16393
16394 res = snprintf(buf, sizeof(buf),
16395 "VENDOR_ELEM_ADD 14 ff053a%08x",
16396 short_ssid_hex);
16397 if (res < 0 || res >= (int) sizeof(buf) ||
16398 wpa_command(intf, buf)) {
16399 send_resp(dut, conn, SIGMA_ERROR,
16400 "errorCode,Failed to add short SSID");
16401 return STATUS_SENT_ERROR;
16402 }
16403 }
16404
Kiran Kumar Lokerec0deb482020-03-04 16:35:06 -080016405 scan_freq = get_param(cmd, "ChnlFreq");
Veerendranath Jakkam132c4b42020-08-10 00:29:03 +053016406 if (scan_freq) {
16407 if (strcasecmp(scan_freq, "2G") == 0)
16408 scan_freq = "2412-2462";
16409 else if (strcasecmp(scan_freq, "5G") == 0)
16410 scan_freq = "5180-5925";
16411 }
Kiran Kumar Lokerec0deb482020-03-04 16:35:06 -080016412
Jouni Malinen228a2fc2020-06-22 23:37:45 +030016413 val = get_param(cmd, "WaitCompletion");
16414 if (val && atoi(val) == 1) {
16415 ctrl = open_wpa_mon(intf);
16416 if (!ctrl) {
16417 send_resp(dut, conn, SIGMA_ERROR,
16418 "errorCode,Failed to open monitor socket");
16419 return STATUS_SENT_ERROR;
16420 }
16421 }
16422
Kiran Kumar Lokerec0deb482020-03-04 16:35:06 -080016423 res = snprintf(buf, sizeof(buf), "SCAN%s%s%s%s%s%s%s",
vamsi krishna89ad8c62017-09-19 12:51:18 +053016424 bssid ? " bssid=": "",
16425 bssid ? bssid : "",
16426 ssid ? " ssid " : "",
Kiran Kumar Lokere3399af22020-03-04 16:31:56 -080016427 ssid ? ssid_hex : "",
Kiran Kumar Lokerec0deb482020-03-04 16:35:06 -080016428 wildcard_ssid ? " wildcard_ssid=1" : "",
16429 scan_freq ? " freq=" : "",
16430 scan_freq ? scan_freq : "");
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016431 if (res < 0 || res >= (int) sizeof(buf)) {
16432 send_resp(dut, conn, SIGMA_ERROR,
16433 "errorCode,Could not build scan command");
16434 status = STATUS_SENT_ERROR;
16435 goto remove_s_ssid;
16436 }
vamsi krishna89ad8c62017-09-19 12:51:18 +053016437
Veerendranathdc581b52020-08-10 03:29:08 -070016438 res = wpa_command_resp(intf, buf, scan_res, sizeof(scan_res));
16439 if (strncmp(scan_res, "FAIL-BUSY", 9) == 0) {
16440 sigma_dut_print(dut, DUT_MSG_DEBUG,
16441 "Scan request rejected with busy status, abort ongoing scan and try again");
16442 wpa_command(intf, "ABORT_SCAN");
16443 res = wpa_command(intf, buf);
16444 }
16445
16446 if (res < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016447 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not start "
16448 "scan");
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016449 status = STATUS_SENT_ERROR;
16450 } else {
16451 status = SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016452 }
16453
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016454remove_s_ssid:
16455 if (short_ssid && wpa_command(intf, "VENDOR_ELEM_REMOVE 14 *"))
16456 sigma_dut_print(dut, DUT_MSG_ERROR,
16457 "Failed to delete vendor element");
16458
Jouni Malinen228a2fc2020-06-22 23:37:45 +030016459 if (ctrl) {
16460 if (status == SUCCESS_SEND_STATUS) {
16461 res = get_wpa_cli_event(dut, ctrl,
16462 "CTRL-EVENT-SCAN-RESULTS",
16463 buf, sizeof(buf));
16464 if (res < 0) {
16465 send_resp(dut, conn, SIGMA_ERROR,
16466 "ErrorCode,scan did not complete");
16467 status = STATUS_SENT_ERROR;
16468 }
16469 }
16470
16471 wpa_ctrl_detach(ctrl);
16472 wpa_ctrl_close(ctrl);
16473 }
16474
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016475 return status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016476}
16477
16478
Jouni Malinenf7222712019-06-13 01:50:21 +030016479static enum sigma_cmd_result cmd_sta_scan_bss(struct sigma_dut *dut,
16480 struct sigma_conn *conn,
16481 struct sigma_cmd *cmd)
Jouni Malinen5e5d43d2018-01-10 17:29:33 +020016482{
16483 const char *intf = get_param(cmd, "Interface");
16484 const char *bssid;
16485 char buf[4096], *pos;
16486 int freq, chan;
16487 char *ssid;
16488 char resp[100];
16489 int res;
16490 struct wpa_ctrl *ctrl;
16491
16492 bssid = get_param(cmd, "BSSID");
16493 if (!bssid) {
16494 send_resp(dut, conn, SIGMA_INVALID,
16495 "errorCode,BSSID argument is missing");
16496 return 0;
16497 }
16498
16499 ctrl = open_wpa_mon(intf);
16500 if (!ctrl) {
16501 sigma_dut_print(dut, DUT_MSG_ERROR,
16502 "Failed to open wpa_supplicant monitor connection");
16503 return -1;
16504 }
16505
16506 if (wpa_command(intf, "SCAN TYPE=ONLY")) {
16507 send_resp(dut, conn, SIGMA_ERROR,
16508 "errorCode,Could not start scan");
16509 wpa_ctrl_detach(ctrl);
16510 wpa_ctrl_close(ctrl);
16511 return 0;
16512 }
16513
16514 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
16515 buf, sizeof(buf));
16516
16517 wpa_ctrl_detach(ctrl);
16518 wpa_ctrl_close(ctrl);
16519
16520 if (res < 0) {
16521 send_resp(dut, conn, SIGMA_ERROR,
16522 "errorCode,Scan did not complete");
16523 return 0;
16524 }
16525
16526 snprintf(buf, sizeof(buf), "BSS %s", bssid);
16527 if (wpa_command_resp(intf, buf, buf, sizeof(buf)) < 0 ||
16528 strncmp(buf, "id=", 3) != 0) {
16529 send_resp(dut, conn, SIGMA_ERROR,
16530 "errorCode,Specified BSSID not found");
16531 return 0;
16532 }
16533
16534 pos = strstr(buf, "\nfreq=");
16535 if (!pos) {
16536 send_resp(dut, conn, SIGMA_ERROR,
16537 "errorCode,Channel not found");
16538 return 0;
16539 }
16540 freq = atoi(pos + 6);
16541 chan = freq_to_channel(freq);
16542
16543 pos = strstr(buf, "\nssid=");
16544 if (!pos) {
16545 send_resp(dut, conn, SIGMA_ERROR,
16546 "errorCode,SSID not found");
16547 return 0;
16548 }
16549 ssid = pos + 6;
16550 pos = strchr(ssid, '\n');
16551 if (pos)
16552 *pos = '\0';
16553 snprintf(resp, sizeof(resp), "ssid,%s,bsschannel,%d", ssid, chan);
16554 send_resp(dut, conn, SIGMA_COMPLETE, resp);
16555 return 0;
16556}
16557
16558
Jouni Malinenf7222712019-06-13 01:50:21 +030016559static enum sigma_cmd_result cmd_sta_set_systime(struct sigma_dut *dut,
16560 struct sigma_conn *conn,
16561 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016562{
16563#ifdef __linux__
16564 struct timeval tv;
16565 struct tm tm;
16566 time_t t;
16567 const char *val;
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +053016568 int v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016569
Jouni Malinen016ae6c2019-11-04 17:00:01 +020016570 wpa_command(get_station_ifname(dut), "PMKSA_FLUSH");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016571
16572 memset(&tm, 0, sizeof(tm));
16573 val = get_param(cmd, "seconds");
16574 if (val)
16575 tm.tm_sec = atoi(val);
16576 val = get_param(cmd, "minutes");
16577 if (val)
16578 tm.tm_min = atoi(val);
16579 val = get_param(cmd, "hours");
16580 if (val)
16581 tm.tm_hour = atoi(val);
16582 val = get_param(cmd, "date");
16583 if (val)
16584 tm.tm_mday = atoi(val);
16585 val = get_param(cmd, "month");
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +053016586 if (val) {
16587 v = atoi(val);
16588 if (v < 1 || v > 12) {
16589 send_resp(dut, conn, SIGMA_INVALID,
16590 "errorCode,Invalid month");
16591 return 0;
16592 }
16593 tm.tm_mon = v - 1;
16594 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016595 val = get_param(cmd, "year");
16596 if (val) {
16597 int year = atoi(val);
16598#ifdef ANDROID
16599 if (year > 2035)
16600 year = 2035; /* years beyond 2035 not supported */
16601#endif /* ANDROID */
16602 tm.tm_year = year - 1900;
16603 }
16604 t = mktime(&tm);
16605 if (t == (time_t) -1) {
16606 send_resp(dut, conn, SIGMA_ERROR,
16607 "errorCode,Invalid date or time");
16608 return 0;
16609 }
16610
16611 memset(&tv, 0, sizeof(tv));
16612 tv.tv_sec = t;
16613
16614 if (settimeofday(&tv, NULL) < 0) {
16615 sigma_dut_print(dut, DUT_MSG_INFO, "settimeofday failed: %s",
16616 strerror(errno));
16617 send_resp(dut, conn, SIGMA_ERROR,
16618 "errorCode,Failed to set time");
16619 return 0;
16620 }
16621
16622 return 1;
16623#endif /* __linux__ */
16624
16625 return -1;
16626}
16627
16628
Jouni Malinenf7222712019-06-13 01:50:21 +030016629static enum sigma_cmd_result cmd_sta_osu(struct sigma_dut *dut,
16630 struct sigma_conn *conn,
16631 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016632{
16633 const char *intf = get_param(cmd, "Interface");
Jouni Malinen4c8681c2018-09-12 23:28:11 +030016634 const char *name, *osu_ssid, *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016635 int prod_ess_assoc = 1;
Jouni Malinen4c8681c2018-09-12 23:28:11 +030016636 char buf[300], bssid[100], ssid[100];
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016637 int res;
16638 struct wpa_ctrl *ctrl;
16639
16640 name = get_param(cmd, "osuFriendlyName");
Jouni Malinen4c8681c2018-09-12 23:28:11 +030016641 osu_ssid = get_param(cmd, "osu_ssid");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016642
16643 val = get_param(cmd, "ProdESSAssoc");
16644 if (val)
16645 prod_ess_assoc = atoi(val);
16646
16647 kill_dhcp_client(dut, intf);
16648 if (start_dhcp_client(dut, intf) < 0)
16649 return -2;
16650
16651 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger OSU");
16652 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
16653 res = snprintf(buf, sizeof(buf),
Jouni Malinen4c8681c2018-09-12 23:28:11 +030016654 "%s %s%s%s %s%s%s signup osu-ca.pem",
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016655 prod_ess_assoc ? "" : "-N",
16656 name ? "-O'" : "", name ? name : "",
Jouni Malinen4c8681c2018-09-12 23:28:11 +030016657 name ? "'" : "",
16658 osu_ssid ? "-o'" : "", osu_ssid ? osu_ssid : "",
16659 osu_ssid ? "'" : "");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016660
Kanchanapally, Vidyullatha12b66762015-12-31 16:46:42 +053016661 hs2_set_policy(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016662 if (run_hs20_osu(dut, buf) < 0) {
16663 FILE *f;
16664
16665 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to complete OSU");
16666
16667 f = fopen("hs20-osu-client.res", "r");
16668 if (f) {
16669 char resp[400], res[300], *pos;
16670 if (!fgets(res, sizeof(res), f))
16671 res[0] = '\0';
16672 pos = strchr(res, '\n');
16673 if (pos)
16674 *pos = '\0';
16675 fclose(f);
16676 sigma_dut_summary(dut, "hs20-osu-client provisioning failed: %s",
16677 res);
16678 snprintf(resp, sizeof(resp), "notify-send '%s'", res);
16679 if (system(resp) != 0) {
16680 }
16681 snprintf(resp, sizeof(resp),
16682 "SSID,,BSSID,,failureReason,%s", res);
16683 send_resp(dut, conn, SIGMA_COMPLETE, resp);
16684 return 0;
16685 }
16686
16687 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
16688 return 0;
16689 }
16690
16691 if (!prod_ess_assoc)
16692 goto report;
16693
16694 ctrl = open_wpa_mon(intf);
16695 if (ctrl == NULL) {
16696 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
16697 "wpa_supplicant monitor connection");
16698 return -1;
16699 }
16700
16701 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
16702 buf, sizeof(buf));
16703
16704 wpa_ctrl_detach(ctrl);
16705 wpa_ctrl_close(ctrl);
16706
16707 if (res < 0) {
16708 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to connect to "
16709 "network after OSU");
16710 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
16711 return 0;
16712 }
16713
16714report:
16715 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
16716 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
16717 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to get BSSID/SSID");
16718 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
16719 return 0;
16720 }
16721
16722 snprintf(buf, sizeof(buf), "SSID,%s,BSSID,%s", ssid, bssid);
16723 send_resp(dut, conn, SIGMA_COMPLETE, buf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016724 return 0;
16725}
16726
16727
Jouni Malinenf7222712019-06-13 01:50:21 +030016728static enum sigma_cmd_result cmd_sta_policy_update(struct sigma_dut *dut,
16729 struct sigma_conn *conn,
16730 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016731{
16732 const char *val;
16733 int timeout = 120;
16734
16735 val = get_param(cmd, "PolicyUpdate");
16736 if (val == NULL || atoi(val) == 0)
16737 return 1; /* No operation requested */
16738
16739 val = get_param(cmd, "Timeout");
16740 if (val)
16741 timeout = atoi(val);
16742
16743 if (timeout) {
16744 /* TODO: time out the command and return
16745 * PolicyUpdateStatus,TIMEOUT if needed. */
16746 }
16747
16748 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger policy update");
16749 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
16750 if (run_hs20_osu(dut, "pol_upd fqdn=wi-fi.org") < 0) {
16751 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,FAIL");
16752 return 0;
16753 }
16754
16755 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,SUCCESS");
16756 return 0;
16757}
16758
16759
Jouni Malinenf7222712019-06-13 01:50:21 +030016760static enum sigma_cmd_result cmd_sta_er_config(struct sigma_dut *dut,
16761 struct sigma_conn *conn,
16762 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016763{
16764 struct wpa_ctrl *ctrl;
16765 const char *intf = get_param(cmd, "Interface");
16766 const char *bssid = get_param(cmd, "Bssid");
16767 const char *ssid = get_param(cmd, "SSID");
16768 const char *security = get_param(cmd, "Security");
16769 const char *passphrase = get_param(cmd, "Passphrase");
16770 const char *pin = get_param(cmd, "PIN");
16771 char buf[1000];
16772 char ssid_hex[200], passphrase_hex[200];
16773 const char *keymgmt, *cipher;
16774
16775 if (intf == NULL)
Jouni Malinen016ae6c2019-11-04 17:00:01 +020016776 intf = get_main_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016777
16778 if (!bssid) {
16779 send_resp(dut, conn, SIGMA_ERROR,
16780 "ErrorCode,Missing Bssid argument");
16781 return 0;
16782 }
16783
16784 if (!ssid) {
16785 send_resp(dut, conn, SIGMA_ERROR,
16786 "ErrorCode,Missing SSID argument");
16787 return 0;
16788 }
16789
16790 if (!security) {
16791 send_resp(dut, conn, SIGMA_ERROR,
16792 "ErrorCode,Missing Security argument");
16793 return 0;
16794 }
16795
16796 if (!passphrase) {
16797 send_resp(dut, conn, SIGMA_ERROR,
16798 "ErrorCode,Missing Passphrase argument");
16799 return 0;
16800 }
16801
16802 if (!pin) {
16803 send_resp(dut, conn, SIGMA_ERROR,
16804 "ErrorCode,Missing PIN argument");
16805 return 0;
16806 }
16807
vamsi krishna8c9c1562017-05-12 15:51:46 +053016808 if (2 * strlen(ssid) >= sizeof(ssid_hex) ||
16809 2 * strlen(passphrase) >= sizeof(passphrase_hex)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016810 send_resp(dut, conn, SIGMA_ERROR,
16811 "ErrorCode,Too long SSID/passphrase");
16812 return 0;
16813 }
16814
16815 ctrl = open_wpa_mon(intf);
16816 if (ctrl == NULL) {
16817 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
16818 "wpa_supplicant monitor connection");
16819 return -2;
16820 }
16821
16822 if (strcasecmp(security, "wpa2-psk") == 0) {
16823 keymgmt = "WPA2PSK";
16824 cipher = "CCMP";
16825 } else {
16826 wpa_ctrl_detach(ctrl);
16827 wpa_ctrl_close(ctrl);
16828 send_resp(dut, conn, SIGMA_ERROR,
16829 "ErrorCode,Unsupported Security value");
16830 return 0;
16831 }
16832
16833 ascii2hexstr(ssid, ssid_hex);
16834 ascii2hexstr(passphrase, passphrase_hex);
16835 snprintf(buf, sizeof(buf), "WPS_REG %s %s %s %s %s %s",
16836 bssid, pin, ssid_hex, keymgmt, cipher, passphrase_hex);
16837
16838 if (wpa_command(intf, buf) < 0) {
16839 wpa_ctrl_detach(ctrl);
16840 wpa_ctrl_close(ctrl);
16841 send_resp(dut, conn, SIGMA_ERROR,
16842 "ErrorCode,Failed to start registrar");
16843 return 0;
16844 }
16845
16846 snprintf(dut->er_oper_bssid, sizeof(dut->er_oper_bssid), "%s", bssid);
16847 dut->er_oper_performed = 1;
16848
16849 return wps_connection_event(dut, conn, ctrl, intf, 0);
16850}
16851
16852
Jouni Malinenf7222712019-06-13 01:50:21 +030016853static enum sigma_cmd_result
16854cmd_sta_wps_connect_pw_token(struct sigma_dut *dut, struct sigma_conn *conn,
16855 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016856{
16857 struct wpa_ctrl *ctrl;
16858 const char *intf = get_param(cmd, "Interface");
16859 const char *bssid = get_param(cmd, "Bssid");
16860 char buf[100];
16861
16862 if (!bssid) {
16863 send_resp(dut, conn, SIGMA_ERROR,
16864 "ErrorCode,Missing Bssid argument");
16865 return 0;
16866 }
16867
16868 ctrl = open_wpa_mon(intf);
16869 if (ctrl == NULL) {
16870 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
16871 "wpa_supplicant monitor connection");
16872 return -2;
16873 }
16874
16875 snprintf(buf, sizeof(buf), "WPS_NFC %s", bssid);
16876
16877 if (wpa_command(intf, buf) < 0) {
16878 wpa_ctrl_detach(ctrl);
16879 wpa_ctrl_close(ctrl);
16880 send_resp(dut, conn, SIGMA_ERROR,
16881 "ErrorCode,Failed to start registrar");
16882 return 0;
16883 }
16884
16885 return wps_connection_event(dut, conn, ctrl, intf, 0);
16886}
16887
16888
Jouni Malinenf7222712019-06-13 01:50:21 +030016889static enum sigma_cmd_result cmd_start_wps_registration(struct sigma_dut *dut,
16890 struct sigma_conn *conn,
16891 struct sigma_cmd *cmd)
vamsi krishna9b144002017-09-20 13:28:13 +053016892{
16893 struct wpa_ctrl *ctrl;
16894 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020016895 const char *network_mode = get_param(cmd, "network_mode");
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020016896 const char *config_method = get_param(cmd, "WPSConfigMethod");
16897 const char *role;
vamsi krishna9b144002017-09-20 13:28:13 +053016898 int res;
16899 char buf[256];
16900 const char *events[] = {
16901 "CTRL-EVENT-CONNECTED",
16902 "WPS-OVERLAP-DETECTED",
16903 "WPS-TIMEOUT",
16904 "WPS-FAIL",
16905 NULL
16906 };
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020016907 int id = 0;
vamsi krishna9b144002017-09-20 13:28:13 +053016908
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020016909 /* 60G WPS tests do not pass Interface parameter */
16910 if (!intf)
Jouni Malinen016ae6c2019-11-04 17:00:01 +020016911 intf = get_main_ifname(dut);
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020016912
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020016913 if (dut->mode == SIGMA_MODE_AP)
16914 return ap_wps_registration(dut, conn, cmd);
16915
16916 if (config_method) {
16917 /* WFA_CS_WPS_PIN_KEYPAD mode is set when using the
16918 * sta_wps_enter_pin before calling start_wps_registration. */
16919 if (strcasecmp(config_method, "PBC") == 0)
16920 dut->wps_method = WFA_CS_WPS_PBC;
16921 }
16922 if (dut->wps_method == WFA_CS_WPS_NOT_READY) {
16923 send_resp(dut, conn, SIGMA_ERROR,
16924 "ErrorCode,WPS parameters not yet set");
16925 return STATUS_SENT;
16926 }
16927
16928 /* Make sure WPS is enabled (also for STA mode) */
16929 dut->wps_disable = 0;
16930
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020016931 if (dut->band == WPS_BAND_60G && network_mode &&
16932 strcasecmp(network_mode, "PBSS") == 0) {
16933 sigma_dut_print(dut, DUT_MSG_DEBUG,
16934 "Set PBSS network mode, network id %d", id);
Jouni Malinen016ae6c2019-11-04 17:00:01 +020016935 if (set_network(get_station_ifname(dut), id, "pbss", "1") < 0)
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020016936 return -2;
16937 }
16938
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020016939 if (dut->force_rsn_ie) {
16940 sigma_dut_print(dut, DUT_MSG_DEBUG, "Force RSN_IE: %d",
16941 dut->force_rsn_ie);
16942 if (sta_60g_force_rsn_ie(dut, dut->force_rsn_ie) < 0) {
16943 sigma_dut_print(dut, DUT_MSG_INFO,
16944 "Failed to force RSN_IE");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020016945 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020016946 }
16947 }
16948
vamsi krishna9b144002017-09-20 13:28:13 +053016949 ctrl = open_wpa_mon(intf);
16950 if (!ctrl) {
16951 sigma_dut_print(dut, DUT_MSG_ERROR,
16952 "Failed to open wpa_supplicant monitor connection");
16953 return -2;
16954 }
16955
16956 role = get_param(cmd, "WpsRole");
16957 if (!role) {
16958 send_resp(dut, conn, SIGMA_INVALID,
16959 "ErrorCode,WpsRole not provided");
16960 goto fail;
16961 }
16962
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020016963 if (strcasecmp(role, "Enrollee") != 0) {
16964 /* Registrar role for STA not supported */
16965 send_resp(dut, conn, SIGMA_ERROR,
16966 "ErrorCode,Unsupported WpsRole value");
16967 goto fail;
16968 }
16969
16970 if (is_60g_sigma_dut(dut)) {
16971 if (dut->wps_method == WFA_CS_WPS_PBC)
16972 snprintf(buf, sizeof(buf), "WPS_PBC");
16973 else /* WFA_CS_WPS_PIN_KEYPAD */
16974 snprintf(buf, sizeof(buf), "WPS_PIN any %s",
16975 dut->wps_pin);
16976 if (wpa_command(intf, buf) < 0) {
16977 send_resp(dut, conn, SIGMA_ERROR,
16978 "ErrorCode,Failed to start WPS");
vamsi krishna9b144002017-09-20 13:28:13 +053016979 goto fail;
16980 }
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020016981 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
16982 if (res < 0) {
16983 send_resp(dut, conn, SIGMA_ERROR,
16984 "ErrorCode,WPS connection did not complete");
16985 goto fail;
16986 }
16987 if (strstr(buf, "WPS-TIMEOUT")) {
16988 send_resp(dut, conn, SIGMA_COMPLETE, "WpsState,NoPeer");
16989 } else if (strstr(buf, "WPS-OVERLAP-DETECTED")) {
16990 send_resp(dut, conn, SIGMA_COMPLETE,
16991 "WpsState,OverlapSession");
16992 } else if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
16993 send_resp(dut, conn, SIGMA_COMPLETE,
16994 "WpsState,Successful");
16995 } else {
16996 send_resp(dut, conn, SIGMA_COMPLETE,
16997 "WpsState,Failure");
16998 }
16999 } else {
17000 if (dut->wps_method == WFA_CS_WPS_PBC) {
vamsi krishna9b144002017-09-20 13:28:13 +053017001 if (wpa_command(intf, "WPS_PBC") < 0) {
17002 send_resp(dut, conn, SIGMA_ERROR,
17003 "ErrorCode,Failed to enable PBC");
17004 goto fail;
17005 }
17006 } else {
17007 /* TODO: PIN method */
17008 send_resp(dut, conn, SIGMA_ERROR,
17009 "ErrorCode,Unsupported WpsConfigMethod value");
17010 goto fail;
17011 }
17012 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
17013 if (res < 0) {
17014 send_resp(dut, conn, SIGMA_ERROR,
17015 "ErrorCode,WPS connection did not complete");
17016 goto fail;
17017 }
17018 if (strstr(buf, "WPS-TIMEOUT")) {
17019 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,NoPeer");
17020 } else if (strstr(buf, "WPS-OVERLAP-DETECTED")) {
17021 send_resp(dut, conn, SIGMA_ERROR,
17022 "ErrorCode,OverlapSession");
17023 } else if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
17024 send_resp(dut, conn, SIGMA_COMPLETE, "Successful");
17025 } else {
17026 send_resp(dut, conn, SIGMA_ERROR,
17027 "ErrorCode,WPS operation failed");
17028 }
vamsi krishna9b144002017-09-20 13:28:13 +053017029 }
17030
17031fail:
17032 wpa_ctrl_detach(ctrl);
17033 wpa_ctrl_close(ctrl);
17034 return 0;
17035}
17036
17037
Jouni Malinencd4e3c32015-10-29 12:39:56 +020017038static int req_intf(struct sigma_cmd *cmd)
17039{
17040 return get_param(cmd, "interface") == NULL ? -1 : 0;
17041}
17042
17043
17044void sta_register_cmds(void)
17045{
17046 sigma_dut_reg_cmd("sta_get_ip_config", req_intf,
17047 cmd_sta_get_ip_config);
17048 sigma_dut_reg_cmd("sta_set_ip_config", req_intf,
17049 cmd_sta_set_ip_config);
17050 sigma_dut_reg_cmd("sta_get_info", req_intf, cmd_sta_get_info);
17051 sigma_dut_reg_cmd("sta_get_mac_address", req_intf,
17052 cmd_sta_get_mac_address);
17053 sigma_dut_reg_cmd("sta_is_connected", req_intf, cmd_sta_is_connected);
17054 sigma_dut_reg_cmd("sta_verify_ip_connection", req_intf,
17055 cmd_sta_verify_ip_connection);
17056 sigma_dut_reg_cmd("sta_get_bssid", req_intf, cmd_sta_get_bssid);
17057 sigma_dut_reg_cmd("sta_set_encryption", req_intf,
17058 cmd_sta_set_encryption);
17059 sigma_dut_reg_cmd("sta_set_psk", req_intf, cmd_sta_set_psk);
17060 sigma_dut_reg_cmd("sta_set_eaptls", req_intf, cmd_sta_set_eaptls);
17061 sigma_dut_reg_cmd("sta_set_eapttls", req_intf, cmd_sta_set_eapttls);
17062 sigma_dut_reg_cmd("sta_set_eapsim", req_intf, cmd_sta_set_eapsim);
17063 sigma_dut_reg_cmd("sta_set_peap", req_intf, cmd_sta_set_peap);
17064 sigma_dut_reg_cmd("sta_set_eapfast", req_intf, cmd_sta_set_eapfast);
17065 sigma_dut_reg_cmd("sta_set_eapaka", req_intf, cmd_sta_set_eapaka);
17066 sigma_dut_reg_cmd("sta_set_eapakaprime", req_intf,
17067 cmd_sta_set_eapakaprime);
17068 sigma_dut_reg_cmd("sta_set_security", req_intf, cmd_sta_set_security);
17069 sigma_dut_reg_cmd("sta_set_uapsd", req_intf, cmd_sta_set_uapsd);
17070 /* TODO: sta_set_ibss */
17071 /* TODO: sta_set_mode */
17072 sigma_dut_reg_cmd("sta_set_wmm", req_intf, cmd_sta_set_wmm);
17073 sigma_dut_reg_cmd("sta_associate", req_intf, cmd_sta_associate);
17074 /* TODO: sta_up_load */
17075 sigma_dut_reg_cmd("sta_preset_testparameters", req_intf,
17076 cmd_sta_preset_testparameters);
17077 /* TODO: sta_set_system */
17078 sigma_dut_reg_cmd("sta_set_11n", req_intf, cmd_sta_set_11n);
17079 /* TODO: sta_set_rifs_test */
17080 sigma_dut_reg_cmd("sta_set_wireless", req_intf, cmd_sta_set_wireless);
17081 sigma_dut_reg_cmd("sta_send_addba", req_intf, cmd_sta_send_addba);
17082 /* TODO: sta_send_coexist_mgmt */
17083 sigma_dut_reg_cmd("sta_disconnect", req_intf, cmd_sta_disconnect);
17084 sigma_dut_reg_cmd("sta_reassoc", req_intf, cmd_sta_reassoc);
17085 sigma_dut_reg_cmd("sta_reassociate", req_intf, cmd_sta_reassoc);
17086 sigma_dut_reg_cmd("sta_reset_default", req_intf,
17087 cmd_sta_reset_default);
17088 sigma_dut_reg_cmd("sta_send_frame", req_intf, cmd_sta_send_frame);
17089 sigma_dut_reg_cmd("sta_set_macaddr", req_intf, cmd_sta_set_macaddr);
17090 sigma_dut_reg_cmd("sta_set_rfeature", req_intf, cmd_sta_set_rfeature);
17091 sigma_dut_reg_cmd("sta_set_radio", req_intf, cmd_sta_set_radio);
17092 sigma_dut_reg_cmd("sta_set_pwrsave", req_intf, cmd_sta_set_pwrsave);
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020017093 sigma_dut_reg_cmd("sta_set_power_save", req_intf, cmd_sta_set_pwrsave);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020017094 sigma_dut_reg_cmd("sta_bssid_pool", req_intf, cmd_sta_bssid_pool);
17095 sigma_dut_reg_cmd("sta_reset_parm", req_intf, cmd_sta_reset_parm);
17096 sigma_dut_reg_cmd("sta_get_key", req_intf, cmd_sta_get_key);
17097 sigma_dut_reg_cmd("sta_hs2_associate", req_intf,
17098 cmd_sta_hs2_associate);
Jouni Malinenb639f1c2018-09-13 02:39:46 +030017099 sigma_dut_reg_cmd("sta_hs2_venue_info", req_intf,
17100 cmd_sta_hs2_venue_info);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020017101 sigma_dut_reg_cmd("sta_add_credential", req_intf,
17102 cmd_sta_add_credential);
17103 sigma_dut_reg_cmd("sta_scan", req_intf, cmd_sta_scan);
Jouni Malinen5e5d43d2018-01-10 17:29:33 +020017104 sigma_dut_reg_cmd("sta_scan_bss", req_intf, cmd_sta_scan_bss);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020017105 sigma_dut_reg_cmd("sta_set_systime", NULL, cmd_sta_set_systime);
17106 sigma_dut_reg_cmd("sta_osu", req_intf, cmd_sta_osu);
17107 sigma_dut_reg_cmd("sta_policy_update", req_intf, cmd_sta_policy_update);
17108 sigma_dut_reg_cmd("sta_er_config", NULL, cmd_sta_er_config);
17109 sigma_dut_reg_cmd("sta_wps_connect_pw_token", req_intf,
17110 cmd_sta_wps_connect_pw_token);
Jouni Malinen82905202018-04-29 17:20:10 +030017111 sigma_dut_reg_cmd("sta_exec_action", NULL, cmd_sta_exec_action);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020017112 sigma_dut_reg_cmd("sta_get_events", req_intf, cmd_sta_get_events);
17113 sigma_dut_reg_cmd("sta_get_parameter", req_intf, cmd_sta_get_parameter);
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020017114 sigma_dut_reg_cmd("start_wps_registration", NULL,
vamsi krishna9b144002017-09-20 13:28:13 +053017115 cmd_start_wps_registration);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020017116}