blob: 31e65dea579d576b1addb671d7c9c6e489d9bdf4 [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) {
241 snprintf(buf, sizeof(buf), "iwpriv wlan0 dump 906");
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530242 if (system(buf) != 0)
243 goto set_power_save;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200244 } else {
245 snprintf(buf, sizeof(buf), "iwpriv wlan0 dump 905");
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530246 if (system(buf) != 0)
247 goto set_power_save;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200248 snprintf(buf, sizeof(buf), "iwpriv wlan0 dump 912");
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530249 if (system(buf) != 0)
250 goto set_power_save;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200251 }
252
253 return 0;
254 }
255
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530256set_power_save:
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200257 snprintf(buf, sizeof(buf), "./iw dev %s set power_save %s",
258 intf, enabled ? "on" : "off");
259 if (system(buf) != 0) {
260 snprintf(buf, sizeof(buf), "iw dev %s set power_save %s",
261 intf, enabled ? "on" : "off");
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530262 if (system(buf) != 0) {
263 sigma_dut_print(dut, DUT_MSG_ERROR,
264 "Failed to set power save %s",
265 enabled ? "on" : "off");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200266 return -1;
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530267 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200268 }
269
270 return 0;
271#else /* __linux__ */
272 return -1;
273#endif /* __linux__ */
274}
275
276
Lior Davidcc88b562017-01-03 18:52:09 +0200277#ifdef __linux__
Lior David0fe101e2017-03-09 16:09:50 +0200278
Lior Davidcc88b562017-01-03 18:52:09 +0200279static int wil6210_get_debugfs_dir(struct sigma_dut *dut, char *path,
280 size_t len)
281{
282 DIR *dir, *wil_dir;
283 struct dirent *entry;
284 int ret = -1;
285 const char *root_path = "/sys/kernel/debug/ieee80211";
286
287 dir = opendir(root_path);
288 if (!dir)
289 return -2;
290
291 while ((entry = readdir(dir))) {
292 if (strcmp(entry->d_name, ".") == 0 ||
293 strcmp(entry->d_name, "..") == 0)
294 continue;
295
296 if (snprintf(path, len, "%s/%s/wil6210",
297 root_path, entry->d_name) >= (int) len) {
298 ret = -3;
299 break;
300 }
301
302 wil_dir = opendir(path);
303 if (wil_dir) {
304 closedir(wil_dir);
305 ret = 0;
306 break;
307 }
308 }
309
310 closedir(dir);
311 return ret;
312}
Lior David0fe101e2017-03-09 16:09:50 +0200313
314
315static int wil6210_wmi_send(struct sigma_dut *dut, uint16_t command,
316 void *payload, uint16_t length)
317{
318 struct {
319 struct wil_wmi_header hdr;
320 char payload[WIL_WMI_MAX_PAYLOAD];
321 } __attribute__((packed)) cmd;
322 char buf[128], fname[128];
323 size_t towrite, written;
324 FILE *f;
Jouni Malinen3aa72862019-05-29 23:14:51 +0300325 int res;
Lior David0fe101e2017-03-09 16:09:50 +0200326
327 if (length > WIL_WMI_MAX_PAYLOAD) {
328 sigma_dut_print(dut, DUT_MSG_ERROR,
329 "payload too large(%u, max %u)",
330 length, WIL_WMI_MAX_PAYLOAD);
331 return -1;
332 }
333
334 memset(&cmd.hdr, 0, sizeof(cmd.hdr));
335 cmd.hdr.cmd = command;
336 memcpy(cmd.payload, payload, length);
337
338 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
339 sigma_dut_print(dut, DUT_MSG_ERROR,
340 "failed to get wil6210 debugfs dir");
341 return -1;
342 }
343
Jouni Malinen3aa72862019-05-29 23:14:51 +0300344 res = snprintf(fname, sizeof(fname), "%s/wmi_send", buf);
345 if (res < 0 || res >= sizeof(fname))
346 return -1;
Lior David0fe101e2017-03-09 16:09:50 +0200347 f = fopen(fname, "wb");
348 if (!f) {
349 sigma_dut_print(dut, DUT_MSG_ERROR,
350 "failed to open: %s", fname);
351 return -1;
352 }
353
354 towrite = sizeof(cmd.hdr) + length;
355 written = fwrite(&cmd, 1, towrite, f);
356 fclose(f);
357 if (written != towrite) {
358 sigma_dut_print(dut, DUT_MSG_ERROR,
359 "failed to send wmi %u", command);
360 return -1;
361 }
362
363 return 0;
364}
365
366
367static int wil6210_get_sta_info_field(struct sigma_dut *dut, const char *bssid,
368 const char *pattern, unsigned int *field)
369{
370 char buf[128], fname[128];
371 FILE *f;
372 regex_t re;
373 regmatch_t m[2];
Jouni Malinen3aa72862019-05-29 23:14:51 +0300374 int rc, ret = -1, res;
Lior David0fe101e2017-03-09 16:09:50 +0200375
376 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
377 sigma_dut_print(dut, DUT_MSG_ERROR,
378 "failed to get wil6210 debugfs dir");
379 return -1;
380 }
381
Jouni Malinen3aa72862019-05-29 23:14:51 +0300382 res = snprintf(fname, sizeof(fname), "%s/stations", buf);
383 if (res < 0 || res >= sizeof(fname))
384 return -1;
Lior David0fe101e2017-03-09 16:09:50 +0200385 f = fopen(fname, "r");
386 if (!f) {
387 sigma_dut_print(dut, DUT_MSG_ERROR,
388 "failed to open: %s", fname);
389 return -1;
390 }
391
392 if (regcomp(&re, pattern, REG_EXTENDED)) {
393 sigma_dut_print(dut, DUT_MSG_ERROR,
394 "regcomp failed: %s", pattern);
395 goto out;
396 }
397
398 /*
399 * find the entry for the mac address
400 * line is of the form: [n] 11:22:33:44:55:66 state AID aid
401 */
402 while (fgets(buf, sizeof(buf), f)) {
403 if (strcasestr(buf, bssid)) {
404 /* extract the field (CID/AID/state) */
405 rc = regexec(&re, buf, 2, m, 0);
406 if (!rc && (m[1].rm_so >= 0)) {
407 buf[m[1].rm_eo] = 0;
408 *field = atoi(&buf[m[1].rm_so]);
409 ret = 0;
410 break;
411 }
412 }
413 }
414
415 regfree(&re);
416 if (ret)
417 sigma_dut_print(dut, DUT_MSG_ERROR,
418 "could not extract field");
419
420out:
421 fclose(f);
422
423 return ret;
424}
425
426
427static int wil6210_get_cid(struct sigma_dut *dut, const char *bssid,
428 unsigned int *cid)
429{
430 const char *pattern = "\\[([0-9]+)\\]";
431
432 return wil6210_get_sta_info_field(dut, bssid, pattern, cid);
433}
434
435
436static int wil6210_send_brp_rx(struct sigma_dut *dut, const char *mac,
437 int l_rx)
438{
Rakesh Sunki556237d2017-03-30 14:49:31 -0700439 struct wil_wmi_bf_trig_cmd cmd;
Lior David0fe101e2017-03-09 16:09:50 +0200440 unsigned int cid;
441
Rakesh Sunki556237d2017-03-30 14:49:31 -0700442 memset(&cmd, 0, sizeof(cmd));
443
Lior David0fe101e2017-03-09 16:09:50 +0200444 if (wil6210_get_cid(dut, mac, &cid))
445 return -1;
446
447 cmd.bf_type = WIL_WMI_BRP_RX;
448 cmd.sta_id = cid;
449 /* training length (l_rx) is ignored, FW always uses length 16 */
450 return wil6210_wmi_send(dut, WIL_WMI_BF_TRIG_CMDID,
451 &cmd, sizeof(cmd));
452}
453
454
455static int wil6210_send_sls(struct sigma_dut *dut, const char *mac)
456{
Rakesh Sunki556237d2017-03-30 14:49:31 -0700457 struct wil_wmi_bf_trig_cmd cmd;
458
459 memset(&cmd, 0, sizeof(cmd));
Lior David0fe101e2017-03-09 16:09:50 +0200460
461 if (parse_mac_address(dut, mac, (unsigned char *)&cmd.dest_mac))
462 return -1;
463
464 cmd.bf_type = WIL_WMI_SLS;
465 return wil6210_wmi_send(dut, WIL_WMI_BF_TRIG_CMDID,
466 &cmd, sizeof(cmd));
467}
468
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +0200469
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +0200470int wil6210_set_ese(struct sigma_dut *dut, int count,
471 struct sigma_ese_alloc *allocs)
472{
473 struct wil_wmi_ese_cfg cmd = { };
474 int i;
475
476 if (count == 0 || count > WIL_WMI_MAX_ESE_SLOTS)
477 return -1;
478
479 if (dut->ap_bcnint <= 0) {
480 sigma_dut_print(dut, DUT_MSG_ERROR,
481 "invalid beacon interval(%d), check test",
482 dut->ap_bcnint);
483 return -1;
484 }
485
486 cmd.ese_advertisment = WIL_WMI_ADVERTISE_ESE_IN_BEACON;
487 cmd.flags = 0x1d;
488 cmd.num_allocs = count;
489 for (i = 0; i < count; i++) {
490 /*
491 * Convert percent from BI (BI specified in milliseconds)
492 * to absolute duration in microseconds.
493 */
494 cmd.slots[i].duration =
495 (allocs[i].percent_bi * dut->ap_bcnint * 1000) / 100;
496 switch (allocs[i].type) {
497 case ESE_CBAP:
498 cmd.slots[i].slot_type = WIL_WMI_ESE_CBAP;
499 break;
500 case ESE_SP:
501 cmd.slots[i].slot_type = WIL_WMI_ESE_SP;
502 break;
503 default:
504 sigma_dut_print(dut, DUT_MSG_ERROR,
505 "invalid slot type(%d) at index %d",
506 allocs[i].type, i);
507 return -1;
508 }
509 cmd.slots[i].src_aid = allocs[i].src_aid;
510 cmd.slots[i].dst_aid = allocs[i].dst_aid;
511 sigma_dut_print(dut, DUT_MSG_INFO,
512 "slot %d, duration %u, type %d, srcAID %u dstAID %u",
513 i, cmd.slots[i].duration,
514 cmd.slots[i].slot_type, cmd.slots[i].src_aid,
515 cmd.slots[i].dst_aid);
516 }
517
518 return wil6210_wmi_send(dut, WIL_WMI_ESE_CFG_CMDID, &cmd, sizeof(cmd));
519}
520
521
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +0200522int wil6210_set_force_mcs(struct sigma_dut *dut, int force, int mcs)
523{
524 struct wil_wmi_force_mcs cmd = { };
525
526 cmd.module_id = WIL_WMI_UT_HW_SYSAPI;
527 cmd.subtype_id = WIL_WMI_UT_FORCE_MCS;
528 cmd.force_enable = (uint32_t) force;
529 cmd.mcs = (uint32_t) mcs;
530
531 return wil6210_wmi_send(dut, WIL_WMI_UNIT_TEST_CMDID,
532 &cmd, sizeof(cmd));
533}
534
535
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +0200536static int wil6210_force_rsn_ie(struct sigma_dut *dut, int state)
537{
538 struct wil_wmi_force_rsn_ie cmd = { };
539
540 cmd.module_id = WIL_WMI_UT_HW_SYSAPI;
541 cmd.subtype_id = WIL_WMI_UT_FORCE_RSN_IE;
542 cmd.state = (uint32_t) state;
543
544 return wil6210_wmi_send(dut, WIL_WMI_UNIT_TEST_CMDID,
545 &cmd, sizeof(cmd));
546}
547
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +0300548
549/*
550 * this function is also used to configure generic remain-on-channel
551 */
552static int wil6210_p2p_cfg(struct sigma_dut *dut, int freq)
553{
554 struct wil_wmi_p2p_cfg_cmd cmd = { };
555 int channel = freq_to_channel(freq);
556
557 if (channel < 0)
558 return -1;
559 cmd.discovery_mode = WMI_DISCOVERY_MODE_NON_OFFLOAD;
560 cmd.channel = channel - 1;
561 cmd.bcon_interval = WIL_DEFAULT_BI;
562 cmd.discovery_mode = WMI_DISCOVERY_MODE_PEER2PEER;
563
564 return wil6210_wmi_send(dut, WIL_WMI_P2P_CFG_CMDID,
565 &cmd, sizeof(cmd));
566}
567
568
569static int wil6210_remain_on_channel(struct sigma_dut *dut, int freq)
570{
571 int ret = wil6210_p2p_cfg(dut, freq);
572
573 if (ret)
574 return ret;
575
576 ret = wil6210_wmi_send(dut, WIL_WMI_START_LISTEN_CMDID, NULL, 0);
577 if (!ret) {
578 /*
579 * wait a bit to allow FW to setup the radio
580 * especially important if we switch channels
581 */
582 usleep(500000);
583 }
584
585 return ret;
586}
587
588
589static int wil6210_stop_discovery(struct sigma_dut *dut)
590{
591 return wil6210_wmi_send(dut, WIL_WMI_DISCOVERY_STOP_CMDID, NULL, 0);
592}
593
594
595static int wil6210_transmit_frame(struct sigma_dut *dut, int freq,
596 int wait_duration,
597 const char *frame, size_t frame_len)
598{
599 char buf[128], fname[128];
600 FILE *f;
Jouni Malinen3aa72862019-05-29 23:14:51 +0300601 int res = 0, r;
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +0300602 size_t written;
603
604 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
605 sigma_dut_print(dut, DUT_MSG_ERROR,
606 "failed to get wil6210 debugfs dir");
607 return -1;
608 }
Jouni Malinen3aa72862019-05-29 23:14:51 +0300609 r = snprintf(fname, sizeof(fname), "%s/tx_mgmt", buf);
610 if (r < 0 || r >= sizeof(fname))
611 return -1;
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +0300612
613 if (wil6210_remain_on_channel(dut, freq)) {
614 sigma_dut_print(dut, DUT_MSG_ERROR,
615 "failed to listen on channel");
616 return -1;
617 }
618
619 f = fopen(fname, "wb");
620 if (!f) {
621 sigma_dut_print(dut, DUT_MSG_ERROR,
622 "failed to open: %s", fname);
623 res = -1;
624 goto out_stop;
625 }
626 written = fwrite(frame, 1, frame_len, f);
627 fclose(f);
628
629 if (written != frame_len) {
630 sigma_dut_print(dut, DUT_MSG_ERROR,
631 "failed to transmit frame (got %zd, expected %zd)",
632 written, frame_len);
633 res = -1;
634 goto out_stop;
635 }
636
637 usleep(wait_duration * 1000);
638
639out_stop:
640 wil6210_stop_discovery(dut);
641 return res;
642}
643
644
645static int find_template_frame_tag(struct template_frame_tag *tags,
646 int total_tags, int tag_num)
647{
648 int i;
649
650 for (i = 0; i < total_tags; i++) {
651 if (tag_num == tags[i].num)
652 return i;
653 }
654
655 return -1;
656}
657
658
659static int replace_p2p_attribute(struct sigma_dut *dut, char *buf, size_t len,
660 int id, const char *value, size_t val_len)
661{
662 struct wfa_p2p_attribute *attr = (struct wfa_p2p_attribute *) buf;
663
664 if (len < 3 + val_len) {
665 sigma_dut_print(dut, DUT_MSG_ERROR,
666 "not enough space to replace P2P attribute");
667 return -1;
668 }
669
670 if (attr->len != val_len) {
671 sigma_dut_print(dut, DUT_MSG_ERROR,
672 "attribute length mismatch (need %zu have %hu)",
673 val_len, attr->len);
674 return -1;
675 }
676
677 if (attr->id != id) {
678 sigma_dut_print(dut, DUT_MSG_ERROR,
679 "incorrect attribute id (expected %d actual %d)",
680 id, attr->id);
681 return -1;
682 }
683
684 memcpy(attr->variable, value, val_len);
685
686 return 0;
687}
688
689
690static int parse_template_frame_file(struct sigma_dut *dut, const char *fname,
691 char *buf, size_t *length,
692 struct template_frame_tag *tags,
693 size_t *num_tags)
694{
695 char line[512];
696 FILE *f;
697 size_t offset = 0, tag_index = 0;
698 int num, index;
699 int in_tag = 0, tag_num = 0, tag_offset = 0;
700
701 if (*length < sizeof(struct ieee80211_hdr_3addr)) {
702 sigma_dut_print(dut, DUT_MSG_ERROR,
703 "supplied buffer is too small");
704 return -1;
705 }
706
707 f = fopen(fname, "r");
708 if (!f) {
709 sigma_dut_print(dut, DUT_MSG_ERROR,
710 "failed to open template file %s", fname);
711 return -1;
712 }
713
714 /*
715 * template file format: lines beginning with # are comments and
716 * ignored.
717 * It is possible to tag bytes in the frame to make it easy
718 * to replace fields in the template, espcially if they appear
719 * in variable-sized sections (such as IEs)
720 * This is done by a line beginning with $NUM where NUM is an integer
721 * tag number. It can be followed by space(s) and comment.
722 * The next line is considered the tagged bytes. The parser will fill
723 * the tag number, offset and length of the tagged bytes.
724 * rest of the lines contain frame bytes as sequence of hex digits,
725 * 2 digits for each byte. Spaces are allowed between bytes.
726 * On bytes lines only hex digits and spaces are allowed
727 */
728 while (!feof(f)) {
729 if (!fgets(line, sizeof(line), f))
730 break;
731 index = 0;
732 while (isspace((unsigned char) line[index]))
733 index++;
734 if (!line[index] || line[index] == '#')
735 continue;
736 if (line[index] == '$') {
737 if (tags) {
738 index++;
739 tag_num = strtol(&line[index], NULL, 0);
740 tag_offset = offset;
741 in_tag = 1;
742 }
743 continue;
744 }
745 while (line[index]) {
746 if (isspace((unsigned char) line[index])) {
747 index++;
748 continue;
749 }
750 num = hex_byte(&line[index]);
751 if (num < 0)
752 break;
753 buf[offset++] = num;
754 if (offset == *length)
755 goto out;
756 index += 2;
757 }
758
759 if (in_tag) {
760 if (tag_index < *num_tags) {
761 tags[tag_index].num = tag_num;
762 tags[tag_index].offset = tag_offset;
763 tags[tag_index].len = offset - tag_offset;
764 tag_index++;
765 } else {
766 sigma_dut_print(dut, DUT_MSG_INFO,
767 "too many tags, tag ignored");
768 }
769 in_tag = 0;
770 }
771 }
772
773 if (num_tags)
774 *num_tags = tag_index;
775out:
776 fclose(f);
777 if (offset < sizeof(struct ieee80211_hdr_3addr)) {
778 sigma_dut_print(dut, DUT_MSG_ERROR,
779 "template frame is too small");
780 return -1;
781 }
782
783 *length = offset;
784 return 0;
785}
786
Lior Davidcc88b562017-01-03 18:52:09 +0200787#endif /* __linux__ */
788
789
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200790static void static_ip_file(int proto, const char *addr, const char *mask,
791 const char *gw)
792{
793 if (proto) {
794 FILE *f = fopen("static-ip", "w");
795 if (f) {
796 fprintf(f, "%d %s %s %s\n", proto, addr,
797 mask ? mask : "N/A",
798 gw ? gw : "N/A");
799 fclose(f);
800 }
801 } else {
802 unlink("static-ip");
803 }
804}
805
806
807static int send_neighbor_request(struct sigma_dut *dut, const char *intf,
808 const char *ssid)
809{
810#ifdef __linux__
811 char buf[100];
812
813 snprintf(buf, sizeof(buf), "iwpriv %s neighbor %s",
814 intf, ssid);
815 sigma_dut_print(dut, DUT_MSG_INFO, "Request: %s", buf);
816
817 if (system(buf) != 0) {
818 sigma_dut_print(dut, DUT_MSG_ERROR,
819 "iwpriv neighbor request failed");
820 return -1;
821 }
822
823 sigma_dut_print(dut, DUT_MSG_INFO, "iwpriv neighbor request send");
824
825 return 0;
826#else /* __linux__ */
827 return -1;
828#endif /* __linux__ */
829}
830
831
832static int send_trans_mgmt_query(struct sigma_dut *dut, const char *intf,
Ashwini Patil5acd7382017-04-13 15:55:04 +0530833 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200834{
Ashwini Patil5acd7382017-04-13 15:55:04 +0530835 const char *val;
836 int reason_code = 0;
837 char buf[1024];
838
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200839 /*
840 * In the earlier builds we used WNM_QUERY and in later
841 * builds used WNM_BSS_QUERY.
842 */
843
Ashwini Patil5acd7382017-04-13 15:55:04 +0530844 val = get_param(cmd, "BTMQuery_Reason_Code");
845 if (val)
846 reason_code = atoi(val);
847
848 val = get_param(cmd, "Cand_List");
849 if (val && atoi(val) == 1 && dut->btm_query_cand_list) {
850 snprintf(buf, sizeof(buf), "WNM_BSS_QUERY %d%s", reason_code,
851 dut->btm_query_cand_list);
852 free(dut->btm_query_cand_list);
853 dut->btm_query_cand_list = NULL;
854 } else {
855 snprintf(buf, sizeof(buf), "WNM_BSS_QUERY %d", reason_code);
856 }
857
858 if (wpa_command(intf, buf) != 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200859 sigma_dut_print(dut, DUT_MSG_ERROR,
860 "transition management query failed");
861 return -1;
862 }
863
864 sigma_dut_print(dut, DUT_MSG_DEBUG,
865 "transition management query sent");
866
867 return 0;
868}
869
870
871int is_ip_addr(const char *str)
872{
873 const char *pos = str;
874 struct in_addr addr;
875
876 while (*pos) {
877 if (*pos != '.' && (*pos < '0' || *pos > '9'))
878 return 0;
879 pos++;
880 }
881
882 return inet_aton(str, &addr);
883}
884
885
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200886int get_ip_config(struct sigma_dut *dut, const char *ifname, char *buf,
887 size_t buf_len)
888{
vamsi krishnaa11d0732018-05-16 12:19:48 +0530889 char tmp[256];
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200890 char ip[16], mask[15], dns[16], sec_dns[16];
891 int is_dhcp = 0;
892 int s;
893#ifdef ANDROID
894 char prop[PROPERTY_VALUE_MAX];
vamsi krishnaa11d0732018-05-16 12:19:48 +0530895#else /* ANDROID */
896 FILE *f;
897#ifdef __linux__
898 const char *str_ps;
899#endif /* __linux__ */
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200900#endif /* ANDROID */
901
902 ip[0] = '\0';
903 mask[0] = '\0';
904 dns[0] = '\0';
905 sec_dns[0] = '\0';
906
907 s = socket(PF_INET, SOCK_DGRAM, 0);
908 if (s >= 0) {
909 struct ifreq ifr;
910 struct sockaddr_in saddr;
911
912 memset(&ifr, 0, sizeof(ifr));
Peng Xub8fc5cc2017-05-10 17:27:28 -0700913 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200914 if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
915 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to get "
916 "%s IP address: %s",
917 ifname, strerror(errno));
918 } else {
919 memcpy(&saddr, &ifr.ifr_addr,
920 sizeof(struct sockaddr_in));
Peng Xub8fc5cc2017-05-10 17:27:28 -0700921 strlcpy(ip, inet_ntoa(saddr.sin_addr), sizeof(ip));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200922 }
923
924 if (ioctl(s, SIOCGIFNETMASK, &ifr) == 0) {
925 memcpy(&saddr, &ifr.ifr_addr,
926 sizeof(struct sockaddr_in));
Peng Xub8fc5cc2017-05-10 17:27:28 -0700927 strlcpy(mask, inet_ntoa(saddr.sin_addr), sizeof(mask));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200928 }
929 close(s);
930 }
931
932#ifdef ANDROID
933 snprintf(tmp, sizeof(tmp), "dhcp.%s.pid", ifname);
934 if (property_get(tmp, prop, NULL) != 0 && atoi(prop) > 0) {
935 snprintf(tmp, sizeof(tmp), "dhcp.%s.result", ifname);
936 if (property_get(tmp, prop, NULL) != 0 &&
937 strcmp(prop, "ok") == 0) {
938 snprintf(tmp, sizeof(tmp), "dhcp.%s.ipaddress",
939 ifname);
940 if (property_get(tmp, prop, NULL) != 0 &&
941 strcmp(ip, prop) == 0)
942 is_dhcp = 1;
943 }
944 }
945
946 snprintf(tmp, sizeof(tmp), "dhcp.%s.dns1", ifname);
Peng Xub8fc5cc2017-05-10 17:27:28 -0700947 if (property_get(tmp, prop, NULL) != 0)
948 strlcpy(dns, prop, sizeof(dns));
949 else if (property_get("net.dns1", prop, NULL) != 0)
950 strlcpy(dns, prop, sizeof(dns));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200951
952 snprintf(tmp, sizeof(tmp), "dhcp.%s.dns2", ifname);
Peng Xub8fc5cc2017-05-10 17:27:28 -0700953 if (property_get(tmp, prop, NULL) != 0)
954 strlcpy(sec_dns, prop, sizeof(sec_dns));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200955#else /* ANDROID */
956#ifdef __linux__
Jouni Malinen016ae6c2019-11-04 17:00:01 +0200957 if (get_driver_type(dut) == DRIVER_OPENWRT)
Sarvepalli, Rajesh Babua76c6442016-03-18 20:34:26 +0530958 str_ps = "ps -w";
959 else
960 str_ps = "ps ax";
961 snprintf(tmp, sizeof(tmp),
962 "%s | grep dhclient | grep -v grep | grep -q %s",
963 str_ps, ifname);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200964 if (system(tmp) == 0)
965 is_dhcp = 1;
966 else {
Sarvepalli, Rajesh Babua76c6442016-03-18 20:34:26 +0530967 snprintf(tmp, sizeof(tmp),
968 "%s | grep udhcpc | grep -v grep | grep -q %s",
969 str_ps, ifname);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200970 if (system(tmp) == 0)
971 is_dhcp = 1;
972 else {
Sarvepalli, Rajesh Babua76c6442016-03-18 20:34:26 +0530973 snprintf(tmp, sizeof(tmp),
974 "%s | grep dhcpcd | grep -v grep | grep -q %s",
975 str_ps, ifname);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200976 if (system(tmp) == 0)
977 is_dhcp = 1;
978 }
979 }
980#endif /* __linux__ */
981
982 f = fopen("/etc/resolv.conf", "r");
983 if (f) {
vamsi krishnaa11d0732018-05-16 12:19:48 +0530984 char *pos, *pos2;
985
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200986 while (fgets(tmp, sizeof(tmp), f)) {
987 if (strncmp(tmp, "nameserver", 10) != 0)
988 continue;
989 pos = tmp + 10;
990 while (*pos == ' ' || *pos == '\t')
991 pos++;
992 pos2 = pos;
993 while (*pos2) {
994 if (*pos2 == '\n' || *pos2 == '\r') {
995 *pos2 = '\0';
996 break;
997 }
998 pos2++;
999 }
Peng Xub8fc5cc2017-05-10 17:27:28 -07001000 if (!dns[0])
1001 strlcpy(dns, pos, sizeof(dns));
1002 else if (!sec_dns[0])
1003 strlcpy(sec_dns, pos, sizeof(sec_dns));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001004 }
1005 fclose(f);
1006 }
1007#endif /* ANDROID */
1008
1009 snprintf(buf, buf_len, "dhcp,%d,ip,%s,mask,%s,primary-dns,%s",
1010 is_dhcp, ip, mask, dns);
1011 buf[buf_len - 1] = '\0';
1012
1013 return 0;
1014}
1015
1016
1017
1018
1019int get_ipv6_config(struct sigma_dut *dut, const char *ifname, char *buf,
1020 size_t buf_len)
1021{
1022#ifdef __linux__
1023#ifdef ANDROID
1024 char cmd[200], result[1000], *pos, *end;
1025 FILE *f;
1026 size_t len;
1027
1028 snprintf(cmd, sizeof(cmd), "ip addr show dev %s scope global", ifname);
1029 f = popen(cmd, "r");
1030 if (f == NULL)
1031 return -1;
1032 len = fread(result, 1, sizeof(result) - 1, f);
1033 pclose(f);
1034 if (len == 0)
1035 return -1;
1036 result[len] = '\0';
1037 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s result: %s\n", cmd, result);
1038
1039 pos = strstr(result, "inet6 ");
1040 if (pos == NULL)
1041 return -1;
1042 pos += 6;
1043 end = strchr(pos, ' ');
1044 if (end)
1045 *end = '\0';
1046 end = strchr(pos, '/');
1047 if (end)
1048 *end = '\0';
1049 snprintf(buf, buf_len, "ip,%s", pos);
1050 buf[buf_len - 1] = '\0';
1051 return 0;
1052#else /* ANDROID */
1053 struct ifaddrs *ifaddr, *ifa;
1054 int res, found = 0;
1055 char host[NI_MAXHOST];
1056
1057 if (getifaddrs(&ifaddr) < 0) {
1058 perror("getifaddrs");
1059 return -1;
1060 }
1061
1062 for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
1063 if (strcasecmp(ifname, ifa->ifa_name) != 0)
1064 continue;
1065 if (ifa->ifa_addr == NULL ||
1066 ifa->ifa_addr->sa_family != AF_INET6)
1067 continue;
1068
1069 res = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in6),
1070 host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
1071 if (res != 0) {
1072 sigma_dut_print(dut, DUT_MSG_DEBUG, "getnameinfo: %s",
1073 gai_strerror(res));
1074 continue;
1075 }
1076 if (strncmp(host, "fe80::", 6) == 0)
1077 continue; /* skip link-local */
1078
1079 sigma_dut_print(dut, DUT_MSG_DEBUG, "ifaddr: %s", host);
1080 found = 1;
1081 break;
1082 }
1083
1084 freeifaddrs(ifaddr);
1085
1086 if (found) {
1087 char *pos;
1088 pos = strchr(host, '%');
1089 if (pos)
1090 *pos = '\0';
1091 snprintf(buf, buf_len, "ip,%s", host);
1092 buf[buf_len - 1] = '\0';
1093 return 0;
1094 }
1095
1096#endif /* ANDROID */
1097#endif /* __linux__ */
1098 return -1;
1099}
1100
1101
Jouni Malinenf7222712019-06-13 01:50:21 +03001102static enum sigma_cmd_result cmd_sta_get_ip_config(struct sigma_dut *dut,
1103 struct sigma_conn *conn,
1104 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001105{
1106 const char *intf = get_param(cmd, "Interface");
1107 const char *ifname;
1108 char buf[200];
1109 const char *val;
1110 int type = 1;
1111
1112 if (intf == NULL)
1113 return -1;
1114
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001115 if (strcmp(intf, get_main_ifname(dut)) == 0)
1116 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001117 else
1118 ifname = intf;
1119
1120 /*
1121 * UCC may assume the IP address to be available immediately after
1122 * association without trying to run sta_get_ip_config multiple times.
1123 * Sigma CAPI does not specify this command as a block command that
1124 * would wait for the address to become available, but to pass tests
1125 * more reliably, it looks like such a wait may be needed here.
1126 */
1127 if (wait_ip_addr(dut, ifname, 15) < 0) {
1128 sigma_dut_print(dut, DUT_MSG_INFO, "Could not get IP address "
1129 "for sta_get_ip_config");
1130 /*
1131 * Try to continue anyway since many UCC tests do not really
1132 * care about the return value from here..
1133 */
1134 }
1135
1136 val = get_param(cmd, "Type");
1137 if (val)
1138 type = atoi(val);
1139 if (type == 2 || dut->last_set_ip_config_ipv6) {
1140 int i;
1141
1142 /*
1143 * Since we do not have proper wait for IPv6 addresses, use a
1144 * fixed two second delay here as a workaround for UCC script
1145 * assuming IPv6 address is available when this command returns.
1146 * Some scripts did not use Type,2 properly for IPv6, so include
1147 * also the cases where the previous sta_set_ip_config indicated
1148 * use of IPv6.
1149 */
1150 sigma_dut_print(dut, DUT_MSG_INFO, "Wait up to extra ten seconds in sta_get_ip_config for IPv6 address");
1151 for (i = 0; i < 10; i++) {
1152 sleep(1);
1153 if (get_ipv6_config(dut, ifname, buf, sizeof(buf)) == 0)
1154 {
1155 sigma_dut_print(dut, DUT_MSG_INFO, "Found IPv6 address");
1156 send_resp(dut, conn, SIGMA_COMPLETE, buf);
1157#ifdef ANDROID
1158 sigma_dut_print(dut, DUT_MSG_INFO,
1159 "Adding IPv6 rule on Android");
1160 add_ipv6_rule(dut, intf);
1161#endif /* ANDROID */
1162
1163 return 0;
1164 }
1165 }
1166 }
1167 if (type == 1) {
1168 if (get_ip_config(dut, ifname, buf, sizeof(buf)) < 0)
1169 return -2;
1170 } else if (type == 2) {
1171 if (get_ipv6_config(dut, ifname, buf, sizeof(buf)) < 0)
1172 return -2;
1173 } else {
1174 send_resp(dut, conn, SIGMA_ERROR,
1175 "errorCode,Unsupported address type");
1176 return 0;
1177 }
1178
1179 send_resp(dut, conn, SIGMA_COMPLETE, buf);
1180 return 0;
1181}
1182
1183
1184static void kill_dhcp_client(struct sigma_dut *dut, const char *ifname)
1185{
1186#ifdef __linux__
1187 char buf[200];
1188 char path[128];
1189 struct stat s;
1190
1191#ifdef ANDROID
1192 snprintf(path, sizeof(path), "/data/misc/dhcp/dhcpcd-%s.pid", ifname);
1193#else /* ANDROID */
1194 snprintf(path, sizeof(path), "/var/run/dhclient-%s.pid", ifname);
1195#endif /* ANDROID */
1196 if (stat(path, &s) == 0) {
1197 snprintf(buf, sizeof(buf), "kill `cat %s`", path);
1198 sigma_dut_print(dut, DUT_MSG_INFO,
1199 "Kill previous DHCP client: %s", buf);
1200 if (system(buf) != 0)
1201 sigma_dut_print(dut, DUT_MSG_INFO,
1202 "Failed to kill DHCP client");
1203 unlink(path);
1204 sleep(1);
1205 } else {
1206 snprintf(path, sizeof(path), "/var/run/dhcpcd-%s.pid", ifname);
1207
1208 if (stat(path, &s) == 0) {
1209 snprintf(buf, sizeof(buf), "kill `cat %s`", path);
1210 sigma_dut_print(dut, DUT_MSG_INFO,
1211 "Kill previous DHCP client: %s", buf);
1212 if (system(buf) != 0)
1213 sigma_dut_print(dut, DUT_MSG_INFO,
1214 "Failed to kill DHCP client");
1215 unlink(path);
1216 sleep(1);
1217 }
1218 }
1219#endif /* __linux__ */
1220}
1221
1222
1223static int start_dhcp_client(struct sigma_dut *dut, const char *ifname)
1224{
1225#ifdef __linux__
1226 char buf[200];
1227
1228#ifdef ANDROID
Purushottam Kushwaha46d64262016-08-23 17:57:53 +05301229 if (access("/system/bin/dhcpcd", F_OK) != -1) {
1230 snprintf(buf, sizeof(buf),
1231 "/system/bin/dhcpcd -b %s", ifname);
1232 } else if (access("/system/bin/dhcptool", F_OK) != -1) {
1233 snprintf(buf, sizeof(buf), "/system/bin/dhcptool %s &", ifname);
Ankita Bajaj8454e5d2019-04-05 16:04:55 +05301234 } else if (access("/vendor/bin/dhcpcd", F_OK) != -1) {
1235 snprintf(buf, sizeof(buf), "/vendor/bin/dhcpcd -b %s", ifname);
1236 } else if (access("/vendor/bin/dhcptool", F_OK) != -1) {
1237 snprintf(buf, sizeof(buf), "/vendor/bin/dhcptool %s", ifname);
Purushottam Kushwaha46d64262016-08-23 17:57:53 +05301238 } else {
1239 sigma_dut_print(dut, DUT_MSG_ERROR,
1240 "DHCP client program missing");
1241 return 0;
1242 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001243#else /* ANDROID */
1244 snprintf(buf, sizeof(buf),
1245 "dhclient -nw -pf /var/run/dhclient-%s.pid %s",
1246 ifname, ifname);
1247#endif /* ANDROID */
1248 sigma_dut_print(dut, DUT_MSG_INFO, "Start DHCP client: %s", buf);
1249 if (system(buf) != 0) {
1250 snprintf(buf, sizeof(buf), "dhcpcd -t 0 %s &", ifname);
1251 if (system(buf) != 0) {
1252 sigma_dut_print(dut, DUT_MSG_INFO,
1253 "Failed to start DHCP client");
1254#ifndef ANDROID
1255 return -1;
1256#endif /* ANDROID */
1257 }
1258 }
1259#endif /* __linux__ */
1260
1261 return 0;
1262}
1263
1264
1265static int clear_ip_addr(struct sigma_dut *dut, const char *ifname)
1266{
1267#ifdef __linux__
1268 char buf[200];
1269
1270 snprintf(buf, sizeof(buf), "ip addr flush dev %s", ifname);
1271 if (system(buf) != 0) {
1272 sigma_dut_print(dut, DUT_MSG_INFO,
1273 "Failed to clear IP addresses");
1274 return -1;
1275 }
1276#endif /* __linux__ */
1277
1278 return 0;
1279}
1280
1281
1282#ifdef ANDROID
1283static int add_ipv6_rule(struct sigma_dut *dut, const char *ifname)
1284{
1285 char cmd[200], *result, *pos;
1286 FILE *fp;
Pradeep Reddy POTTETIf58a1fe2016-10-13 17:22:03 +05301287 int tableid;
1288 size_t len, result_len = 1000;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001289
1290 snprintf(cmd, sizeof(cmd), "ip -6 route list table all | grep %s",
1291 ifname);
1292 fp = popen(cmd, "r");
1293 if (fp == NULL)
1294 return -1;
1295
1296 result = malloc(result_len);
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05301297 if (result == NULL) {
1298 fclose(fp);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001299 return -1;
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05301300 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001301
Pradeep Reddy POTTETIf58a1fe2016-10-13 17:22:03 +05301302 len = fread(result, 1, result_len - 1, fp);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001303 fclose(fp);
1304
1305 if (len == 0) {
1306 free(result);
1307 return -1;
1308 }
Pradeep Reddy POTTETIf58a1fe2016-10-13 17:22:03 +05301309 result[len] = '\0';
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001310
1311 pos = strstr(result, "table ");
1312 if (pos == NULL) {
1313 free(result);
1314 return -1;
1315 }
1316
1317 pos += strlen("table ");
1318 tableid = atoi(pos);
1319 if (tableid != 0) {
1320 if (system("ip -6 rule del prio 22000") != 0) {
1321 /* ignore any error */
1322 }
1323 snprintf(cmd, sizeof(cmd),
1324 "ip -6 rule add from all lookup %d prio 22000",
1325 tableid);
1326 if (system(cmd) != 0) {
1327 sigma_dut_print(dut, DUT_MSG_INFO,
1328 "Failed to run %s", cmd);
1329 free(result);
1330 return -1;
1331 }
1332 } else {
1333 sigma_dut_print(dut, DUT_MSG_INFO,
1334 "No Valid Table Id found %s", pos);
1335 free(result);
1336 return -1;
1337 }
1338 free(result);
1339
1340 return 0;
1341}
1342#endif /* ANDROID */
1343
1344
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301345int set_ipv4_addr(struct sigma_dut *dut, const char *ifname,
1346 const char *ip, const char *mask)
1347{
1348 char buf[200];
1349
1350 snprintf(buf, sizeof(buf), "ifconfig %s %s netmask %s",
1351 ifname, ip, mask);
1352 return system(buf) == 0;
1353}
1354
1355
1356int set_ipv4_gw(struct sigma_dut *dut, const char *gw)
1357{
1358 char buf[200];
1359
1360 if (!is_ip_addr(gw)) {
1361 sigma_dut_print(dut, DUT_MSG_DEBUG, "Invalid gw addr - %s", gw);
1362 return -1;
1363 }
1364
1365 snprintf(buf, sizeof(buf), "route add default gw %s", gw);
1366 if (!dut->no_ip_addr_set && system(buf) != 0) {
1367 snprintf(buf, sizeof(buf), "ip ro re default via %s",
1368 gw);
1369 if (system(buf) != 0)
1370 return 0;
1371 }
1372
1373 return 1;
1374}
1375
1376
Jouni Malinenf7222712019-06-13 01:50:21 +03001377static enum sigma_cmd_result cmd_sta_set_ip_config(struct sigma_dut *dut,
1378 struct sigma_conn *conn,
1379 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001380{
1381 const char *intf = get_param(cmd, "Interface");
1382 const char *ifname;
1383 char buf[200];
1384 const char *val, *ip, *mask, *gw;
1385 int type = 1;
1386
1387 if (intf == NULL)
1388 return -1;
1389
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001390 if (strcmp(intf, get_main_ifname(dut)) == 0)
1391 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001392 else
1393 ifname = intf;
1394
1395 if (if_nametoindex(ifname) == 0) {
1396 send_resp(dut, conn, SIGMA_ERROR,
1397 "ErrorCode,Unknown interface");
1398 return 0;
1399 }
1400
1401 val = get_param(cmd, "Type");
1402 if (val) {
1403 type = atoi(val);
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301404 if (type < 1 || type > 3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001405 send_resp(dut, conn, SIGMA_ERROR,
1406 "ErrorCode,Unsupported address type");
1407 return 0;
1408 }
1409 }
1410
1411 dut->last_set_ip_config_ipv6 = 0;
1412
1413 val = get_param(cmd, "dhcp");
1414 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "true") == 0)) {
1415 static_ip_file(0, NULL, NULL, NULL);
1416#ifdef __linux__
1417 if (type == 2) {
1418 dut->last_set_ip_config_ipv6 = 1;
1419 sigma_dut_print(dut, DUT_MSG_INFO, "Using IPv6 "
1420 "stateless address autoconfiguration");
1421#ifdef ANDROID
1422 /*
1423 * This sleep is required as the assignment in case of
1424 * Android is taking time and is done by the kernel.
1425 * The subsequent ping for IPv6 is impacting HS20 test
1426 * case.
1427 */
1428 sleep(2);
1429 add_ipv6_rule(dut, intf);
1430#endif /* ANDROID */
1431 /* Assume this happens by default */
1432 return 1;
1433 }
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301434 if (type != 3) {
1435 kill_dhcp_client(dut, ifname);
1436 if (start_dhcp_client(dut, ifname) < 0)
1437 return -2;
1438 } else {
1439 sigma_dut_print(dut, DUT_MSG_DEBUG,
1440 "Using FILS HLP DHCPv4 Rapid Commit");
1441 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001442
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001443 return 1;
1444#endif /* __linux__ */
1445 return -2;
1446 }
1447
1448 ip = get_param(cmd, "ip");
Pradeep Reddy POTTETIb18c5652016-01-18 12:45:37 +05301449 if (!ip) {
1450 send_resp(dut, conn, SIGMA_INVALID,
1451 "ErrorCode,Missing IP address");
1452 return 0;
1453 }
1454
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001455 mask = get_param(cmd, "mask");
Pradeep Reddy POTTETIb18c5652016-01-18 12:45:37 +05301456 if (!mask) {
1457 send_resp(dut, conn, SIGMA_INVALID,
1458 "ErrorCode,Missing subnet mask");
1459 return 0;
1460 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001461
1462 if (type == 2) {
1463 int net = atoi(mask);
1464
1465 if ((net < 0 && net > 64) || !is_ipv6_addr(ip))
1466 return -1;
1467
1468 if (dut->no_ip_addr_set) {
1469 snprintf(buf, sizeof(buf),
1470 "sysctl net.ipv6.conf.%s.disable_ipv6=1",
1471 ifname);
1472 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
1473 if (system(buf) != 0) {
1474 sigma_dut_print(dut, DUT_MSG_DEBUG,
1475 "Failed to disable IPv6 address before association");
1476 }
1477 } else {
1478 snprintf(buf, sizeof(buf),
1479 "ip -6 addr del %s/%s dev %s",
1480 ip, mask, ifname);
1481 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
1482 if (system(buf) != 0) {
1483 /*
1484 * This command may fail if the address being
1485 * deleted does not exist. Inaction here is
1486 * intentional.
1487 */
1488 }
1489
1490 snprintf(buf, sizeof(buf),
1491 "ip -6 addr add %s/%s dev %s",
1492 ip, mask, ifname);
1493 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
1494 if (system(buf) != 0) {
1495 send_resp(dut, conn, SIGMA_ERROR,
1496 "ErrorCode,Failed to set IPv6 address");
1497 return 0;
1498 }
1499 }
1500
1501 dut->last_set_ip_config_ipv6 = 1;
1502 static_ip_file(6, ip, mask, NULL);
1503 return 1;
1504 } else if (type == 1) {
Pradeep Reddy POTTETIb18c5652016-01-18 12:45:37 +05301505 if (!is_ip_addr(ip) || !is_ip_addr(mask))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001506 return -1;
1507 }
1508
1509 kill_dhcp_client(dut, ifname);
1510
1511 if (!dut->no_ip_addr_set) {
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301512 if (!set_ipv4_addr(dut, ifname, ip, mask)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001513 send_resp(dut, conn, SIGMA_ERROR,
1514 "ErrorCode,Failed to set IP address");
1515 return 0;
1516 }
1517 }
1518
1519 gw = get_param(cmd, "defaultGateway");
1520 if (gw) {
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301521 if (set_ipv4_gw(dut, gw) < 1) {
1522 send_resp(dut, conn, SIGMA_ERROR,
1523 "ErrorCode,Failed to set default gateway");
1524 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001525 }
1526 }
1527
1528 val = get_param(cmd, "primary-dns");
1529 if (val) {
1530 /* TODO */
1531 sigma_dut_print(dut, DUT_MSG_INFO, "Ignored primary-dns %s "
1532 "setting", val);
1533 }
1534
1535 val = get_param(cmd, "secondary-dns");
1536 if (val) {
1537 /* TODO */
1538 sigma_dut_print(dut, DUT_MSG_INFO, "Ignored secondary-dns %s "
1539 "setting", val);
1540 }
1541
1542 static_ip_file(4, ip, mask, gw);
1543
1544 return 1;
1545}
1546
1547
Jouni Malinenf7222712019-06-13 01:50:21 +03001548static enum sigma_cmd_result cmd_sta_get_info(struct sigma_dut *dut,
1549 struct sigma_conn *conn,
1550 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001551{
1552 /* const char *intf = get_param(cmd, "Interface"); */
1553 /* TODO: could report more details here */
1554 send_resp(dut, conn, SIGMA_COMPLETE, "vendor,Atheros");
1555 return 0;
1556}
1557
1558
Jouni Malinenf7222712019-06-13 01:50:21 +03001559static enum sigma_cmd_result cmd_sta_get_mac_address(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 char addr[20], resp[50];
1565
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05301566 if (dut->dev_role == DEVROLE_STA_CFON)
1567 return sta_cfon_get_mac_address(dut, conn, cmd);
1568
Jouni Malinen9540e012019-11-05 17:08:42 +02001569 start_sta_mode(dut);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001570 if (get_wpa_status(get_station_ifname(dut), "address",
1571 addr, sizeof(addr)) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001572 return -2;
1573
1574 snprintf(resp, sizeof(resp), "mac,%s", addr);
1575 send_resp(dut, conn, SIGMA_COMPLETE, resp);
1576 return 0;
1577}
1578
1579
Jouni Malinenf7222712019-06-13 01:50:21 +03001580static enum sigma_cmd_result cmd_sta_is_connected(struct sigma_dut *dut,
1581 struct sigma_conn *conn,
1582 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001583{
1584 /* const char *intf = get_param(cmd, "Interface"); */
1585 int connected = 0;
1586 char result[32];
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001587 if (get_wpa_status(get_station_ifname(dut), "wpa_state", result,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001588 sizeof(result)) < 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001589 sigma_dut_print(dut, DUT_MSG_INFO,
1590 "Could not get interface %s status",
1591 get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001592 return -2;
1593 }
1594
1595 sigma_dut_print(dut, DUT_MSG_DEBUG, "wpa_state=%s", result);
1596 if (strncmp(result, "COMPLETED", 9) == 0)
1597 connected = 1;
1598
1599 if (connected)
1600 send_resp(dut, conn, SIGMA_COMPLETE, "connected,1");
1601 else
1602 send_resp(dut, conn, SIGMA_COMPLETE, "connected,0");
1603
1604 return 0;
1605}
1606
1607
Jouni Malinenf7222712019-06-13 01:50:21 +03001608static enum sigma_cmd_result
1609cmd_sta_verify_ip_connection(struct sigma_dut *dut, struct sigma_conn *conn,
1610 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001611{
1612 /* const char *intf = get_param(cmd, "Interface"); */
1613 const char *dst, *timeout;
1614 int wait_time = 90;
1615 char buf[100];
1616 int res;
1617
1618 dst = get_param(cmd, "destination");
1619 if (dst == NULL || !is_ip_addr(dst))
1620 return -1;
1621
1622 timeout = get_param(cmd, "timeout");
1623 if (timeout) {
1624 wait_time = atoi(timeout);
1625 if (wait_time < 1)
1626 wait_time = 1;
1627 }
1628
1629 /* TODO: force renewal of IP lease if DHCP is enabled */
1630
1631 snprintf(buf, sizeof(buf), "ping %s -c 3 -W %d", dst, wait_time);
1632 res = system(buf);
1633 sigma_dut_print(dut, DUT_MSG_DEBUG, "ping returned: %d", res);
1634 if (res == 0)
1635 send_resp(dut, conn, SIGMA_COMPLETE, "connected,1");
1636 else if (res == 256)
1637 send_resp(dut, conn, SIGMA_COMPLETE, "connected,0");
1638 else
1639 return -2;
1640
1641 return 0;
1642}
1643
1644
Jouni Malinenf7222712019-06-13 01:50:21 +03001645static enum sigma_cmd_result cmd_sta_get_bssid(struct sigma_dut *dut,
1646 struct sigma_conn *conn,
1647 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001648{
1649 /* const char *intf = get_param(cmd, "Interface"); */
1650 char bssid[20], resp[50];
1651
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001652 if (get_wpa_status(get_station_ifname(dut), "bssid",
1653 bssid, sizeof(bssid)) < 0)
Peng Xub8fc5cc2017-05-10 17:27:28 -07001654 strlcpy(bssid, "00:00:00:00:00:00", sizeof(bssid));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001655
1656 snprintf(resp, sizeof(resp), "bssid,%s", bssid);
1657 send_resp(dut, conn, SIGMA_COMPLETE, resp);
1658 return 0;
1659}
1660
1661
1662#ifdef __SAMSUNG__
1663static int add_use_network(const char *ifname)
1664{
1665 char buf[100];
1666
1667 snprintf(buf, sizeof(buf), "USE_NETWORK ON");
1668 wpa_command(ifname, buf);
1669 return 0;
1670}
1671#endif /* __SAMSUNG__ */
1672
1673
1674static int add_network_common(struct sigma_dut *dut, struct sigma_conn *conn,
1675 const char *ifname, struct sigma_cmd *cmd)
1676{
1677 const char *ssid = get_param(cmd, "ssid");
1678 int id;
1679 const char *val;
1680
1681 if (ssid == NULL)
1682 return -1;
1683
1684 start_sta_mode(dut);
1685
1686#ifdef __SAMSUNG__
1687 add_use_network(ifname);
1688#endif /* __SAMSUNG__ */
1689
1690 id = add_network(ifname);
1691 if (id < 0)
1692 return -2;
1693 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding network %d", id);
1694
1695 if (set_network_quoted(ifname, id, "ssid", ssid) < 0)
1696 return -2;
1697
1698 dut->infra_network_id = id;
1699 snprintf(dut->infra_ssid, sizeof(dut->infra_ssid), "%s", ssid);
1700
1701 val = get_param(cmd, "program");
1702 if (!val)
1703 val = get_param(cmd, "prog");
1704 if (val && strcasecmp(val, "hs2") == 0) {
1705 char buf[100];
1706 snprintf(buf, sizeof(buf), "ENABLE_NETWORK %d no-connect", id);
1707 wpa_command(ifname, buf);
1708
1709 val = get_param(cmd, "prefer");
1710 if (val && atoi(val) > 0)
1711 set_network(ifname, id, "priority", "1");
1712 }
1713
1714 return id;
1715}
1716
1717
Jouni Malinenf7222712019-06-13 01:50:21 +03001718static enum sigma_cmd_result cmd_sta_set_encryption(struct sigma_dut *dut,
1719 struct sigma_conn *conn,
1720 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001721{
1722 const char *intf = get_param(cmd, "Interface");
1723 const char *ssid = get_param(cmd, "ssid");
1724 const char *type = get_param(cmd, "encpType");
1725 const char *ifname;
1726 char buf[200];
1727 int id;
1728
1729 if (intf == NULL || ssid == NULL)
1730 return -1;
1731
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001732 if (strcmp(intf, get_main_ifname(dut)) == 0)
1733 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001734 else
1735 ifname = intf;
1736
1737 id = add_network_common(dut, conn, ifname, cmd);
1738 if (id < 0)
1739 return id;
1740
1741 if (set_network(ifname, id, "key_mgmt", "NONE") < 0)
1742 return -2;
1743
1744 if (type && strcasecmp(type, "wep") == 0) {
1745 const char *val;
1746 int i;
1747
1748 val = get_param(cmd, "activeKey");
1749 if (val) {
1750 int keyid;
1751 keyid = atoi(val);
1752 if (keyid < 1 || keyid > 4)
1753 return -1;
1754 snprintf(buf, sizeof(buf), "%d", keyid - 1);
1755 if (set_network(ifname, id, "wep_tx_keyidx", buf) < 0)
1756 return -2;
1757 }
1758
1759 for (i = 0; i < 4; i++) {
1760 snprintf(buf, sizeof(buf), "key%d", i + 1);
1761 val = get_param(cmd, buf);
1762 if (val == NULL)
1763 continue;
1764 snprintf(buf, sizeof(buf), "wep_key%d", i);
1765 if (set_network(ifname, id, buf, val) < 0)
1766 return -2;
1767 }
1768 }
1769
1770 return 1;
1771}
1772
1773
Jouni Malinene4fde732019-03-25 22:29:37 +02001774static int set_akm_suites(struct sigma_dut *dut, const char *ifname,
1775 int id, const char *val)
1776{
1777 char key_mgmt[200], *end, *pos;
1778 const char *in_pos = val;
1779
Jouni Malinen8179fee2019-03-28 03:19:47 +02001780 dut->akm_values = 0;
Jouni Malinene4fde732019-03-25 22:29:37 +02001781 pos = key_mgmt;
1782 end = pos + sizeof(key_mgmt);
1783 while (*in_pos) {
1784 int res, akm = atoi(in_pos);
1785 const char *str;
1786
Jouni Malinen8179fee2019-03-28 03:19:47 +02001787 if (akm >= 0 && akm < 32)
1788 dut->akm_values |= 1 << akm;
1789
Jouni Malinene4fde732019-03-25 22:29:37 +02001790 switch (akm) {
1791 case AKM_WPA_EAP:
1792 str = "WPA-EAP";
1793 break;
1794 case AKM_WPA_PSK:
1795 str = "WPA-PSK";
1796 break;
1797 case AKM_FT_EAP:
1798 str = "FT-EAP";
1799 break;
1800 case AKM_FT_PSK:
1801 str = "FT-PSK";
1802 break;
1803 case AKM_EAP_SHA256:
1804 str = "WPA-EAP-SHA256";
1805 break;
1806 case AKM_PSK_SHA256:
1807 str = "WPA-PSK-SHA256";
1808 break;
1809 case AKM_SAE:
1810 str = "SAE";
1811 break;
1812 case AKM_FT_SAE:
1813 str = "FT-SAE";
1814 break;
1815 case AKM_SUITE_B:
1816 str = "WPA-EAP-SUITE-B-192";
1817 break;
1818 case AKM_FT_SUITE_B:
1819 str = "FT-EAP-SHA384";
1820 break;
1821 case AKM_FILS_SHA256:
1822 str = "FILS-SHA256";
1823 break;
1824 case AKM_FILS_SHA384:
1825 str = "FILS-SHA384";
1826 break;
1827 case AKM_FT_FILS_SHA256:
1828 str = "FT-FILS-SHA256";
1829 break;
1830 case AKM_FT_FILS_SHA384:
1831 str = "FT-FILS-SHA384";
1832 break;
1833 default:
1834 sigma_dut_print(dut, DUT_MSG_ERROR,
1835 "Unsupported AKMSuitetype %d", akm);
1836 return -1;
1837 }
1838
1839 res = snprintf(pos, end - pos, "%s%s",
1840 pos == key_mgmt ? "" : " ", str);
1841 if (res < 0 || res >= end - pos)
1842 return -1;
1843 pos += res;
1844
1845 in_pos = strchr(in_pos, ';');
1846 if (!in_pos)
1847 break;
1848 while (*in_pos == ';')
1849 in_pos++;
1850 }
1851 sigma_dut_print(dut, DUT_MSG_DEBUG, "AKMSuiteType %s --> %s",
1852 val, key_mgmt);
1853 return set_network(ifname, id, "key_mgmt", key_mgmt);
1854}
1855
1856
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001857static int set_wpa_common(struct sigma_dut *dut, struct sigma_conn *conn,
1858 const char *ifname, struct sigma_cmd *cmd)
1859{
1860 const char *val;
1861 int id;
Jouni Malinenad395a22017-09-01 21:13:46 +03001862 int cipher_set = 0;
Jouni Malinen47dcc952017-10-09 16:43:24 +03001863 int owe;
Sunil Duttc75a1e62018-01-11 20:47:50 +05301864 int suite_b = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001865
1866 id = add_network_common(dut, conn, ifname, cmd);
1867 if (id < 0)
1868 return id;
1869
Jouni Malinen47dcc952017-10-09 16:43:24 +03001870 val = get_param(cmd, "Type");
1871 owe = val && strcasecmp(val, "OWE") == 0;
1872
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001873 val = get_param(cmd, "keyMgmtType");
Jouni Malinen47dcc952017-10-09 16:43:24 +03001874 if (!val && owe)
1875 val = "OWE";
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001876 if (val == NULL) {
Jouni Malinene4fde732019-03-25 22:29:37 +02001877 /* keyMgmtType is being replaced with AKMSuiteType, so ignore
1878 * this missing parameter and assume proto=WPA2. */
1879 if (set_network(ifname, id, "proto", "WPA2") < 0)
1880 return ERROR_SEND_STATUS;
1881 } else if (strcasecmp(val, "wpa") == 0 ||
1882 strcasecmp(val, "wpa-psk") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001883 if (set_network(ifname, id, "proto", "WPA") < 0)
1884 return -2;
1885 } else if (strcasecmp(val, "wpa2") == 0 ||
1886 strcasecmp(val, "wpa2-psk") == 0 ||
1887 strcasecmp(val, "wpa2-ft") == 0 ||
1888 strcasecmp(val, "wpa2-sha256") == 0) {
1889 if (set_network(ifname, id, "proto", "WPA2") < 0)
1890 return -2;
Pradeep Reddy POTTETI6d04b3b2016-11-15 14:51:26 +05301891 } else if (strcasecmp(val, "wpa2-wpa-psk") == 0 ||
1892 strcasecmp(val, "wpa2-wpa-ent") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001893 if (set_network(ifname, id, "proto", "WPA WPA2") < 0)
1894 return -2;
Jouni Malinenad395a22017-09-01 21:13:46 +03001895 } else if (strcasecmp(val, "SuiteB") == 0) {
Sunil Duttc75a1e62018-01-11 20:47:50 +05301896 suite_b = 1;
Jouni Malinenad395a22017-09-01 21:13:46 +03001897 if (set_network(ifname, id, "proto", "WPA2") < 0)
1898 return -2;
Jouni Malinen47dcc952017-10-09 16:43:24 +03001899 } else if (strcasecmp(val, "OWE") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001900 } else {
1901 send_resp(dut, conn, SIGMA_INVALID, "errorCode,Unrecognized keyMgmtType value");
1902 return 0;
1903 }
1904
1905 val = get_param(cmd, "encpType");
Jouni Malinenad395a22017-09-01 21:13:46 +03001906 if (val) {
1907 cipher_set = 1;
1908 if (strcasecmp(val, "tkip") == 0) {
1909 if (set_network(ifname, id, "pairwise", "TKIP") < 0)
1910 return -2;
1911 } else if (strcasecmp(val, "aes-ccmp") == 0) {
1912 if (set_network(ifname, id, "pairwise", "CCMP") < 0)
1913 return -2;
1914 } else if (strcasecmp(val, "aes-ccmp-tkip") == 0) {
1915 if (set_network(ifname, id, "pairwise",
1916 "CCMP TKIP") < 0)
1917 return -2;
1918 } else if (strcasecmp(val, "aes-gcmp") == 0) {
1919 if (set_network(ifname, id, "pairwise", "GCMP") < 0)
1920 return -2;
1921 if (set_network(ifname, id, "group", "GCMP") < 0)
1922 return -2;
1923 } else {
1924 send_resp(dut, conn, SIGMA_ERROR,
1925 "errorCode,Unrecognized encpType value");
1926 return 0;
1927 }
1928 }
1929
1930 val = get_param(cmd, "PairwiseCipher");
1931 if (val) {
1932 cipher_set = 1;
1933 /* TODO: Support space separated list */
1934 if (strcasecmp(val, "AES-GCMP-256") == 0) {
1935 if (set_network(ifname, id, "pairwise", "GCMP-256") < 0)
1936 return -2;
1937 } else if (strcasecmp(val, "AES-CCMP-256") == 0) {
1938 if (set_network(ifname, id, "pairwise",
1939 "CCMP-256") < 0)
1940 return -2;
1941 } else if (strcasecmp(val, "AES-GCMP-128") == 0) {
1942 if (set_network(ifname, id, "pairwise", "GCMP") < 0)
1943 return -2;
1944 } else if (strcasecmp(val, "AES-CCMP-128") == 0) {
1945 if (set_network(ifname, id, "pairwise", "CCMP") < 0)
1946 return -2;
1947 } else {
1948 send_resp(dut, conn, SIGMA_ERROR,
1949 "errorCode,Unrecognized PairwiseCipher value");
1950 return 0;
1951 }
1952 }
1953
Jouni Malinen47dcc952017-10-09 16:43:24 +03001954 if (!cipher_set && !owe) {
Jouni Malinenad395a22017-09-01 21:13:46 +03001955 send_resp(dut, conn, SIGMA_ERROR,
1956 "errorCode,Missing encpType and PairwiseCipher");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001957 return 0;
1958 }
Jouni Malinenad395a22017-09-01 21:13:46 +03001959
1960 val = get_param(cmd, "GroupCipher");
1961 if (val) {
1962 if (strcasecmp(val, "AES-GCMP-256") == 0) {
1963 if (set_network(ifname, id, "group", "GCMP-256") < 0)
1964 return -2;
1965 } else if (strcasecmp(val, "AES-CCMP-256") == 0) {
1966 if (set_network(ifname, id, "group", "CCMP-256") < 0)
1967 return -2;
1968 } else if (strcasecmp(val, "AES-GCMP-128") == 0) {
1969 if (set_network(ifname, id, "group", "GCMP") < 0)
1970 return -2;
1971 } else if (strcasecmp(val, "AES-CCMP-128") == 0) {
1972 if (set_network(ifname, id, "group", "CCMP") < 0)
1973 return -2;
1974 } else {
1975 send_resp(dut, conn, SIGMA_ERROR,
1976 "errorCode,Unrecognized GroupCipher value");
1977 return 0;
1978 }
1979 }
1980
Jouni Malinen7b239522017-09-14 21:37:18 +03001981 val = get_param(cmd, "GroupMgntCipher");
Jouni Malinenad395a22017-09-01 21:13:46 +03001982 if (val) {
Jouni Malinene8898cb2017-09-26 17:55:26 +03001983 const char *cipher;
1984
1985 if (strcasecmp(val, "BIP-GMAC-256") == 0) {
1986 cipher = "BIP-GMAC-256";
1987 } else if (strcasecmp(val, "BIP-CMAC-256") == 0) {
1988 cipher = "BIP-CMAC-256";
1989 } else if (strcasecmp(val, "BIP-GMAC-128") == 0) {
1990 cipher = "BIP-GMAC-128";
1991 } else if (strcasecmp(val, "BIP-CMAC-128") == 0) {
1992 cipher = "AES-128-CMAC";
1993 } else {
1994 send_resp(dut, conn, SIGMA_INVALID,
1995 "errorCode,Unsupported GroupMgntCipher");
1996 return 0;
1997 }
1998 if (set_network(ifname, id, "group_mgmt", cipher) < 0) {
1999 send_resp(dut, conn, SIGMA_INVALID,
2000 "errorCode,Failed to set GroupMgntCipher");
2001 return 0;
2002 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002003 }
2004
Jouni Malinene4fde732019-03-25 22:29:37 +02002005 val = get_param(cmd, "AKMSuiteType");
2006 if (val && set_akm_suites(dut, ifname, id, val) < 0)
2007 return ERROR_SEND_STATUS;
2008
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002009 dut->sta_pmf = STA_PMF_DISABLED;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302010
2011 if (dut->program == PROGRAM_OCE) {
2012 dut->sta_pmf = STA_PMF_OPTIONAL;
2013 if (set_network(ifname, id, "ieee80211w", "1") < 0)
2014 return -2;
2015 }
2016
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002017 val = get_param(cmd, "PMF");
2018 if (val) {
2019 if (strcasecmp(val, "Required") == 0 ||
2020 strcasecmp(val, "Forced_Required") == 0) {
2021 dut->sta_pmf = STA_PMF_REQUIRED;
2022 if (set_network(ifname, id, "ieee80211w", "2") < 0)
2023 return -2;
2024 } else if (strcasecmp(val, "Optional") == 0) {
2025 dut->sta_pmf = STA_PMF_OPTIONAL;
2026 if (set_network(ifname, id, "ieee80211w", "1") < 0)
2027 return -2;
2028 } else if (strcasecmp(val, "Disabled") == 0 ||
Kiran Kumar Lokere07da3b22018-12-16 22:42:49 -08002029 strcasecmp(val, "Disable") == 0 ||
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002030 strcasecmp(val, "Forced_Disabled") == 0) {
2031 dut->sta_pmf = STA_PMF_DISABLED;
2032 } else {
2033 send_resp(dut, conn, SIGMA_INVALID, "errorCode,Unrecognized PMF value");
2034 return 0;
2035 }
Sunil Duttc75a1e62018-01-11 20:47:50 +05302036 } else if (owe || suite_b) {
Jouni Malinen1287cd72018-01-04 17:08:01 +02002037 dut->sta_pmf = STA_PMF_REQUIRED;
2038 if (set_network(ifname, id, "ieee80211w", "2") < 0)
2039 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002040 }
2041
2042 return id;
2043}
2044
2045
Jouni Malinenf7222712019-06-13 01:50:21 +03002046static enum sigma_cmd_result cmd_sta_set_psk(struct sigma_dut *dut,
2047 struct sigma_conn *conn,
2048 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002049{
2050 const char *intf = get_param(cmd, "Interface");
Jouni Malinen992a81e2017-08-22 13:57:47 +03002051 const char *type = get_param(cmd, "Type");
Jouni Malinen1287cd72018-01-04 17:08:01 +02002052 const char *pmf = get_param(cmd, "PMF");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002053 const char *network_mode = get_param(cmd, "network_mode");
Jouni Malinene4fde732019-03-25 22:29:37 +02002054 const char *akm = get_param(cmd, "AKMSuiteType");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002055 const char *ifname, *val, *alg;
2056 int id;
Jouni Malinen4b3769d2019-10-10 16:20:29 +03002057 char buf[50];
Jouni Malinen11e55212019-11-22 21:46:59 +02002058 int sae_pwe = -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002059
2060 if (intf == NULL)
2061 return -1;
2062
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002063 if (strcmp(intf, get_main_ifname(dut)) == 0)
2064 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002065 else
2066 ifname = intf;
2067
2068 id = set_wpa_common(dut, conn, ifname, cmd);
2069 if (id < 0)
2070 return id;
2071
2072 val = get_param(cmd, "keyMgmtType");
2073 alg = get_param(cmd, "micAlg");
2074
Jouni Malinen992a81e2017-08-22 13:57:47 +03002075 if (type && strcasecmp(type, "SAE") == 0) {
Jouni Malinene4fde732019-03-25 22:29:37 +02002076 if (!akm && val && strcasecmp(val, "wpa2-ft") == 0) {
Jouni Malinen992a81e2017-08-22 13:57:47 +03002077 if (set_network(ifname, id, "key_mgmt", "FT-SAE") < 0)
2078 return -2;
Jouni Malinene4fde732019-03-25 22:29:37 +02002079 } else if (!akm) {
Jouni Malinen992a81e2017-08-22 13:57:47 +03002080 if (set_network(ifname, id, "key_mgmt", "SAE") < 0)
2081 return -2;
2082 }
2083 if (wpa_command(ifname, "SET sae_groups ") != 0) {
2084 sigma_dut_print(dut, DUT_MSG_ERROR,
2085 "Failed to clear sae_groups to default");
2086 return -2;
2087 }
Jouni Malinen1287cd72018-01-04 17:08:01 +02002088 if (!pmf) {
2089 dut->sta_pmf = STA_PMF_REQUIRED;
2090 if (set_network(ifname, id, "ieee80211w", "2") < 0)
2091 return -2;
2092 }
Jouni Malinen0ab50f42017-08-31 01:34:59 +03002093 } else if (type && strcasecmp(type, "PSK-SAE") == 0) {
2094 if (val && strcasecmp(val, "wpa2-ft") == 0) {
2095 if (set_network(ifname, id, "key_mgmt",
2096 "FT-SAE FT-PSK") < 0)
2097 return -2;
Jouni Malinen3b73d872019-06-12 03:13:25 +03002098 } else if (!akm) {
Jouni Malinen0ab50f42017-08-31 01:34:59 +03002099 if (set_network(ifname, id, "key_mgmt",
2100 "SAE WPA-PSK") < 0)
2101 return -2;
2102 }
2103 if (wpa_command(ifname, "SET sae_groups ") != 0) {
2104 sigma_dut_print(dut, DUT_MSG_ERROR,
2105 "Failed to clear sae_groups to default");
2106 return -2;
2107 }
Jouni Malinen1287cd72018-01-04 17:08:01 +02002108 if (!pmf) {
2109 dut->sta_pmf = STA_PMF_OPTIONAL;
2110 if (set_network(ifname, id, "ieee80211w", "1") < 0)
2111 return -2;
2112 }
Jouni Malinen992a81e2017-08-22 13:57:47 +03002113 } else if (alg && strcasecmp(alg, "SHA-256") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002114 if (set_network(ifname, id, "key_mgmt", "WPA-PSK-SHA256") < 0)
2115 return -2;
2116 } else if (alg && strcasecmp(alg, "SHA-1") == 0) {
2117 if (set_network(ifname, id, "key_mgmt", "WPA-PSK") < 0)
2118 return -2;
Ashwini Patil6dbf7b02017-03-20 13:42:11 +05302119 } else if (val && strcasecmp(val, "wpa2-ft") == 0) {
2120 if (set_network(ifname, id, "key_mgmt", "FT-PSK") < 0)
2121 return -2;
Jouni Malinen3b73d872019-06-12 03:13:25 +03002122 } else if (!akm &&
2123 ((val && strcasecmp(val, "wpa2-sha256") == 0) ||
2124 dut->sta_pmf == STA_PMF_REQUIRED)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002125 if (set_network(ifname, id, "key_mgmt",
2126 "WPA-PSK WPA-PSK-SHA256") < 0)
2127 return -2;
Jouni Malinen77ff3f02019-03-28 03:45:40 +02002128 } else if (!akm && dut->sta_pmf == STA_PMF_OPTIONAL) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002129 if (set_network(ifname, id, "key_mgmt",
2130 "WPA-PSK WPA-PSK-SHA256") < 0)
2131 return -2;
Jouni Malinen77ff3f02019-03-28 03:45:40 +02002132 } else if (!akm) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002133 if (set_network(ifname, id, "key_mgmt", "WPA-PSK") < 0)
2134 return -2;
2135 }
2136
2137 val = get_param(cmd, "passPhrase");
2138 if (val == NULL)
2139 return -1;
Jouni Malinen2126f422017-10-11 23:24:33 +03002140 if (type && strcasecmp(type, "SAE") == 0) {
2141 if (set_network_quoted(ifname, id, "sae_password", val) < 0)
2142 return -2;
2143 } else {
2144 if (set_network_quoted(ifname, id, "psk", val) < 0)
2145 return -2;
2146 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002147
Jouni Malinen78d10c42019-03-25 22:34:32 +02002148 val = get_param(cmd, "PasswordId");
2149 if (val && set_network_quoted(ifname, id, "sae_password_id", val) < 0)
2150 return ERROR_SEND_STATUS;
2151
Jouni Malinen992a81e2017-08-22 13:57:47 +03002152 val = get_param(cmd, "ECGroupID");
2153 if (val) {
Jouni Malinen992a81e2017-08-22 13:57:47 +03002154 snprintf(buf, sizeof(buf), "SET sae_groups %u", atoi(val));
2155 if (wpa_command(ifname, buf) != 0) {
2156 sigma_dut_print(dut, DUT_MSG_ERROR,
2157 "Failed to clear sae_groups");
2158 return -2;
2159 }
2160 }
2161
Jouni Malinen68143132017-09-02 02:34:08 +03002162 val = get_param(cmd, "InvalidSAEElement");
2163 if (val) {
2164 free(dut->sae_commit_override);
2165 dut->sae_commit_override = strdup(val);
2166 }
2167
Jouni Malinen4b3769d2019-10-10 16:20:29 +03002168 val = get_param(cmd, "PMKID_Include");
2169 if (val) {
2170 snprintf(buf, sizeof(buf), "SET sae_pmkid_in_assoc %d",
2171 get_enable_disable(val));
2172 wpa_command(intf, buf);
2173 }
2174
Jouni Malinen11e55212019-11-22 21:46:59 +02002175 val = get_param(cmd, "sae_pwe");
2176 if (val) {
2177 if (strcasecmp(val, "h2e") == 0) {
2178 dut->sae_pwe = SAE_PWE_H2E;
2179 } else if (strcasecmp(val, "loop") == 0) {
2180 dut->sae_pwe = SAE_PWE_LOOP;
2181 } else {
2182 send_resp(dut, conn, SIGMA_ERROR,
2183 "errorCode,Unsupported sae_pwe value");
2184 return STATUS_SENT_ERROR;
2185 }
2186 }
2187 if (dut->sae_pwe == SAE_PWE_LOOP)
2188 sae_pwe = 0;
2189 else if (dut->sae_pwe == SAE_PWE_H2E)
2190 sae_pwe = 1;
2191 else if (dut->sae_h2e_default)
2192 sae_pwe = 2;
2193 snprintf(buf, sizeof(buf), "SET sae_pwe %d", sae_pwe);
2194 if (sae_pwe >= 0 && wpa_command(ifname, buf) != 0)
2195 return ERROR_SEND_STATUS;
2196
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002197 if (dut->program == PROGRAM_60GHZ && network_mode &&
2198 strcasecmp(network_mode, "PBSS") == 0 &&
2199 set_network(ifname, id, "pbss", "1") < 0)
2200 return -2;
2201
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002202 return 1;
2203}
2204
2205
Jouni Malinen8ac93452019-08-14 15:19:13 +03002206static enum sigma_cmd_result set_trust_root_system(struct sigma_dut *dut,
2207 struct sigma_conn *conn,
2208 const char *ifname, int id)
2209{
2210 char buf[200];
2211
2212 snprintf(buf, sizeof(buf), "%s/certs", sigma_cert_path);
2213 if (!file_exists(buf))
2214 strlcpy(buf, "/system/etc/security/cacerts", sizeof(buf));
2215 if (!file_exists(buf))
2216 strlcpy(buf, "/etc/ssl/certs", sizeof(buf));
2217 if (!file_exists(buf)) {
2218 char msg[300];
2219
2220 snprintf(msg, sizeof(msg),
2221 "ErrorCode,trustedRootCA system store (%s) not found",
2222 buf);
2223 send_resp(dut, conn, SIGMA_ERROR, msg);
2224 return STATUS_SENT_ERROR;
2225 }
2226
2227 if (set_network_quoted(ifname, id, "ca_path", buf) < 0)
2228 return ERROR_SEND_STATUS;
2229
2230 return SUCCESS_SEND_STATUS;
2231}
2232
2233
2234static enum sigma_cmd_result set_trust_root(struct sigma_dut *dut,
2235 struct sigma_conn *conn,
2236 const char *ifname, int id,
2237 const char *val)
2238{
2239 char buf[200];
2240#ifdef ANDROID
2241 unsigned char kvalue[KEYSTORE_MESSAGE_SIZE];
2242 int length;
2243#endif /* ANDROID */
2244
2245 if (strcmp(val, "DEFAULT") == 0)
2246 return set_trust_root_system(dut, conn, ifname, id);
2247
2248#ifdef ANDROID
2249 snprintf(buf, sizeof(buf), "CACERT_%s", val);
2250 length = android_keystore_get(ANDROID_KEYSTORE_GET, buf, kvalue);
2251 if (length > 0) {
2252 sigma_dut_print(dut, DUT_MSG_INFO, "Use Android keystore [%s]",
2253 buf);
2254 snprintf(buf, sizeof(buf), "keystore://CACERT_%s", val);
2255 goto ca_cert_selected;
2256 }
2257#endif /* ANDROID */
2258
2259 snprintf(buf, sizeof(buf), "%s/%s", sigma_cert_path, val);
2260#ifdef __linux__
2261 if (!file_exists(buf)) {
2262 char msg[300];
2263
2264 snprintf(msg, sizeof(msg),
2265 "ErrorCode,trustedRootCA file (%s) not found", buf);
2266 send_resp(dut, conn, SIGMA_ERROR, msg);
2267 return STATUS_SENT_ERROR;
2268 }
2269#endif /* __linux__ */
2270#ifdef ANDROID
2271ca_cert_selected:
2272#endif /* ANDROID */
2273 if (set_network_quoted(ifname, id, "ca_cert", buf) < 0)
2274 return ERROR_SEND_STATUS;
2275
2276 return SUCCESS_SEND_STATUS;
2277}
2278
2279
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002280static int set_eap_common(struct sigma_dut *dut, struct sigma_conn *conn,
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302281 const char *ifname, int username_identity,
2282 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002283{
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002284 const char *val, *alg, *akm, *trust_root, *domain, *domain_suffix;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002285 int id;
Jouni Malinen53264f62019-05-03 13:04:40 +03002286 char buf[200], buf2[300];
Jouni Malinen8179fee2019-03-28 03:19:47 +02002287 int erp = 0;
Jouni Malinen8ac93452019-08-14 15:19:13 +03002288 enum sigma_cmd_result res;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002289
2290 id = set_wpa_common(dut, conn, ifname, cmd);
2291 if (id < 0)
2292 return id;
2293
2294 val = get_param(cmd, "keyMgmtType");
2295 alg = get_param(cmd, "micAlg");
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302296 akm = get_param(cmd, "AKMSuiteType");
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002297 trust_root = get_param(cmd, "trustedRootCA");
2298 domain = get_param(cmd, "Domain");
2299 domain_suffix = get_param(cmd, "DomainSuffix");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002300
Jouni Malinenad395a22017-09-01 21:13:46 +03002301 if (val && strcasecmp(val, "SuiteB") == 0) {
2302 if (set_network(ifname, id, "key_mgmt", "WPA-EAP-SUITE-B-192") <
2303 0)
2304 return -2;
2305 } else if (alg && strcasecmp(alg, "SHA-256") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002306 if (set_network(ifname, id, "key_mgmt", "WPA-EAP-SHA256") < 0)
2307 return -2;
2308 } else if (alg && strcasecmp(alg, "SHA-1") == 0) {
2309 if (set_network(ifname, id, "key_mgmt", "WPA-EAP") < 0)
2310 return -2;
2311 } else if (val && strcasecmp(val, "wpa2-ft") == 0) {
2312 if (set_network(ifname, id, "key_mgmt", "FT-EAP") < 0)
2313 return -2;
Jouni Malinend6a9d692019-03-28 03:01:24 +02002314 } else if (!akm &&
2315 ((val && strcasecmp(val, "wpa2-sha256") == 0) ||
2316 dut->sta_pmf == STA_PMF_REQUIRED)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002317 if (set_network(ifname, id, "key_mgmt",
2318 "WPA-EAP WPA-EAP-SHA256") < 0)
2319 return -2;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302320 } else if (akm && atoi(akm) == 14) {
2321 if (dut->sta_pmf == STA_PMF_OPTIONAL ||
2322 dut->sta_pmf == STA_PMF_REQUIRED) {
2323 if (set_network(ifname, id, "key_mgmt",
2324 "WPA-EAP-SHA256 FILS-SHA256") < 0)
2325 return -2;
2326 } else {
2327 if (set_network(ifname, id, "key_mgmt",
2328 "WPA-EAP FILS-SHA256") < 0)
2329 return -2;
2330 }
2331
Jouni Malinen8179fee2019-03-28 03:19:47 +02002332 erp = 1;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302333 } else if (akm && atoi(akm) == 15) {
2334 if (dut->sta_pmf == STA_PMF_OPTIONAL ||
2335 dut->sta_pmf == STA_PMF_REQUIRED) {
2336 if (set_network(ifname, id, "key_mgmt",
2337 "WPA-EAP-SHA256 FILS-SHA384") < 0)
2338 return -2;
2339 } else {
2340 if (set_network(ifname, id, "key_mgmt",
2341 "WPA-EAP FILS-SHA384") < 0)
2342 return -2;
2343 }
2344
Jouni Malinen8179fee2019-03-28 03:19:47 +02002345 erp = 1;
Jouni Malinend6a9d692019-03-28 03:01:24 +02002346 } else if (!akm && dut->sta_pmf == STA_PMF_OPTIONAL) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002347 if (set_network(ifname, id, "key_mgmt",
2348 "WPA-EAP WPA-EAP-SHA256") < 0)
2349 return -2;
Jouni Malinend6a9d692019-03-28 03:01:24 +02002350 } else if (!akm) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002351 if (set_network(ifname, id, "key_mgmt", "WPA-EAP") < 0)
2352 return -2;
2353 }
2354
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002355 if (trust_root) {
2356 if (strcmp(trust_root, "DEFAULT") == 0 && !domain &&
2357 !domain_suffix) {
2358 send_resp(dut, conn, SIGMA_ERROR,
2359 "errorCode,trustRootCA DEFAULT used without specifying Domain or DomainSuffix");
2360 return STATUS_SENT_ERROR;
2361 }
2362 res = set_trust_root(dut, conn, ifname, id, trust_root);
Jouni Malinen8ac93452019-08-14 15:19:13 +03002363 if (res != SUCCESS_SEND_STATUS)
2364 return res;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002365 }
2366
Jouni Malinen53264f62019-05-03 13:04:40 +03002367 val = get_param(cmd, "ServerCert");
2368 if (val) {
2369 FILE *f;
2370 char *result = NULL, *pos;
2371
2372 snprintf(buf, sizeof(buf), "%s/%s.sha256", sigma_cert_path,
2373 val);
2374 f = fopen(buf, "r");
2375 if (f) {
2376 result = fgets(buf, sizeof(buf), f);
2377 fclose(f);
2378 }
2379 if (!result) {
2380 snprintf(buf2, sizeof(buf2),
2381 "ErrorCode,ServerCert hash could not be read from %s",
2382 buf);
2383 send_resp(dut, conn, SIGMA_ERROR, buf2);
2384 return STATUS_SENT_ERROR;
2385 }
2386 pos = strchr(buf, '\n');
2387 if (pos)
2388 *pos = '\0';
2389 snprintf(buf2, sizeof(buf2), "hash://server/sha256/%s", buf);
2390 if (set_network_quoted(ifname, id, "ca_cert", buf2) < 0)
2391 return ERROR_SEND_STATUS;
Jouni Malinen29108dc2019-06-13 23:42:11 +03002392
2393 snprintf(buf, sizeof(buf), "%s/%s.tod", sigma_cert_path, val);
2394 if (file_exists(buf)) {
2395 sigma_dut_print(dut, DUT_MSG_DEBUG,
2396 "TOD policy enabled for the configured ServerCert hash");
2397 dut->sta_tod_policy = 1;
2398 }
Jouni Malinen53264f62019-05-03 13:04:40 +03002399 }
2400
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002401 if (domain &&
2402 set_network_quoted(ifname, id, "domain_match", domain) < 0)
Jouni Malinen96f84b02019-05-03 12:32:56 +03002403 return ERROR_SEND_STATUS;
2404
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002405 if (domain_suffix &&
2406 set_network_quoted(ifname, id, "domain_suffix_match",
2407 domain_suffix) < 0)
Jouni Malinen96f84b02019-05-03 12:32:56 +03002408 return ERROR_SEND_STATUS;
2409
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302410 if (username_identity) {
2411 val = get_param(cmd, "username");
2412 if (val) {
2413 if (set_network_quoted(ifname, id, "identity", val) < 0)
2414 return -2;
2415 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002416
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302417 val = get_param(cmd, "password");
2418 if (val) {
2419 if (set_network_quoted(ifname, id, "password", val) < 0)
2420 return -2;
2421 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002422 }
2423
Jouni Malinen8179fee2019-03-28 03:19:47 +02002424 if (dut->akm_values &
2425 ((1 << AKM_FILS_SHA256) |
2426 (1 << AKM_FILS_SHA384) |
2427 (1 << AKM_FT_FILS_SHA256) |
2428 (1 << AKM_FT_FILS_SHA384)))
2429 erp = 1;
2430 if (erp && set_network(ifname, id, "erp", "1") < 0)
2431 return ERROR_SEND_STATUS;
2432
Jouni Malinen134fe3c2019-06-12 04:16:49 +03002433 dut->sta_associate_wait_connect = 1;
2434
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002435 return id;
2436}
2437
2438
Jouni Malinen5eabb2a2017-10-03 18:17:30 +03002439static int set_tls_cipher(const char *ifname, int id, const char *cipher)
2440{
2441 const char *val;
2442
2443 if (!cipher)
2444 return 0;
2445
2446 if (strcasecmp(cipher, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384") == 0)
2447 val = "ECDHE-ECDSA-AES256-GCM-SHA384";
2448 else if (strcasecmp(cipher,
2449 "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384") == 0)
2450 val = "ECDHE-RSA-AES256-GCM-SHA384";
2451 else if (strcasecmp(cipher, "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384") == 0)
2452 val = "DHE-RSA-AES256-GCM-SHA384";
2453 else if (strcasecmp(cipher,
2454 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256") == 0)
2455 val = "ECDHE-ECDSA-AES128-GCM-SHA256";
2456 else
2457 return -1;
2458
2459 /* Need to clear phase1="tls_suiteb=1" to allow cipher enforcement */
2460 set_network_quoted(ifname, id, "phase1", "");
2461
2462 return set_network_quoted(ifname, id, "openssl_ciphers", val);
2463}
2464
2465
Jouni Malinenf7222712019-06-13 01:50:21 +03002466static enum sigma_cmd_result cmd_sta_set_eaptls(struct sigma_dut *dut,
2467 struct sigma_conn *conn,
2468 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002469{
2470 const char *intf = get_param(cmd, "Interface");
2471 const char *ifname, *val;
2472 int id;
2473 char buf[200];
2474#ifdef ANDROID
2475 unsigned char kvalue[KEYSTORE_MESSAGE_SIZE];
2476 int length;
2477 int jb_or_newer = 0;
2478 char prop[PROPERTY_VALUE_MAX];
2479#endif /* ANDROID */
2480
2481 if (intf == NULL)
2482 return -1;
2483
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002484 if (strcmp(intf, get_main_ifname(dut)) == 0)
2485 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002486 else
2487 ifname = intf;
2488
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302489 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002490 if (id < 0)
2491 return id;
2492
2493 if (set_network(ifname, id, "eap", "TLS") < 0)
2494 return -2;
2495
Pradeep Reddy POTTETI9f6c2132016-05-05 16:28:19 +05302496 if (!get_param(cmd, "username") &&
2497 set_network_quoted(ifname, id, "identity",
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002498 "wifi-user@wifilabs.local") < 0)
2499 return -2;
2500
2501 val = get_param(cmd, "clientCertificate");
2502 if (val == NULL)
2503 return -1;
2504#ifdef ANDROID
2505 snprintf(buf, sizeof(buf), "USRPKEY_%s", val);
2506 length = android_keystore_get(ANDROID_KEYSTORE_GET, buf, kvalue);
2507 if (length < 0) {
2508 /*
2509 * JB started reporting keystore type mismatches, so retry with
2510 * the GET_PUBKEY command if the generic GET fails.
2511 */
2512 length = android_keystore_get(ANDROID_KEYSTORE_GET_PUBKEY,
2513 buf, kvalue);
2514 }
2515
2516 if (property_get("ro.build.version.release", prop, NULL) != 0) {
2517 sigma_dut_print(dut, DUT_MSG_DEBUG, "Android release %s", prop);
2518 if (strncmp(prop, "4.0", 3) != 0)
2519 jb_or_newer = 1;
2520 } else
2521 jb_or_newer = 1; /* assume newer */
2522
2523 if (jb_or_newer && length > 0) {
2524 sigma_dut_print(dut, DUT_MSG_INFO,
2525 "Use Android keystore [%s]", buf);
2526 if (set_network(ifname, id, "engine", "1") < 0)
2527 return -2;
2528 if (set_network_quoted(ifname, id, "engine_id", "keystore") < 0)
2529 return -2;
2530 snprintf(buf, sizeof(buf), "USRPKEY_%s", val);
2531 if (set_network_quoted(ifname, id, "key_id", buf) < 0)
2532 return -2;
2533 snprintf(buf, sizeof(buf), "keystore://USRCERT_%s", val);
2534 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
2535 return -2;
2536 return 1;
2537 } else if (length > 0) {
2538 sigma_dut_print(dut, DUT_MSG_INFO,
2539 "Use Android keystore [%s]", buf);
2540 snprintf(buf, sizeof(buf), "keystore://USRPKEY_%s", val);
2541 if (set_network_quoted(ifname, id, "private_key", buf) < 0)
2542 return -2;
2543 snprintf(buf, sizeof(buf), "keystore://USRCERT_%s", val);
2544 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
2545 return -2;
2546 return 1;
2547 }
2548#endif /* ANDROID */
2549
2550 snprintf(buf, sizeof(buf), "%s/%s", sigma_cert_path, val);
2551#ifdef __linux__
2552 if (!file_exists(buf)) {
2553 char msg[300];
2554 snprintf(msg, sizeof(msg), "ErrorCode,clientCertificate file "
2555 "(%s) not found", buf);
2556 send_resp(dut, conn, SIGMA_ERROR, msg);
2557 return -3;
2558 }
2559#endif /* __linux__ */
2560 if (set_network_quoted(ifname, id, "private_key", buf) < 0)
2561 return -2;
2562 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
2563 return -2;
2564
2565 if (set_network_quoted(ifname, id, "private_key_passwd", "wifi") < 0)
2566 return -2;
2567
Jouni Malinen5eabb2a2017-10-03 18:17:30 +03002568 val = get_param(cmd, "keyMgmtType");
2569 if (val && strcasecmp(val, "SuiteB") == 0) {
2570 val = get_param(cmd, "CertType");
2571 if (val && strcasecmp(val, "RSA") == 0) {
2572 if (set_network_quoted(ifname, id, "phase1",
2573 "tls_suiteb=1") < 0)
2574 return -2;
2575 } else {
2576 if (set_network_quoted(ifname, id, "openssl_ciphers",
2577 "SUITEB192") < 0)
2578 return -2;
2579 }
2580
2581 val = get_param(cmd, "TLSCipher");
2582 if (set_tls_cipher(ifname, id, val) < 0) {
2583 send_resp(dut, conn, SIGMA_ERROR,
2584 "ErrorCode,Unsupported TLSCipher value");
2585 return -3;
2586 }
2587 }
2588
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002589 return 1;
2590}
2591
2592
Jouni Malinenf7222712019-06-13 01:50:21 +03002593static enum sigma_cmd_result cmd_sta_set_eapttls(struct sigma_dut *dut,
2594 struct sigma_conn *conn,
2595 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002596{
2597 const char *intf = get_param(cmd, "Interface");
2598 const char *ifname;
2599 int id;
2600
2601 if (intf == NULL)
2602 return -1;
2603
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002604 if (strcmp(intf, get_main_ifname(dut)) == 0)
2605 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002606 else
2607 ifname = intf;
2608
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302609 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002610 if (id < 0)
2611 return id;
2612
2613 if (set_network(ifname, id, "eap", "TTLS") < 0) {
2614 send_resp(dut, conn, SIGMA_ERROR,
2615 "errorCode,Failed to set TTLS method");
2616 return 0;
2617 }
2618
2619 if (set_network_quoted(ifname, id, "phase2", "auth=MSCHAPV2") < 0) {
2620 send_resp(dut, conn, SIGMA_ERROR,
2621 "errorCode,Failed to set MSCHAPv2 for TTLS Phase 2");
2622 return 0;
2623 }
2624
2625 return 1;
2626}
2627
2628
Jouni Malinenf7222712019-06-13 01:50:21 +03002629static enum sigma_cmd_result cmd_sta_set_eapsim(struct sigma_dut *dut,
2630 struct sigma_conn *conn,
2631 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002632{
2633 const char *intf = get_param(cmd, "Interface");
2634 const char *ifname;
2635 int id;
2636
2637 if (intf == NULL)
2638 return -1;
2639
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002640 if (strcmp(intf, get_main_ifname(dut)) == 0)
2641 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002642 else
2643 ifname = intf;
2644
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302645 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002646 if (id < 0)
2647 return id;
2648
2649 if (set_network(ifname, id, "eap", "SIM") < 0)
2650 return -2;
2651
2652 return 1;
2653}
2654
2655
Jouni Malinenf7222712019-06-13 01:50:21 +03002656static enum sigma_cmd_result cmd_sta_set_peap(struct sigma_dut *dut,
2657 struct sigma_conn *conn,
2658 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002659{
2660 const char *intf = get_param(cmd, "Interface");
2661 const char *ifname, *val;
2662 int id;
2663 char buf[100];
2664
2665 if (intf == NULL)
2666 return -1;
2667
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002668 if (strcmp(intf, get_main_ifname(dut)) == 0)
2669 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002670 else
2671 ifname = intf;
2672
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302673 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002674 if (id < 0)
2675 return id;
2676
2677 if (set_network(ifname, id, "eap", "PEAP") < 0)
2678 return -2;
2679
2680 val = get_param(cmd, "innerEAP");
2681 if (val) {
2682 if (strcasecmp(val, "MSCHAPv2") == 0) {
2683 if (set_network_quoted(ifname, id, "phase2",
2684 "auth=MSCHAPV2") < 0)
2685 return -2;
2686 } else if (strcasecmp(val, "GTC") == 0) {
2687 if (set_network_quoted(ifname, id, "phase2",
2688 "auth=GTC") < 0)
2689 return -2;
2690 } else
2691 return -1;
2692 }
2693
2694 val = get_param(cmd, "peapVersion");
2695 if (val) {
2696 int ver = atoi(val);
2697 if (ver < 0 || ver > 1)
2698 return -1;
2699 snprintf(buf, sizeof(buf), "peapver=%d", ver);
2700 if (set_network_quoted(ifname, id, "phase1", buf) < 0)
2701 return -2;
2702 }
2703
2704 return 1;
2705}
2706
2707
Jouni Malinenf7222712019-06-13 01:50:21 +03002708static enum sigma_cmd_result cmd_sta_set_eapfast(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", "FAST") < 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, "validateServer");
2747 if (val) {
2748 /* TODO */
2749 sigma_dut_print(dut, DUT_MSG_INFO, "Ignored EAP-FAST "
2750 "validateServer=%s", val);
2751 }
2752
2753 val = get_param(cmd, "pacFile");
2754 if (val) {
2755 snprintf(buf, sizeof(buf), "blob://%s", val);
2756 if (set_network_quoted(ifname, id, "pac_file", buf) < 0)
2757 return -2;
2758 }
2759
2760 if (set_network_quoted(ifname, id, "phase1", "fast_provisioning=2") <
2761 0)
2762 return -2;
2763
2764 return 1;
2765}
2766
2767
Jouni Malinenf7222712019-06-13 01:50:21 +03002768static enum sigma_cmd_result cmd_sta_set_eapaka(struct sigma_dut *dut,
2769 struct sigma_conn *conn,
2770 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002771{
2772 const char *intf = get_param(cmd, "Interface");
Purushottam Kushwahacdd8cb12019-10-04 11:33:59 +05302773 const char *username = get_param(cmd, "Username");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002774 const char *ifname;
2775 int id;
2776
2777 if (intf == NULL)
2778 return -1;
2779
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002780 if (strcmp(intf, get_main_ifname(dut)) == 0)
2781 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002782 else
2783 ifname = intf;
2784
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302785 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002786 if (id < 0)
2787 return id;
2788
Purushottam Kushwahacdd8cb12019-10-04 11:33:59 +05302789 /* RFC 5448: EAP-AKA' MUST use the leading character "6" (ASCII 36
2790 * hexadecimal).
2791 */
2792 if (username && username[0] == '6') {
2793 if (set_network(ifname, id, "eap", "AKA'") < 0)
2794 return -2;
2795 } else if (set_network(ifname, id, "eap", "AKA") < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002796 return -2;
Purushottam Kushwahacdd8cb12019-10-04 11:33:59 +05302797 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002798
2799 return 1;
2800}
2801
2802
Jouni Malinenf7222712019-06-13 01:50:21 +03002803static enum sigma_cmd_result cmd_sta_set_eapakaprime(struct sigma_dut *dut,
2804 struct sigma_conn *conn,
2805 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002806{
2807 const char *intf = get_param(cmd, "Interface");
2808 const char *ifname;
2809 int id;
2810
2811 if (intf == NULL)
2812 return -1;
2813
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002814 if (strcmp(intf, get_main_ifname(dut)) == 0)
2815 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002816 else
2817 ifname = intf;
2818
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302819 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002820 if (id < 0)
2821 return id;
2822
2823 if (set_network(ifname, id, "eap", "AKA'") < 0)
2824 return -2;
2825
2826 return 1;
2827}
2828
2829
2830static int sta_set_open(struct sigma_dut *dut, struct sigma_conn *conn,
2831 struct sigma_cmd *cmd)
2832{
2833 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002834 const char *network_mode = get_param(cmd, "network_mode");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002835 const char *ifname;
2836 int id;
2837
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002838 if (strcmp(intf, get_main_ifname(dut)) == 0)
2839 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002840 else
2841 ifname = intf;
2842
2843 id = add_network_common(dut, conn, ifname, cmd);
2844 if (id < 0)
2845 return id;
2846
2847 if (set_network(ifname, id, "key_mgmt", "NONE") < 0)
2848 return -2;
2849
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002850 if (dut->program == PROGRAM_60GHZ && network_mode &&
2851 strcasecmp(network_mode, "PBSS") == 0 &&
2852 set_network(ifname, id, "pbss", "1") < 0)
2853 return -2;
2854
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002855 return 1;
2856}
2857
2858
Jouni Malinen47dcc952017-10-09 16:43:24 +03002859static int sta_set_owe(struct sigma_dut *dut, struct sigma_conn *conn,
2860 struct sigma_cmd *cmd)
2861{
2862 const char *intf = get_param(cmd, "Interface");
2863 const char *ifname, *val;
2864 int id;
2865
2866 if (intf == NULL)
2867 return -1;
2868
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002869 if (strcmp(intf, get_main_ifname(dut)) == 0)
2870 ifname = get_station_ifname(dut);
Jouni Malinen47dcc952017-10-09 16:43:24 +03002871 else
2872 ifname = intf;
2873
2874 id = set_wpa_common(dut, conn, ifname, cmd);
2875 if (id < 0)
2876 return id;
2877
2878 if (set_network(ifname, id, "key_mgmt", "OWE") < 0)
2879 return -2;
2880
2881 val = get_param(cmd, "ECGroupID");
Jouni Malinenfac9cad2017-10-10 18:35:55 +03002882 if (val && strcmp(val, "0") == 0) {
2883 if (wpa_command(ifname,
2884 "VENDOR_ELEM_ADD 13 ff23200000783590fb7440e03d5b3b33911f86affdcc6b4411b707846ac4ff08ddc8831ccd") != 0) {
2885 sigma_dut_print(dut, DUT_MSG_ERROR,
2886 "Failed to set OWE DH Param element override");
2887 return -2;
2888 }
2889 } else if (val && set_network(ifname, id, "owe_group", val) < 0) {
Jouni Malinen47dcc952017-10-09 16:43:24 +03002890 sigma_dut_print(dut, DUT_MSG_ERROR,
2891 "Failed to clear owe_group");
2892 return -2;
2893 }
2894
2895 return 1;
2896}
2897
2898
Jouni Malinenf7222712019-06-13 01:50:21 +03002899static enum sigma_cmd_result cmd_sta_set_security(struct sigma_dut *dut,
2900 struct sigma_conn *conn,
2901 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002902{
2903 const char *type = get_param(cmd, "Type");
2904
2905 if (type == NULL) {
2906 send_resp(dut, conn, SIGMA_ERROR,
2907 "ErrorCode,Missing Type argument");
2908 return 0;
2909 }
2910
2911 if (strcasecmp(type, "OPEN") == 0)
2912 return sta_set_open(dut, conn, cmd);
Jouni Malinen47dcc952017-10-09 16:43:24 +03002913 if (strcasecmp(type, "OWE") == 0)
2914 return sta_set_owe(dut, conn, cmd);
Jouni Malinen992a81e2017-08-22 13:57:47 +03002915 if (strcasecmp(type, "PSK") == 0 ||
Jouni Malinen0ab50f42017-08-31 01:34:59 +03002916 strcasecmp(type, "PSK-SAE") == 0 ||
Jouni Malinen992a81e2017-08-22 13:57:47 +03002917 strcasecmp(type, "SAE") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002918 return cmd_sta_set_psk(dut, conn, cmd);
2919 if (strcasecmp(type, "EAPTLS") == 0)
2920 return cmd_sta_set_eaptls(dut, conn, cmd);
2921 if (strcasecmp(type, "EAPTTLS") == 0)
2922 return cmd_sta_set_eapttls(dut, conn, cmd);
2923 if (strcasecmp(type, "EAPPEAP") == 0)
2924 return cmd_sta_set_peap(dut, conn, cmd);
2925 if (strcasecmp(type, "EAPSIM") == 0)
2926 return cmd_sta_set_eapsim(dut, conn, cmd);
2927 if (strcasecmp(type, "EAPFAST") == 0)
2928 return cmd_sta_set_eapfast(dut, conn, cmd);
2929 if (strcasecmp(type, "EAPAKA") == 0)
2930 return cmd_sta_set_eapaka(dut, conn, cmd);
2931 if (strcasecmp(type, "EAPAKAPRIME") == 0)
2932 return cmd_sta_set_eapakaprime(dut, conn, cmd);
Amarnath Hullur Subramanyam81b11cd2018-01-30 19:07:17 -08002933 if (strcasecmp(type, "wep") == 0)
2934 return cmd_sta_set_encryption(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002935
2936 send_resp(dut, conn, SIGMA_ERROR,
2937 "ErrorCode,Unsupported Type value");
2938 return 0;
2939}
2940
2941
2942int ath6kl_client_uapsd(struct sigma_dut *dut, const char *intf, int uapsd)
2943{
2944#ifdef __linux__
2945 /* special handling for ath6kl */
2946 char path[128], fname[128], *pos;
2947 ssize_t res;
2948 FILE *f;
2949
Jouni Malinene39cd562019-05-29 23:39:56 +03002950 res = snprintf(fname, sizeof(fname), "/sys/class/net/%s/phy80211",
2951 intf);
2952 if (res < 0 || res >= sizeof(fname))
2953 return 0;
2954 res = readlink(fname, path, sizeof(path));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002955 if (res < 0)
2956 return 0; /* not ath6kl */
2957
2958 if (res >= (int) sizeof(path))
2959 res = sizeof(path) - 1;
2960 path[res] = '\0';
2961 pos = strrchr(path, '/');
2962 if (pos == NULL)
2963 pos = path;
2964 else
2965 pos++;
2966 snprintf(fname, sizeof(fname),
2967 "/sys/kernel/debug/ieee80211/%s/ath6kl/"
2968 "create_qos", pos);
2969 if (!file_exists(fname))
2970 return 0; /* not ath6kl */
2971
2972 if (uapsd) {
2973 f = fopen(fname, "w");
2974 if (f == NULL)
2975 return -1;
2976
2977 sigma_dut_print(dut, DUT_MSG_DEBUG, "Use ath6kl create_qos");
2978 fprintf(f, "4 2 2 1 2 9999999 9999999 9999999 7777777 0 4 "
2979 "45000 200 56789000 56789000 5678900 0 0 9999999 "
2980 "20000 0\n");
2981 fclose(f);
2982 } else {
2983 snprintf(fname, sizeof(fname),
2984 "/sys/kernel/debug/ieee80211/%s/ath6kl/"
2985 "delete_qos", pos);
2986
2987 f = fopen(fname, "w");
2988 if (f == NULL)
2989 return -1;
2990
2991 sigma_dut_print(dut, DUT_MSG_DEBUG, "Use ath6kl delete_qos");
2992 fprintf(f, "2 4\n");
2993 fclose(f);
2994 }
2995#endif /* __linux__ */
2996
2997 return 0;
2998}
2999
3000
Jouni Malinenf7222712019-06-13 01:50:21 +03003001static enum sigma_cmd_result cmd_sta_set_uapsd(struct sigma_dut *dut,
3002 struct sigma_conn *conn,
3003 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003004{
3005 const char *intf = get_param(cmd, "Interface");
3006 /* const char *ssid = get_param(cmd, "ssid"); */
3007 const char *val;
3008 int max_sp_len = 4;
3009 int ac_be = 1, ac_bk = 1, ac_vi = 1, ac_vo = 1;
3010 char buf[100];
3011 int ret1, ret2;
3012
3013 val = get_param(cmd, "maxSPLength");
3014 if (val) {
3015 max_sp_len = atoi(val);
3016 if (max_sp_len != 0 && max_sp_len != 1 && max_sp_len != 2 &&
3017 max_sp_len != 4)
3018 return -1;
3019 }
3020
3021 val = get_param(cmd, "acBE");
3022 if (val)
3023 ac_be = atoi(val);
3024
3025 val = get_param(cmd, "acBK");
3026 if (val)
3027 ac_bk = atoi(val);
3028
3029 val = get_param(cmd, "acVI");
3030 if (val)
3031 ac_vi = atoi(val);
3032
3033 val = get_param(cmd, "acVO");
3034 if (val)
3035 ac_vo = atoi(val);
3036
3037 dut->client_uapsd = ac_be || ac_bk || ac_vi || ac_vo;
3038
3039 snprintf(buf, sizeof(buf), "P2P_SET client_apsd %d,%d,%d,%d;%d",
3040 ac_be, ac_bk, ac_vi, ac_vo, max_sp_len);
3041 ret1 = wpa_command(intf, buf);
3042
3043 snprintf(buf, sizeof(buf), "SET uapsd %d,%d,%d,%d;%d",
3044 ac_be, ac_bk, ac_vi, ac_vo, max_sp_len);
3045 ret2 = wpa_command(intf, buf);
3046
3047 if (ret1 && ret2) {
3048 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to set client mode "
3049 "UAPSD parameters.");
3050 return -2;
3051 }
3052
3053 if (ath6kl_client_uapsd(dut, intf, dut->client_uapsd) < 0) {
3054 send_resp(dut, conn, SIGMA_ERROR,
3055 "ErrorCode,Failed to set ath6kl QoS parameters");
3056 return 0;
3057 }
3058
3059 return 1;
3060}
3061
3062
Jouni Malinenf7222712019-06-13 01:50:21 +03003063static enum sigma_cmd_result cmd_sta_set_wmm(struct sigma_dut *dut,
3064 struct sigma_conn *conn,
3065 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003066{
3067 char buf[1000];
3068 const char *intf = get_param(cmd, "Interface");
3069 const char *grp = get_param(cmd, "Group");
3070 const char *act = get_param(cmd, "Action");
3071 const char *tid = get_param(cmd, "Tid");
3072 const char *dir = get_param(cmd, "Direction");
3073 const char *psb = get_param(cmd, "Psb");
3074 const char *up = get_param(cmd, "Up");
3075 const char *fixed = get_param(cmd, "Fixed");
3076 const char *size = get_param(cmd, "Size");
3077 const char *msize = get_param(cmd, "Maxsize");
3078 const char *minsi = get_param(cmd, "Min_srvc_intrvl");
3079 const char *maxsi = get_param(cmd, "Max_srvc_intrvl");
3080 const char *inact = get_param(cmd, "Inactivity");
3081 const char *sus = get_param(cmd, "Suspension");
3082 const char *mindr = get_param(cmd, "Mindatarate");
3083 const char *meandr = get_param(cmd, "Meandatarate");
3084 const char *peakdr = get_param(cmd, "Peakdatarate");
3085 const char *phyrate = get_param(cmd, "Phyrate");
3086 const char *burstsize = get_param(cmd, "Burstsize");
3087 const char *sba = get_param(cmd, "Sba");
3088 int direction;
3089 int handle;
Peng Xu93319622017-10-04 17:58:16 -07003090 float sba_fv = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003091 int fixed_int;
3092 int psb_ts;
3093
3094 if (intf == NULL || grp == NULL || act == NULL )
3095 return -1;
3096
3097 if (strcasecmp(act, "addts") == 0) {
3098 if (tid == NULL || dir == NULL || psb == NULL ||
3099 up == NULL || fixed == NULL || size == NULL)
3100 return -1;
3101
3102 /*
3103 * Note: Sigma CAPI spec lists uplink, downlink, and bidi as the
3104 * possible values, but WMM-AC and V-E test scripts use "UP,
3105 * "DOWN", and "BIDI".
3106 */
3107 if (strcasecmp(dir, "uplink") == 0 ||
3108 strcasecmp(dir, "up") == 0) {
3109 direction = 0;
3110 } else if (strcasecmp(dir, "downlink") == 0 ||
3111 strcasecmp(dir, "down") == 0) {
3112 direction = 1;
3113 } else if (strcasecmp(dir, "bidi") == 0) {
3114 direction = 2;
3115 } else {
3116 sigma_dut_print(dut, DUT_MSG_ERROR,
3117 "Direction %s not supported", dir);
3118 return -1;
3119 }
3120
3121 if (strcasecmp(psb, "legacy") == 0) {
3122 psb_ts = 0;
3123 } else if (strcasecmp(psb, "uapsd") == 0) {
3124 psb_ts = 1;
3125 } else {
3126 sigma_dut_print(dut, DUT_MSG_ERROR,
3127 "PSB %s not supported", psb);
3128 return -1;
3129 }
3130
3131 if (atoi(tid) < 0 || atoi(tid) > 7) {
3132 sigma_dut_print(dut, DUT_MSG_ERROR,
3133 "TID %s not supported", tid);
3134 return -1;
3135 }
3136
3137 if (strcasecmp(fixed, "true") == 0) {
3138 fixed_int = 1;
3139 } else {
3140 fixed_int = 0;
3141 }
3142
Peng Xu93319622017-10-04 17:58:16 -07003143 if (sba)
3144 sba_fv = atof(sba);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003145
3146 dut->dialog_token++;
3147 handle = 7000 + dut->dialog_token;
3148
3149 /*
3150 * size: convert to hex
3151 * maxsi: convert to hex
3152 * mindr: convert to hex
3153 * meandr: convert to hex
3154 * peakdr: convert to hex
3155 * burstsize: convert to hex
3156 * phyrate: convert to hex
3157 * sba: convert to hex with modification
3158 * minsi: convert to integer
3159 * sus: convert to integer
3160 * inact: convert to integer
3161 * maxsi: convert to integer
3162 */
3163
3164 /*
3165 * The Nominal MSDU Size field is 2 octets long and contains an
3166 * unsigned integer that specifies the nominal size, in octets,
3167 * of MSDUs belonging to the traffic under this traffic
3168 * specification and is defined in Figure 16. If the Fixed
3169 * subfield is set to 1, then the size of the MSDU is fixed and
3170 * is indicated by the Size Subfield. If the Fixed subfield is
3171 * set to 0, then the size of the MSDU might not be fixed and
3172 * the Size indicates the nominal MSDU size.
3173 *
3174 * The Surplus Bandwidth Allowance Factor field is 2 octets long
3175 * and specifies the excess allocation of time (and bandwidth)
3176 * over and above the stated rates required to transport an MSDU
3177 * belonging to the traffic in this TSPEC. This field is
3178 * represented as an unsigned binary number with an implicit
3179 * binary point after the leftmost 3 bits. For example, an SBA
3180 * of 1.75 is represented as 0x3800. This field is included to
3181 * account for retransmissions. As such, the value of this field
3182 * must be greater than unity.
3183 */
3184
3185 snprintf(buf, sizeof(buf),
3186 "iwpriv %s addTspec %d %s %d %d %s 0x%X"
3187 " 0x%X 0x%X 0x%X"
3188 " 0x%X 0x%X 0x%X"
3189 " 0x%X %d %d %d %d"
3190 " %d %d",
3191 intf, handle, tid, direction, psb_ts, up,
3192 (unsigned int) ((fixed_int << 15) | atoi(size)),
3193 msize ? atoi(msize) : 0,
3194 mindr ? atoi(mindr) : 0,
3195 meandr ? atoi(meandr) : 0,
3196 peakdr ? atoi(peakdr) : 0,
3197 burstsize ? atoi(burstsize) : 0,
3198 phyrate ? atoi(phyrate) : 0,
3199 sba ? ((unsigned int) (((int) sba_fv << 13) |
3200 (int)((sba_fv - (int) sba_fv) *
3201 8192))) : 0,
3202 minsi ? atoi(minsi) : 0,
3203 sus ? atoi(sus) : 0,
3204 0, 0,
3205 inact ? atoi(inact) : 0,
3206 maxsi ? atoi(maxsi) : 0);
3207
3208 if (system(buf) != 0) {
3209 sigma_dut_print(dut, DUT_MSG_ERROR,
3210 "iwpriv addtspec request failed");
3211 send_resp(dut, conn, SIGMA_ERROR,
3212 "errorCode,Failed to execute addTspec command");
3213 return 0;
3214 }
3215
3216 sigma_dut_print(dut, DUT_MSG_INFO,
3217 "iwpriv addtspec request send");
3218
3219 /* Mapping handle to a TID */
3220 dut->tid_to_handle[atoi(tid)] = handle;
3221 } else if (strcasecmp(act, "delts") == 0) {
3222 if (tid == NULL)
3223 return -1;
3224
3225 if (atoi(tid) < 0 || atoi(tid) > 7) {
3226 sigma_dut_print(dut, DUT_MSG_ERROR,
3227 "TID %s not supported", tid);
3228 send_resp(dut, conn, SIGMA_ERROR,
3229 "errorCode,Unsupported TID");
3230 return 0;
3231 }
3232
3233 handle = dut->tid_to_handle[atoi(tid)];
3234
3235 if (handle < 7000 || handle > 7255) {
3236 /* Invalid handle ie no mapping for that TID */
3237 sigma_dut_print(dut, DUT_MSG_ERROR,
3238 "handle-> %d not found", handle);
3239 }
3240
3241 snprintf(buf, sizeof(buf), "iwpriv %s delTspec %d",
3242 intf, handle);
3243
3244 if (system(buf) != 0) {
3245 sigma_dut_print(dut, DUT_MSG_ERROR,
3246 "iwpriv deltspec request failed");
3247 send_resp(dut, conn, SIGMA_ERROR,
3248 "errorCode,Failed to execute delTspec command");
3249 return 0;
3250 }
3251
3252 sigma_dut_print(dut, DUT_MSG_INFO,
3253 "iwpriv deltspec request send");
3254
3255 dut->tid_to_handle[atoi(tid)] = 0;
3256 } else {
3257 sigma_dut_print(dut, DUT_MSG_ERROR,
3258 "Action type %s not supported", act);
3259 send_resp(dut, conn, SIGMA_ERROR,
3260 "errorCode,Unsupported Action");
3261 return 0;
3262 }
3263
3264 return 1;
3265}
3266
3267
vamsi krishna52e16f92017-08-29 12:37:34 +05303268static int find_network(struct sigma_dut *dut, const char *ssid)
3269{
3270 char list[4096];
3271 char *pos;
3272
3273 sigma_dut_print(dut, DUT_MSG_DEBUG,
3274 "Search for profile based on SSID: '%s'", ssid);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003275 if (wpa_command_resp(get_station_ifname(dut), "LIST_NETWORKS",
vamsi krishna52e16f92017-08-29 12:37:34 +05303276 list, sizeof(list)) < 0)
3277 return -1;
3278 pos = strstr(list, ssid);
3279 if (!pos || pos == list || pos[-1] != '\t' || pos[strlen(ssid)] != '\t')
3280 return -1;
3281
3282 while (pos > list && pos[-1] != '\n')
3283 pos--;
3284 dut->infra_network_id = atoi(pos);
3285 snprintf(dut->infra_ssid, sizeof(dut->infra_ssid), "%s", ssid);
3286 return 0;
3287}
3288
3289
Sunil Dutt44595082018-02-12 19:41:45 +05303290#ifdef NL80211_SUPPORT
3291static int sta_config_rsnie(struct sigma_dut *dut, int val)
3292{
3293 struct nl_msg *msg;
3294 int ret;
3295 struct nlattr *params;
3296 int ifindex;
3297
3298 ifindex = if_nametoindex("wlan0");
3299 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
3300 NL80211_CMD_VENDOR)) ||
3301 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
3302 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
3303 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
3304 QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION) ||
3305 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
3306 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE, val)) {
3307 sigma_dut_print(dut, DUT_MSG_ERROR,
3308 "%s: err in adding vendor_cmd and vendor_data",
3309 __func__);
3310 nlmsg_free(msg);
3311 return -1;
3312 }
3313 nla_nest_end(msg, params);
3314
3315 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
3316 if (ret) {
3317 sigma_dut_print(dut, DUT_MSG_ERROR,
3318 "%s: err in send_and_recv_msgs, ret=%d",
3319 __func__, ret);
3320 return ret;
3321 }
3322
3323 return 0;
3324}
3325#endif /* NL80211_SUPPORT */
3326
3327
Jouni Malinenf7222712019-06-13 01:50:21 +03003328static enum sigma_cmd_result cmd_sta_associate(struct sigma_dut *dut,
3329 struct sigma_conn *conn,
3330 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003331{
3332 /* const char *intf = get_param(cmd, "Interface"); */
3333 const char *ssid = get_param(cmd, "ssid");
3334 const char *wps_param = get_param(cmd, "WPS");
3335 const char *bssid = get_param(cmd, "bssid");
Jouni Malinen46a19b62017-06-23 14:31:27 +03003336 const char *chan = get_param(cmd, "channel");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02003337 const char *network_mode = get_param(cmd, "network_mode");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003338 int wps = 0;
Jouni Malinen3c367e82017-06-23 17:01:47 +03003339 char buf[1000], extra[50];
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003340 int e;
3341 enum sigma_cmd_result ret = SUCCESS_SEND_STATUS;
3342 struct wpa_ctrl *ctrl = NULL;
3343 int num_network_not_found = 0;
3344 int num_disconnected = 0;
3345 int tod = -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003346
3347 if (ssid == NULL)
3348 return -1;
3349
Jouni Malinen37d5c692019-08-19 16:56:55 +03003350 dut->server_cert_tod = 0;
3351
Jouni Malinen3c367e82017-06-23 17:01:47 +03003352 if (dut->rsne_override) {
Sunil Dutt44595082018-02-12 19:41:45 +05303353#ifdef NL80211_SUPPORT
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003354 if (get_driver_type(dut) == DRIVER_WCN) {
Sunil Dutt44595082018-02-12 19:41:45 +05303355 sta_config_rsnie(dut, 1);
3356 dut->config_rsnie = 1;
3357 }
3358#endif /* NL80211_SUPPORT */
Jouni Malinen3c367e82017-06-23 17:01:47 +03003359 snprintf(buf, sizeof(buf), "TEST_ASSOC_IE %s",
3360 dut->rsne_override);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003361 if (wpa_command(get_station_ifname(dut), buf) < 0) {
Jouni Malinen3c367e82017-06-23 17:01:47 +03003362 send_resp(dut, conn, SIGMA_ERROR,
3363 "ErrorCode,Failed to set DEV_CONFIGURE_IE RSNE override");
3364 return 0;
3365 }
3366 }
3367
Jouni Malinen68143132017-09-02 02:34:08 +03003368 if (dut->sae_commit_override) {
3369 snprintf(buf, sizeof(buf), "SET sae_commit_override %s",
3370 dut->sae_commit_override);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003371 if (wpa_command(get_station_ifname(dut), buf) < 0) {
Jouni Malinen68143132017-09-02 02:34:08 +03003372 send_resp(dut, conn, SIGMA_ERROR,
3373 "ErrorCode,Failed to set SAE commit override");
3374 return 0;
3375 }
3376 }
Ankita Bajaj1bde7942018-01-09 19:15:01 +05303377#ifdef ANDROID
3378 if (dut->fils_hlp)
3379 process_fils_hlp(dut);
3380#endif /* ANDROID */
Jouni Malinen68143132017-09-02 02:34:08 +03003381
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003382 if (wps_param &&
3383 (strcmp(wps_param, "1") == 0 || strcasecmp(wps_param, "On") == 0))
3384 wps = 1;
3385
3386 if (wps) {
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02003387 if (dut->program == PROGRAM_60GHZ && network_mode &&
3388 strcasecmp(network_mode, "PBSS") == 0 &&
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003389 set_network(get_station_ifname(dut), dut->infra_network_id,
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02003390 "pbss", "1") < 0)
3391 return -2;
3392
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003393 if (dut->wps_method == WFA_CS_WPS_NOT_READY) {
3394 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,WPS "
3395 "parameters not yet set");
3396 return 0;
3397 }
3398 if (dut->wps_method == WFA_CS_WPS_PBC) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003399 if (wpa_command(get_station_ifname(dut), "WPS_PBC") < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003400 return -2;
3401 } else {
3402 snprintf(buf, sizeof(buf), "WPS_PIN any %s",
3403 dut->wps_pin);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003404 if (wpa_command(get_station_ifname(dut), buf) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003405 return -2;
3406 }
3407 } else {
vamsi krishna52e16f92017-08-29 12:37:34 +05303408 if (strcmp(ssid, dut->infra_ssid) == 0) {
3409 sigma_dut_print(dut, DUT_MSG_DEBUG,
3410 "sta_associate for the most recently added network");
3411 } else if (find_network(dut, ssid) < 0) {
3412 sigma_dut_print(dut, DUT_MSG_DEBUG,
3413 "sta_associate for a previously stored network profile");
3414 send_resp(dut, conn, SIGMA_ERROR,
3415 "ErrorCode,Profile not found");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003416 return 0;
3417 }
3418
3419 if (bssid &&
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003420 set_network(get_station_ifname(dut), dut->infra_network_id,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003421 "bssid", bssid) < 0) {
3422 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
3423 "Invalid bssid argument");
3424 return 0;
3425 }
3426
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003427 if (dut->program == PROGRAM_WPA3 &&
3428 dut->sta_associate_wait_connect) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003429 ctrl = open_wpa_mon(get_station_ifname(dut));
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003430 if (!ctrl)
3431 return ERROR_SEND_STATUS;
3432 }
3433
Jouni Malinen46a19b62017-06-23 14:31:27 +03003434 extra[0] = '\0';
3435 if (chan)
3436 snprintf(extra, sizeof(extra), " freq=%u",
Alexei Avshalom Lazar093569f2018-11-13 14:08:17 +02003437 channel_to_freq(dut, atoi(chan)));
Jouni Malinen46a19b62017-06-23 14:31:27 +03003438 snprintf(buf, sizeof(buf), "SELECT_NETWORK %d%s",
3439 dut->infra_network_id, extra);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003440 if (wpa_command(get_station_ifname(dut), buf) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003441 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to select "
3442 "network id %d on %s",
3443 dut->infra_network_id,
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003444 get_station_ifname(dut));
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003445 ret = ERROR_SEND_STATUS;
3446 goto done;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003447 }
3448 }
3449
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003450 if (!ctrl)
3451 return SUCCESS_SEND_STATUS;
3452
3453 /* Wait for connection result to be able to store server certificate
3454 * hash for trust root override testing
3455 * (dev_exec_action,ServerCertTrust). */
3456
3457 for (e = 0; e < 20; e++) {
3458 const char *events[] = {
3459 "CTRL-EVENT-EAP-PEER-CERT",
3460 "CTRL-EVENT-EAP-TLS-CERT-ERROR",
3461 "CTRL-EVENT-DISCONNECTED",
3462 "CTRL-EVENT-CONNECTED",
3463 "CTRL-EVENT-NETWORK-NOT-FOUND",
3464 NULL
3465 };
3466 char buf[1024];
3467 int res;
3468
3469 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
3470 if (res < 0) {
Jouni Malinenf1f16642019-11-15 21:19:04 +02003471 send_resp(dut, conn, SIGMA_COMPLETE,
3472 "Result,Association did not complete");
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003473 ret = STATUS_SENT_ERROR;
3474 break;
3475 }
3476 sigma_dut_print(dut, DUT_MSG_DEBUG, "Connection event: %s",
3477 buf);
3478
3479 if (strstr(buf, "CTRL-EVENT-EAP-PEER-CERT") &&
3480 strstr(buf, " depth=0")) {
3481 char *pos = strstr(buf, " hash=");
3482
3483 if (pos) {
3484 char *end;
3485
Jouni Malinen34b19cb2019-08-16 16:37:17 +03003486 if (strstr(buf, " tod=1"))
3487 tod = 1;
3488 else if (strstr(buf, " tod=2"))
3489 tod = 2;
3490 else
3491 tod = 0;
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003492 sigma_dut_print(dut, DUT_MSG_DEBUG,
3493 "Server certificate TOD policy: %d",
3494 tod);
Jouni Malinen37d5c692019-08-19 16:56:55 +03003495 dut->server_cert_tod = tod;
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003496
3497 pos += 6;
3498 end = strchr(pos, ' ');
3499 if (end)
3500 *end = '\0';
3501 strlcpy(dut->server_cert_hash, pos,
3502 sizeof(dut->server_cert_hash));
3503 sigma_dut_print(dut, DUT_MSG_DEBUG,
3504 "Server certificate hash: %s",
3505 dut->server_cert_hash);
3506 }
3507 }
3508
3509 if (strstr(buf, "CTRL-EVENT-EAP-TLS-CERT-ERROR")) {
3510 send_resp(dut, conn, SIGMA_COMPLETE,
3511 "Result,TLS server certificate validation failed");
3512 ret = STATUS_SENT_ERROR;
3513 break;
3514 }
3515
3516 if (strstr(buf, "CTRL-EVENT-NETWORK-NOT-FOUND")) {
3517 num_network_not_found++;
3518
3519 if (num_network_not_found > 2) {
3520 send_resp(dut, conn, SIGMA_COMPLETE,
3521 "Result,Network not found");
3522 ret = STATUS_SENT_ERROR;
3523 break;
3524 }
3525 }
3526
3527 if (strstr(buf, "CTRL-EVENT-DISCONNECTED")) {
3528 num_disconnected++;
3529
3530 if (num_disconnected > 2) {
3531 send_resp(dut, conn, SIGMA_COMPLETE,
3532 "Result,Connection failed");
3533 ret = STATUS_SENT_ERROR;
3534 break;
3535 }
3536 }
3537
3538 if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
3539 if (tod >= 0) {
3540 sigma_dut_print(dut, DUT_MSG_DEBUG,
3541 "Network profile TOD policy update: %d -> %d",
3542 dut->sta_tod_policy, tod);
3543 dut->sta_tod_policy = tod;
3544 }
3545 break;
3546 }
3547 }
3548done:
3549 if (ctrl) {
3550 wpa_ctrl_detach(ctrl);
3551 wpa_ctrl_close(ctrl);
3552 }
3553 return ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003554}
3555
3556
3557static int run_hs20_osu(struct sigma_dut *dut, const char *params)
3558{
3559 char buf[500], cmd[200];
3560 int res;
3561
3562 /* Use hs20-osu-client file at the current dir, if found; otherwise use
3563 * default path */
3564 res = snprintf(cmd, sizeof(cmd),
3565 "%s -w \"%s\" -r hs20-osu-client.res %s%s -dddKt -f Logs/hs20-osu-client.txt",
3566 file_exists("./hs20-osu-client") ?
3567 "./hs20-osu-client" : "hs20-osu-client",
3568 sigma_wpas_ctrl,
3569 dut->summary_log ? "-s " : "",
3570 dut->summary_log ? dut->summary_log : "");
3571 if (res < 0 || res >= (int) sizeof(cmd))
3572 return -1;
3573
3574 res = snprintf(buf, sizeof(buf), "%s %s", cmd, params);
3575 if (res < 0 || res >= (int) sizeof(buf))
3576 return -1;
3577 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
3578
3579 if (system(buf) != 0) {
3580 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to run: %s", buf);
3581 return -1;
3582 }
3583 sigma_dut_print(dut, DUT_MSG_DEBUG,
3584 "Completed hs20-osu-client operation");
3585
3586 return 0;
3587}
3588
3589
3590static int download_ppsmo(struct sigma_dut *dut,
3591 struct sigma_conn *conn,
3592 const char *intf,
3593 struct sigma_cmd *cmd)
3594{
3595 const char *name, *path, *val;
3596 char url[500], buf[600], fbuf[100];
3597 char *fqdn = NULL;
3598
3599 name = get_param(cmd, "FileName");
3600 path = get_param(cmd, "FilePath");
3601 if (name == NULL || path == NULL)
3602 return -1;
3603
3604 if (strcasecmp(path, "VendorSpecific") == 0) {
3605 snprintf(url, sizeof(url), "PPS/%s", name);
3606 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured PPS MO "
3607 "from the device (%s)", url);
3608 if (!file_exists(url)) {
3609 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
3610 "PPS MO file does not exist");
3611 return 0;
3612 }
3613 snprintf(buf, sizeof(buf), "cp %s pps-tnds.xml", url);
3614 if (system(buf) != 0) {
3615 send_resp(dut, conn, SIGMA_ERROR,
3616 "errorCode,Failed to copy PPS MO");
3617 return 0;
3618 }
3619 } else if (strncasecmp(path, "http:", 5) != 0 &&
3620 strncasecmp(path, "https:", 6) != 0) {
3621 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
3622 "Unsupported FilePath value");
3623 return 0;
3624 } else {
3625 snprintf(url, sizeof(url), "%s/%s", path, name);
3626 sigma_dut_print(dut, DUT_MSG_INFO, "Downloading PPS MO from %s",
3627 url);
3628 snprintf(buf, sizeof(buf), "wget -T 10 -t 3 -O pps-tnds.xml '%s'", url);
3629 remove("pps-tnds.xml");
3630 if (system(buf) != 0) {
3631 send_resp(dut, conn, SIGMA_ERROR,
3632 "errorCode,Failed to download PPS MO");
3633 return 0;
3634 }
3635 }
3636
3637 if (run_hs20_osu(dut, "from_tnds pps-tnds.xml pps.xml") < 0) {
3638 send_resp(dut, conn, SIGMA_ERROR,
3639 "errorCode,Failed to parse downloaded PPSMO");
3640 return 0;
3641 }
3642 unlink("pps-tnds.xml");
3643
3644 val = get_param(cmd, "managementTreeURI");
3645 if (val) {
3646 const char *pos, *end;
3647 sigma_dut_print(dut, DUT_MSG_DEBUG, "managementTreeURI: %s",
3648 val);
3649 if (strncmp(val, "./Wi-Fi/", 8) != 0) {
3650 send_resp(dut, conn, SIGMA_ERROR,
3651 "errorCode,Invalid managementTreeURI prefix");
3652 return 0;
3653 }
3654 pos = val + 8;
3655 end = strchr(pos, '/');
3656 if (end == NULL ||
3657 strcmp(end, "/PerProviderSubscription") != 0) {
3658 send_resp(dut, conn, SIGMA_ERROR,
3659 "errorCode,Invalid managementTreeURI postfix");
3660 return 0;
3661 }
3662 if (end - pos >= (int) sizeof(fbuf)) {
3663 send_resp(dut, conn, SIGMA_ERROR,
3664 "errorCode,Too long FQDN in managementTreeURI");
3665 return 0;
3666 }
3667 memcpy(fbuf, pos, end - pos);
3668 fbuf[end - pos] = '\0';
3669 fqdn = fbuf;
3670 sigma_dut_print(dut, DUT_MSG_INFO,
3671 "FQDN from managementTreeURI: %s", fqdn);
3672 } else if (run_hs20_osu(dut, "get_fqdn pps.xml") == 0) {
3673 FILE *f = fopen("pps-fqdn", "r");
3674 if (f) {
3675 if (fgets(fbuf, sizeof(fbuf), f)) {
3676 fbuf[sizeof(fbuf) - 1] = '\0';
3677 fqdn = fbuf;
3678 sigma_dut_print(dut, DUT_MSG_DEBUG,
3679 "Use FQDN %s", fqdn);
3680 }
3681 fclose(f);
3682 }
3683 }
3684
3685 if (fqdn == NULL) {
3686 send_resp(dut, conn, SIGMA_ERROR,
3687 "errorCode,No FQDN specified");
3688 return 0;
3689 }
3690
3691 mkdir("SP", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
3692 snprintf(buf, sizeof(buf), "SP/%s", fqdn);
3693 mkdir(buf, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
3694
3695 snprintf(buf, sizeof(buf), "SP/%s/pps.xml", fqdn);
3696 if (rename("pps.xml", buf) < 0) {
3697 send_resp(dut, conn, SIGMA_ERROR,
3698 "errorCode,Could not move PPS MO");
3699 return 0;
3700 }
3701
3702 if (strcasecmp(path, "VendorSpecific") == 0) {
3703 snprintf(buf, sizeof(buf), "cp Certs/ca.pem SP/%s/ca.pem",
3704 fqdn);
3705 if (system(buf)) {
3706 send_resp(dut, conn, SIGMA_ERROR,
3707 "errorCode,Failed to copy OSU CA cert");
3708 return 0;
3709 }
3710
3711 snprintf(buf, sizeof(buf),
3712 "cp Certs/aaa-ca.pem SP/%s/aaa-ca.pem",
3713 fqdn);
3714 if (system(buf)) {
3715 send_resp(dut, conn, SIGMA_ERROR,
3716 "errorCode,Failed to copy AAA CA cert");
3717 return 0;
3718 }
3719 } else {
3720 snprintf(buf, sizeof(buf),
3721 "dl_osu_ca SP/%s/pps.xml SP/%s/ca.pem",
3722 fqdn, fqdn);
3723 if (run_hs20_osu(dut, buf) < 0) {
3724 send_resp(dut, conn, SIGMA_ERROR,
3725 "errorCode,Failed to download OSU CA cert");
3726 return 0;
3727 }
3728
3729 snprintf(buf, sizeof(buf),
3730 "dl_aaa_ca SP/%s/pps.xml SP/%s/aaa-ca.pem",
3731 fqdn, fqdn);
3732 if (run_hs20_osu(dut, buf) < 0) {
3733 sigma_dut_print(dut, DUT_MSG_INFO,
3734 "Failed to download AAA CA cert");
3735 }
3736 }
3737
3738 if (file_exists("next-client-cert.pem")) {
3739 snprintf(buf, sizeof(buf), "SP/%s/client-cert.pem", fqdn);
3740 if (rename("next-client-cert.pem", buf) < 0) {
3741 send_resp(dut, conn, SIGMA_ERROR,
3742 "errorCode,Could not move client certificate");
3743 return 0;
3744 }
3745 }
3746
3747 if (file_exists("next-client-key.pem")) {
3748 snprintf(buf, sizeof(buf), "SP/%s/client-key.pem", fqdn);
3749 if (rename("next-client-key.pem", buf) < 0) {
3750 send_resp(dut, conn, SIGMA_ERROR,
3751 "errorCode,Could not move client key");
3752 return 0;
3753 }
3754 }
3755
3756 snprintf(buf, sizeof(buf), "set_pps SP/%s/pps.xml", fqdn);
3757 if (run_hs20_osu(dut, buf) < 0) {
3758 send_resp(dut, conn, SIGMA_ERROR,
3759 "errorCode,Failed to configure credential from "
3760 "PPSMO");
3761 return 0;
3762 }
3763
3764 return 1;
3765}
3766
3767
3768static int download_cert(struct sigma_dut *dut,
3769 struct sigma_conn *conn,
3770 const char *intf,
3771 struct sigma_cmd *cmd)
3772{
3773 const char *name, *path;
3774 char url[500], buf[600];
3775
3776 name = get_param(cmd, "FileName");
3777 path = get_param(cmd, "FilePath");
3778 if (name == NULL || path == NULL)
3779 return -1;
3780
3781 if (strcasecmp(path, "VendorSpecific") == 0) {
3782 snprintf(url, sizeof(url), "Certs/%s-cert.pem", name);
3783 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured client "
3784 "certificate from the device (%s)", url);
3785 if (!file_exists(url)) {
3786 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
3787 "certificate file does not exist");
3788 return 0;
3789 }
3790 snprintf(buf, sizeof(buf), "cp %s next-client-cert.pem", url);
3791 if (system(buf) != 0) {
3792 send_resp(dut, conn, SIGMA_ERROR,
3793 "errorCode,Failed to copy client "
3794 "certificate");
3795 return 0;
3796 }
3797
3798 snprintf(url, sizeof(url), "Certs/%s-key.pem", name);
3799 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured client "
3800 "private key from the device (%s)", url);
3801 if (!file_exists(url)) {
3802 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
3803 "private key file does not exist");
3804 return 0;
3805 }
3806 snprintf(buf, sizeof(buf), "cp %s next-client-key.pem", url);
3807 if (system(buf) != 0) {
3808 send_resp(dut, conn, SIGMA_ERROR,
3809 "errorCode,Failed to copy client key");
3810 return 0;
3811 }
3812 } else if (strncasecmp(path, "http:", 5) != 0 &&
3813 strncasecmp(path, "https:", 6) != 0) {
3814 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
3815 "Unsupported FilePath value");
3816 return 0;
3817 } else {
3818 snprintf(url, sizeof(url), "%s/%s.pem", path, name);
3819 sigma_dut_print(dut, DUT_MSG_INFO, "Downloading client "
3820 "certificate/key from %s", url);
3821 snprintf(buf, sizeof(buf),
3822 "wget -T 10 -t 3 -O next-client-cert.pem '%s'", url);
3823 if (system(buf) != 0) {
3824 send_resp(dut, conn, SIGMA_ERROR,
3825 "errorCode,Failed to download client "
3826 "certificate");
3827 return 0;
3828 }
3829
3830 if (system("cp next-client-cert.pem next-client-key.pem") != 0)
3831 {
3832 send_resp(dut, conn, SIGMA_ERROR,
3833 "errorCode,Failed to copy client key");
3834 return 0;
3835 }
3836 }
3837
3838 return 1;
3839}
3840
3841
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02003842static int cmd_sta_preset_testparameters_60ghz(struct sigma_dut *dut,
3843 struct sigma_conn *conn,
3844 struct sigma_cmd *cmd)
3845{
3846 const char *val;
3847 const char *intf = get_param(cmd, "interface");
3848
3849 if (!intf)
3850 return -1;
3851
3852 val = get_param(cmd, "WscIEFragment");
3853 if (val && strcasecmp(val, "enable") == 0) {
3854 sigma_dut_print(dut, DUT_MSG_DEBUG,
3855 "Enable WSC IE fragmentation");
3856
3857 dut->wsc_fragment = 1;
3858 /* set long attributes to force fragmentation */
3859 if (wpa_command(intf, "SET device_name "
3860 WPS_LONG_DEVICE_NAME) < 0)
3861 return -2;
3862 if (wpa_command(intf, "SET manufacturer "
3863 WPS_LONG_MANUFACTURER) < 0)
3864 return -2;
3865 if (wpa_command(intf, "SET model_name "
3866 WPS_LONG_MODEL_NAME) < 0)
3867 return -2;
3868 if (wpa_command(intf, "SET model_number "
3869 WPS_LONG_MODEL_NUMBER) < 0)
3870 return -2;
3871 if (wpa_command(intf, "SET serial_number "
3872 WPS_LONG_SERIAL_NUMBER) < 0)
3873 return -2;
3874 }
3875
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02003876 val = get_param(cmd, "RSN_IE");
3877 if (val) {
3878 if (strcasecmp(val, "disable") == 0)
3879 dut->force_rsn_ie = FORCE_RSN_IE_REMOVE;
3880 else if (strcasecmp(val, "enable") == 0)
3881 dut->force_rsn_ie = FORCE_RSN_IE_ADD;
3882 }
3883
Alexei Avshalom Lazar744ae8a2019-01-31 17:26:46 +02003884 val = get_param(cmd, "WpsVersion");
3885 if (val)
3886 dut->wps_forced_version = get_wps_forced_version(dut, val);
3887
Alexei Avshalom Lazar2eccf4d2019-01-31 10:03:59 +02003888 val = get_param(cmd, "WscEAPFragment");
3889 if (val && strcasecmp(val, "enable") == 0)
3890 dut->eap_fragment = 1;
3891
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02003892 return 1;
3893}
3894
3895
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003896static int cmd_sta_preset_testparameters_hs2_r2(struct sigma_dut *dut,
3897 struct sigma_conn *conn,
3898 const char *intf,
3899 struct sigma_cmd *cmd)
3900{
3901 const char *val;
3902
3903 val = get_param(cmd, "FileType");
3904 if (val && strcasecmp(val, "PPSMO") == 0)
3905 return download_ppsmo(dut, conn, intf, cmd);
3906 if (val && strcasecmp(val, "CERT") == 0)
3907 return download_cert(dut, conn, intf, cmd);
3908 if (val) {
3909 send_resp(dut, conn, SIGMA_ERROR,
3910 "ErrorCode,Unsupported FileType");
3911 return 0;
3912 }
3913
3914 return 1;
3915}
3916
3917
Ankita Bajaja2cb5672017-10-25 16:08:28 +05303918static int cmd_sta_preset_testparameters_oce(struct sigma_dut *dut,
3919 struct sigma_conn *conn,
3920 const char *intf,
3921 struct sigma_cmd *cmd)
3922{
3923 const char *val;
Ankita Bajaj1bde7942018-01-09 19:15:01 +05303924 char buf[1000];
3925 char text[20];
3926 unsigned char addr[ETH_ALEN];
Ankita Bajaja2cb5672017-10-25 16:08:28 +05303927
3928 val = get_param(cmd, "OCESupport");
3929 if (val && strcasecmp(val, "Disable") == 0) {
3930 if (wpa_command(intf, "SET oce 0") < 0) {
3931 send_resp(dut, conn, SIGMA_ERROR,
3932 "ErrorCode,Failed to disable OCE");
3933 return 0;
3934 }
3935 } else if (val && strcasecmp(val, "Enable") == 0) {
3936 if (wpa_command(intf, "SET oce 1") < 0) {
3937 send_resp(dut, conn, SIGMA_ERROR,
3938 "ErrorCode,Failed to enable OCE");
3939 return 0;
3940 }
3941 }
3942
vamsi krishnaa2799492017-12-05 14:28:01 +05303943 val = get_param(cmd, "FILScap");
3944 if (val && (atoi(val) == 1)) {
3945 if (wpa_command(intf, "SET disable_fils 0") < 0) {
3946 send_resp(dut, conn, SIGMA_ERROR,
3947 "ErrorCode,Failed to enable FILS");
3948 return 0;
3949 }
3950 } else if (val && (atoi(val) == 0)) {
3951 if (wpa_command(intf, "SET disable_fils 1") < 0) {
3952 send_resp(dut, conn, SIGMA_ERROR,
3953 "ErrorCode,Failed to disable FILS");
3954 return 0;
3955 }
3956 }
3957
Ankita Bajaj1bde7942018-01-09 19:15:01 +05303958 val = get_param(cmd, "FILSHLP");
3959 if (val && strcasecmp(val, "Enable") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003960 if (get_wpa_status(get_station_ifname(dut), "address", text,
Ankita Bajaj1bde7942018-01-09 19:15:01 +05303961 sizeof(text)) < 0)
3962 return -2;
3963 hwaddr_aton(text, addr);
3964 snprintf(buf, sizeof(buf),
3965 "FILS_HLP_REQ_ADD ff:ff:ff:ff:ff:ff "
3966 "080045100140000040004011399e00000000ffffffff00440043"
3967 "012cb30001010600fd4f46410000000000000000000000000000"
3968 "000000000000"
3969 "%02x%02x%02x%02x%02x%02x"
3970 "0000000000000000000000000000000000000000000000000000"
3971 "0000000000000000000000000000000000000000000000000000"
3972 "0000000000000000000000000000000000000000000000000000"
3973 "0000000000000000000000000000000000000000000000000000"
3974 "0000000000000000000000000000000000000000000000000000"
3975 "0000000000000000000000000000000000000000000000000000"
3976 "0000000000000000000000000000000000000000000000000000"
3977 "0000000000000000000000000000000000000000638253633501"
3978 "013d0701000af549d29b390205dc3c12616e64726f69642d6468"
3979 "63702d382e302e30370a0103060f1a1c333a3b2b5000ff00",
3980 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
3981 if (wpa_command(intf, buf)) {
3982 send_resp(dut, conn, SIGMA_ERROR,
3983 "ErrorCode,Failed to add HLP");
3984 return 0;
3985 }
3986 dut->fils_hlp = 1;
3987 }
3988
Ankita Bajaja2cb5672017-10-25 16:08:28 +05303989 return 1;
3990}
3991
3992
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003993static void ath_sta_set_noack(struct sigma_dut *dut, const char *intf,
3994 const char *val)
3995{
3996 int counter = 0;
3997 char token[50];
3998 char *result;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05303999 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004000
Peng Xub8fc5cc2017-05-10 17:27:28 -07004001 strlcpy(token, val, sizeof(token));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004002 token[sizeof(token) - 1] = '\0';
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05304003 result = strtok_r(token, ":", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004004 while (result) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004005 if (strcmp(result, "disable") == 0)
4006 run_iwpriv(dut, intf, "noackpolicy %d 1 0", counter);
4007 else
4008 run_iwpriv(dut, intf, "noackpolicy %d 1 1", counter);
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05304009 result = strtok_r(NULL, ":", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004010 counter++;
4011 }
4012}
4013
4014
4015static void ath_sta_set_rts(struct sigma_dut *dut, const char *intf,
4016 const char *val)
4017{
4018 char buf[100];
4019
4020 snprintf(buf, sizeof(buf), "iwconfig %s rts %s", intf, val);
4021 if (system(buf) != 0) {
4022 sigma_dut_print(dut, DUT_MSG_ERROR, "iwconfig RTS failed");
4023 }
4024}
4025
4026
4027static void ath_sta_set_wmm(struct sigma_dut *dut, const char *intf,
4028 const char *val)
4029{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004030 if (strcasecmp(val, "off") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004031 run_iwpriv(dut, intf, "wmm 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004032 }
4033}
4034
4035
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08004036static int wcn_sta_set_wmm(struct sigma_dut *dut, const char *intf,
4037 const char *val)
4038{
4039#ifdef NL80211_SUPPORT
4040 struct nl_msg *msg;
4041 int ret = 0;
4042 struct nlattr *params;
4043 int ifindex;
4044 int wmmenable = 1;
4045
4046 if (val &&
4047 (strcasecmp(val, "off") == 0 || strcmp(val, "0") == 0))
4048 wmmenable = 0;
4049
4050 ifindex = if_nametoindex(intf);
4051 if (ifindex == 0) {
4052 sigma_dut_print(dut, DUT_MSG_ERROR,
4053 "%s: Index for interface %s failed",
4054 __func__, intf);
4055 return -1;
4056 }
4057
4058 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4059 NL80211_CMD_VENDOR)) ||
4060 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4061 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4062 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4063 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4064 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4065 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WMM_ENABLE,
4066 wmmenable)) {
4067 sigma_dut_print(dut, DUT_MSG_ERROR,
4068 "%s: err in adding vendor_cmd and vendor_data",
4069 __func__);
4070 nlmsg_free(msg);
4071 return -1;
4072 }
4073 nla_nest_end(msg, params);
4074
4075 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4076 if (ret) {
4077 sigma_dut_print(dut, DUT_MSG_ERROR,
4078 "%s: err in send_and_recv_msgs, ret=%d",
4079 __func__, ret);
4080 }
4081 return ret;
4082#else /* NL80211_SUPPORT */
4083 sigma_dut_print(dut, DUT_MSG_ERROR,
4084 "WMM cannot be changed without NL80211_SUPPORT defined");
4085 return -1;
4086#endif /* NL80211_SUPPORT */
4087}
4088
4089
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004090static void ath_sta_set_sgi(struct sigma_dut *dut, const char *intf,
4091 const char *val)
4092{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004093 int sgi20;
4094
4095 sgi20 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
4096
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004097 run_iwpriv(dut, intf, "shortgi %d", sgi20);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004098}
4099
4100
4101static void ath_sta_set_11nrates(struct sigma_dut *dut, const char *intf,
4102 const char *val)
4103{
Pradeep Reddy POTTETI67376b72016-10-25 20:08:17 +05304104 int rate_code, v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004105
4106 /* Disable Tx Beam forming when using a fixed rate */
4107 ath_disable_txbf(dut, intf);
4108
Pradeep Reddy POTTETI67376b72016-10-25 20:08:17 +05304109 v = atoi(val);
4110 if (v < 0 || v > 32) {
4111 sigma_dut_print(dut, DUT_MSG_ERROR,
4112 "Invalid Fixed MCS rate: %d", v);
4113 return;
4114 }
4115 rate_code = 0x80 + v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004116
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004117 run_iwpriv(dut, intf, "set11NRates 0x%x", rate_code);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004118
4119 /* Channel width gets messed up, fix this */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004120 run_iwpriv(dut, intf, "chwidth %d", dut->chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004121}
4122
4123
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08004124static void iwpriv_sta_set_amsdu(struct sigma_dut *dut, const char *intf,
4125 const char *val)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004126{
4127 char buf[60];
4128
4129 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)
4130 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 2", intf);
4131 else
4132 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 1", intf);
4133
4134 if (system(buf) != 0)
4135 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv amsdu failed");
4136}
4137
4138
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07004139static int iwpriv_sta_set_ampdu(struct sigma_dut *dut, const char *intf,
4140 int ampdu)
4141{
4142 char buf[60];
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08004143 int maxaggregation = 63;
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07004144
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08004145 if (ampdu)
4146 ampdu = maxaggregation;
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07004147 snprintf(buf, sizeof(buf), "iwpriv %s ampdu %d", intf, ampdu);
4148 if (system(buf) != 0) {
4149 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv ampdu failed");
4150 return -1;
4151 }
4152
4153 return 0;
4154}
4155
4156
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004157static void ath_sta_set_stbc(struct sigma_dut *dut, const char *intf,
4158 const char *val)
4159{
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004160 run_iwpriv(dut, intf, "tx_stbc %s", val);
4161 run_iwpriv(dut, intf, "rx_stbc %s", val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004162}
4163
4164
4165static int wcn_sta_set_cts_width(struct sigma_dut *dut, const char *intf,
4166 const char *val)
4167{
4168 char buf[60];
4169
Peng Xucc317ed2017-05-18 16:44:37 -07004170 if (strcmp(val, "160") == 0) {
4171 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 5", intf);
4172 } else if (strcmp(val, "80") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004173 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 3", intf);
4174 } else if (strcmp(val, "40") == 0) {
4175 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 2", intf);
4176 } else if (strcmp(val, "20") == 0) {
4177 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 1", intf);
4178 } else if (strcasecmp(val, "Auto") == 0) {
4179 buf[0] = '\0';
4180 } else {
4181 sigma_dut_print(dut, DUT_MSG_ERROR,
4182 "WIDTH/CTS_WIDTH value not supported");
4183 return -1;
4184 }
4185
4186 if (buf[0] != '\0' && system(buf) != 0) {
4187 sigma_dut_print(dut, DUT_MSG_ERROR,
4188 "Failed to set WIDTH/CTS_WIDTH");
4189 return -1;
4190 }
4191
4192 return 0;
4193}
4194
4195
4196int ath_set_width(struct sigma_dut *dut, struct sigma_conn *conn,
4197 const char *intf, const char *val)
4198{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004199 if (strcasecmp(val, "Auto") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004200 run_iwpriv(dut, intf, "chwidth 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004201 dut->chwidth = 0;
4202 } else if (strcasecmp(val, "20") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004203 run_iwpriv(dut, intf, "chwidth 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004204 dut->chwidth = 0;
4205 } else if (strcasecmp(val, "40") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004206 run_iwpriv(dut, intf, "chwidth 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004207 dut->chwidth = 1;
4208 } else if (strcasecmp(val, "80") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004209 run_iwpriv(dut, intf, "chwidth 2");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004210 dut->chwidth = 2;
4211 } else if (strcasecmp(val, "160") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004212 run_iwpriv(dut, intf, "chwidth 3");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004213 dut->chwidth = 3;
4214 } else {
4215 send_resp(dut, conn, SIGMA_ERROR,
4216 "ErrorCode,WIDTH not supported");
4217 return -1;
4218 }
4219
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004220 return 0;
4221}
4222
4223
4224static int wcn_sta_set_sp_stream(struct sigma_dut *dut, const char *intf,
4225 const char *val)
4226{
4227 char buf[60];
Arif Hussainac6c5112018-05-25 17:34:00 -07004228 int sta_nss;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004229
Amarnath Hullur Subramanyamd5374fa2018-02-25 19:00:24 -08004230 if (strcmp(val, "1SS") == 0 || strcmp(val, "1") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004231 snprintf(buf, sizeof(buf), "iwpriv %s nss 1", intf);
Arif Hussainac6c5112018-05-25 17:34:00 -07004232 sta_nss = 1;
Amarnath Hullur Subramanyamd5374fa2018-02-25 19:00:24 -08004233 } else if (strcmp(val, "2SS") == 0 || strcmp(val, "2") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004234 snprintf(buf, sizeof(buf), "iwpriv %s nss 2", intf);
Arif Hussainac6c5112018-05-25 17:34:00 -07004235 sta_nss = 2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004236 } else {
4237 sigma_dut_print(dut, DUT_MSG_ERROR,
4238 "SP_STREAM value not supported");
4239 return -1;
4240 }
4241
4242 if (system(buf) != 0) {
4243 sigma_dut_print(dut, DUT_MSG_ERROR,
4244 "Failed to set SP_STREAM");
4245 return -1;
4246 }
4247
Arif Hussainac6c5112018-05-25 17:34:00 -07004248 dut->sta_nss = sta_nss;
4249
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004250 return 0;
4251}
4252
4253
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05304254static void wcn_sta_set_stbc(struct sigma_dut *dut, const char *intf,
4255 const char *val)
4256{
4257 char buf[60];
4258
4259 snprintf(buf, sizeof(buf), "iwpriv %s tx_stbc %s", intf, val);
4260 if (system(buf) != 0)
4261 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv tx_stbc failed");
4262
4263 snprintf(buf, sizeof(buf), "iwpriv %s rx_stbc %s", intf, val);
4264 if (system(buf) != 0)
4265 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv rx_stbc failed");
4266}
4267
4268
Ashwini Patil68d02cd2017-01-10 15:39:16 +05304269static int mbo_set_cellular_data_capa(struct sigma_dut *dut,
4270 struct sigma_conn *conn,
4271 const char *intf, int capa)
4272{
4273 char buf[32];
4274
4275 if (capa > 0 && capa < 4) {
4276 snprintf(buf, sizeof(buf), "SET mbo_cell_capa %d", capa);
4277 if (wpa_command(intf, buf) < 0) {
4278 send_resp(dut, conn, SIGMA_ERROR,
4279 "ErrorCode, Failed to set cellular data capability");
4280 return 0;
4281 }
4282 return 1;
4283 }
4284
4285 sigma_dut_print(dut, DUT_MSG_ERROR,
4286 "Invalid Cellular data capability: %d", capa);
4287 send_resp(dut, conn, SIGMA_INVALID,
4288 "ErrorCode,Invalid cellular data capability");
4289 return 0;
4290}
4291
4292
Ashwini Patil9183fdb2017-04-13 16:58:25 +05304293static int mbo_set_roaming(struct sigma_dut *dut, struct sigma_conn *conn,
4294 const char *intf, const char *val)
4295{
4296 if (strcasecmp(val, "Disable") == 0) {
4297 if (wpa_command(intf, "SET roaming 0") < 0) {
4298 send_resp(dut, conn, SIGMA_ERROR,
4299 "ErrorCode,Failed to disable roaming");
4300 return 0;
4301 }
4302 return 1;
4303 }
4304
4305 if (strcasecmp(val, "Enable") == 0) {
4306 if (wpa_command(intf, "SET roaming 1") < 0) {
4307 send_resp(dut, conn, SIGMA_ERROR,
4308 "ErrorCode,Failed to enable roaming");
4309 return 0;
4310 }
4311 return 1;
4312 }
4313
4314 sigma_dut_print(dut, DUT_MSG_ERROR,
4315 "Invalid value provided for roaming: %s", val);
4316 send_resp(dut, conn, SIGMA_INVALID,
4317 "ErrorCode,Unknown value provided for Roaming");
4318 return 0;
4319}
4320
4321
Ashwini Patila75de5a2017-04-13 16:35:05 +05304322static int mbo_set_assoc_disallow(struct sigma_dut *dut,
4323 struct sigma_conn *conn,
4324 const char *intf, const char *val)
4325{
4326 if (strcasecmp(val, "Disable") == 0) {
4327 if (wpa_command(intf, "SET ignore_assoc_disallow 1") < 0) {
4328 send_resp(dut, conn, SIGMA_ERROR,
4329 "ErrorCode,Failed to disable Assoc_disallow");
4330 return 0;
4331 }
4332 return 1;
4333 }
4334
4335 if (strcasecmp(val, "Enable") == 0) {
4336 if (wpa_command(intf, "SET ignore_assoc_disallow 0") < 0) {
4337 send_resp(dut, conn, SIGMA_ERROR,
4338 "ErrorCode,Failed to enable Assoc_disallow");
4339 return 0;
4340 }
4341 return 1;
4342 }
4343
4344 sigma_dut_print(dut, DUT_MSG_ERROR,
4345 "Invalid value provided for Assoc_disallow: %s", val);
4346 send_resp(dut, conn, SIGMA_INVALID,
4347 "ErrorCode,Unknown value provided for Assoc_disallow");
4348 return 0;
4349}
4350
4351
Ashwini Patilc63161e2017-04-13 16:30:23 +05304352static int mbo_set_bss_trans_req(struct sigma_dut *dut, struct sigma_conn *conn,
4353 const char *intf, const char *val)
4354{
4355 if (strcasecmp(val, "Reject") == 0) {
4356 if (wpa_command(intf, "SET reject_btm_req_reason 1") < 0) {
4357 send_resp(dut, conn, SIGMA_ERROR,
4358 "ErrorCode,Failed to Reject BTM Request");
4359 return 0;
4360 }
4361 return 1;
4362 }
4363
4364 if (strcasecmp(val, "Accept") == 0) {
4365 if (wpa_command(intf, "SET reject_btm_req_reason 0") < 0) {
4366 send_resp(dut, conn, SIGMA_ERROR,
4367 "ErrorCode,Failed to Accept BTM Request");
4368 return 0;
4369 }
4370 return 1;
4371 }
4372
4373 sigma_dut_print(dut, DUT_MSG_ERROR,
4374 "Invalid value provided for BSS_Transition: %s", val);
4375 send_resp(dut, conn, SIGMA_INVALID,
4376 "ErrorCode,Unknown value provided for BSS_Transition");
4377 return 0;
4378}
4379
4380
Ashwini Patil00402582017-04-13 12:29:39 +05304381static int mbo_set_non_pref_ch_list(struct sigma_dut *dut,
4382 struct sigma_conn *conn,
4383 const char *intf,
4384 struct sigma_cmd *cmd)
4385{
4386 const char *ch, *pref, *op_class, *reason;
4387 char buf[120];
4388 int len, ret;
4389
4390 pref = get_param(cmd, "Ch_Pref");
4391 if (!pref)
4392 return 1;
4393
4394 if (strcasecmp(pref, "clear") == 0) {
4395 free(dut->non_pref_ch_list);
4396 dut->non_pref_ch_list = NULL;
4397 } else {
4398 op_class = get_param(cmd, "Ch_Op_Class");
4399 if (!op_class) {
4400 send_resp(dut, conn, SIGMA_INVALID,
4401 "ErrorCode,Ch_Op_Class not provided");
4402 return 0;
4403 }
4404
4405 ch = get_param(cmd, "Ch_Pref_Num");
4406 if (!ch) {
4407 send_resp(dut, conn, SIGMA_INVALID,
4408 "ErrorCode,Ch_Pref_Num not provided");
4409 return 0;
4410 }
4411
4412 reason = get_param(cmd, "Ch_Reason_Code");
4413 if (!reason) {
4414 send_resp(dut, conn, SIGMA_INVALID,
4415 "ErrorCode,Ch_Reason_Code not provided");
4416 return 0;
4417 }
4418
4419 if (!dut->non_pref_ch_list) {
4420 dut->non_pref_ch_list =
4421 calloc(1, NON_PREF_CH_LIST_SIZE);
4422 if (!dut->non_pref_ch_list) {
4423 send_resp(dut, conn, SIGMA_ERROR,
4424 "ErrorCode,Failed to allocate memory for non_pref_ch_list");
4425 return 0;
4426 }
4427 }
4428 len = strlen(dut->non_pref_ch_list);
4429 ret = snprintf(dut->non_pref_ch_list + len,
4430 NON_PREF_CH_LIST_SIZE - len,
4431 " %s:%s:%s:%s", op_class, ch, pref, reason);
4432 if (ret > 0 && ret < NON_PREF_CH_LIST_SIZE - len) {
4433 sigma_dut_print(dut, DUT_MSG_DEBUG, "non_pref_list: %s",
4434 dut->non_pref_ch_list);
4435 } else {
4436 sigma_dut_print(dut, DUT_MSG_ERROR,
4437 "snprintf failed for non_pref_list, ret = %d",
4438 ret);
4439 send_resp(dut, conn, SIGMA_ERROR,
4440 "ErrorCode,snprintf failed");
4441 free(dut->non_pref_ch_list);
4442 dut->non_pref_ch_list = NULL;
4443 return 0;
4444 }
4445 }
4446
4447 ret = snprintf(buf, sizeof(buf), "SET non_pref_chan%s",
4448 dut->non_pref_ch_list ? dut->non_pref_ch_list : " ");
4449 if (ret < 0 || ret >= (int) sizeof(buf)) {
4450 sigma_dut_print(dut, DUT_MSG_DEBUG,
4451 "snprintf failed for set non_pref_chan, ret: %d",
4452 ret);
4453 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,snprint failed");
4454 return 0;
4455 }
4456
4457 if (wpa_command(intf, buf) < 0) {
4458 send_resp(dut, conn, SIGMA_ERROR,
4459 "ErrorCode,Failed to set non-preferred channel list");
4460 return 0;
4461 }
4462
4463 return 1;
4464}
4465
4466
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08004467#ifdef NL80211_SUPPORT
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08004468
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08004469static int sta_set_he_htc_supp(struct sigma_dut *dut, const char *intf,
4470 uint8_t cfg)
4471{
4472 struct nl_msg *msg;
4473 int ret = 0;
4474 struct nlattr *params;
4475 int ifindex;
4476
4477 ifindex = if_nametoindex(intf);
4478 if (ifindex == 0) {
4479 sigma_dut_print(dut, DUT_MSG_ERROR,
4480 "%s: Index for interface %s failed",
4481 __func__, intf);
4482 return -1;
4483 }
4484
4485 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4486 NL80211_CMD_VENDOR)) ||
4487 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4488 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4489 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4490 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4491 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4492 nla_put_u8(msg,
4493 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_HTC_HE_SUPP,
4494 cfg)) {
4495 sigma_dut_print(dut, DUT_MSG_ERROR,
4496 "%s: err in adding vendor_cmd and vendor_data",
4497 __func__);
4498 nlmsg_free(msg);
4499 return -1;
4500 }
4501 nla_nest_end(msg, params);
4502
4503 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4504 if (ret) {
4505 sigma_dut_print(dut, DUT_MSG_ERROR,
4506 "%s: err in send_and_recv_msgs, ret=%d",
4507 __func__, ret);
4508 }
4509 return ret;
4510}
4511
4512
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08004513static int sta_set_he_fragmentation(struct sigma_dut *dut, const char *intf,
4514 enum he_fragmentation_val frag)
4515{
4516 struct nl_msg *msg;
4517 int ret = 0;
4518 struct nlattr *params;
4519 int ifindex;
4520
4521 ifindex = if_nametoindex(intf);
4522 if (ifindex == 0) {
4523 sigma_dut_print(dut, DUT_MSG_ERROR,
4524 "%s: Index for interface %s failed",
4525 __func__, intf);
4526 return -1;
4527 }
4528
4529 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4530 NL80211_CMD_VENDOR)) ||
4531 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4532 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4533 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4534 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4535 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4536 nla_put_u8(msg,
4537 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_FRAGMENTATION,
4538 frag)) {
4539 sigma_dut_print(dut, DUT_MSG_ERROR,
4540 "%s: err in adding vendor_cmd and vendor_data",
4541 __func__);
4542 nlmsg_free(msg);
4543 return -1;
4544 }
4545 nla_nest_end(msg, params);
4546
4547 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4548 if (ret) {
4549 sigma_dut_print(dut, DUT_MSG_ERROR,
4550 "%s: err in send_and_recv_msgs, ret=%d",
4551 __func__, ret);
4552 }
4553 return ret;
4554}
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08004555
4556
Subhani Shaik8e7a3052018-04-24 14:03:00 -07004557static int sta_set_he_ltf(struct sigma_dut *dut, const char *intf,
4558 enum qca_wlan_he_ltf_cfg ltf)
4559{
4560 struct nl_msg *msg;
4561 int ret = 0;
4562 struct nlattr *params;
4563 int ifindex;
4564
4565 ifindex = if_nametoindex(intf);
4566 if (ifindex == 0) {
4567 sigma_dut_print(dut, DUT_MSG_ERROR,
4568 "%s: Index for interface %s failed",
4569 __func__, intf);
4570 return -1;
4571 }
4572
4573 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4574 NL80211_CMD_VENDOR)) ||
4575 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4576 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4577 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4578 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4579 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4580 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_LTF,
4581 ltf)) {
4582 sigma_dut_print(dut, DUT_MSG_ERROR,
4583 "%s: err in adding vendor_cmd and vendor_data",
4584 __func__);
4585 nlmsg_free(msg);
4586 return -1;
4587 }
4588 nla_nest_end(msg, params);
4589
4590 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4591 if (ret) {
4592 sigma_dut_print(dut, DUT_MSG_ERROR,
4593 "%s: err in send_and_recv_msgs, ret=%d",
4594 __func__, ret);
4595 }
4596 return ret;
4597}
4598
4599
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08004600static int nlvendor_sta_set_noack(struct sigma_dut *dut, const char *intf,
4601 int noack, enum qca_wlan_ac_type ac)
4602{
4603 struct nl_msg *msg;
4604 int ret = 0;
4605 struct nlattr *params;
4606 int ifindex;
4607
4608 ifindex = if_nametoindex(intf);
4609 if (ifindex == 0) {
4610 sigma_dut_print(dut, DUT_MSG_ERROR,
4611 "%s: Index for interface %s failed",
4612 __func__, intf);
4613 return -1;
4614 }
4615
4616 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4617 NL80211_CMD_VENDOR)) ||
4618 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4619 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4620 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4621 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4622 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4623 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_NO_ACK,
4624 noack) ||
4625 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_NO_ACK_AC,
4626 ac)) {
4627 sigma_dut_print(dut, DUT_MSG_ERROR,
4628 "%s: err in adding vendor_cmd and vendor_data",
4629 __func__);
4630 nlmsg_free(msg);
4631 return -1;
4632 }
4633 nla_nest_end(msg, params);
4634
4635 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4636 if (ret) {
4637 sigma_dut_print(dut, DUT_MSG_ERROR,
4638 "%s: err in send_and_recv_msgs, ret=%d",
4639 __func__, ret);
4640 }
4641 return ret;
4642}
4643
4644
4645static void wcn_sta_set_noack(struct sigma_dut *dut, const char *intf,
4646 const char *val)
4647{
4648 int noack, ret;
4649 char token[100];
4650 char *result;
4651 char *saveptr;
4652 enum qca_wlan_ac_type ac = QCA_WLAN_AC_BE;
4653
4654 strlcpy(token, val, sizeof(token));
4655 token[sizeof(token) - 1] = '\0';
4656 result = strtok_r(token, ":", &saveptr);
4657 while (result) {
4658 noack = strcasecmp(result, "Disable") != 0;
4659 ret = nlvendor_sta_set_noack(dut, intf, noack, ac);
4660 if (ret) {
4661 sigma_dut_print(dut, DUT_MSG_ERROR,
4662 "nlvendor_sta_set_noack failed for ac:%d, ret:%d",
4663 ac, ret);
4664 }
4665 result = strtok_r(NULL, ":", &saveptr);
4666 ac++;
4667 }
4668}
4669
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08004670#endif /* NL80211_SUPPORT */
4671
4672
Jouni Malinenf7222712019-06-13 01:50:21 +03004673static enum sigma_cmd_result
4674cmd_sta_preset_testparameters(struct sigma_dut *dut, struct sigma_conn *conn,
4675 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004676{
4677 const char *intf = get_param(cmd, "Interface");
4678 const char *val;
4679
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03004680 val = get_param(cmd, "FT_DS");
4681 if (val) {
4682 if (strcasecmp(val, "Enable") == 0) {
4683 dut->sta_ft_ds = 1;
4684 } else if (strcasecmp(val, "Disable") == 0) {
4685 dut->sta_ft_ds = 0;
4686 } else {
4687 send_resp(dut, conn, SIGMA_ERROR,
4688 "errorCode,Unsupported value for FT_DS");
4689 return STATUS_SENT_ERROR;
4690 }
4691 }
4692
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004693 val = get_param(cmd, "Program");
Jouni Malinen1f6ae642018-06-07 23:56:13 +03004694 if (val && (strcasecmp(val, "HS2-R2") == 0 ||
4695 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004696 return cmd_sta_preset_testparameters_hs2_r2(dut, conn, intf,
4697 cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004698
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07004699 if (val && strcasecmp(val, "LOC") == 0)
4700 return loc_cmd_sta_preset_testparameters(dut, conn, cmd);
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02004701 if (val && strcasecmp(val, "60GHZ") == 0) {
4702 val = get_param(cmd, "WPS");
4703 if (val && strcasecmp(val, "disable") == 0) {
4704 dut->wps_disable = 1;
4705 sigma_dut_print(dut, DUT_MSG_INFO, "WPS disabled");
4706 } else {
4707 /* wps_disable can have other value from the previous
4708 * test, so make sure it has the correct value.
4709 */
4710 dut->wps_disable = 0;
4711 }
4712
4713 val = get_param(cmd, "P2P");
4714 if (val && strcasecmp(val, "disable") == 0)
4715 sigma_dut_print(dut, DUT_MSG_INFO, "P2P disabled");
4716 }
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07004717
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02004718 if (dut->program == PROGRAM_WPS && dut->band == WPS_BAND_60G)
4719 return cmd_sta_preset_testparameters_60ghz(dut, conn, cmd);
4720
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004721#ifdef ANDROID_NAN
4722 if (val && strcasecmp(val, "NAN") == 0)
4723 return nan_cmd_sta_preset_testparameters(dut, conn, cmd);
4724#endif /* ANDROID_NAN */
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07004725#ifdef MIRACAST
4726 if (val && (strcasecmp(val, "WFD") == 0 ||
4727 strcasecmp(val, "DisplayR2") == 0))
4728 return miracast_preset_testparameters(dut, conn, cmd);
4729#endif /* MIRACAST */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004730
Ashwini Patil68d02cd2017-01-10 15:39:16 +05304731 if (val && strcasecmp(val, "MBO") == 0) {
4732 val = get_param(cmd, "Cellular_Data_Cap");
4733 if (val &&
4734 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
4735 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +05304736
4737 val = get_param(cmd, "Ch_Pref");
4738 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
4739 return 0;
4740
Ashwini Patilc63161e2017-04-13 16:30:23 +05304741 val = get_param(cmd, "BSS_Transition");
4742 if (val && mbo_set_bss_trans_req(dut, conn, intf, val) == 0)
4743 return 0;
4744
Ashwini Patila75de5a2017-04-13 16:35:05 +05304745 val = get_param(cmd, "Assoc_Disallow");
4746 if (val && mbo_set_assoc_disallow(dut, conn, intf, val) == 0)
4747 return 0;
4748
Ashwini Patil9183fdb2017-04-13 16:58:25 +05304749 val = get_param(cmd, "Roaming");
4750 if (val && mbo_set_roaming(dut, conn, intf, val) == 0)
4751 return 0;
4752
Ashwini Patil68d02cd2017-01-10 15:39:16 +05304753 return 1;
4754 }
4755
Ankita Bajaja2cb5672017-10-25 16:08:28 +05304756 if (val && strcasecmp(val, "OCE") == 0)
4757 return cmd_sta_preset_testparameters_oce(dut, conn, intf, cmd);
4758
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004759#if 0
4760 val = get_param(cmd, "Supplicant");
4761 if (val && strcasecmp(val, "Default") != 0) {
4762 send_resp(dut, conn, SIGMA_ERROR,
4763 "ErrorCode,Only default(Vendor) supplicant "
4764 "supported");
4765 return 0;
4766 }
4767#endif
4768
4769 val = get_param(cmd, "RTS");
4770 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004771 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004772 case DRIVER_ATHEROS:
4773 ath_sta_set_rts(dut, intf, val);
4774 break;
4775 default:
4776#if 0
4777 send_resp(dut, conn, SIGMA_ERROR,
4778 "ErrorCode,Setting RTS not supported");
4779 return 0;
4780#else
4781 sigma_dut_print(dut, DUT_MSG_DEBUG,
4782 "Setting RTS not supported");
4783 break;
4784#endif
4785 }
4786 }
4787
4788#if 0
4789 val = get_param(cmd, "FRGMNT");
4790 if (val) {
4791 /* TODO */
4792 send_resp(dut, conn, SIGMA_ERROR,
4793 "ErrorCode,Setting FRGMNT not supported");
4794 return 0;
4795 }
4796#endif
4797
4798#if 0
4799 val = get_param(cmd, "Preamble");
4800 if (val) {
4801 /* TODO: Long/Short */
4802 send_resp(dut, conn, SIGMA_ERROR,
4803 "ErrorCode,Setting Preamble not supported");
4804 return 0;
4805 }
4806#endif
4807
4808 val = get_param(cmd, "Mode");
4809 if (val) {
4810 if (strcmp(val, "11b") == 0 ||
4811 strcmp(val, "11g") == 0 ||
4812 strcmp(val, "11a") == 0 ||
4813 strcmp(val, "11n") == 0 ||
4814 strcmp(val, "11ng") == 0 ||
4815 strcmp(val, "11nl") == 0 ||
4816 strcmp(val, "11nl(nabg)") == 0 ||
4817 strcmp(val, "AC") == 0 ||
4818 strcmp(val, "11AC") == 0 ||
4819 strcmp(val, "11ac") == 0 ||
4820 strcmp(val, "11na") == 0 ||
Amarnath Hullur Subramanyamb0db2712018-01-30 19:40:35 -08004821 strcmp(val, "11an") == 0 ||
4822 strcmp(val, "11ax") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004823 /* STA supports all modes by default */
4824 } else {
4825 send_resp(dut, conn, SIGMA_ERROR,
4826 "ErrorCode,Setting Mode not supported");
4827 return 0;
4828 }
Amarnath Hullur Subramanyam97d0e532018-01-31 02:53:02 -08004829
4830 /* Change the mode only in case of testbed for HE program
4831 * and for 11a and 11g modes only. */
4832 if (dut->program == PROGRAM_HE &&
4833 dut->device_type == STA_testbed) {
4834 int phymode;
4835 char buf[60];
4836
4837 if (strcmp(val, "11a") == 0) {
Amarnath Hullur Subramanyam94dfaf02018-03-02 19:26:57 -08004838 phymode = 1; /* IEEE80211_MODE_11A */
4839 } else if (strcmp(val, "11g") == 0) {
4840 phymode = 3; /* IEEE80211_MODE_11G */
4841 } else if (strcmp(val, "11b") == 0) {
4842 phymode = 2; /* IEEE80211_MODE_11B */
4843 } else if (strcmp(val, "11n") == 0 ||
4844 strcmp(val, "11nl") == 0 ||
4845 strcmp(val, "11nl(nabg)") == 0) {
4846 phymode = 22; /* IEEE80211_MODE_11AGN */
4847 } else if (strcmp(val, "11ng") == 0) {
4848 phymode = 13; /* IEEE80211_MODE_11NG_HT40 */
4849 } else if (strcmp(val, "AC") == 0 ||
4850 strcasecmp(val, "11AC") == 0) {
4851 phymode = 19; /* IEEE80211_MODE_11AC_VHT80 */
4852 } else if (strcmp(val, "11na") == 0 ||
4853 strcasecmp(val, "11an") == 0) {
4854 phymode = 14; /* IEEE80211_MODE_11NA_HT40 */
4855 } else if (strcmp(val, "11ax") == 0) {
4856 phymode = 0; /* IEEE80211_MODE_AUTO */
Amarnath Hullur Subramanyam97d0e532018-01-31 02:53:02 -08004857 } else {
4858 sigma_dut_print(dut, DUT_MSG_DEBUG,
4859 "Ignoring mode change for mode: %s",
4860 val);
4861 phymode = -1;
4862 }
4863 if (phymode != -1) {
4864 snprintf(buf, sizeof(buf),
4865 "iwpriv %s setphymode %d",
4866 intf, phymode);
4867 if (system(buf) != 0) {
4868 sigma_dut_print(dut, DUT_MSG_ERROR,
4869 "iwpriv setting of phymode failed");
4870 }
4871 }
4872 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004873 }
4874
4875 val = get_param(cmd, "wmm");
4876 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004877 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004878 case DRIVER_ATHEROS:
4879 ath_sta_set_wmm(dut, intf, val);
4880 break;
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08004881 case DRIVER_WCN:
4882 wcn_sta_set_wmm(dut, intf, val);
4883 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004884 default:
4885 sigma_dut_print(dut, DUT_MSG_DEBUG,
4886 "Setting wmm not supported");
4887 break;
4888 }
4889 }
4890
4891 val = get_param(cmd, "Powersave");
4892 if (val) {
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08004893 char buf[60];
4894
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004895 if (strcmp(val, "0") == 0 || strcasecmp(val, "off") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004896 if (get_driver_type(dut) == DRIVER_WCN) {
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08004897 snprintf(buf, sizeof(buf),
4898 "iwpriv %s setPower 2", intf);
4899 if (system(buf) != 0) {
4900 sigma_dut_print(dut, DUT_MSG_ERROR,
4901 "iwpriv setPower 2 failed");
4902 return 0;
4903 }
4904 }
4905
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004906 if (wpa_command(get_station_ifname(dut),
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004907 "P2P_SET ps 0") < 0)
4908 return -2;
4909 /* Make sure test modes are disabled */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004910 wpa_command(get_station_ifname(dut), "P2P_SET ps 98");
4911 wpa_command(get_station_ifname(dut), "P2P_SET ps 96");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004912 } else if (strcmp(val, "1") == 0 ||
4913 strcasecmp(val, "PSPoll") == 0 ||
4914 strcasecmp(val, "on") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004915 if (get_driver_type(dut) == DRIVER_WCN) {
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08004916 snprintf(buf, sizeof(buf),
4917 "iwpriv %s setPower 1", intf);
4918 if (system(buf) != 0) {
4919 sigma_dut_print(dut, DUT_MSG_ERROR,
4920 "iwpriv setPower 1 failed");
4921 return 0;
4922 }
4923 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004924 /* Disable default power save mode */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004925 wpa_command(get_station_ifname(dut), "P2P_SET ps 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004926 /* Enable PS-Poll test mode */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004927 if (wpa_command(get_station_ifname(dut),
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004928 "P2P_SET ps 97") < 0 ||
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004929 wpa_command(get_station_ifname(dut),
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004930 "P2P_SET ps 99") < 0)
4931 return -2;
4932 } else if (strcmp(val, "2") == 0 ||
4933 strcasecmp(val, "Fast") == 0) {
4934 /* TODO */
4935 send_resp(dut, conn, SIGMA_ERROR,
4936 "ErrorCode,Powersave=Fast not supported");
4937 return 0;
4938 } else if (strcmp(val, "3") == 0 ||
4939 strcasecmp(val, "PSNonPoll") == 0) {
4940 /* Make sure test modes are disabled */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004941 wpa_command(get_station_ifname(dut), "P2P_SET ps 98");
4942 wpa_command(get_station_ifname(dut), "P2P_SET ps 96");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004943
4944 /* Enable default power save mode */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004945 if (wpa_command(get_station_ifname(dut),
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004946 "P2P_SET ps 1") < 0)
4947 return -2;
4948 } else
4949 return -1;
4950 }
4951
4952 val = get_param(cmd, "NoAck");
4953 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004954 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004955 case DRIVER_ATHEROS:
4956 ath_sta_set_noack(dut, intf, val);
4957 break;
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08004958#ifdef NL80211_SUPPORT
4959 case DRIVER_WCN:
4960 wcn_sta_set_noack(dut, intf, val);
4961 break;
4962#endif /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004963 default:
4964 send_resp(dut, conn, SIGMA_ERROR,
4965 "ErrorCode,Setting NoAck not supported");
4966 return 0;
4967 }
4968 }
4969
4970 val = get_param(cmd, "IgnoreChswitchProhibit");
4971 if (val) {
4972 /* TODO: Enabled/disabled */
4973 if (strcasecmp(val, "Enabled") == 0) {
4974 send_resp(dut, conn, SIGMA_ERROR,
4975 "ErrorCode,Enabling IgnoreChswitchProhibit "
4976 "not supported");
4977 return 0;
4978 }
4979 }
4980
4981 val = get_param(cmd, "TDLS");
4982 if (val) {
4983 if (strcasecmp(val, "Disabled") == 0) {
4984 if (wpa_command(intf, "SET tdls_disabled 1")) {
4985 send_resp(dut, conn, SIGMA_ERROR,
4986 "ErrorCode,Failed to disable TDLS");
4987 return 0;
4988 }
4989 } else if (strcasecmp(val, "Enabled") == 0) {
4990 if (wpa_command(intf, "SET tdls_disabled 0")) {
4991 send_resp(dut, conn, SIGMA_ERROR,
4992 "ErrorCode,Failed to enable TDLS");
4993 return 0;
4994 }
4995 } else {
4996 send_resp(dut, conn, SIGMA_ERROR,
4997 "ErrorCode,Unsupported TDLS value");
4998 return 0;
4999 }
5000 }
5001
5002 val = get_param(cmd, "TDLSmode");
5003 if (val) {
5004 if (strcasecmp(val, "Default") == 0) {
5005 wpa_command(intf, "SET tdls_testing 0");
5006 } else if (strcasecmp(val, "APProhibit") == 0) {
5007 if (wpa_command(intf, "SET tdls_testing 0x400")) {
5008 send_resp(dut, conn, SIGMA_ERROR,
5009 "ErrorCode,Failed to enable ignore "
5010 "APProhibit TDLS mode");
5011 return 0;
5012 }
5013 } else if (strcasecmp(val, "HiLoMac") == 0) {
5014 /* STA should respond with TDLS setup req for a TDLS
5015 * setup req */
5016 if (wpa_command(intf, "SET tdls_testing 0x80")) {
5017 send_resp(dut, conn, SIGMA_ERROR,
5018 "ErrorCode,Failed to enable HiLoMac "
5019 "TDLS mode");
5020 return 0;
5021 }
5022 } else if (strcasecmp(val, "WeakSecurity") == 0) {
5023 /*
5024 * Since all security modes are enabled by default when
5025 * Sigma control is used, there is no need to do
5026 * anything here.
5027 */
5028 } else if (strcasecmp(val, "ExistLink") == 0) {
5029 /*
5030 * Since we allow new TDLS Setup Request even if there
5031 * is an existing link, nothing needs to be done for
5032 * this.
5033 */
5034 } else {
5035 /* TODO:
5036 * ExistLink: STA should send TDLS setup req even if
5037 * direct link already exists
5038 */
5039 send_resp(dut, conn, SIGMA_ERROR,
5040 "ErrorCode,Unsupported TDLSmode value");
5041 return 0;
5042 }
5043 }
5044
5045 val = get_param(cmd, "FakePubKey");
5046 if (val && atoi(val) && wpa_command(intf, "SET wps_corrupt_pkhash 1")) {
5047 send_resp(dut, conn, SIGMA_ERROR,
5048 "ErrorCode,Failed to enable FakePubKey");
5049 return 0;
5050 }
5051
Amarnath Hullur Subramanyamae1042b2018-02-22 21:52:52 -08005052#ifdef NL80211_SUPPORT
5053 val = get_param(cmd, "FrgmntSupport");
5054 if (val) {
5055 if (strcasecmp(val, "Enable") == 0) {
5056 if (sta_set_he_fragmentation(dut, intf,
5057 HE_FRAG_LEVEL1)) {
5058 send_resp(dut, conn, SIGMA_ERROR,
5059 "ErrorCode,Failed to enable HE Fragmentation");
5060 return 0;
5061 }
5062 } else if (strcasecmp(val, "Disable") == 0) {
5063 if (sta_set_he_fragmentation(dut, intf,
5064 HE_FRAG_DISABLE)) {
5065 send_resp(dut, conn, SIGMA_ERROR,
5066 "ErrorCode,Failed to disable HE Fragmentation");
5067 return 0;
5068 }
5069 }
5070 }
5071#endif /* NL80211_SUPPORT */
5072
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005073 return 1;
5074}
5075
5076
5077static const char * ath_get_radio_name(const char *radio_name)
5078{
5079 if (radio_name == NULL)
5080 return "wifi0";
5081 if (strcmp(radio_name, "wifi1") == 0)
5082 return "wifi1";
5083 if (strcmp(radio_name, "wifi2") == 0)
5084 return "wifi2";
5085 return "wifi0";
5086}
5087
5088
5089static void ath_sta_set_txsp_stream(struct sigma_dut *dut, const char *intf,
5090 const char *val)
5091{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005092 unsigned int vht_mcsmap = 0;
5093 int txchainmask = 0;
5094 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
5095
5096 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
5097 if (dut->testbed_flag_txsp == 1) {
5098 vht_mcsmap = 0xfffc;
5099 dut->testbed_flag_txsp = 0;
5100 } else {
5101 vht_mcsmap = 0xfffe;
5102 }
5103 txchainmask = 1;
5104 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
5105 if (dut->testbed_flag_txsp == 1) {
5106 vht_mcsmap = 0xfff0;
5107 dut->testbed_flag_txsp = 0;
5108 } else {
5109 vht_mcsmap = 0xfffa;
5110 }
5111 txchainmask = 3;
5112 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
5113 if (dut->testbed_flag_txsp == 1) {
5114 vht_mcsmap = 0xffc0;
5115 dut->testbed_flag_txsp = 0;
5116 } else {
5117 vht_mcsmap = 0xffea;
5118 }
5119 txchainmask = 7;
5120 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
5121 if (dut->testbed_flag_txsp == 1) {
5122 vht_mcsmap = 0xff00;
5123 dut->testbed_flag_txsp = 0;
5124 } else {
5125 vht_mcsmap = 0xffaa;
5126 }
5127 txchainmask = 15;
5128 } else {
5129 if (dut->testbed_flag_txsp == 1) {
5130 vht_mcsmap = 0xffc0;
5131 dut->testbed_flag_txsp = 0;
5132 } else {
5133 vht_mcsmap = 0xffea;
5134 }
5135 }
5136
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005137 if (txchainmask)
5138 run_iwpriv(dut, basedev, "txchainmask %d", txchainmask);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005139
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005140 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005141}
5142
5143
5144static void ath_sta_set_rxsp_stream(struct sigma_dut *dut, const char *intf,
5145 const char *val)
5146{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005147 unsigned int vht_mcsmap = 0;
5148 int rxchainmask = 0;
5149 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
5150
5151 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
5152 if (dut->testbed_flag_rxsp == 1) {
5153 vht_mcsmap = 0xfffc;
5154 dut->testbed_flag_rxsp = 0;
5155 } else {
5156 vht_mcsmap = 0xfffe;
5157 }
5158 rxchainmask = 1;
5159 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
5160 if (dut->testbed_flag_rxsp == 1) {
5161 vht_mcsmap = 0xfff0;
5162 dut->testbed_flag_rxsp = 0;
5163 } else {
5164 vht_mcsmap = 0xfffa;
5165 }
5166 rxchainmask = 3;
5167 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
5168 if (dut->testbed_flag_rxsp == 1) {
5169 vht_mcsmap = 0xffc0;
5170 dut->testbed_flag_rxsp = 0;
5171 } else {
5172 vht_mcsmap = 0xffea;
5173 }
5174 rxchainmask = 7;
5175 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
5176 if (dut->testbed_flag_rxsp == 1) {
5177 vht_mcsmap = 0xff00;
5178 dut->testbed_flag_rxsp = 0;
5179 } else {
5180 vht_mcsmap = 0xffaa;
5181 }
5182 rxchainmask = 15;
5183 } else {
5184 if (dut->testbed_flag_rxsp == 1) {
5185 vht_mcsmap = 0xffc0;
5186 dut->testbed_flag_rxsp = 0;
5187 } else {
5188 vht_mcsmap = 0xffea;
5189 }
5190 }
5191
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005192 if (rxchainmask)
5193 run_iwpriv(dut, basedev, "rxchainmask %d", rxchainmask);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005194
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005195 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005196}
5197
5198
5199void ath_set_zero_crc(struct sigma_dut *dut, const char *val)
5200{
5201 if (strcasecmp(val, "enable") == 0) {
5202 if (system("athdiag --set --address=0x2a204 --and=0xbfffffff")
5203 != 0) {
5204 sigma_dut_print(dut, DUT_MSG_ERROR,
5205 "Disable BB_VHTSIGB_CRC_CALC failed");
5206 }
5207
5208 if (system("athdiag --set --address=0x2a204 --or=0x80000000")
5209 != 0) {
5210 sigma_dut_print(dut, DUT_MSG_ERROR,
5211 "Enable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
5212 }
5213 } else {
5214 if (system("athdiag --set --address=0x2a204 --and=0x7fffffff")
5215 != 0) {
5216 sigma_dut_print(dut, DUT_MSG_ERROR,
5217 "Disable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
5218 }
5219
5220 if (system("athdiag --set --address=0x2a204 --or=0x40000000")
5221 != 0) {
5222 sigma_dut_print(dut, DUT_MSG_ERROR,
5223 "Enable BB_VHTSIGB_CRC_CALC failed");
5224 }
5225 }
5226}
5227
5228
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08005229static int wcn_sta_set_width(struct sigma_dut *dut, const char *intf,
5230 const char *val)
5231{
5232 char buf[60];
5233
5234 if (strcmp(val, "20") == 0) {
5235 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 0", intf);
5236 dut->chwidth = 0;
5237 } else if (strcmp(val, "40") == 0) {
5238 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 1", intf);
5239 dut->chwidth = 1;
5240 } else if (strcmp(val, "80") == 0) {
5241 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 2", intf);
5242 dut->chwidth = 2;
Sunil Duttb1cccac2018-05-22 21:03:12 +05305243 } else if (strcasecmp(val, "Auto") == 0) {
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08005244 buf[0] = '\0';
5245 } else {
5246 sigma_dut_print(dut, DUT_MSG_ERROR, "WIDTH %s not supported",
5247 val);
5248 return -1;
5249 }
5250
5251 if (buf[0] != '\0' && system(buf) != 0) {
5252 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv chwidth failed");
5253 return -1;
5254 }
5255
5256 return 0;
5257}
5258
5259
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005260static int nlvendor_sta_set_addba_reject(struct sigma_dut *dut,
5261 const char *intf, int addbareject)
5262{
5263#ifdef NL80211_SUPPORT
5264 struct nl_msg *msg;
5265 int ret = 0;
5266 struct nlattr *params;
5267 int ifindex;
5268
5269 ifindex = if_nametoindex(intf);
5270 if (ifindex == 0) {
5271 sigma_dut_print(dut, DUT_MSG_ERROR,
5272 "%s: Index for interface %s failed",
5273 __func__, intf);
5274 return -1;
5275 }
5276
5277 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
5278 NL80211_CMD_VENDOR)) ||
5279 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
5280 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
5281 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
5282 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
5283 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
5284 nla_put_u8(msg,
5285 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ACCEPT_ADDBA_REQ,
5286 !addbareject)) {
5287 sigma_dut_print(dut, DUT_MSG_ERROR,
5288 "%s: err in adding vendor_cmd and vendor_data",
5289 __func__);
5290 nlmsg_free(msg);
5291 return -1;
5292 }
5293 nla_nest_end(msg, params);
5294
5295 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5296 if (ret) {
5297 sigma_dut_print(dut, DUT_MSG_ERROR,
5298 "%s: err in send_and_recv_msgs, ret=%d",
5299 __func__, ret);
5300 }
5301 return ret;
5302#else /* NL80211_SUPPORT */
5303 sigma_dut_print(dut, DUT_MSG_ERROR,
5304 "ADDBA_REJECT cannot be set without NL80211_SUPPORT defined");
5305 return -1;
5306#endif /* NL80211_SUPPORT */
5307}
5308
5309
5310static int sta_set_addba_reject(struct sigma_dut *dut, const char *intf,
5311 int addbareject)
5312{
5313 int ret;
5314
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005315 switch (get_driver_type(dut)) {
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005316 case DRIVER_WCN:
5317 ret = nlvendor_sta_set_addba_reject(dut, intf, addbareject);
5318 if (ret) {
5319 sigma_dut_print(dut, DUT_MSG_ERROR,
5320 "nlvendor_sta_set_addba_reject failed, ret:%d",
5321 ret);
5322 return ret;
5323 }
5324 break;
5325 default:
5326 sigma_dut_print(dut, DUT_MSG_ERROR,
5327 "errorCode,Unsupported ADDBA_REJECT with the current driver");
5328 ret = -1;
5329 break;
5330 }
5331
5332 return ret;
5333}
5334
5335
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08005336static int nlvendor_config_send_addba(struct sigma_dut *dut, const char *intf,
5337 int enable)
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005338{
5339#ifdef NL80211_SUPPORT
5340 struct nl_msg *msg;
5341 int ret = 0;
5342 struct nlattr *params;
5343 int ifindex;
5344
5345 ifindex = if_nametoindex(intf);
5346 if (ifindex == 0) {
5347 sigma_dut_print(dut, DUT_MSG_ERROR,
5348 "%s: Index for interface %s failed",
5349 __func__, intf);
5350 return -1;
5351 }
5352
5353 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
5354 NL80211_CMD_VENDOR)) ||
5355 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
5356 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
5357 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
5358 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
5359 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
5360 nla_put_u8(msg,
5361 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_SEND_ADDBA_REQ,
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08005362 enable)) {
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005363 sigma_dut_print(dut, DUT_MSG_ERROR,
5364 "%s: err in adding vendor_cmd and vendor_data",
5365 __func__);
5366 nlmsg_free(msg);
5367 return -1;
5368 }
5369 nla_nest_end(msg, params);
5370
5371 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5372 if (ret) {
5373 sigma_dut_print(dut, DUT_MSG_ERROR,
5374 "%s: err in send_and_recv_msgs, ret=%d",
5375 __func__, ret);
5376 }
5377 return ret;
5378#else /* NL80211_SUPPORT */
5379 sigma_dut_print(dut, DUT_MSG_ERROR,
5380 "Disable addba not possible without NL80211_SUPPORT defined");
5381 return -1;
5382#endif /* NL80211_SUPPORT */
5383}
5384
5385
Veerendranath Jakkamadcd6202019-04-17 12:32:21 +05305386#ifdef NL80211_SUPPORT
5387static int nl80211_sta_set_rts(struct sigma_dut *dut, const char *intf, int val)
5388{
5389 struct nl_msg *msg;
5390 int ret = 0;
5391 int ifindex;
5392
5393 ifindex = if_nametoindex(intf);
5394 if (ifindex == 0) {
5395 sigma_dut_print(dut, DUT_MSG_ERROR,
5396 "%s: Index for interface %s failed",
5397 __func__, intf);
5398 return -1;
5399 }
5400
5401 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
5402 NL80211_CMD_SET_WIPHY)) ||
5403 nla_put_u32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD, val)) {
5404 sigma_dut_print(dut, DUT_MSG_ERROR,
5405 "%s: err in adding RTS threshold",
5406 __func__);
5407 nlmsg_free(msg);
5408 return -1;
5409 }
5410
5411 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5412 if (ret) {
5413 sigma_dut_print(dut, DUT_MSG_ERROR,
5414 "%s: err in send_and_recv_msgs, ret=%d",
5415 __func__, ret);
5416 }
5417 return ret;
5418}
5419#endif /* NL80211_SUPPORT */
5420
5421
5422static int sta_set_rts(struct sigma_dut *dut, const char *intf, int val)
5423{
5424 char buf[100];
5425
5426#ifdef NL80211_SUPPORT
5427 if (nl80211_sta_set_rts(dut, intf, val) == 0)
5428 return 0;
5429 sigma_dut_print(dut, DUT_MSG_DEBUG,
5430 "Fall back to using iwconfig for setting RTS threshold");
5431#endif /* NL80211_SUPPORT */
5432
5433 snprintf(buf, sizeof(buf), "iwconfig %s rts %d", intf, val);
5434 if (system(buf) != 0) {
5435 sigma_dut_print(dut, DUT_MSG_ERROR,
5436 "Failed to set RTS threshold %d", val);
5437 return -1;
5438 }
5439 return 0;
5440}
5441
5442
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005443static int cmd_sta_set_wireless_common(const char *intf, struct sigma_dut *dut,
5444 struct sigma_conn *conn,
5445 struct sigma_cmd *cmd)
5446{
5447 const char *val;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005448 int ampdu = -1, addbareject = -1;
Jouni Malinen3aa72862019-05-29 23:14:51 +03005449 char buf[128];
5450 int res;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005451
5452 val = get_param(cmd, "40_INTOLERANT");
5453 if (val) {
5454 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
5455 /* TODO: iwpriv ht40intol through wpa_supplicant */
5456 send_resp(dut, conn, SIGMA_ERROR,
5457 "ErrorCode,40_INTOLERANT not supported");
5458 return 0;
5459 }
5460 }
5461
5462 val = get_param(cmd, "ADDBA_REJECT");
5463 if (val) {
5464 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
5465 /* reject any ADDBA with status "decline" */
5466 ampdu = 0;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005467 addbareject = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005468 } else {
5469 /* accept ADDBA */
5470 ampdu = 1;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005471 addbareject = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005472 }
5473 }
5474
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005475 if (addbareject >= 0 &&
5476 sta_set_addba_reject(dut, intf, addbareject) < 0) {
5477 send_resp(dut, conn, SIGMA_ERROR,
5478 "ErrorCode,set addba_reject failed");
5479 return 0;
5480 }
5481
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005482 val = get_param(cmd, "AMPDU");
5483 if (val) {
5484 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
5485 /* enable AMPDU Aggregation */
5486 if (ampdu == 0) {
5487 send_resp(dut, conn, SIGMA_ERROR,
5488 "ErrorCode,Mismatch in "
5489 "addba_reject/ampdu - "
5490 "not supported");
5491 return 0;
5492 }
5493 ampdu = 1;
5494 } else {
5495 /* disable AMPDU Aggregation */
5496 if (ampdu == 1) {
5497 send_resp(dut, conn, SIGMA_ERROR,
5498 "ErrorCode,Mismatch in "
5499 "addba_reject/ampdu - "
5500 "not supported");
5501 return 0;
5502 }
5503 ampdu = 0;
5504 }
5505 }
5506
5507 if (ampdu >= 0) {
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005508 int ret;
5509
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005510 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s A-MPDU aggregation",
5511 ampdu ? "Enabling" : "Disabling");
5512 snprintf(buf, sizeof(buf), "SET ampdu %d", ampdu);
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07005513 if (wpa_command(intf, buf) < 0 &&
5514 iwpriv_sta_set_ampdu(dut, intf, ampdu) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005515 send_resp(dut, conn, SIGMA_ERROR,
5516 "ErrorCode,set aggr failed");
5517 return 0;
5518 }
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005519
5520 if (ampdu == 0) {
5521 /* Disable sending of addba using nl vendor command */
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08005522 ret = nlvendor_config_send_addba(dut, intf, 0);
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005523 if (ret) {
5524 sigma_dut_print(dut, DUT_MSG_ERROR,
5525 "Failed to disable addba, ret:%d",
5526 ret);
5527 }
5528 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005529 }
5530
5531 val = get_param(cmd, "AMSDU");
5532 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005533 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005534 case DRIVER_ATHEROS:
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08005535 case DRIVER_WCN:
5536 iwpriv_sta_set_amsdu(dut, intf, val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005537 break;
5538 default:
5539 if (strcmp(val, "1") == 0 ||
5540 strcasecmp(val, "Enable") == 0) {
5541 /* Enable AMSDU Aggregation */
5542 send_resp(dut, conn, SIGMA_ERROR,
5543 "ErrorCode,AMSDU aggregation not supported");
5544 return 0;
5545 }
5546 break;
5547 }
5548 }
5549
5550 val = get_param(cmd, "STBC_RX");
5551 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005552 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005553 case DRIVER_ATHEROS:
5554 ath_sta_set_stbc(dut, intf, val);
5555 break;
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05305556 case DRIVER_WCN:
5557 wcn_sta_set_stbc(dut, intf, val);
5558 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005559 default:
5560 send_resp(dut, conn, SIGMA_ERROR,
5561 "ErrorCode,STBC_RX not supported");
5562 return 0;
5563 }
5564 }
5565
5566 val = get_param(cmd, "WIDTH");
5567 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005568 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005569 case DRIVER_WCN:
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08005570 if (wcn_sta_set_width(dut, intf, val) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005571 send_resp(dut, conn, SIGMA_ERROR,
5572 "ErrorCode,Failed to set WIDTH");
5573 return 0;
5574 }
5575 break;
5576 case DRIVER_ATHEROS:
5577 if (ath_set_width(dut, conn, intf, val) < 0)
5578 return 0;
5579 break;
5580 default:
5581 sigma_dut_print(dut, DUT_MSG_ERROR,
5582 "Setting WIDTH not supported");
5583 break;
5584 }
5585 }
5586
5587 val = get_param(cmd, "SMPS");
5588 if (val) {
5589 /* TODO: Dynamic/0, Static/1, No Limit/2 */
5590 send_resp(dut, conn, SIGMA_ERROR,
5591 "ErrorCode,SMPS not supported");
5592 return 0;
5593 }
5594
5595 val = get_param(cmd, "TXSP_STREAM");
5596 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005597 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005598 case DRIVER_WCN:
5599 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
5600 send_resp(dut, conn, SIGMA_ERROR,
5601 "ErrorCode,Failed to set TXSP_STREAM");
5602 return 0;
5603 }
5604 break;
5605 case DRIVER_ATHEROS:
5606 ath_sta_set_txsp_stream(dut, intf, val);
5607 break;
5608 default:
5609 sigma_dut_print(dut, DUT_MSG_ERROR,
5610 "Setting TXSP_STREAM not supported");
5611 break;
5612 }
5613 }
5614
5615 val = get_param(cmd, "RXSP_STREAM");
5616 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005617 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005618 case DRIVER_WCN:
5619 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
5620 send_resp(dut, conn, SIGMA_ERROR,
5621 "ErrorCode,Failed to set RXSP_STREAM");
5622 return 0;
5623 }
5624 break;
5625 case DRIVER_ATHEROS:
5626 ath_sta_set_rxsp_stream(dut, intf, val);
5627 break;
5628 default:
5629 sigma_dut_print(dut, DUT_MSG_ERROR,
5630 "Setting RXSP_STREAM not supported");
5631 break;
5632 }
5633 }
5634
5635 val = get_param(cmd, "DYN_BW_SGNL");
5636 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005637 switch (get_driver_type(dut)) {
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08005638 case DRIVER_WCN:
Peng Xuc59afd32016-11-21 15:01:11 -08005639 if (strcasecmp(val, "enable") == 0) {
5640 snprintf(buf, sizeof(buf),
5641 "iwpriv %s cwmenable 1", intf);
5642 if (system(buf) != 0) {
5643 sigma_dut_print(dut, DUT_MSG_ERROR,
5644 "iwpriv cwmenable 1 failed");
5645 return 0;
5646 }
5647 } else if (strcasecmp(val, "disable") == 0) {
5648 snprintf(buf, sizeof(buf),
5649 "iwpriv %s cwmenable 0", intf);
5650 if (system(buf) != 0) {
5651 sigma_dut_print(dut, DUT_MSG_ERROR,
5652 "iwpriv cwmenable 0 failed");
5653 return 0;
5654 }
5655 } else {
5656 sigma_dut_print(dut, DUT_MSG_ERROR,
5657 "Unsupported DYN_BW_SGL");
5658 }
5659
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005660 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 3", intf);
5661 if (system(buf) != 0) {
5662 sigma_dut_print(dut, DUT_MSG_ERROR,
5663 "Failed to set cts_cbw in DYN_BW_SGNL");
5664 return 0;
5665 }
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08005666 break;
5667 case DRIVER_ATHEROS:
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -07005668 novap_reset(dut, intf, 1);
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08005669 ath_config_dyn_bw_sig(dut, intf, val);
5670 break;
5671 default:
5672 sigma_dut_print(dut, DUT_MSG_ERROR,
5673 "Failed to set DYN_BW_SGNL");
5674 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005675 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005676 }
5677
5678 val = get_param(cmd, "RTS_FORCE");
5679 if (val) {
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -07005680 novap_reset(dut, intf, 1);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005681 if (strcasecmp(val, "Enable") == 0) {
Veerendranath Jakkamadcd6202019-04-17 12:32:21 +05305682 if (sta_set_rts(dut, intf, 64) != 0) {
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02005683 sigma_dut_print(dut, DUT_MSG_ERROR,
5684 "Failed to set RTS_FORCE 64");
5685 }
Jouni Malinen3aa72862019-05-29 23:14:51 +03005686 res = snprintf(buf, sizeof(buf),
5687 "wifitool %s beeliner_fw_test 100 1",
5688 intf);
5689 if (res < 0 || res >= sizeof(buf) || system(buf) != 0) {
priyadharshini gowthaman270870e2015-12-09 10:10:23 -08005690 sigma_dut_print(dut, DUT_MSG_ERROR,
5691 "wifitool beeliner_fw_test 100 1 failed");
5692 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005693 } else if (strcasecmp(val, "Disable") == 0) {
Veerendranath Jakkamadcd6202019-04-17 12:32:21 +05305694 if (sta_set_rts(dut, intf, 2347) != 0) {
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02005695 sigma_dut_print(dut, DUT_MSG_ERROR,
5696 "Failed to set RTS_FORCE 2347");
5697 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005698 } else {
5699 send_resp(dut, conn, SIGMA_ERROR,
5700 "ErrorCode,RTS_FORCE value not supported");
5701 return 0;
5702 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005703 }
5704
5705 val = get_param(cmd, "CTS_WIDTH");
5706 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005707 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005708 case DRIVER_WCN:
5709 if (wcn_sta_set_cts_width(dut, intf, val) < 0) {
5710 send_resp(dut, conn, SIGMA_ERROR,
5711 "ErrorCode,Failed to set CTS_WIDTH");
5712 return 0;
5713 }
5714 break;
5715 case DRIVER_ATHEROS:
5716 ath_set_cts_width(dut, intf, val);
5717 break;
5718 default:
5719 sigma_dut_print(dut, DUT_MSG_ERROR,
5720 "Setting CTS_WIDTH not supported");
5721 break;
5722 }
5723 }
5724
5725 val = get_param(cmd, "BW_SGNL");
5726 if (val) {
5727 if (strcasecmp(val, "Enable") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005728 run_iwpriv(dut, intf, "cwmenable 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005729 } else if (strcasecmp(val, "Disable") == 0) {
5730 /* TODO: Disable */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005731 } else {
5732 send_resp(dut, conn, SIGMA_ERROR,
5733 "ErrorCode,BW_SGNL value not supported");
5734 return 0;
5735 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005736 }
5737
5738 val = get_param(cmd, "Band");
5739 if (val) {
5740 if (strcmp(val, "2.4") == 0 || strcmp(val, "5") == 0) {
5741 /* STA supports all bands by default */
5742 } else {
5743 send_resp(dut, conn, SIGMA_ERROR,
5744 "ErrorCode,Unsupported Band");
5745 return 0;
5746 }
5747 }
5748
5749 val = get_param(cmd, "zero_crc");
5750 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005751 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005752 case DRIVER_ATHEROS:
5753 ath_set_zero_crc(dut, val);
5754 break;
5755 default:
5756 break;
5757 }
5758 }
5759
5760 return 1;
5761}
5762
5763
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02005764static int sta_set_force_mcs(struct sigma_dut *dut, int force, int mcs)
5765{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005766 switch (get_driver_type(dut)) {
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02005767#ifdef __linux__
5768 case DRIVER_WIL6210:
5769 return wil6210_set_force_mcs(dut, force, mcs);
5770#endif /* __linux__ */
5771 default:
5772 sigma_dut_print(dut, DUT_MSG_ERROR,
5773 "Unsupported sta_set_force_mcs with the current driver");
5774 return -1;
5775 }
5776}
5777
5778
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02005779static int sta_60g_force_rsn_ie(struct sigma_dut *dut, int state)
5780{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005781 switch (get_driver_type(dut)) {
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02005782#ifdef __linux__
5783 case DRIVER_WIL6210:
5784 return wil6210_force_rsn_ie(dut, state);
5785#endif /* __linux__ */
5786 default:
5787 sigma_dut_print(dut, DUT_MSG_ERROR,
5788 "Unsupported sta_60g_force_rsn_ie with the current driver");
5789 return -1;
5790 }
5791}
5792
5793
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005794static int sta_set_60g_common(struct sigma_dut *dut, struct sigma_conn *conn,
5795 struct sigma_cmd *cmd)
5796{
5797 const char *val;
5798 char buf[100];
5799
5800 val = get_param(cmd, "MSDUSize");
5801 if (val) {
5802 int mtu;
5803
5804 dut->amsdu_size = atoi(val);
5805 if (dut->amsdu_size > IEEE80211_MAX_DATA_LEN_DMG ||
5806 dut->amsdu_size < IEEE80211_SNAP_LEN_DMG) {
5807 sigma_dut_print(dut, DUT_MSG_ERROR,
5808 "MSDUSize %d is above max %d or below min %d",
5809 dut->amsdu_size,
5810 IEEE80211_MAX_DATA_LEN_DMG,
5811 IEEE80211_SNAP_LEN_DMG);
5812 dut->amsdu_size = 0;
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005813 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005814 }
5815
5816 mtu = dut->amsdu_size - IEEE80211_SNAP_LEN_DMG;
5817 sigma_dut_print(dut, DUT_MSG_DEBUG,
5818 "Setting amsdu_size to %d", mtu);
5819 snprintf(buf, sizeof(buf), "ifconfig %s mtu %d",
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005820 get_station_ifname(dut), mtu);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005821
5822 if (system(buf) != 0) {
5823 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
5824 buf);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005825 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005826 }
5827 }
5828
5829 val = get_param(cmd, "BAckRcvBuf");
5830 if (val) {
5831 dut->back_rcv_buf = atoi(val);
5832 if (dut->back_rcv_buf == 0) {
5833 sigma_dut_print(dut, DUT_MSG_ERROR,
5834 "Failed to convert %s or value is 0",
5835 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005836 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005837 }
5838
5839 sigma_dut_print(dut, DUT_MSG_DEBUG,
5840 "Setting BAckRcvBuf to %s", val);
5841 }
5842
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02005843 val = get_param(cmd, "MCS_FixedRate");
5844 if (val) {
5845 if (sta_set_force_mcs(dut, 1, atoi(val))) {
5846 sigma_dut_print(dut, DUT_MSG_ERROR,
5847 "Failed to force MCS");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005848 return ERROR_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02005849 }
5850 }
5851
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005852 return SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005853}
5854
5855
5856static int sta_pcp_start(struct sigma_dut *dut, struct sigma_conn *conn,
5857 struct sigma_cmd *cmd)
5858{
5859 int net_id;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005860 const char *ifname;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005861 const char *val;
5862 char buf[100];
5863
5864 dut->mode = SIGMA_MODE_STATION;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005865 ifname = get_main_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005866 if (wpa_command(ifname, "PING") != 0) {
5867 sigma_dut_print(dut, DUT_MSG_ERROR, "Supplicant not running");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005868 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005869 }
5870
5871 wpa_command(ifname, "FLUSH");
5872 net_id = add_network_common(dut, conn, ifname, cmd);
5873 if (net_id < 0) {
5874 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add network");
5875 return net_id;
5876 }
5877
5878 /* TODO: mode=2 for the AP; in the future, replace for mode PCP */
5879 if (set_network(ifname, net_id, "mode", "2") < 0) {
5880 sigma_dut_print(dut, DUT_MSG_ERROR,
5881 "Failed to set supplicant network mode");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005882 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005883 }
5884
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02005885 if (set_network(ifname, net_id, "pbss", "1") < 0)
5886 return -2;
5887
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005888 sigma_dut_print(dut, DUT_MSG_DEBUG,
Alexei Avshalom Lazarfd9f1352018-11-13 14:07:58 +02005889 "Supplicant set network with mode 2. network_id %d",
5890 net_id);
5891
5892 if (set_network(ifname, net_id, "wps_disabled", "0") < 0) {
5893 sigma_dut_print(dut, DUT_MSG_INFO,
5894 "Failed to set supplicant to WPS ENABLE");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005895 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarfd9f1352018-11-13 14:07:58 +02005896 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005897
5898 val = get_param(cmd, "Security");
5899 if (val && strcasecmp(val, "OPEN") == 0) {
5900 dut->ap_key_mgmt = AP_OPEN;
5901 if (set_network(ifname, net_id, "key_mgmt", "NONE") < 0) {
5902 sigma_dut_print(dut, DUT_MSG_ERROR,
5903 "Failed to set supplicant to %s security",
5904 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005905 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005906 }
5907 } else if (val && strcasecmp(val, "WPA2-PSK") == 0) {
5908 dut->ap_key_mgmt = AP_WPA2_PSK;
5909 if (set_network(ifname, net_id, "key_mgmt", "WPA-PSK") < 0) {
5910 sigma_dut_print(dut, DUT_MSG_ERROR,
5911 "Failed to set supplicant to %s security",
5912 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005913 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005914 }
5915
5916 if (set_network(ifname, net_id, "proto", "RSN") < 0) {
5917 sigma_dut_print(dut, DUT_MSG_ERROR,
5918 "Failed to set supplicant to proto RSN");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005919 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005920 }
5921 } else if (val) {
5922 sigma_dut_print(dut, DUT_MSG_ERROR,
5923 "Requested Security %s is not supported on 60GHz",
5924 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005925 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005926 }
5927
5928 val = get_param(cmd, "Encrypt");
5929 if (val && strcasecmp(val, "AES-GCMP") == 0) {
5930 if (set_network(ifname, net_id, "pairwise", "GCMP") < 0) {
5931 sigma_dut_print(dut, DUT_MSG_ERROR,
5932 "Failed to set supplicant to pairwise GCMP");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005933 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005934 }
5935 if (set_network(ifname, net_id, "group", "GCMP") < 0) {
5936 sigma_dut_print(dut, DUT_MSG_ERROR,
5937 "Failed to set supplicant to group GCMP");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005938 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005939 }
5940 } else if (val) {
5941 sigma_dut_print(dut, DUT_MSG_ERROR,
5942 "Requested Encrypt %s is not supported on 60 GHz",
5943 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005944 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005945 }
5946
5947 val = get_param(cmd, "PSK");
5948 if (val && set_network_quoted(ifname, net_id, "psk", val) < 0) {
5949 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set psk %s",
5950 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005951 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005952 }
5953
5954 /* Convert 60G channel to freq */
5955 switch (dut->ap_channel) {
5956 case 1:
5957 val = "58320";
5958 break;
5959 case 2:
5960 val = "60480";
5961 break;
5962 case 3:
5963 val = "62640";
5964 break;
5965 default:
5966 sigma_dut_print(dut, DUT_MSG_ERROR,
5967 "Failed to configure channel %d. Not supported",
5968 dut->ap_channel);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005969 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005970 }
5971
5972 if (set_network(ifname, net_id, "frequency", val) < 0) {
5973 sigma_dut_print(dut, DUT_MSG_ERROR,
5974 "Failed to set supplicant network frequency");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005975 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005976 }
5977
Alexei Avshalom Lazar2eccf4d2019-01-31 10:03:59 +02005978 if (dut->eap_fragment) {
5979 sigma_dut_print(dut, DUT_MSG_DEBUG,
5980 "Set EAP fragment size to 128 bytes.");
5981 if (set_network(ifname, net_id, "fragment_size", "128") < 0)
5982 return ERROR_SEND_STATUS;
5983 }
5984
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005985 sigma_dut_print(dut, DUT_MSG_DEBUG,
5986 "Supplicant set network with frequency");
5987
5988 snprintf(buf, sizeof(buf), "SELECT_NETWORK %d", net_id);
5989 if (wpa_command(ifname, buf) < 0) {
5990 sigma_dut_print(dut, DUT_MSG_INFO,
5991 "Failed to select network id %d on %s",
5992 net_id, ifname);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005993 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005994 }
5995
5996 sigma_dut_print(dut, DUT_MSG_DEBUG, "Selected network");
5997
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005998 return SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005999}
6000
6001
Lior David67543f52017-01-03 19:04:22 +02006002static int wil6210_set_abft_len(struct sigma_dut *dut, int abft_len)
6003{
6004 char buf[128], fname[128];
6005 FILE *f;
Jouni Malinen3aa72862019-05-29 23:14:51 +03006006 int res;
Lior David67543f52017-01-03 19:04:22 +02006007
6008 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
6009 sigma_dut_print(dut, DUT_MSG_ERROR,
6010 "failed to get wil6210 debugfs dir");
6011 return -1;
6012 }
6013
Jouni Malinen3aa72862019-05-29 23:14:51 +03006014 res = snprintf(fname, sizeof(fname), "%s/abft_len", buf);
6015 if (res < 0 || res >= sizeof(fname))
6016 return -1;
Lior David67543f52017-01-03 19:04:22 +02006017 f = fopen(fname, "w");
6018 if (!f) {
6019 sigma_dut_print(dut, DUT_MSG_ERROR,
6020 "failed to open: %s", fname);
6021 return -1;
6022 }
6023
6024 fprintf(f, "%d\n", abft_len);
6025 fclose(f);
6026
6027 return 0;
6028}
6029
6030
Alexei Avshalom Lazar49498b82019-01-31 15:16:32 +02006031int sta_set_60g_abft_len(struct sigma_dut *dut, struct sigma_conn *conn,
6032 int abft_len)
Lior David67543f52017-01-03 19:04:22 +02006033{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006034 switch (get_driver_type(dut)) {
Lior David67543f52017-01-03 19:04:22 +02006035 case DRIVER_WIL6210:
6036 return wil6210_set_abft_len(dut, abft_len);
6037 default:
6038 sigma_dut_print(dut, DUT_MSG_ERROR,
6039 "set abft_len not supported");
6040 return -1;
6041 }
6042}
6043
6044
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006045static int sta_set_60g_pcp(struct sigma_dut *dut, struct sigma_conn *conn,
6046 struct sigma_cmd *cmd)
6047{
6048 const char *val;
Lior David67543f52017-01-03 19:04:22 +02006049 unsigned int abft_len = 1; /* default is one slot */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006050
6051 if (dut->dev_role != DEVROLE_PCP) {
6052 send_resp(dut, conn, SIGMA_INVALID,
6053 "ErrorCode,Invalid DevRole");
6054 return 0;
6055 }
6056
6057 val = get_param(cmd, "SSID");
6058 if (val) {
6059 if (strlen(val) > sizeof(dut->ap_ssid) - 1) {
6060 send_resp(dut, conn, SIGMA_INVALID,
6061 "ErrorCode,Invalid SSID");
6062 return -1;
6063 }
6064
Peng Xub8fc5cc2017-05-10 17:27:28 -07006065 strlcpy(dut->ap_ssid, val, sizeof(dut->ap_ssid));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006066 }
6067
6068 val = get_param(cmd, "CHANNEL");
6069 if (val) {
6070 const char *pos;
6071
6072 dut->ap_channel = atoi(val);
6073 pos = strchr(val, ';');
6074 if (pos) {
6075 pos++;
6076 dut->ap_channel_1 = atoi(pos);
6077 }
6078 }
6079
6080 switch (dut->ap_channel) {
6081 case 1:
6082 case 2:
6083 case 3:
6084 break;
6085 default:
6086 sigma_dut_print(dut, DUT_MSG_ERROR,
6087 "Channel %d is not supported", dut->ap_channel);
6088 send_resp(dut, conn, SIGMA_ERROR,
6089 "Requested channel is not supported");
6090 return -1;
6091 }
6092
6093 val = get_param(cmd, "BCNINT");
6094 if (val)
6095 dut->ap_bcnint = atoi(val);
6096
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006097 val = get_param(cmd, "AllocType");
6098 if (val) {
6099 send_resp(dut, conn, SIGMA_ERROR,
6100 "ErrorCode,AllocType is not supported yet");
6101 return -1;
6102 }
6103
6104 val = get_param(cmd, "PercentBI");
6105 if (val) {
6106 send_resp(dut, conn, SIGMA_ERROR,
6107 "ErrorCode,PercentBI is not supported yet");
6108 return -1;
6109 }
6110
6111 val = get_param(cmd, "CBAPOnly");
6112 if (val) {
6113 send_resp(dut, conn, SIGMA_ERROR,
6114 "ErrorCode,CBAPOnly is not supported yet");
6115 return -1;
6116 }
6117
6118 val = get_param(cmd, "AMPDU");
6119 if (val) {
6120 if (strcasecmp(val, "Enable") == 0)
6121 dut->ap_ampdu = 1;
6122 else if (strcasecmp(val, "Disable") == 0)
6123 dut->ap_ampdu = 2;
6124 else {
6125 send_resp(dut, conn, SIGMA_ERROR,
6126 "ErrorCode,AMPDU value is not Enable nor Disabled");
6127 return -1;
6128 }
6129 }
6130
6131 val = get_param(cmd, "AMSDU");
6132 if (val) {
6133 if (strcasecmp(val, "Enable") == 0)
6134 dut->ap_amsdu = 1;
6135 else if (strcasecmp(val, "Disable") == 0)
6136 dut->ap_amsdu = 2;
6137 }
6138
6139 val = get_param(cmd, "NumMSDU");
6140 if (val) {
6141 send_resp(dut, conn, SIGMA_ERROR,
6142 "ErrorCode, NumMSDU is not supported yet");
6143 return -1;
6144 }
6145
6146 val = get_param(cmd, "ABFTLRang");
6147 if (val) {
6148 sigma_dut_print(dut, DUT_MSG_DEBUG,
Lior David67543f52017-01-03 19:04:22 +02006149 "ABFTLRang parameter %s", val);
6150 if (strcmp(val, "Gt1") == 0)
6151 abft_len = 2; /* 2 slots in this case */
6152 }
6153
6154 if (sta_set_60g_abft_len(dut, conn, abft_len)) {
6155 send_resp(dut, conn, SIGMA_ERROR,
6156 "ErrorCode, Can't set ABFT length");
6157 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006158 }
6159
6160 if (sta_pcp_start(dut, conn, cmd) < 0) {
6161 send_resp(dut, conn, SIGMA_ERROR,
6162 "ErrorCode, Can't start PCP role");
6163 return -1;
6164 }
6165
6166 return sta_set_60g_common(dut, conn, cmd);
6167}
6168
6169
6170static int sta_set_60g_sta(struct sigma_dut *dut, struct sigma_conn *conn,
6171 struct sigma_cmd *cmd)
6172{
6173 const char *val = get_param(cmd, "DiscoveryMode");
6174
6175 if (dut->dev_role != DEVROLE_STA) {
6176 send_resp(dut, conn, SIGMA_INVALID,
6177 "ErrorCode,Invalid DevRole");
6178 return 0;
6179 }
6180
6181 if (val) {
6182 sigma_dut_print(dut, DUT_MSG_DEBUG, "Discovery: %s", val);
6183 /* Ignore Discovery mode till Driver expose API. */
6184#if 0
6185 if (strcasecmp(val, "1") == 0) {
6186 send_resp(dut, conn, SIGMA_INVALID,
6187 "ErrorCode,DiscoveryMode 1 not supported");
6188 return 0;
6189 }
6190
6191 if (strcasecmp(val, "0") == 0) {
6192 /* OK */
6193 } else {
6194 send_resp(dut, conn, SIGMA_INVALID,
6195 "ErrorCode,DiscoveryMode not supported");
6196 return 0;
6197 }
6198#endif
6199 }
6200
6201 if (start_sta_mode(dut) != 0)
Jouni Malinen0e29cf22019-02-19 01:13:21 +02006202 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006203 return sta_set_60g_common(dut, conn, cmd);
6204}
6205
6206
Jouni Malinenf7222712019-06-13 01:50:21 +03006207static enum sigma_cmd_result cmd_sta_disconnect(struct sigma_dut *dut,
6208 struct sigma_conn *conn,
6209 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006210{
6211 const char *intf = get_param(cmd, "Interface");
Jouni Malinened77e672018-01-10 16:45:13 +02006212 const char *val = get_param(cmd, "maintain_profile");
vamsi krishnad605c422017-09-20 14:56:31 +05306213
Jouni Malinened77e672018-01-10 16:45:13 +02006214 if (dut->program == PROGRAM_OCE ||
Amarnath Hullur Subramanyamebeda9e2018-01-31 03:21:48 -08006215 dut->program == PROGRAM_HE ||
Jouni Malinened77e672018-01-10 16:45:13 +02006216 (val && atoi(val) == 1)) {
vamsi krishnad605c422017-09-20 14:56:31 +05306217 wpa_command(intf, "DISCONNECT");
6218 return 1;
6219 }
6220
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006221 disconnect_station(dut);
6222 /* Try to ignore old scan results to avoid HS 2.0R2 test case failures
6223 * due to cached results. */
6224 wpa_command(intf, "SET ignore_old_scan_res 1");
6225 wpa_command(intf, "BSS_FLUSH");
6226 return 1;
6227}
6228
6229
Jouni Malinenf7222712019-06-13 01:50:21 +03006230static enum sigma_cmd_result cmd_sta_reassoc(struct sigma_dut *dut,
6231 struct sigma_conn *conn,
6232 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006233{
6234 const char *intf = get_param(cmd, "Interface");
6235 const char *bssid = get_param(cmd, "bssid");
6236 const char *val = get_param(cmd, "CHANNEL");
6237 struct wpa_ctrl *ctrl;
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05306238 char buf[1000];
Sunil Duttd30ce092018-01-11 23:56:29 +05306239 char result[32];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006240 int res;
6241 int chan = 0;
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006242 enum sigma_cmd_result status = STATUS_SENT;
Sunil Duttd30ce092018-01-11 23:56:29 +05306243 int fastreassoc = 1;
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006244 int ft_ds = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006245
6246 if (bssid == NULL) {
6247 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing bssid "
6248 "argument");
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006249 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006250 }
6251
6252 if (val)
6253 chan = atoi(val);
6254
6255 if (wifi_chip_type != DRIVER_WCN && wifi_chip_type != DRIVER_AR6003) {
6256 /* The current network may be from sta_associate or
6257 * sta_hs2_associate
6258 */
6259 if (set_network(intf, dut->infra_network_id, "bssid", bssid) <
6260 0 ||
6261 set_network(intf, 0, "bssid", bssid) < 0)
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006262 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006263 }
6264
6265 ctrl = open_wpa_mon(intf);
6266 if (ctrl == NULL) {
6267 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
6268 "wpa_supplicant monitor connection");
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006269 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006270 }
6271
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006272 if (get_wpa_status(get_station_ifname(dut), "wpa_state", result,
Sunil Duttd30ce092018-01-11 23:56:29 +05306273 sizeof(result)) < 0 ||
6274 strncmp(result, "COMPLETED", 9) != 0) {
6275 sigma_dut_print(dut, DUT_MSG_DEBUG,
6276 "sta_reassoc: Not connected");
6277 fastreassoc = 0;
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006278 } else if (dut->sta_ft_ds) {
6279 sigma_dut_print(dut, DUT_MSG_DEBUG,
6280 "sta_reassoc: Use FT-over-DS");
6281 ft_ds = 1;
Sunil Duttd30ce092018-01-11 23:56:29 +05306282 }
6283
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05306284 if (dut->rsne_override) {
6285#ifdef NL80211_SUPPORT
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006286 if (get_driver_type(dut) == DRIVER_WCN &&
6287 dut->config_rsnie == 0) {
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05306288 sta_config_rsnie(dut, 1);
6289 dut->config_rsnie = 1;
6290 }
6291#endif /* NL80211_SUPPORT */
6292 snprintf(buf, sizeof(buf), "TEST_ASSOC_IE %s",
6293 dut->rsne_override);
6294 if (wpa_command(intf, buf) < 0) {
6295 send_resp(dut, conn, SIGMA_ERROR,
6296 "ErrorCode,Failed to set DEV_CONFIGURE_IE RSNE override");
6297 return 0;
6298 }
6299 }
6300
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006301 if (ft_ds) {
6302 if (chan) {
6303 unsigned int freq;
6304
6305 freq = channel_to_freq(dut, chan);
6306 if (!freq) {
6307 sigma_dut_print(dut, DUT_MSG_ERROR,
6308 "Invalid channel number provided: %d",
6309 chan);
6310 send_resp(dut, conn, SIGMA_INVALID,
6311 "ErrorCode,Invalid channel number");
6312 goto close_mon_conn;
6313 }
6314 res = snprintf(buf, sizeof(buf),
6315 "SCAN TYPE=ONLY freq=%d", freq);
6316 } else {
6317 res = snprintf(buf, sizeof(buf), "SCAN TYPE=ONLY");
6318 }
6319 if (res < 0 || res >= (int) sizeof(buf)) {
6320 send_resp(dut, conn, SIGMA_ERROR,
6321 "ErrorCode,snprintf failed");
6322 goto close_mon_conn;
6323 }
6324 if (wpa_command(intf, buf) < 0) {
6325 sigma_dut_print(dut, DUT_MSG_INFO,
6326 "Failed to start scan");
6327 send_resp(dut, conn, SIGMA_ERROR,
6328 "ErrorCode,scan failed");
6329 goto close_mon_conn;
6330 }
6331
6332 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
6333 buf, sizeof(buf));
6334 if (res < 0) {
6335 sigma_dut_print(dut, DUT_MSG_INFO,
6336 "Scan did not complete");
6337 send_resp(dut, conn, SIGMA_ERROR,
6338 "ErrorCode,scan did not complete");
6339 goto close_mon_conn;
6340 }
6341
6342 res = snprintf(buf, sizeof(buf), "FT_DS %s", bssid);
6343 if (res > 0 && res < (int) sizeof(buf))
6344 res = wpa_command(intf, buf);
6345
6346 if (res < 0 || res >= (int) sizeof(buf)) {
6347 send_resp(dut, conn, SIGMA_ERROR,
6348 "errorCode,FT_DS command failed");
6349 status = STATUS_SENT_ERROR;
6350 goto close_mon_conn;
6351 }
6352 } else if (wifi_chip_type == DRIVER_WCN && fastreassoc) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006353#ifdef ANDROID
Ashwini Patil4c8158f2017-05-25 12:49:21 +05306354 if (chan) {
6355 unsigned int freq;
6356
Alexei Avshalom Lazar093569f2018-11-13 14:08:17 +02006357 freq = channel_to_freq(dut, chan);
Ashwini Patil4c8158f2017-05-25 12:49:21 +05306358 if (!freq) {
6359 sigma_dut_print(dut, DUT_MSG_ERROR,
6360 "Invalid channel number provided: %d",
6361 chan);
6362 send_resp(dut, conn, SIGMA_INVALID,
6363 "ErrorCode,Invalid channel number");
6364 goto close_mon_conn;
6365 }
6366 res = snprintf(buf, sizeof(buf),
6367 "SCAN TYPE=ONLY freq=%d", freq);
6368 } else {
6369 res = snprintf(buf, sizeof(buf), "SCAN TYPE=ONLY");
6370 }
6371 if (res < 0 || res >= (int) sizeof(buf)) {
6372 send_resp(dut, conn, SIGMA_ERROR,
6373 "ErrorCode,snprintf failed");
6374 goto close_mon_conn;
6375 }
6376 if (wpa_command(intf, buf) < 0) {
6377 sigma_dut_print(dut, DUT_MSG_INFO,
6378 "Failed to start scan");
6379 send_resp(dut, conn, SIGMA_ERROR,
6380 "ErrorCode,scan failed");
6381 goto close_mon_conn;
6382 }
6383
6384 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
6385 buf, sizeof(buf));
6386 if (res < 0) {
6387 sigma_dut_print(dut, DUT_MSG_INFO,
6388 "Scan did not complete");
6389 send_resp(dut, conn, SIGMA_ERROR,
6390 "ErrorCode,scan did not complete");
6391 goto close_mon_conn;
6392 }
6393
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006394 if (set_network(intf, dut->infra_network_id, "bssid", "any")
6395 < 0) {
6396 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
6397 "bssid to any during FASTREASSOC");
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006398 status = ERROR_SEND_STATUS;
Ashwini Patil467efef2017-05-25 12:18:27 +05306399 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006400 }
6401 res = snprintf(buf, sizeof(buf), "DRIVER FASTREASSOC %s %d",
6402 bssid, chan);
6403 if (res > 0 && res < (int) sizeof(buf))
6404 res = wpa_command(intf, buf);
6405
6406 if (res < 0 || res >= (int) sizeof(buf)) {
6407 send_resp(dut, conn, SIGMA_ERROR,
6408 "errorCode,Failed to run DRIVER FASTREASSOC");
Ashwini Patil467efef2017-05-25 12:18:27 +05306409 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006410 }
6411#else /* ANDROID */
6412 sigma_dut_print(dut, DUT_MSG_DEBUG,
6413 "Reassoc using iwpriv - skip chan=%d info",
6414 chan);
6415 snprintf(buf, sizeof(buf), "iwpriv %s reassoc", intf);
6416 if (system(buf) != 0) {
6417 sigma_dut_print(dut, DUT_MSG_ERROR, "%s failed", buf);
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006418 status = ERROR_SEND_STATUS;
Ashwini Patil467efef2017-05-25 12:18:27 +05306419 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006420 }
6421#endif /* ANDROID */
6422 sigma_dut_print(dut, DUT_MSG_INFO,
6423 "sta_reassoc: Run %s successful", buf);
6424 } else if (wpa_command(intf, "REASSOCIATE")) {
6425 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
6426 "request reassociation");
Ashwini Patil467efef2017-05-25 12:18:27 +05306427 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006428 }
6429
6430 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
6431 buf, sizeof(buf));
Ashwini Patil467efef2017-05-25 12:18:27 +05306432 if (res < 0) {
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006433 send_resp(dut, conn, SIGMA_ERROR,
6434 "errorCode,Connection did not complete");
6435 status = STATUS_SENT_ERROR;
Ashwini Patil467efef2017-05-25 12:18:27 +05306436 goto close_mon_conn;
6437 }
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006438 status = SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006439
Ashwini Patil467efef2017-05-25 12:18:27 +05306440close_mon_conn:
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006441 wpa_ctrl_detach(ctrl);
6442 wpa_ctrl_close(ctrl);
Ashwini Patil467efef2017-05-25 12:18:27 +05306443 return status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006444}
6445
6446
6447static void hs2_clear_credentials(const char *intf)
6448{
6449 wpa_command(intf, "REMOVE_CRED all");
6450}
6451
6452
Lior Davidcc88b562017-01-03 18:52:09 +02006453#ifdef __linux__
6454static int wil6210_get_aid(struct sigma_dut *dut, const char *bssid,
6455 unsigned int *aid)
6456{
Lior David0fe101e2017-03-09 16:09:50 +02006457 const char *pattern = "AID[ \t]+([0-9]+)";
Lior Davidcc88b562017-01-03 18:52:09 +02006458
Lior David0fe101e2017-03-09 16:09:50 +02006459 return wil6210_get_sta_info_field(dut, bssid, pattern, aid);
Lior Davidcc88b562017-01-03 18:52:09 +02006460}
6461#endif /* __linux__ */
6462
6463
6464static int sta_get_aid_60g(struct sigma_dut *dut, const char *bssid,
6465 unsigned int *aid)
6466{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006467 switch (get_driver_type(dut)) {
Lior Davidcc88b562017-01-03 18:52:09 +02006468#ifdef __linux__
6469 case DRIVER_WIL6210:
6470 return wil6210_get_aid(dut, bssid, aid);
6471#endif /* __linux__ */
6472 default:
6473 sigma_dut_print(dut, DUT_MSG_ERROR, "get AID not supported");
6474 return -1;
6475 }
6476}
6477
6478
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006479static int sta_get_parameter_60g(struct sigma_dut *dut, struct sigma_conn *conn,
6480 struct sigma_cmd *cmd)
6481{
6482 char buf[MAX_CMD_LEN];
6483 char bss_list[MAX_CMD_LEN];
6484 const char *parameter = get_param(cmd, "Parameter");
6485
6486 if (parameter == NULL)
6487 return -1;
6488
Lior Davidcc88b562017-01-03 18:52:09 +02006489 if (strcasecmp(parameter, "AID") == 0) {
6490 unsigned int aid = 0;
6491 char bssid[20];
6492
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006493 if (get_wpa_status(get_station_ifname(dut), "bssid",
Lior Davidcc88b562017-01-03 18:52:09 +02006494 bssid, sizeof(bssid)) < 0) {
6495 sigma_dut_print(dut, DUT_MSG_ERROR,
6496 "could not get bssid");
6497 return -2;
6498 }
6499
6500 if (sta_get_aid_60g(dut, bssid, &aid))
6501 return -2;
6502
6503 snprintf(buf, sizeof(buf), "aid,%d", aid);
6504 sigma_dut_print(dut, DUT_MSG_INFO, "%s", buf);
6505 send_resp(dut, conn, SIGMA_COMPLETE, buf);
6506 return 0;
6507 }
6508
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006509 if (strcasecmp(parameter, "DiscoveredDevList") == 0) {
6510 char *bss_line;
6511 char *bss_id = NULL;
6512 const char *ifname = get_param(cmd, "Interface");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05306513 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006514
6515 if (ifname == NULL) {
6516 sigma_dut_print(dut, DUT_MSG_INFO,
6517 "For get DiscoveredDevList need Interface name.");
6518 return -1;
6519 }
6520
6521 /*
6522 * Use "BSS RANGE=ALL MASK=0x2" which provides a list
6523 * of BSSIDs in "bssid=<BSSID>\n"
6524 */
6525 if (wpa_command_resp(ifname, "BSS RANGE=ALL MASK=0x2",
6526 bss_list,
6527 sizeof(bss_list)) < 0) {
6528 sigma_dut_print(dut, DUT_MSG_ERROR,
6529 "Failed to get bss list");
6530 return -1;
6531 }
6532
6533 sigma_dut_print(dut, DUT_MSG_DEBUG,
6534 "bss list for ifname:%s is:%s",
6535 ifname, bss_list);
6536
6537 snprintf(buf, sizeof(buf), "DeviceList");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05306538 bss_line = strtok_r(bss_list, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006539 while (bss_line) {
6540 if (sscanf(bss_line, "bssid=%ms", &bss_id) > 0 &&
6541 bss_id) {
6542 int len;
6543
6544 len = snprintf(buf + strlen(buf),
6545 sizeof(buf) - strlen(buf),
6546 ",%s", bss_id);
6547 free(bss_id);
6548 bss_id = NULL;
6549 if (len < 0) {
6550 sigma_dut_print(dut,
6551 DUT_MSG_ERROR,
6552 "Failed to read BSSID");
6553 send_resp(dut, conn, SIGMA_ERROR,
6554 "ErrorCode,Failed to read BSS ID");
6555 return 0;
6556 }
6557
6558 if ((size_t) len >= sizeof(buf) - strlen(buf)) {
6559 sigma_dut_print(dut,
6560 DUT_MSG_ERROR,
6561 "Response buf too small for list");
6562 send_resp(dut, conn,
6563 SIGMA_ERROR,
6564 "ErrorCode,Response buf too small for list");
6565 return 0;
6566 }
6567 }
6568
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05306569 bss_line = strtok_r(NULL, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006570 }
6571
6572 sigma_dut_print(dut, DUT_MSG_INFO, "DiscoveredDevList is %s",
6573 buf);
6574 send_resp(dut, conn, SIGMA_COMPLETE, buf);
6575 return 0;
6576 }
6577
6578 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
6579 return 0;
6580}
6581
6582
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07006583static int sta_get_parameter_he(struct sigma_dut *dut, struct sigma_conn *conn,
6584 struct sigma_cmd *cmd)
6585{
6586 char buf[MAX_CMD_LEN];
6587 const char *parameter = get_param(cmd, "Parameter");
6588
6589 if (!parameter)
6590 return -1;
6591
6592 if (strcasecmp(parameter, "RSSI") == 0) {
6593 char rssi[10];
6594
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006595 if (get_wpa_signal_poll(dut, get_station_ifname(dut), "RSSI",
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07006596 rssi, sizeof(rssi)) < 0) {
6597 sigma_dut_print(dut, DUT_MSG_ERROR,
6598 "Could not get RSSI");
6599 return -2;
6600 }
6601
6602 snprintf(buf, sizeof(buf), "rssi,%s", rssi);
6603 sigma_dut_print(dut, DUT_MSG_INFO, "RSSI %s", buf);
6604 send_resp(dut, conn, SIGMA_COMPLETE, buf);
6605 return 0;
6606 }
6607
6608 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
6609 return 0;
6610}
6611
6612
Jouni Malinenf7222712019-06-13 01:50:21 +03006613static enum sigma_cmd_result cmd_sta_get_parameter(struct sigma_dut *dut,
6614 struct sigma_conn *conn,
6615 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006616{
6617 const char *program = get_param(cmd, "Program");
6618
6619 if (program == NULL)
6620 return -1;
6621
6622 if (strcasecmp(program, "P2PNFC") == 0)
6623 return p2p_cmd_sta_get_parameter(dut, conn, cmd);
6624
6625 if (strcasecmp(program, "60ghz") == 0)
6626 return sta_get_parameter_60g(dut, conn, cmd);
6627
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07006628 if (strcasecmp(program, "he") == 0)
6629 return sta_get_parameter_he(dut, conn, cmd);
6630
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006631#ifdef ANDROID_NAN
6632 if (strcasecmp(program, "NAN") == 0)
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07006633 return nan_cmd_sta_get_parameter(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006634#endif /* ANDROID_NAN */
6635
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07006636#ifdef MIRACAST
6637 if (strcasecmp(program, "WFD") == 0 ||
6638 strcasecmp(program, "DisplayR2") == 0)
6639 return miracast_cmd_sta_get_parameter(dut, conn, cmd);
6640#endif /* MIRACAST */
6641
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006642 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
6643 return 0;
6644}
6645
6646
6647static void sta_reset_default_ath(struct sigma_dut *dut, const char *intf,
6648 const char *type)
6649{
6650 char buf[100];
6651
6652 if (dut->program == PROGRAM_VHT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006653 run_iwpriv(dut, intf, "chwidth 2");
6654 run_iwpriv(dut, intf, "mode 11ACVHT80");
6655 run_iwpriv(dut, intf, "vhtmcs -1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006656 }
6657
6658 if (dut->program == PROGRAM_HT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006659 run_iwpriv(dut, intf, "chwidth 0");
6660 run_iwpriv(dut, intf, "mode 11naht40");
6661 run_iwpriv(dut, intf, "set11NRates 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006662 }
6663
6664 if (dut->program == PROGRAM_VHT || dut->program == PROGRAM_HT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006665 run_iwpriv(dut, intf, "powersave 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006666
6667 /* Reset CTS width */
6668 snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 54 0",
6669 intf);
6670 if (system(buf) != 0) {
6671 sigma_dut_print(dut, DUT_MSG_ERROR,
6672 "wifitool %s beeliner_fw_test 54 0 failed",
6673 intf);
6674 }
6675
6676 /* Enable Dynamic Bandwidth signalling by default */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006677 run_iwpriv(dut, intf, "cwmenable 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006678
6679 snprintf(buf, sizeof(buf), "iwconfig %s rts 2347", intf);
6680 if (system(buf) != 0) {
6681 sigma_dut_print(dut, DUT_MSG_ERROR,
6682 "iwpriv rts failed");
6683 }
6684 }
6685
6686 if (type && strcasecmp(type, "Testbed") == 0) {
6687 dut->testbed_flag_txsp = 1;
6688 dut->testbed_flag_rxsp = 1;
6689 /* STA has to set spatial stream to 2 per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006690 run_iwpriv(dut, intf, "vht_mcsmap 0xfff0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006691
6692 /* Disable LDPC per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006693 run_iwpriv(dut, intf, "ldpc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006694
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006695 run_iwpriv(dut, intf, "amsdu 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006696
6697 /* TODO: Disable STBC 2x1 transmit and receive */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006698 run_iwpriv(dut, intf, "tx_stbc 0");
6699 run_iwpriv(dut, intf, "rx_stbc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006700
6701 /* STA has to disable Short GI per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006702 run_iwpriv(dut, intf, "shortgi 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006703 }
6704
6705 if (type && strcasecmp(type, "DUT") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006706 run_iwpriv(dut, intf, "nss 3");
Arif Hussainac6c5112018-05-25 17:34:00 -07006707 dut->sta_nss = 3;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006708
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006709 run_iwpriv(dut, intf, "shortgi 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006710 }
6711}
6712
6713
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08006714#ifdef NL80211_SUPPORT
6715static int sta_set_he_mcs(struct sigma_dut *dut, const char *intf,
6716 enum he_mcs_config mcs)
6717{
6718 struct nl_msg *msg;
6719 int ret = 0;
6720 struct nlattr *params;
6721 int ifindex;
6722
6723 ifindex = if_nametoindex(intf);
6724 if (ifindex == 0) {
6725 sigma_dut_print(dut, DUT_MSG_ERROR,
6726 "%s: Index for interface %s failed",
6727 __func__, intf);
6728 return -1;
6729 }
6730
6731 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6732 NL80211_CMD_VENDOR)) ||
6733 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6734 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6735 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6736 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6737 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6738 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MCS,
6739 mcs)) {
6740 sigma_dut_print(dut, DUT_MSG_ERROR,
6741 "%s: err in adding vendor_cmd and vendor_data",
6742 __func__);
6743 nlmsg_free(msg);
6744 return -1;
6745 }
6746 nla_nest_end(msg, params);
6747
6748 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6749 if (ret) {
6750 sigma_dut_print(dut, DUT_MSG_ERROR,
6751 "%s: err in send_and_recv_msgs, ret=%d",
6752 __func__, ret);
6753 }
6754 return ret;
6755}
6756#endif /* NL80211_SUPPORT */
6757
6758
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07006759static int sta_set_action_tx_in_he_tb_ppdu(struct sigma_dut *dut,
6760 const char *intf, int enable)
6761{
6762#ifdef NL80211_SUPPORT
6763 struct nl_msg *msg;
6764 int ret = 0;
6765 struct nlattr *params;
6766 int ifindex;
6767
6768 ifindex = if_nametoindex(intf);
6769 if (ifindex == 0) {
6770 sigma_dut_print(dut, DUT_MSG_ERROR,
6771 "%s: Index for interface %s failed",
6772 __func__, intf);
6773 return -1;
6774 }
6775
6776 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6777 NL80211_CMD_VENDOR)) ||
6778 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6779 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6780 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6781 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6782 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6783 nla_put_u8(msg,
6784 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_ACTION_TX_TB_PPDU,
6785 enable)) {
6786 sigma_dut_print(dut, DUT_MSG_ERROR,
6787 "%s: err in adding vendor_cmd and vendor_data",
6788 __func__);
6789 nlmsg_free(msg);
6790 return -1;
6791 }
6792 nla_nest_end(msg, params);
6793
6794 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6795 if (ret) {
6796 sigma_dut_print(dut, DUT_MSG_ERROR,
6797 "%s: err in send_and_recv_msgs, ret=%d",
6798 __func__, ret);
6799 }
6800 return ret;
6801#else /* NL80211_SUPPORT */
6802 sigma_dut_print(dut, DUT_MSG_ERROR,
6803 "HE action Tx TB PPDU cannot be set without NL80211_SUPPORT defined");
6804 return -1;
6805#endif /* NL80211_SUPPORT */
6806}
6807
6808
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08006809static int sta_set_heconfig_and_wep_tkip(struct sigma_dut *dut,
6810 const char *intf, int enable)
6811{
6812#ifdef NL80211_SUPPORT
6813 struct nl_msg *msg;
6814 int ret = 0;
6815 struct nlattr *params;
6816 int ifindex;
6817
6818 ifindex = if_nametoindex(intf);
6819 if (ifindex == 0) {
6820 sigma_dut_print(dut, DUT_MSG_ERROR,
6821 "%s: Index for interface %s failed",
6822 __func__, intf);
6823 return -1;
6824 }
6825
6826 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6827 NL80211_CMD_VENDOR)) ||
6828 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6829 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6830 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6831 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6832 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6833 nla_put_u8(msg,
6834 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WEP_TKIP_IN_HE,
6835 enable)) {
6836 sigma_dut_print(dut, DUT_MSG_ERROR,
6837 "%s: err in adding vendor_cmd and vendor_data",
6838 __func__);
6839 nlmsg_free(msg);
6840 return -1;
6841 }
6842 nla_nest_end(msg, params);
6843
6844 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6845 if (ret) {
6846 sigma_dut_print(dut, DUT_MSG_ERROR,
6847 "%s: err in send_and_recv_msgs, ret=%d",
6848 __func__, ret);
6849 }
6850 return ret;
6851#else /* NL80211_SUPPORT */
6852 sigma_dut_print(dut, DUT_MSG_ERROR,
6853 "HE config enablement cannot be changed without NL80211_SUPPORT defined");
6854 return -1;
6855#endif /* NL80211_SUPPORT */
6856}
6857
6858
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08006859#ifdef NL80211_SUPPORT
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08006860
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08006861static int sta_set_he_testbed_def(struct sigma_dut *dut,
6862 const char *intf, int cfg)
6863{
6864 struct nl_msg *msg;
6865 int ret = 0;
6866 struct nlattr *params;
6867 int ifindex;
6868
6869 ifindex = if_nametoindex(intf);
6870 if (ifindex == 0) {
6871 sigma_dut_print(dut, DUT_MSG_ERROR,
6872 "%s: Index for interface %s failed",
6873 __func__, intf);
6874 return -1;
6875 }
6876
6877 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6878 NL80211_CMD_VENDOR)) ||
6879 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6880 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6881 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6882 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6883 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6884 nla_put_u8(msg,
6885 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_SET_HE_TESTBED_DEFAULTS,
6886 cfg)) {
6887 sigma_dut_print(dut, DUT_MSG_ERROR,
6888 "%s: err in adding vendor_cmd and vendor_data",
6889 __func__);
6890 nlmsg_free(msg);
6891 return -1;
6892 }
6893 nla_nest_end(msg, params);
6894
6895 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6896 if (ret) {
6897 sigma_dut_print(dut, DUT_MSG_ERROR,
6898 "%s: err in send_and_recv_msgs, ret=%d",
6899 __func__, ret);
6900 }
6901 return ret;
6902}
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08006903
6904
6905static int sta_set_2g_vht_supp(struct sigma_dut *dut, const char *intf, int cfg)
6906{
6907 struct nl_msg *msg;
6908 int ret = 0;
6909 struct nlattr *params;
6910 int ifindex;
6911
6912 ifindex = if_nametoindex(intf);
6913 if (ifindex == 0) {
6914 sigma_dut_print(dut, DUT_MSG_ERROR,
6915 "%s: Index for interface %s failed",
6916 __func__, intf);
6917 return -1;
6918 }
6919
6920 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6921 NL80211_CMD_VENDOR)) ||
6922 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6923 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6924 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6925 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6926 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6927 nla_put_u8(msg,
6928 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_2G_VHT,
6929 cfg)) {
6930 sigma_dut_print(dut, DUT_MSG_ERROR,
6931 "%s: err in adding vendor_cmd and vendor_data",
6932 __func__);
6933 nlmsg_free(msg);
6934 return -1;
6935 }
6936 nla_nest_end(msg, params);
6937
6938 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6939 if (ret) {
6940 sigma_dut_print(dut, DUT_MSG_ERROR,
6941 "%s: err in send_and_recv_msgs, ret=%d",
6942 __func__, ret);
6943 }
6944 return ret;
6945}
6946
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08006947#endif /* NL80211_SUPPORT */
6948
6949
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08006950static int sta_set_addba_buf_size(struct sigma_dut *dut,
6951 const char *intf, int bufsize)
6952{
6953#ifdef NL80211_SUPPORT
6954 struct nl_msg *msg;
6955 int ret = 0;
6956 struct nlattr *params;
6957 int ifindex;
6958
6959 ifindex = if_nametoindex(intf);
6960 if (ifindex == 0) {
6961 sigma_dut_print(dut, DUT_MSG_ERROR,
6962 "%s: Index for interface %s failed",
6963 __func__, intf);
6964 return -1;
6965 }
6966
6967 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6968 NL80211_CMD_VENDOR)) ||
6969 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6970 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6971 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6972 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6973 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
Kiran Kumar Lokere26e27582018-08-01 16:18:34 -07006974 nla_put_u16(msg,
6975 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE,
6976 bufsize)) {
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08006977 sigma_dut_print(dut, DUT_MSG_ERROR,
6978 "%s: err in adding vendor_cmd and vendor_data",
6979 __func__);
6980 nlmsg_free(msg);
6981 return -1;
6982 }
6983 nla_nest_end(msg, params);
6984
6985 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6986 if (ret) {
6987 sigma_dut_print(dut, DUT_MSG_ERROR,
6988 "%s: err in send_and_recv_msgs, ret=%d",
6989 __func__, ret);
6990 }
6991 return ret;
6992#else /* NL80211_SUPPORT */
6993 sigma_dut_print(dut, DUT_MSG_ERROR,
6994 "AddBA bufsize cannot be changed without NL80211_SUPPORT defined");
6995 return -1;
6996#endif /* NL80211_SUPPORT */
6997}
6998
6999
Arif Hussain8d5b27b2018-05-14 14:31:03 -07007000static int sta_set_tx_beamformee(struct sigma_dut *dut, const char *intf,
7001 int enable)
7002{
7003#ifdef NL80211_SUPPORT
7004 struct nl_msg *msg;
7005 int ret = 0;
7006 struct nlattr *params;
7007 int ifindex;
7008
7009 ifindex = if_nametoindex(intf);
7010 if (ifindex == 0) {
7011 sigma_dut_print(dut, DUT_MSG_ERROR,
7012 "%s: Index for interface %s failed",
7013 __func__, intf);
7014 return -1;
7015 }
7016
7017 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7018 NL80211_CMD_VENDOR)) ||
7019 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7020 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7021 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7022 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7023 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7024 nla_put_u8(msg,
7025 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_TX_BEAMFORMEE,
7026 enable)) {
7027 sigma_dut_print(dut, DUT_MSG_ERROR,
7028 "%s: err in adding vendor_cmd and vendor_data",
7029 __func__);
7030 nlmsg_free(msg);
7031 return -1;
7032 }
7033 nla_nest_end(msg, params);
7034
7035 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7036 if (ret) {
7037 sigma_dut_print(dut, DUT_MSG_ERROR,
7038 "%s: err in send_and_recv_msgs, ret=%d",
7039 __func__, ret);
7040 }
7041 return ret;
7042#else /* NL80211_SUPPORT */
7043 sigma_dut_print(dut, DUT_MSG_ERROR,
7044 "tx beamformee cannot be changed without NL80211_SUPPORT defined");
7045 return -1;
7046#endif /* NL80211_SUPPORT */
7047}
7048
7049
Arif Hussain9765f7d2018-07-03 08:28:26 -07007050static int sta_set_beamformee_sts(struct sigma_dut *dut, const char *intf,
7051 int val)
7052{
7053#ifdef NL80211_SUPPORT
7054 struct nl_msg *msg;
7055 int ret = 0;
7056 struct nlattr *params;
7057 int ifindex;
7058
7059 ifindex = if_nametoindex(intf);
7060 if (ifindex == 0) {
7061 sigma_dut_print(dut, DUT_MSG_ERROR,
7062 "%s: Index for interface %s failed, val:%d",
7063 __func__, intf, val);
7064 return -1;
7065 }
7066
7067 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7068 NL80211_CMD_VENDOR)) ||
7069 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7070 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7071 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7072 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7073 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7074 nla_put_u8(msg,
7075 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_BEAMFORMEE_NSTS,
7076 val)) {
7077 sigma_dut_print(dut, DUT_MSG_ERROR,
7078 "%s: err in adding vendor_cmd and vendor_data, val: %d",
7079 __func__, val);
7080 nlmsg_free(msg);
7081 return -1;
7082 }
7083 nla_nest_end(msg, params);
7084
7085 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7086 if (ret) {
7087 sigma_dut_print(dut, DUT_MSG_ERROR,
7088 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
7089 __func__, ret, val);
7090 }
7091 return ret;
7092#else /* NL80211_SUPPORT */
7093 sigma_dut_print(dut, DUT_MSG_ERROR,
7094 "beamformee sts cannot be changed without NL80211_SUPPORT defined");
7095 return -1;
7096#endif /* NL80211_SUPPORT */
7097}
7098
7099
Arif Hussain68d23f52018-07-11 13:39:08 -07007100#ifdef NL80211_SUPPORT
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07007101static int sta_set_mac_padding_duration(struct sigma_dut *dut, const char *intf,
7102 enum qca_wlan_he_mac_padding_dur val)
7103{
Arif Hussain68d23f52018-07-11 13:39:08 -07007104 struct nl_msg *msg;
7105 int ret = 0;
7106 struct nlattr *params;
7107 int ifindex;
7108
7109 ifindex = if_nametoindex(intf);
7110 if (ifindex == 0) {
7111 sigma_dut_print(dut, DUT_MSG_ERROR,
7112 "%s: Index for interface %s failed, val:%d",
7113 __func__, intf, val);
7114 return -1;
7115 }
7116
7117 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7118 NL80211_CMD_VENDOR)) ||
7119 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7120 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7121 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7122 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7123 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7124 nla_put_u8(msg,
7125 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MAC_PADDING_DUR,
7126 val)) {
7127 sigma_dut_print(dut, DUT_MSG_ERROR,
7128 "%s: err in adding vendor_cmd and vendor_data, val: %d",
7129 __func__, val);
7130 nlmsg_free(msg);
7131 return -1;
7132 }
7133 nla_nest_end(msg, params);
7134
7135 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7136 if (ret) {
7137 sigma_dut_print(dut, DUT_MSG_ERROR,
7138 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
7139 __func__, ret, val);
7140 }
7141 return ret;
Arif Hussain68d23f52018-07-11 13:39:08 -07007142}
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07007143#endif /* NL80211_SUPPORT */
Arif Hussain68d23f52018-07-11 13:39:08 -07007144
7145
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07007146static int sta_set_tx_su_ppdu_cfg(struct sigma_dut *dut, const char *intf,
7147 int val)
7148{
7149#ifdef NL80211_SUPPORT
7150 struct nl_msg *msg;
7151 int ret = 0;
7152 struct nlattr *params;
7153 int ifindex;
7154
7155 ifindex = if_nametoindex(intf);
7156 if (ifindex == 0) {
7157 sigma_dut_print(dut, DUT_MSG_ERROR,
7158 "%s: Index for interface %s failed, val:%d",
7159 __func__, intf, val);
7160 return -1;
7161 }
7162
7163 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7164 NL80211_CMD_VENDOR)) ||
7165 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7166 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7167 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7168 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7169 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7170 nla_put_u8(msg,
7171 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_SUPPDU,
7172 val)) {
7173 sigma_dut_print(dut, DUT_MSG_ERROR,
7174 "%s: err in adding vendor_cmd and vendor_data, val: %d",
7175 __func__, val);
7176 nlmsg_free(msg);
7177 return -1;
7178 }
7179 nla_nest_end(msg, params);
7180
7181 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7182 if (ret) {
7183 sigma_dut_print(dut, DUT_MSG_ERROR,
7184 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
7185 __func__, ret, val);
7186 }
7187 return ret;
7188#else /* NL80211_SUPPORT */
7189 sigma_dut_print(dut, DUT_MSG_ERROR,
7190 "Tx SU PPDU cannot be set without NL80211_SUPPORT defined");
7191 return -1;
7192#endif /* NL80211_SUPPORT */
7193}
7194
7195
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07007196#ifdef NL80211_SUPPORT
7197static int sta_set_he_om_ctrl_reset(struct sigma_dut *dut, const char *intf)
7198{
7199 struct nl_msg *msg;
7200 int ret = 0;
7201 struct nlattr *params;
7202 int ifindex;
7203
7204 ifindex = if_nametoindex(intf);
7205 if (ifindex == 0) {
7206 sigma_dut_print(dut, DUT_MSG_ERROR,
7207 "%s: Index for interface %s failed",
7208 __func__, intf);
7209 return -1;
7210 }
7211
7212 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7213 NL80211_CMD_VENDOR)) ||
7214 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7215 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7216 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7217 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7218 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7219 nla_put_flag(msg,
7220 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_CLEAR_HE_OM_CTRL_CONFIG)) {
7221 sigma_dut_print(dut, DUT_MSG_ERROR,
7222 "%s: err in adding vendor_cmd and vendor_data",
7223 __func__);
7224 nlmsg_free(msg);
7225 return -1;
7226 }
7227 nla_nest_end(msg, params);
7228
7229 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7230 if (ret) {
7231 sigma_dut_print(dut, DUT_MSG_ERROR,
7232 "%s: err in send_and_recv_msgs, ret=%d",
7233 __func__, ret);
7234 }
7235 return ret;
7236}
7237#endif /* NL80211_SUPPORT */
7238
7239
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07007240static int sta_set_mu_edca_override(struct sigma_dut *dut, const char *intf,
7241 int val)
7242{
7243#ifdef NL80211_SUPPORT
7244 struct nl_msg *msg;
7245 int ret = 0;
7246 struct nlattr *params;
7247 int ifindex;
7248
7249 ifindex = if_nametoindex(intf);
7250 if (ifindex == 0) {
7251 sigma_dut_print(dut, DUT_MSG_ERROR,
7252 "%s: Index for interface %s failed, val:%d",
7253 __func__, intf, val);
7254 return -1;
7255 }
7256
7257 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7258 NL80211_CMD_VENDOR)) ||
7259 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7260 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7261 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7262 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7263 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7264 nla_put_u8(msg,
7265 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_OVERRIDE_MU_EDCA,
7266 val)) {
7267 sigma_dut_print(dut, DUT_MSG_ERROR,
7268 "%s: err in adding vendor_cmd and vendor_data, val: %d",
7269 __func__, val);
7270 nlmsg_free(msg);
7271 return -1;
7272 }
7273 nla_nest_end(msg, params);
7274
7275 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7276 if (ret) {
7277 sigma_dut_print(dut, DUT_MSG_ERROR,
7278 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
7279 __func__, ret, val);
7280 }
7281 return ret;
7282#else /* NL80211_SUPPORT */
7283 sigma_dut_print(dut, DUT_MSG_ERROR,
7284 "MU EDCA override cannot be changed without NL80211_SUPPORT defined");
7285 return -1;
7286#endif /* NL80211_SUPPORT */
7287}
7288
7289
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07007290static int sta_set_om_ctrl_supp(struct sigma_dut *dut, const char *intf,
7291 int val)
7292{
7293#ifdef NL80211_SUPPORT
7294 struct nl_msg *msg;
7295 int ret = 0;
7296 struct nlattr *params;
7297 int ifindex;
7298
7299 ifindex = if_nametoindex(intf);
7300 if (ifindex == 0) {
7301 sigma_dut_print(dut, DUT_MSG_ERROR,
7302 "%s: Index for interface %s failed, val:%d",
7303 __func__, intf, val);
7304 return -1;
7305 }
7306
7307 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7308 NL80211_CMD_VENDOR)) ||
7309 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7310 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7311 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7312 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7313 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7314 nla_put_u8(msg,
7315 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OM_CTRL_SUPP,
7316 val)) {
7317 sigma_dut_print(dut, DUT_MSG_ERROR,
7318 "%s: err in adding vendor_cmd and vendor_data, val: %d",
7319 __func__, val);
7320 nlmsg_free(msg);
7321 return -1;
7322 }
7323 nla_nest_end(msg, params);
7324
7325 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7326 if (ret) {
7327 sigma_dut_print(dut, DUT_MSG_ERROR,
7328 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
7329 __func__, ret, val);
7330 }
7331 return ret;
7332#else /* NL80211_SUPPORT */
7333 sigma_dut_print(dut, DUT_MSG_ERROR,
7334 "HE OM ctrl cannot be changed without NL80211_SUPPORT defined");
7335 return -1;
7336#endif /* NL80211_SUPPORT */
7337}
7338
7339
Arif Hussain480d5f42019-03-12 14:40:42 -07007340static int sta_set_twt_req_support(struct sigma_dut *dut, const char *intf,
7341 int val)
7342{
7343#ifdef NL80211_SUPPORT
7344 struct nl_msg *msg;
7345 int ret;
7346 struct nlattr *params;
7347 int ifindex;
7348
7349 ifindex = if_nametoindex(intf);
7350 if (ifindex == 0) {
7351 sigma_dut_print(dut, DUT_MSG_ERROR,
7352 "%s: Index for interface %s failed, val:%d",
7353 __func__, intf, val);
7354 return -1;
7355 }
7356
7357 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7358 NL80211_CMD_VENDOR)) ||
7359 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7360 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7361 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7362 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7363 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7364 nla_put_u8(msg,
7365 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TWT_REQ_SUPPORT,
7366 val)) {
7367 sigma_dut_print(dut, DUT_MSG_ERROR,
7368 "%s: err in adding vendor_cmd and vendor_data, val: %d",
7369 __func__, val);
7370 nlmsg_free(msg);
7371 return -1;
7372 }
7373 nla_nest_end(msg, params);
7374
7375 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7376 if (ret) {
7377 sigma_dut_print(dut, DUT_MSG_ERROR,
7378 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
7379 __func__, ret, val);
7380 }
7381 return ret;
7382#else /* NL80211_SUPPORT */
7383 sigma_dut_print(dut, DUT_MSG_ERROR,
7384 "TWT Request cannot be changed without NL80211_SUPPORT defined");
7385 return -1;
7386#endif /* NL80211_SUPPORT */
7387}
7388
7389
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08007390static void sta_reset_default_wcn(struct sigma_dut *dut, const char *intf,
7391 const char *type)
7392{
7393 char buf[60];
7394
7395 if (dut->program == PROGRAM_HE) {
7396 /* resetting phymode to auto in case of HE program */
7397 snprintf(buf, sizeof(buf), "iwpriv %s setphymode 0", intf);
7398 if (system(buf) != 0) {
7399 sigma_dut_print(dut, DUT_MSG_ERROR,
7400 "iwpriv %s setphymode failed", intf);
7401 }
7402
Amarnath Hullur Subramanyam9cecb502018-04-25 13:26:30 -07007403 /* reset the rate to Auto rate */
7404 snprintf(buf, sizeof(buf), "iwpriv %s set_11ax_rate 0xff",
7405 intf);
7406 if (system(buf) != 0) {
7407 sigma_dut_print(dut, DUT_MSG_ERROR,
7408 "iwpriv %s set_11ax_rate 0xff failed",
7409 intf);
7410 }
7411
Kiran Kumar Lokere86cfe3a2018-06-01 11:55:15 -07007412 /* reset the LDPC setting */
7413 snprintf(buf, sizeof(buf), "iwpriv %s ldpc 1", intf);
7414 if (system(buf) != 0) {
7415 sigma_dut_print(dut, DUT_MSG_ERROR,
7416 "iwpriv %s ldpc 1 failed", intf);
7417 }
7418
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08007419 /* reset the power save setting */
7420 snprintf(buf, sizeof(buf), "iwpriv %s setPower 2", intf);
7421 if (system(buf) != 0) {
7422 sigma_dut_print(dut, DUT_MSG_ERROR,
7423 "iwpriv %s setPower 2 failed", intf);
7424 }
7425
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08007426 /* remove all network profiles */
7427 remove_wpa_networks(intf);
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08007428
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08007429 /* Configure ADDBA Req/Rsp buffer size to be 64 */
7430 sta_set_addba_buf_size(dut, intf, 64);
7431
Amarnath Hullur Subramanyam5f32d572018-03-02 00:02:33 -08007432#ifdef NL80211_SUPPORT
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08007433 /* Reset the device HE capabilities to its default supported
7434 * configuration. */
7435 sta_set_he_testbed_def(dut, intf, 0);
7436
Amarnath Hullur Subramanyam5f32d572018-03-02 00:02:33 -08007437 /* Disable noackpolicy for all AC */
7438 if (nlvendor_sta_set_noack(dut, intf, 0, QCA_WLAN_AC_ALL)) {
7439 sigma_dut_print(dut, DUT_MSG_ERROR,
7440 "Disable of noackpolicy for all AC failed");
7441 }
7442#endif /* NL80211_SUPPORT */
7443
Amarnath Hullur Subramanyamb1724a52018-03-07 14:31:46 -08007444 /* Enable WMM by default */
7445 if (wcn_sta_set_wmm(dut, intf, "on")) {
7446 sigma_dut_print(dut, DUT_MSG_ERROR,
7447 "Enable of WMM in sta_reset_default_wcn failed");
7448 }
7449
7450 /* Disable ADDBA_REJECT by default */
7451 if (nlvendor_sta_set_addba_reject(dut, intf, 0)) {
7452 sigma_dut_print(dut, DUT_MSG_ERROR,
7453 "Disable of addba_reject in sta_reset_default_wcn failed");
7454 }
7455
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08007456 /* Enable sending of ADDBA by default */
7457 if (nlvendor_config_send_addba(dut, intf, 1)) {
7458 sigma_dut_print(dut, DUT_MSG_ERROR,
7459 "Enable sending of ADDBA in sta_reset_default_wcn failed");
7460 }
7461
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08007462 /* Enable AMPDU by default */
7463 iwpriv_sta_set_ampdu(dut, intf, 1);
7464
Subhani Shaik8e7a3052018-04-24 14:03:00 -07007465#ifdef NL80211_SUPPORT
7466 if (sta_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_AUTO)) {
7467 sigma_dut_print(dut, DUT_MSG_ERROR,
7468 "Set LTF config to default in sta_reset_default_wcn failed");
7469 }
Arif Hussain9765f7d2018-07-03 08:28:26 -07007470
Kiran Kumar Lokerebad51122018-12-12 19:03:36 -08007471 /* set the beamformee NSTS(maximum number of
7472 * space-time streams) to default DUT config
7473 */
7474 if (sta_set_beamformee_sts(dut, intf, 7)) {
Arif Hussain9765f7d2018-07-03 08:28:26 -07007475 sigma_dut_print(dut, DUT_MSG_ERROR,
7476 "Failed to set BeamformeeSTS");
7477 }
Arif Hussain68d23f52018-07-11 13:39:08 -07007478
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07007479 if (sta_set_mac_padding_duration(
7480 dut, intf,
7481 QCA_WLAN_HE_NO_ADDITIONAL_PROCESS_TIME)) {
Arif Hussain68d23f52018-07-11 13:39:08 -07007482 sigma_dut_print(dut, DUT_MSG_ERROR,
7483 "Failed to set MAC padding duration");
7484 }
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07007485
7486 if (sta_set_mu_edca_override(dut, intf, 0)) {
7487 sigma_dut_print(dut, DUT_MSG_ERROR,
7488 "ErrorCode,Failed to set MU EDCA override disable");
7489 }
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07007490
7491 if (sta_set_om_ctrl_supp(dut, intf, 1)) {
7492 sigma_dut_print(dut, DUT_MSG_ERROR,
7493 "Failed to set OM ctrl supp");
7494 }
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07007495
7496 if (sta_set_tx_su_ppdu_cfg(dut, intf, 1)) {
7497 sigma_dut_print(dut, DUT_MSG_ERROR,
7498 "Failed to set Tx SU PPDU enable");
7499 }
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07007500
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07007501 if (sta_set_action_tx_in_he_tb_ppdu(dut, intf, 0)) {
7502 sigma_dut_print(dut, DUT_MSG_ERROR,
7503 "failed to send TB PPDU Tx cfg");
7504 }
7505
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07007506 if (sta_set_he_om_ctrl_reset(dut, intf)) {
7507 sigma_dut_print(dut, DUT_MSG_ERROR,
7508 "Failed to set OM ctrl reset");
7509 }
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08007510
7511 /* +HTC-HE support default on */
7512 if (sta_set_he_htc_supp(dut, intf, 1)) {
7513 sigma_dut_print(dut, DUT_MSG_ERROR,
7514 "Setting of +HTC-HE support failed");
7515 }
Subhani Shaik8e7a3052018-04-24 14:03:00 -07007516#endif /* NL80211_SUPPORT */
7517
Arif Hussain8d5b27b2018-05-14 14:31:03 -07007518 if (sta_set_tx_beamformee(dut, intf, 1)) {
7519 sigma_dut_print(dut, DUT_MSG_ERROR,
7520 "Set tx beamformee enable by default in sta_reset_default_wcn failed");
7521 }
7522
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08007523 /* Set nss to 1 and MCS 0-7 in case of testbed */
7524 if (type && strcasecmp(type, "Testbed") == 0) {
7525#ifdef NL80211_SUPPORT
7526 int ret;
7527#endif /* NL80211_SUPPORT */
7528
7529 snprintf(buf, sizeof(buf), "iwpriv %s nss 1", intf);
7530 if (system(buf) != 0) {
7531 sigma_dut_print(dut, DUT_MSG_ERROR,
7532 "iwpriv %s nss failed", intf);
7533 }
7534
7535#ifdef NL80211_SUPPORT
7536 ret = sta_set_he_mcs(dut, intf, HE_80_MCS0_7);
7537 if (ret) {
7538 sigma_dut_print(dut, DUT_MSG_ERROR,
7539 "Setting of MCS failed, ret:%d",
7540 ret);
7541 }
7542#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyamc67621d2018-02-04 23:18:01 -08007543
7544 /* Disable STBC as default */
7545 wcn_sta_set_stbc(dut, intf, "0");
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08007546
7547 /* Disable AMSDU as default */
7548 iwpriv_sta_set_amsdu(dut, intf, "0");
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08007549
7550#ifdef NL80211_SUPPORT
7551 /* HE fragmentation default off */
7552 if (sta_set_he_fragmentation(dut, intf,
7553 HE_FRAG_DISABLE)) {
7554 sigma_dut_print(dut, DUT_MSG_ERROR,
7555 "Setting of HE fragmentation failed");
7556 }
Kiran Kumar Lokerebad51122018-12-12 19:03:36 -08007557
7558 /* set the beamformee NSTS(maximum number of
7559 * space-time streams) to default testbed config
7560 */
7561 if (sta_set_beamformee_sts(dut, intf, 3)) {
7562 sigma_dut_print(dut, DUT_MSG_ERROR,
7563 "Failed to set BeamformeeSTS");
7564 }
7565
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08007566 /* +HTC-HE support default off */
7567 if (sta_set_he_htc_supp(dut, intf, 0)) {
7568 sigma_dut_print(dut, DUT_MSG_ERROR,
7569 "Setting of +HTC-HE support failed");
7570 }
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08007571
7572 /* Set device HE capabilities to testbed default
7573 * configuration. */
7574 if (sta_set_he_testbed_def(dut, intf, 1)) {
7575 sigma_dut_print(dut, DUT_MSG_DEBUG,
7576 "Failed to set HE defaults");
7577 }
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08007578
7579 /* Disable VHT support in 2.4 GHz for testbed */
7580 sta_set_2g_vht_supp(dut, intf, 0);
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08007581#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08007582
7583 /* Enable WEP/TKIP with HE capability in testbed */
7584 if (sta_set_heconfig_and_wep_tkip(dut, intf, 1)) {
7585 sigma_dut_print(dut, DUT_MSG_ERROR,
7586 "Enabling HE config with WEP/TKIP failed");
7587 }
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08007588 }
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08007589
7590 /* Defaults in case of DUT */
7591 if (type && strcasecmp(type, "DUT") == 0) {
Arif Hussaind48fcc72018-05-01 18:34:18 -07007592 /* Enable STBC by default */
7593 wcn_sta_set_stbc(dut, intf, "1");
7594
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08007595 /* set nss to 2 */
7596 snprintf(buf, sizeof(buf), "iwpriv %s nss 2", intf);
7597 if (system(buf) != 0) {
7598 sigma_dut_print(dut, DUT_MSG_ERROR,
7599 "iwpriv %s nss 2 failed", intf);
7600 }
Arif Hussainac6c5112018-05-25 17:34:00 -07007601 dut->sta_nss = 2;
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08007602
7603#ifdef NL80211_SUPPORT
Arif Hussainae239842018-05-01 18:20:05 -07007604 /* Set HE_MCS to 0-11 */
7605 if (sta_set_he_mcs(dut, intf, HE_80_MCS0_11)) {
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08007606 sigma_dut_print(dut, DUT_MSG_ERROR,
7607 "Setting of MCS failed");
7608 }
7609#endif /* NL80211_SUPPORT */
7610
7611 /* Disable WEP/TKIP with HE capability in DUT */
7612 if (sta_set_heconfig_and_wep_tkip(dut, intf, 0)) {
7613 sigma_dut_print(dut, DUT_MSG_ERROR,
7614 "Enabling HE config with WEP/TKIP failed");
7615 }
7616 }
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08007617 }
7618}
7619
7620
Jouni Malinenf7222712019-06-13 01:50:21 +03007621static enum sigma_cmd_result cmd_sta_reset_default(struct sigma_dut *dut,
7622 struct sigma_conn *conn,
7623 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007624{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007625 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007626 const char *band = get_param(cmd, "band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007627 const char *type;
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07007628 const char *program = get_param(cmd, "program");
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05307629 const char *dev_role = get_param(cmd, "DevRole");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007630
Jouni Malinenb21f0542019-11-04 17:53:38 +02007631 if (dut->station_ifname_2g &&
7632 strcmp(dut->station_ifname_2g, intf) == 0)
7633 dut->use_5g = 0;
7634 else if (dut->station_ifname_5g &&
7635 strcmp(dut->station_ifname_5g, intf) == 0)
7636 dut->use_5g = 1;
7637
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07007638 if (!program)
7639 program = get_param(cmd, "prog");
7640 dut->program = sigma_program_to_enum(program);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007641 dut->device_type = STA_unknown;
7642 type = get_param(cmd, "type");
7643 if (type && strcasecmp(type, "Testbed") == 0)
7644 dut->device_type = STA_testbed;
7645 if (type && strcasecmp(type, "DUT") == 0)
7646 dut->device_type = STA_dut;
7647
7648 if (dut->program == PROGRAM_TDLS) {
7649 /* Clear TDLS testing mode */
7650 wpa_command(intf, "SET tdls_disabled 0");
7651 wpa_command(intf, "SET tdls_testing 0");
7652 dut->no_tpk_expiration = 0;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007653 if (get_driver_type(dut) == DRIVER_WCN) {
Pradeep Reddy POTTETI8ce2a232016-10-28 12:17:32 +05307654 /* Enable the WCN driver in TDLS Explicit trigger mode
7655 */
7656 wpa_command(intf, "SET tdls_external_control 0");
7657 wpa_command(intf, "SET tdls_trigger_control 0");
7658 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007659 }
7660
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07007661#ifdef MIRACAST
7662 if (dut->program == PROGRAM_WFD ||
7663 dut->program == PROGRAM_DISPLAYR2)
7664 miracast_sta_reset_default(dut, conn, cmd);
7665#endif /* MIRACAST */
7666
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007667 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007668 case DRIVER_ATHEROS:
7669 sta_reset_default_ath(dut, intf, type);
7670 break;
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08007671 case DRIVER_WCN:
7672 sta_reset_default_wcn(dut, intf, type);
7673 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007674 default:
7675 break;
7676 }
7677
7678#ifdef ANDROID_NAN
7679 if (dut->program == PROGRAM_NAN)
7680 nan_cmd_sta_reset_default(dut, conn, cmd);
7681#endif /* ANDROID_NAN */
7682
Vinay Gannevaram3b9fdd32019-06-14 17:55:44 +05307683 if (dut->program == PROGRAM_LOC &&
7684 lowi_cmd_sta_reset_default(dut, conn, cmd) < 0)
7685 return ERROR_SEND_STATUS;
7686
Jouni Malinenba630452018-06-22 11:49:59 +03007687 if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007688 unlink("SP/wi-fi.org/pps.xml");
7689 if (system("rm -r SP/*") != 0) {
7690 }
7691 unlink("next-client-cert.pem");
7692 unlink("next-client-key.pem");
7693 }
7694
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007695 /* For WPS program of the 60 GHz band the band type needs to be saved */
7696 if (dut->program == PROGRAM_WPS) {
7697 if (band && strcasecmp(band, "60GHz") == 0) {
7698 dut->band = WPS_BAND_60G;
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02007699 /* For 60 GHz enable WPS for WPS TCs */
7700 dut->wps_disable = 0;
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007701 } else {
7702 dut->band = WPS_BAND_NON_60G;
7703 }
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02007704 } else if (dut->program == PROGRAM_60GHZ) {
7705 /* For 60 GHz MAC/PHY TCs WPS must be disabled */
7706 dut->wps_disable = 1;
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007707 }
7708
Alexei Avshalom Lazar157ba062018-12-23 16:15:26 +02007709 if (is_60g_sigma_dut(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007710 const char *dev_role = get_param(cmd, "DevRole");
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02007711 char buf[256];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007712
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02007713 sigma_dut_print(dut, DUT_MSG_INFO,
7714 "WPS 60 GHz program, wps_disable = %d",
7715 dut->wps_disable);
7716
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007717 if (!dev_role) {
7718 send_resp(dut, conn, SIGMA_ERROR,
7719 "errorCode,Missing DevRole argument");
7720 return 0;
7721 }
7722
7723 if (strcasecmp(dev_role, "STA") == 0)
7724 dut->dev_role = DEVROLE_STA;
7725 else if (strcasecmp(dev_role, "PCP") == 0)
7726 dut->dev_role = DEVROLE_PCP;
7727 else {
7728 send_resp(dut, conn, SIGMA_ERROR,
7729 "errorCode,Unknown DevRole");
7730 return 0;
7731 }
7732
7733 if (dut->device_type == STA_unknown) {
7734 sigma_dut_print(dut, DUT_MSG_ERROR,
7735 "Device type is not STA testbed or DUT");
7736 send_resp(dut, conn, SIGMA_ERROR,
7737 "errorCode,Unknown device type");
7738 return 0;
7739 }
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02007740
7741 sigma_dut_print(dut, DUT_MSG_DEBUG,
7742 "Setting msdu_size to MAX: 7912");
7743 snprintf(buf, sizeof(buf), "ifconfig %s mtu 7912",
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007744 get_station_ifname(dut));
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02007745
7746 if (system(buf) != 0) {
7747 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
7748 buf);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007749 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02007750 }
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02007751
7752 if (sta_set_force_mcs(dut, 0, 1)) {
7753 sigma_dut_print(dut, DUT_MSG_ERROR,
7754 "Failed to reset force MCS");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007755 return ERROR_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02007756 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007757 }
7758
7759 wpa_command(intf, "WPS_ER_STOP");
7760 wpa_command(intf, "FLUSH");
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05307761 wpa_command(intf, "ERP_FLUSH");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007762 wpa_command(intf, "SET radio_disabled 0");
7763
Alexei Avshalom Lazar744ae8a2019-01-31 17:26:46 +02007764 dut->wps_forced_version = 0;
7765
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007766 if (dut->wsc_fragment) {
7767 dut->wsc_fragment = 0;
7768 wpa_command(intf, "SET device_name Test client");
7769 wpa_command(intf, "SET manufacturer ");
7770 wpa_command(intf, "SET model_name ");
7771 wpa_command(intf, "SET model_number ");
7772 wpa_command(intf, "SET serial_number ");
7773 }
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02007774 if (is_60g_sigma_dut(dut) && dut->force_rsn_ie) {
7775 dut->force_rsn_ie = FORCE_RSN_IE_NONE;
7776 sta_60g_force_rsn_ie(dut, FORCE_RSN_IE_NONE);
7777 }
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007778
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007779 if (dut->tmp_mac_addr && dut->set_macaddr) {
7780 dut->tmp_mac_addr = 0;
7781 if (system(dut->set_macaddr) != 0) {
7782 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to clear "
7783 "temporary MAC address");
7784 }
7785 }
7786
7787 set_ps(intf, dut, 0);
7788
Jouni Malinenba630452018-06-22 11:49:59 +03007789 if (dut->program == PROGRAM_HS2 || dut->program == PROGRAM_HS2_R2 ||
7790 dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007791 wpa_command(intf, "SET interworking 1");
7792 wpa_command(intf, "SET hs20 1");
7793 }
7794
Deepak Dhamdhere0fe0e452017-12-18 14:52:09 -08007795 if (dut->program == PROGRAM_HS2_R2 ||
Jouni Malinenba630452018-06-22 11:49:59 +03007796 dut->program == PROGRAM_HS2_R3 ||
Deepak Dhamdhere0fe0e452017-12-18 14:52:09 -08007797 dut->program == PROGRAM_OCE) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007798 wpa_command(intf, "SET pmf 1");
7799 } else {
7800 wpa_command(intf, "SET pmf 0");
7801 }
7802
7803 hs2_clear_credentials(intf);
7804 wpa_command(intf, "SET hessid 00:00:00:00:00:00");
7805 wpa_command(intf, "SET access_network_type 15");
7806
7807 static_ip_file(0, NULL, NULL, NULL);
7808 kill_dhcp_client(dut, intf);
7809 clear_ip_addr(dut, intf);
7810
7811 dut->er_oper_performed = 0;
7812 dut->er_oper_bssid[0] = '\0';
7813
priyadharshini gowthamanad6cbba2016-10-04 10:39:58 -07007814 if (dut->program == PROGRAM_LOC) {
7815 /* Disable Interworking by default */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007816 wpa_command(get_station_ifname(dut), "SET interworking 0");
priyadharshini gowthamanad6cbba2016-10-04 10:39:58 -07007817 }
7818
Ashwini Patil00402582017-04-13 12:29:39 +05307819 if (dut->program == PROGRAM_MBO) {
7820 free(dut->non_pref_ch_list);
7821 dut->non_pref_ch_list = NULL;
Ashwini Patil5acd7382017-04-13 15:55:04 +05307822 free(dut->btm_query_cand_list);
7823 dut->btm_query_cand_list = NULL;
Ashwini Patilc63161e2017-04-13 16:30:23 +05307824 wpa_command(intf, "SET reject_btm_req_reason 0");
Ashwini Patila75de5a2017-04-13 16:35:05 +05307825 wpa_command(intf, "SET ignore_assoc_disallow 0");
Ashwini Patild174f2c2017-04-13 16:49:46 +05307826 wpa_command(intf, "SET gas_address3 0");
Ashwini Patil9183fdb2017-04-13 16:58:25 +05307827 wpa_command(intf, "SET roaming 1");
Ankita Bajaj1d974552018-09-18 16:56:44 +05307828 wpa_command(intf, "SET interworking 1");
Ashwini Patil00402582017-04-13 12:29:39 +05307829 }
7830
Jouni Malinen3c367e82017-06-23 17:01:47 +03007831 free(dut->rsne_override);
7832 dut->rsne_override = NULL;
7833
Jouni Malinen68143132017-09-02 02:34:08 +03007834 free(dut->sae_commit_override);
7835 dut->sae_commit_override = NULL;
Jouni Malinen4b3769d2019-10-10 16:20:29 +03007836 wpa_command(intf, "SET sae_pmkid_in_assoc 0");
Jouni Malinen11e55212019-11-22 21:46:59 +02007837 dut->sae_pwe = SAE_PWE_DEFAULT;
Jouni Malinen68143132017-09-02 02:34:08 +03007838
Jouni Malinen134fe3c2019-06-12 04:16:49 +03007839 dut->sta_associate_wait_connect = 0;
7840 dut->server_cert_hash[0] = '\0';
Jouni Malinen37d5c692019-08-19 16:56:55 +03007841 dut->server_cert_tod = 0;
Jouni Malinen134fe3c2019-06-12 04:16:49 +03007842 dut->sta_tod_policy = 0;
7843
Jouni Malinend86e5822017-08-29 03:55:32 +03007844 dut->dpp_conf_id = -1;
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02007845 free(dut->dpp_peer_uri);
7846 dut->dpp_peer_uri = NULL;
Jouni Malinen63d50412017-11-24 11:55:38 +02007847 dut->dpp_local_bootstrap = -1;
Jouni Malinen5011fb52017-12-05 21:00:15 +02007848 wpa_command(intf, "SET dpp_config_processing 2");
Jouni Malinend86e5822017-08-29 03:55:32 +03007849
Jouni Malinenfac9cad2017-10-10 18:35:55 +03007850 wpa_command(intf, "VENDOR_ELEM_REMOVE 13 *");
7851
vamsi krishnaa2799492017-12-05 14:28:01 +05307852 if (dut->program == PROGRAM_OCE) {
Ankita Bajaja2cb5672017-10-25 16:08:28 +05307853 wpa_command(intf, "SET oce 1");
vamsi krishnaa2799492017-12-05 14:28:01 +05307854 wpa_command(intf, "SET disable_fils 0");
Ankita Bajaj1bde7942018-01-09 19:15:01 +05307855 wpa_command(intf, "FILS_HLP_REQ_FLUSH");
7856 dut->fils_hlp = 0;
7857#ifdef ANDROID
7858 hlp_thread_cleanup(dut);
7859#endif /* ANDROID */
vamsi krishnaa2799492017-12-05 14:28:01 +05307860 }
Ankita Bajaja2cb5672017-10-25 16:08:28 +05307861
Jouni Malinen8179fee2019-03-28 03:19:47 +02007862 dut->akm_values = 0;
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007863 dut->sta_ft_ds = 0;
Jouni Malinen8179fee2019-03-28 03:19:47 +02007864
Sunil Dutt076081f2018-02-05 19:45:50 +05307865#ifdef NL80211_SUPPORT
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007866 if (get_driver_type(dut) == DRIVER_WCN &&
Sunil Dutt44595082018-02-12 19:41:45 +05307867 dut->config_rsnie == 1) {
7868 dut->config_rsnie = 0;
7869 sta_config_rsnie(dut, 0);
Sunil Dutt076081f2018-02-05 19:45:50 +05307870 }
7871#endif /* NL80211_SUPPORT */
7872
Sunil Duttfebf8a82018-02-09 18:50:13 +05307873 if (dev_role && strcasecmp(dev_role, "STA-CFON") == 0) {
7874 dut->dev_role = DEVROLE_STA_CFON;
7875 return sta_cfon_reset_default(dut, conn, cmd);
7876 }
7877
Jouni Malinen439352d2018-09-13 03:42:23 +03007878 wpa_command(intf, "SET setband AUTO");
7879
Sunil Duttfebf8a82018-02-09 18:50:13 +05307880 if (dut->program != PROGRAM_VHT)
7881 return cmd_sta_p2p_reset(dut, conn, cmd);
7882
Priyadharshini Gowthamana7dfd492015-11-09 14:34:08 -08007883 return 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007884}
7885
7886
Jouni Malinenf7222712019-06-13 01:50:21 +03007887static enum sigma_cmd_result cmd_sta_get_events(struct sigma_dut *dut,
7888 struct sigma_conn *conn,
7889 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007890{
7891 const char *program = get_param(cmd, "Program");
7892
7893 if (program == NULL)
7894 return -1;
7895#ifdef ANDROID_NAN
7896 if (strcasecmp(program, "NAN") == 0)
7897 return nan_cmd_sta_get_events(dut, conn, cmd);
7898#endif /* ANDROID_NAN */
7899 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
7900 return 0;
7901}
7902
7903
Jouni Malinen82905202018-04-29 17:20:10 +03007904static int sta_exec_action_url(struct sigma_dut *dut, struct sigma_conn *conn,
7905 struct sigma_cmd *cmd)
7906{
7907 const char *url = get_param(cmd, "url");
7908 const char *method = get_param(cmd, "method");
7909 pid_t pid;
7910 int status;
7911
7912 if (!url || !method)
7913 return -1;
7914
7915 /* TODO: Add support for method,post */
7916 if (strcasecmp(method, "get") != 0) {
7917 send_resp(dut, conn, SIGMA_ERROR,
7918 "ErrorCode,Unsupported method");
7919 return 0;
7920 }
7921
7922 pid = fork();
7923 if (pid < 0) {
7924 perror("fork");
7925 return -1;
7926 }
7927
7928 if (pid == 0) {
7929 char * argv[5] = { "wget", "-O", "/dev/null",
7930 (char *) url, NULL };
7931
7932 execv("/usr/bin/wget", argv);
7933 perror("execv");
7934 exit(0);
7935 return -1;
7936 }
7937
7938 if (waitpid(pid, &status, 0) < 0) {
7939 perror("waitpid");
7940 return -1;
7941 }
7942
7943 if (WIFEXITED(status)) {
7944 const char *errmsg;
7945
7946 if (WEXITSTATUS(status) == 0)
7947 return 1;
7948 sigma_dut_print(dut, DUT_MSG_INFO, "wget exit status %d",
7949 WEXITSTATUS(status));
7950 switch (WEXITSTATUS(status)) {
7951 case 4:
7952 errmsg = "errmsg,Network failure";
7953 break;
7954 case 8:
7955 errmsg = "errmsg,Server issued an error response";
7956 break;
7957 default:
7958 errmsg = "errmsg,Unknown failure from wget";
7959 break;
7960 }
7961 send_resp(dut, conn, SIGMA_ERROR, errmsg);
7962 return 0;
7963 }
7964
7965 send_resp(dut, conn, SIGMA_ERROR, "errmsg,Unknown failure");
7966 return 0;
7967}
7968
7969
Jouni Malinenf7222712019-06-13 01:50:21 +03007970static enum sigma_cmd_result cmd_sta_exec_action(struct sigma_dut *dut,
7971 struct sigma_conn *conn,
7972 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007973{
7974 const char *program = get_param(cmd, "Prog");
7975
Jouni Malinen82905202018-04-29 17:20:10 +03007976 if (program && !get_param(cmd, "interface"))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007977 return -1;
7978#ifdef ANDROID_NAN
Jouni Malinen82905202018-04-29 17:20:10 +03007979 if (program && strcasecmp(program, "NAN") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007980 return nan_cmd_sta_exec_action(dut, conn, cmd);
7981#endif /* ANDROID_NAN */
Jouni Malinen82905202018-04-29 17:20:10 +03007982
7983 if (program && strcasecmp(program, "Loc") == 0)
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07007984 return loc_cmd_sta_exec_action(dut, conn, cmd);
Jouni Malinen82905202018-04-29 17:20:10 +03007985
7986 if (get_param(cmd, "url"))
7987 return sta_exec_action_url(dut, conn, cmd);
7988
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007989 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
7990 return 0;
7991}
7992
7993
Jouni Malinenf7222712019-06-13 01:50:21 +03007994static enum sigma_cmd_result cmd_sta_set_11n(struct sigma_dut *dut,
7995 struct sigma_conn *conn,
7996 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007997{
7998 const char *intf = get_param(cmd, "Interface");
7999 const char *val, *mcs32, *rate;
8000
8001 val = get_param(cmd, "GREENFIELD");
8002 if (val) {
8003 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
8004 /* Enable GD */
8005 send_resp(dut, conn, SIGMA_ERROR,
8006 "ErrorCode,GF not supported");
8007 return 0;
8008 }
8009 }
8010
8011 val = get_param(cmd, "SGI20");
8012 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02008013 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008014 case DRIVER_ATHEROS:
8015 ath_sta_set_sgi(dut, intf, val);
8016 break;
8017 default:
8018 send_resp(dut, conn, SIGMA_ERROR,
8019 "ErrorCode,SGI20 not supported");
8020 return 0;
8021 }
8022 }
8023
8024 mcs32 = get_param(cmd, "MCS32"); /* HT Duplicate Mode Enable/Disable */
8025 rate = get_param(cmd, "MCS_FIXEDRATE"); /* Fixed MCS rate (0..31) */
8026 if (mcs32 && rate) {
8027 /* TODO */
8028 send_resp(dut, conn, SIGMA_ERROR,
8029 "ErrorCode,MCS32,MCS_FIXEDRATE not supported");
8030 return 0;
8031 } else if (mcs32 && !rate) {
8032 /* TODO */
8033 send_resp(dut, conn, SIGMA_ERROR,
8034 "ErrorCode,MCS32 not supported");
8035 return 0;
8036 } else if (!mcs32 && rate) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02008037 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008038 case DRIVER_ATHEROS:
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -07008039 novap_reset(dut, intf, 1);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008040 ath_sta_set_11nrates(dut, intf, rate);
8041 break;
8042 default:
8043 send_resp(dut, conn, SIGMA_ERROR,
8044 "ErrorCode,MCS32_FIXEDRATE not supported");
8045 return 0;
8046 }
8047 }
8048
8049 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
8050}
8051
8052
Arif Hussain7b47d2d2018-05-09 10:44:02 -07008053static void cmd_set_max_he_mcs(struct sigma_dut *dut, const char *intf,
8054 int mcs_config)
8055{
8056#ifdef NL80211_SUPPORT
8057 int ret;
8058
8059 switch (mcs_config) {
8060 case HE_80_MCS0_7:
8061 case HE_80_MCS0_9:
8062 case HE_80_MCS0_11:
8063 ret = sta_set_he_mcs(dut, intf, mcs_config);
8064 if (ret) {
8065 sigma_dut_print(dut, DUT_MSG_ERROR,
8066 "cmd_set_max_he_mcs: Setting of MCS:%d failed, ret:%d",
8067 mcs_config, ret);
8068 }
8069 break;
8070 default:
8071 sigma_dut_print(dut, DUT_MSG_ERROR,
8072 "cmd_set_max_he_mcs: Invalid mcs %d",
8073 mcs_config);
8074 break;
8075 }
8076#else /* NL80211_SUPPORT */
8077 sigma_dut_print(dut, DUT_MSG_ERROR,
8078 "max HE MCS cannot be changed without NL80211_SUPPORT defined");
8079#endif /* NL80211_SUPPORT */
8080}
8081
8082
Arif Hussain480d5f42019-03-12 14:40:42 -07008083static int sta_twt_request(struct sigma_dut *dut, struct sigma_conn *conn,
8084 struct sigma_cmd *cmd)
8085{
8086#ifdef NL80211_SUPPORT
8087 struct nlattr *params;
8088 struct nlattr *attr;
8089 struct nlattr *attr1;
8090 struct nl_msg *msg;
8091 int ifindex, ret;
8092 const char *val;
8093 const char *intf = get_param(cmd, "Interface");
8094 int wake_interval_exp = 10, nominal_min_wake_dur = 255,
8095 wake_interval_mantissa = 512;
8096 int flow_type = 0, twt_trigger = 0, target_wake_time = 0,
8097 protection = 0;
8098
8099 ifindex = if_nametoindex(intf);
8100 if (ifindex == 0) {
8101 sigma_dut_print(dut, DUT_MSG_ERROR,
8102 "%s: Index for interface %s failed",
8103 __func__, intf);
8104 return -1;
8105 }
8106
8107 val = get_param(cmd, "FlowType");
8108 if (val) {
8109 flow_type = atoi(val);
8110 if (flow_type != 0 && flow_type != 1) {
8111 sigma_dut_print(dut, DUT_MSG_ERROR,
8112 "TWT: Invalid FlowType %d", flow_type);
8113 return -1;
8114 }
8115 }
8116
8117 val = get_param(cmd, "TWT_Trigger");
8118 if (val) {
8119 twt_trigger = atoi(val);
8120 if (twt_trigger != 0 && twt_trigger != 1) {
8121 sigma_dut_print(dut, DUT_MSG_ERROR,
8122 "TWT: Invalid TWT_Trigger %d",
8123 twt_trigger);
8124 return -1;
8125 }
8126 }
8127
8128 val = get_param(cmd, "Protection");
8129 if (val) {
8130 protection = atoi(val);
8131 if (protection != 0 && protection != 1) {
8132 sigma_dut_print(dut, DUT_MSG_ERROR,
8133 "TWT: Invalid Protection %d",
8134 protection);
8135 return -1;
8136 }
8137 }
8138
8139 val = get_param(cmd, "TargetWakeTime");
8140 if (val)
8141 target_wake_time = atoi(val);
8142
8143 val = get_param(cmd, "WakeIntervalMantissa");
8144 if (val)
8145 wake_interval_mantissa = atoi(val);
8146
8147 val = get_param(cmd, "WakeIntervalExp");
8148 if (val)
8149 wake_interval_exp = atoi(val);
8150
8151 val = get_param(cmd, "NominalMinWakeDur");
8152 if (val)
8153 nominal_min_wake_dur = atoi(val);
8154
8155 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8156 NL80211_CMD_VENDOR)) ||
8157 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
8158 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
8159 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
8160 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
8161 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8162 !(params = nla_nest_start(
8163 msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_SETUP)) ||
8164 !(attr1 = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8165 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_EXP,
8166 wake_interval_exp) ||
Arif Hussain480d5f42019-03-12 14:40:42 -07008167 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_REQ_TYPE, 1) ||
Kiran Kumar Lokere2cffae52019-09-26 18:44:15 -07008168 (twt_trigger &&
8169 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TRIGGER)) ||
Arif Hussain480d5f42019-03-12 14:40:42 -07008170 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE,
8171 flow_type) ||
Kiran Kumar Lokere2cffae52019-09-26 18:44:15 -07008172 (protection &&
8173 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_PROTECTION)) ||
Arif Hussain480d5f42019-03-12 14:40:42 -07008174 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME,
8175 target_wake_time) ||
8176 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_DURATION,
8177 nominal_min_wake_dur) ||
8178 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_MANTISSA,
8179 wake_interval_mantissa)) {
8180 sigma_dut_print(dut, DUT_MSG_ERROR,
8181 "%s: err in adding vendor_cmd and vendor_data",
8182 __func__);
8183 nlmsg_free(msg);
8184 return -1;
8185 }
8186 nla_nest_end(msg, attr1);
8187 nla_nest_end(msg, params);
8188 nla_nest_end(msg, attr);
8189
8190 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
8191 if (ret) {
8192 sigma_dut_print(dut, DUT_MSG_ERROR,
8193 "%s: err in send_and_recv_msgs, ret=%d",
8194 __func__, ret);
8195 }
8196
8197 return ret;
8198#else /* NL80211_SUPPORT */
8199 sigma_dut_print(dut, DUT_MSG_ERROR,
8200 "TWT request cannot be done without NL80211_SUPPORT defined");
8201 return -1;
8202#endif /* NL80211_SUPPORT */
8203}
8204
8205
8206static int sta_twt_teardown(struct sigma_dut *dut, struct sigma_conn *conn,
8207 struct sigma_cmd *cmd)
8208{
8209 #ifdef NL80211_SUPPORT
8210 struct nlattr *params;
8211 struct nlattr *attr;
8212 struct nlattr *attr1;
8213 int ifindex, ret;
8214 struct nl_msg *msg;
8215 const char *intf = get_param(cmd, "Interface");
8216
8217 ifindex = if_nametoindex(intf);
8218 if (ifindex == 0) {
8219 sigma_dut_print(dut, DUT_MSG_ERROR,
8220 "%s: Index for interface %s failed",
8221 __func__, intf);
8222 return -1;
8223 }
8224
8225 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8226 NL80211_CMD_VENDOR)) ||
8227 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
8228 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
8229 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
8230 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
8231 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8232 !(params = nla_nest_start(
8233 msg,
8234 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_TERMINATE)) ||
8235 !(attr1 = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8236 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE, 0)) {
8237 sigma_dut_print(dut, DUT_MSG_ERROR,
8238 "%s: err in adding vendor_cmd and vendor_data",
8239 __func__);
8240 nlmsg_free(msg);
8241 return -1;
8242 }
8243 nla_nest_end(msg, attr1);
8244 nla_nest_end(msg, params);
8245 nla_nest_end(msg, attr);
8246
8247 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
8248 if (ret) {
8249 sigma_dut_print(dut, DUT_MSG_ERROR,
8250 "%s: err in send_and_recv_msgs, ret=%d",
8251 __func__, ret);
8252 }
8253
8254 return ret;
8255#else /* NL80211_SUPPORT */
8256 sigma_dut_print(dut, DUT_MSG_ERROR,
8257 "TWT teardown cannot be done without NL80211_SUPPORT defined");
8258 return -1;
8259#endif /* NL80211_SUPPORT */
8260}
8261
8262
Kiran Kumar Lokere50eb2cd2018-12-18 18:31:28 -08008263static int sta_transmit_omi(struct sigma_dut *dut, struct sigma_conn *conn,
8264 struct sigma_cmd *cmd)
8265{
8266#ifdef NL80211_SUPPORT
8267 struct nlattr *params;
8268 struct nlattr *attr;
8269 struct nlattr *attr1;
8270 struct nl_msg *msg;
8271 int ifindex, ret;
8272 const char *val;
8273 const char *intf = get_param(cmd, "Interface");
8274 uint8_t rx_nss = 0xFF, ch_bw = 0xFF, tx_nsts = 0xFF, ulmu_dis = 0,
8275 ulmu_data_dis = 0;
8276
8277 ifindex = if_nametoindex(intf);
8278 if (ifindex == 0) {
8279 sigma_dut_print(dut, DUT_MSG_ERROR,
8280 "%s: Index for interface %s failed",
8281 __func__, intf);
8282 return -1;
8283 }
8284 val = get_param(cmd, "OMCtrl_RxNSS");
8285 if (val)
8286 rx_nss = atoi(val);
8287
8288 val = get_param(cmd, "OMCtrl_ChnlWidth");
8289 if (val)
8290 ch_bw = atoi(val);
8291
8292 val = get_param(cmd, "OMCtrl_ULMUDisable");
8293 if (val)
8294 ulmu_dis = atoi(val);
8295
8296 val = get_param(cmd, "OMCtrl_TxNSTS");
8297 if (val)
8298 tx_nsts = atoi(val);
8299
8300 val = get_param(cmd, "OMCtrl_ULMUDataDisable");
8301 if (val)
8302 ulmu_data_dis = atoi(val);
8303
8304 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8305 NL80211_CMD_VENDOR)) ||
8306 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
8307 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
8308 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
8309 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
8310 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8311 !(params = nla_nest_start(
8312 msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OMI_TX)) ||
8313 !(attr1 = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8314 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_RX_NSS, rx_nss) ||
8315 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_CH_BW, ch_bw) ||
8316 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_TX_NSTS, tx_nsts) ||
8317 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DATA_DISABLE,
8318 ulmu_data_dis) ||
8319 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DISABLE,
8320 ulmu_dis)) {
8321 sigma_dut_print(dut, DUT_MSG_ERROR,
8322 "%s: err in adding vendor_cmd and vendor_data",
8323 __func__);
8324 nlmsg_free(msg);
8325 return -1;
8326 }
8327 nla_nest_end(msg, attr1);
8328 nla_nest_end(msg, params);
8329 nla_nest_end(msg, attr);
8330
8331 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
8332 if (ret) {
8333 sigma_dut_print(dut, DUT_MSG_ERROR,
8334 "%s: err in send_and_recv_msgs, ret=%d",
8335 __func__, ret);
8336 }
8337
8338 return ret;
8339#else /* NL80211_SUPPORT */
8340 sigma_dut_print(dut, DUT_MSG_ERROR,
8341 "OMI TX cannot be processed without NL80211_SUPPORT defined");
8342 return -1;
8343#endif /* NL80211_SUPPORT */
8344}
8345
8346
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008347static int cmd_sta_set_wireless_vht(struct sigma_dut *dut,
8348 struct sigma_conn *conn,
8349 struct sigma_cmd *cmd)
8350{
8351 const char *intf = get_param(cmd, "Interface");
8352 const char *val;
Arif Hussaina37e9552018-06-20 17:05:59 -07008353 const char *program;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008354 int tkip = -1;
8355 int wep = -1;
8356
Arif Hussaina37e9552018-06-20 17:05:59 -07008357 program = get_param(cmd, "Program");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008358 val = get_param(cmd, "SGI80");
8359 if (val) {
8360 int sgi80;
8361
8362 sgi80 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008363 run_iwpriv(dut, intf, "shortgi %d", sgi80);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008364 }
8365
8366 val = get_param(cmd, "TxBF");
8367 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02008368 switch (get_driver_type(dut)) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07008369 case DRIVER_WCN:
8370 if (sta_set_tx_beamformee(dut, intf, 1)) {
8371 send_resp(dut, conn, SIGMA_ERROR,
8372 "ErrorCode,Failed to set TX beamformee enable");
8373 return 0;
8374 }
8375 break;
8376 case DRIVER_ATHEROS:
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008377 if (run_iwpriv(dut, intf, "vhtsubfee 1") < 0) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07008378 send_resp(dut, conn, SIGMA_ERROR,
8379 "ErrorCode,Setting vhtsubfee failed");
8380 return 0;
8381 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008382 if (run_iwpriv(dut, intf, "vhtsubfer 1") < 0) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07008383 send_resp(dut, conn, SIGMA_ERROR,
8384 "ErrorCode,Setting vhtsubfer failed");
8385 return 0;
8386 }
8387 break;
8388 default:
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008389 sigma_dut_print(dut, DUT_MSG_ERROR,
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07008390 "Unsupported driver type");
8391 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008392 }
8393 }
8394
8395 val = get_param(cmd, "MU_TxBF");
8396 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02008397 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008398 case DRIVER_ATHEROS:
8399 ath_sta_set_txsp_stream(dut, intf, "1SS");
8400 ath_sta_set_rxsp_stream(dut, intf, "1SS");
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008401 run_iwpriv(dut, intf, "vhtmubfee 1");
8402 run_iwpriv(dut, intf, "vhtmubfer 1");
Sunil Duttae9e5d12018-06-29 11:50:47 +05308403 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008404 case DRIVER_WCN:
8405 if (wcn_sta_set_sp_stream(dut, intf, "1SS") < 0) {
8406 send_resp(dut, conn, SIGMA_ERROR,
8407 "ErrorCode,Failed to set RX/TXSP_STREAM");
8408 return 0;
8409 }
Sunil Duttae9e5d12018-06-29 11:50:47 +05308410 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008411 default:
8412 sigma_dut_print(dut, DUT_MSG_ERROR,
8413 "Setting SP_STREAM not supported");
8414 break;
8415 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008416 }
8417
8418 val = get_param(cmd, "LDPC");
8419 if (val) {
8420 int ldpc;
8421
8422 ldpc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008423 run_iwpriv(dut, intf, "ldpc %d", ldpc);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008424 }
8425
Amarnath Hullur Subramanyam7bae60e2018-01-31 03:46:50 -08008426 val = get_param(cmd, "BCC");
8427 if (val) {
8428 int bcc;
8429
8430 bcc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
8431 /* use LDPC iwpriv itself to set bcc coding, bcc coding
8432 * is mutually exclusive to bcc */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008433 run_iwpriv(dut, intf, "ldpc %d", !bcc);
Amarnath Hullur Subramanyam7bae60e2018-01-31 03:46:50 -08008434 }
8435
Arif Hussain7b47d2d2018-05-09 10:44:02 -07008436 val = get_param(cmd, "MaxHE-MCS_1SS_RxMapLTE80");
8437 if (val && dut->sta_nss == 1)
8438 cmd_set_max_he_mcs(dut, intf, atoi(val));
8439
8440 val = get_param(cmd, "MaxHE-MCS_2SS_RxMapLTE80");
8441 if (val && dut->sta_nss == 2)
8442 cmd_set_max_he_mcs(dut, intf, atoi(val));
8443
Arif Hussainac6c5112018-05-25 17:34:00 -07008444 val = get_param(cmd, "MCS_FixedRate");
8445 if (val) {
8446#ifdef NL80211_SUPPORT
8447 int mcs, ratecode = 0;
8448 enum he_mcs_config mcs_config;
8449 int ret;
Jouni Malinenb9b671d2019-04-26 13:23:17 +03008450 char buf[60];
Arif Hussainac6c5112018-05-25 17:34:00 -07008451
8452 ratecode = (0x07 & dut->sta_nss) << 5;
8453 mcs = atoi(val);
8454 /* Add the MCS to the ratecode */
8455 if (mcs >= 0 && mcs <= 11) {
8456 ratecode += mcs;
8457 if (dut->device_type == STA_testbed &&
8458 mcs > 7 && mcs <= 11) {
8459 if (mcs <= 9)
8460 mcs_config = HE_80_MCS0_9;
8461 else
8462 mcs_config = HE_80_MCS0_11;
8463 ret = sta_set_he_mcs(dut, intf, mcs_config);
8464 if (ret) {
8465 sigma_dut_print(dut, DUT_MSG_ERROR,
8466 "MCS_FixedRate: mcs setting failed, mcs:%d, mcs_config %d, ret:%d",
8467 mcs, mcs_config, ret);
8468 }
8469 }
8470 snprintf(buf, sizeof(buf),
8471 "iwpriv %s set_11ax_rate 0x%03x",
8472 intf, ratecode);
8473 if (system(buf) != 0) {
8474 sigma_dut_print(dut, DUT_MSG_ERROR,
8475 "MCS_FixedRate: iwpriv setting of 11ax rates 0x%03x failed",
8476 ratecode);
8477 }
8478 } else {
8479 sigma_dut_print(dut, DUT_MSG_ERROR,
8480 "MCS_FixedRate: HE MCS %d not supported",
8481 mcs);
8482 }
8483#else /* NL80211_SUPPORT */
8484 sigma_dut_print(dut, DUT_MSG_ERROR,
8485 "MCS_FixedRate cannot be changed without NL80211_SUPPORT defined");
8486#endif /* NL80211_SUPPORT */
8487 }
8488
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008489 val = get_param(cmd, "opt_md_notif_ie");
8490 if (val) {
8491 char *result = NULL;
8492 char delim[] = ";";
8493 char token[30];
8494 int value, config_val = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308495 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008496
Peng Xub8fc5cc2017-05-10 17:27:28 -07008497 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308498 result = strtok_r(token, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008499
8500 /* Extract the NSS information */
8501 if (result) {
8502 value = atoi(result);
8503 switch (value) {
8504 case 1:
8505 config_val = 1;
8506 break;
8507 case 2:
8508 config_val = 3;
8509 break;
8510 case 3:
8511 config_val = 7;
8512 break;
8513 case 4:
8514 config_val = 15;
8515 break;
8516 default:
8517 config_val = 3;
8518 break;
8519 }
8520
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008521 run_iwpriv(dut, intf, "rxchainmask %d", config_val);
8522 run_iwpriv(dut, intf, "txchainmask %d", config_val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008523
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008524 }
8525
8526 /* Extract the channel width information */
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308527 result = strtok_r(NULL, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008528 if (result) {
8529 value = atoi(result);
8530 switch (value) {
8531 case 20:
8532 config_val = 0;
8533 break;
8534 case 40:
8535 config_val = 1;
8536 break;
8537 case 80:
8538 config_val = 2;
8539 break;
8540 case 160:
8541 config_val = 3;
8542 break;
8543 default:
8544 config_val = 2;
8545 break;
8546 }
8547
8548 dut->chwidth = config_val;
8549
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008550 run_iwpriv(dut, intf, "chwidth %d", config_val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008551 }
8552
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008553 run_iwpriv(dut, intf, "opmode_notify 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008554 }
8555
8556 val = get_param(cmd, "nss_mcs_cap");
8557 if (val) {
8558 int nss, mcs;
8559 char token[20];
8560 char *result = NULL;
8561 unsigned int vht_mcsmap = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308562 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008563
Peng Xub8fc5cc2017-05-10 17:27:28 -07008564 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308565 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05308566 if (!result) {
8567 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07008568 "NSS not specified");
8569 send_resp(dut, conn, SIGMA_ERROR,
8570 "errorCode,NSS not specified");
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05308571 return 0;
8572 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008573 nss = atoi(result);
8574
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008575 run_iwpriv(dut, intf, "nss %d", nss);
Arif Hussainac6c5112018-05-25 17:34:00 -07008576 dut->sta_nss = nss;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008577
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308578 result = strtok_r(NULL, ";", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008579 if (result == NULL) {
8580 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07008581 "MCS not specified");
8582 send_resp(dut, conn, SIGMA_ERROR,
8583 "errorCode,MCS not specified");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008584 return 0;
8585 }
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308586 result = strtok_r(result, "-", &saveptr);
8587 result = strtok_r(NULL, "-", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05308588 if (!result) {
8589 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07008590 "MCS not specified");
8591 send_resp(dut, conn, SIGMA_ERROR,
8592 "errorCode,MCS not specified");
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05308593 return 0;
8594 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008595 mcs = atoi(result);
8596
Arif Hussaina37e9552018-06-20 17:05:59 -07008597 if (program && strcasecmp(program, "HE") == 0) {
8598#ifdef NL80211_SUPPORT
8599 enum he_mcs_config mcs_config;
8600 int ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008601
Arif Hussaina37e9552018-06-20 17:05:59 -07008602 if (mcs >= 0 && mcs <= 7) {
8603 mcs_config = HE_80_MCS0_7;
8604 } else if (mcs > 7 && mcs <= 9) {
8605 mcs_config = HE_80_MCS0_9;
8606 } else if (mcs > 9 && mcs <= 11) {
8607 mcs_config = HE_80_MCS0_11;
8608 } else {
8609 sigma_dut_print(dut, DUT_MSG_ERROR,
8610 "nss_mcs_cap: HE: Invalid mcs: %d",
8611 mcs);
8612 send_resp(dut, conn, SIGMA_ERROR,
8613 "errorCode,Invalid MCS");
8614 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008615 }
Arif Hussaina37e9552018-06-20 17:05:59 -07008616
8617 ret = sta_set_he_mcs(dut, intf, mcs_config);
8618 if (ret) {
8619 sigma_dut_print(dut, DUT_MSG_ERROR,
8620 "nss_mcs_cap: HE: Setting of MCS failed, mcs_config: %d, ret: %d",
8621 mcs_config, ret);
8622 send_resp(dut, conn, SIGMA_ERROR,
8623 "errorCode,Failed to set MCS");
8624 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008625 }
Arif Hussaina37e9552018-06-20 17:05:59 -07008626#else /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008627 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07008628 "nss_mcs_cap: HE: MCS cannot be changed without NL80211_SUPPORT defined");
8629#endif /* NL80211_SUPPORT */
8630 } else {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008631 run_iwpriv(dut, intf, "vhtmcs %d", mcs);
Arif Hussaina37e9552018-06-20 17:05:59 -07008632
8633 switch (nss) {
8634 case 1:
8635 switch (mcs) {
8636 case 7:
8637 vht_mcsmap = 0xfffc;
8638 break;
8639 case 8:
8640 vht_mcsmap = 0xfffd;
8641 break;
8642 case 9:
8643 vht_mcsmap = 0xfffe;
8644 break;
8645 default:
8646 vht_mcsmap = 0xfffe;
8647 break;
8648 }
8649 break;
8650 case 2:
8651 switch (mcs) {
8652 case 7:
8653 vht_mcsmap = 0xfff0;
8654 break;
8655 case 8:
8656 vht_mcsmap = 0xfff5;
8657 break;
8658 case 9:
8659 vht_mcsmap = 0xfffa;
8660 break;
8661 default:
8662 vht_mcsmap = 0xfffa;
8663 break;
8664 }
8665 break;
8666 case 3:
8667 switch (mcs) {
8668 case 7:
8669 vht_mcsmap = 0xffc0;
8670 break;
8671 case 8:
8672 vht_mcsmap = 0xffd5;
8673 break;
8674 case 9:
8675 vht_mcsmap = 0xffea;
8676 break;
8677 default:
8678 vht_mcsmap = 0xffea;
8679 break;
8680 }
8681 break;
8682 default:
8683 vht_mcsmap = 0xffea;
8684 break;
8685 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008686 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008687 }
8688 }
8689
8690 /* UNSUPPORTED: val = get_param(cmd, "Tx_lgi_rate"); */
8691
8692 val = get_param(cmd, "Vht_tkip");
8693 if (val)
8694 tkip = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
8695
8696 val = get_param(cmd, "Vht_wep");
8697 if (val)
8698 wep = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
8699
8700 if (tkip != -1 || wep != -1) {
8701 if ((tkip == 1 && wep != 0) || (wep == 1 && tkip != 0)) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008702 run_iwpriv(dut, intf, "htweptkip 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008703 } else if ((tkip == 0 && wep != 1) || (wep == 0 && tkip != 1)) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008704 run_iwpriv(dut, intf, "htweptkip 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008705 } else {
8706 sigma_dut_print(dut, DUT_MSG_ERROR,
8707 "ErrorCode,mixed mode of VHT TKIP/WEP not supported");
8708 return 0;
8709 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008710 }
8711
Arif Hussain55f00da2018-07-03 08:28:26 -07008712 val = get_param(cmd, "txBandwidth");
8713 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02008714 switch (get_driver_type(dut)) {
Arif Hussain55f00da2018-07-03 08:28:26 -07008715 case DRIVER_WCN:
8716 if (wcn_sta_set_width(dut, intf, val) < 0) {
8717 send_resp(dut, conn, SIGMA_ERROR,
8718 "ErrorCode,Failed to set txBandwidth");
8719 return 0;
8720 }
8721 break;
8722 case DRIVER_ATHEROS:
8723 if (ath_set_width(dut, conn, intf, val) < 0) {
8724 send_resp(dut, conn, SIGMA_ERROR,
8725 "ErrorCode,Failed to set txBandwidth");
8726 return 0;
8727 }
8728 break;
8729 default:
8730 sigma_dut_print(dut, DUT_MSG_ERROR,
8731 "Setting txBandwidth not supported");
8732 break;
8733 }
8734 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008735
Arif Hussain9765f7d2018-07-03 08:28:26 -07008736 val = get_param(cmd, "BeamformeeSTS");
8737 if (val) {
Kiran Kumar Lokerebc89d432018-07-10 12:20:13 -07008738 if (sta_set_tx_beamformee(dut, intf, 1)) {
8739 send_resp(dut, conn, SIGMA_ERROR,
8740 "ErrorCode,Failed to set TX beamformee enable");
8741 return 0;
8742 }
8743
Arif Hussain9765f7d2018-07-03 08:28:26 -07008744 if (sta_set_beamformee_sts(dut, intf, atoi(val))) {
8745 send_resp(dut, conn, SIGMA_ERROR,
8746 "ErrorCode,Failed to set BeamformeeSTS");
8747 return 0;
8748 }
8749 }
8750
Arif Hussain68d23f52018-07-11 13:39:08 -07008751 val = get_param(cmd, "Trig_MAC_Padding_Dur");
8752 if (val) {
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07008753#ifdef NL80211_SUPPORT
8754 enum qca_wlan_he_mac_padding_dur set_val;
8755
8756 switch (atoi(val)) {
8757 case 16:
8758 set_val = QCA_WLAN_HE_16US_OF_PROCESS_TIME;
8759 break;
8760 case 8:
8761 set_val = QCA_WLAN_HE_8US_OF_PROCESS_TIME;
8762 break;
8763 default:
8764 set_val = QCA_WLAN_HE_NO_ADDITIONAL_PROCESS_TIME;
8765 break;
8766 }
8767 if (sta_set_mac_padding_duration(dut, intf, set_val)) {
Arif Hussain68d23f52018-07-11 13:39:08 -07008768 send_resp(dut, conn, SIGMA_ERROR,
8769 "ErrorCode,Failed to set MAC padding duration");
8770 return 0;
8771 }
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07008772#else /* NL80211_SUPPORT */
8773 sigma_dut_print(dut, DUT_MSG_ERROR,
8774 "MAC padding duration cannot be changed without NL80211_SUPPORT defined");
8775#endif /* NL80211_SUPPORT */
Arif Hussain68d23f52018-07-11 13:39:08 -07008776 }
8777
Arif Hussain480d5f42019-03-12 14:40:42 -07008778 val = get_param(cmd, "TWT_ReqSupport");
8779 if (val) {
8780 int set_val;
8781
8782 if (strcasecmp(val, "Enable") == 0) {
8783 set_val = 1;
8784 } else if (strcasecmp(val, "Disable") == 0) {
8785 set_val = 0;
8786 } else {
8787 send_resp(dut, conn, SIGMA_ERROR,
8788 "ErrorCode,Invalid TWT_ReqSupport");
8789 return STATUS_SENT;
8790 }
8791
8792 if (sta_set_twt_req_support(dut, intf, set_val)) {
8793 sigma_dut_print(dut, DUT_MSG_ERROR,
8794 "Failed to set TWT req support %d",
8795 set_val);
8796 send_resp(dut, conn, SIGMA_ERROR,
8797 "ErrorCode,Failed to set TWT_ReqSupport");
8798 return STATUS_SENT;
8799 }
8800 }
8801
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07008802 val = get_param(cmd, "MU_EDCA");
8803 if (val && (strcasecmp(val, "Override") == 0)) {
8804 if (sta_set_mu_edca_override(dut, intf, 1)) {
8805 send_resp(dut, conn, SIGMA_ERROR,
8806 "ErrorCode,Failed to set MU EDCA override");
8807 return 0;
8808 }
8809 }
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -07008810
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07008811 val = get_param(cmd, "OMControl");
8812 if (val) {
8813 int set_val = 1;
8814
8815 if (strcasecmp(val, "Enable") == 0)
8816 set_val = 1;
8817 else if (strcasecmp(val, "Disable") == 0)
8818 set_val = 0;
8819
8820 if (sta_set_om_ctrl_supp(dut, intf, set_val)) {
8821 send_resp(dut, conn, SIGMA_ERROR,
8822 "ErrorCode,Failed to set OM ctrl supp");
8823 return 0;
8824 }
8825 }
8826
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -07008827 val = get_param(cmd, "ADDBAResp_BufSize");
8828 if (val) {
8829 int buf_size;
8830
8831 if (strcasecmp(val, "gt64") == 0)
8832 buf_size = 256;
8833 else
8834 buf_size = 64;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02008835 if (get_driver_type(dut) == DRIVER_WCN &&
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -07008836 sta_set_addba_buf_size(dut, intf, buf_size)) {
8837 send_resp(dut, conn, SIGMA_ERROR,
8838 "ErrorCode,set addbaresp_buff_size failed");
8839 return 0;
8840 }
8841 }
8842
8843 val = get_param(cmd, "ADDBAReq_BufSize");
8844 if (val) {
8845 int buf_size;
8846
8847 if (strcasecmp(val, "gt64") == 0)
8848 buf_size = 256;
8849 else
8850 buf_size = 64;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02008851 if (get_driver_type(dut) == DRIVER_WCN &&
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -07008852 sta_set_addba_buf_size(dut, intf, buf_size)) {
8853 send_resp(dut, conn, SIGMA_ERROR,
8854 "ErrorCode,set addbareq_buff_size failed");
8855 return 0;
8856 }
8857 }
8858
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008859 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
8860}
8861
8862
8863static int sta_set_wireless_60g(struct sigma_dut *dut,
8864 struct sigma_conn *conn,
8865 struct sigma_cmd *cmd)
8866{
8867 const char *dev_role = get_param(cmd, "DevRole");
8868
8869 if (!dev_role) {
8870 send_resp(dut, conn, SIGMA_INVALID,
8871 "ErrorCode,DevRole not specified");
8872 return 0;
8873 }
8874
8875 if (strcasecmp(dev_role, "PCP") == 0)
8876 return sta_set_60g_pcp(dut, conn, cmd);
8877 if (strcasecmp(dev_role, "STA") == 0)
8878 return sta_set_60g_sta(dut, conn, cmd);
8879 send_resp(dut, conn, SIGMA_INVALID,
8880 "ErrorCode,DevRole not supported");
8881 return 0;
8882}
8883
8884
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05308885static int sta_set_wireless_oce(struct sigma_dut *dut, struct sigma_conn *conn,
8886 struct sigma_cmd *cmd)
8887{
8888 int status;
8889 const char *intf = get_param(cmd, "Interface");
8890 const char *val = get_param(cmd, "DevRole");
8891
8892 if (val && strcasecmp(val, "STA-CFON") == 0) {
8893 status = sta_cfon_set_wireless(dut, conn, cmd);
8894 if (status)
8895 return status;
8896 }
8897 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
8898}
8899
8900
Jouni Malinenf7222712019-06-13 01:50:21 +03008901static enum sigma_cmd_result cmd_sta_set_wireless(struct sigma_dut *dut,
8902 struct sigma_conn *conn,
8903 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008904{
8905 const char *val;
8906
8907 val = get_param(cmd, "Program");
8908 if (val) {
8909 if (strcasecmp(val, "11n") == 0)
8910 return cmd_sta_set_11n(dut, conn, cmd);
Amarnath Hullur Subramanyam4f860292018-01-31 03:49:35 -08008911 if (strcasecmp(val, "VHT") == 0 || strcasecmp(val, "HE") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008912 return cmd_sta_set_wireless_vht(dut, conn, cmd);
8913 if (strcasecmp(val, "60ghz") == 0)
8914 return sta_set_wireless_60g(dut, conn, cmd);
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05308915 if (strcasecmp(val, "OCE") == 0)
8916 return sta_set_wireless_oce(dut, conn, cmd);
Alexei Avshalom Lazar66bb9972018-12-18 16:01:43 +02008917 /* sta_set_wireless in WPS program is only used for 60G */
8918 if (is_60g_sigma_dut(dut))
8919 return sta_set_wireless_60g(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008920 send_resp(dut, conn, SIGMA_ERROR,
8921 "ErrorCode,Program value not supported");
8922 } else {
8923 send_resp(dut, conn, SIGMA_ERROR,
8924 "ErrorCode,Program argument not available");
8925 }
8926
8927 return 0;
8928}
8929
8930
8931static void ath_sta_inject_frame(struct sigma_dut *dut, const char *intf,
8932 int tid)
8933{
8934 char buf[100];
8935 int tid_to_dscp [] = { 0x00, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0 };
8936
Pradeep Reddy POTTETId31d1322016-10-13 17:22:03 +05308937 if (tid < 0 ||
8938 tid >= (int) (sizeof(tid_to_dscp) / sizeof(tid_to_dscp[0]))) {
8939 sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported TID: %d", tid);
8940 return;
8941 }
8942
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008943 /*
8944 * Two ways to ensure that addba request with a
8945 * non zero TID could be sent out. EV 117296
8946 */
8947 snprintf(buf, sizeof(buf),
8948 "ping -c 8 -Q %d `arp -a | grep wlan0 | awk '{print $2}' | tr -d '()'`",
8949 tid);
8950 if (system(buf) != 0) {
8951 sigma_dut_print(dut, DUT_MSG_ERROR,
8952 "Ping did not send out");
8953 }
8954
8955 snprintf(buf, sizeof(buf),
8956 "iwconfig %s | grep Access | awk '{print $6}' > %s",
8957 intf, VI_QOS_TMP_FILE);
8958 if (system(buf) != 0)
8959 return;
8960
8961 snprintf(buf, sizeof(buf),
8962 "ifconfig %s | grep HWaddr | cut -b 39-56 >> %s",
8963 intf, VI_QOS_TMP_FILE);
8964 if (system(buf) != 0)
8965 sigma_dut_print(dut, DUT_MSG_ERROR, "HWaddr matching failed");
8966
8967 snprintf(buf,sizeof(buf), "sed -n '3,$p' %s >> %s",
8968 VI_QOS_REFFILE, VI_QOS_TMP_FILE);
8969 if (system(buf) != 0) {
8970 sigma_dut_print(dut, DUT_MSG_ERROR,
8971 "VI_QOS_TEMP_FILE generation error failed");
8972 }
8973 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
8974 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
8975 if (system(buf) != 0) {
8976 sigma_dut_print(dut, DUT_MSG_ERROR,
8977 "VI_QOS_FILE generation failed");
8978 }
8979
8980 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
8981 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
8982 if (system(buf) != 0) {
8983 sigma_dut_print(dut, DUT_MSG_ERROR,
8984 "VI_QOS_FILE generation failed");
8985 }
8986
8987 snprintf(buf, sizeof(buf), "ethinject %s %s", intf, VI_QOS_FILE);
8988 if (system(buf) != 0) {
8989 }
8990}
8991
8992
8993static int ath_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
8994 struct sigma_cmd *cmd)
8995{
8996 const char *intf = get_param(cmd, "Interface");
8997 const char *val;
8998 int tid = 0;
8999 char buf[100];
9000
9001 val = get_param(cmd, "TID");
9002 if (val) {
9003 tid = atoi(val);
9004 if (tid)
9005 ath_sta_inject_frame(dut, intf, tid);
9006 }
9007
9008 /* Command sequence for ADDBA request on Peregrine based devices */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07009009 run_iwpriv(dut, intf, "setaddbaoper 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009010
9011 snprintf(buf, sizeof(buf), "wifitool %s senddelba 1 %d 1 4", intf, tid);
9012 if (system(buf) != 0) {
9013 sigma_dut_print(dut, DUT_MSG_ERROR,
9014 "wifitool senddelba failed");
9015 }
9016
9017 snprintf(buf, sizeof(buf), "wifitool %s sendaddba 1 %d 64", intf, tid);
9018 if (system(buf) != 0) {
9019 sigma_dut_print(dut, DUT_MSG_ERROR,
9020 "wifitool sendaddba failed");
9021 }
9022
9023 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
9024
9025 return 1;
9026}
9027
9028
Lior David9981b512017-01-20 13:16:40 +02009029#ifdef __linux__
9030
9031static int wil6210_send_addba(struct sigma_dut *dut, const char *dest_mac,
9032 int agg_size)
9033{
9034 char dir[128], buf[128];
9035 FILE *f;
9036 regex_t re;
9037 regmatch_t m[2];
Jouni Malinen3aa72862019-05-29 23:14:51 +03009038 int rc, ret = -1, vring_id, found, res;
Lior David9981b512017-01-20 13:16:40 +02009039
9040 if (wil6210_get_debugfs_dir(dut, dir, sizeof(dir))) {
9041 sigma_dut_print(dut, DUT_MSG_ERROR,
9042 "failed to get wil6210 debugfs dir");
9043 return -1;
9044 }
9045
Jouni Malinen3aa72862019-05-29 23:14:51 +03009046 res = snprintf(buf, sizeof(buf), "%s/vrings", dir);
9047 if (res < 0 || res >= sizeof(buf))
9048 return -1;
Lior David9981b512017-01-20 13:16:40 +02009049 f = fopen(buf, "r");
9050 if (!f) {
9051 sigma_dut_print(dut, DUT_MSG_ERROR, "failed to open: %s", buf);
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +02009052 /* newer wil6210 driver renamed file to "rings" */
Jouni Malinen3aa72862019-05-29 23:14:51 +03009053 res = snprintf(buf, sizeof(buf), "%s/rings", dir);
9054 if (res < 0 || res >= sizeof(buf))
9055 return -1;
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +02009056 f = fopen(buf, "r");
9057 if (!f) {
9058 sigma_dut_print(dut, DUT_MSG_ERROR,
9059 "failed to open: %s", buf);
9060 return -1;
9061 }
Lior David9981b512017-01-20 13:16:40 +02009062 }
9063
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +02009064 /* can be either VRING tx... or RING... */
9065 if (regcomp(&re, "RING tx_[ \t]*([0-9]+)", REG_EXTENDED)) {
Lior David9981b512017-01-20 13:16:40 +02009066 sigma_dut_print(dut, DUT_MSG_ERROR, "regcomp failed");
9067 goto out;
9068 }
9069
9070 /* find TX VRING for the mac address */
9071 found = 0;
9072 while (fgets(buf, sizeof(buf), f)) {
9073 if (strcasestr(buf, dest_mac)) {
9074 found = 1;
9075 break;
9076 }
9077 }
9078
9079 if (!found) {
9080 sigma_dut_print(dut, DUT_MSG_ERROR,
9081 "no TX VRING for %s", dest_mac);
9082 goto out;
9083 }
9084
9085 /* extract VRING ID, "VRING tx_<id> = {" */
9086 if (!fgets(buf, sizeof(buf), f)) {
9087 sigma_dut_print(dut, DUT_MSG_ERROR,
9088 "no VRING start line for %s", dest_mac);
9089 goto out;
9090 }
9091
9092 rc = regexec(&re, buf, 2, m, 0);
9093 regfree(&re);
9094 if (rc || m[1].rm_so < 0) {
9095 sigma_dut_print(dut, DUT_MSG_ERROR,
9096 "no VRING TX ID for %s", dest_mac);
9097 goto out;
9098 }
9099 buf[m[1].rm_eo] = 0;
9100 vring_id = atoi(&buf[m[1].rm_so]);
9101
9102 /* send the addba command */
9103 fclose(f);
Jouni Malinen3aa72862019-05-29 23:14:51 +03009104 res = snprintf(buf, sizeof(buf), "%s/back", dir);
9105 if (res < 0 || res >= sizeof(buf))
9106 return -1;
Lior David9981b512017-01-20 13:16:40 +02009107 f = fopen(buf, "w");
9108 if (!f) {
9109 sigma_dut_print(dut, DUT_MSG_ERROR,
9110 "failed to open: %s", buf);
9111 return -1;
9112 }
9113
9114 fprintf(f, "add %d %d\n", vring_id, agg_size);
9115
9116 ret = 0;
9117
9118out:
9119 fclose(f);
9120
9121 return ret;
9122}
9123
9124
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +02009125int send_addba_60g(struct sigma_dut *dut, struct sigma_conn *conn,
9126 struct sigma_cmd *cmd, const char *mac_param)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009127{
9128 const char *val;
9129 int tid = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009130
9131 val = get_param(cmd, "TID");
9132 if (val) {
9133 tid = atoi(val);
9134 if (tid != 0) {
9135 sigma_dut_print(dut, DUT_MSG_ERROR,
9136 "Ignore TID %d for send_addba use TID 0 for 60g since only 0 required on TX",
9137 tid);
9138 }
9139 }
9140
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +02009141 val = get_param(cmd, mac_param);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009142 if (!val) {
9143 sigma_dut_print(dut, DUT_MSG_ERROR,
9144 "Currently not supporting addba for 60G without Dest_mac");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02009145 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009146 }
9147
Lior David9981b512017-01-20 13:16:40 +02009148 if (wil6210_send_addba(dut, val, dut->back_rcv_buf))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009149 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009150
9151 return 1;
9152}
9153
Lior David9981b512017-01-20 13:16:40 +02009154#endif /* __linux__ */
9155
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009156
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009157static int wcn_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
9158 struct sigma_cmd *cmd)
9159{
9160#ifdef NL80211_SUPPORT
9161 const char *intf = get_param(cmd, "Interface");
9162 const char *val;
9163 int tid = -1;
9164 int bufsize = 64;
9165 struct nl_msg *msg;
9166 int ret = 0;
9167 struct nlattr *params;
9168 int ifindex;
9169
9170 val = get_param(cmd, "TID");
9171 if (val)
9172 tid = atoi(val);
9173
9174 if (tid == -1) {
9175 send_resp(dut, conn, SIGMA_ERROR,
9176 "ErrorCode,sta_send_addba tid invalid");
9177 return 0;
9178 }
9179
9180 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
9181
9182 ifindex = if_nametoindex(intf);
9183 if (ifindex == 0) {
9184 sigma_dut_print(dut, DUT_MSG_ERROR,
9185 "%s: Index for interface %s failed",
9186 __func__, intf);
9187 send_resp(dut, conn, SIGMA_ERROR,
9188 "ErrorCode,sta_send_addba interface invalid");
9189 return 0;
9190 }
9191
9192 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
9193 NL80211_CMD_VENDOR)) ||
9194 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
9195 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
9196 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
9197 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
9198 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
9199 nla_put_u8(msg,
9200 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADD_DEL_BA_SESSION,
9201 QCA_WLAN_ADD_BA) ||
9202 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BA_TID,
9203 tid) ||
Kiran Kumar Lokere26e27582018-08-01 16:18:34 -07009204 nla_put_u16(msg,
9205 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE,
9206 bufsize)) {
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009207 sigma_dut_print(dut, DUT_MSG_ERROR,
9208 "%s: err in adding vendor_cmd and vendor_data",
9209 __func__);
9210 nlmsg_free(msg);
9211 send_resp(dut, conn, SIGMA_ERROR,
9212 "ErrorCode,sta_send_addba err in adding vendor_cmd and vendor_data");
9213 return 0;
9214 }
9215 nla_nest_end(msg, params);
9216
9217 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
9218 if (ret) {
9219 sigma_dut_print(dut, DUT_MSG_ERROR,
9220 "%s: err in send_and_recv_msgs, ret=%d",
9221 __func__, ret);
Sunil Dutt30605592018-05-04 20:35:50 +05309222 if (ret == -EOPNOTSUPP)
9223 return 1;
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009224 send_resp(dut, conn, SIGMA_ERROR,
9225 "ErrorCode,sta_send_addba err in send_and_recv_msgs");
9226 return 0;
9227 }
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009228#else /* NL80211_SUPPORT */
9229 sigma_dut_print(dut, DUT_MSG_ERROR,
9230 "sta_send_addba not supported without NL80211_SUPPORT defined");
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009231#endif /* NL80211_SUPPORT */
Sunil Dutt30605592018-05-04 20:35:50 +05309232
9233 return 1;
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009234}
9235
9236
Jouni Malinenf7222712019-06-13 01:50:21 +03009237static enum sigma_cmd_result cmd_sta_send_addba(struct sigma_dut *dut,
9238 struct sigma_conn *conn,
9239 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009240{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009241 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009242 case DRIVER_ATHEROS:
9243 return ath_sta_send_addba(dut, conn, cmd);
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009244 case DRIVER_WCN:
9245 return wcn_sta_send_addba(dut, conn, cmd);
Lior David9981b512017-01-20 13:16:40 +02009246#ifdef __linux__
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009247 case DRIVER_WIL6210:
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +02009248 return send_addba_60g(dut, conn, cmd, "Dest_mac");
Lior David9981b512017-01-20 13:16:40 +02009249#endif /* __linux__ */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009250 default:
9251 /*
9252 * There is no driver specific implementation for other drivers.
9253 * Ignore the command and report COMPLETE since the following
9254 * throughput test operation will end up sending ADDBA anyway.
9255 */
9256 return 1;
9257 }
9258}
9259
9260
9261int inject_eth_frame(int s, const void *data, size_t len,
9262 unsigned short ethtype, char *dst, char *src)
9263{
9264 struct iovec iov[4] = {
9265 {
9266 .iov_base = dst,
9267 .iov_len = ETH_ALEN,
9268 },
9269 {
9270 .iov_base = src,
9271 .iov_len = ETH_ALEN,
9272 },
9273 {
9274 .iov_base = &ethtype,
9275 .iov_len = sizeof(unsigned short),
9276 },
9277 {
9278 .iov_base = (void *) data,
9279 .iov_len = len,
9280 }
9281 };
9282 struct msghdr msg = {
9283 .msg_name = NULL,
9284 .msg_namelen = 0,
9285 .msg_iov = iov,
9286 .msg_iovlen = 4,
9287 .msg_control = NULL,
9288 .msg_controllen = 0,
9289 .msg_flags = 0,
9290 };
9291
9292 return sendmsg(s, &msg, 0);
9293}
9294
9295#if defined(__linux__) || defined(__QNXNTO__)
9296
9297int inject_frame(int s, const void *data, size_t len, int encrypt)
9298{
9299#define IEEE80211_RADIOTAP_F_WEP 0x04
9300#define IEEE80211_RADIOTAP_F_FRAG 0x08
9301 unsigned char rtap_hdr[] = {
9302 0x00, 0x00, /* radiotap version */
9303 0x0e, 0x00, /* radiotap length */
9304 0x02, 0xc0, 0x00, 0x00, /* bmap: flags, tx and rx flags */
9305 IEEE80211_RADIOTAP_F_FRAG, /* F_FRAG (fragment if required) */
9306 0x00, /* padding */
9307 0x00, 0x00, /* RX and TX flags to indicate that */
9308 0x00, 0x00, /* this is the injected frame directly */
9309 };
9310 struct iovec iov[2] = {
9311 {
9312 .iov_base = &rtap_hdr,
9313 .iov_len = sizeof(rtap_hdr),
9314 },
9315 {
9316 .iov_base = (void *) data,
9317 .iov_len = len,
9318 }
9319 };
9320 struct msghdr msg = {
9321 .msg_name = NULL,
9322 .msg_namelen = 0,
9323 .msg_iov = iov,
9324 .msg_iovlen = 2,
9325 .msg_control = NULL,
9326 .msg_controllen = 0,
9327 .msg_flags = 0,
9328 };
9329
9330 if (encrypt)
9331 rtap_hdr[8] |= IEEE80211_RADIOTAP_F_WEP;
9332
9333 return sendmsg(s, &msg, 0);
9334}
9335
9336
9337int open_monitor(const char *ifname)
9338{
9339#ifdef __QNXNTO__
9340 struct sockaddr_dl ll;
9341 int s;
9342
9343 memset(&ll, 0, sizeof(ll));
9344 ll.sdl_family = AF_LINK;
9345 ll.sdl_index = if_nametoindex(ifname);
9346 if (ll.sdl_index == 0) {
9347 perror("if_nametoindex");
9348 return -1;
9349 }
9350 s = socket(PF_INET, SOCK_RAW, 0);
9351#else /* __QNXNTO__ */
9352 struct sockaddr_ll ll;
9353 int s;
9354
9355 memset(&ll, 0, sizeof(ll));
9356 ll.sll_family = AF_PACKET;
9357 ll.sll_ifindex = if_nametoindex(ifname);
9358 if (ll.sll_ifindex == 0) {
9359 perror("if_nametoindex");
9360 return -1;
9361 }
9362 s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
9363#endif /* __QNXNTO__ */
9364 if (s < 0) {
9365 perror("socket[PF_PACKET,SOCK_RAW]");
9366 return -1;
9367 }
9368
9369 if (bind(s, (struct sockaddr *) &ll, sizeof(ll)) < 0) {
9370 perror("monitor socket bind");
9371 close(s);
9372 return -1;
9373 }
9374
9375 return s;
9376}
9377
9378
9379static int hex2num(char c)
9380{
9381 if (c >= '0' && c <= '9')
9382 return c - '0';
9383 if (c >= 'a' && c <= 'f')
9384 return c - 'a' + 10;
9385 if (c >= 'A' && c <= 'F')
9386 return c - 'A' + 10;
9387 return -1;
9388}
9389
9390
9391int hwaddr_aton(const char *txt, unsigned char *addr)
9392{
9393 int i;
9394
9395 for (i = 0; i < 6; i++) {
9396 int a, b;
9397
9398 a = hex2num(*txt++);
9399 if (a < 0)
9400 return -1;
9401 b = hex2num(*txt++);
9402 if (b < 0)
9403 return -1;
9404 *addr++ = (a << 4) | b;
9405 if (i < 5 && *txt++ != ':')
9406 return -1;
9407 }
9408
9409 return 0;
9410}
9411
9412#endif /* defined(__linux__) || defined(__QNXNTO__) */
9413
9414enum send_frame_type {
9415 DISASSOC, DEAUTH, SAQUERY, AUTH, ASSOCREQ, REASSOCREQ, DLS_REQ
9416};
9417enum send_frame_protection {
9418 CORRECT_KEY, INCORRECT_KEY, UNPROTECTED
9419};
9420
9421
9422static int sta_inject_frame(struct sigma_dut *dut, struct sigma_conn *conn,
9423 enum send_frame_type frame,
9424 enum send_frame_protection protected,
9425 const char *dest)
9426{
9427#ifdef __linux__
9428 unsigned char buf[1000], *pos;
9429 int s, res;
9430 char bssid[20], addr[20];
9431 char result[32], ssid[100];
9432 size_t ssid_len;
9433
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009434 if (get_wpa_status(get_station_ifname(dut), "wpa_state", result,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009435 sizeof(result)) < 0 ||
9436 strncmp(result, "COMPLETED", 9) != 0) {
9437 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Not connected");
9438 return 0;
9439 }
9440
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009441 if (get_wpa_status(get_station_ifname(dut), "bssid",
9442 bssid, sizeof(bssid)) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009443 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
9444 "current BSSID");
9445 return 0;
9446 }
9447
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009448 if (get_wpa_status(get_station_ifname(dut), "address",
9449 addr, sizeof(addr)) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009450 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
9451 "own MAC address");
9452 return 0;
9453 }
9454
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009455 if (get_wpa_status(get_station_ifname(dut), "ssid", ssid, sizeof(ssid))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009456 < 0) {
9457 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
9458 "current SSID");
9459 return 0;
9460 }
9461 ssid_len = strlen(ssid);
9462
9463 pos = buf;
9464
9465 /* Frame Control */
9466 switch (frame) {
9467 case DISASSOC:
9468 *pos++ = 0xa0;
9469 break;
9470 case DEAUTH:
9471 *pos++ = 0xc0;
9472 break;
9473 case SAQUERY:
9474 *pos++ = 0xd0;
9475 break;
9476 case AUTH:
9477 *pos++ = 0xb0;
9478 break;
9479 case ASSOCREQ:
9480 *pos++ = 0x00;
9481 break;
9482 case REASSOCREQ:
9483 *pos++ = 0x20;
9484 break;
9485 case DLS_REQ:
9486 *pos++ = 0xd0;
9487 break;
9488 }
9489
9490 if (protected == INCORRECT_KEY)
9491 *pos++ = 0x40; /* Set Protected field to 1 */
9492 else
9493 *pos++ = 0x00;
9494
9495 /* Duration */
9496 *pos++ = 0x00;
9497 *pos++ = 0x00;
9498
9499 /* addr1 = DA (current AP) */
9500 hwaddr_aton(bssid, pos);
9501 pos += 6;
9502 /* addr2 = SA (own address) */
9503 hwaddr_aton(addr, pos);
9504 pos += 6;
9505 /* addr3 = BSSID (current AP) */
9506 hwaddr_aton(bssid, pos);
9507 pos += 6;
9508
9509 /* Seq# (to be filled by driver/mac80211) */
9510 *pos++ = 0x00;
9511 *pos++ = 0x00;
9512
9513 if (protected == INCORRECT_KEY) {
9514 /* CCMP parameters */
9515 memcpy(pos, "\x61\x01\x00\x20\x00\x10\x00\x00", 8);
9516 pos += 8;
9517 }
9518
9519 if (protected == INCORRECT_KEY) {
9520 switch (frame) {
9521 case DEAUTH:
9522 /* Reason code (encrypted) */
9523 memcpy(pos, "\xa7\x39", 2);
9524 pos += 2;
9525 break;
9526 case DISASSOC:
9527 /* Reason code (encrypted) */
9528 memcpy(pos, "\xa7\x39", 2);
9529 pos += 2;
9530 break;
9531 case SAQUERY:
9532 /* Category|Action|TransID (encrypted) */
9533 memcpy(pos, "\x6f\xbd\xe9\x4d", 4);
9534 pos += 4;
9535 break;
9536 default:
9537 return -1;
9538 }
9539
9540 /* CCMP MIC */
9541 memcpy(pos, "\xc8\xd8\x3b\x06\x5d\xb7\x25\x68", 8);
9542 pos += 8;
9543 } else {
9544 switch (frame) {
9545 case DEAUTH:
9546 /* reason code = 8 */
9547 *pos++ = 0x08;
9548 *pos++ = 0x00;
9549 break;
9550 case DISASSOC:
9551 /* reason code = 8 */
9552 *pos++ = 0x08;
9553 *pos++ = 0x00;
9554 break;
9555 case SAQUERY:
9556 /* Category - SA Query */
9557 *pos++ = 0x08;
9558 /* SA query Action - Request */
9559 *pos++ = 0x00;
9560 /* Transaction ID */
9561 *pos++ = 0x12;
9562 *pos++ = 0x34;
9563 break;
9564 case AUTH:
9565 /* Auth Alg (Open) */
9566 *pos++ = 0x00;
9567 *pos++ = 0x00;
9568 /* Seq# */
9569 *pos++ = 0x01;
9570 *pos++ = 0x00;
9571 /* Status code */
9572 *pos++ = 0x00;
9573 *pos++ = 0x00;
9574 break;
9575 case ASSOCREQ:
9576 /* Capability Information */
9577 *pos++ = 0x31;
9578 *pos++ = 0x04;
9579 /* Listen Interval */
9580 *pos++ = 0x0a;
9581 *pos++ = 0x00;
9582 /* SSID */
9583 *pos++ = 0x00;
9584 *pos++ = ssid_len;
9585 memcpy(pos, ssid, ssid_len);
9586 pos += ssid_len;
9587 /* Supported Rates */
9588 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
9589 10);
9590 pos += 10;
9591 /* Extended Supported Rates */
9592 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
9593 pos += 6;
9594 /* RSN */
9595 memcpy(pos, "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00"
9596 "\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x02\xc0"
9597 "\x00\x00\x00\x00\x0f\xac\x06", 28);
9598 pos += 28;
9599 break;
9600 case REASSOCREQ:
9601 /* Capability Information */
9602 *pos++ = 0x31;
9603 *pos++ = 0x04;
9604 /* Listen Interval */
9605 *pos++ = 0x0a;
9606 *pos++ = 0x00;
9607 /* Current AP */
9608 hwaddr_aton(bssid, pos);
9609 pos += 6;
9610 /* SSID */
9611 *pos++ = 0x00;
9612 *pos++ = ssid_len;
9613 memcpy(pos, ssid, ssid_len);
9614 pos += ssid_len;
9615 /* Supported Rates */
9616 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
9617 10);
9618 pos += 10;
9619 /* Extended Supported Rates */
9620 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
9621 pos += 6;
9622 /* RSN */
9623 memcpy(pos, "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00"
9624 "\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x02\xc0"
9625 "\x00\x00\x00\x00\x0f\xac\x06", 28);
9626 pos += 28;
9627 break;
9628 case DLS_REQ:
9629 /* Category - DLS */
9630 *pos++ = 0x02;
9631 /* DLS Action - Request */
9632 *pos++ = 0x00;
9633 /* Destination MACAddress */
9634 if (dest)
9635 hwaddr_aton(dest, pos);
9636 else
9637 memset(pos, 0, 6);
9638 pos += 6;
9639 /* Source MACAddress */
9640 hwaddr_aton(addr, pos);
9641 pos += 6;
9642 /* Capability Information */
9643 *pos++ = 0x10; /* Privacy */
9644 *pos++ = 0x06; /* QoS */
9645 /* DLS Timeout Value */
9646 *pos++ = 0x00;
9647 *pos++ = 0x01;
9648 /* Supported rates */
9649 *pos++ = 0x01;
9650 *pos++ = 0x08;
9651 *pos++ = 0x0c; /* 6 Mbps */
9652 *pos++ = 0x12; /* 9 Mbps */
9653 *pos++ = 0x18; /* 12 Mbps */
9654 *pos++ = 0x24; /* 18 Mbps */
9655 *pos++ = 0x30; /* 24 Mbps */
9656 *pos++ = 0x48; /* 36 Mbps */
9657 *pos++ = 0x60; /* 48 Mbps */
9658 *pos++ = 0x6c; /* 54 Mbps */
9659 /* TODO: Extended Supported Rates */
9660 /* TODO: HT Capabilities */
9661 break;
9662 }
9663 }
9664
9665 s = open_monitor("sigmadut");
9666 if (s < 0) {
9667 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
9668 "monitor socket");
9669 return 0;
9670 }
9671
9672 res = inject_frame(s, buf, pos - buf, protected == CORRECT_KEY);
9673 if (res < 0) {
9674 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
9675 "inject frame");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05309676 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009677 return 0;
9678 }
9679 if (res < pos - buf) {
9680 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Only partial "
9681 "frame sent");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05309682 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009683 return 0;
9684 }
9685
9686 close(s);
9687
9688 return 1;
9689#else /* __linux__ */
9690 send_resp(dut, conn, SIGMA_ERROR, "errorCode,sta_send_frame not "
9691 "yet supported");
9692 return 0;
9693#endif /* __linux__ */
9694}
9695
9696
9697static int cmd_sta_send_frame_tdls(struct sigma_dut *dut,
9698 struct sigma_conn *conn,
9699 struct sigma_cmd *cmd)
9700{
9701 const char *intf = get_param(cmd, "Interface");
9702 const char *sta, *val;
9703 unsigned char addr[ETH_ALEN];
9704 char buf[100];
9705
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +03009706 if (!intf)
9707 return -1;
9708
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009709 sta = get_param(cmd, "peer");
9710 if (sta == NULL)
9711 sta = get_param(cmd, "station");
9712 if (sta == NULL) {
9713 send_resp(dut, conn, SIGMA_ERROR,
9714 "ErrorCode,Missing peer address");
9715 return 0;
9716 }
9717 if (hwaddr_aton(sta, addr) < 0) {
9718 send_resp(dut, conn, SIGMA_ERROR,
9719 "ErrorCode,Invalid peer address");
9720 return 0;
9721 }
9722
9723 val = get_param(cmd, "type");
9724 if (val == NULL)
9725 return -1;
9726
9727 if (strcasecmp(val, "DISCOVERY") == 0) {
9728 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", sta);
9729 if (wpa_command(intf, buf) < 0) {
9730 send_resp(dut, conn, SIGMA_ERROR,
9731 "ErrorCode,Failed to send TDLS discovery");
9732 return 0;
9733 }
9734 return 1;
9735 }
9736
9737 if (strcasecmp(val, "SETUP") == 0) {
9738 int status = 0, timeout = 0;
9739
9740 val = get_param(cmd, "Status");
9741 if (val)
9742 status = atoi(val);
9743
9744 val = get_param(cmd, "Timeout");
9745 if (val)
9746 timeout = atoi(val);
9747
9748 if (status != 0 && status != 37) {
9749 send_resp(dut, conn, SIGMA_ERROR,
9750 "ErrorCode,Unsupported status value");
9751 return 0;
9752 }
9753
9754 if (timeout != 0 && timeout != 301) {
9755 send_resp(dut, conn, SIGMA_ERROR,
9756 "ErrorCode,Unsupported timeout value");
9757 return 0;
9758 }
9759
9760 if (status && timeout) {
9761 send_resp(dut, conn, SIGMA_ERROR,
9762 "ErrorCode,Unsupported timeout+status "
9763 "combination");
9764 return 0;
9765 }
9766
9767 if (status == 37 &&
9768 wpa_command(intf, "SET tdls_testing 0x200")) {
9769 send_resp(dut, conn, SIGMA_ERROR,
9770 "ErrorCode,Failed to enable "
9771 "decline setup response test mode");
9772 return 0;
9773 }
9774
9775 if (timeout == 301) {
9776 int res;
9777 if (dut->no_tpk_expiration)
9778 res = wpa_command(intf,
9779 "SET tdls_testing 0x108");
9780 else
9781 res = wpa_command(intf,
9782 "SET tdls_testing 0x8");
9783 if (res) {
9784 send_resp(dut, conn, SIGMA_ERROR,
9785 "ErrorCode,Failed to set short TPK "
9786 "lifetime");
9787 return 0;
9788 }
9789 }
9790
9791 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", sta);
9792 if (wpa_command(intf, buf) < 0) {
9793 send_resp(dut, conn, SIGMA_ERROR,
9794 "ErrorCode,Failed to send TDLS setup");
9795 return 0;
9796 }
9797 return 1;
9798 }
9799
9800 if (strcasecmp(val, "TEARDOWN") == 0) {
9801 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", sta);
9802 if (wpa_command(intf, buf) < 0) {
9803 send_resp(dut, conn, SIGMA_ERROR,
9804 "ErrorCode,Failed to send TDLS teardown");
9805 return 0;
9806 }
9807 return 1;
9808 }
9809
9810 send_resp(dut, conn, SIGMA_ERROR,
9811 "ErrorCode,Unsupported TDLS frame");
9812 return 0;
9813}
9814
9815
9816static int sta_ap_known(const char *ifname, const char *bssid)
9817{
9818 char buf[4096];
9819
Jouni Malinendd32f192018-09-15 02:55:19 +03009820 snprintf(buf, sizeof(buf), "BSS MASK=1 %s", bssid);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009821 if (wpa_command_resp(ifname, buf, buf, sizeof(buf)) < 0)
9822 return 0;
9823 if (strncmp(buf, "id=", 3) != 0)
9824 return 0;
9825 return 1;
9826}
9827
9828
9829static int sta_scan_ap(struct sigma_dut *dut, const char *ifname,
9830 const char *bssid)
9831{
9832 int res;
9833 struct wpa_ctrl *ctrl;
9834 char buf[256];
9835
9836 if (sta_ap_known(ifname, bssid))
9837 return 0;
9838 sigma_dut_print(dut, DUT_MSG_DEBUG,
9839 "AP not in BSS table - start scan");
9840
9841 ctrl = open_wpa_mon(ifname);
9842 if (ctrl == NULL) {
9843 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
9844 "wpa_supplicant monitor connection");
9845 return -1;
9846 }
9847
9848 if (wpa_command(ifname, "SCAN") < 0) {
9849 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to start scan");
9850 wpa_ctrl_detach(ctrl);
9851 wpa_ctrl_close(ctrl);
9852 return -1;
9853 }
9854
9855 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
9856 buf, sizeof(buf));
9857
9858 wpa_ctrl_detach(ctrl);
9859 wpa_ctrl_close(ctrl);
9860
9861 if (res < 0) {
9862 sigma_dut_print(dut, DUT_MSG_INFO, "Scan did not complete");
9863 return -1;
9864 }
9865
9866 if (sta_ap_known(ifname, bssid))
9867 return 0;
9868 sigma_dut_print(dut, DUT_MSG_INFO, "AP not in BSS table");
9869 return -1;
9870}
9871
9872
9873static int cmd_sta_send_frame_hs2_neighadv(struct sigma_dut *dut,
9874 struct sigma_conn *conn,
9875 struct sigma_cmd *cmd,
9876 const char *intf)
9877{
9878 char buf[200];
9879
9880 snprintf(buf, sizeof(buf), "ndsend 2001:DB8::1 %s", intf);
9881 if (system(buf) != 0) {
9882 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Failed to run "
9883 "ndsend");
9884 return 0;
9885 }
9886
9887 return 1;
9888}
9889
9890
9891static int cmd_sta_send_frame_hs2_neighsolreq(struct sigma_dut *dut,
9892 struct sigma_conn *conn,
9893 struct sigma_cmd *cmd,
9894 const char *intf)
9895{
9896 char buf[200];
9897 const char *ip = get_param(cmd, "SenderIP");
9898
Peng Xu26b356d2017-10-04 17:58:16 -07009899 if (!ip)
9900 return 0;
9901
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009902 snprintf(buf, sizeof(buf), "ndisc6 -nm %s %s -r 4", ip, intf);
9903 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
9904 if (system(buf) == 0) {
9905 sigma_dut_print(dut, DUT_MSG_INFO,
9906 "Neighbor Solicitation got a response "
9907 "for %s@%s", ip, intf);
9908 }
9909
9910 return 1;
9911}
9912
9913
9914static int cmd_sta_send_frame_hs2_arpprobe(struct sigma_dut *dut,
9915 struct sigma_conn *conn,
9916 struct sigma_cmd *cmd,
9917 const char *ifname)
9918{
9919 char buf[200];
9920 const char *ip = get_param(cmd, "SenderIP");
9921
9922 if (ip == NULL) {
9923 send_resp(dut, conn, SIGMA_ERROR,
9924 "ErrorCode,Missing SenderIP parameter");
9925 return 0;
9926 }
9927 snprintf(buf, sizeof(buf), "arping -I %s -D %s -c 4", ifname, ip);
9928 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
9929 if (system(buf) != 0) {
9930 sigma_dut_print(dut, DUT_MSG_INFO, "arping DAD got a response "
9931 "for %s@%s", ip, ifname);
9932 }
9933
9934 return 1;
9935}
9936
9937
9938static int cmd_sta_send_frame_hs2_arpannounce(struct sigma_dut *dut,
9939 struct sigma_conn *conn,
9940 struct sigma_cmd *cmd,
9941 const char *ifname)
9942{
9943 char buf[200];
9944 char ip[16];
9945 int s;
Peng Xub3756882017-10-04 14:39:09 -07009946 struct ifreq ifr;
9947 struct sockaddr_in saddr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009948
9949 s = socket(PF_INET, SOCK_DGRAM, 0);
Peng Xub3756882017-10-04 14:39:09 -07009950 if (s < 0) {
9951 perror("socket");
9952 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009953 }
9954
Peng Xub3756882017-10-04 14:39:09 -07009955 memset(&ifr, 0, sizeof(ifr));
9956 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
9957 if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
9958 sigma_dut_print(dut, DUT_MSG_INFO,
9959 "Failed to get %s IP address: %s",
9960 ifname, strerror(errno));
9961 close(s);
9962 return -1;
9963 }
9964 close(s);
9965
9966 memcpy(&saddr, &ifr.ifr_addr, sizeof(struct sockaddr_in));
9967 strlcpy(ip, inet_ntoa(saddr.sin_addr), sizeof(ip));
9968
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009969 snprintf(buf, sizeof(buf), "arping -I %s -s %s %s -c 4", ifname, ip,
9970 ip);
9971 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
9972 if (system(buf) != 0) {
9973 }
9974
9975 return 1;
9976}
9977
9978
9979static int cmd_sta_send_frame_hs2_arpreply(struct sigma_dut *dut,
9980 struct sigma_conn *conn,
9981 struct sigma_cmd *cmd,
9982 const char *ifname)
9983{
9984 char buf[200], addr[20];
9985 char dst[ETH_ALEN], src[ETH_ALEN];
9986 short ethtype = htons(ETH_P_ARP);
9987 char *pos;
9988 int s, res;
9989 const char *val;
9990 struct sockaddr_in taddr;
9991
9992 val = get_param(cmd, "dest");
9993 if (val)
9994 hwaddr_aton(val, (unsigned char *) dst);
9995
9996 val = get_param(cmd, "DestIP");
9997 if (val)
9998 inet_aton(val, &taddr.sin_addr);
Peng Xu151c9e12017-10-04 14:39:09 -07009999 else
10000 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010001
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010002 if (get_wpa_status(get_station_ifname(dut), "address", addr,
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010003 sizeof(addr)) < 0)
10004 return -2;
10005 hwaddr_aton(addr, (unsigned char *) src);
10006
10007 pos = buf;
10008 *pos++ = 0x00;
10009 *pos++ = 0x01;
10010 *pos++ = 0x08;
10011 *pos++ = 0x00;
10012 *pos++ = 0x06;
10013 *pos++ = 0x04;
10014 *pos++ = 0x00;
10015 *pos++ = 0x02;
10016 memcpy(pos, src, ETH_ALEN);
10017 pos += ETH_ALEN;
10018 memcpy(pos, &taddr.sin_addr, 4);
10019 pos += 4;
10020 memcpy(pos, dst, ETH_ALEN);
10021 pos += ETH_ALEN;
10022 memcpy(pos, &taddr.sin_addr, 4);
10023 pos += 4;
10024
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010025 s = open_monitor(get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010026 if (s < 0) {
10027 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
10028 "monitor socket");
10029 return 0;
10030 }
10031
10032 res = inject_eth_frame(s, buf, pos - buf, ethtype, dst, src);
10033 if (res < 0) {
10034 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
10035 "inject frame");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +053010036 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010037 return 0;
10038 }
10039
10040 close(s);
10041
10042 return 1;
10043}
10044
10045
10046static int cmd_sta_send_frame_hs2_dls_req(struct sigma_dut *dut,
10047 struct sigma_conn *conn,
10048 struct sigma_cmd *cmd,
10049 const char *intf, const char *dest)
10050{
10051 char buf[100];
10052
10053 if (if_nametoindex("sigmadut") == 0) {
10054 snprintf(buf, sizeof(buf),
10055 "iw dev %s interface add sigmadut type monitor",
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010056 get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010057 if (system(buf) != 0 ||
10058 if_nametoindex("sigmadut") == 0) {
10059 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
10060 "monitor interface with '%s'", buf);
10061 return -2;
10062 }
10063 }
10064
10065 if (system("ifconfig sigmadut up") != 0) {
10066 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
10067 "monitor interface up");
10068 return -2;
10069 }
10070
10071 return sta_inject_frame(dut, conn, DLS_REQ, UNPROTECTED, dest);
10072}
10073
10074
10075static int cmd_sta_send_frame_hs2(struct sigma_dut *dut,
10076 struct sigma_conn *conn,
10077 struct sigma_cmd *cmd)
10078{
10079 const char *intf = get_param(cmd, "Interface");
10080 const char *dest = get_param(cmd, "Dest");
10081 const char *type = get_param(cmd, "FrameName");
10082 const char *val;
10083 char buf[200], *pos, *end;
10084 int count, count2;
10085
10086 if (type == NULL)
10087 type = get_param(cmd, "Type");
10088
10089 if (intf == NULL || dest == NULL || type == NULL)
10090 return -1;
10091
10092 if (strcasecmp(type, "NeighAdv") == 0)
10093 return cmd_sta_send_frame_hs2_neighadv(dut, conn, cmd, intf);
10094
10095 if (strcasecmp(type, "NeighSolicitReq") == 0)
10096 return cmd_sta_send_frame_hs2_neighsolreq(dut, conn, cmd, intf);
10097
10098 if (strcasecmp(type, "ARPProbe") == 0)
10099 return cmd_sta_send_frame_hs2_arpprobe(dut, conn, cmd, intf);
10100
10101 if (strcasecmp(type, "ARPAnnounce") == 0)
10102 return cmd_sta_send_frame_hs2_arpannounce(dut, conn, cmd, intf);
10103
10104 if (strcasecmp(type, "ARPReply") == 0)
10105 return cmd_sta_send_frame_hs2_arpreply(dut, conn, cmd, intf);
10106
10107 if (strcasecmp(type, "DLS-request") == 0 ||
10108 strcasecmp(type, "DLSrequest") == 0)
10109 return cmd_sta_send_frame_hs2_dls_req(dut, conn, cmd, intf,
10110 dest);
10111
10112 if (strcasecmp(type, "ANQPQuery") != 0 &&
10113 strcasecmp(type, "Query") != 0) {
10114 send_resp(dut, conn, SIGMA_ERROR,
10115 "ErrorCode,Unsupported HS 2.0 send frame type");
10116 return 0;
10117 }
10118
10119 if (sta_scan_ap(dut, intf, dest) < 0) {
10120 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not find "
10121 "the requested AP");
10122 return 0;
10123 }
10124
10125 pos = buf;
10126 end = buf + sizeof(buf);
10127 count = 0;
10128 pos += snprintf(pos, end - pos, "ANQP_GET %s ", dest);
10129
10130 val = get_param(cmd, "ANQP_CAP_LIST");
10131 if (val && atoi(val)) {
10132 pos += snprintf(pos, end - pos, "%s257", count > 0 ? "," : "");
10133 count++;
10134 }
10135
10136 val = get_param(cmd, "VENUE_NAME");
10137 if (val && atoi(val)) {
10138 pos += snprintf(pos, end - pos, "%s258", count > 0 ? "," : "");
10139 count++;
10140 }
10141
10142 val = get_param(cmd, "NETWORK_AUTH_TYPE");
10143 if (val && atoi(val)) {
10144 pos += snprintf(pos, end - pos, "%s260", count > 0 ? "," : "");
10145 count++;
10146 }
10147
10148 val = get_param(cmd, "ROAMING_CONS");
10149 if (val && atoi(val)) {
10150 pos += snprintf(pos, end - pos, "%s261", count > 0 ? "," : "");
10151 count++;
10152 }
10153
10154 val = get_param(cmd, "IP_ADDR_TYPE_AVAILABILITY");
10155 if (val && atoi(val)) {
10156 pos += snprintf(pos, end - pos, "%s262", count > 0 ? "," : "");
10157 count++;
10158 }
10159
10160 val = get_param(cmd, "NAI_REALM_LIST");
10161 if (val && atoi(val)) {
10162 pos += snprintf(pos, end - pos, "%s263", count > 0 ? "," : "");
10163 count++;
10164 }
10165
10166 val = get_param(cmd, "3GPP_INFO");
10167 if (val && atoi(val)) {
10168 pos += snprintf(pos, end - pos, "%s264", count > 0 ? "," : "");
10169 count++;
10170 }
10171
10172 val = get_param(cmd, "DOMAIN_LIST");
10173 if (val && atoi(val)) {
10174 pos += snprintf(pos, end - pos, "%s268", count > 0 ? "," : "");
10175 count++;
10176 }
10177
Jouni Malinen34cf9532018-04-29 19:26:33 +030010178 val = get_param(cmd, "Venue_URL");
10179 if (val && atoi(val)) {
10180 pos += snprintf(pos, end - pos, "%s277", count > 0 ? "," : "");
10181 count++;
10182 }
10183
Jouni Malinend3bca5d2018-04-29 17:25:23 +030010184 val = get_param(cmd, "Advice_Of_Charge");
10185 if (val && atoi(val)) {
10186 pos += snprintf(pos, end - pos, "%s278", count > 0 ? "," : "");
10187 count++;
10188 }
10189
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010190 if (count && wpa_command(intf, buf)) {
10191 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,ANQP_GET failed");
10192 return 0;
10193 }
10194
10195 pos = buf;
10196 end = buf + sizeof(buf);
10197 count2 = 0;
10198 pos += snprintf(pos, end - pos, "HS20_ANQP_GET %s ", dest);
10199
10200 val = get_param(cmd, "HS_CAP_LIST");
10201 if (val && atoi(val)) {
10202 pos += snprintf(pos, end - pos, "%s2", count2 > 0 ? "," : "");
10203 count2++;
10204 }
10205
10206 val = get_param(cmd, "OPER_NAME");
10207 if (val && atoi(val)) {
10208 pos += snprintf(pos, end - pos, "%s3", count2 > 0 ? "," : "");
10209 count2++;
10210 }
10211
10212 val = get_param(cmd, "WAN_METRICS");
10213 if (!val)
10214 val = get_param(cmd, "WAN_MAT");
10215 if (!val)
10216 val = get_param(cmd, "WAN_MET");
10217 if (val && atoi(val)) {
10218 pos += snprintf(pos, end - pos, "%s4", count2 > 0 ? "," : "");
10219 count2++;
10220 }
10221
10222 val = get_param(cmd, "CONNECTION_CAPABILITY");
10223 if (val && atoi(val)) {
10224 pos += snprintf(pos, end - pos, "%s5", count2 > 0 ? "," : "");
10225 count2++;
10226 }
10227
10228 val = get_param(cmd, "OP_CLASS");
10229 if (val && atoi(val)) {
10230 pos += snprintf(pos, end - pos, "%s7", count2 > 0 ? "," : "");
10231 count2++;
10232 }
10233
10234 val = get_param(cmd, "OSU_PROVIDER_LIST");
10235 if (val && atoi(val)) {
10236 pos += snprintf(pos, end - pos, "%s8", count2 > 0 ? "," : "");
10237 count2++;
10238 }
10239
Jouni Malinenf67afec2018-04-29 19:24:58 +030010240 val = get_param(cmd, "OPER_ICON_METADATA");
10241 if (!val)
10242 val = get_param(cmd, "OPERATOR_ICON_METADATA");
10243 if (val && atoi(val)) {
10244 pos += snprintf(pos, end - pos, "%s12", count2 > 0 ? "," : "");
10245 count2++;
10246 }
10247
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010248 if (count && count2) {
10249 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before sending out "
10250 "second query");
10251 sleep(1);
10252 }
10253
10254 if (count2 && wpa_command(intf, buf)) {
10255 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,HS20_ANQP_GET "
10256 "failed");
10257 return 0;
10258 }
10259
10260 val = get_param(cmd, "NAI_HOME_REALM_LIST");
10261 if (val) {
10262 if (count || count2) {
10263 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
10264 "sending out second query");
10265 sleep(1);
10266 }
10267
10268 if (strcmp(val, "1") == 0)
10269 val = "mail.example.com";
10270 snprintf(buf, end - pos,
10271 "HS20_GET_NAI_HOME_REALM_LIST %s realm=%s",
10272 dest, val);
10273 if (wpa_command(intf, buf)) {
10274 send_resp(dut, conn, SIGMA_ERROR,
10275 "ErrorCode,HS20_GET_NAI_HOME_REALM_LIST "
10276 "failed");
10277 return 0;
10278 }
10279 }
10280
10281 val = get_param(cmd, "ICON_REQUEST");
10282 if (val) {
10283 if (count || count2) {
10284 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
10285 "sending out second query");
10286 sleep(1);
10287 }
10288
10289 snprintf(buf, end - pos,
10290 "HS20_ICON_REQUEST %s %s", dest, val);
10291 if (wpa_command(intf, buf)) {
10292 send_resp(dut, conn, SIGMA_ERROR,
10293 "ErrorCode,HS20_ICON_REQUEST failed");
10294 return 0;
10295 }
10296 }
10297
10298 return 1;
10299}
10300
10301
10302static int ath_sta_send_frame_vht(struct sigma_dut *dut,
10303 struct sigma_conn *conn,
10304 struct sigma_cmd *cmd)
10305{
10306 const char *val;
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010307 const char *ifname;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010308 int chwidth, nss;
10309
10310 val = get_param(cmd, "framename");
10311 if (!val)
10312 return -1;
10313 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
10314
10315 /* Command sequence to generate Op mode notification */
10316 if (val && strcasecmp(val, "Op_md_notif_frm") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010317 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010318
10319 /* Disable STBC */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010320 run_iwpriv(dut, ifname, "tx_stbc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010321
10322 /* Extract Channel width */
10323 val = get_param(cmd, "Channel_width");
10324 if (val) {
10325 switch (atoi(val)) {
10326 case 20:
10327 chwidth = 0;
10328 break;
10329 case 40:
10330 chwidth = 1;
10331 break;
10332 case 80:
10333 chwidth = 2;
10334 break;
10335 case 160:
10336 chwidth = 3;
10337 break;
10338 default:
10339 chwidth = 2;
10340 break;
10341 }
10342
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010343 run_iwpriv(dut, ifname, "chwidth %d", chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010344 }
10345
10346 /* Extract NSS */
10347 val = get_param(cmd, "NSS");
10348 if (val) {
10349 switch (atoi(val)) {
10350 case 1:
10351 nss = 1;
10352 break;
10353 case 2:
10354 nss = 3;
10355 break;
10356 case 3:
10357 nss = 7;
10358 break;
10359 default:
10360 /* We do not support NSS > 3 */
10361 nss = 3;
10362 break;
10363 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010364 run_iwpriv(dut, ifname, "rxchainmask %d", nss);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010365 }
10366
10367 /* Opmode notify */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010368 run_iwpriv(dut, ifname, "opmode_notify 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010369 }
10370
10371 return 1;
10372}
10373
10374
10375static int cmd_sta_send_frame_vht(struct sigma_dut *dut,
10376 struct sigma_conn *conn,
10377 struct sigma_cmd *cmd)
10378{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010379 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010380 case DRIVER_ATHEROS:
10381 return ath_sta_send_frame_vht(dut, conn, cmd);
10382 default:
10383 send_resp(dut, conn, SIGMA_ERROR,
10384 "errorCode,Unsupported sta_set_frame(VHT) with the current driver");
10385 return 0;
10386 }
10387}
10388
10389
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070010390static int wcn_sta_send_frame_he(struct sigma_dut *dut, struct sigma_conn *conn,
10391 struct sigma_cmd *cmd)
10392{
10393 const char *val;
10394 const char *intf = get_param(cmd, "Interface");
10395
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +030010396 if (!intf)
10397 return -1;
10398
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070010399 val = get_param(cmd, "framename");
10400 if (!val)
10401 return -1;
10402 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
10403
10404 /* Command sequence to generate Op mode notification */
10405 if (val && strcasecmp(val, "action") == 0) {
10406 val = get_param(cmd, "PPDUTxType");
10407 if (val && strcasecmp(val, "TB") == 0) {
10408 if (sta_set_action_tx_in_he_tb_ppdu(dut, intf, 1)) {
10409 sigma_dut_print(dut, DUT_MSG_ERROR,
10410 "failed to send TB PPDU Tx cfg");
10411 send_resp(dut, conn, SIGMA_ERROR,
10412 "ErrorCode,set TB PPDU Tx cfg failed");
10413 return 0;
10414 }
10415 return 1;
10416 }
10417
10418 sigma_dut_print(dut, DUT_MSG_ERROR,
10419 "Action Tx type is not defined");
10420 }
10421
10422 return 1;
10423}
10424
10425
10426static int cmd_sta_send_frame_he(struct sigma_dut *dut,
10427 struct sigma_conn *conn,
10428 struct sigma_cmd *cmd)
10429{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010430 switch (get_driver_type(dut)) {
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070010431 case DRIVER_WCN:
10432 return wcn_sta_send_frame_he(dut, conn, cmd);
10433 default:
10434 send_resp(dut, conn, SIGMA_ERROR,
10435 "errorCode,Unsupported sta_set_frame(HE) with the current driver");
10436 return 0;
10437 }
10438}
10439
10440
Lior David0fe101e2017-03-09 16:09:50 +020010441#ifdef __linux__
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030010442
10443static int
10444wil6210_send_p2p_frame_60g(struct sigma_dut *dut, struct sigma_cmd *cmd,
10445 const char *frame_name, const char *dest_mac)
10446{
10447 int isprobereq = strcasecmp(frame_name, "probereq") == 0;
10448 const char *ssid = get_param(cmd, "ssid");
10449 const char *countstr = get_param(cmd, "count");
10450 const char *channelstr = get_param(cmd, "channel");
10451 const char *group_id = get_param(cmd, "groupid");
10452 const char *client_id = get_param(cmd, "clientmac");
10453 int count, channel, freq, i;
10454 const char *fname;
10455 char frame[1024], src_mac[20], group_id_attr[25],
10456 device_macstr[3 * ETH_ALEN], client_mac[ETH_ALEN];
10457 const char *group_ssid;
10458 const int group_ssid_prefix_len = 9;
10459 struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *) frame;
10460 size_t framelen = sizeof(frame);
10461 struct template_frame_tag tags[2];
10462 size_t tags_total = ARRAY_SIZE(tags);
10463 int tag_index, len, dst_len;
10464
10465 if (!countstr || !channelstr) {
10466 sigma_dut_print(dut, DUT_MSG_ERROR,
10467 "Missing argument: count, channel");
10468 return -1;
10469 }
10470 if (isprobereq && !ssid) {
10471 sigma_dut_print(dut, DUT_MSG_ERROR,
10472 "Missing argument: ssid");
10473 return -1;
10474 }
10475 if (!isprobereq && (!group_id || !client_id)) {
10476 sigma_dut_print(dut, DUT_MSG_ERROR,
10477 "Missing argument: group_id, client_id");
10478 return -1;
10479 }
10480
10481 count = atoi(countstr);
10482 channel = atoi(channelstr);
10483 freq = channel_to_freq(dut, channel);
10484
10485 if (!freq) {
10486 sigma_dut_print(dut, DUT_MSG_ERROR,
10487 "invalid channel: %s", channelstr);
10488 return -1;
10489 }
10490
10491 if (isprobereq) {
10492 if (strcasecmp(ssid, "wildcard") == 0) {
10493 fname = "probe_req_wildcard.txt";
10494 } else if (strcasecmp(ssid, "P2P_Wildcard") == 0) {
10495 fname = "probe_req_P2P_Wildcard.txt";
10496 } else {
10497 sigma_dut_print(dut, DUT_MSG_ERROR,
10498 "invalid probe request type");
10499 return -1;
10500 }
10501 } else {
10502 fname = "P2P_device_discovery_req.txt";
10503 }
10504
10505 if (parse_template_frame_file(dut, fname, frame, &framelen,
10506 tags, &tags_total)) {
10507 sigma_dut_print(dut, DUT_MSG_ERROR,
10508 "invalid frame template: %s", fname);
10509 return -1;
10510 }
10511
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010512 if (get_wpa_status(get_station_ifname(dut), "address",
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030010513 src_mac, sizeof(src_mac)) < 0 ||
10514 parse_mac_address(dut, src_mac, &hdr->addr2[0]) ||
10515 parse_mac_address(dut, dest_mac, &hdr->addr1[0]))
10516 return -1;
10517 /* Use wildcard BSSID, since we are in PBSS */
10518 memset(&hdr->addr3, 0xFF, ETH_ALEN);
10519
10520 if (!isprobereq) {
10521 tag_index = find_template_frame_tag(tags, tags_total, 1);
10522 if (tag_index < 0) {
10523 sigma_dut_print(dut, DUT_MSG_ERROR,
10524 "can't find device id attribute");
10525 return -1;
10526 }
10527 if (parse_mac_address(dut, client_id,
10528 (unsigned char *) client_mac)) {
10529 sigma_dut_print(dut, DUT_MSG_ERROR,
10530 "invalid client_id: %s", client_id);
10531 return -1;
10532 }
10533 if (replace_p2p_attribute(dut, &frame[tags[tag_index].offset],
10534 framelen - tags[tag_index].offset,
10535 IEEE80211_P2P_ATTR_DEVICE_ID,
10536 client_mac, ETH_ALEN)) {
10537 sigma_dut_print(dut, DUT_MSG_ERROR,
10538 "fail to replace device id attribute");
10539 return -1;
10540 }
10541
10542 /*
10543 * group_id arg contains device MAC address followed by
10544 * space and SSID (DIRECT-somessid).
10545 * group id attribute contains device address (6 bytes)
10546 * followed by SSID prefix DIRECT-XX (9 bytes)
10547 */
10548 if (strlen(group_id) < sizeof(device_macstr)) {
10549 sigma_dut_print(dut, DUT_MSG_ERROR,
10550 "group_id arg too short");
10551 return -1;
10552 }
10553 memcpy(device_macstr, group_id, sizeof(device_macstr));
10554 device_macstr[sizeof(device_macstr) - 1] = '\0';
10555 if (parse_mac_address(dut, device_macstr,
10556 (unsigned char *) group_id_attr)) {
10557 sigma_dut_print(dut, DUT_MSG_ERROR,
10558 "fail to parse device address from group_id");
10559 return -1;
10560 }
10561 group_ssid = strchr(group_id, ' ');
10562 if (!group_ssid) {
10563 sigma_dut_print(dut, DUT_MSG_ERROR,
10564 "invalid group_id arg, no ssid");
10565 return -1;
10566 }
10567 group_ssid++;
10568 len = strlen(group_ssid);
10569 if (len < group_ssid_prefix_len) {
10570 sigma_dut_print(dut, DUT_MSG_ERROR,
10571 "group_id SSID too short");
10572 return -1;
10573 }
10574 dst_len = sizeof(group_id_attr) - ETH_ALEN;
10575 if (len > dst_len) {
10576 sigma_dut_print(dut, DUT_MSG_ERROR,
10577 "group_id SSID (%s) too long",
10578 group_ssid);
10579 return -1;
10580 }
10581
10582 memcpy(group_id_attr + ETH_ALEN, group_ssid, len);
10583 tag_index = find_template_frame_tag(tags, tags_total, 2);
10584 if (tag_index < 0) {
10585 sigma_dut_print(dut, DUT_MSG_ERROR,
10586 "can't find group id attribute");
10587 return -1;
10588 }
10589 if (replace_p2p_attribute(dut, &frame[tags[tag_index].offset],
10590 framelen - tags[tag_index].offset,
10591 IEEE80211_P2P_ATTR_GROUP_ID,
10592 group_id_attr,
10593 sizeof(group_id_attr))) {
10594 sigma_dut_print(dut, DUT_MSG_ERROR,
10595 "fail to replace group id attribute");
10596 return -1;
10597 }
10598 }
10599
10600 for (i = 0; i < count; i++) {
10601 if (wil6210_transmit_frame(dut, freq,
10602 WIL_TRANSMIT_FRAME_DEFAULT_ROC,
10603 frame, framelen)) {
10604 sigma_dut_print(dut, DUT_MSG_ERROR,
10605 "fail to transmit probe request frame");
10606 return -1;
10607 }
10608 }
10609
10610 return 0;
10611}
10612
10613
Lior David0fe101e2017-03-09 16:09:50 +020010614int wil6210_send_frame_60g(struct sigma_dut *dut, struct sigma_conn *conn,
10615 struct sigma_cmd *cmd)
10616{
10617 const char *frame_name = get_param(cmd, "framename");
10618 const char *mac = get_param(cmd, "dest_mac");
10619
10620 if (!frame_name || !mac) {
10621 sigma_dut_print(dut, DUT_MSG_ERROR,
10622 "framename and dest_mac must be provided");
10623 return -1;
10624 }
10625
10626 if (strcasecmp(frame_name, "brp") == 0) {
10627 const char *l_rx = get_param(cmd, "L-RX");
10628 int l_rx_i;
10629
10630 if (!l_rx) {
10631 sigma_dut_print(dut, DUT_MSG_ERROR,
10632 "L-RX must be provided");
10633 return -1;
10634 }
10635 l_rx_i = atoi(l_rx);
10636
10637 sigma_dut_print(dut, DUT_MSG_INFO,
10638 "dev_send_frame: BRP-RX, dest_mac %s, L-RX %s",
10639 mac, l_rx);
10640 if (l_rx_i != 16) {
10641 sigma_dut_print(dut, DUT_MSG_ERROR,
10642 "unsupported L-RX: %s", l_rx);
10643 return -1;
10644 }
10645
10646 if (wil6210_send_brp_rx(dut, mac, l_rx_i))
10647 return -1;
10648 } else if (strcasecmp(frame_name, "ssw") == 0) {
10649 sigma_dut_print(dut, DUT_MSG_INFO,
10650 "dev_send_frame: SLS, dest_mac %s", mac);
10651 if (wil6210_send_sls(dut, mac))
10652 return -1;
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030010653 } else if ((strcasecmp(frame_name, "probereq") == 0) ||
10654 (strcasecmp(frame_name, "devdiscreq") == 0)) {
10655 sigma_dut_print(dut, DUT_MSG_INFO,
10656 "dev_send_frame: %s, dest_mac %s", frame_name,
10657 mac);
10658 if (wil6210_send_p2p_frame_60g(dut, cmd, frame_name, mac))
10659 return -1;
Lior David0fe101e2017-03-09 16:09:50 +020010660 } else {
10661 sigma_dut_print(dut, DUT_MSG_ERROR,
10662 "unsupported frame type: %s", frame_name);
10663 return -1;
10664 }
10665
10666 return 1;
10667}
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030010668
Lior David0fe101e2017-03-09 16:09:50 +020010669#endif /* __linux__ */
10670
10671
10672static int cmd_sta_send_frame_60g(struct sigma_dut *dut,
10673 struct sigma_conn *conn,
10674 struct sigma_cmd *cmd)
10675{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010676 switch (get_driver_type(dut)) {
Lior David0fe101e2017-03-09 16:09:50 +020010677#ifdef __linux__
10678 case DRIVER_WIL6210:
10679 return wil6210_send_frame_60g(dut, conn, cmd);
10680#endif /* __linux__ */
10681 default:
10682 send_resp(dut, conn, SIGMA_ERROR,
10683 "errorCode,Unsupported sta_set_frame(60G) with the current driver");
10684 return 0;
10685 }
10686}
10687
10688
Ashwini Patildb59b3c2017-04-13 15:19:23 +053010689static int mbo_send_anqp_query(struct sigma_dut *dut, struct sigma_conn *conn,
10690 const char *intf, struct sigma_cmd *cmd)
10691{
10692 const char *val, *addr;
10693 char buf[100];
10694
10695 addr = get_param(cmd, "DestMac");
10696 if (!addr) {
10697 send_resp(dut, conn, SIGMA_INVALID,
10698 "ErrorCode,AP MAC address is missing");
10699 return 0;
10700 }
10701
10702 val = get_param(cmd, "ANQPQuery_ID");
10703 if (!val) {
10704 send_resp(dut, conn, SIGMA_INVALID,
10705 "ErrorCode,Missing ANQPQuery_ID");
10706 return 0;
10707 }
10708
10709 if (strcasecmp(val, "NeighborReportReq") == 0) {
10710 snprintf(buf, sizeof(buf), "ANQP_GET %s 272", addr);
10711 } else if (strcasecmp(val, "QueryListWithCellPref") == 0) {
10712 snprintf(buf, sizeof(buf), "ANQP_GET %s 272,mbo:2", addr);
10713 } else {
10714 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid ANQPQuery_ID: %s",
10715 val);
10716 send_resp(dut, conn, SIGMA_INVALID,
10717 "ErrorCode,Invalid ANQPQuery_ID");
10718 return 0;
10719 }
10720
Ashwini Patild174f2c2017-04-13 16:49:46 +053010721 /* Set gas_address3 field to IEEE 802.11-2012 standard compliant form
10722 * (Address3 = Wildcard BSSID when sent to not-associated AP;
10723 * if associated, AP BSSID).
10724 */
10725 if (wpa_command(intf, "SET gas_address3 1") < 0) {
10726 send_resp(dut, conn, SIGMA_ERROR,
10727 "ErrorCode,Failed to set gas_address3");
10728 return 0;
10729 }
10730
Ashwini Patildb59b3c2017-04-13 15:19:23 +053010731 if (wpa_command(intf, buf) < 0) {
10732 send_resp(dut, conn, SIGMA_ERROR,
10733 "ErrorCode,Failed to send ANQP query");
10734 return 0;
10735 }
10736
10737 return 1;
10738}
10739
10740
10741static int mbo_cmd_sta_send_frame(struct sigma_dut *dut,
10742 struct sigma_conn *conn,
10743 const char *intf,
10744 struct sigma_cmd *cmd)
10745{
10746 const char *val = get_param(cmd, "FrameName");
10747
10748 if (val && strcasecmp(val, "ANQPQuery") == 0)
10749 return mbo_send_anqp_query(dut, conn, intf, cmd);
10750
10751 return 2;
10752}
10753
10754
Jouni Malinenf7222712019-06-13 01:50:21 +030010755enum sigma_cmd_result cmd_sta_send_frame(struct sigma_dut *dut,
10756 struct sigma_conn *conn,
10757 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010758{
10759 const char *intf = get_param(cmd, "Interface");
10760 const char *val;
10761 enum send_frame_type frame;
10762 enum send_frame_protection protected;
10763 char buf[100];
10764 unsigned char addr[ETH_ALEN];
10765 int res;
10766
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +030010767 if (!intf)
10768 return -1;
10769
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010770 val = get_param(cmd, "program");
10771 if (val == NULL)
10772 val = get_param(cmd, "frame");
10773 if (val && strcasecmp(val, "TDLS") == 0)
10774 return cmd_sta_send_frame_tdls(dut, conn, cmd);
10775 if (val && (strcasecmp(val, "HS2") == 0 ||
Jouni Malinen1f6ae642018-06-07 23:56:13 +030010776 strcasecmp(val, "HS2-R2") == 0 ||
10777 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010778 return cmd_sta_send_frame_hs2(dut, conn, cmd);
10779 if (val && strcasecmp(val, "VHT") == 0)
10780 return cmd_sta_send_frame_vht(dut, conn, cmd);
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070010781 if (val && strcasecmp(val, "HE") == 0)
10782 return cmd_sta_send_frame_he(dut, conn, cmd);
priyadharshini gowthamand66913a2016-07-29 15:11:17 -070010783 if (val && strcasecmp(val, "LOC") == 0)
10784 return loc_cmd_sta_send_frame(dut, conn, cmd);
Lior David0fe101e2017-03-09 16:09:50 +020010785 if (val && strcasecmp(val, "60GHz") == 0)
10786 return cmd_sta_send_frame_60g(dut, conn, cmd);
Ashwini Patildb59b3c2017-04-13 15:19:23 +053010787 if (val && strcasecmp(val, "MBO") == 0) {
10788 res = mbo_cmd_sta_send_frame(dut, conn, intf, cmd);
10789 if (res != 2)
10790 return res;
10791 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010792
10793 val = get_param(cmd, "TD_DISC");
10794 if (val) {
10795 if (hwaddr_aton(val, addr) < 0)
10796 return -1;
10797 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", val);
10798 if (wpa_command(intf, buf) < 0) {
10799 send_resp(dut, conn, SIGMA_ERROR,
10800 "ErrorCode,Failed to send TDLS discovery");
10801 return 0;
10802 }
10803 return 1;
10804 }
10805
10806 val = get_param(cmd, "TD_Setup");
10807 if (val) {
10808 if (hwaddr_aton(val, addr) < 0)
10809 return -1;
10810 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", val);
10811 if (wpa_command(intf, buf) < 0) {
10812 send_resp(dut, conn, SIGMA_ERROR,
10813 "ErrorCode,Failed to start TDLS setup");
10814 return 0;
10815 }
10816 return 1;
10817 }
10818
10819 val = get_param(cmd, "TD_TearDown");
10820 if (val) {
10821 if (hwaddr_aton(val, addr) < 0)
10822 return -1;
10823 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", val);
10824 if (wpa_command(intf, buf) < 0) {
10825 send_resp(dut, conn, SIGMA_ERROR,
10826 "ErrorCode,Failed to tear down TDLS link");
10827 return 0;
10828 }
10829 return 1;
10830 }
10831
10832 val = get_param(cmd, "TD_ChannelSwitch");
10833 if (val) {
10834 /* TODO */
10835 send_resp(dut, conn, SIGMA_ERROR,
10836 "ErrorCode,TD_ChannelSwitch not yet supported");
10837 return 0;
10838 }
10839
10840 val = get_param(cmd, "TD_NF");
10841 if (val) {
10842 /* TODO */
10843 send_resp(dut, conn, SIGMA_ERROR,
10844 "ErrorCode,TD_NF not yet supported");
10845 return 0;
10846 }
10847
10848 val = get_param(cmd, "PMFFrameType");
10849 if (val == NULL)
10850 val = get_param(cmd, "FrameName");
10851 if (val == NULL)
10852 val = get_param(cmd, "Type");
10853 if (val == NULL)
10854 return -1;
10855 if (strcasecmp(val, "disassoc") == 0)
10856 frame = DISASSOC;
10857 else if (strcasecmp(val, "deauth") == 0)
10858 frame = DEAUTH;
10859 else if (strcasecmp(val, "saquery") == 0)
10860 frame = SAQUERY;
10861 else if (strcasecmp(val, "auth") == 0)
10862 frame = AUTH;
10863 else if (strcasecmp(val, "assocreq") == 0)
10864 frame = ASSOCREQ;
10865 else if (strcasecmp(val, "reassocreq") == 0)
10866 frame = REASSOCREQ;
10867 else if (strcasecmp(val, "neigreq") == 0) {
10868 sigma_dut_print(dut, DUT_MSG_INFO, "Got neighbor request");
10869
10870 val = get_param(cmd, "ssid");
10871 if (val == NULL)
10872 return -1;
10873
10874 res = send_neighbor_request(dut, intf, val);
10875 if (res) {
10876 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
10877 "Failed to send neighbor report request");
10878 return 0;
10879 }
10880
10881 return 1;
Ashwini Patil5acd7382017-04-13 15:55:04 +053010882 } else if (strcasecmp(val, "transmgmtquery") == 0 ||
10883 strcasecmp(val, "BTMQuery") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010884 sigma_dut_print(dut, DUT_MSG_DEBUG,
10885 "Got Transition Management Query");
10886
Ashwini Patil5acd7382017-04-13 15:55:04 +053010887 res = send_trans_mgmt_query(dut, intf, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010888 if (res) {
10889 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
10890 "Failed to send Transition Management Query");
10891 return 0;
10892 }
10893
10894 return 1;
10895 } else {
10896 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
10897 "PMFFrameType");
10898 return 0;
10899 }
10900
10901 val = get_param(cmd, "PMFProtected");
10902 if (val == NULL)
10903 val = get_param(cmd, "Protected");
10904 if (val == NULL)
10905 return -1;
10906 if (strcasecmp(val, "Correct-key") == 0 ||
10907 strcasecmp(val, "CorrectKey") == 0)
10908 protected = CORRECT_KEY;
10909 else if (strcasecmp(val, "IncorrectKey") == 0)
10910 protected = INCORRECT_KEY;
10911 else if (strcasecmp(val, "Unprotected") == 0)
10912 protected = UNPROTECTED;
10913 else {
10914 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
10915 "PMFProtected");
10916 return 0;
10917 }
10918
10919 if (protected != UNPROTECTED &&
10920 (frame == AUTH || frame == ASSOCREQ || frame == REASSOCREQ)) {
10921 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Impossible "
10922 "PMFProtected for auth/assocreq/reassocreq");
10923 return 0;
10924 }
10925
10926 if (if_nametoindex("sigmadut") == 0) {
10927 snprintf(buf, sizeof(buf),
10928 "iw dev %s interface add sigmadut type monitor",
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010929 get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010930 if (system(buf) != 0 ||
10931 if_nametoindex("sigmadut") == 0) {
10932 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
10933 "monitor interface with '%s'", buf);
10934 return -2;
10935 }
10936 }
10937
10938 if (system("ifconfig sigmadut up") != 0) {
10939 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
10940 "monitor interface up");
10941 return -2;
10942 }
10943
10944 return sta_inject_frame(dut, conn, frame, protected, NULL);
10945}
10946
10947
10948static int cmd_sta_set_parameter_hs2(struct sigma_dut *dut,
10949 struct sigma_conn *conn,
10950 struct sigma_cmd *cmd,
10951 const char *ifname)
10952{
10953 char buf[200];
10954 const char *val;
10955
10956 val = get_param(cmd, "ClearARP");
10957 if (val && atoi(val) == 1) {
10958 snprintf(buf, sizeof(buf), "ip neigh flush dev %s", ifname);
10959 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10960 if (system(buf) != 0) {
10961 send_resp(dut, conn, SIGMA_ERROR,
10962 "errorCode,Failed to clear ARP cache");
10963 return 0;
10964 }
10965 }
10966
10967 return 1;
10968}
10969
10970
10971int cmd_sta_set_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
10972 struct sigma_cmd *cmd)
10973{
10974 const char *intf = get_param(cmd, "Interface");
10975 const char *val;
10976
10977 if (intf == NULL)
10978 return -1;
10979
10980 val = get_param(cmd, "program");
10981 if (val && (strcasecmp(val, "HS2") == 0 ||
Jouni Malinen1f6ae642018-06-07 23:56:13 +030010982 strcasecmp(val, "HS2-R2") == 0 ||
10983 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010984 return cmd_sta_set_parameter_hs2(dut, conn, cmd, intf);
10985
10986 return -1;
10987}
10988
10989
Jouni Malinenf7222712019-06-13 01:50:21 +030010990static enum sigma_cmd_result cmd_sta_set_macaddr(struct sigma_dut *dut,
10991 struct sigma_conn *conn,
10992 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010993{
10994 const char *intf = get_param(cmd, "Interface");
10995 const char *mac = get_param(cmd, "MAC");
10996
10997 if (intf == NULL || mac == NULL)
10998 return -1;
10999
11000 sigma_dut_print(dut, DUT_MSG_INFO, "Change local MAC address for "
11001 "interface %s to %s", intf, mac);
11002
11003 if (dut->set_macaddr) {
11004 char buf[128];
11005 int res;
11006 if (strcasecmp(mac, "default") == 0) {
11007 res = snprintf(buf, sizeof(buf), "%s",
11008 dut->set_macaddr);
11009 dut->tmp_mac_addr = 0;
11010 } else {
11011 res = snprintf(buf, sizeof(buf), "%s %s",
11012 dut->set_macaddr, mac);
11013 dut->tmp_mac_addr = 1;
11014 }
11015 if (res < 0 || res >= (int) sizeof(buf))
11016 return -1;
11017 if (system(buf) != 0) {
11018 send_resp(dut, conn, SIGMA_ERROR,
11019 "errorCode,Failed to set MAC "
11020 "address");
11021 return 0;
11022 }
11023 return 1;
11024 }
11025
11026 if (strcasecmp(mac, "default") == 0)
11027 return 1;
11028
11029 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
11030 "command");
11031 return 0;
11032}
11033
11034
11035static int iwpriv_tdlsoffchnmode(struct sigma_dut *dut,
11036 struct sigma_conn *conn, const char *intf,
11037 int val)
11038{
11039 char buf[200];
11040 int res;
11041
11042 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchnmode %d",
11043 intf, val);
11044 if (res < 0 || res >= (int) sizeof(buf))
11045 return -1;
11046 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
11047 if (system(buf) != 0) {
11048 send_resp(dut, conn, SIGMA_ERROR,
11049 "errorCode,Failed to configure offchannel mode");
11050 return 0;
11051 }
11052
11053 return 1;
11054}
11055
11056
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011057static int off_chan_val(enum sec_ch_offset off)
11058{
11059 switch (off) {
11060 case SEC_CH_NO:
11061 return 0;
11062 case SEC_CH_40ABOVE:
11063 return 40;
11064 case SEC_CH_40BELOW:
11065 return -40;
11066 }
11067
11068 return 0;
11069}
11070
11071
11072static int iwpriv_set_offchan(struct sigma_dut *dut, struct sigma_conn *conn,
11073 const char *intf, int off_ch_num,
11074 enum sec_ch_offset sec)
11075{
11076 char buf[200];
11077 int res;
11078
11079 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchan %d",
11080 intf, off_ch_num);
11081 if (res < 0 || res >= (int) sizeof(buf))
11082 return -1;
11083 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
11084 if (system(buf) != 0) {
11085 send_resp(dut, conn, SIGMA_ERROR,
11086 "errorCode,Failed to set offchan");
11087 return 0;
11088 }
11089
11090 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsecchnoffst %d",
11091 intf, off_chan_val(sec));
11092 if (res < 0 || res >= (int) sizeof(buf))
11093 return -1;
11094 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
11095 if (system(buf) != 0) {
11096 send_resp(dut, conn, SIGMA_ERROR,
11097 "errorCode,Failed to set sec chan offset");
11098 return 0;
11099 }
11100
11101 return 1;
11102}
11103
11104
11105static int tdls_set_offchannel_offset(struct sigma_dut *dut,
11106 struct sigma_conn *conn,
11107 const char *intf, int off_ch_num,
11108 enum sec_ch_offset sec)
11109{
11110 char buf[200];
11111 int res;
11112
11113 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNEL %d",
11114 off_ch_num);
11115 if (res < 0 || res >= (int) sizeof(buf))
11116 return -1;
11117 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
11118
11119 if (wpa_command(intf, buf) < 0) {
11120 send_resp(dut, conn, SIGMA_ERROR,
11121 "ErrorCode,Failed to set offchan");
11122 return 0;
11123 }
11124 res = snprintf(buf, sizeof(buf), "DRIVER TDLSSECONDARYCHANNELOFFSET %d",
11125 off_chan_val(sec));
11126 if (res < 0 || res >= (int) sizeof(buf))
11127 return -1;
11128
11129 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
11130
11131 if (wpa_command(intf, buf) < 0) {
11132 send_resp(dut, conn, SIGMA_ERROR,
11133 "ErrorCode,Failed to set sec chan offset");
11134 return 0;
11135 }
11136
11137 return 1;
11138}
11139
11140
11141static int tdls_set_offchannel_mode(struct sigma_dut *dut,
11142 struct sigma_conn *conn,
11143 const char *intf, int val)
11144{
11145 char buf[200];
11146 int res;
11147
11148 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNELMODE %d",
11149 val);
11150 if (res < 0 || res >= (int) sizeof(buf))
11151 return -1;
11152 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
11153
11154 if (wpa_command(intf, buf) < 0) {
11155 send_resp(dut, conn, SIGMA_ERROR,
11156 "ErrorCode,Failed to configure offchannel mode");
11157 return 0;
11158 }
11159
11160 return 1;
11161}
11162
11163
11164static int cmd_sta_set_rfeature_tdls(const char *intf, struct sigma_dut *dut,
11165 struct sigma_conn *conn,
11166 struct sigma_cmd *cmd)
11167{
11168 const char *val;
11169 enum {
11170 CHSM_NOT_SET,
11171 CHSM_ENABLE,
11172 CHSM_DISABLE,
11173 CHSM_REJREQ,
11174 CHSM_UNSOLRESP
11175 } chsm = CHSM_NOT_SET;
11176 int off_ch_num = -1;
11177 enum sec_ch_offset sec_ch = SEC_CH_NO;
11178 int res;
11179
11180 val = get_param(cmd, "Uapsd");
11181 if (val) {
11182 char buf[100];
11183 if (strcasecmp(val, "Enable") == 0)
11184 snprintf(buf, sizeof(buf), "SET ps 99");
11185 else if (strcasecmp(val, "Disable") == 0)
11186 snprintf(buf, sizeof(buf), "SET ps 98");
11187 else {
11188 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
11189 "Unsupported uapsd parameter value");
11190 return 0;
11191 }
11192 if (wpa_command(intf, buf)) {
11193 send_resp(dut, conn, SIGMA_ERROR,
11194 "ErrorCode,Failed to change U-APSD "
11195 "powersave mode");
11196 return 0;
11197 }
11198 }
11199
11200 val = get_param(cmd, "TPKTIMER");
11201 if (val && strcasecmp(val, "DISABLE") == 0) {
11202 if (wpa_command(intf, "SET tdls_testing 0x100")) {
11203 send_resp(dut, conn, SIGMA_ERROR,
11204 "ErrorCode,Failed to enable no TPK "
11205 "expiration test mode");
11206 return 0;
11207 }
11208 dut->no_tpk_expiration = 1;
11209 }
11210
11211 val = get_param(cmd, "ChSwitchMode");
11212 if (val) {
11213 if (strcasecmp(val, "Enable") == 0 ||
11214 strcasecmp(val, "Initiate") == 0)
11215 chsm = CHSM_ENABLE;
11216 else if (strcasecmp(val, "Disable") == 0 ||
11217 strcasecmp(val, "passive") == 0)
11218 chsm = CHSM_DISABLE;
11219 else if (strcasecmp(val, "RejReq") == 0)
11220 chsm = CHSM_REJREQ;
11221 else if (strcasecmp(val, "UnSolResp") == 0)
11222 chsm = CHSM_UNSOLRESP;
11223 else {
11224 send_resp(dut, conn, SIGMA_ERROR,
11225 "ErrorCode,Unknown ChSwitchMode value");
11226 return 0;
11227 }
11228 }
11229
11230 val = get_param(cmd, "OffChNum");
11231 if (val) {
11232 off_ch_num = atoi(val);
11233 if (off_ch_num == 0) {
11234 send_resp(dut, conn, SIGMA_ERROR,
11235 "ErrorCode,Invalid OffChNum");
11236 return 0;
11237 }
11238 }
11239
11240 val = get_param(cmd, "SecChOffset");
11241 if (val) {
11242 if (strcmp(val, "20") == 0)
11243 sec_ch = SEC_CH_NO;
11244 else if (strcasecmp(val, "40above") == 0)
11245 sec_ch = SEC_CH_40ABOVE;
11246 else if (strcasecmp(val, "40below") == 0)
11247 sec_ch = SEC_CH_40BELOW;
11248 else {
11249 send_resp(dut, conn, SIGMA_ERROR,
11250 "ErrorCode,Unknown SecChOffset value");
11251 return 0;
11252 }
11253 }
11254
11255 if (chsm == CHSM_NOT_SET) {
11256 /* no offchannel changes requested */
11257 return 1;
11258 }
11259
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011260 if (strcmp(intf, get_main_ifname(dut)) != 0 &&
11261 strcmp(intf, get_station_ifname(dut)) != 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011262 send_resp(dut, conn, SIGMA_ERROR,
11263 "ErrorCode,Unknown interface");
11264 return 0;
11265 }
11266
11267 switch (chsm) {
11268 case CHSM_NOT_SET:
Jouni Malinen280f5ba2016-08-29 21:33:10 +030011269 res = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011270 break;
11271 case CHSM_ENABLE:
11272 if (off_ch_num < 0) {
11273 send_resp(dut, conn, SIGMA_ERROR,
11274 "ErrorCode,Missing OffChNum argument");
11275 return 0;
11276 }
11277 if (wifi_chip_type == DRIVER_WCN) {
11278 res = tdls_set_offchannel_offset(dut, conn, intf,
11279 off_ch_num, sec_ch);
11280 } else {
11281 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
11282 sec_ch);
11283 }
11284 if (res != 1)
11285 return res;
11286 if (wifi_chip_type == DRIVER_WCN)
11287 res = tdls_set_offchannel_mode(dut, conn, intf, 1);
11288 else
11289 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 1);
11290 break;
11291 case CHSM_DISABLE:
11292 if (wifi_chip_type == DRIVER_WCN)
11293 res = tdls_set_offchannel_mode(dut, conn, intf, 2);
11294 else
11295 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 2);
11296 break;
11297 case CHSM_REJREQ:
11298 if (wifi_chip_type == DRIVER_WCN)
11299 res = tdls_set_offchannel_mode(dut, conn, intf, 3);
11300 else
11301 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 3);
11302 break;
11303 case CHSM_UNSOLRESP:
11304 if (off_ch_num < 0) {
11305 send_resp(dut, conn, SIGMA_ERROR,
11306 "ErrorCode,Missing OffChNum argument");
11307 return 0;
11308 }
11309 if (wifi_chip_type == DRIVER_WCN) {
11310 res = tdls_set_offchannel_offset(dut, conn, intf,
11311 off_ch_num, sec_ch);
11312 } else {
11313 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
11314 sec_ch);
11315 }
11316 if (res != 1)
11317 return res;
11318 if (wifi_chip_type == DRIVER_WCN)
11319 res = tdls_set_offchannel_mode(dut, conn, intf, 4);
11320 else
11321 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 4);
11322 break;
11323 }
11324
11325 return res;
11326}
11327
11328
11329static int ath_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
11330 struct sigma_conn *conn,
11331 struct sigma_cmd *cmd)
11332{
11333 const char *val;
Srikanth Marepalli5415acf2018-08-27 12:53:11 +053011334 char *token = NULL, *result;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011335
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -070011336 novap_reset(dut, intf, 1);
priyadharshini gowthamane5e25172015-12-08 14:53:48 -080011337
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011338 val = get_param(cmd, "nss_mcs_opt");
11339 if (val) {
11340 /* String (nss_operating_mode; mcs_operating_mode) */
11341 int nss, mcs;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053011342 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011343
11344 token = strdup(val);
11345 if (!token)
11346 return 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053011347 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +053011348 if (!result) {
11349 sigma_dut_print(dut, DUT_MSG_ERROR,
11350 "VHT NSS not specified");
11351 goto failed;
11352 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011353 if (strcasecmp(result, "def") != 0) {
11354 nss = atoi(result);
11355 if (nss == 4)
11356 ath_disable_txbf(dut, intf);
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011357 if (run_iwpriv(dut, intf, "nss %d", nss) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011358 goto failed;
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011359
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011360 }
11361
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053011362 result = strtok_r(NULL, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +053011363 if (!result) {
11364 sigma_dut_print(dut, DUT_MSG_ERROR,
11365 "VHT MCS not specified");
11366 goto failed;
11367 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011368 if (strcasecmp(result, "def") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011369 if (run_iwpriv(dut, intf, "set11NRates 0") < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011370 goto failed;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011371 } else {
11372 mcs = atoi(result);
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011373 if (run_iwpriv(dut, intf, "vhtmcs %d", mcs) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011374 goto failed;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011375 }
11376 /* Channel width gets messed up, fix this */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011377 run_iwpriv(dut, intf, "chwidth %d", dut->chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011378 }
11379
Srikanth Marepalli5415acf2018-08-27 12:53:11 +053011380 free(token);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011381 return 1;
11382failed:
11383 free(token);
11384 return 0;
11385}
11386
11387
11388static int cmd_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
11389 struct sigma_conn *conn,
11390 struct sigma_cmd *cmd)
11391{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011392 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011393 case DRIVER_ATHEROS:
11394 return ath_sta_set_rfeature_vht(intf, dut, conn, cmd);
11395 default:
11396 send_resp(dut, conn, SIGMA_ERROR,
11397 "errorCode,Unsupported sta_set_rfeature(VHT) with the current driver");
11398 return 0;
11399 }
11400}
11401
11402
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011403static int wcn_sta_set_rfeature_he(const char *intf, struct sigma_dut *dut,
11404 struct sigma_conn *conn,
11405 struct sigma_cmd *cmd)
11406{
11407 const char *val;
11408 char *token = NULL, *result;
11409 char buf[60];
11410
11411 val = get_param(cmd, "nss_mcs_opt");
11412 if (val) {
11413 /* String (nss_operating_mode; mcs_operating_mode) */
11414 int nss, mcs, ratecode;
11415 char *saveptr;
11416
11417 token = strdup(val);
11418 if (!token)
11419 return -2;
11420
11421 result = strtok_r(token, ";", &saveptr);
11422 if (!result) {
11423 sigma_dut_print(dut, DUT_MSG_ERROR,
11424 "HE NSS not specified");
11425 goto failed;
11426 }
11427 nss = 1;
11428 if (strcasecmp(result, "def") != 0)
11429 nss = atoi(result);
11430
11431 result = strtok_r(NULL, ";", &saveptr);
11432 if (!result) {
11433 sigma_dut_print(dut, DUT_MSG_ERROR,
11434 "HE MCS not specified");
11435 goto failed;
11436 }
11437 mcs = 7;
11438 if (strcasecmp(result, "def") != 0)
11439 mcs = atoi(result);
11440
Arif Hussain557bf412018-05-25 17:29:36 -070011441 ratecode = 0x20; /* for nss:1 MCS 0 */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011442 if (nss == 2) {
Arif Hussain557bf412018-05-25 17:29:36 -070011443 ratecode = 0x40; /* for nss:2 MCS 0 */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011444 } else if (nss > 2) {
11445 sigma_dut_print(dut, DUT_MSG_ERROR,
11446 "HE NSS %d not supported", nss);
11447 goto failed;
11448 }
11449
Arif Hussain557bf412018-05-25 17:29:36 -070011450 snprintf(buf, sizeof(buf), "iwpriv %s nss %d", intf, nss);
11451 if (system(buf) != 0) {
11452 sigma_dut_print(dut, DUT_MSG_ERROR,
11453 "nss_mcs_opt: iwpriv %s nss %d failed",
11454 intf, nss);
11455 goto failed;
11456 }
Arif Hussainac6c5112018-05-25 17:34:00 -070011457 dut->sta_nss = nss;
Arif Hussain557bf412018-05-25 17:29:36 -070011458
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011459 /* Add the MCS to the ratecode */
11460 if (mcs >= 0 && mcs <= 11) {
11461 ratecode += mcs;
Arif Hussain557bf412018-05-25 17:29:36 -070011462#ifdef NL80211_SUPPORT
11463 if (dut->device_type == STA_testbed) {
11464 enum he_mcs_config mcs_config;
11465 int ret;
11466
11467 if (mcs <= 7)
11468 mcs_config = HE_80_MCS0_7;
11469 else if (mcs <= 9)
11470 mcs_config = HE_80_MCS0_9;
11471 else
11472 mcs_config = HE_80_MCS0_11;
11473 ret = sta_set_he_mcs(dut, intf, mcs_config);
11474 if (ret) {
11475 sigma_dut_print(dut, DUT_MSG_ERROR,
11476 "nss_mcs_opt: mcs setting failed, mcs:%d, mcs_config %d, ret:%d",
11477 mcs, mcs_config, ret);
11478 goto failed;
11479 }
11480 }
11481#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011482 } else {
11483 sigma_dut_print(dut, DUT_MSG_ERROR,
11484 "HE MCS %d not supported", mcs);
11485 goto failed;
11486 }
11487 snprintf(buf, sizeof(buf), "iwpriv %s set_11ax_rate 0x%03x",
11488 intf, ratecode);
11489 if (system(buf) != 0) {
11490 sigma_dut_print(dut, DUT_MSG_ERROR,
11491 "iwpriv setting of 11ax rates failed");
11492 goto failed;
11493 }
11494 free(token);
11495 }
11496
11497 val = get_param(cmd, "GI");
11498 if (val) {
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011499 int fix_rate_sgi;
11500
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011501 if (strcmp(val, "0.8") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070011502 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 9", intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011503 fix_rate_sgi = 1;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011504 } else if (strcmp(val, "1.6") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070011505 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 10",
11506 intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011507 fix_rate_sgi = 2;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011508 } else if (strcmp(val, "3.2") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070011509 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 11",
11510 intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011511 fix_rate_sgi = 3;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011512 } else {
11513 send_resp(dut, conn, SIGMA_ERROR,
11514 "errorCode,GI value not supported");
11515 return 0;
11516 }
11517 if (system(buf) != 0) {
11518 send_resp(dut, conn, SIGMA_ERROR,
11519 "errorCode,Failed to set shortgi");
11520 return 0;
11521 }
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011522 snprintf(buf, sizeof(buf), "iwpriv %s shortgi %d",
11523 intf, fix_rate_sgi);
11524 if (system(buf) != 0) {
11525 send_resp(dut, conn, SIGMA_ERROR,
11526 "errorCode,Failed to set fix rate shortgi");
11527 return STATUS_SENT;
11528 }
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011529 }
11530
Subhani Shaik8e7a3052018-04-24 14:03:00 -070011531 val = get_param(cmd, "LTF");
11532 if (val) {
11533#ifdef NL80211_SUPPORT
11534 if (strcmp(val, "3.2") == 0) {
11535 sta_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_1X);
11536 } if (strcmp(val, "6.4") == 0) {
11537 sta_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_2X);
11538 } else if (strcmp(val, "12.8") == 0) {
11539 sta_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_4X);
11540 } else {
11541 send_resp(dut, conn, SIGMA_ERROR,
11542 "errorCode, LTF value not supported");
11543 return 0;
11544 }
11545#else /* NL80211_SUPPORT */
11546 sigma_dut_print(dut, DUT_MSG_ERROR,
11547 "LTF cannot be set without NL80211_SUPPORT defined");
11548 return -2;
11549#endif /* NL80211_SUPPORT */
11550 }
11551
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -070011552 val = get_param(cmd, "TxSUPPDU");
11553 if (val) {
11554 int set_val = 1;
11555
11556 if (strcasecmp(val, "Enable") == 0)
11557 set_val = 1;
11558 else if (strcasecmp(val, "Disable") == 0)
11559 set_val = 0;
11560
11561 if (sta_set_tx_su_ppdu_cfg(dut, intf, set_val)) {
11562 send_resp(dut, conn, SIGMA_ERROR,
11563 "ErrorCode,Failed to set Tx SU PPDU config");
11564 return 0;
11565 }
11566 }
11567
Arif Hussain480d5f42019-03-12 14:40:42 -070011568 val = get_param(cmd, "TWT_Setup");
11569 if (val) {
11570 if (strcasecmp(val, "Request") == 0) {
11571 if (sta_twt_request(dut, conn, cmd)) {
11572 send_resp(dut, conn, SIGMA_ERROR,
11573 "ErrorCode,sta_twt_request failed");
11574 return STATUS_SENT;
11575 }
11576 } else if (strcasecmp(val, "Teardown") == 0) {
11577 if (sta_twt_teardown(dut, conn, cmd)) {
11578 send_resp(dut, conn, SIGMA_ERROR,
11579 "ErrorCode,sta_twt_teardown failed");
11580 return STATUS_SENT;
11581 }
11582 }
11583 }
11584
Kiran Kumar Lokere50eb2cd2018-12-18 18:31:28 -080011585 val = get_param(cmd, "transmitOMI");
11586 if (val && sta_transmit_omi(dut, conn, cmd)) {
11587 send_resp(dut, conn, SIGMA_ERROR,
11588 "ErrorCode,sta_transmit_omi failed");
11589 return STATUS_SENT;
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -070011590 }
11591
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080011592 val = get_param(cmd, "Powersave");
11593 if (val) {
11594 char buf[60];
11595
11596 if (strcasecmp(val, "off") == 0) {
11597 snprintf(buf, sizeof(buf),
11598 "iwpriv %s setPower 2", intf);
11599 if (system(buf) != 0) {
11600 sigma_dut_print(dut, DUT_MSG_ERROR,
11601 "iwpriv setPower 2 failed");
11602 return 0;
11603 }
11604 } else if (strcasecmp(val, "on") == 0) {
11605 snprintf(buf, sizeof(buf),
11606 "iwpriv %s setPower 1", intf);
11607 if (system(buf) != 0) {
11608 sigma_dut_print(dut, DUT_MSG_ERROR,
11609 "iwpriv setPower 1 failed");
11610 return 0;
11611 }
11612 } else {
11613 sigma_dut_print(dut, DUT_MSG_ERROR,
11614 "Unsupported Powersave value '%s'",
11615 val);
11616 return -1;
11617 }
11618 }
11619
Kiran Kumar Lokere2c4b7ce2019-01-30 12:02:28 -080011620 val = get_param(cmd, "MU_EDCA");
11621 if (val) {
11622 if (strcasecmp(val, "Override") == 0) {
11623 if (sta_set_mu_edca_override(dut, intf, 1)) {
11624 send_resp(dut, conn, SIGMA_ERROR,
11625 "errorCode,MU EDCA override set failed");
11626 return STATUS_SENT;
11627 }
11628 } else if (strcasecmp(val, "Disable") == 0) {
11629 if (sta_set_mu_edca_override(dut, intf, 0)) {
11630 send_resp(dut, conn, SIGMA_ERROR,
11631 "errorCode,MU EDCA override disable failed");
11632 return STATUS_SENT;
11633 }
11634 }
11635 }
11636
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011637 return 1;
11638
11639failed:
11640 free(token);
11641 return -2;
11642}
11643
11644
11645static int cmd_sta_set_rfeature_he(const char *intf, struct sigma_dut *dut,
11646 struct sigma_conn *conn,
11647 struct sigma_cmd *cmd)
11648{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011649 switch (get_driver_type(dut)) {
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011650 case DRIVER_WCN:
11651 return wcn_sta_set_rfeature_he(intf, dut, conn, cmd);
11652 default:
11653 send_resp(dut, conn, SIGMA_ERROR,
11654 "errorCode,Unsupported sta_set_rfeature(HE) with the current driver");
11655 return 0;
11656 }
11657}
11658
11659
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080011660static int cmd_sta_set_power_save_he(const char *intf, struct sigma_dut *dut,
11661 struct sigma_conn *conn,
11662 struct sigma_cmd *cmd)
11663{
11664 const char *val;
11665
11666 val = get_param(cmd, "powersave");
11667 if (val) {
11668 char buf[60];
11669
11670 if (strcasecmp(val, "off") == 0) {
11671 snprintf(buf, sizeof(buf), "iwpriv %s setPower 2",
11672 intf);
11673 if (system(buf) != 0) {
11674 sigma_dut_print(dut, DUT_MSG_ERROR,
11675 "iwpriv setPower 2 failed");
11676 return 0;
11677 }
11678 } else if (strcasecmp(val, "on") == 0) {
11679 snprintf(buf, sizeof(buf), "iwpriv %s setPower 1",
11680 intf);
11681 if (system(buf) != 0) {
11682 sigma_dut_print(dut, DUT_MSG_ERROR,
11683 "iwpriv setPower 1 failed");
11684 return 0;
11685 }
11686 } else {
11687 sigma_dut_print(dut, DUT_MSG_ERROR,
11688 "Unsupported power save config");
11689 return -1;
11690 }
11691 return 1;
11692 }
11693
11694 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported command");
11695
11696 return 0;
11697}
11698
11699
Ashwini Patil5acd7382017-04-13 15:55:04 +053011700static int btm_query_candidate_list(struct sigma_dut *dut,
11701 struct sigma_conn *conn,
11702 struct sigma_cmd *cmd)
11703{
11704 const char *bssid, *info, *op_class, *ch, *phy_type, *pref;
11705 int len, ret;
11706 char buf[10];
11707
11708 /*
11709 * Neighbor Report elements format:
11710 * neighbor=<BSSID>,<BSSID Information>,<Operating Class>,
11711 * <Channel Number>,<PHY Type>[,<hexdump of Optional Subelements>]
11712 * eg: neighbor=aa:bb:cc:dd:ee:ff,17,81,6,1,030101
11713 */
11714
11715 bssid = get_param(cmd, "Nebor_BSSID");
11716 if (!bssid) {
11717 send_resp(dut, conn, SIGMA_INVALID,
11718 "errorCode,Nebor_BSSID is missing");
11719 return 0;
11720 }
11721
11722 info = get_param(cmd, "Nebor_Bssid_Info");
11723 if (!info) {
11724 sigma_dut_print(dut, DUT_MSG_INFO,
11725 "Using default value for Nebor_Bssid_Info: %s",
11726 DEFAULT_NEIGHBOR_BSSID_INFO);
11727 info = DEFAULT_NEIGHBOR_BSSID_INFO;
11728 }
11729
11730 op_class = get_param(cmd, "Nebor_Op_Class");
11731 if (!op_class) {
11732 send_resp(dut, conn, SIGMA_INVALID,
11733 "errorCode,Nebor_Op_Class is missing");
11734 return 0;
11735 }
11736
11737 ch = get_param(cmd, "Nebor_Op_Ch");
11738 if (!ch) {
11739 send_resp(dut, conn, SIGMA_INVALID,
11740 "errorCode,Nebor_Op_Ch is missing");
11741 return 0;
11742 }
11743
11744 phy_type = get_param(cmd, "Nebor_Phy_Type");
11745 if (!phy_type) {
11746 sigma_dut_print(dut, DUT_MSG_INFO,
11747 "Using default value for Nebor_Phy_Type: %s",
11748 DEFAULT_NEIGHBOR_PHY_TYPE);
11749 phy_type = DEFAULT_NEIGHBOR_PHY_TYPE;
11750 }
11751
11752 /* Parse optional subelements */
11753 buf[0] = '\0';
11754 pref = get_param(cmd, "Nebor_Pref");
11755 if (pref) {
11756 /* hexdump for preferrence subelement */
11757 ret = snprintf(buf, sizeof(buf), ",0301%02x", atoi(pref));
11758 if (ret < 0 || ret >= (int) sizeof(buf)) {
11759 sigma_dut_print(dut, DUT_MSG_ERROR,
11760 "snprintf failed for optional subelement ret: %d",
11761 ret);
11762 send_resp(dut, conn, SIGMA_ERROR,
11763 "errorCode,snprintf failed for subelement");
11764 return 0;
11765 }
11766 }
11767
11768 if (!dut->btm_query_cand_list) {
11769 dut->btm_query_cand_list = calloc(1, NEIGHBOR_REPORT_SIZE);
11770 if (!dut->btm_query_cand_list) {
11771 send_resp(dut, conn, SIGMA_ERROR,
11772 "errorCode,Failed to allocate memory for btm_query_cand_list");
11773 return 0;
11774 }
11775 }
11776
11777 len = strlen(dut->btm_query_cand_list);
11778 ret = snprintf(dut->btm_query_cand_list + len,
11779 NEIGHBOR_REPORT_SIZE - len, " neighbor=%s,%s,%s,%s,%s%s",
11780 bssid, info, op_class, ch, phy_type, buf);
11781 if (ret < 0 || ret >= NEIGHBOR_REPORT_SIZE - len) {
11782 sigma_dut_print(dut, DUT_MSG_ERROR,
11783 "snprintf failed for neighbor report list ret: %d",
11784 ret);
11785 send_resp(dut, conn, SIGMA_ERROR,
11786 "errorCode,snprintf failed for neighbor report");
11787 free(dut->btm_query_cand_list);
11788 dut->btm_query_cand_list = NULL;
11789 return 0;
11790 }
11791
11792 return 1;
11793}
11794
11795
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020011796int sta_extract_60g_ese(struct sigma_dut *dut, struct sigma_cmd *cmd,
11797 struct sigma_ese_alloc *allocs, int *allocs_size)
11798{
11799 int max_count = *allocs_size;
11800 int count = 0, i;
11801 const char *val;
11802
11803 do {
11804 val = get_param_indexed(cmd, "AllocID", count);
11805 if (val)
11806 count++;
11807 } while (val);
11808
11809 if (count == 0 || count > max_count) {
11810 sigma_dut_print(dut, DUT_MSG_ERROR,
11811 "Invalid number of allocations(%d)", count);
11812 return -1;
11813 }
11814
11815 for (i = 0; i < count; i++) {
11816 val = get_param_indexed(cmd, "PercentBI", i);
11817 if (!val) {
11818 sigma_dut_print(dut, DUT_MSG_ERROR,
11819 "Missing PercentBI parameter at index %d",
11820 i);
11821 return -1;
11822 }
11823 allocs[i].percent_bi = atoi(val);
11824
11825 val = get_param_indexed(cmd, "SrcAID", i);
11826 if (val)
11827 allocs[i].src_aid = strtol(val, NULL, 0);
11828 else
11829 allocs[i].src_aid = ESE_BCAST_AID;
11830
11831 val = get_param_indexed(cmd, "DestAID", i);
11832 if (val)
11833 allocs[i].dst_aid = strtol(val, NULL, 0);
11834 else
11835 allocs[i].dst_aid = ESE_BCAST_AID;
11836
11837 allocs[i].type = ESE_CBAP;
11838 sigma_dut_print(dut, DUT_MSG_INFO,
11839 "Alloc %d PercentBI %d SrcAID %d DstAID %d",
11840 i, allocs[i].percent_bi, allocs[i].src_aid,
11841 allocs[i].dst_aid);
11842 }
11843
11844 *allocs_size = count;
11845 return 0;
11846}
11847
11848
11849static int sta_set_60g_ese(struct sigma_dut *dut, int count,
11850 struct sigma_ese_alloc *allocs)
11851{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011852 switch (get_driver_type(dut)) {
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020011853#ifdef __linux__
11854 case DRIVER_WIL6210:
11855 if (wil6210_set_ese(dut, count, allocs))
11856 return -1;
11857 return 1;
11858#endif /* __linux__ */
11859 default:
11860 sigma_dut_print(dut, DUT_MSG_ERROR,
11861 "Unsupported sta_set_60g_ese with the current driver");
11862 return -1;
11863 }
11864}
11865
11866
11867static int cmd_sta_set_rfeature_60g(const char *intf, struct sigma_dut *dut,
11868 struct sigma_conn *conn,
11869 struct sigma_cmd *cmd)
11870{
11871 const char *val;
11872
11873 val = get_param(cmd, "ExtSchIE");
11874 if (val && !strcasecmp(val, "Enable")) {
11875 struct sigma_ese_alloc allocs[MAX_ESE_ALLOCS];
11876 int count = MAX_ESE_ALLOCS;
11877
11878 if (sta_extract_60g_ese(dut, cmd, allocs, &count))
11879 return -1;
11880 return sta_set_60g_ese(dut, count, allocs);
11881 }
11882
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +020011883 val = get_param(cmd, "MCS_FixedRate");
11884 if (val) {
11885 int sta_mcs = atoi(val);
11886
11887 sigma_dut_print(dut, DUT_MSG_INFO, "Force STA MCS to %d",
11888 sta_mcs);
11889 wil6210_set_force_mcs(dut, 1, sta_mcs);
11890
Jouni Malinen0e29cf22019-02-19 01:13:21 +020011891 return SUCCESS_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +020011892 }
11893
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020011894 send_resp(dut, conn, SIGMA_ERROR,
11895 "errorCode,Invalid sta_set_rfeature(60G)");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020011896 return STATUS_SENT;
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020011897}
11898
11899
Jouni Malinenf7222712019-06-13 01:50:21 +030011900static enum sigma_cmd_result cmd_sta_set_rfeature(struct sigma_dut *dut,
11901 struct sigma_conn *conn,
11902 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011903{
11904 const char *intf = get_param(cmd, "Interface");
11905 const char *prog = get_param(cmd, "Prog");
Ashwini Patil68d02cd2017-01-10 15:39:16 +053011906 const char *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011907
11908 if (intf == NULL || prog == NULL)
11909 return -1;
11910
Ashwini Patil5acd7382017-04-13 15:55:04 +053011911 /* BSS Transition candidate list for BTM query */
11912 val = get_param(cmd, "Nebor_BSSID");
11913 if (val && btm_query_candidate_list(dut, conn, cmd) == 0)
11914 return 0;
11915
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011916 if (strcasecmp(prog, "TDLS") == 0)
11917 return cmd_sta_set_rfeature_tdls(intf, dut, conn, cmd);
11918
11919 if (strcasecmp(prog, "VHT") == 0)
11920 return cmd_sta_set_rfeature_vht(intf, dut, conn, cmd);
11921
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011922 if (strcasecmp(prog, "HE") == 0)
11923 return cmd_sta_set_rfeature_he(intf, dut, conn, cmd);
11924
Ashwini Patil68d02cd2017-01-10 15:39:16 +053011925 if (strcasecmp(prog, "MBO") == 0) {
11926 val = get_param(cmd, "Cellular_Data_Cap");
11927 if (val &&
11928 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
11929 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +053011930
11931 val = get_param(cmd, "Ch_Pref");
11932 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
11933 return 0;
11934
Ashwini Patil68d02cd2017-01-10 15:39:16 +053011935 return 1;
11936 }
11937
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020011938 if (strcasecmp(prog, "60GHz") == 0)
11939 return cmd_sta_set_rfeature_60g(intf, dut, conn, cmd);
11940
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011941 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported Prog");
11942 return 0;
11943}
11944
11945
Jouni Malinenf7222712019-06-13 01:50:21 +030011946static enum sigma_cmd_result cmd_sta_set_radio(struct sigma_dut *dut,
11947 struct sigma_conn *conn,
11948 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011949{
11950 const char *intf = get_param(cmd, "Interface");
11951 const char *mode = get_param(cmd, "Mode");
11952 int res;
11953
11954 if (intf == NULL || mode == NULL)
11955 return -1;
11956
11957 if (strcasecmp(mode, "On") == 0)
11958 res = wpa_command(intf, "SET radio_disabled 0");
11959 else if (strcasecmp(mode, "Off") == 0)
11960 res = wpa_command(intf, "SET radio_disabled 1");
11961 else
11962 return -1;
11963
11964 if (res) {
11965 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
11966 "radio mode");
11967 return 0;
11968 }
11969
11970 return 1;
11971}
11972
11973
Jouni Malinenf7222712019-06-13 01:50:21 +030011974static enum sigma_cmd_result cmd_sta_set_pwrsave(struct sigma_dut *dut,
11975 struct sigma_conn *conn,
11976 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011977{
11978 const char *intf = get_param(cmd, "Interface");
11979 const char *mode = get_param(cmd, "Mode");
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020011980 const char *prog = get_param(cmd, "program");
11981 const char *powersave = get_param(cmd, "powersave");
11982 int res = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011983
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020011984 if (intf == NULL)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011985 return -1;
11986
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020011987 if (prog && strcasecmp(prog, "60GHz") == 0) {
11988 /*
11989 * The CAPI mode parameter does not exist in 60G
11990 * unscheduled PS.
11991 */
Hu Wang5dc3ff12019-06-14 15:14:26 +080011992 if (powersave && strcasecmp(powersave, "unscheduled") == 0)
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020011993 res = set_ps(intf, dut, 1);
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011994 } else if (prog && get_driver_type(dut) == DRIVER_WCN &&
Alexei Avshalom Lazar2f6fdb42019-02-04 14:16:08 +020011995 strcasecmp(prog, "HE") == 0) {
11996 return cmd_sta_set_power_save_he(intf, dut, conn, cmd);
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020011997 } else {
11998 if (mode == NULL)
11999 return -1;
12000
12001 if (strcasecmp(mode, "On") == 0)
12002 res = set_ps(intf, dut, 1);
12003 else if (strcasecmp(mode, "Off") == 0)
12004 res = set_ps(intf, dut, 0);
12005 else
12006 return -1;
12007 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012008
12009 if (res) {
12010 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
12011 "power save mode");
12012 return 0;
12013 }
12014
12015 return 1;
12016}
12017
12018
Jouni Malinenf7222712019-06-13 01:50:21 +030012019static enum sigma_cmd_result cmd_sta_bssid_pool(struct sigma_dut *dut,
12020 struct sigma_conn *conn,
12021 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012022{
12023 const char *intf = get_param(cmd, "Interface");
12024 const char *val, *bssid;
12025 int res;
12026 char *buf;
12027 size_t buf_len;
12028
12029 val = get_param(cmd, "BSSID_FILTER");
12030 if (val == NULL)
12031 return -1;
12032
12033 bssid = get_param(cmd, "BSSID_List");
12034 if (atoi(val) == 0 || bssid == NULL) {
12035 /* Disable BSSID filter */
12036 if (wpa_command(intf, "SET bssid_filter ")) {
12037 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed "
12038 "to disable BSSID filter");
12039 return 0;
12040 }
12041
12042 return 1;
12043 }
12044
12045 buf_len = 100 + strlen(bssid);
12046 buf = malloc(buf_len);
12047 if (buf == NULL)
12048 return -1;
12049
12050 snprintf(buf, buf_len, "SET bssid_filter %s", bssid);
12051 res = wpa_command(intf, buf);
12052 free(buf);
12053 if (res) {
12054 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to enable "
12055 "BSSID filter");
12056 return 0;
12057 }
12058
12059 return 1;
12060}
12061
12062
Jouni Malinenf7222712019-06-13 01:50:21 +030012063static enum sigma_cmd_result cmd_sta_reset_parm(struct sigma_dut *dut,
12064 struct sigma_conn *conn,
12065 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012066{
12067 const char *intf = get_param(cmd, "Interface");
12068 const char *val;
12069
12070 /* TODO: ARP */
12071
12072 val = get_param(cmd, "HS2_CACHE_PROFILE");
12073 if (val && strcasecmp(val, "All") == 0)
12074 hs2_clear_credentials(intf);
12075
12076 return 1;
12077}
12078
12079
Jouni Malinenf7222712019-06-13 01:50:21 +030012080static enum sigma_cmd_result cmd_sta_get_key(struct sigma_dut *dut,
12081 struct sigma_conn *conn,
12082 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012083{
12084 const char *intf = get_param(cmd, "Interface");
12085 const char *key_type = get_param(cmd, "KeyType");
12086 char buf[100], resp[200];
12087
12088 if (key_type == NULL)
12089 return -1;
12090
12091 if (strcasecmp(key_type, "GTK") == 0) {
12092 if (wpa_command_resp(intf, "GET gtk", buf, sizeof(buf)) < 0 ||
12093 strncmp(buf, "FAIL", 4) == 0) {
12094 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12095 "not fetch current GTK");
12096 return 0;
12097 }
12098 snprintf(resp, sizeof(resp), "KeyValue,%s", buf);
12099 send_resp(dut, conn, SIGMA_COMPLETE, resp);
12100 return 0;
12101 } else {
12102 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
12103 "KeyType");
12104 return 0;
12105 }
12106
12107 return 1;
12108}
12109
12110
12111static int hs2_set_policy(struct sigma_dut *dut)
12112{
12113#ifdef ANDROID
12114 system("ip rule del prio 23000");
12115 if (system("ip rule add from all lookup main prio 23000") != 0) {
12116 sigma_dut_print(dut, DUT_MSG_ERROR,
12117 "Failed to run:ip rule add from all lookup main prio");
12118 return -1;
12119 }
12120 if (system("ip route flush cache") != 0) {
12121 sigma_dut_print(dut, DUT_MSG_ERROR,
12122 "Failed to run ip route flush cache");
12123 return -1;
12124 }
12125 return 1;
12126#else /* ANDROID */
12127 return 0;
12128#endif /* ANDROID */
12129}
12130
12131
Jouni Malinenf7222712019-06-13 01:50:21 +030012132static enum sigma_cmd_result cmd_sta_hs2_associate(struct sigma_dut *dut,
12133 struct sigma_conn *conn,
12134 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012135{
12136 const char *intf = get_param(cmd, "Interface");
12137 const char *val = get_param(cmd, "Ignore_blacklist");
Jouni Malinen439352d2018-09-13 03:42:23 +030012138 const char *band = get_param(cmd, "Band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012139 struct wpa_ctrl *ctrl;
Jouni Malinen3aa72862019-05-29 23:14:51 +030012140 int res, r;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012141 char bssid[20], ssid[40], resp[100], buf[100], blacklisted[100];
12142 int tries = 0;
12143 int ignore_blacklist = 0;
12144 const char *events[] = {
12145 "CTRL-EVENT-CONNECTED",
12146 "INTERWORKING-BLACKLISTED",
12147 "INTERWORKING-NO-MATCH",
12148 NULL
12149 };
12150
12151 start_sta_mode(dut);
12152
Jouni Malinen439352d2018-09-13 03:42:23 +030012153 if (band) {
12154 if (strcmp(band, "2.4") == 0) {
12155 wpa_command(intf, "SET setband 2G");
12156 } else if (strcmp(band, "5") == 0) {
12157 wpa_command(intf, "SET setband 5G");
12158 } else {
12159 send_resp(dut, conn, SIGMA_ERROR,
12160 "errorCode,Unsupported band");
12161 return 0;
12162 }
12163 }
12164
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012165 blacklisted[0] = '\0';
12166 if (val && atoi(val))
12167 ignore_blacklist = 1;
12168
12169try_again:
12170 ctrl = open_wpa_mon(intf);
12171 if (ctrl == NULL) {
12172 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
12173 "wpa_supplicant monitor connection");
12174 return -2;
12175 }
12176
12177 tries++;
12178 if (wpa_command(intf, "INTERWORKING_SELECT auto")) {
12179 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start "
12180 "Interworking connection");
12181 wpa_ctrl_detach(ctrl);
12182 wpa_ctrl_close(ctrl);
12183 return 0;
12184 }
12185
12186 buf[0] = '\0';
12187 while (1) {
12188 char *pos;
12189 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
12190 pos = strstr(buf, "INTERWORKING-BLACKLISTED");
12191 if (!pos)
12192 break;
12193 pos += 25;
12194 sigma_dut_print(dut, DUT_MSG_DEBUG, "Found blacklisted AP: %s",
12195 pos);
12196 if (!blacklisted[0])
12197 memcpy(blacklisted, pos, strlen(pos) + 1);
12198 }
12199
12200 if (ignore_blacklist && blacklisted[0]) {
12201 char *end;
12202 end = strchr(blacklisted, ' ');
12203 if (end)
12204 *end = '\0';
12205 sigma_dut_print(dut, DUT_MSG_DEBUG, "Try to connect to a blacklisted network: %s",
12206 blacklisted);
Jouni Malinen3aa72862019-05-29 23:14:51 +030012207 r = snprintf(buf, sizeof(buf), "INTERWORKING_CONNECT %s",
12208 blacklisted);
12209 if (r < 0 || r >= sizeof(buf) || wpa_command(intf, buf)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012210 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start Interworking connection to blacklisted network");
12211 wpa_ctrl_detach(ctrl);
12212 wpa_ctrl_close(ctrl);
12213 return 0;
12214 }
12215 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
12216 buf, sizeof(buf));
12217 }
12218
12219 wpa_ctrl_detach(ctrl);
12220 wpa_ctrl_close(ctrl);
12221
12222 if (res < 0) {
12223 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
12224 "connect");
12225 return 0;
12226 }
12227
12228 if (strstr(buf, "INTERWORKING-NO-MATCH") ||
12229 strstr(buf, "INTERWORKING-BLACKLISTED")) {
12230 if (tries < 2) {
12231 sigma_dut_print(dut, DUT_MSG_INFO, "No match found - try again to verify no APs were missed in the scan");
12232 goto try_again;
12233 }
12234 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,No network with "
12235 "matching credentials found");
12236 return 0;
12237 }
12238
12239 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
12240 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
12241 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
12242 "get current BSSID/SSID");
12243 return 0;
12244 }
12245
12246 snprintf(resp, sizeof(resp), "SSID,%s,BSSID,%s", ssid, bssid);
12247 send_resp(dut, conn, SIGMA_COMPLETE, resp);
12248 hs2_set_policy(dut);
12249 return 0;
12250}
12251
12252
Jouni Malinenf7222712019-06-13 01:50:21 +030012253static enum sigma_cmd_result cmd_sta_hs2_venue_info(struct sigma_dut *dut,
12254 struct sigma_conn *conn,
12255 struct sigma_cmd *cmd)
Jouni Malinenb639f1c2018-09-13 02:39:46 +030012256{
12257 const char *intf = get_param(cmd, "Interface");
12258 const char *display = get_param(cmd, "Display");
12259 struct wpa_ctrl *ctrl;
12260 char buf[300], params[400], *pos;
12261 char bssid[20];
12262 int info_avail = 0;
12263 unsigned int old_timeout;
12264 int res;
12265
12266 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0) {
12267 send_resp(dut, conn, SIGMA_ERROR,
12268 "ErrorCode,Could not get current BSSID");
12269 return 0;
12270 }
12271 ctrl = open_wpa_mon(intf);
12272 if (!ctrl) {
12273 sigma_dut_print(dut, DUT_MSG_ERROR,
12274 "Failed to open wpa_supplicant monitor connection");
12275 return -2;
12276 }
12277
12278 snprintf(buf, sizeof(buf), "ANQP_GET %s 277", bssid);
12279 wpa_command(intf, buf);
12280
12281 res = get_wpa_cli_event(dut, ctrl, "GAS-QUERY-DONE", buf, sizeof(buf));
12282 if (res < 0) {
12283 send_resp(dut, conn, SIGMA_ERROR,
12284 "ErrorCode,Could not complete GAS query");
12285 goto fail;
12286 }
12287
12288 old_timeout = dut->default_timeout;
12289 dut->default_timeout = 2;
12290 res = get_wpa_cli_event(dut, ctrl, "RX-VENUE-URL", buf, sizeof(buf));
12291 dut->default_timeout = old_timeout;
12292 if (res < 0)
12293 goto done;
12294 pos = strchr(buf, ' ');
12295 if (!pos)
12296 goto done;
12297 pos++;
12298 pos = strchr(pos, ' ');
12299 if (!pos)
12300 goto done;
12301 pos++;
12302 info_avail = 1;
12303 snprintf(params, sizeof(params), "browser %s", pos);
12304
12305 if (display && strcasecmp(display, "Yes") == 0) {
12306 pid_t pid;
12307
12308 pid = fork();
12309 if (pid < 0) {
12310 perror("fork");
12311 return -1;
12312 }
12313
12314 if (pid == 0) {
12315 run_hs20_osu(dut, params);
12316 exit(0);
12317 }
12318 }
12319
12320done:
12321 snprintf(buf, sizeof(buf), "Info_available,%s",
12322 info_avail ? "Yes" : "No");
12323 send_resp(dut, conn, SIGMA_COMPLETE, buf);
12324fail:
12325 wpa_ctrl_detach(ctrl);
12326 wpa_ctrl_close(ctrl);
12327 return 0;
12328}
12329
12330
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012331static int sta_add_credential_uname_pwd(struct sigma_dut *dut,
12332 struct sigma_conn *conn,
12333 const char *ifname,
12334 struct sigma_cmd *cmd)
12335{
12336 const char *val;
12337 int id;
12338
12339 id = add_cred(ifname);
12340 if (id < 0)
12341 return -2;
12342 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
12343
12344 val = get_param(cmd, "prefer");
12345 if (val && atoi(val) > 0)
12346 set_cred(ifname, id, "priority", "1");
12347
12348 val = get_param(cmd, "REALM");
12349 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
12350 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12351 "realm");
12352 return 0;
12353 }
12354
12355 val = get_param(cmd, "HOME_FQDN");
12356 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
12357 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12358 "home_fqdn");
12359 return 0;
12360 }
12361
12362 val = get_param(cmd, "Username");
12363 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
12364 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12365 "username");
12366 return 0;
12367 }
12368
12369 val = get_param(cmd, "Password");
12370 if (val && set_cred_quoted(ifname, id, "password", val) < 0) {
12371 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12372 "password");
12373 return 0;
12374 }
12375
12376 val = get_param(cmd, "ROOT_CA");
12377 if (val) {
12378 char fname[200];
12379 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
12380#ifdef __linux__
12381 if (!file_exists(fname)) {
12382 char msg[300];
12383 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
12384 "file (%s) not found", fname);
12385 send_resp(dut, conn, SIGMA_ERROR, msg);
12386 return 0;
12387 }
12388#endif /* __linux__ */
12389 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
12390 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12391 "not set root CA");
12392 return 0;
12393 }
12394 }
12395
12396 return 1;
12397}
12398
12399
12400static int update_devdetail_imsi(struct sigma_dut *dut, const char *imsi)
12401{
12402 FILE *in, *out;
12403 char buf[500];
12404 int found = 0;
12405
12406 in = fopen("devdetail.xml", "r");
12407 if (in == NULL)
12408 return -1;
12409 out = fopen("devdetail.xml.tmp", "w");
12410 if (out == NULL) {
12411 fclose(in);
12412 return -1;
12413 }
12414
12415 while (fgets(buf, sizeof(buf), in)) {
12416 char *pos = strstr(buf, "<IMSI>");
12417 if (pos) {
12418 sigma_dut_print(dut, DUT_MSG_INFO, "Updated DevDetail IMSI to %s",
12419 imsi);
12420 pos += 6;
12421 *pos = '\0';
12422 fprintf(out, "%s%s</IMSI>\n", buf, imsi);
12423 found++;
12424 } else {
12425 fprintf(out, "%s", buf);
12426 }
12427 }
12428
12429 fclose(out);
12430 fclose(in);
12431 if (found)
12432 rename("devdetail.xml.tmp", "devdetail.xml");
12433 else
12434 unlink("devdetail.xml.tmp");
12435
12436 return 0;
12437}
12438
12439
12440static int sta_add_credential_sim(struct sigma_dut *dut,
12441 struct sigma_conn *conn,
12442 const char *ifname, struct sigma_cmd *cmd)
12443{
12444 const char *val, *imsi = NULL;
12445 int id;
12446 char buf[200];
12447 int res;
12448 const char *pos;
12449 size_t mnc_len;
12450 char plmn_mcc[4];
12451 char plmn_mnc[4];
12452
12453 id = add_cred(ifname);
12454 if (id < 0)
12455 return -2;
12456 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
12457
12458 val = get_param(cmd, "prefer");
12459 if (val && atoi(val) > 0)
12460 set_cred(ifname, id, "priority", "1");
12461
12462 val = get_param(cmd, "PLMN_MCC");
12463 if (val == NULL) {
12464 send_resp(dut, conn, SIGMA_ERROR,
12465 "errorCode,Missing PLMN_MCC");
12466 return 0;
12467 }
12468 if (strlen(val) != 3) {
12469 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MCC");
12470 return 0;
12471 }
12472 snprintf(plmn_mcc, sizeof(plmn_mcc), "%s", val);
12473
12474 val = get_param(cmd, "PLMN_MNC");
12475 if (val == NULL) {
12476 send_resp(dut, conn, SIGMA_ERROR,
12477 "errorCode,Missing PLMN_MNC");
12478 return 0;
12479 }
12480 if (strlen(val) != 2 && strlen(val) != 3) {
12481 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MNC");
12482 return 0;
12483 }
12484 snprintf(plmn_mnc, sizeof(plmn_mnc), "%s", val);
12485
12486 val = get_param(cmd, "IMSI");
12487 if (val == NULL) {
12488 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing SIM "
12489 "IMSI");
12490 return 0;
12491 }
12492
12493 imsi = pos = val;
12494
12495 if (strncmp(plmn_mcc, pos, 3) != 0) {
12496 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MCC mismatch");
12497 return 0;
12498 }
12499 pos += 3;
12500
12501 mnc_len = strlen(plmn_mnc);
12502 if (mnc_len < 2) {
12503 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC not set");
12504 return 0;
12505 }
12506
12507 if (strncmp(plmn_mnc, pos, mnc_len) != 0) {
12508 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC mismatch");
12509 return 0;
12510 }
12511 pos += mnc_len;
12512
12513 res = snprintf(buf, sizeof(buf), "%s%s-%s",plmn_mcc, plmn_mnc, pos);
12514 if (res < 0 || res >= (int) sizeof(buf))
12515 return -1;
12516 if (set_cred_quoted(ifname, id, "imsi", buf) < 0) {
12517 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12518 "not set IMSI");
12519 return 0;
12520 }
12521
12522 val = get_param(cmd, "Password");
12523 if (val && set_cred_quoted(ifname, id, "milenage", val) < 0) {
12524 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12525 "not set password");
12526 return 0;
12527 }
12528
Jouni Malinenba630452018-06-22 11:49:59 +030012529 if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012530 /*
12531 * Set provisioning_sp for the test cases where SIM/USIM
12532 * provisioning is used.
12533 */
12534 if (val && set_cred_quoted(ifname, id, "provisioning_sp",
12535 "wi-fi.org") < 0) {
12536 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12537 "not set provisioning_sp");
12538 return 0;
12539 }
12540
12541 update_devdetail_imsi(dut, imsi);
12542 }
12543
12544 return 1;
12545}
12546
12547
12548static int sta_add_credential_cert(struct sigma_dut *dut,
12549 struct sigma_conn *conn,
12550 const char *ifname,
12551 struct sigma_cmd *cmd)
12552{
12553 const char *val;
12554 int id;
12555
12556 id = add_cred(ifname);
12557 if (id < 0)
12558 return -2;
12559 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
12560
12561 val = get_param(cmd, "prefer");
12562 if (val && atoi(val) > 0)
12563 set_cred(ifname, id, "priority", "1");
12564
12565 val = get_param(cmd, "REALM");
12566 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
12567 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12568 "realm");
12569 return 0;
12570 }
12571
12572 val = get_param(cmd, "HOME_FQDN");
12573 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
12574 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12575 "home_fqdn");
12576 return 0;
12577 }
12578
12579 val = get_param(cmd, "Username");
12580 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
12581 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12582 "username");
12583 return 0;
12584 }
12585
12586 val = get_param(cmd, "clientCertificate");
12587 if (val) {
12588 char fname[200];
12589 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
12590#ifdef __linux__
12591 if (!file_exists(fname)) {
12592 char msg[300];
12593 snprintf(msg, sizeof(msg),
12594 "ErrorCode,clientCertificate "
12595 "file (%s) not found", fname);
12596 send_resp(dut, conn, SIGMA_ERROR, msg);
12597 return 0;
12598 }
12599#endif /* __linux__ */
12600 if (set_cred_quoted(ifname, id, "client_cert", fname) < 0) {
12601 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12602 "not set client_cert");
12603 return 0;
12604 }
12605 if (set_cred_quoted(ifname, id, "private_key", fname) < 0) {
12606 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12607 "not set private_key");
12608 return 0;
12609 }
12610 }
12611
12612 val = get_param(cmd, "ROOT_CA");
12613 if (val) {
12614 char fname[200];
12615 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
12616#ifdef __linux__
12617 if (!file_exists(fname)) {
12618 char msg[300];
12619 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
12620 "file (%s) not found", fname);
12621 send_resp(dut, conn, SIGMA_ERROR, msg);
12622 return 0;
12623 }
12624#endif /* __linux__ */
12625 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
12626 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12627 "not set root CA");
12628 return 0;
12629 }
12630 }
12631
12632 return 1;
12633}
12634
12635
Jouni Malinenf7222712019-06-13 01:50:21 +030012636static enum sigma_cmd_result cmd_sta_add_credential(struct sigma_dut *dut,
12637 struct sigma_conn *conn,
12638 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012639{
12640 const char *intf = get_param(cmd, "Interface");
12641 const char *type;
12642
12643 start_sta_mode(dut);
12644
12645 type = get_param(cmd, "Type");
12646 if (!type)
12647 return -1;
12648
12649 if (strcasecmp(type, "uname_pwd") == 0)
12650 return sta_add_credential_uname_pwd(dut, conn, intf, cmd);
12651
12652 if (strcasecmp(type, "sim") == 0)
12653 return sta_add_credential_sim(dut, conn, intf, cmd);
12654
12655 if (strcasecmp(type, "cert") == 0)
12656 return sta_add_credential_cert(dut, conn, intf, cmd);
12657
12658 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported credential "
12659 "type");
12660 return 0;
12661}
12662
12663
Jouni Malinenf7222712019-06-13 01:50:21 +030012664static enum sigma_cmd_result cmd_sta_scan(struct sigma_dut *dut,
12665 struct sigma_conn *conn,
12666 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012667{
12668 const char *intf = get_param(cmd, "Interface");
vamsi krishna89ad8c62017-09-19 12:51:18 +053012669 const char *val, *bssid, *ssid;
Arif Hussain66a4af02019-02-07 15:04:51 -080012670 char buf[4096];
vamsi krishna89ad8c62017-09-19 12:51:18 +053012671 char ssid_hex[65];
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012672 int res;
12673
Jouni Malinen8c1abeb2019-11-06 18:48:34 +020012674 start_sta_mode(dut);
12675
Arif Hussain66a4af02019-02-07 15:04:51 -080012676 val = get_param(cmd, "GetParameter");
12677 if (val && strcmp(val, "SSID_BSSID") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012678 if (get_wpa_ssid_bssid(dut, get_station_ifname(dut),
Arif Hussain66a4af02019-02-07 15:04:51 -080012679 buf, sizeof(buf)) < 0) {
12680 sigma_dut_print(dut, DUT_MSG_ERROR,
12681 "Could not get ssid bssid");
12682 return ERROR_SEND_STATUS;
12683 }
12684
12685 sigma_dut_print(dut, DUT_MSG_INFO, "%s", buf);
12686 send_resp(dut, conn, SIGMA_COMPLETE, buf);
12687 return STATUS_SENT;
12688 }
12689
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012690 val = get_param(cmd, "HESSID");
12691 if (val) {
12692 res = snprintf(buf, sizeof(buf), "SET hessid %s", val);
12693 if (res < 0 || res >= (int) sizeof(buf))
12694 return -1;
12695 wpa_command(intf, buf);
12696 }
12697
12698 val = get_param(cmd, "ACCS_NET_TYPE");
12699 if (val) {
12700 res = snprintf(buf, sizeof(buf), "SET access_network_type %s",
12701 val);
12702 if (res < 0 || res >= (int) sizeof(buf))
12703 return -1;
12704 wpa_command(intf, buf);
12705 }
12706
vamsi krishna89ad8c62017-09-19 12:51:18 +053012707 bssid = get_param(cmd, "Bssid");
12708 ssid = get_param(cmd, "Ssid");
12709
12710 if (ssid) {
12711 if (2 * strlen(ssid) >= sizeof(ssid_hex)) {
12712 send_resp(dut, conn, SIGMA_ERROR,
12713 "ErrorCode,Too long SSID");
12714 return 0;
12715 }
12716 ascii2hexstr(ssid, ssid_hex);
12717 }
12718
12719 res = snprintf(buf, sizeof(buf), "SCAN%s%s%s%s",
12720 bssid ? " bssid=": "",
12721 bssid ? bssid : "",
12722 ssid ? " ssid " : "",
12723 ssid ? ssid_hex : "");
12724 if (res < 0 || res >= (int) sizeof(buf))
12725 return -1;
12726
12727 if (wpa_command(intf, buf)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012728 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not start "
12729 "scan");
12730 return 0;
12731 }
12732
12733 return 1;
12734}
12735
12736
Jouni Malinenf7222712019-06-13 01:50:21 +030012737static enum sigma_cmd_result cmd_sta_scan_bss(struct sigma_dut *dut,
12738 struct sigma_conn *conn,
12739 struct sigma_cmd *cmd)
Jouni Malinen5e5d43d2018-01-10 17:29:33 +020012740{
12741 const char *intf = get_param(cmd, "Interface");
12742 const char *bssid;
12743 char buf[4096], *pos;
12744 int freq, chan;
12745 char *ssid;
12746 char resp[100];
12747 int res;
12748 struct wpa_ctrl *ctrl;
12749
12750 bssid = get_param(cmd, "BSSID");
12751 if (!bssid) {
12752 send_resp(dut, conn, SIGMA_INVALID,
12753 "errorCode,BSSID argument is missing");
12754 return 0;
12755 }
12756
12757 ctrl = open_wpa_mon(intf);
12758 if (!ctrl) {
12759 sigma_dut_print(dut, DUT_MSG_ERROR,
12760 "Failed to open wpa_supplicant monitor connection");
12761 return -1;
12762 }
12763
12764 if (wpa_command(intf, "SCAN TYPE=ONLY")) {
12765 send_resp(dut, conn, SIGMA_ERROR,
12766 "errorCode,Could not start scan");
12767 wpa_ctrl_detach(ctrl);
12768 wpa_ctrl_close(ctrl);
12769 return 0;
12770 }
12771
12772 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
12773 buf, sizeof(buf));
12774
12775 wpa_ctrl_detach(ctrl);
12776 wpa_ctrl_close(ctrl);
12777
12778 if (res < 0) {
12779 send_resp(dut, conn, SIGMA_ERROR,
12780 "errorCode,Scan did not complete");
12781 return 0;
12782 }
12783
12784 snprintf(buf, sizeof(buf), "BSS %s", bssid);
12785 if (wpa_command_resp(intf, buf, buf, sizeof(buf)) < 0 ||
12786 strncmp(buf, "id=", 3) != 0) {
12787 send_resp(dut, conn, SIGMA_ERROR,
12788 "errorCode,Specified BSSID not found");
12789 return 0;
12790 }
12791
12792 pos = strstr(buf, "\nfreq=");
12793 if (!pos) {
12794 send_resp(dut, conn, SIGMA_ERROR,
12795 "errorCode,Channel not found");
12796 return 0;
12797 }
12798 freq = atoi(pos + 6);
12799 chan = freq_to_channel(freq);
12800
12801 pos = strstr(buf, "\nssid=");
12802 if (!pos) {
12803 send_resp(dut, conn, SIGMA_ERROR,
12804 "errorCode,SSID not found");
12805 return 0;
12806 }
12807 ssid = pos + 6;
12808 pos = strchr(ssid, '\n');
12809 if (pos)
12810 *pos = '\0';
12811 snprintf(resp, sizeof(resp), "ssid,%s,bsschannel,%d", ssid, chan);
12812 send_resp(dut, conn, SIGMA_COMPLETE, resp);
12813 return 0;
12814}
12815
12816
Jouni Malinenf7222712019-06-13 01:50:21 +030012817static enum sigma_cmd_result cmd_sta_set_systime(struct sigma_dut *dut,
12818 struct sigma_conn *conn,
12819 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012820{
12821#ifdef __linux__
12822 struct timeval tv;
12823 struct tm tm;
12824 time_t t;
12825 const char *val;
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +053012826 int v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012827
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012828 wpa_command(get_station_ifname(dut), "PMKSA_FLUSH");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012829
12830 memset(&tm, 0, sizeof(tm));
12831 val = get_param(cmd, "seconds");
12832 if (val)
12833 tm.tm_sec = atoi(val);
12834 val = get_param(cmd, "minutes");
12835 if (val)
12836 tm.tm_min = atoi(val);
12837 val = get_param(cmd, "hours");
12838 if (val)
12839 tm.tm_hour = atoi(val);
12840 val = get_param(cmd, "date");
12841 if (val)
12842 tm.tm_mday = atoi(val);
12843 val = get_param(cmd, "month");
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +053012844 if (val) {
12845 v = atoi(val);
12846 if (v < 1 || v > 12) {
12847 send_resp(dut, conn, SIGMA_INVALID,
12848 "errorCode,Invalid month");
12849 return 0;
12850 }
12851 tm.tm_mon = v - 1;
12852 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012853 val = get_param(cmd, "year");
12854 if (val) {
12855 int year = atoi(val);
12856#ifdef ANDROID
12857 if (year > 2035)
12858 year = 2035; /* years beyond 2035 not supported */
12859#endif /* ANDROID */
12860 tm.tm_year = year - 1900;
12861 }
12862 t = mktime(&tm);
12863 if (t == (time_t) -1) {
12864 send_resp(dut, conn, SIGMA_ERROR,
12865 "errorCode,Invalid date or time");
12866 return 0;
12867 }
12868
12869 memset(&tv, 0, sizeof(tv));
12870 tv.tv_sec = t;
12871
12872 if (settimeofday(&tv, NULL) < 0) {
12873 sigma_dut_print(dut, DUT_MSG_INFO, "settimeofday failed: %s",
12874 strerror(errno));
12875 send_resp(dut, conn, SIGMA_ERROR,
12876 "errorCode,Failed to set time");
12877 return 0;
12878 }
12879
12880 return 1;
12881#endif /* __linux__ */
12882
12883 return -1;
12884}
12885
12886
Jouni Malinenf7222712019-06-13 01:50:21 +030012887static enum sigma_cmd_result cmd_sta_osu(struct sigma_dut *dut,
12888 struct sigma_conn *conn,
12889 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012890{
12891 const char *intf = get_param(cmd, "Interface");
Jouni Malinen4c8681c2018-09-12 23:28:11 +030012892 const char *name, *osu_ssid, *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012893 int prod_ess_assoc = 1;
Jouni Malinen4c8681c2018-09-12 23:28:11 +030012894 char buf[300], bssid[100], ssid[100];
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012895 int res;
12896 struct wpa_ctrl *ctrl;
12897
12898 name = get_param(cmd, "osuFriendlyName");
Jouni Malinen4c8681c2018-09-12 23:28:11 +030012899 osu_ssid = get_param(cmd, "osu_ssid");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012900
12901 val = get_param(cmd, "ProdESSAssoc");
12902 if (val)
12903 prod_ess_assoc = atoi(val);
12904
12905 kill_dhcp_client(dut, intf);
12906 if (start_dhcp_client(dut, intf) < 0)
12907 return -2;
12908
12909 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger OSU");
12910 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
12911 res = snprintf(buf, sizeof(buf),
Jouni Malinen4c8681c2018-09-12 23:28:11 +030012912 "%s %s%s%s %s%s%s signup osu-ca.pem",
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012913 prod_ess_assoc ? "" : "-N",
12914 name ? "-O'" : "", name ? name : "",
Jouni Malinen4c8681c2018-09-12 23:28:11 +030012915 name ? "'" : "",
12916 osu_ssid ? "-o'" : "", osu_ssid ? osu_ssid : "",
12917 osu_ssid ? "'" : "");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012918
Kanchanapally, Vidyullatha12b66762015-12-31 16:46:42 +053012919 hs2_set_policy(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012920 if (run_hs20_osu(dut, buf) < 0) {
12921 FILE *f;
12922
12923 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to complete OSU");
12924
12925 f = fopen("hs20-osu-client.res", "r");
12926 if (f) {
12927 char resp[400], res[300], *pos;
12928 if (!fgets(res, sizeof(res), f))
12929 res[0] = '\0';
12930 pos = strchr(res, '\n');
12931 if (pos)
12932 *pos = '\0';
12933 fclose(f);
12934 sigma_dut_summary(dut, "hs20-osu-client provisioning failed: %s",
12935 res);
12936 snprintf(resp, sizeof(resp), "notify-send '%s'", res);
12937 if (system(resp) != 0) {
12938 }
12939 snprintf(resp, sizeof(resp),
12940 "SSID,,BSSID,,failureReason,%s", res);
12941 send_resp(dut, conn, SIGMA_COMPLETE, resp);
12942 return 0;
12943 }
12944
12945 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
12946 return 0;
12947 }
12948
12949 if (!prod_ess_assoc)
12950 goto report;
12951
12952 ctrl = open_wpa_mon(intf);
12953 if (ctrl == NULL) {
12954 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
12955 "wpa_supplicant monitor connection");
12956 return -1;
12957 }
12958
12959 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
12960 buf, sizeof(buf));
12961
12962 wpa_ctrl_detach(ctrl);
12963 wpa_ctrl_close(ctrl);
12964
12965 if (res < 0) {
12966 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to connect to "
12967 "network after OSU");
12968 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
12969 return 0;
12970 }
12971
12972report:
12973 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
12974 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
12975 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to get BSSID/SSID");
12976 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
12977 return 0;
12978 }
12979
12980 snprintf(buf, sizeof(buf), "SSID,%s,BSSID,%s", ssid, bssid);
12981 send_resp(dut, conn, SIGMA_COMPLETE, buf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012982 return 0;
12983}
12984
12985
Jouni Malinenf7222712019-06-13 01:50:21 +030012986static enum sigma_cmd_result cmd_sta_policy_update(struct sigma_dut *dut,
12987 struct sigma_conn *conn,
12988 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012989{
12990 const char *val;
12991 int timeout = 120;
12992
12993 val = get_param(cmd, "PolicyUpdate");
12994 if (val == NULL || atoi(val) == 0)
12995 return 1; /* No operation requested */
12996
12997 val = get_param(cmd, "Timeout");
12998 if (val)
12999 timeout = atoi(val);
13000
13001 if (timeout) {
13002 /* TODO: time out the command and return
13003 * PolicyUpdateStatus,TIMEOUT if needed. */
13004 }
13005
13006 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger policy update");
13007 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
13008 if (run_hs20_osu(dut, "pol_upd fqdn=wi-fi.org") < 0) {
13009 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,FAIL");
13010 return 0;
13011 }
13012
13013 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,SUCCESS");
13014 return 0;
13015}
13016
13017
Jouni Malinenf7222712019-06-13 01:50:21 +030013018static enum sigma_cmd_result cmd_sta_er_config(struct sigma_dut *dut,
13019 struct sigma_conn *conn,
13020 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013021{
13022 struct wpa_ctrl *ctrl;
13023 const char *intf = get_param(cmd, "Interface");
13024 const char *bssid = get_param(cmd, "Bssid");
13025 const char *ssid = get_param(cmd, "SSID");
13026 const char *security = get_param(cmd, "Security");
13027 const char *passphrase = get_param(cmd, "Passphrase");
13028 const char *pin = get_param(cmd, "PIN");
13029 char buf[1000];
13030 char ssid_hex[200], passphrase_hex[200];
13031 const char *keymgmt, *cipher;
13032
13033 if (intf == NULL)
Jouni Malinen016ae6c2019-11-04 17:00:01 +020013034 intf = get_main_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013035
13036 if (!bssid) {
13037 send_resp(dut, conn, SIGMA_ERROR,
13038 "ErrorCode,Missing Bssid argument");
13039 return 0;
13040 }
13041
13042 if (!ssid) {
13043 send_resp(dut, conn, SIGMA_ERROR,
13044 "ErrorCode,Missing SSID argument");
13045 return 0;
13046 }
13047
13048 if (!security) {
13049 send_resp(dut, conn, SIGMA_ERROR,
13050 "ErrorCode,Missing Security argument");
13051 return 0;
13052 }
13053
13054 if (!passphrase) {
13055 send_resp(dut, conn, SIGMA_ERROR,
13056 "ErrorCode,Missing Passphrase argument");
13057 return 0;
13058 }
13059
13060 if (!pin) {
13061 send_resp(dut, conn, SIGMA_ERROR,
13062 "ErrorCode,Missing PIN argument");
13063 return 0;
13064 }
13065
vamsi krishna8c9c1562017-05-12 15:51:46 +053013066 if (2 * strlen(ssid) >= sizeof(ssid_hex) ||
13067 2 * strlen(passphrase) >= sizeof(passphrase_hex)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013068 send_resp(dut, conn, SIGMA_ERROR,
13069 "ErrorCode,Too long SSID/passphrase");
13070 return 0;
13071 }
13072
13073 ctrl = open_wpa_mon(intf);
13074 if (ctrl == NULL) {
13075 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
13076 "wpa_supplicant monitor connection");
13077 return -2;
13078 }
13079
13080 if (strcasecmp(security, "wpa2-psk") == 0) {
13081 keymgmt = "WPA2PSK";
13082 cipher = "CCMP";
13083 } else {
13084 wpa_ctrl_detach(ctrl);
13085 wpa_ctrl_close(ctrl);
13086 send_resp(dut, conn, SIGMA_ERROR,
13087 "ErrorCode,Unsupported Security value");
13088 return 0;
13089 }
13090
13091 ascii2hexstr(ssid, ssid_hex);
13092 ascii2hexstr(passphrase, passphrase_hex);
13093 snprintf(buf, sizeof(buf), "WPS_REG %s %s %s %s %s %s",
13094 bssid, pin, ssid_hex, keymgmt, cipher, passphrase_hex);
13095
13096 if (wpa_command(intf, buf) < 0) {
13097 wpa_ctrl_detach(ctrl);
13098 wpa_ctrl_close(ctrl);
13099 send_resp(dut, conn, SIGMA_ERROR,
13100 "ErrorCode,Failed to start registrar");
13101 return 0;
13102 }
13103
13104 snprintf(dut->er_oper_bssid, sizeof(dut->er_oper_bssid), "%s", bssid);
13105 dut->er_oper_performed = 1;
13106
13107 return wps_connection_event(dut, conn, ctrl, intf, 0);
13108}
13109
13110
Jouni Malinenf7222712019-06-13 01:50:21 +030013111static enum sigma_cmd_result
13112cmd_sta_wps_connect_pw_token(struct sigma_dut *dut, struct sigma_conn *conn,
13113 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013114{
13115 struct wpa_ctrl *ctrl;
13116 const char *intf = get_param(cmd, "Interface");
13117 const char *bssid = get_param(cmd, "Bssid");
13118 char buf[100];
13119
13120 if (!bssid) {
13121 send_resp(dut, conn, SIGMA_ERROR,
13122 "ErrorCode,Missing Bssid argument");
13123 return 0;
13124 }
13125
13126 ctrl = open_wpa_mon(intf);
13127 if (ctrl == NULL) {
13128 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
13129 "wpa_supplicant monitor connection");
13130 return -2;
13131 }
13132
13133 snprintf(buf, sizeof(buf), "WPS_NFC %s", bssid);
13134
13135 if (wpa_command(intf, buf) < 0) {
13136 wpa_ctrl_detach(ctrl);
13137 wpa_ctrl_close(ctrl);
13138 send_resp(dut, conn, SIGMA_ERROR,
13139 "ErrorCode,Failed to start registrar");
13140 return 0;
13141 }
13142
13143 return wps_connection_event(dut, conn, ctrl, intf, 0);
13144}
13145
13146
Jouni Malinenf7222712019-06-13 01:50:21 +030013147static enum sigma_cmd_result cmd_start_wps_registration(struct sigma_dut *dut,
13148 struct sigma_conn *conn,
13149 struct sigma_cmd *cmd)
vamsi krishna9b144002017-09-20 13:28:13 +053013150{
13151 struct wpa_ctrl *ctrl;
13152 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020013153 const char *network_mode = get_param(cmd, "network_mode");
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020013154 const char *config_method = get_param(cmd, "WPSConfigMethod");
13155 const char *role;
vamsi krishna9b144002017-09-20 13:28:13 +053013156 int res;
13157 char buf[256];
13158 const char *events[] = {
13159 "CTRL-EVENT-CONNECTED",
13160 "WPS-OVERLAP-DETECTED",
13161 "WPS-TIMEOUT",
13162 "WPS-FAIL",
13163 NULL
13164 };
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020013165 int id = 0;
vamsi krishna9b144002017-09-20 13:28:13 +053013166
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020013167 /* 60G WPS tests do not pass Interface parameter */
13168 if (!intf)
Jouni Malinen016ae6c2019-11-04 17:00:01 +020013169 intf = get_main_ifname(dut);
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020013170
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020013171 if (dut->mode == SIGMA_MODE_AP)
13172 return ap_wps_registration(dut, conn, cmd);
13173
13174 if (config_method) {
13175 /* WFA_CS_WPS_PIN_KEYPAD mode is set when using the
13176 * sta_wps_enter_pin before calling start_wps_registration. */
13177 if (strcasecmp(config_method, "PBC") == 0)
13178 dut->wps_method = WFA_CS_WPS_PBC;
13179 }
13180 if (dut->wps_method == WFA_CS_WPS_NOT_READY) {
13181 send_resp(dut, conn, SIGMA_ERROR,
13182 "ErrorCode,WPS parameters not yet set");
13183 return STATUS_SENT;
13184 }
13185
13186 /* Make sure WPS is enabled (also for STA mode) */
13187 dut->wps_disable = 0;
13188
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020013189 if (dut->band == WPS_BAND_60G && network_mode &&
13190 strcasecmp(network_mode, "PBSS") == 0) {
13191 sigma_dut_print(dut, DUT_MSG_DEBUG,
13192 "Set PBSS network mode, network id %d", id);
Jouni Malinen016ae6c2019-11-04 17:00:01 +020013193 if (set_network(get_station_ifname(dut), id, "pbss", "1") < 0)
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020013194 return -2;
13195 }
13196
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020013197 if (dut->force_rsn_ie) {
13198 sigma_dut_print(dut, DUT_MSG_DEBUG, "Force RSN_IE: %d",
13199 dut->force_rsn_ie);
13200 if (sta_60g_force_rsn_ie(dut, dut->force_rsn_ie) < 0) {
13201 sigma_dut_print(dut, DUT_MSG_INFO,
13202 "Failed to force RSN_IE");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020013203 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020013204 }
13205 }
13206
vamsi krishna9b144002017-09-20 13:28:13 +053013207 ctrl = open_wpa_mon(intf);
13208 if (!ctrl) {
13209 sigma_dut_print(dut, DUT_MSG_ERROR,
13210 "Failed to open wpa_supplicant monitor connection");
13211 return -2;
13212 }
13213
13214 role = get_param(cmd, "WpsRole");
13215 if (!role) {
13216 send_resp(dut, conn, SIGMA_INVALID,
13217 "ErrorCode,WpsRole not provided");
13218 goto fail;
13219 }
13220
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020013221 if (strcasecmp(role, "Enrollee") != 0) {
13222 /* Registrar role for STA not supported */
13223 send_resp(dut, conn, SIGMA_ERROR,
13224 "ErrorCode,Unsupported WpsRole value");
13225 goto fail;
13226 }
13227
13228 if (is_60g_sigma_dut(dut)) {
13229 if (dut->wps_method == WFA_CS_WPS_PBC)
13230 snprintf(buf, sizeof(buf), "WPS_PBC");
13231 else /* WFA_CS_WPS_PIN_KEYPAD */
13232 snprintf(buf, sizeof(buf), "WPS_PIN any %s",
13233 dut->wps_pin);
13234 if (wpa_command(intf, buf) < 0) {
13235 send_resp(dut, conn, SIGMA_ERROR,
13236 "ErrorCode,Failed to start WPS");
vamsi krishna9b144002017-09-20 13:28:13 +053013237 goto fail;
13238 }
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020013239 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
13240 if (res < 0) {
13241 send_resp(dut, conn, SIGMA_ERROR,
13242 "ErrorCode,WPS connection did not complete");
13243 goto fail;
13244 }
13245 if (strstr(buf, "WPS-TIMEOUT")) {
13246 send_resp(dut, conn, SIGMA_COMPLETE, "WpsState,NoPeer");
13247 } else if (strstr(buf, "WPS-OVERLAP-DETECTED")) {
13248 send_resp(dut, conn, SIGMA_COMPLETE,
13249 "WpsState,OverlapSession");
13250 } else if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
13251 send_resp(dut, conn, SIGMA_COMPLETE,
13252 "WpsState,Successful");
13253 } else {
13254 send_resp(dut, conn, SIGMA_COMPLETE,
13255 "WpsState,Failure");
13256 }
13257 } else {
13258 if (dut->wps_method == WFA_CS_WPS_PBC) {
vamsi krishna9b144002017-09-20 13:28:13 +053013259 if (wpa_command(intf, "WPS_PBC") < 0) {
13260 send_resp(dut, conn, SIGMA_ERROR,
13261 "ErrorCode,Failed to enable PBC");
13262 goto fail;
13263 }
13264 } else {
13265 /* TODO: PIN method */
13266 send_resp(dut, conn, SIGMA_ERROR,
13267 "ErrorCode,Unsupported WpsConfigMethod value");
13268 goto fail;
13269 }
13270 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
13271 if (res < 0) {
13272 send_resp(dut, conn, SIGMA_ERROR,
13273 "ErrorCode,WPS connection did not complete");
13274 goto fail;
13275 }
13276 if (strstr(buf, "WPS-TIMEOUT")) {
13277 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,NoPeer");
13278 } else if (strstr(buf, "WPS-OVERLAP-DETECTED")) {
13279 send_resp(dut, conn, SIGMA_ERROR,
13280 "ErrorCode,OverlapSession");
13281 } else if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
13282 send_resp(dut, conn, SIGMA_COMPLETE, "Successful");
13283 } else {
13284 send_resp(dut, conn, SIGMA_ERROR,
13285 "ErrorCode,WPS operation failed");
13286 }
vamsi krishna9b144002017-09-20 13:28:13 +053013287 }
13288
13289fail:
13290 wpa_ctrl_detach(ctrl);
13291 wpa_ctrl_close(ctrl);
13292 return 0;
13293}
13294
13295
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013296static int req_intf(struct sigma_cmd *cmd)
13297{
13298 return get_param(cmd, "interface") == NULL ? -1 : 0;
13299}
13300
13301
13302void sta_register_cmds(void)
13303{
13304 sigma_dut_reg_cmd("sta_get_ip_config", req_intf,
13305 cmd_sta_get_ip_config);
13306 sigma_dut_reg_cmd("sta_set_ip_config", req_intf,
13307 cmd_sta_set_ip_config);
13308 sigma_dut_reg_cmd("sta_get_info", req_intf, cmd_sta_get_info);
13309 sigma_dut_reg_cmd("sta_get_mac_address", req_intf,
13310 cmd_sta_get_mac_address);
13311 sigma_dut_reg_cmd("sta_is_connected", req_intf, cmd_sta_is_connected);
13312 sigma_dut_reg_cmd("sta_verify_ip_connection", req_intf,
13313 cmd_sta_verify_ip_connection);
13314 sigma_dut_reg_cmd("sta_get_bssid", req_intf, cmd_sta_get_bssid);
13315 sigma_dut_reg_cmd("sta_set_encryption", req_intf,
13316 cmd_sta_set_encryption);
13317 sigma_dut_reg_cmd("sta_set_psk", req_intf, cmd_sta_set_psk);
13318 sigma_dut_reg_cmd("sta_set_eaptls", req_intf, cmd_sta_set_eaptls);
13319 sigma_dut_reg_cmd("sta_set_eapttls", req_intf, cmd_sta_set_eapttls);
13320 sigma_dut_reg_cmd("sta_set_eapsim", req_intf, cmd_sta_set_eapsim);
13321 sigma_dut_reg_cmd("sta_set_peap", req_intf, cmd_sta_set_peap);
13322 sigma_dut_reg_cmd("sta_set_eapfast", req_intf, cmd_sta_set_eapfast);
13323 sigma_dut_reg_cmd("sta_set_eapaka", req_intf, cmd_sta_set_eapaka);
13324 sigma_dut_reg_cmd("sta_set_eapakaprime", req_intf,
13325 cmd_sta_set_eapakaprime);
13326 sigma_dut_reg_cmd("sta_set_security", req_intf, cmd_sta_set_security);
13327 sigma_dut_reg_cmd("sta_set_uapsd", req_intf, cmd_sta_set_uapsd);
13328 /* TODO: sta_set_ibss */
13329 /* TODO: sta_set_mode */
13330 sigma_dut_reg_cmd("sta_set_wmm", req_intf, cmd_sta_set_wmm);
13331 sigma_dut_reg_cmd("sta_associate", req_intf, cmd_sta_associate);
13332 /* TODO: sta_up_load */
13333 sigma_dut_reg_cmd("sta_preset_testparameters", req_intf,
13334 cmd_sta_preset_testparameters);
13335 /* TODO: sta_set_system */
13336 sigma_dut_reg_cmd("sta_set_11n", req_intf, cmd_sta_set_11n);
13337 /* TODO: sta_set_rifs_test */
13338 sigma_dut_reg_cmd("sta_set_wireless", req_intf, cmd_sta_set_wireless);
13339 sigma_dut_reg_cmd("sta_send_addba", req_intf, cmd_sta_send_addba);
13340 /* TODO: sta_send_coexist_mgmt */
13341 sigma_dut_reg_cmd("sta_disconnect", req_intf, cmd_sta_disconnect);
13342 sigma_dut_reg_cmd("sta_reassoc", req_intf, cmd_sta_reassoc);
13343 sigma_dut_reg_cmd("sta_reassociate", req_intf, cmd_sta_reassoc);
13344 sigma_dut_reg_cmd("sta_reset_default", req_intf,
13345 cmd_sta_reset_default);
13346 sigma_dut_reg_cmd("sta_send_frame", req_intf, cmd_sta_send_frame);
13347 sigma_dut_reg_cmd("sta_set_macaddr", req_intf, cmd_sta_set_macaddr);
13348 sigma_dut_reg_cmd("sta_set_rfeature", req_intf, cmd_sta_set_rfeature);
13349 sigma_dut_reg_cmd("sta_set_radio", req_intf, cmd_sta_set_radio);
13350 sigma_dut_reg_cmd("sta_set_pwrsave", req_intf, cmd_sta_set_pwrsave);
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020013351 sigma_dut_reg_cmd("sta_set_power_save", req_intf, cmd_sta_set_pwrsave);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013352 sigma_dut_reg_cmd("sta_bssid_pool", req_intf, cmd_sta_bssid_pool);
13353 sigma_dut_reg_cmd("sta_reset_parm", req_intf, cmd_sta_reset_parm);
13354 sigma_dut_reg_cmd("sta_get_key", req_intf, cmd_sta_get_key);
13355 sigma_dut_reg_cmd("sta_hs2_associate", req_intf,
13356 cmd_sta_hs2_associate);
Jouni Malinenb639f1c2018-09-13 02:39:46 +030013357 sigma_dut_reg_cmd("sta_hs2_venue_info", req_intf,
13358 cmd_sta_hs2_venue_info);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013359 sigma_dut_reg_cmd("sta_add_credential", req_intf,
13360 cmd_sta_add_credential);
13361 sigma_dut_reg_cmd("sta_scan", req_intf, cmd_sta_scan);
Jouni Malinen5e5d43d2018-01-10 17:29:33 +020013362 sigma_dut_reg_cmd("sta_scan_bss", req_intf, cmd_sta_scan_bss);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013363 sigma_dut_reg_cmd("sta_set_systime", NULL, cmd_sta_set_systime);
13364 sigma_dut_reg_cmd("sta_osu", req_intf, cmd_sta_osu);
13365 sigma_dut_reg_cmd("sta_policy_update", req_intf, cmd_sta_policy_update);
13366 sigma_dut_reg_cmd("sta_er_config", NULL, cmd_sta_er_config);
13367 sigma_dut_reg_cmd("sta_wps_connect_pw_token", req_intf,
13368 cmd_sta_wps_connect_pw_token);
Jouni Malinen82905202018-04-29 17:20:10 +030013369 sigma_dut_reg_cmd("sta_exec_action", NULL, cmd_sta_exec_action);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013370 sigma_dut_reg_cmd("sta_get_events", req_intf, cmd_sta_get_events);
13371 sigma_dut_reg_cmd("sta_get_parameter", req_intf, cmd_sta_get_parameter);
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020013372 sigma_dut_reg_cmd("start_wps_registration", NULL,
vamsi krishna9b144002017-09-20 13:28:13 +053013373 cmd_start_wps_registration);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013374}