blob: be765fadc0d404652fa7edb7895753517b34d5c0 [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"
Jouni Malinencd4e3c32015-10-29 12:39:56 +020037
38/* Temporary files for sta_send_addba */
39#define VI_QOS_TMP_FILE "/tmp/vi-qos.tmp"
40#define VI_QOS_FILE "/tmp/vi-qos.txt"
41#define VI_QOS_REFFILE "/etc/vi-qos.txt"
42
43/*
44 * MTU for Ethernet need to take into account 8-byte SNAP header
45 * to be added when encapsulating Ethernet frame into 802.11
46 */
47#ifndef IEEE80211_MAX_DATA_LEN_DMG
48#define IEEE80211_MAX_DATA_LEN_DMG 7920
49#endif
50#ifndef IEEE80211_SNAP_LEN_DMG
51#define IEEE80211_SNAP_LEN_DMG 8
52#endif
53
Ashwini Patil00402582017-04-13 12:29:39 +053054#define NON_PREF_CH_LIST_SIZE 100
Ashwini Patil5acd7382017-04-13 15:55:04 +053055#define NEIGHBOR_REPORT_SIZE 1000
56#define DEFAULT_NEIGHBOR_BSSID_INFO "17"
57#define DEFAULT_NEIGHBOR_PHY_TYPE "1"
Ashwini Patil00402582017-04-13 12:29:39 +053058
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030059#define WIL_DEFAULT_BI 100
60
61/* default remain on channel time for transmitting frames (milliseconds) */
62#define WIL_TRANSMIT_FRAME_DEFAULT_ROC 500
63#define IEEE80211_P2P_ATTR_DEVICE_ID 3
64#define IEEE80211_P2P_ATTR_GROUP_ID 15
65
66/* describes tagged bytes in template frame file */
67struct template_frame_tag {
68 int num;
69 int offset;
70 size_t len;
71};
72
Jouni Malinencd4e3c32015-10-29 12:39:56 +020073extern char *sigma_wpas_ctrl;
74extern char *sigma_cert_path;
75extern enum driver_type wifi_chip_type;
76extern char *sigma_radio_ifname[];
77
Lior David0fe101e2017-03-09 16:09:50 +020078#ifdef __linux__
79#define WIL_WMI_MAX_PAYLOAD 248
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020080#define WIL_WMI_ESE_CFG_CMDID 0xa01
Lior David0fe101e2017-03-09 16:09:50 +020081#define WIL_WMI_BF_TRIG_CMDID 0x83a
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020082#define WIL_WMI_UNIT_TEST_CMDID 0x900
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030083#define WIL_WMI_P2P_CFG_CMDID 0x910
84#define WIL_WMI_START_LISTEN_CMDID 0x914
85#define WIL_WMI_DISCOVERY_STOP_CMDID 0x917
Lior David0fe101e2017-03-09 16:09:50 +020086
87struct wil_wmi_header {
88 uint8_t mid;
89 uint8_t reserved;
90 uint16_t cmd;
91 uint32_t ts;
92} __attribute__((packed));
93
94enum wil_wmi_bf_trig_type {
95 WIL_WMI_SLS,
96 WIL_WMI_BRP_RX,
97 WIL_WMI_BRP_TX,
98};
99
100struct wil_wmi_bf_trig_cmd {
101 /* enum wil_wmi_bf_trig_type */
102 uint32_t bf_type;
103 /* cid when type == WMI_BRP_RX */
104 uint32_t sta_id;
105 uint32_t reserved;
106 /* mac address when type = WIL_WMI_SLS */
107 uint8_t dest_mac[6];
108} __attribute__((packed));
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +0200109
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +0200110enum wil_wmi_sched_scheme_advertisment {
111 WIL_WMI_ADVERTISE_ESE_DISABLED,
112 WIL_WMI_ADVERTISE_ESE_IN_BEACON,
113 WIL_WMI_ADVERTISE_ESE_IN_ANNOUNCE_FRAME,
114};
115
116enum wil_wmi_ese_slot_type {
117 WIL_WMI_ESE_SP,
118 WIL_WMI_ESE_CBAP,
119 WIL_WMI_ESE_ANNOUNCE_NO_ACK,
120};
121
122struct wil_wmi_ese_slot {
123 /* offset from start of BI in microseconds */
124 uint32_t tbtt_offset;
125 uint8_t flags;
126 /* enum wil_wmi_ese_slot_type */
127 uint8_t slot_type;
128 /* duration in microseconds */
129 uint16_t duration;
130 /* frame exchange sequence duration, microseconds */
131 uint16_t tx_op;
132 /* time between 2 blocks for periodic allocation(microseconds) */
133 uint16_t period;
134 /* number of blocks in periodic allocation */
135 uint8_t num_blocks;
136 /* for semi-active allocations */
137 uint8_t idle_period;
138 uint8_t src_aid;
139 uint8_t dst_aid;
140 uint32_t reserved;
141} __attribute__((packed));
142
143#define WIL_WMI_MAX_ESE_SLOTS 4
144struct wil_wmi_ese_cfg {
145 uint8_t serial_num;
146 /* wil_wmi_sched_scheme_advertisment */
147 uint8_t ese_advertisment;
148 uint16_t flags;
149 uint8_t num_allocs;
150 uint8_t reserved[3];
151 uint64_t start_tbtt;
152 /* allocations list */
153 struct wil_wmi_ese_slot slots[WIL_WMI_MAX_ESE_SLOTS];
154} __attribute__((packed));
155
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +0200156#define WIL_WMI_UT_FORCE_MCS 6
157struct wil_wmi_force_mcs {
158 /* WIL_WMI_UT_HW_SYSAPI */
159 uint16_t module_id;
160 /* WIL_WMI_UT_FORCE_MCS */
161 uint16_t subtype_id;
162 /* cid (ignored in oob_mode, affects all stations) */
163 uint32_t cid;
164 /* 1 to force MCS, 0 to restore default behavior */
165 uint32_t force_enable;
166 /* MCS index, 0-12 */
167 uint32_t mcs;
168} __attribute__((packed));
169
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +0200170#define WIL_WMI_UT_HW_SYSAPI 10
171#define WIL_WMI_UT_FORCE_RSN_IE 0x29
172struct wil_wmi_force_rsn_ie {
173 /* WIL_WMI_UT_HW_SYSAPI */
174 uint16_t module_id;
175 /* WIL_WMI_UT_FORCE_RSN_IE */
176 uint16_t subtype_id;
177 /* 0 = no change, 1 = remove if exists, 2 = add if does not exist */
178 uint32_t state;
179} __attribute__((packed));
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +0300180
181enum wil_wmi_discovery_mode {
182 WMI_DISCOVERY_MODE_NON_OFFLOAD,
183 WMI_DISCOVERY_MODE_OFFLOAD,
184 WMI_DISCOVERY_MODE_PEER2PEER,
185};
186
187struct wil_wmi_p2p_cfg_cmd {
188 /* enum wil_wmi_discovery_mode */
189 uint8_t discovery_mode;
190 /* 0-based (wireless channel - 1) */
191 uint8_t channel;
192 /* set to WIL_DEFAULT_BI */
193 uint16_t bcon_interval;
194} __attribute__((packed));
Lior David0fe101e2017-03-09 16:09:50 +0200195#endif /* __linux__ */
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200196
197#ifdef ANDROID
198
199static int add_ipv6_rule(struct sigma_dut *dut, const char *ifname);
200
201#define ANDROID_KEYSTORE_GET 'g'
202#define ANDROID_KEYSTORE_GET_PUBKEY 'b'
203
204static int android_keystore_get(char cmd, const char *key, unsigned char *val)
205{
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200206 /* Android 4.3 changed keystore design, so need to use keystore_get() */
207#ifndef KEYSTORE_MESSAGE_SIZE
208#define KEYSTORE_MESSAGE_SIZE 65535
209#endif /* KEYSTORE_MESSAGE_SIZE */
210
211 ssize_t len;
212 uint8_t *value = NULL;
213
214 __android_log_print(ANDROID_LOG_DEBUG, "sigma_dut",
215 "keystore command '%c' key '%s' --> keystore_get",
216 cmd, key);
217
218 len = keystore_get(key, strlen(key), &value);
219 if (len < 0) {
220 __android_log_print(ANDROID_LOG_DEBUG, "sigma_dut",
221 "keystore_get() failed");
222 return -1;
223 }
224
225 if (len > KEYSTORE_MESSAGE_SIZE)
226 len = KEYSTORE_MESSAGE_SIZE;
227 memcpy(val, value, len);
228 free(value);
229 return len;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200230}
231#endif /* ANDROID */
232
233
Vinita S. Maloo0fcb57d2020-04-24 14:03:56 +0530234#ifdef NL80211_SUPPORT
235static int nl80211_sta_set_power_save(struct sigma_dut *dut,
236 const char *intf,
237 enum nl80211_ps_state ps_state)
238{
239 struct nl_msg *msg;
240 int ifindex, ret;
241
242 ifindex = if_nametoindex(intf);
243 if (ifindex == 0) {
244 sigma_dut_print(dut, DUT_MSG_ERROR,
245 "%s: Index for interface %s not found",
246 __func__, intf);
247 return -1;
248 }
249
250 msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
251 NL80211_CMD_SET_POWER_SAVE);
252 if (!msg) {
253 sigma_dut_print(dut, DUT_MSG_ERROR,
254 "%s: err in creating nl80211 msg", __func__);
255 return -1;
256 }
257
258 if (nla_put_u32(msg, NL80211_ATTR_PS_STATE, ps_state)) {
259 sigma_dut_print(dut, DUT_MSG_ERROR,
260 "%s: err in populating nl80211 msg", __func__);
261 nlmsg_free(msg);
262 return -1;
263 }
264
265 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
266 if (ret) {
267 sigma_dut_print(dut, DUT_MSG_ERROR,
268 "%s: err in send_and_recv_msgs, ret=%d (%s)",
269 __func__, ret, strerror(-ret));
270 return -1;
271 }
272
273 return 0;
274}
275#endif /* NL80211_SUPPORT */
276
277
Vinita S. Malooa8b62722020-04-23 01:45:41 +0530278static int set_power_save_wcn(struct sigma_dut *dut, const char *intf, int ps)
279{
280 char buf[100];
Vinita S. Maloo0fcb57d2020-04-24 14:03:56 +0530281#ifdef NL80211_SUPPORT
282 enum nl80211_ps_state ps_state;
283
284 ps_state = ps == 1 ? NL80211_PS_ENABLED : NL80211_PS_DISABLED;
285 if (nl80211_sta_set_power_save(dut, intf, ps_state) == 0)
286 return 0;
287#endif /* NL80211_SUPPORT */
Vinita S. Malooa8b62722020-04-23 01:45:41 +0530288
289 snprintf(buf, sizeof(buf), "iwpriv %s setPower %d", intf, ps);
290 if (system(buf) != 0) {
291 sigma_dut_print(dut, DUT_MSG_ERROR,
292 "iwpriv setPower %d failed", ps);
293 return -1;
294 }
295 return 0;
296}
297
298
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200299int set_ps(const char *intf, struct sigma_dut *dut, int enabled)
300{
301#ifdef __linux__
302 char buf[100];
303
304 if (wifi_chip_type == DRIVER_WCN) {
305 if (enabled) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +0530306 if (set_power_save_wcn(dut, intf, 1) < 0) {
Purushottam Kushwaha304561d2019-12-23 16:57:18 +0530307 snprintf(buf, sizeof(buf),
308 "iwpriv wlan0 dump 906");
309 if (system(buf) != 0)
310 goto set_power_save;
311 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200312 } else {
Vinita S. Malooa8b62722020-04-23 01:45:41 +0530313 if (set_power_save_wcn(dut, intf, 2) < 0) {
Purushottam Kushwaha304561d2019-12-23 16:57:18 +0530314 snprintf(buf, sizeof(buf),
315 "iwpriv wlan0 dump 905");
316 if (system(buf) != 0)
317 goto set_power_save;
318 snprintf(buf, sizeof(buf),
319 "iwpriv wlan0 dump 912");
320 if (system(buf) != 0)
321 goto set_power_save;
322 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200323 }
324
325 return 0;
326 }
327
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530328set_power_save:
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200329 snprintf(buf, sizeof(buf), "./iw dev %s set power_save %s",
330 intf, enabled ? "on" : "off");
331 if (system(buf) != 0) {
332 snprintf(buf, sizeof(buf), "iw dev %s set power_save %s",
333 intf, enabled ? "on" : "off");
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530334 if (system(buf) != 0) {
335 sigma_dut_print(dut, DUT_MSG_ERROR,
336 "Failed to set power save %s",
337 enabled ? "on" : "off");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200338 return -1;
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530339 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200340 }
341
342 return 0;
343#else /* __linux__ */
344 return -1;
345#endif /* __linux__ */
346}
347
348
Lior Davidcc88b562017-01-03 18:52:09 +0200349#ifdef __linux__
Lior David0fe101e2017-03-09 16:09:50 +0200350
Lior Davidcc88b562017-01-03 18:52:09 +0200351static int wil6210_get_debugfs_dir(struct sigma_dut *dut, char *path,
352 size_t len)
353{
354 DIR *dir, *wil_dir;
355 struct dirent *entry;
356 int ret = -1;
357 const char *root_path = "/sys/kernel/debug/ieee80211";
358
359 dir = opendir(root_path);
360 if (!dir)
361 return -2;
362
363 while ((entry = readdir(dir))) {
364 if (strcmp(entry->d_name, ".") == 0 ||
365 strcmp(entry->d_name, "..") == 0)
366 continue;
367
368 if (snprintf(path, len, "%s/%s/wil6210",
369 root_path, entry->d_name) >= (int) len) {
370 ret = -3;
371 break;
372 }
373
374 wil_dir = opendir(path);
375 if (wil_dir) {
376 closedir(wil_dir);
377 ret = 0;
378 break;
379 }
380 }
381
382 closedir(dir);
383 return ret;
384}
Lior David0fe101e2017-03-09 16:09:50 +0200385
386
387static int wil6210_wmi_send(struct sigma_dut *dut, uint16_t command,
388 void *payload, uint16_t length)
389{
390 struct {
391 struct wil_wmi_header hdr;
392 char payload[WIL_WMI_MAX_PAYLOAD];
393 } __attribute__((packed)) cmd;
394 char buf[128], fname[128];
395 size_t towrite, written;
396 FILE *f;
Jouni Malinen3aa72862019-05-29 23:14:51 +0300397 int res;
Lior David0fe101e2017-03-09 16:09:50 +0200398
399 if (length > WIL_WMI_MAX_PAYLOAD) {
400 sigma_dut_print(dut, DUT_MSG_ERROR,
401 "payload too large(%u, max %u)",
402 length, WIL_WMI_MAX_PAYLOAD);
403 return -1;
404 }
405
406 memset(&cmd.hdr, 0, sizeof(cmd.hdr));
407 cmd.hdr.cmd = command;
408 memcpy(cmd.payload, payload, length);
409
410 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
411 sigma_dut_print(dut, DUT_MSG_ERROR,
412 "failed to get wil6210 debugfs dir");
413 return -1;
414 }
415
Jouni Malinen3aa72862019-05-29 23:14:51 +0300416 res = snprintf(fname, sizeof(fname), "%s/wmi_send", buf);
417 if (res < 0 || res >= sizeof(fname))
418 return -1;
Lior David0fe101e2017-03-09 16:09:50 +0200419 f = fopen(fname, "wb");
420 if (!f) {
421 sigma_dut_print(dut, DUT_MSG_ERROR,
422 "failed to open: %s", fname);
423 return -1;
424 }
425
426 towrite = sizeof(cmd.hdr) + length;
427 written = fwrite(&cmd, 1, towrite, f);
428 fclose(f);
429 if (written != towrite) {
430 sigma_dut_print(dut, DUT_MSG_ERROR,
431 "failed to send wmi %u", command);
432 return -1;
433 }
434
435 return 0;
436}
437
438
439static int wil6210_get_sta_info_field(struct sigma_dut *dut, const char *bssid,
440 const char *pattern, unsigned int *field)
441{
442 char buf[128], fname[128];
443 FILE *f;
444 regex_t re;
445 regmatch_t m[2];
Jouni Malinen3aa72862019-05-29 23:14:51 +0300446 int rc, ret = -1, res;
Lior David0fe101e2017-03-09 16:09:50 +0200447
448 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
449 sigma_dut_print(dut, DUT_MSG_ERROR,
450 "failed to get wil6210 debugfs dir");
451 return -1;
452 }
453
Jouni Malinen3aa72862019-05-29 23:14:51 +0300454 res = snprintf(fname, sizeof(fname), "%s/stations", buf);
455 if (res < 0 || res >= sizeof(fname))
456 return -1;
Lior David0fe101e2017-03-09 16:09:50 +0200457 f = fopen(fname, "r");
458 if (!f) {
459 sigma_dut_print(dut, DUT_MSG_ERROR,
460 "failed to open: %s", fname);
461 return -1;
462 }
463
464 if (regcomp(&re, pattern, REG_EXTENDED)) {
465 sigma_dut_print(dut, DUT_MSG_ERROR,
466 "regcomp failed: %s", pattern);
467 goto out;
468 }
469
470 /*
471 * find the entry for the mac address
472 * line is of the form: [n] 11:22:33:44:55:66 state AID aid
473 */
474 while (fgets(buf, sizeof(buf), f)) {
475 if (strcasestr(buf, bssid)) {
476 /* extract the field (CID/AID/state) */
477 rc = regexec(&re, buf, 2, m, 0);
478 if (!rc && (m[1].rm_so >= 0)) {
479 buf[m[1].rm_eo] = 0;
480 *field = atoi(&buf[m[1].rm_so]);
481 ret = 0;
482 break;
483 }
484 }
485 }
486
487 regfree(&re);
488 if (ret)
489 sigma_dut_print(dut, DUT_MSG_ERROR,
490 "could not extract field");
491
492out:
493 fclose(f);
494
495 return ret;
496}
497
498
499static int wil6210_get_cid(struct sigma_dut *dut, const char *bssid,
500 unsigned int *cid)
501{
502 const char *pattern = "\\[([0-9]+)\\]";
503
504 return wil6210_get_sta_info_field(dut, bssid, pattern, cid);
505}
506
507
508static int wil6210_send_brp_rx(struct sigma_dut *dut, const char *mac,
509 int l_rx)
510{
Rakesh Sunki556237d2017-03-30 14:49:31 -0700511 struct wil_wmi_bf_trig_cmd cmd;
Lior David0fe101e2017-03-09 16:09:50 +0200512 unsigned int cid;
513
Rakesh Sunki556237d2017-03-30 14:49:31 -0700514 memset(&cmd, 0, sizeof(cmd));
515
Lior David0fe101e2017-03-09 16:09:50 +0200516 if (wil6210_get_cid(dut, mac, &cid))
517 return -1;
518
519 cmd.bf_type = WIL_WMI_BRP_RX;
520 cmd.sta_id = cid;
521 /* training length (l_rx) is ignored, FW always uses length 16 */
522 return wil6210_wmi_send(dut, WIL_WMI_BF_TRIG_CMDID,
523 &cmd, sizeof(cmd));
524}
525
526
527static int wil6210_send_sls(struct sigma_dut *dut, const char *mac)
528{
Rakesh Sunki556237d2017-03-30 14:49:31 -0700529 struct wil_wmi_bf_trig_cmd cmd;
530
531 memset(&cmd, 0, sizeof(cmd));
Lior David0fe101e2017-03-09 16:09:50 +0200532
533 if (parse_mac_address(dut, mac, (unsigned char *)&cmd.dest_mac))
534 return -1;
535
536 cmd.bf_type = WIL_WMI_SLS;
537 return wil6210_wmi_send(dut, WIL_WMI_BF_TRIG_CMDID,
538 &cmd, sizeof(cmd));
539}
540
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +0200541
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +0200542int wil6210_set_ese(struct sigma_dut *dut, int count,
543 struct sigma_ese_alloc *allocs)
544{
545 struct wil_wmi_ese_cfg cmd = { };
546 int i;
547
548 if (count == 0 || count > WIL_WMI_MAX_ESE_SLOTS)
549 return -1;
550
551 if (dut->ap_bcnint <= 0) {
552 sigma_dut_print(dut, DUT_MSG_ERROR,
553 "invalid beacon interval(%d), check test",
554 dut->ap_bcnint);
555 return -1;
556 }
557
558 cmd.ese_advertisment = WIL_WMI_ADVERTISE_ESE_IN_BEACON;
559 cmd.flags = 0x1d;
560 cmd.num_allocs = count;
561 for (i = 0; i < count; i++) {
562 /*
563 * Convert percent from BI (BI specified in milliseconds)
564 * to absolute duration in microseconds.
565 */
566 cmd.slots[i].duration =
567 (allocs[i].percent_bi * dut->ap_bcnint * 1000) / 100;
568 switch (allocs[i].type) {
569 case ESE_CBAP:
570 cmd.slots[i].slot_type = WIL_WMI_ESE_CBAP;
571 break;
572 case ESE_SP:
573 cmd.slots[i].slot_type = WIL_WMI_ESE_SP;
574 break;
575 default:
576 sigma_dut_print(dut, DUT_MSG_ERROR,
577 "invalid slot type(%d) at index %d",
578 allocs[i].type, i);
579 return -1;
580 }
581 cmd.slots[i].src_aid = allocs[i].src_aid;
582 cmd.slots[i].dst_aid = allocs[i].dst_aid;
583 sigma_dut_print(dut, DUT_MSG_INFO,
584 "slot %d, duration %u, type %d, srcAID %u dstAID %u",
585 i, cmd.slots[i].duration,
586 cmd.slots[i].slot_type, cmd.slots[i].src_aid,
587 cmd.slots[i].dst_aid);
588 }
589
590 return wil6210_wmi_send(dut, WIL_WMI_ESE_CFG_CMDID, &cmd, sizeof(cmd));
591}
592
593
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +0200594int wil6210_set_force_mcs(struct sigma_dut *dut, int force, int mcs)
595{
596 struct wil_wmi_force_mcs cmd = { };
597
598 cmd.module_id = WIL_WMI_UT_HW_SYSAPI;
599 cmd.subtype_id = WIL_WMI_UT_FORCE_MCS;
600 cmd.force_enable = (uint32_t) force;
601 cmd.mcs = (uint32_t) mcs;
602
603 return wil6210_wmi_send(dut, WIL_WMI_UNIT_TEST_CMDID,
604 &cmd, sizeof(cmd));
605}
606
607
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +0200608static int wil6210_force_rsn_ie(struct sigma_dut *dut, int state)
609{
610 struct wil_wmi_force_rsn_ie cmd = { };
611
612 cmd.module_id = WIL_WMI_UT_HW_SYSAPI;
613 cmd.subtype_id = WIL_WMI_UT_FORCE_RSN_IE;
614 cmd.state = (uint32_t) state;
615
616 return wil6210_wmi_send(dut, WIL_WMI_UNIT_TEST_CMDID,
617 &cmd, sizeof(cmd));
618}
619
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +0300620
621/*
622 * this function is also used to configure generic remain-on-channel
623 */
624static int wil6210_p2p_cfg(struct sigma_dut *dut, int freq)
625{
626 struct wil_wmi_p2p_cfg_cmd cmd = { };
627 int channel = freq_to_channel(freq);
628
629 if (channel < 0)
630 return -1;
631 cmd.discovery_mode = WMI_DISCOVERY_MODE_NON_OFFLOAD;
632 cmd.channel = channel - 1;
633 cmd.bcon_interval = WIL_DEFAULT_BI;
634 cmd.discovery_mode = WMI_DISCOVERY_MODE_PEER2PEER;
635
636 return wil6210_wmi_send(dut, WIL_WMI_P2P_CFG_CMDID,
637 &cmd, sizeof(cmd));
638}
639
640
641static int wil6210_remain_on_channel(struct sigma_dut *dut, int freq)
642{
643 int ret = wil6210_p2p_cfg(dut, freq);
644
645 if (ret)
646 return ret;
647
648 ret = wil6210_wmi_send(dut, WIL_WMI_START_LISTEN_CMDID, NULL, 0);
649 if (!ret) {
650 /*
651 * wait a bit to allow FW to setup the radio
652 * especially important if we switch channels
653 */
654 usleep(500000);
655 }
656
657 return ret;
658}
659
660
661static int wil6210_stop_discovery(struct sigma_dut *dut)
662{
663 return wil6210_wmi_send(dut, WIL_WMI_DISCOVERY_STOP_CMDID, NULL, 0);
664}
665
666
667static int wil6210_transmit_frame(struct sigma_dut *dut, int freq,
668 int wait_duration,
669 const char *frame, size_t frame_len)
670{
671 char buf[128], fname[128];
672 FILE *f;
Jouni Malinen3aa72862019-05-29 23:14:51 +0300673 int res = 0, r;
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +0300674 size_t written;
675
676 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
677 sigma_dut_print(dut, DUT_MSG_ERROR,
678 "failed to get wil6210 debugfs dir");
679 return -1;
680 }
Jouni Malinen3aa72862019-05-29 23:14:51 +0300681 r = snprintf(fname, sizeof(fname), "%s/tx_mgmt", buf);
682 if (r < 0 || r >= sizeof(fname))
683 return -1;
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +0300684
685 if (wil6210_remain_on_channel(dut, freq)) {
686 sigma_dut_print(dut, DUT_MSG_ERROR,
687 "failed to listen on channel");
688 return -1;
689 }
690
691 f = fopen(fname, "wb");
692 if (!f) {
693 sigma_dut_print(dut, DUT_MSG_ERROR,
694 "failed to open: %s", fname);
695 res = -1;
696 goto out_stop;
697 }
698 written = fwrite(frame, 1, frame_len, f);
699 fclose(f);
700
701 if (written != frame_len) {
702 sigma_dut_print(dut, DUT_MSG_ERROR,
703 "failed to transmit frame (got %zd, expected %zd)",
704 written, frame_len);
705 res = -1;
706 goto out_stop;
707 }
708
709 usleep(wait_duration * 1000);
710
711out_stop:
712 wil6210_stop_discovery(dut);
713 return res;
714}
715
716
717static int find_template_frame_tag(struct template_frame_tag *tags,
718 int total_tags, int tag_num)
719{
720 int i;
721
722 for (i = 0; i < total_tags; i++) {
723 if (tag_num == tags[i].num)
724 return i;
725 }
726
727 return -1;
728}
729
730
731static int replace_p2p_attribute(struct sigma_dut *dut, char *buf, size_t len,
732 int id, const char *value, size_t val_len)
733{
734 struct wfa_p2p_attribute *attr = (struct wfa_p2p_attribute *) buf;
735
736 if (len < 3 + val_len) {
737 sigma_dut_print(dut, DUT_MSG_ERROR,
738 "not enough space to replace P2P attribute");
739 return -1;
740 }
741
742 if (attr->len != val_len) {
743 sigma_dut_print(dut, DUT_MSG_ERROR,
744 "attribute length mismatch (need %zu have %hu)",
745 val_len, attr->len);
746 return -1;
747 }
748
749 if (attr->id != id) {
750 sigma_dut_print(dut, DUT_MSG_ERROR,
751 "incorrect attribute id (expected %d actual %d)",
752 id, attr->id);
753 return -1;
754 }
755
756 memcpy(attr->variable, value, val_len);
757
758 return 0;
759}
760
761
762static int parse_template_frame_file(struct sigma_dut *dut, const char *fname,
763 char *buf, size_t *length,
764 struct template_frame_tag *tags,
765 size_t *num_tags)
766{
767 char line[512];
768 FILE *f;
769 size_t offset = 0, tag_index = 0;
770 int num, index;
771 int in_tag = 0, tag_num = 0, tag_offset = 0;
772
773 if (*length < sizeof(struct ieee80211_hdr_3addr)) {
774 sigma_dut_print(dut, DUT_MSG_ERROR,
775 "supplied buffer is too small");
776 return -1;
777 }
778
779 f = fopen(fname, "r");
780 if (!f) {
781 sigma_dut_print(dut, DUT_MSG_ERROR,
782 "failed to open template file %s", fname);
783 return -1;
784 }
785
786 /*
787 * template file format: lines beginning with # are comments and
788 * ignored.
789 * It is possible to tag bytes in the frame to make it easy
790 * to replace fields in the template, espcially if they appear
791 * in variable-sized sections (such as IEs)
792 * This is done by a line beginning with $NUM where NUM is an integer
793 * tag number. It can be followed by space(s) and comment.
794 * The next line is considered the tagged bytes. The parser will fill
795 * the tag number, offset and length of the tagged bytes.
796 * rest of the lines contain frame bytes as sequence of hex digits,
797 * 2 digits for each byte. Spaces are allowed between bytes.
798 * On bytes lines only hex digits and spaces are allowed
799 */
800 while (!feof(f)) {
801 if (!fgets(line, sizeof(line), f))
802 break;
803 index = 0;
804 while (isspace((unsigned char) line[index]))
805 index++;
806 if (!line[index] || line[index] == '#')
807 continue;
808 if (line[index] == '$') {
809 if (tags) {
810 index++;
811 tag_num = strtol(&line[index], NULL, 0);
812 tag_offset = offset;
813 in_tag = 1;
814 }
815 continue;
816 }
817 while (line[index]) {
818 if (isspace((unsigned char) line[index])) {
819 index++;
820 continue;
821 }
822 num = hex_byte(&line[index]);
823 if (num < 0)
824 break;
825 buf[offset++] = num;
826 if (offset == *length)
827 goto out;
828 index += 2;
829 }
830
831 if (in_tag) {
832 if (tag_index < *num_tags) {
833 tags[tag_index].num = tag_num;
834 tags[tag_index].offset = tag_offset;
835 tags[tag_index].len = offset - tag_offset;
836 tag_index++;
837 } else {
838 sigma_dut_print(dut, DUT_MSG_INFO,
839 "too many tags, tag ignored");
840 }
841 in_tag = 0;
842 }
843 }
844
845 if (num_tags)
846 *num_tags = tag_index;
847out:
848 fclose(f);
849 if (offset < sizeof(struct ieee80211_hdr_3addr)) {
850 sigma_dut_print(dut, DUT_MSG_ERROR,
851 "template frame is too small");
852 return -1;
853 }
854
855 *length = offset;
856 return 0;
857}
858
Lior Davidcc88b562017-01-03 18:52:09 +0200859#endif /* __linux__ */
860
861
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200862static void static_ip_file(int proto, const char *addr, const char *mask,
863 const char *gw)
864{
865 if (proto) {
866 FILE *f = fopen("static-ip", "w");
867 if (f) {
868 fprintf(f, "%d %s %s %s\n", proto, addr,
869 mask ? mask : "N/A",
870 gw ? gw : "N/A");
871 fclose(f);
872 }
873 } else {
874 unlink("static-ip");
875 }
876}
877
878
879static int send_neighbor_request(struct sigma_dut *dut, const char *intf,
880 const char *ssid)
881{
882#ifdef __linux__
883 char buf[100];
884
885 snprintf(buf, sizeof(buf), "iwpriv %s neighbor %s",
886 intf, ssid);
887 sigma_dut_print(dut, DUT_MSG_INFO, "Request: %s", buf);
888
889 if (system(buf) != 0) {
890 sigma_dut_print(dut, DUT_MSG_ERROR,
891 "iwpriv neighbor request failed");
892 return -1;
893 }
894
895 sigma_dut_print(dut, DUT_MSG_INFO, "iwpriv neighbor request send");
896
897 return 0;
898#else /* __linux__ */
899 return -1;
900#endif /* __linux__ */
901}
902
903
904static int send_trans_mgmt_query(struct sigma_dut *dut, const char *intf,
Ashwini Patil5acd7382017-04-13 15:55:04 +0530905 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200906{
Ashwini Patil5acd7382017-04-13 15:55:04 +0530907 const char *val;
908 int reason_code = 0;
909 char buf[1024];
910
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200911 /*
912 * In the earlier builds we used WNM_QUERY and in later
913 * builds used WNM_BSS_QUERY.
914 */
915
Ashwini Patil5acd7382017-04-13 15:55:04 +0530916 val = get_param(cmd, "BTMQuery_Reason_Code");
917 if (val)
918 reason_code = atoi(val);
919
920 val = get_param(cmd, "Cand_List");
921 if (val && atoi(val) == 1 && dut->btm_query_cand_list) {
922 snprintf(buf, sizeof(buf), "WNM_BSS_QUERY %d%s", reason_code,
923 dut->btm_query_cand_list);
924 free(dut->btm_query_cand_list);
925 dut->btm_query_cand_list = NULL;
926 } else {
927 snprintf(buf, sizeof(buf), "WNM_BSS_QUERY %d", reason_code);
928 }
929
930 if (wpa_command(intf, buf) != 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200931 sigma_dut_print(dut, DUT_MSG_ERROR,
932 "transition management query failed");
933 return -1;
934 }
935
936 sigma_dut_print(dut, DUT_MSG_DEBUG,
937 "transition management query sent");
938
939 return 0;
940}
941
942
943int is_ip_addr(const char *str)
944{
945 const char *pos = str;
946 struct in_addr addr;
947
948 while (*pos) {
949 if (*pos != '.' && (*pos < '0' || *pos > '9'))
950 return 0;
951 pos++;
952 }
953
954 return inet_aton(str, &addr);
955}
956
957
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200958int get_ip_config(struct sigma_dut *dut, const char *ifname, char *buf,
959 size_t buf_len)
960{
vamsi krishnaa11d0732018-05-16 12:19:48 +0530961 char tmp[256];
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200962 char ip[16], mask[15], dns[16], sec_dns[16];
963 int is_dhcp = 0;
964 int s;
965#ifdef ANDROID
966 char prop[PROPERTY_VALUE_MAX];
vamsi krishnaa11d0732018-05-16 12:19:48 +0530967#else /* ANDROID */
968 FILE *f;
969#ifdef __linux__
970 const char *str_ps;
971#endif /* __linux__ */
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200972#endif /* ANDROID */
973
974 ip[0] = '\0';
975 mask[0] = '\0';
976 dns[0] = '\0';
977 sec_dns[0] = '\0';
978
979 s = socket(PF_INET, SOCK_DGRAM, 0);
980 if (s >= 0) {
981 struct ifreq ifr;
982 struct sockaddr_in saddr;
983
984 memset(&ifr, 0, sizeof(ifr));
Peng Xub8fc5cc2017-05-10 17:27:28 -0700985 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200986 if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
987 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to get "
988 "%s IP address: %s",
989 ifname, strerror(errno));
990 } else {
991 memcpy(&saddr, &ifr.ifr_addr,
992 sizeof(struct sockaddr_in));
Peng Xub8fc5cc2017-05-10 17:27:28 -0700993 strlcpy(ip, inet_ntoa(saddr.sin_addr), sizeof(ip));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200994 }
995
996 if (ioctl(s, SIOCGIFNETMASK, &ifr) == 0) {
997 memcpy(&saddr, &ifr.ifr_addr,
998 sizeof(struct sockaddr_in));
Peng Xub8fc5cc2017-05-10 17:27:28 -0700999 strlcpy(mask, inet_ntoa(saddr.sin_addr), sizeof(mask));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001000 }
1001 close(s);
1002 }
1003
1004#ifdef ANDROID
1005 snprintf(tmp, sizeof(tmp), "dhcp.%s.pid", ifname);
1006 if (property_get(tmp, prop, NULL) != 0 && atoi(prop) > 0) {
1007 snprintf(tmp, sizeof(tmp), "dhcp.%s.result", ifname);
1008 if (property_get(tmp, prop, NULL) != 0 &&
1009 strcmp(prop, "ok") == 0) {
1010 snprintf(tmp, sizeof(tmp), "dhcp.%s.ipaddress",
1011 ifname);
1012 if (property_get(tmp, prop, NULL) != 0 &&
1013 strcmp(ip, prop) == 0)
1014 is_dhcp = 1;
1015 }
1016 }
1017
1018 snprintf(tmp, sizeof(tmp), "dhcp.%s.dns1", ifname);
Peng Xub8fc5cc2017-05-10 17:27:28 -07001019 if (property_get(tmp, prop, NULL) != 0)
1020 strlcpy(dns, prop, sizeof(dns));
1021 else if (property_get("net.dns1", prop, NULL) != 0)
1022 strlcpy(dns, prop, sizeof(dns));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001023
1024 snprintf(tmp, sizeof(tmp), "dhcp.%s.dns2", ifname);
Peng Xub8fc5cc2017-05-10 17:27:28 -07001025 if (property_get(tmp, prop, NULL) != 0)
1026 strlcpy(sec_dns, prop, sizeof(sec_dns));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001027#else /* ANDROID */
1028#ifdef __linux__
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001029 if (get_driver_type(dut) == DRIVER_OPENWRT)
Sarvepalli, Rajesh Babua76c6442016-03-18 20:34:26 +05301030 str_ps = "ps -w";
1031 else
1032 str_ps = "ps ax";
1033 snprintf(tmp, sizeof(tmp),
1034 "%s | grep dhclient | grep -v grep | grep -q %s",
1035 str_ps, ifname);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001036 if (system(tmp) == 0)
1037 is_dhcp = 1;
1038 else {
Sarvepalli, Rajesh Babua76c6442016-03-18 20:34:26 +05301039 snprintf(tmp, sizeof(tmp),
1040 "%s | grep udhcpc | grep -v grep | grep -q %s",
1041 str_ps, ifname);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001042 if (system(tmp) == 0)
1043 is_dhcp = 1;
1044 else {
Sarvepalli, Rajesh Babua76c6442016-03-18 20:34:26 +05301045 snprintf(tmp, sizeof(tmp),
1046 "%s | grep dhcpcd | grep -v grep | grep -q %s",
1047 str_ps, ifname);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001048 if (system(tmp) == 0)
1049 is_dhcp = 1;
1050 }
1051 }
1052#endif /* __linux__ */
1053
1054 f = fopen("/etc/resolv.conf", "r");
1055 if (f) {
vamsi krishnaa11d0732018-05-16 12:19:48 +05301056 char *pos, *pos2;
1057
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001058 while (fgets(tmp, sizeof(tmp), f)) {
1059 if (strncmp(tmp, "nameserver", 10) != 0)
1060 continue;
1061 pos = tmp + 10;
1062 while (*pos == ' ' || *pos == '\t')
1063 pos++;
1064 pos2 = pos;
1065 while (*pos2) {
1066 if (*pos2 == '\n' || *pos2 == '\r') {
1067 *pos2 = '\0';
1068 break;
1069 }
1070 pos2++;
1071 }
Peng Xub8fc5cc2017-05-10 17:27:28 -07001072 if (!dns[0])
1073 strlcpy(dns, pos, sizeof(dns));
1074 else if (!sec_dns[0])
1075 strlcpy(sec_dns, pos, sizeof(sec_dns));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001076 }
1077 fclose(f);
1078 }
1079#endif /* ANDROID */
1080
1081 snprintf(buf, buf_len, "dhcp,%d,ip,%s,mask,%s,primary-dns,%s",
1082 is_dhcp, ip, mask, dns);
1083 buf[buf_len - 1] = '\0';
1084
1085 return 0;
1086}
1087
1088
1089
1090
1091int get_ipv6_config(struct sigma_dut *dut, const char *ifname, char *buf,
1092 size_t buf_len)
1093{
1094#ifdef __linux__
1095#ifdef ANDROID
1096 char cmd[200], result[1000], *pos, *end;
1097 FILE *f;
1098 size_t len;
1099
1100 snprintf(cmd, sizeof(cmd), "ip addr show dev %s scope global", ifname);
1101 f = popen(cmd, "r");
1102 if (f == NULL)
1103 return -1;
1104 len = fread(result, 1, sizeof(result) - 1, f);
1105 pclose(f);
1106 if (len == 0)
1107 return -1;
1108 result[len] = '\0';
1109 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s result: %s\n", cmd, result);
1110
1111 pos = strstr(result, "inet6 ");
1112 if (pos == NULL)
1113 return -1;
1114 pos += 6;
1115 end = strchr(pos, ' ');
1116 if (end)
1117 *end = '\0';
1118 end = strchr(pos, '/');
1119 if (end)
1120 *end = '\0';
1121 snprintf(buf, buf_len, "ip,%s", pos);
1122 buf[buf_len - 1] = '\0';
1123 return 0;
1124#else /* ANDROID */
1125 struct ifaddrs *ifaddr, *ifa;
1126 int res, found = 0;
1127 char host[NI_MAXHOST];
1128
1129 if (getifaddrs(&ifaddr) < 0) {
1130 perror("getifaddrs");
1131 return -1;
1132 }
1133
1134 for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
1135 if (strcasecmp(ifname, ifa->ifa_name) != 0)
1136 continue;
1137 if (ifa->ifa_addr == NULL ||
1138 ifa->ifa_addr->sa_family != AF_INET6)
1139 continue;
1140
1141 res = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in6),
1142 host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
1143 if (res != 0) {
1144 sigma_dut_print(dut, DUT_MSG_DEBUG, "getnameinfo: %s",
1145 gai_strerror(res));
1146 continue;
1147 }
1148 if (strncmp(host, "fe80::", 6) == 0)
1149 continue; /* skip link-local */
1150
1151 sigma_dut_print(dut, DUT_MSG_DEBUG, "ifaddr: %s", host);
1152 found = 1;
1153 break;
1154 }
1155
1156 freeifaddrs(ifaddr);
1157
1158 if (found) {
1159 char *pos;
1160 pos = strchr(host, '%');
1161 if (pos)
1162 *pos = '\0';
1163 snprintf(buf, buf_len, "ip,%s", host);
1164 buf[buf_len - 1] = '\0';
1165 return 0;
1166 }
1167
1168#endif /* ANDROID */
1169#endif /* __linux__ */
1170 return -1;
1171}
1172
1173
Jouni Malinenf7222712019-06-13 01:50:21 +03001174static enum sigma_cmd_result cmd_sta_get_ip_config(struct sigma_dut *dut,
1175 struct sigma_conn *conn,
1176 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001177{
1178 const char *intf = get_param(cmd, "Interface");
1179 const char *ifname;
1180 char buf[200];
1181 const char *val;
1182 int type = 1;
1183
1184 if (intf == NULL)
1185 return -1;
1186
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001187 if (strcmp(intf, get_main_ifname(dut)) == 0)
1188 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001189 else
1190 ifname = intf;
1191
1192 /*
1193 * UCC may assume the IP address to be available immediately after
1194 * association without trying to run sta_get_ip_config multiple times.
1195 * Sigma CAPI does not specify this command as a block command that
1196 * would wait for the address to become available, but to pass tests
1197 * more reliably, it looks like such a wait may be needed here.
1198 */
1199 if (wait_ip_addr(dut, ifname, 15) < 0) {
1200 sigma_dut_print(dut, DUT_MSG_INFO, "Could not get IP address "
1201 "for sta_get_ip_config");
1202 /*
1203 * Try to continue anyway since many UCC tests do not really
1204 * care about the return value from here..
1205 */
1206 }
1207
1208 val = get_param(cmd, "Type");
1209 if (val)
1210 type = atoi(val);
1211 if (type == 2 || dut->last_set_ip_config_ipv6) {
1212 int i;
1213
1214 /*
1215 * Since we do not have proper wait for IPv6 addresses, use a
1216 * fixed two second delay here as a workaround for UCC script
1217 * assuming IPv6 address is available when this command returns.
1218 * Some scripts did not use Type,2 properly for IPv6, so include
1219 * also the cases where the previous sta_set_ip_config indicated
1220 * use of IPv6.
1221 */
1222 sigma_dut_print(dut, DUT_MSG_INFO, "Wait up to extra ten seconds in sta_get_ip_config for IPv6 address");
1223 for (i = 0; i < 10; i++) {
1224 sleep(1);
1225 if (get_ipv6_config(dut, ifname, buf, sizeof(buf)) == 0)
1226 {
1227 sigma_dut_print(dut, DUT_MSG_INFO, "Found IPv6 address");
1228 send_resp(dut, conn, SIGMA_COMPLETE, buf);
1229#ifdef ANDROID
1230 sigma_dut_print(dut, DUT_MSG_INFO,
1231 "Adding IPv6 rule on Android");
1232 add_ipv6_rule(dut, intf);
1233#endif /* ANDROID */
1234
1235 return 0;
1236 }
1237 }
1238 }
1239 if (type == 1) {
1240 if (get_ip_config(dut, ifname, buf, sizeof(buf)) < 0)
1241 return -2;
1242 } else if (type == 2) {
1243 if (get_ipv6_config(dut, ifname, buf, sizeof(buf)) < 0)
1244 return -2;
1245 } else {
1246 send_resp(dut, conn, SIGMA_ERROR,
1247 "errorCode,Unsupported address type");
1248 return 0;
1249 }
1250
1251 send_resp(dut, conn, SIGMA_COMPLETE, buf);
1252 return 0;
1253}
1254
1255
1256static void kill_dhcp_client(struct sigma_dut *dut, const char *ifname)
1257{
1258#ifdef __linux__
1259 char buf[200];
1260 char path[128];
1261 struct stat s;
1262
1263#ifdef ANDROID
1264 snprintf(path, sizeof(path), "/data/misc/dhcp/dhcpcd-%s.pid", ifname);
1265#else /* ANDROID */
1266 snprintf(path, sizeof(path), "/var/run/dhclient-%s.pid", ifname);
1267#endif /* ANDROID */
1268 if (stat(path, &s) == 0) {
1269 snprintf(buf, sizeof(buf), "kill `cat %s`", path);
1270 sigma_dut_print(dut, DUT_MSG_INFO,
1271 "Kill previous DHCP client: %s", buf);
1272 if (system(buf) != 0)
1273 sigma_dut_print(dut, DUT_MSG_INFO,
1274 "Failed to kill DHCP client");
1275 unlink(path);
1276 sleep(1);
1277 } else {
1278 snprintf(path, sizeof(path), "/var/run/dhcpcd-%s.pid", ifname);
1279
1280 if (stat(path, &s) == 0) {
1281 snprintf(buf, sizeof(buf), "kill `cat %s`", path);
1282 sigma_dut_print(dut, DUT_MSG_INFO,
1283 "Kill previous DHCP client: %s", buf);
1284 if (system(buf) != 0)
1285 sigma_dut_print(dut, DUT_MSG_INFO,
1286 "Failed to kill DHCP client");
1287 unlink(path);
1288 sleep(1);
1289 }
1290 }
1291#endif /* __linux__ */
1292}
1293
1294
1295static int start_dhcp_client(struct sigma_dut *dut, const char *ifname)
1296{
1297#ifdef __linux__
1298 char buf[200];
1299
1300#ifdef ANDROID
Purushottam Kushwaha46d64262016-08-23 17:57:53 +05301301 if (access("/system/bin/dhcpcd", F_OK) != -1) {
1302 snprintf(buf, sizeof(buf),
1303 "/system/bin/dhcpcd -b %s", ifname);
1304 } else if (access("/system/bin/dhcptool", F_OK) != -1) {
1305 snprintf(buf, sizeof(buf), "/system/bin/dhcptool %s &", ifname);
Ankita Bajaj8454e5d2019-04-05 16:04:55 +05301306 } else if (access("/vendor/bin/dhcpcd", F_OK) != -1) {
1307 snprintf(buf, sizeof(buf), "/vendor/bin/dhcpcd -b %s", ifname);
1308 } else if (access("/vendor/bin/dhcptool", F_OK) != -1) {
1309 snprintf(buf, sizeof(buf), "/vendor/bin/dhcptool %s", ifname);
Purushottam Kushwaha46d64262016-08-23 17:57:53 +05301310 } else {
1311 sigma_dut_print(dut, DUT_MSG_ERROR,
1312 "DHCP client program missing");
1313 return 0;
1314 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001315#else /* ANDROID */
1316 snprintf(buf, sizeof(buf),
1317 "dhclient -nw -pf /var/run/dhclient-%s.pid %s",
1318 ifname, ifname);
1319#endif /* ANDROID */
1320 sigma_dut_print(dut, DUT_MSG_INFO, "Start DHCP client: %s", buf);
1321 if (system(buf) != 0) {
1322 snprintf(buf, sizeof(buf), "dhcpcd -t 0 %s &", ifname);
1323 if (system(buf) != 0) {
1324 sigma_dut_print(dut, DUT_MSG_INFO,
1325 "Failed to start DHCP client");
1326#ifndef ANDROID
1327 return -1;
1328#endif /* ANDROID */
1329 }
1330 }
1331#endif /* __linux__ */
1332
1333 return 0;
1334}
1335
1336
1337static int clear_ip_addr(struct sigma_dut *dut, const char *ifname)
1338{
1339#ifdef __linux__
1340 char buf[200];
1341
1342 snprintf(buf, sizeof(buf), "ip addr flush dev %s", ifname);
1343 if (system(buf) != 0) {
1344 sigma_dut_print(dut, DUT_MSG_INFO,
1345 "Failed to clear IP addresses");
1346 return -1;
1347 }
1348#endif /* __linux__ */
1349
1350 return 0;
1351}
1352
1353
1354#ifdef ANDROID
1355static int add_ipv6_rule(struct sigma_dut *dut, const char *ifname)
1356{
1357 char cmd[200], *result, *pos;
1358 FILE *fp;
Pradeep Reddy POTTETIf58a1fe2016-10-13 17:22:03 +05301359 int tableid;
1360 size_t len, result_len = 1000;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001361
1362 snprintf(cmd, sizeof(cmd), "ip -6 route list table all | grep %s",
1363 ifname);
1364 fp = popen(cmd, "r");
1365 if (fp == NULL)
1366 return -1;
1367
1368 result = malloc(result_len);
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05301369 if (result == NULL) {
1370 fclose(fp);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001371 return -1;
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05301372 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001373
Pradeep Reddy POTTETIf58a1fe2016-10-13 17:22:03 +05301374 len = fread(result, 1, result_len - 1, fp);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001375 fclose(fp);
1376
1377 if (len == 0) {
1378 free(result);
1379 return -1;
1380 }
Pradeep Reddy POTTETIf58a1fe2016-10-13 17:22:03 +05301381 result[len] = '\0';
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001382
1383 pos = strstr(result, "table ");
1384 if (pos == NULL) {
1385 free(result);
1386 return -1;
1387 }
1388
1389 pos += strlen("table ");
1390 tableid = atoi(pos);
1391 if (tableid != 0) {
1392 if (system("ip -6 rule del prio 22000") != 0) {
1393 /* ignore any error */
1394 }
1395 snprintf(cmd, sizeof(cmd),
1396 "ip -6 rule add from all lookup %d prio 22000",
1397 tableid);
1398 if (system(cmd) != 0) {
1399 sigma_dut_print(dut, DUT_MSG_INFO,
1400 "Failed to run %s", cmd);
1401 free(result);
1402 return -1;
1403 }
1404 } else {
1405 sigma_dut_print(dut, DUT_MSG_INFO,
1406 "No Valid Table Id found %s", pos);
1407 free(result);
1408 return -1;
1409 }
1410 free(result);
1411
1412 return 0;
1413}
1414#endif /* ANDROID */
1415
1416
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301417int set_ipv4_addr(struct sigma_dut *dut, const char *ifname,
1418 const char *ip, const char *mask)
1419{
1420 char buf[200];
1421
1422 snprintf(buf, sizeof(buf), "ifconfig %s %s netmask %s",
1423 ifname, ip, mask);
1424 return system(buf) == 0;
1425}
1426
1427
1428int set_ipv4_gw(struct sigma_dut *dut, const char *gw)
1429{
1430 char buf[200];
1431
1432 if (!is_ip_addr(gw)) {
1433 sigma_dut_print(dut, DUT_MSG_DEBUG, "Invalid gw addr - %s", gw);
1434 return -1;
1435 }
1436
1437 snprintf(buf, sizeof(buf), "route add default gw %s", gw);
1438 if (!dut->no_ip_addr_set && system(buf) != 0) {
1439 snprintf(buf, sizeof(buf), "ip ro re default via %s",
1440 gw);
1441 if (system(buf) != 0)
1442 return 0;
1443 }
1444
1445 return 1;
1446}
1447
1448
Jouni Malinenf7222712019-06-13 01:50:21 +03001449static enum sigma_cmd_result cmd_sta_set_ip_config(struct sigma_dut *dut,
1450 struct sigma_conn *conn,
1451 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001452{
1453 const char *intf = get_param(cmd, "Interface");
1454 const char *ifname;
1455 char buf[200];
1456 const char *val, *ip, *mask, *gw;
1457 int type = 1;
1458
1459 if (intf == NULL)
1460 return -1;
1461
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001462 if (strcmp(intf, get_main_ifname(dut)) == 0)
1463 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001464 else
1465 ifname = intf;
1466
1467 if (if_nametoindex(ifname) == 0) {
1468 send_resp(dut, conn, SIGMA_ERROR,
1469 "ErrorCode,Unknown interface");
1470 return 0;
1471 }
1472
1473 val = get_param(cmd, "Type");
1474 if (val) {
1475 type = atoi(val);
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301476 if (type < 1 || type > 3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001477 send_resp(dut, conn, SIGMA_ERROR,
1478 "ErrorCode,Unsupported address type");
1479 return 0;
1480 }
1481 }
1482
1483 dut->last_set_ip_config_ipv6 = 0;
1484
1485 val = get_param(cmd, "dhcp");
1486 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "true") == 0)) {
1487 static_ip_file(0, NULL, NULL, NULL);
1488#ifdef __linux__
1489 if (type == 2) {
1490 dut->last_set_ip_config_ipv6 = 1;
1491 sigma_dut_print(dut, DUT_MSG_INFO, "Using IPv6 "
1492 "stateless address autoconfiguration");
1493#ifdef ANDROID
1494 /*
1495 * This sleep is required as the assignment in case of
1496 * Android is taking time and is done by the kernel.
1497 * The subsequent ping for IPv6 is impacting HS20 test
1498 * case.
1499 */
1500 sleep(2);
1501 add_ipv6_rule(dut, intf);
1502#endif /* ANDROID */
1503 /* Assume this happens by default */
1504 return 1;
1505 }
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301506 if (type != 3) {
1507 kill_dhcp_client(dut, ifname);
1508 if (start_dhcp_client(dut, ifname) < 0)
1509 return -2;
1510 } else {
1511 sigma_dut_print(dut, DUT_MSG_DEBUG,
1512 "Using FILS HLP DHCPv4 Rapid Commit");
1513 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001514
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001515 return 1;
1516#endif /* __linux__ */
1517 return -2;
1518 }
1519
1520 ip = get_param(cmd, "ip");
Pradeep Reddy POTTETIb18c5652016-01-18 12:45:37 +05301521 if (!ip) {
1522 send_resp(dut, conn, SIGMA_INVALID,
1523 "ErrorCode,Missing IP address");
1524 return 0;
1525 }
1526
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001527 mask = get_param(cmd, "mask");
Pradeep Reddy POTTETIb18c5652016-01-18 12:45:37 +05301528 if (!mask) {
1529 send_resp(dut, conn, SIGMA_INVALID,
1530 "ErrorCode,Missing subnet mask");
1531 return 0;
1532 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001533
1534 if (type == 2) {
1535 int net = atoi(mask);
1536
1537 if ((net < 0 && net > 64) || !is_ipv6_addr(ip))
1538 return -1;
1539
1540 if (dut->no_ip_addr_set) {
1541 snprintf(buf, sizeof(buf),
1542 "sysctl net.ipv6.conf.%s.disable_ipv6=1",
1543 ifname);
1544 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
1545 if (system(buf) != 0) {
1546 sigma_dut_print(dut, DUT_MSG_DEBUG,
1547 "Failed to disable IPv6 address before association");
1548 }
1549 } else {
Veerendranath Jakkam176181c2020-05-16 00:19:21 +05301550 if (set_ipv6_addr(dut, ip, mask, ifname) != 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001551 send_resp(dut, conn, SIGMA_ERROR,
1552 "ErrorCode,Failed to set IPv6 address");
1553 return 0;
1554 }
1555 }
1556
1557 dut->last_set_ip_config_ipv6 = 1;
1558 static_ip_file(6, ip, mask, NULL);
1559 return 1;
1560 } else if (type == 1) {
Pradeep Reddy POTTETIb18c5652016-01-18 12:45:37 +05301561 if (!is_ip_addr(ip) || !is_ip_addr(mask))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001562 return -1;
1563 }
1564
1565 kill_dhcp_client(dut, ifname);
1566
1567 if (!dut->no_ip_addr_set) {
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301568 if (!set_ipv4_addr(dut, ifname, ip, mask)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001569 send_resp(dut, conn, SIGMA_ERROR,
1570 "ErrorCode,Failed to set IP address");
1571 return 0;
1572 }
1573 }
1574
1575 gw = get_param(cmd, "defaultGateway");
1576 if (gw) {
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301577 if (set_ipv4_gw(dut, gw) < 1) {
1578 send_resp(dut, conn, SIGMA_ERROR,
1579 "ErrorCode,Failed to set default gateway");
1580 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001581 }
1582 }
1583
1584 val = get_param(cmd, "primary-dns");
1585 if (val) {
Vinita S. Maloo069e8d42021-04-29 13:15:08 +05301586#ifdef ANDROID
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001587 /* TODO */
1588 sigma_dut_print(dut, DUT_MSG_INFO, "Ignored primary-dns %s "
1589 "setting", val);
Vinita S. Maloo069e8d42021-04-29 13:15:08 +05301590#else /* ANDROID */
1591 char dns_cmd[200];
1592 int len;
1593
1594 if (system("sed -i '/nameserver/d' /etc/resolv.conf") != 0) {
1595 sigma_dut_print(dut, DUT_MSG_ERROR,
1596 "Failed to clear nameserver entries in /etc/resolv.conf");
1597 return ERROR_SEND_STATUS;
1598 }
1599
1600 len = snprintf(dns_cmd, sizeof(dns_cmd),
1601 "sed -i '1 i nameserver %s' /etc/resolv.conf", val);
1602 if (len < 0 || len >= sizeof(dns_cmd))
1603 return ERROR_SEND_STATUS;
1604
1605 sigma_dut_print(dut, DUT_MSG_DEBUG, "Running %s", dns_cmd);
1606 if (system(dns_cmd) != 0) {
1607 send_resp(dut, conn, SIGMA_ERROR,
1608 "ErrorCode,Failed to set primary-dns");
1609 return STATUS_SENT_ERROR;
1610 }
1611#endif /* ANDROID */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001612 }
1613
1614 val = get_param(cmd, "secondary-dns");
1615 if (val) {
1616 /* TODO */
1617 sigma_dut_print(dut, DUT_MSG_INFO, "Ignored secondary-dns %s "
1618 "setting", val);
1619 }
1620
1621 static_ip_file(4, ip, mask, gw);
1622
1623 return 1;
1624}
1625
1626
Jouni Malinenf7222712019-06-13 01:50:21 +03001627static enum sigma_cmd_result cmd_sta_get_info(struct sigma_dut *dut,
1628 struct sigma_conn *conn,
1629 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001630{
1631 /* const char *intf = get_param(cmd, "Interface"); */
1632 /* TODO: could report more details here */
1633 send_resp(dut, conn, SIGMA_COMPLETE, "vendor,Atheros");
1634 return 0;
1635}
1636
1637
Jouni Malinenf7222712019-06-13 01:50:21 +03001638static enum sigma_cmd_result cmd_sta_get_mac_address(struct sigma_dut *dut,
1639 struct sigma_conn *conn,
1640 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001641{
1642 /* const char *intf = get_param(cmd, "Interface"); */
1643 char addr[20], resp[50];
1644
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05301645 if (dut->dev_role == DEVROLE_STA_CFON)
1646 return sta_cfon_get_mac_address(dut, conn, cmd);
1647
Jouni Malinen9540e012019-11-05 17:08:42 +02001648 start_sta_mode(dut);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001649 if (get_wpa_status(get_station_ifname(dut), "address",
1650 addr, sizeof(addr)) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001651 return -2;
1652
1653 snprintf(resp, sizeof(resp), "mac,%s", addr);
1654 send_resp(dut, conn, SIGMA_COMPLETE, resp);
1655 return 0;
1656}
1657
1658
Jouni Malinenf7222712019-06-13 01:50:21 +03001659static enum sigma_cmd_result cmd_sta_is_connected(struct sigma_dut *dut,
1660 struct sigma_conn *conn,
1661 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001662{
1663 /* const char *intf = get_param(cmd, "Interface"); */
1664 int connected = 0;
1665 char result[32];
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001666 if (get_wpa_status(get_station_ifname(dut), "wpa_state", result,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001667 sizeof(result)) < 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001668 sigma_dut_print(dut, DUT_MSG_INFO,
1669 "Could not get interface %s status",
1670 get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001671 return -2;
1672 }
1673
1674 sigma_dut_print(dut, DUT_MSG_DEBUG, "wpa_state=%s", result);
1675 if (strncmp(result, "COMPLETED", 9) == 0)
1676 connected = 1;
1677
1678 if (connected)
1679 send_resp(dut, conn, SIGMA_COMPLETE, "connected,1");
1680 else
1681 send_resp(dut, conn, SIGMA_COMPLETE, "connected,0");
1682
1683 return 0;
1684}
1685
1686
Jouni Malinenf7222712019-06-13 01:50:21 +03001687static enum sigma_cmd_result
1688cmd_sta_verify_ip_connection(struct sigma_dut *dut, struct sigma_conn *conn,
1689 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001690{
1691 /* const char *intf = get_param(cmd, "Interface"); */
1692 const char *dst, *timeout;
1693 int wait_time = 90;
1694 char buf[100];
1695 int res;
1696
1697 dst = get_param(cmd, "destination");
1698 if (dst == NULL || !is_ip_addr(dst))
1699 return -1;
1700
1701 timeout = get_param(cmd, "timeout");
1702 if (timeout) {
1703 wait_time = atoi(timeout);
1704 if (wait_time < 1)
1705 wait_time = 1;
1706 }
1707
1708 /* TODO: force renewal of IP lease if DHCP is enabled */
1709
1710 snprintf(buf, sizeof(buf), "ping %s -c 3 -W %d", dst, wait_time);
1711 res = system(buf);
1712 sigma_dut_print(dut, DUT_MSG_DEBUG, "ping returned: %d", res);
1713 if (res == 0)
1714 send_resp(dut, conn, SIGMA_COMPLETE, "connected,1");
1715 else if (res == 256)
1716 send_resp(dut, conn, SIGMA_COMPLETE, "connected,0");
1717 else
1718 return -2;
1719
1720 return 0;
1721}
1722
1723
Jouni Malinenf7222712019-06-13 01:50:21 +03001724static enum sigma_cmd_result cmd_sta_get_bssid(struct sigma_dut *dut,
1725 struct sigma_conn *conn,
1726 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001727{
1728 /* const char *intf = get_param(cmd, "Interface"); */
1729 char bssid[20], resp[50];
1730
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001731 if (get_wpa_status(get_station_ifname(dut), "bssid",
1732 bssid, sizeof(bssid)) < 0)
Peng Xub8fc5cc2017-05-10 17:27:28 -07001733 strlcpy(bssid, "00:00:00:00:00:00", sizeof(bssid));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001734
1735 snprintf(resp, sizeof(resp), "bssid,%s", bssid);
1736 send_resp(dut, conn, SIGMA_COMPLETE, resp);
1737 return 0;
1738}
1739
1740
1741#ifdef __SAMSUNG__
1742static int add_use_network(const char *ifname)
1743{
1744 char buf[100];
1745
1746 snprintf(buf, sizeof(buf), "USE_NETWORK ON");
1747 wpa_command(ifname, buf);
1748 return 0;
1749}
1750#endif /* __SAMSUNG__ */
1751
1752
1753static int add_network_common(struct sigma_dut *dut, struct sigma_conn *conn,
1754 const char *ifname, struct sigma_cmd *cmd)
1755{
1756 const char *ssid = get_param(cmd, "ssid");
1757 int id;
1758 const char *val;
1759
1760 if (ssid == NULL)
1761 return -1;
1762
1763 start_sta_mode(dut);
1764
1765#ifdef __SAMSUNG__
1766 add_use_network(ifname);
1767#endif /* __SAMSUNG__ */
1768
1769 id = add_network(ifname);
1770 if (id < 0)
1771 return -2;
1772 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding network %d", id);
1773
1774 if (set_network_quoted(ifname, id, "ssid", ssid) < 0)
1775 return -2;
1776
1777 dut->infra_network_id = id;
1778 snprintf(dut->infra_ssid, sizeof(dut->infra_ssid), "%s", ssid);
1779
1780 val = get_param(cmd, "program");
1781 if (!val)
1782 val = get_param(cmd, "prog");
1783 if (val && strcasecmp(val, "hs2") == 0) {
1784 char buf[100];
1785 snprintf(buf, sizeof(buf), "ENABLE_NETWORK %d no-connect", id);
1786 wpa_command(ifname, buf);
1787
1788 val = get_param(cmd, "prefer");
1789 if (val && atoi(val) > 0)
1790 set_network(ifname, id, "priority", "1");
1791 }
1792
1793 return id;
1794}
1795
1796
Jouni Malinenf7222712019-06-13 01:50:21 +03001797static enum sigma_cmd_result cmd_sta_set_encryption(struct sigma_dut *dut,
1798 struct sigma_conn *conn,
1799 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001800{
1801 const char *intf = get_param(cmd, "Interface");
1802 const char *ssid = get_param(cmd, "ssid");
1803 const char *type = get_param(cmd, "encpType");
1804 const char *ifname;
1805 char buf[200];
1806 int id;
1807
1808 if (intf == NULL || ssid == NULL)
1809 return -1;
1810
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001811 if (strcmp(intf, get_main_ifname(dut)) == 0)
1812 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001813 else
1814 ifname = intf;
1815
1816 id = add_network_common(dut, conn, ifname, cmd);
1817 if (id < 0)
1818 return id;
1819
1820 if (set_network(ifname, id, "key_mgmt", "NONE") < 0)
1821 return -2;
1822
1823 if (type && strcasecmp(type, "wep") == 0) {
1824 const char *val;
1825 int i;
1826
1827 val = get_param(cmd, "activeKey");
1828 if (val) {
1829 int keyid;
1830 keyid = atoi(val);
1831 if (keyid < 1 || keyid > 4)
1832 return -1;
1833 snprintf(buf, sizeof(buf), "%d", keyid - 1);
1834 if (set_network(ifname, id, "wep_tx_keyidx", buf) < 0)
1835 return -2;
1836 }
1837
1838 for (i = 0; i < 4; i++) {
1839 snprintf(buf, sizeof(buf), "key%d", i + 1);
1840 val = get_param(cmd, buf);
1841 if (val == NULL)
1842 continue;
1843 snprintf(buf, sizeof(buf), "wep_key%d", i);
1844 if (set_network(ifname, id, buf, val) < 0)
1845 return -2;
1846 }
1847 }
1848
1849 return 1;
1850}
1851
1852
Jouni Malinene4fde732019-03-25 22:29:37 +02001853static int set_akm_suites(struct sigma_dut *dut, const char *ifname,
1854 int id, const char *val)
1855{
1856 char key_mgmt[200], *end, *pos;
1857 const char *in_pos = val;
1858
Jouni Malinen8179fee2019-03-28 03:19:47 +02001859 dut->akm_values = 0;
Jouni Malinene4fde732019-03-25 22:29:37 +02001860 pos = key_mgmt;
1861 end = pos + sizeof(key_mgmt);
1862 while (*in_pos) {
1863 int res, akm = atoi(in_pos);
1864 const char *str;
1865
Jouni Malinen8179fee2019-03-28 03:19:47 +02001866 if (akm >= 0 && akm < 32)
1867 dut->akm_values |= 1 << akm;
1868
Jouni Malinene4fde732019-03-25 22:29:37 +02001869 switch (akm) {
1870 case AKM_WPA_EAP:
1871 str = "WPA-EAP";
1872 break;
1873 case AKM_WPA_PSK:
1874 str = "WPA-PSK";
1875 break;
1876 case AKM_FT_EAP:
1877 str = "FT-EAP";
1878 break;
1879 case AKM_FT_PSK:
1880 str = "FT-PSK";
1881 break;
1882 case AKM_EAP_SHA256:
1883 str = "WPA-EAP-SHA256";
1884 break;
1885 case AKM_PSK_SHA256:
1886 str = "WPA-PSK-SHA256";
1887 break;
1888 case AKM_SAE:
1889 str = "SAE";
1890 break;
1891 case AKM_FT_SAE:
1892 str = "FT-SAE";
1893 break;
1894 case AKM_SUITE_B:
1895 str = "WPA-EAP-SUITE-B-192";
1896 break;
1897 case AKM_FT_SUITE_B:
1898 str = "FT-EAP-SHA384";
1899 break;
1900 case AKM_FILS_SHA256:
1901 str = "FILS-SHA256";
1902 break;
1903 case AKM_FILS_SHA384:
1904 str = "FILS-SHA384";
1905 break;
1906 case AKM_FT_FILS_SHA256:
1907 str = "FT-FILS-SHA256";
1908 break;
1909 case AKM_FT_FILS_SHA384:
1910 str = "FT-FILS-SHA384";
1911 break;
1912 default:
1913 sigma_dut_print(dut, DUT_MSG_ERROR,
1914 "Unsupported AKMSuitetype %d", akm);
1915 return -1;
1916 }
1917
1918 res = snprintf(pos, end - pos, "%s%s",
1919 pos == key_mgmt ? "" : " ", str);
1920 if (res < 0 || res >= end - pos)
1921 return -1;
1922 pos += res;
1923
1924 in_pos = strchr(in_pos, ';');
1925 if (!in_pos)
1926 break;
1927 while (*in_pos == ';')
1928 in_pos++;
1929 }
1930 sigma_dut_print(dut, DUT_MSG_DEBUG, "AKMSuiteType %s --> %s",
1931 val, key_mgmt);
1932 return set_network(ifname, id, "key_mgmt", key_mgmt);
1933}
1934
1935
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001936static int set_wpa_common(struct sigma_dut *dut, struct sigma_conn *conn,
1937 const char *ifname, struct sigma_cmd *cmd)
1938{
1939 const char *val;
1940 int id;
Jouni Malinenad395a22017-09-01 21:13:46 +03001941 int cipher_set = 0;
Jouni Malinen47dcc952017-10-09 16:43:24 +03001942 int owe;
Sunil Duttc75a1e62018-01-11 20:47:50 +05301943 int suite_b = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001944
1945 id = add_network_common(dut, conn, ifname, cmd);
1946 if (id < 0)
1947 return id;
1948
Jouni Malinen47dcc952017-10-09 16:43:24 +03001949 val = get_param(cmd, "Type");
1950 owe = val && strcasecmp(val, "OWE") == 0;
1951
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001952 val = get_param(cmd, "keyMgmtType");
Jouni Malinen47dcc952017-10-09 16:43:24 +03001953 if (!val && owe)
1954 val = "OWE";
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001955 if (val == NULL) {
Jouni Malinene4fde732019-03-25 22:29:37 +02001956 /* keyMgmtType is being replaced with AKMSuiteType, so ignore
1957 * this missing parameter and assume proto=WPA2. */
1958 if (set_network(ifname, id, "proto", "WPA2") < 0)
1959 return ERROR_SEND_STATUS;
1960 } else if (strcasecmp(val, "wpa") == 0 ||
1961 strcasecmp(val, "wpa-psk") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001962 if (set_network(ifname, id, "proto", "WPA") < 0)
1963 return -2;
1964 } else if (strcasecmp(val, "wpa2") == 0 ||
1965 strcasecmp(val, "wpa2-psk") == 0 ||
1966 strcasecmp(val, "wpa2-ft") == 0 ||
1967 strcasecmp(val, "wpa2-sha256") == 0) {
1968 if (set_network(ifname, id, "proto", "WPA2") < 0)
1969 return -2;
Pradeep Reddy POTTETI6d04b3b2016-11-15 14:51:26 +05301970 } else if (strcasecmp(val, "wpa2-wpa-psk") == 0 ||
1971 strcasecmp(val, "wpa2-wpa-ent") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001972 if (set_network(ifname, id, "proto", "WPA WPA2") < 0)
1973 return -2;
Jouni Malinenad395a22017-09-01 21:13:46 +03001974 } else if (strcasecmp(val, "SuiteB") == 0) {
Sunil Duttc75a1e62018-01-11 20:47:50 +05301975 suite_b = 1;
Jouni Malinenad395a22017-09-01 21:13:46 +03001976 if (set_network(ifname, id, "proto", "WPA2") < 0)
1977 return -2;
Jouni Malinen47dcc952017-10-09 16:43:24 +03001978 } else if (strcasecmp(val, "OWE") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001979 } else {
1980 send_resp(dut, conn, SIGMA_INVALID, "errorCode,Unrecognized keyMgmtType value");
1981 return 0;
1982 }
1983
1984 val = get_param(cmd, "encpType");
Jouni Malinenad395a22017-09-01 21:13:46 +03001985 if (val) {
1986 cipher_set = 1;
1987 if (strcasecmp(val, "tkip") == 0) {
1988 if (set_network(ifname, id, "pairwise", "TKIP") < 0)
1989 return -2;
1990 } else if (strcasecmp(val, "aes-ccmp") == 0) {
1991 if (set_network(ifname, id, "pairwise", "CCMP") < 0)
1992 return -2;
1993 } else if (strcasecmp(val, "aes-ccmp-tkip") == 0) {
1994 if (set_network(ifname, id, "pairwise",
1995 "CCMP TKIP") < 0)
1996 return -2;
1997 } else if (strcasecmp(val, "aes-gcmp") == 0) {
1998 if (set_network(ifname, id, "pairwise", "GCMP") < 0)
1999 return -2;
2000 if (set_network(ifname, id, "group", "GCMP") < 0)
2001 return -2;
2002 } else {
2003 send_resp(dut, conn, SIGMA_ERROR,
2004 "errorCode,Unrecognized encpType value");
2005 return 0;
2006 }
2007 }
2008
2009 val = get_param(cmd, "PairwiseCipher");
2010 if (val) {
2011 cipher_set = 1;
2012 /* TODO: Support space separated list */
2013 if (strcasecmp(val, "AES-GCMP-256") == 0) {
2014 if (set_network(ifname, id, "pairwise", "GCMP-256") < 0)
2015 return -2;
2016 } else if (strcasecmp(val, "AES-CCMP-256") == 0) {
2017 if (set_network(ifname, id, "pairwise",
2018 "CCMP-256") < 0)
2019 return -2;
2020 } else if (strcasecmp(val, "AES-GCMP-128") == 0) {
2021 if (set_network(ifname, id, "pairwise", "GCMP") < 0)
2022 return -2;
2023 } else if (strcasecmp(val, "AES-CCMP-128") == 0) {
2024 if (set_network(ifname, id, "pairwise", "CCMP") < 0)
2025 return -2;
2026 } else {
2027 send_resp(dut, conn, SIGMA_ERROR,
2028 "errorCode,Unrecognized PairwiseCipher value");
2029 return 0;
2030 }
2031 }
2032
Jouni Malinen47dcc952017-10-09 16:43:24 +03002033 if (!cipher_set && !owe) {
Jouni Malinenad395a22017-09-01 21:13:46 +03002034 send_resp(dut, conn, SIGMA_ERROR,
2035 "errorCode,Missing encpType and PairwiseCipher");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002036 return 0;
2037 }
Jouni Malinenad395a22017-09-01 21:13:46 +03002038
2039 val = get_param(cmd, "GroupCipher");
2040 if (val) {
2041 if (strcasecmp(val, "AES-GCMP-256") == 0) {
2042 if (set_network(ifname, id, "group", "GCMP-256") < 0)
2043 return -2;
2044 } else if (strcasecmp(val, "AES-CCMP-256") == 0) {
2045 if (set_network(ifname, id, "group", "CCMP-256") < 0)
2046 return -2;
2047 } else if (strcasecmp(val, "AES-GCMP-128") == 0) {
2048 if (set_network(ifname, id, "group", "GCMP") < 0)
2049 return -2;
2050 } else if (strcasecmp(val, "AES-CCMP-128") == 0) {
2051 if (set_network(ifname, id, "group", "CCMP") < 0)
2052 return -2;
2053 } else {
2054 send_resp(dut, conn, SIGMA_ERROR,
2055 "errorCode,Unrecognized GroupCipher value");
2056 return 0;
2057 }
2058 }
2059
Jouni Malinen7b239522017-09-14 21:37:18 +03002060 val = get_param(cmd, "GroupMgntCipher");
Jouni Malinenad395a22017-09-01 21:13:46 +03002061 if (val) {
Jouni Malinene8898cb2017-09-26 17:55:26 +03002062 const char *cipher;
2063
2064 if (strcasecmp(val, "BIP-GMAC-256") == 0) {
2065 cipher = "BIP-GMAC-256";
2066 } else if (strcasecmp(val, "BIP-CMAC-256") == 0) {
2067 cipher = "BIP-CMAC-256";
2068 } else if (strcasecmp(val, "BIP-GMAC-128") == 0) {
2069 cipher = "BIP-GMAC-128";
2070 } else if (strcasecmp(val, "BIP-CMAC-128") == 0) {
2071 cipher = "AES-128-CMAC";
2072 } else {
2073 send_resp(dut, conn, SIGMA_INVALID,
2074 "errorCode,Unsupported GroupMgntCipher");
2075 return 0;
2076 }
2077 if (set_network(ifname, id, "group_mgmt", cipher) < 0) {
2078 send_resp(dut, conn, SIGMA_INVALID,
2079 "errorCode,Failed to set GroupMgntCipher");
2080 return 0;
2081 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002082 }
2083
Jouni Malinene4fde732019-03-25 22:29:37 +02002084 val = get_param(cmd, "AKMSuiteType");
2085 if (val && set_akm_suites(dut, ifname, id, val) < 0)
2086 return ERROR_SEND_STATUS;
2087
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002088 dut->sta_pmf = STA_PMF_DISABLED;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302089
2090 if (dut->program == PROGRAM_OCE) {
2091 dut->sta_pmf = STA_PMF_OPTIONAL;
2092 if (set_network(ifname, id, "ieee80211w", "1") < 0)
2093 return -2;
2094 }
2095
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002096 val = get_param(cmd, "PMF");
2097 if (val) {
2098 if (strcasecmp(val, "Required") == 0 ||
2099 strcasecmp(val, "Forced_Required") == 0) {
2100 dut->sta_pmf = STA_PMF_REQUIRED;
2101 if (set_network(ifname, id, "ieee80211w", "2") < 0)
2102 return -2;
2103 } else if (strcasecmp(val, "Optional") == 0) {
2104 dut->sta_pmf = STA_PMF_OPTIONAL;
2105 if (set_network(ifname, id, "ieee80211w", "1") < 0)
2106 return -2;
2107 } else if (strcasecmp(val, "Disabled") == 0 ||
Kiran Kumar Lokere07da3b22018-12-16 22:42:49 -08002108 strcasecmp(val, "Disable") == 0 ||
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002109 strcasecmp(val, "Forced_Disabled") == 0) {
2110 dut->sta_pmf = STA_PMF_DISABLED;
2111 } else {
2112 send_resp(dut, conn, SIGMA_INVALID, "errorCode,Unrecognized PMF value");
2113 return 0;
2114 }
Sunil Duttc75a1e62018-01-11 20:47:50 +05302115 } else if (owe || suite_b) {
Jouni Malinen1287cd72018-01-04 17:08:01 +02002116 dut->sta_pmf = STA_PMF_REQUIRED;
2117 if (set_network(ifname, id, "ieee80211w", "2") < 0)
2118 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002119 }
2120
Jouni Malinen0165c7f2020-03-26 11:51:58 +02002121 val = get_param(cmd, "BeaconProtection");
Veerendranath Jakkamc1f71b62021-01-23 03:09:51 +05302122 if (val)
2123 dut->beacon_prot = atoi(val);
2124 if (dut->beacon_prot && set_network(ifname, id, "beacon_prot", "1") < 0)
Jouni Malinen0165c7f2020-03-26 11:51:58 +02002125 return ERROR_SEND_STATUS;
2126
Veerendranath Jakkam54fd51c2020-12-21 01:36:04 +05302127 if (dut->ocvc && set_network(ifname, id, "ocv", "1") < 0)
2128 return ERROR_SEND_STATUS;
2129
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002130 return id;
2131}
2132
2133
Veerendranath Jakkamca239592021-10-11 20:48:00 +05302134static int wcn_set_ignore_h2e_rsnxe(struct sigma_dut *dut, const char *intf,
2135 uint8_t cfg)
2136{
2137#ifdef NL80211_SUPPORT
2138 return wcn_wifi_test_config_set_u8(
2139 dut, intf,
2140 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_IGNORE_H2E_RSNXE, cfg);
2141#else /* NL80211_SUPPORT */
2142 sigma_dut_print(dut, DUT_MSG_ERROR,
2143 "Ignore SAE H2E requirement mismatch can't be set without NL80211_SUPPORT defined");
2144 return -1;
2145#endif /* NL80211_SUPPORT */
2146}
2147
2148
Jouni Malinenf7222712019-06-13 01:50:21 +03002149static enum sigma_cmd_result cmd_sta_set_psk(struct sigma_dut *dut,
2150 struct sigma_conn *conn,
2151 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002152{
2153 const char *intf = get_param(cmd, "Interface");
Jouni Malinen992a81e2017-08-22 13:57:47 +03002154 const char *type = get_param(cmd, "Type");
Jouni Malinen1287cd72018-01-04 17:08:01 +02002155 const char *pmf = get_param(cmd, "PMF");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002156 const char *network_mode = get_param(cmd, "network_mode");
Jouni Malinene4fde732019-03-25 22:29:37 +02002157 const char *akm = get_param(cmd, "AKMSuiteType");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002158 const char *ifname, *val, *alg;
2159 int id;
Jouni Malinen4b3769d2019-10-10 16:20:29 +03002160 char buf[50];
Jouni Malinen11e55212019-11-22 21:46:59 +02002161 int sae_pwe = -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002162
2163 if (intf == NULL)
2164 return -1;
2165
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002166 if (strcmp(intf, get_main_ifname(dut)) == 0)
2167 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002168 else
2169 ifname = intf;
2170
2171 id = set_wpa_common(dut, conn, ifname, cmd);
2172 if (id < 0)
2173 return id;
2174
2175 val = get_param(cmd, "keyMgmtType");
2176 alg = get_param(cmd, "micAlg");
2177
Jouni Malinen992a81e2017-08-22 13:57:47 +03002178 if (type && strcasecmp(type, "SAE") == 0) {
Jouni Malinene4fde732019-03-25 22:29:37 +02002179 if (!akm && val && strcasecmp(val, "wpa2-ft") == 0) {
Jouni Malinen992a81e2017-08-22 13:57:47 +03002180 if (set_network(ifname, id, "key_mgmt", "FT-SAE") < 0)
2181 return -2;
Jouni Malinene4fde732019-03-25 22:29:37 +02002182 } else if (!akm) {
Jouni Malinen992a81e2017-08-22 13:57:47 +03002183 if (set_network(ifname, id, "key_mgmt", "SAE") < 0)
2184 return -2;
2185 }
2186 if (wpa_command(ifname, "SET sae_groups ") != 0) {
2187 sigma_dut_print(dut, DUT_MSG_ERROR,
2188 "Failed to clear sae_groups to default");
2189 return -2;
2190 }
Jouni Malinen1287cd72018-01-04 17:08:01 +02002191 if (!pmf) {
2192 dut->sta_pmf = STA_PMF_REQUIRED;
2193 if (set_network(ifname, id, "ieee80211w", "2") < 0)
2194 return -2;
2195 }
Jouni Malinen0ab50f42017-08-31 01:34:59 +03002196 } else if (type && strcasecmp(type, "PSK-SAE") == 0) {
2197 if (val && strcasecmp(val, "wpa2-ft") == 0) {
2198 if (set_network(ifname, id, "key_mgmt",
2199 "FT-SAE FT-PSK") < 0)
2200 return -2;
Jouni Malinen3b73d872019-06-12 03:13:25 +03002201 } else if (!akm) {
Jouni Malinen0ab50f42017-08-31 01:34:59 +03002202 if (set_network(ifname, id, "key_mgmt",
2203 "SAE WPA-PSK") < 0)
2204 return -2;
2205 }
2206 if (wpa_command(ifname, "SET sae_groups ") != 0) {
2207 sigma_dut_print(dut, DUT_MSG_ERROR,
2208 "Failed to clear sae_groups to default");
2209 return -2;
2210 }
Jouni Malinen1287cd72018-01-04 17:08:01 +02002211 if (!pmf) {
2212 dut->sta_pmf = STA_PMF_OPTIONAL;
2213 if (set_network(ifname, id, "ieee80211w", "1") < 0)
2214 return -2;
2215 }
Jouni Malinen992a81e2017-08-22 13:57:47 +03002216 } else if (alg && strcasecmp(alg, "SHA-256") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002217 if (set_network(ifname, id, "key_mgmt", "WPA-PSK-SHA256") < 0)
2218 return -2;
2219 } else if (alg && strcasecmp(alg, "SHA-1") == 0) {
2220 if (set_network(ifname, id, "key_mgmt", "WPA-PSK") < 0)
2221 return -2;
Ashwini Patil6dbf7b02017-03-20 13:42:11 +05302222 } else if (val && strcasecmp(val, "wpa2-ft") == 0) {
2223 if (set_network(ifname, id, "key_mgmt", "FT-PSK") < 0)
2224 return -2;
Jouni Malinen3b73d872019-06-12 03:13:25 +03002225 } else if (!akm &&
2226 ((val && strcasecmp(val, "wpa2-sha256") == 0) ||
2227 dut->sta_pmf == STA_PMF_REQUIRED)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002228 if (set_network(ifname, id, "key_mgmt",
2229 "WPA-PSK WPA-PSK-SHA256") < 0)
2230 return -2;
Jouni Malinen77ff3f02019-03-28 03:45:40 +02002231 } else if (!akm && dut->sta_pmf == STA_PMF_OPTIONAL) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002232 if (set_network(ifname, id, "key_mgmt",
2233 "WPA-PSK WPA-PSK-SHA256") < 0)
2234 return -2;
Jouni Malinen77ff3f02019-03-28 03:45:40 +02002235 } else if (!akm) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002236 if (set_network(ifname, id, "key_mgmt", "WPA-PSK") < 0)
2237 return -2;
2238 }
2239
2240 val = get_param(cmd, "passPhrase");
2241 if (val == NULL)
2242 return -1;
Jouni Malinen2126f422017-10-11 23:24:33 +03002243 if (type && strcasecmp(type, "SAE") == 0) {
2244 if (set_network_quoted(ifname, id, "sae_password", val) < 0)
2245 return -2;
2246 } else {
2247 if (set_network_quoted(ifname, id, "psk", val) < 0)
2248 return -2;
2249 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002250
Jouni Malinen78d10c42019-03-25 22:34:32 +02002251 val = get_param(cmd, "PasswordId");
2252 if (val && set_network_quoted(ifname, id, "sae_password_id", val) < 0)
2253 return ERROR_SEND_STATUS;
2254
Jouni Malinen992a81e2017-08-22 13:57:47 +03002255 val = get_param(cmd, "ECGroupID");
2256 if (val) {
Jouni Malinenb54f0df2019-12-12 01:57:29 +02002257 snprintf(buf, sizeof(buf), "SET sae_groups %s", val);
Jouni Malinen992a81e2017-08-22 13:57:47 +03002258 if (wpa_command(ifname, buf) != 0) {
2259 sigma_dut_print(dut, DUT_MSG_ERROR,
2260 "Failed to clear sae_groups");
2261 return -2;
2262 }
2263 }
2264
Jouni Malinen68143132017-09-02 02:34:08 +03002265 val = get_param(cmd, "InvalidSAEElement");
2266 if (val) {
2267 free(dut->sae_commit_override);
2268 dut->sae_commit_override = strdup(val);
2269 }
2270
Jouni Malinen4b3769d2019-10-10 16:20:29 +03002271 val = get_param(cmd, "PMKID_Include");
2272 if (val) {
2273 snprintf(buf, sizeof(buf), "SET sae_pmkid_in_assoc %d",
2274 get_enable_disable(val));
2275 wpa_command(intf, buf);
2276 }
2277
Jouni Malineneeb43d32019-12-06 17:40:07 +02002278 val = get_param(cmd, "IgnoreH2E_RSNXE_BSSMemSel");
2279 if (val) {
2280 snprintf(buf, sizeof(buf), "SET ignore_sae_h2e_only %d",
2281 get_enable_disable(val));
2282 wpa_command(intf, buf);
Veerendranath Jakkamca239592021-10-11 20:48:00 +05302283 if (get_driver_type(dut) == DRIVER_WCN)
2284 wcn_set_ignore_h2e_rsnxe(dut, intf,
2285 get_enable_disable(val));
Jouni Malineneeb43d32019-12-06 17:40:07 +02002286 }
2287
Jouni Malinenf2348d22019-12-07 11:52:55 +02002288 val = get_param(cmd, "ECGroupID_RGE");
2289 if (val) {
2290 snprintf(buf, sizeof(buf), "SET extra_sae_rejected_groups %s",
2291 val);
2292 wpa_command(intf, buf);
2293 }
2294
Jouni Malinen99e55022019-12-07 13:59:41 +02002295 val = get_param(cmd, "RSNXE_Content");
2296 if (val) {
2297 const char *param;
2298
2299 if (strncasecmp(val, "AssocReq:", 9) == 0) {
2300 val += 9;
2301 param = "rsnxe_override_assoc";
2302 } else if (strncasecmp(val, "EapolM2:", 8) == 0) {
2303 val += 8;
2304 param = "rsnxe_override_eapol";
2305 } else {
2306 send_resp(dut, conn, SIGMA_ERROR,
2307 "errorCode,Unsupported RSNXE_Content value");
2308 return STATUS_SENT_ERROR;
2309 }
2310 snprintf(buf, sizeof(buf), "SET %s %s", param, val);
2311 wpa_command(intf, buf);
2312 }
2313
Jouni Malinen11e55212019-11-22 21:46:59 +02002314 val = get_param(cmd, "sae_pwe");
2315 if (val) {
2316 if (strcasecmp(val, "h2e") == 0) {
2317 dut->sae_pwe = SAE_PWE_H2E;
Jouni Malinen7244a412019-12-07 11:54:10 +02002318 } else if (strcasecmp(val, "loop") == 0 ||
2319 strcasecmp(val, "looping") == 0) {
Jouni Malinen11e55212019-11-22 21:46:59 +02002320 dut->sae_pwe = SAE_PWE_LOOP;
2321 } else {
2322 send_resp(dut, conn, SIGMA_ERROR,
2323 "errorCode,Unsupported sae_pwe value");
2324 return STATUS_SENT_ERROR;
2325 }
2326 }
Vinita S. Maloo6d7454f2020-04-02 15:03:26 +05302327
2328 val = get_param(cmd, "Clear_RSNXE");
2329 if (val && strcmp(val, "1") == 0 &&
2330 (wpa_command(intf, "SET rsnxe_override_assoc ") ||
2331 wpa_command(intf, "SET rsnxe_override_eapol "))) {
2332 send_resp(dut, conn, SIGMA_ERROR,
2333 "errorCode,Failed to clear RSNXE");
Jouni Malinenb11498c2020-08-03 11:05:53 +03002334 return STATUS_SENT_ERROR;
Vinita S. Maloo6d7454f2020-04-02 15:03:26 +05302335 }
2336
Jouni Malinenc0078772020-03-04 21:23:16 +02002337 if (dut->sae_pwe == SAE_PWE_LOOP && get_param(cmd, "PasswordId"))
2338 sae_pwe = 3;
2339 else if (dut->sae_pwe == SAE_PWE_LOOP)
Jouni Malinen11e55212019-11-22 21:46:59 +02002340 sae_pwe = 0;
2341 else if (dut->sae_pwe == SAE_PWE_H2E)
2342 sae_pwe = 1;
2343 else if (dut->sae_h2e_default)
2344 sae_pwe = 2;
2345 snprintf(buf, sizeof(buf), "SET sae_pwe %d", sae_pwe);
2346 if (sae_pwe >= 0 && wpa_command(ifname, buf) != 0)
2347 return ERROR_SEND_STATUS;
2348
Veerendranath Jakkam0316be12020-06-23 20:11:41 +05302349 val = get_param(cmd, "sae_pk");
2350 if (val && strcmp(val, "0") == 0 &&
2351 set_network(ifname, id, "sae_pk", "2") < 0)
2352 return ERROR_SEND_STATUS;
2353
Veerendranath Jakkama9177042020-08-10 00:14:03 +05302354 val = get_param(cmd, "sae_pk_only");
2355 if (val && strcmp(val, "1") == 0 &&
2356 set_network(ifname, id, "sae_pk", "1") < 0)
2357 return ERROR_SEND_STATUS;
2358
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002359 if (dut->program == PROGRAM_60GHZ && network_mode &&
2360 strcasecmp(network_mode, "PBSS") == 0 &&
2361 set_network(ifname, id, "pbss", "1") < 0)
2362 return -2;
2363
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002364 return 1;
2365}
2366
2367
Jouni Malinen8ac93452019-08-14 15:19:13 +03002368static enum sigma_cmd_result set_trust_root_system(struct sigma_dut *dut,
2369 struct sigma_conn *conn,
2370 const char *ifname, int id)
2371{
2372 char buf[200];
2373
2374 snprintf(buf, sizeof(buf), "%s/certs", sigma_cert_path);
2375 if (!file_exists(buf))
2376 strlcpy(buf, "/system/etc/security/cacerts", sizeof(buf));
2377 if (!file_exists(buf))
2378 strlcpy(buf, "/etc/ssl/certs", sizeof(buf));
2379 if (!file_exists(buf)) {
2380 char msg[300];
2381
2382 snprintf(msg, sizeof(msg),
2383 "ErrorCode,trustedRootCA system store (%s) not found",
2384 buf);
2385 send_resp(dut, conn, SIGMA_ERROR, msg);
2386 return STATUS_SENT_ERROR;
2387 }
2388
2389 if (set_network_quoted(ifname, id, "ca_path", buf) < 0)
2390 return ERROR_SEND_STATUS;
2391
2392 return SUCCESS_SEND_STATUS;
2393}
2394
2395
2396static enum sigma_cmd_result set_trust_root(struct sigma_dut *dut,
2397 struct sigma_conn *conn,
2398 const char *ifname, int id,
2399 const char *val)
2400{
2401 char buf[200];
2402#ifdef ANDROID
2403 unsigned char kvalue[KEYSTORE_MESSAGE_SIZE];
2404 int length;
2405#endif /* ANDROID */
2406
2407 if (strcmp(val, "DEFAULT") == 0)
2408 return set_trust_root_system(dut, conn, ifname, id);
2409
2410#ifdef ANDROID
2411 snprintf(buf, sizeof(buf), "CACERT_%s", val);
2412 length = android_keystore_get(ANDROID_KEYSTORE_GET, buf, kvalue);
2413 if (length > 0) {
2414 sigma_dut_print(dut, DUT_MSG_INFO, "Use Android keystore [%s]",
2415 buf);
2416 snprintf(buf, sizeof(buf), "keystore://CACERT_%s", val);
2417 goto ca_cert_selected;
2418 }
2419#endif /* ANDROID */
2420
2421 snprintf(buf, sizeof(buf), "%s/%s", sigma_cert_path, val);
2422#ifdef __linux__
2423 if (!file_exists(buf)) {
2424 char msg[300];
2425
2426 snprintf(msg, sizeof(msg),
2427 "ErrorCode,trustedRootCA file (%s) not found", buf);
2428 send_resp(dut, conn, SIGMA_ERROR, msg);
2429 return STATUS_SENT_ERROR;
2430 }
2431#endif /* __linux__ */
2432#ifdef ANDROID
2433ca_cert_selected:
2434#endif /* ANDROID */
2435 if (set_network_quoted(ifname, id, "ca_cert", buf) < 0)
2436 return ERROR_SEND_STATUS;
2437
2438 return SUCCESS_SEND_STATUS;
2439}
2440
2441
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002442static int set_eap_common(struct sigma_dut *dut, struct sigma_conn *conn,
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302443 const char *ifname, int username_identity,
2444 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002445{
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002446 const char *val, *alg, *akm, *trust_root, *domain, *domain_suffix;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002447 int id;
Jouni Malinen53264f62019-05-03 13:04:40 +03002448 char buf[200], buf2[300];
Jouni Malinen8179fee2019-03-28 03:19:47 +02002449 int erp = 0;
Jouni Malinen8ac93452019-08-14 15:19:13 +03002450 enum sigma_cmd_result res;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002451
2452 id = set_wpa_common(dut, conn, ifname, cmd);
2453 if (id < 0)
2454 return id;
2455
2456 val = get_param(cmd, "keyMgmtType");
2457 alg = get_param(cmd, "micAlg");
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302458 akm = get_param(cmd, "AKMSuiteType");
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002459 trust_root = get_param(cmd, "trustedRootCA");
2460 domain = get_param(cmd, "Domain");
2461 domain_suffix = get_param(cmd, "DomainSuffix");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002462
Jouni Malinenad395a22017-09-01 21:13:46 +03002463 if (val && strcasecmp(val, "SuiteB") == 0) {
2464 if (set_network(ifname, id, "key_mgmt", "WPA-EAP-SUITE-B-192") <
2465 0)
2466 return -2;
2467 } else if (alg && strcasecmp(alg, "SHA-256") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002468 if (set_network(ifname, id, "key_mgmt", "WPA-EAP-SHA256") < 0)
2469 return -2;
2470 } else if (alg && strcasecmp(alg, "SHA-1") == 0) {
2471 if (set_network(ifname, id, "key_mgmt", "WPA-EAP") < 0)
2472 return -2;
2473 } else if (val && strcasecmp(val, "wpa2-ft") == 0) {
2474 if (set_network(ifname, id, "key_mgmt", "FT-EAP") < 0)
2475 return -2;
Jouni Malinend6a9d692019-03-28 03:01:24 +02002476 } else if (!akm &&
2477 ((val && strcasecmp(val, "wpa2-sha256") == 0) ||
2478 dut->sta_pmf == STA_PMF_REQUIRED)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002479 if (set_network(ifname, id, "key_mgmt",
2480 "WPA-EAP WPA-EAP-SHA256") < 0)
2481 return -2;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302482 } else if (akm && atoi(akm) == 14) {
2483 if (dut->sta_pmf == STA_PMF_OPTIONAL ||
2484 dut->sta_pmf == STA_PMF_REQUIRED) {
2485 if (set_network(ifname, id, "key_mgmt",
2486 "WPA-EAP-SHA256 FILS-SHA256") < 0)
2487 return -2;
2488 } else {
2489 if (set_network(ifname, id, "key_mgmt",
2490 "WPA-EAP FILS-SHA256") < 0)
2491 return -2;
2492 }
2493
Jouni Malinen8179fee2019-03-28 03:19:47 +02002494 erp = 1;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302495 } else if (akm && atoi(akm) == 15) {
2496 if (dut->sta_pmf == STA_PMF_OPTIONAL ||
2497 dut->sta_pmf == STA_PMF_REQUIRED) {
2498 if (set_network(ifname, id, "key_mgmt",
2499 "WPA-EAP-SHA256 FILS-SHA384") < 0)
2500 return -2;
2501 } else {
2502 if (set_network(ifname, id, "key_mgmt",
2503 "WPA-EAP FILS-SHA384") < 0)
2504 return -2;
2505 }
2506
Jouni Malinen8179fee2019-03-28 03:19:47 +02002507 erp = 1;
Jouni Malinend6a9d692019-03-28 03:01:24 +02002508 } else if (!akm && dut->sta_pmf == STA_PMF_OPTIONAL) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002509 if (set_network(ifname, id, "key_mgmt",
2510 "WPA-EAP WPA-EAP-SHA256") < 0)
2511 return -2;
Jouni Malinend6a9d692019-03-28 03:01:24 +02002512 } else if (!akm) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002513 if (set_network(ifname, id, "key_mgmt", "WPA-EAP") < 0)
2514 return -2;
2515 }
2516
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002517 if (trust_root) {
2518 if (strcmp(trust_root, "DEFAULT") == 0 && !domain &&
2519 !domain_suffix) {
2520 send_resp(dut, conn, SIGMA_ERROR,
2521 "errorCode,trustRootCA DEFAULT used without specifying Domain or DomainSuffix");
2522 return STATUS_SENT_ERROR;
2523 }
2524 res = set_trust_root(dut, conn, ifname, id, trust_root);
Jouni Malinen8ac93452019-08-14 15:19:13 +03002525 if (res != SUCCESS_SEND_STATUS)
2526 return res;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002527 }
2528
Jouni Malinen53264f62019-05-03 13:04:40 +03002529 val = get_param(cmd, "ServerCert");
2530 if (val) {
2531 FILE *f;
2532 char *result = NULL, *pos;
2533
2534 snprintf(buf, sizeof(buf), "%s/%s.sha256", sigma_cert_path,
2535 val);
2536 f = fopen(buf, "r");
2537 if (f) {
2538 result = fgets(buf, sizeof(buf), f);
2539 fclose(f);
2540 }
2541 if (!result) {
2542 snprintf(buf2, sizeof(buf2),
2543 "ErrorCode,ServerCert hash could not be read from %s",
2544 buf);
2545 send_resp(dut, conn, SIGMA_ERROR, buf2);
2546 return STATUS_SENT_ERROR;
2547 }
2548 pos = strchr(buf, '\n');
2549 if (pos)
2550 *pos = '\0';
Jouni Malinen0572a742020-10-08 13:53:25 +03002551 pos = strchr(buf, '\r');
2552 if (pos)
2553 *pos = '\0';
Jouni Malinen53264f62019-05-03 13:04:40 +03002554 snprintf(buf2, sizeof(buf2), "hash://server/sha256/%s", buf);
2555 if (set_network_quoted(ifname, id, "ca_cert", buf2) < 0)
2556 return ERROR_SEND_STATUS;
Jouni Malinen29108dc2019-06-13 23:42:11 +03002557
2558 snprintf(buf, sizeof(buf), "%s/%s.tod", sigma_cert_path, val);
2559 if (file_exists(buf)) {
2560 sigma_dut_print(dut, DUT_MSG_DEBUG,
2561 "TOD policy enabled for the configured ServerCert hash");
2562 dut->sta_tod_policy = 1;
2563 }
Jouni Malinen53264f62019-05-03 13:04:40 +03002564 }
2565
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002566 if (domain &&
2567 set_network_quoted(ifname, id, "domain_match", domain) < 0)
Jouni Malinen96f84b02019-05-03 12:32:56 +03002568 return ERROR_SEND_STATUS;
2569
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002570 if (domain_suffix &&
2571 set_network_quoted(ifname, id, "domain_suffix_match",
2572 domain_suffix) < 0)
Jouni Malinen96f84b02019-05-03 12:32:56 +03002573 return ERROR_SEND_STATUS;
2574
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302575 if (username_identity) {
2576 val = get_param(cmd, "username");
2577 if (val) {
2578 if (set_network_quoted(ifname, id, "identity", val) < 0)
2579 return -2;
2580 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002581
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302582 val = get_param(cmd, "password");
2583 if (val) {
2584 if (set_network_quoted(ifname, id, "password", val) < 0)
2585 return -2;
2586 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002587 }
2588
Jouni Malinen8179fee2019-03-28 03:19:47 +02002589 if (dut->akm_values &
2590 ((1 << AKM_FILS_SHA256) |
2591 (1 << AKM_FILS_SHA384) |
2592 (1 << AKM_FT_FILS_SHA256) |
2593 (1 << AKM_FT_FILS_SHA384)))
2594 erp = 1;
2595 if (erp && set_network(ifname, id, "erp", "1") < 0)
2596 return ERROR_SEND_STATUS;
2597
Jouni Malinen134fe3c2019-06-12 04:16:49 +03002598 dut->sta_associate_wait_connect = 1;
2599
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002600 return id;
2601}
2602
2603
Jouni Malinen5eabb2a2017-10-03 18:17:30 +03002604static int set_tls_cipher(const char *ifname, int id, const char *cipher)
2605{
2606 const char *val;
2607
2608 if (!cipher)
2609 return 0;
2610
2611 if (strcasecmp(cipher, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384") == 0)
2612 val = "ECDHE-ECDSA-AES256-GCM-SHA384";
2613 else if (strcasecmp(cipher,
2614 "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384") == 0)
2615 val = "ECDHE-RSA-AES256-GCM-SHA384";
2616 else if (strcasecmp(cipher, "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384") == 0)
2617 val = "DHE-RSA-AES256-GCM-SHA384";
2618 else if (strcasecmp(cipher,
2619 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256") == 0)
2620 val = "ECDHE-ECDSA-AES128-GCM-SHA256";
2621 else
2622 return -1;
2623
2624 /* Need to clear phase1="tls_suiteb=1" to allow cipher enforcement */
2625 set_network_quoted(ifname, id, "phase1", "");
2626
2627 return set_network_quoted(ifname, id, "openssl_ciphers", val);
2628}
2629
2630
Jouni Malinenf7222712019-06-13 01:50:21 +03002631static enum sigma_cmd_result cmd_sta_set_eaptls(struct sigma_dut *dut,
2632 struct sigma_conn *conn,
2633 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002634{
2635 const char *intf = get_param(cmd, "Interface");
2636 const char *ifname, *val;
2637 int id;
2638 char buf[200];
2639#ifdef ANDROID
2640 unsigned char kvalue[KEYSTORE_MESSAGE_SIZE];
2641 int length;
2642 int jb_or_newer = 0;
2643 char prop[PROPERTY_VALUE_MAX];
2644#endif /* ANDROID */
2645
2646 if (intf == NULL)
2647 return -1;
2648
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002649 if (strcmp(intf, get_main_ifname(dut)) == 0)
2650 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002651 else
2652 ifname = intf;
2653
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302654 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002655 if (id < 0)
2656 return id;
2657
2658 if (set_network(ifname, id, "eap", "TLS") < 0)
2659 return -2;
2660
Pradeep Reddy POTTETI9f6c2132016-05-05 16:28:19 +05302661 if (!get_param(cmd, "username") &&
2662 set_network_quoted(ifname, id, "identity",
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002663 "wifi-user@wifilabs.local") < 0)
2664 return -2;
2665
2666 val = get_param(cmd, "clientCertificate");
2667 if (val == NULL)
2668 return -1;
2669#ifdef ANDROID
2670 snprintf(buf, sizeof(buf), "USRPKEY_%s", val);
2671 length = android_keystore_get(ANDROID_KEYSTORE_GET, buf, kvalue);
2672 if (length < 0) {
2673 /*
2674 * JB started reporting keystore type mismatches, so retry with
2675 * the GET_PUBKEY command if the generic GET fails.
2676 */
2677 length = android_keystore_get(ANDROID_KEYSTORE_GET_PUBKEY,
2678 buf, kvalue);
2679 }
2680
2681 if (property_get("ro.build.version.release", prop, NULL) != 0) {
2682 sigma_dut_print(dut, DUT_MSG_DEBUG, "Android release %s", prop);
2683 if (strncmp(prop, "4.0", 3) != 0)
2684 jb_or_newer = 1;
2685 } else
2686 jb_or_newer = 1; /* assume newer */
2687
2688 if (jb_or_newer && length > 0) {
2689 sigma_dut_print(dut, DUT_MSG_INFO,
2690 "Use Android keystore [%s]", buf);
2691 if (set_network(ifname, id, "engine", "1") < 0)
2692 return -2;
2693 if (set_network_quoted(ifname, id, "engine_id", "keystore") < 0)
2694 return -2;
2695 snprintf(buf, sizeof(buf), "USRPKEY_%s", val);
2696 if (set_network_quoted(ifname, id, "key_id", buf) < 0)
2697 return -2;
2698 snprintf(buf, sizeof(buf), "keystore://USRCERT_%s", val);
2699 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
2700 return -2;
2701 return 1;
2702 } else if (length > 0) {
2703 sigma_dut_print(dut, DUT_MSG_INFO,
2704 "Use Android keystore [%s]", buf);
2705 snprintf(buf, sizeof(buf), "keystore://USRPKEY_%s", val);
2706 if (set_network_quoted(ifname, id, "private_key", buf) < 0)
2707 return -2;
2708 snprintf(buf, sizeof(buf), "keystore://USRCERT_%s", val);
2709 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
2710 return -2;
2711 return 1;
2712 }
2713#endif /* ANDROID */
2714
2715 snprintf(buf, sizeof(buf), "%s/%s", sigma_cert_path, val);
2716#ifdef __linux__
2717 if (!file_exists(buf)) {
2718 char msg[300];
2719 snprintf(msg, sizeof(msg), "ErrorCode,clientCertificate file "
2720 "(%s) not found", buf);
2721 send_resp(dut, conn, SIGMA_ERROR, msg);
2722 return -3;
2723 }
2724#endif /* __linux__ */
2725 if (set_network_quoted(ifname, id, "private_key", buf) < 0)
2726 return -2;
2727 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
2728 return -2;
2729
2730 if (set_network_quoted(ifname, id, "private_key_passwd", "wifi") < 0)
2731 return -2;
2732
Jouni Malinen5eabb2a2017-10-03 18:17:30 +03002733 val = get_param(cmd, "keyMgmtType");
2734 if (val && strcasecmp(val, "SuiteB") == 0) {
2735 val = get_param(cmd, "CertType");
2736 if (val && strcasecmp(val, "RSA") == 0) {
2737 if (set_network_quoted(ifname, id, "phase1",
2738 "tls_suiteb=1") < 0)
2739 return -2;
2740 } else {
2741 if (set_network_quoted(ifname, id, "openssl_ciphers",
2742 "SUITEB192") < 0)
2743 return -2;
2744 }
2745
2746 val = get_param(cmd, "TLSCipher");
2747 if (set_tls_cipher(ifname, id, val) < 0) {
2748 send_resp(dut, conn, SIGMA_ERROR,
2749 "ErrorCode,Unsupported TLSCipher value");
2750 return -3;
2751 }
2752 }
2753
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002754 return 1;
2755}
2756
2757
Jouni Malinenf7222712019-06-13 01:50:21 +03002758static enum sigma_cmd_result cmd_sta_set_eapttls(struct sigma_dut *dut,
2759 struct sigma_conn *conn,
2760 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002761{
2762 const char *intf = get_param(cmd, "Interface");
2763 const char *ifname;
2764 int id;
2765
2766 if (intf == NULL)
2767 return -1;
2768
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002769 if (strcmp(intf, get_main_ifname(dut)) == 0)
2770 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002771 else
2772 ifname = intf;
2773
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302774 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002775 if (id < 0)
2776 return id;
2777
2778 if (set_network(ifname, id, "eap", "TTLS") < 0) {
2779 send_resp(dut, conn, SIGMA_ERROR,
2780 "errorCode,Failed to set TTLS method");
2781 return 0;
2782 }
2783
2784 if (set_network_quoted(ifname, id, "phase2", "auth=MSCHAPV2") < 0) {
2785 send_resp(dut, conn, SIGMA_ERROR,
2786 "errorCode,Failed to set MSCHAPv2 for TTLS Phase 2");
2787 return 0;
2788 }
2789
2790 return 1;
2791}
2792
2793
Jouni Malinenf7222712019-06-13 01:50:21 +03002794static enum sigma_cmd_result cmd_sta_set_eapsim(struct sigma_dut *dut,
2795 struct sigma_conn *conn,
2796 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002797{
2798 const char *intf = get_param(cmd, "Interface");
2799 const char *ifname;
2800 int id;
2801
2802 if (intf == NULL)
2803 return -1;
2804
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002805 if (strcmp(intf, get_main_ifname(dut)) == 0)
2806 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002807 else
2808 ifname = intf;
2809
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302810 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002811 if (id < 0)
2812 return id;
2813
2814 if (set_network(ifname, id, "eap", "SIM") < 0)
2815 return -2;
2816
2817 return 1;
2818}
2819
2820
Jouni Malinenf7222712019-06-13 01:50:21 +03002821static enum sigma_cmd_result cmd_sta_set_peap(struct sigma_dut *dut,
2822 struct sigma_conn *conn,
2823 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002824{
2825 const char *intf = get_param(cmd, "Interface");
2826 const char *ifname, *val;
2827 int id;
2828 char buf[100];
2829
2830 if (intf == NULL)
2831 return -1;
2832
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002833 if (strcmp(intf, get_main_ifname(dut)) == 0)
2834 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002835 else
2836 ifname = intf;
2837
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302838 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002839 if (id < 0)
2840 return id;
2841
2842 if (set_network(ifname, id, "eap", "PEAP") < 0)
2843 return -2;
2844
2845 val = get_param(cmd, "innerEAP");
2846 if (val) {
2847 if (strcasecmp(val, "MSCHAPv2") == 0) {
2848 if (set_network_quoted(ifname, id, "phase2",
2849 "auth=MSCHAPV2") < 0)
2850 return -2;
2851 } else if (strcasecmp(val, "GTC") == 0) {
2852 if (set_network_quoted(ifname, id, "phase2",
2853 "auth=GTC") < 0)
2854 return -2;
2855 } else
2856 return -1;
2857 }
2858
2859 val = get_param(cmd, "peapVersion");
2860 if (val) {
2861 int ver = atoi(val);
2862 if (ver < 0 || ver > 1)
2863 return -1;
2864 snprintf(buf, sizeof(buf), "peapver=%d", ver);
2865 if (set_network_quoted(ifname, id, "phase1", buf) < 0)
2866 return -2;
2867 }
2868
2869 return 1;
2870}
2871
2872
Jouni Malinenf7222712019-06-13 01:50:21 +03002873static enum sigma_cmd_result cmd_sta_set_eapfast(struct sigma_dut *dut,
2874 struct sigma_conn *conn,
2875 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002876{
2877 const char *intf = get_param(cmd, "Interface");
2878 const char *ifname, *val;
2879 int id;
2880 char buf[100];
2881
2882 if (intf == NULL)
2883 return -1;
2884
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002885 if (strcmp(intf, get_main_ifname(dut)) == 0)
2886 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002887 else
2888 ifname = intf;
2889
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302890 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002891 if (id < 0)
2892 return id;
2893
2894 if (set_network(ifname, id, "eap", "FAST") < 0)
2895 return -2;
2896
2897 val = get_param(cmd, "innerEAP");
2898 if (val) {
2899 if (strcasecmp(val, "MSCHAPV2") == 0) {
2900 if (set_network_quoted(ifname, id, "phase2",
2901 "auth=MSCHAPV2") < 0)
2902 return -2;
2903 } else if (strcasecmp(val, "GTC") == 0) {
2904 if (set_network_quoted(ifname, id, "phase2",
2905 "auth=GTC") < 0)
2906 return -2;
2907 } else
2908 return -1;
2909 }
2910
2911 val = get_param(cmd, "validateServer");
2912 if (val) {
2913 /* TODO */
2914 sigma_dut_print(dut, DUT_MSG_INFO, "Ignored EAP-FAST "
2915 "validateServer=%s", val);
2916 }
2917
2918 val = get_param(cmd, "pacFile");
2919 if (val) {
2920 snprintf(buf, sizeof(buf), "blob://%s", val);
2921 if (set_network_quoted(ifname, id, "pac_file", buf) < 0)
2922 return -2;
2923 }
2924
2925 if (set_network_quoted(ifname, id, "phase1", "fast_provisioning=2") <
2926 0)
2927 return -2;
2928
2929 return 1;
2930}
2931
2932
Jouni Malinenf7222712019-06-13 01:50:21 +03002933static enum sigma_cmd_result cmd_sta_set_eapaka(struct sigma_dut *dut,
2934 struct sigma_conn *conn,
2935 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002936{
2937 const char *intf = get_param(cmd, "Interface");
Purushottam Kushwahacdd8cb12019-10-04 11:33:59 +05302938 const char *username = get_param(cmd, "Username");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002939 const char *ifname;
2940 int id;
2941
2942 if (intf == NULL)
2943 return -1;
2944
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002945 if (strcmp(intf, get_main_ifname(dut)) == 0)
2946 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002947 else
2948 ifname = intf;
2949
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302950 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002951 if (id < 0)
2952 return id;
2953
Purushottam Kushwahacdd8cb12019-10-04 11:33:59 +05302954 /* RFC 5448: EAP-AKA' MUST use the leading character "6" (ASCII 36
2955 * hexadecimal).
2956 */
2957 if (username && username[0] == '6') {
2958 if (set_network(ifname, id, "eap", "AKA'") < 0)
2959 return -2;
2960 } else if (set_network(ifname, id, "eap", "AKA") < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002961 return -2;
Purushottam Kushwahacdd8cb12019-10-04 11:33:59 +05302962 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002963
2964 return 1;
2965}
2966
2967
Jouni Malinenf7222712019-06-13 01:50:21 +03002968static enum sigma_cmd_result cmd_sta_set_eapakaprime(struct sigma_dut *dut,
2969 struct sigma_conn *conn,
2970 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002971{
2972 const char *intf = get_param(cmd, "Interface");
2973 const char *ifname;
2974 int id;
2975
2976 if (intf == NULL)
2977 return -1;
2978
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002979 if (strcmp(intf, get_main_ifname(dut)) == 0)
2980 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002981 else
2982 ifname = intf;
2983
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302984 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002985 if (id < 0)
2986 return id;
2987
2988 if (set_network(ifname, id, "eap", "AKA'") < 0)
2989 return -2;
2990
2991 return 1;
2992}
2993
2994
2995static int sta_set_open(struct sigma_dut *dut, struct sigma_conn *conn,
2996 struct sigma_cmd *cmd)
2997{
2998 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002999 const char *network_mode = get_param(cmd, "network_mode");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003000 const char *ifname;
3001 int id;
3002
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003003 if (strcmp(intf, get_main_ifname(dut)) == 0)
3004 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003005 else
3006 ifname = intf;
3007
3008 id = add_network_common(dut, conn, ifname, cmd);
3009 if (id < 0)
3010 return id;
3011
3012 if (set_network(ifname, id, "key_mgmt", "NONE") < 0)
3013 return -2;
3014
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02003015 if (dut->program == PROGRAM_60GHZ && network_mode &&
3016 strcasecmp(network_mode, "PBSS") == 0 &&
3017 set_network(ifname, id, "pbss", "1") < 0)
3018 return -2;
3019
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003020 return 1;
3021}
3022
3023
Jouni Malinen8e3f8812020-10-05 10:02:03 +03003024static enum sigma_cmd_result sta_set_owe(struct sigma_dut *dut,
3025 struct sigma_conn *conn,
3026 struct sigma_cmd *cmd)
Jouni Malinen47dcc952017-10-09 16:43:24 +03003027{
3028 const char *intf = get_param(cmd, "Interface");
3029 const char *ifname, *val;
3030 int id;
3031
3032 if (intf == NULL)
Jouni Malinen8e3f8812020-10-05 10:02:03 +03003033 return INVALID_SEND_STATUS;
Jouni Malinen47dcc952017-10-09 16:43:24 +03003034
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003035 if (strcmp(intf, get_main_ifname(dut)) == 0)
3036 ifname = get_station_ifname(dut);
Jouni Malinen47dcc952017-10-09 16:43:24 +03003037 else
3038 ifname = intf;
3039
3040 id = set_wpa_common(dut, conn, ifname, cmd);
3041 if (id < 0)
3042 return id;
3043
3044 if (set_network(ifname, id, "key_mgmt", "OWE") < 0)
Jouni Malinen8e3f8812020-10-05 10:02:03 +03003045 return ERROR_SEND_STATUS;
Jouni Malinen47dcc952017-10-09 16:43:24 +03003046
Hu Wangdd5eed22020-07-16 12:18:03 +08003047 if (dut->owe_ptk_workaround &&
3048 set_network(ifname, id, "owe_ptk_workaround", "1") < 0) {
3049 sigma_dut_print(dut, DUT_MSG_ERROR,
3050 "Failed to set owe_ptk_workaround to 1");
Jouni Malinen8e3f8812020-10-05 10:02:03 +03003051 return ERROR_SEND_STATUS;
Hu Wangdd5eed22020-07-16 12:18:03 +08003052 }
3053
Jouni Malinen47dcc952017-10-09 16:43:24 +03003054 val = get_param(cmd, "ECGroupID");
Jouni Malinenfac9cad2017-10-10 18:35:55 +03003055 if (val && strcmp(val, "0") == 0) {
3056 if (wpa_command(ifname,
3057 "VENDOR_ELEM_ADD 13 ff23200000783590fb7440e03d5b3b33911f86affdcc6b4411b707846ac4ff08ddc8831ccd") != 0) {
3058 sigma_dut_print(dut, DUT_MSG_ERROR,
3059 "Failed to set OWE DH Param element override");
Jouni Malinen8e3f8812020-10-05 10:02:03 +03003060 return ERROR_SEND_STATUS;
Jouni Malinenfac9cad2017-10-10 18:35:55 +03003061 }
Hu Wangdd5eed22020-07-16 12:18:03 +08003062 } else if (val && set_network(ifname, id, "owe_group", val) < 0) {
Jouni Malinen47dcc952017-10-09 16:43:24 +03003063 sigma_dut_print(dut, DUT_MSG_ERROR,
Hu Wang6010ce72020-03-05 19:33:53 +08003064 "Failed to set owe_group");
Jouni Malinen8e3f8812020-10-05 10:02:03 +03003065 return ERROR_SEND_STATUS;
Jouni Malinen47dcc952017-10-09 16:43:24 +03003066 }
3067
Jouni Malinen8e3f8812020-10-05 10:02:03 +03003068 return SUCCESS_SEND_STATUS;
Jouni Malinen47dcc952017-10-09 16:43:24 +03003069}
3070
3071
Jouni Malinenf7222712019-06-13 01:50:21 +03003072static enum sigma_cmd_result cmd_sta_set_security(struct sigma_dut *dut,
3073 struct sigma_conn *conn,
3074 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003075{
3076 const char *type = get_param(cmd, "Type");
3077
3078 if (type == NULL) {
3079 send_resp(dut, conn, SIGMA_ERROR,
3080 "ErrorCode,Missing Type argument");
3081 return 0;
3082 }
3083
3084 if (strcasecmp(type, "OPEN") == 0)
3085 return sta_set_open(dut, conn, cmd);
Jouni Malinen47dcc952017-10-09 16:43:24 +03003086 if (strcasecmp(type, "OWE") == 0)
3087 return sta_set_owe(dut, conn, cmd);
Jouni Malinen992a81e2017-08-22 13:57:47 +03003088 if (strcasecmp(type, "PSK") == 0 ||
Jouni Malinen0ab50f42017-08-31 01:34:59 +03003089 strcasecmp(type, "PSK-SAE") == 0 ||
Jouni Malinen992a81e2017-08-22 13:57:47 +03003090 strcasecmp(type, "SAE") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003091 return cmd_sta_set_psk(dut, conn, cmd);
3092 if (strcasecmp(type, "EAPTLS") == 0)
3093 return cmd_sta_set_eaptls(dut, conn, cmd);
3094 if (strcasecmp(type, "EAPTTLS") == 0)
3095 return cmd_sta_set_eapttls(dut, conn, cmd);
3096 if (strcasecmp(type, "EAPPEAP") == 0)
3097 return cmd_sta_set_peap(dut, conn, cmd);
3098 if (strcasecmp(type, "EAPSIM") == 0)
3099 return cmd_sta_set_eapsim(dut, conn, cmd);
3100 if (strcasecmp(type, "EAPFAST") == 0)
3101 return cmd_sta_set_eapfast(dut, conn, cmd);
3102 if (strcasecmp(type, "EAPAKA") == 0)
3103 return cmd_sta_set_eapaka(dut, conn, cmd);
3104 if (strcasecmp(type, "EAPAKAPRIME") == 0)
3105 return cmd_sta_set_eapakaprime(dut, conn, cmd);
Amarnath Hullur Subramanyam81b11cd2018-01-30 19:07:17 -08003106 if (strcasecmp(type, "wep") == 0)
3107 return cmd_sta_set_encryption(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003108
3109 send_resp(dut, conn, SIGMA_ERROR,
3110 "ErrorCode,Unsupported Type value");
3111 return 0;
3112}
3113
3114
3115int ath6kl_client_uapsd(struct sigma_dut *dut, const char *intf, int uapsd)
3116{
3117#ifdef __linux__
3118 /* special handling for ath6kl */
3119 char path[128], fname[128], *pos;
3120 ssize_t res;
3121 FILE *f;
3122
Jouni Malinene39cd562019-05-29 23:39:56 +03003123 res = snprintf(fname, sizeof(fname), "/sys/class/net/%s/phy80211",
3124 intf);
3125 if (res < 0 || res >= sizeof(fname))
3126 return 0;
3127 res = readlink(fname, path, sizeof(path));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003128 if (res < 0)
3129 return 0; /* not ath6kl */
3130
3131 if (res >= (int) sizeof(path))
3132 res = sizeof(path) - 1;
3133 path[res] = '\0';
3134 pos = strrchr(path, '/');
3135 if (pos == NULL)
3136 pos = path;
3137 else
3138 pos++;
Jouni Malinen77dda642020-01-07 11:21:55 +02003139 res = snprintf(fname, sizeof(fname),
3140 "/sys/kernel/debug/ieee80211/%s/ath6kl/"
3141 "create_qos", pos);
3142 if (res < 0 || res >= sizeof(fname) || !file_exists(fname))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003143 return 0; /* not ath6kl */
3144
3145 if (uapsd) {
3146 f = fopen(fname, "w");
3147 if (f == NULL)
3148 return -1;
3149
3150 sigma_dut_print(dut, DUT_MSG_DEBUG, "Use ath6kl create_qos");
3151 fprintf(f, "4 2 2 1 2 9999999 9999999 9999999 7777777 0 4 "
3152 "45000 200 56789000 56789000 5678900 0 0 9999999 "
3153 "20000 0\n");
3154 fclose(f);
3155 } else {
Jouni Malinen77dda642020-01-07 11:21:55 +02003156 res = snprintf(fname, sizeof(fname),
3157 "/sys/kernel/debug/ieee80211/%s/ath6kl/"
3158 "delete_qos", pos);
3159 if (res < 0 || res >= sizeof(fname))
3160 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003161
3162 f = fopen(fname, "w");
3163 if (f == NULL)
3164 return -1;
3165
3166 sigma_dut_print(dut, DUT_MSG_DEBUG, "Use ath6kl delete_qos");
3167 fprintf(f, "2 4\n");
3168 fclose(f);
3169 }
3170#endif /* __linux__ */
3171
3172 return 0;
3173}
3174
3175
Jouni Malinenf7222712019-06-13 01:50:21 +03003176static enum sigma_cmd_result cmd_sta_set_uapsd(struct sigma_dut *dut,
3177 struct sigma_conn *conn,
3178 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003179{
3180 const char *intf = get_param(cmd, "Interface");
3181 /* const char *ssid = get_param(cmd, "ssid"); */
3182 const char *val;
3183 int max_sp_len = 4;
3184 int ac_be = 1, ac_bk = 1, ac_vi = 1, ac_vo = 1;
3185 char buf[100];
3186 int ret1, ret2;
3187
3188 val = get_param(cmd, "maxSPLength");
3189 if (val) {
3190 max_sp_len = atoi(val);
3191 if (max_sp_len != 0 && max_sp_len != 1 && max_sp_len != 2 &&
3192 max_sp_len != 4)
3193 return -1;
3194 }
3195
3196 val = get_param(cmd, "acBE");
3197 if (val)
3198 ac_be = atoi(val);
3199
3200 val = get_param(cmd, "acBK");
3201 if (val)
3202 ac_bk = atoi(val);
3203
3204 val = get_param(cmd, "acVI");
3205 if (val)
3206 ac_vi = atoi(val);
3207
3208 val = get_param(cmd, "acVO");
3209 if (val)
3210 ac_vo = atoi(val);
3211
3212 dut->client_uapsd = ac_be || ac_bk || ac_vi || ac_vo;
3213
3214 snprintf(buf, sizeof(buf), "P2P_SET client_apsd %d,%d,%d,%d;%d",
3215 ac_be, ac_bk, ac_vi, ac_vo, max_sp_len);
3216 ret1 = wpa_command(intf, buf);
3217
3218 snprintf(buf, sizeof(buf), "SET uapsd %d,%d,%d,%d;%d",
3219 ac_be, ac_bk, ac_vi, ac_vo, max_sp_len);
3220 ret2 = wpa_command(intf, buf);
3221
3222 if (ret1 && ret2) {
3223 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to set client mode "
3224 "UAPSD parameters.");
3225 return -2;
3226 }
3227
3228 if (ath6kl_client_uapsd(dut, intf, dut->client_uapsd) < 0) {
3229 send_resp(dut, conn, SIGMA_ERROR,
3230 "ErrorCode,Failed to set ath6kl QoS parameters");
3231 return 0;
3232 }
3233
3234 return 1;
3235}
3236
3237
Jouni Malinenf7222712019-06-13 01:50:21 +03003238static enum sigma_cmd_result cmd_sta_set_wmm(struct sigma_dut *dut,
3239 struct sigma_conn *conn,
3240 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003241{
3242 char buf[1000];
3243 const char *intf = get_param(cmd, "Interface");
3244 const char *grp = get_param(cmd, "Group");
3245 const char *act = get_param(cmd, "Action");
3246 const char *tid = get_param(cmd, "Tid");
3247 const char *dir = get_param(cmd, "Direction");
3248 const char *psb = get_param(cmd, "Psb");
3249 const char *up = get_param(cmd, "Up");
3250 const char *fixed = get_param(cmd, "Fixed");
3251 const char *size = get_param(cmd, "Size");
3252 const char *msize = get_param(cmd, "Maxsize");
3253 const char *minsi = get_param(cmd, "Min_srvc_intrvl");
3254 const char *maxsi = get_param(cmd, "Max_srvc_intrvl");
3255 const char *inact = get_param(cmd, "Inactivity");
3256 const char *sus = get_param(cmd, "Suspension");
3257 const char *mindr = get_param(cmd, "Mindatarate");
3258 const char *meandr = get_param(cmd, "Meandatarate");
3259 const char *peakdr = get_param(cmd, "Peakdatarate");
3260 const char *phyrate = get_param(cmd, "Phyrate");
3261 const char *burstsize = get_param(cmd, "Burstsize");
3262 const char *sba = get_param(cmd, "Sba");
3263 int direction;
3264 int handle;
Peng Xu93319622017-10-04 17:58:16 -07003265 float sba_fv = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003266 int fixed_int;
3267 int psb_ts;
3268
3269 if (intf == NULL || grp == NULL || act == NULL )
3270 return -1;
3271
3272 if (strcasecmp(act, "addts") == 0) {
3273 if (tid == NULL || dir == NULL || psb == NULL ||
3274 up == NULL || fixed == NULL || size == NULL)
3275 return -1;
3276
3277 /*
3278 * Note: Sigma CAPI spec lists uplink, downlink, and bidi as the
3279 * possible values, but WMM-AC and V-E test scripts use "UP,
3280 * "DOWN", and "BIDI".
3281 */
3282 if (strcasecmp(dir, "uplink") == 0 ||
3283 strcasecmp(dir, "up") == 0) {
3284 direction = 0;
3285 } else if (strcasecmp(dir, "downlink") == 0 ||
3286 strcasecmp(dir, "down") == 0) {
3287 direction = 1;
3288 } else if (strcasecmp(dir, "bidi") == 0) {
3289 direction = 2;
3290 } else {
3291 sigma_dut_print(dut, DUT_MSG_ERROR,
3292 "Direction %s not supported", dir);
3293 return -1;
3294 }
3295
3296 if (strcasecmp(psb, "legacy") == 0) {
3297 psb_ts = 0;
3298 } else if (strcasecmp(psb, "uapsd") == 0) {
3299 psb_ts = 1;
3300 } else {
3301 sigma_dut_print(dut, DUT_MSG_ERROR,
3302 "PSB %s not supported", psb);
3303 return -1;
3304 }
3305
3306 if (atoi(tid) < 0 || atoi(tid) > 7) {
3307 sigma_dut_print(dut, DUT_MSG_ERROR,
3308 "TID %s not supported", tid);
3309 return -1;
3310 }
3311
3312 if (strcasecmp(fixed, "true") == 0) {
3313 fixed_int = 1;
3314 } else {
3315 fixed_int = 0;
3316 }
3317
Peng Xu93319622017-10-04 17:58:16 -07003318 if (sba)
3319 sba_fv = atof(sba);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003320
3321 dut->dialog_token++;
3322 handle = 7000 + dut->dialog_token;
3323
3324 /*
3325 * size: convert to hex
3326 * maxsi: convert to hex
3327 * mindr: convert to hex
3328 * meandr: convert to hex
3329 * peakdr: convert to hex
3330 * burstsize: convert to hex
3331 * phyrate: convert to hex
3332 * sba: convert to hex with modification
3333 * minsi: convert to integer
3334 * sus: convert to integer
3335 * inact: convert to integer
3336 * maxsi: convert to integer
3337 */
3338
3339 /*
3340 * The Nominal MSDU Size field is 2 octets long and contains an
3341 * unsigned integer that specifies the nominal size, in octets,
3342 * of MSDUs belonging to the traffic under this traffic
3343 * specification and is defined in Figure 16. If the Fixed
3344 * subfield is set to 1, then the size of the MSDU is fixed and
3345 * is indicated by the Size Subfield. If the Fixed subfield is
3346 * set to 0, then the size of the MSDU might not be fixed and
3347 * the Size indicates the nominal MSDU size.
3348 *
3349 * The Surplus Bandwidth Allowance Factor field is 2 octets long
3350 * and specifies the excess allocation of time (and bandwidth)
3351 * over and above the stated rates required to transport an MSDU
3352 * belonging to the traffic in this TSPEC. This field is
3353 * represented as an unsigned binary number with an implicit
3354 * binary point after the leftmost 3 bits. For example, an SBA
3355 * of 1.75 is represented as 0x3800. This field is included to
3356 * account for retransmissions. As such, the value of this field
3357 * must be greater than unity.
3358 */
3359
3360 snprintf(buf, sizeof(buf),
3361 "iwpriv %s addTspec %d %s %d %d %s 0x%X"
3362 " 0x%X 0x%X 0x%X"
3363 " 0x%X 0x%X 0x%X"
3364 " 0x%X %d %d %d %d"
3365 " %d %d",
3366 intf, handle, tid, direction, psb_ts, up,
3367 (unsigned int) ((fixed_int << 15) | atoi(size)),
3368 msize ? atoi(msize) : 0,
3369 mindr ? atoi(mindr) : 0,
3370 meandr ? atoi(meandr) : 0,
3371 peakdr ? atoi(peakdr) : 0,
3372 burstsize ? atoi(burstsize) : 0,
3373 phyrate ? atoi(phyrate) : 0,
3374 sba ? ((unsigned int) (((int) sba_fv << 13) |
3375 (int)((sba_fv - (int) sba_fv) *
3376 8192))) : 0,
3377 minsi ? atoi(minsi) : 0,
3378 sus ? atoi(sus) : 0,
3379 0, 0,
3380 inact ? atoi(inact) : 0,
3381 maxsi ? atoi(maxsi) : 0);
3382
3383 if (system(buf) != 0) {
3384 sigma_dut_print(dut, DUT_MSG_ERROR,
3385 "iwpriv addtspec request failed");
3386 send_resp(dut, conn, SIGMA_ERROR,
3387 "errorCode,Failed to execute addTspec command");
3388 return 0;
3389 }
3390
3391 sigma_dut_print(dut, DUT_MSG_INFO,
3392 "iwpriv addtspec request send");
3393
3394 /* Mapping handle to a TID */
3395 dut->tid_to_handle[atoi(tid)] = handle;
3396 } else if (strcasecmp(act, "delts") == 0) {
3397 if (tid == NULL)
3398 return -1;
3399
3400 if (atoi(tid) < 0 || atoi(tid) > 7) {
3401 sigma_dut_print(dut, DUT_MSG_ERROR,
3402 "TID %s not supported", tid);
3403 send_resp(dut, conn, SIGMA_ERROR,
3404 "errorCode,Unsupported TID");
3405 return 0;
3406 }
3407
3408 handle = dut->tid_to_handle[atoi(tid)];
3409
3410 if (handle < 7000 || handle > 7255) {
3411 /* Invalid handle ie no mapping for that TID */
3412 sigma_dut_print(dut, DUT_MSG_ERROR,
3413 "handle-> %d not found", handle);
3414 }
3415
3416 snprintf(buf, sizeof(buf), "iwpriv %s delTspec %d",
3417 intf, handle);
3418
3419 if (system(buf) != 0) {
3420 sigma_dut_print(dut, DUT_MSG_ERROR,
3421 "iwpriv deltspec request failed");
3422 send_resp(dut, conn, SIGMA_ERROR,
3423 "errorCode,Failed to execute delTspec command");
3424 return 0;
3425 }
3426
3427 sigma_dut_print(dut, DUT_MSG_INFO,
3428 "iwpriv deltspec request send");
3429
3430 dut->tid_to_handle[atoi(tid)] = 0;
3431 } else {
3432 sigma_dut_print(dut, DUT_MSG_ERROR,
3433 "Action type %s not supported", act);
3434 send_resp(dut, conn, SIGMA_ERROR,
3435 "errorCode,Unsupported Action");
3436 return 0;
3437 }
3438
3439 return 1;
3440}
3441
3442
vamsi krishna52e16f92017-08-29 12:37:34 +05303443static int find_network(struct sigma_dut *dut, const char *ssid)
3444{
3445 char list[4096];
3446 char *pos;
3447
3448 sigma_dut_print(dut, DUT_MSG_DEBUG,
3449 "Search for profile based on SSID: '%s'", ssid);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003450 if (wpa_command_resp(get_station_ifname(dut), "LIST_NETWORKS",
vamsi krishna52e16f92017-08-29 12:37:34 +05303451 list, sizeof(list)) < 0)
3452 return -1;
3453 pos = strstr(list, ssid);
3454 if (!pos || pos == list || pos[-1] != '\t' || pos[strlen(ssid)] != '\t')
3455 return -1;
3456
3457 while (pos > list && pos[-1] != '\n')
3458 pos--;
3459 dut->infra_network_id = atoi(pos);
3460 snprintf(dut->infra_ssid, sizeof(dut->infra_ssid), "%s", ssid);
3461 return 0;
3462}
3463
3464
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05303465/**
3466 * enum qca_sta_helper_config_params - This helper enum defines the config
3467 * parameters which can be delivered to sta.
3468 */
3469enum qca_sta_helper_config_params {
3470 /* For the attribute QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE */
3471 STA_SET_RSNIE,
3472
3473 /* For the attribute QCA_WLAN_VENDOR_ATTR_CONFIG_LDPC */
3474 STA_SET_LDPC,
3475
3476 /* For the attribute QCA_WLAN_VENDOR_ATTR_CONFIG_TX_STBC */
3477 STA_SET_TX_STBC,
3478
3479 /* For the attribute QCA_WLAN_VENDOR_ATTR_CONFIG_RX_STBC */
3480 STA_SET_RX_STBC,
3481
3482 /* For the attribute QCA_WLAN_VENDOR_ATTR_CONFIG_TX_MSDU_AGGREGATION */
3483 STA_SET_TX_MSDU,
3484
3485 /* For the attribute QCA_WLAN_VENDOR_ATTR_CONFIG_RX_MSDU_AGGREGATION */
3486 STA_SET_RX_MSDU,
Shivani Baranwal2a572842021-09-16 12:27:15 +05303487
3488 /* For the attribute QCA_WLAN_VENDOR_ATTR_CONFIG_CHANNEL_WIDTH */
3489 STA_SET_CHAN_WIDTH,
Shivani Baranwal7aa48602021-09-29 10:53:38 +05303490
3491 /* For the attribute QCA_WLAN_VENDOR_ATTR_CONFIG_FT_OVER_DS */
3492 STA_SET_FT_DS,
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05303493};
3494
3495
3496static int sta_config_params(struct sigma_dut *dut, const char *intf,
3497 enum qca_sta_helper_config_params config_cmd,
3498 int value)
Sunil Dutt44595082018-02-12 19:41:45 +05303499{
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05303500#ifdef NL80211_SUPPORT
Sunil Dutt44595082018-02-12 19:41:45 +05303501 struct nl_msg *msg;
3502 int ret;
3503 struct nlattr *params;
3504 int ifindex;
3505
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05303506 ifindex = if_nametoindex(intf);
3507 if (ifindex == 0) {
3508 sigma_dut_print(dut, DUT_MSG_ERROR,
3509 "%s: Interface %s does not exist",
3510 __func__, intf);
3511 return -1;
3512 }
3513
Sunil Dutt44595082018-02-12 19:41:45 +05303514 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
3515 NL80211_CMD_VENDOR)) ||
3516 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
3517 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
3518 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
3519 QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION) ||
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05303520 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)))
3521 goto fail;
3522
3523 switch (config_cmd) {
3524 case STA_SET_RSNIE:
3525 if (nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE, value))
3526 goto fail;
3527 break;
3528 case STA_SET_LDPC:
3529 if (nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_LDPC, value))
3530 goto fail;
3531 break;
3532 case STA_SET_TX_STBC:
3533 if (nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TX_STBC, value))
3534 goto fail;
3535 break;
3536 case STA_SET_RX_STBC:
3537 if (nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_RX_STBC, value))
3538 goto fail;
3539 break;
3540 case STA_SET_TX_MSDU:
3541 if (nla_put_u8(msg,
3542 QCA_WLAN_VENDOR_ATTR_CONFIG_TX_MSDU_AGGREGATION,
3543 value))
3544 goto fail;
3545 break;
3546 case STA_SET_RX_MSDU:
3547 if (nla_put_u8(msg,
3548 QCA_WLAN_VENDOR_ATTR_CONFIG_RX_MSDU_AGGREGATION,
3549 value))
3550 goto fail;
3551 break;
Shivani Baranwal2a572842021-09-16 12:27:15 +05303552 case STA_SET_CHAN_WIDTH:
3553 if (nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_CHANNEL_WIDTH,
3554 value))
3555 goto fail;
3556 break;
Shivani Baranwal7aa48602021-09-29 10:53:38 +05303557 case STA_SET_FT_DS:
3558 if (nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_FT_OVER_DS,
3559 value))
3560 goto fail;
3561 break;
Sunil Dutt44595082018-02-12 19:41:45 +05303562 }
3563 nla_nest_end(msg, params);
3564
3565 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
3566 if (ret) {
3567 sigma_dut_print(dut, DUT_MSG_ERROR,
3568 "%s: err in send_and_recv_msgs, ret=%d",
3569 __func__, ret);
3570 return ret;
3571 }
3572
3573 return 0;
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05303574
3575fail:
3576 sigma_dut_print(dut, DUT_MSG_ERROR,
3577 "%s: err in adding vendor_cmd and vendor_data",
3578 __func__);
3579 nlmsg_free(msg);
Sunil Dutt44595082018-02-12 19:41:45 +05303580#endif /* NL80211_SUPPORT */
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05303581 return -1;
3582}
Sunil Dutt44595082018-02-12 19:41:45 +05303583
3584
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05303585void free_dscp_policy_table(struct sigma_dut *dut)
3586{
3587 struct dscp_policy_data *dscp_policy;
3588
3589 while (dut->dscp_policy_table) {
3590 dscp_policy = dut->dscp_policy_table;
3591 dut->dscp_policy_table = dscp_policy->next;
3592 free(dscp_policy);
3593 }
3594}
3595
3596
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05303597static char * protocol_to_str(int proto)
3598{
3599 switch (proto) {
3600 case 6:
3601 return "tcp";
3602 case 17:
3603 return "udp";
3604 case 50:
3605 return "esp";
3606 default:
3607 return "unknown";
3608 }
3609}
3610
3611
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05303612static int delete_nft_table(struct sigma_dut *dut, const char *table,
3613 const char *ip_type)
3614{
3615 int res;
3616 char cmd[200];
3617
3618 res = snprintf(cmd, sizeof(cmd), "nft delete table %s %s_%s", ip_type,
3619 table, ip_type);
3620 if (snprintf_error(sizeof(cmd), res)) {
3621 sigma_dut_print(dut, DUT_MSG_ERROR,
3622 "Failed to create delete table command");
3623 return -1;
3624 }
3625
3626 if (system(cmd) != 0) {
3627 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to run %s", cmd);
3628 return -1;
3629 }
3630
3631 return 0;
3632}
3633
3634
3635static int remove_nft_rule(struct sigma_dut *dut, int policy_id,
3636 enum ip_version ip_ver)
3637{
3638 int res;
3639 char table[50];
3640
3641 res = snprintf(table, sizeof(table), "wifi_%s_dscp_policy_%d",
3642 dut->station_ifname, policy_id);
3643 if (snprintf_error(sizeof(table), res)) {
3644 sigma_dut_print(dut, DUT_MSG_INFO,
3645 "Failed to create table name for policy %d",
3646 policy_id);
3647 return -1;
3648 }
3649
3650
3651 if (ip_ver == IPV6)
3652 return delete_nft_table(dut, table, "ip6");
3653 else
3654 return delete_nft_table(dut, table, "ip");
3655}
3656
3657
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05303658static int remove_iptable_rule(struct sigma_dut *dut,
3659 struct dscp_policy_data *dscp_policy)
3660{
3661 char ip_cmd[1000];
3662 char *pos;
3663 int ret, len;
3664 enum ip_version ip_ver = dscp_policy->ip_version;
3665
3666 pos = ip_cmd;
3667 len = sizeof(ip_cmd);
3668
3669 ret = snprintf(pos, len,
3670 "/system/bin/%s -t mangle -D OUTPUT -o %s",
3671 ip_ver == IPV6 ? "ip6tables" : "iptables",
3672 dut->station_ifname);
3673 if (snprintf_error(len, ret)) {
3674 sigma_dut_print(dut, DUT_MSG_INFO,
3675 "Failed to create delete iptables command %s",
3676 ip_cmd);
3677 return -1;
3678 }
3679
3680 pos += ret;
3681 len -= ret;
3682
3683 if (strlen(dscp_policy->src_ip)) {
3684 ret = snprintf(pos, len, " -s %s", dscp_policy->src_ip);
3685 if (snprintf_error(len, ret)) {
3686 sigma_dut_print(dut, DUT_MSG_INFO,
3687 "Error in adding src_ip %s in delete command",
3688 dscp_policy->src_ip);
3689 return -1;
3690 }
3691 pos += ret;
3692 len -= ret;
3693 }
3694
3695 if (strlen(dscp_policy->dst_ip)) {
3696 ret = snprintf(pos, len, " -d %s",
3697 dscp_policy->dst_ip);
3698 if (snprintf_error(len, ret)) {
3699 sigma_dut_print(dut, DUT_MSG_INFO,
3700 "Error in adding dst_ip %s in delete cmd",
3701 dscp_policy->dst_ip);
3702 return -1;
3703 }
3704 pos += ret;
3705 len -= ret;
3706 }
3707
3708 if (dscp_policy->src_port || dscp_policy->dst_port ||
3709 (dscp_policy->start_port && dscp_policy->end_port)) {
3710 ret = snprintf(pos, len, " -p %s",
3711 protocol_to_str(dscp_policy->protocol));
3712 if (snprintf_error(len, ret)) {
3713 sigma_dut_print(dut, DUT_MSG_INFO,
3714 "Error in adding protocol %d in delete command",
3715 dscp_policy->protocol);
3716 return -1;
3717 }
3718 pos += ret;
3719 len -= ret;
3720 }
3721
3722 if (dscp_policy->src_port) {
3723 ret = snprintf(pos, len, " --sport %d",
3724 dscp_policy->src_port);
3725 if (snprintf_error(len, ret)) {
3726 sigma_dut_print(dut, DUT_MSG_INFO,
3727 "Error in adding src_port %d in delete command",
3728 dscp_policy->src_port);
3729 return -1;
3730 }
3731 pos += ret;
3732 len -= ret;
3733 }
3734
3735 if (dscp_policy->dst_port) {
3736 ret = snprintf(pos, len, " --dport %d",
3737 dscp_policy->dst_port);
3738 if (snprintf_error(len, ret)) {
3739 sigma_dut_print(dut, DUT_MSG_INFO,
3740 "Error in adding dst_port %d in delete command",
3741 dscp_policy->dst_port);
3742 return -1;
3743 }
3744 pos += ret;
3745 len -= ret;
3746 }
3747
3748 if (dscp_policy->start_port && dscp_policy->end_port) {
3749 ret = snprintf(pos, len, " --match multiport --dports %d:%d",
3750 dscp_policy->start_port,
3751 dscp_policy->end_port);
3752 if (snprintf_error(len, ret)) {
3753 sigma_dut_print(dut, DUT_MSG_INFO,
3754 "Error in adding start:end port %d:%d in delete command",
3755 dscp_policy->start_port,
3756 dscp_policy->end_port);
3757 return -1;
3758 }
3759 pos += ret;
3760 len -= ret;
3761 }
3762
3763 ret = snprintf(pos, len, " -j DSCP --set-dscp 0x%0x",
3764 dscp_policy->dscp);
3765 if (snprintf_error(len, ret)) {
3766 sigma_dut_print(dut, DUT_MSG_INFO,
3767 "Error in adding dscp %0x in delete command",
3768 dscp_policy->dscp);
3769 return -1;
3770 }
3771 ret = system(ip_cmd);
3772 sigma_dut_print(dut, DUT_MSG_DEBUG, "iptables rule: %s err: %d",
3773 ip_cmd, ret);
3774
3775 return ret;
3776}
3777
3778
3779static int remove_dscp_policy_rule(struct sigma_dut *dut,
3780 struct dscp_policy_data *dscp_policy)
3781{
3782 return dut->dscp_use_iptables ? remove_iptable_rule(dut, dscp_policy) :
3783 remove_nft_rule(dut, dscp_policy->policy_id,
3784 dscp_policy->ip_version);
3785}
3786
3787
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05303788static int create_nft_table(struct sigma_dut *dut, int policy_id,
3789 const char *table_name, enum ip_version ip_ver)
3790{
3791 char cmd[200];
3792 int res;
3793
3794 res = snprintf(cmd, sizeof(cmd), "nft add table %s %s",
3795 ip_ver == IPV6 ? "ip6" : "ip", table_name);
3796 if (snprintf_error(sizeof(cmd), res)) {
3797 sigma_dut_print(dut, DUT_MSG_INFO,
3798 "Failed to add rule to create table for policy id %d",
3799 policy_id);
3800 return -1;
3801 }
3802
3803 if (system(cmd) != 0) {
3804 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to run %s", cmd);
3805 return -1;
3806 }
3807
3808 res = snprintf(cmd, sizeof(cmd),
3809 "nft add chain %s %s OUTPUT { type filter hook output priority 0 \\; }",
3810 ip_ver == IPV6 ? "ip6" : "ip", table_name);
3811 if (snprintf_error(sizeof(cmd), res)) {
3812 sigma_dut_print(dut, DUT_MSG_INFO,
3813 "Failed to add rule to create chain for table = %s",
3814 table_name);
3815 return -1;
3816 }
3817
3818 if (system(cmd) != 0) {
3819 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to run %s", cmd);
3820 return -1;
3821 }
3822
3823 return 0;
3824}
3825
3826
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05303827static int remove_dscp_policy(struct sigma_dut *dut, u8 policy_id)
3828{
3829 struct dscp_policy_data *dscp_policy = dut->dscp_policy_table;
3830 struct dscp_policy_data *prev = NULL;
3831
3832 while (dscp_policy) {
3833 if (dscp_policy->policy_id == policy_id)
3834 break;
3835
3836 prev = dscp_policy;
3837 dscp_policy = dscp_policy->next;
3838 }
3839
3840 /*
3841 * Consider remove request for a policy id which does not exist as
3842 * success.
3843 */
3844 if (!dscp_policy)
3845 return 0;
3846
3847 if (strlen(dscp_policy->domain_name) == 0 &&
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05303848 remove_dscp_policy_rule(dut, dscp_policy))
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05303849 return -1;
3850
3851 if (prev)
3852 prev->next = dscp_policy->next;
3853 else
3854 dut->dscp_policy_table = dscp_policy->next;
3855
3856 free(dscp_policy);
3857 return 0;
3858}
3859
3860
3861static int add_nft_rule(struct sigma_dut *dut,
3862 struct dscp_policy_data *dscp_policy)
3863{
3864 char nft_cmd[1000], ip[4], table_name[100];
3865 char *pos;
3866 int ret, len, policy_id = dscp_policy->policy_id;
3867 enum ip_version ip_ver = dscp_policy->ip_version;
3868
3869 if (ip_ver == IPV6)
3870 strlcpy(ip, "ip6", sizeof(ip));
3871 else
3872 strlcpy(ip, "ip", sizeof(ip));
3873
3874 ret = snprintf(table_name, sizeof(table_name),
3875 "wifi_%s_dscp_policy_%d_%s",
3876 dut->station_ifname, policy_id, ip);
3877 if (snprintf_error(sizeof(table_name), ret))
3878 return -1;
3879
3880 if (create_nft_table(dut, policy_id, table_name, ip_ver)) {
3881 sigma_dut_print(dut, DUT_MSG_INFO,
3882 "Failed to create nft table");
3883 return -1;
3884 }
3885
3886 pos = nft_cmd;
3887 len = sizeof(nft_cmd);
3888
3889 ret = snprintf(pos, len,
3890 "nft add rule %s %s OUTPUT oifname \"%s\"",
3891 ip, table_name, dut->station_ifname);
3892 if (snprintf_error(len, ret)) {
3893 sigma_dut_print(dut, DUT_MSG_INFO,
3894 "Failed to create nft cmd %s", nft_cmd);
3895 return -1;
3896 }
3897
3898 pos += ret;
3899 len -= ret;
3900
3901 if (strlen(dscp_policy->src_ip)) {
3902 ret = snprintf(pos, len, " %s saddr %s", ip,
3903 dscp_policy->src_ip);
3904 if (snprintf_error(len, ret))
3905 return -1;
3906
3907 pos += ret;
3908 len -= ret;
3909 }
3910
3911 if (strlen(dscp_policy->dst_ip)) {
3912 ret = snprintf(pos, len, " %s daddr %s", ip,
3913 dscp_policy->dst_ip);
3914 if (snprintf_error(len, ret))
3915 return -1;
3916
3917 pos += ret;
3918 len -= ret;
3919 }
3920
3921 if (dscp_policy->src_port) {
3922 ret = snprintf(pos, len, " %s sport %d",
3923 protocol_to_str(dscp_policy->protocol),
3924 dscp_policy->src_port);
3925 if (snprintf_error(len, ret))
3926 return -1;
3927
3928 pos += ret;
3929 len -= ret;
3930 }
3931
3932 if (dscp_policy->dst_port) {
3933 ret = snprintf(pos, len, " %s dport %d",
3934 protocol_to_str(dscp_policy->protocol),
3935 dscp_policy->dst_port);
3936 if (snprintf_error(len, ret))
3937 return -1;
3938
3939 pos += ret;
3940 len -= ret;
3941 }
3942
3943 if (dscp_policy->start_port && dscp_policy->end_port) {
3944 ret = snprintf(pos, len, " %s dport %d-%d",
3945 protocol_to_str(dscp_policy->protocol),
3946 dscp_policy->start_port,
3947 dscp_policy->end_port);
3948 if (snprintf_error(len, ret))
3949 return -1;
3950
3951 pos += ret;
3952 len -= ret;
3953 }
3954
3955 ret = snprintf(pos, len, " counter %s dscp set 0x%0x", ip,
3956 dscp_policy->dscp);
3957 if (snprintf_error(len, ret))
3958 return -1;
3959
3960 ret = system(nft_cmd);
3961 sigma_dut_print(dut, DUT_MSG_INFO, "nft rule: %s err: %d",
3962 nft_cmd, ret);
3963
3964 return ret;
3965}
3966
3967
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05303968static int add_iptable_rule(struct sigma_dut *dut,
3969 struct dscp_policy_data *dscp_policy)
3970{
3971 char ip_cmd[1000];
3972 char *pos;
3973 int ret, len;
3974 enum ip_version ip_ver = dscp_policy->ip_version;
3975 struct dscp_policy_data *active_policy = dut->dscp_policy_table;
3976 int ipv4_rule_num = 1, ipv6_rule_num = 1;
3977
3978 pos = ip_cmd;
3979 len = sizeof(ip_cmd);
3980
3981 /*
3982 * DSCP target in the mangle table doesn't stop processing of rules
3983 * so to make sure the most granular rule is applied last, add the new
3984 * rules in granularity increasing order.
3985 */
3986 while (active_policy) {
3987 /*
3988 * Domain name rules are managed in sigma_dut thus don't count
3989 * them while counting the number of active rules.
3990 */
3991 if (strlen(active_policy->domain_name)) {
3992 active_policy = active_policy->next;
3993 continue;
3994 }
3995
3996 if (active_policy->granularity_score >
3997 dscp_policy->granularity_score)
3998 break;
3999
4000 if (active_policy->ip_version == IPV6)
4001 ipv6_rule_num++;
4002 else
4003 ipv4_rule_num++;
4004
4005 active_policy = active_policy->next;
4006 }
4007
4008 ret = snprintf(pos, len,
4009 "/system/bin/%s -t mangle -I OUTPUT %d -o %s",
4010 ip_ver == IPV6 ? "ip6tables" : "iptables",
4011 ip_ver == IPV6 ? ipv6_rule_num : ipv4_rule_num,
4012 dut->station_ifname);
4013 if (snprintf_error(len, ret)) {
4014 sigma_dut_print(dut, DUT_MSG_INFO,
4015 "Failed to create iptables command %s", ip_cmd);
4016 return -1;
4017 }
4018
4019 pos += ret;
4020 len -= ret;
4021
4022 if (strlen(dscp_policy->src_ip)) {
4023 ret = snprintf(pos, len, " -s %s", dscp_policy->src_ip);
4024 if (snprintf_error(len, ret)) {
4025 sigma_dut_print(dut, DUT_MSG_INFO,
4026 "Error in adding src_ip %s",
4027 dscp_policy->src_ip);
4028 return -1;
4029 }
4030 pos += ret;
4031 len -= ret;
4032 }
4033
4034 if (strlen(dscp_policy->dst_ip)) {
4035 ret = snprintf(pos, len, " -d %s", dscp_policy->dst_ip);
4036 if (snprintf_error(len, ret)) {
4037 sigma_dut_print(dut, DUT_MSG_INFO,
4038 "Error in adding dst_ip %s",
4039 dscp_policy->dst_ip);
4040 return -1;
4041 }
4042 pos += ret;
4043 len -= ret;
4044 }
4045
4046 if (dscp_policy->src_port || dscp_policy->dst_port ||
4047 (dscp_policy->start_port && dscp_policy->end_port)) {
4048 ret = snprintf(pos, len, " -p %s",
4049 protocol_to_str(dscp_policy->protocol));
4050 if (snprintf_error(len, ret)) {
4051 sigma_dut_print(dut, DUT_MSG_INFO,
4052 "Error in adding protocol %d in add command",
4053 dscp_policy->protocol);
4054 return -1;
4055 }
4056 pos += ret;
4057 len -= ret;
4058 }
4059
4060 if (dscp_policy->src_port) {
4061 ret = snprintf(pos, len, " --sport %d", dscp_policy->src_port);
4062 if (snprintf_error(len, ret)) {
4063 sigma_dut_print(dut, DUT_MSG_INFO,
4064 "Error in adding src_port %d",
4065 dscp_policy->src_port);
4066 return -1;
4067 }
4068 pos += ret;
4069 len -= ret;
4070 }
4071
4072 if (dscp_policy->dst_port) {
4073 ret = snprintf(pos, len, " --dport %d", dscp_policy->dst_port);
4074 if (snprintf_error(len, ret)) {
4075 sigma_dut_print(dut, DUT_MSG_INFO,
4076 "Error in adding dst_port %d",
4077 dscp_policy->dst_port);
4078 return -1;
4079 }
4080 pos += ret;
4081 len -= ret;
4082 }
4083
4084 if (dscp_policy->start_port && dscp_policy->end_port) {
4085 ret = snprintf(pos, len, " --match multiport --dports %d:%d",
4086 dscp_policy->start_port, dscp_policy->end_port);
4087 if (snprintf_error(len, ret)) {
4088 sigma_dut_print(dut, DUT_MSG_INFO,
4089 "Error in adding start:end port %d:%d",
4090 dscp_policy->start_port,
4091 dscp_policy->end_port);
4092 return -1;
4093 }
4094 pos += ret;
4095 len -= ret;
4096 }
4097
4098 ret = snprintf(pos, len, " -j DSCP --set-dscp 0x%0x",
4099 dscp_policy->dscp);
4100 if (snprintf_error(len, ret)) {
4101 sigma_dut_print(dut, DUT_MSG_INFO,
4102 "Error in adding dscp %0x", dscp_policy->dscp);
4103 return -1;
4104 }
4105 ret = system(ip_cmd);
4106 sigma_dut_print(dut, DUT_MSG_DEBUG, "iptables rule: %s err: %d",
4107 ip_cmd, ret);
4108
4109 return ret;
4110}
4111
4112
4113static int add_dscp_policy_rule(struct sigma_dut *dut,
4114 struct dscp_policy_data *dscp_policy)
4115{
4116 return dut->dscp_use_iptables ? add_iptable_rule(dut, dscp_policy) :
4117 add_nft_rule(dut, dscp_policy);
4118}
4119
4120
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304121static void clear_all_dscp_policies(struct sigma_dut *dut)
4122{
4123 free_dscp_policy_table(dut);
4124
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304125 if (dut->dscp_use_iptables) {
4126 if (system("/system/bin/iptables -t mangle -F && /system/bin/iptables -t mangle -X") != 0 ||
4127 system("/system/bin/ip6tables -t mangle -F && /system/bin/iptables -t mangle -X") != 0)
4128 sigma_dut_print(dut, DUT_MSG_ERROR,
4129 "iptables: Failed to flush DSCP policy");
4130 } else {
4131 if (system("nft flush ruleset") != 0)
4132 sigma_dut_print(dut, DUT_MSG_ERROR,
4133 "nftables: Failed to flush DSCP policy");
4134 }
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304135}
4136
4137
4138static int send_dscp_response(struct sigma_dut *dut,
4139 struct dscp_policy_status *status_list,
4140 int num_status)
4141{
4142 int rem_len, ret;
4143 char buf[200] = "", *pos, cmd[256];
4144
4145 pos = buf;
4146 rem_len = sizeof(buf);
4147
4148 ret = snprintf(pos, rem_len, " solicited");
4149 if (snprintf_error(rem_len, ret)) {
4150 sigma_dut_print(dut, DUT_MSG_ERROR,
4151 "Failed to write DSCP policy response command");
4152 return -1;
4153 }
4154 pos += ret;
4155 rem_len -= ret;
4156
4157 for (int i = 0; i < num_status; i++) {
4158 ret = snprintf(pos, rem_len, " policy_id=%d status=%d",
4159 status_list[i].id, status_list[i].status);
4160 if (snprintf_error(rem_len, ret)) {
4161 sigma_dut_print(dut, DUT_MSG_ERROR,
4162 "Failed to wite DSCP policy response");
4163 return -1;
4164 }
4165
4166 pos += ret;
4167 rem_len -= ret;
4168 }
4169
4170 ret = snprintf(cmd, sizeof(cmd), "DSCP_RESP%s", buf);
4171 if (snprintf_error(sizeof(cmd), ret)) {
4172 sigma_dut_print(dut, DUT_MSG_ERROR,
4173 "Failed to create DSCP Policy Response frame");
4174 return -1;
4175 }
4176
4177 if (wpa_command(dut->station_ifname, cmd) != 0) {
4178 sigma_dut_print(dut, DUT_MSG_ERROR,
4179 "Failed to send DSCP Policy Response frame");
4180 return -1;
4181 }
4182
4183 sigma_dut_print(dut, DUT_MSG_DEBUG,
4184 "DSCP Policy Response frame sent: %s", cmd);
4185 return 0;
4186}
4187
4188
4189#ifdef ANDROID
4190static void thread_cancel_handler(int sig)
4191{
4192 if (sig == SIGUSR1)
4193 pthread_exit(0);
4194}
4195#endif /* ANDROID */
4196
4197
4198static void * mon_dscp_policies(void *ptr)
4199{
4200 struct sigma_dut *dut = ptr;
4201 int ret, policy_id;
4202 struct wpa_ctrl *ctrl;
4203 char buf[4096], *pos, *end;
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304204 struct dscp_policy_data *policy = NULL, *current_policy, *prev_policy;
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304205 struct dscp_policy_status status_list[10];
4206 int num_status = 0;
4207 const char *events[] = {
4208 "CTRL-EVENT-DISCONNECTED",
4209 "CTRL-EVENT-DSCP-POLICY",
4210 NULL
4211 };
4212#ifdef ANDROID
4213 struct sigaction actions;
4214#endif /* ANDROID */
4215
4216 ctrl = open_wpa_mon(get_station_ifname(dut));
4217 if (!ctrl) {
4218 sigma_dut_print(dut, DUT_MSG_ERROR,
4219 "Failed to open wpa_supplicant monitor connection");
4220 return NULL;
4221 }
4222
4223#ifdef ANDROID
4224 memset(&actions, 0, sizeof(actions));
4225 sigemptyset(&actions.sa_mask);
4226 actions.sa_flags = 0;
4227 actions.sa_handler = thread_cancel_handler;
4228 if (sigaction(SIGUSR1, &actions, NULL) == -1) {
4229 sigma_dut_print(dut, DUT_MSG_ERROR,
4230 "Failed to register exit handler for %s",
4231 __func__);
4232 wpa_ctrl_detach(ctrl);
4233 wpa_ctrl_close(ctrl);
4234 return NULL;
4235 }
4236#endif /* ANDROID */
4237
4238 while (1) {
4239 ret = get_wpa_cli_events_timeout(dut, ctrl, events,
4240 buf, sizeof(buf), 0);
4241
4242 if (ret || strlen(buf) == 0) {
4243 sigma_dut_print(dut, DUT_MSG_INFO,
4244 "Did not receive any event");
4245 continue;
4246 }
4247
4248 if (strstr(buf, "CTRL-EVENT-DISCONNECTED")) {
4249 clear_all_dscp_policies(dut);
4250 break;
4251 }
4252
4253 if (strstr(buf, "request_start")) {
4254 num_status = 0;
4255 if (strstr(buf, "clear_all"))
4256 clear_all_dscp_policies(dut);
4257 continue;
4258 }
4259
4260 if (strstr(buf, "request_end")) {
4261 send_dscp_response(dut, status_list, num_status);
4262 continue;
4263 }
4264
4265 if (!strstr(buf, "add") && !strstr(buf, "remove") &&
4266 !strstr(buf, "reject")) {
4267 sigma_dut_print(dut, DUT_MSG_DEBUG, "Ignore event: %s",
4268 buf);
4269 continue;
4270 }
4271
4272 pos = strstr(buf, "policy_id=");
4273 if (!pos) {
4274 sigma_dut_print(dut, DUT_MSG_INFO,
4275 "Policy id not present");
4276 continue;
4277 }
4278 policy_id = atoi(pos + 10);
4279
4280 if (num_status >= ARRAY_SIZE(status_list)) {
4281 sigma_dut_print(dut, DUT_MSG_INFO,
4282 "Max policies allowed per DSCP request reached. Drop policy id %d request",
4283 policy_id);
4284 continue;
4285 }
4286 status_list[num_status].id = policy_id;
4287
Veerendranath Jakkama16cdc82021-09-12 16:44:22 +05304288 if (dut->reject_dscp_policies) {
4289 status_list[num_status].status =
4290 dut->dscp_reject_resp_code;
4291 num_status++;
4292 continue;
4293 }
4294
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304295 if (strstr(buf, "reject"))
4296 goto reject;
4297
4298 /*
4299 * In case of "add" also if policy with same policy id exist it
4300 * shall be removed. So always call remove_dscp_policy().
4301 */
4302 if (remove_dscp_policy(dut, policy_id))
4303 goto reject;
4304
4305 if (strstr(buf, "remove"))
4306 goto success;
4307
4308 policy = malloc(sizeof(*policy));
4309 if (!policy)
4310 goto reject;
4311
4312 memset(policy, 0, sizeof(*policy));
4313
4314 policy->policy_id = policy_id;
4315
4316 pos = strstr(buf, "dscp=");
4317 if (!pos) {
4318 sigma_dut_print(dut, DUT_MSG_ERROR,
4319 "DSCP info not present");
4320 goto reject;
4321 }
4322 policy->dscp = atoi(pos + 5);
4323
4324 pos = strstr(buf, "ip_version=");
4325 if (!pos) {
4326 sigma_dut_print(dut, DUT_MSG_ERROR,
4327 "IP version info not present");
4328 goto reject;
4329 }
4330 policy->ip_version = atoi(pos + 11);
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304331 if (policy->ip_version)
4332 policy->granularity_score++;
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304333
4334 pos = strstr(buf, "domain_name=");
4335 if (pos) {
4336 pos += 12;
4337 end = strchr(pos, ' ');
4338 if (!end)
4339 end = pos + strlen(pos);
4340
4341 if (end - pos >= (int) sizeof(policy->domain_name))
4342 goto reject;
4343
4344 memcpy(policy->domain_name, pos, end - pos);
4345 policy->domain_name[end - pos] = '\0';
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304346 policy->granularity_score++;
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304347 }
4348
4349 pos = strstr(buf, "start_port=");
4350 if (pos) {
4351 pos += 11;
4352 policy->start_port = atoi(pos);
4353 }
4354
4355 pos = strstr(buf, "end_port=");
4356 if (pos) {
4357 pos += 9;
4358 policy->end_port = atoi(pos);
4359 }
4360
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304361 if (policy->start_port && policy->end_port)
4362 policy->granularity_score++;
4363
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304364 pos = strstr(buf, "src_ip=");
4365 if (pos) {
4366 pos += 7;
4367 end = strchr(pos, ' ');
4368 if (!end)
4369 end = pos + strlen(pos);
4370
4371 if (end - pos >= (int) sizeof(policy->src_ip))
4372 goto reject;
4373
4374 memcpy(policy->src_ip, pos, end - pos);
4375 policy->src_ip[end - pos] = '\0';
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304376 policy->granularity_score++;
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304377 }
4378
4379 pos = strstr(buf, "dst_ip=");
4380 if (pos) {
4381 pos += 7;
4382 end = strchr(pos, ' ');
4383 if (!end)
4384 end = pos + strlen(pos);
4385
4386 if (end - pos >= (int) sizeof(policy->dst_ip))
4387 goto reject;
4388
4389 memcpy(policy->dst_ip, pos, end - pos);
4390 policy->dst_ip[end - pos] = '\0';
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304391 policy->granularity_score++;
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304392 }
4393
4394 pos = strstr(buf, "src_port=");
4395 if (pos) {
4396 pos += 9;
4397 policy->src_port = atoi(pos);
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304398 policy->granularity_score++;
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304399 }
4400
4401 pos = strstr(buf, "dst_port=");
4402 if (pos) {
4403 pos += 9;
4404 policy->dst_port = atoi(pos);
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304405 policy->granularity_score++;
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304406 }
4407
4408 pos = strstr(buf, "protocol=");
4409 if (pos) {
4410 pos += 9;
4411 policy->protocol = atoi(pos);
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304412 policy->granularity_score++;
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304413 }
4414
4415 /*
4416 * Skip adding nft rules for doman name policies.
4417 * Domain name rules are applied in sigma_dut itself.
4418 */
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304419 if (!strlen(policy->domain_name) &&
4420 add_dscp_policy_rule(dut, policy))
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304421 goto reject;
4422
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304423 /*
4424 * Add the new policy in policy table in granularity increasing
4425 * order.
4426 */
4427 current_policy = dut->dscp_policy_table;
4428 prev_policy = NULL;
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304429
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304430 while (current_policy) {
4431 if (current_policy->granularity_score >
4432 policy->granularity_score)
4433 break;
4434
4435 prev_policy = current_policy;
4436 current_policy = current_policy->next;
4437 }
4438
4439 if (prev_policy)
4440 prev_policy->next = policy;
4441 else
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304442 dut->dscp_policy_table = policy;
4443
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304444 policy->next = current_policy;
4445
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304446success:
4447 status_list[num_status].status = DSCP_POLICY_SUCCESS;
4448 num_status++;
4449 policy = NULL;
4450 continue;
4451reject:
4452 status_list[num_status].status = DSCP_POLICY_REJECT;
4453 num_status++;
4454 free(policy);
4455 policy = NULL;
4456 }
4457
4458 free_dscp_policy_table(dut);
4459 wpa_ctrl_detach(ctrl);
4460 wpa_ctrl_close(ctrl);
4461
4462 pthread_exit(0);
4463 return NULL;
4464}
4465
4466
4467static void start_dscp_policy_mon_thread(struct sigma_dut *dut)
4468{
4469 /* Create event thread */
4470 pthread_create(&dut->dscp_policy_mon_thread, NULL, &mon_dscp_policies,
4471 (void *) dut);
4472}
4473
4474
4475void stop_dscp_policy_mon_thread(struct sigma_dut *dut)
4476{
4477 if (dut->dscp_policy_mon_thread) {
4478#ifdef ANDROID
4479 /* pthread_cancel not supported in Android */
4480 pthread_kill(dut->dscp_policy_mon_thread, SIGUSR1);
4481#else /* ANDROID */
4482 pthread_cancel(dut->dscp_policy_mon_thread);
4483#endif /* ANDROID */
4484 dut->dscp_policy_mon_thread = 0;
4485 }
4486}
4487
4488
Jouni Malinenf7222712019-06-13 01:50:21 +03004489static enum sigma_cmd_result cmd_sta_associate(struct sigma_dut *dut,
4490 struct sigma_conn *conn,
4491 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004492{
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05304493#ifdef NL80211_SUPPORT
4494 const char *intf = get_param(cmd, "Interface");
4495#endif /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004496 const char *ssid = get_param(cmd, "ssid");
4497 const char *wps_param = get_param(cmd, "WPS");
4498 const char *bssid = get_param(cmd, "bssid");
Jouni Malinen46a19b62017-06-23 14:31:27 +03004499 const char *chan = get_param(cmd, "channel");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02004500 const char *network_mode = get_param(cmd, "network_mode");
Veerendranath Jakkama082e342020-05-16 00:19:21 +05304501 const char *ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004502 int wps = 0;
Jouni Malinen3c367e82017-06-23 17:01:47 +03004503 char buf[1000], extra[50];
Jouni Malinen134fe3c2019-06-12 04:16:49 +03004504 int e;
4505 enum sigma_cmd_result ret = SUCCESS_SEND_STATUS;
4506 struct wpa_ctrl *ctrl = NULL;
4507 int num_network_not_found = 0;
4508 int num_disconnected = 0;
4509 int tod = -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004510
4511 if (ssid == NULL)
4512 return -1;
4513
Jouni Malinen37d5c692019-08-19 16:56:55 +03004514 dut->server_cert_tod = 0;
4515
Jouni Malinen3c367e82017-06-23 17:01:47 +03004516 if (dut->rsne_override) {
Sunil Dutt44595082018-02-12 19:41:45 +05304517#ifdef NL80211_SUPPORT
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004518 if (get_driver_type(dut) == DRIVER_WCN) {
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05304519 sta_config_params(dut, intf, STA_SET_RSNIE, 1);
Sunil Dutt44595082018-02-12 19:41:45 +05304520 dut->config_rsnie = 1;
4521 }
4522#endif /* NL80211_SUPPORT */
Jouni Malinen3c367e82017-06-23 17:01:47 +03004523 snprintf(buf, sizeof(buf), "TEST_ASSOC_IE %s",
4524 dut->rsne_override);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004525 if (wpa_command(get_station_ifname(dut), buf) < 0) {
Jouni Malinen3c367e82017-06-23 17:01:47 +03004526 send_resp(dut, conn, SIGMA_ERROR,
4527 "ErrorCode,Failed to set DEV_CONFIGURE_IE RSNE override");
4528 return 0;
4529 }
4530 }
4531
Jouni Malinen68143132017-09-02 02:34:08 +03004532 if (dut->sae_commit_override) {
4533 snprintf(buf, sizeof(buf), "SET sae_commit_override %s",
4534 dut->sae_commit_override);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004535 if (wpa_command(get_station_ifname(dut), buf) < 0) {
Jouni Malinen68143132017-09-02 02:34:08 +03004536 send_resp(dut, conn, SIGMA_ERROR,
4537 "ErrorCode,Failed to set SAE commit override");
4538 return 0;
4539 }
4540 }
Ankita Bajaj1bde7942018-01-09 19:15:01 +05304541#ifdef ANDROID
4542 if (dut->fils_hlp)
4543 process_fils_hlp(dut);
4544#endif /* ANDROID */
Jouni Malinen68143132017-09-02 02:34:08 +03004545
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004546 if (wps_param &&
4547 (strcmp(wps_param, "1") == 0 || strcasecmp(wps_param, "On") == 0))
4548 wps = 1;
4549
4550 if (wps) {
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02004551 if (dut->program == PROGRAM_60GHZ && network_mode &&
4552 strcasecmp(network_mode, "PBSS") == 0 &&
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004553 set_network(get_station_ifname(dut), dut->infra_network_id,
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02004554 "pbss", "1") < 0)
4555 return -2;
4556
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004557 if (dut->wps_method == WFA_CS_WPS_NOT_READY) {
4558 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,WPS "
4559 "parameters not yet set");
4560 return 0;
4561 }
4562 if (dut->wps_method == WFA_CS_WPS_PBC) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004563 if (wpa_command(get_station_ifname(dut), "WPS_PBC") < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004564 return -2;
4565 } else {
4566 snprintf(buf, sizeof(buf), "WPS_PIN any %s",
4567 dut->wps_pin);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004568 if (wpa_command(get_station_ifname(dut), buf) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004569 return -2;
4570 }
4571 } else {
vamsi krishna52e16f92017-08-29 12:37:34 +05304572 if (strcmp(ssid, dut->infra_ssid) == 0) {
4573 sigma_dut_print(dut, DUT_MSG_DEBUG,
4574 "sta_associate for the most recently added network");
4575 } else if (find_network(dut, ssid) < 0) {
4576 sigma_dut_print(dut, DUT_MSG_DEBUG,
4577 "sta_associate for a previously stored network profile");
4578 send_resp(dut, conn, SIGMA_ERROR,
4579 "ErrorCode,Profile not found");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004580 return 0;
4581 }
4582
4583 if (bssid &&
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004584 set_network(get_station_ifname(dut), dut->infra_network_id,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004585 "bssid", bssid) < 0) {
4586 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
4587 "Invalid bssid argument");
4588 return 0;
4589 }
4590
Veerendranath Jakkama082e342020-05-16 00:19:21 +05304591 if ((dut->program == PROGRAM_WPA3 &&
4592 dut->sta_associate_wait_connect) ||
4593 dut->program == PROGRAM_QM) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004594 ctrl = open_wpa_mon(get_station_ifname(dut));
Jouni Malinen134fe3c2019-06-12 04:16:49 +03004595 if (!ctrl)
4596 return ERROR_SEND_STATUS;
4597 }
4598
Jouni Malinen46a19b62017-06-23 14:31:27 +03004599 extra[0] = '\0';
4600 if (chan)
4601 snprintf(extra, sizeof(extra), " freq=%u",
Alexei Avshalom Lazar093569f2018-11-13 14:08:17 +02004602 channel_to_freq(dut, atoi(chan)));
Jouni Malinen46a19b62017-06-23 14:31:27 +03004603 snprintf(buf, sizeof(buf), "SELECT_NETWORK %d%s",
4604 dut->infra_network_id, extra);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004605 if (wpa_command(get_station_ifname(dut), buf) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004606 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to select "
4607 "network id %d on %s",
4608 dut->infra_network_id,
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004609 get_station_ifname(dut));
Jouni Malinen134fe3c2019-06-12 04:16:49 +03004610 ret = ERROR_SEND_STATUS;
4611 goto done;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004612 }
4613 }
4614
Jouni Malinen134fe3c2019-06-12 04:16:49 +03004615 if (!ctrl)
4616 return SUCCESS_SEND_STATUS;
4617
4618 /* Wait for connection result to be able to store server certificate
4619 * hash for trust root override testing
4620 * (dev_exec_action,ServerCertTrust). */
4621
4622 for (e = 0; e < 20; e++) {
4623 const char *events[] = {
4624 "CTRL-EVENT-EAP-PEER-CERT",
4625 "CTRL-EVENT-EAP-TLS-CERT-ERROR",
4626 "CTRL-EVENT-DISCONNECTED",
4627 "CTRL-EVENT-CONNECTED",
4628 "CTRL-EVENT-NETWORK-NOT-FOUND",
4629 NULL
4630 };
4631 char buf[1024];
4632 int res;
4633
4634 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
4635 if (res < 0) {
Jouni Malinenf1f16642019-11-15 21:19:04 +02004636 send_resp(dut, conn, SIGMA_COMPLETE,
4637 "Result,Association did not complete");
Jouni Malinen134fe3c2019-06-12 04:16:49 +03004638 ret = STATUS_SENT_ERROR;
4639 break;
4640 }
4641 sigma_dut_print(dut, DUT_MSG_DEBUG, "Connection event: %s",
4642 buf);
4643
4644 if (strstr(buf, "CTRL-EVENT-EAP-PEER-CERT") &&
4645 strstr(buf, " depth=0")) {
4646 char *pos = strstr(buf, " hash=");
4647
4648 if (pos) {
4649 char *end;
4650
Jouni Malinen34b19cb2019-08-16 16:37:17 +03004651 if (strstr(buf, " tod=1"))
4652 tod = 1;
4653 else if (strstr(buf, " tod=2"))
4654 tod = 2;
4655 else
4656 tod = 0;
Jouni Malinen134fe3c2019-06-12 04:16:49 +03004657 sigma_dut_print(dut, DUT_MSG_DEBUG,
4658 "Server certificate TOD policy: %d",
4659 tod);
Jouni Malinen37d5c692019-08-19 16:56:55 +03004660 dut->server_cert_tod = tod;
Jouni Malinen134fe3c2019-06-12 04:16:49 +03004661
4662 pos += 6;
4663 end = strchr(pos, ' ');
4664 if (end)
4665 *end = '\0';
4666 strlcpy(dut->server_cert_hash, pos,
4667 sizeof(dut->server_cert_hash));
4668 sigma_dut_print(dut, DUT_MSG_DEBUG,
4669 "Server certificate hash: %s",
4670 dut->server_cert_hash);
4671 }
4672 }
4673
4674 if (strstr(buf, "CTRL-EVENT-EAP-TLS-CERT-ERROR")) {
4675 send_resp(dut, conn, SIGMA_COMPLETE,
4676 "Result,TLS server certificate validation failed");
4677 ret = STATUS_SENT_ERROR;
4678 break;
4679 }
4680
4681 if (strstr(buf, "CTRL-EVENT-NETWORK-NOT-FOUND")) {
4682 num_network_not_found++;
4683
4684 if (num_network_not_found > 2) {
4685 send_resp(dut, conn, SIGMA_COMPLETE,
4686 "Result,Network not found");
4687 ret = STATUS_SENT_ERROR;
4688 break;
4689 }
4690 }
4691
4692 if (strstr(buf, "CTRL-EVENT-DISCONNECTED")) {
4693 num_disconnected++;
4694
4695 if (num_disconnected > 2) {
4696 send_resp(dut, conn, SIGMA_COMPLETE,
4697 "Result,Connection failed");
4698 ret = STATUS_SENT_ERROR;
4699 break;
4700 }
4701 }
4702
4703 if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
4704 if (tod >= 0) {
4705 sigma_dut_print(dut, DUT_MSG_DEBUG,
4706 "Network profile TOD policy update: %d -> %d",
4707 dut->sta_tod_policy, tod);
4708 dut->sta_tod_policy = tod;
4709 }
Veerendranath Jakkama082e342020-05-16 00:19:21 +05304710 if (dut->program == PROGRAM_QM) {
4711 unsigned char iface_mac_addr[ETH_ALEN];
4712 char ipv6[100];
4713
4714 if (get_hwaddr(ifname, iface_mac_addr) < 0) {
4715 sigma_dut_print(dut, DUT_MSG_ERROR,
4716 "%s: get_hwaddr %s failed",
4717 __func__, ifname);
4718 ret = ERROR_SEND_STATUS;
4719 break;
4720 }
4721
4722 convert_mac_addr_to_ipv6_lladdr(iface_mac_addr,
4723 ipv6,
4724 sizeof(ipv6));
4725
4726 if (set_ipv6_addr(dut, ipv6, "64", ifname) !=
4727 0) {
4728 ret = ERROR_SEND_STATUS;
4729 break;
4730 }
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304731 start_dscp_policy_mon_thread(dut);
Veerendranath Jakkama082e342020-05-16 00:19:21 +05304732 }
Jouni Malinen134fe3c2019-06-12 04:16:49 +03004733 break;
4734 }
4735 }
4736done:
4737 if (ctrl) {
4738 wpa_ctrl_detach(ctrl);
4739 wpa_ctrl_close(ctrl);
4740 }
4741 return ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004742}
4743
4744
4745static int run_hs20_osu(struct sigma_dut *dut, const char *params)
4746{
4747 char buf[500], cmd[200];
4748 int res;
4749
4750 /* Use hs20-osu-client file at the current dir, if found; otherwise use
4751 * default path */
4752 res = snprintf(cmd, sizeof(cmd),
4753 "%s -w \"%s\" -r hs20-osu-client.res %s%s -dddKt -f Logs/hs20-osu-client.txt",
4754 file_exists("./hs20-osu-client") ?
4755 "./hs20-osu-client" : "hs20-osu-client",
4756 sigma_wpas_ctrl,
4757 dut->summary_log ? "-s " : "",
4758 dut->summary_log ? dut->summary_log : "");
4759 if (res < 0 || res >= (int) sizeof(cmd))
4760 return -1;
4761
4762 res = snprintf(buf, sizeof(buf), "%s %s", cmd, params);
4763 if (res < 0 || res >= (int) sizeof(buf))
4764 return -1;
4765 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
4766
4767 if (system(buf) != 0) {
4768 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to run: %s", buf);
4769 return -1;
4770 }
4771 sigma_dut_print(dut, DUT_MSG_DEBUG,
4772 "Completed hs20-osu-client operation");
4773
4774 return 0;
4775}
4776
4777
4778static int download_ppsmo(struct sigma_dut *dut,
4779 struct sigma_conn *conn,
4780 const char *intf,
4781 struct sigma_cmd *cmd)
4782{
4783 const char *name, *path, *val;
4784 char url[500], buf[600], fbuf[100];
4785 char *fqdn = NULL;
4786
4787 name = get_param(cmd, "FileName");
4788 path = get_param(cmd, "FilePath");
4789 if (name == NULL || path == NULL)
4790 return -1;
4791
4792 if (strcasecmp(path, "VendorSpecific") == 0) {
4793 snprintf(url, sizeof(url), "PPS/%s", name);
4794 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured PPS MO "
4795 "from the device (%s)", url);
4796 if (!file_exists(url)) {
4797 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
4798 "PPS MO file does not exist");
4799 return 0;
4800 }
4801 snprintf(buf, sizeof(buf), "cp %s pps-tnds.xml", url);
4802 if (system(buf) != 0) {
4803 send_resp(dut, conn, SIGMA_ERROR,
4804 "errorCode,Failed to copy PPS MO");
4805 return 0;
4806 }
4807 } else if (strncasecmp(path, "http:", 5) != 0 &&
4808 strncasecmp(path, "https:", 6) != 0) {
4809 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
4810 "Unsupported FilePath value");
4811 return 0;
4812 } else {
4813 snprintf(url, sizeof(url), "%s/%s", path, name);
4814 sigma_dut_print(dut, DUT_MSG_INFO, "Downloading PPS MO from %s",
4815 url);
4816 snprintf(buf, sizeof(buf), "wget -T 10 -t 3 -O pps-tnds.xml '%s'", url);
4817 remove("pps-tnds.xml");
4818 if (system(buf) != 0) {
4819 send_resp(dut, conn, SIGMA_ERROR,
4820 "errorCode,Failed to download PPS MO");
4821 return 0;
4822 }
4823 }
4824
4825 if (run_hs20_osu(dut, "from_tnds pps-tnds.xml pps.xml") < 0) {
4826 send_resp(dut, conn, SIGMA_ERROR,
4827 "errorCode,Failed to parse downloaded PPSMO");
4828 return 0;
4829 }
4830 unlink("pps-tnds.xml");
4831
4832 val = get_param(cmd, "managementTreeURI");
4833 if (val) {
4834 const char *pos, *end;
4835 sigma_dut_print(dut, DUT_MSG_DEBUG, "managementTreeURI: %s",
4836 val);
4837 if (strncmp(val, "./Wi-Fi/", 8) != 0) {
4838 send_resp(dut, conn, SIGMA_ERROR,
4839 "errorCode,Invalid managementTreeURI prefix");
4840 return 0;
4841 }
4842 pos = val + 8;
4843 end = strchr(pos, '/');
4844 if (end == NULL ||
4845 strcmp(end, "/PerProviderSubscription") != 0) {
4846 send_resp(dut, conn, SIGMA_ERROR,
4847 "errorCode,Invalid managementTreeURI postfix");
4848 return 0;
4849 }
4850 if (end - pos >= (int) sizeof(fbuf)) {
4851 send_resp(dut, conn, SIGMA_ERROR,
4852 "errorCode,Too long FQDN in managementTreeURI");
4853 return 0;
4854 }
4855 memcpy(fbuf, pos, end - pos);
4856 fbuf[end - pos] = '\0';
4857 fqdn = fbuf;
4858 sigma_dut_print(dut, DUT_MSG_INFO,
4859 "FQDN from managementTreeURI: %s", fqdn);
4860 } else if (run_hs20_osu(dut, "get_fqdn pps.xml") == 0) {
4861 FILE *f = fopen("pps-fqdn", "r");
4862 if (f) {
4863 if (fgets(fbuf, sizeof(fbuf), f)) {
4864 fbuf[sizeof(fbuf) - 1] = '\0';
4865 fqdn = fbuf;
4866 sigma_dut_print(dut, DUT_MSG_DEBUG,
4867 "Use FQDN %s", fqdn);
4868 }
4869 fclose(f);
4870 }
4871 }
4872
4873 if (fqdn == NULL) {
4874 send_resp(dut, conn, SIGMA_ERROR,
4875 "errorCode,No FQDN specified");
4876 return 0;
4877 }
4878
4879 mkdir("SP", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
4880 snprintf(buf, sizeof(buf), "SP/%s", fqdn);
4881 mkdir(buf, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
4882
4883 snprintf(buf, sizeof(buf), "SP/%s/pps.xml", fqdn);
4884 if (rename("pps.xml", buf) < 0) {
4885 send_resp(dut, conn, SIGMA_ERROR,
4886 "errorCode,Could not move PPS MO");
4887 return 0;
4888 }
4889
4890 if (strcasecmp(path, "VendorSpecific") == 0) {
4891 snprintf(buf, sizeof(buf), "cp Certs/ca.pem SP/%s/ca.pem",
4892 fqdn);
4893 if (system(buf)) {
4894 send_resp(dut, conn, SIGMA_ERROR,
4895 "errorCode,Failed to copy OSU CA cert");
4896 return 0;
4897 }
4898
4899 snprintf(buf, sizeof(buf),
4900 "cp Certs/aaa-ca.pem SP/%s/aaa-ca.pem",
4901 fqdn);
4902 if (system(buf)) {
4903 send_resp(dut, conn, SIGMA_ERROR,
4904 "errorCode,Failed to copy AAA CA cert");
4905 return 0;
4906 }
4907 } else {
4908 snprintf(buf, sizeof(buf),
4909 "dl_osu_ca SP/%s/pps.xml SP/%s/ca.pem",
4910 fqdn, fqdn);
4911 if (run_hs20_osu(dut, buf) < 0) {
4912 send_resp(dut, conn, SIGMA_ERROR,
4913 "errorCode,Failed to download OSU CA cert");
4914 return 0;
4915 }
4916
4917 snprintf(buf, sizeof(buf),
4918 "dl_aaa_ca SP/%s/pps.xml SP/%s/aaa-ca.pem",
4919 fqdn, fqdn);
4920 if (run_hs20_osu(dut, buf) < 0) {
4921 sigma_dut_print(dut, DUT_MSG_INFO,
4922 "Failed to download AAA CA cert");
4923 }
4924 }
4925
4926 if (file_exists("next-client-cert.pem")) {
4927 snprintf(buf, sizeof(buf), "SP/%s/client-cert.pem", fqdn);
4928 if (rename("next-client-cert.pem", buf) < 0) {
4929 send_resp(dut, conn, SIGMA_ERROR,
4930 "errorCode,Could not move client certificate");
4931 return 0;
4932 }
4933 }
4934
4935 if (file_exists("next-client-key.pem")) {
4936 snprintf(buf, sizeof(buf), "SP/%s/client-key.pem", fqdn);
4937 if (rename("next-client-key.pem", buf) < 0) {
4938 send_resp(dut, conn, SIGMA_ERROR,
4939 "errorCode,Could not move client key");
4940 return 0;
4941 }
4942 }
4943
4944 snprintf(buf, sizeof(buf), "set_pps SP/%s/pps.xml", fqdn);
4945 if (run_hs20_osu(dut, buf) < 0) {
4946 send_resp(dut, conn, SIGMA_ERROR,
4947 "errorCode,Failed to configure credential from "
4948 "PPSMO");
4949 return 0;
4950 }
4951
4952 return 1;
4953}
4954
4955
4956static int download_cert(struct sigma_dut *dut,
4957 struct sigma_conn *conn,
4958 const char *intf,
4959 struct sigma_cmd *cmd)
4960{
4961 const char *name, *path;
4962 char url[500], buf[600];
4963
4964 name = get_param(cmd, "FileName");
4965 path = get_param(cmd, "FilePath");
4966 if (name == NULL || path == NULL)
4967 return -1;
4968
4969 if (strcasecmp(path, "VendorSpecific") == 0) {
4970 snprintf(url, sizeof(url), "Certs/%s-cert.pem", name);
4971 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured client "
4972 "certificate from the device (%s)", url);
4973 if (!file_exists(url)) {
4974 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
4975 "certificate file does not exist");
4976 return 0;
4977 }
4978 snprintf(buf, sizeof(buf), "cp %s next-client-cert.pem", url);
4979 if (system(buf) != 0) {
4980 send_resp(dut, conn, SIGMA_ERROR,
4981 "errorCode,Failed to copy client "
4982 "certificate");
4983 return 0;
4984 }
4985
4986 snprintf(url, sizeof(url), "Certs/%s-key.pem", name);
4987 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured client "
4988 "private key from the device (%s)", url);
4989 if (!file_exists(url)) {
4990 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
4991 "private key file does not exist");
4992 return 0;
4993 }
4994 snprintf(buf, sizeof(buf), "cp %s next-client-key.pem", url);
4995 if (system(buf) != 0) {
4996 send_resp(dut, conn, SIGMA_ERROR,
4997 "errorCode,Failed to copy client key");
4998 return 0;
4999 }
5000 } else if (strncasecmp(path, "http:", 5) != 0 &&
5001 strncasecmp(path, "https:", 6) != 0) {
5002 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
5003 "Unsupported FilePath value");
5004 return 0;
5005 } else {
5006 snprintf(url, sizeof(url), "%s/%s.pem", path, name);
5007 sigma_dut_print(dut, DUT_MSG_INFO, "Downloading client "
5008 "certificate/key from %s", url);
5009 snprintf(buf, sizeof(buf),
5010 "wget -T 10 -t 3 -O next-client-cert.pem '%s'", url);
5011 if (system(buf) != 0) {
5012 send_resp(dut, conn, SIGMA_ERROR,
5013 "errorCode,Failed to download client "
5014 "certificate");
5015 return 0;
5016 }
5017
5018 if (system("cp next-client-cert.pem next-client-key.pem") != 0)
5019 {
5020 send_resp(dut, conn, SIGMA_ERROR,
5021 "errorCode,Failed to copy client key");
5022 return 0;
5023 }
5024 }
5025
5026 return 1;
5027}
5028
5029
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02005030static int cmd_sta_preset_testparameters_60ghz(struct sigma_dut *dut,
5031 struct sigma_conn *conn,
5032 struct sigma_cmd *cmd)
5033{
5034 const char *val;
5035 const char *intf = get_param(cmd, "interface");
5036
5037 if (!intf)
5038 return -1;
5039
5040 val = get_param(cmd, "WscIEFragment");
5041 if (val && strcasecmp(val, "enable") == 0) {
5042 sigma_dut_print(dut, DUT_MSG_DEBUG,
5043 "Enable WSC IE fragmentation");
5044
5045 dut->wsc_fragment = 1;
5046 /* set long attributes to force fragmentation */
5047 if (wpa_command(intf, "SET device_name "
5048 WPS_LONG_DEVICE_NAME) < 0)
5049 return -2;
5050 if (wpa_command(intf, "SET manufacturer "
5051 WPS_LONG_MANUFACTURER) < 0)
5052 return -2;
5053 if (wpa_command(intf, "SET model_name "
5054 WPS_LONG_MODEL_NAME) < 0)
5055 return -2;
5056 if (wpa_command(intf, "SET model_number "
5057 WPS_LONG_MODEL_NUMBER) < 0)
5058 return -2;
5059 if (wpa_command(intf, "SET serial_number "
5060 WPS_LONG_SERIAL_NUMBER) < 0)
5061 return -2;
5062 }
5063
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02005064 val = get_param(cmd, "RSN_IE");
5065 if (val) {
5066 if (strcasecmp(val, "disable") == 0)
5067 dut->force_rsn_ie = FORCE_RSN_IE_REMOVE;
5068 else if (strcasecmp(val, "enable") == 0)
5069 dut->force_rsn_ie = FORCE_RSN_IE_ADD;
5070 }
5071
Alexei Avshalom Lazar744ae8a2019-01-31 17:26:46 +02005072 val = get_param(cmd, "WpsVersion");
5073 if (val)
5074 dut->wps_forced_version = get_wps_forced_version(dut, val);
5075
Alexei Avshalom Lazar2eccf4d2019-01-31 10:03:59 +02005076 val = get_param(cmd, "WscEAPFragment");
5077 if (val && strcasecmp(val, "enable") == 0)
5078 dut->eap_fragment = 1;
5079
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02005080 return 1;
5081}
5082
5083
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005084static int cmd_sta_preset_testparameters_hs2_r2(struct sigma_dut *dut,
5085 struct sigma_conn *conn,
5086 const char *intf,
5087 struct sigma_cmd *cmd)
5088{
5089 const char *val;
5090
5091 val = get_param(cmd, "FileType");
5092 if (val && strcasecmp(val, "PPSMO") == 0)
5093 return download_ppsmo(dut, conn, intf, cmd);
5094 if (val && strcasecmp(val, "CERT") == 0)
5095 return download_cert(dut, conn, intf, cmd);
5096 if (val) {
5097 send_resp(dut, conn, SIGMA_ERROR,
5098 "ErrorCode,Unsupported FileType");
5099 return 0;
5100 }
5101
5102 return 1;
5103}
5104
5105
Ankita Bajaja2cb5672017-10-25 16:08:28 +05305106static int cmd_sta_preset_testparameters_oce(struct sigma_dut *dut,
5107 struct sigma_conn *conn,
5108 const char *intf,
5109 struct sigma_cmd *cmd)
5110{
5111 const char *val;
Ankita Bajaj1bde7942018-01-09 19:15:01 +05305112 char buf[1000];
5113 char text[20];
5114 unsigned char addr[ETH_ALEN];
Ankita Bajaja2cb5672017-10-25 16:08:28 +05305115
5116 val = get_param(cmd, "OCESupport");
5117 if (val && strcasecmp(val, "Disable") == 0) {
5118 if (wpa_command(intf, "SET oce 0") < 0) {
5119 send_resp(dut, conn, SIGMA_ERROR,
5120 "ErrorCode,Failed to disable OCE");
5121 return 0;
5122 }
5123 } else if (val && strcasecmp(val, "Enable") == 0) {
5124 if (wpa_command(intf, "SET oce 1") < 0) {
5125 send_resp(dut, conn, SIGMA_ERROR,
5126 "ErrorCode,Failed to enable OCE");
5127 return 0;
5128 }
5129 }
5130
vamsi krishnaa2799492017-12-05 14:28:01 +05305131 val = get_param(cmd, "FILScap");
5132 if (val && (atoi(val) == 1)) {
5133 if (wpa_command(intf, "SET disable_fils 0") < 0) {
5134 send_resp(dut, conn, SIGMA_ERROR,
5135 "ErrorCode,Failed to enable FILS");
5136 return 0;
5137 }
5138 } else if (val && (atoi(val) == 0)) {
5139 if (wpa_command(intf, "SET disable_fils 1") < 0) {
5140 send_resp(dut, conn, SIGMA_ERROR,
5141 "ErrorCode,Failed to disable FILS");
5142 return 0;
5143 }
5144 }
5145
Ankita Bajaj1bde7942018-01-09 19:15:01 +05305146 val = get_param(cmd, "FILSHLP");
5147 if (val && strcasecmp(val, "Enable") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005148 if (get_wpa_status(get_station_ifname(dut), "address", text,
Ankita Bajaj1bde7942018-01-09 19:15:01 +05305149 sizeof(text)) < 0)
5150 return -2;
5151 hwaddr_aton(text, addr);
5152 snprintf(buf, sizeof(buf),
5153 "FILS_HLP_REQ_ADD ff:ff:ff:ff:ff:ff "
5154 "080045100140000040004011399e00000000ffffffff00440043"
5155 "012cb30001010600fd4f46410000000000000000000000000000"
5156 "000000000000"
5157 "%02x%02x%02x%02x%02x%02x"
5158 "0000000000000000000000000000000000000000000000000000"
5159 "0000000000000000000000000000000000000000000000000000"
5160 "0000000000000000000000000000000000000000000000000000"
5161 "0000000000000000000000000000000000000000000000000000"
5162 "0000000000000000000000000000000000000000000000000000"
5163 "0000000000000000000000000000000000000000000000000000"
5164 "0000000000000000000000000000000000000000000000000000"
5165 "0000000000000000000000000000000000000000638253633501"
5166 "013d0701000af549d29b390205dc3c12616e64726f69642d6468"
5167 "63702d382e302e30370a0103060f1a1c333a3b2b5000ff00",
5168 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
5169 if (wpa_command(intf, buf)) {
5170 send_resp(dut, conn, SIGMA_ERROR,
5171 "ErrorCode,Failed to add HLP");
5172 return 0;
5173 }
5174 dut->fils_hlp = 1;
5175 }
5176
Ankita Bajaja2cb5672017-10-25 16:08:28 +05305177 return 1;
5178}
5179
5180
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005181static void ath_sta_set_noack(struct sigma_dut *dut, const char *intf,
5182 const char *val)
5183{
5184 int counter = 0;
5185 char token[50];
5186 char *result;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05305187 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005188
Peng Xub8fc5cc2017-05-10 17:27:28 -07005189 strlcpy(token, val, sizeof(token));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005190 token[sizeof(token) - 1] = '\0';
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05305191 result = strtok_r(token, ":", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005192 while (result) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005193 if (strcmp(result, "disable") == 0)
5194 run_iwpriv(dut, intf, "noackpolicy %d 1 0", counter);
5195 else
5196 run_iwpriv(dut, intf, "noackpolicy %d 1 1", counter);
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05305197 result = strtok_r(NULL, ":", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005198 counter++;
5199 }
5200}
5201
5202
5203static void ath_sta_set_rts(struct sigma_dut *dut, const char *intf,
5204 const char *val)
5205{
5206 char buf[100];
5207
5208 snprintf(buf, sizeof(buf), "iwconfig %s rts %s", intf, val);
5209 if (system(buf) != 0) {
5210 sigma_dut_print(dut, DUT_MSG_ERROR, "iwconfig RTS failed");
5211 }
5212}
5213
5214
5215static void ath_sta_set_wmm(struct sigma_dut *dut, const char *intf,
5216 const char *val)
5217{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005218 if (strcasecmp(val, "off") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005219 run_iwpriv(dut, intf, "wmm 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005220 }
5221}
5222
5223
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08005224static int wcn_sta_set_wmm(struct sigma_dut *dut, const char *intf,
5225 const char *val)
5226{
5227#ifdef NL80211_SUPPORT
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08005228 int wmmenable = 1;
5229
5230 if (val &&
5231 (strcasecmp(val, "off") == 0 || strcmp(val, "0") == 0))
5232 wmmenable = 0;
5233
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05305234 return wcn_wifi_test_config_set_u8(
5235 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WMM_ENABLE,
5236 wmmenable);
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08005237#else /* NL80211_SUPPORT */
5238 sigma_dut_print(dut, DUT_MSG_ERROR,
5239 "WMM cannot be changed without NL80211_SUPPORT defined");
5240 return -1;
5241#endif /* NL80211_SUPPORT */
5242}
5243
5244
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005245static void ath_sta_set_sgi(struct sigma_dut *dut, const char *intf,
5246 const char *val)
5247{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005248 int sgi20;
5249
5250 sgi20 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
5251
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005252 run_iwpriv(dut, intf, "shortgi %d", sgi20);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005253}
5254
5255
5256static void ath_sta_set_11nrates(struct sigma_dut *dut, const char *intf,
5257 const char *val)
5258{
Pradeep Reddy POTTETI67376b72016-10-25 20:08:17 +05305259 int rate_code, v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005260
5261 /* Disable Tx Beam forming when using a fixed rate */
5262 ath_disable_txbf(dut, intf);
5263
Pradeep Reddy POTTETI67376b72016-10-25 20:08:17 +05305264 v = atoi(val);
5265 if (v < 0 || v > 32) {
5266 sigma_dut_print(dut, DUT_MSG_ERROR,
5267 "Invalid Fixed MCS rate: %d", v);
5268 return;
5269 }
5270 rate_code = 0x80 + v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005271
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005272 run_iwpriv(dut, intf, "set11NRates 0x%x", rate_code);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005273
5274 /* Channel width gets messed up, fix this */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005275 run_iwpriv(dut, intf, "chwidth %d", dut->chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005276}
5277
5278
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08005279static void iwpriv_sta_set_amsdu(struct sigma_dut *dut, const char *intf,
5280 const char *val)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005281{
5282 char buf[60];
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05305283 int ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005284
5285 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)
5286 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 2", intf);
5287 else
5288 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 1", intf);
5289
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05305290 ret = system(buf);
5291#ifdef NL80211_SUPPORT
5292 if (ret) {
5293 int value = (strcasecmp(val, "Enable") == 0) ? 2 : 1;
5294
5295 ret = sta_config_params(dut, intf, STA_SET_TX_MSDU, value);
5296 ret |= sta_config_params(dut, intf, STA_SET_RX_MSDU, value);
5297 }
5298#endif /* NL80211_SUPPORT */
5299 if (ret)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005300 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv amsdu failed");
5301}
5302
5303
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07005304static int iwpriv_sta_set_ampdu(struct sigma_dut *dut, const char *intf,
5305 int ampdu)
5306{
5307 char buf[60];
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08005308 int maxaggregation = 63;
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07005309
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08005310 if (ampdu)
5311 ampdu = maxaggregation;
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07005312 snprintf(buf, sizeof(buf), "iwpriv %s ampdu %d", intf, ampdu);
5313 if (system(buf) != 0) {
5314 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv ampdu failed");
5315 return -1;
5316 }
5317
5318 return 0;
5319}
5320
5321
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005322static void ath_sta_set_stbc(struct sigma_dut *dut, const char *intf,
5323 const char *val)
5324{
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005325 run_iwpriv(dut, intf, "tx_stbc %s", val);
5326 run_iwpriv(dut, intf, "rx_stbc %s", val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005327}
5328
5329
5330static int wcn_sta_set_cts_width(struct sigma_dut *dut, const char *intf,
5331 const char *val)
5332{
5333 char buf[60];
5334
Peng Xucc317ed2017-05-18 16:44:37 -07005335 if (strcmp(val, "160") == 0) {
5336 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 5", intf);
5337 } else if (strcmp(val, "80") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005338 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 3", intf);
5339 } else if (strcmp(val, "40") == 0) {
5340 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 2", intf);
5341 } else if (strcmp(val, "20") == 0) {
5342 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 1", intf);
5343 } else if (strcasecmp(val, "Auto") == 0) {
5344 buf[0] = '\0';
5345 } else {
5346 sigma_dut_print(dut, DUT_MSG_ERROR,
5347 "WIDTH/CTS_WIDTH value not supported");
5348 return -1;
5349 }
5350
5351 if (buf[0] != '\0' && system(buf) != 0) {
5352 sigma_dut_print(dut, DUT_MSG_ERROR,
5353 "Failed to set WIDTH/CTS_WIDTH");
5354 return -1;
5355 }
5356
5357 return 0;
5358}
5359
5360
5361int ath_set_width(struct sigma_dut *dut, struct sigma_conn *conn,
5362 const char *intf, const char *val)
5363{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005364 if (strcasecmp(val, "Auto") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005365 run_iwpriv(dut, intf, "chwidth 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005366 dut->chwidth = 0;
5367 } else if (strcasecmp(val, "20") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005368 run_iwpriv(dut, intf, "chwidth 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005369 dut->chwidth = 0;
5370 } else if (strcasecmp(val, "40") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005371 run_iwpriv(dut, intf, "chwidth 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005372 dut->chwidth = 1;
5373 } else if (strcasecmp(val, "80") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005374 run_iwpriv(dut, intf, "chwidth 2");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005375 dut->chwidth = 2;
5376 } else if (strcasecmp(val, "160") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005377 run_iwpriv(dut, intf, "chwidth 3");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005378 dut->chwidth = 3;
5379 } else {
5380 send_resp(dut, conn, SIGMA_ERROR,
5381 "ErrorCode,WIDTH not supported");
5382 return -1;
5383 }
5384
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005385 return 0;
5386}
5387
5388
5389static int wcn_sta_set_sp_stream(struct sigma_dut *dut, const char *intf,
5390 const char *val)
5391{
5392 char buf[60];
Arif Hussainac6c5112018-05-25 17:34:00 -07005393 int sta_nss;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005394
Amarnath Hullur Subramanyamd5374fa2018-02-25 19:00:24 -08005395 if (strcmp(val, "1SS") == 0 || strcmp(val, "1") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005396 snprintf(buf, sizeof(buf), "iwpriv %s nss 1", intf);
Arif Hussainac6c5112018-05-25 17:34:00 -07005397 sta_nss = 1;
Amarnath Hullur Subramanyamd5374fa2018-02-25 19:00:24 -08005398 } else if (strcmp(val, "2SS") == 0 || strcmp(val, "2") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005399 snprintf(buf, sizeof(buf), "iwpriv %s nss 2", intf);
Arif Hussainac6c5112018-05-25 17:34:00 -07005400 sta_nss = 2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005401 } else {
5402 sigma_dut_print(dut, DUT_MSG_ERROR,
5403 "SP_STREAM value not supported");
5404 return -1;
5405 }
5406
5407 if (system(buf) != 0) {
5408 sigma_dut_print(dut, DUT_MSG_ERROR,
5409 "Failed to set SP_STREAM");
5410 return -1;
5411 }
5412
Arif Hussainac6c5112018-05-25 17:34:00 -07005413 dut->sta_nss = sta_nss;
5414
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005415 return 0;
5416}
5417
5418
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05305419static void wcn_sta_set_stbc(struct sigma_dut *dut, const char *intf,
5420 const char *val)
5421{
5422 char buf[60];
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05305423 int ret;
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05305424
5425 snprintf(buf, sizeof(buf), "iwpriv %s tx_stbc %s", intf, val);
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05305426 ret = system(buf);
5427#ifdef NL80211_SUPPORT
5428 if (ret)
5429 ret = sta_config_params(dut, intf, STA_SET_TX_STBC,
5430 strcmp(val, "0") == 0 ? 0 : 1);
5431#endif /* NL80211_SUPPORT */
5432 if (ret)
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05305433 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv tx_stbc failed");
5434
5435 snprintf(buf, sizeof(buf), "iwpriv %s rx_stbc %s", intf, val);
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05305436 ret = system(buf);
5437#ifdef NL80211_SUPPORT
5438 if (ret)
5439 ret = sta_config_params(dut, intf, STA_SET_RX_STBC,
5440 strcmp(val, "0") == 0 ? 0 : 1);
5441#endif /* NL80211_SUPPORT */
5442 if (ret)
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05305443 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv rx_stbc failed");
5444}
5445
5446
Ashwini Patil68d02cd2017-01-10 15:39:16 +05305447static int mbo_set_cellular_data_capa(struct sigma_dut *dut,
5448 struct sigma_conn *conn,
5449 const char *intf, int capa)
5450{
5451 char buf[32];
5452
5453 if (capa > 0 && capa < 4) {
5454 snprintf(buf, sizeof(buf), "SET mbo_cell_capa %d", capa);
5455 if (wpa_command(intf, buf) < 0) {
5456 send_resp(dut, conn, SIGMA_ERROR,
5457 "ErrorCode, Failed to set cellular data capability");
5458 return 0;
5459 }
5460 return 1;
5461 }
5462
5463 sigma_dut_print(dut, DUT_MSG_ERROR,
5464 "Invalid Cellular data capability: %d", capa);
5465 send_resp(dut, conn, SIGMA_INVALID,
5466 "ErrorCode,Invalid cellular data capability");
5467 return 0;
5468}
5469
5470
Ashwini Patil9183fdb2017-04-13 16:58:25 +05305471static int mbo_set_roaming(struct sigma_dut *dut, struct sigma_conn *conn,
5472 const char *intf, const char *val)
5473{
5474 if (strcasecmp(val, "Disable") == 0) {
5475 if (wpa_command(intf, "SET roaming 0") < 0) {
5476 send_resp(dut, conn, SIGMA_ERROR,
5477 "ErrorCode,Failed to disable roaming");
5478 return 0;
5479 }
5480 return 1;
5481 }
5482
5483 if (strcasecmp(val, "Enable") == 0) {
5484 if (wpa_command(intf, "SET roaming 1") < 0) {
5485 send_resp(dut, conn, SIGMA_ERROR,
5486 "ErrorCode,Failed to enable roaming");
5487 return 0;
5488 }
5489 return 1;
5490 }
5491
5492 sigma_dut_print(dut, DUT_MSG_ERROR,
5493 "Invalid value provided for roaming: %s", val);
5494 send_resp(dut, conn, SIGMA_INVALID,
5495 "ErrorCode,Unknown value provided for Roaming");
5496 return 0;
5497}
5498
5499
Ashwini Patila75de5a2017-04-13 16:35:05 +05305500static int mbo_set_assoc_disallow(struct sigma_dut *dut,
5501 struct sigma_conn *conn,
5502 const char *intf, const char *val)
5503{
5504 if (strcasecmp(val, "Disable") == 0) {
5505 if (wpa_command(intf, "SET ignore_assoc_disallow 1") < 0) {
5506 send_resp(dut, conn, SIGMA_ERROR,
5507 "ErrorCode,Failed to disable Assoc_disallow");
5508 return 0;
5509 }
5510 return 1;
5511 }
5512
5513 if (strcasecmp(val, "Enable") == 0) {
5514 if (wpa_command(intf, "SET ignore_assoc_disallow 0") < 0) {
5515 send_resp(dut, conn, SIGMA_ERROR,
5516 "ErrorCode,Failed to enable Assoc_disallow");
5517 return 0;
5518 }
5519 return 1;
5520 }
5521
5522 sigma_dut_print(dut, DUT_MSG_ERROR,
5523 "Invalid value provided for Assoc_disallow: %s", val);
5524 send_resp(dut, conn, SIGMA_INVALID,
5525 "ErrorCode,Unknown value provided for Assoc_disallow");
5526 return 0;
5527}
5528
5529
Ashwini Patilc63161e2017-04-13 16:30:23 +05305530static int mbo_set_bss_trans_req(struct sigma_dut *dut, struct sigma_conn *conn,
5531 const char *intf, const char *val)
5532{
5533 if (strcasecmp(val, "Reject") == 0) {
5534 if (wpa_command(intf, "SET reject_btm_req_reason 1") < 0) {
5535 send_resp(dut, conn, SIGMA_ERROR,
5536 "ErrorCode,Failed to Reject BTM Request");
5537 return 0;
5538 }
5539 return 1;
5540 }
5541
5542 if (strcasecmp(val, "Accept") == 0) {
5543 if (wpa_command(intf, "SET reject_btm_req_reason 0") < 0) {
5544 send_resp(dut, conn, SIGMA_ERROR,
5545 "ErrorCode,Failed to Accept BTM Request");
5546 return 0;
5547 }
5548 return 1;
5549 }
5550
5551 sigma_dut_print(dut, DUT_MSG_ERROR,
5552 "Invalid value provided for BSS_Transition: %s", val);
5553 send_resp(dut, conn, SIGMA_INVALID,
5554 "ErrorCode,Unknown value provided for BSS_Transition");
5555 return 0;
5556}
5557
5558
Ashwini Patil00402582017-04-13 12:29:39 +05305559static int mbo_set_non_pref_ch_list(struct sigma_dut *dut,
5560 struct sigma_conn *conn,
5561 const char *intf,
5562 struct sigma_cmd *cmd)
5563{
5564 const char *ch, *pref, *op_class, *reason;
5565 char buf[120];
5566 int len, ret;
5567
5568 pref = get_param(cmd, "Ch_Pref");
5569 if (!pref)
5570 return 1;
5571
5572 if (strcasecmp(pref, "clear") == 0) {
5573 free(dut->non_pref_ch_list);
5574 dut->non_pref_ch_list = NULL;
5575 } else {
5576 op_class = get_param(cmd, "Ch_Op_Class");
5577 if (!op_class) {
5578 send_resp(dut, conn, SIGMA_INVALID,
5579 "ErrorCode,Ch_Op_Class not provided");
5580 return 0;
5581 }
5582
5583 ch = get_param(cmd, "Ch_Pref_Num");
5584 if (!ch) {
5585 send_resp(dut, conn, SIGMA_INVALID,
5586 "ErrorCode,Ch_Pref_Num not provided");
5587 return 0;
5588 }
5589
5590 reason = get_param(cmd, "Ch_Reason_Code");
5591 if (!reason) {
5592 send_resp(dut, conn, SIGMA_INVALID,
5593 "ErrorCode,Ch_Reason_Code not provided");
5594 return 0;
5595 }
5596
5597 if (!dut->non_pref_ch_list) {
5598 dut->non_pref_ch_list =
5599 calloc(1, NON_PREF_CH_LIST_SIZE);
5600 if (!dut->non_pref_ch_list) {
5601 send_resp(dut, conn, SIGMA_ERROR,
5602 "ErrorCode,Failed to allocate memory for non_pref_ch_list");
5603 return 0;
5604 }
5605 }
5606 len = strlen(dut->non_pref_ch_list);
5607 ret = snprintf(dut->non_pref_ch_list + len,
5608 NON_PREF_CH_LIST_SIZE - len,
5609 " %s:%s:%s:%s", op_class, ch, pref, reason);
5610 if (ret > 0 && ret < NON_PREF_CH_LIST_SIZE - len) {
5611 sigma_dut_print(dut, DUT_MSG_DEBUG, "non_pref_list: %s",
5612 dut->non_pref_ch_list);
5613 } else {
5614 sigma_dut_print(dut, DUT_MSG_ERROR,
5615 "snprintf failed for non_pref_list, ret = %d",
5616 ret);
5617 send_resp(dut, conn, SIGMA_ERROR,
5618 "ErrorCode,snprintf failed");
5619 free(dut->non_pref_ch_list);
5620 dut->non_pref_ch_list = NULL;
5621 return 0;
5622 }
5623 }
5624
5625 ret = snprintf(buf, sizeof(buf), "SET non_pref_chan%s",
5626 dut->non_pref_ch_list ? dut->non_pref_ch_list : " ");
5627 if (ret < 0 || ret >= (int) sizeof(buf)) {
5628 sigma_dut_print(dut, DUT_MSG_DEBUG,
5629 "snprintf failed for set non_pref_chan, ret: %d",
5630 ret);
5631 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,snprint failed");
5632 return 0;
5633 }
5634
5635 if (wpa_command(intf, buf) < 0) {
5636 send_resp(dut, conn, SIGMA_ERROR,
5637 "ErrorCode,Failed to set non-preferred channel list");
5638 return 0;
5639 }
5640
5641 return 1;
5642}
5643
5644
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08005645#ifdef NL80211_SUPPORT
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08005646
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08005647static int sta_set_he_htc_supp(struct sigma_dut *dut, const char *intf,
5648 uint8_t cfg)
5649{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05305650 return wcn_wifi_test_config_set_u8(
5651 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_HTC_HE_SUPP,
5652 cfg);
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08005653}
5654
5655
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08005656static int sta_set_he_fragmentation(struct sigma_dut *dut, const char *intf,
5657 enum he_fragmentation_val frag)
5658{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05305659 return wcn_wifi_test_config_set_u8(
5660 dut, intf,
5661 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_FRAGMENTATION, frag);
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08005662}
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08005663
5664
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -08005665int wcn_set_he_ltf(struct sigma_dut *dut, const char *intf,
5666 enum qca_wlan_he_ltf_cfg ltf)
Subhani Shaik8e7a3052018-04-24 14:03:00 -07005667{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05305668 return wcn_wifi_test_config_set_u8(
5669 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_LTF, ltf);
Subhani Shaik8e7a3052018-04-24 14:03:00 -07005670}
5671
5672
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08005673static int nlvendor_sta_set_noack(struct sigma_dut *dut, const char *intf,
5674 int noack, enum qca_wlan_ac_type ac)
5675{
5676 struct nl_msg *msg;
5677 int ret = 0;
5678 struct nlattr *params;
5679 int ifindex;
5680
5681 ifindex = if_nametoindex(intf);
5682 if (ifindex == 0) {
5683 sigma_dut_print(dut, DUT_MSG_ERROR,
5684 "%s: Index for interface %s failed",
5685 __func__, intf);
5686 return -1;
5687 }
5688
5689 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
5690 NL80211_CMD_VENDOR)) ||
5691 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
5692 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
5693 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
5694 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
5695 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
5696 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_NO_ACK,
5697 noack) ||
5698 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_NO_ACK_AC,
5699 ac)) {
5700 sigma_dut_print(dut, DUT_MSG_ERROR,
5701 "%s: err in adding vendor_cmd and vendor_data",
5702 __func__);
5703 nlmsg_free(msg);
5704 return -1;
5705 }
5706 nla_nest_end(msg, params);
5707
5708 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5709 if (ret) {
5710 sigma_dut_print(dut, DUT_MSG_ERROR,
5711 "%s: err in send_and_recv_msgs, ret=%d",
5712 __func__, ret);
5713 }
5714 return ret;
5715}
5716
5717
5718static void wcn_sta_set_noack(struct sigma_dut *dut, const char *intf,
5719 const char *val)
5720{
5721 int noack, ret;
5722 char token[100];
5723 char *result;
5724 char *saveptr;
5725 enum qca_wlan_ac_type ac = QCA_WLAN_AC_BE;
5726
5727 strlcpy(token, val, sizeof(token));
5728 token[sizeof(token) - 1] = '\0';
5729 result = strtok_r(token, ":", &saveptr);
5730 while (result) {
5731 noack = strcasecmp(result, "Disable") != 0;
5732 ret = nlvendor_sta_set_noack(dut, intf, noack, ac);
5733 if (ret) {
5734 sigma_dut_print(dut, DUT_MSG_ERROR,
5735 "nlvendor_sta_set_noack failed for ac:%d, ret:%d",
5736 ac, ret);
5737 }
5738 result = strtok_r(NULL, ":", &saveptr);
5739 ac++;
5740 }
5741}
5742
Vinita S. Maloo7462e812020-05-22 15:16:04 +05305743
5744static int nlvendor_sta_set_phymode(struct sigma_dut *dut, const char *intf,
5745 enum qca_wlan_vendor_phy_mode val)
5746{
5747 struct nl_msg *msg;
5748 struct nlattr *params;
5749 int ifindex, ret;
5750
5751 ifindex = if_nametoindex(intf);
5752 if (ifindex == 0) {
5753 sigma_dut_print(dut, DUT_MSG_ERROR,
5754 "%s: Index for interface %s not found",
5755 __func__, intf);
5756 return -1;
5757 }
5758
5759 msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
5760 NL80211_CMD_VENDOR);
5761 if (!msg) {
5762 sigma_dut_print(dut, DUT_MSG_ERROR,
5763 "%s: err in adding vendor_cmd", __func__);
5764 return -1;
5765 }
5766
5767 if (nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
5768 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
5769 QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION)) {
5770 sigma_dut_print(dut, DUT_MSG_ERROR,
5771 "%s: err in adding vendor_attr", __func__);
5772 nlmsg_free(msg);
5773 return -1;
5774 }
5775
5776 params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
5777 if (!params || nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_PHY_MODE,
5778 val)) {
5779 sigma_dut_print(dut, DUT_MSG_ERROR,
5780 "%s: err in adding vendor_data", __func__);
5781 nlmsg_free(msg);
5782 return -1;
5783 }
5784
5785 nla_nest_end(msg, params);
5786 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5787 if (ret) {
5788 sigma_dut_print(dut, DUT_MSG_ERROR,
5789 "%s: err in send_and_recv_msgs, ret=%d (%s)",
5790 __func__, ret, strerror(-ret));
5791 return ret;
5792 }
5793
5794 return 0;
5795}
5796
5797
5798static enum qca_wlan_vendor_phy_mode get_qca_vendor_phymode(const char *val)
5799{
5800 if (strcmp(val, "11a") == 0) {
5801 /* IEEE80211_MODE_11A */
5802 return QCA_WLAN_VENDOR_PHY_MODE_11A;
5803 }
5804
5805 if (strcmp(val, "11g") == 0) {
5806 /* IEEE80211_MODE_11G */
5807 return QCA_WLAN_VENDOR_PHY_MODE_11G;
5808 }
5809
5810 if (strcmp(val, "11b") == 0) {
5811 /* IEEE80211_MODE_11B */
5812 return QCA_WLAN_VENDOR_PHY_MODE_11B;
5813 }
5814
5815 if (strcmp(val, "11n") == 0 ||
5816 strcmp(val, "11nl") == 0 ||
5817 strcmp(val, "11nl(nabg)") == 0) {
5818 /* IEEE80211_MODE_11AGN */
5819 return QCA_WLAN_VENDOR_PHY_MODE_11AGN;
5820 }
5821
5822 if (strcmp(val, "11ng") == 0) {
5823 /* IEEE80211_MODE_11NG_HT40 */
5824 return QCA_WLAN_VENDOR_PHY_MODE_11NG_HT40;
5825 }
5826
5827 if (strcmp(val, "AC") == 0 ||
5828 strcasecmp(val, "11AC") == 0) {
5829 /* IEEE80211_MODE_11AC_VHT80 */
5830 return QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT80;
5831 }
5832
5833 if (strcmp(val, "11na") == 0 ||
5834 strcasecmp(val, "11an") == 0) {
5835 /* IEEE80211_MODE_11NA_HT40 */
5836 return QCA_WLAN_VENDOR_PHY_MODE_11NA_HT40;
5837 }
5838
5839 if (strcmp(val, "11ax") == 0 ||
5840 strcmp(val, "auto") == 0) {
5841 /* IEEE80211_MODE_AUTO */
5842 return QCA_WLAN_VENDOR_PHY_MODE_AUTO;
5843 }
5844
5845 return -1;
5846}
5847
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08005848#endif /* NL80211_SUPPORT */
5849
5850
Vinita S. Maloo13a5cf72020-05-22 14:45:06 +05305851static int get_phymode(const char *val)
5852{
5853 if (strcmp(val, "11a") == 0)
5854 return 1; /* IEEE80211_MODE_11A */
5855 if (strcmp(val, "11g") == 0)
5856 return 3; /* IEEE80211_MODE_11G */
5857 if (strcmp(val, "11b") == 0)
5858 return 2; /* IEEE80211_MODE_11B */
5859 if (strcmp(val, "11n") == 0 ||
5860 strcmp(val, "11nl") == 0 ||
5861 strcmp(val, "11nl(nabg)") == 0)
5862 return 22; /* IEEE80211_MODE_11AGN */
5863 if (strcmp(val, "11ng") == 0)
5864 return 13; /* IEEE80211_MODE_11NG_HT40 */
5865 if (strcmp(val, "AC") == 0 ||
5866 strcasecmp(val, "11AC") == 0)
5867 return 19; /* IEEE80211_MODE_11AC_VHT80 */
5868 if (strcmp(val, "11na") == 0 ||
5869 strcasecmp(val, "11an") == 0)
5870 return 14; /* IEEE80211_MODE_11NA_HT40 */
5871 if (strcmp(val, "11ax") == 0 ||
5872 strcmp(val, "auto") == 0)
5873 return 0; /* IEEE80211_MODE_AUTO */
5874 return -1;
5875}
5876
5877
5878static void sta_set_phymode(struct sigma_dut *dut, const char *intf,
5879 const char *val)
5880{
5881 char buf[100];
5882 int len, phymode;
Vinita S. Maloo7462e812020-05-22 15:16:04 +05305883#ifdef NL80211_SUPPORT
5884 enum qca_wlan_vendor_phy_mode qca_phymode;
5885
5886 qca_phymode = get_qca_vendor_phymode(val);
5887 if (qca_phymode == -1) {
5888 sigma_dut_print(dut, DUT_MSG_DEBUG,
5889 "Ignoring mode change for mode: %s",
5890 val);
5891 return;
5892 }
5893
5894 if (nlvendor_sta_set_phymode(dut, intf, qca_phymode) == 0)
5895 return;
5896#endif /* NL80211_SUPPORT */
Vinita S. Maloo13a5cf72020-05-22 14:45:06 +05305897
5898 phymode = get_phymode(val);
5899 if (phymode == -1) {
5900 sigma_dut_print(dut, DUT_MSG_DEBUG,
5901 "Ignoring mode change for mode: %s",
5902 val);
5903 return;
5904 }
5905
5906 len = snprintf(buf, sizeof(buf), "iwpriv %s setphymode %d", intf,
5907 phymode);
5908 if (len < 0 || len >= sizeof(buf)) {
5909 sigma_dut_print(dut, DUT_MSG_ERROR,
5910 "Failed to set phymode");
5911 return;
5912 }
5913
5914 if (system(buf) != 0)
5915 sigma_dut_print(dut, DUT_MSG_ERROR,
5916 "iwpriv setting of phymode failed");
5917}
5918
5919
Jouni Malinenf7222712019-06-13 01:50:21 +03005920static enum sigma_cmd_result
5921cmd_sta_preset_testparameters(struct sigma_dut *dut, struct sigma_conn *conn,
5922 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005923{
5924 const char *intf = get_param(cmd, "Interface");
5925 const char *val;
5926
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03005927 val = get_param(cmd, "FT_DS");
5928 if (val) {
5929 if (strcasecmp(val, "Enable") == 0) {
5930 dut->sta_ft_ds = 1;
5931 } else if (strcasecmp(val, "Disable") == 0) {
5932 dut->sta_ft_ds = 0;
5933 } else {
5934 send_resp(dut, conn, SIGMA_ERROR,
5935 "errorCode,Unsupported value for FT_DS");
5936 return STATUS_SENT_ERROR;
5937 }
Shivani Baranwal7aa48602021-09-29 10:53:38 +05305938 if (get_driver_type(dut) == DRIVER_WCN &&
5939 sta_config_params(dut, intf, STA_SET_FT_DS,
5940 dut->sta_ft_ds) != 0) {
5941 send_resp(dut, conn, SIGMA_ERROR,
5942 "errorCode,Failed to enable/disable FT_DS");
5943 return STATUS_SENT_ERROR;
5944 }
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03005945 }
5946
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005947 val = get_param(cmd, "Program");
Jouni Malinen1f6ae642018-06-07 23:56:13 +03005948 if (val && (strcasecmp(val, "HS2-R2") == 0 ||
5949 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005950 return cmd_sta_preset_testparameters_hs2_r2(dut, conn, intf,
5951 cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005952
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07005953 if (val && strcasecmp(val, "LOC") == 0)
5954 return loc_cmd_sta_preset_testparameters(dut, conn, cmd);
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02005955 if (val && strcasecmp(val, "60GHZ") == 0) {
5956 val = get_param(cmd, "WPS");
5957 if (val && strcasecmp(val, "disable") == 0) {
5958 dut->wps_disable = 1;
5959 sigma_dut_print(dut, DUT_MSG_INFO, "WPS disabled");
5960 } else {
5961 /* wps_disable can have other value from the previous
5962 * test, so make sure it has the correct value.
5963 */
5964 dut->wps_disable = 0;
5965 }
5966
5967 val = get_param(cmd, "P2P");
5968 if (val && strcasecmp(val, "disable") == 0)
5969 sigma_dut_print(dut, DUT_MSG_INFO, "P2P disabled");
5970 }
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07005971
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02005972 if (dut->program == PROGRAM_WPS && dut->band == WPS_BAND_60G)
5973 return cmd_sta_preset_testparameters_60ghz(dut, conn, cmd);
5974
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005975#ifdef ANDROID_NAN
5976 if (val && strcasecmp(val, "NAN") == 0)
5977 return nan_cmd_sta_preset_testparameters(dut, conn, cmd);
5978#endif /* ANDROID_NAN */
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07005979#ifdef MIRACAST
5980 if (val && (strcasecmp(val, "WFD") == 0 ||
5981 strcasecmp(val, "DisplayR2") == 0))
5982 return miracast_preset_testparameters(dut, conn, cmd);
5983#endif /* MIRACAST */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005984
Kiran Kumar Lokeredd086642020-06-04 00:29:26 -07005985 if (val &&
5986 (strcasecmp(val, "MBO") == 0 || strcasecmp(val, "HE") == 0)) {
Ashwini Patil68d02cd2017-01-10 15:39:16 +05305987 val = get_param(cmd, "Cellular_Data_Cap");
5988 if (val &&
5989 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
5990 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +05305991
5992 val = get_param(cmd, "Ch_Pref");
5993 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
5994 return 0;
5995
Ashwini Patilc63161e2017-04-13 16:30:23 +05305996 val = get_param(cmd, "BSS_Transition");
5997 if (val && mbo_set_bss_trans_req(dut, conn, intf, val) == 0)
5998 return 0;
5999
Ashwini Patila75de5a2017-04-13 16:35:05 +05306000 val = get_param(cmd, "Assoc_Disallow");
6001 if (val && mbo_set_assoc_disallow(dut, conn, intf, val) == 0)
6002 return 0;
6003
Ashwini Patil9183fdb2017-04-13 16:58:25 +05306004 val = get_param(cmd, "Roaming");
6005 if (val && mbo_set_roaming(dut, conn, intf, val) == 0)
6006 return 0;
6007
Ashwini Patil68d02cd2017-01-10 15:39:16 +05306008 return 1;
6009 }
6010
Ankita Bajaja2cb5672017-10-25 16:08:28 +05306011 if (val && strcasecmp(val, "OCE") == 0)
6012 return cmd_sta_preset_testparameters_oce(dut, conn, intf, cmd);
6013
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006014#if 0
6015 val = get_param(cmd, "Supplicant");
6016 if (val && strcasecmp(val, "Default") != 0) {
6017 send_resp(dut, conn, SIGMA_ERROR,
6018 "ErrorCode,Only default(Vendor) supplicant "
6019 "supported");
6020 return 0;
6021 }
6022#endif
6023
6024 val = get_param(cmd, "RTS");
6025 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006026 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006027 case DRIVER_ATHEROS:
6028 ath_sta_set_rts(dut, intf, val);
6029 break;
6030 default:
6031#if 0
6032 send_resp(dut, conn, SIGMA_ERROR,
6033 "ErrorCode,Setting RTS not supported");
6034 return 0;
6035#else
6036 sigma_dut_print(dut, DUT_MSG_DEBUG,
6037 "Setting RTS not supported");
6038 break;
6039#endif
6040 }
6041 }
6042
6043#if 0
6044 val = get_param(cmd, "FRGMNT");
6045 if (val) {
6046 /* TODO */
6047 send_resp(dut, conn, SIGMA_ERROR,
6048 "ErrorCode,Setting FRGMNT not supported");
6049 return 0;
6050 }
6051#endif
6052
6053#if 0
6054 val = get_param(cmd, "Preamble");
6055 if (val) {
6056 /* TODO: Long/Short */
6057 send_resp(dut, conn, SIGMA_ERROR,
6058 "ErrorCode,Setting Preamble not supported");
6059 return 0;
6060 }
6061#endif
6062
6063 val = get_param(cmd, "Mode");
6064 if (val) {
6065 if (strcmp(val, "11b") == 0 ||
6066 strcmp(val, "11g") == 0 ||
6067 strcmp(val, "11a") == 0 ||
6068 strcmp(val, "11n") == 0 ||
6069 strcmp(val, "11ng") == 0 ||
6070 strcmp(val, "11nl") == 0 ||
6071 strcmp(val, "11nl(nabg)") == 0 ||
6072 strcmp(val, "AC") == 0 ||
6073 strcmp(val, "11AC") == 0 ||
6074 strcmp(val, "11ac") == 0 ||
6075 strcmp(val, "11na") == 0 ||
Amarnath Hullur Subramanyamb0db2712018-01-30 19:40:35 -08006076 strcmp(val, "11an") == 0 ||
6077 strcmp(val, "11ax") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006078 /* STA supports all modes by default */
6079 } else {
6080 send_resp(dut, conn, SIGMA_ERROR,
6081 "ErrorCode,Setting Mode not supported");
6082 return 0;
6083 }
Amarnath Hullur Subramanyam97d0e532018-01-31 02:53:02 -08006084
6085 /* Change the mode only in case of testbed for HE program
6086 * and for 11a and 11g modes only. */
6087 if (dut->program == PROGRAM_HE &&
6088 dut->device_type == STA_testbed) {
Vinita S. Maloo13a5cf72020-05-22 14:45:06 +05306089 sta_set_phymode(dut, intf, val);
Amarnath Hullur Subramanyam97d0e532018-01-31 02:53:02 -08006090 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006091 }
6092
6093 val = get_param(cmd, "wmm");
6094 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006095 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006096 case DRIVER_ATHEROS:
6097 ath_sta_set_wmm(dut, intf, val);
6098 break;
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08006099 case DRIVER_WCN:
6100 wcn_sta_set_wmm(dut, intf, val);
6101 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006102 default:
6103 sigma_dut_print(dut, DUT_MSG_DEBUG,
6104 "Setting wmm not supported");
6105 break;
6106 }
6107 }
6108
6109 val = get_param(cmd, "Powersave");
6110 if (val) {
6111 if (strcmp(val, "0") == 0 || strcasecmp(val, "off") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006112 if (get_driver_type(dut) == DRIVER_WCN) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +05306113 if (set_power_save_wcn(dut, intf, 2) < 0)
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08006114 return 0;
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08006115 }
6116
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006117 if (wpa_command(get_station_ifname(dut),
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006118 "P2P_SET ps 0") < 0)
6119 return -2;
6120 /* Make sure test modes are disabled */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006121 wpa_command(get_station_ifname(dut), "P2P_SET ps 98");
6122 wpa_command(get_station_ifname(dut), "P2P_SET ps 96");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006123 } else if (strcmp(val, "1") == 0 ||
6124 strcasecmp(val, "PSPoll") == 0 ||
6125 strcasecmp(val, "on") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006126 if (get_driver_type(dut) == DRIVER_WCN) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +05306127 if (set_power_save_wcn(dut, intf, 1) < 0)
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08006128 return 0;
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08006129 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006130 /* Disable default power save mode */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006131 wpa_command(get_station_ifname(dut), "P2P_SET ps 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006132 /* Enable PS-Poll test mode */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006133 if (wpa_command(get_station_ifname(dut),
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006134 "P2P_SET ps 97") < 0 ||
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006135 wpa_command(get_station_ifname(dut),
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006136 "P2P_SET ps 99") < 0)
6137 return -2;
6138 } else if (strcmp(val, "2") == 0 ||
6139 strcasecmp(val, "Fast") == 0) {
6140 /* TODO */
6141 send_resp(dut, conn, SIGMA_ERROR,
6142 "ErrorCode,Powersave=Fast not supported");
6143 return 0;
6144 } else if (strcmp(val, "3") == 0 ||
6145 strcasecmp(val, "PSNonPoll") == 0) {
6146 /* Make sure test modes are disabled */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006147 wpa_command(get_station_ifname(dut), "P2P_SET ps 98");
6148 wpa_command(get_station_ifname(dut), "P2P_SET ps 96");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006149
6150 /* Enable default power save mode */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006151 if (wpa_command(get_station_ifname(dut),
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006152 "P2P_SET ps 1") < 0)
6153 return -2;
6154 } else
6155 return -1;
6156 }
6157
6158 val = get_param(cmd, "NoAck");
6159 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006160 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006161 case DRIVER_ATHEROS:
6162 ath_sta_set_noack(dut, intf, val);
6163 break;
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08006164#ifdef NL80211_SUPPORT
6165 case DRIVER_WCN:
6166 wcn_sta_set_noack(dut, intf, val);
6167 break;
6168#endif /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006169 default:
6170 send_resp(dut, conn, SIGMA_ERROR,
6171 "ErrorCode,Setting NoAck not supported");
6172 return 0;
6173 }
6174 }
6175
6176 val = get_param(cmd, "IgnoreChswitchProhibit");
6177 if (val) {
6178 /* TODO: Enabled/disabled */
6179 if (strcasecmp(val, "Enabled") == 0) {
6180 send_resp(dut, conn, SIGMA_ERROR,
6181 "ErrorCode,Enabling IgnoreChswitchProhibit "
6182 "not supported");
6183 return 0;
6184 }
6185 }
6186
6187 val = get_param(cmd, "TDLS");
6188 if (val) {
6189 if (strcasecmp(val, "Disabled") == 0) {
6190 if (wpa_command(intf, "SET tdls_disabled 1")) {
6191 send_resp(dut, conn, SIGMA_ERROR,
6192 "ErrorCode,Failed to disable TDLS");
6193 return 0;
6194 }
6195 } else if (strcasecmp(val, "Enabled") == 0) {
6196 if (wpa_command(intf, "SET tdls_disabled 0")) {
6197 send_resp(dut, conn, SIGMA_ERROR,
6198 "ErrorCode,Failed to enable TDLS");
6199 return 0;
6200 }
6201 } else {
6202 send_resp(dut, conn, SIGMA_ERROR,
6203 "ErrorCode,Unsupported TDLS value");
6204 return 0;
6205 }
6206 }
6207
6208 val = get_param(cmd, "TDLSmode");
6209 if (val) {
6210 if (strcasecmp(val, "Default") == 0) {
6211 wpa_command(intf, "SET tdls_testing 0");
6212 } else if (strcasecmp(val, "APProhibit") == 0) {
6213 if (wpa_command(intf, "SET tdls_testing 0x400")) {
6214 send_resp(dut, conn, SIGMA_ERROR,
6215 "ErrorCode,Failed to enable ignore "
6216 "APProhibit TDLS mode");
6217 return 0;
6218 }
6219 } else if (strcasecmp(val, "HiLoMac") == 0) {
6220 /* STA should respond with TDLS setup req for a TDLS
6221 * setup req */
6222 if (wpa_command(intf, "SET tdls_testing 0x80")) {
6223 send_resp(dut, conn, SIGMA_ERROR,
6224 "ErrorCode,Failed to enable HiLoMac "
6225 "TDLS mode");
6226 return 0;
6227 }
6228 } else if (strcasecmp(val, "WeakSecurity") == 0) {
6229 /*
6230 * Since all security modes are enabled by default when
6231 * Sigma control is used, there is no need to do
6232 * anything here.
6233 */
6234 } else if (strcasecmp(val, "ExistLink") == 0) {
6235 /*
6236 * Since we allow new TDLS Setup Request even if there
6237 * is an existing link, nothing needs to be done for
6238 * this.
6239 */
6240 } else {
6241 /* TODO:
6242 * ExistLink: STA should send TDLS setup req even if
6243 * direct link already exists
6244 */
6245 send_resp(dut, conn, SIGMA_ERROR,
6246 "ErrorCode,Unsupported TDLSmode value");
6247 return 0;
6248 }
6249 }
6250
6251 val = get_param(cmd, "FakePubKey");
6252 if (val && atoi(val) && wpa_command(intf, "SET wps_corrupt_pkhash 1")) {
6253 send_resp(dut, conn, SIGMA_ERROR,
6254 "ErrorCode,Failed to enable FakePubKey");
6255 return 0;
6256 }
6257
Amarnath Hullur Subramanyamae1042b2018-02-22 21:52:52 -08006258#ifdef NL80211_SUPPORT
6259 val = get_param(cmd, "FrgmntSupport");
6260 if (val) {
6261 if (strcasecmp(val, "Enable") == 0) {
6262 if (sta_set_he_fragmentation(dut, intf,
6263 HE_FRAG_LEVEL1)) {
6264 send_resp(dut, conn, SIGMA_ERROR,
6265 "ErrorCode,Failed to enable HE Fragmentation");
6266 return 0;
6267 }
6268 } else if (strcasecmp(val, "Disable") == 0) {
6269 if (sta_set_he_fragmentation(dut, intf,
6270 HE_FRAG_DISABLE)) {
6271 send_resp(dut, conn, SIGMA_ERROR,
6272 "ErrorCode,Failed to disable HE Fragmentation");
6273 return 0;
6274 }
6275 }
6276 }
6277#endif /* NL80211_SUPPORT */
6278
Vinita S. Maloo8a4779c2020-06-22 19:32:37 +05306279 val = get_param(cmd, "IncludeMSCSDescriptor");
6280 if (val && strcasecmp(val, "1") == 0) {
6281 char buf[128];
6282 int len;
6283
6284 len = snprintf(buf, sizeof(buf),
Veerendranath Jakkam62cde372020-08-19 18:03:06 +05306285 "MSCS add up_bitmap=F0 up_limit=7 stream_timeout=60000 frame_classifier=045F%032x",
Vinita S. Maloo8a4779c2020-06-22 19:32:37 +05306286 0);
6287
6288 if (len < 0 || len >= sizeof(buf)) {
6289 sigma_dut_print(dut, DUT_MSG_ERROR,
6290 "Failed to build MSCS Descriptor IE");
6291 return ERROR_SEND_STATUS;
6292 }
6293
6294 if (wpa_command(intf, buf) != 0) {
6295 send_resp(dut, conn, SIGMA_ERROR,
6296 "ErrorCode,Failed to include MSCS descriptor");
6297 return STATUS_SENT_ERROR;
6298 }
6299 }
6300
Vinita S. Maloo2287f142021-02-01 16:17:09 +05306301 val = get_param(cmd, "SCSSupport");
6302 if (val) {
6303 char buf[30];
6304 int disable_scs, len;
6305
6306 if (strcasecmp(val, "Enable") == 0) {
6307 disable_scs = 0;
6308 } else if (strcasecmp(val, "Disable") == 0) {
6309 disable_scs = 1;
6310 } else {
6311 sigma_dut_print(dut, DUT_MSG_ERROR,
6312 "Invalid SCSsupport parameter");
6313 return INVALID_SEND_STATUS;
6314 }
6315
Shivani Baranwalebde8f62021-10-19 12:26:02 +05306316 if (disable_scs || dut->prev_disable_scs_support) {
6317 len = snprintf(buf, sizeof(buf),
6318 "SET disable_scs_support %d",
6319 disable_scs);
6320 if (len < 0 || len >= sizeof(buf) ||
6321 wpa_command(intf, buf) != 0) {
6322 send_resp(dut, conn, SIGMA_ERROR,
6323 "ErrorCode,Failed to update SCS support");
6324 return STATUS_SENT_ERROR;
6325 }
6326 dut->prev_disable_scs_support = disable_scs;
Vinita S. Maloo2287f142021-02-01 16:17:09 +05306327 }
6328 }
6329
Vinita S. Maloo83dee552021-04-12 16:47:47 +05306330 val = get_param(cmd, "MSCSSupport");
6331 if (val) {
6332 char buf[30];
6333 int disable_mscs, len;
6334
6335 if (strcasecmp(val, "Enable") == 0) {
6336 disable_mscs = 0;
6337 } else if (strcasecmp(val, "Disable") == 0) {
6338 disable_mscs = 1;
6339 } else {
6340 sigma_dut_print(dut, DUT_MSG_ERROR,
6341 "Invalid MSCSsupport parameter");
6342 return INVALID_SEND_STATUS;
6343 }
6344
Shivani Baranwalebde8f62021-10-19 12:26:02 +05306345 if (disable_mscs || dut->prev_disable_mscs_support) {
6346 len = snprintf(buf, sizeof(buf),
6347 "SET disable_mscs_support %d",
6348 disable_mscs);
6349 if (len < 0 || len >= sizeof(buf) ||
6350 wpa_command(intf, buf) != 0) {
6351 send_resp(dut, conn, SIGMA_ERROR,
6352 "ErrorCode,Failed to update MSCS support");
6353 return STATUS_SENT_ERROR;
6354 }
6355 dut->prev_disable_mscs_support = disable_mscs;
Vinita S. Maloo83dee552021-04-12 16:47:47 +05306356 }
6357 }
6358
Veerendranath Jakkama16cdc82021-09-12 16:44:22 +05306359 val = get_param(cmd, "DSCPPolicyCapability");
6360 if (val) {
6361 char buf[35];
6362 int len;
6363
6364 if (strcasecmp(val, "Enable") == 0) {
6365 len = snprintf(buf, sizeof(buf),
6366 "SET enable_dscp_policy_capa 1");
6367 } else if (strcasecmp(val, "Disable") == 0) {
6368 len = snprintf(buf, sizeof(buf),
6369 "SET enable_dscp_policy_capa 0");
6370 } else {
6371 sigma_dut_print(dut, DUT_MSG_ERROR,
6372 "Invalid DSCP policy parameter");
6373 return INVALID_SEND_STATUS;
6374 }
6375
6376 if (len < 0 || len >= sizeof(buf) ||
6377 wpa_command(intf, buf) != 0) {
6378 send_resp(dut, conn, SIGMA_ERROR,
6379 "ErrorCode,Failed to update DSCP policy capability");
6380 return STATUS_SENT_ERROR;
6381 }
6382 }
6383
6384 val = get_param(cmd, "DSCPPolicyRespParams");
6385 if (val) {
6386 if (strcasecmp(val, "RejectAll") == 0) {
6387 dut->reject_dscp_policies = 1;
6388 dut->dscp_reject_resp_code = DSCP_POLICY_REJECT;
6389 } else if (strcasecmp(val, "AcceptAll") == 0) {
6390 dut->reject_dscp_policies = 0;
6391 }
6392 }
6393
6394 val = get_param(cmd, "DSCPPolicyResp_StatusCode");
6395 if (val)
6396 dut->dscp_reject_resp_code = atoi(val);
6397
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006398 return 1;
6399}
6400
6401
6402static const char * ath_get_radio_name(const char *radio_name)
6403{
6404 if (radio_name == NULL)
6405 return "wifi0";
6406 if (strcmp(radio_name, "wifi1") == 0)
6407 return "wifi1";
6408 if (strcmp(radio_name, "wifi2") == 0)
6409 return "wifi2";
6410 return "wifi0";
6411}
6412
6413
6414static void ath_sta_set_txsp_stream(struct sigma_dut *dut, const char *intf,
6415 const char *val)
6416{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006417 unsigned int vht_mcsmap = 0;
6418 int txchainmask = 0;
6419 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
6420
6421 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
6422 if (dut->testbed_flag_txsp == 1) {
6423 vht_mcsmap = 0xfffc;
6424 dut->testbed_flag_txsp = 0;
6425 } else {
6426 vht_mcsmap = 0xfffe;
6427 }
6428 txchainmask = 1;
6429 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
6430 if (dut->testbed_flag_txsp == 1) {
6431 vht_mcsmap = 0xfff0;
6432 dut->testbed_flag_txsp = 0;
6433 } else {
6434 vht_mcsmap = 0xfffa;
6435 }
6436 txchainmask = 3;
6437 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
6438 if (dut->testbed_flag_txsp == 1) {
6439 vht_mcsmap = 0xffc0;
6440 dut->testbed_flag_txsp = 0;
6441 } else {
6442 vht_mcsmap = 0xffea;
6443 }
6444 txchainmask = 7;
6445 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
6446 if (dut->testbed_flag_txsp == 1) {
6447 vht_mcsmap = 0xff00;
6448 dut->testbed_flag_txsp = 0;
6449 } else {
6450 vht_mcsmap = 0xffaa;
6451 }
6452 txchainmask = 15;
6453 } else {
6454 if (dut->testbed_flag_txsp == 1) {
6455 vht_mcsmap = 0xffc0;
6456 dut->testbed_flag_txsp = 0;
6457 } else {
6458 vht_mcsmap = 0xffea;
6459 }
6460 }
6461
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006462 if (txchainmask)
6463 run_iwpriv(dut, basedev, "txchainmask %d", txchainmask);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006464
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006465 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006466}
6467
6468
6469static void ath_sta_set_rxsp_stream(struct sigma_dut *dut, const char *intf,
6470 const char *val)
6471{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006472 unsigned int vht_mcsmap = 0;
6473 int rxchainmask = 0;
6474 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
6475
6476 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
6477 if (dut->testbed_flag_rxsp == 1) {
6478 vht_mcsmap = 0xfffc;
6479 dut->testbed_flag_rxsp = 0;
6480 } else {
6481 vht_mcsmap = 0xfffe;
6482 }
6483 rxchainmask = 1;
6484 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
6485 if (dut->testbed_flag_rxsp == 1) {
6486 vht_mcsmap = 0xfff0;
6487 dut->testbed_flag_rxsp = 0;
6488 } else {
6489 vht_mcsmap = 0xfffa;
6490 }
6491 rxchainmask = 3;
6492 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
6493 if (dut->testbed_flag_rxsp == 1) {
6494 vht_mcsmap = 0xffc0;
6495 dut->testbed_flag_rxsp = 0;
6496 } else {
6497 vht_mcsmap = 0xffea;
6498 }
6499 rxchainmask = 7;
6500 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
6501 if (dut->testbed_flag_rxsp == 1) {
6502 vht_mcsmap = 0xff00;
6503 dut->testbed_flag_rxsp = 0;
6504 } else {
6505 vht_mcsmap = 0xffaa;
6506 }
6507 rxchainmask = 15;
6508 } else {
6509 if (dut->testbed_flag_rxsp == 1) {
6510 vht_mcsmap = 0xffc0;
6511 dut->testbed_flag_rxsp = 0;
6512 } else {
6513 vht_mcsmap = 0xffea;
6514 }
6515 }
6516
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006517 if (rxchainmask)
6518 run_iwpriv(dut, basedev, "rxchainmask %d", rxchainmask);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006519
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006520 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006521}
6522
6523
6524void ath_set_zero_crc(struct sigma_dut *dut, const char *val)
6525{
6526 if (strcasecmp(val, "enable") == 0) {
6527 if (system("athdiag --set --address=0x2a204 --and=0xbfffffff")
6528 != 0) {
6529 sigma_dut_print(dut, DUT_MSG_ERROR,
6530 "Disable BB_VHTSIGB_CRC_CALC failed");
6531 }
6532
6533 if (system("athdiag --set --address=0x2a204 --or=0x80000000")
6534 != 0) {
6535 sigma_dut_print(dut, DUT_MSG_ERROR,
6536 "Enable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
6537 }
6538 } else {
6539 if (system("athdiag --set --address=0x2a204 --and=0x7fffffff")
6540 != 0) {
6541 sigma_dut_print(dut, DUT_MSG_ERROR,
6542 "Disable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
6543 }
6544
6545 if (system("athdiag --set --address=0x2a204 --or=0x40000000")
6546 != 0) {
6547 sigma_dut_print(dut, DUT_MSG_ERROR,
6548 "Enable BB_VHTSIGB_CRC_CALC failed");
6549 }
6550 }
6551}
6552
6553
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08006554static int wcn_sta_set_width(struct sigma_dut *dut, const char *intf,
6555 const char *val)
6556{
6557 char buf[60];
6558
Shivani Baranwal2a572842021-09-16 12:27:15 +05306559#ifdef NL80211_SUPPORT
6560 enum nl80211_chan_width qca_channel_width;
6561
6562 if (strcmp(val, "20") == 0) {
6563 qca_channel_width = NL80211_CHAN_WIDTH_20;
6564 dut->chwidth = 0;
6565 } else if (strcmp(val, "40") == 0) {
6566 qca_channel_width = NL80211_CHAN_WIDTH_40;
6567 dut->chwidth = 1;
6568 } else if (strcmp(val, "80") == 0) {
6569 qca_channel_width = NL80211_CHAN_WIDTH_80;
6570 dut->chwidth = 2;
6571 } else if (strcmp(val, "160") == 0) {
6572 qca_channel_width = NL80211_CHAN_WIDTH_160;
6573 dut->chwidth = 3;
6574 } else if (strcasecmp(val, "Auto") == 0) {
6575 return 0;
6576 } else {
6577 sigma_dut_print(dut, DUT_MSG_ERROR, "WIDTH %s not supported",
6578 val);
6579 return -1;
6580 }
6581 if (sta_config_params(dut, intf, STA_SET_CHAN_WIDTH,
6582 qca_channel_width) == 0)
6583 return 0;
6584#endif /* NL80211_SUPPORT */
6585
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08006586 if (strcmp(val, "20") == 0) {
6587 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 0", intf);
6588 dut->chwidth = 0;
6589 } else if (strcmp(val, "40") == 0) {
6590 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 1", intf);
6591 dut->chwidth = 1;
6592 } else if (strcmp(val, "80") == 0) {
6593 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 2", intf);
6594 dut->chwidth = 2;
Sunil Duttb1cccac2018-05-22 21:03:12 +05306595 } else if (strcasecmp(val, "Auto") == 0) {
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08006596 buf[0] = '\0';
6597 } else {
6598 sigma_dut_print(dut, DUT_MSG_ERROR, "WIDTH %s not supported",
6599 val);
6600 return -1;
6601 }
6602
6603 if (buf[0] != '\0' && system(buf) != 0) {
6604 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv chwidth failed");
6605 return -1;
6606 }
6607
6608 return 0;
6609}
6610
6611
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006612static int nlvendor_sta_set_addba_reject(struct sigma_dut *dut,
6613 const char *intf, int addbareject)
6614{
6615#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05306616 return wcn_wifi_test_config_set_u8(
6617 dut, intf,
6618 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ACCEPT_ADDBA_REQ,
6619 !addbareject);
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006620#else /* NL80211_SUPPORT */
6621 sigma_dut_print(dut, DUT_MSG_ERROR,
6622 "ADDBA_REJECT cannot be set without NL80211_SUPPORT defined");
6623 return -1;
6624#endif /* NL80211_SUPPORT */
6625}
6626
6627
6628static int sta_set_addba_reject(struct sigma_dut *dut, const char *intf,
6629 int addbareject)
6630{
6631 int ret;
6632
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006633 switch (get_driver_type(dut)) {
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006634 case DRIVER_WCN:
6635 ret = nlvendor_sta_set_addba_reject(dut, intf, addbareject);
6636 if (ret) {
6637 sigma_dut_print(dut, DUT_MSG_ERROR,
6638 "nlvendor_sta_set_addba_reject failed, ret:%d",
6639 ret);
6640 return ret;
6641 }
6642 break;
6643 default:
6644 sigma_dut_print(dut, DUT_MSG_ERROR,
6645 "errorCode,Unsupported ADDBA_REJECT with the current driver");
6646 ret = -1;
6647 break;
6648 }
6649
6650 return ret;
6651}
6652
6653
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08006654static int nlvendor_config_send_addba(struct sigma_dut *dut, const char *intf,
6655 int enable)
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08006656{
6657#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05306658 return wcn_wifi_test_config_set_u8(
6659 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_SEND_ADDBA_REQ,
6660 enable);
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08006661#else /* NL80211_SUPPORT */
6662 sigma_dut_print(dut, DUT_MSG_ERROR,
6663 "Disable addba not possible without NL80211_SUPPORT defined");
6664 return -1;
6665#endif /* NL80211_SUPPORT */
6666}
6667
6668
Veerendranath Jakkamadcd6202019-04-17 12:32:21 +05306669#ifdef NL80211_SUPPORT
6670static int nl80211_sta_set_rts(struct sigma_dut *dut, const char *intf, int val)
6671{
6672 struct nl_msg *msg;
6673 int ret = 0;
6674 int ifindex;
6675
6676 ifindex = if_nametoindex(intf);
6677 if (ifindex == 0) {
6678 sigma_dut_print(dut, DUT_MSG_ERROR,
6679 "%s: Index for interface %s failed",
6680 __func__, intf);
6681 return -1;
6682 }
6683
6684 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6685 NL80211_CMD_SET_WIPHY)) ||
6686 nla_put_u32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD, val)) {
6687 sigma_dut_print(dut, DUT_MSG_ERROR,
6688 "%s: err in adding RTS threshold",
6689 __func__);
6690 nlmsg_free(msg);
6691 return -1;
6692 }
6693
6694 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6695 if (ret) {
6696 sigma_dut_print(dut, DUT_MSG_ERROR,
6697 "%s: err in send_and_recv_msgs, ret=%d",
6698 __func__, ret);
6699 }
6700 return ret;
6701}
6702#endif /* NL80211_SUPPORT */
6703
6704
6705static int sta_set_rts(struct sigma_dut *dut, const char *intf, int val)
6706{
6707 char buf[100];
6708
6709#ifdef NL80211_SUPPORT
6710 if (nl80211_sta_set_rts(dut, intf, val) == 0)
6711 return 0;
6712 sigma_dut_print(dut, DUT_MSG_DEBUG,
6713 "Fall back to using iwconfig for setting RTS threshold");
6714#endif /* NL80211_SUPPORT */
6715
6716 snprintf(buf, sizeof(buf), "iwconfig %s rts %d", intf, val);
6717 if (system(buf) != 0) {
6718 sigma_dut_print(dut, DUT_MSG_ERROR,
6719 "Failed to set RTS threshold %d", val);
6720 return -1;
6721 }
6722 return 0;
6723}
6724
6725
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006726static enum sigma_cmd_result
6727cmd_sta_set_wireless_common(const char *intf, struct sigma_dut *dut,
6728 struct sigma_conn *conn, struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006729{
6730 const char *val;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006731 int ampdu = -1, addbareject = -1;
Jouni Malinen3aa72862019-05-29 23:14:51 +03006732 char buf[128];
6733 int res;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006734
6735 val = get_param(cmd, "40_INTOLERANT");
6736 if (val) {
6737 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
6738 /* TODO: iwpriv ht40intol through wpa_supplicant */
6739 send_resp(dut, conn, SIGMA_ERROR,
6740 "ErrorCode,40_INTOLERANT not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006741 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006742 }
6743 }
6744
6745 val = get_param(cmd, "ADDBA_REJECT");
6746 if (val) {
6747 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
6748 /* reject any ADDBA with status "decline" */
6749 ampdu = 0;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006750 addbareject = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006751 } else {
6752 /* accept ADDBA */
6753 ampdu = 1;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006754 addbareject = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006755 }
6756 }
6757
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006758 if (addbareject >= 0 &&
6759 sta_set_addba_reject(dut, intf, addbareject) < 0) {
6760 send_resp(dut, conn, SIGMA_ERROR,
6761 "ErrorCode,set addba_reject failed");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006762 return STATUS_SENT_ERROR;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006763 }
6764
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006765 val = get_param(cmd, "AMPDU");
6766 if (val) {
6767 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
6768 /* enable AMPDU Aggregation */
6769 if (ampdu == 0) {
6770 send_resp(dut, conn, SIGMA_ERROR,
6771 "ErrorCode,Mismatch in "
6772 "addba_reject/ampdu - "
6773 "not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006774 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006775 }
6776 ampdu = 1;
6777 } else {
6778 /* disable AMPDU Aggregation */
6779 if (ampdu == 1) {
6780 send_resp(dut, conn, SIGMA_ERROR,
6781 "ErrorCode,Mismatch in "
6782 "addba_reject/ampdu - "
6783 "not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006784 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006785 }
6786 ampdu = 0;
6787 }
6788 }
6789
6790 if (ampdu >= 0) {
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08006791 int ret;
6792
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006793 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s A-MPDU aggregation",
6794 ampdu ? "Enabling" : "Disabling");
6795 snprintf(buf, sizeof(buf), "SET ampdu %d", ampdu);
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07006796 if (wpa_command(intf, buf) < 0 &&
6797 iwpriv_sta_set_ampdu(dut, intf, ampdu) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006798 send_resp(dut, conn, SIGMA_ERROR,
6799 "ErrorCode,set aggr failed");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006800 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006801 }
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08006802
6803 if (ampdu == 0) {
6804 /* Disable sending of addba using nl vendor command */
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08006805 ret = nlvendor_config_send_addba(dut, intf, 0);
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08006806 if (ret) {
6807 sigma_dut_print(dut, DUT_MSG_ERROR,
6808 "Failed to disable addba, ret:%d",
6809 ret);
6810 }
6811 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006812 }
6813
6814 val = get_param(cmd, "AMSDU");
6815 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006816 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006817 case DRIVER_ATHEROS:
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08006818 case DRIVER_WCN:
6819 iwpriv_sta_set_amsdu(dut, intf, val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006820 break;
6821 default:
6822 if (strcmp(val, "1") == 0 ||
6823 strcasecmp(val, "Enable") == 0) {
6824 /* Enable AMSDU Aggregation */
6825 send_resp(dut, conn, SIGMA_ERROR,
6826 "ErrorCode,AMSDU aggregation not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006827 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006828 }
6829 break;
6830 }
6831 }
6832
6833 val = get_param(cmd, "STBC_RX");
6834 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006835 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006836 case DRIVER_ATHEROS:
6837 ath_sta_set_stbc(dut, intf, val);
6838 break;
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05306839 case DRIVER_WCN:
6840 wcn_sta_set_stbc(dut, intf, val);
6841 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006842 default:
6843 send_resp(dut, conn, SIGMA_ERROR,
6844 "ErrorCode,STBC_RX not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006845 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006846 }
6847 }
6848
6849 val = get_param(cmd, "WIDTH");
6850 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006851 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006852 case DRIVER_WCN:
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08006853 if (wcn_sta_set_width(dut, intf, val) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006854 send_resp(dut, conn, SIGMA_ERROR,
6855 "ErrorCode,Failed to set WIDTH");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006856 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006857 }
6858 break;
6859 case DRIVER_ATHEROS:
6860 if (ath_set_width(dut, conn, intf, val) < 0)
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006861 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006862 break;
6863 default:
6864 sigma_dut_print(dut, DUT_MSG_ERROR,
6865 "Setting WIDTH not supported");
6866 break;
6867 }
6868 }
6869
6870 val = get_param(cmd, "SMPS");
6871 if (val) {
6872 /* TODO: Dynamic/0, Static/1, No Limit/2 */
6873 send_resp(dut, conn, SIGMA_ERROR,
6874 "ErrorCode,SMPS not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006875 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006876 }
6877
6878 val = get_param(cmd, "TXSP_STREAM");
6879 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006880 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006881 case DRIVER_WCN:
6882 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
6883 send_resp(dut, conn, SIGMA_ERROR,
6884 "ErrorCode,Failed to set TXSP_STREAM");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006885 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006886 }
6887 break;
6888 case DRIVER_ATHEROS:
6889 ath_sta_set_txsp_stream(dut, intf, val);
6890 break;
6891 default:
6892 sigma_dut_print(dut, DUT_MSG_ERROR,
6893 "Setting TXSP_STREAM not supported");
6894 break;
6895 }
6896 }
6897
6898 val = get_param(cmd, "RXSP_STREAM");
6899 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006900 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006901 case DRIVER_WCN:
6902 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
6903 send_resp(dut, conn, SIGMA_ERROR,
6904 "ErrorCode,Failed to set RXSP_STREAM");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006905 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006906 }
6907 break;
6908 case DRIVER_ATHEROS:
6909 ath_sta_set_rxsp_stream(dut, intf, val);
6910 break;
6911 default:
6912 sigma_dut_print(dut, DUT_MSG_ERROR,
6913 "Setting RXSP_STREAM not supported");
6914 break;
6915 }
6916 }
6917
6918 val = get_param(cmd, "DYN_BW_SGNL");
6919 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006920 switch (get_driver_type(dut)) {
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08006921 case DRIVER_WCN:
Peng Xuc59afd32016-11-21 15:01:11 -08006922 if (strcasecmp(val, "enable") == 0) {
6923 snprintf(buf, sizeof(buf),
6924 "iwpriv %s cwmenable 1", intf);
6925 if (system(buf) != 0) {
6926 sigma_dut_print(dut, DUT_MSG_ERROR,
6927 "iwpriv cwmenable 1 failed");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006928 return ERROR_SEND_STATUS;
Peng Xuc59afd32016-11-21 15:01:11 -08006929 }
6930 } else if (strcasecmp(val, "disable") == 0) {
6931 snprintf(buf, sizeof(buf),
6932 "iwpriv %s cwmenable 0", intf);
6933 if (system(buf) != 0) {
6934 sigma_dut_print(dut, DUT_MSG_ERROR,
6935 "iwpriv cwmenable 0 failed");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006936 return ERROR_SEND_STATUS;
Peng Xuc59afd32016-11-21 15:01:11 -08006937 }
6938 } else {
6939 sigma_dut_print(dut, DUT_MSG_ERROR,
6940 "Unsupported DYN_BW_SGL");
6941 }
6942
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006943 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 3", intf);
6944 if (system(buf) != 0) {
6945 sigma_dut_print(dut, DUT_MSG_ERROR,
6946 "Failed to set cts_cbw in DYN_BW_SGNL");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006947 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006948 }
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08006949 break;
6950 case DRIVER_ATHEROS:
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -07006951 novap_reset(dut, intf, 1);
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08006952 ath_config_dyn_bw_sig(dut, intf, val);
6953 break;
6954 default:
6955 sigma_dut_print(dut, DUT_MSG_ERROR,
6956 "Failed to set DYN_BW_SGNL");
6957 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006958 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006959 }
6960
6961 val = get_param(cmd, "RTS_FORCE");
6962 if (val) {
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -07006963 novap_reset(dut, intf, 1);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006964 if (strcasecmp(val, "Enable") == 0) {
Veerendranath Jakkamadcd6202019-04-17 12:32:21 +05306965 if (sta_set_rts(dut, intf, 64) != 0) {
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02006966 sigma_dut_print(dut, DUT_MSG_ERROR,
6967 "Failed to set RTS_FORCE 64");
6968 }
Jouni Malinen3aa72862019-05-29 23:14:51 +03006969 res = snprintf(buf, sizeof(buf),
6970 "wifitool %s beeliner_fw_test 100 1",
6971 intf);
6972 if (res < 0 || res >= sizeof(buf) || system(buf) != 0) {
priyadharshini gowthaman270870e2015-12-09 10:10:23 -08006973 sigma_dut_print(dut, DUT_MSG_ERROR,
6974 "wifitool beeliner_fw_test 100 1 failed");
6975 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006976 } else if (strcasecmp(val, "Disable") == 0) {
Veerendranath Jakkamadcd6202019-04-17 12:32:21 +05306977 if (sta_set_rts(dut, intf, 2347) != 0) {
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02006978 sigma_dut_print(dut, DUT_MSG_ERROR,
6979 "Failed to set RTS_FORCE 2347");
6980 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006981 } else {
6982 send_resp(dut, conn, SIGMA_ERROR,
6983 "ErrorCode,RTS_FORCE value not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006984 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006985 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006986 }
6987
6988 val = get_param(cmd, "CTS_WIDTH");
6989 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006990 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006991 case DRIVER_WCN:
6992 if (wcn_sta_set_cts_width(dut, intf, val) < 0) {
6993 send_resp(dut, conn, SIGMA_ERROR,
6994 "ErrorCode,Failed to set CTS_WIDTH");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006995 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006996 }
6997 break;
6998 case DRIVER_ATHEROS:
6999 ath_set_cts_width(dut, intf, val);
7000 break;
7001 default:
7002 sigma_dut_print(dut, DUT_MSG_ERROR,
7003 "Setting CTS_WIDTH not supported");
7004 break;
7005 }
7006 }
7007
7008 val = get_param(cmd, "BW_SGNL");
7009 if (val) {
7010 if (strcasecmp(val, "Enable") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07007011 run_iwpriv(dut, intf, "cwmenable 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007012 } else if (strcasecmp(val, "Disable") == 0) {
7013 /* TODO: Disable */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007014 } else {
7015 send_resp(dut, conn, SIGMA_ERROR,
7016 "ErrorCode,BW_SGNL value not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03007017 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007018 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007019 }
7020
7021 val = get_param(cmd, "Band");
7022 if (val) {
7023 if (strcmp(val, "2.4") == 0 || strcmp(val, "5") == 0) {
7024 /* STA supports all bands by default */
7025 } else {
7026 send_resp(dut, conn, SIGMA_ERROR,
7027 "ErrorCode,Unsupported Band");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03007028 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007029 }
7030 }
7031
7032 val = get_param(cmd, "zero_crc");
7033 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007034 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007035 case DRIVER_ATHEROS:
7036 ath_set_zero_crc(dut, val);
7037 break;
7038 default:
7039 break;
7040 }
7041 }
7042
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03007043 return SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007044}
7045
7046
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02007047static int sta_set_force_mcs(struct sigma_dut *dut, int force, int mcs)
7048{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007049 switch (get_driver_type(dut)) {
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02007050#ifdef __linux__
7051 case DRIVER_WIL6210:
7052 return wil6210_set_force_mcs(dut, force, mcs);
7053#endif /* __linux__ */
7054 default:
7055 sigma_dut_print(dut, DUT_MSG_ERROR,
7056 "Unsupported sta_set_force_mcs with the current driver");
7057 return -1;
7058 }
7059}
7060
7061
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02007062static int sta_60g_force_rsn_ie(struct sigma_dut *dut, int state)
7063{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007064 switch (get_driver_type(dut)) {
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02007065#ifdef __linux__
7066 case DRIVER_WIL6210:
7067 return wil6210_force_rsn_ie(dut, state);
7068#endif /* __linux__ */
7069 default:
7070 sigma_dut_print(dut, DUT_MSG_ERROR,
7071 "Unsupported sta_60g_force_rsn_ie with the current driver");
7072 return -1;
7073 }
7074}
7075
7076
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007077static int sta_set_60g_common(struct sigma_dut *dut, struct sigma_conn *conn,
7078 struct sigma_cmd *cmd)
7079{
7080 const char *val;
7081 char buf[100];
7082
7083 val = get_param(cmd, "MSDUSize");
7084 if (val) {
7085 int mtu;
7086
7087 dut->amsdu_size = atoi(val);
7088 if (dut->amsdu_size > IEEE80211_MAX_DATA_LEN_DMG ||
7089 dut->amsdu_size < IEEE80211_SNAP_LEN_DMG) {
7090 sigma_dut_print(dut, DUT_MSG_ERROR,
7091 "MSDUSize %d is above max %d or below min %d",
7092 dut->amsdu_size,
7093 IEEE80211_MAX_DATA_LEN_DMG,
7094 IEEE80211_SNAP_LEN_DMG);
7095 dut->amsdu_size = 0;
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007096 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007097 }
7098
7099 mtu = dut->amsdu_size - IEEE80211_SNAP_LEN_DMG;
7100 sigma_dut_print(dut, DUT_MSG_DEBUG,
7101 "Setting amsdu_size to %d", mtu);
7102 snprintf(buf, sizeof(buf), "ifconfig %s mtu %d",
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007103 get_station_ifname(dut), mtu);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007104
7105 if (system(buf) != 0) {
7106 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
7107 buf);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007108 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007109 }
7110 }
7111
7112 val = get_param(cmd, "BAckRcvBuf");
7113 if (val) {
7114 dut->back_rcv_buf = atoi(val);
7115 if (dut->back_rcv_buf == 0) {
7116 sigma_dut_print(dut, DUT_MSG_ERROR,
7117 "Failed to convert %s or value is 0",
7118 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007119 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007120 }
7121
7122 sigma_dut_print(dut, DUT_MSG_DEBUG,
7123 "Setting BAckRcvBuf to %s", val);
7124 }
7125
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02007126 val = get_param(cmd, "MCS_FixedRate");
7127 if (val) {
7128 if (sta_set_force_mcs(dut, 1, atoi(val))) {
7129 sigma_dut_print(dut, DUT_MSG_ERROR,
7130 "Failed to force MCS");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007131 return ERROR_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02007132 }
7133 }
7134
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007135 return SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007136}
7137
7138
7139static int sta_pcp_start(struct sigma_dut *dut, struct sigma_conn *conn,
7140 struct sigma_cmd *cmd)
7141{
7142 int net_id;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007143 const char *ifname;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007144 const char *val;
7145 char buf[100];
7146
7147 dut->mode = SIGMA_MODE_STATION;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007148 ifname = get_main_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007149 if (wpa_command(ifname, "PING") != 0) {
7150 sigma_dut_print(dut, DUT_MSG_ERROR, "Supplicant not running");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007151 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007152 }
7153
7154 wpa_command(ifname, "FLUSH");
7155 net_id = add_network_common(dut, conn, ifname, cmd);
7156 if (net_id < 0) {
7157 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add network");
7158 return net_id;
7159 }
7160
7161 /* TODO: mode=2 for the AP; in the future, replace for mode PCP */
7162 if (set_network(ifname, net_id, "mode", "2") < 0) {
7163 sigma_dut_print(dut, DUT_MSG_ERROR,
7164 "Failed to set supplicant network mode");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007165 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007166 }
7167
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02007168 if (set_network(ifname, net_id, "pbss", "1") < 0)
7169 return -2;
7170
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007171 sigma_dut_print(dut, DUT_MSG_DEBUG,
Alexei Avshalom Lazarfd9f1352018-11-13 14:07:58 +02007172 "Supplicant set network with mode 2. network_id %d",
7173 net_id);
7174
7175 if (set_network(ifname, net_id, "wps_disabled", "0") < 0) {
7176 sigma_dut_print(dut, DUT_MSG_INFO,
7177 "Failed to set supplicant to WPS ENABLE");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007178 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarfd9f1352018-11-13 14:07:58 +02007179 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007180
7181 val = get_param(cmd, "Security");
7182 if (val && strcasecmp(val, "OPEN") == 0) {
7183 dut->ap_key_mgmt = AP_OPEN;
7184 if (set_network(ifname, net_id, "key_mgmt", "NONE") < 0) {
7185 sigma_dut_print(dut, DUT_MSG_ERROR,
7186 "Failed to set supplicant to %s security",
7187 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007188 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007189 }
7190 } else if (val && strcasecmp(val, "WPA2-PSK") == 0) {
7191 dut->ap_key_mgmt = AP_WPA2_PSK;
7192 if (set_network(ifname, net_id, "key_mgmt", "WPA-PSK") < 0) {
7193 sigma_dut_print(dut, DUT_MSG_ERROR,
7194 "Failed to set supplicant to %s security",
7195 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007196 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007197 }
7198
7199 if (set_network(ifname, net_id, "proto", "RSN") < 0) {
7200 sigma_dut_print(dut, DUT_MSG_ERROR,
7201 "Failed to set supplicant to proto RSN");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007202 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007203 }
7204 } else if (val) {
7205 sigma_dut_print(dut, DUT_MSG_ERROR,
7206 "Requested Security %s is not supported on 60GHz",
7207 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007208 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007209 }
7210
7211 val = get_param(cmd, "Encrypt");
7212 if (val && strcasecmp(val, "AES-GCMP") == 0) {
7213 if (set_network(ifname, net_id, "pairwise", "GCMP") < 0) {
7214 sigma_dut_print(dut, DUT_MSG_ERROR,
7215 "Failed to set supplicant to pairwise GCMP");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007216 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007217 }
7218 if (set_network(ifname, net_id, "group", "GCMP") < 0) {
7219 sigma_dut_print(dut, DUT_MSG_ERROR,
7220 "Failed to set supplicant to group GCMP");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007221 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007222 }
7223 } else if (val) {
7224 sigma_dut_print(dut, DUT_MSG_ERROR,
7225 "Requested Encrypt %s is not supported on 60 GHz",
7226 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007227 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007228 }
7229
7230 val = get_param(cmd, "PSK");
7231 if (val && set_network_quoted(ifname, net_id, "psk", val) < 0) {
7232 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set psk %s",
7233 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007234 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007235 }
7236
7237 /* Convert 60G channel to freq */
7238 switch (dut->ap_channel) {
7239 case 1:
7240 val = "58320";
7241 break;
7242 case 2:
7243 val = "60480";
7244 break;
7245 case 3:
7246 val = "62640";
7247 break;
7248 default:
7249 sigma_dut_print(dut, DUT_MSG_ERROR,
7250 "Failed to configure channel %d. Not supported",
7251 dut->ap_channel);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007252 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007253 }
7254
7255 if (set_network(ifname, net_id, "frequency", val) < 0) {
7256 sigma_dut_print(dut, DUT_MSG_ERROR,
7257 "Failed to set supplicant network frequency");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007258 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007259 }
7260
Alexei Avshalom Lazar2eccf4d2019-01-31 10:03:59 +02007261 if (dut->eap_fragment) {
7262 sigma_dut_print(dut, DUT_MSG_DEBUG,
7263 "Set EAP fragment size to 128 bytes.");
7264 if (set_network(ifname, net_id, "fragment_size", "128") < 0)
7265 return ERROR_SEND_STATUS;
7266 }
7267
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007268 sigma_dut_print(dut, DUT_MSG_DEBUG,
7269 "Supplicant set network with frequency");
7270
7271 snprintf(buf, sizeof(buf), "SELECT_NETWORK %d", net_id);
7272 if (wpa_command(ifname, buf) < 0) {
7273 sigma_dut_print(dut, DUT_MSG_INFO,
7274 "Failed to select network id %d on %s",
7275 net_id, ifname);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007276 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007277 }
7278
7279 sigma_dut_print(dut, DUT_MSG_DEBUG, "Selected network");
7280
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007281 return SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007282}
7283
7284
Lior David67543f52017-01-03 19:04:22 +02007285static int wil6210_set_abft_len(struct sigma_dut *dut, int abft_len)
7286{
7287 char buf[128], fname[128];
7288 FILE *f;
Jouni Malinen3aa72862019-05-29 23:14:51 +03007289 int res;
Lior David67543f52017-01-03 19:04:22 +02007290
7291 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
7292 sigma_dut_print(dut, DUT_MSG_ERROR,
7293 "failed to get wil6210 debugfs dir");
7294 return -1;
7295 }
7296
Jouni Malinen3aa72862019-05-29 23:14:51 +03007297 res = snprintf(fname, sizeof(fname), "%s/abft_len", buf);
7298 if (res < 0 || res >= sizeof(fname))
7299 return -1;
Lior David67543f52017-01-03 19:04:22 +02007300 f = fopen(fname, "w");
7301 if (!f) {
7302 sigma_dut_print(dut, DUT_MSG_ERROR,
7303 "failed to open: %s", fname);
7304 return -1;
7305 }
7306
7307 fprintf(f, "%d\n", abft_len);
7308 fclose(f);
7309
7310 return 0;
7311}
7312
7313
Alexei Avshalom Lazar49498b82019-01-31 15:16:32 +02007314int sta_set_60g_abft_len(struct sigma_dut *dut, struct sigma_conn *conn,
7315 int abft_len)
Lior David67543f52017-01-03 19:04:22 +02007316{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007317 switch (get_driver_type(dut)) {
Lior David67543f52017-01-03 19:04:22 +02007318 case DRIVER_WIL6210:
7319 return wil6210_set_abft_len(dut, abft_len);
7320 default:
7321 sigma_dut_print(dut, DUT_MSG_ERROR,
7322 "set abft_len not supported");
7323 return -1;
7324 }
7325}
7326
7327
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007328static int sta_set_60g_pcp(struct sigma_dut *dut, struct sigma_conn *conn,
7329 struct sigma_cmd *cmd)
7330{
7331 const char *val;
Lior David67543f52017-01-03 19:04:22 +02007332 unsigned int abft_len = 1; /* default is one slot */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007333
7334 if (dut->dev_role != DEVROLE_PCP) {
7335 send_resp(dut, conn, SIGMA_INVALID,
7336 "ErrorCode,Invalid DevRole");
7337 return 0;
7338 }
7339
7340 val = get_param(cmd, "SSID");
7341 if (val) {
7342 if (strlen(val) > sizeof(dut->ap_ssid) - 1) {
7343 send_resp(dut, conn, SIGMA_INVALID,
7344 "ErrorCode,Invalid SSID");
7345 return -1;
7346 }
7347
Peng Xub8fc5cc2017-05-10 17:27:28 -07007348 strlcpy(dut->ap_ssid, val, sizeof(dut->ap_ssid));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007349 }
7350
7351 val = get_param(cmd, "CHANNEL");
7352 if (val) {
7353 const char *pos;
7354
7355 dut->ap_channel = atoi(val);
7356 pos = strchr(val, ';');
7357 if (pos) {
7358 pos++;
7359 dut->ap_channel_1 = atoi(pos);
7360 }
7361 }
7362
7363 switch (dut->ap_channel) {
7364 case 1:
7365 case 2:
7366 case 3:
7367 break;
7368 default:
7369 sigma_dut_print(dut, DUT_MSG_ERROR,
7370 "Channel %d is not supported", dut->ap_channel);
7371 send_resp(dut, conn, SIGMA_ERROR,
7372 "Requested channel is not supported");
7373 return -1;
7374 }
7375
7376 val = get_param(cmd, "BCNINT");
7377 if (val)
7378 dut->ap_bcnint = atoi(val);
7379
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007380 val = get_param(cmd, "AllocType");
7381 if (val) {
7382 send_resp(dut, conn, SIGMA_ERROR,
7383 "ErrorCode,AllocType is not supported yet");
7384 return -1;
7385 }
7386
7387 val = get_param(cmd, "PercentBI");
7388 if (val) {
7389 send_resp(dut, conn, SIGMA_ERROR,
7390 "ErrorCode,PercentBI is not supported yet");
7391 return -1;
7392 }
7393
7394 val = get_param(cmd, "CBAPOnly");
7395 if (val) {
7396 send_resp(dut, conn, SIGMA_ERROR,
7397 "ErrorCode,CBAPOnly is not supported yet");
7398 return -1;
7399 }
7400
7401 val = get_param(cmd, "AMPDU");
7402 if (val) {
7403 if (strcasecmp(val, "Enable") == 0)
7404 dut->ap_ampdu = 1;
7405 else if (strcasecmp(val, "Disable") == 0)
7406 dut->ap_ampdu = 2;
7407 else {
7408 send_resp(dut, conn, SIGMA_ERROR,
7409 "ErrorCode,AMPDU value is not Enable nor Disabled");
7410 return -1;
7411 }
7412 }
7413
7414 val = get_param(cmd, "AMSDU");
7415 if (val) {
7416 if (strcasecmp(val, "Enable") == 0)
7417 dut->ap_amsdu = 1;
7418 else if (strcasecmp(val, "Disable") == 0)
7419 dut->ap_amsdu = 2;
7420 }
7421
7422 val = get_param(cmd, "NumMSDU");
7423 if (val) {
7424 send_resp(dut, conn, SIGMA_ERROR,
7425 "ErrorCode, NumMSDU is not supported yet");
7426 return -1;
7427 }
7428
7429 val = get_param(cmd, "ABFTLRang");
7430 if (val) {
7431 sigma_dut_print(dut, DUT_MSG_DEBUG,
Lior David67543f52017-01-03 19:04:22 +02007432 "ABFTLRang parameter %s", val);
7433 if (strcmp(val, "Gt1") == 0)
7434 abft_len = 2; /* 2 slots in this case */
7435 }
7436
7437 if (sta_set_60g_abft_len(dut, conn, abft_len)) {
7438 send_resp(dut, conn, SIGMA_ERROR,
7439 "ErrorCode, Can't set ABFT length");
7440 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007441 }
7442
7443 if (sta_pcp_start(dut, conn, cmd) < 0) {
7444 send_resp(dut, conn, SIGMA_ERROR,
7445 "ErrorCode, Can't start PCP role");
7446 return -1;
7447 }
7448
7449 return sta_set_60g_common(dut, conn, cmd);
7450}
7451
7452
7453static int sta_set_60g_sta(struct sigma_dut *dut, struct sigma_conn *conn,
7454 struct sigma_cmd *cmd)
7455{
7456 const char *val = get_param(cmd, "DiscoveryMode");
7457
7458 if (dut->dev_role != DEVROLE_STA) {
7459 send_resp(dut, conn, SIGMA_INVALID,
7460 "ErrorCode,Invalid DevRole");
7461 return 0;
7462 }
7463
7464 if (val) {
7465 sigma_dut_print(dut, DUT_MSG_DEBUG, "Discovery: %s", val);
7466 /* Ignore Discovery mode till Driver expose API. */
7467#if 0
7468 if (strcasecmp(val, "1") == 0) {
7469 send_resp(dut, conn, SIGMA_INVALID,
7470 "ErrorCode,DiscoveryMode 1 not supported");
7471 return 0;
7472 }
7473
7474 if (strcasecmp(val, "0") == 0) {
7475 /* OK */
7476 } else {
7477 send_resp(dut, conn, SIGMA_INVALID,
7478 "ErrorCode,DiscoveryMode not supported");
7479 return 0;
7480 }
7481#endif
7482 }
7483
7484 if (start_sta_mode(dut) != 0)
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007485 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007486 return sta_set_60g_common(dut, conn, cmd);
7487}
7488
7489
Jouni Malinenf7222712019-06-13 01:50:21 +03007490static enum sigma_cmd_result cmd_sta_disconnect(struct sigma_dut *dut,
7491 struct sigma_conn *conn,
7492 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007493{
7494 const char *intf = get_param(cmd, "Interface");
Jouni Malinened77e672018-01-10 16:45:13 +02007495 const char *val = get_param(cmd, "maintain_profile");
vamsi krishnad605c422017-09-20 14:56:31 +05307496
Jouni Malinened77e672018-01-10 16:45:13 +02007497 if (dut->program == PROGRAM_OCE ||
Amarnath Hullur Subramanyamebeda9e2018-01-31 03:21:48 -08007498 dut->program == PROGRAM_HE ||
Jouni Malinened77e672018-01-10 16:45:13 +02007499 (val && atoi(val) == 1)) {
vamsi krishnad605c422017-09-20 14:56:31 +05307500 wpa_command(intf, "DISCONNECT");
7501 return 1;
7502 }
7503
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007504 disconnect_station(dut);
7505 /* Try to ignore old scan results to avoid HS 2.0R2 test case failures
7506 * due to cached results. */
7507 wpa_command(intf, "SET ignore_old_scan_res 1");
7508 wpa_command(intf, "BSS_FLUSH");
7509 return 1;
7510}
7511
7512
Jouni Malinenf7222712019-06-13 01:50:21 +03007513static enum sigma_cmd_result cmd_sta_reassoc(struct sigma_dut *dut,
7514 struct sigma_conn *conn,
7515 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007516{
7517 const char *intf = get_param(cmd, "Interface");
7518 const char *bssid = get_param(cmd, "bssid");
7519 const char *val = get_param(cmd, "CHANNEL");
Kiran Kumar Lokere94a86b52020-06-03 23:25:19 -07007520 const char *freq_val = get_param(cmd, "ChnlFreq");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007521 struct wpa_ctrl *ctrl;
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05307522 char buf[1000];
Sunil Duttd30ce092018-01-11 23:56:29 +05307523 char result[32];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007524 int res;
7525 int chan = 0;
Kiran Kumar Lokere94a86b52020-06-03 23:25:19 -07007526 int freq = 0;
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007527 enum sigma_cmd_result status = STATUS_SENT;
Sunil Duttd30ce092018-01-11 23:56:29 +05307528 int fastreassoc = 1;
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007529 int ft_ds = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007530
7531 if (bssid == NULL) {
7532 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing bssid "
7533 "argument");
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007534 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007535 }
7536
7537 if (val)
7538 chan = atoi(val);
7539
Kiran Kumar Lokere94a86b52020-06-03 23:25:19 -07007540 if (freq_val)
7541 freq = atoi(freq_val);
7542
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007543 if (wifi_chip_type != DRIVER_WCN && wifi_chip_type != DRIVER_AR6003) {
7544 /* The current network may be from sta_associate or
7545 * sta_hs2_associate
7546 */
7547 if (set_network(intf, dut->infra_network_id, "bssid", bssid) <
7548 0 ||
7549 set_network(intf, 0, "bssid", bssid) < 0)
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007550 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007551 }
7552
7553 ctrl = open_wpa_mon(intf);
7554 if (ctrl == NULL) {
7555 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
7556 "wpa_supplicant monitor connection");
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007557 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007558 }
7559
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007560 if (get_wpa_status(get_station_ifname(dut), "wpa_state", result,
Sunil Duttd30ce092018-01-11 23:56:29 +05307561 sizeof(result)) < 0 ||
7562 strncmp(result, "COMPLETED", 9) != 0) {
7563 sigma_dut_print(dut, DUT_MSG_DEBUG,
7564 "sta_reassoc: Not connected");
7565 fastreassoc = 0;
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007566 } else if (dut->sta_ft_ds) {
7567 sigma_dut_print(dut, DUT_MSG_DEBUG,
7568 "sta_reassoc: Use FT-over-DS");
7569 ft_ds = 1;
Sunil Duttd30ce092018-01-11 23:56:29 +05307570 }
7571
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05307572 if (dut->rsne_override) {
7573#ifdef NL80211_SUPPORT
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007574 if (get_driver_type(dut) == DRIVER_WCN &&
7575 dut->config_rsnie == 0) {
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05307576 sta_config_params(dut, intf, STA_SET_RSNIE, 1);
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05307577 dut->config_rsnie = 1;
7578 }
7579#endif /* NL80211_SUPPORT */
7580 snprintf(buf, sizeof(buf), "TEST_ASSOC_IE %s",
7581 dut->rsne_override);
7582 if (wpa_command(intf, buf) < 0) {
7583 send_resp(dut, conn, SIGMA_ERROR,
7584 "ErrorCode,Failed to set DEV_CONFIGURE_IE RSNE override");
7585 return 0;
7586 }
7587 }
7588
Shivani Baranwal7aa48602021-09-29 10:53:38 +05307589 if (ft_ds && get_driver_type(dut) != DRIVER_WCN) {
Kiran Kumar Lokere94a86b52020-06-03 23:25:19 -07007590 if (chan || freq) {
7591 if (!freq)
7592 freq = channel_to_freq(dut, chan);
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007593 if (!freq) {
7594 sigma_dut_print(dut, DUT_MSG_ERROR,
7595 "Invalid channel number provided: %d",
7596 chan);
7597 send_resp(dut, conn, SIGMA_INVALID,
7598 "ErrorCode,Invalid channel number");
7599 goto close_mon_conn;
7600 }
7601 res = snprintf(buf, sizeof(buf),
7602 "SCAN TYPE=ONLY freq=%d", freq);
7603 } else {
7604 res = snprintf(buf, sizeof(buf), "SCAN TYPE=ONLY");
7605 }
7606 if (res < 0 || res >= (int) sizeof(buf)) {
7607 send_resp(dut, conn, SIGMA_ERROR,
7608 "ErrorCode,snprintf failed");
7609 goto close_mon_conn;
7610 }
7611 if (wpa_command(intf, buf) < 0) {
7612 sigma_dut_print(dut, DUT_MSG_INFO,
7613 "Failed to start scan");
7614 send_resp(dut, conn, SIGMA_ERROR,
7615 "ErrorCode,scan failed");
7616 goto close_mon_conn;
7617 }
7618
7619 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
7620 buf, sizeof(buf));
7621 if (res < 0) {
7622 sigma_dut_print(dut, DUT_MSG_INFO,
7623 "Scan did not complete");
7624 send_resp(dut, conn, SIGMA_ERROR,
7625 "ErrorCode,scan did not complete");
7626 goto close_mon_conn;
7627 }
7628
7629 res = snprintf(buf, sizeof(buf), "FT_DS %s", bssid);
7630 if (res > 0 && res < (int) sizeof(buf))
7631 res = wpa_command(intf, buf);
7632
7633 if (res < 0 || res >= (int) sizeof(buf)) {
7634 send_resp(dut, conn, SIGMA_ERROR,
7635 "errorCode,FT_DS command failed");
7636 status = STATUS_SENT_ERROR;
7637 goto close_mon_conn;
7638 }
7639 } else if (wifi_chip_type == DRIVER_WCN && fastreassoc) {
Kiran Kumar Lokere94a86b52020-06-03 23:25:19 -07007640 if (chan || freq) {
7641 if (!freq)
7642 freq = channel_to_freq(dut, chan);
Ashwini Patil4c8158f2017-05-25 12:49:21 +05307643 if (!freq) {
7644 sigma_dut_print(dut, DUT_MSG_ERROR,
7645 "Invalid channel number provided: %d",
7646 chan);
7647 send_resp(dut, conn, SIGMA_INVALID,
7648 "ErrorCode,Invalid channel number");
7649 goto close_mon_conn;
7650 }
7651 res = snprintf(buf, sizeof(buf),
7652 "SCAN TYPE=ONLY freq=%d", freq);
7653 } else {
7654 res = snprintf(buf, sizeof(buf), "SCAN TYPE=ONLY");
7655 }
7656 if (res < 0 || res >= (int) sizeof(buf)) {
7657 send_resp(dut, conn, SIGMA_ERROR,
7658 "ErrorCode,snprintf failed");
7659 goto close_mon_conn;
7660 }
7661 if (wpa_command(intf, buf) < 0) {
7662 sigma_dut_print(dut, DUT_MSG_INFO,
7663 "Failed to start scan");
7664 send_resp(dut, conn, SIGMA_ERROR,
7665 "ErrorCode,scan failed");
7666 goto close_mon_conn;
7667 }
7668
7669 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
7670 buf, sizeof(buf));
7671 if (res < 0) {
7672 sigma_dut_print(dut, DUT_MSG_INFO,
7673 "Scan did not complete");
7674 send_resp(dut, conn, SIGMA_ERROR,
7675 "ErrorCode,scan did not complete");
7676 goto close_mon_conn;
7677 }
7678
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007679 if (set_network(intf, dut->infra_network_id, "bssid", "any")
7680 < 0) {
7681 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
7682 "bssid to any during FASTREASSOC");
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007683 status = ERROR_SEND_STATUS;
Ashwini Patil467efef2017-05-25 12:18:27 +05307684 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007685 }
Vinita Maloo54b78cf2020-03-30 12:18:19 +05307686 res = snprintf(buf, sizeof(buf), "FASTREASSOC %s %d",
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007687 bssid, chan);
Vinita Maloo54b78cf2020-03-30 12:18:19 +05307688 if (res < 0 || res >= (int) sizeof(buf) ||
7689 wcn_driver_cmd(intf, buf) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007690 send_resp(dut, conn, SIGMA_ERROR,
Vinita Maloo54b78cf2020-03-30 12:18:19 +05307691 "errorCode,Failed to run FASTREASSOC");
Ashwini Patil467efef2017-05-25 12:18:27 +05307692 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007693 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007694 sigma_dut_print(dut, DUT_MSG_INFO,
7695 "sta_reassoc: Run %s successful", buf);
7696 } else if (wpa_command(intf, "REASSOCIATE")) {
7697 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
7698 "request reassociation");
Ashwini Patil467efef2017-05-25 12:18:27 +05307699 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007700 }
7701
7702 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
7703 buf, sizeof(buf));
Ashwini Patil467efef2017-05-25 12:18:27 +05307704 if (res < 0) {
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007705 send_resp(dut, conn, SIGMA_ERROR,
7706 "errorCode,Connection did not complete");
7707 status = STATUS_SENT_ERROR;
Ashwini Patil467efef2017-05-25 12:18:27 +05307708 goto close_mon_conn;
7709 }
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007710 status = SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007711
Ashwini Patil467efef2017-05-25 12:18:27 +05307712close_mon_conn:
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007713 wpa_ctrl_detach(ctrl);
7714 wpa_ctrl_close(ctrl);
Ashwini Patil467efef2017-05-25 12:18:27 +05307715 return status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007716}
7717
7718
7719static void hs2_clear_credentials(const char *intf)
7720{
7721 wpa_command(intf, "REMOVE_CRED all");
7722}
7723
7724
Lior Davidcc88b562017-01-03 18:52:09 +02007725#ifdef __linux__
7726static int wil6210_get_aid(struct sigma_dut *dut, const char *bssid,
7727 unsigned int *aid)
7728{
Lior David0fe101e2017-03-09 16:09:50 +02007729 const char *pattern = "AID[ \t]+([0-9]+)";
Lior Davidcc88b562017-01-03 18:52:09 +02007730
Lior David0fe101e2017-03-09 16:09:50 +02007731 return wil6210_get_sta_info_field(dut, bssid, pattern, aid);
Lior Davidcc88b562017-01-03 18:52:09 +02007732}
7733#endif /* __linux__ */
7734
7735
7736static int sta_get_aid_60g(struct sigma_dut *dut, const char *bssid,
7737 unsigned int *aid)
7738{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007739 switch (get_driver_type(dut)) {
Lior Davidcc88b562017-01-03 18:52:09 +02007740#ifdef __linux__
7741 case DRIVER_WIL6210:
7742 return wil6210_get_aid(dut, bssid, aid);
7743#endif /* __linux__ */
7744 default:
7745 sigma_dut_print(dut, DUT_MSG_ERROR, "get AID not supported");
7746 return -1;
7747 }
7748}
7749
7750
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007751static int sta_get_parameter_60g(struct sigma_dut *dut, struct sigma_conn *conn,
7752 struct sigma_cmd *cmd)
7753{
7754 char buf[MAX_CMD_LEN];
7755 char bss_list[MAX_CMD_LEN];
7756 const char *parameter = get_param(cmd, "Parameter");
7757
7758 if (parameter == NULL)
7759 return -1;
7760
Lior Davidcc88b562017-01-03 18:52:09 +02007761 if (strcasecmp(parameter, "AID") == 0) {
7762 unsigned int aid = 0;
7763 char bssid[20];
7764
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007765 if (get_wpa_status(get_station_ifname(dut), "bssid",
Lior Davidcc88b562017-01-03 18:52:09 +02007766 bssid, sizeof(bssid)) < 0) {
7767 sigma_dut_print(dut, DUT_MSG_ERROR,
7768 "could not get bssid");
7769 return -2;
7770 }
7771
7772 if (sta_get_aid_60g(dut, bssid, &aid))
7773 return -2;
7774
7775 snprintf(buf, sizeof(buf), "aid,%d", aid);
7776 sigma_dut_print(dut, DUT_MSG_INFO, "%s", buf);
7777 send_resp(dut, conn, SIGMA_COMPLETE, buf);
7778 return 0;
7779 }
7780
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007781 if (strcasecmp(parameter, "DiscoveredDevList") == 0) {
7782 char *bss_line;
7783 char *bss_id = NULL;
7784 const char *ifname = get_param(cmd, "Interface");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307785 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007786
7787 if (ifname == NULL) {
7788 sigma_dut_print(dut, DUT_MSG_INFO,
7789 "For get DiscoveredDevList need Interface name.");
7790 return -1;
7791 }
7792
7793 /*
7794 * Use "BSS RANGE=ALL MASK=0x2" which provides a list
7795 * of BSSIDs in "bssid=<BSSID>\n"
7796 */
7797 if (wpa_command_resp(ifname, "BSS RANGE=ALL MASK=0x2",
7798 bss_list,
7799 sizeof(bss_list)) < 0) {
7800 sigma_dut_print(dut, DUT_MSG_ERROR,
7801 "Failed to get bss list");
7802 return -1;
7803 }
7804
7805 sigma_dut_print(dut, DUT_MSG_DEBUG,
7806 "bss list for ifname:%s is:%s",
7807 ifname, bss_list);
7808
7809 snprintf(buf, sizeof(buf), "DeviceList");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307810 bss_line = strtok_r(bss_list, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007811 while (bss_line) {
7812 if (sscanf(bss_line, "bssid=%ms", &bss_id) > 0 &&
7813 bss_id) {
7814 int len;
7815
7816 len = snprintf(buf + strlen(buf),
7817 sizeof(buf) - strlen(buf),
7818 ",%s", bss_id);
7819 free(bss_id);
7820 bss_id = NULL;
7821 if (len < 0) {
7822 sigma_dut_print(dut,
7823 DUT_MSG_ERROR,
7824 "Failed to read BSSID");
7825 send_resp(dut, conn, SIGMA_ERROR,
7826 "ErrorCode,Failed to read BSS ID");
7827 return 0;
7828 }
7829
7830 if ((size_t) len >= sizeof(buf) - strlen(buf)) {
7831 sigma_dut_print(dut,
7832 DUT_MSG_ERROR,
7833 "Response buf too small for list");
7834 send_resp(dut, conn,
7835 SIGMA_ERROR,
7836 "ErrorCode,Response buf too small for list");
7837 return 0;
7838 }
7839 }
7840
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307841 bss_line = strtok_r(NULL, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007842 }
7843
7844 sigma_dut_print(dut, DUT_MSG_INFO, "DiscoveredDevList is %s",
7845 buf);
7846 send_resp(dut, conn, SIGMA_COMPLETE, buf);
7847 return 0;
7848 }
7849
7850 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
7851 return 0;
7852}
7853
7854
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07007855static int sta_get_parameter_he(struct sigma_dut *dut, struct sigma_conn *conn,
7856 struct sigma_cmd *cmd)
7857{
7858 char buf[MAX_CMD_LEN];
7859 const char *parameter = get_param(cmd, "Parameter");
7860
7861 if (!parameter)
7862 return -1;
7863
7864 if (strcasecmp(parameter, "RSSI") == 0) {
7865 char rssi[10];
7866
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007867 if (get_wpa_signal_poll(dut, get_station_ifname(dut), "RSSI",
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07007868 rssi, sizeof(rssi)) < 0) {
7869 sigma_dut_print(dut, DUT_MSG_ERROR,
7870 "Could not get RSSI");
7871 return -2;
7872 }
7873
7874 snprintf(buf, sizeof(buf), "rssi,%s", rssi);
7875 sigma_dut_print(dut, DUT_MSG_INFO, "RSSI %s", buf);
7876 send_resp(dut, conn, SIGMA_COMPLETE, buf);
7877 return 0;
7878 }
7879
7880 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
7881 return 0;
7882}
7883
7884
Veerendranath Jakkamd0ad6ef2020-05-21 17:09:26 +05307885#ifdef NL80211_SUPPORT
7886
7887struct station_info {
7888 uint64_t filled;
7889 uint32_t beacon_mic_error_count;
7890 uint32_t beacon_replay_count;
7891};
7892
7893
7894static int qca_get_sta_info_handler(struct nl_msg *msg, void *arg)
7895{
7896 struct nlattr *tb[NL80211_ATTR_MAX + 1];
7897 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
7898 struct station_info *data = arg;
7899 struct nlattr *info[QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAX + 1];
7900 static struct nla_policy info_policy[
7901 QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAX + 1] = {
7902 [QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_MIC_ERROR_COUNT] = {
7903 .type = NLA_U32
7904 },
7905 [QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT] = {
7906 .type = NLA_U32
7907 },
7908 };
7909
7910 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
7911 genlmsg_attrlen(gnlh, 0), NULL);
7912
7913 if (!tb[NL80211_ATTR_VENDOR_DATA])
7914 return NL_SKIP;
7915
7916 if (nla_parse_nested(info, QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAX,
7917 tb[NL80211_ATTR_VENDOR_DATA], info_policy)) {
7918 return NL_SKIP;
7919 }
7920
7921 if (info[QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_MIC_ERROR_COUNT]) {
7922 data->filled |=
7923 BIT_ULL(QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_MIC_ERROR_COUNT);
7924 data->beacon_mic_error_count =
7925 nla_get_u32(info[QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_MIC_ERROR_COUNT]);
7926 }
7927
7928 if (info[QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT]) {
7929 data->filled |=
7930 BIT_ULL(QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT);
7931 data->beacon_replay_count =
7932 nla_get_u32(info[QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT]);
7933 }
7934
7935 return NL_SKIP;
7936}
7937
7938
7939static int qca_nl80211_get_sta_info(struct sigma_dut *dut, const char *intf,
7940 struct station_info *sta_data)
7941{
7942 struct nl_msg *msg;
7943 int ifindex, ret;
7944
7945 ifindex = if_nametoindex(intf);
7946 if (ifindex == 0) {
7947 sigma_dut_print(dut, DUT_MSG_ERROR,
7948 "%s: Index for interface %s not found",
7949 __func__, intf);
7950 return -1;
7951 }
7952
7953 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7954 NL80211_CMD_VENDOR)) ||
7955 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7956 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7957 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7958 QCA_NL80211_VENDOR_SUBCMD_GET_STA_INFO)) {
7959 sigma_dut_print(dut, DUT_MSG_ERROR,
7960 "%s: err in adding vendor_cmd", __func__);
7961 nlmsg_free(msg);
7962 return -1;
7963 }
7964
7965 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg,
7966 qca_get_sta_info_handler, sta_data);
7967 if (ret) {
7968 sigma_dut_print(dut, DUT_MSG_ERROR,
7969 "%s: err in send_and_recv_msgs, ret=%d",
7970 __func__, ret);
7971 }
7972 return ret;
7973}
7974#endif /* NL80211_SUPPORT */
7975
7976
7977static int get_bip_mic_error_count(struct sigma_dut *dut,
7978 const char *ifname,
7979 unsigned int *count)
7980{
7981#ifdef NL80211_SUPPORT
7982 struct station_info sta_data;
7983#endif /* NL80211_SUPPORT */
7984
7985 if (get_driver_type(dut) != DRIVER_WCN) {
7986 sigma_dut_print(dut, DUT_MSG_ERROR,
7987 "BIP MIC error count not supported");
7988 return -1;
7989 }
7990
7991#ifdef NL80211_SUPPORT
7992 if (qca_nl80211_get_sta_info(dut, ifname, &sta_data) != 0 ||
7993 !(sta_data.filled &
7994 BIT_ULL(QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_MIC_ERROR_COUNT))) {
7995 sigma_dut_print(dut, DUT_MSG_ERROR,
7996 "BIP MIC error count fetching failed");
7997 return -1;
7998 }
7999
8000 *count = sta_data.beacon_mic_error_count;
8001 return 0;
8002#else /* NL80211_SUPPORT */
8003 sigma_dut_print(dut, DUT_MSG_ERROR,
8004 "BIP MIC error count cannot be fetched without NL80211_SUPPORT defined");
8005 return -1;
8006#endif /* NL80211_SUPPORT */
8007}
8008
8009
8010static int get_cmac_replay_count(struct sigma_dut *dut, const char *ifname,
8011 unsigned int *count)
8012{
8013#ifdef NL80211_SUPPORT
8014 struct station_info sta_data;
8015#endif /* NL80211_SUPPORT */
8016
8017 if (get_driver_type(dut) != DRIVER_WCN) {
8018 sigma_dut_print(dut, DUT_MSG_ERROR,
8019 "CMAC reply count not supported");
8020 return -1;
8021 }
8022
8023#ifdef NL80211_SUPPORT
8024 if (qca_nl80211_get_sta_info(dut, ifname, &sta_data) != 0 ||
8025 !(sta_data.filled &
8026 BIT_ULL(QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT))) {
8027 sigma_dut_print(dut, DUT_MSG_ERROR,
8028 "CMAC replay count fetching failed");
8029 return -1;
8030 }
8031
8032 *count = sta_data.beacon_replay_count;
8033 return 0;
8034#else /* NL80211_SUPPORT */
8035 sigma_dut_print(dut, DUT_MSG_ERROR,
8036 "CMAC replay count cannot be fetched without NL80211_SUPPORT defined");
8037 return -1;
8038#endif /* NL80211_SUPPORT */
8039}
8040
8041
8042static enum sigma_cmd_result sta_get_parameter_wpa3(struct sigma_dut *dut,
8043 struct sigma_conn *conn,
8044 struct sigma_cmd *cmd)
8045{
8046 char buf[MAX_CMD_LEN];
8047 const char *ifname = get_param(cmd, "interface");
8048 const char *parameter = get_param(cmd, "Parameter");
8049 unsigned int val;
8050
8051 if (!ifname || !parameter)
8052 return INVALID_SEND_STATUS;
8053
8054 if (strcasecmp(parameter, "BIPMICErrors") == 0) {
8055 if (get_bip_mic_error_count(dut, ifname, &val)) {
8056 send_resp(dut, conn, SIGMA_ERROR,
8057 "ErrorCode,Failed to get BIPMICErrors");
8058 return STATUS_SENT_ERROR;
8059 }
8060 snprintf(buf, sizeof(buf), "BIPMICErrors,%d", val);
8061 sigma_dut_print(dut, DUT_MSG_INFO, "BIPMICErrors %s", buf);
8062 send_resp(dut, conn, SIGMA_COMPLETE, buf);
8063 return STATUS_SENT;
8064 }
8065
8066 if (strcasecmp(parameter, "CMACReplays") == 0) {
8067 if (get_cmac_replay_count(dut, ifname, &val)) {
8068 send_resp(dut, conn, SIGMA_ERROR,
8069 "ErrorCode,Failed to get CMACReplays");
8070 return STATUS_SENT_ERROR;
8071 }
8072 snprintf(buf, sizeof(buf), "CMACReplays,%d", val);
8073 sigma_dut_print(dut, DUT_MSG_INFO, "CMACReplays %s", buf);
8074 send_resp(dut, conn, SIGMA_COMPLETE, buf);
8075 return STATUS_SENT;
8076 }
8077
8078 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
8079 return STATUS_SENT_ERROR;
8080}
8081
8082
Jouni Malinenca0abd32020-02-09 20:18:10 +02008083static enum sigma_cmd_result sta_get_pmk(struct sigma_dut *dut,
8084 struct sigma_conn *conn,
8085 struct sigma_cmd *cmd)
8086{
8087 const char *intf = get_param(cmd, "Interface");
8088 char buf[4096], bssid[20], resp[200], *pos, *tmp;
8089
8090 snprintf(buf, sizeof(buf), "PMKSA_GET %d", dut->infra_network_id);
8091 if (wpa_command_resp(intf, buf, buf, sizeof(buf)) < 0 ||
8092 strncmp(buf, "UNKNOWN COMMAND", 15) == 0) {
8093 send_resp(dut, conn, SIGMA_ERROR,
8094 "ErrorCode,PMKSA_GET not supported");
8095 return STATUS_SENT_ERROR;
8096 }
8097
8098 if (strncmp(buf, "FAIL", 4) == 0 ||
8099 get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0) {
8100 send_resp(dut, conn, SIGMA_ERROR,
8101 "ErrorCode,Could not find current network");
8102 return STATUS_SENT_ERROR;
8103 }
8104
8105 pos = buf;
8106 while (pos) {
8107 if (strncmp(pos, bssid, 17) == 0) {
8108 pos = strchr(pos, ' ');
8109 if (!pos)
Mohammad Asaad Akram956bfc32020-04-08 16:26:18 +05308110 break;
Jouni Malinenca0abd32020-02-09 20:18:10 +02008111 pos++;
8112 pos = strchr(pos, ' ');
8113 if (!pos)
Mohammad Asaad Akram956bfc32020-04-08 16:26:18 +05308114 break;
Jouni Malinenca0abd32020-02-09 20:18:10 +02008115 pos++;
8116 tmp = strchr(pos, ' ');
8117 if (!tmp)
Mohammad Asaad Akram956bfc32020-04-08 16:26:18 +05308118 break;
Jouni Malinenca0abd32020-02-09 20:18:10 +02008119 *tmp = '\0';
8120 break;
8121 }
Jouni Malinenca0abd32020-02-09 20:18:10 +02008122 pos = strchr(pos, '\n');
8123 if (pos)
8124 pos++;
8125 }
8126
8127 if (!pos) {
8128 send_resp(dut, conn, SIGMA_ERROR,
8129 "ErrorCode,PMK not available");
8130 return STATUS_SENT_ERROR;
8131 }
8132
8133 snprintf(resp, sizeof(resp), "PMK,%s", pos);
8134 send_resp(dut, conn, SIGMA_COMPLETE, resp);
8135 return STATUS_SENT;
8136}
8137
8138
Jouni Malinenf7222712019-06-13 01:50:21 +03008139static enum sigma_cmd_result cmd_sta_get_parameter(struct sigma_dut *dut,
8140 struct sigma_conn *conn,
8141 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008142{
8143 const char *program = get_param(cmd, "Program");
Jouni Malinenca0abd32020-02-09 20:18:10 +02008144 const char *parameter = get_param(cmd, "Parameter");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008145
Jouni Malinenca0abd32020-02-09 20:18:10 +02008146 if (!parameter)
8147 return INVALID_SEND_STATUS;
8148
8149 if (strcasecmp(parameter, "PMK") == 0)
8150 return sta_get_pmk(dut, conn, cmd);
8151
8152 if (!program)
8153 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008154
8155 if (strcasecmp(program, "P2PNFC") == 0)
8156 return p2p_cmd_sta_get_parameter(dut, conn, cmd);
8157
8158 if (strcasecmp(program, "60ghz") == 0)
8159 return sta_get_parameter_60g(dut, conn, cmd);
8160
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07008161 if (strcasecmp(program, "he") == 0)
8162 return sta_get_parameter_he(dut, conn, cmd);
8163
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008164#ifdef ANDROID_NAN
8165 if (strcasecmp(program, "NAN") == 0)
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07008166 return nan_cmd_sta_get_parameter(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008167#endif /* ANDROID_NAN */
8168
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07008169#ifdef MIRACAST
8170 if (strcasecmp(program, "WFD") == 0 ||
8171 strcasecmp(program, "DisplayR2") == 0)
8172 return miracast_cmd_sta_get_parameter(dut, conn, cmd);
8173#endif /* MIRACAST */
Veerendranath Jakkamd0ad6ef2020-05-21 17:09:26 +05308174 if (strcasecmp(program, "WPA3") == 0)
8175 return sta_get_parameter_wpa3(dut, conn, cmd);
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07008176
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008177 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
8178 return 0;
8179}
8180
8181
8182static void sta_reset_default_ath(struct sigma_dut *dut, const char *intf,
8183 const char *type)
8184{
8185 char buf[100];
8186
8187 if (dut->program == PROGRAM_VHT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008188 run_iwpriv(dut, intf, "chwidth 2");
8189 run_iwpriv(dut, intf, "mode 11ACVHT80");
8190 run_iwpriv(dut, intf, "vhtmcs -1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008191 }
8192
8193 if (dut->program == PROGRAM_HT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008194 run_iwpriv(dut, intf, "chwidth 0");
8195 run_iwpriv(dut, intf, "mode 11naht40");
8196 run_iwpriv(dut, intf, "set11NRates 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008197 }
8198
8199 if (dut->program == PROGRAM_VHT || dut->program == PROGRAM_HT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008200 run_iwpriv(dut, intf, "powersave 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008201
8202 /* Reset CTS width */
8203 snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 54 0",
8204 intf);
8205 if (system(buf) != 0) {
8206 sigma_dut_print(dut, DUT_MSG_ERROR,
8207 "wifitool %s beeliner_fw_test 54 0 failed",
8208 intf);
8209 }
8210
8211 /* Enable Dynamic Bandwidth signalling by default */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008212 run_iwpriv(dut, intf, "cwmenable 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008213
8214 snprintf(buf, sizeof(buf), "iwconfig %s rts 2347", intf);
8215 if (system(buf) != 0) {
8216 sigma_dut_print(dut, DUT_MSG_ERROR,
8217 "iwpriv rts failed");
8218 }
8219 }
8220
8221 if (type && strcasecmp(type, "Testbed") == 0) {
8222 dut->testbed_flag_txsp = 1;
8223 dut->testbed_flag_rxsp = 1;
8224 /* STA has to set spatial stream to 2 per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008225 run_iwpriv(dut, intf, "vht_mcsmap 0xfff0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008226
8227 /* Disable LDPC per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008228 run_iwpriv(dut, intf, "ldpc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008229
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008230 run_iwpriv(dut, intf, "amsdu 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008231
8232 /* TODO: Disable STBC 2x1 transmit and receive */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008233 run_iwpriv(dut, intf, "tx_stbc 0");
8234 run_iwpriv(dut, intf, "rx_stbc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008235
8236 /* STA has to disable Short GI per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008237 run_iwpriv(dut, intf, "shortgi 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008238 }
8239
8240 if (type && strcasecmp(type, "DUT") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008241 run_iwpriv(dut, intf, "nss 3");
Arif Hussainac6c5112018-05-25 17:34:00 -07008242 dut->sta_nss = 3;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008243
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008244 run_iwpriv(dut, intf, "shortgi 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008245 }
8246}
8247
8248
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08008249#ifdef NL80211_SUPPORT
8250static int sta_set_he_mcs(struct sigma_dut *dut, const char *intf,
8251 enum he_mcs_config mcs)
8252{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308253 return wcn_wifi_test_config_set_u8(
8254 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MCS, mcs);
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08008255}
8256#endif /* NL80211_SUPPORT */
8257
8258
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07008259static int sta_set_action_tx_in_he_tb_ppdu(struct sigma_dut *dut,
8260 const char *intf, int enable)
8261{
8262#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308263 return wcn_wifi_test_config_set_u8(
8264 dut, intf,
8265 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_ACTION_TX_TB_PPDU,
8266 enable);
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07008267#else /* NL80211_SUPPORT */
8268 sigma_dut_print(dut, DUT_MSG_ERROR,
8269 "HE action Tx TB PPDU cannot be set without NL80211_SUPPORT defined");
8270 return -1;
8271#endif /* NL80211_SUPPORT */
8272}
8273
8274
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08008275static int sta_set_heconfig_and_wep_tkip(struct sigma_dut *dut,
8276 const char *intf, int enable)
8277{
8278#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308279 return wcn_wifi_test_config_set_u8(
8280 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WEP_TKIP_IN_HE,
8281 enable);
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08008282#else /* NL80211_SUPPORT */
8283 sigma_dut_print(dut, DUT_MSG_ERROR,
8284 "HE config enablement cannot be changed without NL80211_SUPPORT defined");
8285 return -1;
8286#endif /* NL80211_SUPPORT */
8287}
8288
8289
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08008290#ifdef NL80211_SUPPORT
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08008291
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08008292static int sta_set_he_testbed_def(struct sigma_dut *dut,
8293 const char *intf, int cfg)
8294{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308295 return wcn_wifi_test_config_set_u8(
8296 dut, intf,
8297 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_SET_HE_TESTBED_DEFAULTS,
8298 cfg);
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08008299}
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08008300
8301
8302static int sta_set_2g_vht_supp(struct sigma_dut *dut, const char *intf, int cfg)
8303{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308304 return wcn_wifi_test_config_set_u8(
8305 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_2G_VHT,
8306 cfg);
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08008307}
8308
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08008309#endif /* NL80211_SUPPORT */
8310
8311
Qiwei Caib6806972020-01-15 13:52:11 +08008312int sta_set_addba_buf_size(struct sigma_dut *dut,
8313 const char *intf, int bufsize)
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08008314{
8315#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308316 return wcn_wifi_test_config_set_u16(
8317 dut, intf,
8318 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE, bufsize);
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08008319#else /* NL80211_SUPPORT */
8320 sigma_dut_print(dut, DUT_MSG_ERROR,
8321 "AddBA bufsize cannot be changed without NL80211_SUPPORT defined");
8322 return -1;
8323#endif /* NL80211_SUPPORT */
8324}
8325
8326
Kiran Kumar Lokere69d89952021-08-08 23:41:46 -07008327static int sta_set_scan_unicast_probe(struct sigma_dut *dut,
8328 const char *intf, int val)
8329{
8330#ifdef NL80211_SUPPORT
8331 return wcn_wifi_test_config_set_u8(
8332 dut, intf,
8333 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_USE_BSSID_IN_PROBE_REQ_RA,
8334 val);
8335#else /* NL80211_SUPPORT */
8336 sigma_dut_print(dut, DUT_MSG_ERROR,
8337 "Unicast RA in Probe Request frame cannot be set without NL80211_SUPPORT defined");
8338 return -1;
8339#endif /* NL80211_SUPPORT */
8340}
8341
8342
Kiran Kumar Lokere09dbcef2021-08-09 00:01:41 -07008343static int sta_set_rx_ctrl_multi_bss(struct sigma_dut *dut, const char *intf,
8344 int enable)
8345{
8346#ifdef NL80211_SUPPORT
8347 return wcn_wifi_test_config_set_u8(
8348 dut, intf,
8349 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_RX_CTRL_FRAME_TO_MBSS,
8350 enable);
8351#else /* NL80211_SUPPORT */
8352 sigma_dut_print(dut, DUT_MSG_ERROR,
8353 "Rx ctrl frame to Multi-BSS cannot be changed without NL80211_SUPPORT defined");
8354 return -1;
8355#endif /* NL80211_SUPPORT */
8356}
8357
8358
8359static int sta_set_bcast_twt_support(struct sigma_dut *dut, const char *intf,
8360 int enable)
8361{
8362#ifdef NL80211_SUPPORT
8363 return wcn_wifi_test_config_set_u8(
8364 dut, intf,
8365 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BCAST_TWT_SUPPORT,
8366 enable);
8367#else /* NL80211_SUPPORT */
8368 sigma_dut_print(dut, DUT_MSG_ERROR,
8369 "BCAST TWT cannot be changed without NL80211_SUPPORT defined");
8370 return -1;
8371#endif /* NL80211_SUPPORT */
8372}
8373
8374
Arif Hussain8d5b27b2018-05-14 14:31:03 -07008375static int sta_set_tx_beamformee(struct sigma_dut *dut, const char *intf,
8376 int enable)
8377{
8378#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308379 return wcn_wifi_test_config_set_u8(
8380 dut, intf,
8381 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_TX_BEAMFORMEE,
8382 enable);
Arif Hussain8d5b27b2018-05-14 14:31:03 -07008383#else /* NL80211_SUPPORT */
8384 sigma_dut_print(dut, DUT_MSG_ERROR,
8385 "tx beamformee cannot be changed without NL80211_SUPPORT defined");
8386 return -1;
8387#endif /* NL80211_SUPPORT */
8388}
8389
8390
Arif Hussain9765f7d2018-07-03 08:28:26 -07008391static int sta_set_beamformee_sts(struct sigma_dut *dut, const char *intf,
8392 int val)
8393{
8394#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308395 return wcn_wifi_test_config_set_u8(
8396 dut, intf,
8397 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_BEAMFORMEE_NSTS,
8398 val);
Arif Hussain9765f7d2018-07-03 08:28:26 -07008399#else /* NL80211_SUPPORT */
8400 sigma_dut_print(dut, DUT_MSG_ERROR,
8401 "beamformee sts cannot be changed without NL80211_SUPPORT defined");
8402 return -1;
8403#endif /* NL80211_SUPPORT */
8404}
8405
8406
Arif Hussain68d23f52018-07-11 13:39:08 -07008407#ifdef NL80211_SUPPORT
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07008408static int sta_set_mac_padding_duration(struct sigma_dut *dut, const char *intf,
8409 enum qca_wlan_he_mac_padding_dur val)
8410{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308411 return wcn_wifi_test_config_set_u8(
8412 dut, intf,
8413 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MAC_PADDING_DUR, val);
Arif Hussain68d23f52018-07-11 13:39:08 -07008414}
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07008415#endif /* NL80211_SUPPORT */
Arif Hussain68d23f52018-07-11 13:39:08 -07008416
8417
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07008418static int sta_set_tx_su_ppdu_cfg(struct sigma_dut *dut, const char *intf,
8419 int val)
8420{
8421#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308422 return wcn_wifi_test_config_set_u8(
8423 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_SUPPDU,
8424 val);
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07008425#else /* NL80211_SUPPORT */
8426 sigma_dut_print(dut, DUT_MSG_ERROR,
8427 "Tx SU PPDU cannot be set without NL80211_SUPPORT defined");
8428 return -1;
8429#endif /* NL80211_SUPPORT */
8430}
8431
8432
Kiran Kumar Lokere54b72522021-04-01 00:22:44 -07008433static int sta_set_mgmt_data_tx_disable_cfg(struct sigma_dut *dut,
8434 const char *intf, int val)
8435{
8436#ifdef NL80211_SUPPORT
8437 return wcn_wifi_test_config_set_u8(
8438 dut, intf,
8439 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_DISABLE_DATA_MGMT_RSP_TX,
8440 val);
8441#else /* NL80211_SUPPORT */
8442 sigma_dut_print(dut, DUT_MSG_ERROR,
8443 "Tx disable config cannot be set without NL80211_SUPPORT defined");
8444 return -1;
8445#endif /* NL80211_SUPPORT */
8446}
8447
8448
Kiran Kumar Lokere1809da12021-06-24 00:45:38 -07008449static int sta_set_keep_alive_data_cfg(struct sigma_dut *dut, const char *intf,
8450 int val)
8451{
8452#ifdef NL80211_SUPPORT
8453 return wcn_wifi_test_config_set_u8(
8454 dut, intf,
8455 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_KEEP_ALIVE_FRAME_TYPE,
8456 val);
8457#else /* NL80211_SUPPORT */
8458 sigma_dut_print(dut, DUT_MSG_ERROR,
8459 "Keep alive data type cannot be set without NL80211_SUPPORT defined");
8460 return -1;
8461#endif /* NL80211_SUPPORT */
8462}
8463
8464
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07008465#ifdef NL80211_SUPPORT
8466static int sta_set_he_om_ctrl_reset(struct sigma_dut *dut, const char *intf)
8467{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308468 return wcn_wifi_test_config_set_flag(
8469 dut, intf,
8470 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_CLEAR_HE_OM_CTRL_CONFIG);
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07008471}
8472#endif /* NL80211_SUPPORT */
8473
8474
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07008475static int sta_set_mu_edca_override(struct sigma_dut *dut, const char *intf,
8476 int val)
8477{
8478#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308479 return wcn_wifi_test_config_set_u8(
8480 dut, intf,
8481 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_OVERRIDE_MU_EDCA, val);
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07008482#else /* NL80211_SUPPORT */
8483 sigma_dut_print(dut, DUT_MSG_ERROR,
8484 "MU EDCA override cannot be changed without NL80211_SUPPORT defined");
8485 return -1;
8486#endif /* NL80211_SUPPORT */
8487}
8488
8489
Kiran Kumar Lokerefa7c7b92021-08-09 00:50:55 -07008490static int sta_set_er_su_ppdu_type_tx(struct sigma_dut *dut, const char *intf,
8491 int val)
8492{
8493#ifdef NL80211_SUPPORT
8494 return wcn_wifi_test_config_set_u8(
8495 dut, intf,
8496 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ER_SU_PPDU_TYPE, val);
8497#else /* NL80211_SUPPORT */
8498 sigma_dut_print(dut, DUT_MSG_ERROR,
8499 "ER-SU PPDU type cannot be set without NL80211_SUPPORT defined");
8500 return -1;
8501#endif /* NL80211_SUPPORT */
8502}
8503
8504
8505static int sta_set_ru_242_tone_tx(struct sigma_dut *dut, const char *intf,
8506 int val)
8507{
8508#ifdef NL80211_SUPPORT
8509 return wcn_wifi_test_config_set_u8(
8510 dut, intf,
8511 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_RU_242_TONE_TX, val);
8512#else /* NL80211_SUPPORT */
8513 sigma_dut_print(dut, DUT_MSG_ERROR,
8514 "RU 242 tone cannot be set without NL80211_SUPPORT defined");
8515 return -1;
8516#endif /* NL80211_SUPPORT */
8517}
8518
8519
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07008520static int sta_set_om_ctrl_supp(struct sigma_dut *dut, const char *intf,
8521 int val)
8522{
8523#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308524 return wcn_wifi_test_config_set_u8(
8525 dut, intf,
8526 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OM_CTRL_SUPP, val);
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07008527#else /* NL80211_SUPPORT */
8528 sigma_dut_print(dut, DUT_MSG_ERROR,
8529 "HE OM ctrl cannot be changed without NL80211_SUPPORT defined");
8530 return -1;
8531#endif /* NL80211_SUPPORT */
8532}
8533
8534
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07008535#ifdef NL80211_SUPPORT
8536
8537struct features_info {
8538 unsigned char flags[8];
8539 size_t flags_len;
8540};
8541
8542static int features_info_handler(struct nl_msg *msg, void *arg)
8543{
8544 struct nlattr *tb[NL80211_ATTR_MAX + 1];
8545 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
8546 struct features_info *info = arg;
8547 struct nlattr *nl_vend, *attr;
8548
8549 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
8550 genlmsg_attrlen(gnlh, 0), NULL);
8551
8552 nl_vend = tb[NL80211_ATTR_VENDOR_DATA];
8553 if (nl_vend) {
8554 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_MAX + 1];
8555
8556 nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_MAX,
8557 nla_data(nl_vend), nla_len(nl_vend), NULL);
8558
8559 attr = tb_vendor[QCA_WLAN_VENDOR_ATTR_FEATURE_FLAGS];
8560 if (attr) {
8561 int len = nla_len(attr);
8562
Vamsi Krishna79a91132021-08-16 21:40:22 +05308563 if (info && len <= sizeof(info->flags)) {
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07008564 memcpy(info->flags, nla_data(attr), len);
8565 info->flags_len = len;
8566 }
8567 }
8568 }
8569
8570 return NL_SKIP;
8571}
8572
8573
8574static int check_feature(enum qca_wlan_vendor_features feature,
8575 struct features_info *info)
8576{
8577 size_t idx = feature / 8;
8578
Vamsi Krishna79a91132021-08-16 21:40:22 +05308579 if (!info)
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07008580 return 0;
8581
8582 return (idx < info->flags_len) &&
8583 (info->flags[idx] & BIT(feature % 8));
8584}
8585
8586#endif /* NL80211_SUPPORT */
8587
8588
8589static void sta_get_twt_feature_async_supp(struct sigma_dut *dut,
8590 const char *intf)
8591{
8592#ifdef NL80211_SUPPORT
8593 struct nl_msg *msg;
8594 struct features_info info = { 0 };
8595 int ifindex, ret;
8596
8597 ifindex = if_nametoindex(intf);
8598 if (ifindex == 0) {
8599 sigma_dut_print(dut, DUT_MSG_ERROR,
8600 "%s: Index for interface %s failed",
8601 __func__, intf);
8602 return;
8603 }
8604
8605 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8606 NL80211_CMD_VENDOR)) ||
8607 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
8608 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
8609 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
8610 QCA_NL80211_VENDOR_SUBCMD_GET_FEATURES)) {
8611 sigma_dut_print(dut, DUT_MSG_ERROR,
8612 "%s: err in adding vendor_cmd and vendor_data",
8613 __func__);
8614 nlmsg_free(msg);
8615 return;
8616 }
8617
8618 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, features_info_handler,
8619 &info);
8620 if (ret) {
8621 sigma_dut_print(dut, DUT_MSG_ERROR,
8622 "%s: err in send_and_recv_msgs, ret=%d",
8623 __func__, ret);
8624 return;
8625 }
8626
8627 if (check_feature(QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT, &info))
8628 dut->sta_async_twt_supp = 1;
8629 else
8630 dut->sta_async_twt_supp = 0;
8631
8632 sigma_dut_print(dut, DUT_MSG_DEBUG,
8633 "%s: sta_async_twt_supp %d",
8634 __func__, dut->sta_async_twt_supp);
8635#else /* NL80211_SUPPORT */
8636 sigma_dut_print(dut, DUT_MSG_INFO,
8637 "TWT async supp get cannot be done without NL80211_SUPPORT defined");
8638 dut->sta_async_twt_supp = 0;
8639#endif /* NL80211_SUPPORT */
8640}
8641
8642
Arif Hussain480d5f42019-03-12 14:40:42 -07008643static int sta_set_twt_req_support(struct sigma_dut *dut, const char *intf,
8644 int val)
8645{
8646#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308647 return wcn_wifi_test_config_set_u8(
8648 dut, intf,
8649 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TWT_REQ_SUPPORT, val);
Arif Hussain480d5f42019-03-12 14:40:42 -07008650#else /* NL80211_SUPPORT */
8651 sigma_dut_print(dut, DUT_MSG_ERROR,
8652 "TWT Request cannot be changed without NL80211_SUPPORT defined");
8653 return -1;
8654#endif /* NL80211_SUPPORT */
8655}
8656
8657
Kiran Kumar Lokere4f2d4b02021-04-01 00:07:39 -07008658static int sta_set_bss_max_idle_period(struct sigma_dut *dut, const char *intf,
8659 int val)
8660{
8661#ifdef NL80211_SUPPORT
8662 return wcn_wifi_test_config_set_u16(
8663 dut, intf,
8664 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BSS_MAX_IDLE_PERIOD, val);
8665#else /* NL80211_SUPPORT */
8666 sigma_dut_print(dut, DUT_MSG_ERROR,
8667 "BSS max idle period cannot be set without NL80211_SUPPORT defined");
8668 return -1;
8669#endif /* NL80211_SUPPORT */
8670}
8671
8672
Kiran Kumar Lokere07ad92b2021-08-09 00:27:14 -07008673static int sta_set_bss_max_idle_support(struct sigma_dut *dut, const char *intf,
8674 int val)
8675{
8676#ifdef NL80211_SUPPORT
8677 return wcn_wifi_test_config_set_u8(
8678 dut, intf,
8679 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BSS_MAX_IDLE_PERIOD_ENABLE,
8680 val);
8681#else /* NL80211_SUPPORT */
8682 sigma_dut_print(dut, DUT_MSG_ERROR,
8683 "BSS max idle support cannot be set without NL80211_SUPPORT defined");
8684 return -1;
8685#endif /* NL80211_SUPPORT */
8686}
8687
8688
Srinivas Girigowda0525e292020-11-12 13:28:21 -08008689static int sta_set_fullbw_ulmumimo(struct sigma_dut *dut, const char *intf,
8690 int val)
8691{
8692#ifdef NL80211_SUPPORT
8693 return wcn_wifi_test_config_set_u8(
8694 dut, intf,
8695 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_FULL_BW_UL_MU_MIMO, val);
8696#else /* NL80211_SUPPORT */
8697 sigma_dut_print(dut, DUT_MSG_ERROR,
8698 "Full BW UL MU MIMO cannot be changed without NL80211_SUPPORT defined");
8699 return -1;
8700#endif /* NL80211_SUPPORT */
8701}
8702
8703
Kiran Kumar Lokered0ec5ed2021-04-01 00:15:04 -07008704static int sta_set_punctured_preamble_rx(struct sigma_dut *dut,
8705 const char *intf, int val)
8706{
8707#ifdef NL80211_SUPPORT
8708 return wcn_wifi_test_config_set_u8(
8709 dut, intf,
8710 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_PUNCTURED_PREAMBLE_RX,
8711 val);
8712#else /* NL80211_SUPPORT */
8713 sigma_dut_print(dut, DUT_MSG_ERROR,
8714 "Punctured preamble Rx cannot be set without NL80211_SUPPORT defined");
8715 return -1;
8716#endif /* NL80211_SUPPORT */
8717}
8718
8719
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08008720static void sta_reset_default_wcn(struct sigma_dut *dut, const char *intf,
8721 const char *type)
8722{
8723 char buf[60];
8724
8725 if (dut->program == PROGRAM_HE) {
8726 /* resetting phymode to auto in case of HE program */
Vinita S. Maloo13a5cf72020-05-22 14:45:06 +05308727 sta_set_phymode(dut, intf, "auto");
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08008728
Amarnath Hullur Subramanyam9cecb502018-04-25 13:26:30 -07008729 /* reset the rate to Auto rate */
8730 snprintf(buf, sizeof(buf), "iwpriv %s set_11ax_rate 0xff",
8731 intf);
8732 if (system(buf) != 0) {
8733 sigma_dut_print(dut, DUT_MSG_ERROR,
8734 "iwpriv %s set_11ax_rate 0xff failed",
8735 intf);
8736 }
8737
Kiran Kumar Lokere86cfe3a2018-06-01 11:55:15 -07008738 /* reset the LDPC setting */
8739 snprintf(buf, sizeof(buf), "iwpriv %s ldpc 1", intf);
8740 if (system(buf) != 0) {
8741 sigma_dut_print(dut, DUT_MSG_ERROR,
8742 "iwpriv %s ldpc 1 failed", intf);
8743 }
8744
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08008745 /* reset the power save setting */
Vinita S. Malooa8b62722020-04-23 01:45:41 +05308746 set_power_save_wcn(dut, intf, 2);
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08008747
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08008748 /* remove all network profiles */
8749 remove_wpa_networks(intf);
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08008750
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08008751 /* Configure ADDBA Req/Rsp buffer size to be 64 */
8752 sta_set_addba_buf_size(dut, intf, 64);
8753
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07008754 if (dut->sta_async_twt_supp == -1)
8755 sta_get_twt_feature_async_supp(dut, intf);
8756
Kiran Kumar Lokere69d89952021-08-08 23:41:46 -07008757 sta_set_scan_unicast_probe(dut, intf, 0);
8758
Amarnath Hullur Subramanyam5f32d572018-03-02 00:02:33 -08008759#ifdef NL80211_SUPPORT
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08008760 /* Reset the device HE capabilities to its default supported
8761 * configuration. */
8762 sta_set_he_testbed_def(dut, intf, 0);
8763
Amarnath Hullur Subramanyam5f32d572018-03-02 00:02:33 -08008764 /* Disable noackpolicy for all AC */
8765 if (nlvendor_sta_set_noack(dut, intf, 0, QCA_WLAN_AC_ALL)) {
8766 sigma_dut_print(dut, DUT_MSG_ERROR,
8767 "Disable of noackpolicy for all AC failed");
8768 }
8769#endif /* NL80211_SUPPORT */
8770
Amarnath Hullur Subramanyamb1724a52018-03-07 14:31:46 -08008771 /* Enable WMM by default */
8772 if (wcn_sta_set_wmm(dut, intf, "on")) {
8773 sigma_dut_print(dut, DUT_MSG_ERROR,
8774 "Enable of WMM in sta_reset_default_wcn failed");
8775 }
8776
8777 /* Disable ADDBA_REJECT by default */
8778 if (nlvendor_sta_set_addba_reject(dut, intf, 0)) {
8779 sigma_dut_print(dut, DUT_MSG_ERROR,
8780 "Disable of addba_reject in sta_reset_default_wcn failed");
8781 }
8782
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08008783 /* Enable sending of ADDBA by default */
8784 if (nlvendor_config_send_addba(dut, intf, 1)) {
8785 sigma_dut_print(dut, DUT_MSG_ERROR,
8786 "Enable sending of ADDBA in sta_reset_default_wcn failed");
8787 }
8788
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08008789 /* Enable AMPDU by default */
8790 iwpriv_sta_set_ampdu(dut, intf, 1);
8791
Subhani Shaik8e7a3052018-04-24 14:03:00 -07008792#ifdef NL80211_SUPPORT
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -08008793 if (wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_AUTO)) {
Subhani Shaik8e7a3052018-04-24 14:03:00 -07008794 sigma_dut_print(dut, DUT_MSG_ERROR,
8795 "Set LTF config to default in sta_reset_default_wcn failed");
8796 }
Arif Hussain9765f7d2018-07-03 08:28:26 -07008797
Kiran Kumar Lokerebad51122018-12-12 19:03:36 -08008798 /* set the beamformee NSTS(maximum number of
8799 * space-time streams) to default DUT config
8800 */
8801 if (sta_set_beamformee_sts(dut, intf, 7)) {
Arif Hussain9765f7d2018-07-03 08:28:26 -07008802 sigma_dut_print(dut, DUT_MSG_ERROR,
8803 "Failed to set BeamformeeSTS");
8804 }
Arif Hussain68d23f52018-07-11 13:39:08 -07008805
Kiran Kumar Lokere54b72522021-04-01 00:22:44 -07008806 if (sta_set_mgmt_data_tx_disable_cfg(dut, intf, 0)) {
8807 sigma_dut_print(dut, DUT_MSG_ERROR,
8808 "Failed to reset mgmt/data Tx disable config");
8809 }
8810
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07008811 if (sta_set_mac_padding_duration(
8812 dut, intf,
8813 QCA_WLAN_HE_NO_ADDITIONAL_PROCESS_TIME)) {
Arif Hussain68d23f52018-07-11 13:39:08 -07008814 sigma_dut_print(dut, DUT_MSG_ERROR,
8815 "Failed to set MAC padding duration");
8816 }
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07008817
8818 if (sta_set_mu_edca_override(dut, intf, 0)) {
8819 sigma_dut_print(dut, DUT_MSG_ERROR,
8820 "ErrorCode,Failed to set MU EDCA override disable");
8821 }
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07008822
Kiran Kumar Lokerefa7c7b92021-08-09 00:50:55 -07008823 if (sta_set_ru_242_tone_tx(dut, intf, 0)) {
8824 sigma_dut_print(dut, DUT_MSG_ERROR,
8825 "Failed to set RU 242 tone Tx");
8826 }
8827
8828 if (sta_set_er_su_ppdu_type_tx(dut, intf, 0)) {
8829 sigma_dut_print(dut, DUT_MSG_ERROR,
8830 "Failed to set ER-SU PPDU type Tx");
8831 }
8832
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07008833 if (sta_set_om_ctrl_supp(dut, intf, 1)) {
8834 sigma_dut_print(dut, DUT_MSG_ERROR,
8835 "Failed to set OM ctrl supp");
8836 }
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07008837
8838 if (sta_set_tx_su_ppdu_cfg(dut, intf, 1)) {
8839 sigma_dut_print(dut, DUT_MSG_ERROR,
8840 "Failed to set Tx SU PPDU enable");
8841 }
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07008842
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07008843 if (sta_set_action_tx_in_he_tb_ppdu(dut, intf, 0)) {
8844 sigma_dut_print(dut, DUT_MSG_ERROR,
8845 "failed to send TB PPDU Tx cfg");
8846 }
8847
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07008848 if (sta_set_he_om_ctrl_reset(dut, intf)) {
8849 sigma_dut_print(dut, DUT_MSG_ERROR,
8850 "Failed to set OM ctrl reset");
8851 }
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08008852
8853 /* +HTC-HE support default on */
8854 if (sta_set_he_htc_supp(dut, intf, 1)) {
8855 sigma_dut_print(dut, DUT_MSG_ERROR,
8856 "Setting of +HTC-HE support failed");
8857 }
Subhani Shaik8e7a3052018-04-24 14:03:00 -07008858#endif /* NL80211_SUPPORT */
8859
Arif Hussain8d5b27b2018-05-14 14:31:03 -07008860 if (sta_set_tx_beamformee(dut, intf, 1)) {
8861 sigma_dut_print(dut, DUT_MSG_ERROR,
8862 "Set tx beamformee enable by default in sta_reset_default_wcn failed");
8863 }
8864
Kiran Kumar Lokereb55ff442020-07-15 00:20:40 -07008865 wpa_command(intf, "SET oce 1");
8866
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08008867 /* Set nss to 1 and MCS 0-7 in case of testbed */
8868 if (type && strcasecmp(type, "Testbed") == 0) {
8869#ifdef NL80211_SUPPORT
8870 int ret;
8871#endif /* NL80211_SUPPORT */
8872
Kiran Kumar Lokereb55ff442020-07-15 00:20:40 -07008873 wpa_command(intf, "SET oce 0");
8874
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08008875 snprintf(buf, sizeof(buf), "iwpriv %s nss 1", intf);
8876 if (system(buf) != 0) {
8877 sigma_dut_print(dut, DUT_MSG_ERROR,
8878 "iwpriv %s nss failed", intf);
8879 }
8880
8881#ifdef NL80211_SUPPORT
8882 ret = sta_set_he_mcs(dut, intf, HE_80_MCS0_7);
8883 if (ret) {
8884 sigma_dut_print(dut, DUT_MSG_ERROR,
8885 "Setting of MCS failed, ret:%d",
8886 ret);
8887 }
8888#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyamc67621d2018-02-04 23:18:01 -08008889
8890 /* Disable STBC as default */
8891 wcn_sta_set_stbc(dut, intf, "0");
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08008892
8893 /* Disable AMSDU as default */
8894 iwpriv_sta_set_amsdu(dut, intf, "0");
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08008895
8896#ifdef NL80211_SUPPORT
8897 /* HE fragmentation default off */
8898 if (sta_set_he_fragmentation(dut, intf,
8899 HE_FRAG_DISABLE)) {
8900 sigma_dut_print(dut, DUT_MSG_ERROR,
8901 "Setting of HE fragmentation failed");
8902 }
Kiran Kumar Lokerebad51122018-12-12 19:03:36 -08008903
8904 /* set the beamformee NSTS(maximum number of
8905 * space-time streams) to default testbed config
8906 */
8907 if (sta_set_beamformee_sts(dut, intf, 3)) {
8908 sigma_dut_print(dut, DUT_MSG_ERROR,
8909 "Failed to set BeamformeeSTS");
8910 }
8911
Kiran Kumar Lokered0ec5ed2021-04-01 00:15:04 -07008912 if (sta_set_punctured_preamble_rx(dut, intf, 0)) {
8913 sigma_dut_print(dut, DUT_MSG_ERROR,
8914 "Failed to reset PreamblePunctRx support");
8915 }
8916
Kiran Kumar Lokere727687f2021-06-24 00:35:49 -07008917 if (sta_set_bss_max_idle_period(dut, intf, 0)) {
8918 sigma_dut_print(dut, DUT_MSG_ERROR,
8919 "Failed to reset BSS max idle period");
8920 }
8921
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08008922 /* +HTC-HE support default off */
8923 if (sta_set_he_htc_supp(dut, intf, 0)) {
8924 sigma_dut_print(dut, DUT_MSG_ERROR,
8925 "Setting of +HTC-HE support failed");
8926 }
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08008927
8928 /* Set device HE capabilities to testbed default
8929 * configuration. */
8930 if (sta_set_he_testbed_def(dut, intf, 1)) {
8931 sigma_dut_print(dut, DUT_MSG_DEBUG,
8932 "Failed to set HE defaults");
8933 }
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08008934
8935 /* Disable VHT support in 2.4 GHz for testbed */
8936 sta_set_2g_vht_supp(dut, intf, 0);
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08008937#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08008938
8939 /* Enable WEP/TKIP with HE capability in testbed */
8940 if (sta_set_heconfig_and_wep_tkip(dut, intf, 1)) {
8941 sigma_dut_print(dut, DUT_MSG_ERROR,
8942 "Enabling HE config with WEP/TKIP failed");
8943 }
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08008944 }
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08008945
8946 /* Defaults in case of DUT */
8947 if (type && strcasecmp(type, "DUT") == 0) {
Arif Hussaind48fcc72018-05-01 18:34:18 -07008948 /* Enable STBC by default */
8949 wcn_sta_set_stbc(dut, intf, "1");
8950
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08008951 /* set nss to 2 */
8952 snprintf(buf, sizeof(buf), "iwpriv %s nss 2", intf);
8953 if (system(buf) != 0) {
8954 sigma_dut_print(dut, DUT_MSG_ERROR,
8955 "iwpriv %s nss 2 failed", intf);
8956 }
Arif Hussainac6c5112018-05-25 17:34:00 -07008957 dut->sta_nss = 2;
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08008958
8959#ifdef NL80211_SUPPORT
Arif Hussainae239842018-05-01 18:20:05 -07008960 /* Set HE_MCS to 0-11 */
8961 if (sta_set_he_mcs(dut, intf, HE_80_MCS0_11)) {
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08008962 sigma_dut_print(dut, DUT_MSG_ERROR,
8963 "Setting of MCS failed");
8964 }
8965#endif /* NL80211_SUPPORT */
8966
8967 /* Disable WEP/TKIP with HE capability in DUT */
8968 if (sta_set_heconfig_and_wep_tkip(dut, intf, 0)) {
8969 sigma_dut_print(dut, DUT_MSG_ERROR,
8970 "Enabling HE config with WEP/TKIP failed");
8971 }
8972 }
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08008973 }
8974}
8975
8976
Veerendranath Jakkam47867202020-12-21 01:53:52 +05308977static int sta_set_client_privacy(struct sigma_dut *dut,
8978 struct sigma_conn *conn, const char *intf,
8979 int enable)
8980{
8981 if (enable &&
8982 (wpa_command(intf, "SET mac_addr 1") < 0 ||
8983 wpa_command(intf, "SET rand_addr_lifetime 1") < 0 ||
Veerendranath Jakkam39fd5c42020-12-21 02:02:21 +05308984 (wpa_command(intf, "MAC_RAND_SCAN enable=1 all") < 0 &&
8985 wpa_command(intf, "SET preassoc_mac_addr 1") < 0) ||
Veerendranath Jakkam47867202020-12-21 01:53:52 +05308986 wpa_command(intf, "SET gas_rand_mac_addr 1") < 0 ||
8987 wpa_command(intf, "SET gas_rand_addr_lifetime 1") < 0))
8988 return -1;
8989
8990 if (!enable &&
8991 (wpa_command(intf, "SET mac_addr 0") < 0 ||
Veerendranath Jakkam39fd5c42020-12-21 02:02:21 +05308992 (wpa_command(intf, "MAC_RAND_SCAN enable=0 all") < 0 &&
8993 wpa_command(intf, "SET preassoc_mac_addr 0") < 0) ||
Veerendranath Jakkam47867202020-12-21 01:53:52 +05308994 wpa_command(intf, "SET gas_rand_mac_addr 0") < 0))
8995 return -1;
8996
8997 dut->client_privacy = enable;
8998 return 0;
8999}
9000
9001
Jouni Malinenf7222712019-06-13 01:50:21 +03009002static enum sigma_cmd_result cmd_sta_reset_default(struct sigma_dut *dut,
9003 struct sigma_conn *conn,
9004 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009005{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009006 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02009007 const char *band = get_param(cmd, "band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009008 const char *type;
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07009009 const char *program = get_param(cmd, "program");
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05309010 const char *dev_role = get_param(cmd, "DevRole");
Veerendranath Jakkamc1f71b62021-01-23 03:09:51 +05309011 char resp[20];
Veerendranath Jakkamea7f0692021-08-11 19:13:12 +05309012 char buf[100];
Veerendranath Jakkamc1f71b62021-01-23 03:09:51 +05309013 int ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009014
Jouni Malinenb21f0542019-11-04 17:53:38 +02009015 if (dut->station_ifname_2g &&
9016 strcmp(dut->station_ifname_2g, intf) == 0)
9017 dut->use_5g = 0;
9018 else if (dut->station_ifname_5g &&
9019 strcmp(dut->station_ifname_5g, intf) == 0)
9020 dut->use_5g = 1;
9021
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07009022 if (!program)
9023 program = get_param(cmd, "prog");
9024 dut->program = sigma_program_to_enum(program);
Vinita S. Maloof7a2cbf2020-11-18 19:29:44 +05309025
9026 if (dut->program == PROGRAM_WFD && dut->user_config_timeout)
9027 dut->default_timeout = dut->user_config_timeout;
9028
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009029 dut->device_type = STA_unknown;
9030 type = get_param(cmd, "type");
9031 if (type && strcasecmp(type, "Testbed") == 0)
9032 dut->device_type = STA_testbed;
9033 if (type && strcasecmp(type, "DUT") == 0)
9034 dut->device_type = STA_dut;
9035
9036 if (dut->program == PROGRAM_TDLS) {
9037 /* Clear TDLS testing mode */
9038 wpa_command(intf, "SET tdls_disabled 0");
9039 wpa_command(intf, "SET tdls_testing 0");
9040 dut->no_tpk_expiration = 0;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009041 if (get_driver_type(dut) == DRIVER_WCN) {
Pradeep Reddy POTTETI8ce2a232016-10-28 12:17:32 +05309042 /* Enable the WCN driver in TDLS Explicit trigger mode
9043 */
9044 wpa_command(intf, "SET tdls_external_control 0");
9045 wpa_command(intf, "SET tdls_trigger_control 0");
9046 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009047 }
9048
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07009049#ifdef MIRACAST
9050 if (dut->program == PROGRAM_WFD ||
9051 dut->program == PROGRAM_DISPLAYR2)
9052 miracast_sta_reset_default(dut, conn, cmd);
9053#endif /* MIRACAST */
9054
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009055 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009056 case DRIVER_ATHEROS:
9057 sta_reset_default_ath(dut, intf, type);
9058 break;
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08009059 case DRIVER_WCN:
9060 sta_reset_default_wcn(dut, intf, type);
9061 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009062 default:
9063 break;
9064 }
9065
9066#ifdef ANDROID_NAN
9067 if (dut->program == PROGRAM_NAN)
9068 nan_cmd_sta_reset_default(dut, conn, cmd);
9069#endif /* ANDROID_NAN */
9070
Vinay Gannevaram3b9fdd32019-06-14 17:55:44 +05309071 if (dut->program == PROGRAM_LOC &&
9072 lowi_cmd_sta_reset_default(dut, conn, cmd) < 0)
9073 return ERROR_SEND_STATUS;
9074
Jouni Malinenba630452018-06-22 11:49:59 +03009075 if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009076 unlink("SP/wi-fi.org/pps.xml");
9077 if (system("rm -r SP/*") != 0) {
9078 }
9079 unlink("next-client-cert.pem");
9080 unlink("next-client-key.pem");
9081 }
9082
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02009083 /* For WPS program of the 60 GHz band the band type needs to be saved */
9084 if (dut->program == PROGRAM_WPS) {
9085 if (band && strcasecmp(band, "60GHz") == 0) {
9086 dut->band = WPS_BAND_60G;
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02009087 /* For 60 GHz enable WPS for WPS TCs */
9088 dut->wps_disable = 0;
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02009089 } else {
9090 dut->band = WPS_BAND_NON_60G;
9091 }
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02009092 } else if (dut->program == PROGRAM_60GHZ) {
9093 /* For 60 GHz MAC/PHY TCs WPS must be disabled */
9094 dut->wps_disable = 1;
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02009095 }
9096
Alexei Avshalom Lazar157ba062018-12-23 16:15:26 +02009097 if (is_60g_sigma_dut(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009098 const char *dev_role = get_param(cmd, "DevRole");
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02009099 char buf[256];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009100
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02009101 sigma_dut_print(dut, DUT_MSG_INFO,
9102 "WPS 60 GHz program, wps_disable = %d",
9103 dut->wps_disable);
9104
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009105 if (!dev_role) {
9106 send_resp(dut, conn, SIGMA_ERROR,
9107 "errorCode,Missing DevRole argument");
9108 return 0;
9109 }
9110
9111 if (strcasecmp(dev_role, "STA") == 0)
9112 dut->dev_role = DEVROLE_STA;
9113 else if (strcasecmp(dev_role, "PCP") == 0)
9114 dut->dev_role = DEVROLE_PCP;
9115 else {
9116 send_resp(dut, conn, SIGMA_ERROR,
9117 "errorCode,Unknown DevRole");
9118 return 0;
9119 }
9120
9121 if (dut->device_type == STA_unknown) {
9122 sigma_dut_print(dut, DUT_MSG_ERROR,
9123 "Device type is not STA testbed or DUT");
9124 send_resp(dut, conn, SIGMA_ERROR,
9125 "errorCode,Unknown device type");
9126 return 0;
9127 }
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02009128
9129 sigma_dut_print(dut, DUT_MSG_DEBUG,
9130 "Setting msdu_size to MAX: 7912");
9131 snprintf(buf, sizeof(buf), "ifconfig %s mtu 7912",
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009132 get_station_ifname(dut));
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02009133
9134 if (system(buf) != 0) {
9135 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
9136 buf);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02009137 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02009138 }
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02009139
9140 if (sta_set_force_mcs(dut, 0, 1)) {
9141 sigma_dut_print(dut, DUT_MSG_ERROR,
9142 "Failed to reset force MCS");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02009143 return ERROR_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02009144 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009145 }
9146
9147 wpa_command(intf, "WPS_ER_STOP");
9148 wpa_command(intf, "FLUSH");
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05309149 wpa_command(intf, "ERP_FLUSH");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009150 wpa_command(intf, "SET radio_disabled 0");
9151
Alexei Avshalom Lazar744ae8a2019-01-31 17:26:46 +02009152 dut->wps_forced_version = 0;
9153
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02009154 if (dut->wsc_fragment) {
9155 dut->wsc_fragment = 0;
9156 wpa_command(intf, "SET device_name Test client");
9157 wpa_command(intf, "SET manufacturer ");
9158 wpa_command(intf, "SET model_name ");
9159 wpa_command(intf, "SET model_number ");
9160 wpa_command(intf, "SET serial_number ");
9161 }
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02009162 if (is_60g_sigma_dut(dut) && dut->force_rsn_ie) {
9163 dut->force_rsn_ie = FORCE_RSN_IE_NONE;
9164 sta_60g_force_rsn_ie(dut, FORCE_RSN_IE_NONE);
9165 }
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02009166
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009167 if (dut->tmp_mac_addr && dut->set_macaddr) {
9168 dut->tmp_mac_addr = 0;
9169 if (system(dut->set_macaddr) != 0) {
9170 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to clear "
9171 "temporary MAC address");
9172 }
9173 }
9174
9175 set_ps(intf, dut, 0);
9176
Jouni Malinenba630452018-06-22 11:49:59 +03009177 if (dut->program == PROGRAM_HS2 || dut->program == PROGRAM_HS2_R2 ||
9178 dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009179 wpa_command(intf, "SET interworking 1");
9180 wpa_command(intf, "SET hs20 1");
9181 }
9182
Deepak Dhamdhere0fe0e452017-12-18 14:52:09 -08009183 if (dut->program == PROGRAM_HS2_R2 ||
Jouni Malinenba630452018-06-22 11:49:59 +03009184 dut->program == PROGRAM_HS2_R3 ||
Deepak Dhamdhere0fe0e452017-12-18 14:52:09 -08009185 dut->program == PROGRAM_OCE) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009186 wpa_command(intf, "SET pmf 1");
9187 } else {
9188 wpa_command(intf, "SET pmf 0");
9189 }
9190
9191 hs2_clear_credentials(intf);
9192 wpa_command(intf, "SET hessid 00:00:00:00:00:00");
9193 wpa_command(intf, "SET access_network_type 15");
9194
9195 static_ip_file(0, NULL, NULL, NULL);
9196 kill_dhcp_client(dut, intf);
9197 clear_ip_addr(dut, intf);
9198
9199 dut->er_oper_performed = 0;
9200 dut->er_oper_bssid[0] = '\0';
9201
priyadharshini gowthamanad6cbba2016-10-04 10:39:58 -07009202 if (dut->program == PROGRAM_LOC) {
9203 /* Disable Interworking by default */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009204 wpa_command(get_station_ifname(dut), "SET interworking 0");
priyadharshini gowthamanad6cbba2016-10-04 10:39:58 -07009205 }
9206
Kiran Kumar Lokeredd086642020-06-04 00:29:26 -07009207 if (dut->program == PROGRAM_MBO || dut->program == PROGRAM_HE) {
Ashwini Patil00402582017-04-13 12:29:39 +05309208 free(dut->non_pref_ch_list);
9209 dut->non_pref_ch_list = NULL;
Ashwini Patil5acd7382017-04-13 15:55:04 +05309210 free(dut->btm_query_cand_list);
9211 dut->btm_query_cand_list = NULL;
Ashwini Patilc63161e2017-04-13 16:30:23 +05309212 wpa_command(intf, "SET reject_btm_req_reason 0");
Ashwini Patila75de5a2017-04-13 16:35:05 +05309213 wpa_command(intf, "SET ignore_assoc_disallow 0");
Ashwini Patild174f2c2017-04-13 16:49:46 +05309214 wpa_command(intf, "SET gas_address3 0");
Ashwini Patil9183fdb2017-04-13 16:58:25 +05309215 wpa_command(intf, "SET roaming 1");
Ankita Bajaj1d974552018-09-18 16:56:44 +05309216 wpa_command(intf, "SET interworking 1");
Ashwini Patil00402582017-04-13 12:29:39 +05309217 }
9218
Jouni Malinen3c367e82017-06-23 17:01:47 +03009219 free(dut->rsne_override);
9220 dut->rsne_override = NULL;
9221
Jouni Malinen68143132017-09-02 02:34:08 +03009222 free(dut->sae_commit_override);
9223 dut->sae_commit_override = NULL;
Jouni Malinen4b3769d2019-10-10 16:20:29 +03009224 wpa_command(intf, "SET sae_pmkid_in_assoc 0");
Jouni Malinen11e55212019-11-22 21:46:59 +02009225 dut->sae_pwe = SAE_PWE_DEFAULT;
Jouni Malinen68143132017-09-02 02:34:08 +03009226
Jouni Malinen134fe3c2019-06-12 04:16:49 +03009227 dut->sta_associate_wait_connect = 0;
9228 dut->server_cert_hash[0] = '\0';
Jouni Malinen37d5c692019-08-19 16:56:55 +03009229 dut->server_cert_tod = 0;
Jouni Malinen134fe3c2019-06-12 04:16:49 +03009230 dut->sta_tod_policy = 0;
9231
Jouni Malinend86e5822017-08-29 03:55:32 +03009232 dut->dpp_conf_id = -1;
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02009233 free(dut->dpp_peer_uri);
9234 dut->dpp_peer_uri = NULL;
Jouni Malinen63d50412017-11-24 11:55:38 +02009235 dut->dpp_local_bootstrap = -1;
Jouni Malinen5011fb52017-12-05 21:00:15 +02009236 wpa_command(intf, "SET dpp_config_processing 2");
Jouni Malinen90776b12020-05-04 15:34:46 +03009237 wpa_command(intf, "SET dpp_mud_url ");
Jouni Malinend86e5822017-08-29 03:55:32 +03009238
Jouni Malinenfac9cad2017-10-10 18:35:55 +03009239 wpa_command(intf, "VENDOR_ELEM_REMOVE 13 *");
9240
vamsi krishnaa2799492017-12-05 14:28:01 +05309241 if (dut->program == PROGRAM_OCE) {
Ankita Bajaja2cb5672017-10-25 16:08:28 +05309242 wpa_command(intf, "SET oce 1");
vamsi krishnaa2799492017-12-05 14:28:01 +05309243 wpa_command(intf, "SET disable_fils 0");
Ankita Bajaj1bde7942018-01-09 19:15:01 +05309244 wpa_command(intf, "FILS_HLP_REQ_FLUSH");
9245 dut->fils_hlp = 0;
9246#ifdef ANDROID
9247 hlp_thread_cleanup(dut);
9248#endif /* ANDROID */
vamsi krishnaa2799492017-12-05 14:28:01 +05309249 }
Ankita Bajaja2cb5672017-10-25 16:08:28 +05309250
Veerendranath Jakkamea7f0692021-08-11 19:13:12 +05309251 if (dut->program == PROGRAM_QM) {
Vamsi Krishnaf642d6a2020-03-27 12:33:14 +05309252 wpa_command(intf, "SET interworking 1");
Veerendranath Jakkama16cdc82021-09-12 16:44:22 +05309253 wpa_command(intf, "SET enable_dscp_policy_capa 1");
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +05309254 dut->qm_domain_name[0] = '\0';
Veerendranath Jakkama16cdc82021-09-12 16:44:22 +05309255 dut->reject_dscp_policies = 0;
Veerendranath Jakkam1bf1bd62021-09-12 16:35:55 +05309256 dut->num_dscp_status = 0;
Veerendranath Jakkamea7f0692021-08-11 19:13:12 +05309257 snprintf(buf, sizeof(buf),
9258 "ip -6 route replace fe80::/64 dev %s table local",
9259 intf);
9260 if (system(buf) != 0)
9261 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to run: %s",
9262 buf);
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05309263
9264 stop_dscp_policy_mon_thread(dut);
9265 clear_all_dscp_policies(dut);
Veerendranath Jakkamea7f0692021-08-11 19:13:12 +05309266 }
Vamsi Krishnaf642d6a2020-03-27 12:33:14 +05309267
Jouni Malinen8179fee2019-03-28 03:19:47 +02009268 dut->akm_values = 0;
Shivani Baranwal7aa48602021-09-29 10:53:38 +05309269
9270#ifdef NL80211_SUPPORT
9271 if (get_driver_type(dut) == DRIVER_WCN)
9272 sta_config_params(dut, intf, STA_SET_FT_DS, 0);
9273#endif /* NL80211_SUPPORT */
9274
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03009275 dut->sta_ft_ds = 0;
Jouni Malinen8179fee2019-03-28 03:19:47 +02009276
Sunil Dutt076081f2018-02-05 19:45:50 +05309277#ifdef NL80211_SUPPORT
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009278 if (get_driver_type(dut) == DRIVER_WCN &&
Sunil Dutt44595082018-02-12 19:41:45 +05309279 dut->config_rsnie == 1) {
9280 dut->config_rsnie = 0;
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05309281 sta_config_params(dut, intf, STA_SET_RSNIE, 0);
Sunil Dutt076081f2018-02-05 19:45:50 +05309282 }
9283#endif /* NL80211_SUPPORT */
9284
Sunil Duttfebf8a82018-02-09 18:50:13 +05309285 if (dev_role && strcasecmp(dev_role, "STA-CFON") == 0) {
9286 dut->dev_role = DEVROLE_STA_CFON;
9287 return sta_cfon_reset_default(dut, conn, cmd);
9288 }
9289
Jouni Malinen439352d2018-09-13 03:42:23 +03009290 wpa_command(intf, "SET setband AUTO");
9291
Veerendranath Jakkamc1f71b62021-01-23 03:09:51 +05309292 ret = wpa_command_resp(intf, "GET_CAPABILITY ocv", resp, sizeof(resp));
9293 dut->ocvc = ret == 0 && strncmp(resp, "supported", 9) == 0;
9294
9295 ret = wpa_command_resp(intf, "GET_CAPABILITY beacon_prot", resp,
9296 sizeof(resp));
9297 dut->beacon_prot = ret == 0 && strncmp(resp, "supported", 9) == 0;
9298
Veerendranath Jakkam47867202020-12-21 01:53:52 +05309299 if (sta_set_client_privacy(dut, conn, intf,
9300 dut->program == PROGRAM_WPA3 &&
9301 dut->device_type == STA_dut &&
9302 dut->client_privacy_default)) {
9303 sigma_dut_print(dut, DUT_MSG_ERROR,
9304 "Failed to set client privacy functionality");
9305 /* sta_reset_default command is not really supposed to fail,
9306 * so allow this to continue. */
9307 }
9308
Veerendranath Jakkamca239592021-10-11 20:48:00 +05309309 if (get_driver_type(dut) == DRIVER_WCN)
9310 wcn_set_ignore_h2e_rsnxe(dut, intf, 0);
9311
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +05309312 dut->saquery_oci_freq = 0;
Shivani Baranwalebde8f62021-10-19 12:26:02 +05309313 dut->prev_disable_scs_support = 0;
9314 dut->prev_disable_mscs_support = 0;
Vamsi Krishnac1633d22020-05-06 18:31:21 +05309315
Sunil Duttfebf8a82018-02-09 18:50:13 +05309316 if (dut->program != PROGRAM_VHT)
9317 return cmd_sta_p2p_reset(dut, conn, cmd);
9318
Priyadharshini Gowthamana7dfd492015-11-09 14:34:08 -08009319 return 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009320}
9321
9322
Jouni Malinenf7222712019-06-13 01:50:21 +03009323static enum sigma_cmd_result cmd_sta_get_events(struct sigma_dut *dut,
9324 struct sigma_conn *conn,
9325 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009326{
9327 const char *program = get_param(cmd, "Program");
9328
9329 if (program == NULL)
9330 return -1;
9331#ifdef ANDROID_NAN
9332 if (strcasecmp(program, "NAN") == 0)
9333 return nan_cmd_sta_get_events(dut, conn, cmd);
9334#endif /* ANDROID_NAN */
9335 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
9336 return 0;
9337}
9338
9339
Jouni Malinen82905202018-04-29 17:20:10 +03009340static int sta_exec_action_url(struct sigma_dut *dut, struct sigma_conn *conn,
9341 struct sigma_cmd *cmd)
9342{
9343 const char *url = get_param(cmd, "url");
9344 const char *method = get_param(cmd, "method");
9345 pid_t pid;
9346 int status;
9347
9348 if (!url || !method)
9349 return -1;
9350
9351 /* TODO: Add support for method,post */
9352 if (strcasecmp(method, "get") != 0) {
9353 send_resp(dut, conn, SIGMA_ERROR,
9354 "ErrorCode,Unsupported method");
9355 return 0;
9356 }
9357
9358 pid = fork();
9359 if (pid < 0) {
9360 perror("fork");
9361 return -1;
9362 }
9363
9364 if (pid == 0) {
9365 char * argv[5] = { "wget", "-O", "/dev/null",
9366 (char *) url, NULL };
9367
9368 execv("/usr/bin/wget", argv);
9369 perror("execv");
9370 exit(0);
9371 return -1;
9372 }
9373
9374 if (waitpid(pid, &status, 0) < 0) {
9375 perror("waitpid");
9376 return -1;
9377 }
9378
9379 if (WIFEXITED(status)) {
9380 const char *errmsg;
9381
9382 if (WEXITSTATUS(status) == 0)
9383 return 1;
9384 sigma_dut_print(dut, DUT_MSG_INFO, "wget exit status %d",
9385 WEXITSTATUS(status));
9386 switch (WEXITSTATUS(status)) {
9387 case 4:
9388 errmsg = "errmsg,Network failure";
9389 break;
9390 case 8:
9391 errmsg = "errmsg,Server issued an error response";
9392 break;
9393 default:
9394 errmsg = "errmsg,Unknown failure from wget";
9395 break;
9396 }
9397 send_resp(dut, conn, SIGMA_ERROR, errmsg);
9398 return 0;
9399 }
9400
9401 send_resp(dut, conn, SIGMA_ERROR, "errmsg,Unknown failure");
9402 return 0;
9403}
9404
9405
Jouni Malinenf7222712019-06-13 01:50:21 +03009406static enum sigma_cmd_result cmd_sta_exec_action(struct sigma_dut *dut,
9407 struct sigma_conn *conn,
9408 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009409{
9410 const char *program = get_param(cmd, "Prog");
9411
Jouni Malinen82905202018-04-29 17:20:10 +03009412 if (program && !get_param(cmd, "interface"))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009413 return -1;
9414#ifdef ANDROID_NAN
Jouni Malinen82905202018-04-29 17:20:10 +03009415 if (program && strcasecmp(program, "NAN") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009416 return nan_cmd_sta_exec_action(dut, conn, cmd);
9417#endif /* ANDROID_NAN */
Jouni Malinen82905202018-04-29 17:20:10 +03009418
9419 if (program && strcasecmp(program, "Loc") == 0)
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07009420 return loc_cmd_sta_exec_action(dut, conn, cmd);
Jouni Malinen82905202018-04-29 17:20:10 +03009421
9422 if (get_param(cmd, "url"))
9423 return sta_exec_action_url(dut, conn, cmd);
9424
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009425 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
9426 return 0;
9427}
9428
9429
Jouni Malinenf7222712019-06-13 01:50:21 +03009430static enum sigma_cmd_result cmd_sta_set_11n(struct sigma_dut *dut,
9431 struct sigma_conn *conn,
9432 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009433{
9434 const char *intf = get_param(cmd, "Interface");
9435 const char *val, *mcs32, *rate;
9436
9437 val = get_param(cmd, "GREENFIELD");
9438 if (val) {
9439 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
9440 /* Enable GD */
9441 send_resp(dut, conn, SIGMA_ERROR,
9442 "ErrorCode,GF not supported");
9443 return 0;
9444 }
9445 }
9446
9447 val = get_param(cmd, "SGI20");
9448 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009449 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009450 case DRIVER_ATHEROS:
9451 ath_sta_set_sgi(dut, intf, val);
9452 break;
9453 default:
9454 send_resp(dut, conn, SIGMA_ERROR,
9455 "ErrorCode,SGI20 not supported");
9456 return 0;
9457 }
9458 }
9459
9460 mcs32 = get_param(cmd, "MCS32"); /* HT Duplicate Mode Enable/Disable */
9461 rate = get_param(cmd, "MCS_FIXEDRATE"); /* Fixed MCS rate (0..31) */
9462 if (mcs32 && rate) {
9463 /* TODO */
9464 send_resp(dut, conn, SIGMA_ERROR,
9465 "ErrorCode,MCS32,MCS_FIXEDRATE not supported");
9466 return 0;
9467 } else if (mcs32 && !rate) {
9468 /* TODO */
9469 send_resp(dut, conn, SIGMA_ERROR,
9470 "ErrorCode,MCS32 not supported");
9471 return 0;
9472 } else if (!mcs32 && rate) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009473 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009474 case DRIVER_ATHEROS:
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -07009475 novap_reset(dut, intf, 1);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009476 ath_sta_set_11nrates(dut, intf, rate);
9477 break;
9478 default:
9479 send_resp(dut, conn, SIGMA_ERROR,
9480 "ErrorCode,MCS32_FIXEDRATE not supported");
9481 return 0;
9482 }
9483 }
9484
9485 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
9486}
9487
9488
Arif Hussain7b47d2d2018-05-09 10:44:02 -07009489static void cmd_set_max_he_mcs(struct sigma_dut *dut, const char *intf,
9490 int mcs_config)
9491{
9492#ifdef NL80211_SUPPORT
9493 int ret;
9494
9495 switch (mcs_config) {
9496 case HE_80_MCS0_7:
9497 case HE_80_MCS0_9:
9498 case HE_80_MCS0_11:
9499 ret = sta_set_he_mcs(dut, intf, mcs_config);
9500 if (ret) {
9501 sigma_dut_print(dut, DUT_MSG_ERROR,
9502 "cmd_set_max_he_mcs: Setting of MCS:%d failed, ret:%d",
9503 mcs_config, ret);
9504 }
9505 break;
9506 default:
9507 sigma_dut_print(dut, DUT_MSG_ERROR,
9508 "cmd_set_max_he_mcs: Invalid mcs %d",
9509 mcs_config);
9510 break;
9511 }
9512#else /* NL80211_SUPPORT */
9513 sigma_dut_print(dut, DUT_MSG_ERROR,
9514 "max HE MCS cannot be changed without NL80211_SUPPORT defined");
9515#endif /* NL80211_SUPPORT */
9516}
9517
9518
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07009519struct wait_event {
9520 struct sigma_dut *dut;
9521 int cmd;
9522 unsigned int twt_op;
9523};
9524
9525#ifdef NL80211_SUPPORT
9526
9527static int twt_event_handler(struct nl_msg *msg, void *arg)
9528{
9529 struct wait_event *wait = arg;
9530 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
9531 struct nlattr *tb[NL80211_ATTR_MAX + 1];
9532 uint32_t subcmd;
9533 uint8_t *data = NULL;
9534 size_t len = 0;
9535 struct nlattr *twt_rsp[QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_MAX + 1];
9536 struct nlattr *twt_status[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX + 1];
9537 int cmd_id;
9538 unsigned char val;
9539
9540 if (!wait)
9541 return NL_SKIP;
9542
9543 if (gnlh->cmd != NL80211_CMD_VENDOR) {
9544 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9545 "%s: NL cmd is not vendor %d", __func__,
9546 gnlh->cmd);
9547 return NL_SKIP;
9548 }
9549
9550 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
9551 genlmsg_attrlen(gnlh, 0), NULL);
9552
9553 if (!tb[NL80211_ATTR_VENDOR_ID] || !tb[NL80211_ATTR_VENDOR_SUBCMD]) {
9554 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9555 "%s: vendor ID not found", __func__);
9556 return NL_SKIP;
9557 }
9558 subcmd = nla_get_u32(tb[NL80211_ATTR_VENDOR_SUBCMD]);
9559
9560 if (subcmd != QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) {
9561 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9562 "%s: Not a TWT_cmd %d", __func__, subcmd);
9563 return NL_SKIP;
9564 }
9565 if (tb[NL80211_ATTR_VENDOR_DATA]) {
9566 data = nla_data(tb[NL80211_ATTR_VENDOR_DATA]);
9567 len = nla_len(tb[NL80211_ATTR_VENDOR_DATA]);
9568 } else {
9569 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9570 "%s: vendor data not present", __func__);
9571 return NL_SKIP;
9572 }
9573 if (!data || !len) {
9574 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9575 "Invalid vendor data or len");
9576 return NL_SKIP;
9577 }
9578 sigma_dut_print(wait->dut, DUT_MSG_DEBUG,
9579 "event data len %ld", len);
9580 hex_dump(wait->dut, data, len);
9581 if (nla_parse(twt_rsp, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_MAX,
9582 (struct nlattr *) data, len, NULL)) {
9583 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9584 "vendor data parse error");
9585 return NL_SKIP;
9586 }
9587
9588 val = nla_get_u8(twt_rsp[QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION]);
9589 if (val != wait->twt_op) {
9590 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9591 "Invalid TWT operation, expected %d, rcvd %d",
9592 wait->twt_op, val);
9593 return NL_SKIP;
9594 }
9595 if (nla_parse_nested(twt_status, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX,
9596 twt_rsp[QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS],
9597 NULL)) {
9598 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9599 "nla_parse failed for TWT event");
9600 return NL_SKIP;
9601 }
9602
9603 cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_STATUS;
9604 if (!twt_status[cmd_id]) {
9605 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9606 "%s TWT resp status missing", __func__);
9607 wait->cmd = -1;
9608 } else {
9609 val = nla_get_u8(twt_status[cmd_id]);
9610 if (val != QCA_WLAN_VENDOR_TWT_STATUS_OK) {
9611 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9612 "%s TWT resp status %d", __func__, val);
9613 wait->cmd = -1;
9614 } else {
9615 wait->cmd = 1;
9616 }
9617 }
9618
9619 return NL_SKIP;
9620}
9621
9622
9623static int wait_on_nl_socket(struct nl_sock *sock, struct sigma_dut *dut,
9624 unsigned int timeout)
9625{
9626 fd_set read_fd_set;
9627 int retval;
9628 int sock_fd;
9629 struct timeval time_out;
9630
9631 time_out.tv_sec = timeout;
9632 time_out.tv_usec = 0;
9633
9634 FD_ZERO(&read_fd_set);
9635
9636 if (!sock)
9637 return -1;
9638
9639 sock_fd = nl_socket_get_fd(sock);
9640 FD_SET(sock_fd, &read_fd_set);
9641
9642 retval = select(sock_fd + 1, &read_fd_set, NULL, NULL, &time_out);
9643
9644 if (retval == 0)
9645 sigma_dut_print(dut, DUT_MSG_ERROR,
9646 "%s: TWT event response timedout", __func__);
9647
9648 if (retval < 0)
9649 sigma_dut_print(dut, DUT_MSG_ERROR, "%s:no NL msgs, ret=%d",
9650 __func__, retval);
9651
9652 return retval;
9653}
9654
9655
9656#define TWT_ASYNC_EVENT_WAIT_TIME_SEC 6
9657
9658static int twt_async_event_wait(struct sigma_dut *dut, unsigned int twt_op)
9659{
9660 struct nl_cb *cb;
9661 int err_code = 0, select_retval = 0;
9662 struct wait_event wait_info;
9663
9664 cb = nl_socket_get_cb(dut->nl_ctx->event_sock);
9665 if (!cb) {
9666 sigma_dut_print(dut, DUT_MSG_ERROR,
9667 "event callback not found");
9668 return ERROR_SEND_STATUS;
9669 }
9670
9671 wait_info.cmd = 0;
9672 wait_info.dut = dut;
9673 wait_info.twt_op = twt_op;
9674
9675 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, twt_event_handler, &wait_info);
9676
9677 while (!wait_info.cmd) {
9678 select_retval = wait_on_nl_socket(
9679 dut->nl_ctx->event_sock, dut,
9680 TWT_ASYNC_EVENT_WAIT_TIME_SEC);
9681
9682 if (select_retval > 0) {
9683 err_code = nl_recvmsgs(dut->nl_ctx->event_sock, cb);
9684 if (err_code < 0) {
9685 sigma_dut_print(dut, DUT_MSG_ERROR,
9686 "%s: nl rcv failed, err_code %d",
9687 __func__, err_code);
9688 break;
9689 }
9690 } else {
9691 sigma_dut_print(dut, DUT_MSG_ERROR,
9692 "%s: wait on socket failed %d",
9693 __func__, select_retval);
9694 err_code = 1;
9695 break;
9696 }
9697
9698 }
9699 nl_cb_put(cb);
9700
9701 if (wait_info.cmd < 0)
9702 err_code = 1;
9703
9704 sigma_dut_print(dut, DUT_MSG_DEBUG,
9705 "%s: rcvd cmd %d, err_code %d, s_ret %d",
9706 __func__, wait_info.cmd, err_code, select_retval);
9707
9708 return err_code;
9709}
9710
9711#endif /* NL80211_SUPPORT */
9712
9713
Srinivas Girigowda6707f032020-10-26 15:24:46 -07009714static int sta_twt_send_suspend(struct sigma_dut *dut, struct sigma_conn *conn,
9715 struct sigma_cmd *cmd)
9716{
9717#ifdef NL80211_SUPPORT
9718 struct nlattr *attr, *attr1;
9719 struct nl_msg *msg;
9720 int ifindex, ret;
9721 const char *intf = get_param(cmd, "Interface");
9722
9723 ifindex = if_nametoindex(intf);
9724 if (ifindex == 0) {
9725 sigma_dut_print(dut, DUT_MSG_ERROR,
9726 "%s: Index for interface %s failed",
9727 __func__, intf);
9728 return ERROR_SEND_STATUS;
9729 }
9730
9731 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
9732 NL80211_CMD_VENDOR)) ||
9733 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
9734 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
9735 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
9736 QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
9737 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
9738 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
9739 QCA_WLAN_TWT_SUSPEND) ||
9740 !(attr1 = nla_nest_start(msg,
Kiran Kumar Lokere7ede00c2021-08-09 00:59:52 -07009741 QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS))) {
Srinivas Girigowda6707f032020-10-26 15:24:46 -07009742 sigma_dut_print(dut, DUT_MSG_ERROR,
9743 "%s: err in adding vendor_cmd and vendor_data",
9744 __func__);
9745 nlmsg_free(msg);
9746 return ERROR_SEND_STATUS;
9747 }
9748 nla_nest_end(msg, attr1);
9749 nla_nest_end(msg, attr);
9750
9751 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
9752 if (ret) {
9753 sigma_dut_print(dut, DUT_MSG_ERROR,
9754 "%s: err in send_and_recv_msgs, ret=%d",
9755 __func__, ret);
9756 }
9757
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07009758 if (!dut->sta_async_twt_supp)
9759 return ret;
9760
9761 return twt_async_event_wait(dut, QCA_WLAN_TWT_SUSPEND);
Srinivas Girigowda6707f032020-10-26 15:24:46 -07009762#else /* NL80211_SUPPORT */
9763 sigma_dut_print(dut, DUT_MSG_ERROR,
9764 "TWT suspend cannot be done without NL80211_SUPPORT defined");
9765 return ERROR_SEND_STATUS;
9766#endif /* NL80211_SUPPORT */
9767}
9768
9769
9770static int sta_twt_send_nudge(struct sigma_dut *dut, struct sigma_conn *conn,
9771 struct sigma_cmd *cmd,
9772 unsigned int suspend_duration)
9773{
9774#ifdef NL80211_SUPPORT
9775 struct nlattr *attr, *attr1;
9776 struct nl_msg *msg;
9777 int ifindex, ret;
9778 const char *intf = get_param(cmd, "Interface");
9779 int next_twt_size = 1;
9780
9781 ifindex = if_nametoindex(intf);
9782 if (ifindex == 0) {
9783 sigma_dut_print(dut, DUT_MSG_ERROR,
9784 "%s: Index for interface %s failed",
9785 __func__, intf);
9786 return ERROR_SEND_STATUS;
9787 }
9788
9789 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
9790 NL80211_CMD_VENDOR)) ||
9791 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
9792 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
9793 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
9794 QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
9795 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
9796 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
9797 QCA_WLAN_TWT_NUDGE) ||
9798 !(attr1 = nla_nest_start(msg,
9799 QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS)) ||
9800 (suspend_duration &&
9801 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_WAKE_TIME,
9802 suspend_duration)) ||
9803 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_NEXT_TWT_SIZE,
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -07009804 next_twt_size) ||
9805 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_FLOW_ID, 0)) {
Srinivas Girigowda6707f032020-10-26 15:24:46 -07009806 sigma_dut_print(dut, DUT_MSG_ERROR,
9807 "%s: err in adding vendor_cmd and vendor_data",
9808 __func__);
9809 nlmsg_free(msg);
9810 return ERROR_SEND_STATUS;
9811 }
9812 nla_nest_end(msg, attr1);
9813 nla_nest_end(msg, attr);
9814
9815 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
9816 if (ret) {
9817 sigma_dut_print(dut, DUT_MSG_ERROR,
9818 "%s: err in send_and_recv_msgs, ret=%d",
9819 __func__, ret);
9820 }
9821
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07009822 if (!dut->sta_async_twt_supp)
9823 return ret;
9824
9825 return twt_async_event_wait(dut, QCA_WLAN_TWT_NUDGE);
Srinivas Girigowda6707f032020-10-26 15:24:46 -07009826#else /* NL80211_SUPPORT */
9827 sigma_dut_print(dut, DUT_MSG_ERROR,
9828 "TWT suspend cannot be done without NL80211_SUPPORT defined");
9829 return ERROR_SEND_STATUS;
9830#endif /* NL80211_SUPPORT */
9831}
9832
9833
9834static int sta_twt_suspend_or_nudge(struct sigma_dut *dut,
9835 struct sigma_conn *conn,
9836 struct sigma_cmd *cmd)
9837{
9838 const char *val;
9839
9840 val = get_param(cmd, "TWT_SuspendDuration");
9841 if (val) {
9842 unsigned int suspend_duration;
9843
9844 suspend_duration = atoi(val);
9845 suspend_duration = suspend_duration * 1000 * 1000;
9846 return sta_twt_send_nudge(dut, conn, cmd, suspend_duration);
9847 }
9848
9849 return sta_twt_send_suspend(dut, conn, cmd);
9850}
9851
9852
9853static int sta_twt_resume(struct sigma_dut *dut, struct sigma_conn *conn,
9854 struct sigma_cmd *cmd)
9855{
9856#ifdef NL80211_SUPPORT
9857 struct nlattr *attr, *attr1;
9858 struct nl_msg *msg;
9859 int ifindex, ret;
9860 const char *intf = get_param(cmd, "Interface");
9861 int next2_twt_size = 1;
9862 unsigned int resume_duration = 0;
9863 const char *val;
9864
9865 ifindex = if_nametoindex(intf);
9866 if (ifindex == 0) {
9867 sigma_dut_print(dut, DUT_MSG_ERROR,
9868 "%s: Index for interface %s failed",
9869 __func__, intf);
9870 return ERROR_SEND_STATUS;
9871 }
9872
9873 val = get_param(cmd, "TWT_ResumeDuration");
9874 if (val) {
9875 resume_duration = atoi(val);
9876 resume_duration = resume_duration * 1000 * 1000;
9877 }
9878
9879 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
9880 NL80211_CMD_VENDOR)) ||
9881 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
9882 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
9883 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
9884 QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
9885 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
9886 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
9887 QCA_WLAN_TWT_RESUME) ||
9888 !(attr1 = nla_nest_start(msg,
9889 QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS)) ||
9890 (resume_duration &&
9891 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_RESUME_NEXT2_TWT,
9892 resume_duration)) ||
9893 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_RESUME_NEXT_TWT_SIZE,
9894 next2_twt_size)) {
9895 sigma_dut_print(dut, DUT_MSG_ERROR,
9896 "%s: err in adding vendor_cmd and vendor_data",
9897 __func__);
9898 nlmsg_free(msg);
9899 return ERROR_SEND_STATUS;
9900 }
9901 nla_nest_end(msg, attr1);
9902 nla_nest_end(msg, attr);
9903
9904 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
9905 if (ret) {
9906 sigma_dut_print(dut, DUT_MSG_ERROR,
9907 "%s: err in send_and_recv_msgs, ret=%d",
9908 __func__, ret);
9909 }
9910
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07009911 if (!dut->sta_async_twt_supp)
9912 return ret;
9913
9914 return twt_async_event_wait(dut, QCA_WLAN_TWT_RESUME);
Srinivas Girigowda6707f032020-10-26 15:24:46 -07009915#else /* NL80211_SUPPORT */
9916 sigma_dut_print(dut, DUT_MSG_ERROR,
9917 "TWT resume cannot be done without NL80211_SUPPORT defined");
9918 return ERROR_SEND_STATUS;
9919#endif /* NL80211_SUPPORT */
9920}
9921
9922
Kiran Kumar Lokerebd396102020-04-27 12:01:09 -07009923#define TWT_REQUEST_CMD 0
9924#define TWT_SUGGEST_CMD 1
9925#define TWT_DEMAND_CMD 2
9926
Arif Hussain480d5f42019-03-12 14:40:42 -07009927static int sta_twt_request(struct sigma_dut *dut, struct sigma_conn *conn,
9928 struct sigma_cmd *cmd)
9929{
9930#ifdef NL80211_SUPPORT
9931 struct nlattr *params;
9932 struct nlattr *attr;
Arif Hussain480d5f42019-03-12 14:40:42 -07009933 struct nl_msg *msg;
9934 int ifindex, ret;
9935 const char *val;
9936 const char *intf = get_param(cmd, "Interface");
9937 int wake_interval_exp = 10, nominal_min_wake_dur = 255,
9938 wake_interval_mantissa = 512;
9939 int flow_type = 0, twt_trigger = 0, target_wake_time = 0,
Kiran Kumar Lokerebd396102020-04-27 12:01:09 -07009940 protection = 0, cmd_type = QCA_WLAN_VENDOR_TWT_SETUP_SUGGEST;
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -07009941 int bcast_twt = 0;
9942 int bcast_twt_id = 0, bcast_twt_recommdn = 0, bcast_twt_persis = 0;
Arif Hussain480d5f42019-03-12 14:40:42 -07009943
9944 ifindex = if_nametoindex(intf);
9945 if (ifindex == 0) {
9946 sigma_dut_print(dut, DUT_MSG_ERROR,
9947 "%s: Index for interface %s failed",
9948 __func__, intf);
9949 return -1;
9950 }
9951
9952 val = get_param(cmd, "FlowType");
9953 if (val) {
9954 flow_type = atoi(val);
9955 if (flow_type != 0 && flow_type != 1) {
9956 sigma_dut_print(dut, DUT_MSG_ERROR,
9957 "TWT: Invalid FlowType %d", flow_type);
9958 return -1;
9959 }
9960 }
9961
9962 val = get_param(cmd, "TWT_Trigger");
9963 if (val) {
9964 twt_trigger = atoi(val);
9965 if (twt_trigger != 0 && twt_trigger != 1) {
9966 sigma_dut_print(dut, DUT_MSG_ERROR,
9967 "TWT: Invalid TWT_Trigger %d",
9968 twt_trigger);
9969 return -1;
9970 }
9971 }
9972
9973 val = get_param(cmd, "Protection");
9974 if (val) {
9975 protection = atoi(val);
9976 if (protection != 0 && protection != 1) {
9977 sigma_dut_print(dut, DUT_MSG_ERROR,
9978 "TWT: Invalid Protection %d",
9979 protection);
9980 return -1;
9981 }
9982 }
9983
Kiran Kumar Lokerebd396102020-04-27 12:01:09 -07009984 val = get_param(cmd, "SetupCommand");
9985 if (val) {
9986 cmd_type = atoi(val);
9987 if (cmd_type == TWT_REQUEST_CMD)
9988 cmd_type = QCA_WLAN_VENDOR_TWT_SETUP_REQUEST;
9989 else if (cmd_type == TWT_SUGGEST_CMD)
9990 cmd_type = QCA_WLAN_VENDOR_TWT_SETUP_SUGGEST;
9991 else if (cmd_type == TWT_DEMAND_CMD)
9992 cmd_type = QCA_WLAN_VENDOR_TWT_SETUP_DEMAND;
9993 else
9994 sigma_dut_print(dut, DUT_MSG_ERROR,
9995 "Default suggest is used for cmd %d",
9996 cmd_type);
9997 }
9998
Arif Hussain480d5f42019-03-12 14:40:42 -07009999 val = get_param(cmd, "TargetWakeTime");
10000 if (val)
10001 target_wake_time = atoi(val);
10002
10003 val = get_param(cmd, "WakeIntervalMantissa");
10004 if (val)
10005 wake_interval_mantissa = atoi(val);
10006
10007 val = get_param(cmd, "WakeIntervalExp");
10008 if (val)
10009 wake_interval_exp = atoi(val);
10010
10011 val = get_param(cmd, "NominalMinWakeDur");
10012 if (val)
10013 nominal_min_wake_dur = atoi(val);
10014
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010015 val = get_param(cmd, "BTWT_ID");
10016 if (val) {
10017 bcast_twt_id = atoi(val);
10018 bcast_twt = 1;
10019 }
10020
10021 val = get_param(cmd, "BTWT_Persistence");
10022 if (val) {
10023 bcast_twt_persis = atoi(val);
10024 bcast_twt = 1;
10025 }
10026
10027 val = get_param(cmd, "BTWT_Recommendation");
10028 if (val) {
10029 bcast_twt_recommdn = atoi(val);
10030 bcast_twt = 1;
10031 }
10032
10033 if (bcast_twt)
10034 sigma_dut_print(dut, DUT_MSG_DEBUG,
10035 "BCAST_TWT: ID %d, RECOMM %d, PERSIS %d",
10036 bcast_twt_id, bcast_twt_recommdn,
10037 bcast_twt_persis);
10038
Arif Hussain480d5f42019-03-12 14:40:42 -070010039 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
10040 NL80211_CMD_VENDOR)) ||
10041 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
10042 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
10043 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010044 QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010045 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010046 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
10047 QCA_WLAN_TWT_SET) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010048 !(params = nla_nest_start(
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010049 msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS)) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010050 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_EXP,
10051 wake_interval_exp) ||
Kiran Kumar Lokerebd396102020-04-27 12:01:09 -070010052 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_REQ_TYPE, cmd_type) ||
Kiran Kumar Lokere2cffae52019-09-26 18:44:15 -070010053 (twt_trigger &&
10054 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TRIGGER)) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010055 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE,
10056 flow_type) ||
Kiran Kumar Lokere2cffae52019-09-26 18:44:15 -070010057 (protection &&
10058 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_PROTECTION)) ||
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010059 (bcast_twt &&
10060 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST)) ||
10061 (bcast_twt &&
10062 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_ID,
10063 bcast_twt_id)) ||
10064 (bcast_twt &&
10065 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_PERSISTENCE,
10066 bcast_twt_persis)) ||
10067 (bcast_twt &&
10068 nla_put_u8(msg,
10069 QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_RECOMMENDATION,
10070 bcast_twt_recommdn)) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010071 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME,
10072 target_wake_time) ||
10073 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_DURATION,
10074 nominal_min_wake_dur) ||
10075 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_MANTISSA,
10076 wake_interval_mantissa)) {
10077 sigma_dut_print(dut, DUT_MSG_ERROR,
10078 "%s: err in adding vendor_cmd and vendor_data",
10079 __func__);
10080 nlmsg_free(msg);
10081 return -1;
10082 }
Arif Hussain480d5f42019-03-12 14:40:42 -070010083 nla_nest_end(msg, params);
10084 nla_nest_end(msg, attr);
10085
10086 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
10087 if (ret) {
10088 sigma_dut_print(dut, DUT_MSG_ERROR,
10089 "%s: err in send_and_recv_msgs, ret=%d",
10090 __func__, ret);
10091 }
10092
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -070010093 if (!dut->sta_async_twt_supp)
10094 return ret;
10095
10096 return twt_async_event_wait(dut, QCA_WLAN_TWT_SET);
Arif Hussain480d5f42019-03-12 14:40:42 -070010097#else /* NL80211_SUPPORT */
10098 sigma_dut_print(dut, DUT_MSG_ERROR,
10099 "TWT request cannot be done without NL80211_SUPPORT defined");
10100 return -1;
10101#endif /* NL80211_SUPPORT */
10102}
10103
10104
10105static int sta_twt_teardown(struct sigma_dut *dut, struct sigma_conn *conn,
10106 struct sigma_cmd *cmd)
10107{
10108 #ifdef NL80211_SUPPORT
10109 struct nlattr *params;
10110 struct nlattr *attr;
Arif Hussain480d5f42019-03-12 14:40:42 -070010111 int ifindex, ret;
10112 struct nl_msg *msg;
10113 const char *intf = get_param(cmd, "Interface");
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010114 int bcast_twt = 0;
10115 int bcast_twt_id = 0;
10116 const char *val;
Arif Hussain480d5f42019-03-12 14:40:42 -070010117
10118 ifindex = if_nametoindex(intf);
10119 if (ifindex == 0) {
10120 sigma_dut_print(dut, DUT_MSG_ERROR,
10121 "%s: Index for interface %s failed",
10122 __func__, intf);
10123 return -1;
10124 }
10125
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010126 val = get_param(cmd, "BTWT_ID");
10127 if (val) {
10128 bcast_twt_id = atoi(val);
10129 bcast_twt = 1;
10130 }
10131
Arif Hussain480d5f42019-03-12 14:40:42 -070010132 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
10133 NL80211_CMD_VENDOR)) ||
10134 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
10135 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
10136 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010137 QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010138 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010139 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
10140 QCA_WLAN_TWT_TERMINATE) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010141 !(params = nla_nest_start(
10142 msg,
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010143 QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS)) ||
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010144 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE, 0) ||
10145 (bcast_twt &&
10146 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST)) ||
10147 (bcast_twt &&
10148 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_ID,
10149 bcast_twt_id))) {
Arif Hussain480d5f42019-03-12 14:40:42 -070010150 sigma_dut_print(dut, DUT_MSG_ERROR,
10151 "%s: err in adding vendor_cmd and vendor_data",
10152 __func__);
10153 nlmsg_free(msg);
10154 return -1;
10155 }
Arif Hussain480d5f42019-03-12 14:40:42 -070010156 nla_nest_end(msg, params);
10157 nla_nest_end(msg, attr);
10158
10159 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
10160 if (ret) {
10161 sigma_dut_print(dut, DUT_MSG_ERROR,
10162 "%s: err in send_and_recv_msgs, ret=%d",
10163 __func__, ret);
10164 }
10165
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -070010166 if (!dut->sta_async_twt_supp)
10167 return ret;
10168
10169 return twt_async_event_wait(dut, QCA_WLAN_TWT_TERMINATE);
Arif Hussain480d5f42019-03-12 14:40:42 -070010170#else /* NL80211_SUPPORT */
10171 sigma_dut_print(dut, DUT_MSG_ERROR,
10172 "TWT teardown cannot be done without NL80211_SUPPORT defined");
10173 return -1;
10174#endif /* NL80211_SUPPORT */
10175}
10176
10177
Kiran Kumar Lokere50eb2cd2018-12-18 18:31:28 -080010178static int sta_transmit_omi(struct sigma_dut *dut, struct sigma_conn *conn,
10179 struct sigma_cmd *cmd)
10180{
10181#ifdef NL80211_SUPPORT
10182 struct nlattr *params;
10183 struct nlattr *attr;
10184 struct nlattr *attr1;
10185 struct nl_msg *msg;
10186 int ifindex, ret;
10187 const char *val;
10188 const char *intf = get_param(cmd, "Interface");
10189 uint8_t rx_nss = 0xFF, ch_bw = 0xFF, tx_nsts = 0xFF, ulmu_dis = 0,
10190 ulmu_data_dis = 0;
10191
10192 ifindex = if_nametoindex(intf);
10193 if (ifindex == 0) {
10194 sigma_dut_print(dut, DUT_MSG_ERROR,
10195 "%s: Index for interface %s failed",
10196 __func__, intf);
10197 return -1;
10198 }
10199 val = get_param(cmd, "OMCtrl_RxNSS");
10200 if (val)
10201 rx_nss = atoi(val);
10202
10203 val = get_param(cmd, "OMCtrl_ChnlWidth");
10204 if (val)
10205 ch_bw = atoi(val);
10206
10207 val = get_param(cmd, "OMCtrl_ULMUDisable");
10208 if (val)
10209 ulmu_dis = atoi(val);
10210
10211 val = get_param(cmd, "OMCtrl_TxNSTS");
10212 if (val)
10213 tx_nsts = atoi(val);
10214
10215 val = get_param(cmd, "OMCtrl_ULMUDataDisable");
10216 if (val)
10217 ulmu_data_dis = atoi(val);
10218
10219 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
10220 NL80211_CMD_VENDOR)) ||
10221 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
10222 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
10223 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
10224 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
10225 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
10226 !(params = nla_nest_start(
10227 msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OMI_TX)) ||
10228 !(attr1 = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
10229 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_RX_NSS, rx_nss) ||
10230 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_CH_BW, ch_bw) ||
10231 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_TX_NSTS, tx_nsts) ||
10232 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DATA_DISABLE,
10233 ulmu_data_dis) ||
10234 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DISABLE,
10235 ulmu_dis)) {
10236 sigma_dut_print(dut, DUT_MSG_ERROR,
10237 "%s: err in adding vendor_cmd and vendor_data",
10238 __func__);
10239 nlmsg_free(msg);
10240 return -1;
10241 }
10242 nla_nest_end(msg, attr1);
10243 nla_nest_end(msg, params);
10244 nla_nest_end(msg, attr);
10245
10246 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
10247 if (ret) {
10248 sigma_dut_print(dut, DUT_MSG_ERROR,
10249 "%s: err in send_and_recv_msgs, ret=%d",
10250 __func__, ret);
10251 }
10252
10253 return ret;
10254#else /* NL80211_SUPPORT */
10255 sigma_dut_print(dut, DUT_MSG_ERROR,
10256 "OMI TX cannot be processed without NL80211_SUPPORT defined");
10257 return -1;
10258#endif /* NL80211_SUPPORT */
10259}
10260
10261
Jouni Malinen224e3902021-06-09 16:41:27 +030010262static enum sigma_cmd_result
10263cmd_sta_set_wireless_vht(struct sigma_dut *dut, struct sigma_conn *conn,
10264 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010265{
10266 const char *intf = get_param(cmd, "Interface");
10267 const char *val;
Arif Hussaina37e9552018-06-20 17:05:59 -070010268 const char *program;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010269 int tkip = -1;
10270 int wep = -1;
Mohammad Asaad Akram50848402020-05-28 14:10:24 +053010271 int iwpriv_status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010272
Arif Hussaina37e9552018-06-20 17:05:59 -070010273 program = get_param(cmd, "Program");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010274 val = get_param(cmd, "SGI80");
10275 if (val) {
10276 int sgi80;
10277
10278 sgi80 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010279 run_iwpriv(dut, intf, "shortgi %d", sgi80);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010280 }
10281
10282 val = get_param(cmd, "TxBF");
10283 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010284 switch (get_driver_type(dut)) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010285 case DRIVER_WCN:
10286 if (sta_set_tx_beamformee(dut, intf, 1)) {
10287 send_resp(dut, conn, SIGMA_ERROR,
10288 "ErrorCode,Failed to set TX beamformee enable");
Jouni Malinen224e3902021-06-09 16:41:27 +030010289 return STATUS_SENT_ERROR;
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010290 }
10291 break;
10292 case DRIVER_ATHEROS:
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010293 if (run_iwpriv(dut, intf, "vhtsubfee 1") < 0) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010294 send_resp(dut, conn, SIGMA_ERROR,
10295 "ErrorCode,Setting vhtsubfee failed");
Jouni Malinen224e3902021-06-09 16:41:27 +030010296 return STATUS_SENT_ERROR;
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010297 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010298 if (run_iwpriv(dut, intf, "vhtsubfer 1") < 0) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010299 send_resp(dut, conn, SIGMA_ERROR,
10300 "ErrorCode,Setting vhtsubfer failed");
Jouni Malinen224e3902021-06-09 16:41:27 +030010301 return STATUS_SENT_ERROR;
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010302 }
10303 break;
10304 default:
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010305 sigma_dut_print(dut, DUT_MSG_ERROR,
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010306 "Unsupported driver type");
10307 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010308 }
10309 }
10310
10311 val = get_param(cmd, "MU_TxBF");
10312 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010313 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010314 case DRIVER_ATHEROS:
10315 ath_sta_set_txsp_stream(dut, intf, "1SS");
10316 ath_sta_set_rxsp_stream(dut, intf, "1SS");
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010317 run_iwpriv(dut, intf, "vhtmubfee 1");
10318 run_iwpriv(dut, intf, "vhtmubfer 1");
Sunil Duttae9e5d12018-06-29 11:50:47 +053010319 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010320 case DRIVER_WCN:
10321 if (wcn_sta_set_sp_stream(dut, intf, "1SS") < 0) {
10322 send_resp(dut, conn, SIGMA_ERROR,
10323 "ErrorCode,Failed to set RX/TXSP_STREAM");
Jouni Malinen224e3902021-06-09 16:41:27 +030010324 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010325 }
Sunil Duttae9e5d12018-06-29 11:50:47 +053010326 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010327 default:
10328 sigma_dut_print(dut, DUT_MSG_ERROR,
10329 "Setting SP_STREAM not supported");
10330 break;
10331 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010332 }
10333
10334 val = get_param(cmd, "LDPC");
10335 if (val) {
10336 int ldpc;
10337
10338 ldpc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
Mohammad Asaad Akram50848402020-05-28 14:10:24 +053010339 iwpriv_status = run_iwpriv(dut, intf, "ldpc %d", ldpc);
10340 if (iwpriv_status)
10341 sta_config_params(dut, intf, STA_SET_LDPC, ldpc);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010342 }
10343
Amarnath Hullur Subramanyam7bae60e2018-01-31 03:46:50 -080010344 val = get_param(cmd, "BCC");
10345 if (val) {
10346 int bcc;
10347
10348 bcc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
10349 /* use LDPC iwpriv itself to set bcc coding, bcc coding
10350 * is mutually exclusive to bcc */
Mohammad Asaad Akram50848402020-05-28 14:10:24 +053010351 iwpriv_status = run_iwpriv(dut, intf, "ldpc %d", !bcc);
10352 if (iwpriv_status)
10353 sta_config_params(dut, intf, STA_SET_LDPC, !bcc);
Amarnath Hullur Subramanyam7bae60e2018-01-31 03:46:50 -080010354 }
10355
Arif Hussain7b47d2d2018-05-09 10:44:02 -070010356 val = get_param(cmd, "MaxHE-MCS_1SS_RxMapLTE80");
10357 if (val && dut->sta_nss == 1)
10358 cmd_set_max_he_mcs(dut, intf, atoi(val));
10359
10360 val = get_param(cmd, "MaxHE-MCS_2SS_RxMapLTE80");
10361 if (val && dut->sta_nss == 2)
10362 cmd_set_max_he_mcs(dut, intf, atoi(val));
10363
Arif Hussainac6c5112018-05-25 17:34:00 -070010364 val = get_param(cmd, "MCS_FixedRate");
10365 if (val) {
10366#ifdef NL80211_SUPPORT
10367 int mcs, ratecode = 0;
10368 enum he_mcs_config mcs_config;
10369 int ret;
Jouni Malinenb9b671d2019-04-26 13:23:17 +030010370 char buf[60];
Arif Hussainac6c5112018-05-25 17:34:00 -070010371
10372 ratecode = (0x07 & dut->sta_nss) << 5;
10373 mcs = atoi(val);
10374 /* Add the MCS to the ratecode */
10375 if (mcs >= 0 && mcs <= 11) {
10376 ratecode += mcs;
10377 if (dut->device_type == STA_testbed &&
10378 mcs > 7 && mcs <= 11) {
10379 if (mcs <= 9)
10380 mcs_config = HE_80_MCS0_9;
10381 else
10382 mcs_config = HE_80_MCS0_11;
10383 ret = sta_set_he_mcs(dut, intf, mcs_config);
10384 if (ret) {
10385 sigma_dut_print(dut, DUT_MSG_ERROR,
10386 "MCS_FixedRate: mcs setting failed, mcs:%d, mcs_config %d, ret:%d",
10387 mcs, mcs_config, ret);
10388 }
10389 }
10390 snprintf(buf, sizeof(buf),
10391 "iwpriv %s set_11ax_rate 0x%03x",
10392 intf, ratecode);
10393 if (system(buf) != 0) {
10394 sigma_dut_print(dut, DUT_MSG_ERROR,
10395 "MCS_FixedRate: iwpriv setting of 11ax rates 0x%03x failed",
10396 ratecode);
10397 }
10398 } else {
10399 sigma_dut_print(dut, DUT_MSG_ERROR,
10400 "MCS_FixedRate: HE MCS %d not supported",
10401 mcs);
10402 }
10403#else /* NL80211_SUPPORT */
10404 sigma_dut_print(dut, DUT_MSG_ERROR,
10405 "MCS_FixedRate cannot be changed without NL80211_SUPPORT defined");
10406#endif /* NL80211_SUPPORT */
10407 }
10408
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010409 val = get_param(cmd, "opt_md_notif_ie");
10410 if (val) {
10411 char *result = NULL;
10412 char delim[] = ";";
10413 char token[30];
10414 int value, config_val = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010415 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010416
Peng Xub8fc5cc2017-05-10 17:27:28 -070010417 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010418 result = strtok_r(token, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010419
10420 /* Extract the NSS information */
10421 if (result) {
10422 value = atoi(result);
10423 switch (value) {
10424 case 1:
10425 config_val = 1;
10426 break;
10427 case 2:
10428 config_val = 3;
10429 break;
10430 case 3:
10431 config_val = 7;
10432 break;
10433 case 4:
10434 config_val = 15;
10435 break;
10436 default:
10437 config_val = 3;
10438 break;
10439 }
10440
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010441 run_iwpriv(dut, intf, "rxchainmask %d", config_val);
10442 run_iwpriv(dut, intf, "txchainmask %d", config_val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010443
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010444 }
10445
10446 /* Extract the channel width information */
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010447 result = strtok_r(NULL, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010448 if (result) {
10449 value = atoi(result);
10450 switch (value) {
10451 case 20:
10452 config_val = 0;
10453 break;
10454 case 40:
10455 config_val = 1;
10456 break;
10457 case 80:
10458 config_val = 2;
10459 break;
10460 case 160:
10461 config_val = 3;
10462 break;
10463 default:
10464 config_val = 2;
10465 break;
10466 }
10467
10468 dut->chwidth = config_val;
10469
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010470 run_iwpriv(dut, intf, "chwidth %d", config_val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010471 }
10472
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010473 run_iwpriv(dut, intf, "opmode_notify 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010474 }
10475
10476 val = get_param(cmd, "nss_mcs_cap");
10477 if (val) {
10478 int nss, mcs;
10479 char token[20];
10480 char *result = NULL;
10481 unsigned int vht_mcsmap = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010482 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010483
Peng Xub8fc5cc2017-05-10 17:27:28 -070010484 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010485 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +053010486 if (!result) {
10487 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -070010488 "NSS not specified");
10489 send_resp(dut, conn, SIGMA_ERROR,
10490 "errorCode,NSS not specified");
Jouni Malinen224e3902021-06-09 16:41:27 +030010491 return STATUS_SENT_ERROR;
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +053010492 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010493 nss = atoi(result);
10494
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010495 run_iwpriv(dut, intf, "nss %d", nss);
Arif Hussainac6c5112018-05-25 17:34:00 -070010496 dut->sta_nss = nss;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010497
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010498 result = strtok_r(NULL, ";", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010499 if (result == NULL) {
10500 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -070010501 "MCS not specified");
10502 send_resp(dut, conn, SIGMA_ERROR,
10503 "errorCode,MCS not specified");
Jouni Malinen224e3902021-06-09 16:41:27 +030010504 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010505 }
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010506 result = strtok_r(result, "-", &saveptr);
10507 result = strtok_r(NULL, "-", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +053010508 if (!result) {
10509 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -070010510 "MCS not specified");
10511 send_resp(dut, conn, SIGMA_ERROR,
10512 "errorCode,MCS not specified");
Jouni Malinen224e3902021-06-09 16:41:27 +030010513 return STATUS_SENT_ERROR;
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +053010514 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010515 mcs = atoi(result);
10516
Arif Hussaina37e9552018-06-20 17:05:59 -070010517 if (program && strcasecmp(program, "HE") == 0) {
10518#ifdef NL80211_SUPPORT
10519 enum he_mcs_config mcs_config;
10520 int ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010521
Arif Hussaina37e9552018-06-20 17:05:59 -070010522 if (mcs >= 0 && mcs <= 7) {
10523 mcs_config = HE_80_MCS0_7;
10524 } else if (mcs > 7 && mcs <= 9) {
10525 mcs_config = HE_80_MCS0_9;
10526 } else if (mcs > 9 && mcs <= 11) {
10527 mcs_config = HE_80_MCS0_11;
10528 } else {
10529 sigma_dut_print(dut, DUT_MSG_ERROR,
10530 "nss_mcs_cap: HE: Invalid mcs: %d",
10531 mcs);
10532 send_resp(dut, conn, SIGMA_ERROR,
10533 "errorCode,Invalid MCS");
Jouni Malinen224e3902021-06-09 16:41:27 +030010534 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010535 }
Arif Hussaina37e9552018-06-20 17:05:59 -070010536
10537 ret = sta_set_he_mcs(dut, intf, mcs_config);
10538 if (ret) {
10539 sigma_dut_print(dut, DUT_MSG_ERROR,
10540 "nss_mcs_cap: HE: Setting of MCS failed, mcs_config: %d, ret: %d",
10541 mcs_config, ret);
10542 send_resp(dut, conn, SIGMA_ERROR,
10543 "errorCode,Failed to set MCS");
Jouni Malinen224e3902021-06-09 16:41:27 +030010544 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010545 }
Arif Hussaina37e9552018-06-20 17:05:59 -070010546#else /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010547 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -070010548 "nss_mcs_cap: HE: MCS cannot be changed without NL80211_SUPPORT defined");
10549#endif /* NL80211_SUPPORT */
10550 } else {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010551 run_iwpriv(dut, intf, "vhtmcs %d", mcs);
Arif Hussaina37e9552018-06-20 17:05:59 -070010552
10553 switch (nss) {
10554 case 1:
10555 switch (mcs) {
10556 case 7:
10557 vht_mcsmap = 0xfffc;
10558 break;
10559 case 8:
10560 vht_mcsmap = 0xfffd;
10561 break;
10562 case 9:
10563 vht_mcsmap = 0xfffe;
10564 break;
10565 default:
10566 vht_mcsmap = 0xfffe;
10567 break;
10568 }
10569 break;
10570 case 2:
10571 switch (mcs) {
10572 case 7:
10573 vht_mcsmap = 0xfff0;
10574 break;
10575 case 8:
10576 vht_mcsmap = 0xfff5;
10577 break;
10578 case 9:
10579 vht_mcsmap = 0xfffa;
10580 break;
10581 default:
10582 vht_mcsmap = 0xfffa;
10583 break;
10584 }
10585 break;
10586 case 3:
10587 switch (mcs) {
10588 case 7:
10589 vht_mcsmap = 0xffc0;
10590 break;
10591 case 8:
10592 vht_mcsmap = 0xffd5;
10593 break;
10594 case 9:
10595 vht_mcsmap = 0xffea;
10596 break;
10597 default:
10598 vht_mcsmap = 0xffea;
10599 break;
10600 }
10601 break;
10602 default:
10603 vht_mcsmap = 0xffea;
10604 break;
10605 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010606 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010607 }
10608 }
10609
10610 /* UNSUPPORTED: val = get_param(cmd, "Tx_lgi_rate"); */
10611
10612 val = get_param(cmd, "Vht_tkip");
10613 if (val)
10614 tkip = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
10615
10616 val = get_param(cmd, "Vht_wep");
10617 if (val)
10618 wep = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
10619
10620 if (tkip != -1 || wep != -1) {
10621 if ((tkip == 1 && wep != 0) || (wep == 1 && tkip != 0)) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010622 run_iwpriv(dut, intf, "htweptkip 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010623 } else if ((tkip == 0 && wep != 1) || (wep == 0 && tkip != 1)) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010624 run_iwpriv(dut, intf, "htweptkip 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010625 } else {
Jouni Malinen224e3902021-06-09 16:41:27 +030010626 send_resp(dut, conn, SIGMA_ERROR,
10627 "ErrorCode,mixed mode of VHT TKIP/WEP not supported");
10628 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010629 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010630 }
10631
Kiran Kumar Lokere09dbcef2021-08-09 00:01:41 -070010632 val = get_param(cmd, "TWTSchedSTASupport");
10633 if (val) {
10634 int set_val;
10635
10636 switch (get_driver_type(dut)) {
10637 case DRIVER_WCN:
10638 if (strcasecmp(val, "Enable") == 0) {
10639 set_val = 1;
10640 } else if (strcasecmp(val, "Disable") == 0) {
10641 set_val = 0;
10642 } else {
10643 send_resp(dut, conn, SIGMA_ERROR,
10644 "ErrorCode,Invalid TWTSchedSTASupport");
10645 return STATUS_SENT_ERROR;
10646 }
10647
10648 if (sta_set_bcast_twt_support(dut, intf, set_val)) {
10649 send_resp(dut, conn, SIGMA_ERROR,
10650 "ErrorCode,Failed to set TWTSchedSTASupport");
10651 return STATUS_SENT_ERROR;
10652 }
10653 break;
10654 default:
10655 sigma_dut_print(dut, DUT_MSG_ERROR,
10656 "Setting TWTSchedSTASupport not supported");
10657 break;
10658 }
10659 }
10660
10661 val = get_param(cmd, "MBSSID_RxCtrl");
10662 if (val) {
10663 int set_val;
10664
10665 switch (get_driver_type(dut)) {
10666 case DRIVER_WCN:
10667 if (strcasecmp(val, "Enable") == 0) {
10668 set_val = 1;
10669 } else if (strcasecmp(val, "Disable") == 0) {
10670 set_val = 0;
10671 } else {
10672 send_resp(dut, conn, SIGMA_ERROR,
10673 "ErrorCode,Invalid MBSSID_RxCtrl");
10674 return STATUS_SENT_ERROR;
10675 }
10676
10677 if (sta_set_rx_ctrl_multi_bss(dut, intf, set_val)) {
10678 send_resp(dut, conn, SIGMA_ERROR,
10679 "ErrorCode,Failed to set MBSSID_RxCtrl");
10680 return STATUS_SENT_ERROR;
10681 }
10682 break;
10683 default:
10684 sigma_dut_print(dut, DUT_MSG_ERROR,
10685 "Setting MBSSID_RxCtrl not supported");
10686 break;
10687 }
10688 }
10689
Arif Hussain55f00da2018-07-03 08:28:26 -070010690 val = get_param(cmd, "txBandwidth");
10691 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010692 switch (get_driver_type(dut)) {
Arif Hussain55f00da2018-07-03 08:28:26 -070010693 case DRIVER_WCN:
10694 if (wcn_sta_set_width(dut, intf, val) < 0) {
10695 send_resp(dut, conn, SIGMA_ERROR,
10696 "ErrorCode,Failed to set txBandwidth");
Jouni Malinen224e3902021-06-09 16:41:27 +030010697 return STATUS_SENT_ERROR;
Arif Hussain55f00da2018-07-03 08:28:26 -070010698 }
10699 break;
10700 case DRIVER_ATHEROS:
10701 if (ath_set_width(dut, conn, intf, val) < 0) {
10702 send_resp(dut, conn, SIGMA_ERROR,
10703 "ErrorCode,Failed to set txBandwidth");
Jouni Malinen224e3902021-06-09 16:41:27 +030010704 return STATUS_SENT_ERROR;
Arif Hussain55f00da2018-07-03 08:28:26 -070010705 }
10706 break;
10707 default:
10708 sigma_dut_print(dut, DUT_MSG_ERROR,
10709 "Setting txBandwidth not supported");
10710 break;
10711 }
10712 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010713
Arif Hussain9765f7d2018-07-03 08:28:26 -070010714 val = get_param(cmd, "BeamformeeSTS");
10715 if (val) {
Kiran Kumar Lokerebc89d432018-07-10 12:20:13 -070010716 if (sta_set_tx_beamformee(dut, intf, 1)) {
10717 send_resp(dut, conn, SIGMA_ERROR,
10718 "ErrorCode,Failed to set TX beamformee enable");
Jouni Malinen224e3902021-06-09 16:41:27 +030010719 return STATUS_SENT_ERROR;
Kiran Kumar Lokerebc89d432018-07-10 12:20:13 -070010720 }
10721
Arif Hussain9765f7d2018-07-03 08:28:26 -070010722 if (sta_set_beamformee_sts(dut, intf, atoi(val))) {
10723 send_resp(dut, conn, SIGMA_ERROR,
10724 "ErrorCode,Failed to set BeamformeeSTS");
Jouni Malinen224e3902021-06-09 16:41:27 +030010725 return STATUS_SENT_ERROR;
Arif Hussain9765f7d2018-07-03 08:28:26 -070010726 }
10727 }
10728
Arif Hussain68d23f52018-07-11 13:39:08 -070010729 val = get_param(cmd, "Trig_MAC_Padding_Dur");
10730 if (val) {
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -070010731#ifdef NL80211_SUPPORT
10732 enum qca_wlan_he_mac_padding_dur set_val;
10733
10734 switch (atoi(val)) {
10735 case 16:
10736 set_val = QCA_WLAN_HE_16US_OF_PROCESS_TIME;
10737 break;
10738 case 8:
10739 set_val = QCA_WLAN_HE_8US_OF_PROCESS_TIME;
10740 break;
10741 default:
10742 set_val = QCA_WLAN_HE_NO_ADDITIONAL_PROCESS_TIME;
10743 break;
10744 }
10745 if (sta_set_mac_padding_duration(dut, intf, set_val)) {
Arif Hussain68d23f52018-07-11 13:39:08 -070010746 send_resp(dut, conn, SIGMA_ERROR,
10747 "ErrorCode,Failed to set MAC padding duration");
Jouni Malinen224e3902021-06-09 16:41:27 +030010748 return STATUS_SENT_ERROR;
Arif Hussain68d23f52018-07-11 13:39:08 -070010749 }
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -070010750#else /* NL80211_SUPPORT */
10751 sigma_dut_print(dut, DUT_MSG_ERROR,
10752 "MAC padding duration cannot be changed without NL80211_SUPPORT defined");
10753#endif /* NL80211_SUPPORT */
Arif Hussain68d23f52018-07-11 13:39:08 -070010754 }
10755
Arif Hussain480d5f42019-03-12 14:40:42 -070010756 val = get_param(cmd, "TWT_ReqSupport");
10757 if (val) {
10758 int set_val;
10759
10760 if (strcasecmp(val, "Enable") == 0) {
10761 set_val = 1;
10762 } else if (strcasecmp(val, "Disable") == 0) {
10763 set_val = 0;
10764 } else {
10765 send_resp(dut, conn, SIGMA_ERROR,
10766 "ErrorCode,Invalid TWT_ReqSupport");
Jouni Malinen224e3902021-06-09 16:41:27 +030010767 return STATUS_SENT_ERROR;
Arif Hussain480d5f42019-03-12 14:40:42 -070010768 }
10769
10770 if (sta_set_twt_req_support(dut, intf, set_val)) {
10771 sigma_dut_print(dut, DUT_MSG_ERROR,
10772 "Failed to set TWT req support %d",
10773 set_val);
10774 send_resp(dut, conn, SIGMA_ERROR,
10775 "ErrorCode,Failed to set TWT_ReqSupport");
Jouni Malinen224e3902021-06-09 16:41:27 +030010776 return STATUS_SENT_ERROR;
Arif Hussain480d5f42019-03-12 14:40:42 -070010777 }
10778 }
10779
Kiran Kumar Lokered0ec5ed2021-04-01 00:15:04 -070010780 val = get_param(cmd, "PreamblePunctRx");
10781 if (val && get_driver_type(dut) == DRIVER_WCN) {
10782 int set_val;
10783
10784 if (strcasecmp(val, "Enable") == 0) {
10785 set_val = 1;
10786 } else if (strcasecmp(val, "Disable") == 0) {
10787 set_val = 0;
10788 } else {
10789 send_resp(dut, conn, SIGMA_ERROR,
10790 "ErrorCode,Invalid PreamblePunctRx");
10791 return STATUS_SENT_ERROR;
10792 }
10793
10794 if (sta_set_punctured_preamble_rx(dut, intf, set_val)) {
10795 sigma_dut_print(dut, DUT_MSG_ERROR,
10796 "Failed to set PreamblePunctRx support %d",
10797 set_val);
10798 send_resp(dut, conn, SIGMA_ERROR,
10799 "ErrorCode,Failed to set PreamblePunctRx");
10800 return STATUS_SENT_ERROR;
10801 }
10802 }
10803
Srinivas Girigowda0525e292020-11-12 13:28:21 -080010804 val = get_param(cmd, "FullBW_ULMUMIMO");
10805 if (val) {
10806 int set_val;
10807
10808 if (strcasecmp(val, "Enable") == 0) {
10809 set_val = 1;
10810 } else if (strcasecmp(val, "Disable") == 0) {
10811 set_val = 0;
10812 } else {
10813 send_resp(dut, conn, SIGMA_ERROR,
10814 "ErrorCode,Invalid FullBW_ULMUMIMO");
10815 return STATUS_SENT_ERROR;
10816 }
10817
10818 if (sta_set_fullbw_ulmumimo(dut, intf, set_val)) {
10819 sigma_dut_print(dut, DUT_MSG_ERROR,
10820 "Failed to set FullBW_ULMUMIMO %d",
10821 set_val);
10822 send_resp(dut, conn, SIGMA_ERROR,
10823 "ErrorCode,Failed to set FullBW_ULMUMIMO");
10824 return STATUS_SENT_ERROR;
10825 }
10826 }
10827
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010828 val = get_param(cmd, "TWTInfoFrameTx");
10829 if (val) {
10830 if (strcasecmp(val, "Enable") == 0) {
10831 /* No-op */
10832 } else if (strcasecmp(val, "Disable") == 0) {
10833 /* No-op */
10834 } else {
10835 send_resp(dut, conn, SIGMA_ERROR,
10836 "ErrorCode,Invalid TWTInfoFrameTx");
10837 return STATUS_SENT_ERROR;
10838 }
10839 }
10840
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -070010841 val = get_param(cmd, "MU_EDCA");
10842 if (val && (strcasecmp(val, "Override") == 0)) {
10843 if (sta_set_mu_edca_override(dut, intf, 1)) {
10844 send_resp(dut, conn, SIGMA_ERROR,
10845 "ErrorCode,Failed to set MU EDCA override");
Jouni Malinen224e3902021-06-09 16:41:27 +030010846 return STATUS_SENT_ERROR;
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -070010847 }
10848 }
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -070010849
Kiran Kumar Lokerefa7c7b92021-08-09 00:50:55 -070010850 val = get_param(cmd, "PPDUTxType");
10851 if (val && strcasecmp(val, "ER-SU") == 0) {
10852 if (sta_set_er_su_ppdu_type_tx(dut, intf, 1)) {
10853 send_resp(dut, conn, SIGMA_ERROR,
10854 "ErrorCode,Failed to set ER-SU PPDU type Tx");
10855 return STATUS_SENT_ERROR;
10856 }
10857 }
10858
10859 val = get_param(cmd, "RUAllocTone");
10860 if (val && strcasecmp(val, "242") == 0) {
10861 if (sta_set_ru_242_tone_tx(dut, intf, 1)) {
10862 send_resp(dut, conn, SIGMA_ERROR,
10863 "ErrorCode,Failed to set RU 242 tone Tx");
10864 return STATUS_SENT_ERROR;
10865 }
10866 }
10867
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -070010868 val = get_param(cmd, "OMControl");
10869 if (val) {
10870 int set_val = 1;
10871
10872 if (strcasecmp(val, "Enable") == 0)
10873 set_val = 1;
10874 else if (strcasecmp(val, "Disable") == 0)
10875 set_val = 0;
10876
10877 if (sta_set_om_ctrl_supp(dut, intf, set_val)) {
10878 send_resp(dut, conn, SIGMA_ERROR,
10879 "ErrorCode,Failed to set OM ctrl supp");
Jouni Malinen224e3902021-06-09 16:41:27 +030010880 return STATUS_SENT_ERROR;
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -070010881 }
10882 }
10883
Kiran Kumar Lokere4f2d4b02021-04-01 00:07:39 -070010884 val = get_param(cmd, "BSSMaxIdlePeriod");
10885 if (val && sta_set_bss_max_idle_period(dut, intf, atoi(val))) {
10886 send_resp(dut, conn, SIGMA_ERROR,
10887 "ErrorCode,Failed to set BSS max idle period");
10888 return STATUS_SENT_ERROR;
10889 }
10890
Kiran Kumar Lokere07ad92b2021-08-09 00:27:14 -070010891 val = get_param(cmd, "BSS_max_idle");
10892 if (val) {
10893 int set_val = 0;
10894
10895 if (strcasecmp(val, "Enable") == 0)
10896 set_val = 1;
10897 else if (strcasecmp(val, "Disable") == 0)
10898 set_val = 0;
10899 if (sta_set_bss_max_idle_support(dut, intf, set_val)) {
10900 send_resp(dut, conn, SIGMA_ERROR,
10901 "ErrorCode,Failed to set BSS max idle support");
10902 return STATUS_SENT_ERROR;
10903 }
10904 }
10905
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -070010906 val = get_param(cmd, "ADDBAResp_BufSize");
10907 if (val) {
10908 int buf_size;
10909
10910 if (strcasecmp(val, "gt64") == 0)
10911 buf_size = 256;
10912 else
10913 buf_size = 64;
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010914 if (get_driver_type(dut) == DRIVER_WCN &&
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -070010915 sta_set_addba_buf_size(dut, intf, buf_size)) {
10916 send_resp(dut, conn, SIGMA_ERROR,
10917 "ErrorCode,set addbaresp_buff_size failed");
Jouni Malinen224e3902021-06-09 16:41:27 +030010918 return STATUS_SENT_ERROR;
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -070010919 }
10920 }
10921
10922 val = get_param(cmd, "ADDBAReq_BufSize");
10923 if (val) {
10924 int buf_size;
10925
10926 if (strcasecmp(val, "gt64") == 0)
10927 buf_size = 256;
10928 else
10929 buf_size = 64;
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010930 if (get_driver_type(dut) == DRIVER_WCN &&
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -070010931 sta_set_addba_buf_size(dut, intf, buf_size)) {
10932 send_resp(dut, conn, SIGMA_ERROR,
10933 "ErrorCode,set addbareq_buff_size failed");
Jouni Malinen224e3902021-06-09 16:41:27 +030010934 return STATUS_SENT_ERROR;
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -070010935 }
10936 }
10937
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010938 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
10939}
10940
10941
10942static int sta_set_wireless_60g(struct sigma_dut *dut,
10943 struct sigma_conn *conn,
10944 struct sigma_cmd *cmd)
10945{
10946 const char *dev_role = get_param(cmd, "DevRole");
10947
10948 if (!dev_role) {
10949 send_resp(dut, conn, SIGMA_INVALID,
10950 "ErrorCode,DevRole not specified");
10951 return 0;
10952 }
10953
10954 if (strcasecmp(dev_role, "PCP") == 0)
10955 return sta_set_60g_pcp(dut, conn, cmd);
10956 if (strcasecmp(dev_role, "STA") == 0)
10957 return sta_set_60g_sta(dut, conn, cmd);
10958 send_resp(dut, conn, SIGMA_INVALID,
10959 "ErrorCode,DevRole not supported");
10960 return 0;
10961}
10962
10963
Ankita Bajaj0d5825b2017-10-25 16:20:17 +053010964static int sta_set_wireless_oce(struct sigma_dut *dut, struct sigma_conn *conn,
10965 struct sigma_cmd *cmd)
10966{
10967 int status;
10968 const char *intf = get_param(cmd, "Interface");
10969 const char *val = get_param(cmd, "DevRole");
10970
10971 if (val && strcasecmp(val, "STA-CFON") == 0) {
10972 status = sta_cfon_set_wireless(dut, conn, cmd);
10973 if (status)
10974 return status;
10975 }
10976 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
10977}
10978
10979
Jouni Malinen67433fc2020-06-26 22:50:33 +030010980static enum sigma_cmd_result
10981sta_set_wireless_wpa3(struct sigma_dut *dut, struct sigma_conn *conn,
10982 struct sigma_cmd *cmd)
Vamsi Krishnac1633d22020-05-06 18:31:21 +053010983{
10984 const char *intf = get_param(cmd, "Interface");
10985 const char *val;
10986
10987 val = get_param(cmd, "ocvc");
10988 if (val)
10989 dut->ocvc = atoi(val);
10990
Jouni Malinen67433fc2020-06-26 22:50:33 +030010991 val = get_param(cmd, "ClientPrivacy");
Veerendranath Jakkam47867202020-12-21 01:53:52 +053010992 if (val && dut->client_privacy != atoi(val) &&
10993 sta_set_client_privacy(dut, conn, intf, atoi(val))) {
10994 send_resp(dut, conn, SIGMA_ERROR,
10995 "errorCode,Failed to configure random MAC address use");
10996 return STATUS_SENT_ERROR;
Jouni Malinen67433fc2020-06-26 22:50:33 +030010997 }
10998
Vamsi Krishnac1633d22020-05-06 18:31:21 +053010999 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
11000}
11001
11002
Jouni Malinenf7222712019-06-13 01:50:21 +030011003static enum sigma_cmd_result cmd_sta_set_wireless(struct sigma_dut *dut,
11004 struct sigma_conn *conn,
11005 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011006{
11007 const char *val;
11008
11009 val = get_param(cmd, "Program");
11010 if (val) {
11011 if (strcasecmp(val, "11n") == 0)
11012 return cmd_sta_set_11n(dut, conn, cmd);
Amarnath Hullur Subramanyam4f860292018-01-31 03:49:35 -080011013 if (strcasecmp(val, "VHT") == 0 || strcasecmp(val, "HE") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011014 return cmd_sta_set_wireless_vht(dut, conn, cmd);
11015 if (strcasecmp(val, "60ghz") == 0)
11016 return sta_set_wireless_60g(dut, conn, cmd);
Ankita Bajaj0d5825b2017-10-25 16:20:17 +053011017 if (strcasecmp(val, "OCE") == 0)
11018 return sta_set_wireless_oce(dut, conn, cmd);
Alexei Avshalom Lazar66bb9972018-12-18 16:01:43 +020011019 /* sta_set_wireless in WPS program is only used for 60G */
11020 if (is_60g_sigma_dut(dut))
11021 return sta_set_wireless_60g(dut, conn, cmd);
Vamsi Krishnac1633d22020-05-06 18:31:21 +053011022 if (strcasecmp(val, "WPA3") == 0)
11023 return sta_set_wireless_wpa3(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011024 send_resp(dut, conn, SIGMA_ERROR,
11025 "ErrorCode,Program value not supported");
11026 } else {
11027 send_resp(dut, conn, SIGMA_ERROR,
11028 "ErrorCode,Program argument not available");
11029 }
11030
11031 return 0;
11032}
11033
11034
11035static void ath_sta_inject_frame(struct sigma_dut *dut, const char *intf,
11036 int tid)
11037{
11038 char buf[100];
11039 int tid_to_dscp [] = { 0x00, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0 };
11040
Pradeep Reddy POTTETId31d1322016-10-13 17:22:03 +053011041 if (tid < 0 ||
11042 tid >= (int) (sizeof(tid_to_dscp) / sizeof(tid_to_dscp[0]))) {
11043 sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported TID: %d", tid);
11044 return;
11045 }
11046
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011047 /*
11048 * Two ways to ensure that addba request with a
11049 * non zero TID could be sent out. EV 117296
11050 */
11051 snprintf(buf, sizeof(buf),
11052 "ping -c 8 -Q %d `arp -a | grep wlan0 | awk '{print $2}' | tr -d '()'`",
11053 tid);
11054 if (system(buf) != 0) {
11055 sigma_dut_print(dut, DUT_MSG_ERROR,
11056 "Ping did not send out");
11057 }
11058
11059 snprintf(buf, sizeof(buf),
11060 "iwconfig %s | grep Access | awk '{print $6}' > %s",
11061 intf, VI_QOS_TMP_FILE);
11062 if (system(buf) != 0)
11063 return;
11064
11065 snprintf(buf, sizeof(buf),
11066 "ifconfig %s | grep HWaddr | cut -b 39-56 >> %s",
11067 intf, VI_QOS_TMP_FILE);
11068 if (system(buf) != 0)
11069 sigma_dut_print(dut, DUT_MSG_ERROR, "HWaddr matching failed");
11070
11071 snprintf(buf,sizeof(buf), "sed -n '3,$p' %s >> %s",
11072 VI_QOS_REFFILE, VI_QOS_TMP_FILE);
11073 if (system(buf) != 0) {
11074 sigma_dut_print(dut, DUT_MSG_ERROR,
11075 "VI_QOS_TEMP_FILE generation error failed");
11076 }
11077 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
11078 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
11079 if (system(buf) != 0) {
11080 sigma_dut_print(dut, DUT_MSG_ERROR,
11081 "VI_QOS_FILE generation failed");
11082 }
11083
11084 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
11085 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
11086 if (system(buf) != 0) {
11087 sigma_dut_print(dut, DUT_MSG_ERROR,
11088 "VI_QOS_FILE generation failed");
11089 }
11090
11091 snprintf(buf, sizeof(buf), "ethinject %s %s", intf, VI_QOS_FILE);
11092 if (system(buf) != 0) {
11093 }
11094}
11095
11096
11097static int ath_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
11098 struct sigma_cmd *cmd)
11099{
11100 const char *intf = get_param(cmd, "Interface");
11101 const char *val;
11102 int tid = 0;
11103 char buf[100];
11104
11105 val = get_param(cmd, "TID");
11106 if (val) {
11107 tid = atoi(val);
11108 if (tid)
11109 ath_sta_inject_frame(dut, intf, tid);
11110 }
11111
11112 /* Command sequence for ADDBA request on Peregrine based devices */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011113 run_iwpriv(dut, intf, "setaddbaoper 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011114
11115 snprintf(buf, sizeof(buf), "wifitool %s senddelba 1 %d 1 4", intf, tid);
11116 if (system(buf) != 0) {
11117 sigma_dut_print(dut, DUT_MSG_ERROR,
11118 "wifitool senddelba failed");
11119 }
11120
11121 snprintf(buf, sizeof(buf), "wifitool %s sendaddba 1 %d 64", intf, tid);
11122 if (system(buf) != 0) {
11123 sigma_dut_print(dut, DUT_MSG_ERROR,
11124 "wifitool sendaddba failed");
11125 }
11126
11127 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
11128
11129 return 1;
11130}
11131
11132
Lior David9981b512017-01-20 13:16:40 +020011133#ifdef __linux__
11134
11135static int wil6210_send_addba(struct sigma_dut *dut, const char *dest_mac,
11136 int agg_size)
11137{
11138 char dir[128], buf[128];
11139 FILE *f;
11140 regex_t re;
11141 regmatch_t m[2];
Jouni Malinen3aa72862019-05-29 23:14:51 +030011142 int rc, ret = -1, vring_id, found, res;
Lior David9981b512017-01-20 13:16:40 +020011143
11144 if (wil6210_get_debugfs_dir(dut, dir, sizeof(dir))) {
11145 sigma_dut_print(dut, DUT_MSG_ERROR,
11146 "failed to get wil6210 debugfs dir");
11147 return -1;
11148 }
11149
Jouni Malinen3aa72862019-05-29 23:14:51 +030011150 res = snprintf(buf, sizeof(buf), "%s/vrings", dir);
11151 if (res < 0 || res >= sizeof(buf))
11152 return -1;
Lior David9981b512017-01-20 13:16:40 +020011153 f = fopen(buf, "r");
11154 if (!f) {
11155 sigma_dut_print(dut, DUT_MSG_ERROR, "failed to open: %s", buf);
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +020011156 /* newer wil6210 driver renamed file to "rings" */
Jouni Malinen3aa72862019-05-29 23:14:51 +030011157 res = snprintf(buf, sizeof(buf), "%s/rings", dir);
11158 if (res < 0 || res >= sizeof(buf))
11159 return -1;
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +020011160 f = fopen(buf, "r");
11161 if (!f) {
11162 sigma_dut_print(dut, DUT_MSG_ERROR,
11163 "failed to open: %s", buf);
11164 return -1;
11165 }
Lior David9981b512017-01-20 13:16:40 +020011166 }
11167
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +020011168 /* can be either VRING tx... or RING... */
11169 if (regcomp(&re, "RING tx_[ \t]*([0-9]+)", REG_EXTENDED)) {
Lior David9981b512017-01-20 13:16:40 +020011170 sigma_dut_print(dut, DUT_MSG_ERROR, "regcomp failed");
11171 goto out;
11172 }
11173
11174 /* find TX VRING for the mac address */
11175 found = 0;
11176 while (fgets(buf, sizeof(buf), f)) {
11177 if (strcasestr(buf, dest_mac)) {
11178 found = 1;
11179 break;
11180 }
11181 }
11182
11183 if (!found) {
11184 sigma_dut_print(dut, DUT_MSG_ERROR,
11185 "no TX VRING for %s", dest_mac);
11186 goto out;
11187 }
11188
11189 /* extract VRING ID, "VRING tx_<id> = {" */
11190 if (!fgets(buf, sizeof(buf), f)) {
11191 sigma_dut_print(dut, DUT_MSG_ERROR,
11192 "no VRING start line for %s", dest_mac);
11193 goto out;
11194 }
11195
11196 rc = regexec(&re, buf, 2, m, 0);
11197 regfree(&re);
11198 if (rc || m[1].rm_so < 0) {
11199 sigma_dut_print(dut, DUT_MSG_ERROR,
11200 "no VRING TX ID for %s", dest_mac);
11201 goto out;
11202 }
11203 buf[m[1].rm_eo] = 0;
11204 vring_id = atoi(&buf[m[1].rm_so]);
11205
11206 /* send the addba command */
11207 fclose(f);
Jouni Malinen3aa72862019-05-29 23:14:51 +030011208 res = snprintf(buf, sizeof(buf), "%s/back", dir);
11209 if (res < 0 || res >= sizeof(buf))
11210 return -1;
Lior David9981b512017-01-20 13:16:40 +020011211 f = fopen(buf, "w");
11212 if (!f) {
11213 sigma_dut_print(dut, DUT_MSG_ERROR,
11214 "failed to open: %s", buf);
11215 return -1;
11216 }
11217
11218 fprintf(f, "add %d %d\n", vring_id, agg_size);
11219
11220 ret = 0;
11221
11222out:
11223 fclose(f);
11224
11225 return ret;
11226}
11227
11228
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +020011229int send_addba_60g(struct sigma_dut *dut, struct sigma_conn *conn,
11230 struct sigma_cmd *cmd, const char *mac_param)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011231{
11232 const char *val;
11233 int tid = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011234
11235 val = get_param(cmd, "TID");
11236 if (val) {
11237 tid = atoi(val);
11238 if (tid != 0) {
11239 sigma_dut_print(dut, DUT_MSG_ERROR,
11240 "Ignore TID %d for send_addba use TID 0 for 60g since only 0 required on TX",
11241 tid);
11242 }
11243 }
11244
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +020011245 val = get_param(cmd, mac_param);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011246 if (!val) {
11247 sigma_dut_print(dut, DUT_MSG_ERROR,
11248 "Currently not supporting addba for 60G without Dest_mac");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020011249 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011250 }
11251
Lior David9981b512017-01-20 13:16:40 +020011252 if (wil6210_send_addba(dut, val, dut->back_rcv_buf))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011253 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011254
11255 return 1;
11256}
11257
Lior David9981b512017-01-20 13:16:40 +020011258#endif /* __linux__ */
11259
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011260
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011261static int wcn_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
11262 struct sigma_cmd *cmd)
11263{
11264#ifdef NL80211_SUPPORT
11265 const char *intf = get_param(cmd, "Interface");
11266 const char *val;
11267 int tid = -1;
11268 int bufsize = 64;
11269 struct nl_msg *msg;
11270 int ret = 0;
11271 struct nlattr *params;
11272 int ifindex;
11273
11274 val = get_param(cmd, "TID");
11275 if (val)
11276 tid = atoi(val);
11277
11278 if (tid == -1) {
11279 send_resp(dut, conn, SIGMA_ERROR,
11280 "ErrorCode,sta_send_addba tid invalid");
11281 return 0;
11282 }
11283
11284 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
11285
11286 ifindex = if_nametoindex(intf);
11287 if (ifindex == 0) {
11288 sigma_dut_print(dut, DUT_MSG_ERROR,
11289 "%s: Index for interface %s failed",
11290 __func__, intf);
11291 send_resp(dut, conn, SIGMA_ERROR,
11292 "ErrorCode,sta_send_addba interface invalid");
11293 return 0;
11294 }
11295
11296 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
11297 NL80211_CMD_VENDOR)) ||
11298 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
11299 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
11300 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
11301 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
11302 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
11303 nla_put_u8(msg,
11304 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADD_DEL_BA_SESSION,
11305 QCA_WLAN_ADD_BA) ||
11306 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BA_TID,
11307 tid) ||
Kiran Kumar Lokere26e27582018-08-01 16:18:34 -070011308 nla_put_u16(msg,
11309 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE,
11310 bufsize)) {
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011311 sigma_dut_print(dut, DUT_MSG_ERROR,
11312 "%s: err in adding vendor_cmd and vendor_data",
11313 __func__);
11314 nlmsg_free(msg);
11315 send_resp(dut, conn, SIGMA_ERROR,
11316 "ErrorCode,sta_send_addba err in adding vendor_cmd and vendor_data");
11317 return 0;
11318 }
11319 nla_nest_end(msg, params);
11320
11321 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
11322 if (ret) {
11323 sigma_dut_print(dut, DUT_MSG_ERROR,
11324 "%s: err in send_and_recv_msgs, ret=%d",
11325 __func__, ret);
Sunil Dutt30605592018-05-04 20:35:50 +053011326 if (ret == -EOPNOTSUPP)
11327 return 1;
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011328 send_resp(dut, conn, SIGMA_ERROR,
11329 "ErrorCode,sta_send_addba err in send_and_recv_msgs");
11330 return 0;
11331 }
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011332#else /* NL80211_SUPPORT */
11333 sigma_dut_print(dut, DUT_MSG_ERROR,
11334 "sta_send_addba not supported without NL80211_SUPPORT defined");
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011335#endif /* NL80211_SUPPORT */
Sunil Dutt30605592018-05-04 20:35:50 +053011336
11337 return 1;
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011338}
11339
11340
Jouni Malinenf7222712019-06-13 01:50:21 +030011341static enum sigma_cmd_result cmd_sta_send_addba(struct sigma_dut *dut,
11342 struct sigma_conn *conn,
11343 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011344{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011345 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011346 case DRIVER_ATHEROS:
11347 return ath_sta_send_addba(dut, conn, cmd);
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011348 case DRIVER_WCN:
11349 return wcn_sta_send_addba(dut, conn, cmd);
Lior David9981b512017-01-20 13:16:40 +020011350#ifdef __linux__
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011351 case DRIVER_WIL6210:
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +020011352 return send_addba_60g(dut, conn, cmd, "Dest_mac");
Lior David9981b512017-01-20 13:16:40 +020011353#endif /* __linux__ */
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011354 default:
11355 /*
11356 * There is no driver specific implementation for other drivers.
11357 * Ignore the command and report COMPLETE since the following
11358 * throughput test operation will end up sending ADDBA anyway.
11359 */
11360 return 1;
11361 }
11362}
11363
11364
11365int inject_eth_frame(int s, const void *data, size_t len,
11366 unsigned short ethtype, char *dst, char *src)
11367{
11368 struct iovec iov[4] = {
11369 {
11370 .iov_base = dst,
11371 .iov_len = ETH_ALEN,
11372 },
11373 {
11374 .iov_base = src,
11375 .iov_len = ETH_ALEN,
11376 },
11377 {
11378 .iov_base = &ethtype,
11379 .iov_len = sizeof(unsigned short),
11380 },
11381 {
11382 .iov_base = (void *) data,
11383 .iov_len = len,
11384 }
11385 };
11386 struct msghdr msg = {
11387 .msg_name = NULL,
11388 .msg_namelen = 0,
11389 .msg_iov = iov,
11390 .msg_iovlen = 4,
11391 .msg_control = NULL,
11392 .msg_controllen = 0,
11393 .msg_flags = 0,
11394 };
11395
11396 return sendmsg(s, &msg, 0);
11397}
11398
11399#if defined(__linux__) || defined(__QNXNTO__)
11400
11401int inject_frame(int s, const void *data, size_t len, int encrypt)
11402{
11403#define IEEE80211_RADIOTAP_F_WEP 0x04
11404#define IEEE80211_RADIOTAP_F_FRAG 0x08
11405 unsigned char rtap_hdr[] = {
11406 0x00, 0x00, /* radiotap version */
11407 0x0e, 0x00, /* radiotap length */
11408 0x02, 0xc0, 0x00, 0x00, /* bmap: flags, tx and rx flags */
11409 IEEE80211_RADIOTAP_F_FRAG, /* F_FRAG (fragment if required) */
11410 0x00, /* padding */
11411 0x00, 0x00, /* RX and TX flags to indicate that */
11412 0x00, 0x00, /* this is the injected frame directly */
11413 };
11414 struct iovec iov[2] = {
11415 {
11416 .iov_base = &rtap_hdr,
11417 .iov_len = sizeof(rtap_hdr),
11418 },
11419 {
11420 .iov_base = (void *) data,
11421 .iov_len = len,
11422 }
11423 };
11424 struct msghdr msg = {
11425 .msg_name = NULL,
11426 .msg_namelen = 0,
11427 .msg_iov = iov,
11428 .msg_iovlen = 2,
11429 .msg_control = NULL,
11430 .msg_controllen = 0,
11431 .msg_flags = 0,
11432 };
11433
11434 if (encrypt)
11435 rtap_hdr[8] |= IEEE80211_RADIOTAP_F_WEP;
11436
11437 return sendmsg(s, &msg, 0);
11438}
11439
11440
11441int open_monitor(const char *ifname)
11442{
11443#ifdef __QNXNTO__
11444 struct sockaddr_dl ll;
11445 int s;
11446
11447 memset(&ll, 0, sizeof(ll));
11448 ll.sdl_family = AF_LINK;
11449 ll.sdl_index = if_nametoindex(ifname);
11450 if (ll.sdl_index == 0) {
11451 perror("if_nametoindex");
11452 return -1;
11453 }
11454 s = socket(PF_INET, SOCK_RAW, 0);
11455#else /* __QNXNTO__ */
11456 struct sockaddr_ll ll;
11457 int s;
11458
11459 memset(&ll, 0, sizeof(ll));
11460 ll.sll_family = AF_PACKET;
11461 ll.sll_ifindex = if_nametoindex(ifname);
11462 if (ll.sll_ifindex == 0) {
11463 perror("if_nametoindex");
11464 return -1;
11465 }
11466 s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
11467#endif /* __QNXNTO__ */
11468 if (s < 0) {
11469 perror("socket[PF_PACKET,SOCK_RAW]");
11470 return -1;
11471 }
11472
11473 if (bind(s, (struct sockaddr *) &ll, sizeof(ll)) < 0) {
11474 perror("monitor socket bind");
11475 close(s);
11476 return -1;
11477 }
11478
11479 return s;
11480}
11481
11482
11483static int hex2num(char c)
11484{
11485 if (c >= '0' && c <= '9')
11486 return c - '0';
11487 if (c >= 'a' && c <= 'f')
11488 return c - 'a' + 10;
11489 if (c >= 'A' && c <= 'F')
11490 return c - 'A' + 10;
11491 return -1;
11492}
11493
11494
11495int hwaddr_aton(const char *txt, unsigned char *addr)
11496{
11497 int i;
11498
11499 for (i = 0; i < 6; i++) {
11500 int a, b;
11501
11502 a = hex2num(*txt++);
11503 if (a < 0)
11504 return -1;
11505 b = hex2num(*txt++);
11506 if (b < 0)
11507 return -1;
11508 *addr++ = (a << 4) | b;
11509 if (i < 5 && *txt++ != ':')
11510 return -1;
11511 }
11512
11513 return 0;
11514}
11515
11516#endif /* defined(__linux__) || defined(__QNXNTO__) */
11517
Veerendranath Jakkam49774122020-07-05 09:52:18 +053011518
11519#ifdef NL80211_SUPPORT
11520static int nl80211_send_frame_cmd(struct sigma_dut *dut, const char *intf,
11521 const u8 *data, size_t data_len, int freq)
11522{
11523 struct nl_msg *msg;
11524 int ret = 0;
11525 int ifindex;
11526
11527 ifindex = if_nametoindex(intf);
11528 if (ifindex == 0) {
11529 sigma_dut_print(dut, DUT_MSG_ERROR,
11530 "%s: Index for interface %s failed",
11531 __func__, intf);
11532 return -1;
11533 }
11534
11535 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
11536 NL80211_CMD_FRAME)) ||
11537 (freq && nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq)) ||
11538 nla_put(msg, NL80211_ATTR_FRAME, data_len, data)) {
11539 sigma_dut_print(dut, DUT_MSG_ERROR,
11540 "%s: Error in adding NL80211_CMD_FRAME",
11541 __func__);
11542 nlmsg_free(msg);
11543 return -1;
11544 }
11545
11546 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
11547 if (ret) {
11548 sigma_dut_print(dut, DUT_MSG_ERROR,
11549 "nl80211: Frame command failed: ret=%d (%s) req=%u",
11550 ret, strerror(-ret), freq);
11551 return -1;
11552 }
11553
11554 return 0;
11555}
11556#endif /* NL80211_SUPPORT */
11557
11558
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011559enum send_frame_type {
11560 DISASSOC, DEAUTH, SAQUERY, AUTH, ASSOCREQ, REASSOCREQ, DLS_REQ
11561};
11562enum send_frame_protection {
11563 CORRECT_KEY, INCORRECT_KEY, UNPROTECTED
11564};
11565
11566
11567static int sta_inject_frame(struct sigma_dut *dut, struct sigma_conn *conn,
Veerendranath Jakkam49774122020-07-05 09:52:18 +053011568 const char *intf, enum send_frame_type frame,
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011569 enum send_frame_protection protected,
Veerendranath Jakkam49774122020-07-05 09:52:18 +053011570 const char *dest, int use_monitor)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011571{
11572#ifdef __linux__
11573 unsigned char buf[1000], *pos;
11574 int s, res;
11575 char bssid[20], addr[20];
11576 char result[32], ssid[100];
11577 size_t ssid_len;
11578
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011579 if (get_wpa_status(get_station_ifname(dut), "wpa_state", result,
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011580 sizeof(result)) < 0 ||
11581 strncmp(result, "COMPLETED", 9) != 0) {
11582 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Not connected");
11583 return 0;
11584 }
11585
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011586 if (get_wpa_status(get_station_ifname(dut), "bssid",
11587 bssid, sizeof(bssid)) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011588 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
11589 "current BSSID");
11590 return 0;
11591 }
11592
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011593 if (get_wpa_status(get_station_ifname(dut), "address",
11594 addr, sizeof(addr)) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011595 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
11596 "own MAC address");
11597 return 0;
11598 }
11599
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011600 if (get_wpa_status(get_station_ifname(dut), "ssid", ssid, sizeof(ssid))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011601 < 0) {
11602 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
11603 "current SSID");
11604 return 0;
11605 }
11606 ssid_len = strlen(ssid);
11607
11608 pos = buf;
11609
11610 /* Frame Control */
11611 switch (frame) {
11612 case DISASSOC:
11613 *pos++ = 0xa0;
11614 break;
11615 case DEAUTH:
11616 *pos++ = 0xc0;
11617 break;
11618 case SAQUERY:
11619 *pos++ = 0xd0;
11620 break;
11621 case AUTH:
11622 *pos++ = 0xb0;
11623 break;
11624 case ASSOCREQ:
11625 *pos++ = 0x00;
11626 break;
11627 case REASSOCREQ:
11628 *pos++ = 0x20;
11629 break;
11630 case DLS_REQ:
11631 *pos++ = 0xd0;
11632 break;
11633 }
11634
11635 if (protected == INCORRECT_KEY)
11636 *pos++ = 0x40; /* Set Protected field to 1 */
11637 else
11638 *pos++ = 0x00;
11639
11640 /* Duration */
11641 *pos++ = 0x00;
11642 *pos++ = 0x00;
11643
11644 /* addr1 = DA (current AP) */
11645 hwaddr_aton(bssid, pos);
11646 pos += 6;
11647 /* addr2 = SA (own address) */
11648 hwaddr_aton(addr, pos);
11649 pos += 6;
11650 /* addr3 = BSSID (current AP) */
11651 hwaddr_aton(bssid, pos);
11652 pos += 6;
11653
11654 /* Seq# (to be filled by driver/mac80211) */
11655 *pos++ = 0x00;
11656 *pos++ = 0x00;
11657
11658 if (protected == INCORRECT_KEY) {
11659 /* CCMP parameters */
11660 memcpy(pos, "\x61\x01\x00\x20\x00\x10\x00\x00", 8);
11661 pos += 8;
11662 }
11663
11664 if (protected == INCORRECT_KEY) {
11665 switch (frame) {
11666 case DEAUTH:
11667 /* Reason code (encrypted) */
11668 memcpy(pos, "\xa7\x39", 2);
11669 pos += 2;
11670 break;
11671 case DISASSOC:
11672 /* Reason code (encrypted) */
11673 memcpy(pos, "\xa7\x39", 2);
11674 pos += 2;
11675 break;
11676 case SAQUERY:
11677 /* Category|Action|TransID (encrypted) */
11678 memcpy(pos, "\x6f\xbd\xe9\x4d", 4);
11679 pos += 4;
11680 break;
11681 default:
11682 return -1;
11683 }
11684
11685 /* CCMP MIC */
11686 memcpy(pos, "\xc8\xd8\x3b\x06\x5d\xb7\x25\x68", 8);
11687 pos += 8;
11688 } else {
11689 switch (frame) {
11690 case DEAUTH:
11691 /* reason code = 8 */
11692 *pos++ = 0x08;
11693 *pos++ = 0x00;
11694 break;
11695 case DISASSOC:
11696 /* reason code = 8 */
11697 *pos++ = 0x08;
11698 *pos++ = 0x00;
11699 break;
11700 case SAQUERY:
11701 /* Category - SA Query */
11702 *pos++ = 0x08;
11703 /* SA query Action - Request */
11704 *pos++ = 0x00;
11705 /* Transaction ID */
11706 *pos++ = 0x12;
11707 *pos++ = 0x34;
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +053011708 if (dut->saquery_oci_freq) {
11709 /* OCI IE - Extended ID */
11710 *pos++ = 0xFF;
11711 *pos++ = 0x04;
11712 *pos++ = 0x36;
11713 /* Operating Class */
11714 *pos++ = 0x74;
11715 /* Primary Channel */
11716 *pos++ = freq_to_channel(dut->saquery_oci_freq);
11717 /* Frequency Segment 1 Channel Number */
11718 *pos++ = 0x00;
11719 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011720 break;
11721 case AUTH:
11722 /* Auth Alg (Open) */
11723 *pos++ = 0x00;
11724 *pos++ = 0x00;
11725 /* Seq# */
11726 *pos++ = 0x01;
11727 *pos++ = 0x00;
11728 /* Status code */
11729 *pos++ = 0x00;
11730 *pos++ = 0x00;
11731 break;
11732 case ASSOCREQ:
11733 /* Capability Information */
11734 *pos++ = 0x31;
11735 *pos++ = 0x04;
11736 /* Listen Interval */
11737 *pos++ = 0x0a;
11738 *pos++ = 0x00;
11739 /* SSID */
11740 *pos++ = 0x00;
11741 *pos++ = ssid_len;
11742 memcpy(pos, ssid, ssid_len);
11743 pos += ssid_len;
11744 /* Supported Rates */
11745 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
11746 10);
11747 pos += 10;
11748 /* Extended Supported Rates */
11749 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
11750 pos += 6;
11751 /* RSN */
11752 memcpy(pos, "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00"
11753 "\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x02\xc0"
11754 "\x00\x00\x00\x00\x0f\xac\x06", 28);
11755 pos += 28;
11756 break;
11757 case REASSOCREQ:
11758 /* Capability Information */
11759 *pos++ = 0x31;
11760 *pos++ = 0x04;
11761 /* Listen Interval */
11762 *pos++ = 0x0a;
11763 *pos++ = 0x00;
11764 /* Current AP */
11765 hwaddr_aton(bssid, pos);
11766 pos += 6;
11767 /* SSID */
11768 *pos++ = 0x00;
11769 *pos++ = ssid_len;
11770 memcpy(pos, ssid, ssid_len);
11771 pos += ssid_len;
11772 /* Supported Rates */
11773 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
11774 10);
11775 pos += 10;
11776 /* Extended Supported Rates */
11777 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
11778 pos += 6;
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +053011779 /* RSNE - Group and Pairwise ciphers */
11780 memcpy(pos,
11781 "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04",
11782 14);
11783 pos += 14;
11784 /* RSNE - AKM Suite count */
11785 *pos++ = 0x01;
11786 *pos++ = 0x00;
11787 /* RSNE - AKM Suites */
11788 if (dut->program == PROGRAM_WPA3)
11789 memcpy(pos, "\x00\x0f\xac\x08", 4);
11790 else
11791 memcpy(pos, "\x00\x0f\xac\x02", 4);
11792 pos += 4;
11793 /* RSNE - Capabilities */
11794 *pos++ = 0xc0;
11795 if (dut->ocvc)
11796 *pos++ = 0x40;
11797 else
11798 *pos++ = 0x00;
11799 /* RSNE - PMKID list and Group Management Ciphers */
11800 memcpy(pos, "\x00\x00\x00\x0f\xac\x06", 6);
11801 pos += 6;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011802 break;
11803 case DLS_REQ:
11804 /* Category - DLS */
11805 *pos++ = 0x02;
11806 /* DLS Action - Request */
11807 *pos++ = 0x00;
11808 /* Destination MACAddress */
11809 if (dest)
11810 hwaddr_aton(dest, pos);
11811 else
11812 memset(pos, 0, 6);
11813 pos += 6;
11814 /* Source MACAddress */
11815 hwaddr_aton(addr, pos);
11816 pos += 6;
11817 /* Capability Information */
11818 *pos++ = 0x10; /* Privacy */
11819 *pos++ = 0x06; /* QoS */
11820 /* DLS Timeout Value */
11821 *pos++ = 0x00;
11822 *pos++ = 0x01;
11823 /* Supported rates */
11824 *pos++ = 0x01;
11825 *pos++ = 0x08;
11826 *pos++ = 0x0c; /* 6 Mbps */
11827 *pos++ = 0x12; /* 9 Mbps */
11828 *pos++ = 0x18; /* 12 Mbps */
11829 *pos++ = 0x24; /* 18 Mbps */
11830 *pos++ = 0x30; /* 24 Mbps */
11831 *pos++ = 0x48; /* 36 Mbps */
11832 *pos++ = 0x60; /* 48 Mbps */
11833 *pos++ = 0x6c; /* 54 Mbps */
11834 /* TODO: Extended Supported Rates */
11835 /* TODO: HT Capabilities */
11836 break;
11837 }
11838 }
11839
Veerendranath Jakkam49774122020-07-05 09:52:18 +053011840 if (use_monitor) {
11841 s = open_monitor("sigmadut");
11842 if (s < 0) {
11843 send_resp(dut, conn, SIGMA_ERROR,
11844 "errorCode,Failed to open monitor socket");
11845 return 0;
11846 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011847
Veerendranath Jakkam49774122020-07-05 09:52:18 +053011848 res = inject_frame(s, buf, pos - buf, protected == CORRECT_KEY);
11849 if (res < 0) {
11850 send_resp(dut, conn, SIGMA_ERROR,
11851 "errorCode,Failed to inject frame");
11852 close(s);
11853 return 0;
11854 }
11855 if (res < pos - buf) {
11856 send_resp(dut, conn, SIGMA_ERROR,
11857 "errorCode,Only partial frame sent");
11858 close(s);
11859 return 0;
11860 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011861
Veerendranath Jakkam49774122020-07-05 09:52:18 +053011862 close(s);
11863 } else {
11864#ifdef NL80211_SUPPORT
11865 int freq;
11866 char freq_str[10];
11867
11868 if (get_wpa_status(get_station_ifname(dut), "freq",
11869 freq_str, sizeof(freq_str)) < 0) {
11870 send_resp(dut, conn, SIGMA_ERROR,
11871 "errorCode,Could not get current operating frequency");
11872 return 0;
11873 }
11874 freq = atoi(freq_str);
11875
11876 if (nl80211_send_frame_cmd(dut, intf, buf, pos - buf, freq)) {
11877 send_resp(dut, conn, SIGMA_ERROR,
11878 "errorCode,Failed to inject frame");
11879 return 0;
11880 }
11881#else /* NL80211_SUPPORT */
11882 send_resp(dut, conn, SIGMA_ERROR,
11883 "errorCode,Failed to inject frame (no NL80211_SUPPORT)");
11884 return 0;
11885#endif /* NL80211_SUPPORT */
11886 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011887
11888 return 1;
11889#else /* __linux__ */
11890 send_resp(dut, conn, SIGMA_ERROR, "errorCode,sta_send_frame not "
11891 "yet supported");
11892 return 0;
11893#endif /* __linux__ */
11894}
11895
11896
11897static int cmd_sta_send_frame_tdls(struct sigma_dut *dut,
11898 struct sigma_conn *conn,
11899 struct sigma_cmd *cmd)
11900{
11901 const char *intf = get_param(cmd, "Interface");
11902 const char *sta, *val;
11903 unsigned char addr[ETH_ALEN];
11904 char buf[100];
11905
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +030011906 if (!intf)
11907 return -1;
11908
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011909 sta = get_param(cmd, "peer");
11910 if (sta == NULL)
11911 sta = get_param(cmd, "station");
11912 if (sta == NULL) {
11913 send_resp(dut, conn, SIGMA_ERROR,
11914 "ErrorCode,Missing peer address");
11915 return 0;
11916 }
11917 if (hwaddr_aton(sta, addr) < 0) {
11918 send_resp(dut, conn, SIGMA_ERROR,
11919 "ErrorCode,Invalid peer address");
11920 return 0;
11921 }
11922
11923 val = get_param(cmd, "type");
11924 if (val == NULL)
11925 return -1;
11926
11927 if (strcasecmp(val, "DISCOVERY") == 0) {
11928 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", sta);
11929 if (wpa_command(intf, buf) < 0) {
11930 send_resp(dut, conn, SIGMA_ERROR,
11931 "ErrorCode,Failed to send TDLS discovery");
11932 return 0;
11933 }
11934 return 1;
11935 }
11936
11937 if (strcasecmp(val, "SETUP") == 0) {
11938 int status = 0, timeout = 0;
11939
11940 val = get_param(cmd, "Status");
11941 if (val)
11942 status = atoi(val);
11943
11944 val = get_param(cmd, "Timeout");
11945 if (val)
11946 timeout = atoi(val);
11947
11948 if (status != 0 && status != 37) {
11949 send_resp(dut, conn, SIGMA_ERROR,
11950 "ErrorCode,Unsupported status value");
11951 return 0;
11952 }
11953
11954 if (timeout != 0 && timeout != 301) {
11955 send_resp(dut, conn, SIGMA_ERROR,
11956 "ErrorCode,Unsupported timeout value");
11957 return 0;
11958 }
11959
11960 if (status && timeout) {
11961 send_resp(dut, conn, SIGMA_ERROR,
11962 "ErrorCode,Unsupported timeout+status "
11963 "combination");
11964 return 0;
11965 }
11966
11967 if (status == 37 &&
11968 wpa_command(intf, "SET tdls_testing 0x200")) {
11969 send_resp(dut, conn, SIGMA_ERROR,
11970 "ErrorCode,Failed to enable "
11971 "decline setup response test mode");
11972 return 0;
11973 }
11974
11975 if (timeout == 301) {
11976 int res;
11977 if (dut->no_tpk_expiration)
11978 res = wpa_command(intf,
11979 "SET tdls_testing 0x108");
11980 else
11981 res = wpa_command(intf,
11982 "SET tdls_testing 0x8");
11983 if (res) {
11984 send_resp(dut, conn, SIGMA_ERROR,
11985 "ErrorCode,Failed to set short TPK "
11986 "lifetime");
11987 return 0;
11988 }
11989 }
11990
11991 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", sta);
11992 if (wpa_command(intf, buf) < 0) {
11993 send_resp(dut, conn, SIGMA_ERROR,
11994 "ErrorCode,Failed to send TDLS setup");
11995 return 0;
11996 }
11997 return 1;
11998 }
11999
12000 if (strcasecmp(val, "TEARDOWN") == 0) {
12001 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", sta);
12002 if (wpa_command(intf, buf) < 0) {
12003 send_resp(dut, conn, SIGMA_ERROR,
12004 "ErrorCode,Failed to send TDLS teardown");
12005 return 0;
12006 }
12007 return 1;
12008 }
12009
12010 send_resp(dut, conn, SIGMA_ERROR,
12011 "ErrorCode,Unsupported TDLS frame");
12012 return 0;
12013}
12014
12015
12016static int sta_ap_known(const char *ifname, const char *bssid)
12017{
12018 char buf[4096];
12019
Jouni Malinendd32f192018-09-15 02:55:19 +030012020 snprintf(buf, sizeof(buf), "BSS MASK=1 %s", bssid);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012021 if (wpa_command_resp(ifname, buf, buf, sizeof(buf)) < 0)
12022 return 0;
12023 if (strncmp(buf, "id=", 3) != 0)
12024 return 0;
12025 return 1;
12026}
12027
12028
12029static int sta_scan_ap(struct sigma_dut *dut, const char *ifname,
12030 const char *bssid)
12031{
12032 int res;
12033 struct wpa_ctrl *ctrl;
12034 char buf[256];
12035
12036 if (sta_ap_known(ifname, bssid))
12037 return 0;
12038 sigma_dut_print(dut, DUT_MSG_DEBUG,
12039 "AP not in BSS table - start scan");
12040
12041 ctrl = open_wpa_mon(ifname);
12042 if (ctrl == NULL) {
12043 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
12044 "wpa_supplicant monitor connection");
12045 return -1;
12046 }
12047
12048 if (wpa_command(ifname, "SCAN") < 0) {
12049 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to start scan");
12050 wpa_ctrl_detach(ctrl);
12051 wpa_ctrl_close(ctrl);
12052 return -1;
12053 }
12054
12055 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
12056 buf, sizeof(buf));
12057
12058 wpa_ctrl_detach(ctrl);
12059 wpa_ctrl_close(ctrl);
12060
12061 if (res < 0) {
12062 sigma_dut_print(dut, DUT_MSG_INFO, "Scan did not complete");
12063 return -1;
12064 }
12065
12066 if (sta_ap_known(ifname, bssid))
12067 return 0;
12068 sigma_dut_print(dut, DUT_MSG_INFO, "AP not in BSS table");
12069 return -1;
12070}
12071
12072
12073static int cmd_sta_send_frame_hs2_neighadv(struct sigma_dut *dut,
12074 struct sigma_conn *conn,
12075 struct sigma_cmd *cmd,
12076 const char *intf)
12077{
12078 char buf[200];
12079
12080 snprintf(buf, sizeof(buf), "ndsend 2001:DB8::1 %s", intf);
12081 if (system(buf) != 0) {
12082 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Failed to run "
12083 "ndsend");
12084 return 0;
12085 }
12086
12087 return 1;
12088}
12089
12090
12091static int cmd_sta_send_frame_hs2_neighsolreq(struct sigma_dut *dut,
12092 struct sigma_conn *conn,
12093 struct sigma_cmd *cmd,
12094 const char *intf)
12095{
12096 char buf[200];
12097 const char *ip = get_param(cmd, "SenderIP");
12098
Peng Xu26b356d2017-10-04 17:58:16 -070012099 if (!ip)
12100 return 0;
12101
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012102 snprintf(buf, sizeof(buf), "ndisc6 -nm %s %s -r 4", ip, intf);
12103 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
12104 if (system(buf) == 0) {
12105 sigma_dut_print(dut, DUT_MSG_INFO,
12106 "Neighbor Solicitation got a response "
12107 "for %s@%s", ip, intf);
12108 }
12109
12110 return 1;
12111}
12112
12113
12114static int cmd_sta_send_frame_hs2_arpprobe(struct sigma_dut *dut,
12115 struct sigma_conn *conn,
12116 struct sigma_cmd *cmd,
12117 const char *ifname)
12118{
12119 char buf[200];
12120 const char *ip = get_param(cmd, "SenderIP");
12121
12122 if (ip == NULL) {
12123 send_resp(dut, conn, SIGMA_ERROR,
12124 "ErrorCode,Missing SenderIP parameter");
12125 return 0;
12126 }
12127 snprintf(buf, sizeof(buf), "arping -I %s -D %s -c 4", ifname, ip);
12128 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
12129 if (system(buf) != 0) {
12130 sigma_dut_print(dut, DUT_MSG_INFO, "arping DAD got a response "
12131 "for %s@%s", ip, ifname);
12132 }
12133
12134 return 1;
12135}
12136
12137
12138static int cmd_sta_send_frame_hs2_arpannounce(struct sigma_dut *dut,
12139 struct sigma_conn *conn,
12140 struct sigma_cmd *cmd,
12141 const char *ifname)
12142{
12143 char buf[200];
12144 char ip[16];
12145 int s;
Peng Xub3756882017-10-04 14:39:09 -070012146 struct ifreq ifr;
12147 struct sockaddr_in saddr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012148
12149 s = socket(PF_INET, SOCK_DGRAM, 0);
Peng Xub3756882017-10-04 14:39:09 -070012150 if (s < 0) {
12151 perror("socket");
12152 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012153 }
12154
Peng Xub3756882017-10-04 14:39:09 -070012155 memset(&ifr, 0, sizeof(ifr));
12156 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
12157 if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
12158 sigma_dut_print(dut, DUT_MSG_INFO,
12159 "Failed to get %s IP address: %s",
12160 ifname, strerror(errno));
12161 close(s);
12162 return -1;
12163 }
12164 close(s);
12165
12166 memcpy(&saddr, &ifr.ifr_addr, sizeof(struct sockaddr_in));
12167 strlcpy(ip, inet_ntoa(saddr.sin_addr), sizeof(ip));
12168
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012169 snprintf(buf, sizeof(buf), "arping -I %s -s %s %s -c 4", ifname, ip,
12170 ip);
12171 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
12172 if (system(buf) != 0) {
12173 }
12174
12175 return 1;
12176}
12177
12178
12179static int cmd_sta_send_frame_hs2_arpreply(struct sigma_dut *dut,
12180 struct sigma_conn *conn,
12181 struct sigma_cmd *cmd,
12182 const char *ifname)
12183{
12184 char buf[200], addr[20];
12185 char dst[ETH_ALEN], src[ETH_ALEN];
12186 short ethtype = htons(ETH_P_ARP);
12187 char *pos;
12188 int s, res;
12189 const char *val;
12190 struct sockaddr_in taddr;
12191
12192 val = get_param(cmd, "dest");
12193 if (val)
12194 hwaddr_aton(val, (unsigned char *) dst);
12195
12196 val = get_param(cmd, "DestIP");
12197 if (val)
12198 inet_aton(val, &taddr.sin_addr);
Peng Xu151c9e12017-10-04 14:39:09 -070012199 else
12200 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012201
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012202 if (get_wpa_status(get_station_ifname(dut), "address", addr,
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012203 sizeof(addr)) < 0)
12204 return -2;
12205 hwaddr_aton(addr, (unsigned char *) src);
12206
12207 pos = buf;
12208 *pos++ = 0x00;
12209 *pos++ = 0x01;
12210 *pos++ = 0x08;
12211 *pos++ = 0x00;
12212 *pos++ = 0x06;
12213 *pos++ = 0x04;
12214 *pos++ = 0x00;
12215 *pos++ = 0x02;
12216 memcpy(pos, src, ETH_ALEN);
12217 pos += ETH_ALEN;
12218 memcpy(pos, &taddr.sin_addr, 4);
12219 pos += 4;
12220 memcpy(pos, dst, ETH_ALEN);
12221 pos += ETH_ALEN;
12222 memcpy(pos, &taddr.sin_addr, 4);
12223 pos += 4;
12224
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012225 s = open_monitor(get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012226 if (s < 0) {
12227 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
12228 "monitor socket");
12229 return 0;
12230 }
12231
12232 res = inject_eth_frame(s, buf, pos - buf, ethtype, dst, src);
12233 if (res < 0) {
12234 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
12235 "inject frame");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +053012236 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012237 return 0;
12238 }
12239
12240 close(s);
12241
12242 return 1;
12243}
12244
12245
12246static int cmd_sta_send_frame_hs2_dls_req(struct sigma_dut *dut,
12247 struct sigma_conn *conn,
12248 struct sigma_cmd *cmd,
12249 const char *intf, const char *dest)
12250{
12251 char buf[100];
12252
12253 if (if_nametoindex("sigmadut") == 0) {
12254 snprintf(buf, sizeof(buf),
12255 "iw dev %s interface add sigmadut type monitor",
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012256 get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012257 if (system(buf) != 0 ||
12258 if_nametoindex("sigmadut") == 0) {
12259 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
12260 "monitor interface with '%s'", buf);
12261 return -2;
12262 }
12263 }
12264
12265 if (system("ifconfig sigmadut up") != 0) {
12266 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
12267 "monitor interface up");
12268 return -2;
12269 }
12270
Veerendranath Jakkam49774122020-07-05 09:52:18 +053012271 return sta_inject_frame(dut, conn, intf, DLS_REQ, UNPROTECTED, dest, 1);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012272}
12273
12274
12275static int cmd_sta_send_frame_hs2(struct sigma_dut *dut,
12276 struct sigma_conn *conn,
12277 struct sigma_cmd *cmd)
12278{
12279 const char *intf = get_param(cmd, "Interface");
12280 const char *dest = get_param(cmd, "Dest");
12281 const char *type = get_param(cmd, "FrameName");
12282 const char *val;
12283 char buf[200], *pos, *end;
12284 int count, count2;
12285
12286 if (type == NULL)
12287 type = get_param(cmd, "Type");
12288
12289 if (intf == NULL || dest == NULL || type == NULL)
12290 return -1;
12291
12292 if (strcasecmp(type, "NeighAdv") == 0)
12293 return cmd_sta_send_frame_hs2_neighadv(dut, conn, cmd, intf);
12294
12295 if (strcasecmp(type, "NeighSolicitReq") == 0)
12296 return cmd_sta_send_frame_hs2_neighsolreq(dut, conn, cmd, intf);
12297
12298 if (strcasecmp(type, "ARPProbe") == 0)
12299 return cmd_sta_send_frame_hs2_arpprobe(dut, conn, cmd, intf);
12300
12301 if (strcasecmp(type, "ARPAnnounce") == 0)
12302 return cmd_sta_send_frame_hs2_arpannounce(dut, conn, cmd, intf);
12303
12304 if (strcasecmp(type, "ARPReply") == 0)
12305 return cmd_sta_send_frame_hs2_arpreply(dut, conn, cmd, intf);
12306
12307 if (strcasecmp(type, "DLS-request") == 0 ||
12308 strcasecmp(type, "DLSrequest") == 0)
12309 return cmd_sta_send_frame_hs2_dls_req(dut, conn, cmd, intf,
12310 dest);
12311
12312 if (strcasecmp(type, "ANQPQuery") != 0 &&
12313 strcasecmp(type, "Query") != 0) {
12314 send_resp(dut, conn, SIGMA_ERROR,
12315 "ErrorCode,Unsupported HS 2.0 send frame type");
12316 return 0;
12317 }
12318
12319 if (sta_scan_ap(dut, intf, dest) < 0) {
12320 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not find "
12321 "the requested AP");
12322 return 0;
12323 }
12324
12325 pos = buf;
12326 end = buf + sizeof(buf);
12327 count = 0;
12328 pos += snprintf(pos, end - pos, "ANQP_GET %s ", dest);
12329
12330 val = get_param(cmd, "ANQP_CAP_LIST");
12331 if (val && atoi(val)) {
12332 pos += snprintf(pos, end - pos, "%s257", count > 0 ? "," : "");
12333 count++;
12334 }
12335
12336 val = get_param(cmd, "VENUE_NAME");
12337 if (val && atoi(val)) {
12338 pos += snprintf(pos, end - pos, "%s258", count > 0 ? "," : "");
12339 count++;
12340 }
12341
12342 val = get_param(cmd, "NETWORK_AUTH_TYPE");
12343 if (val && atoi(val)) {
12344 pos += snprintf(pos, end - pos, "%s260", count > 0 ? "," : "");
12345 count++;
12346 }
12347
12348 val = get_param(cmd, "ROAMING_CONS");
12349 if (val && atoi(val)) {
12350 pos += snprintf(pos, end - pos, "%s261", count > 0 ? "," : "");
12351 count++;
12352 }
12353
12354 val = get_param(cmd, "IP_ADDR_TYPE_AVAILABILITY");
12355 if (val && atoi(val)) {
12356 pos += snprintf(pos, end - pos, "%s262", count > 0 ? "," : "");
12357 count++;
12358 }
12359
12360 val = get_param(cmd, "NAI_REALM_LIST");
12361 if (val && atoi(val)) {
12362 pos += snprintf(pos, end - pos, "%s263", count > 0 ? "," : "");
12363 count++;
12364 }
12365
12366 val = get_param(cmd, "3GPP_INFO");
12367 if (val && atoi(val)) {
12368 pos += snprintf(pos, end - pos, "%s264", count > 0 ? "," : "");
12369 count++;
12370 }
12371
12372 val = get_param(cmd, "DOMAIN_LIST");
12373 if (val && atoi(val)) {
12374 pos += snprintf(pos, end - pos, "%s268", count > 0 ? "," : "");
12375 count++;
12376 }
12377
Jouni Malinen34cf9532018-04-29 19:26:33 +030012378 val = get_param(cmd, "Venue_URL");
12379 if (val && atoi(val)) {
12380 pos += snprintf(pos, end - pos, "%s277", count > 0 ? "," : "");
12381 count++;
12382 }
12383
Jouni Malinend3bca5d2018-04-29 17:25:23 +030012384 val = get_param(cmd, "Advice_Of_Charge");
12385 if (val && atoi(val)) {
12386 pos += snprintf(pos, end - pos, "%s278", count > 0 ? "," : "");
12387 count++;
12388 }
12389
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012390 if (count && wpa_command(intf, buf)) {
12391 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,ANQP_GET failed");
12392 return 0;
12393 }
12394
12395 pos = buf;
12396 end = buf + sizeof(buf);
12397 count2 = 0;
12398 pos += snprintf(pos, end - pos, "HS20_ANQP_GET %s ", dest);
12399
12400 val = get_param(cmd, "HS_CAP_LIST");
12401 if (val && atoi(val)) {
12402 pos += snprintf(pos, end - pos, "%s2", count2 > 0 ? "," : "");
12403 count2++;
12404 }
12405
12406 val = get_param(cmd, "OPER_NAME");
12407 if (val && atoi(val)) {
12408 pos += snprintf(pos, end - pos, "%s3", count2 > 0 ? "," : "");
12409 count2++;
12410 }
12411
12412 val = get_param(cmd, "WAN_METRICS");
12413 if (!val)
12414 val = get_param(cmd, "WAN_MAT");
12415 if (!val)
12416 val = get_param(cmd, "WAN_MET");
12417 if (val && atoi(val)) {
12418 pos += snprintf(pos, end - pos, "%s4", count2 > 0 ? "," : "");
12419 count2++;
12420 }
12421
12422 val = get_param(cmd, "CONNECTION_CAPABILITY");
12423 if (val && atoi(val)) {
12424 pos += snprintf(pos, end - pos, "%s5", count2 > 0 ? "," : "");
12425 count2++;
12426 }
12427
12428 val = get_param(cmd, "OP_CLASS");
12429 if (val && atoi(val)) {
12430 pos += snprintf(pos, end - pos, "%s7", count2 > 0 ? "," : "");
12431 count2++;
12432 }
12433
12434 val = get_param(cmd, "OSU_PROVIDER_LIST");
12435 if (val && atoi(val)) {
12436 pos += snprintf(pos, end - pos, "%s8", count2 > 0 ? "," : "");
12437 count2++;
12438 }
12439
Jouni Malinenf67afec2018-04-29 19:24:58 +030012440 val = get_param(cmd, "OPER_ICON_METADATA");
12441 if (!val)
12442 val = get_param(cmd, "OPERATOR_ICON_METADATA");
12443 if (val && atoi(val)) {
12444 pos += snprintf(pos, end - pos, "%s12", count2 > 0 ? "," : "");
12445 count2++;
12446 }
12447
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012448 if (count && count2) {
12449 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before sending out "
12450 "second query");
12451 sleep(1);
12452 }
12453
12454 if (count2 && wpa_command(intf, buf)) {
12455 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,HS20_ANQP_GET "
12456 "failed");
12457 return 0;
12458 }
12459
12460 val = get_param(cmd, "NAI_HOME_REALM_LIST");
12461 if (val) {
12462 if (count || count2) {
12463 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
12464 "sending out second query");
12465 sleep(1);
12466 }
12467
12468 if (strcmp(val, "1") == 0)
12469 val = "mail.example.com";
12470 snprintf(buf, end - pos,
12471 "HS20_GET_NAI_HOME_REALM_LIST %s realm=%s",
12472 dest, val);
12473 if (wpa_command(intf, buf)) {
12474 send_resp(dut, conn, SIGMA_ERROR,
12475 "ErrorCode,HS20_GET_NAI_HOME_REALM_LIST "
12476 "failed");
12477 return 0;
12478 }
12479 }
12480
12481 val = get_param(cmd, "ICON_REQUEST");
12482 if (val) {
12483 if (count || count2) {
12484 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
12485 "sending out second query");
12486 sleep(1);
12487 }
12488
12489 snprintf(buf, end - pos,
12490 "HS20_ICON_REQUEST %s %s", dest, val);
12491 if (wpa_command(intf, buf)) {
12492 send_resp(dut, conn, SIGMA_ERROR,
12493 "ErrorCode,HS20_ICON_REQUEST failed");
12494 return 0;
12495 }
12496 }
12497
12498 return 1;
12499}
12500
12501
12502static int ath_sta_send_frame_vht(struct sigma_dut *dut,
12503 struct sigma_conn *conn,
12504 struct sigma_cmd *cmd)
12505{
12506 const char *val;
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012507 const char *ifname;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012508 int chwidth, nss;
12509
12510 val = get_param(cmd, "framename");
12511 if (!val)
12512 return -1;
12513 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
12514
12515 /* Command sequence to generate Op mode notification */
12516 if (val && strcasecmp(val, "Op_md_notif_frm") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012517 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012518
12519 /* Disable STBC */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070012520 run_iwpriv(dut, ifname, "tx_stbc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012521
12522 /* Extract Channel width */
12523 val = get_param(cmd, "Channel_width");
12524 if (val) {
12525 switch (atoi(val)) {
12526 case 20:
12527 chwidth = 0;
12528 break;
12529 case 40:
12530 chwidth = 1;
12531 break;
12532 case 80:
12533 chwidth = 2;
12534 break;
12535 case 160:
12536 chwidth = 3;
12537 break;
12538 default:
12539 chwidth = 2;
12540 break;
12541 }
12542
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070012543 run_iwpriv(dut, ifname, "chwidth %d", chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012544 }
12545
12546 /* Extract NSS */
12547 val = get_param(cmd, "NSS");
12548 if (val) {
12549 switch (atoi(val)) {
12550 case 1:
12551 nss = 1;
12552 break;
12553 case 2:
12554 nss = 3;
12555 break;
12556 case 3:
12557 nss = 7;
12558 break;
12559 default:
12560 /* We do not support NSS > 3 */
12561 nss = 3;
12562 break;
12563 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070012564 run_iwpriv(dut, ifname, "rxchainmask %d", nss);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012565 }
12566
12567 /* Opmode notify */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070012568 run_iwpriv(dut, ifname, "opmode_notify 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012569 }
12570
12571 return 1;
12572}
12573
12574
Kiran Kumar Lokere00d74412020-07-23 13:26:51 -070012575static int wcn_sta_set_pmf_config(struct sigma_dut *dut, const char *intf,
12576 enum send_frame_protection protected)
12577{
12578#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +053012579 return wcn_wifi_test_config_set_u8(
12580 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_PMF_PROTECTION,
12581 protected);
Kiran Kumar Lokere00d74412020-07-23 13:26:51 -070012582#else /* NL80211_SUPPORT */
12583 sigma_dut_print(dut, DUT_MSG_ERROR,
12584 "PMF config cannot be set without NL80211_SUPPORT defined");
12585 return -1;
12586#endif /* NL80211_SUPPORT */
12587}
12588
12589
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012590static int cmd_sta_send_frame_vht(struct sigma_dut *dut,
12591 struct sigma_conn *conn,
12592 struct sigma_cmd *cmd)
12593{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012594 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012595 case DRIVER_ATHEROS:
12596 return ath_sta_send_frame_vht(dut, conn, cmd);
12597 default:
12598 send_resp(dut, conn, SIGMA_ERROR,
12599 "errorCode,Unsupported sta_set_frame(VHT) with the current driver");
12600 return 0;
12601 }
12602}
12603
12604
Kiran Kumar Lokerec2c3b412020-07-23 13:51:27 -070012605static int wcn_sta_send_disassoc(struct sigma_dut *dut, const char *intf)
12606{
12607#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +053012608 return wcn_wifi_test_config_set_flag(
12609 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_DISASSOC_TX);
Kiran Kumar Lokerec2c3b412020-07-23 13:51:27 -070012610#else /* NL80211_SUPPORT */
12611 sigma_dut_print(dut, DUT_MSG_ERROR,
12612 "Disassoc Tx cannot be done without NL80211_SUPPORT defined");
12613 return -1;
12614#endif /* NL80211_SUPPORT */
12615}
12616
12617
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012618static int wcn_sta_send_frame_he(struct sigma_dut *dut, struct sigma_conn *conn,
12619 struct sigma_cmd *cmd)
12620{
12621 const char *val;
12622 const char *intf = get_param(cmd, "Interface");
Kiran Kumar Lokere00d74412020-07-23 13:26:51 -070012623 enum send_frame_protection protected;
12624 const char *pmf;
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012625
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +030012626 if (!intf)
12627 return -1;
12628
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012629 val = get_param(cmd, "framename");
12630 if (!val)
12631 return -1;
12632 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
12633
Kiran Kumar Lokere00d74412020-07-23 13:26:51 -070012634 pmf = get_param(cmd, "PMFProtected");
12635 if (!pmf)
12636 pmf = get_param(cmd, "Protected");
12637 if (pmf) {
12638 if (strcasecmp(pmf, "Correct-key") == 0 ||
12639 strcasecmp(pmf, "CorrectKey") == 0) {
12640 protected = CORRECT_KEY;
12641 } else if (strcasecmp(pmf, "IncorrectKey") == 0) {
12642 protected = INCORRECT_KEY;
12643 } else if (strcasecmp(pmf, "Unprotected") == 0) {
12644 protected = UNPROTECTED;
12645 } else {
12646 send_resp(dut, conn, SIGMA_ERROR,
12647 "errorCode,Unsupported PMFProtected");
12648 return STATUS_SENT_ERROR;
12649 }
12650 sigma_dut_print(dut, DUT_MSG_DEBUG, "Config PMF protection %d",
12651 protected);
12652 wcn_sta_set_pmf_config(dut, intf, protected);
12653 }
12654
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012655 /* Command sequence to generate Op mode notification */
12656 if (val && strcasecmp(val, "action") == 0) {
12657 val = get_param(cmd, "PPDUTxType");
12658 if (val && strcasecmp(val, "TB") == 0) {
12659 if (sta_set_action_tx_in_he_tb_ppdu(dut, intf, 1)) {
12660 sigma_dut_print(dut, DUT_MSG_ERROR,
12661 "failed to send TB PPDU Tx cfg");
12662 send_resp(dut, conn, SIGMA_ERROR,
12663 "ErrorCode,set TB PPDU Tx cfg failed");
12664 return 0;
12665 }
12666 return 1;
12667 }
12668
12669 sigma_dut_print(dut, DUT_MSG_ERROR,
12670 "Action Tx type is not defined");
Kiran Kumar Lokerec2c3b412020-07-23 13:51:27 -070012671
12672 return SUCCESS_SEND_STATUS;
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012673 }
12674
Kiran Kumar Lokerec2c3b412020-07-23 13:51:27 -070012675 if (strcasecmp(val, "disassoc") == 0)
12676 wcn_sta_send_disassoc(dut, intf);
12677
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012678 return 1;
12679}
12680
12681
12682static int cmd_sta_send_frame_he(struct sigma_dut *dut,
12683 struct sigma_conn *conn,
12684 struct sigma_cmd *cmd)
12685{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012686 switch (get_driver_type(dut)) {
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012687 case DRIVER_WCN:
12688 return wcn_sta_send_frame_he(dut, conn, cmd);
12689 default:
12690 send_resp(dut, conn, SIGMA_ERROR,
12691 "errorCode,Unsupported sta_set_frame(HE) with the current driver");
12692 return 0;
12693 }
12694}
12695
12696
Lior David0fe101e2017-03-09 16:09:50 +020012697#ifdef __linux__
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030012698
12699static int
12700wil6210_send_p2p_frame_60g(struct sigma_dut *dut, struct sigma_cmd *cmd,
12701 const char *frame_name, const char *dest_mac)
12702{
12703 int isprobereq = strcasecmp(frame_name, "probereq") == 0;
12704 const char *ssid = get_param(cmd, "ssid");
12705 const char *countstr = get_param(cmd, "count");
12706 const char *channelstr = get_param(cmd, "channel");
12707 const char *group_id = get_param(cmd, "groupid");
12708 const char *client_id = get_param(cmd, "clientmac");
12709 int count, channel, freq, i;
12710 const char *fname;
12711 char frame[1024], src_mac[20], group_id_attr[25],
12712 device_macstr[3 * ETH_ALEN], client_mac[ETH_ALEN];
12713 const char *group_ssid;
12714 const int group_ssid_prefix_len = 9;
12715 struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *) frame;
12716 size_t framelen = sizeof(frame);
12717 struct template_frame_tag tags[2];
12718 size_t tags_total = ARRAY_SIZE(tags);
12719 int tag_index, len, dst_len;
12720
12721 if (!countstr || !channelstr) {
12722 sigma_dut_print(dut, DUT_MSG_ERROR,
12723 "Missing argument: count, channel");
12724 return -1;
12725 }
12726 if (isprobereq && !ssid) {
12727 sigma_dut_print(dut, DUT_MSG_ERROR,
12728 "Missing argument: ssid");
12729 return -1;
12730 }
12731 if (!isprobereq && (!group_id || !client_id)) {
12732 sigma_dut_print(dut, DUT_MSG_ERROR,
12733 "Missing argument: group_id, client_id");
12734 return -1;
12735 }
12736
12737 count = atoi(countstr);
12738 channel = atoi(channelstr);
12739 freq = channel_to_freq(dut, channel);
12740
12741 if (!freq) {
12742 sigma_dut_print(dut, DUT_MSG_ERROR,
12743 "invalid channel: %s", channelstr);
12744 return -1;
12745 }
12746
12747 if (isprobereq) {
12748 if (strcasecmp(ssid, "wildcard") == 0) {
12749 fname = "probe_req_wildcard.txt";
12750 } else if (strcasecmp(ssid, "P2P_Wildcard") == 0) {
12751 fname = "probe_req_P2P_Wildcard.txt";
12752 } else {
12753 sigma_dut_print(dut, DUT_MSG_ERROR,
12754 "invalid probe request type");
12755 return -1;
12756 }
12757 } else {
12758 fname = "P2P_device_discovery_req.txt";
12759 }
12760
12761 if (parse_template_frame_file(dut, fname, frame, &framelen,
12762 tags, &tags_total)) {
12763 sigma_dut_print(dut, DUT_MSG_ERROR,
12764 "invalid frame template: %s", fname);
12765 return -1;
12766 }
12767
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012768 if (get_wpa_status(get_station_ifname(dut), "address",
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030012769 src_mac, sizeof(src_mac)) < 0 ||
12770 parse_mac_address(dut, src_mac, &hdr->addr2[0]) ||
12771 parse_mac_address(dut, dest_mac, &hdr->addr1[0]))
12772 return -1;
12773 /* Use wildcard BSSID, since we are in PBSS */
12774 memset(&hdr->addr3, 0xFF, ETH_ALEN);
12775
12776 if (!isprobereq) {
12777 tag_index = find_template_frame_tag(tags, tags_total, 1);
12778 if (tag_index < 0) {
12779 sigma_dut_print(dut, DUT_MSG_ERROR,
12780 "can't find device id attribute");
12781 return -1;
12782 }
12783 if (parse_mac_address(dut, client_id,
12784 (unsigned char *) client_mac)) {
12785 sigma_dut_print(dut, DUT_MSG_ERROR,
12786 "invalid client_id: %s", client_id);
12787 return -1;
12788 }
12789 if (replace_p2p_attribute(dut, &frame[tags[tag_index].offset],
12790 framelen - tags[tag_index].offset,
12791 IEEE80211_P2P_ATTR_DEVICE_ID,
12792 client_mac, ETH_ALEN)) {
12793 sigma_dut_print(dut, DUT_MSG_ERROR,
12794 "fail to replace device id attribute");
12795 return -1;
12796 }
12797
12798 /*
12799 * group_id arg contains device MAC address followed by
12800 * space and SSID (DIRECT-somessid).
12801 * group id attribute contains device address (6 bytes)
12802 * followed by SSID prefix DIRECT-XX (9 bytes)
12803 */
12804 if (strlen(group_id) < sizeof(device_macstr)) {
12805 sigma_dut_print(dut, DUT_MSG_ERROR,
12806 "group_id arg too short");
12807 return -1;
12808 }
12809 memcpy(device_macstr, group_id, sizeof(device_macstr));
12810 device_macstr[sizeof(device_macstr) - 1] = '\0';
12811 if (parse_mac_address(dut, device_macstr,
12812 (unsigned char *) group_id_attr)) {
12813 sigma_dut_print(dut, DUT_MSG_ERROR,
12814 "fail to parse device address from group_id");
12815 return -1;
12816 }
12817 group_ssid = strchr(group_id, ' ');
12818 if (!group_ssid) {
12819 sigma_dut_print(dut, DUT_MSG_ERROR,
12820 "invalid group_id arg, no ssid");
12821 return -1;
12822 }
12823 group_ssid++;
12824 len = strlen(group_ssid);
12825 if (len < group_ssid_prefix_len) {
12826 sigma_dut_print(dut, DUT_MSG_ERROR,
12827 "group_id SSID too short");
12828 return -1;
12829 }
12830 dst_len = sizeof(group_id_attr) - ETH_ALEN;
12831 if (len > dst_len) {
12832 sigma_dut_print(dut, DUT_MSG_ERROR,
12833 "group_id SSID (%s) too long",
12834 group_ssid);
12835 return -1;
12836 }
12837
12838 memcpy(group_id_attr + ETH_ALEN, group_ssid, len);
12839 tag_index = find_template_frame_tag(tags, tags_total, 2);
12840 if (tag_index < 0) {
12841 sigma_dut_print(dut, DUT_MSG_ERROR,
12842 "can't find group id attribute");
12843 return -1;
12844 }
12845 if (replace_p2p_attribute(dut, &frame[tags[tag_index].offset],
12846 framelen - tags[tag_index].offset,
12847 IEEE80211_P2P_ATTR_GROUP_ID,
12848 group_id_attr,
12849 sizeof(group_id_attr))) {
12850 sigma_dut_print(dut, DUT_MSG_ERROR,
12851 "fail to replace group id attribute");
12852 return -1;
12853 }
12854 }
12855
12856 for (i = 0; i < count; i++) {
12857 if (wil6210_transmit_frame(dut, freq,
12858 WIL_TRANSMIT_FRAME_DEFAULT_ROC,
12859 frame, framelen)) {
12860 sigma_dut_print(dut, DUT_MSG_ERROR,
12861 "fail to transmit probe request frame");
12862 return -1;
12863 }
12864 }
12865
12866 return 0;
12867}
12868
12869
Lior David0fe101e2017-03-09 16:09:50 +020012870int wil6210_send_frame_60g(struct sigma_dut *dut, struct sigma_conn *conn,
12871 struct sigma_cmd *cmd)
12872{
12873 const char *frame_name = get_param(cmd, "framename");
12874 const char *mac = get_param(cmd, "dest_mac");
12875
12876 if (!frame_name || !mac) {
12877 sigma_dut_print(dut, DUT_MSG_ERROR,
12878 "framename and dest_mac must be provided");
12879 return -1;
12880 }
12881
12882 if (strcasecmp(frame_name, "brp") == 0) {
12883 const char *l_rx = get_param(cmd, "L-RX");
12884 int l_rx_i;
12885
12886 if (!l_rx) {
12887 sigma_dut_print(dut, DUT_MSG_ERROR,
12888 "L-RX must be provided");
12889 return -1;
12890 }
12891 l_rx_i = atoi(l_rx);
12892
12893 sigma_dut_print(dut, DUT_MSG_INFO,
12894 "dev_send_frame: BRP-RX, dest_mac %s, L-RX %s",
12895 mac, l_rx);
12896 if (l_rx_i != 16) {
12897 sigma_dut_print(dut, DUT_MSG_ERROR,
12898 "unsupported L-RX: %s", l_rx);
12899 return -1;
12900 }
12901
12902 if (wil6210_send_brp_rx(dut, mac, l_rx_i))
12903 return -1;
12904 } else if (strcasecmp(frame_name, "ssw") == 0) {
12905 sigma_dut_print(dut, DUT_MSG_INFO,
12906 "dev_send_frame: SLS, dest_mac %s", mac);
12907 if (wil6210_send_sls(dut, mac))
12908 return -1;
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030012909 } else if ((strcasecmp(frame_name, "probereq") == 0) ||
12910 (strcasecmp(frame_name, "devdiscreq") == 0)) {
12911 sigma_dut_print(dut, DUT_MSG_INFO,
12912 "dev_send_frame: %s, dest_mac %s", frame_name,
12913 mac);
12914 if (wil6210_send_p2p_frame_60g(dut, cmd, frame_name, mac))
12915 return -1;
Lior David0fe101e2017-03-09 16:09:50 +020012916 } else {
12917 sigma_dut_print(dut, DUT_MSG_ERROR,
12918 "unsupported frame type: %s", frame_name);
12919 return -1;
12920 }
12921
12922 return 1;
12923}
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030012924
Lior David0fe101e2017-03-09 16:09:50 +020012925#endif /* __linux__ */
12926
12927
12928static int cmd_sta_send_frame_60g(struct sigma_dut *dut,
12929 struct sigma_conn *conn,
12930 struct sigma_cmd *cmd)
12931{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012932 switch (get_driver_type(dut)) {
Lior David0fe101e2017-03-09 16:09:50 +020012933#ifdef __linux__
12934 case DRIVER_WIL6210:
12935 return wil6210_send_frame_60g(dut, conn, cmd);
12936#endif /* __linux__ */
12937 default:
12938 send_resp(dut, conn, SIGMA_ERROR,
12939 "errorCode,Unsupported sta_set_frame(60G) with the current driver");
12940 return 0;
12941 }
12942}
12943
12944
Ashwini Patildb59b3c2017-04-13 15:19:23 +053012945static int mbo_send_anqp_query(struct sigma_dut *dut, struct sigma_conn *conn,
12946 const char *intf, struct sigma_cmd *cmd)
12947{
12948 const char *val, *addr;
12949 char buf[100];
12950
12951 addr = get_param(cmd, "DestMac");
12952 if (!addr) {
12953 send_resp(dut, conn, SIGMA_INVALID,
12954 "ErrorCode,AP MAC address is missing");
12955 return 0;
12956 }
12957
12958 val = get_param(cmd, "ANQPQuery_ID");
12959 if (!val) {
12960 send_resp(dut, conn, SIGMA_INVALID,
12961 "ErrorCode,Missing ANQPQuery_ID");
12962 return 0;
12963 }
12964
12965 if (strcasecmp(val, "NeighborReportReq") == 0) {
12966 snprintf(buf, sizeof(buf), "ANQP_GET %s 272", addr);
12967 } else if (strcasecmp(val, "QueryListWithCellPref") == 0) {
12968 snprintf(buf, sizeof(buf), "ANQP_GET %s 272,mbo:2", addr);
12969 } else {
12970 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid ANQPQuery_ID: %s",
12971 val);
12972 send_resp(dut, conn, SIGMA_INVALID,
12973 "ErrorCode,Invalid ANQPQuery_ID");
12974 return 0;
12975 }
12976
Ashwini Patild174f2c2017-04-13 16:49:46 +053012977 /* Set gas_address3 field to IEEE 802.11-2012 standard compliant form
12978 * (Address3 = Wildcard BSSID when sent to not-associated AP;
12979 * if associated, AP BSSID).
12980 */
12981 if (wpa_command(intf, "SET gas_address3 1") < 0) {
12982 send_resp(dut, conn, SIGMA_ERROR,
12983 "ErrorCode,Failed to set gas_address3");
12984 return 0;
12985 }
12986
Ashwini Patildb59b3c2017-04-13 15:19:23 +053012987 if (wpa_command(intf, buf) < 0) {
12988 send_resp(dut, conn, SIGMA_ERROR,
12989 "ErrorCode,Failed to send ANQP query");
12990 return 0;
12991 }
12992
12993 return 1;
12994}
12995
12996
12997static int mbo_cmd_sta_send_frame(struct sigma_dut *dut,
12998 struct sigma_conn *conn,
12999 const char *intf,
13000 struct sigma_cmd *cmd)
13001{
13002 const char *val = get_param(cmd, "FrameName");
13003
13004 if (val && strcasecmp(val, "ANQPQuery") == 0)
13005 return mbo_send_anqp_query(dut, conn, intf, cmd);
13006
13007 return 2;
13008}
13009
13010
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +053013011static enum sigma_cmd_result cmd_sta_send_frame_wpa3(struct sigma_dut *dut,
13012 struct sigma_conn *conn,
13013 const char *intf,
13014 struct sigma_cmd *cmd)
13015{
13016 const char *val = get_param(cmd, "framename");
13017
13018 if (!val)
13019 return INVALID_SEND_STATUS;
13020
13021 if (strcasecmp(val, "SAQueryReq") == 0) {
13022 val = get_param(cmd, "OCIChannel");
13023
13024 if (!val) {
13025 send_resp(dut, conn, SIGMA_ERROR,
13026 "errorCode,OCIChannel not present");
13027 return STATUS_SENT_ERROR;
13028 }
13029
13030 dut->saquery_oci_freq = channel_to_freq(dut, atoi(val));
13031 if (!dut->saquery_oci_freq) {
13032 send_resp(dut, conn, SIGMA_ERROR,
13033 "errorCode,Invalid OCIChannel number");
13034 return STATUS_SENT_ERROR;
13035 }
13036
13037 return sta_inject_frame(dut, conn, intf, SAQUERY, CORRECT_KEY,
13038 NULL, 0);
13039 }
13040
13041 if (strcasecmp(val, "reassocreq") == 0)
13042 return sta_inject_frame(dut, conn, intf, REASSOCREQ,
13043 CORRECT_KEY, NULL, 0);
13044
Veerendranath9f81dfb2020-08-10 01:21:29 -070013045 if (strcasecmp(val, "ANQPQuery") == 0) {
13046 char buf[50];
13047 const char *dest = get_param(cmd, "DestMac");
13048 const char *chan = get_param(cmd, "channel");
Veerendranath Jakkam78862fc2020-11-19 21:23:27 +053013049 const char *freq_str = get_param(cmd, "ChnlFreq");
Veerendranath9f81dfb2020-08-10 01:21:29 -070013050 int len, freq;
13051
Veerendranath Jakkam78862fc2020-11-19 21:23:27 +053013052 if (freq_str)
13053 freq = atoi(freq_str);
13054 else
13055 freq = chan ? channel_to_freq(dut, atoi(chan)) : 0;
13056
Veerendranath9f81dfb2020-08-10 01:21:29 -070013057 if (!dest || !freq)
13058 return INVALID_SEND_STATUS;
13059
13060 len = snprintf(buf, sizeof(buf), "ANQP_GET %s freq=%d 257",
13061 dest, freq);
13062 if (len < 0 || len >= sizeof(buf)) {
13063 sigma_dut_print(dut, DUT_MSG_ERROR,
13064 "Failed to allocate buf");
13065 return ERROR_SEND_STATUS;
13066 }
13067
13068 if (wpa_command(intf, buf) != 0) {
13069 send_resp(dut, conn, SIGMA_ERROR,
13070 "ErrorCode,Failed to send ANQP Query frame");
13071 return STATUS_SENT_ERROR;
13072 }
13073
13074 sigma_dut_print(dut, DUT_MSG_DEBUG,
13075 "ANQP Query sent: %s", buf);
13076
13077 return SUCCESS_SEND_STATUS;
13078 }
13079
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +053013080 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported framename");
13081 return STATUS_SENT_ERROR;
13082}
13083
13084
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013085static int
13086get_type4_frame_classifier(struct sigma_dut *dut, struct sigma_cmd *cmd,
13087 char *pos, int rem_len, int num_of_scs_desc,
13088 int num_of_tclas_elem)
13089{
13090 const char *val;
13091 int ipv6;
13092 int len, total_len = 0;
13093
13094 val = get_param_fmt(cmd, "TCLASElem_Version_%d_%d", num_of_scs_desc,
13095 num_of_tclas_elem);
13096 if (!val) {
13097 sigma_dut_print(dut, DUT_MSG_ERROR, "%s: ip_version empty",
13098 __func__);
13099 return -1;
13100 }
13101
13102 if (strcmp(val, "6") == 0) {
13103 ipv6 = 1;
13104 } else if (strcmp(val, "4") == 0) {
13105 ipv6 = 0;
13106 } else {
13107 sigma_dut_print(dut, DUT_MSG_ERROR, "%s: ip_version invalid",
13108 __func__);
13109 return -1;
13110 }
13111
13112 len = snprintf(pos, rem_len, " ip_version=%s", ipv6 ? "ipv6" : "ipv4");
13113 if (len < 0 || len >= rem_len)
13114 return -1;
13115
13116 pos += len;
13117 rem_len -= len;
13118 total_len += len;
13119
13120 val = get_param_fmt(cmd, "TCLASElem_SourceIPAddr_%d_%d",
13121 num_of_scs_desc, num_of_tclas_elem);
13122 if (val) {
13123 len = snprintf(pos, rem_len, " src_ip=%s", val);
13124 if (len < 0 || len >= rem_len)
13125 return -1;
13126
13127 pos += len;
13128 rem_len -= len;
13129 total_len += len;
13130 }
13131
13132 val = get_param_fmt(cmd, "TCLASElem_DestinationIPAddr_%d_%d",
13133 num_of_scs_desc, num_of_tclas_elem);
13134 if (val) {
13135 len = snprintf(pos, rem_len, " dst_ip=%s", val);
13136 if (len < 0 || len >= rem_len)
13137 return -1;
13138
13139 pos += len;
13140 rem_len -= len;
13141 total_len += len;
13142 }
13143
13144 val = get_param_fmt(cmd, "TCLASElem_SourcePort_%d_%d", num_of_scs_desc,
13145 num_of_tclas_elem);
13146 if (val) {
13147 len = snprintf(pos, rem_len, " src_port=%s", val);
13148 if (len < 0 || len >= rem_len)
13149 return -1;
13150
13151 pos += len;
13152 rem_len -= len;
13153 total_len += len;
13154 }
13155
13156 val = get_param_fmt(cmd, "TCLASElem_DestinationPort_%d_%d",
13157 num_of_scs_desc, num_of_tclas_elem);
13158 if (val) {
13159 len = snprintf(pos, rem_len, " dst_port=%s", val);
13160 if (len < 0 || len >= rem_len)
13161 return -1;
13162
13163 pos += len;
13164 rem_len -= len;
13165 total_len += len;
13166 }
13167
13168 val = get_param_fmt(cmd, "TCLASElem_DSCP_%d_%d", num_of_scs_desc,
13169 num_of_tclas_elem);
13170 if (val) {
13171 len = snprintf(pos, rem_len, " dscp=%s", val);
13172 if (len < 0 || len >= rem_len)
13173 return -1;
13174
13175 pos += len;
13176 rem_len -= len;
13177 total_len += len;
13178 }
13179
13180 val = get_param_fmt(cmd, "TCLASElem_ProtocolNxtHeader_%d_%d",
13181 num_of_scs_desc, num_of_tclas_elem);
13182 if (val) {
13183 char *prot;
13184
13185 switch (atoi(val)) {
13186 case 17:
13187 prot = "udp";
13188 break;
13189 case 6:
13190 prot = "tcp";
13191 break;
13192 case 50:
13193 prot = "esp";
13194 break;
13195 default:
13196 sigma_dut_print(dut, DUT_MSG_ERROR,
13197 "Invalid protocol %d", atoi(val));
13198 return -1;
13199 }
13200
13201 if (ipv6)
13202 len = snprintf(pos, rem_len, " next_header=%s", prot);
13203 else
13204 len = snprintf(pos, rem_len, " protocol=%s", prot);
13205 if (len < 0 || len >= rem_len)
13206 return -1;
13207
13208 pos += len;
13209 rem_len -= len;
13210 total_len += len;
13211 }
13212
13213 return total_len;
13214}
13215
13216
13217static int
13218get_type10_frame_classifier(struct sigma_dut *dut, struct sigma_cmd *cmd,
13219 char *pos, int rem_len, int num_of_scs_desc,
13220 int num_of_tclas_elem)
13221{
13222 const char *val;
13223 int len, total_len = 0;
13224
13225 val = get_param_fmt(cmd, "TCLASElem_ProtoInstance_%d_%d",
13226 num_of_scs_desc, num_of_tclas_elem);
13227 if (val) {
13228 len = snprintf(pos, rem_len, " prot_instance=%s",
13229 val);
13230 if (len < 0 || len >= rem_len)
13231 return -1;
13232
13233 pos += len;
13234 rem_len -= len;
13235 total_len += len;
13236 }
13237
13238 val = get_param_fmt(cmd, "TCLASElem_ProtoNumNextHeader_%d_%d",
13239 num_of_scs_desc, num_of_tclas_elem);
13240 if (val) {
13241 char *prot;
13242
13243 switch (atoi(val)) {
13244 case 17:
13245 prot = "udp";
13246 break;
13247 case 6:
13248 prot = "tcp";
13249 break;
13250 case 50:
13251 prot = "esp";
13252 break;
13253 default:
13254 sigma_dut_print(dut, DUT_MSG_ERROR,
13255 "Invalid protocol %d",
13256 atoi(val));
13257 return -1;
13258 }
13259
13260 len = snprintf(pos, rem_len, " prot_number=%s", prot);
13261 if (len < 0 || len >= rem_len)
13262 return -1;
13263
13264 pos += len;
13265 rem_len -= len;
13266 total_len += len;
13267 }
13268
13269 val = get_param_fmt(cmd, "TCLASElem_FilterValue_%d_%d",
13270 num_of_scs_desc, num_of_tclas_elem);
13271 if (val) {
13272 len = snprintf(pos, rem_len, " filter_value=%s", (val + 2));
13273 if (len < 0 || len >= rem_len)
13274 return -1;
13275
13276 pos += len;
13277 rem_len -= len;
13278 total_len += len;
13279 }
13280
13281 val = get_param_fmt(cmd, "TCLASElem_FilterMask_%d_%d", num_of_scs_desc,
13282 num_of_tclas_elem);
13283 if (val && strlen(val) >= 2) {
13284 len = snprintf(pos, rem_len, " filter_mask=%s", val + 2);
13285 if (len < 0 || len >= rem_len)
13286 return -1;
13287
13288 pos += len;
13289 rem_len -= len;
13290 total_len += len;
13291 }
13292
13293 return total_len;
13294}
13295
13296
13297static enum sigma_cmd_result
13298cmd_sta_send_frame_scs(struct sigma_dut *dut, struct sigma_conn *conn,
13299 const char *intf, struct sigma_cmd *cmd)
13300{
13301 char buf[4096], *pos;
13302 const char *val, *scs_id, *classifier_type;
13303 int len, rem_len, total_bytes;
13304 int num_of_scs_desc = 0, num_of_tclas_elem = 0;
13305
13306 scs_id = get_param(cmd, "SCSDescrElem_SCSID_1");
13307 if (!scs_id) {
13308 sigma_dut_print(dut, DUT_MSG_ERROR, "SCS ID empty");
13309 return INVALID_SEND_STATUS;
13310 }
13311
13312 rem_len = sizeof(buf);
13313 pos = buf;
13314
13315 len = snprintf(buf, sizeof(buf), "SCS");
13316 if (len < 0 || len > rem_len)
13317 goto fail;
13318
13319 pos += len;
13320 rem_len -= len;
13321
13322 while (scs_id) {
13323 num_of_scs_desc++;
13324
13325 val = get_param_fmt(cmd, "SCSDescrElem_RequestType_%d",
13326 num_of_scs_desc);
13327 if (!val)
13328 return INVALID_SEND_STATUS;
13329
13330 if (strcasecmp(val, "Add") == 0) {
13331 len = snprintf(pos, rem_len, " scs_id=%s add",
13332 scs_id);
13333 } else if (strcasecmp(val, "Change") == 0) {
13334 len = snprintf(pos, rem_len, " scs_id=%s change",
13335 scs_id);
13336 } else if (strcasecmp(val, "Remove") == 0) {
13337 len = snprintf(pos, rem_len, " scs_id=%s remove",
13338 scs_id);
13339 if (len < 0 || len >= rem_len)
13340 goto fail;
13341
13342 pos += len;
13343 rem_len -= len;
13344 goto scs_desc_end;
13345 } else {
13346 sigma_dut_print(dut, DUT_MSG_ERROR,
13347 "%s: request type - %s is invalid",
13348 __func__, val);
13349 return INVALID_SEND_STATUS;
13350 }
13351
13352 if (len < 0 || len >= rem_len)
13353 goto fail;
13354
13355 pos += len;
13356 rem_len -= len;
13357
13358 val = get_param_fmt(cmd, "IntraAccessCatElem_UP_%d",
13359 num_of_scs_desc);
13360 if (!val) {
13361 sigma_dut_print(dut, DUT_MSG_ERROR,
13362 "IntraAccess Priority empty");
13363 return INVALID_SEND_STATUS;
13364 }
13365
13366 len = snprintf(pos, rem_len, " scs_up=%s", val);
13367 if (len < 0 || len >= rem_len)
13368 goto fail;
13369
13370 pos += len;
13371 rem_len -= len;
13372
13373 classifier_type = get_param_fmt(cmd,
13374 "TCLASElem_ClassifierType_%d_1",
13375 num_of_scs_desc);
13376 if (!classifier_type) {
13377 sigma_dut_print(dut, DUT_MSG_ERROR,
13378 "classifier type missing");
13379 return INVALID_SEND_STATUS;
13380 }
13381
13382 while (classifier_type) {
13383 num_of_tclas_elem++;
13384
13385 len = snprintf(pos, rem_len, " classifier_type=%s",
13386 classifier_type);
13387 if (len < 0 || len >= rem_len)
13388 goto fail;
13389
13390 pos += len;
13391 rem_len -= len;
13392
13393 if (strcmp(classifier_type, "10") == 0) {
13394 total_bytes = get_type10_frame_classifier(
13395 dut, cmd, pos, rem_len,
13396 num_of_scs_desc,
13397 num_of_tclas_elem);
13398 } else if (strcmp(classifier_type, "4") == 0) {
13399 total_bytes = get_type4_frame_classifier(
13400 dut, cmd, pos, rem_len,
13401 num_of_scs_desc,
13402 num_of_tclas_elem);
13403 } else {
13404 sigma_dut_print(dut, DUT_MSG_ERROR,
13405 "classifier_type invalid");
13406 goto fail;
13407 }
13408
13409 if (total_bytes < 0)
13410 goto fail;
13411
13412 pos += total_bytes;
13413 rem_len -= total_bytes;
13414
13415 classifier_type = get_param_fmt(
13416 cmd, "TCLASElem_ClassifierType_%d_%d",
13417 num_of_scs_desc, num_of_tclas_elem + 1);
13418 }
13419
13420 if (num_of_tclas_elem > 1) {
13421 val = get_param_fmt(cmd,
13422 "TCLASProcessingElem_Processing_%d",
13423 num_of_scs_desc);
13424 if (!val) {
13425 sigma_dut_print(dut, DUT_MSG_ERROR,
13426 "Tclas_processing element %d empty",
13427 num_of_scs_desc);
13428 goto fail;
13429 }
13430
13431 len = snprintf(pos, rem_len,
13432 " tclas_processing=%s", val);
13433 if (len < 0 || len >= rem_len)
13434 goto fail;
13435
13436 pos += len;
13437 rem_len -= len;
13438 }
13439scs_desc_end:
13440 num_of_tclas_elem = 0;
13441 scs_id = get_param_fmt(cmd, "SCSDescrElem_SCSID_%d",
13442 num_of_scs_desc + 1);
13443 }
13444
13445 if (wpa_command(intf, buf) != 0) {
13446 send_resp(dut, conn, SIGMA_ERROR,
13447 "ErrorCode,Failed to send SCS frame request");
13448 return STATUS_SENT_ERROR;
13449 }
13450
13451 sigma_dut_print(dut, DUT_MSG_DEBUG,
13452 "SCS frame request sent: %s", buf);
13453
13454 return SUCCESS_SEND_STATUS;
13455fail:
13456 sigma_dut_print(dut, DUT_MSG_ERROR,
13457 "Failed to create SCS frame request");
13458 return ERROR_SEND_STATUS;
13459}
13460
13461
Vinita S. Malooee9e7e92020-04-28 16:26:50 +053013462static enum sigma_cmd_result
13463cmd_sta_send_frame_mscs(struct sigma_dut *dut, struct sigma_conn *conn,
13464 const char *intf, struct sigma_cmd *cmd)
13465{
13466 char buf[128], *pos;
13467 const char *val, *classifier_type = "04", *type;
13468 int len, rem_len;
13469 u8 up_bitmap;
13470
Vinita S. Malooee9e7e92020-04-28 16:26:50 +053013471 type = get_param(cmd, "Request_Type");
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013472 if (!type) {
Vinita S. Malooee9e7e92020-04-28 16:26:50 +053013473 sigma_dut_print(dut, DUT_MSG_ERROR,
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013474 "%s: type not valid", __func__);
Vinita S. Malooee9e7e92020-04-28 16:26:50 +053013475 return INVALID_SEND_STATUS;
13476 }
13477
13478 rem_len = sizeof(buf);
13479 pos = buf;
13480 if (strcasecmp(type, "add") == 0) {
13481 len = snprintf(pos, rem_len, "MSCS add");
13482 } else if (strcasecmp(type, "update") == 0) {
13483 len = snprintf(pos, rem_len, "MSCS change");
13484 } else if (strcasecmp(type, "remove") == 0) {
13485 if (wpa_command(intf, "MSCS remove") != 0) {
13486 send_resp(dut, conn, SIGMA_ERROR,
13487 "ErrorCode,Failed to send MSCS frame req");
13488 return STATUS_SENT_ERROR;
13489 }
13490 return SUCCESS_SEND_STATUS;
13491 } else {
13492 sigma_dut_print(dut, DUT_MSG_ERROR,
13493 "%s: request type invalid", __func__);
13494 return INVALID_SEND_STATUS;
13495 }
13496
13497 if (len < 0 || len >= rem_len)
13498 goto fail;
13499
13500 pos += len;
13501 rem_len -= len;
13502
13503 val = get_param(cmd, "User_Priority_Bitmap");
13504 if (!val) {
13505 sigma_dut_print(dut, DUT_MSG_ERROR,
13506 "%s: user priority bitmap empty", __func__);
13507 return INVALID_SEND_STATUS;
13508 }
13509
13510 switch (atoi(val)) {
13511 case 0:
13512 up_bitmap = 0x00;
13513 break;
13514 case 1:
13515 up_bitmap = 0xF0;
13516 break;
13517 case 2:
13518 up_bitmap = 0xF6;
13519 break;
13520 default:
13521 sigma_dut_print(dut, DUT_MSG_ERROR,
13522 "%s: Unknown User_Priority_Bitmap value %d",
13523 __func__, atoi(val));
13524 return INVALID_SEND_STATUS;
13525 }
13526
13527 len = snprintf(pos, rem_len, " up_bitmap=%02x", up_bitmap);
13528 if (len < 0 || len >= rem_len)
13529 goto fail;
13530
13531 pos += len;
13532 rem_len -= len;
13533
13534 val = get_param(cmd, "User_Priority_Limit");
13535 if (!val) {
13536 sigma_dut_print(dut, DUT_MSG_ERROR,
13537 "%s: invalid user priority limit", __func__);
13538 return INVALID_SEND_STATUS;
13539 }
13540
13541 len = snprintf(pos, rem_len, " up_limit=%s", val);
13542 if (len < 0 || len >= rem_len)
13543 goto fail;
13544
13545 pos += len;
13546 rem_len -= len;
13547
13548 val = get_param(cmd, "Stream_Timeout");
13549 if (!val)
13550 val = get_param(cmd, "Stream_Timtout");
13551 if (!val) {
13552 sigma_dut_print(dut, DUT_MSG_ERROR,
13553 "%s: invalid stream timeout", __func__);
13554 return INVALID_SEND_STATUS;
13555 }
13556
13557 len = snprintf(pos, rem_len, " stream_timeout=%s", val);
13558 if (len < 0 || len >= rem_len)
13559 goto fail;
13560
13561 pos += len;
13562 rem_len -= len;
13563
13564 val = get_param(cmd, "TCLAS_Mask");
13565 if (!val) {
13566 sigma_dut_print(dut, DUT_MSG_ERROR,
13567 "%s: invalid tclas mask", __func__);
13568 return INVALID_SEND_STATUS;
13569 }
13570
13571 len = snprintf(pos, rem_len, " frame_classifier=%s%lx%032x",
13572 classifier_type, strtol(val, NULL, 2), 0);
13573 if (len < 0 || len >= rem_len)
13574 goto fail;
13575
13576 if (wpa_command(intf, buf) != 0) {
13577 send_resp(dut, conn, SIGMA_ERROR,
13578 "ErrorCode,Failed to send MSCS frame req");
13579 return STATUS_SENT_ERROR;
13580 }
13581
13582 sigma_dut_print(dut, DUT_MSG_DEBUG,
13583 "MSCS frame request sent: %s", buf);
13584
13585 return SUCCESS_SEND_STATUS;
13586fail:
13587 sigma_dut_print(dut, DUT_MSG_ERROR,
13588 "Failed to create MSCS frame req");
13589 return ERROR_SEND_STATUS;
13590}
13591
13592
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013593static enum sigma_cmd_result
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053013594cmd_sta_send_frame_dscp_query(struct sigma_dut *dut, struct sigma_conn *conn,
13595 const char *intf, struct sigma_cmd *cmd)
13596{
13597 char buf[150], *pos;
13598 const char *val;
13599 int len, rem_len;
13600
13601 rem_len = sizeof(buf);
13602 pos = buf;
13603
13604 len = snprintf(pos, rem_len, "DSCP_QUERY");
13605 if (len < 0 || len >= rem_len)
13606 goto fail;
13607
13608 pos += len;
13609 rem_len -= len;
13610
13611 val = get_param(cmd, "Wildcard");
13612 if (val && strcasecmp(val, "Yes") == 0) {
13613 len = snprintf(pos, rem_len, " wildcard");
13614 if (len < 0 || len >= rem_len)
13615 goto fail;
13616 } else if (strlen(dut->qm_domain_name)) {
13617 len = snprintf(pos, rem_len, " domain_name=%s",
13618 dut->qm_domain_name);
13619 if (len < 0 || len >= rem_len)
13620 goto fail;
13621 } else {
13622 sigma_dut_print(dut, DUT_MSG_ERROR,
13623 "Invalid DSCP Query configuration");
13624 return INVALID_SEND_STATUS;
13625 }
13626
13627 if (wpa_command(intf, buf) != 0) {
13628 send_resp(dut, conn, SIGMA_ERROR,
13629 "ErrorCode,Failed to send DSCP policy query frame");
13630 return STATUS_SENT_ERROR;
13631 }
13632
13633 sigma_dut_print(dut, DUT_MSG_DEBUG,
13634 "DSCP policy query frame sent: %s", buf);
13635 return SUCCESS_SEND_STATUS;
13636fail:
13637 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to send DSCP query");
13638 return ERROR_SEND_STATUS;
13639}
13640
13641
13642static enum sigma_cmd_result
Veerendranath Jakkam1bf1bd62021-09-12 16:35:55 +053013643cmd_sta_send_frame_dscp_response(struct sigma_dut *dut, struct sigma_conn *conn,
13644 const char *intf, struct sigma_cmd *cmd)
13645{
13646 char buf[256], *pos, *item, *list, *saveptr;
13647 const char *val;
13648 int len, rem_len;
13649
13650 pos = buf;
13651 rem_len = sizeof(buf);
13652
13653 len = snprintf(pos, rem_len, "DSCP_RESP");
13654 if (snprintf_error(rem_len, len)) {
13655 sigma_dut_print(dut, DUT_MSG_ERROR,
13656 "Failed to create DSCP Policy Response command");
13657 return ERROR_SEND_STATUS;
13658 }
13659
13660 pos += len;
13661 rem_len -= len;
13662
13663 val = get_param(cmd, "PolicyID_List");
13664 if (!val) {
13665 sigma_dut_print(dut, DUT_MSG_ERROR,
13666 "DSCP policy ID list missing");
13667 return INVALID_SEND_STATUS;
13668 }
13669
13670 list = strdup(val);
13671 if (!list)
13672 return ERROR_SEND_STATUS;
13673
13674 item = strtok_r(list, "_", &saveptr);
13675 while (item) {
13676 unsigned int i;
13677 int policy_id = atoi(item);
13678
13679 for (i = 0; i < dut->num_dscp_status; i++)
13680 if (dut->dscp_status[i].id == policy_id)
13681 break;
13682
13683 if (i == dut->num_dscp_status) {
13684 free(list);
13685 send_resp(dut, conn, SIGMA_ERROR,
13686 "ErrorCode,DSCP policy id not found in status list");
13687 return STATUS_SENT_ERROR;
13688 }
13689
13690 len = snprintf(pos, rem_len, " policy_id=%d status=%d",
13691 policy_id, dut->dscp_status[i].status);
13692 if (snprintf_error(rem_len, len)) {
13693 free(list);
13694 sigma_dut_print(dut, DUT_MSG_ERROR,
13695 "Failed to write DSCP policy list");
13696 return ERROR_SEND_STATUS;
13697 }
13698
13699 pos += len;
13700 rem_len -= len;
13701
13702 if (dut->dscp_status[i].status)
13703 remove_dscp_policy(dut, policy_id);
13704
13705 item = strtok_r(NULL, "_", &saveptr);
13706 }
13707
13708 free(list);
13709
13710 if (wpa_command(intf, buf) != 0) {
13711 send_resp(dut, conn, SIGMA_ERROR,
13712 "ErrorCode,Failed to send DSCP Policy Response frame");
13713 return STATUS_SENT_ERROR;
13714 }
13715
13716 sigma_dut_print(dut, DUT_MSG_DEBUG,
13717 "DSCP Policy Response frame sent: %s", buf);
13718 return SUCCESS_SEND_STATUS;
13719}
13720
13721
13722static enum sigma_cmd_result
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013723cmd_sta_send_frame_qm(struct sigma_dut *dut, struct sigma_conn *conn,
13724 const char *intf, struct sigma_cmd *cmd)
13725{
13726 const char *val;
13727
13728 val = get_param(cmd, "FrameName");
13729 if (val) {
13730 if (strcasecmp(val, "MSCSReq") == 0)
13731 return cmd_sta_send_frame_mscs(dut, conn, intf, cmd);
13732 if (strcasecmp(val, "SCSReq") == 0)
13733 return cmd_sta_send_frame_scs(dut, conn, intf, cmd);
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053013734 if (strcasecmp(val, "DSCPPolicyQuery") == 0)
13735 return cmd_sta_send_frame_dscp_query(dut, conn, intf,
13736 cmd);
Veerendranath Jakkam1bf1bd62021-09-12 16:35:55 +053013737 if (strcasecmp(val, "DSCPPolicyResponse") == 0)
13738 return cmd_sta_send_frame_dscp_response(dut, conn, intf,
13739 cmd);
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013740
13741 sigma_dut_print(dut, DUT_MSG_ERROR,
13742 "%s: frame name - %s is invalid",
13743 __func__, val);
13744 }
13745
13746 return INVALID_SEND_STATUS;
13747}
13748
13749
Jouni Malinenf7222712019-06-13 01:50:21 +030013750enum sigma_cmd_result cmd_sta_send_frame(struct sigma_dut *dut,
13751 struct sigma_conn *conn,
13752 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013753{
13754 const char *intf = get_param(cmd, "Interface");
13755 const char *val;
13756 enum send_frame_type frame;
13757 enum send_frame_protection protected;
13758 char buf[100];
13759 unsigned char addr[ETH_ALEN];
13760 int res;
13761
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +030013762 if (!intf)
13763 return -1;
13764
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013765 val = get_param(cmd, "program");
13766 if (val == NULL)
13767 val = get_param(cmd, "frame");
13768 if (val && strcasecmp(val, "TDLS") == 0)
13769 return cmd_sta_send_frame_tdls(dut, conn, cmd);
13770 if (val && (strcasecmp(val, "HS2") == 0 ||
Jouni Malinen1f6ae642018-06-07 23:56:13 +030013771 strcasecmp(val, "HS2-R2") == 0 ||
13772 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013773 return cmd_sta_send_frame_hs2(dut, conn, cmd);
13774 if (val && strcasecmp(val, "VHT") == 0)
13775 return cmd_sta_send_frame_vht(dut, conn, cmd);
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070013776 if (val && strcasecmp(val, "HE") == 0)
13777 return cmd_sta_send_frame_he(dut, conn, cmd);
priyadharshini gowthamand66913a2016-07-29 15:11:17 -070013778 if (val && strcasecmp(val, "LOC") == 0)
13779 return loc_cmd_sta_send_frame(dut, conn, cmd);
Lior David0fe101e2017-03-09 16:09:50 +020013780 if (val && strcasecmp(val, "60GHz") == 0)
13781 return cmd_sta_send_frame_60g(dut, conn, cmd);
Ashwini Patildb59b3c2017-04-13 15:19:23 +053013782 if (val && strcasecmp(val, "MBO") == 0) {
13783 res = mbo_cmd_sta_send_frame(dut, conn, intf, cmd);
13784 if (res != 2)
13785 return res;
13786 }
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +053013787 if (val && strcasecmp(val, "WPA3") == 0)
13788 return cmd_sta_send_frame_wpa3(dut, conn, intf, cmd);
Vinita S. Malooee9e7e92020-04-28 16:26:50 +053013789 if (val && strcasecmp(val, "QM") == 0)
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013790 return cmd_sta_send_frame_qm(dut, conn, intf, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013791
13792 val = get_param(cmd, "TD_DISC");
13793 if (val) {
13794 if (hwaddr_aton(val, addr) < 0)
13795 return -1;
13796 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", val);
13797 if (wpa_command(intf, buf) < 0) {
13798 send_resp(dut, conn, SIGMA_ERROR,
13799 "ErrorCode,Failed to send TDLS discovery");
13800 return 0;
13801 }
13802 return 1;
13803 }
13804
13805 val = get_param(cmd, "TD_Setup");
13806 if (val) {
13807 if (hwaddr_aton(val, addr) < 0)
13808 return -1;
13809 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", val);
13810 if (wpa_command(intf, buf) < 0) {
13811 send_resp(dut, conn, SIGMA_ERROR,
13812 "ErrorCode,Failed to start TDLS setup");
13813 return 0;
13814 }
13815 return 1;
13816 }
13817
13818 val = get_param(cmd, "TD_TearDown");
13819 if (val) {
13820 if (hwaddr_aton(val, addr) < 0)
13821 return -1;
13822 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", val);
13823 if (wpa_command(intf, buf) < 0) {
13824 send_resp(dut, conn, SIGMA_ERROR,
13825 "ErrorCode,Failed to tear down TDLS link");
13826 return 0;
13827 }
13828 return 1;
13829 }
13830
13831 val = get_param(cmd, "TD_ChannelSwitch");
13832 if (val) {
13833 /* TODO */
13834 send_resp(dut, conn, SIGMA_ERROR,
13835 "ErrorCode,TD_ChannelSwitch not yet supported");
13836 return 0;
13837 }
13838
13839 val = get_param(cmd, "TD_NF");
13840 if (val) {
13841 /* TODO */
13842 send_resp(dut, conn, SIGMA_ERROR,
13843 "ErrorCode,TD_NF not yet supported");
13844 return 0;
13845 }
13846
13847 val = get_param(cmd, "PMFFrameType");
13848 if (val == NULL)
13849 val = get_param(cmd, "FrameName");
13850 if (val == NULL)
13851 val = get_param(cmd, "Type");
13852 if (val == NULL)
13853 return -1;
13854 if (strcasecmp(val, "disassoc") == 0)
13855 frame = DISASSOC;
13856 else if (strcasecmp(val, "deauth") == 0)
13857 frame = DEAUTH;
13858 else if (strcasecmp(val, "saquery") == 0)
13859 frame = SAQUERY;
13860 else if (strcasecmp(val, "auth") == 0)
13861 frame = AUTH;
13862 else if (strcasecmp(val, "assocreq") == 0)
13863 frame = ASSOCREQ;
13864 else if (strcasecmp(val, "reassocreq") == 0)
13865 frame = REASSOCREQ;
13866 else if (strcasecmp(val, "neigreq") == 0) {
13867 sigma_dut_print(dut, DUT_MSG_INFO, "Got neighbor request");
13868
13869 val = get_param(cmd, "ssid");
13870 if (val == NULL)
13871 return -1;
13872
13873 res = send_neighbor_request(dut, intf, val);
13874 if (res) {
13875 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
13876 "Failed to send neighbor report request");
13877 return 0;
13878 }
13879
13880 return 1;
Ashwini Patil5acd7382017-04-13 15:55:04 +053013881 } else if (strcasecmp(val, "transmgmtquery") == 0 ||
13882 strcasecmp(val, "BTMQuery") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013883 sigma_dut_print(dut, DUT_MSG_DEBUG,
13884 "Got Transition Management Query");
13885
Ashwini Patil5acd7382017-04-13 15:55:04 +053013886 res = send_trans_mgmt_query(dut, intf, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013887 if (res) {
13888 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
13889 "Failed to send Transition Management Query");
13890 return 0;
13891 }
13892
13893 return 1;
13894 } else {
13895 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
13896 "PMFFrameType");
13897 return 0;
13898 }
13899
13900 val = get_param(cmd, "PMFProtected");
13901 if (val == NULL)
13902 val = get_param(cmd, "Protected");
13903 if (val == NULL)
13904 return -1;
13905 if (strcasecmp(val, "Correct-key") == 0 ||
13906 strcasecmp(val, "CorrectKey") == 0)
13907 protected = CORRECT_KEY;
13908 else if (strcasecmp(val, "IncorrectKey") == 0)
13909 protected = INCORRECT_KEY;
13910 else if (strcasecmp(val, "Unprotected") == 0)
13911 protected = UNPROTECTED;
13912 else {
13913 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
13914 "PMFProtected");
13915 return 0;
13916 }
13917
13918 if (protected != UNPROTECTED &&
13919 (frame == AUTH || frame == ASSOCREQ || frame == REASSOCREQ)) {
13920 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Impossible "
13921 "PMFProtected for auth/assocreq/reassocreq");
13922 return 0;
13923 }
13924
13925 if (if_nametoindex("sigmadut") == 0) {
13926 snprintf(buf, sizeof(buf),
13927 "iw dev %s interface add sigmadut type monitor",
Jouni Malinen016ae6c2019-11-04 17:00:01 +020013928 get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013929 if (system(buf) != 0 ||
13930 if_nametoindex("sigmadut") == 0) {
13931 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
13932 "monitor interface with '%s'", buf);
13933 return -2;
13934 }
13935 }
13936
13937 if (system("ifconfig sigmadut up") != 0) {
13938 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
13939 "monitor interface up");
13940 return -2;
13941 }
13942
Veerendranath Jakkam49774122020-07-05 09:52:18 +053013943 return sta_inject_frame(dut, conn, intf, frame, protected, NULL, 1);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013944}
13945
13946
13947static int cmd_sta_set_parameter_hs2(struct sigma_dut *dut,
13948 struct sigma_conn *conn,
13949 struct sigma_cmd *cmd,
13950 const char *ifname)
13951{
13952 char buf[200];
13953 const char *val;
13954
13955 val = get_param(cmd, "ClearARP");
13956 if (val && atoi(val) == 1) {
13957 snprintf(buf, sizeof(buf), "ip neigh flush dev %s", ifname);
13958 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
13959 if (system(buf) != 0) {
13960 send_resp(dut, conn, SIGMA_ERROR,
13961 "errorCode,Failed to clear ARP cache");
13962 return 0;
13963 }
13964 }
13965
13966 return 1;
13967}
13968
13969
13970int cmd_sta_set_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
13971 struct sigma_cmd *cmd)
13972{
13973 const char *intf = get_param(cmd, "Interface");
13974 const char *val;
13975
13976 if (intf == NULL)
13977 return -1;
13978
13979 val = get_param(cmd, "program");
13980 if (val && (strcasecmp(val, "HS2") == 0 ||
Jouni Malinen1f6ae642018-06-07 23:56:13 +030013981 strcasecmp(val, "HS2-R2") == 0 ||
13982 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013983 return cmd_sta_set_parameter_hs2(dut, conn, cmd, intf);
13984
13985 return -1;
13986}
13987
13988
Jouni Malinenf7222712019-06-13 01:50:21 +030013989static enum sigma_cmd_result cmd_sta_set_macaddr(struct sigma_dut *dut,
13990 struct sigma_conn *conn,
13991 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013992{
13993 const char *intf = get_param(cmd, "Interface");
13994 const char *mac = get_param(cmd, "MAC");
13995
13996 if (intf == NULL || mac == NULL)
13997 return -1;
13998
13999 sigma_dut_print(dut, DUT_MSG_INFO, "Change local MAC address for "
14000 "interface %s to %s", intf, mac);
14001
14002 if (dut->set_macaddr) {
14003 char buf[128];
14004 int res;
14005 if (strcasecmp(mac, "default") == 0) {
14006 res = snprintf(buf, sizeof(buf), "%s",
14007 dut->set_macaddr);
14008 dut->tmp_mac_addr = 0;
14009 } else {
14010 res = snprintf(buf, sizeof(buf), "%s %s",
14011 dut->set_macaddr, mac);
14012 dut->tmp_mac_addr = 1;
14013 }
14014 if (res < 0 || res >= (int) sizeof(buf))
14015 return -1;
14016 if (system(buf) != 0) {
14017 send_resp(dut, conn, SIGMA_ERROR,
14018 "errorCode,Failed to set MAC "
14019 "address");
14020 return 0;
14021 }
14022 return 1;
14023 }
14024
14025 if (strcasecmp(mac, "default") == 0)
14026 return 1;
14027
14028 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
14029 "command");
14030 return 0;
14031}
14032
14033
14034static int iwpriv_tdlsoffchnmode(struct sigma_dut *dut,
14035 struct sigma_conn *conn, const char *intf,
14036 int val)
14037{
14038 char buf[200];
14039 int res;
14040
14041 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchnmode %d",
14042 intf, val);
14043 if (res < 0 || res >= (int) sizeof(buf))
14044 return -1;
14045 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14046 if (system(buf) != 0) {
14047 send_resp(dut, conn, SIGMA_ERROR,
14048 "errorCode,Failed to configure offchannel mode");
14049 return 0;
14050 }
14051
14052 return 1;
14053}
14054
14055
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014056static int off_chan_val(enum sec_ch_offset off)
14057{
14058 switch (off) {
14059 case SEC_CH_NO:
14060 return 0;
14061 case SEC_CH_40ABOVE:
14062 return 40;
14063 case SEC_CH_40BELOW:
14064 return -40;
14065 }
14066
14067 return 0;
14068}
14069
14070
14071static int iwpriv_set_offchan(struct sigma_dut *dut, struct sigma_conn *conn,
14072 const char *intf, int off_ch_num,
14073 enum sec_ch_offset sec)
14074{
14075 char buf[200];
14076 int res;
14077
14078 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchan %d",
14079 intf, off_ch_num);
14080 if (res < 0 || res >= (int) sizeof(buf))
14081 return -1;
14082 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14083 if (system(buf) != 0) {
14084 send_resp(dut, conn, SIGMA_ERROR,
14085 "errorCode,Failed to set offchan");
14086 return 0;
14087 }
14088
14089 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsecchnoffst %d",
14090 intf, off_chan_val(sec));
14091 if (res < 0 || res >= (int) sizeof(buf))
14092 return -1;
14093 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14094 if (system(buf) != 0) {
14095 send_resp(dut, conn, SIGMA_ERROR,
14096 "errorCode,Failed to set sec chan offset");
14097 return 0;
14098 }
14099
14100 return 1;
14101}
14102
14103
14104static int tdls_set_offchannel_offset(struct sigma_dut *dut,
14105 struct sigma_conn *conn,
14106 const char *intf, int off_ch_num,
14107 enum sec_ch_offset sec)
14108{
14109 char buf[200];
14110 int res;
14111
14112 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNEL %d",
14113 off_ch_num);
14114 if (res < 0 || res >= (int) sizeof(buf))
14115 return -1;
14116 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14117
14118 if (wpa_command(intf, buf) < 0) {
14119 send_resp(dut, conn, SIGMA_ERROR,
14120 "ErrorCode,Failed to set offchan");
14121 return 0;
14122 }
14123 res = snprintf(buf, sizeof(buf), "DRIVER TDLSSECONDARYCHANNELOFFSET %d",
14124 off_chan_val(sec));
14125 if (res < 0 || res >= (int) sizeof(buf))
14126 return -1;
14127
14128 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14129
14130 if (wpa_command(intf, buf) < 0) {
14131 send_resp(dut, conn, SIGMA_ERROR,
14132 "ErrorCode,Failed to set sec chan offset");
14133 return 0;
14134 }
14135
14136 return 1;
14137}
14138
14139
14140static int tdls_set_offchannel_mode(struct sigma_dut *dut,
14141 struct sigma_conn *conn,
14142 const char *intf, int val)
14143{
14144 char buf[200];
14145 int res;
14146
14147 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNELMODE %d",
14148 val);
14149 if (res < 0 || res >= (int) sizeof(buf))
14150 return -1;
14151 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14152
14153 if (wpa_command(intf, buf) < 0) {
14154 send_resp(dut, conn, SIGMA_ERROR,
14155 "ErrorCode,Failed to configure offchannel mode");
14156 return 0;
14157 }
14158
14159 return 1;
14160}
14161
14162
14163static int cmd_sta_set_rfeature_tdls(const char *intf, struct sigma_dut *dut,
14164 struct sigma_conn *conn,
14165 struct sigma_cmd *cmd)
14166{
14167 const char *val;
14168 enum {
14169 CHSM_NOT_SET,
14170 CHSM_ENABLE,
14171 CHSM_DISABLE,
14172 CHSM_REJREQ,
14173 CHSM_UNSOLRESP
14174 } chsm = CHSM_NOT_SET;
14175 int off_ch_num = -1;
14176 enum sec_ch_offset sec_ch = SEC_CH_NO;
14177 int res;
14178
14179 val = get_param(cmd, "Uapsd");
14180 if (val) {
14181 char buf[100];
14182 if (strcasecmp(val, "Enable") == 0)
14183 snprintf(buf, sizeof(buf), "SET ps 99");
14184 else if (strcasecmp(val, "Disable") == 0)
14185 snprintf(buf, sizeof(buf), "SET ps 98");
14186 else {
14187 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
14188 "Unsupported uapsd parameter value");
14189 return 0;
14190 }
14191 if (wpa_command(intf, buf)) {
14192 send_resp(dut, conn, SIGMA_ERROR,
14193 "ErrorCode,Failed to change U-APSD "
14194 "powersave mode");
14195 return 0;
14196 }
14197 }
14198
14199 val = get_param(cmd, "TPKTIMER");
14200 if (val && strcasecmp(val, "DISABLE") == 0) {
14201 if (wpa_command(intf, "SET tdls_testing 0x100")) {
14202 send_resp(dut, conn, SIGMA_ERROR,
14203 "ErrorCode,Failed to enable no TPK "
14204 "expiration test mode");
14205 return 0;
14206 }
14207 dut->no_tpk_expiration = 1;
14208 }
14209
14210 val = get_param(cmd, "ChSwitchMode");
14211 if (val) {
14212 if (strcasecmp(val, "Enable") == 0 ||
14213 strcasecmp(val, "Initiate") == 0)
14214 chsm = CHSM_ENABLE;
14215 else if (strcasecmp(val, "Disable") == 0 ||
14216 strcasecmp(val, "passive") == 0)
14217 chsm = CHSM_DISABLE;
14218 else if (strcasecmp(val, "RejReq") == 0)
14219 chsm = CHSM_REJREQ;
14220 else if (strcasecmp(val, "UnSolResp") == 0)
14221 chsm = CHSM_UNSOLRESP;
14222 else {
14223 send_resp(dut, conn, SIGMA_ERROR,
14224 "ErrorCode,Unknown ChSwitchMode value");
14225 return 0;
14226 }
14227 }
14228
14229 val = get_param(cmd, "OffChNum");
14230 if (val) {
14231 off_ch_num = atoi(val);
14232 if (off_ch_num == 0) {
14233 send_resp(dut, conn, SIGMA_ERROR,
14234 "ErrorCode,Invalid OffChNum");
14235 return 0;
14236 }
14237 }
14238
14239 val = get_param(cmd, "SecChOffset");
14240 if (val) {
14241 if (strcmp(val, "20") == 0)
14242 sec_ch = SEC_CH_NO;
14243 else if (strcasecmp(val, "40above") == 0)
14244 sec_ch = SEC_CH_40ABOVE;
14245 else if (strcasecmp(val, "40below") == 0)
14246 sec_ch = SEC_CH_40BELOW;
14247 else {
14248 send_resp(dut, conn, SIGMA_ERROR,
14249 "ErrorCode,Unknown SecChOffset value");
14250 return 0;
14251 }
14252 }
14253
14254 if (chsm == CHSM_NOT_SET) {
14255 /* no offchannel changes requested */
14256 return 1;
14257 }
14258
Jouni Malinen016ae6c2019-11-04 17:00:01 +020014259 if (strcmp(intf, get_main_ifname(dut)) != 0 &&
14260 strcmp(intf, get_station_ifname(dut)) != 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014261 send_resp(dut, conn, SIGMA_ERROR,
14262 "ErrorCode,Unknown interface");
14263 return 0;
14264 }
14265
14266 switch (chsm) {
14267 case CHSM_NOT_SET:
Jouni Malinen280f5ba2016-08-29 21:33:10 +030014268 res = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014269 break;
14270 case CHSM_ENABLE:
14271 if (off_ch_num < 0) {
14272 send_resp(dut, conn, SIGMA_ERROR,
14273 "ErrorCode,Missing OffChNum argument");
14274 return 0;
14275 }
14276 if (wifi_chip_type == DRIVER_WCN) {
14277 res = tdls_set_offchannel_offset(dut, conn, intf,
14278 off_ch_num, sec_ch);
14279 } else {
14280 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
14281 sec_ch);
14282 }
14283 if (res != 1)
14284 return res;
14285 if (wifi_chip_type == DRIVER_WCN)
14286 res = tdls_set_offchannel_mode(dut, conn, intf, 1);
14287 else
14288 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 1);
14289 break;
14290 case CHSM_DISABLE:
14291 if (wifi_chip_type == DRIVER_WCN)
14292 res = tdls_set_offchannel_mode(dut, conn, intf, 2);
14293 else
14294 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 2);
14295 break;
14296 case CHSM_REJREQ:
14297 if (wifi_chip_type == DRIVER_WCN)
14298 res = tdls_set_offchannel_mode(dut, conn, intf, 3);
14299 else
14300 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 3);
14301 break;
14302 case CHSM_UNSOLRESP:
14303 if (off_ch_num < 0) {
14304 send_resp(dut, conn, SIGMA_ERROR,
14305 "ErrorCode,Missing OffChNum argument");
14306 return 0;
14307 }
14308 if (wifi_chip_type == DRIVER_WCN) {
14309 res = tdls_set_offchannel_offset(dut, conn, intf,
14310 off_ch_num, sec_ch);
14311 } else {
14312 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
14313 sec_ch);
14314 }
14315 if (res != 1)
14316 return res;
14317 if (wifi_chip_type == DRIVER_WCN)
14318 res = tdls_set_offchannel_mode(dut, conn, intf, 4);
14319 else
14320 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 4);
14321 break;
14322 }
14323
14324 return res;
14325}
14326
14327
14328static int ath_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
14329 struct sigma_conn *conn,
14330 struct sigma_cmd *cmd)
14331{
14332 const char *val;
Srikanth Marepalli5415acf2018-08-27 12:53:11 +053014333 char *token = NULL, *result;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014334
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -070014335 novap_reset(dut, intf, 1);
priyadharshini gowthamane5e25172015-12-08 14:53:48 -080014336
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014337 val = get_param(cmd, "nss_mcs_opt");
14338 if (val) {
14339 /* String (nss_operating_mode; mcs_operating_mode) */
14340 int nss, mcs;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053014341 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014342
14343 token = strdup(val);
14344 if (!token)
14345 return 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053014346 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +053014347 if (!result) {
14348 sigma_dut_print(dut, DUT_MSG_ERROR,
14349 "VHT NSS not specified");
14350 goto failed;
14351 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014352 if (strcasecmp(result, "def") != 0) {
14353 nss = atoi(result);
14354 if (nss == 4)
14355 ath_disable_txbf(dut, intf);
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070014356 if (run_iwpriv(dut, intf, "nss %d", nss) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014357 goto failed;
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070014358
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014359 }
14360
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053014361 result = strtok_r(NULL, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +053014362 if (!result) {
14363 sigma_dut_print(dut, DUT_MSG_ERROR,
14364 "VHT MCS not specified");
14365 goto failed;
14366 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014367 if (strcasecmp(result, "def") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070014368 if (run_iwpriv(dut, intf, "set11NRates 0") < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014369 goto failed;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014370 } else {
14371 mcs = atoi(result);
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070014372 if (run_iwpriv(dut, intf, "vhtmcs %d", mcs) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014373 goto failed;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014374 }
14375 /* Channel width gets messed up, fix this */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070014376 run_iwpriv(dut, intf, "chwidth %d", dut->chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014377 }
14378
Srikanth Marepalli5415acf2018-08-27 12:53:11 +053014379 free(token);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014380 return 1;
14381failed:
14382 free(token);
14383 return 0;
14384}
14385
14386
14387static int cmd_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
14388 struct sigma_conn *conn,
14389 struct sigma_cmd *cmd)
14390{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020014391 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014392 case DRIVER_ATHEROS:
14393 return ath_sta_set_rfeature_vht(intf, dut, conn, cmd);
14394 default:
14395 send_resp(dut, conn, SIGMA_ERROR,
14396 "errorCode,Unsupported sta_set_rfeature(VHT) with the current driver");
14397 return 0;
14398 }
14399}
14400
14401
Jouni Malinen1702fe32021-06-08 19:08:01 +030014402static enum sigma_cmd_result
14403wcn_sta_set_rfeature_he(const char *intf, struct sigma_dut *dut,
14404 struct sigma_conn *conn, struct sigma_cmd *cmd)
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014405{
14406 const char *val;
14407 char *token = NULL, *result;
14408 char buf[60];
14409
14410 val = get_param(cmd, "nss_mcs_opt");
14411 if (val) {
14412 /* String (nss_operating_mode; mcs_operating_mode) */
14413 int nss, mcs, ratecode;
14414 char *saveptr;
14415
14416 token = strdup(val);
14417 if (!token)
Jouni Malinen1702fe32021-06-08 19:08:01 +030014418 return ERROR_SEND_STATUS;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014419
14420 result = strtok_r(token, ";", &saveptr);
14421 if (!result) {
14422 sigma_dut_print(dut, DUT_MSG_ERROR,
14423 "HE NSS not specified");
14424 goto failed;
14425 }
14426 nss = 1;
14427 if (strcasecmp(result, "def") != 0)
14428 nss = atoi(result);
14429
14430 result = strtok_r(NULL, ";", &saveptr);
14431 if (!result) {
14432 sigma_dut_print(dut, DUT_MSG_ERROR,
14433 "HE MCS not specified");
14434 goto failed;
14435 }
14436 mcs = 7;
14437 if (strcasecmp(result, "def") != 0)
14438 mcs = atoi(result);
14439
Arif Hussain557bf412018-05-25 17:29:36 -070014440 ratecode = 0x20; /* for nss:1 MCS 0 */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014441 if (nss == 2) {
Arif Hussain557bf412018-05-25 17:29:36 -070014442 ratecode = 0x40; /* for nss:2 MCS 0 */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014443 } else if (nss > 2) {
14444 sigma_dut_print(dut, DUT_MSG_ERROR,
14445 "HE NSS %d not supported", nss);
14446 goto failed;
14447 }
14448
Arif Hussain557bf412018-05-25 17:29:36 -070014449 snprintf(buf, sizeof(buf), "iwpriv %s nss %d", intf, nss);
14450 if (system(buf) != 0) {
14451 sigma_dut_print(dut, DUT_MSG_ERROR,
14452 "nss_mcs_opt: iwpriv %s nss %d failed",
14453 intf, nss);
14454 goto failed;
14455 }
Arif Hussainac6c5112018-05-25 17:34:00 -070014456 dut->sta_nss = nss;
Arif Hussain557bf412018-05-25 17:29:36 -070014457
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014458 /* Add the MCS to the ratecode */
14459 if (mcs >= 0 && mcs <= 11) {
14460 ratecode += mcs;
Arif Hussain557bf412018-05-25 17:29:36 -070014461#ifdef NL80211_SUPPORT
14462 if (dut->device_type == STA_testbed) {
14463 enum he_mcs_config mcs_config;
14464 int ret;
14465
14466 if (mcs <= 7)
14467 mcs_config = HE_80_MCS0_7;
14468 else if (mcs <= 9)
14469 mcs_config = HE_80_MCS0_9;
14470 else
14471 mcs_config = HE_80_MCS0_11;
14472 ret = sta_set_he_mcs(dut, intf, mcs_config);
14473 if (ret) {
14474 sigma_dut_print(dut, DUT_MSG_ERROR,
14475 "nss_mcs_opt: mcs setting failed, mcs:%d, mcs_config %d, ret:%d",
14476 mcs, mcs_config, ret);
14477 goto failed;
14478 }
14479 }
14480#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014481 } else {
14482 sigma_dut_print(dut, DUT_MSG_ERROR,
14483 "HE MCS %d not supported", mcs);
14484 goto failed;
14485 }
14486 snprintf(buf, sizeof(buf), "iwpriv %s set_11ax_rate 0x%03x",
14487 intf, ratecode);
14488 if (system(buf) != 0) {
14489 sigma_dut_print(dut, DUT_MSG_ERROR,
14490 "iwpriv setting of 11ax rates failed");
14491 goto failed;
14492 }
14493 free(token);
14494 }
14495
14496 val = get_param(cmd, "GI");
14497 if (val) {
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080014498 int fix_rate_sgi;
14499
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014500 if (strcmp(val, "0.8") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070014501 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 9", intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080014502 fix_rate_sgi = 1;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014503 } else if (strcmp(val, "1.6") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070014504 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 10",
14505 intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080014506 fix_rate_sgi = 2;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014507 } else if (strcmp(val, "3.2") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070014508 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 11",
14509 intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080014510 fix_rate_sgi = 3;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014511 } else {
14512 send_resp(dut, conn, SIGMA_ERROR,
14513 "errorCode,GI value not supported");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014514 return STATUS_SENT_ERROR;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014515 }
14516 if (system(buf) != 0) {
14517 send_resp(dut, conn, SIGMA_ERROR,
14518 "errorCode,Failed to set shortgi");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014519 return STATUS_SENT_ERROR;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014520 }
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080014521 snprintf(buf, sizeof(buf), "iwpriv %s shortgi %d",
14522 intf, fix_rate_sgi);
14523 if (system(buf) != 0) {
14524 send_resp(dut, conn, SIGMA_ERROR,
14525 "errorCode,Failed to set fix rate shortgi");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014526 return STATUS_SENT_ERROR;
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080014527 }
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014528 }
14529
Subhani Shaik8e7a3052018-04-24 14:03:00 -070014530 val = get_param(cmd, "LTF");
14531 if (val) {
14532#ifdef NL80211_SUPPORT
14533 if (strcmp(val, "3.2") == 0) {
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -080014534 wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_1X);
Subhani Shaik8e7a3052018-04-24 14:03:00 -070014535 } if (strcmp(val, "6.4") == 0) {
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -080014536 wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_2X);
Subhani Shaik8e7a3052018-04-24 14:03:00 -070014537 } else if (strcmp(val, "12.8") == 0) {
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -080014538 wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_4X);
Subhani Shaik8e7a3052018-04-24 14:03:00 -070014539 } else {
14540 send_resp(dut, conn, SIGMA_ERROR,
14541 "errorCode, LTF value not supported");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014542 return STATUS_SENT_ERROR;
Subhani Shaik8e7a3052018-04-24 14:03:00 -070014543 }
14544#else /* NL80211_SUPPORT */
14545 sigma_dut_print(dut, DUT_MSG_ERROR,
14546 "LTF cannot be set without NL80211_SUPPORT defined");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014547 return ERROR_SEND_STATUS;
Subhani Shaik8e7a3052018-04-24 14:03:00 -070014548#endif /* NL80211_SUPPORT */
14549 }
14550
Kiran Kumar Lokere1809da12021-06-24 00:45:38 -070014551 val = get_param(cmd, "KeepAlive");
14552 if (val) {
14553 int set_val = QCA_WLAN_KEEP_ALIVE_DEFAULT;
14554
14555 if (strcasecmp(val, "Data") == 0)
14556 set_val = QCA_WLAN_KEEP_ALIVE_DATA;
14557 else if (strcasecmp(val, "Mgmt") == 0)
14558 set_val = QCA_WLAN_KEEP_ALIVE_MGMT;
14559
14560 if (sta_set_keep_alive_data_cfg(dut, intf, set_val)) {
14561 send_resp(dut, conn, SIGMA_ERROR,
14562 "ErrorCode,Failed to set keep alive type config");
14563 return STATUS_SENT_ERROR;
14564 }
14565 }
14566
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -070014567 val = get_param(cmd, "TxSUPPDU");
14568 if (val) {
14569 int set_val = 1;
14570
14571 if (strcasecmp(val, "Enable") == 0)
14572 set_val = 1;
14573 else if (strcasecmp(val, "Disable") == 0)
14574 set_val = 0;
14575
14576 if (sta_set_tx_su_ppdu_cfg(dut, intf, set_val)) {
14577 send_resp(dut, conn, SIGMA_ERROR,
14578 "ErrorCode,Failed to set Tx SU PPDU config");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014579 return STATUS_SENT_ERROR;
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -070014580 }
14581 }
14582
Kiran Kumar Lokere54b72522021-04-01 00:22:44 -070014583 val = get_param(cmd, "Mgmt_Data_TX_Resp_Frame");
14584 if (val) {
14585 int set_val = 0;
14586
14587 if (strcasecmp(val, "Enable") == 0)
14588 set_val = 0;
14589 else if (strcasecmp(val, "Disable") == 0)
14590 set_val = 1;
14591
14592 if (sta_set_mgmt_data_tx_disable_cfg(dut, intf, set_val)) {
14593 send_resp(dut, conn, SIGMA_ERROR,
14594 "ErrorCode,Failed to set mgmt/data Tx disable config");
14595 return STATUS_SENT_ERROR;
14596 }
14597 }
14598
Arif Hussain480d5f42019-03-12 14:40:42 -070014599 val = get_param(cmd, "TWT_Setup");
14600 if (val) {
14601 if (strcasecmp(val, "Request") == 0) {
Kiran Kumar Lokereafac46a2021-11-29 14:03:20 -080014602 if (set_power_save_wcn(dut, intf, 1) < 0)
14603 sigma_dut_print(dut, DUT_MSG_ERROR,
14604 "Failed to enable power save");
Arif Hussain480d5f42019-03-12 14:40:42 -070014605 if (sta_twt_request(dut, conn, cmd)) {
14606 send_resp(dut, conn, SIGMA_ERROR,
Srinivas Girigowda6707f032020-10-26 15:24:46 -070014607 "ErrorCode,TWT setup failed");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014608 return STATUS_SENT_ERROR;
Arif Hussain480d5f42019-03-12 14:40:42 -070014609 }
14610 } else if (strcasecmp(val, "Teardown") == 0) {
14611 if (sta_twt_teardown(dut, conn, cmd)) {
14612 send_resp(dut, conn, SIGMA_ERROR,
Srinivas Girigowda6707f032020-10-26 15:24:46 -070014613 "ErrorCode,TWT teardown failed");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014614 return STATUS_SENT_ERROR;
Arif Hussain480d5f42019-03-12 14:40:42 -070014615 }
14616 }
14617 }
14618
Srinivas Girigowda6707f032020-10-26 15:24:46 -070014619 val = get_param(cmd, "TWT_Operation");
14620 if (val) {
14621 if (strcasecmp(val, "Suspend") == 0) {
14622 if (sta_twt_suspend_or_nudge(dut, conn, cmd)) {
14623 send_resp(dut, conn, SIGMA_ERROR,
14624 "ErrorCode,TWT suspend failed");
14625 return STATUS_SENT_ERROR;
14626 }
14627 } else if (strcasecmp(val, "Resume") == 0) {
14628 if (sta_twt_resume(dut, conn, cmd)) {
14629 send_resp(dut, conn, SIGMA_ERROR,
14630 "ErrorCode,TWT resume failed");
14631 return STATUS_SENT_ERROR;
14632 }
14633 }
14634 }
14635
Kiran Kumar Lokere50eb2cd2018-12-18 18:31:28 -080014636 val = get_param(cmd, "transmitOMI");
14637 if (val && sta_transmit_omi(dut, conn, cmd)) {
14638 send_resp(dut, conn, SIGMA_ERROR,
14639 "ErrorCode,sta_transmit_omi failed");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014640 return STATUS_SENT_ERROR;
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -070014641 }
14642
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080014643 val = get_param(cmd, "Powersave");
14644 if (val) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014645 int ps;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080014646
14647 if (strcasecmp(val, "off") == 0) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014648 ps = 2;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080014649 } else if (strcasecmp(val, "on") == 0) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014650 ps = 1;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080014651 } else {
14652 sigma_dut_print(dut, DUT_MSG_ERROR,
14653 "Unsupported Powersave value '%s'",
14654 val);
Jouni Malinen1702fe32021-06-08 19:08:01 +030014655 return INVALID_SEND_STATUS;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080014656 }
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014657 if (set_power_save_wcn(dut, intf, ps) < 0)
Jouni Malinen1702fe32021-06-08 19:08:01 +030014658 return ERROR_SEND_STATUS;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080014659 }
14660
Kiran Kumar Lokere2c4b7ce2019-01-30 12:02:28 -080014661 val = get_param(cmd, "MU_EDCA");
14662 if (val) {
14663 if (strcasecmp(val, "Override") == 0) {
14664 if (sta_set_mu_edca_override(dut, intf, 1)) {
14665 send_resp(dut, conn, SIGMA_ERROR,
14666 "errorCode,MU EDCA override set failed");
14667 return STATUS_SENT;
14668 }
14669 } else if (strcasecmp(val, "Disable") == 0) {
14670 if (sta_set_mu_edca_override(dut, intf, 0)) {
14671 send_resp(dut, conn, SIGMA_ERROR,
14672 "errorCode,MU EDCA override disable failed");
14673 return STATUS_SENT;
14674 }
14675 }
14676 }
14677
Kiran Kumar Lokerefa7c7b92021-08-09 00:50:55 -070014678 val = get_param(cmd, "RUAllocTone");
14679 if (val && strcasecmp(val, "242") == 0) {
14680 if (sta_set_ru_242_tone_tx(dut, intf, 1)) {
14681 send_resp(dut, conn, SIGMA_ERROR,
14682 "ErrorCode,Failed to set RU 242 tone Tx");
14683 return STATUS_SENT_ERROR;
14684 }
14685 }
14686
14687 val = get_param(cmd, "PPDUTxType");
14688 if (val && strcasecmp(val, "ER-SU") == 0) {
14689 if (sta_set_er_su_ppdu_type_tx(dut, intf, 1)) {
14690 send_resp(dut, conn, SIGMA_ERROR,
14691 "ErrorCode,Failed to set ER-SU PPDU type Tx");
14692 return STATUS_SENT_ERROR;
14693 }
14694 }
14695
Kiran Kumar Lokeredd086642020-06-04 00:29:26 -070014696 val = get_param(cmd, "Ch_Pref");
14697 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
14698 return STATUS_SENT;
14699
14700 val = get_param(cmd, "Cellular_Data_Cap");
14701 if (val && mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
14702 return STATUS_SENT;
14703
Jouni Malinen1702fe32021-06-08 19:08:01 +030014704 return SUCCESS_SEND_STATUS;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014705
14706failed:
14707 free(token);
Jouni Malinen1702fe32021-06-08 19:08:01 +030014708 return ERROR_SEND_STATUS;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014709}
14710
14711
Jouni Malinen1702fe32021-06-08 19:08:01 +030014712static enum sigma_cmd_result
14713cmd_sta_set_rfeature_he(const char *intf, struct sigma_dut *dut,
14714 struct sigma_conn *conn, struct sigma_cmd *cmd)
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014715{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020014716 switch (get_driver_type(dut)) {
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014717 case DRIVER_WCN:
14718 return wcn_sta_set_rfeature_he(intf, dut, conn, cmd);
14719 default:
14720 send_resp(dut, conn, SIGMA_ERROR,
14721 "errorCode,Unsupported sta_set_rfeature(HE) with the current driver");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014722 return STATUS_SENT_ERROR;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014723 }
14724}
14725
14726
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080014727static int cmd_sta_set_power_save_he(const char *intf, struct sigma_dut *dut,
14728 struct sigma_conn *conn,
14729 struct sigma_cmd *cmd)
14730{
14731 const char *val;
14732
14733 val = get_param(cmd, "powersave");
14734 if (val) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014735 int ps;
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080014736
14737 if (strcasecmp(val, "off") == 0) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014738 ps = 2;
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080014739 } else if (strcasecmp(val, "on") == 0) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014740 ps = 1;
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080014741 } else {
14742 sigma_dut_print(dut, DUT_MSG_ERROR,
14743 "Unsupported power save config");
14744 return -1;
14745 }
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014746 if (set_power_save_wcn(dut, intf, ps) < 0)
14747 return 0;
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080014748 return 1;
14749 }
14750
14751 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported command");
14752
14753 return 0;
14754}
14755
14756
Ashwini Patil5acd7382017-04-13 15:55:04 +053014757static int btm_query_candidate_list(struct sigma_dut *dut,
14758 struct sigma_conn *conn,
14759 struct sigma_cmd *cmd)
14760{
14761 const char *bssid, *info, *op_class, *ch, *phy_type, *pref;
14762 int len, ret;
14763 char buf[10];
14764
14765 /*
14766 * Neighbor Report elements format:
14767 * neighbor=<BSSID>,<BSSID Information>,<Operating Class>,
14768 * <Channel Number>,<PHY Type>[,<hexdump of Optional Subelements>]
14769 * eg: neighbor=aa:bb:cc:dd:ee:ff,17,81,6,1,030101
14770 */
14771
14772 bssid = get_param(cmd, "Nebor_BSSID");
14773 if (!bssid) {
14774 send_resp(dut, conn, SIGMA_INVALID,
14775 "errorCode,Nebor_BSSID is missing");
14776 return 0;
14777 }
14778
14779 info = get_param(cmd, "Nebor_Bssid_Info");
14780 if (!info) {
14781 sigma_dut_print(dut, DUT_MSG_INFO,
14782 "Using default value for Nebor_Bssid_Info: %s",
14783 DEFAULT_NEIGHBOR_BSSID_INFO);
14784 info = DEFAULT_NEIGHBOR_BSSID_INFO;
14785 }
14786
14787 op_class = get_param(cmd, "Nebor_Op_Class");
14788 if (!op_class) {
14789 send_resp(dut, conn, SIGMA_INVALID,
14790 "errorCode,Nebor_Op_Class is missing");
14791 return 0;
14792 }
14793
14794 ch = get_param(cmd, "Nebor_Op_Ch");
14795 if (!ch) {
14796 send_resp(dut, conn, SIGMA_INVALID,
14797 "errorCode,Nebor_Op_Ch is missing");
14798 return 0;
14799 }
14800
14801 phy_type = get_param(cmd, "Nebor_Phy_Type");
14802 if (!phy_type) {
14803 sigma_dut_print(dut, DUT_MSG_INFO,
14804 "Using default value for Nebor_Phy_Type: %s",
14805 DEFAULT_NEIGHBOR_PHY_TYPE);
14806 phy_type = DEFAULT_NEIGHBOR_PHY_TYPE;
14807 }
14808
14809 /* Parse optional subelements */
14810 buf[0] = '\0';
14811 pref = get_param(cmd, "Nebor_Pref");
14812 if (pref) {
14813 /* hexdump for preferrence subelement */
14814 ret = snprintf(buf, sizeof(buf), ",0301%02x", atoi(pref));
14815 if (ret < 0 || ret >= (int) sizeof(buf)) {
14816 sigma_dut_print(dut, DUT_MSG_ERROR,
14817 "snprintf failed for optional subelement ret: %d",
14818 ret);
14819 send_resp(dut, conn, SIGMA_ERROR,
14820 "errorCode,snprintf failed for subelement");
14821 return 0;
14822 }
14823 }
14824
14825 if (!dut->btm_query_cand_list) {
14826 dut->btm_query_cand_list = calloc(1, NEIGHBOR_REPORT_SIZE);
14827 if (!dut->btm_query_cand_list) {
14828 send_resp(dut, conn, SIGMA_ERROR,
14829 "errorCode,Failed to allocate memory for btm_query_cand_list");
14830 return 0;
14831 }
14832 }
14833
14834 len = strlen(dut->btm_query_cand_list);
14835 ret = snprintf(dut->btm_query_cand_list + len,
14836 NEIGHBOR_REPORT_SIZE - len, " neighbor=%s,%s,%s,%s,%s%s",
14837 bssid, info, op_class, ch, phy_type, buf);
14838 if (ret < 0 || ret >= NEIGHBOR_REPORT_SIZE - len) {
14839 sigma_dut_print(dut, DUT_MSG_ERROR,
14840 "snprintf failed for neighbor report list ret: %d",
14841 ret);
14842 send_resp(dut, conn, SIGMA_ERROR,
14843 "errorCode,snprintf failed for neighbor report");
14844 free(dut->btm_query_cand_list);
14845 dut->btm_query_cand_list = NULL;
14846 return 0;
14847 }
14848
14849 return 1;
14850}
14851
14852
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020014853int sta_extract_60g_ese(struct sigma_dut *dut, struct sigma_cmd *cmd,
14854 struct sigma_ese_alloc *allocs, int *allocs_size)
14855{
14856 int max_count = *allocs_size;
14857 int count = 0, i;
14858 const char *val;
14859
14860 do {
14861 val = get_param_indexed(cmd, "AllocID", count);
14862 if (val)
14863 count++;
14864 } while (val);
14865
14866 if (count == 0 || count > max_count) {
14867 sigma_dut_print(dut, DUT_MSG_ERROR,
14868 "Invalid number of allocations(%d)", count);
14869 return -1;
14870 }
14871
14872 for (i = 0; i < count; i++) {
14873 val = get_param_indexed(cmd, "PercentBI", i);
14874 if (!val) {
14875 sigma_dut_print(dut, DUT_MSG_ERROR,
14876 "Missing PercentBI parameter at index %d",
14877 i);
14878 return -1;
14879 }
14880 allocs[i].percent_bi = atoi(val);
14881
14882 val = get_param_indexed(cmd, "SrcAID", i);
14883 if (val)
14884 allocs[i].src_aid = strtol(val, NULL, 0);
14885 else
14886 allocs[i].src_aid = ESE_BCAST_AID;
14887
14888 val = get_param_indexed(cmd, "DestAID", i);
14889 if (val)
14890 allocs[i].dst_aid = strtol(val, NULL, 0);
14891 else
14892 allocs[i].dst_aid = ESE_BCAST_AID;
14893
14894 allocs[i].type = ESE_CBAP;
14895 sigma_dut_print(dut, DUT_MSG_INFO,
14896 "Alloc %d PercentBI %d SrcAID %d DstAID %d",
14897 i, allocs[i].percent_bi, allocs[i].src_aid,
14898 allocs[i].dst_aid);
14899 }
14900
14901 *allocs_size = count;
14902 return 0;
14903}
14904
14905
14906static int sta_set_60g_ese(struct sigma_dut *dut, int count,
14907 struct sigma_ese_alloc *allocs)
14908{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020014909 switch (get_driver_type(dut)) {
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020014910#ifdef __linux__
14911 case DRIVER_WIL6210:
14912 if (wil6210_set_ese(dut, count, allocs))
14913 return -1;
14914 return 1;
14915#endif /* __linux__ */
14916 default:
14917 sigma_dut_print(dut, DUT_MSG_ERROR,
14918 "Unsupported sta_set_60g_ese with the current driver");
14919 return -1;
14920 }
14921}
14922
14923
14924static int cmd_sta_set_rfeature_60g(const char *intf, struct sigma_dut *dut,
14925 struct sigma_conn *conn,
14926 struct sigma_cmd *cmd)
14927{
14928 const char *val;
14929
14930 val = get_param(cmd, "ExtSchIE");
14931 if (val && !strcasecmp(val, "Enable")) {
14932 struct sigma_ese_alloc allocs[MAX_ESE_ALLOCS];
14933 int count = MAX_ESE_ALLOCS;
14934
14935 if (sta_extract_60g_ese(dut, cmd, allocs, &count))
14936 return -1;
14937 return sta_set_60g_ese(dut, count, allocs);
14938 }
14939
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +020014940 val = get_param(cmd, "MCS_FixedRate");
14941 if (val) {
14942 int sta_mcs = atoi(val);
14943
14944 sigma_dut_print(dut, DUT_MSG_INFO, "Force STA MCS to %d",
14945 sta_mcs);
14946 wil6210_set_force_mcs(dut, 1, sta_mcs);
14947
Jouni Malinen0e29cf22019-02-19 01:13:21 +020014948 return SUCCESS_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +020014949 }
14950
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020014951 send_resp(dut, conn, SIGMA_ERROR,
14952 "errorCode,Invalid sta_set_rfeature(60G)");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020014953 return STATUS_SENT;
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020014954}
14955
14956
Veerendranath Jakkam76a845c2020-07-14 13:19:40 +053014957static int wcn_sta_override_oci(struct sigma_dut *dut, const char *intf,
14958 const char *oci_frametype, uint32_t oci_freq)
14959{
14960#ifdef NL80211_SUPPORT
14961 struct nl_msg *msg;
14962 int ret = 0;
14963 struct nlattr *params;
14964 struct nlattr *attr;
14965 int ifindex;
14966 u8 frame_type;
14967
14968 ifindex = if_nametoindex(intf);
14969 if (ifindex == 0) {
14970 sigma_dut_print(dut, DUT_MSG_ERROR,
14971 "%s: Index for interface %s failed",
14972 __func__, intf);
14973 return -1;
14974 }
14975
14976 if (strcasecmp(oci_frametype, "SAQueryReq") == 0) {
14977 frame_type = QCA_WLAN_VENDOR_OCI_OVERRIDE_FRAME_SA_QUERY_REQ;
14978 } else if (strcasecmp(oci_frametype, "SAQueryResp") == 0) {
14979 frame_type = QCA_WLAN_VENDOR_OCI_OVERRIDE_FRAME_SA_QUERY_RESP;
14980 } else if (strcasecmp(oci_frametype, "Reassocreq") == 0) {
14981 frame_type = QCA_WLAN_VENDOR_OCI_OVERRIDE_FRAME_FT_REASSOC_REQ;
14982 } else {
14983 sigma_dut_print(dut, DUT_MSG_ERROR, "%s: Unknown frametype %s",
14984 __func__, oci_frametype);
14985 return -1;
14986 }
14987
14988
14989 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
14990 NL80211_CMD_VENDOR)) ||
14991 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
14992 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
14993 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
14994 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
14995 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
14996 !(params = nla_nest_start(
14997 msg,
14998 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_OCI_OVERRIDE)) ||
14999 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_OCI_OVERRIDE_FRAME_TYPE,
15000 frame_type) ||
15001 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_OCI_OVERRIDE_FREQUENCY,
15002 oci_freq)) {
15003 sigma_dut_print(dut, DUT_MSG_ERROR,
15004 "%s: err in adding vendor_cmd and vendor_data",
15005 __func__);
15006 nlmsg_free(msg);
15007 return -1;
15008 }
15009 nla_nest_end(msg, params);
15010 nla_nest_end(msg, attr);
15011
15012 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
15013 if (ret) {
15014 sigma_dut_print(dut, DUT_MSG_ERROR,
15015 "%s: err in send_and_recv_msgs, ret=%d",
15016 __func__, ret);
15017 }
15018 return ret;
15019#else /* NL80211_SUPPORT */
15020 sigma_dut_print(dut, DUT_MSG_ERROR,
15021 "OCI override not possible without NL80211_SUPPORT defined");
15022 return -1;
15023#endif /* NL80211_SUPPORT */
15024}
15025
15026
Veerendranath Jakkam50d5c782020-07-22 01:59:01 +053015027static int wcn_sta_ignore_csa(struct sigma_dut *dut, const char *intf,
15028 uint8_t ignore_csa)
15029{
15030#ifdef NL80211_SUPPORT
15031 return wcn_wifi_test_config_set_u8(
15032 dut, intf,
15033 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_IGNORE_CSA, ignore_csa);
15034#else /* NL80211_SUPPORT */
15035 sigma_dut_print(dut, DUT_MSG_ERROR,
15036 "IgnoreCSA can't be set without NL80211_SUPPORT defined");
15037 return -1;
15038#endif /* NL80211_SUPPORT */
15039}
15040
15041
Veerendranath Jakkamc771fac2020-07-22 01:32:56 +053015042static int wcn_sta_set_rsnxe_used(struct sigma_dut *dut, const char *intf,
15043 uint8_t rsnxe_used)
15044{
15045#ifdef NL80211_SUPPORT
15046 return wcn_wifi_test_config_set_u8(
15047 dut, intf,
15048 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_FT_REASSOCREQ_RSNXE_USED,
15049 rsnxe_used);
15050#else /* NL80211_SUPPORT */
15051 sigma_dut_print(dut, DUT_MSG_ERROR,
15052 "RSNXE_Used can't be set without NL80211_SUPPORT defined");
15053 return -1;
15054#endif /* NL80211_SUPPORT */
15055}
15056
15057
Veerendranath Jakkam1e1e5fd2020-09-10 07:12:37 +053015058static int wcn_sta_ignore_sa_query_timeout(struct sigma_dut *dut,
15059 const char *intf,
15060 uint8_t ignore_sa_query_timeout)
15061{
15062#ifdef NL80211_SUPPORT
15063 return wcn_wifi_test_config_set_u8(
15064 dut, intf,
15065 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_IGNORE_SA_QUERY_TIMEOUT,
15066 ignore_sa_query_timeout);
15067#else /* NL80211_SUPPORT */
15068 sigma_dut_print(dut, DUT_MSG_ERROR,
15069 "Ignore SA Query timeout can't be set without NL80211_SUPPORT defined");
15070 return -1;
15071#endif /* NL80211_SUPPORT */
15072}
15073
15074
Jouni Malinen6250cb02020-04-15 13:54:45 +030015075static enum sigma_cmd_result
15076cmd_sta_set_rfeature_wpa3(const char *intf, struct sigma_dut *dut,
15077 struct sigma_conn *conn,
15078 struct sigma_cmd *cmd)
15079{
Vamsi Krishnad29bc762020-05-08 23:23:30 +053015080 const char *val, *oci_chan, *oci_frametype;
Jouni Malinen6250cb02020-04-15 13:54:45 +030015081
Veerendranath Jakkam30bf9072020-04-16 14:37:57 +053015082 val = get_param(cmd, "ReassocReq_RSNXE_Used");
Jouni Malinen6250cb02020-04-15 13:54:45 +030015083 if (val && atoi(val) == 1) {
Veerendranath Jakkamc771fac2020-07-22 01:32:56 +053015084 if (wifi_chip_type == DRIVER_WCN) {
15085 if (wcn_sta_set_rsnxe_used(dut, intf, 1)) {
15086 send_resp(dut, conn, SIGMA_ERROR,
15087 "errorCode,Failed to set ft_rsnxe_used");
15088 return STATUS_SENT_ERROR;
15089 }
15090 return SUCCESS_SEND_STATUS;
15091 } else if (wpa_command(intf, "SET ft_rsnxe_used 1") < 0) {
Jouni Malinen6250cb02020-04-15 13:54:45 +030015092 send_resp(dut, conn, SIGMA_ERROR,
15093 "errorCode,Failed to set ft_rsnxe_used");
15094 return STATUS_SENT_ERROR;
15095 }
15096 return SUCCESS_SEND_STATUS;
15097 }
Vamsi Krishnad29bc762020-05-08 23:23:30 +053015098
15099 oci_chan = get_param(cmd, "OCIChannel");
15100 oci_frametype = get_param(cmd, "OCIFrameType");
15101 if (oci_chan && oci_frametype) {
15102 unsigned int oci_freq = channel_to_freq(dut, atoi(oci_chan));
15103 char buf[100];
15104
15105 if (!oci_freq) {
15106 send_resp(dut, conn, SIGMA_ERROR,
15107 "errorCode,Invalid OCIChannel number");
15108 return STATUS_SENT_ERROR;
15109 }
15110
Veerendranath Jakkam76a845c2020-07-14 13:19:40 +053015111 if (wifi_chip_type == DRIVER_WCN &&
15112 (strcasecmp(oci_frametype, "SAQueryReq") == 0 ||
15113 strcasecmp(oci_frametype, "SAQueryResp") == 0 ||
15114 strcasecmp(oci_frametype, "Reassocreq") == 0)) {
15115 if (wcn_sta_override_oci(dut, intf, oci_frametype,
15116 oci_freq)) {
15117 send_resp(dut, conn, SIGMA_ERROR,
15118 "errorCode,Failed to override OCI");
15119 return STATUS_SENT_ERROR;
15120 }
15121 return SUCCESS_SEND_STATUS;
15122 }
15123
Vamsi Krishnad29bc762020-05-08 23:23:30 +053015124 if (strcasecmp(oci_frametype, "eapolM2") == 0) {
15125 snprintf(buf, sizeof(buf),
15126 "SET oci_freq_override_eapol %d", oci_freq);
15127 } else if (strcasecmp(oci_frametype, "SAQueryReq") == 0) {
15128 snprintf(buf, sizeof(buf),
15129 "SET oci_freq_override_saquery_req %d",
15130 oci_freq);
15131 } else if (strcasecmp(oci_frametype, "SAQueryResp") == 0) {
15132 snprintf(buf, sizeof(buf),
15133 "SET oci_freq_override_saquery_resp %d",
15134 oci_freq);
Veerendranath Jakkam76a845c2020-07-14 13:19:40 +053015135 } else if (strcasecmp(oci_frametype, "GrpKeyM2") == 0) {
15136 snprintf(buf, sizeof(buf),
15137 "SET oci_freq_override_eapol_g2 %d",
15138 oci_freq);
15139 } else if (strcasecmp(oci_frametype, "Reassocreq") == 0) {
15140 snprintf(buf, sizeof(buf),
15141 "SET oci_freq_override_ft_assoc %d",
15142 oci_freq);
Vamsi Krishnad29bc762020-05-08 23:23:30 +053015143 } else {
15144 send_resp(dut, conn, SIGMA_ERROR,
15145 "errorCode,Unsupported OCIFrameType");
15146 return STATUS_SENT_ERROR;
15147 }
15148 if (wpa_command(intf, buf) < 0) {
15149 send_resp(dut, conn, SIGMA_ERROR,
15150 "errorCode,Failed to set oci_freq_override");
15151 return STATUS_SENT_ERROR;
15152 }
15153 return SUCCESS_SEND_STATUS;
15154 }
15155
Veerendranath Jakkam50d5c782020-07-22 01:59:01 +053015156 val = get_param(cmd, "IgnoreCSA");
15157 if (val && atoi(val) == 1) {
15158 if (wifi_chip_type == DRIVER_WCN) {
15159 if (wcn_sta_ignore_csa(dut, intf, 1)) {
15160 send_resp(dut, conn, SIGMA_ERROR,
15161 "errorCode,Failed to set ignore CSA");
15162 return STATUS_SENT_ERROR;
15163 }
15164 return SUCCESS_SEND_STATUS;
15165 }
15166 }
15167
Veerendranath Jakkam1e1e5fd2020-09-10 07:12:37 +053015168 val = get_param(cmd, "Deauth_Per_SAQueryResp");
15169 if (val && atoi(val) == 0) {
15170 if (wifi_chip_type == DRIVER_WCN) {
15171 if (wcn_sta_ignore_sa_query_timeout(dut, intf, 1)) {
15172 send_resp(dut, conn, SIGMA_ERROR,
15173 "errorCode,Failed to set ignore SA Query timeout");
15174 return STATUS_SENT_ERROR;
15175 }
15176 return SUCCESS_SEND_STATUS;
15177 }
15178 }
15179
Jouni Malinen6250cb02020-04-15 13:54:45 +030015180 send_resp(dut, conn, SIGMA_ERROR,
15181 "errorCode,Unsupported WPA3 rfeature");
15182 return STATUS_SENT_ERROR;
15183}
15184
15185
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053015186static enum sigma_cmd_result
15187cmd_sta_set_rfeature_qm(const char *intf, struct sigma_dut *dut,
15188 struct sigma_conn *conn, struct sigma_cmd *cmd)
15189{
15190 const char *val;
15191
15192 val = get_param(cmd, "DomainName_Domain");
15193 if (val) {
15194 if (strlen(val) >= sizeof(dut->qm_domain_name))
15195 return ERROR_SEND_STATUS;
15196
15197 strlcpy(dut->qm_domain_name, val, sizeof(dut->qm_domain_name));
15198 return SUCCESS_SEND_STATUS;
15199 }
15200
Veerendranath Jakkam1bf1bd62021-09-12 16:35:55 +053015201 val = get_param(cmd, "DSCPPolicy_PolicyID");
15202 if (val) {
15203 unsigned int i;
15204 int policy_id = atoi(val);
15205
15206 val = get_param(cmd, "DSCPPolicy_RequestType");
15207
15208 if (!policy_id || !val)
15209 return INVALID_SEND_STATUS;
15210
15211 if (dut->num_dscp_status >= ARRAY_SIZE(dut->dscp_status)) {
15212 send_resp(dut, conn, SIGMA_ERROR,
15213 "errorCode,DSCP status list full");
15214 return STATUS_SENT_ERROR;
15215 }
15216
15217 for (i = 0; i < dut->num_dscp_status; i++)
15218 if (dut->dscp_status[i].id == policy_id)
15219 break;
15220
15221 /* New policy configured */
15222 if (i == dut->num_dscp_status) {
15223 dut->dscp_status[i].id = policy_id;
15224 dut->num_dscp_status++;
15225 }
15226
15227 dut->dscp_status[i].status = strcasecmp(val, "Remove") ?
15228 DSCP_POLICY_SUCCESS : DSCP_POLICY_REJECT;
15229
15230 return SUCCESS_SEND_STATUS;
15231 }
15232
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053015233 send_resp(dut, conn, SIGMA_ERROR,
15234 "errorCode,Unsupported QM rfeature");
15235 return STATUS_SENT_ERROR;
15236}
15237
15238
Jouni Malinenf7222712019-06-13 01:50:21 +030015239static enum sigma_cmd_result cmd_sta_set_rfeature(struct sigma_dut *dut,
15240 struct sigma_conn *conn,
15241 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015242{
15243 const char *intf = get_param(cmd, "Interface");
15244 const char *prog = get_param(cmd, "Prog");
Ashwini Patil68d02cd2017-01-10 15:39:16 +053015245 const char *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015246
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053015247 if (!prog)
15248 prog = get_param(cmd, "Program");
15249
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015250 if (intf == NULL || prog == NULL)
15251 return -1;
15252
Ashwini Patil5acd7382017-04-13 15:55:04 +053015253 /* BSS Transition candidate list for BTM query */
15254 val = get_param(cmd, "Nebor_BSSID");
15255 if (val && btm_query_candidate_list(dut, conn, cmd) == 0)
15256 return 0;
15257
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015258 if (strcasecmp(prog, "TDLS") == 0)
15259 return cmd_sta_set_rfeature_tdls(intf, dut, conn, cmd);
15260
15261 if (strcasecmp(prog, "VHT") == 0)
15262 return cmd_sta_set_rfeature_vht(intf, dut, conn, cmd);
15263
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080015264 if (strcasecmp(prog, "HE") == 0)
15265 return cmd_sta_set_rfeature_he(intf, dut, conn, cmd);
15266
Ashwini Patil68d02cd2017-01-10 15:39:16 +053015267 if (strcasecmp(prog, "MBO") == 0) {
15268 val = get_param(cmd, "Cellular_Data_Cap");
15269 if (val &&
15270 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
15271 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +053015272
15273 val = get_param(cmd, "Ch_Pref");
15274 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
15275 return 0;
15276
Ashwini Patil68d02cd2017-01-10 15:39:16 +053015277 return 1;
15278 }
15279
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020015280 if (strcasecmp(prog, "60GHz") == 0)
15281 return cmd_sta_set_rfeature_60g(intf, dut, conn, cmd);
15282
Jouni Malinen6250cb02020-04-15 13:54:45 +030015283 if (strcasecmp(prog, "WPA3") == 0)
15284 return cmd_sta_set_rfeature_wpa3(intf, dut, conn, cmd);
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053015285 if (strcasecmp(prog, "QM") == 0)
15286 return cmd_sta_set_rfeature_qm(intf, dut, conn, cmd);
Jouni Malinen6250cb02020-04-15 13:54:45 +030015287
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015288 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported Prog");
15289 return 0;
15290}
15291
15292
Jouni Malinenf7222712019-06-13 01:50:21 +030015293static enum sigma_cmd_result cmd_sta_set_radio(struct sigma_dut *dut,
15294 struct sigma_conn *conn,
15295 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015296{
15297 const char *intf = get_param(cmd, "Interface");
15298 const char *mode = get_param(cmd, "Mode");
15299 int res;
15300
15301 if (intf == NULL || mode == NULL)
15302 return -1;
15303
15304 if (strcasecmp(mode, "On") == 0)
15305 res = wpa_command(intf, "SET radio_disabled 0");
15306 else if (strcasecmp(mode, "Off") == 0)
15307 res = wpa_command(intf, "SET radio_disabled 1");
15308 else
15309 return -1;
15310
15311 if (res) {
15312 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
15313 "radio mode");
15314 return 0;
15315 }
15316
15317 return 1;
15318}
15319
15320
Jouni Malinenf7222712019-06-13 01:50:21 +030015321static enum sigma_cmd_result cmd_sta_set_pwrsave(struct sigma_dut *dut,
15322 struct sigma_conn *conn,
15323 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015324{
15325 const char *intf = get_param(cmd, "Interface");
15326 const char *mode = get_param(cmd, "Mode");
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020015327 const char *prog = get_param(cmd, "program");
15328 const char *powersave = get_param(cmd, "powersave");
15329 int res = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015330
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020015331 if (intf == NULL)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015332 return -1;
15333
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020015334 if (prog && strcasecmp(prog, "60GHz") == 0) {
15335 /*
15336 * The CAPI mode parameter does not exist in 60G
15337 * unscheduled PS.
15338 */
Hu Wang5dc3ff12019-06-14 15:14:26 +080015339 if (powersave && strcasecmp(powersave, "unscheduled") == 0)
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020015340 res = set_ps(intf, dut, 1);
Jouni Malinen016ae6c2019-11-04 17:00:01 +020015341 } else if (prog && get_driver_type(dut) == DRIVER_WCN &&
Alexei Avshalom Lazar2f6fdb42019-02-04 14:16:08 +020015342 strcasecmp(prog, "HE") == 0) {
15343 return cmd_sta_set_power_save_he(intf, dut, conn, cmd);
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020015344 } else {
15345 if (mode == NULL)
15346 return -1;
15347
15348 if (strcasecmp(mode, "On") == 0)
15349 res = set_ps(intf, dut, 1);
15350 else if (strcasecmp(mode, "Off") == 0)
15351 res = set_ps(intf, dut, 0);
15352 else
15353 return -1;
15354 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015355
15356 if (res) {
15357 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
15358 "power save mode");
15359 return 0;
15360 }
15361
15362 return 1;
15363}
15364
15365
Jouni Malinenf7222712019-06-13 01:50:21 +030015366static enum sigma_cmd_result cmd_sta_bssid_pool(struct sigma_dut *dut,
15367 struct sigma_conn *conn,
15368 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015369{
15370 const char *intf = get_param(cmd, "Interface");
15371 const char *val, *bssid;
15372 int res;
15373 char *buf;
15374 size_t buf_len;
15375
15376 val = get_param(cmd, "BSSID_FILTER");
15377 if (val == NULL)
15378 return -1;
15379
15380 bssid = get_param(cmd, "BSSID_List");
15381 if (atoi(val) == 0 || bssid == NULL) {
15382 /* Disable BSSID filter */
15383 if (wpa_command(intf, "SET bssid_filter ")) {
15384 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed "
15385 "to disable BSSID filter");
15386 return 0;
15387 }
15388
15389 return 1;
15390 }
15391
15392 buf_len = 100 + strlen(bssid);
15393 buf = malloc(buf_len);
15394 if (buf == NULL)
15395 return -1;
15396
15397 snprintf(buf, buf_len, "SET bssid_filter %s", bssid);
15398 res = wpa_command(intf, buf);
15399 free(buf);
15400 if (res) {
15401 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to enable "
15402 "BSSID filter");
15403 return 0;
15404 }
15405
15406 return 1;
15407}
15408
15409
Jouni Malinenf7222712019-06-13 01:50:21 +030015410static enum sigma_cmd_result cmd_sta_reset_parm(struct sigma_dut *dut,
15411 struct sigma_conn *conn,
15412 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015413{
15414 const char *intf = get_param(cmd, "Interface");
15415 const char *val;
15416
15417 /* TODO: ARP */
15418
15419 val = get_param(cmd, "HS2_CACHE_PROFILE");
15420 if (val && strcasecmp(val, "All") == 0)
15421 hs2_clear_credentials(intf);
15422
15423 return 1;
15424}
15425
15426
Jouni Malinenf7222712019-06-13 01:50:21 +030015427static enum sigma_cmd_result cmd_sta_get_key(struct sigma_dut *dut,
15428 struct sigma_conn *conn,
15429 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015430{
15431 const char *intf = get_param(cmd, "Interface");
15432 const char *key_type = get_param(cmd, "KeyType");
15433 char buf[100], resp[200];
15434
15435 if (key_type == NULL)
15436 return -1;
15437
15438 if (strcasecmp(key_type, "GTK") == 0) {
15439 if (wpa_command_resp(intf, "GET gtk", buf, sizeof(buf)) < 0 ||
15440 strncmp(buf, "FAIL", 4) == 0) {
15441 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
15442 "not fetch current GTK");
15443 return 0;
15444 }
15445 snprintf(resp, sizeof(resp), "KeyValue,%s", buf);
15446 send_resp(dut, conn, SIGMA_COMPLETE, resp);
15447 return 0;
15448 } else {
15449 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
15450 "KeyType");
15451 return 0;
15452 }
15453
15454 return 1;
15455}
15456
15457
15458static int hs2_set_policy(struct sigma_dut *dut)
15459{
15460#ifdef ANDROID
15461 system("ip rule del prio 23000");
15462 if (system("ip rule add from all lookup main prio 23000") != 0) {
15463 sigma_dut_print(dut, DUT_MSG_ERROR,
15464 "Failed to run:ip rule add from all lookup main prio");
15465 return -1;
15466 }
15467 if (system("ip route flush cache") != 0) {
15468 sigma_dut_print(dut, DUT_MSG_ERROR,
15469 "Failed to run ip route flush cache");
15470 return -1;
15471 }
15472 return 1;
15473#else /* ANDROID */
15474 return 0;
15475#endif /* ANDROID */
15476}
15477
15478
Jouni Malinenf7222712019-06-13 01:50:21 +030015479static enum sigma_cmd_result cmd_sta_hs2_associate(struct sigma_dut *dut,
15480 struct sigma_conn *conn,
15481 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015482{
15483 const char *intf = get_param(cmd, "Interface");
15484 const char *val = get_param(cmd, "Ignore_blacklist");
Jouni Malinen439352d2018-09-13 03:42:23 +030015485 const char *band = get_param(cmd, "Band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015486 struct wpa_ctrl *ctrl;
Jouni Malinen3aa72862019-05-29 23:14:51 +030015487 int res, r;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015488 char bssid[20], ssid[40], resp[100], buf[100], blacklisted[100];
15489 int tries = 0;
15490 int ignore_blacklist = 0;
15491 const char *events[] = {
15492 "CTRL-EVENT-CONNECTED",
15493 "INTERWORKING-BLACKLISTED",
15494 "INTERWORKING-NO-MATCH",
15495 NULL
15496 };
15497
15498 start_sta_mode(dut);
15499
Jouni Malinen439352d2018-09-13 03:42:23 +030015500 if (band) {
15501 if (strcmp(band, "2.4") == 0) {
15502 wpa_command(intf, "SET setband 2G");
15503 } else if (strcmp(band, "5") == 0) {
15504 wpa_command(intf, "SET setband 5G");
15505 } else {
15506 send_resp(dut, conn, SIGMA_ERROR,
15507 "errorCode,Unsupported band");
15508 return 0;
15509 }
15510 }
15511
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015512 blacklisted[0] = '\0';
15513 if (val && atoi(val))
15514 ignore_blacklist = 1;
15515
15516try_again:
15517 ctrl = open_wpa_mon(intf);
15518 if (ctrl == NULL) {
15519 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
15520 "wpa_supplicant monitor connection");
15521 return -2;
15522 }
15523
15524 tries++;
15525 if (wpa_command(intf, "INTERWORKING_SELECT auto")) {
15526 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start "
15527 "Interworking connection");
15528 wpa_ctrl_detach(ctrl);
15529 wpa_ctrl_close(ctrl);
15530 return 0;
15531 }
15532
15533 buf[0] = '\0';
15534 while (1) {
15535 char *pos;
15536 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
15537 pos = strstr(buf, "INTERWORKING-BLACKLISTED");
15538 if (!pos)
15539 break;
15540 pos += 25;
15541 sigma_dut_print(dut, DUT_MSG_DEBUG, "Found blacklisted AP: %s",
15542 pos);
15543 if (!blacklisted[0])
15544 memcpy(blacklisted, pos, strlen(pos) + 1);
15545 }
15546
15547 if (ignore_blacklist && blacklisted[0]) {
15548 char *end;
15549 end = strchr(blacklisted, ' ');
15550 if (end)
15551 *end = '\0';
15552 sigma_dut_print(dut, DUT_MSG_DEBUG, "Try to connect to a blacklisted network: %s",
15553 blacklisted);
Jouni Malinen3aa72862019-05-29 23:14:51 +030015554 r = snprintf(buf, sizeof(buf), "INTERWORKING_CONNECT %s",
15555 blacklisted);
15556 if (r < 0 || r >= sizeof(buf) || wpa_command(intf, buf)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015557 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start Interworking connection to blacklisted network");
15558 wpa_ctrl_detach(ctrl);
15559 wpa_ctrl_close(ctrl);
15560 return 0;
15561 }
15562 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
15563 buf, sizeof(buf));
15564 }
15565
15566 wpa_ctrl_detach(ctrl);
15567 wpa_ctrl_close(ctrl);
15568
15569 if (res < 0) {
15570 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
15571 "connect");
15572 return 0;
15573 }
15574
15575 if (strstr(buf, "INTERWORKING-NO-MATCH") ||
15576 strstr(buf, "INTERWORKING-BLACKLISTED")) {
15577 if (tries < 2) {
15578 sigma_dut_print(dut, DUT_MSG_INFO, "No match found - try again to verify no APs were missed in the scan");
15579 goto try_again;
15580 }
15581 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,No network with "
15582 "matching credentials found");
15583 return 0;
15584 }
15585
15586 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
15587 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
15588 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
15589 "get current BSSID/SSID");
15590 return 0;
15591 }
15592
15593 snprintf(resp, sizeof(resp), "SSID,%s,BSSID,%s", ssid, bssid);
15594 send_resp(dut, conn, SIGMA_COMPLETE, resp);
15595 hs2_set_policy(dut);
15596 return 0;
15597}
15598
15599
Jouni Malinenf7222712019-06-13 01:50:21 +030015600static enum sigma_cmd_result cmd_sta_hs2_venue_info(struct sigma_dut *dut,
15601 struct sigma_conn *conn,
15602 struct sigma_cmd *cmd)
Jouni Malinenb639f1c2018-09-13 02:39:46 +030015603{
15604 const char *intf = get_param(cmd, "Interface");
15605 const char *display = get_param(cmd, "Display");
15606 struct wpa_ctrl *ctrl;
15607 char buf[300], params[400], *pos;
15608 char bssid[20];
15609 int info_avail = 0;
15610 unsigned int old_timeout;
15611 int res;
15612
15613 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0) {
15614 send_resp(dut, conn, SIGMA_ERROR,
15615 "ErrorCode,Could not get current BSSID");
15616 return 0;
15617 }
15618 ctrl = open_wpa_mon(intf);
15619 if (!ctrl) {
15620 sigma_dut_print(dut, DUT_MSG_ERROR,
15621 "Failed to open wpa_supplicant monitor connection");
15622 return -2;
15623 }
15624
15625 snprintf(buf, sizeof(buf), "ANQP_GET %s 277", bssid);
15626 wpa_command(intf, buf);
15627
15628 res = get_wpa_cli_event(dut, ctrl, "GAS-QUERY-DONE", buf, sizeof(buf));
15629 if (res < 0) {
15630 send_resp(dut, conn, SIGMA_ERROR,
15631 "ErrorCode,Could not complete GAS query");
15632 goto fail;
15633 }
15634
15635 old_timeout = dut->default_timeout;
15636 dut->default_timeout = 2;
15637 res = get_wpa_cli_event(dut, ctrl, "RX-VENUE-URL", buf, sizeof(buf));
15638 dut->default_timeout = old_timeout;
15639 if (res < 0)
15640 goto done;
15641 pos = strchr(buf, ' ');
15642 if (!pos)
15643 goto done;
15644 pos++;
15645 pos = strchr(pos, ' ');
15646 if (!pos)
15647 goto done;
15648 pos++;
15649 info_avail = 1;
15650 snprintf(params, sizeof(params), "browser %s", pos);
15651
15652 if (display && strcasecmp(display, "Yes") == 0) {
15653 pid_t pid;
15654
15655 pid = fork();
15656 if (pid < 0) {
15657 perror("fork");
15658 return -1;
15659 }
15660
15661 if (pid == 0) {
15662 run_hs20_osu(dut, params);
15663 exit(0);
15664 }
15665 }
15666
15667done:
15668 snprintf(buf, sizeof(buf), "Info_available,%s",
15669 info_avail ? "Yes" : "No");
15670 send_resp(dut, conn, SIGMA_COMPLETE, buf);
15671fail:
15672 wpa_ctrl_detach(ctrl);
15673 wpa_ctrl_close(ctrl);
15674 return 0;
15675}
15676
15677
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015678static int sta_add_credential_uname_pwd(struct sigma_dut *dut,
15679 struct sigma_conn *conn,
15680 const char *ifname,
15681 struct sigma_cmd *cmd)
15682{
15683 const char *val;
15684 int id;
15685
15686 id = add_cred(ifname);
15687 if (id < 0)
15688 return -2;
15689 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
15690
15691 val = get_param(cmd, "prefer");
15692 if (val && atoi(val) > 0)
15693 set_cred(ifname, id, "priority", "1");
15694
15695 val = get_param(cmd, "REALM");
15696 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
15697 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
15698 "realm");
15699 return 0;
15700 }
15701
15702 val = get_param(cmd, "HOME_FQDN");
15703 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
15704 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
15705 "home_fqdn");
15706 return 0;
15707 }
15708
15709 val = get_param(cmd, "Username");
15710 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
15711 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
15712 "username");
15713 return 0;
15714 }
15715
15716 val = get_param(cmd, "Password");
15717 if (val && set_cred_quoted(ifname, id, "password", val) < 0) {
15718 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
15719 "password");
15720 return 0;
15721 }
15722
15723 val = get_param(cmd, "ROOT_CA");
15724 if (val) {
15725 char fname[200];
15726 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
15727#ifdef __linux__
15728 if (!file_exists(fname)) {
15729 char msg[300];
15730 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
15731 "file (%s) not found", fname);
15732 send_resp(dut, conn, SIGMA_ERROR, msg);
15733 return 0;
15734 }
15735#endif /* __linux__ */
15736 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
15737 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
15738 "not set root CA");
15739 return 0;
15740 }
15741 }
15742
15743 return 1;
15744}
15745
15746
15747static int update_devdetail_imsi(struct sigma_dut *dut, const char *imsi)
15748{
15749 FILE *in, *out;
15750 char buf[500];
15751 int found = 0;
15752
15753 in = fopen("devdetail.xml", "r");
15754 if (in == NULL)
15755 return -1;
15756 out = fopen("devdetail.xml.tmp", "w");
15757 if (out == NULL) {
15758 fclose(in);
15759 return -1;
15760 }
15761
15762 while (fgets(buf, sizeof(buf), in)) {
15763 char *pos = strstr(buf, "<IMSI>");
15764 if (pos) {
15765 sigma_dut_print(dut, DUT_MSG_INFO, "Updated DevDetail IMSI to %s",
15766 imsi);
15767 pos += 6;
15768 *pos = '\0';
15769 fprintf(out, "%s%s</IMSI>\n", buf, imsi);
15770 found++;
15771 } else {
15772 fprintf(out, "%s", buf);
15773 }
15774 }
15775
15776 fclose(out);
15777 fclose(in);
15778 if (found)
15779 rename("devdetail.xml.tmp", "devdetail.xml");
15780 else
15781 unlink("devdetail.xml.tmp");
15782
15783 return 0;
15784}
15785
15786
15787static int sta_add_credential_sim(struct sigma_dut *dut,
15788 struct sigma_conn *conn,
15789 const char *ifname, struct sigma_cmd *cmd)
15790{
15791 const char *val, *imsi = NULL;
15792 int id;
15793 char buf[200];
15794 int res;
15795 const char *pos;
15796 size_t mnc_len;
15797 char plmn_mcc[4];
15798 char plmn_mnc[4];
15799
15800 id = add_cred(ifname);
15801 if (id < 0)
15802 return -2;
15803 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
15804
15805 val = get_param(cmd, "prefer");
15806 if (val && atoi(val) > 0)
15807 set_cred(ifname, id, "priority", "1");
15808
15809 val = get_param(cmd, "PLMN_MCC");
15810 if (val == NULL) {
15811 send_resp(dut, conn, SIGMA_ERROR,
15812 "errorCode,Missing PLMN_MCC");
15813 return 0;
15814 }
15815 if (strlen(val) != 3) {
15816 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MCC");
15817 return 0;
15818 }
15819 snprintf(plmn_mcc, sizeof(plmn_mcc), "%s", val);
15820
15821 val = get_param(cmd, "PLMN_MNC");
15822 if (val == NULL) {
15823 send_resp(dut, conn, SIGMA_ERROR,
15824 "errorCode,Missing PLMN_MNC");
15825 return 0;
15826 }
15827 if (strlen(val) != 2 && strlen(val) != 3) {
15828 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MNC");
15829 return 0;
15830 }
15831 snprintf(plmn_mnc, sizeof(plmn_mnc), "%s", val);
15832
15833 val = get_param(cmd, "IMSI");
15834 if (val == NULL) {
15835 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing SIM "
15836 "IMSI");
15837 return 0;
15838 }
15839
15840 imsi = pos = val;
15841
15842 if (strncmp(plmn_mcc, pos, 3) != 0) {
15843 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MCC mismatch");
15844 return 0;
15845 }
15846 pos += 3;
15847
15848 mnc_len = strlen(plmn_mnc);
15849 if (mnc_len < 2) {
15850 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC not set");
15851 return 0;
15852 }
15853
15854 if (strncmp(plmn_mnc, pos, mnc_len) != 0) {
15855 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC mismatch");
15856 return 0;
15857 }
15858 pos += mnc_len;
15859
15860 res = snprintf(buf, sizeof(buf), "%s%s-%s",plmn_mcc, plmn_mnc, pos);
15861 if (res < 0 || res >= (int) sizeof(buf))
15862 return -1;
15863 if (set_cred_quoted(ifname, id, "imsi", buf) < 0) {
15864 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
15865 "not set IMSI");
15866 return 0;
15867 }
15868
15869 val = get_param(cmd, "Password");
15870 if (val && set_cred_quoted(ifname, id, "milenage", val) < 0) {
15871 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
15872 "not set password");
15873 return 0;
15874 }
15875
Jouni Malinenba630452018-06-22 11:49:59 +030015876 if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015877 /*
15878 * Set provisioning_sp for the test cases where SIM/USIM
15879 * provisioning is used.
15880 */
15881 if (val && set_cred_quoted(ifname, id, "provisioning_sp",
15882 "wi-fi.org") < 0) {
15883 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
15884 "not set provisioning_sp");
15885 return 0;
15886 }
15887
15888 update_devdetail_imsi(dut, imsi);
15889 }
15890
15891 return 1;
15892}
15893
15894
15895static int sta_add_credential_cert(struct sigma_dut *dut,
15896 struct sigma_conn *conn,
15897 const char *ifname,
15898 struct sigma_cmd *cmd)
15899{
15900 const char *val;
15901 int id;
15902
15903 id = add_cred(ifname);
15904 if (id < 0)
15905 return -2;
15906 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
15907
15908 val = get_param(cmd, "prefer");
15909 if (val && atoi(val) > 0)
15910 set_cred(ifname, id, "priority", "1");
15911
15912 val = get_param(cmd, "REALM");
15913 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
15914 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
15915 "realm");
15916 return 0;
15917 }
15918
15919 val = get_param(cmd, "HOME_FQDN");
15920 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
15921 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
15922 "home_fqdn");
15923 return 0;
15924 }
15925
15926 val = get_param(cmd, "Username");
15927 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
15928 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
15929 "username");
15930 return 0;
15931 }
15932
15933 val = get_param(cmd, "clientCertificate");
15934 if (val) {
15935 char fname[200];
15936 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
15937#ifdef __linux__
15938 if (!file_exists(fname)) {
15939 char msg[300];
15940 snprintf(msg, sizeof(msg),
15941 "ErrorCode,clientCertificate "
15942 "file (%s) not found", fname);
15943 send_resp(dut, conn, SIGMA_ERROR, msg);
15944 return 0;
15945 }
15946#endif /* __linux__ */
15947 if (set_cred_quoted(ifname, id, "client_cert", fname) < 0) {
15948 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
15949 "not set client_cert");
15950 return 0;
15951 }
15952 if (set_cred_quoted(ifname, id, "private_key", fname) < 0) {
15953 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
15954 "not set private_key");
15955 return 0;
15956 }
15957 }
15958
15959 val = get_param(cmd, "ROOT_CA");
15960 if (val) {
15961 char fname[200];
15962 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
15963#ifdef __linux__
15964 if (!file_exists(fname)) {
15965 char msg[300];
15966 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
15967 "file (%s) not found", fname);
15968 send_resp(dut, conn, SIGMA_ERROR, msg);
15969 return 0;
15970 }
15971#endif /* __linux__ */
15972 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
15973 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
15974 "not set root CA");
15975 return 0;
15976 }
15977 }
15978
15979 return 1;
15980}
15981
15982
Jouni Malinenf7222712019-06-13 01:50:21 +030015983static enum sigma_cmd_result cmd_sta_add_credential(struct sigma_dut *dut,
15984 struct sigma_conn *conn,
15985 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015986{
15987 const char *intf = get_param(cmd, "Interface");
15988 const char *type;
15989
15990 start_sta_mode(dut);
15991
15992 type = get_param(cmd, "Type");
15993 if (!type)
15994 return -1;
15995
15996 if (strcasecmp(type, "uname_pwd") == 0)
15997 return sta_add_credential_uname_pwd(dut, conn, intf, cmd);
15998
15999 if (strcasecmp(type, "sim") == 0)
16000 return sta_add_credential_sim(dut, conn, intf, cmd);
16001
16002 if (strcasecmp(type, "cert") == 0)
16003 return sta_add_credential_cert(dut, conn, intf, cmd);
16004
16005 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported credential "
16006 "type");
16007 return 0;
16008}
16009
16010
Jouni Malinenf7222712019-06-13 01:50:21 +030016011static enum sigma_cmd_result cmd_sta_scan(struct sigma_dut *dut,
16012 struct sigma_conn *conn,
16013 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016014{
16015 const char *intf = get_param(cmd, "Interface");
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016016 const char *val, *bssid, *ssid, *scan_freq, *short_ssid;
Veerendranathdc581b52020-08-10 03:29:08 -070016017 char buf[4096], scan_res[20];
vamsi krishna89ad8c62017-09-19 12:51:18 +053016018 char ssid_hex[65];
Kiran Kumar Lokere3399af22020-03-04 16:31:56 -080016019 int wildcard_ssid = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016020 int res;
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016021 enum sigma_cmd_result status;
Jouni Malinen228a2fc2020-06-22 23:37:45 +030016022 struct wpa_ctrl *ctrl = NULL;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016023
Jouni Malinen8c1abeb2019-11-06 18:48:34 +020016024 start_sta_mode(dut);
16025
Arif Hussain66a4af02019-02-07 15:04:51 -080016026 val = get_param(cmd, "GetParameter");
16027 if (val && strcmp(val, "SSID_BSSID") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020016028 if (get_wpa_ssid_bssid(dut, get_station_ifname(dut),
Arif Hussain66a4af02019-02-07 15:04:51 -080016029 buf, sizeof(buf)) < 0) {
16030 sigma_dut_print(dut, DUT_MSG_ERROR,
16031 "Could not get ssid bssid");
16032 return ERROR_SEND_STATUS;
16033 }
16034
16035 sigma_dut_print(dut, DUT_MSG_INFO, "%s", buf);
16036 send_resp(dut, conn, SIGMA_COMPLETE, buf);
16037 return STATUS_SENT;
16038 }
16039
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016040 val = get_param(cmd, "HESSID");
16041 if (val) {
16042 res = snprintf(buf, sizeof(buf), "SET hessid %s", val);
16043 if (res < 0 || res >= (int) sizeof(buf))
16044 return -1;
16045 wpa_command(intf, buf);
16046 }
16047
16048 val = get_param(cmd, "ACCS_NET_TYPE");
16049 if (val) {
16050 res = snprintf(buf, sizeof(buf), "SET access_network_type %s",
16051 val);
16052 if (res < 0 || res >= (int) sizeof(buf))
16053 return -1;
16054 wpa_command(intf, buf);
16055 }
16056
Kiran Kumar Lokere69d89952021-08-08 23:41:46 -070016057 if (get_param(cmd, "RxMac"))
16058 sta_set_scan_unicast_probe(dut, intf, 1);
16059
vamsi krishna89ad8c62017-09-19 12:51:18 +053016060 bssid = get_param(cmd, "Bssid");
16061 ssid = get_param(cmd, "Ssid");
Kiran Kumar Lokere69d89952021-08-08 23:41:46 -070016062 if (!bssid)
16063 bssid = get_param(cmd, "RxMac");
vamsi krishna89ad8c62017-09-19 12:51:18 +053016064
Kiran Kumar Lokere3399af22020-03-04 16:31:56 -080016065 if (ssid && strcasecmp(ssid, "ZeroLength") == 0 &&
16066 dut->device_type == STA_testbed) {
16067 ssid = NULL;
16068 wildcard_ssid = 1;
16069 }
16070
vamsi krishna89ad8c62017-09-19 12:51:18 +053016071 if (ssid) {
16072 if (2 * strlen(ssid) >= sizeof(ssid_hex)) {
16073 send_resp(dut, conn, SIGMA_ERROR,
16074 "ErrorCode,Too long SSID");
16075 return 0;
16076 }
16077 ascii2hexstr(ssid, ssid_hex);
16078 }
16079
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016080 short_ssid = get_param(cmd, "ShortSSID");
16081 if (short_ssid) {
16082 uint32_t short_ssid_hex;
16083
16084 short_ssid_hex = strtoul(short_ssid, NULL, 16);
16085 short_ssid_hex = ((short_ssid_hex & 0xFF) << 24) |
16086 (((short_ssid_hex >> 8) & 0xFF) << 16) |
16087 (((short_ssid_hex >> 16) & 0xFF) << 8) |
16088 ((short_ssid_hex >> 24) & 0xFF);
16089
16090 res = snprintf(buf, sizeof(buf),
16091 "VENDOR_ELEM_ADD 14 ff053a%08x",
16092 short_ssid_hex);
16093 if (res < 0 || res >= (int) sizeof(buf) ||
16094 wpa_command(intf, buf)) {
16095 send_resp(dut, conn, SIGMA_ERROR,
16096 "errorCode,Failed to add short SSID");
16097 return STATUS_SENT_ERROR;
16098 }
16099 }
16100
Kiran Kumar Lokerec0deb482020-03-04 16:35:06 -080016101 scan_freq = get_param(cmd, "ChnlFreq");
Veerendranath Jakkam132c4b42020-08-10 00:29:03 +053016102 if (scan_freq) {
16103 if (strcasecmp(scan_freq, "2G") == 0)
16104 scan_freq = "2412-2462";
16105 else if (strcasecmp(scan_freq, "5G") == 0)
16106 scan_freq = "5180-5925";
16107 }
Kiran Kumar Lokerec0deb482020-03-04 16:35:06 -080016108
Jouni Malinen228a2fc2020-06-22 23:37:45 +030016109 val = get_param(cmd, "WaitCompletion");
16110 if (val && atoi(val) == 1) {
16111 ctrl = open_wpa_mon(intf);
16112 if (!ctrl) {
16113 send_resp(dut, conn, SIGMA_ERROR,
16114 "errorCode,Failed to open monitor socket");
16115 return STATUS_SENT_ERROR;
16116 }
16117 }
16118
Kiran Kumar Lokerec0deb482020-03-04 16:35:06 -080016119 res = snprintf(buf, sizeof(buf), "SCAN%s%s%s%s%s%s%s",
vamsi krishna89ad8c62017-09-19 12:51:18 +053016120 bssid ? " bssid=": "",
16121 bssid ? bssid : "",
16122 ssid ? " ssid " : "",
Kiran Kumar Lokere3399af22020-03-04 16:31:56 -080016123 ssid ? ssid_hex : "",
Kiran Kumar Lokerec0deb482020-03-04 16:35:06 -080016124 wildcard_ssid ? " wildcard_ssid=1" : "",
16125 scan_freq ? " freq=" : "",
16126 scan_freq ? scan_freq : "");
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016127 if (res < 0 || res >= (int) sizeof(buf)) {
16128 send_resp(dut, conn, SIGMA_ERROR,
16129 "errorCode,Could not build scan command");
16130 status = STATUS_SENT_ERROR;
16131 goto remove_s_ssid;
16132 }
vamsi krishna89ad8c62017-09-19 12:51:18 +053016133
Veerendranathdc581b52020-08-10 03:29:08 -070016134 res = wpa_command_resp(intf, buf, scan_res, sizeof(scan_res));
16135 if (strncmp(scan_res, "FAIL-BUSY", 9) == 0) {
16136 sigma_dut_print(dut, DUT_MSG_DEBUG,
16137 "Scan request rejected with busy status, abort ongoing scan and try again");
16138 wpa_command(intf, "ABORT_SCAN");
16139 res = wpa_command(intf, buf);
16140 }
16141
16142 if (res < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016143 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not start "
16144 "scan");
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016145 status = STATUS_SENT_ERROR;
16146 } else {
16147 status = SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016148 }
16149
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016150remove_s_ssid:
16151 if (short_ssid && wpa_command(intf, "VENDOR_ELEM_REMOVE 14 *"))
16152 sigma_dut_print(dut, DUT_MSG_ERROR,
16153 "Failed to delete vendor element");
16154
Jouni Malinen228a2fc2020-06-22 23:37:45 +030016155 if (ctrl) {
16156 if (status == SUCCESS_SEND_STATUS) {
16157 res = get_wpa_cli_event(dut, ctrl,
16158 "CTRL-EVENT-SCAN-RESULTS",
16159 buf, sizeof(buf));
16160 if (res < 0) {
16161 send_resp(dut, conn, SIGMA_ERROR,
16162 "ErrorCode,scan did not complete");
16163 status = STATUS_SENT_ERROR;
16164 }
16165 }
16166
16167 wpa_ctrl_detach(ctrl);
16168 wpa_ctrl_close(ctrl);
16169 }
16170
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016171 return status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016172}
16173
16174
Jouni Malinenf7222712019-06-13 01:50:21 +030016175static enum sigma_cmd_result cmd_sta_scan_bss(struct sigma_dut *dut,
16176 struct sigma_conn *conn,
16177 struct sigma_cmd *cmd)
Jouni Malinen5e5d43d2018-01-10 17:29:33 +020016178{
16179 const char *intf = get_param(cmd, "Interface");
16180 const char *bssid;
16181 char buf[4096], *pos;
16182 int freq, chan;
16183 char *ssid;
16184 char resp[100];
16185 int res;
16186 struct wpa_ctrl *ctrl;
16187
16188 bssid = get_param(cmd, "BSSID");
16189 if (!bssid) {
16190 send_resp(dut, conn, SIGMA_INVALID,
16191 "errorCode,BSSID argument is missing");
16192 return 0;
16193 }
16194
16195 ctrl = open_wpa_mon(intf);
16196 if (!ctrl) {
16197 sigma_dut_print(dut, DUT_MSG_ERROR,
16198 "Failed to open wpa_supplicant monitor connection");
16199 return -1;
16200 }
16201
16202 if (wpa_command(intf, "SCAN TYPE=ONLY")) {
16203 send_resp(dut, conn, SIGMA_ERROR,
16204 "errorCode,Could not start scan");
16205 wpa_ctrl_detach(ctrl);
16206 wpa_ctrl_close(ctrl);
16207 return 0;
16208 }
16209
16210 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
16211 buf, sizeof(buf));
16212
16213 wpa_ctrl_detach(ctrl);
16214 wpa_ctrl_close(ctrl);
16215
16216 if (res < 0) {
16217 send_resp(dut, conn, SIGMA_ERROR,
16218 "errorCode,Scan did not complete");
16219 return 0;
16220 }
16221
16222 snprintf(buf, sizeof(buf), "BSS %s", bssid);
16223 if (wpa_command_resp(intf, buf, buf, sizeof(buf)) < 0 ||
16224 strncmp(buf, "id=", 3) != 0) {
16225 send_resp(dut, conn, SIGMA_ERROR,
16226 "errorCode,Specified BSSID not found");
16227 return 0;
16228 }
16229
16230 pos = strstr(buf, "\nfreq=");
16231 if (!pos) {
16232 send_resp(dut, conn, SIGMA_ERROR,
16233 "errorCode,Channel not found");
16234 return 0;
16235 }
16236 freq = atoi(pos + 6);
16237 chan = freq_to_channel(freq);
16238
16239 pos = strstr(buf, "\nssid=");
16240 if (!pos) {
16241 send_resp(dut, conn, SIGMA_ERROR,
16242 "errorCode,SSID not found");
16243 return 0;
16244 }
16245 ssid = pos + 6;
16246 pos = strchr(ssid, '\n');
16247 if (pos)
16248 *pos = '\0';
16249 snprintf(resp, sizeof(resp), "ssid,%s,bsschannel,%d", ssid, chan);
16250 send_resp(dut, conn, SIGMA_COMPLETE, resp);
16251 return 0;
16252}
16253
16254
Jouni Malinenf7222712019-06-13 01:50:21 +030016255static enum sigma_cmd_result cmd_sta_set_systime(struct sigma_dut *dut,
16256 struct sigma_conn *conn,
16257 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016258{
16259#ifdef __linux__
16260 struct timeval tv;
16261 struct tm tm;
16262 time_t t;
16263 const char *val;
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +053016264 int v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016265
Jouni Malinen016ae6c2019-11-04 17:00:01 +020016266 wpa_command(get_station_ifname(dut), "PMKSA_FLUSH");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016267
16268 memset(&tm, 0, sizeof(tm));
16269 val = get_param(cmd, "seconds");
16270 if (val)
16271 tm.tm_sec = atoi(val);
16272 val = get_param(cmd, "minutes");
16273 if (val)
16274 tm.tm_min = atoi(val);
16275 val = get_param(cmd, "hours");
16276 if (val)
16277 tm.tm_hour = atoi(val);
16278 val = get_param(cmd, "date");
16279 if (val)
16280 tm.tm_mday = atoi(val);
16281 val = get_param(cmd, "month");
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +053016282 if (val) {
16283 v = atoi(val);
16284 if (v < 1 || v > 12) {
16285 send_resp(dut, conn, SIGMA_INVALID,
16286 "errorCode,Invalid month");
16287 return 0;
16288 }
16289 tm.tm_mon = v - 1;
16290 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016291 val = get_param(cmd, "year");
16292 if (val) {
16293 int year = atoi(val);
16294#ifdef ANDROID
16295 if (year > 2035)
16296 year = 2035; /* years beyond 2035 not supported */
16297#endif /* ANDROID */
16298 tm.tm_year = year - 1900;
16299 }
16300 t = mktime(&tm);
16301 if (t == (time_t) -1) {
16302 send_resp(dut, conn, SIGMA_ERROR,
16303 "errorCode,Invalid date or time");
16304 return 0;
16305 }
16306
16307 memset(&tv, 0, sizeof(tv));
16308 tv.tv_sec = t;
16309
16310 if (settimeofday(&tv, NULL) < 0) {
16311 sigma_dut_print(dut, DUT_MSG_INFO, "settimeofday failed: %s",
16312 strerror(errno));
16313 send_resp(dut, conn, SIGMA_ERROR,
16314 "errorCode,Failed to set time");
16315 return 0;
16316 }
16317
16318 return 1;
16319#endif /* __linux__ */
16320
16321 return -1;
16322}
16323
16324
Jouni Malinenf7222712019-06-13 01:50:21 +030016325static enum sigma_cmd_result cmd_sta_osu(struct sigma_dut *dut,
16326 struct sigma_conn *conn,
16327 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016328{
16329 const char *intf = get_param(cmd, "Interface");
Jouni Malinen4c8681c2018-09-12 23:28:11 +030016330 const char *name, *osu_ssid, *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016331 int prod_ess_assoc = 1;
Jouni Malinen4c8681c2018-09-12 23:28:11 +030016332 char buf[300], bssid[100], ssid[100];
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016333 int res;
16334 struct wpa_ctrl *ctrl;
16335
16336 name = get_param(cmd, "osuFriendlyName");
Jouni Malinen4c8681c2018-09-12 23:28:11 +030016337 osu_ssid = get_param(cmd, "osu_ssid");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016338
16339 val = get_param(cmd, "ProdESSAssoc");
16340 if (val)
16341 prod_ess_assoc = atoi(val);
16342
16343 kill_dhcp_client(dut, intf);
16344 if (start_dhcp_client(dut, intf) < 0)
16345 return -2;
16346
16347 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger OSU");
16348 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
16349 res = snprintf(buf, sizeof(buf),
Jouni Malinen4c8681c2018-09-12 23:28:11 +030016350 "%s %s%s%s %s%s%s signup osu-ca.pem",
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016351 prod_ess_assoc ? "" : "-N",
16352 name ? "-O'" : "", name ? name : "",
Jouni Malinen4c8681c2018-09-12 23:28:11 +030016353 name ? "'" : "",
16354 osu_ssid ? "-o'" : "", osu_ssid ? osu_ssid : "",
16355 osu_ssid ? "'" : "");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016356
Kanchanapally, Vidyullatha12b66762015-12-31 16:46:42 +053016357 hs2_set_policy(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016358 if (run_hs20_osu(dut, buf) < 0) {
16359 FILE *f;
16360
16361 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to complete OSU");
16362
16363 f = fopen("hs20-osu-client.res", "r");
16364 if (f) {
16365 char resp[400], res[300], *pos;
16366 if (!fgets(res, sizeof(res), f))
16367 res[0] = '\0';
16368 pos = strchr(res, '\n');
16369 if (pos)
16370 *pos = '\0';
16371 fclose(f);
16372 sigma_dut_summary(dut, "hs20-osu-client provisioning failed: %s",
16373 res);
16374 snprintf(resp, sizeof(resp), "notify-send '%s'", res);
16375 if (system(resp) != 0) {
16376 }
16377 snprintf(resp, sizeof(resp),
16378 "SSID,,BSSID,,failureReason,%s", res);
16379 send_resp(dut, conn, SIGMA_COMPLETE, resp);
16380 return 0;
16381 }
16382
16383 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
16384 return 0;
16385 }
16386
16387 if (!prod_ess_assoc)
16388 goto report;
16389
16390 ctrl = open_wpa_mon(intf);
16391 if (ctrl == NULL) {
16392 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
16393 "wpa_supplicant monitor connection");
16394 return -1;
16395 }
16396
16397 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
16398 buf, sizeof(buf));
16399
16400 wpa_ctrl_detach(ctrl);
16401 wpa_ctrl_close(ctrl);
16402
16403 if (res < 0) {
16404 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to connect to "
16405 "network after OSU");
16406 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
16407 return 0;
16408 }
16409
16410report:
16411 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
16412 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
16413 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to get BSSID/SSID");
16414 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
16415 return 0;
16416 }
16417
16418 snprintf(buf, sizeof(buf), "SSID,%s,BSSID,%s", ssid, bssid);
16419 send_resp(dut, conn, SIGMA_COMPLETE, buf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016420 return 0;
16421}
16422
16423
Jouni Malinenf7222712019-06-13 01:50:21 +030016424static enum sigma_cmd_result cmd_sta_policy_update(struct sigma_dut *dut,
16425 struct sigma_conn *conn,
16426 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016427{
16428 const char *val;
16429 int timeout = 120;
16430
16431 val = get_param(cmd, "PolicyUpdate");
16432 if (val == NULL || atoi(val) == 0)
16433 return 1; /* No operation requested */
16434
16435 val = get_param(cmd, "Timeout");
16436 if (val)
16437 timeout = atoi(val);
16438
16439 if (timeout) {
16440 /* TODO: time out the command and return
16441 * PolicyUpdateStatus,TIMEOUT if needed. */
16442 }
16443
16444 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger policy update");
16445 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
16446 if (run_hs20_osu(dut, "pol_upd fqdn=wi-fi.org") < 0) {
16447 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,FAIL");
16448 return 0;
16449 }
16450
16451 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,SUCCESS");
16452 return 0;
16453}
16454
16455
Jouni Malinenf7222712019-06-13 01:50:21 +030016456static enum sigma_cmd_result cmd_sta_er_config(struct sigma_dut *dut,
16457 struct sigma_conn *conn,
16458 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016459{
16460 struct wpa_ctrl *ctrl;
16461 const char *intf = get_param(cmd, "Interface");
16462 const char *bssid = get_param(cmd, "Bssid");
16463 const char *ssid = get_param(cmd, "SSID");
16464 const char *security = get_param(cmd, "Security");
16465 const char *passphrase = get_param(cmd, "Passphrase");
16466 const char *pin = get_param(cmd, "PIN");
16467 char buf[1000];
16468 char ssid_hex[200], passphrase_hex[200];
16469 const char *keymgmt, *cipher;
16470
16471 if (intf == NULL)
Jouni Malinen016ae6c2019-11-04 17:00:01 +020016472 intf = get_main_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016473
16474 if (!bssid) {
16475 send_resp(dut, conn, SIGMA_ERROR,
16476 "ErrorCode,Missing Bssid argument");
16477 return 0;
16478 }
16479
16480 if (!ssid) {
16481 send_resp(dut, conn, SIGMA_ERROR,
16482 "ErrorCode,Missing SSID argument");
16483 return 0;
16484 }
16485
16486 if (!security) {
16487 send_resp(dut, conn, SIGMA_ERROR,
16488 "ErrorCode,Missing Security argument");
16489 return 0;
16490 }
16491
16492 if (!passphrase) {
16493 send_resp(dut, conn, SIGMA_ERROR,
16494 "ErrorCode,Missing Passphrase argument");
16495 return 0;
16496 }
16497
16498 if (!pin) {
16499 send_resp(dut, conn, SIGMA_ERROR,
16500 "ErrorCode,Missing PIN argument");
16501 return 0;
16502 }
16503
vamsi krishna8c9c1562017-05-12 15:51:46 +053016504 if (2 * strlen(ssid) >= sizeof(ssid_hex) ||
16505 2 * strlen(passphrase) >= sizeof(passphrase_hex)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016506 send_resp(dut, conn, SIGMA_ERROR,
16507 "ErrorCode,Too long SSID/passphrase");
16508 return 0;
16509 }
16510
16511 ctrl = open_wpa_mon(intf);
16512 if (ctrl == NULL) {
16513 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
16514 "wpa_supplicant monitor connection");
16515 return -2;
16516 }
16517
16518 if (strcasecmp(security, "wpa2-psk") == 0) {
16519 keymgmt = "WPA2PSK";
16520 cipher = "CCMP";
16521 } else {
16522 wpa_ctrl_detach(ctrl);
16523 wpa_ctrl_close(ctrl);
16524 send_resp(dut, conn, SIGMA_ERROR,
16525 "ErrorCode,Unsupported Security value");
16526 return 0;
16527 }
16528
16529 ascii2hexstr(ssid, ssid_hex);
16530 ascii2hexstr(passphrase, passphrase_hex);
16531 snprintf(buf, sizeof(buf), "WPS_REG %s %s %s %s %s %s",
16532 bssid, pin, ssid_hex, keymgmt, cipher, passphrase_hex);
16533
16534 if (wpa_command(intf, buf) < 0) {
16535 wpa_ctrl_detach(ctrl);
16536 wpa_ctrl_close(ctrl);
16537 send_resp(dut, conn, SIGMA_ERROR,
16538 "ErrorCode,Failed to start registrar");
16539 return 0;
16540 }
16541
16542 snprintf(dut->er_oper_bssid, sizeof(dut->er_oper_bssid), "%s", bssid);
16543 dut->er_oper_performed = 1;
16544
16545 return wps_connection_event(dut, conn, ctrl, intf, 0);
16546}
16547
16548
Jouni Malinenf7222712019-06-13 01:50:21 +030016549static enum sigma_cmd_result
16550cmd_sta_wps_connect_pw_token(struct sigma_dut *dut, struct sigma_conn *conn,
16551 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016552{
16553 struct wpa_ctrl *ctrl;
16554 const char *intf = get_param(cmd, "Interface");
16555 const char *bssid = get_param(cmd, "Bssid");
16556 char buf[100];
16557
16558 if (!bssid) {
16559 send_resp(dut, conn, SIGMA_ERROR,
16560 "ErrorCode,Missing Bssid argument");
16561 return 0;
16562 }
16563
16564 ctrl = open_wpa_mon(intf);
16565 if (ctrl == NULL) {
16566 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
16567 "wpa_supplicant monitor connection");
16568 return -2;
16569 }
16570
16571 snprintf(buf, sizeof(buf), "WPS_NFC %s", bssid);
16572
16573 if (wpa_command(intf, buf) < 0) {
16574 wpa_ctrl_detach(ctrl);
16575 wpa_ctrl_close(ctrl);
16576 send_resp(dut, conn, SIGMA_ERROR,
16577 "ErrorCode,Failed to start registrar");
16578 return 0;
16579 }
16580
16581 return wps_connection_event(dut, conn, ctrl, intf, 0);
16582}
16583
16584
Jouni Malinenf7222712019-06-13 01:50:21 +030016585static enum sigma_cmd_result cmd_start_wps_registration(struct sigma_dut *dut,
16586 struct sigma_conn *conn,
16587 struct sigma_cmd *cmd)
vamsi krishna9b144002017-09-20 13:28:13 +053016588{
16589 struct wpa_ctrl *ctrl;
16590 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020016591 const char *network_mode = get_param(cmd, "network_mode");
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020016592 const char *config_method = get_param(cmd, "WPSConfigMethod");
16593 const char *role;
vamsi krishna9b144002017-09-20 13:28:13 +053016594 int res;
16595 char buf[256];
16596 const char *events[] = {
16597 "CTRL-EVENT-CONNECTED",
16598 "WPS-OVERLAP-DETECTED",
16599 "WPS-TIMEOUT",
16600 "WPS-FAIL",
16601 NULL
16602 };
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020016603 int id = 0;
vamsi krishna9b144002017-09-20 13:28:13 +053016604
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020016605 /* 60G WPS tests do not pass Interface parameter */
16606 if (!intf)
Jouni Malinen016ae6c2019-11-04 17:00:01 +020016607 intf = get_main_ifname(dut);
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020016608
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020016609 if (dut->mode == SIGMA_MODE_AP)
16610 return ap_wps_registration(dut, conn, cmd);
16611
16612 if (config_method) {
16613 /* WFA_CS_WPS_PIN_KEYPAD mode is set when using the
16614 * sta_wps_enter_pin before calling start_wps_registration. */
16615 if (strcasecmp(config_method, "PBC") == 0)
16616 dut->wps_method = WFA_CS_WPS_PBC;
16617 }
16618 if (dut->wps_method == WFA_CS_WPS_NOT_READY) {
16619 send_resp(dut, conn, SIGMA_ERROR,
16620 "ErrorCode,WPS parameters not yet set");
16621 return STATUS_SENT;
16622 }
16623
16624 /* Make sure WPS is enabled (also for STA mode) */
16625 dut->wps_disable = 0;
16626
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020016627 if (dut->band == WPS_BAND_60G && network_mode &&
16628 strcasecmp(network_mode, "PBSS") == 0) {
16629 sigma_dut_print(dut, DUT_MSG_DEBUG,
16630 "Set PBSS network mode, network id %d", id);
Jouni Malinen016ae6c2019-11-04 17:00:01 +020016631 if (set_network(get_station_ifname(dut), id, "pbss", "1") < 0)
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020016632 return -2;
16633 }
16634
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020016635 if (dut->force_rsn_ie) {
16636 sigma_dut_print(dut, DUT_MSG_DEBUG, "Force RSN_IE: %d",
16637 dut->force_rsn_ie);
16638 if (sta_60g_force_rsn_ie(dut, dut->force_rsn_ie) < 0) {
16639 sigma_dut_print(dut, DUT_MSG_INFO,
16640 "Failed to force RSN_IE");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020016641 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020016642 }
16643 }
16644
vamsi krishna9b144002017-09-20 13:28:13 +053016645 ctrl = open_wpa_mon(intf);
16646 if (!ctrl) {
16647 sigma_dut_print(dut, DUT_MSG_ERROR,
16648 "Failed to open wpa_supplicant monitor connection");
16649 return -2;
16650 }
16651
16652 role = get_param(cmd, "WpsRole");
16653 if (!role) {
16654 send_resp(dut, conn, SIGMA_INVALID,
16655 "ErrorCode,WpsRole not provided");
16656 goto fail;
16657 }
16658
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020016659 if (strcasecmp(role, "Enrollee") != 0) {
16660 /* Registrar role for STA not supported */
16661 send_resp(dut, conn, SIGMA_ERROR,
16662 "ErrorCode,Unsupported WpsRole value");
16663 goto fail;
16664 }
16665
16666 if (is_60g_sigma_dut(dut)) {
16667 if (dut->wps_method == WFA_CS_WPS_PBC)
16668 snprintf(buf, sizeof(buf), "WPS_PBC");
16669 else /* WFA_CS_WPS_PIN_KEYPAD */
16670 snprintf(buf, sizeof(buf), "WPS_PIN any %s",
16671 dut->wps_pin);
16672 if (wpa_command(intf, buf) < 0) {
16673 send_resp(dut, conn, SIGMA_ERROR,
16674 "ErrorCode,Failed to start WPS");
vamsi krishna9b144002017-09-20 13:28:13 +053016675 goto fail;
16676 }
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020016677 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
16678 if (res < 0) {
16679 send_resp(dut, conn, SIGMA_ERROR,
16680 "ErrorCode,WPS connection did not complete");
16681 goto fail;
16682 }
16683 if (strstr(buf, "WPS-TIMEOUT")) {
16684 send_resp(dut, conn, SIGMA_COMPLETE, "WpsState,NoPeer");
16685 } else if (strstr(buf, "WPS-OVERLAP-DETECTED")) {
16686 send_resp(dut, conn, SIGMA_COMPLETE,
16687 "WpsState,OverlapSession");
16688 } else if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
16689 send_resp(dut, conn, SIGMA_COMPLETE,
16690 "WpsState,Successful");
16691 } else {
16692 send_resp(dut, conn, SIGMA_COMPLETE,
16693 "WpsState,Failure");
16694 }
16695 } else {
16696 if (dut->wps_method == WFA_CS_WPS_PBC) {
vamsi krishna9b144002017-09-20 13:28:13 +053016697 if (wpa_command(intf, "WPS_PBC") < 0) {
16698 send_resp(dut, conn, SIGMA_ERROR,
16699 "ErrorCode,Failed to enable PBC");
16700 goto fail;
16701 }
16702 } else {
16703 /* TODO: PIN method */
16704 send_resp(dut, conn, SIGMA_ERROR,
16705 "ErrorCode,Unsupported WpsConfigMethod value");
16706 goto fail;
16707 }
16708 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
16709 if (res < 0) {
16710 send_resp(dut, conn, SIGMA_ERROR,
16711 "ErrorCode,WPS connection did not complete");
16712 goto fail;
16713 }
16714 if (strstr(buf, "WPS-TIMEOUT")) {
16715 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,NoPeer");
16716 } else if (strstr(buf, "WPS-OVERLAP-DETECTED")) {
16717 send_resp(dut, conn, SIGMA_ERROR,
16718 "ErrorCode,OverlapSession");
16719 } else if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
16720 send_resp(dut, conn, SIGMA_COMPLETE, "Successful");
16721 } else {
16722 send_resp(dut, conn, SIGMA_ERROR,
16723 "ErrorCode,WPS operation failed");
16724 }
vamsi krishna9b144002017-09-20 13:28:13 +053016725 }
16726
16727fail:
16728 wpa_ctrl_detach(ctrl);
16729 wpa_ctrl_close(ctrl);
16730 return 0;
16731}
16732
16733
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016734static int req_intf(struct sigma_cmd *cmd)
16735{
16736 return get_param(cmd, "interface") == NULL ? -1 : 0;
16737}
16738
16739
16740void sta_register_cmds(void)
16741{
16742 sigma_dut_reg_cmd("sta_get_ip_config", req_intf,
16743 cmd_sta_get_ip_config);
16744 sigma_dut_reg_cmd("sta_set_ip_config", req_intf,
16745 cmd_sta_set_ip_config);
16746 sigma_dut_reg_cmd("sta_get_info", req_intf, cmd_sta_get_info);
16747 sigma_dut_reg_cmd("sta_get_mac_address", req_intf,
16748 cmd_sta_get_mac_address);
16749 sigma_dut_reg_cmd("sta_is_connected", req_intf, cmd_sta_is_connected);
16750 sigma_dut_reg_cmd("sta_verify_ip_connection", req_intf,
16751 cmd_sta_verify_ip_connection);
16752 sigma_dut_reg_cmd("sta_get_bssid", req_intf, cmd_sta_get_bssid);
16753 sigma_dut_reg_cmd("sta_set_encryption", req_intf,
16754 cmd_sta_set_encryption);
16755 sigma_dut_reg_cmd("sta_set_psk", req_intf, cmd_sta_set_psk);
16756 sigma_dut_reg_cmd("sta_set_eaptls", req_intf, cmd_sta_set_eaptls);
16757 sigma_dut_reg_cmd("sta_set_eapttls", req_intf, cmd_sta_set_eapttls);
16758 sigma_dut_reg_cmd("sta_set_eapsim", req_intf, cmd_sta_set_eapsim);
16759 sigma_dut_reg_cmd("sta_set_peap", req_intf, cmd_sta_set_peap);
16760 sigma_dut_reg_cmd("sta_set_eapfast", req_intf, cmd_sta_set_eapfast);
16761 sigma_dut_reg_cmd("sta_set_eapaka", req_intf, cmd_sta_set_eapaka);
16762 sigma_dut_reg_cmd("sta_set_eapakaprime", req_intf,
16763 cmd_sta_set_eapakaprime);
16764 sigma_dut_reg_cmd("sta_set_security", req_intf, cmd_sta_set_security);
16765 sigma_dut_reg_cmd("sta_set_uapsd", req_intf, cmd_sta_set_uapsd);
16766 /* TODO: sta_set_ibss */
16767 /* TODO: sta_set_mode */
16768 sigma_dut_reg_cmd("sta_set_wmm", req_intf, cmd_sta_set_wmm);
16769 sigma_dut_reg_cmd("sta_associate", req_intf, cmd_sta_associate);
16770 /* TODO: sta_up_load */
16771 sigma_dut_reg_cmd("sta_preset_testparameters", req_intf,
16772 cmd_sta_preset_testparameters);
16773 /* TODO: sta_set_system */
16774 sigma_dut_reg_cmd("sta_set_11n", req_intf, cmd_sta_set_11n);
16775 /* TODO: sta_set_rifs_test */
16776 sigma_dut_reg_cmd("sta_set_wireless", req_intf, cmd_sta_set_wireless);
16777 sigma_dut_reg_cmd("sta_send_addba", req_intf, cmd_sta_send_addba);
16778 /* TODO: sta_send_coexist_mgmt */
16779 sigma_dut_reg_cmd("sta_disconnect", req_intf, cmd_sta_disconnect);
16780 sigma_dut_reg_cmd("sta_reassoc", req_intf, cmd_sta_reassoc);
16781 sigma_dut_reg_cmd("sta_reassociate", req_intf, cmd_sta_reassoc);
16782 sigma_dut_reg_cmd("sta_reset_default", req_intf,
16783 cmd_sta_reset_default);
16784 sigma_dut_reg_cmd("sta_send_frame", req_intf, cmd_sta_send_frame);
16785 sigma_dut_reg_cmd("sta_set_macaddr", req_intf, cmd_sta_set_macaddr);
16786 sigma_dut_reg_cmd("sta_set_rfeature", req_intf, cmd_sta_set_rfeature);
16787 sigma_dut_reg_cmd("sta_set_radio", req_intf, cmd_sta_set_radio);
16788 sigma_dut_reg_cmd("sta_set_pwrsave", req_intf, cmd_sta_set_pwrsave);
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020016789 sigma_dut_reg_cmd("sta_set_power_save", req_intf, cmd_sta_set_pwrsave);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016790 sigma_dut_reg_cmd("sta_bssid_pool", req_intf, cmd_sta_bssid_pool);
16791 sigma_dut_reg_cmd("sta_reset_parm", req_intf, cmd_sta_reset_parm);
16792 sigma_dut_reg_cmd("sta_get_key", req_intf, cmd_sta_get_key);
16793 sigma_dut_reg_cmd("sta_hs2_associate", req_intf,
16794 cmd_sta_hs2_associate);
Jouni Malinenb639f1c2018-09-13 02:39:46 +030016795 sigma_dut_reg_cmd("sta_hs2_venue_info", req_intf,
16796 cmd_sta_hs2_venue_info);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016797 sigma_dut_reg_cmd("sta_add_credential", req_intf,
16798 cmd_sta_add_credential);
16799 sigma_dut_reg_cmd("sta_scan", req_intf, cmd_sta_scan);
Jouni Malinen5e5d43d2018-01-10 17:29:33 +020016800 sigma_dut_reg_cmd("sta_scan_bss", req_intf, cmd_sta_scan_bss);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016801 sigma_dut_reg_cmd("sta_set_systime", NULL, cmd_sta_set_systime);
16802 sigma_dut_reg_cmd("sta_osu", req_intf, cmd_sta_osu);
16803 sigma_dut_reg_cmd("sta_policy_update", req_intf, cmd_sta_policy_update);
16804 sigma_dut_reg_cmd("sta_er_config", NULL, cmd_sta_er_config);
16805 sigma_dut_reg_cmd("sta_wps_connect_pw_token", req_intf,
16806 cmd_sta_wps_connect_pw_token);
Jouni Malinen82905202018-04-29 17:20:10 +030016807 sigma_dut_reg_cmd("sta_exec_action", NULL, cmd_sta_exec_action);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016808 sigma_dut_reg_cmd("sta_get_events", req_intf, cmd_sta_get_events);
16809 sigma_dut_reg_cmd("sta_get_parameter", req_intf, cmd_sta_get_parameter);
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020016810 sigma_dut_reg_cmd("start_wps_registration", NULL,
vamsi krishna9b144002017-09-20 13:28:13 +053016811 cmd_start_wps_registration);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016812}