blob: 41305a322c0ae74151f340913e3a012d901545d7 [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 }
Jouni Malinenc0078772020-03-04 21:23:16 +02002237 if (dut->sae_pwe == SAE_PWE_LOOP && get_param(cmd, "PasswordId"))
2238 sae_pwe = 3;
2239 else if (dut->sae_pwe == SAE_PWE_LOOP)
Jouni Malinen11e55212019-11-22 21:46:59 +02002240 sae_pwe = 0;
2241 else if (dut->sae_pwe == SAE_PWE_H2E)
2242 sae_pwe = 1;
2243 else if (dut->sae_h2e_default)
2244 sae_pwe = 2;
2245 snprintf(buf, sizeof(buf), "SET sae_pwe %d", sae_pwe);
2246 if (sae_pwe >= 0 && wpa_command(ifname, buf) != 0)
2247 return ERROR_SEND_STATUS;
2248
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002249 if (dut->program == PROGRAM_60GHZ && network_mode &&
2250 strcasecmp(network_mode, "PBSS") == 0 &&
2251 set_network(ifname, id, "pbss", "1") < 0)
2252 return -2;
2253
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002254 return 1;
2255}
2256
2257
Jouni Malinen8ac93452019-08-14 15:19:13 +03002258static enum sigma_cmd_result set_trust_root_system(struct sigma_dut *dut,
2259 struct sigma_conn *conn,
2260 const char *ifname, int id)
2261{
2262 char buf[200];
2263
2264 snprintf(buf, sizeof(buf), "%s/certs", sigma_cert_path);
2265 if (!file_exists(buf))
2266 strlcpy(buf, "/system/etc/security/cacerts", sizeof(buf));
2267 if (!file_exists(buf))
2268 strlcpy(buf, "/etc/ssl/certs", sizeof(buf));
2269 if (!file_exists(buf)) {
2270 char msg[300];
2271
2272 snprintf(msg, sizeof(msg),
2273 "ErrorCode,trustedRootCA system store (%s) not found",
2274 buf);
2275 send_resp(dut, conn, SIGMA_ERROR, msg);
2276 return STATUS_SENT_ERROR;
2277 }
2278
2279 if (set_network_quoted(ifname, id, "ca_path", buf) < 0)
2280 return ERROR_SEND_STATUS;
2281
2282 return SUCCESS_SEND_STATUS;
2283}
2284
2285
2286static enum sigma_cmd_result set_trust_root(struct sigma_dut *dut,
2287 struct sigma_conn *conn,
2288 const char *ifname, int id,
2289 const char *val)
2290{
2291 char buf[200];
2292#ifdef ANDROID
2293 unsigned char kvalue[KEYSTORE_MESSAGE_SIZE];
2294 int length;
2295#endif /* ANDROID */
2296
2297 if (strcmp(val, "DEFAULT") == 0)
2298 return set_trust_root_system(dut, conn, ifname, id);
2299
2300#ifdef ANDROID
2301 snprintf(buf, sizeof(buf), "CACERT_%s", val);
2302 length = android_keystore_get(ANDROID_KEYSTORE_GET, buf, kvalue);
2303 if (length > 0) {
2304 sigma_dut_print(dut, DUT_MSG_INFO, "Use Android keystore [%s]",
2305 buf);
2306 snprintf(buf, sizeof(buf), "keystore://CACERT_%s", val);
2307 goto ca_cert_selected;
2308 }
2309#endif /* ANDROID */
2310
2311 snprintf(buf, sizeof(buf), "%s/%s", sigma_cert_path, val);
2312#ifdef __linux__
2313 if (!file_exists(buf)) {
2314 char msg[300];
2315
2316 snprintf(msg, sizeof(msg),
2317 "ErrorCode,trustedRootCA file (%s) not found", buf);
2318 send_resp(dut, conn, SIGMA_ERROR, msg);
2319 return STATUS_SENT_ERROR;
2320 }
2321#endif /* __linux__ */
2322#ifdef ANDROID
2323ca_cert_selected:
2324#endif /* ANDROID */
2325 if (set_network_quoted(ifname, id, "ca_cert", buf) < 0)
2326 return ERROR_SEND_STATUS;
2327
2328 return SUCCESS_SEND_STATUS;
2329}
2330
2331
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002332static int set_eap_common(struct sigma_dut *dut, struct sigma_conn *conn,
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302333 const char *ifname, int username_identity,
2334 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002335{
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002336 const char *val, *alg, *akm, *trust_root, *domain, *domain_suffix;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002337 int id;
Jouni Malinen53264f62019-05-03 13:04:40 +03002338 char buf[200], buf2[300];
Jouni Malinen8179fee2019-03-28 03:19:47 +02002339 int erp = 0;
Jouni Malinen8ac93452019-08-14 15:19:13 +03002340 enum sigma_cmd_result res;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002341
2342 id = set_wpa_common(dut, conn, ifname, cmd);
2343 if (id < 0)
2344 return id;
2345
2346 val = get_param(cmd, "keyMgmtType");
2347 alg = get_param(cmd, "micAlg");
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302348 akm = get_param(cmd, "AKMSuiteType");
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002349 trust_root = get_param(cmd, "trustedRootCA");
2350 domain = get_param(cmd, "Domain");
2351 domain_suffix = get_param(cmd, "DomainSuffix");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002352
Jouni Malinenad395a22017-09-01 21:13:46 +03002353 if (val && strcasecmp(val, "SuiteB") == 0) {
2354 if (set_network(ifname, id, "key_mgmt", "WPA-EAP-SUITE-B-192") <
2355 0)
2356 return -2;
2357 } else if (alg && strcasecmp(alg, "SHA-256") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002358 if (set_network(ifname, id, "key_mgmt", "WPA-EAP-SHA256") < 0)
2359 return -2;
2360 } else if (alg && strcasecmp(alg, "SHA-1") == 0) {
2361 if (set_network(ifname, id, "key_mgmt", "WPA-EAP") < 0)
2362 return -2;
2363 } else if (val && strcasecmp(val, "wpa2-ft") == 0) {
2364 if (set_network(ifname, id, "key_mgmt", "FT-EAP") < 0)
2365 return -2;
Jouni Malinend6a9d692019-03-28 03:01:24 +02002366 } else if (!akm &&
2367 ((val && strcasecmp(val, "wpa2-sha256") == 0) ||
2368 dut->sta_pmf == STA_PMF_REQUIRED)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002369 if (set_network(ifname, id, "key_mgmt",
2370 "WPA-EAP WPA-EAP-SHA256") < 0)
2371 return -2;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302372 } else if (akm && atoi(akm) == 14) {
2373 if (dut->sta_pmf == STA_PMF_OPTIONAL ||
2374 dut->sta_pmf == STA_PMF_REQUIRED) {
2375 if (set_network(ifname, id, "key_mgmt",
2376 "WPA-EAP-SHA256 FILS-SHA256") < 0)
2377 return -2;
2378 } else {
2379 if (set_network(ifname, id, "key_mgmt",
2380 "WPA-EAP FILS-SHA256") < 0)
2381 return -2;
2382 }
2383
Jouni Malinen8179fee2019-03-28 03:19:47 +02002384 erp = 1;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302385 } else if (akm && atoi(akm) == 15) {
2386 if (dut->sta_pmf == STA_PMF_OPTIONAL ||
2387 dut->sta_pmf == STA_PMF_REQUIRED) {
2388 if (set_network(ifname, id, "key_mgmt",
2389 "WPA-EAP-SHA256 FILS-SHA384") < 0)
2390 return -2;
2391 } else {
2392 if (set_network(ifname, id, "key_mgmt",
2393 "WPA-EAP FILS-SHA384") < 0)
2394 return -2;
2395 }
2396
Jouni Malinen8179fee2019-03-28 03:19:47 +02002397 erp = 1;
Jouni Malinend6a9d692019-03-28 03:01:24 +02002398 } else if (!akm && dut->sta_pmf == STA_PMF_OPTIONAL) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002399 if (set_network(ifname, id, "key_mgmt",
2400 "WPA-EAP WPA-EAP-SHA256") < 0)
2401 return -2;
Jouni Malinend6a9d692019-03-28 03:01:24 +02002402 } else if (!akm) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002403 if (set_network(ifname, id, "key_mgmt", "WPA-EAP") < 0)
2404 return -2;
2405 }
2406
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002407 if (trust_root) {
2408 if (strcmp(trust_root, "DEFAULT") == 0 && !domain &&
2409 !domain_suffix) {
2410 send_resp(dut, conn, SIGMA_ERROR,
2411 "errorCode,trustRootCA DEFAULT used without specifying Domain or DomainSuffix");
2412 return STATUS_SENT_ERROR;
2413 }
2414 res = set_trust_root(dut, conn, ifname, id, trust_root);
Jouni Malinen8ac93452019-08-14 15:19:13 +03002415 if (res != SUCCESS_SEND_STATUS)
2416 return res;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002417 }
2418
Jouni Malinen53264f62019-05-03 13:04:40 +03002419 val = get_param(cmd, "ServerCert");
2420 if (val) {
2421 FILE *f;
2422 char *result = NULL, *pos;
2423
2424 snprintf(buf, sizeof(buf), "%s/%s.sha256", sigma_cert_path,
2425 val);
2426 f = fopen(buf, "r");
2427 if (f) {
2428 result = fgets(buf, sizeof(buf), f);
2429 fclose(f);
2430 }
2431 if (!result) {
2432 snprintf(buf2, sizeof(buf2),
2433 "ErrorCode,ServerCert hash could not be read from %s",
2434 buf);
2435 send_resp(dut, conn, SIGMA_ERROR, buf2);
2436 return STATUS_SENT_ERROR;
2437 }
2438 pos = strchr(buf, '\n');
2439 if (pos)
2440 *pos = '\0';
2441 snprintf(buf2, sizeof(buf2), "hash://server/sha256/%s", buf);
2442 if (set_network_quoted(ifname, id, "ca_cert", buf2) < 0)
2443 return ERROR_SEND_STATUS;
Jouni Malinen29108dc2019-06-13 23:42:11 +03002444
2445 snprintf(buf, sizeof(buf), "%s/%s.tod", sigma_cert_path, val);
2446 if (file_exists(buf)) {
2447 sigma_dut_print(dut, DUT_MSG_DEBUG,
2448 "TOD policy enabled for the configured ServerCert hash");
2449 dut->sta_tod_policy = 1;
2450 }
Jouni Malinen53264f62019-05-03 13:04:40 +03002451 }
2452
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002453 if (domain &&
2454 set_network_quoted(ifname, id, "domain_match", domain) < 0)
Jouni Malinen96f84b02019-05-03 12:32:56 +03002455 return ERROR_SEND_STATUS;
2456
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002457 if (domain_suffix &&
2458 set_network_quoted(ifname, id, "domain_suffix_match",
2459 domain_suffix) < 0)
Jouni Malinen96f84b02019-05-03 12:32:56 +03002460 return ERROR_SEND_STATUS;
2461
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302462 if (username_identity) {
2463 val = get_param(cmd, "username");
2464 if (val) {
2465 if (set_network_quoted(ifname, id, "identity", val) < 0)
2466 return -2;
2467 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002468
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302469 val = get_param(cmd, "password");
2470 if (val) {
2471 if (set_network_quoted(ifname, id, "password", val) < 0)
2472 return -2;
2473 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002474 }
2475
Jouni Malinen8179fee2019-03-28 03:19:47 +02002476 if (dut->akm_values &
2477 ((1 << AKM_FILS_SHA256) |
2478 (1 << AKM_FILS_SHA384) |
2479 (1 << AKM_FT_FILS_SHA256) |
2480 (1 << AKM_FT_FILS_SHA384)))
2481 erp = 1;
2482 if (erp && set_network(ifname, id, "erp", "1") < 0)
2483 return ERROR_SEND_STATUS;
2484
Jouni Malinen134fe3c2019-06-12 04:16:49 +03002485 dut->sta_associate_wait_connect = 1;
2486
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002487 return id;
2488}
2489
2490
Jouni Malinen5eabb2a2017-10-03 18:17:30 +03002491static int set_tls_cipher(const char *ifname, int id, const char *cipher)
2492{
2493 const char *val;
2494
2495 if (!cipher)
2496 return 0;
2497
2498 if (strcasecmp(cipher, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384") == 0)
2499 val = "ECDHE-ECDSA-AES256-GCM-SHA384";
2500 else if (strcasecmp(cipher,
2501 "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384") == 0)
2502 val = "ECDHE-RSA-AES256-GCM-SHA384";
2503 else if (strcasecmp(cipher, "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384") == 0)
2504 val = "DHE-RSA-AES256-GCM-SHA384";
2505 else if (strcasecmp(cipher,
2506 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256") == 0)
2507 val = "ECDHE-ECDSA-AES128-GCM-SHA256";
2508 else
2509 return -1;
2510
2511 /* Need to clear phase1="tls_suiteb=1" to allow cipher enforcement */
2512 set_network_quoted(ifname, id, "phase1", "");
2513
2514 return set_network_quoted(ifname, id, "openssl_ciphers", val);
2515}
2516
2517
Jouni Malinenf7222712019-06-13 01:50:21 +03002518static enum sigma_cmd_result cmd_sta_set_eaptls(struct sigma_dut *dut,
2519 struct sigma_conn *conn,
2520 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002521{
2522 const char *intf = get_param(cmd, "Interface");
2523 const char *ifname, *val;
2524 int id;
2525 char buf[200];
2526#ifdef ANDROID
2527 unsigned char kvalue[KEYSTORE_MESSAGE_SIZE];
2528 int length;
2529 int jb_or_newer = 0;
2530 char prop[PROPERTY_VALUE_MAX];
2531#endif /* ANDROID */
2532
2533 if (intf == NULL)
2534 return -1;
2535
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002536 if (strcmp(intf, get_main_ifname(dut)) == 0)
2537 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002538 else
2539 ifname = intf;
2540
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302541 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002542 if (id < 0)
2543 return id;
2544
2545 if (set_network(ifname, id, "eap", "TLS") < 0)
2546 return -2;
2547
Pradeep Reddy POTTETI9f6c2132016-05-05 16:28:19 +05302548 if (!get_param(cmd, "username") &&
2549 set_network_quoted(ifname, id, "identity",
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002550 "wifi-user@wifilabs.local") < 0)
2551 return -2;
2552
2553 val = get_param(cmd, "clientCertificate");
2554 if (val == NULL)
2555 return -1;
2556#ifdef ANDROID
2557 snprintf(buf, sizeof(buf), "USRPKEY_%s", val);
2558 length = android_keystore_get(ANDROID_KEYSTORE_GET, buf, kvalue);
2559 if (length < 0) {
2560 /*
2561 * JB started reporting keystore type mismatches, so retry with
2562 * the GET_PUBKEY command if the generic GET fails.
2563 */
2564 length = android_keystore_get(ANDROID_KEYSTORE_GET_PUBKEY,
2565 buf, kvalue);
2566 }
2567
2568 if (property_get("ro.build.version.release", prop, NULL) != 0) {
2569 sigma_dut_print(dut, DUT_MSG_DEBUG, "Android release %s", prop);
2570 if (strncmp(prop, "4.0", 3) != 0)
2571 jb_or_newer = 1;
2572 } else
2573 jb_or_newer = 1; /* assume newer */
2574
2575 if (jb_or_newer && length > 0) {
2576 sigma_dut_print(dut, DUT_MSG_INFO,
2577 "Use Android keystore [%s]", buf);
2578 if (set_network(ifname, id, "engine", "1") < 0)
2579 return -2;
2580 if (set_network_quoted(ifname, id, "engine_id", "keystore") < 0)
2581 return -2;
2582 snprintf(buf, sizeof(buf), "USRPKEY_%s", val);
2583 if (set_network_quoted(ifname, id, "key_id", buf) < 0)
2584 return -2;
2585 snprintf(buf, sizeof(buf), "keystore://USRCERT_%s", val);
2586 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
2587 return -2;
2588 return 1;
2589 } else if (length > 0) {
2590 sigma_dut_print(dut, DUT_MSG_INFO,
2591 "Use Android keystore [%s]", buf);
2592 snprintf(buf, sizeof(buf), "keystore://USRPKEY_%s", val);
2593 if (set_network_quoted(ifname, id, "private_key", 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 }
2600#endif /* ANDROID */
2601
2602 snprintf(buf, sizeof(buf), "%s/%s", sigma_cert_path, val);
2603#ifdef __linux__
2604 if (!file_exists(buf)) {
2605 char msg[300];
2606 snprintf(msg, sizeof(msg), "ErrorCode,clientCertificate file "
2607 "(%s) not found", buf);
2608 send_resp(dut, conn, SIGMA_ERROR, msg);
2609 return -3;
2610 }
2611#endif /* __linux__ */
2612 if (set_network_quoted(ifname, id, "private_key", buf) < 0)
2613 return -2;
2614 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
2615 return -2;
2616
2617 if (set_network_quoted(ifname, id, "private_key_passwd", "wifi") < 0)
2618 return -2;
2619
Jouni Malinen5eabb2a2017-10-03 18:17:30 +03002620 val = get_param(cmd, "keyMgmtType");
2621 if (val && strcasecmp(val, "SuiteB") == 0) {
2622 val = get_param(cmd, "CertType");
2623 if (val && strcasecmp(val, "RSA") == 0) {
2624 if (set_network_quoted(ifname, id, "phase1",
2625 "tls_suiteb=1") < 0)
2626 return -2;
2627 } else {
2628 if (set_network_quoted(ifname, id, "openssl_ciphers",
2629 "SUITEB192") < 0)
2630 return -2;
2631 }
2632
2633 val = get_param(cmd, "TLSCipher");
2634 if (set_tls_cipher(ifname, id, val) < 0) {
2635 send_resp(dut, conn, SIGMA_ERROR,
2636 "ErrorCode,Unsupported TLSCipher value");
2637 return -3;
2638 }
2639 }
2640
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002641 return 1;
2642}
2643
2644
Jouni Malinenf7222712019-06-13 01:50:21 +03002645static enum sigma_cmd_result cmd_sta_set_eapttls(struct sigma_dut *dut,
2646 struct sigma_conn *conn,
2647 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002648{
2649 const char *intf = get_param(cmd, "Interface");
2650 const char *ifname;
2651 int id;
2652
2653 if (intf == NULL)
2654 return -1;
2655
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002656 if (strcmp(intf, get_main_ifname(dut)) == 0)
2657 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002658 else
2659 ifname = intf;
2660
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302661 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002662 if (id < 0)
2663 return id;
2664
2665 if (set_network(ifname, id, "eap", "TTLS") < 0) {
2666 send_resp(dut, conn, SIGMA_ERROR,
2667 "errorCode,Failed to set TTLS method");
2668 return 0;
2669 }
2670
2671 if (set_network_quoted(ifname, id, "phase2", "auth=MSCHAPV2") < 0) {
2672 send_resp(dut, conn, SIGMA_ERROR,
2673 "errorCode,Failed to set MSCHAPv2 for TTLS Phase 2");
2674 return 0;
2675 }
2676
2677 return 1;
2678}
2679
2680
Jouni Malinenf7222712019-06-13 01:50:21 +03002681static enum sigma_cmd_result cmd_sta_set_eapsim(struct sigma_dut *dut,
2682 struct sigma_conn *conn,
2683 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002684{
2685 const char *intf = get_param(cmd, "Interface");
2686 const char *ifname;
2687 int id;
2688
2689 if (intf == NULL)
2690 return -1;
2691
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002692 if (strcmp(intf, get_main_ifname(dut)) == 0)
2693 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002694 else
2695 ifname = intf;
2696
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302697 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002698 if (id < 0)
2699 return id;
2700
2701 if (set_network(ifname, id, "eap", "SIM") < 0)
2702 return -2;
2703
2704 return 1;
2705}
2706
2707
Jouni Malinenf7222712019-06-13 01:50:21 +03002708static enum sigma_cmd_result cmd_sta_set_peap(struct sigma_dut *dut,
2709 struct sigma_conn *conn,
2710 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002711{
2712 const char *intf = get_param(cmd, "Interface");
2713 const char *ifname, *val;
2714 int id;
2715 char buf[100];
2716
2717 if (intf == NULL)
2718 return -1;
2719
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002720 if (strcmp(intf, get_main_ifname(dut)) == 0)
2721 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002722 else
2723 ifname = intf;
2724
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302725 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002726 if (id < 0)
2727 return id;
2728
2729 if (set_network(ifname, id, "eap", "PEAP") < 0)
2730 return -2;
2731
2732 val = get_param(cmd, "innerEAP");
2733 if (val) {
2734 if (strcasecmp(val, "MSCHAPv2") == 0) {
2735 if (set_network_quoted(ifname, id, "phase2",
2736 "auth=MSCHAPV2") < 0)
2737 return -2;
2738 } else if (strcasecmp(val, "GTC") == 0) {
2739 if (set_network_quoted(ifname, id, "phase2",
2740 "auth=GTC") < 0)
2741 return -2;
2742 } else
2743 return -1;
2744 }
2745
2746 val = get_param(cmd, "peapVersion");
2747 if (val) {
2748 int ver = atoi(val);
2749 if (ver < 0 || ver > 1)
2750 return -1;
2751 snprintf(buf, sizeof(buf), "peapver=%d", ver);
2752 if (set_network_quoted(ifname, id, "phase1", buf) < 0)
2753 return -2;
2754 }
2755
2756 return 1;
2757}
2758
2759
Jouni Malinenf7222712019-06-13 01:50:21 +03002760static enum sigma_cmd_result cmd_sta_set_eapfast(struct sigma_dut *dut,
2761 struct sigma_conn *conn,
2762 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002763{
2764 const char *intf = get_param(cmd, "Interface");
2765 const char *ifname, *val;
2766 int id;
2767 char buf[100];
2768
2769 if (intf == NULL)
2770 return -1;
2771
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002772 if (strcmp(intf, get_main_ifname(dut)) == 0)
2773 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002774 else
2775 ifname = intf;
2776
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302777 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002778 if (id < 0)
2779 return id;
2780
2781 if (set_network(ifname, id, "eap", "FAST") < 0)
2782 return -2;
2783
2784 val = get_param(cmd, "innerEAP");
2785 if (val) {
2786 if (strcasecmp(val, "MSCHAPV2") == 0) {
2787 if (set_network_quoted(ifname, id, "phase2",
2788 "auth=MSCHAPV2") < 0)
2789 return -2;
2790 } else if (strcasecmp(val, "GTC") == 0) {
2791 if (set_network_quoted(ifname, id, "phase2",
2792 "auth=GTC") < 0)
2793 return -2;
2794 } else
2795 return -1;
2796 }
2797
2798 val = get_param(cmd, "validateServer");
2799 if (val) {
2800 /* TODO */
2801 sigma_dut_print(dut, DUT_MSG_INFO, "Ignored EAP-FAST "
2802 "validateServer=%s", val);
2803 }
2804
2805 val = get_param(cmd, "pacFile");
2806 if (val) {
2807 snprintf(buf, sizeof(buf), "blob://%s", val);
2808 if (set_network_quoted(ifname, id, "pac_file", buf) < 0)
2809 return -2;
2810 }
2811
2812 if (set_network_quoted(ifname, id, "phase1", "fast_provisioning=2") <
2813 0)
2814 return -2;
2815
2816 return 1;
2817}
2818
2819
Jouni Malinenf7222712019-06-13 01:50:21 +03002820static enum sigma_cmd_result cmd_sta_set_eapaka(struct sigma_dut *dut,
2821 struct sigma_conn *conn,
2822 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002823{
2824 const char *intf = get_param(cmd, "Interface");
Purushottam Kushwahacdd8cb12019-10-04 11:33:59 +05302825 const char *username = get_param(cmd, "Username");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002826 const char *ifname;
2827 int id;
2828
2829 if (intf == NULL)
2830 return -1;
2831
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002832 if (strcmp(intf, get_main_ifname(dut)) == 0)
2833 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002834 else
2835 ifname = intf;
2836
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302837 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002838 if (id < 0)
2839 return id;
2840
Purushottam Kushwahacdd8cb12019-10-04 11:33:59 +05302841 /* RFC 5448: EAP-AKA' MUST use the leading character "6" (ASCII 36
2842 * hexadecimal).
2843 */
2844 if (username && username[0] == '6') {
2845 if (set_network(ifname, id, "eap", "AKA'") < 0)
2846 return -2;
2847 } else if (set_network(ifname, id, "eap", "AKA") < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002848 return -2;
Purushottam Kushwahacdd8cb12019-10-04 11:33:59 +05302849 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002850
2851 return 1;
2852}
2853
2854
Jouni Malinenf7222712019-06-13 01:50:21 +03002855static enum sigma_cmd_result cmd_sta_set_eapakaprime(struct sigma_dut *dut,
2856 struct sigma_conn *conn,
2857 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002858{
2859 const char *intf = get_param(cmd, "Interface");
2860 const char *ifname;
2861 int id;
2862
2863 if (intf == NULL)
2864 return -1;
2865
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002866 if (strcmp(intf, get_main_ifname(dut)) == 0)
2867 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002868 else
2869 ifname = intf;
2870
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302871 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002872 if (id < 0)
2873 return id;
2874
2875 if (set_network(ifname, id, "eap", "AKA'") < 0)
2876 return -2;
2877
2878 return 1;
2879}
2880
2881
2882static int sta_set_open(struct sigma_dut *dut, struct sigma_conn *conn,
2883 struct sigma_cmd *cmd)
2884{
2885 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002886 const char *network_mode = get_param(cmd, "network_mode");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002887 const char *ifname;
2888 int id;
2889
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002890 if (strcmp(intf, get_main_ifname(dut)) == 0)
2891 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002892 else
2893 ifname = intf;
2894
2895 id = add_network_common(dut, conn, ifname, cmd);
2896 if (id < 0)
2897 return id;
2898
2899 if (set_network(ifname, id, "key_mgmt", "NONE") < 0)
2900 return -2;
2901
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002902 if (dut->program == PROGRAM_60GHZ && network_mode &&
2903 strcasecmp(network_mode, "PBSS") == 0 &&
2904 set_network(ifname, id, "pbss", "1") < 0)
2905 return -2;
2906
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002907 return 1;
2908}
2909
2910
Jouni Malinen47dcc952017-10-09 16:43:24 +03002911static int sta_set_owe(struct sigma_dut *dut, struct sigma_conn *conn,
2912 struct sigma_cmd *cmd)
2913{
2914 const char *intf = get_param(cmd, "Interface");
2915 const char *ifname, *val;
2916 int id;
2917
2918 if (intf == NULL)
2919 return -1;
2920
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002921 if (strcmp(intf, get_main_ifname(dut)) == 0)
2922 ifname = get_station_ifname(dut);
Jouni Malinen47dcc952017-10-09 16:43:24 +03002923 else
2924 ifname = intf;
2925
2926 id = set_wpa_common(dut, conn, ifname, cmd);
2927 if (id < 0)
2928 return id;
2929
2930 if (set_network(ifname, id, "key_mgmt", "OWE") < 0)
2931 return -2;
2932
2933 val = get_param(cmd, "ECGroupID");
Jouni Malinenfac9cad2017-10-10 18:35:55 +03002934 if (val && strcmp(val, "0") == 0) {
2935 if (wpa_command(ifname,
2936 "VENDOR_ELEM_ADD 13 ff23200000783590fb7440e03d5b3b33911f86affdcc6b4411b707846ac4ff08ddc8831ccd") != 0) {
2937 sigma_dut_print(dut, DUT_MSG_ERROR,
2938 "Failed to set OWE DH Param element override");
2939 return -2;
2940 }
Hu Wang6010ce72020-03-05 19:33:53 +08002941 } else if (val &&
2942 (set_network(ifname, id, "owe_group", val) < 0 ||
2943 (dut->owe_ptk_workaround &&
2944 set_network(ifname, id, "owe_ptk_workaround", "1") < 0))) {
Jouni Malinen47dcc952017-10-09 16:43:24 +03002945 sigma_dut_print(dut, DUT_MSG_ERROR,
Hu Wang6010ce72020-03-05 19:33:53 +08002946 "Failed to set owe_group");
Jouni Malinen47dcc952017-10-09 16:43:24 +03002947 return -2;
2948 }
2949
2950 return 1;
2951}
2952
2953
Jouni Malinenf7222712019-06-13 01:50:21 +03002954static enum sigma_cmd_result cmd_sta_set_security(struct sigma_dut *dut,
2955 struct sigma_conn *conn,
2956 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002957{
2958 const char *type = get_param(cmd, "Type");
2959
2960 if (type == NULL) {
2961 send_resp(dut, conn, SIGMA_ERROR,
2962 "ErrorCode,Missing Type argument");
2963 return 0;
2964 }
2965
2966 if (strcasecmp(type, "OPEN") == 0)
2967 return sta_set_open(dut, conn, cmd);
Jouni Malinen47dcc952017-10-09 16:43:24 +03002968 if (strcasecmp(type, "OWE") == 0)
2969 return sta_set_owe(dut, conn, cmd);
Jouni Malinen992a81e2017-08-22 13:57:47 +03002970 if (strcasecmp(type, "PSK") == 0 ||
Jouni Malinen0ab50f42017-08-31 01:34:59 +03002971 strcasecmp(type, "PSK-SAE") == 0 ||
Jouni Malinen992a81e2017-08-22 13:57:47 +03002972 strcasecmp(type, "SAE") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002973 return cmd_sta_set_psk(dut, conn, cmd);
2974 if (strcasecmp(type, "EAPTLS") == 0)
2975 return cmd_sta_set_eaptls(dut, conn, cmd);
2976 if (strcasecmp(type, "EAPTTLS") == 0)
2977 return cmd_sta_set_eapttls(dut, conn, cmd);
2978 if (strcasecmp(type, "EAPPEAP") == 0)
2979 return cmd_sta_set_peap(dut, conn, cmd);
2980 if (strcasecmp(type, "EAPSIM") == 0)
2981 return cmd_sta_set_eapsim(dut, conn, cmd);
2982 if (strcasecmp(type, "EAPFAST") == 0)
2983 return cmd_sta_set_eapfast(dut, conn, cmd);
2984 if (strcasecmp(type, "EAPAKA") == 0)
2985 return cmd_sta_set_eapaka(dut, conn, cmd);
2986 if (strcasecmp(type, "EAPAKAPRIME") == 0)
2987 return cmd_sta_set_eapakaprime(dut, conn, cmd);
Amarnath Hullur Subramanyam81b11cd2018-01-30 19:07:17 -08002988 if (strcasecmp(type, "wep") == 0)
2989 return cmd_sta_set_encryption(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002990
2991 send_resp(dut, conn, SIGMA_ERROR,
2992 "ErrorCode,Unsupported Type value");
2993 return 0;
2994}
2995
2996
2997int ath6kl_client_uapsd(struct sigma_dut *dut, const char *intf, int uapsd)
2998{
2999#ifdef __linux__
3000 /* special handling for ath6kl */
3001 char path[128], fname[128], *pos;
3002 ssize_t res;
3003 FILE *f;
3004
Jouni Malinene39cd562019-05-29 23:39:56 +03003005 res = snprintf(fname, sizeof(fname), "/sys/class/net/%s/phy80211",
3006 intf);
3007 if (res < 0 || res >= sizeof(fname))
3008 return 0;
3009 res = readlink(fname, path, sizeof(path));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003010 if (res < 0)
3011 return 0; /* not ath6kl */
3012
3013 if (res >= (int) sizeof(path))
3014 res = sizeof(path) - 1;
3015 path[res] = '\0';
3016 pos = strrchr(path, '/');
3017 if (pos == NULL)
3018 pos = path;
3019 else
3020 pos++;
Jouni Malinen77dda642020-01-07 11:21:55 +02003021 res = snprintf(fname, sizeof(fname),
3022 "/sys/kernel/debug/ieee80211/%s/ath6kl/"
3023 "create_qos", pos);
3024 if (res < 0 || res >= sizeof(fname) || !file_exists(fname))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003025 return 0; /* not ath6kl */
3026
3027 if (uapsd) {
3028 f = fopen(fname, "w");
3029 if (f == NULL)
3030 return -1;
3031
3032 sigma_dut_print(dut, DUT_MSG_DEBUG, "Use ath6kl create_qos");
3033 fprintf(f, "4 2 2 1 2 9999999 9999999 9999999 7777777 0 4 "
3034 "45000 200 56789000 56789000 5678900 0 0 9999999 "
3035 "20000 0\n");
3036 fclose(f);
3037 } else {
Jouni Malinen77dda642020-01-07 11:21:55 +02003038 res = snprintf(fname, sizeof(fname),
3039 "/sys/kernel/debug/ieee80211/%s/ath6kl/"
3040 "delete_qos", pos);
3041 if (res < 0 || res >= sizeof(fname))
3042 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003043
3044 f = fopen(fname, "w");
3045 if (f == NULL)
3046 return -1;
3047
3048 sigma_dut_print(dut, DUT_MSG_DEBUG, "Use ath6kl delete_qos");
3049 fprintf(f, "2 4\n");
3050 fclose(f);
3051 }
3052#endif /* __linux__ */
3053
3054 return 0;
3055}
3056
3057
Jouni Malinenf7222712019-06-13 01:50:21 +03003058static enum sigma_cmd_result cmd_sta_set_uapsd(struct sigma_dut *dut,
3059 struct sigma_conn *conn,
3060 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003061{
3062 const char *intf = get_param(cmd, "Interface");
3063 /* const char *ssid = get_param(cmd, "ssid"); */
3064 const char *val;
3065 int max_sp_len = 4;
3066 int ac_be = 1, ac_bk = 1, ac_vi = 1, ac_vo = 1;
3067 char buf[100];
3068 int ret1, ret2;
3069
3070 val = get_param(cmd, "maxSPLength");
3071 if (val) {
3072 max_sp_len = atoi(val);
3073 if (max_sp_len != 0 && max_sp_len != 1 && max_sp_len != 2 &&
3074 max_sp_len != 4)
3075 return -1;
3076 }
3077
3078 val = get_param(cmd, "acBE");
3079 if (val)
3080 ac_be = atoi(val);
3081
3082 val = get_param(cmd, "acBK");
3083 if (val)
3084 ac_bk = atoi(val);
3085
3086 val = get_param(cmd, "acVI");
3087 if (val)
3088 ac_vi = atoi(val);
3089
3090 val = get_param(cmd, "acVO");
3091 if (val)
3092 ac_vo = atoi(val);
3093
3094 dut->client_uapsd = ac_be || ac_bk || ac_vi || ac_vo;
3095
3096 snprintf(buf, sizeof(buf), "P2P_SET client_apsd %d,%d,%d,%d;%d",
3097 ac_be, ac_bk, ac_vi, ac_vo, max_sp_len);
3098 ret1 = wpa_command(intf, buf);
3099
3100 snprintf(buf, sizeof(buf), "SET uapsd %d,%d,%d,%d;%d",
3101 ac_be, ac_bk, ac_vi, ac_vo, max_sp_len);
3102 ret2 = wpa_command(intf, buf);
3103
3104 if (ret1 && ret2) {
3105 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to set client mode "
3106 "UAPSD parameters.");
3107 return -2;
3108 }
3109
3110 if (ath6kl_client_uapsd(dut, intf, dut->client_uapsd) < 0) {
3111 send_resp(dut, conn, SIGMA_ERROR,
3112 "ErrorCode,Failed to set ath6kl QoS parameters");
3113 return 0;
3114 }
3115
3116 return 1;
3117}
3118
3119
Jouni Malinenf7222712019-06-13 01:50:21 +03003120static enum sigma_cmd_result cmd_sta_set_wmm(struct sigma_dut *dut,
3121 struct sigma_conn *conn,
3122 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003123{
3124 char buf[1000];
3125 const char *intf = get_param(cmd, "Interface");
3126 const char *grp = get_param(cmd, "Group");
3127 const char *act = get_param(cmd, "Action");
3128 const char *tid = get_param(cmd, "Tid");
3129 const char *dir = get_param(cmd, "Direction");
3130 const char *psb = get_param(cmd, "Psb");
3131 const char *up = get_param(cmd, "Up");
3132 const char *fixed = get_param(cmd, "Fixed");
3133 const char *size = get_param(cmd, "Size");
3134 const char *msize = get_param(cmd, "Maxsize");
3135 const char *minsi = get_param(cmd, "Min_srvc_intrvl");
3136 const char *maxsi = get_param(cmd, "Max_srvc_intrvl");
3137 const char *inact = get_param(cmd, "Inactivity");
3138 const char *sus = get_param(cmd, "Suspension");
3139 const char *mindr = get_param(cmd, "Mindatarate");
3140 const char *meandr = get_param(cmd, "Meandatarate");
3141 const char *peakdr = get_param(cmd, "Peakdatarate");
3142 const char *phyrate = get_param(cmd, "Phyrate");
3143 const char *burstsize = get_param(cmd, "Burstsize");
3144 const char *sba = get_param(cmd, "Sba");
3145 int direction;
3146 int handle;
Peng Xu93319622017-10-04 17:58:16 -07003147 float sba_fv = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003148 int fixed_int;
3149 int psb_ts;
3150
3151 if (intf == NULL || grp == NULL || act == NULL )
3152 return -1;
3153
3154 if (strcasecmp(act, "addts") == 0) {
3155 if (tid == NULL || dir == NULL || psb == NULL ||
3156 up == NULL || fixed == NULL || size == NULL)
3157 return -1;
3158
3159 /*
3160 * Note: Sigma CAPI spec lists uplink, downlink, and bidi as the
3161 * possible values, but WMM-AC and V-E test scripts use "UP,
3162 * "DOWN", and "BIDI".
3163 */
3164 if (strcasecmp(dir, "uplink") == 0 ||
3165 strcasecmp(dir, "up") == 0) {
3166 direction = 0;
3167 } else if (strcasecmp(dir, "downlink") == 0 ||
3168 strcasecmp(dir, "down") == 0) {
3169 direction = 1;
3170 } else if (strcasecmp(dir, "bidi") == 0) {
3171 direction = 2;
3172 } else {
3173 sigma_dut_print(dut, DUT_MSG_ERROR,
3174 "Direction %s not supported", dir);
3175 return -1;
3176 }
3177
3178 if (strcasecmp(psb, "legacy") == 0) {
3179 psb_ts = 0;
3180 } else if (strcasecmp(psb, "uapsd") == 0) {
3181 psb_ts = 1;
3182 } else {
3183 sigma_dut_print(dut, DUT_MSG_ERROR,
3184 "PSB %s not supported", psb);
3185 return -1;
3186 }
3187
3188 if (atoi(tid) < 0 || atoi(tid) > 7) {
3189 sigma_dut_print(dut, DUT_MSG_ERROR,
3190 "TID %s not supported", tid);
3191 return -1;
3192 }
3193
3194 if (strcasecmp(fixed, "true") == 0) {
3195 fixed_int = 1;
3196 } else {
3197 fixed_int = 0;
3198 }
3199
Peng Xu93319622017-10-04 17:58:16 -07003200 if (sba)
3201 sba_fv = atof(sba);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003202
3203 dut->dialog_token++;
3204 handle = 7000 + dut->dialog_token;
3205
3206 /*
3207 * size: convert to hex
3208 * maxsi: convert to hex
3209 * mindr: convert to hex
3210 * meandr: convert to hex
3211 * peakdr: convert to hex
3212 * burstsize: convert to hex
3213 * phyrate: convert to hex
3214 * sba: convert to hex with modification
3215 * minsi: convert to integer
3216 * sus: convert to integer
3217 * inact: convert to integer
3218 * maxsi: convert to integer
3219 */
3220
3221 /*
3222 * The Nominal MSDU Size field is 2 octets long and contains an
3223 * unsigned integer that specifies the nominal size, in octets,
3224 * of MSDUs belonging to the traffic under this traffic
3225 * specification and is defined in Figure 16. If the Fixed
3226 * subfield is set to 1, then the size of the MSDU is fixed and
3227 * is indicated by the Size Subfield. If the Fixed subfield is
3228 * set to 0, then the size of the MSDU might not be fixed and
3229 * the Size indicates the nominal MSDU size.
3230 *
3231 * The Surplus Bandwidth Allowance Factor field is 2 octets long
3232 * and specifies the excess allocation of time (and bandwidth)
3233 * over and above the stated rates required to transport an MSDU
3234 * belonging to the traffic in this TSPEC. This field is
3235 * represented as an unsigned binary number with an implicit
3236 * binary point after the leftmost 3 bits. For example, an SBA
3237 * of 1.75 is represented as 0x3800. This field is included to
3238 * account for retransmissions. As such, the value of this field
3239 * must be greater than unity.
3240 */
3241
3242 snprintf(buf, sizeof(buf),
3243 "iwpriv %s addTspec %d %s %d %d %s 0x%X"
3244 " 0x%X 0x%X 0x%X"
3245 " 0x%X 0x%X 0x%X"
3246 " 0x%X %d %d %d %d"
3247 " %d %d",
3248 intf, handle, tid, direction, psb_ts, up,
3249 (unsigned int) ((fixed_int << 15) | atoi(size)),
3250 msize ? atoi(msize) : 0,
3251 mindr ? atoi(mindr) : 0,
3252 meandr ? atoi(meandr) : 0,
3253 peakdr ? atoi(peakdr) : 0,
3254 burstsize ? atoi(burstsize) : 0,
3255 phyrate ? atoi(phyrate) : 0,
3256 sba ? ((unsigned int) (((int) sba_fv << 13) |
3257 (int)((sba_fv - (int) sba_fv) *
3258 8192))) : 0,
3259 minsi ? atoi(minsi) : 0,
3260 sus ? atoi(sus) : 0,
3261 0, 0,
3262 inact ? atoi(inact) : 0,
3263 maxsi ? atoi(maxsi) : 0);
3264
3265 if (system(buf) != 0) {
3266 sigma_dut_print(dut, DUT_MSG_ERROR,
3267 "iwpriv addtspec request failed");
3268 send_resp(dut, conn, SIGMA_ERROR,
3269 "errorCode,Failed to execute addTspec command");
3270 return 0;
3271 }
3272
3273 sigma_dut_print(dut, DUT_MSG_INFO,
3274 "iwpriv addtspec request send");
3275
3276 /* Mapping handle to a TID */
3277 dut->tid_to_handle[atoi(tid)] = handle;
3278 } else if (strcasecmp(act, "delts") == 0) {
3279 if (tid == NULL)
3280 return -1;
3281
3282 if (atoi(tid) < 0 || atoi(tid) > 7) {
3283 sigma_dut_print(dut, DUT_MSG_ERROR,
3284 "TID %s not supported", tid);
3285 send_resp(dut, conn, SIGMA_ERROR,
3286 "errorCode,Unsupported TID");
3287 return 0;
3288 }
3289
3290 handle = dut->tid_to_handle[atoi(tid)];
3291
3292 if (handle < 7000 || handle > 7255) {
3293 /* Invalid handle ie no mapping for that TID */
3294 sigma_dut_print(dut, DUT_MSG_ERROR,
3295 "handle-> %d not found", handle);
3296 }
3297
3298 snprintf(buf, sizeof(buf), "iwpriv %s delTspec %d",
3299 intf, handle);
3300
3301 if (system(buf) != 0) {
3302 sigma_dut_print(dut, DUT_MSG_ERROR,
3303 "iwpriv deltspec request failed");
3304 send_resp(dut, conn, SIGMA_ERROR,
3305 "errorCode,Failed to execute delTspec command");
3306 return 0;
3307 }
3308
3309 sigma_dut_print(dut, DUT_MSG_INFO,
3310 "iwpriv deltspec request send");
3311
3312 dut->tid_to_handle[atoi(tid)] = 0;
3313 } else {
3314 sigma_dut_print(dut, DUT_MSG_ERROR,
3315 "Action type %s not supported", act);
3316 send_resp(dut, conn, SIGMA_ERROR,
3317 "errorCode,Unsupported Action");
3318 return 0;
3319 }
3320
3321 return 1;
3322}
3323
3324
vamsi krishna52e16f92017-08-29 12:37:34 +05303325static int find_network(struct sigma_dut *dut, const char *ssid)
3326{
3327 char list[4096];
3328 char *pos;
3329
3330 sigma_dut_print(dut, DUT_MSG_DEBUG,
3331 "Search for profile based on SSID: '%s'", ssid);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003332 if (wpa_command_resp(get_station_ifname(dut), "LIST_NETWORKS",
vamsi krishna52e16f92017-08-29 12:37:34 +05303333 list, sizeof(list)) < 0)
3334 return -1;
3335 pos = strstr(list, ssid);
3336 if (!pos || pos == list || pos[-1] != '\t' || pos[strlen(ssid)] != '\t')
3337 return -1;
3338
3339 while (pos > list && pos[-1] != '\n')
3340 pos--;
3341 dut->infra_network_id = atoi(pos);
3342 snprintf(dut->infra_ssid, sizeof(dut->infra_ssid), "%s", ssid);
3343 return 0;
3344}
3345
3346
Sunil Dutt44595082018-02-12 19:41:45 +05303347#ifdef NL80211_SUPPORT
3348static int sta_config_rsnie(struct sigma_dut *dut, int val)
3349{
3350 struct nl_msg *msg;
3351 int ret;
3352 struct nlattr *params;
3353 int ifindex;
3354
3355 ifindex = if_nametoindex("wlan0");
3356 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
3357 NL80211_CMD_VENDOR)) ||
3358 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
3359 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
3360 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
3361 QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION) ||
3362 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
3363 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE, val)) {
3364 sigma_dut_print(dut, DUT_MSG_ERROR,
3365 "%s: err in adding vendor_cmd and vendor_data",
3366 __func__);
3367 nlmsg_free(msg);
3368 return -1;
3369 }
3370 nla_nest_end(msg, params);
3371
3372 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
3373 if (ret) {
3374 sigma_dut_print(dut, DUT_MSG_ERROR,
3375 "%s: err in send_and_recv_msgs, ret=%d",
3376 __func__, ret);
3377 return ret;
3378 }
3379
3380 return 0;
3381}
3382#endif /* NL80211_SUPPORT */
3383
3384
Jouni Malinenf7222712019-06-13 01:50:21 +03003385static enum sigma_cmd_result cmd_sta_associate(struct sigma_dut *dut,
3386 struct sigma_conn *conn,
3387 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003388{
3389 /* const char *intf = get_param(cmd, "Interface"); */
3390 const char *ssid = get_param(cmd, "ssid");
3391 const char *wps_param = get_param(cmd, "WPS");
3392 const char *bssid = get_param(cmd, "bssid");
Jouni Malinen46a19b62017-06-23 14:31:27 +03003393 const char *chan = get_param(cmd, "channel");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02003394 const char *network_mode = get_param(cmd, "network_mode");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003395 int wps = 0;
Jouni Malinen3c367e82017-06-23 17:01:47 +03003396 char buf[1000], extra[50];
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003397 int e;
3398 enum sigma_cmd_result ret = SUCCESS_SEND_STATUS;
3399 struct wpa_ctrl *ctrl = NULL;
3400 int num_network_not_found = 0;
3401 int num_disconnected = 0;
3402 int tod = -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003403
3404 if (ssid == NULL)
3405 return -1;
3406
Jouni Malinen37d5c692019-08-19 16:56:55 +03003407 dut->server_cert_tod = 0;
3408
Jouni Malinen3c367e82017-06-23 17:01:47 +03003409 if (dut->rsne_override) {
Sunil Dutt44595082018-02-12 19:41:45 +05303410#ifdef NL80211_SUPPORT
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003411 if (get_driver_type(dut) == DRIVER_WCN) {
Sunil Dutt44595082018-02-12 19:41:45 +05303412 sta_config_rsnie(dut, 1);
3413 dut->config_rsnie = 1;
3414 }
3415#endif /* NL80211_SUPPORT */
Jouni Malinen3c367e82017-06-23 17:01:47 +03003416 snprintf(buf, sizeof(buf), "TEST_ASSOC_IE %s",
3417 dut->rsne_override);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003418 if (wpa_command(get_station_ifname(dut), buf) < 0) {
Jouni Malinen3c367e82017-06-23 17:01:47 +03003419 send_resp(dut, conn, SIGMA_ERROR,
3420 "ErrorCode,Failed to set DEV_CONFIGURE_IE RSNE override");
3421 return 0;
3422 }
3423 }
3424
Jouni Malinen68143132017-09-02 02:34:08 +03003425 if (dut->sae_commit_override) {
3426 snprintf(buf, sizeof(buf), "SET sae_commit_override %s",
3427 dut->sae_commit_override);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003428 if (wpa_command(get_station_ifname(dut), buf) < 0) {
Jouni Malinen68143132017-09-02 02:34:08 +03003429 send_resp(dut, conn, SIGMA_ERROR,
3430 "ErrorCode,Failed to set SAE commit override");
3431 return 0;
3432 }
3433 }
Ankita Bajaj1bde7942018-01-09 19:15:01 +05303434#ifdef ANDROID
3435 if (dut->fils_hlp)
3436 process_fils_hlp(dut);
3437#endif /* ANDROID */
Jouni Malinen68143132017-09-02 02:34:08 +03003438
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003439 if (wps_param &&
3440 (strcmp(wps_param, "1") == 0 || strcasecmp(wps_param, "On") == 0))
3441 wps = 1;
3442
3443 if (wps) {
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02003444 if (dut->program == PROGRAM_60GHZ && network_mode &&
3445 strcasecmp(network_mode, "PBSS") == 0 &&
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003446 set_network(get_station_ifname(dut), dut->infra_network_id,
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02003447 "pbss", "1") < 0)
3448 return -2;
3449
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003450 if (dut->wps_method == WFA_CS_WPS_NOT_READY) {
3451 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,WPS "
3452 "parameters not yet set");
3453 return 0;
3454 }
3455 if (dut->wps_method == WFA_CS_WPS_PBC) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003456 if (wpa_command(get_station_ifname(dut), "WPS_PBC") < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003457 return -2;
3458 } else {
3459 snprintf(buf, sizeof(buf), "WPS_PIN any %s",
3460 dut->wps_pin);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003461 if (wpa_command(get_station_ifname(dut), buf) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003462 return -2;
3463 }
3464 } else {
vamsi krishna52e16f92017-08-29 12:37:34 +05303465 if (strcmp(ssid, dut->infra_ssid) == 0) {
3466 sigma_dut_print(dut, DUT_MSG_DEBUG,
3467 "sta_associate for the most recently added network");
3468 } else if (find_network(dut, ssid) < 0) {
3469 sigma_dut_print(dut, DUT_MSG_DEBUG,
3470 "sta_associate for a previously stored network profile");
3471 send_resp(dut, conn, SIGMA_ERROR,
3472 "ErrorCode,Profile not found");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003473 return 0;
3474 }
3475
3476 if (bssid &&
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003477 set_network(get_station_ifname(dut), dut->infra_network_id,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003478 "bssid", bssid) < 0) {
3479 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
3480 "Invalid bssid argument");
3481 return 0;
3482 }
3483
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003484 if (dut->program == PROGRAM_WPA3 &&
3485 dut->sta_associate_wait_connect) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003486 ctrl = open_wpa_mon(get_station_ifname(dut));
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003487 if (!ctrl)
3488 return ERROR_SEND_STATUS;
3489 }
3490
Jouni Malinen46a19b62017-06-23 14:31:27 +03003491 extra[0] = '\0';
3492 if (chan)
3493 snprintf(extra, sizeof(extra), " freq=%u",
Alexei Avshalom Lazar093569f2018-11-13 14:08:17 +02003494 channel_to_freq(dut, atoi(chan)));
Jouni Malinen46a19b62017-06-23 14:31:27 +03003495 snprintf(buf, sizeof(buf), "SELECT_NETWORK %d%s",
3496 dut->infra_network_id, extra);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003497 if (wpa_command(get_station_ifname(dut), buf) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003498 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to select "
3499 "network id %d on %s",
3500 dut->infra_network_id,
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003501 get_station_ifname(dut));
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003502 ret = ERROR_SEND_STATUS;
3503 goto done;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003504 }
3505 }
3506
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003507 if (!ctrl)
3508 return SUCCESS_SEND_STATUS;
3509
3510 /* Wait for connection result to be able to store server certificate
3511 * hash for trust root override testing
3512 * (dev_exec_action,ServerCertTrust). */
3513
3514 for (e = 0; e < 20; e++) {
3515 const char *events[] = {
3516 "CTRL-EVENT-EAP-PEER-CERT",
3517 "CTRL-EVENT-EAP-TLS-CERT-ERROR",
3518 "CTRL-EVENT-DISCONNECTED",
3519 "CTRL-EVENT-CONNECTED",
3520 "CTRL-EVENT-NETWORK-NOT-FOUND",
3521 NULL
3522 };
3523 char buf[1024];
3524 int res;
3525
3526 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
3527 if (res < 0) {
Jouni Malinenf1f16642019-11-15 21:19:04 +02003528 send_resp(dut, conn, SIGMA_COMPLETE,
3529 "Result,Association did not complete");
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003530 ret = STATUS_SENT_ERROR;
3531 break;
3532 }
3533 sigma_dut_print(dut, DUT_MSG_DEBUG, "Connection event: %s",
3534 buf);
3535
3536 if (strstr(buf, "CTRL-EVENT-EAP-PEER-CERT") &&
3537 strstr(buf, " depth=0")) {
3538 char *pos = strstr(buf, " hash=");
3539
3540 if (pos) {
3541 char *end;
3542
Jouni Malinen34b19cb2019-08-16 16:37:17 +03003543 if (strstr(buf, " tod=1"))
3544 tod = 1;
3545 else if (strstr(buf, " tod=2"))
3546 tod = 2;
3547 else
3548 tod = 0;
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003549 sigma_dut_print(dut, DUT_MSG_DEBUG,
3550 "Server certificate TOD policy: %d",
3551 tod);
Jouni Malinen37d5c692019-08-19 16:56:55 +03003552 dut->server_cert_tod = tod;
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003553
3554 pos += 6;
3555 end = strchr(pos, ' ');
3556 if (end)
3557 *end = '\0';
3558 strlcpy(dut->server_cert_hash, pos,
3559 sizeof(dut->server_cert_hash));
3560 sigma_dut_print(dut, DUT_MSG_DEBUG,
3561 "Server certificate hash: %s",
3562 dut->server_cert_hash);
3563 }
3564 }
3565
3566 if (strstr(buf, "CTRL-EVENT-EAP-TLS-CERT-ERROR")) {
3567 send_resp(dut, conn, SIGMA_COMPLETE,
3568 "Result,TLS server certificate validation failed");
3569 ret = STATUS_SENT_ERROR;
3570 break;
3571 }
3572
3573 if (strstr(buf, "CTRL-EVENT-NETWORK-NOT-FOUND")) {
3574 num_network_not_found++;
3575
3576 if (num_network_not_found > 2) {
3577 send_resp(dut, conn, SIGMA_COMPLETE,
3578 "Result,Network not found");
3579 ret = STATUS_SENT_ERROR;
3580 break;
3581 }
3582 }
3583
3584 if (strstr(buf, "CTRL-EVENT-DISCONNECTED")) {
3585 num_disconnected++;
3586
3587 if (num_disconnected > 2) {
3588 send_resp(dut, conn, SIGMA_COMPLETE,
3589 "Result,Connection failed");
3590 ret = STATUS_SENT_ERROR;
3591 break;
3592 }
3593 }
3594
3595 if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
3596 if (tod >= 0) {
3597 sigma_dut_print(dut, DUT_MSG_DEBUG,
3598 "Network profile TOD policy update: %d -> %d",
3599 dut->sta_tod_policy, tod);
3600 dut->sta_tod_policy = tod;
3601 }
3602 break;
3603 }
3604 }
3605done:
3606 if (ctrl) {
3607 wpa_ctrl_detach(ctrl);
3608 wpa_ctrl_close(ctrl);
3609 }
3610 return ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003611}
3612
3613
3614static int run_hs20_osu(struct sigma_dut *dut, const char *params)
3615{
3616 char buf[500], cmd[200];
3617 int res;
3618
3619 /* Use hs20-osu-client file at the current dir, if found; otherwise use
3620 * default path */
3621 res = snprintf(cmd, sizeof(cmd),
3622 "%s -w \"%s\" -r hs20-osu-client.res %s%s -dddKt -f Logs/hs20-osu-client.txt",
3623 file_exists("./hs20-osu-client") ?
3624 "./hs20-osu-client" : "hs20-osu-client",
3625 sigma_wpas_ctrl,
3626 dut->summary_log ? "-s " : "",
3627 dut->summary_log ? dut->summary_log : "");
3628 if (res < 0 || res >= (int) sizeof(cmd))
3629 return -1;
3630
3631 res = snprintf(buf, sizeof(buf), "%s %s", cmd, params);
3632 if (res < 0 || res >= (int) sizeof(buf))
3633 return -1;
3634 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
3635
3636 if (system(buf) != 0) {
3637 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to run: %s", buf);
3638 return -1;
3639 }
3640 sigma_dut_print(dut, DUT_MSG_DEBUG,
3641 "Completed hs20-osu-client operation");
3642
3643 return 0;
3644}
3645
3646
3647static int download_ppsmo(struct sigma_dut *dut,
3648 struct sigma_conn *conn,
3649 const char *intf,
3650 struct sigma_cmd *cmd)
3651{
3652 const char *name, *path, *val;
3653 char url[500], buf[600], fbuf[100];
3654 char *fqdn = NULL;
3655
3656 name = get_param(cmd, "FileName");
3657 path = get_param(cmd, "FilePath");
3658 if (name == NULL || path == NULL)
3659 return -1;
3660
3661 if (strcasecmp(path, "VendorSpecific") == 0) {
3662 snprintf(url, sizeof(url), "PPS/%s", name);
3663 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured PPS MO "
3664 "from the device (%s)", url);
3665 if (!file_exists(url)) {
3666 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
3667 "PPS MO file does not exist");
3668 return 0;
3669 }
3670 snprintf(buf, sizeof(buf), "cp %s pps-tnds.xml", url);
3671 if (system(buf) != 0) {
3672 send_resp(dut, conn, SIGMA_ERROR,
3673 "errorCode,Failed to copy PPS MO");
3674 return 0;
3675 }
3676 } else if (strncasecmp(path, "http:", 5) != 0 &&
3677 strncasecmp(path, "https:", 6) != 0) {
3678 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
3679 "Unsupported FilePath value");
3680 return 0;
3681 } else {
3682 snprintf(url, sizeof(url), "%s/%s", path, name);
3683 sigma_dut_print(dut, DUT_MSG_INFO, "Downloading PPS MO from %s",
3684 url);
3685 snprintf(buf, sizeof(buf), "wget -T 10 -t 3 -O pps-tnds.xml '%s'", url);
3686 remove("pps-tnds.xml");
3687 if (system(buf) != 0) {
3688 send_resp(dut, conn, SIGMA_ERROR,
3689 "errorCode,Failed to download PPS MO");
3690 return 0;
3691 }
3692 }
3693
3694 if (run_hs20_osu(dut, "from_tnds pps-tnds.xml pps.xml") < 0) {
3695 send_resp(dut, conn, SIGMA_ERROR,
3696 "errorCode,Failed to parse downloaded PPSMO");
3697 return 0;
3698 }
3699 unlink("pps-tnds.xml");
3700
3701 val = get_param(cmd, "managementTreeURI");
3702 if (val) {
3703 const char *pos, *end;
3704 sigma_dut_print(dut, DUT_MSG_DEBUG, "managementTreeURI: %s",
3705 val);
3706 if (strncmp(val, "./Wi-Fi/", 8) != 0) {
3707 send_resp(dut, conn, SIGMA_ERROR,
3708 "errorCode,Invalid managementTreeURI prefix");
3709 return 0;
3710 }
3711 pos = val + 8;
3712 end = strchr(pos, '/');
3713 if (end == NULL ||
3714 strcmp(end, "/PerProviderSubscription") != 0) {
3715 send_resp(dut, conn, SIGMA_ERROR,
3716 "errorCode,Invalid managementTreeURI postfix");
3717 return 0;
3718 }
3719 if (end - pos >= (int) sizeof(fbuf)) {
3720 send_resp(dut, conn, SIGMA_ERROR,
3721 "errorCode,Too long FQDN in managementTreeURI");
3722 return 0;
3723 }
3724 memcpy(fbuf, pos, end - pos);
3725 fbuf[end - pos] = '\0';
3726 fqdn = fbuf;
3727 sigma_dut_print(dut, DUT_MSG_INFO,
3728 "FQDN from managementTreeURI: %s", fqdn);
3729 } else if (run_hs20_osu(dut, "get_fqdn pps.xml") == 0) {
3730 FILE *f = fopen("pps-fqdn", "r");
3731 if (f) {
3732 if (fgets(fbuf, sizeof(fbuf), f)) {
3733 fbuf[sizeof(fbuf) - 1] = '\0';
3734 fqdn = fbuf;
3735 sigma_dut_print(dut, DUT_MSG_DEBUG,
3736 "Use FQDN %s", fqdn);
3737 }
3738 fclose(f);
3739 }
3740 }
3741
3742 if (fqdn == NULL) {
3743 send_resp(dut, conn, SIGMA_ERROR,
3744 "errorCode,No FQDN specified");
3745 return 0;
3746 }
3747
3748 mkdir("SP", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
3749 snprintf(buf, sizeof(buf), "SP/%s", fqdn);
3750 mkdir(buf, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
3751
3752 snprintf(buf, sizeof(buf), "SP/%s/pps.xml", fqdn);
3753 if (rename("pps.xml", buf) < 0) {
3754 send_resp(dut, conn, SIGMA_ERROR,
3755 "errorCode,Could not move PPS MO");
3756 return 0;
3757 }
3758
3759 if (strcasecmp(path, "VendorSpecific") == 0) {
3760 snprintf(buf, sizeof(buf), "cp Certs/ca.pem SP/%s/ca.pem",
3761 fqdn);
3762 if (system(buf)) {
3763 send_resp(dut, conn, SIGMA_ERROR,
3764 "errorCode,Failed to copy OSU CA cert");
3765 return 0;
3766 }
3767
3768 snprintf(buf, sizeof(buf),
3769 "cp Certs/aaa-ca.pem SP/%s/aaa-ca.pem",
3770 fqdn);
3771 if (system(buf)) {
3772 send_resp(dut, conn, SIGMA_ERROR,
3773 "errorCode,Failed to copy AAA CA cert");
3774 return 0;
3775 }
3776 } else {
3777 snprintf(buf, sizeof(buf),
3778 "dl_osu_ca SP/%s/pps.xml SP/%s/ca.pem",
3779 fqdn, fqdn);
3780 if (run_hs20_osu(dut, buf) < 0) {
3781 send_resp(dut, conn, SIGMA_ERROR,
3782 "errorCode,Failed to download OSU CA cert");
3783 return 0;
3784 }
3785
3786 snprintf(buf, sizeof(buf),
3787 "dl_aaa_ca SP/%s/pps.xml SP/%s/aaa-ca.pem",
3788 fqdn, fqdn);
3789 if (run_hs20_osu(dut, buf) < 0) {
3790 sigma_dut_print(dut, DUT_MSG_INFO,
3791 "Failed to download AAA CA cert");
3792 }
3793 }
3794
3795 if (file_exists("next-client-cert.pem")) {
3796 snprintf(buf, sizeof(buf), "SP/%s/client-cert.pem", fqdn);
3797 if (rename("next-client-cert.pem", buf) < 0) {
3798 send_resp(dut, conn, SIGMA_ERROR,
3799 "errorCode,Could not move client certificate");
3800 return 0;
3801 }
3802 }
3803
3804 if (file_exists("next-client-key.pem")) {
3805 snprintf(buf, sizeof(buf), "SP/%s/client-key.pem", fqdn);
3806 if (rename("next-client-key.pem", buf) < 0) {
3807 send_resp(dut, conn, SIGMA_ERROR,
3808 "errorCode,Could not move client key");
3809 return 0;
3810 }
3811 }
3812
3813 snprintf(buf, sizeof(buf), "set_pps SP/%s/pps.xml", fqdn);
3814 if (run_hs20_osu(dut, buf) < 0) {
3815 send_resp(dut, conn, SIGMA_ERROR,
3816 "errorCode,Failed to configure credential from "
3817 "PPSMO");
3818 return 0;
3819 }
3820
3821 return 1;
3822}
3823
3824
3825static int download_cert(struct sigma_dut *dut,
3826 struct sigma_conn *conn,
3827 const char *intf,
3828 struct sigma_cmd *cmd)
3829{
3830 const char *name, *path;
3831 char url[500], buf[600];
3832
3833 name = get_param(cmd, "FileName");
3834 path = get_param(cmd, "FilePath");
3835 if (name == NULL || path == NULL)
3836 return -1;
3837
3838 if (strcasecmp(path, "VendorSpecific") == 0) {
3839 snprintf(url, sizeof(url), "Certs/%s-cert.pem", name);
3840 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured client "
3841 "certificate from the device (%s)", url);
3842 if (!file_exists(url)) {
3843 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
3844 "certificate file does not exist");
3845 return 0;
3846 }
3847 snprintf(buf, sizeof(buf), "cp %s next-client-cert.pem", url);
3848 if (system(buf) != 0) {
3849 send_resp(dut, conn, SIGMA_ERROR,
3850 "errorCode,Failed to copy client "
3851 "certificate");
3852 return 0;
3853 }
3854
3855 snprintf(url, sizeof(url), "Certs/%s-key.pem", name);
3856 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured client "
3857 "private key from the device (%s)", url);
3858 if (!file_exists(url)) {
3859 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
3860 "private key file does not exist");
3861 return 0;
3862 }
3863 snprintf(buf, sizeof(buf), "cp %s next-client-key.pem", url);
3864 if (system(buf) != 0) {
3865 send_resp(dut, conn, SIGMA_ERROR,
3866 "errorCode,Failed to copy client key");
3867 return 0;
3868 }
3869 } else if (strncasecmp(path, "http:", 5) != 0 &&
3870 strncasecmp(path, "https:", 6) != 0) {
3871 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
3872 "Unsupported FilePath value");
3873 return 0;
3874 } else {
3875 snprintf(url, sizeof(url), "%s/%s.pem", path, name);
3876 sigma_dut_print(dut, DUT_MSG_INFO, "Downloading client "
3877 "certificate/key from %s", url);
3878 snprintf(buf, sizeof(buf),
3879 "wget -T 10 -t 3 -O next-client-cert.pem '%s'", url);
3880 if (system(buf) != 0) {
3881 send_resp(dut, conn, SIGMA_ERROR,
3882 "errorCode,Failed to download client "
3883 "certificate");
3884 return 0;
3885 }
3886
3887 if (system("cp next-client-cert.pem next-client-key.pem") != 0)
3888 {
3889 send_resp(dut, conn, SIGMA_ERROR,
3890 "errorCode,Failed to copy client key");
3891 return 0;
3892 }
3893 }
3894
3895 return 1;
3896}
3897
3898
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02003899static int cmd_sta_preset_testparameters_60ghz(struct sigma_dut *dut,
3900 struct sigma_conn *conn,
3901 struct sigma_cmd *cmd)
3902{
3903 const char *val;
3904 const char *intf = get_param(cmd, "interface");
3905
3906 if (!intf)
3907 return -1;
3908
3909 val = get_param(cmd, "WscIEFragment");
3910 if (val && strcasecmp(val, "enable") == 0) {
3911 sigma_dut_print(dut, DUT_MSG_DEBUG,
3912 "Enable WSC IE fragmentation");
3913
3914 dut->wsc_fragment = 1;
3915 /* set long attributes to force fragmentation */
3916 if (wpa_command(intf, "SET device_name "
3917 WPS_LONG_DEVICE_NAME) < 0)
3918 return -2;
3919 if (wpa_command(intf, "SET manufacturer "
3920 WPS_LONG_MANUFACTURER) < 0)
3921 return -2;
3922 if (wpa_command(intf, "SET model_name "
3923 WPS_LONG_MODEL_NAME) < 0)
3924 return -2;
3925 if (wpa_command(intf, "SET model_number "
3926 WPS_LONG_MODEL_NUMBER) < 0)
3927 return -2;
3928 if (wpa_command(intf, "SET serial_number "
3929 WPS_LONG_SERIAL_NUMBER) < 0)
3930 return -2;
3931 }
3932
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02003933 val = get_param(cmd, "RSN_IE");
3934 if (val) {
3935 if (strcasecmp(val, "disable") == 0)
3936 dut->force_rsn_ie = FORCE_RSN_IE_REMOVE;
3937 else if (strcasecmp(val, "enable") == 0)
3938 dut->force_rsn_ie = FORCE_RSN_IE_ADD;
3939 }
3940
Alexei Avshalom Lazar744ae8a2019-01-31 17:26:46 +02003941 val = get_param(cmd, "WpsVersion");
3942 if (val)
3943 dut->wps_forced_version = get_wps_forced_version(dut, val);
3944
Alexei Avshalom Lazar2eccf4d2019-01-31 10:03:59 +02003945 val = get_param(cmd, "WscEAPFragment");
3946 if (val && strcasecmp(val, "enable") == 0)
3947 dut->eap_fragment = 1;
3948
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02003949 return 1;
3950}
3951
3952
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003953static int cmd_sta_preset_testparameters_hs2_r2(struct sigma_dut *dut,
3954 struct sigma_conn *conn,
3955 const char *intf,
3956 struct sigma_cmd *cmd)
3957{
3958 const char *val;
3959
3960 val = get_param(cmd, "FileType");
3961 if (val && strcasecmp(val, "PPSMO") == 0)
3962 return download_ppsmo(dut, conn, intf, cmd);
3963 if (val && strcasecmp(val, "CERT") == 0)
3964 return download_cert(dut, conn, intf, cmd);
3965 if (val) {
3966 send_resp(dut, conn, SIGMA_ERROR,
3967 "ErrorCode,Unsupported FileType");
3968 return 0;
3969 }
3970
3971 return 1;
3972}
3973
3974
Ankita Bajaja2cb5672017-10-25 16:08:28 +05303975static int cmd_sta_preset_testparameters_oce(struct sigma_dut *dut,
3976 struct sigma_conn *conn,
3977 const char *intf,
3978 struct sigma_cmd *cmd)
3979{
3980 const char *val;
Ankita Bajaj1bde7942018-01-09 19:15:01 +05303981 char buf[1000];
3982 char text[20];
3983 unsigned char addr[ETH_ALEN];
Ankita Bajaja2cb5672017-10-25 16:08:28 +05303984
3985 val = get_param(cmd, "OCESupport");
3986 if (val && strcasecmp(val, "Disable") == 0) {
3987 if (wpa_command(intf, "SET oce 0") < 0) {
3988 send_resp(dut, conn, SIGMA_ERROR,
3989 "ErrorCode,Failed to disable OCE");
3990 return 0;
3991 }
3992 } else if (val && strcasecmp(val, "Enable") == 0) {
3993 if (wpa_command(intf, "SET oce 1") < 0) {
3994 send_resp(dut, conn, SIGMA_ERROR,
3995 "ErrorCode,Failed to enable OCE");
3996 return 0;
3997 }
3998 }
3999
vamsi krishnaa2799492017-12-05 14:28:01 +05304000 val = get_param(cmd, "FILScap");
4001 if (val && (atoi(val) == 1)) {
4002 if (wpa_command(intf, "SET disable_fils 0") < 0) {
4003 send_resp(dut, conn, SIGMA_ERROR,
4004 "ErrorCode,Failed to enable FILS");
4005 return 0;
4006 }
4007 } else if (val && (atoi(val) == 0)) {
4008 if (wpa_command(intf, "SET disable_fils 1") < 0) {
4009 send_resp(dut, conn, SIGMA_ERROR,
4010 "ErrorCode,Failed to disable FILS");
4011 return 0;
4012 }
4013 }
4014
Ankita Bajaj1bde7942018-01-09 19:15:01 +05304015 val = get_param(cmd, "FILSHLP");
4016 if (val && strcasecmp(val, "Enable") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004017 if (get_wpa_status(get_station_ifname(dut), "address", text,
Ankita Bajaj1bde7942018-01-09 19:15:01 +05304018 sizeof(text)) < 0)
4019 return -2;
4020 hwaddr_aton(text, addr);
4021 snprintf(buf, sizeof(buf),
4022 "FILS_HLP_REQ_ADD ff:ff:ff:ff:ff:ff "
4023 "080045100140000040004011399e00000000ffffffff00440043"
4024 "012cb30001010600fd4f46410000000000000000000000000000"
4025 "000000000000"
4026 "%02x%02x%02x%02x%02x%02x"
4027 "0000000000000000000000000000000000000000000000000000"
4028 "0000000000000000000000000000000000000000000000000000"
4029 "0000000000000000000000000000000000000000000000000000"
4030 "0000000000000000000000000000000000000000000000000000"
4031 "0000000000000000000000000000000000000000000000000000"
4032 "0000000000000000000000000000000000000000000000000000"
4033 "0000000000000000000000000000000000000000000000000000"
4034 "0000000000000000000000000000000000000000638253633501"
4035 "013d0701000af549d29b390205dc3c12616e64726f69642d6468"
4036 "63702d382e302e30370a0103060f1a1c333a3b2b5000ff00",
4037 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
4038 if (wpa_command(intf, buf)) {
4039 send_resp(dut, conn, SIGMA_ERROR,
4040 "ErrorCode,Failed to add HLP");
4041 return 0;
4042 }
4043 dut->fils_hlp = 1;
4044 }
4045
Ankita Bajaja2cb5672017-10-25 16:08:28 +05304046 return 1;
4047}
4048
4049
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004050static void ath_sta_set_noack(struct sigma_dut *dut, const char *intf,
4051 const char *val)
4052{
4053 int counter = 0;
4054 char token[50];
4055 char *result;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05304056 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004057
Peng Xub8fc5cc2017-05-10 17:27:28 -07004058 strlcpy(token, val, sizeof(token));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004059 token[sizeof(token) - 1] = '\0';
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05304060 result = strtok_r(token, ":", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004061 while (result) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004062 if (strcmp(result, "disable") == 0)
4063 run_iwpriv(dut, intf, "noackpolicy %d 1 0", counter);
4064 else
4065 run_iwpriv(dut, intf, "noackpolicy %d 1 1", counter);
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05304066 result = strtok_r(NULL, ":", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004067 counter++;
4068 }
4069}
4070
4071
4072static void ath_sta_set_rts(struct sigma_dut *dut, const char *intf,
4073 const char *val)
4074{
4075 char buf[100];
4076
4077 snprintf(buf, sizeof(buf), "iwconfig %s rts %s", intf, val);
4078 if (system(buf) != 0) {
4079 sigma_dut_print(dut, DUT_MSG_ERROR, "iwconfig RTS failed");
4080 }
4081}
4082
4083
4084static void ath_sta_set_wmm(struct sigma_dut *dut, const char *intf,
4085 const char *val)
4086{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004087 if (strcasecmp(val, "off") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004088 run_iwpriv(dut, intf, "wmm 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004089 }
4090}
4091
4092
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08004093static int wcn_sta_set_wmm(struct sigma_dut *dut, const char *intf,
4094 const char *val)
4095{
4096#ifdef NL80211_SUPPORT
4097 struct nl_msg *msg;
4098 int ret = 0;
4099 struct nlattr *params;
4100 int ifindex;
4101 int wmmenable = 1;
4102
4103 if (val &&
4104 (strcasecmp(val, "off") == 0 || strcmp(val, "0") == 0))
4105 wmmenable = 0;
4106
4107 ifindex = if_nametoindex(intf);
4108 if (ifindex == 0) {
4109 sigma_dut_print(dut, DUT_MSG_ERROR,
4110 "%s: Index for interface %s failed",
4111 __func__, intf);
4112 return -1;
4113 }
4114
4115 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4116 NL80211_CMD_VENDOR)) ||
4117 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4118 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4119 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4120 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4121 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4122 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WMM_ENABLE,
4123 wmmenable)) {
4124 sigma_dut_print(dut, DUT_MSG_ERROR,
4125 "%s: err in adding vendor_cmd and vendor_data",
4126 __func__);
4127 nlmsg_free(msg);
4128 return -1;
4129 }
4130 nla_nest_end(msg, params);
4131
4132 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4133 if (ret) {
4134 sigma_dut_print(dut, DUT_MSG_ERROR,
4135 "%s: err in send_and_recv_msgs, ret=%d",
4136 __func__, ret);
4137 }
4138 return ret;
4139#else /* NL80211_SUPPORT */
4140 sigma_dut_print(dut, DUT_MSG_ERROR,
4141 "WMM cannot be changed without NL80211_SUPPORT defined");
4142 return -1;
4143#endif /* NL80211_SUPPORT */
4144}
4145
4146
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004147static void ath_sta_set_sgi(struct sigma_dut *dut, const char *intf,
4148 const char *val)
4149{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004150 int sgi20;
4151
4152 sgi20 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
4153
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004154 run_iwpriv(dut, intf, "shortgi %d", sgi20);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004155}
4156
4157
4158static void ath_sta_set_11nrates(struct sigma_dut *dut, const char *intf,
4159 const char *val)
4160{
Pradeep Reddy POTTETI67376b72016-10-25 20:08:17 +05304161 int rate_code, v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004162
4163 /* Disable Tx Beam forming when using a fixed rate */
4164 ath_disable_txbf(dut, intf);
4165
Pradeep Reddy POTTETI67376b72016-10-25 20:08:17 +05304166 v = atoi(val);
4167 if (v < 0 || v > 32) {
4168 sigma_dut_print(dut, DUT_MSG_ERROR,
4169 "Invalid Fixed MCS rate: %d", v);
4170 return;
4171 }
4172 rate_code = 0x80 + v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004173
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004174 run_iwpriv(dut, intf, "set11NRates 0x%x", rate_code);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004175
4176 /* Channel width gets messed up, fix this */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004177 run_iwpriv(dut, intf, "chwidth %d", dut->chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004178}
4179
4180
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08004181static void iwpriv_sta_set_amsdu(struct sigma_dut *dut, const char *intf,
4182 const char *val)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004183{
4184 char buf[60];
4185
4186 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)
4187 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 2", intf);
4188 else
4189 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 1", intf);
4190
4191 if (system(buf) != 0)
4192 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv amsdu failed");
4193}
4194
4195
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07004196static int iwpriv_sta_set_ampdu(struct sigma_dut *dut, const char *intf,
4197 int ampdu)
4198{
4199 char buf[60];
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08004200 int maxaggregation = 63;
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07004201
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08004202 if (ampdu)
4203 ampdu = maxaggregation;
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07004204 snprintf(buf, sizeof(buf), "iwpriv %s ampdu %d", intf, ampdu);
4205 if (system(buf) != 0) {
4206 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv ampdu failed");
4207 return -1;
4208 }
4209
4210 return 0;
4211}
4212
4213
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004214static void ath_sta_set_stbc(struct sigma_dut *dut, const char *intf,
4215 const char *val)
4216{
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004217 run_iwpriv(dut, intf, "tx_stbc %s", val);
4218 run_iwpriv(dut, intf, "rx_stbc %s", val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004219}
4220
4221
4222static int wcn_sta_set_cts_width(struct sigma_dut *dut, const char *intf,
4223 const char *val)
4224{
4225 char buf[60];
4226
Peng Xucc317ed2017-05-18 16:44:37 -07004227 if (strcmp(val, "160") == 0) {
4228 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 5", intf);
4229 } else if (strcmp(val, "80") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004230 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 3", intf);
4231 } else if (strcmp(val, "40") == 0) {
4232 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 2", intf);
4233 } else if (strcmp(val, "20") == 0) {
4234 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 1", intf);
4235 } else if (strcasecmp(val, "Auto") == 0) {
4236 buf[0] = '\0';
4237 } else {
4238 sigma_dut_print(dut, DUT_MSG_ERROR,
4239 "WIDTH/CTS_WIDTH value not supported");
4240 return -1;
4241 }
4242
4243 if (buf[0] != '\0' && system(buf) != 0) {
4244 sigma_dut_print(dut, DUT_MSG_ERROR,
4245 "Failed to set WIDTH/CTS_WIDTH");
4246 return -1;
4247 }
4248
4249 return 0;
4250}
4251
4252
4253int ath_set_width(struct sigma_dut *dut, struct sigma_conn *conn,
4254 const char *intf, const char *val)
4255{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004256 if (strcasecmp(val, "Auto") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004257 run_iwpriv(dut, intf, "chwidth 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004258 dut->chwidth = 0;
4259 } else if (strcasecmp(val, "20") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004260 run_iwpriv(dut, intf, "chwidth 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004261 dut->chwidth = 0;
4262 } else if (strcasecmp(val, "40") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004263 run_iwpriv(dut, intf, "chwidth 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004264 dut->chwidth = 1;
4265 } else if (strcasecmp(val, "80") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004266 run_iwpriv(dut, intf, "chwidth 2");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004267 dut->chwidth = 2;
4268 } else if (strcasecmp(val, "160") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004269 run_iwpriv(dut, intf, "chwidth 3");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004270 dut->chwidth = 3;
4271 } else {
4272 send_resp(dut, conn, SIGMA_ERROR,
4273 "ErrorCode,WIDTH not supported");
4274 return -1;
4275 }
4276
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004277 return 0;
4278}
4279
4280
4281static int wcn_sta_set_sp_stream(struct sigma_dut *dut, const char *intf,
4282 const char *val)
4283{
4284 char buf[60];
Arif Hussainac6c5112018-05-25 17:34:00 -07004285 int sta_nss;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004286
Amarnath Hullur Subramanyamd5374fa2018-02-25 19:00:24 -08004287 if (strcmp(val, "1SS") == 0 || strcmp(val, "1") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004288 snprintf(buf, sizeof(buf), "iwpriv %s nss 1", intf);
Arif Hussainac6c5112018-05-25 17:34:00 -07004289 sta_nss = 1;
Amarnath Hullur Subramanyamd5374fa2018-02-25 19:00:24 -08004290 } else if (strcmp(val, "2SS") == 0 || strcmp(val, "2") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004291 snprintf(buf, sizeof(buf), "iwpriv %s nss 2", intf);
Arif Hussainac6c5112018-05-25 17:34:00 -07004292 sta_nss = 2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004293 } else {
4294 sigma_dut_print(dut, DUT_MSG_ERROR,
4295 "SP_STREAM value not supported");
4296 return -1;
4297 }
4298
4299 if (system(buf) != 0) {
4300 sigma_dut_print(dut, DUT_MSG_ERROR,
4301 "Failed to set SP_STREAM");
4302 return -1;
4303 }
4304
Arif Hussainac6c5112018-05-25 17:34:00 -07004305 dut->sta_nss = sta_nss;
4306
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004307 return 0;
4308}
4309
4310
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05304311static void wcn_sta_set_stbc(struct sigma_dut *dut, const char *intf,
4312 const char *val)
4313{
4314 char buf[60];
4315
4316 snprintf(buf, sizeof(buf), "iwpriv %s tx_stbc %s", intf, val);
4317 if (system(buf) != 0)
4318 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv tx_stbc failed");
4319
4320 snprintf(buf, sizeof(buf), "iwpriv %s rx_stbc %s", intf, val);
4321 if (system(buf) != 0)
4322 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv rx_stbc failed");
4323}
4324
4325
Ashwini Patil68d02cd2017-01-10 15:39:16 +05304326static int mbo_set_cellular_data_capa(struct sigma_dut *dut,
4327 struct sigma_conn *conn,
4328 const char *intf, int capa)
4329{
4330 char buf[32];
4331
4332 if (capa > 0 && capa < 4) {
4333 snprintf(buf, sizeof(buf), "SET mbo_cell_capa %d", capa);
4334 if (wpa_command(intf, buf) < 0) {
4335 send_resp(dut, conn, SIGMA_ERROR,
4336 "ErrorCode, Failed to set cellular data capability");
4337 return 0;
4338 }
4339 return 1;
4340 }
4341
4342 sigma_dut_print(dut, DUT_MSG_ERROR,
4343 "Invalid Cellular data capability: %d", capa);
4344 send_resp(dut, conn, SIGMA_INVALID,
4345 "ErrorCode,Invalid cellular data capability");
4346 return 0;
4347}
4348
4349
Ashwini Patil9183fdb2017-04-13 16:58:25 +05304350static int mbo_set_roaming(struct sigma_dut *dut, struct sigma_conn *conn,
4351 const char *intf, const char *val)
4352{
4353 if (strcasecmp(val, "Disable") == 0) {
4354 if (wpa_command(intf, "SET roaming 0") < 0) {
4355 send_resp(dut, conn, SIGMA_ERROR,
4356 "ErrorCode,Failed to disable roaming");
4357 return 0;
4358 }
4359 return 1;
4360 }
4361
4362 if (strcasecmp(val, "Enable") == 0) {
4363 if (wpa_command(intf, "SET roaming 1") < 0) {
4364 send_resp(dut, conn, SIGMA_ERROR,
4365 "ErrorCode,Failed to enable roaming");
4366 return 0;
4367 }
4368 return 1;
4369 }
4370
4371 sigma_dut_print(dut, DUT_MSG_ERROR,
4372 "Invalid value provided for roaming: %s", val);
4373 send_resp(dut, conn, SIGMA_INVALID,
4374 "ErrorCode,Unknown value provided for Roaming");
4375 return 0;
4376}
4377
4378
Ashwini Patila75de5a2017-04-13 16:35:05 +05304379static int mbo_set_assoc_disallow(struct sigma_dut *dut,
4380 struct sigma_conn *conn,
4381 const char *intf, const char *val)
4382{
4383 if (strcasecmp(val, "Disable") == 0) {
4384 if (wpa_command(intf, "SET ignore_assoc_disallow 1") < 0) {
4385 send_resp(dut, conn, SIGMA_ERROR,
4386 "ErrorCode,Failed to disable Assoc_disallow");
4387 return 0;
4388 }
4389 return 1;
4390 }
4391
4392 if (strcasecmp(val, "Enable") == 0) {
4393 if (wpa_command(intf, "SET ignore_assoc_disallow 0") < 0) {
4394 send_resp(dut, conn, SIGMA_ERROR,
4395 "ErrorCode,Failed to enable Assoc_disallow");
4396 return 0;
4397 }
4398 return 1;
4399 }
4400
4401 sigma_dut_print(dut, DUT_MSG_ERROR,
4402 "Invalid value provided for Assoc_disallow: %s", val);
4403 send_resp(dut, conn, SIGMA_INVALID,
4404 "ErrorCode,Unknown value provided for Assoc_disallow");
4405 return 0;
4406}
4407
4408
Ashwini Patilc63161e2017-04-13 16:30:23 +05304409static int mbo_set_bss_trans_req(struct sigma_dut *dut, struct sigma_conn *conn,
4410 const char *intf, const char *val)
4411{
4412 if (strcasecmp(val, "Reject") == 0) {
4413 if (wpa_command(intf, "SET reject_btm_req_reason 1") < 0) {
4414 send_resp(dut, conn, SIGMA_ERROR,
4415 "ErrorCode,Failed to Reject BTM Request");
4416 return 0;
4417 }
4418 return 1;
4419 }
4420
4421 if (strcasecmp(val, "Accept") == 0) {
4422 if (wpa_command(intf, "SET reject_btm_req_reason 0") < 0) {
4423 send_resp(dut, conn, SIGMA_ERROR,
4424 "ErrorCode,Failed to Accept BTM Request");
4425 return 0;
4426 }
4427 return 1;
4428 }
4429
4430 sigma_dut_print(dut, DUT_MSG_ERROR,
4431 "Invalid value provided for BSS_Transition: %s", val);
4432 send_resp(dut, conn, SIGMA_INVALID,
4433 "ErrorCode,Unknown value provided for BSS_Transition");
4434 return 0;
4435}
4436
4437
Ashwini Patil00402582017-04-13 12:29:39 +05304438static int mbo_set_non_pref_ch_list(struct sigma_dut *dut,
4439 struct sigma_conn *conn,
4440 const char *intf,
4441 struct sigma_cmd *cmd)
4442{
4443 const char *ch, *pref, *op_class, *reason;
4444 char buf[120];
4445 int len, ret;
4446
4447 pref = get_param(cmd, "Ch_Pref");
4448 if (!pref)
4449 return 1;
4450
4451 if (strcasecmp(pref, "clear") == 0) {
4452 free(dut->non_pref_ch_list);
4453 dut->non_pref_ch_list = NULL;
4454 } else {
4455 op_class = get_param(cmd, "Ch_Op_Class");
4456 if (!op_class) {
4457 send_resp(dut, conn, SIGMA_INVALID,
4458 "ErrorCode,Ch_Op_Class not provided");
4459 return 0;
4460 }
4461
4462 ch = get_param(cmd, "Ch_Pref_Num");
4463 if (!ch) {
4464 send_resp(dut, conn, SIGMA_INVALID,
4465 "ErrorCode,Ch_Pref_Num not provided");
4466 return 0;
4467 }
4468
4469 reason = get_param(cmd, "Ch_Reason_Code");
4470 if (!reason) {
4471 send_resp(dut, conn, SIGMA_INVALID,
4472 "ErrorCode,Ch_Reason_Code not provided");
4473 return 0;
4474 }
4475
4476 if (!dut->non_pref_ch_list) {
4477 dut->non_pref_ch_list =
4478 calloc(1, NON_PREF_CH_LIST_SIZE);
4479 if (!dut->non_pref_ch_list) {
4480 send_resp(dut, conn, SIGMA_ERROR,
4481 "ErrorCode,Failed to allocate memory for non_pref_ch_list");
4482 return 0;
4483 }
4484 }
4485 len = strlen(dut->non_pref_ch_list);
4486 ret = snprintf(dut->non_pref_ch_list + len,
4487 NON_PREF_CH_LIST_SIZE - len,
4488 " %s:%s:%s:%s", op_class, ch, pref, reason);
4489 if (ret > 0 && ret < NON_PREF_CH_LIST_SIZE - len) {
4490 sigma_dut_print(dut, DUT_MSG_DEBUG, "non_pref_list: %s",
4491 dut->non_pref_ch_list);
4492 } else {
4493 sigma_dut_print(dut, DUT_MSG_ERROR,
4494 "snprintf failed for non_pref_list, ret = %d",
4495 ret);
4496 send_resp(dut, conn, SIGMA_ERROR,
4497 "ErrorCode,snprintf failed");
4498 free(dut->non_pref_ch_list);
4499 dut->non_pref_ch_list = NULL;
4500 return 0;
4501 }
4502 }
4503
4504 ret = snprintf(buf, sizeof(buf), "SET non_pref_chan%s",
4505 dut->non_pref_ch_list ? dut->non_pref_ch_list : " ");
4506 if (ret < 0 || ret >= (int) sizeof(buf)) {
4507 sigma_dut_print(dut, DUT_MSG_DEBUG,
4508 "snprintf failed for set non_pref_chan, ret: %d",
4509 ret);
4510 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,snprint failed");
4511 return 0;
4512 }
4513
4514 if (wpa_command(intf, buf) < 0) {
4515 send_resp(dut, conn, SIGMA_ERROR,
4516 "ErrorCode,Failed to set non-preferred channel list");
4517 return 0;
4518 }
4519
4520 return 1;
4521}
4522
4523
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08004524#ifdef NL80211_SUPPORT
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08004525
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08004526static int sta_set_he_htc_supp(struct sigma_dut *dut, const char *intf,
4527 uint8_t cfg)
4528{
4529 struct nl_msg *msg;
4530 int ret = 0;
4531 struct nlattr *params;
4532 int ifindex;
4533
4534 ifindex = if_nametoindex(intf);
4535 if (ifindex == 0) {
4536 sigma_dut_print(dut, DUT_MSG_ERROR,
4537 "%s: Index for interface %s failed",
4538 __func__, intf);
4539 return -1;
4540 }
4541
4542 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4543 NL80211_CMD_VENDOR)) ||
4544 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4545 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4546 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4547 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4548 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4549 nla_put_u8(msg,
4550 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_HTC_HE_SUPP,
4551 cfg)) {
4552 sigma_dut_print(dut, DUT_MSG_ERROR,
4553 "%s: err in adding vendor_cmd and vendor_data",
4554 __func__);
4555 nlmsg_free(msg);
4556 return -1;
4557 }
4558 nla_nest_end(msg, params);
4559
4560 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4561 if (ret) {
4562 sigma_dut_print(dut, DUT_MSG_ERROR,
4563 "%s: err in send_and_recv_msgs, ret=%d",
4564 __func__, ret);
4565 }
4566 return ret;
4567}
4568
4569
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08004570static int sta_set_he_fragmentation(struct sigma_dut *dut, const char *intf,
4571 enum he_fragmentation_val frag)
4572{
4573 struct nl_msg *msg;
4574 int ret = 0;
4575 struct nlattr *params;
4576 int ifindex;
4577
4578 ifindex = if_nametoindex(intf);
4579 if (ifindex == 0) {
4580 sigma_dut_print(dut, DUT_MSG_ERROR,
4581 "%s: Index for interface %s failed",
4582 __func__, intf);
4583 return -1;
4584 }
4585
4586 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4587 NL80211_CMD_VENDOR)) ||
4588 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4589 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4590 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4591 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4592 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4593 nla_put_u8(msg,
4594 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_FRAGMENTATION,
4595 frag)) {
4596 sigma_dut_print(dut, DUT_MSG_ERROR,
4597 "%s: err in adding vendor_cmd and vendor_data",
4598 __func__);
4599 nlmsg_free(msg);
4600 return -1;
4601 }
4602 nla_nest_end(msg, params);
4603
4604 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4605 if (ret) {
4606 sigma_dut_print(dut, DUT_MSG_ERROR,
4607 "%s: err in send_and_recv_msgs, ret=%d",
4608 __func__, ret);
4609 }
4610 return ret;
4611}
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08004612
4613
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -08004614int wcn_set_he_ltf(struct sigma_dut *dut, const char *intf,
4615 enum qca_wlan_he_ltf_cfg ltf)
Subhani Shaik8e7a3052018-04-24 14:03:00 -07004616{
4617 struct nl_msg *msg;
4618 int ret = 0;
4619 struct nlattr *params;
4620 int ifindex;
4621
4622 ifindex = if_nametoindex(intf);
4623 if (ifindex == 0) {
4624 sigma_dut_print(dut, DUT_MSG_ERROR,
4625 "%s: Index for interface %s failed",
4626 __func__, intf);
4627 return -1;
4628 }
4629
4630 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4631 NL80211_CMD_VENDOR)) ||
4632 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4633 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4634 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4635 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4636 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4637 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_LTF,
4638 ltf)) {
4639 sigma_dut_print(dut, DUT_MSG_ERROR,
4640 "%s: err in adding vendor_cmd and vendor_data",
4641 __func__);
4642 nlmsg_free(msg);
4643 return -1;
4644 }
4645 nla_nest_end(msg, params);
4646
4647 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4648 if (ret) {
4649 sigma_dut_print(dut, DUT_MSG_ERROR,
4650 "%s: err in send_and_recv_msgs, ret=%d",
4651 __func__, ret);
4652 }
4653 return ret;
4654}
4655
4656
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08004657static int nlvendor_sta_set_noack(struct sigma_dut *dut, const char *intf,
4658 int noack, enum qca_wlan_ac_type ac)
4659{
4660 struct nl_msg *msg;
4661 int ret = 0;
4662 struct nlattr *params;
4663 int ifindex;
4664
4665 ifindex = if_nametoindex(intf);
4666 if (ifindex == 0) {
4667 sigma_dut_print(dut, DUT_MSG_ERROR,
4668 "%s: Index for interface %s failed",
4669 __func__, intf);
4670 return -1;
4671 }
4672
4673 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4674 NL80211_CMD_VENDOR)) ||
4675 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4676 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4677 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4678 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4679 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4680 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_NO_ACK,
4681 noack) ||
4682 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_NO_ACK_AC,
4683 ac)) {
4684 sigma_dut_print(dut, DUT_MSG_ERROR,
4685 "%s: err in adding vendor_cmd and vendor_data",
4686 __func__);
4687 nlmsg_free(msg);
4688 return -1;
4689 }
4690 nla_nest_end(msg, params);
4691
4692 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4693 if (ret) {
4694 sigma_dut_print(dut, DUT_MSG_ERROR,
4695 "%s: err in send_and_recv_msgs, ret=%d",
4696 __func__, ret);
4697 }
4698 return ret;
4699}
4700
4701
4702static void wcn_sta_set_noack(struct sigma_dut *dut, const char *intf,
4703 const char *val)
4704{
4705 int noack, ret;
4706 char token[100];
4707 char *result;
4708 char *saveptr;
4709 enum qca_wlan_ac_type ac = QCA_WLAN_AC_BE;
4710
4711 strlcpy(token, val, sizeof(token));
4712 token[sizeof(token) - 1] = '\0';
4713 result = strtok_r(token, ":", &saveptr);
4714 while (result) {
4715 noack = strcasecmp(result, "Disable") != 0;
4716 ret = nlvendor_sta_set_noack(dut, intf, noack, ac);
4717 if (ret) {
4718 sigma_dut_print(dut, DUT_MSG_ERROR,
4719 "nlvendor_sta_set_noack failed for ac:%d, ret:%d",
4720 ac, ret);
4721 }
4722 result = strtok_r(NULL, ":", &saveptr);
4723 ac++;
4724 }
4725}
4726
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08004727#endif /* NL80211_SUPPORT */
4728
4729
Jouni Malinenf7222712019-06-13 01:50:21 +03004730static enum sigma_cmd_result
4731cmd_sta_preset_testparameters(struct sigma_dut *dut, struct sigma_conn *conn,
4732 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004733{
4734 const char *intf = get_param(cmd, "Interface");
4735 const char *val;
4736
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03004737 val = get_param(cmd, "FT_DS");
4738 if (val) {
4739 if (strcasecmp(val, "Enable") == 0) {
4740 dut->sta_ft_ds = 1;
4741 } else if (strcasecmp(val, "Disable") == 0) {
4742 dut->sta_ft_ds = 0;
4743 } else {
4744 send_resp(dut, conn, SIGMA_ERROR,
4745 "errorCode,Unsupported value for FT_DS");
4746 return STATUS_SENT_ERROR;
4747 }
4748 }
4749
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004750 val = get_param(cmd, "Program");
Jouni Malinen1f6ae642018-06-07 23:56:13 +03004751 if (val && (strcasecmp(val, "HS2-R2") == 0 ||
4752 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004753 return cmd_sta_preset_testparameters_hs2_r2(dut, conn, intf,
4754 cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004755
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07004756 if (val && strcasecmp(val, "LOC") == 0)
4757 return loc_cmd_sta_preset_testparameters(dut, conn, cmd);
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02004758 if (val && strcasecmp(val, "60GHZ") == 0) {
4759 val = get_param(cmd, "WPS");
4760 if (val && strcasecmp(val, "disable") == 0) {
4761 dut->wps_disable = 1;
4762 sigma_dut_print(dut, DUT_MSG_INFO, "WPS disabled");
4763 } else {
4764 /* wps_disable can have other value from the previous
4765 * test, so make sure it has the correct value.
4766 */
4767 dut->wps_disable = 0;
4768 }
4769
4770 val = get_param(cmd, "P2P");
4771 if (val && strcasecmp(val, "disable") == 0)
4772 sigma_dut_print(dut, DUT_MSG_INFO, "P2P disabled");
4773 }
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07004774
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02004775 if (dut->program == PROGRAM_WPS && dut->band == WPS_BAND_60G)
4776 return cmd_sta_preset_testparameters_60ghz(dut, conn, cmd);
4777
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004778#ifdef ANDROID_NAN
4779 if (val && strcasecmp(val, "NAN") == 0)
4780 return nan_cmd_sta_preset_testparameters(dut, conn, cmd);
4781#endif /* ANDROID_NAN */
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07004782#ifdef MIRACAST
4783 if (val && (strcasecmp(val, "WFD") == 0 ||
4784 strcasecmp(val, "DisplayR2") == 0))
4785 return miracast_preset_testparameters(dut, conn, cmd);
4786#endif /* MIRACAST */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004787
Ashwini Patil68d02cd2017-01-10 15:39:16 +05304788 if (val && strcasecmp(val, "MBO") == 0) {
4789 val = get_param(cmd, "Cellular_Data_Cap");
4790 if (val &&
4791 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
4792 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +05304793
4794 val = get_param(cmd, "Ch_Pref");
4795 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
4796 return 0;
4797
Ashwini Patilc63161e2017-04-13 16:30:23 +05304798 val = get_param(cmd, "BSS_Transition");
4799 if (val && mbo_set_bss_trans_req(dut, conn, intf, val) == 0)
4800 return 0;
4801
Ashwini Patila75de5a2017-04-13 16:35:05 +05304802 val = get_param(cmd, "Assoc_Disallow");
4803 if (val && mbo_set_assoc_disallow(dut, conn, intf, val) == 0)
4804 return 0;
4805
Ashwini Patil9183fdb2017-04-13 16:58:25 +05304806 val = get_param(cmd, "Roaming");
4807 if (val && mbo_set_roaming(dut, conn, intf, val) == 0)
4808 return 0;
4809
Ashwini Patil68d02cd2017-01-10 15:39:16 +05304810 return 1;
4811 }
4812
Ankita Bajaja2cb5672017-10-25 16:08:28 +05304813 if (val && strcasecmp(val, "OCE") == 0)
4814 return cmd_sta_preset_testparameters_oce(dut, conn, intf, cmd);
4815
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004816#if 0
4817 val = get_param(cmd, "Supplicant");
4818 if (val && strcasecmp(val, "Default") != 0) {
4819 send_resp(dut, conn, SIGMA_ERROR,
4820 "ErrorCode,Only default(Vendor) supplicant "
4821 "supported");
4822 return 0;
4823 }
4824#endif
4825
4826 val = get_param(cmd, "RTS");
4827 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004828 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004829 case DRIVER_ATHEROS:
4830 ath_sta_set_rts(dut, intf, val);
4831 break;
4832 default:
4833#if 0
4834 send_resp(dut, conn, SIGMA_ERROR,
4835 "ErrorCode,Setting RTS not supported");
4836 return 0;
4837#else
4838 sigma_dut_print(dut, DUT_MSG_DEBUG,
4839 "Setting RTS not supported");
4840 break;
4841#endif
4842 }
4843 }
4844
4845#if 0
4846 val = get_param(cmd, "FRGMNT");
4847 if (val) {
4848 /* TODO */
4849 send_resp(dut, conn, SIGMA_ERROR,
4850 "ErrorCode,Setting FRGMNT not supported");
4851 return 0;
4852 }
4853#endif
4854
4855#if 0
4856 val = get_param(cmd, "Preamble");
4857 if (val) {
4858 /* TODO: Long/Short */
4859 send_resp(dut, conn, SIGMA_ERROR,
4860 "ErrorCode,Setting Preamble not supported");
4861 return 0;
4862 }
4863#endif
4864
4865 val = get_param(cmd, "Mode");
4866 if (val) {
4867 if (strcmp(val, "11b") == 0 ||
4868 strcmp(val, "11g") == 0 ||
4869 strcmp(val, "11a") == 0 ||
4870 strcmp(val, "11n") == 0 ||
4871 strcmp(val, "11ng") == 0 ||
4872 strcmp(val, "11nl") == 0 ||
4873 strcmp(val, "11nl(nabg)") == 0 ||
4874 strcmp(val, "AC") == 0 ||
4875 strcmp(val, "11AC") == 0 ||
4876 strcmp(val, "11ac") == 0 ||
4877 strcmp(val, "11na") == 0 ||
Amarnath Hullur Subramanyamb0db2712018-01-30 19:40:35 -08004878 strcmp(val, "11an") == 0 ||
4879 strcmp(val, "11ax") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004880 /* STA supports all modes by default */
4881 } else {
4882 send_resp(dut, conn, SIGMA_ERROR,
4883 "ErrorCode,Setting Mode not supported");
4884 return 0;
4885 }
Amarnath Hullur Subramanyam97d0e532018-01-31 02:53:02 -08004886
4887 /* Change the mode only in case of testbed for HE program
4888 * and for 11a and 11g modes only. */
4889 if (dut->program == PROGRAM_HE &&
4890 dut->device_type == STA_testbed) {
4891 int phymode;
4892 char buf[60];
4893
4894 if (strcmp(val, "11a") == 0) {
Amarnath Hullur Subramanyam94dfaf02018-03-02 19:26:57 -08004895 phymode = 1; /* IEEE80211_MODE_11A */
4896 } else if (strcmp(val, "11g") == 0) {
4897 phymode = 3; /* IEEE80211_MODE_11G */
4898 } else if (strcmp(val, "11b") == 0) {
4899 phymode = 2; /* IEEE80211_MODE_11B */
4900 } else if (strcmp(val, "11n") == 0 ||
4901 strcmp(val, "11nl") == 0 ||
4902 strcmp(val, "11nl(nabg)") == 0) {
4903 phymode = 22; /* IEEE80211_MODE_11AGN */
4904 } else if (strcmp(val, "11ng") == 0) {
4905 phymode = 13; /* IEEE80211_MODE_11NG_HT40 */
4906 } else if (strcmp(val, "AC") == 0 ||
4907 strcasecmp(val, "11AC") == 0) {
4908 phymode = 19; /* IEEE80211_MODE_11AC_VHT80 */
4909 } else if (strcmp(val, "11na") == 0 ||
4910 strcasecmp(val, "11an") == 0) {
4911 phymode = 14; /* IEEE80211_MODE_11NA_HT40 */
4912 } else if (strcmp(val, "11ax") == 0) {
4913 phymode = 0; /* IEEE80211_MODE_AUTO */
Amarnath Hullur Subramanyam97d0e532018-01-31 02:53:02 -08004914 } else {
4915 sigma_dut_print(dut, DUT_MSG_DEBUG,
4916 "Ignoring mode change for mode: %s",
4917 val);
4918 phymode = -1;
4919 }
4920 if (phymode != -1) {
4921 snprintf(buf, sizeof(buf),
4922 "iwpriv %s setphymode %d",
4923 intf, phymode);
4924 if (system(buf) != 0) {
4925 sigma_dut_print(dut, DUT_MSG_ERROR,
4926 "iwpriv setting of phymode failed");
4927 }
4928 }
4929 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004930 }
4931
4932 val = get_param(cmd, "wmm");
4933 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004934 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004935 case DRIVER_ATHEROS:
4936 ath_sta_set_wmm(dut, intf, val);
4937 break;
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08004938 case DRIVER_WCN:
4939 wcn_sta_set_wmm(dut, intf, val);
4940 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004941 default:
4942 sigma_dut_print(dut, DUT_MSG_DEBUG,
4943 "Setting wmm not supported");
4944 break;
4945 }
4946 }
4947
4948 val = get_param(cmd, "Powersave");
4949 if (val) {
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08004950 char buf[60];
4951
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004952 if (strcmp(val, "0") == 0 || strcasecmp(val, "off") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004953 if (get_driver_type(dut) == DRIVER_WCN) {
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08004954 snprintf(buf, sizeof(buf),
4955 "iwpriv %s setPower 2", intf);
4956 if (system(buf) != 0) {
4957 sigma_dut_print(dut, DUT_MSG_ERROR,
4958 "iwpriv setPower 2 failed");
4959 return 0;
4960 }
4961 }
4962
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004963 if (wpa_command(get_station_ifname(dut),
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004964 "P2P_SET ps 0") < 0)
4965 return -2;
4966 /* Make sure test modes are disabled */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004967 wpa_command(get_station_ifname(dut), "P2P_SET ps 98");
4968 wpa_command(get_station_ifname(dut), "P2P_SET ps 96");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004969 } else if (strcmp(val, "1") == 0 ||
4970 strcasecmp(val, "PSPoll") == 0 ||
4971 strcasecmp(val, "on") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004972 if (get_driver_type(dut) == DRIVER_WCN) {
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08004973 snprintf(buf, sizeof(buf),
4974 "iwpriv %s setPower 1", intf);
4975 if (system(buf) != 0) {
4976 sigma_dut_print(dut, DUT_MSG_ERROR,
4977 "iwpriv setPower 1 failed");
4978 return 0;
4979 }
4980 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004981 /* Disable default power save mode */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004982 wpa_command(get_station_ifname(dut), "P2P_SET ps 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004983 /* Enable PS-Poll test mode */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004984 if (wpa_command(get_station_ifname(dut),
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004985 "P2P_SET ps 97") < 0 ||
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004986 wpa_command(get_station_ifname(dut),
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004987 "P2P_SET ps 99") < 0)
4988 return -2;
4989 } else if (strcmp(val, "2") == 0 ||
4990 strcasecmp(val, "Fast") == 0) {
4991 /* TODO */
4992 send_resp(dut, conn, SIGMA_ERROR,
4993 "ErrorCode,Powersave=Fast not supported");
4994 return 0;
4995 } else if (strcmp(val, "3") == 0 ||
4996 strcasecmp(val, "PSNonPoll") == 0) {
4997 /* Make sure test modes are disabled */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004998 wpa_command(get_station_ifname(dut), "P2P_SET ps 98");
4999 wpa_command(get_station_ifname(dut), "P2P_SET ps 96");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005000
5001 /* Enable default power save mode */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005002 if (wpa_command(get_station_ifname(dut),
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005003 "P2P_SET ps 1") < 0)
5004 return -2;
5005 } else
5006 return -1;
5007 }
5008
5009 val = get_param(cmd, "NoAck");
5010 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005011 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005012 case DRIVER_ATHEROS:
5013 ath_sta_set_noack(dut, intf, val);
5014 break;
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08005015#ifdef NL80211_SUPPORT
5016 case DRIVER_WCN:
5017 wcn_sta_set_noack(dut, intf, val);
5018 break;
5019#endif /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005020 default:
5021 send_resp(dut, conn, SIGMA_ERROR,
5022 "ErrorCode,Setting NoAck not supported");
5023 return 0;
5024 }
5025 }
5026
5027 val = get_param(cmd, "IgnoreChswitchProhibit");
5028 if (val) {
5029 /* TODO: Enabled/disabled */
5030 if (strcasecmp(val, "Enabled") == 0) {
5031 send_resp(dut, conn, SIGMA_ERROR,
5032 "ErrorCode,Enabling IgnoreChswitchProhibit "
5033 "not supported");
5034 return 0;
5035 }
5036 }
5037
5038 val = get_param(cmd, "TDLS");
5039 if (val) {
5040 if (strcasecmp(val, "Disabled") == 0) {
5041 if (wpa_command(intf, "SET tdls_disabled 1")) {
5042 send_resp(dut, conn, SIGMA_ERROR,
5043 "ErrorCode,Failed to disable TDLS");
5044 return 0;
5045 }
5046 } else if (strcasecmp(val, "Enabled") == 0) {
5047 if (wpa_command(intf, "SET tdls_disabled 0")) {
5048 send_resp(dut, conn, SIGMA_ERROR,
5049 "ErrorCode,Failed to enable TDLS");
5050 return 0;
5051 }
5052 } else {
5053 send_resp(dut, conn, SIGMA_ERROR,
5054 "ErrorCode,Unsupported TDLS value");
5055 return 0;
5056 }
5057 }
5058
5059 val = get_param(cmd, "TDLSmode");
5060 if (val) {
5061 if (strcasecmp(val, "Default") == 0) {
5062 wpa_command(intf, "SET tdls_testing 0");
5063 } else if (strcasecmp(val, "APProhibit") == 0) {
5064 if (wpa_command(intf, "SET tdls_testing 0x400")) {
5065 send_resp(dut, conn, SIGMA_ERROR,
5066 "ErrorCode,Failed to enable ignore "
5067 "APProhibit TDLS mode");
5068 return 0;
5069 }
5070 } else if (strcasecmp(val, "HiLoMac") == 0) {
5071 /* STA should respond with TDLS setup req for a TDLS
5072 * setup req */
5073 if (wpa_command(intf, "SET tdls_testing 0x80")) {
5074 send_resp(dut, conn, SIGMA_ERROR,
5075 "ErrorCode,Failed to enable HiLoMac "
5076 "TDLS mode");
5077 return 0;
5078 }
5079 } else if (strcasecmp(val, "WeakSecurity") == 0) {
5080 /*
5081 * Since all security modes are enabled by default when
5082 * Sigma control is used, there is no need to do
5083 * anything here.
5084 */
5085 } else if (strcasecmp(val, "ExistLink") == 0) {
5086 /*
5087 * Since we allow new TDLS Setup Request even if there
5088 * is an existing link, nothing needs to be done for
5089 * this.
5090 */
5091 } else {
5092 /* TODO:
5093 * ExistLink: STA should send TDLS setup req even if
5094 * direct link already exists
5095 */
5096 send_resp(dut, conn, SIGMA_ERROR,
5097 "ErrorCode,Unsupported TDLSmode value");
5098 return 0;
5099 }
5100 }
5101
5102 val = get_param(cmd, "FakePubKey");
5103 if (val && atoi(val) && wpa_command(intf, "SET wps_corrupt_pkhash 1")) {
5104 send_resp(dut, conn, SIGMA_ERROR,
5105 "ErrorCode,Failed to enable FakePubKey");
5106 return 0;
5107 }
5108
Amarnath Hullur Subramanyamae1042b2018-02-22 21:52:52 -08005109#ifdef NL80211_SUPPORT
5110 val = get_param(cmd, "FrgmntSupport");
5111 if (val) {
5112 if (strcasecmp(val, "Enable") == 0) {
5113 if (sta_set_he_fragmentation(dut, intf,
5114 HE_FRAG_LEVEL1)) {
5115 send_resp(dut, conn, SIGMA_ERROR,
5116 "ErrorCode,Failed to enable HE Fragmentation");
5117 return 0;
5118 }
5119 } else if (strcasecmp(val, "Disable") == 0) {
5120 if (sta_set_he_fragmentation(dut, intf,
5121 HE_FRAG_DISABLE)) {
5122 send_resp(dut, conn, SIGMA_ERROR,
5123 "ErrorCode,Failed to disable HE Fragmentation");
5124 return 0;
5125 }
5126 }
5127 }
5128#endif /* NL80211_SUPPORT */
5129
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005130 return 1;
5131}
5132
5133
5134static const char * ath_get_radio_name(const char *radio_name)
5135{
5136 if (radio_name == NULL)
5137 return "wifi0";
5138 if (strcmp(radio_name, "wifi1") == 0)
5139 return "wifi1";
5140 if (strcmp(radio_name, "wifi2") == 0)
5141 return "wifi2";
5142 return "wifi0";
5143}
5144
5145
5146static void ath_sta_set_txsp_stream(struct sigma_dut *dut, const char *intf,
5147 const char *val)
5148{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005149 unsigned int vht_mcsmap = 0;
5150 int txchainmask = 0;
5151 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
5152
5153 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
5154 if (dut->testbed_flag_txsp == 1) {
5155 vht_mcsmap = 0xfffc;
5156 dut->testbed_flag_txsp = 0;
5157 } else {
5158 vht_mcsmap = 0xfffe;
5159 }
5160 txchainmask = 1;
5161 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
5162 if (dut->testbed_flag_txsp == 1) {
5163 vht_mcsmap = 0xfff0;
5164 dut->testbed_flag_txsp = 0;
5165 } else {
5166 vht_mcsmap = 0xfffa;
5167 }
5168 txchainmask = 3;
5169 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
5170 if (dut->testbed_flag_txsp == 1) {
5171 vht_mcsmap = 0xffc0;
5172 dut->testbed_flag_txsp = 0;
5173 } else {
5174 vht_mcsmap = 0xffea;
5175 }
5176 txchainmask = 7;
5177 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
5178 if (dut->testbed_flag_txsp == 1) {
5179 vht_mcsmap = 0xff00;
5180 dut->testbed_flag_txsp = 0;
5181 } else {
5182 vht_mcsmap = 0xffaa;
5183 }
5184 txchainmask = 15;
5185 } else {
5186 if (dut->testbed_flag_txsp == 1) {
5187 vht_mcsmap = 0xffc0;
5188 dut->testbed_flag_txsp = 0;
5189 } else {
5190 vht_mcsmap = 0xffea;
5191 }
5192 }
5193
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005194 if (txchainmask)
5195 run_iwpriv(dut, basedev, "txchainmask %d", txchainmask);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005196
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005197 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005198}
5199
5200
5201static void ath_sta_set_rxsp_stream(struct sigma_dut *dut, const char *intf,
5202 const char *val)
5203{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005204 unsigned int vht_mcsmap = 0;
5205 int rxchainmask = 0;
5206 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
5207
5208 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
5209 if (dut->testbed_flag_rxsp == 1) {
5210 vht_mcsmap = 0xfffc;
5211 dut->testbed_flag_rxsp = 0;
5212 } else {
5213 vht_mcsmap = 0xfffe;
5214 }
5215 rxchainmask = 1;
5216 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
5217 if (dut->testbed_flag_rxsp == 1) {
5218 vht_mcsmap = 0xfff0;
5219 dut->testbed_flag_rxsp = 0;
5220 } else {
5221 vht_mcsmap = 0xfffa;
5222 }
5223 rxchainmask = 3;
5224 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
5225 if (dut->testbed_flag_rxsp == 1) {
5226 vht_mcsmap = 0xffc0;
5227 dut->testbed_flag_rxsp = 0;
5228 } else {
5229 vht_mcsmap = 0xffea;
5230 }
5231 rxchainmask = 7;
5232 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
5233 if (dut->testbed_flag_rxsp == 1) {
5234 vht_mcsmap = 0xff00;
5235 dut->testbed_flag_rxsp = 0;
5236 } else {
5237 vht_mcsmap = 0xffaa;
5238 }
5239 rxchainmask = 15;
5240 } else {
5241 if (dut->testbed_flag_rxsp == 1) {
5242 vht_mcsmap = 0xffc0;
5243 dut->testbed_flag_rxsp = 0;
5244 } else {
5245 vht_mcsmap = 0xffea;
5246 }
5247 }
5248
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005249 if (rxchainmask)
5250 run_iwpriv(dut, basedev, "rxchainmask %d", rxchainmask);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005251
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005252 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005253}
5254
5255
5256void ath_set_zero_crc(struct sigma_dut *dut, const char *val)
5257{
5258 if (strcasecmp(val, "enable") == 0) {
5259 if (system("athdiag --set --address=0x2a204 --and=0xbfffffff")
5260 != 0) {
5261 sigma_dut_print(dut, DUT_MSG_ERROR,
5262 "Disable BB_VHTSIGB_CRC_CALC failed");
5263 }
5264
5265 if (system("athdiag --set --address=0x2a204 --or=0x80000000")
5266 != 0) {
5267 sigma_dut_print(dut, DUT_MSG_ERROR,
5268 "Enable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
5269 }
5270 } else {
5271 if (system("athdiag --set --address=0x2a204 --and=0x7fffffff")
5272 != 0) {
5273 sigma_dut_print(dut, DUT_MSG_ERROR,
5274 "Disable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
5275 }
5276
5277 if (system("athdiag --set --address=0x2a204 --or=0x40000000")
5278 != 0) {
5279 sigma_dut_print(dut, DUT_MSG_ERROR,
5280 "Enable BB_VHTSIGB_CRC_CALC failed");
5281 }
5282 }
5283}
5284
5285
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08005286static int wcn_sta_set_width(struct sigma_dut *dut, const char *intf,
5287 const char *val)
5288{
5289 char buf[60];
5290
5291 if (strcmp(val, "20") == 0) {
5292 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 0", intf);
5293 dut->chwidth = 0;
5294 } else if (strcmp(val, "40") == 0) {
5295 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 1", intf);
5296 dut->chwidth = 1;
5297 } else if (strcmp(val, "80") == 0) {
5298 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 2", intf);
5299 dut->chwidth = 2;
Sunil Duttb1cccac2018-05-22 21:03:12 +05305300 } else if (strcasecmp(val, "Auto") == 0) {
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08005301 buf[0] = '\0';
5302 } else {
5303 sigma_dut_print(dut, DUT_MSG_ERROR, "WIDTH %s not supported",
5304 val);
5305 return -1;
5306 }
5307
5308 if (buf[0] != '\0' && system(buf) != 0) {
5309 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv chwidth failed");
5310 return -1;
5311 }
5312
5313 return 0;
5314}
5315
5316
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005317static int nlvendor_sta_set_addba_reject(struct sigma_dut *dut,
5318 const char *intf, int addbareject)
5319{
5320#ifdef NL80211_SUPPORT
5321 struct nl_msg *msg;
5322 int ret = 0;
5323 struct nlattr *params;
5324 int ifindex;
5325
5326 ifindex = if_nametoindex(intf);
5327 if (ifindex == 0) {
5328 sigma_dut_print(dut, DUT_MSG_ERROR,
5329 "%s: Index for interface %s failed",
5330 __func__, intf);
5331 return -1;
5332 }
5333
5334 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
5335 NL80211_CMD_VENDOR)) ||
5336 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
5337 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
5338 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
5339 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
5340 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
5341 nla_put_u8(msg,
5342 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ACCEPT_ADDBA_REQ,
5343 !addbareject)) {
5344 sigma_dut_print(dut, DUT_MSG_ERROR,
5345 "%s: err in adding vendor_cmd and vendor_data",
5346 __func__);
5347 nlmsg_free(msg);
5348 return -1;
5349 }
5350 nla_nest_end(msg, params);
5351
5352 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5353 if (ret) {
5354 sigma_dut_print(dut, DUT_MSG_ERROR,
5355 "%s: err in send_and_recv_msgs, ret=%d",
5356 __func__, ret);
5357 }
5358 return ret;
5359#else /* NL80211_SUPPORT */
5360 sigma_dut_print(dut, DUT_MSG_ERROR,
5361 "ADDBA_REJECT cannot be set without NL80211_SUPPORT defined");
5362 return -1;
5363#endif /* NL80211_SUPPORT */
5364}
5365
5366
5367static int sta_set_addba_reject(struct sigma_dut *dut, const char *intf,
5368 int addbareject)
5369{
5370 int ret;
5371
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005372 switch (get_driver_type(dut)) {
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005373 case DRIVER_WCN:
5374 ret = nlvendor_sta_set_addba_reject(dut, intf, addbareject);
5375 if (ret) {
5376 sigma_dut_print(dut, DUT_MSG_ERROR,
5377 "nlvendor_sta_set_addba_reject failed, ret:%d",
5378 ret);
5379 return ret;
5380 }
5381 break;
5382 default:
5383 sigma_dut_print(dut, DUT_MSG_ERROR,
5384 "errorCode,Unsupported ADDBA_REJECT with the current driver");
5385 ret = -1;
5386 break;
5387 }
5388
5389 return ret;
5390}
5391
5392
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08005393static int nlvendor_config_send_addba(struct sigma_dut *dut, const char *intf,
5394 int enable)
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005395{
5396#ifdef NL80211_SUPPORT
5397 struct nl_msg *msg;
5398 int ret = 0;
5399 struct nlattr *params;
5400 int ifindex;
5401
5402 ifindex = if_nametoindex(intf);
5403 if (ifindex == 0) {
5404 sigma_dut_print(dut, DUT_MSG_ERROR,
5405 "%s: Index for interface %s failed",
5406 __func__, intf);
5407 return -1;
5408 }
5409
5410 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
5411 NL80211_CMD_VENDOR)) ||
5412 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
5413 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
5414 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
5415 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
5416 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
5417 nla_put_u8(msg,
5418 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_SEND_ADDBA_REQ,
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08005419 enable)) {
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005420 sigma_dut_print(dut, DUT_MSG_ERROR,
5421 "%s: err in adding vendor_cmd and vendor_data",
5422 __func__);
5423 nlmsg_free(msg);
5424 return -1;
5425 }
5426 nla_nest_end(msg, params);
5427
5428 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5429 if (ret) {
5430 sigma_dut_print(dut, DUT_MSG_ERROR,
5431 "%s: err in send_and_recv_msgs, ret=%d",
5432 __func__, ret);
5433 }
5434 return ret;
5435#else /* NL80211_SUPPORT */
5436 sigma_dut_print(dut, DUT_MSG_ERROR,
5437 "Disable addba not possible without NL80211_SUPPORT defined");
5438 return -1;
5439#endif /* NL80211_SUPPORT */
5440}
5441
5442
Veerendranath Jakkamadcd6202019-04-17 12:32:21 +05305443#ifdef NL80211_SUPPORT
5444static int nl80211_sta_set_rts(struct sigma_dut *dut, const char *intf, int val)
5445{
5446 struct nl_msg *msg;
5447 int ret = 0;
5448 int ifindex;
5449
5450 ifindex = if_nametoindex(intf);
5451 if (ifindex == 0) {
5452 sigma_dut_print(dut, DUT_MSG_ERROR,
5453 "%s: Index for interface %s failed",
5454 __func__, intf);
5455 return -1;
5456 }
5457
5458 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
5459 NL80211_CMD_SET_WIPHY)) ||
5460 nla_put_u32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD, val)) {
5461 sigma_dut_print(dut, DUT_MSG_ERROR,
5462 "%s: err in adding RTS threshold",
5463 __func__);
5464 nlmsg_free(msg);
5465 return -1;
5466 }
5467
5468 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5469 if (ret) {
5470 sigma_dut_print(dut, DUT_MSG_ERROR,
5471 "%s: err in send_and_recv_msgs, ret=%d",
5472 __func__, ret);
5473 }
5474 return ret;
5475}
5476#endif /* NL80211_SUPPORT */
5477
5478
5479static int sta_set_rts(struct sigma_dut *dut, const char *intf, int val)
5480{
5481 char buf[100];
5482
5483#ifdef NL80211_SUPPORT
5484 if (nl80211_sta_set_rts(dut, intf, val) == 0)
5485 return 0;
5486 sigma_dut_print(dut, DUT_MSG_DEBUG,
5487 "Fall back to using iwconfig for setting RTS threshold");
5488#endif /* NL80211_SUPPORT */
5489
5490 snprintf(buf, sizeof(buf), "iwconfig %s rts %d", intf, val);
5491 if (system(buf) != 0) {
5492 sigma_dut_print(dut, DUT_MSG_ERROR,
5493 "Failed to set RTS threshold %d", val);
5494 return -1;
5495 }
5496 return 0;
5497}
5498
5499
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005500static int cmd_sta_set_wireless_common(const char *intf, struct sigma_dut *dut,
5501 struct sigma_conn *conn,
5502 struct sigma_cmd *cmd)
5503{
5504 const char *val;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005505 int ampdu = -1, addbareject = -1;
Jouni Malinen3aa72862019-05-29 23:14:51 +03005506 char buf[128];
5507 int res;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005508
5509 val = get_param(cmd, "40_INTOLERANT");
5510 if (val) {
5511 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
5512 /* TODO: iwpriv ht40intol through wpa_supplicant */
5513 send_resp(dut, conn, SIGMA_ERROR,
5514 "ErrorCode,40_INTOLERANT not supported");
5515 return 0;
5516 }
5517 }
5518
5519 val = get_param(cmd, "ADDBA_REJECT");
5520 if (val) {
5521 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
5522 /* reject any ADDBA with status "decline" */
5523 ampdu = 0;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005524 addbareject = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005525 } else {
5526 /* accept ADDBA */
5527 ampdu = 1;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005528 addbareject = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005529 }
5530 }
5531
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005532 if (addbareject >= 0 &&
5533 sta_set_addba_reject(dut, intf, addbareject) < 0) {
5534 send_resp(dut, conn, SIGMA_ERROR,
5535 "ErrorCode,set addba_reject failed");
5536 return 0;
5537 }
5538
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005539 val = get_param(cmd, "AMPDU");
5540 if (val) {
5541 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
5542 /* enable AMPDU Aggregation */
5543 if (ampdu == 0) {
5544 send_resp(dut, conn, SIGMA_ERROR,
5545 "ErrorCode,Mismatch in "
5546 "addba_reject/ampdu - "
5547 "not supported");
5548 return 0;
5549 }
5550 ampdu = 1;
5551 } else {
5552 /* disable AMPDU Aggregation */
5553 if (ampdu == 1) {
5554 send_resp(dut, conn, SIGMA_ERROR,
5555 "ErrorCode,Mismatch in "
5556 "addba_reject/ampdu - "
5557 "not supported");
5558 return 0;
5559 }
5560 ampdu = 0;
5561 }
5562 }
5563
5564 if (ampdu >= 0) {
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005565 int ret;
5566
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005567 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s A-MPDU aggregation",
5568 ampdu ? "Enabling" : "Disabling");
5569 snprintf(buf, sizeof(buf), "SET ampdu %d", ampdu);
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07005570 if (wpa_command(intf, buf) < 0 &&
5571 iwpriv_sta_set_ampdu(dut, intf, ampdu) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005572 send_resp(dut, conn, SIGMA_ERROR,
5573 "ErrorCode,set aggr failed");
5574 return 0;
5575 }
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005576
5577 if (ampdu == 0) {
5578 /* Disable sending of addba using nl vendor command */
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08005579 ret = nlvendor_config_send_addba(dut, intf, 0);
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005580 if (ret) {
5581 sigma_dut_print(dut, DUT_MSG_ERROR,
5582 "Failed to disable addba, ret:%d",
5583 ret);
5584 }
5585 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005586 }
5587
5588 val = get_param(cmd, "AMSDU");
5589 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005590 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005591 case DRIVER_ATHEROS:
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08005592 case DRIVER_WCN:
5593 iwpriv_sta_set_amsdu(dut, intf, val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005594 break;
5595 default:
5596 if (strcmp(val, "1") == 0 ||
5597 strcasecmp(val, "Enable") == 0) {
5598 /* Enable AMSDU Aggregation */
5599 send_resp(dut, conn, SIGMA_ERROR,
5600 "ErrorCode,AMSDU aggregation not supported");
5601 return 0;
5602 }
5603 break;
5604 }
5605 }
5606
5607 val = get_param(cmd, "STBC_RX");
5608 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005609 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005610 case DRIVER_ATHEROS:
5611 ath_sta_set_stbc(dut, intf, val);
5612 break;
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05305613 case DRIVER_WCN:
5614 wcn_sta_set_stbc(dut, intf, val);
5615 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005616 default:
5617 send_resp(dut, conn, SIGMA_ERROR,
5618 "ErrorCode,STBC_RX not supported");
5619 return 0;
5620 }
5621 }
5622
5623 val = get_param(cmd, "WIDTH");
5624 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005625 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005626 case DRIVER_WCN:
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08005627 if (wcn_sta_set_width(dut, intf, val) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005628 send_resp(dut, conn, SIGMA_ERROR,
5629 "ErrorCode,Failed to set WIDTH");
5630 return 0;
5631 }
5632 break;
5633 case DRIVER_ATHEROS:
5634 if (ath_set_width(dut, conn, intf, val) < 0)
5635 return 0;
5636 break;
5637 default:
5638 sigma_dut_print(dut, DUT_MSG_ERROR,
5639 "Setting WIDTH not supported");
5640 break;
5641 }
5642 }
5643
5644 val = get_param(cmd, "SMPS");
5645 if (val) {
5646 /* TODO: Dynamic/0, Static/1, No Limit/2 */
5647 send_resp(dut, conn, SIGMA_ERROR,
5648 "ErrorCode,SMPS not supported");
5649 return 0;
5650 }
5651
5652 val = get_param(cmd, "TXSP_STREAM");
5653 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005654 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005655 case DRIVER_WCN:
5656 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
5657 send_resp(dut, conn, SIGMA_ERROR,
5658 "ErrorCode,Failed to set TXSP_STREAM");
5659 return 0;
5660 }
5661 break;
5662 case DRIVER_ATHEROS:
5663 ath_sta_set_txsp_stream(dut, intf, val);
5664 break;
5665 default:
5666 sigma_dut_print(dut, DUT_MSG_ERROR,
5667 "Setting TXSP_STREAM not supported");
5668 break;
5669 }
5670 }
5671
5672 val = get_param(cmd, "RXSP_STREAM");
5673 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005674 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005675 case DRIVER_WCN:
5676 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
5677 send_resp(dut, conn, SIGMA_ERROR,
5678 "ErrorCode,Failed to set RXSP_STREAM");
5679 return 0;
5680 }
5681 break;
5682 case DRIVER_ATHEROS:
5683 ath_sta_set_rxsp_stream(dut, intf, val);
5684 break;
5685 default:
5686 sigma_dut_print(dut, DUT_MSG_ERROR,
5687 "Setting RXSP_STREAM not supported");
5688 break;
5689 }
5690 }
5691
5692 val = get_param(cmd, "DYN_BW_SGNL");
5693 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005694 switch (get_driver_type(dut)) {
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08005695 case DRIVER_WCN:
Peng Xuc59afd32016-11-21 15:01:11 -08005696 if (strcasecmp(val, "enable") == 0) {
5697 snprintf(buf, sizeof(buf),
5698 "iwpriv %s cwmenable 1", intf);
5699 if (system(buf) != 0) {
5700 sigma_dut_print(dut, DUT_MSG_ERROR,
5701 "iwpriv cwmenable 1 failed");
5702 return 0;
5703 }
5704 } else if (strcasecmp(val, "disable") == 0) {
5705 snprintf(buf, sizeof(buf),
5706 "iwpriv %s cwmenable 0", intf);
5707 if (system(buf) != 0) {
5708 sigma_dut_print(dut, DUT_MSG_ERROR,
5709 "iwpriv cwmenable 0 failed");
5710 return 0;
5711 }
5712 } else {
5713 sigma_dut_print(dut, DUT_MSG_ERROR,
5714 "Unsupported DYN_BW_SGL");
5715 }
5716
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005717 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 3", intf);
5718 if (system(buf) != 0) {
5719 sigma_dut_print(dut, DUT_MSG_ERROR,
5720 "Failed to set cts_cbw in DYN_BW_SGNL");
5721 return 0;
5722 }
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08005723 break;
5724 case DRIVER_ATHEROS:
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -07005725 novap_reset(dut, intf, 1);
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08005726 ath_config_dyn_bw_sig(dut, intf, val);
5727 break;
5728 default:
5729 sigma_dut_print(dut, DUT_MSG_ERROR,
5730 "Failed to set DYN_BW_SGNL");
5731 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005732 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005733 }
5734
5735 val = get_param(cmd, "RTS_FORCE");
5736 if (val) {
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -07005737 novap_reset(dut, intf, 1);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005738 if (strcasecmp(val, "Enable") == 0) {
Veerendranath Jakkamadcd6202019-04-17 12:32:21 +05305739 if (sta_set_rts(dut, intf, 64) != 0) {
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02005740 sigma_dut_print(dut, DUT_MSG_ERROR,
5741 "Failed to set RTS_FORCE 64");
5742 }
Jouni Malinen3aa72862019-05-29 23:14:51 +03005743 res = snprintf(buf, sizeof(buf),
5744 "wifitool %s beeliner_fw_test 100 1",
5745 intf);
5746 if (res < 0 || res >= sizeof(buf) || system(buf) != 0) {
priyadharshini gowthaman270870e2015-12-09 10:10:23 -08005747 sigma_dut_print(dut, DUT_MSG_ERROR,
5748 "wifitool beeliner_fw_test 100 1 failed");
5749 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005750 } else if (strcasecmp(val, "Disable") == 0) {
Veerendranath Jakkamadcd6202019-04-17 12:32:21 +05305751 if (sta_set_rts(dut, intf, 2347) != 0) {
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02005752 sigma_dut_print(dut, DUT_MSG_ERROR,
5753 "Failed to set RTS_FORCE 2347");
5754 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005755 } else {
5756 send_resp(dut, conn, SIGMA_ERROR,
5757 "ErrorCode,RTS_FORCE value not supported");
5758 return 0;
5759 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005760 }
5761
5762 val = get_param(cmd, "CTS_WIDTH");
5763 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005764 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005765 case DRIVER_WCN:
5766 if (wcn_sta_set_cts_width(dut, intf, val) < 0) {
5767 send_resp(dut, conn, SIGMA_ERROR,
5768 "ErrorCode,Failed to set CTS_WIDTH");
5769 return 0;
5770 }
5771 break;
5772 case DRIVER_ATHEROS:
5773 ath_set_cts_width(dut, intf, val);
5774 break;
5775 default:
5776 sigma_dut_print(dut, DUT_MSG_ERROR,
5777 "Setting CTS_WIDTH not supported");
5778 break;
5779 }
5780 }
5781
5782 val = get_param(cmd, "BW_SGNL");
5783 if (val) {
5784 if (strcasecmp(val, "Enable") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005785 run_iwpriv(dut, intf, "cwmenable 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005786 } else if (strcasecmp(val, "Disable") == 0) {
5787 /* TODO: Disable */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005788 } else {
5789 send_resp(dut, conn, SIGMA_ERROR,
5790 "ErrorCode,BW_SGNL value not supported");
5791 return 0;
5792 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005793 }
5794
5795 val = get_param(cmd, "Band");
5796 if (val) {
5797 if (strcmp(val, "2.4") == 0 || strcmp(val, "5") == 0) {
5798 /* STA supports all bands by default */
5799 } else {
5800 send_resp(dut, conn, SIGMA_ERROR,
5801 "ErrorCode,Unsupported Band");
5802 return 0;
5803 }
5804 }
5805
5806 val = get_param(cmd, "zero_crc");
5807 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005808 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005809 case DRIVER_ATHEROS:
5810 ath_set_zero_crc(dut, val);
5811 break;
5812 default:
5813 break;
5814 }
5815 }
5816
5817 return 1;
5818}
5819
5820
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02005821static int sta_set_force_mcs(struct sigma_dut *dut, int force, int mcs)
5822{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005823 switch (get_driver_type(dut)) {
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02005824#ifdef __linux__
5825 case DRIVER_WIL6210:
5826 return wil6210_set_force_mcs(dut, force, mcs);
5827#endif /* __linux__ */
5828 default:
5829 sigma_dut_print(dut, DUT_MSG_ERROR,
5830 "Unsupported sta_set_force_mcs with the current driver");
5831 return -1;
5832 }
5833}
5834
5835
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02005836static int sta_60g_force_rsn_ie(struct sigma_dut *dut, int state)
5837{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005838 switch (get_driver_type(dut)) {
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02005839#ifdef __linux__
5840 case DRIVER_WIL6210:
5841 return wil6210_force_rsn_ie(dut, state);
5842#endif /* __linux__ */
5843 default:
5844 sigma_dut_print(dut, DUT_MSG_ERROR,
5845 "Unsupported sta_60g_force_rsn_ie with the current driver");
5846 return -1;
5847 }
5848}
5849
5850
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005851static int sta_set_60g_common(struct sigma_dut *dut, struct sigma_conn *conn,
5852 struct sigma_cmd *cmd)
5853{
5854 const char *val;
5855 char buf[100];
5856
5857 val = get_param(cmd, "MSDUSize");
5858 if (val) {
5859 int mtu;
5860
5861 dut->amsdu_size = atoi(val);
5862 if (dut->amsdu_size > IEEE80211_MAX_DATA_LEN_DMG ||
5863 dut->amsdu_size < IEEE80211_SNAP_LEN_DMG) {
5864 sigma_dut_print(dut, DUT_MSG_ERROR,
5865 "MSDUSize %d is above max %d or below min %d",
5866 dut->amsdu_size,
5867 IEEE80211_MAX_DATA_LEN_DMG,
5868 IEEE80211_SNAP_LEN_DMG);
5869 dut->amsdu_size = 0;
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005870 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005871 }
5872
5873 mtu = dut->amsdu_size - IEEE80211_SNAP_LEN_DMG;
5874 sigma_dut_print(dut, DUT_MSG_DEBUG,
5875 "Setting amsdu_size to %d", mtu);
5876 snprintf(buf, sizeof(buf), "ifconfig %s mtu %d",
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005877 get_station_ifname(dut), mtu);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005878
5879 if (system(buf) != 0) {
5880 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
5881 buf);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005882 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005883 }
5884 }
5885
5886 val = get_param(cmd, "BAckRcvBuf");
5887 if (val) {
5888 dut->back_rcv_buf = atoi(val);
5889 if (dut->back_rcv_buf == 0) {
5890 sigma_dut_print(dut, DUT_MSG_ERROR,
5891 "Failed to convert %s or value is 0",
5892 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005893 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005894 }
5895
5896 sigma_dut_print(dut, DUT_MSG_DEBUG,
5897 "Setting BAckRcvBuf to %s", val);
5898 }
5899
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02005900 val = get_param(cmd, "MCS_FixedRate");
5901 if (val) {
5902 if (sta_set_force_mcs(dut, 1, atoi(val))) {
5903 sigma_dut_print(dut, DUT_MSG_ERROR,
5904 "Failed to force MCS");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005905 return ERROR_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02005906 }
5907 }
5908
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005909 return SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005910}
5911
5912
5913static int sta_pcp_start(struct sigma_dut *dut, struct sigma_conn *conn,
5914 struct sigma_cmd *cmd)
5915{
5916 int net_id;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005917 const char *ifname;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005918 const char *val;
5919 char buf[100];
5920
5921 dut->mode = SIGMA_MODE_STATION;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005922 ifname = get_main_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005923 if (wpa_command(ifname, "PING") != 0) {
5924 sigma_dut_print(dut, DUT_MSG_ERROR, "Supplicant not running");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005925 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005926 }
5927
5928 wpa_command(ifname, "FLUSH");
5929 net_id = add_network_common(dut, conn, ifname, cmd);
5930 if (net_id < 0) {
5931 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add network");
5932 return net_id;
5933 }
5934
5935 /* TODO: mode=2 for the AP; in the future, replace for mode PCP */
5936 if (set_network(ifname, net_id, "mode", "2") < 0) {
5937 sigma_dut_print(dut, DUT_MSG_ERROR,
5938 "Failed to set supplicant network mode");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005939 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005940 }
5941
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02005942 if (set_network(ifname, net_id, "pbss", "1") < 0)
5943 return -2;
5944
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005945 sigma_dut_print(dut, DUT_MSG_DEBUG,
Alexei Avshalom Lazarfd9f1352018-11-13 14:07:58 +02005946 "Supplicant set network with mode 2. network_id %d",
5947 net_id);
5948
5949 if (set_network(ifname, net_id, "wps_disabled", "0") < 0) {
5950 sigma_dut_print(dut, DUT_MSG_INFO,
5951 "Failed to set supplicant to WPS ENABLE");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005952 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarfd9f1352018-11-13 14:07:58 +02005953 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005954
5955 val = get_param(cmd, "Security");
5956 if (val && strcasecmp(val, "OPEN") == 0) {
5957 dut->ap_key_mgmt = AP_OPEN;
5958 if (set_network(ifname, net_id, "key_mgmt", "NONE") < 0) {
5959 sigma_dut_print(dut, DUT_MSG_ERROR,
5960 "Failed to set supplicant to %s security",
5961 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005962 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005963 }
5964 } else if (val && strcasecmp(val, "WPA2-PSK") == 0) {
5965 dut->ap_key_mgmt = AP_WPA2_PSK;
5966 if (set_network(ifname, net_id, "key_mgmt", "WPA-PSK") < 0) {
5967 sigma_dut_print(dut, DUT_MSG_ERROR,
5968 "Failed to set supplicant to %s security",
5969 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005970 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005971 }
5972
5973 if (set_network(ifname, net_id, "proto", "RSN") < 0) {
5974 sigma_dut_print(dut, DUT_MSG_ERROR,
5975 "Failed to set supplicant to proto RSN");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005976 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005977 }
5978 } else if (val) {
5979 sigma_dut_print(dut, DUT_MSG_ERROR,
5980 "Requested Security %s is not supported on 60GHz",
5981 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005982 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005983 }
5984
5985 val = get_param(cmd, "Encrypt");
5986 if (val && strcasecmp(val, "AES-GCMP") == 0) {
5987 if (set_network(ifname, net_id, "pairwise", "GCMP") < 0) {
5988 sigma_dut_print(dut, DUT_MSG_ERROR,
5989 "Failed to set supplicant to pairwise GCMP");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005990 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005991 }
5992 if (set_network(ifname, net_id, "group", "GCMP") < 0) {
5993 sigma_dut_print(dut, DUT_MSG_ERROR,
5994 "Failed to set supplicant to group GCMP");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005995 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005996 }
5997 } else if (val) {
5998 sigma_dut_print(dut, DUT_MSG_ERROR,
5999 "Requested Encrypt %s is not supported on 60 GHz",
6000 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02006001 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006002 }
6003
6004 val = get_param(cmd, "PSK");
6005 if (val && set_network_quoted(ifname, net_id, "psk", val) < 0) {
6006 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set psk %s",
6007 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02006008 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006009 }
6010
6011 /* Convert 60G channel to freq */
6012 switch (dut->ap_channel) {
6013 case 1:
6014 val = "58320";
6015 break;
6016 case 2:
6017 val = "60480";
6018 break;
6019 case 3:
6020 val = "62640";
6021 break;
6022 default:
6023 sigma_dut_print(dut, DUT_MSG_ERROR,
6024 "Failed to configure channel %d. Not supported",
6025 dut->ap_channel);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02006026 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006027 }
6028
6029 if (set_network(ifname, net_id, "frequency", val) < 0) {
6030 sigma_dut_print(dut, DUT_MSG_ERROR,
6031 "Failed to set supplicant network frequency");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02006032 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006033 }
6034
Alexei Avshalom Lazar2eccf4d2019-01-31 10:03:59 +02006035 if (dut->eap_fragment) {
6036 sigma_dut_print(dut, DUT_MSG_DEBUG,
6037 "Set EAP fragment size to 128 bytes.");
6038 if (set_network(ifname, net_id, "fragment_size", "128") < 0)
6039 return ERROR_SEND_STATUS;
6040 }
6041
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006042 sigma_dut_print(dut, DUT_MSG_DEBUG,
6043 "Supplicant set network with frequency");
6044
6045 snprintf(buf, sizeof(buf), "SELECT_NETWORK %d", net_id);
6046 if (wpa_command(ifname, buf) < 0) {
6047 sigma_dut_print(dut, DUT_MSG_INFO,
6048 "Failed to select network id %d on %s",
6049 net_id, ifname);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02006050 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006051 }
6052
6053 sigma_dut_print(dut, DUT_MSG_DEBUG, "Selected network");
6054
Jouni Malinen0e29cf22019-02-19 01:13:21 +02006055 return SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006056}
6057
6058
Lior David67543f52017-01-03 19:04:22 +02006059static int wil6210_set_abft_len(struct sigma_dut *dut, int abft_len)
6060{
6061 char buf[128], fname[128];
6062 FILE *f;
Jouni Malinen3aa72862019-05-29 23:14:51 +03006063 int res;
Lior David67543f52017-01-03 19:04:22 +02006064
6065 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
6066 sigma_dut_print(dut, DUT_MSG_ERROR,
6067 "failed to get wil6210 debugfs dir");
6068 return -1;
6069 }
6070
Jouni Malinen3aa72862019-05-29 23:14:51 +03006071 res = snprintf(fname, sizeof(fname), "%s/abft_len", buf);
6072 if (res < 0 || res >= sizeof(fname))
6073 return -1;
Lior David67543f52017-01-03 19:04:22 +02006074 f = fopen(fname, "w");
6075 if (!f) {
6076 sigma_dut_print(dut, DUT_MSG_ERROR,
6077 "failed to open: %s", fname);
6078 return -1;
6079 }
6080
6081 fprintf(f, "%d\n", abft_len);
6082 fclose(f);
6083
6084 return 0;
6085}
6086
6087
Alexei Avshalom Lazar49498b82019-01-31 15:16:32 +02006088int sta_set_60g_abft_len(struct sigma_dut *dut, struct sigma_conn *conn,
6089 int abft_len)
Lior David67543f52017-01-03 19:04:22 +02006090{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006091 switch (get_driver_type(dut)) {
Lior David67543f52017-01-03 19:04:22 +02006092 case DRIVER_WIL6210:
6093 return wil6210_set_abft_len(dut, abft_len);
6094 default:
6095 sigma_dut_print(dut, DUT_MSG_ERROR,
6096 "set abft_len not supported");
6097 return -1;
6098 }
6099}
6100
6101
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006102static int sta_set_60g_pcp(struct sigma_dut *dut, struct sigma_conn *conn,
6103 struct sigma_cmd *cmd)
6104{
6105 const char *val;
Lior David67543f52017-01-03 19:04:22 +02006106 unsigned int abft_len = 1; /* default is one slot */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006107
6108 if (dut->dev_role != DEVROLE_PCP) {
6109 send_resp(dut, conn, SIGMA_INVALID,
6110 "ErrorCode,Invalid DevRole");
6111 return 0;
6112 }
6113
6114 val = get_param(cmd, "SSID");
6115 if (val) {
6116 if (strlen(val) > sizeof(dut->ap_ssid) - 1) {
6117 send_resp(dut, conn, SIGMA_INVALID,
6118 "ErrorCode,Invalid SSID");
6119 return -1;
6120 }
6121
Peng Xub8fc5cc2017-05-10 17:27:28 -07006122 strlcpy(dut->ap_ssid, val, sizeof(dut->ap_ssid));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006123 }
6124
6125 val = get_param(cmd, "CHANNEL");
6126 if (val) {
6127 const char *pos;
6128
6129 dut->ap_channel = atoi(val);
6130 pos = strchr(val, ';');
6131 if (pos) {
6132 pos++;
6133 dut->ap_channel_1 = atoi(pos);
6134 }
6135 }
6136
6137 switch (dut->ap_channel) {
6138 case 1:
6139 case 2:
6140 case 3:
6141 break;
6142 default:
6143 sigma_dut_print(dut, DUT_MSG_ERROR,
6144 "Channel %d is not supported", dut->ap_channel);
6145 send_resp(dut, conn, SIGMA_ERROR,
6146 "Requested channel is not supported");
6147 return -1;
6148 }
6149
6150 val = get_param(cmd, "BCNINT");
6151 if (val)
6152 dut->ap_bcnint = atoi(val);
6153
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006154 val = get_param(cmd, "AllocType");
6155 if (val) {
6156 send_resp(dut, conn, SIGMA_ERROR,
6157 "ErrorCode,AllocType is not supported yet");
6158 return -1;
6159 }
6160
6161 val = get_param(cmd, "PercentBI");
6162 if (val) {
6163 send_resp(dut, conn, SIGMA_ERROR,
6164 "ErrorCode,PercentBI is not supported yet");
6165 return -1;
6166 }
6167
6168 val = get_param(cmd, "CBAPOnly");
6169 if (val) {
6170 send_resp(dut, conn, SIGMA_ERROR,
6171 "ErrorCode,CBAPOnly is not supported yet");
6172 return -1;
6173 }
6174
6175 val = get_param(cmd, "AMPDU");
6176 if (val) {
6177 if (strcasecmp(val, "Enable") == 0)
6178 dut->ap_ampdu = 1;
6179 else if (strcasecmp(val, "Disable") == 0)
6180 dut->ap_ampdu = 2;
6181 else {
6182 send_resp(dut, conn, SIGMA_ERROR,
6183 "ErrorCode,AMPDU value is not Enable nor Disabled");
6184 return -1;
6185 }
6186 }
6187
6188 val = get_param(cmd, "AMSDU");
6189 if (val) {
6190 if (strcasecmp(val, "Enable") == 0)
6191 dut->ap_amsdu = 1;
6192 else if (strcasecmp(val, "Disable") == 0)
6193 dut->ap_amsdu = 2;
6194 }
6195
6196 val = get_param(cmd, "NumMSDU");
6197 if (val) {
6198 send_resp(dut, conn, SIGMA_ERROR,
6199 "ErrorCode, NumMSDU is not supported yet");
6200 return -1;
6201 }
6202
6203 val = get_param(cmd, "ABFTLRang");
6204 if (val) {
6205 sigma_dut_print(dut, DUT_MSG_DEBUG,
Lior David67543f52017-01-03 19:04:22 +02006206 "ABFTLRang parameter %s", val);
6207 if (strcmp(val, "Gt1") == 0)
6208 abft_len = 2; /* 2 slots in this case */
6209 }
6210
6211 if (sta_set_60g_abft_len(dut, conn, abft_len)) {
6212 send_resp(dut, conn, SIGMA_ERROR,
6213 "ErrorCode, Can't set ABFT length");
6214 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006215 }
6216
6217 if (sta_pcp_start(dut, conn, cmd) < 0) {
6218 send_resp(dut, conn, SIGMA_ERROR,
6219 "ErrorCode, Can't start PCP role");
6220 return -1;
6221 }
6222
6223 return sta_set_60g_common(dut, conn, cmd);
6224}
6225
6226
6227static int sta_set_60g_sta(struct sigma_dut *dut, struct sigma_conn *conn,
6228 struct sigma_cmd *cmd)
6229{
6230 const char *val = get_param(cmd, "DiscoveryMode");
6231
6232 if (dut->dev_role != DEVROLE_STA) {
6233 send_resp(dut, conn, SIGMA_INVALID,
6234 "ErrorCode,Invalid DevRole");
6235 return 0;
6236 }
6237
6238 if (val) {
6239 sigma_dut_print(dut, DUT_MSG_DEBUG, "Discovery: %s", val);
6240 /* Ignore Discovery mode till Driver expose API. */
6241#if 0
6242 if (strcasecmp(val, "1") == 0) {
6243 send_resp(dut, conn, SIGMA_INVALID,
6244 "ErrorCode,DiscoveryMode 1 not supported");
6245 return 0;
6246 }
6247
6248 if (strcasecmp(val, "0") == 0) {
6249 /* OK */
6250 } else {
6251 send_resp(dut, conn, SIGMA_INVALID,
6252 "ErrorCode,DiscoveryMode not supported");
6253 return 0;
6254 }
6255#endif
6256 }
6257
6258 if (start_sta_mode(dut) != 0)
Jouni Malinen0e29cf22019-02-19 01:13:21 +02006259 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006260 return sta_set_60g_common(dut, conn, cmd);
6261}
6262
6263
Jouni Malinenf7222712019-06-13 01:50:21 +03006264static enum sigma_cmd_result cmd_sta_disconnect(struct sigma_dut *dut,
6265 struct sigma_conn *conn,
6266 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006267{
6268 const char *intf = get_param(cmd, "Interface");
Jouni Malinened77e672018-01-10 16:45:13 +02006269 const char *val = get_param(cmd, "maintain_profile");
vamsi krishnad605c422017-09-20 14:56:31 +05306270
Jouni Malinened77e672018-01-10 16:45:13 +02006271 if (dut->program == PROGRAM_OCE ||
Amarnath Hullur Subramanyamebeda9e2018-01-31 03:21:48 -08006272 dut->program == PROGRAM_HE ||
Jouni Malinened77e672018-01-10 16:45:13 +02006273 (val && atoi(val) == 1)) {
vamsi krishnad605c422017-09-20 14:56:31 +05306274 wpa_command(intf, "DISCONNECT");
6275 return 1;
6276 }
6277
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006278 disconnect_station(dut);
6279 /* Try to ignore old scan results to avoid HS 2.0R2 test case failures
6280 * due to cached results. */
6281 wpa_command(intf, "SET ignore_old_scan_res 1");
6282 wpa_command(intf, "BSS_FLUSH");
6283 return 1;
6284}
6285
6286
Jouni Malinenf7222712019-06-13 01:50:21 +03006287static enum sigma_cmd_result cmd_sta_reassoc(struct sigma_dut *dut,
6288 struct sigma_conn *conn,
6289 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006290{
6291 const char *intf = get_param(cmd, "Interface");
6292 const char *bssid = get_param(cmd, "bssid");
6293 const char *val = get_param(cmd, "CHANNEL");
6294 struct wpa_ctrl *ctrl;
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05306295 char buf[1000];
Sunil Duttd30ce092018-01-11 23:56:29 +05306296 char result[32];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006297 int res;
6298 int chan = 0;
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006299 enum sigma_cmd_result status = STATUS_SENT;
Sunil Duttd30ce092018-01-11 23:56:29 +05306300 int fastreassoc = 1;
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006301 int ft_ds = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006302
6303 if (bssid == NULL) {
6304 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing bssid "
6305 "argument");
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006306 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006307 }
6308
6309 if (val)
6310 chan = atoi(val);
6311
6312 if (wifi_chip_type != DRIVER_WCN && wifi_chip_type != DRIVER_AR6003) {
6313 /* The current network may be from sta_associate or
6314 * sta_hs2_associate
6315 */
6316 if (set_network(intf, dut->infra_network_id, "bssid", bssid) <
6317 0 ||
6318 set_network(intf, 0, "bssid", bssid) < 0)
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006319 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006320 }
6321
6322 ctrl = open_wpa_mon(intf);
6323 if (ctrl == NULL) {
6324 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
6325 "wpa_supplicant monitor connection");
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006326 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006327 }
6328
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006329 if (get_wpa_status(get_station_ifname(dut), "wpa_state", result,
Sunil Duttd30ce092018-01-11 23:56:29 +05306330 sizeof(result)) < 0 ||
6331 strncmp(result, "COMPLETED", 9) != 0) {
6332 sigma_dut_print(dut, DUT_MSG_DEBUG,
6333 "sta_reassoc: Not connected");
6334 fastreassoc = 0;
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006335 } else if (dut->sta_ft_ds) {
6336 sigma_dut_print(dut, DUT_MSG_DEBUG,
6337 "sta_reassoc: Use FT-over-DS");
6338 ft_ds = 1;
Sunil Duttd30ce092018-01-11 23:56:29 +05306339 }
6340
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05306341 if (dut->rsne_override) {
6342#ifdef NL80211_SUPPORT
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006343 if (get_driver_type(dut) == DRIVER_WCN &&
6344 dut->config_rsnie == 0) {
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05306345 sta_config_rsnie(dut, 1);
6346 dut->config_rsnie = 1;
6347 }
6348#endif /* NL80211_SUPPORT */
6349 snprintf(buf, sizeof(buf), "TEST_ASSOC_IE %s",
6350 dut->rsne_override);
6351 if (wpa_command(intf, buf) < 0) {
6352 send_resp(dut, conn, SIGMA_ERROR,
6353 "ErrorCode,Failed to set DEV_CONFIGURE_IE RSNE override");
6354 return 0;
6355 }
6356 }
6357
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006358 if (ft_ds) {
6359 if (chan) {
6360 unsigned int freq;
6361
6362 freq = channel_to_freq(dut, chan);
6363 if (!freq) {
6364 sigma_dut_print(dut, DUT_MSG_ERROR,
6365 "Invalid channel number provided: %d",
6366 chan);
6367 send_resp(dut, conn, SIGMA_INVALID,
6368 "ErrorCode,Invalid channel number");
6369 goto close_mon_conn;
6370 }
6371 res = snprintf(buf, sizeof(buf),
6372 "SCAN TYPE=ONLY freq=%d", freq);
6373 } else {
6374 res = snprintf(buf, sizeof(buf), "SCAN TYPE=ONLY");
6375 }
6376 if (res < 0 || res >= (int) sizeof(buf)) {
6377 send_resp(dut, conn, SIGMA_ERROR,
6378 "ErrorCode,snprintf failed");
6379 goto close_mon_conn;
6380 }
6381 if (wpa_command(intf, buf) < 0) {
6382 sigma_dut_print(dut, DUT_MSG_INFO,
6383 "Failed to start scan");
6384 send_resp(dut, conn, SIGMA_ERROR,
6385 "ErrorCode,scan failed");
6386 goto close_mon_conn;
6387 }
6388
6389 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
6390 buf, sizeof(buf));
6391 if (res < 0) {
6392 sigma_dut_print(dut, DUT_MSG_INFO,
6393 "Scan did not complete");
6394 send_resp(dut, conn, SIGMA_ERROR,
6395 "ErrorCode,scan did not complete");
6396 goto close_mon_conn;
6397 }
6398
6399 res = snprintf(buf, sizeof(buf), "FT_DS %s", bssid);
6400 if (res > 0 && res < (int) sizeof(buf))
6401 res = wpa_command(intf, buf);
6402
6403 if (res < 0 || res >= (int) sizeof(buf)) {
6404 send_resp(dut, conn, SIGMA_ERROR,
6405 "errorCode,FT_DS command failed");
6406 status = STATUS_SENT_ERROR;
6407 goto close_mon_conn;
6408 }
6409 } else if (wifi_chip_type == DRIVER_WCN && fastreassoc) {
Ashwini Patil4c8158f2017-05-25 12:49:21 +05306410 if (chan) {
6411 unsigned int freq;
6412
Alexei Avshalom Lazar093569f2018-11-13 14:08:17 +02006413 freq = channel_to_freq(dut, chan);
Ashwini Patil4c8158f2017-05-25 12:49:21 +05306414 if (!freq) {
6415 sigma_dut_print(dut, DUT_MSG_ERROR,
6416 "Invalid channel number provided: %d",
6417 chan);
6418 send_resp(dut, conn, SIGMA_INVALID,
6419 "ErrorCode,Invalid channel number");
6420 goto close_mon_conn;
6421 }
6422 res = snprintf(buf, sizeof(buf),
6423 "SCAN TYPE=ONLY freq=%d", freq);
6424 } else {
6425 res = snprintf(buf, sizeof(buf), "SCAN TYPE=ONLY");
6426 }
6427 if (res < 0 || res >= (int) sizeof(buf)) {
6428 send_resp(dut, conn, SIGMA_ERROR,
6429 "ErrorCode,snprintf failed");
6430 goto close_mon_conn;
6431 }
6432 if (wpa_command(intf, buf) < 0) {
6433 sigma_dut_print(dut, DUT_MSG_INFO,
6434 "Failed to start scan");
6435 send_resp(dut, conn, SIGMA_ERROR,
6436 "ErrorCode,scan failed");
6437 goto close_mon_conn;
6438 }
6439
6440 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
6441 buf, sizeof(buf));
6442 if (res < 0) {
6443 sigma_dut_print(dut, DUT_MSG_INFO,
6444 "Scan did not complete");
6445 send_resp(dut, conn, SIGMA_ERROR,
6446 "ErrorCode,scan did not complete");
6447 goto close_mon_conn;
6448 }
6449
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006450 if (set_network(intf, dut->infra_network_id, "bssid", "any")
6451 < 0) {
6452 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
6453 "bssid to any during FASTREASSOC");
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006454 status = ERROR_SEND_STATUS;
Ashwini Patil467efef2017-05-25 12:18:27 +05306455 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006456 }
Vinita Maloo54b78cf2020-03-30 12:18:19 +05306457 res = snprintf(buf, sizeof(buf), "FASTREASSOC %s %d",
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006458 bssid, chan);
Vinita Maloo54b78cf2020-03-30 12:18:19 +05306459 if (res < 0 || res >= (int) sizeof(buf) ||
6460 wcn_driver_cmd(intf, buf) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006461 send_resp(dut, conn, SIGMA_ERROR,
Vinita Maloo54b78cf2020-03-30 12:18:19 +05306462 "errorCode,Failed to run FASTREASSOC");
Ashwini Patil467efef2017-05-25 12:18:27 +05306463 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006464 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006465 sigma_dut_print(dut, DUT_MSG_INFO,
6466 "sta_reassoc: Run %s successful", buf);
6467 } else if (wpa_command(intf, "REASSOCIATE")) {
6468 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
6469 "request reassociation");
Ashwini Patil467efef2017-05-25 12:18:27 +05306470 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006471 }
6472
6473 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
6474 buf, sizeof(buf));
Ashwini Patil467efef2017-05-25 12:18:27 +05306475 if (res < 0) {
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006476 send_resp(dut, conn, SIGMA_ERROR,
6477 "errorCode,Connection did not complete");
6478 status = STATUS_SENT_ERROR;
Ashwini Patil467efef2017-05-25 12:18:27 +05306479 goto close_mon_conn;
6480 }
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006481 status = SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006482
Ashwini Patil467efef2017-05-25 12:18:27 +05306483close_mon_conn:
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006484 wpa_ctrl_detach(ctrl);
6485 wpa_ctrl_close(ctrl);
Ashwini Patil467efef2017-05-25 12:18:27 +05306486 return status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006487}
6488
6489
6490static void hs2_clear_credentials(const char *intf)
6491{
6492 wpa_command(intf, "REMOVE_CRED all");
6493}
6494
6495
Lior Davidcc88b562017-01-03 18:52:09 +02006496#ifdef __linux__
6497static int wil6210_get_aid(struct sigma_dut *dut, const char *bssid,
6498 unsigned int *aid)
6499{
Lior David0fe101e2017-03-09 16:09:50 +02006500 const char *pattern = "AID[ \t]+([0-9]+)";
Lior Davidcc88b562017-01-03 18:52:09 +02006501
Lior David0fe101e2017-03-09 16:09:50 +02006502 return wil6210_get_sta_info_field(dut, bssid, pattern, aid);
Lior Davidcc88b562017-01-03 18:52:09 +02006503}
6504#endif /* __linux__ */
6505
6506
6507static int sta_get_aid_60g(struct sigma_dut *dut, const char *bssid,
6508 unsigned int *aid)
6509{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006510 switch (get_driver_type(dut)) {
Lior Davidcc88b562017-01-03 18:52:09 +02006511#ifdef __linux__
6512 case DRIVER_WIL6210:
6513 return wil6210_get_aid(dut, bssid, aid);
6514#endif /* __linux__ */
6515 default:
6516 sigma_dut_print(dut, DUT_MSG_ERROR, "get AID not supported");
6517 return -1;
6518 }
6519}
6520
6521
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006522static int sta_get_parameter_60g(struct sigma_dut *dut, struct sigma_conn *conn,
6523 struct sigma_cmd *cmd)
6524{
6525 char buf[MAX_CMD_LEN];
6526 char bss_list[MAX_CMD_LEN];
6527 const char *parameter = get_param(cmd, "Parameter");
6528
6529 if (parameter == NULL)
6530 return -1;
6531
Lior Davidcc88b562017-01-03 18:52:09 +02006532 if (strcasecmp(parameter, "AID") == 0) {
6533 unsigned int aid = 0;
6534 char bssid[20];
6535
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006536 if (get_wpa_status(get_station_ifname(dut), "bssid",
Lior Davidcc88b562017-01-03 18:52:09 +02006537 bssid, sizeof(bssid)) < 0) {
6538 sigma_dut_print(dut, DUT_MSG_ERROR,
6539 "could not get bssid");
6540 return -2;
6541 }
6542
6543 if (sta_get_aid_60g(dut, bssid, &aid))
6544 return -2;
6545
6546 snprintf(buf, sizeof(buf), "aid,%d", aid);
6547 sigma_dut_print(dut, DUT_MSG_INFO, "%s", buf);
6548 send_resp(dut, conn, SIGMA_COMPLETE, buf);
6549 return 0;
6550 }
6551
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006552 if (strcasecmp(parameter, "DiscoveredDevList") == 0) {
6553 char *bss_line;
6554 char *bss_id = NULL;
6555 const char *ifname = get_param(cmd, "Interface");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05306556 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006557
6558 if (ifname == NULL) {
6559 sigma_dut_print(dut, DUT_MSG_INFO,
6560 "For get DiscoveredDevList need Interface name.");
6561 return -1;
6562 }
6563
6564 /*
6565 * Use "BSS RANGE=ALL MASK=0x2" which provides a list
6566 * of BSSIDs in "bssid=<BSSID>\n"
6567 */
6568 if (wpa_command_resp(ifname, "BSS RANGE=ALL MASK=0x2",
6569 bss_list,
6570 sizeof(bss_list)) < 0) {
6571 sigma_dut_print(dut, DUT_MSG_ERROR,
6572 "Failed to get bss list");
6573 return -1;
6574 }
6575
6576 sigma_dut_print(dut, DUT_MSG_DEBUG,
6577 "bss list for ifname:%s is:%s",
6578 ifname, bss_list);
6579
6580 snprintf(buf, sizeof(buf), "DeviceList");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05306581 bss_line = strtok_r(bss_list, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006582 while (bss_line) {
6583 if (sscanf(bss_line, "bssid=%ms", &bss_id) > 0 &&
6584 bss_id) {
6585 int len;
6586
6587 len = snprintf(buf + strlen(buf),
6588 sizeof(buf) - strlen(buf),
6589 ",%s", bss_id);
6590 free(bss_id);
6591 bss_id = NULL;
6592 if (len < 0) {
6593 sigma_dut_print(dut,
6594 DUT_MSG_ERROR,
6595 "Failed to read BSSID");
6596 send_resp(dut, conn, SIGMA_ERROR,
6597 "ErrorCode,Failed to read BSS ID");
6598 return 0;
6599 }
6600
6601 if ((size_t) len >= sizeof(buf) - strlen(buf)) {
6602 sigma_dut_print(dut,
6603 DUT_MSG_ERROR,
6604 "Response buf too small for list");
6605 send_resp(dut, conn,
6606 SIGMA_ERROR,
6607 "ErrorCode,Response buf too small for list");
6608 return 0;
6609 }
6610 }
6611
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05306612 bss_line = strtok_r(NULL, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006613 }
6614
6615 sigma_dut_print(dut, DUT_MSG_INFO, "DiscoveredDevList is %s",
6616 buf);
6617 send_resp(dut, conn, SIGMA_COMPLETE, buf);
6618 return 0;
6619 }
6620
6621 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
6622 return 0;
6623}
6624
6625
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07006626static int sta_get_parameter_he(struct sigma_dut *dut, struct sigma_conn *conn,
6627 struct sigma_cmd *cmd)
6628{
6629 char buf[MAX_CMD_LEN];
6630 const char *parameter = get_param(cmd, "Parameter");
6631
6632 if (!parameter)
6633 return -1;
6634
6635 if (strcasecmp(parameter, "RSSI") == 0) {
6636 char rssi[10];
6637
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006638 if (get_wpa_signal_poll(dut, get_station_ifname(dut), "RSSI",
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07006639 rssi, sizeof(rssi)) < 0) {
6640 sigma_dut_print(dut, DUT_MSG_ERROR,
6641 "Could not get RSSI");
6642 return -2;
6643 }
6644
6645 snprintf(buf, sizeof(buf), "rssi,%s", rssi);
6646 sigma_dut_print(dut, DUT_MSG_INFO, "RSSI %s", buf);
6647 send_resp(dut, conn, SIGMA_COMPLETE, buf);
6648 return 0;
6649 }
6650
6651 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
6652 return 0;
6653}
6654
6655
Jouni Malinenca0abd32020-02-09 20:18:10 +02006656static enum sigma_cmd_result sta_get_pmk(struct sigma_dut *dut,
6657 struct sigma_conn *conn,
6658 struct sigma_cmd *cmd)
6659{
6660 const char *intf = get_param(cmd, "Interface");
6661 char buf[4096], bssid[20], resp[200], *pos, *tmp;
6662
6663 snprintf(buf, sizeof(buf), "PMKSA_GET %d", dut->infra_network_id);
6664 if (wpa_command_resp(intf, buf, buf, sizeof(buf)) < 0 ||
6665 strncmp(buf, "UNKNOWN COMMAND", 15) == 0) {
6666 send_resp(dut, conn, SIGMA_ERROR,
6667 "ErrorCode,PMKSA_GET not supported");
6668 return STATUS_SENT_ERROR;
6669 }
6670
6671 if (strncmp(buf, "FAIL", 4) == 0 ||
6672 get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0) {
6673 send_resp(dut, conn, SIGMA_ERROR,
6674 "ErrorCode,Could not find current network");
6675 return STATUS_SENT_ERROR;
6676 }
6677
6678 pos = buf;
6679 while (pos) {
6680 if (strncmp(pos, bssid, 17) == 0) {
6681 pos = strchr(pos, ' ');
6682 if (!pos)
6683 goto fail;
6684 pos++;
6685 pos = strchr(pos, ' ');
6686 if (!pos)
6687 goto fail;
6688 pos++;
6689 tmp = strchr(pos, ' ');
6690 if (!tmp)
6691 goto fail;
6692 *tmp = '\0';
6693 break;
6694 }
6695
6696 fail:
6697 pos = strchr(pos, '\n');
6698 if (pos)
6699 pos++;
6700 }
6701
6702 if (!pos) {
6703 send_resp(dut, conn, SIGMA_ERROR,
6704 "ErrorCode,PMK not available");
6705 return STATUS_SENT_ERROR;
6706 }
6707
6708 snprintf(resp, sizeof(resp), "PMK,%s", pos);
6709 send_resp(dut, conn, SIGMA_COMPLETE, resp);
6710 return STATUS_SENT;
6711}
6712
6713
Jouni Malinenf7222712019-06-13 01:50:21 +03006714static enum sigma_cmd_result cmd_sta_get_parameter(struct sigma_dut *dut,
6715 struct sigma_conn *conn,
6716 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006717{
6718 const char *program = get_param(cmd, "Program");
Jouni Malinenca0abd32020-02-09 20:18:10 +02006719 const char *parameter = get_param(cmd, "Parameter");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006720
Jouni Malinenca0abd32020-02-09 20:18:10 +02006721 if (!parameter)
6722 return INVALID_SEND_STATUS;
6723
6724 if (strcasecmp(parameter, "PMK") == 0)
6725 return sta_get_pmk(dut, conn, cmd);
6726
6727 if (!program)
6728 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006729
6730 if (strcasecmp(program, "P2PNFC") == 0)
6731 return p2p_cmd_sta_get_parameter(dut, conn, cmd);
6732
6733 if (strcasecmp(program, "60ghz") == 0)
6734 return sta_get_parameter_60g(dut, conn, cmd);
6735
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07006736 if (strcasecmp(program, "he") == 0)
6737 return sta_get_parameter_he(dut, conn, cmd);
6738
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006739#ifdef ANDROID_NAN
6740 if (strcasecmp(program, "NAN") == 0)
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07006741 return nan_cmd_sta_get_parameter(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006742#endif /* ANDROID_NAN */
6743
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07006744#ifdef MIRACAST
6745 if (strcasecmp(program, "WFD") == 0 ||
6746 strcasecmp(program, "DisplayR2") == 0)
6747 return miracast_cmd_sta_get_parameter(dut, conn, cmd);
6748#endif /* MIRACAST */
6749
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006750 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
6751 return 0;
6752}
6753
6754
6755static void sta_reset_default_ath(struct sigma_dut *dut, const char *intf,
6756 const char *type)
6757{
6758 char buf[100];
6759
6760 if (dut->program == PROGRAM_VHT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006761 run_iwpriv(dut, intf, "chwidth 2");
6762 run_iwpriv(dut, intf, "mode 11ACVHT80");
6763 run_iwpriv(dut, intf, "vhtmcs -1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006764 }
6765
6766 if (dut->program == PROGRAM_HT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006767 run_iwpriv(dut, intf, "chwidth 0");
6768 run_iwpriv(dut, intf, "mode 11naht40");
6769 run_iwpriv(dut, intf, "set11NRates 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006770 }
6771
6772 if (dut->program == PROGRAM_VHT || dut->program == PROGRAM_HT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006773 run_iwpriv(dut, intf, "powersave 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006774
6775 /* Reset CTS width */
6776 snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 54 0",
6777 intf);
6778 if (system(buf) != 0) {
6779 sigma_dut_print(dut, DUT_MSG_ERROR,
6780 "wifitool %s beeliner_fw_test 54 0 failed",
6781 intf);
6782 }
6783
6784 /* Enable Dynamic Bandwidth signalling by default */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006785 run_iwpriv(dut, intf, "cwmenable 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006786
6787 snprintf(buf, sizeof(buf), "iwconfig %s rts 2347", intf);
6788 if (system(buf) != 0) {
6789 sigma_dut_print(dut, DUT_MSG_ERROR,
6790 "iwpriv rts failed");
6791 }
6792 }
6793
6794 if (type && strcasecmp(type, "Testbed") == 0) {
6795 dut->testbed_flag_txsp = 1;
6796 dut->testbed_flag_rxsp = 1;
6797 /* STA has to set spatial stream to 2 per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006798 run_iwpriv(dut, intf, "vht_mcsmap 0xfff0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006799
6800 /* Disable LDPC per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006801 run_iwpriv(dut, intf, "ldpc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006802
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006803 run_iwpriv(dut, intf, "amsdu 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006804
6805 /* TODO: Disable STBC 2x1 transmit and receive */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006806 run_iwpriv(dut, intf, "tx_stbc 0");
6807 run_iwpriv(dut, intf, "rx_stbc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006808
6809 /* STA has to disable Short GI per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006810 run_iwpriv(dut, intf, "shortgi 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006811 }
6812
6813 if (type && strcasecmp(type, "DUT") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006814 run_iwpriv(dut, intf, "nss 3");
Arif Hussainac6c5112018-05-25 17:34:00 -07006815 dut->sta_nss = 3;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006816
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006817 run_iwpriv(dut, intf, "shortgi 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006818 }
6819}
6820
6821
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08006822#ifdef NL80211_SUPPORT
6823static int sta_set_he_mcs(struct sigma_dut *dut, const char *intf,
6824 enum he_mcs_config mcs)
6825{
6826 struct nl_msg *msg;
6827 int ret = 0;
6828 struct nlattr *params;
6829 int ifindex;
6830
6831 ifindex = if_nametoindex(intf);
6832 if (ifindex == 0) {
6833 sigma_dut_print(dut, DUT_MSG_ERROR,
6834 "%s: Index for interface %s failed",
6835 __func__, intf);
6836 return -1;
6837 }
6838
6839 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6840 NL80211_CMD_VENDOR)) ||
6841 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6842 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6843 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6844 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6845 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6846 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MCS,
6847 mcs)) {
6848 sigma_dut_print(dut, DUT_MSG_ERROR,
6849 "%s: err in adding vendor_cmd and vendor_data",
6850 __func__);
6851 nlmsg_free(msg);
6852 return -1;
6853 }
6854 nla_nest_end(msg, params);
6855
6856 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6857 if (ret) {
6858 sigma_dut_print(dut, DUT_MSG_ERROR,
6859 "%s: err in send_and_recv_msgs, ret=%d",
6860 __func__, ret);
6861 }
6862 return ret;
6863}
6864#endif /* NL80211_SUPPORT */
6865
6866
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07006867static int sta_set_action_tx_in_he_tb_ppdu(struct sigma_dut *dut,
6868 const char *intf, int enable)
6869{
6870#ifdef NL80211_SUPPORT
6871 struct nl_msg *msg;
6872 int ret = 0;
6873 struct nlattr *params;
6874 int ifindex;
6875
6876 ifindex = if_nametoindex(intf);
6877 if (ifindex == 0) {
6878 sigma_dut_print(dut, DUT_MSG_ERROR,
6879 "%s: Index for interface %s failed",
6880 __func__, intf);
6881 return -1;
6882 }
6883
6884 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6885 NL80211_CMD_VENDOR)) ||
6886 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6887 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6888 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6889 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6890 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6891 nla_put_u8(msg,
6892 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_ACTION_TX_TB_PPDU,
6893 enable)) {
6894 sigma_dut_print(dut, DUT_MSG_ERROR,
6895 "%s: err in adding vendor_cmd and vendor_data",
6896 __func__);
6897 nlmsg_free(msg);
6898 return -1;
6899 }
6900 nla_nest_end(msg, params);
6901
6902 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6903 if (ret) {
6904 sigma_dut_print(dut, DUT_MSG_ERROR,
6905 "%s: err in send_and_recv_msgs, ret=%d",
6906 __func__, ret);
6907 }
6908 return ret;
6909#else /* NL80211_SUPPORT */
6910 sigma_dut_print(dut, DUT_MSG_ERROR,
6911 "HE action Tx TB PPDU cannot be set without NL80211_SUPPORT defined");
6912 return -1;
6913#endif /* NL80211_SUPPORT */
6914}
6915
6916
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08006917static int sta_set_heconfig_and_wep_tkip(struct sigma_dut *dut,
6918 const char *intf, int enable)
6919{
6920#ifdef NL80211_SUPPORT
6921 struct nl_msg *msg;
6922 int ret = 0;
6923 struct nlattr *params;
6924 int ifindex;
6925
6926 ifindex = if_nametoindex(intf);
6927 if (ifindex == 0) {
6928 sigma_dut_print(dut, DUT_MSG_ERROR,
6929 "%s: Index for interface %s failed",
6930 __func__, intf);
6931 return -1;
6932 }
6933
6934 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6935 NL80211_CMD_VENDOR)) ||
6936 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6937 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6938 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6939 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6940 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6941 nla_put_u8(msg,
6942 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WEP_TKIP_IN_HE,
6943 enable)) {
6944 sigma_dut_print(dut, DUT_MSG_ERROR,
6945 "%s: err in adding vendor_cmd and vendor_data",
6946 __func__);
6947 nlmsg_free(msg);
6948 return -1;
6949 }
6950 nla_nest_end(msg, params);
6951
6952 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6953 if (ret) {
6954 sigma_dut_print(dut, DUT_MSG_ERROR,
6955 "%s: err in send_and_recv_msgs, ret=%d",
6956 __func__, ret);
6957 }
6958 return ret;
6959#else /* NL80211_SUPPORT */
6960 sigma_dut_print(dut, DUT_MSG_ERROR,
6961 "HE config enablement cannot be changed without NL80211_SUPPORT defined");
6962 return -1;
6963#endif /* NL80211_SUPPORT */
6964}
6965
6966
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08006967#ifdef NL80211_SUPPORT
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08006968
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08006969static int sta_set_he_testbed_def(struct sigma_dut *dut,
6970 const char *intf, int cfg)
6971{
6972 struct nl_msg *msg;
6973 int ret = 0;
6974 struct nlattr *params;
6975 int ifindex;
6976
6977 ifindex = if_nametoindex(intf);
6978 if (ifindex == 0) {
6979 sigma_dut_print(dut, DUT_MSG_ERROR,
6980 "%s: Index for interface %s failed",
6981 __func__, intf);
6982 return -1;
6983 }
6984
6985 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6986 NL80211_CMD_VENDOR)) ||
6987 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6988 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6989 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6990 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6991 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6992 nla_put_u8(msg,
6993 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_SET_HE_TESTBED_DEFAULTS,
6994 cfg)) {
6995 sigma_dut_print(dut, DUT_MSG_ERROR,
6996 "%s: err in adding vendor_cmd and vendor_data",
6997 __func__);
6998 nlmsg_free(msg);
6999 return -1;
7000 }
7001 nla_nest_end(msg, params);
7002
7003 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7004 if (ret) {
7005 sigma_dut_print(dut, DUT_MSG_ERROR,
7006 "%s: err in send_and_recv_msgs, ret=%d",
7007 __func__, ret);
7008 }
7009 return ret;
7010}
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08007011
7012
7013static int sta_set_2g_vht_supp(struct sigma_dut *dut, const char *intf, int cfg)
7014{
7015 struct nl_msg *msg;
7016 int ret = 0;
7017 struct nlattr *params;
7018 int ifindex;
7019
7020 ifindex = if_nametoindex(intf);
7021 if (ifindex == 0) {
7022 sigma_dut_print(dut, DUT_MSG_ERROR,
7023 "%s: Index for interface %s failed",
7024 __func__, intf);
7025 return -1;
7026 }
7027
7028 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7029 NL80211_CMD_VENDOR)) ||
7030 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7031 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7032 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7033 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7034 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7035 nla_put_u8(msg,
7036 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_2G_VHT,
7037 cfg)) {
7038 sigma_dut_print(dut, DUT_MSG_ERROR,
7039 "%s: err in adding vendor_cmd and vendor_data",
7040 __func__);
7041 nlmsg_free(msg);
7042 return -1;
7043 }
7044 nla_nest_end(msg, params);
7045
7046 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7047 if (ret) {
7048 sigma_dut_print(dut, DUT_MSG_ERROR,
7049 "%s: err in send_and_recv_msgs, ret=%d",
7050 __func__, ret);
7051 }
7052 return ret;
7053}
7054
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08007055#endif /* NL80211_SUPPORT */
7056
7057
Qiwei Caib6806972020-01-15 13:52:11 +08007058int sta_set_addba_buf_size(struct sigma_dut *dut,
7059 const char *intf, int bufsize)
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08007060{
7061#ifdef NL80211_SUPPORT
7062 struct nl_msg *msg;
7063 int ret = 0;
7064 struct nlattr *params;
7065 int ifindex;
7066
7067 ifindex = if_nametoindex(intf);
7068 if (ifindex == 0) {
7069 sigma_dut_print(dut, DUT_MSG_ERROR,
7070 "%s: Index for interface %s failed",
7071 __func__, intf);
7072 return -1;
7073 }
7074
7075 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7076 NL80211_CMD_VENDOR)) ||
7077 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7078 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7079 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7080 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7081 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
Kiran Kumar Lokere26e27582018-08-01 16:18:34 -07007082 nla_put_u16(msg,
7083 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE,
7084 bufsize)) {
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08007085 sigma_dut_print(dut, DUT_MSG_ERROR,
7086 "%s: err in adding vendor_cmd and vendor_data",
7087 __func__);
7088 nlmsg_free(msg);
7089 return -1;
7090 }
7091 nla_nest_end(msg, params);
7092
7093 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7094 if (ret) {
7095 sigma_dut_print(dut, DUT_MSG_ERROR,
7096 "%s: err in send_and_recv_msgs, ret=%d",
7097 __func__, ret);
7098 }
7099 return ret;
7100#else /* NL80211_SUPPORT */
7101 sigma_dut_print(dut, DUT_MSG_ERROR,
7102 "AddBA bufsize cannot be changed without NL80211_SUPPORT defined");
7103 return -1;
7104#endif /* NL80211_SUPPORT */
7105}
7106
7107
Arif Hussain8d5b27b2018-05-14 14:31:03 -07007108static int sta_set_tx_beamformee(struct sigma_dut *dut, const char *intf,
7109 int enable)
7110{
7111#ifdef NL80211_SUPPORT
7112 struct nl_msg *msg;
7113 int ret = 0;
7114 struct nlattr *params;
7115 int ifindex;
7116
7117 ifindex = if_nametoindex(intf);
7118 if (ifindex == 0) {
7119 sigma_dut_print(dut, DUT_MSG_ERROR,
7120 "%s: Index for interface %s failed",
7121 __func__, intf);
7122 return -1;
7123 }
7124
7125 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7126 NL80211_CMD_VENDOR)) ||
7127 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7128 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7129 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7130 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7131 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7132 nla_put_u8(msg,
7133 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_TX_BEAMFORMEE,
7134 enable)) {
7135 sigma_dut_print(dut, DUT_MSG_ERROR,
7136 "%s: err in adding vendor_cmd and vendor_data",
7137 __func__);
7138 nlmsg_free(msg);
7139 return -1;
7140 }
7141 nla_nest_end(msg, params);
7142
7143 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7144 if (ret) {
7145 sigma_dut_print(dut, DUT_MSG_ERROR,
7146 "%s: err in send_and_recv_msgs, ret=%d",
7147 __func__, ret);
7148 }
7149 return ret;
7150#else /* NL80211_SUPPORT */
7151 sigma_dut_print(dut, DUT_MSG_ERROR,
7152 "tx beamformee cannot be changed without NL80211_SUPPORT defined");
7153 return -1;
7154#endif /* NL80211_SUPPORT */
7155}
7156
7157
Arif Hussain9765f7d2018-07-03 08:28:26 -07007158static int sta_set_beamformee_sts(struct sigma_dut *dut, const char *intf,
7159 int val)
7160{
7161#ifdef NL80211_SUPPORT
7162 struct nl_msg *msg;
7163 int ret = 0;
7164 struct nlattr *params;
7165 int ifindex;
7166
7167 ifindex = if_nametoindex(intf);
7168 if (ifindex == 0) {
7169 sigma_dut_print(dut, DUT_MSG_ERROR,
7170 "%s: Index for interface %s failed, val:%d",
7171 __func__, intf, val);
7172 return -1;
7173 }
7174
7175 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7176 NL80211_CMD_VENDOR)) ||
7177 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7178 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7179 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7180 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7181 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7182 nla_put_u8(msg,
7183 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_BEAMFORMEE_NSTS,
7184 val)) {
7185 sigma_dut_print(dut, DUT_MSG_ERROR,
7186 "%s: err in adding vendor_cmd and vendor_data, val: %d",
7187 __func__, val);
7188 nlmsg_free(msg);
7189 return -1;
7190 }
7191 nla_nest_end(msg, params);
7192
7193 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7194 if (ret) {
7195 sigma_dut_print(dut, DUT_MSG_ERROR,
7196 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
7197 __func__, ret, val);
7198 }
7199 return ret;
7200#else /* NL80211_SUPPORT */
7201 sigma_dut_print(dut, DUT_MSG_ERROR,
7202 "beamformee sts cannot be changed without NL80211_SUPPORT defined");
7203 return -1;
7204#endif /* NL80211_SUPPORT */
7205}
7206
7207
Arif Hussain68d23f52018-07-11 13:39:08 -07007208#ifdef NL80211_SUPPORT
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07007209static int sta_set_mac_padding_duration(struct sigma_dut *dut, const char *intf,
7210 enum qca_wlan_he_mac_padding_dur val)
7211{
Arif Hussain68d23f52018-07-11 13:39:08 -07007212 struct nl_msg *msg;
7213 int ret = 0;
7214 struct nlattr *params;
7215 int ifindex;
7216
7217 ifindex = if_nametoindex(intf);
7218 if (ifindex == 0) {
7219 sigma_dut_print(dut, DUT_MSG_ERROR,
7220 "%s: Index for interface %s failed, val:%d",
7221 __func__, intf, val);
7222 return -1;
7223 }
7224
7225 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7226 NL80211_CMD_VENDOR)) ||
7227 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7228 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7229 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7230 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7231 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7232 nla_put_u8(msg,
7233 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MAC_PADDING_DUR,
7234 val)) {
7235 sigma_dut_print(dut, DUT_MSG_ERROR,
7236 "%s: err in adding vendor_cmd and vendor_data, val: %d",
7237 __func__, val);
7238 nlmsg_free(msg);
7239 return -1;
7240 }
7241 nla_nest_end(msg, params);
7242
7243 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7244 if (ret) {
7245 sigma_dut_print(dut, DUT_MSG_ERROR,
7246 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
7247 __func__, ret, val);
7248 }
7249 return ret;
Arif Hussain68d23f52018-07-11 13:39:08 -07007250}
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07007251#endif /* NL80211_SUPPORT */
Arif Hussain68d23f52018-07-11 13:39:08 -07007252
7253
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07007254static int sta_set_tx_su_ppdu_cfg(struct sigma_dut *dut, const char *intf,
7255 int val)
7256{
7257#ifdef NL80211_SUPPORT
7258 struct nl_msg *msg;
7259 int ret = 0;
7260 struct nlattr *params;
7261 int ifindex;
7262
7263 ifindex = if_nametoindex(intf);
7264 if (ifindex == 0) {
7265 sigma_dut_print(dut, DUT_MSG_ERROR,
7266 "%s: Index for interface %s failed, val:%d",
7267 __func__, intf, val);
7268 return -1;
7269 }
7270
7271 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7272 NL80211_CMD_VENDOR)) ||
7273 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7274 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7275 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7276 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7277 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7278 nla_put_u8(msg,
7279 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_SUPPDU,
7280 val)) {
7281 sigma_dut_print(dut, DUT_MSG_ERROR,
7282 "%s: err in adding vendor_cmd and vendor_data, val: %d",
7283 __func__, val);
7284 nlmsg_free(msg);
7285 return -1;
7286 }
7287 nla_nest_end(msg, params);
7288
7289 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7290 if (ret) {
7291 sigma_dut_print(dut, DUT_MSG_ERROR,
7292 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
7293 __func__, ret, val);
7294 }
7295 return ret;
7296#else /* NL80211_SUPPORT */
7297 sigma_dut_print(dut, DUT_MSG_ERROR,
7298 "Tx SU PPDU cannot be set without NL80211_SUPPORT defined");
7299 return -1;
7300#endif /* NL80211_SUPPORT */
7301}
7302
7303
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07007304#ifdef NL80211_SUPPORT
7305static int sta_set_he_om_ctrl_reset(struct sigma_dut *dut, const char *intf)
7306{
7307 struct nl_msg *msg;
7308 int ret = 0;
7309 struct nlattr *params;
7310 int ifindex;
7311
7312 ifindex = if_nametoindex(intf);
7313 if (ifindex == 0) {
7314 sigma_dut_print(dut, DUT_MSG_ERROR,
7315 "%s: Index for interface %s failed",
7316 __func__, intf);
7317 return -1;
7318 }
7319
7320 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7321 NL80211_CMD_VENDOR)) ||
7322 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7323 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7324 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7325 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7326 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7327 nla_put_flag(msg,
7328 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_CLEAR_HE_OM_CTRL_CONFIG)) {
7329 sigma_dut_print(dut, DUT_MSG_ERROR,
7330 "%s: err in adding vendor_cmd and vendor_data",
7331 __func__);
7332 nlmsg_free(msg);
7333 return -1;
7334 }
7335 nla_nest_end(msg, params);
7336
7337 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7338 if (ret) {
7339 sigma_dut_print(dut, DUT_MSG_ERROR,
7340 "%s: err in send_and_recv_msgs, ret=%d",
7341 __func__, ret);
7342 }
7343 return ret;
7344}
7345#endif /* NL80211_SUPPORT */
7346
7347
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07007348static int sta_set_mu_edca_override(struct sigma_dut *dut, const char *intf,
7349 int val)
7350{
7351#ifdef NL80211_SUPPORT
7352 struct nl_msg *msg;
7353 int ret = 0;
7354 struct nlattr *params;
7355 int ifindex;
7356
7357 ifindex = if_nametoindex(intf);
7358 if (ifindex == 0) {
7359 sigma_dut_print(dut, DUT_MSG_ERROR,
7360 "%s: Index for interface %s failed, val:%d",
7361 __func__, intf, val);
7362 return -1;
7363 }
7364
7365 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7366 NL80211_CMD_VENDOR)) ||
7367 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7368 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7369 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7370 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7371 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7372 nla_put_u8(msg,
7373 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_OVERRIDE_MU_EDCA,
7374 val)) {
7375 sigma_dut_print(dut, DUT_MSG_ERROR,
7376 "%s: err in adding vendor_cmd and vendor_data, val: %d",
7377 __func__, val);
7378 nlmsg_free(msg);
7379 return -1;
7380 }
7381 nla_nest_end(msg, params);
7382
7383 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7384 if (ret) {
7385 sigma_dut_print(dut, DUT_MSG_ERROR,
7386 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
7387 __func__, ret, val);
7388 }
7389 return ret;
7390#else /* NL80211_SUPPORT */
7391 sigma_dut_print(dut, DUT_MSG_ERROR,
7392 "MU EDCA override cannot be changed without NL80211_SUPPORT defined");
7393 return -1;
7394#endif /* NL80211_SUPPORT */
7395}
7396
7397
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07007398static int sta_set_om_ctrl_supp(struct sigma_dut *dut, const char *intf,
7399 int val)
7400{
7401#ifdef NL80211_SUPPORT
7402 struct nl_msg *msg;
7403 int ret = 0;
7404 struct nlattr *params;
7405 int ifindex;
7406
7407 ifindex = if_nametoindex(intf);
7408 if (ifindex == 0) {
7409 sigma_dut_print(dut, DUT_MSG_ERROR,
7410 "%s: Index for interface %s failed, val:%d",
7411 __func__, intf, val);
7412 return -1;
7413 }
7414
7415 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7416 NL80211_CMD_VENDOR)) ||
7417 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7418 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7419 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7420 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7421 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7422 nla_put_u8(msg,
7423 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OM_CTRL_SUPP,
7424 val)) {
7425 sigma_dut_print(dut, DUT_MSG_ERROR,
7426 "%s: err in adding vendor_cmd and vendor_data, val: %d",
7427 __func__, val);
7428 nlmsg_free(msg);
7429 return -1;
7430 }
7431 nla_nest_end(msg, params);
7432
7433 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7434 if (ret) {
7435 sigma_dut_print(dut, DUT_MSG_ERROR,
7436 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
7437 __func__, ret, val);
7438 }
7439 return ret;
7440#else /* NL80211_SUPPORT */
7441 sigma_dut_print(dut, DUT_MSG_ERROR,
7442 "HE OM ctrl cannot be changed without NL80211_SUPPORT defined");
7443 return -1;
7444#endif /* NL80211_SUPPORT */
7445}
7446
7447
Arif Hussain480d5f42019-03-12 14:40:42 -07007448static int sta_set_twt_req_support(struct sigma_dut *dut, const char *intf,
7449 int val)
7450{
7451#ifdef NL80211_SUPPORT
7452 struct nl_msg *msg;
7453 int ret;
7454 struct nlattr *params;
7455 int ifindex;
7456
7457 ifindex = if_nametoindex(intf);
7458 if (ifindex == 0) {
7459 sigma_dut_print(dut, DUT_MSG_ERROR,
7460 "%s: Index for interface %s failed, val:%d",
7461 __func__, intf, val);
7462 return -1;
7463 }
7464
7465 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7466 NL80211_CMD_VENDOR)) ||
7467 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7468 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7469 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7470 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7471 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7472 nla_put_u8(msg,
7473 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TWT_REQ_SUPPORT,
7474 val)) {
7475 sigma_dut_print(dut, DUT_MSG_ERROR,
7476 "%s: err in adding vendor_cmd and vendor_data, val: %d",
7477 __func__, val);
7478 nlmsg_free(msg);
7479 return -1;
7480 }
7481 nla_nest_end(msg, params);
7482
7483 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7484 if (ret) {
7485 sigma_dut_print(dut, DUT_MSG_ERROR,
7486 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
7487 __func__, ret, val);
7488 }
7489 return ret;
7490#else /* NL80211_SUPPORT */
7491 sigma_dut_print(dut, DUT_MSG_ERROR,
7492 "TWT Request cannot be changed without NL80211_SUPPORT defined");
7493 return -1;
7494#endif /* NL80211_SUPPORT */
7495}
7496
7497
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08007498static void sta_reset_default_wcn(struct sigma_dut *dut, const char *intf,
7499 const char *type)
7500{
7501 char buf[60];
7502
7503 if (dut->program == PROGRAM_HE) {
7504 /* resetting phymode to auto in case of HE program */
7505 snprintf(buf, sizeof(buf), "iwpriv %s setphymode 0", intf);
7506 if (system(buf) != 0) {
7507 sigma_dut_print(dut, DUT_MSG_ERROR,
7508 "iwpriv %s setphymode failed", intf);
7509 }
7510
Amarnath Hullur Subramanyam9cecb502018-04-25 13:26:30 -07007511 /* reset the rate to Auto rate */
7512 snprintf(buf, sizeof(buf), "iwpriv %s set_11ax_rate 0xff",
7513 intf);
7514 if (system(buf) != 0) {
7515 sigma_dut_print(dut, DUT_MSG_ERROR,
7516 "iwpriv %s set_11ax_rate 0xff failed",
7517 intf);
7518 }
7519
Kiran Kumar Lokere86cfe3a2018-06-01 11:55:15 -07007520 /* reset the LDPC setting */
7521 snprintf(buf, sizeof(buf), "iwpriv %s ldpc 1", intf);
7522 if (system(buf) != 0) {
7523 sigma_dut_print(dut, DUT_MSG_ERROR,
7524 "iwpriv %s ldpc 1 failed", intf);
7525 }
7526
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08007527 /* reset the power save setting */
7528 snprintf(buf, sizeof(buf), "iwpriv %s setPower 2", intf);
7529 if (system(buf) != 0) {
7530 sigma_dut_print(dut, DUT_MSG_ERROR,
7531 "iwpriv %s setPower 2 failed", intf);
7532 }
7533
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08007534 /* remove all network profiles */
7535 remove_wpa_networks(intf);
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08007536
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08007537 /* Configure ADDBA Req/Rsp buffer size to be 64 */
7538 sta_set_addba_buf_size(dut, intf, 64);
7539
Amarnath Hullur Subramanyam5f32d572018-03-02 00:02:33 -08007540#ifdef NL80211_SUPPORT
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08007541 /* Reset the device HE capabilities to its default supported
7542 * configuration. */
7543 sta_set_he_testbed_def(dut, intf, 0);
7544
Amarnath Hullur Subramanyam5f32d572018-03-02 00:02:33 -08007545 /* Disable noackpolicy for all AC */
7546 if (nlvendor_sta_set_noack(dut, intf, 0, QCA_WLAN_AC_ALL)) {
7547 sigma_dut_print(dut, DUT_MSG_ERROR,
7548 "Disable of noackpolicy for all AC failed");
7549 }
7550#endif /* NL80211_SUPPORT */
7551
Amarnath Hullur Subramanyamb1724a52018-03-07 14:31:46 -08007552 /* Enable WMM by default */
7553 if (wcn_sta_set_wmm(dut, intf, "on")) {
7554 sigma_dut_print(dut, DUT_MSG_ERROR,
7555 "Enable of WMM in sta_reset_default_wcn failed");
7556 }
7557
7558 /* Disable ADDBA_REJECT by default */
7559 if (nlvendor_sta_set_addba_reject(dut, intf, 0)) {
7560 sigma_dut_print(dut, DUT_MSG_ERROR,
7561 "Disable of addba_reject in sta_reset_default_wcn failed");
7562 }
7563
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08007564 /* Enable sending of ADDBA by default */
7565 if (nlvendor_config_send_addba(dut, intf, 1)) {
7566 sigma_dut_print(dut, DUT_MSG_ERROR,
7567 "Enable sending of ADDBA in sta_reset_default_wcn failed");
7568 }
7569
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08007570 /* Enable AMPDU by default */
7571 iwpriv_sta_set_ampdu(dut, intf, 1);
7572
Subhani Shaik8e7a3052018-04-24 14:03:00 -07007573#ifdef NL80211_SUPPORT
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -08007574 if (wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_AUTO)) {
Subhani Shaik8e7a3052018-04-24 14:03:00 -07007575 sigma_dut_print(dut, DUT_MSG_ERROR,
7576 "Set LTF config to default in sta_reset_default_wcn failed");
7577 }
Arif Hussain9765f7d2018-07-03 08:28:26 -07007578
Kiran Kumar Lokerebad51122018-12-12 19:03:36 -08007579 /* set the beamformee NSTS(maximum number of
7580 * space-time streams) to default DUT config
7581 */
7582 if (sta_set_beamformee_sts(dut, intf, 7)) {
Arif Hussain9765f7d2018-07-03 08:28:26 -07007583 sigma_dut_print(dut, DUT_MSG_ERROR,
7584 "Failed to set BeamformeeSTS");
7585 }
Arif Hussain68d23f52018-07-11 13:39:08 -07007586
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07007587 if (sta_set_mac_padding_duration(
7588 dut, intf,
7589 QCA_WLAN_HE_NO_ADDITIONAL_PROCESS_TIME)) {
Arif Hussain68d23f52018-07-11 13:39:08 -07007590 sigma_dut_print(dut, DUT_MSG_ERROR,
7591 "Failed to set MAC padding duration");
7592 }
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07007593
7594 if (sta_set_mu_edca_override(dut, intf, 0)) {
7595 sigma_dut_print(dut, DUT_MSG_ERROR,
7596 "ErrorCode,Failed to set MU EDCA override disable");
7597 }
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07007598
7599 if (sta_set_om_ctrl_supp(dut, intf, 1)) {
7600 sigma_dut_print(dut, DUT_MSG_ERROR,
7601 "Failed to set OM ctrl supp");
7602 }
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07007603
7604 if (sta_set_tx_su_ppdu_cfg(dut, intf, 1)) {
7605 sigma_dut_print(dut, DUT_MSG_ERROR,
7606 "Failed to set Tx SU PPDU enable");
7607 }
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07007608
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07007609 if (sta_set_action_tx_in_he_tb_ppdu(dut, intf, 0)) {
7610 sigma_dut_print(dut, DUT_MSG_ERROR,
7611 "failed to send TB PPDU Tx cfg");
7612 }
7613
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07007614 if (sta_set_he_om_ctrl_reset(dut, intf)) {
7615 sigma_dut_print(dut, DUT_MSG_ERROR,
7616 "Failed to set OM ctrl reset");
7617 }
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08007618
7619 /* +HTC-HE support default on */
7620 if (sta_set_he_htc_supp(dut, intf, 1)) {
7621 sigma_dut_print(dut, DUT_MSG_ERROR,
7622 "Setting of +HTC-HE support failed");
7623 }
Subhani Shaik8e7a3052018-04-24 14:03:00 -07007624#endif /* NL80211_SUPPORT */
7625
Arif Hussain8d5b27b2018-05-14 14:31:03 -07007626 if (sta_set_tx_beamformee(dut, intf, 1)) {
7627 sigma_dut_print(dut, DUT_MSG_ERROR,
7628 "Set tx beamformee enable by default in sta_reset_default_wcn failed");
7629 }
7630
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08007631 /* Set nss to 1 and MCS 0-7 in case of testbed */
7632 if (type && strcasecmp(type, "Testbed") == 0) {
7633#ifdef NL80211_SUPPORT
7634 int ret;
7635#endif /* NL80211_SUPPORT */
7636
7637 snprintf(buf, sizeof(buf), "iwpriv %s nss 1", intf);
7638 if (system(buf) != 0) {
7639 sigma_dut_print(dut, DUT_MSG_ERROR,
7640 "iwpriv %s nss failed", intf);
7641 }
7642
7643#ifdef NL80211_SUPPORT
7644 ret = sta_set_he_mcs(dut, intf, HE_80_MCS0_7);
7645 if (ret) {
7646 sigma_dut_print(dut, DUT_MSG_ERROR,
7647 "Setting of MCS failed, ret:%d",
7648 ret);
7649 }
7650#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyamc67621d2018-02-04 23:18:01 -08007651
7652 /* Disable STBC as default */
7653 wcn_sta_set_stbc(dut, intf, "0");
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08007654
7655 /* Disable AMSDU as default */
7656 iwpriv_sta_set_amsdu(dut, intf, "0");
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08007657
7658#ifdef NL80211_SUPPORT
7659 /* HE fragmentation default off */
7660 if (sta_set_he_fragmentation(dut, intf,
7661 HE_FRAG_DISABLE)) {
7662 sigma_dut_print(dut, DUT_MSG_ERROR,
7663 "Setting of HE fragmentation failed");
7664 }
Kiran Kumar Lokerebad51122018-12-12 19:03:36 -08007665
7666 /* set the beamformee NSTS(maximum number of
7667 * space-time streams) to default testbed config
7668 */
7669 if (sta_set_beamformee_sts(dut, intf, 3)) {
7670 sigma_dut_print(dut, DUT_MSG_ERROR,
7671 "Failed to set BeamformeeSTS");
7672 }
7673
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08007674 /* +HTC-HE support default off */
7675 if (sta_set_he_htc_supp(dut, intf, 0)) {
7676 sigma_dut_print(dut, DUT_MSG_ERROR,
7677 "Setting of +HTC-HE support failed");
7678 }
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08007679
7680 /* Set device HE capabilities to testbed default
7681 * configuration. */
7682 if (sta_set_he_testbed_def(dut, intf, 1)) {
7683 sigma_dut_print(dut, DUT_MSG_DEBUG,
7684 "Failed to set HE defaults");
7685 }
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08007686
7687 /* Disable VHT support in 2.4 GHz for testbed */
7688 sta_set_2g_vht_supp(dut, intf, 0);
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08007689#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08007690
7691 /* Enable WEP/TKIP with HE capability in testbed */
7692 if (sta_set_heconfig_and_wep_tkip(dut, intf, 1)) {
7693 sigma_dut_print(dut, DUT_MSG_ERROR,
7694 "Enabling HE config with WEP/TKIP failed");
7695 }
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08007696 }
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08007697
7698 /* Defaults in case of DUT */
7699 if (type && strcasecmp(type, "DUT") == 0) {
Arif Hussaind48fcc72018-05-01 18:34:18 -07007700 /* Enable STBC by default */
7701 wcn_sta_set_stbc(dut, intf, "1");
7702
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08007703 /* set nss to 2 */
7704 snprintf(buf, sizeof(buf), "iwpriv %s nss 2", intf);
7705 if (system(buf) != 0) {
7706 sigma_dut_print(dut, DUT_MSG_ERROR,
7707 "iwpriv %s nss 2 failed", intf);
7708 }
Arif Hussainac6c5112018-05-25 17:34:00 -07007709 dut->sta_nss = 2;
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08007710
7711#ifdef NL80211_SUPPORT
Arif Hussainae239842018-05-01 18:20:05 -07007712 /* Set HE_MCS to 0-11 */
7713 if (sta_set_he_mcs(dut, intf, HE_80_MCS0_11)) {
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08007714 sigma_dut_print(dut, DUT_MSG_ERROR,
7715 "Setting of MCS failed");
7716 }
7717#endif /* NL80211_SUPPORT */
7718
7719 /* Disable WEP/TKIP with HE capability in DUT */
7720 if (sta_set_heconfig_and_wep_tkip(dut, intf, 0)) {
7721 sigma_dut_print(dut, DUT_MSG_ERROR,
7722 "Enabling HE config with WEP/TKIP failed");
7723 }
7724 }
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08007725 }
7726}
7727
7728
Jouni Malinenf7222712019-06-13 01:50:21 +03007729static enum sigma_cmd_result cmd_sta_reset_default(struct sigma_dut *dut,
7730 struct sigma_conn *conn,
7731 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007732{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007733 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007734 const char *band = get_param(cmd, "band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007735 const char *type;
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07007736 const char *program = get_param(cmd, "program");
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05307737 const char *dev_role = get_param(cmd, "DevRole");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007738
Jouni Malinenb21f0542019-11-04 17:53:38 +02007739 if (dut->station_ifname_2g &&
7740 strcmp(dut->station_ifname_2g, intf) == 0)
7741 dut->use_5g = 0;
7742 else if (dut->station_ifname_5g &&
7743 strcmp(dut->station_ifname_5g, intf) == 0)
7744 dut->use_5g = 1;
7745
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07007746 if (!program)
7747 program = get_param(cmd, "prog");
7748 dut->program = sigma_program_to_enum(program);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007749 dut->device_type = STA_unknown;
7750 type = get_param(cmd, "type");
7751 if (type && strcasecmp(type, "Testbed") == 0)
7752 dut->device_type = STA_testbed;
7753 if (type && strcasecmp(type, "DUT") == 0)
7754 dut->device_type = STA_dut;
7755
7756 if (dut->program == PROGRAM_TDLS) {
7757 /* Clear TDLS testing mode */
7758 wpa_command(intf, "SET tdls_disabled 0");
7759 wpa_command(intf, "SET tdls_testing 0");
7760 dut->no_tpk_expiration = 0;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007761 if (get_driver_type(dut) == DRIVER_WCN) {
Pradeep Reddy POTTETI8ce2a232016-10-28 12:17:32 +05307762 /* Enable the WCN driver in TDLS Explicit trigger mode
7763 */
7764 wpa_command(intf, "SET tdls_external_control 0");
7765 wpa_command(intf, "SET tdls_trigger_control 0");
7766 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007767 }
7768
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07007769#ifdef MIRACAST
7770 if (dut->program == PROGRAM_WFD ||
7771 dut->program == PROGRAM_DISPLAYR2)
7772 miracast_sta_reset_default(dut, conn, cmd);
7773#endif /* MIRACAST */
7774
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007775 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007776 case DRIVER_ATHEROS:
7777 sta_reset_default_ath(dut, intf, type);
7778 break;
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08007779 case DRIVER_WCN:
7780 sta_reset_default_wcn(dut, intf, type);
7781 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007782 default:
7783 break;
7784 }
7785
7786#ifdef ANDROID_NAN
7787 if (dut->program == PROGRAM_NAN)
7788 nan_cmd_sta_reset_default(dut, conn, cmd);
7789#endif /* ANDROID_NAN */
7790
Vinay Gannevaram3b9fdd32019-06-14 17:55:44 +05307791 if (dut->program == PROGRAM_LOC &&
7792 lowi_cmd_sta_reset_default(dut, conn, cmd) < 0)
7793 return ERROR_SEND_STATUS;
7794
Jouni Malinenba630452018-06-22 11:49:59 +03007795 if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007796 unlink("SP/wi-fi.org/pps.xml");
7797 if (system("rm -r SP/*") != 0) {
7798 }
7799 unlink("next-client-cert.pem");
7800 unlink("next-client-key.pem");
7801 }
7802
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007803 /* For WPS program of the 60 GHz band the band type needs to be saved */
7804 if (dut->program == PROGRAM_WPS) {
7805 if (band && strcasecmp(band, "60GHz") == 0) {
7806 dut->band = WPS_BAND_60G;
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02007807 /* For 60 GHz enable WPS for WPS TCs */
7808 dut->wps_disable = 0;
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007809 } else {
7810 dut->band = WPS_BAND_NON_60G;
7811 }
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02007812 } else if (dut->program == PROGRAM_60GHZ) {
7813 /* For 60 GHz MAC/PHY TCs WPS must be disabled */
7814 dut->wps_disable = 1;
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007815 }
7816
Alexei Avshalom Lazar157ba062018-12-23 16:15:26 +02007817 if (is_60g_sigma_dut(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007818 const char *dev_role = get_param(cmd, "DevRole");
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02007819 char buf[256];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007820
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02007821 sigma_dut_print(dut, DUT_MSG_INFO,
7822 "WPS 60 GHz program, wps_disable = %d",
7823 dut->wps_disable);
7824
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007825 if (!dev_role) {
7826 send_resp(dut, conn, SIGMA_ERROR,
7827 "errorCode,Missing DevRole argument");
7828 return 0;
7829 }
7830
7831 if (strcasecmp(dev_role, "STA") == 0)
7832 dut->dev_role = DEVROLE_STA;
7833 else if (strcasecmp(dev_role, "PCP") == 0)
7834 dut->dev_role = DEVROLE_PCP;
7835 else {
7836 send_resp(dut, conn, SIGMA_ERROR,
7837 "errorCode,Unknown DevRole");
7838 return 0;
7839 }
7840
7841 if (dut->device_type == STA_unknown) {
7842 sigma_dut_print(dut, DUT_MSG_ERROR,
7843 "Device type is not STA testbed or DUT");
7844 send_resp(dut, conn, SIGMA_ERROR,
7845 "errorCode,Unknown device type");
7846 return 0;
7847 }
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02007848
7849 sigma_dut_print(dut, DUT_MSG_DEBUG,
7850 "Setting msdu_size to MAX: 7912");
7851 snprintf(buf, sizeof(buf), "ifconfig %s mtu 7912",
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007852 get_station_ifname(dut));
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02007853
7854 if (system(buf) != 0) {
7855 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
7856 buf);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007857 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02007858 }
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02007859
7860 if (sta_set_force_mcs(dut, 0, 1)) {
7861 sigma_dut_print(dut, DUT_MSG_ERROR,
7862 "Failed to reset force MCS");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007863 return ERROR_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02007864 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007865 }
7866
7867 wpa_command(intf, "WPS_ER_STOP");
7868 wpa_command(intf, "FLUSH");
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05307869 wpa_command(intf, "ERP_FLUSH");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007870 wpa_command(intf, "SET radio_disabled 0");
7871
Alexei Avshalom Lazar744ae8a2019-01-31 17:26:46 +02007872 dut->wps_forced_version = 0;
7873
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007874 if (dut->wsc_fragment) {
7875 dut->wsc_fragment = 0;
7876 wpa_command(intf, "SET device_name Test client");
7877 wpa_command(intf, "SET manufacturer ");
7878 wpa_command(intf, "SET model_name ");
7879 wpa_command(intf, "SET model_number ");
7880 wpa_command(intf, "SET serial_number ");
7881 }
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02007882 if (is_60g_sigma_dut(dut) && dut->force_rsn_ie) {
7883 dut->force_rsn_ie = FORCE_RSN_IE_NONE;
7884 sta_60g_force_rsn_ie(dut, FORCE_RSN_IE_NONE);
7885 }
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007886
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007887 if (dut->tmp_mac_addr && dut->set_macaddr) {
7888 dut->tmp_mac_addr = 0;
7889 if (system(dut->set_macaddr) != 0) {
7890 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to clear "
7891 "temporary MAC address");
7892 }
7893 }
7894
7895 set_ps(intf, dut, 0);
7896
Jouni Malinenba630452018-06-22 11:49:59 +03007897 if (dut->program == PROGRAM_HS2 || dut->program == PROGRAM_HS2_R2 ||
7898 dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007899 wpa_command(intf, "SET interworking 1");
7900 wpa_command(intf, "SET hs20 1");
7901 }
7902
Deepak Dhamdhere0fe0e452017-12-18 14:52:09 -08007903 if (dut->program == PROGRAM_HS2_R2 ||
Jouni Malinenba630452018-06-22 11:49:59 +03007904 dut->program == PROGRAM_HS2_R3 ||
Deepak Dhamdhere0fe0e452017-12-18 14:52:09 -08007905 dut->program == PROGRAM_OCE) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007906 wpa_command(intf, "SET pmf 1");
7907 } else {
7908 wpa_command(intf, "SET pmf 0");
7909 }
7910
7911 hs2_clear_credentials(intf);
7912 wpa_command(intf, "SET hessid 00:00:00:00:00:00");
7913 wpa_command(intf, "SET access_network_type 15");
7914
7915 static_ip_file(0, NULL, NULL, NULL);
7916 kill_dhcp_client(dut, intf);
7917 clear_ip_addr(dut, intf);
7918
7919 dut->er_oper_performed = 0;
7920 dut->er_oper_bssid[0] = '\0';
7921
priyadharshini gowthamanad6cbba2016-10-04 10:39:58 -07007922 if (dut->program == PROGRAM_LOC) {
7923 /* Disable Interworking by default */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007924 wpa_command(get_station_ifname(dut), "SET interworking 0");
priyadharshini gowthamanad6cbba2016-10-04 10:39:58 -07007925 }
7926
Ashwini Patil00402582017-04-13 12:29:39 +05307927 if (dut->program == PROGRAM_MBO) {
7928 free(dut->non_pref_ch_list);
7929 dut->non_pref_ch_list = NULL;
Ashwini Patil5acd7382017-04-13 15:55:04 +05307930 free(dut->btm_query_cand_list);
7931 dut->btm_query_cand_list = NULL;
Ashwini Patilc63161e2017-04-13 16:30:23 +05307932 wpa_command(intf, "SET reject_btm_req_reason 0");
Ashwini Patila75de5a2017-04-13 16:35:05 +05307933 wpa_command(intf, "SET ignore_assoc_disallow 0");
Ashwini Patild174f2c2017-04-13 16:49:46 +05307934 wpa_command(intf, "SET gas_address3 0");
Ashwini Patil9183fdb2017-04-13 16:58:25 +05307935 wpa_command(intf, "SET roaming 1");
Ankita Bajaj1d974552018-09-18 16:56:44 +05307936 wpa_command(intf, "SET interworking 1");
Ashwini Patil00402582017-04-13 12:29:39 +05307937 }
7938
Jouni Malinen3c367e82017-06-23 17:01:47 +03007939 free(dut->rsne_override);
7940 dut->rsne_override = NULL;
7941
Jouni Malinen68143132017-09-02 02:34:08 +03007942 free(dut->sae_commit_override);
7943 dut->sae_commit_override = NULL;
Jouni Malinen4b3769d2019-10-10 16:20:29 +03007944 wpa_command(intf, "SET sae_pmkid_in_assoc 0");
Jouni Malinen11e55212019-11-22 21:46:59 +02007945 dut->sae_pwe = SAE_PWE_DEFAULT;
Jouni Malinen68143132017-09-02 02:34:08 +03007946
Jouni Malinen134fe3c2019-06-12 04:16:49 +03007947 dut->sta_associate_wait_connect = 0;
7948 dut->server_cert_hash[0] = '\0';
Jouni Malinen37d5c692019-08-19 16:56:55 +03007949 dut->server_cert_tod = 0;
Jouni Malinen134fe3c2019-06-12 04:16:49 +03007950 dut->sta_tod_policy = 0;
7951
Jouni Malinend86e5822017-08-29 03:55:32 +03007952 dut->dpp_conf_id = -1;
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02007953 free(dut->dpp_peer_uri);
7954 dut->dpp_peer_uri = NULL;
Jouni Malinen63d50412017-11-24 11:55:38 +02007955 dut->dpp_local_bootstrap = -1;
Jouni Malinen5011fb52017-12-05 21:00:15 +02007956 wpa_command(intf, "SET dpp_config_processing 2");
Jouni Malinend86e5822017-08-29 03:55:32 +03007957
Jouni Malinenfac9cad2017-10-10 18:35:55 +03007958 wpa_command(intf, "VENDOR_ELEM_REMOVE 13 *");
7959
vamsi krishnaa2799492017-12-05 14:28:01 +05307960 if (dut->program == PROGRAM_OCE) {
Ankita Bajaja2cb5672017-10-25 16:08:28 +05307961 wpa_command(intf, "SET oce 1");
vamsi krishnaa2799492017-12-05 14:28:01 +05307962 wpa_command(intf, "SET disable_fils 0");
Ankita Bajaj1bde7942018-01-09 19:15:01 +05307963 wpa_command(intf, "FILS_HLP_REQ_FLUSH");
7964 dut->fils_hlp = 0;
7965#ifdef ANDROID
7966 hlp_thread_cleanup(dut);
7967#endif /* ANDROID */
vamsi krishnaa2799492017-12-05 14:28:01 +05307968 }
Ankita Bajaja2cb5672017-10-25 16:08:28 +05307969
Vamsi Krishnaf642d6a2020-03-27 12:33:14 +05307970 if (dut->program == PROGRAM_QM)
7971 wpa_command(intf, "SET interworking 1");
7972
Jouni Malinen8179fee2019-03-28 03:19:47 +02007973 dut->akm_values = 0;
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007974 dut->sta_ft_ds = 0;
Jouni Malinen8179fee2019-03-28 03:19:47 +02007975
Sunil Dutt076081f2018-02-05 19:45:50 +05307976#ifdef NL80211_SUPPORT
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007977 if (get_driver_type(dut) == DRIVER_WCN &&
Sunil Dutt44595082018-02-12 19:41:45 +05307978 dut->config_rsnie == 1) {
7979 dut->config_rsnie = 0;
7980 sta_config_rsnie(dut, 0);
Sunil Dutt076081f2018-02-05 19:45:50 +05307981 }
7982#endif /* NL80211_SUPPORT */
7983
Sunil Duttfebf8a82018-02-09 18:50:13 +05307984 if (dev_role && strcasecmp(dev_role, "STA-CFON") == 0) {
7985 dut->dev_role = DEVROLE_STA_CFON;
7986 return sta_cfon_reset_default(dut, conn, cmd);
7987 }
7988
Jouni Malinen439352d2018-09-13 03:42:23 +03007989 wpa_command(intf, "SET setband AUTO");
7990
Sunil Duttfebf8a82018-02-09 18:50:13 +05307991 if (dut->program != PROGRAM_VHT)
7992 return cmd_sta_p2p_reset(dut, conn, cmd);
7993
Priyadharshini Gowthamana7dfd492015-11-09 14:34:08 -08007994 return 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007995}
7996
7997
Jouni Malinenf7222712019-06-13 01:50:21 +03007998static enum sigma_cmd_result cmd_sta_get_events(struct sigma_dut *dut,
7999 struct sigma_conn *conn,
8000 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008001{
8002 const char *program = get_param(cmd, "Program");
8003
8004 if (program == NULL)
8005 return -1;
8006#ifdef ANDROID_NAN
8007 if (strcasecmp(program, "NAN") == 0)
8008 return nan_cmd_sta_get_events(dut, conn, cmd);
8009#endif /* ANDROID_NAN */
8010 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
8011 return 0;
8012}
8013
8014
Jouni Malinen82905202018-04-29 17:20:10 +03008015static int sta_exec_action_url(struct sigma_dut *dut, struct sigma_conn *conn,
8016 struct sigma_cmd *cmd)
8017{
8018 const char *url = get_param(cmd, "url");
8019 const char *method = get_param(cmd, "method");
8020 pid_t pid;
8021 int status;
8022
8023 if (!url || !method)
8024 return -1;
8025
8026 /* TODO: Add support for method,post */
8027 if (strcasecmp(method, "get") != 0) {
8028 send_resp(dut, conn, SIGMA_ERROR,
8029 "ErrorCode,Unsupported method");
8030 return 0;
8031 }
8032
8033 pid = fork();
8034 if (pid < 0) {
8035 perror("fork");
8036 return -1;
8037 }
8038
8039 if (pid == 0) {
8040 char * argv[5] = { "wget", "-O", "/dev/null",
8041 (char *) url, NULL };
8042
8043 execv("/usr/bin/wget", argv);
8044 perror("execv");
8045 exit(0);
8046 return -1;
8047 }
8048
8049 if (waitpid(pid, &status, 0) < 0) {
8050 perror("waitpid");
8051 return -1;
8052 }
8053
8054 if (WIFEXITED(status)) {
8055 const char *errmsg;
8056
8057 if (WEXITSTATUS(status) == 0)
8058 return 1;
8059 sigma_dut_print(dut, DUT_MSG_INFO, "wget exit status %d",
8060 WEXITSTATUS(status));
8061 switch (WEXITSTATUS(status)) {
8062 case 4:
8063 errmsg = "errmsg,Network failure";
8064 break;
8065 case 8:
8066 errmsg = "errmsg,Server issued an error response";
8067 break;
8068 default:
8069 errmsg = "errmsg,Unknown failure from wget";
8070 break;
8071 }
8072 send_resp(dut, conn, SIGMA_ERROR, errmsg);
8073 return 0;
8074 }
8075
8076 send_resp(dut, conn, SIGMA_ERROR, "errmsg,Unknown failure");
8077 return 0;
8078}
8079
8080
Jouni Malinenf7222712019-06-13 01:50:21 +03008081static enum sigma_cmd_result cmd_sta_exec_action(struct sigma_dut *dut,
8082 struct sigma_conn *conn,
8083 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008084{
8085 const char *program = get_param(cmd, "Prog");
8086
Jouni Malinen82905202018-04-29 17:20:10 +03008087 if (program && !get_param(cmd, "interface"))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008088 return -1;
8089#ifdef ANDROID_NAN
Jouni Malinen82905202018-04-29 17:20:10 +03008090 if (program && strcasecmp(program, "NAN") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008091 return nan_cmd_sta_exec_action(dut, conn, cmd);
8092#endif /* ANDROID_NAN */
Jouni Malinen82905202018-04-29 17:20:10 +03008093
8094 if (program && strcasecmp(program, "Loc") == 0)
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07008095 return loc_cmd_sta_exec_action(dut, conn, cmd);
Jouni Malinen82905202018-04-29 17:20:10 +03008096
8097 if (get_param(cmd, "url"))
8098 return sta_exec_action_url(dut, conn, cmd);
8099
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008100 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
8101 return 0;
8102}
8103
8104
Jouni Malinenf7222712019-06-13 01:50:21 +03008105static enum sigma_cmd_result cmd_sta_set_11n(struct sigma_dut *dut,
8106 struct sigma_conn *conn,
8107 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008108{
8109 const char *intf = get_param(cmd, "Interface");
8110 const char *val, *mcs32, *rate;
8111
8112 val = get_param(cmd, "GREENFIELD");
8113 if (val) {
8114 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
8115 /* Enable GD */
8116 send_resp(dut, conn, SIGMA_ERROR,
8117 "ErrorCode,GF not supported");
8118 return 0;
8119 }
8120 }
8121
8122 val = get_param(cmd, "SGI20");
8123 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02008124 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008125 case DRIVER_ATHEROS:
8126 ath_sta_set_sgi(dut, intf, val);
8127 break;
8128 default:
8129 send_resp(dut, conn, SIGMA_ERROR,
8130 "ErrorCode,SGI20 not supported");
8131 return 0;
8132 }
8133 }
8134
8135 mcs32 = get_param(cmd, "MCS32"); /* HT Duplicate Mode Enable/Disable */
8136 rate = get_param(cmd, "MCS_FIXEDRATE"); /* Fixed MCS rate (0..31) */
8137 if (mcs32 && rate) {
8138 /* TODO */
8139 send_resp(dut, conn, SIGMA_ERROR,
8140 "ErrorCode,MCS32,MCS_FIXEDRATE not supported");
8141 return 0;
8142 } else if (mcs32 && !rate) {
8143 /* TODO */
8144 send_resp(dut, conn, SIGMA_ERROR,
8145 "ErrorCode,MCS32 not supported");
8146 return 0;
8147 } else if (!mcs32 && rate) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02008148 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008149 case DRIVER_ATHEROS:
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -07008150 novap_reset(dut, intf, 1);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008151 ath_sta_set_11nrates(dut, intf, rate);
8152 break;
8153 default:
8154 send_resp(dut, conn, SIGMA_ERROR,
8155 "ErrorCode,MCS32_FIXEDRATE not supported");
8156 return 0;
8157 }
8158 }
8159
8160 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
8161}
8162
8163
Arif Hussain7b47d2d2018-05-09 10:44:02 -07008164static void cmd_set_max_he_mcs(struct sigma_dut *dut, const char *intf,
8165 int mcs_config)
8166{
8167#ifdef NL80211_SUPPORT
8168 int ret;
8169
8170 switch (mcs_config) {
8171 case HE_80_MCS0_7:
8172 case HE_80_MCS0_9:
8173 case HE_80_MCS0_11:
8174 ret = sta_set_he_mcs(dut, intf, mcs_config);
8175 if (ret) {
8176 sigma_dut_print(dut, DUT_MSG_ERROR,
8177 "cmd_set_max_he_mcs: Setting of MCS:%d failed, ret:%d",
8178 mcs_config, ret);
8179 }
8180 break;
8181 default:
8182 sigma_dut_print(dut, DUT_MSG_ERROR,
8183 "cmd_set_max_he_mcs: Invalid mcs %d",
8184 mcs_config);
8185 break;
8186 }
8187#else /* NL80211_SUPPORT */
8188 sigma_dut_print(dut, DUT_MSG_ERROR,
8189 "max HE MCS cannot be changed without NL80211_SUPPORT defined");
8190#endif /* NL80211_SUPPORT */
8191}
8192
8193
Arif Hussain480d5f42019-03-12 14:40:42 -07008194static int sta_twt_request(struct sigma_dut *dut, struct sigma_conn *conn,
8195 struct sigma_cmd *cmd)
8196{
8197#ifdef NL80211_SUPPORT
8198 struct nlattr *params;
8199 struct nlattr *attr;
8200 struct nlattr *attr1;
8201 struct nl_msg *msg;
8202 int ifindex, ret;
8203 const char *val;
8204 const char *intf = get_param(cmd, "Interface");
8205 int wake_interval_exp = 10, nominal_min_wake_dur = 255,
8206 wake_interval_mantissa = 512;
8207 int flow_type = 0, twt_trigger = 0, target_wake_time = 0,
8208 protection = 0;
8209
8210 ifindex = if_nametoindex(intf);
8211 if (ifindex == 0) {
8212 sigma_dut_print(dut, DUT_MSG_ERROR,
8213 "%s: Index for interface %s failed",
8214 __func__, intf);
8215 return -1;
8216 }
8217
8218 val = get_param(cmd, "FlowType");
8219 if (val) {
8220 flow_type = atoi(val);
8221 if (flow_type != 0 && flow_type != 1) {
8222 sigma_dut_print(dut, DUT_MSG_ERROR,
8223 "TWT: Invalid FlowType %d", flow_type);
8224 return -1;
8225 }
8226 }
8227
8228 val = get_param(cmd, "TWT_Trigger");
8229 if (val) {
8230 twt_trigger = atoi(val);
8231 if (twt_trigger != 0 && twt_trigger != 1) {
8232 sigma_dut_print(dut, DUT_MSG_ERROR,
8233 "TWT: Invalid TWT_Trigger %d",
8234 twt_trigger);
8235 return -1;
8236 }
8237 }
8238
8239 val = get_param(cmd, "Protection");
8240 if (val) {
8241 protection = atoi(val);
8242 if (protection != 0 && protection != 1) {
8243 sigma_dut_print(dut, DUT_MSG_ERROR,
8244 "TWT: Invalid Protection %d",
8245 protection);
8246 return -1;
8247 }
8248 }
8249
8250 val = get_param(cmd, "TargetWakeTime");
8251 if (val)
8252 target_wake_time = atoi(val);
8253
8254 val = get_param(cmd, "WakeIntervalMantissa");
8255 if (val)
8256 wake_interval_mantissa = atoi(val);
8257
8258 val = get_param(cmd, "WakeIntervalExp");
8259 if (val)
8260 wake_interval_exp = atoi(val);
8261
8262 val = get_param(cmd, "NominalMinWakeDur");
8263 if (val)
8264 nominal_min_wake_dur = atoi(val);
8265
8266 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8267 NL80211_CMD_VENDOR)) ||
8268 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
8269 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
8270 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
8271 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
8272 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8273 !(params = nla_nest_start(
8274 msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_SETUP)) ||
8275 !(attr1 = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8276 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_EXP,
8277 wake_interval_exp) ||
Arif Hussain480d5f42019-03-12 14:40:42 -07008278 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_REQ_TYPE, 1) ||
Kiran Kumar Lokere2cffae52019-09-26 18:44:15 -07008279 (twt_trigger &&
8280 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TRIGGER)) ||
Arif Hussain480d5f42019-03-12 14:40:42 -07008281 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE,
8282 flow_type) ||
Kiran Kumar Lokere2cffae52019-09-26 18:44:15 -07008283 (protection &&
8284 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_PROTECTION)) ||
Arif Hussain480d5f42019-03-12 14:40:42 -07008285 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME,
8286 target_wake_time) ||
8287 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_DURATION,
8288 nominal_min_wake_dur) ||
8289 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_MANTISSA,
8290 wake_interval_mantissa)) {
8291 sigma_dut_print(dut, DUT_MSG_ERROR,
8292 "%s: err in adding vendor_cmd and vendor_data",
8293 __func__);
8294 nlmsg_free(msg);
8295 return -1;
8296 }
8297 nla_nest_end(msg, attr1);
8298 nla_nest_end(msg, params);
8299 nla_nest_end(msg, attr);
8300
8301 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
8302 if (ret) {
8303 sigma_dut_print(dut, DUT_MSG_ERROR,
8304 "%s: err in send_and_recv_msgs, ret=%d",
8305 __func__, ret);
8306 }
8307
8308 return ret;
8309#else /* NL80211_SUPPORT */
8310 sigma_dut_print(dut, DUT_MSG_ERROR,
8311 "TWT request cannot be done without NL80211_SUPPORT defined");
8312 return -1;
8313#endif /* NL80211_SUPPORT */
8314}
8315
8316
8317static int sta_twt_teardown(struct sigma_dut *dut, struct sigma_conn *conn,
8318 struct sigma_cmd *cmd)
8319{
8320 #ifdef NL80211_SUPPORT
8321 struct nlattr *params;
8322 struct nlattr *attr;
8323 struct nlattr *attr1;
8324 int ifindex, ret;
8325 struct nl_msg *msg;
8326 const char *intf = get_param(cmd, "Interface");
8327
8328 ifindex = if_nametoindex(intf);
8329 if (ifindex == 0) {
8330 sigma_dut_print(dut, DUT_MSG_ERROR,
8331 "%s: Index for interface %s failed",
8332 __func__, intf);
8333 return -1;
8334 }
8335
8336 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8337 NL80211_CMD_VENDOR)) ||
8338 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
8339 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
8340 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
8341 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
8342 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8343 !(params = nla_nest_start(
8344 msg,
8345 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_TERMINATE)) ||
8346 !(attr1 = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8347 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE, 0)) {
8348 sigma_dut_print(dut, DUT_MSG_ERROR,
8349 "%s: err in adding vendor_cmd and vendor_data",
8350 __func__);
8351 nlmsg_free(msg);
8352 return -1;
8353 }
8354 nla_nest_end(msg, attr1);
8355 nla_nest_end(msg, params);
8356 nla_nest_end(msg, attr);
8357
8358 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
8359 if (ret) {
8360 sigma_dut_print(dut, DUT_MSG_ERROR,
8361 "%s: err in send_and_recv_msgs, ret=%d",
8362 __func__, ret);
8363 }
8364
8365 return ret;
8366#else /* NL80211_SUPPORT */
8367 sigma_dut_print(dut, DUT_MSG_ERROR,
8368 "TWT teardown cannot be done without NL80211_SUPPORT defined");
8369 return -1;
8370#endif /* NL80211_SUPPORT */
8371}
8372
8373
Kiran Kumar Lokere50eb2cd2018-12-18 18:31:28 -08008374static int sta_transmit_omi(struct sigma_dut *dut, struct sigma_conn *conn,
8375 struct sigma_cmd *cmd)
8376{
8377#ifdef NL80211_SUPPORT
8378 struct nlattr *params;
8379 struct nlattr *attr;
8380 struct nlattr *attr1;
8381 struct nl_msg *msg;
8382 int ifindex, ret;
8383 const char *val;
8384 const char *intf = get_param(cmd, "Interface");
8385 uint8_t rx_nss = 0xFF, ch_bw = 0xFF, tx_nsts = 0xFF, ulmu_dis = 0,
8386 ulmu_data_dis = 0;
8387
8388 ifindex = if_nametoindex(intf);
8389 if (ifindex == 0) {
8390 sigma_dut_print(dut, DUT_MSG_ERROR,
8391 "%s: Index for interface %s failed",
8392 __func__, intf);
8393 return -1;
8394 }
8395 val = get_param(cmd, "OMCtrl_RxNSS");
8396 if (val)
8397 rx_nss = atoi(val);
8398
8399 val = get_param(cmd, "OMCtrl_ChnlWidth");
8400 if (val)
8401 ch_bw = atoi(val);
8402
8403 val = get_param(cmd, "OMCtrl_ULMUDisable");
8404 if (val)
8405 ulmu_dis = atoi(val);
8406
8407 val = get_param(cmd, "OMCtrl_TxNSTS");
8408 if (val)
8409 tx_nsts = atoi(val);
8410
8411 val = get_param(cmd, "OMCtrl_ULMUDataDisable");
8412 if (val)
8413 ulmu_data_dis = atoi(val);
8414
8415 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8416 NL80211_CMD_VENDOR)) ||
8417 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
8418 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
8419 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
8420 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
8421 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8422 !(params = nla_nest_start(
8423 msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OMI_TX)) ||
8424 !(attr1 = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8425 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_RX_NSS, rx_nss) ||
8426 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_CH_BW, ch_bw) ||
8427 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_TX_NSTS, tx_nsts) ||
8428 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DATA_DISABLE,
8429 ulmu_data_dis) ||
8430 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DISABLE,
8431 ulmu_dis)) {
8432 sigma_dut_print(dut, DUT_MSG_ERROR,
8433 "%s: err in adding vendor_cmd and vendor_data",
8434 __func__);
8435 nlmsg_free(msg);
8436 return -1;
8437 }
8438 nla_nest_end(msg, attr1);
8439 nla_nest_end(msg, params);
8440 nla_nest_end(msg, attr);
8441
8442 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
8443 if (ret) {
8444 sigma_dut_print(dut, DUT_MSG_ERROR,
8445 "%s: err in send_and_recv_msgs, ret=%d",
8446 __func__, ret);
8447 }
8448
8449 return ret;
8450#else /* NL80211_SUPPORT */
8451 sigma_dut_print(dut, DUT_MSG_ERROR,
8452 "OMI TX cannot be processed without NL80211_SUPPORT defined");
8453 return -1;
8454#endif /* NL80211_SUPPORT */
8455}
8456
8457
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008458static int cmd_sta_set_wireless_vht(struct sigma_dut *dut,
8459 struct sigma_conn *conn,
8460 struct sigma_cmd *cmd)
8461{
8462 const char *intf = get_param(cmd, "Interface");
8463 const char *val;
Arif Hussaina37e9552018-06-20 17:05:59 -07008464 const char *program;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008465 int tkip = -1;
8466 int wep = -1;
8467
Arif Hussaina37e9552018-06-20 17:05:59 -07008468 program = get_param(cmd, "Program");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008469 val = get_param(cmd, "SGI80");
8470 if (val) {
8471 int sgi80;
8472
8473 sgi80 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008474 run_iwpriv(dut, intf, "shortgi %d", sgi80);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008475 }
8476
8477 val = get_param(cmd, "TxBF");
8478 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02008479 switch (get_driver_type(dut)) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07008480 case DRIVER_WCN:
8481 if (sta_set_tx_beamformee(dut, intf, 1)) {
8482 send_resp(dut, conn, SIGMA_ERROR,
8483 "ErrorCode,Failed to set TX beamformee enable");
8484 return 0;
8485 }
8486 break;
8487 case DRIVER_ATHEROS:
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008488 if (run_iwpriv(dut, intf, "vhtsubfee 1") < 0) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07008489 send_resp(dut, conn, SIGMA_ERROR,
8490 "ErrorCode,Setting vhtsubfee failed");
8491 return 0;
8492 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008493 if (run_iwpriv(dut, intf, "vhtsubfer 1") < 0) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07008494 send_resp(dut, conn, SIGMA_ERROR,
8495 "ErrorCode,Setting vhtsubfer failed");
8496 return 0;
8497 }
8498 break;
8499 default:
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008500 sigma_dut_print(dut, DUT_MSG_ERROR,
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07008501 "Unsupported driver type");
8502 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008503 }
8504 }
8505
8506 val = get_param(cmd, "MU_TxBF");
8507 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02008508 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008509 case DRIVER_ATHEROS:
8510 ath_sta_set_txsp_stream(dut, intf, "1SS");
8511 ath_sta_set_rxsp_stream(dut, intf, "1SS");
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008512 run_iwpriv(dut, intf, "vhtmubfee 1");
8513 run_iwpriv(dut, intf, "vhtmubfer 1");
Sunil Duttae9e5d12018-06-29 11:50:47 +05308514 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008515 case DRIVER_WCN:
8516 if (wcn_sta_set_sp_stream(dut, intf, "1SS") < 0) {
8517 send_resp(dut, conn, SIGMA_ERROR,
8518 "ErrorCode,Failed to set RX/TXSP_STREAM");
8519 return 0;
8520 }
Sunil Duttae9e5d12018-06-29 11:50:47 +05308521 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008522 default:
8523 sigma_dut_print(dut, DUT_MSG_ERROR,
8524 "Setting SP_STREAM not supported");
8525 break;
8526 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008527 }
8528
8529 val = get_param(cmd, "LDPC");
8530 if (val) {
8531 int ldpc;
8532
8533 ldpc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008534 run_iwpriv(dut, intf, "ldpc %d", ldpc);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008535 }
8536
Amarnath Hullur Subramanyam7bae60e2018-01-31 03:46:50 -08008537 val = get_param(cmd, "BCC");
8538 if (val) {
8539 int bcc;
8540
8541 bcc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
8542 /* use LDPC iwpriv itself to set bcc coding, bcc coding
8543 * is mutually exclusive to bcc */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008544 run_iwpriv(dut, intf, "ldpc %d", !bcc);
Amarnath Hullur Subramanyam7bae60e2018-01-31 03:46:50 -08008545 }
8546
Arif Hussain7b47d2d2018-05-09 10:44:02 -07008547 val = get_param(cmd, "MaxHE-MCS_1SS_RxMapLTE80");
8548 if (val && dut->sta_nss == 1)
8549 cmd_set_max_he_mcs(dut, intf, atoi(val));
8550
8551 val = get_param(cmd, "MaxHE-MCS_2SS_RxMapLTE80");
8552 if (val && dut->sta_nss == 2)
8553 cmd_set_max_he_mcs(dut, intf, atoi(val));
8554
Arif Hussainac6c5112018-05-25 17:34:00 -07008555 val = get_param(cmd, "MCS_FixedRate");
8556 if (val) {
8557#ifdef NL80211_SUPPORT
8558 int mcs, ratecode = 0;
8559 enum he_mcs_config mcs_config;
8560 int ret;
Jouni Malinenb9b671d2019-04-26 13:23:17 +03008561 char buf[60];
Arif Hussainac6c5112018-05-25 17:34:00 -07008562
8563 ratecode = (0x07 & dut->sta_nss) << 5;
8564 mcs = atoi(val);
8565 /* Add the MCS to the ratecode */
8566 if (mcs >= 0 && mcs <= 11) {
8567 ratecode += mcs;
8568 if (dut->device_type == STA_testbed &&
8569 mcs > 7 && mcs <= 11) {
8570 if (mcs <= 9)
8571 mcs_config = HE_80_MCS0_9;
8572 else
8573 mcs_config = HE_80_MCS0_11;
8574 ret = sta_set_he_mcs(dut, intf, mcs_config);
8575 if (ret) {
8576 sigma_dut_print(dut, DUT_MSG_ERROR,
8577 "MCS_FixedRate: mcs setting failed, mcs:%d, mcs_config %d, ret:%d",
8578 mcs, mcs_config, ret);
8579 }
8580 }
8581 snprintf(buf, sizeof(buf),
8582 "iwpriv %s set_11ax_rate 0x%03x",
8583 intf, ratecode);
8584 if (system(buf) != 0) {
8585 sigma_dut_print(dut, DUT_MSG_ERROR,
8586 "MCS_FixedRate: iwpriv setting of 11ax rates 0x%03x failed",
8587 ratecode);
8588 }
8589 } else {
8590 sigma_dut_print(dut, DUT_MSG_ERROR,
8591 "MCS_FixedRate: HE MCS %d not supported",
8592 mcs);
8593 }
8594#else /* NL80211_SUPPORT */
8595 sigma_dut_print(dut, DUT_MSG_ERROR,
8596 "MCS_FixedRate cannot be changed without NL80211_SUPPORT defined");
8597#endif /* NL80211_SUPPORT */
8598 }
8599
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008600 val = get_param(cmd, "opt_md_notif_ie");
8601 if (val) {
8602 char *result = NULL;
8603 char delim[] = ";";
8604 char token[30];
8605 int value, config_val = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308606 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008607
Peng Xub8fc5cc2017-05-10 17:27:28 -07008608 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308609 result = strtok_r(token, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008610
8611 /* Extract the NSS information */
8612 if (result) {
8613 value = atoi(result);
8614 switch (value) {
8615 case 1:
8616 config_val = 1;
8617 break;
8618 case 2:
8619 config_val = 3;
8620 break;
8621 case 3:
8622 config_val = 7;
8623 break;
8624 case 4:
8625 config_val = 15;
8626 break;
8627 default:
8628 config_val = 3;
8629 break;
8630 }
8631
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008632 run_iwpriv(dut, intf, "rxchainmask %d", config_val);
8633 run_iwpriv(dut, intf, "txchainmask %d", config_val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008634
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008635 }
8636
8637 /* Extract the channel width information */
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308638 result = strtok_r(NULL, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008639 if (result) {
8640 value = atoi(result);
8641 switch (value) {
8642 case 20:
8643 config_val = 0;
8644 break;
8645 case 40:
8646 config_val = 1;
8647 break;
8648 case 80:
8649 config_val = 2;
8650 break;
8651 case 160:
8652 config_val = 3;
8653 break;
8654 default:
8655 config_val = 2;
8656 break;
8657 }
8658
8659 dut->chwidth = config_val;
8660
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008661 run_iwpriv(dut, intf, "chwidth %d", config_val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008662 }
8663
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008664 run_iwpriv(dut, intf, "opmode_notify 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008665 }
8666
8667 val = get_param(cmd, "nss_mcs_cap");
8668 if (val) {
8669 int nss, mcs;
8670 char token[20];
8671 char *result = NULL;
8672 unsigned int vht_mcsmap = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308673 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008674
Peng Xub8fc5cc2017-05-10 17:27:28 -07008675 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308676 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05308677 if (!result) {
8678 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07008679 "NSS not specified");
8680 send_resp(dut, conn, SIGMA_ERROR,
8681 "errorCode,NSS not specified");
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05308682 return 0;
8683 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008684 nss = atoi(result);
8685
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008686 run_iwpriv(dut, intf, "nss %d", nss);
Arif Hussainac6c5112018-05-25 17:34:00 -07008687 dut->sta_nss = nss;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008688
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308689 result = strtok_r(NULL, ";", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008690 if (result == NULL) {
8691 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07008692 "MCS not specified");
8693 send_resp(dut, conn, SIGMA_ERROR,
8694 "errorCode,MCS not specified");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008695 return 0;
8696 }
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308697 result = strtok_r(result, "-", &saveptr);
8698 result = strtok_r(NULL, "-", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05308699 if (!result) {
8700 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07008701 "MCS not specified");
8702 send_resp(dut, conn, SIGMA_ERROR,
8703 "errorCode,MCS not specified");
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05308704 return 0;
8705 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008706 mcs = atoi(result);
8707
Arif Hussaina37e9552018-06-20 17:05:59 -07008708 if (program && strcasecmp(program, "HE") == 0) {
8709#ifdef NL80211_SUPPORT
8710 enum he_mcs_config mcs_config;
8711 int ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008712
Arif Hussaina37e9552018-06-20 17:05:59 -07008713 if (mcs >= 0 && mcs <= 7) {
8714 mcs_config = HE_80_MCS0_7;
8715 } else if (mcs > 7 && mcs <= 9) {
8716 mcs_config = HE_80_MCS0_9;
8717 } else if (mcs > 9 && mcs <= 11) {
8718 mcs_config = HE_80_MCS0_11;
8719 } else {
8720 sigma_dut_print(dut, DUT_MSG_ERROR,
8721 "nss_mcs_cap: HE: Invalid mcs: %d",
8722 mcs);
8723 send_resp(dut, conn, SIGMA_ERROR,
8724 "errorCode,Invalid MCS");
8725 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008726 }
Arif Hussaina37e9552018-06-20 17:05:59 -07008727
8728 ret = sta_set_he_mcs(dut, intf, mcs_config);
8729 if (ret) {
8730 sigma_dut_print(dut, DUT_MSG_ERROR,
8731 "nss_mcs_cap: HE: Setting of MCS failed, mcs_config: %d, ret: %d",
8732 mcs_config, ret);
8733 send_resp(dut, conn, SIGMA_ERROR,
8734 "errorCode,Failed to set MCS");
8735 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008736 }
Arif Hussaina37e9552018-06-20 17:05:59 -07008737#else /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008738 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07008739 "nss_mcs_cap: HE: MCS cannot be changed without NL80211_SUPPORT defined");
8740#endif /* NL80211_SUPPORT */
8741 } else {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008742 run_iwpriv(dut, intf, "vhtmcs %d", mcs);
Arif Hussaina37e9552018-06-20 17:05:59 -07008743
8744 switch (nss) {
8745 case 1:
8746 switch (mcs) {
8747 case 7:
8748 vht_mcsmap = 0xfffc;
8749 break;
8750 case 8:
8751 vht_mcsmap = 0xfffd;
8752 break;
8753 case 9:
8754 vht_mcsmap = 0xfffe;
8755 break;
8756 default:
8757 vht_mcsmap = 0xfffe;
8758 break;
8759 }
8760 break;
8761 case 2:
8762 switch (mcs) {
8763 case 7:
8764 vht_mcsmap = 0xfff0;
8765 break;
8766 case 8:
8767 vht_mcsmap = 0xfff5;
8768 break;
8769 case 9:
8770 vht_mcsmap = 0xfffa;
8771 break;
8772 default:
8773 vht_mcsmap = 0xfffa;
8774 break;
8775 }
8776 break;
8777 case 3:
8778 switch (mcs) {
8779 case 7:
8780 vht_mcsmap = 0xffc0;
8781 break;
8782 case 8:
8783 vht_mcsmap = 0xffd5;
8784 break;
8785 case 9:
8786 vht_mcsmap = 0xffea;
8787 break;
8788 default:
8789 vht_mcsmap = 0xffea;
8790 break;
8791 }
8792 break;
8793 default:
8794 vht_mcsmap = 0xffea;
8795 break;
8796 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008797 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008798 }
8799 }
8800
8801 /* UNSUPPORTED: val = get_param(cmd, "Tx_lgi_rate"); */
8802
8803 val = get_param(cmd, "Vht_tkip");
8804 if (val)
8805 tkip = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
8806
8807 val = get_param(cmd, "Vht_wep");
8808 if (val)
8809 wep = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
8810
8811 if (tkip != -1 || wep != -1) {
8812 if ((tkip == 1 && wep != 0) || (wep == 1 && tkip != 0)) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008813 run_iwpriv(dut, intf, "htweptkip 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008814 } else if ((tkip == 0 && wep != 1) || (wep == 0 && tkip != 1)) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008815 run_iwpriv(dut, intf, "htweptkip 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008816 } else {
8817 sigma_dut_print(dut, DUT_MSG_ERROR,
8818 "ErrorCode,mixed mode of VHT TKIP/WEP not supported");
8819 return 0;
8820 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008821 }
8822
Arif Hussain55f00da2018-07-03 08:28:26 -07008823 val = get_param(cmd, "txBandwidth");
8824 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02008825 switch (get_driver_type(dut)) {
Arif Hussain55f00da2018-07-03 08:28:26 -07008826 case DRIVER_WCN:
8827 if (wcn_sta_set_width(dut, intf, val) < 0) {
8828 send_resp(dut, conn, SIGMA_ERROR,
8829 "ErrorCode,Failed to set txBandwidth");
8830 return 0;
8831 }
8832 break;
8833 case DRIVER_ATHEROS:
8834 if (ath_set_width(dut, conn, intf, val) < 0) {
8835 send_resp(dut, conn, SIGMA_ERROR,
8836 "ErrorCode,Failed to set txBandwidth");
8837 return 0;
8838 }
8839 break;
8840 default:
8841 sigma_dut_print(dut, DUT_MSG_ERROR,
8842 "Setting txBandwidth not supported");
8843 break;
8844 }
8845 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008846
Arif Hussain9765f7d2018-07-03 08:28:26 -07008847 val = get_param(cmd, "BeamformeeSTS");
8848 if (val) {
Kiran Kumar Lokerebc89d432018-07-10 12:20:13 -07008849 if (sta_set_tx_beamformee(dut, intf, 1)) {
8850 send_resp(dut, conn, SIGMA_ERROR,
8851 "ErrorCode,Failed to set TX beamformee enable");
8852 return 0;
8853 }
8854
Arif Hussain9765f7d2018-07-03 08:28:26 -07008855 if (sta_set_beamformee_sts(dut, intf, atoi(val))) {
8856 send_resp(dut, conn, SIGMA_ERROR,
8857 "ErrorCode,Failed to set BeamformeeSTS");
8858 return 0;
8859 }
8860 }
8861
Arif Hussain68d23f52018-07-11 13:39:08 -07008862 val = get_param(cmd, "Trig_MAC_Padding_Dur");
8863 if (val) {
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07008864#ifdef NL80211_SUPPORT
8865 enum qca_wlan_he_mac_padding_dur set_val;
8866
8867 switch (atoi(val)) {
8868 case 16:
8869 set_val = QCA_WLAN_HE_16US_OF_PROCESS_TIME;
8870 break;
8871 case 8:
8872 set_val = QCA_WLAN_HE_8US_OF_PROCESS_TIME;
8873 break;
8874 default:
8875 set_val = QCA_WLAN_HE_NO_ADDITIONAL_PROCESS_TIME;
8876 break;
8877 }
8878 if (sta_set_mac_padding_duration(dut, intf, set_val)) {
Arif Hussain68d23f52018-07-11 13:39:08 -07008879 send_resp(dut, conn, SIGMA_ERROR,
8880 "ErrorCode,Failed to set MAC padding duration");
8881 return 0;
8882 }
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07008883#else /* NL80211_SUPPORT */
8884 sigma_dut_print(dut, DUT_MSG_ERROR,
8885 "MAC padding duration cannot be changed without NL80211_SUPPORT defined");
8886#endif /* NL80211_SUPPORT */
Arif Hussain68d23f52018-07-11 13:39:08 -07008887 }
8888
Arif Hussain480d5f42019-03-12 14:40:42 -07008889 val = get_param(cmd, "TWT_ReqSupport");
8890 if (val) {
8891 int set_val;
8892
8893 if (strcasecmp(val, "Enable") == 0) {
8894 set_val = 1;
8895 } else if (strcasecmp(val, "Disable") == 0) {
8896 set_val = 0;
8897 } else {
8898 send_resp(dut, conn, SIGMA_ERROR,
8899 "ErrorCode,Invalid TWT_ReqSupport");
8900 return STATUS_SENT;
8901 }
8902
8903 if (sta_set_twt_req_support(dut, intf, set_val)) {
8904 sigma_dut_print(dut, DUT_MSG_ERROR,
8905 "Failed to set TWT req support %d",
8906 set_val);
8907 send_resp(dut, conn, SIGMA_ERROR,
8908 "ErrorCode,Failed to set TWT_ReqSupport");
8909 return STATUS_SENT;
8910 }
8911 }
8912
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07008913 val = get_param(cmd, "MU_EDCA");
8914 if (val && (strcasecmp(val, "Override") == 0)) {
8915 if (sta_set_mu_edca_override(dut, intf, 1)) {
8916 send_resp(dut, conn, SIGMA_ERROR,
8917 "ErrorCode,Failed to set MU EDCA override");
8918 return 0;
8919 }
8920 }
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -07008921
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07008922 val = get_param(cmd, "OMControl");
8923 if (val) {
8924 int set_val = 1;
8925
8926 if (strcasecmp(val, "Enable") == 0)
8927 set_val = 1;
8928 else if (strcasecmp(val, "Disable") == 0)
8929 set_val = 0;
8930
8931 if (sta_set_om_ctrl_supp(dut, intf, set_val)) {
8932 send_resp(dut, conn, SIGMA_ERROR,
8933 "ErrorCode,Failed to set OM ctrl supp");
8934 return 0;
8935 }
8936 }
8937
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -07008938 val = get_param(cmd, "ADDBAResp_BufSize");
8939 if (val) {
8940 int buf_size;
8941
8942 if (strcasecmp(val, "gt64") == 0)
8943 buf_size = 256;
8944 else
8945 buf_size = 64;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02008946 if (get_driver_type(dut) == DRIVER_WCN &&
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -07008947 sta_set_addba_buf_size(dut, intf, buf_size)) {
8948 send_resp(dut, conn, SIGMA_ERROR,
8949 "ErrorCode,set addbaresp_buff_size failed");
8950 return 0;
8951 }
8952 }
8953
8954 val = get_param(cmd, "ADDBAReq_BufSize");
8955 if (val) {
8956 int buf_size;
8957
8958 if (strcasecmp(val, "gt64") == 0)
8959 buf_size = 256;
8960 else
8961 buf_size = 64;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02008962 if (get_driver_type(dut) == DRIVER_WCN &&
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -07008963 sta_set_addba_buf_size(dut, intf, buf_size)) {
8964 send_resp(dut, conn, SIGMA_ERROR,
8965 "ErrorCode,set addbareq_buff_size failed");
8966 return 0;
8967 }
8968 }
8969
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008970 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
8971}
8972
8973
8974static int sta_set_wireless_60g(struct sigma_dut *dut,
8975 struct sigma_conn *conn,
8976 struct sigma_cmd *cmd)
8977{
8978 const char *dev_role = get_param(cmd, "DevRole");
8979
8980 if (!dev_role) {
8981 send_resp(dut, conn, SIGMA_INVALID,
8982 "ErrorCode,DevRole not specified");
8983 return 0;
8984 }
8985
8986 if (strcasecmp(dev_role, "PCP") == 0)
8987 return sta_set_60g_pcp(dut, conn, cmd);
8988 if (strcasecmp(dev_role, "STA") == 0)
8989 return sta_set_60g_sta(dut, conn, cmd);
8990 send_resp(dut, conn, SIGMA_INVALID,
8991 "ErrorCode,DevRole not supported");
8992 return 0;
8993}
8994
8995
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05308996static int sta_set_wireless_oce(struct sigma_dut *dut, struct sigma_conn *conn,
8997 struct sigma_cmd *cmd)
8998{
8999 int status;
9000 const char *intf = get_param(cmd, "Interface");
9001 const char *val = get_param(cmd, "DevRole");
9002
9003 if (val && strcasecmp(val, "STA-CFON") == 0) {
9004 status = sta_cfon_set_wireless(dut, conn, cmd);
9005 if (status)
9006 return status;
9007 }
9008 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
9009}
9010
9011
Jouni Malinenf7222712019-06-13 01:50:21 +03009012static enum sigma_cmd_result cmd_sta_set_wireless(struct sigma_dut *dut,
9013 struct sigma_conn *conn,
9014 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009015{
9016 const char *val;
9017
9018 val = get_param(cmd, "Program");
9019 if (val) {
9020 if (strcasecmp(val, "11n") == 0)
9021 return cmd_sta_set_11n(dut, conn, cmd);
Amarnath Hullur Subramanyam4f860292018-01-31 03:49:35 -08009022 if (strcasecmp(val, "VHT") == 0 || strcasecmp(val, "HE") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009023 return cmd_sta_set_wireless_vht(dut, conn, cmd);
9024 if (strcasecmp(val, "60ghz") == 0)
9025 return sta_set_wireless_60g(dut, conn, cmd);
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05309026 if (strcasecmp(val, "OCE") == 0)
9027 return sta_set_wireless_oce(dut, conn, cmd);
Alexei Avshalom Lazar66bb9972018-12-18 16:01:43 +02009028 /* sta_set_wireless in WPS program is only used for 60G */
9029 if (is_60g_sigma_dut(dut))
9030 return sta_set_wireless_60g(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009031 send_resp(dut, conn, SIGMA_ERROR,
9032 "ErrorCode,Program value not supported");
9033 } else {
9034 send_resp(dut, conn, SIGMA_ERROR,
9035 "ErrorCode,Program argument not available");
9036 }
9037
9038 return 0;
9039}
9040
9041
9042static void ath_sta_inject_frame(struct sigma_dut *dut, const char *intf,
9043 int tid)
9044{
9045 char buf[100];
9046 int tid_to_dscp [] = { 0x00, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0 };
9047
Pradeep Reddy POTTETId31d1322016-10-13 17:22:03 +05309048 if (tid < 0 ||
9049 tid >= (int) (sizeof(tid_to_dscp) / sizeof(tid_to_dscp[0]))) {
9050 sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported TID: %d", tid);
9051 return;
9052 }
9053
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009054 /*
9055 * Two ways to ensure that addba request with a
9056 * non zero TID could be sent out. EV 117296
9057 */
9058 snprintf(buf, sizeof(buf),
9059 "ping -c 8 -Q %d `arp -a | grep wlan0 | awk '{print $2}' | tr -d '()'`",
9060 tid);
9061 if (system(buf) != 0) {
9062 sigma_dut_print(dut, DUT_MSG_ERROR,
9063 "Ping did not send out");
9064 }
9065
9066 snprintf(buf, sizeof(buf),
9067 "iwconfig %s | grep Access | awk '{print $6}' > %s",
9068 intf, VI_QOS_TMP_FILE);
9069 if (system(buf) != 0)
9070 return;
9071
9072 snprintf(buf, sizeof(buf),
9073 "ifconfig %s | grep HWaddr | cut -b 39-56 >> %s",
9074 intf, VI_QOS_TMP_FILE);
9075 if (system(buf) != 0)
9076 sigma_dut_print(dut, DUT_MSG_ERROR, "HWaddr matching failed");
9077
9078 snprintf(buf,sizeof(buf), "sed -n '3,$p' %s >> %s",
9079 VI_QOS_REFFILE, VI_QOS_TMP_FILE);
9080 if (system(buf) != 0) {
9081 sigma_dut_print(dut, DUT_MSG_ERROR,
9082 "VI_QOS_TEMP_FILE generation error failed");
9083 }
9084 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
9085 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
9086 if (system(buf) != 0) {
9087 sigma_dut_print(dut, DUT_MSG_ERROR,
9088 "VI_QOS_FILE generation failed");
9089 }
9090
9091 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
9092 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
9093 if (system(buf) != 0) {
9094 sigma_dut_print(dut, DUT_MSG_ERROR,
9095 "VI_QOS_FILE generation failed");
9096 }
9097
9098 snprintf(buf, sizeof(buf), "ethinject %s %s", intf, VI_QOS_FILE);
9099 if (system(buf) != 0) {
9100 }
9101}
9102
9103
9104static int ath_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
9105 struct sigma_cmd *cmd)
9106{
9107 const char *intf = get_param(cmd, "Interface");
9108 const char *val;
9109 int tid = 0;
9110 char buf[100];
9111
9112 val = get_param(cmd, "TID");
9113 if (val) {
9114 tid = atoi(val);
9115 if (tid)
9116 ath_sta_inject_frame(dut, intf, tid);
9117 }
9118
9119 /* Command sequence for ADDBA request on Peregrine based devices */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07009120 run_iwpriv(dut, intf, "setaddbaoper 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009121
9122 snprintf(buf, sizeof(buf), "wifitool %s senddelba 1 %d 1 4", intf, tid);
9123 if (system(buf) != 0) {
9124 sigma_dut_print(dut, DUT_MSG_ERROR,
9125 "wifitool senddelba failed");
9126 }
9127
9128 snprintf(buf, sizeof(buf), "wifitool %s sendaddba 1 %d 64", intf, tid);
9129 if (system(buf) != 0) {
9130 sigma_dut_print(dut, DUT_MSG_ERROR,
9131 "wifitool sendaddba failed");
9132 }
9133
9134 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
9135
9136 return 1;
9137}
9138
9139
Lior David9981b512017-01-20 13:16:40 +02009140#ifdef __linux__
9141
9142static int wil6210_send_addba(struct sigma_dut *dut, const char *dest_mac,
9143 int agg_size)
9144{
9145 char dir[128], buf[128];
9146 FILE *f;
9147 regex_t re;
9148 regmatch_t m[2];
Jouni Malinen3aa72862019-05-29 23:14:51 +03009149 int rc, ret = -1, vring_id, found, res;
Lior David9981b512017-01-20 13:16:40 +02009150
9151 if (wil6210_get_debugfs_dir(dut, dir, sizeof(dir))) {
9152 sigma_dut_print(dut, DUT_MSG_ERROR,
9153 "failed to get wil6210 debugfs dir");
9154 return -1;
9155 }
9156
Jouni Malinen3aa72862019-05-29 23:14:51 +03009157 res = snprintf(buf, sizeof(buf), "%s/vrings", dir);
9158 if (res < 0 || res >= sizeof(buf))
9159 return -1;
Lior David9981b512017-01-20 13:16:40 +02009160 f = fopen(buf, "r");
9161 if (!f) {
9162 sigma_dut_print(dut, DUT_MSG_ERROR, "failed to open: %s", buf);
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +02009163 /* newer wil6210 driver renamed file to "rings" */
Jouni Malinen3aa72862019-05-29 23:14:51 +03009164 res = snprintf(buf, sizeof(buf), "%s/rings", dir);
9165 if (res < 0 || res >= sizeof(buf))
9166 return -1;
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +02009167 f = fopen(buf, "r");
9168 if (!f) {
9169 sigma_dut_print(dut, DUT_MSG_ERROR,
9170 "failed to open: %s", buf);
9171 return -1;
9172 }
Lior David9981b512017-01-20 13:16:40 +02009173 }
9174
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +02009175 /* can be either VRING tx... or RING... */
9176 if (regcomp(&re, "RING tx_[ \t]*([0-9]+)", REG_EXTENDED)) {
Lior David9981b512017-01-20 13:16:40 +02009177 sigma_dut_print(dut, DUT_MSG_ERROR, "regcomp failed");
9178 goto out;
9179 }
9180
9181 /* find TX VRING for the mac address */
9182 found = 0;
9183 while (fgets(buf, sizeof(buf), f)) {
9184 if (strcasestr(buf, dest_mac)) {
9185 found = 1;
9186 break;
9187 }
9188 }
9189
9190 if (!found) {
9191 sigma_dut_print(dut, DUT_MSG_ERROR,
9192 "no TX VRING for %s", dest_mac);
9193 goto out;
9194 }
9195
9196 /* extract VRING ID, "VRING tx_<id> = {" */
9197 if (!fgets(buf, sizeof(buf), f)) {
9198 sigma_dut_print(dut, DUT_MSG_ERROR,
9199 "no VRING start line for %s", dest_mac);
9200 goto out;
9201 }
9202
9203 rc = regexec(&re, buf, 2, m, 0);
9204 regfree(&re);
9205 if (rc || m[1].rm_so < 0) {
9206 sigma_dut_print(dut, DUT_MSG_ERROR,
9207 "no VRING TX ID for %s", dest_mac);
9208 goto out;
9209 }
9210 buf[m[1].rm_eo] = 0;
9211 vring_id = atoi(&buf[m[1].rm_so]);
9212
9213 /* send the addba command */
9214 fclose(f);
Jouni Malinen3aa72862019-05-29 23:14:51 +03009215 res = snprintf(buf, sizeof(buf), "%s/back", dir);
9216 if (res < 0 || res >= sizeof(buf))
9217 return -1;
Lior David9981b512017-01-20 13:16:40 +02009218 f = fopen(buf, "w");
9219 if (!f) {
9220 sigma_dut_print(dut, DUT_MSG_ERROR,
9221 "failed to open: %s", buf);
9222 return -1;
9223 }
9224
9225 fprintf(f, "add %d %d\n", vring_id, agg_size);
9226
9227 ret = 0;
9228
9229out:
9230 fclose(f);
9231
9232 return ret;
9233}
9234
9235
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +02009236int send_addba_60g(struct sigma_dut *dut, struct sigma_conn *conn,
9237 struct sigma_cmd *cmd, const char *mac_param)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009238{
9239 const char *val;
9240 int tid = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009241
9242 val = get_param(cmd, "TID");
9243 if (val) {
9244 tid = atoi(val);
9245 if (tid != 0) {
9246 sigma_dut_print(dut, DUT_MSG_ERROR,
9247 "Ignore TID %d for send_addba use TID 0 for 60g since only 0 required on TX",
9248 tid);
9249 }
9250 }
9251
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +02009252 val = get_param(cmd, mac_param);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009253 if (!val) {
9254 sigma_dut_print(dut, DUT_MSG_ERROR,
9255 "Currently not supporting addba for 60G without Dest_mac");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02009256 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009257 }
9258
Lior David9981b512017-01-20 13:16:40 +02009259 if (wil6210_send_addba(dut, val, dut->back_rcv_buf))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009260 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009261
9262 return 1;
9263}
9264
Lior David9981b512017-01-20 13:16:40 +02009265#endif /* __linux__ */
9266
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009267
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009268static int wcn_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
9269 struct sigma_cmd *cmd)
9270{
9271#ifdef NL80211_SUPPORT
9272 const char *intf = get_param(cmd, "Interface");
9273 const char *val;
9274 int tid = -1;
9275 int bufsize = 64;
9276 struct nl_msg *msg;
9277 int ret = 0;
9278 struct nlattr *params;
9279 int ifindex;
9280
9281 val = get_param(cmd, "TID");
9282 if (val)
9283 tid = atoi(val);
9284
9285 if (tid == -1) {
9286 send_resp(dut, conn, SIGMA_ERROR,
9287 "ErrorCode,sta_send_addba tid invalid");
9288 return 0;
9289 }
9290
9291 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
9292
9293 ifindex = if_nametoindex(intf);
9294 if (ifindex == 0) {
9295 sigma_dut_print(dut, DUT_MSG_ERROR,
9296 "%s: Index for interface %s failed",
9297 __func__, intf);
9298 send_resp(dut, conn, SIGMA_ERROR,
9299 "ErrorCode,sta_send_addba interface invalid");
9300 return 0;
9301 }
9302
9303 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
9304 NL80211_CMD_VENDOR)) ||
9305 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
9306 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
9307 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
9308 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
9309 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
9310 nla_put_u8(msg,
9311 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADD_DEL_BA_SESSION,
9312 QCA_WLAN_ADD_BA) ||
9313 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BA_TID,
9314 tid) ||
Kiran Kumar Lokere26e27582018-08-01 16:18:34 -07009315 nla_put_u16(msg,
9316 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE,
9317 bufsize)) {
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009318 sigma_dut_print(dut, DUT_MSG_ERROR,
9319 "%s: err in adding vendor_cmd and vendor_data",
9320 __func__);
9321 nlmsg_free(msg);
9322 send_resp(dut, conn, SIGMA_ERROR,
9323 "ErrorCode,sta_send_addba err in adding vendor_cmd and vendor_data");
9324 return 0;
9325 }
9326 nla_nest_end(msg, params);
9327
9328 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
9329 if (ret) {
9330 sigma_dut_print(dut, DUT_MSG_ERROR,
9331 "%s: err in send_and_recv_msgs, ret=%d",
9332 __func__, ret);
Sunil Dutt30605592018-05-04 20:35:50 +05309333 if (ret == -EOPNOTSUPP)
9334 return 1;
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009335 send_resp(dut, conn, SIGMA_ERROR,
9336 "ErrorCode,sta_send_addba err in send_and_recv_msgs");
9337 return 0;
9338 }
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009339#else /* NL80211_SUPPORT */
9340 sigma_dut_print(dut, DUT_MSG_ERROR,
9341 "sta_send_addba not supported without NL80211_SUPPORT defined");
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009342#endif /* NL80211_SUPPORT */
Sunil Dutt30605592018-05-04 20:35:50 +05309343
9344 return 1;
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009345}
9346
9347
Jouni Malinenf7222712019-06-13 01:50:21 +03009348static enum sigma_cmd_result cmd_sta_send_addba(struct sigma_dut *dut,
9349 struct sigma_conn *conn,
9350 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009351{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009352 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009353 case DRIVER_ATHEROS:
9354 return ath_sta_send_addba(dut, conn, cmd);
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009355 case DRIVER_WCN:
9356 return wcn_sta_send_addba(dut, conn, cmd);
Lior David9981b512017-01-20 13:16:40 +02009357#ifdef __linux__
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009358 case DRIVER_WIL6210:
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +02009359 return send_addba_60g(dut, conn, cmd, "Dest_mac");
Lior David9981b512017-01-20 13:16:40 +02009360#endif /* __linux__ */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009361 default:
9362 /*
9363 * There is no driver specific implementation for other drivers.
9364 * Ignore the command and report COMPLETE since the following
9365 * throughput test operation will end up sending ADDBA anyway.
9366 */
9367 return 1;
9368 }
9369}
9370
9371
9372int inject_eth_frame(int s, const void *data, size_t len,
9373 unsigned short ethtype, char *dst, char *src)
9374{
9375 struct iovec iov[4] = {
9376 {
9377 .iov_base = dst,
9378 .iov_len = ETH_ALEN,
9379 },
9380 {
9381 .iov_base = src,
9382 .iov_len = ETH_ALEN,
9383 },
9384 {
9385 .iov_base = &ethtype,
9386 .iov_len = sizeof(unsigned short),
9387 },
9388 {
9389 .iov_base = (void *) data,
9390 .iov_len = len,
9391 }
9392 };
9393 struct msghdr msg = {
9394 .msg_name = NULL,
9395 .msg_namelen = 0,
9396 .msg_iov = iov,
9397 .msg_iovlen = 4,
9398 .msg_control = NULL,
9399 .msg_controllen = 0,
9400 .msg_flags = 0,
9401 };
9402
9403 return sendmsg(s, &msg, 0);
9404}
9405
9406#if defined(__linux__) || defined(__QNXNTO__)
9407
9408int inject_frame(int s, const void *data, size_t len, int encrypt)
9409{
9410#define IEEE80211_RADIOTAP_F_WEP 0x04
9411#define IEEE80211_RADIOTAP_F_FRAG 0x08
9412 unsigned char rtap_hdr[] = {
9413 0x00, 0x00, /* radiotap version */
9414 0x0e, 0x00, /* radiotap length */
9415 0x02, 0xc0, 0x00, 0x00, /* bmap: flags, tx and rx flags */
9416 IEEE80211_RADIOTAP_F_FRAG, /* F_FRAG (fragment if required) */
9417 0x00, /* padding */
9418 0x00, 0x00, /* RX and TX flags to indicate that */
9419 0x00, 0x00, /* this is the injected frame directly */
9420 };
9421 struct iovec iov[2] = {
9422 {
9423 .iov_base = &rtap_hdr,
9424 .iov_len = sizeof(rtap_hdr),
9425 },
9426 {
9427 .iov_base = (void *) data,
9428 .iov_len = len,
9429 }
9430 };
9431 struct msghdr msg = {
9432 .msg_name = NULL,
9433 .msg_namelen = 0,
9434 .msg_iov = iov,
9435 .msg_iovlen = 2,
9436 .msg_control = NULL,
9437 .msg_controllen = 0,
9438 .msg_flags = 0,
9439 };
9440
9441 if (encrypt)
9442 rtap_hdr[8] |= IEEE80211_RADIOTAP_F_WEP;
9443
9444 return sendmsg(s, &msg, 0);
9445}
9446
9447
9448int open_monitor(const char *ifname)
9449{
9450#ifdef __QNXNTO__
9451 struct sockaddr_dl ll;
9452 int s;
9453
9454 memset(&ll, 0, sizeof(ll));
9455 ll.sdl_family = AF_LINK;
9456 ll.sdl_index = if_nametoindex(ifname);
9457 if (ll.sdl_index == 0) {
9458 perror("if_nametoindex");
9459 return -1;
9460 }
9461 s = socket(PF_INET, SOCK_RAW, 0);
9462#else /* __QNXNTO__ */
9463 struct sockaddr_ll ll;
9464 int s;
9465
9466 memset(&ll, 0, sizeof(ll));
9467 ll.sll_family = AF_PACKET;
9468 ll.sll_ifindex = if_nametoindex(ifname);
9469 if (ll.sll_ifindex == 0) {
9470 perror("if_nametoindex");
9471 return -1;
9472 }
9473 s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
9474#endif /* __QNXNTO__ */
9475 if (s < 0) {
9476 perror("socket[PF_PACKET,SOCK_RAW]");
9477 return -1;
9478 }
9479
9480 if (bind(s, (struct sockaddr *) &ll, sizeof(ll)) < 0) {
9481 perror("monitor socket bind");
9482 close(s);
9483 return -1;
9484 }
9485
9486 return s;
9487}
9488
9489
9490static int hex2num(char c)
9491{
9492 if (c >= '0' && c <= '9')
9493 return c - '0';
9494 if (c >= 'a' && c <= 'f')
9495 return c - 'a' + 10;
9496 if (c >= 'A' && c <= 'F')
9497 return c - 'A' + 10;
9498 return -1;
9499}
9500
9501
9502int hwaddr_aton(const char *txt, unsigned char *addr)
9503{
9504 int i;
9505
9506 for (i = 0; i < 6; i++) {
9507 int a, b;
9508
9509 a = hex2num(*txt++);
9510 if (a < 0)
9511 return -1;
9512 b = hex2num(*txt++);
9513 if (b < 0)
9514 return -1;
9515 *addr++ = (a << 4) | b;
9516 if (i < 5 && *txt++ != ':')
9517 return -1;
9518 }
9519
9520 return 0;
9521}
9522
9523#endif /* defined(__linux__) || defined(__QNXNTO__) */
9524
9525enum send_frame_type {
9526 DISASSOC, DEAUTH, SAQUERY, AUTH, ASSOCREQ, REASSOCREQ, DLS_REQ
9527};
9528enum send_frame_protection {
9529 CORRECT_KEY, INCORRECT_KEY, UNPROTECTED
9530};
9531
9532
9533static int sta_inject_frame(struct sigma_dut *dut, struct sigma_conn *conn,
9534 enum send_frame_type frame,
9535 enum send_frame_protection protected,
9536 const char *dest)
9537{
9538#ifdef __linux__
9539 unsigned char buf[1000], *pos;
9540 int s, res;
9541 char bssid[20], addr[20];
9542 char result[32], ssid[100];
9543 size_t ssid_len;
9544
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009545 if (get_wpa_status(get_station_ifname(dut), "wpa_state", result,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009546 sizeof(result)) < 0 ||
9547 strncmp(result, "COMPLETED", 9) != 0) {
9548 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Not connected");
9549 return 0;
9550 }
9551
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009552 if (get_wpa_status(get_station_ifname(dut), "bssid",
9553 bssid, sizeof(bssid)) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009554 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
9555 "current BSSID");
9556 return 0;
9557 }
9558
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009559 if (get_wpa_status(get_station_ifname(dut), "address",
9560 addr, sizeof(addr)) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009561 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
9562 "own MAC address");
9563 return 0;
9564 }
9565
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009566 if (get_wpa_status(get_station_ifname(dut), "ssid", ssid, sizeof(ssid))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009567 < 0) {
9568 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
9569 "current SSID");
9570 return 0;
9571 }
9572 ssid_len = strlen(ssid);
9573
9574 pos = buf;
9575
9576 /* Frame Control */
9577 switch (frame) {
9578 case DISASSOC:
9579 *pos++ = 0xa0;
9580 break;
9581 case DEAUTH:
9582 *pos++ = 0xc0;
9583 break;
9584 case SAQUERY:
9585 *pos++ = 0xd0;
9586 break;
9587 case AUTH:
9588 *pos++ = 0xb0;
9589 break;
9590 case ASSOCREQ:
9591 *pos++ = 0x00;
9592 break;
9593 case REASSOCREQ:
9594 *pos++ = 0x20;
9595 break;
9596 case DLS_REQ:
9597 *pos++ = 0xd0;
9598 break;
9599 }
9600
9601 if (protected == INCORRECT_KEY)
9602 *pos++ = 0x40; /* Set Protected field to 1 */
9603 else
9604 *pos++ = 0x00;
9605
9606 /* Duration */
9607 *pos++ = 0x00;
9608 *pos++ = 0x00;
9609
9610 /* addr1 = DA (current AP) */
9611 hwaddr_aton(bssid, pos);
9612 pos += 6;
9613 /* addr2 = SA (own address) */
9614 hwaddr_aton(addr, pos);
9615 pos += 6;
9616 /* addr3 = BSSID (current AP) */
9617 hwaddr_aton(bssid, pos);
9618 pos += 6;
9619
9620 /* Seq# (to be filled by driver/mac80211) */
9621 *pos++ = 0x00;
9622 *pos++ = 0x00;
9623
9624 if (protected == INCORRECT_KEY) {
9625 /* CCMP parameters */
9626 memcpy(pos, "\x61\x01\x00\x20\x00\x10\x00\x00", 8);
9627 pos += 8;
9628 }
9629
9630 if (protected == INCORRECT_KEY) {
9631 switch (frame) {
9632 case DEAUTH:
9633 /* Reason code (encrypted) */
9634 memcpy(pos, "\xa7\x39", 2);
9635 pos += 2;
9636 break;
9637 case DISASSOC:
9638 /* Reason code (encrypted) */
9639 memcpy(pos, "\xa7\x39", 2);
9640 pos += 2;
9641 break;
9642 case SAQUERY:
9643 /* Category|Action|TransID (encrypted) */
9644 memcpy(pos, "\x6f\xbd\xe9\x4d", 4);
9645 pos += 4;
9646 break;
9647 default:
9648 return -1;
9649 }
9650
9651 /* CCMP MIC */
9652 memcpy(pos, "\xc8\xd8\x3b\x06\x5d\xb7\x25\x68", 8);
9653 pos += 8;
9654 } else {
9655 switch (frame) {
9656 case DEAUTH:
9657 /* reason code = 8 */
9658 *pos++ = 0x08;
9659 *pos++ = 0x00;
9660 break;
9661 case DISASSOC:
9662 /* reason code = 8 */
9663 *pos++ = 0x08;
9664 *pos++ = 0x00;
9665 break;
9666 case SAQUERY:
9667 /* Category - SA Query */
9668 *pos++ = 0x08;
9669 /* SA query Action - Request */
9670 *pos++ = 0x00;
9671 /* Transaction ID */
9672 *pos++ = 0x12;
9673 *pos++ = 0x34;
9674 break;
9675 case AUTH:
9676 /* Auth Alg (Open) */
9677 *pos++ = 0x00;
9678 *pos++ = 0x00;
9679 /* Seq# */
9680 *pos++ = 0x01;
9681 *pos++ = 0x00;
9682 /* Status code */
9683 *pos++ = 0x00;
9684 *pos++ = 0x00;
9685 break;
9686 case ASSOCREQ:
9687 /* Capability Information */
9688 *pos++ = 0x31;
9689 *pos++ = 0x04;
9690 /* Listen Interval */
9691 *pos++ = 0x0a;
9692 *pos++ = 0x00;
9693 /* SSID */
9694 *pos++ = 0x00;
9695 *pos++ = ssid_len;
9696 memcpy(pos, ssid, ssid_len);
9697 pos += ssid_len;
9698 /* Supported Rates */
9699 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
9700 10);
9701 pos += 10;
9702 /* Extended Supported Rates */
9703 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
9704 pos += 6;
9705 /* RSN */
9706 memcpy(pos, "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00"
9707 "\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x02\xc0"
9708 "\x00\x00\x00\x00\x0f\xac\x06", 28);
9709 pos += 28;
9710 break;
9711 case REASSOCREQ:
9712 /* Capability Information */
9713 *pos++ = 0x31;
9714 *pos++ = 0x04;
9715 /* Listen Interval */
9716 *pos++ = 0x0a;
9717 *pos++ = 0x00;
9718 /* Current AP */
9719 hwaddr_aton(bssid, pos);
9720 pos += 6;
9721 /* SSID */
9722 *pos++ = 0x00;
9723 *pos++ = ssid_len;
9724 memcpy(pos, ssid, ssid_len);
9725 pos += ssid_len;
9726 /* Supported Rates */
9727 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
9728 10);
9729 pos += 10;
9730 /* Extended Supported Rates */
9731 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
9732 pos += 6;
9733 /* RSN */
9734 memcpy(pos, "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00"
9735 "\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x02\xc0"
9736 "\x00\x00\x00\x00\x0f\xac\x06", 28);
9737 pos += 28;
9738 break;
9739 case DLS_REQ:
9740 /* Category - DLS */
9741 *pos++ = 0x02;
9742 /* DLS Action - Request */
9743 *pos++ = 0x00;
9744 /* Destination MACAddress */
9745 if (dest)
9746 hwaddr_aton(dest, pos);
9747 else
9748 memset(pos, 0, 6);
9749 pos += 6;
9750 /* Source MACAddress */
9751 hwaddr_aton(addr, pos);
9752 pos += 6;
9753 /* Capability Information */
9754 *pos++ = 0x10; /* Privacy */
9755 *pos++ = 0x06; /* QoS */
9756 /* DLS Timeout Value */
9757 *pos++ = 0x00;
9758 *pos++ = 0x01;
9759 /* Supported rates */
9760 *pos++ = 0x01;
9761 *pos++ = 0x08;
9762 *pos++ = 0x0c; /* 6 Mbps */
9763 *pos++ = 0x12; /* 9 Mbps */
9764 *pos++ = 0x18; /* 12 Mbps */
9765 *pos++ = 0x24; /* 18 Mbps */
9766 *pos++ = 0x30; /* 24 Mbps */
9767 *pos++ = 0x48; /* 36 Mbps */
9768 *pos++ = 0x60; /* 48 Mbps */
9769 *pos++ = 0x6c; /* 54 Mbps */
9770 /* TODO: Extended Supported Rates */
9771 /* TODO: HT Capabilities */
9772 break;
9773 }
9774 }
9775
9776 s = open_monitor("sigmadut");
9777 if (s < 0) {
9778 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
9779 "monitor socket");
9780 return 0;
9781 }
9782
9783 res = inject_frame(s, buf, pos - buf, protected == CORRECT_KEY);
9784 if (res < 0) {
9785 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
9786 "inject frame");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05309787 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009788 return 0;
9789 }
9790 if (res < pos - buf) {
9791 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Only partial "
9792 "frame sent");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05309793 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009794 return 0;
9795 }
9796
9797 close(s);
9798
9799 return 1;
9800#else /* __linux__ */
9801 send_resp(dut, conn, SIGMA_ERROR, "errorCode,sta_send_frame not "
9802 "yet supported");
9803 return 0;
9804#endif /* __linux__ */
9805}
9806
9807
9808static int cmd_sta_send_frame_tdls(struct sigma_dut *dut,
9809 struct sigma_conn *conn,
9810 struct sigma_cmd *cmd)
9811{
9812 const char *intf = get_param(cmd, "Interface");
9813 const char *sta, *val;
9814 unsigned char addr[ETH_ALEN];
9815 char buf[100];
9816
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +03009817 if (!intf)
9818 return -1;
9819
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009820 sta = get_param(cmd, "peer");
9821 if (sta == NULL)
9822 sta = get_param(cmd, "station");
9823 if (sta == NULL) {
9824 send_resp(dut, conn, SIGMA_ERROR,
9825 "ErrorCode,Missing peer address");
9826 return 0;
9827 }
9828 if (hwaddr_aton(sta, addr) < 0) {
9829 send_resp(dut, conn, SIGMA_ERROR,
9830 "ErrorCode,Invalid peer address");
9831 return 0;
9832 }
9833
9834 val = get_param(cmd, "type");
9835 if (val == NULL)
9836 return -1;
9837
9838 if (strcasecmp(val, "DISCOVERY") == 0) {
9839 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", sta);
9840 if (wpa_command(intf, buf) < 0) {
9841 send_resp(dut, conn, SIGMA_ERROR,
9842 "ErrorCode,Failed to send TDLS discovery");
9843 return 0;
9844 }
9845 return 1;
9846 }
9847
9848 if (strcasecmp(val, "SETUP") == 0) {
9849 int status = 0, timeout = 0;
9850
9851 val = get_param(cmd, "Status");
9852 if (val)
9853 status = atoi(val);
9854
9855 val = get_param(cmd, "Timeout");
9856 if (val)
9857 timeout = atoi(val);
9858
9859 if (status != 0 && status != 37) {
9860 send_resp(dut, conn, SIGMA_ERROR,
9861 "ErrorCode,Unsupported status value");
9862 return 0;
9863 }
9864
9865 if (timeout != 0 && timeout != 301) {
9866 send_resp(dut, conn, SIGMA_ERROR,
9867 "ErrorCode,Unsupported timeout value");
9868 return 0;
9869 }
9870
9871 if (status && timeout) {
9872 send_resp(dut, conn, SIGMA_ERROR,
9873 "ErrorCode,Unsupported timeout+status "
9874 "combination");
9875 return 0;
9876 }
9877
9878 if (status == 37 &&
9879 wpa_command(intf, "SET tdls_testing 0x200")) {
9880 send_resp(dut, conn, SIGMA_ERROR,
9881 "ErrorCode,Failed to enable "
9882 "decline setup response test mode");
9883 return 0;
9884 }
9885
9886 if (timeout == 301) {
9887 int res;
9888 if (dut->no_tpk_expiration)
9889 res = wpa_command(intf,
9890 "SET tdls_testing 0x108");
9891 else
9892 res = wpa_command(intf,
9893 "SET tdls_testing 0x8");
9894 if (res) {
9895 send_resp(dut, conn, SIGMA_ERROR,
9896 "ErrorCode,Failed to set short TPK "
9897 "lifetime");
9898 return 0;
9899 }
9900 }
9901
9902 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", sta);
9903 if (wpa_command(intf, buf) < 0) {
9904 send_resp(dut, conn, SIGMA_ERROR,
9905 "ErrorCode,Failed to send TDLS setup");
9906 return 0;
9907 }
9908 return 1;
9909 }
9910
9911 if (strcasecmp(val, "TEARDOWN") == 0) {
9912 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", sta);
9913 if (wpa_command(intf, buf) < 0) {
9914 send_resp(dut, conn, SIGMA_ERROR,
9915 "ErrorCode,Failed to send TDLS teardown");
9916 return 0;
9917 }
9918 return 1;
9919 }
9920
9921 send_resp(dut, conn, SIGMA_ERROR,
9922 "ErrorCode,Unsupported TDLS frame");
9923 return 0;
9924}
9925
9926
9927static int sta_ap_known(const char *ifname, const char *bssid)
9928{
9929 char buf[4096];
9930
Jouni Malinendd32f192018-09-15 02:55:19 +03009931 snprintf(buf, sizeof(buf), "BSS MASK=1 %s", bssid);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009932 if (wpa_command_resp(ifname, buf, buf, sizeof(buf)) < 0)
9933 return 0;
9934 if (strncmp(buf, "id=", 3) != 0)
9935 return 0;
9936 return 1;
9937}
9938
9939
9940static int sta_scan_ap(struct sigma_dut *dut, const char *ifname,
9941 const char *bssid)
9942{
9943 int res;
9944 struct wpa_ctrl *ctrl;
9945 char buf[256];
9946
9947 if (sta_ap_known(ifname, bssid))
9948 return 0;
9949 sigma_dut_print(dut, DUT_MSG_DEBUG,
9950 "AP not in BSS table - start scan");
9951
9952 ctrl = open_wpa_mon(ifname);
9953 if (ctrl == NULL) {
9954 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
9955 "wpa_supplicant monitor connection");
9956 return -1;
9957 }
9958
9959 if (wpa_command(ifname, "SCAN") < 0) {
9960 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to start scan");
9961 wpa_ctrl_detach(ctrl);
9962 wpa_ctrl_close(ctrl);
9963 return -1;
9964 }
9965
9966 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
9967 buf, sizeof(buf));
9968
9969 wpa_ctrl_detach(ctrl);
9970 wpa_ctrl_close(ctrl);
9971
9972 if (res < 0) {
9973 sigma_dut_print(dut, DUT_MSG_INFO, "Scan did not complete");
9974 return -1;
9975 }
9976
9977 if (sta_ap_known(ifname, bssid))
9978 return 0;
9979 sigma_dut_print(dut, DUT_MSG_INFO, "AP not in BSS table");
9980 return -1;
9981}
9982
9983
9984static int cmd_sta_send_frame_hs2_neighadv(struct sigma_dut *dut,
9985 struct sigma_conn *conn,
9986 struct sigma_cmd *cmd,
9987 const char *intf)
9988{
9989 char buf[200];
9990
9991 snprintf(buf, sizeof(buf), "ndsend 2001:DB8::1 %s", intf);
9992 if (system(buf) != 0) {
9993 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Failed to run "
9994 "ndsend");
9995 return 0;
9996 }
9997
9998 return 1;
9999}
10000
10001
10002static int cmd_sta_send_frame_hs2_neighsolreq(struct sigma_dut *dut,
10003 struct sigma_conn *conn,
10004 struct sigma_cmd *cmd,
10005 const char *intf)
10006{
10007 char buf[200];
10008 const char *ip = get_param(cmd, "SenderIP");
10009
Peng Xu26b356d2017-10-04 17:58:16 -070010010 if (!ip)
10011 return 0;
10012
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010013 snprintf(buf, sizeof(buf), "ndisc6 -nm %s %s -r 4", ip, intf);
10014 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10015 if (system(buf) == 0) {
10016 sigma_dut_print(dut, DUT_MSG_INFO,
10017 "Neighbor Solicitation got a response "
10018 "for %s@%s", ip, intf);
10019 }
10020
10021 return 1;
10022}
10023
10024
10025static int cmd_sta_send_frame_hs2_arpprobe(struct sigma_dut *dut,
10026 struct sigma_conn *conn,
10027 struct sigma_cmd *cmd,
10028 const char *ifname)
10029{
10030 char buf[200];
10031 const char *ip = get_param(cmd, "SenderIP");
10032
10033 if (ip == NULL) {
10034 send_resp(dut, conn, SIGMA_ERROR,
10035 "ErrorCode,Missing SenderIP parameter");
10036 return 0;
10037 }
10038 snprintf(buf, sizeof(buf), "arping -I %s -D %s -c 4", ifname, ip);
10039 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10040 if (system(buf) != 0) {
10041 sigma_dut_print(dut, DUT_MSG_INFO, "arping DAD got a response "
10042 "for %s@%s", ip, ifname);
10043 }
10044
10045 return 1;
10046}
10047
10048
10049static int cmd_sta_send_frame_hs2_arpannounce(struct sigma_dut *dut,
10050 struct sigma_conn *conn,
10051 struct sigma_cmd *cmd,
10052 const char *ifname)
10053{
10054 char buf[200];
10055 char ip[16];
10056 int s;
Peng Xub3756882017-10-04 14:39:09 -070010057 struct ifreq ifr;
10058 struct sockaddr_in saddr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010059
10060 s = socket(PF_INET, SOCK_DGRAM, 0);
Peng Xub3756882017-10-04 14:39:09 -070010061 if (s < 0) {
10062 perror("socket");
10063 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010064 }
10065
Peng Xub3756882017-10-04 14:39:09 -070010066 memset(&ifr, 0, sizeof(ifr));
10067 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
10068 if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
10069 sigma_dut_print(dut, DUT_MSG_INFO,
10070 "Failed to get %s IP address: %s",
10071 ifname, strerror(errno));
10072 close(s);
10073 return -1;
10074 }
10075 close(s);
10076
10077 memcpy(&saddr, &ifr.ifr_addr, sizeof(struct sockaddr_in));
10078 strlcpy(ip, inet_ntoa(saddr.sin_addr), sizeof(ip));
10079
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010080 snprintf(buf, sizeof(buf), "arping -I %s -s %s %s -c 4", ifname, ip,
10081 ip);
10082 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10083 if (system(buf) != 0) {
10084 }
10085
10086 return 1;
10087}
10088
10089
10090static int cmd_sta_send_frame_hs2_arpreply(struct sigma_dut *dut,
10091 struct sigma_conn *conn,
10092 struct sigma_cmd *cmd,
10093 const char *ifname)
10094{
10095 char buf[200], addr[20];
10096 char dst[ETH_ALEN], src[ETH_ALEN];
10097 short ethtype = htons(ETH_P_ARP);
10098 char *pos;
10099 int s, res;
10100 const char *val;
10101 struct sockaddr_in taddr;
10102
10103 val = get_param(cmd, "dest");
10104 if (val)
10105 hwaddr_aton(val, (unsigned char *) dst);
10106
10107 val = get_param(cmd, "DestIP");
10108 if (val)
10109 inet_aton(val, &taddr.sin_addr);
Peng Xu151c9e12017-10-04 14:39:09 -070010110 else
10111 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010112
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010113 if (get_wpa_status(get_station_ifname(dut), "address", addr,
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010114 sizeof(addr)) < 0)
10115 return -2;
10116 hwaddr_aton(addr, (unsigned char *) src);
10117
10118 pos = buf;
10119 *pos++ = 0x00;
10120 *pos++ = 0x01;
10121 *pos++ = 0x08;
10122 *pos++ = 0x00;
10123 *pos++ = 0x06;
10124 *pos++ = 0x04;
10125 *pos++ = 0x00;
10126 *pos++ = 0x02;
10127 memcpy(pos, src, ETH_ALEN);
10128 pos += ETH_ALEN;
10129 memcpy(pos, &taddr.sin_addr, 4);
10130 pos += 4;
10131 memcpy(pos, dst, ETH_ALEN);
10132 pos += ETH_ALEN;
10133 memcpy(pos, &taddr.sin_addr, 4);
10134 pos += 4;
10135
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010136 s = open_monitor(get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010137 if (s < 0) {
10138 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
10139 "monitor socket");
10140 return 0;
10141 }
10142
10143 res = inject_eth_frame(s, buf, pos - buf, ethtype, dst, src);
10144 if (res < 0) {
10145 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
10146 "inject frame");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +053010147 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010148 return 0;
10149 }
10150
10151 close(s);
10152
10153 return 1;
10154}
10155
10156
10157static int cmd_sta_send_frame_hs2_dls_req(struct sigma_dut *dut,
10158 struct sigma_conn *conn,
10159 struct sigma_cmd *cmd,
10160 const char *intf, const char *dest)
10161{
10162 char buf[100];
10163
10164 if (if_nametoindex("sigmadut") == 0) {
10165 snprintf(buf, sizeof(buf),
10166 "iw dev %s interface add sigmadut type monitor",
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010167 get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010168 if (system(buf) != 0 ||
10169 if_nametoindex("sigmadut") == 0) {
10170 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
10171 "monitor interface with '%s'", buf);
10172 return -2;
10173 }
10174 }
10175
10176 if (system("ifconfig sigmadut up") != 0) {
10177 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
10178 "monitor interface up");
10179 return -2;
10180 }
10181
10182 return sta_inject_frame(dut, conn, DLS_REQ, UNPROTECTED, dest);
10183}
10184
10185
10186static int cmd_sta_send_frame_hs2(struct sigma_dut *dut,
10187 struct sigma_conn *conn,
10188 struct sigma_cmd *cmd)
10189{
10190 const char *intf = get_param(cmd, "Interface");
10191 const char *dest = get_param(cmd, "Dest");
10192 const char *type = get_param(cmd, "FrameName");
10193 const char *val;
10194 char buf[200], *pos, *end;
10195 int count, count2;
10196
10197 if (type == NULL)
10198 type = get_param(cmd, "Type");
10199
10200 if (intf == NULL || dest == NULL || type == NULL)
10201 return -1;
10202
10203 if (strcasecmp(type, "NeighAdv") == 0)
10204 return cmd_sta_send_frame_hs2_neighadv(dut, conn, cmd, intf);
10205
10206 if (strcasecmp(type, "NeighSolicitReq") == 0)
10207 return cmd_sta_send_frame_hs2_neighsolreq(dut, conn, cmd, intf);
10208
10209 if (strcasecmp(type, "ARPProbe") == 0)
10210 return cmd_sta_send_frame_hs2_arpprobe(dut, conn, cmd, intf);
10211
10212 if (strcasecmp(type, "ARPAnnounce") == 0)
10213 return cmd_sta_send_frame_hs2_arpannounce(dut, conn, cmd, intf);
10214
10215 if (strcasecmp(type, "ARPReply") == 0)
10216 return cmd_sta_send_frame_hs2_arpreply(dut, conn, cmd, intf);
10217
10218 if (strcasecmp(type, "DLS-request") == 0 ||
10219 strcasecmp(type, "DLSrequest") == 0)
10220 return cmd_sta_send_frame_hs2_dls_req(dut, conn, cmd, intf,
10221 dest);
10222
10223 if (strcasecmp(type, "ANQPQuery") != 0 &&
10224 strcasecmp(type, "Query") != 0) {
10225 send_resp(dut, conn, SIGMA_ERROR,
10226 "ErrorCode,Unsupported HS 2.0 send frame type");
10227 return 0;
10228 }
10229
10230 if (sta_scan_ap(dut, intf, dest) < 0) {
10231 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not find "
10232 "the requested AP");
10233 return 0;
10234 }
10235
10236 pos = buf;
10237 end = buf + sizeof(buf);
10238 count = 0;
10239 pos += snprintf(pos, end - pos, "ANQP_GET %s ", dest);
10240
10241 val = get_param(cmd, "ANQP_CAP_LIST");
10242 if (val && atoi(val)) {
10243 pos += snprintf(pos, end - pos, "%s257", count > 0 ? "," : "");
10244 count++;
10245 }
10246
10247 val = get_param(cmd, "VENUE_NAME");
10248 if (val && atoi(val)) {
10249 pos += snprintf(pos, end - pos, "%s258", count > 0 ? "," : "");
10250 count++;
10251 }
10252
10253 val = get_param(cmd, "NETWORK_AUTH_TYPE");
10254 if (val && atoi(val)) {
10255 pos += snprintf(pos, end - pos, "%s260", count > 0 ? "," : "");
10256 count++;
10257 }
10258
10259 val = get_param(cmd, "ROAMING_CONS");
10260 if (val && atoi(val)) {
10261 pos += snprintf(pos, end - pos, "%s261", count > 0 ? "," : "");
10262 count++;
10263 }
10264
10265 val = get_param(cmd, "IP_ADDR_TYPE_AVAILABILITY");
10266 if (val && atoi(val)) {
10267 pos += snprintf(pos, end - pos, "%s262", count > 0 ? "," : "");
10268 count++;
10269 }
10270
10271 val = get_param(cmd, "NAI_REALM_LIST");
10272 if (val && atoi(val)) {
10273 pos += snprintf(pos, end - pos, "%s263", count > 0 ? "," : "");
10274 count++;
10275 }
10276
10277 val = get_param(cmd, "3GPP_INFO");
10278 if (val && atoi(val)) {
10279 pos += snprintf(pos, end - pos, "%s264", count > 0 ? "," : "");
10280 count++;
10281 }
10282
10283 val = get_param(cmd, "DOMAIN_LIST");
10284 if (val && atoi(val)) {
10285 pos += snprintf(pos, end - pos, "%s268", count > 0 ? "," : "");
10286 count++;
10287 }
10288
Jouni Malinen34cf9532018-04-29 19:26:33 +030010289 val = get_param(cmd, "Venue_URL");
10290 if (val && atoi(val)) {
10291 pos += snprintf(pos, end - pos, "%s277", count > 0 ? "," : "");
10292 count++;
10293 }
10294
Jouni Malinend3bca5d2018-04-29 17:25:23 +030010295 val = get_param(cmd, "Advice_Of_Charge");
10296 if (val && atoi(val)) {
10297 pos += snprintf(pos, end - pos, "%s278", count > 0 ? "," : "");
10298 count++;
10299 }
10300
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010301 if (count && wpa_command(intf, buf)) {
10302 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,ANQP_GET failed");
10303 return 0;
10304 }
10305
10306 pos = buf;
10307 end = buf + sizeof(buf);
10308 count2 = 0;
10309 pos += snprintf(pos, end - pos, "HS20_ANQP_GET %s ", dest);
10310
10311 val = get_param(cmd, "HS_CAP_LIST");
10312 if (val && atoi(val)) {
10313 pos += snprintf(pos, end - pos, "%s2", count2 > 0 ? "," : "");
10314 count2++;
10315 }
10316
10317 val = get_param(cmd, "OPER_NAME");
10318 if (val && atoi(val)) {
10319 pos += snprintf(pos, end - pos, "%s3", count2 > 0 ? "," : "");
10320 count2++;
10321 }
10322
10323 val = get_param(cmd, "WAN_METRICS");
10324 if (!val)
10325 val = get_param(cmd, "WAN_MAT");
10326 if (!val)
10327 val = get_param(cmd, "WAN_MET");
10328 if (val && atoi(val)) {
10329 pos += snprintf(pos, end - pos, "%s4", count2 > 0 ? "," : "");
10330 count2++;
10331 }
10332
10333 val = get_param(cmd, "CONNECTION_CAPABILITY");
10334 if (val && atoi(val)) {
10335 pos += snprintf(pos, end - pos, "%s5", count2 > 0 ? "," : "");
10336 count2++;
10337 }
10338
10339 val = get_param(cmd, "OP_CLASS");
10340 if (val && atoi(val)) {
10341 pos += snprintf(pos, end - pos, "%s7", count2 > 0 ? "," : "");
10342 count2++;
10343 }
10344
10345 val = get_param(cmd, "OSU_PROVIDER_LIST");
10346 if (val && atoi(val)) {
10347 pos += snprintf(pos, end - pos, "%s8", count2 > 0 ? "," : "");
10348 count2++;
10349 }
10350
Jouni Malinenf67afec2018-04-29 19:24:58 +030010351 val = get_param(cmd, "OPER_ICON_METADATA");
10352 if (!val)
10353 val = get_param(cmd, "OPERATOR_ICON_METADATA");
10354 if (val && atoi(val)) {
10355 pos += snprintf(pos, end - pos, "%s12", count2 > 0 ? "," : "");
10356 count2++;
10357 }
10358
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010359 if (count && count2) {
10360 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before sending out "
10361 "second query");
10362 sleep(1);
10363 }
10364
10365 if (count2 && wpa_command(intf, buf)) {
10366 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,HS20_ANQP_GET "
10367 "failed");
10368 return 0;
10369 }
10370
10371 val = get_param(cmd, "NAI_HOME_REALM_LIST");
10372 if (val) {
10373 if (count || count2) {
10374 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
10375 "sending out second query");
10376 sleep(1);
10377 }
10378
10379 if (strcmp(val, "1") == 0)
10380 val = "mail.example.com";
10381 snprintf(buf, end - pos,
10382 "HS20_GET_NAI_HOME_REALM_LIST %s realm=%s",
10383 dest, val);
10384 if (wpa_command(intf, buf)) {
10385 send_resp(dut, conn, SIGMA_ERROR,
10386 "ErrorCode,HS20_GET_NAI_HOME_REALM_LIST "
10387 "failed");
10388 return 0;
10389 }
10390 }
10391
10392 val = get_param(cmd, "ICON_REQUEST");
10393 if (val) {
10394 if (count || count2) {
10395 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
10396 "sending out second query");
10397 sleep(1);
10398 }
10399
10400 snprintf(buf, end - pos,
10401 "HS20_ICON_REQUEST %s %s", dest, val);
10402 if (wpa_command(intf, buf)) {
10403 send_resp(dut, conn, SIGMA_ERROR,
10404 "ErrorCode,HS20_ICON_REQUEST failed");
10405 return 0;
10406 }
10407 }
10408
10409 return 1;
10410}
10411
10412
10413static int ath_sta_send_frame_vht(struct sigma_dut *dut,
10414 struct sigma_conn *conn,
10415 struct sigma_cmd *cmd)
10416{
10417 const char *val;
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010418 const char *ifname;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010419 int chwidth, nss;
10420
10421 val = get_param(cmd, "framename");
10422 if (!val)
10423 return -1;
10424 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
10425
10426 /* Command sequence to generate Op mode notification */
10427 if (val && strcasecmp(val, "Op_md_notif_frm") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010428 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010429
10430 /* Disable STBC */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010431 run_iwpriv(dut, ifname, "tx_stbc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010432
10433 /* Extract Channel width */
10434 val = get_param(cmd, "Channel_width");
10435 if (val) {
10436 switch (atoi(val)) {
10437 case 20:
10438 chwidth = 0;
10439 break;
10440 case 40:
10441 chwidth = 1;
10442 break;
10443 case 80:
10444 chwidth = 2;
10445 break;
10446 case 160:
10447 chwidth = 3;
10448 break;
10449 default:
10450 chwidth = 2;
10451 break;
10452 }
10453
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010454 run_iwpriv(dut, ifname, "chwidth %d", chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010455 }
10456
10457 /* Extract NSS */
10458 val = get_param(cmd, "NSS");
10459 if (val) {
10460 switch (atoi(val)) {
10461 case 1:
10462 nss = 1;
10463 break;
10464 case 2:
10465 nss = 3;
10466 break;
10467 case 3:
10468 nss = 7;
10469 break;
10470 default:
10471 /* We do not support NSS > 3 */
10472 nss = 3;
10473 break;
10474 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010475 run_iwpriv(dut, ifname, "rxchainmask %d", nss);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010476 }
10477
10478 /* Opmode notify */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010479 run_iwpriv(dut, ifname, "opmode_notify 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010480 }
10481
10482 return 1;
10483}
10484
10485
10486static int cmd_sta_send_frame_vht(struct sigma_dut *dut,
10487 struct sigma_conn *conn,
10488 struct sigma_cmd *cmd)
10489{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010490 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010491 case DRIVER_ATHEROS:
10492 return ath_sta_send_frame_vht(dut, conn, cmd);
10493 default:
10494 send_resp(dut, conn, SIGMA_ERROR,
10495 "errorCode,Unsupported sta_set_frame(VHT) with the current driver");
10496 return 0;
10497 }
10498}
10499
10500
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070010501static int wcn_sta_send_frame_he(struct sigma_dut *dut, struct sigma_conn *conn,
10502 struct sigma_cmd *cmd)
10503{
10504 const char *val;
10505 const char *intf = get_param(cmd, "Interface");
10506
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +030010507 if (!intf)
10508 return -1;
10509
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070010510 val = get_param(cmd, "framename");
10511 if (!val)
10512 return -1;
10513 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
10514
10515 /* Command sequence to generate Op mode notification */
10516 if (val && strcasecmp(val, "action") == 0) {
10517 val = get_param(cmd, "PPDUTxType");
10518 if (val && strcasecmp(val, "TB") == 0) {
10519 if (sta_set_action_tx_in_he_tb_ppdu(dut, intf, 1)) {
10520 sigma_dut_print(dut, DUT_MSG_ERROR,
10521 "failed to send TB PPDU Tx cfg");
10522 send_resp(dut, conn, SIGMA_ERROR,
10523 "ErrorCode,set TB PPDU Tx cfg failed");
10524 return 0;
10525 }
10526 return 1;
10527 }
10528
10529 sigma_dut_print(dut, DUT_MSG_ERROR,
10530 "Action Tx type is not defined");
10531 }
10532
10533 return 1;
10534}
10535
10536
10537static int cmd_sta_send_frame_he(struct sigma_dut *dut,
10538 struct sigma_conn *conn,
10539 struct sigma_cmd *cmd)
10540{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010541 switch (get_driver_type(dut)) {
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070010542 case DRIVER_WCN:
10543 return wcn_sta_send_frame_he(dut, conn, cmd);
10544 default:
10545 send_resp(dut, conn, SIGMA_ERROR,
10546 "errorCode,Unsupported sta_set_frame(HE) with the current driver");
10547 return 0;
10548 }
10549}
10550
10551
Lior David0fe101e2017-03-09 16:09:50 +020010552#ifdef __linux__
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030010553
10554static int
10555wil6210_send_p2p_frame_60g(struct sigma_dut *dut, struct sigma_cmd *cmd,
10556 const char *frame_name, const char *dest_mac)
10557{
10558 int isprobereq = strcasecmp(frame_name, "probereq") == 0;
10559 const char *ssid = get_param(cmd, "ssid");
10560 const char *countstr = get_param(cmd, "count");
10561 const char *channelstr = get_param(cmd, "channel");
10562 const char *group_id = get_param(cmd, "groupid");
10563 const char *client_id = get_param(cmd, "clientmac");
10564 int count, channel, freq, i;
10565 const char *fname;
10566 char frame[1024], src_mac[20], group_id_attr[25],
10567 device_macstr[3 * ETH_ALEN], client_mac[ETH_ALEN];
10568 const char *group_ssid;
10569 const int group_ssid_prefix_len = 9;
10570 struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *) frame;
10571 size_t framelen = sizeof(frame);
10572 struct template_frame_tag tags[2];
10573 size_t tags_total = ARRAY_SIZE(tags);
10574 int tag_index, len, dst_len;
10575
10576 if (!countstr || !channelstr) {
10577 sigma_dut_print(dut, DUT_MSG_ERROR,
10578 "Missing argument: count, channel");
10579 return -1;
10580 }
10581 if (isprobereq && !ssid) {
10582 sigma_dut_print(dut, DUT_MSG_ERROR,
10583 "Missing argument: ssid");
10584 return -1;
10585 }
10586 if (!isprobereq && (!group_id || !client_id)) {
10587 sigma_dut_print(dut, DUT_MSG_ERROR,
10588 "Missing argument: group_id, client_id");
10589 return -1;
10590 }
10591
10592 count = atoi(countstr);
10593 channel = atoi(channelstr);
10594 freq = channel_to_freq(dut, channel);
10595
10596 if (!freq) {
10597 sigma_dut_print(dut, DUT_MSG_ERROR,
10598 "invalid channel: %s", channelstr);
10599 return -1;
10600 }
10601
10602 if (isprobereq) {
10603 if (strcasecmp(ssid, "wildcard") == 0) {
10604 fname = "probe_req_wildcard.txt";
10605 } else if (strcasecmp(ssid, "P2P_Wildcard") == 0) {
10606 fname = "probe_req_P2P_Wildcard.txt";
10607 } else {
10608 sigma_dut_print(dut, DUT_MSG_ERROR,
10609 "invalid probe request type");
10610 return -1;
10611 }
10612 } else {
10613 fname = "P2P_device_discovery_req.txt";
10614 }
10615
10616 if (parse_template_frame_file(dut, fname, frame, &framelen,
10617 tags, &tags_total)) {
10618 sigma_dut_print(dut, DUT_MSG_ERROR,
10619 "invalid frame template: %s", fname);
10620 return -1;
10621 }
10622
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010623 if (get_wpa_status(get_station_ifname(dut), "address",
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030010624 src_mac, sizeof(src_mac)) < 0 ||
10625 parse_mac_address(dut, src_mac, &hdr->addr2[0]) ||
10626 parse_mac_address(dut, dest_mac, &hdr->addr1[0]))
10627 return -1;
10628 /* Use wildcard BSSID, since we are in PBSS */
10629 memset(&hdr->addr3, 0xFF, ETH_ALEN);
10630
10631 if (!isprobereq) {
10632 tag_index = find_template_frame_tag(tags, tags_total, 1);
10633 if (tag_index < 0) {
10634 sigma_dut_print(dut, DUT_MSG_ERROR,
10635 "can't find device id attribute");
10636 return -1;
10637 }
10638 if (parse_mac_address(dut, client_id,
10639 (unsigned char *) client_mac)) {
10640 sigma_dut_print(dut, DUT_MSG_ERROR,
10641 "invalid client_id: %s", client_id);
10642 return -1;
10643 }
10644 if (replace_p2p_attribute(dut, &frame[tags[tag_index].offset],
10645 framelen - tags[tag_index].offset,
10646 IEEE80211_P2P_ATTR_DEVICE_ID,
10647 client_mac, ETH_ALEN)) {
10648 sigma_dut_print(dut, DUT_MSG_ERROR,
10649 "fail to replace device id attribute");
10650 return -1;
10651 }
10652
10653 /*
10654 * group_id arg contains device MAC address followed by
10655 * space and SSID (DIRECT-somessid).
10656 * group id attribute contains device address (6 bytes)
10657 * followed by SSID prefix DIRECT-XX (9 bytes)
10658 */
10659 if (strlen(group_id) < sizeof(device_macstr)) {
10660 sigma_dut_print(dut, DUT_MSG_ERROR,
10661 "group_id arg too short");
10662 return -1;
10663 }
10664 memcpy(device_macstr, group_id, sizeof(device_macstr));
10665 device_macstr[sizeof(device_macstr) - 1] = '\0';
10666 if (parse_mac_address(dut, device_macstr,
10667 (unsigned char *) group_id_attr)) {
10668 sigma_dut_print(dut, DUT_MSG_ERROR,
10669 "fail to parse device address from group_id");
10670 return -1;
10671 }
10672 group_ssid = strchr(group_id, ' ');
10673 if (!group_ssid) {
10674 sigma_dut_print(dut, DUT_MSG_ERROR,
10675 "invalid group_id arg, no ssid");
10676 return -1;
10677 }
10678 group_ssid++;
10679 len = strlen(group_ssid);
10680 if (len < group_ssid_prefix_len) {
10681 sigma_dut_print(dut, DUT_MSG_ERROR,
10682 "group_id SSID too short");
10683 return -1;
10684 }
10685 dst_len = sizeof(group_id_attr) - ETH_ALEN;
10686 if (len > dst_len) {
10687 sigma_dut_print(dut, DUT_MSG_ERROR,
10688 "group_id SSID (%s) too long",
10689 group_ssid);
10690 return -1;
10691 }
10692
10693 memcpy(group_id_attr + ETH_ALEN, group_ssid, len);
10694 tag_index = find_template_frame_tag(tags, tags_total, 2);
10695 if (tag_index < 0) {
10696 sigma_dut_print(dut, DUT_MSG_ERROR,
10697 "can't find group id attribute");
10698 return -1;
10699 }
10700 if (replace_p2p_attribute(dut, &frame[tags[tag_index].offset],
10701 framelen - tags[tag_index].offset,
10702 IEEE80211_P2P_ATTR_GROUP_ID,
10703 group_id_attr,
10704 sizeof(group_id_attr))) {
10705 sigma_dut_print(dut, DUT_MSG_ERROR,
10706 "fail to replace group id attribute");
10707 return -1;
10708 }
10709 }
10710
10711 for (i = 0; i < count; i++) {
10712 if (wil6210_transmit_frame(dut, freq,
10713 WIL_TRANSMIT_FRAME_DEFAULT_ROC,
10714 frame, framelen)) {
10715 sigma_dut_print(dut, DUT_MSG_ERROR,
10716 "fail to transmit probe request frame");
10717 return -1;
10718 }
10719 }
10720
10721 return 0;
10722}
10723
10724
Lior David0fe101e2017-03-09 16:09:50 +020010725int wil6210_send_frame_60g(struct sigma_dut *dut, struct sigma_conn *conn,
10726 struct sigma_cmd *cmd)
10727{
10728 const char *frame_name = get_param(cmd, "framename");
10729 const char *mac = get_param(cmd, "dest_mac");
10730
10731 if (!frame_name || !mac) {
10732 sigma_dut_print(dut, DUT_MSG_ERROR,
10733 "framename and dest_mac must be provided");
10734 return -1;
10735 }
10736
10737 if (strcasecmp(frame_name, "brp") == 0) {
10738 const char *l_rx = get_param(cmd, "L-RX");
10739 int l_rx_i;
10740
10741 if (!l_rx) {
10742 sigma_dut_print(dut, DUT_MSG_ERROR,
10743 "L-RX must be provided");
10744 return -1;
10745 }
10746 l_rx_i = atoi(l_rx);
10747
10748 sigma_dut_print(dut, DUT_MSG_INFO,
10749 "dev_send_frame: BRP-RX, dest_mac %s, L-RX %s",
10750 mac, l_rx);
10751 if (l_rx_i != 16) {
10752 sigma_dut_print(dut, DUT_MSG_ERROR,
10753 "unsupported L-RX: %s", l_rx);
10754 return -1;
10755 }
10756
10757 if (wil6210_send_brp_rx(dut, mac, l_rx_i))
10758 return -1;
10759 } else if (strcasecmp(frame_name, "ssw") == 0) {
10760 sigma_dut_print(dut, DUT_MSG_INFO,
10761 "dev_send_frame: SLS, dest_mac %s", mac);
10762 if (wil6210_send_sls(dut, mac))
10763 return -1;
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030010764 } else if ((strcasecmp(frame_name, "probereq") == 0) ||
10765 (strcasecmp(frame_name, "devdiscreq") == 0)) {
10766 sigma_dut_print(dut, DUT_MSG_INFO,
10767 "dev_send_frame: %s, dest_mac %s", frame_name,
10768 mac);
10769 if (wil6210_send_p2p_frame_60g(dut, cmd, frame_name, mac))
10770 return -1;
Lior David0fe101e2017-03-09 16:09:50 +020010771 } else {
10772 sigma_dut_print(dut, DUT_MSG_ERROR,
10773 "unsupported frame type: %s", frame_name);
10774 return -1;
10775 }
10776
10777 return 1;
10778}
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030010779
Lior David0fe101e2017-03-09 16:09:50 +020010780#endif /* __linux__ */
10781
10782
10783static int cmd_sta_send_frame_60g(struct sigma_dut *dut,
10784 struct sigma_conn *conn,
10785 struct sigma_cmd *cmd)
10786{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010787 switch (get_driver_type(dut)) {
Lior David0fe101e2017-03-09 16:09:50 +020010788#ifdef __linux__
10789 case DRIVER_WIL6210:
10790 return wil6210_send_frame_60g(dut, conn, cmd);
10791#endif /* __linux__ */
10792 default:
10793 send_resp(dut, conn, SIGMA_ERROR,
10794 "errorCode,Unsupported sta_set_frame(60G) with the current driver");
10795 return 0;
10796 }
10797}
10798
10799
Ashwini Patildb59b3c2017-04-13 15:19:23 +053010800static int mbo_send_anqp_query(struct sigma_dut *dut, struct sigma_conn *conn,
10801 const char *intf, struct sigma_cmd *cmd)
10802{
10803 const char *val, *addr;
10804 char buf[100];
10805
10806 addr = get_param(cmd, "DestMac");
10807 if (!addr) {
10808 send_resp(dut, conn, SIGMA_INVALID,
10809 "ErrorCode,AP MAC address is missing");
10810 return 0;
10811 }
10812
10813 val = get_param(cmd, "ANQPQuery_ID");
10814 if (!val) {
10815 send_resp(dut, conn, SIGMA_INVALID,
10816 "ErrorCode,Missing ANQPQuery_ID");
10817 return 0;
10818 }
10819
10820 if (strcasecmp(val, "NeighborReportReq") == 0) {
10821 snprintf(buf, sizeof(buf), "ANQP_GET %s 272", addr);
10822 } else if (strcasecmp(val, "QueryListWithCellPref") == 0) {
10823 snprintf(buf, sizeof(buf), "ANQP_GET %s 272,mbo:2", addr);
10824 } else {
10825 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid ANQPQuery_ID: %s",
10826 val);
10827 send_resp(dut, conn, SIGMA_INVALID,
10828 "ErrorCode,Invalid ANQPQuery_ID");
10829 return 0;
10830 }
10831
Ashwini Patild174f2c2017-04-13 16:49:46 +053010832 /* Set gas_address3 field to IEEE 802.11-2012 standard compliant form
10833 * (Address3 = Wildcard BSSID when sent to not-associated AP;
10834 * if associated, AP BSSID).
10835 */
10836 if (wpa_command(intf, "SET gas_address3 1") < 0) {
10837 send_resp(dut, conn, SIGMA_ERROR,
10838 "ErrorCode,Failed to set gas_address3");
10839 return 0;
10840 }
10841
Ashwini Patildb59b3c2017-04-13 15:19:23 +053010842 if (wpa_command(intf, buf) < 0) {
10843 send_resp(dut, conn, SIGMA_ERROR,
10844 "ErrorCode,Failed to send ANQP query");
10845 return 0;
10846 }
10847
10848 return 1;
10849}
10850
10851
10852static int mbo_cmd_sta_send_frame(struct sigma_dut *dut,
10853 struct sigma_conn *conn,
10854 const char *intf,
10855 struct sigma_cmd *cmd)
10856{
10857 const char *val = get_param(cmd, "FrameName");
10858
10859 if (val && strcasecmp(val, "ANQPQuery") == 0)
10860 return mbo_send_anqp_query(dut, conn, intf, cmd);
10861
10862 return 2;
10863}
10864
10865
Jouni Malinenf7222712019-06-13 01:50:21 +030010866enum sigma_cmd_result cmd_sta_send_frame(struct sigma_dut *dut,
10867 struct sigma_conn *conn,
10868 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010869{
10870 const char *intf = get_param(cmd, "Interface");
10871 const char *val;
10872 enum send_frame_type frame;
10873 enum send_frame_protection protected;
10874 char buf[100];
10875 unsigned char addr[ETH_ALEN];
10876 int res;
10877
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +030010878 if (!intf)
10879 return -1;
10880
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010881 val = get_param(cmd, "program");
10882 if (val == NULL)
10883 val = get_param(cmd, "frame");
10884 if (val && strcasecmp(val, "TDLS") == 0)
10885 return cmd_sta_send_frame_tdls(dut, conn, cmd);
10886 if (val && (strcasecmp(val, "HS2") == 0 ||
Jouni Malinen1f6ae642018-06-07 23:56:13 +030010887 strcasecmp(val, "HS2-R2") == 0 ||
10888 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010889 return cmd_sta_send_frame_hs2(dut, conn, cmd);
10890 if (val && strcasecmp(val, "VHT") == 0)
10891 return cmd_sta_send_frame_vht(dut, conn, cmd);
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070010892 if (val && strcasecmp(val, "HE") == 0)
10893 return cmd_sta_send_frame_he(dut, conn, cmd);
priyadharshini gowthamand66913a2016-07-29 15:11:17 -070010894 if (val && strcasecmp(val, "LOC") == 0)
10895 return loc_cmd_sta_send_frame(dut, conn, cmd);
Lior David0fe101e2017-03-09 16:09:50 +020010896 if (val && strcasecmp(val, "60GHz") == 0)
10897 return cmd_sta_send_frame_60g(dut, conn, cmd);
Ashwini Patildb59b3c2017-04-13 15:19:23 +053010898 if (val && strcasecmp(val, "MBO") == 0) {
10899 res = mbo_cmd_sta_send_frame(dut, conn, intf, cmd);
10900 if (res != 2)
10901 return res;
10902 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010903
10904 val = get_param(cmd, "TD_DISC");
10905 if (val) {
10906 if (hwaddr_aton(val, addr) < 0)
10907 return -1;
10908 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", val);
10909 if (wpa_command(intf, buf) < 0) {
10910 send_resp(dut, conn, SIGMA_ERROR,
10911 "ErrorCode,Failed to send TDLS discovery");
10912 return 0;
10913 }
10914 return 1;
10915 }
10916
10917 val = get_param(cmd, "TD_Setup");
10918 if (val) {
10919 if (hwaddr_aton(val, addr) < 0)
10920 return -1;
10921 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", val);
10922 if (wpa_command(intf, buf) < 0) {
10923 send_resp(dut, conn, SIGMA_ERROR,
10924 "ErrorCode,Failed to start TDLS setup");
10925 return 0;
10926 }
10927 return 1;
10928 }
10929
10930 val = get_param(cmd, "TD_TearDown");
10931 if (val) {
10932 if (hwaddr_aton(val, addr) < 0)
10933 return -1;
10934 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", val);
10935 if (wpa_command(intf, buf) < 0) {
10936 send_resp(dut, conn, SIGMA_ERROR,
10937 "ErrorCode,Failed to tear down TDLS link");
10938 return 0;
10939 }
10940 return 1;
10941 }
10942
10943 val = get_param(cmd, "TD_ChannelSwitch");
10944 if (val) {
10945 /* TODO */
10946 send_resp(dut, conn, SIGMA_ERROR,
10947 "ErrorCode,TD_ChannelSwitch not yet supported");
10948 return 0;
10949 }
10950
10951 val = get_param(cmd, "TD_NF");
10952 if (val) {
10953 /* TODO */
10954 send_resp(dut, conn, SIGMA_ERROR,
10955 "ErrorCode,TD_NF not yet supported");
10956 return 0;
10957 }
10958
10959 val = get_param(cmd, "PMFFrameType");
10960 if (val == NULL)
10961 val = get_param(cmd, "FrameName");
10962 if (val == NULL)
10963 val = get_param(cmd, "Type");
10964 if (val == NULL)
10965 return -1;
10966 if (strcasecmp(val, "disassoc") == 0)
10967 frame = DISASSOC;
10968 else if (strcasecmp(val, "deauth") == 0)
10969 frame = DEAUTH;
10970 else if (strcasecmp(val, "saquery") == 0)
10971 frame = SAQUERY;
10972 else if (strcasecmp(val, "auth") == 0)
10973 frame = AUTH;
10974 else if (strcasecmp(val, "assocreq") == 0)
10975 frame = ASSOCREQ;
10976 else if (strcasecmp(val, "reassocreq") == 0)
10977 frame = REASSOCREQ;
10978 else if (strcasecmp(val, "neigreq") == 0) {
10979 sigma_dut_print(dut, DUT_MSG_INFO, "Got neighbor request");
10980
10981 val = get_param(cmd, "ssid");
10982 if (val == NULL)
10983 return -1;
10984
10985 res = send_neighbor_request(dut, intf, val);
10986 if (res) {
10987 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
10988 "Failed to send neighbor report request");
10989 return 0;
10990 }
10991
10992 return 1;
Ashwini Patil5acd7382017-04-13 15:55:04 +053010993 } else if (strcasecmp(val, "transmgmtquery") == 0 ||
10994 strcasecmp(val, "BTMQuery") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010995 sigma_dut_print(dut, DUT_MSG_DEBUG,
10996 "Got Transition Management Query");
10997
Ashwini Patil5acd7382017-04-13 15:55:04 +053010998 res = send_trans_mgmt_query(dut, intf, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010999 if (res) {
11000 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
11001 "Failed to send Transition Management Query");
11002 return 0;
11003 }
11004
11005 return 1;
11006 } else {
11007 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
11008 "PMFFrameType");
11009 return 0;
11010 }
11011
11012 val = get_param(cmd, "PMFProtected");
11013 if (val == NULL)
11014 val = get_param(cmd, "Protected");
11015 if (val == NULL)
11016 return -1;
11017 if (strcasecmp(val, "Correct-key") == 0 ||
11018 strcasecmp(val, "CorrectKey") == 0)
11019 protected = CORRECT_KEY;
11020 else if (strcasecmp(val, "IncorrectKey") == 0)
11021 protected = INCORRECT_KEY;
11022 else if (strcasecmp(val, "Unprotected") == 0)
11023 protected = UNPROTECTED;
11024 else {
11025 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
11026 "PMFProtected");
11027 return 0;
11028 }
11029
11030 if (protected != UNPROTECTED &&
11031 (frame == AUTH || frame == ASSOCREQ || frame == REASSOCREQ)) {
11032 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Impossible "
11033 "PMFProtected for auth/assocreq/reassocreq");
11034 return 0;
11035 }
11036
11037 if (if_nametoindex("sigmadut") == 0) {
11038 snprintf(buf, sizeof(buf),
11039 "iw dev %s interface add sigmadut type monitor",
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011040 get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011041 if (system(buf) != 0 ||
11042 if_nametoindex("sigmadut") == 0) {
11043 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
11044 "monitor interface with '%s'", buf);
11045 return -2;
11046 }
11047 }
11048
11049 if (system("ifconfig sigmadut up") != 0) {
11050 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
11051 "monitor interface up");
11052 return -2;
11053 }
11054
11055 return sta_inject_frame(dut, conn, frame, protected, NULL);
11056}
11057
11058
11059static int cmd_sta_set_parameter_hs2(struct sigma_dut *dut,
11060 struct sigma_conn *conn,
11061 struct sigma_cmd *cmd,
11062 const char *ifname)
11063{
11064 char buf[200];
11065 const char *val;
11066
11067 val = get_param(cmd, "ClearARP");
11068 if (val && atoi(val) == 1) {
11069 snprintf(buf, sizeof(buf), "ip neigh flush dev %s", ifname);
11070 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
11071 if (system(buf) != 0) {
11072 send_resp(dut, conn, SIGMA_ERROR,
11073 "errorCode,Failed to clear ARP cache");
11074 return 0;
11075 }
11076 }
11077
11078 return 1;
11079}
11080
11081
11082int cmd_sta_set_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
11083 struct sigma_cmd *cmd)
11084{
11085 const char *intf = get_param(cmd, "Interface");
11086 const char *val;
11087
11088 if (intf == NULL)
11089 return -1;
11090
11091 val = get_param(cmd, "program");
11092 if (val && (strcasecmp(val, "HS2") == 0 ||
Jouni Malinen1f6ae642018-06-07 23:56:13 +030011093 strcasecmp(val, "HS2-R2") == 0 ||
11094 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011095 return cmd_sta_set_parameter_hs2(dut, conn, cmd, intf);
11096
11097 return -1;
11098}
11099
11100
Jouni Malinenf7222712019-06-13 01:50:21 +030011101static enum sigma_cmd_result cmd_sta_set_macaddr(struct sigma_dut *dut,
11102 struct sigma_conn *conn,
11103 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011104{
11105 const char *intf = get_param(cmd, "Interface");
11106 const char *mac = get_param(cmd, "MAC");
11107
11108 if (intf == NULL || mac == NULL)
11109 return -1;
11110
11111 sigma_dut_print(dut, DUT_MSG_INFO, "Change local MAC address for "
11112 "interface %s to %s", intf, mac);
11113
11114 if (dut->set_macaddr) {
11115 char buf[128];
11116 int res;
11117 if (strcasecmp(mac, "default") == 0) {
11118 res = snprintf(buf, sizeof(buf), "%s",
11119 dut->set_macaddr);
11120 dut->tmp_mac_addr = 0;
11121 } else {
11122 res = snprintf(buf, sizeof(buf), "%s %s",
11123 dut->set_macaddr, mac);
11124 dut->tmp_mac_addr = 1;
11125 }
11126 if (res < 0 || res >= (int) sizeof(buf))
11127 return -1;
11128 if (system(buf) != 0) {
11129 send_resp(dut, conn, SIGMA_ERROR,
11130 "errorCode,Failed to set MAC "
11131 "address");
11132 return 0;
11133 }
11134 return 1;
11135 }
11136
11137 if (strcasecmp(mac, "default") == 0)
11138 return 1;
11139
11140 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
11141 "command");
11142 return 0;
11143}
11144
11145
11146static int iwpriv_tdlsoffchnmode(struct sigma_dut *dut,
11147 struct sigma_conn *conn, const char *intf,
11148 int val)
11149{
11150 char buf[200];
11151 int res;
11152
11153 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchnmode %d",
11154 intf, val);
11155 if (res < 0 || res >= (int) sizeof(buf))
11156 return -1;
11157 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
11158 if (system(buf) != 0) {
11159 send_resp(dut, conn, SIGMA_ERROR,
11160 "errorCode,Failed to configure offchannel mode");
11161 return 0;
11162 }
11163
11164 return 1;
11165}
11166
11167
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011168static int off_chan_val(enum sec_ch_offset off)
11169{
11170 switch (off) {
11171 case SEC_CH_NO:
11172 return 0;
11173 case SEC_CH_40ABOVE:
11174 return 40;
11175 case SEC_CH_40BELOW:
11176 return -40;
11177 }
11178
11179 return 0;
11180}
11181
11182
11183static int iwpriv_set_offchan(struct sigma_dut *dut, struct sigma_conn *conn,
11184 const char *intf, int off_ch_num,
11185 enum sec_ch_offset sec)
11186{
11187 char buf[200];
11188 int res;
11189
11190 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchan %d",
11191 intf, off_ch_num);
11192 if (res < 0 || res >= (int) sizeof(buf))
11193 return -1;
11194 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
11195 if (system(buf) != 0) {
11196 send_resp(dut, conn, SIGMA_ERROR,
11197 "errorCode,Failed to set offchan");
11198 return 0;
11199 }
11200
11201 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsecchnoffst %d",
11202 intf, off_chan_val(sec));
11203 if (res < 0 || res >= (int) sizeof(buf))
11204 return -1;
11205 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
11206 if (system(buf) != 0) {
11207 send_resp(dut, conn, SIGMA_ERROR,
11208 "errorCode,Failed to set sec chan offset");
11209 return 0;
11210 }
11211
11212 return 1;
11213}
11214
11215
11216static int tdls_set_offchannel_offset(struct sigma_dut *dut,
11217 struct sigma_conn *conn,
11218 const char *intf, int off_ch_num,
11219 enum sec_ch_offset sec)
11220{
11221 char buf[200];
11222 int res;
11223
11224 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNEL %d",
11225 off_ch_num);
11226 if (res < 0 || res >= (int) sizeof(buf))
11227 return -1;
11228 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
11229
11230 if (wpa_command(intf, buf) < 0) {
11231 send_resp(dut, conn, SIGMA_ERROR,
11232 "ErrorCode,Failed to set offchan");
11233 return 0;
11234 }
11235 res = snprintf(buf, sizeof(buf), "DRIVER TDLSSECONDARYCHANNELOFFSET %d",
11236 off_chan_val(sec));
11237 if (res < 0 || res >= (int) sizeof(buf))
11238 return -1;
11239
11240 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
11241
11242 if (wpa_command(intf, buf) < 0) {
11243 send_resp(dut, conn, SIGMA_ERROR,
11244 "ErrorCode,Failed to set sec chan offset");
11245 return 0;
11246 }
11247
11248 return 1;
11249}
11250
11251
11252static int tdls_set_offchannel_mode(struct sigma_dut *dut,
11253 struct sigma_conn *conn,
11254 const char *intf, int val)
11255{
11256 char buf[200];
11257 int res;
11258
11259 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNELMODE %d",
11260 val);
11261 if (res < 0 || res >= (int) sizeof(buf))
11262 return -1;
11263 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
11264
11265 if (wpa_command(intf, buf) < 0) {
11266 send_resp(dut, conn, SIGMA_ERROR,
11267 "ErrorCode,Failed to configure offchannel mode");
11268 return 0;
11269 }
11270
11271 return 1;
11272}
11273
11274
11275static int cmd_sta_set_rfeature_tdls(const char *intf, struct sigma_dut *dut,
11276 struct sigma_conn *conn,
11277 struct sigma_cmd *cmd)
11278{
11279 const char *val;
11280 enum {
11281 CHSM_NOT_SET,
11282 CHSM_ENABLE,
11283 CHSM_DISABLE,
11284 CHSM_REJREQ,
11285 CHSM_UNSOLRESP
11286 } chsm = CHSM_NOT_SET;
11287 int off_ch_num = -1;
11288 enum sec_ch_offset sec_ch = SEC_CH_NO;
11289 int res;
11290
11291 val = get_param(cmd, "Uapsd");
11292 if (val) {
11293 char buf[100];
11294 if (strcasecmp(val, "Enable") == 0)
11295 snprintf(buf, sizeof(buf), "SET ps 99");
11296 else if (strcasecmp(val, "Disable") == 0)
11297 snprintf(buf, sizeof(buf), "SET ps 98");
11298 else {
11299 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
11300 "Unsupported uapsd parameter value");
11301 return 0;
11302 }
11303 if (wpa_command(intf, buf)) {
11304 send_resp(dut, conn, SIGMA_ERROR,
11305 "ErrorCode,Failed to change U-APSD "
11306 "powersave mode");
11307 return 0;
11308 }
11309 }
11310
11311 val = get_param(cmd, "TPKTIMER");
11312 if (val && strcasecmp(val, "DISABLE") == 0) {
11313 if (wpa_command(intf, "SET tdls_testing 0x100")) {
11314 send_resp(dut, conn, SIGMA_ERROR,
11315 "ErrorCode,Failed to enable no TPK "
11316 "expiration test mode");
11317 return 0;
11318 }
11319 dut->no_tpk_expiration = 1;
11320 }
11321
11322 val = get_param(cmd, "ChSwitchMode");
11323 if (val) {
11324 if (strcasecmp(val, "Enable") == 0 ||
11325 strcasecmp(val, "Initiate") == 0)
11326 chsm = CHSM_ENABLE;
11327 else if (strcasecmp(val, "Disable") == 0 ||
11328 strcasecmp(val, "passive") == 0)
11329 chsm = CHSM_DISABLE;
11330 else if (strcasecmp(val, "RejReq") == 0)
11331 chsm = CHSM_REJREQ;
11332 else if (strcasecmp(val, "UnSolResp") == 0)
11333 chsm = CHSM_UNSOLRESP;
11334 else {
11335 send_resp(dut, conn, SIGMA_ERROR,
11336 "ErrorCode,Unknown ChSwitchMode value");
11337 return 0;
11338 }
11339 }
11340
11341 val = get_param(cmd, "OffChNum");
11342 if (val) {
11343 off_ch_num = atoi(val);
11344 if (off_ch_num == 0) {
11345 send_resp(dut, conn, SIGMA_ERROR,
11346 "ErrorCode,Invalid OffChNum");
11347 return 0;
11348 }
11349 }
11350
11351 val = get_param(cmd, "SecChOffset");
11352 if (val) {
11353 if (strcmp(val, "20") == 0)
11354 sec_ch = SEC_CH_NO;
11355 else if (strcasecmp(val, "40above") == 0)
11356 sec_ch = SEC_CH_40ABOVE;
11357 else if (strcasecmp(val, "40below") == 0)
11358 sec_ch = SEC_CH_40BELOW;
11359 else {
11360 send_resp(dut, conn, SIGMA_ERROR,
11361 "ErrorCode,Unknown SecChOffset value");
11362 return 0;
11363 }
11364 }
11365
11366 if (chsm == CHSM_NOT_SET) {
11367 /* no offchannel changes requested */
11368 return 1;
11369 }
11370
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011371 if (strcmp(intf, get_main_ifname(dut)) != 0 &&
11372 strcmp(intf, get_station_ifname(dut)) != 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011373 send_resp(dut, conn, SIGMA_ERROR,
11374 "ErrorCode,Unknown interface");
11375 return 0;
11376 }
11377
11378 switch (chsm) {
11379 case CHSM_NOT_SET:
Jouni Malinen280f5ba2016-08-29 21:33:10 +030011380 res = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011381 break;
11382 case CHSM_ENABLE:
11383 if (off_ch_num < 0) {
11384 send_resp(dut, conn, SIGMA_ERROR,
11385 "ErrorCode,Missing OffChNum argument");
11386 return 0;
11387 }
11388 if (wifi_chip_type == DRIVER_WCN) {
11389 res = tdls_set_offchannel_offset(dut, conn, intf,
11390 off_ch_num, sec_ch);
11391 } else {
11392 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
11393 sec_ch);
11394 }
11395 if (res != 1)
11396 return res;
11397 if (wifi_chip_type == DRIVER_WCN)
11398 res = tdls_set_offchannel_mode(dut, conn, intf, 1);
11399 else
11400 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 1);
11401 break;
11402 case CHSM_DISABLE:
11403 if (wifi_chip_type == DRIVER_WCN)
11404 res = tdls_set_offchannel_mode(dut, conn, intf, 2);
11405 else
11406 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 2);
11407 break;
11408 case CHSM_REJREQ:
11409 if (wifi_chip_type == DRIVER_WCN)
11410 res = tdls_set_offchannel_mode(dut, conn, intf, 3);
11411 else
11412 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 3);
11413 break;
11414 case CHSM_UNSOLRESP:
11415 if (off_ch_num < 0) {
11416 send_resp(dut, conn, SIGMA_ERROR,
11417 "ErrorCode,Missing OffChNum argument");
11418 return 0;
11419 }
11420 if (wifi_chip_type == DRIVER_WCN) {
11421 res = tdls_set_offchannel_offset(dut, conn, intf,
11422 off_ch_num, sec_ch);
11423 } else {
11424 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
11425 sec_ch);
11426 }
11427 if (res != 1)
11428 return res;
11429 if (wifi_chip_type == DRIVER_WCN)
11430 res = tdls_set_offchannel_mode(dut, conn, intf, 4);
11431 else
11432 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 4);
11433 break;
11434 }
11435
11436 return res;
11437}
11438
11439
11440static int ath_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
11441 struct sigma_conn *conn,
11442 struct sigma_cmd *cmd)
11443{
11444 const char *val;
Srikanth Marepalli5415acf2018-08-27 12:53:11 +053011445 char *token = NULL, *result;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011446
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -070011447 novap_reset(dut, intf, 1);
priyadharshini gowthamane5e25172015-12-08 14:53:48 -080011448
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011449 val = get_param(cmd, "nss_mcs_opt");
11450 if (val) {
11451 /* String (nss_operating_mode; mcs_operating_mode) */
11452 int nss, mcs;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053011453 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011454
11455 token = strdup(val);
11456 if (!token)
11457 return 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053011458 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +053011459 if (!result) {
11460 sigma_dut_print(dut, DUT_MSG_ERROR,
11461 "VHT NSS not specified");
11462 goto failed;
11463 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011464 if (strcasecmp(result, "def") != 0) {
11465 nss = atoi(result);
11466 if (nss == 4)
11467 ath_disable_txbf(dut, intf);
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011468 if (run_iwpriv(dut, intf, "nss %d", nss) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011469 goto failed;
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011470
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011471 }
11472
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053011473 result = strtok_r(NULL, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +053011474 if (!result) {
11475 sigma_dut_print(dut, DUT_MSG_ERROR,
11476 "VHT MCS not specified");
11477 goto failed;
11478 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011479 if (strcasecmp(result, "def") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011480 if (run_iwpriv(dut, intf, "set11NRates 0") < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011481 goto failed;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011482 } else {
11483 mcs = atoi(result);
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011484 if (run_iwpriv(dut, intf, "vhtmcs %d", mcs) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011485 goto failed;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011486 }
11487 /* Channel width gets messed up, fix this */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011488 run_iwpriv(dut, intf, "chwidth %d", dut->chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011489 }
11490
Srikanth Marepalli5415acf2018-08-27 12:53:11 +053011491 free(token);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011492 return 1;
11493failed:
11494 free(token);
11495 return 0;
11496}
11497
11498
11499static int cmd_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
11500 struct sigma_conn *conn,
11501 struct sigma_cmd *cmd)
11502{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011503 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011504 case DRIVER_ATHEROS:
11505 return ath_sta_set_rfeature_vht(intf, dut, conn, cmd);
11506 default:
11507 send_resp(dut, conn, SIGMA_ERROR,
11508 "errorCode,Unsupported sta_set_rfeature(VHT) with the current driver");
11509 return 0;
11510 }
11511}
11512
11513
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011514static int wcn_sta_set_rfeature_he(const char *intf, struct sigma_dut *dut,
11515 struct sigma_conn *conn,
11516 struct sigma_cmd *cmd)
11517{
11518 const char *val;
11519 char *token = NULL, *result;
11520 char buf[60];
11521
11522 val = get_param(cmd, "nss_mcs_opt");
11523 if (val) {
11524 /* String (nss_operating_mode; mcs_operating_mode) */
11525 int nss, mcs, ratecode;
11526 char *saveptr;
11527
11528 token = strdup(val);
11529 if (!token)
11530 return -2;
11531
11532 result = strtok_r(token, ";", &saveptr);
11533 if (!result) {
11534 sigma_dut_print(dut, DUT_MSG_ERROR,
11535 "HE NSS not specified");
11536 goto failed;
11537 }
11538 nss = 1;
11539 if (strcasecmp(result, "def") != 0)
11540 nss = atoi(result);
11541
11542 result = strtok_r(NULL, ";", &saveptr);
11543 if (!result) {
11544 sigma_dut_print(dut, DUT_MSG_ERROR,
11545 "HE MCS not specified");
11546 goto failed;
11547 }
11548 mcs = 7;
11549 if (strcasecmp(result, "def") != 0)
11550 mcs = atoi(result);
11551
Arif Hussain557bf412018-05-25 17:29:36 -070011552 ratecode = 0x20; /* for nss:1 MCS 0 */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011553 if (nss == 2) {
Arif Hussain557bf412018-05-25 17:29:36 -070011554 ratecode = 0x40; /* for nss:2 MCS 0 */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011555 } else if (nss > 2) {
11556 sigma_dut_print(dut, DUT_MSG_ERROR,
11557 "HE NSS %d not supported", nss);
11558 goto failed;
11559 }
11560
Arif Hussain557bf412018-05-25 17:29:36 -070011561 snprintf(buf, sizeof(buf), "iwpriv %s nss %d", intf, nss);
11562 if (system(buf) != 0) {
11563 sigma_dut_print(dut, DUT_MSG_ERROR,
11564 "nss_mcs_opt: iwpriv %s nss %d failed",
11565 intf, nss);
11566 goto failed;
11567 }
Arif Hussainac6c5112018-05-25 17:34:00 -070011568 dut->sta_nss = nss;
Arif Hussain557bf412018-05-25 17:29:36 -070011569
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011570 /* Add the MCS to the ratecode */
11571 if (mcs >= 0 && mcs <= 11) {
11572 ratecode += mcs;
Arif Hussain557bf412018-05-25 17:29:36 -070011573#ifdef NL80211_SUPPORT
11574 if (dut->device_type == STA_testbed) {
11575 enum he_mcs_config mcs_config;
11576 int ret;
11577
11578 if (mcs <= 7)
11579 mcs_config = HE_80_MCS0_7;
11580 else if (mcs <= 9)
11581 mcs_config = HE_80_MCS0_9;
11582 else
11583 mcs_config = HE_80_MCS0_11;
11584 ret = sta_set_he_mcs(dut, intf, mcs_config);
11585 if (ret) {
11586 sigma_dut_print(dut, DUT_MSG_ERROR,
11587 "nss_mcs_opt: mcs setting failed, mcs:%d, mcs_config %d, ret:%d",
11588 mcs, mcs_config, ret);
11589 goto failed;
11590 }
11591 }
11592#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011593 } else {
11594 sigma_dut_print(dut, DUT_MSG_ERROR,
11595 "HE MCS %d not supported", mcs);
11596 goto failed;
11597 }
11598 snprintf(buf, sizeof(buf), "iwpriv %s set_11ax_rate 0x%03x",
11599 intf, ratecode);
11600 if (system(buf) != 0) {
11601 sigma_dut_print(dut, DUT_MSG_ERROR,
11602 "iwpriv setting of 11ax rates failed");
11603 goto failed;
11604 }
11605 free(token);
11606 }
11607
11608 val = get_param(cmd, "GI");
11609 if (val) {
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011610 int fix_rate_sgi;
11611
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011612 if (strcmp(val, "0.8") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070011613 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 9", intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011614 fix_rate_sgi = 1;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011615 } else if (strcmp(val, "1.6") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070011616 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 10",
11617 intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011618 fix_rate_sgi = 2;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011619 } else if (strcmp(val, "3.2") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070011620 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 11",
11621 intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011622 fix_rate_sgi = 3;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011623 } else {
11624 send_resp(dut, conn, SIGMA_ERROR,
11625 "errorCode,GI value not supported");
11626 return 0;
11627 }
11628 if (system(buf) != 0) {
11629 send_resp(dut, conn, SIGMA_ERROR,
11630 "errorCode,Failed to set shortgi");
11631 return 0;
11632 }
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011633 snprintf(buf, sizeof(buf), "iwpriv %s shortgi %d",
11634 intf, fix_rate_sgi);
11635 if (system(buf) != 0) {
11636 send_resp(dut, conn, SIGMA_ERROR,
11637 "errorCode,Failed to set fix rate shortgi");
11638 return STATUS_SENT;
11639 }
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011640 }
11641
Subhani Shaik8e7a3052018-04-24 14:03:00 -070011642 val = get_param(cmd, "LTF");
11643 if (val) {
11644#ifdef NL80211_SUPPORT
11645 if (strcmp(val, "3.2") == 0) {
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -080011646 wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_1X);
Subhani Shaik8e7a3052018-04-24 14:03:00 -070011647 } if (strcmp(val, "6.4") == 0) {
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -080011648 wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_2X);
Subhani Shaik8e7a3052018-04-24 14:03:00 -070011649 } else if (strcmp(val, "12.8") == 0) {
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -080011650 wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_4X);
Subhani Shaik8e7a3052018-04-24 14:03:00 -070011651 } else {
11652 send_resp(dut, conn, SIGMA_ERROR,
11653 "errorCode, LTF value not supported");
11654 return 0;
11655 }
11656#else /* NL80211_SUPPORT */
11657 sigma_dut_print(dut, DUT_MSG_ERROR,
11658 "LTF cannot be set without NL80211_SUPPORT defined");
11659 return -2;
11660#endif /* NL80211_SUPPORT */
11661 }
11662
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -070011663 val = get_param(cmd, "TxSUPPDU");
11664 if (val) {
11665 int set_val = 1;
11666
11667 if (strcasecmp(val, "Enable") == 0)
11668 set_val = 1;
11669 else if (strcasecmp(val, "Disable") == 0)
11670 set_val = 0;
11671
11672 if (sta_set_tx_su_ppdu_cfg(dut, intf, set_val)) {
11673 send_resp(dut, conn, SIGMA_ERROR,
11674 "ErrorCode,Failed to set Tx SU PPDU config");
11675 return 0;
11676 }
11677 }
11678
Arif Hussain480d5f42019-03-12 14:40:42 -070011679 val = get_param(cmd, "TWT_Setup");
11680 if (val) {
11681 if (strcasecmp(val, "Request") == 0) {
11682 if (sta_twt_request(dut, conn, cmd)) {
11683 send_resp(dut, conn, SIGMA_ERROR,
11684 "ErrorCode,sta_twt_request failed");
11685 return STATUS_SENT;
11686 }
11687 } else if (strcasecmp(val, "Teardown") == 0) {
11688 if (sta_twt_teardown(dut, conn, cmd)) {
11689 send_resp(dut, conn, SIGMA_ERROR,
11690 "ErrorCode,sta_twt_teardown failed");
11691 return STATUS_SENT;
11692 }
11693 }
11694 }
11695
Kiran Kumar Lokere50eb2cd2018-12-18 18:31:28 -080011696 val = get_param(cmd, "transmitOMI");
11697 if (val && sta_transmit_omi(dut, conn, cmd)) {
11698 send_resp(dut, conn, SIGMA_ERROR,
11699 "ErrorCode,sta_transmit_omi failed");
11700 return STATUS_SENT;
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -070011701 }
11702
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080011703 val = get_param(cmd, "Powersave");
11704 if (val) {
11705 char buf[60];
11706
11707 if (strcasecmp(val, "off") == 0) {
11708 snprintf(buf, sizeof(buf),
11709 "iwpriv %s setPower 2", intf);
11710 if (system(buf) != 0) {
11711 sigma_dut_print(dut, DUT_MSG_ERROR,
11712 "iwpriv setPower 2 failed");
11713 return 0;
11714 }
11715 } else if (strcasecmp(val, "on") == 0) {
11716 snprintf(buf, sizeof(buf),
11717 "iwpriv %s setPower 1", intf);
11718 if (system(buf) != 0) {
11719 sigma_dut_print(dut, DUT_MSG_ERROR,
11720 "iwpriv setPower 1 failed");
11721 return 0;
11722 }
11723 } else {
11724 sigma_dut_print(dut, DUT_MSG_ERROR,
11725 "Unsupported Powersave value '%s'",
11726 val);
11727 return -1;
11728 }
11729 }
11730
Kiran Kumar Lokere2c4b7ce2019-01-30 12:02:28 -080011731 val = get_param(cmd, "MU_EDCA");
11732 if (val) {
11733 if (strcasecmp(val, "Override") == 0) {
11734 if (sta_set_mu_edca_override(dut, intf, 1)) {
11735 send_resp(dut, conn, SIGMA_ERROR,
11736 "errorCode,MU EDCA override set failed");
11737 return STATUS_SENT;
11738 }
11739 } else if (strcasecmp(val, "Disable") == 0) {
11740 if (sta_set_mu_edca_override(dut, intf, 0)) {
11741 send_resp(dut, conn, SIGMA_ERROR,
11742 "errorCode,MU EDCA override disable failed");
11743 return STATUS_SENT;
11744 }
11745 }
11746 }
11747
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011748 return 1;
11749
11750failed:
11751 free(token);
11752 return -2;
11753}
11754
11755
11756static int cmd_sta_set_rfeature_he(const char *intf, struct sigma_dut *dut,
11757 struct sigma_conn *conn,
11758 struct sigma_cmd *cmd)
11759{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011760 switch (get_driver_type(dut)) {
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011761 case DRIVER_WCN:
11762 return wcn_sta_set_rfeature_he(intf, dut, conn, cmd);
11763 default:
11764 send_resp(dut, conn, SIGMA_ERROR,
11765 "errorCode,Unsupported sta_set_rfeature(HE) with the current driver");
11766 return 0;
11767 }
11768}
11769
11770
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080011771static int cmd_sta_set_power_save_he(const char *intf, struct sigma_dut *dut,
11772 struct sigma_conn *conn,
11773 struct sigma_cmd *cmd)
11774{
11775 const char *val;
11776
11777 val = get_param(cmd, "powersave");
11778 if (val) {
11779 char buf[60];
11780
11781 if (strcasecmp(val, "off") == 0) {
11782 snprintf(buf, sizeof(buf), "iwpriv %s setPower 2",
11783 intf);
11784 if (system(buf) != 0) {
11785 sigma_dut_print(dut, DUT_MSG_ERROR,
11786 "iwpriv setPower 2 failed");
11787 return 0;
11788 }
11789 } else if (strcasecmp(val, "on") == 0) {
11790 snprintf(buf, sizeof(buf), "iwpriv %s setPower 1",
11791 intf);
11792 if (system(buf) != 0) {
11793 sigma_dut_print(dut, DUT_MSG_ERROR,
11794 "iwpriv setPower 1 failed");
11795 return 0;
11796 }
11797 } else {
11798 sigma_dut_print(dut, DUT_MSG_ERROR,
11799 "Unsupported power save config");
11800 return -1;
11801 }
11802 return 1;
11803 }
11804
11805 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported command");
11806
11807 return 0;
11808}
11809
11810
Ashwini Patil5acd7382017-04-13 15:55:04 +053011811static int btm_query_candidate_list(struct sigma_dut *dut,
11812 struct sigma_conn *conn,
11813 struct sigma_cmd *cmd)
11814{
11815 const char *bssid, *info, *op_class, *ch, *phy_type, *pref;
11816 int len, ret;
11817 char buf[10];
11818
11819 /*
11820 * Neighbor Report elements format:
11821 * neighbor=<BSSID>,<BSSID Information>,<Operating Class>,
11822 * <Channel Number>,<PHY Type>[,<hexdump of Optional Subelements>]
11823 * eg: neighbor=aa:bb:cc:dd:ee:ff,17,81,6,1,030101
11824 */
11825
11826 bssid = get_param(cmd, "Nebor_BSSID");
11827 if (!bssid) {
11828 send_resp(dut, conn, SIGMA_INVALID,
11829 "errorCode,Nebor_BSSID is missing");
11830 return 0;
11831 }
11832
11833 info = get_param(cmd, "Nebor_Bssid_Info");
11834 if (!info) {
11835 sigma_dut_print(dut, DUT_MSG_INFO,
11836 "Using default value for Nebor_Bssid_Info: %s",
11837 DEFAULT_NEIGHBOR_BSSID_INFO);
11838 info = DEFAULT_NEIGHBOR_BSSID_INFO;
11839 }
11840
11841 op_class = get_param(cmd, "Nebor_Op_Class");
11842 if (!op_class) {
11843 send_resp(dut, conn, SIGMA_INVALID,
11844 "errorCode,Nebor_Op_Class is missing");
11845 return 0;
11846 }
11847
11848 ch = get_param(cmd, "Nebor_Op_Ch");
11849 if (!ch) {
11850 send_resp(dut, conn, SIGMA_INVALID,
11851 "errorCode,Nebor_Op_Ch is missing");
11852 return 0;
11853 }
11854
11855 phy_type = get_param(cmd, "Nebor_Phy_Type");
11856 if (!phy_type) {
11857 sigma_dut_print(dut, DUT_MSG_INFO,
11858 "Using default value for Nebor_Phy_Type: %s",
11859 DEFAULT_NEIGHBOR_PHY_TYPE);
11860 phy_type = DEFAULT_NEIGHBOR_PHY_TYPE;
11861 }
11862
11863 /* Parse optional subelements */
11864 buf[0] = '\0';
11865 pref = get_param(cmd, "Nebor_Pref");
11866 if (pref) {
11867 /* hexdump for preferrence subelement */
11868 ret = snprintf(buf, sizeof(buf), ",0301%02x", atoi(pref));
11869 if (ret < 0 || ret >= (int) sizeof(buf)) {
11870 sigma_dut_print(dut, DUT_MSG_ERROR,
11871 "snprintf failed for optional subelement ret: %d",
11872 ret);
11873 send_resp(dut, conn, SIGMA_ERROR,
11874 "errorCode,snprintf failed for subelement");
11875 return 0;
11876 }
11877 }
11878
11879 if (!dut->btm_query_cand_list) {
11880 dut->btm_query_cand_list = calloc(1, NEIGHBOR_REPORT_SIZE);
11881 if (!dut->btm_query_cand_list) {
11882 send_resp(dut, conn, SIGMA_ERROR,
11883 "errorCode,Failed to allocate memory for btm_query_cand_list");
11884 return 0;
11885 }
11886 }
11887
11888 len = strlen(dut->btm_query_cand_list);
11889 ret = snprintf(dut->btm_query_cand_list + len,
11890 NEIGHBOR_REPORT_SIZE - len, " neighbor=%s,%s,%s,%s,%s%s",
11891 bssid, info, op_class, ch, phy_type, buf);
11892 if (ret < 0 || ret >= NEIGHBOR_REPORT_SIZE - len) {
11893 sigma_dut_print(dut, DUT_MSG_ERROR,
11894 "snprintf failed for neighbor report list ret: %d",
11895 ret);
11896 send_resp(dut, conn, SIGMA_ERROR,
11897 "errorCode,snprintf failed for neighbor report");
11898 free(dut->btm_query_cand_list);
11899 dut->btm_query_cand_list = NULL;
11900 return 0;
11901 }
11902
11903 return 1;
11904}
11905
11906
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020011907int sta_extract_60g_ese(struct sigma_dut *dut, struct sigma_cmd *cmd,
11908 struct sigma_ese_alloc *allocs, int *allocs_size)
11909{
11910 int max_count = *allocs_size;
11911 int count = 0, i;
11912 const char *val;
11913
11914 do {
11915 val = get_param_indexed(cmd, "AllocID", count);
11916 if (val)
11917 count++;
11918 } while (val);
11919
11920 if (count == 0 || count > max_count) {
11921 sigma_dut_print(dut, DUT_MSG_ERROR,
11922 "Invalid number of allocations(%d)", count);
11923 return -1;
11924 }
11925
11926 for (i = 0; i < count; i++) {
11927 val = get_param_indexed(cmd, "PercentBI", i);
11928 if (!val) {
11929 sigma_dut_print(dut, DUT_MSG_ERROR,
11930 "Missing PercentBI parameter at index %d",
11931 i);
11932 return -1;
11933 }
11934 allocs[i].percent_bi = atoi(val);
11935
11936 val = get_param_indexed(cmd, "SrcAID", i);
11937 if (val)
11938 allocs[i].src_aid = strtol(val, NULL, 0);
11939 else
11940 allocs[i].src_aid = ESE_BCAST_AID;
11941
11942 val = get_param_indexed(cmd, "DestAID", i);
11943 if (val)
11944 allocs[i].dst_aid = strtol(val, NULL, 0);
11945 else
11946 allocs[i].dst_aid = ESE_BCAST_AID;
11947
11948 allocs[i].type = ESE_CBAP;
11949 sigma_dut_print(dut, DUT_MSG_INFO,
11950 "Alloc %d PercentBI %d SrcAID %d DstAID %d",
11951 i, allocs[i].percent_bi, allocs[i].src_aid,
11952 allocs[i].dst_aid);
11953 }
11954
11955 *allocs_size = count;
11956 return 0;
11957}
11958
11959
11960static int sta_set_60g_ese(struct sigma_dut *dut, int count,
11961 struct sigma_ese_alloc *allocs)
11962{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011963 switch (get_driver_type(dut)) {
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020011964#ifdef __linux__
11965 case DRIVER_WIL6210:
11966 if (wil6210_set_ese(dut, count, allocs))
11967 return -1;
11968 return 1;
11969#endif /* __linux__ */
11970 default:
11971 sigma_dut_print(dut, DUT_MSG_ERROR,
11972 "Unsupported sta_set_60g_ese with the current driver");
11973 return -1;
11974 }
11975}
11976
11977
11978static int cmd_sta_set_rfeature_60g(const char *intf, struct sigma_dut *dut,
11979 struct sigma_conn *conn,
11980 struct sigma_cmd *cmd)
11981{
11982 const char *val;
11983
11984 val = get_param(cmd, "ExtSchIE");
11985 if (val && !strcasecmp(val, "Enable")) {
11986 struct sigma_ese_alloc allocs[MAX_ESE_ALLOCS];
11987 int count = MAX_ESE_ALLOCS;
11988
11989 if (sta_extract_60g_ese(dut, cmd, allocs, &count))
11990 return -1;
11991 return sta_set_60g_ese(dut, count, allocs);
11992 }
11993
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +020011994 val = get_param(cmd, "MCS_FixedRate");
11995 if (val) {
11996 int sta_mcs = atoi(val);
11997
11998 sigma_dut_print(dut, DUT_MSG_INFO, "Force STA MCS to %d",
11999 sta_mcs);
12000 wil6210_set_force_mcs(dut, 1, sta_mcs);
12001
Jouni Malinen0e29cf22019-02-19 01:13:21 +020012002 return SUCCESS_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +020012003 }
12004
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020012005 send_resp(dut, conn, SIGMA_ERROR,
12006 "errorCode,Invalid sta_set_rfeature(60G)");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020012007 return STATUS_SENT;
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020012008}
12009
12010
Jouni Malinenf7222712019-06-13 01:50:21 +030012011static enum sigma_cmd_result cmd_sta_set_rfeature(struct sigma_dut *dut,
12012 struct sigma_conn *conn,
12013 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012014{
12015 const char *intf = get_param(cmd, "Interface");
12016 const char *prog = get_param(cmd, "Prog");
Ashwini Patil68d02cd2017-01-10 15:39:16 +053012017 const char *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012018
12019 if (intf == NULL || prog == NULL)
12020 return -1;
12021
Ashwini Patil5acd7382017-04-13 15:55:04 +053012022 /* BSS Transition candidate list for BTM query */
12023 val = get_param(cmd, "Nebor_BSSID");
12024 if (val && btm_query_candidate_list(dut, conn, cmd) == 0)
12025 return 0;
12026
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012027 if (strcasecmp(prog, "TDLS") == 0)
12028 return cmd_sta_set_rfeature_tdls(intf, dut, conn, cmd);
12029
12030 if (strcasecmp(prog, "VHT") == 0)
12031 return cmd_sta_set_rfeature_vht(intf, dut, conn, cmd);
12032
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080012033 if (strcasecmp(prog, "HE") == 0)
12034 return cmd_sta_set_rfeature_he(intf, dut, conn, cmd);
12035
Ashwini Patil68d02cd2017-01-10 15:39:16 +053012036 if (strcasecmp(prog, "MBO") == 0) {
12037 val = get_param(cmd, "Cellular_Data_Cap");
12038 if (val &&
12039 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
12040 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +053012041
12042 val = get_param(cmd, "Ch_Pref");
12043 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
12044 return 0;
12045
Ashwini Patil68d02cd2017-01-10 15:39:16 +053012046 return 1;
12047 }
12048
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020012049 if (strcasecmp(prog, "60GHz") == 0)
12050 return cmd_sta_set_rfeature_60g(intf, dut, conn, cmd);
12051
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012052 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported Prog");
12053 return 0;
12054}
12055
12056
Jouni Malinenf7222712019-06-13 01:50:21 +030012057static enum sigma_cmd_result cmd_sta_set_radio(struct sigma_dut *dut,
12058 struct sigma_conn *conn,
12059 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012060{
12061 const char *intf = get_param(cmd, "Interface");
12062 const char *mode = get_param(cmd, "Mode");
12063 int res;
12064
12065 if (intf == NULL || mode == NULL)
12066 return -1;
12067
12068 if (strcasecmp(mode, "On") == 0)
12069 res = wpa_command(intf, "SET radio_disabled 0");
12070 else if (strcasecmp(mode, "Off") == 0)
12071 res = wpa_command(intf, "SET radio_disabled 1");
12072 else
12073 return -1;
12074
12075 if (res) {
12076 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
12077 "radio mode");
12078 return 0;
12079 }
12080
12081 return 1;
12082}
12083
12084
Jouni Malinenf7222712019-06-13 01:50:21 +030012085static enum sigma_cmd_result cmd_sta_set_pwrsave(struct sigma_dut *dut,
12086 struct sigma_conn *conn,
12087 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012088{
12089 const char *intf = get_param(cmd, "Interface");
12090 const char *mode = get_param(cmd, "Mode");
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020012091 const char *prog = get_param(cmd, "program");
12092 const char *powersave = get_param(cmd, "powersave");
12093 int res = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012094
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020012095 if (intf == NULL)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012096 return -1;
12097
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020012098 if (prog && strcasecmp(prog, "60GHz") == 0) {
12099 /*
12100 * The CAPI mode parameter does not exist in 60G
12101 * unscheduled PS.
12102 */
Hu Wang5dc3ff12019-06-14 15:14:26 +080012103 if (powersave && strcasecmp(powersave, "unscheduled") == 0)
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020012104 res = set_ps(intf, dut, 1);
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012105 } else if (prog && get_driver_type(dut) == DRIVER_WCN &&
Alexei Avshalom Lazar2f6fdb42019-02-04 14:16:08 +020012106 strcasecmp(prog, "HE") == 0) {
12107 return cmd_sta_set_power_save_he(intf, dut, conn, cmd);
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020012108 } else {
12109 if (mode == NULL)
12110 return -1;
12111
12112 if (strcasecmp(mode, "On") == 0)
12113 res = set_ps(intf, dut, 1);
12114 else if (strcasecmp(mode, "Off") == 0)
12115 res = set_ps(intf, dut, 0);
12116 else
12117 return -1;
12118 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012119
12120 if (res) {
12121 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
12122 "power save mode");
12123 return 0;
12124 }
12125
12126 return 1;
12127}
12128
12129
Jouni Malinenf7222712019-06-13 01:50:21 +030012130static enum sigma_cmd_result cmd_sta_bssid_pool(struct sigma_dut *dut,
12131 struct sigma_conn *conn,
12132 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012133{
12134 const char *intf = get_param(cmd, "Interface");
12135 const char *val, *bssid;
12136 int res;
12137 char *buf;
12138 size_t buf_len;
12139
12140 val = get_param(cmd, "BSSID_FILTER");
12141 if (val == NULL)
12142 return -1;
12143
12144 bssid = get_param(cmd, "BSSID_List");
12145 if (atoi(val) == 0 || bssid == NULL) {
12146 /* Disable BSSID filter */
12147 if (wpa_command(intf, "SET bssid_filter ")) {
12148 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed "
12149 "to disable BSSID filter");
12150 return 0;
12151 }
12152
12153 return 1;
12154 }
12155
12156 buf_len = 100 + strlen(bssid);
12157 buf = malloc(buf_len);
12158 if (buf == NULL)
12159 return -1;
12160
12161 snprintf(buf, buf_len, "SET bssid_filter %s", bssid);
12162 res = wpa_command(intf, buf);
12163 free(buf);
12164 if (res) {
12165 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to enable "
12166 "BSSID filter");
12167 return 0;
12168 }
12169
12170 return 1;
12171}
12172
12173
Jouni Malinenf7222712019-06-13 01:50:21 +030012174static enum sigma_cmd_result cmd_sta_reset_parm(struct sigma_dut *dut,
12175 struct sigma_conn *conn,
12176 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012177{
12178 const char *intf = get_param(cmd, "Interface");
12179 const char *val;
12180
12181 /* TODO: ARP */
12182
12183 val = get_param(cmd, "HS2_CACHE_PROFILE");
12184 if (val && strcasecmp(val, "All") == 0)
12185 hs2_clear_credentials(intf);
12186
12187 return 1;
12188}
12189
12190
Jouni Malinenf7222712019-06-13 01:50:21 +030012191static enum sigma_cmd_result cmd_sta_get_key(struct sigma_dut *dut,
12192 struct sigma_conn *conn,
12193 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012194{
12195 const char *intf = get_param(cmd, "Interface");
12196 const char *key_type = get_param(cmd, "KeyType");
12197 char buf[100], resp[200];
12198
12199 if (key_type == NULL)
12200 return -1;
12201
12202 if (strcasecmp(key_type, "GTK") == 0) {
12203 if (wpa_command_resp(intf, "GET gtk", buf, sizeof(buf)) < 0 ||
12204 strncmp(buf, "FAIL", 4) == 0) {
12205 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12206 "not fetch current GTK");
12207 return 0;
12208 }
12209 snprintf(resp, sizeof(resp), "KeyValue,%s", buf);
12210 send_resp(dut, conn, SIGMA_COMPLETE, resp);
12211 return 0;
12212 } else {
12213 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
12214 "KeyType");
12215 return 0;
12216 }
12217
12218 return 1;
12219}
12220
12221
12222static int hs2_set_policy(struct sigma_dut *dut)
12223{
12224#ifdef ANDROID
12225 system("ip rule del prio 23000");
12226 if (system("ip rule add from all lookup main prio 23000") != 0) {
12227 sigma_dut_print(dut, DUT_MSG_ERROR,
12228 "Failed to run:ip rule add from all lookup main prio");
12229 return -1;
12230 }
12231 if (system("ip route flush cache") != 0) {
12232 sigma_dut_print(dut, DUT_MSG_ERROR,
12233 "Failed to run ip route flush cache");
12234 return -1;
12235 }
12236 return 1;
12237#else /* ANDROID */
12238 return 0;
12239#endif /* ANDROID */
12240}
12241
12242
Jouni Malinenf7222712019-06-13 01:50:21 +030012243static enum sigma_cmd_result cmd_sta_hs2_associate(struct sigma_dut *dut,
12244 struct sigma_conn *conn,
12245 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012246{
12247 const char *intf = get_param(cmd, "Interface");
12248 const char *val = get_param(cmd, "Ignore_blacklist");
Jouni Malinen439352d2018-09-13 03:42:23 +030012249 const char *band = get_param(cmd, "Band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012250 struct wpa_ctrl *ctrl;
Jouni Malinen3aa72862019-05-29 23:14:51 +030012251 int res, r;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012252 char bssid[20], ssid[40], resp[100], buf[100], blacklisted[100];
12253 int tries = 0;
12254 int ignore_blacklist = 0;
12255 const char *events[] = {
12256 "CTRL-EVENT-CONNECTED",
12257 "INTERWORKING-BLACKLISTED",
12258 "INTERWORKING-NO-MATCH",
12259 NULL
12260 };
12261
12262 start_sta_mode(dut);
12263
Jouni Malinen439352d2018-09-13 03:42:23 +030012264 if (band) {
12265 if (strcmp(band, "2.4") == 0) {
12266 wpa_command(intf, "SET setband 2G");
12267 } else if (strcmp(band, "5") == 0) {
12268 wpa_command(intf, "SET setband 5G");
12269 } else {
12270 send_resp(dut, conn, SIGMA_ERROR,
12271 "errorCode,Unsupported band");
12272 return 0;
12273 }
12274 }
12275
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012276 blacklisted[0] = '\0';
12277 if (val && atoi(val))
12278 ignore_blacklist = 1;
12279
12280try_again:
12281 ctrl = open_wpa_mon(intf);
12282 if (ctrl == NULL) {
12283 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
12284 "wpa_supplicant monitor connection");
12285 return -2;
12286 }
12287
12288 tries++;
12289 if (wpa_command(intf, "INTERWORKING_SELECT auto")) {
12290 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start "
12291 "Interworking connection");
12292 wpa_ctrl_detach(ctrl);
12293 wpa_ctrl_close(ctrl);
12294 return 0;
12295 }
12296
12297 buf[0] = '\0';
12298 while (1) {
12299 char *pos;
12300 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
12301 pos = strstr(buf, "INTERWORKING-BLACKLISTED");
12302 if (!pos)
12303 break;
12304 pos += 25;
12305 sigma_dut_print(dut, DUT_MSG_DEBUG, "Found blacklisted AP: %s",
12306 pos);
12307 if (!blacklisted[0])
12308 memcpy(blacklisted, pos, strlen(pos) + 1);
12309 }
12310
12311 if (ignore_blacklist && blacklisted[0]) {
12312 char *end;
12313 end = strchr(blacklisted, ' ');
12314 if (end)
12315 *end = '\0';
12316 sigma_dut_print(dut, DUT_MSG_DEBUG, "Try to connect to a blacklisted network: %s",
12317 blacklisted);
Jouni Malinen3aa72862019-05-29 23:14:51 +030012318 r = snprintf(buf, sizeof(buf), "INTERWORKING_CONNECT %s",
12319 blacklisted);
12320 if (r < 0 || r >= sizeof(buf) || wpa_command(intf, buf)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012321 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start Interworking connection to blacklisted network");
12322 wpa_ctrl_detach(ctrl);
12323 wpa_ctrl_close(ctrl);
12324 return 0;
12325 }
12326 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
12327 buf, sizeof(buf));
12328 }
12329
12330 wpa_ctrl_detach(ctrl);
12331 wpa_ctrl_close(ctrl);
12332
12333 if (res < 0) {
12334 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
12335 "connect");
12336 return 0;
12337 }
12338
12339 if (strstr(buf, "INTERWORKING-NO-MATCH") ||
12340 strstr(buf, "INTERWORKING-BLACKLISTED")) {
12341 if (tries < 2) {
12342 sigma_dut_print(dut, DUT_MSG_INFO, "No match found - try again to verify no APs were missed in the scan");
12343 goto try_again;
12344 }
12345 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,No network with "
12346 "matching credentials found");
12347 return 0;
12348 }
12349
12350 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
12351 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
12352 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
12353 "get current BSSID/SSID");
12354 return 0;
12355 }
12356
12357 snprintf(resp, sizeof(resp), "SSID,%s,BSSID,%s", ssid, bssid);
12358 send_resp(dut, conn, SIGMA_COMPLETE, resp);
12359 hs2_set_policy(dut);
12360 return 0;
12361}
12362
12363
Jouni Malinenf7222712019-06-13 01:50:21 +030012364static enum sigma_cmd_result cmd_sta_hs2_venue_info(struct sigma_dut *dut,
12365 struct sigma_conn *conn,
12366 struct sigma_cmd *cmd)
Jouni Malinenb639f1c2018-09-13 02:39:46 +030012367{
12368 const char *intf = get_param(cmd, "Interface");
12369 const char *display = get_param(cmd, "Display");
12370 struct wpa_ctrl *ctrl;
12371 char buf[300], params[400], *pos;
12372 char bssid[20];
12373 int info_avail = 0;
12374 unsigned int old_timeout;
12375 int res;
12376
12377 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0) {
12378 send_resp(dut, conn, SIGMA_ERROR,
12379 "ErrorCode,Could not get current BSSID");
12380 return 0;
12381 }
12382 ctrl = open_wpa_mon(intf);
12383 if (!ctrl) {
12384 sigma_dut_print(dut, DUT_MSG_ERROR,
12385 "Failed to open wpa_supplicant monitor connection");
12386 return -2;
12387 }
12388
12389 snprintf(buf, sizeof(buf), "ANQP_GET %s 277", bssid);
12390 wpa_command(intf, buf);
12391
12392 res = get_wpa_cli_event(dut, ctrl, "GAS-QUERY-DONE", buf, sizeof(buf));
12393 if (res < 0) {
12394 send_resp(dut, conn, SIGMA_ERROR,
12395 "ErrorCode,Could not complete GAS query");
12396 goto fail;
12397 }
12398
12399 old_timeout = dut->default_timeout;
12400 dut->default_timeout = 2;
12401 res = get_wpa_cli_event(dut, ctrl, "RX-VENUE-URL", buf, sizeof(buf));
12402 dut->default_timeout = old_timeout;
12403 if (res < 0)
12404 goto done;
12405 pos = strchr(buf, ' ');
12406 if (!pos)
12407 goto done;
12408 pos++;
12409 pos = strchr(pos, ' ');
12410 if (!pos)
12411 goto done;
12412 pos++;
12413 info_avail = 1;
12414 snprintf(params, sizeof(params), "browser %s", pos);
12415
12416 if (display && strcasecmp(display, "Yes") == 0) {
12417 pid_t pid;
12418
12419 pid = fork();
12420 if (pid < 0) {
12421 perror("fork");
12422 return -1;
12423 }
12424
12425 if (pid == 0) {
12426 run_hs20_osu(dut, params);
12427 exit(0);
12428 }
12429 }
12430
12431done:
12432 snprintf(buf, sizeof(buf), "Info_available,%s",
12433 info_avail ? "Yes" : "No");
12434 send_resp(dut, conn, SIGMA_COMPLETE, buf);
12435fail:
12436 wpa_ctrl_detach(ctrl);
12437 wpa_ctrl_close(ctrl);
12438 return 0;
12439}
12440
12441
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012442static int sta_add_credential_uname_pwd(struct sigma_dut *dut,
12443 struct sigma_conn *conn,
12444 const char *ifname,
12445 struct sigma_cmd *cmd)
12446{
12447 const char *val;
12448 int id;
12449
12450 id = add_cred(ifname);
12451 if (id < 0)
12452 return -2;
12453 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
12454
12455 val = get_param(cmd, "prefer");
12456 if (val && atoi(val) > 0)
12457 set_cred(ifname, id, "priority", "1");
12458
12459 val = get_param(cmd, "REALM");
12460 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
12461 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12462 "realm");
12463 return 0;
12464 }
12465
12466 val = get_param(cmd, "HOME_FQDN");
12467 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
12468 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12469 "home_fqdn");
12470 return 0;
12471 }
12472
12473 val = get_param(cmd, "Username");
12474 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
12475 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12476 "username");
12477 return 0;
12478 }
12479
12480 val = get_param(cmd, "Password");
12481 if (val && set_cred_quoted(ifname, id, "password", val) < 0) {
12482 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12483 "password");
12484 return 0;
12485 }
12486
12487 val = get_param(cmd, "ROOT_CA");
12488 if (val) {
12489 char fname[200];
12490 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
12491#ifdef __linux__
12492 if (!file_exists(fname)) {
12493 char msg[300];
12494 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
12495 "file (%s) not found", fname);
12496 send_resp(dut, conn, SIGMA_ERROR, msg);
12497 return 0;
12498 }
12499#endif /* __linux__ */
12500 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
12501 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12502 "not set root CA");
12503 return 0;
12504 }
12505 }
12506
12507 return 1;
12508}
12509
12510
12511static int update_devdetail_imsi(struct sigma_dut *dut, const char *imsi)
12512{
12513 FILE *in, *out;
12514 char buf[500];
12515 int found = 0;
12516
12517 in = fopen("devdetail.xml", "r");
12518 if (in == NULL)
12519 return -1;
12520 out = fopen("devdetail.xml.tmp", "w");
12521 if (out == NULL) {
12522 fclose(in);
12523 return -1;
12524 }
12525
12526 while (fgets(buf, sizeof(buf), in)) {
12527 char *pos = strstr(buf, "<IMSI>");
12528 if (pos) {
12529 sigma_dut_print(dut, DUT_MSG_INFO, "Updated DevDetail IMSI to %s",
12530 imsi);
12531 pos += 6;
12532 *pos = '\0';
12533 fprintf(out, "%s%s</IMSI>\n", buf, imsi);
12534 found++;
12535 } else {
12536 fprintf(out, "%s", buf);
12537 }
12538 }
12539
12540 fclose(out);
12541 fclose(in);
12542 if (found)
12543 rename("devdetail.xml.tmp", "devdetail.xml");
12544 else
12545 unlink("devdetail.xml.tmp");
12546
12547 return 0;
12548}
12549
12550
12551static int sta_add_credential_sim(struct sigma_dut *dut,
12552 struct sigma_conn *conn,
12553 const char *ifname, struct sigma_cmd *cmd)
12554{
12555 const char *val, *imsi = NULL;
12556 int id;
12557 char buf[200];
12558 int res;
12559 const char *pos;
12560 size_t mnc_len;
12561 char plmn_mcc[4];
12562 char plmn_mnc[4];
12563
12564 id = add_cred(ifname);
12565 if (id < 0)
12566 return -2;
12567 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
12568
12569 val = get_param(cmd, "prefer");
12570 if (val && atoi(val) > 0)
12571 set_cred(ifname, id, "priority", "1");
12572
12573 val = get_param(cmd, "PLMN_MCC");
12574 if (val == NULL) {
12575 send_resp(dut, conn, SIGMA_ERROR,
12576 "errorCode,Missing PLMN_MCC");
12577 return 0;
12578 }
12579 if (strlen(val) != 3) {
12580 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MCC");
12581 return 0;
12582 }
12583 snprintf(plmn_mcc, sizeof(plmn_mcc), "%s", val);
12584
12585 val = get_param(cmd, "PLMN_MNC");
12586 if (val == NULL) {
12587 send_resp(dut, conn, SIGMA_ERROR,
12588 "errorCode,Missing PLMN_MNC");
12589 return 0;
12590 }
12591 if (strlen(val) != 2 && strlen(val) != 3) {
12592 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MNC");
12593 return 0;
12594 }
12595 snprintf(plmn_mnc, sizeof(plmn_mnc), "%s", val);
12596
12597 val = get_param(cmd, "IMSI");
12598 if (val == NULL) {
12599 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing SIM "
12600 "IMSI");
12601 return 0;
12602 }
12603
12604 imsi = pos = val;
12605
12606 if (strncmp(plmn_mcc, pos, 3) != 0) {
12607 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MCC mismatch");
12608 return 0;
12609 }
12610 pos += 3;
12611
12612 mnc_len = strlen(plmn_mnc);
12613 if (mnc_len < 2) {
12614 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC not set");
12615 return 0;
12616 }
12617
12618 if (strncmp(plmn_mnc, pos, mnc_len) != 0) {
12619 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC mismatch");
12620 return 0;
12621 }
12622 pos += mnc_len;
12623
12624 res = snprintf(buf, sizeof(buf), "%s%s-%s",plmn_mcc, plmn_mnc, pos);
12625 if (res < 0 || res >= (int) sizeof(buf))
12626 return -1;
12627 if (set_cred_quoted(ifname, id, "imsi", buf) < 0) {
12628 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12629 "not set IMSI");
12630 return 0;
12631 }
12632
12633 val = get_param(cmd, "Password");
12634 if (val && set_cred_quoted(ifname, id, "milenage", val) < 0) {
12635 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12636 "not set password");
12637 return 0;
12638 }
12639
Jouni Malinenba630452018-06-22 11:49:59 +030012640 if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012641 /*
12642 * Set provisioning_sp for the test cases where SIM/USIM
12643 * provisioning is used.
12644 */
12645 if (val && set_cred_quoted(ifname, id, "provisioning_sp",
12646 "wi-fi.org") < 0) {
12647 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12648 "not set provisioning_sp");
12649 return 0;
12650 }
12651
12652 update_devdetail_imsi(dut, imsi);
12653 }
12654
12655 return 1;
12656}
12657
12658
12659static int sta_add_credential_cert(struct sigma_dut *dut,
12660 struct sigma_conn *conn,
12661 const char *ifname,
12662 struct sigma_cmd *cmd)
12663{
12664 const char *val;
12665 int id;
12666
12667 id = add_cred(ifname);
12668 if (id < 0)
12669 return -2;
12670 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
12671
12672 val = get_param(cmd, "prefer");
12673 if (val && atoi(val) > 0)
12674 set_cred(ifname, id, "priority", "1");
12675
12676 val = get_param(cmd, "REALM");
12677 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
12678 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12679 "realm");
12680 return 0;
12681 }
12682
12683 val = get_param(cmd, "HOME_FQDN");
12684 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
12685 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12686 "home_fqdn");
12687 return 0;
12688 }
12689
12690 val = get_param(cmd, "Username");
12691 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
12692 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12693 "username");
12694 return 0;
12695 }
12696
12697 val = get_param(cmd, "clientCertificate");
12698 if (val) {
12699 char fname[200];
12700 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
12701#ifdef __linux__
12702 if (!file_exists(fname)) {
12703 char msg[300];
12704 snprintf(msg, sizeof(msg),
12705 "ErrorCode,clientCertificate "
12706 "file (%s) not found", fname);
12707 send_resp(dut, conn, SIGMA_ERROR, msg);
12708 return 0;
12709 }
12710#endif /* __linux__ */
12711 if (set_cred_quoted(ifname, id, "client_cert", fname) < 0) {
12712 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12713 "not set client_cert");
12714 return 0;
12715 }
12716 if (set_cred_quoted(ifname, id, "private_key", fname) < 0) {
12717 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12718 "not set private_key");
12719 return 0;
12720 }
12721 }
12722
12723 val = get_param(cmd, "ROOT_CA");
12724 if (val) {
12725 char fname[200];
12726 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
12727#ifdef __linux__
12728 if (!file_exists(fname)) {
12729 char msg[300];
12730 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
12731 "file (%s) not found", fname);
12732 send_resp(dut, conn, SIGMA_ERROR, msg);
12733 return 0;
12734 }
12735#endif /* __linux__ */
12736 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
12737 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12738 "not set root CA");
12739 return 0;
12740 }
12741 }
12742
12743 return 1;
12744}
12745
12746
Jouni Malinenf7222712019-06-13 01:50:21 +030012747static enum sigma_cmd_result cmd_sta_add_credential(struct sigma_dut *dut,
12748 struct sigma_conn *conn,
12749 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012750{
12751 const char *intf = get_param(cmd, "Interface");
12752 const char *type;
12753
12754 start_sta_mode(dut);
12755
12756 type = get_param(cmd, "Type");
12757 if (!type)
12758 return -1;
12759
12760 if (strcasecmp(type, "uname_pwd") == 0)
12761 return sta_add_credential_uname_pwd(dut, conn, intf, cmd);
12762
12763 if (strcasecmp(type, "sim") == 0)
12764 return sta_add_credential_sim(dut, conn, intf, cmd);
12765
12766 if (strcasecmp(type, "cert") == 0)
12767 return sta_add_credential_cert(dut, conn, intf, cmd);
12768
12769 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported credential "
12770 "type");
12771 return 0;
12772}
12773
12774
Jouni Malinenf7222712019-06-13 01:50:21 +030012775static enum sigma_cmd_result cmd_sta_scan(struct sigma_dut *dut,
12776 struct sigma_conn *conn,
12777 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012778{
12779 const char *intf = get_param(cmd, "Interface");
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080012780 const char *val, *bssid, *ssid, *scan_freq, *short_ssid;
Arif Hussain66a4af02019-02-07 15:04:51 -080012781 char buf[4096];
vamsi krishna89ad8c62017-09-19 12:51:18 +053012782 char ssid_hex[65];
Kiran Kumar Lokere3399af22020-03-04 16:31:56 -080012783 int wildcard_ssid = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012784 int res;
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080012785 enum sigma_cmd_result status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012786
Jouni Malinen8c1abeb2019-11-06 18:48:34 +020012787 start_sta_mode(dut);
12788
Arif Hussain66a4af02019-02-07 15:04:51 -080012789 val = get_param(cmd, "GetParameter");
12790 if (val && strcmp(val, "SSID_BSSID") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012791 if (get_wpa_ssid_bssid(dut, get_station_ifname(dut),
Arif Hussain66a4af02019-02-07 15:04:51 -080012792 buf, sizeof(buf)) < 0) {
12793 sigma_dut_print(dut, DUT_MSG_ERROR,
12794 "Could not get ssid bssid");
12795 return ERROR_SEND_STATUS;
12796 }
12797
12798 sigma_dut_print(dut, DUT_MSG_INFO, "%s", buf);
12799 send_resp(dut, conn, SIGMA_COMPLETE, buf);
12800 return STATUS_SENT;
12801 }
12802
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012803 val = get_param(cmd, "HESSID");
12804 if (val) {
12805 res = snprintf(buf, sizeof(buf), "SET hessid %s", val);
12806 if (res < 0 || res >= (int) sizeof(buf))
12807 return -1;
12808 wpa_command(intf, buf);
12809 }
12810
12811 val = get_param(cmd, "ACCS_NET_TYPE");
12812 if (val) {
12813 res = snprintf(buf, sizeof(buf), "SET access_network_type %s",
12814 val);
12815 if (res < 0 || res >= (int) sizeof(buf))
12816 return -1;
12817 wpa_command(intf, buf);
12818 }
12819
vamsi krishna89ad8c62017-09-19 12:51:18 +053012820 bssid = get_param(cmd, "Bssid");
12821 ssid = get_param(cmd, "Ssid");
12822
Kiran Kumar Lokere3399af22020-03-04 16:31:56 -080012823 if (ssid && strcasecmp(ssid, "ZeroLength") == 0 &&
12824 dut->device_type == STA_testbed) {
12825 ssid = NULL;
12826 wildcard_ssid = 1;
12827 }
12828
vamsi krishna89ad8c62017-09-19 12:51:18 +053012829 if (ssid) {
12830 if (2 * strlen(ssid) >= sizeof(ssid_hex)) {
12831 send_resp(dut, conn, SIGMA_ERROR,
12832 "ErrorCode,Too long SSID");
12833 return 0;
12834 }
12835 ascii2hexstr(ssid, ssid_hex);
12836 }
12837
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080012838 short_ssid = get_param(cmd, "ShortSSID");
12839 if (short_ssid) {
12840 uint32_t short_ssid_hex;
12841
12842 short_ssid_hex = strtoul(short_ssid, NULL, 16);
12843 short_ssid_hex = ((short_ssid_hex & 0xFF) << 24) |
12844 (((short_ssid_hex >> 8) & 0xFF) << 16) |
12845 (((short_ssid_hex >> 16) & 0xFF) << 8) |
12846 ((short_ssid_hex >> 24) & 0xFF);
12847
12848 res = snprintf(buf, sizeof(buf),
12849 "VENDOR_ELEM_ADD 14 ff053a%08x",
12850 short_ssid_hex);
12851 if (res < 0 || res >= (int) sizeof(buf) ||
12852 wpa_command(intf, buf)) {
12853 send_resp(dut, conn, SIGMA_ERROR,
12854 "errorCode,Failed to add short SSID");
12855 return STATUS_SENT_ERROR;
12856 }
12857 }
12858
Kiran Kumar Lokerec0deb482020-03-04 16:35:06 -080012859 scan_freq = get_param(cmd, "ChnlFreq");
12860
12861 res = snprintf(buf, sizeof(buf), "SCAN%s%s%s%s%s%s%s",
vamsi krishna89ad8c62017-09-19 12:51:18 +053012862 bssid ? " bssid=": "",
12863 bssid ? bssid : "",
12864 ssid ? " ssid " : "",
Kiran Kumar Lokere3399af22020-03-04 16:31:56 -080012865 ssid ? ssid_hex : "",
Kiran Kumar Lokerec0deb482020-03-04 16:35:06 -080012866 wildcard_ssid ? " wildcard_ssid=1" : "",
12867 scan_freq ? " freq=" : "",
12868 scan_freq ? scan_freq : "");
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080012869 if (res < 0 || res >= (int) sizeof(buf)) {
12870 send_resp(dut, conn, SIGMA_ERROR,
12871 "errorCode,Could not build scan command");
12872 status = STATUS_SENT_ERROR;
12873 goto remove_s_ssid;
12874 }
vamsi krishna89ad8c62017-09-19 12:51:18 +053012875
12876 if (wpa_command(intf, buf)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012877 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not start "
12878 "scan");
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080012879 status = STATUS_SENT_ERROR;
12880 } else {
12881 status = SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012882 }
12883
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080012884remove_s_ssid:
12885 if (short_ssid && wpa_command(intf, "VENDOR_ELEM_REMOVE 14 *"))
12886 sigma_dut_print(dut, DUT_MSG_ERROR,
12887 "Failed to delete vendor element");
12888
12889 return status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012890}
12891
12892
Jouni Malinenf7222712019-06-13 01:50:21 +030012893static enum sigma_cmd_result cmd_sta_scan_bss(struct sigma_dut *dut,
12894 struct sigma_conn *conn,
12895 struct sigma_cmd *cmd)
Jouni Malinen5e5d43d2018-01-10 17:29:33 +020012896{
12897 const char *intf = get_param(cmd, "Interface");
12898 const char *bssid;
12899 char buf[4096], *pos;
12900 int freq, chan;
12901 char *ssid;
12902 char resp[100];
12903 int res;
12904 struct wpa_ctrl *ctrl;
12905
12906 bssid = get_param(cmd, "BSSID");
12907 if (!bssid) {
12908 send_resp(dut, conn, SIGMA_INVALID,
12909 "errorCode,BSSID argument is missing");
12910 return 0;
12911 }
12912
12913 ctrl = open_wpa_mon(intf);
12914 if (!ctrl) {
12915 sigma_dut_print(dut, DUT_MSG_ERROR,
12916 "Failed to open wpa_supplicant monitor connection");
12917 return -1;
12918 }
12919
12920 if (wpa_command(intf, "SCAN TYPE=ONLY")) {
12921 send_resp(dut, conn, SIGMA_ERROR,
12922 "errorCode,Could not start scan");
12923 wpa_ctrl_detach(ctrl);
12924 wpa_ctrl_close(ctrl);
12925 return 0;
12926 }
12927
12928 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
12929 buf, sizeof(buf));
12930
12931 wpa_ctrl_detach(ctrl);
12932 wpa_ctrl_close(ctrl);
12933
12934 if (res < 0) {
12935 send_resp(dut, conn, SIGMA_ERROR,
12936 "errorCode,Scan did not complete");
12937 return 0;
12938 }
12939
12940 snprintf(buf, sizeof(buf), "BSS %s", bssid);
12941 if (wpa_command_resp(intf, buf, buf, sizeof(buf)) < 0 ||
12942 strncmp(buf, "id=", 3) != 0) {
12943 send_resp(dut, conn, SIGMA_ERROR,
12944 "errorCode,Specified BSSID not found");
12945 return 0;
12946 }
12947
12948 pos = strstr(buf, "\nfreq=");
12949 if (!pos) {
12950 send_resp(dut, conn, SIGMA_ERROR,
12951 "errorCode,Channel not found");
12952 return 0;
12953 }
12954 freq = atoi(pos + 6);
12955 chan = freq_to_channel(freq);
12956
12957 pos = strstr(buf, "\nssid=");
12958 if (!pos) {
12959 send_resp(dut, conn, SIGMA_ERROR,
12960 "errorCode,SSID not found");
12961 return 0;
12962 }
12963 ssid = pos + 6;
12964 pos = strchr(ssid, '\n');
12965 if (pos)
12966 *pos = '\0';
12967 snprintf(resp, sizeof(resp), "ssid,%s,bsschannel,%d", ssid, chan);
12968 send_resp(dut, conn, SIGMA_COMPLETE, resp);
12969 return 0;
12970}
12971
12972
Jouni Malinenf7222712019-06-13 01:50:21 +030012973static enum sigma_cmd_result cmd_sta_set_systime(struct sigma_dut *dut,
12974 struct sigma_conn *conn,
12975 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012976{
12977#ifdef __linux__
12978 struct timeval tv;
12979 struct tm tm;
12980 time_t t;
12981 const char *val;
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +053012982 int v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012983
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012984 wpa_command(get_station_ifname(dut), "PMKSA_FLUSH");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012985
12986 memset(&tm, 0, sizeof(tm));
12987 val = get_param(cmd, "seconds");
12988 if (val)
12989 tm.tm_sec = atoi(val);
12990 val = get_param(cmd, "minutes");
12991 if (val)
12992 tm.tm_min = atoi(val);
12993 val = get_param(cmd, "hours");
12994 if (val)
12995 tm.tm_hour = atoi(val);
12996 val = get_param(cmd, "date");
12997 if (val)
12998 tm.tm_mday = atoi(val);
12999 val = get_param(cmd, "month");
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +053013000 if (val) {
13001 v = atoi(val);
13002 if (v < 1 || v > 12) {
13003 send_resp(dut, conn, SIGMA_INVALID,
13004 "errorCode,Invalid month");
13005 return 0;
13006 }
13007 tm.tm_mon = v - 1;
13008 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013009 val = get_param(cmd, "year");
13010 if (val) {
13011 int year = atoi(val);
13012#ifdef ANDROID
13013 if (year > 2035)
13014 year = 2035; /* years beyond 2035 not supported */
13015#endif /* ANDROID */
13016 tm.tm_year = year - 1900;
13017 }
13018 t = mktime(&tm);
13019 if (t == (time_t) -1) {
13020 send_resp(dut, conn, SIGMA_ERROR,
13021 "errorCode,Invalid date or time");
13022 return 0;
13023 }
13024
13025 memset(&tv, 0, sizeof(tv));
13026 tv.tv_sec = t;
13027
13028 if (settimeofday(&tv, NULL) < 0) {
13029 sigma_dut_print(dut, DUT_MSG_INFO, "settimeofday failed: %s",
13030 strerror(errno));
13031 send_resp(dut, conn, SIGMA_ERROR,
13032 "errorCode,Failed to set time");
13033 return 0;
13034 }
13035
13036 return 1;
13037#endif /* __linux__ */
13038
13039 return -1;
13040}
13041
13042
Jouni Malinenf7222712019-06-13 01:50:21 +030013043static enum sigma_cmd_result cmd_sta_osu(struct sigma_dut *dut,
13044 struct sigma_conn *conn,
13045 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013046{
13047 const char *intf = get_param(cmd, "Interface");
Jouni Malinen4c8681c2018-09-12 23:28:11 +030013048 const char *name, *osu_ssid, *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013049 int prod_ess_assoc = 1;
Jouni Malinen4c8681c2018-09-12 23:28:11 +030013050 char buf[300], bssid[100], ssid[100];
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013051 int res;
13052 struct wpa_ctrl *ctrl;
13053
13054 name = get_param(cmd, "osuFriendlyName");
Jouni Malinen4c8681c2018-09-12 23:28:11 +030013055 osu_ssid = get_param(cmd, "osu_ssid");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013056
13057 val = get_param(cmd, "ProdESSAssoc");
13058 if (val)
13059 prod_ess_assoc = atoi(val);
13060
13061 kill_dhcp_client(dut, intf);
13062 if (start_dhcp_client(dut, intf) < 0)
13063 return -2;
13064
13065 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger OSU");
13066 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
13067 res = snprintf(buf, sizeof(buf),
Jouni Malinen4c8681c2018-09-12 23:28:11 +030013068 "%s %s%s%s %s%s%s signup osu-ca.pem",
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013069 prod_ess_assoc ? "" : "-N",
13070 name ? "-O'" : "", name ? name : "",
Jouni Malinen4c8681c2018-09-12 23:28:11 +030013071 name ? "'" : "",
13072 osu_ssid ? "-o'" : "", osu_ssid ? osu_ssid : "",
13073 osu_ssid ? "'" : "");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013074
Kanchanapally, Vidyullatha12b66762015-12-31 16:46:42 +053013075 hs2_set_policy(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013076 if (run_hs20_osu(dut, buf) < 0) {
13077 FILE *f;
13078
13079 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to complete OSU");
13080
13081 f = fopen("hs20-osu-client.res", "r");
13082 if (f) {
13083 char resp[400], res[300], *pos;
13084 if (!fgets(res, sizeof(res), f))
13085 res[0] = '\0';
13086 pos = strchr(res, '\n');
13087 if (pos)
13088 *pos = '\0';
13089 fclose(f);
13090 sigma_dut_summary(dut, "hs20-osu-client provisioning failed: %s",
13091 res);
13092 snprintf(resp, sizeof(resp), "notify-send '%s'", res);
13093 if (system(resp) != 0) {
13094 }
13095 snprintf(resp, sizeof(resp),
13096 "SSID,,BSSID,,failureReason,%s", res);
13097 send_resp(dut, conn, SIGMA_COMPLETE, resp);
13098 return 0;
13099 }
13100
13101 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
13102 return 0;
13103 }
13104
13105 if (!prod_ess_assoc)
13106 goto report;
13107
13108 ctrl = open_wpa_mon(intf);
13109 if (ctrl == NULL) {
13110 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
13111 "wpa_supplicant monitor connection");
13112 return -1;
13113 }
13114
13115 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
13116 buf, sizeof(buf));
13117
13118 wpa_ctrl_detach(ctrl);
13119 wpa_ctrl_close(ctrl);
13120
13121 if (res < 0) {
13122 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to connect to "
13123 "network after OSU");
13124 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
13125 return 0;
13126 }
13127
13128report:
13129 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
13130 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
13131 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to get BSSID/SSID");
13132 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
13133 return 0;
13134 }
13135
13136 snprintf(buf, sizeof(buf), "SSID,%s,BSSID,%s", ssid, bssid);
13137 send_resp(dut, conn, SIGMA_COMPLETE, buf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013138 return 0;
13139}
13140
13141
Jouni Malinenf7222712019-06-13 01:50:21 +030013142static enum sigma_cmd_result cmd_sta_policy_update(struct sigma_dut *dut,
13143 struct sigma_conn *conn,
13144 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013145{
13146 const char *val;
13147 int timeout = 120;
13148
13149 val = get_param(cmd, "PolicyUpdate");
13150 if (val == NULL || atoi(val) == 0)
13151 return 1; /* No operation requested */
13152
13153 val = get_param(cmd, "Timeout");
13154 if (val)
13155 timeout = atoi(val);
13156
13157 if (timeout) {
13158 /* TODO: time out the command and return
13159 * PolicyUpdateStatus,TIMEOUT if needed. */
13160 }
13161
13162 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger policy update");
13163 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
13164 if (run_hs20_osu(dut, "pol_upd fqdn=wi-fi.org") < 0) {
13165 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,FAIL");
13166 return 0;
13167 }
13168
13169 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,SUCCESS");
13170 return 0;
13171}
13172
13173
Jouni Malinenf7222712019-06-13 01:50:21 +030013174static enum sigma_cmd_result cmd_sta_er_config(struct sigma_dut *dut,
13175 struct sigma_conn *conn,
13176 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013177{
13178 struct wpa_ctrl *ctrl;
13179 const char *intf = get_param(cmd, "Interface");
13180 const char *bssid = get_param(cmd, "Bssid");
13181 const char *ssid = get_param(cmd, "SSID");
13182 const char *security = get_param(cmd, "Security");
13183 const char *passphrase = get_param(cmd, "Passphrase");
13184 const char *pin = get_param(cmd, "PIN");
13185 char buf[1000];
13186 char ssid_hex[200], passphrase_hex[200];
13187 const char *keymgmt, *cipher;
13188
13189 if (intf == NULL)
Jouni Malinen016ae6c2019-11-04 17:00:01 +020013190 intf = get_main_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013191
13192 if (!bssid) {
13193 send_resp(dut, conn, SIGMA_ERROR,
13194 "ErrorCode,Missing Bssid argument");
13195 return 0;
13196 }
13197
13198 if (!ssid) {
13199 send_resp(dut, conn, SIGMA_ERROR,
13200 "ErrorCode,Missing SSID argument");
13201 return 0;
13202 }
13203
13204 if (!security) {
13205 send_resp(dut, conn, SIGMA_ERROR,
13206 "ErrorCode,Missing Security argument");
13207 return 0;
13208 }
13209
13210 if (!passphrase) {
13211 send_resp(dut, conn, SIGMA_ERROR,
13212 "ErrorCode,Missing Passphrase argument");
13213 return 0;
13214 }
13215
13216 if (!pin) {
13217 send_resp(dut, conn, SIGMA_ERROR,
13218 "ErrorCode,Missing PIN argument");
13219 return 0;
13220 }
13221
vamsi krishna8c9c1562017-05-12 15:51:46 +053013222 if (2 * strlen(ssid) >= sizeof(ssid_hex) ||
13223 2 * strlen(passphrase) >= sizeof(passphrase_hex)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013224 send_resp(dut, conn, SIGMA_ERROR,
13225 "ErrorCode,Too long SSID/passphrase");
13226 return 0;
13227 }
13228
13229 ctrl = open_wpa_mon(intf);
13230 if (ctrl == NULL) {
13231 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
13232 "wpa_supplicant monitor connection");
13233 return -2;
13234 }
13235
13236 if (strcasecmp(security, "wpa2-psk") == 0) {
13237 keymgmt = "WPA2PSK";
13238 cipher = "CCMP";
13239 } else {
13240 wpa_ctrl_detach(ctrl);
13241 wpa_ctrl_close(ctrl);
13242 send_resp(dut, conn, SIGMA_ERROR,
13243 "ErrorCode,Unsupported Security value");
13244 return 0;
13245 }
13246
13247 ascii2hexstr(ssid, ssid_hex);
13248 ascii2hexstr(passphrase, passphrase_hex);
13249 snprintf(buf, sizeof(buf), "WPS_REG %s %s %s %s %s %s",
13250 bssid, pin, ssid_hex, keymgmt, cipher, passphrase_hex);
13251
13252 if (wpa_command(intf, buf) < 0) {
13253 wpa_ctrl_detach(ctrl);
13254 wpa_ctrl_close(ctrl);
13255 send_resp(dut, conn, SIGMA_ERROR,
13256 "ErrorCode,Failed to start registrar");
13257 return 0;
13258 }
13259
13260 snprintf(dut->er_oper_bssid, sizeof(dut->er_oper_bssid), "%s", bssid);
13261 dut->er_oper_performed = 1;
13262
13263 return wps_connection_event(dut, conn, ctrl, intf, 0);
13264}
13265
13266
Jouni Malinenf7222712019-06-13 01:50:21 +030013267static enum sigma_cmd_result
13268cmd_sta_wps_connect_pw_token(struct sigma_dut *dut, struct sigma_conn *conn,
13269 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013270{
13271 struct wpa_ctrl *ctrl;
13272 const char *intf = get_param(cmd, "Interface");
13273 const char *bssid = get_param(cmd, "Bssid");
13274 char buf[100];
13275
13276 if (!bssid) {
13277 send_resp(dut, conn, SIGMA_ERROR,
13278 "ErrorCode,Missing Bssid argument");
13279 return 0;
13280 }
13281
13282 ctrl = open_wpa_mon(intf);
13283 if (ctrl == NULL) {
13284 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
13285 "wpa_supplicant monitor connection");
13286 return -2;
13287 }
13288
13289 snprintf(buf, sizeof(buf), "WPS_NFC %s", bssid);
13290
13291 if (wpa_command(intf, buf) < 0) {
13292 wpa_ctrl_detach(ctrl);
13293 wpa_ctrl_close(ctrl);
13294 send_resp(dut, conn, SIGMA_ERROR,
13295 "ErrorCode,Failed to start registrar");
13296 return 0;
13297 }
13298
13299 return wps_connection_event(dut, conn, ctrl, intf, 0);
13300}
13301
13302
Jouni Malinenf7222712019-06-13 01:50:21 +030013303static enum sigma_cmd_result cmd_start_wps_registration(struct sigma_dut *dut,
13304 struct sigma_conn *conn,
13305 struct sigma_cmd *cmd)
vamsi krishna9b144002017-09-20 13:28:13 +053013306{
13307 struct wpa_ctrl *ctrl;
13308 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020013309 const char *network_mode = get_param(cmd, "network_mode");
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020013310 const char *config_method = get_param(cmd, "WPSConfigMethod");
13311 const char *role;
vamsi krishna9b144002017-09-20 13:28:13 +053013312 int res;
13313 char buf[256];
13314 const char *events[] = {
13315 "CTRL-EVENT-CONNECTED",
13316 "WPS-OVERLAP-DETECTED",
13317 "WPS-TIMEOUT",
13318 "WPS-FAIL",
13319 NULL
13320 };
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020013321 int id = 0;
vamsi krishna9b144002017-09-20 13:28:13 +053013322
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020013323 /* 60G WPS tests do not pass Interface parameter */
13324 if (!intf)
Jouni Malinen016ae6c2019-11-04 17:00:01 +020013325 intf = get_main_ifname(dut);
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020013326
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020013327 if (dut->mode == SIGMA_MODE_AP)
13328 return ap_wps_registration(dut, conn, cmd);
13329
13330 if (config_method) {
13331 /* WFA_CS_WPS_PIN_KEYPAD mode is set when using the
13332 * sta_wps_enter_pin before calling start_wps_registration. */
13333 if (strcasecmp(config_method, "PBC") == 0)
13334 dut->wps_method = WFA_CS_WPS_PBC;
13335 }
13336 if (dut->wps_method == WFA_CS_WPS_NOT_READY) {
13337 send_resp(dut, conn, SIGMA_ERROR,
13338 "ErrorCode,WPS parameters not yet set");
13339 return STATUS_SENT;
13340 }
13341
13342 /* Make sure WPS is enabled (also for STA mode) */
13343 dut->wps_disable = 0;
13344
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020013345 if (dut->band == WPS_BAND_60G && network_mode &&
13346 strcasecmp(network_mode, "PBSS") == 0) {
13347 sigma_dut_print(dut, DUT_MSG_DEBUG,
13348 "Set PBSS network mode, network id %d", id);
Jouni Malinen016ae6c2019-11-04 17:00:01 +020013349 if (set_network(get_station_ifname(dut), id, "pbss", "1") < 0)
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020013350 return -2;
13351 }
13352
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020013353 if (dut->force_rsn_ie) {
13354 sigma_dut_print(dut, DUT_MSG_DEBUG, "Force RSN_IE: %d",
13355 dut->force_rsn_ie);
13356 if (sta_60g_force_rsn_ie(dut, dut->force_rsn_ie) < 0) {
13357 sigma_dut_print(dut, DUT_MSG_INFO,
13358 "Failed to force RSN_IE");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020013359 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020013360 }
13361 }
13362
vamsi krishna9b144002017-09-20 13:28:13 +053013363 ctrl = open_wpa_mon(intf);
13364 if (!ctrl) {
13365 sigma_dut_print(dut, DUT_MSG_ERROR,
13366 "Failed to open wpa_supplicant monitor connection");
13367 return -2;
13368 }
13369
13370 role = get_param(cmd, "WpsRole");
13371 if (!role) {
13372 send_resp(dut, conn, SIGMA_INVALID,
13373 "ErrorCode,WpsRole not provided");
13374 goto fail;
13375 }
13376
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020013377 if (strcasecmp(role, "Enrollee") != 0) {
13378 /* Registrar role for STA not supported */
13379 send_resp(dut, conn, SIGMA_ERROR,
13380 "ErrorCode,Unsupported WpsRole value");
13381 goto fail;
13382 }
13383
13384 if (is_60g_sigma_dut(dut)) {
13385 if (dut->wps_method == WFA_CS_WPS_PBC)
13386 snprintf(buf, sizeof(buf), "WPS_PBC");
13387 else /* WFA_CS_WPS_PIN_KEYPAD */
13388 snprintf(buf, sizeof(buf), "WPS_PIN any %s",
13389 dut->wps_pin);
13390 if (wpa_command(intf, buf) < 0) {
13391 send_resp(dut, conn, SIGMA_ERROR,
13392 "ErrorCode,Failed to start WPS");
vamsi krishna9b144002017-09-20 13:28:13 +053013393 goto fail;
13394 }
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020013395 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
13396 if (res < 0) {
13397 send_resp(dut, conn, SIGMA_ERROR,
13398 "ErrorCode,WPS connection did not complete");
13399 goto fail;
13400 }
13401 if (strstr(buf, "WPS-TIMEOUT")) {
13402 send_resp(dut, conn, SIGMA_COMPLETE, "WpsState,NoPeer");
13403 } else if (strstr(buf, "WPS-OVERLAP-DETECTED")) {
13404 send_resp(dut, conn, SIGMA_COMPLETE,
13405 "WpsState,OverlapSession");
13406 } else if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
13407 send_resp(dut, conn, SIGMA_COMPLETE,
13408 "WpsState,Successful");
13409 } else {
13410 send_resp(dut, conn, SIGMA_COMPLETE,
13411 "WpsState,Failure");
13412 }
13413 } else {
13414 if (dut->wps_method == WFA_CS_WPS_PBC) {
vamsi krishna9b144002017-09-20 13:28:13 +053013415 if (wpa_command(intf, "WPS_PBC") < 0) {
13416 send_resp(dut, conn, SIGMA_ERROR,
13417 "ErrorCode,Failed to enable PBC");
13418 goto fail;
13419 }
13420 } else {
13421 /* TODO: PIN method */
13422 send_resp(dut, conn, SIGMA_ERROR,
13423 "ErrorCode,Unsupported WpsConfigMethod value");
13424 goto fail;
13425 }
13426 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
13427 if (res < 0) {
13428 send_resp(dut, conn, SIGMA_ERROR,
13429 "ErrorCode,WPS connection did not complete");
13430 goto fail;
13431 }
13432 if (strstr(buf, "WPS-TIMEOUT")) {
13433 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,NoPeer");
13434 } else if (strstr(buf, "WPS-OVERLAP-DETECTED")) {
13435 send_resp(dut, conn, SIGMA_ERROR,
13436 "ErrorCode,OverlapSession");
13437 } else if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
13438 send_resp(dut, conn, SIGMA_COMPLETE, "Successful");
13439 } else {
13440 send_resp(dut, conn, SIGMA_ERROR,
13441 "ErrorCode,WPS operation failed");
13442 }
vamsi krishna9b144002017-09-20 13:28:13 +053013443 }
13444
13445fail:
13446 wpa_ctrl_detach(ctrl);
13447 wpa_ctrl_close(ctrl);
13448 return 0;
13449}
13450
13451
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013452static int req_intf(struct sigma_cmd *cmd)
13453{
13454 return get_param(cmd, "interface") == NULL ? -1 : 0;
13455}
13456
13457
13458void sta_register_cmds(void)
13459{
13460 sigma_dut_reg_cmd("sta_get_ip_config", req_intf,
13461 cmd_sta_get_ip_config);
13462 sigma_dut_reg_cmd("sta_set_ip_config", req_intf,
13463 cmd_sta_set_ip_config);
13464 sigma_dut_reg_cmd("sta_get_info", req_intf, cmd_sta_get_info);
13465 sigma_dut_reg_cmd("sta_get_mac_address", req_intf,
13466 cmd_sta_get_mac_address);
13467 sigma_dut_reg_cmd("sta_is_connected", req_intf, cmd_sta_is_connected);
13468 sigma_dut_reg_cmd("sta_verify_ip_connection", req_intf,
13469 cmd_sta_verify_ip_connection);
13470 sigma_dut_reg_cmd("sta_get_bssid", req_intf, cmd_sta_get_bssid);
13471 sigma_dut_reg_cmd("sta_set_encryption", req_intf,
13472 cmd_sta_set_encryption);
13473 sigma_dut_reg_cmd("sta_set_psk", req_intf, cmd_sta_set_psk);
13474 sigma_dut_reg_cmd("sta_set_eaptls", req_intf, cmd_sta_set_eaptls);
13475 sigma_dut_reg_cmd("sta_set_eapttls", req_intf, cmd_sta_set_eapttls);
13476 sigma_dut_reg_cmd("sta_set_eapsim", req_intf, cmd_sta_set_eapsim);
13477 sigma_dut_reg_cmd("sta_set_peap", req_intf, cmd_sta_set_peap);
13478 sigma_dut_reg_cmd("sta_set_eapfast", req_intf, cmd_sta_set_eapfast);
13479 sigma_dut_reg_cmd("sta_set_eapaka", req_intf, cmd_sta_set_eapaka);
13480 sigma_dut_reg_cmd("sta_set_eapakaprime", req_intf,
13481 cmd_sta_set_eapakaprime);
13482 sigma_dut_reg_cmd("sta_set_security", req_intf, cmd_sta_set_security);
13483 sigma_dut_reg_cmd("sta_set_uapsd", req_intf, cmd_sta_set_uapsd);
13484 /* TODO: sta_set_ibss */
13485 /* TODO: sta_set_mode */
13486 sigma_dut_reg_cmd("sta_set_wmm", req_intf, cmd_sta_set_wmm);
13487 sigma_dut_reg_cmd("sta_associate", req_intf, cmd_sta_associate);
13488 /* TODO: sta_up_load */
13489 sigma_dut_reg_cmd("sta_preset_testparameters", req_intf,
13490 cmd_sta_preset_testparameters);
13491 /* TODO: sta_set_system */
13492 sigma_dut_reg_cmd("sta_set_11n", req_intf, cmd_sta_set_11n);
13493 /* TODO: sta_set_rifs_test */
13494 sigma_dut_reg_cmd("sta_set_wireless", req_intf, cmd_sta_set_wireless);
13495 sigma_dut_reg_cmd("sta_send_addba", req_intf, cmd_sta_send_addba);
13496 /* TODO: sta_send_coexist_mgmt */
13497 sigma_dut_reg_cmd("sta_disconnect", req_intf, cmd_sta_disconnect);
13498 sigma_dut_reg_cmd("sta_reassoc", req_intf, cmd_sta_reassoc);
13499 sigma_dut_reg_cmd("sta_reassociate", req_intf, cmd_sta_reassoc);
13500 sigma_dut_reg_cmd("sta_reset_default", req_intf,
13501 cmd_sta_reset_default);
13502 sigma_dut_reg_cmd("sta_send_frame", req_intf, cmd_sta_send_frame);
13503 sigma_dut_reg_cmd("sta_set_macaddr", req_intf, cmd_sta_set_macaddr);
13504 sigma_dut_reg_cmd("sta_set_rfeature", req_intf, cmd_sta_set_rfeature);
13505 sigma_dut_reg_cmd("sta_set_radio", req_intf, cmd_sta_set_radio);
13506 sigma_dut_reg_cmd("sta_set_pwrsave", req_intf, cmd_sta_set_pwrsave);
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020013507 sigma_dut_reg_cmd("sta_set_power_save", req_intf, cmd_sta_set_pwrsave);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013508 sigma_dut_reg_cmd("sta_bssid_pool", req_intf, cmd_sta_bssid_pool);
13509 sigma_dut_reg_cmd("sta_reset_parm", req_intf, cmd_sta_reset_parm);
13510 sigma_dut_reg_cmd("sta_get_key", req_intf, cmd_sta_get_key);
13511 sigma_dut_reg_cmd("sta_hs2_associate", req_intf,
13512 cmd_sta_hs2_associate);
Jouni Malinenb639f1c2018-09-13 02:39:46 +030013513 sigma_dut_reg_cmd("sta_hs2_venue_info", req_intf,
13514 cmd_sta_hs2_venue_info);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013515 sigma_dut_reg_cmd("sta_add_credential", req_intf,
13516 cmd_sta_add_credential);
13517 sigma_dut_reg_cmd("sta_scan", req_intf, cmd_sta_scan);
Jouni Malinen5e5d43d2018-01-10 17:29:33 +020013518 sigma_dut_reg_cmd("sta_scan_bss", req_intf, cmd_sta_scan_bss);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013519 sigma_dut_reg_cmd("sta_set_systime", NULL, cmd_sta_set_systime);
13520 sigma_dut_reg_cmd("sta_osu", req_intf, cmd_sta_osu);
13521 sigma_dut_reg_cmd("sta_policy_update", req_intf, cmd_sta_policy_update);
13522 sigma_dut_reg_cmd("sta_er_config", NULL, cmd_sta_er_config);
13523 sigma_dut_reg_cmd("sta_wps_connect_pw_token", req_intf,
13524 cmd_sta_wps_connect_pw_token);
Jouni Malinen82905202018-04-29 17:20:10 +030013525 sigma_dut_reg_cmd("sta_exec_action", NULL, cmd_sta_exec_action);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013526 sigma_dut_reg_cmd("sta_get_events", req_intf, cmd_sta_get_events);
13527 sigma_dut_reg_cmd("sta_get_parameter", req_intf, cmd_sta_get_parameter);
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020013528 sigma_dut_reg_cmd("start_wps_registration", NULL,
vamsi krishna9b144002017-09-20 13:28:13 +053013529 cmd_start_wps_registration);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013530}