blob: 8240cf4827e5b8d49adfbc83bad29884232b2376 [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 Malinenc12ea4a2018-01-05 21:07:10 +02005 * Copyright (c) 2018, 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
Jouni Malinenf7222712019-06-13 01:50:21 +03002134static enum sigma_cmd_result cmd_sta_set_psk(struct sigma_dut *dut,
2135 struct sigma_conn *conn,
2136 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002137{
2138 const char *intf = get_param(cmd, "Interface");
Jouni Malinen992a81e2017-08-22 13:57:47 +03002139 const char *type = get_param(cmd, "Type");
Jouni Malinen1287cd72018-01-04 17:08:01 +02002140 const char *pmf = get_param(cmd, "PMF");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002141 const char *network_mode = get_param(cmd, "network_mode");
Jouni Malinene4fde732019-03-25 22:29:37 +02002142 const char *akm = get_param(cmd, "AKMSuiteType");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002143 const char *ifname, *val, *alg;
2144 int id;
Jouni Malinen4b3769d2019-10-10 16:20:29 +03002145 char buf[50];
Jouni Malinen11e55212019-11-22 21:46:59 +02002146 int sae_pwe = -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002147
2148 if (intf == NULL)
2149 return -1;
2150
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002151 if (strcmp(intf, get_main_ifname(dut)) == 0)
2152 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002153 else
2154 ifname = intf;
2155
2156 id = set_wpa_common(dut, conn, ifname, cmd);
2157 if (id < 0)
2158 return id;
2159
2160 val = get_param(cmd, "keyMgmtType");
2161 alg = get_param(cmd, "micAlg");
2162
Jouni Malinen992a81e2017-08-22 13:57:47 +03002163 if (type && strcasecmp(type, "SAE") == 0) {
Jouni Malinene4fde732019-03-25 22:29:37 +02002164 if (!akm && val && strcasecmp(val, "wpa2-ft") == 0) {
Jouni Malinen992a81e2017-08-22 13:57:47 +03002165 if (set_network(ifname, id, "key_mgmt", "FT-SAE") < 0)
2166 return -2;
Jouni Malinene4fde732019-03-25 22:29:37 +02002167 } else if (!akm) {
Jouni Malinen992a81e2017-08-22 13:57:47 +03002168 if (set_network(ifname, id, "key_mgmt", "SAE") < 0)
2169 return -2;
2170 }
2171 if (wpa_command(ifname, "SET sae_groups ") != 0) {
2172 sigma_dut_print(dut, DUT_MSG_ERROR,
2173 "Failed to clear sae_groups to default");
2174 return -2;
2175 }
Jouni Malinen1287cd72018-01-04 17:08:01 +02002176 if (!pmf) {
2177 dut->sta_pmf = STA_PMF_REQUIRED;
2178 if (set_network(ifname, id, "ieee80211w", "2") < 0)
2179 return -2;
2180 }
Jouni Malinen0ab50f42017-08-31 01:34:59 +03002181 } else if (type && strcasecmp(type, "PSK-SAE") == 0) {
2182 if (val && strcasecmp(val, "wpa2-ft") == 0) {
2183 if (set_network(ifname, id, "key_mgmt",
2184 "FT-SAE FT-PSK") < 0)
2185 return -2;
Jouni Malinen3b73d872019-06-12 03:13:25 +03002186 } else if (!akm) {
Jouni Malinen0ab50f42017-08-31 01:34:59 +03002187 if (set_network(ifname, id, "key_mgmt",
2188 "SAE WPA-PSK") < 0)
2189 return -2;
2190 }
2191 if (wpa_command(ifname, "SET sae_groups ") != 0) {
2192 sigma_dut_print(dut, DUT_MSG_ERROR,
2193 "Failed to clear sae_groups to default");
2194 return -2;
2195 }
Jouni Malinen1287cd72018-01-04 17:08:01 +02002196 if (!pmf) {
2197 dut->sta_pmf = STA_PMF_OPTIONAL;
2198 if (set_network(ifname, id, "ieee80211w", "1") < 0)
2199 return -2;
2200 }
Jouni Malinen992a81e2017-08-22 13:57:47 +03002201 } else if (alg && strcasecmp(alg, "SHA-256") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002202 if (set_network(ifname, id, "key_mgmt", "WPA-PSK-SHA256") < 0)
2203 return -2;
2204 } else if (alg && strcasecmp(alg, "SHA-1") == 0) {
2205 if (set_network(ifname, id, "key_mgmt", "WPA-PSK") < 0)
2206 return -2;
Ashwini Patil6dbf7b02017-03-20 13:42:11 +05302207 } else if (val && strcasecmp(val, "wpa2-ft") == 0) {
2208 if (set_network(ifname, id, "key_mgmt", "FT-PSK") < 0)
2209 return -2;
Jouni Malinen3b73d872019-06-12 03:13:25 +03002210 } else if (!akm &&
2211 ((val && strcasecmp(val, "wpa2-sha256") == 0) ||
2212 dut->sta_pmf == STA_PMF_REQUIRED)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002213 if (set_network(ifname, id, "key_mgmt",
2214 "WPA-PSK WPA-PSK-SHA256") < 0)
2215 return -2;
Jouni Malinen77ff3f02019-03-28 03:45:40 +02002216 } else if (!akm && dut->sta_pmf == STA_PMF_OPTIONAL) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002217 if (set_network(ifname, id, "key_mgmt",
2218 "WPA-PSK WPA-PSK-SHA256") < 0)
2219 return -2;
Jouni Malinen77ff3f02019-03-28 03:45:40 +02002220 } else if (!akm) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002221 if (set_network(ifname, id, "key_mgmt", "WPA-PSK") < 0)
2222 return -2;
2223 }
2224
2225 val = get_param(cmd, "passPhrase");
2226 if (val == NULL)
2227 return -1;
Jouni Malinen2126f422017-10-11 23:24:33 +03002228 if (type && strcasecmp(type, "SAE") == 0) {
2229 if (set_network_quoted(ifname, id, "sae_password", val) < 0)
2230 return -2;
2231 } else {
2232 if (set_network_quoted(ifname, id, "psk", val) < 0)
2233 return -2;
2234 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002235
Jouni Malinen78d10c42019-03-25 22:34:32 +02002236 val = get_param(cmd, "PasswordId");
2237 if (val && set_network_quoted(ifname, id, "sae_password_id", val) < 0)
2238 return ERROR_SEND_STATUS;
2239
Jouni Malinen992a81e2017-08-22 13:57:47 +03002240 val = get_param(cmd, "ECGroupID");
2241 if (val) {
Jouni Malinenb54f0df2019-12-12 01:57:29 +02002242 snprintf(buf, sizeof(buf), "SET sae_groups %s", val);
Jouni Malinen992a81e2017-08-22 13:57:47 +03002243 if (wpa_command(ifname, buf) != 0) {
2244 sigma_dut_print(dut, DUT_MSG_ERROR,
2245 "Failed to clear sae_groups");
2246 return -2;
2247 }
2248 }
2249
Jouni Malinen68143132017-09-02 02:34:08 +03002250 val = get_param(cmd, "InvalidSAEElement");
2251 if (val) {
2252 free(dut->sae_commit_override);
2253 dut->sae_commit_override = strdup(val);
2254 }
2255
Jouni Malinen4b3769d2019-10-10 16:20:29 +03002256 val = get_param(cmd, "PMKID_Include");
2257 if (val) {
2258 snprintf(buf, sizeof(buf), "SET sae_pmkid_in_assoc %d",
2259 get_enable_disable(val));
2260 wpa_command(intf, buf);
2261 }
2262
Jouni Malineneeb43d32019-12-06 17:40:07 +02002263 val = get_param(cmd, "IgnoreH2E_RSNXE_BSSMemSel");
2264 if (val) {
2265 snprintf(buf, sizeof(buf), "SET ignore_sae_h2e_only %d",
2266 get_enable_disable(val));
2267 wpa_command(intf, buf);
2268 }
2269
Jouni Malinenf2348d22019-12-07 11:52:55 +02002270 val = get_param(cmd, "ECGroupID_RGE");
2271 if (val) {
2272 snprintf(buf, sizeof(buf), "SET extra_sae_rejected_groups %s",
2273 val);
2274 wpa_command(intf, buf);
2275 }
2276
Jouni Malinen99e55022019-12-07 13:59:41 +02002277 val = get_param(cmd, "RSNXE_Content");
2278 if (val) {
2279 const char *param;
2280
2281 if (strncasecmp(val, "AssocReq:", 9) == 0) {
2282 val += 9;
2283 param = "rsnxe_override_assoc";
2284 } else if (strncasecmp(val, "EapolM2:", 8) == 0) {
2285 val += 8;
2286 param = "rsnxe_override_eapol";
2287 } else {
2288 send_resp(dut, conn, SIGMA_ERROR,
2289 "errorCode,Unsupported RSNXE_Content value");
2290 return STATUS_SENT_ERROR;
2291 }
2292 snprintf(buf, sizeof(buf), "SET %s %s", param, val);
2293 wpa_command(intf, buf);
2294 }
2295
Jouni Malinen11e55212019-11-22 21:46:59 +02002296 val = get_param(cmd, "sae_pwe");
2297 if (val) {
2298 if (strcasecmp(val, "h2e") == 0) {
2299 dut->sae_pwe = SAE_PWE_H2E;
Jouni Malinen7244a412019-12-07 11:54:10 +02002300 } else if (strcasecmp(val, "loop") == 0 ||
2301 strcasecmp(val, "looping") == 0) {
Jouni Malinen11e55212019-11-22 21:46:59 +02002302 dut->sae_pwe = SAE_PWE_LOOP;
2303 } else {
2304 send_resp(dut, conn, SIGMA_ERROR,
2305 "errorCode,Unsupported sae_pwe value");
2306 return STATUS_SENT_ERROR;
2307 }
2308 }
Vinita S. Maloo6d7454f2020-04-02 15:03:26 +05302309
2310 val = get_param(cmd, "Clear_RSNXE");
2311 if (val && strcmp(val, "1") == 0 &&
2312 (wpa_command(intf, "SET rsnxe_override_assoc ") ||
2313 wpa_command(intf, "SET rsnxe_override_eapol "))) {
2314 send_resp(dut, conn, SIGMA_ERROR,
2315 "errorCode,Failed to clear RSNXE");
Jouni Malinenb11498c2020-08-03 11:05:53 +03002316 return STATUS_SENT_ERROR;
Vinita S. Maloo6d7454f2020-04-02 15:03:26 +05302317 }
2318
Jouni Malinenc0078772020-03-04 21:23:16 +02002319 if (dut->sae_pwe == SAE_PWE_LOOP && get_param(cmd, "PasswordId"))
2320 sae_pwe = 3;
2321 else if (dut->sae_pwe == SAE_PWE_LOOP)
Jouni Malinen11e55212019-11-22 21:46:59 +02002322 sae_pwe = 0;
2323 else if (dut->sae_pwe == SAE_PWE_H2E)
2324 sae_pwe = 1;
2325 else if (dut->sae_h2e_default)
2326 sae_pwe = 2;
2327 snprintf(buf, sizeof(buf), "SET sae_pwe %d", sae_pwe);
2328 if (sae_pwe >= 0 && wpa_command(ifname, buf) != 0)
2329 return ERROR_SEND_STATUS;
2330
Veerendranath Jakkam0316be12020-06-23 20:11:41 +05302331 val = get_param(cmd, "sae_pk");
2332 if (val && strcmp(val, "0") == 0 &&
2333 set_network(ifname, id, "sae_pk", "2") < 0)
2334 return ERROR_SEND_STATUS;
2335
Veerendranath Jakkama9177042020-08-10 00:14:03 +05302336 val = get_param(cmd, "sae_pk_only");
2337 if (val && strcmp(val, "1") == 0 &&
2338 set_network(ifname, id, "sae_pk", "1") < 0)
2339 return ERROR_SEND_STATUS;
2340
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002341 if (dut->program == PROGRAM_60GHZ && network_mode &&
2342 strcasecmp(network_mode, "PBSS") == 0 &&
2343 set_network(ifname, id, "pbss", "1") < 0)
2344 return -2;
2345
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002346 return 1;
2347}
2348
2349
Jouni Malinen8ac93452019-08-14 15:19:13 +03002350static enum sigma_cmd_result set_trust_root_system(struct sigma_dut *dut,
2351 struct sigma_conn *conn,
2352 const char *ifname, int id)
2353{
2354 char buf[200];
2355
2356 snprintf(buf, sizeof(buf), "%s/certs", sigma_cert_path);
2357 if (!file_exists(buf))
2358 strlcpy(buf, "/system/etc/security/cacerts", sizeof(buf));
2359 if (!file_exists(buf))
2360 strlcpy(buf, "/etc/ssl/certs", sizeof(buf));
2361 if (!file_exists(buf)) {
2362 char msg[300];
2363
2364 snprintf(msg, sizeof(msg),
2365 "ErrorCode,trustedRootCA system store (%s) not found",
2366 buf);
2367 send_resp(dut, conn, SIGMA_ERROR, msg);
2368 return STATUS_SENT_ERROR;
2369 }
2370
2371 if (set_network_quoted(ifname, id, "ca_path", buf) < 0)
2372 return ERROR_SEND_STATUS;
2373
2374 return SUCCESS_SEND_STATUS;
2375}
2376
2377
2378static enum sigma_cmd_result set_trust_root(struct sigma_dut *dut,
2379 struct sigma_conn *conn,
2380 const char *ifname, int id,
2381 const char *val)
2382{
2383 char buf[200];
2384#ifdef ANDROID
2385 unsigned char kvalue[KEYSTORE_MESSAGE_SIZE];
2386 int length;
2387#endif /* ANDROID */
2388
2389 if (strcmp(val, "DEFAULT") == 0)
2390 return set_trust_root_system(dut, conn, ifname, id);
2391
2392#ifdef ANDROID
2393 snprintf(buf, sizeof(buf), "CACERT_%s", val);
2394 length = android_keystore_get(ANDROID_KEYSTORE_GET, buf, kvalue);
2395 if (length > 0) {
2396 sigma_dut_print(dut, DUT_MSG_INFO, "Use Android keystore [%s]",
2397 buf);
2398 snprintf(buf, sizeof(buf), "keystore://CACERT_%s", val);
2399 goto ca_cert_selected;
2400 }
2401#endif /* ANDROID */
2402
2403 snprintf(buf, sizeof(buf), "%s/%s", sigma_cert_path, val);
2404#ifdef __linux__
2405 if (!file_exists(buf)) {
2406 char msg[300];
2407
2408 snprintf(msg, sizeof(msg),
2409 "ErrorCode,trustedRootCA file (%s) not found", buf);
2410 send_resp(dut, conn, SIGMA_ERROR, msg);
2411 return STATUS_SENT_ERROR;
2412 }
2413#endif /* __linux__ */
2414#ifdef ANDROID
2415ca_cert_selected:
2416#endif /* ANDROID */
2417 if (set_network_quoted(ifname, id, "ca_cert", buf) < 0)
2418 return ERROR_SEND_STATUS;
2419
2420 return SUCCESS_SEND_STATUS;
2421}
2422
2423
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002424static int set_eap_common(struct sigma_dut *dut, struct sigma_conn *conn,
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302425 const char *ifname, int username_identity,
2426 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002427{
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002428 const char *val, *alg, *akm, *trust_root, *domain, *domain_suffix;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002429 int id;
Jouni Malinen53264f62019-05-03 13:04:40 +03002430 char buf[200], buf2[300];
Jouni Malinen8179fee2019-03-28 03:19:47 +02002431 int erp = 0;
Jouni Malinen8ac93452019-08-14 15:19:13 +03002432 enum sigma_cmd_result res;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002433
2434 id = set_wpa_common(dut, conn, ifname, cmd);
2435 if (id < 0)
2436 return id;
2437
2438 val = get_param(cmd, "keyMgmtType");
2439 alg = get_param(cmd, "micAlg");
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302440 akm = get_param(cmd, "AKMSuiteType");
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002441 trust_root = get_param(cmd, "trustedRootCA");
2442 domain = get_param(cmd, "Domain");
2443 domain_suffix = get_param(cmd, "DomainSuffix");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002444
Jouni Malinenad395a22017-09-01 21:13:46 +03002445 if (val && strcasecmp(val, "SuiteB") == 0) {
2446 if (set_network(ifname, id, "key_mgmt", "WPA-EAP-SUITE-B-192") <
2447 0)
2448 return -2;
2449 } else if (alg && strcasecmp(alg, "SHA-256") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002450 if (set_network(ifname, id, "key_mgmt", "WPA-EAP-SHA256") < 0)
2451 return -2;
2452 } else if (alg && strcasecmp(alg, "SHA-1") == 0) {
2453 if (set_network(ifname, id, "key_mgmt", "WPA-EAP") < 0)
2454 return -2;
2455 } else if (val && strcasecmp(val, "wpa2-ft") == 0) {
2456 if (set_network(ifname, id, "key_mgmt", "FT-EAP") < 0)
2457 return -2;
Jouni Malinend6a9d692019-03-28 03:01:24 +02002458 } else if (!akm &&
2459 ((val && strcasecmp(val, "wpa2-sha256") == 0) ||
2460 dut->sta_pmf == STA_PMF_REQUIRED)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002461 if (set_network(ifname, id, "key_mgmt",
2462 "WPA-EAP WPA-EAP-SHA256") < 0)
2463 return -2;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302464 } else if (akm && atoi(akm) == 14) {
2465 if (dut->sta_pmf == STA_PMF_OPTIONAL ||
2466 dut->sta_pmf == STA_PMF_REQUIRED) {
2467 if (set_network(ifname, id, "key_mgmt",
2468 "WPA-EAP-SHA256 FILS-SHA256") < 0)
2469 return -2;
2470 } else {
2471 if (set_network(ifname, id, "key_mgmt",
2472 "WPA-EAP FILS-SHA256") < 0)
2473 return -2;
2474 }
2475
Jouni Malinen8179fee2019-03-28 03:19:47 +02002476 erp = 1;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302477 } else if (akm && atoi(akm) == 15) {
2478 if (dut->sta_pmf == STA_PMF_OPTIONAL ||
2479 dut->sta_pmf == STA_PMF_REQUIRED) {
2480 if (set_network(ifname, id, "key_mgmt",
2481 "WPA-EAP-SHA256 FILS-SHA384") < 0)
2482 return -2;
2483 } else {
2484 if (set_network(ifname, id, "key_mgmt",
2485 "WPA-EAP FILS-SHA384") < 0)
2486 return -2;
2487 }
2488
Jouni Malinen8179fee2019-03-28 03:19:47 +02002489 erp = 1;
Jouni Malinend6a9d692019-03-28 03:01:24 +02002490 } else if (!akm && dut->sta_pmf == STA_PMF_OPTIONAL) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002491 if (set_network(ifname, id, "key_mgmt",
2492 "WPA-EAP WPA-EAP-SHA256") < 0)
2493 return -2;
Jouni Malinend6a9d692019-03-28 03:01:24 +02002494 } else if (!akm) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002495 if (set_network(ifname, id, "key_mgmt", "WPA-EAP") < 0)
2496 return -2;
2497 }
2498
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002499 if (trust_root) {
2500 if (strcmp(trust_root, "DEFAULT") == 0 && !domain &&
2501 !domain_suffix) {
2502 send_resp(dut, conn, SIGMA_ERROR,
2503 "errorCode,trustRootCA DEFAULT used without specifying Domain or DomainSuffix");
2504 return STATUS_SENT_ERROR;
2505 }
2506 res = set_trust_root(dut, conn, ifname, id, trust_root);
Jouni Malinen8ac93452019-08-14 15:19:13 +03002507 if (res != SUCCESS_SEND_STATUS)
2508 return res;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002509 }
2510
Jouni Malinen53264f62019-05-03 13:04:40 +03002511 val = get_param(cmd, "ServerCert");
2512 if (val) {
2513 FILE *f;
2514 char *result = NULL, *pos;
2515
2516 snprintf(buf, sizeof(buf), "%s/%s.sha256", sigma_cert_path,
2517 val);
2518 f = fopen(buf, "r");
2519 if (f) {
2520 result = fgets(buf, sizeof(buf), f);
2521 fclose(f);
2522 }
2523 if (!result) {
2524 snprintf(buf2, sizeof(buf2),
2525 "ErrorCode,ServerCert hash could not be read from %s",
2526 buf);
2527 send_resp(dut, conn, SIGMA_ERROR, buf2);
2528 return STATUS_SENT_ERROR;
2529 }
2530 pos = strchr(buf, '\n');
2531 if (pos)
2532 *pos = '\0';
Jouni Malinen0572a742020-10-08 13:53:25 +03002533 pos = strchr(buf, '\r');
2534 if (pos)
2535 *pos = '\0';
Jouni Malinen53264f62019-05-03 13:04:40 +03002536 snprintf(buf2, sizeof(buf2), "hash://server/sha256/%s", buf);
2537 if (set_network_quoted(ifname, id, "ca_cert", buf2) < 0)
2538 return ERROR_SEND_STATUS;
Jouni Malinen29108dc2019-06-13 23:42:11 +03002539
2540 snprintf(buf, sizeof(buf), "%s/%s.tod", sigma_cert_path, val);
2541 if (file_exists(buf)) {
2542 sigma_dut_print(dut, DUT_MSG_DEBUG,
2543 "TOD policy enabled for the configured ServerCert hash");
2544 dut->sta_tod_policy = 1;
2545 }
Jouni Malinen53264f62019-05-03 13:04:40 +03002546 }
2547
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002548 if (domain &&
2549 set_network_quoted(ifname, id, "domain_match", domain) < 0)
Jouni Malinen96f84b02019-05-03 12:32:56 +03002550 return ERROR_SEND_STATUS;
2551
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002552 if (domain_suffix &&
2553 set_network_quoted(ifname, id, "domain_suffix_match",
2554 domain_suffix) < 0)
Jouni Malinen96f84b02019-05-03 12:32:56 +03002555 return ERROR_SEND_STATUS;
2556
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302557 if (username_identity) {
2558 val = get_param(cmd, "username");
2559 if (val) {
2560 if (set_network_quoted(ifname, id, "identity", val) < 0)
2561 return -2;
2562 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002563
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302564 val = get_param(cmd, "password");
2565 if (val) {
2566 if (set_network_quoted(ifname, id, "password", val) < 0)
2567 return -2;
2568 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002569 }
2570
Jouni Malinen8179fee2019-03-28 03:19:47 +02002571 if (dut->akm_values &
2572 ((1 << AKM_FILS_SHA256) |
2573 (1 << AKM_FILS_SHA384) |
2574 (1 << AKM_FT_FILS_SHA256) |
2575 (1 << AKM_FT_FILS_SHA384)))
2576 erp = 1;
2577 if (erp && set_network(ifname, id, "erp", "1") < 0)
2578 return ERROR_SEND_STATUS;
2579
Jouni Malinen134fe3c2019-06-12 04:16:49 +03002580 dut->sta_associate_wait_connect = 1;
2581
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002582 return id;
2583}
2584
2585
Jouni Malinen5eabb2a2017-10-03 18:17:30 +03002586static int set_tls_cipher(const char *ifname, int id, const char *cipher)
2587{
2588 const char *val;
2589
2590 if (!cipher)
2591 return 0;
2592
2593 if (strcasecmp(cipher, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384") == 0)
2594 val = "ECDHE-ECDSA-AES256-GCM-SHA384";
2595 else if (strcasecmp(cipher,
2596 "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384") == 0)
2597 val = "ECDHE-RSA-AES256-GCM-SHA384";
2598 else if (strcasecmp(cipher, "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384") == 0)
2599 val = "DHE-RSA-AES256-GCM-SHA384";
2600 else if (strcasecmp(cipher,
2601 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256") == 0)
2602 val = "ECDHE-ECDSA-AES128-GCM-SHA256";
2603 else
2604 return -1;
2605
2606 /* Need to clear phase1="tls_suiteb=1" to allow cipher enforcement */
2607 set_network_quoted(ifname, id, "phase1", "");
2608
2609 return set_network_quoted(ifname, id, "openssl_ciphers", val);
2610}
2611
2612
Jouni Malinenf7222712019-06-13 01:50:21 +03002613static enum sigma_cmd_result cmd_sta_set_eaptls(struct sigma_dut *dut,
2614 struct sigma_conn *conn,
2615 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002616{
2617 const char *intf = get_param(cmd, "Interface");
2618 const char *ifname, *val;
2619 int id;
2620 char buf[200];
2621#ifdef ANDROID
2622 unsigned char kvalue[KEYSTORE_MESSAGE_SIZE];
2623 int length;
2624 int jb_or_newer = 0;
2625 char prop[PROPERTY_VALUE_MAX];
2626#endif /* ANDROID */
2627
2628 if (intf == NULL)
2629 return -1;
2630
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002631 if (strcmp(intf, get_main_ifname(dut)) == 0)
2632 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002633 else
2634 ifname = intf;
2635
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302636 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002637 if (id < 0)
2638 return id;
2639
2640 if (set_network(ifname, id, "eap", "TLS") < 0)
2641 return -2;
2642
Pradeep Reddy POTTETI9f6c2132016-05-05 16:28:19 +05302643 if (!get_param(cmd, "username") &&
2644 set_network_quoted(ifname, id, "identity",
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002645 "wifi-user@wifilabs.local") < 0)
2646 return -2;
2647
2648 val = get_param(cmd, "clientCertificate");
2649 if (val == NULL)
2650 return -1;
2651#ifdef ANDROID
2652 snprintf(buf, sizeof(buf), "USRPKEY_%s", val);
2653 length = android_keystore_get(ANDROID_KEYSTORE_GET, buf, kvalue);
2654 if (length < 0) {
2655 /*
2656 * JB started reporting keystore type mismatches, so retry with
2657 * the GET_PUBKEY command if the generic GET fails.
2658 */
2659 length = android_keystore_get(ANDROID_KEYSTORE_GET_PUBKEY,
2660 buf, kvalue);
2661 }
2662
2663 if (property_get("ro.build.version.release", prop, NULL) != 0) {
2664 sigma_dut_print(dut, DUT_MSG_DEBUG, "Android release %s", prop);
2665 if (strncmp(prop, "4.0", 3) != 0)
2666 jb_or_newer = 1;
2667 } else
2668 jb_or_newer = 1; /* assume newer */
2669
2670 if (jb_or_newer && length > 0) {
2671 sigma_dut_print(dut, DUT_MSG_INFO,
2672 "Use Android keystore [%s]", buf);
2673 if (set_network(ifname, id, "engine", "1") < 0)
2674 return -2;
2675 if (set_network_quoted(ifname, id, "engine_id", "keystore") < 0)
2676 return -2;
2677 snprintf(buf, sizeof(buf), "USRPKEY_%s", val);
2678 if (set_network_quoted(ifname, id, "key_id", buf) < 0)
2679 return -2;
2680 snprintf(buf, sizeof(buf), "keystore://USRCERT_%s", val);
2681 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
2682 return -2;
2683 return 1;
2684 } else if (length > 0) {
2685 sigma_dut_print(dut, DUT_MSG_INFO,
2686 "Use Android keystore [%s]", buf);
2687 snprintf(buf, sizeof(buf), "keystore://USRPKEY_%s", val);
2688 if (set_network_quoted(ifname, id, "private_key", buf) < 0)
2689 return -2;
2690 snprintf(buf, sizeof(buf), "keystore://USRCERT_%s", val);
2691 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
2692 return -2;
2693 return 1;
2694 }
2695#endif /* ANDROID */
2696
2697 snprintf(buf, sizeof(buf), "%s/%s", sigma_cert_path, val);
2698#ifdef __linux__
2699 if (!file_exists(buf)) {
2700 char msg[300];
2701 snprintf(msg, sizeof(msg), "ErrorCode,clientCertificate file "
2702 "(%s) not found", buf);
2703 send_resp(dut, conn, SIGMA_ERROR, msg);
2704 return -3;
2705 }
2706#endif /* __linux__ */
2707 if (set_network_quoted(ifname, id, "private_key", buf) < 0)
2708 return -2;
2709 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
2710 return -2;
2711
2712 if (set_network_quoted(ifname, id, "private_key_passwd", "wifi") < 0)
2713 return -2;
2714
Jouni Malinen5eabb2a2017-10-03 18:17:30 +03002715 val = get_param(cmd, "keyMgmtType");
2716 if (val && strcasecmp(val, "SuiteB") == 0) {
2717 val = get_param(cmd, "CertType");
2718 if (val && strcasecmp(val, "RSA") == 0) {
2719 if (set_network_quoted(ifname, id, "phase1",
2720 "tls_suiteb=1") < 0)
2721 return -2;
2722 } else {
2723 if (set_network_quoted(ifname, id, "openssl_ciphers",
2724 "SUITEB192") < 0)
2725 return -2;
2726 }
2727
2728 val = get_param(cmd, "TLSCipher");
2729 if (set_tls_cipher(ifname, id, val) < 0) {
2730 send_resp(dut, conn, SIGMA_ERROR,
2731 "ErrorCode,Unsupported TLSCipher value");
2732 return -3;
2733 }
2734 }
2735
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002736 return 1;
2737}
2738
2739
Jouni Malinenf7222712019-06-13 01:50:21 +03002740static enum sigma_cmd_result cmd_sta_set_eapttls(struct sigma_dut *dut,
2741 struct sigma_conn *conn,
2742 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002743{
2744 const char *intf = get_param(cmd, "Interface");
2745 const char *ifname;
2746 int id;
2747
2748 if (intf == NULL)
2749 return -1;
2750
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002751 if (strcmp(intf, get_main_ifname(dut)) == 0)
2752 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002753 else
2754 ifname = intf;
2755
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302756 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002757 if (id < 0)
2758 return id;
2759
2760 if (set_network(ifname, id, "eap", "TTLS") < 0) {
2761 send_resp(dut, conn, SIGMA_ERROR,
2762 "errorCode,Failed to set TTLS method");
2763 return 0;
2764 }
2765
2766 if (set_network_quoted(ifname, id, "phase2", "auth=MSCHAPV2") < 0) {
2767 send_resp(dut, conn, SIGMA_ERROR,
2768 "errorCode,Failed to set MSCHAPv2 for TTLS Phase 2");
2769 return 0;
2770 }
2771
2772 return 1;
2773}
2774
2775
Jouni Malinenf7222712019-06-13 01:50:21 +03002776static enum sigma_cmd_result cmd_sta_set_eapsim(struct sigma_dut *dut,
2777 struct sigma_conn *conn,
2778 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002779{
2780 const char *intf = get_param(cmd, "Interface");
2781 const char *ifname;
2782 int id;
2783
2784 if (intf == NULL)
2785 return -1;
2786
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002787 if (strcmp(intf, get_main_ifname(dut)) == 0)
2788 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002789 else
2790 ifname = intf;
2791
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302792 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002793 if (id < 0)
2794 return id;
2795
2796 if (set_network(ifname, id, "eap", "SIM") < 0)
2797 return -2;
2798
2799 return 1;
2800}
2801
2802
Jouni Malinenf7222712019-06-13 01:50:21 +03002803static enum sigma_cmd_result cmd_sta_set_peap(struct sigma_dut *dut,
2804 struct sigma_conn *conn,
2805 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002806{
2807 const char *intf = get_param(cmd, "Interface");
2808 const char *ifname, *val;
2809 int id;
2810 char buf[100];
2811
2812 if (intf == NULL)
2813 return -1;
2814
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002815 if (strcmp(intf, get_main_ifname(dut)) == 0)
2816 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002817 else
2818 ifname = intf;
2819
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302820 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002821 if (id < 0)
2822 return id;
2823
2824 if (set_network(ifname, id, "eap", "PEAP") < 0)
2825 return -2;
2826
2827 val = get_param(cmd, "innerEAP");
2828 if (val) {
2829 if (strcasecmp(val, "MSCHAPv2") == 0) {
2830 if (set_network_quoted(ifname, id, "phase2",
2831 "auth=MSCHAPV2") < 0)
2832 return -2;
2833 } else if (strcasecmp(val, "GTC") == 0) {
2834 if (set_network_quoted(ifname, id, "phase2",
2835 "auth=GTC") < 0)
2836 return -2;
2837 } else
2838 return -1;
2839 }
2840
2841 val = get_param(cmd, "peapVersion");
2842 if (val) {
2843 int ver = atoi(val);
2844 if (ver < 0 || ver > 1)
2845 return -1;
2846 snprintf(buf, sizeof(buf), "peapver=%d", ver);
2847 if (set_network_quoted(ifname, id, "phase1", buf) < 0)
2848 return -2;
2849 }
2850
2851 return 1;
2852}
2853
2854
Jouni Malinenf7222712019-06-13 01:50:21 +03002855static enum sigma_cmd_result cmd_sta_set_eapfast(struct sigma_dut *dut,
2856 struct sigma_conn *conn,
2857 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002858{
2859 const char *intf = get_param(cmd, "Interface");
2860 const char *ifname, *val;
2861 int id;
2862 char buf[100];
2863
2864 if (intf == NULL)
2865 return -1;
2866
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002867 if (strcmp(intf, get_main_ifname(dut)) == 0)
2868 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002869 else
2870 ifname = intf;
2871
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302872 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002873 if (id < 0)
2874 return id;
2875
2876 if (set_network(ifname, id, "eap", "FAST") < 0)
2877 return -2;
2878
2879 val = get_param(cmd, "innerEAP");
2880 if (val) {
2881 if (strcasecmp(val, "MSCHAPV2") == 0) {
2882 if (set_network_quoted(ifname, id, "phase2",
2883 "auth=MSCHAPV2") < 0)
2884 return -2;
2885 } else if (strcasecmp(val, "GTC") == 0) {
2886 if (set_network_quoted(ifname, id, "phase2",
2887 "auth=GTC") < 0)
2888 return -2;
2889 } else
2890 return -1;
2891 }
2892
2893 val = get_param(cmd, "validateServer");
2894 if (val) {
2895 /* TODO */
2896 sigma_dut_print(dut, DUT_MSG_INFO, "Ignored EAP-FAST "
2897 "validateServer=%s", val);
2898 }
2899
2900 val = get_param(cmd, "pacFile");
2901 if (val) {
2902 snprintf(buf, sizeof(buf), "blob://%s", val);
2903 if (set_network_quoted(ifname, id, "pac_file", buf) < 0)
2904 return -2;
2905 }
2906
2907 if (set_network_quoted(ifname, id, "phase1", "fast_provisioning=2") <
2908 0)
2909 return -2;
2910
2911 return 1;
2912}
2913
2914
Jouni Malinenf7222712019-06-13 01:50:21 +03002915static enum sigma_cmd_result cmd_sta_set_eapaka(struct sigma_dut *dut,
2916 struct sigma_conn *conn,
2917 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002918{
2919 const char *intf = get_param(cmd, "Interface");
Purushottam Kushwahacdd8cb12019-10-04 11:33:59 +05302920 const char *username = get_param(cmd, "Username");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002921 const char *ifname;
2922 int id;
2923
2924 if (intf == NULL)
2925 return -1;
2926
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002927 if (strcmp(intf, get_main_ifname(dut)) == 0)
2928 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002929 else
2930 ifname = intf;
2931
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302932 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002933 if (id < 0)
2934 return id;
2935
Purushottam Kushwahacdd8cb12019-10-04 11:33:59 +05302936 /* RFC 5448: EAP-AKA' MUST use the leading character "6" (ASCII 36
2937 * hexadecimal).
2938 */
2939 if (username && username[0] == '6') {
2940 if (set_network(ifname, id, "eap", "AKA'") < 0)
2941 return -2;
2942 } else if (set_network(ifname, id, "eap", "AKA") < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002943 return -2;
Purushottam Kushwahacdd8cb12019-10-04 11:33:59 +05302944 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002945
2946 return 1;
2947}
2948
2949
Jouni Malinenf7222712019-06-13 01:50:21 +03002950static enum sigma_cmd_result cmd_sta_set_eapakaprime(struct sigma_dut *dut,
2951 struct sigma_conn *conn,
2952 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002953{
2954 const char *intf = get_param(cmd, "Interface");
2955 const char *ifname;
2956 int id;
2957
2958 if (intf == NULL)
2959 return -1;
2960
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002961 if (strcmp(intf, get_main_ifname(dut)) == 0)
2962 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002963 else
2964 ifname = intf;
2965
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302966 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002967 if (id < 0)
2968 return id;
2969
2970 if (set_network(ifname, id, "eap", "AKA'") < 0)
2971 return -2;
2972
2973 return 1;
2974}
2975
2976
2977static int sta_set_open(struct sigma_dut *dut, struct sigma_conn *conn,
2978 struct sigma_cmd *cmd)
2979{
2980 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002981 const char *network_mode = get_param(cmd, "network_mode");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002982 const char *ifname;
2983 int id;
2984
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002985 if (strcmp(intf, get_main_ifname(dut)) == 0)
2986 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002987 else
2988 ifname = intf;
2989
2990 id = add_network_common(dut, conn, ifname, cmd);
2991 if (id < 0)
2992 return id;
2993
2994 if (set_network(ifname, id, "key_mgmt", "NONE") < 0)
2995 return -2;
2996
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002997 if (dut->program == PROGRAM_60GHZ && network_mode &&
2998 strcasecmp(network_mode, "PBSS") == 0 &&
2999 set_network(ifname, id, "pbss", "1") < 0)
3000 return -2;
3001
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003002 return 1;
3003}
3004
3005
Jouni Malinen8e3f8812020-10-05 10:02:03 +03003006static enum sigma_cmd_result sta_set_owe(struct sigma_dut *dut,
3007 struct sigma_conn *conn,
3008 struct sigma_cmd *cmd)
Jouni Malinen47dcc952017-10-09 16:43:24 +03003009{
3010 const char *intf = get_param(cmd, "Interface");
3011 const char *ifname, *val;
3012 int id;
3013
3014 if (intf == NULL)
Jouni Malinen8e3f8812020-10-05 10:02:03 +03003015 return INVALID_SEND_STATUS;
Jouni Malinen47dcc952017-10-09 16:43:24 +03003016
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003017 if (strcmp(intf, get_main_ifname(dut)) == 0)
3018 ifname = get_station_ifname(dut);
Jouni Malinen47dcc952017-10-09 16:43:24 +03003019 else
3020 ifname = intf;
3021
3022 id = set_wpa_common(dut, conn, ifname, cmd);
3023 if (id < 0)
3024 return id;
3025
3026 if (set_network(ifname, id, "key_mgmt", "OWE") < 0)
Jouni Malinen8e3f8812020-10-05 10:02:03 +03003027 return ERROR_SEND_STATUS;
Jouni Malinen47dcc952017-10-09 16:43:24 +03003028
Hu Wangdd5eed22020-07-16 12:18:03 +08003029 if (dut->owe_ptk_workaround &&
3030 set_network(ifname, id, "owe_ptk_workaround", "1") < 0) {
3031 sigma_dut_print(dut, DUT_MSG_ERROR,
3032 "Failed to set owe_ptk_workaround to 1");
Jouni Malinen8e3f8812020-10-05 10:02:03 +03003033 return ERROR_SEND_STATUS;
Hu Wangdd5eed22020-07-16 12:18:03 +08003034 }
3035
Jouni Malinen47dcc952017-10-09 16:43:24 +03003036 val = get_param(cmd, "ECGroupID");
Jouni Malinenfac9cad2017-10-10 18:35:55 +03003037 if (val && strcmp(val, "0") == 0) {
3038 if (wpa_command(ifname,
3039 "VENDOR_ELEM_ADD 13 ff23200000783590fb7440e03d5b3b33911f86affdcc6b4411b707846ac4ff08ddc8831ccd") != 0) {
3040 sigma_dut_print(dut, DUT_MSG_ERROR,
3041 "Failed to set OWE DH Param element override");
Jouni Malinen8e3f8812020-10-05 10:02:03 +03003042 return ERROR_SEND_STATUS;
Jouni Malinenfac9cad2017-10-10 18:35:55 +03003043 }
Hu Wangdd5eed22020-07-16 12:18:03 +08003044 } else if (val && set_network(ifname, id, "owe_group", val) < 0) {
Jouni Malinen47dcc952017-10-09 16:43:24 +03003045 sigma_dut_print(dut, DUT_MSG_ERROR,
Hu Wang6010ce72020-03-05 19:33:53 +08003046 "Failed to set owe_group");
Jouni Malinen8e3f8812020-10-05 10:02:03 +03003047 return ERROR_SEND_STATUS;
Jouni Malinen47dcc952017-10-09 16:43:24 +03003048 }
3049
Jouni Malinen8e3f8812020-10-05 10:02:03 +03003050 return SUCCESS_SEND_STATUS;
Jouni Malinen47dcc952017-10-09 16:43:24 +03003051}
3052
3053
Jouni Malinenf7222712019-06-13 01:50:21 +03003054static enum sigma_cmd_result cmd_sta_set_security(struct sigma_dut *dut,
3055 struct sigma_conn *conn,
3056 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003057{
3058 const char *type = get_param(cmd, "Type");
3059
3060 if (type == NULL) {
3061 send_resp(dut, conn, SIGMA_ERROR,
3062 "ErrorCode,Missing Type argument");
3063 return 0;
3064 }
3065
3066 if (strcasecmp(type, "OPEN") == 0)
3067 return sta_set_open(dut, conn, cmd);
Jouni Malinen47dcc952017-10-09 16:43:24 +03003068 if (strcasecmp(type, "OWE") == 0)
3069 return sta_set_owe(dut, conn, cmd);
Jouni Malinen992a81e2017-08-22 13:57:47 +03003070 if (strcasecmp(type, "PSK") == 0 ||
Jouni Malinen0ab50f42017-08-31 01:34:59 +03003071 strcasecmp(type, "PSK-SAE") == 0 ||
Jouni Malinen992a81e2017-08-22 13:57:47 +03003072 strcasecmp(type, "SAE") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003073 return cmd_sta_set_psk(dut, conn, cmd);
3074 if (strcasecmp(type, "EAPTLS") == 0)
3075 return cmd_sta_set_eaptls(dut, conn, cmd);
3076 if (strcasecmp(type, "EAPTTLS") == 0)
3077 return cmd_sta_set_eapttls(dut, conn, cmd);
3078 if (strcasecmp(type, "EAPPEAP") == 0)
3079 return cmd_sta_set_peap(dut, conn, cmd);
3080 if (strcasecmp(type, "EAPSIM") == 0)
3081 return cmd_sta_set_eapsim(dut, conn, cmd);
3082 if (strcasecmp(type, "EAPFAST") == 0)
3083 return cmd_sta_set_eapfast(dut, conn, cmd);
3084 if (strcasecmp(type, "EAPAKA") == 0)
3085 return cmd_sta_set_eapaka(dut, conn, cmd);
3086 if (strcasecmp(type, "EAPAKAPRIME") == 0)
3087 return cmd_sta_set_eapakaprime(dut, conn, cmd);
Amarnath Hullur Subramanyam81b11cd2018-01-30 19:07:17 -08003088 if (strcasecmp(type, "wep") == 0)
3089 return cmd_sta_set_encryption(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003090
3091 send_resp(dut, conn, SIGMA_ERROR,
3092 "ErrorCode,Unsupported Type value");
3093 return 0;
3094}
3095
3096
3097int ath6kl_client_uapsd(struct sigma_dut *dut, const char *intf, int uapsd)
3098{
3099#ifdef __linux__
3100 /* special handling for ath6kl */
3101 char path[128], fname[128], *pos;
3102 ssize_t res;
3103 FILE *f;
3104
Jouni Malinene39cd562019-05-29 23:39:56 +03003105 res = snprintf(fname, sizeof(fname), "/sys/class/net/%s/phy80211",
3106 intf);
3107 if (res < 0 || res >= sizeof(fname))
3108 return 0;
3109 res = readlink(fname, path, sizeof(path));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003110 if (res < 0)
3111 return 0; /* not ath6kl */
3112
3113 if (res >= (int) sizeof(path))
3114 res = sizeof(path) - 1;
3115 path[res] = '\0';
3116 pos = strrchr(path, '/');
3117 if (pos == NULL)
3118 pos = path;
3119 else
3120 pos++;
Jouni Malinen77dda642020-01-07 11:21:55 +02003121 res = snprintf(fname, sizeof(fname),
3122 "/sys/kernel/debug/ieee80211/%s/ath6kl/"
3123 "create_qos", pos);
3124 if (res < 0 || res >= sizeof(fname) || !file_exists(fname))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003125 return 0; /* not ath6kl */
3126
3127 if (uapsd) {
3128 f = fopen(fname, "w");
3129 if (f == NULL)
3130 return -1;
3131
3132 sigma_dut_print(dut, DUT_MSG_DEBUG, "Use ath6kl create_qos");
3133 fprintf(f, "4 2 2 1 2 9999999 9999999 9999999 7777777 0 4 "
3134 "45000 200 56789000 56789000 5678900 0 0 9999999 "
3135 "20000 0\n");
3136 fclose(f);
3137 } else {
Jouni Malinen77dda642020-01-07 11:21:55 +02003138 res = snprintf(fname, sizeof(fname),
3139 "/sys/kernel/debug/ieee80211/%s/ath6kl/"
3140 "delete_qos", pos);
3141 if (res < 0 || res >= sizeof(fname))
3142 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003143
3144 f = fopen(fname, "w");
3145 if (f == NULL)
3146 return -1;
3147
3148 sigma_dut_print(dut, DUT_MSG_DEBUG, "Use ath6kl delete_qos");
3149 fprintf(f, "2 4\n");
3150 fclose(f);
3151 }
3152#endif /* __linux__ */
3153
3154 return 0;
3155}
3156
3157
Jouni Malinenf7222712019-06-13 01:50:21 +03003158static enum sigma_cmd_result cmd_sta_set_uapsd(struct sigma_dut *dut,
3159 struct sigma_conn *conn,
3160 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003161{
3162 const char *intf = get_param(cmd, "Interface");
3163 /* const char *ssid = get_param(cmd, "ssid"); */
3164 const char *val;
3165 int max_sp_len = 4;
3166 int ac_be = 1, ac_bk = 1, ac_vi = 1, ac_vo = 1;
3167 char buf[100];
3168 int ret1, ret2;
3169
3170 val = get_param(cmd, "maxSPLength");
3171 if (val) {
3172 max_sp_len = atoi(val);
3173 if (max_sp_len != 0 && max_sp_len != 1 && max_sp_len != 2 &&
3174 max_sp_len != 4)
3175 return -1;
3176 }
3177
3178 val = get_param(cmd, "acBE");
3179 if (val)
3180 ac_be = atoi(val);
3181
3182 val = get_param(cmd, "acBK");
3183 if (val)
3184 ac_bk = atoi(val);
3185
3186 val = get_param(cmd, "acVI");
3187 if (val)
3188 ac_vi = atoi(val);
3189
3190 val = get_param(cmd, "acVO");
3191 if (val)
3192 ac_vo = atoi(val);
3193
3194 dut->client_uapsd = ac_be || ac_bk || ac_vi || ac_vo;
3195
3196 snprintf(buf, sizeof(buf), "P2P_SET client_apsd %d,%d,%d,%d;%d",
3197 ac_be, ac_bk, ac_vi, ac_vo, max_sp_len);
3198 ret1 = wpa_command(intf, buf);
3199
3200 snprintf(buf, sizeof(buf), "SET uapsd %d,%d,%d,%d;%d",
3201 ac_be, ac_bk, ac_vi, ac_vo, max_sp_len);
3202 ret2 = wpa_command(intf, buf);
3203
3204 if (ret1 && ret2) {
3205 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to set client mode "
3206 "UAPSD parameters.");
3207 return -2;
3208 }
3209
3210 if (ath6kl_client_uapsd(dut, intf, dut->client_uapsd) < 0) {
3211 send_resp(dut, conn, SIGMA_ERROR,
3212 "ErrorCode,Failed to set ath6kl QoS parameters");
3213 return 0;
3214 }
3215
3216 return 1;
3217}
3218
3219
Jouni Malinenf7222712019-06-13 01:50:21 +03003220static enum sigma_cmd_result cmd_sta_set_wmm(struct sigma_dut *dut,
3221 struct sigma_conn *conn,
3222 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003223{
3224 char buf[1000];
3225 const char *intf = get_param(cmd, "Interface");
3226 const char *grp = get_param(cmd, "Group");
3227 const char *act = get_param(cmd, "Action");
3228 const char *tid = get_param(cmd, "Tid");
3229 const char *dir = get_param(cmd, "Direction");
3230 const char *psb = get_param(cmd, "Psb");
3231 const char *up = get_param(cmd, "Up");
3232 const char *fixed = get_param(cmd, "Fixed");
3233 const char *size = get_param(cmd, "Size");
3234 const char *msize = get_param(cmd, "Maxsize");
3235 const char *minsi = get_param(cmd, "Min_srvc_intrvl");
3236 const char *maxsi = get_param(cmd, "Max_srvc_intrvl");
3237 const char *inact = get_param(cmd, "Inactivity");
3238 const char *sus = get_param(cmd, "Suspension");
3239 const char *mindr = get_param(cmd, "Mindatarate");
3240 const char *meandr = get_param(cmd, "Meandatarate");
3241 const char *peakdr = get_param(cmd, "Peakdatarate");
3242 const char *phyrate = get_param(cmd, "Phyrate");
3243 const char *burstsize = get_param(cmd, "Burstsize");
3244 const char *sba = get_param(cmd, "Sba");
3245 int direction;
3246 int handle;
Peng Xu93319622017-10-04 17:58:16 -07003247 float sba_fv = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003248 int fixed_int;
3249 int psb_ts;
3250
3251 if (intf == NULL || grp == NULL || act == NULL )
3252 return -1;
3253
3254 if (strcasecmp(act, "addts") == 0) {
3255 if (tid == NULL || dir == NULL || psb == NULL ||
3256 up == NULL || fixed == NULL || size == NULL)
3257 return -1;
3258
3259 /*
3260 * Note: Sigma CAPI spec lists uplink, downlink, and bidi as the
3261 * possible values, but WMM-AC and V-E test scripts use "UP,
3262 * "DOWN", and "BIDI".
3263 */
3264 if (strcasecmp(dir, "uplink") == 0 ||
3265 strcasecmp(dir, "up") == 0) {
3266 direction = 0;
3267 } else if (strcasecmp(dir, "downlink") == 0 ||
3268 strcasecmp(dir, "down") == 0) {
3269 direction = 1;
3270 } else if (strcasecmp(dir, "bidi") == 0) {
3271 direction = 2;
3272 } else {
3273 sigma_dut_print(dut, DUT_MSG_ERROR,
3274 "Direction %s not supported", dir);
3275 return -1;
3276 }
3277
3278 if (strcasecmp(psb, "legacy") == 0) {
3279 psb_ts = 0;
3280 } else if (strcasecmp(psb, "uapsd") == 0) {
3281 psb_ts = 1;
3282 } else {
3283 sigma_dut_print(dut, DUT_MSG_ERROR,
3284 "PSB %s not supported", psb);
3285 return -1;
3286 }
3287
3288 if (atoi(tid) < 0 || atoi(tid) > 7) {
3289 sigma_dut_print(dut, DUT_MSG_ERROR,
3290 "TID %s not supported", tid);
3291 return -1;
3292 }
3293
3294 if (strcasecmp(fixed, "true") == 0) {
3295 fixed_int = 1;
3296 } else {
3297 fixed_int = 0;
3298 }
3299
Peng Xu93319622017-10-04 17:58:16 -07003300 if (sba)
3301 sba_fv = atof(sba);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003302
3303 dut->dialog_token++;
3304 handle = 7000 + dut->dialog_token;
3305
3306 /*
3307 * size: convert to hex
3308 * maxsi: convert to hex
3309 * mindr: convert to hex
3310 * meandr: convert to hex
3311 * peakdr: convert to hex
3312 * burstsize: convert to hex
3313 * phyrate: convert to hex
3314 * sba: convert to hex with modification
3315 * minsi: convert to integer
3316 * sus: convert to integer
3317 * inact: convert to integer
3318 * maxsi: convert to integer
3319 */
3320
3321 /*
3322 * The Nominal MSDU Size field is 2 octets long and contains an
3323 * unsigned integer that specifies the nominal size, in octets,
3324 * of MSDUs belonging to the traffic under this traffic
3325 * specification and is defined in Figure 16. If the Fixed
3326 * subfield is set to 1, then the size of the MSDU is fixed and
3327 * is indicated by the Size Subfield. If the Fixed subfield is
3328 * set to 0, then the size of the MSDU might not be fixed and
3329 * the Size indicates the nominal MSDU size.
3330 *
3331 * The Surplus Bandwidth Allowance Factor field is 2 octets long
3332 * and specifies the excess allocation of time (and bandwidth)
3333 * over and above the stated rates required to transport an MSDU
3334 * belonging to the traffic in this TSPEC. This field is
3335 * represented as an unsigned binary number with an implicit
3336 * binary point after the leftmost 3 bits. For example, an SBA
3337 * of 1.75 is represented as 0x3800. This field is included to
3338 * account for retransmissions. As such, the value of this field
3339 * must be greater than unity.
3340 */
3341
3342 snprintf(buf, sizeof(buf),
3343 "iwpriv %s addTspec %d %s %d %d %s 0x%X"
3344 " 0x%X 0x%X 0x%X"
3345 " 0x%X 0x%X 0x%X"
3346 " 0x%X %d %d %d %d"
3347 " %d %d",
3348 intf, handle, tid, direction, psb_ts, up,
3349 (unsigned int) ((fixed_int << 15) | atoi(size)),
3350 msize ? atoi(msize) : 0,
3351 mindr ? atoi(mindr) : 0,
3352 meandr ? atoi(meandr) : 0,
3353 peakdr ? atoi(peakdr) : 0,
3354 burstsize ? atoi(burstsize) : 0,
3355 phyrate ? atoi(phyrate) : 0,
3356 sba ? ((unsigned int) (((int) sba_fv << 13) |
3357 (int)((sba_fv - (int) sba_fv) *
3358 8192))) : 0,
3359 minsi ? atoi(minsi) : 0,
3360 sus ? atoi(sus) : 0,
3361 0, 0,
3362 inact ? atoi(inact) : 0,
3363 maxsi ? atoi(maxsi) : 0);
3364
3365 if (system(buf) != 0) {
3366 sigma_dut_print(dut, DUT_MSG_ERROR,
3367 "iwpriv addtspec request failed");
3368 send_resp(dut, conn, SIGMA_ERROR,
3369 "errorCode,Failed to execute addTspec command");
3370 return 0;
3371 }
3372
3373 sigma_dut_print(dut, DUT_MSG_INFO,
3374 "iwpriv addtspec request send");
3375
3376 /* Mapping handle to a TID */
3377 dut->tid_to_handle[atoi(tid)] = handle;
3378 } else if (strcasecmp(act, "delts") == 0) {
3379 if (tid == NULL)
3380 return -1;
3381
3382 if (atoi(tid) < 0 || atoi(tid) > 7) {
3383 sigma_dut_print(dut, DUT_MSG_ERROR,
3384 "TID %s not supported", tid);
3385 send_resp(dut, conn, SIGMA_ERROR,
3386 "errorCode,Unsupported TID");
3387 return 0;
3388 }
3389
3390 handle = dut->tid_to_handle[atoi(tid)];
3391
3392 if (handle < 7000 || handle > 7255) {
3393 /* Invalid handle ie no mapping for that TID */
3394 sigma_dut_print(dut, DUT_MSG_ERROR,
3395 "handle-> %d not found", handle);
3396 }
3397
3398 snprintf(buf, sizeof(buf), "iwpriv %s delTspec %d",
3399 intf, handle);
3400
3401 if (system(buf) != 0) {
3402 sigma_dut_print(dut, DUT_MSG_ERROR,
3403 "iwpriv deltspec request failed");
3404 send_resp(dut, conn, SIGMA_ERROR,
3405 "errorCode,Failed to execute delTspec command");
3406 return 0;
3407 }
3408
3409 sigma_dut_print(dut, DUT_MSG_INFO,
3410 "iwpriv deltspec request send");
3411
3412 dut->tid_to_handle[atoi(tid)] = 0;
3413 } else {
3414 sigma_dut_print(dut, DUT_MSG_ERROR,
3415 "Action type %s not supported", act);
3416 send_resp(dut, conn, SIGMA_ERROR,
3417 "errorCode,Unsupported Action");
3418 return 0;
3419 }
3420
3421 return 1;
3422}
3423
3424
vamsi krishna52e16f92017-08-29 12:37:34 +05303425static int find_network(struct sigma_dut *dut, const char *ssid)
3426{
3427 char list[4096];
3428 char *pos;
3429
3430 sigma_dut_print(dut, DUT_MSG_DEBUG,
3431 "Search for profile based on SSID: '%s'", ssid);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003432 if (wpa_command_resp(get_station_ifname(dut), "LIST_NETWORKS",
vamsi krishna52e16f92017-08-29 12:37:34 +05303433 list, sizeof(list)) < 0)
3434 return -1;
3435 pos = strstr(list, ssid);
3436 if (!pos || pos == list || pos[-1] != '\t' || pos[strlen(ssid)] != '\t')
3437 return -1;
3438
3439 while (pos > list && pos[-1] != '\n')
3440 pos--;
3441 dut->infra_network_id = atoi(pos);
3442 snprintf(dut->infra_ssid, sizeof(dut->infra_ssid), "%s", ssid);
3443 return 0;
3444}
3445
3446
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05303447/**
3448 * enum qca_sta_helper_config_params - This helper enum defines the config
3449 * parameters which can be delivered to sta.
3450 */
3451enum qca_sta_helper_config_params {
3452 /* For the attribute QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE */
3453 STA_SET_RSNIE,
3454
3455 /* For the attribute QCA_WLAN_VENDOR_ATTR_CONFIG_LDPC */
3456 STA_SET_LDPC,
3457
3458 /* For the attribute QCA_WLAN_VENDOR_ATTR_CONFIG_TX_STBC */
3459 STA_SET_TX_STBC,
3460
3461 /* For the attribute QCA_WLAN_VENDOR_ATTR_CONFIG_RX_STBC */
3462 STA_SET_RX_STBC,
3463
3464 /* For the attribute QCA_WLAN_VENDOR_ATTR_CONFIG_TX_MSDU_AGGREGATION */
3465 STA_SET_TX_MSDU,
3466
3467 /* For the attribute QCA_WLAN_VENDOR_ATTR_CONFIG_RX_MSDU_AGGREGATION */
3468 STA_SET_RX_MSDU,
Shivani Baranwal2a572842021-09-16 12:27:15 +05303469
3470 /* For the attribute QCA_WLAN_VENDOR_ATTR_CONFIG_CHANNEL_WIDTH */
3471 STA_SET_CHAN_WIDTH,
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05303472};
3473
3474
3475static int sta_config_params(struct sigma_dut *dut, const char *intf,
3476 enum qca_sta_helper_config_params config_cmd,
3477 int value)
Sunil Dutt44595082018-02-12 19:41:45 +05303478{
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05303479#ifdef NL80211_SUPPORT
Sunil Dutt44595082018-02-12 19:41:45 +05303480 struct nl_msg *msg;
3481 int ret;
3482 struct nlattr *params;
3483 int ifindex;
3484
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05303485 ifindex = if_nametoindex(intf);
3486 if (ifindex == 0) {
3487 sigma_dut_print(dut, DUT_MSG_ERROR,
3488 "%s: Interface %s does not exist",
3489 __func__, intf);
3490 return -1;
3491 }
3492
Sunil Dutt44595082018-02-12 19:41:45 +05303493 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
3494 NL80211_CMD_VENDOR)) ||
3495 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
3496 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
3497 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
3498 QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION) ||
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05303499 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)))
3500 goto fail;
3501
3502 switch (config_cmd) {
3503 case STA_SET_RSNIE:
3504 if (nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE, value))
3505 goto fail;
3506 break;
3507 case STA_SET_LDPC:
3508 if (nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_LDPC, value))
3509 goto fail;
3510 break;
3511 case STA_SET_TX_STBC:
3512 if (nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TX_STBC, value))
3513 goto fail;
3514 break;
3515 case STA_SET_RX_STBC:
3516 if (nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_RX_STBC, value))
3517 goto fail;
3518 break;
3519 case STA_SET_TX_MSDU:
3520 if (nla_put_u8(msg,
3521 QCA_WLAN_VENDOR_ATTR_CONFIG_TX_MSDU_AGGREGATION,
3522 value))
3523 goto fail;
3524 break;
3525 case STA_SET_RX_MSDU:
3526 if (nla_put_u8(msg,
3527 QCA_WLAN_VENDOR_ATTR_CONFIG_RX_MSDU_AGGREGATION,
3528 value))
3529 goto fail;
3530 break;
Shivani Baranwal2a572842021-09-16 12:27:15 +05303531 case STA_SET_CHAN_WIDTH:
3532 if (nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_CHANNEL_WIDTH,
3533 value))
3534 goto fail;
3535 break;
Sunil Dutt44595082018-02-12 19:41:45 +05303536 }
3537 nla_nest_end(msg, params);
3538
3539 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
3540 if (ret) {
3541 sigma_dut_print(dut, DUT_MSG_ERROR,
3542 "%s: err in send_and_recv_msgs, ret=%d",
3543 __func__, ret);
3544 return ret;
3545 }
3546
3547 return 0;
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05303548
3549fail:
3550 sigma_dut_print(dut, DUT_MSG_ERROR,
3551 "%s: err in adding vendor_cmd and vendor_data",
3552 __func__);
3553 nlmsg_free(msg);
Sunil Dutt44595082018-02-12 19:41:45 +05303554#endif /* NL80211_SUPPORT */
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05303555 return -1;
3556}
Sunil Dutt44595082018-02-12 19:41:45 +05303557
3558
Jouni Malinenf7222712019-06-13 01:50:21 +03003559static enum sigma_cmd_result cmd_sta_associate(struct sigma_dut *dut,
3560 struct sigma_conn *conn,
3561 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003562{
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05303563#ifdef NL80211_SUPPORT
3564 const char *intf = get_param(cmd, "Interface");
3565#endif /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003566 const char *ssid = get_param(cmd, "ssid");
3567 const char *wps_param = get_param(cmd, "WPS");
3568 const char *bssid = get_param(cmd, "bssid");
Jouni Malinen46a19b62017-06-23 14:31:27 +03003569 const char *chan = get_param(cmd, "channel");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02003570 const char *network_mode = get_param(cmd, "network_mode");
Veerendranath Jakkama082e342020-05-16 00:19:21 +05303571 const char *ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003572 int wps = 0;
Jouni Malinen3c367e82017-06-23 17:01:47 +03003573 char buf[1000], extra[50];
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003574 int e;
3575 enum sigma_cmd_result ret = SUCCESS_SEND_STATUS;
3576 struct wpa_ctrl *ctrl = NULL;
3577 int num_network_not_found = 0;
3578 int num_disconnected = 0;
3579 int tod = -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003580
3581 if (ssid == NULL)
3582 return -1;
3583
Jouni Malinen37d5c692019-08-19 16:56:55 +03003584 dut->server_cert_tod = 0;
3585
Jouni Malinen3c367e82017-06-23 17:01:47 +03003586 if (dut->rsne_override) {
Sunil Dutt44595082018-02-12 19:41:45 +05303587#ifdef NL80211_SUPPORT
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003588 if (get_driver_type(dut) == DRIVER_WCN) {
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05303589 sta_config_params(dut, intf, STA_SET_RSNIE, 1);
Sunil Dutt44595082018-02-12 19:41:45 +05303590 dut->config_rsnie = 1;
3591 }
3592#endif /* NL80211_SUPPORT */
Jouni Malinen3c367e82017-06-23 17:01:47 +03003593 snprintf(buf, sizeof(buf), "TEST_ASSOC_IE %s",
3594 dut->rsne_override);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003595 if (wpa_command(get_station_ifname(dut), buf) < 0) {
Jouni Malinen3c367e82017-06-23 17:01:47 +03003596 send_resp(dut, conn, SIGMA_ERROR,
3597 "ErrorCode,Failed to set DEV_CONFIGURE_IE RSNE override");
3598 return 0;
3599 }
3600 }
3601
Jouni Malinen68143132017-09-02 02:34:08 +03003602 if (dut->sae_commit_override) {
3603 snprintf(buf, sizeof(buf), "SET sae_commit_override %s",
3604 dut->sae_commit_override);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003605 if (wpa_command(get_station_ifname(dut), buf) < 0) {
Jouni Malinen68143132017-09-02 02:34:08 +03003606 send_resp(dut, conn, SIGMA_ERROR,
3607 "ErrorCode,Failed to set SAE commit override");
3608 return 0;
3609 }
3610 }
Ankita Bajaj1bde7942018-01-09 19:15:01 +05303611#ifdef ANDROID
3612 if (dut->fils_hlp)
3613 process_fils_hlp(dut);
3614#endif /* ANDROID */
Jouni Malinen68143132017-09-02 02:34:08 +03003615
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003616 if (wps_param &&
3617 (strcmp(wps_param, "1") == 0 || strcasecmp(wps_param, "On") == 0))
3618 wps = 1;
3619
3620 if (wps) {
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02003621 if (dut->program == PROGRAM_60GHZ && network_mode &&
3622 strcasecmp(network_mode, "PBSS") == 0 &&
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003623 set_network(get_station_ifname(dut), dut->infra_network_id,
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02003624 "pbss", "1") < 0)
3625 return -2;
3626
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003627 if (dut->wps_method == WFA_CS_WPS_NOT_READY) {
3628 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,WPS "
3629 "parameters not yet set");
3630 return 0;
3631 }
3632 if (dut->wps_method == WFA_CS_WPS_PBC) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003633 if (wpa_command(get_station_ifname(dut), "WPS_PBC") < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003634 return -2;
3635 } else {
3636 snprintf(buf, sizeof(buf), "WPS_PIN any %s",
3637 dut->wps_pin);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003638 if (wpa_command(get_station_ifname(dut), buf) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003639 return -2;
3640 }
3641 } else {
vamsi krishna52e16f92017-08-29 12:37:34 +05303642 if (strcmp(ssid, dut->infra_ssid) == 0) {
3643 sigma_dut_print(dut, DUT_MSG_DEBUG,
3644 "sta_associate for the most recently added network");
3645 } else if (find_network(dut, ssid) < 0) {
3646 sigma_dut_print(dut, DUT_MSG_DEBUG,
3647 "sta_associate for a previously stored network profile");
3648 send_resp(dut, conn, SIGMA_ERROR,
3649 "ErrorCode,Profile not found");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003650 return 0;
3651 }
3652
3653 if (bssid &&
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003654 set_network(get_station_ifname(dut), dut->infra_network_id,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003655 "bssid", bssid) < 0) {
3656 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
3657 "Invalid bssid argument");
3658 return 0;
3659 }
3660
Veerendranath Jakkama082e342020-05-16 00:19:21 +05303661 if ((dut->program == PROGRAM_WPA3 &&
3662 dut->sta_associate_wait_connect) ||
3663 dut->program == PROGRAM_QM) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003664 ctrl = open_wpa_mon(get_station_ifname(dut));
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003665 if (!ctrl)
3666 return ERROR_SEND_STATUS;
3667 }
3668
Jouni Malinen46a19b62017-06-23 14:31:27 +03003669 extra[0] = '\0';
3670 if (chan)
3671 snprintf(extra, sizeof(extra), " freq=%u",
Alexei Avshalom Lazar093569f2018-11-13 14:08:17 +02003672 channel_to_freq(dut, atoi(chan)));
Jouni Malinen46a19b62017-06-23 14:31:27 +03003673 snprintf(buf, sizeof(buf), "SELECT_NETWORK %d%s",
3674 dut->infra_network_id, extra);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003675 if (wpa_command(get_station_ifname(dut), buf) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003676 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to select "
3677 "network id %d on %s",
3678 dut->infra_network_id,
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003679 get_station_ifname(dut));
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003680 ret = ERROR_SEND_STATUS;
3681 goto done;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003682 }
3683 }
3684
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003685 if (!ctrl)
3686 return SUCCESS_SEND_STATUS;
3687
3688 /* Wait for connection result to be able to store server certificate
3689 * hash for trust root override testing
3690 * (dev_exec_action,ServerCertTrust). */
3691
3692 for (e = 0; e < 20; e++) {
3693 const char *events[] = {
3694 "CTRL-EVENT-EAP-PEER-CERT",
3695 "CTRL-EVENT-EAP-TLS-CERT-ERROR",
3696 "CTRL-EVENT-DISCONNECTED",
3697 "CTRL-EVENT-CONNECTED",
3698 "CTRL-EVENT-NETWORK-NOT-FOUND",
3699 NULL
3700 };
3701 char buf[1024];
3702 int res;
3703
3704 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
3705 if (res < 0) {
Jouni Malinenf1f16642019-11-15 21:19:04 +02003706 send_resp(dut, conn, SIGMA_COMPLETE,
3707 "Result,Association did not complete");
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003708 ret = STATUS_SENT_ERROR;
3709 break;
3710 }
3711 sigma_dut_print(dut, DUT_MSG_DEBUG, "Connection event: %s",
3712 buf);
3713
3714 if (strstr(buf, "CTRL-EVENT-EAP-PEER-CERT") &&
3715 strstr(buf, " depth=0")) {
3716 char *pos = strstr(buf, " hash=");
3717
3718 if (pos) {
3719 char *end;
3720
Jouni Malinen34b19cb2019-08-16 16:37:17 +03003721 if (strstr(buf, " tod=1"))
3722 tod = 1;
3723 else if (strstr(buf, " tod=2"))
3724 tod = 2;
3725 else
3726 tod = 0;
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003727 sigma_dut_print(dut, DUT_MSG_DEBUG,
3728 "Server certificate TOD policy: %d",
3729 tod);
Jouni Malinen37d5c692019-08-19 16:56:55 +03003730 dut->server_cert_tod = tod;
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003731
3732 pos += 6;
3733 end = strchr(pos, ' ');
3734 if (end)
3735 *end = '\0';
3736 strlcpy(dut->server_cert_hash, pos,
3737 sizeof(dut->server_cert_hash));
3738 sigma_dut_print(dut, DUT_MSG_DEBUG,
3739 "Server certificate hash: %s",
3740 dut->server_cert_hash);
3741 }
3742 }
3743
3744 if (strstr(buf, "CTRL-EVENT-EAP-TLS-CERT-ERROR")) {
3745 send_resp(dut, conn, SIGMA_COMPLETE,
3746 "Result,TLS server certificate validation failed");
3747 ret = STATUS_SENT_ERROR;
3748 break;
3749 }
3750
3751 if (strstr(buf, "CTRL-EVENT-NETWORK-NOT-FOUND")) {
3752 num_network_not_found++;
3753
3754 if (num_network_not_found > 2) {
3755 send_resp(dut, conn, SIGMA_COMPLETE,
3756 "Result,Network not found");
3757 ret = STATUS_SENT_ERROR;
3758 break;
3759 }
3760 }
3761
3762 if (strstr(buf, "CTRL-EVENT-DISCONNECTED")) {
3763 num_disconnected++;
3764
3765 if (num_disconnected > 2) {
3766 send_resp(dut, conn, SIGMA_COMPLETE,
3767 "Result,Connection failed");
3768 ret = STATUS_SENT_ERROR;
3769 break;
3770 }
3771 }
3772
3773 if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
3774 if (tod >= 0) {
3775 sigma_dut_print(dut, DUT_MSG_DEBUG,
3776 "Network profile TOD policy update: %d -> %d",
3777 dut->sta_tod_policy, tod);
3778 dut->sta_tod_policy = tod;
3779 }
Veerendranath Jakkama082e342020-05-16 00:19:21 +05303780 if (dut->program == PROGRAM_QM) {
3781 unsigned char iface_mac_addr[ETH_ALEN];
3782 char ipv6[100];
3783
3784 if (get_hwaddr(ifname, iface_mac_addr) < 0) {
3785 sigma_dut_print(dut, DUT_MSG_ERROR,
3786 "%s: get_hwaddr %s failed",
3787 __func__, ifname);
3788 ret = ERROR_SEND_STATUS;
3789 break;
3790 }
3791
3792 convert_mac_addr_to_ipv6_lladdr(iface_mac_addr,
3793 ipv6,
3794 sizeof(ipv6));
3795
3796 if (set_ipv6_addr(dut, ipv6, "64", ifname) !=
3797 0) {
3798 ret = ERROR_SEND_STATUS;
3799 break;
3800 }
3801 }
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003802 break;
3803 }
3804 }
3805done:
3806 if (ctrl) {
3807 wpa_ctrl_detach(ctrl);
3808 wpa_ctrl_close(ctrl);
3809 }
3810 return ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003811}
3812
3813
3814static int run_hs20_osu(struct sigma_dut *dut, const char *params)
3815{
3816 char buf[500], cmd[200];
3817 int res;
3818
3819 /* Use hs20-osu-client file at the current dir, if found; otherwise use
3820 * default path */
3821 res = snprintf(cmd, sizeof(cmd),
3822 "%s -w \"%s\" -r hs20-osu-client.res %s%s -dddKt -f Logs/hs20-osu-client.txt",
3823 file_exists("./hs20-osu-client") ?
3824 "./hs20-osu-client" : "hs20-osu-client",
3825 sigma_wpas_ctrl,
3826 dut->summary_log ? "-s " : "",
3827 dut->summary_log ? dut->summary_log : "");
3828 if (res < 0 || res >= (int) sizeof(cmd))
3829 return -1;
3830
3831 res = snprintf(buf, sizeof(buf), "%s %s", cmd, params);
3832 if (res < 0 || res >= (int) sizeof(buf))
3833 return -1;
3834 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
3835
3836 if (system(buf) != 0) {
3837 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to run: %s", buf);
3838 return -1;
3839 }
3840 sigma_dut_print(dut, DUT_MSG_DEBUG,
3841 "Completed hs20-osu-client operation");
3842
3843 return 0;
3844}
3845
3846
3847static int download_ppsmo(struct sigma_dut *dut,
3848 struct sigma_conn *conn,
3849 const char *intf,
3850 struct sigma_cmd *cmd)
3851{
3852 const char *name, *path, *val;
3853 char url[500], buf[600], fbuf[100];
3854 char *fqdn = NULL;
3855
3856 name = get_param(cmd, "FileName");
3857 path = get_param(cmd, "FilePath");
3858 if (name == NULL || path == NULL)
3859 return -1;
3860
3861 if (strcasecmp(path, "VendorSpecific") == 0) {
3862 snprintf(url, sizeof(url), "PPS/%s", name);
3863 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured PPS MO "
3864 "from the device (%s)", url);
3865 if (!file_exists(url)) {
3866 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
3867 "PPS MO file does not exist");
3868 return 0;
3869 }
3870 snprintf(buf, sizeof(buf), "cp %s pps-tnds.xml", url);
3871 if (system(buf) != 0) {
3872 send_resp(dut, conn, SIGMA_ERROR,
3873 "errorCode,Failed to copy PPS MO");
3874 return 0;
3875 }
3876 } else if (strncasecmp(path, "http:", 5) != 0 &&
3877 strncasecmp(path, "https:", 6) != 0) {
3878 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
3879 "Unsupported FilePath value");
3880 return 0;
3881 } else {
3882 snprintf(url, sizeof(url), "%s/%s", path, name);
3883 sigma_dut_print(dut, DUT_MSG_INFO, "Downloading PPS MO from %s",
3884 url);
3885 snprintf(buf, sizeof(buf), "wget -T 10 -t 3 -O pps-tnds.xml '%s'", url);
3886 remove("pps-tnds.xml");
3887 if (system(buf) != 0) {
3888 send_resp(dut, conn, SIGMA_ERROR,
3889 "errorCode,Failed to download PPS MO");
3890 return 0;
3891 }
3892 }
3893
3894 if (run_hs20_osu(dut, "from_tnds pps-tnds.xml pps.xml") < 0) {
3895 send_resp(dut, conn, SIGMA_ERROR,
3896 "errorCode,Failed to parse downloaded PPSMO");
3897 return 0;
3898 }
3899 unlink("pps-tnds.xml");
3900
3901 val = get_param(cmd, "managementTreeURI");
3902 if (val) {
3903 const char *pos, *end;
3904 sigma_dut_print(dut, DUT_MSG_DEBUG, "managementTreeURI: %s",
3905 val);
3906 if (strncmp(val, "./Wi-Fi/", 8) != 0) {
3907 send_resp(dut, conn, SIGMA_ERROR,
3908 "errorCode,Invalid managementTreeURI prefix");
3909 return 0;
3910 }
3911 pos = val + 8;
3912 end = strchr(pos, '/');
3913 if (end == NULL ||
3914 strcmp(end, "/PerProviderSubscription") != 0) {
3915 send_resp(dut, conn, SIGMA_ERROR,
3916 "errorCode,Invalid managementTreeURI postfix");
3917 return 0;
3918 }
3919 if (end - pos >= (int) sizeof(fbuf)) {
3920 send_resp(dut, conn, SIGMA_ERROR,
3921 "errorCode,Too long FQDN in managementTreeURI");
3922 return 0;
3923 }
3924 memcpy(fbuf, pos, end - pos);
3925 fbuf[end - pos] = '\0';
3926 fqdn = fbuf;
3927 sigma_dut_print(dut, DUT_MSG_INFO,
3928 "FQDN from managementTreeURI: %s", fqdn);
3929 } else if (run_hs20_osu(dut, "get_fqdn pps.xml") == 0) {
3930 FILE *f = fopen("pps-fqdn", "r");
3931 if (f) {
3932 if (fgets(fbuf, sizeof(fbuf), f)) {
3933 fbuf[sizeof(fbuf) - 1] = '\0';
3934 fqdn = fbuf;
3935 sigma_dut_print(dut, DUT_MSG_DEBUG,
3936 "Use FQDN %s", fqdn);
3937 }
3938 fclose(f);
3939 }
3940 }
3941
3942 if (fqdn == NULL) {
3943 send_resp(dut, conn, SIGMA_ERROR,
3944 "errorCode,No FQDN specified");
3945 return 0;
3946 }
3947
3948 mkdir("SP", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
3949 snprintf(buf, sizeof(buf), "SP/%s", fqdn);
3950 mkdir(buf, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
3951
3952 snprintf(buf, sizeof(buf), "SP/%s/pps.xml", fqdn);
3953 if (rename("pps.xml", buf) < 0) {
3954 send_resp(dut, conn, SIGMA_ERROR,
3955 "errorCode,Could not move PPS MO");
3956 return 0;
3957 }
3958
3959 if (strcasecmp(path, "VendorSpecific") == 0) {
3960 snprintf(buf, sizeof(buf), "cp Certs/ca.pem SP/%s/ca.pem",
3961 fqdn);
3962 if (system(buf)) {
3963 send_resp(dut, conn, SIGMA_ERROR,
3964 "errorCode,Failed to copy OSU CA cert");
3965 return 0;
3966 }
3967
3968 snprintf(buf, sizeof(buf),
3969 "cp Certs/aaa-ca.pem SP/%s/aaa-ca.pem",
3970 fqdn);
3971 if (system(buf)) {
3972 send_resp(dut, conn, SIGMA_ERROR,
3973 "errorCode,Failed to copy AAA CA cert");
3974 return 0;
3975 }
3976 } else {
3977 snprintf(buf, sizeof(buf),
3978 "dl_osu_ca SP/%s/pps.xml SP/%s/ca.pem",
3979 fqdn, fqdn);
3980 if (run_hs20_osu(dut, buf) < 0) {
3981 send_resp(dut, conn, SIGMA_ERROR,
3982 "errorCode,Failed to download OSU CA cert");
3983 return 0;
3984 }
3985
3986 snprintf(buf, sizeof(buf),
3987 "dl_aaa_ca SP/%s/pps.xml SP/%s/aaa-ca.pem",
3988 fqdn, fqdn);
3989 if (run_hs20_osu(dut, buf) < 0) {
3990 sigma_dut_print(dut, DUT_MSG_INFO,
3991 "Failed to download AAA CA cert");
3992 }
3993 }
3994
3995 if (file_exists("next-client-cert.pem")) {
3996 snprintf(buf, sizeof(buf), "SP/%s/client-cert.pem", fqdn);
3997 if (rename("next-client-cert.pem", buf) < 0) {
3998 send_resp(dut, conn, SIGMA_ERROR,
3999 "errorCode,Could not move client certificate");
4000 return 0;
4001 }
4002 }
4003
4004 if (file_exists("next-client-key.pem")) {
4005 snprintf(buf, sizeof(buf), "SP/%s/client-key.pem", fqdn);
4006 if (rename("next-client-key.pem", buf) < 0) {
4007 send_resp(dut, conn, SIGMA_ERROR,
4008 "errorCode,Could not move client key");
4009 return 0;
4010 }
4011 }
4012
4013 snprintf(buf, sizeof(buf), "set_pps SP/%s/pps.xml", fqdn);
4014 if (run_hs20_osu(dut, buf) < 0) {
4015 send_resp(dut, conn, SIGMA_ERROR,
4016 "errorCode,Failed to configure credential from "
4017 "PPSMO");
4018 return 0;
4019 }
4020
4021 return 1;
4022}
4023
4024
4025static int download_cert(struct sigma_dut *dut,
4026 struct sigma_conn *conn,
4027 const char *intf,
4028 struct sigma_cmd *cmd)
4029{
4030 const char *name, *path;
4031 char url[500], buf[600];
4032
4033 name = get_param(cmd, "FileName");
4034 path = get_param(cmd, "FilePath");
4035 if (name == NULL || path == NULL)
4036 return -1;
4037
4038 if (strcasecmp(path, "VendorSpecific") == 0) {
4039 snprintf(url, sizeof(url), "Certs/%s-cert.pem", name);
4040 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured client "
4041 "certificate from the device (%s)", url);
4042 if (!file_exists(url)) {
4043 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
4044 "certificate file does not exist");
4045 return 0;
4046 }
4047 snprintf(buf, sizeof(buf), "cp %s next-client-cert.pem", url);
4048 if (system(buf) != 0) {
4049 send_resp(dut, conn, SIGMA_ERROR,
4050 "errorCode,Failed to copy client "
4051 "certificate");
4052 return 0;
4053 }
4054
4055 snprintf(url, sizeof(url), "Certs/%s-key.pem", name);
4056 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured client "
4057 "private key from the device (%s)", url);
4058 if (!file_exists(url)) {
4059 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
4060 "private key file does not exist");
4061 return 0;
4062 }
4063 snprintf(buf, sizeof(buf), "cp %s next-client-key.pem", url);
4064 if (system(buf) != 0) {
4065 send_resp(dut, conn, SIGMA_ERROR,
4066 "errorCode,Failed to copy client key");
4067 return 0;
4068 }
4069 } else if (strncasecmp(path, "http:", 5) != 0 &&
4070 strncasecmp(path, "https:", 6) != 0) {
4071 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
4072 "Unsupported FilePath value");
4073 return 0;
4074 } else {
4075 snprintf(url, sizeof(url), "%s/%s.pem", path, name);
4076 sigma_dut_print(dut, DUT_MSG_INFO, "Downloading client "
4077 "certificate/key from %s", url);
4078 snprintf(buf, sizeof(buf),
4079 "wget -T 10 -t 3 -O next-client-cert.pem '%s'", url);
4080 if (system(buf) != 0) {
4081 send_resp(dut, conn, SIGMA_ERROR,
4082 "errorCode,Failed to download client "
4083 "certificate");
4084 return 0;
4085 }
4086
4087 if (system("cp next-client-cert.pem next-client-key.pem") != 0)
4088 {
4089 send_resp(dut, conn, SIGMA_ERROR,
4090 "errorCode,Failed to copy client key");
4091 return 0;
4092 }
4093 }
4094
4095 return 1;
4096}
4097
4098
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02004099static int cmd_sta_preset_testparameters_60ghz(struct sigma_dut *dut,
4100 struct sigma_conn *conn,
4101 struct sigma_cmd *cmd)
4102{
4103 const char *val;
4104 const char *intf = get_param(cmd, "interface");
4105
4106 if (!intf)
4107 return -1;
4108
4109 val = get_param(cmd, "WscIEFragment");
4110 if (val && strcasecmp(val, "enable") == 0) {
4111 sigma_dut_print(dut, DUT_MSG_DEBUG,
4112 "Enable WSC IE fragmentation");
4113
4114 dut->wsc_fragment = 1;
4115 /* set long attributes to force fragmentation */
4116 if (wpa_command(intf, "SET device_name "
4117 WPS_LONG_DEVICE_NAME) < 0)
4118 return -2;
4119 if (wpa_command(intf, "SET manufacturer "
4120 WPS_LONG_MANUFACTURER) < 0)
4121 return -2;
4122 if (wpa_command(intf, "SET model_name "
4123 WPS_LONG_MODEL_NAME) < 0)
4124 return -2;
4125 if (wpa_command(intf, "SET model_number "
4126 WPS_LONG_MODEL_NUMBER) < 0)
4127 return -2;
4128 if (wpa_command(intf, "SET serial_number "
4129 WPS_LONG_SERIAL_NUMBER) < 0)
4130 return -2;
4131 }
4132
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02004133 val = get_param(cmd, "RSN_IE");
4134 if (val) {
4135 if (strcasecmp(val, "disable") == 0)
4136 dut->force_rsn_ie = FORCE_RSN_IE_REMOVE;
4137 else if (strcasecmp(val, "enable") == 0)
4138 dut->force_rsn_ie = FORCE_RSN_IE_ADD;
4139 }
4140
Alexei Avshalom Lazar744ae8a2019-01-31 17:26:46 +02004141 val = get_param(cmd, "WpsVersion");
4142 if (val)
4143 dut->wps_forced_version = get_wps_forced_version(dut, val);
4144
Alexei Avshalom Lazar2eccf4d2019-01-31 10:03:59 +02004145 val = get_param(cmd, "WscEAPFragment");
4146 if (val && strcasecmp(val, "enable") == 0)
4147 dut->eap_fragment = 1;
4148
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02004149 return 1;
4150}
4151
4152
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004153static int cmd_sta_preset_testparameters_hs2_r2(struct sigma_dut *dut,
4154 struct sigma_conn *conn,
4155 const char *intf,
4156 struct sigma_cmd *cmd)
4157{
4158 const char *val;
4159
4160 val = get_param(cmd, "FileType");
4161 if (val && strcasecmp(val, "PPSMO") == 0)
4162 return download_ppsmo(dut, conn, intf, cmd);
4163 if (val && strcasecmp(val, "CERT") == 0)
4164 return download_cert(dut, conn, intf, cmd);
4165 if (val) {
4166 send_resp(dut, conn, SIGMA_ERROR,
4167 "ErrorCode,Unsupported FileType");
4168 return 0;
4169 }
4170
4171 return 1;
4172}
4173
4174
Ankita Bajaja2cb5672017-10-25 16:08:28 +05304175static int cmd_sta_preset_testparameters_oce(struct sigma_dut *dut,
4176 struct sigma_conn *conn,
4177 const char *intf,
4178 struct sigma_cmd *cmd)
4179{
4180 const char *val;
Ankita Bajaj1bde7942018-01-09 19:15:01 +05304181 char buf[1000];
4182 char text[20];
4183 unsigned char addr[ETH_ALEN];
Ankita Bajaja2cb5672017-10-25 16:08:28 +05304184
4185 val = get_param(cmd, "OCESupport");
4186 if (val && strcasecmp(val, "Disable") == 0) {
4187 if (wpa_command(intf, "SET oce 0") < 0) {
4188 send_resp(dut, conn, SIGMA_ERROR,
4189 "ErrorCode,Failed to disable OCE");
4190 return 0;
4191 }
4192 } else if (val && strcasecmp(val, "Enable") == 0) {
4193 if (wpa_command(intf, "SET oce 1") < 0) {
4194 send_resp(dut, conn, SIGMA_ERROR,
4195 "ErrorCode,Failed to enable OCE");
4196 return 0;
4197 }
4198 }
4199
vamsi krishnaa2799492017-12-05 14:28:01 +05304200 val = get_param(cmd, "FILScap");
4201 if (val && (atoi(val) == 1)) {
4202 if (wpa_command(intf, "SET disable_fils 0") < 0) {
4203 send_resp(dut, conn, SIGMA_ERROR,
4204 "ErrorCode,Failed to enable FILS");
4205 return 0;
4206 }
4207 } else if (val && (atoi(val) == 0)) {
4208 if (wpa_command(intf, "SET disable_fils 1") < 0) {
4209 send_resp(dut, conn, SIGMA_ERROR,
4210 "ErrorCode,Failed to disable FILS");
4211 return 0;
4212 }
4213 }
4214
Ankita Bajaj1bde7942018-01-09 19:15:01 +05304215 val = get_param(cmd, "FILSHLP");
4216 if (val && strcasecmp(val, "Enable") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004217 if (get_wpa_status(get_station_ifname(dut), "address", text,
Ankita Bajaj1bde7942018-01-09 19:15:01 +05304218 sizeof(text)) < 0)
4219 return -2;
4220 hwaddr_aton(text, addr);
4221 snprintf(buf, sizeof(buf),
4222 "FILS_HLP_REQ_ADD ff:ff:ff:ff:ff:ff "
4223 "080045100140000040004011399e00000000ffffffff00440043"
4224 "012cb30001010600fd4f46410000000000000000000000000000"
4225 "000000000000"
4226 "%02x%02x%02x%02x%02x%02x"
4227 "0000000000000000000000000000000000000000000000000000"
4228 "0000000000000000000000000000000000000000000000000000"
4229 "0000000000000000000000000000000000000000000000000000"
4230 "0000000000000000000000000000000000000000000000000000"
4231 "0000000000000000000000000000000000000000000000000000"
4232 "0000000000000000000000000000000000000000000000000000"
4233 "0000000000000000000000000000000000000000000000000000"
4234 "0000000000000000000000000000000000000000638253633501"
4235 "013d0701000af549d29b390205dc3c12616e64726f69642d6468"
4236 "63702d382e302e30370a0103060f1a1c333a3b2b5000ff00",
4237 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
4238 if (wpa_command(intf, buf)) {
4239 send_resp(dut, conn, SIGMA_ERROR,
4240 "ErrorCode,Failed to add HLP");
4241 return 0;
4242 }
4243 dut->fils_hlp = 1;
4244 }
4245
Ankita Bajaja2cb5672017-10-25 16:08:28 +05304246 return 1;
4247}
4248
4249
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004250static void ath_sta_set_noack(struct sigma_dut *dut, const char *intf,
4251 const char *val)
4252{
4253 int counter = 0;
4254 char token[50];
4255 char *result;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05304256 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004257
Peng Xub8fc5cc2017-05-10 17:27:28 -07004258 strlcpy(token, val, sizeof(token));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004259 token[sizeof(token) - 1] = '\0';
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05304260 result = strtok_r(token, ":", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004261 while (result) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004262 if (strcmp(result, "disable") == 0)
4263 run_iwpriv(dut, intf, "noackpolicy %d 1 0", counter);
4264 else
4265 run_iwpriv(dut, intf, "noackpolicy %d 1 1", counter);
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05304266 result = strtok_r(NULL, ":", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004267 counter++;
4268 }
4269}
4270
4271
4272static void ath_sta_set_rts(struct sigma_dut *dut, const char *intf,
4273 const char *val)
4274{
4275 char buf[100];
4276
4277 snprintf(buf, sizeof(buf), "iwconfig %s rts %s", intf, val);
4278 if (system(buf) != 0) {
4279 sigma_dut_print(dut, DUT_MSG_ERROR, "iwconfig RTS failed");
4280 }
4281}
4282
4283
4284static void ath_sta_set_wmm(struct sigma_dut *dut, const char *intf,
4285 const char *val)
4286{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004287 if (strcasecmp(val, "off") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004288 run_iwpriv(dut, intf, "wmm 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004289 }
4290}
4291
4292
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08004293static int wcn_sta_set_wmm(struct sigma_dut *dut, const char *intf,
4294 const char *val)
4295{
4296#ifdef NL80211_SUPPORT
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08004297 int wmmenable = 1;
4298
4299 if (val &&
4300 (strcasecmp(val, "off") == 0 || strcmp(val, "0") == 0))
4301 wmmenable = 0;
4302
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05304303 return wcn_wifi_test_config_set_u8(
4304 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WMM_ENABLE,
4305 wmmenable);
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08004306#else /* NL80211_SUPPORT */
4307 sigma_dut_print(dut, DUT_MSG_ERROR,
4308 "WMM cannot be changed without NL80211_SUPPORT defined");
4309 return -1;
4310#endif /* NL80211_SUPPORT */
4311}
4312
4313
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004314static void ath_sta_set_sgi(struct sigma_dut *dut, const char *intf,
4315 const char *val)
4316{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004317 int sgi20;
4318
4319 sgi20 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
4320
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004321 run_iwpriv(dut, intf, "shortgi %d", sgi20);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004322}
4323
4324
4325static void ath_sta_set_11nrates(struct sigma_dut *dut, const char *intf,
4326 const char *val)
4327{
Pradeep Reddy POTTETI67376b72016-10-25 20:08:17 +05304328 int rate_code, v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004329
4330 /* Disable Tx Beam forming when using a fixed rate */
4331 ath_disable_txbf(dut, intf);
4332
Pradeep Reddy POTTETI67376b72016-10-25 20:08:17 +05304333 v = atoi(val);
4334 if (v < 0 || v > 32) {
4335 sigma_dut_print(dut, DUT_MSG_ERROR,
4336 "Invalid Fixed MCS rate: %d", v);
4337 return;
4338 }
4339 rate_code = 0x80 + v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004340
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004341 run_iwpriv(dut, intf, "set11NRates 0x%x", rate_code);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004342
4343 /* Channel width gets messed up, fix this */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004344 run_iwpriv(dut, intf, "chwidth %d", dut->chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004345}
4346
4347
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08004348static void iwpriv_sta_set_amsdu(struct sigma_dut *dut, const char *intf,
4349 const char *val)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004350{
4351 char buf[60];
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05304352 int ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004353
4354 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)
4355 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 2", intf);
4356 else
4357 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 1", intf);
4358
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05304359 ret = system(buf);
4360#ifdef NL80211_SUPPORT
4361 if (ret) {
4362 int value = (strcasecmp(val, "Enable") == 0) ? 2 : 1;
4363
4364 ret = sta_config_params(dut, intf, STA_SET_TX_MSDU, value);
4365 ret |= sta_config_params(dut, intf, STA_SET_RX_MSDU, value);
4366 }
4367#endif /* NL80211_SUPPORT */
4368 if (ret)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004369 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv amsdu failed");
4370}
4371
4372
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07004373static int iwpriv_sta_set_ampdu(struct sigma_dut *dut, const char *intf,
4374 int ampdu)
4375{
4376 char buf[60];
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08004377 int maxaggregation = 63;
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07004378
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08004379 if (ampdu)
4380 ampdu = maxaggregation;
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07004381 snprintf(buf, sizeof(buf), "iwpriv %s ampdu %d", intf, ampdu);
4382 if (system(buf) != 0) {
4383 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv ampdu failed");
4384 return -1;
4385 }
4386
4387 return 0;
4388}
4389
4390
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004391static void ath_sta_set_stbc(struct sigma_dut *dut, const char *intf,
4392 const char *val)
4393{
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004394 run_iwpriv(dut, intf, "tx_stbc %s", val);
4395 run_iwpriv(dut, intf, "rx_stbc %s", val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004396}
4397
4398
4399static int wcn_sta_set_cts_width(struct sigma_dut *dut, const char *intf,
4400 const char *val)
4401{
4402 char buf[60];
4403
Peng Xucc317ed2017-05-18 16:44:37 -07004404 if (strcmp(val, "160") == 0) {
4405 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 5", intf);
4406 } else if (strcmp(val, "80") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004407 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 3", intf);
4408 } else if (strcmp(val, "40") == 0) {
4409 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 2", intf);
4410 } else if (strcmp(val, "20") == 0) {
4411 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 1", intf);
4412 } else if (strcasecmp(val, "Auto") == 0) {
4413 buf[0] = '\0';
4414 } else {
4415 sigma_dut_print(dut, DUT_MSG_ERROR,
4416 "WIDTH/CTS_WIDTH value not supported");
4417 return -1;
4418 }
4419
4420 if (buf[0] != '\0' && system(buf) != 0) {
4421 sigma_dut_print(dut, DUT_MSG_ERROR,
4422 "Failed to set WIDTH/CTS_WIDTH");
4423 return -1;
4424 }
4425
4426 return 0;
4427}
4428
4429
4430int ath_set_width(struct sigma_dut *dut, struct sigma_conn *conn,
4431 const char *intf, const char *val)
4432{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004433 if (strcasecmp(val, "Auto") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004434 run_iwpriv(dut, intf, "chwidth 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004435 dut->chwidth = 0;
4436 } else if (strcasecmp(val, "20") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004437 run_iwpriv(dut, intf, "chwidth 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004438 dut->chwidth = 0;
4439 } else if (strcasecmp(val, "40") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004440 run_iwpriv(dut, intf, "chwidth 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004441 dut->chwidth = 1;
4442 } else if (strcasecmp(val, "80") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004443 run_iwpriv(dut, intf, "chwidth 2");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004444 dut->chwidth = 2;
4445 } else if (strcasecmp(val, "160") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004446 run_iwpriv(dut, intf, "chwidth 3");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004447 dut->chwidth = 3;
4448 } else {
4449 send_resp(dut, conn, SIGMA_ERROR,
4450 "ErrorCode,WIDTH not supported");
4451 return -1;
4452 }
4453
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004454 return 0;
4455}
4456
4457
4458static int wcn_sta_set_sp_stream(struct sigma_dut *dut, const char *intf,
4459 const char *val)
4460{
4461 char buf[60];
Arif Hussainac6c5112018-05-25 17:34:00 -07004462 int sta_nss;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004463
Amarnath Hullur Subramanyamd5374fa2018-02-25 19:00:24 -08004464 if (strcmp(val, "1SS") == 0 || strcmp(val, "1") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004465 snprintf(buf, sizeof(buf), "iwpriv %s nss 1", intf);
Arif Hussainac6c5112018-05-25 17:34:00 -07004466 sta_nss = 1;
Amarnath Hullur Subramanyamd5374fa2018-02-25 19:00:24 -08004467 } else if (strcmp(val, "2SS") == 0 || strcmp(val, "2") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004468 snprintf(buf, sizeof(buf), "iwpriv %s nss 2", intf);
Arif Hussainac6c5112018-05-25 17:34:00 -07004469 sta_nss = 2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004470 } else {
4471 sigma_dut_print(dut, DUT_MSG_ERROR,
4472 "SP_STREAM value not supported");
4473 return -1;
4474 }
4475
4476 if (system(buf) != 0) {
4477 sigma_dut_print(dut, DUT_MSG_ERROR,
4478 "Failed to set SP_STREAM");
4479 return -1;
4480 }
4481
Arif Hussainac6c5112018-05-25 17:34:00 -07004482 dut->sta_nss = sta_nss;
4483
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004484 return 0;
4485}
4486
4487
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05304488static void wcn_sta_set_stbc(struct sigma_dut *dut, const char *intf,
4489 const char *val)
4490{
4491 char buf[60];
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05304492 int ret;
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05304493
4494 snprintf(buf, sizeof(buf), "iwpriv %s tx_stbc %s", intf, val);
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05304495 ret = system(buf);
4496#ifdef NL80211_SUPPORT
4497 if (ret)
4498 ret = sta_config_params(dut, intf, STA_SET_TX_STBC,
4499 strcmp(val, "0") == 0 ? 0 : 1);
4500#endif /* NL80211_SUPPORT */
4501 if (ret)
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05304502 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv tx_stbc failed");
4503
4504 snprintf(buf, sizeof(buf), "iwpriv %s rx_stbc %s", intf, val);
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05304505 ret = system(buf);
4506#ifdef NL80211_SUPPORT
4507 if (ret)
4508 ret = sta_config_params(dut, intf, STA_SET_RX_STBC,
4509 strcmp(val, "0") == 0 ? 0 : 1);
4510#endif /* NL80211_SUPPORT */
4511 if (ret)
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05304512 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv rx_stbc failed");
4513}
4514
4515
Ashwini Patil68d02cd2017-01-10 15:39:16 +05304516static int mbo_set_cellular_data_capa(struct sigma_dut *dut,
4517 struct sigma_conn *conn,
4518 const char *intf, int capa)
4519{
4520 char buf[32];
4521
4522 if (capa > 0 && capa < 4) {
4523 snprintf(buf, sizeof(buf), "SET mbo_cell_capa %d", capa);
4524 if (wpa_command(intf, buf) < 0) {
4525 send_resp(dut, conn, SIGMA_ERROR,
4526 "ErrorCode, Failed to set cellular data capability");
4527 return 0;
4528 }
4529 return 1;
4530 }
4531
4532 sigma_dut_print(dut, DUT_MSG_ERROR,
4533 "Invalid Cellular data capability: %d", capa);
4534 send_resp(dut, conn, SIGMA_INVALID,
4535 "ErrorCode,Invalid cellular data capability");
4536 return 0;
4537}
4538
4539
Ashwini Patil9183fdb2017-04-13 16:58:25 +05304540static int mbo_set_roaming(struct sigma_dut *dut, struct sigma_conn *conn,
4541 const char *intf, const char *val)
4542{
4543 if (strcasecmp(val, "Disable") == 0) {
4544 if (wpa_command(intf, "SET roaming 0") < 0) {
4545 send_resp(dut, conn, SIGMA_ERROR,
4546 "ErrorCode,Failed to disable roaming");
4547 return 0;
4548 }
4549 return 1;
4550 }
4551
4552 if (strcasecmp(val, "Enable") == 0) {
4553 if (wpa_command(intf, "SET roaming 1") < 0) {
4554 send_resp(dut, conn, SIGMA_ERROR,
4555 "ErrorCode,Failed to enable roaming");
4556 return 0;
4557 }
4558 return 1;
4559 }
4560
4561 sigma_dut_print(dut, DUT_MSG_ERROR,
4562 "Invalid value provided for roaming: %s", val);
4563 send_resp(dut, conn, SIGMA_INVALID,
4564 "ErrorCode,Unknown value provided for Roaming");
4565 return 0;
4566}
4567
4568
Ashwini Patila75de5a2017-04-13 16:35:05 +05304569static int mbo_set_assoc_disallow(struct sigma_dut *dut,
4570 struct sigma_conn *conn,
4571 const char *intf, const char *val)
4572{
4573 if (strcasecmp(val, "Disable") == 0) {
4574 if (wpa_command(intf, "SET ignore_assoc_disallow 1") < 0) {
4575 send_resp(dut, conn, SIGMA_ERROR,
4576 "ErrorCode,Failed to disable Assoc_disallow");
4577 return 0;
4578 }
4579 return 1;
4580 }
4581
4582 if (strcasecmp(val, "Enable") == 0) {
4583 if (wpa_command(intf, "SET ignore_assoc_disallow 0") < 0) {
4584 send_resp(dut, conn, SIGMA_ERROR,
4585 "ErrorCode,Failed to enable Assoc_disallow");
4586 return 0;
4587 }
4588 return 1;
4589 }
4590
4591 sigma_dut_print(dut, DUT_MSG_ERROR,
4592 "Invalid value provided for Assoc_disallow: %s", val);
4593 send_resp(dut, conn, SIGMA_INVALID,
4594 "ErrorCode,Unknown value provided for Assoc_disallow");
4595 return 0;
4596}
4597
4598
Ashwini Patilc63161e2017-04-13 16:30:23 +05304599static int mbo_set_bss_trans_req(struct sigma_dut *dut, struct sigma_conn *conn,
4600 const char *intf, const char *val)
4601{
4602 if (strcasecmp(val, "Reject") == 0) {
4603 if (wpa_command(intf, "SET reject_btm_req_reason 1") < 0) {
4604 send_resp(dut, conn, SIGMA_ERROR,
4605 "ErrorCode,Failed to Reject BTM Request");
4606 return 0;
4607 }
4608 return 1;
4609 }
4610
4611 if (strcasecmp(val, "Accept") == 0) {
4612 if (wpa_command(intf, "SET reject_btm_req_reason 0") < 0) {
4613 send_resp(dut, conn, SIGMA_ERROR,
4614 "ErrorCode,Failed to Accept BTM Request");
4615 return 0;
4616 }
4617 return 1;
4618 }
4619
4620 sigma_dut_print(dut, DUT_MSG_ERROR,
4621 "Invalid value provided for BSS_Transition: %s", val);
4622 send_resp(dut, conn, SIGMA_INVALID,
4623 "ErrorCode,Unknown value provided for BSS_Transition");
4624 return 0;
4625}
4626
4627
Ashwini Patil00402582017-04-13 12:29:39 +05304628static int mbo_set_non_pref_ch_list(struct sigma_dut *dut,
4629 struct sigma_conn *conn,
4630 const char *intf,
4631 struct sigma_cmd *cmd)
4632{
4633 const char *ch, *pref, *op_class, *reason;
4634 char buf[120];
4635 int len, ret;
4636
4637 pref = get_param(cmd, "Ch_Pref");
4638 if (!pref)
4639 return 1;
4640
4641 if (strcasecmp(pref, "clear") == 0) {
4642 free(dut->non_pref_ch_list);
4643 dut->non_pref_ch_list = NULL;
4644 } else {
4645 op_class = get_param(cmd, "Ch_Op_Class");
4646 if (!op_class) {
4647 send_resp(dut, conn, SIGMA_INVALID,
4648 "ErrorCode,Ch_Op_Class not provided");
4649 return 0;
4650 }
4651
4652 ch = get_param(cmd, "Ch_Pref_Num");
4653 if (!ch) {
4654 send_resp(dut, conn, SIGMA_INVALID,
4655 "ErrorCode,Ch_Pref_Num not provided");
4656 return 0;
4657 }
4658
4659 reason = get_param(cmd, "Ch_Reason_Code");
4660 if (!reason) {
4661 send_resp(dut, conn, SIGMA_INVALID,
4662 "ErrorCode,Ch_Reason_Code not provided");
4663 return 0;
4664 }
4665
4666 if (!dut->non_pref_ch_list) {
4667 dut->non_pref_ch_list =
4668 calloc(1, NON_PREF_CH_LIST_SIZE);
4669 if (!dut->non_pref_ch_list) {
4670 send_resp(dut, conn, SIGMA_ERROR,
4671 "ErrorCode,Failed to allocate memory for non_pref_ch_list");
4672 return 0;
4673 }
4674 }
4675 len = strlen(dut->non_pref_ch_list);
4676 ret = snprintf(dut->non_pref_ch_list + len,
4677 NON_PREF_CH_LIST_SIZE - len,
4678 " %s:%s:%s:%s", op_class, ch, pref, reason);
4679 if (ret > 0 && ret < NON_PREF_CH_LIST_SIZE - len) {
4680 sigma_dut_print(dut, DUT_MSG_DEBUG, "non_pref_list: %s",
4681 dut->non_pref_ch_list);
4682 } else {
4683 sigma_dut_print(dut, DUT_MSG_ERROR,
4684 "snprintf failed for non_pref_list, ret = %d",
4685 ret);
4686 send_resp(dut, conn, SIGMA_ERROR,
4687 "ErrorCode,snprintf failed");
4688 free(dut->non_pref_ch_list);
4689 dut->non_pref_ch_list = NULL;
4690 return 0;
4691 }
4692 }
4693
4694 ret = snprintf(buf, sizeof(buf), "SET non_pref_chan%s",
4695 dut->non_pref_ch_list ? dut->non_pref_ch_list : " ");
4696 if (ret < 0 || ret >= (int) sizeof(buf)) {
4697 sigma_dut_print(dut, DUT_MSG_DEBUG,
4698 "snprintf failed for set non_pref_chan, ret: %d",
4699 ret);
4700 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,snprint failed");
4701 return 0;
4702 }
4703
4704 if (wpa_command(intf, buf) < 0) {
4705 send_resp(dut, conn, SIGMA_ERROR,
4706 "ErrorCode,Failed to set non-preferred channel list");
4707 return 0;
4708 }
4709
4710 return 1;
4711}
4712
4713
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08004714#ifdef NL80211_SUPPORT
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08004715
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08004716static int sta_set_he_htc_supp(struct sigma_dut *dut, const char *intf,
4717 uint8_t cfg)
4718{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05304719 return wcn_wifi_test_config_set_u8(
4720 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_HTC_HE_SUPP,
4721 cfg);
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08004722}
4723
4724
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08004725static int sta_set_he_fragmentation(struct sigma_dut *dut, const char *intf,
4726 enum he_fragmentation_val frag)
4727{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05304728 return wcn_wifi_test_config_set_u8(
4729 dut, intf,
4730 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_FRAGMENTATION, frag);
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08004731}
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08004732
4733
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -08004734int wcn_set_he_ltf(struct sigma_dut *dut, const char *intf,
4735 enum qca_wlan_he_ltf_cfg ltf)
Subhani Shaik8e7a3052018-04-24 14:03:00 -07004736{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05304737 return wcn_wifi_test_config_set_u8(
4738 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_LTF, ltf);
Subhani Shaik8e7a3052018-04-24 14:03:00 -07004739}
4740
4741
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08004742static int nlvendor_sta_set_noack(struct sigma_dut *dut, const char *intf,
4743 int noack, enum qca_wlan_ac_type ac)
4744{
4745 struct nl_msg *msg;
4746 int ret = 0;
4747 struct nlattr *params;
4748 int ifindex;
4749
4750 ifindex = if_nametoindex(intf);
4751 if (ifindex == 0) {
4752 sigma_dut_print(dut, DUT_MSG_ERROR,
4753 "%s: Index for interface %s failed",
4754 __func__, intf);
4755 return -1;
4756 }
4757
4758 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4759 NL80211_CMD_VENDOR)) ||
4760 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4761 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4762 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4763 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4764 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4765 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_NO_ACK,
4766 noack) ||
4767 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_NO_ACK_AC,
4768 ac)) {
4769 sigma_dut_print(dut, DUT_MSG_ERROR,
4770 "%s: err in adding vendor_cmd and vendor_data",
4771 __func__);
4772 nlmsg_free(msg);
4773 return -1;
4774 }
4775 nla_nest_end(msg, params);
4776
4777 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4778 if (ret) {
4779 sigma_dut_print(dut, DUT_MSG_ERROR,
4780 "%s: err in send_and_recv_msgs, ret=%d",
4781 __func__, ret);
4782 }
4783 return ret;
4784}
4785
4786
4787static void wcn_sta_set_noack(struct sigma_dut *dut, const char *intf,
4788 const char *val)
4789{
4790 int noack, ret;
4791 char token[100];
4792 char *result;
4793 char *saveptr;
4794 enum qca_wlan_ac_type ac = QCA_WLAN_AC_BE;
4795
4796 strlcpy(token, val, sizeof(token));
4797 token[sizeof(token) - 1] = '\0';
4798 result = strtok_r(token, ":", &saveptr);
4799 while (result) {
4800 noack = strcasecmp(result, "Disable") != 0;
4801 ret = nlvendor_sta_set_noack(dut, intf, noack, ac);
4802 if (ret) {
4803 sigma_dut_print(dut, DUT_MSG_ERROR,
4804 "nlvendor_sta_set_noack failed for ac:%d, ret:%d",
4805 ac, ret);
4806 }
4807 result = strtok_r(NULL, ":", &saveptr);
4808 ac++;
4809 }
4810}
4811
Vinita S. Maloo7462e812020-05-22 15:16:04 +05304812
4813static int nlvendor_sta_set_phymode(struct sigma_dut *dut, const char *intf,
4814 enum qca_wlan_vendor_phy_mode val)
4815{
4816 struct nl_msg *msg;
4817 struct nlattr *params;
4818 int ifindex, ret;
4819
4820 ifindex = if_nametoindex(intf);
4821 if (ifindex == 0) {
4822 sigma_dut_print(dut, DUT_MSG_ERROR,
4823 "%s: Index for interface %s not found",
4824 __func__, intf);
4825 return -1;
4826 }
4827
4828 msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4829 NL80211_CMD_VENDOR);
4830 if (!msg) {
4831 sigma_dut_print(dut, DUT_MSG_ERROR,
4832 "%s: err in adding vendor_cmd", __func__);
4833 return -1;
4834 }
4835
4836 if (nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4837 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4838 QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION)) {
4839 sigma_dut_print(dut, DUT_MSG_ERROR,
4840 "%s: err in adding vendor_attr", __func__);
4841 nlmsg_free(msg);
4842 return -1;
4843 }
4844
4845 params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
4846 if (!params || nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_PHY_MODE,
4847 val)) {
4848 sigma_dut_print(dut, DUT_MSG_ERROR,
4849 "%s: err in adding vendor_data", __func__);
4850 nlmsg_free(msg);
4851 return -1;
4852 }
4853
4854 nla_nest_end(msg, params);
4855 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4856 if (ret) {
4857 sigma_dut_print(dut, DUT_MSG_ERROR,
4858 "%s: err in send_and_recv_msgs, ret=%d (%s)",
4859 __func__, ret, strerror(-ret));
4860 return ret;
4861 }
4862
4863 return 0;
4864}
4865
4866
4867static enum qca_wlan_vendor_phy_mode get_qca_vendor_phymode(const char *val)
4868{
4869 if (strcmp(val, "11a") == 0) {
4870 /* IEEE80211_MODE_11A */
4871 return QCA_WLAN_VENDOR_PHY_MODE_11A;
4872 }
4873
4874 if (strcmp(val, "11g") == 0) {
4875 /* IEEE80211_MODE_11G */
4876 return QCA_WLAN_VENDOR_PHY_MODE_11G;
4877 }
4878
4879 if (strcmp(val, "11b") == 0) {
4880 /* IEEE80211_MODE_11B */
4881 return QCA_WLAN_VENDOR_PHY_MODE_11B;
4882 }
4883
4884 if (strcmp(val, "11n") == 0 ||
4885 strcmp(val, "11nl") == 0 ||
4886 strcmp(val, "11nl(nabg)") == 0) {
4887 /* IEEE80211_MODE_11AGN */
4888 return QCA_WLAN_VENDOR_PHY_MODE_11AGN;
4889 }
4890
4891 if (strcmp(val, "11ng") == 0) {
4892 /* IEEE80211_MODE_11NG_HT40 */
4893 return QCA_WLAN_VENDOR_PHY_MODE_11NG_HT40;
4894 }
4895
4896 if (strcmp(val, "AC") == 0 ||
4897 strcasecmp(val, "11AC") == 0) {
4898 /* IEEE80211_MODE_11AC_VHT80 */
4899 return QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT80;
4900 }
4901
4902 if (strcmp(val, "11na") == 0 ||
4903 strcasecmp(val, "11an") == 0) {
4904 /* IEEE80211_MODE_11NA_HT40 */
4905 return QCA_WLAN_VENDOR_PHY_MODE_11NA_HT40;
4906 }
4907
4908 if (strcmp(val, "11ax") == 0 ||
4909 strcmp(val, "auto") == 0) {
4910 /* IEEE80211_MODE_AUTO */
4911 return QCA_WLAN_VENDOR_PHY_MODE_AUTO;
4912 }
4913
4914 return -1;
4915}
4916
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08004917#endif /* NL80211_SUPPORT */
4918
4919
Vinita S. Maloo13a5cf72020-05-22 14:45:06 +05304920static int get_phymode(const char *val)
4921{
4922 if (strcmp(val, "11a") == 0)
4923 return 1; /* IEEE80211_MODE_11A */
4924 if (strcmp(val, "11g") == 0)
4925 return 3; /* IEEE80211_MODE_11G */
4926 if (strcmp(val, "11b") == 0)
4927 return 2; /* IEEE80211_MODE_11B */
4928 if (strcmp(val, "11n") == 0 ||
4929 strcmp(val, "11nl") == 0 ||
4930 strcmp(val, "11nl(nabg)") == 0)
4931 return 22; /* IEEE80211_MODE_11AGN */
4932 if (strcmp(val, "11ng") == 0)
4933 return 13; /* IEEE80211_MODE_11NG_HT40 */
4934 if (strcmp(val, "AC") == 0 ||
4935 strcasecmp(val, "11AC") == 0)
4936 return 19; /* IEEE80211_MODE_11AC_VHT80 */
4937 if (strcmp(val, "11na") == 0 ||
4938 strcasecmp(val, "11an") == 0)
4939 return 14; /* IEEE80211_MODE_11NA_HT40 */
4940 if (strcmp(val, "11ax") == 0 ||
4941 strcmp(val, "auto") == 0)
4942 return 0; /* IEEE80211_MODE_AUTO */
4943 return -1;
4944}
4945
4946
4947static void sta_set_phymode(struct sigma_dut *dut, const char *intf,
4948 const char *val)
4949{
4950 char buf[100];
4951 int len, phymode;
Vinita S. Maloo7462e812020-05-22 15:16:04 +05304952#ifdef NL80211_SUPPORT
4953 enum qca_wlan_vendor_phy_mode qca_phymode;
4954
4955 qca_phymode = get_qca_vendor_phymode(val);
4956 if (qca_phymode == -1) {
4957 sigma_dut_print(dut, DUT_MSG_DEBUG,
4958 "Ignoring mode change for mode: %s",
4959 val);
4960 return;
4961 }
4962
4963 if (nlvendor_sta_set_phymode(dut, intf, qca_phymode) == 0)
4964 return;
4965#endif /* NL80211_SUPPORT */
Vinita S. Maloo13a5cf72020-05-22 14:45:06 +05304966
4967 phymode = get_phymode(val);
4968 if (phymode == -1) {
4969 sigma_dut_print(dut, DUT_MSG_DEBUG,
4970 "Ignoring mode change for mode: %s",
4971 val);
4972 return;
4973 }
4974
4975 len = snprintf(buf, sizeof(buf), "iwpriv %s setphymode %d", intf,
4976 phymode);
4977 if (len < 0 || len >= sizeof(buf)) {
4978 sigma_dut_print(dut, DUT_MSG_ERROR,
4979 "Failed to set phymode");
4980 return;
4981 }
4982
4983 if (system(buf) != 0)
4984 sigma_dut_print(dut, DUT_MSG_ERROR,
4985 "iwpriv setting of phymode failed");
4986}
4987
4988
Jouni Malinenf7222712019-06-13 01:50:21 +03004989static enum sigma_cmd_result
4990cmd_sta_preset_testparameters(struct sigma_dut *dut, struct sigma_conn *conn,
4991 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004992{
4993 const char *intf = get_param(cmd, "Interface");
4994 const char *val;
4995
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03004996 val = get_param(cmd, "FT_DS");
4997 if (val) {
4998 if (strcasecmp(val, "Enable") == 0) {
4999 dut->sta_ft_ds = 1;
5000 } else if (strcasecmp(val, "Disable") == 0) {
5001 dut->sta_ft_ds = 0;
5002 } else {
5003 send_resp(dut, conn, SIGMA_ERROR,
5004 "errorCode,Unsupported value for FT_DS");
5005 return STATUS_SENT_ERROR;
5006 }
5007 }
5008
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005009 val = get_param(cmd, "Program");
Jouni Malinen1f6ae642018-06-07 23:56:13 +03005010 if (val && (strcasecmp(val, "HS2-R2") == 0 ||
5011 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005012 return cmd_sta_preset_testparameters_hs2_r2(dut, conn, intf,
5013 cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005014
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07005015 if (val && strcasecmp(val, "LOC") == 0)
5016 return loc_cmd_sta_preset_testparameters(dut, conn, cmd);
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02005017 if (val && strcasecmp(val, "60GHZ") == 0) {
5018 val = get_param(cmd, "WPS");
5019 if (val && strcasecmp(val, "disable") == 0) {
5020 dut->wps_disable = 1;
5021 sigma_dut_print(dut, DUT_MSG_INFO, "WPS disabled");
5022 } else {
5023 /* wps_disable can have other value from the previous
5024 * test, so make sure it has the correct value.
5025 */
5026 dut->wps_disable = 0;
5027 }
5028
5029 val = get_param(cmd, "P2P");
5030 if (val && strcasecmp(val, "disable") == 0)
5031 sigma_dut_print(dut, DUT_MSG_INFO, "P2P disabled");
5032 }
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07005033
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02005034 if (dut->program == PROGRAM_WPS && dut->band == WPS_BAND_60G)
5035 return cmd_sta_preset_testparameters_60ghz(dut, conn, cmd);
5036
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005037#ifdef ANDROID_NAN
5038 if (val && strcasecmp(val, "NAN") == 0)
5039 return nan_cmd_sta_preset_testparameters(dut, conn, cmd);
5040#endif /* ANDROID_NAN */
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07005041#ifdef MIRACAST
5042 if (val && (strcasecmp(val, "WFD") == 0 ||
5043 strcasecmp(val, "DisplayR2") == 0))
5044 return miracast_preset_testparameters(dut, conn, cmd);
5045#endif /* MIRACAST */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005046
Kiran Kumar Lokeredd086642020-06-04 00:29:26 -07005047 if (val &&
5048 (strcasecmp(val, "MBO") == 0 || strcasecmp(val, "HE") == 0)) {
Ashwini Patil68d02cd2017-01-10 15:39:16 +05305049 val = get_param(cmd, "Cellular_Data_Cap");
5050 if (val &&
5051 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
5052 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +05305053
5054 val = get_param(cmd, "Ch_Pref");
5055 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
5056 return 0;
5057
Ashwini Patilc63161e2017-04-13 16:30:23 +05305058 val = get_param(cmd, "BSS_Transition");
5059 if (val && mbo_set_bss_trans_req(dut, conn, intf, val) == 0)
5060 return 0;
5061
Ashwini Patila75de5a2017-04-13 16:35:05 +05305062 val = get_param(cmd, "Assoc_Disallow");
5063 if (val && mbo_set_assoc_disallow(dut, conn, intf, val) == 0)
5064 return 0;
5065
Ashwini Patil9183fdb2017-04-13 16:58:25 +05305066 val = get_param(cmd, "Roaming");
5067 if (val && mbo_set_roaming(dut, conn, intf, val) == 0)
5068 return 0;
5069
Ashwini Patil68d02cd2017-01-10 15:39:16 +05305070 return 1;
5071 }
5072
Ankita Bajaja2cb5672017-10-25 16:08:28 +05305073 if (val && strcasecmp(val, "OCE") == 0)
5074 return cmd_sta_preset_testparameters_oce(dut, conn, intf, cmd);
5075
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005076#if 0
5077 val = get_param(cmd, "Supplicant");
5078 if (val && strcasecmp(val, "Default") != 0) {
5079 send_resp(dut, conn, SIGMA_ERROR,
5080 "ErrorCode,Only default(Vendor) supplicant "
5081 "supported");
5082 return 0;
5083 }
5084#endif
5085
5086 val = get_param(cmd, "RTS");
5087 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005088 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005089 case DRIVER_ATHEROS:
5090 ath_sta_set_rts(dut, intf, val);
5091 break;
5092 default:
5093#if 0
5094 send_resp(dut, conn, SIGMA_ERROR,
5095 "ErrorCode,Setting RTS not supported");
5096 return 0;
5097#else
5098 sigma_dut_print(dut, DUT_MSG_DEBUG,
5099 "Setting RTS not supported");
5100 break;
5101#endif
5102 }
5103 }
5104
5105#if 0
5106 val = get_param(cmd, "FRGMNT");
5107 if (val) {
5108 /* TODO */
5109 send_resp(dut, conn, SIGMA_ERROR,
5110 "ErrorCode,Setting FRGMNT not supported");
5111 return 0;
5112 }
5113#endif
5114
5115#if 0
5116 val = get_param(cmd, "Preamble");
5117 if (val) {
5118 /* TODO: Long/Short */
5119 send_resp(dut, conn, SIGMA_ERROR,
5120 "ErrorCode,Setting Preamble not supported");
5121 return 0;
5122 }
5123#endif
5124
5125 val = get_param(cmd, "Mode");
5126 if (val) {
5127 if (strcmp(val, "11b") == 0 ||
5128 strcmp(val, "11g") == 0 ||
5129 strcmp(val, "11a") == 0 ||
5130 strcmp(val, "11n") == 0 ||
5131 strcmp(val, "11ng") == 0 ||
5132 strcmp(val, "11nl") == 0 ||
5133 strcmp(val, "11nl(nabg)") == 0 ||
5134 strcmp(val, "AC") == 0 ||
5135 strcmp(val, "11AC") == 0 ||
5136 strcmp(val, "11ac") == 0 ||
5137 strcmp(val, "11na") == 0 ||
Amarnath Hullur Subramanyamb0db2712018-01-30 19:40:35 -08005138 strcmp(val, "11an") == 0 ||
5139 strcmp(val, "11ax") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005140 /* STA supports all modes by default */
5141 } else {
5142 send_resp(dut, conn, SIGMA_ERROR,
5143 "ErrorCode,Setting Mode not supported");
5144 return 0;
5145 }
Amarnath Hullur Subramanyam97d0e532018-01-31 02:53:02 -08005146
5147 /* Change the mode only in case of testbed for HE program
5148 * and for 11a and 11g modes only. */
5149 if (dut->program == PROGRAM_HE &&
5150 dut->device_type == STA_testbed) {
Vinita S. Maloo13a5cf72020-05-22 14:45:06 +05305151 sta_set_phymode(dut, intf, val);
Amarnath Hullur Subramanyam97d0e532018-01-31 02:53:02 -08005152 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005153 }
5154
5155 val = get_param(cmd, "wmm");
5156 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005157 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005158 case DRIVER_ATHEROS:
5159 ath_sta_set_wmm(dut, intf, val);
5160 break;
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08005161 case DRIVER_WCN:
5162 wcn_sta_set_wmm(dut, intf, val);
5163 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005164 default:
5165 sigma_dut_print(dut, DUT_MSG_DEBUG,
5166 "Setting wmm not supported");
5167 break;
5168 }
5169 }
5170
5171 val = get_param(cmd, "Powersave");
5172 if (val) {
5173 if (strcmp(val, "0") == 0 || strcasecmp(val, "off") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005174 if (get_driver_type(dut) == DRIVER_WCN) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +05305175 if (set_power_save_wcn(dut, intf, 2) < 0)
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08005176 return 0;
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08005177 }
5178
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005179 if (wpa_command(get_station_ifname(dut),
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005180 "P2P_SET ps 0") < 0)
5181 return -2;
5182 /* Make sure test modes are disabled */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005183 wpa_command(get_station_ifname(dut), "P2P_SET ps 98");
5184 wpa_command(get_station_ifname(dut), "P2P_SET ps 96");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005185 } else if (strcmp(val, "1") == 0 ||
5186 strcasecmp(val, "PSPoll") == 0 ||
5187 strcasecmp(val, "on") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005188 if (get_driver_type(dut) == DRIVER_WCN) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +05305189 if (set_power_save_wcn(dut, intf, 1) < 0)
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08005190 return 0;
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08005191 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005192 /* Disable default power save mode */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005193 wpa_command(get_station_ifname(dut), "P2P_SET ps 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005194 /* Enable PS-Poll test mode */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005195 if (wpa_command(get_station_ifname(dut),
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005196 "P2P_SET ps 97") < 0 ||
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005197 wpa_command(get_station_ifname(dut),
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005198 "P2P_SET ps 99") < 0)
5199 return -2;
5200 } else if (strcmp(val, "2") == 0 ||
5201 strcasecmp(val, "Fast") == 0) {
5202 /* TODO */
5203 send_resp(dut, conn, SIGMA_ERROR,
5204 "ErrorCode,Powersave=Fast not supported");
5205 return 0;
5206 } else if (strcmp(val, "3") == 0 ||
5207 strcasecmp(val, "PSNonPoll") == 0) {
5208 /* Make sure test modes are disabled */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005209 wpa_command(get_station_ifname(dut), "P2P_SET ps 98");
5210 wpa_command(get_station_ifname(dut), "P2P_SET ps 96");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005211
5212 /* Enable default power save mode */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005213 if (wpa_command(get_station_ifname(dut),
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005214 "P2P_SET ps 1") < 0)
5215 return -2;
5216 } else
5217 return -1;
5218 }
5219
5220 val = get_param(cmd, "NoAck");
5221 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005222 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005223 case DRIVER_ATHEROS:
5224 ath_sta_set_noack(dut, intf, val);
5225 break;
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08005226#ifdef NL80211_SUPPORT
5227 case DRIVER_WCN:
5228 wcn_sta_set_noack(dut, intf, val);
5229 break;
5230#endif /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005231 default:
5232 send_resp(dut, conn, SIGMA_ERROR,
5233 "ErrorCode,Setting NoAck not supported");
5234 return 0;
5235 }
5236 }
5237
5238 val = get_param(cmd, "IgnoreChswitchProhibit");
5239 if (val) {
5240 /* TODO: Enabled/disabled */
5241 if (strcasecmp(val, "Enabled") == 0) {
5242 send_resp(dut, conn, SIGMA_ERROR,
5243 "ErrorCode,Enabling IgnoreChswitchProhibit "
5244 "not supported");
5245 return 0;
5246 }
5247 }
5248
5249 val = get_param(cmd, "TDLS");
5250 if (val) {
5251 if (strcasecmp(val, "Disabled") == 0) {
5252 if (wpa_command(intf, "SET tdls_disabled 1")) {
5253 send_resp(dut, conn, SIGMA_ERROR,
5254 "ErrorCode,Failed to disable TDLS");
5255 return 0;
5256 }
5257 } else if (strcasecmp(val, "Enabled") == 0) {
5258 if (wpa_command(intf, "SET tdls_disabled 0")) {
5259 send_resp(dut, conn, SIGMA_ERROR,
5260 "ErrorCode,Failed to enable TDLS");
5261 return 0;
5262 }
5263 } else {
5264 send_resp(dut, conn, SIGMA_ERROR,
5265 "ErrorCode,Unsupported TDLS value");
5266 return 0;
5267 }
5268 }
5269
5270 val = get_param(cmd, "TDLSmode");
5271 if (val) {
5272 if (strcasecmp(val, "Default") == 0) {
5273 wpa_command(intf, "SET tdls_testing 0");
5274 } else if (strcasecmp(val, "APProhibit") == 0) {
5275 if (wpa_command(intf, "SET tdls_testing 0x400")) {
5276 send_resp(dut, conn, SIGMA_ERROR,
5277 "ErrorCode,Failed to enable ignore "
5278 "APProhibit TDLS mode");
5279 return 0;
5280 }
5281 } else if (strcasecmp(val, "HiLoMac") == 0) {
5282 /* STA should respond with TDLS setup req for a TDLS
5283 * setup req */
5284 if (wpa_command(intf, "SET tdls_testing 0x80")) {
5285 send_resp(dut, conn, SIGMA_ERROR,
5286 "ErrorCode,Failed to enable HiLoMac "
5287 "TDLS mode");
5288 return 0;
5289 }
5290 } else if (strcasecmp(val, "WeakSecurity") == 0) {
5291 /*
5292 * Since all security modes are enabled by default when
5293 * Sigma control is used, there is no need to do
5294 * anything here.
5295 */
5296 } else if (strcasecmp(val, "ExistLink") == 0) {
5297 /*
5298 * Since we allow new TDLS Setup Request even if there
5299 * is an existing link, nothing needs to be done for
5300 * this.
5301 */
5302 } else {
5303 /* TODO:
5304 * ExistLink: STA should send TDLS setup req even if
5305 * direct link already exists
5306 */
5307 send_resp(dut, conn, SIGMA_ERROR,
5308 "ErrorCode,Unsupported TDLSmode value");
5309 return 0;
5310 }
5311 }
5312
5313 val = get_param(cmd, "FakePubKey");
5314 if (val && atoi(val) && wpa_command(intf, "SET wps_corrupt_pkhash 1")) {
5315 send_resp(dut, conn, SIGMA_ERROR,
5316 "ErrorCode,Failed to enable FakePubKey");
5317 return 0;
5318 }
5319
Amarnath Hullur Subramanyamae1042b2018-02-22 21:52:52 -08005320#ifdef NL80211_SUPPORT
5321 val = get_param(cmd, "FrgmntSupport");
5322 if (val) {
5323 if (strcasecmp(val, "Enable") == 0) {
5324 if (sta_set_he_fragmentation(dut, intf,
5325 HE_FRAG_LEVEL1)) {
5326 send_resp(dut, conn, SIGMA_ERROR,
5327 "ErrorCode,Failed to enable HE Fragmentation");
5328 return 0;
5329 }
5330 } else if (strcasecmp(val, "Disable") == 0) {
5331 if (sta_set_he_fragmentation(dut, intf,
5332 HE_FRAG_DISABLE)) {
5333 send_resp(dut, conn, SIGMA_ERROR,
5334 "ErrorCode,Failed to disable HE Fragmentation");
5335 return 0;
5336 }
5337 }
5338 }
5339#endif /* NL80211_SUPPORT */
5340
Vinita S. Maloo8a4779c2020-06-22 19:32:37 +05305341 val = get_param(cmd, "IncludeMSCSDescriptor");
5342 if (val && strcasecmp(val, "1") == 0) {
5343 char buf[128];
5344 int len;
5345
5346 len = snprintf(buf, sizeof(buf),
Veerendranath Jakkam62cde372020-08-19 18:03:06 +05305347 "MSCS add up_bitmap=F0 up_limit=7 stream_timeout=60000 frame_classifier=045F%032x",
Vinita S. Maloo8a4779c2020-06-22 19:32:37 +05305348 0);
5349
5350 if (len < 0 || len >= sizeof(buf)) {
5351 sigma_dut_print(dut, DUT_MSG_ERROR,
5352 "Failed to build MSCS Descriptor IE");
5353 return ERROR_SEND_STATUS;
5354 }
5355
5356 if (wpa_command(intf, buf) != 0) {
5357 send_resp(dut, conn, SIGMA_ERROR,
5358 "ErrorCode,Failed to include MSCS descriptor");
5359 return STATUS_SENT_ERROR;
5360 }
5361 }
5362
Vinita S. Maloo2287f142021-02-01 16:17:09 +05305363 val = get_param(cmd, "SCSSupport");
5364 if (val) {
5365 char buf[30];
5366 int disable_scs, len;
5367
5368 if (strcasecmp(val, "Enable") == 0) {
5369 disable_scs = 0;
5370 } else if (strcasecmp(val, "Disable") == 0) {
5371 disable_scs = 1;
5372 } else {
5373 sigma_dut_print(dut, DUT_MSG_ERROR,
5374 "Invalid SCSsupport parameter");
5375 return INVALID_SEND_STATUS;
5376 }
5377
5378 len = snprintf(buf, sizeof(buf), "SET disable_scs_support %d",
5379 disable_scs);
5380 if (len < 0 || len >= sizeof(buf) ||
5381 wpa_command(intf, buf) != 0) {
5382 send_resp(dut, conn, SIGMA_ERROR,
5383 "ErrorCode,Failed to update SCS support");
5384 return STATUS_SENT_ERROR;
5385 }
5386 }
5387
Vinita S. Maloo83dee552021-04-12 16:47:47 +05305388 val = get_param(cmd, "MSCSSupport");
5389 if (val) {
5390 char buf[30];
5391 int disable_mscs, len;
5392
5393 if (strcasecmp(val, "Enable") == 0) {
5394 disable_mscs = 0;
5395 } else if (strcasecmp(val, "Disable") == 0) {
5396 disable_mscs = 1;
5397 } else {
5398 sigma_dut_print(dut, DUT_MSG_ERROR,
5399 "Invalid MSCSsupport parameter");
5400 return INVALID_SEND_STATUS;
5401 }
5402
5403 len = snprintf(buf, sizeof(buf), "SET disable_mscs_support %d",
5404 disable_mscs);
5405 if (len < 0 || len >= sizeof(buf) ||
5406 wpa_command(intf, buf) != 0) {
5407 send_resp(dut, conn, SIGMA_ERROR,
5408 "ErrorCode,Failed to update MSCS support");
5409 return STATUS_SENT_ERROR;
5410 }
5411 }
5412
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005413 return 1;
5414}
5415
5416
5417static const char * ath_get_radio_name(const char *radio_name)
5418{
5419 if (radio_name == NULL)
5420 return "wifi0";
5421 if (strcmp(radio_name, "wifi1") == 0)
5422 return "wifi1";
5423 if (strcmp(radio_name, "wifi2") == 0)
5424 return "wifi2";
5425 return "wifi0";
5426}
5427
5428
5429static void ath_sta_set_txsp_stream(struct sigma_dut *dut, const char *intf,
5430 const char *val)
5431{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005432 unsigned int vht_mcsmap = 0;
5433 int txchainmask = 0;
5434 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
5435
5436 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
5437 if (dut->testbed_flag_txsp == 1) {
5438 vht_mcsmap = 0xfffc;
5439 dut->testbed_flag_txsp = 0;
5440 } else {
5441 vht_mcsmap = 0xfffe;
5442 }
5443 txchainmask = 1;
5444 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
5445 if (dut->testbed_flag_txsp == 1) {
5446 vht_mcsmap = 0xfff0;
5447 dut->testbed_flag_txsp = 0;
5448 } else {
5449 vht_mcsmap = 0xfffa;
5450 }
5451 txchainmask = 3;
5452 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
5453 if (dut->testbed_flag_txsp == 1) {
5454 vht_mcsmap = 0xffc0;
5455 dut->testbed_flag_txsp = 0;
5456 } else {
5457 vht_mcsmap = 0xffea;
5458 }
5459 txchainmask = 7;
5460 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
5461 if (dut->testbed_flag_txsp == 1) {
5462 vht_mcsmap = 0xff00;
5463 dut->testbed_flag_txsp = 0;
5464 } else {
5465 vht_mcsmap = 0xffaa;
5466 }
5467 txchainmask = 15;
5468 } else {
5469 if (dut->testbed_flag_txsp == 1) {
5470 vht_mcsmap = 0xffc0;
5471 dut->testbed_flag_txsp = 0;
5472 } else {
5473 vht_mcsmap = 0xffea;
5474 }
5475 }
5476
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005477 if (txchainmask)
5478 run_iwpriv(dut, basedev, "txchainmask %d", txchainmask);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005479
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005480 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005481}
5482
5483
5484static void ath_sta_set_rxsp_stream(struct sigma_dut *dut, const char *intf,
5485 const char *val)
5486{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005487 unsigned int vht_mcsmap = 0;
5488 int rxchainmask = 0;
5489 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
5490
5491 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
5492 if (dut->testbed_flag_rxsp == 1) {
5493 vht_mcsmap = 0xfffc;
5494 dut->testbed_flag_rxsp = 0;
5495 } else {
5496 vht_mcsmap = 0xfffe;
5497 }
5498 rxchainmask = 1;
5499 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
5500 if (dut->testbed_flag_rxsp == 1) {
5501 vht_mcsmap = 0xfff0;
5502 dut->testbed_flag_rxsp = 0;
5503 } else {
5504 vht_mcsmap = 0xfffa;
5505 }
5506 rxchainmask = 3;
5507 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
5508 if (dut->testbed_flag_rxsp == 1) {
5509 vht_mcsmap = 0xffc0;
5510 dut->testbed_flag_rxsp = 0;
5511 } else {
5512 vht_mcsmap = 0xffea;
5513 }
5514 rxchainmask = 7;
5515 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
5516 if (dut->testbed_flag_rxsp == 1) {
5517 vht_mcsmap = 0xff00;
5518 dut->testbed_flag_rxsp = 0;
5519 } else {
5520 vht_mcsmap = 0xffaa;
5521 }
5522 rxchainmask = 15;
5523 } else {
5524 if (dut->testbed_flag_rxsp == 1) {
5525 vht_mcsmap = 0xffc0;
5526 dut->testbed_flag_rxsp = 0;
5527 } else {
5528 vht_mcsmap = 0xffea;
5529 }
5530 }
5531
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005532 if (rxchainmask)
5533 run_iwpriv(dut, basedev, "rxchainmask %d", rxchainmask);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005534
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005535 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005536}
5537
5538
5539void ath_set_zero_crc(struct sigma_dut *dut, const char *val)
5540{
5541 if (strcasecmp(val, "enable") == 0) {
5542 if (system("athdiag --set --address=0x2a204 --and=0xbfffffff")
5543 != 0) {
5544 sigma_dut_print(dut, DUT_MSG_ERROR,
5545 "Disable BB_VHTSIGB_CRC_CALC failed");
5546 }
5547
5548 if (system("athdiag --set --address=0x2a204 --or=0x80000000")
5549 != 0) {
5550 sigma_dut_print(dut, DUT_MSG_ERROR,
5551 "Enable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
5552 }
5553 } else {
5554 if (system("athdiag --set --address=0x2a204 --and=0x7fffffff")
5555 != 0) {
5556 sigma_dut_print(dut, DUT_MSG_ERROR,
5557 "Disable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
5558 }
5559
5560 if (system("athdiag --set --address=0x2a204 --or=0x40000000")
5561 != 0) {
5562 sigma_dut_print(dut, DUT_MSG_ERROR,
5563 "Enable BB_VHTSIGB_CRC_CALC failed");
5564 }
5565 }
5566}
5567
5568
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08005569static int wcn_sta_set_width(struct sigma_dut *dut, const char *intf,
5570 const char *val)
5571{
5572 char buf[60];
5573
Shivani Baranwal2a572842021-09-16 12:27:15 +05305574#ifdef NL80211_SUPPORT
5575 enum nl80211_chan_width qca_channel_width;
5576
5577 if (strcmp(val, "20") == 0) {
5578 qca_channel_width = NL80211_CHAN_WIDTH_20;
5579 dut->chwidth = 0;
5580 } else if (strcmp(val, "40") == 0) {
5581 qca_channel_width = NL80211_CHAN_WIDTH_40;
5582 dut->chwidth = 1;
5583 } else if (strcmp(val, "80") == 0) {
5584 qca_channel_width = NL80211_CHAN_WIDTH_80;
5585 dut->chwidth = 2;
5586 } else if (strcmp(val, "160") == 0) {
5587 qca_channel_width = NL80211_CHAN_WIDTH_160;
5588 dut->chwidth = 3;
5589 } else if (strcasecmp(val, "Auto") == 0) {
5590 return 0;
5591 } else {
5592 sigma_dut_print(dut, DUT_MSG_ERROR, "WIDTH %s not supported",
5593 val);
5594 return -1;
5595 }
5596 if (sta_config_params(dut, intf, STA_SET_CHAN_WIDTH,
5597 qca_channel_width) == 0)
5598 return 0;
5599#endif /* NL80211_SUPPORT */
5600
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08005601 if (strcmp(val, "20") == 0) {
5602 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 0", intf);
5603 dut->chwidth = 0;
5604 } else if (strcmp(val, "40") == 0) {
5605 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 1", intf);
5606 dut->chwidth = 1;
5607 } else if (strcmp(val, "80") == 0) {
5608 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 2", intf);
5609 dut->chwidth = 2;
Sunil Duttb1cccac2018-05-22 21:03:12 +05305610 } else if (strcasecmp(val, "Auto") == 0) {
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08005611 buf[0] = '\0';
5612 } else {
5613 sigma_dut_print(dut, DUT_MSG_ERROR, "WIDTH %s not supported",
5614 val);
5615 return -1;
5616 }
5617
5618 if (buf[0] != '\0' && system(buf) != 0) {
5619 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv chwidth failed");
5620 return -1;
5621 }
5622
5623 return 0;
5624}
5625
5626
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005627static int nlvendor_sta_set_addba_reject(struct sigma_dut *dut,
5628 const char *intf, int addbareject)
5629{
5630#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05305631 return wcn_wifi_test_config_set_u8(
5632 dut, intf,
5633 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ACCEPT_ADDBA_REQ,
5634 !addbareject);
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005635#else /* NL80211_SUPPORT */
5636 sigma_dut_print(dut, DUT_MSG_ERROR,
5637 "ADDBA_REJECT cannot be set without NL80211_SUPPORT defined");
5638 return -1;
5639#endif /* NL80211_SUPPORT */
5640}
5641
5642
5643static int sta_set_addba_reject(struct sigma_dut *dut, const char *intf,
5644 int addbareject)
5645{
5646 int ret;
5647
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005648 switch (get_driver_type(dut)) {
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005649 case DRIVER_WCN:
5650 ret = nlvendor_sta_set_addba_reject(dut, intf, addbareject);
5651 if (ret) {
5652 sigma_dut_print(dut, DUT_MSG_ERROR,
5653 "nlvendor_sta_set_addba_reject failed, ret:%d",
5654 ret);
5655 return ret;
5656 }
5657 break;
5658 default:
5659 sigma_dut_print(dut, DUT_MSG_ERROR,
5660 "errorCode,Unsupported ADDBA_REJECT with the current driver");
5661 ret = -1;
5662 break;
5663 }
5664
5665 return ret;
5666}
5667
5668
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08005669static int nlvendor_config_send_addba(struct sigma_dut *dut, const char *intf,
5670 int enable)
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005671{
5672#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05305673 return wcn_wifi_test_config_set_u8(
5674 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_SEND_ADDBA_REQ,
5675 enable);
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005676#else /* NL80211_SUPPORT */
5677 sigma_dut_print(dut, DUT_MSG_ERROR,
5678 "Disable addba not possible without NL80211_SUPPORT defined");
5679 return -1;
5680#endif /* NL80211_SUPPORT */
5681}
5682
5683
Veerendranath Jakkamadcd6202019-04-17 12:32:21 +05305684#ifdef NL80211_SUPPORT
5685static int nl80211_sta_set_rts(struct sigma_dut *dut, const char *intf, int val)
5686{
5687 struct nl_msg *msg;
5688 int ret = 0;
5689 int ifindex;
5690
5691 ifindex = if_nametoindex(intf);
5692 if (ifindex == 0) {
5693 sigma_dut_print(dut, DUT_MSG_ERROR,
5694 "%s: Index for interface %s failed",
5695 __func__, intf);
5696 return -1;
5697 }
5698
5699 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
5700 NL80211_CMD_SET_WIPHY)) ||
5701 nla_put_u32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD, val)) {
5702 sigma_dut_print(dut, DUT_MSG_ERROR,
5703 "%s: err in adding RTS threshold",
5704 __func__);
5705 nlmsg_free(msg);
5706 return -1;
5707 }
5708
5709 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5710 if (ret) {
5711 sigma_dut_print(dut, DUT_MSG_ERROR,
5712 "%s: err in send_and_recv_msgs, ret=%d",
5713 __func__, ret);
5714 }
5715 return ret;
5716}
5717#endif /* NL80211_SUPPORT */
5718
5719
5720static int sta_set_rts(struct sigma_dut *dut, const char *intf, int val)
5721{
5722 char buf[100];
5723
5724#ifdef NL80211_SUPPORT
5725 if (nl80211_sta_set_rts(dut, intf, val) == 0)
5726 return 0;
5727 sigma_dut_print(dut, DUT_MSG_DEBUG,
5728 "Fall back to using iwconfig for setting RTS threshold");
5729#endif /* NL80211_SUPPORT */
5730
5731 snprintf(buf, sizeof(buf), "iwconfig %s rts %d", intf, val);
5732 if (system(buf) != 0) {
5733 sigma_dut_print(dut, DUT_MSG_ERROR,
5734 "Failed to set RTS threshold %d", val);
5735 return -1;
5736 }
5737 return 0;
5738}
5739
5740
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03005741static enum sigma_cmd_result
5742cmd_sta_set_wireless_common(const char *intf, struct sigma_dut *dut,
5743 struct sigma_conn *conn, struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005744{
5745 const char *val;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005746 int ampdu = -1, addbareject = -1;
Jouni Malinen3aa72862019-05-29 23:14:51 +03005747 char buf[128];
5748 int res;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005749
5750 val = get_param(cmd, "40_INTOLERANT");
5751 if (val) {
5752 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
5753 /* TODO: iwpriv ht40intol through wpa_supplicant */
5754 send_resp(dut, conn, SIGMA_ERROR,
5755 "ErrorCode,40_INTOLERANT not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03005756 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005757 }
5758 }
5759
5760 val = get_param(cmd, "ADDBA_REJECT");
5761 if (val) {
5762 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
5763 /* reject any ADDBA with status "decline" */
5764 ampdu = 0;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005765 addbareject = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005766 } else {
5767 /* accept ADDBA */
5768 ampdu = 1;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005769 addbareject = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005770 }
5771 }
5772
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005773 if (addbareject >= 0 &&
5774 sta_set_addba_reject(dut, intf, addbareject) < 0) {
5775 send_resp(dut, conn, SIGMA_ERROR,
5776 "ErrorCode,set addba_reject failed");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03005777 return STATUS_SENT_ERROR;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005778 }
5779
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005780 val = get_param(cmd, "AMPDU");
5781 if (val) {
5782 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
5783 /* enable AMPDU Aggregation */
5784 if (ampdu == 0) {
5785 send_resp(dut, conn, SIGMA_ERROR,
5786 "ErrorCode,Mismatch in "
5787 "addba_reject/ampdu - "
5788 "not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03005789 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005790 }
5791 ampdu = 1;
5792 } else {
5793 /* disable AMPDU Aggregation */
5794 if (ampdu == 1) {
5795 send_resp(dut, conn, SIGMA_ERROR,
5796 "ErrorCode,Mismatch in "
5797 "addba_reject/ampdu - "
5798 "not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03005799 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005800 }
5801 ampdu = 0;
5802 }
5803 }
5804
5805 if (ampdu >= 0) {
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005806 int ret;
5807
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005808 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s A-MPDU aggregation",
5809 ampdu ? "Enabling" : "Disabling");
5810 snprintf(buf, sizeof(buf), "SET ampdu %d", ampdu);
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07005811 if (wpa_command(intf, buf) < 0 &&
5812 iwpriv_sta_set_ampdu(dut, intf, ampdu) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005813 send_resp(dut, conn, SIGMA_ERROR,
5814 "ErrorCode,set aggr failed");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03005815 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005816 }
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005817
5818 if (ampdu == 0) {
5819 /* Disable sending of addba using nl vendor command */
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08005820 ret = nlvendor_config_send_addba(dut, intf, 0);
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005821 if (ret) {
5822 sigma_dut_print(dut, DUT_MSG_ERROR,
5823 "Failed to disable addba, ret:%d",
5824 ret);
5825 }
5826 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005827 }
5828
5829 val = get_param(cmd, "AMSDU");
5830 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005831 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005832 case DRIVER_ATHEROS:
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08005833 case DRIVER_WCN:
5834 iwpriv_sta_set_amsdu(dut, intf, val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005835 break;
5836 default:
5837 if (strcmp(val, "1") == 0 ||
5838 strcasecmp(val, "Enable") == 0) {
5839 /* Enable AMSDU Aggregation */
5840 send_resp(dut, conn, SIGMA_ERROR,
5841 "ErrorCode,AMSDU aggregation not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03005842 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005843 }
5844 break;
5845 }
5846 }
5847
5848 val = get_param(cmd, "STBC_RX");
5849 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005850 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005851 case DRIVER_ATHEROS:
5852 ath_sta_set_stbc(dut, intf, val);
5853 break;
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05305854 case DRIVER_WCN:
5855 wcn_sta_set_stbc(dut, intf, val);
5856 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005857 default:
5858 send_resp(dut, conn, SIGMA_ERROR,
5859 "ErrorCode,STBC_RX not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03005860 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005861 }
5862 }
5863
5864 val = get_param(cmd, "WIDTH");
5865 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005866 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005867 case DRIVER_WCN:
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08005868 if (wcn_sta_set_width(dut, intf, val) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005869 send_resp(dut, conn, SIGMA_ERROR,
5870 "ErrorCode,Failed to set WIDTH");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03005871 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005872 }
5873 break;
5874 case DRIVER_ATHEROS:
5875 if (ath_set_width(dut, conn, intf, val) < 0)
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03005876 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005877 break;
5878 default:
5879 sigma_dut_print(dut, DUT_MSG_ERROR,
5880 "Setting WIDTH not supported");
5881 break;
5882 }
5883 }
5884
5885 val = get_param(cmd, "SMPS");
5886 if (val) {
5887 /* TODO: Dynamic/0, Static/1, No Limit/2 */
5888 send_resp(dut, conn, SIGMA_ERROR,
5889 "ErrorCode,SMPS not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03005890 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005891 }
5892
5893 val = get_param(cmd, "TXSP_STREAM");
5894 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005895 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005896 case DRIVER_WCN:
5897 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
5898 send_resp(dut, conn, SIGMA_ERROR,
5899 "ErrorCode,Failed to set TXSP_STREAM");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03005900 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005901 }
5902 break;
5903 case DRIVER_ATHEROS:
5904 ath_sta_set_txsp_stream(dut, intf, val);
5905 break;
5906 default:
5907 sigma_dut_print(dut, DUT_MSG_ERROR,
5908 "Setting TXSP_STREAM not supported");
5909 break;
5910 }
5911 }
5912
5913 val = get_param(cmd, "RXSP_STREAM");
5914 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005915 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005916 case DRIVER_WCN:
5917 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
5918 send_resp(dut, conn, SIGMA_ERROR,
5919 "ErrorCode,Failed to set RXSP_STREAM");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03005920 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005921 }
5922 break;
5923 case DRIVER_ATHEROS:
5924 ath_sta_set_rxsp_stream(dut, intf, val);
5925 break;
5926 default:
5927 sigma_dut_print(dut, DUT_MSG_ERROR,
5928 "Setting RXSP_STREAM not supported");
5929 break;
5930 }
5931 }
5932
5933 val = get_param(cmd, "DYN_BW_SGNL");
5934 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005935 switch (get_driver_type(dut)) {
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08005936 case DRIVER_WCN:
Peng Xuc59afd32016-11-21 15:01:11 -08005937 if (strcasecmp(val, "enable") == 0) {
5938 snprintf(buf, sizeof(buf),
5939 "iwpriv %s cwmenable 1", intf);
5940 if (system(buf) != 0) {
5941 sigma_dut_print(dut, DUT_MSG_ERROR,
5942 "iwpriv cwmenable 1 failed");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03005943 return ERROR_SEND_STATUS;
Peng Xuc59afd32016-11-21 15:01:11 -08005944 }
5945 } else if (strcasecmp(val, "disable") == 0) {
5946 snprintf(buf, sizeof(buf),
5947 "iwpriv %s cwmenable 0", intf);
5948 if (system(buf) != 0) {
5949 sigma_dut_print(dut, DUT_MSG_ERROR,
5950 "iwpriv cwmenable 0 failed");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03005951 return ERROR_SEND_STATUS;
Peng Xuc59afd32016-11-21 15:01:11 -08005952 }
5953 } else {
5954 sigma_dut_print(dut, DUT_MSG_ERROR,
5955 "Unsupported DYN_BW_SGL");
5956 }
5957
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005958 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 3", intf);
5959 if (system(buf) != 0) {
5960 sigma_dut_print(dut, DUT_MSG_ERROR,
5961 "Failed to set cts_cbw in DYN_BW_SGNL");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03005962 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005963 }
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08005964 break;
5965 case DRIVER_ATHEROS:
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -07005966 novap_reset(dut, intf, 1);
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08005967 ath_config_dyn_bw_sig(dut, intf, val);
5968 break;
5969 default:
5970 sigma_dut_print(dut, DUT_MSG_ERROR,
5971 "Failed to set DYN_BW_SGNL");
5972 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005973 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005974 }
5975
5976 val = get_param(cmd, "RTS_FORCE");
5977 if (val) {
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -07005978 novap_reset(dut, intf, 1);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005979 if (strcasecmp(val, "Enable") == 0) {
Veerendranath Jakkamadcd6202019-04-17 12:32:21 +05305980 if (sta_set_rts(dut, intf, 64) != 0) {
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02005981 sigma_dut_print(dut, DUT_MSG_ERROR,
5982 "Failed to set RTS_FORCE 64");
5983 }
Jouni Malinen3aa72862019-05-29 23:14:51 +03005984 res = snprintf(buf, sizeof(buf),
5985 "wifitool %s beeliner_fw_test 100 1",
5986 intf);
5987 if (res < 0 || res >= sizeof(buf) || system(buf) != 0) {
priyadharshini gowthaman270870e2015-12-09 10:10:23 -08005988 sigma_dut_print(dut, DUT_MSG_ERROR,
5989 "wifitool beeliner_fw_test 100 1 failed");
5990 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005991 } else if (strcasecmp(val, "Disable") == 0) {
Veerendranath Jakkamadcd6202019-04-17 12:32:21 +05305992 if (sta_set_rts(dut, intf, 2347) != 0) {
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02005993 sigma_dut_print(dut, DUT_MSG_ERROR,
5994 "Failed to set RTS_FORCE 2347");
5995 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005996 } else {
5997 send_resp(dut, conn, SIGMA_ERROR,
5998 "ErrorCode,RTS_FORCE value not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03005999 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006000 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006001 }
6002
6003 val = get_param(cmd, "CTS_WIDTH");
6004 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006005 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006006 case DRIVER_WCN:
6007 if (wcn_sta_set_cts_width(dut, intf, val) < 0) {
6008 send_resp(dut, conn, SIGMA_ERROR,
6009 "ErrorCode,Failed to set CTS_WIDTH");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006010 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006011 }
6012 break;
6013 case DRIVER_ATHEROS:
6014 ath_set_cts_width(dut, intf, val);
6015 break;
6016 default:
6017 sigma_dut_print(dut, DUT_MSG_ERROR,
6018 "Setting CTS_WIDTH not supported");
6019 break;
6020 }
6021 }
6022
6023 val = get_param(cmd, "BW_SGNL");
6024 if (val) {
6025 if (strcasecmp(val, "Enable") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006026 run_iwpriv(dut, intf, "cwmenable 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006027 } else if (strcasecmp(val, "Disable") == 0) {
6028 /* TODO: Disable */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006029 } else {
6030 send_resp(dut, conn, SIGMA_ERROR,
6031 "ErrorCode,BW_SGNL value not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006032 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006033 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006034 }
6035
6036 val = get_param(cmd, "Band");
6037 if (val) {
6038 if (strcmp(val, "2.4") == 0 || strcmp(val, "5") == 0) {
6039 /* STA supports all bands by default */
6040 } else {
6041 send_resp(dut, conn, SIGMA_ERROR,
6042 "ErrorCode,Unsupported Band");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006043 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006044 }
6045 }
6046
6047 val = get_param(cmd, "zero_crc");
6048 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006049 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006050 case DRIVER_ATHEROS:
6051 ath_set_zero_crc(dut, val);
6052 break;
6053 default:
6054 break;
6055 }
6056 }
6057
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006058 return SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006059}
6060
6061
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02006062static int sta_set_force_mcs(struct sigma_dut *dut, int force, int mcs)
6063{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006064 switch (get_driver_type(dut)) {
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02006065#ifdef __linux__
6066 case DRIVER_WIL6210:
6067 return wil6210_set_force_mcs(dut, force, mcs);
6068#endif /* __linux__ */
6069 default:
6070 sigma_dut_print(dut, DUT_MSG_ERROR,
6071 "Unsupported sta_set_force_mcs with the current driver");
6072 return -1;
6073 }
6074}
6075
6076
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02006077static int sta_60g_force_rsn_ie(struct sigma_dut *dut, int state)
6078{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006079 switch (get_driver_type(dut)) {
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02006080#ifdef __linux__
6081 case DRIVER_WIL6210:
6082 return wil6210_force_rsn_ie(dut, state);
6083#endif /* __linux__ */
6084 default:
6085 sigma_dut_print(dut, DUT_MSG_ERROR,
6086 "Unsupported sta_60g_force_rsn_ie with the current driver");
6087 return -1;
6088 }
6089}
6090
6091
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006092static int sta_set_60g_common(struct sigma_dut *dut, struct sigma_conn *conn,
6093 struct sigma_cmd *cmd)
6094{
6095 const char *val;
6096 char buf[100];
6097
6098 val = get_param(cmd, "MSDUSize");
6099 if (val) {
6100 int mtu;
6101
6102 dut->amsdu_size = atoi(val);
6103 if (dut->amsdu_size > IEEE80211_MAX_DATA_LEN_DMG ||
6104 dut->amsdu_size < IEEE80211_SNAP_LEN_DMG) {
6105 sigma_dut_print(dut, DUT_MSG_ERROR,
6106 "MSDUSize %d is above max %d or below min %d",
6107 dut->amsdu_size,
6108 IEEE80211_MAX_DATA_LEN_DMG,
6109 IEEE80211_SNAP_LEN_DMG);
6110 dut->amsdu_size = 0;
Jouni Malinen0e29cf22019-02-19 01:13:21 +02006111 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006112 }
6113
6114 mtu = dut->amsdu_size - IEEE80211_SNAP_LEN_DMG;
6115 sigma_dut_print(dut, DUT_MSG_DEBUG,
6116 "Setting amsdu_size to %d", mtu);
6117 snprintf(buf, sizeof(buf), "ifconfig %s mtu %d",
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006118 get_station_ifname(dut), mtu);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006119
6120 if (system(buf) != 0) {
6121 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
6122 buf);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02006123 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006124 }
6125 }
6126
6127 val = get_param(cmd, "BAckRcvBuf");
6128 if (val) {
6129 dut->back_rcv_buf = atoi(val);
6130 if (dut->back_rcv_buf == 0) {
6131 sigma_dut_print(dut, DUT_MSG_ERROR,
6132 "Failed to convert %s or value is 0",
6133 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02006134 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006135 }
6136
6137 sigma_dut_print(dut, DUT_MSG_DEBUG,
6138 "Setting BAckRcvBuf to %s", val);
6139 }
6140
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02006141 val = get_param(cmd, "MCS_FixedRate");
6142 if (val) {
6143 if (sta_set_force_mcs(dut, 1, atoi(val))) {
6144 sigma_dut_print(dut, DUT_MSG_ERROR,
6145 "Failed to force MCS");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02006146 return ERROR_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02006147 }
6148 }
6149
Jouni Malinen0e29cf22019-02-19 01:13:21 +02006150 return SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006151}
6152
6153
6154static int sta_pcp_start(struct sigma_dut *dut, struct sigma_conn *conn,
6155 struct sigma_cmd *cmd)
6156{
6157 int net_id;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006158 const char *ifname;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006159 const char *val;
6160 char buf[100];
6161
6162 dut->mode = SIGMA_MODE_STATION;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006163 ifname = get_main_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006164 if (wpa_command(ifname, "PING") != 0) {
6165 sigma_dut_print(dut, DUT_MSG_ERROR, "Supplicant not running");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02006166 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006167 }
6168
6169 wpa_command(ifname, "FLUSH");
6170 net_id = add_network_common(dut, conn, ifname, cmd);
6171 if (net_id < 0) {
6172 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add network");
6173 return net_id;
6174 }
6175
6176 /* TODO: mode=2 for the AP; in the future, replace for mode PCP */
6177 if (set_network(ifname, net_id, "mode", "2") < 0) {
6178 sigma_dut_print(dut, DUT_MSG_ERROR,
6179 "Failed to set supplicant network mode");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02006180 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006181 }
6182
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02006183 if (set_network(ifname, net_id, "pbss", "1") < 0)
6184 return -2;
6185
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006186 sigma_dut_print(dut, DUT_MSG_DEBUG,
Alexei Avshalom Lazarfd9f1352018-11-13 14:07:58 +02006187 "Supplicant set network with mode 2. network_id %d",
6188 net_id);
6189
6190 if (set_network(ifname, net_id, "wps_disabled", "0") < 0) {
6191 sigma_dut_print(dut, DUT_MSG_INFO,
6192 "Failed to set supplicant to WPS ENABLE");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02006193 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarfd9f1352018-11-13 14:07:58 +02006194 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006195
6196 val = get_param(cmd, "Security");
6197 if (val && strcasecmp(val, "OPEN") == 0) {
6198 dut->ap_key_mgmt = AP_OPEN;
6199 if (set_network(ifname, net_id, "key_mgmt", "NONE") < 0) {
6200 sigma_dut_print(dut, DUT_MSG_ERROR,
6201 "Failed to set supplicant to %s security",
6202 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02006203 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006204 }
6205 } else if (val && strcasecmp(val, "WPA2-PSK") == 0) {
6206 dut->ap_key_mgmt = AP_WPA2_PSK;
6207 if (set_network(ifname, net_id, "key_mgmt", "WPA-PSK") < 0) {
6208 sigma_dut_print(dut, DUT_MSG_ERROR,
6209 "Failed to set supplicant to %s security",
6210 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02006211 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006212 }
6213
6214 if (set_network(ifname, net_id, "proto", "RSN") < 0) {
6215 sigma_dut_print(dut, DUT_MSG_ERROR,
6216 "Failed to set supplicant to proto RSN");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02006217 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006218 }
6219 } else if (val) {
6220 sigma_dut_print(dut, DUT_MSG_ERROR,
6221 "Requested Security %s is not supported on 60GHz",
6222 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02006223 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006224 }
6225
6226 val = get_param(cmd, "Encrypt");
6227 if (val && strcasecmp(val, "AES-GCMP") == 0) {
6228 if (set_network(ifname, net_id, "pairwise", "GCMP") < 0) {
6229 sigma_dut_print(dut, DUT_MSG_ERROR,
6230 "Failed to set supplicant to pairwise GCMP");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02006231 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006232 }
6233 if (set_network(ifname, net_id, "group", "GCMP") < 0) {
6234 sigma_dut_print(dut, DUT_MSG_ERROR,
6235 "Failed to set supplicant to group GCMP");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02006236 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006237 }
6238 } else if (val) {
6239 sigma_dut_print(dut, DUT_MSG_ERROR,
6240 "Requested Encrypt %s is not supported on 60 GHz",
6241 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02006242 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006243 }
6244
6245 val = get_param(cmd, "PSK");
6246 if (val && set_network_quoted(ifname, net_id, "psk", val) < 0) {
6247 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set psk %s",
6248 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02006249 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006250 }
6251
6252 /* Convert 60G channel to freq */
6253 switch (dut->ap_channel) {
6254 case 1:
6255 val = "58320";
6256 break;
6257 case 2:
6258 val = "60480";
6259 break;
6260 case 3:
6261 val = "62640";
6262 break;
6263 default:
6264 sigma_dut_print(dut, DUT_MSG_ERROR,
6265 "Failed to configure channel %d. Not supported",
6266 dut->ap_channel);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02006267 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006268 }
6269
6270 if (set_network(ifname, net_id, "frequency", val) < 0) {
6271 sigma_dut_print(dut, DUT_MSG_ERROR,
6272 "Failed to set supplicant network frequency");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02006273 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006274 }
6275
Alexei Avshalom Lazar2eccf4d2019-01-31 10:03:59 +02006276 if (dut->eap_fragment) {
6277 sigma_dut_print(dut, DUT_MSG_DEBUG,
6278 "Set EAP fragment size to 128 bytes.");
6279 if (set_network(ifname, net_id, "fragment_size", "128") < 0)
6280 return ERROR_SEND_STATUS;
6281 }
6282
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006283 sigma_dut_print(dut, DUT_MSG_DEBUG,
6284 "Supplicant set network with frequency");
6285
6286 snprintf(buf, sizeof(buf), "SELECT_NETWORK %d", net_id);
6287 if (wpa_command(ifname, buf) < 0) {
6288 sigma_dut_print(dut, DUT_MSG_INFO,
6289 "Failed to select network id %d on %s",
6290 net_id, ifname);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02006291 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006292 }
6293
6294 sigma_dut_print(dut, DUT_MSG_DEBUG, "Selected network");
6295
Jouni Malinen0e29cf22019-02-19 01:13:21 +02006296 return SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006297}
6298
6299
Lior David67543f52017-01-03 19:04:22 +02006300static int wil6210_set_abft_len(struct sigma_dut *dut, int abft_len)
6301{
6302 char buf[128], fname[128];
6303 FILE *f;
Jouni Malinen3aa72862019-05-29 23:14:51 +03006304 int res;
Lior David67543f52017-01-03 19:04:22 +02006305
6306 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
6307 sigma_dut_print(dut, DUT_MSG_ERROR,
6308 "failed to get wil6210 debugfs dir");
6309 return -1;
6310 }
6311
Jouni Malinen3aa72862019-05-29 23:14:51 +03006312 res = snprintf(fname, sizeof(fname), "%s/abft_len", buf);
6313 if (res < 0 || res >= sizeof(fname))
6314 return -1;
Lior David67543f52017-01-03 19:04:22 +02006315 f = fopen(fname, "w");
6316 if (!f) {
6317 sigma_dut_print(dut, DUT_MSG_ERROR,
6318 "failed to open: %s", fname);
6319 return -1;
6320 }
6321
6322 fprintf(f, "%d\n", abft_len);
6323 fclose(f);
6324
6325 return 0;
6326}
6327
6328
Alexei Avshalom Lazar49498b82019-01-31 15:16:32 +02006329int sta_set_60g_abft_len(struct sigma_dut *dut, struct sigma_conn *conn,
6330 int abft_len)
Lior David67543f52017-01-03 19:04:22 +02006331{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006332 switch (get_driver_type(dut)) {
Lior David67543f52017-01-03 19:04:22 +02006333 case DRIVER_WIL6210:
6334 return wil6210_set_abft_len(dut, abft_len);
6335 default:
6336 sigma_dut_print(dut, DUT_MSG_ERROR,
6337 "set abft_len not supported");
6338 return -1;
6339 }
6340}
6341
6342
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006343static int sta_set_60g_pcp(struct sigma_dut *dut, struct sigma_conn *conn,
6344 struct sigma_cmd *cmd)
6345{
6346 const char *val;
Lior David67543f52017-01-03 19:04:22 +02006347 unsigned int abft_len = 1; /* default is one slot */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006348
6349 if (dut->dev_role != DEVROLE_PCP) {
6350 send_resp(dut, conn, SIGMA_INVALID,
6351 "ErrorCode,Invalid DevRole");
6352 return 0;
6353 }
6354
6355 val = get_param(cmd, "SSID");
6356 if (val) {
6357 if (strlen(val) > sizeof(dut->ap_ssid) - 1) {
6358 send_resp(dut, conn, SIGMA_INVALID,
6359 "ErrorCode,Invalid SSID");
6360 return -1;
6361 }
6362
Peng Xub8fc5cc2017-05-10 17:27:28 -07006363 strlcpy(dut->ap_ssid, val, sizeof(dut->ap_ssid));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006364 }
6365
6366 val = get_param(cmd, "CHANNEL");
6367 if (val) {
6368 const char *pos;
6369
6370 dut->ap_channel = atoi(val);
6371 pos = strchr(val, ';');
6372 if (pos) {
6373 pos++;
6374 dut->ap_channel_1 = atoi(pos);
6375 }
6376 }
6377
6378 switch (dut->ap_channel) {
6379 case 1:
6380 case 2:
6381 case 3:
6382 break;
6383 default:
6384 sigma_dut_print(dut, DUT_MSG_ERROR,
6385 "Channel %d is not supported", dut->ap_channel);
6386 send_resp(dut, conn, SIGMA_ERROR,
6387 "Requested channel is not supported");
6388 return -1;
6389 }
6390
6391 val = get_param(cmd, "BCNINT");
6392 if (val)
6393 dut->ap_bcnint = atoi(val);
6394
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006395 val = get_param(cmd, "AllocType");
6396 if (val) {
6397 send_resp(dut, conn, SIGMA_ERROR,
6398 "ErrorCode,AllocType is not supported yet");
6399 return -1;
6400 }
6401
6402 val = get_param(cmd, "PercentBI");
6403 if (val) {
6404 send_resp(dut, conn, SIGMA_ERROR,
6405 "ErrorCode,PercentBI is not supported yet");
6406 return -1;
6407 }
6408
6409 val = get_param(cmd, "CBAPOnly");
6410 if (val) {
6411 send_resp(dut, conn, SIGMA_ERROR,
6412 "ErrorCode,CBAPOnly is not supported yet");
6413 return -1;
6414 }
6415
6416 val = get_param(cmd, "AMPDU");
6417 if (val) {
6418 if (strcasecmp(val, "Enable") == 0)
6419 dut->ap_ampdu = 1;
6420 else if (strcasecmp(val, "Disable") == 0)
6421 dut->ap_ampdu = 2;
6422 else {
6423 send_resp(dut, conn, SIGMA_ERROR,
6424 "ErrorCode,AMPDU value is not Enable nor Disabled");
6425 return -1;
6426 }
6427 }
6428
6429 val = get_param(cmd, "AMSDU");
6430 if (val) {
6431 if (strcasecmp(val, "Enable") == 0)
6432 dut->ap_amsdu = 1;
6433 else if (strcasecmp(val, "Disable") == 0)
6434 dut->ap_amsdu = 2;
6435 }
6436
6437 val = get_param(cmd, "NumMSDU");
6438 if (val) {
6439 send_resp(dut, conn, SIGMA_ERROR,
6440 "ErrorCode, NumMSDU is not supported yet");
6441 return -1;
6442 }
6443
6444 val = get_param(cmd, "ABFTLRang");
6445 if (val) {
6446 sigma_dut_print(dut, DUT_MSG_DEBUG,
Lior David67543f52017-01-03 19:04:22 +02006447 "ABFTLRang parameter %s", val);
6448 if (strcmp(val, "Gt1") == 0)
6449 abft_len = 2; /* 2 slots in this case */
6450 }
6451
6452 if (sta_set_60g_abft_len(dut, conn, abft_len)) {
6453 send_resp(dut, conn, SIGMA_ERROR,
6454 "ErrorCode, Can't set ABFT length");
6455 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006456 }
6457
6458 if (sta_pcp_start(dut, conn, cmd) < 0) {
6459 send_resp(dut, conn, SIGMA_ERROR,
6460 "ErrorCode, Can't start PCP role");
6461 return -1;
6462 }
6463
6464 return sta_set_60g_common(dut, conn, cmd);
6465}
6466
6467
6468static int sta_set_60g_sta(struct sigma_dut *dut, struct sigma_conn *conn,
6469 struct sigma_cmd *cmd)
6470{
6471 const char *val = get_param(cmd, "DiscoveryMode");
6472
6473 if (dut->dev_role != DEVROLE_STA) {
6474 send_resp(dut, conn, SIGMA_INVALID,
6475 "ErrorCode,Invalid DevRole");
6476 return 0;
6477 }
6478
6479 if (val) {
6480 sigma_dut_print(dut, DUT_MSG_DEBUG, "Discovery: %s", val);
6481 /* Ignore Discovery mode till Driver expose API. */
6482#if 0
6483 if (strcasecmp(val, "1") == 0) {
6484 send_resp(dut, conn, SIGMA_INVALID,
6485 "ErrorCode,DiscoveryMode 1 not supported");
6486 return 0;
6487 }
6488
6489 if (strcasecmp(val, "0") == 0) {
6490 /* OK */
6491 } else {
6492 send_resp(dut, conn, SIGMA_INVALID,
6493 "ErrorCode,DiscoveryMode not supported");
6494 return 0;
6495 }
6496#endif
6497 }
6498
6499 if (start_sta_mode(dut) != 0)
Jouni Malinen0e29cf22019-02-19 01:13:21 +02006500 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006501 return sta_set_60g_common(dut, conn, cmd);
6502}
6503
6504
Jouni Malinenf7222712019-06-13 01:50:21 +03006505static enum sigma_cmd_result cmd_sta_disconnect(struct sigma_dut *dut,
6506 struct sigma_conn *conn,
6507 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006508{
6509 const char *intf = get_param(cmd, "Interface");
Jouni Malinened77e672018-01-10 16:45:13 +02006510 const char *val = get_param(cmd, "maintain_profile");
vamsi krishnad605c422017-09-20 14:56:31 +05306511
Jouni Malinened77e672018-01-10 16:45:13 +02006512 if (dut->program == PROGRAM_OCE ||
Amarnath Hullur Subramanyamebeda9e2018-01-31 03:21:48 -08006513 dut->program == PROGRAM_HE ||
Jouni Malinened77e672018-01-10 16:45:13 +02006514 (val && atoi(val) == 1)) {
vamsi krishnad605c422017-09-20 14:56:31 +05306515 wpa_command(intf, "DISCONNECT");
6516 return 1;
6517 }
6518
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006519 disconnect_station(dut);
6520 /* Try to ignore old scan results to avoid HS 2.0R2 test case failures
6521 * due to cached results. */
6522 wpa_command(intf, "SET ignore_old_scan_res 1");
6523 wpa_command(intf, "BSS_FLUSH");
6524 return 1;
6525}
6526
6527
Jouni Malinenf7222712019-06-13 01:50:21 +03006528static enum sigma_cmd_result cmd_sta_reassoc(struct sigma_dut *dut,
6529 struct sigma_conn *conn,
6530 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006531{
6532 const char *intf = get_param(cmd, "Interface");
6533 const char *bssid = get_param(cmd, "bssid");
6534 const char *val = get_param(cmd, "CHANNEL");
Kiran Kumar Lokere94a86b52020-06-03 23:25:19 -07006535 const char *freq_val = get_param(cmd, "ChnlFreq");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006536 struct wpa_ctrl *ctrl;
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05306537 char buf[1000];
Sunil Duttd30ce092018-01-11 23:56:29 +05306538 char result[32];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006539 int res;
6540 int chan = 0;
Kiran Kumar Lokere94a86b52020-06-03 23:25:19 -07006541 int freq = 0;
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006542 enum sigma_cmd_result status = STATUS_SENT;
Sunil Duttd30ce092018-01-11 23:56:29 +05306543 int fastreassoc = 1;
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006544 int ft_ds = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006545
6546 if (bssid == NULL) {
6547 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing bssid "
6548 "argument");
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006549 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006550 }
6551
6552 if (val)
6553 chan = atoi(val);
6554
Kiran Kumar Lokere94a86b52020-06-03 23:25:19 -07006555 if (freq_val)
6556 freq = atoi(freq_val);
6557
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006558 if (wifi_chip_type != DRIVER_WCN && wifi_chip_type != DRIVER_AR6003) {
6559 /* The current network may be from sta_associate or
6560 * sta_hs2_associate
6561 */
6562 if (set_network(intf, dut->infra_network_id, "bssid", bssid) <
6563 0 ||
6564 set_network(intf, 0, "bssid", bssid) < 0)
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006565 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006566 }
6567
6568 ctrl = open_wpa_mon(intf);
6569 if (ctrl == NULL) {
6570 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
6571 "wpa_supplicant monitor connection");
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006572 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006573 }
6574
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006575 if (get_wpa_status(get_station_ifname(dut), "wpa_state", result,
Sunil Duttd30ce092018-01-11 23:56:29 +05306576 sizeof(result)) < 0 ||
6577 strncmp(result, "COMPLETED", 9) != 0) {
6578 sigma_dut_print(dut, DUT_MSG_DEBUG,
6579 "sta_reassoc: Not connected");
6580 fastreassoc = 0;
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006581 } else if (dut->sta_ft_ds) {
6582 sigma_dut_print(dut, DUT_MSG_DEBUG,
6583 "sta_reassoc: Use FT-over-DS");
6584 ft_ds = 1;
Sunil Duttd30ce092018-01-11 23:56:29 +05306585 }
6586
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05306587 if (dut->rsne_override) {
6588#ifdef NL80211_SUPPORT
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006589 if (get_driver_type(dut) == DRIVER_WCN &&
6590 dut->config_rsnie == 0) {
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05306591 sta_config_params(dut, intf, STA_SET_RSNIE, 1);
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05306592 dut->config_rsnie = 1;
6593 }
6594#endif /* NL80211_SUPPORT */
6595 snprintf(buf, sizeof(buf), "TEST_ASSOC_IE %s",
6596 dut->rsne_override);
6597 if (wpa_command(intf, buf) < 0) {
6598 send_resp(dut, conn, SIGMA_ERROR,
6599 "ErrorCode,Failed to set DEV_CONFIGURE_IE RSNE override");
6600 return 0;
6601 }
6602 }
6603
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006604 if (ft_ds) {
Kiran Kumar Lokere94a86b52020-06-03 23:25:19 -07006605 if (chan || freq) {
6606 if (!freq)
6607 freq = channel_to_freq(dut, chan);
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006608 if (!freq) {
6609 sigma_dut_print(dut, DUT_MSG_ERROR,
6610 "Invalid channel number provided: %d",
6611 chan);
6612 send_resp(dut, conn, SIGMA_INVALID,
6613 "ErrorCode,Invalid channel number");
6614 goto close_mon_conn;
6615 }
6616 res = snprintf(buf, sizeof(buf),
6617 "SCAN TYPE=ONLY freq=%d", freq);
6618 } else {
6619 res = snprintf(buf, sizeof(buf), "SCAN TYPE=ONLY");
6620 }
6621 if (res < 0 || res >= (int) sizeof(buf)) {
6622 send_resp(dut, conn, SIGMA_ERROR,
6623 "ErrorCode,snprintf failed");
6624 goto close_mon_conn;
6625 }
6626 if (wpa_command(intf, buf) < 0) {
6627 sigma_dut_print(dut, DUT_MSG_INFO,
6628 "Failed to start scan");
6629 send_resp(dut, conn, SIGMA_ERROR,
6630 "ErrorCode,scan failed");
6631 goto close_mon_conn;
6632 }
6633
6634 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
6635 buf, sizeof(buf));
6636 if (res < 0) {
6637 sigma_dut_print(dut, DUT_MSG_INFO,
6638 "Scan did not complete");
6639 send_resp(dut, conn, SIGMA_ERROR,
6640 "ErrorCode,scan did not complete");
6641 goto close_mon_conn;
6642 }
6643
6644 res = snprintf(buf, sizeof(buf), "FT_DS %s", bssid);
6645 if (res > 0 && res < (int) sizeof(buf))
6646 res = wpa_command(intf, buf);
6647
6648 if (res < 0 || res >= (int) sizeof(buf)) {
6649 send_resp(dut, conn, SIGMA_ERROR,
6650 "errorCode,FT_DS command failed");
6651 status = STATUS_SENT_ERROR;
6652 goto close_mon_conn;
6653 }
6654 } else if (wifi_chip_type == DRIVER_WCN && fastreassoc) {
Kiran Kumar Lokere94a86b52020-06-03 23:25:19 -07006655 if (chan || freq) {
6656 if (!freq)
6657 freq = channel_to_freq(dut, chan);
Ashwini Patil4c8158f2017-05-25 12:49:21 +05306658 if (!freq) {
6659 sigma_dut_print(dut, DUT_MSG_ERROR,
6660 "Invalid channel number provided: %d",
6661 chan);
6662 send_resp(dut, conn, SIGMA_INVALID,
6663 "ErrorCode,Invalid channel number");
6664 goto close_mon_conn;
6665 }
6666 res = snprintf(buf, sizeof(buf),
6667 "SCAN TYPE=ONLY freq=%d", freq);
6668 } else {
6669 res = snprintf(buf, sizeof(buf), "SCAN TYPE=ONLY");
6670 }
6671 if (res < 0 || res >= (int) sizeof(buf)) {
6672 send_resp(dut, conn, SIGMA_ERROR,
6673 "ErrorCode,snprintf failed");
6674 goto close_mon_conn;
6675 }
6676 if (wpa_command(intf, buf) < 0) {
6677 sigma_dut_print(dut, DUT_MSG_INFO,
6678 "Failed to start scan");
6679 send_resp(dut, conn, SIGMA_ERROR,
6680 "ErrorCode,scan failed");
6681 goto close_mon_conn;
6682 }
6683
6684 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
6685 buf, sizeof(buf));
6686 if (res < 0) {
6687 sigma_dut_print(dut, DUT_MSG_INFO,
6688 "Scan did not complete");
6689 send_resp(dut, conn, SIGMA_ERROR,
6690 "ErrorCode,scan did not complete");
6691 goto close_mon_conn;
6692 }
6693
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006694 if (set_network(intf, dut->infra_network_id, "bssid", "any")
6695 < 0) {
6696 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
6697 "bssid to any during FASTREASSOC");
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006698 status = ERROR_SEND_STATUS;
Ashwini Patil467efef2017-05-25 12:18:27 +05306699 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006700 }
Vinita Maloo54b78cf2020-03-30 12:18:19 +05306701 res = snprintf(buf, sizeof(buf), "FASTREASSOC %s %d",
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006702 bssid, chan);
Vinita Maloo54b78cf2020-03-30 12:18:19 +05306703 if (res < 0 || res >= (int) sizeof(buf) ||
6704 wcn_driver_cmd(intf, buf) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006705 send_resp(dut, conn, SIGMA_ERROR,
Vinita Maloo54b78cf2020-03-30 12:18:19 +05306706 "errorCode,Failed to run FASTREASSOC");
Ashwini Patil467efef2017-05-25 12:18:27 +05306707 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006708 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006709 sigma_dut_print(dut, DUT_MSG_INFO,
6710 "sta_reassoc: Run %s successful", buf);
6711 } else if (wpa_command(intf, "REASSOCIATE")) {
6712 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
6713 "request reassociation");
Ashwini Patil467efef2017-05-25 12:18:27 +05306714 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006715 }
6716
6717 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
6718 buf, sizeof(buf));
Ashwini Patil467efef2017-05-25 12:18:27 +05306719 if (res < 0) {
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006720 send_resp(dut, conn, SIGMA_ERROR,
6721 "errorCode,Connection did not complete");
6722 status = STATUS_SENT_ERROR;
Ashwini Patil467efef2017-05-25 12:18:27 +05306723 goto close_mon_conn;
6724 }
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006725 status = SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006726
Ashwini Patil467efef2017-05-25 12:18:27 +05306727close_mon_conn:
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006728 wpa_ctrl_detach(ctrl);
6729 wpa_ctrl_close(ctrl);
Ashwini Patil467efef2017-05-25 12:18:27 +05306730 return status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006731}
6732
6733
6734static void hs2_clear_credentials(const char *intf)
6735{
6736 wpa_command(intf, "REMOVE_CRED all");
6737}
6738
6739
Lior Davidcc88b562017-01-03 18:52:09 +02006740#ifdef __linux__
6741static int wil6210_get_aid(struct sigma_dut *dut, const char *bssid,
6742 unsigned int *aid)
6743{
Lior David0fe101e2017-03-09 16:09:50 +02006744 const char *pattern = "AID[ \t]+([0-9]+)";
Lior Davidcc88b562017-01-03 18:52:09 +02006745
Lior David0fe101e2017-03-09 16:09:50 +02006746 return wil6210_get_sta_info_field(dut, bssid, pattern, aid);
Lior Davidcc88b562017-01-03 18:52:09 +02006747}
6748#endif /* __linux__ */
6749
6750
6751static int sta_get_aid_60g(struct sigma_dut *dut, const char *bssid,
6752 unsigned int *aid)
6753{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006754 switch (get_driver_type(dut)) {
Lior Davidcc88b562017-01-03 18:52:09 +02006755#ifdef __linux__
6756 case DRIVER_WIL6210:
6757 return wil6210_get_aid(dut, bssid, aid);
6758#endif /* __linux__ */
6759 default:
6760 sigma_dut_print(dut, DUT_MSG_ERROR, "get AID not supported");
6761 return -1;
6762 }
6763}
6764
6765
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006766static int sta_get_parameter_60g(struct sigma_dut *dut, struct sigma_conn *conn,
6767 struct sigma_cmd *cmd)
6768{
6769 char buf[MAX_CMD_LEN];
6770 char bss_list[MAX_CMD_LEN];
6771 const char *parameter = get_param(cmd, "Parameter");
6772
6773 if (parameter == NULL)
6774 return -1;
6775
Lior Davidcc88b562017-01-03 18:52:09 +02006776 if (strcasecmp(parameter, "AID") == 0) {
6777 unsigned int aid = 0;
6778 char bssid[20];
6779
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006780 if (get_wpa_status(get_station_ifname(dut), "bssid",
Lior Davidcc88b562017-01-03 18:52:09 +02006781 bssid, sizeof(bssid)) < 0) {
6782 sigma_dut_print(dut, DUT_MSG_ERROR,
6783 "could not get bssid");
6784 return -2;
6785 }
6786
6787 if (sta_get_aid_60g(dut, bssid, &aid))
6788 return -2;
6789
6790 snprintf(buf, sizeof(buf), "aid,%d", aid);
6791 sigma_dut_print(dut, DUT_MSG_INFO, "%s", buf);
6792 send_resp(dut, conn, SIGMA_COMPLETE, buf);
6793 return 0;
6794 }
6795
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006796 if (strcasecmp(parameter, "DiscoveredDevList") == 0) {
6797 char *bss_line;
6798 char *bss_id = NULL;
6799 const char *ifname = get_param(cmd, "Interface");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05306800 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006801
6802 if (ifname == NULL) {
6803 sigma_dut_print(dut, DUT_MSG_INFO,
6804 "For get DiscoveredDevList need Interface name.");
6805 return -1;
6806 }
6807
6808 /*
6809 * Use "BSS RANGE=ALL MASK=0x2" which provides a list
6810 * of BSSIDs in "bssid=<BSSID>\n"
6811 */
6812 if (wpa_command_resp(ifname, "BSS RANGE=ALL MASK=0x2",
6813 bss_list,
6814 sizeof(bss_list)) < 0) {
6815 sigma_dut_print(dut, DUT_MSG_ERROR,
6816 "Failed to get bss list");
6817 return -1;
6818 }
6819
6820 sigma_dut_print(dut, DUT_MSG_DEBUG,
6821 "bss list for ifname:%s is:%s",
6822 ifname, bss_list);
6823
6824 snprintf(buf, sizeof(buf), "DeviceList");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05306825 bss_line = strtok_r(bss_list, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006826 while (bss_line) {
6827 if (sscanf(bss_line, "bssid=%ms", &bss_id) > 0 &&
6828 bss_id) {
6829 int len;
6830
6831 len = snprintf(buf + strlen(buf),
6832 sizeof(buf) - strlen(buf),
6833 ",%s", bss_id);
6834 free(bss_id);
6835 bss_id = NULL;
6836 if (len < 0) {
6837 sigma_dut_print(dut,
6838 DUT_MSG_ERROR,
6839 "Failed to read BSSID");
6840 send_resp(dut, conn, SIGMA_ERROR,
6841 "ErrorCode,Failed to read BSS ID");
6842 return 0;
6843 }
6844
6845 if ((size_t) len >= sizeof(buf) - strlen(buf)) {
6846 sigma_dut_print(dut,
6847 DUT_MSG_ERROR,
6848 "Response buf too small for list");
6849 send_resp(dut, conn,
6850 SIGMA_ERROR,
6851 "ErrorCode,Response buf too small for list");
6852 return 0;
6853 }
6854 }
6855
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05306856 bss_line = strtok_r(NULL, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006857 }
6858
6859 sigma_dut_print(dut, DUT_MSG_INFO, "DiscoveredDevList is %s",
6860 buf);
6861 send_resp(dut, conn, SIGMA_COMPLETE, buf);
6862 return 0;
6863 }
6864
6865 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
6866 return 0;
6867}
6868
6869
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07006870static int sta_get_parameter_he(struct sigma_dut *dut, struct sigma_conn *conn,
6871 struct sigma_cmd *cmd)
6872{
6873 char buf[MAX_CMD_LEN];
6874 const char *parameter = get_param(cmd, "Parameter");
6875
6876 if (!parameter)
6877 return -1;
6878
6879 if (strcasecmp(parameter, "RSSI") == 0) {
6880 char rssi[10];
6881
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006882 if (get_wpa_signal_poll(dut, get_station_ifname(dut), "RSSI",
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07006883 rssi, sizeof(rssi)) < 0) {
6884 sigma_dut_print(dut, DUT_MSG_ERROR,
6885 "Could not get RSSI");
6886 return -2;
6887 }
6888
6889 snprintf(buf, sizeof(buf), "rssi,%s", rssi);
6890 sigma_dut_print(dut, DUT_MSG_INFO, "RSSI %s", buf);
6891 send_resp(dut, conn, SIGMA_COMPLETE, buf);
6892 return 0;
6893 }
6894
6895 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
6896 return 0;
6897}
6898
6899
Veerendranath Jakkamd0ad6ef2020-05-21 17:09:26 +05306900#ifdef NL80211_SUPPORT
6901
6902struct station_info {
6903 uint64_t filled;
6904 uint32_t beacon_mic_error_count;
6905 uint32_t beacon_replay_count;
6906};
6907
6908
6909static int qca_get_sta_info_handler(struct nl_msg *msg, void *arg)
6910{
6911 struct nlattr *tb[NL80211_ATTR_MAX + 1];
6912 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
6913 struct station_info *data = arg;
6914 struct nlattr *info[QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAX + 1];
6915 static struct nla_policy info_policy[
6916 QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAX + 1] = {
6917 [QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_MIC_ERROR_COUNT] = {
6918 .type = NLA_U32
6919 },
6920 [QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT] = {
6921 .type = NLA_U32
6922 },
6923 };
6924
6925 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
6926 genlmsg_attrlen(gnlh, 0), NULL);
6927
6928 if (!tb[NL80211_ATTR_VENDOR_DATA])
6929 return NL_SKIP;
6930
6931 if (nla_parse_nested(info, QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAX,
6932 tb[NL80211_ATTR_VENDOR_DATA], info_policy)) {
6933 return NL_SKIP;
6934 }
6935
6936 if (info[QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_MIC_ERROR_COUNT]) {
6937 data->filled |=
6938 BIT_ULL(QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_MIC_ERROR_COUNT);
6939 data->beacon_mic_error_count =
6940 nla_get_u32(info[QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_MIC_ERROR_COUNT]);
6941 }
6942
6943 if (info[QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT]) {
6944 data->filled |=
6945 BIT_ULL(QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT);
6946 data->beacon_replay_count =
6947 nla_get_u32(info[QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT]);
6948 }
6949
6950 return NL_SKIP;
6951}
6952
6953
6954static int qca_nl80211_get_sta_info(struct sigma_dut *dut, const char *intf,
6955 struct station_info *sta_data)
6956{
6957 struct nl_msg *msg;
6958 int ifindex, ret;
6959
6960 ifindex = if_nametoindex(intf);
6961 if (ifindex == 0) {
6962 sigma_dut_print(dut, DUT_MSG_ERROR,
6963 "%s: Index for interface %s not found",
6964 __func__, intf);
6965 return -1;
6966 }
6967
6968 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6969 NL80211_CMD_VENDOR)) ||
6970 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6971 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6972 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6973 QCA_NL80211_VENDOR_SUBCMD_GET_STA_INFO)) {
6974 sigma_dut_print(dut, DUT_MSG_ERROR,
6975 "%s: err in adding vendor_cmd", __func__);
6976 nlmsg_free(msg);
6977 return -1;
6978 }
6979
6980 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg,
6981 qca_get_sta_info_handler, sta_data);
6982 if (ret) {
6983 sigma_dut_print(dut, DUT_MSG_ERROR,
6984 "%s: err in send_and_recv_msgs, ret=%d",
6985 __func__, ret);
6986 }
6987 return ret;
6988}
6989#endif /* NL80211_SUPPORT */
6990
6991
6992static int get_bip_mic_error_count(struct sigma_dut *dut,
6993 const char *ifname,
6994 unsigned int *count)
6995{
6996#ifdef NL80211_SUPPORT
6997 struct station_info sta_data;
6998#endif /* NL80211_SUPPORT */
6999
7000 if (get_driver_type(dut) != DRIVER_WCN) {
7001 sigma_dut_print(dut, DUT_MSG_ERROR,
7002 "BIP MIC error count not supported");
7003 return -1;
7004 }
7005
7006#ifdef NL80211_SUPPORT
7007 if (qca_nl80211_get_sta_info(dut, ifname, &sta_data) != 0 ||
7008 !(sta_data.filled &
7009 BIT_ULL(QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_MIC_ERROR_COUNT))) {
7010 sigma_dut_print(dut, DUT_MSG_ERROR,
7011 "BIP MIC error count fetching failed");
7012 return -1;
7013 }
7014
7015 *count = sta_data.beacon_mic_error_count;
7016 return 0;
7017#else /* NL80211_SUPPORT */
7018 sigma_dut_print(dut, DUT_MSG_ERROR,
7019 "BIP MIC error count cannot be fetched without NL80211_SUPPORT defined");
7020 return -1;
7021#endif /* NL80211_SUPPORT */
7022}
7023
7024
7025static int get_cmac_replay_count(struct sigma_dut *dut, const char *ifname,
7026 unsigned int *count)
7027{
7028#ifdef NL80211_SUPPORT
7029 struct station_info sta_data;
7030#endif /* NL80211_SUPPORT */
7031
7032 if (get_driver_type(dut) != DRIVER_WCN) {
7033 sigma_dut_print(dut, DUT_MSG_ERROR,
7034 "CMAC reply count not supported");
7035 return -1;
7036 }
7037
7038#ifdef NL80211_SUPPORT
7039 if (qca_nl80211_get_sta_info(dut, ifname, &sta_data) != 0 ||
7040 !(sta_data.filled &
7041 BIT_ULL(QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT))) {
7042 sigma_dut_print(dut, DUT_MSG_ERROR,
7043 "CMAC replay count fetching failed");
7044 return -1;
7045 }
7046
7047 *count = sta_data.beacon_replay_count;
7048 return 0;
7049#else /* NL80211_SUPPORT */
7050 sigma_dut_print(dut, DUT_MSG_ERROR,
7051 "CMAC replay count cannot be fetched without NL80211_SUPPORT defined");
7052 return -1;
7053#endif /* NL80211_SUPPORT */
7054}
7055
7056
7057static enum sigma_cmd_result sta_get_parameter_wpa3(struct sigma_dut *dut,
7058 struct sigma_conn *conn,
7059 struct sigma_cmd *cmd)
7060{
7061 char buf[MAX_CMD_LEN];
7062 const char *ifname = get_param(cmd, "interface");
7063 const char *parameter = get_param(cmd, "Parameter");
7064 unsigned int val;
7065
7066 if (!ifname || !parameter)
7067 return INVALID_SEND_STATUS;
7068
7069 if (strcasecmp(parameter, "BIPMICErrors") == 0) {
7070 if (get_bip_mic_error_count(dut, ifname, &val)) {
7071 send_resp(dut, conn, SIGMA_ERROR,
7072 "ErrorCode,Failed to get BIPMICErrors");
7073 return STATUS_SENT_ERROR;
7074 }
7075 snprintf(buf, sizeof(buf), "BIPMICErrors,%d", val);
7076 sigma_dut_print(dut, DUT_MSG_INFO, "BIPMICErrors %s", buf);
7077 send_resp(dut, conn, SIGMA_COMPLETE, buf);
7078 return STATUS_SENT;
7079 }
7080
7081 if (strcasecmp(parameter, "CMACReplays") == 0) {
7082 if (get_cmac_replay_count(dut, ifname, &val)) {
7083 send_resp(dut, conn, SIGMA_ERROR,
7084 "ErrorCode,Failed to get CMACReplays");
7085 return STATUS_SENT_ERROR;
7086 }
7087 snprintf(buf, sizeof(buf), "CMACReplays,%d", val);
7088 sigma_dut_print(dut, DUT_MSG_INFO, "CMACReplays %s", buf);
7089 send_resp(dut, conn, SIGMA_COMPLETE, buf);
7090 return STATUS_SENT;
7091 }
7092
7093 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
7094 return STATUS_SENT_ERROR;
7095}
7096
7097
Jouni Malinenca0abd32020-02-09 20:18:10 +02007098static enum sigma_cmd_result sta_get_pmk(struct sigma_dut *dut,
7099 struct sigma_conn *conn,
7100 struct sigma_cmd *cmd)
7101{
7102 const char *intf = get_param(cmd, "Interface");
7103 char buf[4096], bssid[20], resp[200], *pos, *tmp;
7104
7105 snprintf(buf, sizeof(buf), "PMKSA_GET %d", dut->infra_network_id);
7106 if (wpa_command_resp(intf, buf, buf, sizeof(buf)) < 0 ||
7107 strncmp(buf, "UNKNOWN COMMAND", 15) == 0) {
7108 send_resp(dut, conn, SIGMA_ERROR,
7109 "ErrorCode,PMKSA_GET not supported");
7110 return STATUS_SENT_ERROR;
7111 }
7112
7113 if (strncmp(buf, "FAIL", 4) == 0 ||
7114 get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0) {
7115 send_resp(dut, conn, SIGMA_ERROR,
7116 "ErrorCode,Could not find current network");
7117 return STATUS_SENT_ERROR;
7118 }
7119
7120 pos = buf;
7121 while (pos) {
7122 if (strncmp(pos, bssid, 17) == 0) {
7123 pos = strchr(pos, ' ');
7124 if (!pos)
Mohammad Asaad Akram956bfc32020-04-08 16:26:18 +05307125 break;
Jouni Malinenca0abd32020-02-09 20:18:10 +02007126 pos++;
7127 pos = strchr(pos, ' ');
7128 if (!pos)
Mohammad Asaad Akram956bfc32020-04-08 16:26:18 +05307129 break;
Jouni Malinenca0abd32020-02-09 20:18:10 +02007130 pos++;
7131 tmp = strchr(pos, ' ');
7132 if (!tmp)
Mohammad Asaad Akram956bfc32020-04-08 16:26:18 +05307133 break;
Jouni Malinenca0abd32020-02-09 20:18:10 +02007134 *tmp = '\0';
7135 break;
7136 }
Jouni Malinenca0abd32020-02-09 20:18:10 +02007137 pos = strchr(pos, '\n');
7138 if (pos)
7139 pos++;
7140 }
7141
7142 if (!pos) {
7143 send_resp(dut, conn, SIGMA_ERROR,
7144 "ErrorCode,PMK not available");
7145 return STATUS_SENT_ERROR;
7146 }
7147
7148 snprintf(resp, sizeof(resp), "PMK,%s", pos);
7149 send_resp(dut, conn, SIGMA_COMPLETE, resp);
7150 return STATUS_SENT;
7151}
7152
7153
Jouni Malinenf7222712019-06-13 01:50:21 +03007154static enum sigma_cmd_result cmd_sta_get_parameter(struct sigma_dut *dut,
7155 struct sigma_conn *conn,
7156 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007157{
7158 const char *program = get_param(cmd, "Program");
Jouni Malinenca0abd32020-02-09 20:18:10 +02007159 const char *parameter = get_param(cmd, "Parameter");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007160
Jouni Malinenca0abd32020-02-09 20:18:10 +02007161 if (!parameter)
7162 return INVALID_SEND_STATUS;
7163
7164 if (strcasecmp(parameter, "PMK") == 0)
7165 return sta_get_pmk(dut, conn, cmd);
7166
7167 if (!program)
7168 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007169
7170 if (strcasecmp(program, "P2PNFC") == 0)
7171 return p2p_cmd_sta_get_parameter(dut, conn, cmd);
7172
7173 if (strcasecmp(program, "60ghz") == 0)
7174 return sta_get_parameter_60g(dut, conn, cmd);
7175
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07007176 if (strcasecmp(program, "he") == 0)
7177 return sta_get_parameter_he(dut, conn, cmd);
7178
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007179#ifdef ANDROID_NAN
7180 if (strcasecmp(program, "NAN") == 0)
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07007181 return nan_cmd_sta_get_parameter(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007182#endif /* ANDROID_NAN */
7183
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07007184#ifdef MIRACAST
7185 if (strcasecmp(program, "WFD") == 0 ||
7186 strcasecmp(program, "DisplayR2") == 0)
7187 return miracast_cmd_sta_get_parameter(dut, conn, cmd);
7188#endif /* MIRACAST */
Veerendranath Jakkamd0ad6ef2020-05-21 17:09:26 +05307189 if (strcasecmp(program, "WPA3") == 0)
7190 return sta_get_parameter_wpa3(dut, conn, cmd);
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07007191
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007192 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
7193 return 0;
7194}
7195
7196
7197static void sta_reset_default_ath(struct sigma_dut *dut, const char *intf,
7198 const char *type)
7199{
7200 char buf[100];
7201
7202 if (dut->program == PROGRAM_VHT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07007203 run_iwpriv(dut, intf, "chwidth 2");
7204 run_iwpriv(dut, intf, "mode 11ACVHT80");
7205 run_iwpriv(dut, intf, "vhtmcs -1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007206 }
7207
7208 if (dut->program == PROGRAM_HT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07007209 run_iwpriv(dut, intf, "chwidth 0");
7210 run_iwpriv(dut, intf, "mode 11naht40");
7211 run_iwpriv(dut, intf, "set11NRates 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007212 }
7213
7214 if (dut->program == PROGRAM_VHT || dut->program == PROGRAM_HT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07007215 run_iwpriv(dut, intf, "powersave 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007216
7217 /* Reset CTS width */
7218 snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 54 0",
7219 intf);
7220 if (system(buf) != 0) {
7221 sigma_dut_print(dut, DUT_MSG_ERROR,
7222 "wifitool %s beeliner_fw_test 54 0 failed",
7223 intf);
7224 }
7225
7226 /* Enable Dynamic Bandwidth signalling by default */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07007227 run_iwpriv(dut, intf, "cwmenable 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007228
7229 snprintf(buf, sizeof(buf), "iwconfig %s rts 2347", intf);
7230 if (system(buf) != 0) {
7231 sigma_dut_print(dut, DUT_MSG_ERROR,
7232 "iwpriv rts failed");
7233 }
7234 }
7235
7236 if (type && strcasecmp(type, "Testbed") == 0) {
7237 dut->testbed_flag_txsp = 1;
7238 dut->testbed_flag_rxsp = 1;
7239 /* STA has to set spatial stream to 2 per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07007240 run_iwpriv(dut, intf, "vht_mcsmap 0xfff0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007241
7242 /* Disable LDPC per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07007243 run_iwpriv(dut, intf, "ldpc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007244
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07007245 run_iwpriv(dut, intf, "amsdu 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007246
7247 /* TODO: Disable STBC 2x1 transmit and receive */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07007248 run_iwpriv(dut, intf, "tx_stbc 0");
7249 run_iwpriv(dut, intf, "rx_stbc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007250
7251 /* STA has to disable Short GI per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07007252 run_iwpriv(dut, intf, "shortgi 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007253 }
7254
7255 if (type && strcasecmp(type, "DUT") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07007256 run_iwpriv(dut, intf, "nss 3");
Arif Hussainac6c5112018-05-25 17:34:00 -07007257 dut->sta_nss = 3;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007258
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07007259 run_iwpriv(dut, intf, "shortgi 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007260 }
7261}
7262
7263
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08007264#ifdef NL80211_SUPPORT
7265static int sta_set_he_mcs(struct sigma_dut *dut, const char *intf,
7266 enum he_mcs_config mcs)
7267{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05307268 return wcn_wifi_test_config_set_u8(
7269 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MCS, mcs);
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08007270}
7271#endif /* NL80211_SUPPORT */
7272
7273
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07007274static int sta_set_action_tx_in_he_tb_ppdu(struct sigma_dut *dut,
7275 const char *intf, int enable)
7276{
7277#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05307278 return wcn_wifi_test_config_set_u8(
7279 dut, intf,
7280 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_ACTION_TX_TB_PPDU,
7281 enable);
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07007282#else /* NL80211_SUPPORT */
7283 sigma_dut_print(dut, DUT_MSG_ERROR,
7284 "HE action Tx TB PPDU cannot be set without NL80211_SUPPORT defined");
7285 return -1;
7286#endif /* NL80211_SUPPORT */
7287}
7288
7289
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08007290static int sta_set_heconfig_and_wep_tkip(struct sigma_dut *dut,
7291 const char *intf, int enable)
7292{
7293#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05307294 return wcn_wifi_test_config_set_u8(
7295 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WEP_TKIP_IN_HE,
7296 enable);
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08007297#else /* NL80211_SUPPORT */
7298 sigma_dut_print(dut, DUT_MSG_ERROR,
7299 "HE config enablement cannot be changed without NL80211_SUPPORT defined");
7300 return -1;
7301#endif /* NL80211_SUPPORT */
7302}
7303
7304
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08007305#ifdef NL80211_SUPPORT
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08007306
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08007307static int sta_set_he_testbed_def(struct sigma_dut *dut,
7308 const char *intf, int cfg)
7309{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05307310 return wcn_wifi_test_config_set_u8(
7311 dut, intf,
7312 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_SET_HE_TESTBED_DEFAULTS,
7313 cfg);
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08007314}
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08007315
7316
7317static int sta_set_2g_vht_supp(struct sigma_dut *dut, const char *intf, int cfg)
7318{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05307319 return wcn_wifi_test_config_set_u8(
7320 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_2G_VHT,
7321 cfg);
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08007322}
7323
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08007324#endif /* NL80211_SUPPORT */
7325
7326
Qiwei Caib6806972020-01-15 13:52:11 +08007327int sta_set_addba_buf_size(struct sigma_dut *dut,
7328 const char *intf, int bufsize)
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08007329{
7330#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05307331 return wcn_wifi_test_config_set_u16(
7332 dut, intf,
7333 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE, bufsize);
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08007334#else /* NL80211_SUPPORT */
7335 sigma_dut_print(dut, DUT_MSG_ERROR,
7336 "AddBA bufsize cannot be changed without NL80211_SUPPORT defined");
7337 return -1;
7338#endif /* NL80211_SUPPORT */
7339}
7340
7341
Kiran Kumar Lokere69d89952021-08-08 23:41:46 -07007342static int sta_set_scan_unicast_probe(struct sigma_dut *dut,
7343 const char *intf, int val)
7344{
7345#ifdef NL80211_SUPPORT
7346 return wcn_wifi_test_config_set_u8(
7347 dut, intf,
7348 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_USE_BSSID_IN_PROBE_REQ_RA,
7349 val);
7350#else /* NL80211_SUPPORT */
7351 sigma_dut_print(dut, DUT_MSG_ERROR,
7352 "Unicast RA in Probe Request frame cannot be set without NL80211_SUPPORT defined");
7353 return -1;
7354#endif /* NL80211_SUPPORT */
7355}
7356
7357
Kiran Kumar Lokere09dbcef2021-08-09 00:01:41 -07007358static int sta_set_rx_ctrl_multi_bss(struct sigma_dut *dut, const char *intf,
7359 int enable)
7360{
7361#ifdef NL80211_SUPPORT
7362 return wcn_wifi_test_config_set_u8(
7363 dut, intf,
7364 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_RX_CTRL_FRAME_TO_MBSS,
7365 enable);
7366#else /* NL80211_SUPPORT */
7367 sigma_dut_print(dut, DUT_MSG_ERROR,
7368 "Rx ctrl frame to Multi-BSS cannot be changed without NL80211_SUPPORT defined");
7369 return -1;
7370#endif /* NL80211_SUPPORT */
7371}
7372
7373
7374static int sta_set_bcast_twt_support(struct sigma_dut *dut, const char *intf,
7375 int enable)
7376{
7377#ifdef NL80211_SUPPORT
7378 return wcn_wifi_test_config_set_u8(
7379 dut, intf,
7380 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BCAST_TWT_SUPPORT,
7381 enable);
7382#else /* NL80211_SUPPORT */
7383 sigma_dut_print(dut, DUT_MSG_ERROR,
7384 "BCAST TWT cannot be changed without NL80211_SUPPORT defined");
7385 return -1;
7386#endif /* NL80211_SUPPORT */
7387}
7388
7389
Arif Hussain8d5b27b2018-05-14 14:31:03 -07007390static int sta_set_tx_beamformee(struct sigma_dut *dut, const char *intf,
7391 int enable)
7392{
7393#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05307394 return wcn_wifi_test_config_set_u8(
7395 dut, intf,
7396 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_TX_BEAMFORMEE,
7397 enable);
Arif Hussain8d5b27b2018-05-14 14:31:03 -07007398#else /* NL80211_SUPPORT */
7399 sigma_dut_print(dut, DUT_MSG_ERROR,
7400 "tx beamformee cannot be changed without NL80211_SUPPORT defined");
7401 return -1;
7402#endif /* NL80211_SUPPORT */
7403}
7404
7405
Arif Hussain9765f7d2018-07-03 08:28:26 -07007406static int sta_set_beamformee_sts(struct sigma_dut *dut, const char *intf,
7407 int val)
7408{
7409#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05307410 return wcn_wifi_test_config_set_u8(
7411 dut, intf,
7412 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_BEAMFORMEE_NSTS,
7413 val);
Arif Hussain9765f7d2018-07-03 08:28:26 -07007414#else /* NL80211_SUPPORT */
7415 sigma_dut_print(dut, DUT_MSG_ERROR,
7416 "beamformee sts cannot be changed without NL80211_SUPPORT defined");
7417 return -1;
7418#endif /* NL80211_SUPPORT */
7419}
7420
7421
Arif Hussain68d23f52018-07-11 13:39:08 -07007422#ifdef NL80211_SUPPORT
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07007423static int sta_set_mac_padding_duration(struct sigma_dut *dut, const char *intf,
7424 enum qca_wlan_he_mac_padding_dur val)
7425{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05307426 return wcn_wifi_test_config_set_u8(
7427 dut, intf,
7428 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MAC_PADDING_DUR, val);
Arif Hussain68d23f52018-07-11 13:39:08 -07007429}
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07007430#endif /* NL80211_SUPPORT */
Arif Hussain68d23f52018-07-11 13:39:08 -07007431
7432
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07007433static int sta_set_tx_su_ppdu_cfg(struct sigma_dut *dut, const char *intf,
7434 int val)
7435{
7436#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05307437 return wcn_wifi_test_config_set_u8(
7438 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_SUPPDU,
7439 val);
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07007440#else /* NL80211_SUPPORT */
7441 sigma_dut_print(dut, DUT_MSG_ERROR,
7442 "Tx SU PPDU cannot be set without NL80211_SUPPORT defined");
7443 return -1;
7444#endif /* NL80211_SUPPORT */
7445}
7446
7447
Kiran Kumar Lokere54b72522021-04-01 00:22:44 -07007448static int sta_set_mgmt_data_tx_disable_cfg(struct sigma_dut *dut,
7449 const char *intf, int val)
7450{
7451#ifdef NL80211_SUPPORT
7452 return wcn_wifi_test_config_set_u8(
7453 dut, intf,
7454 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_DISABLE_DATA_MGMT_RSP_TX,
7455 val);
7456#else /* NL80211_SUPPORT */
7457 sigma_dut_print(dut, DUT_MSG_ERROR,
7458 "Tx disable config cannot be set without NL80211_SUPPORT defined");
7459 return -1;
7460#endif /* NL80211_SUPPORT */
7461}
7462
7463
Kiran Kumar Lokere1809da12021-06-24 00:45:38 -07007464static int sta_set_keep_alive_data_cfg(struct sigma_dut *dut, const char *intf,
7465 int val)
7466{
7467#ifdef NL80211_SUPPORT
7468 return wcn_wifi_test_config_set_u8(
7469 dut, intf,
7470 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_KEEP_ALIVE_FRAME_TYPE,
7471 val);
7472#else /* NL80211_SUPPORT */
7473 sigma_dut_print(dut, DUT_MSG_ERROR,
7474 "Keep alive data type cannot be set without NL80211_SUPPORT defined");
7475 return -1;
7476#endif /* NL80211_SUPPORT */
7477}
7478
7479
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07007480#ifdef NL80211_SUPPORT
7481static int sta_set_he_om_ctrl_reset(struct sigma_dut *dut, const char *intf)
7482{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05307483 return wcn_wifi_test_config_set_flag(
7484 dut, intf,
7485 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_CLEAR_HE_OM_CTRL_CONFIG);
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07007486}
7487#endif /* NL80211_SUPPORT */
7488
7489
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07007490static int sta_set_mu_edca_override(struct sigma_dut *dut, const char *intf,
7491 int val)
7492{
7493#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05307494 return wcn_wifi_test_config_set_u8(
7495 dut, intf,
7496 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_OVERRIDE_MU_EDCA, val);
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07007497#else /* NL80211_SUPPORT */
7498 sigma_dut_print(dut, DUT_MSG_ERROR,
7499 "MU EDCA override cannot be changed without NL80211_SUPPORT defined");
7500 return -1;
7501#endif /* NL80211_SUPPORT */
7502}
7503
7504
Kiran Kumar Lokerefa7c7b92021-08-09 00:50:55 -07007505static int sta_set_er_su_ppdu_type_tx(struct sigma_dut *dut, const char *intf,
7506 int val)
7507{
7508#ifdef NL80211_SUPPORT
7509 return wcn_wifi_test_config_set_u8(
7510 dut, intf,
7511 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ER_SU_PPDU_TYPE, val);
7512#else /* NL80211_SUPPORT */
7513 sigma_dut_print(dut, DUT_MSG_ERROR,
7514 "ER-SU PPDU type cannot be set without NL80211_SUPPORT defined");
7515 return -1;
7516#endif /* NL80211_SUPPORT */
7517}
7518
7519
7520static int sta_set_ru_242_tone_tx(struct sigma_dut *dut, const char *intf,
7521 int val)
7522{
7523#ifdef NL80211_SUPPORT
7524 return wcn_wifi_test_config_set_u8(
7525 dut, intf,
7526 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_RU_242_TONE_TX, val);
7527#else /* NL80211_SUPPORT */
7528 sigma_dut_print(dut, DUT_MSG_ERROR,
7529 "RU 242 tone cannot be set without NL80211_SUPPORT defined");
7530 return -1;
7531#endif /* NL80211_SUPPORT */
7532}
7533
7534
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07007535static int sta_set_om_ctrl_supp(struct sigma_dut *dut, const char *intf,
7536 int val)
7537{
7538#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05307539 return wcn_wifi_test_config_set_u8(
7540 dut, intf,
7541 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OM_CTRL_SUPP, val);
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07007542#else /* NL80211_SUPPORT */
7543 sigma_dut_print(dut, DUT_MSG_ERROR,
7544 "HE OM ctrl cannot be changed without NL80211_SUPPORT defined");
7545 return -1;
7546#endif /* NL80211_SUPPORT */
7547}
7548
7549
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07007550#ifdef NL80211_SUPPORT
7551
7552struct features_info {
7553 unsigned char flags[8];
7554 size_t flags_len;
7555};
7556
7557static int features_info_handler(struct nl_msg *msg, void *arg)
7558{
7559 struct nlattr *tb[NL80211_ATTR_MAX + 1];
7560 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
7561 struct features_info *info = arg;
7562 struct nlattr *nl_vend, *attr;
7563
7564 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
7565 genlmsg_attrlen(gnlh, 0), NULL);
7566
7567 nl_vend = tb[NL80211_ATTR_VENDOR_DATA];
7568 if (nl_vend) {
7569 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_MAX + 1];
7570
7571 nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_MAX,
7572 nla_data(nl_vend), nla_len(nl_vend), NULL);
7573
7574 attr = tb_vendor[QCA_WLAN_VENDOR_ATTR_FEATURE_FLAGS];
7575 if (attr) {
7576 int len = nla_len(attr);
7577
Vamsi Krishna79a91132021-08-16 21:40:22 +05307578 if (info && len <= sizeof(info->flags)) {
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07007579 memcpy(info->flags, nla_data(attr), len);
7580 info->flags_len = len;
7581 }
7582 }
7583 }
7584
7585 return NL_SKIP;
7586}
7587
7588
7589static int check_feature(enum qca_wlan_vendor_features feature,
7590 struct features_info *info)
7591{
7592 size_t idx = feature / 8;
7593
Vamsi Krishna79a91132021-08-16 21:40:22 +05307594 if (!info)
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07007595 return 0;
7596
7597 return (idx < info->flags_len) &&
7598 (info->flags[idx] & BIT(feature % 8));
7599}
7600
7601#endif /* NL80211_SUPPORT */
7602
7603
7604static void sta_get_twt_feature_async_supp(struct sigma_dut *dut,
7605 const char *intf)
7606{
7607#ifdef NL80211_SUPPORT
7608 struct nl_msg *msg;
7609 struct features_info info = { 0 };
7610 int ifindex, ret;
7611
7612 ifindex = if_nametoindex(intf);
7613 if (ifindex == 0) {
7614 sigma_dut_print(dut, DUT_MSG_ERROR,
7615 "%s: Index for interface %s failed",
7616 __func__, intf);
7617 return;
7618 }
7619
7620 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7621 NL80211_CMD_VENDOR)) ||
7622 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7623 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7624 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7625 QCA_NL80211_VENDOR_SUBCMD_GET_FEATURES)) {
7626 sigma_dut_print(dut, DUT_MSG_ERROR,
7627 "%s: err in adding vendor_cmd and vendor_data",
7628 __func__);
7629 nlmsg_free(msg);
7630 return;
7631 }
7632
7633 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, features_info_handler,
7634 &info);
7635 if (ret) {
7636 sigma_dut_print(dut, DUT_MSG_ERROR,
7637 "%s: err in send_and_recv_msgs, ret=%d",
7638 __func__, ret);
7639 return;
7640 }
7641
7642 if (check_feature(QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT, &info))
7643 dut->sta_async_twt_supp = 1;
7644 else
7645 dut->sta_async_twt_supp = 0;
7646
7647 sigma_dut_print(dut, DUT_MSG_DEBUG,
7648 "%s: sta_async_twt_supp %d",
7649 __func__, dut->sta_async_twt_supp);
7650#else /* NL80211_SUPPORT */
7651 sigma_dut_print(dut, DUT_MSG_INFO,
7652 "TWT async supp get cannot be done without NL80211_SUPPORT defined");
7653 dut->sta_async_twt_supp = 0;
7654#endif /* NL80211_SUPPORT */
7655}
7656
7657
Arif Hussain480d5f42019-03-12 14:40:42 -07007658static int sta_set_twt_req_support(struct sigma_dut *dut, const char *intf,
7659 int val)
7660{
7661#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05307662 return wcn_wifi_test_config_set_u8(
7663 dut, intf,
7664 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TWT_REQ_SUPPORT, val);
Arif Hussain480d5f42019-03-12 14:40:42 -07007665#else /* NL80211_SUPPORT */
7666 sigma_dut_print(dut, DUT_MSG_ERROR,
7667 "TWT Request cannot be changed without NL80211_SUPPORT defined");
7668 return -1;
7669#endif /* NL80211_SUPPORT */
7670}
7671
7672
Kiran Kumar Lokere4f2d4b02021-04-01 00:07:39 -07007673static int sta_set_bss_max_idle_period(struct sigma_dut *dut, const char *intf,
7674 int val)
7675{
7676#ifdef NL80211_SUPPORT
7677 return wcn_wifi_test_config_set_u16(
7678 dut, intf,
7679 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BSS_MAX_IDLE_PERIOD, val);
7680#else /* NL80211_SUPPORT */
7681 sigma_dut_print(dut, DUT_MSG_ERROR,
7682 "BSS max idle period cannot be set without NL80211_SUPPORT defined");
7683 return -1;
7684#endif /* NL80211_SUPPORT */
7685}
7686
7687
Kiran Kumar Lokere07ad92b2021-08-09 00:27:14 -07007688static int sta_set_bss_max_idle_support(struct sigma_dut *dut, const char *intf,
7689 int val)
7690{
7691#ifdef NL80211_SUPPORT
7692 return wcn_wifi_test_config_set_u8(
7693 dut, intf,
7694 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BSS_MAX_IDLE_PERIOD_ENABLE,
7695 val);
7696#else /* NL80211_SUPPORT */
7697 sigma_dut_print(dut, DUT_MSG_ERROR,
7698 "BSS max idle support cannot be set without NL80211_SUPPORT defined");
7699 return -1;
7700#endif /* NL80211_SUPPORT */
7701}
7702
7703
Srinivas Girigowda0525e292020-11-12 13:28:21 -08007704static int sta_set_fullbw_ulmumimo(struct sigma_dut *dut, const char *intf,
7705 int val)
7706{
7707#ifdef NL80211_SUPPORT
7708 return wcn_wifi_test_config_set_u8(
7709 dut, intf,
7710 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_FULL_BW_UL_MU_MIMO, val);
7711#else /* NL80211_SUPPORT */
7712 sigma_dut_print(dut, DUT_MSG_ERROR,
7713 "Full BW UL MU MIMO cannot be changed without NL80211_SUPPORT defined");
7714 return -1;
7715#endif /* NL80211_SUPPORT */
7716}
7717
7718
Kiran Kumar Lokered0ec5ed2021-04-01 00:15:04 -07007719static int sta_set_punctured_preamble_rx(struct sigma_dut *dut,
7720 const char *intf, int val)
7721{
7722#ifdef NL80211_SUPPORT
7723 return wcn_wifi_test_config_set_u8(
7724 dut, intf,
7725 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_PUNCTURED_PREAMBLE_RX,
7726 val);
7727#else /* NL80211_SUPPORT */
7728 sigma_dut_print(dut, DUT_MSG_ERROR,
7729 "Punctured preamble Rx cannot be set without NL80211_SUPPORT defined");
7730 return -1;
7731#endif /* NL80211_SUPPORT */
7732}
7733
7734
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08007735static void sta_reset_default_wcn(struct sigma_dut *dut, const char *intf,
7736 const char *type)
7737{
7738 char buf[60];
7739
7740 if (dut->program == PROGRAM_HE) {
7741 /* resetting phymode to auto in case of HE program */
Vinita S. Maloo13a5cf72020-05-22 14:45:06 +05307742 sta_set_phymode(dut, intf, "auto");
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08007743
Amarnath Hullur Subramanyam9cecb502018-04-25 13:26:30 -07007744 /* reset the rate to Auto rate */
7745 snprintf(buf, sizeof(buf), "iwpriv %s set_11ax_rate 0xff",
7746 intf);
7747 if (system(buf) != 0) {
7748 sigma_dut_print(dut, DUT_MSG_ERROR,
7749 "iwpriv %s set_11ax_rate 0xff failed",
7750 intf);
7751 }
7752
Kiran Kumar Lokere86cfe3a2018-06-01 11:55:15 -07007753 /* reset the LDPC setting */
7754 snprintf(buf, sizeof(buf), "iwpriv %s ldpc 1", intf);
7755 if (system(buf) != 0) {
7756 sigma_dut_print(dut, DUT_MSG_ERROR,
7757 "iwpriv %s ldpc 1 failed", intf);
7758 }
7759
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08007760 /* reset the power save setting */
Vinita S. Malooa8b62722020-04-23 01:45:41 +05307761 set_power_save_wcn(dut, intf, 2);
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08007762
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08007763 /* remove all network profiles */
7764 remove_wpa_networks(intf);
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08007765
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08007766 /* Configure ADDBA Req/Rsp buffer size to be 64 */
7767 sta_set_addba_buf_size(dut, intf, 64);
7768
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07007769 if (dut->sta_async_twt_supp == -1)
7770 sta_get_twt_feature_async_supp(dut, intf);
7771
Kiran Kumar Lokere69d89952021-08-08 23:41:46 -07007772 sta_set_scan_unicast_probe(dut, intf, 0);
7773
Amarnath Hullur Subramanyam5f32d572018-03-02 00:02:33 -08007774#ifdef NL80211_SUPPORT
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08007775 /* Reset the device HE capabilities to its default supported
7776 * configuration. */
7777 sta_set_he_testbed_def(dut, intf, 0);
7778
Amarnath Hullur Subramanyam5f32d572018-03-02 00:02:33 -08007779 /* Disable noackpolicy for all AC */
7780 if (nlvendor_sta_set_noack(dut, intf, 0, QCA_WLAN_AC_ALL)) {
7781 sigma_dut_print(dut, DUT_MSG_ERROR,
7782 "Disable of noackpolicy for all AC failed");
7783 }
7784#endif /* NL80211_SUPPORT */
7785
Amarnath Hullur Subramanyamb1724a52018-03-07 14:31:46 -08007786 /* Enable WMM by default */
7787 if (wcn_sta_set_wmm(dut, intf, "on")) {
7788 sigma_dut_print(dut, DUT_MSG_ERROR,
7789 "Enable of WMM in sta_reset_default_wcn failed");
7790 }
7791
7792 /* Disable ADDBA_REJECT by default */
7793 if (nlvendor_sta_set_addba_reject(dut, intf, 0)) {
7794 sigma_dut_print(dut, DUT_MSG_ERROR,
7795 "Disable of addba_reject in sta_reset_default_wcn failed");
7796 }
7797
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08007798 /* Enable sending of ADDBA by default */
7799 if (nlvendor_config_send_addba(dut, intf, 1)) {
7800 sigma_dut_print(dut, DUT_MSG_ERROR,
7801 "Enable sending of ADDBA in sta_reset_default_wcn failed");
7802 }
7803
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08007804 /* Enable AMPDU by default */
7805 iwpriv_sta_set_ampdu(dut, intf, 1);
7806
Subhani Shaik8e7a3052018-04-24 14:03:00 -07007807#ifdef NL80211_SUPPORT
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -08007808 if (wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_AUTO)) {
Subhani Shaik8e7a3052018-04-24 14:03:00 -07007809 sigma_dut_print(dut, DUT_MSG_ERROR,
7810 "Set LTF config to default in sta_reset_default_wcn failed");
7811 }
Arif Hussain9765f7d2018-07-03 08:28:26 -07007812
Kiran Kumar Lokerebad51122018-12-12 19:03:36 -08007813 /* set the beamformee NSTS(maximum number of
7814 * space-time streams) to default DUT config
7815 */
7816 if (sta_set_beamformee_sts(dut, intf, 7)) {
Arif Hussain9765f7d2018-07-03 08:28:26 -07007817 sigma_dut_print(dut, DUT_MSG_ERROR,
7818 "Failed to set BeamformeeSTS");
7819 }
Arif Hussain68d23f52018-07-11 13:39:08 -07007820
Kiran Kumar Lokere54b72522021-04-01 00:22:44 -07007821 if (sta_set_mgmt_data_tx_disable_cfg(dut, intf, 0)) {
7822 sigma_dut_print(dut, DUT_MSG_ERROR,
7823 "Failed to reset mgmt/data Tx disable config");
7824 }
7825
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07007826 if (sta_set_mac_padding_duration(
7827 dut, intf,
7828 QCA_WLAN_HE_NO_ADDITIONAL_PROCESS_TIME)) {
Arif Hussain68d23f52018-07-11 13:39:08 -07007829 sigma_dut_print(dut, DUT_MSG_ERROR,
7830 "Failed to set MAC padding duration");
7831 }
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07007832
7833 if (sta_set_mu_edca_override(dut, intf, 0)) {
7834 sigma_dut_print(dut, DUT_MSG_ERROR,
7835 "ErrorCode,Failed to set MU EDCA override disable");
7836 }
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07007837
Kiran Kumar Lokerefa7c7b92021-08-09 00:50:55 -07007838 if (sta_set_ru_242_tone_tx(dut, intf, 0)) {
7839 sigma_dut_print(dut, DUT_MSG_ERROR,
7840 "Failed to set RU 242 tone Tx");
7841 }
7842
7843 if (sta_set_er_su_ppdu_type_tx(dut, intf, 0)) {
7844 sigma_dut_print(dut, DUT_MSG_ERROR,
7845 "Failed to set ER-SU PPDU type Tx");
7846 }
7847
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07007848 if (sta_set_om_ctrl_supp(dut, intf, 1)) {
7849 sigma_dut_print(dut, DUT_MSG_ERROR,
7850 "Failed to set OM ctrl supp");
7851 }
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07007852
7853 if (sta_set_tx_su_ppdu_cfg(dut, intf, 1)) {
7854 sigma_dut_print(dut, DUT_MSG_ERROR,
7855 "Failed to set Tx SU PPDU enable");
7856 }
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07007857
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07007858 if (sta_set_action_tx_in_he_tb_ppdu(dut, intf, 0)) {
7859 sigma_dut_print(dut, DUT_MSG_ERROR,
7860 "failed to send TB PPDU Tx cfg");
7861 }
7862
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07007863 if (sta_set_he_om_ctrl_reset(dut, intf)) {
7864 sigma_dut_print(dut, DUT_MSG_ERROR,
7865 "Failed to set OM ctrl reset");
7866 }
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08007867
7868 /* +HTC-HE support default on */
7869 if (sta_set_he_htc_supp(dut, intf, 1)) {
7870 sigma_dut_print(dut, DUT_MSG_ERROR,
7871 "Setting of +HTC-HE support failed");
7872 }
Subhani Shaik8e7a3052018-04-24 14:03:00 -07007873#endif /* NL80211_SUPPORT */
7874
Arif Hussain8d5b27b2018-05-14 14:31:03 -07007875 if (sta_set_tx_beamformee(dut, intf, 1)) {
7876 sigma_dut_print(dut, DUT_MSG_ERROR,
7877 "Set tx beamformee enable by default in sta_reset_default_wcn failed");
7878 }
7879
Kiran Kumar Lokereb55ff442020-07-15 00:20:40 -07007880 wpa_command(intf, "SET oce 1");
7881
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08007882 /* Set nss to 1 and MCS 0-7 in case of testbed */
7883 if (type && strcasecmp(type, "Testbed") == 0) {
7884#ifdef NL80211_SUPPORT
7885 int ret;
7886#endif /* NL80211_SUPPORT */
7887
Kiran Kumar Lokereb55ff442020-07-15 00:20:40 -07007888 wpa_command(intf, "SET oce 0");
7889
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08007890 snprintf(buf, sizeof(buf), "iwpriv %s nss 1", intf);
7891 if (system(buf) != 0) {
7892 sigma_dut_print(dut, DUT_MSG_ERROR,
7893 "iwpriv %s nss failed", intf);
7894 }
7895
7896#ifdef NL80211_SUPPORT
7897 ret = sta_set_he_mcs(dut, intf, HE_80_MCS0_7);
7898 if (ret) {
7899 sigma_dut_print(dut, DUT_MSG_ERROR,
7900 "Setting of MCS failed, ret:%d",
7901 ret);
7902 }
7903#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyamc67621d2018-02-04 23:18:01 -08007904
7905 /* Disable STBC as default */
7906 wcn_sta_set_stbc(dut, intf, "0");
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08007907
7908 /* Disable AMSDU as default */
7909 iwpriv_sta_set_amsdu(dut, intf, "0");
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08007910
7911#ifdef NL80211_SUPPORT
7912 /* HE fragmentation default off */
7913 if (sta_set_he_fragmentation(dut, intf,
7914 HE_FRAG_DISABLE)) {
7915 sigma_dut_print(dut, DUT_MSG_ERROR,
7916 "Setting of HE fragmentation failed");
7917 }
Kiran Kumar Lokerebad51122018-12-12 19:03:36 -08007918
7919 /* set the beamformee NSTS(maximum number of
7920 * space-time streams) to default testbed config
7921 */
7922 if (sta_set_beamformee_sts(dut, intf, 3)) {
7923 sigma_dut_print(dut, DUT_MSG_ERROR,
7924 "Failed to set BeamformeeSTS");
7925 }
7926
Kiran Kumar Lokered0ec5ed2021-04-01 00:15:04 -07007927 if (sta_set_punctured_preamble_rx(dut, intf, 0)) {
7928 sigma_dut_print(dut, DUT_MSG_ERROR,
7929 "Failed to reset PreamblePunctRx support");
7930 }
7931
Kiran Kumar Lokere727687f2021-06-24 00:35:49 -07007932 if (sta_set_bss_max_idle_period(dut, intf, 0)) {
7933 sigma_dut_print(dut, DUT_MSG_ERROR,
7934 "Failed to reset BSS max idle period");
7935 }
7936
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08007937 /* +HTC-HE support default off */
7938 if (sta_set_he_htc_supp(dut, intf, 0)) {
7939 sigma_dut_print(dut, DUT_MSG_ERROR,
7940 "Setting of +HTC-HE support failed");
7941 }
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08007942
7943 /* Set device HE capabilities to testbed default
7944 * configuration. */
7945 if (sta_set_he_testbed_def(dut, intf, 1)) {
7946 sigma_dut_print(dut, DUT_MSG_DEBUG,
7947 "Failed to set HE defaults");
7948 }
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08007949
7950 /* Disable VHT support in 2.4 GHz for testbed */
7951 sta_set_2g_vht_supp(dut, intf, 0);
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08007952#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08007953
7954 /* Enable WEP/TKIP with HE capability in testbed */
7955 if (sta_set_heconfig_and_wep_tkip(dut, intf, 1)) {
7956 sigma_dut_print(dut, DUT_MSG_ERROR,
7957 "Enabling HE config with WEP/TKIP failed");
7958 }
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08007959 }
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08007960
7961 /* Defaults in case of DUT */
7962 if (type && strcasecmp(type, "DUT") == 0) {
Arif Hussaind48fcc72018-05-01 18:34:18 -07007963 /* Enable STBC by default */
7964 wcn_sta_set_stbc(dut, intf, "1");
7965
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08007966 /* set nss to 2 */
7967 snprintf(buf, sizeof(buf), "iwpriv %s nss 2", intf);
7968 if (system(buf) != 0) {
7969 sigma_dut_print(dut, DUT_MSG_ERROR,
7970 "iwpriv %s nss 2 failed", intf);
7971 }
Arif Hussainac6c5112018-05-25 17:34:00 -07007972 dut->sta_nss = 2;
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08007973
7974#ifdef NL80211_SUPPORT
Arif Hussainae239842018-05-01 18:20:05 -07007975 /* Set HE_MCS to 0-11 */
7976 if (sta_set_he_mcs(dut, intf, HE_80_MCS0_11)) {
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08007977 sigma_dut_print(dut, DUT_MSG_ERROR,
7978 "Setting of MCS failed");
7979 }
7980#endif /* NL80211_SUPPORT */
7981
7982 /* Disable WEP/TKIP with HE capability in DUT */
7983 if (sta_set_heconfig_and_wep_tkip(dut, intf, 0)) {
7984 sigma_dut_print(dut, DUT_MSG_ERROR,
7985 "Enabling HE config with WEP/TKIP failed");
7986 }
7987 }
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08007988 }
7989}
7990
7991
Veerendranath Jakkam47867202020-12-21 01:53:52 +05307992static int sta_set_client_privacy(struct sigma_dut *dut,
7993 struct sigma_conn *conn, const char *intf,
7994 int enable)
7995{
7996 if (enable &&
7997 (wpa_command(intf, "SET mac_addr 1") < 0 ||
7998 wpa_command(intf, "SET rand_addr_lifetime 1") < 0 ||
Veerendranath Jakkam39fd5c42020-12-21 02:02:21 +05307999 (wpa_command(intf, "MAC_RAND_SCAN enable=1 all") < 0 &&
8000 wpa_command(intf, "SET preassoc_mac_addr 1") < 0) ||
Veerendranath Jakkam47867202020-12-21 01:53:52 +05308001 wpa_command(intf, "SET gas_rand_mac_addr 1") < 0 ||
8002 wpa_command(intf, "SET gas_rand_addr_lifetime 1") < 0))
8003 return -1;
8004
8005 if (!enable &&
8006 (wpa_command(intf, "SET mac_addr 0") < 0 ||
Veerendranath Jakkam39fd5c42020-12-21 02:02:21 +05308007 (wpa_command(intf, "MAC_RAND_SCAN enable=0 all") < 0 &&
8008 wpa_command(intf, "SET preassoc_mac_addr 0") < 0) ||
Veerendranath Jakkam47867202020-12-21 01:53:52 +05308009 wpa_command(intf, "SET gas_rand_mac_addr 0") < 0))
8010 return -1;
8011
8012 dut->client_privacy = enable;
8013 return 0;
8014}
8015
8016
Jouni Malinenf7222712019-06-13 01:50:21 +03008017static enum sigma_cmd_result cmd_sta_reset_default(struct sigma_dut *dut,
8018 struct sigma_conn *conn,
8019 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008020{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008021 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02008022 const char *band = get_param(cmd, "band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008023 const char *type;
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07008024 const char *program = get_param(cmd, "program");
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05308025 const char *dev_role = get_param(cmd, "DevRole");
Veerendranath Jakkamc1f71b62021-01-23 03:09:51 +05308026 char resp[20];
Veerendranath Jakkamea7f0692021-08-11 19:13:12 +05308027 char buf[100];
Veerendranath Jakkamc1f71b62021-01-23 03:09:51 +05308028 int ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008029
Jouni Malinenb21f0542019-11-04 17:53:38 +02008030 if (dut->station_ifname_2g &&
8031 strcmp(dut->station_ifname_2g, intf) == 0)
8032 dut->use_5g = 0;
8033 else if (dut->station_ifname_5g &&
8034 strcmp(dut->station_ifname_5g, intf) == 0)
8035 dut->use_5g = 1;
8036
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07008037 if (!program)
8038 program = get_param(cmd, "prog");
8039 dut->program = sigma_program_to_enum(program);
Vinita S. Maloof7a2cbf2020-11-18 19:29:44 +05308040
8041 if (dut->program == PROGRAM_WFD && dut->user_config_timeout)
8042 dut->default_timeout = dut->user_config_timeout;
8043
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008044 dut->device_type = STA_unknown;
8045 type = get_param(cmd, "type");
8046 if (type && strcasecmp(type, "Testbed") == 0)
8047 dut->device_type = STA_testbed;
8048 if (type && strcasecmp(type, "DUT") == 0)
8049 dut->device_type = STA_dut;
8050
8051 if (dut->program == PROGRAM_TDLS) {
8052 /* Clear TDLS testing mode */
8053 wpa_command(intf, "SET tdls_disabled 0");
8054 wpa_command(intf, "SET tdls_testing 0");
8055 dut->no_tpk_expiration = 0;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02008056 if (get_driver_type(dut) == DRIVER_WCN) {
Pradeep Reddy POTTETI8ce2a232016-10-28 12:17:32 +05308057 /* Enable the WCN driver in TDLS Explicit trigger mode
8058 */
8059 wpa_command(intf, "SET tdls_external_control 0");
8060 wpa_command(intf, "SET tdls_trigger_control 0");
8061 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008062 }
8063
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07008064#ifdef MIRACAST
8065 if (dut->program == PROGRAM_WFD ||
8066 dut->program == PROGRAM_DISPLAYR2)
8067 miracast_sta_reset_default(dut, conn, cmd);
8068#endif /* MIRACAST */
8069
Jouni Malinen016ae6c2019-11-04 17:00:01 +02008070 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008071 case DRIVER_ATHEROS:
8072 sta_reset_default_ath(dut, intf, type);
8073 break;
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08008074 case DRIVER_WCN:
8075 sta_reset_default_wcn(dut, intf, type);
8076 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008077 default:
8078 break;
8079 }
8080
8081#ifdef ANDROID_NAN
8082 if (dut->program == PROGRAM_NAN)
8083 nan_cmd_sta_reset_default(dut, conn, cmd);
8084#endif /* ANDROID_NAN */
8085
Vinay Gannevaram3b9fdd32019-06-14 17:55:44 +05308086 if (dut->program == PROGRAM_LOC &&
8087 lowi_cmd_sta_reset_default(dut, conn, cmd) < 0)
8088 return ERROR_SEND_STATUS;
8089
Jouni Malinenba630452018-06-22 11:49:59 +03008090 if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008091 unlink("SP/wi-fi.org/pps.xml");
8092 if (system("rm -r SP/*") != 0) {
8093 }
8094 unlink("next-client-cert.pem");
8095 unlink("next-client-key.pem");
8096 }
8097
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02008098 /* For WPS program of the 60 GHz band the band type needs to be saved */
8099 if (dut->program == PROGRAM_WPS) {
8100 if (band && strcasecmp(band, "60GHz") == 0) {
8101 dut->band = WPS_BAND_60G;
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02008102 /* For 60 GHz enable WPS for WPS TCs */
8103 dut->wps_disable = 0;
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02008104 } else {
8105 dut->band = WPS_BAND_NON_60G;
8106 }
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02008107 } else if (dut->program == PROGRAM_60GHZ) {
8108 /* For 60 GHz MAC/PHY TCs WPS must be disabled */
8109 dut->wps_disable = 1;
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02008110 }
8111
Alexei Avshalom Lazar157ba062018-12-23 16:15:26 +02008112 if (is_60g_sigma_dut(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008113 const char *dev_role = get_param(cmd, "DevRole");
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02008114 char buf[256];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008115
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02008116 sigma_dut_print(dut, DUT_MSG_INFO,
8117 "WPS 60 GHz program, wps_disable = %d",
8118 dut->wps_disable);
8119
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008120 if (!dev_role) {
8121 send_resp(dut, conn, SIGMA_ERROR,
8122 "errorCode,Missing DevRole argument");
8123 return 0;
8124 }
8125
8126 if (strcasecmp(dev_role, "STA") == 0)
8127 dut->dev_role = DEVROLE_STA;
8128 else if (strcasecmp(dev_role, "PCP") == 0)
8129 dut->dev_role = DEVROLE_PCP;
8130 else {
8131 send_resp(dut, conn, SIGMA_ERROR,
8132 "errorCode,Unknown DevRole");
8133 return 0;
8134 }
8135
8136 if (dut->device_type == STA_unknown) {
8137 sigma_dut_print(dut, DUT_MSG_ERROR,
8138 "Device type is not STA testbed or DUT");
8139 send_resp(dut, conn, SIGMA_ERROR,
8140 "errorCode,Unknown device type");
8141 return 0;
8142 }
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02008143
8144 sigma_dut_print(dut, DUT_MSG_DEBUG,
8145 "Setting msdu_size to MAX: 7912");
8146 snprintf(buf, sizeof(buf), "ifconfig %s mtu 7912",
Jouni Malinen016ae6c2019-11-04 17:00:01 +02008147 get_station_ifname(dut));
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02008148
8149 if (system(buf) != 0) {
8150 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
8151 buf);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02008152 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02008153 }
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02008154
8155 if (sta_set_force_mcs(dut, 0, 1)) {
8156 sigma_dut_print(dut, DUT_MSG_ERROR,
8157 "Failed to reset force MCS");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02008158 return ERROR_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02008159 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008160 }
8161
8162 wpa_command(intf, "WPS_ER_STOP");
8163 wpa_command(intf, "FLUSH");
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05308164 wpa_command(intf, "ERP_FLUSH");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008165 wpa_command(intf, "SET radio_disabled 0");
8166
Alexei Avshalom Lazar744ae8a2019-01-31 17:26:46 +02008167 dut->wps_forced_version = 0;
8168
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02008169 if (dut->wsc_fragment) {
8170 dut->wsc_fragment = 0;
8171 wpa_command(intf, "SET device_name Test client");
8172 wpa_command(intf, "SET manufacturer ");
8173 wpa_command(intf, "SET model_name ");
8174 wpa_command(intf, "SET model_number ");
8175 wpa_command(intf, "SET serial_number ");
8176 }
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02008177 if (is_60g_sigma_dut(dut) && dut->force_rsn_ie) {
8178 dut->force_rsn_ie = FORCE_RSN_IE_NONE;
8179 sta_60g_force_rsn_ie(dut, FORCE_RSN_IE_NONE);
8180 }
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02008181
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008182 if (dut->tmp_mac_addr && dut->set_macaddr) {
8183 dut->tmp_mac_addr = 0;
8184 if (system(dut->set_macaddr) != 0) {
8185 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to clear "
8186 "temporary MAC address");
8187 }
8188 }
8189
8190 set_ps(intf, dut, 0);
8191
Jouni Malinenba630452018-06-22 11:49:59 +03008192 if (dut->program == PROGRAM_HS2 || dut->program == PROGRAM_HS2_R2 ||
8193 dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008194 wpa_command(intf, "SET interworking 1");
8195 wpa_command(intf, "SET hs20 1");
8196 }
8197
Deepak Dhamdhere0fe0e452017-12-18 14:52:09 -08008198 if (dut->program == PROGRAM_HS2_R2 ||
Jouni Malinenba630452018-06-22 11:49:59 +03008199 dut->program == PROGRAM_HS2_R3 ||
Deepak Dhamdhere0fe0e452017-12-18 14:52:09 -08008200 dut->program == PROGRAM_OCE) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008201 wpa_command(intf, "SET pmf 1");
8202 } else {
8203 wpa_command(intf, "SET pmf 0");
8204 }
8205
8206 hs2_clear_credentials(intf);
8207 wpa_command(intf, "SET hessid 00:00:00:00:00:00");
8208 wpa_command(intf, "SET access_network_type 15");
8209
8210 static_ip_file(0, NULL, NULL, NULL);
8211 kill_dhcp_client(dut, intf);
8212 clear_ip_addr(dut, intf);
8213
8214 dut->er_oper_performed = 0;
8215 dut->er_oper_bssid[0] = '\0';
8216
priyadharshini gowthamanad6cbba2016-10-04 10:39:58 -07008217 if (dut->program == PROGRAM_LOC) {
8218 /* Disable Interworking by default */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02008219 wpa_command(get_station_ifname(dut), "SET interworking 0");
priyadharshini gowthamanad6cbba2016-10-04 10:39:58 -07008220 }
8221
Kiran Kumar Lokeredd086642020-06-04 00:29:26 -07008222 if (dut->program == PROGRAM_MBO || dut->program == PROGRAM_HE) {
Ashwini Patil00402582017-04-13 12:29:39 +05308223 free(dut->non_pref_ch_list);
8224 dut->non_pref_ch_list = NULL;
Ashwini Patil5acd7382017-04-13 15:55:04 +05308225 free(dut->btm_query_cand_list);
8226 dut->btm_query_cand_list = NULL;
Ashwini Patilc63161e2017-04-13 16:30:23 +05308227 wpa_command(intf, "SET reject_btm_req_reason 0");
Ashwini Patila75de5a2017-04-13 16:35:05 +05308228 wpa_command(intf, "SET ignore_assoc_disallow 0");
Ashwini Patild174f2c2017-04-13 16:49:46 +05308229 wpa_command(intf, "SET gas_address3 0");
Ashwini Patil9183fdb2017-04-13 16:58:25 +05308230 wpa_command(intf, "SET roaming 1");
Ankita Bajaj1d974552018-09-18 16:56:44 +05308231 wpa_command(intf, "SET interworking 1");
Ashwini Patil00402582017-04-13 12:29:39 +05308232 }
8233
Jouni Malinen3c367e82017-06-23 17:01:47 +03008234 free(dut->rsne_override);
8235 dut->rsne_override = NULL;
8236
Jouni Malinen68143132017-09-02 02:34:08 +03008237 free(dut->sae_commit_override);
8238 dut->sae_commit_override = NULL;
Jouni Malinen4b3769d2019-10-10 16:20:29 +03008239 wpa_command(intf, "SET sae_pmkid_in_assoc 0");
Jouni Malinen11e55212019-11-22 21:46:59 +02008240 dut->sae_pwe = SAE_PWE_DEFAULT;
Jouni Malinen68143132017-09-02 02:34:08 +03008241
Jouni Malinen134fe3c2019-06-12 04:16:49 +03008242 dut->sta_associate_wait_connect = 0;
8243 dut->server_cert_hash[0] = '\0';
Jouni Malinen37d5c692019-08-19 16:56:55 +03008244 dut->server_cert_tod = 0;
Jouni Malinen134fe3c2019-06-12 04:16:49 +03008245 dut->sta_tod_policy = 0;
8246
Jouni Malinend86e5822017-08-29 03:55:32 +03008247 dut->dpp_conf_id = -1;
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02008248 free(dut->dpp_peer_uri);
8249 dut->dpp_peer_uri = NULL;
Jouni Malinen63d50412017-11-24 11:55:38 +02008250 dut->dpp_local_bootstrap = -1;
Jouni Malinen5011fb52017-12-05 21:00:15 +02008251 wpa_command(intf, "SET dpp_config_processing 2");
Jouni Malinen90776b12020-05-04 15:34:46 +03008252 wpa_command(intf, "SET dpp_mud_url ");
Jouni Malinend86e5822017-08-29 03:55:32 +03008253
Jouni Malinenfac9cad2017-10-10 18:35:55 +03008254 wpa_command(intf, "VENDOR_ELEM_REMOVE 13 *");
8255
vamsi krishnaa2799492017-12-05 14:28:01 +05308256 if (dut->program == PROGRAM_OCE) {
Ankita Bajaja2cb5672017-10-25 16:08:28 +05308257 wpa_command(intf, "SET oce 1");
vamsi krishnaa2799492017-12-05 14:28:01 +05308258 wpa_command(intf, "SET disable_fils 0");
Ankita Bajaj1bde7942018-01-09 19:15:01 +05308259 wpa_command(intf, "FILS_HLP_REQ_FLUSH");
8260 dut->fils_hlp = 0;
8261#ifdef ANDROID
8262 hlp_thread_cleanup(dut);
8263#endif /* ANDROID */
vamsi krishnaa2799492017-12-05 14:28:01 +05308264 }
Ankita Bajaja2cb5672017-10-25 16:08:28 +05308265
Veerendranath Jakkamea7f0692021-08-11 19:13:12 +05308266 if (dut->program == PROGRAM_QM) {
Vamsi Krishnaf642d6a2020-03-27 12:33:14 +05308267 wpa_command(intf, "SET interworking 1");
Vinita S. Maloo2287f142021-02-01 16:17:09 +05308268 wpa_command(intf, "SET disable_scs_support 0");
Vinita S. Maloo83dee552021-04-12 16:47:47 +05308269 wpa_command(intf, "SET disable_mscs_support 0");
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +05308270 dut->qm_domain_name[0] = '\0';
Veerendranath Jakkamea7f0692021-08-11 19:13:12 +05308271 snprintf(buf, sizeof(buf),
8272 "ip -6 route replace fe80::/64 dev %s table local",
8273 intf);
8274 if (system(buf) != 0)
8275 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to run: %s",
8276 buf);
8277 }
Vamsi Krishnaf642d6a2020-03-27 12:33:14 +05308278
Jouni Malinen8179fee2019-03-28 03:19:47 +02008279 dut->akm_values = 0;
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03008280 dut->sta_ft_ds = 0;
Jouni Malinen8179fee2019-03-28 03:19:47 +02008281
Sunil Dutt076081f2018-02-05 19:45:50 +05308282#ifdef NL80211_SUPPORT
Jouni Malinen016ae6c2019-11-04 17:00:01 +02008283 if (get_driver_type(dut) == DRIVER_WCN &&
Sunil Dutt44595082018-02-12 19:41:45 +05308284 dut->config_rsnie == 1) {
8285 dut->config_rsnie = 0;
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05308286 sta_config_params(dut, intf, STA_SET_RSNIE, 0);
Sunil Dutt076081f2018-02-05 19:45:50 +05308287 }
8288#endif /* NL80211_SUPPORT */
8289
Sunil Duttfebf8a82018-02-09 18:50:13 +05308290 if (dev_role && strcasecmp(dev_role, "STA-CFON") == 0) {
8291 dut->dev_role = DEVROLE_STA_CFON;
8292 return sta_cfon_reset_default(dut, conn, cmd);
8293 }
8294
Jouni Malinen439352d2018-09-13 03:42:23 +03008295 wpa_command(intf, "SET setband AUTO");
8296
Veerendranath Jakkamc1f71b62021-01-23 03:09:51 +05308297 ret = wpa_command_resp(intf, "GET_CAPABILITY ocv", resp, sizeof(resp));
8298 dut->ocvc = ret == 0 && strncmp(resp, "supported", 9) == 0;
8299
8300 ret = wpa_command_resp(intf, "GET_CAPABILITY beacon_prot", resp,
8301 sizeof(resp));
8302 dut->beacon_prot = ret == 0 && strncmp(resp, "supported", 9) == 0;
8303
Veerendranath Jakkam47867202020-12-21 01:53:52 +05308304 if (sta_set_client_privacy(dut, conn, intf,
8305 dut->program == PROGRAM_WPA3 &&
8306 dut->device_type == STA_dut &&
8307 dut->client_privacy_default)) {
8308 sigma_dut_print(dut, DUT_MSG_ERROR,
8309 "Failed to set client privacy functionality");
8310 /* sta_reset_default command is not really supposed to fail,
8311 * so allow this to continue. */
8312 }
8313
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +05308314 dut->saquery_oci_freq = 0;
Vamsi Krishnac1633d22020-05-06 18:31:21 +05308315
Sunil Duttfebf8a82018-02-09 18:50:13 +05308316 if (dut->program != PROGRAM_VHT)
8317 return cmd_sta_p2p_reset(dut, conn, cmd);
8318
Priyadharshini Gowthamana7dfd492015-11-09 14:34:08 -08008319 return 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008320}
8321
8322
Jouni Malinenf7222712019-06-13 01:50:21 +03008323static enum sigma_cmd_result cmd_sta_get_events(struct sigma_dut *dut,
8324 struct sigma_conn *conn,
8325 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008326{
8327 const char *program = get_param(cmd, "Program");
8328
8329 if (program == NULL)
8330 return -1;
8331#ifdef ANDROID_NAN
8332 if (strcasecmp(program, "NAN") == 0)
8333 return nan_cmd_sta_get_events(dut, conn, cmd);
8334#endif /* ANDROID_NAN */
8335 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
8336 return 0;
8337}
8338
8339
Jouni Malinen82905202018-04-29 17:20:10 +03008340static int sta_exec_action_url(struct sigma_dut *dut, struct sigma_conn *conn,
8341 struct sigma_cmd *cmd)
8342{
8343 const char *url = get_param(cmd, "url");
8344 const char *method = get_param(cmd, "method");
8345 pid_t pid;
8346 int status;
8347
8348 if (!url || !method)
8349 return -1;
8350
8351 /* TODO: Add support for method,post */
8352 if (strcasecmp(method, "get") != 0) {
8353 send_resp(dut, conn, SIGMA_ERROR,
8354 "ErrorCode,Unsupported method");
8355 return 0;
8356 }
8357
8358 pid = fork();
8359 if (pid < 0) {
8360 perror("fork");
8361 return -1;
8362 }
8363
8364 if (pid == 0) {
8365 char * argv[5] = { "wget", "-O", "/dev/null",
8366 (char *) url, NULL };
8367
8368 execv("/usr/bin/wget", argv);
8369 perror("execv");
8370 exit(0);
8371 return -1;
8372 }
8373
8374 if (waitpid(pid, &status, 0) < 0) {
8375 perror("waitpid");
8376 return -1;
8377 }
8378
8379 if (WIFEXITED(status)) {
8380 const char *errmsg;
8381
8382 if (WEXITSTATUS(status) == 0)
8383 return 1;
8384 sigma_dut_print(dut, DUT_MSG_INFO, "wget exit status %d",
8385 WEXITSTATUS(status));
8386 switch (WEXITSTATUS(status)) {
8387 case 4:
8388 errmsg = "errmsg,Network failure";
8389 break;
8390 case 8:
8391 errmsg = "errmsg,Server issued an error response";
8392 break;
8393 default:
8394 errmsg = "errmsg,Unknown failure from wget";
8395 break;
8396 }
8397 send_resp(dut, conn, SIGMA_ERROR, errmsg);
8398 return 0;
8399 }
8400
8401 send_resp(dut, conn, SIGMA_ERROR, "errmsg,Unknown failure");
8402 return 0;
8403}
8404
8405
Jouni Malinenf7222712019-06-13 01:50:21 +03008406static enum sigma_cmd_result cmd_sta_exec_action(struct sigma_dut *dut,
8407 struct sigma_conn *conn,
8408 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008409{
8410 const char *program = get_param(cmd, "Prog");
8411
Jouni Malinen82905202018-04-29 17:20:10 +03008412 if (program && !get_param(cmd, "interface"))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008413 return -1;
8414#ifdef ANDROID_NAN
Jouni Malinen82905202018-04-29 17:20:10 +03008415 if (program && strcasecmp(program, "NAN") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008416 return nan_cmd_sta_exec_action(dut, conn, cmd);
8417#endif /* ANDROID_NAN */
Jouni Malinen82905202018-04-29 17:20:10 +03008418
8419 if (program && strcasecmp(program, "Loc") == 0)
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07008420 return loc_cmd_sta_exec_action(dut, conn, cmd);
Jouni Malinen82905202018-04-29 17:20:10 +03008421
8422 if (get_param(cmd, "url"))
8423 return sta_exec_action_url(dut, conn, cmd);
8424
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008425 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
8426 return 0;
8427}
8428
8429
Jouni Malinenf7222712019-06-13 01:50:21 +03008430static enum sigma_cmd_result cmd_sta_set_11n(struct sigma_dut *dut,
8431 struct sigma_conn *conn,
8432 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008433{
8434 const char *intf = get_param(cmd, "Interface");
8435 const char *val, *mcs32, *rate;
8436
8437 val = get_param(cmd, "GREENFIELD");
8438 if (val) {
8439 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
8440 /* Enable GD */
8441 send_resp(dut, conn, SIGMA_ERROR,
8442 "ErrorCode,GF not supported");
8443 return 0;
8444 }
8445 }
8446
8447 val = get_param(cmd, "SGI20");
8448 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02008449 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008450 case DRIVER_ATHEROS:
8451 ath_sta_set_sgi(dut, intf, val);
8452 break;
8453 default:
8454 send_resp(dut, conn, SIGMA_ERROR,
8455 "ErrorCode,SGI20 not supported");
8456 return 0;
8457 }
8458 }
8459
8460 mcs32 = get_param(cmd, "MCS32"); /* HT Duplicate Mode Enable/Disable */
8461 rate = get_param(cmd, "MCS_FIXEDRATE"); /* Fixed MCS rate (0..31) */
8462 if (mcs32 && rate) {
8463 /* TODO */
8464 send_resp(dut, conn, SIGMA_ERROR,
8465 "ErrorCode,MCS32,MCS_FIXEDRATE not supported");
8466 return 0;
8467 } else if (mcs32 && !rate) {
8468 /* TODO */
8469 send_resp(dut, conn, SIGMA_ERROR,
8470 "ErrorCode,MCS32 not supported");
8471 return 0;
8472 } else if (!mcs32 && rate) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02008473 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008474 case DRIVER_ATHEROS:
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -07008475 novap_reset(dut, intf, 1);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008476 ath_sta_set_11nrates(dut, intf, rate);
8477 break;
8478 default:
8479 send_resp(dut, conn, SIGMA_ERROR,
8480 "ErrorCode,MCS32_FIXEDRATE not supported");
8481 return 0;
8482 }
8483 }
8484
8485 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
8486}
8487
8488
Arif Hussain7b47d2d2018-05-09 10:44:02 -07008489static void cmd_set_max_he_mcs(struct sigma_dut *dut, const char *intf,
8490 int mcs_config)
8491{
8492#ifdef NL80211_SUPPORT
8493 int ret;
8494
8495 switch (mcs_config) {
8496 case HE_80_MCS0_7:
8497 case HE_80_MCS0_9:
8498 case HE_80_MCS0_11:
8499 ret = sta_set_he_mcs(dut, intf, mcs_config);
8500 if (ret) {
8501 sigma_dut_print(dut, DUT_MSG_ERROR,
8502 "cmd_set_max_he_mcs: Setting of MCS:%d failed, ret:%d",
8503 mcs_config, ret);
8504 }
8505 break;
8506 default:
8507 sigma_dut_print(dut, DUT_MSG_ERROR,
8508 "cmd_set_max_he_mcs: Invalid mcs %d",
8509 mcs_config);
8510 break;
8511 }
8512#else /* NL80211_SUPPORT */
8513 sigma_dut_print(dut, DUT_MSG_ERROR,
8514 "max HE MCS cannot be changed without NL80211_SUPPORT defined");
8515#endif /* NL80211_SUPPORT */
8516}
8517
8518
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07008519struct wait_event {
8520 struct sigma_dut *dut;
8521 int cmd;
8522 unsigned int twt_op;
8523};
8524
8525#ifdef NL80211_SUPPORT
8526
8527static int twt_event_handler(struct nl_msg *msg, void *arg)
8528{
8529 struct wait_event *wait = arg;
8530 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
8531 struct nlattr *tb[NL80211_ATTR_MAX + 1];
8532 uint32_t subcmd;
8533 uint8_t *data = NULL;
8534 size_t len = 0;
8535 struct nlattr *twt_rsp[QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_MAX + 1];
8536 struct nlattr *twt_status[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX + 1];
8537 int cmd_id;
8538 unsigned char val;
8539
8540 if (!wait)
8541 return NL_SKIP;
8542
8543 if (gnlh->cmd != NL80211_CMD_VENDOR) {
8544 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
8545 "%s: NL cmd is not vendor %d", __func__,
8546 gnlh->cmd);
8547 return NL_SKIP;
8548 }
8549
8550 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
8551 genlmsg_attrlen(gnlh, 0), NULL);
8552
8553 if (!tb[NL80211_ATTR_VENDOR_ID] || !tb[NL80211_ATTR_VENDOR_SUBCMD]) {
8554 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
8555 "%s: vendor ID not found", __func__);
8556 return NL_SKIP;
8557 }
8558 subcmd = nla_get_u32(tb[NL80211_ATTR_VENDOR_SUBCMD]);
8559
8560 if (subcmd != QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) {
8561 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
8562 "%s: Not a TWT_cmd %d", __func__, subcmd);
8563 return NL_SKIP;
8564 }
8565 if (tb[NL80211_ATTR_VENDOR_DATA]) {
8566 data = nla_data(tb[NL80211_ATTR_VENDOR_DATA]);
8567 len = nla_len(tb[NL80211_ATTR_VENDOR_DATA]);
8568 } else {
8569 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
8570 "%s: vendor data not present", __func__);
8571 return NL_SKIP;
8572 }
8573 if (!data || !len) {
8574 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
8575 "Invalid vendor data or len");
8576 return NL_SKIP;
8577 }
8578 sigma_dut_print(wait->dut, DUT_MSG_DEBUG,
8579 "event data len %ld", len);
8580 hex_dump(wait->dut, data, len);
8581 if (nla_parse(twt_rsp, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_MAX,
8582 (struct nlattr *) data, len, NULL)) {
8583 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
8584 "vendor data parse error");
8585 return NL_SKIP;
8586 }
8587
8588 val = nla_get_u8(twt_rsp[QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION]);
8589 if (val != wait->twt_op) {
8590 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
8591 "Invalid TWT operation, expected %d, rcvd %d",
8592 wait->twt_op, val);
8593 return NL_SKIP;
8594 }
8595 if (nla_parse_nested(twt_status, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX,
8596 twt_rsp[QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS],
8597 NULL)) {
8598 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
8599 "nla_parse failed for TWT event");
8600 return NL_SKIP;
8601 }
8602
8603 cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_STATUS;
8604 if (!twt_status[cmd_id]) {
8605 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
8606 "%s TWT resp status missing", __func__);
8607 wait->cmd = -1;
8608 } else {
8609 val = nla_get_u8(twt_status[cmd_id]);
8610 if (val != QCA_WLAN_VENDOR_TWT_STATUS_OK) {
8611 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
8612 "%s TWT resp status %d", __func__, val);
8613 wait->cmd = -1;
8614 } else {
8615 wait->cmd = 1;
8616 }
8617 }
8618
8619 return NL_SKIP;
8620}
8621
8622
8623static int wait_on_nl_socket(struct nl_sock *sock, struct sigma_dut *dut,
8624 unsigned int timeout)
8625{
8626 fd_set read_fd_set;
8627 int retval;
8628 int sock_fd;
8629 struct timeval time_out;
8630
8631 time_out.tv_sec = timeout;
8632 time_out.tv_usec = 0;
8633
8634 FD_ZERO(&read_fd_set);
8635
8636 if (!sock)
8637 return -1;
8638
8639 sock_fd = nl_socket_get_fd(sock);
8640 FD_SET(sock_fd, &read_fd_set);
8641
8642 retval = select(sock_fd + 1, &read_fd_set, NULL, NULL, &time_out);
8643
8644 if (retval == 0)
8645 sigma_dut_print(dut, DUT_MSG_ERROR,
8646 "%s: TWT event response timedout", __func__);
8647
8648 if (retval < 0)
8649 sigma_dut_print(dut, DUT_MSG_ERROR, "%s:no NL msgs, ret=%d",
8650 __func__, retval);
8651
8652 return retval;
8653}
8654
8655
8656#define TWT_ASYNC_EVENT_WAIT_TIME_SEC 6
8657
8658static int twt_async_event_wait(struct sigma_dut *dut, unsigned int twt_op)
8659{
8660 struct nl_cb *cb;
8661 int err_code = 0, select_retval = 0;
8662 struct wait_event wait_info;
8663
8664 cb = nl_socket_get_cb(dut->nl_ctx->event_sock);
8665 if (!cb) {
8666 sigma_dut_print(dut, DUT_MSG_ERROR,
8667 "event callback not found");
8668 return ERROR_SEND_STATUS;
8669 }
8670
8671 wait_info.cmd = 0;
8672 wait_info.dut = dut;
8673 wait_info.twt_op = twt_op;
8674
8675 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, twt_event_handler, &wait_info);
8676
8677 while (!wait_info.cmd) {
8678 select_retval = wait_on_nl_socket(
8679 dut->nl_ctx->event_sock, dut,
8680 TWT_ASYNC_EVENT_WAIT_TIME_SEC);
8681
8682 if (select_retval > 0) {
8683 err_code = nl_recvmsgs(dut->nl_ctx->event_sock, cb);
8684 if (err_code < 0) {
8685 sigma_dut_print(dut, DUT_MSG_ERROR,
8686 "%s: nl rcv failed, err_code %d",
8687 __func__, err_code);
8688 break;
8689 }
8690 } else {
8691 sigma_dut_print(dut, DUT_MSG_ERROR,
8692 "%s: wait on socket failed %d",
8693 __func__, select_retval);
8694 err_code = 1;
8695 break;
8696 }
8697
8698 }
8699 nl_cb_put(cb);
8700
8701 if (wait_info.cmd < 0)
8702 err_code = 1;
8703
8704 sigma_dut_print(dut, DUT_MSG_DEBUG,
8705 "%s: rcvd cmd %d, err_code %d, s_ret %d",
8706 __func__, wait_info.cmd, err_code, select_retval);
8707
8708 return err_code;
8709}
8710
8711#endif /* NL80211_SUPPORT */
8712
8713
Srinivas Girigowda6707f032020-10-26 15:24:46 -07008714static int sta_twt_send_suspend(struct sigma_dut *dut, struct sigma_conn *conn,
8715 struct sigma_cmd *cmd)
8716{
8717#ifdef NL80211_SUPPORT
8718 struct nlattr *attr, *attr1;
8719 struct nl_msg *msg;
8720 int ifindex, ret;
8721 const char *intf = get_param(cmd, "Interface");
8722
8723 ifindex = if_nametoindex(intf);
8724 if (ifindex == 0) {
8725 sigma_dut_print(dut, DUT_MSG_ERROR,
8726 "%s: Index for interface %s failed",
8727 __func__, intf);
8728 return ERROR_SEND_STATUS;
8729 }
8730
8731 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8732 NL80211_CMD_VENDOR)) ||
8733 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
8734 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
8735 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
8736 QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
8737 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8738 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
8739 QCA_WLAN_TWT_SUSPEND) ||
8740 !(attr1 = nla_nest_start(msg,
Kiran Kumar Lokere7ede00c2021-08-09 00:59:52 -07008741 QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS))) {
Srinivas Girigowda6707f032020-10-26 15:24:46 -07008742 sigma_dut_print(dut, DUT_MSG_ERROR,
8743 "%s: err in adding vendor_cmd and vendor_data",
8744 __func__);
8745 nlmsg_free(msg);
8746 return ERROR_SEND_STATUS;
8747 }
8748 nla_nest_end(msg, attr1);
8749 nla_nest_end(msg, attr);
8750
8751 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
8752 if (ret) {
8753 sigma_dut_print(dut, DUT_MSG_ERROR,
8754 "%s: err in send_and_recv_msgs, ret=%d",
8755 __func__, ret);
8756 }
8757
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07008758 if (!dut->sta_async_twt_supp)
8759 return ret;
8760
8761 return twt_async_event_wait(dut, QCA_WLAN_TWT_SUSPEND);
Srinivas Girigowda6707f032020-10-26 15:24:46 -07008762#else /* NL80211_SUPPORT */
8763 sigma_dut_print(dut, DUT_MSG_ERROR,
8764 "TWT suspend cannot be done without NL80211_SUPPORT defined");
8765 return ERROR_SEND_STATUS;
8766#endif /* NL80211_SUPPORT */
8767}
8768
8769
8770static int sta_twt_send_nudge(struct sigma_dut *dut, struct sigma_conn *conn,
8771 struct sigma_cmd *cmd,
8772 unsigned int suspend_duration)
8773{
8774#ifdef NL80211_SUPPORT
8775 struct nlattr *attr, *attr1;
8776 struct nl_msg *msg;
8777 int ifindex, ret;
8778 const char *intf = get_param(cmd, "Interface");
8779 int next_twt_size = 1;
8780
8781 ifindex = if_nametoindex(intf);
8782 if (ifindex == 0) {
8783 sigma_dut_print(dut, DUT_MSG_ERROR,
8784 "%s: Index for interface %s failed",
8785 __func__, intf);
8786 return ERROR_SEND_STATUS;
8787 }
8788
8789 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8790 NL80211_CMD_VENDOR)) ||
8791 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
8792 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
8793 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
8794 QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
8795 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8796 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
8797 QCA_WLAN_TWT_NUDGE) ||
8798 !(attr1 = nla_nest_start(msg,
8799 QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS)) ||
8800 (suspend_duration &&
8801 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_WAKE_TIME,
8802 suspend_duration)) ||
8803 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_NEXT_TWT_SIZE,
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -07008804 next_twt_size) ||
8805 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_FLOW_ID, 0)) {
Srinivas Girigowda6707f032020-10-26 15:24:46 -07008806 sigma_dut_print(dut, DUT_MSG_ERROR,
8807 "%s: err in adding vendor_cmd and vendor_data",
8808 __func__);
8809 nlmsg_free(msg);
8810 return ERROR_SEND_STATUS;
8811 }
8812 nla_nest_end(msg, attr1);
8813 nla_nest_end(msg, attr);
8814
8815 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
8816 if (ret) {
8817 sigma_dut_print(dut, DUT_MSG_ERROR,
8818 "%s: err in send_and_recv_msgs, ret=%d",
8819 __func__, ret);
8820 }
8821
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07008822 if (!dut->sta_async_twt_supp)
8823 return ret;
8824
8825 return twt_async_event_wait(dut, QCA_WLAN_TWT_NUDGE);
Srinivas Girigowda6707f032020-10-26 15:24:46 -07008826#else /* NL80211_SUPPORT */
8827 sigma_dut_print(dut, DUT_MSG_ERROR,
8828 "TWT suspend cannot be done without NL80211_SUPPORT defined");
8829 return ERROR_SEND_STATUS;
8830#endif /* NL80211_SUPPORT */
8831}
8832
8833
8834static int sta_twt_suspend_or_nudge(struct sigma_dut *dut,
8835 struct sigma_conn *conn,
8836 struct sigma_cmd *cmd)
8837{
8838 const char *val;
8839
8840 val = get_param(cmd, "TWT_SuspendDuration");
8841 if (val) {
8842 unsigned int suspend_duration;
8843
8844 suspend_duration = atoi(val);
8845 suspend_duration = suspend_duration * 1000 * 1000;
8846 return sta_twt_send_nudge(dut, conn, cmd, suspend_duration);
8847 }
8848
8849 return sta_twt_send_suspend(dut, conn, cmd);
8850}
8851
8852
8853static int sta_twt_resume(struct sigma_dut *dut, struct sigma_conn *conn,
8854 struct sigma_cmd *cmd)
8855{
8856#ifdef NL80211_SUPPORT
8857 struct nlattr *attr, *attr1;
8858 struct nl_msg *msg;
8859 int ifindex, ret;
8860 const char *intf = get_param(cmd, "Interface");
8861 int next2_twt_size = 1;
8862 unsigned int resume_duration = 0;
8863 const char *val;
8864
8865 ifindex = if_nametoindex(intf);
8866 if (ifindex == 0) {
8867 sigma_dut_print(dut, DUT_MSG_ERROR,
8868 "%s: Index for interface %s failed",
8869 __func__, intf);
8870 return ERROR_SEND_STATUS;
8871 }
8872
8873 val = get_param(cmd, "TWT_ResumeDuration");
8874 if (val) {
8875 resume_duration = atoi(val);
8876 resume_duration = resume_duration * 1000 * 1000;
8877 }
8878
8879 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8880 NL80211_CMD_VENDOR)) ||
8881 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
8882 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
8883 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
8884 QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
8885 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8886 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
8887 QCA_WLAN_TWT_RESUME) ||
8888 !(attr1 = nla_nest_start(msg,
8889 QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS)) ||
8890 (resume_duration &&
8891 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_RESUME_NEXT2_TWT,
8892 resume_duration)) ||
8893 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_RESUME_NEXT_TWT_SIZE,
8894 next2_twt_size)) {
8895 sigma_dut_print(dut, DUT_MSG_ERROR,
8896 "%s: err in adding vendor_cmd and vendor_data",
8897 __func__);
8898 nlmsg_free(msg);
8899 return ERROR_SEND_STATUS;
8900 }
8901 nla_nest_end(msg, attr1);
8902 nla_nest_end(msg, attr);
8903
8904 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
8905 if (ret) {
8906 sigma_dut_print(dut, DUT_MSG_ERROR,
8907 "%s: err in send_and_recv_msgs, ret=%d",
8908 __func__, ret);
8909 }
8910
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07008911 if (!dut->sta_async_twt_supp)
8912 return ret;
8913
8914 return twt_async_event_wait(dut, QCA_WLAN_TWT_RESUME);
Srinivas Girigowda6707f032020-10-26 15:24:46 -07008915#else /* NL80211_SUPPORT */
8916 sigma_dut_print(dut, DUT_MSG_ERROR,
8917 "TWT resume cannot be done without NL80211_SUPPORT defined");
8918 return ERROR_SEND_STATUS;
8919#endif /* NL80211_SUPPORT */
8920}
8921
8922
Kiran Kumar Lokerebd396102020-04-27 12:01:09 -07008923#define TWT_REQUEST_CMD 0
8924#define TWT_SUGGEST_CMD 1
8925#define TWT_DEMAND_CMD 2
8926
Arif Hussain480d5f42019-03-12 14:40:42 -07008927static int sta_twt_request(struct sigma_dut *dut, struct sigma_conn *conn,
8928 struct sigma_cmd *cmd)
8929{
8930#ifdef NL80211_SUPPORT
8931 struct nlattr *params;
8932 struct nlattr *attr;
Arif Hussain480d5f42019-03-12 14:40:42 -07008933 struct nl_msg *msg;
8934 int ifindex, ret;
8935 const char *val;
8936 const char *intf = get_param(cmd, "Interface");
8937 int wake_interval_exp = 10, nominal_min_wake_dur = 255,
8938 wake_interval_mantissa = 512;
8939 int flow_type = 0, twt_trigger = 0, target_wake_time = 0,
Kiran Kumar Lokerebd396102020-04-27 12:01:09 -07008940 protection = 0, cmd_type = QCA_WLAN_VENDOR_TWT_SETUP_SUGGEST;
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -07008941 int bcast_twt = 0;
8942 int bcast_twt_id = 0, bcast_twt_recommdn = 0, bcast_twt_persis = 0;
Arif Hussain480d5f42019-03-12 14:40:42 -07008943
8944 ifindex = if_nametoindex(intf);
8945 if (ifindex == 0) {
8946 sigma_dut_print(dut, DUT_MSG_ERROR,
8947 "%s: Index for interface %s failed",
8948 __func__, intf);
8949 return -1;
8950 }
8951
8952 val = get_param(cmd, "FlowType");
8953 if (val) {
8954 flow_type = atoi(val);
8955 if (flow_type != 0 && flow_type != 1) {
8956 sigma_dut_print(dut, DUT_MSG_ERROR,
8957 "TWT: Invalid FlowType %d", flow_type);
8958 return -1;
8959 }
8960 }
8961
8962 val = get_param(cmd, "TWT_Trigger");
8963 if (val) {
8964 twt_trigger = atoi(val);
8965 if (twt_trigger != 0 && twt_trigger != 1) {
8966 sigma_dut_print(dut, DUT_MSG_ERROR,
8967 "TWT: Invalid TWT_Trigger %d",
8968 twt_trigger);
8969 return -1;
8970 }
8971 }
8972
8973 val = get_param(cmd, "Protection");
8974 if (val) {
8975 protection = atoi(val);
8976 if (protection != 0 && protection != 1) {
8977 sigma_dut_print(dut, DUT_MSG_ERROR,
8978 "TWT: Invalid Protection %d",
8979 protection);
8980 return -1;
8981 }
8982 }
8983
Kiran Kumar Lokerebd396102020-04-27 12:01:09 -07008984 val = get_param(cmd, "SetupCommand");
8985 if (val) {
8986 cmd_type = atoi(val);
8987 if (cmd_type == TWT_REQUEST_CMD)
8988 cmd_type = QCA_WLAN_VENDOR_TWT_SETUP_REQUEST;
8989 else if (cmd_type == TWT_SUGGEST_CMD)
8990 cmd_type = QCA_WLAN_VENDOR_TWT_SETUP_SUGGEST;
8991 else if (cmd_type == TWT_DEMAND_CMD)
8992 cmd_type = QCA_WLAN_VENDOR_TWT_SETUP_DEMAND;
8993 else
8994 sigma_dut_print(dut, DUT_MSG_ERROR,
8995 "Default suggest is used for cmd %d",
8996 cmd_type);
8997 }
8998
Arif Hussain480d5f42019-03-12 14:40:42 -07008999 val = get_param(cmd, "TargetWakeTime");
9000 if (val)
9001 target_wake_time = atoi(val);
9002
9003 val = get_param(cmd, "WakeIntervalMantissa");
9004 if (val)
9005 wake_interval_mantissa = atoi(val);
9006
9007 val = get_param(cmd, "WakeIntervalExp");
9008 if (val)
9009 wake_interval_exp = atoi(val);
9010
9011 val = get_param(cmd, "NominalMinWakeDur");
9012 if (val)
9013 nominal_min_wake_dur = atoi(val);
9014
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -07009015 val = get_param(cmd, "BTWT_ID");
9016 if (val) {
9017 bcast_twt_id = atoi(val);
9018 bcast_twt = 1;
9019 }
9020
9021 val = get_param(cmd, "BTWT_Persistence");
9022 if (val) {
9023 bcast_twt_persis = atoi(val);
9024 bcast_twt = 1;
9025 }
9026
9027 val = get_param(cmd, "BTWT_Recommendation");
9028 if (val) {
9029 bcast_twt_recommdn = atoi(val);
9030 bcast_twt = 1;
9031 }
9032
9033 if (bcast_twt)
9034 sigma_dut_print(dut, DUT_MSG_DEBUG,
9035 "BCAST_TWT: ID %d, RECOMM %d, PERSIS %d",
9036 bcast_twt_id, bcast_twt_recommdn,
9037 bcast_twt_persis);
9038
Arif Hussain480d5f42019-03-12 14:40:42 -07009039 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
9040 NL80211_CMD_VENDOR)) ||
9041 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
9042 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
9043 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
Srinivas Girigowda6707f032020-10-26 15:24:46 -07009044 QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
Arif Hussain480d5f42019-03-12 14:40:42 -07009045 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
Srinivas Girigowda6707f032020-10-26 15:24:46 -07009046 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
9047 QCA_WLAN_TWT_SET) ||
Arif Hussain480d5f42019-03-12 14:40:42 -07009048 !(params = nla_nest_start(
Srinivas Girigowda6707f032020-10-26 15:24:46 -07009049 msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS)) ||
Arif Hussain480d5f42019-03-12 14:40:42 -07009050 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_EXP,
9051 wake_interval_exp) ||
Kiran Kumar Lokerebd396102020-04-27 12:01:09 -07009052 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_REQ_TYPE, cmd_type) ||
Kiran Kumar Lokere2cffae52019-09-26 18:44:15 -07009053 (twt_trigger &&
9054 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TRIGGER)) ||
Arif Hussain480d5f42019-03-12 14:40:42 -07009055 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE,
9056 flow_type) ||
Kiran Kumar Lokere2cffae52019-09-26 18:44:15 -07009057 (protection &&
9058 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_PROTECTION)) ||
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -07009059 (bcast_twt &&
9060 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST)) ||
9061 (bcast_twt &&
9062 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_ID,
9063 bcast_twt_id)) ||
9064 (bcast_twt &&
9065 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_PERSISTENCE,
9066 bcast_twt_persis)) ||
9067 (bcast_twt &&
9068 nla_put_u8(msg,
9069 QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_RECOMMENDATION,
9070 bcast_twt_recommdn)) ||
Arif Hussain480d5f42019-03-12 14:40:42 -07009071 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME,
9072 target_wake_time) ||
9073 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_DURATION,
9074 nominal_min_wake_dur) ||
9075 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_MANTISSA,
9076 wake_interval_mantissa)) {
9077 sigma_dut_print(dut, DUT_MSG_ERROR,
9078 "%s: err in adding vendor_cmd and vendor_data",
9079 __func__);
9080 nlmsg_free(msg);
9081 return -1;
9082 }
Arif Hussain480d5f42019-03-12 14:40:42 -07009083 nla_nest_end(msg, params);
9084 nla_nest_end(msg, attr);
9085
9086 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
9087 if (ret) {
9088 sigma_dut_print(dut, DUT_MSG_ERROR,
9089 "%s: err in send_and_recv_msgs, ret=%d",
9090 __func__, ret);
9091 }
9092
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07009093 if (!dut->sta_async_twt_supp)
9094 return ret;
9095
9096 return twt_async_event_wait(dut, QCA_WLAN_TWT_SET);
Arif Hussain480d5f42019-03-12 14:40:42 -07009097#else /* NL80211_SUPPORT */
9098 sigma_dut_print(dut, DUT_MSG_ERROR,
9099 "TWT request cannot be done without NL80211_SUPPORT defined");
9100 return -1;
9101#endif /* NL80211_SUPPORT */
9102}
9103
9104
9105static int sta_twt_teardown(struct sigma_dut *dut, struct sigma_conn *conn,
9106 struct sigma_cmd *cmd)
9107{
9108 #ifdef NL80211_SUPPORT
9109 struct nlattr *params;
9110 struct nlattr *attr;
Arif Hussain480d5f42019-03-12 14:40:42 -07009111 int ifindex, ret;
9112 struct nl_msg *msg;
9113 const char *intf = get_param(cmd, "Interface");
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -07009114 int bcast_twt = 0;
9115 int bcast_twt_id = 0;
9116 const char *val;
Arif Hussain480d5f42019-03-12 14:40:42 -07009117
9118 ifindex = if_nametoindex(intf);
9119 if (ifindex == 0) {
9120 sigma_dut_print(dut, DUT_MSG_ERROR,
9121 "%s: Index for interface %s failed",
9122 __func__, intf);
9123 return -1;
9124 }
9125
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -07009126 val = get_param(cmd, "BTWT_ID");
9127 if (val) {
9128 bcast_twt_id = atoi(val);
9129 bcast_twt = 1;
9130 }
9131
Arif Hussain480d5f42019-03-12 14:40:42 -07009132 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
9133 NL80211_CMD_VENDOR)) ||
9134 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
9135 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
9136 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
Srinivas Girigowda6707f032020-10-26 15:24:46 -07009137 QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
Arif Hussain480d5f42019-03-12 14:40:42 -07009138 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
Srinivas Girigowda6707f032020-10-26 15:24:46 -07009139 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
9140 QCA_WLAN_TWT_TERMINATE) ||
Arif Hussain480d5f42019-03-12 14:40:42 -07009141 !(params = nla_nest_start(
9142 msg,
Srinivas Girigowda6707f032020-10-26 15:24:46 -07009143 QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS)) ||
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -07009144 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE, 0) ||
9145 (bcast_twt &&
9146 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST)) ||
9147 (bcast_twt &&
9148 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_ID,
9149 bcast_twt_id))) {
Arif Hussain480d5f42019-03-12 14:40:42 -07009150 sigma_dut_print(dut, DUT_MSG_ERROR,
9151 "%s: err in adding vendor_cmd and vendor_data",
9152 __func__);
9153 nlmsg_free(msg);
9154 return -1;
9155 }
Arif Hussain480d5f42019-03-12 14:40:42 -07009156 nla_nest_end(msg, params);
9157 nla_nest_end(msg, attr);
9158
9159 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
9160 if (ret) {
9161 sigma_dut_print(dut, DUT_MSG_ERROR,
9162 "%s: err in send_and_recv_msgs, ret=%d",
9163 __func__, ret);
9164 }
9165
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07009166 if (!dut->sta_async_twt_supp)
9167 return ret;
9168
9169 return twt_async_event_wait(dut, QCA_WLAN_TWT_TERMINATE);
Arif Hussain480d5f42019-03-12 14:40:42 -07009170#else /* NL80211_SUPPORT */
9171 sigma_dut_print(dut, DUT_MSG_ERROR,
9172 "TWT teardown cannot be done without NL80211_SUPPORT defined");
9173 return -1;
9174#endif /* NL80211_SUPPORT */
9175}
9176
9177
Kiran Kumar Lokere50eb2cd2018-12-18 18:31:28 -08009178static int sta_transmit_omi(struct sigma_dut *dut, struct sigma_conn *conn,
9179 struct sigma_cmd *cmd)
9180{
9181#ifdef NL80211_SUPPORT
9182 struct nlattr *params;
9183 struct nlattr *attr;
9184 struct nlattr *attr1;
9185 struct nl_msg *msg;
9186 int ifindex, ret;
9187 const char *val;
9188 const char *intf = get_param(cmd, "Interface");
9189 uint8_t rx_nss = 0xFF, ch_bw = 0xFF, tx_nsts = 0xFF, ulmu_dis = 0,
9190 ulmu_data_dis = 0;
9191
9192 ifindex = if_nametoindex(intf);
9193 if (ifindex == 0) {
9194 sigma_dut_print(dut, DUT_MSG_ERROR,
9195 "%s: Index for interface %s failed",
9196 __func__, intf);
9197 return -1;
9198 }
9199 val = get_param(cmd, "OMCtrl_RxNSS");
9200 if (val)
9201 rx_nss = atoi(val);
9202
9203 val = get_param(cmd, "OMCtrl_ChnlWidth");
9204 if (val)
9205 ch_bw = atoi(val);
9206
9207 val = get_param(cmd, "OMCtrl_ULMUDisable");
9208 if (val)
9209 ulmu_dis = atoi(val);
9210
9211 val = get_param(cmd, "OMCtrl_TxNSTS");
9212 if (val)
9213 tx_nsts = atoi(val);
9214
9215 val = get_param(cmd, "OMCtrl_ULMUDataDisable");
9216 if (val)
9217 ulmu_data_dis = atoi(val);
9218
9219 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
9220 NL80211_CMD_VENDOR)) ||
9221 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
9222 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
9223 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
9224 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
9225 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
9226 !(params = nla_nest_start(
9227 msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OMI_TX)) ||
9228 !(attr1 = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
9229 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_RX_NSS, rx_nss) ||
9230 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_CH_BW, ch_bw) ||
9231 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_TX_NSTS, tx_nsts) ||
9232 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DATA_DISABLE,
9233 ulmu_data_dis) ||
9234 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DISABLE,
9235 ulmu_dis)) {
9236 sigma_dut_print(dut, DUT_MSG_ERROR,
9237 "%s: err in adding vendor_cmd and vendor_data",
9238 __func__);
9239 nlmsg_free(msg);
9240 return -1;
9241 }
9242 nla_nest_end(msg, attr1);
9243 nla_nest_end(msg, params);
9244 nla_nest_end(msg, attr);
9245
9246 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
9247 if (ret) {
9248 sigma_dut_print(dut, DUT_MSG_ERROR,
9249 "%s: err in send_and_recv_msgs, ret=%d",
9250 __func__, ret);
9251 }
9252
9253 return ret;
9254#else /* NL80211_SUPPORT */
9255 sigma_dut_print(dut, DUT_MSG_ERROR,
9256 "OMI TX cannot be processed without NL80211_SUPPORT defined");
9257 return -1;
9258#endif /* NL80211_SUPPORT */
9259}
9260
9261
Jouni Malinen224e3902021-06-09 16:41:27 +03009262static enum sigma_cmd_result
9263cmd_sta_set_wireless_vht(struct sigma_dut *dut, struct sigma_conn *conn,
9264 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009265{
9266 const char *intf = get_param(cmd, "Interface");
9267 const char *val;
Arif Hussaina37e9552018-06-20 17:05:59 -07009268 const char *program;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009269 int tkip = -1;
9270 int wep = -1;
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05309271 int iwpriv_status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009272
Arif Hussaina37e9552018-06-20 17:05:59 -07009273 program = get_param(cmd, "Program");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009274 val = get_param(cmd, "SGI80");
9275 if (val) {
9276 int sgi80;
9277
9278 sgi80 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07009279 run_iwpriv(dut, intf, "shortgi %d", sgi80);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009280 }
9281
9282 val = get_param(cmd, "TxBF");
9283 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009284 switch (get_driver_type(dut)) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07009285 case DRIVER_WCN:
9286 if (sta_set_tx_beamformee(dut, intf, 1)) {
9287 send_resp(dut, conn, SIGMA_ERROR,
9288 "ErrorCode,Failed to set TX beamformee enable");
Jouni Malinen224e3902021-06-09 16:41:27 +03009289 return STATUS_SENT_ERROR;
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07009290 }
9291 break;
9292 case DRIVER_ATHEROS:
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07009293 if (run_iwpriv(dut, intf, "vhtsubfee 1") < 0) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07009294 send_resp(dut, conn, SIGMA_ERROR,
9295 "ErrorCode,Setting vhtsubfee failed");
Jouni Malinen224e3902021-06-09 16:41:27 +03009296 return STATUS_SENT_ERROR;
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07009297 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07009298 if (run_iwpriv(dut, intf, "vhtsubfer 1") < 0) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07009299 send_resp(dut, conn, SIGMA_ERROR,
9300 "ErrorCode,Setting vhtsubfer failed");
Jouni Malinen224e3902021-06-09 16:41:27 +03009301 return STATUS_SENT_ERROR;
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07009302 }
9303 break;
9304 default:
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009305 sigma_dut_print(dut, DUT_MSG_ERROR,
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07009306 "Unsupported driver type");
9307 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009308 }
9309 }
9310
9311 val = get_param(cmd, "MU_TxBF");
9312 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009313 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009314 case DRIVER_ATHEROS:
9315 ath_sta_set_txsp_stream(dut, intf, "1SS");
9316 ath_sta_set_rxsp_stream(dut, intf, "1SS");
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07009317 run_iwpriv(dut, intf, "vhtmubfee 1");
9318 run_iwpriv(dut, intf, "vhtmubfer 1");
Sunil Duttae9e5d12018-06-29 11:50:47 +05309319 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009320 case DRIVER_WCN:
9321 if (wcn_sta_set_sp_stream(dut, intf, "1SS") < 0) {
9322 send_resp(dut, conn, SIGMA_ERROR,
9323 "ErrorCode,Failed to set RX/TXSP_STREAM");
Jouni Malinen224e3902021-06-09 16:41:27 +03009324 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009325 }
Sunil Duttae9e5d12018-06-29 11:50:47 +05309326 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009327 default:
9328 sigma_dut_print(dut, DUT_MSG_ERROR,
9329 "Setting SP_STREAM not supported");
9330 break;
9331 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009332 }
9333
9334 val = get_param(cmd, "LDPC");
9335 if (val) {
9336 int ldpc;
9337
9338 ldpc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05309339 iwpriv_status = run_iwpriv(dut, intf, "ldpc %d", ldpc);
9340 if (iwpriv_status)
9341 sta_config_params(dut, intf, STA_SET_LDPC, ldpc);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009342 }
9343
Amarnath Hullur Subramanyam7bae60e2018-01-31 03:46:50 -08009344 val = get_param(cmd, "BCC");
9345 if (val) {
9346 int bcc;
9347
9348 bcc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
9349 /* use LDPC iwpriv itself to set bcc coding, bcc coding
9350 * is mutually exclusive to bcc */
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05309351 iwpriv_status = run_iwpriv(dut, intf, "ldpc %d", !bcc);
9352 if (iwpriv_status)
9353 sta_config_params(dut, intf, STA_SET_LDPC, !bcc);
Amarnath Hullur Subramanyam7bae60e2018-01-31 03:46:50 -08009354 }
9355
Arif Hussain7b47d2d2018-05-09 10:44:02 -07009356 val = get_param(cmd, "MaxHE-MCS_1SS_RxMapLTE80");
9357 if (val && dut->sta_nss == 1)
9358 cmd_set_max_he_mcs(dut, intf, atoi(val));
9359
9360 val = get_param(cmd, "MaxHE-MCS_2SS_RxMapLTE80");
9361 if (val && dut->sta_nss == 2)
9362 cmd_set_max_he_mcs(dut, intf, atoi(val));
9363
Arif Hussainac6c5112018-05-25 17:34:00 -07009364 val = get_param(cmd, "MCS_FixedRate");
9365 if (val) {
9366#ifdef NL80211_SUPPORT
9367 int mcs, ratecode = 0;
9368 enum he_mcs_config mcs_config;
9369 int ret;
Jouni Malinenb9b671d2019-04-26 13:23:17 +03009370 char buf[60];
Arif Hussainac6c5112018-05-25 17:34:00 -07009371
9372 ratecode = (0x07 & dut->sta_nss) << 5;
9373 mcs = atoi(val);
9374 /* Add the MCS to the ratecode */
9375 if (mcs >= 0 && mcs <= 11) {
9376 ratecode += mcs;
9377 if (dut->device_type == STA_testbed &&
9378 mcs > 7 && mcs <= 11) {
9379 if (mcs <= 9)
9380 mcs_config = HE_80_MCS0_9;
9381 else
9382 mcs_config = HE_80_MCS0_11;
9383 ret = sta_set_he_mcs(dut, intf, mcs_config);
9384 if (ret) {
9385 sigma_dut_print(dut, DUT_MSG_ERROR,
9386 "MCS_FixedRate: mcs setting failed, mcs:%d, mcs_config %d, ret:%d",
9387 mcs, mcs_config, ret);
9388 }
9389 }
9390 snprintf(buf, sizeof(buf),
9391 "iwpriv %s set_11ax_rate 0x%03x",
9392 intf, ratecode);
9393 if (system(buf) != 0) {
9394 sigma_dut_print(dut, DUT_MSG_ERROR,
9395 "MCS_FixedRate: iwpriv setting of 11ax rates 0x%03x failed",
9396 ratecode);
9397 }
9398 } else {
9399 sigma_dut_print(dut, DUT_MSG_ERROR,
9400 "MCS_FixedRate: HE MCS %d not supported",
9401 mcs);
9402 }
9403#else /* NL80211_SUPPORT */
9404 sigma_dut_print(dut, DUT_MSG_ERROR,
9405 "MCS_FixedRate cannot be changed without NL80211_SUPPORT defined");
9406#endif /* NL80211_SUPPORT */
9407 }
9408
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009409 val = get_param(cmd, "opt_md_notif_ie");
9410 if (val) {
9411 char *result = NULL;
9412 char delim[] = ";";
9413 char token[30];
9414 int value, config_val = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05309415 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009416
Peng Xub8fc5cc2017-05-10 17:27:28 -07009417 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05309418 result = strtok_r(token, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009419
9420 /* Extract the NSS information */
9421 if (result) {
9422 value = atoi(result);
9423 switch (value) {
9424 case 1:
9425 config_val = 1;
9426 break;
9427 case 2:
9428 config_val = 3;
9429 break;
9430 case 3:
9431 config_val = 7;
9432 break;
9433 case 4:
9434 config_val = 15;
9435 break;
9436 default:
9437 config_val = 3;
9438 break;
9439 }
9440
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07009441 run_iwpriv(dut, intf, "rxchainmask %d", config_val);
9442 run_iwpriv(dut, intf, "txchainmask %d", config_val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009443
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009444 }
9445
9446 /* Extract the channel width information */
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05309447 result = strtok_r(NULL, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009448 if (result) {
9449 value = atoi(result);
9450 switch (value) {
9451 case 20:
9452 config_val = 0;
9453 break;
9454 case 40:
9455 config_val = 1;
9456 break;
9457 case 80:
9458 config_val = 2;
9459 break;
9460 case 160:
9461 config_val = 3;
9462 break;
9463 default:
9464 config_val = 2;
9465 break;
9466 }
9467
9468 dut->chwidth = config_val;
9469
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07009470 run_iwpriv(dut, intf, "chwidth %d", config_val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009471 }
9472
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07009473 run_iwpriv(dut, intf, "opmode_notify 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009474 }
9475
9476 val = get_param(cmd, "nss_mcs_cap");
9477 if (val) {
9478 int nss, mcs;
9479 char token[20];
9480 char *result = NULL;
9481 unsigned int vht_mcsmap = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05309482 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009483
Peng Xub8fc5cc2017-05-10 17:27:28 -07009484 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05309485 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05309486 if (!result) {
9487 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07009488 "NSS not specified");
9489 send_resp(dut, conn, SIGMA_ERROR,
9490 "errorCode,NSS not specified");
Jouni Malinen224e3902021-06-09 16:41:27 +03009491 return STATUS_SENT_ERROR;
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05309492 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009493 nss = atoi(result);
9494
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07009495 run_iwpriv(dut, intf, "nss %d", nss);
Arif Hussainac6c5112018-05-25 17:34:00 -07009496 dut->sta_nss = nss;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009497
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05309498 result = strtok_r(NULL, ";", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009499 if (result == NULL) {
9500 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07009501 "MCS not specified");
9502 send_resp(dut, conn, SIGMA_ERROR,
9503 "errorCode,MCS not specified");
Jouni Malinen224e3902021-06-09 16:41:27 +03009504 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009505 }
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05309506 result = strtok_r(result, "-", &saveptr);
9507 result = strtok_r(NULL, "-", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05309508 if (!result) {
9509 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07009510 "MCS not specified");
9511 send_resp(dut, conn, SIGMA_ERROR,
9512 "errorCode,MCS not specified");
Jouni Malinen224e3902021-06-09 16:41:27 +03009513 return STATUS_SENT_ERROR;
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05309514 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009515 mcs = atoi(result);
9516
Arif Hussaina37e9552018-06-20 17:05:59 -07009517 if (program && strcasecmp(program, "HE") == 0) {
9518#ifdef NL80211_SUPPORT
9519 enum he_mcs_config mcs_config;
9520 int ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009521
Arif Hussaina37e9552018-06-20 17:05:59 -07009522 if (mcs >= 0 && mcs <= 7) {
9523 mcs_config = HE_80_MCS0_7;
9524 } else if (mcs > 7 && mcs <= 9) {
9525 mcs_config = HE_80_MCS0_9;
9526 } else if (mcs > 9 && mcs <= 11) {
9527 mcs_config = HE_80_MCS0_11;
9528 } else {
9529 sigma_dut_print(dut, DUT_MSG_ERROR,
9530 "nss_mcs_cap: HE: Invalid mcs: %d",
9531 mcs);
9532 send_resp(dut, conn, SIGMA_ERROR,
9533 "errorCode,Invalid MCS");
Jouni Malinen224e3902021-06-09 16:41:27 +03009534 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009535 }
Arif Hussaina37e9552018-06-20 17:05:59 -07009536
9537 ret = sta_set_he_mcs(dut, intf, mcs_config);
9538 if (ret) {
9539 sigma_dut_print(dut, DUT_MSG_ERROR,
9540 "nss_mcs_cap: HE: Setting of MCS failed, mcs_config: %d, ret: %d",
9541 mcs_config, ret);
9542 send_resp(dut, conn, SIGMA_ERROR,
9543 "errorCode,Failed to set MCS");
Jouni Malinen224e3902021-06-09 16:41:27 +03009544 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009545 }
Arif Hussaina37e9552018-06-20 17:05:59 -07009546#else /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009547 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07009548 "nss_mcs_cap: HE: MCS cannot be changed without NL80211_SUPPORT defined");
9549#endif /* NL80211_SUPPORT */
9550 } else {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07009551 run_iwpriv(dut, intf, "vhtmcs %d", mcs);
Arif Hussaina37e9552018-06-20 17:05:59 -07009552
9553 switch (nss) {
9554 case 1:
9555 switch (mcs) {
9556 case 7:
9557 vht_mcsmap = 0xfffc;
9558 break;
9559 case 8:
9560 vht_mcsmap = 0xfffd;
9561 break;
9562 case 9:
9563 vht_mcsmap = 0xfffe;
9564 break;
9565 default:
9566 vht_mcsmap = 0xfffe;
9567 break;
9568 }
9569 break;
9570 case 2:
9571 switch (mcs) {
9572 case 7:
9573 vht_mcsmap = 0xfff0;
9574 break;
9575 case 8:
9576 vht_mcsmap = 0xfff5;
9577 break;
9578 case 9:
9579 vht_mcsmap = 0xfffa;
9580 break;
9581 default:
9582 vht_mcsmap = 0xfffa;
9583 break;
9584 }
9585 break;
9586 case 3:
9587 switch (mcs) {
9588 case 7:
9589 vht_mcsmap = 0xffc0;
9590 break;
9591 case 8:
9592 vht_mcsmap = 0xffd5;
9593 break;
9594 case 9:
9595 vht_mcsmap = 0xffea;
9596 break;
9597 default:
9598 vht_mcsmap = 0xffea;
9599 break;
9600 }
9601 break;
9602 default:
9603 vht_mcsmap = 0xffea;
9604 break;
9605 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07009606 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009607 }
9608 }
9609
9610 /* UNSUPPORTED: val = get_param(cmd, "Tx_lgi_rate"); */
9611
9612 val = get_param(cmd, "Vht_tkip");
9613 if (val)
9614 tkip = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
9615
9616 val = get_param(cmd, "Vht_wep");
9617 if (val)
9618 wep = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
9619
9620 if (tkip != -1 || wep != -1) {
9621 if ((tkip == 1 && wep != 0) || (wep == 1 && tkip != 0)) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07009622 run_iwpriv(dut, intf, "htweptkip 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009623 } else if ((tkip == 0 && wep != 1) || (wep == 0 && tkip != 1)) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07009624 run_iwpriv(dut, intf, "htweptkip 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009625 } else {
Jouni Malinen224e3902021-06-09 16:41:27 +03009626 send_resp(dut, conn, SIGMA_ERROR,
9627 "ErrorCode,mixed mode of VHT TKIP/WEP not supported");
9628 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009629 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009630 }
9631
Kiran Kumar Lokere09dbcef2021-08-09 00:01:41 -07009632 val = get_param(cmd, "TWTSchedSTASupport");
9633 if (val) {
9634 int set_val;
9635
9636 switch (get_driver_type(dut)) {
9637 case DRIVER_WCN:
9638 if (strcasecmp(val, "Enable") == 0) {
9639 set_val = 1;
9640 } else if (strcasecmp(val, "Disable") == 0) {
9641 set_val = 0;
9642 } else {
9643 send_resp(dut, conn, SIGMA_ERROR,
9644 "ErrorCode,Invalid TWTSchedSTASupport");
9645 return STATUS_SENT_ERROR;
9646 }
9647
9648 if (sta_set_bcast_twt_support(dut, intf, set_val)) {
9649 send_resp(dut, conn, SIGMA_ERROR,
9650 "ErrorCode,Failed to set TWTSchedSTASupport");
9651 return STATUS_SENT_ERROR;
9652 }
9653 break;
9654 default:
9655 sigma_dut_print(dut, DUT_MSG_ERROR,
9656 "Setting TWTSchedSTASupport not supported");
9657 break;
9658 }
9659 }
9660
9661 val = get_param(cmd, "MBSSID_RxCtrl");
9662 if (val) {
9663 int set_val;
9664
9665 switch (get_driver_type(dut)) {
9666 case DRIVER_WCN:
9667 if (strcasecmp(val, "Enable") == 0) {
9668 set_val = 1;
9669 } else if (strcasecmp(val, "Disable") == 0) {
9670 set_val = 0;
9671 } else {
9672 send_resp(dut, conn, SIGMA_ERROR,
9673 "ErrorCode,Invalid MBSSID_RxCtrl");
9674 return STATUS_SENT_ERROR;
9675 }
9676
9677 if (sta_set_rx_ctrl_multi_bss(dut, intf, set_val)) {
9678 send_resp(dut, conn, SIGMA_ERROR,
9679 "ErrorCode,Failed to set MBSSID_RxCtrl");
9680 return STATUS_SENT_ERROR;
9681 }
9682 break;
9683 default:
9684 sigma_dut_print(dut, DUT_MSG_ERROR,
9685 "Setting MBSSID_RxCtrl not supported");
9686 break;
9687 }
9688 }
9689
Arif Hussain55f00da2018-07-03 08:28:26 -07009690 val = get_param(cmd, "txBandwidth");
9691 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009692 switch (get_driver_type(dut)) {
Arif Hussain55f00da2018-07-03 08:28:26 -07009693 case DRIVER_WCN:
9694 if (wcn_sta_set_width(dut, intf, val) < 0) {
9695 send_resp(dut, conn, SIGMA_ERROR,
9696 "ErrorCode,Failed to set txBandwidth");
Jouni Malinen224e3902021-06-09 16:41:27 +03009697 return STATUS_SENT_ERROR;
Arif Hussain55f00da2018-07-03 08:28:26 -07009698 }
9699 break;
9700 case DRIVER_ATHEROS:
9701 if (ath_set_width(dut, conn, intf, val) < 0) {
9702 send_resp(dut, conn, SIGMA_ERROR,
9703 "ErrorCode,Failed to set txBandwidth");
Jouni Malinen224e3902021-06-09 16:41:27 +03009704 return STATUS_SENT_ERROR;
Arif Hussain55f00da2018-07-03 08:28:26 -07009705 }
9706 break;
9707 default:
9708 sigma_dut_print(dut, DUT_MSG_ERROR,
9709 "Setting txBandwidth not supported");
9710 break;
9711 }
9712 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009713
Arif Hussain9765f7d2018-07-03 08:28:26 -07009714 val = get_param(cmd, "BeamformeeSTS");
9715 if (val) {
Kiran Kumar Lokerebc89d432018-07-10 12:20:13 -07009716 if (sta_set_tx_beamformee(dut, intf, 1)) {
9717 send_resp(dut, conn, SIGMA_ERROR,
9718 "ErrorCode,Failed to set TX beamformee enable");
Jouni Malinen224e3902021-06-09 16:41:27 +03009719 return STATUS_SENT_ERROR;
Kiran Kumar Lokerebc89d432018-07-10 12:20:13 -07009720 }
9721
Arif Hussain9765f7d2018-07-03 08:28:26 -07009722 if (sta_set_beamformee_sts(dut, intf, atoi(val))) {
9723 send_resp(dut, conn, SIGMA_ERROR,
9724 "ErrorCode,Failed to set BeamformeeSTS");
Jouni Malinen224e3902021-06-09 16:41:27 +03009725 return STATUS_SENT_ERROR;
Arif Hussain9765f7d2018-07-03 08:28:26 -07009726 }
9727 }
9728
Arif Hussain68d23f52018-07-11 13:39:08 -07009729 val = get_param(cmd, "Trig_MAC_Padding_Dur");
9730 if (val) {
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07009731#ifdef NL80211_SUPPORT
9732 enum qca_wlan_he_mac_padding_dur set_val;
9733
9734 switch (atoi(val)) {
9735 case 16:
9736 set_val = QCA_WLAN_HE_16US_OF_PROCESS_TIME;
9737 break;
9738 case 8:
9739 set_val = QCA_WLAN_HE_8US_OF_PROCESS_TIME;
9740 break;
9741 default:
9742 set_val = QCA_WLAN_HE_NO_ADDITIONAL_PROCESS_TIME;
9743 break;
9744 }
9745 if (sta_set_mac_padding_duration(dut, intf, set_val)) {
Arif Hussain68d23f52018-07-11 13:39:08 -07009746 send_resp(dut, conn, SIGMA_ERROR,
9747 "ErrorCode,Failed to set MAC padding duration");
Jouni Malinen224e3902021-06-09 16:41:27 +03009748 return STATUS_SENT_ERROR;
Arif Hussain68d23f52018-07-11 13:39:08 -07009749 }
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07009750#else /* NL80211_SUPPORT */
9751 sigma_dut_print(dut, DUT_MSG_ERROR,
9752 "MAC padding duration cannot be changed without NL80211_SUPPORT defined");
9753#endif /* NL80211_SUPPORT */
Arif Hussain68d23f52018-07-11 13:39:08 -07009754 }
9755
Arif Hussain480d5f42019-03-12 14:40:42 -07009756 val = get_param(cmd, "TWT_ReqSupport");
9757 if (val) {
9758 int set_val;
9759
9760 if (strcasecmp(val, "Enable") == 0) {
9761 set_val = 1;
9762 } else if (strcasecmp(val, "Disable") == 0) {
9763 set_val = 0;
9764 } else {
9765 send_resp(dut, conn, SIGMA_ERROR,
9766 "ErrorCode,Invalid TWT_ReqSupport");
Jouni Malinen224e3902021-06-09 16:41:27 +03009767 return STATUS_SENT_ERROR;
Arif Hussain480d5f42019-03-12 14:40:42 -07009768 }
9769
9770 if (sta_set_twt_req_support(dut, intf, set_val)) {
9771 sigma_dut_print(dut, DUT_MSG_ERROR,
9772 "Failed to set TWT req support %d",
9773 set_val);
9774 send_resp(dut, conn, SIGMA_ERROR,
9775 "ErrorCode,Failed to set TWT_ReqSupport");
Jouni Malinen224e3902021-06-09 16:41:27 +03009776 return STATUS_SENT_ERROR;
Arif Hussain480d5f42019-03-12 14:40:42 -07009777 }
9778 }
9779
Kiran Kumar Lokered0ec5ed2021-04-01 00:15:04 -07009780 val = get_param(cmd, "PreamblePunctRx");
9781 if (val && get_driver_type(dut) == DRIVER_WCN) {
9782 int set_val;
9783
9784 if (strcasecmp(val, "Enable") == 0) {
9785 set_val = 1;
9786 } else if (strcasecmp(val, "Disable") == 0) {
9787 set_val = 0;
9788 } else {
9789 send_resp(dut, conn, SIGMA_ERROR,
9790 "ErrorCode,Invalid PreamblePunctRx");
9791 return STATUS_SENT_ERROR;
9792 }
9793
9794 if (sta_set_punctured_preamble_rx(dut, intf, set_val)) {
9795 sigma_dut_print(dut, DUT_MSG_ERROR,
9796 "Failed to set PreamblePunctRx support %d",
9797 set_val);
9798 send_resp(dut, conn, SIGMA_ERROR,
9799 "ErrorCode,Failed to set PreamblePunctRx");
9800 return STATUS_SENT_ERROR;
9801 }
9802 }
9803
Srinivas Girigowda0525e292020-11-12 13:28:21 -08009804 val = get_param(cmd, "FullBW_ULMUMIMO");
9805 if (val) {
9806 int set_val;
9807
9808 if (strcasecmp(val, "Enable") == 0) {
9809 set_val = 1;
9810 } else if (strcasecmp(val, "Disable") == 0) {
9811 set_val = 0;
9812 } else {
9813 send_resp(dut, conn, SIGMA_ERROR,
9814 "ErrorCode,Invalid FullBW_ULMUMIMO");
9815 return STATUS_SENT_ERROR;
9816 }
9817
9818 if (sta_set_fullbw_ulmumimo(dut, intf, set_val)) {
9819 sigma_dut_print(dut, DUT_MSG_ERROR,
9820 "Failed to set FullBW_ULMUMIMO %d",
9821 set_val);
9822 send_resp(dut, conn, SIGMA_ERROR,
9823 "ErrorCode,Failed to set FullBW_ULMUMIMO");
9824 return STATUS_SENT_ERROR;
9825 }
9826 }
9827
Srinivas Girigowda6707f032020-10-26 15:24:46 -07009828 val = get_param(cmd, "TWTInfoFrameTx");
9829 if (val) {
9830 if (strcasecmp(val, "Enable") == 0) {
9831 /* No-op */
9832 } else if (strcasecmp(val, "Disable") == 0) {
9833 /* No-op */
9834 } else {
9835 send_resp(dut, conn, SIGMA_ERROR,
9836 "ErrorCode,Invalid TWTInfoFrameTx");
9837 return STATUS_SENT_ERROR;
9838 }
9839 }
9840
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07009841 val = get_param(cmd, "MU_EDCA");
9842 if (val && (strcasecmp(val, "Override") == 0)) {
9843 if (sta_set_mu_edca_override(dut, intf, 1)) {
9844 send_resp(dut, conn, SIGMA_ERROR,
9845 "ErrorCode,Failed to set MU EDCA override");
Jouni Malinen224e3902021-06-09 16:41:27 +03009846 return STATUS_SENT_ERROR;
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07009847 }
9848 }
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -07009849
Kiran Kumar Lokerefa7c7b92021-08-09 00:50:55 -07009850 val = get_param(cmd, "PPDUTxType");
9851 if (val && strcasecmp(val, "ER-SU") == 0) {
9852 if (sta_set_er_su_ppdu_type_tx(dut, intf, 1)) {
9853 send_resp(dut, conn, SIGMA_ERROR,
9854 "ErrorCode,Failed to set ER-SU PPDU type Tx");
9855 return STATUS_SENT_ERROR;
9856 }
9857 }
9858
9859 val = get_param(cmd, "RUAllocTone");
9860 if (val && strcasecmp(val, "242") == 0) {
9861 if (sta_set_ru_242_tone_tx(dut, intf, 1)) {
9862 send_resp(dut, conn, SIGMA_ERROR,
9863 "ErrorCode,Failed to set RU 242 tone Tx");
9864 return STATUS_SENT_ERROR;
9865 }
9866 }
9867
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07009868 val = get_param(cmd, "OMControl");
9869 if (val) {
9870 int set_val = 1;
9871
9872 if (strcasecmp(val, "Enable") == 0)
9873 set_val = 1;
9874 else if (strcasecmp(val, "Disable") == 0)
9875 set_val = 0;
9876
9877 if (sta_set_om_ctrl_supp(dut, intf, set_val)) {
9878 send_resp(dut, conn, SIGMA_ERROR,
9879 "ErrorCode,Failed to set OM ctrl supp");
Jouni Malinen224e3902021-06-09 16:41:27 +03009880 return STATUS_SENT_ERROR;
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07009881 }
9882 }
9883
Kiran Kumar Lokere4f2d4b02021-04-01 00:07:39 -07009884 val = get_param(cmd, "BSSMaxIdlePeriod");
9885 if (val && sta_set_bss_max_idle_period(dut, intf, atoi(val))) {
9886 send_resp(dut, conn, SIGMA_ERROR,
9887 "ErrorCode,Failed to set BSS max idle period");
9888 return STATUS_SENT_ERROR;
9889 }
9890
Kiran Kumar Lokere07ad92b2021-08-09 00:27:14 -07009891 val = get_param(cmd, "BSS_max_idle");
9892 if (val) {
9893 int set_val = 0;
9894
9895 if (strcasecmp(val, "Enable") == 0)
9896 set_val = 1;
9897 else if (strcasecmp(val, "Disable") == 0)
9898 set_val = 0;
9899 if (sta_set_bss_max_idle_support(dut, intf, set_val)) {
9900 send_resp(dut, conn, SIGMA_ERROR,
9901 "ErrorCode,Failed to set BSS max idle support");
9902 return STATUS_SENT_ERROR;
9903 }
9904 }
9905
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -07009906 val = get_param(cmd, "ADDBAResp_BufSize");
9907 if (val) {
9908 int buf_size;
9909
9910 if (strcasecmp(val, "gt64") == 0)
9911 buf_size = 256;
9912 else
9913 buf_size = 64;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009914 if (get_driver_type(dut) == DRIVER_WCN &&
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -07009915 sta_set_addba_buf_size(dut, intf, buf_size)) {
9916 send_resp(dut, conn, SIGMA_ERROR,
9917 "ErrorCode,set addbaresp_buff_size failed");
Jouni Malinen224e3902021-06-09 16:41:27 +03009918 return STATUS_SENT_ERROR;
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -07009919 }
9920 }
9921
9922 val = get_param(cmd, "ADDBAReq_BufSize");
9923 if (val) {
9924 int buf_size;
9925
9926 if (strcasecmp(val, "gt64") == 0)
9927 buf_size = 256;
9928 else
9929 buf_size = 64;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009930 if (get_driver_type(dut) == DRIVER_WCN &&
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -07009931 sta_set_addba_buf_size(dut, intf, buf_size)) {
9932 send_resp(dut, conn, SIGMA_ERROR,
9933 "ErrorCode,set addbareq_buff_size failed");
Jouni Malinen224e3902021-06-09 16:41:27 +03009934 return STATUS_SENT_ERROR;
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -07009935 }
9936 }
9937
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009938 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
9939}
9940
9941
9942static int sta_set_wireless_60g(struct sigma_dut *dut,
9943 struct sigma_conn *conn,
9944 struct sigma_cmd *cmd)
9945{
9946 const char *dev_role = get_param(cmd, "DevRole");
9947
9948 if (!dev_role) {
9949 send_resp(dut, conn, SIGMA_INVALID,
9950 "ErrorCode,DevRole not specified");
9951 return 0;
9952 }
9953
9954 if (strcasecmp(dev_role, "PCP") == 0)
9955 return sta_set_60g_pcp(dut, conn, cmd);
9956 if (strcasecmp(dev_role, "STA") == 0)
9957 return sta_set_60g_sta(dut, conn, cmd);
9958 send_resp(dut, conn, SIGMA_INVALID,
9959 "ErrorCode,DevRole not supported");
9960 return 0;
9961}
9962
9963
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05309964static int sta_set_wireless_oce(struct sigma_dut *dut, struct sigma_conn *conn,
9965 struct sigma_cmd *cmd)
9966{
9967 int status;
9968 const char *intf = get_param(cmd, "Interface");
9969 const char *val = get_param(cmd, "DevRole");
9970
9971 if (val && strcasecmp(val, "STA-CFON") == 0) {
9972 status = sta_cfon_set_wireless(dut, conn, cmd);
9973 if (status)
9974 return status;
9975 }
9976 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
9977}
9978
9979
Jouni Malinen67433fc2020-06-26 22:50:33 +03009980static enum sigma_cmd_result
9981sta_set_wireless_wpa3(struct sigma_dut *dut, struct sigma_conn *conn,
9982 struct sigma_cmd *cmd)
Vamsi Krishnac1633d22020-05-06 18:31:21 +05309983{
9984 const char *intf = get_param(cmd, "Interface");
9985 const char *val;
9986
9987 val = get_param(cmd, "ocvc");
9988 if (val)
9989 dut->ocvc = atoi(val);
9990
Jouni Malinen67433fc2020-06-26 22:50:33 +03009991 val = get_param(cmd, "ClientPrivacy");
Veerendranath Jakkam47867202020-12-21 01:53:52 +05309992 if (val && dut->client_privacy != atoi(val) &&
9993 sta_set_client_privacy(dut, conn, intf, atoi(val))) {
9994 send_resp(dut, conn, SIGMA_ERROR,
9995 "errorCode,Failed to configure random MAC address use");
9996 return STATUS_SENT_ERROR;
Jouni Malinen67433fc2020-06-26 22:50:33 +03009997 }
9998
Vamsi Krishnac1633d22020-05-06 18:31:21 +05309999 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
10000}
10001
10002
Jouni Malinenf7222712019-06-13 01:50:21 +030010003static enum sigma_cmd_result cmd_sta_set_wireless(struct sigma_dut *dut,
10004 struct sigma_conn *conn,
10005 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010006{
10007 const char *val;
10008
10009 val = get_param(cmd, "Program");
10010 if (val) {
10011 if (strcasecmp(val, "11n") == 0)
10012 return cmd_sta_set_11n(dut, conn, cmd);
Amarnath Hullur Subramanyam4f860292018-01-31 03:49:35 -080010013 if (strcasecmp(val, "VHT") == 0 || strcasecmp(val, "HE") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010014 return cmd_sta_set_wireless_vht(dut, conn, cmd);
10015 if (strcasecmp(val, "60ghz") == 0)
10016 return sta_set_wireless_60g(dut, conn, cmd);
Ankita Bajaj0d5825b2017-10-25 16:20:17 +053010017 if (strcasecmp(val, "OCE") == 0)
10018 return sta_set_wireless_oce(dut, conn, cmd);
Alexei Avshalom Lazar66bb9972018-12-18 16:01:43 +020010019 /* sta_set_wireless in WPS program is only used for 60G */
10020 if (is_60g_sigma_dut(dut))
10021 return sta_set_wireless_60g(dut, conn, cmd);
Vamsi Krishnac1633d22020-05-06 18:31:21 +053010022 if (strcasecmp(val, "WPA3") == 0)
10023 return sta_set_wireless_wpa3(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010024 send_resp(dut, conn, SIGMA_ERROR,
10025 "ErrorCode,Program value not supported");
10026 } else {
10027 send_resp(dut, conn, SIGMA_ERROR,
10028 "ErrorCode,Program argument not available");
10029 }
10030
10031 return 0;
10032}
10033
10034
10035static void ath_sta_inject_frame(struct sigma_dut *dut, const char *intf,
10036 int tid)
10037{
10038 char buf[100];
10039 int tid_to_dscp [] = { 0x00, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0 };
10040
Pradeep Reddy POTTETId31d1322016-10-13 17:22:03 +053010041 if (tid < 0 ||
10042 tid >= (int) (sizeof(tid_to_dscp) / sizeof(tid_to_dscp[0]))) {
10043 sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported TID: %d", tid);
10044 return;
10045 }
10046
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010047 /*
10048 * Two ways to ensure that addba request with a
10049 * non zero TID could be sent out. EV 117296
10050 */
10051 snprintf(buf, sizeof(buf),
10052 "ping -c 8 -Q %d `arp -a | grep wlan0 | awk '{print $2}' | tr -d '()'`",
10053 tid);
10054 if (system(buf) != 0) {
10055 sigma_dut_print(dut, DUT_MSG_ERROR,
10056 "Ping did not send out");
10057 }
10058
10059 snprintf(buf, sizeof(buf),
10060 "iwconfig %s | grep Access | awk '{print $6}' > %s",
10061 intf, VI_QOS_TMP_FILE);
10062 if (system(buf) != 0)
10063 return;
10064
10065 snprintf(buf, sizeof(buf),
10066 "ifconfig %s | grep HWaddr | cut -b 39-56 >> %s",
10067 intf, VI_QOS_TMP_FILE);
10068 if (system(buf) != 0)
10069 sigma_dut_print(dut, DUT_MSG_ERROR, "HWaddr matching failed");
10070
10071 snprintf(buf,sizeof(buf), "sed -n '3,$p' %s >> %s",
10072 VI_QOS_REFFILE, VI_QOS_TMP_FILE);
10073 if (system(buf) != 0) {
10074 sigma_dut_print(dut, DUT_MSG_ERROR,
10075 "VI_QOS_TEMP_FILE generation error failed");
10076 }
10077 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
10078 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
10079 if (system(buf) != 0) {
10080 sigma_dut_print(dut, DUT_MSG_ERROR,
10081 "VI_QOS_FILE generation failed");
10082 }
10083
10084 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
10085 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
10086 if (system(buf) != 0) {
10087 sigma_dut_print(dut, DUT_MSG_ERROR,
10088 "VI_QOS_FILE generation failed");
10089 }
10090
10091 snprintf(buf, sizeof(buf), "ethinject %s %s", intf, VI_QOS_FILE);
10092 if (system(buf) != 0) {
10093 }
10094}
10095
10096
10097static int ath_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
10098 struct sigma_cmd *cmd)
10099{
10100 const char *intf = get_param(cmd, "Interface");
10101 const char *val;
10102 int tid = 0;
10103 char buf[100];
10104
10105 val = get_param(cmd, "TID");
10106 if (val) {
10107 tid = atoi(val);
10108 if (tid)
10109 ath_sta_inject_frame(dut, intf, tid);
10110 }
10111
10112 /* Command sequence for ADDBA request on Peregrine based devices */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010113 run_iwpriv(dut, intf, "setaddbaoper 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010114
10115 snprintf(buf, sizeof(buf), "wifitool %s senddelba 1 %d 1 4", intf, tid);
10116 if (system(buf) != 0) {
10117 sigma_dut_print(dut, DUT_MSG_ERROR,
10118 "wifitool senddelba failed");
10119 }
10120
10121 snprintf(buf, sizeof(buf), "wifitool %s sendaddba 1 %d 64", intf, tid);
10122 if (system(buf) != 0) {
10123 sigma_dut_print(dut, DUT_MSG_ERROR,
10124 "wifitool sendaddba failed");
10125 }
10126
10127 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
10128
10129 return 1;
10130}
10131
10132
Lior David9981b512017-01-20 13:16:40 +020010133#ifdef __linux__
10134
10135static int wil6210_send_addba(struct sigma_dut *dut, const char *dest_mac,
10136 int agg_size)
10137{
10138 char dir[128], buf[128];
10139 FILE *f;
10140 regex_t re;
10141 regmatch_t m[2];
Jouni Malinen3aa72862019-05-29 23:14:51 +030010142 int rc, ret = -1, vring_id, found, res;
Lior David9981b512017-01-20 13:16:40 +020010143
10144 if (wil6210_get_debugfs_dir(dut, dir, sizeof(dir))) {
10145 sigma_dut_print(dut, DUT_MSG_ERROR,
10146 "failed to get wil6210 debugfs dir");
10147 return -1;
10148 }
10149
Jouni Malinen3aa72862019-05-29 23:14:51 +030010150 res = snprintf(buf, sizeof(buf), "%s/vrings", dir);
10151 if (res < 0 || res >= sizeof(buf))
10152 return -1;
Lior David9981b512017-01-20 13:16:40 +020010153 f = fopen(buf, "r");
10154 if (!f) {
10155 sigma_dut_print(dut, DUT_MSG_ERROR, "failed to open: %s", buf);
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +020010156 /* newer wil6210 driver renamed file to "rings" */
Jouni Malinen3aa72862019-05-29 23:14:51 +030010157 res = snprintf(buf, sizeof(buf), "%s/rings", dir);
10158 if (res < 0 || res >= sizeof(buf))
10159 return -1;
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +020010160 f = fopen(buf, "r");
10161 if (!f) {
10162 sigma_dut_print(dut, DUT_MSG_ERROR,
10163 "failed to open: %s", buf);
10164 return -1;
10165 }
Lior David9981b512017-01-20 13:16:40 +020010166 }
10167
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +020010168 /* can be either VRING tx... or RING... */
10169 if (regcomp(&re, "RING tx_[ \t]*([0-9]+)", REG_EXTENDED)) {
Lior David9981b512017-01-20 13:16:40 +020010170 sigma_dut_print(dut, DUT_MSG_ERROR, "regcomp failed");
10171 goto out;
10172 }
10173
10174 /* find TX VRING for the mac address */
10175 found = 0;
10176 while (fgets(buf, sizeof(buf), f)) {
10177 if (strcasestr(buf, dest_mac)) {
10178 found = 1;
10179 break;
10180 }
10181 }
10182
10183 if (!found) {
10184 sigma_dut_print(dut, DUT_MSG_ERROR,
10185 "no TX VRING for %s", dest_mac);
10186 goto out;
10187 }
10188
10189 /* extract VRING ID, "VRING tx_<id> = {" */
10190 if (!fgets(buf, sizeof(buf), f)) {
10191 sigma_dut_print(dut, DUT_MSG_ERROR,
10192 "no VRING start line for %s", dest_mac);
10193 goto out;
10194 }
10195
10196 rc = regexec(&re, buf, 2, m, 0);
10197 regfree(&re);
10198 if (rc || m[1].rm_so < 0) {
10199 sigma_dut_print(dut, DUT_MSG_ERROR,
10200 "no VRING TX ID for %s", dest_mac);
10201 goto out;
10202 }
10203 buf[m[1].rm_eo] = 0;
10204 vring_id = atoi(&buf[m[1].rm_so]);
10205
10206 /* send the addba command */
10207 fclose(f);
Jouni Malinen3aa72862019-05-29 23:14:51 +030010208 res = snprintf(buf, sizeof(buf), "%s/back", dir);
10209 if (res < 0 || res >= sizeof(buf))
10210 return -1;
Lior David9981b512017-01-20 13:16:40 +020010211 f = fopen(buf, "w");
10212 if (!f) {
10213 sigma_dut_print(dut, DUT_MSG_ERROR,
10214 "failed to open: %s", buf);
10215 return -1;
10216 }
10217
10218 fprintf(f, "add %d %d\n", vring_id, agg_size);
10219
10220 ret = 0;
10221
10222out:
10223 fclose(f);
10224
10225 return ret;
10226}
10227
10228
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +020010229int send_addba_60g(struct sigma_dut *dut, struct sigma_conn *conn,
10230 struct sigma_cmd *cmd, const char *mac_param)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010231{
10232 const char *val;
10233 int tid = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010234
10235 val = get_param(cmd, "TID");
10236 if (val) {
10237 tid = atoi(val);
10238 if (tid != 0) {
10239 sigma_dut_print(dut, DUT_MSG_ERROR,
10240 "Ignore TID %d for send_addba use TID 0 for 60g since only 0 required on TX",
10241 tid);
10242 }
10243 }
10244
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +020010245 val = get_param(cmd, mac_param);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010246 if (!val) {
10247 sigma_dut_print(dut, DUT_MSG_ERROR,
10248 "Currently not supporting addba for 60G without Dest_mac");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020010249 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010250 }
10251
Lior David9981b512017-01-20 13:16:40 +020010252 if (wil6210_send_addba(dut, val, dut->back_rcv_buf))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010253 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010254
10255 return 1;
10256}
10257
Lior David9981b512017-01-20 13:16:40 +020010258#endif /* __linux__ */
10259
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010260
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080010261static int wcn_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
10262 struct sigma_cmd *cmd)
10263{
10264#ifdef NL80211_SUPPORT
10265 const char *intf = get_param(cmd, "Interface");
10266 const char *val;
10267 int tid = -1;
10268 int bufsize = 64;
10269 struct nl_msg *msg;
10270 int ret = 0;
10271 struct nlattr *params;
10272 int ifindex;
10273
10274 val = get_param(cmd, "TID");
10275 if (val)
10276 tid = atoi(val);
10277
10278 if (tid == -1) {
10279 send_resp(dut, conn, SIGMA_ERROR,
10280 "ErrorCode,sta_send_addba tid invalid");
10281 return 0;
10282 }
10283
10284 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
10285
10286 ifindex = if_nametoindex(intf);
10287 if (ifindex == 0) {
10288 sigma_dut_print(dut, DUT_MSG_ERROR,
10289 "%s: Index for interface %s failed",
10290 __func__, intf);
10291 send_resp(dut, conn, SIGMA_ERROR,
10292 "ErrorCode,sta_send_addba interface invalid");
10293 return 0;
10294 }
10295
10296 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
10297 NL80211_CMD_VENDOR)) ||
10298 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
10299 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
10300 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
10301 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
10302 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
10303 nla_put_u8(msg,
10304 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADD_DEL_BA_SESSION,
10305 QCA_WLAN_ADD_BA) ||
10306 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BA_TID,
10307 tid) ||
Kiran Kumar Lokere26e27582018-08-01 16:18:34 -070010308 nla_put_u16(msg,
10309 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE,
10310 bufsize)) {
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080010311 sigma_dut_print(dut, DUT_MSG_ERROR,
10312 "%s: err in adding vendor_cmd and vendor_data",
10313 __func__);
10314 nlmsg_free(msg);
10315 send_resp(dut, conn, SIGMA_ERROR,
10316 "ErrorCode,sta_send_addba err in adding vendor_cmd and vendor_data");
10317 return 0;
10318 }
10319 nla_nest_end(msg, params);
10320
10321 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
10322 if (ret) {
10323 sigma_dut_print(dut, DUT_MSG_ERROR,
10324 "%s: err in send_and_recv_msgs, ret=%d",
10325 __func__, ret);
Sunil Dutt30605592018-05-04 20:35:50 +053010326 if (ret == -EOPNOTSUPP)
10327 return 1;
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080010328 send_resp(dut, conn, SIGMA_ERROR,
10329 "ErrorCode,sta_send_addba err in send_and_recv_msgs");
10330 return 0;
10331 }
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080010332#else /* NL80211_SUPPORT */
10333 sigma_dut_print(dut, DUT_MSG_ERROR,
10334 "sta_send_addba not supported without NL80211_SUPPORT defined");
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080010335#endif /* NL80211_SUPPORT */
Sunil Dutt30605592018-05-04 20:35:50 +053010336
10337 return 1;
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080010338}
10339
10340
Jouni Malinenf7222712019-06-13 01:50:21 +030010341static enum sigma_cmd_result cmd_sta_send_addba(struct sigma_dut *dut,
10342 struct sigma_conn *conn,
10343 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010344{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010345 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010346 case DRIVER_ATHEROS:
10347 return ath_sta_send_addba(dut, conn, cmd);
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080010348 case DRIVER_WCN:
10349 return wcn_sta_send_addba(dut, conn, cmd);
Lior David9981b512017-01-20 13:16:40 +020010350#ifdef __linux__
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010351 case DRIVER_WIL6210:
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +020010352 return send_addba_60g(dut, conn, cmd, "Dest_mac");
Lior David9981b512017-01-20 13:16:40 +020010353#endif /* __linux__ */
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010354 default:
10355 /*
10356 * There is no driver specific implementation for other drivers.
10357 * Ignore the command and report COMPLETE since the following
10358 * throughput test operation will end up sending ADDBA anyway.
10359 */
10360 return 1;
10361 }
10362}
10363
10364
10365int inject_eth_frame(int s, const void *data, size_t len,
10366 unsigned short ethtype, char *dst, char *src)
10367{
10368 struct iovec iov[4] = {
10369 {
10370 .iov_base = dst,
10371 .iov_len = ETH_ALEN,
10372 },
10373 {
10374 .iov_base = src,
10375 .iov_len = ETH_ALEN,
10376 },
10377 {
10378 .iov_base = &ethtype,
10379 .iov_len = sizeof(unsigned short),
10380 },
10381 {
10382 .iov_base = (void *) data,
10383 .iov_len = len,
10384 }
10385 };
10386 struct msghdr msg = {
10387 .msg_name = NULL,
10388 .msg_namelen = 0,
10389 .msg_iov = iov,
10390 .msg_iovlen = 4,
10391 .msg_control = NULL,
10392 .msg_controllen = 0,
10393 .msg_flags = 0,
10394 };
10395
10396 return sendmsg(s, &msg, 0);
10397}
10398
10399#if defined(__linux__) || defined(__QNXNTO__)
10400
10401int inject_frame(int s, const void *data, size_t len, int encrypt)
10402{
10403#define IEEE80211_RADIOTAP_F_WEP 0x04
10404#define IEEE80211_RADIOTAP_F_FRAG 0x08
10405 unsigned char rtap_hdr[] = {
10406 0x00, 0x00, /* radiotap version */
10407 0x0e, 0x00, /* radiotap length */
10408 0x02, 0xc0, 0x00, 0x00, /* bmap: flags, tx and rx flags */
10409 IEEE80211_RADIOTAP_F_FRAG, /* F_FRAG (fragment if required) */
10410 0x00, /* padding */
10411 0x00, 0x00, /* RX and TX flags to indicate that */
10412 0x00, 0x00, /* this is the injected frame directly */
10413 };
10414 struct iovec iov[2] = {
10415 {
10416 .iov_base = &rtap_hdr,
10417 .iov_len = sizeof(rtap_hdr),
10418 },
10419 {
10420 .iov_base = (void *) data,
10421 .iov_len = len,
10422 }
10423 };
10424 struct msghdr msg = {
10425 .msg_name = NULL,
10426 .msg_namelen = 0,
10427 .msg_iov = iov,
10428 .msg_iovlen = 2,
10429 .msg_control = NULL,
10430 .msg_controllen = 0,
10431 .msg_flags = 0,
10432 };
10433
10434 if (encrypt)
10435 rtap_hdr[8] |= IEEE80211_RADIOTAP_F_WEP;
10436
10437 return sendmsg(s, &msg, 0);
10438}
10439
10440
10441int open_monitor(const char *ifname)
10442{
10443#ifdef __QNXNTO__
10444 struct sockaddr_dl ll;
10445 int s;
10446
10447 memset(&ll, 0, sizeof(ll));
10448 ll.sdl_family = AF_LINK;
10449 ll.sdl_index = if_nametoindex(ifname);
10450 if (ll.sdl_index == 0) {
10451 perror("if_nametoindex");
10452 return -1;
10453 }
10454 s = socket(PF_INET, SOCK_RAW, 0);
10455#else /* __QNXNTO__ */
10456 struct sockaddr_ll ll;
10457 int s;
10458
10459 memset(&ll, 0, sizeof(ll));
10460 ll.sll_family = AF_PACKET;
10461 ll.sll_ifindex = if_nametoindex(ifname);
10462 if (ll.sll_ifindex == 0) {
10463 perror("if_nametoindex");
10464 return -1;
10465 }
10466 s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
10467#endif /* __QNXNTO__ */
10468 if (s < 0) {
10469 perror("socket[PF_PACKET,SOCK_RAW]");
10470 return -1;
10471 }
10472
10473 if (bind(s, (struct sockaddr *) &ll, sizeof(ll)) < 0) {
10474 perror("monitor socket bind");
10475 close(s);
10476 return -1;
10477 }
10478
10479 return s;
10480}
10481
10482
10483static int hex2num(char c)
10484{
10485 if (c >= '0' && c <= '9')
10486 return c - '0';
10487 if (c >= 'a' && c <= 'f')
10488 return c - 'a' + 10;
10489 if (c >= 'A' && c <= 'F')
10490 return c - 'A' + 10;
10491 return -1;
10492}
10493
10494
10495int hwaddr_aton(const char *txt, unsigned char *addr)
10496{
10497 int i;
10498
10499 for (i = 0; i < 6; i++) {
10500 int a, b;
10501
10502 a = hex2num(*txt++);
10503 if (a < 0)
10504 return -1;
10505 b = hex2num(*txt++);
10506 if (b < 0)
10507 return -1;
10508 *addr++ = (a << 4) | b;
10509 if (i < 5 && *txt++ != ':')
10510 return -1;
10511 }
10512
10513 return 0;
10514}
10515
10516#endif /* defined(__linux__) || defined(__QNXNTO__) */
10517
Veerendranath Jakkam49774122020-07-05 09:52:18 +053010518
10519#ifdef NL80211_SUPPORT
10520static int nl80211_send_frame_cmd(struct sigma_dut *dut, const char *intf,
10521 const u8 *data, size_t data_len, int freq)
10522{
10523 struct nl_msg *msg;
10524 int ret = 0;
10525 int ifindex;
10526
10527 ifindex = if_nametoindex(intf);
10528 if (ifindex == 0) {
10529 sigma_dut_print(dut, DUT_MSG_ERROR,
10530 "%s: Index for interface %s failed",
10531 __func__, intf);
10532 return -1;
10533 }
10534
10535 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
10536 NL80211_CMD_FRAME)) ||
10537 (freq && nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq)) ||
10538 nla_put(msg, NL80211_ATTR_FRAME, data_len, data)) {
10539 sigma_dut_print(dut, DUT_MSG_ERROR,
10540 "%s: Error in adding NL80211_CMD_FRAME",
10541 __func__);
10542 nlmsg_free(msg);
10543 return -1;
10544 }
10545
10546 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
10547 if (ret) {
10548 sigma_dut_print(dut, DUT_MSG_ERROR,
10549 "nl80211: Frame command failed: ret=%d (%s) req=%u",
10550 ret, strerror(-ret), freq);
10551 return -1;
10552 }
10553
10554 return 0;
10555}
10556#endif /* NL80211_SUPPORT */
10557
10558
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010559enum send_frame_type {
10560 DISASSOC, DEAUTH, SAQUERY, AUTH, ASSOCREQ, REASSOCREQ, DLS_REQ
10561};
10562enum send_frame_protection {
10563 CORRECT_KEY, INCORRECT_KEY, UNPROTECTED
10564};
10565
10566
10567static int sta_inject_frame(struct sigma_dut *dut, struct sigma_conn *conn,
Veerendranath Jakkam49774122020-07-05 09:52:18 +053010568 const char *intf, enum send_frame_type frame,
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010569 enum send_frame_protection protected,
Veerendranath Jakkam49774122020-07-05 09:52:18 +053010570 const char *dest, int use_monitor)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010571{
10572#ifdef __linux__
10573 unsigned char buf[1000], *pos;
10574 int s, res;
10575 char bssid[20], addr[20];
10576 char result[32], ssid[100];
10577 size_t ssid_len;
10578
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010579 if (get_wpa_status(get_station_ifname(dut), "wpa_state", result,
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010580 sizeof(result)) < 0 ||
10581 strncmp(result, "COMPLETED", 9) != 0) {
10582 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Not connected");
10583 return 0;
10584 }
10585
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010586 if (get_wpa_status(get_station_ifname(dut), "bssid",
10587 bssid, sizeof(bssid)) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010588 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
10589 "current BSSID");
10590 return 0;
10591 }
10592
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010593 if (get_wpa_status(get_station_ifname(dut), "address",
10594 addr, sizeof(addr)) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010595 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
10596 "own MAC address");
10597 return 0;
10598 }
10599
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010600 if (get_wpa_status(get_station_ifname(dut), "ssid", ssid, sizeof(ssid))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010601 < 0) {
10602 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
10603 "current SSID");
10604 return 0;
10605 }
10606 ssid_len = strlen(ssid);
10607
10608 pos = buf;
10609
10610 /* Frame Control */
10611 switch (frame) {
10612 case DISASSOC:
10613 *pos++ = 0xa0;
10614 break;
10615 case DEAUTH:
10616 *pos++ = 0xc0;
10617 break;
10618 case SAQUERY:
10619 *pos++ = 0xd0;
10620 break;
10621 case AUTH:
10622 *pos++ = 0xb0;
10623 break;
10624 case ASSOCREQ:
10625 *pos++ = 0x00;
10626 break;
10627 case REASSOCREQ:
10628 *pos++ = 0x20;
10629 break;
10630 case DLS_REQ:
10631 *pos++ = 0xd0;
10632 break;
10633 }
10634
10635 if (protected == INCORRECT_KEY)
10636 *pos++ = 0x40; /* Set Protected field to 1 */
10637 else
10638 *pos++ = 0x00;
10639
10640 /* Duration */
10641 *pos++ = 0x00;
10642 *pos++ = 0x00;
10643
10644 /* addr1 = DA (current AP) */
10645 hwaddr_aton(bssid, pos);
10646 pos += 6;
10647 /* addr2 = SA (own address) */
10648 hwaddr_aton(addr, pos);
10649 pos += 6;
10650 /* addr3 = BSSID (current AP) */
10651 hwaddr_aton(bssid, pos);
10652 pos += 6;
10653
10654 /* Seq# (to be filled by driver/mac80211) */
10655 *pos++ = 0x00;
10656 *pos++ = 0x00;
10657
10658 if (protected == INCORRECT_KEY) {
10659 /* CCMP parameters */
10660 memcpy(pos, "\x61\x01\x00\x20\x00\x10\x00\x00", 8);
10661 pos += 8;
10662 }
10663
10664 if (protected == INCORRECT_KEY) {
10665 switch (frame) {
10666 case DEAUTH:
10667 /* Reason code (encrypted) */
10668 memcpy(pos, "\xa7\x39", 2);
10669 pos += 2;
10670 break;
10671 case DISASSOC:
10672 /* Reason code (encrypted) */
10673 memcpy(pos, "\xa7\x39", 2);
10674 pos += 2;
10675 break;
10676 case SAQUERY:
10677 /* Category|Action|TransID (encrypted) */
10678 memcpy(pos, "\x6f\xbd\xe9\x4d", 4);
10679 pos += 4;
10680 break;
10681 default:
10682 return -1;
10683 }
10684
10685 /* CCMP MIC */
10686 memcpy(pos, "\xc8\xd8\x3b\x06\x5d\xb7\x25\x68", 8);
10687 pos += 8;
10688 } else {
10689 switch (frame) {
10690 case DEAUTH:
10691 /* reason code = 8 */
10692 *pos++ = 0x08;
10693 *pos++ = 0x00;
10694 break;
10695 case DISASSOC:
10696 /* reason code = 8 */
10697 *pos++ = 0x08;
10698 *pos++ = 0x00;
10699 break;
10700 case SAQUERY:
10701 /* Category - SA Query */
10702 *pos++ = 0x08;
10703 /* SA query Action - Request */
10704 *pos++ = 0x00;
10705 /* Transaction ID */
10706 *pos++ = 0x12;
10707 *pos++ = 0x34;
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +053010708 if (dut->saquery_oci_freq) {
10709 /* OCI IE - Extended ID */
10710 *pos++ = 0xFF;
10711 *pos++ = 0x04;
10712 *pos++ = 0x36;
10713 /* Operating Class */
10714 *pos++ = 0x74;
10715 /* Primary Channel */
10716 *pos++ = freq_to_channel(dut->saquery_oci_freq);
10717 /* Frequency Segment 1 Channel Number */
10718 *pos++ = 0x00;
10719 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010720 break;
10721 case AUTH:
10722 /* Auth Alg (Open) */
10723 *pos++ = 0x00;
10724 *pos++ = 0x00;
10725 /* Seq# */
10726 *pos++ = 0x01;
10727 *pos++ = 0x00;
10728 /* Status code */
10729 *pos++ = 0x00;
10730 *pos++ = 0x00;
10731 break;
10732 case ASSOCREQ:
10733 /* Capability Information */
10734 *pos++ = 0x31;
10735 *pos++ = 0x04;
10736 /* Listen Interval */
10737 *pos++ = 0x0a;
10738 *pos++ = 0x00;
10739 /* SSID */
10740 *pos++ = 0x00;
10741 *pos++ = ssid_len;
10742 memcpy(pos, ssid, ssid_len);
10743 pos += ssid_len;
10744 /* Supported Rates */
10745 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
10746 10);
10747 pos += 10;
10748 /* Extended Supported Rates */
10749 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
10750 pos += 6;
10751 /* RSN */
10752 memcpy(pos, "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00"
10753 "\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x02\xc0"
10754 "\x00\x00\x00\x00\x0f\xac\x06", 28);
10755 pos += 28;
10756 break;
10757 case REASSOCREQ:
10758 /* Capability Information */
10759 *pos++ = 0x31;
10760 *pos++ = 0x04;
10761 /* Listen Interval */
10762 *pos++ = 0x0a;
10763 *pos++ = 0x00;
10764 /* Current AP */
10765 hwaddr_aton(bssid, pos);
10766 pos += 6;
10767 /* SSID */
10768 *pos++ = 0x00;
10769 *pos++ = ssid_len;
10770 memcpy(pos, ssid, ssid_len);
10771 pos += ssid_len;
10772 /* Supported Rates */
10773 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
10774 10);
10775 pos += 10;
10776 /* Extended Supported Rates */
10777 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
10778 pos += 6;
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +053010779 /* RSNE - Group and Pairwise ciphers */
10780 memcpy(pos,
10781 "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04",
10782 14);
10783 pos += 14;
10784 /* RSNE - AKM Suite count */
10785 *pos++ = 0x01;
10786 *pos++ = 0x00;
10787 /* RSNE - AKM Suites */
10788 if (dut->program == PROGRAM_WPA3)
10789 memcpy(pos, "\x00\x0f\xac\x08", 4);
10790 else
10791 memcpy(pos, "\x00\x0f\xac\x02", 4);
10792 pos += 4;
10793 /* RSNE - Capabilities */
10794 *pos++ = 0xc0;
10795 if (dut->ocvc)
10796 *pos++ = 0x40;
10797 else
10798 *pos++ = 0x00;
10799 /* RSNE - PMKID list and Group Management Ciphers */
10800 memcpy(pos, "\x00\x00\x00\x0f\xac\x06", 6);
10801 pos += 6;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010802 break;
10803 case DLS_REQ:
10804 /* Category - DLS */
10805 *pos++ = 0x02;
10806 /* DLS Action - Request */
10807 *pos++ = 0x00;
10808 /* Destination MACAddress */
10809 if (dest)
10810 hwaddr_aton(dest, pos);
10811 else
10812 memset(pos, 0, 6);
10813 pos += 6;
10814 /* Source MACAddress */
10815 hwaddr_aton(addr, pos);
10816 pos += 6;
10817 /* Capability Information */
10818 *pos++ = 0x10; /* Privacy */
10819 *pos++ = 0x06; /* QoS */
10820 /* DLS Timeout Value */
10821 *pos++ = 0x00;
10822 *pos++ = 0x01;
10823 /* Supported rates */
10824 *pos++ = 0x01;
10825 *pos++ = 0x08;
10826 *pos++ = 0x0c; /* 6 Mbps */
10827 *pos++ = 0x12; /* 9 Mbps */
10828 *pos++ = 0x18; /* 12 Mbps */
10829 *pos++ = 0x24; /* 18 Mbps */
10830 *pos++ = 0x30; /* 24 Mbps */
10831 *pos++ = 0x48; /* 36 Mbps */
10832 *pos++ = 0x60; /* 48 Mbps */
10833 *pos++ = 0x6c; /* 54 Mbps */
10834 /* TODO: Extended Supported Rates */
10835 /* TODO: HT Capabilities */
10836 break;
10837 }
10838 }
10839
Veerendranath Jakkam49774122020-07-05 09:52:18 +053010840 if (use_monitor) {
10841 s = open_monitor("sigmadut");
10842 if (s < 0) {
10843 send_resp(dut, conn, SIGMA_ERROR,
10844 "errorCode,Failed to open monitor socket");
10845 return 0;
10846 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010847
Veerendranath Jakkam49774122020-07-05 09:52:18 +053010848 res = inject_frame(s, buf, pos - buf, protected == CORRECT_KEY);
10849 if (res < 0) {
10850 send_resp(dut, conn, SIGMA_ERROR,
10851 "errorCode,Failed to inject frame");
10852 close(s);
10853 return 0;
10854 }
10855 if (res < pos - buf) {
10856 send_resp(dut, conn, SIGMA_ERROR,
10857 "errorCode,Only partial frame sent");
10858 close(s);
10859 return 0;
10860 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010861
Veerendranath Jakkam49774122020-07-05 09:52:18 +053010862 close(s);
10863 } else {
10864#ifdef NL80211_SUPPORT
10865 int freq;
10866 char freq_str[10];
10867
10868 if (get_wpa_status(get_station_ifname(dut), "freq",
10869 freq_str, sizeof(freq_str)) < 0) {
10870 send_resp(dut, conn, SIGMA_ERROR,
10871 "errorCode,Could not get current operating frequency");
10872 return 0;
10873 }
10874 freq = atoi(freq_str);
10875
10876 if (nl80211_send_frame_cmd(dut, intf, buf, pos - buf, freq)) {
10877 send_resp(dut, conn, SIGMA_ERROR,
10878 "errorCode,Failed to inject frame");
10879 return 0;
10880 }
10881#else /* NL80211_SUPPORT */
10882 send_resp(dut, conn, SIGMA_ERROR,
10883 "errorCode,Failed to inject frame (no NL80211_SUPPORT)");
10884 return 0;
10885#endif /* NL80211_SUPPORT */
10886 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010887
10888 return 1;
10889#else /* __linux__ */
10890 send_resp(dut, conn, SIGMA_ERROR, "errorCode,sta_send_frame not "
10891 "yet supported");
10892 return 0;
10893#endif /* __linux__ */
10894}
10895
10896
10897static int cmd_sta_send_frame_tdls(struct sigma_dut *dut,
10898 struct sigma_conn *conn,
10899 struct sigma_cmd *cmd)
10900{
10901 const char *intf = get_param(cmd, "Interface");
10902 const char *sta, *val;
10903 unsigned char addr[ETH_ALEN];
10904 char buf[100];
10905
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +030010906 if (!intf)
10907 return -1;
10908
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010909 sta = get_param(cmd, "peer");
10910 if (sta == NULL)
10911 sta = get_param(cmd, "station");
10912 if (sta == NULL) {
10913 send_resp(dut, conn, SIGMA_ERROR,
10914 "ErrorCode,Missing peer address");
10915 return 0;
10916 }
10917 if (hwaddr_aton(sta, addr) < 0) {
10918 send_resp(dut, conn, SIGMA_ERROR,
10919 "ErrorCode,Invalid peer address");
10920 return 0;
10921 }
10922
10923 val = get_param(cmd, "type");
10924 if (val == NULL)
10925 return -1;
10926
10927 if (strcasecmp(val, "DISCOVERY") == 0) {
10928 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", sta);
10929 if (wpa_command(intf, buf) < 0) {
10930 send_resp(dut, conn, SIGMA_ERROR,
10931 "ErrorCode,Failed to send TDLS discovery");
10932 return 0;
10933 }
10934 return 1;
10935 }
10936
10937 if (strcasecmp(val, "SETUP") == 0) {
10938 int status = 0, timeout = 0;
10939
10940 val = get_param(cmd, "Status");
10941 if (val)
10942 status = atoi(val);
10943
10944 val = get_param(cmd, "Timeout");
10945 if (val)
10946 timeout = atoi(val);
10947
10948 if (status != 0 && status != 37) {
10949 send_resp(dut, conn, SIGMA_ERROR,
10950 "ErrorCode,Unsupported status value");
10951 return 0;
10952 }
10953
10954 if (timeout != 0 && timeout != 301) {
10955 send_resp(dut, conn, SIGMA_ERROR,
10956 "ErrorCode,Unsupported timeout value");
10957 return 0;
10958 }
10959
10960 if (status && timeout) {
10961 send_resp(dut, conn, SIGMA_ERROR,
10962 "ErrorCode,Unsupported timeout+status "
10963 "combination");
10964 return 0;
10965 }
10966
10967 if (status == 37 &&
10968 wpa_command(intf, "SET tdls_testing 0x200")) {
10969 send_resp(dut, conn, SIGMA_ERROR,
10970 "ErrorCode,Failed to enable "
10971 "decline setup response test mode");
10972 return 0;
10973 }
10974
10975 if (timeout == 301) {
10976 int res;
10977 if (dut->no_tpk_expiration)
10978 res = wpa_command(intf,
10979 "SET tdls_testing 0x108");
10980 else
10981 res = wpa_command(intf,
10982 "SET tdls_testing 0x8");
10983 if (res) {
10984 send_resp(dut, conn, SIGMA_ERROR,
10985 "ErrorCode,Failed to set short TPK "
10986 "lifetime");
10987 return 0;
10988 }
10989 }
10990
10991 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", sta);
10992 if (wpa_command(intf, buf) < 0) {
10993 send_resp(dut, conn, SIGMA_ERROR,
10994 "ErrorCode,Failed to send TDLS setup");
10995 return 0;
10996 }
10997 return 1;
10998 }
10999
11000 if (strcasecmp(val, "TEARDOWN") == 0) {
11001 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", sta);
11002 if (wpa_command(intf, buf) < 0) {
11003 send_resp(dut, conn, SIGMA_ERROR,
11004 "ErrorCode,Failed to send TDLS teardown");
11005 return 0;
11006 }
11007 return 1;
11008 }
11009
11010 send_resp(dut, conn, SIGMA_ERROR,
11011 "ErrorCode,Unsupported TDLS frame");
11012 return 0;
11013}
11014
11015
11016static int sta_ap_known(const char *ifname, const char *bssid)
11017{
11018 char buf[4096];
11019
Jouni Malinendd32f192018-09-15 02:55:19 +030011020 snprintf(buf, sizeof(buf), "BSS MASK=1 %s", bssid);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011021 if (wpa_command_resp(ifname, buf, buf, sizeof(buf)) < 0)
11022 return 0;
11023 if (strncmp(buf, "id=", 3) != 0)
11024 return 0;
11025 return 1;
11026}
11027
11028
11029static int sta_scan_ap(struct sigma_dut *dut, const char *ifname,
11030 const char *bssid)
11031{
11032 int res;
11033 struct wpa_ctrl *ctrl;
11034 char buf[256];
11035
11036 if (sta_ap_known(ifname, bssid))
11037 return 0;
11038 sigma_dut_print(dut, DUT_MSG_DEBUG,
11039 "AP not in BSS table - start scan");
11040
11041 ctrl = open_wpa_mon(ifname);
11042 if (ctrl == NULL) {
11043 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
11044 "wpa_supplicant monitor connection");
11045 return -1;
11046 }
11047
11048 if (wpa_command(ifname, "SCAN") < 0) {
11049 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to start scan");
11050 wpa_ctrl_detach(ctrl);
11051 wpa_ctrl_close(ctrl);
11052 return -1;
11053 }
11054
11055 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
11056 buf, sizeof(buf));
11057
11058 wpa_ctrl_detach(ctrl);
11059 wpa_ctrl_close(ctrl);
11060
11061 if (res < 0) {
11062 sigma_dut_print(dut, DUT_MSG_INFO, "Scan did not complete");
11063 return -1;
11064 }
11065
11066 if (sta_ap_known(ifname, bssid))
11067 return 0;
11068 sigma_dut_print(dut, DUT_MSG_INFO, "AP not in BSS table");
11069 return -1;
11070}
11071
11072
11073static int cmd_sta_send_frame_hs2_neighadv(struct sigma_dut *dut,
11074 struct sigma_conn *conn,
11075 struct sigma_cmd *cmd,
11076 const char *intf)
11077{
11078 char buf[200];
11079
11080 snprintf(buf, sizeof(buf), "ndsend 2001:DB8::1 %s", intf);
11081 if (system(buf) != 0) {
11082 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Failed to run "
11083 "ndsend");
11084 return 0;
11085 }
11086
11087 return 1;
11088}
11089
11090
11091static int cmd_sta_send_frame_hs2_neighsolreq(struct sigma_dut *dut,
11092 struct sigma_conn *conn,
11093 struct sigma_cmd *cmd,
11094 const char *intf)
11095{
11096 char buf[200];
11097 const char *ip = get_param(cmd, "SenderIP");
11098
Peng Xu26b356d2017-10-04 17:58:16 -070011099 if (!ip)
11100 return 0;
11101
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011102 snprintf(buf, sizeof(buf), "ndisc6 -nm %s %s -r 4", ip, intf);
11103 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
11104 if (system(buf) == 0) {
11105 sigma_dut_print(dut, DUT_MSG_INFO,
11106 "Neighbor Solicitation got a response "
11107 "for %s@%s", ip, intf);
11108 }
11109
11110 return 1;
11111}
11112
11113
11114static int cmd_sta_send_frame_hs2_arpprobe(struct sigma_dut *dut,
11115 struct sigma_conn *conn,
11116 struct sigma_cmd *cmd,
11117 const char *ifname)
11118{
11119 char buf[200];
11120 const char *ip = get_param(cmd, "SenderIP");
11121
11122 if (ip == NULL) {
11123 send_resp(dut, conn, SIGMA_ERROR,
11124 "ErrorCode,Missing SenderIP parameter");
11125 return 0;
11126 }
11127 snprintf(buf, sizeof(buf), "arping -I %s -D %s -c 4", ifname, ip);
11128 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
11129 if (system(buf) != 0) {
11130 sigma_dut_print(dut, DUT_MSG_INFO, "arping DAD got a response "
11131 "for %s@%s", ip, ifname);
11132 }
11133
11134 return 1;
11135}
11136
11137
11138static int cmd_sta_send_frame_hs2_arpannounce(struct sigma_dut *dut,
11139 struct sigma_conn *conn,
11140 struct sigma_cmd *cmd,
11141 const char *ifname)
11142{
11143 char buf[200];
11144 char ip[16];
11145 int s;
Peng Xub3756882017-10-04 14:39:09 -070011146 struct ifreq ifr;
11147 struct sockaddr_in saddr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011148
11149 s = socket(PF_INET, SOCK_DGRAM, 0);
Peng Xub3756882017-10-04 14:39:09 -070011150 if (s < 0) {
11151 perror("socket");
11152 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011153 }
11154
Peng Xub3756882017-10-04 14:39:09 -070011155 memset(&ifr, 0, sizeof(ifr));
11156 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
11157 if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
11158 sigma_dut_print(dut, DUT_MSG_INFO,
11159 "Failed to get %s IP address: %s",
11160 ifname, strerror(errno));
11161 close(s);
11162 return -1;
11163 }
11164 close(s);
11165
11166 memcpy(&saddr, &ifr.ifr_addr, sizeof(struct sockaddr_in));
11167 strlcpy(ip, inet_ntoa(saddr.sin_addr), sizeof(ip));
11168
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011169 snprintf(buf, sizeof(buf), "arping -I %s -s %s %s -c 4", ifname, ip,
11170 ip);
11171 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
11172 if (system(buf) != 0) {
11173 }
11174
11175 return 1;
11176}
11177
11178
11179static int cmd_sta_send_frame_hs2_arpreply(struct sigma_dut *dut,
11180 struct sigma_conn *conn,
11181 struct sigma_cmd *cmd,
11182 const char *ifname)
11183{
11184 char buf[200], addr[20];
11185 char dst[ETH_ALEN], src[ETH_ALEN];
11186 short ethtype = htons(ETH_P_ARP);
11187 char *pos;
11188 int s, res;
11189 const char *val;
11190 struct sockaddr_in taddr;
11191
11192 val = get_param(cmd, "dest");
11193 if (val)
11194 hwaddr_aton(val, (unsigned char *) dst);
11195
11196 val = get_param(cmd, "DestIP");
11197 if (val)
11198 inet_aton(val, &taddr.sin_addr);
Peng Xu151c9e12017-10-04 14:39:09 -070011199 else
11200 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011201
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011202 if (get_wpa_status(get_station_ifname(dut), "address", addr,
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011203 sizeof(addr)) < 0)
11204 return -2;
11205 hwaddr_aton(addr, (unsigned char *) src);
11206
11207 pos = buf;
11208 *pos++ = 0x00;
11209 *pos++ = 0x01;
11210 *pos++ = 0x08;
11211 *pos++ = 0x00;
11212 *pos++ = 0x06;
11213 *pos++ = 0x04;
11214 *pos++ = 0x00;
11215 *pos++ = 0x02;
11216 memcpy(pos, src, ETH_ALEN);
11217 pos += ETH_ALEN;
11218 memcpy(pos, &taddr.sin_addr, 4);
11219 pos += 4;
11220 memcpy(pos, dst, ETH_ALEN);
11221 pos += ETH_ALEN;
11222 memcpy(pos, &taddr.sin_addr, 4);
11223 pos += 4;
11224
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011225 s = open_monitor(get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011226 if (s < 0) {
11227 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
11228 "monitor socket");
11229 return 0;
11230 }
11231
11232 res = inject_eth_frame(s, buf, pos - buf, ethtype, dst, src);
11233 if (res < 0) {
11234 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
11235 "inject frame");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +053011236 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011237 return 0;
11238 }
11239
11240 close(s);
11241
11242 return 1;
11243}
11244
11245
11246static int cmd_sta_send_frame_hs2_dls_req(struct sigma_dut *dut,
11247 struct sigma_conn *conn,
11248 struct sigma_cmd *cmd,
11249 const char *intf, const char *dest)
11250{
11251 char buf[100];
11252
11253 if (if_nametoindex("sigmadut") == 0) {
11254 snprintf(buf, sizeof(buf),
11255 "iw dev %s interface add sigmadut type monitor",
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011256 get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011257 if (system(buf) != 0 ||
11258 if_nametoindex("sigmadut") == 0) {
11259 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
11260 "monitor interface with '%s'", buf);
11261 return -2;
11262 }
11263 }
11264
11265 if (system("ifconfig sigmadut up") != 0) {
11266 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
11267 "monitor interface up");
11268 return -2;
11269 }
11270
Veerendranath Jakkam49774122020-07-05 09:52:18 +053011271 return sta_inject_frame(dut, conn, intf, DLS_REQ, UNPROTECTED, dest, 1);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011272}
11273
11274
11275static int cmd_sta_send_frame_hs2(struct sigma_dut *dut,
11276 struct sigma_conn *conn,
11277 struct sigma_cmd *cmd)
11278{
11279 const char *intf = get_param(cmd, "Interface");
11280 const char *dest = get_param(cmd, "Dest");
11281 const char *type = get_param(cmd, "FrameName");
11282 const char *val;
11283 char buf[200], *pos, *end;
11284 int count, count2;
11285
11286 if (type == NULL)
11287 type = get_param(cmd, "Type");
11288
11289 if (intf == NULL || dest == NULL || type == NULL)
11290 return -1;
11291
11292 if (strcasecmp(type, "NeighAdv") == 0)
11293 return cmd_sta_send_frame_hs2_neighadv(dut, conn, cmd, intf);
11294
11295 if (strcasecmp(type, "NeighSolicitReq") == 0)
11296 return cmd_sta_send_frame_hs2_neighsolreq(dut, conn, cmd, intf);
11297
11298 if (strcasecmp(type, "ARPProbe") == 0)
11299 return cmd_sta_send_frame_hs2_arpprobe(dut, conn, cmd, intf);
11300
11301 if (strcasecmp(type, "ARPAnnounce") == 0)
11302 return cmd_sta_send_frame_hs2_arpannounce(dut, conn, cmd, intf);
11303
11304 if (strcasecmp(type, "ARPReply") == 0)
11305 return cmd_sta_send_frame_hs2_arpreply(dut, conn, cmd, intf);
11306
11307 if (strcasecmp(type, "DLS-request") == 0 ||
11308 strcasecmp(type, "DLSrequest") == 0)
11309 return cmd_sta_send_frame_hs2_dls_req(dut, conn, cmd, intf,
11310 dest);
11311
11312 if (strcasecmp(type, "ANQPQuery") != 0 &&
11313 strcasecmp(type, "Query") != 0) {
11314 send_resp(dut, conn, SIGMA_ERROR,
11315 "ErrorCode,Unsupported HS 2.0 send frame type");
11316 return 0;
11317 }
11318
11319 if (sta_scan_ap(dut, intf, dest) < 0) {
11320 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not find "
11321 "the requested AP");
11322 return 0;
11323 }
11324
11325 pos = buf;
11326 end = buf + sizeof(buf);
11327 count = 0;
11328 pos += snprintf(pos, end - pos, "ANQP_GET %s ", dest);
11329
11330 val = get_param(cmd, "ANQP_CAP_LIST");
11331 if (val && atoi(val)) {
11332 pos += snprintf(pos, end - pos, "%s257", count > 0 ? "," : "");
11333 count++;
11334 }
11335
11336 val = get_param(cmd, "VENUE_NAME");
11337 if (val && atoi(val)) {
11338 pos += snprintf(pos, end - pos, "%s258", count > 0 ? "," : "");
11339 count++;
11340 }
11341
11342 val = get_param(cmd, "NETWORK_AUTH_TYPE");
11343 if (val && atoi(val)) {
11344 pos += snprintf(pos, end - pos, "%s260", count > 0 ? "," : "");
11345 count++;
11346 }
11347
11348 val = get_param(cmd, "ROAMING_CONS");
11349 if (val && atoi(val)) {
11350 pos += snprintf(pos, end - pos, "%s261", count > 0 ? "," : "");
11351 count++;
11352 }
11353
11354 val = get_param(cmd, "IP_ADDR_TYPE_AVAILABILITY");
11355 if (val && atoi(val)) {
11356 pos += snprintf(pos, end - pos, "%s262", count > 0 ? "," : "");
11357 count++;
11358 }
11359
11360 val = get_param(cmd, "NAI_REALM_LIST");
11361 if (val && atoi(val)) {
11362 pos += snprintf(pos, end - pos, "%s263", count > 0 ? "," : "");
11363 count++;
11364 }
11365
11366 val = get_param(cmd, "3GPP_INFO");
11367 if (val && atoi(val)) {
11368 pos += snprintf(pos, end - pos, "%s264", count > 0 ? "," : "");
11369 count++;
11370 }
11371
11372 val = get_param(cmd, "DOMAIN_LIST");
11373 if (val && atoi(val)) {
11374 pos += snprintf(pos, end - pos, "%s268", count > 0 ? "," : "");
11375 count++;
11376 }
11377
Jouni Malinen34cf9532018-04-29 19:26:33 +030011378 val = get_param(cmd, "Venue_URL");
11379 if (val && atoi(val)) {
11380 pos += snprintf(pos, end - pos, "%s277", count > 0 ? "," : "");
11381 count++;
11382 }
11383
Jouni Malinend3bca5d2018-04-29 17:25:23 +030011384 val = get_param(cmd, "Advice_Of_Charge");
11385 if (val && atoi(val)) {
11386 pos += snprintf(pos, end - pos, "%s278", count > 0 ? "," : "");
11387 count++;
11388 }
11389
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011390 if (count && wpa_command(intf, buf)) {
11391 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,ANQP_GET failed");
11392 return 0;
11393 }
11394
11395 pos = buf;
11396 end = buf + sizeof(buf);
11397 count2 = 0;
11398 pos += snprintf(pos, end - pos, "HS20_ANQP_GET %s ", dest);
11399
11400 val = get_param(cmd, "HS_CAP_LIST");
11401 if (val && atoi(val)) {
11402 pos += snprintf(pos, end - pos, "%s2", count2 > 0 ? "," : "");
11403 count2++;
11404 }
11405
11406 val = get_param(cmd, "OPER_NAME");
11407 if (val && atoi(val)) {
11408 pos += snprintf(pos, end - pos, "%s3", count2 > 0 ? "," : "");
11409 count2++;
11410 }
11411
11412 val = get_param(cmd, "WAN_METRICS");
11413 if (!val)
11414 val = get_param(cmd, "WAN_MAT");
11415 if (!val)
11416 val = get_param(cmd, "WAN_MET");
11417 if (val && atoi(val)) {
11418 pos += snprintf(pos, end - pos, "%s4", count2 > 0 ? "," : "");
11419 count2++;
11420 }
11421
11422 val = get_param(cmd, "CONNECTION_CAPABILITY");
11423 if (val && atoi(val)) {
11424 pos += snprintf(pos, end - pos, "%s5", count2 > 0 ? "," : "");
11425 count2++;
11426 }
11427
11428 val = get_param(cmd, "OP_CLASS");
11429 if (val && atoi(val)) {
11430 pos += snprintf(pos, end - pos, "%s7", count2 > 0 ? "," : "");
11431 count2++;
11432 }
11433
11434 val = get_param(cmd, "OSU_PROVIDER_LIST");
11435 if (val && atoi(val)) {
11436 pos += snprintf(pos, end - pos, "%s8", count2 > 0 ? "," : "");
11437 count2++;
11438 }
11439
Jouni Malinenf67afec2018-04-29 19:24:58 +030011440 val = get_param(cmd, "OPER_ICON_METADATA");
11441 if (!val)
11442 val = get_param(cmd, "OPERATOR_ICON_METADATA");
11443 if (val && atoi(val)) {
11444 pos += snprintf(pos, end - pos, "%s12", count2 > 0 ? "," : "");
11445 count2++;
11446 }
11447
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011448 if (count && count2) {
11449 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before sending out "
11450 "second query");
11451 sleep(1);
11452 }
11453
11454 if (count2 && wpa_command(intf, buf)) {
11455 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,HS20_ANQP_GET "
11456 "failed");
11457 return 0;
11458 }
11459
11460 val = get_param(cmd, "NAI_HOME_REALM_LIST");
11461 if (val) {
11462 if (count || count2) {
11463 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
11464 "sending out second query");
11465 sleep(1);
11466 }
11467
11468 if (strcmp(val, "1") == 0)
11469 val = "mail.example.com";
11470 snprintf(buf, end - pos,
11471 "HS20_GET_NAI_HOME_REALM_LIST %s realm=%s",
11472 dest, val);
11473 if (wpa_command(intf, buf)) {
11474 send_resp(dut, conn, SIGMA_ERROR,
11475 "ErrorCode,HS20_GET_NAI_HOME_REALM_LIST "
11476 "failed");
11477 return 0;
11478 }
11479 }
11480
11481 val = get_param(cmd, "ICON_REQUEST");
11482 if (val) {
11483 if (count || count2) {
11484 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
11485 "sending out second query");
11486 sleep(1);
11487 }
11488
11489 snprintf(buf, end - pos,
11490 "HS20_ICON_REQUEST %s %s", dest, val);
11491 if (wpa_command(intf, buf)) {
11492 send_resp(dut, conn, SIGMA_ERROR,
11493 "ErrorCode,HS20_ICON_REQUEST failed");
11494 return 0;
11495 }
11496 }
11497
11498 return 1;
11499}
11500
11501
11502static int ath_sta_send_frame_vht(struct sigma_dut *dut,
11503 struct sigma_conn *conn,
11504 struct sigma_cmd *cmd)
11505{
11506 const char *val;
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011507 const char *ifname;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011508 int chwidth, nss;
11509
11510 val = get_param(cmd, "framename");
11511 if (!val)
11512 return -1;
11513 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
11514
11515 /* Command sequence to generate Op mode notification */
11516 if (val && strcasecmp(val, "Op_md_notif_frm") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011517 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011518
11519 /* Disable STBC */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011520 run_iwpriv(dut, ifname, "tx_stbc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011521
11522 /* Extract Channel width */
11523 val = get_param(cmd, "Channel_width");
11524 if (val) {
11525 switch (atoi(val)) {
11526 case 20:
11527 chwidth = 0;
11528 break;
11529 case 40:
11530 chwidth = 1;
11531 break;
11532 case 80:
11533 chwidth = 2;
11534 break;
11535 case 160:
11536 chwidth = 3;
11537 break;
11538 default:
11539 chwidth = 2;
11540 break;
11541 }
11542
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011543 run_iwpriv(dut, ifname, "chwidth %d", chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011544 }
11545
11546 /* Extract NSS */
11547 val = get_param(cmd, "NSS");
11548 if (val) {
11549 switch (atoi(val)) {
11550 case 1:
11551 nss = 1;
11552 break;
11553 case 2:
11554 nss = 3;
11555 break;
11556 case 3:
11557 nss = 7;
11558 break;
11559 default:
11560 /* We do not support NSS > 3 */
11561 nss = 3;
11562 break;
11563 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011564 run_iwpriv(dut, ifname, "rxchainmask %d", nss);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011565 }
11566
11567 /* Opmode notify */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011568 run_iwpriv(dut, ifname, "opmode_notify 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011569 }
11570
11571 return 1;
11572}
11573
11574
Kiran Kumar Lokere00d74412020-07-23 13:26:51 -070011575static int wcn_sta_set_pmf_config(struct sigma_dut *dut, const char *intf,
11576 enum send_frame_protection protected)
11577{
11578#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +053011579 return wcn_wifi_test_config_set_u8(
11580 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_PMF_PROTECTION,
11581 protected);
Kiran Kumar Lokere00d74412020-07-23 13:26:51 -070011582#else /* NL80211_SUPPORT */
11583 sigma_dut_print(dut, DUT_MSG_ERROR,
11584 "PMF config cannot be set without NL80211_SUPPORT defined");
11585 return -1;
11586#endif /* NL80211_SUPPORT */
11587}
11588
11589
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011590static int cmd_sta_send_frame_vht(struct sigma_dut *dut,
11591 struct sigma_conn *conn,
11592 struct sigma_cmd *cmd)
11593{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011594 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011595 case DRIVER_ATHEROS:
11596 return ath_sta_send_frame_vht(dut, conn, cmd);
11597 default:
11598 send_resp(dut, conn, SIGMA_ERROR,
11599 "errorCode,Unsupported sta_set_frame(VHT) with the current driver");
11600 return 0;
11601 }
11602}
11603
11604
Kiran Kumar Lokerec2c3b412020-07-23 13:51:27 -070011605static int wcn_sta_send_disassoc(struct sigma_dut *dut, const char *intf)
11606{
11607#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +053011608 return wcn_wifi_test_config_set_flag(
11609 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_DISASSOC_TX);
Kiran Kumar Lokerec2c3b412020-07-23 13:51:27 -070011610#else /* NL80211_SUPPORT */
11611 sigma_dut_print(dut, DUT_MSG_ERROR,
11612 "Disassoc Tx cannot be done without NL80211_SUPPORT defined");
11613 return -1;
11614#endif /* NL80211_SUPPORT */
11615}
11616
11617
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070011618static int wcn_sta_send_frame_he(struct sigma_dut *dut, struct sigma_conn *conn,
11619 struct sigma_cmd *cmd)
11620{
11621 const char *val;
11622 const char *intf = get_param(cmd, "Interface");
Kiran Kumar Lokere00d74412020-07-23 13:26:51 -070011623 enum send_frame_protection protected;
11624 const char *pmf;
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070011625
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +030011626 if (!intf)
11627 return -1;
11628
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070011629 val = get_param(cmd, "framename");
11630 if (!val)
11631 return -1;
11632 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
11633
Kiran Kumar Lokere00d74412020-07-23 13:26:51 -070011634 pmf = get_param(cmd, "PMFProtected");
11635 if (!pmf)
11636 pmf = get_param(cmd, "Protected");
11637 if (pmf) {
11638 if (strcasecmp(pmf, "Correct-key") == 0 ||
11639 strcasecmp(pmf, "CorrectKey") == 0) {
11640 protected = CORRECT_KEY;
11641 } else if (strcasecmp(pmf, "IncorrectKey") == 0) {
11642 protected = INCORRECT_KEY;
11643 } else if (strcasecmp(pmf, "Unprotected") == 0) {
11644 protected = UNPROTECTED;
11645 } else {
11646 send_resp(dut, conn, SIGMA_ERROR,
11647 "errorCode,Unsupported PMFProtected");
11648 return STATUS_SENT_ERROR;
11649 }
11650 sigma_dut_print(dut, DUT_MSG_DEBUG, "Config PMF protection %d",
11651 protected);
11652 wcn_sta_set_pmf_config(dut, intf, protected);
11653 }
11654
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070011655 /* Command sequence to generate Op mode notification */
11656 if (val && strcasecmp(val, "action") == 0) {
11657 val = get_param(cmd, "PPDUTxType");
11658 if (val && strcasecmp(val, "TB") == 0) {
11659 if (sta_set_action_tx_in_he_tb_ppdu(dut, intf, 1)) {
11660 sigma_dut_print(dut, DUT_MSG_ERROR,
11661 "failed to send TB PPDU Tx cfg");
11662 send_resp(dut, conn, SIGMA_ERROR,
11663 "ErrorCode,set TB PPDU Tx cfg failed");
11664 return 0;
11665 }
11666 return 1;
11667 }
11668
11669 sigma_dut_print(dut, DUT_MSG_ERROR,
11670 "Action Tx type is not defined");
Kiran Kumar Lokerec2c3b412020-07-23 13:51:27 -070011671
11672 return SUCCESS_SEND_STATUS;
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070011673 }
11674
Kiran Kumar Lokerec2c3b412020-07-23 13:51:27 -070011675 if (strcasecmp(val, "disassoc") == 0)
11676 wcn_sta_send_disassoc(dut, intf);
11677
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070011678 return 1;
11679}
11680
11681
11682static int cmd_sta_send_frame_he(struct sigma_dut *dut,
11683 struct sigma_conn *conn,
11684 struct sigma_cmd *cmd)
11685{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011686 switch (get_driver_type(dut)) {
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070011687 case DRIVER_WCN:
11688 return wcn_sta_send_frame_he(dut, conn, cmd);
11689 default:
11690 send_resp(dut, conn, SIGMA_ERROR,
11691 "errorCode,Unsupported sta_set_frame(HE) with the current driver");
11692 return 0;
11693 }
11694}
11695
11696
Lior David0fe101e2017-03-09 16:09:50 +020011697#ifdef __linux__
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030011698
11699static int
11700wil6210_send_p2p_frame_60g(struct sigma_dut *dut, struct sigma_cmd *cmd,
11701 const char *frame_name, const char *dest_mac)
11702{
11703 int isprobereq = strcasecmp(frame_name, "probereq") == 0;
11704 const char *ssid = get_param(cmd, "ssid");
11705 const char *countstr = get_param(cmd, "count");
11706 const char *channelstr = get_param(cmd, "channel");
11707 const char *group_id = get_param(cmd, "groupid");
11708 const char *client_id = get_param(cmd, "clientmac");
11709 int count, channel, freq, i;
11710 const char *fname;
11711 char frame[1024], src_mac[20], group_id_attr[25],
11712 device_macstr[3 * ETH_ALEN], client_mac[ETH_ALEN];
11713 const char *group_ssid;
11714 const int group_ssid_prefix_len = 9;
11715 struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *) frame;
11716 size_t framelen = sizeof(frame);
11717 struct template_frame_tag tags[2];
11718 size_t tags_total = ARRAY_SIZE(tags);
11719 int tag_index, len, dst_len;
11720
11721 if (!countstr || !channelstr) {
11722 sigma_dut_print(dut, DUT_MSG_ERROR,
11723 "Missing argument: count, channel");
11724 return -1;
11725 }
11726 if (isprobereq && !ssid) {
11727 sigma_dut_print(dut, DUT_MSG_ERROR,
11728 "Missing argument: ssid");
11729 return -1;
11730 }
11731 if (!isprobereq && (!group_id || !client_id)) {
11732 sigma_dut_print(dut, DUT_MSG_ERROR,
11733 "Missing argument: group_id, client_id");
11734 return -1;
11735 }
11736
11737 count = atoi(countstr);
11738 channel = atoi(channelstr);
11739 freq = channel_to_freq(dut, channel);
11740
11741 if (!freq) {
11742 sigma_dut_print(dut, DUT_MSG_ERROR,
11743 "invalid channel: %s", channelstr);
11744 return -1;
11745 }
11746
11747 if (isprobereq) {
11748 if (strcasecmp(ssid, "wildcard") == 0) {
11749 fname = "probe_req_wildcard.txt";
11750 } else if (strcasecmp(ssid, "P2P_Wildcard") == 0) {
11751 fname = "probe_req_P2P_Wildcard.txt";
11752 } else {
11753 sigma_dut_print(dut, DUT_MSG_ERROR,
11754 "invalid probe request type");
11755 return -1;
11756 }
11757 } else {
11758 fname = "P2P_device_discovery_req.txt";
11759 }
11760
11761 if (parse_template_frame_file(dut, fname, frame, &framelen,
11762 tags, &tags_total)) {
11763 sigma_dut_print(dut, DUT_MSG_ERROR,
11764 "invalid frame template: %s", fname);
11765 return -1;
11766 }
11767
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011768 if (get_wpa_status(get_station_ifname(dut), "address",
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030011769 src_mac, sizeof(src_mac)) < 0 ||
11770 parse_mac_address(dut, src_mac, &hdr->addr2[0]) ||
11771 parse_mac_address(dut, dest_mac, &hdr->addr1[0]))
11772 return -1;
11773 /* Use wildcard BSSID, since we are in PBSS */
11774 memset(&hdr->addr3, 0xFF, ETH_ALEN);
11775
11776 if (!isprobereq) {
11777 tag_index = find_template_frame_tag(tags, tags_total, 1);
11778 if (tag_index < 0) {
11779 sigma_dut_print(dut, DUT_MSG_ERROR,
11780 "can't find device id attribute");
11781 return -1;
11782 }
11783 if (parse_mac_address(dut, client_id,
11784 (unsigned char *) client_mac)) {
11785 sigma_dut_print(dut, DUT_MSG_ERROR,
11786 "invalid client_id: %s", client_id);
11787 return -1;
11788 }
11789 if (replace_p2p_attribute(dut, &frame[tags[tag_index].offset],
11790 framelen - tags[tag_index].offset,
11791 IEEE80211_P2P_ATTR_DEVICE_ID,
11792 client_mac, ETH_ALEN)) {
11793 sigma_dut_print(dut, DUT_MSG_ERROR,
11794 "fail to replace device id attribute");
11795 return -1;
11796 }
11797
11798 /*
11799 * group_id arg contains device MAC address followed by
11800 * space and SSID (DIRECT-somessid).
11801 * group id attribute contains device address (6 bytes)
11802 * followed by SSID prefix DIRECT-XX (9 bytes)
11803 */
11804 if (strlen(group_id) < sizeof(device_macstr)) {
11805 sigma_dut_print(dut, DUT_MSG_ERROR,
11806 "group_id arg too short");
11807 return -1;
11808 }
11809 memcpy(device_macstr, group_id, sizeof(device_macstr));
11810 device_macstr[sizeof(device_macstr) - 1] = '\0';
11811 if (parse_mac_address(dut, device_macstr,
11812 (unsigned char *) group_id_attr)) {
11813 sigma_dut_print(dut, DUT_MSG_ERROR,
11814 "fail to parse device address from group_id");
11815 return -1;
11816 }
11817 group_ssid = strchr(group_id, ' ');
11818 if (!group_ssid) {
11819 sigma_dut_print(dut, DUT_MSG_ERROR,
11820 "invalid group_id arg, no ssid");
11821 return -1;
11822 }
11823 group_ssid++;
11824 len = strlen(group_ssid);
11825 if (len < group_ssid_prefix_len) {
11826 sigma_dut_print(dut, DUT_MSG_ERROR,
11827 "group_id SSID too short");
11828 return -1;
11829 }
11830 dst_len = sizeof(group_id_attr) - ETH_ALEN;
11831 if (len > dst_len) {
11832 sigma_dut_print(dut, DUT_MSG_ERROR,
11833 "group_id SSID (%s) too long",
11834 group_ssid);
11835 return -1;
11836 }
11837
11838 memcpy(group_id_attr + ETH_ALEN, group_ssid, len);
11839 tag_index = find_template_frame_tag(tags, tags_total, 2);
11840 if (tag_index < 0) {
11841 sigma_dut_print(dut, DUT_MSG_ERROR,
11842 "can't find group id attribute");
11843 return -1;
11844 }
11845 if (replace_p2p_attribute(dut, &frame[tags[tag_index].offset],
11846 framelen - tags[tag_index].offset,
11847 IEEE80211_P2P_ATTR_GROUP_ID,
11848 group_id_attr,
11849 sizeof(group_id_attr))) {
11850 sigma_dut_print(dut, DUT_MSG_ERROR,
11851 "fail to replace group id attribute");
11852 return -1;
11853 }
11854 }
11855
11856 for (i = 0; i < count; i++) {
11857 if (wil6210_transmit_frame(dut, freq,
11858 WIL_TRANSMIT_FRAME_DEFAULT_ROC,
11859 frame, framelen)) {
11860 sigma_dut_print(dut, DUT_MSG_ERROR,
11861 "fail to transmit probe request frame");
11862 return -1;
11863 }
11864 }
11865
11866 return 0;
11867}
11868
11869
Lior David0fe101e2017-03-09 16:09:50 +020011870int wil6210_send_frame_60g(struct sigma_dut *dut, struct sigma_conn *conn,
11871 struct sigma_cmd *cmd)
11872{
11873 const char *frame_name = get_param(cmd, "framename");
11874 const char *mac = get_param(cmd, "dest_mac");
11875
11876 if (!frame_name || !mac) {
11877 sigma_dut_print(dut, DUT_MSG_ERROR,
11878 "framename and dest_mac must be provided");
11879 return -1;
11880 }
11881
11882 if (strcasecmp(frame_name, "brp") == 0) {
11883 const char *l_rx = get_param(cmd, "L-RX");
11884 int l_rx_i;
11885
11886 if (!l_rx) {
11887 sigma_dut_print(dut, DUT_MSG_ERROR,
11888 "L-RX must be provided");
11889 return -1;
11890 }
11891 l_rx_i = atoi(l_rx);
11892
11893 sigma_dut_print(dut, DUT_MSG_INFO,
11894 "dev_send_frame: BRP-RX, dest_mac %s, L-RX %s",
11895 mac, l_rx);
11896 if (l_rx_i != 16) {
11897 sigma_dut_print(dut, DUT_MSG_ERROR,
11898 "unsupported L-RX: %s", l_rx);
11899 return -1;
11900 }
11901
11902 if (wil6210_send_brp_rx(dut, mac, l_rx_i))
11903 return -1;
11904 } else if (strcasecmp(frame_name, "ssw") == 0) {
11905 sigma_dut_print(dut, DUT_MSG_INFO,
11906 "dev_send_frame: SLS, dest_mac %s", mac);
11907 if (wil6210_send_sls(dut, mac))
11908 return -1;
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030011909 } else if ((strcasecmp(frame_name, "probereq") == 0) ||
11910 (strcasecmp(frame_name, "devdiscreq") == 0)) {
11911 sigma_dut_print(dut, DUT_MSG_INFO,
11912 "dev_send_frame: %s, dest_mac %s", frame_name,
11913 mac);
11914 if (wil6210_send_p2p_frame_60g(dut, cmd, frame_name, mac))
11915 return -1;
Lior David0fe101e2017-03-09 16:09:50 +020011916 } else {
11917 sigma_dut_print(dut, DUT_MSG_ERROR,
11918 "unsupported frame type: %s", frame_name);
11919 return -1;
11920 }
11921
11922 return 1;
11923}
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030011924
Lior David0fe101e2017-03-09 16:09:50 +020011925#endif /* __linux__ */
11926
11927
11928static int cmd_sta_send_frame_60g(struct sigma_dut *dut,
11929 struct sigma_conn *conn,
11930 struct sigma_cmd *cmd)
11931{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011932 switch (get_driver_type(dut)) {
Lior David0fe101e2017-03-09 16:09:50 +020011933#ifdef __linux__
11934 case DRIVER_WIL6210:
11935 return wil6210_send_frame_60g(dut, conn, cmd);
11936#endif /* __linux__ */
11937 default:
11938 send_resp(dut, conn, SIGMA_ERROR,
11939 "errorCode,Unsupported sta_set_frame(60G) with the current driver");
11940 return 0;
11941 }
11942}
11943
11944
Ashwini Patildb59b3c2017-04-13 15:19:23 +053011945static int mbo_send_anqp_query(struct sigma_dut *dut, struct sigma_conn *conn,
11946 const char *intf, struct sigma_cmd *cmd)
11947{
11948 const char *val, *addr;
11949 char buf[100];
11950
11951 addr = get_param(cmd, "DestMac");
11952 if (!addr) {
11953 send_resp(dut, conn, SIGMA_INVALID,
11954 "ErrorCode,AP MAC address is missing");
11955 return 0;
11956 }
11957
11958 val = get_param(cmd, "ANQPQuery_ID");
11959 if (!val) {
11960 send_resp(dut, conn, SIGMA_INVALID,
11961 "ErrorCode,Missing ANQPQuery_ID");
11962 return 0;
11963 }
11964
11965 if (strcasecmp(val, "NeighborReportReq") == 0) {
11966 snprintf(buf, sizeof(buf), "ANQP_GET %s 272", addr);
11967 } else if (strcasecmp(val, "QueryListWithCellPref") == 0) {
11968 snprintf(buf, sizeof(buf), "ANQP_GET %s 272,mbo:2", addr);
11969 } else {
11970 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid ANQPQuery_ID: %s",
11971 val);
11972 send_resp(dut, conn, SIGMA_INVALID,
11973 "ErrorCode,Invalid ANQPQuery_ID");
11974 return 0;
11975 }
11976
Ashwini Patild174f2c2017-04-13 16:49:46 +053011977 /* Set gas_address3 field to IEEE 802.11-2012 standard compliant form
11978 * (Address3 = Wildcard BSSID when sent to not-associated AP;
11979 * if associated, AP BSSID).
11980 */
11981 if (wpa_command(intf, "SET gas_address3 1") < 0) {
11982 send_resp(dut, conn, SIGMA_ERROR,
11983 "ErrorCode,Failed to set gas_address3");
11984 return 0;
11985 }
11986
Ashwini Patildb59b3c2017-04-13 15:19:23 +053011987 if (wpa_command(intf, buf) < 0) {
11988 send_resp(dut, conn, SIGMA_ERROR,
11989 "ErrorCode,Failed to send ANQP query");
11990 return 0;
11991 }
11992
11993 return 1;
11994}
11995
11996
11997static int mbo_cmd_sta_send_frame(struct sigma_dut *dut,
11998 struct sigma_conn *conn,
11999 const char *intf,
12000 struct sigma_cmd *cmd)
12001{
12002 const char *val = get_param(cmd, "FrameName");
12003
12004 if (val && strcasecmp(val, "ANQPQuery") == 0)
12005 return mbo_send_anqp_query(dut, conn, intf, cmd);
12006
12007 return 2;
12008}
12009
12010
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +053012011static enum sigma_cmd_result cmd_sta_send_frame_wpa3(struct sigma_dut *dut,
12012 struct sigma_conn *conn,
12013 const char *intf,
12014 struct sigma_cmd *cmd)
12015{
12016 const char *val = get_param(cmd, "framename");
12017
12018 if (!val)
12019 return INVALID_SEND_STATUS;
12020
12021 if (strcasecmp(val, "SAQueryReq") == 0) {
12022 val = get_param(cmd, "OCIChannel");
12023
12024 if (!val) {
12025 send_resp(dut, conn, SIGMA_ERROR,
12026 "errorCode,OCIChannel not present");
12027 return STATUS_SENT_ERROR;
12028 }
12029
12030 dut->saquery_oci_freq = channel_to_freq(dut, atoi(val));
12031 if (!dut->saquery_oci_freq) {
12032 send_resp(dut, conn, SIGMA_ERROR,
12033 "errorCode,Invalid OCIChannel number");
12034 return STATUS_SENT_ERROR;
12035 }
12036
12037 return sta_inject_frame(dut, conn, intf, SAQUERY, CORRECT_KEY,
12038 NULL, 0);
12039 }
12040
12041 if (strcasecmp(val, "reassocreq") == 0)
12042 return sta_inject_frame(dut, conn, intf, REASSOCREQ,
12043 CORRECT_KEY, NULL, 0);
12044
Veerendranath9f81dfb2020-08-10 01:21:29 -070012045 if (strcasecmp(val, "ANQPQuery") == 0) {
12046 char buf[50];
12047 const char *dest = get_param(cmd, "DestMac");
12048 const char *chan = get_param(cmd, "channel");
Veerendranath Jakkam78862fc2020-11-19 21:23:27 +053012049 const char *freq_str = get_param(cmd, "ChnlFreq");
Veerendranath9f81dfb2020-08-10 01:21:29 -070012050 int len, freq;
12051
Veerendranath Jakkam78862fc2020-11-19 21:23:27 +053012052 if (freq_str)
12053 freq = atoi(freq_str);
12054 else
12055 freq = chan ? channel_to_freq(dut, atoi(chan)) : 0;
12056
Veerendranath9f81dfb2020-08-10 01:21:29 -070012057 if (!dest || !freq)
12058 return INVALID_SEND_STATUS;
12059
12060 len = snprintf(buf, sizeof(buf), "ANQP_GET %s freq=%d 257",
12061 dest, freq);
12062 if (len < 0 || len >= sizeof(buf)) {
12063 sigma_dut_print(dut, DUT_MSG_ERROR,
12064 "Failed to allocate buf");
12065 return ERROR_SEND_STATUS;
12066 }
12067
12068 if (wpa_command(intf, buf) != 0) {
12069 send_resp(dut, conn, SIGMA_ERROR,
12070 "ErrorCode,Failed to send ANQP Query frame");
12071 return STATUS_SENT_ERROR;
12072 }
12073
12074 sigma_dut_print(dut, DUT_MSG_DEBUG,
12075 "ANQP Query sent: %s", buf);
12076
12077 return SUCCESS_SEND_STATUS;
12078 }
12079
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +053012080 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported framename");
12081 return STATUS_SENT_ERROR;
12082}
12083
12084
Vinita S. Malooca85fd22021-01-15 02:54:34 +053012085static int
12086get_type4_frame_classifier(struct sigma_dut *dut, struct sigma_cmd *cmd,
12087 char *pos, int rem_len, int num_of_scs_desc,
12088 int num_of_tclas_elem)
12089{
12090 const char *val;
12091 int ipv6;
12092 int len, total_len = 0;
12093
12094 val = get_param_fmt(cmd, "TCLASElem_Version_%d_%d", num_of_scs_desc,
12095 num_of_tclas_elem);
12096 if (!val) {
12097 sigma_dut_print(dut, DUT_MSG_ERROR, "%s: ip_version empty",
12098 __func__);
12099 return -1;
12100 }
12101
12102 if (strcmp(val, "6") == 0) {
12103 ipv6 = 1;
12104 } else if (strcmp(val, "4") == 0) {
12105 ipv6 = 0;
12106 } else {
12107 sigma_dut_print(dut, DUT_MSG_ERROR, "%s: ip_version invalid",
12108 __func__);
12109 return -1;
12110 }
12111
12112 len = snprintf(pos, rem_len, " ip_version=%s", ipv6 ? "ipv6" : "ipv4");
12113 if (len < 0 || len >= rem_len)
12114 return -1;
12115
12116 pos += len;
12117 rem_len -= len;
12118 total_len += len;
12119
12120 val = get_param_fmt(cmd, "TCLASElem_SourceIPAddr_%d_%d",
12121 num_of_scs_desc, num_of_tclas_elem);
12122 if (val) {
12123 len = snprintf(pos, rem_len, " src_ip=%s", val);
12124 if (len < 0 || len >= rem_len)
12125 return -1;
12126
12127 pos += len;
12128 rem_len -= len;
12129 total_len += len;
12130 }
12131
12132 val = get_param_fmt(cmd, "TCLASElem_DestinationIPAddr_%d_%d",
12133 num_of_scs_desc, num_of_tclas_elem);
12134 if (val) {
12135 len = snprintf(pos, rem_len, " dst_ip=%s", val);
12136 if (len < 0 || len >= rem_len)
12137 return -1;
12138
12139 pos += len;
12140 rem_len -= len;
12141 total_len += len;
12142 }
12143
12144 val = get_param_fmt(cmd, "TCLASElem_SourcePort_%d_%d", num_of_scs_desc,
12145 num_of_tclas_elem);
12146 if (val) {
12147 len = snprintf(pos, rem_len, " src_port=%s", val);
12148 if (len < 0 || len >= rem_len)
12149 return -1;
12150
12151 pos += len;
12152 rem_len -= len;
12153 total_len += len;
12154 }
12155
12156 val = get_param_fmt(cmd, "TCLASElem_DestinationPort_%d_%d",
12157 num_of_scs_desc, num_of_tclas_elem);
12158 if (val) {
12159 len = snprintf(pos, rem_len, " dst_port=%s", val);
12160 if (len < 0 || len >= rem_len)
12161 return -1;
12162
12163 pos += len;
12164 rem_len -= len;
12165 total_len += len;
12166 }
12167
12168 val = get_param_fmt(cmd, "TCLASElem_DSCP_%d_%d", num_of_scs_desc,
12169 num_of_tclas_elem);
12170 if (val) {
12171 len = snprintf(pos, rem_len, " dscp=%s", val);
12172 if (len < 0 || len >= rem_len)
12173 return -1;
12174
12175 pos += len;
12176 rem_len -= len;
12177 total_len += len;
12178 }
12179
12180 val = get_param_fmt(cmd, "TCLASElem_ProtocolNxtHeader_%d_%d",
12181 num_of_scs_desc, num_of_tclas_elem);
12182 if (val) {
12183 char *prot;
12184
12185 switch (atoi(val)) {
12186 case 17:
12187 prot = "udp";
12188 break;
12189 case 6:
12190 prot = "tcp";
12191 break;
12192 case 50:
12193 prot = "esp";
12194 break;
12195 default:
12196 sigma_dut_print(dut, DUT_MSG_ERROR,
12197 "Invalid protocol %d", atoi(val));
12198 return -1;
12199 }
12200
12201 if (ipv6)
12202 len = snprintf(pos, rem_len, " next_header=%s", prot);
12203 else
12204 len = snprintf(pos, rem_len, " protocol=%s", prot);
12205 if (len < 0 || len >= rem_len)
12206 return -1;
12207
12208 pos += len;
12209 rem_len -= len;
12210 total_len += len;
12211 }
12212
12213 return total_len;
12214}
12215
12216
12217static int
12218get_type10_frame_classifier(struct sigma_dut *dut, struct sigma_cmd *cmd,
12219 char *pos, int rem_len, int num_of_scs_desc,
12220 int num_of_tclas_elem)
12221{
12222 const char *val;
12223 int len, total_len = 0;
12224
12225 val = get_param_fmt(cmd, "TCLASElem_ProtoInstance_%d_%d",
12226 num_of_scs_desc, num_of_tclas_elem);
12227 if (val) {
12228 len = snprintf(pos, rem_len, " prot_instance=%s",
12229 val);
12230 if (len < 0 || len >= rem_len)
12231 return -1;
12232
12233 pos += len;
12234 rem_len -= len;
12235 total_len += len;
12236 }
12237
12238 val = get_param_fmt(cmd, "TCLASElem_ProtoNumNextHeader_%d_%d",
12239 num_of_scs_desc, num_of_tclas_elem);
12240 if (val) {
12241 char *prot;
12242
12243 switch (atoi(val)) {
12244 case 17:
12245 prot = "udp";
12246 break;
12247 case 6:
12248 prot = "tcp";
12249 break;
12250 case 50:
12251 prot = "esp";
12252 break;
12253 default:
12254 sigma_dut_print(dut, DUT_MSG_ERROR,
12255 "Invalid protocol %d",
12256 atoi(val));
12257 return -1;
12258 }
12259
12260 len = snprintf(pos, rem_len, " prot_number=%s", prot);
12261 if (len < 0 || len >= rem_len)
12262 return -1;
12263
12264 pos += len;
12265 rem_len -= len;
12266 total_len += len;
12267 }
12268
12269 val = get_param_fmt(cmd, "TCLASElem_FilterValue_%d_%d",
12270 num_of_scs_desc, num_of_tclas_elem);
12271 if (val) {
12272 len = snprintf(pos, rem_len, " filter_value=%s", (val + 2));
12273 if (len < 0 || len >= rem_len)
12274 return -1;
12275
12276 pos += len;
12277 rem_len -= len;
12278 total_len += len;
12279 }
12280
12281 val = get_param_fmt(cmd, "TCLASElem_FilterMask_%d_%d", num_of_scs_desc,
12282 num_of_tclas_elem);
12283 if (val && strlen(val) >= 2) {
12284 len = snprintf(pos, rem_len, " filter_mask=%s", val + 2);
12285 if (len < 0 || len >= rem_len)
12286 return -1;
12287
12288 pos += len;
12289 rem_len -= len;
12290 total_len += len;
12291 }
12292
12293 return total_len;
12294}
12295
12296
12297static enum sigma_cmd_result
12298cmd_sta_send_frame_scs(struct sigma_dut *dut, struct sigma_conn *conn,
12299 const char *intf, struct sigma_cmd *cmd)
12300{
12301 char buf[4096], *pos;
12302 const char *val, *scs_id, *classifier_type;
12303 int len, rem_len, total_bytes;
12304 int num_of_scs_desc = 0, num_of_tclas_elem = 0;
12305
12306 scs_id = get_param(cmd, "SCSDescrElem_SCSID_1");
12307 if (!scs_id) {
12308 sigma_dut_print(dut, DUT_MSG_ERROR, "SCS ID empty");
12309 return INVALID_SEND_STATUS;
12310 }
12311
12312 rem_len = sizeof(buf);
12313 pos = buf;
12314
12315 len = snprintf(buf, sizeof(buf), "SCS");
12316 if (len < 0 || len > rem_len)
12317 goto fail;
12318
12319 pos += len;
12320 rem_len -= len;
12321
12322 while (scs_id) {
12323 num_of_scs_desc++;
12324
12325 val = get_param_fmt(cmd, "SCSDescrElem_RequestType_%d",
12326 num_of_scs_desc);
12327 if (!val)
12328 return INVALID_SEND_STATUS;
12329
12330 if (strcasecmp(val, "Add") == 0) {
12331 len = snprintf(pos, rem_len, " scs_id=%s add",
12332 scs_id);
12333 } else if (strcasecmp(val, "Change") == 0) {
12334 len = snprintf(pos, rem_len, " scs_id=%s change",
12335 scs_id);
12336 } else if (strcasecmp(val, "Remove") == 0) {
12337 len = snprintf(pos, rem_len, " scs_id=%s remove",
12338 scs_id);
12339 if (len < 0 || len >= rem_len)
12340 goto fail;
12341
12342 pos += len;
12343 rem_len -= len;
12344 goto scs_desc_end;
12345 } else {
12346 sigma_dut_print(dut, DUT_MSG_ERROR,
12347 "%s: request type - %s is invalid",
12348 __func__, val);
12349 return INVALID_SEND_STATUS;
12350 }
12351
12352 if (len < 0 || len >= rem_len)
12353 goto fail;
12354
12355 pos += len;
12356 rem_len -= len;
12357
12358 val = get_param_fmt(cmd, "IntraAccessCatElem_UP_%d",
12359 num_of_scs_desc);
12360 if (!val) {
12361 sigma_dut_print(dut, DUT_MSG_ERROR,
12362 "IntraAccess Priority empty");
12363 return INVALID_SEND_STATUS;
12364 }
12365
12366 len = snprintf(pos, rem_len, " scs_up=%s", val);
12367 if (len < 0 || len >= rem_len)
12368 goto fail;
12369
12370 pos += len;
12371 rem_len -= len;
12372
12373 classifier_type = get_param_fmt(cmd,
12374 "TCLASElem_ClassifierType_%d_1",
12375 num_of_scs_desc);
12376 if (!classifier_type) {
12377 sigma_dut_print(dut, DUT_MSG_ERROR,
12378 "classifier type missing");
12379 return INVALID_SEND_STATUS;
12380 }
12381
12382 while (classifier_type) {
12383 num_of_tclas_elem++;
12384
12385 len = snprintf(pos, rem_len, " classifier_type=%s",
12386 classifier_type);
12387 if (len < 0 || len >= rem_len)
12388 goto fail;
12389
12390 pos += len;
12391 rem_len -= len;
12392
12393 if (strcmp(classifier_type, "10") == 0) {
12394 total_bytes = get_type10_frame_classifier(
12395 dut, cmd, pos, rem_len,
12396 num_of_scs_desc,
12397 num_of_tclas_elem);
12398 } else if (strcmp(classifier_type, "4") == 0) {
12399 total_bytes = get_type4_frame_classifier(
12400 dut, cmd, pos, rem_len,
12401 num_of_scs_desc,
12402 num_of_tclas_elem);
12403 } else {
12404 sigma_dut_print(dut, DUT_MSG_ERROR,
12405 "classifier_type invalid");
12406 goto fail;
12407 }
12408
12409 if (total_bytes < 0)
12410 goto fail;
12411
12412 pos += total_bytes;
12413 rem_len -= total_bytes;
12414
12415 classifier_type = get_param_fmt(
12416 cmd, "TCLASElem_ClassifierType_%d_%d",
12417 num_of_scs_desc, num_of_tclas_elem + 1);
12418 }
12419
12420 if (num_of_tclas_elem > 1) {
12421 val = get_param_fmt(cmd,
12422 "TCLASProcessingElem_Processing_%d",
12423 num_of_scs_desc);
12424 if (!val) {
12425 sigma_dut_print(dut, DUT_MSG_ERROR,
12426 "Tclas_processing element %d empty",
12427 num_of_scs_desc);
12428 goto fail;
12429 }
12430
12431 len = snprintf(pos, rem_len,
12432 " tclas_processing=%s", val);
12433 if (len < 0 || len >= rem_len)
12434 goto fail;
12435
12436 pos += len;
12437 rem_len -= len;
12438 }
12439scs_desc_end:
12440 num_of_tclas_elem = 0;
12441 scs_id = get_param_fmt(cmd, "SCSDescrElem_SCSID_%d",
12442 num_of_scs_desc + 1);
12443 }
12444
12445 if (wpa_command(intf, buf) != 0) {
12446 send_resp(dut, conn, SIGMA_ERROR,
12447 "ErrorCode,Failed to send SCS frame request");
12448 return STATUS_SENT_ERROR;
12449 }
12450
12451 sigma_dut_print(dut, DUT_MSG_DEBUG,
12452 "SCS frame request sent: %s", buf);
12453
12454 return SUCCESS_SEND_STATUS;
12455fail:
12456 sigma_dut_print(dut, DUT_MSG_ERROR,
12457 "Failed to create SCS frame request");
12458 return ERROR_SEND_STATUS;
12459}
12460
12461
Vinita S. Malooee9e7e92020-04-28 16:26:50 +053012462static enum sigma_cmd_result
12463cmd_sta_send_frame_mscs(struct sigma_dut *dut, struct sigma_conn *conn,
12464 const char *intf, struct sigma_cmd *cmd)
12465{
12466 char buf[128], *pos;
12467 const char *val, *classifier_type = "04", *type;
12468 int len, rem_len;
12469 u8 up_bitmap;
12470
Vinita S. Malooee9e7e92020-04-28 16:26:50 +053012471 type = get_param(cmd, "Request_Type");
Vinita S. Malooca85fd22021-01-15 02:54:34 +053012472 if (!type) {
Vinita S. Malooee9e7e92020-04-28 16:26:50 +053012473 sigma_dut_print(dut, DUT_MSG_ERROR,
Vinita S. Malooca85fd22021-01-15 02:54:34 +053012474 "%s: type not valid", __func__);
Vinita S. Malooee9e7e92020-04-28 16:26:50 +053012475 return INVALID_SEND_STATUS;
12476 }
12477
12478 rem_len = sizeof(buf);
12479 pos = buf;
12480 if (strcasecmp(type, "add") == 0) {
12481 len = snprintf(pos, rem_len, "MSCS add");
12482 } else if (strcasecmp(type, "update") == 0) {
12483 len = snprintf(pos, rem_len, "MSCS change");
12484 } else if (strcasecmp(type, "remove") == 0) {
12485 if (wpa_command(intf, "MSCS remove") != 0) {
12486 send_resp(dut, conn, SIGMA_ERROR,
12487 "ErrorCode,Failed to send MSCS frame req");
12488 return STATUS_SENT_ERROR;
12489 }
12490 return SUCCESS_SEND_STATUS;
12491 } else {
12492 sigma_dut_print(dut, DUT_MSG_ERROR,
12493 "%s: request type invalid", __func__);
12494 return INVALID_SEND_STATUS;
12495 }
12496
12497 if (len < 0 || len >= rem_len)
12498 goto fail;
12499
12500 pos += len;
12501 rem_len -= len;
12502
12503 val = get_param(cmd, "User_Priority_Bitmap");
12504 if (!val) {
12505 sigma_dut_print(dut, DUT_MSG_ERROR,
12506 "%s: user priority bitmap empty", __func__);
12507 return INVALID_SEND_STATUS;
12508 }
12509
12510 switch (atoi(val)) {
12511 case 0:
12512 up_bitmap = 0x00;
12513 break;
12514 case 1:
12515 up_bitmap = 0xF0;
12516 break;
12517 case 2:
12518 up_bitmap = 0xF6;
12519 break;
12520 default:
12521 sigma_dut_print(dut, DUT_MSG_ERROR,
12522 "%s: Unknown User_Priority_Bitmap value %d",
12523 __func__, atoi(val));
12524 return INVALID_SEND_STATUS;
12525 }
12526
12527 len = snprintf(pos, rem_len, " up_bitmap=%02x", up_bitmap);
12528 if (len < 0 || len >= rem_len)
12529 goto fail;
12530
12531 pos += len;
12532 rem_len -= len;
12533
12534 val = get_param(cmd, "User_Priority_Limit");
12535 if (!val) {
12536 sigma_dut_print(dut, DUT_MSG_ERROR,
12537 "%s: invalid user priority limit", __func__);
12538 return INVALID_SEND_STATUS;
12539 }
12540
12541 len = snprintf(pos, rem_len, " up_limit=%s", val);
12542 if (len < 0 || len >= rem_len)
12543 goto fail;
12544
12545 pos += len;
12546 rem_len -= len;
12547
12548 val = get_param(cmd, "Stream_Timeout");
12549 if (!val)
12550 val = get_param(cmd, "Stream_Timtout");
12551 if (!val) {
12552 sigma_dut_print(dut, DUT_MSG_ERROR,
12553 "%s: invalid stream timeout", __func__);
12554 return INVALID_SEND_STATUS;
12555 }
12556
12557 len = snprintf(pos, rem_len, " stream_timeout=%s", val);
12558 if (len < 0 || len >= rem_len)
12559 goto fail;
12560
12561 pos += len;
12562 rem_len -= len;
12563
12564 val = get_param(cmd, "TCLAS_Mask");
12565 if (!val) {
12566 sigma_dut_print(dut, DUT_MSG_ERROR,
12567 "%s: invalid tclas mask", __func__);
12568 return INVALID_SEND_STATUS;
12569 }
12570
12571 len = snprintf(pos, rem_len, " frame_classifier=%s%lx%032x",
12572 classifier_type, strtol(val, NULL, 2), 0);
12573 if (len < 0 || len >= rem_len)
12574 goto fail;
12575
12576 if (wpa_command(intf, buf) != 0) {
12577 send_resp(dut, conn, SIGMA_ERROR,
12578 "ErrorCode,Failed to send MSCS frame req");
12579 return STATUS_SENT_ERROR;
12580 }
12581
12582 sigma_dut_print(dut, DUT_MSG_DEBUG,
12583 "MSCS frame request sent: %s", buf);
12584
12585 return SUCCESS_SEND_STATUS;
12586fail:
12587 sigma_dut_print(dut, DUT_MSG_ERROR,
12588 "Failed to create MSCS frame req");
12589 return ERROR_SEND_STATUS;
12590}
12591
12592
Vinita S. Malooca85fd22021-01-15 02:54:34 +053012593static enum sigma_cmd_result
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053012594cmd_sta_send_frame_dscp_query(struct sigma_dut *dut, struct sigma_conn *conn,
12595 const char *intf, struct sigma_cmd *cmd)
12596{
12597 char buf[150], *pos;
12598 const char *val;
12599 int len, rem_len;
12600
12601 rem_len = sizeof(buf);
12602 pos = buf;
12603
12604 len = snprintf(pos, rem_len, "DSCP_QUERY");
12605 if (len < 0 || len >= rem_len)
12606 goto fail;
12607
12608 pos += len;
12609 rem_len -= len;
12610
12611 val = get_param(cmd, "Wildcard");
12612 if (val && strcasecmp(val, "Yes") == 0) {
12613 len = snprintf(pos, rem_len, " wildcard");
12614 if (len < 0 || len >= rem_len)
12615 goto fail;
12616 } else if (strlen(dut->qm_domain_name)) {
12617 len = snprintf(pos, rem_len, " domain_name=%s",
12618 dut->qm_domain_name);
12619 if (len < 0 || len >= rem_len)
12620 goto fail;
12621 } else {
12622 sigma_dut_print(dut, DUT_MSG_ERROR,
12623 "Invalid DSCP Query configuration");
12624 return INVALID_SEND_STATUS;
12625 }
12626
12627 if (wpa_command(intf, buf) != 0) {
12628 send_resp(dut, conn, SIGMA_ERROR,
12629 "ErrorCode,Failed to send DSCP policy query frame");
12630 return STATUS_SENT_ERROR;
12631 }
12632
12633 sigma_dut_print(dut, DUT_MSG_DEBUG,
12634 "DSCP policy query frame sent: %s", buf);
12635 return SUCCESS_SEND_STATUS;
12636fail:
12637 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to send DSCP query");
12638 return ERROR_SEND_STATUS;
12639}
12640
12641
12642static enum sigma_cmd_result
Vinita S. Malooca85fd22021-01-15 02:54:34 +053012643cmd_sta_send_frame_qm(struct sigma_dut *dut, struct sigma_conn *conn,
12644 const char *intf, struct sigma_cmd *cmd)
12645{
12646 const char *val;
12647
12648 val = get_param(cmd, "FrameName");
12649 if (val) {
12650 if (strcasecmp(val, "MSCSReq") == 0)
12651 return cmd_sta_send_frame_mscs(dut, conn, intf, cmd);
12652 if (strcasecmp(val, "SCSReq") == 0)
12653 return cmd_sta_send_frame_scs(dut, conn, intf, cmd);
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053012654 if (strcasecmp(val, "DSCPPolicyQuery") == 0)
12655 return cmd_sta_send_frame_dscp_query(dut, conn, intf,
12656 cmd);
Vinita S. Malooca85fd22021-01-15 02:54:34 +053012657
12658 sigma_dut_print(dut, DUT_MSG_ERROR,
12659 "%s: frame name - %s is invalid",
12660 __func__, val);
12661 }
12662
12663 return INVALID_SEND_STATUS;
12664}
12665
12666
Jouni Malinenf7222712019-06-13 01:50:21 +030012667enum sigma_cmd_result cmd_sta_send_frame(struct sigma_dut *dut,
12668 struct sigma_conn *conn,
12669 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012670{
12671 const char *intf = get_param(cmd, "Interface");
12672 const char *val;
12673 enum send_frame_type frame;
12674 enum send_frame_protection protected;
12675 char buf[100];
12676 unsigned char addr[ETH_ALEN];
12677 int res;
12678
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +030012679 if (!intf)
12680 return -1;
12681
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012682 val = get_param(cmd, "program");
12683 if (val == NULL)
12684 val = get_param(cmd, "frame");
12685 if (val && strcasecmp(val, "TDLS") == 0)
12686 return cmd_sta_send_frame_tdls(dut, conn, cmd);
12687 if (val && (strcasecmp(val, "HS2") == 0 ||
Jouni Malinen1f6ae642018-06-07 23:56:13 +030012688 strcasecmp(val, "HS2-R2") == 0 ||
12689 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012690 return cmd_sta_send_frame_hs2(dut, conn, cmd);
12691 if (val && strcasecmp(val, "VHT") == 0)
12692 return cmd_sta_send_frame_vht(dut, conn, cmd);
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012693 if (val && strcasecmp(val, "HE") == 0)
12694 return cmd_sta_send_frame_he(dut, conn, cmd);
priyadharshini gowthamand66913a2016-07-29 15:11:17 -070012695 if (val && strcasecmp(val, "LOC") == 0)
12696 return loc_cmd_sta_send_frame(dut, conn, cmd);
Lior David0fe101e2017-03-09 16:09:50 +020012697 if (val && strcasecmp(val, "60GHz") == 0)
12698 return cmd_sta_send_frame_60g(dut, conn, cmd);
Ashwini Patildb59b3c2017-04-13 15:19:23 +053012699 if (val && strcasecmp(val, "MBO") == 0) {
12700 res = mbo_cmd_sta_send_frame(dut, conn, intf, cmd);
12701 if (res != 2)
12702 return res;
12703 }
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +053012704 if (val && strcasecmp(val, "WPA3") == 0)
12705 return cmd_sta_send_frame_wpa3(dut, conn, intf, cmd);
Vinita S. Malooee9e7e92020-04-28 16:26:50 +053012706 if (val && strcasecmp(val, "QM") == 0)
Vinita S. Malooca85fd22021-01-15 02:54:34 +053012707 return cmd_sta_send_frame_qm(dut, conn, intf, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012708
12709 val = get_param(cmd, "TD_DISC");
12710 if (val) {
12711 if (hwaddr_aton(val, addr) < 0)
12712 return -1;
12713 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", val);
12714 if (wpa_command(intf, buf) < 0) {
12715 send_resp(dut, conn, SIGMA_ERROR,
12716 "ErrorCode,Failed to send TDLS discovery");
12717 return 0;
12718 }
12719 return 1;
12720 }
12721
12722 val = get_param(cmd, "TD_Setup");
12723 if (val) {
12724 if (hwaddr_aton(val, addr) < 0)
12725 return -1;
12726 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", val);
12727 if (wpa_command(intf, buf) < 0) {
12728 send_resp(dut, conn, SIGMA_ERROR,
12729 "ErrorCode,Failed to start TDLS setup");
12730 return 0;
12731 }
12732 return 1;
12733 }
12734
12735 val = get_param(cmd, "TD_TearDown");
12736 if (val) {
12737 if (hwaddr_aton(val, addr) < 0)
12738 return -1;
12739 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", val);
12740 if (wpa_command(intf, buf) < 0) {
12741 send_resp(dut, conn, SIGMA_ERROR,
12742 "ErrorCode,Failed to tear down TDLS link");
12743 return 0;
12744 }
12745 return 1;
12746 }
12747
12748 val = get_param(cmd, "TD_ChannelSwitch");
12749 if (val) {
12750 /* TODO */
12751 send_resp(dut, conn, SIGMA_ERROR,
12752 "ErrorCode,TD_ChannelSwitch not yet supported");
12753 return 0;
12754 }
12755
12756 val = get_param(cmd, "TD_NF");
12757 if (val) {
12758 /* TODO */
12759 send_resp(dut, conn, SIGMA_ERROR,
12760 "ErrorCode,TD_NF not yet supported");
12761 return 0;
12762 }
12763
12764 val = get_param(cmd, "PMFFrameType");
12765 if (val == NULL)
12766 val = get_param(cmd, "FrameName");
12767 if (val == NULL)
12768 val = get_param(cmd, "Type");
12769 if (val == NULL)
12770 return -1;
12771 if (strcasecmp(val, "disassoc") == 0)
12772 frame = DISASSOC;
12773 else if (strcasecmp(val, "deauth") == 0)
12774 frame = DEAUTH;
12775 else if (strcasecmp(val, "saquery") == 0)
12776 frame = SAQUERY;
12777 else if (strcasecmp(val, "auth") == 0)
12778 frame = AUTH;
12779 else if (strcasecmp(val, "assocreq") == 0)
12780 frame = ASSOCREQ;
12781 else if (strcasecmp(val, "reassocreq") == 0)
12782 frame = REASSOCREQ;
12783 else if (strcasecmp(val, "neigreq") == 0) {
12784 sigma_dut_print(dut, DUT_MSG_INFO, "Got neighbor request");
12785
12786 val = get_param(cmd, "ssid");
12787 if (val == NULL)
12788 return -1;
12789
12790 res = send_neighbor_request(dut, intf, val);
12791 if (res) {
12792 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
12793 "Failed to send neighbor report request");
12794 return 0;
12795 }
12796
12797 return 1;
Ashwini Patil5acd7382017-04-13 15:55:04 +053012798 } else if (strcasecmp(val, "transmgmtquery") == 0 ||
12799 strcasecmp(val, "BTMQuery") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012800 sigma_dut_print(dut, DUT_MSG_DEBUG,
12801 "Got Transition Management Query");
12802
Ashwini Patil5acd7382017-04-13 15:55:04 +053012803 res = send_trans_mgmt_query(dut, intf, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012804 if (res) {
12805 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
12806 "Failed to send Transition Management Query");
12807 return 0;
12808 }
12809
12810 return 1;
12811 } else {
12812 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
12813 "PMFFrameType");
12814 return 0;
12815 }
12816
12817 val = get_param(cmd, "PMFProtected");
12818 if (val == NULL)
12819 val = get_param(cmd, "Protected");
12820 if (val == NULL)
12821 return -1;
12822 if (strcasecmp(val, "Correct-key") == 0 ||
12823 strcasecmp(val, "CorrectKey") == 0)
12824 protected = CORRECT_KEY;
12825 else if (strcasecmp(val, "IncorrectKey") == 0)
12826 protected = INCORRECT_KEY;
12827 else if (strcasecmp(val, "Unprotected") == 0)
12828 protected = UNPROTECTED;
12829 else {
12830 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
12831 "PMFProtected");
12832 return 0;
12833 }
12834
12835 if (protected != UNPROTECTED &&
12836 (frame == AUTH || frame == ASSOCREQ || frame == REASSOCREQ)) {
12837 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Impossible "
12838 "PMFProtected for auth/assocreq/reassocreq");
12839 return 0;
12840 }
12841
12842 if (if_nametoindex("sigmadut") == 0) {
12843 snprintf(buf, sizeof(buf),
12844 "iw dev %s interface add sigmadut type monitor",
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012845 get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012846 if (system(buf) != 0 ||
12847 if_nametoindex("sigmadut") == 0) {
12848 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
12849 "monitor interface with '%s'", buf);
12850 return -2;
12851 }
12852 }
12853
12854 if (system("ifconfig sigmadut up") != 0) {
12855 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
12856 "monitor interface up");
12857 return -2;
12858 }
12859
Veerendranath Jakkam49774122020-07-05 09:52:18 +053012860 return sta_inject_frame(dut, conn, intf, frame, protected, NULL, 1);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012861}
12862
12863
12864static int cmd_sta_set_parameter_hs2(struct sigma_dut *dut,
12865 struct sigma_conn *conn,
12866 struct sigma_cmd *cmd,
12867 const char *ifname)
12868{
12869 char buf[200];
12870 const char *val;
12871
12872 val = get_param(cmd, "ClearARP");
12873 if (val && atoi(val) == 1) {
12874 snprintf(buf, sizeof(buf), "ip neigh flush dev %s", ifname);
12875 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
12876 if (system(buf) != 0) {
12877 send_resp(dut, conn, SIGMA_ERROR,
12878 "errorCode,Failed to clear ARP cache");
12879 return 0;
12880 }
12881 }
12882
12883 return 1;
12884}
12885
12886
12887int cmd_sta_set_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
12888 struct sigma_cmd *cmd)
12889{
12890 const char *intf = get_param(cmd, "Interface");
12891 const char *val;
12892
12893 if (intf == NULL)
12894 return -1;
12895
12896 val = get_param(cmd, "program");
12897 if (val && (strcasecmp(val, "HS2") == 0 ||
Jouni Malinen1f6ae642018-06-07 23:56:13 +030012898 strcasecmp(val, "HS2-R2") == 0 ||
12899 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012900 return cmd_sta_set_parameter_hs2(dut, conn, cmd, intf);
12901
12902 return -1;
12903}
12904
12905
Jouni Malinenf7222712019-06-13 01:50:21 +030012906static enum sigma_cmd_result cmd_sta_set_macaddr(struct sigma_dut *dut,
12907 struct sigma_conn *conn,
12908 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012909{
12910 const char *intf = get_param(cmd, "Interface");
12911 const char *mac = get_param(cmd, "MAC");
12912
12913 if (intf == NULL || mac == NULL)
12914 return -1;
12915
12916 sigma_dut_print(dut, DUT_MSG_INFO, "Change local MAC address for "
12917 "interface %s to %s", intf, mac);
12918
12919 if (dut->set_macaddr) {
12920 char buf[128];
12921 int res;
12922 if (strcasecmp(mac, "default") == 0) {
12923 res = snprintf(buf, sizeof(buf), "%s",
12924 dut->set_macaddr);
12925 dut->tmp_mac_addr = 0;
12926 } else {
12927 res = snprintf(buf, sizeof(buf), "%s %s",
12928 dut->set_macaddr, mac);
12929 dut->tmp_mac_addr = 1;
12930 }
12931 if (res < 0 || res >= (int) sizeof(buf))
12932 return -1;
12933 if (system(buf) != 0) {
12934 send_resp(dut, conn, SIGMA_ERROR,
12935 "errorCode,Failed to set MAC "
12936 "address");
12937 return 0;
12938 }
12939 return 1;
12940 }
12941
12942 if (strcasecmp(mac, "default") == 0)
12943 return 1;
12944
12945 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
12946 "command");
12947 return 0;
12948}
12949
12950
12951static int iwpriv_tdlsoffchnmode(struct sigma_dut *dut,
12952 struct sigma_conn *conn, const char *intf,
12953 int val)
12954{
12955 char buf[200];
12956 int res;
12957
12958 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchnmode %d",
12959 intf, val);
12960 if (res < 0 || res >= (int) sizeof(buf))
12961 return -1;
12962 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
12963 if (system(buf) != 0) {
12964 send_resp(dut, conn, SIGMA_ERROR,
12965 "errorCode,Failed to configure offchannel mode");
12966 return 0;
12967 }
12968
12969 return 1;
12970}
12971
12972
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012973static int off_chan_val(enum sec_ch_offset off)
12974{
12975 switch (off) {
12976 case SEC_CH_NO:
12977 return 0;
12978 case SEC_CH_40ABOVE:
12979 return 40;
12980 case SEC_CH_40BELOW:
12981 return -40;
12982 }
12983
12984 return 0;
12985}
12986
12987
12988static int iwpriv_set_offchan(struct sigma_dut *dut, struct sigma_conn *conn,
12989 const char *intf, int off_ch_num,
12990 enum sec_ch_offset sec)
12991{
12992 char buf[200];
12993 int res;
12994
12995 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchan %d",
12996 intf, off_ch_num);
12997 if (res < 0 || res >= (int) sizeof(buf))
12998 return -1;
12999 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
13000 if (system(buf) != 0) {
13001 send_resp(dut, conn, SIGMA_ERROR,
13002 "errorCode,Failed to set offchan");
13003 return 0;
13004 }
13005
13006 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsecchnoffst %d",
13007 intf, off_chan_val(sec));
13008 if (res < 0 || res >= (int) sizeof(buf))
13009 return -1;
13010 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
13011 if (system(buf) != 0) {
13012 send_resp(dut, conn, SIGMA_ERROR,
13013 "errorCode,Failed to set sec chan offset");
13014 return 0;
13015 }
13016
13017 return 1;
13018}
13019
13020
13021static int tdls_set_offchannel_offset(struct sigma_dut *dut,
13022 struct sigma_conn *conn,
13023 const char *intf, int off_ch_num,
13024 enum sec_ch_offset sec)
13025{
13026 char buf[200];
13027 int res;
13028
13029 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNEL %d",
13030 off_ch_num);
13031 if (res < 0 || res >= (int) sizeof(buf))
13032 return -1;
13033 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
13034
13035 if (wpa_command(intf, buf) < 0) {
13036 send_resp(dut, conn, SIGMA_ERROR,
13037 "ErrorCode,Failed to set offchan");
13038 return 0;
13039 }
13040 res = snprintf(buf, sizeof(buf), "DRIVER TDLSSECONDARYCHANNELOFFSET %d",
13041 off_chan_val(sec));
13042 if (res < 0 || res >= (int) sizeof(buf))
13043 return -1;
13044
13045 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
13046
13047 if (wpa_command(intf, buf) < 0) {
13048 send_resp(dut, conn, SIGMA_ERROR,
13049 "ErrorCode,Failed to set sec chan offset");
13050 return 0;
13051 }
13052
13053 return 1;
13054}
13055
13056
13057static int tdls_set_offchannel_mode(struct sigma_dut *dut,
13058 struct sigma_conn *conn,
13059 const char *intf, int val)
13060{
13061 char buf[200];
13062 int res;
13063
13064 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNELMODE %d",
13065 val);
13066 if (res < 0 || res >= (int) sizeof(buf))
13067 return -1;
13068 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
13069
13070 if (wpa_command(intf, buf) < 0) {
13071 send_resp(dut, conn, SIGMA_ERROR,
13072 "ErrorCode,Failed to configure offchannel mode");
13073 return 0;
13074 }
13075
13076 return 1;
13077}
13078
13079
13080static int cmd_sta_set_rfeature_tdls(const char *intf, struct sigma_dut *dut,
13081 struct sigma_conn *conn,
13082 struct sigma_cmd *cmd)
13083{
13084 const char *val;
13085 enum {
13086 CHSM_NOT_SET,
13087 CHSM_ENABLE,
13088 CHSM_DISABLE,
13089 CHSM_REJREQ,
13090 CHSM_UNSOLRESP
13091 } chsm = CHSM_NOT_SET;
13092 int off_ch_num = -1;
13093 enum sec_ch_offset sec_ch = SEC_CH_NO;
13094 int res;
13095
13096 val = get_param(cmd, "Uapsd");
13097 if (val) {
13098 char buf[100];
13099 if (strcasecmp(val, "Enable") == 0)
13100 snprintf(buf, sizeof(buf), "SET ps 99");
13101 else if (strcasecmp(val, "Disable") == 0)
13102 snprintf(buf, sizeof(buf), "SET ps 98");
13103 else {
13104 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
13105 "Unsupported uapsd parameter value");
13106 return 0;
13107 }
13108 if (wpa_command(intf, buf)) {
13109 send_resp(dut, conn, SIGMA_ERROR,
13110 "ErrorCode,Failed to change U-APSD "
13111 "powersave mode");
13112 return 0;
13113 }
13114 }
13115
13116 val = get_param(cmd, "TPKTIMER");
13117 if (val && strcasecmp(val, "DISABLE") == 0) {
13118 if (wpa_command(intf, "SET tdls_testing 0x100")) {
13119 send_resp(dut, conn, SIGMA_ERROR,
13120 "ErrorCode,Failed to enable no TPK "
13121 "expiration test mode");
13122 return 0;
13123 }
13124 dut->no_tpk_expiration = 1;
13125 }
13126
13127 val = get_param(cmd, "ChSwitchMode");
13128 if (val) {
13129 if (strcasecmp(val, "Enable") == 0 ||
13130 strcasecmp(val, "Initiate") == 0)
13131 chsm = CHSM_ENABLE;
13132 else if (strcasecmp(val, "Disable") == 0 ||
13133 strcasecmp(val, "passive") == 0)
13134 chsm = CHSM_DISABLE;
13135 else if (strcasecmp(val, "RejReq") == 0)
13136 chsm = CHSM_REJREQ;
13137 else if (strcasecmp(val, "UnSolResp") == 0)
13138 chsm = CHSM_UNSOLRESP;
13139 else {
13140 send_resp(dut, conn, SIGMA_ERROR,
13141 "ErrorCode,Unknown ChSwitchMode value");
13142 return 0;
13143 }
13144 }
13145
13146 val = get_param(cmd, "OffChNum");
13147 if (val) {
13148 off_ch_num = atoi(val);
13149 if (off_ch_num == 0) {
13150 send_resp(dut, conn, SIGMA_ERROR,
13151 "ErrorCode,Invalid OffChNum");
13152 return 0;
13153 }
13154 }
13155
13156 val = get_param(cmd, "SecChOffset");
13157 if (val) {
13158 if (strcmp(val, "20") == 0)
13159 sec_ch = SEC_CH_NO;
13160 else if (strcasecmp(val, "40above") == 0)
13161 sec_ch = SEC_CH_40ABOVE;
13162 else if (strcasecmp(val, "40below") == 0)
13163 sec_ch = SEC_CH_40BELOW;
13164 else {
13165 send_resp(dut, conn, SIGMA_ERROR,
13166 "ErrorCode,Unknown SecChOffset value");
13167 return 0;
13168 }
13169 }
13170
13171 if (chsm == CHSM_NOT_SET) {
13172 /* no offchannel changes requested */
13173 return 1;
13174 }
13175
Jouni Malinen016ae6c2019-11-04 17:00:01 +020013176 if (strcmp(intf, get_main_ifname(dut)) != 0 &&
13177 strcmp(intf, get_station_ifname(dut)) != 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013178 send_resp(dut, conn, SIGMA_ERROR,
13179 "ErrorCode,Unknown interface");
13180 return 0;
13181 }
13182
13183 switch (chsm) {
13184 case CHSM_NOT_SET:
Jouni Malinen280f5ba2016-08-29 21:33:10 +030013185 res = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013186 break;
13187 case CHSM_ENABLE:
13188 if (off_ch_num < 0) {
13189 send_resp(dut, conn, SIGMA_ERROR,
13190 "ErrorCode,Missing OffChNum argument");
13191 return 0;
13192 }
13193 if (wifi_chip_type == DRIVER_WCN) {
13194 res = tdls_set_offchannel_offset(dut, conn, intf,
13195 off_ch_num, sec_ch);
13196 } else {
13197 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
13198 sec_ch);
13199 }
13200 if (res != 1)
13201 return res;
13202 if (wifi_chip_type == DRIVER_WCN)
13203 res = tdls_set_offchannel_mode(dut, conn, intf, 1);
13204 else
13205 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 1);
13206 break;
13207 case CHSM_DISABLE:
13208 if (wifi_chip_type == DRIVER_WCN)
13209 res = tdls_set_offchannel_mode(dut, conn, intf, 2);
13210 else
13211 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 2);
13212 break;
13213 case CHSM_REJREQ:
13214 if (wifi_chip_type == DRIVER_WCN)
13215 res = tdls_set_offchannel_mode(dut, conn, intf, 3);
13216 else
13217 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 3);
13218 break;
13219 case CHSM_UNSOLRESP:
13220 if (off_ch_num < 0) {
13221 send_resp(dut, conn, SIGMA_ERROR,
13222 "ErrorCode,Missing OffChNum argument");
13223 return 0;
13224 }
13225 if (wifi_chip_type == DRIVER_WCN) {
13226 res = tdls_set_offchannel_offset(dut, conn, intf,
13227 off_ch_num, sec_ch);
13228 } else {
13229 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
13230 sec_ch);
13231 }
13232 if (res != 1)
13233 return res;
13234 if (wifi_chip_type == DRIVER_WCN)
13235 res = tdls_set_offchannel_mode(dut, conn, intf, 4);
13236 else
13237 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 4);
13238 break;
13239 }
13240
13241 return res;
13242}
13243
13244
13245static int ath_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
13246 struct sigma_conn *conn,
13247 struct sigma_cmd *cmd)
13248{
13249 const char *val;
Srikanth Marepalli5415acf2018-08-27 12:53:11 +053013250 char *token = NULL, *result;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013251
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -070013252 novap_reset(dut, intf, 1);
priyadharshini gowthamane5e25172015-12-08 14:53:48 -080013253
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013254 val = get_param(cmd, "nss_mcs_opt");
13255 if (val) {
13256 /* String (nss_operating_mode; mcs_operating_mode) */
13257 int nss, mcs;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053013258 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013259
13260 token = strdup(val);
13261 if (!token)
13262 return 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053013263 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +053013264 if (!result) {
13265 sigma_dut_print(dut, DUT_MSG_ERROR,
13266 "VHT NSS not specified");
13267 goto failed;
13268 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013269 if (strcasecmp(result, "def") != 0) {
13270 nss = atoi(result);
13271 if (nss == 4)
13272 ath_disable_txbf(dut, intf);
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070013273 if (run_iwpriv(dut, intf, "nss %d", nss) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013274 goto failed;
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070013275
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013276 }
13277
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053013278 result = strtok_r(NULL, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +053013279 if (!result) {
13280 sigma_dut_print(dut, DUT_MSG_ERROR,
13281 "VHT MCS not specified");
13282 goto failed;
13283 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013284 if (strcasecmp(result, "def") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070013285 if (run_iwpriv(dut, intf, "set11NRates 0") < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013286 goto failed;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013287 } else {
13288 mcs = atoi(result);
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070013289 if (run_iwpriv(dut, intf, "vhtmcs %d", mcs) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013290 goto failed;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013291 }
13292 /* Channel width gets messed up, fix this */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070013293 run_iwpriv(dut, intf, "chwidth %d", dut->chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013294 }
13295
Srikanth Marepalli5415acf2018-08-27 12:53:11 +053013296 free(token);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013297 return 1;
13298failed:
13299 free(token);
13300 return 0;
13301}
13302
13303
13304static int cmd_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
13305 struct sigma_conn *conn,
13306 struct sigma_cmd *cmd)
13307{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020013308 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013309 case DRIVER_ATHEROS:
13310 return ath_sta_set_rfeature_vht(intf, dut, conn, cmd);
13311 default:
13312 send_resp(dut, conn, SIGMA_ERROR,
13313 "errorCode,Unsupported sta_set_rfeature(VHT) with the current driver");
13314 return 0;
13315 }
13316}
13317
13318
Jouni Malinen1702fe32021-06-08 19:08:01 +030013319static enum sigma_cmd_result
13320wcn_sta_set_rfeature_he(const char *intf, struct sigma_dut *dut,
13321 struct sigma_conn *conn, struct sigma_cmd *cmd)
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080013322{
13323 const char *val;
13324 char *token = NULL, *result;
13325 char buf[60];
13326
13327 val = get_param(cmd, "nss_mcs_opt");
13328 if (val) {
13329 /* String (nss_operating_mode; mcs_operating_mode) */
13330 int nss, mcs, ratecode;
13331 char *saveptr;
13332
13333 token = strdup(val);
13334 if (!token)
Jouni Malinen1702fe32021-06-08 19:08:01 +030013335 return ERROR_SEND_STATUS;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080013336
13337 result = strtok_r(token, ";", &saveptr);
13338 if (!result) {
13339 sigma_dut_print(dut, DUT_MSG_ERROR,
13340 "HE NSS not specified");
13341 goto failed;
13342 }
13343 nss = 1;
13344 if (strcasecmp(result, "def") != 0)
13345 nss = atoi(result);
13346
13347 result = strtok_r(NULL, ";", &saveptr);
13348 if (!result) {
13349 sigma_dut_print(dut, DUT_MSG_ERROR,
13350 "HE MCS not specified");
13351 goto failed;
13352 }
13353 mcs = 7;
13354 if (strcasecmp(result, "def") != 0)
13355 mcs = atoi(result);
13356
Arif Hussain557bf412018-05-25 17:29:36 -070013357 ratecode = 0x20; /* for nss:1 MCS 0 */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080013358 if (nss == 2) {
Arif Hussain557bf412018-05-25 17:29:36 -070013359 ratecode = 0x40; /* for nss:2 MCS 0 */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080013360 } else if (nss > 2) {
13361 sigma_dut_print(dut, DUT_MSG_ERROR,
13362 "HE NSS %d not supported", nss);
13363 goto failed;
13364 }
13365
Arif Hussain557bf412018-05-25 17:29:36 -070013366 snprintf(buf, sizeof(buf), "iwpriv %s nss %d", intf, nss);
13367 if (system(buf) != 0) {
13368 sigma_dut_print(dut, DUT_MSG_ERROR,
13369 "nss_mcs_opt: iwpriv %s nss %d failed",
13370 intf, nss);
13371 goto failed;
13372 }
Arif Hussainac6c5112018-05-25 17:34:00 -070013373 dut->sta_nss = nss;
Arif Hussain557bf412018-05-25 17:29:36 -070013374
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080013375 /* Add the MCS to the ratecode */
13376 if (mcs >= 0 && mcs <= 11) {
13377 ratecode += mcs;
Arif Hussain557bf412018-05-25 17:29:36 -070013378#ifdef NL80211_SUPPORT
13379 if (dut->device_type == STA_testbed) {
13380 enum he_mcs_config mcs_config;
13381 int ret;
13382
13383 if (mcs <= 7)
13384 mcs_config = HE_80_MCS0_7;
13385 else if (mcs <= 9)
13386 mcs_config = HE_80_MCS0_9;
13387 else
13388 mcs_config = HE_80_MCS0_11;
13389 ret = sta_set_he_mcs(dut, intf, mcs_config);
13390 if (ret) {
13391 sigma_dut_print(dut, DUT_MSG_ERROR,
13392 "nss_mcs_opt: mcs setting failed, mcs:%d, mcs_config %d, ret:%d",
13393 mcs, mcs_config, ret);
13394 goto failed;
13395 }
13396 }
13397#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080013398 } else {
13399 sigma_dut_print(dut, DUT_MSG_ERROR,
13400 "HE MCS %d not supported", mcs);
13401 goto failed;
13402 }
13403 snprintf(buf, sizeof(buf), "iwpriv %s set_11ax_rate 0x%03x",
13404 intf, ratecode);
13405 if (system(buf) != 0) {
13406 sigma_dut_print(dut, DUT_MSG_ERROR,
13407 "iwpriv setting of 11ax rates failed");
13408 goto failed;
13409 }
13410 free(token);
13411 }
13412
13413 val = get_param(cmd, "GI");
13414 if (val) {
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080013415 int fix_rate_sgi;
13416
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080013417 if (strcmp(val, "0.8") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070013418 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 9", intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080013419 fix_rate_sgi = 1;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080013420 } else if (strcmp(val, "1.6") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070013421 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 10",
13422 intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080013423 fix_rate_sgi = 2;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080013424 } else if (strcmp(val, "3.2") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070013425 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 11",
13426 intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080013427 fix_rate_sgi = 3;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080013428 } else {
13429 send_resp(dut, conn, SIGMA_ERROR,
13430 "errorCode,GI value not supported");
Jouni Malinen1702fe32021-06-08 19:08:01 +030013431 return STATUS_SENT_ERROR;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080013432 }
13433 if (system(buf) != 0) {
13434 send_resp(dut, conn, SIGMA_ERROR,
13435 "errorCode,Failed to set shortgi");
Jouni Malinen1702fe32021-06-08 19:08:01 +030013436 return STATUS_SENT_ERROR;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080013437 }
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080013438 snprintf(buf, sizeof(buf), "iwpriv %s shortgi %d",
13439 intf, fix_rate_sgi);
13440 if (system(buf) != 0) {
13441 send_resp(dut, conn, SIGMA_ERROR,
13442 "errorCode,Failed to set fix rate shortgi");
Jouni Malinen1702fe32021-06-08 19:08:01 +030013443 return STATUS_SENT_ERROR;
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080013444 }
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080013445 }
13446
Subhani Shaik8e7a3052018-04-24 14:03:00 -070013447 val = get_param(cmd, "LTF");
13448 if (val) {
13449#ifdef NL80211_SUPPORT
13450 if (strcmp(val, "3.2") == 0) {
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -080013451 wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_1X);
Subhani Shaik8e7a3052018-04-24 14:03:00 -070013452 } if (strcmp(val, "6.4") == 0) {
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -080013453 wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_2X);
Subhani Shaik8e7a3052018-04-24 14:03:00 -070013454 } else if (strcmp(val, "12.8") == 0) {
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -080013455 wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_4X);
Subhani Shaik8e7a3052018-04-24 14:03:00 -070013456 } else {
13457 send_resp(dut, conn, SIGMA_ERROR,
13458 "errorCode, LTF value not supported");
Jouni Malinen1702fe32021-06-08 19:08:01 +030013459 return STATUS_SENT_ERROR;
Subhani Shaik8e7a3052018-04-24 14:03:00 -070013460 }
13461#else /* NL80211_SUPPORT */
13462 sigma_dut_print(dut, DUT_MSG_ERROR,
13463 "LTF cannot be set without NL80211_SUPPORT defined");
Jouni Malinen1702fe32021-06-08 19:08:01 +030013464 return ERROR_SEND_STATUS;
Subhani Shaik8e7a3052018-04-24 14:03:00 -070013465#endif /* NL80211_SUPPORT */
13466 }
13467
Kiran Kumar Lokere1809da12021-06-24 00:45:38 -070013468 val = get_param(cmd, "KeepAlive");
13469 if (val) {
13470 int set_val = QCA_WLAN_KEEP_ALIVE_DEFAULT;
13471
13472 if (strcasecmp(val, "Data") == 0)
13473 set_val = QCA_WLAN_KEEP_ALIVE_DATA;
13474 else if (strcasecmp(val, "Mgmt") == 0)
13475 set_val = QCA_WLAN_KEEP_ALIVE_MGMT;
13476
13477 if (sta_set_keep_alive_data_cfg(dut, intf, set_val)) {
13478 send_resp(dut, conn, SIGMA_ERROR,
13479 "ErrorCode,Failed to set keep alive type config");
13480 return STATUS_SENT_ERROR;
13481 }
13482 }
13483
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -070013484 val = get_param(cmd, "TxSUPPDU");
13485 if (val) {
13486 int set_val = 1;
13487
13488 if (strcasecmp(val, "Enable") == 0)
13489 set_val = 1;
13490 else if (strcasecmp(val, "Disable") == 0)
13491 set_val = 0;
13492
13493 if (sta_set_tx_su_ppdu_cfg(dut, intf, set_val)) {
13494 send_resp(dut, conn, SIGMA_ERROR,
13495 "ErrorCode,Failed to set Tx SU PPDU config");
Jouni Malinen1702fe32021-06-08 19:08:01 +030013496 return STATUS_SENT_ERROR;
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -070013497 }
13498 }
13499
Kiran Kumar Lokere54b72522021-04-01 00:22:44 -070013500 val = get_param(cmd, "Mgmt_Data_TX_Resp_Frame");
13501 if (val) {
13502 int set_val = 0;
13503
13504 if (strcasecmp(val, "Enable") == 0)
13505 set_val = 0;
13506 else if (strcasecmp(val, "Disable") == 0)
13507 set_val = 1;
13508
13509 if (sta_set_mgmt_data_tx_disable_cfg(dut, intf, set_val)) {
13510 send_resp(dut, conn, SIGMA_ERROR,
13511 "ErrorCode,Failed to set mgmt/data Tx disable config");
13512 return STATUS_SENT_ERROR;
13513 }
13514 }
13515
Arif Hussain480d5f42019-03-12 14:40:42 -070013516 val = get_param(cmd, "TWT_Setup");
13517 if (val) {
13518 if (strcasecmp(val, "Request") == 0) {
13519 if (sta_twt_request(dut, conn, cmd)) {
13520 send_resp(dut, conn, SIGMA_ERROR,
Srinivas Girigowda6707f032020-10-26 15:24:46 -070013521 "ErrorCode,TWT setup failed");
Jouni Malinen1702fe32021-06-08 19:08:01 +030013522 return STATUS_SENT_ERROR;
Arif Hussain480d5f42019-03-12 14:40:42 -070013523 }
13524 } else if (strcasecmp(val, "Teardown") == 0) {
13525 if (sta_twt_teardown(dut, conn, cmd)) {
13526 send_resp(dut, conn, SIGMA_ERROR,
Srinivas Girigowda6707f032020-10-26 15:24:46 -070013527 "ErrorCode,TWT teardown failed");
Jouni Malinen1702fe32021-06-08 19:08:01 +030013528 return STATUS_SENT_ERROR;
Arif Hussain480d5f42019-03-12 14:40:42 -070013529 }
13530 }
13531 }
13532
Srinivas Girigowda6707f032020-10-26 15:24:46 -070013533 val = get_param(cmd, "TWT_Operation");
13534 if (val) {
13535 if (strcasecmp(val, "Suspend") == 0) {
13536 if (sta_twt_suspend_or_nudge(dut, conn, cmd)) {
13537 send_resp(dut, conn, SIGMA_ERROR,
13538 "ErrorCode,TWT suspend failed");
13539 return STATUS_SENT_ERROR;
13540 }
13541 } else if (strcasecmp(val, "Resume") == 0) {
13542 if (sta_twt_resume(dut, conn, cmd)) {
13543 send_resp(dut, conn, SIGMA_ERROR,
13544 "ErrorCode,TWT resume failed");
13545 return STATUS_SENT_ERROR;
13546 }
13547 }
13548 }
13549
Kiran Kumar Lokere50eb2cd2018-12-18 18:31:28 -080013550 val = get_param(cmd, "transmitOMI");
13551 if (val && sta_transmit_omi(dut, conn, cmd)) {
13552 send_resp(dut, conn, SIGMA_ERROR,
13553 "ErrorCode,sta_transmit_omi failed");
Jouni Malinen1702fe32021-06-08 19:08:01 +030013554 return STATUS_SENT_ERROR;
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -070013555 }
13556
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080013557 val = get_param(cmd, "Powersave");
13558 if (val) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053013559 int ps;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080013560
13561 if (strcasecmp(val, "off") == 0) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053013562 ps = 2;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080013563 } else if (strcasecmp(val, "on") == 0) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053013564 ps = 1;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080013565 } else {
13566 sigma_dut_print(dut, DUT_MSG_ERROR,
13567 "Unsupported Powersave value '%s'",
13568 val);
Jouni Malinen1702fe32021-06-08 19:08:01 +030013569 return INVALID_SEND_STATUS;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080013570 }
Vinita S. Malooa8b62722020-04-23 01:45:41 +053013571 if (set_power_save_wcn(dut, intf, ps) < 0)
Jouni Malinen1702fe32021-06-08 19:08:01 +030013572 return ERROR_SEND_STATUS;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080013573 }
13574
Kiran Kumar Lokere2c4b7ce2019-01-30 12:02:28 -080013575 val = get_param(cmd, "MU_EDCA");
13576 if (val) {
13577 if (strcasecmp(val, "Override") == 0) {
13578 if (sta_set_mu_edca_override(dut, intf, 1)) {
13579 send_resp(dut, conn, SIGMA_ERROR,
13580 "errorCode,MU EDCA override set failed");
13581 return STATUS_SENT;
13582 }
13583 } else if (strcasecmp(val, "Disable") == 0) {
13584 if (sta_set_mu_edca_override(dut, intf, 0)) {
13585 send_resp(dut, conn, SIGMA_ERROR,
13586 "errorCode,MU EDCA override disable failed");
13587 return STATUS_SENT;
13588 }
13589 }
13590 }
13591
Kiran Kumar Lokerefa7c7b92021-08-09 00:50:55 -070013592 val = get_param(cmd, "RUAllocTone");
13593 if (val && strcasecmp(val, "242") == 0) {
13594 if (sta_set_ru_242_tone_tx(dut, intf, 1)) {
13595 send_resp(dut, conn, SIGMA_ERROR,
13596 "ErrorCode,Failed to set RU 242 tone Tx");
13597 return STATUS_SENT_ERROR;
13598 }
13599 }
13600
13601 val = get_param(cmd, "PPDUTxType");
13602 if (val && strcasecmp(val, "ER-SU") == 0) {
13603 if (sta_set_er_su_ppdu_type_tx(dut, intf, 1)) {
13604 send_resp(dut, conn, SIGMA_ERROR,
13605 "ErrorCode,Failed to set ER-SU PPDU type Tx");
13606 return STATUS_SENT_ERROR;
13607 }
13608 }
13609
Kiran Kumar Lokeredd086642020-06-04 00:29:26 -070013610 val = get_param(cmd, "Ch_Pref");
13611 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
13612 return STATUS_SENT;
13613
13614 val = get_param(cmd, "Cellular_Data_Cap");
13615 if (val && mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
13616 return STATUS_SENT;
13617
Jouni Malinen1702fe32021-06-08 19:08:01 +030013618 return SUCCESS_SEND_STATUS;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080013619
13620failed:
13621 free(token);
Jouni Malinen1702fe32021-06-08 19:08:01 +030013622 return ERROR_SEND_STATUS;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080013623}
13624
13625
Jouni Malinen1702fe32021-06-08 19:08:01 +030013626static enum sigma_cmd_result
13627cmd_sta_set_rfeature_he(const char *intf, struct sigma_dut *dut,
13628 struct sigma_conn *conn, struct sigma_cmd *cmd)
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080013629{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020013630 switch (get_driver_type(dut)) {
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080013631 case DRIVER_WCN:
13632 return wcn_sta_set_rfeature_he(intf, dut, conn, cmd);
13633 default:
13634 send_resp(dut, conn, SIGMA_ERROR,
13635 "errorCode,Unsupported sta_set_rfeature(HE) with the current driver");
Jouni Malinen1702fe32021-06-08 19:08:01 +030013636 return STATUS_SENT_ERROR;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080013637 }
13638}
13639
13640
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080013641static int cmd_sta_set_power_save_he(const char *intf, struct sigma_dut *dut,
13642 struct sigma_conn *conn,
13643 struct sigma_cmd *cmd)
13644{
13645 const char *val;
13646
13647 val = get_param(cmd, "powersave");
13648 if (val) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053013649 int ps;
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080013650
13651 if (strcasecmp(val, "off") == 0) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053013652 ps = 2;
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080013653 } else if (strcasecmp(val, "on") == 0) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053013654 ps = 1;
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080013655 } else {
13656 sigma_dut_print(dut, DUT_MSG_ERROR,
13657 "Unsupported power save config");
13658 return -1;
13659 }
Vinita S. Malooa8b62722020-04-23 01:45:41 +053013660 if (set_power_save_wcn(dut, intf, ps) < 0)
13661 return 0;
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080013662 return 1;
13663 }
13664
13665 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported command");
13666
13667 return 0;
13668}
13669
13670
Ashwini Patil5acd7382017-04-13 15:55:04 +053013671static int btm_query_candidate_list(struct sigma_dut *dut,
13672 struct sigma_conn *conn,
13673 struct sigma_cmd *cmd)
13674{
13675 const char *bssid, *info, *op_class, *ch, *phy_type, *pref;
13676 int len, ret;
13677 char buf[10];
13678
13679 /*
13680 * Neighbor Report elements format:
13681 * neighbor=<BSSID>,<BSSID Information>,<Operating Class>,
13682 * <Channel Number>,<PHY Type>[,<hexdump of Optional Subelements>]
13683 * eg: neighbor=aa:bb:cc:dd:ee:ff,17,81,6,1,030101
13684 */
13685
13686 bssid = get_param(cmd, "Nebor_BSSID");
13687 if (!bssid) {
13688 send_resp(dut, conn, SIGMA_INVALID,
13689 "errorCode,Nebor_BSSID is missing");
13690 return 0;
13691 }
13692
13693 info = get_param(cmd, "Nebor_Bssid_Info");
13694 if (!info) {
13695 sigma_dut_print(dut, DUT_MSG_INFO,
13696 "Using default value for Nebor_Bssid_Info: %s",
13697 DEFAULT_NEIGHBOR_BSSID_INFO);
13698 info = DEFAULT_NEIGHBOR_BSSID_INFO;
13699 }
13700
13701 op_class = get_param(cmd, "Nebor_Op_Class");
13702 if (!op_class) {
13703 send_resp(dut, conn, SIGMA_INVALID,
13704 "errorCode,Nebor_Op_Class is missing");
13705 return 0;
13706 }
13707
13708 ch = get_param(cmd, "Nebor_Op_Ch");
13709 if (!ch) {
13710 send_resp(dut, conn, SIGMA_INVALID,
13711 "errorCode,Nebor_Op_Ch is missing");
13712 return 0;
13713 }
13714
13715 phy_type = get_param(cmd, "Nebor_Phy_Type");
13716 if (!phy_type) {
13717 sigma_dut_print(dut, DUT_MSG_INFO,
13718 "Using default value for Nebor_Phy_Type: %s",
13719 DEFAULT_NEIGHBOR_PHY_TYPE);
13720 phy_type = DEFAULT_NEIGHBOR_PHY_TYPE;
13721 }
13722
13723 /* Parse optional subelements */
13724 buf[0] = '\0';
13725 pref = get_param(cmd, "Nebor_Pref");
13726 if (pref) {
13727 /* hexdump for preferrence subelement */
13728 ret = snprintf(buf, sizeof(buf), ",0301%02x", atoi(pref));
13729 if (ret < 0 || ret >= (int) sizeof(buf)) {
13730 sigma_dut_print(dut, DUT_MSG_ERROR,
13731 "snprintf failed for optional subelement ret: %d",
13732 ret);
13733 send_resp(dut, conn, SIGMA_ERROR,
13734 "errorCode,snprintf failed for subelement");
13735 return 0;
13736 }
13737 }
13738
13739 if (!dut->btm_query_cand_list) {
13740 dut->btm_query_cand_list = calloc(1, NEIGHBOR_REPORT_SIZE);
13741 if (!dut->btm_query_cand_list) {
13742 send_resp(dut, conn, SIGMA_ERROR,
13743 "errorCode,Failed to allocate memory for btm_query_cand_list");
13744 return 0;
13745 }
13746 }
13747
13748 len = strlen(dut->btm_query_cand_list);
13749 ret = snprintf(dut->btm_query_cand_list + len,
13750 NEIGHBOR_REPORT_SIZE - len, " neighbor=%s,%s,%s,%s,%s%s",
13751 bssid, info, op_class, ch, phy_type, buf);
13752 if (ret < 0 || ret >= NEIGHBOR_REPORT_SIZE - len) {
13753 sigma_dut_print(dut, DUT_MSG_ERROR,
13754 "snprintf failed for neighbor report list ret: %d",
13755 ret);
13756 send_resp(dut, conn, SIGMA_ERROR,
13757 "errorCode,snprintf failed for neighbor report");
13758 free(dut->btm_query_cand_list);
13759 dut->btm_query_cand_list = NULL;
13760 return 0;
13761 }
13762
13763 return 1;
13764}
13765
13766
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020013767int sta_extract_60g_ese(struct sigma_dut *dut, struct sigma_cmd *cmd,
13768 struct sigma_ese_alloc *allocs, int *allocs_size)
13769{
13770 int max_count = *allocs_size;
13771 int count = 0, i;
13772 const char *val;
13773
13774 do {
13775 val = get_param_indexed(cmd, "AllocID", count);
13776 if (val)
13777 count++;
13778 } while (val);
13779
13780 if (count == 0 || count > max_count) {
13781 sigma_dut_print(dut, DUT_MSG_ERROR,
13782 "Invalid number of allocations(%d)", count);
13783 return -1;
13784 }
13785
13786 for (i = 0; i < count; i++) {
13787 val = get_param_indexed(cmd, "PercentBI", i);
13788 if (!val) {
13789 sigma_dut_print(dut, DUT_MSG_ERROR,
13790 "Missing PercentBI parameter at index %d",
13791 i);
13792 return -1;
13793 }
13794 allocs[i].percent_bi = atoi(val);
13795
13796 val = get_param_indexed(cmd, "SrcAID", i);
13797 if (val)
13798 allocs[i].src_aid = strtol(val, NULL, 0);
13799 else
13800 allocs[i].src_aid = ESE_BCAST_AID;
13801
13802 val = get_param_indexed(cmd, "DestAID", i);
13803 if (val)
13804 allocs[i].dst_aid = strtol(val, NULL, 0);
13805 else
13806 allocs[i].dst_aid = ESE_BCAST_AID;
13807
13808 allocs[i].type = ESE_CBAP;
13809 sigma_dut_print(dut, DUT_MSG_INFO,
13810 "Alloc %d PercentBI %d SrcAID %d DstAID %d",
13811 i, allocs[i].percent_bi, allocs[i].src_aid,
13812 allocs[i].dst_aid);
13813 }
13814
13815 *allocs_size = count;
13816 return 0;
13817}
13818
13819
13820static int sta_set_60g_ese(struct sigma_dut *dut, int count,
13821 struct sigma_ese_alloc *allocs)
13822{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020013823 switch (get_driver_type(dut)) {
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020013824#ifdef __linux__
13825 case DRIVER_WIL6210:
13826 if (wil6210_set_ese(dut, count, allocs))
13827 return -1;
13828 return 1;
13829#endif /* __linux__ */
13830 default:
13831 sigma_dut_print(dut, DUT_MSG_ERROR,
13832 "Unsupported sta_set_60g_ese with the current driver");
13833 return -1;
13834 }
13835}
13836
13837
13838static int cmd_sta_set_rfeature_60g(const char *intf, struct sigma_dut *dut,
13839 struct sigma_conn *conn,
13840 struct sigma_cmd *cmd)
13841{
13842 const char *val;
13843
13844 val = get_param(cmd, "ExtSchIE");
13845 if (val && !strcasecmp(val, "Enable")) {
13846 struct sigma_ese_alloc allocs[MAX_ESE_ALLOCS];
13847 int count = MAX_ESE_ALLOCS;
13848
13849 if (sta_extract_60g_ese(dut, cmd, allocs, &count))
13850 return -1;
13851 return sta_set_60g_ese(dut, count, allocs);
13852 }
13853
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +020013854 val = get_param(cmd, "MCS_FixedRate");
13855 if (val) {
13856 int sta_mcs = atoi(val);
13857
13858 sigma_dut_print(dut, DUT_MSG_INFO, "Force STA MCS to %d",
13859 sta_mcs);
13860 wil6210_set_force_mcs(dut, 1, sta_mcs);
13861
Jouni Malinen0e29cf22019-02-19 01:13:21 +020013862 return SUCCESS_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +020013863 }
13864
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020013865 send_resp(dut, conn, SIGMA_ERROR,
13866 "errorCode,Invalid sta_set_rfeature(60G)");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020013867 return STATUS_SENT;
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020013868}
13869
13870
Veerendranath Jakkam76a845c2020-07-14 13:19:40 +053013871static int wcn_sta_override_oci(struct sigma_dut *dut, const char *intf,
13872 const char *oci_frametype, uint32_t oci_freq)
13873{
13874#ifdef NL80211_SUPPORT
13875 struct nl_msg *msg;
13876 int ret = 0;
13877 struct nlattr *params;
13878 struct nlattr *attr;
13879 int ifindex;
13880 u8 frame_type;
13881
13882 ifindex = if_nametoindex(intf);
13883 if (ifindex == 0) {
13884 sigma_dut_print(dut, DUT_MSG_ERROR,
13885 "%s: Index for interface %s failed",
13886 __func__, intf);
13887 return -1;
13888 }
13889
13890 if (strcasecmp(oci_frametype, "SAQueryReq") == 0) {
13891 frame_type = QCA_WLAN_VENDOR_OCI_OVERRIDE_FRAME_SA_QUERY_REQ;
13892 } else if (strcasecmp(oci_frametype, "SAQueryResp") == 0) {
13893 frame_type = QCA_WLAN_VENDOR_OCI_OVERRIDE_FRAME_SA_QUERY_RESP;
13894 } else if (strcasecmp(oci_frametype, "Reassocreq") == 0) {
13895 frame_type = QCA_WLAN_VENDOR_OCI_OVERRIDE_FRAME_FT_REASSOC_REQ;
13896 } else {
13897 sigma_dut_print(dut, DUT_MSG_ERROR, "%s: Unknown frametype %s",
13898 __func__, oci_frametype);
13899 return -1;
13900 }
13901
13902
13903 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
13904 NL80211_CMD_VENDOR)) ||
13905 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
13906 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
13907 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
13908 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
13909 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
13910 !(params = nla_nest_start(
13911 msg,
13912 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_OCI_OVERRIDE)) ||
13913 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_OCI_OVERRIDE_FRAME_TYPE,
13914 frame_type) ||
13915 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_OCI_OVERRIDE_FREQUENCY,
13916 oci_freq)) {
13917 sigma_dut_print(dut, DUT_MSG_ERROR,
13918 "%s: err in adding vendor_cmd and vendor_data",
13919 __func__);
13920 nlmsg_free(msg);
13921 return -1;
13922 }
13923 nla_nest_end(msg, params);
13924 nla_nest_end(msg, attr);
13925
13926 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
13927 if (ret) {
13928 sigma_dut_print(dut, DUT_MSG_ERROR,
13929 "%s: err in send_and_recv_msgs, ret=%d",
13930 __func__, ret);
13931 }
13932 return ret;
13933#else /* NL80211_SUPPORT */
13934 sigma_dut_print(dut, DUT_MSG_ERROR,
13935 "OCI override not possible without NL80211_SUPPORT defined");
13936 return -1;
13937#endif /* NL80211_SUPPORT */
13938}
13939
13940
Veerendranath Jakkam50d5c782020-07-22 01:59:01 +053013941static int wcn_sta_ignore_csa(struct sigma_dut *dut, const char *intf,
13942 uint8_t ignore_csa)
13943{
13944#ifdef NL80211_SUPPORT
13945 return wcn_wifi_test_config_set_u8(
13946 dut, intf,
13947 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_IGNORE_CSA, ignore_csa);
13948#else /* NL80211_SUPPORT */
13949 sigma_dut_print(dut, DUT_MSG_ERROR,
13950 "IgnoreCSA can't be set without NL80211_SUPPORT defined");
13951 return -1;
13952#endif /* NL80211_SUPPORT */
13953}
13954
13955
Veerendranath Jakkamc771fac2020-07-22 01:32:56 +053013956static int wcn_sta_set_rsnxe_used(struct sigma_dut *dut, const char *intf,
13957 uint8_t rsnxe_used)
13958{
13959#ifdef NL80211_SUPPORT
13960 return wcn_wifi_test_config_set_u8(
13961 dut, intf,
13962 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_FT_REASSOCREQ_RSNXE_USED,
13963 rsnxe_used);
13964#else /* NL80211_SUPPORT */
13965 sigma_dut_print(dut, DUT_MSG_ERROR,
13966 "RSNXE_Used can't be set without NL80211_SUPPORT defined");
13967 return -1;
13968#endif /* NL80211_SUPPORT */
13969}
13970
13971
Veerendranath Jakkam1e1e5fd2020-09-10 07:12:37 +053013972static int wcn_sta_ignore_sa_query_timeout(struct sigma_dut *dut,
13973 const char *intf,
13974 uint8_t ignore_sa_query_timeout)
13975{
13976#ifdef NL80211_SUPPORT
13977 return wcn_wifi_test_config_set_u8(
13978 dut, intf,
13979 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_IGNORE_SA_QUERY_TIMEOUT,
13980 ignore_sa_query_timeout);
13981#else /* NL80211_SUPPORT */
13982 sigma_dut_print(dut, DUT_MSG_ERROR,
13983 "Ignore SA Query timeout can't be set without NL80211_SUPPORT defined");
13984 return -1;
13985#endif /* NL80211_SUPPORT */
13986}
13987
13988
Jouni Malinen6250cb02020-04-15 13:54:45 +030013989static enum sigma_cmd_result
13990cmd_sta_set_rfeature_wpa3(const char *intf, struct sigma_dut *dut,
13991 struct sigma_conn *conn,
13992 struct sigma_cmd *cmd)
13993{
Vamsi Krishnad29bc762020-05-08 23:23:30 +053013994 const char *val, *oci_chan, *oci_frametype;
Jouni Malinen6250cb02020-04-15 13:54:45 +030013995
Veerendranath Jakkam30bf9072020-04-16 14:37:57 +053013996 val = get_param(cmd, "ReassocReq_RSNXE_Used");
Jouni Malinen6250cb02020-04-15 13:54:45 +030013997 if (val && atoi(val) == 1) {
Veerendranath Jakkamc771fac2020-07-22 01:32:56 +053013998 if (wifi_chip_type == DRIVER_WCN) {
13999 if (wcn_sta_set_rsnxe_used(dut, intf, 1)) {
14000 send_resp(dut, conn, SIGMA_ERROR,
14001 "errorCode,Failed to set ft_rsnxe_used");
14002 return STATUS_SENT_ERROR;
14003 }
14004 return SUCCESS_SEND_STATUS;
14005 } else if (wpa_command(intf, "SET ft_rsnxe_used 1") < 0) {
Jouni Malinen6250cb02020-04-15 13:54:45 +030014006 send_resp(dut, conn, SIGMA_ERROR,
14007 "errorCode,Failed to set ft_rsnxe_used");
14008 return STATUS_SENT_ERROR;
14009 }
14010 return SUCCESS_SEND_STATUS;
14011 }
Vamsi Krishnad29bc762020-05-08 23:23:30 +053014012
14013 oci_chan = get_param(cmd, "OCIChannel");
14014 oci_frametype = get_param(cmd, "OCIFrameType");
14015 if (oci_chan && oci_frametype) {
14016 unsigned int oci_freq = channel_to_freq(dut, atoi(oci_chan));
14017 char buf[100];
14018
14019 if (!oci_freq) {
14020 send_resp(dut, conn, SIGMA_ERROR,
14021 "errorCode,Invalid OCIChannel number");
14022 return STATUS_SENT_ERROR;
14023 }
14024
Veerendranath Jakkam76a845c2020-07-14 13:19:40 +053014025 if (wifi_chip_type == DRIVER_WCN &&
14026 (strcasecmp(oci_frametype, "SAQueryReq") == 0 ||
14027 strcasecmp(oci_frametype, "SAQueryResp") == 0 ||
14028 strcasecmp(oci_frametype, "Reassocreq") == 0)) {
14029 if (wcn_sta_override_oci(dut, intf, oci_frametype,
14030 oci_freq)) {
14031 send_resp(dut, conn, SIGMA_ERROR,
14032 "errorCode,Failed to override OCI");
14033 return STATUS_SENT_ERROR;
14034 }
14035 return SUCCESS_SEND_STATUS;
14036 }
14037
Vamsi Krishnad29bc762020-05-08 23:23:30 +053014038 if (strcasecmp(oci_frametype, "eapolM2") == 0) {
14039 snprintf(buf, sizeof(buf),
14040 "SET oci_freq_override_eapol %d", oci_freq);
14041 } else if (strcasecmp(oci_frametype, "SAQueryReq") == 0) {
14042 snprintf(buf, sizeof(buf),
14043 "SET oci_freq_override_saquery_req %d",
14044 oci_freq);
14045 } else if (strcasecmp(oci_frametype, "SAQueryResp") == 0) {
14046 snprintf(buf, sizeof(buf),
14047 "SET oci_freq_override_saquery_resp %d",
14048 oci_freq);
Veerendranath Jakkam76a845c2020-07-14 13:19:40 +053014049 } else if (strcasecmp(oci_frametype, "GrpKeyM2") == 0) {
14050 snprintf(buf, sizeof(buf),
14051 "SET oci_freq_override_eapol_g2 %d",
14052 oci_freq);
14053 } else if (strcasecmp(oci_frametype, "Reassocreq") == 0) {
14054 snprintf(buf, sizeof(buf),
14055 "SET oci_freq_override_ft_assoc %d",
14056 oci_freq);
Vamsi Krishnad29bc762020-05-08 23:23:30 +053014057 } else {
14058 send_resp(dut, conn, SIGMA_ERROR,
14059 "errorCode,Unsupported OCIFrameType");
14060 return STATUS_SENT_ERROR;
14061 }
14062 if (wpa_command(intf, buf) < 0) {
14063 send_resp(dut, conn, SIGMA_ERROR,
14064 "errorCode,Failed to set oci_freq_override");
14065 return STATUS_SENT_ERROR;
14066 }
14067 return SUCCESS_SEND_STATUS;
14068 }
14069
Veerendranath Jakkam50d5c782020-07-22 01:59:01 +053014070 val = get_param(cmd, "IgnoreCSA");
14071 if (val && atoi(val) == 1) {
14072 if (wifi_chip_type == DRIVER_WCN) {
14073 if (wcn_sta_ignore_csa(dut, intf, 1)) {
14074 send_resp(dut, conn, SIGMA_ERROR,
14075 "errorCode,Failed to set ignore CSA");
14076 return STATUS_SENT_ERROR;
14077 }
14078 return SUCCESS_SEND_STATUS;
14079 }
14080 }
14081
Veerendranath Jakkam1e1e5fd2020-09-10 07:12:37 +053014082 val = get_param(cmd, "Deauth_Per_SAQueryResp");
14083 if (val && atoi(val) == 0) {
14084 if (wifi_chip_type == DRIVER_WCN) {
14085 if (wcn_sta_ignore_sa_query_timeout(dut, intf, 1)) {
14086 send_resp(dut, conn, SIGMA_ERROR,
14087 "errorCode,Failed to set ignore SA Query timeout");
14088 return STATUS_SENT_ERROR;
14089 }
14090 return SUCCESS_SEND_STATUS;
14091 }
14092 }
14093
Jouni Malinen6250cb02020-04-15 13:54:45 +030014094 send_resp(dut, conn, SIGMA_ERROR,
14095 "errorCode,Unsupported WPA3 rfeature");
14096 return STATUS_SENT_ERROR;
14097}
14098
14099
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053014100static enum sigma_cmd_result
14101cmd_sta_set_rfeature_qm(const char *intf, struct sigma_dut *dut,
14102 struct sigma_conn *conn, struct sigma_cmd *cmd)
14103{
14104 const char *val;
14105
14106 val = get_param(cmd, "DomainName_Domain");
14107 if (val) {
14108 if (strlen(val) >= sizeof(dut->qm_domain_name))
14109 return ERROR_SEND_STATUS;
14110
14111 strlcpy(dut->qm_domain_name, val, sizeof(dut->qm_domain_name));
14112 return SUCCESS_SEND_STATUS;
14113 }
14114
14115 send_resp(dut, conn, SIGMA_ERROR,
14116 "errorCode,Unsupported QM rfeature");
14117 return STATUS_SENT_ERROR;
14118}
14119
14120
Jouni Malinenf7222712019-06-13 01:50:21 +030014121static enum sigma_cmd_result cmd_sta_set_rfeature(struct sigma_dut *dut,
14122 struct sigma_conn *conn,
14123 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014124{
14125 const char *intf = get_param(cmd, "Interface");
14126 const char *prog = get_param(cmd, "Prog");
Ashwini Patil68d02cd2017-01-10 15:39:16 +053014127 const char *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014128
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053014129 if (!prog)
14130 prog = get_param(cmd, "Program");
14131
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014132 if (intf == NULL || prog == NULL)
14133 return -1;
14134
Ashwini Patil5acd7382017-04-13 15:55:04 +053014135 /* BSS Transition candidate list for BTM query */
14136 val = get_param(cmd, "Nebor_BSSID");
14137 if (val && btm_query_candidate_list(dut, conn, cmd) == 0)
14138 return 0;
14139
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014140 if (strcasecmp(prog, "TDLS") == 0)
14141 return cmd_sta_set_rfeature_tdls(intf, dut, conn, cmd);
14142
14143 if (strcasecmp(prog, "VHT") == 0)
14144 return cmd_sta_set_rfeature_vht(intf, dut, conn, cmd);
14145
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014146 if (strcasecmp(prog, "HE") == 0)
14147 return cmd_sta_set_rfeature_he(intf, dut, conn, cmd);
14148
Ashwini Patil68d02cd2017-01-10 15:39:16 +053014149 if (strcasecmp(prog, "MBO") == 0) {
14150 val = get_param(cmd, "Cellular_Data_Cap");
14151 if (val &&
14152 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
14153 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +053014154
14155 val = get_param(cmd, "Ch_Pref");
14156 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
14157 return 0;
14158
Ashwini Patil68d02cd2017-01-10 15:39:16 +053014159 return 1;
14160 }
14161
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020014162 if (strcasecmp(prog, "60GHz") == 0)
14163 return cmd_sta_set_rfeature_60g(intf, dut, conn, cmd);
14164
Jouni Malinen6250cb02020-04-15 13:54:45 +030014165 if (strcasecmp(prog, "WPA3") == 0)
14166 return cmd_sta_set_rfeature_wpa3(intf, dut, conn, cmd);
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053014167 if (strcasecmp(prog, "QM") == 0)
14168 return cmd_sta_set_rfeature_qm(intf, dut, conn, cmd);
Jouni Malinen6250cb02020-04-15 13:54:45 +030014169
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014170 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported Prog");
14171 return 0;
14172}
14173
14174
Jouni Malinenf7222712019-06-13 01:50:21 +030014175static enum sigma_cmd_result cmd_sta_set_radio(struct sigma_dut *dut,
14176 struct sigma_conn *conn,
14177 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014178{
14179 const char *intf = get_param(cmd, "Interface");
14180 const char *mode = get_param(cmd, "Mode");
14181 int res;
14182
14183 if (intf == NULL || mode == NULL)
14184 return -1;
14185
14186 if (strcasecmp(mode, "On") == 0)
14187 res = wpa_command(intf, "SET radio_disabled 0");
14188 else if (strcasecmp(mode, "Off") == 0)
14189 res = wpa_command(intf, "SET radio_disabled 1");
14190 else
14191 return -1;
14192
14193 if (res) {
14194 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
14195 "radio mode");
14196 return 0;
14197 }
14198
14199 return 1;
14200}
14201
14202
Jouni Malinenf7222712019-06-13 01:50:21 +030014203static enum sigma_cmd_result cmd_sta_set_pwrsave(struct sigma_dut *dut,
14204 struct sigma_conn *conn,
14205 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014206{
14207 const char *intf = get_param(cmd, "Interface");
14208 const char *mode = get_param(cmd, "Mode");
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020014209 const char *prog = get_param(cmd, "program");
14210 const char *powersave = get_param(cmd, "powersave");
14211 int res = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014212
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020014213 if (intf == NULL)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014214 return -1;
14215
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020014216 if (prog && strcasecmp(prog, "60GHz") == 0) {
14217 /*
14218 * The CAPI mode parameter does not exist in 60G
14219 * unscheduled PS.
14220 */
Hu Wang5dc3ff12019-06-14 15:14:26 +080014221 if (powersave && strcasecmp(powersave, "unscheduled") == 0)
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020014222 res = set_ps(intf, dut, 1);
Jouni Malinen016ae6c2019-11-04 17:00:01 +020014223 } else if (prog && get_driver_type(dut) == DRIVER_WCN &&
Alexei Avshalom Lazar2f6fdb42019-02-04 14:16:08 +020014224 strcasecmp(prog, "HE") == 0) {
14225 return cmd_sta_set_power_save_he(intf, dut, conn, cmd);
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020014226 } else {
14227 if (mode == NULL)
14228 return -1;
14229
14230 if (strcasecmp(mode, "On") == 0)
14231 res = set_ps(intf, dut, 1);
14232 else if (strcasecmp(mode, "Off") == 0)
14233 res = set_ps(intf, dut, 0);
14234 else
14235 return -1;
14236 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014237
14238 if (res) {
14239 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
14240 "power save mode");
14241 return 0;
14242 }
14243
14244 return 1;
14245}
14246
14247
Jouni Malinenf7222712019-06-13 01:50:21 +030014248static enum sigma_cmd_result cmd_sta_bssid_pool(struct sigma_dut *dut,
14249 struct sigma_conn *conn,
14250 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014251{
14252 const char *intf = get_param(cmd, "Interface");
14253 const char *val, *bssid;
14254 int res;
14255 char *buf;
14256 size_t buf_len;
14257
14258 val = get_param(cmd, "BSSID_FILTER");
14259 if (val == NULL)
14260 return -1;
14261
14262 bssid = get_param(cmd, "BSSID_List");
14263 if (atoi(val) == 0 || bssid == NULL) {
14264 /* Disable BSSID filter */
14265 if (wpa_command(intf, "SET bssid_filter ")) {
14266 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed "
14267 "to disable BSSID filter");
14268 return 0;
14269 }
14270
14271 return 1;
14272 }
14273
14274 buf_len = 100 + strlen(bssid);
14275 buf = malloc(buf_len);
14276 if (buf == NULL)
14277 return -1;
14278
14279 snprintf(buf, buf_len, "SET bssid_filter %s", bssid);
14280 res = wpa_command(intf, buf);
14281 free(buf);
14282 if (res) {
14283 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to enable "
14284 "BSSID filter");
14285 return 0;
14286 }
14287
14288 return 1;
14289}
14290
14291
Jouni Malinenf7222712019-06-13 01:50:21 +030014292static enum sigma_cmd_result cmd_sta_reset_parm(struct sigma_dut *dut,
14293 struct sigma_conn *conn,
14294 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014295{
14296 const char *intf = get_param(cmd, "Interface");
14297 const char *val;
14298
14299 /* TODO: ARP */
14300
14301 val = get_param(cmd, "HS2_CACHE_PROFILE");
14302 if (val && strcasecmp(val, "All") == 0)
14303 hs2_clear_credentials(intf);
14304
14305 return 1;
14306}
14307
14308
Jouni Malinenf7222712019-06-13 01:50:21 +030014309static enum sigma_cmd_result cmd_sta_get_key(struct sigma_dut *dut,
14310 struct sigma_conn *conn,
14311 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014312{
14313 const char *intf = get_param(cmd, "Interface");
14314 const char *key_type = get_param(cmd, "KeyType");
14315 char buf[100], resp[200];
14316
14317 if (key_type == NULL)
14318 return -1;
14319
14320 if (strcasecmp(key_type, "GTK") == 0) {
14321 if (wpa_command_resp(intf, "GET gtk", buf, sizeof(buf)) < 0 ||
14322 strncmp(buf, "FAIL", 4) == 0) {
14323 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
14324 "not fetch current GTK");
14325 return 0;
14326 }
14327 snprintf(resp, sizeof(resp), "KeyValue,%s", buf);
14328 send_resp(dut, conn, SIGMA_COMPLETE, resp);
14329 return 0;
14330 } else {
14331 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
14332 "KeyType");
14333 return 0;
14334 }
14335
14336 return 1;
14337}
14338
14339
14340static int hs2_set_policy(struct sigma_dut *dut)
14341{
14342#ifdef ANDROID
14343 system("ip rule del prio 23000");
14344 if (system("ip rule add from all lookup main prio 23000") != 0) {
14345 sigma_dut_print(dut, DUT_MSG_ERROR,
14346 "Failed to run:ip rule add from all lookup main prio");
14347 return -1;
14348 }
14349 if (system("ip route flush cache") != 0) {
14350 sigma_dut_print(dut, DUT_MSG_ERROR,
14351 "Failed to run ip route flush cache");
14352 return -1;
14353 }
14354 return 1;
14355#else /* ANDROID */
14356 return 0;
14357#endif /* ANDROID */
14358}
14359
14360
Jouni Malinenf7222712019-06-13 01:50:21 +030014361static enum sigma_cmd_result cmd_sta_hs2_associate(struct sigma_dut *dut,
14362 struct sigma_conn *conn,
14363 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014364{
14365 const char *intf = get_param(cmd, "Interface");
14366 const char *val = get_param(cmd, "Ignore_blacklist");
Jouni Malinen439352d2018-09-13 03:42:23 +030014367 const char *band = get_param(cmd, "Band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014368 struct wpa_ctrl *ctrl;
Jouni Malinen3aa72862019-05-29 23:14:51 +030014369 int res, r;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014370 char bssid[20], ssid[40], resp[100], buf[100], blacklisted[100];
14371 int tries = 0;
14372 int ignore_blacklist = 0;
14373 const char *events[] = {
14374 "CTRL-EVENT-CONNECTED",
14375 "INTERWORKING-BLACKLISTED",
14376 "INTERWORKING-NO-MATCH",
14377 NULL
14378 };
14379
14380 start_sta_mode(dut);
14381
Jouni Malinen439352d2018-09-13 03:42:23 +030014382 if (band) {
14383 if (strcmp(band, "2.4") == 0) {
14384 wpa_command(intf, "SET setband 2G");
14385 } else if (strcmp(band, "5") == 0) {
14386 wpa_command(intf, "SET setband 5G");
14387 } else {
14388 send_resp(dut, conn, SIGMA_ERROR,
14389 "errorCode,Unsupported band");
14390 return 0;
14391 }
14392 }
14393
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014394 blacklisted[0] = '\0';
14395 if (val && atoi(val))
14396 ignore_blacklist = 1;
14397
14398try_again:
14399 ctrl = open_wpa_mon(intf);
14400 if (ctrl == NULL) {
14401 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
14402 "wpa_supplicant monitor connection");
14403 return -2;
14404 }
14405
14406 tries++;
14407 if (wpa_command(intf, "INTERWORKING_SELECT auto")) {
14408 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start "
14409 "Interworking connection");
14410 wpa_ctrl_detach(ctrl);
14411 wpa_ctrl_close(ctrl);
14412 return 0;
14413 }
14414
14415 buf[0] = '\0';
14416 while (1) {
14417 char *pos;
14418 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
14419 pos = strstr(buf, "INTERWORKING-BLACKLISTED");
14420 if (!pos)
14421 break;
14422 pos += 25;
14423 sigma_dut_print(dut, DUT_MSG_DEBUG, "Found blacklisted AP: %s",
14424 pos);
14425 if (!blacklisted[0])
14426 memcpy(blacklisted, pos, strlen(pos) + 1);
14427 }
14428
14429 if (ignore_blacklist && blacklisted[0]) {
14430 char *end;
14431 end = strchr(blacklisted, ' ');
14432 if (end)
14433 *end = '\0';
14434 sigma_dut_print(dut, DUT_MSG_DEBUG, "Try to connect to a blacklisted network: %s",
14435 blacklisted);
Jouni Malinen3aa72862019-05-29 23:14:51 +030014436 r = snprintf(buf, sizeof(buf), "INTERWORKING_CONNECT %s",
14437 blacklisted);
14438 if (r < 0 || r >= sizeof(buf) || wpa_command(intf, buf)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014439 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start Interworking connection to blacklisted network");
14440 wpa_ctrl_detach(ctrl);
14441 wpa_ctrl_close(ctrl);
14442 return 0;
14443 }
14444 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
14445 buf, sizeof(buf));
14446 }
14447
14448 wpa_ctrl_detach(ctrl);
14449 wpa_ctrl_close(ctrl);
14450
14451 if (res < 0) {
14452 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
14453 "connect");
14454 return 0;
14455 }
14456
14457 if (strstr(buf, "INTERWORKING-NO-MATCH") ||
14458 strstr(buf, "INTERWORKING-BLACKLISTED")) {
14459 if (tries < 2) {
14460 sigma_dut_print(dut, DUT_MSG_INFO, "No match found - try again to verify no APs were missed in the scan");
14461 goto try_again;
14462 }
14463 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,No network with "
14464 "matching credentials found");
14465 return 0;
14466 }
14467
14468 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
14469 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
14470 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
14471 "get current BSSID/SSID");
14472 return 0;
14473 }
14474
14475 snprintf(resp, sizeof(resp), "SSID,%s,BSSID,%s", ssid, bssid);
14476 send_resp(dut, conn, SIGMA_COMPLETE, resp);
14477 hs2_set_policy(dut);
14478 return 0;
14479}
14480
14481
Jouni Malinenf7222712019-06-13 01:50:21 +030014482static enum sigma_cmd_result cmd_sta_hs2_venue_info(struct sigma_dut *dut,
14483 struct sigma_conn *conn,
14484 struct sigma_cmd *cmd)
Jouni Malinenb639f1c2018-09-13 02:39:46 +030014485{
14486 const char *intf = get_param(cmd, "Interface");
14487 const char *display = get_param(cmd, "Display");
14488 struct wpa_ctrl *ctrl;
14489 char buf[300], params[400], *pos;
14490 char bssid[20];
14491 int info_avail = 0;
14492 unsigned int old_timeout;
14493 int res;
14494
14495 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0) {
14496 send_resp(dut, conn, SIGMA_ERROR,
14497 "ErrorCode,Could not get current BSSID");
14498 return 0;
14499 }
14500 ctrl = open_wpa_mon(intf);
14501 if (!ctrl) {
14502 sigma_dut_print(dut, DUT_MSG_ERROR,
14503 "Failed to open wpa_supplicant monitor connection");
14504 return -2;
14505 }
14506
14507 snprintf(buf, sizeof(buf), "ANQP_GET %s 277", bssid);
14508 wpa_command(intf, buf);
14509
14510 res = get_wpa_cli_event(dut, ctrl, "GAS-QUERY-DONE", buf, sizeof(buf));
14511 if (res < 0) {
14512 send_resp(dut, conn, SIGMA_ERROR,
14513 "ErrorCode,Could not complete GAS query");
14514 goto fail;
14515 }
14516
14517 old_timeout = dut->default_timeout;
14518 dut->default_timeout = 2;
14519 res = get_wpa_cli_event(dut, ctrl, "RX-VENUE-URL", buf, sizeof(buf));
14520 dut->default_timeout = old_timeout;
14521 if (res < 0)
14522 goto done;
14523 pos = strchr(buf, ' ');
14524 if (!pos)
14525 goto done;
14526 pos++;
14527 pos = strchr(pos, ' ');
14528 if (!pos)
14529 goto done;
14530 pos++;
14531 info_avail = 1;
14532 snprintf(params, sizeof(params), "browser %s", pos);
14533
14534 if (display && strcasecmp(display, "Yes") == 0) {
14535 pid_t pid;
14536
14537 pid = fork();
14538 if (pid < 0) {
14539 perror("fork");
14540 return -1;
14541 }
14542
14543 if (pid == 0) {
14544 run_hs20_osu(dut, params);
14545 exit(0);
14546 }
14547 }
14548
14549done:
14550 snprintf(buf, sizeof(buf), "Info_available,%s",
14551 info_avail ? "Yes" : "No");
14552 send_resp(dut, conn, SIGMA_COMPLETE, buf);
14553fail:
14554 wpa_ctrl_detach(ctrl);
14555 wpa_ctrl_close(ctrl);
14556 return 0;
14557}
14558
14559
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014560static int sta_add_credential_uname_pwd(struct sigma_dut *dut,
14561 struct sigma_conn *conn,
14562 const char *ifname,
14563 struct sigma_cmd *cmd)
14564{
14565 const char *val;
14566 int id;
14567
14568 id = add_cred(ifname);
14569 if (id < 0)
14570 return -2;
14571 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
14572
14573 val = get_param(cmd, "prefer");
14574 if (val && atoi(val) > 0)
14575 set_cred(ifname, id, "priority", "1");
14576
14577 val = get_param(cmd, "REALM");
14578 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
14579 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
14580 "realm");
14581 return 0;
14582 }
14583
14584 val = get_param(cmd, "HOME_FQDN");
14585 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
14586 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
14587 "home_fqdn");
14588 return 0;
14589 }
14590
14591 val = get_param(cmd, "Username");
14592 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
14593 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
14594 "username");
14595 return 0;
14596 }
14597
14598 val = get_param(cmd, "Password");
14599 if (val && set_cred_quoted(ifname, id, "password", val) < 0) {
14600 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
14601 "password");
14602 return 0;
14603 }
14604
14605 val = get_param(cmd, "ROOT_CA");
14606 if (val) {
14607 char fname[200];
14608 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
14609#ifdef __linux__
14610 if (!file_exists(fname)) {
14611 char msg[300];
14612 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
14613 "file (%s) not found", fname);
14614 send_resp(dut, conn, SIGMA_ERROR, msg);
14615 return 0;
14616 }
14617#endif /* __linux__ */
14618 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
14619 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
14620 "not set root CA");
14621 return 0;
14622 }
14623 }
14624
14625 return 1;
14626}
14627
14628
14629static int update_devdetail_imsi(struct sigma_dut *dut, const char *imsi)
14630{
14631 FILE *in, *out;
14632 char buf[500];
14633 int found = 0;
14634
14635 in = fopen("devdetail.xml", "r");
14636 if (in == NULL)
14637 return -1;
14638 out = fopen("devdetail.xml.tmp", "w");
14639 if (out == NULL) {
14640 fclose(in);
14641 return -1;
14642 }
14643
14644 while (fgets(buf, sizeof(buf), in)) {
14645 char *pos = strstr(buf, "<IMSI>");
14646 if (pos) {
14647 sigma_dut_print(dut, DUT_MSG_INFO, "Updated DevDetail IMSI to %s",
14648 imsi);
14649 pos += 6;
14650 *pos = '\0';
14651 fprintf(out, "%s%s</IMSI>\n", buf, imsi);
14652 found++;
14653 } else {
14654 fprintf(out, "%s", buf);
14655 }
14656 }
14657
14658 fclose(out);
14659 fclose(in);
14660 if (found)
14661 rename("devdetail.xml.tmp", "devdetail.xml");
14662 else
14663 unlink("devdetail.xml.tmp");
14664
14665 return 0;
14666}
14667
14668
14669static int sta_add_credential_sim(struct sigma_dut *dut,
14670 struct sigma_conn *conn,
14671 const char *ifname, struct sigma_cmd *cmd)
14672{
14673 const char *val, *imsi = NULL;
14674 int id;
14675 char buf[200];
14676 int res;
14677 const char *pos;
14678 size_t mnc_len;
14679 char plmn_mcc[4];
14680 char plmn_mnc[4];
14681
14682 id = add_cred(ifname);
14683 if (id < 0)
14684 return -2;
14685 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
14686
14687 val = get_param(cmd, "prefer");
14688 if (val && atoi(val) > 0)
14689 set_cred(ifname, id, "priority", "1");
14690
14691 val = get_param(cmd, "PLMN_MCC");
14692 if (val == NULL) {
14693 send_resp(dut, conn, SIGMA_ERROR,
14694 "errorCode,Missing PLMN_MCC");
14695 return 0;
14696 }
14697 if (strlen(val) != 3) {
14698 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MCC");
14699 return 0;
14700 }
14701 snprintf(plmn_mcc, sizeof(plmn_mcc), "%s", val);
14702
14703 val = get_param(cmd, "PLMN_MNC");
14704 if (val == NULL) {
14705 send_resp(dut, conn, SIGMA_ERROR,
14706 "errorCode,Missing PLMN_MNC");
14707 return 0;
14708 }
14709 if (strlen(val) != 2 && strlen(val) != 3) {
14710 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MNC");
14711 return 0;
14712 }
14713 snprintf(plmn_mnc, sizeof(plmn_mnc), "%s", val);
14714
14715 val = get_param(cmd, "IMSI");
14716 if (val == NULL) {
14717 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing SIM "
14718 "IMSI");
14719 return 0;
14720 }
14721
14722 imsi = pos = val;
14723
14724 if (strncmp(plmn_mcc, pos, 3) != 0) {
14725 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MCC mismatch");
14726 return 0;
14727 }
14728 pos += 3;
14729
14730 mnc_len = strlen(plmn_mnc);
14731 if (mnc_len < 2) {
14732 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC not set");
14733 return 0;
14734 }
14735
14736 if (strncmp(plmn_mnc, pos, mnc_len) != 0) {
14737 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC mismatch");
14738 return 0;
14739 }
14740 pos += mnc_len;
14741
14742 res = snprintf(buf, sizeof(buf), "%s%s-%s",plmn_mcc, plmn_mnc, pos);
14743 if (res < 0 || res >= (int) sizeof(buf))
14744 return -1;
14745 if (set_cred_quoted(ifname, id, "imsi", buf) < 0) {
14746 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
14747 "not set IMSI");
14748 return 0;
14749 }
14750
14751 val = get_param(cmd, "Password");
14752 if (val && set_cred_quoted(ifname, id, "milenage", val) < 0) {
14753 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
14754 "not set password");
14755 return 0;
14756 }
14757
Jouni Malinenba630452018-06-22 11:49:59 +030014758 if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014759 /*
14760 * Set provisioning_sp for the test cases where SIM/USIM
14761 * provisioning is used.
14762 */
14763 if (val && set_cred_quoted(ifname, id, "provisioning_sp",
14764 "wi-fi.org") < 0) {
14765 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
14766 "not set provisioning_sp");
14767 return 0;
14768 }
14769
14770 update_devdetail_imsi(dut, imsi);
14771 }
14772
14773 return 1;
14774}
14775
14776
14777static int sta_add_credential_cert(struct sigma_dut *dut,
14778 struct sigma_conn *conn,
14779 const char *ifname,
14780 struct sigma_cmd *cmd)
14781{
14782 const char *val;
14783 int id;
14784
14785 id = add_cred(ifname);
14786 if (id < 0)
14787 return -2;
14788 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
14789
14790 val = get_param(cmd, "prefer");
14791 if (val && atoi(val) > 0)
14792 set_cred(ifname, id, "priority", "1");
14793
14794 val = get_param(cmd, "REALM");
14795 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
14796 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
14797 "realm");
14798 return 0;
14799 }
14800
14801 val = get_param(cmd, "HOME_FQDN");
14802 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
14803 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
14804 "home_fqdn");
14805 return 0;
14806 }
14807
14808 val = get_param(cmd, "Username");
14809 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
14810 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
14811 "username");
14812 return 0;
14813 }
14814
14815 val = get_param(cmd, "clientCertificate");
14816 if (val) {
14817 char fname[200];
14818 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
14819#ifdef __linux__
14820 if (!file_exists(fname)) {
14821 char msg[300];
14822 snprintf(msg, sizeof(msg),
14823 "ErrorCode,clientCertificate "
14824 "file (%s) not found", fname);
14825 send_resp(dut, conn, SIGMA_ERROR, msg);
14826 return 0;
14827 }
14828#endif /* __linux__ */
14829 if (set_cred_quoted(ifname, id, "client_cert", fname) < 0) {
14830 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
14831 "not set client_cert");
14832 return 0;
14833 }
14834 if (set_cred_quoted(ifname, id, "private_key", fname) < 0) {
14835 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
14836 "not set private_key");
14837 return 0;
14838 }
14839 }
14840
14841 val = get_param(cmd, "ROOT_CA");
14842 if (val) {
14843 char fname[200];
14844 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
14845#ifdef __linux__
14846 if (!file_exists(fname)) {
14847 char msg[300];
14848 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
14849 "file (%s) not found", fname);
14850 send_resp(dut, conn, SIGMA_ERROR, msg);
14851 return 0;
14852 }
14853#endif /* __linux__ */
14854 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
14855 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
14856 "not set root CA");
14857 return 0;
14858 }
14859 }
14860
14861 return 1;
14862}
14863
14864
Jouni Malinenf7222712019-06-13 01:50:21 +030014865static enum sigma_cmd_result cmd_sta_add_credential(struct sigma_dut *dut,
14866 struct sigma_conn *conn,
14867 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014868{
14869 const char *intf = get_param(cmd, "Interface");
14870 const char *type;
14871
14872 start_sta_mode(dut);
14873
14874 type = get_param(cmd, "Type");
14875 if (!type)
14876 return -1;
14877
14878 if (strcasecmp(type, "uname_pwd") == 0)
14879 return sta_add_credential_uname_pwd(dut, conn, intf, cmd);
14880
14881 if (strcasecmp(type, "sim") == 0)
14882 return sta_add_credential_sim(dut, conn, intf, cmd);
14883
14884 if (strcasecmp(type, "cert") == 0)
14885 return sta_add_credential_cert(dut, conn, intf, cmd);
14886
14887 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported credential "
14888 "type");
14889 return 0;
14890}
14891
14892
Jouni Malinenf7222712019-06-13 01:50:21 +030014893static enum sigma_cmd_result cmd_sta_scan(struct sigma_dut *dut,
14894 struct sigma_conn *conn,
14895 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014896{
14897 const char *intf = get_param(cmd, "Interface");
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080014898 const char *val, *bssid, *ssid, *scan_freq, *short_ssid;
Veerendranathdc581b52020-08-10 03:29:08 -070014899 char buf[4096], scan_res[20];
vamsi krishna89ad8c62017-09-19 12:51:18 +053014900 char ssid_hex[65];
Kiran Kumar Lokere3399af22020-03-04 16:31:56 -080014901 int wildcard_ssid = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014902 int res;
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080014903 enum sigma_cmd_result status;
Jouni Malinen228a2fc2020-06-22 23:37:45 +030014904 struct wpa_ctrl *ctrl = NULL;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014905
Jouni Malinen8c1abeb2019-11-06 18:48:34 +020014906 start_sta_mode(dut);
14907
Arif Hussain66a4af02019-02-07 15:04:51 -080014908 val = get_param(cmd, "GetParameter");
14909 if (val && strcmp(val, "SSID_BSSID") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020014910 if (get_wpa_ssid_bssid(dut, get_station_ifname(dut),
Arif Hussain66a4af02019-02-07 15:04:51 -080014911 buf, sizeof(buf)) < 0) {
14912 sigma_dut_print(dut, DUT_MSG_ERROR,
14913 "Could not get ssid bssid");
14914 return ERROR_SEND_STATUS;
14915 }
14916
14917 sigma_dut_print(dut, DUT_MSG_INFO, "%s", buf);
14918 send_resp(dut, conn, SIGMA_COMPLETE, buf);
14919 return STATUS_SENT;
14920 }
14921
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014922 val = get_param(cmd, "HESSID");
14923 if (val) {
14924 res = snprintf(buf, sizeof(buf), "SET hessid %s", val);
14925 if (res < 0 || res >= (int) sizeof(buf))
14926 return -1;
14927 wpa_command(intf, buf);
14928 }
14929
14930 val = get_param(cmd, "ACCS_NET_TYPE");
14931 if (val) {
14932 res = snprintf(buf, sizeof(buf), "SET access_network_type %s",
14933 val);
14934 if (res < 0 || res >= (int) sizeof(buf))
14935 return -1;
14936 wpa_command(intf, buf);
14937 }
14938
Kiran Kumar Lokere69d89952021-08-08 23:41:46 -070014939 if (get_param(cmd, "RxMac"))
14940 sta_set_scan_unicast_probe(dut, intf, 1);
14941
vamsi krishna89ad8c62017-09-19 12:51:18 +053014942 bssid = get_param(cmd, "Bssid");
14943 ssid = get_param(cmd, "Ssid");
Kiran Kumar Lokere69d89952021-08-08 23:41:46 -070014944 if (!bssid)
14945 bssid = get_param(cmd, "RxMac");
vamsi krishna89ad8c62017-09-19 12:51:18 +053014946
Kiran Kumar Lokere3399af22020-03-04 16:31:56 -080014947 if (ssid && strcasecmp(ssid, "ZeroLength") == 0 &&
14948 dut->device_type == STA_testbed) {
14949 ssid = NULL;
14950 wildcard_ssid = 1;
14951 }
14952
vamsi krishna89ad8c62017-09-19 12:51:18 +053014953 if (ssid) {
14954 if (2 * strlen(ssid) >= sizeof(ssid_hex)) {
14955 send_resp(dut, conn, SIGMA_ERROR,
14956 "ErrorCode,Too long SSID");
14957 return 0;
14958 }
14959 ascii2hexstr(ssid, ssid_hex);
14960 }
14961
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080014962 short_ssid = get_param(cmd, "ShortSSID");
14963 if (short_ssid) {
14964 uint32_t short_ssid_hex;
14965
14966 short_ssid_hex = strtoul(short_ssid, NULL, 16);
14967 short_ssid_hex = ((short_ssid_hex & 0xFF) << 24) |
14968 (((short_ssid_hex >> 8) & 0xFF) << 16) |
14969 (((short_ssid_hex >> 16) & 0xFF) << 8) |
14970 ((short_ssid_hex >> 24) & 0xFF);
14971
14972 res = snprintf(buf, sizeof(buf),
14973 "VENDOR_ELEM_ADD 14 ff053a%08x",
14974 short_ssid_hex);
14975 if (res < 0 || res >= (int) sizeof(buf) ||
14976 wpa_command(intf, buf)) {
14977 send_resp(dut, conn, SIGMA_ERROR,
14978 "errorCode,Failed to add short SSID");
14979 return STATUS_SENT_ERROR;
14980 }
14981 }
14982
Kiran Kumar Lokerec0deb482020-03-04 16:35:06 -080014983 scan_freq = get_param(cmd, "ChnlFreq");
Veerendranath Jakkam132c4b42020-08-10 00:29:03 +053014984 if (scan_freq) {
14985 if (strcasecmp(scan_freq, "2G") == 0)
14986 scan_freq = "2412-2462";
14987 else if (strcasecmp(scan_freq, "5G") == 0)
14988 scan_freq = "5180-5925";
14989 }
Kiran Kumar Lokerec0deb482020-03-04 16:35:06 -080014990
Jouni Malinen228a2fc2020-06-22 23:37:45 +030014991 val = get_param(cmd, "WaitCompletion");
14992 if (val && atoi(val) == 1) {
14993 ctrl = open_wpa_mon(intf);
14994 if (!ctrl) {
14995 send_resp(dut, conn, SIGMA_ERROR,
14996 "errorCode,Failed to open monitor socket");
14997 return STATUS_SENT_ERROR;
14998 }
14999 }
15000
Kiran Kumar Lokerec0deb482020-03-04 16:35:06 -080015001 res = snprintf(buf, sizeof(buf), "SCAN%s%s%s%s%s%s%s",
vamsi krishna89ad8c62017-09-19 12:51:18 +053015002 bssid ? " bssid=": "",
15003 bssid ? bssid : "",
15004 ssid ? " ssid " : "",
Kiran Kumar Lokere3399af22020-03-04 16:31:56 -080015005 ssid ? ssid_hex : "",
Kiran Kumar Lokerec0deb482020-03-04 16:35:06 -080015006 wildcard_ssid ? " wildcard_ssid=1" : "",
15007 scan_freq ? " freq=" : "",
15008 scan_freq ? scan_freq : "");
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080015009 if (res < 0 || res >= (int) sizeof(buf)) {
15010 send_resp(dut, conn, SIGMA_ERROR,
15011 "errorCode,Could not build scan command");
15012 status = STATUS_SENT_ERROR;
15013 goto remove_s_ssid;
15014 }
vamsi krishna89ad8c62017-09-19 12:51:18 +053015015
Veerendranathdc581b52020-08-10 03:29:08 -070015016 res = wpa_command_resp(intf, buf, scan_res, sizeof(scan_res));
15017 if (strncmp(scan_res, "FAIL-BUSY", 9) == 0) {
15018 sigma_dut_print(dut, DUT_MSG_DEBUG,
15019 "Scan request rejected with busy status, abort ongoing scan and try again");
15020 wpa_command(intf, "ABORT_SCAN");
15021 res = wpa_command(intf, buf);
15022 }
15023
15024 if (res < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015025 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not start "
15026 "scan");
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080015027 status = STATUS_SENT_ERROR;
15028 } else {
15029 status = SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015030 }
15031
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080015032remove_s_ssid:
15033 if (short_ssid && wpa_command(intf, "VENDOR_ELEM_REMOVE 14 *"))
15034 sigma_dut_print(dut, DUT_MSG_ERROR,
15035 "Failed to delete vendor element");
15036
Jouni Malinen228a2fc2020-06-22 23:37:45 +030015037 if (ctrl) {
15038 if (status == SUCCESS_SEND_STATUS) {
15039 res = get_wpa_cli_event(dut, ctrl,
15040 "CTRL-EVENT-SCAN-RESULTS",
15041 buf, sizeof(buf));
15042 if (res < 0) {
15043 send_resp(dut, conn, SIGMA_ERROR,
15044 "ErrorCode,scan did not complete");
15045 status = STATUS_SENT_ERROR;
15046 }
15047 }
15048
15049 wpa_ctrl_detach(ctrl);
15050 wpa_ctrl_close(ctrl);
15051 }
15052
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080015053 return status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015054}
15055
15056
Jouni Malinenf7222712019-06-13 01:50:21 +030015057static enum sigma_cmd_result cmd_sta_scan_bss(struct sigma_dut *dut,
15058 struct sigma_conn *conn,
15059 struct sigma_cmd *cmd)
Jouni Malinen5e5d43d2018-01-10 17:29:33 +020015060{
15061 const char *intf = get_param(cmd, "Interface");
15062 const char *bssid;
15063 char buf[4096], *pos;
15064 int freq, chan;
15065 char *ssid;
15066 char resp[100];
15067 int res;
15068 struct wpa_ctrl *ctrl;
15069
15070 bssid = get_param(cmd, "BSSID");
15071 if (!bssid) {
15072 send_resp(dut, conn, SIGMA_INVALID,
15073 "errorCode,BSSID argument is missing");
15074 return 0;
15075 }
15076
15077 ctrl = open_wpa_mon(intf);
15078 if (!ctrl) {
15079 sigma_dut_print(dut, DUT_MSG_ERROR,
15080 "Failed to open wpa_supplicant monitor connection");
15081 return -1;
15082 }
15083
15084 if (wpa_command(intf, "SCAN TYPE=ONLY")) {
15085 send_resp(dut, conn, SIGMA_ERROR,
15086 "errorCode,Could not start scan");
15087 wpa_ctrl_detach(ctrl);
15088 wpa_ctrl_close(ctrl);
15089 return 0;
15090 }
15091
15092 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
15093 buf, sizeof(buf));
15094
15095 wpa_ctrl_detach(ctrl);
15096 wpa_ctrl_close(ctrl);
15097
15098 if (res < 0) {
15099 send_resp(dut, conn, SIGMA_ERROR,
15100 "errorCode,Scan did not complete");
15101 return 0;
15102 }
15103
15104 snprintf(buf, sizeof(buf), "BSS %s", bssid);
15105 if (wpa_command_resp(intf, buf, buf, sizeof(buf)) < 0 ||
15106 strncmp(buf, "id=", 3) != 0) {
15107 send_resp(dut, conn, SIGMA_ERROR,
15108 "errorCode,Specified BSSID not found");
15109 return 0;
15110 }
15111
15112 pos = strstr(buf, "\nfreq=");
15113 if (!pos) {
15114 send_resp(dut, conn, SIGMA_ERROR,
15115 "errorCode,Channel not found");
15116 return 0;
15117 }
15118 freq = atoi(pos + 6);
15119 chan = freq_to_channel(freq);
15120
15121 pos = strstr(buf, "\nssid=");
15122 if (!pos) {
15123 send_resp(dut, conn, SIGMA_ERROR,
15124 "errorCode,SSID not found");
15125 return 0;
15126 }
15127 ssid = pos + 6;
15128 pos = strchr(ssid, '\n');
15129 if (pos)
15130 *pos = '\0';
15131 snprintf(resp, sizeof(resp), "ssid,%s,bsschannel,%d", ssid, chan);
15132 send_resp(dut, conn, SIGMA_COMPLETE, resp);
15133 return 0;
15134}
15135
15136
Jouni Malinenf7222712019-06-13 01:50:21 +030015137static enum sigma_cmd_result cmd_sta_set_systime(struct sigma_dut *dut,
15138 struct sigma_conn *conn,
15139 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015140{
15141#ifdef __linux__
15142 struct timeval tv;
15143 struct tm tm;
15144 time_t t;
15145 const char *val;
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +053015146 int v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015147
Jouni Malinen016ae6c2019-11-04 17:00:01 +020015148 wpa_command(get_station_ifname(dut), "PMKSA_FLUSH");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015149
15150 memset(&tm, 0, sizeof(tm));
15151 val = get_param(cmd, "seconds");
15152 if (val)
15153 tm.tm_sec = atoi(val);
15154 val = get_param(cmd, "minutes");
15155 if (val)
15156 tm.tm_min = atoi(val);
15157 val = get_param(cmd, "hours");
15158 if (val)
15159 tm.tm_hour = atoi(val);
15160 val = get_param(cmd, "date");
15161 if (val)
15162 tm.tm_mday = atoi(val);
15163 val = get_param(cmd, "month");
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +053015164 if (val) {
15165 v = atoi(val);
15166 if (v < 1 || v > 12) {
15167 send_resp(dut, conn, SIGMA_INVALID,
15168 "errorCode,Invalid month");
15169 return 0;
15170 }
15171 tm.tm_mon = v - 1;
15172 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015173 val = get_param(cmd, "year");
15174 if (val) {
15175 int year = atoi(val);
15176#ifdef ANDROID
15177 if (year > 2035)
15178 year = 2035; /* years beyond 2035 not supported */
15179#endif /* ANDROID */
15180 tm.tm_year = year - 1900;
15181 }
15182 t = mktime(&tm);
15183 if (t == (time_t) -1) {
15184 send_resp(dut, conn, SIGMA_ERROR,
15185 "errorCode,Invalid date or time");
15186 return 0;
15187 }
15188
15189 memset(&tv, 0, sizeof(tv));
15190 tv.tv_sec = t;
15191
15192 if (settimeofday(&tv, NULL) < 0) {
15193 sigma_dut_print(dut, DUT_MSG_INFO, "settimeofday failed: %s",
15194 strerror(errno));
15195 send_resp(dut, conn, SIGMA_ERROR,
15196 "errorCode,Failed to set time");
15197 return 0;
15198 }
15199
15200 return 1;
15201#endif /* __linux__ */
15202
15203 return -1;
15204}
15205
15206
Jouni Malinenf7222712019-06-13 01:50:21 +030015207static enum sigma_cmd_result cmd_sta_osu(struct sigma_dut *dut,
15208 struct sigma_conn *conn,
15209 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015210{
15211 const char *intf = get_param(cmd, "Interface");
Jouni Malinen4c8681c2018-09-12 23:28:11 +030015212 const char *name, *osu_ssid, *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015213 int prod_ess_assoc = 1;
Jouni Malinen4c8681c2018-09-12 23:28:11 +030015214 char buf[300], bssid[100], ssid[100];
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015215 int res;
15216 struct wpa_ctrl *ctrl;
15217
15218 name = get_param(cmd, "osuFriendlyName");
Jouni Malinen4c8681c2018-09-12 23:28:11 +030015219 osu_ssid = get_param(cmd, "osu_ssid");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015220
15221 val = get_param(cmd, "ProdESSAssoc");
15222 if (val)
15223 prod_ess_assoc = atoi(val);
15224
15225 kill_dhcp_client(dut, intf);
15226 if (start_dhcp_client(dut, intf) < 0)
15227 return -2;
15228
15229 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger OSU");
15230 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
15231 res = snprintf(buf, sizeof(buf),
Jouni Malinen4c8681c2018-09-12 23:28:11 +030015232 "%s %s%s%s %s%s%s signup osu-ca.pem",
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015233 prod_ess_assoc ? "" : "-N",
15234 name ? "-O'" : "", name ? name : "",
Jouni Malinen4c8681c2018-09-12 23:28:11 +030015235 name ? "'" : "",
15236 osu_ssid ? "-o'" : "", osu_ssid ? osu_ssid : "",
15237 osu_ssid ? "'" : "");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015238
Kanchanapally, Vidyullatha12b66762015-12-31 16:46:42 +053015239 hs2_set_policy(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015240 if (run_hs20_osu(dut, buf) < 0) {
15241 FILE *f;
15242
15243 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to complete OSU");
15244
15245 f = fopen("hs20-osu-client.res", "r");
15246 if (f) {
15247 char resp[400], res[300], *pos;
15248 if (!fgets(res, sizeof(res), f))
15249 res[0] = '\0';
15250 pos = strchr(res, '\n');
15251 if (pos)
15252 *pos = '\0';
15253 fclose(f);
15254 sigma_dut_summary(dut, "hs20-osu-client provisioning failed: %s",
15255 res);
15256 snprintf(resp, sizeof(resp), "notify-send '%s'", res);
15257 if (system(resp) != 0) {
15258 }
15259 snprintf(resp, sizeof(resp),
15260 "SSID,,BSSID,,failureReason,%s", res);
15261 send_resp(dut, conn, SIGMA_COMPLETE, resp);
15262 return 0;
15263 }
15264
15265 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
15266 return 0;
15267 }
15268
15269 if (!prod_ess_assoc)
15270 goto report;
15271
15272 ctrl = open_wpa_mon(intf);
15273 if (ctrl == NULL) {
15274 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
15275 "wpa_supplicant monitor connection");
15276 return -1;
15277 }
15278
15279 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
15280 buf, sizeof(buf));
15281
15282 wpa_ctrl_detach(ctrl);
15283 wpa_ctrl_close(ctrl);
15284
15285 if (res < 0) {
15286 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to connect to "
15287 "network after OSU");
15288 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
15289 return 0;
15290 }
15291
15292report:
15293 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
15294 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
15295 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to get BSSID/SSID");
15296 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
15297 return 0;
15298 }
15299
15300 snprintf(buf, sizeof(buf), "SSID,%s,BSSID,%s", ssid, bssid);
15301 send_resp(dut, conn, SIGMA_COMPLETE, buf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015302 return 0;
15303}
15304
15305
Jouni Malinenf7222712019-06-13 01:50:21 +030015306static enum sigma_cmd_result cmd_sta_policy_update(struct sigma_dut *dut,
15307 struct sigma_conn *conn,
15308 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015309{
15310 const char *val;
15311 int timeout = 120;
15312
15313 val = get_param(cmd, "PolicyUpdate");
15314 if (val == NULL || atoi(val) == 0)
15315 return 1; /* No operation requested */
15316
15317 val = get_param(cmd, "Timeout");
15318 if (val)
15319 timeout = atoi(val);
15320
15321 if (timeout) {
15322 /* TODO: time out the command and return
15323 * PolicyUpdateStatus,TIMEOUT if needed. */
15324 }
15325
15326 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger policy update");
15327 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
15328 if (run_hs20_osu(dut, "pol_upd fqdn=wi-fi.org") < 0) {
15329 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,FAIL");
15330 return 0;
15331 }
15332
15333 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,SUCCESS");
15334 return 0;
15335}
15336
15337
Jouni Malinenf7222712019-06-13 01:50:21 +030015338static enum sigma_cmd_result cmd_sta_er_config(struct sigma_dut *dut,
15339 struct sigma_conn *conn,
15340 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015341{
15342 struct wpa_ctrl *ctrl;
15343 const char *intf = get_param(cmd, "Interface");
15344 const char *bssid = get_param(cmd, "Bssid");
15345 const char *ssid = get_param(cmd, "SSID");
15346 const char *security = get_param(cmd, "Security");
15347 const char *passphrase = get_param(cmd, "Passphrase");
15348 const char *pin = get_param(cmd, "PIN");
15349 char buf[1000];
15350 char ssid_hex[200], passphrase_hex[200];
15351 const char *keymgmt, *cipher;
15352
15353 if (intf == NULL)
Jouni Malinen016ae6c2019-11-04 17:00:01 +020015354 intf = get_main_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015355
15356 if (!bssid) {
15357 send_resp(dut, conn, SIGMA_ERROR,
15358 "ErrorCode,Missing Bssid argument");
15359 return 0;
15360 }
15361
15362 if (!ssid) {
15363 send_resp(dut, conn, SIGMA_ERROR,
15364 "ErrorCode,Missing SSID argument");
15365 return 0;
15366 }
15367
15368 if (!security) {
15369 send_resp(dut, conn, SIGMA_ERROR,
15370 "ErrorCode,Missing Security argument");
15371 return 0;
15372 }
15373
15374 if (!passphrase) {
15375 send_resp(dut, conn, SIGMA_ERROR,
15376 "ErrorCode,Missing Passphrase argument");
15377 return 0;
15378 }
15379
15380 if (!pin) {
15381 send_resp(dut, conn, SIGMA_ERROR,
15382 "ErrorCode,Missing PIN argument");
15383 return 0;
15384 }
15385
vamsi krishna8c9c1562017-05-12 15:51:46 +053015386 if (2 * strlen(ssid) >= sizeof(ssid_hex) ||
15387 2 * strlen(passphrase) >= sizeof(passphrase_hex)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015388 send_resp(dut, conn, SIGMA_ERROR,
15389 "ErrorCode,Too long SSID/passphrase");
15390 return 0;
15391 }
15392
15393 ctrl = open_wpa_mon(intf);
15394 if (ctrl == NULL) {
15395 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
15396 "wpa_supplicant monitor connection");
15397 return -2;
15398 }
15399
15400 if (strcasecmp(security, "wpa2-psk") == 0) {
15401 keymgmt = "WPA2PSK";
15402 cipher = "CCMP";
15403 } else {
15404 wpa_ctrl_detach(ctrl);
15405 wpa_ctrl_close(ctrl);
15406 send_resp(dut, conn, SIGMA_ERROR,
15407 "ErrorCode,Unsupported Security value");
15408 return 0;
15409 }
15410
15411 ascii2hexstr(ssid, ssid_hex);
15412 ascii2hexstr(passphrase, passphrase_hex);
15413 snprintf(buf, sizeof(buf), "WPS_REG %s %s %s %s %s %s",
15414 bssid, pin, ssid_hex, keymgmt, cipher, passphrase_hex);
15415
15416 if (wpa_command(intf, buf) < 0) {
15417 wpa_ctrl_detach(ctrl);
15418 wpa_ctrl_close(ctrl);
15419 send_resp(dut, conn, SIGMA_ERROR,
15420 "ErrorCode,Failed to start registrar");
15421 return 0;
15422 }
15423
15424 snprintf(dut->er_oper_bssid, sizeof(dut->er_oper_bssid), "%s", bssid);
15425 dut->er_oper_performed = 1;
15426
15427 return wps_connection_event(dut, conn, ctrl, intf, 0);
15428}
15429
15430
Jouni Malinenf7222712019-06-13 01:50:21 +030015431static enum sigma_cmd_result
15432cmd_sta_wps_connect_pw_token(struct sigma_dut *dut, struct sigma_conn *conn,
15433 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015434{
15435 struct wpa_ctrl *ctrl;
15436 const char *intf = get_param(cmd, "Interface");
15437 const char *bssid = get_param(cmd, "Bssid");
15438 char buf[100];
15439
15440 if (!bssid) {
15441 send_resp(dut, conn, SIGMA_ERROR,
15442 "ErrorCode,Missing Bssid argument");
15443 return 0;
15444 }
15445
15446 ctrl = open_wpa_mon(intf);
15447 if (ctrl == NULL) {
15448 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
15449 "wpa_supplicant monitor connection");
15450 return -2;
15451 }
15452
15453 snprintf(buf, sizeof(buf), "WPS_NFC %s", bssid);
15454
15455 if (wpa_command(intf, buf) < 0) {
15456 wpa_ctrl_detach(ctrl);
15457 wpa_ctrl_close(ctrl);
15458 send_resp(dut, conn, SIGMA_ERROR,
15459 "ErrorCode,Failed to start registrar");
15460 return 0;
15461 }
15462
15463 return wps_connection_event(dut, conn, ctrl, intf, 0);
15464}
15465
15466
Jouni Malinenf7222712019-06-13 01:50:21 +030015467static enum sigma_cmd_result cmd_start_wps_registration(struct sigma_dut *dut,
15468 struct sigma_conn *conn,
15469 struct sigma_cmd *cmd)
vamsi krishna9b144002017-09-20 13:28:13 +053015470{
15471 struct wpa_ctrl *ctrl;
15472 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020015473 const char *network_mode = get_param(cmd, "network_mode");
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020015474 const char *config_method = get_param(cmd, "WPSConfigMethod");
15475 const char *role;
vamsi krishna9b144002017-09-20 13:28:13 +053015476 int res;
15477 char buf[256];
15478 const char *events[] = {
15479 "CTRL-EVENT-CONNECTED",
15480 "WPS-OVERLAP-DETECTED",
15481 "WPS-TIMEOUT",
15482 "WPS-FAIL",
15483 NULL
15484 };
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020015485 int id = 0;
vamsi krishna9b144002017-09-20 13:28:13 +053015486
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020015487 /* 60G WPS tests do not pass Interface parameter */
15488 if (!intf)
Jouni Malinen016ae6c2019-11-04 17:00:01 +020015489 intf = get_main_ifname(dut);
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020015490
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020015491 if (dut->mode == SIGMA_MODE_AP)
15492 return ap_wps_registration(dut, conn, cmd);
15493
15494 if (config_method) {
15495 /* WFA_CS_WPS_PIN_KEYPAD mode is set when using the
15496 * sta_wps_enter_pin before calling start_wps_registration. */
15497 if (strcasecmp(config_method, "PBC") == 0)
15498 dut->wps_method = WFA_CS_WPS_PBC;
15499 }
15500 if (dut->wps_method == WFA_CS_WPS_NOT_READY) {
15501 send_resp(dut, conn, SIGMA_ERROR,
15502 "ErrorCode,WPS parameters not yet set");
15503 return STATUS_SENT;
15504 }
15505
15506 /* Make sure WPS is enabled (also for STA mode) */
15507 dut->wps_disable = 0;
15508
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020015509 if (dut->band == WPS_BAND_60G && network_mode &&
15510 strcasecmp(network_mode, "PBSS") == 0) {
15511 sigma_dut_print(dut, DUT_MSG_DEBUG,
15512 "Set PBSS network mode, network id %d", id);
Jouni Malinen016ae6c2019-11-04 17:00:01 +020015513 if (set_network(get_station_ifname(dut), id, "pbss", "1") < 0)
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020015514 return -2;
15515 }
15516
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020015517 if (dut->force_rsn_ie) {
15518 sigma_dut_print(dut, DUT_MSG_DEBUG, "Force RSN_IE: %d",
15519 dut->force_rsn_ie);
15520 if (sta_60g_force_rsn_ie(dut, dut->force_rsn_ie) < 0) {
15521 sigma_dut_print(dut, DUT_MSG_INFO,
15522 "Failed to force RSN_IE");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020015523 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020015524 }
15525 }
15526
vamsi krishna9b144002017-09-20 13:28:13 +053015527 ctrl = open_wpa_mon(intf);
15528 if (!ctrl) {
15529 sigma_dut_print(dut, DUT_MSG_ERROR,
15530 "Failed to open wpa_supplicant monitor connection");
15531 return -2;
15532 }
15533
15534 role = get_param(cmd, "WpsRole");
15535 if (!role) {
15536 send_resp(dut, conn, SIGMA_INVALID,
15537 "ErrorCode,WpsRole not provided");
15538 goto fail;
15539 }
15540
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020015541 if (strcasecmp(role, "Enrollee") != 0) {
15542 /* Registrar role for STA not supported */
15543 send_resp(dut, conn, SIGMA_ERROR,
15544 "ErrorCode,Unsupported WpsRole value");
15545 goto fail;
15546 }
15547
15548 if (is_60g_sigma_dut(dut)) {
15549 if (dut->wps_method == WFA_CS_WPS_PBC)
15550 snprintf(buf, sizeof(buf), "WPS_PBC");
15551 else /* WFA_CS_WPS_PIN_KEYPAD */
15552 snprintf(buf, sizeof(buf), "WPS_PIN any %s",
15553 dut->wps_pin);
15554 if (wpa_command(intf, buf) < 0) {
15555 send_resp(dut, conn, SIGMA_ERROR,
15556 "ErrorCode,Failed to start WPS");
vamsi krishna9b144002017-09-20 13:28:13 +053015557 goto fail;
15558 }
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020015559 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
15560 if (res < 0) {
15561 send_resp(dut, conn, SIGMA_ERROR,
15562 "ErrorCode,WPS connection did not complete");
15563 goto fail;
15564 }
15565 if (strstr(buf, "WPS-TIMEOUT")) {
15566 send_resp(dut, conn, SIGMA_COMPLETE, "WpsState,NoPeer");
15567 } else if (strstr(buf, "WPS-OVERLAP-DETECTED")) {
15568 send_resp(dut, conn, SIGMA_COMPLETE,
15569 "WpsState,OverlapSession");
15570 } else if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
15571 send_resp(dut, conn, SIGMA_COMPLETE,
15572 "WpsState,Successful");
15573 } else {
15574 send_resp(dut, conn, SIGMA_COMPLETE,
15575 "WpsState,Failure");
15576 }
15577 } else {
15578 if (dut->wps_method == WFA_CS_WPS_PBC) {
vamsi krishna9b144002017-09-20 13:28:13 +053015579 if (wpa_command(intf, "WPS_PBC") < 0) {
15580 send_resp(dut, conn, SIGMA_ERROR,
15581 "ErrorCode,Failed to enable PBC");
15582 goto fail;
15583 }
15584 } else {
15585 /* TODO: PIN method */
15586 send_resp(dut, conn, SIGMA_ERROR,
15587 "ErrorCode,Unsupported WpsConfigMethod value");
15588 goto fail;
15589 }
15590 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
15591 if (res < 0) {
15592 send_resp(dut, conn, SIGMA_ERROR,
15593 "ErrorCode,WPS connection did not complete");
15594 goto fail;
15595 }
15596 if (strstr(buf, "WPS-TIMEOUT")) {
15597 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,NoPeer");
15598 } else if (strstr(buf, "WPS-OVERLAP-DETECTED")) {
15599 send_resp(dut, conn, SIGMA_ERROR,
15600 "ErrorCode,OverlapSession");
15601 } else if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
15602 send_resp(dut, conn, SIGMA_COMPLETE, "Successful");
15603 } else {
15604 send_resp(dut, conn, SIGMA_ERROR,
15605 "ErrorCode,WPS operation failed");
15606 }
vamsi krishna9b144002017-09-20 13:28:13 +053015607 }
15608
15609fail:
15610 wpa_ctrl_detach(ctrl);
15611 wpa_ctrl_close(ctrl);
15612 return 0;
15613}
15614
15615
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015616static int req_intf(struct sigma_cmd *cmd)
15617{
15618 return get_param(cmd, "interface") == NULL ? -1 : 0;
15619}
15620
15621
15622void sta_register_cmds(void)
15623{
15624 sigma_dut_reg_cmd("sta_get_ip_config", req_intf,
15625 cmd_sta_get_ip_config);
15626 sigma_dut_reg_cmd("sta_set_ip_config", req_intf,
15627 cmd_sta_set_ip_config);
15628 sigma_dut_reg_cmd("sta_get_info", req_intf, cmd_sta_get_info);
15629 sigma_dut_reg_cmd("sta_get_mac_address", req_intf,
15630 cmd_sta_get_mac_address);
15631 sigma_dut_reg_cmd("sta_is_connected", req_intf, cmd_sta_is_connected);
15632 sigma_dut_reg_cmd("sta_verify_ip_connection", req_intf,
15633 cmd_sta_verify_ip_connection);
15634 sigma_dut_reg_cmd("sta_get_bssid", req_intf, cmd_sta_get_bssid);
15635 sigma_dut_reg_cmd("sta_set_encryption", req_intf,
15636 cmd_sta_set_encryption);
15637 sigma_dut_reg_cmd("sta_set_psk", req_intf, cmd_sta_set_psk);
15638 sigma_dut_reg_cmd("sta_set_eaptls", req_intf, cmd_sta_set_eaptls);
15639 sigma_dut_reg_cmd("sta_set_eapttls", req_intf, cmd_sta_set_eapttls);
15640 sigma_dut_reg_cmd("sta_set_eapsim", req_intf, cmd_sta_set_eapsim);
15641 sigma_dut_reg_cmd("sta_set_peap", req_intf, cmd_sta_set_peap);
15642 sigma_dut_reg_cmd("sta_set_eapfast", req_intf, cmd_sta_set_eapfast);
15643 sigma_dut_reg_cmd("sta_set_eapaka", req_intf, cmd_sta_set_eapaka);
15644 sigma_dut_reg_cmd("sta_set_eapakaprime", req_intf,
15645 cmd_sta_set_eapakaprime);
15646 sigma_dut_reg_cmd("sta_set_security", req_intf, cmd_sta_set_security);
15647 sigma_dut_reg_cmd("sta_set_uapsd", req_intf, cmd_sta_set_uapsd);
15648 /* TODO: sta_set_ibss */
15649 /* TODO: sta_set_mode */
15650 sigma_dut_reg_cmd("sta_set_wmm", req_intf, cmd_sta_set_wmm);
15651 sigma_dut_reg_cmd("sta_associate", req_intf, cmd_sta_associate);
15652 /* TODO: sta_up_load */
15653 sigma_dut_reg_cmd("sta_preset_testparameters", req_intf,
15654 cmd_sta_preset_testparameters);
15655 /* TODO: sta_set_system */
15656 sigma_dut_reg_cmd("sta_set_11n", req_intf, cmd_sta_set_11n);
15657 /* TODO: sta_set_rifs_test */
15658 sigma_dut_reg_cmd("sta_set_wireless", req_intf, cmd_sta_set_wireless);
15659 sigma_dut_reg_cmd("sta_send_addba", req_intf, cmd_sta_send_addba);
15660 /* TODO: sta_send_coexist_mgmt */
15661 sigma_dut_reg_cmd("sta_disconnect", req_intf, cmd_sta_disconnect);
15662 sigma_dut_reg_cmd("sta_reassoc", req_intf, cmd_sta_reassoc);
15663 sigma_dut_reg_cmd("sta_reassociate", req_intf, cmd_sta_reassoc);
15664 sigma_dut_reg_cmd("sta_reset_default", req_intf,
15665 cmd_sta_reset_default);
15666 sigma_dut_reg_cmd("sta_send_frame", req_intf, cmd_sta_send_frame);
15667 sigma_dut_reg_cmd("sta_set_macaddr", req_intf, cmd_sta_set_macaddr);
15668 sigma_dut_reg_cmd("sta_set_rfeature", req_intf, cmd_sta_set_rfeature);
15669 sigma_dut_reg_cmd("sta_set_radio", req_intf, cmd_sta_set_radio);
15670 sigma_dut_reg_cmd("sta_set_pwrsave", req_intf, cmd_sta_set_pwrsave);
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020015671 sigma_dut_reg_cmd("sta_set_power_save", req_intf, cmd_sta_set_pwrsave);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015672 sigma_dut_reg_cmd("sta_bssid_pool", req_intf, cmd_sta_bssid_pool);
15673 sigma_dut_reg_cmd("sta_reset_parm", req_intf, cmd_sta_reset_parm);
15674 sigma_dut_reg_cmd("sta_get_key", req_intf, cmd_sta_get_key);
15675 sigma_dut_reg_cmd("sta_hs2_associate", req_intf,
15676 cmd_sta_hs2_associate);
Jouni Malinenb639f1c2018-09-13 02:39:46 +030015677 sigma_dut_reg_cmd("sta_hs2_venue_info", req_intf,
15678 cmd_sta_hs2_venue_info);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015679 sigma_dut_reg_cmd("sta_add_credential", req_intf,
15680 cmd_sta_add_credential);
15681 sigma_dut_reg_cmd("sta_scan", req_intf, cmd_sta_scan);
Jouni Malinen5e5d43d2018-01-10 17:29:33 +020015682 sigma_dut_reg_cmd("sta_scan_bss", req_intf, cmd_sta_scan_bss);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015683 sigma_dut_reg_cmd("sta_set_systime", NULL, cmd_sta_set_systime);
15684 sigma_dut_reg_cmd("sta_osu", req_intf, cmd_sta_osu);
15685 sigma_dut_reg_cmd("sta_policy_update", req_intf, cmd_sta_policy_update);
15686 sigma_dut_reg_cmd("sta_er_config", NULL, cmd_sta_er_config);
15687 sigma_dut_reg_cmd("sta_wps_connect_pw_token", req_intf,
15688 cmd_sta_wps_connect_pw_token);
Jouni Malinen82905202018-04-29 17:20:10 +030015689 sigma_dut_reg_cmd("sta_exec_action", NULL, cmd_sta_exec_action);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015690 sigma_dut_reg_cmd("sta_get_events", req_intf, cmd_sta_get_events);
15691 sigma_dut_reg_cmd("sta_get_parameter", req_intf, cmd_sta_get_parameter);
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020015692 sigma_dut_reg_cmd("start_wps_registration", NULL,
vamsi krishna9b144002017-09-20 13:28:13 +053015693 cmd_start_wps_registration);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015694}