blob: f40345e2ebdf157851d9b66348875d4652f2e13c [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
234int set_ps(const char *intf, struct sigma_dut *dut, int enabled)
235{
236#ifdef __linux__
237 char buf[100];
238
239 if (wifi_chip_type == DRIVER_WCN) {
240 if (enabled) {
Purushottam Kushwaha304561d2019-12-23 16:57:18 +0530241 snprintf(buf, sizeof(buf), "iwpriv %s setPower 1",
242 intf);
243 if (system(buf) != 0) {
244 snprintf(buf, sizeof(buf),
245 "iwpriv wlan0 dump 906");
246 if (system(buf) != 0)
247 goto set_power_save;
248 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200249 } else {
Purushottam Kushwaha304561d2019-12-23 16:57:18 +0530250 snprintf(buf, sizeof(buf), "iwpriv %s setPower 2",
251 intf);
252 if (system(buf) != 0) {
253 snprintf(buf, sizeof(buf),
254 "iwpriv wlan0 dump 905");
255 if (system(buf) != 0)
256 goto set_power_save;
257 snprintf(buf, sizeof(buf),
258 "iwpriv wlan0 dump 912");
259 if (system(buf) != 0)
260 goto set_power_save;
261 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200262 }
263
264 return 0;
265 }
266
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530267set_power_save:
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200268 snprintf(buf, sizeof(buf), "./iw dev %s set power_save %s",
269 intf, enabled ? "on" : "off");
270 if (system(buf) != 0) {
271 snprintf(buf, sizeof(buf), "iw dev %s set power_save %s",
272 intf, enabled ? "on" : "off");
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530273 if (system(buf) != 0) {
274 sigma_dut_print(dut, DUT_MSG_ERROR,
275 "Failed to set power save %s",
276 enabled ? "on" : "off");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200277 return -1;
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530278 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200279 }
280
281 return 0;
282#else /* __linux__ */
283 return -1;
284#endif /* __linux__ */
285}
286
287
Lior Davidcc88b562017-01-03 18:52:09 +0200288#ifdef __linux__
Lior David0fe101e2017-03-09 16:09:50 +0200289
Lior Davidcc88b562017-01-03 18:52:09 +0200290static int wil6210_get_debugfs_dir(struct sigma_dut *dut, char *path,
291 size_t len)
292{
293 DIR *dir, *wil_dir;
294 struct dirent *entry;
295 int ret = -1;
296 const char *root_path = "/sys/kernel/debug/ieee80211";
297
298 dir = opendir(root_path);
299 if (!dir)
300 return -2;
301
302 while ((entry = readdir(dir))) {
303 if (strcmp(entry->d_name, ".") == 0 ||
304 strcmp(entry->d_name, "..") == 0)
305 continue;
306
307 if (snprintf(path, len, "%s/%s/wil6210",
308 root_path, entry->d_name) >= (int) len) {
309 ret = -3;
310 break;
311 }
312
313 wil_dir = opendir(path);
314 if (wil_dir) {
315 closedir(wil_dir);
316 ret = 0;
317 break;
318 }
319 }
320
321 closedir(dir);
322 return ret;
323}
Lior David0fe101e2017-03-09 16:09:50 +0200324
325
326static int wil6210_wmi_send(struct sigma_dut *dut, uint16_t command,
327 void *payload, uint16_t length)
328{
329 struct {
330 struct wil_wmi_header hdr;
331 char payload[WIL_WMI_MAX_PAYLOAD];
332 } __attribute__((packed)) cmd;
333 char buf[128], fname[128];
334 size_t towrite, written;
335 FILE *f;
Jouni Malinen3aa72862019-05-29 23:14:51 +0300336 int res;
Lior David0fe101e2017-03-09 16:09:50 +0200337
338 if (length > WIL_WMI_MAX_PAYLOAD) {
339 sigma_dut_print(dut, DUT_MSG_ERROR,
340 "payload too large(%u, max %u)",
341 length, WIL_WMI_MAX_PAYLOAD);
342 return -1;
343 }
344
345 memset(&cmd.hdr, 0, sizeof(cmd.hdr));
346 cmd.hdr.cmd = command;
347 memcpy(cmd.payload, payload, length);
348
349 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
350 sigma_dut_print(dut, DUT_MSG_ERROR,
351 "failed to get wil6210 debugfs dir");
352 return -1;
353 }
354
Jouni Malinen3aa72862019-05-29 23:14:51 +0300355 res = snprintf(fname, sizeof(fname), "%s/wmi_send", buf);
356 if (res < 0 || res >= sizeof(fname))
357 return -1;
Lior David0fe101e2017-03-09 16:09:50 +0200358 f = fopen(fname, "wb");
359 if (!f) {
360 sigma_dut_print(dut, DUT_MSG_ERROR,
361 "failed to open: %s", fname);
362 return -1;
363 }
364
365 towrite = sizeof(cmd.hdr) + length;
366 written = fwrite(&cmd, 1, towrite, f);
367 fclose(f);
368 if (written != towrite) {
369 sigma_dut_print(dut, DUT_MSG_ERROR,
370 "failed to send wmi %u", command);
371 return -1;
372 }
373
374 return 0;
375}
376
377
378static int wil6210_get_sta_info_field(struct sigma_dut *dut, const char *bssid,
379 const char *pattern, unsigned int *field)
380{
381 char buf[128], fname[128];
382 FILE *f;
383 regex_t re;
384 regmatch_t m[2];
Jouni Malinen3aa72862019-05-29 23:14:51 +0300385 int rc, ret = -1, res;
Lior David0fe101e2017-03-09 16:09:50 +0200386
387 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
388 sigma_dut_print(dut, DUT_MSG_ERROR,
389 "failed to get wil6210 debugfs dir");
390 return -1;
391 }
392
Jouni Malinen3aa72862019-05-29 23:14:51 +0300393 res = snprintf(fname, sizeof(fname), "%s/stations", buf);
394 if (res < 0 || res >= sizeof(fname))
395 return -1;
Lior David0fe101e2017-03-09 16:09:50 +0200396 f = fopen(fname, "r");
397 if (!f) {
398 sigma_dut_print(dut, DUT_MSG_ERROR,
399 "failed to open: %s", fname);
400 return -1;
401 }
402
403 if (regcomp(&re, pattern, REG_EXTENDED)) {
404 sigma_dut_print(dut, DUT_MSG_ERROR,
405 "regcomp failed: %s", pattern);
406 goto out;
407 }
408
409 /*
410 * find the entry for the mac address
411 * line is of the form: [n] 11:22:33:44:55:66 state AID aid
412 */
413 while (fgets(buf, sizeof(buf), f)) {
414 if (strcasestr(buf, bssid)) {
415 /* extract the field (CID/AID/state) */
416 rc = regexec(&re, buf, 2, m, 0);
417 if (!rc && (m[1].rm_so >= 0)) {
418 buf[m[1].rm_eo] = 0;
419 *field = atoi(&buf[m[1].rm_so]);
420 ret = 0;
421 break;
422 }
423 }
424 }
425
426 regfree(&re);
427 if (ret)
428 sigma_dut_print(dut, DUT_MSG_ERROR,
429 "could not extract field");
430
431out:
432 fclose(f);
433
434 return ret;
435}
436
437
438static int wil6210_get_cid(struct sigma_dut *dut, const char *bssid,
439 unsigned int *cid)
440{
441 const char *pattern = "\\[([0-9]+)\\]";
442
443 return wil6210_get_sta_info_field(dut, bssid, pattern, cid);
444}
445
446
447static int wil6210_send_brp_rx(struct sigma_dut *dut, const char *mac,
448 int l_rx)
449{
Rakesh Sunki556237d2017-03-30 14:49:31 -0700450 struct wil_wmi_bf_trig_cmd cmd;
Lior David0fe101e2017-03-09 16:09:50 +0200451 unsigned int cid;
452
Rakesh Sunki556237d2017-03-30 14:49:31 -0700453 memset(&cmd, 0, sizeof(cmd));
454
Lior David0fe101e2017-03-09 16:09:50 +0200455 if (wil6210_get_cid(dut, mac, &cid))
456 return -1;
457
458 cmd.bf_type = WIL_WMI_BRP_RX;
459 cmd.sta_id = cid;
460 /* training length (l_rx) is ignored, FW always uses length 16 */
461 return wil6210_wmi_send(dut, WIL_WMI_BF_TRIG_CMDID,
462 &cmd, sizeof(cmd));
463}
464
465
466static int wil6210_send_sls(struct sigma_dut *dut, const char *mac)
467{
Rakesh Sunki556237d2017-03-30 14:49:31 -0700468 struct wil_wmi_bf_trig_cmd cmd;
469
470 memset(&cmd, 0, sizeof(cmd));
Lior David0fe101e2017-03-09 16:09:50 +0200471
472 if (parse_mac_address(dut, mac, (unsigned char *)&cmd.dest_mac))
473 return -1;
474
475 cmd.bf_type = WIL_WMI_SLS;
476 return wil6210_wmi_send(dut, WIL_WMI_BF_TRIG_CMDID,
477 &cmd, sizeof(cmd));
478}
479
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +0200480
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +0200481int wil6210_set_ese(struct sigma_dut *dut, int count,
482 struct sigma_ese_alloc *allocs)
483{
484 struct wil_wmi_ese_cfg cmd = { };
485 int i;
486
487 if (count == 0 || count > WIL_WMI_MAX_ESE_SLOTS)
488 return -1;
489
490 if (dut->ap_bcnint <= 0) {
491 sigma_dut_print(dut, DUT_MSG_ERROR,
492 "invalid beacon interval(%d), check test",
493 dut->ap_bcnint);
494 return -1;
495 }
496
497 cmd.ese_advertisment = WIL_WMI_ADVERTISE_ESE_IN_BEACON;
498 cmd.flags = 0x1d;
499 cmd.num_allocs = count;
500 for (i = 0; i < count; i++) {
501 /*
502 * Convert percent from BI (BI specified in milliseconds)
503 * to absolute duration in microseconds.
504 */
505 cmd.slots[i].duration =
506 (allocs[i].percent_bi * dut->ap_bcnint * 1000) / 100;
507 switch (allocs[i].type) {
508 case ESE_CBAP:
509 cmd.slots[i].slot_type = WIL_WMI_ESE_CBAP;
510 break;
511 case ESE_SP:
512 cmd.slots[i].slot_type = WIL_WMI_ESE_SP;
513 break;
514 default:
515 sigma_dut_print(dut, DUT_MSG_ERROR,
516 "invalid slot type(%d) at index %d",
517 allocs[i].type, i);
518 return -1;
519 }
520 cmd.slots[i].src_aid = allocs[i].src_aid;
521 cmd.slots[i].dst_aid = allocs[i].dst_aid;
522 sigma_dut_print(dut, DUT_MSG_INFO,
523 "slot %d, duration %u, type %d, srcAID %u dstAID %u",
524 i, cmd.slots[i].duration,
525 cmd.slots[i].slot_type, cmd.slots[i].src_aid,
526 cmd.slots[i].dst_aid);
527 }
528
529 return wil6210_wmi_send(dut, WIL_WMI_ESE_CFG_CMDID, &cmd, sizeof(cmd));
530}
531
532
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +0200533int wil6210_set_force_mcs(struct sigma_dut *dut, int force, int mcs)
534{
535 struct wil_wmi_force_mcs cmd = { };
536
537 cmd.module_id = WIL_WMI_UT_HW_SYSAPI;
538 cmd.subtype_id = WIL_WMI_UT_FORCE_MCS;
539 cmd.force_enable = (uint32_t) force;
540 cmd.mcs = (uint32_t) mcs;
541
542 return wil6210_wmi_send(dut, WIL_WMI_UNIT_TEST_CMDID,
543 &cmd, sizeof(cmd));
544}
545
546
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +0200547static int wil6210_force_rsn_ie(struct sigma_dut *dut, int state)
548{
549 struct wil_wmi_force_rsn_ie cmd = { };
550
551 cmd.module_id = WIL_WMI_UT_HW_SYSAPI;
552 cmd.subtype_id = WIL_WMI_UT_FORCE_RSN_IE;
553 cmd.state = (uint32_t) state;
554
555 return wil6210_wmi_send(dut, WIL_WMI_UNIT_TEST_CMDID,
556 &cmd, sizeof(cmd));
557}
558
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +0300559
560/*
561 * this function is also used to configure generic remain-on-channel
562 */
563static int wil6210_p2p_cfg(struct sigma_dut *dut, int freq)
564{
565 struct wil_wmi_p2p_cfg_cmd cmd = { };
566 int channel = freq_to_channel(freq);
567
568 if (channel < 0)
569 return -1;
570 cmd.discovery_mode = WMI_DISCOVERY_MODE_NON_OFFLOAD;
571 cmd.channel = channel - 1;
572 cmd.bcon_interval = WIL_DEFAULT_BI;
573 cmd.discovery_mode = WMI_DISCOVERY_MODE_PEER2PEER;
574
575 return wil6210_wmi_send(dut, WIL_WMI_P2P_CFG_CMDID,
576 &cmd, sizeof(cmd));
577}
578
579
580static int wil6210_remain_on_channel(struct sigma_dut *dut, int freq)
581{
582 int ret = wil6210_p2p_cfg(dut, freq);
583
584 if (ret)
585 return ret;
586
587 ret = wil6210_wmi_send(dut, WIL_WMI_START_LISTEN_CMDID, NULL, 0);
588 if (!ret) {
589 /*
590 * wait a bit to allow FW to setup the radio
591 * especially important if we switch channels
592 */
593 usleep(500000);
594 }
595
596 return ret;
597}
598
599
600static int wil6210_stop_discovery(struct sigma_dut *dut)
601{
602 return wil6210_wmi_send(dut, WIL_WMI_DISCOVERY_STOP_CMDID, NULL, 0);
603}
604
605
606static int wil6210_transmit_frame(struct sigma_dut *dut, int freq,
607 int wait_duration,
608 const char *frame, size_t frame_len)
609{
610 char buf[128], fname[128];
611 FILE *f;
Jouni Malinen3aa72862019-05-29 23:14:51 +0300612 int res = 0, r;
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +0300613 size_t written;
614
615 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
616 sigma_dut_print(dut, DUT_MSG_ERROR,
617 "failed to get wil6210 debugfs dir");
618 return -1;
619 }
Jouni Malinen3aa72862019-05-29 23:14:51 +0300620 r = snprintf(fname, sizeof(fname), "%s/tx_mgmt", buf);
621 if (r < 0 || r >= sizeof(fname))
622 return -1;
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +0300623
624 if (wil6210_remain_on_channel(dut, freq)) {
625 sigma_dut_print(dut, DUT_MSG_ERROR,
626 "failed to listen on channel");
627 return -1;
628 }
629
630 f = fopen(fname, "wb");
631 if (!f) {
632 sigma_dut_print(dut, DUT_MSG_ERROR,
633 "failed to open: %s", fname);
634 res = -1;
635 goto out_stop;
636 }
637 written = fwrite(frame, 1, frame_len, f);
638 fclose(f);
639
640 if (written != frame_len) {
641 sigma_dut_print(dut, DUT_MSG_ERROR,
642 "failed to transmit frame (got %zd, expected %zd)",
643 written, frame_len);
644 res = -1;
645 goto out_stop;
646 }
647
648 usleep(wait_duration * 1000);
649
650out_stop:
651 wil6210_stop_discovery(dut);
652 return res;
653}
654
655
656static int find_template_frame_tag(struct template_frame_tag *tags,
657 int total_tags, int tag_num)
658{
659 int i;
660
661 for (i = 0; i < total_tags; i++) {
662 if (tag_num == tags[i].num)
663 return i;
664 }
665
666 return -1;
667}
668
669
670static int replace_p2p_attribute(struct sigma_dut *dut, char *buf, size_t len,
671 int id, const char *value, size_t val_len)
672{
673 struct wfa_p2p_attribute *attr = (struct wfa_p2p_attribute *) buf;
674
675 if (len < 3 + val_len) {
676 sigma_dut_print(dut, DUT_MSG_ERROR,
677 "not enough space to replace P2P attribute");
678 return -1;
679 }
680
681 if (attr->len != val_len) {
682 sigma_dut_print(dut, DUT_MSG_ERROR,
683 "attribute length mismatch (need %zu have %hu)",
684 val_len, attr->len);
685 return -1;
686 }
687
688 if (attr->id != id) {
689 sigma_dut_print(dut, DUT_MSG_ERROR,
690 "incorrect attribute id (expected %d actual %d)",
691 id, attr->id);
692 return -1;
693 }
694
695 memcpy(attr->variable, value, val_len);
696
697 return 0;
698}
699
700
701static int parse_template_frame_file(struct sigma_dut *dut, const char *fname,
702 char *buf, size_t *length,
703 struct template_frame_tag *tags,
704 size_t *num_tags)
705{
706 char line[512];
707 FILE *f;
708 size_t offset = 0, tag_index = 0;
709 int num, index;
710 int in_tag = 0, tag_num = 0, tag_offset = 0;
711
712 if (*length < sizeof(struct ieee80211_hdr_3addr)) {
713 sigma_dut_print(dut, DUT_MSG_ERROR,
714 "supplied buffer is too small");
715 return -1;
716 }
717
718 f = fopen(fname, "r");
719 if (!f) {
720 sigma_dut_print(dut, DUT_MSG_ERROR,
721 "failed to open template file %s", fname);
722 return -1;
723 }
724
725 /*
726 * template file format: lines beginning with # are comments and
727 * ignored.
728 * It is possible to tag bytes in the frame to make it easy
729 * to replace fields in the template, espcially if they appear
730 * in variable-sized sections (such as IEs)
731 * This is done by a line beginning with $NUM where NUM is an integer
732 * tag number. It can be followed by space(s) and comment.
733 * The next line is considered the tagged bytes. The parser will fill
734 * the tag number, offset and length of the tagged bytes.
735 * rest of the lines contain frame bytes as sequence of hex digits,
736 * 2 digits for each byte. Spaces are allowed between bytes.
737 * On bytes lines only hex digits and spaces are allowed
738 */
739 while (!feof(f)) {
740 if (!fgets(line, sizeof(line), f))
741 break;
742 index = 0;
743 while (isspace((unsigned char) line[index]))
744 index++;
745 if (!line[index] || line[index] == '#')
746 continue;
747 if (line[index] == '$') {
748 if (tags) {
749 index++;
750 tag_num = strtol(&line[index], NULL, 0);
751 tag_offset = offset;
752 in_tag = 1;
753 }
754 continue;
755 }
756 while (line[index]) {
757 if (isspace((unsigned char) line[index])) {
758 index++;
759 continue;
760 }
761 num = hex_byte(&line[index]);
762 if (num < 0)
763 break;
764 buf[offset++] = num;
765 if (offset == *length)
766 goto out;
767 index += 2;
768 }
769
770 if (in_tag) {
771 if (tag_index < *num_tags) {
772 tags[tag_index].num = tag_num;
773 tags[tag_index].offset = tag_offset;
774 tags[tag_index].len = offset - tag_offset;
775 tag_index++;
776 } else {
777 sigma_dut_print(dut, DUT_MSG_INFO,
778 "too many tags, tag ignored");
779 }
780 in_tag = 0;
781 }
782 }
783
784 if (num_tags)
785 *num_tags = tag_index;
786out:
787 fclose(f);
788 if (offset < sizeof(struct ieee80211_hdr_3addr)) {
789 sigma_dut_print(dut, DUT_MSG_ERROR,
790 "template frame is too small");
791 return -1;
792 }
793
794 *length = offset;
795 return 0;
796}
797
Lior Davidcc88b562017-01-03 18:52:09 +0200798#endif /* __linux__ */
799
800
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200801static void static_ip_file(int proto, const char *addr, const char *mask,
802 const char *gw)
803{
804 if (proto) {
805 FILE *f = fopen("static-ip", "w");
806 if (f) {
807 fprintf(f, "%d %s %s %s\n", proto, addr,
808 mask ? mask : "N/A",
809 gw ? gw : "N/A");
810 fclose(f);
811 }
812 } else {
813 unlink("static-ip");
814 }
815}
816
817
818static int send_neighbor_request(struct sigma_dut *dut, const char *intf,
819 const char *ssid)
820{
821#ifdef __linux__
822 char buf[100];
823
824 snprintf(buf, sizeof(buf), "iwpriv %s neighbor %s",
825 intf, ssid);
826 sigma_dut_print(dut, DUT_MSG_INFO, "Request: %s", buf);
827
828 if (system(buf) != 0) {
829 sigma_dut_print(dut, DUT_MSG_ERROR,
830 "iwpriv neighbor request failed");
831 return -1;
832 }
833
834 sigma_dut_print(dut, DUT_MSG_INFO, "iwpriv neighbor request send");
835
836 return 0;
837#else /* __linux__ */
838 return -1;
839#endif /* __linux__ */
840}
841
842
843static int send_trans_mgmt_query(struct sigma_dut *dut, const char *intf,
Ashwini Patil5acd7382017-04-13 15:55:04 +0530844 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200845{
Ashwini Patil5acd7382017-04-13 15:55:04 +0530846 const char *val;
847 int reason_code = 0;
848 char buf[1024];
849
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200850 /*
851 * In the earlier builds we used WNM_QUERY and in later
852 * builds used WNM_BSS_QUERY.
853 */
854
Ashwini Patil5acd7382017-04-13 15:55:04 +0530855 val = get_param(cmd, "BTMQuery_Reason_Code");
856 if (val)
857 reason_code = atoi(val);
858
859 val = get_param(cmd, "Cand_List");
860 if (val && atoi(val) == 1 && dut->btm_query_cand_list) {
861 snprintf(buf, sizeof(buf), "WNM_BSS_QUERY %d%s", reason_code,
862 dut->btm_query_cand_list);
863 free(dut->btm_query_cand_list);
864 dut->btm_query_cand_list = NULL;
865 } else {
866 snprintf(buf, sizeof(buf), "WNM_BSS_QUERY %d", reason_code);
867 }
868
869 if (wpa_command(intf, buf) != 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200870 sigma_dut_print(dut, DUT_MSG_ERROR,
871 "transition management query failed");
872 return -1;
873 }
874
875 sigma_dut_print(dut, DUT_MSG_DEBUG,
876 "transition management query sent");
877
878 return 0;
879}
880
881
882int is_ip_addr(const char *str)
883{
884 const char *pos = str;
885 struct in_addr addr;
886
887 while (*pos) {
888 if (*pos != '.' && (*pos < '0' || *pos > '9'))
889 return 0;
890 pos++;
891 }
892
893 return inet_aton(str, &addr);
894}
895
896
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200897int get_ip_config(struct sigma_dut *dut, const char *ifname, char *buf,
898 size_t buf_len)
899{
vamsi krishnaa11d0732018-05-16 12:19:48 +0530900 char tmp[256];
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200901 char ip[16], mask[15], dns[16], sec_dns[16];
902 int is_dhcp = 0;
903 int s;
904#ifdef ANDROID
905 char prop[PROPERTY_VALUE_MAX];
vamsi krishnaa11d0732018-05-16 12:19:48 +0530906#else /* ANDROID */
907 FILE *f;
908#ifdef __linux__
909 const char *str_ps;
910#endif /* __linux__ */
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200911#endif /* ANDROID */
912
913 ip[0] = '\0';
914 mask[0] = '\0';
915 dns[0] = '\0';
916 sec_dns[0] = '\0';
917
918 s = socket(PF_INET, SOCK_DGRAM, 0);
919 if (s >= 0) {
920 struct ifreq ifr;
921 struct sockaddr_in saddr;
922
923 memset(&ifr, 0, sizeof(ifr));
Peng Xub8fc5cc2017-05-10 17:27:28 -0700924 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200925 if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
926 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to get "
927 "%s IP address: %s",
928 ifname, strerror(errno));
929 } else {
930 memcpy(&saddr, &ifr.ifr_addr,
931 sizeof(struct sockaddr_in));
Peng Xub8fc5cc2017-05-10 17:27:28 -0700932 strlcpy(ip, inet_ntoa(saddr.sin_addr), sizeof(ip));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200933 }
934
935 if (ioctl(s, SIOCGIFNETMASK, &ifr) == 0) {
936 memcpy(&saddr, &ifr.ifr_addr,
937 sizeof(struct sockaddr_in));
Peng Xub8fc5cc2017-05-10 17:27:28 -0700938 strlcpy(mask, inet_ntoa(saddr.sin_addr), sizeof(mask));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200939 }
940 close(s);
941 }
942
943#ifdef ANDROID
944 snprintf(tmp, sizeof(tmp), "dhcp.%s.pid", ifname);
945 if (property_get(tmp, prop, NULL) != 0 && atoi(prop) > 0) {
946 snprintf(tmp, sizeof(tmp), "dhcp.%s.result", ifname);
947 if (property_get(tmp, prop, NULL) != 0 &&
948 strcmp(prop, "ok") == 0) {
949 snprintf(tmp, sizeof(tmp), "dhcp.%s.ipaddress",
950 ifname);
951 if (property_get(tmp, prop, NULL) != 0 &&
952 strcmp(ip, prop) == 0)
953 is_dhcp = 1;
954 }
955 }
956
957 snprintf(tmp, sizeof(tmp), "dhcp.%s.dns1", ifname);
Peng Xub8fc5cc2017-05-10 17:27:28 -0700958 if (property_get(tmp, prop, NULL) != 0)
959 strlcpy(dns, prop, sizeof(dns));
960 else if (property_get("net.dns1", prop, NULL) != 0)
961 strlcpy(dns, prop, sizeof(dns));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200962
963 snprintf(tmp, sizeof(tmp), "dhcp.%s.dns2", ifname);
Peng Xub8fc5cc2017-05-10 17:27:28 -0700964 if (property_get(tmp, prop, NULL) != 0)
965 strlcpy(sec_dns, prop, sizeof(sec_dns));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200966#else /* ANDROID */
967#ifdef __linux__
Jouni Malinen016ae6c2019-11-04 17:00:01 +0200968 if (get_driver_type(dut) == DRIVER_OPENWRT)
Sarvepalli, Rajesh Babua76c6442016-03-18 20:34:26 +0530969 str_ps = "ps -w";
970 else
971 str_ps = "ps ax";
972 snprintf(tmp, sizeof(tmp),
973 "%s | grep dhclient | grep -v grep | grep -q %s",
974 str_ps, ifname);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200975 if (system(tmp) == 0)
976 is_dhcp = 1;
977 else {
Sarvepalli, Rajesh Babua76c6442016-03-18 20:34:26 +0530978 snprintf(tmp, sizeof(tmp),
979 "%s | grep udhcpc | grep -v grep | grep -q %s",
980 str_ps, ifname);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200981 if (system(tmp) == 0)
982 is_dhcp = 1;
983 else {
Sarvepalli, Rajesh Babua76c6442016-03-18 20:34:26 +0530984 snprintf(tmp, sizeof(tmp),
985 "%s | grep dhcpcd | grep -v grep | grep -q %s",
986 str_ps, ifname);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200987 if (system(tmp) == 0)
988 is_dhcp = 1;
989 }
990 }
991#endif /* __linux__ */
992
993 f = fopen("/etc/resolv.conf", "r");
994 if (f) {
vamsi krishnaa11d0732018-05-16 12:19:48 +0530995 char *pos, *pos2;
996
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200997 while (fgets(tmp, sizeof(tmp), f)) {
998 if (strncmp(tmp, "nameserver", 10) != 0)
999 continue;
1000 pos = tmp + 10;
1001 while (*pos == ' ' || *pos == '\t')
1002 pos++;
1003 pos2 = pos;
1004 while (*pos2) {
1005 if (*pos2 == '\n' || *pos2 == '\r') {
1006 *pos2 = '\0';
1007 break;
1008 }
1009 pos2++;
1010 }
Peng Xub8fc5cc2017-05-10 17:27:28 -07001011 if (!dns[0])
1012 strlcpy(dns, pos, sizeof(dns));
1013 else if (!sec_dns[0])
1014 strlcpy(sec_dns, pos, sizeof(sec_dns));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001015 }
1016 fclose(f);
1017 }
1018#endif /* ANDROID */
1019
1020 snprintf(buf, buf_len, "dhcp,%d,ip,%s,mask,%s,primary-dns,%s",
1021 is_dhcp, ip, mask, dns);
1022 buf[buf_len - 1] = '\0';
1023
1024 return 0;
1025}
1026
1027
1028
1029
1030int get_ipv6_config(struct sigma_dut *dut, const char *ifname, char *buf,
1031 size_t buf_len)
1032{
1033#ifdef __linux__
1034#ifdef ANDROID
1035 char cmd[200], result[1000], *pos, *end;
1036 FILE *f;
1037 size_t len;
1038
1039 snprintf(cmd, sizeof(cmd), "ip addr show dev %s scope global", ifname);
1040 f = popen(cmd, "r");
1041 if (f == NULL)
1042 return -1;
1043 len = fread(result, 1, sizeof(result) - 1, f);
1044 pclose(f);
1045 if (len == 0)
1046 return -1;
1047 result[len] = '\0';
1048 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s result: %s\n", cmd, result);
1049
1050 pos = strstr(result, "inet6 ");
1051 if (pos == NULL)
1052 return -1;
1053 pos += 6;
1054 end = strchr(pos, ' ');
1055 if (end)
1056 *end = '\0';
1057 end = strchr(pos, '/');
1058 if (end)
1059 *end = '\0';
1060 snprintf(buf, buf_len, "ip,%s", pos);
1061 buf[buf_len - 1] = '\0';
1062 return 0;
1063#else /* ANDROID */
1064 struct ifaddrs *ifaddr, *ifa;
1065 int res, found = 0;
1066 char host[NI_MAXHOST];
1067
1068 if (getifaddrs(&ifaddr) < 0) {
1069 perror("getifaddrs");
1070 return -1;
1071 }
1072
1073 for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
1074 if (strcasecmp(ifname, ifa->ifa_name) != 0)
1075 continue;
1076 if (ifa->ifa_addr == NULL ||
1077 ifa->ifa_addr->sa_family != AF_INET6)
1078 continue;
1079
1080 res = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in6),
1081 host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
1082 if (res != 0) {
1083 sigma_dut_print(dut, DUT_MSG_DEBUG, "getnameinfo: %s",
1084 gai_strerror(res));
1085 continue;
1086 }
1087 if (strncmp(host, "fe80::", 6) == 0)
1088 continue; /* skip link-local */
1089
1090 sigma_dut_print(dut, DUT_MSG_DEBUG, "ifaddr: %s", host);
1091 found = 1;
1092 break;
1093 }
1094
1095 freeifaddrs(ifaddr);
1096
1097 if (found) {
1098 char *pos;
1099 pos = strchr(host, '%');
1100 if (pos)
1101 *pos = '\0';
1102 snprintf(buf, buf_len, "ip,%s", host);
1103 buf[buf_len - 1] = '\0';
1104 return 0;
1105 }
1106
1107#endif /* ANDROID */
1108#endif /* __linux__ */
1109 return -1;
1110}
1111
1112
Jouni Malinenf7222712019-06-13 01:50:21 +03001113static enum sigma_cmd_result cmd_sta_get_ip_config(struct sigma_dut *dut,
1114 struct sigma_conn *conn,
1115 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001116{
1117 const char *intf = get_param(cmd, "Interface");
1118 const char *ifname;
1119 char buf[200];
1120 const char *val;
1121 int type = 1;
1122
1123 if (intf == NULL)
1124 return -1;
1125
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001126 if (strcmp(intf, get_main_ifname(dut)) == 0)
1127 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001128 else
1129 ifname = intf;
1130
1131 /*
1132 * UCC may assume the IP address to be available immediately after
1133 * association without trying to run sta_get_ip_config multiple times.
1134 * Sigma CAPI does not specify this command as a block command that
1135 * would wait for the address to become available, but to pass tests
1136 * more reliably, it looks like such a wait may be needed here.
1137 */
1138 if (wait_ip_addr(dut, ifname, 15) < 0) {
1139 sigma_dut_print(dut, DUT_MSG_INFO, "Could not get IP address "
1140 "for sta_get_ip_config");
1141 /*
1142 * Try to continue anyway since many UCC tests do not really
1143 * care about the return value from here..
1144 */
1145 }
1146
1147 val = get_param(cmd, "Type");
1148 if (val)
1149 type = atoi(val);
1150 if (type == 2 || dut->last_set_ip_config_ipv6) {
1151 int i;
1152
1153 /*
1154 * Since we do not have proper wait for IPv6 addresses, use a
1155 * fixed two second delay here as a workaround for UCC script
1156 * assuming IPv6 address is available when this command returns.
1157 * Some scripts did not use Type,2 properly for IPv6, so include
1158 * also the cases where the previous sta_set_ip_config indicated
1159 * use of IPv6.
1160 */
1161 sigma_dut_print(dut, DUT_MSG_INFO, "Wait up to extra ten seconds in sta_get_ip_config for IPv6 address");
1162 for (i = 0; i < 10; i++) {
1163 sleep(1);
1164 if (get_ipv6_config(dut, ifname, buf, sizeof(buf)) == 0)
1165 {
1166 sigma_dut_print(dut, DUT_MSG_INFO, "Found IPv6 address");
1167 send_resp(dut, conn, SIGMA_COMPLETE, buf);
1168#ifdef ANDROID
1169 sigma_dut_print(dut, DUT_MSG_INFO,
1170 "Adding IPv6 rule on Android");
1171 add_ipv6_rule(dut, intf);
1172#endif /* ANDROID */
1173
1174 return 0;
1175 }
1176 }
1177 }
1178 if (type == 1) {
1179 if (get_ip_config(dut, ifname, buf, sizeof(buf)) < 0)
1180 return -2;
1181 } else if (type == 2) {
1182 if (get_ipv6_config(dut, ifname, buf, sizeof(buf)) < 0)
1183 return -2;
1184 } else {
1185 send_resp(dut, conn, SIGMA_ERROR,
1186 "errorCode,Unsupported address type");
1187 return 0;
1188 }
1189
1190 send_resp(dut, conn, SIGMA_COMPLETE, buf);
1191 return 0;
1192}
1193
1194
1195static void kill_dhcp_client(struct sigma_dut *dut, const char *ifname)
1196{
1197#ifdef __linux__
1198 char buf[200];
1199 char path[128];
1200 struct stat s;
1201
1202#ifdef ANDROID
1203 snprintf(path, sizeof(path), "/data/misc/dhcp/dhcpcd-%s.pid", ifname);
1204#else /* ANDROID */
1205 snprintf(path, sizeof(path), "/var/run/dhclient-%s.pid", ifname);
1206#endif /* ANDROID */
1207 if (stat(path, &s) == 0) {
1208 snprintf(buf, sizeof(buf), "kill `cat %s`", path);
1209 sigma_dut_print(dut, DUT_MSG_INFO,
1210 "Kill previous DHCP client: %s", buf);
1211 if (system(buf) != 0)
1212 sigma_dut_print(dut, DUT_MSG_INFO,
1213 "Failed to kill DHCP client");
1214 unlink(path);
1215 sleep(1);
1216 } else {
1217 snprintf(path, sizeof(path), "/var/run/dhcpcd-%s.pid", ifname);
1218
1219 if (stat(path, &s) == 0) {
1220 snprintf(buf, sizeof(buf), "kill `cat %s`", path);
1221 sigma_dut_print(dut, DUT_MSG_INFO,
1222 "Kill previous DHCP client: %s", buf);
1223 if (system(buf) != 0)
1224 sigma_dut_print(dut, DUT_MSG_INFO,
1225 "Failed to kill DHCP client");
1226 unlink(path);
1227 sleep(1);
1228 }
1229 }
1230#endif /* __linux__ */
1231}
1232
1233
1234static int start_dhcp_client(struct sigma_dut *dut, const char *ifname)
1235{
1236#ifdef __linux__
1237 char buf[200];
1238
1239#ifdef ANDROID
Purushottam Kushwaha46d64262016-08-23 17:57:53 +05301240 if (access("/system/bin/dhcpcd", F_OK) != -1) {
1241 snprintf(buf, sizeof(buf),
1242 "/system/bin/dhcpcd -b %s", ifname);
1243 } else if (access("/system/bin/dhcptool", F_OK) != -1) {
1244 snprintf(buf, sizeof(buf), "/system/bin/dhcptool %s &", ifname);
Ankita Bajaj8454e5d2019-04-05 16:04:55 +05301245 } else if (access("/vendor/bin/dhcpcd", F_OK) != -1) {
1246 snprintf(buf, sizeof(buf), "/vendor/bin/dhcpcd -b %s", ifname);
1247 } else if (access("/vendor/bin/dhcptool", F_OK) != -1) {
1248 snprintf(buf, sizeof(buf), "/vendor/bin/dhcptool %s", ifname);
Purushottam Kushwaha46d64262016-08-23 17:57:53 +05301249 } else {
1250 sigma_dut_print(dut, DUT_MSG_ERROR,
1251 "DHCP client program missing");
1252 return 0;
1253 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001254#else /* ANDROID */
1255 snprintf(buf, sizeof(buf),
1256 "dhclient -nw -pf /var/run/dhclient-%s.pid %s",
1257 ifname, ifname);
1258#endif /* ANDROID */
1259 sigma_dut_print(dut, DUT_MSG_INFO, "Start DHCP client: %s", buf);
1260 if (system(buf) != 0) {
1261 snprintf(buf, sizeof(buf), "dhcpcd -t 0 %s &", ifname);
1262 if (system(buf) != 0) {
1263 sigma_dut_print(dut, DUT_MSG_INFO,
1264 "Failed to start DHCP client");
1265#ifndef ANDROID
1266 return -1;
1267#endif /* ANDROID */
1268 }
1269 }
1270#endif /* __linux__ */
1271
1272 return 0;
1273}
1274
1275
1276static int clear_ip_addr(struct sigma_dut *dut, const char *ifname)
1277{
1278#ifdef __linux__
1279 char buf[200];
1280
1281 snprintf(buf, sizeof(buf), "ip addr flush dev %s", ifname);
1282 if (system(buf) != 0) {
1283 sigma_dut_print(dut, DUT_MSG_INFO,
1284 "Failed to clear IP addresses");
1285 return -1;
1286 }
1287#endif /* __linux__ */
1288
1289 return 0;
1290}
1291
1292
1293#ifdef ANDROID
1294static int add_ipv6_rule(struct sigma_dut *dut, const char *ifname)
1295{
1296 char cmd[200], *result, *pos;
1297 FILE *fp;
Pradeep Reddy POTTETIf58a1fe2016-10-13 17:22:03 +05301298 int tableid;
1299 size_t len, result_len = 1000;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001300
1301 snprintf(cmd, sizeof(cmd), "ip -6 route list table all | grep %s",
1302 ifname);
1303 fp = popen(cmd, "r");
1304 if (fp == NULL)
1305 return -1;
1306
1307 result = malloc(result_len);
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05301308 if (result == NULL) {
1309 fclose(fp);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001310 return -1;
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05301311 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001312
Pradeep Reddy POTTETIf58a1fe2016-10-13 17:22:03 +05301313 len = fread(result, 1, result_len - 1, fp);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001314 fclose(fp);
1315
1316 if (len == 0) {
1317 free(result);
1318 return -1;
1319 }
Pradeep Reddy POTTETIf58a1fe2016-10-13 17:22:03 +05301320 result[len] = '\0';
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001321
1322 pos = strstr(result, "table ");
1323 if (pos == NULL) {
1324 free(result);
1325 return -1;
1326 }
1327
1328 pos += strlen("table ");
1329 tableid = atoi(pos);
1330 if (tableid != 0) {
1331 if (system("ip -6 rule del prio 22000") != 0) {
1332 /* ignore any error */
1333 }
1334 snprintf(cmd, sizeof(cmd),
1335 "ip -6 rule add from all lookup %d prio 22000",
1336 tableid);
1337 if (system(cmd) != 0) {
1338 sigma_dut_print(dut, DUT_MSG_INFO,
1339 "Failed to run %s", cmd);
1340 free(result);
1341 return -1;
1342 }
1343 } else {
1344 sigma_dut_print(dut, DUT_MSG_INFO,
1345 "No Valid Table Id found %s", pos);
1346 free(result);
1347 return -1;
1348 }
1349 free(result);
1350
1351 return 0;
1352}
1353#endif /* ANDROID */
1354
1355
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301356int set_ipv4_addr(struct sigma_dut *dut, const char *ifname,
1357 const char *ip, const char *mask)
1358{
1359 char buf[200];
1360
1361 snprintf(buf, sizeof(buf), "ifconfig %s %s netmask %s",
1362 ifname, ip, mask);
1363 return system(buf) == 0;
1364}
1365
1366
1367int set_ipv4_gw(struct sigma_dut *dut, const char *gw)
1368{
1369 char buf[200];
1370
1371 if (!is_ip_addr(gw)) {
1372 sigma_dut_print(dut, DUT_MSG_DEBUG, "Invalid gw addr - %s", gw);
1373 return -1;
1374 }
1375
1376 snprintf(buf, sizeof(buf), "route add default gw %s", gw);
1377 if (!dut->no_ip_addr_set && system(buf) != 0) {
1378 snprintf(buf, sizeof(buf), "ip ro re default via %s",
1379 gw);
1380 if (system(buf) != 0)
1381 return 0;
1382 }
1383
1384 return 1;
1385}
1386
1387
Jouni Malinenf7222712019-06-13 01:50:21 +03001388static enum sigma_cmd_result cmd_sta_set_ip_config(struct sigma_dut *dut,
1389 struct sigma_conn *conn,
1390 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001391{
1392 const char *intf = get_param(cmd, "Interface");
1393 const char *ifname;
1394 char buf[200];
1395 const char *val, *ip, *mask, *gw;
1396 int type = 1;
1397
1398 if (intf == NULL)
1399 return -1;
1400
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001401 if (strcmp(intf, get_main_ifname(dut)) == 0)
1402 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001403 else
1404 ifname = intf;
1405
1406 if (if_nametoindex(ifname) == 0) {
1407 send_resp(dut, conn, SIGMA_ERROR,
1408 "ErrorCode,Unknown interface");
1409 return 0;
1410 }
1411
1412 val = get_param(cmd, "Type");
1413 if (val) {
1414 type = atoi(val);
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301415 if (type < 1 || type > 3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001416 send_resp(dut, conn, SIGMA_ERROR,
1417 "ErrorCode,Unsupported address type");
1418 return 0;
1419 }
1420 }
1421
1422 dut->last_set_ip_config_ipv6 = 0;
1423
1424 val = get_param(cmd, "dhcp");
1425 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "true") == 0)) {
1426 static_ip_file(0, NULL, NULL, NULL);
1427#ifdef __linux__
1428 if (type == 2) {
1429 dut->last_set_ip_config_ipv6 = 1;
1430 sigma_dut_print(dut, DUT_MSG_INFO, "Using IPv6 "
1431 "stateless address autoconfiguration");
1432#ifdef ANDROID
1433 /*
1434 * This sleep is required as the assignment in case of
1435 * Android is taking time and is done by the kernel.
1436 * The subsequent ping for IPv6 is impacting HS20 test
1437 * case.
1438 */
1439 sleep(2);
1440 add_ipv6_rule(dut, intf);
1441#endif /* ANDROID */
1442 /* Assume this happens by default */
1443 return 1;
1444 }
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301445 if (type != 3) {
1446 kill_dhcp_client(dut, ifname);
1447 if (start_dhcp_client(dut, ifname) < 0)
1448 return -2;
1449 } else {
1450 sigma_dut_print(dut, DUT_MSG_DEBUG,
1451 "Using FILS HLP DHCPv4 Rapid Commit");
1452 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001453
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001454 return 1;
1455#endif /* __linux__ */
1456 return -2;
1457 }
1458
1459 ip = get_param(cmd, "ip");
Pradeep Reddy POTTETIb18c5652016-01-18 12:45:37 +05301460 if (!ip) {
1461 send_resp(dut, conn, SIGMA_INVALID,
1462 "ErrorCode,Missing IP address");
1463 return 0;
1464 }
1465
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001466 mask = get_param(cmd, "mask");
Pradeep Reddy POTTETIb18c5652016-01-18 12:45:37 +05301467 if (!mask) {
1468 send_resp(dut, conn, SIGMA_INVALID,
1469 "ErrorCode,Missing subnet mask");
1470 return 0;
1471 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001472
1473 if (type == 2) {
1474 int net = atoi(mask);
1475
1476 if ((net < 0 && net > 64) || !is_ipv6_addr(ip))
1477 return -1;
1478
1479 if (dut->no_ip_addr_set) {
1480 snprintf(buf, sizeof(buf),
1481 "sysctl net.ipv6.conf.%s.disable_ipv6=1",
1482 ifname);
1483 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
1484 if (system(buf) != 0) {
1485 sigma_dut_print(dut, DUT_MSG_DEBUG,
1486 "Failed to disable IPv6 address before association");
1487 }
1488 } else {
1489 snprintf(buf, sizeof(buf),
1490 "ip -6 addr del %s/%s dev %s",
1491 ip, mask, ifname);
1492 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
1493 if (system(buf) != 0) {
1494 /*
1495 * This command may fail if the address being
1496 * deleted does not exist. Inaction here is
1497 * intentional.
1498 */
1499 }
1500
1501 snprintf(buf, sizeof(buf),
1502 "ip -6 addr add %s/%s dev %s",
1503 ip, mask, ifname);
1504 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
1505 if (system(buf) != 0) {
1506 send_resp(dut, conn, SIGMA_ERROR,
1507 "ErrorCode,Failed to set IPv6 address");
1508 return 0;
1509 }
1510 }
1511
1512 dut->last_set_ip_config_ipv6 = 1;
1513 static_ip_file(6, ip, mask, NULL);
1514 return 1;
1515 } else if (type == 1) {
Pradeep Reddy POTTETIb18c5652016-01-18 12:45:37 +05301516 if (!is_ip_addr(ip) || !is_ip_addr(mask))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001517 return -1;
1518 }
1519
1520 kill_dhcp_client(dut, ifname);
1521
1522 if (!dut->no_ip_addr_set) {
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301523 if (!set_ipv4_addr(dut, ifname, ip, mask)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001524 send_resp(dut, conn, SIGMA_ERROR,
1525 "ErrorCode,Failed to set IP address");
1526 return 0;
1527 }
1528 }
1529
1530 gw = get_param(cmd, "defaultGateway");
1531 if (gw) {
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301532 if (set_ipv4_gw(dut, gw) < 1) {
1533 send_resp(dut, conn, SIGMA_ERROR,
1534 "ErrorCode,Failed to set default gateway");
1535 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001536 }
1537 }
1538
1539 val = get_param(cmd, "primary-dns");
1540 if (val) {
1541 /* TODO */
1542 sigma_dut_print(dut, DUT_MSG_INFO, "Ignored primary-dns %s "
1543 "setting", val);
1544 }
1545
1546 val = get_param(cmd, "secondary-dns");
1547 if (val) {
1548 /* TODO */
1549 sigma_dut_print(dut, DUT_MSG_INFO, "Ignored secondary-dns %s "
1550 "setting", val);
1551 }
1552
1553 static_ip_file(4, ip, mask, gw);
1554
1555 return 1;
1556}
1557
1558
Jouni Malinenf7222712019-06-13 01:50:21 +03001559static enum sigma_cmd_result cmd_sta_get_info(struct sigma_dut *dut,
1560 struct sigma_conn *conn,
1561 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001562{
1563 /* const char *intf = get_param(cmd, "Interface"); */
1564 /* TODO: could report more details here */
1565 send_resp(dut, conn, SIGMA_COMPLETE, "vendor,Atheros");
1566 return 0;
1567}
1568
1569
Jouni Malinenf7222712019-06-13 01:50:21 +03001570static enum sigma_cmd_result cmd_sta_get_mac_address(struct sigma_dut *dut,
1571 struct sigma_conn *conn,
1572 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001573{
1574 /* const char *intf = get_param(cmd, "Interface"); */
1575 char addr[20], resp[50];
1576
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05301577 if (dut->dev_role == DEVROLE_STA_CFON)
1578 return sta_cfon_get_mac_address(dut, conn, cmd);
1579
Jouni Malinen9540e012019-11-05 17:08:42 +02001580 start_sta_mode(dut);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001581 if (get_wpa_status(get_station_ifname(dut), "address",
1582 addr, sizeof(addr)) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001583 return -2;
1584
1585 snprintf(resp, sizeof(resp), "mac,%s", addr);
1586 send_resp(dut, conn, SIGMA_COMPLETE, resp);
1587 return 0;
1588}
1589
1590
Jouni Malinenf7222712019-06-13 01:50:21 +03001591static enum sigma_cmd_result cmd_sta_is_connected(struct sigma_dut *dut,
1592 struct sigma_conn *conn,
1593 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001594{
1595 /* const char *intf = get_param(cmd, "Interface"); */
1596 int connected = 0;
1597 char result[32];
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001598 if (get_wpa_status(get_station_ifname(dut), "wpa_state", result,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001599 sizeof(result)) < 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001600 sigma_dut_print(dut, DUT_MSG_INFO,
1601 "Could not get interface %s status",
1602 get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001603 return -2;
1604 }
1605
1606 sigma_dut_print(dut, DUT_MSG_DEBUG, "wpa_state=%s", result);
1607 if (strncmp(result, "COMPLETED", 9) == 0)
1608 connected = 1;
1609
1610 if (connected)
1611 send_resp(dut, conn, SIGMA_COMPLETE, "connected,1");
1612 else
1613 send_resp(dut, conn, SIGMA_COMPLETE, "connected,0");
1614
1615 return 0;
1616}
1617
1618
Jouni Malinenf7222712019-06-13 01:50:21 +03001619static enum sigma_cmd_result
1620cmd_sta_verify_ip_connection(struct sigma_dut *dut, struct sigma_conn *conn,
1621 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001622{
1623 /* const char *intf = get_param(cmd, "Interface"); */
1624 const char *dst, *timeout;
1625 int wait_time = 90;
1626 char buf[100];
1627 int res;
1628
1629 dst = get_param(cmd, "destination");
1630 if (dst == NULL || !is_ip_addr(dst))
1631 return -1;
1632
1633 timeout = get_param(cmd, "timeout");
1634 if (timeout) {
1635 wait_time = atoi(timeout);
1636 if (wait_time < 1)
1637 wait_time = 1;
1638 }
1639
1640 /* TODO: force renewal of IP lease if DHCP is enabled */
1641
1642 snprintf(buf, sizeof(buf), "ping %s -c 3 -W %d", dst, wait_time);
1643 res = system(buf);
1644 sigma_dut_print(dut, DUT_MSG_DEBUG, "ping returned: %d", res);
1645 if (res == 0)
1646 send_resp(dut, conn, SIGMA_COMPLETE, "connected,1");
1647 else if (res == 256)
1648 send_resp(dut, conn, SIGMA_COMPLETE, "connected,0");
1649 else
1650 return -2;
1651
1652 return 0;
1653}
1654
1655
Jouni Malinenf7222712019-06-13 01:50:21 +03001656static enum sigma_cmd_result cmd_sta_get_bssid(struct sigma_dut *dut,
1657 struct sigma_conn *conn,
1658 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001659{
1660 /* const char *intf = get_param(cmd, "Interface"); */
1661 char bssid[20], resp[50];
1662
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001663 if (get_wpa_status(get_station_ifname(dut), "bssid",
1664 bssid, sizeof(bssid)) < 0)
Peng Xub8fc5cc2017-05-10 17:27:28 -07001665 strlcpy(bssid, "00:00:00:00:00:00", sizeof(bssid));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001666
1667 snprintf(resp, sizeof(resp), "bssid,%s", bssid);
1668 send_resp(dut, conn, SIGMA_COMPLETE, resp);
1669 return 0;
1670}
1671
1672
1673#ifdef __SAMSUNG__
1674static int add_use_network(const char *ifname)
1675{
1676 char buf[100];
1677
1678 snprintf(buf, sizeof(buf), "USE_NETWORK ON");
1679 wpa_command(ifname, buf);
1680 return 0;
1681}
1682#endif /* __SAMSUNG__ */
1683
1684
1685static int add_network_common(struct sigma_dut *dut, struct sigma_conn *conn,
1686 const char *ifname, struct sigma_cmd *cmd)
1687{
1688 const char *ssid = get_param(cmd, "ssid");
1689 int id;
1690 const char *val;
1691
1692 if (ssid == NULL)
1693 return -1;
1694
1695 start_sta_mode(dut);
1696
1697#ifdef __SAMSUNG__
1698 add_use_network(ifname);
1699#endif /* __SAMSUNG__ */
1700
1701 id = add_network(ifname);
1702 if (id < 0)
1703 return -2;
1704 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding network %d", id);
1705
1706 if (set_network_quoted(ifname, id, "ssid", ssid) < 0)
1707 return -2;
1708
1709 dut->infra_network_id = id;
1710 snprintf(dut->infra_ssid, sizeof(dut->infra_ssid), "%s", ssid);
1711
1712 val = get_param(cmd, "program");
1713 if (!val)
1714 val = get_param(cmd, "prog");
1715 if (val && strcasecmp(val, "hs2") == 0) {
1716 char buf[100];
1717 snprintf(buf, sizeof(buf), "ENABLE_NETWORK %d no-connect", id);
1718 wpa_command(ifname, buf);
1719
1720 val = get_param(cmd, "prefer");
1721 if (val && atoi(val) > 0)
1722 set_network(ifname, id, "priority", "1");
1723 }
1724
1725 return id;
1726}
1727
1728
Jouni Malinenf7222712019-06-13 01:50:21 +03001729static enum sigma_cmd_result cmd_sta_set_encryption(struct sigma_dut *dut,
1730 struct sigma_conn *conn,
1731 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001732{
1733 const char *intf = get_param(cmd, "Interface");
1734 const char *ssid = get_param(cmd, "ssid");
1735 const char *type = get_param(cmd, "encpType");
1736 const char *ifname;
1737 char buf[200];
1738 int id;
1739
1740 if (intf == NULL || ssid == NULL)
1741 return -1;
1742
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001743 if (strcmp(intf, get_main_ifname(dut)) == 0)
1744 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001745 else
1746 ifname = intf;
1747
1748 id = add_network_common(dut, conn, ifname, cmd);
1749 if (id < 0)
1750 return id;
1751
1752 if (set_network(ifname, id, "key_mgmt", "NONE") < 0)
1753 return -2;
1754
1755 if (type && strcasecmp(type, "wep") == 0) {
1756 const char *val;
1757 int i;
1758
1759 val = get_param(cmd, "activeKey");
1760 if (val) {
1761 int keyid;
1762 keyid = atoi(val);
1763 if (keyid < 1 || keyid > 4)
1764 return -1;
1765 snprintf(buf, sizeof(buf), "%d", keyid - 1);
1766 if (set_network(ifname, id, "wep_tx_keyidx", buf) < 0)
1767 return -2;
1768 }
1769
1770 for (i = 0; i < 4; i++) {
1771 snprintf(buf, sizeof(buf), "key%d", i + 1);
1772 val = get_param(cmd, buf);
1773 if (val == NULL)
1774 continue;
1775 snprintf(buf, sizeof(buf), "wep_key%d", i);
1776 if (set_network(ifname, id, buf, val) < 0)
1777 return -2;
1778 }
1779 }
1780
1781 return 1;
1782}
1783
1784
Jouni Malinene4fde732019-03-25 22:29:37 +02001785static int set_akm_suites(struct sigma_dut *dut, const char *ifname,
1786 int id, const char *val)
1787{
1788 char key_mgmt[200], *end, *pos;
1789 const char *in_pos = val;
1790
Jouni Malinen8179fee2019-03-28 03:19:47 +02001791 dut->akm_values = 0;
Jouni Malinene4fde732019-03-25 22:29:37 +02001792 pos = key_mgmt;
1793 end = pos + sizeof(key_mgmt);
1794 while (*in_pos) {
1795 int res, akm = atoi(in_pos);
1796 const char *str;
1797
Jouni Malinen8179fee2019-03-28 03:19:47 +02001798 if (akm >= 0 && akm < 32)
1799 dut->akm_values |= 1 << akm;
1800
Jouni Malinene4fde732019-03-25 22:29:37 +02001801 switch (akm) {
1802 case AKM_WPA_EAP:
1803 str = "WPA-EAP";
1804 break;
1805 case AKM_WPA_PSK:
1806 str = "WPA-PSK";
1807 break;
1808 case AKM_FT_EAP:
1809 str = "FT-EAP";
1810 break;
1811 case AKM_FT_PSK:
1812 str = "FT-PSK";
1813 break;
1814 case AKM_EAP_SHA256:
1815 str = "WPA-EAP-SHA256";
1816 break;
1817 case AKM_PSK_SHA256:
1818 str = "WPA-PSK-SHA256";
1819 break;
1820 case AKM_SAE:
1821 str = "SAE";
1822 break;
1823 case AKM_FT_SAE:
1824 str = "FT-SAE";
1825 break;
1826 case AKM_SUITE_B:
1827 str = "WPA-EAP-SUITE-B-192";
1828 break;
1829 case AKM_FT_SUITE_B:
1830 str = "FT-EAP-SHA384";
1831 break;
1832 case AKM_FILS_SHA256:
1833 str = "FILS-SHA256";
1834 break;
1835 case AKM_FILS_SHA384:
1836 str = "FILS-SHA384";
1837 break;
1838 case AKM_FT_FILS_SHA256:
1839 str = "FT-FILS-SHA256";
1840 break;
1841 case AKM_FT_FILS_SHA384:
1842 str = "FT-FILS-SHA384";
1843 break;
1844 default:
1845 sigma_dut_print(dut, DUT_MSG_ERROR,
1846 "Unsupported AKMSuitetype %d", akm);
1847 return -1;
1848 }
1849
1850 res = snprintf(pos, end - pos, "%s%s",
1851 pos == key_mgmt ? "" : " ", str);
1852 if (res < 0 || res >= end - pos)
1853 return -1;
1854 pos += res;
1855
1856 in_pos = strchr(in_pos, ';');
1857 if (!in_pos)
1858 break;
1859 while (*in_pos == ';')
1860 in_pos++;
1861 }
1862 sigma_dut_print(dut, DUT_MSG_DEBUG, "AKMSuiteType %s --> %s",
1863 val, key_mgmt);
1864 return set_network(ifname, id, "key_mgmt", key_mgmt);
1865}
1866
1867
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001868static int set_wpa_common(struct sigma_dut *dut, struct sigma_conn *conn,
1869 const char *ifname, struct sigma_cmd *cmd)
1870{
1871 const char *val;
1872 int id;
Jouni Malinenad395a22017-09-01 21:13:46 +03001873 int cipher_set = 0;
Jouni Malinen47dcc952017-10-09 16:43:24 +03001874 int owe;
Sunil Duttc75a1e62018-01-11 20:47:50 +05301875 int suite_b = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001876
1877 id = add_network_common(dut, conn, ifname, cmd);
1878 if (id < 0)
1879 return id;
1880
Jouni Malinen47dcc952017-10-09 16:43:24 +03001881 val = get_param(cmd, "Type");
1882 owe = val && strcasecmp(val, "OWE") == 0;
1883
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001884 val = get_param(cmd, "keyMgmtType");
Jouni Malinen47dcc952017-10-09 16:43:24 +03001885 if (!val && owe)
1886 val = "OWE";
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001887 if (val == NULL) {
Jouni Malinene4fde732019-03-25 22:29:37 +02001888 /* keyMgmtType is being replaced with AKMSuiteType, so ignore
1889 * this missing parameter and assume proto=WPA2. */
1890 if (set_network(ifname, id, "proto", "WPA2") < 0)
1891 return ERROR_SEND_STATUS;
1892 } else if (strcasecmp(val, "wpa") == 0 ||
1893 strcasecmp(val, "wpa-psk") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001894 if (set_network(ifname, id, "proto", "WPA") < 0)
1895 return -2;
1896 } else if (strcasecmp(val, "wpa2") == 0 ||
1897 strcasecmp(val, "wpa2-psk") == 0 ||
1898 strcasecmp(val, "wpa2-ft") == 0 ||
1899 strcasecmp(val, "wpa2-sha256") == 0) {
1900 if (set_network(ifname, id, "proto", "WPA2") < 0)
1901 return -2;
Pradeep Reddy POTTETI6d04b3b2016-11-15 14:51:26 +05301902 } else if (strcasecmp(val, "wpa2-wpa-psk") == 0 ||
1903 strcasecmp(val, "wpa2-wpa-ent") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001904 if (set_network(ifname, id, "proto", "WPA WPA2") < 0)
1905 return -2;
Jouni Malinenad395a22017-09-01 21:13:46 +03001906 } else if (strcasecmp(val, "SuiteB") == 0) {
Sunil Duttc75a1e62018-01-11 20:47:50 +05301907 suite_b = 1;
Jouni Malinenad395a22017-09-01 21:13:46 +03001908 if (set_network(ifname, id, "proto", "WPA2") < 0)
1909 return -2;
Jouni Malinen47dcc952017-10-09 16:43:24 +03001910 } else if (strcasecmp(val, "OWE") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001911 } else {
1912 send_resp(dut, conn, SIGMA_INVALID, "errorCode,Unrecognized keyMgmtType value");
1913 return 0;
1914 }
1915
1916 val = get_param(cmd, "encpType");
Jouni Malinenad395a22017-09-01 21:13:46 +03001917 if (val) {
1918 cipher_set = 1;
1919 if (strcasecmp(val, "tkip") == 0) {
1920 if (set_network(ifname, id, "pairwise", "TKIP") < 0)
1921 return -2;
1922 } else if (strcasecmp(val, "aes-ccmp") == 0) {
1923 if (set_network(ifname, id, "pairwise", "CCMP") < 0)
1924 return -2;
1925 } else if (strcasecmp(val, "aes-ccmp-tkip") == 0) {
1926 if (set_network(ifname, id, "pairwise",
1927 "CCMP TKIP") < 0)
1928 return -2;
1929 } else if (strcasecmp(val, "aes-gcmp") == 0) {
1930 if (set_network(ifname, id, "pairwise", "GCMP") < 0)
1931 return -2;
1932 if (set_network(ifname, id, "group", "GCMP") < 0)
1933 return -2;
1934 } else {
1935 send_resp(dut, conn, SIGMA_ERROR,
1936 "errorCode,Unrecognized encpType value");
1937 return 0;
1938 }
1939 }
1940
1941 val = get_param(cmd, "PairwiseCipher");
1942 if (val) {
1943 cipher_set = 1;
1944 /* TODO: Support space separated list */
1945 if (strcasecmp(val, "AES-GCMP-256") == 0) {
1946 if (set_network(ifname, id, "pairwise", "GCMP-256") < 0)
1947 return -2;
1948 } else if (strcasecmp(val, "AES-CCMP-256") == 0) {
1949 if (set_network(ifname, id, "pairwise",
1950 "CCMP-256") < 0)
1951 return -2;
1952 } else if (strcasecmp(val, "AES-GCMP-128") == 0) {
1953 if (set_network(ifname, id, "pairwise", "GCMP") < 0)
1954 return -2;
1955 } else if (strcasecmp(val, "AES-CCMP-128") == 0) {
1956 if (set_network(ifname, id, "pairwise", "CCMP") < 0)
1957 return -2;
1958 } else {
1959 send_resp(dut, conn, SIGMA_ERROR,
1960 "errorCode,Unrecognized PairwiseCipher value");
1961 return 0;
1962 }
1963 }
1964
Jouni Malinen47dcc952017-10-09 16:43:24 +03001965 if (!cipher_set && !owe) {
Jouni Malinenad395a22017-09-01 21:13:46 +03001966 send_resp(dut, conn, SIGMA_ERROR,
1967 "errorCode,Missing encpType and PairwiseCipher");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001968 return 0;
1969 }
Jouni Malinenad395a22017-09-01 21:13:46 +03001970
1971 val = get_param(cmd, "GroupCipher");
1972 if (val) {
1973 if (strcasecmp(val, "AES-GCMP-256") == 0) {
1974 if (set_network(ifname, id, "group", "GCMP-256") < 0)
1975 return -2;
1976 } else if (strcasecmp(val, "AES-CCMP-256") == 0) {
1977 if (set_network(ifname, id, "group", "CCMP-256") < 0)
1978 return -2;
1979 } else if (strcasecmp(val, "AES-GCMP-128") == 0) {
1980 if (set_network(ifname, id, "group", "GCMP") < 0)
1981 return -2;
1982 } else if (strcasecmp(val, "AES-CCMP-128") == 0) {
1983 if (set_network(ifname, id, "group", "CCMP") < 0)
1984 return -2;
1985 } else {
1986 send_resp(dut, conn, SIGMA_ERROR,
1987 "errorCode,Unrecognized GroupCipher value");
1988 return 0;
1989 }
1990 }
1991
Jouni Malinen7b239522017-09-14 21:37:18 +03001992 val = get_param(cmd, "GroupMgntCipher");
Jouni Malinenad395a22017-09-01 21:13:46 +03001993 if (val) {
Jouni Malinene8898cb2017-09-26 17:55:26 +03001994 const char *cipher;
1995
1996 if (strcasecmp(val, "BIP-GMAC-256") == 0) {
1997 cipher = "BIP-GMAC-256";
1998 } else if (strcasecmp(val, "BIP-CMAC-256") == 0) {
1999 cipher = "BIP-CMAC-256";
2000 } else if (strcasecmp(val, "BIP-GMAC-128") == 0) {
2001 cipher = "BIP-GMAC-128";
2002 } else if (strcasecmp(val, "BIP-CMAC-128") == 0) {
2003 cipher = "AES-128-CMAC";
2004 } else {
2005 send_resp(dut, conn, SIGMA_INVALID,
2006 "errorCode,Unsupported GroupMgntCipher");
2007 return 0;
2008 }
2009 if (set_network(ifname, id, "group_mgmt", cipher) < 0) {
2010 send_resp(dut, conn, SIGMA_INVALID,
2011 "errorCode,Failed to set GroupMgntCipher");
2012 return 0;
2013 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002014 }
2015
Jouni Malinene4fde732019-03-25 22:29:37 +02002016 val = get_param(cmd, "AKMSuiteType");
2017 if (val && set_akm_suites(dut, ifname, id, val) < 0)
2018 return ERROR_SEND_STATUS;
2019
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002020 dut->sta_pmf = STA_PMF_DISABLED;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302021
2022 if (dut->program == PROGRAM_OCE) {
2023 dut->sta_pmf = STA_PMF_OPTIONAL;
2024 if (set_network(ifname, id, "ieee80211w", "1") < 0)
2025 return -2;
2026 }
2027
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002028 val = get_param(cmd, "PMF");
2029 if (val) {
2030 if (strcasecmp(val, "Required") == 0 ||
2031 strcasecmp(val, "Forced_Required") == 0) {
2032 dut->sta_pmf = STA_PMF_REQUIRED;
2033 if (set_network(ifname, id, "ieee80211w", "2") < 0)
2034 return -2;
2035 } else if (strcasecmp(val, "Optional") == 0) {
2036 dut->sta_pmf = STA_PMF_OPTIONAL;
2037 if (set_network(ifname, id, "ieee80211w", "1") < 0)
2038 return -2;
2039 } else if (strcasecmp(val, "Disabled") == 0 ||
Kiran Kumar Lokere07da3b22018-12-16 22:42:49 -08002040 strcasecmp(val, "Disable") == 0 ||
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002041 strcasecmp(val, "Forced_Disabled") == 0) {
2042 dut->sta_pmf = STA_PMF_DISABLED;
2043 } else {
2044 send_resp(dut, conn, SIGMA_INVALID, "errorCode,Unrecognized PMF value");
2045 return 0;
2046 }
Sunil Duttc75a1e62018-01-11 20:47:50 +05302047 } else if (owe || suite_b) {
Jouni Malinen1287cd72018-01-04 17:08:01 +02002048 dut->sta_pmf = STA_PMF_REQUIRED;
2049 if (set_network(ifname, id, "ieee80211w", "2") < 0)
2050 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002051 }
2052
Jouni Malinen0165c7f2020-03-26 11:51:58 +02002053 val = get_param(cmd, "BeaconProtection");
2054 if (val && atoi(val) == 1 &&
2055 set_network(ifname, id, "beacon_prot", "1") < 0)
2056 return ERROR_SEND_STATUS;
2057
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002058 return id;
2059}
2060
2061
Jouni Malinenf7222712019-06-13 01:50:21 +03002062static enum sigma_cmd_result cmd_sta_set_psk(struct sigma_dut *dut,
2063 struct sigma_conn *conn,
2064 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002065{
2066 const char *intf = get_param(cmd, "Interface");
Jouni Malinen992a81e2017-08-22 13:57:47 +03002067 const char *type = get_param(cmd, "Type");
Jouni Malinen1287cd72018-01-04 17:08:01 +02002068 const char *pmf = get_param(cmd, "PMF");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002069 const char *network_mode = get_param(cmd, "network_mode");
Jouni Malinene4fde732019-03-25 22:29:37 +02002070 const char *akm = get_param(cmd, "AKMSuiteType");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002071 const char *ifname, *val, *alg;
2072 int id;
Jouni Malinen4b3769d2019-10-10 16:20:29 +03002073 char buf[50];
Jouni Malinen11e55212019-11-22 21:46:59 +02002074 int sae_pwe = -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002075
2076 if (intf == NULL)
2077 return -1;
2078
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002079 if (strcmp(intf, get_main_ifname(dut)) == 0)
2080 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002081 else
2082 ifname = intf;
2083
2084 id = set_wpa_common(dut, conn, ifname, cmd);
2085 if (id < 0)
2086 return id;
2087
2088 val = get_param(cmd, "keyMgmtType");
2089 alg = get_param(cmd, "micAlg");
2090
Jouni Malinen992a81e2017-08-22 13:57:47 +03002091 if (type && strcasecmp(type, "SAE") == 0) {
Jouni Malinene4fde732019-03-25 22:29:37 +02002092 if (!akm && val && strcasecmp(val, "wpa2-ft") == 0) {
Jouni Malinen992a81e2017-08-22 13:57:47 +03002093 if (set_network(ifname, id, "key_mgmt", "FT-SAE") < 0)
2094 return -2;
Jouni Malinene4fde732019-03-25 22:29:37 +02002095 } else if (!akm) {
Jouni Malinen992a81e2017-08-22 13:57:47 +03002096 if (set_network(ifname, id, "key_mgmt", "SAE") < 0)
2097 return -2;
2098 }
2099 if (wpa_command(ifname, "SET sae_groups ") != 0) {
2100 sigma_dut_print(dut, DUT_MSG_ERROR,
2101 "Failed to clear sae_groups to default");
2102 return -2;
2103 }
Jouni Malinen1287cd72018-01-04 17:08:01 +02002104 if (!pmf) {
2105 dut->sta_pmf = STA_PMF_REQUIRED;
2106 if (set_network(ifname, id, "ieee80211w", "2") < 0)
2107 return -2;
2108 }
Jouni Malinen0ab50f42017-08-31 01:34:59 +03002109 } else if (type && strcasecmp(type, "PSK-SAE") == 0) {
2110 if (val && strcasecmp(val, "wpa2-ft") == 0) {
2111 if (set_network(ifname, id, "key_mgmt",
2112 "FT-SAE FT-PSK") < 0)
2113 return -2;
Jouni Malinen3b73d872019-06-12 03:13:25 +03002114 } else if (!akm) {
Jouni Malinen0ab50f42017-08-31 01:34:59 +03002115 if (set_network(ifname, id, "key_mgmt",
2116 "SAE WPA-PSK") < 0)
2117 return -2;
2118 }
2119 if (wpa_command(ifname, "SET sae_groups ") != 0) {
2120 sigma_dut_print(dut, DUT_MSG_ERROR,
2121 "Failed to clear sae_groups to default");
2122 return -2;
2123 }
Jouni Malinen1287cd72018-01-04 17:08:01 +02002124 if (!pmf) {
2125 dut->sta_pmf = STA_PMF_OPTIONAL;
2126 if (set_network(ifname, id, "ieee80211w", "1") < 0)
2127 return -2;
2128 }
Jouni Malinen992a81e2017-08-22 13:57:47 +03002129 } else if (alg && strcasecmp(alg, "SHA-256") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002130 if (set_network(ifname, id, "key_mgmt", "WPA-PSK-SHA256") < 0)
2131 return -2;
2132 } else if (alg && strcasecmp(alg, "SHA-1") == 0) {
2133 if (set_network(ifname, id, "key_mgmt", "WPA-PSK") < 0)
2134 return -2;
Ashwini Patil6dbf7b02017-03-20 13:42:11 +05302135 } else if (val && strcasecmp(val, "wpa2-ft") == 0) {
2136 if (set_network(ifname, id, "key_mgmt", "FT-PSK") < 0)
2137 return -2;
Jouni Malinen3b73d872019-06-12 03:13:25 +03002138 } else if (!akm &&
2139 ((val && strcasecmp(val, "wpa2-sha256") == 0) ||
2140 dut->sta_pmf == STA_PMF_REQUIRED)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002141 if (set_network(ifname, id, "key_mgmt",
2142 "WPA-PSK WPA-PSK-SHA256") < 0)
2143 return -2;
Jouni Malinen77ff3f02019-03-28 03:45:40 +02002144 } else if (!akm && dut->sta_pmf == STA_PMF_OPTIONAL) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002145 if (set_network(ifname, id, "key_mgmt",
2146 "WPA-PSK WPA-PSK-SHA256") < 0)
2147 return -2;
Jouni Malinen77ff3f02019-03-28 03:45:40 +02002148 } else if (!akm) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002149 if (set_network(ifname, id, "key_mgmt", "WPA-PSK") < 0)
2150 return -2;
2151 }
2152
2153 val = get_param(cmd, "passPhrase");
2154 if (val == NULL)
2155 return -1;
Jouni Malinen2126f422017-10-11 23:24:33 +03002156 if (type && strcasecmp(type, "SAE") == 0) {
2157 if (set_network_quoted(ifname, id, "sae_password", val) < 0)
2158 return -2;
2159 } else {
2160 if (set_network_quoted(ifname, id, "psk", val) < 0)
2161 return -2;
2162 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002163
Jouni Malinen78d10c42019-03-25 22:34:32 +02002164 val = get_param(cmd, "PasswordId");
2165 if (val && set_network_quoted(ifname, id, "sae_password_id", val) < 0)
2166 return ERROR_SEND_STATUS;
2167
Jouni Malinen992a81e2017-08-22 13:57:47 +03002168 val = get_param(cmd, "ECGroupID");
2169 if (val) {
Jouni Malinenb54f0df2019-12-12 01:57:29 +02002170 snprintf(buf, sizeof(buf), "SET sae_groups %s", val);
Jouni Malinen992a81e2017-08-22 13:57:47 +03002171 if (wpa_command(ifname, buf) != 0) {
2172 sigma_dut_print(dut, DUT_MSG_ERROR,
2173 "Failed to clear sae_groups");
2174 return -2;
2175 }
2176 }
2177
Jouni Malinen68143132017-09-02 02:34:08 +03002178 val = get_param(cmd, "InvalidSAEElement");
2179 if (val) {
2180 free(dut->sae_commit_override);
2181 dut->sae_commit_override = strdup(val);
2182 }
2183
Jouni Malinen4b3769d2019-10-10 16:20:29 +03002184 val = get_param(cmd, "PMKID_Include");
2185 if (val) {
2186 snprintf(buf, sizeof(buf), "SET sae_pmkid_in_assoc %d",
2187 get_enable_disable(val));
2188 wpa_command(intf, buf);
2189 }
2190
Jouni Malineneeb43d32019-12-06 17:40:07 +02002191 val = get_param(cmd, "IgnoreH2E_RSNXE_BSSMemSel");
2192 if (val) {
2193 snprintf(buf, sizeof(buf), "SET ignore_sae_h2e_only %d",
2194 get_enable_disable(val));
2195 wpa_command(intf, buf);
2196 }
2197
Jouni Malinenf2348d22019-12-07 11:52:55 +02002198 val = get_param(cmd, "ECGroupID_RGE");
2199 if (val) {
2200 snprintf(buf, sizeof(buf), "SET extra_sae_rejected_groups %s",
2201 val);
2202 wpa_command(intf, buf);
2203 }
2204
Jouni Malinen99e55022019-12-07 13:59:41 +02002205 val = get_param(cmd, "RSNXE_Content");
2206 if (val) {
2207 const char *param;
2208
2209 if (strncasecmp(val, "AssocReq:", 9) == 0) {
2210 val += 9;
2211 param = "rsnxe_override_assoc";
2212 } else if (strncasecmp(val, "EapolM2:", 8) == 0) {
2213 val += 8;
2214 param = "rsnxe_override_eapol";
2215 } else {
2216 send_resp(dut, conn, SIGMA_ERROR,
2217 "errorCode,Unsupported RSNXE_Content value");
2218 return STATUS_SENT_ERROR;
2219 }
2220 snprintf(buf, sizeof(buf), "SET %s %s", param, val);
2221 wpa_command(intf, buf);
2222 }
2223
Jouni Malinen11e55212019-11-22 21:46:59 +02002224 val = get_param(cmd, "sae_pwe");
2225 if (val) {
2226 if (strcasecmp(val, "h2e") == 0) {
2227 dut->sae_pwe = SAE_PWE_H2E;
Jouni Malinen7244a412019-12-07 11:54:10 +02002228 } else if (strcasecmp(val, "loop") == 0 ||
2229 strcasecmp(val, "looping") == 0) {
Jouni Malinen11e55212019-11-22 21:46:59 +02002230 dut->sae_pwe = SAE_PWE_LOOP;
2231 } else {
2232 send_resp(dut, conn, SIGMA_ERROR,
2233 "errorCode,Unsupported sae_pwe value");
2234 return STATUS_SENT_ERROR;
2235 }
2236 }
Vinita S. Maloo6d7454f2020-04-02 15:03:26 +05302237
2238 val = get_param(cmd, "Clear_RSNXE");
2239 if (val && strcmp(val, "1") == 0 &&
2240 (wpa_command(intf, "SET rsnxe_override_assoc ") ||
2241 wpa_command(intf, "SET rsnxe_override_eapol "))) {
2242 send_resp(dut, conn, SIGMA_ERROR,
2243 "errorCode,Failed to clear RSNXE");
2244 return ERROR_SEND_STATUS;
2245 }
2246
Jouni Malinenc0078772020-03-04 21:23:16 +02002247 if (dut->sae_pwe == SAE_PWE_LOOP && get_param(cmd, "PasswordId"))
2248 sae_pwe = 3;
2249 else if (dut->sae_pwe == SAE_PWE_LOOP)
Jouni Malinen11e55212019-11-22 21:46:59 +02002250 sae_pwe = 0;
2251 else if (dut->sae_pwe == SAE_PWE_H2E)
2252 sae_pwe = 1;
2253 else if (dut->sae_h2e_default)
2254 sae_pwe = 2;
2255 snprintf(buf, sizeof(buf), "SET sae_pwe %d", sae_pwe);
2256 if (sae_pwe >= 0 && wpa_command(ifname, buf) != 0)
2257 return ERROR_SEND_STATUS;
2258
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002259 if (dut->program == PROGRAM_60GHZ && network_mode &&
2260 strcasecmp(network_mode, "PBSS") == 0 &&
2261 set_network(ifname, id, "pbss", "1") < 0)
2262 return -2;
2263
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002264 return 1;
2265}
2266
2267
Jouni Malinen8ac93452019-08-14 15:19:13 +03002268static enum sigma_cmd_result set_trust_root_system(struct sigma_dut *dut,
2269 struct sigma_conn *conn,
2270 const char *ifname, int id)
2271{
2272 char buf[200];
2273
2274 snprintf(buf, sizeof(buf), "%s/certs", sigma_cert_path);
2275 if (!file_exists(buf))
2276 strlcpy(buf, "/system/etc/security/cacerts", sizeof(buf));
2277 if (!file_exists(buf))
2278 strlcpy(buf, "/etc/ssl/certs", sizeof(buf));
2279 if (!file_exists(buf)) {
2280 char msg[300];
2281
2282 snprintf(msg, sizeof(msg),
2283 "ErrorCode,trustedRootCA system store (%s) not found",
2284 buf);
2285 send_resp(dut, conn, SIGMA_ERROR, msg);
2286 return STATUS_SENT_ERROR;
2287 }
2288
2289 if (set_network_quoted(ifname, id, "ca_path", buf) < 0)
2290 return ERROR_SEND_STATUS;
2291
2292 return SUCCESS_SEND_STATUS;
2293}
2294
2295
2296static enum sigma_cmd_result set_trust_root(struct sigma_dut *dut,
2297 struct sigma_conn *conn,
2298 const char *ifname, int id,
2299 const char *val)
2300{
2301 char buf[200];
2302#ifdef ANDROID
2303 unsigned char kvalue[KEYSTORE_MESSAGE_SIZE];
2304 int length;
2305#endif /* ANDROID */
2306
2307 if (strcmp(val, "DEFAULT") == 0)
2308 return set_trust_root_system(dut, conn, ifname, id);
2309
2310#ifdef ANDROID
2311 snprintf(buf, sizeof(buf), "CACERT_%s", val);
2312 length = android_keystore_get(ANDROID_KEYSTORE_GET, buf, kvalue);
2313 if (length > 0) {
2314 sigma_dut_print(dut, DUT_MSG_INFO, "Use Android keystore [%s]",
2315 buf);
2316 snprintf(buf, sizeof(buf), "keystore://CACERT_%s", val);
2317 goto ca_cert_selected;
2318 }
2319#endif /* ANDROID */
2320
2321 snprintf(buf, sizeof(buf), "%s/%s", sigma_cert_path, val);
2322#ifdef __linux__
2323 if (!file_exists(buf)) {
2324 char msg[300];
2325
2326 snprintf(msg, sizeof(msg),
2327 "ErrorCode,trustedRootCA file (%s) not found", buf);
2328 send_resp(dut, conn, SIGMA_ERROR, msg);
2329 return STATUS_SENT_ERROR;
2330 }
2331#endif /* __linux__ */
2332#ifdef ANDROID
2333ca_cert_selected:
2334#endif /* ANDROID */
2335 if (set_network_quoted(ifname, id, "ca_cert", buf) < 0)
2336 return ERROR_SEND_STATUS;
2337
2338 return SUCCESS_SEND_STATUS;
2339}
2340
2341
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002342static int set_eap_common(struct sigma_dut *dut, struct sigma_conn *conn,
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302343 const char *ifname, int username_identity,
2344 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002345{
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002346 const char *val, *alg, *akm, *trust_root, *domain, *domain_suffix;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002347 int id;
Jouni Malinen53264f62019-05-03 13:04:40 +03002348 char buf[200], buf2[300];
Jouni Malinen8179fee2019-03-28 03:19:47 +02002349 int erp = 0;
Jouni Malinen8ac93452019-08-14 15:19:13 +03002350 enum sigma_cmd_result res;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002351
2352 id = set_wpa_common(dut, conn, ifname, cmd);
2353 if (id < 0)
2354 return id;
2355
2356 val = get_param(cmd, "keyMgmtType");
2357 alg = get_param(cmd, "micAlg");
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302358 akm = get_param(cmd, "AKMSuiteType");
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002359 trust_root = get_param(cmd, "trustedRootCA");
2360 domain = get_param(cmd, "Domain");
2361 domain_suffix = get_param(cmd, "DomainSuffix");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002362
Jouni Malinenad395a22017-09-01 21:13:46 +03002363 if (val && strcasecmp(val, "SuiteB") == 0) {
2364 if (set_network(ifname, id, "key_mgmt", "WPA-EAP-SUITE-B-192") <
2365 0)
2366 return -2;
2367 } else if (alg && strcasecmp(alg, "SHA-256") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002368 if (set_network(ifname, id, "key_mgmt", "WPA-EAP-SHA256") < 0)
2369 return -2;
2370 } else if (alg && strcasecmp(alg, "SHA-1") == 0) {
2371 if (set_network(ifname, id, "key_mgmt", "WPA-EAP") < 0)
2372 return -2;
2373 } else if (val && strcasecmp(val, "wpa2-ft") == 0) {
2374 if (set_network(ifname, id, "key_mgmt", "FT-EAP") < 0)
2375 return -2;
Jouni Malinend6a9d692019-03-28 03:01:24 +02002376 } else if (!akm &&
2377 ((val && strcasecmp(val, "wpa2-sha256") == 0) ||
2378 dut->sta_pmf == STA_PMF_REQUIRED)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002379 if (set_network(ifname, id, "key_mgmt",
2380 "WPA-EAP WPA-EAP-SHA256") < 0)
2381 return -2;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302382 } else if (akm && atoi(akm) == 14) {
2383 if (dut->sta_pmf == STA_PMF_OPTIONAL ||
2384 dut->sta_pmf == STA_PMF_REQUIRED) {
2385 if (set_network(ifname, id, "key_mgmt",
2386 "WPA-EAP-SHA256 FILS-SHA256") < 0)
2387 return -2;
2388 } else {
2389 if (set_network(ifname, id, "key_mgmt",
2390 "WPA-EAP FILS-SHA256") < 0)
2391 return -2;
2392 }
2393
Jouni Malinen8179fee2019-03-28 03:19:47 +02002394 erp = 1;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302395 } else if (akm && atoi(akm) == 15) {
2396 if (dut->sta_pmf == STA_PMF_OPTIONAL ||
2397 dut->sta_pmf == STA_PMF_REQUIRED) {
2398 if (set_network(ifname, id, "key_mgmt",
2399 "WPA-EAP-SHA256 FILS-SHA384") < 0)
2400 return -2;
2401 } else {
2402 if (set_network(ifname, id, "key_mgmt",
2403 "WPA-EAP FILS-SHA384") < 0)
2404 return -2;
2405 }
2406
Jouni Malinen8179fee2019-03-28 03:19:47 +02002407 erp = 1;
Jouni Malinend6a9d692019-03-28 03:01:24 +02002408 } else if (!akm && dut->sta_pmf == STA_PMF_OPTIONAL) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002409 if (set_network(ifname, id, "key_mgmt",
2410 "WPA-EAP WPA-EAP-SHA256") < 0)
2411 return -2;
Jouni Malinend6a9d692019-03-28 03:01:24 +02002412 } else if (!akm) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002413 if (set_network(ifname, id, "key_mgmt", "WPA-EAP") < 0)
2414 return -2;
2415 }
2416
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002417 if (trust_root) {
2418 if (strcmp(trust_root, "DEFAULT") == 0 && !domain &&
2419 !domain_suffix) {
2420 send_resp(dut, conn, SIGMA_ERROR,
2421 "errorCode,trustRootCA DEFAULT used without specifying Domain or DomainSuffix");
2422 return STATUS_SENT_ERROR;
2423 }
2424 res = set_trust_root(dut, conn, ifname, id, trust_root);
Jouni Malinen8ac93452019-08-14 15:19:13 +03002425 if (res != SUCCESS_SEND_STATUS)
2426 return res;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002427 }
2428
Jouni Malinen53264f62019-05-03 13:04:40 +03002429 val = get_param(cmd, "ServerCert");
2430 if (val) {
2431 FILE *f;
2432 char *result = NULL, *pos;
2433
2434 snprintf(buf, sizeof(buf), "%s/%s.sha256", sigma_cert_path,
2435 val);
2436 f = fopen(buf, "r");
2437 if (f) {
2438 result = fgets(buf, sizeof(buf), f);
2439 fclose(f);
2440 }
2441 if (!result) {
2442 snprintf(buf2, sizeof(buf2),
2443 "ErrorCode,ServerCert hash could not be read from %s",
2444 buf);
2445 send_resp(dut, conn, SIGMA_ERROR, buf2);
2446 return STATUS_SENT_ERROR;
2447 }
2448 pos = strchr(buf, '\n');
2449 if (pos)
2450 *pos = '\0';
2451 snprintf(buf2, sizeof(buf2), "hash://server/sha256/%s", buf);
2452 if (set_network_quoted(ifname, id, "ca_cert", buf2) < 0)
2453 return ERROR_SEND_STATUS;
Jouni Malinen29108dc2019-06-13 23:42:11 +03002454
2455 snprintf(buf, sizeof(buf), "%s/%s.tod", sigma_cert_path, val);
2456 if (file_exists(buf)) {
2457 sigma_dut_print(dut, DUT_MSG_DEBUG,
2458 "TOD policy enabled for the configured ServerCert hash");
2459 dut->sta_tod_policy = 1;
2460 }
Jouni Malinen53264f62019-05-03 13:04:40 +03002461 }
2462
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002463 if (domain &&
2464 set_network_quoted(ifname, id, "domain_match", domain) < 0)
Jouni Malinen96f84b02019-05-03 12:32:56 +03002465 return ERROR_SEND_STATUS;
2466
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002467 if (domain_suffix &&
2468 set_network_quoted(ifname, id, "domain_suffix_match",
2469 domain_suffix) < 0)
Jouni Malinen96f84b02019-05-03 12:32:56 +03002470 return ERROR_SEND_STATUS;
2471
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302472 if (username_identity) {
2473 val = get_param(cmd, "username");
2474 if (val) {
2475 if (set_network_quoted(ifname, id, "identity", val) < 0)
2476 return -2;
2477 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002478
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302479 val = get_param(cmd, "password");
2480 if (val) {
2481 if (set_network_quoted(ifname, id, "password", val) < 0)
2482 return -2;
2483 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002484 }
2485
Jouni Malinen8179fee2019-03-28 03:19:47 +02002486 if (dut->akm_values &
2487 ((1 << AKM_FILS_SHA256) |
2488 (1 << AKM_FILS_SHA384) |
2489 (1 << AKM_FT_FILS_SHA256) |
2490 (1 << AKM_FT_FILS_SHA384)))
2491 erp = 1;
2492 if (erp && set_network(ifname, id, "erp", "1") < 0)
2493 return ERROR_SEND_STATUS;
2494
Jouni Malinen134fe3c2019-06-12 04:16:49 +03002495 dut->sta_associate_wait_connect = 1;
2496
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002497 return id;
2498}
2499
2500
Jouni Malinen5eabb2a2017-10-03 18:17:30 +03002501static int set_tls_cipher(const char *ifname, int id, const char *cipher)
2502{
2503 const char *val;
2504
2505 if (!cipher)
2506 return 0;
2507
2508 if (strcasecmp(cipher, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384") == 0)
2509 val = "ECDHE-ECDSA-AES256-GCM-SHA384";
2510 else if (strcasecmp(cipher,
2511 "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384") == 0)
2512 val = "ECDHE-RSA-AES256-GCM-SHA384";
2513 else if (strcasecmp(cipher, "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384") == 0)
2514 val = "DHE-RSA-AES256-GCM-SHA384";
2515 else if (strcasecmp(cipher,
2516 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256") == 0)
2517 val = "ECDHE-ECDSA-AES128-GCM-SHA256";
2518 else
2519 return -1;
2520
2521 /* Need to clear phase1="tls_suiteb=1" to allow cipher enforcement */
2522 set_network_quoted(ifname, id, "phase1", "");
2523
2524 return set_network_quoted(ifname, id, "openssl_ciphers", val);
2525}
2526
2527
Jouni Malinenf7222712019-06-13 01:50:21 +03002528static enum sigma_cmd_result cmd_sta_set_eaptls(struct sigma_dut *dut,
2529 struct sigma_conn *conn,
2530 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002531{
2532 const char *intf = get_param(cmd, "Interface");
2533 const char *ifname, *val;
2534 int id;
2535 char buf[200];
2536#ifdef ANDROID
2537 unsigned char kvalue[KEYSTORE_MESSAGE_SIZE];
2538 int length;
2539 int jb_or_newer = 0;
2540 char prop[PROPERTY_VALUE_MAX];
2541#endif /* ANDROID */
2542
2543 if (intf == NULL)
2544 return -1;
2545
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002546 if (strcmp(intf, get_main_ifname(dut)) == 0)
2547 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002548 else
2549 ifname = intf;
2550
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302551 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002552 if (id < 0)
2553 return id;
2554
2555 if (set_network(ifname, id, "eap", "TLS") < 0)
2556 return -2;
2557
Pradeep Reddy POTTETI9f6c2132016-05-05 16:28:19 +05302558 if (!get_param(cmd, "username") &&
2559 set_network_quoted(ifname, id, "identity",
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002560 "wifi-user@wifilabs.local") < 0)
2561 return -2;
2562
2563 val = get_param(cmd, "clientCertificate");
2564 if (val == NULL)
2565 return -1;
2566#ifdef ANDROID
2567 snprintf(buf, sizeof(buf), "USRPKEY_%s", val);
2568 length = android_keystore_get(ANDROID_KEYSTORE_GET, buf, kvalue);
2569 if (length < 0) {
2570 /*
2571 * JB started reporting keystore type mismatches, so retry with
2572 * the GET_PUBKEY command if the generic GET fails.
2573 */
2574 length = android_keystore_get(ANDROID_KEYSTORE_GET_PUBKEY,
2575 buf, kvalue);
2576 }
2577
2578 if (property_get("ro.build.version.release", prop, NULL) != 0) {
2579 sigma_dut_print(dut, DUT_MSG_DEBUG, "Android release %s", prop);
2580 if (strncmp(prop, "4.0", 3) != 0)
2581 jb_or_newer = 1;
2582 } else
2583 jb_or_newer = 1; /* assume newer */
2584
2585 if (jb_or_newer && length > 0) {
2586 sigma_dut_print(dut, DUT_MSG_INFO,
2587 "Use Android keystore [%s]", buf);
2588 if (set_network(ifname, id, "engine", "1") < 0)
2589 return -2;
2590 if (set_network_quoted(ifname, id, "engine_id", "keystore") < 0)
2591 return -2;
2592 snprintf(buf, sizeof(buf), "USRPKEY_%s", val);
2593 if (set_network_quoted(ifname, id, "key_id", buf) < 0)
2594 return -2;
2595 snprintf(buf, sizeof(buf), "keystore://USRCERT_%s", val);
2596 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
2597 return -2;
2598 return 1;
2599 } else if (length > 0) {
2600 sigma_dut_print(dut, DUT_MSG_INFO,
2601 "Use Android keystore [%s]", buf);
2602 snprintf(buf, sizeof(buf), "keystore://USRPKEY_%s", val);
2603 if (set_network_quoted(ifname, id, "private_key", buf) < 0)
2604 return -2;
2605 snprintf(buf, sizeof(buf), "keystore://USRCERT_%s", val);
2606 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
2607 return -2;
2608 return 1;
2609 }
2610#endif /* ANDROID */
2611
2612 snprintf(buf, sizeof(buf), "%s/%s", sigma_cert_path, val);
2613#ifdef __linux__
2614 if (!file_exists(buf)) {
2615 char msg[300];
2616 snprintf(msg, sizeof(msg), "ErrorCode,clientCertificate file "
2617 "(%s) not found", buf);
2618 send_resp(dut, conn, SIGMA_ERROR, msg);
2619 return -3;
2620 }
2621#endif /* __linux__ */
2622 if (set_network_quoted(ifname, id, "private_key", buf) < 0)
2623 return -2;
2624 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
2625 return -2;
2626
2627 if (set_network_quoted(ifname, id, "private_key_passwd", "wifi") < 0)
2628 return -2;
2629
Jouni Malinen5eabb2a2017-10-03 18:17:30 +03002630 val = get_param(cmd, "keyMgmtType");
2631 if (val && strcasecmp(val, "SuiteB") == 0) {
2632 val = get_param(cmd, "CertType");
2633 if (val && strcasecmp(val, "RSA") == 0) {
2634 if (set_network_quoted(ifname, id, "phase1",
2635 "tls_suiteb=1") < 0)
2636 return -2;
2637 } else {
2638 if (set_network_quoted(ifname, id, "openssl_ciphers",
2639 "SUITEB192") < 0)
2640 return -2;
2641 }
2642
2643 val = get_param(cmd, "TLSCipher");
2644 if (set_tls_cipher(ifname, id, val) < 0) {
2645 send_resp(dut, conn, SIGMA_ERROR,
2646 "ErrorCode,Unsupported TLSCipher value");
2647 return -3;
2648 }
2649 }
2650
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002651 return 1;
2652}
2653
2654
Jouni Malinenf7222712019-06-13 01:50:21 +03002655static enum sigma_cmd_result cmd_sta_set_eapttls(struct sigma_dut *dut,
2656 struct sigma_conn *conn,
2657 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002658{
2659 const char *intf = get_param(cmd, "Interface");
2660 const char *ifname;
2661 int id;
2662
2663 if (intf == NULL)
2664 return -1;
2665
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002666 if (strcmp(intf, get_main_ifname(dut)) == 0)
2667 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002668 else
2669 ifname = intf;
2670
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302671 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002672 if (id < 0)
2673 return id;
2674
2675 if (set_network(ifname, id, "eap", "TTLS") < 0) {
2676 send_resp(dut, conn, SIGMA_ERROR,
2677 "errorCode,Failed to set TTLS method");
2678 return 0;
2679 }
2680
2681 if (set_network_quoted(ifname, id, "phase2", "auth=MSCHAPV2") < 0) {
2682 send_resp(dut, conn, SIGMA_ERROR,
2683 "errorCode,Failed to set MSCHAPv2 for TTLS Phase 2");
2684 return 0;
2685 }
2686
2687 return 1;
2688}
2689
2690
Jouni Malinenf7222712019-06-13 01:50:21 +03002691static enum sigma_cmd_result cmd_sta_set_eapsim(struct sigma_dut *dut,
2692 struct sigma_conn *conn,
2693 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002694{
2695 const char *intf = get_param(cmd, "Interface");
2696 const char *ifname;
2697 int id;
2698
2699 if (intf == NULL)
2700 return -1;
2701
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002702 if (strcmp(intf, get_main_ifname(dut)) == 0)
2703 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002704 else
2705 ifname = intf;
2706
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302707 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002708 if (id < 0)
2709 return id;
2710
2711 if (set_network(ifname, id, "eap", "SIM") < 0)
2712 return -2;
2713
2714 return 1;
2715}
2716
2717
Jouni Malinenf7222712019-06-13 01:50:21 +03002718static enum sigma_cmd_result cmd_sta_set_peap(struct sigma_dut *dut,
2719 struct sigma_conn *conn,
2720 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002721{
2722 const char *intf = get_param(cmd, "Interface");
2723 const char *ifname, *val;
2724 int id;
2725 char buf[100];
2726
2727 if (intf == NULL)
2728 return -1;
2729
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002730 if (strcmp(intf, get_main_ifname(dut)) == 0)
2731 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002732 else
2733 ifname = intf;
2734
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302735 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002736 if (id < 0)
2737 return id;
2738
2739 if (set_network(ifname, id, "eap", "PEAP") < 0)
2740 return -2;
2741
2742 val = get_param(cmd, "innerEAP");
2743 if (val) {
2744 if (strcasecmp(val, "MSCHAPv2") == 0) {
2745 if (set_network_quoted(ifname, id, "phase2",
2746 "auth=MSCHAPV2") < 0)
2747 return -2;
2748 } else if (strcasecmp(val, "GTC") == 0) {
2749 if (set_network_quoted(ifname, id, "phase2",
2750 "auth=GTC") < 0)
2751 return -2;
2752 } else
2753 return -1;
2754 }
2755
2756 val = get_param(cmd, "peapVersion");
2757 if (val) {
2758 int ver = atoi(val);
2759 if (ver < 0 || ver > 1)
2760 return -1;
2761 snprintf(buf, sizeof(buf), "peapver=%d", ver);
2762 if (set_network_quoted(ifname, id, "phase1", buf) < 0)
2763 return -2;
2764 }
2765
2766 return 1;
2767}
2768
2769
Jouni Malinenf7222712019-06-13 01:50:21 +03002770static enum sigma_cmd_result cmd_sta_set_eapfast(struct sigma_dut *dut,
2771 struct sigma_conn *conn,
2772 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002773{
2774 const char *intf = get_param(cmd, "Interface");
2775 const char *ifname, *val;
2776 int id;
2777 char buf[100];
2778
2779 if (intf == NULL)
2780 return -1;
2781
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002782 if (strcmp(intf, get_main_ifname(dut)) == 0)
2783 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002784 else
2785 ifname = intf;
2786
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302787 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002788 if (id < 0)
2789 return id;
2790
2791 if (set_network(ifname, id, "eap", "FAST") < 0)
2792 return -2;
2793
2794 val = get_param(cmd, "innerEAP");
2795 if (val) {
2796 if (strcasecmp(val, "MSCHAPV2") == 0) {
2797 if (set_network_quoted(ifname, id, "phase2",
2798 "auth=MSCHAPV2") < 0)
2799 return -2;
2800 } else if (strcasecmp(val, "GTC") == 0) {
2801 if (set_network_quoted(ifname, id, "phase2",
2802 "auth=GTC") < 0)
2803 return -2;
2804 } else
2805 return -1;
2806 }
2807
2808 val = get_param(cmd, "validateServer");
2809 if (val) {
2810 /* TODO */
2811 sigma_dut_print(dut, DUT_MSG_INFO, "Ignored EAP-FAST "
2812 "validateServer=%s", val);
2813 }
2814
2815 val = get_param(cmd, "pacFile");
2816 if (val) {
2817 snprintf(buf, sizeof(buf), "blob://%s", val);
2818 if (set_network_quoted(ifname, id, "pac_file", buf) < 0)
2819 return -2;
2820 }
2821
2822 if (set_network_quoted(ifname, id, "phase1", "fast_provisioning=2") <
2823 0)
2824 return -2;
2825
2826 return 1;
2827}
2828
2829
Jouni Malinenf7222712019-06-13 01:50:21 +03002830static enum sigma_cmd_result cmd_sta_set_eapaka(struct sigma_dut *dut,
2831 struct sigma_conn *conn,
2832 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002833{
2834 const char *intf = get_param(cmd, "Interface");
Purushottam Kushwahacdd8cb12019-10-04 11:33:59 +05302835 const char *username = get_param(cmd, "Username");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002836 const char *ifname;
2837 int id;
2838
2839 if (intf == NULL)
2840 return -1;
2841
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002842 if (strcmp(intf, get_main_ifname(dut)) == 0)
2843 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002844 else
2845 ifname = intf;
2846
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302847 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002848 if (id < 0)
2849 return id;
2850
Purushottam Kushwahacdd8cb12019-10-04 11:33:59 +05302851 /* RFC 5448: EAP-AKA' MUST use the leading character "6" (ASCII 36
2852 * hexadecimal).
2853 */
2854 if (username && username[0] == '6') {
2855 if (set_network(ifname, id, "eap", "AKA'") < 0)
2856 return -2;
2857 } else if (set_network(ifname, id, "eap", "AKA") < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002858 return -2;
Purushottam Kushwahacdd8cb12019-10-04 11:33:59 +05302859 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002860
2861 return 1;
2862}
2863
2864
Jouni Malinenf7222712019-06-13 01:50:21 +03002865static enum sigma_cmd_result cmd_sta_set_eapakaprime(struct sigma_dut *dut,
2866 struct sigma_conn *conn,
2867 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002868{
2869 const char *intf = get_param(cmd, "Interface");
2870 const char *ifname;
2871 int id;
2872
2873 if (intf == NULL)
2874 return -1;
2875
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002876 if (strcmp(intf, get_main_ifname(dut)) == 0)
2877 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002878 else
2879 ifname = intf;
2880
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302881 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002882 if (id < 0)
2883 return id;
2884
2885 if (set_network(ifname, id, "eap", "AKA'") < 0)
2886 return -2;
2887
2888 return 1;
2889}
2890
2891
2892static int sta_set_open(struct sigma_dut *dut, struct sigma_conn *conn,
2893 struct sigma_cmd *cmd)
2894{
2895 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002896 const char *network_mode = get_param(cmd, "network_mode");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002897 const char *ifname;
2898 int id;
2899
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002900 if (strcmp(intf, get_main_ifname(dut)) == 0)
2901 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002902 else
2903 ifname = intf;
2904
2905 id = add_network_common(dut, conn, ifname, cmd);
2906 if (id < 0)
2907 return id;
2908
2909 if (set_network(ifname, id, "key_mgmt", "NONE") < 0)
2910 return -2;
2911
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002912 if (dut->program == PROGRAM_60GHZ && network_mode &&
2913 strcasecmp(network_mode, "PBSS") == 0 &&
2914 set_network(ifname, id, "pbss", "1") < 0)
2915 return -2;
2916
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002917 return 1;
2918}
2919
2920
Jouni Malinen47dcc952017-10-09 16:43:24 +03002921static int sta_set_owe(struct sigma_dut *dut, struct sigma_conn *conn,
2922 struct sigma_cmd *cmd)
2923{
2924 const char *intf = get_param(cmd, "Interface");
2925 const char *ifname, *val;
2926 int id;
2927
2928 if (intf == NULL)
2929 return -1;
2930
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002931 if (strcmp(intf, get_main_ifname(dut)) == 0)
2932 ifname = get_station_ifname(dut);
Jouni Malinen47dcc952017-10-09 16:43:24 +03002933 else
2934 ifname = intf;
2935
2936 id = set_wpa_common(dut, conn, ifname, cmd);
2937 if (id < 0)
2938 return id;
2939
2940 if (set_network(ifname, id, "key_mgmt", "OWE") < 0)
2941 return -2;
2942
2943 val = get_param(cmd, "ECGroupID");
Jouni Malinenfac9cad2017-10-10 18:35:55 +03002944 if (val && strcmp(val, "0") == 0) {
2945 if (wpa_command(ifname,
2946 "VENDOR_ELEM_ADD 13 ff23200000783590fb7440e03d5b3b33911f86affdcc6b4411b707846ac4ff08ddc8831ccd") != 0) {
2947 sigma_dut_print(dut, DUT_MSG_ERROR,
2948 "Failed to set OWE DH Param element override");
2949 return -2;
2950 }
Hu Wang6010ce72020-03-05 19:33:53 +08002951 } else if (val &&
2952 (set_network(ifname, id, "owe_group", val) < 0 ||
2953 (dut->owe_ptk_workaround &&
2954 set_network(ifname, id, "owe_ptk_workaround", "1") < 0))) {
Jouni Malinen47dcc952017-10-09 16:43:24 +03002955 sigma_dut_print(dut, DUT_MSG_ERROR,
Hu Wang6010ce72020-03-05 19:33:53 +08002956 "Failed to set owe_group");
Jouni Malinen47dcc952017-10-09 16:43:24 +03002957 return -2;
2958 }
2959
2960 return 1;
2961}
2962
2963
Jouni Malinenf7222712019-06-13 01:50:21 +03002964static enum sigma_cmd_result cmd_sta_set_security(struct sigma_dut *dut,
2965 struct sigma_conn *conn,
2966 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002967{
2968 const char *type = get_param(cmd, "Type");
2969
2970 if (type == NULL) {
2971 send_resp(dut, conn, SIGMA_ERROR,
2972 "ErrorCode,Missing Type argument");
2973 return 0;
2974 }
2975
2976 if (strcasecmp(type, "OPEN") == 0)
2977 return sta_set_open(dut, conn, cmd);
Jouni Malinen47dcc952017-10-09 16:43:24 +03002978 if (strcasecmp(type, "OWE") == 0)
2979 return sta_set_owe(dut, conn, cmd);
Jouni Malinen992a81e2017-08-22 13:57:47 +03002980 if (strcasecmp(type, "PSK") == 0 ||
Jouni Malinen0ab50f42017-08-31 01:34:59 +03002981 strcasecmp(type, "PSK-SAE") == 0 ||
Jouni Malinen992a81e2017-08-22 13:57:47 +03002982 strcasecmp(type, "SAE") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002983 return cmd_sta_set_psk(dut, conn, cmd);
2984 if (strcasecmp(type, "EAPTLS") == 0)
2985 return cmd_sta_set_eaptls(dut, conn, cmd);
2986 if (strcasecmp(type, "EAPTTLS") == 0)
2987 return cmd_sta_set_eapttls(dut, conn, cmd);
2988 if (strcasecmp(type, "EAPPEAP") == 0)
2989 return cmd_sta_set_peap(dut, conn, cmd);
2990 if (strcasecmp(type, "EAPSIM") == 0)
2991 return cmd_sta_set_eapsim(dut, conn, cmd);
2992 if (strcasecmp(type, "EAPFAST") == 0)
2993 return cmd_sta_set_eapfast(dut, conn, cmd);
2994 if (strcasecmp(type, "EAPAKA") == 0)
2995 return cmd_sta_set_eapaka(dut, conn, cmd);
2996 if (strcasecmp(type, "EAPAKAPRIME") == 0)
2997 return cmd_sta_set_eapakaprime(dut, conn, cmd);
Amarnath Hullur Subramanyam81b11cd2018-01-30 19:07:17 -08002998 if (strcasecmp(type, "wep") == 0)
2999 return cmd_sta_set_encryption(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003000
3001 send_resp(dut, conn, SIGMA_ERROR,
3002 "ErrorCode,Unsupported Type value");
3003 return 0;
3004}
3005
3006
3007int ath6kl_client_uapsd(struct sigma_dut *dut, const char *intf, int uapsd)
3008{
3009#ifdef __linux__
3010 /* special handling for ath6kl */
3011 char path[128], fname[128], *pos;
3012 ssize_t res;
3013 FILE *f;
3014
Jouni Malinene39cd562019-05-29 23:39:56 +03003015 res = snprintf(fname, sizeof(fname), "/sys/class/net/%s/phy80211",
3016 intf);
3017 if (res < 0 || res >= sizeof(fname))
3018 return 0;
3019 res = readlink(fname, path, sizeof(path));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003020 if (res < 0)
3021 return 0; /* not ath6kl */
3022
3023 if (res >= (int) sizeof(path))
3024 res = sizeof(path) - 1;
3025 path[res] = '\0';
3026 pos = strrchr(path, '/');
3027 if (pos == NULL)
3028 pos = path;
3029 else
3030 pos++;
Jouni Malinen77dda642020-01-07 11:21:55 +02003031 res = snprintf(fname, sizeof(fname),
3032 "/sys/kernel/debug/ieee80211/%s/ath6kl/"
3033 "create_qos", pos);
3034 if (res < 0 || res >= sizeof(fname) || !file_exists(fname))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003035 return 0; /* not ath6kl */
3036
3037 if (uapsd) {
3038 f = fopen(fname, "w");
3039 if (f == NULL)
3040 return -1;
3041
3042 sigma_dut_print(dut, DUT_MSG_DEBUG, "Use ath6kl create_qos");
3043 fprintf(f, "4 2 2 1 2 9999999 9999999 9999999 7777777 0 4 "
3044 "45000 200 56789000 56789000 5678900 0 0 9999999 "
3045 "20000 0\n");
3046 fclose(f);
3047 } else {
Jouni Malinen77dda642020-01-07 11:21:55 +02003048 res = snprintf(fname, sizeof(fname),
3049 "/sys/kernel/debug/ieee80211/%s/ath6kl/"
3050 "delete_qos", pos);
3051 if (res < 0 || res >= sizeof(fname))
3052 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003053
3054 f = fopen(fname, "w");
3055 if (f == NULL)
3056 return -1;
3057
3058 sigma_dut_print(dut, DUT_MSG_DEBUG, "Use ath6kl delete_qos");
3059 fprintf(f, "2 4\n");
3060 fclose(f);
3061 }
3062#endif /* __linux__ */
3063
3064 return 0;
3065}
3066
3067
Jouni Malinenf7222712019-06-13 01:50:21 +03003068static enum sigma_cmd_result cmd_sta_set_uapsd(struct sigma_dut *dut,
3069 struct sigma_conn *conn,
3070 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003071{
3072 const char *intf = get_param(cmd, "Interface");
3073 /* const char *ssid = get_param(cmd, "ssid"); */
3074 const char *val;
3075 int max_sp_len = 4;
3076 int ac_be = 1, ac_bk = 1, ac_vi = 1, ac_vo = 1;
3077 char buf[100];
3078 int ret1, ret2;
3079
3080 val = get_param(cmd, "maxSPLength");
3081 if (val) {
3082 max_sp_len = atoi(val);
3083 if (max_sp_len != 0 && max_sp_len != 1 && max_sp_len != 2 &&
3084 max_sp_len != 4)
3085 return -1;
3086 }
3087
3088 val = get_param(cmd, "acBE");
3089 if (val)
3090 ac_be = atoi(val);
3091
3092 val = get_param(cmd, "acBK");
3093 if (val)
3094 ac_bk = atoi(val);
3095
3096 val = get_param(cmd, "acVI");
3097 if (val)
3098 ac_vi = atoi(val);
3099
3100 val = get_param(cmd, "acVO");
3101 if (val)
3102 ac_vo = atoi(val);
3103
3104 dut->client_uapsd = ac_be || ac_bk || ac_vi || ac_vo;
3105
3106 snprintf(buf, sizeof(buf), "P2P_SET client_apsd %d,%d,%d,%d;%d",
3107 ac_be, ac_bk, ac_vi, ac_vo, max_sp_len);
3108 ret1 = wpa_command(intf, buf);
3109
3110 snprintf(buf, sizeof(buf), "SET uapsd %d,%d,%d,%d;%d",
3111 ac_be, ac_bk, ac_vi, ac_vo, max_sp_len);
3112 ret2 = wpa_command(intf, buf);
3113
3114 if (ret1 && ret2) {
3115 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to set client mode "
3116 "UAPSD parameters.");
3117 return -2;
3118 }
3119
3120 if (ath6kl_client_uapsd(dut, intf, dut->client_uapsd) < 0) {
3121 send_resp(dut, conn, SIGMA_ERROR,
3122 "ErrorCode,Failed to set ath6kl QoS parameters");
3123 return 0;
3124 }
3125
3126 return 1;
3127}
3128
3129
Jouni Malinenf7222712019-06-13 01:50:21 +03003130static enum sigma_cmd_result cmd_sta_set_wmm(struct sigma_dut *dut,
3131 struct sigma_conn *conn,
3132 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003133{
3134 char buf[1000];
3135 const char *intf = get_param(cmd, "Interface");
3136 const char *grp = get_param(cmd, "Group");
3137 const char *act = get_param(cmd, "Action");
3138 const char *tid = get_param(cmd, "Tid");
3139 const char *dir = get_param(cmd, "Direction");
3140 const char *psb = get_param(cmd, "Psb");
3141 const char *up = get_param(cmd, "Up");
3142 const char *fixed = get_param(cmd, "Fixed");
3143 const char *size = get_param(cmd, "Size");
3144 const char *msize = get_param(cmd, "Maxsize");
3145 const char *minsi = get_param(cmd, "Min_srvc_intrvl");
3146 const char *maxsi = get_param(cmd, "Max_srvc_intrvl");
3147 const char *inact = get_param(cmd, "Inactivity");
3148 const char *sus = get_param(cmd, "Suspension");
3149 const char *mindr = get_param(cmd, "Mindatarate");
3150 const char *meandr = get_param(cmd, "Meandatarate");
3151 const char *peakdr = get_param(cmd, "Peakdatarate");
3152 const char *phyrate = get_param(cmd, "Phyrate");
3153 const char *burstsize = get_param(cmd, "Burstsize");
3154 const char *sba = get_param(cmd, "Sba");
3155 int direction;
3156 int handle;
Peng Xu93319622017-10-04 17:58:16 -07003157 float sba_fv = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003158 int fixed_int;
3159 int psb_ts;
3160
3161 if (intf == NULL || grp == NULL || act == NULL )
3162 return -1;
3163
3164 if (strcasecmp(act, "addts") == 0) {
3165 if (tid == NULL || dir == NULL || psb == NULL ||
3166 up == NULL || fixed == NULL || size == NULL)
3167 return -1;
3168
3169 /*
3170 * Note: Sigma CAPI spec lists uplink, downlink, and bidi as the
3171 * possible values, but WMM-AC and V-E test scripts use "UP,
3172 * "DOWN", and "BIDI".
3173 */
3174 if (strcasecmp(dir, "uplink") == 0 ||
3175 strcasecmp(dir, "up") == 0) {
3176 direction = 0;
3177 } else if (strcasecmp(dir, "downlink") == 0 ||
3178 strcasecmp(dir, "down") == 0) {
3179 direction = 1;
3180 } else if (strcasecmp(dir, "bidi") == 0) {
3181 direction = 2;
3182 } else {
3183 sigma_dut_print(dut, DUT_MSG_ERROR,
3184 "Direction %s not supported", dir);
3185 return -1;
3186 }
3187
3188 if (strcasecmp(psb, "legacy") == 0) {
3189 psb_ts = 0;
3190 } else if (strcasecmp(psb, "uapsd") == 0) {
3191 psb_ts = 1;
3192 } else {
3193 sigma_dut_print(dut, DUT_MSG_ERROR,
3194 "PSB %s not supported", psb);
3195 return -1;
3196 }
3197
3198 if (atoi(tid) < 0 || atoi(tid) > 7) {
3199 sigma_dut_print(dut, DUT_MSG_ERROR,
3200 "TID %s not supported", tid);
3201 return -1;
3202 }
3203
3204 if (strcasecmp(fixed, "true") == 0) {
3205 fixed_int = 1;
3206 } else {
3207 fixed_int = 0;
3208 }
3209
Peng Xu93319622017-10-04 17:58:16 -07003210 if (sba)
3211 sba_fv = atof(sba);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003212
3213 dut->dialog_token++;
3214 handle = 7000 + dut->dialog_token;
3215
3216 /*
3217 * size: convert to hex
3218 * maxsi: convert to hex
3219 * mindr: convert to hex
3220 * meandr: convert to hex
3221 * peakdr: convert to hex
3222 * burstsize: convert to hex
3223 * phyrate: convert to hex
3224 * sba: convert to hex with modification
3225 * minsi: convert to integer
3226 * sus: convert to integer
3227 * inact: convert to integer
3228 * maxsi: convert to integer
3229 */
3230
3231 /*
3232 * The Nominal MSDU Size field is 2 octets long and contains an
3233 * unsigned integer that specifies the nominal size, in octets,
3234 * of MSDUs belonging to the traffic under this traffic
3235 * specification and is defined in Figure 16. If the Fixed
3236 * subfield is set to 1, then the size of the MSDU is fixed and
3237 * is indicated by the Size Subfield. If the Fixed subfield is
3238 * set to 0, then the size of the MSDU might not be fixed and
3239 * the Size indicates the nominal MSDU size.
3240 *
3241 * The Surplus Bandwidth Allowance Factor field is 2 octets long
3242 * and specifies the excess allocation of time (and bandwidth)
3243 * over and above the stated rates required to transport an MSDU
3244 * belonging to the traffic in this TSPEC. This field is
3245 * represented as an unsigned binary number with an implicit
3246 * binary point after the leftmost 3 bits. For example, an SBA
3247 * of 1.75 is represented as 0x3800. This field is included to
3248 * account for retransmissions. As such, the value of this field
3249 * must be greater than unity.
3250 */
3251
3252 snprintf(buf, sizeof(buf),
3253 "iwpriv %s addTspec %d %s %d %d %s 0x%X"
3254 " 0x%X 0x%X 0x%X"
3255 " 0x%X 0x%X 0x%X"
3256 " 0x%X %d %d %d %d"
3257 " %d %d",
3258 intf, handle, tid, direction, psb_ts, up,
3259 (unsigned int) ((fixed_int << 15) | atoi(size)),
3260 msize ? atoi(msize) : 0,
3261 mindr ? atoi(mindr) : 0,
3262 meandr ? atoi(meandr) : 0,
3263 peakdr ? atoi(peakdr) : 0,
3264 burstsize ? atoi(burstsize) : 0,
3265 phyrate ? atoi(phyrate) : 0,
3266 sba ? ((unsigned int) (((int) sba_fv << 13) |
3267 (int)((sba_fv - (int) sba_fv) *
3268 8192))) : 0,
3269 minsi ? atoi(minsi) : 0,
3270 sus ? atoi(sus) : 0,
3271 0, 0,
3272 inact ? atoi(inact) : 0,
3273 maxsi ? atoi(maxsi) : 0);
3274
3275 if (system(buf) != 0) {
3276 sigma_dut_print(dut, DUT_MSG_ERROR,
3277 "iwpriv addtspec request failed");
3278 send_resp(dut, conn, SIGMA_ERROR,
3279 "errorCode,Failed to execute addTspec command");
3280 return 0;
3281 }
3282
3283 sigma_dut_print(dut, DUT_MSG_INFO,
3284 "iwpriv addtspec request send");
3285
3286 /* Mapping handle to a TID */
3287 dut->tid_to_handle[atoi(tid)] = handle;
3288 } else if (strcasecmp(act, "delts") == 0) {
3289 if (tid == NULL)
3290 return -1;
3291
3292 if (atoi(tid) < 0 || atoi(tid) > 7) {
3293 sigma_dut_print(dut, DUT_MSG_ERROR,
3294 "TID %s not supported", tid);
3295 send_resp(dut, conn, SIGMA_ERROR,
3296 "errorCode,Unsupported TID");
3297 return 0;
3298 }
3299
3300 handle = dut->tid_to_handle[atoi(tid)];
3301
3302 if (handle < 7000 || handle > 7255) {
3303 /* Invalid handle ie no mapping for that TID */
3304 sigma_dut_print(dut, DUT_MSG_ERROR,
3305 "handle-> %d not found", handle);
3306 }
3307
3308 snprintf(buf, sizeof(buf), "iwpriv %s delTspec %d",
3309 intf, handle);
3310
3311 if (system(buf) != 0) {
3312 sigma_dut_print(dut, DUT_MSG_ERROR,
3313 "iwpriv deltspec request failed");
3314 send_resp(dut, conn, SIGMA_ERROR,
3315 "errorCode,Failed to execute delTspec command");
3316 return 0;
3317 }
3318
3319 sigma_dut_print(dut, DUT_MSG_INFO,
3320 "iwpriv deltspec request send");
3321
3322 dut->tid_to_handle[atoi(tid)] = 0;
3323 } else {
3324 sigma_dut_print(dut, DUT_MSG_ERROR,
3325 "Action type %s not supported", act);
3326 send_resp(dut, conn, SIGMA_ERROR,
3327 "errorCode,Unsupported Action");
3328 return 0;
3329 }
3330
3331 return 1;
3332}
3333
3334
vamsi krishna52e16f92017-08-29 12:37:34 +05303335static int find_network(struct sigma_dut *dut, const char *ssid)
3336{
3337 char list[4096];
3338 char *pos;
3339
3340 sigma_dut_print(dut, DUT_MSG_DEBUG,
3341 "Search for profile based on SSID: '%s'", ssid);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003342 if (wpa_command_resp(get_station_ifname(dut), "LIST_NETWORKS",
vamsi krishna52e16f92017-08-29 12:37:34 +05303343 list, sizeof(list)) < 0)
3344 return -1;
3345 pos = strstr(list, ssid);
3346 if (!pos || pos == list || pos[-1] != '\t' || pos[strlen(ssid)] != '\t')
3347 return -1;
3348
3349 while (pos > list && pos[-1] != '\n')
3350 pos--;
3351 dut->infra_network_id = atoi(pos);
3352 snprintf(dut->infra_ssid, sizeof(dut->infra_ssid), "%s", ssid);
3353 return 0;
3354}
3355
3356
Sunil Dutt44595082018-02-12 19:41:45 +05303357#ifdef NL80211_SUPPORT
3358static int sta_config_rsnie(struct sigma_dut *dut, int val)
3359{
3360 struct nl_msg *msg;
3361 int ret;
3362 struct nlattr *params;
3363 int ifindex;
3364
3365 ifindex = if_nametoindex("wlan0");
3366 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
3367 NL80211_CMD_VENDOR)) ||
3368 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
3369 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
3370 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
3371 QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION) ||
3372 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
3373 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE, val)) {
3374 sigma_dut_print(dut, DUT_MSG_ERROR,
3375 "%s: err in adding vendor_cmd and vendor_data",
3376 __func__);
3377 nlmsg_free(msg);
3378 return -1;
3379 }
3380 nla_nest_end(msg, params);
3381
3382 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
3383 if (ret) {
3384 sigma_dut_print(dut, DUT_MSG_ERROR,
3385 "%s: err in send_and_recv_msgs, ret=%d",
3386 __func__, ret);
3387 return ret;
3388 }
3389
3390 return 0;
3391}
3392#endif /* NL80211_SUPPORT */
3393
3394
Jouni Malinenf7222712019-06-13 01:50:21 +03003395static enum sigma_cmd_result cmd_sta_associate(struct sigma_dut *dut,
3396 struct sigma_conn *conn,
3397 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003398{
3399 /* const char *intf = get_param(cmd, "Interface"); */
3400 const char *ssid = get_param(cmd, "ssid");
3401 const char *wps_param = get_param(cmd, "WPS");
3402 const char *bssid = get_param(cmd, "bssid");
Jouni Malinen46a19b62017-06-23 14:31:27 +03003403 const char *chan = get_param(cmd, "channel");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02003404 const char *network_mode = get_param(cmd, "network_mode");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003405 int wps = 0;
Jouni Malinen3c367e82017-06-23 17:01:47 +03003406 char buf[1000], extra[50];
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003407 int e;
3408 enum sigma_cmd_result ret = SUCCESS_SEND_STATUS;
3409 struct wpa_ctrl *ctrl = NULL;
3410 int num_network_not_found = 0;
3411 int num_disconnected = 0;
3412 int tod = -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003413
3414 if (ssid == NULL)
3415 return -1;
3416
Jouni Malinen37d5c692019-08-19 16:56:55 +03003417 dut->server_cert_tod = 0;
3418
Jouni Malinen3c367e82017-06-23 17:01:47 +03003419 if (dut->rsne_override) {
Sunil Dutt44595082018-02-12 19:41:45 +05303420#ifdef NL80211_SUPPORT
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003421 if (get_driver_type(dut) == DRIVER_WCN) {
Sunil Dutt44595082018-02-12 19:41:45 +05303422 sta_config_rsnie(dut, 1);
3423 dut->config_rsnie = 1;
3424 }
3425#endif /* NL80211_SUPPORT */
Jouni Malinen3c367e82017-06-23 17:01:47 +03003426 snprintf(buf, sizeof(buf), "TEST_ASSOC_IE %s",
3427 dut->rsne_override);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003428 if (wpa_command(get_station_ifname(dut), buf) < 0) {
Jouni Malinen3c367e82017-06-23 17:01:47 +03003429 send_resp(dut, conn, SIGMA_ERROR,
3430 "ErrorCode,Failed to set DEV_CONFIGURE_IE RSNE override");
3431 return 0;
3432 }
3433 }
3434
Jouni Malinen68143132017-09-02 02:34:08 +03003435 if (dut->sae_commit_override) {
3436 snprintf(buf, sizeof(buf), "SET sae_commit_override %s",
3437 dut->sae_commit_override);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003438 if (wpa_command(get_station_ifname(dut), buf) < 0) {
Jouni Malinen68143132017-09-02 02:34:08 +03003439 send_resp(dut, conn, SIGMA_ERROR,
3440 "ErrorCode,Failed to set SAE commit override");
3441 return 0;
3442 }
3443 }
Ankita Bajaj1bde7942018-01-09 19:15:01 +05303444#ifdef ANDROID
3445 if (dut->fils_hlp)
3446 process_fils_hlp(dut);
3447#endif /* ANDROID */
Jouni Malinen68143132017-09-02 02:34:08 +03003448
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003449 if (wps_param &&
3450 (strcmp(wps_param, "1") == 0 || strcasecmp(wps_param, "On") == 0))
3451 wps = 1;
3452
3453 if (wps) {
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02003454 if (dut->program == PROGRAM_60GHZ && network_mode &&
3455 strcasecmp(network_mode, "PBSS") == 0 &&
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003456 set_network(get_station_ifname(dut), dut->infra_network_id,
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02003457 "pbss", "1") < 0)
3458 return -2;
3459
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003460 if (dut->wps_method == WFA_CS_WPS_NOT_READY) {
3461 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,WPS "
3462 "parameters not yet set");
3463 return 0;
3464 }
3465 if (dut->wps_method == WFA_CS_WPS_PBC) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003466 if (wpa_command(get_station_ifname(dut), "WPS_PBC") < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003467 return -2;
3468 } else {
3469 snprintf(buf, sizeof(buf), "WPS_PIN any %s",
3470 dut->wps_pin);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003471 if (wpa_command(get_station_ifname(dut), buf) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003472 return -2;
3473 }
3474 } else {
vamsi krishna52e16f92017-08-29 12:37:34 +05303475 if (strcmp(ssid, dut->infra_ssid) == 0) {
3476 sigma_dut_print(dut, DUT_MSG_DEBUG,
3477 "sta_associate for the most recently added network");
3478 } else if (find_network(dut, ssid) < 0) {
3479 sigma_dut_print(dut, DUT_MSG_DEBUG,
3480 "sta_associate for a previously stored network profile");
3481 send_resp(dut, conn, SIGMA_ERROR,
3482 "ErrorCode,Profile not found");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003483 return 0;
3484 }
3485
3486 if (bssid &&
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003487 set_network(get_station_ifname(dut), dut->infra_network_id,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003488 "bssid", bssid) < 0) {
3489 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
3490 "Invalid bssid argument");
3491 return 0;
3492 }
3493
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003494 if (dut->program == PROGRAM_WPA3 &&
3495 dut->sta_associate_wait_connect) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003496 ctrl = open_wpa_mon(get_station_ifname(dut));
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003497 if (!ctrl)
3498 return ERROR_SEND_STATUS;
3499 }
3500
Jouni Malinen46a19b62017-06-23 14:31:27 +03003501 extra[0] = '\0';
3502 if (chan)
3503 snprintf(extra, sizeof(extra), " freq=%u",
Alexei Avshalom Lazar093569f2018-11-13 14:08:17 +02003504 channel_to_freq(dut, atoi(chan)));
Jouni Malinen46a19b62017-06-23 14:31:27 +03003505 snprintf(buf, sizeof(buf), "SELECT_NETWORK %d%s",
3506 dut->infra_network_id, extra);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003507 if (wpa_command(get_station_ifname(dut), buf) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003508 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to select "
3509 "network id %d on %s",
3510 dut->infra_network_id,
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003511 get_station_ifname(dut));
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003512 ret = ERROR_SEND_STATUS;
3513 goto done;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003514 }
3515 }
3516
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003517 if (!ctrl)
3518 return SUCCESS_SEND_STATUS;
3519
3520 /* Wait for connection result to be able to store server certificate
3521 * hash for trust root override testing
3522 * (dev_exec_action,ServerCertTrust). */
3523
3524 for (e = 0; e < 20; e++) {
3525 const char *events[] = {
3526 "CTRL-EVENT-EAP-PEER-CERT",
3527 "CTRL-EVENT-EAP-TLS-CERT-ERROR",
3528 "CTRL-EVENT-DISCONNECTED",
3529 "CTRL-EVENT-CONNECTED",
3530 "CTRL-EVENT-NETWORK-NOT-FOUND",
3531 NULL
3532 };
3533 char buf[1024];
3534 int res;
3535
3536 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
3537 if (res < 0) {
Jouni Malinenf1f16642019-11-15 21:19:04 +02003538 send_resp(dut, conn, SIGMA_COMPLETE,
3539 "Result,Association did not complete");
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003540 ret = STATUS_SENT_ERROR;
3541 break;
3542 }
3543 sigma_dut_print(dut, DUT_MSG_DEBUG, "Connection event: %s",
3544 buf);
3545
3546 if (strstr(buf, "CTRL-EVENT-EAP-PEER-CERT") &&
3547 strstr(buf, " depth=0")) {
3548 char *pos = strstr(buf, " hash=");
3549
3550 if (pos) {
3551 char *end;
3552
Jouni Malinen34b19cb2019-08-16 16:37:17 +03003553 if (strstr(buf, " tod=1"))
3554 tod = 1;
3555 else if (strstr(buf, " tod=2"))
3556 tod = 2;
3557 else
3558 tod = 0;
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003559 sigma_dut_print(dut, DUT_MSG_DEBUG,
3560 "Server certificate TOD policy: %d",
3561 tod);
Jouni Malinen37d5c692019-08-19 16:56:55 +03003562 dut->server_cert_tod = tod;
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003563
3564 pos += 6;
3565 end = strchr(pos, ' ');
3566 if (end)
3567 *end = '\0';
3568 strlcpy(dut->server_cert_hash, pos,
3569 sizeof(dut->server_cert_hash));
3570 sigma_dut_print(dut, DUT_MSG_DEBUG,
3571 "Server certificate hash: %s",
3572 dut->server_cert_hash);
3573 }
3574 }
3575
3576 if (strstr(buf, "CTRL-EVENT-EAP-TLS-CERT-ERROR")) {
3577 send_resp(dut, conn, SIGMA_COMPLETE,
3578 "Result,TLS server certificate validation failed");
3579 ret = STATUS_SENT_ERROR;
3580 break;
3581 }
3582
3583 if (strstr(buf, "CTRL-EVENT-NETWORK-NOT-FOUND")) {
3584 num_network_not_found++;
3585
3586 if (num_network_not_found > 2) {
3587 send_resp(dut, conn, SIGMA_COMPLETE,
3588 "Result,Network not found");
3589 ret = STATUS_SENT_ERROR;
3590 break;
3591 }
3592 }
3593
3594 if (strstr(buf, "CTRL-EVENT-DISCONNECTED")) {
3595 num_disconnected++;
3596
3597 if (num_disconnected > 2) {
3598 send_resp(dut, conn, SIGMA_COMPLETE,
3599 "Result,Connection failed");
3600 ret = STATUS_SENT_ERROR;
3601 break;
3602 }
3603 }
3604
3605 if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
3606 if (tod >= 0) {
3607 sigma_dut_print(dut, DUT_MSG_DEBUG,
3608 "Network profile TOD policy update: %d -> %d",
3609 dut->sta_tod_policy, tod);
3610 dut->sta_tod_policy = tod;
3611 }
3612 break;
3613 }
3614 }
3615done:
3616 if (ctrl) {
3617 wpa_ctrl_detach(ctrl);
3618 wpa_ctrl_close(ctrl);
3619 }
3620 return ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003621}
3622
3623
3624static int run_hs20_osu(struct sigma_dut *dut, const char *params)
3625{
3626 char buf[500], cmd[200];
3627 int res;
3628
3629 /* Use hs20-osu-client file at the current dir, if found; otherwise use
3630 * default path */
3631 res = snprintf(cmd, sizeof(cmd),
3632 "%s -w \"%s\" -r hs20-osu-client.res %s%s -dddKt -f Logs/hs20-osu-client.txt",
3633 file_exists("./hs20-osu-client") ?
3634 "./hs20-osu-client" : "hs20-osu-client",
3635 sigma_wpas_ctrl,
3636 dut->summary_log ? "-s " : "",
3637 dut->summary_log ? dut->summary_log : "");
3638 if (res < 0 || res >= (int) sizeof(cmd))
3639 return -1;
3640
3641 res = snprintf(buf, sizeof(buf), "%s %s", cmd, params);
3642 if (res < 0 || res >= (int) sizeof(buf))
3643 return -1;
3644 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
3645
3646 if (system(buf) != 0) {
3647 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to run: %s", buf);
3648 return -1;
3649 }
3650 sigma_dut_print(dut, DUT_MSG_DEBUG,
3651 "Completed hs20-osu-client operation");
3652
3653 return 0;
3654}
3655
3656
3657static int download_ppsmo(struct sigma_dut *dut,
3658 struct sigma_conn *conn,
3659 const char *intf,
3660 struct sigma_cmd *cmd)
3661{
3662 const char *name, *path, *val;
3663 char url[500], buf[600], fbuf[100];
3664 char *fqdn = NULL;
3665
3666 name = get_param(cmd, "FileName");
3667 path = get_param(cmd, "FilePath");
3668 if (name == NULL || path == NULL)
3669 return -1;
3670
3671 if (strcasecmp(path, "VendorSpecific") == 0) {
3672 snprintf(url, sizeof(url), "PPS/%s", name);
3673 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured PPS MO "
3674 "from the device (%s)", url);
3675 if (!file_exists(url)) {
3676 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
3677 "PPS MO file does not exist");
3678 return 0;
3679 }
3680 snprintf(buf, sizeof(buf), "cp %s pps-tnds.xml", url);
3681 if (system(buf) != 0) {
3682 send_resp(dut, conn, SIGMA_ERROR,
3683 "errorCode,Failed to copy PPS MO");
3684 return 0;
3685 }
3686 } else if (strncasecmp(path, "http:", 5) != 0 &&
3687 strncasecmp(path, "https:", 6) != 0) {
3688 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
3689 "Unsupported FilePath value");
3690 return 0;
3691 } else {
3692 snprintf(url, sizeof(url), "%s/%s", path, name);
3693 sigma_dut_print(dut, DUT_MSG_INFO, "Downloading PPS MO from %s",
3694 url);
3695 snprintf(buf, sizeof(buf), "wget -T 10 -t 3 -O pps-tnds.xml '%s'", url);
3696 remove("pps-tnds.xml");
3697 if (system(buf) != 0) {
3698 send_resp(dut, conn, SIGMA_ERROR,
3699 "errorCode,Failed to download PPS MO");
3700 return 0;
3701 }
3702 }
3703
3704 if (run_hs20_osu(dut, "from_tnds pps-tnds.xml pps.xml") < 0) {
3705 send_resp(dut, conn, SIGMA_ERROR,
3706 "errorCode,Failed to parse downloaded PPSMO");
3707 return 0;
3708 }
3709 unlink("pps-tnds.xml");
3710
3711 val = get_param(cmd, "managementTreeURI");
3712 if (val) {
3713 const char *pos, *end;
3714 sigma_dut_print(dut, DUT_MSG_DEBUG, "managementTreeURI: %s",
3715 val);
3716 if (strncmp(val, "./Wi-Fi/", 8) != 0) {
3717 send_resp(dut, conn, SIGMA_ERROR,
3718 "errorCode,Invalid managementTreeURI prefix");
3719 return 0;
3720 }
3721 pos = val + 8;
3722 end = strchr(pos, '/');
3723 if (end == NULL ||
3724 strcmp(end, "/PerProviderSubscription") != 0) {
3725 send_resp(dut, conn, SIGMA_ERROR,
3726 "errorCode,Invalid managementTreeURI postfix");
3727 return 0;
3728 }
3729 if (end - pos >= (int) sizeof(fbuf)) {
3730 send_resp(dut, conn, SIGMA_ERROR,
3731 "errorCode,Too long FQDN in managementTreeURI");
3732 return 0;
3733 }
3734 memcpy(fbuf, pos, end - pos);
3735 fbuf[end - pos] = '\0';
3736 fqdn = fbuf;
3737 sigma_dut_print(dut, DUT_MSG_INFO,
3738 "FQDN from managementTreeURI: %s", fqdn);
3739 } else if (run_hs20_osu(dut, "get_fqdn pps.xml") == 0) {
3740 FILE *f = fopen("pps-fqdn", "r");
3741 if (f) {
3742 if (fgets(fbuf, sizeof(fbuf), f)) {
3743 fbuf[sizeof(fbuf) - 1] = '\0';
3744 fqdn = fbuf;
3745 sigma_dut_print(dut, DUT_MSG_DEBUG,
3746 "Use FQDN %s", fqdn);
3747 }
3748 fclose(f);
3749 }
3750 }
3751
3752 if (fqdn == NULL) {
3753 send_resp(dut, conn, SIGMA_ERROR,
3754 "errorCode,No FQDN specified");
3755 return 0;
3756 }
3757
3758 mkdir("SP", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
3759 snprintf(buf, sizeof(buf), "SP/%s", fqdn);
3760 mkdir(buf, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
3761
3762 snprintf(buf, sizeof(buf), "SP/%s/pps.xml", fqdn);
3763 if (rename("pps.xml", buf) < 0) {
3764 send_resp(dut, conn, SIGMA_ERROR,
3765 "errorCode,Could not move PPS MO");
3766 return 0;
3767 }
3768
3769 if (strcasecmp(path, "VendorSpecific") == 0) {
3770 snprintf(buf, sizeof(buf), "cp Certs/ca.pem SP/%s/ca.pem",
3771 fqdn);
3772 if (system(buf)) {
3773 send_resp(dut, conn, SIGMA_ERROR,
3774 "errorCode,Failed to copy OSU CA cert");
3775 return 0;
3776 }
3777
3778 snprintf(buf, sizeof(buf),
3779 "cp Certs/aaa-ca.pem SP/%s/aaa-ca.pem",
3780 fqdn);
3781 if (system(buf)) {
3782 send_resp(dut, conn, SIGMA_ERROR,
3783 "errorCode,Failed to copy AAA CA cert");
3784 return 0;
3785 }
3786 } else {
3787 snprintf(buf, sizeof(buf),
3788 "dl_osu_ca SP/%s/pps.xml SP/%s/ca.pem",
3789 fqdn, fqdn);
3790 if (run_hs20_osu(dut, buf) < 0) {
3791 send_resp(dut, conn, SIGMA_ERROR,
3792 "errorCode,Failed to download OSU CA cert");
3793 return 0;
3794 }
3795
3796 snprintf(buf, sizeof(buf),
3797 "dl_aaa_ca SP/%s/pps.xml SP/%s/aaa-ca.pem",
3798 fqdn, fqdn);
3799 if (run_hs20_osu(dut, buf) < 0) {
3800 sigma_dut_print(dut, DUT_MSG_INFO,
3801 "Failed to download AAA CA cert");
3802 }
3803 }
3804
3805 if (file_exists("next-client-cert.pem")) {
3806 snprintf(buf, sizeof(buf), "SP/%s/client-cert.pem", fqdn);
3807 if (rename("next-client-cert.pem", buf) < 0) {
3808 send_resp(dut, conn, SIGMA_ERROR,
3809 "errorCode,Could not move client certificate");
3810 return 0;
3811 }
3812 }
3813
3814 if (file_exists("next-client-key.pem")) {
3815 snprintf(buf, sizeof(buf), "SP/%s/client-key.pem", fqdn);
3816 if (rename("next-client-key.pem", buf) < 0) {
3817 send_resp(dut, conn, SIGMA_ERROR,
3818 "errorCode,Could not move client key");
3819 return 0;
3820 }
3821 }
3822
3823 snprintf(buf, sizeof(buf), "set_pps SP/%s/pps.xml", fqdn);
3824 if (run_hs20_osu(dut, buf) < 0) {
3825 send_resp(dut, conn, SIGMA_ERROR,
3826 "errorCode,Failed to configure credential from "
3827 "PPSMO");
3828 return 0;
3829 }
3830
3831 return 1;
3832}
3833
3834
3835static int download_cert(struct sigma_dut *dut,
3836 struct sigma_conn *conn,
3837 const char *intf,
3838 struct sigma_cmd *cmd)
3839{
3840 const char *name, *path;
3841 char url[500], buf[600];
3842
3843 name = get_param(cmd, "FileName");
3844 path = get_param(cmd, "FilePath");
3845 if (name == NULL || path == NULL)
3846 return -1;
3847
3848 if (strcasecmp(path, "VendorSpecific") == 0) {
3849 snprintf(url, sizeof(url), "Certs/%s-cert.pem", name);
3850 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured client "
3851 "certificate from the device (%s)", url);
3852 if (!file_exists(url)) {
3853 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
3854 "certificate file does not exist");
3855 return 0;
3856 }
3857 snprintf(buf, sizeof(buf), "cp %s next-client-cert.pem", url);
3858 if (system(buf) != 0) {
3859 send_resp(dut, conn, SIGMA_ERROR,
3860 "errorCode,Failed to copy client "
3861 "certificate");
3862 return 0;
3863 }
3864
3865 snprintf(url, sizeof(url), "Certs/%s-key.pem", name);
3866 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured client "
3867 "private key from the device (%s)", url);
3868 if (!file_exists(url)) {
3869 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
3870 "private key file does not exist");
3871 return 0;
3872 }
3873 snprintf(buf, sizeof(buf), "cp %s next-client-key.pem", url);
3874 if (system(buf) != 0) {
3875 send_resp(dut, conn, SIGMA_ERROR,
3876 "errorCode,Failed to copy client key");
3877 return 0;
3878 }
3879 } else if (strncasecmp(path, "http:", 5) != 0 &&
3880 strncasecmp(path, "https:", 6) != 0) {
3881 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
3882 "Unsupported FilePath value");
3883 return 0;
3884 } else {
3885 snprintf(url, sizeof(url), "%s/%s.pem", path, name);
3886 sigma_dut_print(dut, DUT_MSG_INFO, "Downloading client "
3887 "certificate/key from %s", url);
3888 snprintf(buf, sizeof(buf),
3889 "wget -T 10 -t 3 -O next-client-cert.pem '%s'", url);
3890 if (system(buf) != 0) {
3891 send_resp(dut, conn, SIGMA_ERROR,
3892 "errorCode,Failed to download client "
3893 "certificate");
3894 return 0;
3895 }
3896
3897 if (system("cp next-client-cert.pem next-client-key.pem") != 0)
3898 {
3899 send_resp(dut, conn, SIGMA_ERROR,
3900 "errorCode,Failed to copy client key");
3901 return 0;
3902 }
3903 }
3904
3905 return 1;
3906}
3907
3908
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02003909static int cmd_sta_preset_testparameters_60ghz(struct sigma_dut *dut,
3910 struct sigma_conn *conn,
3911 struct sigma_cmd *cmd)
3912{
3913 const char *val;
3914 const char *intf = get_param(cmd, "interface");
3915
3916 if (!intf)
3917 return -1;
3918
3919 val = get_param(cmd, "WscIEFragment");
3920 if (val && strcasecmp(val, "enable") == 0) {
3921 sigma_dut_print(dut, DUT_MSG_DEBUG,
3922 "Enable WSC IE fragmentation");
3923
3924 dut->wsc_fragment = 1;
3925 /* set long attributes to force fragmentation */
3926 if (wpa_command(intf, "SET device_name "
3927 WPS_LONG_DEVICE_NAME) < 0)
3928 return -2;
3929 if (wpa_command(intf, "SET manufacturer "
3930 WPS_LONG_MANUFACTURER) < 0)
3931 return -2;
3932 if (wpa_command(intf, "SET model_name "
3933 WPS_LONG_MODEL_NAME) < 0)
3934 return -2;
3935 if (wpa_command(intf, "SET model_number "
3936 WPS_LONG_MODEL_NUMBER) < 0)
3937 return -2;
3938 if (wpa_command(intf, "SET serial_number "
3939 WPS_LONG_SERIAL_NUMBER) < 0)
3940 return -2;
3941 }
3942
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02003943 val = get_param(cmd, "RSN_IE");
3944 if (val) {
3945 if (strcasecmp(val, "disable") == 0)
3946 dut->force_rsn_ie = FORCE_RSN_IE_REMOVE;
3947 else if (strcasecmp(val, "enable") == 0)
3948 dut->force_rsn_ie = FORCE_RSN_IE_ADD;
3949 }
3950
Alexei Avshalom Lazar744ae8a2019-01-31 17:26:46 +02003951 val = get_param(cmd, "WpsVersion");
3952 if (val)
3953 dut->wps_forced_version = get_wps_forced_version(dut, val);
3954
Alexei Avshalom Lazar2eccf4d2019-01-31 10:03:59 +02003955 val = get_param(cmd, "WscEAPFragment");
3956 if (val && strcasecmp(val, "enable") == 0)
3957 dut->eap_fragment = 1;
3958
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02003959 return 1;
3960}
3961
3962
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003963static int cmd_sta_preset_testparameters_hs2_r2(struct sigma_dut *dut,
3964 struct sigma_conn *conn,
3965 const char *intf,
3966 struct sigma_cmd *cmd)
3967{
3968 const char *val;
3969
3970 val = get_param(cmd, "FileType");
3971 if (val && strcasecmp(val, "PPSMO") == 0)
3972 return download_ppsmo(dut, conn, intf, cmd);
3973 if (val && strcasecmp(val, "CERT") == 0)
3974 return download_cert(dut, conn, intf, cmd);
3975 if (val) {
3976 send_resp(dut, conn, SIGMA_ERROR,
3977 "ErrorCode,Unsupported FileType");
3978 return 0;
3979 }
3980
3981 return 1;
3982}
3983
3984
Ankita Bajaja2cb5672017-10-25 16:08:28 +05303985static int cmd_sta_preset_testparameters_oce(struct sigma_dut *dut,
3986 struct sigma_conn *conn,
3987 const char *intf,
3988 struct sigma_cmd *cmd)
3989{
3990 const char *val;
Ankita Bajaj1bde7942018-01-09 19:15:01 +05303991 char buf[1000];
3992 char text[20];
3993 unsigned char addr[ETH_ALEN];
Ankita Bajaja2cb5672017-10-25 16:08:28 +05303994
3995 val = get_param(cmd, "OCESupport");
3996 if (val && strcasecmp(val, "Disable") == 0) {
3997 if (wpa_command(intf, "SET oce 0") < 0) {
3998 send_resp(dut, conn, SIGMA_ERROR,
3999 "ErrorCode,Failed to disable OCE");
4000 return 0;
4001 }
4002 } else if (val && strcasecmp(val, "Enable") == 0) {
4003 if (wpa_command(intf, "SET oce 1") < 0) {
4004 send_resp(dut, conn, SIGMA_ERROR,
4005 "ErrorCode,Failed to enable OCE");
4006 return 0;
4007 }
4008 }
4009
vamsi krishnaa2799492017-12-05 14:28:01 +05304010 val = get_param(cmd, "FILScap");
4011 if (val && (atoi(val) == 1)) {
4012 if (wpa_command(intf, "SET disable_fils 0") < 0) {
4013 send_resp(dut, conn, SIGMA_ERROR,
4014 "ErrorCode,Failed to enable FILS");
4015 return 0;
4016 }
4017 } else if (val && (atoi(val) == 0)) {
4018 if (wpa_command(intf, "SET disable_fils 1") < 0) {
4019 send_resp(dut, conn, SIGMA_ERROR,
4020 "ErrorCode,Failed to disable FILS");
4021 return 0;
4022 }
4023 }
4024
Ankita Bajaj1bde7942018-01-09 19:15:01 +05304025 val = get_param(cmd, "FILSHLP");
4026 if (val && strcasecmp(val, "Enable") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004027 if (get_wpa_status(get_station_ifname(dut), "address", text,
Ankita Bajaj1bde7942018-01-09 19:15:01 +05304028 sizeof(text)) < 0)
4029 return -2;
4030 hwaddr_aton(text, addr);
4031 snprintf(buf, sizeof(buf),
4032 "FILS_HLP_REQ_ADD ff:ff:ff:ff:ff:ff "
4033 "080045100140000040004011399e00000000ffffffff00440043"
4034 "012cb30001010600fd4f46410000000000000000000000000000"
4035 "000000000000"
4036 "%02x%02x%02x%02x%02x%02x"
4037 "0000000000000000000000000000000000000000000000000000"
4038 "0000000000000000000000000000000000000000000000000000"
4039 "0000000000000000000000000000000000000000000000000000"
4040 "0000000000000000000000000000000000000000000000000000"
4041 "0000000000000000000000000000000000000000000000000000"
4042 "0000000000000000000000000000000000000000000000000000"
4043 "0000000000000000000000000000000000000000000000000000"
4044 "0000000000000000000000000000000000000000638253633501"
4045 "013d0701000af549d29b390205dc3c12616e64726f69642d6468"
4046 "63702d382e302e30370a0103060f1a1c333a3b2b5000ff00",
4047 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
4048 if (wpa_command(intf, buf)) {
4049 send_resp(dut, conn, SIGMA_ERROR,
4050 "ErrorCode,Failed to add HLP");
4051 return 0;
4052 }
4053 dut->fils_hlp = 1;
4054 }
4055
Ankita Bajaja2cb5672017-10-25 16:08:28 +05304056 return 1;
4057}
4058
4059
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004060static void ath_sta_set_noack(struct sigma_dut *dut, const char *intf,
4061 const char *val)
4062{
4063 int counter = 0;
4064 char token[50];
4065 char *result;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05304066 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004067
Peng Xub8fc5cc2017-05-10 17:27:28 -07004068 strlcpy(token, val, sizeof(token));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004069 token[sizeof(token) - 1] = '\0';
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05304070 result = strtok_r(token, ":", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004071 while (result) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004072 if (strcmp(result, "disable") == 0)
4073 run_iwpriv(dut, intf, "noackpolicy %d 1 0", counter);
4074 else
4075 run_iwpriv(dut, intf, "noackpolicy %d 1 1", counter);
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05304076 result = strtok_r(NULL, ":", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004077 counter++;
4078 }
4079}
4080
4081
4082static void ath_sta_set_rts(struct sigma_dut *dut, const char *intf,
4083 const char *val)
4084{
4085 char buf[100];
4086
4087 snprintf(buf, sizeof(buf), "iwconfig %s rts %s", intf, val);
4088 if (system(buf) != 0) {
4089 sigma_dut_print(dut, DUT_MSG_ERROR, "iwconfig RTS failed");
4090 }
4091}
4092
4093
4094static void ath_sta_set_wmm(struct sigma_dut *dut, const char *intf,
4095 const char *val)
4096{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004097 if (strcasecmp(val, "off") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004098 run_iwpriv(dut, intf, "wmm 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004099 }
4100}
4101
4102
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08004103static int wcn_sta_set_wmm(struct sigma_dut *dut, const char *intf,
4104 const char *val)
4105{
4106#ifdef NL80211_SUPPORT
4107 struct nl_msg *msg;
4108 int ret = 0;
4109 struct nlattr *params;
4110 int ifindex;
4111 int wmmenable = 1;
4112
4113 if (val &&
4114 (strcasecmp(val, "off") == 0 || strcmp(val, "0") == 0))
4115 wmmenable = 0;
4116
4117 ifindex = if_nametoindex(intf);
4118 if (ifindex == 0) {
4119 sigma_dut_print(dut, DUT_MSG_ERROR,
4120 "%s: Index for interface %s failed",
4121 __func__, intf);
4122 return -1;
4123 }
4124
4125 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4126 NL80211_CMD_VENDOR)) ||
4127 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4128 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4129 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4130 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4131 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4132 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WMM_ENABLE,
4133 wmmenable)) {
4134 sigma_dut_print(dut, DUT_MSG_ERROR,
4135 "%s: err in adding vendor_cmd and vendor_data",
4136 __func__);
4137 nlmsg_free(msg);
4138 return -1;
4139 }
4140 nla_nest_end(msg, params);
4141
4142 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4143 if (ret) {
4144 sigma_dut_print(dut, DUT_MSG_ERROR,
4145 "%s: err in send_and_recv_msgs, ret=%d",
4146 __func__, ret);
4147 }
4148 return ret;
4149#else /* NL80211_SUPPORT */
4150 sigma_dut_print(dut, DUT_MSG_ERROR,
4151 "WMM cannot be changed without NL80211_SUPPORT defined");
4152 return -1;
4153#endif /* NL80211_SUPPORT */
4154}
4155
4156
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004157static void ath_sta_set_sgi(struct sigma_dut *dut, const char *intf,
4158 const char *val)
4159{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004160 int sgi20;
4161
4162 sgi20 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
4163
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004164 run_iwpriv(dut, intf, "shortgi %d", sgi20);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004165}
4166
4167
4168static void ath_sta_set_11nrates(struct sigma_dut *dut, const char *intf,
4169 const char *val)
4170{
Pradeep Reddy POTTETI67376b72016-10-25 20:08:17 +05304171 int rate_code, v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004172
4173 /* Disable Tx Beam forming when using a fixed rate */
4174 ath_disable_txbf(dut, intf);
4175
Pradeep Reddy POTTETI67376b72016-10-25 20:08:17 +05304176 v = atoi(val);
4177 if (v < 0 || v > 32) {
4178 sigma_dut_print(dut, DUT_MSG_ERROR,
4179 "Invalid Fixed MCS rate: %d", v);
4180 return;
4181 }
4182 rate_code = 0x80 + v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004183
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004184 run_iwpriv(dut, intf, "set11NRates 0x%x", rate_code);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004185
4186 /* Channel width gets messed up, fix this */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004187 run_iwpriv(dut, intf, "chwidth %d", dut->chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004188}
4189
4190
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08004191static void iwpriv_sta_set_amsdu(struct sigma_dut *dut, const char *intf,
4192 const char *val)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004193{
4194 char buf[60];
4195
4196 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)
4197 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 2", intf);
4198 else
4199 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 1", intf);
4200
4201 if (system(buf) != 0)
4202 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv amsdu failed");
4203}
4204
4205
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07004206static int iwpriv_sta_set_ampdu(struct sigma_dut *dut, const char *intf,
4207 int ampdu)
4208{
4209 char buf[60];
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08004210 int maxaggregation = 63;
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07004211
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08004212 if (ampdu)
4213 ampdu = maxaggregation;
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07004214 snprintf(buf, sizeof(buf), "iwpriv %s ampdu %d", intf, ampdu);
4215 if (system(buf) != 0) {
4216 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv ampdu failed");
4217 return -1;
4218 }
4219
4220 return 0;
4221}
4222
4223
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004224static void ath_sta_set_stbc(struct sigma_dut *dut, const char *intf,
4225 const char *val)
4226{
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004227 run_iwpriv(dut, intf, "tx_stbc %s", val);
4228 run_iwpriv(dut, intf, "rx_stbc %s", val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004229}
4230
4231
4232static int wcn_sta_set_cts_width(struct sigma_dut *dut, const char *intf,
4233 const char *val)
4234{
4235 char buf[60];
4236
Peng Xucc317ed2017-05-18 16:44:37 -07004237 if (strcmp(val, "160") == 0) {
4238 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 5", intf);
4239 } else if (strcmp(val, "80") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004240 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 3", intf);
4241 } else if (strcmp(val, "40") == 0) {
4242 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 2", intf);
4243 } else if (strcmp(val, "20") == 0) {
4244 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 1", intf);
4245 } else if (strcasecmp(val, "Auto") == 0) {
4246 buf[0] = '\0';
4247 } else {
4248 sigma_dut_print(dut, DUT_MSG_ERROR,
4249 "WIDTH/CTS_WIDTH value not supported");
4250 return -1;
4251 }
4252
4253 if (buf[0] != '\0' && system(buf) != 0) {
4254 sigma_dut_print(dut, DUT_MSG_ERROR,
4255 "Failed to set WIDTH/CTS_WIDTH");
4256 return -1;
4257 }
4258
4259 return 0;
4260}
4261
4262
4263int ath_set_width(struct sigma_dut *dut, struct sigma_conn *conn,
4264 const char *intf, const char *val)
4265{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004266 if (strcasecmp(val, "Auto") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004267 run_iwpriv(dut, intf, "chwidth 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004268 dut->chwidth = 0;
4269 } else if (strcasecmp(val, "20") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004270 run_iwpriv(dut, intf, "chwidth 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004271 dut->chwidth = 0;
4272 } else if (strcasecmp(val, "40") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004273 run_iwpriv(dut, intf, "chwidth 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004274 dut->chwidth = 1;
4275 } else if (strcasecmp(val, "80") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004276 run_iwpriv(dut, intf, "chwidth 2");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004277 dut->chwidth = 2;
4278 } else if (strcasecmp(val, "160") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004279 run_iwpriv(dut, intf, "chwidth 3");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004280 dut->chwidth = 3;
4281 } else {
4282 send_resp(dut, conn, SIGMA_ERROR,
4283 "ErrorCode,WIDTH not supported");
4284 return -1;
4285 }
4286
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004287 return 0;
4288}
4289
4290
4291static int wcn_sta_set_sp_stream(struct sigma_dut *dut, const char *intf,
4292 const char *val)
4293{
4294 char buf[60];
Arif Hussainac6c5112018-05-25 17:34:00 -07004295 int sta_nss;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004296
Amarnath Hullur Subramanyamd5374fa2018-02-25 19:00:24 -08004297 if (strcmp(val, "1SS") == 0 || strcmp(val, "1") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004298 snprintf(buf, sizeof(buf), "iwpriv %s nss 1", intf);
Arif Hussainac6c5112018-05-25 17:34:00 -07004299 sta_nss = 1;
Amarnath Hullur Subramanyamd5374fa2018-02-25 19:00:24 -08004300 } else if (strcmp(val, "2SS") == 0 || strcmp(val, "2") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004301 snprintf(buf, sizeof(buf), "iwpriv %s nss 2", intf);
Arif Hussainac6c5112018-05-25 17:34:00 -07004302 sta_nss = 2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004303 } else {
4304 sigma_dut_print(dut, DUT_MSG_ERROR,
4305 "SP_STREAM value not supported");
4306 return -1;
4307 }
4308
4309 if (system(buf) != 0) {
4310 sigma_dut_print(dut, DUT_MSG_ERROR,
4311 "Failed to set SP_STREAM");
4312 return -1;
4313 }
4314
Arif Hussainac6c5112018-05-25 17:34:00 -07004315 dut->sta_nss = sta_nss;
4316
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004317 return 0;
4318}
4319
4320
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05304321static void wcn_sta_set_stbc(struct sigma_dut *dut, const char *intf,
4322 const char *val)
4323{
4324 char buf[60];
4325
4326 snprintf(buf, sizeof(buf), "iwpriv %s tx_stbc %s", intf, val);
4327 if (system(buf) != 0)
4328 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv tx_stbc failed");
4329
4330 snprintf(buf, sizeof(buf), "iwpriv %s rx_stbc %s", intf, val);
4331 if (system(buf) != 0)
4332 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv rx_stbc failed");
4333}
4334
4335
Ashwini Patil68d02cd2017-01-10 15:39:16 +05304336static int mbo_set_cellular_data_capa(struct sigma_dut *dut,
4337 struct sigma_conn *conn,
4338 const char *intf, int capa)
4339{
4340 char buf[32];
4341
4342 if (capa > 0 && capa < 4) {
4343 snprintf(buf, sizeof(buf), "SET mbo_cell_capa %d", capa);
4344 if (wpa_command(intf, buf) < 0) {
4345 send_resp(dut, conn, SIGMA_ERROR,
4346 "ErrorCode, Failed to set cellular data capability");
4347 return 0;
4348 }
4349 return 1;
4350 }
4351
4352 sigma_dut_print(dut, DUT_MSG_ERROR,
4353 "Invalid Cellular data capability: %d", capa);
4354 send_resp(dut, conn, SIGMA_INVALID,
4355 "ErrorCode,Invalid cellular data capability");
4356 return 0;
4357}
4358
4359
Ashwini Patil9183fdb2017-04-13 16:58:25 +05304360static int mbo_set_roaming(struct sigma_dut *dut, struct sigma_conn *conn,
4361 const char *intf, const char *val)
4362{
4363 if (strcasecmp(val, "Disable") == 0) {
4364 if (wpa_command(intf, "SET roaming 0") < 0) {
4365 send_resp(dut, conn, SIGMA_ERROR,
4366 "ErrorCode,Failed to disable roaming");
4367 return 0;
4368 }
4369 return 1;
4370 }
4371
4372 if (strcasecmp(val, "Enable") == 0) {
4373 if (wpa_command(intf, "SET roaming 1") < 0) {
4374 send_resp(dut, conn, SIGMA_ERROR,
4375 "ErrorCode,Failed to enable roaming");
4376 return 0;
4377 }
4378 return 1;
4379 }
4380
4381 sigma_dut_print(dut, DUT_MSG_ERROR,
4382 "Invalid value provided for roaming: %s", val);
4383 send_resp(dut, conn, SIGMA_INVALID,
4384 "ErrorCode,Unknown value provided for Roaming");
4385 return 0;
4386}
4387
4388
Ashwini Patila75de5a2017-04-13 16:35:05 +05304389static int mbo_set_assoc_disallow(struct sigma_dut *dut,
4390 struct sigma_conn *conn,
4391 const char *intf, const char *val)
4392{
4393 if (strcasecmp(val, "Disable") == 0) {
4394 if (wpa_command(intf, "SET ignore_assoc_disallow 1") < 0) {
4395 send_resp(dut, conn, SIGMA_ERROR,
4396 "ErrorCode,Failed to disable Assoc_disallow");
4397 return 0;
4398 }
4399 return 1;
4400 }
4401
4402 if (strcasecmp(val, "Enable") == 0) {
4403 if (wpa_command(intf, "SET ignore_assoc_disallow 0") < 0) {
4404 send_resp(dut, conn, SIGMA_ERROR,
4405 "ErrorCode,Failed to enable Assoc_disallow");
4406 return 0;
4407 }
4408 return 1;
4409 }
4410
4411 sigma_dut_print(dut, DUT_MSG_ERROR,
4412 "Invalid value provided for Assoc_disallow: %s", val);
4413 send_resp(dut, conn, SIGMA_INVALID,
4414 "ErrorCode,Unknown value provided for Assoc_disallow");
4415 return 0;
4416}
4417
4418
Ashwini Patilc63161e2017-04-13 16:30:23 +05304419static int mbo_set_bss_trans_req(struct sigma_dut *dut, struct sigma_conn *conn,
4420 const char *intf, const char *val)
4421{
4422 if (strcasecmp(val, "Reject") == 0) {
4423 if (wpa_command(intf, "SET reject_btm_req_reason 1") < 0) {
4424 send_resp(dut, conn, SIGMA_ERROR,
4425 "ErrorCode,Failed to Reject BTM Request");
4426 return 0;
4427 }
4428 return 1;
4429 }
4430
4431 if (strcasecmp(val, "Accept") == 0) {
4432 if (wpa_command(intf, "SET reject_btm_req_reason 0") < 0) {
4433 send_resp(dut, conn, SIGMA_ERROR,
4434 "ErrorCode,Failed to Accept BTM Request");
4435 return 0;
4436 }
4437 return 1;
4438 }
4439
4440 sigma_dut_print(dut, DUT_MSG_ERROR,
4441 "Invalid value provided for BSS_Transition: %s", val);
4442 send_resp(dut, conn, SIGMA_INVALID,
4443 "ErrorCode,Unknown value provided for BSS_Transition");
4444 return 0;
4445}
4446
4447
Ashwini Patil00402582017-04-13 12:29:39 +05304448static int mbo_set_non_pref_ch_list(struct sigma_dut *dut,
4449 struct sigma_conn *conn,
4450 const char *intf,
4451 struct sigma_cmd *cmd)
4452{
4453 const char *ch, *pref, *op_class, *reason;
4454 char buf[120];
4455 int len, ret;
4456
4457 pref = get_param(cmd, "Ch_Pref");
4458 if (!pref)
4459 return 1;
4460
4461 if (strcasecmp(pref, "clear") == 0) {
4462 free(dut->non_pref_ch_list);
4463 dut->non_pref_ch_list = NULL;
4464 } else {
4465 op_class = get_param(cmd, "Ch_Op_Class");
4466 if (!op_class) {
4467 send_resp(dut, conn, SIGMA_INVALID,
4468 "ErrorCode,Ch_Op_Class not provided");
4469 return 0;
4470 }
4471
4472 ch = get_param(cmd, "Ch_Pref_Num");
4473 if (!ch) {
4474 send_resp(dut, conn, SIGMA_INVALID,
4475 "ErrorCode,Ch_Pref_Num not provided");
4476 return 0;
4477 }
4478
4479 reason = get_param(cmd, "Ch_Reason_Code");
4480 if (!reason) {
4481 send_resp(dut, conn, SIGMA_INVALID,
4482 "ErrorCode,Ch_Reason_Code not provided");
4483 return 0;
4484 }
4485
4486 if (!dut->non_pref_ch_list) {
4487 dut->non_pref_ch_list =
4488 calloc(1, NON_PREF_CH_LIST_SIZE);
4489 if (!dut->non_pref_ch_list) {
4490 send_resp(dut, conn, SIGMA_ERROR,
4491 "ErrorCode,Failed to allocate memory for non_pref_ch_list");
4492 return 0;
4493 }
4494 }
4495 len = strlen(dut->non_pref_ch_list);
4496 ret = snprintf(dut->non_pref_ch_list + len,
4497 NON_PREF_CH_LIST_SIZE - len,
4498 " %s:%s:%s:%s", op_class, ch, pref, reason);
4499 if (ret > 0 && ret < NON_PREF_CH_LIST_SIZE - len) {
4500 sigma_dut_print(dut, DUT_MSG_DEBUG, "non_pref_list: %s",
4501 dut->non_pref_ch_list);
4502 } else {
4503 sigma_dut_print(dut, DUT_MSG_ERROR,
4504 "snprintf failed for non_pref_list, ret = %d",
4505 ret);
4506 send_resp(dut, conn, SIGMA_ERROR,
4507 "ErrorCode,snprintf failed");
4508 free(dut->non_pref_ch_list);
4509 dut->non_pref_ch_list = NULL;
4510 return 0;
4511 }
4512 }
4513
4514 ret = snprintf(buf, sizeof(buf), "SET non_pref_chan%s",
4515 dut->non_pref_ch_list ? dut->non_pref_ch_list : " ");
4516 if (ret < 0 || ret >= (int) sizeof(buf)) {
4517 sigma_dut_print(dut, DUT_MSG_DEBUG,
4518 "snprintf failed for set non_pref_chan, ret: %d",
4519 ret);
4520 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,snprint failed");
4521 return 0;
4522 }
4523
4524 if (wpa_command(intf, buf) < 0) {
4525 send_resp(dut, conn, SIGMA_ERROR,
4526 "ErrorCode,Failed to set non-preferred channel list");
4527 return 0;
4528 }
4529
4530 return 1;
4531}
4532
4533
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08004534#ifdef NL80211_SUPPORT
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08004535
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08004536static int sta_set_he_htc_supp(struct sigma_dut *dut, const char *intf,
4537 uint8_t cfg)
4538{
4539 struct nl_msg *msg;
4540 int ret = 0;
4541 struct nlattr *params;
4542 int ifindex;
4543
4544 ifindex = if_nametoindex(intf);
4545 if (ifindex == 0) {
4546 sigma_dut_print(dut, DUT_MSG_ERROR,
4547 "%s: Index for interface %s failed",
4548 __func__, intf);
4549 return -1;
4550 }
4551
4552 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4553 NL80211_CMD_VENDOR)) ||
4554 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4555 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4556 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4557 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4558 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4559 nla_put_u8(msg,
4560 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_HTC_HE_SUPP,
4561 cfg)) {
4562 sigma_dut_print(dut, DUT_MSG_ERROR,
4563 "%s: err in adding vendor_cmd and vendor_data",
4564 __func__);
4565 nlmsg_free(msg);
4566 return -1;
4567 }
4568 nla_nest_end(msg, params);
4569
4570 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4571 if (ret) {
4572 sigma_dut_print(dut, DUT_MSG_ERROR,
4573 "%s: err in send_and_recv_msgs, ret=%d",
4574 __func__, ret);
4575 }
4576 return ret;
4577}
4578
4579
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08004580static int sta_set_he_fragmentation(struct sigma_dut *dut, const char *intf,
4581 enum he_fragmentation_val frag)
4582{
4583 struct nl_msg *msg;
4584 int ret = 0;
4585 struct nlattr *params;
4586 int ifindex;
4587
4588 ifindex = if_nametoindex(intf);
4589 if (ifindex == 0) {
4590 sigma_dut_print(dut, DUT_MSG_ERROR,
4591 "%s: Index for interface %s failed",
4592 __func__, intf);
4593 return -1;
4594 }
4595
4596 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4597 NL80211_CMD_VENDOR)) ||
4598 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4599 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4600 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4601 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4602 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4603 nla_put_u8(msg,
4604 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_FRAGMENTATION,
4605 frag)) {
4606 sigma_dut_print(dut, DUT_MSG_ERROR,
4607 "%s: err in adding vendor_cmd and vendor_data",
4608 __func__);
4609 nlmsg_free(msg);
4610 return -1;
4611 }
4612 nla_nest_end(msg, params);
4613
4614 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4615 if (ret) {
4616 sigma_dut_print(dut, DUT_MSG_ERROR,
4617 "%s: err in send_and_recv_msgs, ret=%d",
4618 __func__, ret);
4619 }
4620 return ret;
4621}
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08004622
4623
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -08004624int wcn_set_he_ltf(struct sigma_dut *dut, const char *intf,
4625 enum qca_wlan_he_ltf_cfg ltf)
Subhani Shaik8e7a3052018-04-24 14:03:00 -07004626{
4627 struct nl_msg *msg;
4628 int ret = 0;
4629 struct nlattr *params;
4630 int ifindex;
4631
4632 ifindex = if_nametoindex(intf);
4633 if (ifindex == 0) {
4634 sigma_dut_print(dut, DUT_MSG_ERROR,
4635 "%s: Index for interface %s failed",
4636 __func__, intf);
4637 return -1;
4638 }
4639
4640 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4641 NL80211_CMD_VENDOR)) ||
4642 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4643 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4644 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4645 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4646 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4647 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_LTF,
4648 ltf)) {
4649 sigma_dut_print(dut, DUT_MSG_ERROR,
4650 "%s: err in adding vendor_cmd and vendor_data",
4651 __func__);
4652 nlmsg_free(msg);
4653 return -1;
4654 }
4655 nla_nest_end(msg, params);
4656
4657 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4658 if (ret) {
4659 sigma_dut_print(dut, DUT_MSG_ERROR,
4660 "%s: err in send_and_recv_msgs, ret=%d",
4661 __func__, ret);
4662 }
4663 return ret;
4664}
4665
4666
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08004667static int nlvendor_sta_set_noack(struct sigma_dut *dut, const char *intf,
4668 int noack, enum qca_wlan_ac_type ac)
4669{
4670 struct nl_msg *msg;
4671 int ret = 0;
4672 struct nlattr *params;
4673 int ifindex;
4674
4675 ifindex = if_nametoindex(intf);
4676 if (ifindex == 0) {
4677 sigma_dut_print(dut, DUT_MSG_ERROR,
4678 "%s: Index for interface %s failed",
4679 __func__, intf);
4680 return -1;
4681 }
4682
4683 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4684 NL80211_CMD_VENDOR)) ||
4685 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4686 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4687 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4688 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4689 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4690 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_NO_ACK,
4691 noack) ||
4692 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_NO_ACK_AC,
4693 ac)) {
4694 sigma_dut_print(dut, DUT_MSG_ERROR,
4695 "%s: err in adding vendor_cmd and vendor_data",
4696 __func__);
4697 nlmsg_free(msg);
4698 return -1;
4699 }
4700 nla_nest_end(msg, params);
4701
4702 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4703 if (ret) {
4704 sigma_dut_print(dut, DUT_MSG_ERROR,
4705 "%s: err in send_and_recv_msgs, ret=%d",
4706 __func__, ret);
4707 }
4708 return ret;
4709}
4710
4711
4712static void wcn_sta_set_noack(struct sigma_dut *dut, const char *intf,
4713 const char *val)
4714{
4715 int noack, ret;
4716 char token[100];
4717 char *result;
4718 char *saveptr;
4719 enum qca_wlan_ac_type ac = QCA_WLAN_AC_BE;
4720
4721 strlcpy(token, val, sizeof(token));
4722 token[sizeof(token) - 1] = '\0';
4723 result = strtok_r(token, ":", &saveptr);
4724 while (result) {
4725 noack = strcasecmp(result, "Disable") != 0;
4726 ret = nlvendor_sta_set_noack(dut, intf, noack, ac);
4727 if (ret) {
4728 sigma_dut_print(dut, DUT_MSG_ERROR,
4729 "nlvendor_sta_set_noack failed for ac:%d, ret:%d",
4730 ac, ret);
4731 }
4732 result = strtok_r(NULL, ":", &saveptr);
4733 ac++;
4734 }
4735}
4736
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08004737#endif /* NL80211_SUPPORT */
4738
4739
Jouni Malinenf7222712019-06-13 01:50:21 +03004740static enum sigma_cmd_result
4741cmd_sta_preset_testparameters(struct sigma_dut *dut, struct sigma_conn *conn,
4742 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004743{
4744 const char *intf = get_param(cmd, "Interface");
4745 const char *val;
4746
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03004747 val = get_param(cmd, "FT_DS");
4748 if (val) {
4749 if (strcasecmp(val, "Enable") == 0) {
4750 dut->sta_ft_ds = 1;
4751 } else if (strcasecmp(val, "Disable") == 0) {
4752 dut->sta_ft_ds = 0;
4753 } else {
4754 send_resp(dut, conn, SIGMA_ERROR,
4755 "errorCode,Unsupported value for FT_DS");
4756 return STATUS_SENT_ERROR;
4757 }
4758 }
4759
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004760 val = get_param(cmd, "Program");
Jouni Malinen1f6ae642018-06-07 23:56:13 +03004761 if (val && (strcasecmp(val, "HS2-R2") == 0 ||
4762 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004763 return cmd_sta_preset_testparameters_hs2_r2(dut, conn, intf,
4764 cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004765
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07004766 if (val && strcasecmp(val, "LOC") == 0)
4767 return loc_cmd_sta_preset_testparameters(dut, conn, cmd);
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02004768 if (val && strcasecmp(val, "60GHZ") == 0) {
4769 val = get_param(cmd, "WPS");
4770 if (val && strcasecmp(val, "disable") == 0) {
4771 dut->wps_disable = 1;
4772 sigma_dut_print(dut, DUT_MSG_INFO, "WPS disabled");
4773 } else {
4774 /* wps_disable can have other value from the previous
4775 * test, so make sure it has the correct value.
4776 */
4777 dut->wps_disable = 0;
4778 }
4779
4780 val = get_param(cmd, "P2P");
4781 if (val && strcasecmp(val, "disable") == 0)
4782 sigma_dut_print(dut, DUT_MSG_INFO, "P2P disabled");
4783 }
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07004784
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02004785 if (dut->program == PROGRAM_WPS && dut->band == WPS_BAND_60G)
4786 return cmd_sta_preset_testparameters_60ghz(dut, conn, cmd);
4787
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004788#ifdef ANDROID_NAN
4789 if (val && strcasecmp(val, "NAN") == 0)
4790 return nan_cmd_sta_preset_testparameters(dut, conn, cmd);
4791#endif /* ANDROID_NAN */
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07004792#ifdef MIRACAST
4793 if (val && (strcasecmp(val, "WFD") == 0 ||
4794 strcasecmp(val, "DisplayR2") == 0))
4795 return miracast_preset_testparameters(dut, conn, cmd);
4796#endif /* MIRACAST */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004797
Ashwini Patil68d02cd2017-01-10 15:39:16 +05304798 if (val && strcasecmp(val, "MBO") == 0) {
4799 val = get_param(cmd, "Cellular_Data_Cap");
4800 if (val &&
4801 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
4802 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +05304803
4804 val = get_param(cmd, "Ch_Pref");
4805 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
4806 return 0;
4807
Ashwini Patilc63161e2017-04-13 16:30:23 +05304808 val = get_param(cmd, "BSS_Transition");
4809 if (val && mbo_set_bss_trans_req(dut, conn, intf, val) == 0)
4810 return 0;
4811
Ashwini Patila75de5a2017-04-13 16:35:05 +05304812 val = get_param(cmd, "Assoc_Disallow");
4813 if (val && mbo_set_assoc_disallow(dut, conn, intf, val) == 0)
4814 return 0;
4815
Ashwini Patil9183fdb2017-04-13 16:58:25 +05304816 val = get_param(cmd, "Roaming");
4817 if (val && mbo_set_roaming(dut, conn, intf, val) == 0)
4818 return 0;
4819
Ashwini Patil68d02cd2017-01-10 15:39:16 +05304820 return 1;
4821 }
4822
Ankita Bajaja2cb5672017-10-25 16:08:28 +05304823 if (val && strcasecmp(val, "OCE") == 0)
4824 return cmd_sta_preset_testparameters_oce(dut, conn, intf, cmd);
4825
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004826#if 0
4827 val = get_param(cmd, "Supplicant");
4828 if (val && strcasecmp(val, "Default") != 0) {
4829 send_resp(dut, conn, SIGMA_ERROR,
4830 "ErrorCode,Only default(Vendor) supplicant "
4831 "supported");
4832 return 0;
4833 }
4834#endif
4835
4836 val = get_param(cmd, "RTS");
4837 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004838 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004839 case DRIVER_ATHEROS:
4840 ath_sta_set_rts(dut, intf, val);
4841 break;
4842 default:
4843#if 0
4844 send_resp(dut, conn, SIGMA_ERROR,
4845 "ErrorCode,Setting RTS not supported");
4846 return 0;
4847#else
4848 sigma_dut_print(dut, DUT_MSG_DEBUG,
4849 "Setting RTS not supported");
4850 break;
4851#endif
4852 }
4853 }
4854
4855#if 0
4856 val = get_param(cmd, "FRGMNT");
4857 if (val) {
4858 /* TODO */
4859 send_resp(dut, conn, SIGMA_ERROR,
4860 "ErrorCode,Setting FRGMNT not supported");
4861 return 0;
4862 }
4863#endif
4864
4865#if 0
4866 val = get_param(cmd, "Preamble");
4867 if (val) {
4868 /* TODO: Long/Short */
4869 send_resp(dut, conn, SIGMA_ERROR,
4870 "ErrorCode,Setting Preamble not supported");
4871 return 0;
4872 }
4873#endif
4874
4875 val = get_param(cmd, "Mode");
4876 if (val) {
4877 if (strcmp(val, "11b") == 0 ||
4878 strcmp(val, "11g") == 0 ||
4879 strcmp(val, "11a") == 0 ||
4880 strcmp(val, "11n") == 0 ||
4881 strcmp(val, "11ng") == 0 ||
4882 strcmp(val, "11nl") == 0 ||
4883 strcmp(val, "11nl(nabg)") == 0 ||
4884 strcmp(val, "AC") == 0 ||
4885 strcmp(val, "11AC") == 0 ||
4886 strcmp(val, "11ac") == 0 ||
4887 strcmp(val, "11na") == 0 ||
Amarnath Hullur Subramanyamb0db2712018-01-30 19:40:35 -08004888 strcmp(val, "11an") == 0 ||
4889 strcmp(val, "11ax") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004890 /* STA supports all modes by default */
4891 } else {
4892 send_resp(dut, conn, SIGMA_ERROR,
4893 "ErrorCode,Setting Mode not supported");
4894 return 0;
4895 }
Amarnath Hullur Subramanyam97d0e532018-01-31 02:53:02 -08004896
4897 /* Change the mode only in case of testbed for HE program
4898 * and for 11a and 11g modes only. */
4899 if (dut->program == PROGRAM_HE &&
4900 dut->device_type == STA_testbed) {
4901 int phymode;
4902 char buf[60];
4903
4904 if (strcmp(val, "11a") == 0) {
Amarnath Hullur Subramanyam94dfaf02018-03-02 19:26:57 -08004905 phymode = 1; /* IEEE80211_MODE_11A */
4906 } else if (strcmp(val, "11g") == 0) {
4907 phymode = 3; /* IEEE80211_MODE_11G */
4908 } else if (strcmp(val, "11b") == 0) {
4909 phymode = 2; /* IEEE80211_MODE_11B */
4910 } else if (strcmp(val, "11n") == 0 ||
4911 strcmp(val, "11nl") == 0 ||
4912 strcmp(val, "11nl(nabg)") == 0) {
4913 phymode = 22; /* IEEE80211_MODE_11AGN */
4914 } else if (strcmp(val, "11ng") == 0) {
4915 phymode = 13; /* IEEE80211_MODE_11NG_HT40 */
4916 } else if (strcmp(val, "AC") == 0 ||
4917 strcasecmp(val, "11AC") == 0) {
4918 phymode = 19; /* IEEE80211_MODE_11AC_VHT80 */
4919 } else if (strcmp(val, "11na") == 0 ||
4920 strcasecmp(val, "11an") == 0) {
4921 phymode = 14; /* IEEE80211_MODE_11NA_HT40 */
4922 } else if (strcmp(val, "11ax") == 0) {
4923 phymode = 0; /* IEEE80211_MODE_AUTO */
Amarnath Hullur Subramanyam97d0e532018-01-31 02:53:02 -08004924 } else {
4925 sigma_dut_print(dut, DUT_MSG_DEBUG,
4926 "Ignoring mode change for mode: %s",
4927 val);
4928 phymode = -1;
4929 }
4930 if (phymode != -1) {
4931 snprintf(buf, sizeof(buf),
4932 "iwpriv %s setphymode %d",
4933 intf, phymode);
4934 if (system(buf) != 0) {
4935 sigma_dut_print(dut, DUT_MSG_ERROR,
4936 "iwpriv setting of phymode failed");
4937 }
4938 }
4939 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004940 }
4941
4942 val = get_param(cmd, "wmm");
4943 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004944 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004945 case DRIVER_ATHEROS:
4946 ath_sta_set_wmm(dut, intf, val);
4947 break;
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08004948 case DRIVER_WCN:
4949 wcn_sta_set_wmm(dut, intf, val);
4950 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004951 default:
4952 sigma_dut_print(dut, DUT_MSG_DEBUG,
4953 "Setting wmm not supported");
4954 break;
4955 }
4956 }
4957
4958 val = get_param(cmd, "Powersave");
4959 if (val) {
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08004960 char buf[60];
4961
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004962 if (strcmp(val, "0") == 0 || strcasecmp(val, "off") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004963 if (get_driver_type(dut) == DRIVER_WCN) {
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08004964 snprintf(buf, sizeof(buf),
4965 "iwpriv %s setPower 2", intf);
4966 if (system(buf) != 0) {
4967 sigma_dut_print(dut, DUT_MSG_ERROR,
4968 "iwpriv setPower 2 failed");
4969 return 0;
4970 }
4971 }
4972
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004973 if (wpa_command(get_station_ifname(dut),
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004974 "P2P_SET ps 0") < 0)
4975 return -2;
4976 /* Make sure test modes are disabled */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004977 wpa_command(get_station_ifname(dut), "P2P_SET ps 98");
4978 wpa_command(get_station_ifname(dut), "P2P_SET ps 96");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004979 } else if (strcmp(val, "1") == 0 ||
4980 strcasecmp(val, "PSPoll") == 0 ||
4981 strcasecmp(val, "on") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004982 if (get_driver_type(dut) == DRIVER_WCN) {
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08004983 snprintf(buf, sizeof(buf),
4984 "iwpriv %s setPower 1", intf);
4985 if (system(buf) != 0) {
4986 sigma_dut_print(dut, DUT_MSG_ERROR,
4987 "iwpriv setPower 1 failed");
4988 return 0;
4989 }
4990 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004991 /* Disable default power save mode */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004992 wpa_command(get_station_ifname(dut), "P2P_SET ps 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004993 /* Enable PS-Poll test mode */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004994 if (wpa_command(get_station_ifname(dut),
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004995 "P2P_SET ps 97") < 0 ||
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004996 wpa_command(get_station_ifname(dut),
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004997 "P2P_SET ps 99") < 0)
4998 return -2;
4999 } else if (strcmp(val, "2") == 0 ||
5000 strcasecmp(val, "Fast") == 0) {
5001 /* TODO */
5002 send_resp(dut, conn, SIGMA_ERROR,
5003 "ErrorCode,Powersave=Fast not supported");
5004 return 0;
5005 } else if (strcmp(val, "3") == 0 ||
5006 strcasecmp(val, "PSNonPoll") == 0) {
5007 /* Make sure test modes are disabled */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005008 wpa_command(get_station_ifname(dut), "P2P_SET ps 98");
5009 wpa_command(get_station_ifname(dut), "P2P_SET ps 96");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005010
5011 /* Enable default power save mode */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005012 if (wpa_command(get_station_ifname(dut),
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005013 "P2P_SET ps 1") < 0)
5014 return -2;
5015 } else
5016 return -1;
5017 }
5018
5019 val = get_param(cmd, "NoAck");
5020 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005021 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005022 case DRIVER_ATHEROS:
5023 ath_sta_set_noack(dut, intf, val);
5024 break;
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08005025#ifdef NL80211_SUPPORT
5026 case DRIVER_WCN:
5027 wcn_sta_set_noack(dut, intf, val);
5028 break;
5029#endif /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005030 default:
5031 send_resp(dut, conn, SIGMA_ERROR,
5032 "ErrorCode,Setting NoAck not supported");
5033 return 0;
5034 }
5035 }
5036
5037 val = get_param(cmd, "IgnoreChswitchProhibit");
5038 if (val) {
5039 /* TODO: Enabled/disabled */
5040 if (strcasecmp(val, "Enabled") == 0) {
5041 send_resp(dut, conn, SIGMA_ERROR,
5042 "ErrorCode,Enabling IgnoreChswitchProhibit "
5043 "not supported");
5044 return 0;
5045 }
5046 }
5047
5048 val = get_param(cmd, "TDLS");
5049 if (val) {
5050 if (strcasecmp(val, "Disabled") == 0) {
5051 if (wpa_command(intf, "SET tdls_disabled 1")) {
5052 send_resp(dut, conn, SIGMA_ERROR,
5053 "ErrorCode,Failed to disable TDLS");
5054 return 0;
5055 }
5056 } else if (strcasecmp(val, "Enabled") == 0) {
5057 if (wpa_command(intf, "SET tdls_disabled 0")) {
5058 send_resp(dut, conn, SIGMA_ERROR,
5059 "ErrorCode,Failed to enable TDLS");
5060 return 0;
5061 }
5062 } else {
5063 send_resp(dut, conn, SIGMA_ERROR,
5064 "ErrorCode,Unsupported TDLS value");
5065 return 0;
5066 }
5067 }
5068
5069 val = get_param(cmd, "TDLSmode");
5070 if (val) {
5071 if (strcasecmp(val, "Default") == 0) {
5072 wpa_command(intf, "SET tdls_testing 0");
5073 } else if (strcasecmp(val, "APProhibit") == 0) {
5074 if (wpa_command(intf, "SET tdls_testing 0x400")) {
5075 send_resp(dut, conn, SIGMA_ERROR,
5076 "ErrorCode,Failed to enable ignore "
5077 "APProhibit TDLS mode");
5078 return 0;
5079 }
5080 } else if (strcasecmp(val, "HiLoMac") == 0) {
5081 /* STA should respond with TDLS setup req for a TDLS
5082 * setup req */
5083 if (wpa_command(intf, "SET tdls_testing 0x80")) {
5084 send_resp(dut, conn, SIGMA_ERROR,
5085 "ErrorCode,Failed to enable HiLoMac "
5086 "TDLS mode");
5087 return 0;
5088 }
5089 } else if (strcasecmp(val, "WeakSecurity") == 0) {
5090 /*
5091 * Since all security modes are enabled by default when
5092 * Sigma control is used, there is no need to do
5093 * anything here.
5094 */
5095 } else if (strcasecmp(val, "ExistLink") == 0) {
5096 /*
5097 * Since we allow new TDLS Setup Request even if there
5098 * is an existing link, nothing needs to be done for
5099 * this.
5100 */
5101 } else {
5102 /* TODO:
5103 * ExistLink: STA should send TDLS setup req even if
5104 * direct link already exists
5105 */
5106 send_resp(dut, conn, SIGMA_ERROR,
5107 "ErrorCode,Unsupported TDLSmode value");
5108 return 0;
5109 }
5110 }
5111
5112 val = get_param(cmd, "FakePubKey");
5113 if (val && atoi(val) && wpa_command(intf, "SET wps_corrupt_pkhash 1")) {
5114 send_resp(dut, conn, SIGMA_ERROR,
5115 "ErrorCode,Failed to enable FakePubKey");
5116 return 0;
5117 }
5118
Amarnath Hullur Subramanyamae1042b2018-02-22 21:52:52 -08005119#ifdef NL80211_SUPPORT
5120 val = get_param(cmd, "FrgmntSupport");
5121 if (val) {
5122 if (strcasecmp(val, "Enable") == 0) {
5123 if (sta_set_he_fragmentation(dut, intf,
5124 HE_FRAG_LEVEL1)) {
5125 send_resp(dut, conn, SIGMA_ERROR,
5126 "ErrorCode,Failed to enable HE Fragmentation");
5127 return 0;
5128 }
5129 } else if (strcasecmp(val, "Disable") == 0) {
5130 if (sta_set_he_fragmentation(dut, intf,
5131 HE_FRAG_DISABLE)) {
5132 send_resp(dut, conn, SIGMA_ERROR,
5133 "ErrorCode,Failed to disable HE Fragmentation");
5134 return 0;
5135 }
5136 }
5137 }
5138#endif /* NL80211_SUPPORT */
5139
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005140 return 1;
5141}
5142
5143
5144static const char * ath_get_radio_name(const char *radio_name)
5145{
5146 if (radio_name == NULL)
5147 return "wifi0";
5148 if (strcmp(radio_name, "wifi1") == 0)
5149 return "wifi1";
5150 if (strcmp(radio_name, "wifi2") == 0)
5151 return "wifi2";
5152 return "wifi0";
5153}
5154
5155
5156static void ath_sta_set_txsp_stream(struct sigma_dut *dut, const char *intf,
5157 const char *val)
5158{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005159 unsigned int vht_mcsmap = 0;
5160 int txchainmask = 0;
5161 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
5162
5163 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
5164 if (dut->testbed_flag_txsp == 1) {
5165 vht_mcsmap = 0xfffc;
5166 dut->testbed_flag_txsp = 0;
5167 } else {
5168 vht_mcsmap = 0xfffe;
5169 }
5170 txchainmask = 1;
5171 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
5172 if (dut->testbed_flag_txsp == 1) {
5173 vht_mcsmap = 0xfff0;
5174 dut->testbed_flag_txsp = 0;
5175 } else {
5176 vht_mcsmap = 0xfffa;
5177 }
5178 txchainmask = 3;
5179 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
5180 if (dut->testbed_flag_txsp == 1) {
5181 vht_mcsmap = 0xffc0;
5182 dut->testbed_flag_txsp = 0;
5183 } else {
5184 vht_mcsmap = 0xffea;
5185 }
5186 txchainmask = 7;
5187 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
5188 if (dut->testbed_flag_txsp == 1) {
5189 vht_mcsmap = 0xff00;
5190 dut->testbed_flag_txsp = 0;
5191 } else {
5192 vht_mcsmap = 0xffaa;
5193 }
5194 txchainmask = 15;
5195 } else {
5196 if (dut->testbed_flag_txsp == 1) {
5197 vht_mcsmap = 0xffc0;
5198 dut->testbed_flag_txsp = 0;
5199 } else {
5200 vht_mcsmap = 0xffea;
5201 }
5202 }
5203
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005204 if (txchainmask)
5205 run_iwpriv(dut, basedev, "txchainmask %d", txchainmask);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005206
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005207 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005208}
5209
5210
5211static void ath_sta_set_rxsp_stream(struct sigma_dut *dut, const char *intf,
5212 const char *val)
5213{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005214 unsigned int vht_mcsmap = 0;
5215 int rxchainmask = 0;
5216 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
5217
5218 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
5219 if (dut->testbed_flag_rxsp == 1) {
5220 vht_mcsmap = 0xfffc;
5221 dut->testbed_flag_rxsp = 0;
5222 } else {
5223 vht_mcsmap = 0xfffe;
5224 }
5225 rxchainmask = 1;
5226 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
5227 if (dut->testbed_flag_rxsp == 1) {
5228 vht_mcsmap = 0xfff0;
5229 dut->testbed_flag_rxsp = 0;
5230 } else {
5231 vht_mcsmap = 0xfffa;
5232 }
5233 rxchainmask = 3;
5234 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
5235 if (dut->testbed_flag_rxsp == 1) {
5236 vht_mcsmap = 0xffc0;
5237 dut->testbed_flag_rxsp = 0;
5238 } else {
5239 vht_mcsmap = 0xffea;
5240 }
5241 rxchainmask = 7;
5242 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
5243 if (dut->testbed_flag_rxsp == 1) {
5244 vht_mcsmap = 0xff00;
5245 dut->testbed_flag_rxsp = 0;
5246 } else {
5247 vht_mcsmap = 0xffaa;
5248 }
5249 rxchainmask = 15;
5250 } else {
5251 if (dut->testbed_flag_rxsp == 1) {
5252 vht_mcsmap = 0xffc0;
5253 dut->testbed_flag_rxsp = 0;
5254 } else {
5255 vht_mcsmap = 0xffea;
5256 }
5257 }
5258
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005259 if (rxchainmask)
5260 run_iwpriv(dut, basedev, "rxchainmask %d", rxchainmask);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005261
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005262 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005263}
5264
5265
5266void ath_set_zero_crc(struct sigma_dut *dut, const char *val)
5267{
5268 if (strcasecmp(val, "enable") == 0) {
5269 if (system("athdiag --set --address=0x2a204 --and=0xbfffffff")
5270 != 0) {
5271 sigma_dut_print(dut, DUT_MSG_ERROR,
5272 "Disable BB_VHTSIGB_CRC_CALC failed");
5273 }
5274
5275 if (system("athdiag --set --address=0x2a204 --or=0x80000000")
5276 != 0) {
5277 sigma_dut_print(dut, DUT_MSG_ERROR,
5278 "Enable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
5279 }
5280 } else {
5281 if (system("athdiag --set --address=0x2a204 --and=0x7fffffff")
5282 != 0) {
5283 sigma_dut_print(dut, DUT_MSG_ERROR,
5284 "Disable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
5285 }
5286
5287 if (system("athdiag --set --address=0x2a204 --or=0x40000000")
5288 != 0) {
5289 sigma_dut_print(dut, DUT_MSG_ERROR,
5290 "Enable BB_VHTSIGB_CRC_CALC failed");
5291 }
5292 }
5293}
5294
5295
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08005296static int wcn_sta_set_width(struct sigma_dut *dut, const char *intf,
5297 const char *val)
5298{
5299 char buf[60];
5300
5301 if (strcmp(val, "20") == 0) {
5302 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 0", intf);
5303 dut->chwidth = 0;
5304 } else if (strcmp(val, "40") == 0) {
5305 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 1", intf);
5306 dut->chwidth = 1;
5307 } else if (strcmp(val, "80") == 0) {
5308 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 2", intf);
5309 dut->chwidth = 2;
Sunil Duttb1cccac2018-05-22 21:03:12 +05305310 } else if (strcasecmp(val, "Auto") == 0) {
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08005311 buf[0] = '\0';
5312 } else {
5313 sigma_dut_print(dut, DUT_MSG_ERROR, "WIDTH %s not supported",
5314 val);
5315 return -1;
5316 }
5317
5318 if (buf[0] != '\0' && system(buf) != 0) {
5319 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv chwidth failed");
5320 return -1;
5321 }
5322
5323 return 0;
5324}
5325
5326
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005327static int nlvendor_sta_set_addba_reject(struct sigma_dut *dut,
5328 const char *intf, int addbareject)
5329{
5330#ifdef NL80211_SUPPORT
5331 struct nl_msg *msg;
5332 int ret = 0;
5333 struct nlattr *params;
5334 int ifindex;
5335
5336 ifindex = if_nametoindex(intf);
5337 if (ifindex == 0) {
5338 sigma_dut_print(dut, DUT_MSG_ERROR,
5339 "%s: Index for interface %s failed",
5340 __func__, intf);
5341 return -1;
5342 }
5343
5344 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
5345 NL80211_CMD_VENDOR)) ||
5346 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
5347 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
5348 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
5349 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
5350 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
5351 nla_put_u8(msg,
5352 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ACCEPT_ADDBA_REQ,
5353 !addbareject)) {
5354 sigma_dut_print(dut, DUT_MSG_ERROR,
5355 "%s: err in adding vendor_cmd and vendor_data",
5356 __func__);
5357 nlmsg_free(msg);
5358 return -1;
5359 }
5360 nla_nest_end(msg, params);
5361
5362 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5363 if (ret) {
5364 sigma_dut_print(dut, DUT_MSG_ERROR,
5365 "%s: err in send_and_recv_msgs, ret=%d",
5366 __func__, ret);
5367 }
5368 return ret;
5369#else /* NL80211_SUPPORT */
5370 sigma_dut_print(dut, DUT_MSG_ERROR,
5371 "ADDBA_REJECT cannot be set without NL80211_SUPPORT defined");
5372 return -1;
5373#endif /* NL80211_SUPPORT */
5374}
5375
5376
5377static int sta_set_addba_reject(struct sigma_dut *dut, const char *intf,
5378 int addbareject)
5379{
5380 int ret;
5381
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005382 switch (get_driver_type(dut)) {
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005383 case DRIVER_WCN:
5384 ret = nlvendor_sta_set_addba_reject(dut, intf, addbareject);
5385 if (ret) {
5386 sigma_dut_print(dut, DUT_MSG_ERROR,
5387 "nlvendor_sta_set_addba_reject failed, ret:%d",
5388 ret);
5389 return ret;
5390 }
5391 break;
5392 default:
5393 sigma_dut_print(dut, DUT_MSG_ERROR,
5394 "errorCode,Unsupported ADDBA_REJECT with the current driver");
5395 ret = -1;
5396 break;
5397 }
5398
5399 return ret;
5400}
5401
5402
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08005403static int nlvendor_config_send_addba(struct sigma_dut *dut, const char *intf,
5404 int enable)
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005405{
5406#ifdef NL80211_SUPPORT
5407 struct nl_msg *msg;
5408 int ret = 0;
5409 struct nlattr *params;
5410 int ifindex;
5411
5412 ifindex = if_nametoindex(intf);
5413 if (ifindex == 0) {
5414 sigma_dut_print(dut, DUT_MSG_ERROR,
5415 "%s: Index for interface %s failed",
5416 __func__, intf);
5417 return -1;
5418 }
5419
5420 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
5421 NL80211_CMD_VENDOR)) ||
5422 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
5423 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
5424 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
5425 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
5426 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
5427 nla_put_u8(msg,
5428 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_SEND_ADDBA_REQ,
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08005429 enable)) {
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005430 sigma_dut_print(dut, DUT_MSG_ERROR,
5431 "%s: err in adding vendor_cmd and vendor_data",
5432 __func__);
5433 nlmsg_free(msg);
5434 return -1;
5435 }
5436 nla_nest_end(msg, params);
5437
5438 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5439 if (ret) {
5440 sigma_dut_print(dut, DUT_MSG_ERROR,
5441 "%s: err in send_and_recv_msgs, ret=%d",
5442 __func__, ret);
5443 }
5444 return ret;
5445#else /* NL80211_SUPPORT */
5446 sigma_dut_print(dut, DUT_MSG_ERROR,
5447 "Disable addba not possible without NL80211_SUPPORT defined");
5448 return -1;
5449#endif /* NL80211_SUPPORT */
5450}
5451
5452
Veerendranath Jakkamadcd6202019-04-17 12:32:21 +05305453#ifdef NL80211_SUPPORT
5454static int nl80211_sta_set_rts(struct sigma_dut *dut, const char *intf, int val)
5455{
5456 struct nl_msg *msg;
5457 int ret = 0;
5458 int ifindex;
5459
5460 ifindex = if_nametoindex(intf);
5461 if (ifindex == 0) {
5462 sigma_dut_print(dut, DUT_MSG_ERROR,
5463 "%s: Index for interface %s failed",
5464 __func__, intf);
5465 return -1;
5466 }
5467
5468 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
5469 NL80211_CMD_SET_WIPHY)) ||
5470 nla_put_u32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD, val)) {
5471 sigma_dut_print(dut, DUT_MSG_ERROR,
5472 "%s: err in adding RTS threshold",
5473 __func__);
5474 nlmsg_free(msg);
5475 return -1;
5476 }
5477
5478 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5479 if (ret) {
5480 sigma_dut_print(dut, DUT_MSG_ERROR,
5481 "%s: err in send_and_recv_msgs, ret=%d",
5482 __func__, ret);
5483 }
5484 return ret;
5485}
5486#endif /* NL80211_SUPPORT */
5487
5488
5489static int sta_set_rts(struct sigma_dut *dut, const char *intf, int val)
5490{
5491 char buf[100];
5492
5493#ifdef NL80211_SUPPORT
5494 if (nl80211_sta_set_rts(dut, intf, val) == 0)
5495 return 0;
5496 sigma_dut_print(dut, DUT_MSG_DEBUG,
5497 "Fall back to using iwconfig for setting RTS threshold");
5498#endif /* NL80211_SUPPORT */
5499
5500 snprintf(buf, sizeof(buf), "iwconfig %s rts %d", intf, val);
5501 if (system(buf) != 0) {
5502 sigma_dut_print(dut, DUT_MSG_ERROR,
5503 "Failed to set RTS threshold %d", val);
5504 return -1;
5505 }
5506 return 0;
5507}
5508
5509
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005510static int cmd_sta_set_wireless_common(const char *intf, struct sigma_dut *dut,
5511 struct sigma_conn *conn,
5512 struct sigma_cmd *cmd)
5513{
5514 const char *val;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005515 int ampdu = -1, addbareject = -1;
Jouni Malinen3aa72862019-05-29 23:14:51 +03005516 char buf[128];
5517 int res;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005518
5519 val = get_param(cmd, "40_INTOLERANT");
5520 if (val) {
5521 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
5522 /* TODO: iwpriv ht40intol through wpa_supplicant */
5523 send_resp(dut, conn, SIGMA_ERROR,
5524 "ErrorCode,40_INTOLERANT not supported");
5525 return 0;
5526 }
5527 }
5528
5529 val = get_param(cmd, "ADDBA_REJECT");
5530 if (val) {
5531 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
5532 /* reject any ADDBA with status "decline" */
5533 ampdu = 0;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005534 addbareject = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005535 } else {
5536 /* accept ADDBA */
5537 ampdu = 1;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005538 addbareject = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005539 }
5540 }
5541
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005542 if (addbareject >= 0 &&
5543 sta_set_addba_reject(dut, intf, addbareject) < 0) {
5544 send_resp(dut, conn, SIGMA_ERROR,
5545 "ErrorCode,set addba_reject failed");
5546 return 0;
5547 }
5548
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005549 val = get_param(cmd, "AMPDU");
5550 if (val) {
5551 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
5552 /* enable AMPDU Aggregation */
5553 if (ampdu == 0) {
5554 send_resp(dut, conn, SIGMA_ERROR,
5555 "ErrorCode,Mismatch in "
5556 "addba_reject/ampdu - "
5557 "not supported");
5558 return 0;
5559 }
5560 ampdu = 1;
5561 } else {
5562 /* disable AMPDU Aggregation */
5563 if (ampdu == 1) {
5564 send_resp(dut, conn, SIGMA_ERROR,
5565 "ErrorCode,Mismatch in "
5566 "addba_reject/ampdu - "
5567 "not supported");
5568 return 0;
5569 }
5570 ampdu = 0;
5571 }
5572 }
5573
5574 if (ampdu >= 0) {
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005575 int ret;
5576
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005577 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s A-MPDU aggregation",
5578 ampdu ? "Enabling" : "Disabling");
5579 snprintf(buf, sizeof(buf), "SET ampdu %d", ampdu);
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07005580 if (wpa_command(intf, buf) < 0 &&
5581 iwpriv_sta_set_ampdu(dut, intf, ampdu) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005582 send_resp(dut, conn, SIGMA_ERROR,
5583 "ErrorCode,set aggr failed");
5584 return 0;
5585 }
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005586
5587 if (ampdu == 0) {
5588 /* Disable sending of addba using nl vendor command */
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08005589 ret = nlvendor_config_send_addba(dut, intf, 0);
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005590 if (ret) {
5591 sigma_dut_print(dut, DUT_MSG_ERROR,
5592 "Failed to disable addba, ret:%d",
5593 ret);
5594 }
5595 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005596 }
5597
5598 val = get_param(cmd, "AMSDU");
5599 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005600 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005601 case DRIVER_ATHEROS:
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08005602 case DRIVER_WCN:
5603 iwpriv_sta_set_amsdu(dut, intf, val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005604 break;
5605 default:
5606 if (strcmp(val, "1") == 0 ||
5607 strcasecmp(val, "Enable") == 0) {
5608 /* Enable AMSDU Aggregation */
5609 send_resp(dut, conn, SIGMA_ERROR,
5610 "ErrorCode,AMSDU aggregation not supported");
5611 return 0;
5612 }
5613 break;
5614 }
5615 }
5616
5617 val = get_param(cmd, "STBC_RX");
5618 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005619 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005620 case DRIVER_ATHEROS:
5621 ath_sta_set_stbc(dut, intf, val);
5622 break;
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05305623 case DRIVER_WCN:
5624 wcn_sta_set_stbc(dut, intf, val);
5625 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005626 default:
5627 send_resp(dut, conn, SIGMA_ERROR,
5628 "ErrorCode,STBC_RX not supported");
5629 return 0;
5630 }
5631 }
5632
5633 val = get_param(cmd, "WIDTH");
5634 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005635 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005636 case DRIVER_WCN:
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08005637 if (wcn_sta_set_width(dut, intf, val) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005638 send_resp(dut, conn, SIGMA_ERROR,
5639 "ErrorCode,Failed to set WIDTH");
5640 return 0;
5641 }
5642 break;
5643 case DRIVER_ATHEROS:
5644 if (ath_set_width(dut, conn, intf, val) < 0)
5645 return 0;
5646 break;
5647 default:
5648 sigma_dut_print(dut, DUT_MSG_ERROR,
5649 "Setting WIDTH not supported");
5650 break;
5651 }
5652 }
5653
5654 val = get_param(cmd, "SMPS");
5655 if (val) {
5656 /* TODO: Dynamic/0, Static/1, No Limit/2 */
5657 send_resp(dut, conn, SIGMA_ERROR,
5658 "ErrorCode,SMPS not supported");
5659 return 0;
5660 }
5661
5662 val = get_param(cmd, "TXSP_STREAM");
5663 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005664 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005665 case DRIVER_WCN:
5666 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
5667 send_resp(dut, conn, SIGMA_ERROR,
5668 "ErrorCode,Failed to set TXSP_STREAM");
5669 return 0;
5670 }
5671 break;
5672 case DRIVER_ATHEROS:
5673 ath_sta_set_txsp_stream(dut, intf, val);
5674 break;
5675 default:
5676 sigma_dut_print(dut, DUT_MSG_ERROR,
5677 "Setting TXSP_STREAM not supported");
5678 break;
5679 }
5680 }
5681
5682 val = get_param(cmd, "RXSP_STREAM");
5683 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005684 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005685 case DRIVER_WCN:
5686 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
5687 send_resp(dut, conn, SIGMA_ERROR,
5688 "ErrorCode,Failed to set RXSP_STREAM");
5689 return 0;
5690 }
5691 break;
5692 case DRIVER_ATHEROS:
5693 ath_sta_set_rxsp_stream(dut, intf, val);
5694 break;
5695 default:
5696 sigma_dut_print(dut, DUT_MSG_ERROR,
5697 "Setting RXSP_STREAM not supported");
5698 break;
5699 }
5700 }
5701
5702 val = get_param(cmd, "DYN_BW_SGNL");
5703 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005704 switch (get_driver_type(dut)) {
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08005705 case DRIVER_WCN:
Peng Xuc59afd32016-11-21 15:01:11 -08005706 if (strcasecmp(val, "enable") == 0) {
5707 snprintf(buf, sizeof(buf),
5708 "iwpriv %s cwmenable 1", intf);
5709 if (system(buf) != 0) {
5710 sigma_dut_print(dut, DUT_MSG_ERROR,
5711 "iwpriv cwmenable 1 failed");
5712 return 0;
5713 }
5714 } else if (strcasecmp(val, "disable") == 0) {
5715 snprintf(buf, sizeof(buf),
5716 "iwpriv %s cwmenable 0", intf);
5717 if (system(buf) != 0) {
5718 sigma_dut_print(dut, DUT_MSG_ERROR,
5719 "iwpriv cwmenable 0 failed");
5720 return 0;
5721 }
5722 } else {
5723 sigma_dut_print(dut, DUT_MSG_ERROR,
5724 "Unsupported DYN_BW_SGL");
5725 }
5726
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005727 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 3", intf);
5728 if (system(buf) != 0) {
5729 sigma_dut_print(dut, DUT_MSG_ERROR,
5730 "Failed to set cts_cbw in DYN_BW_SGNL");
5731 return 0;
5732 }
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08005733 break;
5734 case DRIVER_ATHEROS:
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -07005735 novap_reset(dut, intf, 1);
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08005736 ath_config_dyn_bw_sig(dut, intf, val);
5737 break;
5738 default:
5739 sigma_dut_print(dut, DUT_MSG_ERROR,
5740 "Failed to set DYN_BW_SGNL");
5741 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005742 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005743 }
5744
5745 val = get_param(cmd, "RTS_FORCE");
5746 if (val) {
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -07005747 novap_reset(dut, intf, 1);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005748 if (strcasecmp(val, "Enable") == 0) {
Veerendranath Jakkamadcd6202019-04-17 12:32:21 +05305749 if (sta_set_rts(dut, intf, 64) != 0) {
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02005750 sigma_dut_print(dut, DUT_MSG_ERROR,
5751 "Failed to set RTS_FORCE 64");
5752 }
Jouni Malinen3aa72862019-05-29 23:14:51 +03005753 res = snprintf(buf, sizeof(buf),
5754 "wifitool %s beeliner_fw_test 100 1",
5755 intf);
5756 if (res < 0 || res >= sizeof(buf) || system(buf) != 0) {
priyadharshini gowthaman270870e2015-12-09 10:10:23 -08005757 sigma_dut_print(dut, DUT_MSG_ERROR,
5758 "wifitool beeliner_fw_test 100 1 failed");
5759 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005760 } else if (strcasecmp(val, "Disable") == 0) {
Veerendranath Jakkamadcd6202019-04-17 12:32:21 +05305761 if (sta_set_rts(dut, intf, 2347) != 0) {
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02005762 sigma_dut_print(dut, DUT_MSG_ERROR,
5763 "Failed to set RTS_FORCE 2347");
5764 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005765 } else {
5766 send_resp(dut, conn, SIGMA_ERROR,
5767 "ErrorCode,RTS_FORCE value not supported");
5768 return 0;
5769 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005770 }
5771
5772 val = get_param(cmd, "CTS_WIDTH");
5773 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005774 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005775 case DRIVER_WCN:
5776 if (wcn_sta_set_cts_width(dut, intf, val) < 0) {
5777 send_resp(dut, conn, SIGMA_ERROR,
5778 "ErrorCode,Failed to set CTS_WIDTH");
5779 return 0;
5780 }
5781 break;
5782 case DRIVER_ATHEROS:
5783 ath_set_cts_width(dut, intf, val);
5784 break;
5785 default:
5786 sigma_dut_print(dut, DUT_MSG_ERROR,
5787 "Setting CTS_WIDTH not supported");
5788 break;
5789 }
5790 }
5791
5792 val = get_param(cmd, "BW_SGNL");
5793 if (val) {
5794 if (strcasecmp(val, "Enable") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005795 run_iwpriv(dut, intf, "cwmenable 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005796 } else if (strcasecmp(val, "Disable") == 0) {
5797 /* TODO: Disable */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005798 } else {
5799 send_resp(dut, conn, SIGMA_ERROR,
5800 "ErrorCode,BW_SGNL value not supported");
5801 return 0;
5802 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005803 }
5804
5805 val = get_param(cmd, "Band");
5806 if (val) {
5807 if (strcmp(val, "2.4") == 0 || strcmp(val, "5") == 0) {
5808 /* STA supports all bands by default */
5809 } else {
5810 send_resp(dut, conn, SIGMA_ERROR,
5811 "ErrorCode,Unsupported Band");
5812 return 0;
5813 }
5814 }
5815
5816 val = get_param(cmd, "zero_crc");
5817 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005818 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005819 case DRIVER_ATHEROS:
5820 ath_set_zero_crc(dut, val);
5821 break;
5822 default:
5823 break;
5824 }
5825 }
5826
5827 return 1;
5828}
5829
5830
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02005831static int sta_set_force_mcs(struct sigma_dut *dut, int force, int mcs)
5832{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005833 switch (get_driver_type(dut)) {
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02005834#ifdef __linux__
5835 case DRIVER_WIL6210:
5836 return wil6210_set_force_mcs(dut, force, mcs);
5837#endif /* __linux__ */
5838 default:
5839 sigma_dut_print(dut, DUT_MSG_ERROR,
5840 "Unsupported sta_set_force_mcs with the current driver");
5841 return -1;
5842 }
5843}
5844
5845
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02005846static int sta_60g_force_rsn_ie(struct sigma_dut *dut, int state)
5847{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005848 switch (get_driver_type(dut)) {
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02005849#ifdef __linux__
5850 case DRIVER_WIL6210:
5851 return wil6210_force_rsn_ie(dut, state);
5852#endif /* __linux__ */
5853 default:
5854 sigma_dut_print(dut, DUT_MSG_ERROR,
5855 "Unsupported sta_60g_force_rsn_ie with the current driver");
5856 return -1;
5857 }
5858}
5859
5860
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005861static int sta_set_60g_common(struct sigma_dut *dut, struct sigma_conn *conn,
5862 struct sigma_cmd *cmd)
5863{
5864 const char *val;
5865 char buf[100];
5866
5867 val = get_param(cmd, "MSDUSize");
5868 if (val) {
5869 int mtu;
5870
5871 dut->amsdu_size = atoi(val);
5872 if (dut->amsdu_size > IEEE80211_MAX_DATA_LEN_DMG ||
5873 dut->amsdu_size < IEEE80211_SNAP_LEN_DMG) {
5874 sigma_dut_print(dut, DUT_MSG_ERROR,
5875 "MSDUSize %d is above max %d or below min %d",
5876 dut->amsdu_size,
5877 IEEE80211_MAX_DATA_LEN_DMG,
5878 IEEE80211_SNAP_LEN_DMG);
5879 dut->amsdu_size = 0;
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005880 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005881 }
5882
5883 mtu = dut->amsdu_size - IEEE80211_SNAP_LEN_DMG;
5884 sigma_dut_print(dut, DUT_MSG_DEBUG,
5885 "Setting amsdu_size to %d", mtu);
5886 snprintf(buf, sizeof(buf), "ifconfig %s mtu %d",
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005887 get_station_ifname(dut), mtu);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005888
5889 if (system(buf) != 0) {
5890 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
5891 buf);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005892 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005893 }
5894 }
5895
5896 val = get_param(cmd, "BAckRcvBuf");
5897 if (val) {
5898 dut->back_rcv_buf = atoi(val);
5899 if (dut->back_rcv_buf == 0) {
5900 sigma_dut_print(dut, DUT_MSG_ERROR,
5901 "Failed to convert %s or value is 0",
5902 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005903 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005904 }
5905
5906 sigma_dut_print(dut, DUT_MSG_DEBUG,
5907 "Setting BAckRcvBuf to %s", val);
5908 }
5909
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02005910 val = get_param(cmd, "MCS_FixedRate");
5911 if (val) {
5912 if (sta_set_force_mcs(dut, 1, atoi(val))) {
5913 sigma_dut_print(dut, DUT_MSG_ERROR,
5914 "Failed to force MCS");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005915 return ERROR_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02005916 }
5917 }
5918
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005919 return SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005920}
5921
5922
5923static int sta_pcp_start(struct sigma_dut *dut, struct sigma_conn *conn,
5924 struct sigma_cmd *cmd)
5925{
5926 int net_id;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005927 const char *ifname;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005928 const char *val;
5929 char buf[100];
5930
5931 dut->mode = SIGMA_MODE_STATION;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005932 ifname = get_main_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005933 if (wpa_command(ifname, "PING") != 0) {
5934 sigma_dut_print(dut, DUT_MSG_ERROR, "Supplicant not running");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005935 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005936 }
5937
5938 wpa_command(ifname, "FLUSH");
5939 net_id = add_network_common(dut, conn, ifname, cmd);
5940 if (net_id < 0) {
5941 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add network");
5942 return net_id;
5943 }
5944
5945 /* TODO: mode=2 for the AP; in the future, replace for mode PCP */
5946 if (set_network(ifname, net_id, "mode", "2") < 0) {
5947 sigma_dut_print(dut, DUT_MSG_ERROR,
5948 "Failed to set supplicant network mode");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005949 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005950 }
5951
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02005952 if (set_network(ifname, net_id, "pbss", "1") < 0)
5953 return -2;
5954
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005955 sigma_dut_print(dut, DUT_MSG_DEBUG,
Alexei Avshalom Lazarfd9f1352018-11-13 14:07:58 +02005956 "Supplicant set network with mode 2. network_id %d",
5957 net_id);
5958
5959 if (set_network(ifname, net_id, "wps_disabled", "0") < 0) {
5960 sigma_dut_print(dut, DUT_MSG_INFO,
5961 "Failed to set supplicant to WPS ENABLE");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005962 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarfd9f1352018-11-13 14:07:58 +02005963 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005964
5965 val = get_param(cmd, "Security");
5966 if (val && strcasecmp(val, "OPEN") == 0) {
5967 dut->ap_key_mgmt = AP_OPEN;
5968 if (set_network(ifname, net_id, "key_mgmt", "NONE") < 0) {
5969 sigma_dut_print(dut, DUT_MSG_ERROR,
5970 "Failed to set supplicant to %s security",
5971 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005972 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005973 }
5974 } else if (val && strcasecmp(val, "WPA2-PSK") == 0) {
5975 dut->ap_key_mgmt = AP_WPA2_PSK;
5976 if (set_network(ifname, net_id, "key_mgmt", "WPA-PSK") < 0) {
5977 sigma_dut_print(dut, DUT_MSG_ERROR,
5978 "Failed to set supplicant to %s security",
5979 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005980 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005981 }
5982
5983 if (set_network(ifname, net_id, "proto", "RSN") < 0) {
5984 sigma_dut_print(dut, DUT_MSG_ERROR,
5985 "Failed to set supplicant to proto RSN");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005986 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005987 }
5988 } else if (val) {
5989 sigma_dut_print(dut, DUT_MSG_ERROR,
5990 "Requested Security %s is not supported on 60GHz",
5991 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005992 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005993 }
5994
5995 val = get_param(cmd, "Encrypt");
5996 if (val && strcasecmp(val, "AES-GCMP") == 0) {
5997 if (set_network(ifname, net_id, "pairwise", "GCMP") < 0) {
5998 sigma_dut_print(dut, DUT_MSG_ERROR,
5999 "Failed to set supplicant to pairwise GCMP");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02006000 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006001 }
6002 if (set_network(ifname, net_id, "group", "GCMP") < 0) {
6003 sigma_dut_print(dut, DUT_MSG_ERROR,
6004 "Failed to set supplicant to group GCMP");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02006005 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006006 }
6007 } else if (val) {
6008 sigma_dut_print(dut, DUT_MSG_ERROR,
6009 "Requested Encrypt %s is not supported on 60 GHz",
6010 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02006011 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006012 }
6013
6014 val = get_param(cmd, "PSK");
6015 if (val && set_network_quoted(ifname, net_id, "psk", val) < 0) {
6016 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set psk %s",
6017 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02006018 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006019 }
6020
6021 /* Convert 60G channel to freq */
6022 switch (dut->ap_channel) {
6023 case 1:
6024 val = "58320";
6025 break;
6026 case 2:
6027 val = "60480";
6028 break;
6029 case 3:
6030 val = "62640";
6031 break;
6032 default:
6033 sigma_dut_print(dut, DUT_MSG_ERROR,
6034 "Failed to configure channel %d. Not supported",
6035 dut->ap_channel);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02006036 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006037 }
6038
6039 if (set_network(ifname, net_id, "frequency", val) < 0) {
6040 sigma_dut_print(dut, DUT_MSG_ERROR,
6041 "Failed to set supplicant network frequency");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02006042 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006043 }
6044
Alexei Avshalom Lazar2eccf4d2019-01-31 10:03:59 +02006045 if (dut->eap_fragment) {
6046 sigma_dut_print(dut, DUT_MSG_DEBUG,
6047 "Set EAP fragment size to 128 bytes.");
6048 if (set_network(ifname, net_id, "fragment_size", "128") < 0)
6049 return ERROR_SEND_STATUS;
6050 }
6051
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006052 sigma_dut_print(dut, DUT_MSG_DEBUG,
6053 "Supplicant set network with frequency");
6054
6055 snprintf(buf, sizeof(buf), "SELECT_NETWORK %d", net_id);
6056 if (wpa_command(ifname, buf) < 0) {
6057 sigma_dut_print(dut, DUT_MSG_INFO,
6058 "Failed to select network id %d on %s",
6059 net_id, ifname);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02006060 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006061 }
6062
6063 sigma_dut_print(dut, DUT_MSG_DEBUG, "Selected network");
6064
Jouni Malinen0e29cf22019-02-19 01:13:21 +02006065 return SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006066}
6067
6068
Lior David67543f52017-01-03 19:04:22 +02006069static int wil6210_set_abft_len(struct sigma_dut *dut, int abft_len)
6070{
6071 char buf[128], fname[128];
6072 FILE *f;
Jouni Malinen3aa72862019-05-29 23:14:51 +03006073 int res;
Lior David67543f52017-01-03 19:04:22 +02006074
6075 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
6076 sigma_dut_print(dut, DUT_MSG_ERROR,
6077 "failed to get wil6210 debugfs dir");
6078 return -1;
6079 }
6080
Jouni Malinen3aa72862019-05-29 23:14:51 +03006081 res = snprintf(fname, sizeof(fname), "%s/abft_len", buf);
6082 if (res < 0 || res >= sizeof(fname))
6083 return -1;
Lior David67543f52017-01-03 19:04:22 +02006084 f = fopen(fname, "w");
6085 if (!f) {
6086 sigma_dut_print(dut, DUT_MSG_ERROR,
6087 "failed to open: %s", fname);
6088 return -1;
6089 }
6090
6091 fprintf(f, "%d\n", abft_len);
6092 fclose(f);
6093
6094 return 0;
6095}
6096
6097
Alexei Avshalom Lazar49498b82019-01-31 15:16:32 +02006098int sta_set_60g_abft_len(struct sigma_dut *dut, struct sigma_conn *conn,
6099 int abft_len)
Lior David67543f52017-01-03 19:04:22 +02006100{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006101 switch (get_driver_type(dut)) {
Lior David67543f52017-01-03 19:04:22 +02006102 case DRIVER_WIL6210:
6103 return wil6210_set_abft_len(dut, abft_len);
6104 default:
6105 sigma_dut_print(dut, DUT_MSG_ERROR,
6106 "set abft_len not supported");
6107 return -1;
6108 }
6109}
6110
6111
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006112static int sta_set_60g_pcp(struct sigma_dut *dut, struct sigma_conn *conn,
6113 struct sigma_cmd *cmd)
6114{
6115 const char *val;
Lior David67543f52017-01-03 19:04:22 +02006116 unsigned int abft_len = 1; /* default is one slot */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006117
6118 if (dut->dev_role != DEVROLE_PCP) {
6119 send_resp(dut, conn, SIGMA_INVALID,
6120 "ErrorCode,Invalid DevRole");
6121 return 0;
6122 }
6123
6124 val = get_param(cmd, "SSID");
6125 if (val) {
6126 if (strlen(val) > sizeof(dut->ap_ssid) - 1) {
6127 send_resp(dut, conn, SIGMA_INVALID,
6128 "ErrorCode,Invalid SSID");
6129 return -1;
6130 }
6131
Peng Xub8fc5cc2017-05-10 17:27:28 -07006132 strlcpy(dut->ap_ssid, val, sizeof(dut->ap_ssid));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006133 }
6134
6135 val = get_param(cmd, "CHANNEL");
6136 if (val) {
6137 const char *pos;
6138
6139 dut->ap_channel = atoi(val);
6140 pos = strchr(val, ';');
6141 if (pos) {
6142 pos++;
6143 dut->ap_channel_1 = atoi(pos);
6144 }
6145 }
6146
6147 switch (dut->ap_channel) {
6148 case 1:
6149 case 2:
6150 case 3:
6151 break;
6152 default:
6153 sigma_dut_print(dut, DUT_MSG_ERROR,
6154 "Channel %d is not supported", dut->ap_channel);
6155 send_resp(dut, conn, SIGMA_ERROR,
6156 "Requested channel is not supported");
6157 return -1;
6158 }
6159
6160 val = get_param(cmd, "BCNINT");
6161 if (val)
6162 dut->ap_bcnint = atoi(val);
6163
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006164 val = get_param(cmd, "AllocType");
6165 if (val) {
6166 send_resp(dut, conn, SIGMA_ERROR,
6167 "ErrorCode,AllocType is not supported yet");
6168 return -1;
6169 }
6170
6171 val = get_param(cmd, "PercentBI");
6172 if (val) {
6173 send_resp(dut, conn, SIGMA_ERROR,
6174 "ErrorCode,PercentBI is not supported yet");
6175 return -1;
6176 }
6177
6178 val = get_param(cmd, "CBAPOnly");
6179 if (val) {
6180 send_resp(dut, conn, SIGMA_ERROR,
6181 "ErrorCode,CBAPOnly is not supported yet");
6182 return -1;
6183 }
6184
6185 val = get_param(cmd, "AMPDU");
6186 if (val) {
6187 if (strcasecmp(val, "Enable") == 0)
6188 dut->ap_ampdu = 1;
6189 else if (strcasecmp(val, "Disable") == 0)
6190 dut->ap_ampdu = 2;
6191 else {
6192 send_resp(dut, conn, SIGMA_ERROR,
6193 "ErrorCode,AMPDU value is not Enable nor Disabled");
6194 return -1;
6195 }
6196 }
6197
6198 val = get_param(cmd, "AMSDU");
6199 if (val) {
6200 if (strcasecmp(val, "Enable") == 0)
6201 dut->ap_amsdu = 1;
6202 else if (strcasecmp(val, "Disable") == 0)
6203 dut->ap_amsdu = 2;
6204 }
6205
6206 val = get_param(cmd, "NumMSDU");
6207 if (val) {
6208 send_resp(dut, conn, SIGMA_ERROR,
6209 "ErrorCode, NumMSDU is not supported yet");
6210 return -1;
6211 }
6212
6213 val = get_param(cmd, "ABFTLRang");
6214 if (val) {
6215 sigma_dut_print(dut, DUT_MSG_DEBUG,
Lior David67543f52017-01-03 19:04:22 +02006216 "ABFTLRang parameter %s", val);
6217 if (strcmp(val, "Gt1") == 0)
6218 abft_len = 2; /* 2 slots in this case */
6219 }
6220
6221 if (sta_set_60g_abft_len(dut, conn, abft_len)) {
6222 send_resp(dut, conn, SIGMA_ERROR,
6223 "ErrorCode, Can't set ABFT length");
6224 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006225 }
6226
6227 if (sta_pcp_start(dut, conn, cmd) < 0) {
6228 send_resp(dut, conn, SIGMA_ERROR,
6229 "ErrorCode, Can't start PCP role");
6230 return -1;
6231 }
6232
6233 return sta_set_60g_common(dut, conn, cmd);
6234}
6235
6236
6237static int sta_set_60g_sta(struct sigma_dut *dut, struct sigma_conn *conn,
6238 struct sigma_cmd *cmd)
6239{
6240 const char *val = get_param(cmd, "DiscoveryMode");
6241
6242 if (dut->dev_role != DEVROLE_STA) {
6243 send_resp(dut, conn, SIGMA_INVALID,
6244 "ErrorCode,Invalid DevRole");
6245 return 0;
6246 }
6247
6248 if (val) {
6249 sigma_dut_print(dut, DUT_MSG_DEBUG, "Discovery: %s", val);
6250 /* Ignore Discovery mode till Driver expose API. */
6251#if 0
6252 if (strcasecmp(val, "1") == 0) {
6253 send_resp(dut, conn, SIGMA_INVALID,
6254 "ErrorCode,DiscoveryMode 1 not supported");
6255 return 0;
6256 }
6257
6258 if (strcasecmp(val, "0") == 0) {
6259 /* OK */
6260 } else {
6261 send_resp(dut, conn, SIGMA_INVALID,
6262 "ErrorCode,DiscoveryMode not supported");
6263 return 0;
6264 }
6265#endif
6266 }
6267
6268 if (start_sta_mode(dut) != 0)
Jouni Malinen0e29cf22019-02-19 01:13:21 +02006269 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006270 return sta_set_60g_common(dut, conn, cmd);
6271}
6272
6273
Jouni Malinenf7222712019-06-13 01:50:21 +03006274static enum sigma_cmd_result cmd_sta_disconnect(struct sigma_dut *dut,
6275 struct sigma_conn *conn,
6276 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006277{
6278 const char *intf = get_param(cmd, "Interface");
Jouni Malinened77e672018-01-10 16:45:13 +02006279 const char *val = get_param(cmd, "maintain_profile");
vamsi krishnad605c422017-09-20 14:56:31 +05306280
Jouni Malinened77e672018-01-10 16:45:13 +02006281 if (dut->program == PROGRAM_OCE ||
Amarnath Hullur Subramanyamebeda9e2018-01-31 03:21:48 -08006282 dut->program == PROGRAM_HE ||
Jouni Malinened77e672018-01-10 16:45:13 +02006283 (val && atoi(val) == 1)) {
vamsi krishnad605c422017-09-20 14:56:31 +05306284 wpa_command(intf, "DISCONNECT");
6285 return 1;
6286 }
6287
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006288 disconnect_station(dut);
6289 /* Try to ignore old scan results to avoid HS 2.0R2 test case failures
6290 * due to cached results. */
6291 wpa_command(intf, "SET ignore_old_scan_res 1");
6292 wpa_command(intf, "BSS_FLUSH");
6293 return 1;
6294}
6295
6296
Jouni Malinenf7222712019-06-13 01:50:21 +03006297static enum sigma_cmd_result cmd_sta_reassoc(struct sigma_dut *dut,
6298 struct sigma_conn *conn,
6299 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006300{
6301 const char *intf = get_param(cmd, "Interface");
6302 const char *bssid = get_param(cmd, "bssid");
6303 const char *val = get_param(cmd, "CHANNEL");
6304 struct wpa_ctrl *ctrl;
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05306305 char buf[1000];
Sunil Duttd30ce092018-01-11 23:56:29 +05306306 char result[32];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006307 int res;
6308 int chan = 0;
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006309 enum sigma_cmd_result status = STATUS_SENT;
Sunil Duttd30ce092018-01-11 23:56:29 +05306310 int fastreassoc = 1;
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006311 int ft_ds = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006312
6313 if (bssid == NULL) {
6314 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing bssid "
6315 "argument");
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006316 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006317 }
6318
6319 if (val)
6320 chan = atoi(val);
6321
6322 if (wifi_chip_type != DRIVER_WCN && wifi_chip_type != DRIVER_AR6003) {
6323 /* The current network may be from sta_associate or
6324 * sta_hs2_associate
6325 */
6326 if (set_network(intf, dut->infra_network_id, "bssid", bssid) <
6327 0 ||
6328 set_network(intf, 0, "bssid", bssid) < 0)
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006329 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006330 }
6331
6332 ctrl = open_wpa_mon(intf);
6333 if (ctrl == NULL) {
6334 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
6335 "wpa_supplicant monitor connection");
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006336 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006337 }
6338
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006339 if (get_wpa_status(get_station_ifname(dut), "wpa_state", result,
Sunil Duttd30ce092018-01-11 23:56:29 +05306340 sizeof(result)) < 0 ||
6341 strncmp(result, "COMPLETED", 9) != 0) {
6342 sigma_dut_print(dut, DUT_MSG_DEBUG,
6343 "sta_reassoc: Not connected");
6344 fastreassoc = 0;
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006345 } else if (dut->sta_ft_ds) {
6346 sigma_dut_print(dut, DUT_MSG_DEBUG,
6347 "sta_reassoc: Use FT-over-DS");
6348 ft_ds = 1;
Sunil Duttd30ce092018-01-11 23:56:29 +05306349 }
6350
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05306351 if (dut->rsne_override) {
6352#ifdef NL80211_SUPPORT
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006353 if (get_driver_type(dut) == DRIVER_WCN &&
6354 dut->config_rsnie == 0) {
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05306355 sta_config_rsnie(dut, 1);
6356 dut->config_rsnie = 1;
6357 }
6358#endif /* NL80211_SUPPORT */
6359 snprintf(buf, sizeof(buf), "TEST_ASSOC_IE %s",
6360 dut->rsne_override);
6361 if (wpa_command(intf, buf) < 0) {
6362 send_resp(dut, conn, SIGMA_ERROR,
6363 "ErrorCode,Failed to set DEV_CONFIGURE_IE RSNE override");
6364 return 0;
6365 }
6366 }
6367
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006368 if (ft_ds) {
6369 if (chan) {
6370 unsigned int freq;
6371
6372 freq = channel_to_freq(dut, chan);
6373 if (!freq) {
6374 sigma_dut_print(dut, DUT_MSG_ERROR,
6375 "Invalid channel number provided: %d",
6376 chan);
6377 send_resp(dut, conn, SIGMA_INVALID,
6378 "ErrorCode,Invalid channel number");
6379 goto close_mon_conn;
6380 }
6381 res = snprintf(buf, sizeof(buf),
6382 "SCAN TYPE=ONLY freq=%d", freq);
6383 } else {
6384 res = snprintf(buf, sizeof(buf), "SCAN TYPE=ONLY");
6385 }
6386 if (res < 0 || res >= (int) sizeof(buf)) {
6387 send_resp(dut, conn, SIGMA_ERROR,
6388 "ErrorCode,snprintf failed");
6389 goto close_mon_conn;
6390 }
6391 if (wpa_command(intf, buf) < 0) {
6392 sigma_dut_print(dut, DUT_MSG_INFO,
6393 "Failed to start scan");
6394 send_resp(dut, conn, SIGMA_ERROR,
6395 "ErrorCode,scan failed");
6396 goto close_mon_conn;
6397 }
6398
6399 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
6400 buf, sizeof(buf));
6401 if (res < 0) {
6402 sigma_dut_print(dut, DUT_MSG_INFO,
6403 "Scan did not complete");
6404 send_resp(dut, conn, SIGMA_ERROR,
6405 "ErrorCode,scan did not complete");
6406 goto close_mon_conn;
6407 }
6408
6409 res = snprintf(buf, sizeof(buf), "FT_DS %s", bssid);
6410 if (res > 0 && res < (int) sizeof(buf))
6411 res = wpa_command(intf, buf);
6412
6413 if (res < 0 || res >= (int) sizeof(buf)) {
6414 send_resp(dut, conn, SIGMA_ERROR,
6415 "errorCode,FT_DS command failed");
6416 status = STATUS_SENT_ERROR;
6417 goto close_mon_conn;
6418 }
6419 } else if (wifi_chip_type == DRIVER_WCN && fastreassoc) {
Ashwini Patil4c8158f2017-05-25 12:49:21 +05306420 if (chan) {
6421 unsigned int freq;
6422
Alexei Avshalom Lazar093569f2018-11-13 14:08:17 +02006423 freq = channel_to_freq(dut, chan);
Ashwini Patil4c8158f2017-05-25 12:49:21 +05306424 if (!freq) {
6425 sigma_dut_print(dut, DUT_MSG_ERROR,
6426 "Invalid channel number provided: %d",
6427 chan);
6428 send_resp(dut, conn, SIGMA_INVALID,
6429 "ErrorCode,Invalid channel number");
6430 goto close_mon_conn;
6431 }
6432 res = snprintf(buf, sizeof(buf),
6433 "SCAN TYPE=ONLY freq=%d", freq);
6434 } else {
6435 res = snprintf(buf, sizeof(buf), "SCAN TYPE=ONLY");
6436 }
6437 if (res < 0 || res >= (int) sizeof(buf)) {
6438 send_resp(dut, conn, SIGMA_ERROR,
6439 "ErrorCode,snprintf failed");
6440 goto close_mon_conn;
6441 }
6442 if (wpa_command(intf, buf) < 0) {
6443 sigma_dut_print(dut, DUT_MSG_INFO,
6444 "Failed to start scan");
6445 send_resp(dut, conn, SIGMA_ERROR,
6446 "ErrorCode,scan failed");
6447 goto close_mon_conn;
6448 }
6449
6450 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
6451 buf, sizeof(buf));
6452 if (res < 0) {
6453 sigma_dut_print(dut, DUT_MSG_INFO,
6454 "Scan did not complete");
6455 send_resp(dut, conn, SIGMA_ERROR,
6456 "ErrorCode,scan did not complete");
6457 goto close_mon_conn;
6458 }
6459
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006460 if (set_network(intf, dut->infra_network_id, "bssid", "any")
6461 < 0) {
6462 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
6463 "bssid to any during FASTREASSOC");
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006464 status = ERROR_SEND_STATUS;
Ashwini Patil467efef2017-05-25 12:18:27 +05306465 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006466 }
Vinita Maloo54b78cf2020-03-30 12:18:19 +05306467 res = snprintf(buf, sizeof(buf), "FASTREASSOC %s %d",
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006468 bssid, chan);
Vinita Maloo54b78cf2020-03-30 12:18:19 +05306469 if (res < 0 || res >= (int) sizeof(buf) ||
6470 wcn_driver_cmd(intf, buf) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006471 send_resp(dut, conn, SIGMA_ERROR,
Vinita Maloo54b78cf2020-03-30 12:18:19 +05306472 "errorCode,Failed to run FASTREASSOC");
Ashwini Patil467efef2017-05-25 12:18:27 +05306473 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006474 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006475 sigma_dut_print(dut, DUT_MSG_INFO,
6476 "sta_reassoc: Run %s successful", buf);
6477 } else if (wpa_command(intf, "REASSOCIATE")) {
6478 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
6479 "request reassociation");
Ashwini Patil467efef2017-05-25 12:18:27 +05306480 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006481 }
6482
6483 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
6484 buf, sizeof(buf));
Ashwini Patil467efef2017-05-25 12:18:27 +05306485 if (res < 0) {
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006486 send_resp(dut, conn, SIGMA_ERROR,
6487 "errorCode,Connection did not complete");
6488 status = STATUS_SENT_ERROR;
Ashwini Patil467efef2017-05-25 12:18:27 +05306489 goto close_mon_conn;
6490 }
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006491 status = SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006492
Ashwini Patil467efef2017-05-25 12:18:27 +05306493close_mon_conn:
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006494 wpa_ctrl_detach(ctrl);
6495 wpa_ctrl_close(ctrl);
Ashwini Patil467efef2017-05-25 12:18:27 +05306496 return status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006497}
6498
6499
6500static void hs2_clear_credentials(const char *intf)
6501{
6502 wpa_command(intf, "REMOVE_CRED all");
6503}
6504
6505
Lior Davidcc88b562017-01-03 18:52:09 +02006506#ifdef __linux__
6507static int wil6210_get_aid(struct sigma_dut *dut, const char *bssid,
6508 unsigned int *aid)
6509{
Lior David0fe101e2017-03-09 16:09:50 +02006510 const char *pattern = "AID[ \t]+([0-9]+)";
Lior Davidcc88b562017-01-03 18:52:09 +02006511
Lior David0fe101e2017-03-09 16:09:50 +02006512 return wil6210_get_sta_info_field(dut, bssid, pattern, aid);
Lior Davidcc88b562017-01-03 18:52:09 +02006513}
6514#endif /* __linux__ */
6515
6516
6517static int sta_get_aid_60g(struct sigma_dut *dut, const char *bssid,
6518 unsigned int *aid)
6519{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006520 switch (get_driver_type(dut)) {
Lior Davidcc88b562017-01-03 18:52:09 +02006521#ifdef __linux__
6522 case DRIVER_WIL6210:
6523 return wil6210_get_aid(dut, bssid, aid);
6524#endif /* __linux__ */
6525 default:
6526 sigma_dut_print(dut, DUT_MSG_ERROR, "get AID not supported");
6527 return -1;
6528 }
6529}
6530
6531
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006532static int sta_get_parameter_60g(struct sigma_dut *dut, struct sigma_conn *conn,
6533 struct sigma_cmd *cmd)
6534{
6535 char buf[MAX_CMD_LEN];
6536 char bss_list[MAX_CMD_LEN];
6537 const char *parameter = get_param(cmd, "Parameter");
6538
6539 if (parameter == NULL)
6540 return -1;
6541
Lior Davidcc88b562017-01-03 18:52:09 +02006542 if (strcasecmp(parameter, "AID") == 0) {
6543 unsigned int aid = 0;
6544 char bssid[20];
6545
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006546 if (get_wpa_status(get_station_ifname(dut), "bssid",
Lior Davidcc88b562017-01-03 18:52:09 +02006547 bssid, sizeof(bssid)) < 0) {
6548 sigma_dut_print(dut, DUT_MSG_ERROR,
6549 "could not get bssid");
6550 return -2;
6551 }
6552
6553 if (sta_get_aid_60g(dut, bssid, &aid))
6554 return -2;
6555
6556 snprintf(buf, sizeof(buf), "aid,%d", aid);
6557 sigma_dut_print(dut, DUT_MSG_INFO, "%s", buf);
6558 send_resp(dut, conn, SIGMA_COMPLETE, buf);
6559 return 0;
6560 }
6561
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006562 if (strcasecmp(parameter, "DiscoveredDevList") == 0) {
6563 char *bss_line;
6564 char *bss_id = NULL;
6565 const char *ifname = get_param(cmd, "Interface");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05306566 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006567
6568 if (ifname == NULL) {
6569 sigma_dut_print(dut, DUT_MSG_INFO,
6570 "For get DiscoveredDevList need Interface name.");
6571 return -1;
6572 }
6573
6574 /*
6575 * Use "BSS RANGE=ALL MASK=0x2" which provides a list
6576 * of BSSIDs in "bssid=<BSSID>\n"
6577 */
6578 if (wpa_command_resp(ifname, "BSS RANGE=ALL MASK=0x2",
6579 bss_list,
6580 sizeof(bss_list)) < 0) {
6581 sigma_dut_print(dut, DUT_MSG_ERROR,
6582 "Failed to get bss list");
6583 return -1;
6584 }
6585
6586 sigma_dut_print(dut, DUT_MSG_DEBUG,
6587 "bss list for ifname:%s is:%s",
6588 ifname, bss_list);
6589
6590 snprintf(buf, sizeof(buf), "DeviceList");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05306591 bss_line = strtok_r(bss_list, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006592 while (bss_line) {
6593 if (sscanf(bss_line, "bssid=%ms", &bss_id) > 0 &&
6594 bss_id) {
6595 int len;
6596
6597 len = snprintf(buf + strlen(buf),
6598 sizeof(buf) - strlen(buf),
6599 ",%s", bss_id);
6600 free(bss_id);
6601 bss_id = NULL;
6602 if (len < 0) {
6603 sigma_dut_print(dut,
6604 DUT_MSG_ERROR,
6605 "Failed to read BSSID");
6606 send_resp(dut, conn, SIGMA_ERROR,
6607 "ErrorCode,Failed to read BSS ID");
6608 return 0;
6609 }
6610
6611 if ((size_t) len >= sizeof(buf) - strlen(buf)) {
6612 sigma_dut_print(dut,
6613 DUT_MSG_ERROR,
6614 "Response buf too small for list");
6615 send_resp(dut, conn,
6616 SIGMA_ERROR,
6617 "ErrorCode,Response buf too small for list");
6618 return 0;
6619 }
6620 }
6621
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05306622 bss_line = strtok_r(NULL, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006623 }
6624
6625 sigma_dut_print(dut, DUT_MSG_INFO, "DiscoveredDevList is %s",
6626 buf);
6627 send_resp(dut, conn, SIGMA_COMPLETE, buf);
6628 return 0;
6629 }
6630
6631 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
6632 return 0;
6633}
6634
6635
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07006636static int sta_get_parameter_he(struct sigma_dut *dut, struct sigma_conn *conn,
6637 struct sigma_cmd *cmd)
6638{
6639 char buf[MAX_CMD_LEN];
6640 const char *parameter = get_param(cmd, "Parameter");
6641
6642 if (!parameter)
6643 return -1;
6644
6645 if (strcasecmp(parameter, "RSSI") == 0) {
6646 char rssi[10];
6647
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006648 if (get_wpa_signal_poll(dut, get_station_ifname(dut), "RSSI",
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07006649 rssi, sizeof(rssi)) < 0) {
6650 sigma_dut_print(dut, DUT_MSG_ERROR,
6651 "Could not get RSSI");
6652 return -2;
6653 }
6654
6655 snprintf(buf, sizeof(buf), "rssi,%s", rssi);
6656 sigma_dut_print(dut, DUT_MSG_INFO, "RSSI %s", buf);
6657 send_resp(dut, conn, SIGMA_COMPLETE, buf);
6658 return 0;
6659 }
6660
6661 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
6662 return 0;
6663}
6664
6665
Jouni Malinenca0abd32020-02-09 20:18:10 +02006666static enum sigma_cmd_result sta_get_pmk(struct sigma_dut *dut,
6667 struct sigma_conn *conn,
6668 struct sigma_cmd *cmd)
6669{
6670 const char *intf = get_param(cmd, "Interface");
6671 char buf[4096], bssid[20], resp[200], *pos, *tmp;
6672
6673 snprintf(buf, sizeof(buf), "PMKSA_GET %d", dut->infra_network_id);
6674 if (wpa_command_resp(intf, buf, buf, sizeof(buf)) < 0 ||
6675 strncmp(buf, "UNKNOWN COMMAND", 15) == 0) {
6676 send_resp(dut, conn, SIGMA_ERROR,
6677 "ErrorCode,PMKSA_GET not supported");
6678 return STATUS_SENT_ERROR;
6679 }
6680
6681 if (strncmp(buf, "FAIL", 4) == 0 ||
6682 get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0) {
6683 send_resp(dut, conn, SIGMA_ERROR,
6684 "ErrorCode,Could not find current network");
6685 return STATUS_SENT_ERROR;
6686 }
6687
6688 pos = buf;
6689 while (pos) {
6690 if (strncmp(pos, bssid, 17) == 0) {
6691 pos = strchr(pos, ' ');
6692 if (!pos)
Mohammad Asaad Akram956bfc32020-04-08 16:26:18 +05306693 break;
Jouni Malinenca0abd32020-02-09 20:18:10 +02006694 pos++;
6695 pos = strchr(pos, ' ');
6696 if (!pos)
Mohammad Asaad Akram956bfc32020-04-08 16:26:18 +05306697 break;
Jouni Malinenca0abd32020-02-09 20:18:10 +02006698 pos++;
6699 tmp = strchr(pos, ' ');
6700 if (!tmp)
Mohammad Asaad Akram956bfc32020-04-08 16:26:18 +05306701 break;
Jouni Malinenca0abd32020-02-09 20:18:10 +02006702 *tmp = '\0';
6703 break;
6704 }
Jouni Malinenca0abd32020-02-09 20:18:10 +02006705 pos = strchr(pos, '\n');
6706 if (pos)
6707 pos++;
6708 }
6709
6710 if (!pos) {
6711 send_resp(dut, conn, SIGMA_ERROR,
6712 "ErrorCode,PMK not available");
6713 return STATUS_SENT_ERROR;
6714 }
6715
6716 snprintf(resp, sizeof(resp), "PMK,%s", pos);
6717 send_resp(dut, conn, SIGMA_COMPLETE, resp);
6718 return STATUS_SENT;
6719}
6720
6721
Jouni Malinenf7222712019-06-13 01:50:21 +03006722static enum sigma_cmd_result cmd_sta_get_parameter(struct sigma_dut *dut,
6723 struct sigma_conn *conn,
6724 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006725{
6726 const char *program = get_param(cmd, "Program");
Jouni Malinenca0abd32020-02-09 20:18:10 +02006727 const char *parameter = get_param(cmd, "Parameter");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006728
Jouni Malinenca0abd32020-02-09 20:18:10 +02006729 if (!parameter)
6730 return INVALID_SEND_STATUS;
6731
6732 if (strcasecmp(parameter, "PMK") == 0)
6733 return sta_get_pmk(dut, conn, cmd);
6734
6735 if (!program)
6736 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006737
6738 if (strcasecmp(program, "P2PNFC") == 0)
6739 return p2p_cmd_sta_get_parameter(dut, conn, cmd);
6740
6741 if (strcasecmp(program, "60ghz") == 0)
6742 return sta_get_parameter_60g(dut, conn, cmd);
6743
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07006744 if (strcasecmp(program, "he") == 0)
6745 return sta_get_parameter_he(dut, conn, cmd);
6746
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006747#ifdef ANDROID_NAN
6748 if (strcasecmp(program, "NAN") == 0)
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07006749 return nan_cmd_sta_get_parameter(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006750#endif /* ANDROID_NAN */
6751
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07006752#ifdef MIRACAST
6753 if (strcasecmp(program, "WFD") == 0 ||
6754 strcasecmp(program, "DisplayR2") == 0)
6755 return miracast_cmd_sta_get_parameter(dut, conn, cmd);
6756#endif /* MIRACAST */
6757
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006758 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
6759 return 0;
6760}
6761
6762
6763static void sta_reset_default_ath(struct sigma_dut *dut, const char *intf,
6764 const char *type)
6765{
6766 char buf[100];
6767
6768 if (dut->program == PROGRAM_VHT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006769 run_iwpriv(dut, intf, "chwidth 2");
6770 run_iwpriv(dut, intf, "mode 11ACVHT80");
6771 run_iwpriv(dut, intf, "vhtmcs -1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006772 }
6773
6774 if (dut->program == PROGRAM_HT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006775 run_iwpriv(dut, intf, "chwidth 0");
6776 run_iwpriv(dut, intf, "mode 11naht40");
6777 run_iwpriv(dut, intf, "set11NRates 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006778 }
6779
6780 if (dut->program == PROGRAM_VHT || dut->program == PROGRAM_HT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006781 run_iwpriv(dut, intf, "powersave 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006782
6783 /* Reset CTS width */
6784 snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 54 0",
6785 intf);
6786 if (system(buf) != 0) {
6787 sigma_dut_print(dut, DUT_MSG_ERROR,
6788 "wifitool %s beeliner_fw_test 54 0 failed",
6789 intf);
6790 }
6791
6792 /* Enable Dynamic Bandwidth signalling by default */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006793 run_iwpriv(dut, intf, "cwmenable 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006794
6795 snprintf(buf, sizeof(buf), "iwconfig %s rts 2347", intf);
6796 if (system(buf) != 0) {
6797 sigma_dut_print(dut, DUT_MSG_ERROR,
6798 "iwpriv rts failed");
6799 }
6800 }
6801
6802 if (type && strcasecmp(type, "Testbed") == 0) {
6803 dut->testbed_flag_txsp = 1;
6804 dut->testbed_flag_rxsp = 1;
6805 /* STA has to set spatial stream to 2 per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006806 run_iwpriv(dut, intf, "vht_mcsmap 0xfff0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006807
6808 /* Disable LDPC per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006809 run_iwpriv(dut, intf, "ldpc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006810
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006811 run_iwpriv(dut, intf, "amsdu 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006812
6813 /* TODO: Disable STBC 2x1 transmit and receive */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006814 run_iwpriv(dut, intf, "tx_stbc 0");
6815 run_iwpriv(dut, intf, "rx_stbc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006816
6817 /* STA has to disable Short GI per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006818 run_iwpriv(dut, intf, "shortgi 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006819 }
6820
6821 if (type && strcasecmp(type, "DUT") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006822 run_iwpriv(dut, intf, "nss 3");
Arif Hussainac6c5112018-05-25 17:34:00 -07006823 dut->sta_nss = 3;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006824
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006825 run_iwpriv(dut, intf, "shortgi 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006826 }
6827}
6828
6829
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08006830#ifdef NL80211_SUPPORT
6831static int sta_set_he_mcs(struct sigma_dut *dut, const char *intf,
6832 enum he_mcs_config mcs)
6833{
6834 struct nl_msg *msg;
6835 int ret = 0;
6836 struct nlattr *params;
6837 int ifindex;
6838
6839 ifindex = if_nametoindex(intf);
6840 if (ifindex == 0) {
6841 sigma_dut_print(dut, DUT_MSG_ERROR,
6842 "%s: Index for interface %s failed",
6843 __func__, intf);
6844 return -1;
6845 }
6846
6847 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6848 NL80211_CMD_VENDOR)) ||
6849 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6850 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6851 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6852 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6853 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6854 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MCS,
6855 mcs)) {
6856 sigma_dut_print(dut, DUT_MSG_ERROR,
6857 "%s: err in adding vendor_cmd and vendor_data",
6858 __func__);
6859 nlmsg_free(msg);
6860 return -1;
6861 }
6862 nla_nest_end(msg, params);
6863
6864 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6865 if (ret) {
6866 sigma_dut_print(dut, DUT_MSG_ERROR,
6867 "%s: err in send_and_recv_msgs, ret=%d",
6868 __func__, ret);
6869 }
6870 return ret;
6871}
6872#endif /* NL80211_SUPPORT */
6873
6874
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07006875static int sta_set_action_tx_in_he_tb_ppdu(struct sigma_dut *dut,
6876 const char *intf, int enable)
6877{
6878#ifdef NL80211_SUPPORT
6879 struct nl_msg *msg;
6880 int ret = 0;
6881 struct nlattr *params;
6882 int ifindex;
6883
6884 ifindex = if_nametoindex(intf);
6885 if (ifindex == 0) {
6886 sigma_dut_print(dut, DUT_MSG_ERROR,
6887 "%s: Index for interface %s failed",
6888 __func__, intf);
6889 return -1;
6890 }
6891
6892 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6893 NL80211_CMD_VENDOR)) ||
6894 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6895 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6896 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6897 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6898 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6899 nla_put_u8(msg,
6900 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_ACTION_TX_TB_PPDU,
6901 enable)) {
6902 sigma_dut_print(dut, DUT_MSG_ERROR,
6903 "%s: err in adding vendor_cmd and vendor_data",
6904 __func__);
6905 nlmsg_free(msg);
6906 return -1;
6907 }
6908 nla_nest_end(msg, params);
6909
6910 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6911 if (ret) {
6912 sigma_dut_print(dut, DUT_MSG_ERROR,
6913 "%s: err in send_and_recv_msgs, ret=%d",
6914 __func__, ret);
6915 }
6916 return ret;
6917#else /* NL80211_SUPPORT */
6918 sigma_dut_print(dut, DUT_MSG_ERROR,
6919 "HE action Tx TB PPDU cannot be set without NL80211_SUPPORT defined");
6920 return -1;
6921#endif /* NL80211_SUPPORT */
6922}
6923
6924
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08006925static int sta_set_heconfig_and_wep_tkip(struct sigma_dut *dut,
6926 const char *intf, int enable)
6927{
6928#ifdef NL80211_SUPPORT
6929 struct nl_msg *msg;
6930 int ret = 0;
6931 struct nlattr *params;
6932 int ifindex;
6933
6934 ifindex = if_nametoindex(intf);
6935 if (ifindex == 0) {
6936 sigma_dut_print(dut, DUT_MSG_ERROR,
6937 "%s: Index for interface %s failed",
6938 __func__, intf);
6939 return -1;
6940 }
6941
6942 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6943 NL80211_CMD_VENDOR)) ||
6944 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6945 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6946 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6947 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6948 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6949 nla_put_u8(msg,
6950 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WEP_TKIP_IN_HE,
6951 enable)) {
6952 sigma_dut_print(dut, DUT_MSG_ERROR,
6953 "%s: err in adding vendor_cmd and vendor_data",
6954 __func__);
6955 nlmsg_free(msg);
6956 return -1;
6957 }
6958 nla_nest_end(msg, params);
6959
6960 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6961 if (ret) {
6962 sigma_dut_print(dut, DUT_MSG_ERROR,
6963 "%s: err in send_and_recv_msgs, ret=%d",
6964 __func__, ret);
6965 }
6966 return ret;
6967#else /* NL80211_SUPPORT */
6968 sigma_dut_print(dut, DUT_MSG_ERROR,
6969 "HE config enablement cannot be changed without NL80211_SUPPORT defined");
6970 return -1;
6971#endif /* NL80211_SUPPORT */
6972}
6973
6974
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08006975#ifdef NL80211_SUPPORT
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08006976
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08006977static int sta_set_he_testbed_def(struct sigma_dut *dut,
6978 const char *intf, int cfg)
6979{
6980 struct nl_msg *msg;
6981 int ret = 0;
6982 struct nlattr *params;
6983 int ifindex;
6984
6985 ifindex = if_nametoindex(intf);
6986 if (ifindex == 0) {
6987 sigma_dut_print(dut, DUT_MSG_ERROR,
6988 "%s: Index for interface %s failed",
6989 __func__, intf);
6990 return -1;
6991 }
6992
6993 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6994 NL80211_CMD_VENDOR)) ||
6995 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6996 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6997 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6998 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6999 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7000 nla_put_u8(msg,
7001 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_SET_HE_TESTBED_DEFAULTS,
7002 cfg)) {
7003 sigma_dut_print(dut, DUT_MSG_ERROR,
7004 "%s: err in adding vendor_cmd and vendor_data",
7005 __func__);
7006 nlmsg_free(msg);
7007 return -1;
7008 }
7009 nla_nest_end(msg, params);
7010
7011 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7012 if (ret) {
7013 sigma_dut_print(dut, DUT_MSG_ERROR,
7014 "%s: err in send_and_recv_msgs, ret=%d",
7015 __func__, ret);
7016 }
7017 return ret;
7018}
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08007019
7020
7021static int sta_set_2g_vht_supp(struct sigma_dut *dut, const char *intf, int cfg)
7022{
7023 struct nl_msg *msg;
7024 int ret = 0;
7025 struct nlattr *params;
7026 int ifindex;
7027
7028 ifindex = if_nametoindex(intf);
7029 if (ifindex == 0) {
7030 sigma_dut_print(dut, DUT_MSG_ERROR,
7031 "%s: Index for interface %s failed",
7032 __func__, intf);
7033 return -1;
7034 }
7035
7036 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7037 NL80211_CMD_VENDOR)) ||
7038 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7039 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7040 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7041 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7042 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7043 nla_put_u8(msg,
7044 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_2G_VHT,
7045 cfg)) {
7046 sigma_dut_print(dut, DUT_MSG_ERROR,
7047 "%s: err in adding vendor_cmd and vendor_data",
7048 __func__);
7049 nlmsg_free(msg);
7050 return -1;
7051 }
7052 nla_nest_end(msg, params);
7053
7054 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7055 if (ret) {
7056 sigma_dut_print(dut, DUT_MSG_ERROR,
7057 "%s: err in send_and_recv_msgs, ret=%d",
7058 __func__, ret);
7059 }
7060 return ret;
7061}
7062
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08007063#endif /* NL80211_SUPPORT */
7064
7065
Qiwei Caib6806972020-01-15 13:52:11 +08007066int sta_set_addba_buf_size(struct sigma_dut *dut,
7067 const char *intf, int bufsize)
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08007068{
7069#ifdef NL80211_SUPPORT
7070 struct nl_msg *msg;
7071 int ret = 0;
7072 struct nlattr *params;
7073 int ifindex;
7074
7075 ifindex = if_nametoindex(intf);
7076 if (ifindex == 0) {
7077 sigma_dut_print(dut, DUT_MSG_ERROR,
7078 "%s: Index for interface %s failed",
7079 __func__, intf);
7080 return -1;
7081 }
7082
7083 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7084 NL80211_CMD_VENDOR)) ||
7085 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7086 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7087 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7088 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7089 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
Kiran Kumar Lokere26e27582018-08-01 16:18:34 -07007090 nla_put_u16(msg,
7091 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE,
7092 bufsize)) {
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08007093 sigma_dut_print(dut, DUT_MSG_ERROR,
7094 "%s: err in adding vendor_cmd and vendor_data",
7095 __func__);
7096 nlmsg_free(msg);
7097 return -1;
7098 }
7099 nla_nest_end(msg, params);
7100
7101 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7102 if (ret) {
7103 sigma_dut_print(dut, DUT_MSG_ERROR,
7104 "%s: err in send_and_recv_msgs, ret=%d",
7105 __func__, ret);
7106 }
7107 return ret;
7108#else /* NL80211_SUPPORT */
7109 sigma_dut_print(dut, DUT_MSG_ERROR,
7110 "AddBA bufsize cannot be changed without NL80211_SUPPORT defined");
7111 return -1;
7112#endif /* NL80211_SUPPORT */
7113}
7114
7115
Arif Hussain8d5b27b2018-05-14 14:31:03 -07007116static int sta_set_tx_beamformee(struct sigma_dut *dut, const char *intf,
7117 int enable)
7118{
7119#ifdef NL80211_SUPPORT
7120 struct nl_msg *msg;
7121 int ret = 0;
7122 struct nlattr *params;
7123 int ifindex;
7124
7125 ifindex = if_nametoindex(intf);
7126 if (ifindex == 0) {
7127 sigma_dut_print(dut, DUT_MSG_ERROR,
7128 "%s: Index for interface %s failed",
7129 __func__, intf);
7130 return -1;
7131 }
7132
7133 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7134 NL80211_CMD_VENDOR)) ||
7135 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7136 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7137 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7138 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7139 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7140 nla_put_u8(msg,
7141 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_TX_BEAMFORMEE,
7142 enable)) {
7143 sigma_dut_print(dut, DUT_MSG_ERROR,
7144 "%s: err in adding vendor_cmd and vendor_data",
7145 __func__);
7146 nlmsg_free(msg);
7147 return -1;
7148 }
7149 nla_nest_end(msg, params);
7150
7151 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7152 if (ret) {
7153 sigma_dut_print(dut, DUT_MSG_ERROR,
7154 "%s: err in send_and_recv_msgs, ret=%d",
7155 __func__, ret);
7156 }
7157 return ret;
7158#else /* NL80211_SUPPORT */
7159 sigma_dut_print(dut, DUT_MSG_ERROR,
7160 "tx beamformee cannot be changed without NL80211_SUPPORT defined");
7161 return -1;
7162#endif /* NL80211_SUPPORT */
7163}
7164
7165
Arif Hussain9765f7d2018-07-03 08:28:26 -07007166static int sta_set_beamformee_sts(struct sigma_dut *dut, const char *intf,
7167 int val)
7168{
7169#ifdef NL80211_SUPPORT
7170 struct nl_msg *msg;
7171 int ret = 0;
7172 struct nlattr *params;
7173 int ifindex;
7174
7175 ifindex = if_nametoindex(intf);
7176 if (ifindex == 0) {
7177 sigma_dut_print(dut, DUT_MSG_ERROR,
7178 "%s: Index for interface %s failed, val:%d",
7179 __func__, intf, val);
7180 return -1;
7181 }
7182
7183 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7184 NL80211_CMD_VENDOR)) ||
7185 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7186 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7187 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7188 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7189 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7190 nla_put_u8(msg,
7191 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_BEAMFORMEE_NSTS,
7192 val)) {
7193 sigma_dut_print(dut, DUT_MSG_ERROR,
7194 "%s: err in adding vendor_cmd and vendor_data, val: %d",
7195 __func__, val);
7196 nlmsg_free(msg);
7197 return -1;
7198 }
7199 nla_nest_end(msg, params);
7200
7201 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7202 if (ret) {
7203 sigma_dut_print(dut, DUT_MSG_ERROR,
7204 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
7205 __func__, ret, val);
7206 }
7207 return ret;
7208#else /* NL80211_SUPPORT */
7209 sigma_dut_print(dut, DUT_MSG_ERROR,
7210 "beamformee sts cannot be changed without NL80211_SUPPORT defined");
7211 return -1;
7212#endif /* NL80211_SUPPORT */
7213}
7214
7215
Arif Hussain68d23f52018-07-11 13:39:08 -07007216#ifdef NL80211_SUPPORT
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07007217static int sta_set_mac_padding_duration(struct sigma_dut *dut, const char *intf,
7218 enum qca_wlan_he_mac_padding_dur val)
7219{
Arif Hussain68d23f52018-07-11 13:39:08 -07007220 struct nl_msg *msg;
7221 int ret = 0;
7222 struct nlattr *params;
7223 int ifindex;
7224
7225 ifindex = if_nametoindex(intf);
7226 if (ifindex == 0) {
7227 sigma_dut_print(dut, DUT_MSG_ERROR,
7228 "%s: Index for interface %s failed, val:%d",
7229 __func__, intf, val);
7230 return -1;
7231 }
7232
7233 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7234 NL80211_CMD_VENDOR)) ||
7235 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7236 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7237 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7238 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7239 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7240 nla_put_u8(msg,
7241 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MAC_PADDING_DUR,
7242 val)) {
7243 sigma_dut_print(dut, DUT_MSG_ERROR,
7244 "%s: err in adding vendor_cmd and vendor_data, val: %d",
7245 __func__, val);
7246 nlmsg_free(msg);
7247 return -1;
7248 }
7249 nla_nest_end(msg, params);
7250
7251 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7252 if (ret) {
7253 sigma_dut_print(dut, DUT_MSG_ERROR,
7254 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
7255 __func__, ret, val);
7256 }
7257 return ret;
Arif Hussain68d23f52018-07-11 13:39:08 -07007258}
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07007259#endif /* NL80211_SUPPORT */
Arif Hussain68d23f52018-07-11 13:39:08 -07007260
7261
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07007262static int sta_set_tx_su_ppdu_cfg(struct sigma_dut *dut, const char *intf,
7263 int val)
7264{
7265#ifdef NL80211_SUPPORT
7266 struct nl_msg *msg;
7267 int ret = 0;
7268 struct nlattr *params;
7269 int ifindex;
7270
7271 ifindex = if_nametoindex(intf);
7272 if (ifindex == 0) {
7273 sigma_dut_print(dut, DUT_MSG_ERROR,
7274 "%s: Index for interface %s failed, val:%d",
7275 __func__, intf, val);
7276 return -1;
7277 }
7278
7279 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7280 NL80211_CMD_VENDOR)) ||
7281 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7282 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7283 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7284 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7285 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7286 nla_put_u8(msg,
7287 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_SUPPDU,
7288 val)) {
7289 sigma_dut_print(dut, DUT_MSG_ERROR,
7290 "%s: err in adding vendor_cmd and vendor_data, val: %d",
7291 __func__, val);
7292 nlmsg_free(msg);
7293 return -1;
7294 }
7295 nla_nest_end(msg, params);
7296
7297 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7298 if (ret) {
7299 sigma_dut_print(dut, DUT_MSG_ERROR,
7300 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
7301 __func__, ret, val);
7302 }
7303 return ret;
7304#else /* NL80211_SUPPORT */
7305 sigma_dut_print(dut, DUT_MSG_ERROR,
7306 "Tx SU PPDU cannot be set without NL80211_SUPPORT defined");
7307 return -1;
7308#endif /* NL80211_SUPPORT */
7309}
7310
7311
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07007312#ifdef NL80211_SUPPORT
7313static int sta_set_he_om_ctrl_reset(struct sigma_dut *dut, const char *intf)
7314{
7315 struct nl_msg *msg;
7316 int ret = 0;
7317 struct nlattr *params;
7318 int ifindex;
7319
7320 ifindex = if_nametoindex(intf);
7321 if (ifindex == 0) {
7322 sigma_dut_print(dut, DUT_MSG_ERROR,
7323 "%s: Index for interface %s failed",
7324 __func__, intf);
7325 return -1;
7326 }
7327
7328 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7329 NL80211_CMD_VENDOR)) ||
7330 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7331 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7332 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7333 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7334 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7335 nla_put_flag(msg,
7336 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_CLEAR_HE_OM_CTRL_CONFIG)) {
7337 sigma_dut_print(dut, DUT_MSG_ERROR,
7338 "%s: err in adding vendor_cmd and vendor_data",
7339 __func__);
7340 nlmsg_free(msg);
7341 return -1;
7342 }
7343 nla_nest_end(msg, params);
7344
7345 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7346 if (ret) {
7347 sigma_dut_print(dut, DUT_MSG_ERROR,
7348 "%s: err in send_and_recv_msgs, ret=%d",
7349 __func__, ret);
7350 }
7351 return ret;
7352}
7353#endif /* NL80211_SUPPORT */
7354
7355
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07007356static int sta_set_mu_edca_override(struct sigma_dut *dut, const char *intf,
7357 int val)
7358{
7359#ifdef NL80211_SUPPORT
7360 struct nl_msg *msg;
7361 int ret = 0;
7362 struct nlattr *params;
7363 int ifindex;
7364
7365 ifindex = if_nametoindex(intf);
7366 if (ifindex == 0) {
7367 sigma_dut_print(dut, DUT_MSG_ERROR,
7368 "%s: Index for interface %s failed, val:%d",
7369 __func__, intf, val);
7370 return -1;
7371 }
7372
7373 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7374 NL80211_CMD_VENDOR)) ||
7375 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7376 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7377 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7378 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7379 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7380 nla_put_u8(msg,
7381 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_OVERRIDE_MU_EDCA,
7382 val)) {
7383 sigma_dut_print(dut, DUT_MSG_ERROR,
7384 "%s: err in adding vendor_cmd and vendor_data, val: %d",
7385 __func__, val);
7386 nlmsg_free(msg);
7387 return -1;
7388 }
7389 nla_nest_end(msg, params);
7390
7391 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7392 if (ret) {
7393 sigma_dut_print(dut, DUT_MSG_ERROR,
7394 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
7395 __func__, ret, val);
7396 }
7397 return ret;
7398#else /* NL80211_SUPPORT */
7399 sigma_dut_print(dut, DUT_MSG_ERROR,
7400 "MU EDCA override cannot be changed without NL80211_SUPPORT defined");
7401 return -1;
7402#endif /* NL80211_SUPPORT */
7403}
7404
7405
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07007406static int sta_set_om_ctrl_supp(struct sigma_dut *dut, const char *intf,
7407 int val)
7408{
7409#ifdef NL80211_SUPPORT
7410 struct nl_msg *msg;
7411 int ret = 0;
7412 struct nlattr *params;
7413 int ifindex;
7414
7415 ifindex = if_nametoindex(intf);
7416 if (ifindex == 0) {
7417 sigma_dut_print(dut, DUT_MSG_ERROR,
7418 "%s: Index for interface %s failed, val:%d",
7419 __func__, intf, val);
7420 return -1;
7421 }
7422
7423 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7424 NL80211_CMD_VENDOR)) ||
7425 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7426 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7427 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7428 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7429 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7430 nla_put_u8(msg,
7431 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OM_CTRL_SUPP,
7432 val)) {
7433 sigma_dut_print(dut, DUT_MSG_ERROR,
7434 "%s: err in adding vendor_cmd and vendor_data, val: %d",
7435 __func__, val);
7436 nlmsg_free(msg);
7437 return -1;
7438 }
7439 nla_nest_end(msg, params);
7440
7441 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7442 if (ret) {
7443 sigma_dut_print(dut, DUT_MSG_ERROR,
7444 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
7445 __func__, ret, val);
7446 }
7447 return ret;
7448#else /* NL80211_SUPPORT */
7449 sigma_dut_print(dut, DUT_MSG_ERROR,
7450 "HE OM ctrl cannot be changed without NL80211_SUPPORT defined");
7451 return -1;
7452#endif /* NL80211_SUPPORT */
7453}
7454
7455
Arif Hussain480d5f42019-03-12 14:40:42 -07007456static int sta_set_twt_req_support(struct sigma_dut *dut, const char *intf,
7457 int val)
7458{
7459#ifdef NL80211_SUPPORT
7460 struct nl_msg *msg;
7461 int ret;
7462 struct nlattr *params;
7463 int ifindex;
7464
7465 ifindex = if_nametoindex(intf);
7466 if (ifindex == 0) {
7467 sigma_dut_print(dut, DUT_MSG_ERROR,
7468 "%s: Index for interface %s failed, val:%d",
7469 __func__, intf, val);
7470 return -1;
7471 }
7472
7473 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7474 NL80211_CMD_VENDOR)) ||
7475 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7476 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7477 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7478 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7479 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7480 nla_put_u8(msg,
7481 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TWT_REQ_SUPPORT,
7482 val)) {
7483 sigma_dut_print(dut, DUT_MSG_ERROR,
7484 "%s: err in adding vendor_cmd and vendor_data, val: %d",
7485 __func__, val);
7486 nlmsg_free(msg);
7487 return -1;
7488 }
7489 nla_nest_end(msg, params);
7490
7491 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7492 if (ret) {
7493 sigma_dut_print(dut, DUT_MSG_ERROR,
7494 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
7495 __func__, ret, val);
7496 }
7497 return ret;
7498#else /* NL80211_SUPPORT */
7499 sigma_dut_print(dut, DUT_MSG_ERROR,
7500 "TWT Request cannot be changed without NL80211_SUPPORT defined");
7501 return -1;
7502#endif /* NL80211_SUPPORT */
7503}
7504
7505
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08007506static void sta_reset_default_wcn(struct sigma_dut *dut, const char *intf,
7507 const char *type)
7508{
7509 char buf[60];
7510
7511 if (dut->program == PROGRAM_HE) {
7512 /* resetting phymode to auto in case of HE program */
7513 snprintf(buf, sizeof(buf), "iwpriv %s setphymode 0", intf);
7514 if (system(buf) != 0) {
7515 sigma_dut_print(dut, DUT_MSG_ERROR,
7516 "iwpriv %s setphymode failed", intf);
7517 }
7518
Amarnath Hullur Subramanyam9cecb502018-04-25 13:26:30 -07007519 /* reset the rate to Auto rate */
7520 snprintf(buf, sizeof(buf), "iwpriv %s set_11ax_rate 0xff",
7521 intf);
7522 if (system(buf) != 0) {
7523 sigma_dut_print(dut, DUT_MSG_ERROR,
7524 "iwpriv %s set_11ax_rate 0xff failed",
7525 intf);
7526 }
7527
Kiran Kumar Lokere86cfe3a2018-06-01 11:55:15 -07007528 /* reset the LDPC setting */
7529 snprintf(buf, sizeof(buf), "iwpriv %s ldpc 1", intf);
7530 if (system(buf) != 0) {
7531 sigma_dut_print(dut, DUT_MSG_ERROR,
7532 "iwpriv %s ldpc 1 failed", intf);
7533 }
7534
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08007535 /* reset the power save setting */
7536 snprintf(buf, sizeof(buf), "iwpriv %s setPower 2", intf);
7537 if (system(buf) != 0) {
7538 sigma_dut_print(dut, DUT_MSG_ERROR,
7539 "iwpriv %s setPower 2 failed", intf);
7540 }
7541
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08007542 /* remove all network profiles */
7543 remove_wpa_networks(intf);
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08007544
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08007545 /* Configure ADDBA Req/Rsp buffer size to be 64 */
7546 sta_set_addba_buf_size(dut, intf, 64);
7547
Amarnath Hullur Subramanyam5f32d572018-03-02 00:02:33 -08007548#ifdef NL80211_SUPPORT
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08007549 /* Reset the device HE capabilities to its default supported
7550 * configuration. */
7551 sta_set_he_testbed_def(dut, intf, 0);
7552
Amarnath Hullur Subramanyam5f32d572018-03-02 00:02:33 -08007553 /* Disable noackpolicy for all AC */
7554 if (nlvendor_sta_set_noack(dut, intf, 0, QCA_WLAN_AC_ALL)) {
7555 sigma_dut_print(dut, DUT_MSG_ERROR,
7556 "Disable of noackpolicy for all AC failed");
7557 }
7558#endif /* NL80211_SUPPORT */
7559
Amarnath Hullur Subramanyamb1724a52018-03-07 14:31:46 -08007560 /* Enable WMM by default */
7561 if (wcn_sta_set_wmm(dut, intf, "on")) {
7562 sigma_dut_print(dut, DUT_MSG_ERROR,
7563 "Enable of WMM in sta_reset_default_wcn failed");
7564 }
7565
7566 /* Disable ADDBA_REJECT by default */
7567 if (nlvendor_sta_set_addba_reject(dut, intf, 0)) {
7568 sigma_dut_print(dut, DUT_MSG_ERROR,
7569 "Disable of addba_reject in sta_reset_default_wcn failed");
7570 }
7571
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08007572 /* Enable sending of ADDBA by default */
7573 if (nlvendor_config_send_addba(dut, intf, 1)) {
7574 sigma_dut_print(dut, DUT_MSG_ERROR,
7575 "Enable sending of ADDBA in sta_reset_default_wcn failed");
7576 }
7577
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08007578 /* Enable AMPDU by default */
7579 iwpriv_sta_set_ampdu(dut, intf, 1);
7580
Subhani Shaik8e7a3052018-04-24 14:03:00 -07007581#ifdef NL80211_SUPPORT
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -08007582 if (wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_AUTO)) {
Subhani Shaik8e7a3052018-04-24 14:03:00 -07007583 sigma_dut_print(dut, DUT_MSG_ERROR,
7584 "Set LTF config to default in sta_reset_default_wcn failed");
7585 }
Arif Hussain9765f7d2018-07-03 08:28:26 -07007586
Kiran Kumar Lokerebad51122018-12-12 19:03:36 -08007587 /* set the beamformee NSTS(maximum number of
7588 * space-time streams) to default DUT config
7589 */
7590 if (sta_set_beamformee_sts(dut, intf, 7)) {
Arif Hussain9765f7d2018-07-03 08:28:26 -07007591 sigma_dut_print(dut, DUT_MSG_ERROR,
7592 "Failed to set BeamformeeSTS");
7593 }
Arif Hussain68d23f52018-07-11 13:39:08 -07007594
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07007595 if (sta_set_mac_padding_duration(
7596 dut, intf,
7597 QCA_WLAN_HE_NO_ADDITIONAL_PROCESS_TIME)) {
Arif Hussain68d23f52018-07-11 13:39:08 -07007598 sigma_dut_print(dut, DUT_MSG_ERROR,
7599 "Failed to set MAC padding duration");
7600 }
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07007601
7602 if (sta_set_mu_edca_override(dut, intf, 0)) {
7603 sigma_dut_print(dut, DUT_MSG_ERROR,
7604 "ErrorCode,Failed to set MU EDCA override disable");
7605 }
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07007606
7607 if (sta_set_om_ctrl_supp(dut, intf, 1)) {
7608 sigma_dut_print(dut, DUT_MSG_ERROR,
7609 "Failed to set OM ctrl supp");
7610 }
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07007611
7612 if (sta_set_tx_su_ppdu_cfg(dut, intf, 1)) {
7613 sigma_dut_print(dut, DUT_MSG_ERROR,
7614 "Failed to set Tx SU PPDU enable");
7615 }
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07007616
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07007617 if (sta_set_action_tx_in_he_tb_ppdu(dut, intf, 0)) {
7618 sigma_dut_print(dut, DUT_MSG_ERROR,
7619 "failed to send TB PPDU Tx cfg");
7620 }
7621
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07007622 if (sta_set_he_om_ctrl_reset(dut, intf)) {
7623 sigma_dut_print(dut, DUT_MSG_ERROR,
7624 "Failed to set OM ctrl reset");
7625 }
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08007626
7627 /* +HTC-HE support default on */
7628 if (sta_set_he_htc_supp(dut, intf, 1)) {
7629 sigma_dut_print(dut, DUT_MSG_ERROR,
7630 "Setting of +HTC-HE support failed");
7631 }
Subhani Shaik8e7a3052018-04-24 14:03:00 -07007632#endif /* NL80211_SUPPORT */
7633
Arif Hussain8d5b27b2018-05-14 14:31:03 -07007634 if (sta_set_tx_beamformee(dut, intf, 1)) {
7635 sigma_dut_print(dut, DUT_MSG_ERROR,
7636 "Set tx beamformee enable by default in sta_reset_default_wcn failed");
7637 }
7638
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08007639 /* Set nss to 1 and MCS 0-7 in case of testbed */
7640 if (type && strcasecmp(type, "Testbed") == 0) {
7641#ifdef NL80211_SUPPORT
7642 int ret;
7643#endif /* NL80211_SUPPORT */
7644
7645 snprintf(buf, sizeof(buf), "iwpriv %s nss 1", intf);
7646 if (system(buf) != 0) {
7647 sigma_dut_print(dut, DUT_MSG_ERROR,
7648 "iwpriv %s nss failed", intf);
7649 }
7650
7651#ifdef NL80211_SUPPORT
7652 ret = sta_set_he_mcs(dut, intf, HE_80_MCS0_7);
7653 if (ret) {
7654 sigma_dut_print(dut, DUT_MSG_ERROR,
7655 "Setting of MCS failed, ret:%d",
7656 ret);
7657 }
7658#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyamc67621d2018-02-04 23:18:01 -08007659
7660 /* Disable STBC as default */
7661 wcn_sta_set_stbc(dut, intf, "0");
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08007662
7663 /* Disable AMSDU as default */
7664 iwpriv_sta_set_amsdu(dut, intf, "0");
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08007665
7666#ifdef NL80211_SUPPORT
7667 /* HE fragmentation default off */
7668 if (sta_set_he_fragmentation(dut, intf,
7669 HE_FRAG_DISABLE)) {
7670 sigma_dut_print(dut, DUT_MSG_ERROR,
7671 "Setting of HE fragmentation failed");
7672 }
Kiran Kumar Lokerebad51122018-12-12 19:03:36 -08007673
7674 /* set the beamformee NSTS(maximum number of
7675 * space-time streams) to default testbed config
7676 */
7677 if (sta_set_beamformee_sts(dut, intf, 3)) {
7678 sigma_dut_print(dut, DUT_MSG_ERROR,
7679 "Failed to set BeamformeeSTS");
7680 }
7681
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08007682 /* +HTC-HE support default off */
7683 if (sta_set_he_htc_supp(dut, intf, 0)) {
7684 sigma_dut_print(dut, DUT_MSG_ERROR,
7685 "Setting of +HTC-HE support failed");
7686 }
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08007687
7688 /* Set device HE capabilities to testbed default
7689 * configuration. */
7690 if (sta_set_he_testbed_def(dut, intf, 1)) {
7691 sigma_dut_print(dut, DUT_MSG_DEBUG,
7692 "Failed to set HE defaults");
7693 }
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08007694
7695 /* Disable VHT support in 2.4 GHz for testbed */
7696 sta_set_2g_vht_supp(dut, intf, 0);
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08007697#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08007698
7699 /* Enable WEP/TKIP with HE capability in testbed */
7700 if (sta_set_heconfig_and_wep_tkip(dut, intf, 1)) {
7701 sigma_dut_print(dut, DUT_MSG_ERROR,
7702 "Enabling HE config with WEP/TKIP failed");
7703 }
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08007704 }
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08007705
7706 /* Defaults in case of DUT */
7707 if (type && strcasecmp(type, "DUT") == 0) {
Arif Hussaind48fcc72018-05-01 18:34:18 -07007708 /* Enable STBC by default */
7709 wcn_sta_set_stbc(dut, intf, "1");
7710
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08007711 /* set nss to 2 */
7712 snprintf(buf, sizeof(buf), "iwpriv %s nss 2", intf);
7713 if (system(buf) != 0) {
7714 sigma_dut_print(dut, DUT_MSG_ERROR,
7715 "iwpriv %s nss 2 failed", intf);
7716 }
Arif Hussainac6c5112018-05-25 17:34:00 -07007717 dut->sta_nss = 2;
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08007718
7719#ifdef NL80211_SUPPORT
Arif Hussainae239842018-05-01 18:20:05 -07007720 /* Set HE_MCS to 0-11 */
7721 if (sta_set_he_mcs(dut, intf, HE_80_MCS0_11)) {
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08007722 sigma_dut_print(dut, DUT_MSG_ERROR,
7723 "Setting of MCS failed");
7724 }
7725#endif /* NL80211_SUPPORT */
7726
7727 /* Disable WEP/TKIP with HE capability in DUT */
7728 if (sta_set_heconfig_and_wep_tkip(dut, intf, 0)) {
7729 sigma_dut_print(dut, DUT_MSG_ERROR,
7730 "Enabling HE config with WEP/TKIP failed");
7731 }
7732 }
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08007733 }
7734}
7735
7736
Jouni Malinenf7222712019-06-13 01:50:21 +03007737static enum sigma_cmd_result cmd_sta_reset_default(struct sigma_dut *dut,
7738 struct sigma_conn *conn,
7739 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007740{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007741 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007742 const char *band = get_param(cmd, "band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007743 const char *type;
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07007744 const char *program = get_param(cmd, "program");
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05307745 const char *dev_role = get_param(cmd, "DevRole");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007746
Jouni Malinenb21f0542019-11-04 17:53:38 +02007747 if (dut->station_ifname_2g &&
7748 strcmp(dut->station_ifname_2g, intf) == 0)
7749 dut->use_5g = 0;
7750 else if (dut->station_ifname_5g &&
7751 strcmp(dut->station_ifname_5g, intf) == 0)
7752 dut->use_5g = 1;
7753
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07007754 if (!program)
7755 program = get_param(cmd, "prog");
7756 dut->program = sigma_program_to_enum(program);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007757 dut->device_type = STA_unknown;
7758 type = get_param(cmd, "type");
7759 if (type && strcasecmp(type, "Testbed") == 0)
7760 dut->device_type = STA_testbed;
7761 if (type && strcasecmp(type, "DUT") == 0)
7762 dut->device_type = STA_dut;
7763
7764 if (dut->program == PROGRAM_TDLS) {
7765 /* Clear TDLS testing mode */
7766 wpa_command(intf, "SET tdls_disabled 0");
7767 wpa_command(intf, "SET tdls_testing 0");
7768 dut->no_tpk_expiration = 0;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007769 if (get_driver_type(dut) == DRIVER_WCN) {
Pradeep Reddy POTTETI8ce2a232016-10-28 12:17:32 +05307770 /* Enable the WCN driver in TDLS Explicit trigger mode
7771 */
7772 wpa_command(intf, "SET tdls_external_control 0");
7773 wpa_command(intf, "SET tdls_trigger_control 0");
7774 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007775 }
7776
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07007777#ifdef MIRACAST
7778 if (dut->program == PROGRAM_WFD ||
7779 dut->program == PROGRAM_DISPLAYR2)
7780 miracast_sta_reset_default(dut, conn, cmd);
7781#endif /* MIRACAST */
7782
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007783 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007784 case DRIVER_ATHEROS:
7785 sta_reset_default_ath(dut, intf, type);
7786 break;
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08007787 case DRIVER_WCN:
7788 sta_reset_default_wcn(dut, intf, type);
7789 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007790 default:
7791 break;
7792 }
7793
7794#ifdef ANDROID_NAN
7795 if (dut->program == PROGRAM_NAN)
7796 nan_cmd_sta_reset_default(dut, conn, cmd);
7797#endif /* ANDROID_NAN */
7798
Vinay Gannevaram3b9fdd32019-06-14 17:55:44 +05307799 if (dut->program == PROGRAM_LOC &&
7800 lowi_cmd_sta_reset_default(dut, conn, cmd) < 0)
7801 return ERROR_SEND_STATUS;
7802
Jouni Malinenba630452018-06-22 11:49:59 +03007803 if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007804 unlink("SP/wi-fi.org/pps.xml");
7805 if (system("rm -r SP/*") != 0) {
7806 }
7807 unlink("next-client-cert.pem");
7808 unlink("next-client-key.pem");
7809 }
7810
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007811 /* For WPS program of the 60 GHz band the band type needs to be saved */
7812 if (dut->program == PROGRAM_WPS) {
7813 if (band && strcasecmp(band, "60GHz") == 0) {
7814 dut->band = WPS_BAND_60G;
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02007815 /* For 60 GHz enable WPS for WPS TCs */
7816 dut->wps_disable = 0;
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007817 } else {
7818 dut->band = WPS_BAND_NON_60G;
7819 }
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02007820 } else if (dut->program == PROGRAM_60GHZ) {
7821 /* For 60 GHz MAC/PHY TCs WPS must be disabled */
7822 dut->wps_disable = 1;
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007823 }
7824
Alexei Avshalom Lazar157ba062018-12-23 16:15:26 +02007825 if (is_60g_sigma_dut(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007826 const char *dev_role = get_param(cmd, "DevRole");
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02007827 char buf[256];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007828
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02007829 sigma_dut_print(dut, DUT_MSG_INFO,
7830 "WPS 60 GHz program, wps_disable = %d",
7831 dut->wps_disable);
7832
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007833 if (!dev_role) {
7834 send_resp(dut, conn, SIGMA_ERROR,
7835 "errorCode,Missing DevRole argument");
7836 return 0;
7837 }
7838
7839 if (strcasecmp(dev_role, "STA") == 0)
7840 dut->dev_role = DEVROLE_STA;
7841 else if (strcasecmp(dev_role, "PCP") == 0)
7842 dut->dev_role = DEVROLE_PCP;
7843 else {
7844 send_resp(dut, conn, SIGMA_ERROR,
7845 "errorCode,Unknown DevRole");
7846 return 0;
7847 }
7848
7849 if (dut->device_type == STA_unknown) {
7850 sigma_dut_print(dut, DUT_MSG_ERROR,
7851 "Device type is not STA testbed or DUT");
7852 send_resp(dut, conn, SIGMA_ERROR,
7853 "errorCode,Unknown device type");
7854 return 0;
7855 }
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02007856
7857 sigma_dut_print(dut, DUT_MSG_DEBUG,
7858 "Setting msdu_size to MAX: 7912");
7859 snprintf(buf, sizeof(buf), "ifconfig %s mtu 7912",
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007860 get_station_ifname(dut));
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02007861
7862 if (system(buf) != 0) {
7863 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
7864 buf);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007865 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02007866 }
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02007867
7868 if (sta_set_force_mcs(dut, 0, 1)) {
7869 sigma_dut_print(dut, DUT_MSG_ERROR,
7870 "Failed to reset force MCS");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007871 return ERROR_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02007872 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007873 }
7874
7875 wpa_command(intf, "WPS_ER_STOP");
7876 wpa_command(intf, "FLUSH");
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05307877 wpa_command(intf, "ERP_FLUSH");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007878 wpa_command(intf, "SET radio_disabled 0");
7879
Alexei Avshalom Lazar744ae8a2019-01-31 17:26:46 +02007880 dut->wps_forced_version = 0;
7881
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007882 if (dut->wsc_fragment) {
7883 dut->wsc_fragment = 0;
7884 wpa_command(intf, "SET device_name Test client");
7885 wpa_command(intf, "SET manufacturer ");
7886 wpa_command(intf, "SET model_name ");
7887 wpa_command(intf, "SET model_number ");
7888 wpa_command(intf, "SET serial_number ");
7889 }
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02007890 if (is_60g_sigma_dut(dut) && dut->force_rsn_ie) {
7891 dut->force_rsn_ie = FORCE_RSN_IE_NONE;
7892 sta_60g_force_rsn_ie(dut, FORCE_RSN_IE_NONE);
7893 }
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007894
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007895 if (dut->tmp_mac_addr && dut->set_macaddr) {
7896 dut->tmp_mac_addr = 0;
7897 if (system(dut->set_macaddr) != 0) {
7898 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to clear "
7899 "temporary MAC address");
7900 }
7901 }
7902
7903 set_ps(intf, dut, 0);
7904
Jouni Malinenba630452018-06-22 11:49:59 +03007905 if (dut->program == PROGRAM_HS2 || dut->program == PROGRAM_HS2_R2 ||
7906 dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007907 wpa_command(intf, "SET interworking 1");
7908 wpa_command(intf, "SET hs20 1");
7909 }
7910
Deepak Dhamdhere0fe0e452017-12-18 14:52:09 -08007911 if (dut->program == PROGRAM_HS2_R2 ||
Jouni Malinenba630452018-06-22 11:49:59 +03007912 dut->program == PROGRAM_HS2_R3 ||
Deepak Dhamdhere0fe0e452017-12-18 14:52:09 -08007913 dut->program == PROGRAM_OCE) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007914 wpa_command(intf, "SET pmf 1");
7915 } else {
7916 wpa_command(intf, "SET pmf 0");
7917 }
7918
7919 hs2_clear_credentials(intf);
7920 wpa_command(intf, "SET hessid 00:00:00:00:00:00");
7921 wpa_command(intf, "SET access_network_type 15");
7922
7923 static_ip_file(0, NULL, NULL, NULL);
7924 kill_dhcp_client(dut, intf);
7925 clear_ip_addr(dut, intf);
7926
7927 dut->er_oper_performed = 0;
7928 dut->er_oper_bssid[0] = '\0';
7929
priyadharshini gowthamanad6cbba2016-10-04 10:39:58 -07007930 if (dut->program == PROGRAM_LOC) {
7931 /* Disable Interworking by default */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007932 wpa_command(get_station_ifname(dut), "SET interworking 0");
priyadharshini gowthamanad6cbba2016-10-04 10:39:58 -07007933 }
7934
Ashwini Patil00402582017-04-13 12:29:39 +05307935 if (dut->program == PROGRAM_MBO) {
7936 free(dut->non_pref_ch_list);
7937 dut->non_pref_ch_list = NULL;
Ashwini Patil5acd7382017-04-13 15:55:04 +05307938 free(dut->btm_query_cand_list);
7939 dut->btm_query_cand_list = NULL;
Ashwini Patilc63161e2017-04-13 16:30:23 +05307940 wpa_command(intf, "SET reject_btm_req_reason 0");
Ashwini Patila75de5a2017-04-13 16:35:05 +05307941 wpa_command(intf, "SET ignore_assoc_disallow 0");
Ashwini Patild174f2c2017-04-13 16:49:46 +05307942 wpa_command(intf, "SET gas_address3 0");
Ashwini Patil9183fdb2017-04-13 16:58:25 +05307943 wpa_command(intf, "SET roaming 1");
Ankita Bajaj1d974552018-09-18 16:56:44 +05307944 wpa_command(intf, "SET interworking 1");
Ashwini Patil00402582017-04-13 12:29:39 +05307945 }
7946
Jouni Malinen3c367e82017-06-23 17:01:47 +03007947 free(dut->rsne_override);
7948 dut->rsne_override = NULL;
7949
Jouni Malinen68143132017-09-02 02:34:08 +03007950 free(dut->sae_commit_override);
7951 dut->sae_commit_override = NULL;
Jouni Malinen4b3769d2019-10-10 16:20:29 +03007952 wpa_command(intf, "SET sae_pmkid_in_assoc 0");
Jouni Malinen11e55212019-11-22 21:46:59 +02007953 dut->sae_pwe = SAE_PWE_DEFAULT;
Jouni Malinen68143132017-09-02 02:34:08 +03007954
Jouni Malinen134fe3c2019-06-12 04:16:49 +03007955 dut->sta_associate_wait_connect = 0;
7956 dut->server_cert_hash[0] = '\0';
Jouni Malinen37d5c692019-08-19 16:56:55 +03007957 dut->server_cert_tod = 0;
Jouni Malinen134fe3c2019-06-12 04:16:49 +03007958 dut->sta_tod_policy = 0;
7959
Jouni Malinend86e5822017-08-29 03:55:32 +03007960 dut->dpp_conf_id = -1;
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02007961 free(dut->dpp_peer_uri);
7962 dut->dpp_peer_uri = NULL;
Jouni Malinen63d50412017-11-24 11:55:38 +02007963 dut->dpp_local_bootstrap = -1;
Jouni Malinen5011fb52017-12-05 21:00:15 +02007964 wpa_command(intf, "SET dpp_config_processing 2");
Jouni Malinen90776b12020-05-04 15:34:46 +03007965 wpa_command(intf, "SET dpp_mud_url ");
Jouni Malinend86e5822017-08-29 03:55:32 +03007966
Jouni Malinenfac9cad2017-10-10 18:35:55 +03007967 wpa_command(intf, "VENDOR_ELEM_REMOVE 13 *");
7968
vamsi krishnaa2799492017-12-05 14:28:01 +05307969 if (dut->program == PROGRAM_OCE) {
Ankita Bajaja2cb5672017-10-25 16:08:28 +05307970 wpa_command(intf, "SET oce 1");
vamsi krishnaa2799492017-12-05 14:28:01 +05307971 wpa_command(intf, "SET disable_fils 0");
Ankita Bajaj1bde7942018-01-09 19:15:01 +05307972 wpa_command(intf, "FILS_HLP_REQ_FLUSH");
7973 dut->fils_hlp = 0;
7974#ifdef ANDROID
7975 hlp_thread_cleanup(dut);
7976#endif /* ANDROID */
vamsi krishnaa2799492017-12-05 14:28:01 +05307977 }
Ankita Bajaja2cb5672017-10-25 16:08:28 +05307978
Vamsi Krishnaf642d6a2020-03-27 12:33:14 +05307979 if (dut->program == PROGRAM_QM)
7980 wpa_command(intf, "SET interworking 1");
7981
Jouni Malinen8179fee2019-03-28 03:19:47 +02007982 dut->akm_values = 0;
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007983 dut->sta_ft_ds = 0;
Jouni Malinen8179fee2019-03-28 03:19:47 +02007984
Sunil Dutt076081f2018-02-05 19:45:50 +05307985#ifdef NL80211_SUPPORT
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007986 if (get_driver_type(dut) == DRIVER_WCN &&
Sunil Dutt44595082018-02-12 19:41:45 +05307987 dut->config_rsnie == 1) {
7988 dut->config_rsnie = 0;
7989 sta_config_rsnie(dut, 0);
Sunil Dutt076081f2018-02-05 19:45:50 +05307990 }
7991#endif /* NL80211_SUPPORT */
7992
Sunil Duttfebf8a82018-02-09 18:50:13 +05307993 if (dev_role && strcasecmp(dev_role, "STA-CFON") == 0) {
7994 dut->dev_role = DEVROLE_STA_CFON;
7995 return sta_cfon_reset_default(dut, conn, cmd);
7996 }
7997
Jouni Malinen439352d2018-09-13 03:42:23 +03007998 wpa_command(intf, "SET setband AUTO");
7999
Sunil Duttfebf8a82018-02-09 18:50:13 +05308000 if (dut->program != PROGRAM_VHT)
8001 return cmd_sta_p2p_reset(dut, conn, cmd);
8002
Priyadharshini Gowthamana7dfd492015-11-09 14:34:08 -08008003 return 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008004}
8005
8006
Jouni Malinenf7222712019-06-13 01:50:21 +03008007static enum sigma_cmd_result cmd_sta_get_events(struct sigma_dut *dut,
8008 struct sigma_conn *conn,
8009 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008010{
8011 const char *program = get_param(cmd, "Program");
8012
8013 if (program == NULL)
8014 return -1;
8015#ifdef ANDROID_NAN
8016 if (strcasecmp(program, "NAN") == 0)
8017 return nan_cmd_sta_get_events(dut, conn, cmd);
8018#endif /* ANDROID_NAN */
8019 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
8020 return 0;
8021}
8022
8023
Jouni Malinen82905202018-04-29 17:20:10 +03008024static int sta_exec_action_url(struct sigma_dut *dut, struct sigma_conn *conn,
8025 struct sigma_cmd *cmd)
8026{
8027 const char *url = get_param(cmd, "url");
8028 const char *method = get_param(cmd, "method");
8029 pid_t pid;
8030 int status;
8031
8032 if (!url || !method)
8033 return -1;
8034
8035 /* TODO: Add support for method,post */
8036 if (strcasecmp(method, "get") != 0) {
8037 send_resp(dut, conn, SIGMA_ERROR,
8038 "ErrorCode,Unsupported method");
8039 return 0;
8040 }
8041
8042 pid = fork();
8043 if (pid < 0) {
8044 perror("fork");
8045 return -1;
8046 }
8047
8048 if (pid == 0) {
8049 char * argv[5] = { "wget", "-O", "/dev/null",
8050 (char *) url, NULL };
8051
8052 execv("/usr/bin/wget", argv);
8053 perror("execv");
8054 exit(0);
8055 return -1;
8056 }
8057
8058 if (waitpid(pid, &status, 0) < 0) {
8059 perror("waitpid");
8060 return -1;
8061 }
8062
8063 if (WIFEXITED(status)) {
8064 const char *errmsg;
8065
8066 if (WEXITSTATUS(status) == 0)
8067 return 1;
8068 sigma_dut_print(dut, DUT_MSG_INFO, "wget exit status %d",
8069 WEXITSTATUS(status));
8070 switch (WEXITSTATUS(status)) {
8071 case 4:
8072 errmsg = "errmsg,Network failure";
8073 break;
8074 case 8:
8075 errmsg = "errmsg,Server issued an error response";
8076 break;
8077 default:
8078 errmsg = "errmsg,Unknown failure from wget";
8079 break;
8080 }
8081 send_resp(dut, conn, SIGMA_ERROR, errmsg);
8082 return 0;
8083 }
8084
8085 send_resp(dut, conn, SIGMA_ERROR, "errmsg,Unknown failure");
8086 return 0;
8087}
8088
8089
Jouni Malinenf7222712019-06-13 01:50:21 +03008090static enum sigma_cmd_result cmd_sta_exec_action(struct sigma_dut *dut,
8091 struct sigma_conn *conn,
8092 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008093{
8094 const char *program = get_param(cmd, "Prog");
8095
Jouni Malinen82905202018-04-29 17:20:10 +03008096 if (program && !get_param(cmd, "interface"))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008097 return -1;
8098#ifdef ANDROID_NAN
Jouni Malinen82905202018-04-29 17:20:10 +03008099 if (program && strcasecmp(program, "NAN") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008100 return nan_cmd_sta_exec_action(dut, conn, cmd);
8101#endif /* ANDROID_NAN */
Jouni Malinen82905202018-04-29 17:20:10 +03008102
8103 if (program && strcasecmp(program, "Loc") == 0)
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07008104 return loc_cmd_sta_exec_action(dut, conn, cmd);
Jouni Malinen82905202018-04-29 17:20:10 +03008105
8106 if (get_param(cmd, "url"))
8107 return sta_exec_action_url(dut, conn, cmd);
8108
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008109 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
8110 return 0;
8111}
8112
8113
Jouni Malinenf7222712019-06-13 01:50:21 +03008114static enum sigma_cmd_result cmd_sta_set_11n(struct sigma_dut *dut,
8115 struct sigma_conn *conn,
8116 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008117{
8118 const char *intf = get_param(cmd, "Interface");
8119 const char *val, *mcs32, *rate;
8120
8121 val = get_param(cmd, "GREENFIELD");
8122 if (val) {
8123 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
8124 /* Enable GD */
8125 send_resp(dut, conn, SIGMA_ERROR,
8126 "ErrorCode,GF not supported");
8127 return 0;
8128 }
8129 }
8130
8131 val = get_param(cmd, "SGI20");
8132 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02008133 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008134 case DRIVER_ATHEROS:
8135 ath_sta_set_sgi(dut, intf, val);
8136 break;
8137 default:
8138 send_resp(dut, conn, SIGMA_ERROR,
8139 "ErrorCode,SGI20 not supported");
8140 return 0;
8141 }
8142 }
8143
8144 mcs32 = get_param(cmd, "MCS32"); /* HT Duplicate Mode Enable/Disable */
8145 rate = get_param(cmd, "MCS_FIXEDRATE"); /* Fixed MCS rate (0..31) */
8146 if (mcs32 && rate) {
8147 /* TODO */
8148 send_resp(dut, conn, SIGMA_ERROR,
8149 "ErrorCode,MCS32,MCS_FIXEDRATE not supported");
8150 return 0;
8151 } else if (mcs32 && !rate) {
8152 /* TODO */
8153 send_resp(dut, conn, SIGMA_ERROR,
8154 "ErrorCode,MCS32 not supported");
8155 return 0;
8156 } else if (!mcs32 && rate) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02008157 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008158 case DRIVER_ATHEROS:
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -07008159 novap_reset(dut, intf, 1);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008160 ath_sta_set_11nrates(dut, intf, rate);
8161 break;
8162 default:
8163 send_resp(dut, conn, SIGMA_ERROR,
8164 "ErrorCode,MCS32_FIXEDRATE not supported");
8165 return 0;
8166 }
8167 }
8168
8169 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
8170}
8171
8172
Arif Hussain7b47d2d2018-05-09 10:44:02 -07008173static void cmd_set_max_he_mcs(struct sigma_dut *dut, const char *intf,
8174 int mcs_config)
8175{
8176#ifdef NL80211_SUPPORT
8177 int ret;
8178
8179 switch (mcs_config) {
8180 case HE_80_MCS0_7:
8181 case HE_80_MCS0_9:
8182 case HE_80_MCS0_11:
8183 ret = sta_set_he_mcs(dut, intf, mcs_config);
8184 if (ret) {
8185 sigma_dut_print(dut, DUT_MSG_ERROR,
8186 "cmd_set_max_he_mcs: Setting of MCS:%d failed, ret:%d",
8187 mcs_config, ret);
8188 }
8189 break;
8190 default:
8191 sigma_dut_print(dut, DUT_MSG_ERROR,
8192 "cmd_set_max_he_mcs: Invalid mcs %d",
8193 mcs_config);
8194 break;
8195 }
8196#else /* NL80211_SUPPORT */
8197 sigma_dut_print(dut, DUT_MSG_ERROR,
8198 "max HE MCS cannot be changed without NL80211_SUPPORT defined");
8199#endif /* NL80211_SUPPORT */
8200}
8201
8202
Arif Hussain480d5f42019-03-12 14:40:42 -07008203static int sta_twt_request(struct sigma_dut *dut, struct sigma_conn *conn,
8204 struct sigma_cmd *cmd)
8205{
8206#ifdef NL80211_SUPPORT
8207 struct nlattr *params;
8208 struct nlattr *attr;
8209 struct nlattr *attr1;
8210 struct nl_msg *msg;
8211 int ifindex, ret;
8212 const char *val;
8213 const char *intf = get_param(cmd, "Interface");
8214 int wake_interval_exp = 10, nominal_min_wake_dur = 255,
8215 wake_interval_mantissa = 512;
8216 int flow_type = 0, twt_trigger = 0, target_wake_time = 0,
8217 protection = 0;
8218
8219 ifindex = if_nametoindex(intf);
8220 if (ifindex == 0) {
8221 sigma_dut_print(dut, DUT_MSG_ERROR,
8222 "%s: Index for interface %s failed",
8223 __func__, intf);
8224 return -1;
8225 }
8226
8227 val = get_param(cmd, "FlowType");
8228 if (val) {
8229 flow_type = atoi(val);
8230 if (flow_type != 0 && flow_type != 1) {
8231 sigma_dut_print(dut, DUT_MSG_ERROR,
8232 "TWT: Invalid FlowType %d", flow_type);
8233 return -1;
8234 }
8235 }
8236
8237 val = get_param(cmd, "TWT_Trigger");
8238 if (val) {
8239 twt_trigger = atoi(val);
8240 if (twt_trigger != 0 && twt_trigger != 1) {
8241 sigma_dut_print(dut, DUT_MSG_ERROR,
8242 "TWT: Invalid TWT_Trigger %d",
8243 twt_trigger);
8244 return -1;
8245 }
8246 }
8247
8248 val = get_param(cmd, "Protection");
8249 if (val) {
8250 protection = atoi(val);
8251 if (protection != 0 && protection != 1) {
8252 sigma_dut_print(dut, DUT_MSG_ERROR,
8253 "TWT: Invalid Protection %d",
8254 protection);
8255 return -1;
8256 }
8257 }
8258
8259 val = get_param(cmd, "TargetWakeTime");
8260 if (val)
8261 target_wake_time = atoi(val);
8262
8263 val = get_param(cmd, "WakeIntervalMantissa");
8264 if (val)
8265 wake_interval_mantissa = atoi(val);
8266
8267 val = get_param(cmd, "WakeIntervalExp");
8268 if (val)
8269 wake_interval_exp = atoi(val);
8270
8271 val = get_param(cmd, "NominalMinWakeDur");
8272 if (val)
8273 nominal_min_wake_dur = atoi(val);
8274
8275 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8276 NL80211_CMD_VENDOR)) ||
8277 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
8278 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
8279 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
8280 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
8281 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8282 !(params = nla_nest_start(
8283 msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_SETUP)) ||
8284 !(attr1 = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8285 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_EXP,
8286 wake_interval_exp) ||
Arif Hussain480d5f42019-03-12 14:40:42 -07008287 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_REQ_TYPE, 1) ||
Kiran Kumar Lokere2cffae52019-09-26 18:44:15 -07008288 (twt_trigger &&
8289 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TRIGGER)) ||
Arif Hussain480d5f42019-03-12 14:40:42 -07008290 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE,
8291 flow_type) ||
Kiran Kumar Lokere2cffae52019-09-26 18:44:15 -07008292 (protection &&
8293 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_PROTECTION)) ||
Arif Hussain480d5f42019-03-12 14:40:42 -07008294 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME,
8295 target_wake_time) ||
8296 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_DURATION,
8297 nominal_min_wake_dur) ||
8298 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_MANTISSA,
8299 wake_interval_mantissa)) {
8300 sigma_dut_print(dut, DUT_MSG_ERROR,
8301 "%s: err in adding vendor_cmd and vendor_data",
8302 __func__);
8303 nlmsg_free(msg);
8304 return -1;
8305 }
8306 nla_nest_end(msg, attr1);
8307 nla_nest_end(msg, params);
8308 nla_nest_end(msg, attr);
8309
8310 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
8311 if (ret) {
8312 sigma_dut_print(dut, DUT_MSG_ERROR,
8313 "%s: err in send_and_recv_msgs, ret=%d",
8314 __func__, ret);
8315 }
8316
8317 return ret;
8318#else /* NL80211_SUPPORT */
8319 sigma_dut_print(dut, DUT_MSG_ERROR,
8320 "TWT request cannot be done without NL80211_SUPPORT defined");
8321 return -1;
8322#endif /* NL80211_SUPPORT */
8323}
8324
8325
8326static int sta_twt_teardown(struct sigma_dut *dut, struct sigma_conn *conn,
8327 struct sigma_cmd *cmd)
8328{
8329 #ifdef NL80211_SUPPORT
8330 struct nlattr *params;
8331 struct nlattr *attr;
8332 struct nlattr *attr1;
8333 int ifindex, ret;
8334 struct nl_msg *msg;
8335 const char *intf = get_param(cmd, "Interface");
8336
8337 ifindex = if_nametoindex(intf);
8338 if (ifindex == 0) {
8339 sigma_dut_print(dut, DUT_MSG_ERROR,
8340 "%s: Index for interface %s failed",
8341 __func__, intf);
8342 return -1;
8343 }
8344
8345 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8346 NL80211_CMD_VENDOR)) ||
8347 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
8348 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
8349 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
8350 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
8351 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8352 !(params = nla_nest_start(
8353 msg,
8354 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_TERMINATE)) ||
8355 !(attr1 = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8356 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE, 0)) {
8357 sigma_dut_print(dut, DUT_MSG_ERROR,
8358 "%s: err in adding vendor_cmd and vendor_data",
8359 __func__);
8360 nlmsg_free(msg);
8361 return -1;
8362 }
8363 nla_nest_end(msg, attr1);
8364 nla_nest_end(msg, params);
8365 nla_nest_end(msg, attr);
8366
8367 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
8368 if (ret) {
8369 sigma_dut_print(dut, DUT_MSG_ERROR,
8370 "%s: err in send_and_recv_msgs, ret=%d",
8371 __func__, ret);
8372 }
8373
8374 return ret;
8375#else /* NL80211_SUPPORT */
8376 sigma_dut_print(dut, DUT_MSG_ERROR,
8377 "TWT teardown cannot be done without NL80211_SUPPORT defined");
8378 return -1;
8379#endif /* NL80211_SUPPORT */
8380}
8381
8382
Kiran Kumar Lokere50eb2cd2018-12-18 18:31:28 -08008383static int sta_transmit_omi(struct sigma_dut *dut, struct sigma_conn *conn,
8384 struct sigma_cmd *cmd)
8385{
8386#ifdef NL80211_SUPPORT
8387 struct nlattr *params;
8388 struct nlattr *attr;
8389 struct nlattr *attr1;
8390 struct nl_msg *msg;
8391 int ifindex, ret;
8392 const char *val;
8393 const char *intf = get_param(cmd, "Interface");
8394 uint8_t rx_nss = 0xFF, ch_bw = 0xFF, tx_nsts = 0xFF, ulmu_dis = 0,
8395 ulmu_data_dis = 0;
8396
8397 ifindex = if_nametoindex(intf);
8398 if (ifindex == 0) {
8399 sigma_dut_print(dut, DUT_MSG_ERROR,
8400 "%s: Index for interface %s failed",
8401 __func__, intf);
8402 return -1;
8403 }
8404 val = get_param(cmd, "OMCtrl_RxNSS");
8405 if (val)
8406 rx_nss = atoi(val);
8407
8408 val = get_param(cmd, "OMCtrl_ChnlWidth");
8409 if (val)
8410 ch_bw = atoi(val);
8411
8412 val = get_param(cmd, "OMCtrl_ULMUDisable");
8413 if (val)
8414 ulmu_dis = atoi(val);
8415
8416 val = get_param(cmd, "OMCtrl_TxNSTS");
8417 if (val)
8418 tx_nsts = atoi(val);
8419
8420 val = get_param(cmd, "OMCtrl_ULMUDataDisable");
8421 if (val)
8422 ulmu_data_dis = atoi(val);
8423
8424 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8425 NL80211_CMD_VENDOR)) ||
8426 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
8427 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
8428 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
8429 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
8430 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8431 !(params = nla_nest_start(
8432 msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OMI_TX)) ||
8433 !(attr1 = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8434 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_RX_NSS, rx_nss) ||
8435 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_CH_BW, ch_bw) ||
8436 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_TX_NSTS, tx_nsts) ||
8437 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DATA_DISABLE,
8438 ulmu_data_dis) ||
8439 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DISABLE,
8440 ulmu_dis)) {
8441 sigma_dut_print(dut, DUT_MSG_ERROR,
8442 "%s: err in adding vendor_cmd and vendor_data",
8443 __func__);
8444 nlmsg_free(msg);
8445 return -1;
8446 }
8447 nla_nest_end(msg, attr1);
8448 nla_nest_end(msg, params);
8449 nla_nest_end(msg, attr);
8450
8451 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
8452 if (ret) {
8453 sigma_dut_print(dut, DUT_MSG_ERROR,
8454 "%s: err in send_and_recv_msgs, ret=%d",
8455 __func__, ret);
8456 }
8457
8458 return ret;
8459#else /* NL80211_SUPPORT */
8460 sigma_dut_print(dut, DUT_MSG_ERROR,
8461 "OMI TX cannot be processed without NL80211_SUPPORT defined");
8462 return -1;
8463#endif /* NL80211_SUPPORT */
8464}
8465
8466
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008467static int cmd_sta_set_wireless_vht(struct sigma_dut *dut,
8468 struct sigma_conn *conn,
8469 struct sigma_cmd *cmd)
8470{
8471 const char *intf = get_param(cmd, "Interface");
8472 const char *val;
Arif Hussaina37e9552018-06-20 17:05:59 -07008473 const char *program;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008474 int tkip = -1;
8475 int wep = -1;
8476
Arif Hussaina37e9552018-06-20 17:05:59 -07008477 program = get_param(cmd, "Program");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008478 val = get_param(cmd, "SGI80");
8479 if (val) {
8480 int sgi80;
8481
8482 sgi80 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008483 run_iwpriv(dut, intf, "shortgi %d", sgi80);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008484 }
8485
8486 val = get_param(cmd, "TxBF");
8487 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02008488 switch (get_driver_type(dut)) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07008489 case DRIVER_WCN:
8490 if (sta_set_tx_beamformee(dut, intf, 1)) {
8491 send_resp(dut, conn, SIGMA_ERROR,
8492 "ErrorCode,Failed to set TX beamformee enable");
8493 return 0;
8494 }
8495 break;
8496 case DRIVER_ATHEROS:
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008497 if (run_iwpriv(dut, intf, "vhtsubfee 1") < 0) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07008498 send_resp(dut, conn, SIGMA_ERROR,
8499 "ErrorCode,Setting vhtsubfee failed");
8500 return 0;
8501 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008502 if (run_iwpriv(dut, intf, "vhtsubfer 1") < 0) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07008503 send_resp(dut, conn, SIGMA_ERROR,
8504 "ErrorCode,Setting vhtsubfer failed");
8505 return 0;
8506 }
8507 break;
8508 default:
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008509 sigma_dut_print(dut, DUT_MSG_ERROR,
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07008510 "Unsupported driver type");
8511 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008512 }
8513 }
8514
8515 val = get_param(cmd, "MU_TxBF");
8516 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02008517 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008518 case DRIVER_ATHEROS:
8519 ath_sta_set_txsp_stream(dut, intf, "1SS");
8520 ath_sta_set_rxsp_stream(dut, intf, "1SS");
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008521 run_iwpriv(dut, intf, "vhtmubfee 1");
8522 run_iwpriv(dut, intf, "vhtmubfer 1");
Sunil Duttae9e5d12018-06-29 11:50:47 +05308523 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008524 case DRIVER_WCN:
8525 if (wcn_sta_set_sp_stream(dut, intf, "1SS") < 0) {
8526 send_resp(dut, conn, SIGMA_ERROR,
8527 "ErrorCode,Failed to set RX/TXSP_STREAM");
8528 return 0;
8529 }
Sunil Duttae9e5d12018-06-29 11:50:47 +05308530 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008531 default:
8532 sigma_dut_print(dut, DUT_MSG_ERROR,
8533 "Setting SP_STREAM not supported");
8534 break;
8535 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008536 }
8537
8538 val = get_param(cmd, "LDPC");
8539 if (val) {
8540 int ldpc;
8541
8542 ldpc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008543 run_iwpriv(dut, intf, "ldpc %d", ldpc);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008544 }
8545
Amarnath Hullur Subramanyam7bae60e2018-01-31 03:46:50 -08008546 val = get_param(cmd, "BCC");
8547 if (val) {
8548 int bcc;
8549
8550 bcc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
8551 /* use LDPC iwpriv itself to set bcc coding, bcc coding
8552 * is mutually exclusive to bcc */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008553 run_iwpriv(dut, intf, "ldpc %d", !bcc);
Amarnath Hullur Subramanyam7bae60e2018-01-31 03:46:50 -08008554 }
8555
Arif Hussain7b47d2d2018-05-09 10:44:02 -07008556 val = get_param(cmd, "MaxHE-MCS_1SS_RxMapLTE80");
8557 if (val && dut->sta_nss == 1)
8558 cmd_set_max_he_mcs(dut, intf, atoi(val));
8559
8560 val = get_param(cmd, "MaxHE-MCS_2SS_RxMapLTE80");
8561 if (val && dut->sta_nss == 2)
8562 cmd_set_max_he_mcs(dut, intf, atoi(val));
8563
Arif Hussainac6c5112018-05-25 17:34:00 -07008564 val = get_param(cmd, "MCS_FixedRate");
8565 if (val) {
8566#ifdef NL80211_SUPPORT
8567 int mcs, ratecode = 0;
8568 enum he_mcs_config mcs_config;
8569 int ret;
Jouni Malinenb9b671d2019-04-26 13:23:17 +03008570 char buf[60];
Arif Hussainac6c5112018-05-25 17:34:00 -07008571
8572 ratecode = (0x07 & dut->sta_nss) << 5;
8573 mcs = atoi(val);
8574 /* Add the MCS to the ratecode */
8575 if (mcs >= 0 && mcs <= 11) {
8576 ratecode += mcs;
8577 if (dut->device_type == STA_testbed &&
8578 mcs > 7 && mcs <= 11) {
8579 if (mcs <= 9)
8580 mcs_config = HE_80_MCS0_9;
8581 else
8582 mcs_config = HE_80_MCS0_11;
8583 ret = sta_set_he_mcs(dut, intf, mcs_config);
8584 if (ret) {
8585 sigma_dut_print(dut, DUT_MSG_ERROR,
8586 "MCS_FixedRate: mcs setting failed, mcs:%d, mcs_config %d, ret:%d",
8587 mcs, mcs_config, ret);
8588 }
8589 }
8590 snprintf(buf, sizeof(buf),
8591 "iwpriv %s set_11ax_rate 0x%03x",
8592 intf, ratecode);
8593 if (system(buf) != 0) {
8594 sigma_dut_print(dut, DUT_MSG_ERROR,
8595 "MCS_FixedRate: iwpriv setting of 11ax rates 0x%03x failed",
8596 ratecode);
8597 }
8598 } else {
8599 sigma_dut_print(dut, DUT_MSG_ERROR,
8600 "MCS_FixedRate: HE MCS %d not supported",
8601 mcs);
8602 }
8603#else /* NL80211_SUPPORT */
8604 sigma_dut_print(dut, DUT_MSG_ERROR,
8605 "MCS_FixedRate cannot be changed without NL80211_SUPPORT defined");
8606#endif /* NL80211_SUPPORT */
8607 }
8608
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008609 val = get_param(cmd, "opt_md_notif_ie");
8610 if (val) {
8611 char *result = NULL;
8612 char delim[] = ";";
8613 char token[30];
8614 int value, config_val = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308615 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008616
Peng Xub8fc5cc2017-05-10 17:27:28 -07008617 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308618 result = strtok_r(token, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008619
8620 /* Extract the NSS information */
8621 if (result) {
8622 value = atoi(result);
8623 switch (value) {
8624 case 1:
8625 config_val = 1;
8626 break;
8627 case 2:
8628 config_val = 3;
8629 break;
8630 case 3:
8631 config_val = 7;
8632 break;
8633 case 4:
8634 config_val = 15;
8635 break;
8636 default:
8637 config_val = 3;
8638 break;
8639 }
8640
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008641 run_iwpriv(dut, intf, "rxchainmask %d", config_val);
8642 run_iwpriv(dut, intf, "txchainmask %d", config_val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008643
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008644 }
8645
8646 /* Extract the channel width information */
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308647 result = strtok_r(NULL, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008648 if (result) {
8649 value = atoi(result);
8650 switch (value) {
8651 case 20:
8652 config_val = 0;
8653 break;
8654 case 40:
8655 config_val = 1;
8656 break;
8657 case 80:
8658 config_val = 2;
8659 break;
8660 case 160:
8661 config_val = 3;
8662 break;
8663 default:
8664 config_val = 2;
8665 break;
8666 }
8667
8668 dut->chwidth = config_val;
8669
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008670 run_iwpriv(dut, intf, "chwidth %d", config_val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008671 }
8672
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008673 run_iwpriv(dut, intf, "opmode_notify 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008674 }
8675
8676 val = get_param(cmd, "nss_mcs_cap");
8677 if (val) {
8678 int nss, mcs;
8679 char token[20];
8680 char *result = NULL;
8681 unsigned int vht_mcsmap = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308682 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008683
Peng Xub8fc5cc2017-05-10 17:27:28 -07008684 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308685 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05308686 if (!result) {
8687 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07008688 "NSS not specified");
8689 send_resp(dut, conn, SIGMA_ERROR,
8690 "errorCode,NSS not specified");
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05308691 return 0;
8692 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008693 nss = atoi(result);
8694
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008695 run_iwpriv(dut, intf, "nss %d", nss);
Arif Hussainac6c5112018-05-25 17:34:00 -07008696 dut->sta_nss = nss;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008697
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308698 result = strtok_r(NULL, ";", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008699 if (result == NULL) {
8700 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07008701 "MCS not specified");
8702 send_resp(dut, conn, SIGMA_ERROR,
8703 "errorCode,MCS not specified");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008704 return 0;
8705 }
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308706 result = strtok_r(result, "-", &saveptr);
8707 result = strtok_r(NULL, "-", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05308708 if (!result) {
8709 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07008710 "MCS not specified");
8711 send_resp(dut, conn, SIGMA_ERROR,
8712 "errorCode,MCS not specified");
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05308713 return 0;
8714 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008715 mcs = atoi(result);
8716
Arif Hussaina37e9552018-06-20 17:05:59 -07008717 if (program && strcasecmp(program, "HE") == 0) {
8718#ifdef NL80211_SUPPORT
8719 enum he_mcs_config mcs_config;
8720 int ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008721
Arif Hussaina37e9552018-06-20 17:05:59 -07008722 if (mcs >= 0 && mcs <= 7) {
8723 mcs_config = HE_80_MCS0_7;
8724 } else if (mcs > 7 && mcs <= 9) {
8725 mcs_config = HE_80_MCS0_9;
8726 } else if (mcs > 9 && mcs <= 11) {
8727 mcs_config = HE_80_MCS0_11;
8728 } else {
8729 sigma_dut_print(dut, DUT_MSG_ERROR,
8730 "nss_mcs_cap: HE: Invalid mcs: %d",
8731 mcs);
8732 send_resp(dut, conn, SIGMA_ERROR,
8733 "errorCode,Invalid MCS");
8734 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008735 }
Arif Hussaina37e9552018-06-20 17:05:59 -07008736
8737 ret = sta_set_he_mcs(dut, intf, mcs_config);
8738 if (ret) {
8739 sigma_dut_print(dut, DUT_MSG_ERROR,
8740 "nss_mcs_cap: HE: Setting of MCS failed, mcs_config: %d, ret: %d",
8741 mcs_config, ret);
8742 send_resp(dut, conn, SIGMA_ERROR,
8743 "errorCode,Failed to set MCS");
8744 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008745 }
Arif Hussaina37e9552018-06-20 17:05:59 -07008746#else /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008747 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07008748 "nss_mcs_cap: HE: MCS cannot be changed without NL80211_SUPPORT defined");
8749#endif /* NL80211_SUPPORT */
8750 } else {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008751 run_iwpriv(dut, intf, "vhtmcs %d", mcs);
Arif Hussaina37e9552018-06-20 17:05:59 -07008752
8753 switch (nss) {
8754 case 1:
8755 switch (mcs) {
8756 case 7:
8757 vht_mcsmap = 0xfffc;
8758 break;
8759 case 8:
8760 vht_mcsmap = 0xfffd;
8761 break;
8762 case 9:
8763 vht_mcsmap = 0xfffe;
8764 break;
8765 default:
8766 vht_mcsmap = 0xfffe;
8767 break;
8768 }
8769 break;
8770 case 2:
8771 switch (mcs) {
8772 case 7:
8773 vht_mcsmap = 0xfff0;
8774 break;
8775 case 8:
8776 vht_mcsmap = 0xfff5;
8777 break;
8778 case 9:
8779 vht_mcsmap = 0xfffa;
8780 break;
8781 default:
8782 vht_mcsmap = 0xfffa;
8783 break;
8784 }
8785 break;
8786 case 3:
8787 switch (mcs) {
8788 case 7:
8789 vht_mcsmap = 0xffc0;
8790 break;
8791 case 8:
8792 vht_mcsmap = 0xffd5;
8793 break;
8794 case 9:
8795 vht_mcsmap = 0xffea;
8796 break;
8797 default:
8798 vht_mcsmap = 0xffea;
8799 break;
8800 }
8801 break;
8802 default:
8803 vht_mcsmap = 0xffea;
8804 break;
8805 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008806 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008807 }
8808 }
8809
8810 /* UNSUPPORTED: val = get_param(cmd, "Tx_lgi_rate"); */
8811
8812 val = get_param(cmd, "Vht_tkip");
8813 if (val)
8814 tkip = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
8815
8816 val = get_param(cmd, "Vht_wep");
8817 if (val)
8818 wep = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
8819
8820 if (tkip != -1 || wep != -1) {
8821 if ((tkip == 1 && wep != 0) || (wep == 1 && tkip != 0)) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008822 run_iwpriv(dut, intf, "htweptkip 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008823 } else if ((tkip == 0 && wep != 1) || (wep == 0 && tkip != 1)) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008824 run_iwpriv(dut, intf, "htweptkip 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008825 } else {
8826 sigma_dut_print(dut, DUT_MSG_ERROR,
8827 "ErrorCode,mixed mode of VHT TKIP/WEP not supported");
8828 return 0;
8829 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008830 }
8831
Arif Hussain55f00da2018-07-03 08:28:26 -07008832 val = get_param(cmd, "txBandwidth");
8833 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02008834 switch (get_driver_type(dut)) {
Arif Hussain55f00da2018-07-03 08:28:26 -07008835 case DRIVER_WCN:
8836 if (wcn_sta_set_width(dut, intf, val) < 0) {
8837 send_resp(dut, conn, SIGMA_ERROR,
8838 "ErrorCode,Failed to set txBandwidth");
8839 return 0;
8840 }
8841 break;
8842 case DRIVER_ATHEROS:
8843 if (ath_set_width(dut, conn, intf, val) < 0) {
8844 send_resp(dut, conn, SIGMA_ERROR,
8845 "ErrorCode,Failed to set txBandwidth");
8846 return 0;
8847 }
8848 break;
8849 default:
8850 sigma_dut_print(dut, DUT_MSG_ERROR,
8851 "Setting txBandwidth not supported");
8852 break;
8853 }
8854 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008855
Arif Hussain9765f7d2018-07-03 08:28:26 -07008856 val = get_param(cmd, "BeamformeeSTS");
8857 if (val) {
Kiran Kumar Lokerebc89d432018-07-10 12:20:13 -07008858 if (sta_set_tx_beamformee(dut, intf, 1)) {
8859 send_resp(dut, conn, SIGMA_ERROR,
8860 "ErrorCode,Failed to set TX beamformee enable");
8861 return 0;
8862 }
8863
Arif Hussain9765f7d2018-07-03 08:28:26 -07008864 if (sta_set_beamformee_sts(dut, intf, atoi(val))) {
8865 send_resp(dut, conn, SIGMA_ERROR,
8866 "ErrorCode,Failed to set BeamformeeSTS");
8867 return 0;
8868 }
8869 }
8870
Arif Hussain68d23f52018-07-11 13:39:08 -07008871 val = get_param(cmd, "Trig_MAC_Padding_Dur");
8872 if (val) {
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07008873#ifdef NL80211_SUPPORT
8874 enum qca_wlan_he_mac_padding_dur set_val;
8875
8876 switch (atoi(val)) {
8877 case 16:
8878 set_val = QCA_WLAN_HE_16US_OF_PROCESS_TIME;
8879 break;
8880 case 8:
8881 set_val = QCA_WLAN_HE_8US_OF_PROCESS_TIME;
8882 break;
8883 default:
8884 set_val = QCA_WLAN_HE_NO_ADDITIONAL_PROCESS_TIME;
8885 break;
8886 }
8887 if (sta_set_mac_padding_duration(dut, intf, set_val)) {
Arif Hussain68d23f52018-07-11 13:39:08 -07008888 send_resp(dut, conn, SIGMA_ERROR,
8889 "ErrorCode,Failed to set MAC padding duration");
8890 return 0;
8891 }
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07008892#else /* NL80211_SUPPORT */
8893 sigma_dut_print(dut, DUT_MSG_ERROR,
8894 "MAC padding duration cannot be changed without NL80211_SUPPORT defined");
8895#endif /* NL80211_SUPPORT */
Arif Hussain68d23f52018-07-11 13:39:08 -07008896 }
8897
Arif Hussain480d5f42019-03-12 14:40:42 -07008898 val = get_param(cmd, "TWT_ReqSupport");
8899 if (val) {
8900 int set_val;
8901
8902 if (strcasecmp(val, "Enable") == 0) {
8903 set_val = 1;
8904 } else if (strcasecmp(val, "Disable") == 0) {
8905 set_val = 0;
8906 } else {
8907 send_resp(dut, conn, SIGMA_ERROR,
8908 "ErrorCode,Invalid TWT_ReqSupport");
8909 return STATUS_SENT;
8910 }
8911
8912 if (sta_set_twt_req_support(dut, intf, set_val)) {
8913 sigma_dut_print(dut, DUT_MSG_ERROR,
8914 "Failed to set TWT req support %d",
8915 set_val);
8916 send_resp(dut, conn, SIGMA_ERROR,
8917 "ErrorCode,Failed to set TWT_ReqSupport");
8918 return STATUS_SENT;
8919 }
8920 }
8921
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07008922 val = get_param(cmd, "MU_EDCA");
8923 if (val && (strcasecmp(val, "Override") == 0)) {
8924 if (sta_set_mu_edca_override(dut, intf, 1)) {
8925 send_resp(dut, conn, SIGMA_ERROR,
8926 "ErrorCode,Failed to set MU EDCA override");
8927 return 0;
8928 }
8929 }
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -07008930
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07008931 val = get_param(cmd, "OMControl");
8932 if (val) {
8933 int set_val = 1;
8934
8935 if (strcasecmp(val, "Enable") == 0)
8936 set_val = 1;
8937 else if (strcasecmp(val, "Disable") == 0)
8938 set_val = 0;
8939
8940 if (sta_set_om_ctrl_supp(dut, intf, set_val)) {
8941 send_resp(dut, conn, SIGMA_ERROR,
8942 "ErrorCode,Failed to set OM ctrl supp");
8943 return 0;
8944 }
8945 }
8946
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -07008947 val = get_param(cmd, "ADDBAResp_BufSize");
8948 if (val) {
8949 int buf_size;
8950
8951 if (strcasecmp(val, "gt64") == 0)
8952 buf_size = 256;
8953 else
8954 buf_size = 64;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02008955 if (get_driver_type(dut) == DRIVER_WCN &&
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -07008956 sta_set_addba_buf_size(dut, intf, buf_size)) {
8957 send_resp(dut, conn, SIGMA_ERROR,
8958 "ErrorCode,set addbaresp_buff_size failed");
8959 return 0;
8960 }
8961 }
8962
8963 val = get_param(cmd, "ADDBAReq_BufSize");
8964 if (val) {
8965 int buf_size;
8966
8967 if (strcasecmp(val, "gt64") == 0)
8968 buf_size = 256;
8969 else
8970 buf_size = 64;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02008971 if (get_driver_type(dut) == DRIVER_WCN &&
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -07008972 sta_set_addba_buf_size(dut, intf, buf_size)) {
8973 send_resp(dut, conn, SIGMA_ERROR,
8974 "ErrorCode,set addbareq_buff_size failed");
8975 return 0;
8976 }
8977 }
8978
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008979 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
8980}
8981
8982
8983static int sta_set_wireless_60g(struct sigma_dut *dut,
8984 struct sigma_conn *conn,
8985 struct sigma_cmd *cmd)
8986{
8987 const char *dev_role = get_param(cmd, "DevRole");
8988
8989 if (!dev_role) {
8990 send_resp(dut, conn, SIGMA_INVALID,
8991 "ErrorCode,DevRole not specified");
8992 return 0;
8993 }
8994
8995 if (strcasecmp(dev_role, "PCP") == 0)
8996 return sta_set_60g_pcp(dut, conn, cmd);
8997 if (strcasecmp(dev_role, "STA") == 0)
8998 return sta_set_60g_sta(dut, conn, cmd);
8999 send_resp(dut, conn, SIGMA_INVALID,
9000 "ErrorCode,DevRole not supported");
9001 return 0;
9002}
9003
9004
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05309005static int sta_set_wireless_oce(struct sigma_dut *dut, struct sigma_conn *conn,
9006 struct sigma_cmd *cmd)
9007{
9008 int status;
9009 const char *intf = get_param(cmd, "Interface");
9010 const char *val = get_param(cmd, "DevRole");
9011
9012 if (val && strcasecmp(val, "STA-CFON") == 0) {
9013 status = sta_cfon_set_wireless(dut, conn, cmd);
9014 if (status)
9015 return status;
9016 }
9017 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
9018}
9019
9020
Jouni Malinenf7222712019-06-13 01:50:21 +03009021static enum sigma_cmd_result cmd_sta_set_wireless(struct sigma_dut *dut,
9022 struct sigma_conn *conn,
9023 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009024{
9025 const char *val;
9026
9027 val = get_param(cmd, "Program");
9028 if (val) {
9029 if (strcasecmp(val, "11n") == 0)
9030 return cmd_sta_set_11n(dut, conn, cmd);
Amarnath Hullur Subramanyam4f860292018-01-31 03:49:35 -08009031 if (strcasecmp(val, "VHT") == 0 || strcasecmp(val, "HE") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009032 return cmd_sta_set_wireless_vht(dut, conn, cmd);
9033 if (strcasecmp(val, "60ghz") == 0)
9034 return sta_set_wireless_60g(dut, conn, cmd);
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05309035 if (strcasecmp(val, "OCE") == 0)
9036 return sta_set_wireless_oce(dut, conn, cmd);
Alexei Avshalom Lazar66bb9972018-12-18 16:01:43 +02009037 /* sta_set_wireless in WPS program is only used for 60G */
9038 if (is_60g_sigma_dut(dut))
9039 return sta_set_wireless_60g(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009040 send_resp(dut, conn, SIGMA_ERROR,
9041 "ErrorCode,Program value not supported");
9042 } else {
9043 send_resp(dut, conn, SIGMA_ERROR,
9044 "ErrorCode,Program argument not available");
9045 }
9046
9047 return 0;
9048}
9049
9050
9051static void ath_sta_inject_frame(struct sigma_dut *dut, const char *intf,
9052 int tid)
9053{
9054 char buf[100];
9055 int tid_to_dscp [] = { 0x00, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0 };
9056
Pradeep Reddy POTTETId31d1322016-10-13 17:22:03 +05309057 if (tid < 0 ||
9058 tid >= (int) (sizeof(tid_to_dscp) / sizeof(tid_to_dscp[0]))) {
9059 sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported TID: %d", tid);
9060 return;
9061 }
9062
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009063 /*
9064 * Two ways to ensure that addba request with a
9065 * non zero TID could be sent out. EV 117296
9066 */
9067 snprintf(buf, sizeof(buf),
9068 "ping -c 8 -Q %d `arp -a | grep wlan0 | awk '{print $2}' | tr -d '()'`",
9069 tid);
9070 if (system(buf) != 0) {
9071 sigma_dut_print(dut, DUT_MSG_ERROR,
9072 "Ping did not send out");
9073 }
9074
9075 snprintf(buf, sizeof(buf),
9076 "iwconfig %s | grep Access | awk '{print $6}' > %s",
9077 intf, VI_QOS_TMP_FILE);
9078 if (system(buf) != 0)
9079 return;
9080
9081 snprintf(buf, sizeof(buf),
9082 "ifconfig %s | grep HWaddr | cut -b 39-56 >> %s",
9083 intf, VI_QOS_TMP_FILE);
9084 if (system(buf) != 0)
9085 sigma_dut_print(dut, DUT_MSG_ERROR, "HWaddr matching failed");
9086
9087 snprintf(buf,sizeof(buf), "sed -n '3,$p' %s >> %s",
9088 VI_QOS_REFFILE, VI_QOS_TMP_FILE);
9089 if (system(buf) != 0) {
9090 sigma_dut_print(dut, DUT_MSG_ERROR,
9091 "VI_QOS_TEMP_FILE generation error failed");
9092 }
9093 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
9094 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
9095 if (system(buf) != 0) {
9096 sigma_dut_print(dut, DUT_MSG_ERROR,
9097 "VI_QOS_FILE generation failed");
9098 }
9099
9100 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
9101 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
9102 if (system(buf) != 0) {
9103 sigma_dut_print(dut, DUT_MSG_ERROR,
9104 "VI_QOS_FILE generation failed");
9105 }
9106
9107 snprintf(buf, sizeof(buf), "ethinject %s %s", intf, VI_QOS_FILE);
9108 if (system(buf) != 0) {
9109 }
9110}
9111
9112
9113static int ath_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
9114 struct sigma_cmd *cmd)
9115{
9116 const char *intf = get_param(cmd, "Interface");
9117 const char *val;
9118 int tid = 0;
9119 char buf[100];
9120
9121 val = get_param(cmd, "TID");
9122 if (val) {
9123 tid = atoi(val);
9124 if (tid)
9125 ath_sta_inject_frame(dut, intf, tid);
9126 }
9127
9128 /* Command sequence for ADDBA request on Peregrine based devices */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07009129 run_iwpriv(dut, intf, "setaddbaoper 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009130
9131 snprintf(buf, sizeof(buf), "wifitool %s senddelba 1 %d 1 4", intf, tid);
9132 if (system(buf) != 0) {
9133 sigma_dut_print(dut, DUT_MSG_ERROR,
9134 "wifitool senddelba failed");
9135 }
9136
9137 snprintf(buf, sizeof(buf), "wifitool %s sendaddba 1 %d 64", intf, tid);
9138 if (system(buf) != 0) {
9139 sigma_dut_print(dut, DUT_MSG_ERROR,
9140 "wifitool sendaddba failed");
9141 }
9142
9143 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
9144
9145 return 1;
9146}
9147
9148
Lior David9981b512017-01-20 13:16:40 +02009149#ifdef __linux__
9150
9151static int wil6210_send_addba(struct sigma_dut *dut, const char *dest_mac,
9152 int agg_size)
9153{
9154 char dir[128], buf[128];
9155 FILE *f;
9156 regex_t re;
9157 regmatch_t m[2];
Jouni Malinen3aa72862019-05-29 23:14:51 +03009158 int rc, ret = -1, vring_id, found, res;
Lior David9981b512017-01-20 13:16:40 +02009159
9160 if (wil6210_get_debugfs_dir(dut, dir, sizeof(dir))) {
9161 sigma_dut_print(dut, DUT_MSG_ERROR,
9162 "failed to get wil6210 debugfs dir");
9163 return -1;
9164 }
9165
Jouni Malinen3aa72862019-05-29 23:14:51 +03009166 res = snprintf(buf, sizeof(buf), "%s/vrings", dir);
9167 if (res < 0 || res >= sizeof(buf))
9168 return -1;
Lior David9981b512017-01-20 13:16:40 +02009169 f = fopen(buf, "r");
9170 if (!f) {
9171 sigma_dut_print(dut, DUT_MSG_ERROR, "failed to open: %s", buf);
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +02009172 /* newer wil6210 driver renamed file to "rings" */
Jouni Malinen3aa72862019-05-29 23:14:51 +03009173 res = snprintf(buf, sizeof(buf), "%s/rings", dir);
9174 if (res < 0 || res >= sizeof(buf))
9175 return -1;
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +02009176 f = fopen(buf, "r");
9177 if (!f) {
9178 sigma_dut_print(dut, DUT_MSG_ERROR,
9179 "failed to open: %s", buf);
9180 return -1;
9181 }
Lior David9981b512017-01-20 13:16:40 +02009182 }
9183
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +02009184 /* can be either VRING tx... or RING... */
9185 if (regcomp(&re, "RING tx_[ \t]*([0-9]+)", REG_EXTENDED)) {
Lior David9981b512017-01-20 13:16:40 +02009186 sigma_dut_print(dut, DUT_MSG_ERROR, "regcomp failed");
9187 goto out;
9188 }
9189
9190 /* find TX VRING for the mac address */
9191 found = 0;
9192 while (fgets(buf, sizeof(buf), f)) {
9193 if (strcasestr(buf, dest_mac)) {
9194 found = 1;
9195 break;
9196 }
9197 }
9198
9199 if (!found) {
9200 sigma_dut_print(dut, DUT_MSG_ERROR,
9201 "no TX VRING for %s", dest_mac);
9202 goto out;
9203 }
9204
9205 /* extract VRING ID, "VRING tx_<id> = {" */
9206 if (!fgets(buf, sizeof(buf), f)) {
9207 sigma_dut_print(dut, DUT_MSG_ERROR,
9208 "no VRING start line for %s", dest_mac);
9209 goto out;
9210 }
9211
9212 rc = regexec(&re, buf, 2, m, 0);
9213 regfree(&re);
9214 if (rc || m[1].rm_so < 0) {
9215 sigma_dut_print(dut, DUT_MSG_ERROR,
9216 "no VRING TX ID for %s", dest_mac);
9217 goto out;
9218 }
9219 buf[m[1].rm_eo] = 0;
9220 vring_id = atoi(&buf[m[1].rm_so]);
9221
9222 /* send the addba command */
9223 fclose(f);
Jouni Malinen3aa72862019-05-29 23:14:51 +03009224 res = snprintf(buf, sizeof(buf), "%s/back", dir);
9225 if (res < 0 || res >= sizeof(buf))
9226 return -1;
Lior David9981b512017-01-20 13:16:40 +02009227 f = fopen(buf, "w");
9228 if (!f) {
9229 sigma_dut_print(dut, DUT_MSG_ERROR,
9230 "failed to open: %s", buf);
9231 return -1;
9232 }
9233
9234 fprintf(f, "add %d %d\n", vring_id, agg_size);
9235
9236 ret = 0;
9237
9238out:
9239 fclose(f);
9240
9241 return ret;
9242}
9243
9244
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +02009245int send_addba_60g(struct sigma_dut *dut, struct sigma_conn *conn,
9246 struct sigma_cmd *cmd, const char *mac_param)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009247{
9248 const char *val;
9249 int tid = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009250
9251 val = get_param(cmd, "TID");
9252 if (val) {
9253 tid = atoi(val);
9254 if (tid != 0) {
9255 sigma_dut_print(dut, DUT_MSG_ERROR,
9256 "Ignore TID %d for send_addba use TID 0 for 60g since only 0 required on TX",
9257 tid);
9258 }
9259 }
9260
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +02009261 val = get_param(cmd, mac_param);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009262 if (!val) {
9263 sigma_dut_print(dut, DUT_MSG_ERROR,
9264 "Currently not supporting addba for 60G without Dest_mac");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02009265 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009266 }
9267
Lior David9981b512017-01-20 13:16:40 +02009268 if (wil6210_send_addba(dut, val, dut->back_rcv_buf))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009269 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009270
9271 return 1;
9272}
9273
Lior David9981b512017-01-20 13:16:40 +02009274#endif /* __linux__ */
9275
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009276
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009277static int wcn_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
9278 struct sigma_cmd *cmd)
9279{
9280#ifdef NL80211_SUPPORT
9281 const char *intf = get_param(cmd, "Interface");
9282 const char *val;
9283 int tid = -1;
9284 int bufsize = 64;
9285 struct nl_msg *msg;
9286 int ret = 0;
9287 struct nlattr *params;
9288 int ifindex;
9289
9290 val = get_param(cmd, "TID");
9291 if (val)
9292 tid = atoi(val);
9293
9294 if (tid == -1) {
9295 send_resp(dut, conn, SIGMA_ERROR,
9296 "ErrorCode,sta_send_addba tid invalid");
9297 return 0;
9298 }
9299
9300 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
9301
9302 ifindex = if_nametoindex(intf);
9303 if (ifindex == 0) {
9304 sigma_dut_print(dut, DUT_MSG_ERROR,
9305 "%s: Index for interface %s failed",
9306 __func__, intf);
9307 send_resp(dut, conn, SIGMA_ERROR,
9308 "ErrorCode,sta_send_addba interface invalid");
9309 return 0;
9310 }
9311
9312 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
9313 NL80211_CMD_VENDOR)) ||
9314 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
9315 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
9316 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
9317 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
9318 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
9319 nla_put_u8(msg,
9320 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADD_DEL_BA_SESSION,
9321 QCA_WLAN_ADD_BA) ||
9322 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BA_TID,
9323 tid) ||
Kiran Kumar Lokere26e27582018-08-01 16:18:34 -07009324 nla_put_u16(msg,
9325 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE,
9326 bufsize)) {
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009327 sigma_dut_print(dut, DUT_MSG_ERROR,
9328 "%s: err in adding vendor_cmd and vendor_data",
9329 __func__);
9330 nlmsg_free(msg);
9331 send_resp(dut, conn, SIGMA_ERROR,
9332 "ErrorCode,sta_send_addba err in adding vendor_cmd and vendor_data");
9333 return 0;
9334 }
9335 nla_nest_end(msg, params);
9336
9337 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
9338 if (ret) {
9339 sigma_dut_print(dut, DUT_MSG_ERROR,
9340 "%s: err in send_and_recv_msgs, ret=%d",
9341 __func__, ret);
Sunil Dutt30605592018-05-04 20:35:50 +05309342 if (ret == -EOPNOTSUPP)
9343 return 1;
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009344 send_resp(dut, conn, SIGMA_ERROR,
9345 "ErrorCode,sta_send_addba err in send_and_recv_msgs");
9346 return 0;
9347 }
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009348#else /* NL80211_SUPPORT */
9349 sigma_dut_print(dut, DUT_MSG_ERROR,
9350 "sta_send_addba not supported without NL80211_SUPPORT defined");
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009351#endif /* NL80211_SUPPORT */
Sunil Dutt30605592018-05-04 20:35:50 +05309352
9353 return 1;
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009354}
9355
9356
Jouni Malinenf7222712019-06-13 01:50:21 +03009357static enum sigma_cmd_result cmd_sta_send_addba(struct sigma_dut *dut,
9358 struct sigma_conn *conn,
9359 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009360{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009361 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009362 case DRIVER_ATHEROS:
9363 return ath_sta_send_addba(dut, conn, cmd);
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009364 case DRIVER_WCN:
9365 return wcn_sta_send_addba(dut, conn, cmd);
Lior David9981b512017-01-20 13:16:40 +02009366#ifdef __linux__
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009367 case DRIVER_WIL6210:
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +02009368 return send_addba_60g(dut, conn, cmd, "Dest_mac");
Lior David9981b512017-01-20 13:16:40 +02009369#endif /* __linux__ */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009370 default:
9371 /*
9372 * There is no driver specific implementation for other drivers.
9373 * Ignore the command and report COMPLETE since the following
9374 * throughput test operation will end up sending ADDBA anyway.
9375 */
9376 return 1;
9377 }
9378}
9379
9380
9381int inject_eth_frame(int s, const void *data, size_t len,
9382 unsigned short ethtype, char *dst, char *src)
9383{
9384 struct iovec iov[4] = {
9385 {
9386 .iov_base = dst,
9387 .iov_len = ETH_ALEN,
9388 },
9389 {
9390 .iov_base = src,
9391 .iov_len = ETH_ALEN,
9392 },
9393 {
9394 .iov_base = &ethtype,
9395 .iov_len = sizeof(unsigned short),
9396 },
9397 {
9398 .iov_base = (void *) data,
9399 .iov_len = len,
9400 }
9401 };
9402 struct msghdr msg = {
9403 .msg_name = NULL,
9404 .msg_namelen = 0,
9405 .msg_iov = iov,
9406 .msg_iovlen = 4,
9407 .msg_control = NULL,
9408 .msg_controllen = 0,
9409 .msg_flags = 0,
9410 };
9411
9412 return sendmsg(s, &msg, 0);
9413}
9414
9415#if defined(__linux__) || defined(__QNXNTO__)
9416
9417int inject_frame(int s, const void *data, size_t len, int encrypt)
9418{
9419#define IEEE80211_RADIOTAP_F_WEP 0x04
9420#define IEEE80211_RADIOTAP_F_FRAG 0x08
9421 unsigned char rtap_hdr[] = {
9422 0x00, 0x00, /* radiotap version */
9423 0x0e, 0x00, /* radiotap length */
9424 0x02, 0xc0, 0x00, 0x00, /* bmap: flags, tx and rx flags */
9425 IEEE80211_RADIOTAP_F_FRAG, /* F_FRAG (fragment if required) */
9426 0x00, /* padding */
9427 0x00, 0x00, /* RX and TX flags to indicate that */
9428 0x00, 0x00, /* this is the injected frame directly */
9429 };
9430 struct iovec iov[2] = {
9431 {
9432 .iov_base = &rtap_hdr,
9433 .iov_len = sizeof(rtap_hdr),
9434 },
9435 {
9436 .iov_base = (void *) data,
9437 .iov_len = len,
9438 }
9439 };
9440 struct msghdr msg = {
9441 .msg_name = NULL,
9442 .msg_namelen = 0,
9443 .msg_iov = iov,
9444 .msg_iovlen = 2,
9445 .msg_control = NULL,
9446 .msg_controllen = 0,
9447 .msg_flags = 0,
9448 };
9449
9450 if (encrypt)
9451 rtap_hdr[8] |= IEEE80211_RADIOTAP_F_WEP;
9452
9453 return sendmsg(s, &msg, 0);
9454}
9455
9456
9457int open_monitor(const char *ifname)
9458{
9459#ifdef __QNXNTO__
9460 struct sockaddr_dl ll;
9461 int s;
9462
9463 memset(&ll, 0, sizeof(ll));
9464 ll.sdl_family = AF_LINK;
9465 ll.sdl_index = if_nametoindex(ifname);
9466 if (ll.sdl_index == 0) {
9467 perror("if_nametoindex");
9468 return -1;
9469 }
9470 s = socket(PF_INET, SOCK_RAW, 0);
9471#else /* __QNXNTO__ */
9472 struct sockaddr_ll ll;
9473 int s;
9474
9475 memset(&ll, 0, sizeof(ll));
9476 ll.sll_family = AF_PACKET;
9477 ll.sll_ifindex = if_nametoindex(ifname);
9478 if (ll.sll_ifindex == 0) {
9479 perror("if_nametoindex");
9480 return -1;
9481 }
9482 s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
9483#endif /* __QNXNTO__ */
9484 if (s < 0) {
9485 perror("socket[PF_PACKET,SOCK_RAW]");
9486 return -1;
9487 }
9488
9489 if (bind(s, (struct sockaddr *) &ll, sizeof(ll)) < 0) {
9490 perror("monitor socket bind");
9491 close(s);
9492 return -1;
9493 }
9494
9495 return s;
9496}
9497
9498
9499static int hex2num(char c)
9500{
9501 if (c >= '0' && c <= '9')
9502 return c - '0';
9503 if (c >= 'a' && c <= 'f')
9504 return c - 'a' + 10;
9505 if (c >= 'A' && c <= 'F')
9506 return c - 'A' + 10;
9507 return -1;
9508}
9509
9510
9511int hwaddr_aton(const char *txt, unsigned char *addr)
9512{
9513 int i;
9514
9515 for (i = 0; i < 6; i++) {
9516 int a, b;
9517
9518 a = hex2num(*txt++);
9519 if (a < 0)
9520 return -1;
9521 b = hex2num(*txt++);
9522 if (b < 0)
9523 return -1;
9524 *addr++ = (a << 4) | b;
9525 if (i < 5 && *txt++ != ':')
9526 return -1;
9527 }
9528
9529 return 0;
9530}
9531
9532#endif /* defined(__linux__) || defined(__QNXNTO__) */
9533
9534enum send_frame_type {
9535 DISASSOC, DEAUTH, SAQUERY, AUTH, ASSOCREQ, REASSOCREQ, DLS_REQ
9536};
9537enum send_frame_protection {
9538 CORRECT_KEY, INCORRECT_KEY, UNPROTECTED
9539};
9540
9541
9542static int sta_inject_frame(struct sigma_dut *dut, struct sigma_conn *conn,
9543 enum send_frame_type frame,
9544 enum send_frame_protection protected,
9545 const char *dest)
9546{
9547#ifdef __linux__
9548 unsigned char buf[1000], *pos;
9549 int s, res;
9550 char bssid[20], addr[20];
9551 char result[32], ssid[100];
9552 size_t ssid_len;
9553
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009554 if (get_wpa_status(get_station_ifname(dut), "wpa_state", result,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009555 sizeof(result)) < 0 ||
9556 strncmp(result, "COMPLETED", 9) != 0) {
9557 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Not connected");
9558 return 0;
9559 }
9560
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009561 if (get_wpa_status(get_station_ifname(dut), "bssid",
9562 bssid, sizeof(bssid)) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009563 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
9564 "current BSSID");
9565 return 0;
9566 }
9567
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009568 if (get_wpa_status(get_station_ifname(dut), "address",
9569 addr, sizeof(addr)) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009570 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
9571 "own MAC address");
9572 return 0;
9573 }
9574
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009575 if (get_wpa_status(get_station_ifname(dut), "ssid", ssid, sizeof(ssid))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009576 < 0) {
9577 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
9578 "current SSID");
9579 return 0;
9580 }
9581 ssid_len = strlen(ssid);
9582
9583 pos = buf;
9584
9585 /* Frame Control */
9586 switch (frame) {
9587 case DISASSOC:
9588 *pos++ = 0xa0;
9589 break;
9590 case DEAUTH:
9591 *pos++ = 0xc0;
9592 break;
9593 case SAQUERY:
9594 *pos++ = 0xd0;
9595 break;
9596 case AUTH:
9597 *pos++ = 0xb0;
9598 break;
9599 case ASSOCREQ:
9600 *pos++ = 0x00;
9601 break;
9602 case REASSOCREQ:
9603 *pos++ = 0x20;
9604 break;
9605 case DLS_REQ:
9606 *pos++ = 0xd0;
9607 break;
9608 }
9609
9610 if (protected == INCORRECT_KEY)
9611 *pos++ = 0x40; /* Set Protected field to 1 */
9612 else
9613 *pos++ = 0x00;
9614
9615 /* Duration */
9616 *pos++ = 0x00;
9617 *pos++ = 0x00;
9618
9619 /* addr1 = DA (current AP) */
9620 hwaddr_aton(bssid, pos);
9621 pos += 6;
9622 /* addr2 = SA (own address) */
9623 hwaddr_aton(addr, pos);
9624 pos += 6;
9625 /* addr3 = BSSID (current AP) */
9626 hwaddr_aton(bssid, pos);
9627 pos += 6;
9628
9629 /* Seq# (to be filled by driver/mac80211) */
9630 *pos++ = 0x00;
9631 *pos++ = 0x00;
9632
9633 if (protected == INCORRECT_KEY) {
9634 /* CCMP parameters */
9635 memcpy(pos, "\x61\x01\x00\x20\x00\x10\x00\x00", 8);
9636 pos += 8;
9637 }
9638
9639 if (protected == INCORRECT_KEY) {
9640 switch (frame) {
9641 case DEAUTH:
9642 /* Reason code (encrypted) */
9643 memcpy(pos, "\xa7\x39", 2);
9644 pos += 2;
9645 break;
9646 case DISASSOC:
9647 /* Reason code (encrypted) */
9648 memcpy(pos, "\xa7\x39", 2);
9649 pos += 2;
9650 break;
9651 case SAQUERY:
9652 /* Category|Action|TransID (encrypted) */
9653 memcpy(pos, "\x6f\xbd\xe9\x4d", 4);
9654 pos += 4;
9655 break;
9656 default:
9657 return -1;
9658 }
9659
9660 /* CCMP MIC */
9661 memcpy(pos, "\xc8\xd8\x3b\x06\x5d\xb7\x25\x68", 8);
9662 pos += 8;
9663 } else {
9664 switch (frame) {
9665 case DEAUTH:
9666 /* reason code = 8 */
9667 *pos++ = 0x08;
9668 *pos++ = 0x00;
9669 break;
9670 case DISASSOC:
9671 /* reason code = 8 */
9672 *pos++ = 0x08;
9673 *pos++ = 0x00;
9674 break;
9675 case SAQUERY:
9676 /* Category - SA Query */
9677 *pos++ = 0x08;
9678 /* SA query Action - Request */
9679 *pos++ = 0x00;
9680 /* Transaction ID */
9681 *pos++ = 0x12;
9682 *pos++ = 0x34;
9683 break;
9684 case AUTH:
9685 /* Auth Alg (Open) */
9686 *pos++ = 0x00;
9687 *pos++ = 0x00;
9688 /* Seq# */
9689 *pos++ = 0x01;
9690 *pos++ = 0x00;
9691 /* Status code */
9692 *pos++ = 0x00;
9693 *pos++ = 0x00;
9694 break;
9695 case ASSOCREQ:
9696 /* Capability Information */
9697 *pos++ = 0x31;
9698 *pos++ = 0x04;
9699 /* Listen Interval */
9700 *pos++ = 0x0a;
9701 *pos++ = 0x00;
9702 /* SSID */
9703 *pos++ = 0x00;
9704 *pos++ = ssid_len;
9705 memcpy(pos, ssid, ssid_len);
9706 pos += ssid_len;
9707 /* Supported Rates */
9708 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
9709 10);
9710 pos += 10;
9711 /* Extended Supported Rates */
9712 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
9713 pos += 6;
9714 /* RSN */
9715 memcpy(pos, "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00"
9716 "\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x02\xc0"
9717 "\x00\x00\x00\x00\x0f\xac\x06", 28);
9718 pos += 28;
9719 break;
9720 case REASSOCREQ:
9721 /* Capability Information */
9722 *pos++ = 0x31;
9723 *pos++ = 0x04;
9724 /* Listen Interval */
9725 *pos++ = 0x0a;
9726 *pos++ = 0x00;
9727 /* Current AP */
9728 hwaddr_aton(bssid, pos);
9729 pos += 6;
9730 /* SSID */
9731 *pos++ = 0x00;
9732 *pos++ = ssid_len;
9733 memcpy(pos, ssid, ssid_len);
9734 pos += ssid_len;
9735 /* Supported Rates */
9736 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
9737 10);
9738 pos += 10;
9739 /* Extended Supported Rates */
9740 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
9741 pos += 6;
9742 /* RSN */
9743 memcpy(pos, "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00"
9744 "\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x02\xc0"
9745 "\x00\x00\x00\x00\x0f\xac\x06", 28);
9746 pos += 28;
9747 break;
9748 case DLS_REQ:
9749 /* Category - DLS */
9750 *pos++ = 0x02;
9751 /* DLS Action - Request */
9752 *pos++ = 0x00;
9753 /* Destination MACAddress */
9754 if (dest)
9755 hwaddr_aton(dest, pos);
9756 else
9757 memset(pos, 0, 6);
9758 pos += 6;
9759 /* Source MACAddress */
9760 hwaddr_aton(addr, pos);
9761 pos += 6;
9762 /* Capability Information */
9763 *pos++ = 0x10; /* Privacy */
9764 *pos++ = 0x06; /* QoS */
9765 /* DLS Timeout Value */
9766 *pos++ = 0x00;
9767 *pos++ = 0x01;
9768 /* Supported rates */
9769 *pos++ = 0x01;
9770 *pos++ = 0x08;
9771 *pos++ = 0x0c; /* 6 Mbps */
9772 *pos++ = 0x12; /* 9 Mbps */
9773 *pos++ = 0x18; /* 12 Mbps */
9774 *pos++ = 0x24; /* 18 Mbps */
9775 *pos++ = 0x30; /* 24 Mbps */
9776 *pos++ = 0x48; /* 36 Mbps */
9777 *pos++ = 0x60; /* 48 Mbps */
9778 *pos++ = 0x6c; /* 54 Mbps */
9779 /* TODO: Extended Supported Rates */
9780 /* TODO: HT Capabilities */
9781 break;
9782 }
9783 }
9784
9785 s = open_monitor("sigmadut");
9786 if (s < 0) {
9787 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
9788 "monitor socket");
9789 return 0;
9790 }
9791
9792 res = inject_frame(s, buf, pos - buf, protected == CORRECT_KEY);
9793 if (res < 0) {
9794 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
9795 "inject frame");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05309796 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009797 return 0;
9798 }
9799 if (res < pos - buf) {
9800 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Only partial "
9801 "frame sent");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05309802 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009803 return 0;
9804 }
9805
9806 close(s);
9807
9808 return 1;
9809#else /* __linux__ */
9810 send_resp(dut, conn, SIGMA_ERROR, "errorCode,sta_send_frame not "
9811 "yet supported");
9812 return 0;
9813#endif /* __linux__ */
9814}
9815
9816
9817static int cmd_sta_send_frame_tdls(struct sigma_dut *dut,
9818 struct sigma_conn *conn,
9819 struct sigma_cmd *cmd)
9820{
9821 const char *intf = get_param(cmd, "Interface");
9822 const char *sta, *val;
9823 unsigned char addr[ETH_ALEN];
9824 char buf[100];
9825
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +03009826 if (!intf)
9827 return -1;
9828
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009829 sta = get_param(cmd, "peer");
9830 if (sta == NULL)
9831 sta = get_param(cmd, "station");
9832 if (sta == NULL) {
9833 send_resp(dut, conn, SIGMA_ERROR,
9834 "ErrorCode,Missing peer address");
9835 return 0;
9836 }
9837 if (hwaddr_aton(sta, addr) < 0) {
9838 send_resp(dut, conn, SIGMA_ERROR,
9839 "ErrorCode,Invalid peer address");
9840 return 0;
9841 }
9842
9843 val = get_param(cmd, "type");
9844 if (val == NULL)
9845 return -1;
9846
9847 if (strcasecmp(val, "DISCOVERY") == 0) {
9848 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", sta);
9849 if (wpa_command(intf, buf) < 0) {
9850 send_resp(dut, conn, SIGMA_ERROR,
9851 "ErrorCode,Failed to send TDLS discovery");
9852 return 0;
9853 }
9854 return 1;
9855 }
9856
9857 if (strcasecmp(val, "SETUP") == 0) {
9858 int status = 0, timeout = 0;
9859
9860 val = get_param(cmd, "Status");
9861 if (val)
9862 status = atoi(val);
9863
9864 val = get_param(cmd, "Timeout");
9865 if (val)
9866 timeout = atoi(val);
9867
9868 if (status != 0 && status != 37) {
9869 send_resp(dut, conn, SIGMA_ERROR,
9870 "ErrorCode,Unsupported status value");
9871 return 0;
9872 }
9873
9874 if (timeout != 0 && timeout != 301) {
9875 send_resp(dut, conn, SIGMA_ERROR,
9876 "ErrorCode,Unsupported timeout value");
9877 return 0;
9878 }
9879
9880 if (status && timeout) {
9881 send_resp(dut, conn, SIGMA_ERROR,
9882 "ErrorCode,Unsupported timeout+status "
9883 "combination");
9884 return 0;
9885 }
9886
9887 if (status == 37 &&
9888 wpa_command(intf, "SET tdls_testing 0x200")) {
9889 send_resp(dut, conn, SIGMA_ERROR,
9890 "ErrorCode,Failed to enable "
9891 "decline setup response test mode");
9892 return 0;
9893 }
9894
9895 if (timeout == 301) {
9896 int res;
9897 if (dut->no_tpk_expiration)
9898 res = wpa_command(intf,
9899 "SET tdls_testing 0x108");
9900 else
9901 res = wpa_command(intf,
9902 "SET tdls_testing 0x8");
9903 if (res) {
9904 send_resp(dut, conn, SIGMA_ERROR,
9905 "ErrorCode,Failed to set short TPK "
9906 "lifetime");
9907 return 0;
9908 }
9909 }
9910
9911 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", sta);
9912 if (wpa_command(intf, buf) < 0) {
9913 send_resp(dut, conn, SIGMA_ERROR,
9914 "ErrorCode,Failed to send TDLS setup");
9915 return 0;
9916 }
9917 return 1;
9918 }
9919
9920 if (strcasecmp(val, "TEARDOWN") == 0) {
9921 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", sta);
9922 if (wpa_command(intf, buf) < 0) {
9923 send_resp(dut, conn, SIGMA_ERROR,
9924 "ErrorCode,Failed to send TDLS teardown");
9925 return 0;
9926 }
9927 return 1;
9928 }
9929
9930 send_resp(dut, conn, SIGMA_ERROR,
9931 "ErrorCode,Unsupported TDLS frame");
9932 return 0;
9933}
9934
9935
9936static int sta_ap_known(const char *ifname, const char *bssid)
9937{
9938 char buf[4096];
9939
Jouni Malinendd32f192018-09-15 02:55:19 +03009940 snprintf(buf, sizeof(buf), "BSS MASK=1 %s", bssid);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009941 if (wpa_command_resp(ifname, buf, buf, sizeof(buf)) < 0)
9942 return 0;
9943 if (strncmp(buf, "id=", 3) != 0)
9944 return 0;
9945 return 1;
9946}
9947
9948
9949static int sta_scan_ap(struct sigma_dut *dut, const char *ifname,
9950 const char *bssid)
9951{
9952 int res;
9953 struct wpa_ctrl *ctrl;
9954 char buf[256];
9955
9956 if (sta_ap_known(ifname, bssid))
9957 return 0;
9958 sigma_dut_print(dut, DUT_MSG_DEBUG,
9959 "AP not in BSS table - start scan");
9960
9961 ctrl = open_wpa_mon(ifname);
9962 if (ctrl == NULL) {
9963 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
9964 "wpa_supplicant monitor connection");
9965 return -1;
9966 }
9967
9968 if (wpa_command(ifname, "SCAN") < 0) {
9969 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to start scan");
9970 wpa_ctrl_detach(ctrl);
9971 wpa_ctrl_close(ctrl);
9972 return -1;
9973 }
9974
9975 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
9976 buf, sizeof(buf));
9977
9978 wpa_ctrl_detach(ctrl);
9979 wpa_ctrl_close(ctrl);
9980
9981 if (res < 0) {
9982 sigma_dut_print(dut, DUT_MSG_INFO, "Scan did not complete");
9983 return -1;
9984 }
9985
9986 if (sta_ap_known(ifname, bssid))
9987 return 0;
9988 sigma_dut_print(dut, DUT_MSG_INFO, "AP not in BSS table");
9989 return -1;
9990}
9991
9992
9993static int cmd_sta_send_frame_hs2_neighadv(struct sigma_dut *dut,
9994 struct sigma_conn *conn,
9995 struct sigma_cmd *cmd,
9996 const char *intf)
9997{
9998 char buf[200];
9999
10000 snprintf(buf, sizeof(buf), "ndsend 2001:DB8::1 %s", intf);
10001 if (system(buf) != 0) {
10002 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Failed to run "
10003 "ndsend");
10004 return 0;
10005 }
10006
10007 return 1;
10008}
10009
10010
10011static int cmd_sta_send_frame_hs2_neighsolreq(struct sigma_dut *dut,
10012 struct sigma_conn *conn,
10013 struct sigma_cmd *cmd,
10014 const char *intf)
10015{
10016 char buf[200];
10017 const char *ip = get_param(cmd, "SenderIP");
10018
Peng Xu26b356d2017-10-04 17:58:16 -070010019 if (!ip)
10020 return 0;
10021
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010022 snprintf(buf, sizeof(buf), "ndisc6 -nm %s %s -r 4", ip, intf);
10023 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10024 if (system(buf) == 0) {
10025 sigma_dut_print(dut, DUT_MSG_INFO,
10026 "Neighbor Solicitation got a response "
10027 "for %s@%s", ip, intf);
10028 }
10029
10030 return 1;
10031}
10032
10033
10034static int cmd_sta_send_frame_hs2_arpprobe(struct sigma_dut *dut,
10035 struct sigma_conn *conn,
10036 struct sigma_cmd *cmd,
10037 const char *ifname)
10038{
10039 char buf[200];
10040 const char *ip = get_param(cmd, "SenderIP");
10041
10042 if (ip == NULL) {
10043 send_resp(dut, conn, SIGMA_ERROR,
10044 "ErrorCode,Missing SenderIP parameter");
10045 return 0;
10046 }
10047 snprintf(buf, sizeof(buf), "arping -I %s -D %s -c 4", ifname, ip);
10048 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10049 if (system(buf) != 0) {
10050 sigma_dut_print(dut, DUT_MSG_INFO, "arping DAD got a response "
10051 "for %s@%s", ip, ifname);
10052 }
10053
10054 return 1;
10055}
10056
10057
10058static int cmd_sta_send_frame_hs2_arpannounce(struct sigma_dut *dut,
10059 struct sigma_conn *conn,
10060 struct sigma_cmd *cmd,
10061 const char *ifname)
10062{
10063 char buf[200];
10064 char ip[16];
10065 int s;
Peng Xub3756882017-10-04 14:39:09 -070010066 struct ifreq ifr;
10067 struct sockaddr_in saddr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010068
10069 s = socket(PF_INET, SOCK_DGRAM, 0);
Peng Xub3756882017-10-04 14:39:09 -070010070 if (s < 0) {
10071 perror("socket");
10072 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010073 }
10074
Peng Xub3756882017-10-04 14:39:09 -070010075 memset(&ifr, 0, sizeof(ifr));
10076 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
10077 if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
10078 sigma_dut_print(dut, DUT_MSG_INFO,
10079 "Failed to get %s IP address: %s",
10080 ifname, strerror(errno));
10081 close(s);
10082 return -1;
10083 }
10084 close(s);
10085
10086 memcpy(&saddr, &ifr.ifr_addr, sizeof(struct sockaddr_in));
10087 strlcpy(ip, inet_ntoa(saddr.sin_addr), sizeof(ip));
10088
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010089 snprintf(buf, sizeof(buf), "arping -I %s -s %s %s -c 4", ifname, ip,
10090 ip);
10091 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10092 if (system(buf) != 0) {
10093 }
10094
10095 return 1;
10096}
10097
10098
10099static int cmd_sta_send_frame_hs2_arpreply(struct sigma_dut *dut,
10100 struct sigma_conn *conn,
10101 struct sigma_cmd *cmd,
10102 const char *ifname)
10103{
10104 char buf[200], addr[20];
10105 char dst[ETH_ALEN], src[ETH_ALEN];
10106 short ethtype = htons(ETH_P_ARP);
10107 char *pos;
10108 int s, res;
10109 const char *val;
10110 struct sockaddr_in taddr;
10111
10112 val = get_param(cmd, "dest");
10113 if (val)
10114 hwaddr_aton(val, (unsigned char *) dst);
10115
10116 val = get_param(cmd, "DestIP");
10117 if (val)
10118 inet_aton(val, &taddr.sin_addr);
Peng Xu151c9e12017-10-04 14:39:09 -070010119 else
10120 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010121
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010122 if (get_wpa_status(get_station_ifname(dut), "address", addr,
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010123 sizeof(addr)) < 0)
10124 return -2;
10125 hwaddr_aton(addr, (unsigned char *) src);
10126
10127 pos = buf;
10128 *pos++ = 0x00;
10129 *pos++ = 0x01;
10130 *pos++ = 0x08;
10131 *pos++ = 0x00;
10132 *pos++ = 0x06;
10133 *pos++ = 0x04;
10134 *pos++ = 0x00;
10135 *pos++ = 0x02;
10136 memcpy(pos, src, ETH_ALEN);
10137 pos += ETH_ALEN;
10138 memcpy(pos, &taddr.sin_addr, 4);
10139 pos += 4;
10140 memcpy(pos, dst, ETH_ALEN);
10141 pos += ETH_ALEN;
10142 memcpy(pos, &taddr.sin_addr, 4);
10143 pos += 4;
10144
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010145 s = open_monitor(get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010146 if (s < 0) {
10147 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
10148 "monitor socket");
10149 return 0;
10150 }
10151
10152 res = inject_eth_frame(s, buf, pos - buf, ethtype, dst, src);
10153 if (res < 0) {
10154 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
10155 "inject frame");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +053010156 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010157 return 0;
10158 }
10159
10160 close(s);
10161
10162 return 1;
10163}
10164
10165
10166static int cmd_sta_send_frame_hs2_dls_req(struct sigma_dut *dut,
10167 struct sigma_conn *conn,
10168 struct sigma_cmd *cmd,
10169 const char *intf, const char *dest)
10170{
10171 char buf[100];
10172
10173 if (if_nametoindex("sigmadut") == 0) {
10174 snprintf(buf, sizeof(buf),
10175 "iw dev %s interface add sigmadut type monitor",
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010176 get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010177 if (system(buf) != 0 ||
10178 if_nametoindex("sigmadut") == 0) {
10179 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
10180 "monitor interface with '%s'", buf);
10181 return -2;
10182 }
10183 }
10184
10185 if (system("ifconfig sigmadut up") != 0) {
10186 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
10187 "monitor interface up");
10188 return -2;
10189 }
10190
10191 return sta_inject_frame(dut, conn, DLS_REQ, UNPROTECTED, dest);
10192}
10193
10194
10195static int cmd_sta_send_frame_hs2(struct sigma_dut *dut,
10196 struct sigma_conn *conn,
10197 struct sigma_cmd *cmd)
10198{
10199 const char *intf = get_param(cmd, "Interface");
10200 const char *dest = get_param(cmd, "Dest");
10201 const char *type = get_param(cmd, "FrameName");
10202 const char *val;
10203 char buf[200], *pos, *end;
10204 int count, count2;
10205
10206 if (type == NULL)
10207 type = get_param(cmd, "Type");
10208
10209 if (intf == NULL || dest == NULL || type == NULL)
10210 return -1;
10211
10212 if (strcasecmp(type, "NeighAdv") == 0)
10213 return cmd_sta_send_frame_hs2_neighadv(dut, conn, cmd, intf);
10214
10215 if (strcasecmp(type, "NeighSolicitReq") == 0)
10216 return cmd_sta_send_frame_hs2_neighsolreq(dut, conn, cmd, intf);
10217
10218 if (strcasecmp(type, "ARPProbe") == 0)
10219 return cmd_sta_send_frame_hs2_arpprobe(dut, conn, cmd, intf);
10220
10221 if (strcasecmp(type, "ARPAnnounce") == 0)
10222 return cmd_sta_send_frame_hs2_arpannounce(dut, conn, cmd, intf);
10223
10224 if (strcasecmp(type, "ARPReply") == 0)
10225 return cmd_sta_send_frame_hs2_arpreply(dut, conn, cmd, intf);
10226
10227 if (strcasecmp(type, "DLS-request") == 0 ||
10228 strcasecmp(type, "DLSrequest") == 0)
10229 return cmd_sta_send_frame_hs2_dls_req(dut, conn, cmd, intf,
10230 dest);
10231
10232 if (strcasecmp(type, "ANQPQuery") != 0 &&
10233 strcasecmp(type, "Query") != 0) {
10234 send_resp(dut, conn, SIGMA_ERROR,
10235 "ErrorCode,Unsupported HS 2.0 send frame type");
10236 return 0;
10237 }
10238
10239 if (sta_scan_ap(dut, intf, dest) < 0) {
10240 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not find "
10241 "the requested AP");
10242 return 0;
10243 }
10244
10245 pos = buf;
10246 end = buf + sizeof(buf);
10247 count = 0;
10248 pos += snprintf(pos, end - pos, "ANQP_GET %s ", dest);
10249
10250 val = get_param(cmd, "ANQP_CAP_LIST");
10251 if (val && atoi(val)) {
10252 pos += snprintf(pos, end - pos, "%s257", count > 0 ? "," : "");
10253 count++;
10254 }
10255
10256 val = get_param(cmd, "VENUE_NAME");
10257 if (val && atoi(val)) {
10258 pos += snprintf(pos, end - pos, "%s258", count > 0 ? "," : "");
10259 count++;
10260 }
10261
10262 val = get_param(cmd, "NETWORK_AUTH_TYPE");
10263 if (val && atoi(val)) {
10264 pos += snprintf(pos, end - pos, "%s260", count > 0 ? "," : "");
10265 count++;
10266 }
10267
10268 val = get_param(cmd, "ROAMING_CONS");
10269 if (val && atoi(val)) {
10270 pos += snprintf(pos, end - pos, "%s261", count > 0 ? "," : "");
10271 count++;
10272 }
10273
10274 val = get_param(cmd, "IP_ADDR_TYPE_AVAILABILITY");
10275 if (val && atoi(val)) {
10276 pos += snprintf(pos, end - pos, "%s262", count > 0 ? "," : "");
10277 count++;
10278 }
10279
10280 val = get_param(cmd, "NAI_REALM_LIST");
10281 if (val && atoi(val)) {
10282 pos += snprintf(pos, end - pos, "%s263", count > 0 ? "," : "");
10283 count++;
10284 }
10285
10286 val = get_param(cmd, "3GPP_INFO");
10287 if (val && atoi(val)) {
10288 pos += snprintf(pos, end - pos, "%s264", count > 0 ? "," : "");
10289 count++;
10290 }
10291
10292 val = get_param(cmd, "DOMAIN_LIST");
10293 if (val && atoi(val)) {
10294 pos += snprintf(pos, end - pos, "%s268", count > 0 ? "," : "");
10295 count++;
10296 }
10297
Jouni Malinen34cf9532018-04-29 19:26:33 +030010298 val = get_param(cmd, "Venue_URL");
10299 if (val && atoi(val)) {
10300 pos += snprintf(pos, end - pos, "%s277", count > 0 ? "," : "");
10301 count++;
10302 }
10303
Jouni Malinend3bca5d2018-04-29 17:25:23 +030010304 val = get_param(cmd, "Advice_Of_Charge");
10305 if (val && atoi(val)) {
10306 pos += snprintf(pos, end - pos, "%s278", count > 0 ? "," : "");
10307 count++;
10308 }
10309
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010310 if (count && wpa_command(intf, buf)) {
10311 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,ANQP_GET failed");
10312 return 0;
10313 }
10314
10315 pos = buf;
10316 end = buf + sizeof(buf);
10317 count2 = 0;
10318 pos += snprintf(pos, end - pos, "HS20_ANQP_GET %s ", dest);
10319
10320 val = get_param(cmd, "HS_CAP_LIST");
10321 if (val && atoi(val)) {
10322 pos += snprintf(pos, end - pos, "%s2", count2 > 0 ? "," : "");
10323 count2++;
10324 }
10325
10326 val = get_param(cmd, "OPER_NAME");
10327 if (val && atoi(val)) {
10328 pos += snprintf(pos, end - pos, "%s3", count2 > 0 ? "," : "");
10329 count2++;
10330 }
10331
10332 val = get_param(cmd, "WAN_METRICS");
10333 if (!val)
10334 val = get_param(cmd, "WAN_MAT");
10335 if (!val)
10336 val = get_param(cmd, "WAN_MET");
10337 if (val && atoi(val)) {
10338 pos += snprintf(pos, end - pos, "%s4", count2 > 0 ? "," : "");
10339 count2++;
10340 }
10341
10342 val = get_param(cmd, "CONNECTION_CAPABILITY");
10343 if (val && atoi(val)) {
10344 pos += snprintf(pos, end - pos, "%s5", count2 > 0 ? "," : "");
10345 count2++;
10346 }
10347
10348 val = get_param(cmd, "OP_CLASS");
10349 if (val && atoi(val)) {
10350 pos += snprintf(pos, end - pos, "%s7", count2 > 0 ? "," : "");
10351 count2++;
10352 }
10353
10354 val = get_param(cmd, "OSU_PROVIDER_LIST");
10355 if (val && atoi(val)) {
10356 pos += snprintf(pos, end - pos, "%s8", count2 > 0 ? "," : "");
10357 count2++;
10358 }
10359
Jouni Malinenf67afec2018-04-29 19:24:58 +030010360 val = get_param(cmd, "OPER_ICON_METADATA");
10361 if (!val)
10362 val = get_param(cmd, "OPERATOR_ICON_METADATA");
10363 if (val && atoi(val)) {
10364 pos += snprintf(pos, end - pos, "%s12", count2 > 0 ? "," : "");
10365 count2++;
10366 }
10367
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010368 if (count && count2) {
10369 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before sending out "
10370 "second query");
10371 sleep(1);
10372 }
10373
10374 if (count2 && wpa_command(intf, buf)) {
10375 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,HS20_ANQP_GET "
10376 "failed");
10377 return 0;
10378 }
10379
10380 val = get_param(cmd, "NAI_HOME_REALM_LIST");
10381 if (val) {
10382 if (count || count2) {
10383 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
10384 "sending out second query");
10385 sleep(1);
10386 }
10387
10388 if (strcmp(val, "1") == 0)
10389 val = "mail.example.com";
10390 snprintf(buf, end - pos,
10391 "HS20_GET_NAI_HOME_REALM_LIST %s realm=%s",
10392 dest, val);
10393 if (wpa_command(intf, buf)) {
10394 send_resp(dut, conn, SIGMA_ERROR,
10395 "ErrorCode,HS20_GET_NAI_HOME_REALM_LIST "
10396 "failed");
10397 return 0;
10398 }
10399 }
10400
10401 val = get_param(cmd, "ICON_REQUEST");
10402 if (val) {
10403 if (count || count2) {
10404 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
10405 "sending out second query");
10406 sleep(1);
10407 }
10408
10409 snprintf(buf, end - pos,
10410 "HS20_ICON_REQUEST %s %s", dest, val);
10411 if (wpa_command(intf, buf)) {
10412 send_resp(dut, conn, SIGMA_ERROR,
10413 "ErrorCode,HS20_ICON_REQUEST failed");
10414 return 0;
10415 }
10416 }
10417
10418 return 1;
10419}
10420
10421
10422static int ath_sta_send_frame_vht(struct sigma_dut *dut,
10423 struct sigma_conn *conn,
10424 struct sigma_cmd *cmd)
10425{
10426 const char *val;
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010427 const char *ifname;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010428 int chwidth, nss;
10429
10430 val = get_param(cmd, "framename");
10431 if (!val)
10432 return -1;
10433 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
10434
10435 /* Command sequence to generate Op mode notification */
10436 if (val && strcasecmp(val, "Op_md_notif_frm") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010437 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010438
10439 /* Disable STBC */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010440 run_iwpriv(dut, ifname, "tx_stbc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010441
10442 /* Extract Channel width */
10443 val = get_param(cmd, "Channel_width");
10444 if (val) {
10445 switch (atoi(val)) {
10446 case 20:
10447 chwidth = 0;
10448 break;
10449 case 40:
10450 chwidth = 1;
10451 break;
10452 case 80:
10453 chwidth = 2;
10454 break;
10455 case 160:
10456 chwidth = 3;
10457 break;
10458 default:
10459 chwidth = 2;
10460 break;
10461 }
10462
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010463 run_iwpriv(dut, ifname, "chwidth %d", chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010464 }
10465
10466 /* Extract NSS */
10467 val = get_param(cmd, "NSS");
10468 if (val) {
10469 switch (atoi(val)) {
10470 case 1:
10471 nss = 1;
10472 break;
10473 case 2:
10474 nss = 3;
10475 break;
10476 case 3:
10477 nss = 7;
10478 break;
10479 default:
10480 /* We do not support NSS > 3 */
10481 nss = 3;
10482 break;
10483 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010484 run_iwpriv(dut, ifname, "rxchainmask %d", nss);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010485 }
10486
10487 /* Opmode notify */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010488 run_iwpriv(dut, ifname, "opmode_notify 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010489 }
10490
10491 return 1;
10492}
10493
10494
10495static int cmd_sta_send_frame_vht(struct sigma_dut *dut,
10496 struct sigma_conn *conn,
10497 struct sigma_cmd *cmd)
10498{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010499 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010500 case DRIVER_ATHEROS:
10501 return ath_sta_send_frame_vht(dut, conn, cmd);
10502 default:
10503 send_resp(dut, conn, SIGMA_ERROR,
10504 "errorCode,Unsupported sta_set_frame(VHT) with the current driver");
10505 return 0;
10506 }
10507}
10508
10509
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070010510static int wcn_sta_send_frame_he(struct sigma_dut *dut, struct sigma_conn *conn,
10511 struct sigma_cmd *cmd)
10512{
10513 const char *val;
10514 const char *intf = get_param(cmd, "Interface");
10515
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +030010516 if (!intf)
10517 return -1;
10518
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070010519 val = get_param(cmd, "framename");
10520 if (!val)
10521 return -1;
10522 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
10523
10524 /* Command sequence to generate Op mode notification */
10525 if (val && strcasecmp(val, "action") == 0) {
10526 val = get_param(cmd, "PPDUTxType");
10527 if (val && strcasecmp(val, "TB") == 0) {
10528 if (sta_set_action_tx_in_he_tb_ppdu(dut, intf, 1)) {
10529 sigma_dut_print(dut, DUT_MSG_ERROR,
10530 "failed to send TB PPDU Tx cfg");
10531 send_resp(dut, conn, SIGMA_ERROR,
10532 "ErrorCode,set TB PPDU Tx cfg failed");
10533 return 0;
10534 }
10535 return 1;
10536 }
10537
10538 sigma_dut_print(dut, DUT_MSG_ERROR,
10539 "Action Tx type is not defined");
10540 }
10541
10542 return 1;
10543}
10544
10545
10546static int cmd_sta_send_frame_he(struct sigma_dut *dut,
10547 struct sigma_conn *conn,
10548 struct sigma_cmd *cmd)
10549{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010550 switch (get_driver_type(dut)) {
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070010551 case DRIVER_WCN:
10552 return wcn_sta_send_frame_he(dut, conn, cmd);
10553 default:
10554 send_resp(dut, conn, SIGMA_ERROR,
10555 "errorCode,Unsupported sta_set_frame(HE) with the current driver");
10556 return 0;
10557 }
10558}
10559
10560
Lior David0fe101e2017-03-09 16:09:50 +020010561#ifdef __linux__
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030010562
10563static int
10564wil6210_send_p2p_frame_60g(struct sigma_dut *dut, struct sigma_cmd *cmd,
10565 const char *frame_name, const char *dest_mac)
10566{
10567 int isprobereq = strcasecmp(frame_name, "probereq") == 0;
10568 const char *ssid = get_param(cmd, "ssid");
10569 const char *countstr = get_param(cmd, "count");
10570 const char *channelstr = get_param(cmd, "channel");
10571 const char *group_id = get_param(cmd, "groupid");
10572 const char *client_id = get_param(cmd, "clientmac");
10573 int count, channel, freq, i;
10574 const char *fname;
10575 char frame[1024], src_mac[20], group_id_attr[25],
10576 device_macstr[3 * ETH_ALEN], client_mac[ETH_ALEN];
10577 const char *group_ssid;
10578 const int group_ssid_prefix_len = 9;
10579 struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *) frame;
10580 size_t framelen = sizeof(frame);
10581 struct template_frame_tag tags[2];
10582 size_t tags_total = ARRAY_SIZE(tags);
10583 int tag_index, len, dst_len;
10584
10585 if (!countstr || !channelstr) {
10586 sigma_dut_print(dut, DUT_MSG_ERROR,
10587 "Missing argument: count, channel");
10588 return -1;
10589 }
10590 if (isprobereq && !ssid) {
10591 sigma_dut_print(dut, DUT_MSG_ERROR,
10592 "Missing argument: ssid");
10593 return -1;
10594 }
10595 if (!isprobereq && (!group_id || !client_id)) {
10596 sigma_dut_print(dut, DUT_MSG_ERROR,
10597 "Missing argument: group_id, client_id");
10598 return -1;
10599 }
10600
10601 count = atoi(countstr);
10602 channel = atoi(channelstr);
10603 freq = channel_to_freq(dut, channel);
10604
10605 if (!freq) {
10606 sigma_dut_print(dut, DUT_MSG_ERROR,
10607 "invalid channel: %s", channelstr);
10608 return -1;
10609 }
10610
10611 if (isprobereq) {
10612 if (strcasecmp(ssid, "wildcard") == 0) {
10613 fname = "probe_req_wildcard.txt";
10614 } else if (strcasecmp(ssid, "P2P_Wildcard") == 0) {
10615 fname = "probe_req_P2P_Wildcard.txt";
10616 } else {
10617 sigma_dut_print(dut, DUT_MSG_ERROR,
10618 "invalid probe request type");
10619 return -1;
10620 }
10621 } else {
10622 fname = "P2P_device_discovery_req.txt";
10623 }
10624
10625 if (parse_template_frame_file(dut, fname, frame, &framelen,
10626 tags, &tags_total)) {
10627 sigma_dut_print(dut, DUT_MSG_ERROR,
10628 "invalid frame template: %s", fname);
10629 return -1;
10630 }
10631
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010632 if (get_wpa_status(get_station_ifname(dut), "address",
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030010633 src_mac, sizeof(src_mac)) < 0 ||
10634 parse_mac_address(dut, src_mac, &hdr->addr2[0]) ||
10635 parse_mac_address(dut, dest_mac, &hdr->addr1[0]))
10636 return -1;
10637 /* Use wildcard BSSID, since we are in PBSS */
10638 memset(&hdr->addr3, 0xFF, ETH_ALEN);
10639
10640 if (!isprobereq) {
10641 tag_index = find_template_frame_tag(tags, tags_total, 1);
10642 if (tag_index < 0) {
10643 sigma_dut_print(dut, DUT_MSG_ERROR,
10644 "can't find device id attribute");
10645 return -1;
10646 }
10647 if (parse_mac_address(dut, client_id,
10648 (unsigned char *) client_mac)) {
10649 sigma_dut_print(dut, DUT_MSG_ERROR,
10650 "invalid client_id: %s", client_id);
10651 return -1;
10652 }
10653 if (replace_p2p_attribute(dut, &frame[tags[tag_index].offset],
10654 framelen - tags[tag_index].offset,
10655 IEEE80211_P2P_ATTR_DEVICE_ID,
10656 client_mac, ETH_ALEN)) {
10657 sigma_dut_print(dut, DUT_MSG_ERROR,
10658 "fail to replace device id attribute");
10659 return -1;
10660 }
10661
10662 /*
10663 * group_id arg contains device MAC address followed by
10664 * space and SSID (DIRECT-somessid).
10665 * group id attribute contains device address (6 bytes)
10666 * followed by SSID prefix DIRECT-XX (9 bytes)
10667 */
10668 if (strlen(group_id) < sizeof(device_macstr)) {
10669 sigma_dut_print(dut, DUT_MSG_ERROR,
10670 "group_id arg too short");
10671 return -1;
10672 }
10673 memcpy(device_macstr, group_id, sizeof(device_macstr));
10674 device_macstr[sizeof(device_macstr) - 1] = '\0';
10675 if (parse_mac_address(dut, device_macstr,
10676 (unsigned char *) group_id_attr)) {
10677 sigma_dut_print(dut, DUT_MSG_ERROR,
10678 "fail to parse device address from group_id");
10679 return -1;
10680 }
10681 group_ssid = strchr(group_id, ' ');
10682 if (!group_ssid) {
10683 sigma_dut_print(dut, DUT_MSG_ERROR,
10684 "invalid group_id arg, no ssid");
10685 return -1;
10686 }
10687 group_ssid++;
10688 len = strlen(group_ssid);
10689 if (len < group_ssid_prefix_len) {
10690 sigma_dut_print(dut, DUT_MSG_ERROR,
10691 "group_id SSID too short");
10692 return -1;
10693 }
10694 dst_len = sizeof(group_id_attr) - ETH_ALEN;
10695 if (len > dst_len) {
10696 sigma_dut_print(dut, DUT_MSG_ERROR,
10697 "group_id SSID (%s) too long",
10698 group_ssid);
10699 return -1;
10700 }
10701
10702 memcpy(group_id_attr + ETH_ALEN, group_ssid, len);
10703 tag_index = find_template_frame_tag(tags, tags_total, 2);
10704 if (tag_index < 0) {
10705 sigma_dut_print(dut, DUT_MSG_ERROR,
10706 "can't find group id attribute");
10707 return -1;
10708 }
10709 if (replace_p2p_attribute(dut, &frame[tags[tag_index].offset],
10710 framelen - tags[tag_index].offset,
10711 IEEE80211_P2P_ATTR_GROUP_ID,
10712 group_id_attr,
10713 sizeof(group_id_attr))) {
10714 sigma_dut_print(dut, DUT_MSG_ERROR,
10715 "fail to replace group id attribute");
10716 return -1;
10717 }
10718 }
10719
10720 for (i = 0; i < count; i++) {
10721 if (wil6210_transmit_frame(dut, freq,
10722 WIL_TRANSMIT_FRAME_DEFAULT_ROC,
10723 frame, framelen)) {
10724 sigma_dut_print(dut, DUT_MSG_ERROR,
10725 "fail to transmit probe request frame");
10726 return -1;
10727 }
10728 }
10729
10730 return 0;
10731}
10732
10733
Lior David0fe101e2017-03-09 16:09:50 +020010734int wil6210_send_frame_60g(struct sigma_dut *dut, struct sigma_conn *conn,
10735 struct sigma_cmd *cmd)
10736{
10737 const char *frame_name = get_param(cmd, "framename");
10738 const char *mac = get_param(cmd, "dest_mac");
10739
10740 if (!frame_name || !mac) {
10741 sigma_dut_print(dut, DUT_MSG_ERROR,
10742 "framename and dest_mac must be provided");
10743 return -1;
10744 }
10745
10746 if (strcasecmp(frame_name, "brp") == 0) {
10747 const char *l_rx = get_param(cmd, "L-RX");
10748 int l_rx_i;
10749
10750 if (!l_rx) {
10751 sigma_dut_print(dut, DUT_MSG_ERROR,
10752 "L-RX must be provided");
10753 return -1;
10754 }
10755 l_rx_i = atoi(l_rx);
10756
10757 sigma_dut_print(dut, DUT_MSG_INFO,
10758 "dev_send_frame: BRP-RX, dest_mac %s, L-RX %s",
10759 mac, l_rx);
10760 if (l_rx_i != 16) {
10761 sigma_dut_print(dut, DUT_MSG_ERROR,
10762 "unsupported L-RX: %s", l_rx);
10763 return -1;
10764 }
10765
10766 if (wil6210_send_brp_rx(dut, mac, l_rx_i))
10767 return -1;
10768 } else if (strcasecmp(frame_name, "ssw") == 0) {
10769 sigma_dut_print(dut, DUT_MSG_INFO,
10770 "dev_send_frame: SLS, dest_mac %s", mac);
10771 if (wil6210_send_sls(dut, mac))
10772 return -1;
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030010773 } else if ((strcasecmp(frame_name, "probereq") == 0) ||
10774 (strcasecmp(frame_name, "devdiscreq") == 0)) {
10775 sigma_dut_print(dut, DUT_MSG_INFO,
10776 "dev_send_frame: %s, dest_mac %s", frame_name,
10777 mac);
10778 if (wil6210_send_p2p_frame_60g(dut, cmd, frame_name, mac))
10779 return -1;
Lior David0fe101e2017-03-09 16:09:50 +020010780 } else {
10781 sigma_dut_print(dut, DUT_MSG_ERROR,
10782 "unsupported frame type: %s", frame_name);
10783 return -1;
10784 }
10785
10786 return 1;
10787}
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030010788
Lior David0fe101e2017-03-09 16:09:50 +020010789#endif /* __linux__ */
10790
10791
10792static int cmd_sta_send_frame_60g(struct sigma_dut *dut,
10793 struct sigma_conn *conn,
10794 struct sigma_cmd *cmd)
10795{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010796 switch (get_driver_type(dut)) {
Lior David0fe101e2017-03-09 16:09:50 +020010797#ifdef __linux__
10798 case DRIVER_WIL6210:
10799 return wil6210_send_frame_60g(dut, conn, cmd);
10800#endif /* __linux__ */
10801 default:
10802 send_resp(dut, conn, SIGMA_ERROR,
10803 "errorCode,Unsupported sta_set_frame(60G) with the current driver");
10804 return 0;
10805 }
10806}
10807
10808
Ashwini Patildb59b3c2017-04-13 15:19:23 +053010809static int mbo_send_anqp_query(struct sigma_dut *dut, struct sigma_conn *conn,
10810 const char *intf, struct sigma_cmd *cmd)
10811{
10812 const char *val, *addr;
10813 char buf[100];
10814
10815 addr = get_param(cmd, "DestMac");
10816 if (!addr) {
10817 send_resp(dut, conn, SIGMA_INVALID,
10818 "ErrorCode,AP MAC address is missing");
10819 return 0;
10820 }
10821
10822 val = get_param(cmd, "ANQPQuery_ID");
10823 if (!val) {
10824 send_resp(dut, conn, SIGMA_INVALID,
10825 "ErrorCode,Missing ANQPQuery_ID");
10826 return 0;
10827 }
10828
10829 if (strcasecmp(val, "NeighborReportReq") == 0) {
10830 snprintf(buf, sizeof(buf), "ANQP_GET %s 272", addr);
10831 } else if (strcasecmp(val, "QueryListWithCellPref") == 0) {
10832 snprintf(buf, sizeof(buf), "ANQP_GET %s 272,mbo:2", addr);
10833 } else {
10834 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid ANQPQuery_ID: %s",
10835 val);
10836 send_resp(dut, conn, SIGMA_INVALID,
10837 "ErrorCode,Invalid ANQPQuery_ID");
10838 return 0;
10839 }
10840
Ashwini Patild174f2c2017-04-13 16:49:46 +053010841 /* Set gas_address3 field to IEEE 802.11-2012 standard compliant form
10842 * (Address3 = Wildcard BSSID when sent to not-associated AP;
10843 * if associated, AP BSSID).
10844 */
10845 if (wpa_command(intf, "SET gas_address3 1") < 0) {
10846 send_resp(dut, conn, SIGMA_ERROR,
10847 "ErrorCode,Failed to set gas_address3");
10848 return 0;
10849 }
10850
Ashwini Patildb59b3c2017-04-13 15:19:23 +053010851 if (wpa_command(intf, buf) < 0) {
10852 send_resp(dut, conn, SIGMA_ERROR,
10853 "ErrorCode,Failed to send ANQP query");
10854 return 0;
10855 }
10856
10857 return 1;
10858}
10859
10860
10861static int mbo_cmd_sta_send_frame(struct sigma_dut *dut,
10862 struct sigma_conn *conn,
10863 const char *intf,
10864 struct sigma_cmd *cmd)
10865{
10866 const char *val = get_param(cmd, "FrameName");
10867
10868 if (val && strcasecmp(val, "ANQPQuery") == 0)
10869 return mbo_send_anqp_query(dut, conn, intf, cmd);
10870
10871 return 2;
10872}
10873
10874
Jouni Malinenf7222712019-06-13 01:50:21 +030010875enum sigma_cmd_result cmd_sta_send_frame(struct sigma_dut *dut,
10876 struct sigma_conn *conn,
10877 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010878{
10879 const char *intf = get_param(cmd, "Interface");
10880 const char *val;
10881 enum send_frame_type frame;
10882 enum send_frame_protection protected;
10883 char buf[100];
10884 unsigned char addr[ETH_ALEN];
10885 int res;
10886
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +030010887 if (!intf)
10888 return -1;
10889
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010890 val = get_param(cmd, "program");
10891 if (val == NULL)
10892 val = get_param(cmd, "frame");
10893 if (val && strcasecmp(val, "TDLS") == 0)
10894 return cmd_sta_send_frame_tdls(dut, conn, cmd);
10895 if (val && (strcasecmp(val, "HS2") == 0 ||
Jouni Malinen1f6ae642018-06-07 23:56:13 +030010896 strcasecmp(val, "HS2-R2") == 0 ||
10897 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010898 return cmd_sta_send_frame_hs2(dut, conn, cmd);
10899 if (val && strcasecmp(val, "VHT") == 0)
10900 return cmd_sta_send_frame_vht(dut, conn, cmd);
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070010901 if (val && strcasecmp(val, "HE") == 0)
10902 return cmd_sta_send_frame_he(dut, conn, cmd);
priyadharshini gowthamand66913a2016-07-29 15:11:17 -070010903 if (val && strcasecmp(val, "LOC") == 0)
10904 return loc_cmd_sta_send_frame(dut, conn, cmd);
Lior David0fe101e2017-03-09 16:09:50 +020010905 if (val && strcasecmp(val, "60GHz") == 0)
10906 return cmd_sta_send_frame_60g(dut, conn, cmd);
Ashwini Patildb59b3c2017-04-13 15:19:23 +053010907 if (val && strcasecmp(val, "MBO") == 0) {
10908 res = mbo_cmd_sta_send_frame(dut, conn, intf, cmd);
10909 if (res != 2)
10910 return res;
10911 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010912
10913 val = get_param(cmd, "TD_DISC");
10914 if (val) {
10915 if (hwaddr_aton(val, addr) < 0)
10916 return -1;
10917 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", val);
10918 if (wpa_command(intf, buf) < 0) {
10919 send_resp(dut, conn, SIGMA_ERROR,
10920 "ErrorCode,Failed to send TDLS discovery");
10921 return 0;
10922 }
10923 return 1;
10924 }
10925
10926 val = get_param(cmd, "TD_Setup");
10927 if (val) {
10928 if (hwaddr_aton(val, addr) < 0)
10929 return -1;
10930 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", val);
10931 if (wpa_command(intf, buf) < 0) {
10932 send_resp(dut, conn, SIGMA_ERROR,
10933 "ErrorCode,Failed to start TDLS setup");
10934 return 0;
10935 }
10936 return 1;
10937 }
10938
10939 val = get_param(cmd, "TD_TearDown");
10940 if (val) {
10941 if (hwaddr_aton(val, addr) < 0)
10942 return -1;
10943 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", val);
10944 if (wpa_command(intf, buf) < 0) {
10945 send_resp(dut, conn, SIGMA_ERROR,
10946 "ErrorCode,Failed to tear down TDLS link");
10947 return 0;
10948 }
10949 return 1;
10950 }
10951
10952 val = get_param(cmd, "TD_ChannelSwitch");
10953 if (val) {
10954 /* TODO */
10955 send_resp(dut, conn, SIGMA_ERROR,
10956 "ErrorCode,TD_ChannelSwitch not yet supported");
10957 return 0;
10958 }
10959
10960 val = get_param(cmd, "TD_NF");
10961 if (val) {
10962 /* TODO */
10963 send_resp(dut, conn, SIGMA_ERROR,
10964 "ErrorCode,TD_NF not yet supported");
10965 return 0;
10966 }
10967
10968 val = get_param(cmd, "PMFFrameType");
10969 if (val == NULL)
10970 val = get_param(cmd, "FrameName");
10971 if (val == NULL)
10972 val = get_param(cmd, "Type");
10973 if (val == NULL)
10974 return -1;
10975 if (strcasecmp(val, "disassoc") == 0)
10976 frame = DISASSOC;
10977 else if (strcasecmp(val, "deauth") == 0)
10978 frame = DEAUTH;
10979 else if (strcasecmp(val, "saquery") == 0)
10980 frame = SAQUERY;
10981 else if (strcasecmp(val, "auth") == 0)
10982 frame = AUTH;
10983 else if (strcasecmp(val, "assocreq") == 0)
10984 frame = ASSOCREQ;
10985 else if (strcasecmp(val, "reassocreq") == 0)
10986 frame = REASSOCREQ;
10987 else if (strcasecmp(val, "neigreq") == 0) {
10988 sigma_dut_print(dut, DUT_MSG_INFO, "Got neighbor request");
10989
10990 val = get_param(cmd, "ssid");
10991 if (val == NULL)
10992 return -1;
10993
10994 res = send_neighbor_request(dut, intf, val);
10995 if (res) {
10996 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
10997 "Failed to send neighbor report request");
10998 return 0;
10999 }
11000
11001 return 1;
Ashwini Patil5acd7382017-04-13 15:55:04 +053011002 } else if (strcasecmp(val, "transmgmtquery") == 0 ||
11003 strcasecmp(val, "BTMQuery") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011004 sigma_dut_print(dut, DUT_MSG_DEBUG,
11005 "Got Transition Management Query");
11006
Ashwini Patil5acd7382017-04-13 15:55:04 +053011007 res = send_trans_mgmt_query(dut, intf, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011008 if (res) {
11009 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
11010 "Failed to send Transition Management Query");
11011 return 0;
11012 }
11013
11014 return 1;
11015 } else {
11016 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
11017 "PMFFrameType");
11018 return 0;
11019 }
11020
11021 val = get_param(cmd, "PMFProtected");
11022 if (val == NULL)
11023 val = get_param(cmd, "Protected");
11024 if (val == NULL)
11025 return -1;
11026 if (strcasecmp(val, "Correct-key") == 0 ||
11027 strcasecmp(val, "CorrectKey") == 0)
11028 protected = CORRECT_KEY;
11029 else if (strcasecmp(val, "IncorrectKey") == 0)
11030 protected = INCORRECT_KEY;
11031 else if (strcasecmp(val, "Unprotected") == 0)
11032 protected = UNPROTECTED;
11033 else {
11034 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
11035 "PMFProtected");
11036 return 0;
11037 }
11038
11039 if (protected != UNPROTECTED &&
11040 (frame == AUTH || frame == ASSOCREQ || frame == REASSOCREQ)) {
11041 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Impossible "
11042 "PMFProtected for auth/assocreq/reassocreq");
11043 return 0;
11044 }
11045
11046 if (if_nametoindex("sigmadut") == 0) {
11047 snprintf(buf, sizeof(buf),
11048 "iw dev %s interface add sigmadut type monitor",
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011049 get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011050 if (system(buf) != 0 ||
11051 if_nametoindex("sigmadut") == 0) {
11052 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
11053 "monitor interface with '%s'", buf);
11054 return -2;
11055 }
11056 }
11057
11058 if (system("ifconfig sigmadut up") != 0) {
11059 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
11060 "monitor interface up");
11061 return -2;
11062 }
11063
11064 return sta_inject_frame(dut, conn, frame, protected, NULL);
11065}
11066
11067
11068static int cmd_sta_set_parameter_hs2(struct sigma_dut *dut,
11069 struct sigma_conn *conn,
11070 struct sigma_cmd *cmd,
11071 const char *ifname)
11072{
11073 char buf[200];
11074 const char *val;
11075
11076 val = get_param(cmd, "ClearARP");
11077 if (val && atoi(val) == 1) {
11078 snprintf(buf, sizeof(buf), "ip neigh flush dev %s", ifname);
11079 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
11080 if (system(buf) != 0) {
11081 send_resp(dut, conn, SIGMA_ERROR,
11082 "errorCode,Failed to clear ARP cache");
11083 return 0;
11084 }
11085 }
11086
11087 return 1;
11088}
11089
11090
11091int cmd_sta_set_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
11092 struct sigma_cmd *cmd)
11093{
11094 const char *intf = get_param(cmd, "Interface");
11095 const char *val;
11096
11097 if (intf == NULL)
11098 return -1;
11099
11100 val = get_param(cmd, "program");
11101 if (val && (strcasecmp(val, "HS2") == 0 ||
Jouni Malinen1f6ae642018-06-07 23:56:13 +030011102 strcasecmp(val, "HS2-R2") == 0 ||
11103 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011104 return cmd_sta_set_parameter_hs2(dut, conn, cmd, intf);
11105
11106 return -1;
11107}
11108
11109
Jouni Malinenf7222712019-06-13 01:50:21 +030011110static enum sigma_cmd_result cmd_sta_set_macaddr(struct sigma_dut *dut,
11111 struct sigma_conn *conn,
11112 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011113{
11114 const char *intf = get_param(cmd, "Interface");
11115 const char *mac = get_param(cmd, "MAC");
11116
11117 if (intf == NULL || mac == NULL)
11118 return -1;
11119
11120 sigma_dut_print(dut, DUT_MSG_INFO, "Change local MAC address for "
11121 "interface %s to %s", intf, mac);
11122
11123 if (dut->set_macaddr) {
11124 char buf[128];
11125 int res;
11126 if (strcasecmp(mac, "default") == 0) {
11127 res = snprintf(buf, sizeof(buf), "%s",
11128 dut->set_macaddr);
11129 dut->tmp_mac_addr = 0;
11130 } else {
11131 res = snprintf(buf, sizeof(buf), "%s %s",
11132 dut->set_macaddr, mac);
11133 dut->tmp_mac_addr = 1;
11134 }
11135 if (res < 0 || res >= (int) sizeof(buf))
11136 return -1;
11137 if (system(buf) != 0) {
11138 send_resp(dut, conn, SIGMA_ERROR,
11139 "errorCode,Failed to set MAC "
11140 "address");
11141 return 0;
11142 }
11143 return 1;
11144 }
11145
11146 if (strcasecmp(mac, "default") == 0)
11147 return 1;
11148
11149 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
11150 "command");
11151 return 0;
11152}
11153
11154
11155static int iwpriv_tdlsoffchnmode(struct sigma_dut *dut,
11156 struct sigma_conn *conn, const char *intf,
11157 int val)
11158{
11159 char buf[200];
11160 int res;
11161
11162 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchnmode %d",
11163 intf, val);
11164 if (res < 0 || res >= (int) sizeof(buf))
11165 return -1;
11166 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
11167 if (system(buf) != 0) {
11168 send_resp(dut, conn, SIGMA_ERROR,
11169 "errorCode,Failed to configure offchannel mode");
11170 return 0;
11171 }
11172
11173 return 1;
11174}
11175
11176
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011177static int off_chan_val(enum sec_ch_offset off)
11178{
11179 switch (off) {
11180 case SEC_CH_NO:
11181 return 0;
11182 case SEC_CH_40ABOVE:
11183 return 40;
11184 case SEC_CH_40BELOW:
11185 return -40;
11186 }
11187
11188 return 0;
11189}
11190
11191
11192static int iwpriv_set_offchan(struct sigma_dut *dut, struct sigma_conn *conn,
11193 const char *intf, int off_ch_num,
11194 enum sec_ch_offset sec)
11195{
11196 char buf[200];
11197 int res;
11198
11199 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchan %d",
11200 intf, off_ch_num);
11201 if (res < 0 || res >= (int) sizeof(buf))
11202 return -1;
11203 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
11204 if (system(buf) != 0) {
11205 send_resp(dut, conn, SIGMA_ERROR,
11206 "errorCode,Failed to set offchan");
11207 return 0;
11208 }
11209
11210 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsecchnoffst %d",
11211 intf, off_chan_val(sec));
11212 if (res < 0 || res >= (int) sizeof(buf))
11213 return -1;
11214 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
11215 if (system(buf) != 0) {
11216 send_resp(dut, conn, SIGMA_ERROR,
11217 "errorCode,Failed to set sec chan offset");
11218 return 0;
11219 }
11220
11221 return 1;
11222}
11223
11224
11225static int tdls_set_offchannel_offset(struct sigma_dut *dut,
11226 struct sigma_conn *conn,
11227 const char *intf, int off_ch_num,
11228 enum sec_ch_offset sec)
11229{
11230 char buf[200];
11231 int res;
11232
11233 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNEL %d",
11234 off_ch_num);
11235 if (res < 0 || res >= (int) sizeof(buf))
11236 return -1;
11237 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
11238
11239 if (wpa_command(intf, buf) < 0) {
11240 send_resp(dut, conn, SIGMA_ERROR,
11241 "ErrorCode,Failed to set offchan");
11242 return 0;
11243 }
11244 res = snprintf(buf, sizeof(buf), "DRIVER TDLSSECONDARYCHANNELOFFSET %d",
11245 off_chan_val(sec));
11246 if (res < 0 || res >= (int) sizeof(buf))
11247 return -1;
11248
11249 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
11250
11251 if (wpa_command(intf, buf) < 0) {
11252 send_resp(dut, conn, SIGMA_ERROR,
11253 "ErrorCode,Failed to set sec chan offset");
11254 return 0;
11255 }
11256
11257 return 1;
11258}
11259
11260
11261static int tdls_set_offchannel_mode(struct sigma_dut *dut,
11262 struct sigma_conn *conn,
11263 const char *intf, int val)
11264{
11265 char buf[200];
11266 int res;
11267
11268 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNELMODE %d",
11269 val);
11270 if (res < 0 || res >= (int) sizeof(buf))
11271 return -1;
11272 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
11273
11274 if (wpa_command(intf, buf) < 0) {
11275 send_resp(dut, conn, SIGMA_ERROR,
11276 "ErrorCode,Failed to configure offchannel mode");
11277 return 0;
11278 }
11279
11280 return 1;
11281}
11282
11283
11284static int cmd_sta_set_rfeature_tdls(const char *intf, struct sigma_dut *dut,
11285 struct sigma_conn *conn,
11286 struct sigma_cmd *cmd)
11287{
11288 const char *val;
11289 enum {
11290 CHSM_NOT_SET,
11291 CHSM_ENABLE,
11292 CHSM_DISABLE,
11293 CHSM_REJREQ,
11294 CHSM_UNSOLRESP
11295 } chsm = CHSM_NOT_SET;
11296 int off_ch_num = -1;
11297 enum sec_ch_offset sec_ch = SEC_CH_NO;
11298 int res;
11299
11300 val = get_param(cmd, "Uapsd");
11301 if (val) {
11302 char buf[100];
11303 if (strcasecmp(val, "Enable") == 0)
11304 snprintf(buf, sizeof(buf), "SET ps 99");
11305 else if (strcasecmp(val, "Disable") == 0)
11306 snprintf(buf, sizeof(buf), "SET ps 98");
11307 else {
11308 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
11309 "Unsupported uapsd parameter value");
11310 return 0;
11311 }
11312 if (wpa_command(intf, buf)) {
11313 send_resp(dut, conn, SIGMA_ERROR,
11314 "ErrorCode,Failed to change U-APSD "
11315 "powersave mode");
11316 return 0;
11317 }
11318 }
11319
11320 val = get_param(cmd, "TPKTIMER");
11321 if (val && strcasecmp(val, "DISABLE") == 0) {
11322 if (wpa_command(intf, "SET tdls_testing 0x100")) {
11323 send_resp(dut, conn, SIGMA_ERROR,
11324 "ErrorCode,Failed to enable no TPK "
11325 "expiration test mode");
11326 return 0;
11327 }
11328 dut->no_tpk_expiration = 1;
11329 }
11330
11331 val = get_param(cmd, "ChSwitchMode");
11332 if (val) {
11333 if (strcasecmp(val, "Enable") == 0 ||
11334 strcasecmp(val, "Initiate") == 0)
11335 chsm = CHSM_ENABLE;
11336 else if (strcasecmp(val, "Disable") == 0 ||
11337 strcasecmp(val, "passive") == 0)
11338 chsm = CHSM_DISABLE;
11339 else if (strcasecmp(val, "RejReq") == 0)
11340 chsm = CHSM_REJREQ;
11341 else if (strcasecmp(val, "UnSolResp") == 0)
11342 chsm = CHSM_UNSOLRESP;
11343 else {
11344 send_resp(dut, conn, SIGMA_ERROR,
11345 "ErrorCode,Unknown ChSwitchMode value");
11346 return 0;
11347 }
11348 }
11349
11350 val = get_param(cmd, "OffChNum");
11351 if (val) {
11352 off_ch_num = atoi(val);
11353 if (off_ch_num == 0) {
11354 send_resp(dut, conn, SIGMA_ERROR,
11355 "ErrorCode,Invalid OffChNum");
11356 return 0;
11357 }
11358 }
11359
11360 val = get_param(cmd, "SecChOffset");
11361 if (val) {
11362 if (strcmp(val, "20") == 0)
11363 sec_ch = SEC_CH_NO;
11364 else if (strcasecmp(val, "40above") == 0)
11365 sec_ch = SEC_CH_40ABOVE;
11366 else if (strcasecmp(val, "40below") == 0)
11367 sec_ch = SEC_CH_40BELOW;
11368 else {
11369 send_resp(dut, conn, SIGMA_ERROR,
11370 "ErrorCode,Unknown SecChOffset value");
11371 return 0;
11372 }
11373 }
11374
11375 if (chsm == CHSM_NOT_SET) {
11376 /* no offchannel changes requested */
11377 return 1;
11378 }
11379
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011380 if (strcmp(intf, get_main_ifname(dut)) != 0 &&
11381 strcmp(intf, get_station_ifname(dut)) != 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011382 send_resp(dut, conn, SIGMA_ERROR,
11383 "ErrorCode,Unknown interface");
11384 return 0;
11385 }
11386
11387 switch (chsm) {
11388 case CHSM_NOT_SET:
Jouni Malinen280f5ba2016-08-29 21:33:10 +030011389 res = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011390 break;
11391 case CHSM_ENABLE:
11392 if (off_ch_num < 0) {
11393 send_resp(dut, conn, SIGMA_ERROR,
11394 "ErrorCode,Missing OffChNum argument");
11395 return 0;
11396 }
11397 if (wifi_chip_type == DRIVER_WCN) {
11398 res = tdls_set_offchannel_offset(dut, conn, intf,
11399 off_ch_num, sec_ch);
11400 } else {
11401 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
11402 sec_ch);
11403 }
11404 if (res != 1)
11405 return res;
11406 if (wifi_chip_type == DRIVER_WCN)
11407 res = tdls_set_offchannel_mode(dut, conn, intf, 1);
11408 else
11409 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 1);
11410 break;
11411 case CHSM_DISABLE:
11412 if (wifi_chip_type == DRIVER_WCN)
11413 res = tdls_set_offchannel_mode(dut, conn, intf, 2);
11414 else
11415 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 2);
11416 break;
11417 case CHSM_REJREQ:
11418 if (wifi_chip_type == DRIVER_WCN)
11419 res = tdls_set_offchannel_mode(dut, conn, intf, 3);
11420 else
11421 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 3);
11422 break;
11423 case CHSM_UNSOLRESP:
11424 if (off_ch_num < 0) {
11425 send_resp(dut, conn, SIGMA_ERROR,
11426 "ErrorCode,Missing OffChNum argument");
11427 return 0;
11428 }
11429 if (wifi_chip_type == DRIVER_WCN) {
11430 res = tdls_set_offchannel_offset(dut, conn, intf,
11431 off_ch_num, sec_ch);
11432 } else {
11433 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
11434 sec_ch);
11435 }
11436 if (res != 1)
11437 return res;
11438 if (wifi_chip_type == DRIVER_WCN)
11439 res = tdls_set_offchannel_mode(dut, conn, intf, 4);
11440 else
11441 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 4);
11442 break;
11443 }
11444
11445 return res;
11446}
11447
11448
11449static int ath_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
11450 struct sigma_conn *conn,
11451 struct sigma_cmd *cmd)
11452{
11453 const char *val;
Srikanth Marepalli5415acf2018-08-27 12:53:11 +053011454 char *token = NULL, *result;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011455
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -070011456 novap_reset(dut, intf, 1);
priyadharshini gowthamane5e25172015-12-08 14:53:48 -080011457
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011458 val = get_param(cmd, "nss_mcs_opt");
11459 if (val) {
11460 /* String (nss_operating_mode; mcs_operating_mode) */
11461 int nss, mcs;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053011462 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011463
11464 token = strdup(val);
11465 if (!token)
11466 return 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053011467 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +053011468 if (!result) {
11469 sigma_dut_print(dut, DUT_MSG_ERROR,
11470 "VHT NSS not specified");
11471 goto failed;
11472 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011473 if (strcasecmp(result, "def") != 0) {
11474 nss = atoi(result);
11475 if (nss == 4)
11476 ath_disable_txbf(dut, intf);
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011477 if (run_iwpriv(dut, intf, "nss %d", nss) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011478 goto failed;
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011479
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011480 }
11481
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053011482 result = strtok_r(NULL, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +053011483 if (!result) {
11484 sigma_dut_print(dut, DUT_MSG_ERROR,
11485 "VHT MCS not specified");
11486 goto failed;
11487 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011488 if (strcasecmp(result, "def") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011489 if (run_iwpriv(dut, intf, "set11NRates 0") < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011490 goto failed;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011491 } else {
11492 mcs = atoi(result);
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011493 if (run_iwpriv(dut, intf, "vhtmcs %d", mcs) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011494 goto failed;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011495 }
11496 /* Channel width gets messed up, fix this */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011497 run_iwpriv(dut, intf, "chwidth %d", dut->chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011498 }
11499
Srikanth Marepalli5415acf2018-08-27 12:53:11 +053011500 free(token);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011501 return 1;
11502failed:
11503 free(token);
11504 return 0;
11505}
11506
11507
11508static int cmd_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
11509 struct sigma_conn *conn,
11510 struct sigma_cmd *cmd)
11511{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011512 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011513 case DRIVER_ATHEROS:
11514 return ath_sta_set_rfeature_vht(intf, dut, conn, cmd);
11515 default:
11516 send_resp(dut, conn, SIGMA_ERROR,
11517 "errorCode,Unsupported sta_set_rfeature(VHT) with the current driver");
11518 return 0;
11519 }
11520}
11521
11522
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011523static int wcn_sta_set_rfeature_he(const char *intf, struct sigma_dut *dut,
11524 struct sigma_conn *conn,
11525 struct sigma_cmd *cmd)
11526{
11527 const char *val;
11528 char *token = NULL, *result;
11529 char buf[60];
11530
11531 val = get_param(cmd, "nss_mcs_opt");
11532 if (val) {
11533 /* String (nss_operating_mode; mcs_operating_mode) */
11534 int nss, mcs, ratecode;
11535 char *saveptr;
11536
11537 token = strdup(val);
11538 if (!token)
11539 return -2;
11540
11541 result = strtok_r(token, ";", &saveptr);
11542 if (!result) {
11543 sigma_dut_print(dut, DUT_MSG_ERROR,
11544 "HE NSS not specified");
11545 goto failed;
11546 }
11547 nss = 1;
11548 if (strcasecmp(result, "def") != 0)
11549 nss = atoi(result);
11550
11551 result = strtok_r(NULL, ";", &saveptr);
11552 if (!result) {
11553 sigma_dut_print(dut, DUT_MSG_ERROR,
11554 "HE MCS not specified");
11555 goto failed;
11556 }
11557 mcs = 7;
11558 if (strcasecmp(result, "def") != 0)
11559 mcs = atoi(result);
11560
Arif Hussain557bf412018-05-25 17:29:36 -070011561 ratecode = 0x20; /* for nss:1 MCS 0 */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011562 if (nss == 2) {
Arif Hussain557bf412018-05-25 17:29:36 -070011563 ratecode = 0x40; /* for nss:2 MCS 0 */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011564 } else if (nss > 2) {
11565 sigma_dut_print(dut, DUT_MSG_ERROR,
11566 "HE NSS %d not supported", nss);
11567 goto failed;
11568 }
11569
Arif Hussain557bf412018-05-25 17:29:36 -070011570 snprintf(buf, sizeof(buf), "iwpriv %s nss %d", intf, nss);
11571 if (system(buf) != 0) {
11572 sigma_dut_print(dut, DUT_MSG_ERROR,
11573 "nss_mcs_opt: iwpriv %s nss %d failed",
11574 intf, nss);
11575 goto failed;
11576 }
Arif Hussainac6c5112018-05-25 17:34:00 -070011577 dut->sta_nss = nss;
Arif Hussain557bf412018-05-25 17:29:36 -070011578
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011579 /* Add the MCS to the ratecode */
11580 if (mcs >= 0 && mcs <= 11) {
11581 ratecode += mcs;
Arif Hussain557bf412018-05-25 17:29:36 -070011582#ifdef NL80211_SUPPORT
11583 if (dut->device_type == STA_testbed) {
11584 enum he_mcs_config mcs_config;
11585 int ret;
11586
11587 if (mcs <= 7)
11588 mcs_config = HE_80_MCS0_7;
11589 else if (mcs <= 9)
11590 mcs_config = HE_80_MCS0_9;
11591 else
11592 mcs_config = HE_80_MCS0_11;
11593 ret = sta_set_he_mcs(dut, intf, mcs_config);
11594 if (ret) {
11595 sigma_dut_print(dut, DUT_MSG_ERROR,
11596 "nss_mcs_opt: mcs setting failed, mcs:%d, mcs_config %d, ret:%d",
11597 mcs, mcs_config, ret);
11598 goto failed;
11599 }
11600 }
11601#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011602 } else {
11603 sigma_dut_print(dut, DUT_MSG_ERROR,
11604 "HE MCS %d not supported", mcs);
11605 goto failed;
11606 }
11607 snprintf(buf, sizeof(buf), "iwpriv %s set_11ax_rate 0x%03x",
11608 intf, ratecode);
11609 if (system(buf) != 0) {
11610 sigma_dut_print(dut, DUT_MSG_ERROR,
11611 "iwpriv setting of 11ax rates failed");
11612 goto failed;
11613 }
11614 free(token);
11615 }
11616
11617 val = get_param(cmd, "GI");
11618 if (val) {
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011619 int fix_rate_sgi;
11620
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011621 if (strcmp(val, "0.8") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070011622 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 9", intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011623 fix_rate_sgi = 1;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011624 } else if (strcmp(val, "1.6") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070011625 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 10",
11626 intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011627 fix_rate_sgi = 2;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011628 } else if (strcmp(val, "3.2") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070011629 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 11",
11630 intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011631 fix_rate_sgi = 3;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011632 } else {
11633 send_resp(dut, conn, SIGMA_ERROR,
11634 "errorCode,GI value not supported");
11635 return 0;
11636 }
11637 if (system(buf) != 0) {
11638 send_resp(dut, conn, SIGMA_ERROR,
11639 "errorCode,Failed to set shortgi");
11640 return 0;
11641 }
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011642 snprintf(buf, sizeof(buf), "iwpriv %s shortgi %d",
11643 intf, fix_rate_sgi);
11644 if (system(buf) != 0) {
11645 send_resp(dut, conn, SIGMA_ERROR,
11646 "errorCode,Failed to set fix rate shortgi");
11647 return STATUS_SENT;
11648 }
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011649 }
11650
Subhani Shaik8e7a3052018-04-24 14:03:00 -070011651 val = get_param(cmd, "LTF");
11652 if (val) {
11653#ifdef NL80211_SUPPORT
11654 if (strcmp(val, "3.2") == 0) {
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -080011655 wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_1X);
Subhani Shaik8e7a3052018-04-24 14:03:00 -070011656 } if (strcmp(val, "6.4") == 0) {
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -080011657 wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_2X);
Subhani Shaik8e7a3052018-04-24 14:03:00 -070011658 } else if (strcmp(val, "12.8") == 0) {
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -080011659 wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_4X);
Subhani Shaik8e7a3052018-04-24 14:03:00 -070011660 } else {
11661 send_resp(dut, conn, SIGMA_ERROR,
11662 "errorCode, LTF value not supported");
11663 return 0;
11664 }
11665#else /* NL80211_SUPPORT */
11666 sigma_dut_print(dut, DUT_MSG_ERROR,
11667 "LTF cannot be set without NL80211_SUPPORT defined");
11668 return -2;
11669#endif /* NL80211_SUPPORT */
11670 }
11671
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -070011672 val = get_param(cmd, "TxSUPPDU");
11673 if (val) {
11674 int set_val = 1;
11675
11676 if (strcasecmp(val, "Enable") == 0)
11677 set_val = 1;
11678 else if (strcasecmp(val, "Disable") == 0)
11679 set_val = 0;
11680
11681 if (sta_set_tx_su_ppdu_cfg(dut, intf, set_val)) {
11682 send_resp(dut, conn, SIGMA_ERROR,
11683 "ErrorCode,Failed to set Tx SU PPDU config");
11684 return 0;
11685 }
11686 }
11687
Arif Hussain480d5f42019-03-12 14:40:42 -070011688 val = get_param(cmd, "TWT_Setup");
11689 if (val) {
11690 if (strcasecmp(val, "Request") == 0) {
11691 if (sta_twt_request(dut, conn, cmd)) {
11692 send_resp(dut, conn, SIGMA_ERROR,
11693 "ErrorCode,sta_twt_request failed");
11694 return STATUS_SENT;
11695 }
11696 } else if (strcasecmp(val, "Teardown") == 0) {
11697 if (sta_twt_teardown(dut, conn, cmd)) {
11698 send_resp(dut, conn, SIGMA_ERROR,
11699 "ErrorCode,sta_twt_teardown failed");
11700 return STATUS_SENT;
11701 }
11702 }
11703 }
11704
Kiran Kumar Lokere50eb2cd2018-12-18 18:31:28 -080011705 val = get_param(cmd, "transmitOMI");
11706 if (val && sta_transmit_omi(dut, conn, cmd)) {
11707 send_resp(dut, conn, SIGMA_ERROR,
11708 "ErrorCode,sta_transmit_omi failed");
11709 return STATUS_SENT;
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -070011710 }
11711
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080011712 val = get_param(cmd, "Powersave");
11713 if (val) {
11714 char buf[60];
11715
11716 if (strcasecmp(val, "off") == 0) {
11717 snprintf(buf, sizeof(buf),
11718 "iwpriv %s setPower 2", intf);
11719 if (system(buf) != 0) {
11720 sigma_dut_print(dut, DUT_MSG_ERROR,
11721 "iwpriv setPower 2 failed");
11722 return 0;
11723 }
11724 } else if (strcasecmp(val, "on") == 0) {
11725 snprintf(buf, sizeof(buf),
11726 "iwpriv %s setPower 1", intf);
11727 if (system(buf) != 0) {
11728 sigma_dut_print(dut, DUT_MSG_ERROR,
11729 "iwpriv setPower 1 failed");
11730 return 0;
11731 }
11732 } else {
11733 sigma_dut_print(dut, DUT_MSG_ERROR,
11734 "Unsupported Powersave value '%s'",
11735 val);
11736 return -1;
11737 }
11738 }
11739
Kiran Kumar Lokere2c4b7ce2019-01-30 12:02:28 -080011740 val = get_param(cmd, "MU_EDCA");
11741 if (val) {
11742 if (strcasecmp(val, "Override") == 0) {
11743 if (sta_set_mu_edca_override(dut, intf, 1)) {
11744 send_resp(dut, conn, SIGMA_ERROR,
11745 "errorCode,MU EDCA override set failed");
11746 return STATUS_SENT;
11747 }
11748 } else if (strcasecmp(val, "Disable") == 0) {
11749 if (sta_set_mu_edca_override(dut, intf, 0)) {
11750 send_resp(dut, conn, SIGMA_ERROR,
11751 "errorCode,MU EDCA override disable failed");
11752 return STATUS_SENT;
11753 }
11754 }
11755 }
11756
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011757 return 1;
11758
11759failed:
11760 free(token);
11761 return -2;
11762}
11763
11764
11765static int cmd_sta_set_rfeature_he(const char *intf, struct sigma_dut *dut,
11766 struct sigma_conn *conn,
11767 struct sigma_cmd *cmd)
11768{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011769 switch (get_driver_type(dut)) {
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011770 case DRIVER_WCN:
11771 return wcn_sta_set_rfeature_he(intf, dut, conn, cmd);
11772 default:
11773 send_resp(dut, conn, SIGMA_ERROR,
11774 "errorCode,Unsupported sta_set_rfeature(HE) with the current driver");
11775 return 0;
11776 }
11777}
11778
11779
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080011780static int cmd_sta_set_power_save_he(const char *intf, struct sigma_dut *dut,
11781 struct sigma_conn *conn,
11782 struct sigma_cmd *cmd)
11783{
11784 const char *val;
11785
11786 val = get_param(cmd, "powersave");
11787 if (val) {
11788 char buf[60];
11789
11790 if (strcasecmp(val, "off") == 0) {
11791 snprintf(buf, sizeof(buf), "iwpriv %s setPower 2",
11792 intf);
11793 if (system(buf) != 0) {
11794 sigma_dut_print(dut, DUT_MSG_ERROR,
11795 "iwpriv setPower 2 failed");
11796 return 0;
11797 }
11798 } else if (strcasecmp(val, "on") == 0) {
11799 snprintf(buf, sizeof(buf), "iwpriv %s setPower 1",
11800 intf);
11801 if (system(buf) != 0) {
11802 sigma_dut_print(dut, DUT_MSG_ERROR,
11803 "iwpriv setPower 1 failed");
11804 return 0;
11805 }
11806 } else {
11807 sigma_dut_print(dut, DUT_MSG_ERROR,
11808 "Unsupported power save config");
11809 return -1;
11810 }
11811 return 1;
11812 }
11813
11814 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported command");
11815
11816 return 0;
11817}
11818
11819
Ashwini Patil5acd7382017-04-13 15:55:04 +053011820static int btm_query_candidate_list(struct sigma_dut *dut,
11821 struct sigma_conn *conn,
11822 struct sigma_cmd *cmd)
11823{
11824 const char *bssid, *info, *op_class, *ch, *phy_type, *pref;
11825 int len, ret;
11826 char buf[10];
11827
11828 /*
11829 * Neighbor Report elements format:
11830 * neighbor=<BSSID>,<BSSID Information>,<Operating Class>,
11831 * <Channel Number>,<PHY Type>[,<hexdump of Optional Subelements>]
11832 * eg: neighbor=aa:bb:cc:dd:ee:ff,17,81,6,1,030101
11833 */
11834
11835 bssid = get_param(cmd, "Nebor_BSSID");
11836 if (!bssid) {
11837 send_resp(dut, conn, SIGMA_INVALID,
11838 "errorCode,Nebor_BSSID is missing");
11839 return 0;
11840 }
11841
11842 info = get_param(cmd, "Nebor_Bssid_Info");
11843 if (!info) {
11844 sigma_dut_print(dut, DUT_MSG_INFO,
11845 "Using default value for Nebor_Bssid_Info: %s",
11846 DEFAULT_NEIGHBOR_BSSID_INFO);
11847 info = DEFAULT_NEIGHBOR_BSSID_INFO;
11848 }
11849
11850 op_class = get_param(cmd, "Nebor_Op_Class");
11851 if (!op_class) {
11852 send_resp(dut, conn, SIGMA_INVALID,
11853 "errorCode,Nebor_Op_Class is missing");
11854 return 0;
11855 }
11856
11857 ch = get_param(cmd, "Nebor_Op_Ch");
11858 if (!ch) {
11859 send_resp(dut, conn, SIGMA_INVALID,
11860 "errorCode,Nebor_Op_Ch is missing");
11861 return 0;
11862 }
11863
11864 phy_type = get_param(cmd, "Nebor_Phy_Type");
11865 if (!phy_type) {
11866 sigma_dut_print(dut, DUT_MSG_INFO,
11867 "Using default value for Nebor_Phy_Type: %s",
11868 DEFAULT_NEIGHBOR_PHY_TYPE);
11869 phy_type = DEFAULT_NEIGHBOR_PHY_TYPE;
11870 }
11871
11872 /* Parse optional subelements */
11873 buf[0] = '\0';
11874 pref = get_param(cmd, "Nebor_Pref");
11875 if (pref) {
11876 /* hexdump for preferrence subelement */
11877 ret = snprintf(buf, sizeof(buf), ",0301%02x", atoi(pref));
11878 if (ret < 0 || ret >= (int) sizeof(buf)) {
11879 sigma_dut_print(dut, DUT_MSG_ERROR,
11880 "snprintf failed for optional subelement ret: %d",
11881 ret);
11882 send_resp(dut, conn, SIGMA_ERROR,
11883 "errorCode,snprintf failed for subelement");
11884 return 0;
11885 }
11886 }
11887
11888 if (!dut->btm_query_cand_list) {
11889 dut->btm_query_cand_list = calloc(1, NEIGHBOR_REPORT_SIZE);
11890 if (!dut->btm_query_cand_list) {
11891 send_resp(dut, conn, SIGMA_ERROR,
11892 "errorCode,Failed to allocate memory for btm_query_cand_list");
11893 return 0;
11894 }
11895 }
11896
11897 len = strlen(dut->btm_query_cand_list);
11898 ret = snprintf(dut->btm_query_cand_list + len,
11899 NEIGHBOR_REPORT_SIZE - len, " neighbor=%s,%s,%s,%s,%s%s",
11900 bssid, info, op_class, ch, phy_type, buf);
11901 if (ret < 0 || ret >= NEIGHBOR_REPORT_SIZE - len) {
11902 sigma_dut_print(dut, DUT_MSG_ERROR,
11903 "snprintf failed for neighbor report list ret: %d",
11904 ret);
11905 send_resp(dut, conn, SIGMA_ERROR,
11906 "errorCode,snprintf failed for neighbor report");
11907 free(dut->btm_query_cand_list);
11908 dut->btm_query_cand_list = NULL;
11909 return 0;
11910 }
11911
11912 return 1;
11913}
11914
11915
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020011916int sta_extract_60g_ese(struct sigma_dut *dut, struct sigma_cmd *cmd,
11917 struct sigma_ese_alloc *allocs, int *allocs_size)
11918{
11919 int max_count = *allocs_size;
11920 int count = 0, i;
11921 const char *val;
11922
11923 do {
11924 val = get_param_indexed(cmd, "AllocID", count);
11925 if (val)
11926 count++;
11927 } while (val);
11928
11929 if (count == 0 || count > max_count) {
11930 sigma_dut_print(dut, DUT_MSG_ERROR,
11931 "Invalid number of allocations(%d)", count);
11932 return -1;
11933 }
11934
11935 for (i = 0; i < count; i++) {
11936 val = get_param_indexed(cmd, "PercentBI", i);
11937 if (!val) {
11938 sigma_dut_print(dut, DUT_MSG_ERROR,
11939 "Missing PercentBI parameter at index %d",
11940 i);
11941 return -1;
11942 }
11943 allocs[i].percent_bi = atoi(val);
11944
11945 val = get_param_indexed(cmd, "SrcAID", i);
11946 if (val)
11947 allocs[i].src_aid = strtol(val, NULL, 0);
11948 else
11949 allocs[i].src_aid = ESE_BCAST_AID;
11950
11951 val = get_param_indexed(cmd, "DestAID", i);
11952 if (val)
11953 allocs[i].dst_aid = strtol(val, NULL, 0);
11954 else
11955 allocs[i].dst_aid = ESE_BCAST_AID;
11956
11957 allocs[i].type = ESE_CBAP;
11958 sigma_dut_print(dut, DUT_MSG_INFO,
11959 "Alloc %d PercentBI %d SrcAID %d DstAID %d",
11960 i, allocs[i].percent_bi, allocs[i].src_aid,
11961 allocs[i].dst_aid);
11962 }
11963
11964 *allocs_size = count;
11965 return 0;
11966}
11967
11968
11969static int sta_set_60g_ese(struct sigma_dut *dut, int count,
11970 struct sigma_ese_alloc *allocs)
11971{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011972 switch (get_driver_type(dut)) {
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020011973#ifdef __linux__
11974 case DRIVER_WIL6210:
11975 if (wil6210_set_ese(dut, count, allocs))
11976 return -1;
11977 return 1;
11978#endif /* __linux__ */
11979 default:
11980 sigma_dut_print(dut, DUT_MSG_ERROR,
11981 "Unsupported sta_set_60g_ese with the current driver");
11982 return -1;
11983 }
11984}
11985
11986
11987static int cmd_sta_set_rfeature_60g(const char *intf, struct sigma_dut *dut,
11988 struct sigma_conn *conn,
11989 struct sigma_cmd *cmd)
11990{
11991 const char *val;
11992
11993 val = get_param(cmd, "ExtSchIE");
11994 if (val && !strcasecmp(val, "Enable")) {
11995 struct sigma_ese_alloc allocs[MAX_ESE_ALLOCS];
11996 int count = MAX_ESE_ALLOCS;
11997
11998 if (sta_extract_60g_ese(dut, cmd, allocs, &count))
11999 return -1;
12000 return sta_set_60g_ese(dut, count, allocs);
12001 }
12002
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +020012003 val = get_param(cmd, "MCS_FixedRate");
12004 if (val) {
12005 int sta_mcs = atoi(val);
12006
12007 sigma_dut_print(dut, DUT_MSG_INFO, "Force STA MCS to %d",
12008 sta_mcs);
12009 wil6210_set_force_mcs(dut, 1, sta_mcs);
12010
Jouni Malinen0e29cf22019-02-19 01:13:21 +020012011 return SUCCESS_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +020012012 }
12013
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020012014 send_resp(dut, conn, SIGMA_ERROR,
12015 "errorCode,Invalid sta_set_rfeature(60G)");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020012016 return STATUS_SENT;
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020012017}
12018
12019
Jouni Malinen6250cb02020-04-15 13:54:45 +030012020static enum sigma_cmd_result
12021cmd_sta_set_rfeature_wpa3(const char *intf, struct sigma_dut *dut,
12022 struct sigma_conn *conn,
12023 struct sigma_cmd *cmd)
12024{
12025 const char *val;
12026
Veerendranath Jakkam30bf9072020-04-16 14:37:57 +053012027 val = get_param(cmd, "ReassocReq_RSNXE_Used");
Jouni Malinen6250cb02020-04-15 13:54:45 +030012028 if (val && atoi(val) == 1) {
12029 if (wpa_command(intf, "SET ft_rsnxe_used 1") < 0) {
12030 send_resp(dut, conn, SIGMA_ERROR,
12031 "errorCode,Failed to set ft_rsnxe_used");
12032 return STATUS_SENT_ERROR;
12033 }
12034 return SUCCESS_SEND_STATUS;
12035 }
12036 send_resp(dut, conn, SIGMA_ERROR,
12037 "errorCode,Unsupported WPA3 rfeature");
12038 return STATUS_SENT_ERROR;
12039}
12040
12041
Jouni Malinenf7222712019-06-13 01:50:21 +030012042static enum sigma_cmd_result cmd_sta_set_rfeature(struct sigma_dut *dut,
12043 struct sigma_conn *conn,
12044 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012045{
12046 const char *intf = get_param(cmd, "Interface");
12047 const char *prog = get_param(cmd, "Prog");
Ashwini Patil68d02cd2017-01-10 15:39:16 +053012048 const char *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012049
12050 if (intf == NULL || prog == NULL)
12051 return -1;
12052
Ashwini Patil5acd7382017-04-13 15:55:04 +053012053 /* BSS Transition candidate list for BTM query */
12054 val = get_param(cmd, "Nebor_BSSID");
12055 if (val && btm_query_candidate_list(dut, conn, cmd) == 0)
12056 return 0;
12057
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012058 if (strcasecmp(prog, "TDLS") == 0)
12059 return cmd_sta_set_rfeature_tdls(intf, dut, conn, cmd);
12060
12061 if (strcasecmp(prog, "VHT") == 0)
12062 return cmd_sta_set_rfeature_vht(intf, dut, conn, cmd);
12063
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080012064 if (strcasecmp(prog, "HE") == 0)
12065 return cmd_sta_set_rfeature_he(intf, dut, conn, cmd);
12066
Ashwini Patil68d02cd2017-01-10 15:39:16 +053012067 if (strcasecmp(prog, "MBO") == 0) {
12068 val = get_param(cmd, "Cellular_Data_Cap");
12069 if (val &&
12070 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
12071 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +053012072
12073 val = get_param(cmd, "Ch_Pref");
12074 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
12075 return 0;
12076
Ashwini Patil68d02cd2017-01-10 15:39:16 +053012077 return 1;
12078 }
12079
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020012080 if (strcasecmp(prog, "60GHz") == 0)
12081 return cmd_sta_set_rfeature_60g(intf, dut, conn, cmd);
12082
Jouni Malinen6250cb02020-04-15 13:54:45 +030012083 if (strcasecmp(prog, "WPA3") == 0)
12084 return cmd_sta_set_rfeature_wpa3(intf, dut, conn, cmd);
12085
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012086 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported Prog");
12087 return 0;
12088}
12089
12090
Jouni Malinenf7222712019-06-13 01:50:21 +030012091static enum sigma_cmd_result cmd_sta_set_radio(struct sigma_dut *dut,
12092 struct sigma_conn *conn,
12093 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012094{
12095 const char *intf = get_param(cmd, "Interface");
12096 const char *mode = get_param(cmd, "Mode");
12097 int res;
12098
12099 if (intf == NULL || mode == NULL)
12100 return -1;
12101
12102 if (strcasecmp(mode, "On") == 0)
12103 res = wpa_command(intf, "SET radio_disabled 0");
12104 else if (strcasecmp(mode, "Off") == 0)
12105 res = wpa_command(intf, "SET radio_disabled 1");
12106 else
12107 return -1;
12108
12109 if (res) {
12110 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
12111 "radio mode");
12112 return 0;
12113 }
12114
12115 return 1;
12116}
12117
12118
Jouni Malinenf7222712019-06-13 01:50:21 +030012119static enum sigma_cmd_result cmd_sta_set_pwrsave(struct sigma_dut *dut,
12120 struct sigma_conn *conn,
12121 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012122{
12123 const char *intf = get_param(cmd, "Interface");
12124 const char *mode = get_param(cmd, "Mode");
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020012125 const char *prog = get_param(cmd, "program");
12126 const char *powersave = get_param(cmd, "powersave");
12127 int res = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012128
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020012129 if (intf == NULL)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012130 return -1;
12131
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020012132 if (prog && strcasecmp(prog, "60GHz") == 0) {
12133 /*
12134 * The CAPI mode parameter does not exist in 60G
12135 * unscheduled PS.
12136 */
Hu Wang5dc3ff12019-06-14 15:14:26 +080012137 if (powersave && strcasecmp(powersave, "unscheduled") == 0)
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020012138 res = set_ps(intf, dut, 1);
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012139 } else if (prog && get_driver_type(dut) == DRIVER_WCN &&
Alexei Avshalom Lazar2f6fdb42019-02-04 14:16:08 +020012140 strcasecmp(prog, "HE") == 0) {
12141 return cmd_sta_set_power_save_he(intf, dut, conn, cmd);
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020012142 } else {
12143 if (mode == NULL)
12144 return -1;
12145
12146 if (strcasecmp(mode, "On") == 0)
12147 res = set_ps(intf, dut, 1);
12148 else if (strcasecmp(mode, "Off") == 0)
12149 res = set_ps(intf, dut, 0);
12150 else
12151 return -1;
12152 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012153
12154 if (res) {
12155 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
12156 "power save mode");
12157 return 0;
12158 }
12159
12160 return 1;
12161}
12162
12163
Jouni Malinenf7222712019-06-13 01:50:21 +030012164static enum sigma_cmd_result cmd_sta_bssid_pool(struct sigma_dut *dut,
12165 struct sigma_conn *conn,
12166 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012167{
12168 const char *intf = get_param(cmd, "Interface");
12169 const char *val, *bssid;
12170 int res;
12171 char *buf;
12172 size_t buf_len;
12173
12174 val = get_param(cmd, "BSSID_FILTER");
12175 if (val == NULL)
12176 return -1;
12177
12178 bssid = get_param(cmd, "BSSID_List");
12179 if (atoi(val) == 0 || bssid == NULL) {
12180 /* Disable BSSID filter */
12181 if (wpa_command(intf, "SET bssid_filter ")) {
12182 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed "
12183 "to disable BSSID filter");
12184 return 0;
12185 }
12186
12187 return 1;
12188 }
12189
12190 buf_len = 100 + strlen(bssid);
12191 buf = malloc(buf_len);
12192 if (buf == NULL)
12193 return -1;
12194
12195 snprintf(buf, buf_len, "SET bssid_filter %s", bssid);
12196 res = wpa_command(intf, buf);
12197 free(buf);
12198 if (res) {
12199 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to enable "
12200 "BSSID filter");
12201 return 0;
12202 }
12203
12204 return 1;
12205}
12206
12207
Jouni Malinenf7222712019-06-13 01:50:21 +030012208static enum sigma_cmd_result cmd_sta_reset_parm(struct sigma_dut *dut,
12209 struct sigma_conn *conn,
12210 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012211{
12212 const char *intf = get_param(cmd, "Interface");
12213 const char *val;
12214
12215 /* TODO: ARP */
12216
12217 val = get_param(cmd, "HS2_CACHE_PROFILE");
12218 if (val && strcasecmp(val, "All") == 0)
12219 hs2_clear_credentials(intf);
12220
12221 return 1;
12222}
12223
12224
Jouni Malinenf7222712019-06-13 01:50:21 +030012225static enum sigma_cmd_result cmd_sta_get_key(struct sigma_dut *dut,
12226 struct sigma_conn *conn,
12227 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012228{
12229 const char *intf = get_param(cmd, "Interface");
12230 const char *key_type = get_param(cmd, "KeyType");
12231 char buf[100], resp[200];
12232
12233 if (key_type == NULL)
12234 return -1;
12235
12236 if (strcasecmp(key_type, "GTK") == 0) {
12237 if (wpa_command_resp(intf, "GET gtk", buf, sizeof(buf)) < 0 ||
12238 strncmp(buf, "FAIL", 4) == 0) {
12239 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12240 "not fetch current GTK");
12241 return 0;
12242 }
12243 snprintf(resp, sizeof(resp), "KeyValue,%s", buf);
12244 send_resp(dut, conn, SIGMA_COMPLETE, resp);
12245 return 0;
12246 } else {
12247 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
12248 "KeyType");
12249 return 0;
12250 }
12251
12252 return 1;
12253}
12254
12255
12256static int hs2_set_policy(struct sigma_dut *dut)
12257{
12258#ifdef ANDROID
12259 system("ip rule del prio 23000");
12260 if (system("ip rule add from all lookup main prio 23000") != 0) {
12261 sigma_dut_print(dut, DUT_MSG_ERROR,
12262 "Failed to run:ip rule add from all lookup main prio");
12263 return -1;
12264 }
12265 if (system("ip route flush cache") != 0) {
12266 sigma_dut_print(dut, DUT_MSG_ERROR,
12267 "Failed to run ip route flush cache");
12268 return -1;
12269 }
12270 return 1;
12271#else /* ANDROID */
12272 return 0;
12273#endif /* ANDROID */
12274}
12275
12276
Jouni Malinenf7222712019-06-13 01:50:21 +030012277static enum sigma_cmd_result cmd_sta_hs2_associate(struct sigma_dut *dut,
12278 struct sigma_conn *conn,
12279 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012280{
12281 const char *intf = get_param(cmd, "Interface");
12282 const char *val = get_param(cmd, "Ignore_blacklist");
Jouni Malinen439352d2018-09-13 03:42:23 +030012283 const char *band = get_param(cmd, "Band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012284 struct wpa_ctrl *ctrl;
Jouni Malinen3aa72862019-05-29 23:14:51 +030012285 int res, r;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012286 char bssid[20], ssid[40], resp[100], buf[100], blacklisted[100];
12287 int tries = 0;
12288 int ignore_blacklist = 0;
12289 const char *events[] = {
12290 "CTRL-EVENT-CONNECTED",
12291 "INTERWORKING-BLACKLISTED",
12292 "INTERWORKING-NO-MATCH",
12293 NULL
12294 };
12295
12296 start_sta_mode(dut);
12297
Jouni Malinen439352d2018-09-13 03:42:23 +030012298 if (band) {
12299 if (strcmp(band, "2.4") == 0) {
12300 wpa_command(intf, "SET setband 2G");
12301 } else if (strcmp(band, "5") == 0) {
12302 wpa_command(intf, "SET setband 5G");
12303 } else {
12304 send_resp(dut, conn, SIGMA_ERROR,
12305 "errorCode,Unsupported band");
12306 return 0;
12307 }
12308 }
12309
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012310 blacklisted[0] = '\0';
12311 if (val && atoi(val))
12312 ignore_blacklist = 1;
12313
12314try_again:
12315 ctrl = open_wpa_mon(intf);
12316 if (ctrl == NULL) {
12317 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
12318 "wpa_supplicant monitor connection");
12319 return -2;
12320 }
12321
12322 tries++;
12323 if (wpa_command(intf, "INTERWORKING_SELECT auto")) {
12324 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start "
12325 "Interworking connection");
12326 wpa_ctrl_detach(ctrl);
12327 wpa_ctrl_close(ctrl);
12328 return 0;
12329 }
12330
12331 buf[0] = '\0';
12332 while (1) {
12333 char *pos;
12334 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
12335 pos = strstr(buf, "INTERWORKING-BLACKLISTED");
12336 if (!pos)
12337 break;
12338 pos += 25;
12339 sigma_dut_print(dut, DUT_MSG_DEBUG, "Found blacklisted AP: %s",
12340 pos);
12341 if (!blacklisted[0])
12342 memcpy(blacklisted, pos, strlen(pos) + 1);
12343 }
12344
12345 if (ignore_blacklist && blacklisted[0]) {
12346 char *end;
12347 end = strchr(blacklisted, ' ');
12348 if (end)
12349 *end = '\0';
12350 sigma_dut_print(dut, DUT_MSG_DEBUG, "Try to connect to a blacklisted network: %s",
12351 blacklisted);
Jouni Malinen3aa72862019-05-29 23:14:51 +030012352 r = snprintf(buf, sizeof(buf), "INTERWORKING_CONNECT %s",
12353 blacklisted);
12354 if (r < 0 || r >= sizeof(buf) || wpa_command(intf, buf)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012355 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start Interworking connection to blacklisted network");
12356 wpa_ctrl_detach(ctrl);
12357 wpa_ctrl_close(ctrl);
12358 return 0;
12359 }
12360 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
12361 buf, sizeof(buf));
12362 }
12363
12364 wpa_ctrl_detach(ctrl);
12365 wpa_ctrl_close(ctrl);
12366
12367 if (res < 0) {
12368 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
12369 "connect");
12370 return 0;
12371 }
12372
12373 if (strstr(buf, "INTERWORKING-NO-MATCH") ||
12374 strstr(buf, "INTERWORKING-BLACKLISTED")) {
12375 if (tries < 2) {
12376 sigma_dut_print(dut, DUT_MSG_INFO, "No match found - try again to verify no APs were missed in the scan");
12377 goto try_again;
12378 }
12379 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,No network with "
12380 "matching credentials found");
12381 return 0;
12382 }
12383
12384 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
12385 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
12386 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
12387 "get current BSSID/SSID");
12388 return 0;
12389 }
12390
12391 snprintf(resp, sizeof(resp), "SSID,%s,BSSID,%s", ssid, bssid);
12392 send_resp(dut, conn, SIGMA_COMPLETE, resp);
12393 hs2_set_policy(dut);
12394 return 0;
12395}
12396
12397
Jouni Malinenf7222712019-06-13 01:50:21 +030012398static enum sigma_cmd_result cmd_sta_hs2_venue_info(struct sigma_dut *dut,
12399 struct sigma_conn *conn,
12400 struct sigma_cmd *cmd)
Jouni Malinenb639f1c2018-09-13 02:39:46 +030012401{
12402 const char *intf = get_param(cmd, "Interface");
12403 const char *display = get_param(cmd, "Display");
12404 struct wpa_ctrl *ctrl;
12405 char buf[300], params[400], *pos;
12406 char bssid[20];
12407 int info_avail = 0;
12408 unsigned int old_timeout;
12409 int res;
12410
12411 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0) {
12412 send_resp(dut, conn, SIGMA_ERROR,
12413 "ErrorCode,Could not get current BSSID");
12414 return 0;
12415 }
12416 ctrl = open_wpa_mon(intf);
12417 if (!ctrl) {
12418 sigma_dut_print(dut, DUT_MSG_ERROR,
12419 "Failed to open wpa_supplicant monitor connection");
12420 return -2;
12421 }
12422
12423 snprintf(buf, sizeof(buf), "ANQP_GET %s 277", bssid);
12424 wpa_command(intf, buf);
12425
12426 res = get_wpa_cli_event(dut, ctrl, "GAS-QUERY-DONE", buf, sizeof(buf));
12427 if (res < 0) {
12428 send_resp(dut, conn, SIGMA_ERROR,
12429 "ErrorCode,Could not complete GAS query");
12430 goto fail;
12431 }
12432
12433 old_timeout = dut->default_timeout;
12434 dut->default_timeout = 2;
12435 res = get_wpa_cli_event(dut, ctrl, "RX-VENUE-URL", buf, sizeof(buf));
12436 dut->default_timeout = old_timeout;
12437 if (res < 0)
12438 goto done;
12439 pos = strchr(buf, ' ');
12440 if (!pos)
12441 goto done;
12442 pos++;
12443 pos = strchr(pos, ' ');
12444 if (!pos)
12445 goto done;
12446 pos++;
12447 info_avail = 1;
12448 snprintf(params, sizeof(params), "browser %s", pos);
12449
12450 if (display && strcasecmp(display, "Yes") == 0) {
12451 pid_t pid;
12452
12453 pid = fork();
12454 if (pid < 0) {
12455 perror("fork");
12456 return -1;
12457 }
12458
12459 if (pid == 0) {
12460 run_hs20_osu(dut, params);
12461 exit(0);
12462 }
12463 }
12464
12465done:
12466 snprintf(buf, sizeof(buf), "Info_available,%s",
12467 info_avail ? "Yes" : "No");
12468 send_resp(dut, conn, SIGMA_COMPLETE, buf);
12469fail:
12470 wpa_ctrl_detach(ctrl);
12471 wpa_ctrl_close(ctrl);
12472 return 0;
12473}
12474
12475
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012476static int sta_add_credential_uname_pwd(struct sigma_dut *dut,
12477 struct sigma_conn *conn,
12478 const char *ifname,
12479 struct sigma_cmd *cmd)
12480{
12481 const char *val;
12482 int id;
12483
12484 id = add_cred(ifname);
12485 if (id < 0)
12486 return -2;
12487 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
12488
12489 val = get_param(cmd, "prefer");
12490 if (val && atoi(val) > 0)
12491 set_cred(ifname, id, "priority", "1");
12492
12493 val = get_param(cmd, "REALM");
12494 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
12495 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12496 "realm");
12497 return 0;
12498 }
12499
12500 val = get_param(cmd, "HOME_FQDN");
12501 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
12502 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12503 "home_fqdn");
12504 return 0;
12505 }
12506
12507 val = get_param(cmd, "Username");
12508 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
12509 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12510 "username");
12511 return 0;
12512 }
12513
12514 val = get_param(cmd, "Password");
12515 if (val && set_cred_quoted(ifname, id, "password", val) < 0) {
12516 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12517 "password");
12518 return 0;
12519 }
12520
12521 val = get_param(cmd, "ROOT_CA");
12522 if (val) {
12523 char fname[200];
12524 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
12525#ifdef __linux__
12526 if (!file_exists(fname)) {
12527 char msg[300];
12528 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
12529 "file (%s) not found", fname);
12530 send_resp(dut, conn, SIGMA_ERROR, msg);
12531 return 0;
12532 }
12533#endif /* __linux__ */
12534 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
12535 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12536 "not set root CA");
12537 return 0;
12538 }
12539 }
12540
12541 return 1;
12542}
12543
12544
12545static int update_devdetail_imsi(struct sigma_dut *dut, const char *imsi)
12546{
12547 FILE *in, *out;
12548 char buf[500];
12549 int found = 0;
12550
12551 in = fopen("devdetail.xml", "r");
12552 if (in == NULL)
12553 return -1;
12554 out = fopen("devdetail.xml.tmp", "w");
12555 if (out == NULL) {
12556 fclose(in);
12557 return -1;
12558 }
12559
12560 while (fgets(buf, sizeof(buf), in)) {
12561 char *pos = strstr(buf, "<IMSI>");
12562 if (pos) {
12563 sigma_dut_print(dut, DUT_MSG_INFO, "Updated DevDetail IMSI to %s",
12564 imsi);
12565 pos += 6;
12566 *pos = '\0';
12567 fprintf(out, "%s%s</IMSI>\n", buf, imsi);
12568 found++;
12569 } else {
12570 fprintf(out, "%s", buf);
12571 }
12572 }
12573
12574 fclose(out);
12575 fclose(in);
12576 if (found)
12577 rename("devdetail.xml.tmp", "devdetail.xml");
12578 else
12579 unlink("devdetail.xml.tmp");
12580
12581 return 0;
12582}
12583
12584
12585static int sta_add_credential_sim(struct sigma_dut *dut,
12586 struct sigma_conn *conn,
12587 const char *ifname, struct sigma_cmd *cmd)
12588{
12589 const char *val, *imsi = NULL;
12590 int id;
12591 char buf[200];
12592 int res;
12593 const char *pos;
12594 size_t mnc_len;
12595 char plmn_mcc[4];
12596 char plmn_mnc[4];
12597
12598 id = add_cred(ifname);
12599 if (id < 0)
12600 return -2;
12601 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
12602
12603 val = get_param(cmd, "prefer");
12604 if (val && atoi(val) > 0)
12605 set_cred(ifname, id, "priority", "1");
12606
12607 val = get_param(cmd, "PLMN_MCC");
12608 if (val == NULL) {
12609 send_resp(dut, conn, SIGMA_ERROR,
12610 "errorCode,Missing PLMN_MCC");
12611 return 0;
12612 }
12613 if (strlen(val) != 3) {
12614 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MCC");
12615 return 0;
12616 }
12617 snprintf(plmn_mcc, sizeof(plmn_mcc), "%s", val);
12618
12619 val = get_param(cmd, "PLMN_MNC");
12620 if (val == NULL) {
12621 send_resp(dut, conn, SIGMA_ERROR,
12622 "errorCode,Missing PLMN_MNC");
12623 return 0;
12624 }
12625 if (strlen(val) != 2 && strlen(val) != 3) {
12626 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MNC");
12627 return 0;
12628 }
12629 snprintf(plmn_mnc, sizeof(plmn_mnc), "%s", val);
12630
12631 val = get_param(cmd, "IMSI");
12632 if (val == NULL) {
12633 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing SIM "
12634 "IMSI");
12635 return 0;
12636 }
12637
12638 imsi = pos = val;
12639
12640 if (strncmp(plmn_mcc, pos, 3) != 0) {
12641 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MCC mismatch");
12642 return 0;
12643 }
12644 pos += 3;
12645
12646 mnc_len = strlen(plmn_mnc);
12647 if (mnc_len < 2) {
12648 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC not set");
12649 return 0;
12650 }
12651
12652 if (strncmp(plmn_mnc, pos, mnc_len) != 0) {
12653 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC mismatch");
12654 return 0;
12655 }
12656 pos += mnc_len;
12657
12658 res = snprintf(buf, sizeof(buf), "%s%s-%s",plmn_mcc, plmn_mnc, pos);
12659 if (res < 0 || res >= (int) sizeof(buf))
12660 return -1;
12661 if (set_cred_quoted(ifname, id, "imsi", buf) < 0) {
12662 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12663 "not set IMSI");
12664 return 0;
12665 }
12666
12667 val = get_param(cmd, "Password");
12668 if (val && set_cred_quoted(ifname, id, "milenage", val) < 0) {
12669 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12670 "not set password");
12671 return 0;
12672 }
12673
Jouni Malinenba630452018-06-22 11:49:59 +030012674 if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012675 /*
12676 * Set provisioning_sp for the test cases where SIM/USIM
12677 * provisioning is used.
12678 */
12679 if (val && set_cred_quoted(ifname, id, "provisioning_sp",
12680 "wi-fi.org") < 0) {
12681 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12682 "not set provisioning_sp");
12683 return 0;
12684 }
12685
12686 update_devdetail_imsi(dut, imsi);
12687 }
12688
12689 return 1;
12690}
12691
12692
12693static int sta_add_credential_cert(struct sigma_dut *dut,
12694 struct sigma_conn *conn,
12695 const char *ifname,
12696 struct sigma_cmd *cmd)
12697{
12698 const char *val;
12699 int id;
12700
12701 id = add_cred(ifname);
12702 if (id < 0)
12703 return -2;
12704 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
12705
12706 val = get_param(cmd, "prefer");
12707 if (val && atoi(val) > 0)
12708 set_cred(ifname, id, "priority", "1");
12709
12710 val = get_param(cmd, "REALM");
12711 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
12712 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12713 "realm");
12714 return 0;
12715 }
12716
12717 val = get_param(cmd, "HOME_FQDN");
12718 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
12719 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12720 "home_fqdn");
12721 return 0;
12722 }
12723
12724 val = get_param(cmd, "Username");
12725 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
12726 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12727 "username");
12728 return 0;
12729 }
12730
12731 val = get_param(cmd, "clientCertificate");
12732 if (val) {
12733 char fname[200];
12734 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
12735#ifdef __linux__
12736 if (!file_exists(fname)) {
12737 char msg[300];
12738 snprintf(msg, sizeof(msg),
12739 "ErrorCode,clientCertificate "
12740 "file (%s) not found", fname);
12741 send_resp(dut, conn, SIGMA_ERROR, msg);
12742 return 0;
12743 }
12744#endif /* __linux__ */
12745 if (set_cred_quoted(ifname, id, "client_cert", fname) < 0) {
12746 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12747 "not set client_cert");
12748 return 0;
12749 }
12750 if (set_cred_quoted(ifname, id, "private_key", fname) < 0) {
12751 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12752 "not set private_key");
12753 return 0;
12754 }
12755 }
12756
12757 val = get_param(cmd, "ROOT_CA");
12758 if (val) {
12759 char fname[200];
12760 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
12761#ifdef __linux__
12762 if (!file_exists(fname)) {
12763 char msg[300];
12764 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
12765 "file (%s) not found", fname);
12766 send_resp(dut, conn, SIGMA_ERROR, msg);
12767 return 0;
12768 }
12769#endif /* __linux__ */
12770 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
12771 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12772 "not set root CA");
12773 return 0;
12774 }
12775 }
12776
12777 return 1;
12778}
12779
12780
Jouni Malinenf7222712019-06-13 01:50:21 +030012781static enum sigma_cmd_result cmd_sta_add_credential(struct sigma_dut *dut,
12782 struct sigma_conn *conn,
12783 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012784{
12785 const char *intf = get_param(cmd, "Interface");
12786 const char *type;
12787
12788 start_sta_mode(dut);
12789
12790 type = get_param(cmd, "Type");
12791 if (!type)
12792 return -1;
12793
12794 if (strcasecmp(type, "uname_pwd") == 0)
12795 return sta_add_credential_uname_pwd(dut, conn, intf, cmd);
12796
12797 if (strcasecmp(type, "sim") == 0)
12798 return sta_add_credential_sim(dut, conn, intf, cmd);
12799
12800 if (strcasecmp(type, "cert") == 0)
12801 return sta_add_credential_cert(dut, conn, intf, cmd);
12802
12803 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported credential "
12804 "type");
12805 return 0;
12806}
12807
12808
Jouni Malinenf7222712019-06-13 01:50:21 +030012809static enum sigma_cmd_result cmd_sta_scan(struct sigma_dut *dut,
12810 struct sigma_conn *conn,
12811 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012812{
12813 const char *intf = get_param(cmd, "Interface");
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080012814 const char *val, *bssid, *ssid, *scan_freq, *short_ssid;
Arif Hussain66a4af02019-02-07 15:04:51 -080012815 char buf[4096];
vamsi krishna89ad8c62017-09-19 12:51:18 +053012816 char ssid_hex[65];
Kiran Kumar Lokere3399af22020-03-04 16:31:56 -080012817 int wildcard_ssid = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012818 int res;
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080012819 enum sigma_cmd_result status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012820
Jouni Malinen8c1abeb2019-11-06 18:48:34 +020012821 start_sta_mode(dut);
12822
Arif Hussain66a4af02019-02-07 15:04:51 -080012823 val = get_param(cmd, "GetParameter");
12824 if (val && strcmp(val, "SSID_BSSID") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012825 if (get_wpa_ssid_bssid(dut, get_station_ifname(dut),
Arif Hussain66a4af02019-02-07 15:04:51 -080012826 buf, sizeof(buf)) < 0) {
12827 sigma_dut_print(dut, DUT_MSG_ERROR,
12828 "Could not get ssid bssid");
12829 return ERROR_SEND_STATUS;
12830 }
12831
12832 sigma_dut_print(dut, DUT_MSG_INFO, "%s", buf);
12833 send_resp(dut, conn, SIGMA_COMPLETE, buf);
12834 return STATUS_SENT;
12835 }
12836
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012837 val = get_param(cmd, "HESSID");
12838 if (val) {
12839 res = snprintf(buf, sizeof(buf), "SET hessid %s", val);
12840 if (res < 0 || res >= (int) sizeof(buf))
12841 return -1;
12842 wpa_command(intf, buf);
12843 }
12844
12845 val = get_param(cmd, "ACCS_NET_TYPE");
12846 if (val) {
12847 res = snprintf(buf, sizeof(buf), "SET access_network_type %s",
12848 val);
12849 if (res < 0 || res >= (int) sizeof(buf))
12850 return -1;
12851 wpa_command(intf, buf);
12852 }
12853
vamsi krishna89ad8c62017-09-19 12:51:18 +053012854 bssid = get_param(cmd, "Bssid");
12855 ssid = get_param(cmd, "Ssid");
12856
Kiran Kumar Lokere3399af22020-03-04 16:31:56 -080012857 if (ssid && strcasecmp(ssid, "ZeroLength") == 0 &&
12858 dut->device_type == STA_testbed) {
12859 ssid = NULL;
12860 wildcard_ssid = 1;
12861 }
12862
vamsi krishna89ad8c62017-09-19 12:51:18 +053012863 if (ssid) {
12864 if (2 * strlen(ssid) >= sizeof(ssid_hex)) {
12865 send_resp(dut, conn, SIGMA_ERROR,
12866 "ErrorCode,Too long SSID");
12867 return 0;
12868 }
12869 ascii2hexstr(ssid, ssid_hex);
12870 }
12871
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080012872 short_ssid = get_param(cmd, "ShortSSID");
12873 if (short_ssid) {
12874 uint32_t short_ssid_hex;
12875
12876 short_ssid_hex = strtoul(short_ssid, NULL, 16);
12877 short_ssid_hex = ((short_ssid_hex & 0xFF) << 24) |
12878 (((short_ssid_hex >> 8) & 0xFF) << 16) |
12879 (((short_ssid_hex >> 16) & 0xFF) << 8) |
12880 ((short_ssid_hex >> 24) & 0xFF);
12881
12882 res = snprintf(buf, sizeof(buf),
12883 "VENDOR_ELEM_ADD 14 ff053a%08x",
12884 short_ssid_hex);
12885 if (res < 0 || res >= (int) sizeof(buf) ||
12886 wpa_command(intf, buf)) {
12887 send_resp(dut, conn, SIGMA_ERROR,
12888 "errorCode,Failed to add short SSID");
12889 return STATUS_SENT_ERROR;
12890 }
12891 }
12892
Kiran Kumar Lokerec0deb482020-03-04 16:35:06 -080012893 scan_freq = get_param(cmd, "ChnlFreq");
12894
12895 res = snprintf(buf, sizeof(buf), "SCAN%s%s%s%s%s%s%s",
vamsi krishna89ad8c62017-09-19 12:51:18 +053012896 bssid ? " bssid=": "",
12897 bssid ? bssid : "",
12898 ssid ? " ssid " : "",
Kiran Kumar Lokere3399af22020-03-04 16:31:56 -080012899 ssid ? ssid_hex : "",
Kiran Kumar Lokerec0deb482020-03-04 16:35:06 -080012900 wildcard_ssid ? " wildcard_ssid=1" : "",
12901 scan_freq ? " freq=" : "",
12902 scan_freq ? scan_freq : "");
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080012903 if (res < 0 || res >= (int) sizeof(buf)) {
12904 send_resp(dut, conn, SIGMA_ERROR,
12905 "errorCode,Could not build scan command");
12906 status = STATUS_SENT_ERROR;
12907 goto remove_s_ssid;
12908 }
vamsi krishna89ad8c62017-09-19 12:51:18 +053012909
12910 if (wpa_command(intf, buf)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012911 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not start "
12912 "scan");
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080012913 status = STATUS_SENT_ERROR;
12914 } else {
12915 status = SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012916 }
12917
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080012918remove_s_ssid:
12919 if (short_ssid && wpa_command(intf, "VENDOR_ELEM_REMOVE 14 *"))
12920 sigma_dut_print(dut, DUT_MSG_ERROR,
12921 "Failed to delete vendor element");
12922
12923 return status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012924}
12925
12926
Jouni Malinenf7222712019-06-13 01:50:21 +030012927static enum sigma_cmd_result cmd_sta_scan_bss(struct sigma_dut *dut,
12928 struct sigma_conn *conn,
12929 struct sigma_cmd *cmd)
Jouni Malinen5e5d43d2018-01-10 17:29:33 +020012930{
12931 const char *intf = get_param(cmd, "Interface");
12932 const char *bssid;
12933 char buf[4096], *pos;
12934 int freq, chan;
12935 char *ssid;
12936 char resp[100];
12937 int res;
12938 struct wpa_ctrl *ctrl;
12939
12940 bssid = get_param(cmd, "BSSID");
12941 if (!bssid) {
12942 send_resp(dut, conn, SIGMA_INVALID,
12943 "errorCode,BSSID argument is missing");
12944 return 0;
12945 }
12946
12947 ctrl = open_wpa_mon(intf);
12948 if (!ctrl) {
12949 sigma_dut_print(dut, DUT_MSG_ERROR,
12950 "Failed to open wpa_supplicant monitor connection");
12951 return -1;
12952 }
12953
12954 if (wpa_command(intf, "SCAN TYPE=ONLY")) {
12955 send_resp(dut, conn, SIGMA_ERROR,
12956 "errorCode,Could not start scan");
12957 wpa_ctrl_detach(ctrl);
12958 wpa_ctrl_close(ctrl);
12959 return 0;
12960 }
12961
12962 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
12963 buf, sizeof(buf));
12964
12965 wpa_ctrl_detach(ctrl);
12966 wpa_ctrl_close(ctrl);
12967
12968 if (res < 0) {
12969 send_resp(dut, conn, SIGMA_ERROR,
12970 "errorCode,Scan did not complete");
12971 return 0;
12972 }
12973
12974 snprintf(buf, sizeof(buf), "BSS %s", bssid);
12975 if (wpa_command_resp(intf, buf, buf, sizeof(buf)) < 0 ||
12976 strncmp(buf, "id=", 3) != 0) {
12977 send_resp(dut, conn, SIGMA_ERROR,
12978 "errorCode,Specified BSSID not found");
12979 return 0;
12980 }
12981
12982 pos = strstr(buf, "\nfreq=");
12983 if (!pos) {
12984 send_resp(dut, conn, SIGMA_ERROR,
12985 "errorCode,Channel not found");
12986 return 0;
12987 }
12988 freq = atoi(pos + 6);
12989 chan = freq_to_channel(freq);
12990
12991 pos = strstr(buf, "\nssid=");
12992 if (!pos) {
12993 send_resp(dut, conn, SIGMA_ERROR,
12994 "errorCode,SSID not found");
12995 return 0;
12996 }
12997 ssid = pos + 6;
12998 pos = strchr(ssid, '\n');
12999 if (pos)
13000 *pos = '\0';
13001 snprintf(resp, sizeof(resp), "ssid,%s,bsschannel,%d", ssid, chan);
13002 send_resp(dut, conn, SIGMA_COMPLETE, resp);
13003 return 0;
13004}
13005
13006
Jouni Malinenf7222712019-06-13 01:50:21 +030013007static enum sigma_cmd_result cmd_sta_set_systime(struct sigma_dut *dut,
13008 struct sigma_conn *conn,
13009 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013010{
13011#ifdef __linux__
13012 struct timeval tv;
13013 struct tm tm;
13014 time_t t;
13015 const char *val;
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +053013016 int v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013017
Jouni Malinen016ae6c2019-11-04 17:00:01 +020013018 wpa_command(get_station_ifname(dut), "PMKSA_FLUSH");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013019
13020 memset(&tm, 0, sizeof(tm));
13021 val = get_param(cmd, "seconds");
13022 if (val)
13023 tm.tm_sec = atoi(val);
13024 val = get_param(cmd, "minutes");
13025 if (val)
13026 tm.tm_min = atoi(val);
13027 val = get_param(cmd, "hours");
13028 if (val)
13029 tm.tm_hour = atoi(val);
13030 val = get_param(cmd, "date");
13031 if (val)
13032 tm.tm_mday = atoi(val);
13033 val = get_param(cmd, "month");
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +053013034 if (val) {
13035 v = atoi(val);
13036 if (v < 1 || v > 12) {
13037 send_resp(dut, conn, SIGMA_INVALID,
13038 "errorCode,Invalid month");
13039 return 0;
13040 }
13041 tm.tm_mon = v - 1;
13042 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013043 val = get_param(cmd, "year");
13044 if (val) {
13045 int year = atoi(val);
13046#ifdef ANDROID
13047 if (year > 2035)
13048 year = 2035; /* years beyond 2035 not supported */
13049#endif /* ANDROID */
13050 tm.tm_year = year - 1900;
13051 }
13052 t = mktime(&tm);
13053 if (t == (time_t) -1) {
13054 send_resp(dut, conn, SIGMA_ERROR,
13055 "errorCode,Invalid date or time");
13056 return 0;
13057 }
13058
13059 memset(&tv, 0, sizeof(tv));
13060 tv.tv_sec = t;
13061
13062 if (settimeofday(&tv, NULL) < 0) {
13063 sigma_dut_print(dut, DUT_MSG_INFO, "settimeofday failed: %s",
13064 strerror(errno));
13065 send_resp(dut, conn, SIGMA_ERROR,
13066 "errorCode,Failed to set time");
13067 return 0;
13068 }
13069
13070 return 1;
13071#endif /* __linux__ */
13072
13073 return -1;
13074}
13075
13076
Jouni Malinenf7222712019-06-13 01:50:21 +030013077static enum sigma_cmd_result cmd_sta_osu(struct sigma_dut *dut,
13078 struct sigma_conn *conn,
13079 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013080{
13081 const char *intf = get_param(cmd, "Interface");
Jouni Malinen4c8681c2018-09-12 23:28:11 +030013082 const char *name, *osu_ssid, *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013083 int prod_ess_assoc = 1;
Jouni Malinen4c8681c2018-09-12 23:28:11 +030013084 char buf[300], bssid[100], ssid[100];
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013085 int res;
13086 struct wpa_ctrl *ctrl;
13087
13088 name = get_param(cmd, "osuFriendlyName");
Jouni Malinen4c8681c2018-09-12 23:28:11 +030013089 osu_ssid = get_param(cmd, "osu_ssid");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013090
13091 val = get_param(cmd, "ProdESSAssoc");
13092 if (val)
13093 prod_ess_assoc = atoi(val);
13094
13095 kill_dhcp_client(dut, intf);
13096 if (start_dhcp_client(dut, intf) < 0)
13097 return -2;
13098
13099 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger OSU");
13100 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
13101 res = snprintf(buf, sizeof(buf),
Jouni Malinen4c8681c2018-09-12 23:28:11 +030013102 "%s %s%s%s %s%s%s signup osu-ca.pem",
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013103 prod_ess_assoc ? "" : "-N",
13104 name ? "-O'" : "", name ? name : "",
Jouni Malinen4c8681c2018-09-12 23:28:11 +030013105 name ? "'" : "",
13106 osu_ssid ? "-o'" : "", osu_ssid ? osu_ssid : "",
13107 osu_ssid ? "'" : "");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013108
Kanchanapally, Vidyullatha12b66762015-12-31 16:46:42 +053013109 hs2_set_policy(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013110 if (run_hs20_osu(dut, buf) < 0) {
13111 FILE *f;
13112
13113 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to complete OSU");
13114
13115 f = fopen("hs20-osu-client.res", "r");
13116 if (f) {
13117 char resp[400], res[300], *pos;
13118 if (!fgets(res, sizeof(res), f))
13119 res[0] = '\0';
13120 pos = strchr(res, '\n');
13121 if (pos)
13122 *pos = '\0';
13123 fclose(f);
13124 sigma_dut_summary(dut, "hs20-osu-client provisioning failed: %s",
13125 res);
13126 snprintf(resp, sizeof(resp), "notify-send '%s'", res);
13127 if (system(resp) != 0) {
13128 }
13129 snprintf(resp, sizeof(resp),
13130 "SSID,,BSSID,,failureReason,%s", res);
13131 send_resp(dut, conn, SIGMA_COMPLETE, resp);
13132 return 0;
13133 }
13134
13135 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
13136 return 0;
13137 }
13138
13139 if (!prod_ess_assoc)
13140 goto report;
13141
13142 ctrl = open_wpa_mon(intf);
13143 if (ctrl == NULL) {
13144 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
13145 "wpa_supplicant monitor connection");
13146 return -1;
13147 }
13148
13149 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
13150 buf, sizeof(buf));
13151
13152 wpa_ctrl_detach(ctrl);
13153 wpa_ctrl_close(ctrl);
13154
13155 if (res < 0) {
13156 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to connect to "
13157 "network after OSU");
13158 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
13159 return 0;
13160 }
13161
13162report:
13163 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
13164 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
13165 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to get BSSID/SSID");
13166 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
13167 return 0;
13168 }
13169
13170 snprintf(buf, sizeof(buf), "SSID,%s,BSSID,%s", ssid, bssid);
13171 send_resp(dut, conn, SIGMA_COMPLETE, buf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013172 return 0;
13173}
13174
13175
Jouni Malinenf7222712019-06-13 01:50:21 +030013176static enum sigma_cmd_result cmd_sta_policy_update(struct sigma_dut *dut,
13177 struct sigma_conn *conn,
13178 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013179{
13180 const char *val;
13181 int timeout = 120;
13182
13183 val = get_param(cmd, "PolicyUpdate");
13184 if (val == NULL || atoi(val) == 0)
13185 return 1; /* No operation requested */
13186
13187 val = get_param(cmd, "Timeout");
13188 if (val)
13189 timeout = atoi(val);
13190
13191 if (timeout) {
13192 /* TODO: time out the command and return
13193 * PolicyUpdateStatus,TIMEOUT if needed. */
13194 }
13195
13196 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger policy update");
13197 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
13198 if (run_hs20_osu(dut, "pol_upd fqdn=wi-fi.org") < 0) {
13199 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,FAIL");
13200 return 0;
13201 }
13202
13203 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,SUCCESS");
13204 return 0;
13205}
13206
13207
Jouni Malinenf7222712019-06-13 01:50:21 +030013208static enum sigma_cmd_result cmd_sta_er_config(struct sigma_dut *dut,
13209 struct sigma_conn *conn,
13210 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013211{
13212 struct wpa_ctrl *ctrl;
13213 const char *intf = get_param(cmd, "Interface");
13214 const char *bssid = get_param(cmd, "Bssid");
13215 const char *ssid = get_param(cmd, "SSID");
13216 const char *security = get_param(cmd, "Security");
13217 const char *passphrase = get_param(cmd, "Passphrase");
13218 const char *pin = get_param(cmd, "PIN");
13219 char buf[1000];
13220 char ssid_hex[200], passphrase_hex[200];
13221 const char *keymgmt, *cipher;
13222
13223 if (intf == NULL)
Jouni Malinen016ae6c2019-11-04 17:00:01 +020013224 intf = get_main_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013225
13226 if (!bssid) {
13227 send_resp(dut, conn, SIGMA_ERROR,
13228 "ErrorCode,Missing Bssid argument");
13229 return 0;
13230 }
13231
13232 if (!ssid) {
13233 send_resp(dut, conn, SIGMA_ERROR,
13234 "ErrorCode,Missing SSID argument");
13235 return 0;
13236 }
13237
13238 if (!security) {
13239 send_resp(dut, conn, SIGMA_ERROR,
13240 "ErrorCode,Missing Security argument");
13241 return 0;
13242 }
13243
13244 if (!passphrase) {
13245 send_resp(dut, conn, SIGMA_ERROR,
13246 "ErrorCode,Missing Passphrase argument");
13247 return 0;
13248 }
13249
13250 if (!pin) {
13251 send_resp(dut, conn, SIGMA_ERROR,
13252 "ErrorCode,Missing PIN argument");
13253 return 0;
13254 }
13255
vamsi krishna8c9c1562017-05-12 15:51:46 +053013256 if (2 * strlen(ssid) >= sizeof(ssid_hex) ||
13257 2 * strlen(passphrase) >= sizeof(passphrase_hex)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013258 send_resp(dut, conn, SIGMA_ERROR,
13259 "ErrorCode,Too long SSID/passphrase");
13260 return 0;
13261 }
13262
13263 ctrl = open_wpa_mon(intf);
13264 if (ctrl == NULL) {
13265 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
13266 "wpa_supplicant monitor connection");
13267 return -2;
13268 }
13269
13270 if (strcasecmp(security, "wpa2-psk") == 0) {
13271 keymgmt = "WPA2PSK";
13272 cipher = "CCMP";
13273 } else {
13274 wpa_ctrl_detach(ctrl);
13275 wpa_ctrl_close(ctrl);
13276 send_resp(dut, conn, SIGMA_ERROR,
13277 "ErrorCode,Unsupported Security value");
13278 return 0;
13279 }
13280
13281 ascii2hexstr(ssid, ssid_hex);
13282 ascii2hexstr(passphrase, passphrase_hex);
13283 snprintf(buf, sizeof(buf), "WPS_REG %s %s %s %s %s %s",
13284 bssid, pin, ssid_hex, keymgmt, cipher, passphrase_hex);
13285
13286 if (wpa_command(intf, buf) < 0) {
13287 wpa_ctrl_detach(ctrl);
13288 wpa_ctrl_close(ctrl);
13289 send_resp(dut, conn, SIGMA_ERROR,
13290 "ErrorCode,Failed to start registrar");
13291 return 0;
13292 }
13293
13294 snprintf(dut->er_oper_bssid, sizeof(dut->er_oper_bssid), "%s", bssid);
13295 dut->er_oper_performed = 1;
13296
13297 return wps_connection_event(dut, conn, ctrl, intf, 0);
13298}
13299
13300
Jouni Malinenf7222712019-06-13 01:50:21 +030013301static enum sigma_cmd_result
13302cmd_sta_wps_connect_pw_token(struct sigma_dut *dut, struct sigma_conn *conn,
13303 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013304{
13305 struct wpa_ctrl *ctrl;
13306 const char *intf = get_param(cmd, "Interface");
13307 const char *bssid = get_param(cmd, "Bssid");
13308 char buf[100];
13309
13310 if (!bssid) {
13311 send_resp(dut, conn, SIGMA_ERROR,
13312 "ErrorCode,Missing Bssid argument");
13313 return 0;
13314 }
13315
13316 ctrl = open_wpa_mon(intf);
13317 if (ctrl == NULL) {
13318 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
13319 "wpa_supplicant monitor connection");
13320 return -2;
13321 }
13322
13323 snprintf(buf, sizeof(buf), "WPS_NFC %s", bssid);
13324
13325 if (wpa_command(intf, buf) < 0) {
13326 wpa_ctrl_detach(ctrl);
13327 wpa_ctrl_close(ctrl);
13328 send_resp(dut, conn, SIGMA_ERROR,
13329 "ErrorCode,Failed to start registrar");
13330 return 0;
13331 }
13332
13333 return wps_connection_event(dut, conn, ctrl, intf, 0);
13334}
13335
13336
Jouni Malinenf7222712019-06-13 01:50:21 +030013337static enum sigma_cmd_result cmd_start_wps_registration(struct sigma_dut *dut,
13338 struct sigma_conn *conn,
13339 struct sigma_cmd *cmd)
vamsi krishna9b144002017-09-20 13:28:13 +053013340{
13341 struct wpa_ctrl *ctrl;
13342 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020013343 const char *network_mode = get_param(cmd, "network_mode");
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020013344 const char *config_method = get_param(cmd, "WPSConfigMethod");
13345 const char *role;
vamsi krishna9b144002017-09-20 13:28:13 +053013346 int res;
13347 char buf[256];
13348 const char *events[] = {
13349 "CTRL-EVENT-CONNECTED",
13350 "WPS-OVERLAP-DETECTED",
13351 "WPS-TIMEOUT",
13352 "WPS-FAIL",
13353 NULL
13354 };
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020013355 int id = 0;
vamsi krishna9b144002017-09-20 13:28:13 +053013356
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020013357 /* 60G WPS tests do not pass Interface parameter */
13358 if (!intf)
Jouni Malinen016ae6c2019-11-04 17:00:01 +020013359 intf = get_main_ifname(dut);
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020013360
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020013361 if (dut->mode == SIGMA_MODE_AP)
13362 return ap_wps_registration(dut, conn, cmd);
13363
13364 if (config_method) {
13365 /* WFA_CS_WPS_PIN_KEYPAD mode is set when using the
13366 * sta_wps_enter_pin before calling start_wps_registration. */
13367 if (strcasecmp(config_method, "PBC") == 0)
13368 dut->wps_method = WFA_CS_WPS_PBC;
13369 }
13370 if (dut->wps_method == WFA_CS_WPS_NOT_READY) {
13371 send_resp(dut, conn, SIGMA_ERROR,
13372 "ErrorCode,WPS parameters not yet set");
13373 return STATUS_SENT;
13374 }
13375
13376 /* Make sure WPS is enabled (also for STA mode) */
13377 dut->wps_disable = 0;
13378
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020013379 if (dut->band == WPS_BAND_60G && network_mode &&
13380 strcasecmp(network_mode, "PBSS") == 0) {
13381 sigma_dut_print(dut, DUT_MSG_DEBUG,
13382 "Set PBSS network mode, network id %d", id);
Jouni Malinen016ae6c2019-11-04 17:00:01 +020013383 if (set_network(get_station_ifname(dut), id, "pbss", "1") < 0)
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020013384 return -2;
13385 }
13386
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020013387 if (dut->force_rsn_ie) {
13388 sigma_dut_print(dut, DUT_MSG_DEBUG, "Force RSN_IE: %d",
13389 dut->force_rsn_ie);
13390 if (sta_60g_force_rsn_ie(dut, dut->force_rsn_ie) < 0) {
13391 sigma_dut_print(dut, DUT_MSG_INFO,
13392 "Failed to force RSN_IE");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020013393 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020013394 }
13395 }
13396
vamsi krishna9b144002017-09-20 13:28:13 +053013397 ctrl = open_wpa_mon(intf);
13398 if (!ctrl) {
13399 sigma_dut_print(dut, DUT_MSG_ERROR,
13400 "Failed to open wpa_supplicant monitor connection");
13401 return -2;
13402 }
13403
13404 role = get_param(cmd, "WpsRole");
13405 if (!role) {
13406 send_resp(dut, conn, SIGMA_INVALID,
13407 "ErrorCode,WpsRole not provided");
13408 goto fail;
13409 }
13410
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020013411 if (strcasecmp(role, "Enrollee") != 0) {
13412 /* Registrar role for STA not supported */
13413 send_resp(dut, conn, SIGMA_ERROR,
13414 "ErrorCode,Unsupported WpsRole value");
13415 goto fail;
13416 }
13417
13418 if (is_60g_sigma_dut(dut)) {
13419 if (dut->wps_method == WFA_CS_WPS_PBC)
13420 snprintf(buf, sizeof(buf), "WPS_PBC");
13421 else /* WFA_CS_WPS_PIN_KEYPAD */
13422 snprintf(buf, sizeof(buf), "WPS_PIN any %s",
13423 dut->wps_pin);
13424 if (wpa_command(intf, buf) < 0) {
13425 send_resp(dut, conn, SIGMA_ERROR,
13426 "ErrorCode,Failed to start WPS");
vamsi krishna9b144002017-09-20 13:28:13 +053013427 goto fail;
13428 }
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020013429 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
13430 if (res < 0) {
13431 send_resp(dut, conn, SIGMA_ERROR,
13432 "ErrorCode,WPS connection did not complete");
13433 goto fail;
13434 }
13435 if (strstr(buf, "WPS-TIMEOUT")) {
13436 send_resp(dut, conn, SIGMA_COMPLETE, "WpsState,NoPeer");
13437 } else if (strstr(buf, "WPS-OVERLAP-DETECTED")) {
13438 send_resp(dut, conn, SIGMA_COMPLETE,
13439 "WpsState,OverlapSession");
13440 } else if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
13441 send_resp(dut, conn, SIGMA_COMPLETE,
13442 "WpsState,Successful");
13443 } else {
13444 send_resp(dut, conn, SIGMA_COMPLETE,
13445 "WpsState,Failure");
13446 }
13447 } else {
13448 if (dut->wps_method == WFA_CS_WPS_PBC) {
vamsi krishna9b144002017-09-20 13:28:13 +053013449 if (wpa_command(intf, "WPS_PBC") < 0) {
13450 send_resp(dut, conn, SIGMA_ERROR,
13451 "ErrorCode,Failed to enable PBC");
13452 goto fail;
13453 }
13454 } else {
13455 /* TODO: PIN method */
13456 send_resp(dut, conn, SIGMA_ERROR,
13457 "ErrorCode,Unsupported WpsConfigMethod value");
13458 goto fail;
13459 }
13460 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
13461 if (res < 0) {
13462 send_resp(dut, conn, SIGMA_ERROR,
13463 "ErrorCode,WPS connection did not complete");
13464 goto fail;
13465 }
13466 if (strstr(buf, "WPS-TIMEOUT")) {
13467 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,NoPeer");
13468 } else if (strstr(buf, "WPS-OVERLAP-DETECTED")) {
13469 send_resp(dut, conn, SIGMA_ERROR,
13470 "ErrorCode,OverlapSession");
13471 } else if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
13472 send_resp(dut, conn, SIGMA_COMPLETE, "Successful");
13473 } else {
13474 send_resp(dut, conn, SIGMA_ERROR,
13475 "ErrorCode,WPS operation failed");
13476 }
vamsi krishna9b144002017-09-20 13:28:13 +053013477 }
13478
13479fail:
13480 wpa_ctrl_detach(ctrl);
13481 wpa_ctrl_close(ctrl);
13482 return 0;
13483}
13484
13485
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013486static int req_intf(struct sigma_cmd *cmd)
13487{
13488 return get_param(cmd, "interface") == NULL ? -1 : 0;
13489}
13490
13491
13492void sta_register_cmds(void)
13493{
13494 sigma_dut_reg_cmd("sta_get_ip_config", req_intf,
13495 cmd_sta_get_ip_config);
13496 sigma_dut_reg_cmd("sta_set_ip_config", req_intf,
13497 cmd_sta_set_ip_config);
13498 sigma_dut_reg_cmd("sta_get_info", req_intf, cmd_sta_get_info);
13499 sigma_dut_reg_cmd("sta_get_mac_address", req_intf,
13500 cmd_sta_get_mac_address);
13501 sigma_dut_reg_cmd("sta_is_connected", req_intf, cmd_sta_is_connected);
13502 sigma_dut_reg_cmd("sta_verify_ip_connection", req_intf,
13503 cmd_sta_verify_ip_connection);
13504 sigma_dut_reg_cmd("sta_get_bssid", req_intf, cmd_sta_get_bssid);
13505 sigma_dut_reg_cmd("sta_set_encryption", req_intf,
13506 cmd_sta_set_encryption);
13507 sigma_dut_reg_cmd("sta_set_psk", req_intf, cmd_sta_set_psk);
13508 sigma_dut_reg_cmd("sta_set_eaptls", req_intf, cmd_sta_set_eaptls);
13509 sigma_dut_reg_cmd("sta_set_eapttls", req_intf, cmd_sta_set_eapttls);
13510 sigma_dut_reg_cmd("sta_set_eapsim", req_intf, cmd_sta_set_eapsim);
13511 sigma_dut_reg_cmd("sta_set_peap", req_intf, cmd_sta_set_peap);
13512 sigma_dut_reg_cmd("sta_set_eapfast", req_intf, cmd_sta_set_eapfast);
13513 sigma_dut_reg_cmd("sta_set_eapaka", req_intf, cmd_sta_set_eapaka);
13514 sigma_dut_reg_cmd("sta_set_eapakaprime", req_intf,
13515 cmd_sta_set_eapakaprime);
13516 sigma_dut_reg_cmd("sta_set_security", req_intf, cmd_sta_set_security);
13517 sigma_dut_reg_cmd("sta_set_uapsd", req_intf, cmd_sta_set_uapsd);
13518 /* TODO: sta_set_ibss */
13519 /* TODO: sta_set_mode */
13520 sigma_dut_reg_cmd("sta_set_wmm", req_intf, cmd_sta_set_wmm);
13521 sigma_dut_reg_cmd("sta_associate", req_intf, cmd_sta_associate);
13522 /* TODO: sta_up_load */
13523 sigma_dut_reg_cmd("sta_preset_testparameters", req_intf,
13524 cmd_sta_preset_testparameters);
13525 /* TODO: sta_set_system */
13526 sigma_dut_reg_cmd("sta_set_11n", req_intf, cmd_sta_set_11n);
13527 /* TODO: sta_set_rifs_test */
13528 sigma_dut_reg_cmd("sta_set_wireless", req_intf, cmd_sta_set_wireless);
13529 sigma_dut_reg_cmd("sta_send_addba", req_intf, cmd_sta_send_addba);
13530 /* TODO: sta_send_coexist_mgmt */
13531 sigma_dut_reg_cmd("sta_disconnect", req_intf, cmd_sta_disconnect);
13532 sigma_dut_reg_cmd("sta_reassoc", req_intf, cmd_sta_reassoc);
13533 sigma_dut_reg_cmd("sta_reassociate", req_intf, cmd_sta_reassoc);
13534 sigma_dut_reg_cmd("sta_reset_default", req_intf,
13535 cmd_sta_reset_default);
13536 sigma_dut_reg_cmd("sta_send_frame", req_intf, cmd_sta_send_frame);
13537 sigma_dut_reg_cmd("sta_set_macaddr", req_intf, cmd_sta_set_macaddr);
13538 sigma_dut_reg_cmd("sta_set_rfeature", req_intf, cmd_sta_set_rfeature);
13539 sigma_dut_reg_cmd("sta_set_radio", req_intf, cmd_sta_set_radio);
13540 sigma_dut_reg_cmd("sta_set_pwrsave", req_intf, cmd_sta_set_pwrsave);
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020013541 sigma_dut_reg_cmd("sta_set_power_save", req_intf, cmd_sta_set_pwrsave);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013542 sigma_dut_reg_cmd("sta_bssid_pool", req_intf, cmd_sta_bssid_pool);
13543 sigma_dut_reg_cmd("sta_reset_parm", req_intf, cmd_sta_reset_parm);
13544 sigma_dut_reg_cmd("sta_get_key", req_intf, cmd_sta_get_key);
13545 sigma_dut_reg_cmd("sta_hs2_associate", req_intf,
13546 cmd_sta_hs2_associate);
Jouni Malinenb639f1c2018-09-13 02:39:46 +030013547 sigma_dut_reg_cmd("sta_hs2_venue_info", req_intf,
13548 cmd_sta_hs2_venue_info);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013549 sigma_dut_reg_cmd("sta_add_credential", req_intf,
13550 cmd_sta_add_credential);
13551 sigma_dut_reg_cmd("sta_scan", req_intf, cmd_sta_scan);
Jouni Malinen5e5d43d2018-01-10 17:29:33 +020013552 sigma_dut_reg_cmd("sta_scan_bss", req_intf, cmd_sta_scan_bss);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013553 sigma_dut_reg_cmd("sta_set_systime", NULL, cmd_sta_set_systime);
13554 sigma_dut_reg_cmd("sta_osu", req_intf, cmd_sta_osu);
13555 sigma_dut_reg_cmd("sta_policy_update", req_intf, cmd_sta_policy_update);
13556 sigma_dut_reg_cmd("sta_er_config", NULL, cmd_sta_er_config);
13557 sigma_dut_reg_cmd("sta_wps_connect_pw_token", req_intf,
13558 cmd_sta_wps_connect_pw_token);
Jouni Malinen82905202018-04-29 17:20:10 +030013559 sigma_dut_reg_cmd("sta_exec_action", NULL, cmd_sta_exec_action);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013560 sigma_dut_reg_cmd("sta_get_events", req_intf, cmd_sta_get_events);
13561 sigma_dut_reg_cmd("sta_get_parameter", req_intf, cmd_sta_get_parameter);
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020013562 sigma_dut_reg_cmd("start_wps_registration", NULL,
vamsi krishna9b144002017-09-20 13:28:13 +053013563 cmd_start_wps_registration);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013564}