blob: 5e61be1b763d2685bab23cc2104b8be00bd9e905 [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)
6693 goto fail;
6694 pos++;
6695 pos = strchr(pos, ' ');
6696 if (!pos)
6697 goto fail;
6698 pos++;
6699 tmp = strchr(pos, ' ');
6700 if (!tmp)
6701 goto fail;
6702 *tmp = '\0';
6703 break;
6704 }
6705
6706 fail:
6707 pos = strchr(pos, '\n');
6708 if (pos)
6709 pos++;
6710 }
6711
6712 if (!pos) {
6713 send_resp(dut, conn, SIGMA_ERROR,
6714 "ErrorCode,PMK not available");
6715 return STATUS_SENT_ERROR;
6716 }
6717
6718 snprintf(resp, sizeof(resp), "PMK,%s", pos);
6719 send_resp(dut, conn, SIGMA_COMPLETE, resp);
6720 return STATUS_SENT;
6721}
6722
6723
Jouni Malinenf7222712019-06-13 01:50:21 +03006724static enum sigma_cmd_result cmd_sta_get_parameter(struct sigma_dut *dut,
6725 struct sigma_conn *conn,
6726 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006727{
6728 const char *program = get_param(cmd, "Program");
Jouni Malinenca0abd32020-02-09 20:18:10 +02006729 const char *parameter = get_param(cmd, "Parameter");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006730
Jouni Malinenca0abd32020-02-09 20:18:10 +02006731 if (!parameter)
6732 return INVALID_SEND_STATUS;
6733
6734 if (strcasecmp(parameter, "PMK") == 0)
6735 return sta_get_pmk(dut, conn, cmd);
6736
6737 if (!program)
6738 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006739
6740 if (strcasecmp(program, "P2PNFC") == 0)
6741 return p2p_cmd_sta_get_parameter(dut, conn, cmd);
6742
6743 if (strcasecmp(program, "60ghz") == 0)
6744 return sta_get_parameter_60g(dut, conn, cmd);
6745
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07006746 if (strcasecmp(program, "he") == 0)
6747 return sta_get_parameter_he(dut, conn, cmd);
6748
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006749#ifdef ANDROID_NAN
6750 if (strcasecmp(program, "NAN") == 0)
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07006751 return nan_cmd_sta_get_parameter(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006752#endif /* ANDROID_NAN */
6753
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07006754#ifdef MIRACAST
6755 if (strcasecmp(program, "WFD") == 0 ||
6756 strcasecmp(program, "DisplayR2") == 0)
6757 return miracast_cmd_sta_get_parameter(dut, conn, cmd);
6758#endif /* MIRACAST */
6759
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006760 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
6761 return 0;
6762}
6763
6764
6765static void sta_reset_default_ath(struct sigma_dut *dut, const char *intf,
6766 const char *type)
6767{
6768 char buf[100];
6769
6770 if (dut->program == PROGRAM_VHT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006771 run_iwpriv(dut, intf, "chwidth 2");
6772 run_iwpriv(dut, intf, "mode 11ACVHT80");
6773 run_iwpriv(dut, intf, "vhtmcs -1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006774 }
6775
6776 if (dut->program == PROGRAM_HT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006777 run_iwpriv(dut, intf, "chwidth 0");
6778 run_iwpriv(dut, intf, "mode 11naht40");
6779 run_iwpriv(dut, intf, "set11NRates 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006780 }
6781
6782 if (dut->program == PROGRAM_VHT || dut->program == PROGRAM_HT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006783 run_iwpriv(dut, intf, "powersave 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006784
6785 /* Reset CTS width */
6786 snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 54 0",
6787 intf);
6788 if (system(buf) != 0) {
6789 sigma_dut_print(dut, DUT_MSG_ERROR,
6790 "wifitool %s beeliner_fw_test 54 0 failed",
6791 intf);
6792 }
6793
6794 /* Enable Dynamic Bandwidth signalling by default */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006795 run_iwpriv(dut, intf, "cwmenable 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006796
6797 snprintf(buf, sizeof(buf), "iwconfig %s rts 2347", intf);
6798 if (system(buf) != 0) {
6799 sigma_dut_print(dut, DUT_MSG_ERROR,
6800 "iwpriv rts failed");
6801 }
6802 }
6803
6804 if (type && strcasecmp(type, "Testbed") == 0) {
6805 dut->testbed_flag_txsp = 1;
6806 dut->testbed_flag_rxsp = 1;
6807 /* STA has to set spatial stream to 2 per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006808 run_iwpriv(dut, intf, "vht_mcsmap 0xfff0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006809
6810 /* Disable LDPC per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006811 run_iwpriv(dut, intf, "ldpc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006812
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006813 run_iwpriv(dut, intf, "amsdu 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006814
6815 /* TODO: Disable STBC 2x1 transmit and receive */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006816 run_iwpriv(dut, intf, "tx_stbc 0");
6817 run_iwpriv(dut, intf, "rx_stbc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006818
6819 /* STA has to disable Short GI per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006820 run_iwpriv(dut, intf, "shortgi 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006821 }
6822
6823 if (type && strcasecmp(type, "DUT") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006824 run_iwpriv(dut, intf, "nss 3");
Arif Hussainac6c5112018-05-25 17:34:00 -07006825 dut->sta_nss = 3;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006826
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006827 run_iwpriv(dut, intf, "shortgi 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006828 }
6829}
6830
6831
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08006832#ifdef NL80211_SUPPORT
6833static int sta_set_he_mcs(struct sigma_dut *dut, const char *intf,
6834 enum he_mcs_config mcs)
6835{
6836 struct nl_msg *msg;
6837 int ret = 0;
6838 struct nlattr *params;
6839 int ifindex;
6840
6841 ifindex = if_nametoindex(intf);
6842 if (ifindex == 0) {
6843 sigma_dut_print(dut, DUT_MSG_ERROR,
6844 "%s: Index for interface %s failed",
6845 __func__, intf);
6846 return -1;
6847 }
6848
6849 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6850 NL80211_CMD_VENDOR)) ||
6851 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6852 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6853 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6854 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6855 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6856 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MCS,
6857 mcs)) {
6858 sigma_dut_print(dut, DUT_MSG_ERROR,
6859 "%s: err in adding vendor_cmd and vendor_data",
6860 __func__);
6861 nlmsg_free(msg);
6862 return -1;
6863 }
6864 nla_nest_end(msg, params);
6865
6866 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6867 if (ret) {
6868 sigma_dut_print(dut, DUT_MSG_ERROR,
6869 "%s: err in send_and_recv_msgs, ret=%d",
6870 __func__, ret);
6871 }
6872 return ret;
6873}
6874#endif /* NL80211_SUPPORT */
6875
6876
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07006877static int sta_set_action_tx_in_he_tb_ppdu(struct sigma_dut *dut,
6878 const char *intf, int enable)
6879{
6880#ifdef NL80211_SUPPORT
6881 struct nl_msg *msg;
6882 int ret = 0;
6883 struct nlattr *params;
6884 int ifindex;
6885
6886 ifindex = if_nametoindex(intf);
6887 if (ifindex == 0) {
6888 sigma_dut_print(dut, DUT_MSG_ERROR,
6889 "%s: Index for interface %s failed",
6890 __func__, intf);
6891 return -1;
6892 }
6893
6894 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6895 NL80211_CMD_VENDOR)) ||
6896 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6897 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6898 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6899 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6900 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6901 nla_put_u8(msg,
6902 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_ACTION_TX_TB_PPDU,
6903 enable)) {
6904 sigma_dut_print(dut, DUT_MSG_ERROR,
6905 "%s: err in adding vendor_cmd and vendor_data",
6906 __func__);
6907 nlmsg_free(msg);
6908 return -1;
6909 }
6910 nla_nest_end(msg, params);
6911
6912 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6913 if (ret) {
6914 sigma_dut_print(dut, DUT_MSG_ERROR,
6915 "%s: err in send_and_recv_msgs, ret=%d",
6916 __func__, ret);
6917 }
6918 return ret;
6919#else /* NL80211_SUPPORT */
6920 sigma_dut_print(dut, DUT_MSG_ERROR,
6921 "HE action Tx TB PPDU cannot be set without NL80211_SUPPORT defined");
6922 return -1;
6923#endif /* NL80211_SUPPORT */
6924}
6925
6926
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08006927static int sta_set_heconfig_and_wep_tkip(struct sigma_dut *dut,
6928 const char *intf, int enable)
6929{
6930#ifdef NL80211_SUPPORT
6931 struct nl_msg *msg;
6932 int ret = 0;
6933 struct nlattr *params;
6934 int ifindex;
6935
6936 ifindex = if_nametoindex(intf);
6937 if (ifindex == 0) {
6938 sigma_dut_print(dut, DUT_MSG_ERROR,
6939 "%s: Index for interface %s failed",
6940 __func__, intf);
6941 return -1;
6942 }
6943
6944 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6945 NL80211_CMD_VENDOR)) ||
6946 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6947 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6948 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6949 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6950 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6951 nla_put_u8(msg,
6952 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WEP_TKIP_IN_HE,
6953 enable)) {
6954 sigma_dut_print(dut, DUT_MSG_ERROR,
6955 "%s: err in adding vendor_cmd and vendor_data",
6956 __func__);
6957 nlmsg_free(msg);
6958 return -1;
6959 }
6960 nla_nest_end(msg, params);
6961
6962 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6963 if (ret) {
6964 sigma_dut_print(dut, DUT_MSG_ERROR,
6965 "%s: err in send_and_recv_msgs, ret=%d",
6966 __func__, ret);
6967 }
6968 return ret;
6969#else /* NL80211_SUPPORT */
6970 sigma_dut_print(dut, DUT_MSG_ERROR,
6971 "HE config enablement cannot be changed without NL80211_SUPPORT defined");
6972 return -1;
6973#endif /* NL80211_SUPPORT */
6974}
6975
6976
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08006977#ifdef NL80211_SUPPORT
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08006978
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08006979static int sta_set_he_testbed_def(struct sigma_dut *dut,
6980 const char *intf, int cfg)
6981{
6982 struct nl_msg *msg;
6983 int ret = 0;
6984 struct nlattr *params;
6985 int ifindex;
6986
6987 ifindex = if_nametoindex(intf);
6988 if (ifindex == 0) {
6989 sigma_dut_print(dut, DUT_MSG_ERROR,
6990 "%s: Index for interface %s failed",
6991 __func__, intf);
6992 return -1;
6993 }
6994
6995 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6996 NL80211_CMD_VENDOR)) ||
6997 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6998 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6999 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7000 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7001 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7002 nla_put_u8(msg,
7003 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_SET_HE_TESTBED_DEFAULTS,
7004 cfg)) {
7005 sigma_dut_print(dut, DUT_MSG_ERROR,
7006 "%s: err in adding vendor_cmd and vendor_data",
7007 __func__);
7008 nlmsg_free(msg);
7009 return -1;
7010 }
7011 nla_nest_end(msg, params);
7012
7013 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7014 if (ret) {
7015 sigma_dut_print(dut, DUT_MSG_ERROR,
7016 "%s: err in send_and_recv_msgs, ret=%d",
7017 __func__, ret);
7018 }
7019 return ret;
7020}
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08007021
7022
7023static int sta_set_2g_vht_supp(struct sigma_dut *dut, const char *intf, int cfg)
7024{
7025 struct nl_msg *msg;
7026 int ret = 0;
7027 struct nlattr *params;
7028 int ifindex;
7029
7030 ifindex = if_nametoindex(intf);
7031 if (ifindex == 0) {
7032 sigma_dut_print(dut, DUT_MSG_ERROR,
7033 "%s: Index for interface %s failed",
7034 __func__, intf);
7035 return -1;
7036 }
7037
7038 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7039 NL80211_CMD_VENDOR)) ||
7040 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7041 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7042 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7043 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7044 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7045 nla_put_u8(msg,
7046 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_2G_VHT,
7047 cfg)) {
7048 sigma_dut_print(dut, DUT_MSG_ERROR,
7049 "%s: err in adding vendor_cmd and vendor_data",
7050 __func__);
7051 nlmsg_free(msg);
7052 return -1;
7053 }
7054 nla_nest_end(msg, params);
7055
7056 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7057 if (ret) {
7058 sigma_dut_print(dut, DUT_MSG_ERROR,
7059 "%s: err in send_and_recv_msgs, ret=%d",
7060 __func__, ret);
7061 }
7062 return ret;
7063}
7064
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08007065#endif /* NL80211_SUPPORT */
7066
7067
Qiwei Caib6806972020-01-15 13:52:11 +08007068int sta_set_addba_buf_size(struct sigma_dut *dut,
7069 const char *intf, int bufsize)
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08007070{
7071#ifdef NL80211_SUPPORT
7072 struct nl_msg *msg;
7073 int ret = 0;
7074 struct nlattr *params;
7075 int ifindex;
7076
7077 ifindex = if_nametoindex(intf);
7078 if (ifindex == 0) {
7079 sigma_dut_print(dut, DUT_MSG_ERROR,
7080 "%s: Index for interface %s failed",
7081 __func__, intf);
7082 return -1;
7083 }
7084
7085 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7086 NL80211_CMD_VENDOR)) ||
7087 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7088 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7089 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7090 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7091 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
Kiran Kumar Lokere26e27582018-08-01 16:18:34 -07007092 nla_put_u16(msg,
7093 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE,
7094 bufsize)) {
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08007095 sigma_dut_print(dut, DUT_MSG_ERROR,
7096 "%s: err in adding vendor_cmd and vendor_data",
7097 __func__);
7098 nlmsg_free(msg);
7099 return -1;
7100 }
7101 nla_nest_end(msg, params);
7102
7103 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7104 if (ret) {
7105 sigma_dut_print(dut, DUT_MSG_ERROR,
7106 "%s: err in send_and_recv_msgs, ret=%d",
7107 __func__, ret);
7108 }
7109 return ret;
7110#else /* NL80211_SUPPORT */
7111 sigma_dut_print(dut, DUT_MSG_ERROR,
7112 "AddBA bufsize cannot be changed without NL80211_SUPPORT defined");
7113 return -1;
7114#endif /* NL80211_SUPPORT */
7115}
7116
7117
Arif Hussain8d5b27b2018-05-14 14:31:03 -07007118static int sta_set_tx_beamformee(struct sigma_dut *dut, const char *intf,
7119 int enable)
7120{
7121#ifdef NL80211_SUPPORT
7122 struct nl_msg *msg;
7123 int ret = 0;
7124 struct nlattr *params;
7125 int ifindex;
7126
7127 ifindex = if_nametoindex(intf);
7128 if (ifindex == 0) {
7129 sigma_dut_print(dut, DUT_MSG_ERROR,
7130 "%s: Index for interface %s failed",
7131 __func__, intf);
7132 return -1;
7133 }
7134
7135 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7136 NL80211_CMD_VENDOR)) ||
7137 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7138 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7139 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7140 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7141 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7142 nla_put_u8(msg,
7143 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_TX_BEAMFORMEE,
7144 enable)) {
7145 sigma_dut_print(dut, DUT_MSG_ERROR,
7146 "%s: err in adding vendor_cmd and vendor_data",
7147 __func__);
7148 nlmsg_free(msg);
7149 return -1;
7150 }
7151 nla_nest_end(msg, params);
7152
7153 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7154 if (ret) {
7155 sigma_dut_print(dut, DUT_MSG_ERROR,
7156 "%s: err in send_and_recv_msgs, ret=%d",
7157 __func__, ret);
7158 }
7159 return ret;
7160#else /* NL80211_SUPPORT */
7161 sigma_dut_print(dut, DUT_MSG_ERROR,
7162 "tx beamformee cannot be changed without NL80211_SUPPORT defined");
7163 return -1;
7164#endif /* NL80211_SUPPORT */
7165}
7166
7167
Arif Hussain9765f7d2018-07-03 08:28:26 -07007168static int sta_set_beamformee_sts(struct sigma_dut *dut, const char *intf,
7169 int val)
7170{
7171#ifdef NL80211_SUPPORT
7172 struct nl_msg *msg;
7173 int ret = 0;
7174 struct nlattr *params;
7175 int ifindex;
7176
7177 ifindex = if_nametoindex(intf);
7178 if (ifindex == 0) {
7179 sigma_dut_print(dut, DUT_MSG_ERROR,
7180 "%s: Index for interface %s failed, val:%d",
7181 __func__, intf, val);
7182 return -1;
7183 }
7184
7185 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7186 NL80211_CMD_VENDOR)) ||
7187 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7188 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7189 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7190 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7191 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7192 nla_put_u8(msg,
7193 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_BEAMFORMEE_NSTS,
7194 val)) {
7195 sigma_dut_print(dut, DUT_MSG_ERROR,
7196 "%s: err in adding vendor_cmd and vendor_data, val: %d",
7197 __func__, val);
7198 nlmsg_free(msg);
7199 return -1;
7200 }
7201 nla_nest_end(msg, params);
7202
7203 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7204 if (ret) {
7205 sigma_dut_print(dut, DUT_MSG_ERROR,
7206 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
7207 __func__, ret, val);
7208 }
7209 return ret;
7210#else /* NL80211_SUPPORT */
7211 sigma_dut_print(dut, DUT_MSG_ERROR,
7212 "beamformee sts cannot be changed without NL80211_SUPPORT defined");
7213 return -1;
7214#endif /* NL80211_SUPPORT */
7215}
7216
7217
Arif Hussain68d23f52018-07-11 13:39:08 -07007218#ifdef NL80211_SUPPORT
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07007219static int sta_set_mac_padding_duration(struct sigma_dut *dut, const char *intf,
7220 enum qca_wlan_he_mac_padding_dur val)
7221{
Arif Hussain68d23f52018-07-11 13:39:08 -07007222 struct nl_msg *msg;
7223 int ret = 0;
7224 struct nlattr *params;
7225 int ifindex;
7226
7227 ifindex = if_nametoindex(intf);
7228 if (ifindex == 0) {
7229 sigma_dut_print(dut, DUT_MSG_ERROR,
7230 "%s: Index for interface %s failed, val:%d",
7231 __func__, intf, val);
7232 return -1;
7233 }
7234
7235 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7236 NL80211_CMD_VENDOR)) ||
7237 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7238 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7239 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7240 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7241 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7242 nla_put_u8(msg,
7243 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MAC_PADDING_DUR,
7244 val)) {
7245 sigma_dut_print(dut, DUT_MSG_ERROR,
7246 "%s: err in adding vendor_cmd and vendor_data, val: %d",
7247 __func__, val);
7248 nlmsg_free(msg);
7249 return -1;
7250 }
7251 nla_nest_end(msg, params);
7252
7253 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7254 if (ret) {
7255 sigma_dut_print(dut, DUT_MSG_ERROR,
7256 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
7257 __func__, ret, val);
7258 }
7259 return ret;
Arif Hussain68d23f52018-07-11 13:39:08 -07007260}
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07007261#endif /* NL80211_SUPPORT */
Arif Hussain68d23f52018-07-11 13:39:08 -07007262
7263
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07007264static int sta_set_tx_su_ppdu_cfg(struct sigma_dut *dut, const char *intf,
7265 int val)
7266{
7267#ifdef NL80211_SUPPORT
7268 struct nl_msg *msg;
7269 int ret = 0;
7270 struct nlattr *params;
7271 int ifindex;
7272
7273 ifindex = if_nametoindex(intf);
7274 if (ifindex == 0) {
7275 sigma_dut_print(dut, DUT_MSG_ERROR,
7276 "%s: Index for interface %s failed, val:%d",
7277 __func__, intf, val);
7278 return -1;
7279 }
7280
7281 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7282 NL80211_CMD_VENDOR)) ||
7283 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7284 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7285 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7286 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7287 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7288 nla_put_u8(msg,
7289 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_SUPPDU,
7290 val)) {
7291 sigma_dut_print(dut, DUT_MSG_ERROR,
7292 "%s: err in adding vendor_cmd and vendor_data, val: %d",
7293 __func__, val);
7294 nlmsg_free(msg);
7295 return -1;
7296 }
7297 nla_nest_end(msg, params);
7298
7299 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7300 if (ret) {
7301 sigma_dut_print(dut, DUT_MSG_ERROR,
7302 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
7303 __func__, ret, val);
7304 }
7305 return ret;
7306#else /* NL80211_SUPPORT */
7307 sigma_dut_print(dut, DUT_MSG_ERROR,
7308 "Tx SU PPDU cannot be set without NL80211_SUPPORT defined");
7309 return -1;
7310#endif /* NL80211_SUPPORT */
7311}
7312
7313
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07007314#ifdef NL80211_SUPPORT
7315static int sta_set_he_om_ctrl_reset(struct sigma_dut *dut, const char *intf)
7316{
7317 struct nl_msg *msg;
7318 int ret = 0;
7319 struct nlattr *params;
7320 int ifindex;
7321
7322 ifindex = if_nametoindex(intf);
7323 if (ifindex == 0) {
7324 sigma_dut_print(dut, DUT_MSG_ERROR,
7325 "%s: Index for interface %s failed",
7326 __func__, intf);
7327 return -1;
7328 }
7329
7330 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7331 NL80211_CMD_VENDOR)) ||
7332 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7333 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7334 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7335 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7336 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7337 nla_put_flag(msg,
7338 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_CLEAR_HE_OM_CTRL_CONFIG)) {
7339 sigma_dut_print(dut, DUT_MSG_ERROR,
7340 "%s: err in adding vendor_cmd and vendor_data",
7341 __func__);
7342 nlmsg_free(msg);
7343 return -1;
7344 }
7345 nla_nest_end(msg, params);
7346
7347 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7348 if (ret) {
7349 sigma_dut_print(dut, DUT_MSG_ERROR,
7350 "%s: err in send_and_recv_msgs, ret=%d",
7351 __func__, ret);
7352 }
7353 return ret;
7354}
7355#endif /* NL80211_SUPPORT */
7356
7357
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07007358static int sta_set_mu_edca_override(struct sigma_dut *dut, const char *intf,
7359 int val)
7360{
7361#ifdef NL80211_SUPPORT
7362 struct nl_msg *msg;
7363 int ret = 0;
7364 struct nlattr *params;
7365 int ifindex;
7366
7367 ifindex = if_nametoindex(intf);
7368 if (ifindex == 0) {
7369 sigma_dut_print(dut, DUT_MSG_ERROR,
7370 "%s: Index for interface %s failed, val:%d",
7371 __func__, intf, val);
7372 return -1;
7373 }
7374
7375 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7376 NL80211_CMD_VENDOR)) ||
7377 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7378 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7379 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7380 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7381 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7382 nla_put_u8(msg,
7383 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_OVERRIDE_MU_EDCA,
7384 val)) {
7385 sigma_dut_print(dut, DUT_MSG_ERROR,
7386 "%s: err in adding vendor_cmd and vendor_data, val: %d",
7387 __func__, val);
7388 nlmsg_free(msg);
7389 return -1;
7390 }
7391 nla_nest_end(msg, params);
7392
7393 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7394 if (ret) {
7395 sigma_dut_print(dut, DUT_MSG_ERROR,
7396 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
7397 __func__, ret, val);
7398 }
7399 return ret;
7400#else /* NL80211_SUPPORT */
7401 sigma_dut_print(dut, DUT_MSG_ERROR,
7402 "MU EDCA override cannot be changed without NL80211_SUPPORT defined");
7403 return -1;
7404#endif /* NL80211_SUPPORT */
7405}
7406
7407
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07007408static int sta_set_om_ctrl_supp(struct sigma_dut *dut, const char *intf,
7409 int val)
7410{
7411#ifdef NL80211_SUPPORT
7412 struct nl_msg *msg;
7413 int ret = 0;
7414 struct nlattr *params;
7415 int ifindex;
7416
7417 ifindex = if_nametoindex(intf);
7418 if (ifindex == 0) {
7419 sigma_dut_print(dut, DUT_MSG_ERROR,
7420 "%s: Index for interface %s failed, val:%d",
7421 __func__, intf, val);
7422 return -1;
7423 }
7424
7425 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7426 NL80211_CMD_VENDOR)) ||
7427 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7428 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7429 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7430 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7431 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7432 nla_put_u8(msg,
7433 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OM_CTRL_SUPP,
7434 val)) {
7435 sigma_dut_print(dut, DUT_MSG_ERROR,
7436 "%s: err in adding vendor_cmd and vendor_data, val: %d",
7437 __func__, val);
7438 nlmsg_free(msg);
7439 return -1;
7440 }
7441 nla_nest_end(msg, params);
7442
7443 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7444 if (ret) {
7445 sigma_dut_print(dut, DUT_MSG_ERROR,
7446 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
7447 __func__, ret, val);
7448 }
7449 return ret;
7450#else /* NL80211_SUPPORT */
7451 sigma_dut_print(dut, DUT_MSG_ERROR,
7452 "HE OM ctrl cannot be changed without NL80211_SUPPORT defined");
7453 return -1;
7454#endif /* NL80211_SUPPORT */
7455}
7456
7457
Arif Hussain480d5f42019-03-12 14:40:42 -07007458static int sta_set_twt_req_support(struct sigma_dut *dut, const char *intf,
7459 int val)
7460{
7461#ifdef NL80211_SUPPORT
7462 struct nl_msg *msg;
7463 int ret;
7464 struct nlattr *params;
7465 int ifindex;
7466
7467 ifindex = if_nametoindex(intf);
7468 if (ifindex == 0) {
7469 sigma_dut_print(dut, DUT_MSG_ERROR,
7470 "%s: Index for interface %s failed, val:%d",
7471 __func__, intf, val);
7472 return -1;
7473 }
7474
7475 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7476 NL80211_CMD_VENDOR)) ||
7477 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7478 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7479 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7480 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7481 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7482 nla_put_u8(msg,
7483 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TWT_REQ_SUPPORT,
7484 val)) {
7485 sigma_dut_print(dut, DUT_MSG_ERROR,
7486 "%s: err in adding vendor_cmd and vendor_data, val: %d",
7487 __func__, val);
7488 nlmsg_free(msg);
7489 return -1;
7490 }
7491 nla_nest_end(msg, params);
7492
7493 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7494 if (ret) {
7495 sigma_dut_print(dut, DUT_MSG_ERROR,
7496 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
7497 __func__, ret, val);
7498 }
7499 return ret;
7500#else /* NL80211_SUPPORT */
7501 sigma_dut_print(dut, DUT_MSG_ERROR,
7502 "TWT Request cannot be changed without NL80211_SUPPORT defined");
7503 return -1;
7504#endif /* NL80211_SUPPORT */
7505}
7506
7507
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08007508static void sta_reset_default_wcn(struct sigma_dut *dut, const char *intf,
7509 const char *type)
7510{
7511 char buf[60];
7512
7513 if (dut->program == PROGRAM_HE) {
7514 /* resetting phymode to auto in case of HE program */
7515 snprintf(buf, sizeof(buf), "iwpriv %s setphymode 0", intf);
7516 if (system(buf) != 0) {
7517 sigma_dut_print(dut, DUT_MSG_ERROR,
7518 "iwpriv %s setphymode failed", intf);
7519 }
7520
Amarnath Hullur Subramanyam9cecb502018-04-25 13:26:30 -07007521 /* reset the rate to Auto rate */
7522 snprintf(buf, sizeof(buf), "iwpriv %s set_11ax_rate 0xff",
7523 intf);
7524 if (system(buf) != 0) {
7525 sigma_dut_print(dut, DUT_MSG_ERROR,
7526 "iwpriv %s set_11ax_rate 0xff failed",
7527 intf);
7528 }
7529
Kiran Kumar Lokere86cfe3a2018-06-01 11:55:15 -07007530 /* reset the LDPC setting */
7531 snprintf(buf, sizeof(buf), "iwpriv %s ldpc 1", intf);
7532 if (system(buf) != 0) {
7533 sigma_dut_print(dut, DUT_MSG_ERROR,
7534 "iwpriv %s ldpc 1 failed", intf);
7535 }
7536
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08007537 /* reset the power save setting */
7538 snprintf(buf, sizeof(buf), "iwpriv %s setPower 2", intf);
7539 if (system(buf) != 0) {
7540 sigma_dut_print(dut, DUT_MSG_ERROR,
7541 "iwpriv %s setPower 2 failed", intf);
7542 }
7543
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08007544 /* remove all network profiles */
7545 remove_wpa_networks(intf);
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08007546
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08007547 /* Configure ADDBA Req/Rsp buffer size to be 64 */
7548 sta_set_addba_buf_size(dut, intf, 64);
7549
Amarnath Hullur Subramanyam5f32d572018-03-02 00:02:33 -08007550#ifdef NL80211_SUPPORT
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08007551 /* Reset the device HE capabilities to its default supported
7552 * configuration. */
7553 sta_set_he_testbed_def(dut, intf, 0);
7554
Amarnath Hullur Subramanyam5f32d572018-03-02 00:02:33 -08007555 /* Disable noackpolicy for all AC */
7556 if (nlvendor_sta_set_noack(dut, intf, 0, QCA_WLAN_AC_ALL)) {
7557 sigma_dut_print(dut, DUT_MSG_ERROR,
7558 "Disable of noackpolicy for all AC failed");
7559 }
7560#endif /* NL80211_SUPPORT */
7561
Amarnath Hullur Subramanyamb1724a52018-03-07 14:31:46 -08007562 /* Enable WMM by default */
7563 if (wcn_sta_set_wmm(dut, intf, "on")) {
7564 sigma_dut_print(dut, DUT_MSG_ERROR,
7565 "Enable of WMM in sta_reset_default_wcn failed");
7566 }
7567
7568 /* Disable ADDBA_REJECT by default */
7569 if (nlvendor_sta_set_addba_reject(dut, intf, 0)) {
7570 sigma_dut_print(dut, DUT_MSG_ERROR,
7571 "Disable of addba_reject in sta_reset_default_wcn failed");
7572 }
7573
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08007574 /* Enable sending of ADDBA by default */
7575 if (nlvendor_config_send_addba(dut, intf, 1)) {
7576 sigma_dut_print(dut, DUT_MSG_ERROR,
7577 "Enable sending of ADDBA in sta_reset_default_wcn failed");
7578 }
7579
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08007580 /* Enable AMPDU by default */
7581 iwpriv_sta_set_ampdu(dut, intf, 1);
7582
Subhani Shaik8e7a3052018-04-24 14:03:00 -07007583#ifdef NL80211_SUPPORT
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -08007584 if (wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_AUTO)) {
Subhani Shaik8e7a3052018-04-24 14:03:00 -07007585 sigma_dut_print(dut, DUT_MSG_ERROR,
7586 "Set LTF config to default in sta_reset_default_wcn failed");
7587 }
Arif Hussain9765f7d2018-07-03 08:28:26 -07007588
Kiran Kumar Lokerebad51122018-12-12 19:03:36 -08007589 /* set the beamformee NSTS(maximum number of
7590 * space-time streams) to default DUT config
7591 */
7592 if (sta_set_beamformee_sts(dut, intf, 7)) {
Arif Hussain9765f7d2018-07-03 08:28:26 -07007593 sigma_dut_print(dut, DUT_MSG_ERROR,
7594 "Failed to set BeamformeeSTS");
7595 }
Arif Hussain68d23f52018-07-11 13:39:08 -07007596
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07007597 if (sta_set_mac_padding_duration(
7598 dut, intf,
7599 QCA_WLAN_HE_NO_ADDITIONAL_PROCESS_TIME)) {
Arif Hussain68d23f52018-07-11 13:39:08 -07007600 sigma_dut_print(dut, DUT_MSG_ERROR,
7601 "Failed to set MAC padding duration");
7602 }
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07007603
7604 if (sta_set_mu_edca_override(dut, intf, 0)) {
7605 sigma_dut_print(dut, DUT_MSG_ERROR,
7606 "ErrorCode,Failed to set MU EDCA override disable");
7607 }
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07007608
7609 if (sta_set_om_ctrl_supp(dut, intf, 1)) {
7610 sigma_dut_print(dut, DUT_MSG_ERROR,
7611 "Failed to set OM ctrl supp");
7612 }
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07007613
7614 if (sta_set_tx_su_ppdu_cfg(dut, intf, 1)) {
7615 sigma_dut_print(dut, DUT_MSG_ERROR,
7616 "Failed to set Tx SU PPDU enable");
7617 }
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07007618
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07007619 if (sta_set_action_tx_in_he_tb_ppdu(dut, intf, 0)) {
7620 sigma_dut_print(dut, DUT_MSG_ERROR,
7621 "failed to send TB PPDU Tx cfg");
7622 }
7623
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07007624 if (sta_set_he_om_ctrl_reset(dut, intf)) {
7625 sigma_dut_print(dut, DUT_MSG_ERROR,
7626 "Failed to set OM ctrl reset");
7627 }
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08007628
7629 /* +HTC-HE support default on */
7630 if (sta_set_he_htc_supp(dut, intf, 1)) {
7631 sigma_dut_print(dut, DUT_MSG_ERROR,
7632 "Setting of +HTC-HE support failed");
7633 }
Subhani Shaik8e7a3052018-04-24 14:03:00 -07007634#endif /* NL80211_SUPPORT */
7635
Arif Hussain8d5b27b2018-05-14 14:31:03 -07007636 if (sta_set_tx_beamformee(dut, intf, 1)) {
7637 sigma_dut_print(dut, DUT_MSG_ERROR,
7638 "Set tx beamformee enable by default in sta_reset_default_wcn failed");
7639 }
7640
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08007641 /* Set nss to 1 and MCS 0-7 in case of testbed */
7642 if (type && strcasecmp(type, "Testbed") == 0) {
7643#ifdef NL80211_SUPPORT
7644 int ret;
7645#endif /* NL80211_SUPPORT */
7646
7647 snprintf(buf, sizeof(buf), "iwpriv %s nss 1", intf);
7648 if (system(buf) != 0) {
7649 sigma_dut_print(dut, DUT_MSG_ERROR,
7650 "iwpriv %s nss failed", intf);
7651 }
7652
7653#ifdef NL80211_SUPPORT
7654 ret = sta_set_he_mcs(dut, intf, HE_80_MCS0_7);
7655 if (ret) {
7656 sigma_dut_print(dut, DUT_MSG_ERROR,
7657 "Setting of MCS failed, ret:%d",
7658 ret);
7659 }
7660#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyamc67621d2018-02-04 23:18:01 -08007661
7662 /* Disable STBC as default */
7663 wcn_sta_set_stbc(dut, intf, "0");
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08007664
7665 /* Disable AMSDU as default */
7666 iwpriv_sta_set_amsdu(dut, intf, "0");
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08007667
7668#ifdef NL80211_SUPPORT
7669 /* HE fragmentation default off */
7670 if (sta_set_he_fragmentation(dut, intf,
7671 HE_FRAG_DISABLE)) {
7672 sigma_dut_print(dut, DUT_MSG_ERROR,
7673 "Setting of HE fragmentation failed");
7674 }
Kiran Kumar Lokerebad51122018-12-12 19:03:36 -08007675
7676 /* set the beamformee NSTS(maximum number of
7677 * space-time streams) to default testbed config
7678 */
7679 if (sta_set_beamformee_sts(dut, intf, 3)) {
7680 sigma_dut_print(dut, DUT_MSG_ERROR,
7681 "Failed to set BeamformeeSTS");
7682 }
7683
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08007684 /* +HTC-HE support default off */
7685 if (sta_set_he_htc_supp(dut, intf, 0)) {
7686 sigma_dut_print(dut, DUT_MSG_ERROR,
7687 "Setting of +HTC-HE support failed");
7688 }
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08007689
7690 /* Set device HE capabilities to testbed default
7691 * configuration. */
7692 if (sta_set_he_testbed_def(dut, intf, 1)) {
7693 sigma_dut_print(dut, DUT_MSG_DEBUG,
7694 "Failed to set HE defaults");
7695 }
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08007696
7697 /* Disable VHT support in 2.4 GHz for testbed */
7698 sta_set_2g_vht_supp(dut, intf, 0);
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08007699#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08007700
7701 /* Enable WEP/TKIP with HE capability in testbed */
7702 if (sta_set_heconfig_and_wep_tkip(dut, intf, 1)) {
7703 sigma_dut_print(dut, DUT_MSG_ERROR,
7704 "Enabling HE config with WEP/TKIP failed");
7705 }
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08007706 }
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08007707
7708 /* Defaults in case of DUT */
7709 if (type && strcasecmp(type, "DUT") == 0) {
Arif Hussaind48fcc72018-05-01 18:34:18 -07007710 /* Enable STBC by default */
7711 wcn_sta_set_stbc(dut, intf, "1");
7712
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08007713 /* set nss to 2 */
7714 snprintf(buf, sizeof(buf), "iwpriv %s nss 2", intf);
7715 if (system(buf) != 0) {
7716 sigma_dut_print(dut, DUT_MSG_ERROR,
7717 "iwpriv %s nss 2 failed", intf);
7718 }
Arif Hussainac6c5112018-05-25 17:34:00 -07007719 dut->sta_nss = 2;
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08007720
7721#ifdef NL80211_SUPPORT
Arif Hussainae239842018-05-01 18:20:05 -07007722 /* Set HE_MCS to 0-11 */
7723 if (sta_set_he_mcs(dut, intf, HE_80_MCS0_11)) {
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08007724 sigma_dut_print(dut, DUT_MSG_ERROR,
7725 "Setting of MCS failed");
7726 }
7727#endif /* NL80211_SUPPORT */
7728
7729 /* Disable WEP/TKIP with HE capability in DUT */
7730 if (sta_set_heconfig_and_wep_tkip(dut, intf, 0)) {
7731 sigma_dut_print(dut, DUT_MSG_ERROR,
7732 "Enabling HE config with WEP/TKIP failed");
7733 }
7734 }
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08007735 }
7736}
7737
7738
Jouni Malinenf7222712019-06-13 01:50:21 +03007739static enum sigma_cmd_result cmd_sta_reset_default(struct sigma_dut *dut,
7740 struct sigma_conn *conn,
7741 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007742{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007743 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007744 const char *band = get_param(cmd, "band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007745 const char *type;
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07007746 const char *program = get_param(cmd, "program");
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05307747 const char *dev_role = get_param(cmd, "DevRole");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007748
Jouni Malinenb21f0542019-11-04 17:53:38 +02007749 if (dut->station_ifname_2g &&
7750 strcmp(dut->station_ifname_2g, intf) == 0)
7751 dut->use_5g = 0;
7752 else if (dut->station_ifname_5g &&
7753 strcmp(dut->station_ifname_5g, intf) == 0)
7754 dut->use_5g = 1;
7755
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07007756 if (!program)
7757 program = get_param(cmd, "prog");
7758 dut->program = sigma_program_to_enum(program);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007759 dut->device_type = STA_unknown;
7760 type = get_param(cmd, "type");
7761 if (type && strcasecmp(type, "Testbed") == 0)
7762 dut->device_type = STA_testbed;
7763 if (type && strcasecmp(type, "DUT") == 0)
7764 dut->device_type = STA_dut;
7765
7766 if (dut->program == PROGRAM_TDLS) {
7767 /* Clear TDLS testing mode */
7768 wpa_command(intf, "SET tdls_disabled 0");
7769 wpa_command(intf, "SET tdls_testing 0");
7770 dut->no_tpk_expiration = 0;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007771 if (get_driver_type(dut) == DRIVER_WCN) {
Pradeep Reddy POTTETI8ce2a232016-10-28 12:17:32 +05307772 /* Enable the WCN driver in TDLS Explicit trigger mode
7773 */
7774 wpa_command(intf, "SET tdls_external_control 0");
7775 wpa_command(intf, "SET tdls_trigger_control 0");
7776 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007777 }
7778
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07007779#ifdef MIRACAST
7780 if (dut->program == PROGRAM_WFD ||
7781 dut->program == PROGRAM_DISPLAYR2)
7782 miracast_sta_reset_default(dut, conn, cmd);
7783#endif /* MIRACAST */
7784
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007785 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007786 case DRIVER_ATHEROS:
7787 sta_reset_default_ath(dut, intf, type);
7788 break;
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08007789 case DRIVER_WCN:
7790 sta_reset_default_wcn(dut, intf, type);
7791 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007792 default:
7793 break;
7794 }
7795
7796#ifdef ANDROID_NAN
7797 if (dut->program == PROGRAM_NAN)
7798 nan_cmd_sta_reset_default(dut, conn, cmd);
7799#endif /* ANDROID_NAN */
7800
Vinay Gannevaram3b9fdd32019-06-14 17:55:44 +05307801 if (dut->program == PROGRAM_LOC &&
7802 lowi_cmd_sta_reset_default(dut, conn, cmd) < 0)
7803 return ERROR_SEND_STATUS;
7804
Jouni Malinenba630452018-06-22 11:49:59 +03007805 if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007806 unlink("SP/wi-fi.org/pps.xml");
7807 if (system("rm -r SP/*") != 0) {
7808 }
7809 unlink("next-client-cert.pem");
7810 unlink("next-client-key.pem");
7811 }
7812
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007813 /* For WPS program of the 60 GHz band the band type needs to be saved */
7814 if (dut->program == PROGRAM_WPS) {
7815 if (band && strcasecmp(band, "60GHz") == 0) {
7816 dut->band = WPS_BAND_60G;
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02007817 /* For 60 GHz enable WPS for WPS TCs */
7818 dut->wps_disable = 0;
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007819 } else {
7820 dut->band = WPS_BAND_NON_60G;
7821 }
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02007822 } else if (dut->program == PROGRAM_60GHZ) {
7823 /* For 60 GHz MAC/PHY TCs WPS must be disabled */
7824 dut->wps_disable = 1;
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007825 }
7826
Alexei Avshalom Lazar157ba062018-12-23 16:15:26 +02007827 if (is_60g_sigma_dut(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007828 const char *dev_role = get_param(cmd, "DevRole");
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02007829 char buf[256];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007830
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02007831 sigma_dut_print(dut, DUT_MSG_INFO,
7832 "WPS 60 GHz program, wps_disable = %d",
7833 dut->wps_disable);
7834
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007835 if (!dev_role) {
7836 send_resp(dut, conn, SIGMA_ERROR,
7837 "errorCode,Missing DevRole argument");
7838 return 0;
7839 }
7840
7841 if (strcasecmp(dev_role, "STA") == 0)
7842 dut->dev_role = DEVROLE_STA;
7843 else if (strcasecmp(dev_role, "PCP") == 0)
7844 dut->dev_role = DEVROLE_PCP;
7845 else {
7846 send_resp(dut, conn, SIGMA_ERROR,
7847 "errorCode,Unknown DevRole");
7848 return 0;
7849 }
7850
7851 if (dut->device_type == STA_unknown) {
7852 sigma_dut_print(dut, DUT_MSG_ERROR,
7853 "Device type is not STA testbed or DUT");
7854 send_resp(dut, conn, SIGMA_ERROR,
7855 "errorCode,Unknown device type");
7856 return 0;
7857 }
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02007858
7859 sigma_dut_print(dut, DUT_MSG_DEBUG,
7860 "Setting msdu_size to MAX: 7912");
7861 snprintf(buf, sizeof(buf), "ifconfig %s mtu 7912",
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007862 get_station_ifname(dut));
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02007863
7864 if (system(buf) != 0) {
7865 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
7866 buf);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007867 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02007868 }
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02007869
7870 if (sta_set_force_mcs(dut, 0, 1)) {
7871 sigma_dut_print(dut, DUT_MSG_ERROR,
7872 "Failed to reset force MCS");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007873 return ERROR_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02007874 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007875 }
7876
7877 wpa_command(intf, "WPS_ER_STOP");
7878 wpa_command(intf, "FLUSH");
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05307879 wpa_command(intf, "ERP_FLUSH");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007880 wpa_command(intf, "SET radio_disabled 0");
7881
Alexei Avshalom Lazar744ae8a2019-01-31 17:26:46 +02007882 dut->wps_forced_version = 0;
7883
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007884 if (dut->wsc_fragment) {
7885 dut->wsc_fragment = 0;
7886 wpa_command(intf, "SET device_name Test client");
7887 wpa_command(intf, "SET manufacturer ");
7888 wpa_command(intf, "SET model_name ");
7889 wpa_command(intf, "SET model_number ");
7890 wpa_command(intf, "SET serial_number ");
7891 }
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02007892 if (is_60g_sigma_dut(dut) && dut->force_rsn_ie) {
7893 dut->force_rsn_ie = FORCE_RSN_IE_NONE;
7894 sta_60g_force_rsn_ie(dut, FORCE_RSN_IE_NONE);
7895 }
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007896
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007897 if (dut->tmp_mac_addr && dut->set_macaddr) {
7898 dut->tmp_mac_addr = 0;
7899 if (system(dut->set_macaddr) != 0) {
7900 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to clear "
7901 "temporary MAC address");
7902 }
7903 }
7904
7905 set_ps(intf, dut, 0);
7906
Jouni Malinenba630452018-06-22 11:49:59 +03007907 if (dut->program == PROGRAM_HS2 || dut->program == PROGRAM_HS2_R2 ||
7908 dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007909 wpa_command(intf, "SET interworking 1");
7910 wpa_command(intf, "SET hs20 1");
7911 }
7912
Deepak Dhamdhere0fe0e452017-12-18 14:52:09 -08007913 if (dut->program == PROGRAM_HS2_R2 ||
Jouni Malinenba630452018-06-22 11:49:59 +03007914 dut->program == PROGRAM_HS2_R3 ||
Deepak Dhamdhere0fe0e452017-12-18 14:52:09 -08007915 dut->program == PROGRAM_OCE) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007916 wpa_command(intf, "SET pmf 1");
7917 } else {
7918 wpa_command(intf, "SET pmf 0");
7919 }
7920
7921 hs2_clear_credentials(intf);
7922 wpa_command(intf, "SET hessid 00:00:00:00:00:00");
7923 wpa_command(intf, "SET access_network_type 15");
7924
7925 static_ip_file(0, NULL, NULL, NULL);
7926 kill_dhcp_client(dut, intf);
7927 clear_ip_addr(dut, intf);
7928
7929 dut->er_oper_performed = 0;
7930 dut->er_oper_bssid[0] = '\0';
7931
priyadharshini gowthamanad6cbba2016-10-04 10:39:58 -07007932 if (dut->program == PROGRAM_LOC) {
7933 /* Disable Interworking by default */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007934 wpa_command(get_station_ifname(dut), "SET interworking 0");
priyadharshini gowthamanad6cbba2016-10-04 10:39:58 -07007935 }
7936
Ashwini Patil00402582017-04-13 12:29:39 +05307937 if (dut->program == PROGRAM_MBO) {
7938 free(dut->non_pref_ch_list);
7939 dut->non_pref_ch_list = NULL;
Ashwini Patil5acd7382017-04-13 15:55:04 +05307940 free(dut->btm_query_cand_list);
7941 dut->btm_query_cand_list = NULL;
Ashwini Patilc63161e2017-04-13 16:30:23 +05307942 wpa_command(intf, "SET reject_btm_req_reason 0");
Ashwini Patila75de5a2017-04-13 16:35:05 +05307943 wpa_command(intf, "SET ignore_assoc_disallow 0");
Ashwini Patild174f2c2017-04-13 16:49:46 +05307944 wpa_command(intf, "SET gas_address3 0");
Ashwini Patil9183fdb2017-04-13 16:58:25 +05307945 wpa_command(intf, "SET roaming 1");
Ankita Bajaj1d974552018-09-18 16:56:44 +05307946 wpa_command(intf, "SET interworking 1");
Ashwini Patil00402582017-04-13 12:29:39 +05307947 }
7948
Jouni Malinen3c367e82017-06-23 17:01:47 +03007949 free(dut->rsne_override);
7950 dut->rsne_override = NULL;
7951
Jouni Malinen68143132017-09-02 02:34:08 +03007952 free(dut->sae_commit_override);
7953 dut->sae_commit_override = NULL;
Jouni Malinen4b3769d2019-10-10 16:20:29 +03007954 wpa_command(intf, "SET sae_pmkid_in_assoc 0");
Jouni Malinen11e55212019-11-22 21:46:59 +02007955 dut->sae_pwe = SAE_PWE_DEFAULT;
Jouni Malinen68143132017-09-02 02:34:08 +03007956
Jouni Malinen134fe3c2019-06-12 04:16:49 +03007957 dut->sta_associate_wait_connect = 0;
7958 dut->server_cert_hash[0] = '\0';
Jouni Malinen37d5c692019-08-19 16:56:55 +03007959 dut->server_cert_tod = 0;
Jouni Malinen134fe3c2019-06-12 04:16:49 +03007960 dut->sta_tod_policy = 0;
7961
Jouni Malinend86e5822017-08-29 03:55:32 +03007962 dut->dpp_conf_id = -1;
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02007963 free(dut->dpp_peer_uri);
7964 dut->dpp_peer_uri = NULL;
Jouni Malinen63d50412017-11-24 11:55:38 +02007965 dut->dpp_local_bootstrap = -1;
Jouni Malinen5011fb52017-12-05 21:00:15 +02007966 wpa_command(intf, "SET dpp_config_processing 2");
Jouni Malinend86e5822017-08-29 03:55:32 +03007967
Jouni Malinenfac9cad2017-10-10 18:35:55 +03007968 wpa_command(intf, "VENDOR_ELEM_REMOVE 13 *");
7969
vamsi krishnaa2799492017-12-05 14:28:01 +05307970 if (dut->program == PROGRAM_OCE) {
Ankita Bajaja2cb5672017-10-25 16:08:28 +05307971 wpa_command(intf, "SET oce 1");
vamsi krishnaa2799492017-12-05 14:28:01 +05307972 wpa_command(intf, "SET disable_fils 0");
Ankita Bajaj1bde7942018-01-09 19:15:01 +05307973 wpa_command(intf, "FILS_HLP_REQ_FLUSH");
7974 dut->fils_hlp = 0;
7975#ifdef ANDROID
7976 hlp_thread_cleanup(dut);
7977#endif /* ANDROID */
vamsi krishnaa2799492017-12-05 14:28:01 +05307978 }
Ankita Bajaja2cb5672017-10-25 16:08:28 +05307979
Vamsi Krishnaf642d6a2020-03-27 12:33:14 +05307980 if (dut->program == PROGRAM_QM)
7981 wpa_command(intf, "SET interworking 1");
7982
Jouni Malinen8179fee2019-03-28 03:19:47 +02007983 dut->akm_values = 0;
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007984 dut->sta_ft_ds = 0;
Jouni Malinen8179fee2019-03-28 03:19:47 +02007985
Sunil Dutt076081f2018-02-05 19:45:50 +05307986#ifdef NL80211_SUPPORT
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007987 if (get_driver_type(dut) == DRIVER_WCN &&
Sunil Dutt44595082018-02-12 19:41:45 +05307988 dut->config_rsnie == 1) {
7989 dut->config_rsnie = 0;
7990 sta_config_rsnie(dut, 0);
Sunil Dutt076081f2018-02-05 19:45:50 +05307991 }
7992#endif /* NL80211_SUPPORT */
7993
Sunil Duttfebf8a82018-02-09 18:50:13 +05307994 if (dev_role && strcasecmp(dev_role, "STA-CFON") == 0) {
7995 dut->dev_role = DEVROLE_STA_CFON;
7996 return sta_cfon_reset_default(dut, conn, cmd);
7997 }
7998
Jouni Malinen439352d2018-09-13 03:42:23 +03007999 wpa_command(intf, "SET setband AUTO");
8000
Sunil Duttfebf8a82018-02-09 18:50:13 +05308001 if (dut->program != PROGRAM_VHT)
8002 return cmd_sta_p2p_reset(dut, conn, cmd);
8003
Priyadharshini Gowthamana7dfd492015-11-09 14:34:08 -08008004 return 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008005}
8006
8007
Jouni Malinenf7222712019-06-13 01:50:21 +03008008static enum sigma_cmd_result cmd_sta_get_events(struct sigma_dut *dut,
8009 struct sigma_conn *conn,
8010 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008011{
8012 const char *program = get_param(cmd, "Program");
8013
8014 if (program == NULL)
8015 return -1;
8016#ifdef ANDROID_NAN
8017 if (strcasecmp(program, "NAN") == 0)
8018 return nan_cmd_sta_get_events(dut, conn, cmd);
8019#endif /* ANDROID_NAN */
8020 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
8021 return 0;
8022}
8023
8024
Jouni Malinen82905202018-04-29 17:20:10 +03008025static int sta_exec_action_url(struct sigma_dut *dut, struct sigma_conn *conn,
8026 struct sigma_cmd *cmd)
8027{
8028 const char *url = get_param(cmd, "url");
8029 const char *method = get_param(cmd, "method");
8030 pid_t pid;
8031 int status;
8032
8033 if (!url || !method)
8034 return -1;
8035
8036 /* TODO: Add support for method,post */
8037 if (strcasecmp(method, "get") != 0) {
8038 send_resp(dut, conn, SIGMA_ERROR,
8039 "ErrorCode,Unsupported method");
8040 return 0;
8041 }
8042
8043 pid = fork();
8044 if (pid < 0) {
8045 perror("fork");
8046 return -1;
8047 }
8048
8049 if (pid == 0) {
8050 char * argv[5] = { "wget", "-O", "/dev/null",
8051 (char *) url, NULL };
8052
8053 execv("/usr/bin/wget", argv);
8054 perror("execv");
8055 exit(0);
8056 return -1;
8057 }
8058
8059 if (waitpid(pid, &status, 0) < 0) {
8060 perror("waitpid");
8061 return -1;
8062 }
8063
8064 if (WIFEXITED(status)) {
8065 const char *errmsg;
8066
8067 if (WEXITSTATUS(status) == 0)
8068 return 1;
8069 sigma_dut_print(dut, DUT_MSG_INFO, "wget exit status %d",
8070 WEXITSTATUS(status));
8071 switch (WEXITSTATUS(status)) {
8072 case 4:
8073 errmsg = "errmsg,Network failure";
8074 break;
8075 case 8:
8076 errmsg = "errmsg,Server issued an error response";
8077 break;
8078 default:
8079 errmsg = "errmsg,Unknown failure from wget";
8080 break;
8081 }
8082 send_resp(dut, conn, SIGMA_ERROR, errmsg);
8083 return 0;
8084 }
8085
8086 send_resp(dut, conn, SIGMA_ERROR, "errmsg,Unknown failure");
8087 return 0;
8088}
8089
8090
Jouni Malinenf7222712019-06-13 01:50:21 +03008091static enum sigma_cmd_result cmd_sta_exec_action(struct sigma_dut *dut,
8092 struct sigma_conn *conn,
8093 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008094{
8095 const char *program = get_param(cmd, "Prog");
8096
Jouni Malinen82905202018-04-29 17:20:10 +03008097 if (program && !get_param(cmd, "interface"))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008098 return -1;
8099#ifdef ANDROID_NAN
Jouni Malinen82905202018-04-29 17:20:10 +03008100 if (program && strcasecmp(program, "NAN") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008101 return nan_cmd_sta_exec_action(dut, conn, cmd);
8102#endif /* ANDROID_NAN */
Jouni Malinen82905202018-04-29 17:20:10 +03008103
8104 if (program && strcasecmp(program, "Loc") == 0)
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07008105 return loc_cmd_sta_exec_action(dut, conn, cmd);
Jouni Malinen82905202018-04-29 17:20:10 +03008106
8107 if (get_param(cmd, "url"))
8108 return sta_exec_action_url(dut, conn, cmd);
8109
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008110 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
8111 return 0;
8112}
8113
8114
Jouni Malinenf7222712019-06-13 01:50:21 +03008115static enum sigma_cmd_result cmd_sta_set_11n(struct sigma_dut *dut,
8116 struct sigma_conn *conn,
8117 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008118{
8119 const char *intf = get_param(cmd, "Interface");
8120 const char *val, *mcs32, *rate;
8121
8122 val = get_param(cmd, "GREENFIELD");
8123 if (val) {
8124 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
8125 /* Enable GD */
8126 send_resp(dut, conn, SIGMA_ERROR,
8127 "ErrorCode,GF not supported");
8128 return 0;
8129 }
8130 }
8131
8132 val = get_param(cmd, "SGI20");
8133 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02008134 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008135 case DRIVER_ATHEROS:
8136 ath_sta_set_sgi(dut, intf, val);
8137 break;
8138 default:
8139 send_resp(dut, conn, SIGMA_ERROR,
8140 "ErrorCode,SGI20 not supported");
8141 return 0;
8142 }
8143 }
8144
8145 mcs32 = get_param(cmd, "MCS32"); /* HT Duplicate Mode Enable/Disable */
8146 rate = get_param(cmd, "MCS_FIXEDRATE"); /* Fixed MCS rate (0..31) */
8147 if (mcs32 && rate) {
8148 /* TODO */
8149 send_resp(dut, conn, SIGMA_ERROR,
8150 "ErrorCode,MCS32,MCS_FIXEDRATE not supported");
8151 return 0;
8152 } else if (mcs32 && !rate) {
8153 /* TODO */
8154 send_resp(dut, conn, SIGMA_ERROR,
8155 "ErrorCode,MCS32 not supported");
8156 return 0;
8157 } else if (!mcs32 && rate) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02008158 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008159 case DRIVER_ATHEROS:
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -07008160 novap_reset(dut, intf, 1);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008161 ath_sta_set_11nrates(dut, intf, rate);
8162 break;
8163 default:
8164 send_resp(dut, conn, SIGMA_ERROR,
8165 "ErrorCode,MCS32_FIXEDRATE not supported");
8166 return 0;
8167 }
8168 }
8169
8170 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
8171}
8172
8173
Arif Hussain7b47d2d2018-05-09 10:44:02 -07008174static void cmd_set_max_he_mcs(struct sigma_dut *dut, const char *intf,
8175 int mcs_config)
8176{
8177#ifdef NL80211_SUPPORT
8178 int ret;
8179
8180 switch (mcs_config) {
8181 case HE_80_MCS0_7:
8182 case HE_80_MCS0_9:
8183 case HE_80_MCS0_11:
8184 ret = sta_set_he_mcs(dut, intf, mcs_config);
8185 if (ret) {
8186 sigma_dut_print(dut, DUT_MSG_ERROR,
8187 "cmd_set_max_he_mcs: Setting of MCS:%d failed, ret:%d",
8188 mcs_config, ret);
8189 }
8190 break;
8191 default:
8192 sigma_dut_print(dut, DUT_MSG_ERROR,
8193 "cmd_set_max_he_mcs: Invalid mcs %d",
8194 mcs_config);
8195 break;
8196 }
8197#else /* NL80211_SUPPORT */
8198 sigma_dut_print(dut, DUT_MSG_ERROR,
8199 "max HE MCS cannot be changed without NL80211_SUPPORT defined");
8200#endif /* NL80211_SUPPORT */
8201}
8202
8203
Arif Hussain480d5f42019-03-12 14:40:42 -07008204static int sta_twt_request(struct sigma_dut *dut, struct sigma_conn *conn,
8205 struct sigma_cmd *cmd)
8206{
8207#ifdef NL80211_SUPPORT
8208 struct nlattr *params;
8209 struct nlattr *attr;
8210 struct nlattr *attr1;
8211 struct nl_msg *msg;
8212 int ifindex, ret;
8213 const char *val;
8214 const char *intf = get_param(cmd, "Interface");
8215 int wake_interval_exp = 10, nominal_min_wake_dur = 255,
8216 wake_interval_mantissa = 512;
8217 int flow_type = 0, twt_trigger = 0, target_wake_time = 0,
8218 protection = 0;
8219
8220 ifindex = if_nametoindex(intf);
8221 if (ifindex == 0) {
8222 sigma_dut_print(dut, DUT_MSG_ERROR,
8223 "%s: Index for interface %s failed",
8224 __func__, intf);
8225 return -1;
8226 }
8227
8228 val = get_param(cmd, "FlowType");
8229 if (val) {
8230 flow_type = atoi(val);
8231 if (flow_type != 0 && flow_type != 1) {
8232 sigma_dut_print(dut, DUT_MSG_ERROR,
8233 "TWT: Invalid FlowType %d", flow_type);
8234 return -1;
8235 }
8236 }
8237
8238 val = get_param(cmd, "TWT_Trigger");
8239 if (val) {
8240 twt_trigger = atoi(val);
8241 if (twt_trigger != 0 && twt_trigger != 1) {
8242 sigma_dut_print(dut, DUT_MSG_ERROR,
8243 "TWT: Invalid TWT_Trigger %d",
8244 twt_trigger);
8245 return -1;
8246 }
8247 }
8248
8249 val = get_param(cmd, "Protection");
8250 if (val) {
8251 protection = atoi(val);
8252 if (protection != 0 && protection != 1) {
8253 sigma_dut_print(dut, DUT_MSG_ERROR,
8254 "TWT: Invalid Protection %d",
8255 protection);
8256 return -1;
8257 }
8258 }
8259
8260 val = get_param(cmd, "TargetWakeTime");
8261 if (val)
8262 target_wake_time = atoi(val);
8263
8264 val = get_param(cmd, "WakeIntervalMantissa");
8265 if (val)
8266 wake_interval_mantissa = atoi(val);
8267
8268 val = get_param(cmd, "WakeIntervalExp");
8269 if (val)
8270 wake_interval_exp = atoi(val);
8271
8272 val = get_param(cmd, "NominalMinWakeDur");
8273 if (val)
8274 nominal_min_wake_dur = atoi(val);
8275
8276 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8277 NL80211_CMD_VENDOR)) ||
8278 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
8279 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
8280 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
8281 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
8282 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8283 !(params = nla_nest_start(
8284 msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_SETUP)) ||
8285 !(attr1 = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8286 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_EXP,
8287 wake_interval_exp) ||
Arif Hussain480d5f42019-03-12 14:40:42 -07008288 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_REQ_TYPE, 1) ||
Kiran Kumar Lokere2cffae52019-09-26 18:44:15 -07008289 (twt_trigger &&
8290 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TRIGGER)) ||
Arif Hussain480d5f42019-03-12 14:40:42 -07008291 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE,
8292 flow_type) ||
Kiran Kumar Lokere2cffae52019-09-26 18:44:15 -07008293 (protection &&
8294 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_PROTECTION)) ||
Arif Hussain480d5f42019-03-12 14:40:42 -07008295 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME,
8296 target_wake_time) ||
8297 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_DURATION,
8298 nominal_min_wake_dur) ||
8299 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_MANTISSA,
8300 wake_interval_mantissa)) {
8301 sigma_dut_print(dut, DUT_MSG_ERROR,
8302 "%s: err in adding vendor_cmd and vendor_data",
8303 __func__);
8304 nlmsg_free(msg);
8305 return -1;
8306 }
8307 nla_nest_end(msg, attr1);
8308 nla_nest_end(msg, params);
8309 nla_nest_end(msg, attr);
8310
8311 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
8312 if (ret) {
8313 sigma_dut_print(dut, DUT_MSG_ERROR,
8314 "%s: err in send_and_recv_msgs, ret=%d",
8315 __func__, ret);
8316 }
8317
8318 return ret;
8319#else /* NL80211_SUPPORT */
8320 sigma_dut_print(dut, DUT_MSG_ERROR,
8321 "TWT request cannot be done without NL80211_SUPPORT defined");
8322 return -1;
8323#endif /* NL80211_SUPPORT */
8324}
8325
8326
8327static int sta_twt_teardown(struct sigma_dut *dut, struct sigma_conn *conn,
8328 struct sigma_cmd *cmd)
8329{
8330 #ifdef NL80211_SUPPORT
8331 struct nlattr *params;
8332 struct nlattr *attr;
8333 struct nlattr *attr1;
8334 int ifindex, ret;
8335 struct nl_msg *msg;
8336 const char *intf = get_param(cmd, "Interface");
8337
8338 ifindex = if_nametoindex(intf);
8339 if (ifindex == 0) {
8340 sigma_dut_print(dut, DUT_MSG_ERROR,
8341 "%s: Index for interface %s failed",
8342 __func__, intf);
8343 return -1;
8344 }
8345
8346 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8347 NL80211_CMD_VENDOR)) ||
8348 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
8349 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
8350 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
8351 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
8352 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8353 !(params = nla_nest_start(
8354 msg,
8355 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_TERMINATE)) ||
8356 !(attr1 = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8357 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE, 0)) {
8358 sigma_dut_print(dut, DUT_MSG_ERROR,
8359 "%s: err in adding vendor_cmd and vendor_data",
8360 __func__);
8361 nlmsg_free(msg);
8362 return -1;
8363 }
8364 nla_nest_end(msg, attr1);
8365 nla_nest_end(msg, params);
8366 nla_nest_end(msg, attr);
8367
8368 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
8369 if (ret) {
8370 sigma_dut_print(dut, DUT_MSG_ERROR,
8371 "%s: err in send_and_recv_msgs, ret=%d",
8372 __func__, ret);
8373 }
8374
8375 return ret;
8376#else /* NL80211_SUPPORT */
8377 sigma_dut_print(dut, DUT_MSG_ERROR,
8378 "TWT teardown cannot be done without NL80211_SUPPORT defined");
8379 return -1;
8380#endif /* NL80211_SUPPORT */
8381}
8382
8383
Kiran Kumar Lokere50eb2cd2018-12-18 18:31:28 -08008384static int sta_transmit_omi(struct sigma_dut *dut, struct sigma_conn *conn,
8385 struct sigma_cmd *cmd)
8386{
8387#ifdef NL80211_SUPPORT
8388 struct nlattr *params;
8389 struct nlattr *attr;
8390 struct nlattr *attr1;
8391 struct nl_msg *msg;
8392 int ifindex, ret;
8393 const char *val;
8394 const char *intf = get_param(cmd, "Interface");
8395 uint8_t rx_nss = 0xFF, ch_bw = 0xFF, tx_nsts = 0xFF, ulmu_dis = 0,
8396 ulmu_data_dis = 0;
8397
8398 ifindex = if_nametoindex(intf);
8399 if (ifindex == 0) {
8400 sigma_dut_print(dut, DUT_MSG_ERROR,
8401 "%s: Index for interface %s failed",
8402 __func__, intf);
8403 return -1;
8404 }
8405 val = get_param(cmd, "OMCtrl_RxNSS");
8406 if (val)
8407 rx_nss = atoi(val);
8408
8409 val = get_param(cmd, "OMCtrl_ChnlWidth");
8410 if (val)
8411 ch_bw = atoi(val);
8412
8413 val = get_param(cmd, "OMCtrl_ULMUDisable");
8414 if (val)
8415 ulmu_dis = atoi(val);
8416
8417 val = get_param(cmd, "OMCtrl_TxNSTS");
8418 if (val)
8419 tx_nsts = atoi(val);
8420
8421 val = get_param(cmd, "OMCtrl_ULMUDataDisable");
8422 if (val)
8423 ulmu_data_dis = atoi(val);
8424
8425 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8426 NL80211_CMD_VENDOR)) ||
8427 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
8428 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
8429 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
8430 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
8431 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8432 !(params = nla_nest_start(
8433 msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OMI_TX)) ||
8434 !(attr1 = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8435 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_RX_NSS, rx_nss) ||
8436 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_CH_BW, ch_bw) ||
8437 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_TX_NSTS, tx_nsts) ||
8438 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DATA_DISABLE,
8439 ulmu_data_dis) ||
8440 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DISABLE,
8441 ulmu_dis)) {
8442 sigma_dut_print(dut, DUT_MSG_ERROR,
8443 "%s: err in adding vendor_cmd and vendor_data",
8444 __func__);
8445 nlmsg_free(msg);
8446 return -1;
8447 }
8448 nla_nest_end(msg, attr1);
8449 nla_nest_end(msg, params);
8450 nla_nest_end(msg, attr);
8451
8452 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
8453 if (ret) {
8454 sigma_dut_print(dut, DUT_MSG_ERROR,
8455 "%s: err in send_and_recv_msgs, ret=%d",
8456 __func__, ret);
8457 }
8458
8459 return ret;
8460#else /* NL80211_SUPPORT */
8461 sigma_dut_print(dut, DUT_MSG_ERROR,
8462 "OMI TX cannot be processed without NL80211_SUPPORT defined");
8463 return -1;
8464#endif /* NL80211_SUPPORT */
8465}
8466
8467
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008468static int cmd_sta_set_wireless_vht(struct sigma_dut *dut,
8469 struct sigma_conn *conn,
8470 struct sigma_cmd *cmd)
8471{
8472 const char *intf = get_param(cmd, "Interface");
8473 const char *val;
Arif Hussaina37e9552018-06-20 17:05:59 -07008474 const char *program;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008475 int tkip = -1;
8476 int wep = -1;
8477
Arif Hussaina37e9552018-06-20 17:05:59 -07008478 program = get_param(cmd, "Program");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008479 val = get_param(cmd, "SGI80");
8480 if (val) {
8481 int sgi80;
8482
8483 sgi80 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008484 run_iwpriv(dut, intf, "shortgi %d", sgi80);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008485 }
8486
8487 val = get_param(cmd, "TxBF");
8488 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02008489 switch (get_driver_type(dut)) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07008490 case DRIVER_WCN:
8491 if (sta_set_tx_beamformee(dut, intf, 1)) {
8492 send_resp(dut, conn, SIGMA_ERROR,
8493 "ErrorCode,Failed to set TX beamformee enable");
8494 return 0;
8495 }
8496 break;
8497 case DRIVER_ATHEROS:
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008498 if (run_iwpriv(dut, intf, "vhtsubfee 1") < 0) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07008499 send_resp(dut, conn, SIGMA_ERROR,
8500 "ErrorCode,Setting vhtsubfee failed");
8501 return 0;
8502 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008503 if (run_iwpriv(dut, intf, "vhtsubfer 1") < 0) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07008504 send_resp(dut, conn, SIGMA_ERROR,
8505 "ErrorCode,Setting vhtsubfer failed");
8506 return 0;
8507 }
8508 break;
8509 default:
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008510 sigma_dut_print(dut, DUT_MSG_ERROR,
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07008511 "Unsupported driver type");
8512 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008513 }
8514 }
8515
8516 val = get_param(cmd, "MU_TxBF");
8517 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02008518 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008519 case DRIVER_ATHEROS:
8520 ath_sta_set_txsp_stream(dut, intf, "1SS");
8521 ath_sta_set_rxsp_stream(dut, intf, "1SS");
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008522 run_iwpriv(dut, intf, "vhtmubfee 1");
8523 run_iwpriv(dut, intf, "vhtmubfer 1");
Sunil Duttae9e5d12018-06-29 11:50:47 +05308524 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008525 case DRIVER_WCN:
8526 if (wcn_sta_set_sp_stream(dut, intf, "1SS") < 0) {
8527 send_resp(dut, conn, SIGMA_ERROR,
8528 "ErrorCode,Failed to set RX/TXSP_STREAM");
8529 return 0;
8530 }
Sunil Duttae9e5d12018-06-29 11:50:47 +05308531 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008532 default:
8533 sigma_dut_print(dut, DUT_MSG_ERROR,
8534 "Setting SP_STREAM not supported");
8535 break;
8536 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008537 }
8538
8539 val = get_param(cmd, "LDPC");
8540 if (val) {
8541 int ldpc;
8542
8543 ldpc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008544 run_iwpriv(dut, intf, "ldpc %d", ldpc);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008545 }
8546
Amarnath Hullur Subramanyam7bae60e2018-01-31 03:46:50 -08008547 val = get_param(cmd, "BCC");
8548 if (val) {
8549 int bcc;
8550
8551 bcc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
8552 /* use LDPC iwpriv itself to set bcc coding, bcc coding
8553 * is mutually exclusive to bcc */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008554 run_iwpriv(dut, intf, "ldpc %d", !bcc);
Amarnath Hullur Subramanyam7bae60e2018-01-31 03:46:50 -08008555 }
8556
Arif Hussain7b47d2d2018-05-09 10:44:02 -07008557 val = get_param(cmd, "MaxHE-MCS_1SS_RxMapLTE80");
8558 if (val && dut->sta_nss == 1)
8559 cmd_set_max_he_mcs(dut, intf, atoi(val));
8560
8561 val = get_param(cmd, "MaxHE-MCS_2SS_RxMapLTE80");
8562 if (val && dut->sta_nss == 2)
8563 cmd_set_max_he_mcs(dut, intf, atoi(val));
8564
Arif Hussainac6c5112018-05-25 17:34:00 -07008565 val = get_param(cmd, "MCS_FixedRate");
8566 if (val) {
8567#ifdef NL80211_SUPPORT
8568 int mcs, ratecode = 0;
8569 enum he_mcs_config mcs_config;
8570 int ret;
Jouni Malinenb9b671d2019-04-26 13:23:17 +03008571 char buf[60];
Arif Hussainac6c5112018-05-25 17:34:00 -07008572
8573 ratecode = (0x07 & dut->sta_nss) << 5;
8574 mcs = atoi(val);
8575 /* Add the MCS to the ratecode */
8576 if (mcs >= 0 && mcs <= 11) {
8577 ratecode += mcs;
8578 if (dut->device_type == STA_testbed &&
8579 mcs > 7 && mcs <= 11) {
8580 if (mcs <= 9)
8581 mcs_config = HE_80_MCS0_9;
8582 else
8583 mcs_config = HE_80_MCS0_11;
8584 ret = sta_set_he_mcs(dut, intf, mcs_config);
8585 if (ret) {
8586 sigma_dut_print(dut, DUT_MSG_ERROR,
8587 "MCS_FixedRate: mcs setting failed, mcs:%d, mcs_config %d, ret:%d",
8588 mcs, mcs_config, ret);
8589 }
8590 }
8591 snprintf(buf, sizeof(buf),
8592 "iwpriv %s set_11ax_rate 0x%03x",
8593 intf, ratecode);
8594 if (system(buf) != 0) {
8595 sigma_dut_print(dut, DUT_MSG_ERROR,
8596 "MCS_FixedRate: iwpriv setting of 11ax rates 0x%03x failed",
8597 ratecode);
8598 }
8599 } else {
8600 sigma_dut_print(dut, DUT_MSG_ERROR,
8601 "MCS_FixedRate: HE MCS %d not supported",
8602 mcs);
8603 }
8604#else /* NL80211_SUPPORT */
8605 sigma_dut_print(dut, DUT_MSG_ERROR,
8606 "MCS_FixedRate cannot be changed without NL80211_SUPPORT defined");
8607#endif /* NL80211_SUPPORT */
8608 }
8609
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008610 val = get_param(cmd, "opt_md_notif_ie");
8611 if (val) {
8612 char *result = NULL;
8613 char delim[] = ";";
8614 char token[30];
8615 int value, config_val = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308616 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008617
Peng Xub8fc5cc2017-05-10 17:27:28 -07008618 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308619 result = strtok_r(token, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008620
8621 /* Extract the NSS information */
8622 if (result) {
8623 value = atoi(result);
8624 switch (value) {
8625 case 1:
8626 config_val = 1;
8627 break;
8628 case 2:
8629 config_val = 3;
8630 break;
8631 case 3:
8632 config_val = 7;
8633 break;
8634 case 4:
8635 config_val = 15;
8636 break;
8637 default:
8638 config_val = 3;
8639 break;
8640 }
8641
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008642 run_iwpriv(dut, intf, "rxchainmask %d", config_val);
8643 run_iwpriv(dut, intf, "txchainmask %d", config_val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008644
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008645 }
8646
8647 /* Extract the channel width information */
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308648 result = strtok_r(NULL, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008649 if (result) {
8650 value = atoi(result);
8651 switch (value) {
8652 case 20:
8653 config_val = 0;
8654 break;
8655 case 40:
8656 config_val = 1;
8657 break;
8658 case 80:
8659 config_val = 2;
8660 break;
8661 case 160:
8662 config_val = 3;
8663 break;
8664 default:
8665 config_val = 2;
8666 break;
8667 }
8668
8669 dut->chwidth = config_val;
8670
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008671 run_iwpriv(dut, intf, "chwidth %d", config_val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008672 }
8673
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008674 run_iwpriv(dut, intf, "opmode_notify 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008675 }
8676
8677 val = get_param(cmd, "nss_mcs_cap");
8678 if (val) {
8679 int nss, mcs;
8680 char token[20];
8681 char *result = NULL;
8682 unsigned int vht_mcsmap = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308683 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008684
Peng Xub8fc5cc2017-05-10 17:27:28 -07008685 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308686 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05308687 if (!result) {
8688 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07008689 "NSS not specified");
8690 send_resp(dut, conn, SIGMA_ERROR,
8691 "errorCode,NSS not specified");
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05308692 return 0;
8693 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008694 nss = atoi(result);
8695
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008696 run_iwpriv(dut, intf, "nss %d", nss);
Arif Hussainac6c5112018-05-25 17:34:00 -07008697 dut->sta_nss = nss;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008698
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308699 result = strtok_r(NULL, ";", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008700 if (result == NULL) {
8701 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07008702 "MCS not specified");
8703 send_resp(dut, conn, SIGMA_ERROR,
8704 "errorCode,MCS not specified");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008705 return 0;
8706 }
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308707 result = strtok_r(result, "-", &saveptr);
8708 result = strtok_r(NULL, "-", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05308709 if (!result) {
8710 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07008711 "MCS not specified");
8712 send_resp(dut, conn, SIGMA_ERROR,
8713 "errorCode,MCS not specified");
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05308714 return 0;
8715 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008716 mcs = atoi(result);
8717
Arif Hussaina37e9552018-06-20 17:05:59 -07008718 if (program && strcasecmp(program, "HE") == 0) {
8719#ifdef NL80211_SUPPORT
8720 enum he_mcs_config mcs_config;
8721 int ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008722
Arif Hussaina37e9552018-06-20 17:05:59 -07008723 if (mcs >= 0 && mcs <= 7) {
8724 mcs_config = HE_80_MCS0_7;
8725 } else if (mcs > 7 && mcs <= 9) {
8726 mcs_config = HE_80_MCS0_9;
8727 } else if (mcs > 9 && mcs <= 11) {
8728 mcs_config = HE_80_MCS0_11;
8729 } else {
8730 sigma_dut_print(dut, DUT_MSG_ERROR,
8731 "nss_mcs_cap: HE: Invalid mcs: %d",
8732 mcs);
8733 send_resp(dut, conn, SIGMA_ERROR,
8734 "errorCode,Invalid MCS");
8735 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008736 }
Arif Hussaina37e9552018-06-20 17:05:59 -07008737
8738 ret = sta_set_he_mcs(dut, intf, mcs_config);
8739 if (ret) {
8740 sigma_dut_print(dut, DUT_MSG_ERROR,
8741 "nss_mcs_cap: HE: Setting of MCS failed, mcs_config: %d, ret: %d",
8742 mcs_config, ret);
8743 send_resp(dut, conn, SIGMA_ERROR,
8744 "errorCode,Failed to set MCS");
8745 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008746 }
Arif Hussaina37e9552018-06-20 17:05:59 -07008747#else /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008748 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07008749 "nss_mcs_cap: HE: MCS cannot be changed without NL80211_SUPPORT defined");
8750#endif /* NL80211_SUPPORT */
8751 } else {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008752 run_iwpriv(dut, intf, "vhtmcs %d", mcs);
Arif Hussaina37e9552018-06-20 17:05:59 -07008753
8754 switch (nss) {
8755 case 1:
8756 switch (mcs) {
8757 case 7:
8758 vht_mcsmap = 0xfffc;
8759 break;
8760 case 8:
8761 vht_mcsmap = 0xfffd;
8762 break;
8763 case 9:
8764 vht_mcsmap = 0xfffe;
8765 break;
8766 default:
8767 vht_mcsmap = 0xfffe;
8768 break;
8769 }
8770 break;
8771 case 2:
8772 switch (mcs) {
8773 case 7:
8774 vht_mcsmap = 0xfff0;
8775 break;
8776 case 8:
8777 vht_mcsmap = 0xfff5;
8778 break;
8779 case 9:
8780 vht_mcsmap = 0xfffa;
8781 break;
8782 default:
8783 vht_mcsmap = 0xfffa;
8784 break;
8785 }
8786 break;
8787 case 3:
8788 switch (mcs) {
8789 case 7:
8790 vht_mcsmap = 0xffc0;
8791 break;
8792 case 8:
8793 vht_mcsmap = 0xffd5;
8794 break;
8795 case 9:
8796 vht_mcsmap = 0xffea;
8797 break;
8798 default:
8799 vht_mcsmap = 0xffea;
8800 break;
8801 }
8802 break;
8803 default:
8804 vht_mcsmap = 0xffea;
8805 break;
8806 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008807 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008808 }
8809 }
8810
8811 /* UNSUPPORTED: val = get_param(cmd, "Tx_lgi_rate"); */
8812
8813 val = get_param(cmd, "Vht_tkip");
8814 if (val)
8815 tkip = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
8816
8817 val = get_param(cmd, "Vht_wep");
8818 if (val)
8819 wep = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
8820
8821 if (tkip != -1 || wep != -1) {
8822 if ((tkip == 1 && wep != 0) || (wep == 1 && tkip != 0)) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008823 run_iwpriv(dut, intf, "htweptkip 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008824 } else if ((tkip == 0 && wep != 1) || (wep == 0 && tkip != 1)) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008825 run_iwpriv(dut, intf, "htweptkip 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008826 } else {
8827 sigma_dut_print(dut, DUT_MSG_ERROR,
8828 "ErrorCode,mixed mode of VHT TKIP/WEP not supported");
8829 return 0;
8830 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008831 }
8832
Arif Hussain55f00da2018-07-03 08:28:26 -07008833 val = get_param(cmd, "txBandwidth");
8834 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02008835 switch (get_driver_type(dut)) {
Arif Hussain55f00da2018-07-03 08:28:26 -07008836 case DRIVER_WCN:
8837 if (wcn_sta_set_width(dut, intf, val) < 0) {
8838 send_resp(dut, conn, SIGMA_ERROR,
8839 "ErrorCode,Failed to set txBandwidth");
8840 return 0;
8841 }
8842 break;
8843 case DRIVER_ATHEROS:
8844 if (ath_set_width(dut, conn, intf, val) < 0) {
8845 send_resp(dut, conn, SIGMA_ERROR,
8846 "ErrorCode,Failed to set txBandwidth");
8847 return 0;
8848 }
8849 break;
8850 default:
8851 sigma_dut_print(dut, DUT_MSG_ERROR,
8852 "Setting txBandwidth not supported");
8853 break;
8854 }
8855 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008856
Arif Hussain9765f7d2018-07-03 08:28:26 -07008857 val = get_param(cmd, "BeamformeeSTS");
8858 if (val) {
Kiran Kumar Lokerebc89d432018-07-10 12:20:13 -07008859 if (sta_set_tx_beamformee(dut, intf, 1)) {
8860 send_resp(dut, conn, SIGMA_ERROR,
8861 "ErrorCode,Failed to set TX beamformee enable");
8862 return 0;
8863 }
8864
Arif Hussain9765f7d2018-07-03 08:28:26 -07008865 if (sta_set_beamformee_sts(dut, intf, atoi(val))) {
8866 send_resp(dut, conn, SIGMA_ERROR,
8867 "ErrorCode,Failed to set BeamformeeSTS");
8868 return 0;
8869 }
8870 }
8871
Arif Hussain68d23f52018-07-11 13:39:08 -07008872 val = get_param(cmd, "Trig_MAC_Padding_Dur");
8873 if (val) {
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07008874#ifdef NL80211_SUPPORT
8875 enum qca_wlan_he_mac_padding_dur set_val;
8876
8877 switch (atoi(val)) {
8878 case 16:
8879 set_val = QCA_WLAN_HE_16US_OF_PROCESS_TIME;
8880 break;
8881 case 8:
8882 set_val = QCA_WLAN_HE_8US_OF_PROCESS_TIME;
8883 break;
8884 default:
8885 set_val = QCA_WLAN_HE_NO_ADDITIONAL_PROCESS_TIME;
8886 break;
8887 }
8888 if (sta_set_mac_padding_duration(dut, intf, set_val)) {
Arif Hussain68d23f52018-07-11 13:39:08 -07008889 send_resp(dut, conn, SIGMA_ERROR,
8890 "ErrorCode,Failed to set MAC padding duration");
8891 return 0;
8892 }
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07008893#else /* NL80211_SUPPORT */
8894 sigma_dut_print(dut, DUT_MSG_ERROR,
8895 "MAC padding duration cannot be changed without NL80211_SUPPORT defined");
8896#endif /* NL80211_SUPPORT */
Arif Hussain68d23f52018-07-11 13:39:08 -07008897 }
8898
Arif Hussain480d5f42019-03-12 14:40:42 -07008899 val = get_param(cmd, "TWT_ReqSupport");
8900 if (val) {
8901 int set_val;
8902
8903 if (strcasecmp(val, "Enable") == 0) {
8904 set_val = 1;
8905 } else if (strcasecmp(val, "Disable") == 0) {
8906 set_val = 0;
8907 } else {
8908 send_resp(dut, conn, SIGMA_ERROR,
8909 "ErrorCode,Invalid TWT_ReqSupport");
8910 return STATUS_SENT;
8911 }
8912
8913 if (sta_set_twt_req_support(dut, intf, set_val)) {
8914 sigma_dut_print(dut, DUT_MSG_ERROR,
8915 "Failed to set TWT req support %d",
8916 set_val);
8917 send_resp(dut, conn, SIGMA_ERROR,
8918 "ErrorCode,Failed to set TWT_ReqSupport");
8919 return STATUS_SENT;
8920 }
8921 }
8922
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07008923 val = get_param(cmd, "MU_EDCA");
8924 if (val && (strcasecmp(val, "Override") == 0)) {
8925 if (sta_set_mu_edca_override(dut, intf, 1)) {
8926 send_resp(dut, conn, SIGMA_ERROR,
8927 "ErrorCode,Failed to set MU EDCA override");
8928 return 0;
8929 }
8930 }
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -07008931
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07008932 val = get_param(cmd, "OMControl");
8933 if (val) {
8934 int set_val = 1;
8935
8936 if (strcasecmp(val, "Enable") == 0)
8937 set_val = 1;
8938 else if (strcasecmp(val, "Disable") == 0)
8939 set_val = 0;
8940
8941 if (sta_set_om_ctrl_supp(dut, intf, set_val)) {
8942 send_resp(dut, conn, SIGMA_ERROR,
8943 "ErrorCode,Failed to set OM ctrl supp");
8944 return 0;
8945 }
8946 }
8947
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -07008948 val = get_param(cmd, "ADDBAResp_BufSize");
8949 if (val) {
8950 int buf_size;
8951
8952 if (strcasecmp(val, "gt64") == 0)
8953 buf_size = 256;
8954 else
8955 buf_size = 64;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02008956 if (get_driver_type(dut) == DRIVER_WCN &&
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -07008957 sta_set_addba_buf_size(dut, intf, buf_size)) {
8958 send_resp(dut, conn, SIGMA_ERROR,
8959 "ErrorCode,set addbaresp_buff_size failed");
8960 return 0;
8961 }
8962 }
8963
8964 val = get_param(cmd, "ADDBAReq_BufSize");
8965 if (val) {
8966 int buf_size;
8967
8968 if (strcasecmp(val, "gt64") == 0)
8969 buf_size = 256;
8970 else
8971 buf_size = 64;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02008972 if (get_driver_type(dut) == DRIVER_WCN &&
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -07008973 sta_set_addba_buf_size(dut, intf, buf_size)) {
8974 send_resp(dut, conn, SIGMA_ERROR,
8975 "ErrorCode,set addbareq_buff_size failed");
8976 return 0;
8977 }
8978 }
8979
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008980 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
8981}
8982
8983
8984static int sta_set_wireless_60g(struct sigma_dut *dut,
8985 struct sigma_conn *conn,
8986 struct sigma_cmd *cmd)
8987{
8988 const char *dev_role = get_param(cmd, "DevRole");
8989
8990 if (!dev_role) {
8991 send_resp(dut, conn, SIGMA_INVALID,
8992 "ErrorCode,DevRole not specified");
8993 return 0;
8994 }
8995
8996 if (strcasecmp(dev_role, "PCP") == 0)
8997 return sta_set_60g_pcp(dut, conn, cmd);
8998 if (strcasecmp(dev_role, "STA") == 0)
8999 return sta_set_60g_sta(dut, conn, cmd);
9000 send_resp(dut, conn, SIGMA_INVALID,
9001 "ErrorCode,DevRole not supported");
9002 return 0;
9003}
9004
9005
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05309006static int sta_set_wireless_oce(struct sigma_dut *dut, struct sigma_conn *conn,
9007 struct sigma_cmd *cmd)
9008{
9009 int status;
9010 const char *intf = get_param(cmd, "Interface");
9011 const char *val = get_param(cmd, "DevRole");
9012
9013 if (val && strcasecmp(val, "STA-CFON") == 0) {
9014 status = sta_cfon_set_wireless(dut, conn, cmd);
9015 if (status)
9016 return status;
9017 }
9018 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
9019}
9020
9021
Jouni Malinenf7222712019-06-13 01:50:21 +03009022static enum sigma_cmd_result cmd_sta_set_wireless(struct sigma_dut *dut,
9023 struct sigma_conn *conn,
9024 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009025{
9026 const char *val;
9027
9028 val = get_param(cmd, "Program");
9029 if (val) {
9030 if (strcasecmp(val, "11n") == 0)
9031 return cmd_sta_set_11n(dut, conn, cmd);
Amarnath Hullur Subramanyam4f860292018-01-31 03:49:35 -08009032 if (strcasecmp(val, "VHT") == 0 || strcasecmp(val, "HE") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009033 return cmd_sta_set_wireless_vht(dut, conn, cmd);
9034 if (strcasecmp(val, "60ghz") == 0)
9035 return sta_set_wireless_60g(dut, conn, cmd);
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05309036 if (strcasecmp(val, "OCE") == 0)
9037 return sta_set_wireless_oce(dut, conn, cmd);
Alexei Avshalom Lazar66bb9972018-12-18 16:01:43 +02009038 /* sta_set_wireless in WPS program is only used for 60G */
9039 if (is_60g_sigma_dut(dut))
9040 return sta_set_wireless_60g(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009041 send_resp(dut, conn, SIGMA_ERROR,
9042 "ErrorCode,Program value not supported");
9043 } else {
9044 send_resp(dut, conn, SIGMA_ERROR,
9045 "ErrorCode,Program argument not available");
9046 }
9047
9048 return 0;
9049}
9050
9051
9052static void ath_sta_inject_frame(struct sigma_dut *dut, const char *intf,
9053 int tid)
9054{
9055 char buf[100];
9056 int tid_to_dscp [] = { 0x00, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0 };
9057
Pradeep Reddy POTTETId31d1322016-10-13 17:22:03 +05309058 if (tid < 0 ||
9059 tid >= (int) (sizeof(tid_to_dscp) / sizeof(tid_to_dscp[0]))) {
9060 sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported TID: %d", tid);
9061 return;
9062 }
9063
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009064 /*
9065 * Two ways to ensure that addba request with a
9066 * non zero TID could be sent out. EV 117296
9067 */
9068 snprintf(buf, sizeof(buf),
9069 "ping -c 8 -Q %d `arp -a | grep wlan0 | awk '{print $2}' | tr -d '()'`",
9070 tid);
9071 if (system(buf) != 0) {
9072 sigma_dut_print(dut, DUT_MSG_ERROR,
9073 "Ping did not send out");
9074 }
9075
9076 snprintf(buf, sizeof(buf),
9077 "iwconfig %s | grep Access | awk '{print $6}' > %s",
9078 intf, VI_QOS_TMP_FILE);
9079 if (system(buf) != 0)
9080 return;
9081
9082 snprintf(buf, sizeof(buf),
9083 "ifconfig %s | grep HWaddr | cut -b 39-56 >> %s",
9084 intf, VI_QOS_TMP_FILE);
9085 if (system(buf) != 0)
9086 sigma_dut_print(dut, DUT_MSG_ERROR, "HWaddr matching failed");
9087
9088 snprintf(buf,sizeof(buf), "sed -n '3,$p' %s >> %s",
9089 VI_QOS_REFFILE, VI_QOS_TMP_FILE);
9090 if (system(buf) != 0) {
9091 sigma_dut_print(dut, DUT_MSG_ERROR,
9092 "VI_QOS_TEMP_FILE generation error failed");
9093 }
9094 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
9095 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
9096 if (system(buf) != 0) {
9097 sigma_dut_print(dut, DUT_MSG_ERROR,
9098 "VI_QOS_FILE generation failed");
9099 }
9100
9101 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
9102 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
9103 if (system(buf) != 0) {
9104 sigma_dut_print(dut, DUT_MSG_ERROR,
9105 "VI_QOS_FILE generation failed");
9106 }
9107
9108 snprintf(buf, sizeof(buf), "ethinject %s %s", intf, VI_QOS_FILE);
9109 if (system(buf) != 0) {
9110 }
9111}
9112
9113
9114static int ath_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
9115 struct sigma_cmd *cmd)
9116{
9117 const char *intf = get_param(cmd, "Interface");
9118 const char *val;
9119 int tid = 0;
9120 char buf[100];
9121
9122 val = get_param(cmd, "TID");
9123 if (val) {
9124 tid = atoi(val);
9125 if (tid)
9126 ath_sta_inject_frame(dut, intf, tid);
9127 }
9128
9129 /* Command sequence for ADDBA request on Peregrine based devices */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07009130 run_iwpriv(dut, intf, "setaddbaoper 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009131
9132 snprintf(buf, sizeof(buf), "wifitool %s senddelba 1 %d 1 4", intf, tid);
9133 if (system(buf) != 0) {
9134 sigma_dut_print(dut, DUT_MSG_ERROR,
9135 "wifitool senddelba failed");
9136 }
9137
9138 snprintf(buf, sizeof(buf), "wifitool %s sendaddba 1 %d 64", intf, tid);
9139 if (system(buf) != 0) {
9140 sigma_dut_print(dut, DUT_MSG_ERROR,
9141 "wifitool sendaddba failed");
9142 }
9143
9144 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
9145
9146 return 1;
9147}
9148
9149
Lior David9981b512017-01-20 13:16:40 +02009150#ifdef __linux__
9151
9152static int wil6210_send_addba(struct sigma_dut *dut, const char *dest_mac,
9153 int agg_size)
9154{
9155 char dir[128], buf[128];
9156 FILE *f;
9157 regex_t re;
9158 regmatch_t m[2];
Jouni Malinen3aa72862019-05-29 23:14:51 +03009159 int rc, ret = -1, vring_id, found, res;
Lior David9981b512017-01-20 13:16:40 +02009160
9161 if (wil6210_get_debugfs_dir(dut, dir, sizeof(dir))) {
9162 sigma_dut_print(dut, DUT_MSG_ERROR,
9163 "failed to get wil6210 debugfs dir");
9164 return -1;
9165 }
9166
Jouni Malinen3aa72862019-05-29 23:14:51 +03009167 res = snprintf(buf, sizeof(buf), "%s/vrings", dir);
9168 if (res < 0 || res >= sizeof(buf))
9169 return -1;
Lior David9981b512017-01-20 13:16:40 +02009170 f = fopen(buf, "r");
9171 if (!f) {
9172 sigma_dut_print(dut, DUT_MSG_ERROR, "failed to open: %s", buf);
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +02009173 /* newer wil6210 driver renamed file to "rings" */
Jouni Malinen3aa72862019-05-29 23:14:51 +03009174 res = snprintf(buf, sizeof(buf), "%s/rings", dir);
9175 if (res < 0 || res >= sizeof(buf))
9176 return -1;
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +02009177 f = fopen(buf, "r");
9178 if (!f) {
9179 sigma_dut_print(dut, DUT_MSG_ERROR,
9180 "failed to open: %s", buf);
9181 return -1;
9182 }
Lior David9981b512017-01-20 13:16:40 +02009183 }
9184
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +02009185 /* can be either VRING tx... or RING... */
9186 if (regcomp(&re, "RING tx_[ \t]*([0-9]+)", REG_EXTENDED)) {
Lior David9981b512017-01-20 13:16:40 +02009187 sigma_dut_print(dut, DUT_MSG_ERROR, "regcomp failed");
9188 goto out;
9189 }
9190
9191 /* find TX VRING for the mac address */
9192 found = 0;
9193 while (fgets(buf, sizeof(buf), f)) {
9194 if (strcasestr(buf, dest_mac)) {
9195 found = 1;
9196 break;
9197 }
9198 }
9199
9200 if (!found) {
9201 sigma_dut_print(dut, DUT_MSG_ERROR,
9202 "no TX VRING for %s", dest_mac);
9203 goto out;
9204 }
9205
9206 /* extract VRING ID, "VRING tx_<id> = {" */
9207 if (!fgets(buf, sizeof(buf), f)) {
9208 sigma_dut_print(dut, DUT_MSG_ERROR,
9209 "no VRING start line for %s", dest_mac);
9210 goto out;
9211 }
9212
9213 rc = regexec(&re, buf, 2, m, 0);
9214 regfree(&re);
9215 if (rc || m[1].rm_so < 0) {
9216 sigma_dut_print(dut, DUT_MSG_ERROR,
9217 "no VRING TX ID for %s", dest_mac);
9218 goto out;
9219 }
9220 buf[m[1].rm_eo] = 0;
9221 vring_id = atoi(&buf[m[1].rm_so]);
9222
9223 /* send the addba command */
9224 fclose(f);
Jouni Malinen3aa72862019-05-29 23:14:51 +03009225 res = snprintf(buf, sizeof(buf), "%s/back", dir);
9226 if (res < 0 || res >= sizeof(buf))
9227 return -1;
Lior David9981b512017-01-20 13:16:40 +02009228 f = fopen(buf, "w");
9229 if (!f) {
9230 sigma_dut_print(dut, DUT_MSG_ERROR,
9231 "failed to open: %s", buf);
9232 return -1;
9233 }
9234
9235 fprintf(f, "add %d %d\n", vring_id, agg_size);
9236
9237 ret = 0;
9238
9239out:
9240 fclose(f);
9241
9242 return ret;
9243}
9244
9245
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +02009246int send_addba_60g(struct sigma_dut *dut, struct sigma_conn *conn,
9247 struct sigma_cmd *cmd, const char *mac_param)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009248{
9249 const char *val;
9250 int tid = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009251
9252 val = get_param(cmd, "TID");
9253 if (val) {
9254 tid = atoi(val);
9255 if (tid != 0) {
9256 sigma_dut_print(dut, DUT_MSG_ERROR,
9257 "Ignore TID %d for send_addba use TID 0 for 60g since only 0 required on TX",
9258 tid);
9259 }
9260 }
9261
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +02009262 val = get_param(cmd, mac_param);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009263 if (!val) {
9264 sigma_dut_print(dut, DUT_MSG_ERROR,
9265 "Currently not supporting addba for 60G without Dest_mac");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02009266 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009267 }
9268
Lior David9981b512017-01-20 13:16:40 +02009269 if (wil6210_send_addba(dut, val, dut->back_rcv_buf))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009270 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009271
9272 return 1;
9273}
9274
Lior David9981b512017-01-20 13:16:40 +02009275#endif /* __linux__ */
9276
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009277
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009278static int wcn_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
9279 struct sigma_cmd *cmd)
9280{
9281#ifdef NL80211_SUPPORT
9282 const char *intf = get_param(cmd, "Interface");
9283 const char *val;
9284 int tid = -1;
9285 int bufsize = 64;
9286 struct nl_msg *msg;
9287 int ret = 0;
9288 struct nlattr *params;
9289 int ifindex;
9290
9291 val = get_param(cmd, "TID");
9292 if (val)
9293 tid = atoi(val);
9294
9295 if (tid == -1) {
9296 send_resp(dut, conn, SIGMA_ERROR,
9297 "ErrorCode,sta_send_addba tid invalid");
9298 return 0;
9299 }
9300
9301 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
9302
9303 ifindex = if_nametoindex(intf);
9304 if (ifindex == 0) {
9305 sigma_dut_print(dut, DUT_MSG_ERROR,
9306 "%s: Index for interface %s failed",
9307 __func__, intf);
9308 send_resp(dut, conn, SIGMA_ERROR,
9309 "ErrorCode,sta_send_addba interface invalid");
9310 return 0;
9311 }
9312
9313 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
9314 NL80211_CMD_VENDOR)) ||
9315 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
9316 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
9317 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
9318 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
9319 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
9320 nla_put_u8(msg,
9321 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADD_DEL_BA_SESSION,
9322 QCA_WLAN_ADD_BA) ||
9323 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BA_TID,
9324 tid) ||
Kiran Kumar Lokere26e27582018-08-01 16:18:34 -07009325 nla_put_u16(msg,
9326 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE,
9327 bufsize)) {
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009328 sigma_dut_print(dut, DUT_MSG_ERROR,
9329 "%s: err in adding vendor_cmd and vendor_data",
9330 __func__);
9331 nlmsg_free(msg);
9332 send_resp(dut, conn, SIGMA_ERROR,
9333 "ErrorCode,sta_send_addba err in adding vendor_cmd and vendor_data");
9334 return 0;
9335 }
9336 nla_nest_end(msg, params);
9337
9338 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
9339 if (ret) {
9340 sigma_dut_print(dut, DUT_MSG_ERROR,
9341 "%s: err in send_and_recv_msgs, ret=%d",
9342 __func__, ret);
Sunil Dutt30605592018-05-04 20:35:50 +05309343 if (ret == -EOPNOTSUPP)
9344 return 1;
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009345 send_resp(dut, conn, SIGMA_ERROR,
9346 "ErrorCode,sta_send_addba err in send_and_recv_msgs");
9347 return 0;
9348 }
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009349#else /* NL80211_SUPPORT */
9350 sigma_dut_print(dut, DUT_MSG_ERROR,
9351 "sta_send_addba not supported without NL80211_SUPPORT defined");
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009352#endif /* NL80211_SUPPORT */
Sunil Dutt30605592018-05-04 20:35:50 +05309353
9354 return 1;
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009355}
9356
9357
Jouni Malinenf7222712019-06-13 01:50:21 +03009358static enum sigma_cmd_result cmd_sta_send_addba(struct sigma_dut *dut,
9359 struct sigma_conn *conn,
9360 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009361{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009362 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009363 case DRIVER_ATHEROS:
9364 return ath_sta_send_addba(dut, conn, cmd);
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009365 case DRIVER_WCN:
9366 return wcn_sta_send_addba(dut, conn, cmd);
Lior David9981b512017-01-20 13:16:40 +02009367#ifdef __linux__
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009368 case DRIVER_WIL6210:
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +02009369 return send_addba_60g(dut, conn, cmd, "Dest_mac");
Lior David9981b512017-01-20 13:16:40 +02009370#endif /* __linux__ */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009371 default:
9372 /*
9373 * There is no driver specific implementation for other drivers.
9374 * Ignore the command and report COMPLETE since the following
9375 * throughput test operation will end up sending ADDBA anyway.
9376 */
9377 return 1;
9378 }
9379}
9380
9381
9382int inject_eth_frame(int s, const void *data, size_t len,
9383 unsigned short ethtype, char *dst, char *src)
9384{
9385 struct iovec iov[4] = {
9386 {
9387 .iov_base = dst,
9388 .iov_len = ETH_ALEN,
9389 },
9390 {
9391 .iov_base = src,
9392 .iov_len = ETH_ALEN,
9393 },
9394 {
9395 .iov_base = &ethtype,
9396 .iov_len = sizeof(unsigned short),
9397 },
9398 {
9399 .iov_base = (void *) data,
9400 .iov_len = len,
9401 }
9402 };
9403 struct msghdr msg = {
9404 .msg_name = NULL,
9405 .msg_namelen = 0,
9406 .msg_iov = iov,
9407 .msg_iovlen = 4,
9408 .msg_control = NULL,
9409 .msg_controllen = 0,
9410 .msg_flags = 0,
9411 };
9412
9413 return sendmsg(s, &msg, 0);
9414}
9415
9416#if defined(__linux__) || defined(__QNXNTO__)
9417
9418int inject_frame(int s, const void *data, size_t len, int encrypt)
9419{
9420#define IEEE80211_RADIOTAP_F_WEP 0x04
9421#define IEEE80211_RADIOTAP_F_FRAG 0x08
9422 unsigned char rtap_hdr[] = {
9423 0x00, 0x00, /* radiotap version */
9424 0x0e, 0x00, /* radiotap length */
9425 0x02, 0xc0, 0x00, 0x00, /* bmap: flags, tx and rx flags */
9426 IEEE80211_RADIOTAP_F_FRAG, /* F_FRAG (fragment if required) */
9427 0x00, /* padding */
9428 0x00, 0x00, /* RX and TX flags to indicate that */
9429 0x00, 0x00, /* this is the injected frame directly */
9430 };
9431 struct iovec iov[2] = {
9432 {
9433 .iov_base = &rtap_hdr,
9434 .iov_len = sizeof(rtap_hdr),
9435 },
9436 {
9437 .iov_base = (void *) data,
9438 .iov_len = len,
9439 }
9440 };
9441 struct msghdr msg = {
9442 .msg_name = NULL,
9443 .msg_namelen = 0,
9444 .msg_iov = iov,
9445 .msg_iovlen = 2,
9446 .msg_control = NULL,
9447 .msg_controllen = 0,
9448 .msg_flags = 0,
9449 };
9450
9451 if (encrypt)
9452 rtap_hdr[8] |= IEEE80211_RADIOTAP_F_WEP;
9453
9454 return sendmsg(s, &msg, 0);
9455}
9456
9457
9458int open_monitor(const char *ifname)
9459{
9460#ifdef __QNXNTO__
9461 struct sockaddr_dl ll;
9462 int s;
9463
9464 memset(&ll, 0, sizeof(ll));
9465 ll.sdl_family = AF_LINK;
9466 ll.sdl_index = if_nametoindex(ifname);
9467 if (ll.sdl_index == 0) {
9468 perror("if_nametoindex");
9469 return -1;
9470 }
9471 s = socket(PF_INET, SOCK_RAW, 0);
9472#else /* __QNXNTO__ */
9473 struct sockaddr_ll ll;
9474 int s;
9475
9476 memset(&ll, 0, sizeof(ll));
9477 ll.sll_family = AF_PACKET;
9478 ll.sll_ifindex = if_nametoindex(ifname);
9479 if (ll.sll_ifindex == 0) {
9480 perror("if_nametoindex");
9481 return -1;
9482 }
9483 s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
9484#endif /* __QNXNTO__ */
9485 if (s < 0) {
9486 perror("socket[PF_PACKET,SOCK_RAW]");
9487 return -1;
9488 }
9489
9490 if (bind(s, (struct sockaddr *) &ll, sizeof(ll)) < 0) {
9491 perror("monitor socket bind");
9492 close(s);
9493 return -1;
9494 }
9495
9496 return s;
9497}
9498
9499
9500static int hex2num(char c)
9501{
9502 if (c >= '0' && c <= '9')
9503 return c - '0';
9504 if (c >= 'a' && c <= 'f')
9505 return c - 'a' + 10;
9506 if (c >= 'A' && c <= 'F')
9507 return c - 'A' + 10;
9508 return -1;
9509}
9510
9511
9512int hwaddr_aton(const char *txt, unsigned char *addr)
9513{
9514 int i;
9515
9516 for (i = 0; i < 6; i++) {
9517 int a, b;
9518
9519 a = hex2num(*txt++);
9520 if (a < 0)
9521 return -1;
9522 b = hex2num(*txt++);
9523 if (b < 0)
9524 return -1;
9525 *addr++ = (a << 4) | b;
9526 if (i < 5 && *txt++ != ':')
9527 return -1;
9528 }
9529
9530 return 0;
9531}
9532
9533#endif /* defined(__linux__) || defined(__QNXNTO__) */
9534
9535enum send_frame_type {
9536 DISASSOC, DEAUTH, SAQUERY, AUTH, ASSOCREQ, REASSOCREQ, DLS_REQ
9537};
9538enum send_frame_protection {
9539 CORRECT_KEY, INCORRECT_KEY, UNPROTECTED
9540};
9541
9542
9543static int sta_inject_frame(struct sigma_dut *dut, struct sigma_conn *conn,
9544 enum send_frame_type frame,
9545 enum send_frame_protection protected,
9546 const char *dest)
9547{
9548#ifdef __linux__
9549 unsigned char buf[1000], *pos;
9550 int s, res;
9551 char bssid[20], addr[20];
9552 char result[32], ssid[100];
9553 size_t ssid_len;
9554
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009555 if (get_wpa_status(get_station_ifname(dut), "wpa_state", result,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009556 sizeof(result)) < 0 ||
9557 strncmp(result, "COMPLETED", 9) != 0) {
9558 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Not connected");
9559 return 0;
9560 }
9561
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009562 if (get_wpa_status(get_station_ifname(dut), "bssid",
9563 bssid, sizeof(bssid)) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009564 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
9565 "current BSSID");
9566 return 0;
9567 }
9568
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009569 if (get_wpa_status(get_station_ifname(dut), "address",
9570 addr, sizeof(addr)) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009571 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
9572 "own MAC address");
9573 return 0;
9574 }
9575
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009576 if (get_wpa_status(get_station_ifname(dut), "ssid", ssid, sizeof(ssid))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009577 < 0) {
9578 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
9579 "current SSID");
9580 return 0;
9581 }
9582 ssid_len = strlen(ssid);
9583
9584 pos = buf;
9585
9586 /* Frame Control */
9587 switch (frame) {
9588 case DISASSOC:
9589 *pos++ = 0xa0;
9590 break;
9591 case DEAUTH:
9592 *pos++ = 0xc0;
9593 break;
9594 case SAQUERY:
9595 *pos++ = 0xd0;
9596 break;
9597 case AUTH:
9598 *pos++ = 0xb0;
9599 break;
9600 case ASSOCREQ:
9601 *pos++ = 0x00;
9602 break;
9603 case REASSOCREQ:
9604 *pos++ = 0x20;
9605 break;
9606 case DLS_REQ:
9607 *pos++ = 0xd0;
9608 break;
9609 }
9610
9611 if (protected == INCORRECT_KEY)
9612 *pos++ = 0x40; /* Set Protected field to 1 */
9613 else
9614 *pos++ = 0x00;
9615
9616 /* Duration */
9617 *pos++ = 0x00;
9618 *pos++ = 0x00;
9619
9620 /* addr1 = DA (current AP) */
9621 hwaddr_aton(bssid, pos);
9622 pos += 6;
9623 /* addr2 = SA (own address) */
9624 hwaddr_aton(addr, pos);
9625 pos += 6;
9626 /* addr3 = BSSID (current AP) */
9627 hwaddr_aton(bssid, pos);
9628 pos += 6;
9629
9630 /* Seq# (to be filled by driver/mac80211) */
9631 *pos++ = 0x00;
9632 *pos++ = 0x00;
9633
9634 if (protected == INCORRECT_KEY) {
9635 /* CCMP parameters */
9636 memcpy(pos, "\x61\x01\x00\x20\x00\x10\x00\x00", 8);
9637 pos += 8;
9638 }
9639
9640 if (protected == INCORRECT_KEY) {
9641 switch (frame) {
9642 case DEAUTH:
9643 /* Reason code (encrypted) */
9644 memcpy(pos, "\xa7\x39", 2);
9645 pos += 2;
9646 break;
9647 case DISASSOC:
9648 /* Reason code (encrypted) */
9649 memcpy(pos, "\xa7\x39", 2);
9650 pos += 2;
9651 break;
9652 case SAQUERY:
9653 /* Category|Action|TransID (encrypted) */
9654 memcpy(pos, "\x6f\xbd\xe9\x4d", 4);
9655 pos += 4;
9656 break;
9657 default:
9658 return -1;
9659 }
9660
9661 /* CCMP MIC */
9662 memcpy(pos, "\xc8\xd8\x3b\x06\x5d\xb7\x25\x68", 8);
9663 pos += 8;
9664 } else {
9665 switch (frame) {
9666 case DEAUTH:
9667 /* reason code = 8 */
9668 *pos++ = 0x08;
9669 *pos++ = 0x00;
9670 break;
9671 case DISASSOC:
9672 /* reason code = 8 */
9673 *pos++ = 0x08;
9674 *pos++ = 0x00;
9675 break;
9676 case SAQUERY:
9677 /* Category - SA Query */
9678 *pos++ = 0x08;
9679 /* SA query Action - Request */
9680 *pos++ = 0x00;
9681 /* Transaction ID */
9682 *pos++ = 0x12;
9683 *pos++ = 0x34;
9684 break;
9685 case AUTH:
9686 /* Auth Alg (Open) */
9687 *pos++ = 0x00;
9688 *pos++ = 0x00;
9689 /* Seq# */
9690 *pos++ = 0x01;
9691 *pos++ = 0x00;
9692 /* Status code */
9693 *pos++ = 0x00;
9694 *pos++ = 0x00;
9695 break;
9696 case ASSOCREQ:
9697 /* Capability Information */
9698 *pos++ = 0x31;
9699 *pos++ = 0x04;
9700 /* Listen Interval */
9701 *pos++ = 0x0a;
9702 *pos++ = 0x00;
9703 /* SSID */
9704 *pos++ = 0x00;
9705 *pos++ = ssid_len;
9706 memcpy(pos, ssid, ssid_len);
9707 pos += ssid_len;
9708 /* Supported Rates */
9709 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
9710 10);
9711 pos += 10;
9712 /* Extended Supported Rates */
9713 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
9714 pos += 6;
9715 /* RSN */
9716 memcpy(pos, "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00"
9717 "\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x02\xc0"
9718 "\x00\x00\x00\x00\x0f\xac\x06", 28);
9719 pos += 28;
9720 break;
9721 case REASSOCREQ:
9722 /* Capability Information */
9723 *pos++ = 0x31;
9724 *pos++ = 0x04;
9725 /* Listen Interval */
9726 *pos++ = 0x0a;
9727 *pos++ = 0x00;
9728 /* Current AP */
9729 hwaddr_aton(bssid, pos);
9730 pos += 6;
9731 /* SSID */
9732 *pos++ = 0x00;
9733 *pos++ = ssid_len;
9734 memcpy(pos, ssid, ssid_len);
9735 pos += ssid_len;
9736 /* Supported Rates */
9737 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
9738 10);
9739 pos += 10;
9740 /* Extended Supported Rates */
9741 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
9742 pos += 6;
9743 /* RSN */
9744 memcpy(pos, "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00"
9745 "\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x02\xc0"
9746 "\x00\x00\x00\x00\x0f\xac\x06", 28);
9747 pos += 28;
9748 break;
9749 case DLS_REQ:
9750 /* Category - DLS */
9751 *pos++ = 0x02;
9752 /* DLS Action - Request */
9753 *pos++ = 0x00;
9754 /* Destination MACAddress */
9755 if (dest)
9756 hwaddr_aton(dest, pos);
9757 else
9758 memset(pos, 0, 6);
9759 pos += 6;
9760 /* Source MACAddress */
9761 hwaddr_aton(addr, pos);
9762 pos += 6;
9763 /* Capability Information */
9764 *pos++ = 0x10; /* Privacy */
9765 *pos++ = 0x06; /* QoS */
9766 /* DLS Timeout Value */
9767 *pos++ = 0x00;
9768 *pos++ = 0x01;
9769 /* Supported rates */
9770 *pos++ = 0x01;
9771 *pos++ = 0x08;
9772 *pos++ = 0x0c; /* 6 Mbps */
9773 *pos++ = 0x12; /* 9 Mbps */
9774 *pos++ = 0x18; /* 12 Mbps */
9775 *pos++ = 0x24; /* 18 Mbps */
9776 *pos++ = 0x30; /* 24 Mbps */
9777 *pos++ = 0x48; /* 36 Mbps */
9778 *pos++ = 0x60; /* 48 Mbps */
9779 *pos++ = 0x6c; /* 54 Mbps */
9780 /* TODO: Extended Supported Rates */
9781 /* TODO: HT Capabilities */
9782 break;
9783 }
9784 }
9785
9786 s = open_monitor("sigmadut");
9787 if (s < 0) {
9788 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
9789 "monitor socket");
9790 return 0;
9791 }
9792
9793 res = inject_frame(s, buf, pos - buf, protected == CORRECT_KEY);
9794 if (res < 0) {
9795 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
9796 "inject frame");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05309797 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009798 return 0;
9799 }
9800 if (res < pos - buf) {
9801 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Only partial "
9802 "frame sent");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05309803 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009804 return 0;
9805 }
9806
9807 close(s);
9808
9809 return 1;
9810#else /* __linux__ */
9811 send_resp(dut, conn, SIGMA_ERROR, "errorCode,sta_send_frame not "
9812 "yet supported");
9813 return 0;
9814#endif /* __linux__ */
9815}
9816
9817
9818static int cmd_sta_send_frame_tdls(struct sigma_dut *dut,
9819 struct sigma_conn *conn,
9820 struct sigma_cmd *cmd)
9821{
9822 const char *intf = get_param(cmd, "Interface");
9823 const char *sta, *val;
9824 unsigned char addr[ETH_ALEN];
9825 char buf[100];
9826
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +03009827 if (!intf)
9828 return -1;
9829
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009830 sta = get_param(cmd, "peer");
9831 if (sta == NULL)
9832 sta = get_param(cmd, "station");
9833 if (sta == NULL) {
9834 send_resp(dut, conn, SIGMA_ERROR,
9835 "ErrorCode,Missing peer address");
9836 return 0;
9837 }
9838 if (hwaddr_aton(sta, addr) < 0) {
9839 send_resp(dut, conn, SIGMA_ERROR,
9840 "ErrorCode,Invalid peer address");
9841 return 0;
9842 }
9843
9844 val = get_param(cmd, "type");
9845 if (val == NULL)
9846 return -1;
9847
9848 if (strcasecmp(val, "DISCOVERY") == 0) {
9849 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", sta);
9850 if (wpa_command(intf, buf) < 0) {
9851 send_resp(dut, conn, SIGMA_ERROR,
9852 "ErrorCode,Failed to send TDLS discovery");
9853 return 0;
9854 }
9855 return 1;
9856 }
9857
9858 if (strcasecmp(val, "SETUP") == 0) {
9859 int status = 0, timeout = 0;
9860
9861 val = get_param(cmd, "Status");
9862 if (val)
9863 status = atoi(val);
9864
9865 val = get_param(cmd, "Timeout");
9866 if (val)
9867 timeout = atoi(val);
9868
9869 if (status != 0 && status != 37) {
9870 send_resp(dut, conn, SIGMA_ERROR,
9871 "ErrorCode,Unsupported status value");
9872 return 0;
9873 }
9874
9875 if (timeout != 0 && timeout != 301) {
9876 send_resp(dut, conn, SIGMA_ERROR,
9877 "ErrorCode,Unsupported timeout value");
9878 return 0;
9879 }
9880
9881 if (status && timeout) {
9882 send_resp(dut, conn, SIGMA_ERROR,
9883 "ErrorCode,Unsupported timeout+status "
9884 "combination");
9885 return 0;
9886 }
9887
9888 if (status == 37 &&
9889 wpa_command(intf, "SET tdls_testing 0x200")) {
9890 send_resp(dut, conn, SIGMA_ERROR,
9891 "ErrorCode,Failed to enable "
9892 "decline setup response test mode");
9893 return 0;
9894 }
9895
9896 if (timeout == 301) {
9897 int res;
9898 if (dut->no_tpk_expiration)
9899 res = wpa_command(intf,
9900 "SET tdls_testing 0x108");
9901 else
9902 res = wpa_command(intf,
9903 "SET tdls_testing 0x8");
9904 if (res) {
9905 send_resp(dut, conn, SIGMA_ERROR,
9906 "ErrorCode,Failed to set short TPK "
9907 "lifetime");
9908 return 0;
9909 }
9910 }
9911
9912 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", sta);
9913 if (wpa_command(intf, buf) < 0) {
9914 send_resp(dut, conn, SIGMA_ERROR,
9915 "ErrorCode,Failed to send TDLS setup");
9916 return 0;
9917 }
9918 return 1;
9919 }
9920
9921 if (strcasecmp(val, "TEARDOWN") == 0) {
9922 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", sta);
9923 if (wpa_command(intf, buf) < 0) {
9924 send_resp(dut, conn, SIGMA_ERROR,
9925 "ErrorCode,Failed to send TDLS teardown");
9926 return 0;
9927 }
9928 return 1;
9929 }
9930
9931 send_resp(dut, conn, SIGMA_ERROR,
9932 "ErrorCode,Unsupported TDLS frame");
9933 return 0;
9934}
9935
9936
9937static int sta_ap_known(const char *ifname, const char *bssid)
9938{
9939 char buf[4096];
9940
Jouni Malinendd32f192018-09-15 02:55:19 +03009941 snprintf(buf, sizeof(buf), "BSS MASK=1 %s", bssid);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009942 if (wpa_command_resp(ifname, buf, buf, sizeof(buf)) < 0)
9943 return 0;
9944 if (strncmp(buf, "id=", 3) != 0)
9945 return 0;
9946 return 1;
9947}
9948
9949
9950static int sta_scan_ap(struct sigma_dut *dut, const char *ifname,
9951 const char *bssid)
9952{
9953 int res;
9954 struct wpa_ctrl *ctrl;
9955 char buf[256];
9956
9957 if (sta_ap_known(ifname, bssid))
9958 return 0;
9959 sigma_dut_print(dut, DUT_MSG_DEBUG,
9960 "AP not in BSS table - start scan");
9961
9962 ctrl = open_wpa_mon(ifname);
9963 if (ctrl == NULL) {
9964 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
9965 "wpa_supplicant monitor connection");
9966 return -1;
9967 }
9968
9969 if (wpa_command(ifname, "SCAN") < 0) {
9970 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to start scan");
9971 wpa_ctrl_detach(ctrl);
9972 wpa_ctrl_close(ctrl);
9973 return -1;
9974 }
9975
9976 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
9977 buf, sizeof(buf));
9978
9979 wpa_ctrl_detach(ctrl);
9980 wpa_ctrl_close(ctrl);
9981
9982 if (res < 0) {
9983 sigma_dut_print(dut, DUT_MSG_INFO, "Scan did not complete");
9984 return -1;
9985 }
9986
9987 if (sta_ap_known(ifname, bssid))
9988 return 0;
9989 sigma_dut_print(dut, DUT_MSG_INFO, "AP not in BSS table");
9990 return -1;
9991}
9992
9993
9994static int cmd_sta_send_frame_hs2_neighadv(struct sigma_dut *dut,
9995 struct sigma_conn *conn,
9996 struct sigma_cmd *cmd,
9997 const char *intf)
9998{
9999 char buf[200];
10000
10001 snprintf(buf, sizeof(buf), "ndsend 2001:DB8::1 %s", intf);
10002 if (system(buf) != 0) {
10003 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Failed to run "
10004 "ndsend");
10005 return 0;
10006 }
10007
10008 return 1;
10009}
10010
10011
10012static int cmd_sta_send_frame_hs2_neighsolreq(struct sigma_dut *dut,
10013 struct sigma_conn *conn,
10014 struct sigma_cmd *cmd,
10015 const char *intf)
10016{
10017 char buf[200];
10018 const char *ip = get_param(cmd, "SenderIP");
10019
Peng Xu26b356d2017-10-04 17:58:16 -070010020 if (!ip)
10021 return 0;
10022
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010023 snprintf(buf, sizeof(buf), "ndisc6 -nm %s %s -r 4", ip, intf);
10024 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10025 if (system(buf) == 0) {
10026 sigma_dut_print(dut, DUT_MSG_INFO,
10027 "Neighbor Solicitation got a response "
10028 "for %s@%s", ip, intf);
10029 }
10030
10031 return 1;
10032}
10033
10034
10035static int cmd_sta_send_frame_hs2_arpprobe(struct sigma_dut *dut,
10036 struct sigma_conn *conn,
10037 struct sigma_cmd *cmd,
10038 const char *ifname)
10039{
10040 char buf[200];
10041 const char *ip = get_param(cmd, "SenderIP");
10042
10043 if (ip == NULL) {
10044 send_resp(dut, conn, SIGMA_ERROR,
10045 "ErrorCode,Missing SenderIP parameter");
10046 return 0;
10047 }
10048 snprintf(buf, sizeof(buf), "arping -I %s -D %s -c 4", ifname, ip);
10049 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10050 if (system(buf) != 0) {
10051 sigma_dut_print(dut, DUT_MSG_INFO, "arping DAD got a response "
10052 "for %s@%s", ip, ifname);
10053 }
10054
10055 return 1;
10056}
10057
10058
10059static int cmd_sta_send_frame_hs2_arpannounce(struct sigma_dut *dut,
10060 struct sigma_conn *conn,
10061 struct sigma_cmd *cmd,
10062 const char *ifname)
10063{
10064 char buf[200];
10065 char ip[16];
10066 int s;
Peng Xub3756882017-10-04 14:39:09 -070010067 struct ifreq ifr;
10068 struct sockaddr_in saddr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010069
10070 s = socket(PF_INET, SOCK_DGRAM, 0);
Peng Xub3756882017-10-04 14:39:09 -070010071 if (s < 0) {
10072 perror("socket");
10073 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010074 }
10075
Peng Xub3756882017-10-04 14:39:09 -070010076 memset(&ifr, 0, sizeof(ifr));
10077 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
10078 if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
10079 sigma_dut_print(dut, DUT_MSG_INFO,
10080 "Failed to get %s IP address: %s",
10081 ifname, strerror(errno));
10082 close(s);
10083 return -1;
10084 }
10085 close(s);
10086
10087 memcpy(&saddr, &ifr.ifr_addr, sizeof(struct sockaddr_in));
10088 strlcpy(ip, inet_ntoa(saddr.sin_addr), sizeof(ip));
10089
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010090 snprintf(buf, sizeof(buf), "arping -I %s -s %s %s -c 4", ifname, ip,
10091 ip);
10092 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10093 if (system(buf) != 0) {
10094 }
10095
10096 return 1;
10097}
10098
10099
10100static int cmd_sta_send_frame_hs2_arpreply(struct sigma_dut *dut,
10101 struct sigma_conn *conn,
10102 struct sigma_cmd *cmd,
10103 const char *ifname)
10104{
10105 char buf[200], addr[20];
10106 char dst[ETH_ALEN], src[ETH_ALEN];
10107 short ethtype = htons(ETH_P_ARP);
10108 char *pos;
10109 int s, res;
10110 const char *val;
10111 struct sockaddr_in taddr;
10112
10113 val = get_param(cmd, "dest");
10114 if (val)
10115 hwaddr_aton(val, (unsigned char *) dst);
10116
10117 val = get_param(cmd, "DestIP");
10118 if (val)
10119 inet_aton(val, &taddr.sin_addr);
Peng Xu151c9e12017-10-04 14:39:09 -070010120 else
10121 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010122
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010123 if (get_wpa_status(get_station_ifname(dut), "address", addr,
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010124 sizeof(addr)) < 0)
10125 return -2;
10126 hwaddr_aton(addr, (unsigned char *) src);
10127
10128 pos = buf;
10129 *pos++ = 0x00;
10130 *pos++ = 0x01;
10131 *pos++ = 0x08;
10132 *pos++ = 0x00;
10133 *pos++ = 0x06;
10134 *pos++ = 0x04;
10135 *pos++ = 0x00;
10136 *pos++ = 0x02;
10137 memcpy(pos, src, ETH_ALEN);
10138 pos += ETH_ALEN;
10139 memcpy(pos, &taddr.sin_addr, 4);
10140 pos += 4;
10141 memcpy(pos, dst, ETH_ALEN);
10142 pos += ETH_ALEN;
10143 memcpy(pos, &taddr.sin_addr, 4);
10144 pos += 4;
10145
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010146 s = open_monitor(get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010147 if (s < 0) {
10148 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
10149 "monitor socket");
10150 return 0;
10151 }
10152
10153 res = inject_eth_frame(s, buf, pos - buf, ethtype, dst, src);
10154 if (res < 0) {
10155 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
10156 "inject frame");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +053010157 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010158 return 0;
10159 }
10160
10161 close(s);
10162
10163 return 1;
10164}
10165
10166
10167static int cmd_sta_send_frame_hs2_dls_req(struct sigma_dut *dut,
10168 struct sigma_conn *conn,
10169 struct sigma_cmd *cmd,
10170 const char *intf, const char *dest)
10171{
10172 char buf[100];
10173
10174 if (if_nametoindex("sigmadut") == 0) {
10175 snprintf(buf, sizeof(buf),
10176 "iw dev %s interface add sigmadut type monitor",
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010177 get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010178 if (system(buf) != 0 ||
10179 if_nametoindex("sigmadut") == 0) {
10180 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
10181 "monitor interface with '%s'", buf);
10182 return -2;
10183 }
10184 }
10185
10186 if (system("ifconfig sigmadut up") != 0) {
10187 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
10188 "monitor interface up");
10189 return -2;
10190 }
10191
10192 return sta_inject_frame(dut, conn, DLS_REQ, UNPROTECTED, dest);
10193}
10194
10195
10196static int cmd_sta_send_frame_hs2(struct sigma_dut *dut,
10197 struct sigma_conn *conn,
10198 struct sigma_cmd *cmd)
10199{
10200 const char *intf = get_param(cmd, "Interface");
10201 const char *dest = get_param(cmd, "Dest");
10202 const char *type = get_param(cmd, "FrameName");
10203 const char *val;
10204 char buf[200], *pos, *end;
10205 int count, count2;
10206
10207 if (type == NULL)
10208 type = get_param(cmd, "Type");
10209
10210 if (intf == NULL || dest == NULL || type == NULL)
10211 return -1;
10212
10213 if (strcasecmp(type, "NeighAdv") == 0)
10214 return cmd_sta_send_frame_hs2_neighadv(dut, conn, cmd, intf);
10215
10216 if (strcasecmp(type, "NeighSolicitReq") == 0)
10217 return cmd_sta_send_frame_hs2_neighsolreq(dut, conn, cmd, intf);
10218
10219 if (strcasecmp(type, "ARPProbe") == 0)
10220 return cmd_sta_send_frame_hs2_arpprobe(dut, conn, cmd, intf);
10221
10222 if (strcasecmp(type, "ARPAnnounce") == 0)
10223 return cmd_sta_send_frame_hs2_arpannounce(dut, conn, cmd, intf);
10224
10225 if (strcasecmp(type, "ARPReply") == 0)
10226 return cmd_sta_send_frame_hs2_arpreply(dut, conn, cmd, intf);
10227
10228 if (strcasecmp(type, "DLS-request") == 0 ||
10229 strcasecmp(type, "DLSrequest") == 0)
10230 return cmd_sta_send_frame_hs2_dls_req(dut, conn, cmd, intf,
10231 dest);
10232
10233 if (strcasecmp(type, "ANQPQuery") != 0 &&
10234 strcasecmp(type, "Query") != 0) {
10235 send_resp(dut, conn, SIGMA_ERROR,
10236 "ErrorCode,Unsupported HS 2.0 send frame type");
10237 return 0;
10238 }
10239
10240 if (sta_scan_ap(dut, intf, dest) < 0) {
10241 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not find "
10242 "the requested AP");
10243 return 0;
10244 }
10245
10246 pos = buf;
10247 end = buf + sizeof(buf);
10248 count = 0;
10249 pos += snprintf(pos, end - pos, "ANQP_GET %s ", dest);
10250
10251 val = get_param(cmd, "ANQP_CAP_LIST");
10252 if (val && atoi(val)) {
10253 pos += snprintf(pos, end - pos, "%s257", count > 0 ? "," : "");
10254 count++;
10255 }
10256
10257 val = get_param(cmd, "VENUE_NAME");
10258 if (val && atoi(val)) {
10259 pos += snprintf(pos, end - pos, "%s258", count > 0 ? "," : "");
10260 count++;
10261 }
10262
10263 val = get_param(cmd, "NETWORK_AUTH_TYPE");
10264 if (val && atoi(val)) {
10265 pos += snprintf(pos, end - pos, "%s260", count > 0 ? "," : "");
10266 count++;
10267 }
10268
10269 val = get_param(cmd, "ROAMING_CONS");
10270 if (val && atoi(val)) {
10271 pos += snprintf(pos, end - pos, "%s261", count > 0 ? "," : "");
10272 count++;
10273 }
10274
10275 val = get_param(cmd, "IP_ADDR_TYPE_AVAILABILITY");
10276 if (val && atoi(val)) {
10277 pos += snprintf(pos, end - pos, "%s262", count > 0 ? "," : "");
10278 count++;
10279 }
10280
10281 val = get_param(cmd, "NAI_REALM_LIST");
10282 if (val && atoi(val)) {
10283 pos += snprintf(pos, end - pos, "%s263", count > 0 ? "," : "");
10284 count++;
10285 }
10286
10287 val = get_param(cmd, "3GPP_INFO");
10288 if (val && atoi(val)) {
10289 pos += snprintf(pos, end - pos, "%s264", count > 0 ? "," : "");
10290 count++;
10291 }
10292
10293 val = get_param(cmd, "DOMAIN_LIST");
10294 if (val && atoi(val)) {
10295 pos += snprintf(pos, end - pos, "%s268", count > 0 ? "," : "");
10296 count++;
10297 }
10298
Jouni Malinen34cf9532018-04-29 19:26:33 +030010299 val = get_param(cmd, "Venue_URL");
10300 if (val && atoi(val)) {
10301 pos += snprintf(pos, end - pos, "%s277", count > 0 ? "," : "");
10302 count++;
10303 }
10304
Jouni Malinend3bca5d2018-04-29 17:25:23 +030010305 val = get_param(cmd, "Advice_Of_Charge");
10306 if (val && atoi(val)) {
10307 pos += snprintf(pos, end - pos, "%s278", count > 0 ? "," : "");
10308 count++;
10309 }
10310
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010311 if (count && wpa_command(intf, buf)) {
10312 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,ANQP_GET failed");
10313 return 0;
10314 }
10315
10316 pos = buf;
10317 end = buf + sizeof(buf);
10318 count2 = 0;
10319 pos += snprintf(pos, end - pos, "HS20_ANQP_GET %s ", dest);
10320
10321 val = get_param(cmd, "HS_CAP_LIST");
10322 if (val && atoi(val)) {
10323 pos += snprintf(pos, end - pos, "%s2", count2 > 0 ? "," : "");
10324 count2++;
10325 }
10326
10327 val = get_param(cmd, "OPER_NAME");
10328 if (val && atoi(val)) {
10329 pos += snprintf(pos, end - pos, "%s3", count2 > 0 ? "," : "");
10330 count2++;
10331 }
10332
10333 val = get_param(cmd, "WAN_METRICS");
10334 if (!val)
10335 val = get_param(cmd, "WAN_MAT");
10336 if (!val)
10337 val = get_param(cmd, "WAN_MET");
10338 if (val && atoi(val)) {
10339 pos += snprintf(pos, end - pos, "%s4", count2 > 0 ? "," : "");
10340 count2++;
10341 }
10342
10343 val = get_param(cmd, "CONNECTION_CAPABILITY");
10344 if (val && atoi(val)) {
10345 pos += snprintf(pos, end - pos, "%s5", count2 > 0 ? "," : "");
10346 count2++;
10347 }
10348
10349 val = get_param(cmd, "OP_CLASS");
10350 if (val && atoi(val)) {
10351 pos += snprintf(pos, end - pos, "%s7", count2 > 0 ? "," : "");
10352 count2++;
10353 }
10354
10355 val = get_param(cmd, "OSU_PROVIDER_LIST");
10356 if (val && atoi(val)) {
10357 pos += snprintf(pos, end - pos, "%s8", count2 > 0 ? "," : "");
10358 count2++;
10359 }
10360
Jouni Malinenf67afec2018-04-29 19:24:58 +030010361 val = get_param(cmd, "OPER_ICON_METADATA");
10362 if (!val)
10363 val = get_param(cmd, "OPERATOR_ICON_METADATA");
10364 if (val && atoi(val)) {
10365 pos += snprintf(pos, end - pos, "%s12", count2 > 0 ? "," : "");
10366 count2++;
10367 }
10368
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010369 if (count && count2) {
10370 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before sending out "
10371 "second query");
10372 sleep(1);
10373 }
10374
10375 if (count2 && wpa_command(intf, buf)) {
10376 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,HS20_ANQP_GET "
10377 "failed");
10378 return 0;
10379 }
10380
10381 val = get_param(cmd, "NAI_HOME_REALM_LIST");
10382 if (val) {
10383 if (count || count2) {
10384 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
10385 "sending out second query");
10386 sleep(1);
10387 }
10388
10389 if (strcmp(val, "1") == 0)
10390 val = "mail.example.com";
10391 snprintf(buf, end - pos,
10392 "HS20_GET_NAI_HOME_REALM_LIST %s realm=%s",
10393 dest, val);
10394 if (wpa_command(intf, buf)) {
10395 send_resp(dut, conn, SIGMA_ERROR,
10396 "ErrorCode,HS20_GET_NAI_HOME_REALM_LIST "
10397 "failed");
10398 return 0;
10399 }
10400 }
10401
10402 val = get_param(cmd, "ICON_REQUEST");
10403 if (val) {
10404 if (count || count2) {
10405 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
10406 "sending out second query");
10407 sleep(1);
10408 }
10409
10410 snprintf(buf, end - pos,
10411 "HS20_ICON_REQUEST %s %s", dest, val);
10412 if (wpa_command(intf, buf)) {
10413 send_resp(dut, conn, SIGMA_ERROR,
10414 "ErrorCode,HS20_ICON_REQUEST failed");
10415 return 0;
10416 }
10417 }
10418
10419 return 1;
10420}
10421
10422
10423static int ath_sta_send_frame_vht(struct sigma_dut *dut,
10424 struct sigma_conn *conn,
10425 struct sigma_cmd *cmd)
10426{
10427 const char *val;
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010428 const char *ifname;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010429 int chwidth, nss;
10430
10431 val = get_param(cmd, "framename");
10432 if (!val)
10433 return -1;
10434 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
10435
10436 /* Command sequence to generate Op mode notification */
10437 if (val && strcasecmp(val, "Op_md_notif_frm") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010438 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010439
10440 /* Disable STBC */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010441 run_iwpriv(dut, ifname, "tx_stbc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010442
10443 /* Extract Channel width */
10444 val = get_param(cmd, "Channel_width");
10445 if (val) {
10446 switch (atoi(val)) {
10447 case 20:
10448 chwidth = 0;
10449 break;
10450 case 40:
10451 chwidth = 1;
10452 break;
10453 case 80:
10454 chwidth = 2;
10455 break;
10456 case 160:
10457 chwidth = 3;
10458 break;
10459 default:
10460 chwidth = 2;
10461 break;
10462 }
10463
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010464 run_iwpriv(dut, ifname, "chwidth %d", chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010465 }
10466
10467 /* Extract NSS */
10468 val = get_param(cmd, "NSS");
10469 if (val) {
10470 switch (atoi(val)) {
10471 case 1:
10472 nss = 1;
10473 break;
10474 case 2:
10475 nss = 3;
10476 break;
10477 case 3:
10478 nss = 7;
10479 break;
10480 default:
10481 /* We do not support NSS > 3 */
10482 nss = 3;
10483 break;
10484 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010485 run_iwpriv(dut, ifname, "rxchainmask %d", nss);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010486 }
10487
10488 /* Opmode notify */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010489 run_iwpriv(dut, ifname, "opmode_notify 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010490 }
10491
10492 return 1;
10493}
10494
10495
10496static int cmd_sta_send_frame_vht(struct sigma_dut *dut,
10497 struct sigma_conn *conn,
10498 struct sigma_cmd *cmd)
10499{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010500 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010501 case DRIVER_ATHEROS:
10502 return ath_sta_send_frame_vht(dut, conn, cmd);
10503 default:
10504 send_resp(dut, conn, SIGMA_ERROR,
10505 "errorCode,Unsupported sta_set_frame(VHT) with the current driver");
10506 return 0;
10507 }
10508}
10509
10510
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070010511static int wcn_sta_send_frame_he(struct sigma_dut *dut, struct sigma_conn *conn,
10512 struct sigma_cmd *cmd)
10513{
10514 const char *val;
10515 const char *intf = get_param(cmd, "Interface");
10516
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +030010517 if (!intf)
10518 return -1;
10519
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070010520 val = get_param(cmd, "framename");
10521 if (!val)
10522 return -1;
10523 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
10524
10525 /* Command sequence to generate Op mode notification */
10526 if (val && strcasecmp(val, "action") == 0) {
10527 val = get_param(cmd, "PPDUTxType");
10528 if (val && strcasecmp(val, "TB") == 0) {
10529 if (sta_set_action_tx_in_he_tb_ppdu(dut, intf, 1)) {
10530 sigma_dut_print(dut, DUT_MSG_ERROR,
10531 "failed to send TB PPDU Tx cfg");
10532 send_resp(dut, conn, SIGMA_ERROR,
10533 "ErrorCode,set TB PPDU Tx cfg failed");
10534 return 0;
10535 }
10536 return 1;
10537 }
10538
10539 sigma_dut_print(dut, DUT_MSG_ERROR,
10540 "Action Tx type is not defined");
10541 }
10542
10543 return 1;
10544}
10545
10546
10547static int cmd_sta_send_frame_he(struct sigma_dut *dut,
10548 struct sigma_conn *conn,
10549 struct sigma_cmd *cmd)
10550{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010551 switch (get_driver_type(dut)) {
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070010552 case DRIVER_WCN:
10553 return wcn_sta_send_frame_he(dut, conn, cmd);
10554 default:
10555 send_resp(dut, conn, SIGMA_ERROR,
10556 "errorCode,Unsupported sta_set_frame(HE) with the current driver");
10557 return 0;
10558 }
10559}
10560
10561
Lior David0fe101e2017-03-09 16:09:50 +020010562#ifdef __linux__
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030010563
10564static int
10565wil6210_send_p2p_frame_60g(struct sigma_dut *dut, struct sigma_cmd *cmd,
10566 const char *frame_name, const char *dest_mac)
10567{
10568 int isprobereq = strcasecmp(frame_name, "probereq") == 0;
10569 const char *ssid = get_param(cmd, "ssid");
10570 const char *countstr = get_param(cmd, "count");
10571 const char *channelstr = get_param(cmd, "channel");
10572 const char *group_id = get_param(cmd, "groupid");
10573 const char *client_id = get_param(cmd, "clientmac");
10574 int count, channel, freq, i;
10575 const char *fname;
10576 char frame[1024], src_mac[20], group_id_attr[25],
10577 device_macstr[3 * ETH_ALEN], client_mac[ETH_ALEN];
10578 const char *group_ssid;
10579 const int group_ssid_prefix_len = 9;
10580 struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *) frame;
10581 size_t framelen = sizeof(frame);
10582 struct template_frame_tag tags[2];
10583 size_t tags_total = ARRAY_SIZE(tags);
10584 int tag_index, len, dst_len;
10585
10586 if (!countstr || !channelstr) {
10587 sigma_dut_print(dut, DUT_MSG_ERROR,
10588 "Missing argument: count, channel");
10589 return -1;
10590 }
10591 if (isprobereq && !ssid) {
10592 sigma_dut_print(dut, DUT_MSG_ERROR,
10593 "Missing argument: ssid");
10594 return -1;
10595 }
10596 if (!isprobereq && (!group_id || !client_id)) {
10597 sigma_dut_print(dut, DUT_MSG_ERROR,
10598 "Missing argument: group_id, client_id");
10599 return -1;
10600 }
10601
10602 count = atoi(countstr);
10603 channel = atoi(channelstr);
10604 freq = channel_to_freq(dut, channel);
10605
10606 if (!freq) {
10607 sigma_dut_print(dut, DUT_MSG_ERROR,
10608 "invalid channel: %s", channelstr);
10609 return -1;
10610 }
10611
10612 if (isprobereq) {
10613 if (strcasecmp(ssid, "wildcard") == 0) {
10614 fname = "probe_req_wildcard.txt";
10615 } else if (strcasecmp(ssid, "P2P_Wildcard") == 0) {
10616 fname = "probe_req_P2P_Wildcard.txt";
10617 } else {
10618 sigma_dut_print(dut, DUT_MSG_ERROR,
10619 "invalid probe request type");
10620 return -1;
10621 }
10622 } else {
10623 fname = "P2P_device_discovery_req.txt";
10624 }
10625
10626 if (parse_template_frame_file(dut, fname, frame, &framelen,
10627 tags, &tags_total)) {
10628 sigma_dut_print(dut, DUT_MSG_ERROR,
10629 "invalid frame template: %s", fname);
10630 return -1;
10631 }
10632
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010633 if (get_wpa_status(get_station_ifname(dut), "address",
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030010634 src_mac, sizeof(src_mac)) < 0 ||
10635 parse_mac_address(dut, src_mac, &hdr->addr2[0]) ||
10636 parse_mac_address(dut, dest_mac, &hdr->addr1[0]))
10637 return -1;
10638 /* Use wildcard BSSID, since we are in PBSS */
10639 memset(&hdr->addr3, 0xFF, ETH_ALEN);
10640
10641 if (!isprobereq) {
10642 tag_index = find_template_frame_tag(tags, tags_total, 1);
10643 if (tag_index < 0) {
10644 sigma_dut_print(dut, DUT_MSG_ERROR,
10645 "can't find device id attribute");
10646 return -1;
10647 }
10648 if (parse_mac_address(dut, client_id,
10649 (unsigned char *) client_mac)) {
10650 sigma_dut_print(dut, DUT_MSG_ERROR,
10651 "invalid client_id: %s", client_id);
10652 return -1;
10653 }
10654 if (replace_p2p_attribute(dut, &frame[tags[tag_index].offset],
10655 framelen - tags[tag_index].offset,
10656 IEEE80211_P2P_ATTR_DEVICE_ID,
10657 client_mac, ETH_ALEN)) {
10658 sigma_dut_print(dut, DUT_MSG_ERROR,
10659 "fail to replace device id attribute");
10660 return -1;
10661 }
10662
10663 /*
10664 * group_id arg contains device MAC address followed by
10665 * space and SSID (DIRECT-somessid).
10666 * group id attribute contains device address (6 bytes)
10667 * followed by SSID prefix DIRECT-XX (9 bytes)
10668 */
10669 if (strlen(group_id) < sizeof(device_macstr)) {
10670 sigma_dut_print(dut, DUT_MSG_ERROR,
10671 "group_id arg too short");
10672 return -1;
10673 }
10674 memcpy(device_macstr, group_id, sizeof(device_macstr));
10675 device_macstr[sizeof(device_macstr) - 1] = '\0';
10676 if (parse_mac_address(dut, device_macstr,
10677 (unsigned char *) group_id_attr)) {
10678 sigma_dut_print(dut, DUT_MSG_ERROR,
10679 "fail to parse device address from group_id");
10680 return -1;
10681 }
10682 group_ssid = strchr(group_id, ' ');
10683 if (!group_ssid) {
10684 sigma_dut_print(dut, DUT_MSG_ERROR,
10685 "invalid group_id arg, no ssid");
10686 return -1;
10687 }
10688 group_ssid++;
10689 len = strlen(group_ssid);
10690 if (len < group_ssid_prefix_len) {
10691 sigma_dut_print(dut, DUT_MSG_ERROR,
10692 "group_id SSID too short");
10693 return -1;
10694 }
10695 dst_len = sizeof(group_id_attr) - ETH_ALEN;
10696 if (len > dst_len) {
10697 sigma_dut_print(dut, DUT_MSG_ERROR,
10698 "group_id SSID (%s) too long",
10699 group_ssid);
10700 return -1;
10701 }
10702
10703 memcpy(group_id_attr + ETH_ALEN, group_ssid, len);
10704 tag_index = find_template_frame_tag(tags, tags_total, 2);
10705 if (tag_index < 0) {
10706 sigma_dut_print(dut, DUT_MSG_ERROR,
10707 "can't find group id attribute");
10708 return -1;
10709 }
10710 if (replace_p2p_attribute(dut, &frame[tags[tag_index].offset],
10711 framelen - tags[tag_index].offset,
10712 IEEE80211_P2P_ATTR_GROUP_ID,
10713 group_id_attr,
10714 sizeof(group_id_attr))) {
10715 sigma_dut_print(dut, DUT_MSG_ERROR,
10716 "fail to replace group id attribute");
10717 return -1;
10718 }
10719 }
10720
10721 for (i = 0; i < count; i++) {
10722 if (wil6210_transmit_frame(dut, freq,
10723 WIL_TRANSMIT_FRAME_DEFAULT_ROC,
10724 frame, framelen)) {
10725 sigma_dut_print(dut, DUT_MSG_ERROR,
10726 "fail to transmit probe request frame");
10727 return -1;
10728 }
10729 }
10730
10731 return 0;
10732}
10733
10734
Lior David0fe101e2017-03-09 16:09:50 +020010735int wil6210_send_frame_60g(struct sigma_dut *dut, struct sigma_conn *conn,
10736 struct sigma_cmd *cmd)
10737{
10738 const char *frame_name = get_param(cmd, "framename");
10739 const char *mac = get_param(cmd, "dest_mac");
10740
10741 if (!frame_name || !mac) {
10742 sigma_dut_print(dut, DUT_MSG_ERROR,
10743 "framename and dest_mac must be provided");
10744 return -1;
10745 }
10746
10747 if (strcasecmp(frame_name, "brp") == 0) {
10748 const char *l_rx = get_param(cmd, "L-RX");
10749 int l_rx_i;
10750
10751 if (!l_rx) {
10752 sigma_dut_print(dut, DUT_MSG_ERROR,
10753 "L-RX must be provided");
10754 return -1;
10755 }
10756 l_rx_i = atoi(l_rx);
10757
10758 sigma_dut_print(dut, DUT_MSG_INFO,
10759 "dev_send_frame: BRP-RX, dest_mac %s, L-RX %s",
10760 mac, l_rx);
10761 if (l_rx_i != 16) {
10762 sigma_dut_print(dut, DUT_MSG_ERROR,
10763 "unsupported L-RX: %s", l_rx);
10764 return -1;
10765 }
10766
10767 if (wil6210_send_brp_rx(dut, mac, l_rx_i))
10768 return -1;
10769 } else if (strcasecmp(frame_name, "ssw") == 0) {
10770 sigma_dut_print(dut, DUT_MSG_INFO,
10771 "dev_send_frame: SLS, dest_mac %s", mac);
10772 if (wil6210_send_sls(dut, mac))
10773 return -1;
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030010774 } else if ((strcasecmp(frame_name, "probereq") == 0) ||
10775 (strcasecmp(frame_name, "devdiscreq") == 0)) {
10776 sigma_dut_print(dut, DUT_MSG_INFO,
10777 "dev_send_frame: %s, dest_mac %s", frame_name,
10778 mac);
10779 if (wil6210_send_p2p_frame_60g(dut, cmd, frame_name, mac))
10780 return -1;
Lior David0fe101e2017-03-09 16:09:50 +020010781 } else {
10782 sigma_dut_print(dut, DUT_MSG_ERROR,
10783 "unsupported frame type: %s", frame_name);
10784 return -1;
10785 }
10786
10787 return 1;
10788}
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030010789
Lior David0fe101e2017-03-09 16:09:50 +020010790#endif /* __linux__ */
10791
10792
10793static int cmd_sta_send_frame_60g(struct sigma_dut *dut,
10794 struct sigma_conn *conn,
10795 struct sigma_cmd *cmd)
10796{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010797 switch (get_driver_type(dut)) {
Lior David0fe101e2017-03-09 16:09:50 +020010798#ifdef __linux__
10799 case DRIVER_WIL6210:
10800 return wil6210_send_frame_60g(dut, conn, cmd);
10801#endif /* __linux__ */
10802 default:
10803 send_resp(dut, conn, SIGMA_ERROR,
10804 "errorCode,Unsupported sta_set_frame(60G) with the current driver");
10805 return 0;
10806 }
10807}
10808
10809
Ashwini Patildb59b3c2017-04-13 15:19:23 +053010810static int mbo_send_anqp_query(struct sigma_dut *dut, struct sigma_conn *conn,
10811 const char *intf, struct sigma_cmd *cmd)
10812{
10813 const char *val, *addr;
10814 char buf[100];
10815
10816 addr = get_param(cmd, "DestMac");
10817 if (!addr) {
10818 send_resp(dut, conn, SIGMA_INVALID,
10819 "ErrorCode,AP MAC address is missing");
10820 return 0;
10821 }
10822
10823 val = get_param(cmd, "ANQPQuery_ID");
10824 if (!val) {
10825 send_resp(dut, conn, SIGMA_INVALID,
10826 "ErrorCode,Missing ANQPQuery_ID");
10827 return 0;
10828 }
10829
10830 if (strcasecmp(val, "NeighborReportReq") == 0) {
10831 snprintf(buf, sizeof(buf), "ANQP_GET %s 272", addr);
10832 } else if (strcasecmp(val, "QueryListWithCellPref") == 0) {
10833 snprintf(buf, sizeof(buf), "ANQP_GET %s 272,mbo:2", addr);
10834 } else {
10835 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid ANQPQuery_ID: %s",
10836 val);
10837 send_resp(dut, conn, SIGMA_INVALID,
10838 "ErrorCode,Invalid ANQPQuery_ID");
10839 return 0;
10840 }
10841
Ashwini Patild174f2c2017-04-13 16:49:46 +053010842 /* Set gas_address3 field to IEEE 802.11-2012 standard compliant form
10843 * (Address3 = Wildcard BSSID when sent to not-associated AP;
10844 * if associated, AP BSSID).
10845 */
10846 if (wpa_command(intf, "SET gas_address3 1") < 0) {
10847 send_resp(dut, conn, SIGMA_ERROR,
10848 "ErrorCode,Failed to set gas_address3");
10849 return 0;
10850 }
10851
Ashwini Patildb59b3c2017-04-13 15:19:23 +053010852 if (wpa_command(intf, buf) < 0) {
10853 send_resp(dut, conn, SIGMA_ERROR,
10854 "ErrorCode,Failed to send ANQP query");
10855 return 0;
10856 }
10857
10858 return 1;
10859}
10860
10861
10862static int mbo_cmd_sta_send_frame(struct sigma_dut *dut,
10863 struct sigma_conn *conn,
10864 const char *intf,
10865 struct sigma_cmd *cmd)
10866{
10867 const char *val = get_param(cmd, "FrameName");
10868
10869 if (val && strcasecmp(val, "ANQPQuery") == 0)
10870 return mbo_send_anqp_query(dut, conn, intf, cmd);
10871
10872 return 2;
10873}
10874
10875
Jouni Malinenf7222712019-06-13 01:50:21 +030010876enum sigma_cmd_result cmd_sta_send_frame(struct sigma_dut *dut,
10877 struct sigma_conn *conn,
10878 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010879{
10880 const char *intf = get_param(cmd, "Interface");
10881 const char *val;
10882 enum send_frame_type frame;
10883 enum send_frame_protection protected;
10884 char buf[100];
10885 unsigned char addr[ETH_ALEN];
10886 int res;
10887
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +030010888 if (!intf)
10889 return -1;
10890
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010891 val = get_param(cmd, "program");
10892 if (val == NULL)
10893 val = get_param(cmd, "frame");
10894 if (val && strcasecmp(val, "TDLS") == 0)
10895 return cmd_sta_send_frame_tdls(dut, conn, cmd);
10896 if (val && (strcasecmp(val, "HS2") == 0 ||
Jouni Malinen1f6ae642018-06-07 23:56:13 +030010897 strcasecmp(val, "HS2-R2") == 0 ||
10898 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010899 return cmd_sta_send_frame_hs2(dut, conn, cmd);
10900 if (val && strcasecmp(val, "VHT") == 0)
10901 return cmd_sta_send_frame_vht(dut, conn, cmd);
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070010902 if (val && strcasecmp(val, "HE") == 0)
10903 return cmd_sta_send_frame_he(dut, conn, cmd);
priyadharshini gowthamand66913a2016-07-29 15:11:17 -070010904 if (val && strcasecmp(val, "LOC") == 0)
10905 return loc_cmd_sta_send_frame(dut, conn, cmd);
Lior David0fe101e2017-03-09 16:09:50 +020010906 if (val && strcasecmp(val, "60GHz") == 0)
10907 return cmd_sta_send_frame_60g(dut, conn, cmd);
Ashwini Patildb59b3c2017-04-13 15:19:23 +053010908 if (val && strcasecmp(val, "MBO") == 0) {
10909 res = mbo_cmd_sta_send_frame(dut, conn, intf, cmd);
10910 if (res != 2)
10911 return res;
10912 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010913
10914 val = get_param(cmd, "TD_DISC");
10915 if (val) {
10916 if (hwaddr_aton(val, addr) < 0)
10917 return -1;
10918 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", val);
10919 if (wpa_command(intf, buf) < 0) {
10920 send_resp(dut, conn, SIGMA_ERROR,
10921 "ErrorCode,Failed to send TDLS discovery");
10922 return 0;
10923 }
10924 return 1;
10925 }
10926
10927 val = get_param(cmd, "TD_Setup");
10928 if (val) {
10929 if (hwaddr_aton(val, addr) < 0)
10930 return -1;
10931 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", val);
10932 if (wpa_command(intf, buf) < 0) {
10933 send_resp(dut, conn, SIGMA_ERROR,
10934 "ErrorCode,Failed to start TDLS setup");
10935 return 0;
10936 }
10937 return 1;
10938 }
10939
10940 val = get_param(cmd, "TD_TearDown");
10941 if (val) {
10942 if (hwaddr_aton(val, addr) < 0)
10943 return -1;
10944 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", val);
10945 if (wpa_command(intf, buf) < 0) {
10946 send_resp(dut, conn, SIGMA_ERROR,
10947 "ErrorCode,Failed to tear down TDLS link");
10948 return 0;
10949 }
10950 return 1;
10951 }
10952
10953 val = get_param(cmd, "TD_ChannelSwitch");
10954 if (val) {
10955 /* TODO */
10956 send_resp(dut, conn, SIGMA_ERROR,
10957 "ErrorCode,TD_ChannelSwitch not yet supported");
10958 return 0;
10959 }
10960
10961 val = get_param(cmd, "TD_NF");
10962 if (val) {
10963 /* TODO */
10964 send_resp(dut, conn, SIGMA_ERROR,
10965 "ErrorCode,TD_NF not yet supported");
10966 return 0;
10967 }
10968
10969 val = get_param(cmd, "PMFFrameType");
10970 if (val == NULL)
10971 val = get_param(cmd, "FrameName");
10972 if (val == NULL)
10973 val = get_param(cmd, "Type");
10974 if (val == NULL)
10975 return -1;
10976 if (strcasecmp(val, "disassoc") == 0)
10977 frame = DISASSOC;
10978 else if (strcasecmp(val, "deauth") == 0)
10979 frame = DEAUTH;
10980 else if (strcasecmp(val, "saquery") == 0)
10981 frame = SAQUERY;
10982 else if (strcasecmp(val, "auth") == 0)
10983 frame = AUTH;
10984 else if (strcasecmp(val, "assocreq") == 0)
10985 frame = ASSOCREQ;
10986 else if (strcasecmp(val, "reassocreq") == 0)
10987 frame = REASSOCREQ;
10988 else if (strcasecmp(val, "neigreq") == 0) {
10989 sigma_dut_print(dut, DUT_MSG_INFO, "Got neighbor request");
10990
10991 val = get_param(cmd, "ssid");
10992 if (val == NULL)
10993 return -1;
10994
10995 res = send_neighbor_request(dut, intf, val);
10996 if (res) {
10997 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
10998 "Failed to send neighbor report request");
10999 return 0;
11000 }
11001
11002 return 1;
Ashwini Patil5acd7382017-04-13 15:55:04 +053011003 } else if (strcasecmp(val, "transmgmtquery") == 0 ||
11004 strcasecmp(val, "BTMQuery") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011005 sigma_dut_print(dut, DUT_MSG_DEBUG,
11006 "Got Transition Management Query");
11007
Ashwini Patil5acd7382017-04-13 15:55:04 +053011008 res = send_trans_mgmt_query(dut, intf, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011009 if (res) {
11010 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
11011 "Failed to send Transition Management Query");
11012 return 0;
11013 }
11014
11015 return 1;
11016 } else {
11017 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
11018 "PMFFrameType");
11019 return 0;
11020 }
11021
11022 val = get_param(cmd, "PMFProtected");
11023 if (val == NULL)
11024 val = get_param(cmd, "Protected");
11025 if (val == NULL)
11026 return -1;
11027 if (strcasecmp(val, "Correct-key") == 0 ||
11028 strcasecmp(val, "CorrectKey") == 0)
11029 protected = CORRECT_KEY;
11030 else if (strcasecmp(val, "IncorrectKey") == 0)
11031 protected = INCORRECT_KEY;
11032 else if (strcasecmp(val, "Unprotected") == 0)
11033 protected = UNPROTECTED;
11034 else {
11035 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
11036 "PMFProtected");
11037 return 0;
11038 }
11039
11040 if (protected != UNPROTECTED &&
11041 (frame == AUTH || frame == ASSOCREQ || frame == REASSOCREQ)) {
11042 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Impossible "
11043 "PMFProtected for auth/assocreq/reassocreq");
11044 return 0;
11045 }
11046
11047 if (if_nametoindex("sigmadut") == 0) {
11048 snprintf(buf, sizeof(buf),
11049 "iw dev %s interface add sigmadut type monitor",
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011050 get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011051 if (system(buf) != 0 ||
11052 if_nametoindex("sigmadut") == 0) {
11053 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
11054 "monitor interface with '%s'", buf);
11055 return -2;
11056 }
11057 }
11058
11059 if (system("ifconfig sigmadut up") != 0) {
11060 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
11061 "monitor interface up");
11062 return -2;
11063 }
11064
11065 return sta_inject_frame(dut, conn, frame, protected, NULL);
11066}
11067
11068
11069static int cmd_sta_set_parameter_hs2(struct sigma_dut *dut,
11070 struct sigma_conn *conn,
11071 struct sigma_cmd *cmd,
11072 const char *ifname)
11073{
11074 char buf[200];
11075 const char *val;
11076
11077 val = get_param(cmd, "ClearARP");
11078 if (val && atoi(val) == 1) {
11079 snprintf(buf, sizeof(buf), "ip neigh flush dev %s", ifname);
11080 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
11081 if (system(buf) != 0) {
11082 send_resp(dut, conn, SIGMA_ERROR,
11083 "errorCode,Failed to clear ARP cache");
11084 return 0;
11085 }
11086 }
11087
11088 return 1;
11089}
11090
11091
11092int cmd_sta_set_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
11093 struct sigma_cmd *cmd)
11094{
11095 const char *intf = get_param(cmd, "Interface");
11096 const char *val;
11097
11098 if (intf == NULL)
11099 return -1;
11100
11101 val = get_param(cmd, "program");
11102 if (val && (strcasecmp(val, "HS2") == 0 ||
Jouni Malinen1f6ae642018-06-07 23:56:13 +030011103 strcasecmp(val, "HS2-R2") == 0 ||
11104 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011105 return cmd_sta_set_parameter_hs2(dut, conn, cmd, intf);
11106
11107 return -1;
11108}
11109
11110
Jouni Malinenf7222712019-06-13 01:50:21 +030011111static enum sigma_cmd_result cmd_sta_set_macaddr(struct sigma_dut *dut,
11112 struct sigma_conn *conn,
11113 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011114{
11115 const char *intf = get_param(cmd, "Interface");
11116 const char *mac = get_param(cmd, "MAC");
11117
11118 if (intf == NULL || mac == NULL)
11119 return -1;
11120
11121 sigma_dut_print(dut, DUT_MSG_INFO, "Change local MAC address for "
11122 "interface %s to %s", intf, mac);
11123
11124 if (dut->set_macaddr) {
11125 char buf[128];
11126 int res;
11127 if (strcasecmp(mac, "default") == 0) {
11128 res = snprintf(buf, sizeof(buf), "%s",
11129 dut->set_macaddr);
11130 dut->tmp_mac_addr = 0;
11131 } else {
11132 res = snprintf(buf, sizeof(buf), "%s %s",
11133 dut->set_macaddr, mac);
11134 dut->tmp_mac_addr = 1;
11135 }
11136 if (res < 0 || res >= (int) sizeof(buf))
11137 return -1;
11138 if (system(buf) != 0) {
11139 send_resp(dut, conn, SIGMA_ERROR,
11140 "errorCode,Failed to set MAC "
11141 "address");
11142 return 0;
11143 }
11144 return 1;
11145 }
11146
11147 if (strcasecmp(mac, "default") == 0)
11148 return 1;
11149
11150 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
11151 "command");
11152 return 0;
11153}
11154
11155
11156static int iwpriv_tdlsoffchnmode(struct sigma_dut *dut,
11157 struct sigma_conn *conn, const char *intf,
11158 int val)
11159{
11160 char buf[200];
11161 int res;
11162
11163 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchnmode %d",
11164 intf, val);
11165 if (res < 0 || res >= (int) sizeof(buf))
11166 return -1;
11167 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
11168 if (system(buf) != 0) {
11169 send_resp(dut, conn, SIGMA_ERROR,
11170 "errorCode,Failed to configure offchannel mode");
11171 return 0;
11172 }
11173
11174 return 1;
11175}
11176
11177
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011178static int off_chan_val(enum sec_ch_offset off)
11179{
11180 switch (off) {
11181 case SEC_CH_NO:
11182 return 0;
11183 case SEC_CH_40ABOVE:
11184 return 40;
11185 case SEC_CH_40BELOW:
11186 return -40;
11187 }
11188
11189 return 0;
11190}
11191
11192
11193static int iwpriv_set_offchan(struct sigma_dut *dut, struct sigma_conn *conn,
11194 const char *intf, int off_ch_num,
11195 enum sec_ch_offset sec)
11196{
11197 char buf[200];
11198 int res;
11199
11200 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchan %d",
11201 intf, off_ch_num);
11202 if (res < 0 || res >= (int) sizeof(buf))
11203 return -1;
11204 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
11205 if (system(buf) != 0) {
11206 send_resp(dut, conn, SIGMA_ERROR,
11207 "errorCode,Failed to set offchan");
11208 return 0;
11209 }
11210
11211 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsecchnoffst %d",
11212 intf, off_chan_val(sec));
11213 if (res < 0 || res >= (int) sizeof(buf))
11214 return -1;
11215 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
11216 if (system(buf) != 0) {
11217 send_resp(dut, conn, SIGMA_ERROR,
11218 "errorCode,Failed to set sec chan offset");
11219 return 0;
11220 }
11221
11222 return 1;
11223}
11224
11225
11226static int tdls_set_offchannel_offset(struct sigma_dut *dut,
11227 struct sigma_conn *conn,
11228 const char *intf, int off_ch_num,
11229 enum sec_ch_offset sec)
11230{
11231 char buf[200];
11232 int res;
11233
11234 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNEL %d",
11235 off_ch_num);
11236 if (res < 0 || res >= (int) sizeof(buf))
11237 return -1;
11238 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
11239
11240 if (wpa_command(intf, buf) < 0) {
11241 send_resp(dut, conn, SIGMA_ERROR,
11242 "ErrorCode,Failed to set offchan");
11243 return 0;
11244 }
11245 res = snprintf(buf, sizeof(buf), "DRIVER TDLSSECONDARYCHANNELOFFSET %d",
11246 off_chan_val(sec));
11247 if (res < 0 || res >= (int) sizeof(buf))
11248 return -1;
11249
11250 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
11251
11252 if (wpa_command(intf, buf) < 0) {
11253 send_resp(dut, conn, SIGMA_ERROR,
11254 "ErrorCode,Failed to set sec chan offset");
11255 return 0;
11256 }
11257
11258 return 1;
11259}
11260
11261
11262static int tdls_set_offchannel_mode(struct sigma_dut *dut,
11263 struct sigma_conn *conn,
11264 const char *intf, int val)
11265{
11266 char buf[200];
11267 int res;
11268
11269 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNELMODE %d",
11270 val);
11271 if (res < 0 || res >= (int) sizeof(buf))
11272 return -1;
11273 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
11274
11275 if (wpa_command(intf, buf) < 0) {
11276 send_resp(dut, conn, SIGMA_ERROR,
11277 "ErrorCode,Failed to configure offchannel mode");
11278 return 0;
11279 }
11280
11281 return 1;
11282}
11283
11284
11285static int cmd_sta_set_rfeature_tdls(const char *intf, struct sigma_dut *dut,
11286 struct sigma_conn *conn,
11287 struct sigma_cmd *cmd)
11288{
11289 const char *val;
11290 enum {
11291 CHSM_NOT_SET,
11292 CHSM_ENABLE,
11293 CHSM_DISABLE,
11294 CHSM_REJREQ,
11295 CHSM_UNSOLRESP
11296 } chsm = CHSM_NOT_SET;
11297 int off_ch_num = -1;
11298 enum sec_ch_offset sec_ch = SEC_CH_NO;
11299 int res;
11300
11301 val = get_param(cmd, "Uapsd");
11302 if (val) {
11303 char buf[100];
11304 if (strcasecmp(val, "Enable") == 0)
11305 snprintf(buf, sizeof(buf), "SET ps 99");
11306 else if (strcasecmp(val, "Disable") == 0)
11307 snprintf(buf, sizeof(buf), "SET ps 98");
11308 else {
11309 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
11310 "Unsupported uapsd parameter value");
11311 return 0;
11312 }
11313 if (wpa_command(intf, buf)) {
11314 send_resp(dut, conn, SIGMA_ERROR,
11315 "ErrorCode,Failed to change U-APSD "
11316 "powersave mode");
11317 return 0;
11318 }
11319 }
11320
11321 val = get_param(cmd, "TPKTIMER");
11322 if (val && strcasecmp(val, "DISABLE") == 0) {
11323 if (wpa_command(intf, "SET tdls_testing 0x100")) {
11324 send_resp(dut, conn, SIGMA_ERROR,
11325 "ErrorCode,Failed to enable no TPK "
11326 "expiration test mode");
11327 return 0;
11328 }
11329 dut->no_tpk_expiration = 1;
11330 }
11331
11332 val = get_param(cmd, "ChSwitchMode");
11333 if (val) {
11334 if (strcasecmp(val, "Enable") == 0 ||
11335 strcasecmp(val, "Initiate") == 0)
11336 chsm = CHSM_ENABLE;
11337 else if (strcasecmp(val, "Disable") == 0 ||
11338 strcasecmp(val, "passive") == 0)
11339 chsm = CHSM_DISABLE;
11340 else if (strcasecmp(val, "RejReq") == 0)
11341 chsm = CHSM_REJREQ;
11342 else if (strcasecmp(val, "UnSolResp") == 0)
11343 chsm = CHSM_UNSOLRESP;
11344 else {
11345 send_resp(dut, conn, SIGMA_ERROR,
11346 "ErrorCode,Unknown ChSwitchMode value");
11347 return 0;
11348 }
11349 }
11350
11351 val = get_param(cmd, "OffChNum");
11352 if (val) {
11353 off_ch_num = atoi(val);
11354 if (off_ch_num == 0) {
11355 send_resp(dut, conn, SIGMA_ERROR,
11356 "ErrorCode,Invalid OffChNum");
11357 return 0;
11358 }
11359 }
11360
11361 val = get_param(cmd, "SecChOffset");
11362 if (val) {
11363 if (strcmp(val, "20") == 0)
11364 sec_ch = SEC_CH_NO;
11365 else if (strcasecmp(val, "40above") == 0)
11366 sec_ch = SEC_CH_40ABOVE;
11367 else if (strcasecmp(val, "40below") == 0)
11368 sec_ch = SEC_CH_40BELOW;
11369 else {
11370 send_resp(dut, conn, SIGMA_ERROR,
11371 "ErrorCode,Unknown SecChOffset value");
11372 return 0;
11373 }
11374 }
11375
11376 if (chsm == CHSM_NOT_SET) {
11377 /* no offchannel changes requested */
11378 return 1;
11379 }
11380
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011381 if (strcmp(intf, get_main_ifname(dut)) != 0 &&
11382 strcmp(intf, get_station_ifname(dut)) != 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011383 send_resp(dut, conn, SIGMA_ERROR,
11384 "ErrorCode,Unknown interface");
11385 return 0;
11386 }
11387
11388 switch (chsm) {
11389 case CHSM_NOT_SET:
Jouni Malinen280f5ba2016-08-29 21:33:10 +030011390 res = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011391 break;
11392 case CHSM_ENABLE:
11393 if (off_ch_num < 0) {
11394 send_resp(dut, conn, SIGMA_ERROR,
11395 "ErrorCode,Missing OffChNum argument");
11396 return 0;
11397 }
11398 if (wifi_chip_type == DRIVER_WCN) {
11399 res = tdls_set_offchannel_offset(dut, conn, intf,
11400 off_ch_num, sec_ch);
11401 } else {
11402 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
11403 sec_ch);
11404 }
11405 if (res != 1)
11406 return res;
11407 if (wifi_chip_type == DRIVER_WCN)
11408 res = tdls_set_offchannel_mode(dut, conn, intf, 1);
11409 else
11410 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 1);
11411 break;
11412 case CHSM_DISABLE:
11413 if (wifi_chip_type == DRIVER_WCN)
11414 res = tdls_set_offchannel_mode(dut, conn, intf, 2);
11415 else
11416 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 2);
11417 break;
11418 case CHSM_REJREQ:
11419 if (wifi_chip_type == DRIVER_WCN)
11420 res = tdls_set_offchannel_mode(dut, conn, intf, 3);
11421 else
11422 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 3);
11423 break;
11424 case CHSM_UNSOLRESP:
11425 if (off_ch_num < 0) {
11426 send_resp(dut, conn, SIGMA_ERROR,
11427 "ErrorCode,Missing OffChNum argument");
11428 return 0;
11429 }
11430 if (wifi_chip_type == DRIVER_WCN) {
11431 res = tdls_set_offchannel_offset(dut, conn, intf,
11432 off_ch_num, sec_ch);
11433 } else {
11434 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
11435 sec_ch);
11436 }
11437 if (res != 1)
11438 return res;
11439 if (wifi_chip_type == DRIVER_WCN)
11440 res = tdls_set_offchannel_mode(dut, conn, intf, 4);
11441 else
11442 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 4);
11443 break;
11444 }
11445
11446 return res;
11447}
11448
11449
11450static int ath_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
11451 struct sigma_conn *conn,
11452 struct sigma_cmd *cmd)
11453{
11454 const char *val;
Srikanth Marepalli5415acf2018-08-27 12:53:11 +053011455 char *token = NULL, *result;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011456
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -070011457 novap_reset(dut, intf, 1);
priyadharshini gowthamane5e25172015-12-08 14:53:48 -080011458
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011459 val = get_param(cmd, "nss_mcs_opt");
11460 if (val) {
11461 /* String (nss_operating_mode; mcs_operating_mode) */
11462 int nss, mcs;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053011463 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011464
11465 token = strdup(val);
11466 if (!token)
11467 return 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053011468 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +053011469 if (!result) {
11470 sigma_dut_print(dut, DUT_MSG_ERROR,
11471 "VHT NSS not specified");
11472 goto failed;
11473 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011474 if (strcasecmp(result, "def") != 0) {
11475 nss = atoi(result);
11476 if (nss == 4)
11477 ath_disable_txbf(dut, intf);
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011478 if (run_iwpriv(dut, intf, "nss %d", nss) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011479 goto failed;
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011480
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011481 }
11482
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053011483 result = strtok_r(NULL, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +053011484 if (!result) {
11485 sigma_dut_print(dut, DUT_MSG_ERROR,
11486 "VHT MCS not specified");
11487 goto failed;
11488 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011489 if (strcasecmp(result, "def") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011490 if (run_iwpriv(dut, intf, "set11NRates 0") < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011491 goto failed;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011492 } else {
11493 mcs = atoi(result);
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011494 if (run_iwpriv(dut, intf, "vhtmcs %d", mcs) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011495 goto failed;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011496 }
11497 /* Channel width gets messed up, fix this */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011498 run_iwpriv(dut, intf, "chwidth %d", dut->chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011499 }
11500
Srikanth Marepalli5415acf2018-08-27 12:53:11 +053011501 free(token);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011502 return 1;
11503failed:
11504 free(token);
11505 return 0;
11506}
11507
11508
11509static int cmd_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
11510 struct sigma_conn *conn,
11511 struct sigma_cmd *cmd)
11512{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011513 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011514 case DRIVER_ATHEROS:
11515 return ath_sta_set_rfeature_vht(intf, dut, conn, cmd);
11516 default:
11517 send_resp(dut, conn, SIGMA_ERROR,
11518 "errorCode,Unsupported sta_set_rfeature(VHT) with the current driver");
11519 return 0;
11520 }
11521}
11522
11523
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011524static int wcn_sta_set_rfeature_he(const char *intf, struct sigma_dut *dut,
11525 struct sigma_conn *conn,
11526 struct sigma_cmd *cmd)
11527{
11528 const char *val;
11529 char *token = NULL, *result;
11530 char buf[60];
11531
11532 val = get_param(cmd, "nss_mcs_opt");
11533 if (val) {
11534 /* String (nss_operating_mode; mcs_operating_mode) */
11535 int nss, mcs, ratecode;
11536 char *saveptr;
11537
11538 token = strdup(val);
11539 if (!token)
11540 return -2;
11541
11542 result = strtok_r(token, ";", &saveptr);
11543 if (!result) {
11544 sigma_dut_print(dut, DUT_MSG_ERROR,
11545 "HE NSS not specified");
11546 goto failed;
11547 }
11548 nss = 1;
11549 if (strcasecmp(result, "def") != 0)
11550 nss = atoi(result);
11551
11552 result = strtok_r(NULL, ";", &saveptr);
11553 if (!result) {
11554 sigma_dut_print(dut, DUT_MSG_ERROR,
11555 "HE MCS not specified");
11556 goto failed;
11557 }
11558 mcs = 7;
11559 if (strcasecmp(result, "def") != 0)
11560 mcs = atoi(result);
11561
Arif Hussain557bf412018-05-25 17:29:36 -070011562 ratecode = 0x20; /* for nss:1 MCS 0 */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011563 if (nss == 2) {
Arif Hussain557bf412018-05-25 17:29:36 -070011564 ratecode = 0x40; /* for nss:2 MCS 0 */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011565 } else if (nss > 2) {
11566 sigma_dut_print(dut, DUT_MSG_ERROR,
11567 "HE NSS %d not supported", nss);
11568 goto failed;
11569 }
11570
Arif Hussain557bf412018-05-25 17:29:36 -070011571 snprintf(buf, sizeof(buf), "iwpriv %s nss %d", intf, nss);
11572 if (system(buf) != 0) {
11573 sigma_dut_print(dut, DUT_MSG_ERROR,
11574 "nss_mcs_opt: iwpriv %s nss %d failed",
11575 intf, nss);
11576 goto failed;
11577 }
Arif Hussainac6c5112018-05-25 17:34:00 -070011578 dut->sta_nss = nss;
Arif Hussain557bf412018-05-25 17:29:36 -070011579
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011580 /* Add the MCS to the ratecode */
11581 if (mcs >= 0 && mcs <= 11) {
11582 ratecode += mcs;
Arif Hussain557bf412018-05-25 17:29:36 -070011583#ifdef NL80211_SUPPORT
11584 if (dut->device_type == STA_testbed) {
11585 enum he_mcs_config mcs_config;
11586 int ret;
11587
11588 if (mcs <= 7)
11589 mcs_config = HE_80_MCS0_7;
11590 else if (mcs <= 9)
11591 mcs_config = HE_80_MCS0_9;
11592 else
11593 mcs_config = HE_80_MCS0_11;
11594 ret = sta_set_he_mcs(dut, intf, mcs_config);
11595 if (ret) {
11596 sigma_dut_print(dut, DUT_MSG_ERROR,
11597 "nss_mcs_opt: mcs setting failed, mcs:%d, mcs_config %d, ret:%d",
11598 mcs, mcs_config, ret);
11599 goto failed;
11600 }
11601 }
11602#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011603 } else {
11604 sigma_dut_print(dut, DUT_MSG_ERROR,
11605 "HE MCS %d not supported", mcs);
11606 goto failed;
11607 }
11608 snprintf(buf, sizeof(buf), "iwpriv %s set_11ax_rate 0x%03x",
11609 intf, ratecode);
11610 if (system(buf) != 0) {
11611 sigma_dut_print(dut, DUT_MSG_ERROR,
11612 "iwpriv setting of 11ax rates failed");
11613 goto failed;
11614 }
11615 free(token);
11616 }
11617
11618 val = get_param(cmd, "GI");
11619 if (val) {
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011620 int fix_rate_sgi;
11621
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011622 if (strcmp(val, "0.8") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070011623 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 9", intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011624 fix_rate_sgi = 1;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011625 } else if (strcmp(val, "1.6") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070011626 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 10",
11627 intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011628 fix_rate_sgi = 2;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011629 } else if (strcmp(val, "3.2") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070011630 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 11",
11631 intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011632 fix_rate_sgi = 3;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011633 } else {
11634 send_resp(dut, conn, SIGMA_ERROR,
11635 "errorCode,GI value not supported");
11636 return 0;
11637 }
11638 if (system(buf) != 0) {
11639 send_resp(dut, conn, SIGMA_ERROR,
11640 "errorCode,Failed to set shortgi");
11641 return 0;
11642 }
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011643 snprintf(buf, sizeof(buf), "iwpriv %s shortgi %d",
11644 intf, fix_rate_sgi);
11645 if (system(buf) != 0) {
11646 send_resp(dut, conn, SIGMA_ERROR,
11647 "errorCode,Failed to set fix rate shortgi");
11648 return STATUS_SENT;
11649 }
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011650 }
11651
Subhani Shaik8e7a3052018-04-24 14:03:00 -070011652 val = get_param(cmd, "LTF");
11653 if (val) {
11654#ifdef NL80211_SUPPORT
11655 if (strcmp(val, "3.2") == 0) {
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -080011656 wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_1X);
Subhani Shaik8e7a3052018-04-24 14:03:00 -070011657 } if (strcmp(val, "6.4") == 0) {
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -080011658 wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_2X);
Subhani Shaik8e7a3052018-04-24 14:03:00 -070011659 } else if (strcmp(val, "12.8") == 0) {
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -080011660 wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_4X);
Subhani Shaik8e7a3052018-04-24 14:03:00 -070011661 } else {
11662 send_resp(dut, conn, SIGMA_ERROR,
11663 "errorCode, LTF value not supported");
11664 return 0;
11665 }
11666#else /* NL80211_SUPPORT */
11667 sigma_dut_print(dut, DUT_MSG_ERROR,
11668 "LTF cannot be set without NL80211_SUPPORT defined");
11669 return -2;
11670#endif /* NL80211_SUPPORT */
11671 }
11672
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -070011673 val = get_param(cmd, "TxSUPPDU");
11674 if (val) {
11675 int set_val = 1;
11676
11677 if (strcasecmp(val, "Enable") == 0)
11678 set_val = 1;
11679 else if (strcasecmp(val, "Disable") == 0)
11680 set_val = 0;
11681
11682 if (sta_set_tx_su_ppdu_cfg(dut, intf, set_val)) {
11683 send_resp(dut, conn, SIGMA_ERROR,
11684 "ErrorCode,Failed to set Tx SU PPDU config");
11685 return 0;
11686 }
11687 }
11688
Arif Hussain480d5f42019-03-12 14:40:42 -070011689 val = get_param(cmd, "TWT_Setup");
11690 if (val) {
11691 if (strcasecmp(val, "Request") == 0) {
11692 if (sta_twt_request(dut, conn, cmd)) {
11693 send_resp(dut, conn, SIGMA_ERROR,
11694 "ErrorCode,sta_twt_request failed");
11695 return STATUS_SENT;
11696 }
11697 } else if (strcasecmp(val, "Teardown") == 0) {
11698 if (sta_twt_teardown(dut, conn, cmd)) {
11699 send_resp(dut, conn, SIGMA_ERROR,
11700 "ErrorCode,sta_twt_teardown failed");
11701 return STATUS_SENT;
11702 }
11703 }
11704 }
11705
Kiran Kumar Lokere50eb2cd2018-12-18 18:31:28 -080011706 val = get_param(cmd, "transmitOMI");
11707 if (val && sta_transmit_omi(dut, conn, cmd)) {
11708 send_resp(dut, conn, SIGMA_ERROR,
11709 "ErrorCode,sta_transmit_omi failed");
11710 return STATUS_SENT;
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -070011711 }
11712
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080011713 val = get_param(cmd, "Powersave");
11714 if (val) {
11715 char buf[60];
11716
11717 if (strcasecmp(val, "off") == 0) {
11718 snprintf(buf, sizeof(buf),
11719 "iwpriv %s setPower 2", intf);
11720 if (system(buf) != 0) {
11721 sigma_dut_print(dut, DUT_MSG_ERROR,
11722 "iwpriv setPower 2 failed");
11723 return 0;
11724 }
11725 } else if (strcasecmp(val, "on") == 0) {
11726 snprintf(buf, sizeof(buf),
11727 "iwpriv %s setPower 1", intf);
11728 if (system(buf) != 0) {
11729 sigma_dut_print(dut, DUT_MSG_ERROR,
11730 "iwpriv setPower 1 failed");
11731 return 0;
11732 }
11733 } else {
11734 sigma_dut_print(dut, DUT_MSG_ERROR,
11735 "Unsupported Powersave value '%s'",
11736 val);
11737 return -1;
11738 }
11739 }
11740
Kiran Kumar Lokere2c4b7ce2019-01-30 12:02:28 -080011741 val = get_param(cmd, "MU_EDCA");
11742 if (val) {
11743 if (strcasecmp(val, "Override") == 0) {
11744 if (sta_set_mu_edca_override(dut, intf, 1)) {
11745 send_resp(dut, conn, SIGMA_ERROR,
11746 "errorCode,MU EDCA override set failed");
11747 return STATUS_SENT;
11748 }
11749 } else if (strcasecmp(val, "Disable") == 0) {
11750 if (sta_set_mu_edca_override(dut, intf, 0)) {
11751 send_resp(dut, conn, SIGMA_ERROR,
11752 "errorCode,MU EDCA override disable failed");
11753 return STATUS_SENT;
11754 }
11755 }
11756 }
11757
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011758 return 1;
11759
11760failed:
11761 free(token);
11762 return -2;
11763}
11764
11765
11766static int cmd_sta_set_rfeature_he(const char *intf, struct sigma_dut *dut,
11767 struct sigma_conn *conn,
11768 struct sigma_cmd *cmd)
11769{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011770 switch (get_driver_type(dut)) {
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011771 case DRIVER_WCN:
11772 return wcn_sta_set_rfeature_he(intf, dut, conn, cmd);
11773 default:
11774 send_resp(dut, conn, SIGMA_ERROR,
11775 "errorCode,Unsupported sta_set_rfeature(HE) with the current driver");
11776 return 0;
11777 }
11778}
11779
11780
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080011781static int cmd_sta_set_power_save_he(const char *intf, struct sigma_dut *dut,
11782 struct sigma_conn *conn,
11783 struct sigma_cmd *cmd)
11784{
11785 const char *val;
11786
11787 val = get_param(cmd, "powersave");
11788 if (val) {
11789 char buf[60];
11790
11791 if (strcasecmp(val, "off") == 0) {
11792 snprintf(buf, sizeof(buf), "iwpriv %s setPower 2",
11793 intf);
11794 if (system(buf) != 0) {
11795 sigma_dut_print(dut, DUT_MSG_ERROR,
11796 "iwpriv setPower 2 failed");
11797 return 0;
11798 }
11799 } else if (strcasecmp(val, "on") == 0) {
11800 snprintf(buf, sizeof(buf), "iwpriv %s setPower 1",
11801 intf);
11802 if (system(buf) != 0) {
11803 sigma_dut_print(dut, DUT_MSG_ERROR,
11804 "iwpriv setPower 1 failed");
11805 return 0;
11806 }
11807 } else {
11808 sigma_dut_print(dut, DUT_MSG_ERROR,
11809 "Unsupported power save config");
11810 return -1;
11811 }
11812 return 1;
11813 }
11814
11815 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported command");
11816
11817 return 0;
11818}
11819
11820
Ashwini Patil5acd7382017-04-13 15:55:04 +053011821static int btm_query_candidate_list(struct sigma_dut *dut,
11822 struct sigma_conn *conn,
11823 struct sigma_cmd *cmd)
11824{
11825 const char *bssid, *info, *op_class, *ch, *phy_type, *pref;
11826 int len, ret;
11827 char buf[10];
11828
11829 /*
11830 * Neighbor Report elements format:
11831 * neighbor=<BSSID>,<BSSID Information>,<Operating Class>,
11832 * <Channel Number>,<PHY Type>[,<hexdump of Optional Subelements>]
11833 * eg: neighbor=aa:bb:cc:dd:ee:ff,17,81,6,1,030101
11834 */
11835
11836 bssid = get_param(cmd, "Nebor_BSSID");
11837 if (!bssid) {
11838 send_resp(dut, conn, SIGMA_INVALID,
11839 "errorCode,Nebor_BSSID is missing");
11840 return 0;
11841 }
11842
11843 info = get_param(cmd, "Nebor_Bssid_Info");
11844 if (!info) {
11845 sigma_dut_print(dut, DUT_MSG_INFO,
11846 "Using default value for Nebor_Bssid_Info: %s",
11847 DEFAULT_NEIGHBOR_BSSID_INFO);
11848 info = DEFAULT_NEIGHBOR_BSSID_INFO;
11849 }
11850
11851 op_class = get_param(cmd, "Nebor_Op_Class");
11852 if (!op_class) {
11853 send_resp(dut, conn, SIGMA_INVALID,
11854 "errorCode,Nebor_Op_Class is missing");
11855 return 0;
11856 }
11857
11858 ch = get_param(cmd, "Nebor_Op_Ch");
11859 if (!ch) {
11860 send_resp(dut, conn, SIGMA_INVALID,
11861 "errorCode,Nebor_Op_Ch is missing");
11862 return 0;
11863 }
11864
11865 phy_type = get_param(cmd, "Nebor_Phy_Type");
11866 if (!phy_type) {
11867 sigma_dut_print(dut, DUT_MSG_INFO,
11868 "Using default value for Nebor_Phy_Type: %s",
11869 DEFAULT_NEIGHBOR_PHY_TYPE);
11870 phy_type = DEFAULT_NEIGHBOR_PHY_TYPE;
11871 }
11872
11873 /* Parse optional subelements */
11874 buf[0] = '\0';
11875 pref = get_param(cmd, "Nebor_Pref");
11876 if (pref) {
11877 /* hexdump for preferrence subelement */
11878 ret = snprintf(buf, sizeof(buf), ",0301%02x", atoi(pref));
11879 if (ret < 0 || ret >= (int) sizeof(buf)) {
11880 sigma_dut_print(dut, DUT_MSG_ERROR,
11881 "snprintf failed for optional subelement ret: %d",
11882 ret);
11883 send_resp(dut, conn, SIGMA_ERROR,
11884 "errorCode,snprintf failed for subelement");
11885 return 0;
11886 }
11887 }
11888
11889 if (!dut->btm_query_cand_list) {
11890 dut->btm_query_cand_list = calloc(1, NEIGHBOR_REPORT_SIZE);
11891 if (!dut->btm_query_cand_list) {
11892 send_resp(dut, conn, SIGMA_ERROR,
11893 "errorCode,Failed to allocate memory for btm_query_cand_list");
11894 return 0;
11895 }
11896 }
11897
11898 len = strlen(dut->btm_query_cand_list);
11899 ret = snprintf(dut->btm_query_cand_list + len,
11900 NEIGHBOR_REPORT_SIZE - len, " neighbor=%s,%s,%s,%s,%s%s",
11901 bssid, info, op_class, ch, phy_type, buf);
11902 if (ret < 0 || ret >= NEIGHBOR_REPORT_SIZE - len) {
11903 sigma_dut_print(dut, DUT_MSG_ERROR,
11904 "snprintf failed for neighbor report list ret: %d",
11905 ret);
11906 send_resp(dut, conn, SIGMA_ERROR,
11907 "errorCode,snprintf failed for neighbor report");
11908 free(dut->btm_query_cand_list);
11909 dut->btm_query_cand_list = NULL;
11910 return 0;
11911 }
11912
11913 return 1;
11914}
11915
11916
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020011917int sta_extract_60g_ese(struct sigma_dut *dut, struct sigma_cmd *cmd,
11918 struct sigma_ese_alloc *allocs, int *allocs_size)
11919{
11920 int max_count = *allocs_size;
11921 int count = 0, i;
11922 const char *val;
11923
11924 do {
11925 val = get_param_indexed(cmd, "AllocID", count);
11926 if (val)
11927 count++;
11928 } while (val);
11929
11930 if (count == 0 || count > max_count) {
11931 sigma_dut_print(dut, DUT_MSG_ERROR,
11932 "Invalid number of allocations(%d)", count);
11933 return -1;
11934 }
11935
11936 for (i = 0; i < count; i++) {
11937 val = get_param_indexed(cmd, "PercentBI", i);
11938 if (!val) {
11939 sigma_dut_print(dut, DUT_MSG_ERROR,
11940 "Missing PercentBI parameter at index %d",
11941 i);
11942 return -1;
11943 }
11944 allocs[i].percent_bi = atoi(val);
11945
11946 val = get_param_indexed(cmd, "SrcAID", i);
11947 if (val)
11948 allocs[i].src_aid = strtol(val, NULL, 0);
11949 else
11950 allocs[i].src_aid = ESE_BCAST_AID;
11951
11952 val = get_param_indexed(cmd, "DestAID", i);
11953 if (val)
11954 allocs[i].dst_aid = strtol(val, NULL, 0);
11955 else
11956 allocs[i].dst_aid = ESE_BCAST_AID;
11957
11958 allocs[i].type = ESE_CBAP;
11959 sigma_dut_print(dut, DUT_MSG_INFO,
11960 "Alloc %d PercentBI %d SrcAID %d DstAID %d",
11961 i, allocs[i].percent_bi, allocs[i].src_aid,
11962 allocs[i].dst_aid);
11963 }
11964
11965 *allocs_size = count;
11966 return 0;
11967}
11968
11969
11970static int sta_set_60g_ese(struct sigma_dut *dut, int count,
11971 struct sigma_ese_alloc *allocs)
11972{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011973 switch (get_driver_type(dut)) {
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020011974#ifdef __linux__
11975 case DRIVER_WIL6210:
11976 if (wil6210_set_ese(dut, count, allocs))
11977 return -1;
11978 return 1;
11979#endif /* __linux__ */
11980 default:
11981 sigma_dut_print(dut, DUT_MSG_ERROR,
11982 "Unsupported sta_set_60g_ese with the current driver");
11983 return -1;
11984 }
11985}
11986
11987
11988static int cmd_sta_set_rfeature_60g(const char *intf, struct sigma_dut *dut,
11989 struct sigma_conn *conn,
11990 struct sigma_cmd *cmd)
11991{
11992 const char *val;
11993
11994 val = get_param(cmd, "ExtSchIE");
11995 if (val && !strcasecmp(val, "Enable")) {
11996 struct sigma_ese_alloc allocs[MAX_ESE_ALLOCS];
11997 int count = MAX_ESE_ALLOCS;
11998
11999 if (sta_extract_60g_ese(dut, cmd, allocs, &count))
12000 return -1;
12001 return sta_set_60g_ese(dut, count, allocs);
12002 }
12003
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +020012004 val = get_param(cmd, "MCS_FixedRate");
12005 if (val) {
12006 int sta_mcs = atoi(val);
12007
12008 sigma_dut_print(dut, DUT_MSG_INFO, "Force STA MCS to %d",
12009 sta_mcs);
12010 wil6210_set_force_mcs(dut, 1, sta_mcs);
12011
Jouni Malinen0e29cf22019-02-19 01:13:21 +020012012 return SUCCESS_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +020012013 }
12014
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020012015 send_resp(dut, conn, SIGMA_ERROR,
12016 "errorCode,Invalid sta_set_rfeature(60G)");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020012017 return STATUS_SENT;
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020012018}
12019
12020
Jouni Malinenf7222712019-06-13 01:50:21 +030012021static enum sigma_cmd_result cmd_sta_set_rfeature(struct sigma_dut *dut,
12022 struct sigma_conn *conn,
12023 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012024{
12025 const char *intf = get_param(cmd, "Interface");
12026 const char *prog = get_param(cmd, "Prog");
Ashwini Patil68d02cd2017-01-10 15:39:16 +053012027 const char *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012028
12029 if (intf == NULL || prog == NULL)
12030 return -1;
12031
Ashwini Patil5acd7382017-04-13 15:55:04 +053012032 /* BSS Transition candidate list for BTM query */
12033 val = get_param(cmd, "Nebor_BSSID");
12034 if (val && btm_query_candidate_list(dut, conn, cmd) == 0)
12035 return 0;
12036
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012037 if (strcasecmp(prog, "TDLS") == 0)
12038 return cmd_sta_set_rfeature_tdls(intf, dut, conn, cmd);
12039
12040 if (strcasecmp(prog, "VHT") == 0)
12041 return cmd_sta_set_rfeature_vht(intf, dut, conn, cmd);
12042
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080012043 if (strcasecmp(prog, "HE") == 0)
12044 return cmd_sta_set_rfeature_he(intf, dut, conn, cmd);
12045
Ashwini Patil68d02cd2017-01-10 15:39:16 +053012046 if (strcasecmp(prog, "MBO") == 0) {
12047 val = get_param(cmd, "Cellular_Data_Cap");
12048 if (val &&
12049 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
12050 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +053012051
12052 val = get_param(cmd, "Ch_Pref");
12053 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
12054 return 0;
12055
Ashwini Patil68d02cd2017-01-10 15:39:16 +053012056 return 1;
12057 }
12058
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020012059 if (strcasecmp(prog, "60GHz") == 0)
12060 return cmd_sta_set_rfeature_60g(intf, dut, conn, cmd);
12061
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012062 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported Prog");
12063 return 0;
12064}
12065
12066
Jouni Malinenf7222712019-06-13 01:50:21 +030012067static enum sigma_cmd_result cmd_sta_set_radio(struct sigma_dut *dut,
12068 struct sigma_conn *conn,
12069 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012070{
12071 const char *intf = get_param(cmd, "Interface");
12072 const char *mode = get_param(cmd, "Mode");
12073 int res;
12074
12075 if (intf == NULL || mode == NULL)
12076 return -1;
12077
12078 if (strcasecmp(mode, "On") == 0)
12079 res = wpa_command(intf, "SET radio_disabled 0");
12080 else if (strcasecmp(mode, "Off") == 0)
12081 res = wpa_command(intf, "SET radio_disabled 1");
12082 else
12083 return -1;
12084
12085 if (res) {
12086 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
12087 "radio mode");
12088 return 0;
12089 }
12090
12091 return 1;
12092}
12093
12094
Jouni Malinenf7222712019-06-13 01:50:21 +030012095static enum sigma_cmd_result cmd_sta_set_pwrsave(struct sigma_dut *dut,
12096 struct sigma_conn *conn,
12097 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012098{
12099 const char *intf = get_param(cmd, "Interface");
12100 const char *mode = get_param(cmd, "Mode");
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020012101 const char *prog = get_param(cmd, "program");
12102 const char *powersave = get_param(cmd, "powersave");
12103 int res = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012104
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020012105 if (intf == NULL)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012106 return -1;
12107
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020012108 if (prog && strcasecmp(prog, "60GHz") == 0) {
12109 /*
12110 * The CAPI mode parameter does not exist in 60G
12111 * unscheduled PS.
12112 */
Hu Wang5dc3ff12019-06-14 15:14:26 +080012113 if (powersave && strcasecmp(powersave, "unscheduled") == 0)
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020012114 res = set_ps(intf, dut, 1);
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012115 } else if (prog && get_driver_type(dut) == DRIVER_WCN &&
Alexei Avshalom Lazar2f6fdb42019-02-04 14:16:08 +020012116 strcasecmp(prog, "HE") == 0) {
12117 return cmd_sta_set_power_save_he(intf, dut, conn, cmd);
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020012118 } else {
12119 if (mode == NULL)
12120 return -1;
12121
12122 if (strcasecmp(mode, "On") == 0)
12123 res = set_ps(intf, dut, 1);
12124 else if (strcasecmp(mode, "Off") == 0)
12125 res = set_ps(intf, dut, 0);
12126 else
12127 return -1;
12128 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012129
12130 if (res) {
12131 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
12132 "power save mode");
12133 return 0;
12134 }
12135
12136 return 1;
12137}
12138
12139
Jouni Malinenf7222712019-06-13 01:50:21 +030012140static enum sigma_cmd_result cmd_sta_bssid_pool(struct sigma_dut *dut,
12141 struct sigma_conn *conn,
12142 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012143{
12144 const char *intf = get_param(cmd, "Interface");
12145 const char *val, *bssid;
12146 int res;
12147 char *buf;
12148 size_t buf_len;
12149
12150 val = get_param(cmd, "BSSID_FILTER");
12151 if (val == NULL)
12152 return -1;
12153
12154 bssid = get_param(cmd, "BSSID_List");
12155 if (atoi(val) == 0 || bssid == NULL) {
12156 /* Disable BSSID filter */
12157 if (wpa_command(intf, "SET bssid_filter ")) {
12158 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed "
12159 "to disable BSSID filter");
12160 return 0;
12161 }
12162
12163 return 1;
12164 }
12165
12166 buf_len = 100 + strlen(bssid);
12167 buf = malloc(buf_len);
12168 if (buf == NULL)
12169 return -1;
12170
12171 snprintf(buf, buf_len, "SET bssid_filter %s", bssid);
12172 res = wpa_command(intf, buf);
12173 free(buf);
12174 if (res) {
12175 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to enable "
12176 "BSSID filter");
12177 return 0;
12178 }
12179
12180 return 1;
12181}
12182
12183
Jouni Malinenf7222712019-06-13 01:50:21 +030012184static enum sigma_cmd_result cmd_sta_reset_parm(struct sigma_dut *dut,
12185 struct sigma_conn *conn,
12186 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012187{
12188 const char *intf = get_param(cmd, "Interface");
12189 const char *val;
12190
12191 /* TODO: ARP */
12192
12193 val = get_param(cmd, "HS2_CACHE_PROFILE");
12194 if (val && strcasecmp(val, "All") == 0)
12195 hs2_clear_credentials(intf);
12196
12197 return 1;
12198}
12199
12200
Jouni Malinenf7222712019-06-13 01:50:21 +030012201static enum sigma_cmd_result cmd_sta_get_key(struct sigma_dut *dut,
12202 struct sigma_conn *conn,
12203 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012204{
12205 const char *intf = get_param(cmd, "Interface");
12206 const char *key_type = get_param(cmd, "KeyType");
12207 char buf[100], resp[200];
12208
12209 if (key_type == NULL)
12210 return -1;
12211
12212 if (strcasecmp(key_type, "GTK") == 0) {
12213 if (wpa_command_resp(intf, "GET gtk", buf, sizeof(buf)) < 0 ||
12214 strncmp(buf, "FAIL", 4) == 0) {
12215 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12216 "not fetch current GTK");
12217 return 0;
12218 }
12219 snprintf(resp, sizeof(resp), "KeyValue,%s", buf);
12220 send_resp(dut, conn, SIGMA_COMPLETE, resp);
12221 return 0;
12222 } else {
12223 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
12224 "KeyType");
12225 return 0;
12226 }
12227
12228 return 1;
12229}
12230
12231
12232static int hs2_set_policy(struct sigma_dut *dut)
12233{
12234#ifdef ANDROID
12235 system("ip rule del prio 23000");
12236 if (system("ip rule add from all lookup main prio 23000") != 0) {
12237 sigma_dut_print(dut, DUT_MSG_ERROR,
12238 "Failed to run:ip rule add from all lookup main prio");
12239 return -1;
12240 }
12241 if (system("ip route flush cache") != 0) {
12242 sigma_dut_print(dut, DUT_MSG_ERROR,
12243 "Failed to run ip route flush cache");
12244 return -1;
12245 }
12246 return 1;
12247#else /* ANDROID */
12248 return 0;
12249#endif /* ANDROID */
12250}
12251
12252
Jouni Malinenf7222712019-06-13 01:50:21 +030012253static enum sigma_cmd_result cmd_sta_hs2_associate(struct sigma_dut *dut,
12254 struct sigma_conn *conn,
12255 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012256{
12257 const char *intf = get_param(cmd, "Interface");
12258 const char *val = get_param(cmd, "Ignore_blacklist");
Jouni Malinen439352d2018-09-13 03:42:23 +030012259 const char *band = get_param(cmd, "Band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012260 struct wpa_ctrl *ctrl;
Jouni Malinen3aa72862019-05-29 23:14:51 +030012261 int res, r;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012262 char bssid[20], ssid[40], resp[100], buf[100], blacklisted[100];
12263 int tries = 0;
12264 int ignore_blacklist = 0;
12265 const char *events[] = {
12266 "CTRL-EVENT-CONNECTED",
12267 "INTERWORKING-BLACKLISTED",
12268 "INTERWORKING-NO-MATCH",
12269 NULL
12270 };
12271
12272 start_sta_mode(dut);
12273
Jouni Malinen439352d2018-09-13 03:42:23 +030012274 if (band) {
12275 if (strcmp(band, "2.4") == 0) {
12276 wpa_command(intf, "SET setband 2G");
12277 } else if (strcmp(band, "5") == 0) {
12278 wpa_command(intf, "SET setband 5G");
12279 } else {
12280 send_resp(dut, conn, SIGMA_ERROR,
12281 "errorCode,Unsupported band");
12282 return 0;
12283 }
12284 }
12285
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012286 blacklisted[0] = '\0';
12287 if (val && atoi(val))
12288 ignore_blacklist = 1;
12289
12290try_again:
12291 ctrl = open_wpa_mon(intf);
12292 if (ctrl == NULL) {
12293 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
12294 "wpa_supplicant monitor connection");
12295 return -2;
12296 }
12297
12298 tries++;
12299 if (wpa_command(intf, "INTERWORKING_SELECT auto")) {
12300 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start "
12301 "Interworking connection");
12302 wpa_ctrl_detach(ctrl);
12303 wpa_ctrl_close(ctrl);
12304 return 0;
12305 }
12306
12307 buf[0] = '\0';
12308 while (1) {
12309 char *pos;
12310 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
12311 pos = strstr(buf, "INTERWORKING-BLACKLISTED");
12312 if (!pos)
12313 break;
12314 pos += 25;
12315 sigma_dut_print(dut, DUT_MSG_DEBUG, "Found blacklisted AP: %s",
12316 pos);
12317 if (!blacklisted[0])
12318 memcpy(blacklisted, pos, strlen(pos) + 1);
12319 }
12320
12321 if (ignore_blacklist && blacklisted[0]) {
12322 char *end;
12323 end = strchr(blacklisted, ' ');
12324 if (end)
12325 *end = '\0';
12326 sigma_dut_print(dut, DUT_MSG_DEBUG, "Try to connect to a blacklisted network: %s",
12327 blacklisted);
Jouni Malinen3aa72862019-05-29 23:14:51 +030012328 r = snprintf(buf, sizeof(buf), "INTERWORKING_CONNECT %s",
12329 blacklisted);
12330 if (r < 0 || r >= sizeof(buf) || wpa_command(intf, buf)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012331 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start Interworking connection to blacklisted network");
12332 wpa_ctrl_detach(ctrl);
12333 wpa_ctrl_close(ctrl);
12334 return 0;
12335 }
12336 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
12337 buf, sizeof(buf));
12338 }
12339
12340 wpa_ctrl_detach(ctrl);
12341 wpa_ctrl_close(ctrl);
12342
12343 if (res < 0) {
12344 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
12345 "connect");
12346 return 0;
12347 }
12348
12349 if (strstr(buf, "INTERWORKING-NO-MATCH") ||
12350 strstr(buf, "INTERWORKING-BLACKLISTED")) {
12351 if (tries < 2) {
12352 sigma_dut_print(dut, DUT_MSG_INFO, "No match found - try again to verify no APs were missed in the scan");
12353 goto try_again;
12354 }
12355 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,No network with "
12356 "matching credentials found");
12357 return 0;
12358 }
12359
12360 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
12361 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
12362 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
12363 "get current BSSID/SSID");
12364 return 0;
12365 }
12366
12367 snprintf(resp, sizeof(resp), "SSID,%s,BSSID,%s", ssid, bssid);
12368 send_resp(dut, conn, SIGMA_COMPLETE, resp);
12369 hs2_set_policy(dut);
12370 return 0;
12371}
12372
12373
Jouni Malinenf7222712019-06-13 01:50:21 +030012374static enum sigma_cmd_result cmd_sta_hs2_venue_info(struct sigma_dut *dut,
12375 struct sigma_conn *conn,
12376 struct sigma_cmd *cmd)
Jouni Malinenb639f1c2018-09-13 02:39:46 +030012377{
12378 const char *intf = get_param(cmd, "Interface");
12379 const char *display = get_param(cmd, "Display");
12380 struct wpa_ctrl *ctrl;
12381 char buf[300], params[400], *pos;
12382 char bssid[20];
12383 int info_avail = 0;
12384 unsigned int old_timeout;
12385 int res;
12386
12387 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0) {
12388 send_resp(dut, conn, SIGMA_ERROR,
12389 "ErrorCode,Could not get current BSSID");
12390 return 0;
12391 }
12392 ctrl = open_wpa_mon(intf);
12393 if (!ctrl) {
12394 sigma_dut_print(dut, DUT_MSG_ERROR,
12395 "Failed to open wpa_supplicant monitor connection");
12396 return -2;
12397 }
12398
12399 snprintf(buf, sizeof(buf), "ANQP_GET %s 277", bssid);
12400 wpa_command(intf, buf);
12401
12402 res = get_wpa_cli_event(dut, ctrl, "GAS-QUERY-DONE", buf, sizeof(buf));
12403 if (res < 0) {
12404 send_resp(dut, conn, SIGMA_ERROR,
12405 "ErrorCode,Could not complete GAS query");
12406 goto fail;
12407 }
12408
12409 old_timeout = dut->default_timeout;
12410 dut->default_timeout = 2;
12411 res = get_wpa_cli_event(dut, ctrl, "RX-VENUE-URL", buf, sizeof(buf));
12412 dut->default_timeout = old_timeout;
12413 if (res < 0)
12414 goto done;
12415 pos = strchr(buf, ' ');
12416 if (!pos)
12417 goto done;
12418 pos++;
12419 pos = strchr(pos, ' ');
12420 if (!pos)
12421 goto done;
12422 pos++;
12423 info_avail = 1;
12424 snprintf(params, sizeof(params), "browser %s", pos);
12425
12426 if (display && strcasecmp(display, "Yes") == 0) {
12427 pid_t pid;
12428
12429 pid = fork();
12430 if (pid < 0) {
12431 perror("fork");
12432 return -1;
12433 }
12434
12435 if (pid == 0) {
12436 run_hs20_osu(dut, params);
12437 exit(0);
12438 }
12439 }
12440
12441done:
12442 snprintf(buf, sizeof(buf), "Info_available,%s",
12443 info_avail ? "Yes" : "No");
12444 send_resp(dut, conn, SIGMA_COMPLETE, buf);
12445fail:
12446 wpa_ctrl_detach(ctrl);
12447 wpa_ctrl_close(ctrl);
12448 return 0;
12449}
12450
12451
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012452static int sta_add_credential_uname_pwd(struct sigma_dut *dut,
12453 struct sigma_conn *conn,
12454 const char *ifname,
12455 struct sigma_cmd *cmd)
12456{
12457 const char *val;
12458 int id;
12459
12460 id = add_cred(ifname);
12461 if (id < 0)
12462 return -2;
12463 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
12464
12465 val = get_param(cmd, "prefer");
12466 if (val && atoi(val) > 0)
12467 set_cred(ifname, id, "priority", "1");
12468
12469 val = get_param(cmd, "REALM");
12470 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
12471 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12472 "realm");
12473 return 0;
12474 }
12475
12476 val = get_param(cmd, "HOME_FQDN");
12477 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
12478 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12479 "home_fqdn");
12480 return 0;
12481 }
12482
12483 val = get_param(cmd, "Username");
12484 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
12485 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12486 "username");
12487 return 0;
12488 }
12489
12490 val = get_param(cmd, "Password");
12491 if (val && set_cred_quoted(ifname, id, "password", val) < 0) {
12492 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12493 "password");
12494 return 0;
12495 }
12496
12497 val = get_param(cmd, "ROOT_CA");
12498 if (val) {
12499 char fname[200];
12500 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
12501#ifdef __linux__
12502 if (!file_exists(fname)) {
12503 char msg[300];
12504 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
12505 "file (%s) not found", fname);
12506 send_resp(dut, conn, SIGMA_ERROR, msg);
12507 return 0;
12508 }
12509#endif /* __linux__ */
12510 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
12511 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12512 "not set root CA");
12513 return 0;
12514 }
12515 }
12516
12517 return 1;
12518}
12519
12520
12521static int update_devdetail_imsi(struct sigma_dut *dut, const char *imsi)
12522{
12523 FILE *in, *out;
12524 char buf[500];
12525 int found = 0;
12526
12527 in = fopen("devdetail.xml", "r");
12528 if (in == NULL)
12529 return -1;
12530 out = fopen("devdetail.xml.tmp", "w");
12531 if (out == NULL) {
12532 fclose(in);
12533 return -1;
12534 }
12535
12536 while (fgets(buf, sizeof(buf), in)) {
12537 char *pos = strstr(buf, "<IMSI>");
12538 if (pos) {
12539 sigma_dut_print(dut, DUT_MSG_INFO, "Updated DevDetail IMSI to %s",
12540 imsi);
12541 pos += 6;
12542 *pos = '\0';
12543 fprintf(out, "%s%s</IMSI>\n", buf, imsi);
12544 found++;
12545 } else {
12546 fprintf(out, "%s", buf);
12547 }
12548 }
12549
12550 fclose(out);
12551 fclose(in);
12552 if (found)
12553 rename("devdetail.xml.tmp", "devdetail.xml");
12554 else
12555 unlink("devdetail.xml.tmp");
12556
12557 return 0;
12558}
12559
12560
12561static int sta_add_credential_sim(struct sigma_dut *dut,
12562 struct sigma_conn *conn,
12563 const char *ifname, struct sigma_cmd *cmd)
12564{
12565 const char *val, *imsi = NULL;
12566 int id;
12567 char buf[200];
12568 int res;
12569 const char *pos;
12570 size_t mnc_len;
12571 char plmn_mcc[4];
12572 char plmn_mnc[4];
12573
12574 id = add_cred(ifname);
12575 if (id < 0)
12576 return -2;
12577 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
12578
12579 val = get_param(cmd, "prefer");
12580 if (val && atoi(val) > 0)
12581 set_cred(ifname, id, "priority", "1");
12582
12583 val = get_param(cmd, "PLMN_MCC");
12584 if (val == NULL) {
12585 send_resp(dut, conn, SIGMA_ERROR,
12586 "errorCode,Missing PLMN_MCC");
12587 return 0;
12588 }
12589 if (strlen(val) != 3) {
12590 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MCC");
12591 return 0;
12592 }
12593 snprintf(plmn_mcc, sizeof(plmn_mcc), "%s", val);
12594
12595 val = get_param(cmd, "PLMN_MNC");
12596 if (val == NULL) {
12597 send_resp(dut, conn, SIGMA_ERROR,
12598 "errorCode,Missing PLMN_MNC");
12599 return 0;
12600 }
12601 if (strlen(val) != 2 && strlen(val) != 3) {
12602 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MNC");
12603 return 0;
12604 }
12605 snprintf(plmn_mnc, sizeof(plmn_mnc), "%s", val);
12606
12607 val = get_param(cmd, "IMSI");
12608 if (val == NULL) {
12609 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing SIM "
12610 "IMSI");
12611 return 0;
12612 }
12613
12614 imsi = pos = val;
12615
12616 if (strncmp(plmn_mcc, pos, 3) != 0) {
12617 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MCC mismatch");
12618 return 0;
12619 }
12620 pos += 3;
12621
12622 mnc_len = strlen(plmn_mnc);
12623 if (mnc_len < 2) {
12624 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC not set");
12625 return 0;
12626 }
12627
12628 if (strncmp(plmn_mnc, pos, mnc_len) != 0) {
12629 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC mismatch");
12630 return 0;
12631 }
12632 pos += mnc_len;
12633
12634 res = snprintf(buf, sizeof(buf), "%s%s-%s",plmn_mcc, plmn_mnc, pos);
12635 if (res < 0 || res >= (int) sizeof(buf))
12636 return -1;
12637 if (set_cred_quoted(ifname, id, "imsi", buf) < 0) {
12638 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12639 "not set IMSI");
12640 return 0;
12641 }
12642
12643 val = get_param(cmd, "Password");
12644 if (val && set_cred_quoted(ifname, id, "milenage", val) < 0) {
12645 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12646 "not set password");
12647 return 0;
12648 }
12649
Jouni Malinenba630452018-06-22 11:49:59 +030012650 if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012651 /*
12652 * Set provisioning_sp for the test cases where SIM/USIM
12653 * provisioning is used.
12654 */
12655 if (val && set_cred_quoted(ifname, id, "provisioning_sp",
12656 "wi-fi.org") < 0) {
12657 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12658 "not set provisioning_sp");
12659 return 0;
12660 }
12661
12662 update_devdetail_imsi(dut, imsi);
12663 }
12664
12665 return 1;
12666}
12667
12668
12669static int sta_add_credential_cert(struct sigma_dut *dut,
12670 struct sigma_conn *conn,
12671 const char *ifname,
12672 struct sigma_cmd *cmd)
12673{
12674 const char *val;
12675 int id;
12676
12677 id = add_cred(ifname);
12678 if (id < 0)
12679 return -2;
12680 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
12681
12682 val = get_param(cmd, "prefer");
12683 if (val && atoi(val) > 0)
12684 set_cred(ifname, id, "priority", "1");
12685
12686 val = get_param(cmd, "REALM");
12687 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
12688 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12689 "realm");
12690 return 0;
12691 }
12692
12693 val = get_param(cmd, "HOME_FQDN");
12694 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
12695 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12696 "home_fqdn");
12697 return 0;
12698 }
12699
12700 val = get_param(cmd, "Username");
12701 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
12702 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12703 "username");
12704 return 0;
12705 }
12706
12707 val = get_param(cmd, "clientCertificate");
12708 if (val) {
12709 char fname[200];
12710 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
12711#ifdef __linux__
12712 if (!file_exists(fname)) {
12713 char msg[300];
12714 snprintf(msg, sizeof(msg),
12715 "ErrorCode,clientCertificate "
12716 "file (%s) not found", fname);
12717 send_resp(dut, conn, SIGMA_ERROR, msg);
12718 return 0;
12719 }
12720#endif /* __linux__ */
12721 if (set_cred_quoted(ifname, id, "client_cert", fname) < 0) {
12722 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12723 "not set client_cert");
12724 return 0;
12725 }
12726 if (set_cred_quoted(ifname, id, "private_key", fname) < 0) {
12727 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12728 "not set private_key");
12729 return 0;
12730 }
12731 }
12732
12733 val = get_param(cmd, "ROOT_CA");
12734 if (val) {
12735 char fname[200];
12736 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
12737#ifdef __linux__
12738 if (!file_exists(fname)) {
12739 char msg[300];
12740 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
12741 "file (%s) not found", fname);
12742 send_resp(dut, conn, SIGMA_ERROR, msg);
12743 return 0;
12744 }
12745#endif /* __linux__ */
12746 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
12747 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12748 "not set root CA");
12749 return 0;
12750 }
12751 }
12752
12753 return 1;
12754}
12755
12756
Jouni Malinenf7222712019-06-13 01:50:21 +030012757static enum sigma_cmd_result cmd_sta_add_credential(struct sigma_dut *dut,
12758 struct sigma_conn *conn,
12759 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012760{
12761 const char *intf = get_param(cmd, "Interface");
12762 const char *type;
12763
12764 start_sta_mode(dut);
12765
12766 type = get_param(cmd, "Type");
12767 if (!type)
12768 return -1;
12769
12770 if (strcasecmp(type, "uname_pwd") == 0)
12771 return sta_add_credential_uname_pwd(dut, conn, intf, cmd);
12772
12773 if (strcasecmp(type, "sim") == 0)
12774 return sta_add_credential_sim(dut, conn, intf, cmd);
12775
12776 if (strcasecmp(type, "cert") == 0)
12777 return sta_add_credential_cert(dut, conn, intf, cmd);
12778
12779 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported credential "
12780 "type");
12781 return 0;
12782}
12783
12784
Jouni Malinenf7222712019-06-13 01:50:21 +030012785static enum sigma_cmd_result cmd_sta_scan(struct sigma_dut *dut,
12786 struct sigma_conn *conn,
12787 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012788{
12789 const char *intf = get_param(cmd, "Interface");
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080012790 const char *val, *bssid, *ssid, *scan_freq, *short_ssid;
Arif Hussain66a4af02019-02-07 15:04:51 -080012791 char buf[4096];
vamsi krishna89ad8c62017-09-19 12:51:18 +053012792 char ssid_hex[65];
Kiran Kumar Lokere3399af22020-03-04 16:31:56 -080012793 int wildcard_ssid = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012794 int res;
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080012795 enum sigma_cmd_result status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012796
Jouni Malinen8c1abeb2019-11-06 18:48:34 +020012797 start_sta_mode(dut);
12798
Arif Hussain66a4af02019-02-07 15:04:51 -080012799 val = get_param(cmd, "GetParameter");
12800 if (val && strcmp(val, "SSID_BSSID") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012801 if (get_wpa_ssid_bssid(dut, get_station_ifname(dut),
Arif Hussain66a4af02019-02-07 15:04:51 -080012802 buf, sizeof(buf)) < 0) {
12803 sigma_dut_print(dut, DUT_MSG_ERROR,
12804 "Could not get ssid bssid");
12805 return ERROR_SEND_STATUS;
12806 }
12807
12808 sigma_dut_print(dut, DUT_MSG_INFO, "%s", buf);
12809 send_resp(dut, conn, SIGMA_COMPLETE, buf);
12810 return STATUS_SENT;
12811 }
12812
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012813 val = get_param(cmd, "HESSID");
12814 if (val) {
12815 res = snprintf(buf, sizeof(buf), "SET hessid %s", val);
12816 if (res < 0 || res >= (int) sizeof(buf))
12817 return -1;
12818 wpa_command(intf, buf);
12819 }
12820
12821 val = get_param(cmd, "ACCS_NET_TYPE");
12822 if (val) {
12823 res = snprintf(buf, sizeof(buf), "SET access_network_type %s",
12824 val);
12825 if (res < 0 || res >= (int) sizeof(buf))
12826 return -1;
12827 wpa_command(intf, buf);
12828 }
12829
vamsi krishna89ad8c62017-09-19 12:51:18 +053012830 bssid = get_param(cmd, "Bssid");
12831 ssid = get_param(cmd, "Ssid");
12832
Kiran Kumar Lokere3399af22020-03-04 16:31:56 -080012833 if (ssid && strcasecmp(ssid, "ZeroLength") == 0 &&
12834 dut->device_type == STA_testbed) {
12835 ssid = NULL;
12836 wildcard_ssid = 1;
12837 }
12838
vamsi krishna89ad8c62017-09-19 12:51:18 +053012839 if (ssid) {
12840 if (2 * strlen(ssid) >= sizeof(ssid_hex)) {
12841 send_resp(dut, conn, SIGMA_ERROR,
12842 "ErrorCode,Too long SSID");
12843 return 0;
12844 }
12845 ascii2hexstr(ssid, ssid_hex);
12846 }
12847
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080012848 short_ssid = get_param(cmd, "ShortSSID");
12849 if (short_ssid) {
12850 uint32_t short_ssid_hex;
12851
12852 short_ssid_hex = strtoul(short_ssid, NULL, 16);
12853 short_ssid_hex = ((short_ssid_hex & 0xFF) << 24) |
12854 (((short_ssid_hex >> 8) & 0xFF) << 16) |
12855 (((short_ssid_hex >> 16) & 0xFF) << 8) |
12856 ((short_ssid_hex >> 24) & 0xFF);
12857
12858 res = snprintf(buf, sizeof(buf),
12859 "VENDOR_ELEM_ADD 14 ff053a%08x",
12860 short_ssid_hex);
12861 if (res < 0 || res >= (int) sizeof(buf) ||
12862 wpa_command(intf, buf)) {
12863 send_resp(dut, conn, SIGMA_ERROR,
12864 "errorCode,Failed to add short SSID");
12865 return STATUS_SENT_ERROR;
12866 }
12867 }
12868
Kiran Kumar Lokerec0deb482020-03-04 16:35:06 -080012869 scan_freq = get_param(cmd, "ChnlFreq");
12870
12871 res = snprintf(buf, sizeof(buf), "SCAN%s%s%s%s%s%s%s",
vamsi krishna89ad8c62017-09-19 12:51:18 +053012872 bssid ? " bssid=": "",
12873 bssid ? bssid : "",
12874 ssid ? " ssid " : "",
Kiran Kumar Lokere3399af22020-03-04 16:31:56 -080012875 ssid ? ssid_hex : "",
Kiran Kumar Lokerec0deb482020-03-04 16:35:06 -080012876 wildcard_ssid ? " wildcard_ssid=1" : "",
12877 scan_freq ? " freq=" : "",
12878 scan_freq ? scan_freq : "");
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080012879 if (res < 0 || res >= (int) sizeof(buf)) {
12880 send_resp(dut, conn, SIGMA_ERROR,
12881 "errorCode,Could not build scan command");
12882 status = STATUS_SENT_ERROR;
12883 goto remove_s_ssid;
12884 }
vamsi krishna89ad8c62017-09-19 12:51:18 +053012885
12886 if (wpa_command(intf, buf)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012887 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not start "
12888 "scan");
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080012889 status = STATUS_SENT_ERROR;
12890 } else {
12891 status = SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012892 }
12893
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080012894remove_s_ssid:
12895 if (short_ssid && wpa_command(intf, "VENDOR_ELEM_REMOVE 14 *"))
12896 sigma_dut_print(dut, DUT_MSG_ERROR,
12897 "Failed to delete vendor element");
12898
12899 return status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012900}
12901
12902
Jouni Malinenf7222712019-06-13 01:50:21 +030012903static enum sigma_cmd_result cmd_sta_scan_bss(struct sigma_dut *dut,
12904 struct sigma_conn *conn,
12905 struct sigma_cmd *cmd)
Jouni Malinen5e5d43d2018-01-10 17:29:33 +020012906{
12907 const char *intf = get_param(cmd, "Interface");
12908 const char *bssid;
12909 char buf[4096], *pos;
12910 int freq, chan;
12911 char *ssid;
12912 char resp[100];
12913 int res;
12914 struct wpa_ctrl *ctrl;
12915
12916 bssid = get_param(cmd, "BSSID");
12917 if (!bssid) {
12918 send_resp(dut, conn, SIGMA_INVALID,
12919 "errorCode,BSSID argument is missing");
12920 return 0;
12921 }
12922
12923 ctrl = open_wpa_mon(intf);
12924 if (!ctrl) {
12925 sigma_dut_print(dut, DUT_MSG_ERROR,
12926 "Failed to open wpa_supplicant monitor connection");
12927 return -1;
12928 }
12929
12930 if (wpa_command(intf, "SCAN TYPE=ONLY")) {
12931 send_resp(dut, conn, SIGMA_ERROR,
12932 "errorCode,Could not start scan");
12933 wpa_ctrl_detach(ctrl);
12934 wpa_ctrl_close(ctrl);
12935 return 0;
12936 }
12937
12938 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
12939 buf, sizeof(buf));
12940
12941 wpa_ctrl_detach(ctrl);
12942 wpa_ctrl_close(ctrl);
12943
12944 if (res < 0) {
12945 send_resp(dut, conn, SIGMA_ERROR,
12946 "errorCode,Scan did not complete");
12947 return 0;
12948 }
12949
12950 snprintf(buf, sizeof(buf), "BSS %s", bssid);
12951 if (wpa_command_resp(intf, buf, buf, sizeof(buf)) < 0 ||
12952 strncmp(buf, "id=", 3) != 0) {
12953 send_resp(dut, conn, SIGMA_ERROR,
12954 "errorCode,Specified BSSID not found");
12955 return 0;
12956 }
12957
12958 pos = strstr(buf, "\nfreq=");
12959 if (!pos) {
12960 send_resp(dut, conn, SIGMA_ERROR,
12961 "errorCode,Channel not found");
12962 return 0;
12963 }
12964 freq = atoi(pos + 6);
12965 chan = freq_to_channel(freq);
12966
12967 pos = strstr(buf, "\nssid=");
12968 if (!pos) {
12969 send_resp(dut, conn, SIGMA_ERROR,
12970 "errorCode,SSID not found");
12971 return 0;
12972 }
12973 ssid = pos + 6;
12974 pos = strchr(ssid, '\n');
12975 if (pos)
12976 *pos = '\0';
12977 snprintf(resp, sizeof(resp), "ssid,%s,bsschannel,%d", ssid, chan);
12978 send_resp(dut, conn, SIGMA_COMPLETE, resp);
12979 return 0;
12980}
12981
12982
Jouni Malinenf7222712019-06-13 01:50:21 +030012983static enum sigma_cmd_result cmd_sta_set_systime(struct sigma_dut *dut,
12984 struct sigma_conn *conn,
12985 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012986{
12987#ifdef __linux__
12988 struct timeval tv;
12989 struct tm tm;
12990 time_t t;
12991 const char *val;
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +053012992 int v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012993
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012994 wpa_command(get_station_ifname(dut), "PMKSA_FLUSH");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012995
12996 memset(&tm, 0, sizeof(tm));
12997 val = get_param(cmd, "seconds");
12998 if (val)
12999 tm.tm_sec = atoi(val);
13000 val = get_param(cmd, "minutes");
13001 if (val)
13002 tm.tm_min = atoi(val);
13003 val = get_param(cmd, "hours");
13004 if (val)
13005 tm.tm_hour = atoi(val);
13006 val = get_param(cmd, "date");
13007 if (val)
13008 tm.tm_mday = atoi(val);
13009 val = get_param(cmd, "month");
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +053013010 if (val) {
13011 v = atoi(val);
13012 if (v < 1 || v > 12) {
13013 send_resp(dut, conn, SIGMA_INVALID,
13014 "errorCode,Invalid month");
13015 return 0;
13016 }
13017 tm.tm_mon = v - 1;
13018 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013019 val = get_param(cmd, "year");
13020 if (val) {
13021 int year = atoi(val);
13022#ifdef ANDROID
13023 if (year > 2035)
13024 year = 2035; /* years beyond 2035 not supported */
13025#endif /* ANDROID */
13026 tm.tm_year = year - 1900;
13027 }
13028 t = mktime(&tm);
13029 if (t == (time_t) -1) {
13030 send_resp(dut, conn, SIGMA_ERROR,
13031 "errorCode,Invalid date or time");
13032 return 0;
13033 }
13034
13035 memset(&tv, 0, sizeof(tv));
13036 tv.tv_sec = t;
13037
13038 if (settimeofday(&tv, NULL) < 0) {
13039 sigma_dut_print(dut, DUT_MSG_INFO, "settimeofday failed: %s",
13040 strerror(errno));
13041 send_resp(dut, conn, SIGMA_ERROR,
13042 "errorCode,Failed to set time");
13043 return 0;
13044 }
13045
13046 return 1;
13047#endif /* __linux__ */
13048
13049 return -1;
13050}
13051
13052
Jouni Malinenf7222712019-06-13 01:50:21 +030013053static enum sigma_cmd_result cmd_sta_osu(struct sigma_dut *dut,
13054 struct sigma_conn *conn,
13055 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013056{
13057 const char *intf = get_param(cmd, "Interface");
Jouni Malinen4c8681c2018-09-12 23:28:11 +030013058 const char *name, *osu_ssid, *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013059 int prod_ess_assoc = 1;
Jouni Malinen4c8681c2018-09-12 23:28:11 +030013060 char buf[300], bssid[100], ssid[100];
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013061 int res;
13062 struct wpa_ctrl *ctrl;
13063
13064 name = get_param(cmd, "osuFriendlyName");
Jouni Malinen4c8681c2018-09-12 23:28:11 +030013065 osu_ssid = get_param(cmd, "osu_ssid");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013066
13067 val = get_param(cmd, "ProdESSAssoc");
13068 if (val)
13069 prod_ess_assoc = atoi(val);
13070
13071 kill_dhcp_client(dut, intf);
13072 if (start_dhcp_client(dut, intf) < 0)
13073 return -2;
13074
13075 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger OSU");
13076 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
13077 res = snprintf(buf, sizeof(buf),
Jouni Malinen4c8681c2018-09-12 23:28:11 +030013078 "%s %s%s%s %s%s%s signup osu-ca.pem",
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013079 prod_ess_assoc ? "" : "-N",
13080 name ? "-O'" : "", name ? name : "",
Jouni Malinen4c8681c2018-09-12 23:28:11 +030013081 name ? "'" : "",
13082 osu_ssid ? "-o'" : "", osu_ssid ? osu_ssid : "",
13083 osu_ssid ? "'" : "");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013084
Kanchanapally, Vidyullatha12b66762015-12-31 16:46:42 +053013085 hs2_set_policy(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013086 if (run_hs20_osu(dut, buf) < 0) {
13087 FILE *f;
13088
13089 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to complete OSU");
13090
13091 f = fopen("hs20-osu-client.res", "r");
13092 if (f) {
13093 char resp[400], res[300], *pos;
13094 if (!fgets(res, sizeof(res), f))
13095 res[0] = '\0';
13096 pos = strchr(res, '\n');
13097 if (pos)
13098 *pos = '\0';
13099 fclose(f);
13100 sigma_dut_summary(dut, "hs20-osu-client provisioning failed: %s",
13101 res);
13102 snprintf(resp, sizeof(resp), "notify-send '%s'", res);
13103 if (system(resp) != 0) {
13104 }
13105 snprintf(resp, sizeof(resp),
13106 "SSID,,BSSID,,failureReason,%s", res);
13107 send_resp(dut, conn, SIGMA_COMPLETE, resp);
13108 return 0;
13109 }
13110
13111 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
13112 return 0;
13113 }
13114
13115 if (!prod_ess_assoc)
13116 goto report;
13117
13118 ctrl = open_wpa_mon(intf);
13119 if (ctrl == NULL) {
13120 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
13121 "wpa_supplicant monitor connection");
13122 return -1;
13123 }
13124
13125 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
13126 buf, sizeof(buf));
13127
13128 wpa_ctrl_detach(ctrl);
13129 wpa_ctrl_close(ctrl);
13130
13131 if (res < 0) {
13132 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to connect to "
13133 "network after OSU");
13134 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
13135 return 0;
13136 }
13137
13138report:
13139 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
13140 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
13141 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to get BSSID/SSID");
13142 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
13143 return 0;
13144 }
13145
13146 snprintf(buf, sizeof(buf), "SSID,%s,BSSID,%s", ssid, bssid);
13147 send_resp(dut, conn, SIGMA_COMPLETE, buf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013148 return 0;
13149}
13150
13151
Jouni Malinenf7222712019-06-13 01:50:21 +030013152static enum sigma_cmd_result cmd_sta_policy_update(struct sigma_dut *dut,
13153 struct sigma_conn *conn,
13154 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013155{
13156 const char *val;
13157 int timeout = 120;
13158
13159 val = get_param(cmd, "PolicyUpdate");
13160 if (val == NULL || atoi(val) == 0)
13161 return 1; /* No operation requested */
13162
13163 val = get_param(cmd, "Timeout");
13164 if (val)
13165 timeout = atoi(val);
13166
13167 if (timeout) {
13168 /* TODO: time out the command and return
13169 * PolicyUpdateStatus,TIMEOUT if needed. */
13170 }
13171
13172 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger policy update");
13173 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
13174 if (run_hs20_osu(dut, "pol_upd fqdn=wi-fi.org") < 0) {
13175 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,FAIL");
13176 return 0;
13177 }
13178
13179 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,SUCCESS");
13180 return 0;
13181}
13182
13183
Jouni Malinenf7222712019-06-13 01:50:21 +030013184static enum sigma_cmd_result cmd_sta_er_config(struct sigma_dut *dut,
13185 struct sigma_conn *conn,
13186 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013187{
13188 struct wpa_ctrl *ctrl;
13189 const char *intf = get_param(cmd, "Interface");
13190 const char *bssid = get_param(cmd, "Bssid");
13191 const char *ssid = get_param(cmd, "SSID");
13192 const char *security = get_param(cmd, "Security");
13193 const char *passphrase = get_param(cmd, "Passphrase");
13194 const char *pin = get_param(cmd, "PIN");
13195 char buf[1000];
13196 char ssid_hex[200], passphrase_hex[200];
13197 const char *keymgmt, *cipher;
13198
13199 if (intf == NULL)
Jouni Malinen016ae6c2019-11-04 17:00:01 +020013200 intf = get_main_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013201
13202 if (!bssid) {
13203 send_resp(dut, conn, SIGMA_ERROR,
13204 "ErrorCode,Missing Bssid argument");
13205 return 0;
13206 }
13207
13208 if (!ssid) {
13209 send_resp(dut, conn, SIGMA_ERROR,
13210 "ErrorCode,Missing SSID argument");
13211 return 0;
13212 }
13213
13214 if (!security) {
13215 send_resp(dut, conn, SIGMA_ERROR,
13216 "ErrorCode,Missing Security argument");
13217 return 0;
13218 }
13219
13220 if (!passphrase) {
13221 send_resp(dut, conn, SIGMA_ERROR,
13222 "ErrorCode,Missing Passphrase argument");
13223 return 0;
13224 }
13225
13226 if (!pin) {
13227 send_resp(dut, conn, SIGMA_ERROR,
13228 "ErrorCode,Missing PIN argument");
13229 return 0;
13230 }
13231
vamsi krishna8c9c1562017-05-12 15:51:46 +053013232 if (2 * strlen(ssid) >= sizeof(ssid_hex) ||
13233 2 * strlen(passphrase) >= sizeof(passphrase_hex)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013234 send_resp(dut, conn, SIGMA_ERROR,
13235 "ErrorCode,Too long SSID/passphrase");
13236 return 0;
13237 }
13238
13239 ctrl = open_wpa_mon(intf);
13240 if (ctrl == NULL) {
13241 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
13242 "wpa_supplicant monitor connection");
13243 return -2;
13244 }
13245
13246 if (strcasecmp(security, "wpa2-psk") == 0) {
13247 keymgmt = "WPA2PSK";
13248 cipher = "CCMP";
13249 } else {
13250 wpa_ctrl_detach(ctrl);
13251 wpa_ctrl_close(ctrl);
13252 send_resp(dut, conn, SIGMA_ERROR,
13253 "ErrorCode,Unsupported Security value");
13254 return 0;
13255 }
13256
13257 ascii2hexstr(ssid, ssid_hex);
13258 ascii2hexstr(passphrase, passphrase_hex);
13259 snprintf(buf, sizeof(buf), "WPS_REG %s %s %s %s %s %s",
13260 bssid, pin, ssid_hex, keymgmt, cipher, passphrase_hex);
13261
13262 if (wpa_command(intf, buf) < 0) {
13263 wpa_ctrl_detach(ctrl);
13264 wpa_ctrl_close(ctrl);
13265 send_resp(dut, conn, SIGMA_ERROR,
13266 "ErrorCode,Failed to start registrar");
13267 return 0;
13268 }
13269
13270 snprintf(dut->er_oper_bssid, sizeof(dut->er_oper_bssid), "%s", bssid);
13271 dut->er_oper_performed = 1;
13272
13273 return wps_connection_event(dut, conn, ctrl, intf, 0);
13274}
13275
13276
Jouni Malinenf7222712019-06-13 01:50:21 +030013277static enum sigma_cmd_result
13278cmd_sta_wps_connect_pw_token(struct sigma_dut *dut, struct sigma_conn *conn,
13279 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013280{
13281 struct wpa_ctrl *ctrl;
13282 const char *intf = get_param(cmd, "Interface");
13283 const char *bssid = get_param(cmd, "Bssid");
13284 char buf[100];
13285
13286 if (!bssid) {
13287 send_resp(dut, conn, SIGMA_ERROR,
13288 "ErrorCode,Missing Bssid argument");
13289 return 0;
13290 }
13291
13292 ctrl = open_wpa_mon(intf);
13293 if (ctrl == NULL) {
13294 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
13295 "wpa_supplicant monitor connection");
13296 return -2;
13297 }
13298
13299 snprintf(buf, sizeof(buf), "WPS_NFC %s", bssid);
13300
13301 if (wpa_command(intf, buf) < 0) {
13302 wpa_ctrl_detach(ctrl);
13303 wpa_ctrl_close(ctrl);
13304 send_resp(dut, conn, SIGMA_ERROR,
13305 "ErrorCode,Failed to start registrar");
13306 return 0;
13307 }
13308
13309 return wps_connection_event(dut, conn, ctrl, intf, 0);
13310}
13311
13312
Jouni Malinenf7222712019-06-13 01:50:21 +030013313static enum sigma_cmd_result cmd_start_wps_registration(struct sigma_dut *dut,
13314 struct sigma_conn *conn,
13315 struct sigma_cmd *cmd)
vamsi krishna9b144002017-09-20 13:28:13 +053013316{
13317 struct wpa_ctrl *ctrl;
13318 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020013319 const char *network_mode = get_param(cmd, "network_mode");
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020013320 const char *config_method = get_param(cmd, "WPSConfigMethod");
13321 const char *role;
vamsi krishna9b144002017-09-20 13:28:13 +053013322 int res;
13323 char buf[256];
13324 const char *events[] = {
13325 "CTRL-EVENT-CONNECTED",
13326 "WPS-OVERLAP-DETECTED",
13327 "WPS-TIMEOUT",
13328 "WPS-FAIL",
13329 NULL
13330 };
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020013331 int id = 0;
vamsi krishna9b144002017-09-20 13:28:13 +053013332
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020013333 /* 60G WPS tests do not pass Interface parameter */
13334 if (!intf)
Jouni Malinen016ae6c2019-11-04 17:00:01 +020013335 intf = get_main_ifname(dut);
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020013336
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020013337 if (dut->mode == SIGMA_MODE_AP)
13338 return ap_wps_registration(dut, conn, cmd);
13339
13340 if (config_method) {
13341 /* WFA_CS_WPS_PIN_KEYPAD mode is set when using the
13342 * sta_wps_enter_pin before calling start_wps_registration. */
13343 if (strcasecmp(config_method, "PBC") == 0)
13344 dut->wps_method = WFA_CS_WPS_PBC;
13345 }
13346 if (dut->wps_method == WFA_CS_WPS_NOT_READY) {
13347 send_resp(dut, conn, SIGMA_ERROR,
13348 "ErrorCode,WPS parameters not yet set");
13349 return STATUS_SENT;
13350 }
13351
13352 /* Make sure WPS is enabled (also for STA mode) */
13353 dut->wps_disable = 0;
13354
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020013355 if (dut->band == WPS_BAND_60G && network_mode &&
13356 strcasecmp(network_mode, "PBSS") == 0) {
13357 sigma_dut_print(dut, DUT_MSG_DEBUG,
13358 "Set PBSS network mode, network id %d", id);
Jouni Malinen016ae6c2019-11-04 17:00:01 +020013359 if (set_network(get_station_ifname(dut), id, "pbss", "1") < 0)
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020013360 return -2;
13361 }
13362
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020013363 if (dut->force_rsn_ie) {
13364 sigma_dut_print(dut, DUT_MSG_DEBUG, "Force RSN_IE: %d",
13365 dut->force_rsn_ie);
13366 if (sta_60g_force_rsn_ie(dut, dut->force_rsn_ie) < 0) {
13367 sigma_dut_print(dut, DUT_MSG_INFO,
13368 "Failed to force RSN_IE");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020013369 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020013370 }
13371 }
13372
vamsi krishna9b144002017-09-20 13:28:13 +053013373 ctrl = open_wpa_mon(intf);
13374 if (!ctrl) {
13375 sigma_dut_print(dut, DUT_MSG_ERROR,
13376 "Failed to open wpa_supplicant monitor connection");
13377 return -2;
13378 }
13379
13380 role = get_param(cmd, "WpsRole");
13381 if (!role) {
13382 send_resp(dut, conn, SIGMA_INVALID,
13383 "ErrorCode,WpsRole not provided");
13384 goto fail;
13385 }
13386
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020013387 if (strcasecmp(role, "Enrollee") != 0) {
13388 /* Registrar role for STA not supported */
13389 send_resp(dut, conn, SIGMA_ERROR,
13390 "ErrorCode,Unsupported WpsRole value");
13391 goto fail;
13392 }
13393
13394 if (is_60g_sigma_dut(dut)) {
13395 if (dut->wps_method == WFA_CS_WPS_PBC)
13396 snprintf(buf, sizeof(buf), "WPS_PBC");
13397 else /* WFA_CS_WPS_PIN_KEYPAD */
13398 snprintf(buf, sizeof(buf), "WPS_PIN any %s",
13399 dut->wps_pin);
13400 if (wpa_command(intf, buf) < 0) {
13401 send_resp(dut, conn, SIGMA_ERROR,
13402 "ErrorCode,Failed to start WPS");
vamsi krishna9b144002017-09-20 13:28:13 +053013403 goto fail;
13404 }
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020013405 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
13406 if (res < 0) {
13407 send_resp(dut, conn, SIGMA_ERROR,
13408 "ErrorCode,WPS connection did not complete");
13409 goto fail;
13410 }
13411 if (strstr(buf, "WPS-TIMEOUT")) {
13412 send_resp(dut, conn, SIGMA_COMPLETE, "WpsState,NoPeer");
13413 } else if (strstr(buf, "WPS-OVERLAP-DETECTED")) {
13414 send_resp(dut, conn, SIGMA_COMPLETE,
13415 "WpsState,OverlapSession");
13416 } else if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
13417 send_resp(dut, conn, SIGMA_COMPLETE,
13418 "WpsState,Successful");
13419 } else {
13420 send_resp(dut, conn, SIGMA_COMPLETE,
13421 "WpsState,Failure");
13422 }
13423 } else {
13424 if (dut->wps_method == WFA_CS_WPS_PBC) {
vamsi krishna9b144002017-09-20 13:28:13 +053013425 if (wpa_command(intf, "WPS_PBC") < 0) {
13426 send_resp(dut, conn, SIGMA_ERROR,
13427 "ErrorCode,Failed to enable PBC");
13428 goto fail;
13429 }
13430 } else {
13431 /* TODO: PIN method */
13432 send_resp(dut, conn, SIGMA_ERROR,
13433 "ErrorCode,Unsupported WpsConfigMethod value");
13434 goto fail;
13435 }
13436 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
13437 if (res < 0) {
13438 send_resp(dut, conn, SIGMA_ERROR,
13439 "ErrorCode,WPS connection did not complete");
13440 goto fail;
13441 }
13442 if (strstr(buf, "WPS-TIMEOUT")) {
13443 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,NoPeer");
13444 } else if (strstr(buf, "WPS-OVERLAP-DETECTED")) {
13445 send_resp(dut, conn, SIGMA_ERROR,
13446 "ErrorCode,OverlapSession");
13447 } else if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
13448 send_resp(dut, conn, SIGMA_COMPLETE, "Successful");
13449 } else {
13450 send_resp(dut, conn, SIGMA_ERROR,
13451 "ErrorCode,WPS operation failed");
13452 }
vamsi krishna9b144002017-09-20 13:28:13 +053013453 }
13454
13455fail:
13456 wpa_ctrl_detach(ctrl);
13457 wpa_ctrl_close(ctrl);
13458 return 0;
13459}
13460
13461
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013462static int req_intf(struct sigma_cmd *cmd)
13463{
13464 return get_param(cmd, "interface") == NULL ? -1 : 0;
13465}
13466
13467
13468void sta_register_cmds(void)
13469{
13470 sigma_dut_reg_cmd("sta_get_ip_config", req_intf,
13471 cmd_sta_get_ip_config);
13472 sigma_dut_reg_cmd("sta_set_ip_config", req_intf,
13473 cmd_sta_set_ip_config);
13474 sigma_dut_reg_cmd("sta_get_info", req_intf, cmd_sta_get_info);
13475 sigma_dut_reg_cmd("sta_get_mac_address", req_intf,
13476 cmd_sta_get_mac_address);
13477 sigma_dut_reg_cmd("sta_is_connected", req_intf, cmd_sta_is_connected);
13478 sigma_dut_reg_cmd("sta_verify_ip_connection", req_intf,
13479 cmd_sta_verify_ip_connection);
13480 sigma_dut_reg_cmd("sta_get_bssid", req_intf, cmd_sta_get_bssid);
13481 sigma_dut_reg_cmd("sta_set_encryption", req_intf,
13482 cmd_sta_set_encryption);
13483 sigma_dut_reg_cmd("sta_set_psk", req_intf, cmd_sta_set_psk);
13484 sigma_dut_reg_cmd("sta_set_eaptls", req_intf, cmd_sta_set_eaptls);
13485 sigma_dut_reg_cmd("sta_set_eapttls", req_intf, cmd_sta_set_eapttls);
13486 sigma_dut_reg_cmd("sta_set_eapsim", req_intf, cmd_sta_set_eapsim);
13487 sigma_dut_reg_cmd("sta_set_peap", req_intf, cmd_sta_set_peap);
13488 sigma_dut_reg_cmd("sta_set_eapfast", req_intf, cmd_sta_set_eapfast);
13489 sigma_dut_reg_cmd("sta_set_eapaka", req_intf, cmd_sta_set_eapaka);
13490 sigma_dut_reg_cmd("sta_set_eapakaprime", req_intf,
13491 cmd_sta_set_eapakaprime);
13492 sigma_dut_reg_cmd("sta_set_security", req_intf, cmd_sta_set_security);
13493 sigma_dut_reg_cmd("sta_set_uapsd", req_intf, cmd_sta_set_uapsd);
13494 /* TODO: sta_set_ibss */
13495 /* TODO: sta_set_mode */
13496 sigma_dut_reg_cmd("sta_set_wmm", req_intf, cmd_sta_set_wmm);
13497 sigma_dut_reg_cmd("sta_associate", req_intf, cmd_sta_associate);
13498 /* TODO: sta_up_load */
13499 sigma_dut_reg_cmd("sta_preset_testparameters", req_intf,
13500 cmd_sta_preset_testparameters);
13501 /* TODO: sta_set_system */
13502 sigma_dut_reg_cmd("sta_set_11n", req_intf, cmd_sta_set_11n);
13503 /* TODO: sta_set_rifs_test */
13504 sigma_dut_reg_cmd("sta_set_wireless", req_intf, cmd_sta_set_wireless);
13505 sigma_dut_reg_cmd("sta_send_addba", req_intf, cmd_sta_send_addba);
13506 /* TODO: sta_send_coexist_mgmt */
13507 sigma_dut_reg_cmd("sta_disconnect", req_intf, cmd_sta_disconnect);
13508 sigma_dut_reg_cmd("sta_reassoc", req_intf, cmd_sta_reassoc);
13509 sigma_dut_reg_cmd("sta_reassociate", req_intf, cmd_sta_reassoc);
13510 sigma_dut_reg_cmd("sta_reset_default", req_intf,
13511 cmd_sta_reset_default);
13512 sigma_dut_reg_cmd("sta_send_frame", req_intf, cmd_sta_send_frame);
13513 sigma_dut_reg_cmd("sta_set_macaddr", req_intf, cmd_sta_set_macaddr);
13514 sigma_dut_reg_cmd("sta_set_rfeature", req_intf, cmd_sta_set_rfeature);
13515 sigma_dut_reg_cmd("sta_set_radio", req_intf, cmd_sta_set_radio);
13516 sigma_dut_reg_cmd("sta_set_pwrsave", req_intf, cmd_sta_set_pwrsave);
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020013517 sigma_dut_reg_cmd("sta_set_power_save", req_intf, cmd_sta_set_pwrsave);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013518 sigma_dut_reg_cmd("sta_bssid_pool", req_intf, cmd_sta_bssid_pool);
13519 sigma_dut_reg_cmd("sta_reset_parm", req_intf, cmd_sta_reset_parm);
13520 sigma_dut_reg_cmd("sta_get_key", req_intf, cmd_sta_get_key);
13521 sigma_dut_reg_cmd("sta_hs2_associate", req_intf,
13522 cmd_sta_hs2_associate);
Jouni Malinenb639f1c2018-09-13 02:39:46 +030013523 sigma_dut_reg_cmd("sta_hs2_venue_info", req_intf,
13524 cmd_sta_hs2_venue_info);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013525 sigma_dut_reg_cmd("sta_add_credential", req_intf,
13526 cmd_sta_add_credential);
13527 sigma_dut_reg_cmd("sta_scan", req_intf, cmd_sta_scan);
Jouni Malinen5e5d43d2018-01-10 17:29:33 +020013528 sigma_dut_reg_cmd("sta_scan_bss", req_intf, cmd_sta_scan_bss);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013529 sigma_dut_reg_cmd("sta_set_systime", NULL, cmd_sta_set_systime);
13530 sigma_dut_reg_cmd("sta_osu", req_intf, cmd_sta_osu);
13531 sigma_dut_reg_cmd("sta_policy_update", req_intf, cmd_sta_policy_update);
13532 sigma_dut_reg_cmd("sta_er_config", NULL, cmd_sta_er_config);
13533 sigma_dut_reg_cmd("sta_wps_connect_pw_token", req_intf,
13534 cmd_sta_wps_connect_pw_token);
Jouni Malinen82905202018-04-29 17:20:10 +030013535 sigma_dut_reg_cmd("sta_exec_action", NULL, cmd_sta_exec_action);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013536 sigma_dut_reg_cmd("sta_get_events", req_intf, cmd_sta_get_events);
13537 sigma_dut_reg_cmd("sta_get_parameter", req_intf, cmd_sta_get_parameter);
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020013538 sigma_dut_reg_cmd("start_wps_registration", NULL,
vamsi krishna9b144002017-09-20 13:28:13 +053013539 cmd_start_wps_registration);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013540}