blob: b1648474ea2f81b53250ae243d955e8a0f6218a5 [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 Jakkamea7f0692021-08-11 19:13:12 +05308270 snprintf(buf, sizeof(buf),
8271 "ip -6 route replace fe80::/64 dev %s table local",
8272 intf);
8273 if (system(buf) != 0)
8274 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to run: %s",
8275 buf);
8276 }
Vamsi Krishnaf642d6a2020-03-27 12:33:14 +05308277
Jouni Malinen8179fee2019-03-28 03:19:47 +02008278 dut->akm_values = 0;
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03008279 dut->sta_ft_ds = 0;
Jouni Malinen8179fee2019-03-28 03:19:47 +02008280
Sunil Dutt076081f2018-02-05 19:45:50 +05308281#ifdef NL80211_SUPPORT
Jouni Malinen016ae6c2019-11-04 17:00:01 +02008282 if (get_driver_type(dut) == DRIVER_WCN &&
Sunil Dutt44595082018-02-12 19:41:45 +05308283 dut->config_rsnie == 1) {
8284 dut->config_rsnie = 0;
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05308285 sta_config_params(dut, intf, STA_SET_RSNIE, 0);
Sunil Dutt076081f2018-02-05 19:45:50 +05308286 }
8287#endif /* NL80211_SUPPORT */
8288
Sunil Duttfebf8a82018-02-09 18:50:13 +05308289 if (dev_role && strcasecmp(dev_role, "STA-CFON") == 0) {
8290 dut->dev_role = DEVROLE_STA_CFON;
8291 return sta_cfon_reset_default(dut, conn, cmd);
8292 }
8293
Jouni Malinen439352d2018-09-13 03:42:23 +03008294 wpa_command(intf, "SET setband AUTO");
8295
Veerendranath Jakkamc1f71b62021-01-23 03:09:51 +05308296 ret = wpa_command_resp(intf, "GET_CAPABILITY ocv", resp, sizeof(resp));
8297 dut->ocvc = ret == 0 && strncmp(resp, "supported", 9) == 0;
8298
8299 ret = wpa_command_resp(intf, "GET_CAPABILITY beacon_prot", resp,
8300 sizeof(resp));
8301 dut->beacon_prot = ret == 0 && strncmp(resp, "supported", 9) == 0;
8302
Veerendranath Jakkam47867202020-12-21 01:53:52 +05308303 if (sta_set_client_privacy(dut, conn, intf,
8304 dut->program == PROGRAM_WPA3 &&
8305 dut->device_type == STA_dut &&
8306 dut->client_privacy_default)) {
8307 sigma_dut_print(dut, DUT_MSG_ERROR,
8308 "Failed to set client privacy functionality");
8309 /* sta_reset_default command is not really supposed to fail,
8310 * so allow this to continue. */
8311 }
8312
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +05308313 dut->saquery_oci_freq = 0;
Vamsi Krishnac1633d22020-05-06 18:31:21 +05308314
Sunil Duttfebf8a82018-02-09 18:50:13 +05308315 if (dut->program != PROGRAM_VHT)
8316 return cmd_sta_p2p_reset(dut, conn, cmd);
8317
Priyadharshini Gowthamana7dfd492015-11-09 14:34:08 -08008318 return 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008319}
8320
8321
Jouni Malinenf7222712019-06-13 01:50:21 +03008322static enum sigma_cmd_result cmd_sta_get_events(struct sigma_dut *dut,
8323 struct sigma_conn *conn,
8324 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008325{
8326 const char *program = get_param(cmd, "Program");
8327
8328 if (program == NULL)
8329 return -1;
8330#ifdef ANDROID_NAN
8331 if (strcasecmp(program, "NAN") == 0)
8332 return nan_cmd_sta_get_events(dut, conn, cmd);
8333#endif /* ANDROID_NAN */
8334 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
8335 return 0;
8336}
8337
8338
Jouni Malinen82905202018-04-29 17:20:10 +03008339static int sta_exec_action_url(struct sigma_dut *dut, struct sigma_conn *conn,
8340 struct sigma_cmd *cmd)
8341{
8342 const char *url = get_param(cmd, "url");
8343 const char *method = get_param(cmd, "method");
8344 pid_t pid;
8345 int status;
8346
8347 if (!url || !method)
8348 return -1;
8349
8350 /* TODO: Add support for method,post */
8351 if (strcasecmp(method, "get") != 0) {
8352 send_resp(dut, conn, SIGMA_ERROR,
8353 "ErrorCode,Unsupported method");
8354 return 0;
8355 }
8356
8357 pid = fork();
8358 if (pid < 0) {
8359 perror("fork");
8360 return -1;
8361 }
8362
8363 if (pid == 0) {
8364 char * argv[5] = { "wget", "-O", "/dev/null",
8365 (char *) url, NULL };
8366
8367 execv("/usr/bin/wget", argv);
8368 perror("execv");
8369 exit(0);
8370 return -1;
8371 }
8372
8373 if (waitpid(pid, &status, 0) < 0) {
8374 perror("waitpid");
8375 return -1;
8376 }
8377
8378 if (WIFEXITED(status)) {
8379 const char *errmsg;
8380
8381 if (WEXITSTATUS(status) == 0)
8382 return 1;
8383 sigma_dut_print(dut, DUT_MSG_INFO, "wget exit status %d",
8384 WEXITSTATUS(status));
8385 switch (WEXITSTATUS(status)) {
8386 case 4:
8387 errmsg = "errmsg,Network failure";
8388 break;
8389 case 8:
8390 errmsg = "errmsg,Server issued an error response";
8391 break;
8392 default:
8393 errmsg = "errmsg,Unknown failure from wget";
8394 break;
8395 }
8396 send_resp(dut, conn, SIGMA_ERROR, errmsg);
8397 return 0;
8398 }
8399
8400 send_resp(dut, conn, SIGMA_ERROR, "errmsg,Unknown failure");
8401 return 0;
8402}
8403
8404
Jouni Malinenf7222712019-06-13 01:50:21 +03008405static enum sigma_cmd_result cmd_sta_exec_action(struct sigma_dut *dut,
8406 struct sigma_conn *conn,
8407 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008408{
8409 const char *program = get_param(cmd, "Prog");
8410
Jouni Malinen82905202018-04-29 17:20:10 +03008411 if (program && !get_param(cmd, "interface"))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008412 return -1;
8413#ifdef ANDROID_NAN
Jouni Malinen82905202018-04-29 17:20:10 +03008414 if (program && strcasecmp(program, "NAN") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008415 return nan_cmd_sta_exec_action(dut, conn, cmd);
8416#endif /* ANDROID_NAN */
Jouni Malinen82905202018-04-29 17:20:10 +03008417
8418 if (program && strcasecmp(program, "Loc") == 0)
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07008419 return loc_cmd_sta_exec_action(dut, conn, cmd);
Jouni Malinen82905202018-04-29 17:20:10 +03008420
8421 if (get_param(cmd, "url"))
8422 return sta_exec_action_url(dut, conn, cmd);
8423
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008424 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
8425 return 0;
8426}
8427
8428
Jouni Malinenf7222712019-06-13 01:50:21 +03008429static enum sigma_cmd_result cmd_sta_set_11n(struct sigma_dut *dut,
8430 struct sigma_conn *conn,
8431 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008432{
8433 const char *intf = get_param(cmd, "Interface");
8434 const char *val, *mcs32, *rate;
8435
8436 val = get_param(cmd, "GREENFIELD");
8437 if (val) {
8438 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
8439 /* Enable GD */
8440 send_resp(dut, conn, SIGMA_ERROR,
8441 "ErrorCode,GF not supported");
8442 return 0;
8443 }
8444 }
8445
8446 val = get_param(cmd, "SGI20");
8447 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02008448 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008449 case DRIVER_ATHEROS:
8450 ath_sta_set_sgi(dut, intf, val);
8451 break;
8452 default:
8453 send_resp(dut, conn, SIGMA_ERROR,
8454 "ErrorCode,SGI20 not supported");
8455 return 0;
8456 }
8457 }
8458
8459 mcs32 = get_param(cmd, "MCS32"); /* HT Duplicate Mode Enable/Disable */
8460 rate = get_param(cmd, "MCS_FIXEDRATE"); /* Fixed MCS rate (0..31) */
8461 if (mcs32 && rate) {
8462 /* TODO */
8463 send_resp(dut, conn, SIGMA_ERROR,
8464 "ErrorCode,MCS32,MCS_FIXEDRATE not supported");
8465 return 0;
8466 } else if (mcs32 && !rate) {
8467 /* TODO */
8468 send_resp(dut, conn, SIGMA_ERROR,
8469 "ErrorCode,MCS32 not supported");
8470 return 0;
8471 } else if (!mcs32 && rate) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02008472 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008473 case DRIVER_ATHEROS:
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -07008474 novap_reset(dut, intf, 1);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008475 ath_sta_set_11nrates(dut, intf, rate);
8476 break;
8477 default:
8478 send_resp(dut, conn, SIGMA_ERROR,
8479 "ErrorCode,MCS32_FIXEDRATE not supported");
8480 return 0;
8481 }
8482 }
8483
8484 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
8485}
8486
8487
Arif Hussain7b47d2d2018-05-09 10:44:02 -07008488static void cmd_set_max_he_mcs(struct sigma_dut *dut, const char *intf,
8489 int mcs_config)
8490{
8491#ifdef NL80211_SUPPORT
8492 int ret;
8493
8494 switch (mcs_config) {
8495 case HE_80_MCS0_7:
8496 case HE_80_MCS0_9:
8497 case HE_80_MCS0_11:
8498 ret = sta_set_he_mcs(dut, intf, mcs_config);
8499 if (ret) {
8500 sigma_dut_print(dut, DUT_MSG_ERROR,
8501 "cmd_set_max_he_mcs: Setting of MCS:%d failed, ret:%d",
8502 mcs_config, ret);
8503 }
8504 break;
8505 default:
8506 sigma_dut_print(dut, DUT_MSG_ERROR,
8507 "cmd_set_max_he_mcs: Invalid mcs %d",
8508 mcs_config);
8509 break;
8510 }
8511#else /* NL80211_SUPPORT */
8512 sigma_dut_print(dut, DUT_MSG_ERROR,
8513 "max HE MCS cannot be changed without NL80211_SUPPORT defined");
8514#endif /* NL80211_SUPPORT */
8515}
8516
8517
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07008518struct wait_event {
8519 struct sigma_dut *dut;
8520 int cmd;
8521 unsigned int twt_op;
8522};
8523
8524#ifdef NL80211_SUPPORT
8525
8526static int twt_event_handler(struct nl_msg *msg, void *arg)
8527{
8528 struct wait_event *wait = arg;
8529 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
8530 struct nlattr *tb[NL80211_ATTR_MAX + 1];
8531 uint32_t subcmd;
8532 uint8_t *data = NULL;
8533 size_t len = 0;
8534 struct nlattr *twt_rsp[QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_MAX + 1];
8535 struct nlattr *twt_status[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX + 1];
8536 int cmd_id;
8537 unsigned char val;
8538
8539 if (!wait)
8540 return NL_SKIP;
8541
8542 if (gnlh->cmd != NL80211_CMD_VENDOR) {
8543 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
8544 "%s: NL cmd is not vendor %d", __func__,
8545 gnlh->cmd);
8546 return NL_SKIP;
8547 }
8548
8549 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
8550 genlmsg_attrlen(gnlh, 0), NULL);
8551
8552 if (!tb[NL80211_ATTR_VENDOR_ID] || !tb[NL80211_ATTR_VENDOR_SUBCMD]) {
8553 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
8554 "%s: vendor ID not found", __func__);
8555 return NL_SKIP;
8556 }
8557 subcmd = nla_get_u32(tb[NL80211_ATTR_VENDOR_SUBCMD]);
8558
8559 if (subcmd != QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) {
8560 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
8561 "%s: Not a TWT_cmd %d", __func__, subcmd);
8562 return NL_SKIP;
8563 }
8564 if (tb[NL80211_ATTR_VENDOR_DATA]) {
8565 data = nla_data(tb[NL80211_ATTR_VENDOR_DATA]);
8566 len = nla_len(tb[NL80211_ATTR_VENDOR_DATA]);
8567 } else {
8568 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
8569 "%s: vendor data not present", __func__);
8570 return NL_SKIP;
8571 }
8572 if (!data || !len) {
8573 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
8574 "Invalid vendor data or len");
8575 return NL_SKIP;
8576 }
8577 sigma_dut_print(wait->dut, DUT_MSG_DEBUG,
8578 "event data len %ld", len);
8579 hex_dump(wait->dut, data, len);
8580 if (nla_parse(twt_rsp, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_MAX,
8581 (struct nlattr *) data, len, NULL)) {
8582 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
8583 "vendor data parse error");
8584 return NL_SKIP;
8585 }
8586
8587 val = nla_get_u8(twt_rsp[QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION]);
8588 if (val != wait->twt_op) {
8589 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
8590 "Invalid TWT operation, expected %d, rcvd %d",
8591 wait->twt_op, val);
8592 return NL_SKIP;
8593 }
8594 if (nla_parse_nested(twt_status, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX,
8595 twt_rsp[QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS],
8596 NULL)) {
8597 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
8598 "nla_parse failed for TWT event");
8599 return NL_SKIP;
8600 }
8601
8602 cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_STATUS;
8603 if (!twt_status[cmd_id]) {
8604 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
8605 "%s TWT resp status missing", __func__);
8606 wait->cmd = -1;
8607 } else {
8608 val = nla_get_u8(twt_status[cmd_id]);
8609 if (val != QCA_WLAN_VENDOR_TWT_STATUS_OK) {
8610 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
8611 "%s TWT resp status %d", __func__, val);
8612 wait->cmd = -1;
8613 } else {
8614 wait->cmd = 1;
8615 }
8616 }
8617
8618 return NL_SKIP;
8619}
8620
8621
8622static int wait_on_nl_socket(struct nl_sock *sock, struct sigma_dut *dut,
8623 unsigned int timeout)
8624{
8625 fd_set read_fd_set;
8626 int retval;
8627 int sock_fd;
8628 struct timeval time_out;
8629
8630 time_out.tv_sec = timeout;
8631 time_out.tv_usec = 0;
8632
8633 FD_ZERO(&read_fd_set);
8634
8635 if (!sock)
8636 return -1;
8637
8638 sock_fd = nl_socket_get_fd(sock);
8639 FD_SET(sock_fd, &read_fd_set);
8640
8641 retval = select(sock_fd + 1, &read_fd_set, NULL, NULL, &time_out);
8642
8643 if (retval == 0)
8644 sigma_dut_print(dut, DUT_MSG_ERROR,
8645 "%s: TWT event response timedout", __func__);
8646
8647 if (retval < 0)
8648 sigma_dut_print(dut, DUT_MSG_ERROR, "%s:no NL msgs, ret=%d",
8649 __func__, retval);
8650
8651 return retval;
8652}
8653
8654
8655#define TWT_ASYNC_EVENT_WAIT_TIME_SEC 6
8656
8657static int twt_async_event_wait(struct sigma_dut *dut, unsigned int twt_op)
8658{
8659 struct nl_cb *cb;
8660 int err_code = 0, select_retval = 0;
8661 struct wait_event wait_info;
8662
8663 cb = nl_socket_get_cb(dut->nl_ctx->event_sock);
8664 if (!cb) {
8665 sigma_dut_print(dut, DUT_MSG_ERROR,
8666 "event callback not found");
8667 return ERROR_SEND_STATUS;
8668 }
8669
8670 wait_info.cmd = 0;
8671 wait_info.dut = dut;
8672 wait_info.twt_op = twt_op;
8673
8674 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, twt_event_handler, &wait_info);
8675
8676 while (!wait_info.cmd) {
8677 select_retval = wait_on_nl_socket(
8678 dut->nl_ctx->event_sock, dut,
8679 TWT_ASYNC_EVENT_WAIT_TIME_SEC);
8680
8681 if (select_retval > 0) {
8682 err_code = nl_recvmsgs(dut->nl_ctx->event_sock, cb);
8683 if (err_code < 0) {
8684 sigma_dut_print(dut, DUT_MSG_ERROR,
8685 "%s: nl rcv failed, err_code %d",
8686 __func__, err_code);
8687 break;
8688 }
8689 } else {
8690 sigma_dut_print(dut, DUT_MSG_ERROR,
8691 "%s: wait on socket failed %d",
8692 __func__, select_retval);
8693 err_code = 1;
8694 break;
8695 }
8696
8697 }
8698 nl_cb_put(cb);
8699
8700 if (wait_info.cmd < 0)
8701 err_code = 1;
8702
8703 sigma_dut_print(dut, DUT_MSG_DEBUG,
8704 "%s: rcvd cmd %d, err_code %d, s_ret %d",
8705 __func__, wait_info.cmd, err_code, select_retval);
8706
8707 return err_code;
8708}
8709
8710#endif /* NL80211_SUPPORT */
8711
8712
Srinivas Girigowda6707f032020-10-26 15:24:46 -07008713static int sta_twt_send_suspend(struct sigma_dut *dut, struct sigma_conn *conn,
8714 struct sigma_cmd *cmd)
8715{
8716#ifdef NL80211_SUPPORT
8717 struct nlattr *attr, *attr1;
8718 struct nl_msg *msg;
8719 int ifindex, ret;
8720 const char *intf = get_param(cmd, "Interface");
8721
8722 ifindex = if_nametoindex(intf);
8723 if (ifindex == 0) {
8724 sigma_dut_print(dut, DUT_MSG_ERROR,
8725 "%s: Index for interface %s failed",
8726 __func__, intf);
8727 return ERROR_SEND_STATUS;
8728 }
8729
8730 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8731 NL80211_CMD_VENDOR)) ||
8732 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
8733 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
8734 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
8735 QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
8736 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8737 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
8738 QCA_WLAN_TWT_SUSPEND) ||
8739 !(attr1 = nla_nest_start(msg,
Kiran Kumar Lokere7ede00c2021-08-09 00:59:52 -07008740 QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS))) {
Srinivas Girigowda6707f032020-10-26 15:24:46 -07008741 sigma_dut_print(dut, DUT_MSG_ERROR,
8742 "%s: err in adding vendor_cmd and vendor_data",
8743 __func__);
8744 nlmsg_free(msg);
8745 return ERROR_SEND_STATUS;
8746 }
8747 nla_nest_end(msg, attr1);
8748 nla_nest_end(msg, attr);
8749
8750 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
8751 if (ret) {
8752 sigma_dut_print(dut, DUT_MSG_ERROR,
8753 "%s: err in send_and_recv_msgs, ret=%d",
8754 __func__, ret);
8755 }
8756
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07008757 if (!dut->sta_async_twt_supp)
8758 return ret;
8759
8760 return twt_async_event_wait(dut, QCA_WLAN_TWT_SUSPEND);
Srinivas Girigowda6707f032020-10-26 15:24:46 -07008761#else /* NL80211_SUPPORT */
8762 sigma_dut_print(dut, DUT_MSG_ERROR,
8763 "TWT suspend cannot be done without NL80211_SUPPORT defined");
8764 return ERROR_SEND_STATUS;
8765#endif /* NL80211_SUPPORT */
8766}
8767
8768
8769static int sta_twt_send_nudge(struct sigma_dut *dut, struct sigma_conn *conn,
8770 struct sigma_cmd *cmd,
8771 unsigned int suspend_duration)
8772{
8773#ifdef NL80211_SUPPORT
8774 struct nlattr *attr, *attr1;
8775 struct nl_msg *msg;
8776 int ifindex, ret;
8777 const char *intf = get_param(cmd, "Interface");
8778 int next_twt_size = 1;
8779
8780 ifindex = if_nametoindex(intf);
8781 if (ifindex == 0) {
8782 sigma_dut_print(dut, DUT_MSG_ERROR,
8783 "%s: Index for interface %s failed",
8784 __func__, intf);
8785 return ERROR_SEND_STATUS;
8786 }
8787
8788 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8789 NL80211_CMD_VENDOR)) ||
8790 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
8791 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
8792 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
8793 QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
8794 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8795 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
8796 QCA_WLAN_TWT_NUDGE) ||
8797 !(attr1 = nla_nest_start(msg,
8798 QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS)) ||
8799 (suspend_duration &&
8800 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_WAKE_TIME,
8801 suspend_duration)) ||
8802 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_NEXT_TWT_SIZE,
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -07008803 next_twt_size) ||
8804 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_FLOW_ID, 0)) {
Srinivas Girigowda6707f032020-10-26 15:24:46 -07008805 sigma_dut_print(dut, DUT_MSG_ERROR,
8806 "%s: err in adding vendor_cmd and vendor_data",
8807 __func__);
8808 nlmsg_free(msg);
8809 return ERROR_SEND_STATUS;
8810 }
8811 nla_nest_end(msg, attr1);
8812 nla_nest_end(msg, attr);
8813
8814 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
8815 if (ret) {
8816 sigma_dut_print(dut, DUT_MSG_ERROR,
8817 "%s: err in send_and_recv_msgs, ret=%d",
8818 __func__, ret);
8819 }
8820
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07008821 if (!dut->sta_async_twt_supp)
8822 return ret;
8823
8824 return twt_async_event_wait(dut, QCA_WLAN_TWT_NUDGE);
Srinivas Girigowda6707f032020-10-26 15:24:46 -07008825#else /* NL80211_SUPPORT */
8826 sigma_dut_print(dut, DUT_MSG_ERROR,
8827 "TWT suspend cannot be done without NL80211_SUPPORT defined");
8828 return ERROR_SEND_STATUS;
8829#endif /* NL80211_SUPPORT */
8830}
8831
8832
8833static int sta_twt_suspend_or_nudge(struct sigma_dut *dut,
8834 struct sigma_conn *conn,
8835 struct sigma_cmd *cmd)
8836{
8837 const char *val;
8838
8839 val = get_param(cmd, "TWT_SuspendDuration");
8840 if (val) {
8841 unsigned int suspend_duration;
8842
8843 suspend_duration = atoi(val);
8844 suspend_duration = suspend_duration * 1000 * 1000;
8845 return sta_twt_send_nudge(dut, conn, cmd, suspend_duration);
8846 }
8847
8848 return sta_twt_send_suspend(dut, conn, cmd);
8849}
8850
8851
8852static int sta_twt_resume(struct sigma_dut *dut, struct sigma_conn *conn,
8853 struct sigma_cmd *cmd)
8854{
8855#ifdef NL80211_SUPPORT
8856 struct nlattr *attr, *attr1;
8857 struct nl_msg *msg;
8858 int ifindex, ret;
8859 const char *intf = get_param(cmd, "Interface");
8860 int next2_twt_size = 1;
8861 unsigned int resume_duration = 0;
8862 const char *val;
8863
8864 ifindex = if_nametoindex(intf);
8865 if (ifindex == 0) {
8866 sigma_dut_print(dut, DUT_MSG_ERROR,
8867 "%s: Index for interface %s failed",
8868 __func__, intf);
8869 return ERROR_SEND_STATUS;
8870 }
8871
8872 val = get_param(cmd, "TWT_ResumeDuration");
8873 if (val) {
8874 resume_duration = atoi(val);
8875 resume_duration = resume_duration * 1000 * 1000;
8876 }
8877
8878 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8879 NL80211_CMD_VENDOR)) ||
8880 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
8881 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
8882 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
8883 QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
8884 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8885 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
8886 QCA_WLAN_TWT_RESUME) ||
8887 !(attr1 = nla_nest_start(msg,
8888 QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS)) ||
8889 (resume_duration &&
8890 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_RESUME_NEXT2_TWT,
8891 resume_duration)) ||
8892 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_RESUME_NEXT_TWT_SIZE,
8893 next2_twt_size)) {
8894 sigma_dut_print(dut, DUT_MSG_ERROR,
8895 "%s: err in adding vendor_cmd and vendor_data",
8896 __func__);
8897 nlmsg_free(msg);
8898 return ERROR_SEND_STATUS;
8899 }
8900 nla_nest_end(msg, attr1);
8901 nla_nest_end(msg, attr);
8902
8903 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
8904 if (ret) {
8905 sigma_dut_print(dut, DUT_MSG_ERROR,
8906 "%s: err in send_and_recv_msgs, ret=%d",
8907 __func__, ret);
8908 }
8909
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07008910 if (!dut->sta_async_twt_supp)
8911 return ret;
8912
8913 return twt_async_event_wait(dut, QCA_WLAN_TWT_RESUME);
Srinivas Girigowda6707f032020-10-26 15:24:46 -07008914#else /* NL80211_SUPPORT */
8915 sigma_dut_print(dut, DUT_MSG_ERROR,
8916 "TWT resume cannot be done without NL80211_SUPPORT defined");
8917 return ERROR_SEND_STATUS;
8918#endif /* NL80211_SUPPORT */
8919}
8920
8921
Kiran Kumar Lokerebd396102020-04-27 12:01:09 -07008922#define TWT_REQUEST_CMD 0
8923#define TWT_SUGGEST_CMD 1
8924#define TWT_DEMAND_CMD 2
8925
Arif Hussain480d5f42019-03-12 14:40:42 -07008926static int sta_twt_request(struct sigma_dut *dut, struct sigma_conn *conn,
8927 struct sigma_cmd *cmd)
8928{
8929#ifdef NL80211_SUPPORT
8930 struct nlattr *params;
8931 struct nlattr *attr;
Arif Hussain480d5f42019-03-12 14:40:42 -07008932 struct nl_msg *msg;
8933 int ifindex, ret;
8934 const char *val;
8935 const char *intf = get_param(cmd, "Interface");
8936 int wake_interval_exp = 10, nominal_min_wake_dur = 255,
8937 wake_interval_mantissa = 512;
8938 int flow_type = 0, twt_trigger = 0, target_wake_time = 0,
Kiran Kumar Lokerebd396102020-04-27 12:01:09 -07008939 protection = 0, cmd_type = QCA_WLAN_VENDOR_TWT_SETUP_SUGGEST;
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -07008940 int bcast_twt = 0;
8941 int bcast_twt_id = 0, bcast_twt_recommdn = 0, bcast_twt_persis = 0;
Arif Hussain480d5f42019-03-12 14:40:42 -07008942
8943 ifindex = if_nametoindex(intf);
8944 if (ifindex == 0) {
8945 sigma_dut_print(dut, DUT_MSG_ERROR,
8946 "%s: Index for interface %s failed",
8947 __func__, intf);
8948 return -1;
8949 }
8950
8951 val = get_param(cmd, "FlowType");
8952 if (val) {
8953 flow_type = atoi(val);
8954 if (flow_type != 0 && flow_type != 1) {
8955 sigma_dut_print(dut, DUT_MSG_ERROR,
8956 "TWT: Invalid FlowType %d", flow_type);
8957 return -1;
8958 }
8959 }
8960
8961 val = get_param(cmd, "TWT_Trigger");
8962 if (val) {
8963 twt_trigger = atoi(val);
8964 if (twt_trigger != 0 && twt_trigger != 1) {
8965 sigma_dut_print(dut, DUT_MSG_ERROR,
8966 "TWT: Invalid TWT_Trigger %d",
8967 twt_trigger);
8968 return -1;
8969 }
8970 }
8971
8972 val = get_param(cmd, "Protection");
8973 if (val) {
8974 protection = atoi(val);
8975 if (protection != 0 && protection != 1) {
8976 sigma_dut_print(dut, DUT_MSG_ERROR,
8977 "TWT: Invalid Protection %d",
8978 protection);
8979 return -1;
8980 }
8981 }
8982
Kiran Kumar Lokerebd396102020-04-27 12:01:09 -07008983 val = get_param(cmd, "SetupCommand");
8984 if (val) {
8985 cmd_type = atoi(val);
8986 if (cmd_type == TWT_REQUEST_CMD)
8987 cmd_type = QCA_WLAN_VENDOR_TWT_SETUP_REQUEST;
8988 else if (cmd_type == TWT_SUGGEST_CMD)
8989 cmd_type = QCA_WLAN_VENDOR_TWT_SETUP_SUGGEST;
8990 else if (cmd_type == TWT_DEMAND_CMD)
8991 cmd_type = QCA_WLAN_VENDOR_TWT_SETUP_DEMAND;
8992 else
8993 sigma_dut_print(dut, DUT_MSG_ERROR,
8994 "Default suggest is used for cmd %d",
8995 cmd_type);
8996 }
8997
Arif Hussain480d5f42019-03-12 14:40:42 -07008998 val = get_param(cmd, "TargetWakeTime");
8999 if (val)
9000 target_wake_time = atoi(val);
9001
9002 val = get_param(cmd, "WakeIntervalMantissa");
9003 if (val)
9004 wake_interval_mantissa = atoi(val);
9005
9006 val = get_param(cmd, "WakeIntervalExp");
9007 if (val)
9008 wake_interval_exp = atoi(val);
9009
9010 val = get_param(cmd, "NominalMinWakeDur");
9011 if (val)
9012 nominal_min_wake_dur = atoi(val);
9013
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -07009014 val = get_param(cmd, "BTWT_ID");
9015 if (val) {
9016 bcast_twt_id = atoi(val);
9017 bcast_twt = 1;
9018 }
9019
9020 val = get_param(cmd, "BTWT_Persistence");
9021 if (val) {
9022 bcast_twt_persis = atoi(val);
9023 bcast_twt = 1;
9024 }
9025
9026 val = get_param(cmd, "BTWT_Recommendation");
9027 if (val) {
9028 bcast_twt_recommdn = atoi(val);
9029 bcast_twt = 1;
9030 }
9031
9032 if (bcast_twt)
9033 sigma_dut_print(dut, DUT_MSG_DEBUG,
9034 "BCAST_TWT: ID %d, RECOMM %d, PERSIS %d",
9035 bcast_twt_id, bcast_twt_recommdn,
9036 bcast_twt_persis);
9037
Arif Hussain480d5f42019-03-12 14:40:42 -07009038 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
9039 NL80211_CMD_VENDOR)) ||
9040 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
9041 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
9042 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
Srinivas Girigowda6707f032020-10-26 15:24:46 -07009043 QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
Arif Hussain480d5f42019-03-12 14:40:42 -07009044 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
Srinivas Girigowda6707f032020-10-26 15:24:46 -07009045 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
9046 QCA_WLAN_TWT_SET) ||
Arif Hussain480d5f42019-03-12 14:40:42 -07009047 !(params = nla_nest_start(
Srinivas Girigowda6707f032020-10-26 15:24:46 -07009048 msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS)) ||
Arif Hussain480d5f42019-03-12 14:40:42 -07009049 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_EXP,
9050 wake_interval_exp) ||
Kiran Kumar Lokerebd396102020-04-27 12:01:09 -07009051 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_REQ_TYPE, cmd_type) ||
Kiran Kumar Lokere2cffae52019-09-26 18:44:15 -07009052 (twt_trigger &&
9053 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TRIGGER)) ||
Arif Hussain480d5f42019-03-12 14:40:42 -07009054 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE,
9055 flow_type) ||
Kiran Kumar Lokere2cffae52019-09-26 18:44:15 -07009056 (protection &&
9057 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_PROTECTION)) ||
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -07009058 (bcast_twt &&
9059 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST)) ||
9060 (bcast_twt &&
9061 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_ID,
9062 bcast_twt_id)) ||
9063 (bcast_twt &&
9064 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_PERSISTENCE,
9065 bcast_twt_persis)) ||
9066 (bcast_twt &&
9067 nla_put_u8(msg,
9068 QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_RECOMMENDATION,
9069 bcast_twt_recommdn)) ||
Arif Hussain480d5f42019-03-12 14:40:42 -07009070 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME,
9071 target_wake_time) ||
9072 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_DURATION,
9073 nominal_min_wake_dur) ||
9074 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_MANTISSA,
9075 wake_interval_mantissa)) {
9076 sigma_dut_print(dut, DUT_MSG_ERROR,
9077 "%s: err in adding vendor_cmd and vendor_data",
9078 __func__);
9079 nlmsg_free(msg);
9080 return -1;
9081 }
Arif Hussain480d5f42019-03-12 14:40:42 -07009082 nla_nest_end(msg, params);
9083 nla_nest_end(msg, attr);
9084
9085 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
9086 if (ret) {
9087 sigma_dut_print(dut, DUT_MSG_ERROR,
9088 "%s: err in send_and_recv_msgs, ret=%d",
9089 __func__, ret);
9090 }
9091
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07009092 if (!dut->sta_async_twt_supp)
9093 return ret;
9094
9095 return twt_async_event_wait(dut, QCA_WLAN_TWT_SET);
Arif Hussain480d5f42019-03-12 14:40:42 -07009096#else /* NL80211_SUPPORT */
9097 sigma_dut_print(dut, DUT_MSG_ERROR,
9098 "TWT request cannot be done without NL80211_SUPPORT defined");
9099 return -1;
9100#endif /* NL80211_SUPPORT */
9101}
9102
9103
9104static int sta_twt_teardown(struct sigma_dut *dut, struct sigma_conn *conn,
9105 struct sigma_cmd *cmd)
9106{
9107 #ifdef NL80211_SUPPORT
9108 struct nlattr *params;
9109 struct nlattr *attr;
Arif Hussain480d5f42019-03-12 14:40:42 -07009110 int ifindex, ret;
9111 struct nl_msg *msg;
9112 const char *intf = get_param(cmd, "Interface");
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -07009113 int bcast_twt = 0;
9114 int bcast_twt_id = 0;
9115 const char *val;
Arif Hussain480d5f42019-03-12 14:40:42 -07009116
9117 ifindex = if_nametoindex(intf);
9118 if (ifindex == 0) {
9119 sigma_dut_print(dut, DUT_MSG_ERROR,
9120 "%s: Index for interface %s failed",
9121 __func__, intf);
9122 return -1;
9123 }
9124
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -07009125 val = get_param(cmd, "BTWT_ID");
9126 if (val) {
9127 bcast_twt_id = atoi(val);
9128 bcast_twt = 1;
9129 }
9130
Arif Hussain480d5f42019-03-12 14:40:42 -07009131 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
9132 NL80211_CMD_VENDOR)) ||
9133 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
9134 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
9135 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
Srinivas Girigowda6707f032020-10-26 15:24:46 -07009136 QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
Arif Hussain480d5f42019-03-12 14:40:42 -07009137 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
Srinivas Girigowda6707f032020-10-26 15:24:46 -07009138 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
9139 QCA_WLAN_TWT_TERMINATE) ||
Arif Hussain480d5f42019-03-12 14:40:42 -07009140 !(params = nla_nest_start(
9141 msg,
Srinivas Girigowda6707f032020-10-26 15:24:46 -07009142 QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS)) ||
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -07009143 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE, 0) ||
9144 (bcast_twt &&
9145 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST)) ||
9146 (bcast_twt &&
9147 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_ID,
9148 bcast_twt_id))) {
Arif Hussain480d5f42019-03-12 14:40:42 -07009149 sigma_dut_print(dut, DUT_MSG_ERROR,
9150 "%s: err in adding vendor_cmd and vendor_data",
9151 __func__);
9152 nlmsg_free(msg);
9153 return -1;
9154 }
Arif Hussain480d5f42019-03-12 14:40:42 -07009155 nla_nest_end(msg, params);
9156 nla_nest_end(msg, attr);
9157
9158 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
9159 if (ret) {
9160 sigma_dut_print(dut, DUT_MSG_ERROR,
9161 "%s: err in send_and_recv_msgs, ret=%d",
9162 __func__, ret);
9163 }
9164
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07009165 if (!dut->sta_async_twt_supp)
9166 return ret;
9167
9168 return twt_async_event_wait(dut, QCA_WLAN_TWT_TERMINATE);
Arif Hussain480d5f42019-03-12 14:40:42 -07009169#else /* NL80211_SUPPORT */
9170 sigma_dut_print(dut, DUT_MSG_ERROR,
9171 "TWT teardown cannot be done without NL80211_SUPPORT defined");
9172 return -1;
9173#endif /* NL80211_SUPPORT */
9174}
9175
9176
Kiran Kumar Lokere50eb2cd2018-12-18 18:31:28 -08009177static int sta_transmit_omi(struct sigma_dut *dut, struct sigma_conn *conn,
9178 struct sigma_cmd *cmd)
9179{
9180#ifdef NL80211_SUPPORT
9181 struct nlattr *params;
9182 struct nlattr *attr;
9183 struct nlattr *attr1;
9184 struct nl_msg *msg;
9185 int ifindex, ret;
9186 const char *val;
9187 const char *intf = get_param(cmd, "Interface");
9188 uint8_t rx_nss = 0xFF, ch_bw = 0xFF, tx_nsts = 0xFF, ulmu_dis = 0,
9189 ulmu_data_dis = 0;
9190
9191 ifindex = if_nametoindex(intf);
9192 if (ifindex == 0) {
9193 sigma_dut_print(dut, DUT_MSG_ERROR,
9194 "%s: Index for interface %s failed",
9195 __func__, intf);
9196 return -1;
9197 }
9198 val = get_param(cmd, "OMCtrl_RxNSS");
9199 if (val)
9200 rx_nss = atoi(val);
9201
9202 val = get_param(cmd, "OMCtrl_ChnlWidth");
9203 if (val)
9204 ch_bw = atoi(val);
9205
9206 val = get_param(cmd, "OMCtrl_ULMUDisable");
9207 if (val)
9208 ulmu_dis = atoi(val);
9209
9210 val = get_param(cmd, "OMCtrl_TxNSTS");
9211 if (val)
9212 tx_nsts = atoi(val);
9213
9214 val = get_param(cmd, "OMCtrl_ULMUDataDisable");
9215 if (val)
9216 ulmu_data_dis = atoi(val);
9217
9218 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
9219 NL80211_CMD_VENDOR)) ||
9220 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
9221 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
9222 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
9223 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
9224 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
9225 !(params = nla_nest_start(
9226 msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OMI_TX)) ||
9227 !(attr1 = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
9228 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_RX_NSS, rx_nss) ||
9229 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_CH_BW, ch_bw) ||
9230 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_TX_NSTS, tx_nsts) ||
9231 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DATA_DISABLE,
9232 ulmu_data_dis) ||
9233 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DISABLE,
9234 ulmu_dis)) {
9235 sigma_dut_print(dut, DUT_MSG_ERROR,
9236 "%s: err in adding vendor_cmd and vendor_data",
9237 __func__);
9238 nlmsg_free(msg);
9239 return -1;
9240 }
9241 nla_nest_end(msg, attr1);
9242 nla_nest_end(msg, params);
9243 nla_nest_end(msg, attr);
9244
9245 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
9246 if (ret) {
9247 sigma_dut_print(dut, DUT_MSG_ERROR,
9248 "%s: err in send_and_recv_msgs, ret=%d",
9249 __func__, ret);
9250 }
9251
9252 return ret;
9253#else /* NL80211_SUPPORT */
9254 sigma_dut_print(dut, DUT_MSG_ERROR,
9255 "OMI TX cannot be processed without NL80211_SUPPORT defined");
9256 return -1;
9257#endif /* NL80211_SUPPORT */
9258}
9259
9260
Jouni Malinen224e3902021-06-09 16:41:27 +03009261static enum sigma_cmd_result
9262cmd_sta_set_wireless_vht(struct sigma_dut *dut, struct sigma_conn *conn,
9263 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009264{
9265 const char *intf = get_param(cmd, "Interface");
9266 const char *val;
Arif Hussaina37e9552018-06-20 17:05:59 -07009267 const char *program;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009268 int tkip = -1;
9269 int wep = -1;
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05309270 int iwpriv_status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009271
Arif Hussaina37e9552018-06-20 17:05:59 -07009272 program = get_param(cmd, "Program");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009273 val = get_param(cmd, "SGI80");
9274 if (val) {
9275 int sgi80;
9276
9277 sgi80 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07009278 run_iwpriv(dut, intf, "shortgi %d", sgi80);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009279 }
9280
9281 val = get_param(cmd, "TxBF");
9282 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009283 switch (get_driver_type(dut)) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07009284 case DRIVER_WCN:
9285 if (sta_set_tx_beamformee(dut, intf, 1)) {
9286 send_resp(dut, conn, SIGMA_ERROR,
9287 "ErrorCode,Failed to set TX beamformee enable");
Jouni Malinen224e3902021-06-09 16:41:27 +03009288 return STATUS_SENT_ERROR;
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07009289 }
9290 break;
9291 case DRIVER_ATHEROS:
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07009292 if (run_iwpriv(dut, intf, "vhtsubfee 1") < 0) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07009293 send_resp(dut, conn, SIGMA_ERROR,
9294 "ErrorCode,Setting vhtsubfee failed");
Jouni Malinen224e3902021-06-09 16:41:27 +03009295 return STATUS_SENT_ERROR;
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07009296 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07009297 if (run_iwpriv(dut, intf, "vhtsubfer 1") < 0) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07009298 send_resp(dut, conn, SIGMA_ERROR,
9299 "ErrorCode,Setting vhtsubfer failed");
Jouni Malinen224e3902021-06-09 16:41:27 +03009300 return STATUS_SENT_ERROR;
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07009301 }
9302 break;
9303 default:
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009304 sigma_dut_print(dut, DUT_MSG_ERROR,
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07009305 "Unsupported driver type");
9306 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009307 }
9308 }
9309
9310 val = get_param(cmd, "MU_TxBF");
9311 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009312 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009313 case DRIVER_ATHEROS:
9314 ath_sta_set_txsp_stream(dut, intf, "1SS");
9315 ath_sta_set_rxsp_stream(dut, intf, "1SS");
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07009316 run_iwpriv(dut, intf, "vhtmubfee 1");
9317 run_iwpriv(dut, intf, "vhtmubfer 1");
Sunil Duttae9e5d12018-06-29 11:50:47 +05309318 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009319 case DRIVER_WCN:
9320 if (wcn_sta_set_sp_stream(dut, intf, "1SS") < 0) {
9321 send_resp(dut, conn, SIGMA_ERROR,
9322 "ErrorCode,Failed to set RX/TXSP_STREAM");
Jouni Malinen224e3902021-06-09 16:41:27 +03009323 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009324 }
Sunil Duttae9e5d12018-06-29 11:50:47 +05309325 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009326 default:
9327 sigma_dut_print(dut, DUT_MSG_ERROR,
9328 "Setting SP_STREAM not supported");
9329 break;
9330 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009331 }
9332
9333 val = get_param(cmd, "LDPC");
9334 if (val) {
9335 int ldpc;
9336
9337 ldpc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05309338 iwpriv_status = run_iwpriv(dut, intf, "ldpc %d", ldpc);
9339 if (iwpriv_status)
9340 sta_config_params(dut, intf, STA_SET_LDPC, ldpc);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009341 }
9342
Amarnath Hullur Subramanyam7bae60e2018-01-31 03:46:50 -08009343 val = get_param(cmd, "BCC");
9344 if (val) {
9345 int bcc;
9346
9347 bcc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
9348 /* use LDPC iwpriv itself to set bcc coding, bcc coding
9349 * is mutually exclusive to bcc */
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05309350 iwpriv_status = run_iwpriv(dut, intf, "ldpc %d", !bcc);
9351 if (iwpriv_status)
9352 sta_config_params(dut, intf, STA_SET_LDPC, !bcc);
Amarnath Hullur Subramanyam7bae60e2018-01-31 03:46:50 -08009353 }
9354
Arif Hussain7b47d2d2018-05-09 10:44:02 -07009355 val = get_param(cmd, "MaxHE-MCS_1SS_RxMapLTE80");
9356 if (val && dut->sta_nss == 1)
9357 cmd_set_max_he_mcs(dut, intf, atoi(val));
9358
9359 val = get_param(cmd, "MaxHE-MCS_2SS_RxMapLTE80");
9360 if (val && dut->sta_nss == 2)
9361 cmd_set_max_he_mcs(dut, intf, atoi(val));
9362
Arif Hussainac6c5112018-05-25 17:34:00 -07009363 val = get_param(cmd, "MCS_FixedRate");
9364 if (val) {
9365#ifdef NL80211_SUPPORT
9366 int mcs, ratecode = 0;
9367 enum he_mcs_config mcs_config;
9368 int ret;
Jouni Malinenb9b671d2019-04-26 13:23:17 +03009369 char buf[60];
Arif Hussainac6c5112018-05-25 17:34:00 -07009370
9371 ratecode = (0x07 & dut->sta_nss) << 5;
9372 mcs = atoi(val);
9373 /* Add the MCS to the ratecode */
9374 if (mcs >= 0 && mcs <= 11) {
9375 ratecode += mcs;
9376 if (dut->device_type == STA_testbed &&
9377 mcs > 7 && mcs <= 11) {
9378 if (mcs <= 9)
9379 mcs_config = HE_80_MCS0_9;
9380 else
9381 mcs_config = HE_80_MCS0_11;
9382 ret = sta_set_he_mcs(dut, intf, mcs_config);
9383 if (ret) {
9384 sigma_dut_print(dut, DUT_MSG_ERROR,
9385 "MCS_FixedRate: mcs setting failed, mcs:%d, mcs_config %d, ret:%d",
9386 mcs, mcs_config, ret);
9387 }
9388 }
9389 snprintf(buf, sizeof(buf),
9390 "iwpriv %s set_11ax_rate 0x%03x",
9391 intf, ratecode);
9392 if (system(buf) != 0) {
9393 sigma_dut_print(dut, DUT_MSG_ERROR,
9394 "MCS_FixedRate: iwpriv setting of 11ax rates 0x%03x failed",
9395 ratecode);
9396 }
9397 } else {
9398 sigma_dut_print(dut, DUT_MSG_ERROR,
9399 "MCS_FixedRate: HE MCS %d not supported",
9400 mcs);
9401 }
9402#else /* NL80211_SUPPORT */
9403 sigma_dut_print(dut, DUT_MSG_ERROR,
9404 "MCS_FixedRate cannot be changed without NL80211_SUPPORT defined");
9405#endif /* NL80211_SUPPORT */
9406 }
9407
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009408 val = get_param(cmd, "opt_md_notif_ie");
9409 if (val) {
9410 char *result = NULL;
9411 char delim[] = ";";
9412 char token[30];
9413 int value, config_val = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05309414 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009415
Peng Xub8fc5cc2017-05-10 17:27:28 -07009416 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05309417 result = strtok_r(token, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009418
9419 /* Extract the NSS information */
9420 if (result) {
9421 value = atoi(result);
9422 switch (value) {
9423 case 1:
9424 config_val = 1;
9425 break;
9426 case 2:
9427 config_val = 3;
9428 break;
9429 case 3:
9430 config_val = 7;
9431 break;
9432 case 4:
9433 config_val = 15;
9434 break;
9435 default:
9436 config_val = 3;
9437 break;
9438 }
9439
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07009440 run_iwpriv(dut, intf, "rxchainmask %d", config_val);
9441 run_iwpriv(dut, intf, "txchainmask %d", config_val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009442
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009443 }
9444
9445 /* Extract the channel width information */
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05309446 result = strtok_r(NULL, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009447 if (result) {
9448 value = atoi(result);
9449 switch (value) {
9450 case 20:
9451 config_val = 0;
9452 break;
9453 case 40:
9454 config_val = 1;
9455 break;
9456 case 80:
9457 config_val = 2;
9458 break;
9459 case 160:
9460 config_val = 3;
9461 break;
9462 default:
9463 config_val = 2;
9464 break;
9465 }
9466
9467 dut->chwidth = config_val;
9468
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07009469 run_iwpriv(dut, intf, "chwidth %d", config_val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009470 }
9471
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07009472 run_iwpriv(dut, intf, "opmode_notify 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009473 }
9474
9475 val = get_param(cmd, "nss_mcs_cap");
9476 if (val) {
9477 int nss, mcs;
9478 char token[20];
9479 char *result = NULL;
9480 unsigned int vht_mcsmap = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05309481 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009482
Peng Xub8fc5cc2017-05-10 17:27:28 -07009483 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05309484 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05309485 if (!result) {
9486 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07009487 "NSS not specified");
9488 send_resp(dut, conn, SIGMA_ERROR,
9489 "errorCode,NSS not specified");
Jouni Malinen224e3902021-06-09 16:41:27 +03009490 return STATUS_SENT_ERROR;
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05309491 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009492 nss = atoi(result);
9493
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07009494 run_iwpriv(dut, intf, "nss %d", nss);
Arif Hussainac6c5112018-05-25 17:34:00 -07009495 dut->sta_nss = nss;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009496
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05309497 result = strtok_r(NULL, ";", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009498 if (result == NULL) {
9499 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07009500 "MCS not specified");
9501 send_resp(dut, conn, SIGMA_ERROR,
9502 "errorCode,MCS not specified");
Jouni Malinen224e3902021-06-09 16:41:27 +03009503 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009504 }
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05309505 result = strtok_r(result, "-", &saveptr);
9506 result = strtok_r(NULL, "-", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05309507 if (!result) {
9508 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07009509 "MCS not specified");
9510 send_resp(dut, conn, SIGMA_ERROR,
9511 "errorCode,MCS not specified");
Jouni Malinen224e3902021-06-09 16:41:27 +03009512 return STATUS_SENT_ERROR;
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05309513 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009514 mcs = atoi(result);
9515
Arif Hussaina37e9552018-06-20 17:05:59 -07009516 if (program && strcasecmp(program, "HE") == 0) {
9517#ifdef NL80211_SUPPORT
9518 enum he_mcs_config mcs_config;
9519 int ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009520
Arif Hussaina37e9552018-06-20 17:05:59 -07009521 if (mcs >= 0 && mcs <= 7) {
9522 mcs_config = HE_80_MCS0_7;
9523 } else if (mcs > 7 && mcs <= 9) {
9524 mcs_config = HE_80_MCS0_9;
9525 } else if (mcs > 9 && mcs <= 11) {
9526 mcs_config = HE_80_MCS0_11;
9527 } else {
9528 sigma_dut_print(dut, DUT_MSG_ERROR,
9529 "nss_mcs_cap: HE: Invalid mcs: %d",
9530 mcs);
9531 send_resp(dut, conn, SIGMA_ERROR,
9532 "errorCode,Invalid MCS");
Jouni Malinen224e3902021-06-09 16:41:27 +03009533 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009534 }
Arif Hussaina37e9552018-06-20 17:05:59 -07009535
9536 ret = sta_set_he_mcs(dut, intf, mcs_config);
9537 if (ret) {
9538 sigma_dut_print(dut, DUT_MSG_ERROR,
9539 "nss_mcs_cap: HE: Setting of MCS failed, mcs_config: %d, ret: %d",
9540 mcs_config, ret);
9541 send_resp(dut, conn, SIGMA_ERROR,
9542 "errorCode,Failed to set MCS");
Jouni Malinen224e3902021-06-09 16:41:27 +03009543 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009544 }
Arif Hussaina37e9552018-06-20 17:05:59 -07009545#else /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009546 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07009547 "nss_mcs_cap: HE: MCS cannot be changed without NL80211_SUPPORT defined");
9548#endif /* NL80211_SUPPORT */
9549 } else {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07009550 run_iwpriv(dut, intf, "vhtmcs %d", mcs);
Arif Hussaina37e9552018-06-20 17:05:59 -07009551
9552 switch (nss) {
9553 case 1:
9554 switch (mcs) {
9555 case 7:
9556 vht_mcsmap = 0xfffc;
9557 break;
9558 case 8:
9559 vht_mcsmap = 0xfffd;
9560 break;
9561 case 9:
9562 vht_mcsmap = 0xfffe;
9563 break;
9564 default:
9565 vht_mcsmap = 0xfffe;
9566 break;
9567 }
9568 break;
9569 case 2:
9570 switch (mcs) {
9571 case 7:
9572 vht_mcsmap = 0xfff0;
9573 break;
9574 case 8:
9575 vht_mcsmap = 0xfff5;
9576 break;
9577 case 9:
9578 vht_mcsmap = 0xfffa;
9579 break;
9580 default:
9581 vht_mcsmap = 0xfffa;
9582 break;
9583 }
9584 break;
9585 case 3:
9586 switch (mcs) {
9587 case 7:
9588 vht_mcsmap = 0xffc0;
9589 break;
9590 case 8:
9591 vht_mcsmap = 0xffd5;
9592 break;
9593 case 9:
9594 vht_mcsmap = 0xffea;
9595 break;
9596 default:
9597 vht_mcsmap = 0xffea;
9598 break;
9599 }
9600 break;
9601 default:
9602 vht_mcsmap = 0xffea;
9603 break;
9604 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07009605 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009606 }
9607 }
9608
9609 /* UNSUPPORTED: val = get_param(cmd, "Tx_lgi_rate"); */
9610
9611 val = get_param(cmd, "Vht_tkip");
9612 if (val)
9613 tkip = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
9614
9615 val = get_param(cmd, "Vht_wep");
9616 if (val)
9617 wep = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
9618
9619 if (tkip != -1 || wep != -1) {
9620 if ((tkip == 1 && wep != 0) || (wep == 1 && tkip != 0)) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07009621 run_iwpriv(dut, intf, "htweptkip 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009622 } else if ((tkip == 0 && wep != 1) || (wep == 0 && tkip != 1)) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07009623 run_iwpriv(dut, intf, "htweptkip 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009624 } else {
Jouni Malinen224e3902021-06-09 16:41:27 +03009625 send_resp(dut, conn, SIGMA_ERROR,
9626 "ErrorCode,mixed mode of VHT TKIP/WEP not supported");
9627 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009628 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009629 }
9630
Kiran Kumar Lokere09dbcef2021-08-09 00:01:41 -07009631 val = get_param(cmd, "TWTSchedSTASupport");
9632 if (val) {
9633 int set_val;
9634
9635 switch (get_driver_type(dut)) {
9636 case DRIVER_WCN:
9637 if (strcasecmp(val, "Enable") == 0) {
9638 set_val = 1;
9639 } else if (strcasecmp(val, "Disable") == 0) {
9640 set_val = 0;
9641 } else {
9642 send_resp(dut, conn, SIGMA_ERROR,
9643 "ErrorCode,Invalid TWTSchedSTASupport");
9644 return STATUS_SENT_ERROR;
9645 }
9646
9647 if (sta_set_bcast_twt_support(dut, intf, set_val)) {
9648 send_resp(dut, conn, SIGMA_ERROR,
9649 "ErrorCode,Failed to set TWTSchedSTASupport");
9650 return STATUS_SENT_ERROR;
9651 }
9652 break;
9653 default:
9654 sigma_dut_print(dut, DUT_MSG_ERROR,
9655 "Setting TWTSchedSTASupport not supported");
9656 break;
9657 }
9658 }
9659
9660 val = get_param(cmd, "MBSSID_RxCtrl");
9661 if (val) {
9662 int set_val;
9663
9664 switch (get_driver_type(dut)) {
9665 case DRIVER_WCN:
9666 if (strcasecmp(val, "Enable") == 0) {
9667 set_val = 1;
9668 } else if (strcasecmp(val, "Disable") == 0) {
9669 set_val = 0;
9670 } else {
9671 send_resp(dut, conn, SIGMA_ERROR,
9672 "ErrorCode,Invalid MBSSID_RxCtrl");
9673 return STATUS_SENT_ERROR;
9674 }
9675
9676 if (sta_set_rx_ctrl_multi_bss(dut, intf, set_val)) {
9677 send_resp(dut, conn, SIGMA_ERROR,
9678 "ErrorCode,Failed to set MBSSID_RxCtrl");
9679 return STATUS_SENT_ERROR;
9680 }
9681 break;
9682 default:
9683 sigma_dut_print(dut, DUT_MSG_ERROR,
9684 "Setting MBSSID_RxCtrl not supported");
9685 break;
9686 }
9687 }
9688
Arif Hussain55f00da2018-07-03 08:28:26 -07009689 val = get_param(cmd, "txBandwidth");
9690 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009691 switch (get_driver_type(dut)) {
Arif Hussain55f00da2018-07-03 08:28:26 -07009692 case DRIVER_WCN:
9693 if (wcn_sta_set_width(dut, intf, val) < 0) {
9694 send_resp(dut, conn, SIGMA_ERROR,
9695 "ErrorCode,Failed to set txBandwidth");
Jouni Malinen224e3902021-06-09 16:41:27 +03009696 return STATUS_SENT_ERROR;
Arif Hussain55f00da2018-07-03 08:28:26 -07009697 }
9698 break;
9699 case DRIVER_ATHEROS:
9700 if (ath_set_width(dut, conn, intf, val) < 0) {
9701 send_resp(dut, conn, SIGMA_ERROR,
9702 "ErrorCode,Failed to set txBandwidth");
Jouni Malinen224e3902021-06-09 16:41:27 +03009703 return STATUS_SENT_ERROR;
Arif Hussain55f00da2018-07-03 08:28:26 -07009704 }
9705 break;
9706 default:
9707 sigma_dut_print(dut, DUT_MSG_ERROR,
9708 "Setting txBandwidth not supported");
9709 break;
9710 }
9711 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009712
Arif Hussain9765f7d2018-07-03 08:28:26 -07009713 val = get_param(cmd, "BeamformeeSTS");
9714 if (val) {
Kiran Kumar Lokerebc89d432018-07-10 12:20:13 -07009715 if (sta_set_tx_beamformee(dut, intf, 1)) {
9716 send_resp(dut, conn, SIGMA_ERROR,
9717 "ErrorCode,Failed to set TX beamformee enable");
Jouni Malinen224e3902021-06-09 16:41:27 +03009718 return STATUS_SENT_ERROR;
Kiran Kumar Lokerebc89d432018-07-10 12:20:13 -07009719 }
9720
Arif Hussain9765f7d2018-07-03 08:28:26 -07009721 if (sta_set_beamformee_sts(dut, intf, atoi(val))) {
9722 send_resp(dut, conn, SIGMA_ERROR,
9723 "ErrorCode,Failed to set BeamformeeSTS");
Jouni Malinen224e3902021-06-09 16:41:27 +03009724 return STATUS_SENT_ERROR;
Arif Hussain9765f7d2018-07-03 08:28:26 -07009725 }
9726 }
9727
Arif Hussain68d23f52018-07-11 13:39:08 -07009728 val = get_param(cmd, "Trig_MAC_Padding_Dur");
9729 if (val) {
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07009730#ifdef NL80211_SUPPORT
9731 enum qca_wlan_he_mac_padding_dur set_val;
9732
9733 switch (atoi(val)) {
9734 case 16:
9735 set_val = QCA_WLAN_HE_16US_OF_PROCESS_TIME;
9736 break;
9737 case 8:
9738 set_val = QCA_WLAN_HE_8US_OF_PROCESS_TIME;
9739 break;
9740 default:
9741 set_val = QCA_WLAN_HE_NO_ADDITIONAL_PROCESS_TIME;
9742 break;
9743 }
9744 if (sta_set_mac_padding_duration(dut, intf, set_val)) {
Arif Hussain68d23f52018-07-11 13:39:08 -07009745 send_resp(dut, conn, SIGMA_ERROR,
9746 "ErrorCode,Failed to set MAC padding duration");
Jouni Malinen224e3902021-06-09 16:41:27 +03009747 return STATUS_SENT_ERROR;
Arif Hussain68d23f52018-07-11 13:39:08 -07009748 }
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07009749#else /* NL80211_SUPPORT */
9750 sigma_dut_print(dut, DUT_MSG_ERROR,
9751 "MAC padding duration cannot be changed without NL80211_SUPPORT defined");
9752#endif /* NL80211_SUPPORT */
Arif Hussain68d23f52018-07-11 13:39:08 -07009753 }
9754
Arif Hussain480d5f42019-03-12 14:40:42 -07009755 val = get_param(cmd, "TWT_ReqSupport");
9756 if (val) {
9757 int set_val;
9758
9759 if (strcasecmp(val, "Enable") == 0) {
9760 set_val = 1;
9761 } else if (strcasecmp(val, "Disable") == 0) {
9762 set_val = 0;
9763 } else {
9764 send_resp(dut, conn, SIGMA_ERROR,
9765 "ErrorCode,Invalid TWT_ReqSupport");
Jouni Malinen224e3902021-06-09 16:41:27 +03009766 return STATUS_SENT_ERROR;
Arif Hussain480d5f42019-03-12 14:40:42 -07009767 }
9768
9769 if (sta_set_twt_req_support(dut, intf, set_val)) {
9770 sigma_dut_print(dut, DUT_MSG_ERROR,
9771 "Failed to set TWT req support %d",
9772 set_val);
9773 send_resp(dut, conn, SIGMA_ERROR,
9774 "ErrorCode,Failed to set TWT_ReqSupport");
Jouni Malinen224e3902021-06-09 16:41:27 +03009775 return STATUS_SENT_ERROR;
Arif Hussain480d5f42019-03-12 14:40:42 -07009776 }
9777 }
9778
Kiran Kumar Lokered0ec5ed2021-04-01 00:15:04 -07009779 val = get_param(cmd, "PreamblePunctRx");
9780 if (val && get_driver_type(dut) == DRIVER_WCN) {
9781 int set_val;
9782
9783 if (strcasecmp(val, "Enable") == 0) {
9784 set_val = 1;
9785 } else if (strcasecmp(val, "Disable") == 0) {
9786 set_val = 0;
9787 } else {
9788 send_resp(dut, conn, SIGMA_ERROR,
9789 "ErrorCode,Invalid PreamblePunctRx");
9790 return STATUS_SENT_ERROR;
9791 }
9792
9793 if (sta_set_punctured_preamble_rx(dut, intf, set_val)) {
9794 sigma_dut_print(dut, DUT_MSG_ERROR,
9795 "Failed to set PreamblePunctRx support %d",
9796 set_val);
9797 send_resp(dut, conn, SIGMA_ERROR,
9798 "ErrorCode,Failed to set PreamblePunctRx");
9799 return STATUS_SENT_ERROR;
9800 }
9801 }
9802
Srinivas Girigowda0525e292020-11-12 13:28:21 -08009803 val = get_param(cmd, "FullBW_ULMUMIMO");
9804 if (val) {
9805 int set_val;
9806
9807 if (strcasecmp(val, "Enable") == 0) {
9808 set_val = 1;
9809 } else if (strcasecmp(val, "Disable") == 0) {
9810 set_val = 0;
9811 } else {
9812 send_resp(dut, conn, SIGMA_ERROR,
9813 "ErrorCode,Invalid FullBW_ULMUMIMO");
9814 return STATUS_SENT_ERROR;
9815 }
9816
9817 if (sta_set_fullbw_ulmumimo(dut, intf, set_val)) {
9818 sigma_dut_print(dut, DUT_MSG_ERROR,
9819 "Failed to set FullBW_ULMUMIMO %d",
9820 set_val);
9821 send_resp(dut, conn, SIGMA_ERROR,
9822 "ErrorCode,Failed to set FullBW_ULMUMIMO");
9823 return STATUS_SENT_ERROR;
9824 }
9825 }
9826
Srinivas Girigowda6707f032020-10-26 15:24:46 -07009827 val = get_param(cmd, "TWTInfoFrameTx");
9828 if (val) {
9829 if (strcasecmp(val, "Enable") == 0) {
9830 /* No-op */
9831 } else if (strcasecmp(val, "Disable") == 0) {
9832 /* No-op */
9833 } else {
9834 send_resp(dut, conn, SIGMA_ERROR,
9835 "ErrorCode,Invalid TWTInfoFrameTx");
9836 return STATUS_SENT_ERROR;
9837 }
9838 }
9839
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07009840 val = get_param(cmd, "MU_EDCA");
9841 if (val && (strcasecmp(val, "Override") == 0)) {
9842 if (sta_set_mu_edca_override(dut, intf, 1)) {
9843 send_resp(dut, conn, SIGMA_ERROR,
9844 "ErrorCode,Failed to set MU EDCA override");
Jouni Malinen224e3902021-06-09 16:41:27 +03009845 return STATUS_SENT_ERROR;
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07009846 }
9847 }
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -07009848
Kiran Kumar Lokerefa7c7b92021-08-09 00:50:55 -07009849 val = get_param(cmd, "PPDUTxType");
9850 if (val && strcasecmp(val, "ER-SU") == 0) {
9851 if (sta_set_er_su_ppdu_type_tx(dut, intf, 1)) {
9852 send_resp(dut, conn, SIGMA_ERROR,
9853 "ErrorCode,Failed to set ER-SU PPDU type Tx");
9854 return STATUS_SENT_ERROR;
9855 }
9856 }
9857
9858 val = get_param(cmd, "RUAllocTone");
9859 if (val && strcasecmp(val, "242") == 0) {
9860 if (sta_set_ru_242_tone_tx(dut, intf, 1)) {
9861 send_resp(dut, conn, SIGMA_ERROR,
9862 "ErrorCode,Failed to set RU 242 tone Tx");
9863 return STATUS_SENT_ERROR;
9864 }
9865 }
9866
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07009867 val = get_param(cmd, "OMControl");
9868 if (val) {
9869 int set_val = 1;
9870
9871 if (strcasecmp(val, "Enable") == 0)
9872 set_val = 1;
9873 else if (strcasecmp(val, "Disable") == 0)
9874 set_val = 0;
9875
9876 if (sta_set_om_ctrl_supp(dut, intf, set_val)) {
9877 send_resp(dut, conn, SIGMA_ERROR,
9878 "ErrorCode,Failed to set OM ctrl supp");
Jouni Malinen224e3902021-06-09 16:41:27 +03009879 return STATUS_SENT_ERROR;
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07009880 }
9881 }
9882
Kiran Kumar Lokere4f2d4b02021-04-01 00:07:39 -07009883 val = get_param(cmd, "BSSMaxIdlePeriod");
9884 if (val && sta_set_bss_max_idle_period(dut, intf, atoi(val))) {
9885 send_resp(dut, conn, SIGMA_ERROR,
9886 "ErrorCode,Failed to set BSS max idle period");
9887 return STATUS_SENT_ERROR;
9888 }
9889
Kiran Kumar Lokere07ad92b2021-08-09 00:27:14 -07009890 val = get_param(cmd, "BSS_max_idle");
9891 if (val) {
9892 int set_val = 0;
9893
9894 if (strcasecmp(val, "Enable") == 0)
9895 set_val = 1;
9896 else if (strcasecmp(val, "Disable") == 0)
9897 set_val = 0;
9898 if (sta_set_bss_max_idle_support(dut, intf, set_val)) {
9899 send_resp(dut, conn, SIGMA_ERROR,
9900 "ErrorCode,Failed to set BSS max idle support");
9901 return STATUS_SENT_ERROR;
9902 }
9903 }
9904
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -07009905 val = get_param(cmd, "ADDBAResp_BufSize");
9906 if (val) {
9907 int buf_size;
9908
9909 if (strcasecmp(val, "gt64") == 0)
9910 buf_size = 256;
9911 else
9912 buf_size = 64;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009913 if (get_driver_type(dut) == DRIVER_WCN &&
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -07009914 sta_set_addba_buf_size(dut, intf, buf_size)) {
9915 send_resp(dut, conn, SIGMA_ERROR,
9916 "ErrorCode,set addbaresp_buff_size failed");
Jouni Malinen224e3902021-06-09 16:41:27 +03009917 return STATUS_SENT_ERROR;
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -07009918 }
9919 }
9920
9921 val = get_param(cmd, "ADDBAReq_BufSize");
9922 if (val) {
9923 int buf_size;
9924
9925 if (strcasecmp(val, "gt64") == 0)
9926 buf_size = 256;
9927 else
9928 buf_size = 64;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009929 if (get_driver_type(dut) == DRIVER_WCN &&
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -07009930 sta_set_addba_buf_size(dut, intf, buf_size)) {
9931 send_resp(dut, conn, SIGMA_ERROR,
9932 "ErrorCode,set addbareq_buff_size failed");
Jouni Malinen224e3902021-06-09 16:41:27 +03009933 return STATUS_SENT_ERROR;
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -07009934 }
9935 }
9936
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009937 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
9938}
9939
9940
9941static int sta_set_wireless_60g(struct sigma_dut *dut,
9942 struct sigma_conn *conn,
9943 struct sigma_cmd *cmd)
9944{
9945 const char *dev_role = get_param(cmd, "DevRole");
9946
9947 if (!dev_role) {
9948 send_resp(dut, conn, SIGMA_INVALID,
9949 "ErrorCode,DevRole not specified");
9950 return 0;
9951 }
9952
9953 if (strcasecmp(dev_role, "PCP") == 0)
9954 return sta_set_60g_pcp(dut, conn, cmd);
9955 if (strcasecmp(dev_role, "STA") == 0)
9956 return sta_set_60g_sta(dut, conn, cmd);
9957 send_resp(dut, conn, SIGMA_INVALID,
9958 "ErrorCode,DevRole not supported");
9959 return 0;
9960}
9961
9962
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05309963static int sta_set_wireless_oce(struct sigma_dut *dut, struct sigma_conn *conn,
9964 struct sigma_cmd *cmd)
9965{
9966 int status;
9967 const char *intf = get_param(cmd, "Interface");
9968 const char *val = get_param(cmd, "DevRole");
9969
9970 if (val && strcasecmp(val, "STA-CFON") == 0) {
9971 status = sta_cfon_set_wireless(dut, conn, cmd);
9972 if (status)
9973 return status;
9974 }
9975 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
9976}
9977
9978
Jouni Malinen67433fc2020-06-26 22:50:33 +03009979static enum sigma_cmd_result
9980sta_set_wireless_wpa3(struct sigma_dut *dut, struct sigma_conn *conn,
9981 struct sigma_cmd *cmd)
Vamsi Krishnac1633d22020-05-06 18:31:21 +05309982{
9983 const char *intf = get_param(cmd, "Interface");
9984 const char *val;
9985
9986 val = get_param(cmd, "ocvc");
9987 if (val)
9988 dut->ocvc = atoi(val);
9989
Jouni Malinen67433fc2020-06-26 22:50:33 +03009990 val = get_param(cmd, "ClientPrivacy");
Veerendranath Jakkam47867202020-12-21 01:53:52 +05309991 if (val && dut->client_privacy != atoi(val) &&
9992 sta_set_client_privacy(dut, conn, intf, atoi(val))) {
9993 send_resp(dut, conn, SIGMA_ERROR,
9994 "errorCode,Failed to configure random MAC address use");
9995 return STATUS_SENT_ERROR;
Jouni Malinen67433fc2020-06-26 22:50:33 +03009996 }
9997
Vamsi Krishnac1633d22020-05-06 18:31:21 +05309998 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
9999}
10000
10001
Jouni Malinenf7222712019-06-13 01:50:21 +030010002static enum sigma_cmd_result cmd_sta_set_wireless(struct sigma_dut *dut,
10003 struct sigma_conn *conn,
10004 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010005{
10006 const char *val;
10007
10008 val = get_param(cmd, "Program");
10009 if (val) {
10010 if (strcasecmp(val, "11n") == 0)
10011 return cmd_sta_set_11n(dut, conn, cmd);
Amarnath Hullur Subramanyam4f860292018-01-31 03:49:35 -080010012 if (strcasecmp(val, "VHT") == 0 || strcasecmp(val, "HE") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010013 return cmd_sta_set_wireless_vht(dut, conn, cmd);
10014 if (strcasecmp(val, "60ghz") == 0)
10015 return sta_set_wireless_60g(dut, conn, cmd);
Ankita Bajaj0d5825b2017-10-25 16:20:17 +053010016 if (strcasecmp(val, "OCE") == 0)
10017 return sta_set_wireless_oce(dut, conn, cmd);
Alexei Avshalom Lazar66bb9972018-12-18 16:01:43 +020010018 /* sta_set_wireless in WPS program is only used for 60G */
10019 if (is_60g_sigma_dut(dut))
10020 return sta_set_wireless_60g(dut, conn, cmd);
Vamsi Krishnac1633d22020-05-06 18:31:21 +053010021 if (strcasecmp(val, "WPA3") == 0)
10022 return sta_set_wireless_wpa3(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010023 send_resp(dut, conn, SIGMA_ERROR,
10024 "ErrorCode,Program value not supported");
10025 } else {
10026 send_resp(dut, conn, SIGMA_ERROR,
10027 "ErrorCode,Program argument not available");
10028 }
10029
10030 return 0;
10031}
10032
10033
10034static void ath_sta_inject_frame(struct sigma_dut *dut, const char *intf,
10035 int tid)
10036{
10037 char buf[100];
10038 int tid_to_dscp [] = { 0x00, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0 };
10039
Pradeep Reddy POTTETId31d1322016-10-13 17:22:03 +053010040 if (tid < 0 ||
10041 tid >= (int) (sizeof(tid_to_dscp) / sizeof(tid_to_dscp[0]))) {
10042 sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported TID: %d", tid);
10043 return;
10044 }
10045
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010046 /*
10047 * Two ways to ensure that addba request with a
10048 * non zero TID could be sent out. EV 117296
10049 */
10050 snprintf(buf, sizeof(buf),
10051 "ping -c 8 -Q %d `arp -a | grep wlan0 | awk '{print $2}' | tr -d '()'`",
10052 tid);
10053 if (system(buf) != 0) {
10054 sigma_dut_print(dut, DUT_MSG_ERROR,
10055 "Ping did not send out");
10056 }
10057
10058 snprintf(buf, sizeof(buf),
10059 "iwconfig %s | grep Access | awk '{print $6}' > %s",
10060 intf, VI_QOS_TMP_FILE);
10061 if (system(buf) != 0)
10062 return;
10063
10064 snprintf(buf, sizeof(buf),
10065 "ifconfig %s | grep HWaddr | cut -b 39-56 >> %s",
10066 intf, VI_QOS_TMP_FILE);
10067 if (system(buf) != 0)
10068 sigma_dut_print(dut, DUT_MSG_ERROR, "HWaddr matching failed");
10069
10070 snprintf(buf,sizeof(buf), "sed -n '3,$p' %s >> %s",
10071 VI_QOS_REFFILE, VI_QOS_TMP_FILE);
10072 if (system(buf) != 0) {
10073 sigma_dut_print(dut, DUT_MSG_ERROR,
10074 "VI_QOS_TEMP_FILE generation error failed");
10075 }
10076 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
10077 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
10078 if (system(buf) != 0) {
10079 sigma_dut_print(dut, DUT_MSG_ERROR,
10080 "VI_QOS_FILE generation failed");
10081 }
10082
10083 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
10084 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
10085 if (system(buf) != 0) {
10086 sigma_dut_print(dut, DUT_MSG_ERROR,
10087 "VI_QOS_FILE generation failed");
10088 }
10089
10090 snprintf(buf, sizeof(buf), "ethinject %s %s", intf, VI_QOS_FILE);
10091 if (system(buf) != 0) {
10092 }
10093}
10094
10095
10096static int ath_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
10097 struct sigma_cmd *cmd)
10098{
10099 const char *intf = get_param(cmd, "Interface");
10100 const char *val;
10101 int tid = 0;
10102 char buf[100];
10103
10104 val = get_param(cmd, "TID");
10105 if (val) {
10106 tid = atoi(val);
10107 if (tid)
10108 ath_sta_inject_frame(dut, intf, tid);
10109 }
10110
10111 /* Command sequence for ADDBA request on Peregrine based devices */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010112 run_iwpriv(dut, intf, "setaddbaoper 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010113
10114 snprintf(buf, sizeof(buf), "wifitool %s senddelba 1 %d 1 4", intf, tid);
10115 if (system(buf) != 0) {
10116 sigma_dut_print(dut, DUT_MSG_ERROR,
10117 "wifitool senddelba failed");
10118 }
10119
10120 snprintf(buf, sizeof(buf), "wifitool %s sendaddba 1 %d 64", intf, tid);
10121 if (system(buf) != 0) {
10122 sigma_dut_print(dut, DUT_MSG_ERROR,
10123 "wifitool sendaddba failed");
10124 }
10125
10126 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
10127
10128 return 1;
10129}
10130
10131
Lior David9981b512017-01-20 13:16:40 +020010132#ifdef __linux__
10133
10134static int wil6210_send_addba(struct sigma_dut *dut, const char *dest_mac,
10135 int agg_size)
10136{
10137 char dir[128], buf[128];
10138 FILE *f;
10139 regex_t re;
10140 regmatch_t m[2];
Jouni Malinen3aa72862019-05-29 23:14:51 +030010141 int rc, ret = -1, vring_id, found, res;
Lior David9981b512017-01-20 13:16:40 +020010142
10143 if (wil6210_get_debugfs_dir(dut, dir, sizeof(dir))) {
10144 sigma_dut_print(dut, DUT_MSG_ERROR,
10145 "failed to get wil6210 debugfs dir");
10146 return -1;
10147 }
10148
Jouni Malinen3aa72862019-05-29 23:14:51 +030010149 res = snprintf(buf, sizeof(buf), "%s/vrings", dir);
10150 if (res < 0 || res >= sizeof(buf))
10151 return -1;
Lior David9981b512017-01-20 13:16:40 +020010152 f = fopen(buf, "r");
10153 if (!f) {
10154 sigma_dut_print(dut, DUT_MSG_ERROR, "failed to open: %s", buf);
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +020010155 /* newer wil6210 driver renamed file to "rings" */
Jouni Malinen3aa72862019-05-29 23:14:51 +030010156 res = snprintf(buf, sizeof(buf), "%s/rings", dir);
10157 if (res < 0 || res >= sizeof(buf))
10158 return -1;
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +020010159 f = fopen(buf, "r");
10160 if (!f) {
10161 sigma_dut_print(dut, DUT_MSG_ERROR,
10162 "failed to open: %s", buf);
10163 return -1;
10164 }
Lior David9981b512017-01-20 13:16:40 +020010165 }
10166
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +020010167 /* can be either VRING tx... or RING... */
10168 if (regcomp(&re, "RING tx_[ \t]*([0-9]+)", REG_EXTENDED)) {
Lior David9981b512017-01-20 13:16:40 +020010169 sigma_dut_print(dut, DUT_MSG_ERROR, "regcomp failed");
10170 goto out;
10171 }
10172
10173 /* find TX VRING for the mac address */
10174 found = 0;
10175 while (fgets(buf, sizeof(buf), f)) {
10176 if (strcasestr(buf, dest_mac)) {
10177 found = 1;
10178 break;
10179 }
10180 }
10181
10182 if (!found) {
10183 sigma_dut_print(dut, DUT_MSG_ERROR,
10184 "no TX VRING for %s", dest_mac);
10185 goto out;
10186 }
10187
10188 /* extract VRING ID, "VRING tx_<id> = {" */
10189 if (!fgets(buf, sizeof(buf), f)) {
10190 sigma_dut_print(dut, DUT_MSG_ERROR,
10191 "no VRING start line for %s", dest_mac);
10192 goto out;
10193 }
10194
10195 rc = regexec(&re, buf, 2, m, 0);
10196 regfree(&re);
10197 if (rc || m[1].rm_so < 0) {
10198 sigma_dut_print(dut, DUT_MSG_ERROR,
10199 "no VRING TX ID for %s", dest_mac);
10200 goto out;
10201 }
10202 buf[m[1].rm_eo] = 0;
10203 vring_id = atoi(&buf[m[1].rm_so]);
10204
10205 /* send the addba command */
10206 fclose(f);
Jouni Malinen3aa72862019-05-29 23:14:51 +030010207 res = snprintf(buf, sizeof(buf), "%s/back", dir);
10208 if (res < 0 || res >= sizeof(buf))
10209 return -1;
Lior David9981b512017-01-20 13:16:40 +020010210 f = fopen(buf, "w");
10211 if (!f) {
10212 sigma_dut_print(dut, DUT_MSG_ERROR,
10213 "failed to open: %s", buf);
10214 return -1;
10215 }
10216
10217 fprintf(f, "add %d %d\n", vring_id, agg_size);
10218
10219 ret = 0;
10220
10221out:
10222 fclose(f);
10223
10224 return ret;
10225}
10226
10227
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +020010228int send_addba_60g(struct sigma_dut *dut, struct sigma_conn *conn,
10229 struct sigma_cmd *cmd, const char *mac_param)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010230{
10231 const char *val;
10232 int tid = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010233
10234 val = get_param(cmd, "TID");
10235 if (val) {
10236 tid = atoi(val);
10237 if (tid != 0) {
10238 sigma_dut_print(dut, DUT_MSG_ERROR,
10239 "Ignore TID %d for send_addba use TID 0 for 60g since only 0 required on TX",
10240 tid);
10241 }
10242 }
10243
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +020010244 val = get_param(cmd, mac_param);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010245 if (!val) {
10246 sigma_dut_print(dut, DUT_MSG_ERROR,
10247 "Currently not supporting addba for 60G without Dest_mac");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020010248 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010249 }
10250
Lior David9981b512017-01-20 13:16:40 +020010251 if (wil6210_send_addba(dut, val, dut->back_rcv_buf))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010252 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010253
10254 return 1;
10255}
10256
Lior David9981b512017-01-20 13:16:40 +020010257#endif /* __linux__ */
10258
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010259
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080010260static int wcn_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
10261 struct sigma_cmd *cmd)
10262{
10263#ifdef NL80211_SUPPORT
10264 const char *intf = get_param(cmd, "Interface");
10265 const char *val;
10266 int tid = -1;
10267 int bufsize = 64;
10268 struct nl_msg *msg;
10269 int ret = 0;
10270 struct nlattr *params;
10271 int ifindex;
10272
10273 val = get_param(cmd, "TID");
10274 if (val)
10275 tid = atoi(val);
10276
10277 if (tid == -1) {
10278 send_resp(dut, conn, SIGMA_ERROR,
10279 "ErrorCode,sta_send_addba tid invalid");
10280 return 0;
10281 }
10282
10283 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
10284
10285 ifindex = if_nametoindex(intf);
10286 if (ifindex == 0) {
10287 sigma_dut_print(dut, DUT_MSG_ERROR,
10288 "%s: Index for interface %s failed",
10289 __func__, intf);
10290 send_resp(dut, conn, SIGMA_ERROR,
10291 "ErrorCode,sta_send_addba interface invalid");
10292 return 0;
10293 }
10294
10295 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
10296 NL80211_CMD_VENDOR)) ||
10297 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
10298 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
10299 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
10300 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
10301 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
10302 nla_put_u8(msg,
10303 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADD_DEL_BA_SESSION,
10304 QCA_WLAN_ADD_BA) ||
10305 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BA_TID,
10306 tid) ||
Kiran Kumar Lokere26e27582018-08-01 16:18:34 -070010307 nla_put_u16(msg,
10308 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE,
10309 bufsize)) {
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080010310 sigma_dut_print(dut, DUT_MSG_ERROR,
10311 "%s: err in adding vendor_cmd and vendor_data",
10312 __func__);
10313 nlmsg_free(msg);
10314 send_resp(dut, conn, SIGMA_ERROR,
10315 "ErrorCode,sta_send_addba err in adding vendor_cmd and vendor_data");
10316 return 0;
10317 }
10318 nla_nest_end(msg, params);
10319
10320 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
10321 if (ret) {
10322 sigma_dut_print(dut, DUT_MSG_ERROR,
10323 "%s: err in send_and_recv_msgs, ret=%d",
10324 __func__, ret);
Sunil Dutt30605592018-05-04 20:35:50 +053010325 if (ret == -EOPNOTSUPP)
10326 return 1;
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080010327 send_resp(dut, conn, SIGMA_ERROR,
10328 "ErrorCode,sta_send_addba err in send_and_recv_msgs");
10329 return 0;
10330 }
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080010331#else /* NL80211_SUPPORT */
10332 sigma_dut_print(dut, DUT_MSG_ERROR,
10333 "sta_send_addba not supported without NL80211_SUPPORT defined");
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080010334#endif /* NL80211_SUPPORT */
Sunil Dutt30605592018-05-04 20:35:50 +053010335
10336 return 1;
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080010337}
10338
10339
Jouni Malinenf7222712019-06-13 01:50:21 +030010340static enum sigma_cmd_result cmd_sta_send_addba(struct sigma_dut *dut,
10341 struct sigma_conn *conn,
10342 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010343{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010344 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010345 case DRIVER_ATHEROS:
10346 return ath_sta_send_addba(dut, conn, cmd);
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080010347 case DRIVER_WCN:
10348 return wcn_sta_send_addba(dut, conn, cmd);
Lior David9981b512017-01-20 13:16:40 +020010349#ifdef __linux__
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010350 case DRIVER_WIL6210:
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +020010351 return send_addba_60g(dut, conn, cmd, "Dest_mac");
Lior David9981b512017-01-20 13:16:40 +020010352#endif /* __linux__ */
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010353 default:
10354 /*
10355 * There is no driver specific implementation for other drivers.
10356 * Ignore the command and report COMPLETE since the following
10357 * throughput test operation will end up sending ADDBA anyway.
10358 */
10359 return 1;
10360 }
10361}
10362
10363
10364int inject_eth_frame(int s, const void *data, size_t len,
10365 unsigned short ethtype, char *dst, char *src)
10366{
10367 struct iovec iov[4] = {
10368 {
10369 .iov_base = dst,
10370 .iov_len = ETH_ALEN,
10371 },
10372 {
10373 .iov_base = src,
10374 .iov_len = ETH_ALEN,
10375 },
10376 {
10377 .iov_base = &ethtype,
10378 .iov_len = sizeof(unsigned short),
10379 },
10380 {
10381 .iov_base = (void *) data,
10382 .iov_len = len,
10383 }
10384 };
10385 struct msghdr msg = {
10386 .msg_name = NULL,
10387 .msg_namelen = 0,
10388 .msg_iov = iov,
10389 .msg_iovlen = 4,
10390 .msg_control = NULL,
10391 .msg_controllen = 0,
10392 .msg_flags = 0,
10393 };
10394
10395 return sendmsg(s, &msg, 0);
10396}
10397
10398#if defined(__linux__) || defined(__QNXNTO__)
10399
10400int inject_frame(int s, const void *data, size_t len, int encrypt)
10401{
10402#define IEEE80211_RADIOTAP_F_WEP 0x04
10403#define IEEE80211_RADIOTAP_F_FRAG 0x08
10404 unsigned char rtap_hdr[] = {
10405 0x00, 0x00, /* radiotap version */
10406 0x0e, 0x00, /* radiotap length */
10407 0x02, 0xc0, 0x00, 0x00, /* bmap: flags, tx and rx flags */
10408 IEEE80211_RADIOTAP_F_FRAG, /* F_FRAG (fragment if required) */
10409 0x00, /* padding */
10410 0x00, 0x00, /* RX and TX flags to indicate that */
10411 0x00, 0x00, /* this is the injected frame directly */
10412 };
10413 struct iovec iov[2] = {
10414 {
10415 .iov_base = &rtap_hdr,
10416 .iov_len = sizeof(rtap_hdr),
10417 },
10418 {
10419 .iov_base = (void *) data,
10420 .iov_len = len,
10421 }
10422 };
10423 struct msghdr msg = {
10424 .msg_name = NULL,
10425 .msg_namelen = 0,
10426 .msg_iov = iov,
10427 .msg_iovlen = 2,
10428 .msg_control = NULL,
10429 .msg_controllen = 0,
10430 .msg_flags = 0,
10431 };
10432
10433 if (encrypt)
10434 rtap_hdr[8] |= IEEE80211_RADIOTAP_F_WEP;
10435
10436 return sendmsg(s, &msg, 0);
10437}
10438
10439
10440int open_monitor(const char *ifname)
10441{
10442#ifdef __QNXNTO__
10443 struct sockaddr_dl ll;
10444 int s;
10445
10446 memset(&ll, 0, sizeof(ll));
10447 ll.sdl_family = AF_LINK;
10448 ll.sdl_index = if_nametoindex(ifname);
10449 if (ll.sdl_index == 0) {
10450 perror("if_nametoindex");
10451 return -1;
10452 }
10453 s = socket(PF_INET, SOCK_RAW, 0);
10454#else /* __QNXNTO__ */
10455 struct sockaddr_ll ll;
10456 int s;
10457
10458 memset(&ll, 0, sizeof(ll));
10459 ll.sll_family = AF_PACKET;
10460 ll.sll_ifindex = if_nametoindex(ifname);
10461 if (ll.sll_ifindex == 0) {
10462 perror("if_nametoindex");
10463 return -1;
10464 }
10465 s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
10466#endif /* __QNXNTO__ */
10467 if (s < 0) {
10468 perror("socket[PF_PACKET,SOCK_RAW]");
10469 return -1;
10470 }
10471
10472 if (bind(s, (struct sockaddr *) &ll, sizeof(ll)) < 0) {
10473 perror("monitor socket bind");
10474 close(s);
10475 return -1;
10476 }
10477
10478 return s;
10479}
10480
10481
10482static int hex2num(char c)
10483{
10484 if (c >= '0' && c <= '9')
10485 return c - '0';
10486 if (c >= 'a' && c <= 'f')
10487 return c - 'a' + 10;
10488 if (c >= 'A' && c <= 'F')
10489 return c - 'A' + 10;
10490 return -1;
10491}
10492
10493
10494int hwaddr_aton(const char *txt, unsigned char *addr)
10495{
10496 int i;
10497
10498 for (i = 0; i < 6; i++) {
10499 int a, b;
10500
10501 a = hex2num(*txt++);
10502 if (a < 0)
10503 return -1;
10504 b = hex2num(*txt++);
10505 if (b < 0)
10506 return -1;
10507 *addr++ = (a << 4) | b;
10508 if (i < 5 && *txt++ != ':')
10509 return -1;
10510 }
10511
10512 return 0;
10513}
10514
10515#endif /* defined(__linux__) || defined(__QNXNTO__) */
10516
Veerendranath Jakkam49774122020-07-05 09:52:18 +053010517
10518#ifdef NL80211_SUPPORT
10519static int nl80211_send_frame_cmd(struct sigma_dut *dut, const char *intf,
10520 const u8 *data, size_t data_len, int freq)
10521{
10522 struct nl_msg *msg;
10523 int ret = 0;
10524 int ifindex;
10525
10526 ifindex = if_nametoindex(intf);
10527 if (ifindex == 0) {
10528 sigma_dut_print(dut, DUT_MSG_ERROR,
10529 "%s: Index for interface %s failed",
10530 __func__, intf);
10531 return -1;
10532 }
10533
10534 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
10535 NL80211_CMD_FRAME)) ||
10536 (freq && nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq)) ||
10537 nla_put(msg, NL80211_ATTR_FRAME, data_len, data)) {
10538 sigma_dut_print(dut, DUT_MSG_ERROR,
10539 "%s: Error in adding NL80211_CMD_FRAME",
10540 __func__);
10541 nlmsg_free(msg);
10542 return -1;
10543 }
10544
10545 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
10546 if (ret) {
10547 sigma_dut_print(dut, DUT_MSG_ERROR,
10548 "nl80211: Frame command failed: ret=%d (%s) req=%u",
10549 ret, strerror(-ret), freq);
10550 return -1;
10551 }
10552
10553 return 0;
10554}
10555#endif /* NL80211_SUPPORT */
10556
10557
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010558enum send_frame_type {
10559 DISASSOC, DEAUTH, SAQUERY, AUTH, ASSOCREQ, REASSOCREQ, DLS_REQ
10560};
10561enum send_frame_protection {
10562 CORRECT_KEY, INCORRECT_KEY, UNPROTECTED
10563};
10564
10565
10566static int sta_inject_frame(struct sigma_dut *dut, struct sigma_conn *conn,
Veerendranath Jakkam49774122020-07-05 09:52:18 +053010567 const char *intf, enum send_frame_type frame,
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010568 enum send_frame_protection protected,
Veerendranath Jakkam49774122020-07-05 09:52:18 +053010569 const char *dest, int use_monitor)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010570{
10571#ifdef __linux__
10572 unsigned char buf[1000], *pos;
10573 int s, res;
10574 char bssid[20], addr[20];
10575 char result[32], ssid[100];
10576 size_t ssid_len;
10577
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010578 if (get_wpa_status(get_station_ifname(dut), "wpa_state", result,
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010579 sizeof(result)) < 0 ||
10580 strncmp(result, "COMPLETED", 9) != 0) {
10581 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Not connected");
10582 return 0;
10583 }
10584
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010585 if (get_wpa_status(get_station_ifname(dut), "bssid",
10586 bssid, sizeof(bssid)) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010587 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
10588 "current BSSID");
10589 return 0;
10590 }
10591
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010592 if (get_wpa_status(get_station_ifname(dut), "address",
10593 addr, sizeof(addr)) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010594 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
10595 "own MAC address");
10596 return 0;
10597 }
10598
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010599 if (get_wpa_status(get_station_ifname(dut), "ssid", ssid, sizeof(ssid))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010600 < 0) {
10601 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
10602 "current SSID");
10603 return 0;
10604 }
10605 ssid_len = strlen(ssid);
10606
10607 pos = buf;
10608
10609 /* Frame Control */
10610 switch (frame) {
10611 case DISASSOC:
10612 *pos++ = 0xa0;
10613 break;
10614 case DEAUTH:
10615 *pos++ = 0xc0;
10616 break;
10617 case SAQUERY:
10618 *pos++ = 0xd0;
10619 break;
10620 case AUTH:
10621 *pos++ = 0xb0;
10622 break;
10623 case ASSOCREQ:
10624 *pos++ = 0x00;
10625 break;
10626 case REASSOCREQ:
10627 *pos++ = 0x20;
10628 break;
10629 case DLS_REQ:
10630 *pos++ = 0xd0;
10631 break;
10632 }
10633
10634 if (protected == INCORRECT_KEY)
10635 *pos++ = 0x40; /* Set Protected field to 1 */
10636 else
10637 *pos++ = 0x00;
10638
10639 /* Duration */
10640 *pos++ = 0x00;
10641 *pos++ = 0x00;
10642
10643 /* addr1 = DA (current AP) */
10644 hwaddr_aton(bssid, pos);
10645 pos += 6;
10646 /* addr2 = SA (own address) */
10647 hwaddr_aton(addr, pos);
10648 pos += 6;
10649 /* addr3 = BSSID (current AP) */
10650 hwaddr_aton(bssid, pos);
10651 pos += 6;
10652
10653 /* Seq# (to be filled by driver/mac80211) */
10654 *pos++ = 0x00;
10655 *pos++ = 0x00;
10656
10657 if (protected == INCORRECT_KEY) {
10658 /* CCMP parameters */
10659 memcpy(pos, "\x61\x01\x00\x20\x00\x10\x00\x00", 8);
10660 pos += 8;
10661 }
10662
10663 if (protected == INCORRECT_KEY) {
10664 switch (frame) {
10665 case DEAUTH:
10666 /* Reason code (encrypted) */
10667 memcpy(pos, "\xa7\x39", 2);
10668 pos += 2;
10669 break;
10670 case DISASSOC:
10671 /* Reason code (encrypted) */
10672 memcpy(pos, "\xa7\x39", 2);
10673 pos += 2;
10674 break;
10675 case SAQUERY:
10676 /* Category|Action|TransID (encrypted) */
10677 memcpy(pos, "\x6f\xbd\xe9\x4d", 4);
10678 pos += 4;
10679 break;
10680 default:
10681 return -1;
10682 }
10683
10684 /* CCMP MIC */
10685 memcpy(pos, "\xc8\xd8\x3b\x06\x5d\xb7\x25\x68", 8);
10686 pos += 8;
10687 } else {
10688 switch (frame) {
10689 case DEAUTH:
10690 /* reason code = 8 */
10691 *pos++ = 0x08;
10692 *pos++ = 0x00;
10693 break;
10694 case DISASSOC:
10695 /* reason code = 8 */
10696 *pos++ = 0x08;
10697 *pos++ = 0x00;
10698 break;
10699 case SAQUERY:
10700 /* Category - SA Query */
10701 *pos++ = 0x08;
10702 /* SA query Action - Request */
10703 *pos++ = 0x00;
10704 /* Transaction ID */
10705 *pos++ = 0x12;
10706 *pos++ = 0x34;
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +053010707 if (dut->saquery_oci_freq) {
10708 /* OCI IE - Extended ID */
10709 *pos++ = 0xFF;
10710 *pos++ = 0x04;
10711 *pos++ = 0x36;
10712 /* Operating Class */
10713 *pos++ = 0x74;
10714 /* Primary Channel */
10715 *pos++ = freq_to_channel(dut->saquery_oci_freq);
10716 /* Frequency Segment 1 Channel Number */
10717 *pos++ = 0x00;
10718 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010719 break;
10720 case AUTH:
10721 /* Auth Alg (Open) */
10722 *pos++ = 0x00;
10723 *pos++ = 0x00;
10724 /* Seq# */
10725 *pos++ = 0x01;
10726 *pos++ = 0x00;
10727 /* Status code */
10728 *pos++ = 0x00;
10729 *pos++ = 0x00;
10730 break;
10731 case ASSOCREQ:
10732 /* Capability Information */
10733 *pos++ = 0x31;
10734 *pos++ = 0x04;
10735 /* Listen Interval */
10736 *pos++ = 0x0a;
10737 *pos++ = 0x00;
10738 /* SSID */
10739 *pos++ = 0x00;
10740 *pos++ = ssid_len;
10741 memcpy(pos, ssid, ssid_len);
10742 pos += ssid_len;
10743 /* Supported Rates */
10744 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
10745 10);
10746 pos += 10;
10747 /* Extended Supported Rates */
10748 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
10749 pos += 6;
10750 /* RSN */
10751 memcpy(pos, "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00"
10752 "\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x02\xc0"
10753 "\x00\x00\x00\x00\x0f\xac\x06", 28);
10754 pos += 28;
10755 break;
10756 case REASSOCREQ:
10757 /* Capability Information */
10758 *pos++ = 0x31;
10759 *pos++ = 0x04;
10760 /* Listen Interval */
10761 *pos++ = 0x0a;
10762 *pos++ = 0x00;
10763 /* Current AP */
10764 hwaddr_aton(bssid, pos);
10765 pos += 6;
10766 /* SSID */
10767 *pos++ = 0x00;
10768 *pos++ = ssid_len;
10769 memcpy(pos, ssid, ssid_len);
10770 pos += ssid_len;
10771 /* Supported Rates */
10772 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
10773 10);
10774 pos += 10;
10775 /* Extended Supported Rates */
10776 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
10777 pos += 6;
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +053010778 /* RSNE - Group and Pairwise ciphers */
10779 memcpy(pos,
10780 "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04",
10781 14);
10782 pos += 14;
10783 /* RSNE - AKM Suite count */
10784 *pos++ = 0x01;
10785 *pos++ = 0x00;
10786 /* RSNE - AKM Suites */
10787 if (dut->program == PROGRAM_WPA3)
10788 memcpy(pos, "\x00\x0f\xac\x08", 4);
10789 else
10790 memcpy(pos, "\x00\x0f\xac\x02", 4);
10791 pos += 4;
10792 /* RSNE - Capabilities */
10793 *pos++ = 0xc0;
10794 if (dut->ocvc)
10795 *pos++ = 0x40;
10796 else
10797 *pos++ = 0x00;
10798 /* RSNE - PMKID list and Group Management Ciphers */
10799 memcpy(pos, "\x00\x00\x00\x0f\xac\x06", 6);
10800 pos += 6;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010801 break;
10802 case DLS_REQ:
10803 /* Category - DLS */
10804 *pos++ = 0x02;
10805 /* DLS Action - Request */
10806 *pos++ = 0x00;
10807 /* Destination MACAddress */
10808 if (dest)
10809 hwaddr_aton(dest, pos);
10810 else
10811 memset(pos, 0, 6);
10812 pos += 6;
10813 /* Source MACAddress */
10814 hwaddr_aton(addr, pos);
10815 pos += 6;
10816 /* Capability Information */
10817 *pos++ = 0x10; /* Privacy */
10818 *pos++ = 0x06; /* QoS */
10819 /* DLS Timeout Value */
10820 *pos++ = 0x00;
10821 *pos++ = 0x01;
10822 /* Supported rates */
10823 *pos++ = 0x01;
10824 *pos++ = 0x08;
10825 *pos++ = 0x0c; /* 6 Mbps */
10826 *pos++ = 0x12; /* 9 Mbps */
10827 *pos++ = 0x18; /* 12 Mbps */
10828 *pos++ = 0x24; /* 18 Mbps */
10829 *pos++ = 0x30; /* 24 Mbps */
10830 *pos++ = 0x48; /* 36 Mbps */
10831 *pos++ = 0x60; /* 48 Mbps */
10832 *pos++ = 0x6c; /* 54 Mbps */
10833 /* TODO: Extended Supported Rates */
10834 /* TODO: HT Capabilities */
10835 break;
10836 }
10837 }
10838
Veerendranath Jakkam49774122020-07-05 09:52:18 +053010839 if (use_monitor) {
10840 s = open_monitor("sigmadut");
10841 if (s < 0) {
10842 send_resp(dut, conn, SIGMA_ERROR,
10843 "errorCode,Failed to open monitor socket");
10844 return 0;
10845 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010846
Veerendranath Jakkam49774122020-07-05 09:52:18 +053010847 res = inject_frame(s, buf, pos - buf, protected == CORRECT_KEY);
10848 if (res < 0) {
10849 send_resp(dut, conn, SIGMA_ERROR,
10850 "errorCode,Failed to inject frame");
10851 close(s);
10852 return 0;
10853 }
10854 if (res < pos - buf) {
10855 send_resp(dut, conn, SIGMA_ERROR,
10856 "errorCode,Only partial frame sent");
10857 close(s);
10858 return 0;
10859 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010860
Veerendranath Jakkam49774122020-07-05 09:52:18 +053010861 close(s);
10862 } else {
10863#ifdef NL80211_SUPPORT
10864 int freq;
10865 char freq_str[10];
10866
10867 if (get_wpa_status(get_station_ifname(dut), "freq",
10868 freq_str, sizeof(freq_str)) < 0) {
10869 send_resp(dut, conn, SIGMA_ERROR,
10870 "errorCode,Could not get current operating frequency");
10871 return 0;
10872 }
10873 freq = atoi(freq_str);
10874
10875 if (nl80211_send_frame_cmd(dut, intf, buf, pos - buf, freq)) {
10876 send_resp(dut, conn, SIGMA_ERROR,
10877 "errorCode,Failed to inject frame");
10878 return 0;
10879 }
10880#else /* NL80211_SUPPORT */
10881 send_resp(dut, conn, SIGMA_ERROR,
10882 "errorCode,Failed to inject frame (no NL80211_SUPPORT)");
10883 return 0;
10884#endif /* NL80211_SUPPORT */
10885 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010886
10887 return 1;
10888#else /* __linux__ */
10889 send_resp(dut, conn, SIGMA_ERROR, "errorCode,sta_send_frame not "
10890 "yet supported");
10891 return 0;
10892#endif /* __linux__ */
10893}
10894
10895
10896static int cmd_sta_send_frame_tdls(struct sigma_dut *dut,
10897 struct sigma_conn *conn,
10898 struct sigma_cmd *cmd)
10899{
10900 const char *intf = get_param(cmd, "Interface");
10901 const char *sta, *val;
10902 unsigned char addr[ETH_ALEN];
10903 char buf[100];
10904
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +030010905 if (!intf)
10906 return -1;
10907
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010908 sta = get_param(cmd, "peer");
10909 if (sta == NULL)
10910 sta = get_param(cmd, "station");
10911 if (sta == NULL) {
10912 send_resp(dut, conn, SIGMA_ERROR,
10913 "ErrorCode,Missing peer address");
10914 return 0;
10915 }
10916 if (hwaddr_aton(sta, addr) < 0) {
10917 send_resp(dut, conn, SIGMA_ERROR,
10918 "ErrorCode,Invalid peer address");
10919 return 0;
10920 }
10921
10922 val = get_param(cmd, "type");
10923 if (val == NULL)
10924 return -1;
10925
10926 if (strcasecmp(val, "DISCOVERY") == 0) {
10927 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", sta);
10928 if (wpa_command(intf, buf) < 0) {
10929 send_resp(dut, conn, SIGMA_ERROR,
10930 "ErrorCode,Failed to send TDLS discovery");
10931 return 0;
10932 }
10933 return 1;
10934 }
10935
10936 if (strcasecmp(val, "SETUP") == 0) {
10937 int status = 0, timeout = 0;
10938
10939 val = get_param(cmd, "Status");
10940 if (val)
10941 status = atoi(val);
10942
10943 val = get_param(cmd, "Timeout");
10944 if (val)
10945 timeout = atoi(val);
10946
10947 if (status != 0 && status != 37) {
10948 send_resp(dut, conn, SIGMA_ERROR,
10949 "ErrorCode,Unsupported status value");
10950 return 0;
10951 }
10952
10953 if (timeout != 0 && timeout != 301) {
10954 send_resp(dut, conn, SIGMA_ERROR,
10955 "ErrorCode,Unsupported timeout value");
10956 return 0;
10957 }
10958
10959 if (status && timeout) {
10960 send_resp(dut, conn, SIGMA_ERROR,
10961 "ErrorCode,Unsupported timeout+status "
10962 "combination");
10963 return 0;
10964 }
10965
10966 if (status == 37 &&
10967 wpa_command(intf, "SET tdls_testing 0x200")) {
10968 send_resp(dut, conn, SIGMA_ERROR,
10969 "ErrorCode,Failed to enable "
10970 "decline setup response test mode");
10971 return 0;
10972 }
10973
10974 if (timeout == 301) {
10975 int res;
10976 if (dut->no_tpk_expiration)
10977 res = wpa_command(intf,
10978 "SET tdls_testing 0x108");
10979 else
10980 res = wpa_command(intf,
10981 "SET tdls_testing 0x8");
10982 if (res) {
10983 send_resp(dut, conn, SIGMA_ERROR,
10984 "ErrorCode,Failed to set short TPK "
10985 "lifetime");
10986 return 0;
10987 }
10988 }
10989
10990 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", sta);
10991 if (wpa_command(intf, buf) < 0) {
10992 send_resp(dut, conn, SIGMA_ERROR,
10993 "ErrorCode,Failed to send TDLS setup");
10994 return 0;
10995 }
10996 return 1;
10997 }
10998
10999 if (strcasecmp(val, "TEARDOWN") == 0) {
11000 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", sta);
11001 if (wpa_command(intf, buf) < 0) {
11002 send_resp(dut, conn, SIGMA_ERROR,
11003 "ErrorCode,Failed to send TDLS teardown");
11004 return 0;
11005 }
11006 return 1;
11007 }
11008
11009 send_resp(dut, conn, SIGMA_ERROR,
11010 "ErrorCode,Unsupported TDLS frame");
11011 return 0;
11012}
11013
11014
11015static int sta_ap_known(const char *ifname, const char *bssid)
11016{
11017 char buf[4096];
11018
Jouni Malinendd32f192018-09-15 02:55:19 +030011019 snprintf(buf, sizeof(buf), "BSS MASK=1 %s", bssid);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011020 if (wpa_command_resp(ifname, buf, buf, sizeof(buf)) < 0)
11021 return 0;
11022 if (strncmp(buf, "id=", 3) != 0)
11023 return 0;
11024 return 1;
11025}
11026
11027
11028static int sta_scan_ap(struct sigma_dut *dut, const char *ifname,
11029 const char *bssid)
11030{
11031 int res;
11032 struct wpa_ctrl *ctrl;
11033 char buf[256];
11034
11035 if (sta_ap_known(ifname, bssid))
11036 return 0;
11037 sigma_dut_print(dut, DUT_MSG_DEBUG,
11038 "AP not in BSS table - start scan");
11039
11040 ctrl = open_wpa_mon(ifname);
11041 if (ctrl == NULL) {
11042 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
11043 "wpa_supplicant monitor connection");
11044 return -1;
11045 }
11046
11047 if (wpa_command(ifname, "SCAN") < 0) {
11048 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to start scan");
11049 wpa_ctrl_detach(ctrl);
11050 wpa_ctrl_close(ctrl);
11051 return -1;
11052 }
11053
11054 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
11055 buf, sizeof(buf));
11056
11057 wpa_ctrl_detach(ctrl);
11058 wpa_ctrl_close(ctrl);
11059
11060 if (res < 0) {
11061 sigma_dut_print(dut, DUT_MSG_INFO, "Scan did not complete");
11062 return -1;
11063 }
11064
11065 if (sta_ap_known(ifname, bssid))
11066 return 0;
11067 sigma_dut_print(dut, DUT_MSG_INFO, "AP not in BSS table");
11068 return -1;
11069}
11070
11071
11072static int cmd_sta_send_frame_hs2_neighadv(struct sigma_dut *dut,
11073 struct sigma_conn *conn,
11074 struct sigma_cmd *cmd,
11075 const char *intf)
11076{
11077 char buf[200];
11078
11079 snprintf(buf, sizeof(buf), "ndsend 2001:DB8::1 %s", intf);
11080 if (system(buf) != 0) {
11081 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Failed to run "
11082 "ndsend");
11083 return 0;
11084 }
11085
11086 return 1;
11087}
11088
11089
11090static int cmd_sta_send_frame_hs2_neighsolreq(struct sigma_dut *dut,
11091 struct sigma_conn *conn,
11092 struct sigma_cmd *cmd,
11093 const char *intf)
11094{
11095 char buf[200];
11096 const char *ip = get_param(cmd, "SenderIP");
11097
Peng Xu26b356d2017-10-04 17:58:16 -070011098 if (!ip)
11099 return 0;
11100
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011101 snprintf(buf, sizeof(buf), "ndisc6 -nm %s %s -r 4", ip, intf);
11102 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
11103 if (system(buf) == 0) {
11104 sigma_dut_print(dut, DUT_MSG_INFO,
11105 "Neighbor Solicitation got a response "
11106 "for %s@%s", ip, intf);
11107 }
11108
11109 return 1;
11110}
11111
11112
11113static int cmd_sta_send_frame_hs2_arpprobe(struct sigma_dut *dut,
11114 struct sigma_conn *conn,
11115 struct sigma_cmd *cmd,
11116 const char *ifname)
11117{
11118 char buf[200];
11119 const char *ip = get_param(cmd, "SenderIP");
11120
11121 if (ip == NULL) {
11122 send_resp(dut, conn, SIGMA_ERROR,
11123 "ErrorCode,Missing SenderIP parameter");
11124 return 0;
11125 }
11126 snprintf(buf, sizeof(buf), "arping -I %s -D %s -c 4", ifname, ip);
11127 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
11128 if (system(buf) != 0) {
11129 sigma_dut_print(dut, DUT_MSG_INFO, "arping DAD got a response "
11130 "for %s@%s", ip, ifname);
11131 }
11132
11133 return 1;
11134}
11135
11136
11137static int cmd_sta_send_frame_hs2_arpannounce(struct sigma_dut *dut,
11138 struct sigma_conn *conn,
11139 struct sigma_cmd *cmd,
11140 const char *ifname)
11141{
11142 char buf[200];
11143 char ip[16];
11144 int s;
Peng Xub3756882017-10-04 14:39:09 -070011145 struct ifreq ifr;
11146 struct sockaddr_in saddr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011147
11148 s = socket(PF_INET, SOCK_DGRAM, 0);
Peng Xub3756882017-10-04 14:39:09 -070011149 if (s < 0) {
11150 perror("socket");
11151 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011152 }
11153
Peng Xub3756882017-10-04 14:39:09 -070011154 memset(&ifr, 0, sizeof(ifr));
11155 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
11156 if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
11157 sigma_dut_print(dut, DUT_MSG_INFO,
11158 "Failed to get %s IP address: %s",
11159 ifname, strerror(errno));
11160 close(s);
11161 return -1;
11162 }
11163 close(s);
11164
11165 memcpy(&saddr, &ifr.ifr_addr, sizeof(struct sockaddr_in));
11166 strlcpy(ip, inet_ntoa(saddr.sin_addr), sizeof(ip));
11167
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011168 snprintf(buf, sizeof(buf), "arping -I %s -s %s %s -c 4", ifname, ip,
11169 ip);
11170 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
11171 if (system(buf) != 0) {
11172 }
11173
11174 return 1;
11175}
11176
11177
11178static int cmd_sta_send_frame_hs2_arpreply(struct sigma_dut *dut,
11179 struct sigma_conn *conn,
11180 struct sigma_cmd *cmd,
11181 const char *ifname)
11182{
11183 char buf[200], addr[20];
11184 char dst[ETH_ALEN], src[ETH_ALEN];
11185 short ethtype = htons(ETH_P_ARP);
11186 char *pos;
11187 int s, res;
11188 const char *val;
11189 struct sockaddr_in taddr;
11190
11191 val = get_param(cmd, "dest");
11192 if (val)
11193 hwaddr_aton(val, (unsigned char *) dst);
11194
11195 val = get_param(cmd, "DestIP");
11196 if (val)
11197 inet_aton(val, &taddr.sin_addr);
Peng Xu151c9e12017-10-04 14:39:09 -070011198 else
11199 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011200
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011201 if (get_wpa_status(get_station_ifname(dut), "address", addr,
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011202 sizeof(addr)) < 0)
11203 return -2;
11204 hwaddr_aton(addr, (unsigned char *) src);
11205
11206 pos = buf;
11207 *pos++ = 0x00;
11208 *pos++ = 0x01;
11209 *pos++ = 0x08;
11210 *pos++ = 0x00;
11211 *pos++ = 0x06;
11212 *pos++ = 0x04;
11213 *pos++ = 0x00;
11214 *pos++ = 0x02;
11215 memcpy(pos, src, ETH_ALEN);
11216 pos += ETH_ALEN;
11217 memcpy(pos, &taddr.sin_addr, 4);
11218 pos += 4;
11219 memcpy(pos, dst, ETH_ALEN);
11220 pos += ETH_ALEN;
11221 memcpy(pos, &taddr.sin_addr, 4);
11222 pos += 4;
11223
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011224 s = open_monitor(get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011225 if (s < 0) {
11226 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
11227 "monitor socket");
11228 return 0;
11229 }
11230
11231 res = inject_eth_frame(s, buf, pos - buf, ethtype, dst, src);
11232 if (res < 0) {
11233 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
11234 "inject frame");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +053011235 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011236 return 0;
11237 }
11238
11239 close(s);
11240
11241 return 1;
11242}
11243
11244
11245static int cmd_sta_send_frame_hs2_dls_req(struct sigma_dut *dut,
11246 struct sigma_conn *conn,
11247 struct sigma_cmd *cmd,
11248 const char *intf, const char *dest)
11249{
11250 char buf[100];
11251
11252 if (if_nametoindex("sigmadut") == 0) {
11253 snprintf(buf, sizeof(buf),
11254 "iw dev %s interface add sigmadut type monitor",
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011255 get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011256 if (system(buf) != 0 ||
11257 if_nametoindex("sigmadut") == 0) {
11258 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
11259 "monitor interface with '%s'", buf);
11260 return -2;
11261 }
11262 }
11263
11264 if (system("ifconfig sigmadut up") != 0) {
11265 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
11266 "monitor interface up");
11267 return -2;
11268 }
11269
Veerendranath Jakkam49774122020-07-05 09:52:18 +053011270 return sta_inject_frame(dut, conn, intf, DLS_REQ, UNPROTECTED, dest, 1);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011271}
11272
11273
11274static int cmd_sta_send_frame_hs2(struct sigma_dut *dut,
11275 struct sigma_conn *conn,
11276 struct sigma_cmd *cmd)
11277{
11278 const char *intf = get_param(cmd, "Interface");
11279 const char *dest = get_param(cmd, "Dest");
11280 const char *type = get_param(cmd, "FrameName");
11281 const char *val;
11282 char buf[200], *pos, *end;
11283 int count, count2;
11284
11285 if (type == NULL)
11286 type = get_param(cmd, "Type");
11287
11288 if (intf == NULL || dest == NULL || type == NULL)
11289 return -1;
11290
11291 if (strcasecmp(type, "NeighAdv") == 0)
11292 return cmd_sta_send_frame_hs2_neighadv(dut, conn, cmd, intf);
11293
11294 if (strcasecmp(type, "NeighSolicitReq") == 0)
11295 return cmd_sta_send_frame_hs2_neighsolreq(dut, conn, cmd, intf);
11296
11297 if (strcasecmp(type, "ARPProbe") == 0)
11298 return cmd_sta_send_frame_hs2_arpprobe(dut, conn, cmd, intf);
11299
11300 if (strcasecmp(type, "ARPAnnounce") == 0)
11301 return cmd_sta_send_frame_hs2_arpannounce(dut, conn, cmd, intf);
11302
11303 if (strcasecmp(type, "ARPReply") == 0)
11304 return cmd_sta_send_frame_hs2_arpreply(dut, conn, cmd, intf);
11305
11306 if (strcasecmp(type, "DLS-request") == 0 ||
11307 strcasecmp(type, "DLSrequest") == 0)
11308 return cmd_sta_send_frame_hs2_dls_req(dut, conn, cmd, intf,
11309 dest);
11310
11311 if (strcasecmp(type, "ANQPQuery") != 0 &&
11312 strcasecmp(type, "Query") != 0) {
11313 send_resp(dut, conn, SIGMA_ERROR,
11314 "ErrorCode,Unsupported HS 2.0 send frame type");
11315 return 0;
11316 }
11317
11318 if (sta_scan_ap(dut, intf, dest) < 0) {
11319 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not find "
11320 "the requested AP");
11321 return 0;
11322 }
11323
11324 pos = buf;
11325 end = buf + sizeof(buf);
11326 count = 0;
11327 pos += snprintf(pos, end - pos, "ANQP_GET %s ", dest);
11328
11329 val = get_param(cmd, "ANQP_CAP_LIST");
11330 if (val && atoi(val)) {
11331 pos += snprintf(pos, end - pos, "%s257", count > 0 ? "," : "");
11332 count++;
11333 }
11334
11335 val = get_param(cmd, "VENUE_NAME");
11336 if (val && atoi(val)) {
11337 pos += snprintf(pos, end - pos, "%s258", count > 0 ? "," : "");
11338 count++;
11339 }
11340
11341 val = get_param(cmd, "NETWORK_AUTH_TYPE");
11342 if (val && atoi(val)) {
11343 pos += snprintf(pos, end - pos, "%s260", count > 0 ? "," : "");
11344 count++;
11345 }
11346
11347 val = get_param(cmd, "ROAMING_CONS");
11348 if (val && atoi(val)) {
11349 pos += snprintf(pos, end - pos, "%s261", count > 0 ? "," : "");
11350 count++;
11351 }
11352
11353 val = get_param(cmd, "IP_ADDR_TYPE_AVAILABILITY");
11354 if (val && atoi(val)) {
11355 pos += snprintf(pos, end - pos, "%s262", count > 0 ? "," : "");
11356 count++;
11357 }
11358
11359 val = get_param(cmd, "NAI_REALM_LIST");
11360 if (val && atoi(val)) {
11361 pos += snprintf(pos, end - pos, "%s263", count > 0 ? "," : "");
11362 count++;
11363 }
11364
11365 val = get_param(cmd, "3GPP_INFO");
11366 if (val && atoi(val)) {
11367 pos += snprintf(pos, end - pos, "%s264", count > 0 ? "," : "");
11368 count++;
11369 }
11370
11371 val = get_param(cmd, "DOMAIN_LIST");
11372 if (val && atoi(val)) {
11373 pos += snprintf(pos, end - pos, "%s268", count > 0 ? "," : "");
11374 count++;
11375 }
11376
Jouni Malinen34cf9532018-04-29 19:26:33 +030011377 val = get_param(cmd, "Venue_URL");
11378 if (val && atoi(val)) {
11379 pos += snprintf(pos, end - pos, "%s277", count > 0 ? "," : "");
11380 count++;
11381 }
11382
Jouni Malinend3bca5d2018-04-29 17:25:23 +030011383 val = get_param(cmd, "Advice_Of_Charge");
11384 if (val && atoi(val)) {
11385 pos += snprintf(pos, end - pos, "%s278", count > 0 ? "," : "");
11386 count++;
11387 }
11388
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011389 if (count && wpa_command(intf, buf)) {
11390 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,ANQP_GET failed");
11391 return 0;
11392 }
11393
11394 pos = buf;
11395 end = buf + sizeof(buf);
11396 count2 = 0;
11397 pos += snprintf(pos, end - pos, "HS20_ANQP_GET %s ", dest);
11398
11399 val = get_param(cmd, "HS_CAP_LIST");
11400 if (val && atoi(val)) {
11401 pos += snprintf(pos, end - pos, "%s2", count2 > 0 ? "," : "");
11402 count2++;
11403 }
11404
11405 val = get_param(cmd, "OPER_NAME");
11406 if (val && atoi(val)) {
11407 pos += snprintf(pos, end - pos, "%s3", count2 > 0 ? "," : "");
11408 count2++;
11409 }
11410
11411 val = get_param(cmd, "WAN_METRICS");
11412 if (!val)
11413 val = get_param(cmd, "WAN_MAT");
11414 if (!val)
11415 val = get_param(cmd, "WAN_MET");
11416 if (val && atoi(val)) {
11417 pos += snprintf(pos, end - pos, "%s4", count2 > 0 ? "," : "");
11418 count2++;
11419 }
11420
11421 val = get_param(cmd, "CONNECTION_CAPABILITY");
11422 if (val && atoi(val)) {
11423 pos += snprintf(pos, end - pos, "%s5", count2 > 0 ? "," : "");
11424 count2++;
11425 }
11426
11427 val = get_param(cmd, "OP_CLASS");
11428 if (val && atoi(val)) {
11429 pos += snprintf(pos, end - pos, "%s7", count2 > 0 ? "," : "");
11430 count2++;
11431 }
11432
11433 val = get_param(cmd, "OSU_PROVIDER_LIST");
11434 if (val && atoi(val)) {
11435 pos += snprintf(pos, end - pos, "%s8", count2 > 0 ? "," : "");
11436 count2++;
11437 }
11438
Jouni Malinenf67afec2018-04-29 19:24:58 +030011439 val = get_param(cmd, "OPER_ICON_METADATA");
11440 if (!val)
11441 val = get_param(cmd, "OPERATOR_ICON_METADATA");
11442 if (val && atoi(val)) {
11443 pos += snprintf(pos, end - pos, "%s12", count2 > 0 ? "," : "");
11444 count2++;
11445 }
11446
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011447 if (count && count2) {
11448 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before sending out "
11449 "second query");
11450 sleep(1);
11451 }
11452
11453 if (count2 && wpa_command(intf, buf)) {
11454 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,HS20_ANQP_GET "
11455 "failed");
11456 return 0;
11457 }
11458
11459 val = get_param(cmd, "NAI_HOME_REALM_LIST");
11460 if (val) {
11461 if (count || count2) {
11462 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
11463 "sending out second query");
11464 sleep(1);
11465 }
11466
11467 if (strcmp(val, "1") == 0)
11468 val = "mail.example.com";
11469 snprintf(buf, end - pos,
11470 "HS20_GET_NAI_HOME_REALM_LIST %s realm=%s",
11471 dest, val);
11472 if (wpa_command(intf, buf)) {
11473 send_resp(dut, conn, SIGMA_ERROR,
11474 "ErrorCode,HS20_GET_NAI_HOME_REALM_LIST "
11475 "failed");
11476 return 0;
11477 }
11478 }
11479
11480 val = get_param(cmd, "ICON_REQUEST");
11481 if (val) {
11482 if (count || count2) {
11483 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
11484 "sending out second query");
11485 sleep(1);
11486 }
11487
11488 snprintf(buf, end - pos,
11489 "HS20_ICON_REQUEST %s %s", dest, val);
11490 if (wpa_command(intf, buf)) {
11491 send_resp(dut, conn, SIGMA_ERROR,
11492 "ErrorCode,HS20_ICON_REQUEST failed");
11493 return 0;
11494 }
11495 }
11496
11497 return 1;
11498}
11499
11500
11501static int ath_sta_send_frame_vht(struct sigma_dut *dut,
11502 struct sigma_conn *conn,
11503 struct sigma_cmd *cmd)
11504{
11505 const char *val;
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011506 const char *ifname;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011507 int chwidth, nss;
11508
11509 val = get_param(cmd, "framename");
11510 if (!val)
11511 return -1;
11512 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
11513
11514 /* Command sequence to generate Op mode notification */
11515 if (val && strcasecmp(val, "Op_md_notif_frm") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011516 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011517
11518 /* Disable STBC */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011519 run_iwpriv(dut, ifname, "tx_stbc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011520
11521 /* Extract Channel width */
11522 val = get_param(cmd, "Channel_width");
11523 if (val) {
11524 switch (atoi(val)) {
11525 case 20:
11526 chwidth = 0;
11527 break;
11528 case 40:
11529 chwidth = 1;
11530 break;
11531 case 80:
11532 chwidth = 2;
11533 break;
11534 case 160:
11535 chwidth = 3;
11536 break;
11537 default:
11538 chwidth = 2;
11539 break;
11540 }
11541
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011542 run_iwpriv(dut, ifname, "chwidth %d", chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011543 }
11544
11545 /* Extract NSS */
11546 val = get_param(cmd, "NSS");
11547 if (val) {
11548 switch (atoi(val)) {
11549 case 1:
11550 nss = 1;
11551 break;
11552 case 2:
11553 nss = 3;
11554 break;
11555 case 3:
11556 nss = 7;
11557 break;
11558 default:
11559 /* We do not support NSS > 3 */
11560 nss = 3;
11561 break;
11562 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011563 run_iwpriv(dut, ifname, "rxchainmask %d", nss);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011564 }
11565
11566 /* Opmode notify */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011567 run_iwpriv(dut, ifname, "opmode_notify 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011568 }
11569
11570 return 1;
11571}
11572
11573
Kiran Kumar Lokere00d74412020-07-23 13:26:51 -070011574static int wcn_sta_set_pmf_config(struct sigma_dut *dut, const char *intf,
11575 enum send_frame_protection protected)
11576{
11577#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +053011578 return wcn_wifi_test_config_set_u8(
11579 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_PMF_PROTECTION,
11580 protected);
Kiran Kumar Lokere00d74412020-07-23 13:26:51 -070011581#else /* NL80211_SUPPORT */
11582 sigma_dut_print(dut, DUT_MSG_ERROR,
11583 "PMF config cannot be set without NL80211_SUPPORT defined");
11584 return -1;
11585#endif /* NL80211_SUPPORT */
11586}
11587
11588
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011589static int cmd_sta_send_frame_vht(struct sigma_dut *dut,
11590 struct sigma_conn *conn,
11591 struct sigma_cmd *cmd)
11592{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011593 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011594 case DRIVER_ATHEROS:
11595 return ath_sta_send_frame_vht(dut, conn, cmd);
11596 default:
11597 send_resp(dut, conn, SIGMA_ERROR,
11598 "errorCode,Unsupported sta_set_frame(VHT) with the current driver");
11599 return 0;
11600 }
11601}
11602
11603
Kiran Kumar Lokerec2c3b412020-07-23 13:51:27 -070011604static int wcn_sta_send_disassoc(struct sigma_dut *dut, const char *intf)
11605{
11606#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +053011607 return wcn_wifi_test_config_set_flag(
11608 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_DISASSOC_TX);
Kiran Kumar Lokerec2c3b412020-07-23 13:51:27 -070011609#else /* NL80211_SUPPORT */
11610 sigma_dut_print(dut, DUT_MSG_ERROR,
11611 "Disassoc Tx cannot be done without NL80211_SUPPORT defined");
11612 return -1;
11613#endif /* NL80211_SUPPORT */
11614}
11615
11616
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070011617static int wcn_sta_send_frame_he(struct sigma_dut *dut, struct sigma_conn *conn,
11618 struct sigma_cmd *cmd)
11619{
11620 const char *val;
11621 const char *intf = get_param(cmd, "Interface");
Kiran Kumar Lokere00d74412020-07-23 13:26:51 -070011622 enum send_frame_protection protected;
11623 const char *pmf;
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070011624
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +030011625 if (!intf)
11626 return -1;
11627
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070011628 val = get_param(cmd, "framename");
11629 if (!val)
11630 return -1;
11631 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
11632
Kiran Kumar Lokere00d74412020-07-23 13:26:51 -070011633 pmf = get_param(cmd, "PMFProtected");
11634 if (!pmf)
11635 pmf = get_param(cmd, "Protected");
11636 if (pmf) {
11637 if (strcasecmp(pmf, "Correct-key") == 0 ||
11638 strcasecmp(pmf, "CorrectKey") == 0) {
11639 protected = CORRECT_KEY;
11640 } else if (strcasecmp(pmf, "IncorrectKey") == 0) {
11641 protected = INCORRECT_KEY;
11642 } else if (strcasecmp(pmf, "Unprotected") == 0) {
11643 protected = UNPROTECTED;
11644 } else {
11645 send_resp(dut, conn, SIGMA_ERROR,
11646 "errorCode,Unsupported PMFProtected");
11647 return STATUS_SENT_ERROR;
11648 }
11649 sigma_dut_print(dut, DUT_MSG_DEBUG, "Config PMF protection %d",
11650 protected);
11651 wcn_sta_set_pmf_config(dut, intf, protected);
11652 }
11653
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070011654 /* Command sequence to generate Op mode notification */
11655 if (val && strcasecmp(val, "action") == 0) {
11656 val = get_param(cmd, "PPDUTxType");
11657 if (val && strcasecmp(val, "TB") == 0) {
11658 if (sta_set_action_tx_in_he_tb_ppdu(dut, intf, 1)) {
11659 sigma_dut_print(dut, DUT_MSG_ERROR,
11660 "failed to send TB PPDU Tx cfg");
11661 send_resp(dut, conn, SIGMA_ERROR,
11662 "ErrorCode,set TB PPDU Tx cfg failed");
11663 return 0;
11664 }
11665 return 1;
11666 }
11667
11668 sigma_dut_print(dut, DUT_MSG_ERROR,
11669 "Action Tx type is not defined");
Kiran Kumar Lokerec2c3b412020-07-23 13:51:27 -070011670
11671 return SUCCESS_SEND_STATUS;
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070011672 }
11673
Kiran Kumar Lokerec2c3b412020-07-23 13:51:27 -070011674 if (strcasecmp(val, "disassoc") == 0)
11675 wcn_sta_send_disassoc(dut, intf);
11676
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070011677 return 1;
11678}
11679
11680
11681static int cmd_sta_send_frame_he(struct sigma_dut *dut,
11682 struct sigma_conn *conn,
11683 struct sigma_cmd *cmd)
11684{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011685 switch (get_driver_type(dut)) {
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070011686 case DRIVER_WCN:
11687 return wcn_sta_send_frame_he(dut, conn, cmd);
11688 default:
11689 send_resp(dut, conn, SIGMA_ERROR,
11690 "errorCode,Unsupported sta_set_frame(HE) with the current driver");
11691 return 0;
11692 }
11693}
11694
11695
Lior David0fe101e2017-03-09 16:09:50 +020011696#ifdef __linux__
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030011697
11698static int
11699wil6210_send_p2p_frame_60g(struct sigma_dut *dut, struct sigma_cmd *cmd,
11700 const char *frame_name, const char *dest_mac)
11701{
11702 int isprobereq = strcasecmp(frame_name, "probereq") == 0;
11703 const char *ssid = get_param(cmd, "ssid");
11704 const char *countstr = get_param(cmd, "count");
11705 const char *channelstr = get_param(cmd, "channel");
11706 const char *group_id = get_param(cmd, "groupid");
11707 const char *client_id = get_param(cmd, "clientmac");
11708 int count, channel, freq, i;
11709 const char *fname;
11710 char frame[1024], src_mac[20], group_id_attr[25],
11711 device_macstr[3 * ETH_ALEN], client_mac[ETH_ALEN];
11712 const char *group_ssid;
11713 const int group_ssid_prefix_len = 9;
11714 struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *) frame;
11715 size_t framelen = sizeof(frame);
11716 struct template_frame_tag tags[2];
11717 size_t tags_total = ARRAY_SIZE(tags);
11718 int tag_index, len, dst_len;
11719
11720 if (!countstr || !channelstr) {
11721 sigma_dut_print(dut, DUT_MSG_ERROR,
11722 "Missing argument: count, channel");
11723 return -1;
11724 }
11725 if (isprobereq && !ssid) {
11726 sigma_dut_print(dut, DUT_MSG_ERROR,
11727 "Missing argument: ssid");
11728 return -1;
11729 }
11730 if (!isprobereq && (!group_id || !client_id)) {
11731 sigma_dut_print(dut, DUT_MSG_ERROR,
11732 "Missing argument: group_id, client_id");
11733 return -1;
11734 }
11735
11736 count = atoi(countstr);
11737 channel = atoi(channelstr);
11738 freq = channel_to_freq(dut, channel);
11739
11740 if (!freq) {
11741 sigma_dut_print(dut, DUT_MSG_ERROR,
11742 "invalid channel: %s", channelstr);
11743 return -1;
11744 }
11745
11746 if (isprobereq) {
11747 if (strcasecmp(ssid, "wildcard") == 0) {
11748 fname = "probe_req_wildcard.txt";
11749 } else if (strcasecmp(ssid, "P2P_Wildcard") == 0) {
11750 fname = "probe_req_P2P_Wildcard.txt";
11751 } else {
11752 sigma_dut_print(dut, DUT_MSG_ERROR,
11753 "invalid probe request type");
11754 return -1;
11755 }
11756 } else {
11757 fname = "P2P_device_discovery_req.txt";
11758 }
11759
11760 if (parse_template_frame_file(dut, fname, frame, &framelen,
11761 tags, &tags_total)) {
11762 sigma_dut_print(dut, DUT_MSG_ERROR,
11763 "invalid frame template: %s", fname);
11764 return -1;
11765 }
11766
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011767 if (get_wpa_status(get_station_ifname(dut), "address",
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030011768 src_mac, sizeof(src_mac)) < 0 ||
11769 parse_mac_address(dut, src_mac, &hdr->addr2[0]) ||
11770 parse_mac_address(dut, dest_mac, &hdr->addr1[0]))
11771 return -1;
11772 /* Use wildcard BSSID, since we are in PBSS */
11773 memset(&hdr->addr3, 0xFF, ETH_ALEN);
11774
11775 if (!isprobereq) {
11776 tag_index = find_template_frame_tag(tags, tags_total, 1);
11777 if (tag_index < 0) {
11778 sigma_dut_print(dut, DUT_MSG_ERROR,
11779 "can't find device id attribute");
11780 return -1;
11781 }
11782 if (parse_mac_address(dut, client_id,
11783 (unsigned char *) client_mac)) {
11784 sigma_dut_print(dut, DUT_MSG_ERROR,
11785 "invalid client_id: %s", client_id);
11786 return -1;
11787 }
11788 if (replace_p2p_attribute(dut, &frame[tags[tag_index].offset],
11789 framelen - tags[tag_index].offset,
11790 IEEE80211_P2P_ATTR_DEVICE_ID,
11791 client_mac, ETH_ALEN)) {
11792 sigma_dut_print(dut, DUT_MSG_ERROR,
11793 "fail to replace device id attribute");
11794 return -1;
11795 }
11796
11797 /*
11798 * group_id arg contains device MAC address followed by
11799 * space and SSID (DIRECT-somessid).
11800 * group id attribute contains device address (6 bytes)
11801 * followed by SSID prefix DIRECT-XX (9 bytes)
11802 */
11803 if (strlen(group_id) < sizeof(device_macstr)) {
11804 sigma_dut_print(dut, DUT_MSG_ERROR,
11805 "group_id arg too short");
11806 return -1;
11807 }
11808 memcpy(device_macstr, group_id, sizeof(device_macstr));
11809 device_macstr[sizeof(device_macstr) - 1] = '\0';
11810 if (parse_mac_address(dut, device_macstr,
11811 (unsigned char *) group_id_attr)) {
11812 sigma_dut_print(dut, DUT_MSG_ERROR,
11813 "fail to parse device address from group_id");
11814 return -1;
11815 }
11816 group_ssid = strchr(group_id, ' ');
11817 if (!group_ssid) {
11818 sigma_dut_print(dut, DUT_MSG_ERROR,
11819 "invalid group_id arg, no ssid");
11820 return -1;
11821 }
11822 group_ssid++;
11823 len = strlen(group_ssid);
11824 if (len < group_ssid_prefix_len) {
11825 sigma_dut_print(dut, DUT_MSG_ERROR,
11826 "group_id SSID too short");
11827 return -1;
11828 }
11829 dst_len = sizeof(group_id_attr) - ETH_ALEN;
11830 if (len > dst_len) {
11831 sigma_dut_print(dut, DUT_MSG_ERROR,
11832 "group_id SSID (%s) too long",
11833 group_ssid);
11834 return -1;
11835 }
11836
11837 memcpy(group_id_attr + ETH_ALEN, group_ssid, len);
11838 tag_index = find_template_frame_tag(tags, tags_total, 2);
11839 if (tag_index < 0) {
11840 sigma_dut_print(dut, DUT_MSG_ERROR,
11841 "can't find group id attribute");
11842 return -1;
11843 }
11844 if (replace_p2p_attribute(dut, &frame[tags[tag_index].offset],
11845 framelen - tags[tag_index].offset,
11846 IEEE80211_P2P_ATTR_GROUP_ID,
11847 group_id_attr,
11848 sizeof(group_id_attr))) {
11849 sigma_dut_print(dut, DUT_MSG_ERROR,
11850 "fail to replace group id attribute");
11851 return -1;
11852 }
11853 }
11854
11855 for (i = 0; i < count; i++) {
11856 if (wil6210_transmit_frame(dut, freq,
11857 WIL_TRANSMIT_FRAME_DEFAULT_ROC,
11858 frame, framelen)) {
11859 sigma_dut_print(dut, DUT_MSG_ERROR,
11860 "fail to transmit probe request frame");
11861 return -1;
11862 }
11863 }
11864
11865 return 0;
11866}
11867
11868
Lior David0fe101e2017-03-09 16:09:50 +020011869int wil6210_send_frame_60g(struct sigma_dut *dut, struct sigma_conn *conn,
11870 struct sigma_cmd *cmd)
11871{
11872 const char *frame_name = get_param(cmd, "framename");
11873 const char *mac = get_param(cmd, "dest_mac");
11874
11875 if (!frame_name || !mac) {
11876 sigma_dut_print(dut, DUT_MSG_ERROR,
11877 "framename and dest_mac must be provided");
11878 return -1;
11879 }
11880
11881 if (strcasecmp(frame_name, "brp") == 0) {
11882 const char *l_rx = get_param(cmd, "L-RX");
11883 int l_rx_i;
11884
11885 if (!l_rx) {
11886 sigma_dut_print(dut, DUT_MSG_ERROR,
11887 "L-RX must be provided");
11888 return -1;
11889 }
11890 l_rx_i = atoi(l_rx);
11891
11892 sigma_dut_print(dut, DUT_MSG_INFO,
11893 "dev_send_frame: BRP-RX, dest_mac %s, L-RX %s",
11894 mac, l_rx);
11895 if (l_rx_i != 16) {
11896 sigma_dut_print(dut, DUT_MSG_ERROR,
11897 "unsupported L-RX: %s", l_rx);
11898 return -1;
11899 }
11900
11901 if (wil6210_send_brp_rx(dut, mac, l_rx_i))
11902 return -1;
11903 } else if (strcasecmp(frame_name, "ssw") == 0) {
11904 sigma_dut_print(dut, DUT_MSG_INFO,
11905 "dev_send_frame: SLS, dest_mac %s", mac);
11906 if (wil6210_send_sls(dut, mac))
11907 return -1;
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030011908 } else if ((strcasecmp(frame_name, "probereq") == 0) ||
11909 (strcasecmp(frame_name, "devdiscreq") == 0)) {
11910 sigma_dut_print(dut, DUT_MSG_INFO,
11911 "dev_send_frame: %s, dest_mac %s", frame_name,
11912 mac);
11913 if (wil6210_send_p2p_frame_60g(dut, cmd, frame_name, mac))
11914 return -1;
Lior David0fe101e2017-03-09 16:09:50 +020011915 } else {
11916 sigma_dut_print(dut, DUT_MSG_ERROR,
11917 "unsupported frame type: %s", frame_name);
11918 return -1;
11919 }
11920
11921 return 1;
11922}
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030011923
Lior David0fe101e2017-03-09 16:09:50 +020011924#endif /* __linux__ */
11925
11926
11927static int cmd_sta_send_frame_60g(struct sigma_dut *dut,
11928 struct sigma_conn *conn,
11929 struct sigma_cmd *cmd)
11930{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011931 switch (get_driver_type(dut)) {
Lior David0fe101e2017-03-09 16:09:50 +020011932#ifdef __linux__
11933 case DRIVER_WIL6210:
11934 return wil6210_send_frame_60g(dut, conn, cmd);
11935#endif /* __linux__ */
11936 default:
11937 send_resp(dut, conn, SIGMA_ERROR,
11938 "errorCode,Unsupported sta_set_frame(60G) with the current driver");
11939 return 0;
11940 }
11941}
11942
11943
Ashwini Patildb59b3c2017-04-13 15:19:23 +053011944static int mbo_send_anqp_query(struct sigma_dut *dut, struct sigma_conn *conn,
11945 const char *intf, struct sigma_cmd *cmd)
11946{
11947 const char *val, *addr;
11948 char buf[100];
11949
11950 addr = get_param(cmd, "DestMac");
11951 if (!addr) {
11952 send_resp(dut, conn, SIGMA_INVALID,
11953 "ErrorCode,AP MAC address is missing");
11954 return 0;
11955 }
11956
11957 val = get_param(cmd, "ANQPQuery_ID");
11958 if (!val) {
11959 send_resp(dut, conn, SIGMA_INVALID,
11960 "ErrorCode,Missing ANQPQuery_ID");
11961 return 0;
11962 }
11963
11964 if (strcasecmp(val, "NeighborReportReq") == 0) {
11965 snprintf(buf, sizeof(buf), "ANQP_GET %s 272", addr);
11966 } else if (strcasecmp(val, "QueryListWithCellPref") == 0) {
11967 snprintf(buf, sizeof(buf), "ANQP_GET %s 272,mbo:2", addr);
11968 } else {
11969 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid ANQPQuery_ID: %s",
11970 val);
11971 send_resp(dut, conn, SIGMA_INVALID,
11972 "ErrorCode,Invalid ANQPQuery_ID");
11973 return 0;
11974 }
11975
Ashwini Patild174f2c2017-04-13 16:49:46 +053011976 /* Set gas_address3 field to IEEE 802.11-2012 standard compliant form
11977 * (Address3 = Wildcard BSSID when sent to not-associated AP;
11978 * if associated, AP BSSID).
11979 */
11980 if (wpa_command(intf, "SET gas_address3 1") < 0) {
11981 send_resp(dut, conn, SIGMA_ERROR,
11982 "ErrorCode,Failed to set gas_address3");
11983 return 0;
11984 }
11985
Ashwini Patildb59b3c2017-04-13 15:19:23 +053011986 if (wpa_command(intf, buf) < 0) {
11987 send_resp(dut, conn, SIGMA_ERROR,
11988 "ErrorCode,Failed to send ANQP query");
11989 return 0;
11990 }
11991
11992 return 1;
11993}
11994
11995
11996static int mbo_cmd_sta_send_frame(struct sigma_dut *dut,
11997 struct sigma_conn *conn,
11998 const char *intf,
11999 struct sigma_cmd *cmd)
12000{
12001 const char *val = get_param(cmd, "FrameName");
12002
12003 if (val && strcasecmp(val, "ANQPQuery") == 0)
12004 return mbo_send_anqp_query(dut, conn, intf, cmd);
12005
12006 return 2;
12007}
12008
12009
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +053012010static enum sigma_cmd_result cmd_sta_send_frame_wpa3(struct sigma_dut *dut,
12011 struct sigma_conn *conn,
12012 const char *intf,
12013 struct sigma_cmd *cmd)
12014{
12015 const char *val = get_param(cmd, "framename");
12016
12017 if (!val)
12018 return INVALID_SEND_STATUS;
12019
12020 if (strcasecmp(val, "SAQueryReq") == 0) {
12021 val = get_param(cmd, "OCIChannel");
12022
12023 if (!val) {
12024 send_resp(dut, conn, SIGMA_ERROR,
12025 "errorCode,OCIChannel not present");
12026 return STATUS_SENT_ERROR;
12027 }
12028
12029 dut->saquery_oci_freq = channel_to_freq(dut, atoi(val));
12030 if (!dut->saquery_oci_freq) {
12031 send_resp(dut, conn, SIGMA_ERROR,
12032 "errorCode,Invalid OCIChannel number");
12033 return STATUS_SENT_ERROR;
12034 }
12035
12036 return sta_inject_frame(dut, conn, intf, SAQUERY, CORRECT_KEY,
12037 NULL, 0);
12038 }
12039
12040 if (strcasecmp(val, "reassocreq") == 0)
12041 return sta_inject_frame(dut, conn, intf, REASSOCREQ,
12042 CORRECT_KEY, NULL, 0);
12043
Veerendranath9f81dfb2020-08-10 01:21:29 -070012044 if (strcasecmp(val, "ANQPQuery") == 0) {
12045 char buf[50];
12046 const char *dest = get_param(cmd, "DestMac");
12047 const char *chan = get_param(cmd, "channel");
Veerendranath Jakkam78862fc2020-11-19 21:23:27 +053012048 const char *freq_str = get_param(cmd, "ChnlFreq");
Veerendranath9f81dfb2020-08-10 01:21:29 -070012049 int len, freq;
12050
Veerendranath Jakkam78862fc2020-11-19 21:23:27 +053012051 if (freq_str)
12052 freq = atoi(freq_str);
12053 else
12054 freq = chan ? channel_to_freq(dut, atoi(chan)) : 0;
12055
Veerendranath9f81dfb2020-08-10 01:21:29 -070012056 if (!dest || !freq)
12057 return INVALID_SEND_STATUS;
12058
12059 len = snprintf(buf, sizeof(buf), "ANQP_GET %s freq=%d 257",
12060 dest, freq);
12061 if (len < 0 || len >= sizeof(buf)) {
12062 sigma_dut_print(dut, DUT_MSG_ERROR,
12063 "Failed to allocate buf");
12064 return ERROR_SEND_STATUS;
12065 }
12066
12067 if (wpa_command(intf, buf) != 0) {
12068 send_resp(dut, conn, SIGMA_ERROR,
12069 "ErrorCode,Failed to send ANQP Query frame");
12070 return STATUS_SENT_ERROR;
12071 }
12072
12073 sigma_dut_print(dut, DUT_MSG_DEBUG,
12074 "ANQP Query sent: %s", buf);
12075
12076 return SUCCESS_SEND_STATUS;
12077 }
12078
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +053012079 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported framename");
12080 return STATUS_SENT_ERROR;
12081}
12082
12083
Vinita S. Malooca85fd22021-01-15 02:54:34 +053012084static int
12085get_type4_frame_classifier(struct sigma_dut *dut, struct sigma_cmd *cmd,
12086 char *pos, int rem_len, int num_of_scs_desc,
12087 int num_of_tclas_elem)
12088{
12089 const char *val;
12090 int ipv6;
12091 int len, total_len = 0;
12092
12093 val = get_param_fmt(cmd, "TCLASElem_Version_%d_%d", num_of_scs_desc,
12094 num_of_tclas_elem);
12095 if (!val) {
12096 sigma_dut_print(dut, DUT_MSG_ERROR, "%s: ip_version empty",
12097 __func__);
12098 return -1;
12099 }
12100
12101 if (strcmp(val, "6") == 0) {
12102 ipv6 = 1;
12103 } else if (strcmp(val, "4") == 0) {
12104 ipv6 = 0;
12105 } else {
12106 sigma_dut_print(dut, DUT_MSG_ERROR, "%s: ip_version invalid",
12107 __func__);
12108 return -1;
12109 }
12110
12111 len = snprintf(pos, rem_len, " ip_version=%s", ipv6 ? "ipv6" : "ipv4");
12112 if (len < 0 || len >= rem_len)
12113 return -1;
12114
12115 pos += len;
12116 rem_len -= len;
12117 total_len += len;
12118
12119 val = get_param_fmt(cmd, "TCLASElem_SourceIPAddr_%d_%d",
12120 num_of_scs_desc, num_of_tclas_elem);
12121 if (val) {
12122 len = snprintf(pos, rem_len, " src_ip=%s", val);
12123 if (len < 0 || len >= rem_len)
12124 return -1;
12125
12126 pos += len;
12127 rem_len -= len;
12128 total_len += len;
12129 }
12130
12131 val = get_param_fmt(cmd, "TCLASElem_DestinationIPAddr_%d_%d",
12132 num_of_scs_desc, num_of_tclas_elem);
12133 if (val) {
12134 len = snprintf(pos, rem_len, " dst_ip=%s", val);
12135 if (len < 0 || len >= rem_len)
12136 return -1;
12137
12138 pos += len;
12139 rem_len -= len;
12140 total_len += len;
12141 }
12142
12143 val = get_param_fmt(cmd, "TCLASElem_SourcePort_%d_%d", num_of_scs_desc,
12144 num_of_tclas_elem);
12145 if (val) {
12146 len = snprintf(pos, rem_len, " src_port=%s", val);
12147 if (len < 0 || len >= rem_len)
12148 return -1;
12149
12150 pos += len;
12151 rem_len -= len;
12152 total_len += len;
12153 }
12154
12155 val = get_param_fmt(cmd, "TCLASElem_DestinationPort_%d_%d",
12156 num_of_scs_desc, num_of_tclas_elem);
12157 if (val) {
12158 len = snprintf(pos, rem_len, " dst_port=%s", val);
12159 if (len < 0 || len >= rem_len)
12160 return -1;
12161
12162 pos += len;
12163 rem_len -= len;
12164 total_len += len;
12165 }
12166
12167 val = get_param_fmt(cmd, "TCLASElem_DSCP_%d_%d", num_of_scs_desc,
12168 num_of_tclas_elem);
12169 if (val) {
12170 len = snprintf(pos, rem_len, " dscp=%s", val);
12171 if (len < 0 || len >= rem_len)
12172 return -1;
12173
12174 pos += len;
12175 rem_len -= len;
12176 total_len += len;
12177 }
12178
12179 val = get_param_fmt(cmd, "TCLASElem_ProtocolNxtHeader_%d_%d",
12180 num_of_scs_desc, num_of_tclas_elem);
12181 if (val) {
12182 char *prot;
12183
12184 switch (atoi(val)) {
12185 case 17:
12186 prot = "udp";
12187 break;
12188 case 6:
12189 prot = "tcp";
12190 break;
12191 case 50:
12192 prot = "esp";
12193 break;
12194 default:
12195 sigma_dut_print(dut, DUT_MSG_ERROR,
12196 "Invalid protocol %d", atoi(val));
12197 return -1;
12198 }
12199
12200 if (ipv6)
12201 len = snprintf(pos, rem_len, " next_header=%s", prot);
12202 else
12203 len = snprintf(pos, rem_len, " protocol=%s", prot);
12204 if (len < 0 || len >= rem_len)
12205 return -1;
12206
12207 pos += len;
12208 rem_len -= len;
12209 total_len += len;
12210 }
12211
12212 return total_len;
12213}
12214
12215
12216static int
12217get_type10_frame_classifier(struct sigma_dut *dut, struct sigma_cmd *cmd,
12218 char *pos, int rem_len, int num_of_scs_desc,
12219 int num_of_tclas_elem)
12220{
12221 const char *val;
12222 int len, total_len = 0;
12223
12224 val = get_param_fmt(cmd, "TCLASElem_ProtoInstance_%d_%d",
12225 num_of_scs_desc, num_of_tclas_elem);
12226 if (val) {
12227 len = snprintf(pos, rem_len, " prot_instance=%s",
12228 val);
12229 if (len < 0 || len >= rem_len)
12230 return -1;
12231
12232 pos += len;
12233 rem_len -= len;
12234 total_len += len;
12235 }
12236
12237 val = get_param_fmt(cmd, "TCLASElem_ProtoNumNextHeader_%d_%d",
12238 num_of_scs_desc, num_of_tclas_elem);
12239 if (val) {
12240 char *prot;
12241
12242 switch (atoi(val)) {
12243 case 17:
12244 prot = "udp";
12245 break;
12246 case 6:
12247 prot = "tcp";
12248 break;
12249 case 50:
12250 prot = "esp";
12251 break;
12252 default:
12253 sigma_dut_print(dut, DUT_MSG_ERROR,
12254 "Invalid protocol %d",
12255 atoi(val));
12256 return -1;
12257 }
12258
12259 len = snprintf(pos, rem_len, " prot_number=%s", prot);
12260 if (len < 0 || len >= rem_len)
12261 return -1;
12262
12263 pos += len;
12264 rem_len -= len;
12265 total_len += len;
12266 }
12267
12268 val = get_param_fmt(cmd, "TCLASElem_FilterValue_%d_%d",
12269 num_of_scs_desc, num_of_tclas_elem);
12270 if (val) {
12271 len = snprintf(pos, rem_len, " filter_value=%s", (val + 2));
12272 if (len < 0 || len >= rem_len)
12273 return -1;
12274
12275 pos += len;
12276 rem_len -= len;
12277 total_len += len;
12278 }
12279
12280 val = get_param_fmt(cmd, "TCLASElem_FilterMask_%d_%d", num_of_scs_desc,
12281 num_of_tclas_elem);
12282 if (val && strlen(val) >= 2) {
12283 len = snprintf(pos, rem_len, " filter_mask=%s", val + 2);
12284 if (len < 0 || len >= rem_len)
12285 return -1;
12286
12287 pos += len;
12288 rem_len -= len;
12289 total_len += len;
12290 }
12291
12292 return total_len;
12293}
12294
12295
12296static enum sigma_cmd_result
12297cmd_sta_send_frame_scs(struct sigma_dut *dut, struct sigma_conn *conn,
12298 const char *intf, struct sigma_cmd *cmd)
12299{
12300 char buf[4096], *pos;
12301 const char *val, *scs_id, *classifier_type;
12302 int len, rem_len, total_bytes;
12303 int num_of_scs_desc = 0, num_of_tclas_elem = 0;
12304
12305 scs_id = get_param(cmd, "SCSDescrElem_SCSID_1");
12306 if (!scs_id) {
12307 sigma_dut_print(dut, DUT_MSG_ERROR, "SCS ID empty");
12308 return INVALID_SEND_STATUS;
12309 }
12310
12311 rem_len = sizeof(buf);
12312 pos = buf;
12313
12314 len = snprintf(buf, sizeof(buf), "SCS");
12315 if (len < 0 || len > rem_len)
12316 goto fail;
12317
12318 pos += len;
12319 rem_len -= len;
12320
12321 while (scs_id) {
12322 num_of_scs_desc++;
12323
12324 val = get_param_fmt(cmd, "SCSDescrElem_RequestType_%d",
12325 num_of_scs_desc);
12326 if (!val)
12327 return INVALID_SEND_STATUS;
12328
12329 if (strcasecmp(val, "Add") == 0) {
12330 len = snprintf(pos, rem_len, " scs_id=%s add",
12331 scs_id);
12332 } else if (strcasecmp(val, "Change") == 0) {
12333 len = snprintf(pos, rem_len, " scs_id=%s change",
12334 scs_id);
12335 } else if (strcasecmp(val, "Remove") == 0) {
12336 len = snprintf(pos, rem_len, " scs_id=%s remove",
12337 scs_id);
12338 if (len < 0 || len >= rem_len)
12339 goto fail;
12340
12341 pos += len;
12342 rem_len -= len;
12343 goto scs_desc_end;
12344 } else {
12345 sigma_dut_print(dut, DUT_MSG_ERROR,
12346 "%s: request type - %s is invalid",
12347 __func__, val);
12348 return INVALID_SEND_STATUS;
12349 }
12350
12351 if (len < 0 || len >= rem_len)
12352 goto fail;
12353
12354 pos += len;
12355 rem_len -= len;
12356
12357 val = get_param_fmt(cmd, "IntraAccessCatElem_UP_%d",
12358 num_of_scs_desc);
12359 if (!val) {
12360 sigma_dut_print(dut, DUT_MSG_ERROR,
12361 "IntraAccess Priority empty");
12362 return INVALID_SEND_STATUS;
12363 }
12364
12365 len = snprintf(pos, rem_len, " scs_up=%s", val);
12366 if (len < 0 || len >= rem_len)
12367 goto fail;
12368
12369 pos += len;
12370 rem_len -= len;
12371
12372 classifier_type = get_param_fmt(cmd,
12373 "TCLASElem_ClassifierType_%d_1",
12374 num_of_scs_desc);
12375 if (!classifier_type) {
12376 sigma_dut_print(dut, DUT_MSG_ERROR,
12377 "classifier type missing");
12378 return INVALID_SEND_STATUS;
12379 }
12380
12381 while (classifier_type) {
12382 num_of_tclas_elem++;
12383
12384 len = snprintf(pos, rem_len, " classifier_type=%s",
12385 classifier_type);
12386 if (len < 0 || len >= rem_len)
12387 goto fail;
12388
12389 pos += len;
12390 rem_len -= len;
12391
12392 if (strcmp(classifier_type, "10") == 0) {
12393 total_bytes = get_type10_frame_classifier(
12394 dut, cmd, pos, rem_len,
12395 num_of_scs_desc,
12396 num_of_tclas_elem);
12397 } else if (strcmp(classifier_type, "4") == 0) {
12398 total_bytes = get_type4_frame_classifier(
12399 dut, cmd, pos, rem_len,
12400 num_of_scs_desc,
12401 num_of_tclas_elem);
12402 } else {
12403 sigma_dut_print(dut, DUT_MSG_ERROR,
12404 "classifier_type invalid");
12405 goto fail;
12406 }
12407
12408 if (total_bytes < 0)
12409 goto fail;
12410
12411 pos += total_bytes;
12412 rem_len -= total_bytes;
12413
12414 classifier_type = get_param_fmt(
12415 cmd, "TCLASElem_ClassifierType_%d_%d",
12416 num_of_scs_desc, num_of_tclas_elem + 1);
12417 }
12418
12419 if (num_of_tclas_elem > 1) {
12420 val = get_param_fmt(cmd,
12421 "TCLASProcessingElem_Processing_%d",
12422 num_of_scs_desc);
12423 if (!val) {
12424 sigma_dut_print(dut, DUT_MSG_ERROR,
12425 "Tclas_processing element %d empty",
12426 num_of_scs_desc);
12427 goto fail;
12428 }
12429
12430 len = snprintf(pos, rem_len,
12431 " tclas_processing=%s", val);
12432 if (len < 0 || len >= rem_len)
12433 goto fail;
12434
12435 pos += len;
12436 rem_len -= len;
12437 }
12438scs_desc_end:
12439 num_of_tclas_elem = 0;
12440 scs_id = get_param_fmt(cmd, "SCSDescrElem_SCSID_%d",
12441 num_of_scs_desc + 1);
12442 }
12443
12444 if (wpa_command(intf, buf) != 0) {
12445 send_resp(dut, conn, SIGMA_ERROR,
12446 "ErrorCode,Failed to send SCS frame request");
12447 return STATUS_SENT_ERROR;
12448 }
12449
12450 sigma_dut_print(dut, DUT_MSG_DEBUG,
12451 "SCS frame request sent: %s", buf);
12452
12453 return SUCCESS_SEND_STATUS;
12454fail:
12455 sigma_dut_print(dut, DUT_MSG_ERROR,
12456 "Failed to create SCS frame request");
12457 return ERROR_SEND_STATUS;
12458}
12459
12460
Vinita S. Malooee9e7e92020-04-28 16:26:50 +053012461static enum sigma_cmd_result
12462cmd_sta_send_frame_mscs(struct sigma_dut *dut, struct sigma_conn *conn,
12463 const char *intf, struct sigma_cmd *cmd)
12464{
12465 char buf[128], *pos;
12466 const char *val, *classifier_type = "04", *type;
12467 int len, rem_len;
12468 u8 up_bitmap;
12469
Vinita S. Malooee9e7e92020-04-28 16:26:50 +053012470 type = get_param(cmd, "Request_Type");
Vinita S. Malooca85fd22021-01-15 02:54:34 +053012471 if (!type) {
Vinita S. Malooee9e7e92020-04-28 16:26:50 +053012472 sigma_dut_print(dut, DUT_MSG_ERROR,
Vinita S. Malooca85fd22021-01-15 02:54:34 +053012473 "%s: type not valid", __func__);
Vinita S. Malooee9e7e92020-04-28 16:26:50 +053012474 return INVALID_SEND_STATUS;
12475 }
12476
12477 rem_len = sizeof(buf);
12478 pos = buf;
12479 if (strcasecmp(type, "add") == 0) {
12480 len = snprintf(pos, rem_len, "MSCS add");
12481 } else if (strcasecmp(type, "update") == 0) {
12482 len = snprintf(pos, rem_len, "MSCS change");
12483 } else if (strcasecmp(type, "remove") == 0) {
12484 if (wpa_command(intf, "MSCS remove") != 0) {
12485 send_resp(dut, conn, SIGMA_ERROR,
12486 "ErrorCode,Failed to send MSCS frame req");
12487 return STATUS_SENT_ERROR;
12488 }
12489 return SUCCESS_SEND_STATUS;
12490 } else {
12491 sigma_dut_print(dut, DUT_MSG_ERROR,
12492 "%s: request type invalid", __func__);
12493 return INVALID_SEND_STATUS;
12494 }
12495
12496 if (len < 0 || len >= rem_len)
12497 goto fail;
12498
12499 pos += len;
12500 rem_len -= len;
12501
12502 val = get_param(cmd, "User_Priority_Bitmap");
12503 if (!val) {
12504 sigma_dut_print(dut, DUT_MSG_ERROR,
12505 "%s: user priority bitmap empty", __func__);
12506 return INVALID_SEND_STATUS;
12507 }
12508
12509 switch (atoi(val)) {
12510 case 0:
12511 up_bitmap = 0x00;
12512 break;
12513 case 1:
12514 up_bitmap = 0xF0;
12515 break;
12516 case 2:
12517 up_bitmap = 0xF6;
12518 break;
12519 default:
12520 sigma_dut_print(dut, DUT_MSG_ERROR,
12521 "%s: Unknown User_Priority_Bitmap value %d",
12522 __func__, atoi(val));
12523 return INVALID_SEND_STATUS;
12524 }
12525
12526 len = snprintf(pos, rem_len, " up_bitmap=%02x", up_bitmap);
12527 if (len < 0 || len >= rem_len)
12528 goto fail;
12529
12530 pos += len;
12531 rem_len -= len;
12532
12533 val = get_param(cmd, "User_Priority_Limit");
12534 if (!val) {
12535 sigma_dut_print(dut, DUT_MSG_ERROR,
12536 "%s: invalid user priority limit", __func__);
12537 return INVALID_SEND_STATUS;
12538 }
12539
12540 len = snprintf(pos, rem_len, " up_limit=%s", val);
12541 if (len < 0 || len >= rem_len)
12542 goto fail;
12543
12544 pos += len;
12545 rem_len -= len;
12546
12547 val = get_param(cmd, "Stream_Timeout");
12548 if (!val)
12549 val = get_param(cmd, "Stream_Timtout");
12550 if (!val) {
12551 sigma_dut_print(dut, DUT_MSG_ERROR,
12552 "%s: invalid stream timeout", __func__);
12553 return INVALID_SEND_STATUS;
12554 }
12555
12556 len = snprintf(pos, rem_len, " stream_timeout=%s", val);
12557 if (len < 0 || len >= rem_len)
12558 goto fail;
12559
12560 pos += len;
12561 rem_len -= len;
12562
12563 val = get_param(cmd, "TCLAS_Mask");
12564 if (!val) {
12565 sigma_dut_print(dut, DUT_MSG_ERROR,
12566 "%s: invalid tclas mask", __func__);
12567 return INVALID_SEND_STATUS;
12568 }
12569
12570 len = snprintf(pos, rem_len, " frame_classifier=%s%lx%032x",
12571 classifier_type, strtol(val, NULL, 2), 0);
12572 if (len < 0 || len >= rem_len)
12573 goto fail;
12574
12575 if (wpa_command(intf, buf) != 0) {
12576 send_resp(dut, conn, SIGMA_ERROR,
12577 "ErrorCode,Failed to send MSCS frame req");
12578 return STATUS_SENT_ERROR;
12579 }
12580
12581 sigma_dut_print(dut, DUT_MSG_DEBUG,
12582 "MSCS frame request sent: %s", buf);
12583
12584 return SUCCESS_SEND_STATUS;
12585fail:
12586 sigma_dut_print(dut, DUT_MSG_ERROR,
12587 "Failed to create MSCS frame req");
12588 return ERROR_SEND_STATUS;
12589}
12590
12591
Vinita S. Malooca85fd22021-01-15 02:54:34 +053012592static enum sigma_cmd_result
12593cmd_sta_send_frame_qm(struct sigma_dut *dut, struct sigma_conn *conn,
12594 const char *intf, struct sigma_cmd *cmd)
12595{
12596 const char *val;
12597
12598 val = get_param(cmd, "FrameName");
12599 if (val) {
12600 if (strcasecmp(val, "MSCSReq") == 0)
12601 return cmd_sta_send_frame_mscs(dut, conn, intf, cmd);
12602 if (strcasecmp(val, "SCSReq") == 0)
12603 return cmd_sta_send_frame_scs(dut, conn, intf, cmd);
12604
12605 sigma_dut_print(dut, DUT_MSG_ERROR,
12606 "%s: frame name - %s is invalid",
12607 __func__, val);
12608 }
12609
12610 return INVALID_SEND_STATUS;
12611}
12612
12613
Jouni Malinenf7222712019-06-13 01:50:21 +030012614enum sigma_cmd_result cmd_sta_send_frame(struct sigma_dut *dut,
12615 struct sigma_conn *conn,
12616 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012617{
12618 const char *intf = get_param(cmd, "Interface");
12619 const char *val;
12620 enum send_frame_type frame;
12621 enum send_frame_protection protected;
12622 char buf[100];
12623 unsigned char addr[ETH_ALEN];
12624 int res;
12625
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +030012626 if (!intf)
12627 return -1;
12628
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012629 val = get_param(cmd, "program");
12630 if (val == NULL)
12631 val = get_param(cmd, "frame");
12632 if (val && strcasecmp(val, "TDLS") == 0)
12633 return cmd_sta_send_frame_tdls(dut, conn, cmd);
12634 if (val && (strcasecmp(val, "HS2") == 0 ||
Jouni Malinen1f6ae642018-06-07 23:56:13 +030012635 strcasecmp(val, "HS2-R2") == 0 ||
12636 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012637 return cmd_sta_send_frame_hs2(dut, conn, cmd);
12638 if (val && strcasecmp(val, "VHT") == 0)
12639 return cmd_sta_send_frame_vht(dut, conn, cmd);
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012640 if (val && strcasecmp(val, "HE") == 0)
12641 return cmd_sta_send_frame_he(dut, conn, cmd);
priyadharshini gowthamand66913a2016-07-29 15:11:17 -070012642 if (val && strcasecmp(val, "LOC") == 0)
12643 return loc_cmd_sta_send_frame(dut, conn, cmd);
Lior David0fe101e2017-03-09 16:09:50 +020012644 if (val && strcasecmp(val, "60GHz") == 0)
12645 return cmd_sta_send_frame_60g(dut, conn, cmd);
Ashwini Patildb59b3c2017-04-13 15:19:23 +053012646 if (val && strcasecmp(val, "MBO") == 0) {
12647 res = mbo_cmd_sta_send_frame(dut, conn, intf, cmd);
12648 if (res != 2)
12649 return res;
12650 }
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +053012651 if (val && strcasecmp(val, "WPA3") == 0)
12652 return cmd_sta_send_frame_wpa3(dut, conn, intf, cmd);
Vinita S. Malooee9e7e92020-04-28 16:26:50 +053012653 if (val && strcasecmp(val, "QM") == 0)
Vinita S. Malooca85fd22021-01-15 02:54:34 +053012654 return cmd_sta_send_frame_qm(dut, conn, intf, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012655
12656 val = get_param(cmd, "TD_DISC");
12657 if (val) {
12658 if (hwaddr_aton(val, addr) < 0)
12659 return -1;
12660 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", val);
12661 if (wpa_command(intf, buf) < 0) {
12662 send_resp(dut, conn, SIGMA_ERROR,
12663 "ErrorCode,Failed to send TDLS discovery");
12664 return 0;
12665 }
12666 return 1;
12667 }
12668
12669 val = get_param(cmd, "TD_Setup");
12670 if (val) {
12671 if (hwaddr_aton(val, addr) < 0)
12672 return -1;
12673 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", val);
12674 if (wpa_command(intf, buf) < 0) {
12675 send_resp(dut, conn, SIGMA_ERROR,
12676 "ErrorCode,Failed to start TDLS setup");
12677 return 0;
12678 }
12679 return 1;
12680 }
12681
12682 val = get_param(cmd, "TD_TearDown");
12683 if (val) {
12684 if (hwaddr_aton(val, addr) < 0)
12685 return -1;
12686 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", val);
12687 if (wpa_command(intf, buf) < 0) {
12688 send_resp(dut, conn, SIGMA_ERROR,
12689 "ErrorCode,Failed to tear down TDLS link");
12690 return 0;
12691 }
12692 return 1;
12693 }
12694
12695 val = get_param(cmd, "TD_ChannelSwitch");
12696 if (val) {
12697 /* TODO */
12698 send_resp(dut, conn, SIGMA_ERROR,
12699 "ErrorCode,TD_ChannelSwitch not yet supported");
12700 return 0;
12701 }
12702
12703 val = get_param(cmd, "TD_NF");
12704 if (val) {
12705 /* TODO */
12706 send_resp(dut, conn, SIGMA_ERROR,
12707 "ErrorCode,TD_NF not yet supported");
12708 return 0;
12709 }
12710
12711 val = get_param(cmd, "PMFFrameType");
12712 if (val == NULL)
12713 val = get_param(cmd, "FrameName");
12714 if (val == NULL)
12715 val = get_param(cmd, "Type");
12716 if (val == NULL)
12717 return -1;
12718 if (strcasecmp(val, "disassoc") == 0)
12719 frame = DISASSOC;
12720 else if (strcasecmp(val, "deauth") == 0)
12721 frame = DEAUTH;
12722 else if (strcasecmp(val, "saquery") == 0)
12723 frame = SAQUERY;
12724 else if (strcasecmp(val, "auth") == 0)
12725 frame = AUTH;
12726 else if (strcasecmp(val, "assocreq") == 0)
12727 frame = ASSOCREQ;
12728 else if (strcasecmp(val, "reassocreq") == 0)
12729 frame = REASSOCREQ;
12730 else if (strcasecmp(val, "neigreq") == 0) {
12731 sigma_dut_print(dut, DUT_MSG_INFO, "Got neighbor request");
12732
12733 val = get_param(cmd, "ssid");
12734 if (val == NULL)
12735 return -1;
12736
12737 res = send_neighbor_request(dut, intf, val);
12738 if (res) {
12739 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
12740 "Failed to send neighbor report request");
12741 return 0;
12742 }
12743
12744 return 1;
Ashwini Patil5acd7382017-04-13 15:55:04 +053012745 } else if (strcasecmp(val, "transmgmtquery") == 0 ||
12746 strcasecmp(val, "BTMQuery") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012747 sigma_dut_print(dut, DUT_MSG_DEBUG,
12748 "Got Transition Management Query");
12749
Ashwini Patil5acd7382017-04-13 15:55:04 +053012750 res = send_trans_mgmt_query(dut, intf, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012751 if (res) {
12752 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
12753 "Failed to send Transition Management Query");
12754 return 0;
12755 }
12756
12757 return 1;
12758 } else {
12759 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
12760 "PMFFrameType");
12761 return 0;
12762 }
12763
12764 val = get_param(cmd, "PMFProtected");
12765 if (val == NULL)
12766 val = get_param(cmd, "Protected");
12767 if (val == NULL)
12768 return -1;
12769 if (strcasecmp(val, "Correct-key") == 0 ||
12770 strcasecmp(val, "CorrectKey") == 0)
12771 protected = CORRECT_KEY;
12772 else if (strcasecmp(val, "IncorrectKey") == 0)
12773 protected = INCORRECT_KEY;
12774 else if (strcasecmp(val, "Unprotected") == 0)
12775 protected = UNPROTECTED;
12776 else {
12777 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
12778 "PMFProtected");
12779 return 0;
12780 }
12781
12782 if (protected != UNPROTECTED &&
12783 (frame == AUTH || frame == ASSOCREQ || frame == REASSOCREQ)) {
12784 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Impossible "
12785 "PMFProtected for auth/assocreq/reassocreq");
12786 return 0;
12787 }
12788
12789 if (if_nametoindex("sigmadut") == 0) {
12790 snprintf(buf, sizeof(buf),
12791 "iw dev %s interface add sigmadut type monitor",
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012792 get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012793 if (system(buf) != 0 ||
12794 if_nametoindex("sigmadut") == 0) {
12795 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
12796 "monitor interface with '%s'", buf);
12797 return -2;
12798 }
12799 }
12800
12801 if (system("ifconfig sigmadut up") != 0) {
12802 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
12803 "monitor interface up");
12804 return -2;
12805 }
12806
Veerendranath Jakkam49774122020-07-05 09:52:18 +053012807 return sta_inject_frame(dut, conn, intf, frame, protected, NULL, 1);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012808}
12809
12810
12811static int cmd_sta_set_parameter_hs2(struct sigma_dut *dut,
12812 struct sigma_conn *conn,
12813 struct sigma_cmd *cmd,
12814 const char *ifname)
12815{
12816 char buf[200];
12817 const char *val;
12818
12819 val = get_param(cmd, "ClearARP");
12820 if (val && atoi(val) == 1) {
12821 snprintf(buf, sizeof(buf), "ip neigh flush dev %s", ifname);
12822 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
12823 if (system(buf) != 0) {
12824 send_resp(dut, conn, SIGMA_ERROR,
12825 "errorCode,Failed to clear ARP cache");
12826 return 0;
12827 }
12828 }
12829
12830 return 1;
12831}
12832
12833
12834int cmd_sta_set_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
12835 struct sigma_cmd *cmd)
12836{
12837 const char *intf = get_param(cmd, "Interface");
12838 const char *val;
12839
12840 if (intf == NULL)
12841 return -1;
12842
12843 val = get_param(cmd, "program");
12844 if (val && (strcasecmp(val, "HS2") == 0 ||
Jouni Malinen1f6ae642018-06-07 23:56:13 +030012845 strcasecmp(val, "HS2-R2") == 0 ||
12846 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012847 return cmd_sta_set_parameter_hs2(dut, conn, cmd, intf);
12848
12849 return -1;
12850}
12851
12852
Jouni Malinenf7222712019-06-13 01:50:21 +030012853static enum sigma_cmd_result cmd_sta_set_macaddr(struct sigma_dut *dut,
12854 struct sigma_conn *conn,
12855 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012856{
12857 const char *intf = get_param(cmd, "Interface");
12858 const char *mac = get_param(cmd, "MAC");
12859
12860 if (intf == NULL || mac == NULL)
12861 return -1;
12862
12863 sigma_dut_print(dut, DUT_MSG_INFO, "Change local MAC address for "
12864 "interface %s to %s", intf, mac);
12865
12866 if (dut->set_macaddr) {
12867 char buf[128];
12868 int res;
12869 if (strcasecmp(mac, "default") == 0) {
12870 res = snprintf(buf, sizeof(buf), "%s",
12871 dut->set_macaddr);
12872 dut->tmp_mac_addr = 0;
12873 } else {
12874 res = snprintf(buf, sizeof(buf), "%s %s",
12875 dut->set_macaddr, mac);
12876 dut->tmp_mac_addr = 1;
12877 }
12878 if (res < 0 || res >= (int) sizeof(buf))
12879 return -1;
12880 if (system(buf) != 0) {
12881 send_resp(dut, conn, SIGMA_ERROR,
12882 "errorCode,Failed to set MAC "
12883 "address");
12884 return 0;
12885 }
12886 return 1;
12887 }
12888
12889 if (strcasecmp(mac, "default") == 0)
12890 return 1;
12891
12892 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
12893 "command");
12894 return 0;
12895}
12896
12897
12898static int iwpriv_tdlsoffchnmode(struct sigma_dut *dut,
12899 struct sigma_conn *conn, const char *intf,
12900 int val)
12901{
12902 char buf[200];
12903 int res;
12904
12905 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchnmode %d",
12906 intf, val);
12907 if (res < 0 || res >= (int) sizeof(buf))
12908 return -1;
12909 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
12910 if (system(buf) != 0) {
12911 send_resp(dut, conn, SIGMA_ERROR,
12912 "errorCode,Failed to configure offchannel mode");
12913 return 0;
12914 }
12915
12916 return 1;
12917}
12918
12919
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012920static int off_chan_val(enum sec_ch_offset off)
12921{
12922 switch (off) {
12923 case SEC_CH_NO:
12924 return 0;
12925 case SEC_CH_40ABOVE:
12926 return 40;
12927 case SEC_CH_40BELOW:
12928 return -40;
12929 }
12930
12931 return 0;
12932}
12933
12934
12935static int iwpriv_set_offchan(struct sigma_dut *dut, struct sigma_conn *conn,
12936 const char *intf, int off_ch_num,
12937 enum sec_ch_offset sec)
12938{
12939 char buf[200];
12940 int res;
12941
12942 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchan %d",
12943 intf, off_ch_num);
12944 if (res < 0 || res >= (int) sizeof(buf))
12945 return -1;
12946 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
12947 if (system(buf) != 0) {
12948 send_resp(dut, conn, SIGMA_ERROR,
12949 "errorCode,Failed to set offchan");
12950 return 0;
12951 }
12952
12953 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsecchnoffst %d",
12954 intf, off_chan_val(sec));
12955 if (res < 0 || res >= (int) sizeof(buf))
12956 return -1;
12957 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
12958 if (system(buf) != 0) {
12959 send_resp(dut, conn, SIGMA_ERROR,
12960 "errorCode,Failed to set sec chan offset");
12961 return 0;
12962 }
12963
12964 return 1;
12965}
12966
12967
12968static int tdls_set_offchannel_offset(struct sigma_dut *dut,
12969 struct sigma_conn *conn,
12970 const char *intf, int off_ch_num,
12971 enum sec_ch_offset sec)
12972{
12973 char buf[200];
12974 int res;
12975
12976 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNEL %d",
12977 off_ch_num);
12978 if (res < 0 || res >= (int) sizeof(buf))
12979 return -1;
12980 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
12981
12982 if (wpa_command(intf, buf) < 0) {
12983 send_resp(dut, conn, SIGMA_ERROR,
12984 "ErrorCode,Failed to set offchan");
12985 return 0;
12986 }
12987 res = snprintf(buf, sizeof(buf), "DRIVER TDLSSECONDARYCHANNELOFFSET %d",
12988 off_chan_val(sec));
12989 if (res < 0 || res >= (int) sizeof(buf))
12990 return -1;
12991
12992 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
12993
12994 if (wpa_command(intf, buf) < 0) {
12995 send_resp(dut, conn, SIGMA_ERROR,
12996 "ErrorCode,Failed to set sec chan offset");
12997 return 0;
12998 }
12999
13000 return 1;
13001}
13002
13003
13004static int tdls_set_offchannel_mode(struct sigma_dut *dut,
13005 struct sigma_conn *conn,
13006 const char *intf, int val)
13007{
13008 char buf[200];
13009 int res;
13010
13011 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNELMODE %d",
13012 val);
13013 if (res < 0 || res >= (int) sizeof(buf))
13014 return -1;
13015 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
13016
13017 if (wpa_command(intf, buf) < 0) {
13018 send_resp(dut, conn, SIGMA_ERROR,
13019 "ErrorCode,Failed to configure offchannel mode");
13020 return 0;
13021 }
13022
13023 return 1;
13024}
13025
13026
13027static int cmd_sta_set_rfeature_tdls(const char *intf, struct sigma_dut *dut,
13028 struct sigma_conn *conn,
13029 struct sigma_cmd *cmd)
13030{
13031 const char *val;
13032 enum {
13033 CHSM_NOT_SET,
13034 CHSM_ENABLE,
13035 CHSM_DISABLE,
13036 CHSM_REJREQ,
13037 CHSM_UNSOLRESP
13038 } chsm = CHSM_NOT_SET;
13039 int off_ch_num = -1;
13040 enum sec_ch_offset sec_ch = SEC_CH_NO;
13041 int res;
13042
13043 val = get_param(cmd, "Uapsd");
13044 if (val) {
13045 char buf[100];
13046 if (strcasecmp(val, "Enable") == 0)
13047 snprintf(buf, sizeof(buf), "SET ps 99");
13048 else if (strcasecmp(val, "Disable") == 0)
13049 snprintf(buf, sizeof(buf), "SET ps 98");
13050 else {
13051 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
13052 "Unsupported uapsd parameter value");
13053 return 0;
13054 }
13055 if (wpa_command(intf, buf)) {
13056 send_resp(dut, conn, SIGMA_ERROR,
13057 "ErrorCode,Failed to change U-APSD "
13058 "powersave mode");
13059 return 0;
13060 }
13061 }
13062
13063 val = get_param(cmd, "TPKTIMER");
13064 if (val && strcasecmp(val, "DISABLE") == 0) {
13065 if (wpa_command(intf, "SET tdls_testing 0x100")) {
13066 send_resp(dut, conn, SIGMA_ERROR,
13067 "ErrorCode,Failed to enable no TPK "
13068 "expiration test mode");
13069 return 0;
13070 }
13071 dut->no_tpk_expiration = 1;
13072 }
13073
13074 val = get_param(cmd, "ChSwitchMode");
13075 if (val) {
13076 if (strcasecmp(val, "Enable") == 0 ||
13077 strcasecmp(val, "Initiate") == 0)
13078 chsm = CHSM_ENABLE;
13079 else if (strcasecmp(val, "Disable") == 0 ||
13080 strcasecmp(val, "passive") == 0)
13081 chsm = CHSM_DISABLE;
13082 else if (strcasecmp(val, "RejReq") == 0)
13083 chsm = CHSM_REJREQ;
13084 else if (strcasecmp(val, "UnSolResp") == 0)
13085 chsm = CHSM_UNSOLRESP;
13086 else {
13087 send_resp(dut, conn, SIGMA_ERROR,
13088 "ErrorCode,Unknown ChSwitchMode value");
13089 return 0;
13090 }
13091 }
13092
13093 val = get_param(cmd, "OffChNum");
13094 if (val) {
13095 off_ch_num = atoi(val);
13096 if (off_ch_num == 0) {
13097 send_resp(dut, conn, SIGMA_ERROR,
13098 "ErrorCode,Invalid OffChNum");
13099 return 0;
13100 }
13101 }
13102
13103 val = get_param(cmd, "SecChOffset");
13104 if (val) {
13105 if (strcmp(val, "20") == 0)
13106 sec_ch = SEC_CH_NO;
13107 else if (strcasecmp(val, "40above") == 0)
13108 sec_ch = SEC_CH_40ABOVE;
13109 else if (strcasecmp(val, "40below") == 0)
13110 sec_ch = SEC_CH_40BELOW;
13111 else {
13112 send_resp(dut, conn, SIGMA_ERROR,
13113 "ErrorCode,Unknown SecChOffset value");
13114 return 0;
13115 }
13116 }
13117
13118 if (chsm == CHSM_NOT_SET) {
13119 /* no offchannel changes requested */
13120 return 1;
13121 }
13122
Jouni Malinen016ae6c2019-11-04 17:00:01 +020013123 if (strcmp(intf, get_main_ifname(dut)) != 0 &&
13124 strcmp(intf, get_station_ifname(dut)) != 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013125 send_resp(dut, conn, SIGMA_ERROR,
13126 "ErrorCode,Unknown interface");
13127 return 0;
13128 }
13129
13130 switch (chsm) {
13131 case CHSM_NOT_SET:
Jouni Malinen280f5ba2016-08-29 21:33:10 +030013132 res = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013133 break;
13134 case CHSM_ENABLE:
13135 if (off_ch_num < 0) {
13136 send_resp(dut, conn, SIGMA_ERROR,
13137 "ErrorCode,Missing OffChNum argument");
13138 return 0;
13139 }
13140 if (wifi_chip_type == DRIVER_WCN) {
13141 res = tdls_set_offchannel_offset(dut, conn, intf,
13142 off_ch_num, sec_ch);
13143 } else {
13144 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
13145 sec_ch);
13146 }
13147 if (res != 1)
13148 return res;
13149 if (wifi_chip_type == DRIVER_WCN)
13150 res = tdls_set_offchannel_mode(dut, conn, intf, 1);
13151 else
13152 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 1);
13153 break;
13154 case CHSM_DISABLE:
13155 if (wifi_chip_type == DRIVER_WCN)
13156 res = tdls_set_offchannel_mode(dut, conn, intf, 2);
13157 else
13158 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 2);
13159 break;
13160 case CHSM_REJREQ:
13161 if (wifi_chip_type == DRIVER_WCN)
13162 res = tdls_set_offchannel_mode(dut, conn, intf, 3);
13163 else
13164 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 3);
13165 break;
13166 case CHSM_UNSOLRESP:
13167 if (off_ch_num < 0) {
13168 send_resp(dut, conn, SIGMA_ERROR,
13169 "ErrorCode,Missing OffChNum argument");
13170 return 0;
13171 }
13172 if (wifi_chip_type == DRIVER_WCN) {
13173 res = tdls_set_offchannel_offset(dut, conn, intf,
13174 off_ch_num, sec_ch);
13175 } else {
13176 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
13177 sec_ch);
13178 }
13179 if (res != 1)
13180 return res;
13181 if (wifi_chip_type == DRIVER_WCN)
13182 res = tdls_set_offchannel_mode(dut, conn, intf, 4);
13183 else
13184 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 4);
13185 break;
13186 }
13187
13188 return res;
13189}
13190
13191
13192static int ath_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
13193 struct sigma_conn *conn,
13194 struct sigma_cmd *cmd)
13195{
13196 const char *val;
Srikanth Marepalli5415acf2018-08-27 12:53:11 +053013197 char *token = NULL, *result;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013198
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -070013199 novap_reset(dut, intf, 1);
priyadharshini gowthamane5e25172015-12-08 14:53:48 -080013200
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013201 val = get_param(cmd, "nss_mcs_opt");
13202 if (val) {
13203 /* String (nss_operating_mode; mcs_operating_mode) */
13204 int nss, mcs;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053013205 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013206
13207 token = strdup(val);
13208 if (!token)
13209 return 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053013210 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +053013211 if (!result) {
13212 sigma_dut_print(dut, DUT_MSG_ERROR,
13213 "VHT NSS not specified");
13214 goto failed;
13215 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013216 if (strcasecmp(result, "def") != 0) {
13217 nss = atoi(result);
13218 if (nss == 4)
13219 ath_disable_txbf(dut, intf);
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070013220 if (run_iwpriv(dut, intf, "nss %d", nss) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013221 goto failed;
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070013222
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013223 }
13224
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053013225 result = strtok_r(NULL, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +053013226 if (!result) {
13227 sigma_dut_print(dut, DUT_MSG_ERROR,
13228 "VHT MCS not specified");
13229 goto failed;
13230 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013231 if (strcasecmp(result, "def") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070013232 if (run_iwpriv(dut, intf, "set11NRates 0") < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013233 goto failed;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013234 } else {
13235 mcs = atoi(result);
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070013236 if (run_iwpriv(dut, intf, "vhtmcs %d", mcs) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013237 goto failed;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013238 }
13239 /* Channel width gets messed up, fix this */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070013240 run_iwpriv(dut, intf, "chwidth %d", dut->chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013241 }
13242
Srikanth Marepalli5415acf2018-08-27 12:53:11 +053013243 free(token);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013244 return 1;
13245failed:
13246 free(token);
13247 return 0;
13248}
13249
13250
13251static int cmd_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
13252 struct sigma_conn *conn,
13253 struct sigma_cmd *cmd)
13254{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020013255 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013256 case DRIVER_ATHEROS:
13257 return ath_sta_set_rfeature_vht(intf, dut, conn, cmd);
13258 default:
13259 send_resp(dut, conn, SIGMA_ERROR,
13260 "errorCode,Unsupported sta_set_rfeature(VHT) with the current driver");
13261 return 0;
13262 }
13263}
13264
13265
Jouni Malinen1702fe32021-06-08 19:08:01 +030013266static enum sigma_cmd_result
13267wcn_sta_set_rfeature_he(const char *intf, struct sigma_dut *dut,
13268 struct sigma_conn *conn, struct sigma_cmd *cmd)
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080013269{
13270 const char *val;
13271 char *token = NULL, *result;
13272 char buf[60];
13273
13274 val = get_param(cmd, "nss_mcs_opt");
13275 if (val) {
13276 /* String (nss_operating_mode; mcs_operating_mode) */
13277 int nss, mcs, ratecode;
13278 char *saveptr;
13279
13280 token = strdup(val);
13281 if (!token)
Jouni Malinen1702fe32021-06-08 19:08:01 +030013282 return ERROR_SEND_STATUS;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080013283
13284 result = strtok_r(token, ";", &saveptr);
13285 if (!result) {
13286 sigma_dut_print(dut, DUT_MSG_ERROR,
13287 "HE NSS not specified");
13288 goto failed;
13289 }
13290 nss = 1;
13291 if (strcasecmp(result, "def") != 0)
13292 nss = atoi(result);
13293
13294 result = strtok_r(NULL, ";", &saveptr);
13295 if (!result) {
13296 sigma_dut_print(dut, DUT_MSG_ERROR,
13297 "HE MCS not specified");
13298 goto failed;
13299 }
13300 mcs = 7;
13301 if (strcasecmp(result, "def") != 0)
13302 mcs = atoi(result);
13303
Arif Hussain557bf412018-05-25 17:29:36 -070013304 ratecode = 0x20; /* for nss:1 MCS 0 */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080013305 if (nss == 2) {
Arif Hussain557bf412018-05-25 17:29:36 -070013306 ratecode = 0x40; /* for nss:2 MCS 0 */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080013307 } else if (nss > 2) {
13308 sigma_dut_print(dut, DUT_MSG_ERROR,
13309 "HE NSS %d not supported", nss);
13310 goto failed;
13311 }
13312
Arif Hussain557bf412018-05-25 17:29:36 -070013313 snprintf(buf, sizeof(buf), "iwpriv %s nss %d", intf, nss);
13314 if (system(buf) != 0) {
13315 sigma_dut_print(dut, DUT_MSG_ERROR,
13316 "nss_mcs_opt: iwpriv %s nss %d failed",
13317 intf, nss);
13318 goto failed;
13319 }
Arif Hussainac6c5112018-05-25 17:34:00 -070013320 dut->sta_nss = nss;
Arif Hussain557bf412018-05-25 17:29:36 -070013321
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080013322 /* Add the MCS to the ratecode */
13323 if (mcs >= 0 && mcs <= 11) {
13324 ratecode += mcs;
Arif Hussain557bf412018-05-25 17:29:36 -070013325#ifdef NL80211_SUPPORT
13326 if (dut->device_type == STA_testbed) {
13327 enum he_mcs_config mcs_config;
13328 int ret;
13329
13330 if (mcs <= 7)
13331 mcs_config = HE_80_MCS0_7;
13332 else if (mcs <= 9)
13333 mcs_config = HE_80_MCS0_9;
13334 else
13335 mcs_config = HE_80_MCS0_11;
13336 ret = sta_set_he_mcs(dut, intf, mcs_config);
13337 if (ret) {
13338 sigma_dut_print(dut, DUT_MSG_ERROR,
13339 "nss_mcs_opt: mcs setting failed, mcs:%d, mcs_config %d, ret:%d",
13340 mcs, mcs_config, ret);
13341 goto failed;
13342 }
13343 }
13344#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080013345 } else {
13346 sigma_dut_print(dut, DUT_MSG_ERROR,
13347 "HE MCS %d not supported", mcs);
13348 goto failed;
13349 }
13350 snprintf(buf, sizeof(buf), "iwpriv %s set_11ax_rate 0x%03x",
13351 intf, ratecode);
13352 if (system(buf) != 0) {
13353 sigma_dut_print(dut, DUT_MSG_ERROR,
13354 "iwpriv setting of 11ax rates failed");
13355 goto failed;
13356 }
13357 free(token);
13358 }
13359
13360 val = get_param(cmd, "GI");
13361 if (val) {
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080013362 int fix_rate_sgi;
13363
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080013364 if (strcmp(val, "0.8") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070013365 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 9", intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080013366 fix_rate_sgi = 1;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080013367 } else if (strcmp(val, "1.6") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070013368 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 10",
13369 intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080013370 fix_rate_sgi = 2;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080013371 } else if (strcmp(val, "3.2") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070013372 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 11",
13373 intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080013374 fix_rate_sgi = 3;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080013375 } else {
13376 send_resp(dut, conn, SIGMA_ERROR,
13377 "errorCode,GI value not supported");
Jouni Malinen1702fe32021-06-08 19:08:01 +030013378 return STATUS_SENT_ERROR;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080013379 }
13380 if (system(buf) != 0) {
13381 send_resp(dut, conn, SIGMA_ERROR,
13382 "errorCode,Failed to set shortgi");
Jouni Malinen1702fe32021-06-08 19:08:01 +030013383 return STATUS_SENT_ERROR;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080013384 }
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080013385 snprintf(buf, sizeof(buf), "iwpriv %s shortgi %d",
13386 intf, fix_rate_sgi);
13387 if (system(buf) != 0) {
13388 send_resp(dut, conn, SIGMA_ERROR,
13389 "errorCode,Failed to set fix rate shortgi");
Jouni Malinen1702fe32021-06-08 19:08:01 +030013390 return STATUS_SENT_ERROR;
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080013391 }
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080013392 }
13393
Subhani Shaik8e7a3052018-04-24 14:03:00 -070013394 val = get_param(cmd, "LTF");
13395 if (val) {
13396#ifdef NL80211_SUPPORT
13397 if (strcmp(val, "3.2") == 0) {
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -080013398 wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_1X);
Subhani Shaik8e7a3052018-04-24 14:03:00 -070013399 } if (strcmp(val, "6.4") == 0) {
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -080013400 wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_2X);
Subhani Shaik8e7a3052018-04-24 14:03:00 -070013401 } else if (strcmp(val, "12.8") == 0) {
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -080013402 wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_4X);
Subhani Shaik8e7a3052018-04-24 14:03:00 -070013403 } else {
13404 send_resp(dut, conn, SIGMA_ERROR,
13405 "errorCode, LTF value not supported");
Jouni Malinen1702fe32021-06-08 19:08:01 +030013406 return STATUS_SENT_ERROR;
Subhani Shaik8e7a3052018-04-24 14:03:00 -070013407 }
13408#else /* NL80211_SUPPORT */
13409 sigma_dut_print(dut, DUT_MSG_ERROR,
13410 "LTF cannot be set without NL80211_SUPPORT defined");
Jouni Malinen1702fe32021-06-08 19:08:01 +030013411 return ERROR_SEND_STATUS;
Subhani Shaik8e7a3052018-04-24 14:03:00 -070013412#endif /* NL80211_SUPPORT */
13413 }
13414
Kiran Kumar Lokere1809da12021-06-24 00:45:38 -070013415 val = get_param(cmd, "KeepAlive");
13416 if (val) {
13417 int set_val = QCA_WLAN_KEEP_ALIVE_DEFAULT;
13418
13419 if (strcasecmp(val, "Data") == 0)
13420 set_val = QCA_WLAN_KEEP_ALIVE_DATA;
13421 else if (strcasecmp(val, "Mgmt") == 0)
13422 set_val = QCA_WLAN_KEEP_ALIVE_MGMT;
13423
13424 if (sta_set_keep_alive_data_cfg(dut, intf, set_val)) {
13425 send_resp(dut, conn, SIGMA_ERROR,
13426 "ErrorCode,Failed to set keep alive type config");
13427 return STATUS_SENT_ERROR;
13428 }
13429 }
13430
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -070013431 val = get_param(cmd, "TxSUPPDU");
13432 if (val) {
13433 int set_val = 1;
13434
13435 if (strcasecmp(val, "Enable") == 0)
13436 set_val = 1;
13437 else if (strcasecmp(val, "Disable") == 0)
13438 set_val = 0;
13439
13440 if (sta_set_tx_su_ppdu_cfg(dut, intf, set_val)) {
13441 send_resp(dut, conn, SIGMA_ERROR,
13442 "ErrorCode,Failed to set Tx SU PPDU config");
Jouni Malinen1702fe32021-06-08 19:08:01 +030013443 return STATUS_SENT_ERROR;
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -070013444 }
13445 }
13446
Kiran Kumar Lokere54b72522021-04-01 00:22:44 -070013447 val = get_param(cmd, "Mgmt_Data_TX_Resp_Frame");
13448 if (val) {
13449 int set_val = 0;
13450
13451 if (strcasecmp(val, "Enable") == 0)
13452 set_val = 0;
13453 else if (strcasecmp(val, "Disable") == 0)
13454 set_val = 1;
13455
13456 if (sta_set_mgmt_data_tx_disable_cfg(dut, intf, set_val)) {
13457 send_resp(dut, conn, SIGMA_ERROR,
13458 "ErrorCode,Failed to set mgmt/data Tx disable config");
13459 return STATUS_SENT_ERROR;
13460 }
13461 }
13462
Arif Hussain480d5f42019-03-12 14:40:42 -070013463 val = get_param(cmd, "TWT_Setup");
13464 if (val) {
13465 if (strcasecmp(val, "Request") == 0) {
13466 if (sta_twt_request(dut, conn, cmd)) {
13467 send_resp(dut, conn, SIGMA_ERROR,
Srinivas Girigowda6707f032020-10-26 15:24:46 -070013468 "ErrorCode,TWT setup failed");
Jouni Malinen1702fe32021-06-08 19:08:01 +030013469 return STATUS_SENT_ERROR;
Arif Hussain480d5f42019-03-12 14:40:42 -070013470 }
13471 } else if (strcasecmp(val, "Teardown") == 0) {
13472 if (sta_twt_teardown(dut, conn, cmd)) {
13473 send_resp(dut, conn, SIGMA_ERROR,
Srinivas Girigowda6707f032020-10-26 15:24:46 -070013474 "ErrorCode,TWT teardown failed");
Jouni Malinen1702fe32021-06-08 19:08:01 +030013475 return STATUS_SENT_ERROR;
Arif Hussain480d5f42019-03-12 14:40:42 -070013476 }
13477 }
13478 }
13479
Srinivas Girigowda6707f032020-10-26 15:24:46 -070013480 val = get_param(cmd, "TWT_Operation");
13481 if (val) {
13482 if (strcasecmp(val, "Suspend") == 0) {
13483 if (sta_twt_suspend_or_nudge(dut, conn, cmd)) {
13484 send_resp(dut, conn, SIGMA_ERROR,
13485 "ErrorCode,TWT suspend failed");
13486 return STATUS_SENT_ERROR;
13487 }
13488 } else if (strcasecmp(val, "Resume") == 0) {
13489 if (sta_twt_resume(dut, conn, cmd)) {
13490 send_resp(dut, conn, SIGMA_ERROR,
13491 "ErrorCode,TWT resume failed");
13492 return STATUS_SENT_ERROR;
13493 }
13494 }
13495 }
13496
Kiran Kumar Lokere50eb2cd2018-12-18 18:31:28 -080013497 val = get_param(cmd, "transmitOMI");
13498 if (val && sta_transmit_omi(dut, conn, cmd)) {
13499 send_resp(dut, conn, SIGMA_ERROR,
13500 "ErrorCode,sta_transmit_omi failed");
Jouni Malinen1702fe32021-06-08 19:08:01 +030013501 return STATUS_SENT_ERROR;
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -070013502 }
13503
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080013504 val = get_param(cmd, "Powersave");
13505 if (val) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053013506 int ps;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080013507
13508 if (strcasecmp(val, "off") == 0) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053013509 ps = 2;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080013510 } else if (strcasecmp(val, "on") == 0) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053013511 ps = 1;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080013512 } else {
13513 sigma_dut_print(dut, DUT_MSG_ERROR,
13514 "Unsupported Powersave value '%s'",
13515 val);
Jouni Malinen1702fe32021-06-08 19:08:01 +030013516 return INVALID_SEND_STATUS;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080013517 }
Vinita S. Malooa8b62722020-04-23 01:45:41 +053013518 if (set_power_save_wcn(dut, intf, ps) < 0)
Jouni Malinen1702fe32021-06-08 19:08:01 +030013519 return ERROR_SEND_STATUS;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080013520 }
13521
Kiran Kumar Lokere2c4b7ce2019-01-30 12:02:28 -080013522 val = get_param(cmd, "MU_EDCA");
13523 if (val) {
13524 if (strcasecmp(val, "Override") == 0) {
13525 if (sta_set_mu_edca_override(dut, intf, 1)) {
13526 send_resp(dut, conn, SIGMA_ERROR,
13527 "errorCode,MU EDCA override set failed");
13528 return STATUS_SENT;
13529 }
13530 } else if (strcasecmp(val, "Disable") == 0) {
13531 if (sta_set_mu_edca_override(dut, intf, 0)) {
13532 send_resp(dut, conn, SIGMA_ERROR,
13533 "errorCode,MU EDCA override disable failed");
13534 return STATUS_SENT;
13535 }
13536 }
13537 }
13538
Kiran Kumar Lokerefa7c7b92021-08-09 00:50:55 -070013539 val = get_param(cmd, "RUAllocTone");
13540 if (val && strcasecmp(val, "242") == 0) {
13541 if (sta_set_ru_242_tone_tx(dut, intf, 1)) {
13542 send_resp(dut, conn, SIGMA_ERROR,
13543 "ErrorCode,Failed to set RU 242 tone Tx");
13544 return STATUS_SENT_ERROR;
13545 }
13546 }
13547
13548 val = get_param(cmd, "PPDUTxType");
13549 if (val && strcasecmp(val, "ER-SU") == 0) {
13550 if (sta_set_er_su_ppdu_type_tx(dut, intf, 1)) {
13551 send_resp(dut, conn, SIGMA_ERROR,
13552 "ErrorCode,Failed to set ER-SU PPDU type Tx");
13553 return STATUS_SENT_ERROR;
13554 }
13555 }
13556
Kiran Kumar Lokeredd086642020-06-04 00:29:26 -070013557 val = get_param(cmd, "Ch_Pref");
13558 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
13559 return STATUS_SENT;
13560
13561 val = get_param(cmd, "Cellular_Data_Cap");
13562 if (val && mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
13563 return STATUS_SENT;
13564
Jouni Malinen1702fe32021-06-08 19:08:01 +030013565 return SUCCESS_SEND_STATUS;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080013566
13567failed:
13568 free(token);
Jouni Malinen1702fe32021-06-08 19:08:01 +030013569 return ERROR_SEND_STATUS;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080013570}
13571
13572
Jouni Malinen1702fe32021-06-08 19:08:01 +030013573static enum sigma_cmd_result
13574cmd_sta_set_rfeature_he(const char *intf, struct sigma_dut *dut,
13575 struct sigma_conn *conn, struct sigma_cmd *cmd)
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080013576{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020013577 switch (get_driver_type(dut)) {
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080013578 case DRIVER_WCN:
13579 return wcn_sta_set_rfeature_he(intf, dut, conn, cmd);
13580 default:
13581 send_resp(dut, conn, SIGMA_ERROR,
13582 "errorCode,Unsupported sta_set_rfeature(HE) with the current driver");
Jouni Malinen1702fe32021-06-08 19:08:01 +030013583 return STATUS_SENT_ERROR;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080013584 }
13585}
13586
13587
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080013588static int cmd_sta_set_power_save_he(const char *intf, struct sigma_dut *dut,
13589 struct sigma_conn *conn,
13590 struct sigma_cmd *cmd)
13591{
13592 const char *val;
13593
13594 val = get_param(cmd, "powersave");
13595 if (val) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053013596 int ps;
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080013597
13598 if (strcasecmp(val, "off") == 0) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053013599 ps = 2;
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080013600 } else if (strcasecmp(val, "on") == 0) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053013601 ps = 1;
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080013602 } else {
13603 sigma_dut_print(dut, DUT_MSG_ERROR,
13604 "Unsupported power save config");
13605 return -1;
13606 }
Vinita S. Malooa8b62722020-04-23 01:45:41 +053013607 if (set_power_save_wcn(dut, intf, ps) < 0)
13608 return 0;
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080013609 return 1;
13610 }
13611
13612 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported command");
13613
13614 return 0;
13615}
13616
13617
Ashwini Patil5acd7382017-04-13 15:55:04 +053013618static int btm_query_candidate_list(struct sigma_dut *dut,
13619 struct sigma_conn *conn,
13620 struct sigma_cmd *cmd)
13621{
13622 const char *bssid, *info, *op_class, *ch, *phy_type, *pref;
13623 int len, ret;
13624 char buf[10];
13625
13626 /*
13627 * Neighbor Report elements format:
13628 * neighbor=<BSSID>,<BSSID Information>,<Operating Class>,
13629 * <Channel Number>,<PHY Type>[,<hexdump of Optional Subelements>]
13630 * eg: neighbor=aa:bb:cc:dd:ee:ff,17,81,6,1,030101
13631 */
13632
13633 bssid = get_param(cmd, "Nebor_BSSID");
13634 if (!bssid) {
13635 send_resp(dut, conn, SIGMA_INVALID,
13636 "errorCode,Nebor_BSSID is missing");
13637 return 0;
13638 }
13639
13640 info = get_param(cmd, "Nebor_Bssid_Info");
13641 if (!info) {
13642 sigma_dut_print(dut, DUT_MSG_INFO,
13643 "Using default value for Nebor_Bssid_Info: %s",
13644 DEFAULT_NEIGHBOR_BSSID_INFO);
13645 info = DEFAULT_NEIGHBOR_BSSID_INFO;
13646 }
13647
13648 op_class = get_param(cmd, "Nebor_Op_Class");
13649 if (!op_class) {
13650 send_resp(dut, conn, SIGMA_INVALID,
13651 "errorCode,Nebor_Op_Class is missing");
13652 return 0;
13653 }
13654
13655 ch = get_param(cmd, "Nebor_Op_Ch");
13656 if (!ch) {
13657 send_resp(dut, conn, SIGMA_INVALID,
13658 "errorCode,Nebor_Op_Ch is missing");
13659 return 0;
13660 }
13661
13662 phy_type = get_param(cmd, "Nebor_Phy_Type");
13663 if (!phy_type) {
13664 sigma_dut_print(dut, DUT_MSG_INFO,
13665 "Using default value for Nebor_Phy_Type: %s",
13666 DEFAULT_NEIGHBOR_PHY_TYPE);
13667 phy_type = DEFAULT_NEIGHBOR_PHY_TYPE;
13668 }
13669
13670 /* Parse optional subelements */
13671 buf[0] = '\0';
13672 pref = get_param(cmd, "Nebor_Pref");
13673 if (pref) {
13674 /* hexdump for preferrence subelement */
13675 ret = snprintf(buf, sizeof(buf), ",0301%02x", atoi(pref));
13676 if (ret < 0 || ret >= (int) sizeof(buf)) {
13677 sigma_dut_print(dut, DUT_MSG_ERROR,
13678 "snprintf failed for optional subelement ret: %d",
13679 ret);
13680 send_resp(dut, conn, SIGMA_ERROR,
13681 "errorCode,snprintf failed for subelement");
13682 return 0;
13683 }
13684 }
13685
13686 if (!dut->btm_query_cand_list) {
13687 dut->btm_query_cand_list = calloc(1, NEIGHBOR_REPORT_SIZE);
13688 if (!dut->btm_query_cand_list) {
13689 send_resp(dut, conn, SIGMA_ERROR,
13690 "errorCode,Failed to allocate memory for btm_query_cand_list");
13691 return 0;
13692 }
13693 }
13694
13695 len = strlen(dut->btm_query_cand_list);
13696 ret = snprintf(dut->btm_query_cand_list + len,
13697 NEIGHBOR_REPORT_SIZE - len, " neighbor=%s,%s,%s,%s,%s%s",
13698 bssid, info, op_class, ch, phy_type, buf);
13699 if (ret < 0 || ret >= NEIGHBOR_REPORT_SIZE - len) {
13700 sigma_dut_print(dut, DUT_MSG_ERROR,
13701 "snprintf failed for neighbor report list ret: %d",
13702 ret);
13703 send_resp(dut, conn, SIGMA_ERROR,
13704 "errorCode,snprintf failed for neighbor report");
13705 free(dut->btm_query_cand_list);
13706 dut->btm_query_cand_list = NULL;
13707 return 0;
13708 }
13709
13710 return 1;
13711}
13712
13713
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020013714int sta_extract_60g_ese(struct sigma_dut *dut, struct sigma_cmd *cmd,
13715 struct sigma_ese_alloc *allocs, int *allocs_size)
13716{
13717 int max_count = *allocs_size;
13718 int count = 0, i;
13719 const char *val;
13720
13721 do {
13722 val = get_param_indexed(cmd, "AllocID", count);
13723 if (val)
13724 count++;
13725 } while (val);
13726
13727 if (count == 0 || count > max_count) {
13728 sigma_dut_print(dut, DUT_MSG_ERROR,
13729 "Invalid number of allocations(%d)", count);
13730 return -1;
13731 }
13732
13733 for (i = 0; i < count; i++) {
13734 val = get_param_indexed(cmd, "PercentBI", i);
13735 if (!val) {
13736 sigma_dut_print(dut, DUT_MSG_ERROR,
13737 "Missing PercentBI parameter at index %d",
13738 i);
13739 return -1;
13740 }
13741 allocs[i].percent_bi = atoi(val);
13742
13743 val = get_param_indexed(cmd, "SrcAID", i);
13744 if (val)
13745 allocs[i].src_aid = strtol(val, NULL, 0);
13746 else
13747 allocs[i].src_aid = ESE_BCAST_AID;
13748
13749 val = get_param_indexed(cmd, "DestAID", i);
13750 if (val)
13751 allocs[i].dst_aid = strtol(val, NULL, 0);
13752 else
13753 allocs[i].dst_aid = ESE_BCAST_AID;
13754
13755 allocs[i].type = ESE_CBAP;
13756 sigma_dut_print(dut, DUT_MSG_INFO,
13757 "Alloc %d PercentBI %d SrcAID %d DstAID %d",
13758 i, allocs[i].percent_bi, allocs[i].src_aid,
13759 allocs[i].dst_aid);
13760 }
13761
13762 *allocs_size = count;
13763 return 0;
13764}
13765
13766
13767static int sta_set_60g_ese(struct sigma_dut *dut, int count,
13768 struct sigma_ese_alloc *allocs)
13769{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020013770 switch (get_driver_type(dut)) {
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020013771#ifdef __linux__
13772 case DRIVER_WIL6210:
13773 if (wil6210_set_ese(dut, count, allocs))
13774 return -1;
13775 return 1;
13776#endif /* __linux__ */
13777 default:
13778 sigma_dut_print(dut, DUT_MSG_ERROR,
13779 "Unsupported sta_set_60g_ese with the current driver");
13780 return -1;
13781 }
13782}
13783
13784
13785static int cmd_sta_set_rfeature_60g(const char *intf, struct sigma_dut *dut,
13786 struct sigma_conn *conn,
13787 struct sigma_cmd *cmd)
13788{
13789 const char *val;
13790
13791 val = get_param(cmd, "ExtSchIE");
13792 if (val && !strcasecmp(val, "Enable")) {
13793 struct sigma_ese_alloc allocs[MAX_ESE_ALLOCS];
13794 int count = MAX_ESE_ALLOCS;
13795
13796 if (sta_extract_60g_ese(dut, cmd, allocs, &count))
13797 return -1;
13798 return sta_set_60g_ese(dut, count, allocs);
13799 }
13800
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +020013801 val = get_param(cmd, "MCS_FixedRate");
13802 if (val) {
13803 int sta_mcs = atoi(val);
13804
13805 sigma_dut_print(dut, DUT_MSG_INFO, "Force STA MCS to %d",
13806 sta_mcs);
13807 wil6210_set_force_mcs(dut, 1, sta_mcs);
13808
Jouni Malinen0e29cf22019-02-19 01:13:21 +020013809 return SUCCESS_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +020013810 }
13811
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020013812 send_resp(dut, conn, SIGMA_ERROR,
13813 "errorCode,Invalid sta_set_rfeature(60G)");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020013814 return STATUS_SENT;
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020013815}
13816
13817
Veerendranath Jakkam76a845c2020-07-14 13:19:40 +053013818static int wcn_sta_override_oci(struct sigma_dut *dut, const char *intf,
13819 const char *oci_frametype, uint32_t oci_freq)
13820{
13821#ifdef NL80211_SUPPORT
13822 struct nl_msg *msg;
13823 int ret = 0;
13824 struct nlattr *params;
13825 struct nlattr *attr;
13826 int ifindex;
13827 u8 frame_type;
13828
13829 ifindex = if_nametoindex(intf);
13830 if (ifindex == 0) {
13831 sigma_dut_print(dut, DUT_MSG_ERROR,
13832 "%s: Index for interface %s failed",
13833 __func__, intf);
13834 return -1;
13835 }
13836
13837 if (strcasecmp(oci_frametype, "SAQueryReq") == 0) {
13838 frame_type = QCA_WLAN_VENDOR_OCI_OVERRIDE_FRAME_SA_QUERY_REQ;
13839 } else if (strcasecmp(oci_frametype, "SAQueryResp") == 0) {
13840 frame_type = QCA_WLAN_VENDOR_OCI_OVERRIDE_FRAME_SA_QUERY_RESP;
13841 } else if (strcasecmp(oci_frametype, "Reassocreq") == 0) {
13842 frame_type = QCA_WLAN_VENDOR_OCI_OVERRIDE_FRAME_FT_REASSOC_REQ;
13843 } else {
13844 sigma_dut_print(dut, DUT_MSG_ERROR, "%s: Unknown frametype %s",
13845 __func__, oci_frametype);
13846 return -1;
13847 }
13848
13849
13850 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
13851 NL80211_CMD_VENDOR)) ||
13852 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
13853 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
13854 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
13855 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
13856 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
13857 !(params = nla_nest_start(
13858 msg,
13859 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_OCI_OVERRIDE)) ||
13860 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_OCI_OVERRIDE_FRAME_TYPE,
13861 frame_type) ||
13862 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_OCI_OVERRIDE_FREQUENCY,
13863 oci_freq)) {
13864 sigma_dut_print(dut, DUT_MSG_ERROR,
13865 "%s: err in adding vendor_cmd and vendor_data",
13866 __func__);
13867 nlmsg_free(msg);
13868 return -1;
13869 }
13870 nla_nest_end(msg, params);
13871 nla_nest_end(msg, attr);
13872
13873 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
13874 if (ret) {
13875 sigma_dut_print(dut, DUT_MSG_ERROR,
13876 "%s: err in send_and_recv_msgs, ret=%d",
13877 __func__, ret);
13878 }
13879 return ret;
13880#else /* NL80211_SUPPORT */
13881 sigma_dut_print(dut, DUT_MSG_ERROR,
13882 "OCI override not possible without NL80211_SUPPORT defined");
13883 return -1;
13884#endif /* NL80211_SUPPORT */
13885}
13886
13887
Veerendranath Jakkam50d5c782020-07-22 01:59:01 +053013888static int wcn_sta_ignore_csa(struct sigma_dut *dut, const char *intf,
13889 uint8_t ignore_csa)
13890{
13891#ifdef NL80211_SUPPORT
13892 return wcn_wifi_test_config_set_u8(
13893 dut, intf,
13894 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_IGNORE_CSA, ignore_csa);
13895#else /* NL80211_SUPPORT */
13896 sigma_dut_print(dut, DUT_MSG_ERROR,
13897 "IgnoreCSA can't be set without NL80211_SUPPORT defined");
13898 return -1;
13899#endif /* NL80211_SUPPORT */
13900}
13901
13902
Veerendranath Jakkamc771fac2020-07-22 01:32:56 +053013903static int wcn_sta_set_rsnxe_used(struct sigma_dut *dut, const char *intf,
13904 uint8_t rsnxe_used)
13905{
13906#ifdef NL80211_SUPPORT
13907 return wcn_wifi_test_config_set_u8(
13908 dut, intf,
13909 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_FT_REASSOCREQ_RSNXE_USED,
13910 rsnxe_used);
13911#else /* NL80211_SUPPORT */
13912 sigma_dut_print(dut, DUT_MSG_ERROR,
13913 "RSNXE_Used can't be set without NL80211_SUPPORT defined");
13914 return -1;
13915#endif /* NL80211_SUPPORT */
13916}
13917
13918
Veerendranath Jakkam1e1e5fd2020-09-10 07:12:37 +053013919static int wcn_sta_ignore_sa_query_timeout(struct sigma_dut *dut,
13920 const char *intf,
13921 uint8_t ignore_sa_query_timeout)
13922{
13923#ifdef NL80211_SUPPORT
13924 return wcn_wifi_test_config_set_u8(
13925 dut, intf,
13926 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_IGNORE_SA_QUERY_TIMEOUT,
13927 ignore_sa_query_timeout);
13928#else /* NL80211_SUPPORT */
13929 sigma_dut_print(dut, DUT_MSG_ERROR,
13930 "Ignore SA Query timeout can't be set without NL80211_SUPPORT defined");
13931 return -1;
13932#endif /* NL80211_SUPPORT */
13933}
13934
13935
Jouni Malinen6250cb02020-04-15 13:54:45 +030013936static enum sigma_cmd_result
13937cmd_sta_set_rfeature_wpa3(const char *intf, struct sigma_dut *dut,
13938 struct sigma_conn *conn,
13939 struct sigma_cmd *cmd)
13940{
Vamsi Krishnad29bc762020-05-08 23:23:30 +053013941 const char *val, *oci_chan, *oci_frametype;
Jouni Malinen6250cb02020-04-15 13:54:45 +030013942
Veerendranath Jakkam30bf9072020-04-16 14:37:57 +053013943 val = get_param(cmd, "ReassocReq_RSNXE_Used");
Jouni Malinen6250cb02020-04-15 13:54:45 +030013944 if (val && atoi(val) == 1) {
Veerendranath Jakkamc771fac2020-07-22 01:32:56 +053013945 if (wifi_chip_type == DRIVER_WCN) {
13946 if (wcn_sta_set_rsnxe_used(dut, intf, 1)) {
13947 send_resp(dut, conn, SIGMA_ERROR,
13948 "errorCode,Failed to set ft_rsnxe_used");
13949 return STATUS_SENT_ERROR;
13950 }
13951 return SUCCESS_SEND_STATUS;
13952 } else if (wpa_command(intf, "SET ft_rsnxe_used 1") < 0) {
Jouni Malinen6250cb02020-04-15 13:54:45 +030013953 send_resp(dut, conn, SIGMA_ERROR,
13954 "errorCode,Failed to set ft_rsnxe_used");
13955 return STATUS_SENT_ERROR;
13956 }
13957 return SUCCESS_SEND_STATUS;
13958 }
Vamsi Krishnad29bc762020-05-08 23:23:30 +053013959
13960 oci_chan = get_param(cmd, "OCIChannel");
13961 oci_frametype = get_param(cmd, "OCIFrameType");
13962 if (oci_chan && oci_frametype) {
13963 unsigned int oci_freq = channel_to_freq(dut, atoi(oci_chan));
13964 char buf[100];
13965
13966 if (!oci_freq) {
13967 send_resp(dut, conn, SIGMA_ERROR,
13968 "errorCode,Invalid OCIChannel number");
13969 return STATUS_SENT_ERROR;
13970 }
13971
Veerendranath Jakkam76a845c2020-07-14 13:19:40 +053013972 if (wifi_chip_type == DRIVER_WCN &&
13973 (strcasecmp(oci_frametype, "SAQueryReq") == 0 ||
13974 strcasecmp(oci_frametype, "SAQueryResp") == 0 ||
13975 strcasecmp(oci_frametype, "Reassocreq") == 0)) {
13976 if (wcn_sta_override_oci(dut, intf, oci_frametype,
13977 oci_freq)) {
13978 send_resp(dut, conn, SIGMA_ERROR,
13979 "errorCode,Failed to override OCI");
13980 return STATUS_SENT_ERROR;
13981 }
13982 return SUCCESS_SEND_STATUS;
13983 }
13984
Vamsi Krishnad29bc762020-05-08 23:23:30 +053013985 if (strcasecmp(oci_frametype, "eapolM2") == 0) {
13986 snprintf(buf, sizeof(buf),
13987 "SET oci_freq_override_eapol %d", oci_freq);
13988 } else if (strcasecmp(oci_frametype, "SAQueryReq") == 0) {
13989 snprintf(buf, sizeof(buf),
13990 "SET oci_freq_override_saquery_req %d",
13991 oci_freq);
13992 } else if (strcasecmp(oci_frametype, "SAQueryResp") == 0) {
13993 snprintf(buf, sizeof(buf),
13994 "SET oci_freq_override_saquery_resp %d",
13995 oci_freq);
Veerendranath Jakkam76a845c2020-07-14 13:19:40 +053013996 } else if (strcasecmp(oci_frametype, "GrpKeyM2") == 0) {
13997 snprintf(buf, sizeof(buf),
13998 "SET oci_freq_override_eapol_g2 %d",
13999 oci_freq);
14000 } else if (strcasecmp(oci_frametype, "Reassocreq") == 0) {
14001 snprintf(buf, sizeof(buf),
14002 "SET oci_freq_override_ft_assoc %d",
14003 oci_freq);
Vamsi Krishnad29bc762020-05-08 23:23:30 +053014004 } else {
14005 send_resp(dut, conn, SIGMA_ERROR,
14006 "errorCode,Unsupported OCIFrameType");
14007 return STATUS_SENT_ERROR;
14008 }
14009 if (wpa_command(intf, buf) < 0) {
14010 send_resp(dut, conn, SIGMA_ERROR,
14011 "errorCode,Failed to set oci_freq_override");
14012 return STATUS_SENT_ERROR;
14013 }
14014 return SUCCESS_SEND_STATUS;
14015 }
14016
Veerendranath Jakkam50d5c782020-07-22 01:59:01 +053014017 val = get_param(cmd, "IgnoreCSA");
14018 if (val && atoi(val) == 1) {
14019 if (wifi_chip_type == DRIVER_WCN) {
14020 if (wcn_sta_ignore_csa(dut, intf, 1)) {
14021 send_resp(dut, conn, SIGMA_ERROR,
14022 "errorCode,Failed to set ignore CSA");
14023 return STATUS_SENT_ERROR;
14024 }
14025 return SUCCESS_SEND_STATUS;
14026 }
14027 }
14028
Veerendranath Jakkam1e1e5fd2020-09-10 07:12:37 +053014029 val = get_param(cmd, "Deauth_Per_SAQueryResp");
14030 if (val && atoi(val) == 0) {
14031 if (wifi_chip_type == DRIVER_WCN) {
14032 if (wcn_sta_ignore_sa_query_timeout(dut, intf, 1)) {
14033 send_resp(dut, conn, SIGMA_ERROR,
14034 "errorCode,Failed to set ignore SA Query timeout");
14035 return STATUS_SENT_ERROR;
14036 }
14037 return SUCCESS_SEND_STATUS;
14038 }
14039 }
14040
Jouni Malinen6250cb02020-04-15 13:54:45 +030014041 send_resp(dut, conn, SIGMA_ERROR,
14042 "errorCode,Unsupported WPA3 rfeature");
14043 return STATUS_SENT_ERROR;
14044}
14045
14046
Jouni Malinenf7222712019-06-13 01:50:21 +030014047static enum sigma_cmd_result cmd_sta_set_rfeature(struct sigma_dut *dut,
14048 struct sigma_conn *conn,
14049 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014050{
14051 const char *intf = get_param(cmd, "Interface");
14052 const char *prog = get_param(cmd, "Prog");
Ashwini Patil68d02cd2017-01-10 15:39:16 +053014053 const char *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014054
14055 if (intf == NULL || prog == NULL)
14056 return -1;
14057
Ashwini Patil5acd7382017-04-13 15:55:04 +053014058 /* BSS Transition candidate list for BTM query */
14059 val = get_param(cmd, "Nebor_BSSID");
14060 if (val && btm_query_candidate_list(dut, conn, cmd) == 0)
14061 return 0;
14062
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014063 if (strcasecmp(prog, "TDLS") == 0)
14064 return cmd_sta_set_rfeature_tdls(intf, dut, conn, cmd);
14065
14066 if (strcasecmp(prog, "VHT") == 0)
14067 return cmd_sta_set_rfeature_vht(intf, dut, conn, cmd);
14068
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014069 if (strcasecmp(prog, "HE") == 0)
14070 return cmd_sta_set_rfeature_he(intf, dut, conn, cmd);
14071
Ashwini Patil68d02cd2017-01-10 15:39:16 +053014072 if (strcasecmp(prog, "MBO") == 0) {
14073 val = get_param(cmd, "Cellular_Data_Cap");
14074 if (val &&
14075 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
14076 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +053014077
14078 val = get_param(cmd, "Ch_Pref");
14079 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
14080 return 0;
14081
Ashwini Patil68d02cd2017-01-10 15:39:16 +053014082 return 1;
14083 }
14084
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020014085 if (strcasecmp(prog, "60GHz") == 0)
14086 return cmd_sta_set_rfeature_60g(intf, dut, conn, cmd);
14087
Jouni Malinen6250cb02020-04-15 13:54:45 +030014088 if (strcasecmp(prog, "WPA3") == 0)
14089 return cmd_sta_set_rfeature_wpa3(intf, dut, conn, cmd);
14090
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014091 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported Prog");
14092 return 0;
14093}
14094
14095
Jouni Malinenf7222712019-06-13 01:50:21 +030014096static enum sigma_cmd_result cmd_sta_set_radio(struct sigma_dut *dut,
14097 struct sigma_conn *conn,
14098 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014099{
14100 const char *intf = get_param(cmd, "Interface");
14101 const char *mode = get_param(cmd, "Mode");
14102 int res;
14103
14104 if (intf == NULL || mode == NULL)
14105 return -1;
14106
14107 if (strcasecmp(mode, "On") == 0)
14108 res = wpa_command(intf, "SET radio_disabled 0");
14109 else if (strcasecmp(mode, "Off") == 0)
14110 res = wpa_command(intf, "SET radio_disabled 1");
14111 else
14112 return -1;
14113
14114 if (res) {
14115 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
14116 "radio mode");
14117 return 0;
14118 }
14119
14120 return 1;
14121}
14122
14123
Jouni Malinenf7222712019-06-13 01:50:21 +030014124static enum sigma_cmd_result cmd_sta_set_pwrsave(struct sigma_dut *dut,
14125 struct sigma_conn *conn,
14126 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014127{
14128 const char *intf = get_param(cmd, "Interface");
14129 const char *mode = get_param(cmd, "Mode");
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020014130 const char *prog = get_param(cmd, "program");
14131 const char *powersave = get_param(cmd, "powersave");
14132 int res = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014133
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020014134 if (intf == NULL)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014135 return -1;
14136
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020014137 if (prog && strcasecmp(prog, "60GHz") == 0) {
14138 /*
14139 * The CAPI mode parameter does not exist in 60G
14140 * unscheduled PS.
14141 */
Hu Wang5dc3ff12019-06-14 15:14:26 +080014142 if (powersave && strcasecmp(powersave, "unscheduled") == 0)
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020014143 res = set_ps(intf, dut, 1);
Jouni Malinen016ae6c2019-11-04 17:00:01 +020014144 } else if (prog && get_driver_type(dut) == DRIVER_WCN &&
Alexei Avshalom Lazar2f6fdb42019-02-04 14:16:08 +020014145 strcasecmp(prog, "HE") == 0) {
14146 return cmd_sta_set_power_save_he(intf, dut, conn, cmd);
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020014147 } else {
14148 if (mode == NULL)
14149 return -1;
14150
14151 if (strcasecmp(mode, "On") == 0)
14152 res = set_ps(intf, dut, 1);
14153 else if (strcasecmp(mode, "Off") == 0)
14154 res = set_ps(intf, dut, 0);
14155 else
14156 return -1;
14157 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014158
14159 if (res) {
14160 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
14161 "power save mode");
14162 return 0;
14163 }
14164
14165 return 1;
14166}
14167
14168
Jouni Malinenf7222712019-06-13 01:50:21 +030014169static enum sigma_cmd_result cmd_sta_bssid_pool(struct sigma_dut *dut,
14170 struct sigma_conn *conn,
14171 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014172{
14173 const char *intf = get_param(cmd, "Interface");
14174 const char *val, *bssid;
14175 int res;
14176 char *buf;
14177 size_t buf_len;
14178
14179 val = get_param(cmd, "BSSID_FILTER");
14180 if (val == NULL)
14181 return -1;
14182
14183 bssid = get_param(cmd, "BSSID_List");
14184 if (atoi(val) == 0 || bssid == NULL) {
14185 /* Disable BSSID filter */
14186 if (wpa_command(intf, "SET bssid_filter ")) {
14187 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed "
14188 "to disable BSSID filter");
14189 return 0;
14190 }
14191
14192 return 1;
14193 }
14194
14195 buf_len = 100 + strlen(bssid);
14196 buf = malloc(buf_len);
14197 if (buf == NULL)
14198 return -1;
14199
14200 snprintf(buf, buf_len, "SET bssid_filter %s", bssid);
14201 res = wpa_command(intf, buf);
14202 free(buf);
14203 if (res) {
14204 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to enable "
14205 "BSSID filter");
14206 return 0;
14207 }
14208
14209 return 1;
14210}
14211
14212
Jouni Malinenf7222712019-06-13 01:50:21 +030014213static enum sigma_cmd_result cmd_sta_reset_parm(struct sigma_dut *dut,
14214 struct sigma_conn *conn,
14215 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014216{
14217 const char *intf = get_param(cmd, "Interface");
14218 const char *val;
14219
14220 /* TODO: ARP */
14221
14222 val = get_param(cmd, "HS2_CACHE_PROFILE");
14223 if (val && strcasecmp(val, "All") == 0)
14224 hs2_clear_credentials(intf);
14225
14226 return 1;
14227}
14228
14229
Jouni Malinenf7222712019-06-13 01:50:21 +030014230static enum sigma_cmd_result cmd_sta_get_key(struct sigma_dut *dut,
14231 struct sigma_conn *conn,
14232 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014233{
14234 const char *intf = get_param(cmd, "Interface");
14235 const char *key_type = get_param(cmd, "KeyType");
14236 char buf[100], resp[200];
14237
14238 if (key_type == NULL)
14239 return -1;
14240
14241 if (strcasecmp(key_type, "GTK") == 0) {
14242 if (wpa_command_resp(intf, "GET gtk", buf, sizeof(buf)) < 0 ||
14243 strncmp(buf, "FAIL", 4) == 0) {
14244 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
14245 "not fetch current GTK");
14246 return 0;
14247 }
14248 snprintf(resp, sizeof(resp), "KeyValue,%s", buf);
14249 send_resp(dut, conn, SIGMA_COMPLETE, resp);
14250 return 0;
14251 } else {
14252 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
14253 "KeyType");
14254 return 0;
14255 }
14256
14257 return 1;
14258}
14259
14260
14261static int hs2_set_policy(struct sigma_dut *dut)
14262{
14263#ifdef ANDROID
14264 system("ip rule del prio 23000");
14265 if (system("ip rule add from all lookup main prio 23000") != 0) {
14266 sigma_dut_print(dut, DUT_MSG_ERROR,
14267 "Failed to run:ip rule add from all lookup main prio");
14268 return -1;
14269 }
14270 if (system("ip route flush cache") != 0) {
14271 sigma_dut_print(dut, DUT_MSG_ERROR,
14272 "Failed to run ip route flush cache");
14273 return -1;
14274 }
14275 return 1;
14276#else /* ANDROID */
14277 return 0;
14278#endif /* ANDROID */
14279}
14280
14281
Jouni Malinenf7222712019-06-13 01:50:21 +030014282static enum sigma_cmd_result cmd_sta_hs2_associate(struct sigma_dut *dut,
14283 struct sigma_conn *conn,
14284 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014285{
14286 const char *intf = get_param(cmd, "Interface");
14287 const char *val = get_param(cmd, "Ignore_blacklist");
Jouni Malinen439352d2018-09-13 03:42:23 +030014288 const char *band = get_param(cmd, "Band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014289 struct wpa_ctrl *ctrl;
Jouni Malinen3aa72862019-05-29 23:14:51 +030014290 int res, r;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014291 char bssid[20], ssid[40], resp[100], buf[100], blacklisted[100];
14292 int tries = 0;
14293 int ignore_blacklist = 0;
14294 const char *events[] = {
14295 "CTRL-EVENT-CONNECTED",
14296 "INTERWORKING-BLACKLISTED",
14297 "INTERWORKING-NO-MATCH",
14298 NULL
14299 };
14300
14301 start_sta_mode(dut);
14302
Jouni Malinen439352d2018-09-13 03:42:23 +030014303 if (band) {
14304 if (strcmp(band, "2.4") == 0) {
14305 wpa_command(intf, "SET setband 2G");
14306 } else if (strcmp(band, "5") == 0) {
14307 wpa_command(intf, "SET setband 5G");
14308 } else {
14309 send_resp(dut, conn, SIGMA_ERROR,
14310 "errorCode,Unsupported band");
14311 return 0;
14312 }
14313 }
14314
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014315 blacklisted[0] = '\0';
14316 if (val && atoi(val))
14317 ignore_blacklist = 1;
14318
14319try_again:
14320 ctrl = open_wpa_mon(intf);
14321 if (ctrl == NULL) {
14322 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
14323 "wpa_supplicant monitor connection");
14324 return -2;
14325 }
14326
14327 tries++;
14328 if (wpa_command(intf, "INTERWORKING_SELECT auto")) {
14329 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start "
14330 "Interworking connection");
14331 wpa_ctrl_detach(ctrl);
14332 wpa_ctrl_close(ctrl);
14333 return 0;
14334 }
14335
14336 buf[0] = '\0';
14337 while (1) {
14338 char *pos;
14339 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
14340 pos = strstr(buf, "INTERWORKING-BLACKLISTED");
14341 if (!pos)
14342 break;
14343 pos += 25;
14344 sigma_dut_print(dut, DUT_MSG_DEBUG, "Found blacklisted AP: %s",
14345 pos);
14346 if (!blacklisted[0])
14347 memcpy(blacklisted, pos, strlen(pos) + 1);
14348 }
14349
14350 if (ignore_blacklist && blacklisted[0]) {
14351 char *end;
14352 end = strchr(blacklisted, ' ');
14353 if (end)
14354 *end = '\0';
14355 sigma_dut_print(dut, DUT_MSG_DEBUG, "Try to connect to a blacklisted network: %s",
14356 blacklisted);
Jouni Malinen3aa72862019-05-29 23:14:51 +030014357 r = snprintf(buf, sizeof(buf), "INTERWORKING_CONNECT %s",
14358 blacklisted);
14359 if (r < 0 || r >= sizeof(buf) || wpa_command(intf, buf)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014360 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start Interworking connection to blacklisted network");
14361 wpa_ctrl_detach(ctrl);
14362 wpa_ctrl_close(ctrl);
14363 return 0;
14364 }
14365 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
14366 buf, sizeof(buf));
14367 }
14368
14369 wpa_ctrl_detach(ctrl);
14370 wpa_ctrl_close(ctrl);
14371
14372 if (res < 0) {
14373 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
14374 "connect");
14375 return 0;
14376 }
14377
14378 if (strstr(buf, "INTERWORKING-NO-MATCH") ||
14379 strstr(buf, "INTERWORKING-BLACKLISTED")) {
14380 if (tries < 2) {
14381 sigma_dut_print(dut, DUT_MSG_INFO, "No match found - try again to verify no APs were missed in the scan");
14382 goto try_again;
14383 }
14384 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,No network with "
14385 "matching credentials found");
14386 return 0;
14387 }
14388
14389 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
14390 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
14391 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
14392 "get current BSSID/SSID");
14393 return 0;
14394 }
14395
14396 snprintf(resp, sizeof(resp), "SSID,%s,BSSID,%s", ssid, bssid);
14397 send_resp(dut, conn, SIGMA_COMPLETE, resp);
14398 hs2_set_policy(dut);
14399 return 0;
14400}
14401
14402
Jouni Malinenf7222712019-06-13 01:50:21 +030014403static enum sigma_cmd_result cmd_sta_hs2_venue_info(struct sigma_dut *dut,
14404 struct sigma_conn *conn,
14405 struct sigma_cmd *cmd)
Jouni Malinenb639f1c2018-09-13 02:39:46 +030014406{
14407 const char *intf = get_param(cmd, "Interface");
14408 const char *display = get_param(cmd, "Display");
14409 struct wpa_ctrl *ctrl;
14410 char buf[300], params[400], *pos;
14411 char bssid[20];
14412 int info_avail = 0;
14413 unsigned int old_timeout;
14414 int res;
14415
14416 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0) {
14417 send_resp(dut, conn, SIGMA_ERROR,
14418 "ErrorCode,Could not get current BSSID");
14419 return 0;
14420 }
14421 ctrl = open_wpa_mon(intf);
14422 if (!ctrl) {
14423 sigma_dut_print(dut, DUT_MSG_ERROR,
14424 "Failed to open wpa_supplicant monitor connection");
14425 return -2;
14426 }
14427
14428 snprintf(buf, sizeof(buf), "ANQP_GET %s 277", bssid);
14429 wpa_command(intf, buf);
14430
14431 res = get_wpa_cli_event(dut, ctrl, "GAS-QUERY-DONE", buf, sizeof(buf));
14432 if (res < 0) {
14433 send_resp(dut, conn, SIGMA_ERROR,
14434 "ErrorCode,Could not complete GAS query");
14435 goto fail;
14436 }
14437
14438 old_timeout = dut->default_timeout;
14439 dut->default_timeout = 2;
14440 res = get_wpa_cli_event(dut, ctrl, "RX-VENUE-URL", buf, sizeof(buf));
14441 dut->default_timeout = old_timeout;
14442 if (res < 0)
14443 goto done;
14444 pos = strchr(buf, ' ');
14445 if (!pos)
14446 goto done;
14447 pos++;
14448 pos = strchr(pos, ' ');
14449 if (!pos)
14450 goto done;
14451 pos++;
14452 info_avail = 1;
14453 snprintf(params, sizeof(params), "browser %s", pos);
14454
14455 if (display && strcasecmp(display, "Yes") == 0) {
14456 pid_t pid;
14457
14458 pid = fork();
14459 if (pid < 0) {
14460 perror("fork");
14461 return -1;
14462 }
14463
14464 if (pid == 0) {
14465 run_hs20_osu(dut, params);
14466 exit(0);
14467 }
14468 }
14469
14470done:
14471 snprintf(buf, sizeof(buf), "Info_available,%s",
14472 info_avail ? "Yes" : "No");
14473 send_resp(dut, conn, SIGMA_COMPLETE, buf);
14474fail:
14475 wpa_ctrl_detach(ctrl);
14476 wpa_ctrl_close(ctrl);
14477 return 0;
14478}
14479
14480
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014481static int sta_add_credential_uname_pwd(struct sigma_dut *dut,
14482 struct sigma_conn *conn,
14483 const char *ifname,
14484 struct sigma_cmd *cmd)
14485{
14486 const char *val;
14487 int id;
14488
14489 id = add_cred(ifname);
14490 if (id < 0)
14491 return -2;
14492 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
14493
14494 val = get_param(cmd, "prefer");
14495 if (val && atoi(val) > 0)
14496 set_cred(ifname, id, "priority", "1");
14497
14498 val = get_param(cmd, "REALM");
14499 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
14500 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
14501 "realm");
14502 return 0;
14503 }
14504
14505 val = get_param(cmd, "HOME_FQDN");
14506 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
14507 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
14508 "home_fqdn");
14509 return 0;
14510 }
14511
14512 val = get_param(cmd, "Username");
14513 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
14514 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
14515 "username");
14516 return 0;
14517 }
14518
14519 val = get_param(cmd, "Password");
14520 if (val && set_cred_quoted(ifname, id, "password", val) < 0) {
14521 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
14522 "password");
14523 return 0;
14524 }
14525
14526 val = get_param(cmd, "ROOT_CA");
14527 if (val) {
14528 char fname[200];
14529 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
14530#ifdef __linux__
14531 if (!file_exists(fname)) {
14532 char msg[300];
14533 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
14534 "file (%s) not found", fname);
14535 send_resp(dut, conn, SIGMA_ERROR, msg);
14536 return 0;
14537 }
14538#endif /* __linux__ */
14539 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
14540 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
14541 "not set root CA");
14542 return 0;
14543 }
14544 }
14545
14546 return 1;
14547}
14548
14549
14550static int update_devdetail_imsi(struct sigma_dut *dut, const char *imsi)
14551{
14552 FILE *in, *out;
14553 char buf[500];
14554 int found = 0;
14555
14556 in = fopen("devdetail.xml", "r");
14557 if (in == NULL)
14558 return -1;
14559 out = fopen("devdetail.xml.tmp", "w");
14560 if (out == NULL) {
14561 fclose(in);
14562 return -1;
14563 }
14564
14565 while (fgets(buf, sizeof(buf), in)) {
14566 char *pos = strstr(buf, "<IMSI>");
14567 if (pos) {
14568 sigma_dut_print(dut, DUT_MSG_INFO, "Updated DevDetail IMSI to %s",
14569 imsi);
14570 pos += 6;
14571 *pos = '\0';
14572 fprintf(out, "%s%s</IMSI>\n", buf, imsi);
14573 found++;
14574 } else {
14575 fprintf(out, "%s", buf);
14576 }
14577 }
14578
14579 fclose(out);
14580 fclose(in);
14581 if (found)
14582 rename("devdetail.xml.tmp", "devdetail.xml");
14583 else
14584 unlink("devdetail.xml.tmp");
14585
14586 return 0;
14587}
14588
14589
14590static int sta_add_credential_sim(struct sigma_dut *dut,
14591 struct sigma_conn *conn,
14592 const char *ifname, struct sigma_cmd *cmd)
14593{
14594 const char *val, *imsi = NULL;
14595 int id;
14596 char buf[200];
14597 int res;
14598 const char *pos;
14599 size_t mnc_len;
14600 char plmn_mcc[4];
14601 char plmn_mnc[4];
14602
14603 id = add_cred(ifname);
14604 if (id < 0)
14605 return -2;
14606 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
14607
14608 val = get_param(cmd, "prefer");
14609 if (val && atoi(val) > 0)
14610 set_cred(ifname, id, "priority", "1");
14611
14612 val = get_param(cmd, "PLMN_MCC");
14613 if (val == NULL) {
14614 send_resp(dut, conn, SIGMA_ERROR,
14615 "errorCode,Missing PLMN_MCC");
14616 return 0;
14617 }
14618 if (strlen(val) != 3) {
14619 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MCC");
14620 return 0;
14621 }
14622 snprintf(plmn_mcc, sizeof(plmn_mcc), "%s", val);
14623
14624 val = get_param(cmd, "PLMN_MNC");
14625 if (val == NULL) {
14626 send_resp(dut, conn, SIGMA_ERROR,
14627 "errorCode,Missing PLMN_MNC");
14628 return 0;
14629 }
14630 if (strlen(val) != 2 && strlen(val) != 3) {
14631 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MNC");
14632 return 0;
14633 }
14634 snprintf(plmn_mnc, sizeof(plmn_mnc), "%s", val);
14635
14636 val = get_param(cmd, "IMSI");
14637 if (val == NULL) {
14638 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing SIM "
14639 "IMSI");
14640 return 0;
14641 }
14642
14643 imsi = pos = val;
14644
14645 if (strncmp(plmn_mcc, pos, 3) != 0) {
14646 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MCC mismatch");
14647 return 0;
14648 }
14649 pos += 3;
14650
14651 mnc_len = strlen(plmn_mnc);
14652 if (mnc_len < 2) {
14653 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC not set");
14654 return 0;
14655 }
14656
14657 if (strncmp(plmn_mnc, pos, mnc_len) != 0) {
14658 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC mismatch");
14659 return 0;
14660 }
14661 pos += mnc_len;
14662
14663 res = snprintf(buf, sizeof(buf), "%s%s-%s",plmn_mcc, plmn_mnc, pos);
14664 if (res < 0 || res >= (int) sizeof(buf))
14665 return -1;
14666 if (set_cred_quoted(ifname, id, "imsi", buf) < 0) {
14667 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
14668 "not set IMSI");
14669 return 0;
14670 }
14671
14672 val = get_param(cmd, "Password");
14673 if (val && set_cred_quoted(ifname, id, "milenage", val) < 0) {
14674 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
14675 "not set password");
14676 return 0;
14677 }
14678
Jouni Malinenba630452018-06-22 11:49:59 +030014679 if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014680 /*
14681 * Set provisioning_sp for the test cases where SIM/USIM
14682 * provisioning is used.
14683 */
14684 if (val && set_cred_quoted(ifname, id, "provisioning_sp",
14685 "wi-fi.org") < 0) {
14686 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
14687 "not set provisioning_sp");
14688 return 0;
14689 }
14690
14691 update_devdetail_imsi(dut, imsi);
14692 }
14693
14694 return 1;
14695}
14696
14697
14698static int sta_add_credential_cert(struct sigma_dut *dut,
14699 struct sigma_conn *conn,
14700 const char *ifname,
14701 struct sigma_cmd *cmd)
14702{
14703 const char *val;
14704 int id;
14705
14706 id = add_cred(ifname);
14707 if (id < 0)
14708 return -2;
14709 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
14710
14711 val = get_param(cmd, "prefer");
14712 if (val && atoi(val) > 0)
14713 set_cred(ifname, id, "priority", "1");
14714
14715 val = get_param(cmd, "REALM");
14716 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
14717 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
14718 "realm");
14719 return 0;
14720 }
14721
14722 val = get_param(cmd, "HOME_FQDN");
14723 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
14724 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
14725 "home_fqdn");
14726 return 0;
14727 }
14728
14729 val = get_param(cmd, "Username");
14730 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
14731 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
14732 "username");
14733 return 0;
14734 }
14735
14736 val = get_param(cmd, "clientCertificate");
14737 if (val) {
14738 char fname[200];
14739 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
14740#ifdef __linux__
14741 if (!file_exists(fname)) {
14742 char msg[300];
14743 snprintf(msg, sizeof(msg),
14744 "ErrorCode,clientCertificate "
14745 "file (%s) not found", fname);
14746 send_resp(dut, conn, SIGMA_ERROR, msg);
14747 return 0;
14748 }
14749#endif /* __linux__ */
14750 if (set_cred_quoted(ifname, id, "client_cert", fname) < 0) {
14751 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
14752 "not set client_cert");
14753 return 0;
14754 }
14755 if (set_cred_quoted(ifname, id, "private_key", fname) < 0) {
14756 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
14757 "not set private_key");
14758 return 0;
14759 }
14760 }
14761
14762 val = get_param(cmd, "ROOT_CA");
14763 if (val) {
14764 char fname[200];
14765 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
14766#ifdef __linux__
14767 if (!file_exists(fname)) {
14768 char msg[300];
14769 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
14770 "file (%s) not found", fname);
14771 send_resp(dut, conn, SIGMA_ERROR, msg);
14772 return 0;
14773 }
14774#endif /* __linux__ */
14775 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
14776 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
14777 "not set root CA");
14778 return 0;
14779 }
14780 }
14781
14782 return 1;
14783}
14784
14785
Jouni Malinenf7222712019-06-13 01:50:21 +030014786static enum sigma_cmd_result cmd_sta_add_credential(struct sigma_dut *dut,
14787 struct sigma_conn *conn,
14788 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014789{
14790 const char *intf = get_param(cmd, "Interface");
14791 const char *type;
14792
14793 start_sta_mode(dut);
14794
14795 type = get_param(cmd, "Type");
14796 if (!type)
14797 return -1;
14798
14799 if (strcasecmp(type, "uname_pwd") == 0)
14800 return sta_add_credential_uname_pwd(dut, conn, intf, cmd);
14801
14802 if (strcasecmp(type, "sim") == 0)
14803 return sta_add_credential_sim(dut, conn, intf, cmd);
14804
14805 if (strcasecmp(type, "cert") == 0)
14806 return sta_add_credential_cert(dut, conn, intf, cmd);
14807
14808 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported credential "
14809 "type");
14810 return 0;
14811}
14812
14813
Jouni Malinenf7222712019-06-13 01:50:21 +030014814static enum sigma_cmd_result cmd_sta_scan(struct sigma_dut *dut,
14815 struct sigma_conn *conn,
14816 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014817{
14818 const char *intf = get_param(cmd, "Interface");
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080014819 const char *val, *bssid, *ssid, *scan_freq, *short_ssid;
Veerendranathdc581b52020-08-10 03:29:08 -070014820 char buf[4096], scan_res[20];
vamsi krishna89ad8c62017-09-19 12:51:18 +053014821 char ssid_hex[65];
Kiran Kumar Lokere3399af22020-03-04 16:31:56 -080014822 int wildcard_ssid = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014823 int res;
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080014824 enum sigma_cmd_result status;
Jouni Malinen228a2fc2020-06-22 23:37:45 +030014825 struct wpa_ctrl *ctrl = NULL;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014826
Jouni Malinen8c1abeb2019-11-06 18:48:34 +020014827 start_sta_mode(dut);
14828
Arif Hussain66a4af02019-02-07 15:04:51 -080014829 val = get_param(cmd, "GetParameter");
14830 if (val && strcmp(val, "SSID_BSSID") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020014831 if (get_wpa_ssid_bssid(dut, get_station_ifname(dut),
Arif Hussain66a4af02019-02-07 15:04:51 -080014832 buf, sizeof(buf)) < 0) {
14833 sigma_dut_print(dut, DUT_MSG_ERROR,
14834 "Could not get ssid bssid");
14835 return ERROR_SEND_STATUS;
14836 }
14837
14838 sigma_dut_print(dut, DUT_MSG_INFO, "%s", buf);
14839 send_resp(dut, conn, SIGMA_COMPLETE, buf);
14840 return STATUS_SENT;
14841 }
14842
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014843 val = get_param(cmd, "HESSID");
14844 if (val) {
14845 res = snprintf(buf, sizeof(buf), "SET hessid %s", val);
14846 if (res < 0 || res >= (int) sizeof(buf))
14847 return -1;
14848 wpa_command(intf, buf);
14849 }
14850
14851 val = get_param(cmd, "ACCS_NET_TYPE");
14852 if (val) {
14853 res = snprintf(buf, sizeof(buf), "SET access_network_type %s",
14854 val);
14855 if (res < 0 || res >= (int) sizeof(buf))
14856 return -1;
14857 wpa_command(intf, buf);
14858 }
14859
Kiran Kumar Lokere69d89952021-08-08 23:41:46 -070014860 if (get_param(cmd, "RxMac"))
14861 sta_set_scan_unicast_probe(dut, intf, 1);
14862
vamsi krishna89ad8c62017-09-19 12:51:18 +053014863 bssid = get_param(cmd, "Bssid");
14864 ssid = get_param(cmd, "Ssid");
Kiran Kumar Lokere69d89952021-08-08 23:41:46 -070014865 if (!bssid)
14866 bssid = get_param(cmd, "RxMac");
vamsi krishna89ad8c62017-09-19 12:51:18 +053014867
Kiran Kumar Lokere3399af22020-03-04 16:31:56 -080014868 if (ssid && strcasecmp(ssid, "ZeroLength") == 0 &&
14869 dut->device_type == STA_testbed) {
14870 ssid = NULL;
14871 wildcard_ssid = 1;
14872 }
14873
vamsi krishna89ad8c62017-09-19 12:51:18 +053014874 if (ssid) {
14875 if (2 * strlen(ssid) >= sizeof(ssid_hex)) {
14876 send_resp(dut, conn, SIGMA_ERROR,
14877 "ErrorCode,Too long SSID");
14878 return 0;
14879 }
14880 ascii2hexstr(ssid, ssid_hex);
14881 }
14882
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080014883 short_ssid = get_param(cmd, "ShortSSID");
14884 if (short_ssid) {
14885 uint32_t short_ssid_hex;
14886
14887 short_ssid_hex = strtoul(short_ssid, NULL, 16);
14888 short_ssid_hex = ((short_ssid_hex & 0xFF) << 24) |
14889 (((short_ssid_hex >> 8) & 0xFF) << 16) |
14890 (((short_ssid_hex >> 16) & 0xFF) << 8) |
14891 ((short_ssid_hex >> 24) & 0xFF);
14892
14893 res = snprintf(buf, sizeof(buf),
14894 "VENDOR_ELEM_ADD 14 ff053a%08x",
14895 short_ssid_hex);
14896 if (res < 0 || res >= (int) sizeof(buf) ||
14897 wpa_command(intf, buf)) {
14898 send_resp(dut, conn, SIGMA_ERROR,
14899 "errorCode,Failed to add short SSID");
14900 return STATUS_SENT_ERROR;
14901 }
14902 }
14903
Kiran Kumar Lokerec0deb482020-03-04 16:35:06 -080014904 scan_freq = get_param(cmd, "ChnlFreq");
Veerendranath Jakkam132c4b42020-08-10 00:29:03 +053014905 if (scan_freq) {
14906 if (strcasecmp(scan_freq, "2G") == 0)
14907 scan_freq = "2412-2462";
14908 else if (strcasecmp(scan_freq, "5G") == 0)
14909 scan_freq = "5180-5925";
14910 }
Kiran Kumar Lokerec0deb482020-03-04 16:35:06 -080014911
Jouni Malinen228a2fc2020-06-22 23:37:45 +030014912 val = get_param(cmd, "WaitCompletion");
14913 if (val && atoi(val) == 1) {
14914 ctrl = open_wpa_mon(intf);
14915 if (!ctrl) {
14916 send_resp(dut, conn, SIGMA_ERROR,
14917 "errorCode,Failed to open monitor socket");
14918 return STATUS_SENT_ERROR;
14919 }
14920 }
14921
Kiran Kumar Lokerec0deb482020-03-04 16:35:06 -080014922 res = snprintf(buf, sizeof(buf), "SCAN%s%s%s%s%s%s%s",
vamsi krishna89ad8c62017-09-19 12:51:18 +053014923 bssid ? " bssid=": "",
14924 bssid ? bssid : "",
14925 ssid ? " ssid " : "",
Kiran Kumar Lokere3399af22020-03-04 16:31:56 -080014926 ssid ? ssid_hex : "",
Kiran Kumar Lokerec0deb482020-03-04 16:35:06 -080014927 wildcard_ssid ? " wildcard_ssid=1" : "",
14928 scan_freq ? " freq=" : "",
14929 scan_freq ? scan_freq : "");
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080014930 if (res < 0 || res >= (int) sizeof(buf)) {
14931 send_resp(dut, conn, SIGMA_ERROR,
14932 "errorCode,Could not build scan command");
14933 status = STATUS_SENT_ERROR;
14934 goto remove_s_ssid;
14935 }
vamsi krishna89ad8c62017-09-19 12:51:18 +053014936
Veerendranathdc581b52020-08-10 03:29:08 -070014937 res = wpa_command_resp(intf, buf, scan_res, sizeof(scan_res));
14938 if (strncmp(scan_res, "FAIL-BUSY", 9) == 0) {
14939 sigma_dut_print(dut, DUT_MSG_DEBUG,
14940 "Scan request rejected with busy status, abort ongoing scan and try again");
14941 wpa_command(intf, "ABORT_SCAN");
14942 res = wpa_command(intf, buf);
14943 }
14944
14945 if (res < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014946 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not start "
14947 "scan");
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080014948 status = STATUS_SENT_ERROR;
14949 } else {
14950 status = SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014951 }
14952
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080014953remove_s_ssid:
14954 if (short_ssid && wpa_command(intf, "VENDOR_ELEM_REMOVE 14 *"))
14955 sigma_dut_print(dut, DUT_MSG_ERROR,
14956 "Failed to delete vendor element");
14957
Jouni Malinen228a2fc2020-06-22 23:37:45 +030014958 if (ctrl) {
14959 if (status == SUCCESS_SEND_STATUS) {
14960 res = get_wpa_cli_event(dut, ctrl,
14961 "CTRL-EVENT-SCAN-RESULTS",
14962 buf, sizeof(buf));
14963 if (res < 0) {
14964 send_resp(dut, conn, SIGMA_ERROR,
14965 "ErrorCode,scan did not complete");
14966 status = STATUS_SENT_ERROR;
14967 }
14968 }
14969
14970 wpa_ctrl_detach(ctrl);
14971 wpa_ctrl_close(ctrl);
14972 }
14973
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080014974 return status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014975}
14976
14977
Jouni Malinenf7222712019-06-13 01:50:21 +030014978static enum sigma_cmd_result cmd_sta_scan_bss(struct sigma_dut *dut,
14979 struct sigma_conn *conn,
14980 struct sigma_cmd *cmd)
Jouni Malinen5e5d43d2018-01-10 17:29:33 +020014981{
14982 const char *intf = get_param(cmd, "Interface");
14983 const char *bssid;
14984 char buf[4096], *pos;
14985 int freq, chan;
14986 char *ssid;
14987 char resp[100];
14988 int res;
14989 struct wpa_ctrl *ctrl;
14990
14991 bssid = get_param(cmd, "BSSID");
14992 if (!bssid) {
14993 send_resp(dut, conn, SIGMA_INVALID,
14994 "errorCode,BSSID argument is missing");
14995 return 0;
14996 }
14997
14998 ctrl = open_wpa_mon(intf);
14999 if (!ctrl) {
15000 sigma_dut_print(dut, DUT_MSG_ERROR,
15001 "Failed to open wpa_supplicant monitor connection");
15002 return -1;
15003 }
15004
15005 if (wpa_command(intf, "SCAN TYPE=ONLY")) {
15006 send_resp(dut, conn, SIGMA_ERROR,
15007 "errorCode,Could not start scan");
15008 wpa_ctrl_detach(ctrl);
15009 wpa_ctrl_close(ctrl);
15010 return 0;
15011 }
15012
15013 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
15014 buf, sizeof(buf));
15015
15016 wpa_ctrl_detach(ctrl);
15017 wpa_ctrl_close(ctrl);
15018
15019 if (res < 0) {
15020 send_resp(dut, conn, SIGMA_ERROR,
15021 "errorCode,Scan did not complete");
15022 return 0;
15023 }
15024
15025 snprintf(buf, sizeof(buf), "BSS %s", bssid);
15026 if (wpa_command_resp(intf, buf, buf, sizeof(buf)) < 0 ||
15027 strncmp(buf, "id=", 3) != 0) {
15028 send_resp(dut, conn, SIGMA_ERROR,
15029 "errorCode,Specified BSSID not found");
15030 return 0;
15031 }
15032
15033 pos = strstr(buf, "\nfreq=");
15034 if (!pos) {
15035 send_resp(dut, conn, SIGMA_ERROR,
15036 "errorCode,Channel not found");
15037 return 0;
15038 }
15039 freq = atoi(pos + 6);
15040 chan = freq_to_channel(freq);
15041
15042 pos = strstr(buf, "\nssid=");
15043 if (!pos) {
15044 send_resp(dut, conn, SIGMA_ERROR,
15045 "errorCode,SSID not found");
15046 return 0;
15047 }
15048 ssid = pos + 6;
15049 pos = strchr(ssid, '\n');
15050 if (pos)
15051 *pos = '\0';
15052 snprintf(resp, sizeof(resp), "ssid,%s,bsschannel,%d", ssid, chan);
15053 send_resp(dut, conn, SIGMA_COMPLETE, resp);
15054 return 0;
15055}
15056
15057
Jouni Malinenf7222712019-06-13 01:50:21 +030015058static enum sigma_cmd_result cmd_sta_set_systime(struct sigma_dut *dut,
15059 struct sigma_conn *conn,
15060 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015061{
15062#ifdef __linux__
15063 struct timeval tv;
15064 struct tm tm;
15065 time_t t;
15066 const char *val;
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +053015067 int v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015068
Jouni Malinen016ae6c2019-11-04 17:00:01 +020015069 wpa_command(get_station_ifname(dut), "PMKSA_FLUSH");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015070
15071 memset(&tm, 0, sizeof(tm));
15072 val = get_param(cmd, "seconds");
15073 if (val)
15074 tm.tm_sec = atoi(val);
15075 val = get_param(cmd, "minutes");
15076 if (val)
15077 tm.tm_min = atoi(val);
15078 val = get_param(cmd, "hours");
15079 if (val)
15080 tm.tm_hour = atoi(val);
15081 val = get_param(cmd, "date");
15082 if (val)
15083 tm.tm_mday = atoi(val);
15084 val = get_param(cmd, "month");
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +053015085 if (val) {
15086 v = atoi(val);
15087 if (v < 1 || v > 12) {
15088 send_resp(dut, conn, SIGMA_INVALID,
15089 "errorCode,Invalid month");
15090 return 0;
15091 }
15092 tm.tm_mon = v - 1;
15093 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015094 val = get_param(cmd, "year");
15095 if (val) {
15096 int year = atoi(val);
15097#ifdef ANDROID
15098 if (year > 2035)
15099 year = 2035; /* years beyond 2035 not supported */
15100#endif /* ANDROID */
15101 tm.tm_year = year - 1900;
15102 }
15103 t = mktime(&tm);
15104 if (t == (time_t) -1) {
15105 send_resp(dut, conn, SIGMA_ERROR,
15106 "errorCode,Invalid date or time");
15107 return 0;
15108 }
15109
15110 memset(&tv, 0, sizeof(tv));
15111 tv.tv_sec = t;
15112
15113 if (settimeofday(&tv, NULL) < 0) {
15114 sigma_dut_print(dut, DUT_MSG_INFO, "settimeofday failed: %s",
15115 strerror(errno));
15116 send_resp(dut, conn, SIGMA_ERROR,
15117 "errorCode,Failed to set time");
15118 return 0;
15119 }
15120
15121 return 1;
15122#endif /* __linux__ */
15123
15124 return -1;
15125}
15126
15127
Jouni Malinenf7222712019-06-13 01:50:21 +030015128static enum sigma_cmd_result cmd_sta_osu(struct sigma_dut *dut,
15129 struct sigma_conn *conn,
15130 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015131{
15132 const char *intf = get_param(cmd, "Interface");
Jouni Malinen4c8681c2018-09-12 23:28:11 +030015133 const char *name, *osu_ssid, *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015134 int prod_ess_assoc = 1;
Jouni Malinen4c8681c2018-09-12 23:28:11 +030015135 char buf[300], bssid[100], ssid[100];
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015136 int res;
15137 struct wpa_ctrl *ctrl;
15138
15139 name = get_param(cmd, "osuFriendlyName");
Jouni Malinen4c8681c2018-09-12 23:28:11 +030015140 osu_ssid = get_param(cmd, "osu_ssid");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015141
15142 val = get_param(cmd, "ProdESSAssoc");
15143 if (val)
15144 prod_ess_assoc = atoi(val);
15145
15146 kill_dhcp_client(dut, intf);
15147 if (start_dhcp_client(dut, intf) < 0)
15148 return -2;
15149
15150 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger OSU");
15151 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
15152 res = snprintf(buf, sizeof(buf),
Jouni Malinen4c8681c2018-09-12 23:28:11 +030015153 "%s %s%s%s %s%s%s signup osu-ca.pem",
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015154 prod_ess_assoc ? "" : "-N",
15155 name ? "-O'" : "", name ? name : "",
Jouni Malinen4c8681c2018-09-12 23:28:11 +030015156 name ? "'" : "",
15157 osu_ssid ? "-o'" : "", osu_ssid ? osu_ssid : "",
15158 osu_ssid ? "'" : "");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015159
Kanchanapally, Vidyullatha12b66762015-12-31 16:46:42 +053015160 hs2_set_policy(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015161 if (run_hs20_osu(dut, buf) < 0) {
15162 FILE *f;
15163
15164 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to complete OSU");
15165
15166 f = fopen("hs20-osu-client.res", "r");
15167 if (f) {
15168 char resp[400], res[300], *pos;
15169 if (!fgets(res, sizeof(res), f))
15170 res[0] = '\0';
15171 pos = strchr(res, '\n');
15172 if (pos)
15173 *pos = '\0';
15174 fclose(f);
15175 sigma_dut_summary(dut, "hs20-osu-client provisioning failed: %s",
15176 res);
15177 snprintf(resp, sizeof(resp), "notify-send '%s'", res);
15178 if (system(resp) != 0) {
15179 }
15180 snprintf(resp, sizeof(resp),
15181 "SSID,,BSSID,,failureReason,%s", res);
15182 send_resp(dut, conn, SIGMA_COMPLETE, resp);
15183 return 0;
15184 }
15185
15186 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
15187 return 0;
15188 }
15189
15190 if (!prod_ess_assoc)
15191 goto report;
15192
15193 ctrl = open_wpa_mon(intf);
15194 if (ctrl == NULL) {
15195 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
15196 "wpa_supplicant monitor connection");
15197 return -1;
15198 }
15199
15200 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
15201 buf, sizeof(buf));
15202
15203 wpa_ctrl_detach(ctrl);
15204 wpa_ctrl_close(ctrl);
15205
15206 if (res < 0) {
15207 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to connect to "
15208 "network after OSU");
15209 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
15210 return 0;
15211 }
15212
15213report:
15214 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
15215 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
15216 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to get BSSID/SSID");
15217 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
15218 return 0;
15219 }
15220
15221 snprintf(buf, sizeof(buf), "SSID,%s,BSSID,%s", ssid, bssid);
15222 send_resp(dut, conn, SIGMA_COMPLETE, buf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015223 return 0;
15224}
15225
15226
Jouni Malinenf7222712019-06-13 01:50:21 +030015227static enum sigma_cmd_result cmd_sta_policy_update(struct sigma_dut *dut,
15228 struct sigma_conn *conn,
15229 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015230{
15231 const char *val;
15232 int timeout = 120;
15233
15234 val = get_param(cmd, "PolicyUpdate");
15235 if (val == NULL || atoi(val) == 0)
15236 return 1; /* No operation requested */
15237
15238 val = get_param(cmd, "Timeout");
15239 if (val)
15240 timeout = atoi(val);
15241
15242 if (timeout) {
15243 /* TODO: time out the command and return
15244 * PolicyUpdateStatus,TIMEOUT if needed. */
15245 }
15246
15247 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger policy update");
15248 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
15249 if (run_hs20_osu(dut, "pol_upd fqdn=wi-fi.org") < 0) {
15250 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,FAIL");
15251 return 0;
15252 }
15253
15254 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,SUCCESS");
15255 return 0;
15256}
15257
15258
Jouni Malinenf7222712019-06-13 01:50:21 +030015259static enum sigma_cmd_result cmd_sta_er_config(struct sigma_dut *dut,
15260 struct sigma_conn *conn,
15261 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015262{
15263 struct wpa_ctrl *ctrl;
15264 const char *intf = get_param(cmd, "Interface");
15265 const char *bssid = get_param(cmd, "Bssid");
15266 const char *ssid = get_param(cmd, "SSID");
15267 const char *security = get_param(cmd, "Security");
15268 const char *passphrase = get_param(cmd, "Passphrase");
15269 const char *pin = get_param(cmd, "PIN");
15270 char buf[1000];
15271 char ssid_hex[200], passphrase_hex[200];
15272 const char *keymgmt, *cipher;
15273
15274 if (intf == NULL)
Jouni Malinen016ae6c2019-11-04 17:00:01 +020015275 intf = get_main_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015276
15277 if (!bssid) {
15278 send_resp(dut, conn, SIGMA_ERROR,
15279 "ErrorCode,Missing Bssid argument");
15280 return 0;
15281 }
15282
15283 if (!ssid) {
15284 send_resp(dut, conn, SIGMA_ERROR,
15285 "ErrorCode,Missing SSID argument");
15286 return 0;
15287 }
15288
15289 if (!security) {
15290 send_resp(dut, conn, SIGMA_ERROR,
15291 "ErrorCode,Missing Security argument");
15292 return 0;
15293 }
15294
15295 if (!passphrase) {
15296 send_resp(dut, conn, SIGMA_ERROR,
15297 "ErrorCode,Missing Passphrase argument");
15298 return 0;
15299 }
15300
15301 if (!pin) {
15302 send_resp(dut, conn, SIGMA_ERROR,
15303 "ErrorCode,Missing PIN argument");
15304 return 0;
15305 }
15306
vamsi krishna8c9c1562017-05-12 15:51:46 +053015307 if (2 * strlen(ssid) >= sizeof(ssid_hex) ||
15308 2 * strlen(passphrase) >= sizeof(passphrase_hex)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015309 send_resp(dut, conn, SIGMA_ERROR,
15310 "ErrorCode,Too long SSID/passphrase");
15311 return 0;
15312 }
15313
15314 ctrl = open_wpa_mon(intf);
15315 if (ctrl == NULL) {
15316 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
15317 "wpa_supplicant monitor connection");
15318 return -2;
15319 }
15320
15321 if (strcasecmp(security, "wpa2-psk") == 0) {
15322 keymgmt = "WPA2PSK";
15323 cipher = "CCMP";
15324 } else {
15325 wpa_ctrl_detach(ctrl);
15326 wpa_ctrl_close(ctrl);
15327 send_resp(dut, conn, SIGMA_ERROR,
15328 "ErrorCode,Unsupported Security value");
15329 return 0;
15330 }
15331
15332 ascii2hexstr(ssid, ssid_hex);
15333 ascii2hexstr(passphrase, passphrase_hex);
15334 snprintf(buf, sizeof(buf), "WPS_REG %s %s %s %s %s %s",
15335 bssid, pin, ssid_hex, keymgmt, cipher, passphrase_hex);
15336
15337 if (wpa_command(intf, buf) < 0) {
15338 wpa_ctrl_detach(ctrl);
15339 wpa_ctrl_close(ctrl);
15340 send_resp(dut, conn, SIGMA_ERROR,
15341 "ErrorCode,Failed to start registrar");
15342 return 0;
15343 }
15344
15345 snprintf(dut->er_oper_bssid, sizeof(dut->er_oper_bssid), "%s", bssid);
15346 dut->er_oper_performed = 1;
15347
15348 return wps_connection_event(dut, conn, ctrl, intf, 0);
15349}
15350
15351
Jouni Malinenf7222712019-06-13 01:50:21 +030015352static enum sigma_cmd_result
15353cmd_sta_wps_connect_pw_token(struct sigma_dut *dut, struct sigma_conn *conn,
15354 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015355{
15356 struct wpa_ctrl *ctrl;
15357 const char *intf = get_param(cmd, "Interface");
15358 const char *bssid = get_param(cmd, "Bssid");
15359 char buf[100];
15360
15361 if (!bssid) {
15362 send_resp(dut, conn, SIGMA_ERROR,
15363 "ErrorCode,Missing Bssid argument");
15364 return 0;
15365 }
15366
15367 ctrl = open_wpa_mon(intf);
15368 if (ctrl == NULL) {
15369 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
15370 "wpa_supplicant monitor connection");
15371 return -2;
15372 }
15373
15374 snprintf(buf, sizeof(buf), "WPS_NFC %s", bssid);
15375
15376 if (wpa_command(intf, buf) < 0) {
15377 wpa_ctrl_detach(ctrl);
15378 wpa_ctrl_close(ctrl);
15379 send_resp(dut, conn, SIGMA_ERROR,
15380 "ErrorCode,Failed to start registrar");
15381 return 0;
15382 }
15383
15384 return wps_connection_event(dut, conn, ctrl, intf, 0);
15385}
15386
15387
Jouni Malinenf7222712019-06-13 01:50:21 +030015388static enum sigma_cmd_result cmd_start_wps_registration(struct sigma_dut *dut,
15389 struct sigma_conn *conn,
15390 struct sigma_cmd *cmd)
vamsi krishna9b144002017-09-20 13:28:13 +053015391{
15392 struct wpa_ctrl *ctrl;
15393 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020015394 const char *network_mode = get_param(cmd, "network_mode");
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020015395 const char *config_method = get_param(cmd, "WPSConfigMethod");
15396 const char *role;
vamsi krishna9b144002017-09-20 13:28:13 +053015397 int res;
15398 char buf[256];
15399 const char *events[] = {
15400 "CTRL-EVENT-CONNECTED",
15401 "WPS-OVERLAP-DETECTED",
15402 "WPS-TIMEOUT",
15403 "WPS-FAIL",
15404 NULL
15405 };
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020015406 int id = 0;
vamsi krishna9b144002017-09-20 13:28:13 +053015407
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020015408 /* 60G WPS tests do not pass Interface parameter */
15409 if (!intf)
Jouni Malinen016ae6c2019-11-04 17:00:01 +020015410 intf = get_main_ifname(dut);
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020015411
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020015412 if (dut->mode == SIGMA_MODE_AP)
15413 return ap_wps_registration(dut, conn, cmd);
15414
15415 if (config_method) {
15416 /* WFA_CS_WPS_PIN_KEYPAD mode is set when using the
15417 * sta_wps_enter_pin before calling start_wps_registration. */
15418 if (strcasecmp(config_method, "PBC") == 0)
15419 dut->wps_method = WFA_CS_WPS_PBC;
15420 }
15421 if (dut->wps_method == WFA_CS_WPS_NOT_READY) {
15422 send_resp(dut, conn, SIGMA_ERROR,
15423 "ErrorCode,WPS parameters not yet set");
15424 return STATUS_SENT;
15425 }
15426
15427 /* Make sure WPS is enabled (also for STA mode) */
15428 dut->wps_disable = 0;
15429
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020015430 if (dut->band == WPS_BAND_60G && network_mode &&
15431 strcasecmp(network_mode, "PBSS") == 0) {
15432 sigma_dut_print(dut, DUT_MSG_DEBUG,
15433 "Set PBSS network mode, network id %d", id);
Jouni Malinen016ae6c2019-11-04 17:00:01 +020015434 if (set_network(get_station_ifname(dut), id, "pbss", "1") < 0)
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020015435 return -2;
15436 }
15437
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020015438 if (dut->force_rsn_ie) {
15439 sigma_dut_print(dut, DUT_MSG_DEBUG, "Force RSN_IE: %d",
15440 dut->force_rsn_ie);
15441 if (sta_60g_force_rsn_ie(dut, dut->force_rsn_ie) < 0) {
15442 sigma_dut_print(dut, DUT_MSG_INFO,
15443 "Failed to force RSN_IE");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020015444 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020015445 }
15446 }
15447
vamsi krishna9b144002017-09-20 13:28:13 +053015448 ctrl = open_wpa_mon(intf);
15449 if (!ctrl) {
15450 sigma_dut_print(dut, DUT_MSG_ERROR,
15451 "Failed to open wpa_supplicant monitor connection");
15452 return -2;
15453 }
15454
15455 role = get_param(cmd, "WpsRole");
15456 if (!role) {
15457 send_resp(dut, conn, SIGMA_INVALID,
15458 "ErrorCode,WpsRole not provided");
15459 goto fail;
15460 }
15461
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020015462 if (strcasecmp(role, "Enrollee") != 0) {
15463 /* Registrar role for STA not supported */
15464 send_resp(dut, conn, SIGMA_ERROR,
15465 "ErrorCode,Unsupported WpsRole value");
15466 goto fail;
15467 }
15468
15469 if (is_60g_sigma_dut(dut)) {
15470 if (dut->wps_method == WFA_CS_WPS_PBC)
15471 snprintf(buf, sizeof(buf), "WPS_PBC");
15472 else /* WFA_CS_WPS_PIN_KEYPAD */
15473 snprintf(buf, sizeof(buf), "WPS_PIN any %s",
15474 dut->wps_pin);
15475 if (wpa_command(intf, buf) < 0) {
15476 send_resp(dut, conn, SIGMA_ERROR,
15477 "ErrorCode,Failed to start WPS");
vamsi krishna9b144002017-09-20 13:28:13 +053015478 goto fail;
15479 }
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020015480 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
15481 if (res < 0) {
15482 send_resp(dut, conn, SIGMA_ERROR,
15483 "ErrorCode,WPS connection did not complete");
15484 goto fail;
15485 }
15486 if (strstr(buf, "WPS-TIMEOUT")) {
15487 send_resp(dut, conn, SIGMA_COMPLETE, "WpsState,NoPeer");
15488 } else if (strstr(buf, "WPS-OVERLAP-DETECTED")) {
15489 send_resp(dut, conn, SIGMA_COMPLETE,
15490 "WpsState,OverlapSession");
15491 } else if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
15492 send_resp(dut, conn, SIGMA_COMPLETE,
15493 "WpsState,Successful");
15494 } else {
15495 send_resp(dut, conn, SIGMA_COMPLETE,
15496 "WpsState,Failure");
15497 }
15498 } else {
15499 if (dut->wps_method == WFA_CS_WPS_PBC) {
vamsi krishna9b144002017-09-20 13:28:13 +053015500 if (wpa_command(intf, "WPS_PBC") < 0) {
15501 send_resp(dut, conn, SIGMA_ERROR,
15502 "ErrorCode,Failed to enable PBC");
15503 goto fail;
15504 }
15505 } else {
15506 /* TODO: PIN method */
15507 send_resp(dut, conn, SIGMA_ERROR,
15508 "ErrorCode,Unsupported WpsConfigMethod value");
15509 goto fail;
15510 }
15511 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
15512 if (res < 0) {
15513 send_resp(dut, conn, SIGMA_ERROR,
15514 "ErrorCode,WPS connection did not complete");
15515 goto fail;
15516 }
15517 if (strstr(buf, "WPS-TIMEOUT")) {
15518 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,NoPeer");
15519 } else if (strstr(buf, "WPS-OVERLAP-DETECTED")) {
15520 send_resp(dut, conn, SIGMA_ERROR,
15521 "ErrorCode,OverlapSession");
15522 } else if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
15523 send_resp(dut, conn, SIGMA_COMPLETE, "Successful");
15524 } else {
15525 send_resp(dut, conn, SIGMA_ERROR,
15526 "ErrorCode,WPS operation failed");
15527 }
vamsi krishna9b144002017-09-20 13:28:13 +053015528 }
15529
15530fail:
15531 wpa_ctrl_detach(ctrl);
15532 wpa_ctrl_close(ctrl);
15533 return 0;
15534}
15535
15536
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015537static int req_intf(struct sigma_cmd *cmd)
15538{
15539 return get_param(cmd, "interface") == NULL ? -1 : 0;
15540}
15541
15542
15543void sta_register_cmds(void)
15544{
15545 sigma_dut_reg_cmd("sta_get_ip_config", req_intf,
15546 cmd_sta_get_ip_config);
15547 sigma_dut_reg_cmd("sta_set_ip_config", req_intf,
15548 cmd_sta_set_ip_config);
15549 sigma_dut_reg_cmd("sta_get_info", req_intf, cmd_sta_get_info);
15550 sigma_dut_reg_cmd("sta_get_mac_address", req_intf,
15551 cmd_sta_get_mac_address);
15552 sigma_dut_reg_cmd("sta_is_connected", req_intf, cmd_sta_is_connected);
15553 sigma_dut_reg_cmd("sta_verify_ip_connection", req_intf,
15554 cmd_sta_verify_ip_connection);
15555 sigma_dut_reg_cmd("sta_get_bssid", req_intf, cmd_sta_get_bssid);
15556 sigma_dut_reg_cmd("sta_set_encryption", req_intf,
15557 cmd_sta_set_encryption);
15558 sigma_dut_reg_cmd("sta_set_psk", req_intf, cmd_sta_set_psk);
15559 sigma_dut_reg_cmd("sta_set_eaptls", req_intf, cmd_sta_set_eaptls);
15560 sigma_dut_reg_cmd("sta_set_eapttls", req_intf, cmd_sta_set_eapttls);
15561 sigma_dut_reg_cmd("sta_set_eapsim", req_intf, cmd_sta_set_eapsim);
15562 sigma_dut_reg_cmd("sta_set_peap", req_intf, cmd_sta_set_peap);
15563 sigma_dut_reg_cmd("sta_set_eapfast", req_intf, cmd_sta_set_eapfast);
15564 sigma_dut_reg_cmd("sta_set_eapaka", req_intf, cmd_sta_set_eapaka);
15565 sigma_dut_reg_cmd("sta_set_eapakaprime", req_intf,
15566 cmd_sta_set_eapakaprime);
15567 sigma_dut_reg_cmd("sta_set_security", req_intf, cmd_sta_set_security);
15568 sigma_dut_reg_cmd("sta_set_uapsd", req_intf, cmd_sta_set_uapsd);
15569 /* TODO: sta_set_ibss */
15570 /* TODO: sta_set_mode */
15571 sigma_dut_reg_cmd("sta_set_wmm", req_intf, cmd_sta_set_wmm);
15572 sigma_dut_reg_cmd("sta_associate", req_intf, cmd_sta_associate);
15573 /* TODO: sta_up_load */
15574 sigma_dut_reg_cmd("sta_preset_testparameters", req_intf,
15575 cmd_sta_preset_testparameters);
15576 /* TODO: sta_set_system */
15577 sigma_dut_reg_cmd("sta_set_11n", req_intf, cmd_sta_set_11n);
15578 /* TODO: sta_set_rifs_test */
15579 sigma_dut_reg_cmd("sta_set_wireless", req_intf, cmd_sta_set_wireless);
15580 sigma_dut_reg_cmd("sta_send_addba", req_intf, cmd_sta_send_addba);
15581 /* TODO: sta_send_coexist_mgmt */
15582 sigma_dut_reg_cmd("sta_disconnect", req_intf, cmd_sta_disconnect);
15583 sigma_dut_reg_cmd("sta_reassoc", req_intf, cmd_sta_reassoc);
15584 sigma_dut_reg_cmd("sta_reassociate", req_intf, cmd_sta_reassoc);
15585 sigma_dut_reg_cmd("sta_reset_default", req_intf,
15586 cmd_sta_reset_default);
15587 sigma_dut_reg_cmd("sta_send_frame", req_intf, cmd_sta_send_frame);
15588 sigma_dut_reg_cmd("sta_set_macaddr", req_intf, cmd_sta_set_macaddr);
15589 sigma_dut_reg_cmd("sta_set_rfeature", req_intf, cmd_sta_set_rfeature);
15590 sigma_dut_reg_cmd("sta_set_radio", req_intf, cmd_sta_set_radio);
15591 sigma_dut_reg_cmd("sta_set_pwrsave", req_intf, cmd_sta_set_pwrsave);
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020015592 sigma_dut_reg_cmd("sta_set_power_save", req_intf, cmd_sta_set_pwrsave);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015593 sigma_dut_reg_cmd("sta_bssid_pool", req_intf, cmd_sta_bssid_pool);
15594 sigma_dut_reg_cmd("sta_reset_parm", req_intf, cmd_sta_reset_parm);
15595 sigma_dut_reg_cmd("sta_get_key", req_intf, cmd_sta_get_key);
15596 sigma_dut_reg_cmd("sta_hs2_associate", req_intf,
15597 cmd_sta_hs2_associate);
Jouni Malinenb639f1c2018-09-13 02:39:46 +030015598 sigma_dut_reg_cmd("sta_hs2_venue_info", req_intf,
15599 cmd_sta_hs2_venue_info);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015600 sigma_dut_reg_cmd("sta_add_credential", req_intf,
15601 cmd_sta_add_credential);
15602 sigma_dut_reg_cmd("sta_scan", req_intf, cmd_sta_scan);
Jouni Malinen5e5d43d2018-01-10 17:29:33 +020015603 sigma_dut_reg_cmd("sta_scan_bss", req_intf, cmd_sta_scan_bss);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015604 sigma_dut_reg_cmd("sta_set_systime", NULL, cmd_sta_set_systime);
15605 sigma_dut_reg_cmd("sta_osu", req_intf, cmd_sta_osu);
15606 sigma_dut_reg_cmd("sta_policy_update", req_intf, cmd_sta_policy_update);
15607 sigma_dut_reg_cmd("sta_er_config", NULL, cmd_sta_er_config);
15608 sigma_dut_reg_cmd("sta_wps_connect_pw_token", req_intf,
15609 cmd_sta_wps_connect_pw_token);
Jouni Malinen82905202018-04-29 17:20:10 +030015610 sigma_dut_reg_cmd("sta_exec_action", NULL, cmd_sta_exec_action);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015611 sigma_dut_reg_cmd("sta_get_events", req_intf, cmd_sta_get_events);
15612 sigma_dut_reg_cmd("sta_get_parameter", req_intf, cmd_sta_get_parameter);
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020015613 sigma_dut_reg_cmd("start_wps_registration", NULL,
vamsi krishna9b144002017-09-20 13:28:13 +053015614 cmd_start_wps_registration);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015615}