blob: e4d26d24267a6dd75565922412126b72dffd62a9 [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__
Sarvepalli, Rajesh Babua76c6442016-03-18 20:34:26 +0530957 if (get_driver_type() == DRIVER_OPENWRT)
958 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
1102static int cmd_sta_get_ip_config(struct sigma_dut *dut,
1103 struct sigma_conn *conn,
1104 struct sigma_cmd *cmd)
1105{
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
1115 if (strcmp(intf, get_main_ifname()) == 0)
1116 ifname = get_station_ifname();
1117 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 Malinencd4e3c32015-10-29 12:39:56 +02001377static int cmd_sta_set_ip_config(struct sigma_dut *dut,
1378 struct sigma_conn *conn,
1379 struct sigma_cmd *cmd)
1380{
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
1390 if (strcmp(intf, get_main_ifname()) == 0)
1391 ifname = get_station_ifname();
1392 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
1548static int cmd_sta_get_info(struct sigma_dut *dut, struct sigma_conn *conn,
1549 struct sigma_cmd *cmd)
1550{
1551 /* const char *intf = get_param(cmd, "Interface"); */
1552 /* TODO: could report more details here */
1553 send_resp(dut, conn, SIGMA_COMPLETE, "vendor,Atheros");
1554 return 0;
1555}
1556
1557
1558static int cmd_sta_get_mac_address(struct sigma_dut *dut,
1559 struct sigma_conn *conn,
1560 struct sigma_cmd *cmd)
1561{
1562 /* const char *intf = get_param(cmd, "Interface"); */
1563 char addr[20], resp[50];
1564
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05301565 if (dut->dev_role == DEVROLE_STA_CFON)
1566 return sta_cfon_get_mac_address(dut, conn, cmd);
1567
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001568 if (get_wpa_status(get_station_ifname(), "address", addr, sizeof(addr))
1569 < 0)
1570 return -2;
1571
1572 snprintf(resp, sizeof(resp), "mac,%s", addr);
1573 send_resp(dut, conn, SIGMA_COMPLETE, resp);
1574 return 0;
1575}
1576
1577
1578static int cmd_sta_is_connected(struct sigma_dut *dut, struct sigma_conn *conn,
1579 struct sigma_cmd *cmd)
1580{
1581 /* const char *intf = get_param(cmd, "Interface"); */
1582 int connected = 0;
1583 char result[32];
1584 if (get_wpa_status(get_station_ifname(), "wpa_state", result,
1585 sizeof(result)) < 0) {
1586 sigma_dut_print(dut, DUT_MSG_INFO, "Could not get interface "
1587 "%s status", get_station_ifname());
1588 return -2;
1589 }
1590
1591 sigma_dut_print(dut, DUT_MSG_DEBUG, "wpa_state=%s", result);
1592 if (strncmp(result, "COMPLETED", 9) == 0)
1593 connected = 1;
1594
1595 if (connected)
1596 send_resp(dut, conn, SIGMA_COMPLETE, "connected,1");
1597 else
1598 send_resp(dut, conn, SIGMA_COMPLETE, "connected,0");
1599
1600 return 0;
1601}
1602
1603
1604static int cmd_sta_verify_ip_connection(struct sigma_dut *dut,
1605 struct sigma_conn *conn,
1606 struct sigma_cmd *cmd)
1607{
1608 /* const char *intf = get_param(cmd, "Interface"); */
1609 const char *dst, *timeout;
1610 int wait_time = 90;
1611 char buf[100];
1612 int res;
1613
1614 dst = get_param(cmd, "destination");
1615 if (dst == NULL || !is_ip_addr(dst))
1616 return -1;
1617
1618 timeout = get_param(cmd, "timeout");
1619 if (timeout) {
1620 wait_time = atoi(timeout);
1621 if (wait_time < 1)
1622 wait_time = 1;
1623 }
1624
1625 /* TODO: force renewal of IP lease if DHCP is enabled */
1626
1627 snprintf(buf, sizeof(buf), "ping %s -c 3 -W %d", dst, wait_time);
1628 res = system(buf);
1629 sigma_dut_print(dut, DUT_MSG_DEBUG, "ping returned: %d", res);
1630 if (res == 0)
1631 send_resp(dut, conn, SIGMA_COMPLETE, "connected,1");
1632 else if (res == 256)
1633 send_resp(dut, conn, SIGMA_COMPLETE, "connected,0");
1634 else
1635 return -2;
1636
1637 return 0;
1638}
1639
1640
1641static int cmd_sta_get_bssid(struct sigma_dut *dut, struct sigma_conn *conn,
1642 struct sigma_cmd *cmd)
1643{
1644 /* const char *intf = get_param(cmd, "Interface"); */
1645 char bssid[20], resp[50];
1646
1647 if (get_wpa_status(get_station_ifname(), "bssid", bssid, sizeof(bssid))
1648 < 0)
Peng Xub8fc5cc2017-05-10 17:27:28 -07001649 strlcpy(bssid, "00:00:00:00:00:00", sizeof(bssid));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001650
1651 snprintf(resp, sizeof(resp), "bssid,%s", bssid);
1652 send_resp(dut, conn, SIGMA_COMPLETE, resp);
1653 return 0;
1654}
1655
1656
1657#ifdef __SAMSUNG__
1658static int add_use_network(const char *ifname)
1659{
1660 char buf[100];
1661
1662 snprintf(buf, sizeof(buf), "USE_NETWORK ON");
1663 wpa_command(ifname, buf);
1664 return 0;
1665}
1666#endif /* __SAMSUNG__ */
1667
1668
1669static int add_network_common(struct sigma_dut *dut, struct sigma_conn *conn,
1670 const char *ifname, struct sigma_cmd *cmd)
1671{
1672 const char *ssid = get_param(cmd, "ssid");
1673 int id;
1674 const char *val;
1675
1676 if (ssid == NULL)
1677 return -1;
1678
1679 start_sta_mode(dut);
1680
1681#ifdef __SAMSUNG__
1682 add_use_network(ifname);
1683#endif /* __SAMSUNG__ */
1684
1685 id = add_network(ifname);
1686 if (id < 0)
1687 return -2;
1688 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding network %d", id);
1689
1690 if (set_network_quoted(ifname, id, "ssid", ssid) < 0)
1691 return -2;
1692
1693 dut->infra_network_id = id;
1694 snprintf(dut->infra_ssid, sizeof(dut->infra_ssid), "%s", ssid);
1695
1696 val = get_param(cmd, "program");
1697 if (!val)
1698 val = get_param(cmd, "prog");
1699 if (val && strcasecmp(val, "hs2") == 0) {
1700 char buf[100];
1701 snprintf(buf, sizeof(buf), "ENABLE_NETWORK %d no-connect", id);
1702 wpa_command(ifname, buf);
1703
1704 val = get_param(cmd, "prefer");
1705 if (val && atoi(val) > 0)
1706 set_network(ifname, id, "priority", "1");
1707 }
1708
1709 return id;
1710}
1711
1712
1713static int cmd_sta_set_encryption(struct sigma_dut *dut,
1714 struct sigma_conn *conn,
1715 struct sigma_cmd *cmd)
1716{
1717 const char *intf = get_param(cmd, "Interface");
1718 const char *ssid = get_param(cmd, "ssid");
1719 const char *type = get_param(cmd, "encpType");
1720 const char *ifname;
1721 char buf[200];
1722 int id;
1723
1724 if (intf == NULL || ssid == NULL)
1725 return -1;
1726
1727 if (strcmp(intf, get_main_ifname()) == 0)
1728 ifname = get_station_ifname();
1729 else
1730 ifname = intf;
1731
1732 id = add_network_common(dut, conn, ifname, cmd);
1733 if (id < 0)
1734 return id;
1735
1736 if (set_network(ifname, id, "key_mgmt", "NONE") < 0)
1737 return -2;
1738
1739 if (type && strcasecmp(type, "wep") == 0) {
1740 const char *val;
1741 int i;
1742
1743 val = get_param(cmd, "activeKey");
1744 if (val) {
1745 int keyid;
1746 keyid = atoi(val);
1747 if (keyid < 1 || keyid > 4)
1748 return -1;
1749 snprintf(buf, sizeof(buf), "%d", keyid - 1);
1750 if (set_network(ifname, id, "wep_tx_keyidx", buf) < 0)
1751 return -2;
1752 }
1753
1754 for (i = 0; i < 4; i++) {
1755 snprintf(buf, sizeof(buf), "key%d", i + 1);
1756 val = get_param(cmd, buf);
1757 if (val == NULL)
1758 continue;
1759 snprintf(buf, sizeof(buf), "wep_key%d", i);
1760 if (set_network(ifname, id, buf, val) < 0)
1761 return -2;
1762 }
1763 }
1764
1765 return 1;
1766}
1767
1768
Jouni Malinene4fde732019-03-25 22:29:37 +02001769static int set_akm_suites(struct sigma_dut *dut, const char *ifname,
1770 int id, const char *val)
1771{
1772 char key_mgmt[200], *end, *pos;
1773 const char *in_pos = val;
1774
Jouni Malinen8179fee2019-03-28 03:19:47 +02001775 dut->akm_values = 0;
Jouni Malinene4fde732019-03-25 22:29:37 +02001776 pos = key_mgmt;
1777 end = pos + sizeof(key_mgmt);
1778 while (*in_pos) {
1779 int res, akm = atoi(in_pos);
1780 const char *str;
1781
Jouni Malinen8179fee2019-03-28 03:19:47 +02001782 if (akm >= 0 && akm < 32)
1783 dut->akm_values |= 1 << akm;
1784
Jouni Malinene4fde732019-03-25 22:29:37 +02001785 switch (akm) {
1786 case AKM_WPA_EAP:
1787 str = "WPA-EAP";
1788 break;
1789 case AKM_WPA_PSK:
1790 str = "WPA-PSK";
1791 break;
1792 case AKM_FT_EAP:
1793 str = "FT-EAP";
1794 break;
1795 case AKM_FT_PSK:
1796 str = "FT-PSK";
1797 break;
1798 case AKM_EAP_SHA256:
1799 str = "WPA-EAP-SHA256";
1800 break;
1801 case AKM_PSK_SHA256:
1802 str = "WPA-PSK-SHA256";
1803 break;
1804 case AKM_SAE:
1805 str = "SAE";
1806 break;
1807 case AKM_FT_SAE:
1808 str = "FT-SAE";
1809 break;
1810 case AKM_SUITE_B:
1811 str = "WPA-EAP-SUITE-B-192";
1812 break;
1813 case AKM_FT_SUITE_B:
1814 str = "FT-EAP-SHA384";
1815 break;
1816 case AKM_FILS_SHA256:
1817 str = "FILS-SHA256";
1818 break;
1819 case AKM_FILS_SHA384:
1820 str = "FILS-SHA384";
1821 break;
1822 case AKM_FT_FILS_SHA256:
1823 str = "FT-FILS-SHA256";
1824 break;
1825 case AKM_FT_FILS_SHA384:
1826 str = "FT-FILS-SHA384";
1827 break;
1828 default:
1829 sigma_dut_print(dut, DUT_MSG_ERROR,
1830 "Unsupported AKMSuitetype %d", akm);
1831 return -1;
1832 }
1833
1834 res = snprintf(pos, end - pos, "%s%s",
1835 pos == key_mgmt ? "" : " ", str);
1836 if (res < 0 || res >= end - pos)
1837 return -1;
1838 pos += res;
1839
1840 in_pos = strchr(in_pos, ';');
1841 if (!in_pos)
1842 break;
1843 while (*in_pos == ';')
1844 in_pos++;
1845 }
1846 sigma_dut_print(dut, DUT_MSG_DEBUG, "AKMSuiteType %s --> %s",
1847 val, key_mgmt);
1848 return set_network(ifname, id, "key_mgmt", key_mgmt);
1849}
1850
1851
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001852static int set_wpa_common(struct sigma_dut *dut, struct sigma_conn *conn,
1853 const char *ifname, struct sigma_cmd *cmd)
1854{
1855 const char *val;
1856 int id;
Jouni Malinenad395a22017-09-01 21:13:46 +03001857 int cipher_set = 0;
Jouni Malinen47dcc952017-10-09 16:43:24 +03001858 int owe;
Sunil Duttc75a1e62018-01-11 20:47:50 +05301859 int suite_b = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001860
1861 id = add_network_common(dut, conn, ifname, cmd);
1862 if (id < 0)
1863 return id;
1864
Jouni Malinen47dcc952017-10-09 16:43:24 +03001865 val = get_param(cmd, "Type");
1866 owe = val && strcasecmp(val, "OWE") == 0;
1867
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001868 val = get_param(cmd, "keyMgmtType");
Jouni Malinen47dcc952017-10-09 16:43:24 +03001869 if (!val && owe)
1870 val = "OWE";
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001871 if (val == NULL) {
Jouni Malinene4fde732019-03-25 22:29:37 +02001872 /* keyMgmtType is being replaced with AKMSuiteType, so ignore
1873 * this missing parameter and assume proto=WPA2. */
1874 if (set_network(ifname, id, "proto", "WPA2") < 0)
1875 return ERROR_SEND_STATUS;
1876 } else if (strcasecmp(val, "wpa") == 0 ||
1877 strcasecmp(val, "wpa-psk") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001878 if (set_network(ifname, id, "proto", "WPA") < 0)
1879 return -2;
1880 } else if (strcasecmp(val, "wpa2") == 0 ||
1881 strcasecmp(val, "wpa2-psk") == 0 ||
1882 strcasecmp(val, "wpa2-ft") == 0 ||
1883 strcasecmp(val, "wpa2-sha256") == 0) {
1884 if (set_network(ifname, id, "proto", "WPA2") < 0)
1885 return -2;
Pradeep Reddy POTTETI6d04b3b2016-11-15 14:51:26 +05301886 } else if (strcasecmp(val, "wpa2-wpa-psk") == 0 ||
1887 strcasecmp(val, "wpa2-wpa-ent") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001888 if (set_network(ifname, id, "proto", "WPA WPA2") < 0)
1889 return -2;
Jouni Malinenad395a22017-09-01 21:13:46 +03001890 } else if (strcasecmp(val, "SuiteB") == 0) {
Sunil Duttc75a1e62018-01-11 20:47:50 +05301891 suite_b = 1;
Jouni Malinenad395a22017-09-01 21:13:46 +03001892 if (set_network(ifname, id, "proto", "WPA2") < 0)
1893 return -2;
Jouni Malinen47dcc952017-10-09 16:43:24 +03001894 } else if (strcasecmp(val, "OWE") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001895 } else {
1896 send_resp(dut, conn, SIGMA_INVALID, "errorCode,Unrecognized keyMgmtType value");
1897 return 0;
1898 }
1899
1900 val = get_param(cmd, "encpType");
Jouni Malinenad395a22017-09-01 21:13:46 +03001901 if (val) {
1902 cipher_set = 1;
1903 if (strcasecmp(val, "tkip") == 0) {
1904 if (set_network(ifname, id, "pairwise", "TKIP") < 0)
1905 return -2;
1906 } else if (strcasecmp(val, "aes-ccmp") == 0) {
1907 if (set_network(ifname, id, "pairwise", "CCMP") < 0)
1908 return -2;
1909 } else if (strcasecmp(val, "aes-ccmp-tkip") == 0) {
1910 if (set_network(ifname, id, "pairwise",
1911 "CCMP TKIP") < 0)
1912 return -2;
1913 } else if (strcasecmp(val, "aes-gcmp") == 0) {
1914 if (set_network(ifname, id, "pairwise", "GCMP") < 0)
1915 return -2;
1916 if (set_network(ifname, id, "group", "GCMP") < 0)
1917 return -2;
1918 } else {
1919 send_resp(dut, conn, SIGMA_ERROR,
1920 "errorCode,Unrecognized encpType value");
1921 return 0;
1922 }
1923 }
1924
1925 val = get_param(cmd, "PairwiseCipher");
1926 if (val) {
1927 cipher_set = 1;
1928 /* TODO: Support space separated list */
1929 if (strcasecmp(val, "AES-GCMP-256") == 0) {
1930 if (set_network(ifname, id, "pairwise", "GCMP-256") < 0)
1931 return -2;
1932 } else if (strcasecmp(val, "AES-CCMP-256") == 0) {
1933 if (set_network(ifname, id, "pairwise",
1934 "CCMP-256") < 0)
1935 return -2;
1936 } else if (strcasecmp(val, "AES-GCMP-128") == 0) {
1937 if (set_network(ifname, id, "pairwise", "GCMP") < 0)
1938 return -2;
1939 } else if (strcasecmp(val, "AES-CCMP-128") == 0) {
1940 if (set_network(ifname, id, "pairwise", "CCMP") < 0)
1941 return -2;
1942 } else {
1943 send_resp(dut, conn, SIGMA_ERROR,
1944 "errorCode,Unrecognized PairwiseCipher value");
1945 return 0;
1946 }
1947 }
1948
Jouni Malinen47dcc952017-10-09 16:43:24 +03001949 if (!cipher_set && !owe) {
Jouni Malinenad395a22017-09-01 21:13:46 +03001950 send_resp(dut, conn, SIGMA_ERROR,
1951 "errorCode,Missing encpType and PairwiseCipher");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001952 return 0;
1953 }
Jouni Malinenad395a22017-09-01 21:13:46 +03001954
1955 val = get_param(cmd, "GroupCipher");
1956 if (val) {
1957 if (strcasecmp(val, "AES-GCMP-256") == 0) {
1958 if (set_network(ifname, id, "group", "GCMP-256") < 0)
1959 return -2;
1960 } else if (strcasecmp(val, "AES-CCMP-256") == 0) {
1961 if (set_network(ifname, id, "group", "CCMP-256") < 0)
1962 return -2;
1963 } else if (strcasecmp(val, "AES-GCMP-128") == 0) {
1964 if (set_network(ifname, id, "group", "GCMP") < 0)
1965 return -2;
1966 } else if (strcasecmp(val, "AES-CCMP-128") == 0) {
1967 if (set_network(ifname, id, "group", "CCMP") < 0)
1968 return -2;
1969 } else {
1970 send_resp(dut, conn, SIGMA_ERROR,
1971 "errorCode,Unrecognized GroupCipher value");
1972 return 0;
1973 }
1974 }
1975
Jouni Malinen7b239522017-09-14 21:37:18 +03001976 val = get_param(cmd, "GroupMgntCipher");
Jouni Malinenad395a22017-09-01 21:13:46 +03001977 if (val) {
Jouni Malinene8898cb2017-09-26 17:55:26 +03001978 const char *cipher;
1979
1980 if (strcasecmp(val, "BIP-GMAC-256") == 0) {
1981 cipher = "BIP-GMAC-256";
1982 } else if (strcasecmp(val, "BIP-CMAC-256") == 0) {
1983 cipher = "BIP-CMAC-256";
1984 } else if (strcasecmp(val, "BIP-GMAC-128") == 0) {
1985 cipher = "BIP-GMAC-128";
1986 } else if (strcasecmp(val, "BIP-CMAC-128") == 0) {
1987 cipher = "AES-128-CMAC";
1988 } else {
1989 send_resp(dut, conn, SIGMA_INVALID,
1990 "errorCode,Unsupported GroupMgntCipher");
1991 return 0;
1992 }
1993 if (set_network(ifname, id, "group_mgmt", cipher) < 0) {
1994 send_resp(dut, conn, SIGMA_INVALID,
1995 "errorCode,Failed to set GroupMgntCipher");
1996 return 0;
1997 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001998 }
1999
Jouni Malinene4fde732019-03-25 22:29:37 +02002000 val = get_param(cmd, "AKMSuiteType");
2001 if (val && set_akm_suites(dut, ifname, id, val) < 0)
2002 return ERROR_SEND_STATUS;
2003
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002004 dut->sta_pmf = STA_PMF_DISABLED;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302005
2006 if (dut->program == PROGRAM_OCE) {
2007 dut->sta_pmf = STA_PMF_OPTIONAL;
2008 if (set_network(ifname, id, "ieee80211w", "1") < 0)
2009 return -2;
2010 }
2011
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002012 val = get_param(cmd, "PMF");
2013 if (val) {
2014 if (strcasecmp(val, "Required") == 0 ||
2015 strcasecmp(val, "Forced_Required") == 0) {
2016 dut->sta_pmf = STA_PMF_REQUIRED;
2017 if (set_network(ifname, id, "ieee80211w", "2") < 0)
2018 return -2;
2019 } else if (strcasecmp(val, "Optional") == 0) {
2020 dut->sta_pmf = STA_PMF_OPTIONAL;
2021 if (set_network(ifname, id, "ieee80211w", "1") < 0)
2022 return -2;
2023 } else if (strcasecmp(val, "Disabled") == 0 ||
Kiran Kumar Lokere07da3b22018-12-16 22:42:49 -08002024 strcasecmp(val, "Disable") == 0 ||
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002025 strcasecmp(val, "Forced_Disabled") == 0) {
2026 dut->sta_pmf = STA_PMF_DISABLED;
2027 } else {
2028 send_resp(dut, conn, SIGMA_INVALID, "errorCode,Unrecognized PMF value");
2029 return 0;
2030 }
Sunil Duttc75a1e62018-01-11 20:47:50 +05302031 } else if (owe || suite_b) {
Jouni Malinen1287cd72018-01-04 17:08:01 +02002032 dut->sta_pmf = STA_PMF_REQUIRED;
2033 if (set_network(ifname, id, "ieee80211w", "2") < 0)
2034 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002035 }
2036
2037 return id;
2038}
2039
2040
2041static int cmd_sta_set_psk(struct sigma_dut *dut, struct sigma_conn *conn,
2042 struct sigma_cmd *cmd)
2043{
2044 const char *intf = get_param(cmd, "Interface");
Jouni Malinen992a81e2017-08-22 13:57:47 +03002045 const char *type = get_param(cmd, "Type");
Jouni Malinen1287cd72018-01-04 17:08:01 +02002046 const char *pmf = get_param(cmd, "PMF");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002047 const char *network_mode = get_param(cmd, "network_mode");
Jouni Malinene4fde732019-03-25 22:29:37 +02002048 const char *akm = get_param(cmd, "AKMSuiteType");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002049 const char *ifname, *val, *alg;
2050 int id;
2051
2052 if (intf == NULL)
2053 return -1;
2054
2055 if (strcmp(intf, get_main_ifname()) == 0)
2056 ifname = get_station_ifname();
2057 else
2058 ifname = intf;
2059
2060 id = set_wpa_common(dut, conn, ifname, cmd);
2061 if (id < 0)
2062 return id;
2063
2064 val = get_param(cmd, "keyMgmtType");
2065 alg = get_param(cmd, "micAlg");
2066
Jouni Malinen992a81e2017-08-22 13:57:47 +03002067 if (type && strcasecmp(type, "SAE") == 0) {
Jouni Malinene4fde732019-03-25 22:29:37 +02002068 if (!akm && val && strcasecmp(val, "wpa2-ft") == 0) {
Jouni Malinen992a81e2017-08-22 13:57:47 +03002069 if (set_network(ifname, id, "key_mgmt", "FT-SAE") < 0)
2070 return -2;
Jouni Malinene4fde732019-03-25 22:29:37 +02002071 } else if (!akm) {
Jouni Malinen992a81e2017-08-22 13:57:47 +03002072 if (set_network(ifname, id, "key_mgmt", "SAE") < 0)
2073 return -2;
2074 }
2075 if (wpa_command(ifname, "SET sae_groups ") != 0) {
2076 sigma_dut_print(dut, DUT_MSG_ERROR,
2077 "Failed to clear sae_groups to default");
2078 return -2;
2079 }
Jouni Malinen1287cd72018-01-04 17:08:01 +02002080 if (!pmf) {
2081 dut->sta_pmf = STA_PMF_REQUIRED;
2082 if (set_network(ifname, id, "ieee80211w", "2") < 0)
2083 return -2;
2084 }
Jouni Malinen0ab50f42017-08-31 01:34:59 +03002085 } else if (type && strcasecmp(type, "PSK-SAE") == 0) {
2086 if (val && strcasecmp(val, "wpa2-ft") == 0) {
2087 if (set_network(ifname, id, "key_mgmt",
2088 "FT-SAE FT-PSK") < 0)
2089 return -2;
2090 } else {
2091 if (set_network(ifname, id, "key_mgmt",
2092 "SAE WPA-PSK") < 0)
2093 return -2;
2094 }
2095 if (wpa_command(ifname, "SET sae_groups ") != 0) {
2096 sigma_dut_print(dut, DUT_MSG_ERROR,
2097 "Failed to clear sae_groups to default");
2098 return -2;
2099 }
Jouni Malinen1287cd72018-01-04 17:08:01 +02002100 if (!pmf) {
2101 dut->sta_pmf = STA_PMF_OPTIONAL;
2102 if (set_network(ifname, id, "ieee80211w", "1") < 0)
2103 return -2;
2104 }
Jouni Malinen992a81e2017-08-22 13:57:47 +03002105 } else if (alg && strcasecmp(alg, "SHA-256") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002106 if (set_network(ifname, id, "key_mgmt", "WPA-PSK-SHA256") < 0)
2107 return -2;
2108 } else if (alg && strcasecmp(alg, "SHA-1") == 0) {
2109 if (set_network(ifname, id, "key_mgmt", "WPA-PSK") < 0)
2110 return -2;
Ashwini Patil6dbf7b02017-03-20 13:42:11 +05302111 } else if (val && strcasecmp(val, "wpa2-ft") == 0) {
2112 if (set_network(ifname, id, "key_mgmt", "FT-PSK") < 0)
2113 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002114 } else if ((val && strcasecmp(val, "wpa2-sha256") == 0) ||
2115 dut->sta_pmf == STA_PMF_REQUIRED) {
2116 if (set_network(ifname, id, "key_mgmt",
2117 "WPA-PSK WPA-PSK-SHA256") < 0)
2118 return -2;
Jouni Malinen77ff3f02019-03-28 03:45:40 +02002119 } else if (!akm && dut->sta_pmf == STA_PMF_OPTIONAL) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002120 if (set_network(ifname, id, "key_mgmt",
2121 "WPA-PSK WPA-PSK-SHA256") < 0)
2122 return -2;
Jouni Malinen77ff3f02019-03-28 03:45:40 +02002123 } else if (!akm) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002124 if (set_network(ifname, id, "key_mgmt", "WPA-PSK") < 0)
2125 return -2;
2126 }
2127
2128 val = get_param(cmd, "passPhrase");
2129 if (val == NULL)
2130 return -1;
Jouni Malinen2126f422017-10-11 23:24:33 +03002131 if (type && strcasecmp(type, "SAE") == 0) {
2132 if (set_network_quoted(ifname, id, "sae_password", val) < 0)
2133 return -2;
2134 } else {
2135 if (set_network_quoted(ifname, id, "psk", val) < 0)
2136 return -2;
2137 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002138
Jouni Malinen78d10c42019-03-25 22:34:32 +02002139 val = get_param(cmd, "PasswordId");
2140 if (val && set_network_quoted(ifname, id, "sae_password_id", val) < 0)
2141 return ERROR_SEND_STATUS;
2142
Jouni Malinen992a81e2017-08-22 13:57:47 +03002143 val = get_param(cmd, "ECGroupID");
2144 if (val) {
2145 char buf[50];
2146
2147 snprintf(buf, sizeof(buf), "SET sae_groups %u", atoi(val));
2148 if (wpa_command(ifname, buf) != 0) {
2149 sigma_dut_print(dut, DUT_MSG_ERROR,
2150 "Failed to clear sae_groups");
2151 return -2;
2152 }
2153 }
2154
Jouni Malinen68143132017-09-02 02:34:08 +03002155 val = get_param(cmd, "InvalidSAEElement");
2156 if (val) {
2157 free(dut->sae_commit_override);
2158 dut->sae_commit_override = strdup(val);
2159 }
2160
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002161 if (dut->program == PROGRAM_60GHZ && network_mode &&
2162 strcasecmp(network_mode, "PBSS") == 0 &&
2163 set_network(ifname, id, "pbss", "1") < 0)
2164 return -2;
2165
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002166 return 1;
2167}
2168
2169
2170static int set_eap_common(struct sigma_dut *dut, struct sigma_conn *conn,
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302171 const char *ifname, int username_identity,
2172 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002173{
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302174 const char *val, *alg, *akm;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002175 int id;
Jouni Malinen53264f62019-05-03 13:04:40 +03002176 char buf[200], buf2[300];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002177#ifdef ANDROID
2178 unsigned char kvalue[KEYSTORE_MESSAGE_SIZE];
2179 int length;
2180#endif /* ANDROID */
Jouni Malinen8179fee2019-03-28 03:19:47 +02002181 int erp = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002182
2183 id = set_wpa_common(dut, conn, ifname, cmd);
2184 if (id < 0)
2185 return id;
2186
2187 val = get_param(cmd, "keyMgmtType");
2188 alg = get_param(cmd, "micAlg");
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302189 akm = get_param(cmd, "AKMSuiteType");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002190
Jouni Malinenad395a22017-09-01 21:13:46 +03002191 if (val && strcasecmp(val, "SuiteB") == 0) {
2192 if (set_network(ifname, id, "key_mgmt", "WPA-EAP-SUITE-B-192") <
2193 0)
2194 return -2;
2195 } else if (alg && strcasecmp(alg, "SHA-256") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002196 if (set_network(ifname, id, "key_mgmt", "WPA-EAP-SHA256") < 0)
2197 return -2;
2198 } else if (alg && strcasecmp(alg, "SHA-1") == 0) {
2199 if (set_network(ifname, id, "key_mgmt", "WPA-EAP") < 0)
2200 return -2;
2201 } else if (val && strcasecmp(val, "wpa2-ft") == 0) {
2202 if (set_network(ifname, id, "key_mgmt", "FT-EAP") < 0)
2203 return -2;
Jouni Malinend6a9d692019-03-28 03:01:24 +02002204 } else if (!akm &&
2205 ((val && strcasecmp(val, "wpa2-sha256") == 0) ||
2206 dut->sta_pmf == STA_PMF_REQUIRED)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002207 if (set_network(ifname, id, "key_mgmt",
2208 "WPA-EAP WPA-EAP-SHA256") < 0)
2209 return -2;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302210 } else if (akm && atoi(akm) == 14) {
2211 if (dut->sta_pmf == STA_PMF_OPTIONAL ||
2212 dut->sta_pmf == STA_PMF_REQUIRED) {
2213 if (set_network(ifname, id, "key_mgmt",
2214 "WPA-EAP-SHA256 FILS-SHA256") < 0)
2215 return -2;
2216 } else {
2217 if (set_network(ifname, id, "key_mgmt",
2218 "WPA-EAP FILS-SHA256") < 0)
2219 return -2;
2220 }
2221
Jouni Malinen8179fee2019-03-28 03:19:47 +02002222 erp = 1;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302223 } else if (akm && atoi(akm) == 15) {
2224 if (dut->sta_pmf == STA_PMF_OPTIONAL ||
2225 dut->sta_pmf == STA_PMF_REQUIRED) {
2226 if (set_network(ifname, id, "key_mgmt",
2227 "WPA-EAP-SHA256 FILS-SHA384") < 0)
2228 return -2;
2229 } else {
2230 if (set_network(ifname, id, "key_mgmt",
2231 "WPA-EAP FILS-SHA384") < 0)
2232 return -2;
2233 }
2234
Jouni Malinen8179fee2019-03-28 03:19:47 +02002235 erp = 1;
Jouni Malinend6a9d692019-03-28 03:01:24 +02002236 } else if (!akm && dut->sta_pmf == STA_PMF_OPTIONAL) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002237 if (set_network(ifname, id, "key_mgmt",
2238 "WPA-EAP WPA-EAP-SHA256") < 0)
2239 return -2;
Jouni Malinend6a9d692019-03-28 03:01:24 +02002240 } else if (!akm) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002241 if (set_network(ifname, id, "key_mgmt", "WPA-EAP") < 0)
2242 return -2;
2243 }
2244
2245 val = get_param(cmd, "trustedRootCA");
2246 if (val) {
2247#ifdef ANDROID
2248 snprintf(buf, sizeof(buf), "CACERT_%s", val);
2249 length = android_keystore_get(ANDROID_KEYSTORE_GET, buf,
2250 kvalue);
2251 if (length > 0) {
2252 sigma_dut_print(dut, DUT_MSG_INFO,
2253 "Use Android keystore [%s]", buf);
2254 snprintf(buf, sizeof(buf), "keystore://CACERT_%s",
2255 val);
2256 goto ca_cert_selected;
2257 }
2258#endif /* ANDROID */
2259
2260 snprintf(buf, sizeof(buf), "%s/%s", sigma_cert_path, val);
2261#ifdef __linux__
2262 if (!file_exists(buf)) {
2263 char msg[300];
2264 snprintf(msg, sizeof(msg), "ErrorCode,trustedRootCA "
2265 "file (%s) not found", buf);
2266 send_resp(dut, conn, SIGMA_ERROR, msg);
2267 return -3;
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 -2;
2275 }
2276
Jouni Malinen53264f62019-05-03 13:04:40 +03002277 val = get_param(cmd, "ServerCert");
2278 if (val) {
2279 FILE *f;
2280 char *result = NULL, *pos;
2281
2282 snprintf(buf, sizeof(buf), "%s/%s.sha256", sigma_cert_path,
2283 val);
2284 f = fopen(buf, "r");
2285 if (f) {
2286 result = fgets(buf, sizeof(buf), f);
2287 fclose(f);
2288 }
2289 if (!result) {
2290 snprintf(buf2, sizeof(buf2),
2291 "ErrorCode,ServerCert hash could not be read from %s",
2292 buf);
2293 send_resp(dut, conn, SIGMA_ERROR, buf2);
2294 return STATUS_SENT_ERROR;
2295 }
2296 pos = strchr(buf, '\n');
2297 if (pos)
2298 *pos = '\0';
2299 snprintf(buf2, sizeof(buf2), "hash://server/sha256/%s", buf);
2300 if (set_network_quoted(ifname, id, "ca_cert", buf2) < 0)
2301 return ERROR_SEND_STATUS;
2302 }
2303
Jouni Malinen96f84b02019-05-03 12:32:56 +03002304 val = get_param(cmd, "Domain");
2305 if (val && set_network_quoted(ifname, id, "domain_match", val) < 0)
2306 return ERROR_SEND_STATUS;
2307
2308 val = get_param(cmd, "DomainSuffix");
2309 if (val &&
2310 set_network_quoted(ifname, id, "domain_suffix_match", val) < 0)
2311 return ERROR_SEND_STATUS;
2312
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302313 if (username_identity) {
2314 val = get_param(cmd, "username");
2315 if (val) {
2316 if (set_network_quoted(ifname, id, "identity", val) < 0)
2317 return -2;
2318 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002319
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302320 val = get_param(cmd, "password");
2321 if (val) {
2322 if (set_network_quoted(ifname, id, "password", val) < 0)
2323 return -2;
2324 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002325 }
2326
Jouni Malinen8179fee2019-03-28 03:19:47 +02002327 if (dut->akm_values &
2328 ((1 << AKM_FILS_SHA256) |
2329 (1 << AKM_FILS_SHA384) |
2330 (1 << AKM_FT_FILS_SHA256) |
2331 (1 << AKM_FT_FILS_SHA384)))
2332 erp = 1;
2333 if (erp && set_network(ifname, id, "erp", "1") < 0)
2334 return ERROR_SEND_STATUS;
2335
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002336 return id;
2337}
2338
2339
Jouni Malinen5eabb2a2017-10-03 18:17:30 +03002340static int set_tls_cipher(const char *ifname, int id, const char *cipher)
2341{
2342 const char *val;
2343
2344 if (!cipher)
2345 return 0;
2346
2347 if (strcasecmp(cipher, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384") == 0)
2348 val = "ECDHE-ECDSA-AES256-GCM-SHA384";
2349 else if (strcasecmp(cipher,
2350 "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384") == 0)
2351 val = "ECDHE-RSA-AES256-GCM-SHA384";
2352 else if (strcasecmp(cipher, "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384") == 0)
2353 val = "DHE-RSA-AES256-GCM-SHA384";
2354 else if (strcasecmp(cipher,
2355 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256") == 0)
2356 val = "ECDHE-ECDSA-AES128-GCM-SHA256";
2357 else
2358 return -1;
2359
2360 /* Need to clear phase1="tls_suiteb=1" to allow cipher enforcement */
2361 set_network_quoted(ifname, id, "phase1", "");
2362
2363 return set_network_quoted(ifname, id, "openssl_ciphers", val);
2364}
2365
2366
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002367static int cmd_sta_set_eaptls(struct sigma_dut *dut, struct sigma_conn *conn,
2368 struct sigma_cmd *cmd)
2369{
2370 const char *intf = get_param(cmd, "Interface");
2371 const char *ifname, *val;
2372 int id;
2373 char buf[200];
2374#ifdef ANDROID
2375 unsigned char kvalue[KEYSTORE_MESSAGE_SIZE];
2376 int length;
2377 int jb_or_newer = 0;
2378 char prop[PROPERTY_VALUE_MAX];
2379#endif /* ANDROID */
2380
2381 if (intf == NULL)
2382 return -1;
2383
2384 if (strcmp(intf, get_main_ifname()) == 0)
2385 ifname = get_station_ifname();
2386 else
2387 ifname = intf;
2388
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302389 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002390 if (id < 0)
2391 return id;
2392
2393 if (set_network(ifname, id, "eap", "TLS") < 0)
2394 return -2;
2395
Pradeep Reddy POTTETI9f6c2132016-05-05 16:28:19 +05302396 if (!get_param(cmd, "username") &&
2397 set_network_quoted(ifname, id, "identity",
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002398 "wifi-user@wifilabs.local") < 0)
2399 return -2;
2400
2401 val = get_param(cmd, "clientCertificate");
2402 if (val == NULL)
2403 return -1;
2404#ifdef ANDROID
2405 snprintf(buf, sizeof(buf), "USRPKEY_%s", val);
2406 length = android_keystore_get(ANDROID_KEYSTORE_GET, buf, kvalue);
2407 if (length < 0) {
2408 /*
2409 * JB started reporting keystore type mismatches, so retry with
2410 * the GET_PUBKEY command if the generic GET fails.
2411 */
2412 length = android_keystore_get(ANDROID_KEYSTORE_GET_PUBKEY,
2413 buf, kvalue);
2414 }
2415
2416 if (property_get("ro.build.version.release", prop, NULL) != 0) {
2417 sigma_dut_print(dut, DUT_MSG_DEBUG, "Android release %s", prop);
2418 if (strncmp(prop, "4.0", 3) != 0)
2419 jb_or_newer = 1;
2420 } else
2421 jb_or_newer = 1; /* assume newer */
2422
2423 if (jb_or_newer && length > 0) {
2424 sigma_dut_print(dut, DUT_MSG_INFO,
2425 "Use Android keystore [%s]", buf);
2426 if (set_network(ifname, id, "engine", "1") < 0)
2427 return -2;
2428 if (set_network_quoted(ifname, id, "engine_id", "keystore") < 0)
2429 return -2;
2430 snprintf(buf, sizeof(buf), "USRPKEY_%s", val);
2431 if (set_network_quoted(ifname, id, "key_id", buf) < 0)
2432 return -2;
2433 snprintf(buf, sizeof(buf), "keystore://USRCERT_%s", val);
2434 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
2435 return -2;
2436 return 1;
2437 } else if (length > 0) {
2438 sigma_dut_print(dut, DUT_MSG_INFO,
2439 "Use Android keystore [%s]", buf);
2440 snprintf(buf, sizeof(buf), "keystore://USRPKEY_%s", val);
2441 if (set_network_quoted(ifname, id, "private_key", buf) < 0)
2442 return -2;
2443 snprintf(buf, sizeof(buf), "keystore://USRCERT_%s", val);
2444 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
2445 return -2;
2446 return 1;
2447 }
2448#endif /* ANDROID */
2449
2450 snprintf(buf, sizeof(buf), "%s/%s", sigma_cert_path, val);
2451#ifdef __linux__
2452 if (!file_exists(buf)) {
2453 char msg[300];
2454 snprintf(msg, sizeof(msg), "ErrorCode,clientCertificate file "
2455 "(%s) not found", buf);
2456 send_resp(dut, conn, SIGMA_ERROR, msg);
2457 return -3;
2458 }
2459#endif /* __linux__ */
2460 if (set_network_quoted(ifname, id, "private_key", buf) < 0)
2461 return -2;
2462 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
2463 return -2;
2464
2465 if (set_network_quoted(ifname, id, "private_key_passwd", "wifi") < 0)
2466 return -2;
2467
Jouni Malinen5eabb2a2017-10-03 18:17:30 +03002468 val = get_param(cmd, "keyMgmtType");
2469 if (val && strcasecmp(val, "SuiteB") == 0) {
2470 val = get_param(cmd, "CertType");
2471 if (val && strcasecmp(val, "RSA") == 0) {
2472 if (set_network_quoted(ifname, id, "phase1",
2473 "tls_suiteb=1") < 0)
2474 return -2;
2475 } else {
2476 if (set_network_quoted(ifname, id, "openssl_ciphers",
2477 "SUITEB192") < 0)
2478 return -2;
2479 }
2480
2481 val = get_param(cmd, "TLSCipher");
2482 if (set_tls_cipher(ifname, id, val) < 0) {
2483 send_resp(dut, conn, SIGMA_ERROR,
2484 "ErrorCode,Unsupported TLSCipher value");
2485 return -3;
2486 }
2487 }
2488
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002489 return 1;
2490}
2491
2492
2493static int cmd_sta_set_eapttls(struct sigma_dut *dut, struct sigma_conn *conn,
2494 struct sigma_cmd *cmd)
2495{
2496 const char *intf = get_param(cmd, "Interface");
2497 const char *ifname;
2498 int id;
2499
2500 if (intf == NULL)
2501 return -1;
2502
2503 if (strcmp(intf, get_main_ifname()) == 0)
2504 ifname = get_station_ifname();
2505 else
2506 ifname = intf;
2507
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302508 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002509 if (id < 0)
2510 return id;
2511
2512 if (set_network(ifname, id, "eap", "TTLS") < 0) {
2513 send_resp(dut, conn, SIGMA_ERROR,
2514 "errorCode,Failed to set TTLS method");
2515 return 0;
2516 }
2517
2518 if (set_network_quoted(ifname, id, "phase2", "auth=MSCHAPV2") < 0) {
2519 send_resp(dut, conn, SIGMA_ERROR,
2520 "errorCode,Failed to set MSCHAPv2 for TTLS Phase 2");
2521 return 0;
2522 }
2523
2524 return 1;
2525}
2526
2527
2528static int cmd_sta_set_eapsim(struct sigma_dut *dut, struct sigma_conn *conn,
2529 struct sigma_cmd *cmd)
2530{
2531 const char *intf = get_param(cmd, "Interface");
2532 const char *ifname;
2533 int id;
2534
2535 if (intf == NULL)
2536 return -1;
2537
2538 if (strcmp(intf, get_main_ifname()) == 0)
2539 ifname = get_station_ifname();
2540 else
2541 ifname = intf;
2542
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302543 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002544 if (id < 0)
2545 return id;
2546
2547 if (set_network(ifname, id, "eap", "SIM") < 0)
2548 return -2;
2549
2550 return 1;
2551}
2552
2553
2554static int cmd_sta_set_peap(struct sigma_dut *dut, struct sigma_conn *conn,
2555 struct sigma_cmd *cmd)
2556{
2557 const char *intf = get_param(cmd, "Interface");
2558 const char *ifname, *val;
2559 int id;
2560 char buf[100];
2561
2562 if (intf == NULL)
2563 return -1;
2564
2565 if (strcmp(intf, get_main_ifname()) == 0)
2566 ifname = get_station_ifname();
2567 else
2568 ifname = intf;
2569
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302570 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002571 if (id < 0)
2572 return id;
2573
2574 if (set_network(ifname, id, "eap", "PEAP") < 0)
2575 return -2;
2576
2577 val = get_param(cmd, "innerEAP");
2578 if (val) {
2579 if (strcasecmp(val, "MSCHAPv2") == 0) {
2580 if (set_network_quoted(ifname, id, "phase2",
2581 "auth=MSCHAPV2") < 0)
2582 return -2;
2583 } else if (strcasecmp(val, "GTC") == 0) {
2584 if (set_network_quoted(ifname, id, "phase2",
2585 "auth=GTC") < 0)
2586 return -2;
2587 } else
2588 return -1;
2589 }
2590
2591 val = get_param(cmd, "peapVersion");
2592 if (val) {
2593 int ver = atoi(val);
2594 if (ver < 0 || ver > 1)
2595 return -1;
2596 snprintf(buf, sizeof(buf), "peapver=%d", ver);
2597 if (set_network_quoted(ifname, id, "phase1", buf) < 0)
2598 return -2;
2599 }
2600
2601 return 1;
2602}
2603
2604
2605static int cmd_sta_set_eapfast(struct sigma_dut *dut, struct sigma_conn *conn,
2606 struct sigma_cmd *cmd)
2607{
2608 const char *intf = get_param(cmd, "Interface");
2609 const char *ifname, *val;
2610 int id;
2611 char buf[100];
2612
2613 if (intf == NULL)
2614 return -1;
2615
2616 if (strcmp(intf, get_main_ifname()) == 0)
2617 ifname = get_station_ifname();
2618 else
2619 ifname = intf;
2620
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302621 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002622 if (id < 0)
2623 return id;
2624
2625 if (set_network(ifname, id, "eap", "FAST") < 0)
2626 return -2;
2627
2628 val = get_param(cmd, "innerEAP");
2629 if (val) {
2630 if (strcasecmp(val, "MSCHAPV2") == 0) {
2631 if (set_network_quoted(ifname, id, "phase2",
2632 "auth=MSCHAPV2") < 0)
2633 return -2;
2634 } else if (strcasecmp(val, "GTC") == 0) {
2635 if (set_network_quoted(ifname, id, "phase2",
2636 "auth=GTC") < 0)
2637 return -2;
2638 } else
2639 return -1;
2640 }
2641
2642 val = get_param(cmd, "validateServer");
2643 if (val) {
2644 /* TODO */
2645 sigma_dut_print(dut, DUT_MSG_INFO, "Ignored EAP-FAST "
2646 "validateServer=%s", val);
2647 }
2648
2649 val = get_param(cmd, "pacFile");
2650 if (val) {
2651 snprintf(buf, sizeof(buf), "blob://%s", val);
2652 if (set_network_quoted(ifname, id, "pac_file", buf) < 0)
2653 return -2;
2654 }
2655
2656 if (set_network_quoted(ifname, id, "phase1", "fast_provisioning=2") <
2657 0)
2658 return -2;
2659
2660 return 1;
2661}
2662
2663
2664static int cmd_sta_set_eapaka(struct sigma_dut *dut, struct sigma_conn *conn,
2665 struct sigma_cmd *cmd)
2666{
2667 const char *intf = get_param(cmd, "Interface");
2668 const char *ifname;
2669 int id;
2670
2671 if (intf == NULL)
2672 return -1;
2673
2674 if (strcmp(intf, get_main_ifname()) == 0)
2675 ifname = get_station_ifname();
2676 else
2677 ifname = intf;
2678
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302679 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002680 if (id < 0)
2681 return id;
2682
2683 if (set_network(ifname, id, "eap", "AKA") < 0)
2684 return -2;
2685
2686 return 1;
2687}
2688
2689
2690static int cmd_sta_set_eapakaprime(struct sigma_dut *dut,
2691 struct sigma_conn *conn,
2692 struct sigma_cmd *cmd)
2693{
2694 const char *intf = get_param(cmd, "Interface");
2695 const char *ifname;
2696 int id;
2697
2698 if (intf == NULL)
2699 return -1;
2700
2701 if (strcmp(intf, get_main_ifname()) == 0)
2702 ifname = get_station_ifname();
2703 else
2704 ifname = intf;
2705
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302706 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002707 if (id < 0)
2708 return id;
2709
2710 if (set_network(ifname, id, "eap", "AKA'") < 0)
2711 return -2;
2712
2713 return 1;
2714}
2715
2716
2717static int sta_set_open(struct sigma_dut *dut, struct sigma_conn *conn,
2718 struct sigma_cmd *cmd)
2719{
2720 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002721 const char *network_mode = get_param(cmd, "network_mode");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002722 const char *ifname;
2723 int id;
2724
2725 if (strcmp(intf, get_main_ifname()) == 0)
2726 ifname = get_station_ifname();
2727 else
2728 ifname = intf;
2729
2730 id = add_network_common(dut, conn, ifname, cmd);
2731 if (id < 0)
2732 return id;
2733
2734 if (set_network(ifname, id, "key_mgmt", "NONE") < 0)
2735 return -2;
2736
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002737 if (dut->program == PROGRAM_60GHZ && network_mode &&
2738 strcasecmp(network_mode, "PBSS") == 0 &&
2739 set_network(ifname, id, "pbss", "1") < 0)
2740 return -2;
2741
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002742 return 1;
2743}
2744
2745
Jouni Malinen47dcc952017-10-09 16:43:24 +03002746static int sta_set_owe(struct sigma_dut *dut, struct sigma_conn *conn,
2747 struct sigma_cmd *cmd)
2748{
2749 const char *intf = get_param(cmd, "Interface");
2750 const char *ifname, *val;
2751 int id;
2752
2753 if (intf == NULL)
2754 return -1;
2755
2756 if (strcmp(intf, get_main_ifname()) == 0)
2757 ifname = get_station_ifname();
2758 else
2759 ifname = intf;
2760
2761 id = set_wpa_common(dut, conn, ifname, cmd);
2762 if (id < 0)
2763 return id;
2764
2765 if (set_network(ifname, id, "key_mgmt", "OWE") < 0)
2766 return -2;
2767
2768 val = get_param(cmd, "ECGroupID");
Jouni Malinenfac9cad2017-10-10 18:35:55 +03002769 if (val && strcmp(val, "0") == 0) {
2770 if (wpa_command(ifname,
2771 "VENDOR_ELEM_ADD 13 ff23200000783590fb7440e03d5b3b33911f86affdcc6b4411b707846ac4ff08ddc8831ccd") != 0) {
2772 sigma_dut_print(dut, DUT_MSG_ERROR,
2773 "Failed to set OWE DH Param element override");
2774 return -2;
2775 }
2776 } else if (val && set_network(ifname, id, "owe_group", val) < 0) {
Jouni Malinen47dcc952017-10-09 16:43:24 +03002777 sigma_dut_print(dut, DUT_MSG_ERROR,
2778 "Failed to clear owe_group");
2779 return -2;
2780 }
2781
2782 return 1;
2783}
2784
2785
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002786static int cmd_sta_set_security(struct sigma_dut *dut, struct sigma_conn *conn,
2787 struct sigma_cmd *cmd)
2788{
2789 const char *type = get_param(cmd, "Type");
2790
2791 if (type == NULL) {
2792 send_resp(dut, conn, SIGMA_ERROR,
2793 "ErrorCode,Missing Type argument");
2794 return 0;
2795 }
2796
2797 if (strcasecmp(type, "OPEN") == 0)
2798 return sta_set_open(dut, conn, cmd);
Jouni Malinen47dcc952017-10-09 16:43:24 +03002799 if (strcasecmp(type, "OWE") == 0)
2800 return sta_set_owe(dut, conn, cmd);
Jouni Malinen992a81e2017-08-22 13:57:47 +03002801 if (strcasecmp(type, "PSK") == 0 ||
Jouni Malinen0ab50f42017-08-31 01:34:59 +03002802 strcasecmp(type, "PSK-SAE") == 0 ||
Jouni Malinen992a81e2017-08-22 13:57:47 +03002803 strcasecmp(type, "SAE") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002804 return cmd_sta_set_psk(dut, conn, cmd);
2805 if (strcasecmp(type, "EAPTLS") == 0)
2806 return cmd_sta_set_eaptls(dut, conn, cmd);
2807 if (strcasecmp(type, "EAPTTLS") == 0)
2808 return cmd_sta_set_eapttls(dut, conn, cmd);
2809 if (strcasecmp(type, "EAPPEAP") == 0)
2810 return cmd_sta_set_peap(dut, conn, cmd);
2811 if (strcasecmp(type, "EAPSIM") == 0)
2812 return cmd_sta_set_eapsim(dut, conn, cmd);
2813 if (strcasecmp(type, "EAPFAST") == 0)
2814 return cmd_sta_set_eapfast(dut, conn, cmd);
2815 if (strcasecmp(type, "EAPAKA") == 0)
2816 return cmd_sta_set_eapaka(dut, conn, cmd);
2817 if (strcasecmp(type, "EAPAKAPRIME") == 0)
2818 return cmd_sta_set_eapakaprime(dut, conn, cmd);
Amarnath Hullur Subramanyam81b11cd2018-01-30 19:07:17 -08002819 if (strcasecmp(type, "wep") == 0)
2820 return cmd_sta_set_encryption(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002821
2822 send_resp(dut, conn, SIGMA_ERROR,
2823 "ErrorCode,Unsupported Type value");
2824 return 0;
2825}
2826
2827
2828int ath6kl_client_uapsd(struct sigma_dut *dut, const char *intf, int uapsd)
2829{
2830#ifdef __linux__
2831 /* special handling for ath6kl */
2832 char path[128], fname[128], *pos;
2833 ssize_t res;
2834 FILE *f;
2835
Jouni Malinene39cd562019-05-29 23:39:56 +03002836 res = snprintf(fname, sizeof(fname), "/sys/class/net/%s/phy80211",
2837 intf);
2838 if (res < 0 || res >= sizeof(fname))
2839 return 0;
2840 res = readlink(fname, path, sizeof(path));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002841 if (res < 0)
2842 return 0; /* not ath6kl */
2843
2844 if (res >= (int) sizeof(path))
2845 res = sizeof(path) - 1;
2846 path[res] = '\0';
2847 pos = strrchr(path, '/');
2848 if (pos == NULL)
2849 pos = path;
2850 else
2851 pos++;
2852 snprintf(fname, sizeof(fname),
2853 "/sys/kernel/debug/ieee80211/%s/ath6kl/"
2854 "create_qos", pos);
2855 if (!file_exists(fname))
2856 return 0; /* not ath6kl */
2857
2858 if (uapsd) {
2859 f = fopen(fname, "w");
2860 if (f == NULL)
2861 return -1;
2862
2863 sigma_dut_print(dut, DUT_MSG_DEBUG, "Use ath6kl create_qos");
2864 fprintf(f, "4 2 2 1 2 9999999 9999999 9999999 7777777 0 4 "
2865 "45000 200 56789000 56789000 5678900 0 0 9999999 "
2866 "20000 0\n");
2867 fclose(f);
2868 } else {
2869 snprintf(fname, sizeof(fname),
2870 "/sys/kernel/debug/ieee80211/%s/ath6kl/"
2871 "delete_qos", pos);
2872
2873 f = fopen(fname, "w");
2874 if (f == NULL)
2875 return -1;
2876
2877 sigma_dut_print(dut, DUT_MSG_DEBUG, "Use ath6kl delete_qos");
2878 fprintf(f, "2 4\n");
2879 fclose(f);
2880 }
2881#endif /* __linux__ */
2882
2883 return 0;
2884}
2885
2886
2887static int cmd_sta_set_uapsd(struct sigma_dut *dut, struct sigma_conn *conn,
2888 struct sigma_cmd *cmd)
2889{
2890 const char *intf = get_param(cmd, "Interface");
2891 /* const char *ssid = get_param(cmd, "ssid"); */
2892 const char *val;
2893 int max_sp_len = 4;
2894 int ac_be = 1, ac_bk = 1, ac_vi = 1, ac_vo = 1;
2895 char buf[100];
2896 int ret1, ret2;
2897
2898 val = get_param(cmd, "maxSPLength");
2899 if (val) {
2900 max_sp_len = atoi(val);
2901 if (max_sp_len != 0 && max_sp_len != 1 && max_sp_len != 2 &&
2902 max_sp_len != 4)
2903 return -1;
2904 }
2905
2906 val = get_param(cmd, "acBE");
2907 if (val)
2908 ac_be = atoi(val);
2909
2910 val = get_param(cmd, "acBK");
2911 if (val)
2912 ac_bk = atoi(val);
2913
2914 val = get_param(cmd, "acVI");
2915 if (val)
2916 ac_vi = atoi(val);
2917
2918 val = get_param(cmd, "acVO");
2919 if (val)
2920 ac_vo = atoi(val);
2921
2922 dut->client_uapsd = ac_be || ac_bk || ac_vi || ac_vo;
2923
2924 snprintf(buf, sizeof(buf), "P2P_SET client_apsd %d,%d,%d,%d;%d",
2925 ac_be, ac_bk, ac_vi, ac_vo, max_sp_len);
2926 ret1 = wpa_command(intf, buf);
2927
2928 snprintf(buf, sizeof(buf), "SET uapsd %d,%d,%d,%d;%d",
2929 ac_be, ac_bk, ac_vi, ac_vo, max_sp_len);
2930 ret2 = wpa_command(intf, buf);
2931
2932 if (ret1 && ret2) {
2933 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to set client mode "
2934 "UAPSD parameters.");
2935 return -2;
2936 }
2937
2938 if (ath6kl_client_uapsd(dut, intf, dut->client_uapsd) < 0) {
2939 send_resp(dut, conn, SIGMA_ERROR,
2940 "ErrorCode,Failed to set ath6kl QoS parameters");
2941 return 0;
2942 }
2943
2944 return 1;
2945}
2946
2947
2948static int cmd_sta_set_wmm(struct sigma_dut *dut, struct sigma_conn *conn,
2949 struct sigma_cmd *cmd)
2950{
2951 char buf[1000];
2952 const char *intf = get_param(cmd, "Interface");
2953 const char *grp = get_param(cmd, "Group");
2954 const char *act = get_param(cmd, "Action");
2955 const char *tid = get_param(cmd, "Tid");
2956 const char *dir = get_param(cmd, "Direction");
2957 const char *psb = get_param(cmd, "Psb");
2958 const char *up = get_param(cmd, "Up");
2959 const char *fixed = get_param(cmd, "Fixed");
2960 const char *size = get_param(cmd, "Size");
2961 const char *msize = get_param(cmd, "Maxsize");
2962 const char *minsi = get_param(cmd, "Min_srvc_intrvl");
2963 const char *maxsi = get_param(cmd, "Max_srvc_intrvl");
2964 const char *inact = get_param(cmd, "Inactivity");
2965 const char *sus = get_param(cmd, "Suspension");
2966 const char *mindr = get_param(cmd, "Mindatarate");
2967 const char *meandr = get_param(cmd, "Meandatarate");
2968 const char *peakdr = get_param(cmd, "Peakdatarate");
2969 const char *phyrate = get_param(cmd, "Phyrate");
2970 const char *burstsize = get_param(cmd, "Burstsize");
2971 const char *sba = get_param(cmd, "Sba");
2972 int direction;
2973 int handle;
Peng Xu93319622017-10-04 17:58:16 -07002974 float sba_fv = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002975 int fixed_int;
2976 int psb_ts;
2977
2978 if (intf == NULL || grp == NULL || act == NULL )
2979 return -1;
2980
2981 if (strcasecmp(act, "addts") == 0) {
2982 if (tid == NULL || dir == NULL || psb == NULL ||
2983 up == NULL || fixed == NULL || size == NULL)
2984 return -1;
2985
2986 /*
2987 * Note: Sigma CAPI spec lists uplink, downlink, and bidi as the
2988 * possible values, but WMM-AC and V-E test scripts use "UP,
2989 * "DOWN", and "BIDI".
2990 */
2991 if (strcasecmp(dir, "uplink") == 0 ||
2992 strcasecmp(dir, "up") == 0) {
2993 direction = 0;
2994 } else if (strcasecmp(dir, "downlink") == 0 ||
2995 strcasecmp(dir, "down") == 0) {
2996 direction = 1;
2997 } else if (strcasecmp(dir, "bidi") == 0) {
2998 direction = 2;
2999 } else {
3000 sigma_dut_print(dut, DUT_MSG_ERROR,
3001 "Direction %s not supported", dir);
3002 return -1;
3003 }
3004
3005 if (strcasecmp(psb, "legacy") == 0) {
3006 psb_ts = 0;
3007 } else if (strcasecmp(psb, "uapsd") == 0) {
3008 psb_ts = 1;
3009 } else {
3010 sigma_dut_print(dut, DUT_MSG_ERROR,
3011 "PSB %s not supported", psb);
3012 return -1;
3013 }
3014
3015 if (atoi(tid) < 0 || atoi(tid) > 7) {
3016 sigma_dut_print(dut, DUT_MSG_ERROR,
3017 "TID %s not supported", tid);
3018 return -1;
3019 }
3020
3021 if (strcasecmp(fixed, "true") == 0) {
3022 fixed_int = 1;
3023 } else {
3024 fixed_int = 0;
3025 }
3026
Peng Xu93319622017-10-04 17:58:16 -07003027 if (sba)
3028 sba_fv = atof(sba);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003029
3030 dut->dialog_token++;
3031 handle = 7000 + dut->dialog_token;
3032
3033 /*
3034 * size: convert to hex
3035 * maxsi: convert to hex
3036 * mindr: convert to hex
3037 * meandr: convert to hex
3038 * peakdr: convert to hex
3039 * burstsize: convert to hex
3040 * phyrate: convert to hex
3041 * sba: convert to hex with modification
3042 * minsi: convert to integer
3043 * sus: convert to integer
3044 * inact: convert to integer
3045 * maxsi: convert to integer
3046 */
3047
3048 /*
3049 * The Nominal MSDU Size field is 2 octets long and contains an
3050 * unsigned integer that specifies the nominal size, in octets,
3051 * of MSDUs belonging to the traffic under this traffic
3052 * specification and is defined in Figure 16. If the Fixed
3053 * subfield is set to 1, then the size of the MSDU is fixed and
3054 * is indicated by the Size Subfield. If the Fixed subfield is
3055 * set to 0, then the size of the MSDU might not be fixed and
3056 * the Size indicates the nominal MSDU size.
3057 *
3058 * The Surplus Bandwidth Allowance Factor field is 2 octets long
3059 * and specifies the excess allocation of time (and bandwidth)
3060 * over and above the stated rates required to transport an MSDU
3061 * belonging to the traffic in this TSPEC. This field is
3062 * represented as an unsigned binary number with an implicit
3063 * binary point after the leftmost 3 bits. For example, an SBA
3064 * of 1.75 is represented as 0x3800. This field is included to
3065 * account for retransmissions. As such, the value of this field
3066 * must be greater than unity.
3067 */
3068
3069 snprintf(buf, sizeof(buf),
3070 "iwpriv %s addTspec %d %s %d %d %s 0x%X"
3071 " 0x%X 0x%X 0x%X"
3072 " 0x%X 0x%X 0x%X"
3073 " 0x%X %d %d %d %d"
3074 " %d %d",
3075 intf, handle, tid, direction, psb_ts, up,
3076 (unsigned int) ((fixed_int << 15) | atoi(size)),
3077 msize ? atoi(msize) : 0,
3078 mindr ? atoi(mindr) : 0,
3079 meandr ? atoi(meandr) : 0,
3080 peakdr ? atoi(peakdr) : 0,
3081 burstsize ? atoi(burstsize) : 0,
3082 phyrate ? atoi(phyrate) : 0,
3083 sba ? ((unsigned int) (((int) sba_fv << 13) |
3084 (int)((sba_fv - (int) sba_fv) *
3085 8192))) : 0,
3086 minsi ? atoi(minsi) : 0,
3087 sus ? atoi(sus) : 0,
3088 0, 0,
3089 inact ? atoi(inact) : 0,
3090 maxsi ? atoi(maxsi) : 0);
3091
3092 if (system(buf) != 0) {
3093 sigma_dut_print(dut, DUT_MSG_ERROR,
3094 "iwpriv addtspec request failed");
3095 send_resp(dut, conn, SIGMA_ERROR,
3096 "errorCode,Failed to execute addTspec command");
3097 return 0;
3098 }
3099
3100 sigma_dut_print(dut, DUT_MSG_INFO,
3101 "iwpriv addtspec request send");
3102
3103 /* Mapping handle to a TID */
3104 dut->tid_to_handle[atoi(tid)] = handle;
3105 } else if (strcasecmp(act, "delts") == 0) {
3106 if (tid == NULL)
3107 return -1;
3108
3109 if (atoi(tid) < 0 || atoi(tid) > 7) {
3110 sigma_dut_print(dut, DUT_MSG_ERROR,
3111 "TID %s not supported", tid);
3112 send_resp(dut, conn, SIGMA_ERROR,
3113 "errorCode,Unsupported TID");
3114 return 0;
3115 }
3116
3117 handle = dut->tid_to_handle[atoi(tid)];
3118
3119 if (handle < 7000 || handle > 7255) {
3120 /* Invalid handle ie no mapping for that TID */
3121 sigma_dut_print(dut, DUT_MSG_ERROR,
3122 "handle-> %d not found", handle);
3123 }
3124
3125 snprintf(buf, sizeof(buf), "iwpriv %s delTspec %d",
3126 intf, handle);
3127
3128 if (system(buf) != 0) {
3129 sigma_dut_print(dut, DUT_MSG_ERROR,
3130 "iwpriv deltspec request failed");
3131 send_resp(dut, conn, SIGMA_ERROR,
3132 "errorCode,Failed to execute delTspec command");
3133 return 0;
3134 }
3135
3136 sigma_dut_print(dut, DUT_MSG_INFO,
3137 "iwpriv deltspec request send");
3138
3139 dut->tid_to_handle[atoi(tid)] = 0;
3140 } else {
3141 sigma_dut_print(dut, DUT_MSG_ERROR,
3142 "Action type %s not supported", act);
3143 send_resp(dut, conn, SIGMA_ERROR,
3144 "errorCode,Unsupported Action");
3145 return 0;
3146 }
3147
3148 return 1;
3149}
3150
3151
vamsi krishna52e16f92017-08-29 12:37:34 +05303152static int find_network(struct sigma_dut *dut, const char *ssid)
3153{
3154 char list[4096];
3155 char *pos;
3156
3157 sigma_dut_print(dut, DUT_MSG_DEBUG,
3158 "Search for profile based on SSID: '%s'", ssid);
3159 if (wpa_command_resp(get_station_ifname(), "LIST_NETWORKS",
3160 list, sizeof(list)) < 0)
3161 return -1;
3162 pos = strstr(list, ssid);
3163 if (!pos || pos == list || pos[-1] != '\t' || pos[strlen(ssid)] != '\t')
3164 return -1;
3165
3166 while (pos > list && pos[-1] != '\n')
3167 pos--;
3168 dut->infra_network_id = atoi(pos);
3169 snprintf(dut->infra_ssid, sizeof(dut->infra_ssid), "%s", ssid);
3170 return 0;
3171}
3172
3173
Sunil Dutt44595082018-02-12 19:41:45 +05303174#ifdef NL80211_SUPPORT
3175static int sta_config_rsnie(struct sigma_dut *dut, int val)
3176{
3177 struct nl_msg *msg;
3178 int ret;
3179 struct nlattr *params;
3180 int ifindex;
3181
3182 ifindex = if_nametoindex("wlan0");
3183 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
3184 NL80211_CMD_VENDOR)) ||
3185 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
3186 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
3187 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
3188 QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION) ||
3189 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
3190 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE, val)) {
3191 sigma_dut_print(dut, DUT_MSG_ERROR,
3192 "%s: err in adding vendor_cmd and vendor_data",
3193 __func__);
3194 nlmsg_free(msg);
3195 return -1;
3196 }
3197 nla_nest_end(msg, params);
3198
3199 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
3200 if (ret) {
3201 sigma_dut_print(dut, DUT_MSG_ERROR,
3202 "%s: err in send_and_recv_msgs, ret=%d",
3203 __func__, ret);
3204 return ret;
3205 }
3206
3207 return 0;
3208}
3209#endif /* NL80211_SUPPORT */
3210
3211
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003212static int cmd_sta_associate(struct sigma_dut *dut, struct sigma_conn *conn,
3213 struct sigma_cmd *cmd)
3214{
3215 /* const char *intf = get_param(cmd, "Interface"); */
3216 const char *ssid = get_param(cmd, "ssid");
3217 const char *wps_param = get_param(cmd, "WPS");
3218 const char *bssid = get_param(cmd, "bssid");
Jouni Malinen46a19b62017-06-23 14:31:27 +03003219 const char *chan = get_param(cmd, "channel");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02003220 const char *network_mode = get_param(cmd, "network_mode");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003221 int wps = 0;
Jouni Malinen3c367e82017-06-23 17:01:47 +03003222 char buf[1000], extra[50];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003223
3224 if (ssid == NULL)
3225 return -1;
3226
Jouni Malinen3c367e82017-06-23 17:01:47 +03003227 if (dut->rsne_override) {
Sunil Dutt44595082018-02-12 19:41:45 +05303228#ifdef NL80211_SUPPORT
3229 if (get_driver_type() == DRIVER_WCN) {
3230 sta_config_rsnie(dut, 1);
3231 dut->config_rsnie = 1;
3232 }
3233#endif /* NL80211_SUPPORT */
Jouni Malinen3c367e82017-06-23 17:01:47 +03003234 snprintf(buf, sizeof(buf), "TEST_ASSOC_IE %s",
3235 dut->rsne_override);
3236 if (wpa_command(get_station_ifname(), buf) < 0) {
3237 send_resp(dut, conn, SIGMA_ERROR,
3238 "ErrorCode,Failed to set DEV_CONFIGURE_IE RSNE override");
3239 return 0;
3240 }
3241 }
3242
Jouni Malinen68143132017-09-02 02:34:08 +03003243 if (dut->sae_commit_override) {
3244 snprintf(buf, sizeof(buf), "SET sae_commit_override %s",
3245 dut->sae_commit_override);
3246 if (wpa_command(get_station_ifname(), buf) < 0) {
3247 send_resp(dut, conn, SIGMA_ERROR,
3248 "ErrorCode,Failed to set SAE commit override");
3249 return 0;
3250 }
3251 }
Ankita Bajaj1bde7942018-01-09 19:15:01 +05303252#ifdef ANDROID
3253 if (dut->fils_hlp)
3254 process_fils_hlp(dut);
3255#endif /* ANDROID */
Jouni Malinen68143132017-09-02 02:34:08 +03003256
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003257 if (wps_param &&
3258 (strcmp(wps_param, "1") == 0 || strcasecmp(wps_param, "On") == 0))
3259 wps = 1;
3260
3261 if (wps) {
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02003262 if (dut->program == PROGRAM_60GHZ && network_mode &&
3263 strcasecmp(network_mode, "PBSS") == 0 &&
3264 set_network(get_station_ifname(), dut->infra_network_id,
3265 "pbss", "1") < 0)
3266 return -2;
3267
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003268 if (dut->wps_method == WFA_CS_WPS_NOT_READY) {
3269 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,WPS "
3270 "parameters not yet set");
3271 return 0;
3272 }
3273 if (dut->wps_method == WFA_CS_WPS_PBC) {
3274 if (wpa_command(get_station_ifname(), "WPS_PBC") < 0)
3275 return -2;
3276 } else {
3277 snprintf(buf, sizeof(buf), "WPS_PIN any %s",
3278 dut->wps_pin);
3279 if (wpa_command(get_station_ifname(), buf) < 0)
3280 return -2;
3281 }
3282 } else {
vamsi krishna52e16f92017-08-29 12:37:34 +05303283 if (strcmp(ssid, dut->infra_ssid) == 0) {
3284 sigma_dut_print(dut, DUT_MSG_DEBUG,
3285 "sta_associate for the most recently added network");
3286 } else if (find_network(dut, ssid) < 0) {
3287 sigma_dut_print(dut, DUT_MSG_DEBUG,
3288 "sta_associate for a previously stored network profile");
3289 send_resp(dut, conn, SIGMA_ERROR,
3290 "ErrorCode,Profile not found");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003291 return 0;
3292 }
3293
3294 if (bssid &&
3295 set_network(get_station_ifname(), dut->infra_network_id,
3296 "bssid", bssid) < 0) {
3297 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
3298 "Invalid bssid argument");
3299 return 0;
3300 }
3301
Jouni Malinen46a19b62017-06-23 14:31:27 +03003302 extra[0] = '\0';
3303 if (chan)
3304 snprintf(extra, sizeof(extra), " freq=%u",
Alexei Avshalom Lazar093569f2018-11-13 14:08:17 +02003305 channel_to_freq(dut, atoi(chan)));
Jouni Malinen46a19b62017-06-23 14:31:27 +03003306 snprintf(buf, sizeof(buf), "SELECT_NETWORK %d%s",
3307 dut->infra_network_id, extra);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003308 if (wpa_command(get_station_ifname(), buf) < 0) {
3309 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to select "
3310 "network id %d on %s",
3311 dut->infra_network_id,
3312 get_station_ifname());
3313 return -2;
3314 }
3315 }
3316
3317 return 1;
3318}
3319
3320
3321static int run_hs20_osu(struct sigma_dut *dut, const char *params)
3322{
3323 char buf[500], cmd[200];
3324 int res;
3325
3326 /* Use hs20-osu-client file at the current dir, if found; otherwise use
3327 * default path */
3328 res = snprintf(cmd, sizeof(cmd),
3329 "%s -w \"%s\" -r hs20-osu-client.res %s%s -dddKt -f Logs/hs20-osu-client.txt",
3330 file_exists("./hs20-osu-client") ?
3331 "./hs20-osu-client" : "hs20-osu-client",
3332 sigma_wpas_ctrl,
3333 dut->summary_log ? "-s " : "",
3334 dut->summary_log ? dut->summary_log : "");
3335 if (res < 0 || res >= (int) sizeof(cmd))
3336 return -1;
3337
3338 res = snprintf(buf, sizeof(buf), "%s %s", cmd, params);
3339 if (res < 0 || res >= (int) sizeof(buf))
3340 return -1;
3341 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
3342
3343 if (system(buf) != 0) {
3344 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to run: %s", buf);
3345 return -1;
3346 }
3347 sigma_dut_print(dut, DUT_MSG_DEBUG,
3348 "Completed hs20-osu-client operation");
3349
3350 return 0;
3351}
3352
3353
3354static int download_ppsmo(struct sigma_dut *dut,
3355 struct sigma_conn *conn,
3356 const char *intf,
3357 struct sigma_cmd *cmd)
3358{
3359 const char *name, *path, *val;
3360 char url[500], buf[600], fbuf[100];
3361 char *fqdn = NULL;
3362
3363 name = get_param(cmd, "FileName");
3364 path = get_param(cmd, "FilePath");
3365 if (name == NULL || path == NULL)
3366 return -1;
3367
3368 if (strcasecmp(path, "VendorSpecific") == 0) {
3369 snprintf(url, sizeof(url), "PPS/%s", name);
3370 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured PPS MO "
3371 "from the device (%s)", url);
3372 if (!file_exists(url)) {
3373 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
3374 "PPS MO file does not exist");
3375 return 0;
3376 }
3377 snprintf(buf, sizeof(buf), "cp %s pps-tnds.xml", url);
3378 if (system(buf) != 0) {
3379 send_resp(dut, conn, SIGMA_ERROR,
3380 "errorCode,Failed to copy PPS MO");
3381 return 0;
3382 }
3383 } else if (strncasecmp(path, "http:", 5) != 0 &&
3384 strncasecmp(path, "https:", 6) != 0) {
3385 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
3386 "Unsupported FilePath value");
3387 return 0;
3388 } else {
3389 snprintf(url, sizeof(url), "%s/%s", path, name);
3390 sigma_dut_print(dut, DUT_MSG_INFO, "Downloading PPS MO from %s",
3391 url);
3392 snprintf(buf, sizeof(buf), "wget -T 10 -t 3 -O pps-tnds.xml '%s'", url);
3393 remove("pps-tnds.xml");
3394 if (system(buf) != 0) {
3395 send_resp(dut, conn, SIGMA_ERROR,
3396 "errorCode,Failed to download PPS MO");
3397 return 0;
3398 }
3399 }
3400
3401 if (run_hs20_osu(dut, "from_tnds pps-tnds.xml pps.xml") < 0) {
3402 send_resp(dut, conn, SIGMA_ERROR,
3403 "errorCode,Failed to parse downloaded PPSMO");
3404 return 0;
3405 }
3406 unlink("pps-tnds.xml");
3407
3408 val = get_param(cmd, "managementTreeURI");
3409 if (val) {
3410 const char *pos, *end;
3411 sigma_dut_print(dut, DUT_MSG_DEBUG, "managementTreeURI: %s",
3412 val);
3413 if (strncmp(val, "./Wi-Fi/", 8) != 0) {
3414 send_resp(dut, conn, SIGMA_ERROR,
3415 "errorCode,Invalid managementTreeURI prefix");
3416 return 0;
3417 }
3418 pos = val + 8;
3419 end = strchr(pos, '/');
3420 if (end == NULL ||
3421 strcmp(end, "/PerProviderSubscription") != 0) {
3422 send_resp(dut, conn, SIGMA_ERROR,
3423 "errorCode,Invalid managementTreeURI postfix");
3424 return 0;
3425 }
3426 if (end - pos >= (int) sizeof(fbuf)) {
3427 send_resp(dut, conn, SIGMA_ERROR,
3428 "errorCode,Too long FQDN in managementTreeURI");
3429 return 0;
3430 }
3431 memcpy(fbuf, pos, end - pos);
3432 fbuf[end - pos] = '\0';
3433 fqdn = fbuf;
3434 sigma_dut_print(dut, DUT_MSG_INFO,
3435 "FQDN from managementTreeURI: %s", fqdn);
3436 } else if (run_hs20_osu(dut, "get_fqdn pps.xml") == 0) {
3437 FILE *f = fopen("pps-fqdn", "r");
3438 if (f) {
3439 if (fgets(fbuf, sizeof(fbuf), f)) {
3440 fbuf[sizeof(fbuf) - 1] = '\0';
3441 fqdn = fbuf;
3442 sigma_dut_print(dut, DUT_MSG_DEBUG,
3443 "Use FQDN %s", fqdn);
3444 }
3445 fclose(f);
3446 }
3447 }
3448
3449 if (fqdn == NULL) {
3450 send_resp(dut, conn, SIGMA_ERROR,
3451 "errorCode,No FQDN specified");
3452 return 0;
3453 }
3454
3455 mkdir("SP", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
3456 snprintf(buf, sizeof(buf), "SP/%s", fqdn);
3457 mkdir(buf, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
3458
3459 snprintf(buf, sizeof(buf), "SP/%s/pps.xml", fqdn);
3460 if (rename("pps.xml", buf) < 0) {
3461 send_resp(dut, conn, SIGMA_ERROR,
3462 "errorCode,Could not move PPS MO");
3463 return 0;
3464 }
3465
3466 if (strcasecmp(path, "VendorSpecific") == 0) {
3467 snprintf(buf, sizeof(buf), "cp Certs/ca.pem SP/%s/ca.pem",
3468 fqdn);
3469 if (system(buf)) {
3470 send_resp(dut, conn, SIGMA_ERROR,
3471 "errorCode,Failed to copy OSU CA cert");
3472 return 0;
3473 }
3474
3475 snprintf(buf, sizeof(buf),
3476 "cp Certs/aaa-ca.pem SP/%s/aaa-ca.pem",
3477 fqdn);
3478 if (system(buf)) {
3479 send_resp(dut, conn, SIGMA_ERROR,
3480 "errorCode,Failed to copy AAA CA cert");
3481 return 0;
3482 }
3483 } else {
3484 snprintf(buf, sizeof(buf),
3485 "dl_osu_ca SP/%s/pps.xml SP/%s/ca.pem",
3486 fqdn, fqdn);
3487 if (run_hs20_osu(dut, buf) < 0) {
3488 send_resp(dut, conn, SIGMA_ERROR,
3489 "errorCode,Failed to download OSU CA cert");
3490 return 0;
3491 }
3492
3493 snprintf(buf, sizeof(buf),
3494 "dl_aaa_ca SP/%s/pps.xml SP/%s/aaa-ca.pem",
3495 fqdn, fqdn);
3496 if (run_hs20_osu(dut, buf) < 0) {
3497 sigma_dut_print(dut, DUT_MSG_INFO,
3498 "Failed to download AAA CA cert");
3499 }
3500 }
3501
3502 if (file_exists("next-client-cert.pem")) {
3503 snprintf(buf, sizeof(buf), "SP/%s/client-cert.pem", fqdn);
3504 if (rename("next-client-cert.pem", buf) < 0) {
3505 send_resp(dut, conn, SIGMA_ERROR,
3506 "errorCode,Could not move client certificate");
3507 return 0;
3508 }
3509 }
3510
3511 if (file_exists("next-client-key.pem")) {
3512 snprintf(buf, sizeof(buf), "SP/%s/client-key.pem", fqdn);
3513 if (rename("next-client-key.pem", buf) < 0) {
3514 send_resp(dut, conn, SIGMA_ERROR,
3515 "errorCode,Could not move client key");
3516 return 0;
3517 }
3518 }
3519
3520 snprintf(buf, sizeof(buf), "set_pps SP/%s/pps.xml", fqdn);
3521 if (run_hs20_osu(dut, buf) < 0) {
3522 send_resp(dut, conn, SIGMA_ERROR,
3523 "errorCode,Failed to configure credential from "
3524 "PPSMO");
3525 return 0;
3526 }
3527
3528 return 1;
3529}
3530
3531
3532static int download_cert(struct sigma_dut *dut,
3533 struct sigma_conn *conn,
3534 const char *intf,
3535 struct sigma_cmd *cmd)
3536{
3537 const char *name, *path;
3538 char url[500], buf[600];
3539
3540 name = get_param(cmd, "FileName");
3541 path = get_param(cmd, "FilePath");
3542 if (name == NULL || path == NULL)
3543 return -1;
3544
3545 if (strcasecmp(path, "VendorSpecific") == 0) {
3546 snprintf(url, sizeof(url), "Certs/%s-cert.pem", name);
3547 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured client "
3548 "certificate from the device (%s)", url);
3549 if (!file_exists(url)) {
3550 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
3551 "certificate file does not exist");
3552 return 0;
3553 }
3554 snprintf(buf, sizeof(buf), "cp %s next-client-cert.pem", url);
3555 if (system(buf) != 0) {
3556 send_resp(dut, conn, SIGMA_ERROR,
3557 "errorCode,Failed to copy client "
3558 "certificate");
3559 return 0;
3560 }
3561
3562 snprintf(url, sizeof(url), "Certs/%s-key.pem", name);
3563 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured client "
3564 "private key from the device (%s)", url);
3565 if (!file_exists(url)) {
3566 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
3567 "private key file does not exist");
3568 return 0;
3569 }
3570 snprintf(buf, sizeof(buf), "cp %s next-client-key.pem", url);
3571 if (system(buf) != 0) {
3572 send_resp(dut, conn, SIGMA_ERROR,
3573 "errorCode,Failed to copy client key");
3574 return 0;
3575 }
3576 } else if (strncasecmp(path, "http:", 5) != 0 &&
3577 strncasecmp(path, "https:", 6) != 0) {
3578 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
3579 "Unsupported FilePath value");
3580 return 0;
3581 } else {
3582 snprintf(url, sizeof(url), "%s/%s.pem", path, name);
3583 sigma_dut_print(dut, DUT_MSG_INFO, "Downloading client "
3584 "certificate/key from %s", url);
3585 snprintf(buf, sizeof(buf),
3586 "wget -T 10 -t 3 -O next-client-cert.pem '%s'", url);
3587 if (system(buf) != 0) {
3588 send_resp(dut, conn, SIGMA_ERROR,
3589 "errorCode,Failed to download client "
3590 "certificate");
3591 return 0;
3592 }
3593
3594 if (system("cp next-client-cert.pem next-client-key.pem") != 0)
3595 {
3596 send_resp(dut, conn, SIGMA_ERROR,
3597 "errorCode,Failed to copy client key");
3598 return 0;
3599 }
3600 }
3601
3602 return 1;
3603}
3604
3605
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02003606static int cmd_sta_preset_testparameters_60ghz(struct sigma_dut *dut,
3607 struct sigma_conn *conn,
3608 struct sigma_cmd *cmd)
3609{
3610 const char *val;
3611 const char *intf = get_param(cmd, "interface");
3612
3613 if (!intf)
3614 return -1;
3615
3616 val = get_param(cmd, "WscIEFragment");
3617 if (val && strcasecmp(val, "enable") == 0) {
3618 sigma_dut_print(dut, DUT_MSG_DEBUG,
3619 "Enable WSC IE fragmentation");
3620
3621 dut->wsc_fragment = 1;
3622 /* set long attributes to force fragmentation */
3623 if (wpa_command(intf, "SET device_name "
3624 WPS_LONG_DEVICE_NAME) < 0)
3625 return -2;
3626 if (wpa_command(intf, "SET manufacturer "
3627 WPS_LONG_MANUFACTURER) < 0)
3628 return -2;
3629 if (wpa_command(intf, "SET model_name "
3630 WPS_LONG_MODEL_NAME) < 0)
3631 return -2;
3632 if (wpa_command(intf, "SET model_number "
3633 WPS_LONG_MODEL_NUMBER) < 0)
3634 return -2;
3635 if (wpa_command(intf, "SET serial_number "
3636 WPS_LONG_SERIAL_NUMBER) < 0)
3637 return -2;
3638 }
3639
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02003640 val = get_param(cmd, "RSN_IE");
3641 if (val) {
3642 if (strcasecmp(val, "disable") == 0)
3643 dut->force_rsn_ie = FORCE_RSN_IE_REMOVE;
3644 else if (strcasecmp(val, "enable") == 0)
3645 dut->force_rsn_ie = FORCE_RSN_IE_ADD;
3646 }
3647
Alexei Avshalom Lazar744ae8a2019-01-31 17:26:46 +02003648 val = get_param(cmd, "WpsVersion");
3649 if (val)
3650 dut->wps_forced_version = get_wps_forced_version(dut, val);
3651
Alexei Avshalom Lazar2eccf4d2019-01-31 10:03:59 +02003652 val = get_param(cmd, "WscEAPFragment");
3653 if (val && strcasecmp(val, "enable") == 0)
3654 dut->eap_fragment = 1;
3655
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02003656 return 1;
3657}
3658
3659
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003660static int cmd_sta_preset_testparameters_hs2_r2(struct sigma_dut *dut,
3661 struct sigma_conn *conn,
3662 const char *intf,
3663 struct sigma_cmd *cmd)
3664{
3665 const char *val;
3666
3667 val = get_param(cmd, "FileType");
3668 if (val && strcasecmp(val, "PPSMO") == 0)
3669 return download_ppsmo(dut, conn, intf, cmd);
3670 if (val && strcasecmp(val, "CERT") == 0)
3671 return download_cert(dut, conn, intf, cmd);
3672 if (val) {
3673 send_resp(dut, conn, SIGMA_ERROR,
3674 "ErrorCode,Unsupported FileType");
3675 return 0;
3676 }
3677
3678 return 1;
3679}
3680
3681
Ankita Bajaja2cb5672017-10-25 16:08:28 +05303682static int cmd_sta_preset_testparameters_oce(struct sigma_dut *dut,
3683 struct sigma_conn *conn,
3684 const char *intf,
3685 struct sigma_cmd *cmd)
3686{
3687 const char *val;
Ankita Bajaj1bde7942018-01-09 19:15:01 +05303688 char buf[1000];
3689 char text[20];
3690 unsigned char addr[ETH_ALEN];
Ankita Bajaja2cb5672017-10-25 16:08:28 +05303691
3692 val = get_param(cmd, "OCESupport");
3693 if (val && strcasecmp(val, "Disable") == 0) {
3694 if (wpa_command(intf, "SET oce 0") < 0) {
3695 send_resp(dut, conn, SIGMA_ERROR,
3696 "ErrorCode,Failed to disable OCE");
3697 return 0;
3698 }
3699 } else if (val && strcasecmp(val, "Enable") == 0) {
3700 if (wpa_command(intf, "SET oce 1") < 0) {
3701 send_resp(dut, conn, SIGMA_ERROR,
3702 "ErrorCode,Failed to enable OCE");
3703 return 0;
3704 }
3705 }
3706
vamsi krishnaa2799492017-12-05 14:28:01 +05303707 val = get_param(cmd, "FILScap");
3708 if (val && (atoi(val) == 1)) {
3709 if (wpa_command(intf, "SET disable_fils 0") < 0) {
3710 send_resp(dut, conn, SIGMA_ERROR,
3711 "ErrorCode,Failed to enable FILS");
3712 return 0;
3713 }
3714 } else if (val && (atoi(val) == 0)) {
3715 if (wpa_command(intf, "SET disable_fils 1") < 0) {
3716 send_resp(dut, conn, SIGMA_ERROR,
3717 "ErrorCode,Failed to disable FILS");
3718 return 0;
3719 }
3720 }
3721
Ankita Bajaj1bde7942018-01-09 19:15:01 +05303722 val = get_param(cmd, "FILSHLP");
3723 if (val && strcasecmp(val, "Enable") == 0) {
3724 if (get_wpa_status(get_station_ifname(), "address", text,
3725 sizeof(text)) < 0)
3726 return -2;
3727 hwaddr_aton(text, addr);
3728 snprintf(buf, sizeof(buf),
3729 "FILS_HLP_REQ_ADD ff:ff:ff:ff:ff:ff "
3730 "080045100140000040004011399e00000000ffffffff00440043"
3731 "012cb30001010600fd4f46410000000000000000000000000000"
3732 "000000000000"
3733 "%02x%02x%02x%02x%02x%02x"
3734 "0000000000000000000000000000000000000000000000000000"
3735 "0000000000000000000000000000000000000000000000000000"
3736 "0000000000000000000000000000000000000000000000000000"
3737 "0000000000000000000000000000000000000000000000000000"
3738 "0000000000000000000000000000000000000000000000000000"
3739 "0000000000000000000000000000000000000000000000000000"
3740 "0000000000000000000000000000000000000000000000000000"
3741 "0000000000000000000000000000000000000000638253633501"
3742 "013d0701000af549d29b390205dc3c12616e64726f69642d6468"
3743 "63702d382e302e30370a0103060f1a1c333a3b2b5000ff00",
3744 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
3745 if (wpa_command(intf, buf)) {
3746 send_resp(dut, conn, SIGMA_ERROR,
3747 "ErrorCode,Failed to add HLP");
3748 return 0;
3749 }
3750 dut->fils_hlp = 1;
3751 }
3752
Ankita Bajaja2cb5672017-10-25 16:08:28 +05303753 return 1;
3754}
3755
3756
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003757static void ath_sta_set_noack(struct sigma_dut *dut, const char *intf,
3758 const char *val)
3759{
3760 int counter = 0;
3761 char token[50];
3762 char *result;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05303763 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003764
Peng Xub8fc5cc2017-05-10 17:27:28 -07003765 strlcpy(token, val, sizeof(token));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003766 token[sizeof(token) - 1] = '\0';
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05303767 result = strtok_r(token, ":", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003768 while (result) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07003769 if (strcmp(result, "disable") == 0)
3770 run_iwpriv(dut, intf, "noackpolicy %d 1 0", counter);
3771 else
3772 run_iwpriv(dut, intf, "noackpolicy %d 1 1", counter);
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05303773 result = strtok_r(NULL, ":", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003774 counter++;
3775 }
3776}
3777
3778
3779static void ath_sta_set_rts(struct sigma_dut *dut, const char *intf,
3780 const char *val)
3781{
3782 char buf[100];
3783
3784 snprintf(buf, sizeof(buf), "iwconfig %s rts %s", intf, val);
3785 if (system(buf) != 0) {
3786 sigma_dut_print(dut, DUT_MSG_ERROR, "iwconfig RTS failed");
3787 }
3788}
3789
3790
3791static void ath_sta_set_wmm(struct sigma_dut *dut, const char *intf,
3792 const char *val)
3793{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003794 if (strcasecmp(val, "off") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07003795 run_iwpriv(dut, intf, "wmm 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003796 }
3797}
3798
3799
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08003800static int wcn_sta_set_wmm(struct sigma_dut *dut, const char *intf,
3801 const char *val)
3802{
3803#ifdef NL80211_SUPPORT
3804 struct nl_msg *msg;
3805 int ret = 0;
3806 struct nlattr *params;
3807 int ifindex;
3808 int wmmenable = 1;
3809
3810 if (val &&
3811 (strcasecmp(val, "off") == 0 || strcmp(val, "0") == 0))
3812 wmmenable = 0;
3813
3814 ifindex = if_nametoindex(intf);
3815 if (ifindex == 0) {
3816 sigma_dut_print(dut, DUT_MSG_ERROR,
3817 "%s: Index for interface %s failed",
3818 __func__, intf);
3819 return -1;
3820 }
3821
3822 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
3823 NL80211_CMD_VENDOR)) ||
3824 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
3825 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
3826 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
3827 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
3828 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
3829 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WMM_ENABLE,
3830 wmmenable)) {
3831 sigma_dut_print(dut, DUT_MSG_ERROR,
3832 "%s: err in adding vendor_cmd and vendor_data",
3833 __func__);
3834 nlmsg_free(msg);
3835 return -1;
3836 }
3837 nla_nest_end(msg, params);
3838
3839 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
3840 if (ret) {
3841 sigma_dut_print(dut, DUT_MSG_ERROR,
3842 "%s: err in send_and_recv_msgs, ret=%d",
3843 __func__, ret);
3844 }
3845 return ret;
3846#else /* NL80211_SUPPORT */
3847 sigma_dut_print(dut, DUT_MSG_ERROR,
3848 "WMM cannot be changed without NL80211_SUPPORT defined");
3849 return -1;
3850#endif /* NL80211_SUPPORT */
3851}
3852
3853
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003854static void ath_sta_set_sgi(struct sigma_dut *dut, const char *intf,
3855 const char *val)
3856{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003857 int sgi20;
3858
3859 sgi20 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
3860
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07003861 run_iwpriv(dut, intf, "shortgi %d", sgi20);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003862}
3863
3864
3865static void ath_sta_set_11nrates(struct sigma_dut *dut, const char *intf,
3866 const char *val)
3867{
Pradeep Reddy POTTETI67376b72016-10-25 20:08:17 +05303868 int rate_code, v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003869
3870 /* Disable Tx Beam forming when using a fixed rate */
3871 ath_disable_txbf(dut, intf);
3872
Pradeep Reddy POTTETI67376b72016-10-25 20:08:17 +05303873 v = atoi(val);
3874 if (v < 0 || v > 32) {
3875 sigma_dut_print(dut, DUT_MSG_ERROR,
3876 "Invalid Fixed MCS rate: %d", v);
3877 return;
3878 }
3879 rate_code = 0x80 + v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003880
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07003881 run_iwpriv(dut, intf, "set11NRates 0x%x", rate_code);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003882
3883 /* Channel width gets messed up, fix this */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07003884 run_iwpriv(dut, intf, "chwidth %d", dut->chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003885}
3886
3887
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08003888static void iwpriv_sta_set_amsdu(struct sigma_dut *dut, const char *intf,
3889 const char *val)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003890{
3891 char buf[60];
3892
3893 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)
3894 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 2", intf);
3895 else
3896 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 1", intf);
3897
3898 if (system(buf) != 0)
3899 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv amsdu failed");
3900}
3901
3902
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07003903static int iwpriv_sta_set_ampdu(struct sigma_dut *dut, const char *intf,
3904 int ampdu)
3905{
3906 char buf[60];
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08003907 int maxaggregation = 63;
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07003908
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08003909 if (ampdu)
3910 ampdu = maxaggregation;
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07003911 snprintf(buf, sizeof(buf), "iwpriv %s ampdu %d", intf, ampdu);
3912 if (system(buf) != 0) {
3913 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv ampdu failed");
3914 return -1;
3915 }
3916
3917 return 0;
3918}
3919
3920
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003921static void ath_sta_set_stbc(struct sigma_dut *dut, const char *intf,
3922 const char *val)
3923{
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07003924 run_iwpriv(dut, intf, "tx_stbc %s", val);
3925 run_iwpriv(dut, intf, "rx_stbc %s", val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003926}
3927
3928
3929static int wcn_sta_set_cts_width(struct sigma_dut *dut, const char *intf,
3930 const char *val)
3931{
3932 char buf[60];
3933
Peng Xucc317ed2017-05-18 16:44:37 -07003934 if (strcmp(val, "160") == 0) {
3935 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 5", intf);
3936 } else if (strcmp(val, "80") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003937 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 3", intf);
3938 } else if (strcmp(val, "40") == 0) {
3939 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 2", intf);
3940 } else if (strcmp(val, "20") == 0) {
3941 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 1", intf);
3942 } else if (strcasecmp(val, "Auto") == 0) {
3943 buf[0] = '\0';
3944 } else {
3945 sigma_dut_print(dut, DUT_MSG_ERROR,
3946 "WIDTH/CTS_WIDTH value not supported");
3947 return -1;
3948 }
3949
3950 if (buf[0] != '\0' && system(buf) != 0) {
3951 sigma_dut_print(dut, DUT_MSG_ERROR,
3952 "Failed to set WIDTH/CTS_WIDTH");
3953 return -1;
3954 }
3955
3956 return 0;
3957}
3958
3959
3960int ath_set_width(struct sigma_dut *dut, struct sigma_conn *conn,
3961 const char *intf, const char *val)
3962{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003963 if (strcasecmp(val, "Auto") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07003964 run_iwpriv(dut, intf, "chwidth 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003965 dut->chwidth = 0;
3966 } else if (strcasecmp(val, "20") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07003967 run_iwpriv(dut, intf, "chwidth 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003968 dut->chwidth = 0;
3969 } else if (strcasecmp(val, "40") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07003970 run_iwpriv(dut, intf, "chwidth 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003971 dut->chwidth = 1;
3972 } else if (strcasecmp(val, "80") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07003973 run_iwpriv(dut, intf, "chwidth 2");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003974 dut->chwidth = 2;
3975 } else if (strcasecmp(val, "160") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07003976 run_iwpriv(dut, intf, "chwidth 3");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003977 dut->chwidth = 3;
3978 } else {
3979 send_resp(dut, conn, SIGMA_ERROR,
3980 "ErrorCode,WIDTH not supported");
3981 return -1;
3982 }
3983
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003984 return 0;
3985}
3986
3987
3988static int wcn_sta_set_sp_stream(struct sigma_dut *dut, const char *intf,
3989 const char *val)
3990{
3991 char buf[60];
Arif Hussainac6c5112018-05-25 17:34:00 -07003992 int sta_nss;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003993
Amarnath Hullur Subramanyamd5374fa2018-02-25 19:00:24 -08003994 if (strcmp(val, "1SS") == 0 || strcmp(val, "1") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003995 snprintf(buf, sizeof(buf), "iwpriv %s nss 1", intf);
Arif Hussainac6c5112018-05-25 17:34:00 -07003996 sta_nss = 1;
Amarnath Hullur Subramanyamd5374fa2018-02-25 19:00:24 -08003997 } else if (strcmp(val, "2SS") == 0 || strcmp(val, "2") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003998 snprintf(buf, sizeof(buf), "iwpriv %s nss 2", intf);
Arif Hussainac6c5112018-05-25 17:34:00 -07003999 sta_nss = 2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004000 } else {
4001 sigma_dut_print(dut, DUT_MSG_ERROR,
4002 "SP_STREAM value not supported");
4003 return -1;
4004 }
4005
4006 if (system(buf) != 0) {
4007 sigma_dut_print(dut, DUT_MSG_ERROR,
4008 "Failed to set SP_STREAM");
4009 return -1;
4010 }
4011
Arif Hussainac6c5112018-05-25 17:34:00 -07004012 dut->sta_nss = sta_nss;
4013
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004014 return 0;
4015}
4016
4017
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05304018static void wcn_sta_set_stbc(struct sigma_dut *dut, const char *intf,
4019 const char *val)
4020{
4021 char buf[60];
4022
4023 snprintf(buf, sizeof(buf), "iwpriv %s tx_stbc %s", intf, val);
4024 if (system(buf) != 0)
4025 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv tx_stbc failed");
4026
4027 snprintf(buf, sizeof(buf), "iwpriv %s rx_stbc %s", intf, val);
4028 if (system(buf) != 0)
4029 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv rx_stbc failed");
4030}
4031
4032
Ashwini Patil68d02cd2017-01-10 15:39:16 +05304033static int mbo_set_cellular_data_capa(struct sigma_dut *dut,
4034 struct sigma_conn *conn,
4035 const char *intf, int capa)
4036{
4037 char buf[32];
4038
4039 if (capa > 0 && capa < 4) {
4040 snprintf(buf, sizeof(buf), "SET mbo_cell_capa %d", capa);
4041 if (wpa_command(intf, buf) < 0) {
4042 send_resp(dut, conn, SIGMA_ERROR,
4043 "ErrorCode, Failed to set cellular data capability");
4044 return 0;
4045 }
4046 return 1;
4047 }
4048
4049 sigma_dut_print(dut, DUT_MSG_ERROR,
4050 "Invalid Cellular data capability: %d", capa);
4051 send_resp(dut, conn, SIGMA_INVALID,
4052 "ErrorCode,Invalid cellular data capability");
4053 return 0;
4054}
4055
4056
Ashwini Patil9183fdb2017-04-13 16:58:25 +05304057static int mbo_set_roaming(struct sigma_dut *dut, struct sigma_conn *conn,
4058 const char *intf, const char *val)
4059{
4060 if (strcasecmp(val, "Disable") == 0) {
4061 if (wpa_command(intf, "SET roaming 0") < 0) {
4062 send_resp(dut, conn, SIGMA_ERROR,
4063 "ErrorCode,Failed to disable roaming");
4064 return 0;
4065 }
4066 return 1;
4067 }
4068
4069 if (strcasecmp(val, "Enable") == 0) {
4070 if (wpa_command(intf, "SET roaming 1") < 0) {
4071 send_resp(dut, conn, SIGMA_ERROR,
4072 "ErrorCode,Failed to enable roaming");
4073 return 0;
4074 }
4075 return 1;
4076 }
4077
4078 sigma_dut_print(dut, DUT_MSG_ERROR,
4079 "Invalid value provided for roaming: %s", val);
4080 send_resp(dut, conn, SIGMA_INVALID,
4081 "ErrorCode,Unknown value provided for Roaming");
4082 return 0;
4083}
4084
4085
Ashwini Patila75de5a2017-04-13 16:35:05 +05304086static int mbo_set_assoc_disallow(struct sigma_dut *dut,
4087 struct sigma_conn *conn,
4088 const char *intf, const char *val)
4089{
4090 if (strcasecmp(val, "Disable") == 0) {
4091 if (wpa_command(intf, "SET ignore_assoc_disallow 1") < 0) {
4092 send_resp(dut, conn, SIGMA_ERROR,
4093 "ErrorCode,Failed to disable Assoc_disallow");
4094 return 0;
4095 }
4096 return 1;
4097 }
4098
4099 if (strcasecmp(val, "Enable") == 0) {
4100 if (wpa_command(intf, "SET ignore_assoc_disallow 0") < 0) {
4101 send_resp(dut, conn, SIGMA_ERROR,
4102 "ErrorCode,Failed to enable Assoc_disallow");
4103 return 0;
4104 }
4105 return 1;
4106 }
4107
4108 sigma_dut_print(dut, DUT_MSG_ERROR,
4109 "Invalid value provided for Assoc_disallow: %s", val);
4110 send_resp(dut, conn, SIGMA_INVALID,
4111 "ErrorCode,Unknown value provided for Assoc_disallow");
4112 return 0;
4113}
4114
4115
Ashwini Patilc63161e2017-04-13 16:30:23 +05304116static int mbo_set_bss_trans_req(struct sigma_dut *dut, struct sigma_conn *conn,
4117 const char *intf, const char *val)
4118{
4119 if (strcasecmp(val, "Reject") == 0) {
4120 if (wpa_command(intf, "SET reject_btm_req_reason 1") < 0) {
4121 send_resp(dut, conn, SIGMA_ERROR,
4122 "ErrorCode,Failed to Reject BTM Request");
4123 return 0;
4124 }
4125 return 1;
4126 }
4127
4128 if (strcasecmp(val, "Accept") == 0) {
4129 if (wpa_command(intf, "SET reject_btm_req_reason 0") < 0) {
4130 send_resp(dut, conn, SIGMA_ERROR,
4131 "ErrorCode,Failed to Accept BTM Request");
4132 return 0;
4133 }
4134 return 1;
4135 }
4136
4137 sigma_dut_print(dut, DUT_MSG_ERROR,
4138 "Invalid value provided for BSS_Transition: %s", val);
4139 send_resp(dut, conn, SIGMA_INVALID,
4140 "ErrorCode,Unknown value provided for BSS_Transition");
4141 return 0;
4142}
4143
4144
Ashwini Patil00402582017-04-13 12:29:39 +05304145static int mbo_set_non_pref_ch_list(struct sigma_dut *dut,
4146 struct sigma_conn *conn,
4147 const char *intf,
4148 struct sigma_cmd *cmd)
4149{
4150 const char *ch, *pref, *op_class, *reason;
4151 char buf[120];
4152 int len, ret;
4153
4154 pref = get_param(cmd, "Ch_Pref");
4155 if (!pref)
4156 return 1;
4157
4158 if (strcasecmp(pref, "clear") == 0) {
4159 free(dut->non_pref_ch_list);
4160 dut->non_pref_ch_list = NULL;
4161 } else {
4162 op_class = get_param(cmd, "Ch_Op_Class");
4163 if (!op_class) {
4164 send_resp(dut, conn, SIGMA_INVALID,
4165 "ErrorCode,Ch_Op_Class not provided");
4166 return 0;
4167 }
4168
4169 ch = get_param(cmd, "Ch_Pref_Num");
4170 if (!ch) {
4171 send_resp(dut, conn, SIGMA_INVALID,
4172 "ErrorCode,Ch_Pref_Num not provided");
4173 return 0;
4174 }
4175
4176 reason = get_param(cmd, "Ch_Reason_Code");
4177 if (!reason) {
4178 send_resp(dut, conn, SIGMA_INVALID,
4179 "ErrorCode,Ch_Reason_Code not provided");
4180 return 0;
4181 }
4182
4183 if (!dut->non_pref_ch_list) {
4184 dut->non_pref_ch_list =
4185 calloc(1, NON_PREF_CH_LIST_SIZE);
4186 if (!dut->non_pref_ch_list) {
4187 send_resp(dut, conn, SIGMA_ERROR,
4188 "ErrorCode,Failed to allocate memory for non_pref_ch_list");
4189 return 0;
4190 }
4191 }
4192 len = strlen(dut->non_pref_ch_list);
4193 ret = snprintf(dut->non_pref_ch_list + len,
4194 NON_PREF_CH_LIST_SIZE - len,
4195 " %s:%s:%s:%s", op_class, ch, pref, reason);
4196 if (ret > 0 && ret < NON_PREF_CH_LIST_SIZE - len) {
4197 sigma_dut_print(dut, DUT_MSG_DEBUG, "non_pref_list: %s",
4198 dut->non_pref_ch_list);
4199 } else {
4200 sigma_dut_print(dut, DUT_MSG_ERROR,
4201 "snprintf failed for non_pref_list, ret = %d",
4202 ret);
4203 send_resp(dut, conn, SIGMA_ERROR,
4204 "ErrorCode,snprintf failed");
4205 free(dut->non_pref_ch_list);
4206 dut->non_pref_ch_list = NULL;
4207 return 0;
4208 }
4209 }
4210
4211 ret = snprintf(buf, sizeof(buf), "SET non_pref_chan%s",
4212 dut->non_pref_ch_list ? dut->non_pref_ch_list : " ");
4213 if (ret < 0 || ret >= (int) sizeof(buf)) {
4214 sigma_dut_print(dut, DUT_MSG_DEBUG,
4215 "snprintf failed for set non_pref_chan, ret: %d",
4216 ret);
4217 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,snprint failed");
4218 return 0;
4219 }
4220
4221 if (wpa_command(intf, buf) < 0) {
4222 send_resp(dut, conn, SIGMA_ERROR,
4223 "ErrorCode,Failed to set non-preferred channel list");
4224 return 0;
4225 }
4226
4227 return 1;
4228}
4229
4230
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08004231#ifdef NL80211_SUPPORT
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08004232
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08004233static int sta_set_he_htc_supp(struct sigma_dut *dut, const char *intf,
4234 uint8_t cfg)
4235{
4236 struct nl_msg *msg;
4237 int ret = 0;
4238 struct nlattr *params;
4239 int ifindex;
4240
4241 ifindex = if_nametoindex(intf);
4242 if (ifindex == 0) {
4243 sigma_dut_print(dut, DUT_MSG_ERROR,
4244 "%s: Index for interface %s failed",
4245 __func__, intf);
4246 return -1;
4247 }
4248
4249 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4250 NL80211_CMD_VENDOR)) ||
4251 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4252 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4253 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4254 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4255 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4256 nla_put_u8(msg,
4257 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_HTC_HE_SUPP,
4258 cfg)) {
4259 sigma_dut_print(dut, DUT_MSG_ERROR,
4260 "%s: err in adding vendor_cmd and vendor_data",
4261 __func__);
4262 nlmsg_free(msg);
4263 return -1;
4264 }
4265 nla_nest_end(msg, params);
4266
4267 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4268 if (ret) {
4269 sigma_dut_print(dut, DUT_MSG_ERROR,
4270 "%s: err in send_and_recv_msgs, ret=%d",
4271 __func__, ret);
4272 }
4273 return ret;
4274}
4275
4276
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08004277static int sta_set_he_fragmentation(struct sigma_dut *dut, const char *intf,
4278 enum he_fragmentation_val frag)
4279{
4280 struct nl_msg *msg;
4281 int ret = 0;
4282 struct nlattr *params;
4283 int ifindex;
4284
4285 ifindex = if_nametoindex(intf);
4286 if (ifindex == 0) {
4287 sigma_dut_print(dut, DUT_MSG_ERROR,
4288 "%s: Index for interface %s failed",
4289 __func__, intf);
4290 return -1;
4291 }
4292
4293 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4294 NL80211_CMD_VENDOR)) ||
4295 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4296 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4297 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4298 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4299 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4300 nla_put_u8(msg,
4301 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_FRAGMENTATION,
4302 frag)) {
4303 sigma_dut_print(dut, DUT_MSG_ERROR,
4304 "%s: err in adding vendor_cmd and vendor_data",
4305 __func__);
4306 nlmsg_free(msg);
4307 return -1;
4308 }
4309 nla_nest_end(msg, params);
4310
4311 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4312 if (ret) {
4313 sigma_dut_print(dut, DUT_MSG_ERROR,
4314 "%s: err in send_and_recv_msgs, ret=%d",
4315 __func__, ret);
4316 }
4317 return ret;
4318}
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08004319
4320
Subhani Shaik8e7a3052018-04-24 14:03:00 -07004321static int sta_set_he_ltf(struct sigma_dut *dut, const char *intf,
4322 enum qca_wlan_he_ltf_cfg ltf)
4323{
4324 struct nl_msg *msg;
4325 int ret = 0;
4326 struct nlattr *params;
4327 int ifindex;
4328
4329 ifindex = if_nametoindex(intf);
4330 if (ifindex == 0) {
4331 sigma_dut_print(dut, DUT_MSG_ERROR,
4332 "%s: Index for interface %s failed",
4333 __func__, intf);
4334 return -1;
4335 }
4336
4337 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4338 NL80211_CMD_VENDOR)) ||
4339 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4340 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4341 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4342 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4343 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4344 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_LTF,
4345 ltf)) {
4346 sigma_dut_print(dut, DUT_MSG_ERROR,
4347 "%s: err in adding vendor_cmd and vendor_data",
4348 __func__);
4349 nlmsg_free(msg);
4350 return -1;
4351 }
4352 nla_nest_end(msg, params);
4353
4354 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4355 if (ret) {
4356 sigma_dut_print(dut, DUT_MSG_ERROR,
4357 "%s: err in send_and_recv_msgs, ret=%d",
4358 __func__, ret);
4359 }
4360 return ret;
4361}
4362
4363
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08004364static int nlvendor_sta_set_noack(struct sigma_dut *dut, const char *intf,
4365 int noack, enum qca_wlan_ac_type ac)
4366{
4367 struct nl_msg *msg;
4368 int ret = 0;
4369 struct nlattr *params;
4370 int ifindex;
4371
4372 ifindex = if_nametoindex(intf);
4373 if (ifindex == 0) {
4374 sigma_dut_print(dut, DUT_MSG_ERROR,
4375 "%s: Index for interface %s failed",
4376 __func__, intf);
4377 return -1;
4378 }
4379
4380 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4381 NL80211_CMD_VENDOR)) ||
4382 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4383 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4384 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4385 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4386 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4387 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_NO_ACK,
4388 noack) ||
4389 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_NO_ACK_AC,
4390 ac)) {
4391 sigma_dut_print(dut, DUT_MSG_ERROR,
4392 "%s: err in adding vendor_cmd and vendor_data",
4393 __func__);
4394 nlmsg_free(msg);
4395 return -1;
4396 }
4397 nla_nest_end(msg, params);
4398
4399 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4400 if (ret) {
4401 sigma_dut_print(dut, DUT_MSG_ERROR,
4402 "%s: err in send_and_recv_msgs, ret=%d",
4403 __func__, ret);
4404 }
4405 return ret;
4406}
4407
4408
4409static void wcn_sta_set_noack(struct sigma_dut *dut, const char *intf,
4410 const char *val)
4411{
4412 int noack, ret;
4413 char token[100];
4414 char *result;
4415 char *saveptr;
4416 enum qca_wlan_ac_type ac = QCA_WLAN_AC_BE;
4417
4418 strlcpy(token, val, sizeof(token));
4419 token[sizeof(token) - 1] = '\0';
4420 result = strtok_r(token, ":", &saveptr);
4421 while (result) {
4422 noack = strcasecmp(result, "Disable") != 0;
4423 ret = nlvendor_sta_set_noack(dut, intf, noack, ac);
4424 if (ret) {
4425 sigma_dut_print(dut, DUT_MSG_ERROR,
4426 "nlvendor_sta_set_noack failed for ac:%d, ret:%d",
4427 ac, ret);
4428 }
4429 result = strtok_r(NULL, ":", &saveptr);
4430 ac++;
4431 }
4432}
4433
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08004434#endif /* NL80211_SUPPORT */
4435
4436
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004437static int cmd_sta_preset_testparameters(struct sigma_dut *dut,
4438 struct sigma_conn *conn,
4439 struct sigma_cmd *cmd)
4440{
4441 const char *intf = get_param(cmd, "Interface");
4442 const char *val;
4443
4444 val = get_param(cmd, "Program");
Jouni Malinen1f6ae642018-06-07 23:56:13 +03004445 if (val && (strcasecmp(val, "HS2-R2") == 0 ||
4446 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004447 return cmd_sta_preset_testparameters_hs2_r2(dut, conn, intf,
4448 cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004449
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07004450 if (val && strcasecmp(val, "LOC") == 0)
4451 return loc_cmd_sta_preset_testparameters(dut, conn, cmd);
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02004452 if (val && strcasecmp(val, "60GHZ") == 0) {
4453 val = get_param(cmd, "WPS");
4454 if (val && strcasecmp(val, "disable") == 0) {
4455 dut->wps_disable = 1;
4456 sigma_dut_print(dut, DUT_MSG_INFO, "WPS disabled");
4457 } else {
4458 /* wps_disable can have other value from the previous
4459 * test, so make sure it has the correct value.
4460 */
4461 dut->wps_disable = 0;
4462 }
4463
4464 val = get_param(cmd, "P2P");
4465 if (val && strcasecmp(val, "disable") == 0)
4466 sigma_dut_print(dut, DUT_MSG_INFO, "P2P disabled");
4467 }
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07004468
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02004469 if (dut->program == PROGRAM_WPS && dut->band == WPS_BAND_60G)
4470 return cmd_sta_preset_testparameters_60ghz(dut, conn, cmd);
4471
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004472#ifdef ANDROID_NAN
4473 if (val && strcasecmp(val, "NAN") == 0)
4474 return nan_cmd_sta_preset_testparameters(dut, conn, cmd);
4475#endif /* ANDROID_NAN */
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07004476#ifdef MIRACAST
4477 if (val && (strcasecmp(val, "WFD") == 0 ||
4478 strcasecmp(val, "DisplayR2") == 0))
4479 return miracast_preset_testparameters(dut, conn, cmd);
4480#endif /* MIRACAST */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004481
Ashwini Patil68d02cd2017-01-10 15:39:16 +05304482 if (val && strcasecmp(val, "MBO") == 0) {
4483 val = get_param(cmd, "Cellular_Data_Cap");
4484 if (val &&
4485 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
4486 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +05304487
4488 val = get_param(cmd, "Ch_Pref");
4489 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
4490 return 0;
4491
Ashwini Patilc63161e2017-04-13 16:30:23 +05304492 val = get_param(cmd, "BSS_Transition");
4493 if (val && mbo_set_bss_trans_req(dut, conn, intf, val) == 0)
4494 return 0;
4495
Ashwini Patila75de5a2017-04-13 16:35:05 +05304496 val = get_param(cmd, "Assoc_Disallow");
4497 if (val && mbo_set_assoc_disallow(dut, conn, intf, val) == 0)
4498 return 0;
4499
Ashwini Patil9183fdb2017-04-13 16:58:25 +05304500 val = get_param(cmd, "Roaming");
4501 if (val && mbo_set_roaming(dut, conn, intf, val) == 0)
4502 return 0;
4503
Ashwini Patil68d02cd2017-01-10 15:39:16 +05304504 return 1;
4505 }
4506
Ankita Bajaja2cb5672017-10-25 16:08:28 +05304507 if (val && strcasecmp(val, "OCE") == 0)
4508 return cmd_sta_preset_testparameters_oce(dut, conn, intf, cmd);
4509
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004510#if 0
4511 val = get_param(cmd, "Supplicant");
4512 if (val && strcasecmp(val, "Default") != 0) {
4513 send_resp(dut, conn, SIGMA_ERROR,
4514 "ErrorCode,Only default(Vendor) supplicant "
4515 "supported");
4516 return 0;
4517 }
4518#endif
4519
4520 val = get_param(cmd, "RTS");
4521 if (val) {
4522 switch (get_driver_type()) {
4523 case DRIVER_ATHEROS:
4524 ath_sta_set_rts(dut, intf, val);
4525 break;
4526 default:
4527#if 0
4528 send_resp(dut, conn, SIGMA_ERROR,
4529 "ErrorCode,Setting RTS not supported");
4530 return 0;
4531#else
4532 sigma_dut_print(dut, DUT_MSG_DEBUG,
4533 "Setting RTS not supported");
4534 break;
4535#endif
4536 }
4537 }
4538
4539#if 0
4540 val = get_param(cmd, "FRGMNT");
4541 if (val) {
4542 /* TODO */
4543 send_resp(dut, conn, SIGMA_ERROR,
4544 "ErrorCode,Setting FRGMNT not supported");
4545 return 0;
4546 }
4547#endif
4548
4549#if 0
4550 val = get_param(cmd, "Preamble");
4551 if (val) {
4552 /* TODO: Long/Short */
4553 send_resp(dut, conn, SIGMA_ERROR,
4554 "ErrorCode,Setting Preamble not supported");
4555 return 0;
4556 }
4557#endif
4558
4559 val = get_param(cmd, "Mode");
4560 if (val) {
4561 if (strcmp(val, "11b") == 0 ||
4562 strcmp(val, "11g") == 0 ||
4563 strcmp(val, "11a") == 0 ||
4564 strcmp(val, "11n") == 0 ||
4565 strcmp(val, "11ng") == 0 ||
4566 strcmp(val, "11nl") == 0 ||
4567 strcmp(val, "11nl(nabg)") == 0 ||
4568 strcmp(val, "AC") == 0 ||
4569 strcmp(val, "11AC") == 0 ||
4570 strcmp(val, "11ac") == 0 ||
4571 strcmp(val, "11na") == 0 ||
Amarnath Hullur Subramanyamb0db2712018-01-30 19:40:35 -08004572 strcmp(val, "11an") == 0 ||
4573 strcmp(val, "11ax") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004574 /* STA supports all modes by default */
4575 } else {
4576 send_resp(dut, conn, SIGMA_ERROR,
4577 "ErrorCode,Setting Mode not supported");
4578 return 0;
4579 }
Amarnath Hullur Subramanyam97d0e532018-01-31 02:53:02 -08004580
4581 /* Change the mode only in case of testbed for HE program
4582 * and for 11a and 11g modes only. */
4583 if (dut->program == PROGRAM_HE &&
4584 dut->device_type == STA_testbed) {
4585 int phymode;
4586 char buf[60];
4587
4588 if (strcmp(val, "11a") == 0) {
Amarnath Hullur Subramanyam94dfaf02018-03-02 19:26:57 -08004589 phymode = 1; /* IEEE80211_MODE_11A */
4590 } else if (strcmp(val, "11g") == 0) {
4591 phymode = 3; /* IEEE80211_MODE_11G */
4592 } else if (strcmp(val, "11b") == 0) {
4593 phymode = 2; /* IEEE80211_MODE_11B */
4594 } else if (strcmp(val, "11n") == 0 ||
4595 strcmp(val, "11nl") == 0 ||
4596 strcmp(val, "11nl(nabg)") == 0) {
4597 phymode = 22; /* IEEE80211_MODE_11AGN */
4598 } else if (strcmp(val, "11ng") == 0) {
4599 phymode = 13; /* IEEE80211_MODE_11NG_HT40 */
4600 } else if (strcmp(val, "AC") == 0 ||
4601 strcasecmp(val, "11AC") == 0) {
4602 phymode = 19; /* IEEE80211_MODE_11AC_VHT80 */
4603 } else if (strcmp(val, "11na") == 0 ||
4604 strcasecmp(val, "11an") == 0) {
4605 phymode = 14; /* IEEE80211_MODE_11NA_HT40 */
4606 } else if (strcmp(val, "11ax") == 0) {
4607 phymode = 0; /* IEEE80211_MODE_AUTO */
Amarnath Hullur Subramanyam97d0e532018-01-31 02:53:02 -08004608 } else {
4609 sigma_dut_print(dut, DUT_MSG_DEBUG,
4610 "Ignoring mode change for mode: %s",
4611 val);
4612 phymode = -1;
4613 }
4614 if (phymode != -1) {
4615 snprintf(buf, sizeof(buf),
4616 "iwpriv %s setphymode %d",
4617 intf, phymode);
4618 if (system(buf) != 0) {
4619 sigma_dut_print(dut, DUT_MSG_ERROR,
4620 "iwpriv setting of phymode failed");
4621 }
4622 }
4623 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004624 }
4625
4626 val = get_param(cmd, "wmm");
4627 if (val) {
4628 switch (get_driver_type()) {
4629 case DRIVER_ATHEROS:
4630 ath_sta_set_wmm(dut, intf, val);
4631 break;
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08004632 case DRIVER_WCN:
4633 wcn_sta_set_wmm(dut, intf, val);
4634 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004635 default:
4636 sigma_dut_print(dut, DUT_MSG_DEBUG,
4637 "Setting wmm not supported");
4638 break;
4639 }
4640 }
4641
4642 val = get_param(cmd, "Powersave");
4643 if (val) {
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08004644 char buf[60];
4645
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004646 if (strcmp(val, "0") == 0 || strcasecmp(val, "off") == 0) {
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08004647 if (get_driver_type() == DRIVER_WCN) {
4648 snprintf(buf, sizeof(buf),
4649 "iwpriv %s setPower 2", intf);
4650 if (system(buf) != 0) {
4651 sigma_dut_print(dut, DUT_MSG_ERROR,
4652 "iwpriv setPower 2 failed");
4653 return 0;
4654 }
4655 }
4656
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004657 if (wpa_command(get_station_ifname(),
4658 "P2P_SET ps 0") < 0)
4659 return -2;
4660 /* Make sure test modes are disabled */
4661 wpa_command(get_station_ifname(), "P2P_SET ps 98");
4662 wpa_command(get_station_ifname(), "P2P_SET ps 96");
4663 } else if (strcmp(val, "1") == 0 ||
4664 strcasecmp(val, "PSPoll") == 0 ||
4665 strcasecmp(val, "on") == 0) {
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08004666 if (get_driver_type() == DRIVER_WCN) {
4667 snprintf(buf, sizeof(buf),
4668 "iwpriv %s setPower 1", intf);
4669 if (system(buf) != 0) {
4670 sigma_dut_print(dut, DUT_MSG_ERROR,
4671 "iwpriv setPower 1 failed");
4672 return 0;
4673 }
4674 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004675 /* Disable default power save mode */
4676 wpa_command(get_station_ifname(), "P2P_SET ps 0");
4677 /* Enable PS-Poll test mode */
4678 if (wpa_command(get_station_ifname(),
4679 "P2P_SET ps 97") < 0 ||
4680 wpa_command(get_station_ifname(),
4681 "P2P_SET ps 99") < 0)
4682 return -2;
4683 } else if (strcmp(val, "2") == 0 ||
4684 strcasecmp(val, "Fast") == 0) {
4685 /* TODO */
4686 send_resp(dut, conn, SIGMA_ERROR,
4687 "ErrorCode,Powersave=Fast not supported");
4688 return 0;
4689 } else if (strcmp(val, "3") == 0 ||
4690 strcasecmp(val, "PSNonPoll") == 0) {
4691 /* Make sure test modes are disabled */
4692 wpa_command(get_station_ifname(), "P2P_SET ps 98");
4693 wpa_command(get_station_ifname(), "P2P_SET ps 96");
4694
4695 /* Enable default power save mode */
4696 if (wpa_command(get_station_ifname(),
4697 "P2P_SET ps 1") < 0)
4698 return -2;
4699 } else
4700 return -1;
4701 }
4702
4703 val = get_param(cmd, "NoAck");
4704 if (val) {
4705 switch (get_driver_type()) {
4706 case DRIVER_ATHEROS:
4707 ath_sta_set_noack(dut, intf, val);
4708 break;
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08004709#ifdef NL80211_SUPPORT
4710 case DRIVER_WCN:
4711 wcn_sta_set_noack(dut, intf, val);
4712 break;
4713#endif /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004714 default:
4715 send_resp(dut, conn, SIGMA_ERROR,
4716 "ErrorCode,Setting NoAck not supported");
4717 return 0;
4718 }
4719 }
4720
4721 val = get_param(cmd, "IgnoreChswitchProhibit");
4722 if (val) {
4723 /* TODO: Enabled/disabled */
4724 if (strcasecmp(val, "Enabled") == 0) {
4725 send_resp(dut, conn, SIGMA_ERROR,
4726 "ErrorCode,Enabling IgnoreChswitchProhibit "
4727 "not supported");
4728 return 0;
4729 }
4730 }
4731
4732 val = get_param(cmd, "TDLS");
4733 if (val) {
4734 if (strcasecmp(val, "Disabled") == 0) {
4735 if (wpa_command(intf, "SET tdls_disabled 1")) {
4736 send_resp(dut, conn, SIGMA_ERROR,
4737 "ErrorCode,Failed to disable TDLS");
4738 return 0;
4739 }
4740 } else if (strcasecmp(val, "Enabled") == 0) {
4741 if (wpa_command(intf, "SET tdls_disabled 0")) {
4742 send_resp(dut, conn, SIGMA_ERROR,
4743 "ErrorCode,Failed to enable TDLS");
4744 return 0;
4745 }
4746 } else {
4747 send_resp(dut, conn, SIGMA_ERROR,
4748 "ErrorCode,Unsupported TDLS value");
4749 return 0;
4750 }
4751 }
4752
4753 val = get_param(cmd, "TDLSmode");
4754 if (val) {
4755 if (strcasecmp(val, "Default") == 0) {
4756 wpa_command(intf, "SET tdls_testing 0");
4757 } else if (strcasecmp(val, "APProhibit") == 0) {
4758 if (wpa_command(intf, "SET tdls_testing 0x400")) {
4759 send_resp(dut, conn, SIGMA_ERROR,
4760 "ErrorCode,Failed to enable ignore "
4761 "APProhibit TDLS mode");
4762 return 0;
4763 }
4764 } else if (strcasecmp(val, "HiLoMac") == 0) {
4765 /* STA should respond with TDLS setup req for a TDLS
4766 * setup req */
4767 if (wpa_command(intf, "SET tdls_testing 0x80")) {
4768 send_resp(dut, conn, SIGMA_ERROR,
4769 "ErrorCode,Failed to enable HiLoMac "
4770 "TDLS mode");
4771 return 0;
4772 }
4773 } else if (strcasecmp(val, "WeakSecurity") == 0) {
4774 /*
4775 * Since all security modes are enabled by default when
4776 * Sigma control is used, there is no need to do
4777 * anything here.
4778 */
4779 } else if (strcasecmp(val, "ExistLink") == 0) {
4780 /*
4781 * Since we allow new TDLS Setup Request even if there
4782 * is an existing link, nothing needs to be done for
4783 * this.
4784 */
4785 } else {
4786 /* TODO:
4787 * ExistLink: STA should send TDLS setup req even if
4788 * direct link already exists
4789 */
4790 send_resp(dut, conn, SIGMA_ERROR,
4791 "ErrorCode,Unsupported TDLSmode value");
4792 return 0;
4793 }
4794 }
4795
4796 val = get_param(cmd, "FakePubKey");
4797 if (val && atoi(val) && wpa_command(intf, "SET wps_corrupt_pkhash 1")) {
4798 send_resp(dut, conn, SIGMA_ERROR,
4799 "ErrorCode,Failed to enable FakePubKey");
4800 return 0;
4801 }
4802
Amarnath Hullur Subramanyamae1042b2018-02-22 21:52:52 -08004803#ifdef NL80211_SUPPORT
4804 val = get_param(cmd, "FrgmntSupport");
4805 if (val) {
4806 if (strcasecmp(val, "Enable") == 0) {
4807 if (sta_set_he_fragmentation(dut, intf,
4808 HE_FRAG_LEVEL1)) {
4809 send_resp(dut, conn, SIGMA_ERROR,
4810 "ErrorCode,Failed to enable HE Fragmentation");
4811 return 0;
4812 }
4813 } else if (strcasecmp(val, "Disable") == 0) {
4814 if (sta_set_he_fragmentation(dut, intf,
4815 HE_FRAG_DISABLE)) {
4816 send_resp(dut, conn, SIGMA_ERROR,
4817 "ErrorCode,Failed to disable HE Fragmentation");
4818 return 0;
4819 }
4820 }
4821 }
4822#endif /* NL80211_SUPPORT */
4823
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004824 return 1;
4825}
4826
4827
4828static const char * ath_get_radio_name(const char *radio_name)
4829{
4830 if (radio_name == NULL)
4831 return "wifi0";
4832 if (strcmp(radio_name, "wifi1") == 0)
4833 return "wifi1";
4834 if (strcmp(radio_name, "wifi2") == 0)
4835 return "wifi2";
4836 return "wifi0";
4837}
4838
4839
4840static void ath_sta_set_txsp_stream(struct sigma_dut *dut, const char *intf,
4841 const char *val)
4842{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004843 unsigned int vht_mcsmap = 0;
4844 int txchainmask = 0;
4845 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
4846
4847 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
4848 if (dut->testbed_flag_txsp == 1) {
4849 vht_mcsmap = 0xfffc;
4850 dut->testbed_flag_txsp = 0;
4851 } else {
4852 vht_mcsmap = 0xfffe;
4853 }
4854 txchainmask = 1;
4855 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
4856 if (dut->testbed_flag_txsp == 1) {
4857 vht_mcsmap = 0xfff0;
4858 dut->testbed_flag_txsp = 0;
4859 } else {
4860 vht_mcsmap = 0xfffa;
4861 }
4862 txchainmask = 3;
4863 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
4864 if (dut->testbed_flag_txsp == 1) {
4865 vht_mcsmap = 0xffc0;
4866 dut->testbed_flag_txsp = 0;
4867 } else {
4868 vht_mcsmap = 0xffea;
4869 }
4870 txchainmask = 7;
4871 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
4872 if (dut->testbed_flag_txsp == 1) {
4873 vht_mcsmap = 0xff00;
4874 dut->testbed_flag_txsp = 0;
4875 } else {
4876 vht_mcsmap = 0xffaa;
4877 }
4878 txchainmask = 15;
4879 } else {
4880 if (dut->testbed_flag_txsp == 1) {
4881 vht_mcsmap = 0xffc0;
4882 dut->testbed_flag_txsp = 0;
4883 } else {
4884 vht_mcsmap = 0xffea;
4885 }
4886 }
4887
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004888 if (txchainmask)
4889 run_iwpriv(dut, basedev, "txchainmask %d", txchainmask);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004890
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004891 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004892}
4893
4894
4895static void ath_sta_set_rxsp_stream(struct sigma_dut *dut, const char *intf,
4896 const char *val)
4897{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004898 unsigned int vht_mcsmap = 0;
4899 int rxchainmask = 0;
4900 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
4901
4902 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
4903 if (dut->testbed_flag_rxsp == 1) {
4904 vht_mcsmap = 0xfffc;
4905 dut->testbed_flag_rxsp = 0;
4906 } else {
4907 vht_mcsmap = 0xfffe;
4908 }
4909 rxchainmask = 1;
4910 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
4911 if (dut->testbed_flag_rxsp == 1) {
4912 vht_mcsmap = 0xfff0;
4913 dut->testbed_flag_rxsp = 0;
4914 } else {
4915 vht_mcsmap = 0xfffa;
4916 }
4917 rxchainmask = 3;
4918 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
4919 if (dut->testbed_flag_rxsp == 1) {
4920 vht_mcsmap = 0xffc0;
4921 dut->testbed_flag_rxsp = 0;
4922 } else {
4923 vht_mcsmap = 0xffea;
4924 }
4925 rxchainmask = 7;
4926 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
4927 if (dut->testbed_flag_rxsp == 1) {
4928 vht_mcsmap = 0xff00;
4929 dut->testbed_flag_rxsp = 0;
4930 } else {
4931 vht_mcsmap = 0xffaa;
4932 }
4933 rxchainmask = 15;
4934 } else {
4935 if (dut->testbed_flag_rxsp == 1) {
4936 vht_mcsmap = 0xffc0;
4937 dut->testbed_flag_rxsp = 0;
4938 } else {
4939 vht_mcsmap = 0xffea;
4940 }
4941 }
4942
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004943 if (rxchainmask)
4944 run_iwpriv(dut, basedev, "rxchainmask %d", rxchainmask);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004945
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004946 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004947}
4948
4949
4950void ath_set_zero_crc(struct sigma_dut *dut, const char *val)
4951{
4952 if (strcasecmp(val, "enable") == 0) {
4953 if (system("athdiag --set --address=0x2a204 --and=0xbfffffff")
4954 != 0) {
4955 sigma_dut_print(dut, DUT_MSG_ERROR,
4956 "Disable BB_VHTSIGB_CRC_CALC failed");
4957 }
4958
4959 if (system("athdiag --set --address=0x2a204 --or=0x80000000")
4960 != 0) {
4961 sigma_dut_print(dut, DUT_MSG_ERROR,
4962 "Enable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
4963 }
4964 } else {
4965 if (system("athdiag --set --address=0x2a204 --and=0x7fffffff")
4966 != 0) {
4967 sigma_dut_print(dut, DUT_MSG_ERROR,
4968 "Disable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
4969 }
4970
4971 if (system("athdiag --set --address=0x2a204 --or=0x40000000")
4972 != 0) {
4973 sigma_dut_print(dut, DUT_MSG_ERROR,
4974 "Enable BB_VHTSIGB_CRC_CALC failed");
4975 }
4976 }
4977}
4978
4979
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08004980static int wcn_sta_set_width(struct sigma_dut *dut, const char *intf,
4981 const char *val)
4982{
4983 char buf[60];
4984
4985 if (strcmp(val, "20") == 0) {
4986 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 0", intf);
4987 dut->chwidth = 0;
4988 } else if (strcmp(val, "40") == 0) {
4989 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 1", intf);
4990 dut->chwidth = 1;
4991 } else if (strcmp(val, "80") == 0) {
4992 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 2", intf);
4993 dut->chwidth = 2;
Sunil Duttb1cccac2018-05-22 21:03:12 +05304994 } else if (strcasecmp(val, "Auto") == 0) {
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08004995 buf[0] = '\0';
4996 } else {
4997 sigma_dut_print(dut, DUT_MSG_ERROR, "WIDTH %s not supported",
4998 val);
4999 return -1;
5000 }
5001
5002 if (buf[0] != '\0' && system(buf) != 0) {
5003 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv chwidth failed");
5004 return -1;
5005 }
5006
5007 return 0;
5008}
5009
5010
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005011static int nlvendor_sta_set_addba_reject(struct sigma_dut *dut,
5012 const char *intf, int addbareject)
5013{
5014#ifdef NL80211_SUPPORT
5015 struct nl_msg *msg;
5016 int ret = 0;
5017 struct nlattr *params;
5018 int ifindex;
5019
5020 ifindex = if_nametoindex(intf);
5021 if (ifindex == 0) {
5022 sigma_dut_print(dut, DUT_MSG_ERROR,
5023 "%s: Index for interface %s failed",
5024 __func__, intf);
5025 return -1;
5026 }
5027
5028 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
5029 NL80211_CMD_VENDOR)) ||
5030 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
5031 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
5032 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
5033 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
5034 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
5035 nla_put_u8(msg,
5036 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ACCEPT_ADDBA_REQ,
5037 !addbareject)) {
5038 sigma_dut_print(dut, DUT_MSG_ERROR,
5039 "%s: err in adding vendor_cmd and vendor_data",
5040 __func__);
5041 nlmsg_free(msg);
5042 return -1;
5043 }
5044 nla_nest_end(msg, params);
5045
5046 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5047 if (ret) {
5048 sigma_dut_print(dut, DUT_MSG_ERROR,
5049 "%s: err in send_and_recv_msgs, ret=%d",
5050 __func__, ret);
5051 }
5052 return ret;
5053#else /* NL80211_SUPPORT */
5054 sigma_dut_print(dut, DUT_MSG_ERROR,
5055 "ADDBA_REJECT cannot be set without NL80211_SUPPORT defined");
5056 return -1;
5057#endif /* NL80211_SUPPORT */
5058}
5059
5060
5061static int sta_set_addba_reject(struct sigma_dut *dut, const char *intf,
5062 int addbareject)
5063{
5064 int ret;
5065
5066 switch (get_driver_type()) {
5067 case DRIVER_WCN:
5068 ret = nlvendor_sta_set_addba_reject(dut, intf, addbareject);
5069 if (ret) {
5070 sigma_dut_print(dut, DUT_MSG_ERROR,
5071 "nlvendor_sta_set_addba_reject failed, ret:%d",
5072 ret);
5073 return ret;
5074 }
5075 break;
5076 default:
5077 sigma_dut_print(dut, DUT_MSG_ERROR,
5078 "errorCode,Unsupported ADDBA_REJECT with the current driver");
5079 ret = -1;
5080 break;
5081 }
5082
5083 return ret;
5084}
5085
5086
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08005087static int nlvendor_config_send_addba(struct sigma_dut *dut, const char *intf,
5088 int enable)
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005089{
5090#ifdef NL80211_SUPPORT
5091 struct nl_msg *msg;
5092 int ret = 0;
5093 struct nlattr *params;
5094 int ifindex;
5095
5096 ifindex = if_nametoindex(intf);
5097 if (ifindex == 0) {
5098 sigma_dut_print(dut, DUT_MSG_ERROR,
5099 "%s: Index for interface %s failed",
5100 __func__, intf);
5101 return -1;
5102 }
5103
5104 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
5105 NL80211_CMD_VENDOR)) ||
5106 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
5107 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
5108 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
5109 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
5110 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
5111 nla_put_u8(msg,
5112 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_SEND_ADDBA_REQ,
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08005113 enable)) {
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005114 sigma_dut_print(dut, DUT_MSG_ERROR,
5115 "%s: err in adding vendor_cmd and vendor_data",
5116 __func__);
5117 nlmsg_free(msg);
5118 return -1;
5119 }
5120 nla_nest_end(msg, params);
5121
5122 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5123 if (ret) {
5124 sigma_dut_print(dut, DUT_MSG_ERROR,
5125 "%s: err in send_and_recv_msgs, ret=%d",
5126 __func__, ret);
5127 }
5128 return ret;
5129#else /* NL80211_SUPPORT */
5130 sigma_dut_print(dut, DUT_MSG_ERROR,
5131 "Disable addba not possible without NL80211_SUPPORT defined");
5132 return -1;
5133#endif /* NL80211_SUPPORT */
5134}
5135
5136
Veerendranath Jakkamadcd6202019-04-17 12:32:21 +05305137#ifdef NL80211_SUPPORT
5138static int nl80211_sta_set_rts(struct sigma_dut *dut, const char *intf, int val)
5139{
5140 struct nl_msg *msg;
5141 int ret = 0;
5142 int ifindex;
5143
5144 ifindex = if_nametoindex(intf);
5145 if (ifindex == 0) {
5146 sigma_dut_print(dut, DUT_MSG_ERROR,
5147 "%s: Index for interface %s failed",
5148 __func__, intf);
5149 return -1;
5150 }
5151
5152 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
5153 NL80211_CMD_SET_WIPHY)) ||
5154 nla_put_u32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD, val)) {
5155 sigma_dut_print(dut, DUT_MSG_ERROR,
5156 "%s: err in adding RTS threshold",
5157 __func__);
5158 nlmsg_free(msg);
5159 return -1;
5160 }
5161
5162 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5163 if (ret) {
5164 sigma_dut_print(dut, DUT_MSG_ERROR,
5165 "%s: err in send_and_recv_msgs, ret=%d",
5166 __func__, ret);
5167 }
5168 return ret;
5169}
5170#endif /* NL80211_SUPPORT */
5171
5172
5173static int sta_set_rts(struct sigma_dut *dut, const char *intf, int val)
5174{
5175 char buf[100];
5176
5177#ifdef NL80211_SUPPORT
5178 if (nl80211_sta_set_rts(dut, intf, val) == 0)
5179 return 0;
5180 sigma_dut_print(dut, DUT_MSG_DEBUG,
5181 "Fall back to using iwconfig for setting RTS threshold");
5182#endif /* NL80211_SUPPORT */
5183
5184 snprintf(buf, sizeof(buf), "iwconfig %s rts %d", intf, val);
5185 if (system(buf) != 0) {
5186 sigma_dut_print(dut, DUT_MSG_ERROR,
5187 "Failed to set RTS threshold %d", val);
5188 return -1;
5189 }
5190 return 0;
5191}
5192
5193
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005194static int cmd_sta_set_wireless_common(const char *intf, struct sigma_dut *dut,
5195 struct sigma_conn *conn,
5196 struct sigma_cmd *cmd)
5197{
5198 const char *val;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005199 int ampdu = -1, addbareject = -1;
Jouni Malinen3aa72862019-05-29 23:14:51 +03005200 char buf[128];
5201 int res;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005202
5203 val = get_param(cmd, "40_INTOLERANT");
5204 if (val) {
5205 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
5206 /* TODO: iwpriv ht40intol through wpa_supplicant */
5207 send_resp(dut, conn, SIGMA_ERROR,
5208 "ErrorCode,40_INTOLERANT not supported");
5209 return 0;
5210 }
5211 }
5212
5213 val = get_param(cmd, "ADDBA_REJECT");
5214 if (val) {
5215 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
5216 /* reject any ADDBA with status "decline" */
5217 ampdu = 0;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005218 addbareject = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005219 } else {
5220 /* accept ADDBA */
5221 ampdu = 1;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005222 addbareject = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005223 }
5224 }
5225
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005226 if (addbareject >= 0 &&
5227 sta_set_addba_reject(dut, intf, addbareject) < 0) {
5228 send_resp(dut, conn, SIGMA_ERROR,
5229 "ErrorCode,set addba_reject failed");
5230 return 0;
5231 }
5232
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005233 val = get_param(cmd, "AMPDU");
5234 if (val) {
5235 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
5236 /* enable AMPDU Aggregation */
5237 if (ampdu == 0) {
5238 send_resp(dut, conn, SIGMA_ERROR,
5239 "ErrorCode,Mismatch in "
5240 "addba_reject/ampdu - "
5241 "not supported");
5242 return 0;
5243 }
5244 ampdu = 1;
5245 } else {
5246 /* disable AMPDU Aggregation */
5247 if (ampdu == 1) {
5248 send_resp(dut, conn, SIGMA_ERROR,
5249 "ErrorCode,Mismatch in "
5250 "addba_reject/ampdu - "
5251 "not supported");
5252 return 0;
5253 }
5254 ampdu = 0;
5255 }
5256 }
5257
5258 if (ampdu >= 0) {
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005259 int ret;
5260
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005261 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s A-MPDU aggregation",
5262 ampdu ? "Enabling" : "Disabling");
5263 snprintf(buf, sizeof(buf), "SET ampdu %d", ampdu);
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07005264 if (wpa_command(intf, buf) < 0 &&
5265 iwpriv_sta_set_ampdu(dut, intf, ampdu) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005266 send_resp(dut, conn, SIGMA_ERROR,
5267 "ErrorCode,set aggr failed");
5268 return 0;
5269 }
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005270
5271 if (ampdu == 0) {
5272 /* Disable sending of addba using nl vendor command */
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08005273 ret = nlvendor_config_send_addba(dut, intf, 0);
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005274 if (ret) {
5275 sigma_dut_print(dut, DUT_MSG_ERROR,
5276 "Failed to disable addba, ret:%d",
5277 ret);
5278 }
5279 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005280 }
5281
5282 val = get_param(cmd, "AMSDU");
5283 if (val) {
5284 switch (get_driver_type()) {
5285 case DRIVER_ATHEROS:
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08005286 case DRIVER_WCN:
5287 iwpriv_sta_set_amsdu(dut, intf, val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005288 break;
5289 default:
5290 if (strcmp(val, "1") == 0 ||
5291 strcasecmp(val, "Enable") == 0) {
5292 /* Enable AMSDU Aggregation */
5293 send_resp(dut, conn, SIGMA_ERROR,
5294 "ErrorCode,AMSDU aggregation not supported");
5295 return 0;
5296 }
5297 break;
5298 }
5299 }
5300
5301 val = get_param(cmd, "STBC_RX");
5302 if (val) {
5303 switch (get_driver_type()) {
5304 case DRIVER_ATHEROS:
5305 ath_sta_set_stbc(dut, intf, val);
5306 break;
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05305307 case DRIVER_WCN:
5308 wcn_sta_set_stbc(dut, intf, val);
5309 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005310 default:
5311 send_resp(dut, conn, SIGMA_ERROR,
5312 "ErrorCode,STBC_RX not supported");
5313 return 0;
5314 }
5315 }
5316
5317 val = get_param(cmd, "WIDTH");
5318 if (val) {
5319 switch (get_driver_type()) {
5320 case DRIVER_WCN:
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08005321 if (wcn_sta_set_width(dut, intf, val) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005322 send_resp(dut, conn, SIGMA_ERROR,
5323 "ErrorCode,Failed to set WIDTH");
5324 return 0;
5325 }
5326 break;
5327 case DRIVER_ATHEROS:
5328 if (ath_set_width(dut, conn, intf, val) < 0)
5329 return 0;
5330 break;
5331 default:
5332 sigma_dut_print(dut, DUT_MSG_ERROR,
5333 "Setting WIDTH not supported");
5334 break;
5335 }
5336 }
5337
5338 val = get_param(cmd, "SMPS");
5339 if (val) {
5340 /* TODO: Dynamic/0, Static/1, No Limit/2 */
5341 send_resp(dut, conn, SIGMA_ERROR,
5342 "ErrorCode,SMPS not supported");
5343 return 0;
5344 }
5345
5346 val = get_param(cmd, "TXSP_STREAM");
5347 if (val) {
5348 switch (get_driver_type()) {
5349 case DRIVER_WCN:
5350 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
5351 send_resp(dut, conn, SIGMA_ERROR,
5352 "ErrorCode,Failed to set TXSP_STREAM");
5353 return 0;
5354 }
5355 break;
5356 case DRIVER_ATHEROS:
5357 ath_sta_set_txsp_stream(dut, intf, val);
5358 break;
5359 default:
5360 sigma_dut_print(dut, DUT_MSG_ERROR,
5361 "Setting TXSP_STREAM not supported");
5362 break;
5363 }
5364 }
5365
5366 val = get_param(cmd, "RXSP_STREAM");
5367 if (val) {
5368 switch (get_driver_type()) {
5369 case DRIVER_WCN:
5370 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
5371 send_resp(dut, conn, SIGMA_ERROR,
5372 "ErrorCode,Failed to set RXSP_STREAM");
5373 return 0;
5374 }
5375 break;
5376 case DRIVER_ATHEROS:
5377 ath_sta_set_rxsp_stream(dut, intf, val);
5378 break;
5379 default:
5380 sigma_dut_print(dut, DUT_MSG_ERROR,
5381 "Setting RXSP_STREAM not supported");
5382 break;
5383 }
5384 }
5385
5386 val = get_param(cmd, "DYN_BW_SGNL");
5387 if (val) {
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08005388 switch (get_driver_type()) {
5389 case DRIVER_WCN:
Peng Xuc59afd32016-11-21 15:01:11 -08005390 if (strcasecmp(val, "enable") == 0) {
5391 snprintf(buf, sizeof(buf),
5392 "iwpriv %s cwmenable 1", intf);
5393 if (system(buf) != 0) {
5394 sigma_dut_print(dut, DUT_MSG_ERROR,
5395 "iwpriv cwmenable 1 failed");
5396 return 0;
5397 }
5398 } else if (strcasecmp(val, "disable") == 0) {
5399 snprintf(buf, sizeof(buf),
5400 "iwpriv %s cwmenable 0", intf);
5401 if (system(buf) != 0) {
5402 sigma_dut_print(dut, DUT_MSG_ERROR,
5403 "iwpriv cwmenable 0 failed");
5404 return 0;
5405 }
5406 } else {
5407 sigma_dut_print(dut, DUT_MSG_ERROR,
5408 "Unsupported DYN_BW_SGL");
5409 }
5410
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005411 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 3", intf);
5412 if (system(buf) != 0) {
5413 sigma_dut_print(dut, DUT_MSG_ERROR,
5414 "Failed to set cts_cbw in DYN_BW_SGNL");
5415 return 0;
5416 }
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08005417 break;
5418 case DRIVER_ATHEROS:
priyadharshini gowthamane5e25172015-12-08 14:53:48 -08005419 novap_reset(dut, intf);
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08005420 ath_config_dyn_bw_sig(dut, intf, val);
5421 break;
5422 default:
5423 sigma_dut_print(dut, DUT_MSG_ERROR,
5424 "Failed to set DYN_BW_SGNL");
5425 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005426 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005427 }
5428
5429 val = get_param(cmd, "RTS_FORCE");
5430 if (val) {
priyadharshini gowthamane5e25172015-12-08 14:53:48 -08005431 novap_reset(dut, intf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005432 if (strcasecmp(val, "Enable") == 0) {
Veerendranath Jakkamadcd6202019-04-17 12:32:21 +05305433 if (sta_set_rts(dut, intf, 64) != 0) {
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02005434 sigma_dut_print(dut, DUT_MSG_ERROR,
5435 "Failed to set RTS_FORCE 64");
5436 }
Jouni Malinen3aa72862019-05-29 23:14:51 +03005437 res = snprintf(buf, sizeof(buf),
5438 "wifitool %s beeliner_fw_test 100 1",
5439 intf);
5440 if (res < 0 || res >= sizeof(buf) || system(buf) != 0) {
priyadharshini gowthaman270870e2015-12-09 10:10:23 -08005441 sigma_dut_print(dut, DUT_MSG_ERROR,
5442 "wifitool beeliner_fw_test 100 1 failed");
5443 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005444 } else if (strcasecmp(val, "Disable") == 0) {
Veerendranath Jakkamadcd6202019-04-17 12:32:21 +05305445 if (sta_set_rts(dut, intf, 2347) != 0) {
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02005446 sigma_dut_print(dut, DUT_MSG_ERROR,
5447 "Failed to set RTS_FORCE 2347");
5448 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005449 } else {
5450 send_resp(dut, conn, SIGMA_ERROR,
5451 "ErrorCode,RTS_FORCE value not supported");
5452 return 0;
5453 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005454 }
5455
5456 val = get_param(cmd, "CTS_WIDTH");
5457 if (val) {
5458 switch (get_driver_type()) {
5459 case DRIVER_WCN:
5460 if (wcn_sta_set_cts_width(dut, intf, val) < 0) {
5461 send_resp(dut, conn, SIGMA_ERROR,
5462 "ErrorCode,Failed to set CTS_WIDTH");
5463 return 0;
5464 }
5465 break;
5466 case DRIVER_ATHEROS:
5467 ath_set_cts_width(dut, intf, val);
5468 break;
5469 default:
5470 sigma_dut_print(dut, DUT_MSG_ERROR,
5471 "Setting CTS_WIDTH not supported");
5472 break;
5473 }
5474 }
5475
5476 val = get_param(cmd, "BW_SGNL");
5477 if (val) {
5478 if (strcasecmp(val, "Enable") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005479 run_iwpriv(dut, intf, "cwmenable 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005480 } else if (strcasecmp(val, "Disable") == 0) {
5481 /* TODO: Disable */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005482 } else {
5483 send_resp(dut, conn, SIGMA_ERROR,
5484 "ErrorCode,BW_SGNL value not supported");
5485 return 0;
5486 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005487 }
5488
5489 val = get_param(cmd, "Band");
5490 if (val) {
5491 if (strcmp(val, "2.4") == 0 || strcmp(val, "5") == 0) {
5492 /* STA supports all bands by default */
5493 } else {
5494 send_resp(dut, conn, SIGMA_ERROR,
5495 "ErrorCode,Unsupported Band");
5496 return 0;
5497 }
5498 }
5499
5500 val = get_param(cmd, "zero_crc");
5501 if (val) {
5502 switch (get_driver_type()) {
5503 case DRIVER_ATHEROS:
5504 ath_set_zero_crc(dut, val);
5505 break;
5506 default:
5507 break;
5508 }
5509 }
5510
5511 return 1;
5512}
5513
5514
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02005515static int sta_set_force_mcs(struct sigma_dut *dut, int force, int mcs)
5516{
5517 switch (get_driver_type()) {
5518#ifdef __linux__
5519 case DRIVER_WIL6210:
5520 return wil6210_set_force_mcs(dut, force, mcs);
5521#endif /* __linux__ */
5522 default:
5523 sigma_dut_print(dut, DUT_MSG_ERROR,
5524 "Unsupported sta_set_force_mcs with the current driver");
5525 return -1;
5526 }
5527}
5528
5529
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02005530static int sta_60g_force_rsn_ie(struct sigma_dut *dut, int state)
5531{
5532 switch (get_driver_type()) {
5533#ifdef __linux__
5534 case DRIVER_WIL6210:
5535 return wil6210_force_rsn_ie(dut, state);
5536#endif /* __linux__ */
5537 default:
5538 sigma_dut_print(dut, DUT_MSG_ERROR,
5539 "Unsupported sta_60g_force_rsn_ie with the current driver");
5540 return -1;
5541 }
5542}
5543
5544
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005545static int sta_set_60g_common(struct sigma_dut *dut, struct sigma_conn *conn,
5546 struct sigma_cmd *cmd)
5547{
5548 const char *val;
5549 char buf[100];
5550
5551 val = get_param(cmd, "MSDUSize");
5552 if (val) {
5553 int mtu;
5554
5555 dut->amsdu_size = atoi(val);
5556 if (dut->amsdu_size > IEEE80211_MAX_DATA_LEN_DMG ||
5557 dut->amsdu_size < IEEE80211_SNAP_LEN_DMG) {
5558 sigma_dut_print(dut, DUT_MSG_ERROR,
5559 "MSDUSize %d is above max %d or below min %d",
5560 dut->amsdu_size,
5561 IEEE80211_MAX_DATA_LEN_DMG,
5562 IEEE80211_SNAP_LEN_DMG);
5563 dut->amsdu_size = 0;
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005564 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005565 }
5566
5567 mtu = dut->amsdu_size - IEEE80211_SNAP_LEN_DMG;
5568 sigma_dut_print(dut, DUT_MSG_DEBUG,
5569 "Setting amsdu_size to %d", mtu);
5570 snprintf(buf, sizeof(buf), "ifconfig %s mtu %d",
5571 get_station_ifname(), mtu);
5572
5573 if (system(buf) != 0) {
5574 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
5575 buf);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005576 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005577 }
5578 }
5579
5580 val = get_param(cmd, "BAckRcvBuf");
5581 if (val) {
5582 dut->back_rcv_buf = atoi(val);
5583 if (dut->back_rcv_buf == 0) {
5584 sigma_dut_print(dut, DUT_MSG_ERROR,
5585 "Failed to convert %s or value is 0",
5586 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005587 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005588 }
5589
5590 sigma_dut_print(dut, DUT_MSG_DEBUG,
5591 "Setting BAckRcvBuf to %s", val);
5592 }
5593
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02005594 val = get_param(cmd, "MCS_FixedRate");
5595 if (val) {
5596 if (sta_set_force_mcs(dut, 1, atoi(val))) {
5597 sigma_dut_print(dut, DUT_MSG_ERROR,
5598 "Failed to force MCS");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005599 return ERROR_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02005600 }
5601 }
5602
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005603 return SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005604}
5605
5606
5607static int sta_pcp_start(struct sigma_dut *dut, struct sigma_conn *conn,
5608 struct sigma_cmd *cmd)
5609{
5610 int net_id;
5611 char *ifname;
5612 const char *val;
5613 char buf[100];
5614
5615 dut->mode = SIGMA_MODE_STATION;
5616 ifname = get_main_ifname();
5617 if (wpa_command(ifname, "PING") != 0) {
5618 sigma_dut_print(dut, DUT_MSG_ERROR, "Supplicant not running");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005619 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005620 }
5621
5622 wpa_command(ifname, "FLUSH");
5623 net_id = add_network_common(dut, conn, ifname, cmd);
5624 if (net_id < 0) {
5625 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add network");
5626 return net_id;
5627 }
5628
5629 /* TODO: mode=2 for the AP; in the future, replace for mode PCP */
5630 if (set_network(ifname, net_id, "mode", "2") < 0) {
5631 sigma_dut_print(dut, DUT_MSG_ERROR,
5632 "Failed to set supplicant network mode");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005633 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005634 }
5635
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02005636 if (set_network(ifname, net_id, "pbss", "1") < 0)
5637 return -2;
5638
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005639 sigma_dut_print(dut, DUT_MSG_DEBUG,
Alexei Avshalom Lazarfd9f1352018-11-13 14:07:58 +02005640 "Supplicant set network with mode 2. network_id %d",
5641 net_id);
5642
5643 if (set_network(ifname, net_id, "wps_disabled", "0") < 0) {
5644 sigma_dut_print(dut, DUT_MSG_INFO,
5645 "Failed to set supplicant to WPS ENABLE");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005646 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarfd9f1352018-11-13 14:07:58 +02005647 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005648
5649 val = get_param(cmd, "Security");
5650 if (val && strcasecmp(val, "OPEN") == 0) {
5651 dut->ap_key_mgmt = AP_OPEN;
5652 if (set_network(ifname, net_id, "key_mgmt", "NONE") < 0) {
5653 sigma_dut_print(dut, DUT_MSG_ERROR,
5654 "Failed to set supplicant to %s security",
5655 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005656 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005657 }
5658 } else if (val && strcasecmp(val, "WPA2-PSK") == 0) {
5659 dut->ap_key_mgmt = AP_WPA2_PSK;
5660 if (set_network(ifname, net_id, "key_mgmt", "WPA-PSK") < 0) {
5661 sigma_dut_print(dut, DUT_MSG_ERROR,
5662 "Failed to set supplicant to %s security",
5663 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005664 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005665 }
5666
5667 if (set_network(ifname, net_id, "proto", "RSN") < 0) {
5668 sigma_dut_print(dut, DUT_MSG_ERROR,
5669 "Failed to set supplicant to proto RSN");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005670 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005671 }
5672 } else if (val) {
5673 sigma_dut_print(dut, DUT_MSG_ERROR,
5674 "Requested Security %s is not supported on 60GHz",
5675 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005676 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005677 }
5678
5679 val = get_param(cmd, "Encrypt");
5680 if (val && strcasecmp(val, "AES-GCMP") == 0) {
5681 if (set_network(ifname, net_id, "pairwise", "GCMP") < 0) {
5682 sigma_dut_print(dut, DUT_MSG_ERROR,
5683 "Failed to set supplicant to pairwise GCMP");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005684 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005685 }
5686 if (set_network(ifname, net_id, "group", "GCMP") < 0) {
5687 sigma_dut_print(dut, DUT_MSG_ERROR,
5688 "Failed to set supplicant to group GCMP");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005689 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005690 }
5691 } else if (val) {
5692 sigma_dut_print(dut, DUT_MSG_ERROR,
5693 "Requested Encrypt %s is not supported on 60 GHz",
5694 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005695 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005696 }
5697
5698 val = get_param(cmd, "PSK");
5699 if (val && set_network_quoted(ifname, net_id, "psk", val) < 0) {
5700 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set psk %s",
5701 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005702 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005703 }
5704
5705 /* Convert 60G channel to freq */
5706 switch (dut->ap_channel) {
5707 case 1:
5708 val = "58320";
5709 break;
5710 case 2:
5711 val = "60480";
5712 break;
5713 case 3:
5714 val = "62640";
5715 break;
5716 default:
5717 sigma_dut_print(dut, DUT_MSG_ERROR,
5718 "Failed to configure channel %d. Not supported",
5719 dut->ap_channel);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005720 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005721 }
5722
5723 if (set_network(ifname, net_id, "frequency", val) < 0) {
5724 sigma_dut_print(dut, DUT_MSG_ERROR,
5725 "Failed to set supplicant network frequency");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005726 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005727 }
5728
Alexei Avshalom Lazar2eccf4d2019-01-31 10:03:59 +02005729 if (dut->eap_fragment) {
5730 sigma_dut_print(dut, DUT_MSG_DEBUG,
5731 "Set EAP fragment size to 128 bytes.");
5732 if (set_network(ifname, net_id, "fragment_size", "128") < 0)
5733 return ERROR_SEND_STATUS;
5734 }
5735
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005736 sigma_dut_print(dut, DUT_MSG_DEBUG,
5737 "Supplicant set network with frequency");
5738
5739 snprintf(buf, sizeof(buf), "SELECT_NETWORK %d", net_id);
5740 if (wpa_command(ifname, buf) < 0) {
5741 sigma_dut_print(dut, DUT_MSG_INFO,
5742 "Failed to select network id %d on %s",
5743 net_id, ifname);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005744 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005745 }
5746
5747 sigma_dut_print(dut, DUT_MSG_DEBUG, "Selected network");
5748
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005749 return SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005750}
5751
5752
Lior David67543f52017-01-03 19:04:22 +02005753static int wil6210_set_abft_len(struct sigma_dut *dut, int abft_len)
5754{
5755 char buf[128], fname[128];
5756 FILE *f;
Jouni Malinen3aa72862019-05-29 23:14:51 +03005757 int res;
Lior David67543f52017-01-03 19:04:22 +02005758
5759 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
5760 sigma_dut_print(dut, DUT_MSG_ERROR,
5761 "failed to get wil6210 debugfs dir");
5762 return -1;
5763 }
5764
Jouni Malinen3aa72862019-05-29 23:14:51 +03005765 res = snprintf(fname, sizeof(fname), "%s/abft_len", buf);
5766 if (res < 0 || res >= sizeof(fname))
5767 return -1;
Lior David67543f52017-01-03 19:04:22 +02005768 f = fopen(fname, "w");
5769 if (!f) {
5770 sigma_dut_print(dut, DUT_MSG_ERROR,
5771 "failed to open: %s", fname);
5772 return -1;
5773 }
5774
5775 fprintf(f, "%d\n", abft_len);
5776 fclose(f);
5777
5778 return 0;
5779}
5780
5781
Alexei Avshalom Lazar49498b82019-01-31 15:16:32 +02005782int sta_set_60g_abft_len(struct sigma_dut *dut, struct sigma_conn *conn,
5783 int abft_len)
Lior David67543f52017-01-03 19:04:22 +02005784{
5785 switch (get_driver_type()) {
5786 case DRIVER_WIL6210:
5787 return wil6210_set_abft_len(dut, abft_len);
5788 default:
5789 sigma_dut_print(dut, DUT_MSG_ERROR,
5790 "set abft_len not supported");
5791 return -1;
5792 }
5793}
5794
5795
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005796static int sta_set_60g_pcp(struct sigma_dut *dut, struct sigma_conn *conn,
5797 struct sigma_cmd *cmd)
5798{
5799 const char *val;
Lior David67543f52017-01-03 19:04:22 +02005800 unsigned int abft_len = 1; /* default is one slot */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005801
5802 if (dut->dev_role != DEVROLE_PCP) {
5803 send_resp(dut, conn, SIGMA_INVALID,
5804 "ErrorCode,Invalid DevRole");
5805 return 0;
5806 }
5807
5808 val = get_param(cmd, "SSID");
5809 if (val) {
5810 if (strlen(val) > sizeof(dut->ap_ssid) - 1) {
5811 send_resp(dut, conn, SIGMA_INVALID,
5812 "ErrorCode,Invalid SSID");
5813 return -1;
5814 }
5815
Peng Xub8fc5cc2017-05-10 17:27:28 -07005816 strlcpy(dut->ap_ssid, val, sizeof(dut->ap_ssid));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005817 }
5818
5819 val = get_param(cmd, "CHANNEL");
5820 if (val) {
5821 const char *pos;
5822
5823 dut->ap_channel = atoi(val);
5824 pos = strchr(val, ';');
5825 if (pos) {
5826 pos++;
5827 dut->ap_channel_1 = atoi(pos);
5828 }
5829 }
5830
5831 switch (dut->ap_channel) {
5832 case 1:
5833 case 2:
5834 case 3:
5835 break;
5836 default:
5837 sigma_dut_print(dut, DUT_MSG_ERROR,
5838 "Channel %d is not supported", dut->ap_channel);
5839 send_resp(dut, conn, SIGMA_ERROR,
5840 "Requested channel is not supported");
5841 return -1;
5842 }
5843
5844 val = get_param(cmd, "BCNINT");
5845 if (val)
5846 dut->ap_bcnint = atoi(val);
5847
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005848 val = get_param(cmd, "AllocType");
5849 if (val) {
5850 send_resp(dut, conn, SIGMA_ERROR,
5851 "ErrorCode,AllocType is not supported yet");
5852 return -1;
5853 }
5854
5855 val = get_param(cmd, "PercentBI");
5856 if (val) {
5857 send_resp(dut, conn, SIGMA_ERROR,
5858 "ErrorCode,PercentBI is not supported yet");
5859 return -1;
5860 }
5861
5862 val = get_param(cmd, "CBAPOnly");
5863 if (val) {
5864 send_resp(dut, conn, SIGMA_ERROR,
5865 "ErrorCode,CBAPOnly is not supported yet");
5866 return -1;
5867 }
5868
5869 val = get_param(cmd, "AMPDU");
5870 if (val) {
5871 if (strcasecmp(val, "Enable") == 0)
5872 dut->ap_ampdu = 1;
5873 else if (strcasecmp(val, "Disable") == 0)
5874 dut->ap_ampdu = 2;
5875 else {
5876 send_resp(dut, conn, SIGMA_ERROR,
5877 "ErrorCode,AMPDU value is not Enable nor Disabled");
5878 return -1;
5879 }
5880 }
5881
5882 val = get_param(cmd, "AMSDU");
5883 if (val) {
5884 if (strcasecmp(val, "Enable") == 0)
5885 dut->ap_amsdu = 1;
5886 else if (strcasecmp(val, "Disable") == 0)
5887 dut->ap_amsdu = 2;
5888 }
5889
5890 val = get_param(cmd, "NumMSDU");
5891 if (val) {
5892 send_resp(dut, conn, SIGMA_ERROR,
5893 "ErrorCode, NumMSDU is not supported yet");
5894 return -1;
5895 }
5896
5897 val = get_param(cmd, "ABFTLRang");
5898 if (val) {
5899 sigma_dut_print(dut, DUT_MSG_DEBUG,
Lior David67543f52017-01-03 19:04:22 +02005900 "ABFTLRang parameter %s", val);
5901 if (strcmp(val, "Gt1") == 0)
5902 abft_len = 2; /* 2 slots in this case */
5903 }
5904
5905 if (sta_set_60g_abft_len(dut, conn, abft_len)) {
5906 send_resp(dut, conn, SIGMA_ERROR,
5907 "ErrorCode, Can't set ABFT length");
5908 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005909 }
5910
5911 if (sta_pcp_start(dut, conn, cmd) < 0) {
5912 send_resp(dut, conn, SIGMA_ERROR,
5913 "ErrorCode, Can't start PCP role");
5914 return -1;
5915 }
5916
5917 return sta_set_60g_common(dut, conn, cmd);
5918}
5919
5920
5921static int sta_set_60g_sta(struct sigma_dut *dut, struct sigma_conn *conn,
5922 struct sigma_cmd *cmd)
5923{
5924 const char *val = get_param(cmd, "DiscoveryMode");
5925
5926 if (dut->dev_role != DEVROLE_STA) {
5927 send_resp(dut, conn, SIGMA_INVALID,
5928 "ErrorCode,Invalid DevRole");
5929 return 0;
5930 }
5931
5932 if (val) {
5933 sigma_dut_print(dut, DUT_MSG_DEBUG, "Discovery: %s", val);
5934 /* Ignore Discovery mode till Driver expose API. */
5935#if 0
5936 if (strcasecmp(val, "1") == 0) {
5937 send_resp(dut, conn, SIGMA_INVALID,
5938 "ErrorCode,DiscoveryMode 1 not supported");
5939 return 0;
5940 }
5941
5942 if (strcasecmp(val, "0") == 0) {
5943 /* OK */
5944 } else {
5945 send_resp(dut, conn, SIGMA_INVALID,
5946 "ErrorCode,DiscoveryMode not supported");
5947 return 0;
5948 }
5949#endif
5950 }
5951
5952 if (start_sta_mode(dut) != 0)
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005953 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005954 return sta_set_60g_common(dut, conn, cmd);
5955}
5956
5957
5958static int cmd_sta_disconnect(struct sigma_dut *dut, struct sigma_conn *conn,
5959 struct sigma_cmd *cmd)
5960{
5961 const char *intf = get_param(cmd, "Interface");
Jouni Malinened77e672018-01-10 16:45:13 +02005962 const char *val = get_param(cmd, "maintain_profile");
vamsi krishnad605c422017-09-20 14:56:31 +05305963
Jouni Malinened77e672018-01-10 16:45:13 +02005964 if (dut->program == PROGRAM_OCE ||
Amarnath Hullur Subramanyamebeda9e2018-01-31 03:21:48 -08005965 dut->program == PROGRAM_HE ||
Jouni Malinened77e672018-01-10 16:45:13 +02005966 (val && atoi(val) == 1)) {
vamsi krishnad605c422017-09-20 14:56:31 +05305967 wpa_command(intf, "DISCONNECT");
5968 return 1;
5969 }
5970
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005971 disconnect_station(dut);
5972 /* Try to ignore old scan results to avoid HS 2.0R2 test case failures
5973 * due to cached results. */
5974 wpa_command(intf, "SET ignore_old_scan_res 1");
5975 wpa_command(intf, "BSS_FLUSH");
5976 return 1;
5977}
5978
5979
5980static int cmd_sta_reassoc(struct sigma_dut *dut, struct sigma_conn *conn,
5981 struct sigma_cmd *cmd)
5982{
5983 const char *intf = get_param(cmd, "Interface");
5984 const char *bssid = get_param(cmd, "bssid");
5985 const char *val = get_param(cmd, "CHANNEL");
5986 struct wpa_ctrl *ctrl;
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05305987 char buf[1000];
Sunil Duttd30ce092018-01-11 23:56:29 +05305988 char result[32];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005989 int res;
5990 int chan = 0;
Ashwini Patil467efef2017-05-25 12:18:27 +05305991 int status = 0;
Sunil Duttd30ce092018-01-11 23:56:29 +05305992 int fastreassoc = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005993
5994 if (bssid == NULL) {
5995 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing bssid "
5996 "argument");
5997 return 0;
5998 }
5999
6000 if (val)
6001 chan = atoi(val);
6002
6003 if (wifi_chip_type != DRIVER_WCN && wifi_chip_type != DRIVER_AR6003) {
6004 /* The current network may be from sta_associate or
6005 * sta_hs2_associate
6006 */
6007 if (set_network(intf, dut->infra_network_id, "bssid", bssid) <
6008 0 ||
6009 set_network(intf, 0, "bssid", bssid) < 0)
6010 return -2;
6011 }
6012
6013 ctrl = open_wpa_mon(intf);
6014 if (ctrl == NULL) {
6015 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
6016 "wpa_supplicant monitor connection");
6017 return -1;
6018 }
6019
Sunil Duttd30ce092018-01-11 23:56:29 +05306020 if (get_wpa_status(get_station_ifname(), "wpa_state", result,
6021 sizeof(result)) < 0 ||
6022 strncmp(result, "COMPLETED", 9) != 0) {
6023 sigma_dut_print(dut, DUT_MSG_DEBUG,
6024 "sta_reassoc: Not connected");
6025 fastreassoc = 0;
6026 }
6027
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05306028 if (dut->rsne_override) {
6029#ifdef NL80211_SUPPORT
6030 if (get_driver_type() == DRIVER_WCN && dut->config_rsnie == 0) {
6031 sta_config_rsnie(dut, 1);
6032 dut->config_rsnie = 1;
6033 }
6034#endif /* NL80211_SUPPORT */
6035 snprintf(buf, sizeof(buf), "TEST_ASSOC_IE %s",
6036 dut->rsne_override);
6037 if (wpa_command(intf, buf) < 0) {
6038 send_resp(dut, conn, SIGMA_ERROR,
6039 "ErrorCode,Failed to set DEV_CONFIGURE_IE RSNE override");
6040 return 0;
6041 }
6042 }
6043
Sunil Duttd30ce092018-01-11 23:56:29 +05306044 if (wifi_chip_type == DRIVER_WCN && fastreassoc) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006045#ifdef ANDROID
Ashwini Patil4c8158f2017-05-25 12:49:21 +05306046 if (chan) {
6047 unsigned int freq;
6048
Alexei Avshalom Lazar093569f2018-11-13 14:08:17 +02006049 freq = channel_to_freq(dut, chan);
Ashwini Patil4c8158f2017-05-25 12:49:21 +05306050 if (!freq) {
6051 sigma_dut_print(dut, DUT_MSG_ERROR,
6052 "Invalid channel number provided: %d",
6053 chan);
6054 send_resp(dut, conn, SIGMA_INVALID,
6055 "ErrorCode,Invalid channel number");
6056 goto close_mon_conn;
6057 }
6058 res = snprintf(buf, sizeof(buf),
6059 "SCAN TYPE=ONLY freq=%d", freq);
6060 } else {
6061 res = snprintf(buf, sizeof(buf), "SCAN TYPE=ONLY");
6062 }
6063 if (res < 0 || res >= (int) sizeof(buf)) {
6064 send_resp(dut, conn, SIGMA_ERROR,
6065 "ErrorCode,snprintf failed");
6066 goto close_mon_conn;
6067 }
6068 if (wpa_command(intf, buf) < 0) {
6069 sigma_dut_print(dut, DUT_MSG_INFO,
6070 "Failed to start scan");
6071 send_resp(dut, conn, SIGMA_ERROR,
6072 "ErrorCode,scan failed");
6073 goto close_mon_conn;
6074 }
6075
6076 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
6077 buf, sizeof(buf));
6078 if (res < 0) {
6079 sigma_dut_print(dut, DUT_MSG_INFO,
6080 "Scan did not complete");
6081 send_resp(dut, conn, SIGMA_ERROR,
6082 "ErrorCode,scan did not complete");
6083 goto close_mon_conn;
6084 }
6085
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006086 if (set_network(intf, dut->infra_network_id, "bssid", "any")
6087 < 0) {
6088 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
6089 "bssid to any during FASTREASSOC");
Ashwini Patil467efef2017-05-25 12:18:27 +05306090 status = -2;
6091 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006092 }
6093 res = snprintf(buf, sizeof(buf), "DRIVER FASTREASSOC %s %d",
6094 bssid, chan);
6095 if (res > 0 && res < (int) sizeof(buf))
6096 res = wpa_command(intf, buf);
6097
6098 if (res < 0 || res >= (int) sizeof(buf)) {
6099 send_resp(dut, conn, SIGMA_ERROR,
6100 "errorCode,Failed to run DRIVER FASTREASSOC");
Ashwini Patil467efef2017-05-25 12:18:27 +05306101 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006102 }
6103#else /* ANDROID */
6104 sigma_dut_print(dut, DUT_MSG_DEBUG,
6105 "Reassoc using iwpriv - skip chan=%d info",
6106 chan);
6107 snprintf(buf, sizeof(buf), "iwpriv %s reassoc", intf);
6108 if (system(buf) != 0) {
6109 sigma_dut_print(dut, DUT_MSG_ERROR, "%s failed", buf);
Ashwini Patil467efef2017-05-25 12:18:27 +05306110 status = -2;
6111 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006112 }
6113#endif /* ANDROID */
6114 sigma_dut_print(dut, DUT_MSG_INFO,
6115 "sta_reassoc: Run %s successful", buf);
6116 } else if (wpa_command(intf, "REASSOCIATE")) {
6117 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
6118 "request reassociation");
Ashwini Patil467efef2017-05-25 12:18:27 +05306119 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006120 }
6121
6122 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
6123 buf, sizeof(buf));
Ashwini Patil467efef2017-05-25 12:18:27 +05306124 if (res < 0) {
6125 sigma_dut_print(dut, DUT_MSG_INFO, "Connection did not complete");
6126 status = -1;
6127 goto close_mon_conn;
6128 }
6129 status = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006130
Ashwini Patil467efef2017-05-25 12:18:27 +05306131close_mon_conn:
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006132 wpa_ctrl_detach(ctrl);
6133 wpa_ctrl_close(ctrl);
Ashwini Patil467efef2017-05-25 12:18:27 +05306134 return status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006135}
6136
6137
6138static void hs2_clear_credentials(const char *intf)
6139{
6140 wpa_command(intf, "REMOVE_CRED all");
6141}
6142
6143
Lior Davidcc88b562017-01-03 18:52:09 +02006144#ifdef __linux__
6145static int wil6210_get_aid(struct sigma_dut *dut, const char *bssid,
6146 unsigned int *aid)
6147{
Lior David0fe101e2017-03-09 16:09:50 +02006148 const char *pattern = "AID[ \t]+([0-9]+)";
Lior Davidcc88b562017-01-03 18:52:09 +02006149
Lior David0fe101e2017-03-09 16:09:50 +02006150 return wil6210_get_sta_info_field(dut, bssid, pattern, aid);
Lior Davidcc88b562017-01-03 18:52:09 +02006151}
6152#endif /* __linux__ */
6153
6154
6155static int sta_get_aid_60g(struct sigma_dut *dut, const char *bssid,
6156 unsigned int *aid)
6157{
6158 switch (get_driver_type()) {
6159#ifdef __linux__
6160 case DRIVER_WIL6210:
6161 return wil6210_get_aid(dut, bssid, aid);
6162#endif /* __linux__ */
6163 default:
6164 sigma_dut_print(dut, DUT_MSG_ERROR, "get AID not supported");
6165 return -1;
6166 }
6167}
6168
6169
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006170static int sta_get_parameter_60g(struct sigma_dut *dut, struct sigma_conn *conn,
6171 struct sigma_cmd *cmd)
6172{
6173 char buf[MAX_CMD_LEN];
6174 char bss_list[MAX_CMD_LEN];
6175 const char *parameter = get_param(cmd, "Parameter");
6176
6177 if (parameter == NULL)
6178 return -1;
6179
Lior Davidcc88b562017-01-03 18:52:09 +02006180 if (strcasecmp(parameter, "AID") == 0) {
6181 unsigned int aid = 0;
6182 char bssid[20];
6183
6184 if (get_wpa_status(get_station_ifname(), "bssid",
6185 bssid, sizeof(bssid)) < 0) {
6186 sigma_dut_print(dut, DUT_MSG_ERROR,
6187 "could not get bssid");
6188 return -2;
6189 }
6190
6191 if (sta_get_aid_60g(dut, bssid, &aid))
6192 return -2;
6193
6194 snprintf(buf, sizeof(buf), "aid,%d", aid);
6195 sigma_dut_print(dut, DUT_MSG_INFO, "%s", buf);
6196 send_resp(dut, conn, SIGMA_COMPLETE, buf);
6197 return 0;
6198 }
6199
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006200 if (strcasecmp(parameter, "DiscoveredDevList") == 0) {
6201 char *bss_line;
6202 char *bss_id = NULL;
6203 const char *ifname = get_param(cmd, "Interface");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05306204 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006205
6206 if (ifname == NULL) {
6207 sigma_dut_print(dut, DUT_MSG_INFO,
6208 "For get DiscoveredDevList need Interface name.");
6209 return -1;
6210 }
6211
6212 /*
6213 * Use "BSS RANGE=ALL MASK=0x2" which provides a list
6214 * of BSSIDs in "bssid=<BSSID>\n"
6215 */
6216 if (wpa_command_resp(ifname, "BSS RANGE=ALL MASK=0x2",
6217 bss_list,
6218 sizeof(bss_list)) < 0) {
6219 sigma_dut_print(dut, DUT_MSG_ERROR,
6220 "Failed to get bss list");
6221 return -1;
6222 }
6223
6224 sigma_dut_print(dut, DUT_MSG_DEBUG,
6225 "bss list for ifname:%s is:%s",
6226 ifname, bss_list);
6227
6228 snprintf(buf, sizeof(buf), "DeviceList");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05306229 bss_line = strtok_r(bss_list, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006230 while (bss_line) {
6231 if (sscanf(bss_line, "bssid=%ms", &bss_id) > 0 &&
6232 bss_id) {
6233 int len;
6234
6235 len = snprintf(buf + strlen(buf),
6236 sizeof(buf) - strlen(buf),
6237 ",%s", bss_id);
6238 free(bss_id);
6239 bss_id = NULL;
6240 if (len < 0) {
6241 sigma_dut_print(dut,
6242 DUT_MSG_ERROR,
6243 "Failed to read BSSID");
6244 send_resp(dut, conn, SIGMA_ERROR,
6245 "ErrorCode,Failed to read BSS ID");
6246 return 0;
6247 }
6248
6249 if ((size_t) len >= sizeof(buf) - strlen(buf)) {
6250 sigma_dut_print(dut,
6251 DUT_MSG_ERROR,
6252 "Response buf too small for list");
6253 send_resp(dut, conn,
6254 SIGMA_ERROR,
6255 "ErrorCode,Response buf too small for list");
6256 return 0;
6257 }
6258 }
6259
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05306260 bss_line = strtok_r(NULL, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006261 }
6262
6263 sigma_dut_print(dut, DUT_MSG_INFO, "DiscoveredDevList is %s",
6264 buf);
6265 send_resp(dut, conn, SIGMA_COMPLETE, buf);
6266 return 0;
6267 }
6268
6269 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
6270 return 0;
6271}
6272
6273
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07006274static int sta_get_parameter_he(struct sigma_dut *dut, struct sigma_conn *conn,
6275 struct sigma_cmd *cmd)
6276{
6277 char buf[MAX_CMD_LEN];
6278 const char *parameter = get_param(cmd, "Parameter");
6279
6280 if (!parameter)
6281 return -1;
6282
6283 if (strcasecmp(parameter, "RSSI") == 0) {
6284 char rssi[10];
6285
6286 if (get_wpa_signal_poll(dut, get_station_ifname(), "RSSI",
6287 rssi, sizeof(rssi)) < 0) {
6288 sigma_dut_print(dut, DUT_MSG_ERROR,
6289 "Could not get RSSI");
6290 return -2;
6291 }
6292
6293 snprintf(buf, sizeof(buf), "rssi,%s", rssi);
6294 sigma_dut_print(dut, DUT_MSG_INFO, "RSSI %s", buf);
6295 send_resp(dut, conn, SIGMA_COMPLETE, buf);
6296 return 0;
6297 }
6298
6299 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
6300 return 0;
6301}
6302
6303
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006304static int cmd_sta_get_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
6305 struct sigma_cmd *cmd)
6306{
6307 const char *program = get_param(cmd, "Program");
6308
6309 if (program == NULL)
6310 return -1;
6311
6312 if (strcasecmp(program, "P2PNFC") == 0)
6313 return p2p_cmd_sta_get_parameter(dut, conn, cmd);
6314
6315 if (strcasecmp(program, "60ghz") == 0)
6316 return sta_get_parameter_60g(dut, conn, cmd);
6317
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07006318 if (strcasecmp(program, "he") == 0)
6319 return sta_get_parameter_he(dut, conn, cmd);
6320
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006321#ifdef ANDROID_NAN
6322 if (strcasecmp(program, "NAN") == 0)
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07006323 return nan_cmd_sta_get_parameter(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006324#endif /* ANDROID_NAN */
6325
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07006326#ifdef MIRACAST
6327 if (strcasecmp(program, "WFD") == 0 ||
6328 strcasecmp(program, "DisplayR2") == 0)
6329 return miracast_cmd_sta_get_parameter(dut, conn, cmd);
6330#endif /* MIRACAST */
6331
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006332 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
6333 return 0;
6334}
6335
6336
6337static void sta_reset_default_ath(struct sigma_dut *dut, const char *intf,
6338 const char *type)
6339{
6340 char buf[100];
6341
6342 if (dut->program == PROGRAM_VHT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006343 run_iwpriv(dut, intf, "chwidth 2");
6344 run_iwpriv(dut, intf, "mode 11ACVHT80");
6345 run_iwpriv(dut, intf, "vhtmcs -1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006346 }
6347
6348 if (dut->program == PROGRAM_HT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006349 run_iwpriv(dut, intf, "chwidth 0");
6350 run_iwpriv(dut, intf, "mode 11naht40");
6351 run_iwpriv(dut, intf, "set11NRates 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006352 }
6353
6354 if (dut->program == PROGRAM_VHT || dut->program == PROGRAM_HT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006355 run_iwpriv(dut, intf, "powersave 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006356
6357 /* Reset CTS width */
6358 snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 54 0",
6359 intf);
6360 if (system(buf) != 0) {
6361 sigma_dut_print(dut, DUT_MSG_ERROR,
6362 "wifitool %s beeliner_fw_test 54 0 failed",
6363 intf);
6364 }
6365
6366 /* Enable Dynamic Bandwidth signalling by default */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006367 run_iwpriv(dut, intf, "cwmenable 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006368
6369 snprintf(buf, sizeof(buf), "iwconfig %s rts 2347", intf);
6370 if (system(buf) != 0) {
6371 sigma_dut_print(dut, DUT_MSG_ERROR,
6372 "iwpriv rts failed");
6373 }
6374 }
6375
6376 if (type && strcasecmp(type, "Testbed") == 0) {
6377 dut->testbed_flag_txsp = 1;
6378 dut->testbed_flag_rxsp = 1;
6379 /* STA has to set spatial stream to 2 per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006380 run_iwpriv(dut, intf, "vht_mcsmap 0xfff0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006381
6382 /* Disable LDPC per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006383 run_iwpriv(dut, intf, "ldpc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006384
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006385 run_iwpriv(dut, intf, "amsdu 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006386
6387 /* TODO: Disable STBC 2x1 transmit and receive */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006388 run_iwpriv(dut, intf, "tx_stbc 0");
6389 run_iwpriv(dut, intf, "rx_stbc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006390
6391 /* STA has to disable Short GI per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006392 run_iwpriv(dut, intf, "shortgi 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006393 }
6394
6395 if (type && strcasecmp(type, "DUT") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006396 run_iwpriv(dut, intf, "nss 3");
Arif Hussainac6c5112018-05-25 17:34:00 -07006397 dut->sta_nss = 3;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006398
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006399 run_iwpriv(dut, intf, "shortgi 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006400 }
6401}
6402
6403
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08006404#ifdef NL80211_SUPPORT
6405static int sta_set_he_mcs(struct sigma_dut *dut, const char *intf,
6406 enum he_mcs_config mcs)
6407{
6408 struct nl_msg *msg;
6409 int ret = 0;
6410 struct nlattr *params;
6411 int ifindex;
6412
6413 ifindex = if_nametoindex(intf);
6414 if (ifindex == 0) {
6415 sigma_dut_print(dut, DUT_MSG_ERROR,
6416 "%s: Index for interface %s failed",
6417 __func__, intf);
6418 return -1;
6419 }
6420
6421 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6422 NL80211_CMD_VENDOR)) ||
6423 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6424 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6425 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6426 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6427 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6428 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MCS,
6429 mcs)) {
6430 sigma_dut_print(dut, DUT_MSG_ERROR,
6431 "%s: err in adding vendor_cmd and vendor_data",
6432 __func__);
6433 nlmsg_free(msg);
6434 return -1;
6435 }
6436 nla_nest_end(msg, params);
6437
6438 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6439 if (ret) {
6440 sigma_dut_print(dut, DUT_MSG_ERROR,
6441 "%s: err in send_and_recv_msgs, ret=%d",
6442 __func__, ret);
6443 }
6444 return ret;
6445}
6446#endif /* NL80211_SUPPORT */
6447
6448
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07006449static int sta_set_action_tx_in_he_tb_ppdu(struct sigma_dut *dut,
6450 const char *intf, int enable)
6451{
6452#ifdef NL80211_SUPPORT
6453 struct nl_msg *msg;
6454 int ret = 0;
6455 struct nlattr *params;
6456 int ifindex;
6457
6458 ifindex = if_nametoindex(intf);
6459 if (ifindex == 0) {
6460 sigma_dut_print(dut, DUT_MSG_ERROR,
6461 "%s: Index for interface %s failed",
6462 __func__, intf);
6463 return -1;
6464 }
6465
6466 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6467 NL80211_CMD_VENDOR)) ||
6468 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6469 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6470 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6471 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6472 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6473 nla_put_u8(msg,
6474 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_ACTION_TX_TB_PPDU,
6475 enable)) {
6476 sigma_dut_print(dut, DUT_MSG_ERROR,
6477 "%s: err in adding vendor_cmd and vendor_data",
6478 __func__);
6479 nlmsg_free(msg);
6480 return -1;
6481 }
6482 nla_nest_end(msg, params);
6483
6484 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6485 if (ret) {
6486 sigma_dut_print(dut, DUT_MSG_ERROR,
6487 "%s: err in send_and_recv_msgs, ret=%d",
6488 __func__, ret);
6489 }
6490 return ret;
6491#else /* NL80211_SUPPORT */
6492 sigma_dut_print(dut, DUT_MSG_ERROR,
6493 "HE action Tx TB PPDU cannot be set without NL80211_SUPPORT defined");
6494 return -1;
6495#endif /* NL80211_SUPPORT */
6496}
6497
6498
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08006499static int sta_set_heconfig_and_wep_tkip(struct sigma_dut *dut,
6500 const char *intf, int enable)
6501{
6502#ifdef NL80211_SUPPORT
6503 struct nl_msg *msg;
6504 int ret = 0;
6505 struct nlattr *params;
6506 int ifindex;
6507
6508 ifindex = if_nametoindex(intf);
6509 if (ifindex == 0) {
6510 sigma_dut_print(dut, DUT_MSG_ERROR,
6511 "%s: Index for interface %s failed",
6512 __func__, intf);
6513 return -1;
6514 }
6515
6516 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6517 NL80211_CMD_VENDOR)) ||
6518 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6519 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6520 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6521 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6522 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6523 nla_put_u8(msg,
6524 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WEP_TKIP_IN_HE,
6525 enable)) {
6526 sigma_dut_print(dut, DUT_MSG_ERROR,
6527 "%s: err in adding vendor_cmd and vendor_data",
6528 __func__);
6529 nlmsg_free(msg);
6530 return -1;
6531 }
6532 nla_nest_end(msg, params);
6533
6534 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6535 if (ret) {
6536 sigma_dut_print(dut, DUT_MSG_ERROR,
6537 "%s: err in send_and_recv_msgs, ret=%d",
6538 __func__, ret);
6539 }
6540 return ret;
6541#else /* NL80211_SUPPORT */
6542 sigma_dut_print(dut, DUT_MSG_ERROR,
6543 "HE config enablement cannot be changed without NL80211_SUPPORT defined");
6544 return -1;
6545#endif /* NL80211_SUPPORT */
6546}
6547
6548
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08006549#ifdef NL80211_SUPPORT
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08006550
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08006551static int sta_set_he_testbed_def(struct sigma_dut *dut,
6552 const char *intf, int cfg)
6553{
6554 struct nl_msg *msg;
6555 int ret = 0;
6556 struct nlattr *params;
6557 int ifindex;
6558
6559 ifindex = if_nametoindex(intf);
6560 if (ifindex == 0) {
6561 sigma_dut_print(dut, DUT_MSG_ERROR,
6562 "%s: Index for interface %s failed",
6563 __func__, intf);
6564 return -1;
6565 }
6566
6567 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6568 NL80211_CMD_VENDOR)) ||
6569 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6570 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6571 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6572 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6573 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6574 nla_put_u8(msg,
6575 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_SET_HE_TESTBED_DEFAULTS,
6576 cfg)) {
6577 sigma_dut_print(dut, DUT_MSG_ERROR,
6578 "%s: err in adding vendor_cmd and vendor_data",
6579 __func__);
6580 nlmsg_free(msg);
6581 return -1;
6582 }
6583 nla_nest_end(msg, params);
6584
6585 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6586 if (ret) {
6587 sigma_dut_print(dut, DUT_MSG_ERROR,
6588 "%s: err in send_and_recv_msgs, ret=%d",
6589 __func__, ret);
6590 }
6591 return ret;
6592}
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08006593
6594
6595static int sta_set_2g_vht_supp(struct sigma_dut *dut, const char *intf, int cfg)
6596{
6597 struct nl_msg *msg;
6598 int ret = 0;
6599 struct nlattr *params;
6600 int ifindex;
6601
6602 ifindex = if_nametoindex(intf);
6603 if (ifindex == 0) {
6604 sigma_dut_print(dut, DUT_MSG_ERROR,
6605 "%s: Index for interface %s failed",
6606 __func__, intf);
6607 return -1;
6608 }
6609
6610 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6611 NL80211_CMD_VENDOR)) ||
6612 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6613 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6614 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6615 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6616 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6617 nla_put_u8(msg,
6618 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_2G_VHT,
6619 cfg)) {
6620 sigma_dut_print(dut, DUT_MSG_ERROR,
6621 "%s: err in adding vendor_cmd and vendor_data",
6622 __func__);
6623 nlmsg_free(msg);
6624 return -1;
6625 }
6626 nla_nest_end(msg, params);
6627
6628 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6629 if (ret) {
6630 sigma_dut_print(dut, DUT_MSG_ERROR,
6631 "%s: err in send_and_recv_msgs, ret=%d",
6632 __func__, ret);
6633 }
6634 return ret;
6635}
6636
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08006637#endif /* NL80211_SUPPORT */
6638
6639
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08006640static int sta_set_addba_buf_size(struct sigma_dut *dut,
6641 const char *intf, int bufsize)
6642{
6643#ifdef NL80211_SUPPORT
6644 struct nl_msg *msg;
6645 int ret = 0;
6646 struct nlattr *params;
6647 int ifindex;
6648
6649 ifindex = if_nametoindex(intf);
6650 if (ifindex == 0) {
6651 sigma_dut_print(dut, DUT_MSG_ERROR,
6652 "%s: Index for interface %s failed",
6653 __func__, intf);
6654 return -1;
6655 }
6656
6657 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6658 NL80211_CMD_VENDOR)) ||
6659 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6660 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6661 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6662 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6663 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
Kiran Kumar Lokere26e27582018-08-01 16:18:34 -07006664 nla_put_u16(msg,
6665 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE,
6666 bufsize)) {
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08006667 sigma_dut_print(dut, DUT_MSG_ERROR,
6668 "%s: err in adding vendor_cmd and vendor_data",
6669 __func__);
6670 nlmsg_free(msg);
6671 return -1;
6672 }
6673 nla_nest_end(msg, params);
6674
6675 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6676 if (ret) {
6677 sigma_dut_print(dut, DUT_MSG_ERROR,
6678 "%s: err in send_and_recv_msgs, ret=%d",
6679 __func__, ret);
6680 }
6681 return ret;
6682#else /* NL80211_SUPPORT */
6683 sigma_dut_print(dut, DUT_MSG_ERROR,
6684 "AddBA bufsize cannot be changed without NL80211_SUPPORT defined");
6685 return -1;
6686#endif /* NL80211_SUPPORT */
6687}
6688
6689
Arif Hussain8d5b27b2018-05-14 14:31:03 -07006690static int sta_set_tx_beamformee(struct sigma_dut *dut, const char *intf,
6691 int enable)
6692{
6693#ifdef NL80211_SUPPORT
6694 struct nl_msg *msg;
6695 int ret = 0;
6696 struct nlattr *params;
6697 int ifindex;
6698
6699 ifindex = if_nametoindex(intf);
6700 if (ifindex == 0) {
6701 sigma_dut_print(dut, DUT_MSG_ERROR,
6702 "%s: Index for interface %s failed",
6703 __func__, intf);
6704 return -1;
6705 }
6706
6707 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6708 NL80211_CMD_VENDOR)) ||
6709 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6710 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6711 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6712 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6713 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6714 nla_put_u8(msg,
6715 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_TX_BEAMFORMEE,
6716 enable)) {
6717 sigma_dut_print(dut, DUT_MSG_ERROR,
6718 "%s: err in adding vendor_cmd and vendor_data",
6719 __func__);
6720 nlmsg_free(msg);
6721 return -1;
6722 }
6723 nla_nest_end(msg, params);
6724
6725 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6726 if (ret) {
6727 sigma_dut_print(dut, DUT_MSG_ERROR,
6728 "%s: err in send_and_recv_msgs, ret=%d",
6729 __func__, ret);
6730 }
6731 return ret;
6732#else /* NL80211_SUPPORT */
6733 sigma_dut_print(dut, DUT_MSG_ERROR,
6734 "tx beamformee cannot be changed without NL80211_SUPPORT defined");
6735 return -1;
6736#endif /* NL80211_SUPPORT */
6737}
6738
6739
Arif Hussain9765f7d2018-07-03 08:28:26 -07006740static int sta_set_beamformee_sts(struct sigma_dut *dut, const char *intf,
6741 int val)
6742{
6743#ifdef NL80211_SUPPORT
6744 struct nl_msg *msg;
6745 int ret = 0;
6746 struct nlattr *params;
6747 int ifindex;
6748
6749 ifindex = if_nametoindex(intf);
6750 if (ifindex == 0) {
6751 sigma_dut_print(dut, DUT_MSG_ERROR,
6752 "%s: Index for interface %s failed, val:%d",
6753 __func__, intf, val);
6754 return -1;
6755 }
6756
6757 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6758 NL80211_CMD_VENDOR)) ||
6759 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6760 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6761 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6762 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6763 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6764 nla_put_u8(msg,
6765 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_BEAMFORMEE_NSTS,
6766 val)) {
6767 sigma_dut_print(dut, DUT_MSG_ERROR,
6768 "%s: err in adding vendor_cmd and vendor_data, val: %d",
6769 __func__, val);
6770 nlmsg_free(msg);
6771 return -1;
6772 }
6773 nla_nest_end(msg, params);
6774
6775 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6776 if (ret) {
6777 sigma_dut_print(dut, DUT_MSG_ERROR,
6778 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
6779 __func__, ret, val);
6780 }
6781 return ret;
6782#else /* NL80211_SUPPORT */
6783 sigma_dut_print(dut, DUT_MSG_ERROR,
6784 "beamformee sts cannot be changed without NL80211_SUPPORT defined");
6785 return -1;
6786#endif /* NL80211_SUPPORT */
6787}
6788
6789
Arif Hussain68d23f52018-07-11 13:39:08 -07006790#ifdef NL80211_SUPPORT
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07006791static int sta_set_mac_padding_duration(struct sigma_dut *dut, const char *intf,
6792 enum qca_wlan_he_mac_padding_dur val)
6793{
Arif Hussain68d23f52018-07-11 13:39:08 -07006794 struct nl_msg *msg;
6795 int ret = 0;
6796 struct nlattr *params;
6797 int ifindex;
6798
6799 ifindex = if_nametoindex(intf);
6800 if (ifindex == 0) {
6801 sigma_dut_print(dut, DUT_MSG_ERROR,
6802 "%s: Index for interface %s failed, val:%d",
6803 __func__, intf, val);
6804 return -1;
6805 }
6806
6807 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6808 NL80211_CMD_VENDOR)) ||
6809 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6810 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6811 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6812 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6813 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6814 nla_put_u8(msg,
6815 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MAC_PADDING_DUR,
6816 val)) {
6817 sigma_dut_print(dut, DUT_MSG_ERROR,
6818 "%s: err in adding vendor_cmd and vendor_data, val: %d",
6819 __func__, val);
6820 nlmsg_free(msg);
6821 return -1;
6822 }
6823 nla_nest_end(msg, params);
6824
6825 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6826 if (ret) {
6827 sigma_dut_print(dut, DUT_MSG_ERROR,
6828 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
6829 __func__, ret, val);
6830 }
6831 return ret;
Arif Hussain68d23f52018-07-11 13:39:08 -07006832}
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07006833#endif /* NL80211_SUPPORT */
Arif Hussain68d23f52018-07-11 13:39:08 -07006834
6835
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07006836static int sta_set_tx_su_ppdu_cfg(struct sigma_dut *dut, const char *intf,
6837 int val)
6838{
6839#ifdef NL80211_SUPPORT
6840 struct nl_msg *msg;
6841 int ret = 0;
6842 struct nlattr *params;
6843 int ifindex;
6844
6845 ifindex = if_nametoindex(intf);
6846 if (ifindex == 0) {
6847 sigma_dut_print(dut, DUT_MSG_ERROR,
6848 "%s: Index for interface %s failed, val:%d",
6849 __func__, intf, val);
6850 return -1;
6851 }
6852
6853 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6854 NL80211_CMD_VENDOR)) ||
6855 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6856 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6857 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6858 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6859 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6860 nla_put_u8(msg,
6861 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_SUPPDU,
6862 val)) {
6863 sigma_dut_print(dut, DUT_MSG_ERROR,
6864 "%s: err in adding vendor_cmd and vendor_data, val: %d",
6865 __func__, val);
6866 nlmsg_free(msg);
6867 return -1;
6868 }
6869 nla_nest_end(msg, params);
6870
6871 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6872 if (ret) {
6873 sigma_dut_print(dut, DUT_MSG_ERROR,
6874 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
6875 __func__, ret, val);
6876 }
6877 return ret;
6878#else /* NL80211_SUPPORT */
6879 sigma_dut_print(dut, DUT_MSG_ERROR,
6880 "Tx SU PPDU cannot be set without NL80211_SUPPORT defined");
6881 return -1;
6882#endif /* NL80211_SUPPORT */
6883}
6884
6885
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07006886#ifdef NL80211_SUPPORT
6887static int sta_set_he_om_ctrl_reset(struct sigma_dut *dut, const char *intf)
6888{
6889 struct nl_msg *msg;
6890 int ret = 0;
6891 struct nlattr *params;
6892 int ifindex;
6893
6894 ifindex = if_nametoindex(intf);
6895 if (ifindex == 0) {
6896 sigma_dut_print(dut, DUT_MSG_ERROR,
6897 "%s: Index for interface %s failed",
6898 __func__, intf);
6899 return -1;
6900 }
6901
6902 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6903 NL80211_CMD_VENDOR)) ||
6904 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6905 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6906 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6907 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6908 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6909 nla_put_flag(msg,
6910 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_CLEAR_HE_OM_CTRL_CONFIG)) {
6911 sigma_dut_print(dut, DUT_MSG_ERROR,
6912 "%s: err in adding vendor_cmd and vendor_data",
6913 __func__);
6914 nlmsg_free(msg);
6915 return -1;
6916 }
6917 nla_nest_end(msg, params);
6918
6919 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6920 if (ret) {
6921 sigma_dut_print(dut, DUT_MSG_ERROR,
6922 "%s: err in send_and_recv_msgs, ret=%d",
6923 __func__, ret);
6924 }
6925 return ret;
6926}
6927#endif /* NL80211_SUPPORT */
6928
6929
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07006930static int sta_set_mu_edca_override(struct sigma_dut *dut, const char *intf,
6931 int val)
6932{
6933#ifdef NL80211_SUPPORT
6934 struct nl_msg *msg;
6935 int ret = 0;
6936 struct nlattr *params;
6937 int ifindex;
6938
6939 ifindex = if_nametoindex(intf);
6940 if (ifindex == 0) {
6941 sigma_dut_print(dut, DUT_MSG_ERROR,
6942 "%s: Index for interface %s failed, val:%d",
6943 __func__, intf, val);
6944 return -1;
6945 }
6946
6947 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6948 NL80211_CMD_VENDOR)) ||
6949 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6950 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6951 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6952 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6953 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6954 nla_put_u8(msg,
6955 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_OVERRIDE_MU_EDCA,
6956 val)) {
6957 sigma_dut_print(dut, DUT_MSG_ERROR,
6958 "%s: err in adding vendor_cmd and vendor_data, val: %d",
6959 __func__, val);
6960 nlmsg_free(msg);
6961 return -1;
6962 }
6963 nla_nest_end(msg, params);
6964
6965 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6966 if (ret) {
6967 sigma_dut_print(dut, DUT_MSG_ERROR,
6968 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
6969 __func__, ret, val);
6970 }
6971 return ret;
6972#else /* NL80211_SUPPORT */
6973 sigma_dut_print(dut, DUT_MSG_ERROR,
6974 "MU EDCA override cannot be changed without NL80211_SUPPORT defined");
6975 return -1;
6976#endif /* NL80211_SUPPORT */
6977}
6978
6979
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07006980static int sta_set_om_ctrl_supp(struct sigma_dut *dut, const char *intf,
6981 int val)
6982{
6983#ifdef NL80211_SUPPORT
6984 struct nl_msg *msg;
6985 int ret = 0;
6986 struct nlattr *params;
6987 int ifindex;
6988
6989 ifindex = if_nametoindex(intf);
6990 if (ifindex == 0) {
6991 sigma_dut_print(dut, DUT_MSG_ERROR,
6992 "%s: Index for interface %s failed, val:%d",
6993 __func__, intf, val);
6994 return -1;
6995 }
6996
6997 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6998 NL80211_CMD_VENDOR)) ||
6999 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7000 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7001 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7002 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7003 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7004 nla_put_u8(msg,
7005 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OM_CTRL_SUPP,
7006 val)) {
7007 sigma_dut_print(dut, DUT_MSG_ERROR,
7008 "%s: err in adding vendor_cmd and vendor_data, val: %d",
7009 __func__, val);
7010 nlmsg_free(msg);
7011 return -1;
7012 }
7013 nla_nest_end(msg, params);
7014
7015 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7016 if (ret) {
7017 sigma_dut_print(dut, DUT_MSG_ERROR,
7018 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
7019 __func__, ret, val);
7020 }
7021 return ret;
7022#else /* NL80211_SUPPORT */
7023 sigma_dut_print(dut, DUT_MSG_ERROR,
7024 "HE OM ctrl cannot be changed without NL80211_SUPPORT defined");
7025 return -1;
7026#endif /* NL80211_SUPPORT */
7027}
7028
7029
Arif Hussain480d5f42019-03-12 14:40:42 -07007030static int sta_set_twt_req_support(struct sigma_dut *dut, const char *intf,
7031 int val)
7032{
7033#ifdef NL80211_SUPPORT
7034 struct nl_msg *msg;
7035 int ret;
7036 struct nlattr *params;
7037 int ifindex;
7038
7039 ifindex = if_nametoindex(intf);
7040 if (ifindex == 0) {
7041 sigma_dut_print(dut, DUT_MSG_ERROR,
7042 "%s: Index for interface %s failed, val:%d",
7043 __func__, intf, val);
7044 return -1;
7045 }
7046
7047 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7048 NL80211_CMD_VENDOR)) ||
7049 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7050 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7051 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7052 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7053 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7054 nla_put_u8(msg,
7055 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TWT_REQ_SUPPORT,
7056 val)) {
7057 sigma_dut_print(dut, DUT_MSG_ERROR,
7058 "%s: err in adding vendor_cmd and vendor_data, val: %d",
7059 __func__, val);
7060 nlmsg_free(msg);
7061 return -1;
7062 }
7063 nla_nest_end(msg, params);
7064
7065 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7066 if (ret) {
7067 sigma_dut_print(dut, DUT_MSG_ERROR,
7068 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
7069 __func__, ret, val);
7070 }
7071 return ret;
7072#else /* NL80211_SUPPORT */
7073 sigma_dut_print(dut, DUT_MSG_ERROR,
7074 "TWT Request cannot be changed without NL80211_SUPPORT defined");
7075 return -1;
7076#endif /* NL80211_SUPPORT */
7077}
7078
7079
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08007080static void sta_reset_default_wcn(struct sigma_dut *dut, const char *intf,
7081 const char *type)
7082{
7083 char buf[60];
7084
7085 if (dut->program == PROGRAM_HE) {
7086 /* resetting phymode to auto in case of HE program */
7087 snprintf(buf, sizeof(buf), "iwpriv %s setphymode 0", intf);
7088 if (system(buf) != 0) {
7089 sigma_dut_print(dut, DUT_MSG_ERROR,
7090 "iwpriv %s setphymode failed", intf);
7091 }
7092
Amarnath Hullur Subramanyam9cecb502018-04-25 13:26:30 -07007093 /* reset the rate to Auto rate */
7094 snprintf(buf, sizeof(buf), "iwpriv %s set_11ax_rate 0xff",
7095 intf);
7096 if (system(buf) != 0) {
7097 sigma_dut_print(dut, DUT_MSG_ERROR,
7098 "iwpriv %s set_11ax_rate 0xff failed",
7099 intf);
7100 }
7101
Kiran Kumar Lokere86cfe3a2018-06-01 11:55:15 -07007102 /* reset the LDPC setting */
7103 snprintf(buf, sizeof(buf), "iwpriv %s ldpc 1", intf);
7104 if (system(buf) != 0) {
7105 sigma_dut_print(dut, DUT_MSG_ERROR,
7106 "iwpriv %s ldpc 1 failed", intf);
7107 }
7108
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08007109 /* reset the power save setting */
7110 snprintf(buf, sizeof(buf), "iwpriv %s setPower 2", intf);
7111 if (system(buf) != 0) {
7112 sigma_dut_print(dut, DUT_MSG_ERROR,
7113 "iwpriv %s setPower 2 failed", intf);
7114 }
7115
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08007116 /* remove all network profiles */
7117 remove_wpa_networks(intf);
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08007118
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08007119 /* Configure ADDBA Req/Rsp buffer size to be 64 */
7120 sta_set_addba_buf_size(dut, intf, 64);
7121
Amarnath Hullur Subramanyam5f32d572018-03-02 00:02:33 -08007122#ifdef NL80211_SUPPORT
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08007123 /* Reset the device HE capabilities to its default supported
7124 * configuration. */
7125 sta_set_he_testbed_def(dut, intf, 0);
7126
Amarnath Hullur Subramanyam5f32d572018-03-02 00:02:33 -08007127 /* Disable noackpolicy for all AC */
7128 if (nlvendor_sta_set_noack(dut, intf, 0, QCA_WLAN_AC_ALL)) {
7129 sigma_dut_print(dut, DUT_MSG_ERROR,
7130 "Disable of noackpolicy for all AC failed");
7131 }
7132#endif /* NL80211_SUPPORT */
7133
Amarnath Hullur Subramanyamb1724a52018-03-07 14:31:46 -08007134 /* Enable WMM by default */
7135 if (wcn_sta_set_wmm(dut, intf, "on")) {
7136 sigma_dut_print(dut, DUT_MSG_ERROR,
7137 "Enable of WMM in sta_reset_default_wcn failed");
7138 }
7139
7140 /* Disable ADDBA_REJECT by default */
7141 if (nlvendor_sta_set_addba_reject(dut, intf, 0)) {
7142 sigma_dut_print(dut, DUT_MSG_ERROR,
7143 "Disable of addba_reject in sta_reset_default_wcn failed");
7144 }
7145
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08007146 /* Enable sending of ADDBA by default */
7147 if (nlvendor_config_send_addba(dut, intf, 1)) {
7148 sigma_dut_print(dut, DUT_MSG_ERROR,
7149 "Enable sending of ADDBA in sta_reset_default_wcn failed");
7150 }
7151
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08007152 /* Enable AMPDU by default */
7153 iwpriv_sta_set_ampdu(dut, intf, 1);
7154
Subhani Shaik8e7a3052018-04-24 14:03:00 -07007155#ifdef NL80211_SUPPORT
7156 if (sta_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_AUTO)) {
7157 sigma_dut_print(dut, DUT_MSG_ERROR,
7158 "Set LTF config to default in sta_reset_default_wcn failed");
7159 }
Arif Hussain9765f7d2018-07-03 08:28:26 -07007160
Kiran Kumar Lokerebad51122018-12-12 19:03:36 -08007161 /* set the beamformee NSTS(maximum number of
7162 * space-time streams) to default DUT config
7163 */
7164 if (sta_set_beamformee_sts(dut, intf, 7)) {
Arif Hussain9765f7d2018-07-03 08:28:26 -07007165 sigma_dut_print(dut, DUT_MSG_ERROR,
7166 "Failed to set BeamformeeSTS");
7167 }
Arif Hussain68d23f52018-07-11 13:39:08 -07007168
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07007169 if (sta_set_mac_padding_duration(
7170 dut, intf,
7171 QCA_WLAN_HE_NO_ADDITIONAL_PROCESS_TIME)) {
Arif Hussain68d23f52018-07-11 13:39:08 -07007172 sigma_dut_print(dut, DUT_MSG_ERROR,
7173 "Failed to set MAC padding duration");
7174 }
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07007175
7176 if (sta_set_mu_edca_override(dut, intf, 0)) {
7177 sigma_dut_print(dut, DUT_MSG_ERROR,
7178 "ErrorCode,Failed to set MU EDCA override disable");
7179 }
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07007180
7181 if (sta_set_om_ctrl_supp(dut, intf, 1)) {
7182 sigma_dut_print(dut, DUT_MSG_ERROR,
7183 "Failed to set OM ctrl supp");
7184 }
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07007185
7186 if (sta_set_tx_su_ppdu_cfg(dut, intf, 1)) {
7187 sigma_dut_print(dut, DUT_MSG_ERROR,
7188 "Failed to set Tx SU PPDU enable");
7189 }
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07007190
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07007191 if (sta_set_action_tx_in_he_tb_ppdu(dut, intf, 0)) {
7192 sigma_dut_print(dut, DUT_MSG_ERROR,
7193 "failed to send TB PPDU Tx cfg");
7194 }
7195
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07007196 if (sta_set_he_om_ctrl_reset(dut, intf)) {
7197 sigma_dut_print(dut, DUT_MSG_ERROR,
7198 "Failed to set OM ctrl reset");
7199 }
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08007200
7201 /* +HTC-HE support default on */
7202 if (sta_set_he_htc_supp(dut, intf, 1)) {
7203 sigma_dut_print(dut, DUT_MSG_ERROR,
7204 "Setting of +HTC-HE support failed");
7205 }
Subhani Shaik8e7a3052018-04-24 14:03:00 -07007206#endif /* NL80211_SUPPORT */
7207
Arif Hussain8d5b27b2018-05-14 14:31:03 -07007208 if (sta_set_tx_beamformee(dut, intf, 1)) {
7209 sigma_dut_print(dut, DUT_MSG_ERROR,
7210 "Set tx beamformee enable by default in sta_reset_default_wcn failed");
7211 }
7212
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08007213 /* Set nss to 1 and MCS 0-7 in case of testbed */
7214 if (type && strcasecmp(type, "Testbed") == 0) {
7215#ifdef NL80211_SUPPORT
7216 int ret;
7217#endif /* NL80211_SUPPORT */
7218
7219 snprintf(buf, sizeof(buf), "iwpriv %s nss 1", intf);
7220 if (system(buf) != 0) {
7221 sigma_dut_print(dut, DUT_MSG_ERROR,
7222 "iwpriv %s nss failed", intf);
7223 }
7224
7225#ifdef NL80211_SUPPORT
7226 ret = sta_set_he_mcs(dut, intf, HE_80_MCS0_7);
7227 if (ret) {
7228 sigma_dut_print(dut, DUT_MSG_ERROR,
7229 "Setting of MCS failed, ret:%d",
7230 ret);
7231 }
7232#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyamc67621d2018-02-04 23:18:01 -08007233
7234 /* Disable STBC as default */
7235 wcn_sta_set_stbc(dut, intf, "0");
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08007236
7237 /* Disable AMSDU as default */
7238 iwpriv_sta_set_amsdu(dut, intf, "0");
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08007239
7240#ifdef NL80211_SUPPORT
7241 /* HE fragmentation default off */
7242 if (sta_set_he_fragmentation(dut, intf,
7243 HE_FRAG_DISABLE)) {
7244 sigma_dut_print(dut, DUT_MSG_ERROR,
7245 "Setting of HE fragmentation failed");
7246 }
Kiran Kumar Lokerebad51122018-12-12 19:03:36 -08007247
7248 /* set the beamformee NSTS(maximum number of
7249 * space-time streams) to default testbed config
7250 */
7251 if (sta_set_beamformee_sts(dut, intf, 3)) {
7252 sigma_dut_print(dut, DUT_MSG_ERROR,
7253 "Failed to set BeamformeeSTS");
7254 }
7255
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08007256 /* +HTC-HE support default off */
7257 if (sta_set_he_htc_supp(dut, intf, 0)) {
7258 sigma_dut_print(dut, DUT_MSG_ERROR,
7259 "Setting of +HTC-HE support failed");
7260 }
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08007261
7262 /* Set device HE capabilities to testbed default
7263 * configuration. */
7264 if (sta_set_he_testbed_def(dut, intf, 1)) {
7265 sigma_dut_print(dut, DUT_MSG_DEBUG,
7266 "Failed to set HE defaults");
7267 }
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08007268
7269 /* Disable VHT support in 2.4 GHz for testbed */
7270 sta_set_2g_vht_supp(dut, intf, 0);
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08007271#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08007272
7273 /* Enable WEP/TKIP with HE capability in testbed */
7274 if (sta_set_heconfig_and_wep_tkip(dut, intf, 1)) {
7275 sigma_dut_print(dut, DUT_MSG_ERROR,
7276 "Enabling HE config with WEP/TKIP failed");
7277 }
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08007278 }
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08007279
7280 /* Defaults in case of DUT */
7281 if (type && strcasecmp(type, "DUT") == 0) {
Arif Hussaind48fcc72018-05-01 18:34:18 -07007282 /* Enable STBC by default */
7283 wcn_sta_set_stbc(dut, intf, "1");
7284
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08007285 /* set nss to 2 */
7286 snprintf(buf, sizeof(buf), "iwpriv %s nss 2", intf);
7287 if (system(buf) != 0) {
7288 sigma_dut_print(dut, DUT_MSG_ERROR,
7289 "iwpriv %s nss 2 failed", intf);
7290 }
Arif Hussainac6c5112018-05-25 17:34:00 -07007291 dut->sta_nss = 2;
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08007292
7293#ifdef NL80211_SUPPORT
Arif Hussainae239842018-05-01 18:20:05 -07007294 /* Set HE_MCS to 0-11 */
7295 if (sta_set_he_mcs(dut, intf, HE_80_MCS0_11)) {
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08007296 sigma_dut_print(dut, DUT_MSG_ERROR,
7297 "Setting of MCS failed");
7298 }
7299#endif /* NL80211_SUPPORT */
7300
7301 /* Disable WEP/TKIP with HE capability in DUT */
7302 if (sta_set_heconfig_and_wep_tkip(dut, intf, 0)) {
7303 sigma_dut_print(dut, DUT_MSG_ERROR,
7304 "Enabling HE config with WEP/TKIP failed");
7305 }
7306 }
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08007307 }
7308}
7309
7310
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007311static int cmd_sta_reset_default(struct sigma_dut *dut,
7312 struct sigma_conn *conn,
7313 struct sigma_cmd *cmd)
7314{
7315 int cmd_sta_p2p_reset(struct sigma_dut *dut, struct sigma_conn *conn,
7316 struct sigma_cmd *cmd);
7317 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007318 const char *band = get_param(cmd, "band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007319 const char *type;
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07007320 const char *program = get_param(cmd, "program");
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05307321 const char *dev_role = get_param(cmd, "DevRole");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007322
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07007323 if (!program)
7324 program = get_param(cmd, "prog");
7325 dut->program = sigma_program_to_enum(program);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007326 dut->device_type = STA_unknown;
7327 type = get_param(cmd, "type");
7328 if (type && strcasecmp(type, "Testbed") == 0)
7329 dut->device_type = STA_testbed;
7330 if (type && strcasecmp(type, "DUT") == 0)
7331 dut->device_type = STA_dut;
7332
7333 if (dut->program == PROGRAM_TDLS) {
7334 /* Clear TDLS testing mode */
7335 wpa_command(intf, "SET tdls_disabled 0");
7336 wpa_command(intf, "SET tdls_testing 0");
7337 dut->no_tpk_expiration = 0;
Pradeep Reddy POTTETI8ce2a232016-10-28 12:17:32 +05307338 if (get_driver_type() == DRIVER_WCN) {
7339 /* Enable the WCN driver in TDLS Explicit trigger mode
7340 */
7341 wpa_command(intf, "SET tdls_external_control 0");
7342 wpa_command(intf, "SET tdls_trigger_control 0");
7343 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007344 }
7345
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07007346#ifdef MIRACAST
7347 if (dut->program == PROGRAM_WFD ||
7348 dut->program == PROGRAM_DISPLAYR2)
7349 miracast_sta_reset_default(dut, conn, cmd);
7350#endif /* MIRACAST */
7351
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007352 switch (get_driver_type()) {
7353 case DRIVER_ATHEROS:
7354 sta_reset_default_ath(dut, intf, type);
7355 break;
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08007356 case DRIVER_WCN:
7357 sta_reset_default_wcn(dut, intf, type);
7358 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007359 default:
7360 break;
7361 }
7362
7363#ifdef ANDROID_NAN
7364 if (dut->program == PROGRAM_NAN)
7365 nan_cmd_sta_reset_default(dut, conn, cmd);
7366#endif /* ANDROID_NAN */
7367
Jouni Malinenba630452018-06-22 11:49:59 +03007368 if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007369 unlink("SP/wi-fi.org/pps.xml");
7370 if (system("rm -r SP/*") != 0) {
7371 }
7372 unlink("next-client-cert.pem");
7373 unlink("next-client-key.pem");
7374 }
7375
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007376 /* For WPS program of the 60 GHz band the band type needs to be saved */
7377 if (dut->program == PROGRAM_WPS) {
7378 if (band && strcasecmp(band, "60GHz") == 0) {
7379 dut->band = WPS_BAND_60G;
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02007380 /* For 60 GHz enable WPS for WPS TCs */
7381 dut->wps_disable = 0;
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007382 } else {
7383 dut->band = WPS_BAND_NON_60G;
7384 }
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02007385 } else if (dut->program == PROGRAM_60GHZ) {
7386 /* For 60 GHz MAC/PHY TCs WPS must be disabled */
7387 dut->wps_disable = 1;
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007388 }
7389
Alexei Avshalom Lazar157ba062018-12-23 16:15:26 +02007390 if (is_60g_sigma_dut(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007391 const char *dev_role = get_param(cmd, "DevRole");
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02007392 char buf[256];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007393
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02007394 sigma_dut_print(dut, DUT_MSG_INFO,
7395 "WPS 60 GHz program, wps_disable = %d",
7396 dut->wps_disable);
7397
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007398 if (!dev_role) {
7399 send_resp(dut, conn, SIGMA_ERROR,
7400 "errorCode,Missing DevRole argument");
7401 return 0;
7402 }
7403
7404 if (strcasecmp(dev_role, "STA") == 0)
7405 dut->dev_role = DEVROLE_STA;
7406 else if (strcasecmp(dev_role, "PCP") == 0)
7407 dut->dev_role = DEVROLE_PCP;
7408 else {
7409 send_resp(dut, conn, SIGMA_ERROR,
7410 "errorCode,Unknown DevRole");
7411 return 0;
7412 }
7413
7414 if (dut->device_type == STA_unknown) {
7415 sigma_dut_print(dut, DUT_MSG_ERROR,
7416 "Device type is not STA testbed or DUT");
7417 send_resp(dut, conn, SIGMA_ERROR,
7418 "errorCode,Unknown device type");
7419 return 0;
7420 }
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02007421
7422 sigma_dut_print(dut, DUT_MSG_DEBUG,
7423 "Setting msdu_size to MAX: 7912");
7424 snprintf(buf, sizeof(buf), "ifconfig %s mtu 7912",
7425 get_station_ifname());
7426
7427 if (system(buf) != 0) {
7428 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
7429 buf);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007430 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02007431 }
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02007432
7433 if (sta_set_force_mcs(dut, 0, 1)) {
7434 sigma_dut_print(dut, DUT_MSG_ERROR,
7435 "Failed to reset force MCS");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007436 return ERROR_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02007437 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007438 }
7439
7440 wpa_command(intf, "WPS_ER_STOP");
7441 wpa_command(intf, "FLUSH");
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05307442 wpa_command(intf, "ERP_FLUSH");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007443 wpa_command(intf, "SET radio_disabled 0");
7444
Alexei Avshalom Lazar744ae8a2019-01-31 17:26:46 +02007445 dut->wps_forced_version = 0;
7446
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007447 if (dut->wsc_fragment) {
7448 dut->wsc_fragment = 0;
7449 wpa_command(intf, "SET device_name Test client");
7450 wpa_command(intf, "SET manufacturer ");
7451 wpa_command(intf, "SET model_name ");
7452 wpa_command(intf, "SET model_number ");
7453 wpa_command(intf, "SET serial_number ");
7454 }
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02007455 if (is_60g_sigma_dut(dut) && dut->force_rsn_ie) {
7456 dut->force_rsn_ie = FORCE_RSN_IE_NONE;
7457 sta_60g_force_rsn_ie(dut, FORCE_RSN_IE_NONE);
7458 }
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007459
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007460 if (dut->tmp_mac_addr && dut->set_macaddr) {
7461 dut->tmp_mac_addr = 0;
7462 if (system(dut->set_macaddr) != 0) {
7463 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to clear "
7464 "temporary MAC address");
7465 }
7466 }
7467
7468 set_ps(intf, dut, 0);
7469
Jouni Malinenba630452018-06-22 11:49:59 +03007470 if (dut->program == PROGRAM_HS2 || dut->program == PROGRAM_HS2_R2 ||
7471 dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007472 wpa_command(intf, "SET interworking 1");
7473 wpa_command(intf, "SET hs20 1");
7474 }
7475
Deepak Dhamdhere0fe0e452017-12-18 14:52:09 -08007476 if (dut->program == PROGRAM_HS2_R2 ||
Jouni Malinenba630452018-06-22 11:49:59 +03007477 dut->program == PROGRAM_HS2_R3 ||
Deepak Dhamdhere0fe0e452017-12-18 14:52:09 -08007478 dut->program == PROGRAM_OCE) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007479 wpa_command(intf, "SET pmf 1");
7480 } else {
7481 wpa_command(intf, "SET pmf 0");
7482 }
7483
7484 hs2_clear_credentials(intf);
7485 wpa_command(intf, "SET hessid 00:00:00:00:00:00");
7486 wpa_command(intf, "SET access_network_type 15");
7487
7488 static_ip_file(0, NULL, NULL, NULL);
7489 kill_dhcp_client(dut, intf);
7490 clear_ip_addr(dut, intf);
7491
7492 dut->er_oper_performed = 0;
7493 dut->er_oper_bssid[0] = '\0';
7494
priyadharshini gowthamanad6cbba2016-10-04 10:39:58 -07007495 if (dut->program == PROGRAM_LOC) {
7496 /* Disable Interworking by default */
7497 wpa_command(get_station_ifname(), "SET interworking 0");
7498 }
7499
Ashwini Patil00402582017-04-13 12:29:39 +05307500 if (dut->program == PROGRAM_MBO) {
7501 free(dut->non_pref_ch_list);
7502 dut->non_pref_ch_list = NULL;
Ashwini Patil5acd7382017-04-13 15:55:04 +05307503 free(dut->btm_query_cand_list);
7504 dut->btm_query_cand_list = NULL;
Ashwini Patilc63161e2017-04-13 16:30:23 +05307505 wpa_command(intf, "SET reject_btm_req_reason 0");
Ashwini Patila75de5a2017-04-13 16:35:05 +05307506 wpa_command(intf, "SET ignore_assoc_disallow 0");
Ashwini Patild174f2c2017-04-13 16:49:46 +05307507 wpa_command(intf, "SET gas_address3 0");
Ashwini Patil9183fdb2017-04-13 16:58:25 +05307508 wpa_command(intf, "SET roaming 1");
Ankita Bajaj1d974552018-09-18 16:56:44 +05307509 wpa_command(intf, "SET interworking 1");
Ashwini Patil00402582017-04-13 12:29:39 +05307510 }
7511
Jouni Malinen3c367e82017-06-23 17:01:47 +03007512 free(dut->rsne_override);
7513 dut->rsne_override = NULL;
7514
Jouni Malinen68143132017-09-02 02:34:08 +03007515 free(dut->sae_commit_override);
7516 dut->sae_commit_override = NULL;
7517
Jouni Malinend86e5822017-08-29 03:55:32 +03007518 dut->dpp_conf_id = -1;
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02007519 free(dut->dpp_peer_uri);
7520 dut->dpp_peer_uri = NULL;
Jouni Malinen63d50412017-11-24 11:55:38 +02007521 dut->dpp_local_bootstrap = -1;
Jouni Malinen5011fb52017-12-05 21:00:15 +02007522 wpa_command(intf, "SET dpp_config_processing 2");
Jouni Malinend86e5822017-08-29 03:55:32 +03007523
Jouni Malinenfac9cad2017-10-10 18:35:55 +03007524 wpa_command(intf, "VENDOR_ELEM_REMOVE 13 *");
7525
vamsi krishnaa2799492017-12-05 14:28:01 +05307526 if (dut->program == PROGRAM_OCE) {
Ankita Bajaja2cb5672017-10-25 16:08:28 +05307527 wpa_command(intf, "SET oce 1");
vamsi krishnaa2799492017-12-05 14:28:01 +05307528 wpa_command(intf, "SET disable_fils 0");
Ankita Bajaj1bde7942018-01-09 19:15:01 +05307529 wpa_command(intf, "FILS_HLP_REQ_FLUSH");
7530 dut->fils_hlp = 0;
7531#ifdef ANDROID
7532 hlp_thread_cleanup(dut);
7533#endif /* ANDROID */
vamsi krishnaa2799492017-12-05 14:28:01 +05307534 }
Ankita Bajaja2cb5672017-10-25 16:08:28 +05307535
Jouni Malinen8179fee2019-03-28 03:19:47 +02007536 dut->akm_values = 0;
7537
Sunil Dutt076081f2018-02-05 19:45:50 +05307538#ifdef NL80211_SUPPORT
Sunil Dutt44595082018-02-12 19:41:45 +05307539 if (get_driver_type() == DRIVER_WCN &&
7540 dut->config_rsnie == 1) {
7541 dut->config_rsnie = 0;
7542 sta_config_rsnie(dut, 0);
Sunil Dutt076081f2018-02-05 19:45:50 +05307543 }
7544#endif /* NL80211_SUPPORT */
7545
Sunil Duttfebf8a82018-02-09 18:50:13 +05307546 if (dev_role && strcasecmp(dev_role, "STA-CFON") == 0) {
7547 dut->dev_role = DEVROLE_STA_CFON;
7548 return sta_cfon_reset_default(dut, conn, cmd);
7549 }
7550
Jouni Malinen439352d2018-09-13 03:42:23 +03007551 wpa_command(intf, "SET setband AUTO");
7552
Sunil Duttfebf8a82018-02-09 18:50:13 +05307553 if (dut->program != PROGRAM_VHT)
7554 return cmd_sta_p2p_reset(dut, conn, cmd);
7555
Priyadharshini Gowthamana7dfd492015-11-09 14:34:08 -08007556 return 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007557}
7558
7559
7560static int cmd_sta_get_events(struct sigma_dut *dut, struct sigma_conn *conn,
7561 struct sigma_cmd *cmd)
7562{
7563 const char *program = get_param(cmd, "Program");
7564
7565 if (program == NULL)
7566 return -1;
7567#ifdef ANDROID_NAN
7568 if (strcasecmp(program, "NAN") == 0)
7569 return nan_cmd_sta_get_events(dut, conn, cmd);
7570#endif /* ANDROID_NAN */
7571 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
7572 return 0;
7573}
7574
7575
Jouni Malinen82905202018-04-29 17:20:10 +03007576static int sta_exec_action_url(struct sigma_dut *dut, struct sigma_conn *conn,
7577 struct sigma_cmd *cmd)
7578{
7579 const char *url = get_param(cmd, "url");
7580 const char *method = get_param(cmd, "method");
7581 pid_t pid;
7582 int status;
7583
7584 if (!url || !method)
7585 return -1;
7586
7587 /* TODO: Add support for method,post */
7588 if (strcasecmp(method, "get") != 0) {
7589 send_resp(dut, conn, SIGMA_ERROR,
7590 "ErrorCode,Unsupported method");
7591 return 0;
7592 }
7593
7594 pid = fork();
7595 if (pid < 0) {
7596 perror("fork");
7597 return -1;
7598 }
7599
7600 if (pid == 0) {
7601 char * argv[5] = { "wget", "-O", "/dev/null",
7602 (char *) url, NULL };
7603
7604 execv("/usr/bin/wget", argv);
7605 perror("execv");
7606 exit(0);
7607 return -1;
7608 }
7609
7610 if (waitpid(pid, &status, 0) < 0) {
7611 perror("waitpid");
7612 return -1;
7613 }
7614
7615 if (WIFEXITED(status)) {
7616 const char *errmsg;
7617
7618 if (WEXITSTATUS(status) == 0)
7619 return 1;
7620 sigma_dut_print(dut, DUT_MSG_INFO, "wget exit status %d",
7621 WEXITSTATUS(status));
7622 switch (WEXITSTATUS(status)) {
7623 case 4:
7624 errmsg = "errmsg,Network failure";
7625 break;
7626 case 8:
7627 errmsg = "errmsg,Server issued an error response";
7628 break;
7629 default:
7630 errmsg = "errmsg,Unknown failure from wget";
7631 break;
7632 }
7633 send_resp(dut, conn, SIGMA_ERROR, errmsg);
7634 return 0;
7635 }
7636
7637 send_resp(dut, conn, SIGMA_ERROR, "errmsg,Unknown failure");
7638 return 0;
7639}
7640
7641
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007642static int cmd_sta_exec_action(struct sigma_dut *dut, struct sigma_conn *conn,
7643 struct sigma_cmd *cmd)
7644{
7645 const char *program = get_param(cmd, "Prog");
7646
Jouni Malinen82905202018-04-29 17:20:10 +03007647 if (program && !get_param(cmd, "interface"))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007648 return -1;
7649#ifdef ANDROID_NAN
Jouni Malinen82905202018-04-29 17:20:10 +03007650 if (program && strcasecmp(program, "NAN") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007651 return nan_cmd_sta_exec_action(dut, conn, cmd);
7652#endif /* ANDROID_NAN */
Jouni Malinen82905202018-04-29 17:20:10 +03007653
7654 if (program && strcasecmp(program, "Loc") == 0)
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07007655 return loc_cmd_sta_exec_action(dut, conn, cmd);
Jouni Malinen82905202018-04-29 17:20:10 +03007656
7657 if (get_param(cmd, "url"))
7658 return sta_exec_action_url(dut, conn, cmd);
7659
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007660 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
7661 return 0;
7662}
7663
7664
7665static int cmd_sta_set_11n(struct sigma_dut *dut, struct sigma_conn *conn,
7666 struct sigma_cmd *cmd)
7667{
7668 const char *intf = get_param(cmd, "Interface");
7669 const char *val, *mcs32, *rate;
7670
7671 val = get_param(cmd, "GREENFIELD");
7672 if (val) {
7673 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
7674 /* Enable GD */
7675 send_resp(dut, conn, SIGMA_ERROR,
7676 "ErrorCode,GF not supported");
7677 return 0;
7678 }
7679 }
7680
7681 val = get_param(cmd, "SGI20");
7682 if (val) {
7683 switch (get_driver_type()) {
7684 case DRIVER_ATHEROS:
7685 ath_sta_set_sgi(dut, intf, val);
7686 break;
7687 default:
7688 send_resp(dut, conn, SIGMA_ERROR,
7689 "ErrorCode,SGI20 not supported");
7690 return 0;
7691 }
7692 }
7693
7694 mcs32 = get_param(cmd, "MCS32"); /* HT Duplicate Mode Enable/Disable */
7695 rate = get_param(cmd, "MCS_FIXEDRATE"); /* Fixed MCS rate (0..31) */
7696 if (mcs32 && rate) {
7697 /* TODO */
7698 send_resp(dut, conn, SIGMA_ERROR,
7699 "ErrorCode,MCS32,MCS_FIXEDRATE not supported");
7700 return 0;
7701 } else if (mcs32 && !rate) {
7702 /* TODO */
7703 send_resp(dut, conn, SIGMA_ERROR,
7704 "ErrorCode,MCS32 not supported");
7705 return 0;
7706 } else if (!mcs32 && rate) {
7707 switch (get_driver_type()) {
7708 case DRIVER_ATHEROS:
priyadharshini gowthamane5e25172015-12-08 14:53:48 -08007709 novap_reset(dut, intf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007710 ath_sta_set_11nrates(dut, intf, rate);
7711 break;
7712 default:
7713 send_resp(dut, conn, SIGMA_ERROR,
7714 "ErrorCode,MCS32_FIXEDRATE not supported");
7715 return 0;
7716 }
7717 }
7718
7719 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
7720}
7721
7722
Arif Hussain7b47d2d2018-05-09 10:44:02 -07007723static void cmd_set_max_he_mcs(struct sigma_dut *dut, const char *intf,
7724 int mcs_config)
7725{
7726#ifdef NL80211_SUPPORT
7727 int ret;
7728
7729 switch (mcs_config) {
7730 case HE_80_MCS0_7:
7731 case HE_80_MCS0_9:
7732 case HE_80_MCS0_11:
7733 ret = sta_set_he_mcs(dut, intf, mcs_config);
7734 if (ret) {
7735 sigma_dut_print(dut, DUT_MSG_ERROR,
7736 "cmd_set_max_he_mcs: Setting of MCS:%d failed, ret:%d",
7737 mcs_config, ret);
7738 }
7739 break;
7740 default:
7741 sigma_dut_print(dut, DUT_MSG_ERROR,
7742 "cmd_set_max_he_mcs: Invalid mcs %d",
7743 mcs_config);
7744 break;
7745 }
7746#else /* NL80211_SUPPORT */
7747 sigma_dut_print(dut, DUT_MSG_ERROR,
7748 "max HE MCS cannot be changed without NL80211_SUPPORT defined");
7749#endif /* NL80211_SUPPORT */
7750}
7751
7752
Arif Hussain480d5f42019-03-12 14:40:42 -07007753static int sta_twt_request(struct sigma_dut *dut, struct sigma_conn *conn,
7754 struct sigma_cmd *cmd)
7755{
7756#ifdef NL80211_SUPPORT
7757 struct nlattr *params;
7758 struct nlattr *attr;
7759 struct nlattr *attr1;
7760 struct nl_msg *msg;
7761 int ifindex, ret;
7762 const char *val;
7763 const char *intf = get_param(cmd, "Interface");
7764 int wake_interval_exp = 10, nominal_min_wake_dur = 255,
7765 wake_interval_mantissa = 512;
7766 int flow_type = 0, twt_trigger = 0, target_wake_time = 0,
7767 protection = 0;
7768
7769 ifindex = if_nametoindex(intf);
7770 if (ifindex == 0) {
7771 sigma_dut_print(dut, DUT_MSG_ERROR,
7772 "%s: Index for interface %s failed",
7773 __func__, intf);
7774 return -1;
7775 }
7776
7777 val = get_param(cmd, "FlowType");
7778 if (val) {
7779 flow_type = atoi(val);
7780 if (flow_type != 0 && flow_type != 1) {
7781 sigma_dut_print(dut, DUT_MSG_ERROR,
7782 "TWT: Invalid FlowType %d", flow_type);
7783 return -1;
7784 }
7785 }
7786
7787 val = get_param(cmd, "TWT_Trigger");
7788 if (val) {
7789 twt_trigger = atoi(val);
7790 if (twt_trigger != 0 && twt_trigger != 1) {
7791 sigma_dut_print(dut, DUT_MSG_ERROR,
7792 "TWT: Invalid TWT_Trigger %d",
7793 twt_trigger);
7794 return -1;
7795 }
7796 }
7797
7798 val = get_param(cmd, "Protection");
7799 if (val) {
7800 protection = atoi(val);
7801 if (protection != 0 && protection != 1) {
7802 sigma_dut_print(dut, DUT_MSG_ERROR,
7803 "TWT: Invalid Protection %d",
7804 protection);
7805 return -1;
7806 }
7807 }
7808
7809 val = get_param(cmd, "TargetWakeTime");
7810 if (val)
7811 target_wake_time = atoi(val);
7812
7813 val = get_param(cmd, "WakeIntervalMantissa");
7814 if (val)
7815 wake_interval_mantissa = atoi(val);
7816
7817 val = get_param(cmd, "WakeIntervalExp");
7818 if (val)
7819 wake_interval_exp = atoi(val);
7820
7821 val = get_param(cmd, "NominalMinWakeDur");
7822 if (val)
7823 nominal_min_wake_dur = atoi(val);
7824
7825 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7826 NL80211_CMD_VENDOR)) ||
7827 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7828 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7829 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7830 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7831 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7832 !(params = nla_nest_start(
7833 msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_SETUP)) ||
7834 !(attr1 = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7835 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_EXP,
7836 wake_interval_exp) ||
7837 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST, 0) ||
7838 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_REQ_TYPE, 1) ||
7839 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TRIGGER,
7840 twt_trigger) ||
7841 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE,
7842 flow_type) ||
7843 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_PROTECTION,
7844 protection) ||
7845 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME,
7846 target_wake_time) ||
7847 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_DURATION,
7848 nominal_min_wake_dur) ||
7849 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_MANTISSA,
7850 wake_interval_mantissa)) {
7851 sigma_dut_print(dut, DUT_MSG_ERROR,
7852 "%s: err in adding vendor_cmd and vendor_data",
7853 __func__);
7854 nlmsg_free(msg);
7855 return -1;
7856 }
7857 nla_nest_end(msg, attr1);
7858 nla_nest_end(msg, params);
7859 nla_nest_end(msg, attr);
7860
7861 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7862 if (ret) {
7863 sigma_dut_print(dut, DUT_MSG_ERROR,
7864 "%s: err in send_and_recv_msgs, ret=%d",
7865 __func__, ret);
7866 }
7867
7868 return ret;
7869#else /* NL80211_SUPPORT */
7870 sigma_dut_print(dut, DUT_MSG_ERROR,
7871 "TWT request cannot be done without NL80211_SUPPORT defined");
7872 return -1;
7873#endif /* NL80211_SUPPORT */
7874}
7875
7876
7877static int sta_twt_teardown(struct sigma_dut *dut, struct sigma_conn *conn,
7878 struct sigma_cmd *cmd)
7879{
7880 #ifdef NL80211_SUPPORT
7881 struct nlattr *params;
7882 struct nlattr *attr;
7883 struct nlattr *attr1;
7884 int ifindex, ret;
7885 struct nl_msg *msg;
7886 const char *intf = get_param(cmd, "Interface");
7887
7888 ifindex = if_nametoindex(intf);
7889 if (ifindex == 0) {
7890 sigma_dut_print(dut, DUT_MSG_ERROR,
7891 "%s: Index for interface %s failed",
7892 __func__, intf);
7893 return -1;
7894 }
7895
7896 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7897 NL80211_CMD_VENDOR)) ||
7898 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7899 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7900 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7901 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7902 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7903 !(params = nla_nest_start(
7904 msg,
7905 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_TERMINATE)) ||
7906 !(attr1 = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7907 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE, 0)) {
7908 sigma_dut_print(dut, DUT_MSG_ERROR,
7909 "%s: err in adding vendor_cmd and vendor_data",
7910 __func__);
7911 nlmsg_free(msg);
7912 return -1;
7913 }
7914 nla_nest_end(msg, attr1);
7915 nla_nest_end(msg, params);
7916 nla_nest_end(msg, attr);
7917
7918 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7919 if (ret) {
7920 sigma_dut_print(dut, DUT_MSG_ERROR,
7921 "%s: err in send_and_recv_msgs, ret=%d",
7922 __func__, ret);
7923 }
7924
7925 return ret;
7926#else /* NL80211_SUPPORT */
7927 sigma_dut_print(dut, DUT_MSG_ERROR,
7928 "TWT teardown cannot be done without NL80211_SUPPORT defined");
7929 return -1;
7930#endif /* NL80211_SUPPORT */
7931}
7932
7933
Kiran Kumar Lokere50eb2cd2018-12-18 18:31:28 -08007934static int sta_transmit_omi(struct sigma_dut *dut, struct sigma_conn *conn,
7935 struct sigma_cmd *cmd)
7936{
7937#ifdef NL80211_SUPPORT
7938 struct nlattr *params;
7939 struct nlattr *attr;
7940 struct nlattr *attr1;
7941 struct nl_msg *msg;
7942 int ifindex, ret;
7943 const char *val;
7944 const char *intf = get_param(cmd, "Interface");
7945 uint8_t rx_nss = 0xFF, ch_bw = 0xFF, tx_nsts = 0xFF, ulmu_dis = 0,
7946 ulmu_data_dis = 0;
7947
7948 ifindex = if_nametoindex(intf);
7949 if (ifindex == 0) {
7950 sigma_dut_print(dut, DUT_MSG_ERROR,
7951 "%s: Index for interface %s failed",
7952 __func__, intf);
7953 return -1;
7954 }
7955 val = get_param(cmd, "OMCtrl_RxNSS");
7956 if (val)
7957 rx_nss = atoi(val);
7958
7959 val = get_param(cmd, "OMCtrl_ChnlWidth");
7960 if (val)
7961 ch_bw = atoi(val);
7962
7963 val = get_param(cmd, "OMCtrl_ULMUDisable");
7964 if (val)
7965 ulmu_dis = atoi(val);
7966
7967 val = get_param(cmd, "OMCtrl_TxNSTS");
7968 if (val)
7969 tx_nsts = atoi(val);
7970
7971 val = get_param(cmd, "OMCtrl_ULMUDataDisable");
7972 if (val)
7973 ulmu_data_dis = atoi(val);
7974
7975 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7976 NL80211_CMD_VENDOR)) ||
7977 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7978 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7979 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7980 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7981 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7982 !(params = nla_nest_start(
7983 msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OMI_TX)) ||
7984 !(attr1 = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7985 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_RX_NSS, rx_nss) ||
7986 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_CH_BW, ch_bw) ||
7987 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_TX_NSTS, tx_nsts) ||
7988 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DATA_DISABLE,
7989 ulmu_data_dis) ||
7990 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DISABLE,
7991 ulmu_dis)) {
7992 sigma_dut_print(dut, DUT_MSG_ERROR,
7993 "%s: err in adding vendor_cmd and vendor_data",
7994 __func__);
7995 nlmsg_free(msg);
7996 return -1;
7997 }
7998 nla_nest_end(msg, attr1);
7999 nla_nest_end(msg, params);
8000 nla_nest_end(msg, attr);
8001
8002 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
8003 if (ret) {
8004 sigma_dut_print(dut, DUT_MSG_ERROR,
8005 "%s: err in send_and_recv_msgs, ret=%d",
8006 __func__, ret);
8007 }
8008
8009 return ret;
8010#else /* NL80211_SUPPORT */
8011 sigma_dut_print(dut, DUT_MSG_ERROR,
8012 "OMI TX cannot be processed without NL80211_SUPPORT defined");
8013 return -1;
8014#endif /* NL80211_SUPPORT */
8015}
8016
8017
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008018static int cmd_sta_set_wireless_vht(struct sigma_dut *dut,
8019 struct sigma_conn *conn,
8020 struct sigma_cmd *cmd)
8021{
8022 const char *intf = get_param(cmd, "Interface");
8023 const char *val;
Arif Hussaina37e9552018-06-20 17:05:59 -07008024 const char *program;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008025 int tkip = -1;
8026 int wep = -1;
8027
Arif Hussaina37e9552018-06-20 17:05:59 -07008028 program = get_param(cmd, "Program");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008029 val = get_param(cmd, "SGI80");
8030 if (val) {
8031 int sgi80;
8032
8033 sgi80 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008034 run_iwpriv(dut, intf, "shortgi %d", sgi80);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008035 }
8036
8037 val = get_param(cmd, "TxBF");
8038 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07008039 switch (get_driver_type()) {
8040 case DRIVER_WCN:
8041 if (sta_set_tx_beamformee(dut, intf, 1)) {
8042 send_resp(dut, conn, SIGMA_ERROR,
8043 "ErrorCode,Failed to set TX beamformee enable");
8044 return 0;
8045 }
8046 break;
8047 case DRIVER_ATHEROS:
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008048 if (run_iwpriv(dut, intf, "vhtsubfee 1") < 0) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07008049 send_resp(dut, conn, SIGMA_ERROR,
8050 "ErrorCode,Setting vhtsubfee failed");
8051 return 0;
8052 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008053 if (run_iwpriv(dut, intf, "vhtsubfer 1") < 0) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07008054 send_resp(dut, conn, SIGMA_ERROR,
8055 "ErrorCode,Setting vhtsubfer failed");
8056 return 0;
8057 }
8058 break;
8059 default:
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008060 sigma_dut_print(dut, DUT_MSG_ERROR,
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07008061 "Unsupported driver type");
8062 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008063 }
8064 }
8065
8066 val = get_param(cmd, "MU_TxBF");
8067 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
8068 switch (get_driver_type()) {
8069 case DRIVER_ATHEROS:
8070 ath_sta_set_txsp_stream(dut, intf, "1SS");
8071 ath_sta_set_rxsp_stream(dut, intf, "1SS");
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008072 run_iwpriv(dut, intf, "vhtmubfee 1");
8073 run_iwpriv(dut, intf, "vhtmubfer 1");
Sunil Duttae9e5d12018-06-29 11:50:47 +05308074 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008075 case DRIVER_WCN:
8076 if (wcn_sta_set_sp_stream(dut, intf, "1SS") < 0) {
8077 send_resp(dut, conn, SIGMA_ERROR,
8078 "ErrorCode,Failed to set RX/TXSP_STREAM");
8079 return 0;
8080 }
Sunil Duttae9e5d12018-06-29 11:50:47 +05308081 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008082 default:
8083 sigma_dut_print(dut, DUT_MSG_ERROR,
8084 "Setting SP_STREAM not supported");
8085 break;
8086 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008087 }
8088
8089 val = get_param(cmd, "LDPC");
8090 if (val) {
8091 int ldpc;
8092
8093 ldpc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008094 run_iwpriv(dut, intf, "ldpc %d", ldpc);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008095 }
8096
Amarnath Hullur Subramanyam7bae60e2018-01-31 03:46:50 -08008097 val = get_param(cmd, "BCC");
8098 if (val) {
8099 int bcc;
8100
8101 bcc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
8102 /* use LDPC iwpriv itself to set bcc coding, bcc coding
8103 * is mutually exclusive to bcc */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008104 run_iwpriv(dut, intf, "ldpc %d", !bcc);
Amarnath Hullur Subramanyam7bae60e2018-01-31 03:46:50 -08008105 }
8106
Arif Hussain7b47d2d2018-05-09 10:44:02 -07008107 val = get_param(cmd, "MaxHE-MCS_1SS_RxMapLTE80");
8108 if (val && dut->sta_nss == 1)
8109 cmd_set_max_he_mcs(dut, intf, atoi(val));
8110
8111 val = get_param(cmd, "MaxHE-MCS_2SS_RxMapLTE80");
8112 if (val && dut->sta_nss == 2)
8113 cmd_set_max_he_mcs(dut, intf, atoi(val));
8114
Arif Hussainac6c5112018-05-25 17:34:00 -07008115 val = get_param(cmd, "MCS_FixedRate");
8116 if (val) {
8117#ifdef NL80211_SUPPORT
8118 int mcs, ratecode = 0;
8119 enum he_mcs_config mcs_config;
8120 int ret;
Jouni Malinenb9b671d2019-04-26 13:23:17 +03008121 char buf[60];
Arif Hussainac6c5112018-05-25 17:34:00 -07008122
8123 ratecode = (0x07 & dut->sta_nss) << 5;
8124 mcs = atoi(val);
8125 /* Add the MCS to the ratecode */
8126 if (mcs >= 0 && mcs <= 11) {
8127 ratecode += mcs;
8128 if (dut->device_type == STA_testbed &&
8129 mcs > 7 && mcs <= 11) {
8130 if (mcs <= 9)
8131 mcs_config = HE_80_MCS0_9;
8132 else
8133 mcs_config = HE_80_MCS0_11;
8134 ret = sta_set_he_mcs(dut, intf, mcs_config);
8135 if (ret) {
8136 sigma_dut_print(dut, DUT_MSG_ERROR,
8137 "MCS_FixedRate: mcs setting failed, mcs:%d, mcs_config %d, ret:%d",
8138 mcs, mcs_config, ret);
8139 }
8140 }
8141 snprintf(buf, sizeof(buf),
8142 "iwpriv %s set_11ax_rate 0x%03x",
8143 intf, ratecode);
8144 if (system(buf) != 0) {
8145 sigma_dut_print(dut, DUT_MSG_ERROR,
8146 "MCS_FixedRate: iwpriv setting of 11ax rates 0x%03x failed",
8147 ratecode);
8148 }
8149 } else {
8150 sigma_dut_print(dut, DUT_MSG_ERROR,
8151 "MCS_FixedRate: HE MCS %d not supported",
8152 mcs);
8153 }
8154#else /* NL80211_SUPPORT */
8155 sigma_dut_print(dut, DUT_MSG_ERROR,
8156 "MCS_FixedRate cannot be changed without NL80211_SUPPORT defined");
8157#endif /* NL80211_SUPPORT */
8158 }
8159
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008160 val = get_param(cmd, "opt_md_notif_ie");
8161 if (val) {
8162 char *result = NULL;
8163 char delim[] = ";";
8164 char token[30];
8165 int value, config_val = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308166 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008167
Peng Xub8fc5cc2017-05-10 17:27:28 -07008168 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308169 result = strtok_r(token, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008170
8171 /* Extract the NSS information */
8172 if (result) {
8173 value = atoi(result);
8174 switch (value) {
8175 case 1:
8176 config_val = 1;
8177 break;
8178 case 2:
8179 config_val = 3;
8180 break;
8181 case 3:
8182 config_val = 7;
8183 break;
8184 case 4:
8185 config_val = 15;
8186 break;
8187 default:
8188 config_val = 3;
8189 break;
8190 }
8191
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008192 run_iwpriv(dut, intf, "rxchainmask %d", config_val);
8193 run_iwpriv(dut, intf, "txchainmask %d", config_val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008194
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008195 }
8196
8197 /* Extract the channel width information */
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308198 result = strtok_r(NULL, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008199 if (result) {
8200 value = atoi(result);
8201 switch (value) {
8202 case 20:
8203 config_val = 0;
8204 break;
8205 case 40:
8206 config_val = 1;
8207 break;
8208 case 80:
8209 config_val = 2;
8210 break;
8211 case 160:
8212 config_val = 3;
8213 break;
8214 default:
8215 config_val = 2;
8216 break;
8217 }
8218
8219 dut->chwidth = config_val;
8220
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008221 run_iwpriv(dut, intf, "chwidth %d", config_val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008222 }
8223
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008224 run_iwpriv(dut, intf, "opmode_notify 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008225 }
8226
8227 val = get_param(cmd, "nss_mcs_cap");
8228 if (val) {
8229 int nss, mcs;
8230 char token[20];
8231 char *result = NULL;
8232 unsigned int vht_mcsmap = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308233 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008234
Peng Xub8fc5cc2017-05-10 17:27:28 -07008235 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308236 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05308237 if (!result) {
8238 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07008239 "NSS not specified");
8240 send_resp(dut, conn, SIGMA_ERROR,
8241 "errorCode,NSS not specified");
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05308242 return 0;
8243 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008244 nss = atoi(result);
8245
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008246 run_iwpriv(dut, intf, "nss %d", nss);
Arif Hussainac6c5112018-05-25 17:34:00 -07008247 dut->sta_nss = nss;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008248
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308249 result = strtok_r(NULL, ";", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008250 if (result == NULL) {
8251 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07008252 "MCS not specified");
8253 send_resp(dut, conn, SIGMA_ERROR,
8254 "errorCode,MCS not specified");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008255 return 0;
8256 }
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308257 result = strtok_r(result, "-", &saveptr);
8258 result = strtok_r(NULL, "-", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05308259 if (!result) {
8260 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07008261 "MCS not specified");
8262 send_resp(dut, conn, SIGMA_ERROR,
8263 "errorCode,MCS not specified");
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05308264 return 0;
8265 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008266 mcs = atoi(result);
8267
Arif Hussaina37e9552018-06-20 17:05:59 -07008268 if (program && strcasecmp(program, "HE") == 0) {
8269#ifdef NL80211_SUPPORT
8270 enum he_mcs_config mcs_config;
8271 int ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008272
Arif Hussaina37e9552018-06-20 17:05:59 -07008273 if (mcs >= 0 && mcs <= 7) {
8274 mcs_config = HE_80_MCS0_7;
8275 } else if (mcs > 7 && mcs <= 9) {
8276 mcs_config = HE_80_MCS0_9;
8277 } else if (mcs > 9 && mcs <= 11) {
8278 mcs_config = HE_80_MCS0_11;
8279 } else {
8280 sigma_dut_print(dut, DUT_MSG_ERROR,
8281 "nss_mcs_cap: HE: Invalid mcs: %d",
8282 mcs);
8283 send_resp(dut, conn, SIGMA_ERROR,
8284 "errorCode,Invalid MCS");
8285 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008286 }
Arif Hussaina37e9552018-06-20 17:05:59 -07008287
8288 ret = sta_set_he_mcs(dut, intf, mcs_config);
8289 if (ret) {
8290 sigma_dut_print(dut, DUT_MSG_ERROR,
8291 "nss_mcs_cap: HE: Setting of MCS failed, mcs_config: %d, ret: %d",
8292 mcs_config, ret);
8293 send_resp(dut, conn, SIGMA_ERROR,
8294 "errorCode,Failed to set MCS");
8295 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008296 }
Arif Hussaina37e9552018-06-20 17:05:59 -07008297#else /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008298 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07008299 "nss_mcs_cap: HE: MCS cannot be changed without NL80211_SUPPORT defined");
8300#endif /* NL80211_SUPPORT */
8301 } else {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008302 run_iwpriv(dut, intf, "vhtmcs %d", mcs);
Arif Hussaina37e9552018-06-20 17:05:59 -07008303
8304 switch (nss) {
8305 case 1:
8306 switch (mcs) {
8307 case 7:
8308 vht_mcsmap = 0xfffc;
8309 break;
8310 case 8:
8311 vht_mcsmap = 0xfffd;
8312 break;
8313 case 9:
8314 vht_mcsmap = 0xfffe;
8315 break;
8316 default:
8317 vht_mcsmap = 0xfffe;
8318 break;
8319 }
8320 break;
8321 case 2:
8322 switch (mcs) {
8323 case 7:
8324 vht_mcsmap = 0xfff0;
8325 break;
8326 case 8:
8327 vht_mcsmap = 0xfff5;
8328 break;
8329 case 9:
8330 vht_mcsmap = 0xfffa;
8331 break;
8332 default:
8333 vht_mcsmap = 0xfffa;
8334 break;
8335 }
8336 break;
8337 case 3:
8338 switch (mcs) {
8339 case 7:
8340 vht_mcsmap = 0xffc0;
8341 break;
8342 case 8:
8343 vht_mcsmap = 0xffd5;
8344 break;
8345 case 9:
8346 vht_mcsmap = 0xffea;
8347 break;
8348 default:
8349 vht_mcsmap = 0xffea;
8350 break;
8351 }
8352 break;
8353 default:
8354 vht_mcsmap = 0xffea;
8355 break;
8356 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008357 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008358 }
8359 }
8360
8361 /* UNSUPPORTED: val = get_param(cmd, "Tx_lgi_rate"); */
8362
8363 val = get_param(cmd, "Vht_tkip");
8364 if (val)
8365 tkip = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
8366
8367 val = get_param(cmd, "Vht_wep");
8368 if (val)
8369 wep = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
8370
8371 if (tkip != -1 || wep != -1) {
8372 if ((tkip == 1 && wep != 0) || (wep == 1 && tkip != 0)) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008373 run_iwpriv(dut, intf, "htweptkip 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008374 } else if ((tkip == 0 && wep != 1) || (wep == 0 && tkip != 1)) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008375 run_iwpriv(dut, intf, "htweptkip 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008376 } else {
8377 sigma_dut_print(dut, DUT_MSG_ERROR,
8378 "ErrorCode,mixed mode of VHT TKIP/WEP not supported");
8379 return 0;
8380 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008381 }
8382
Arif Hussain55f00da2018-07-03 08:28:26 -07008383 val = get_param(cmd, "txBandwidth");
8384 if (val) {
8385 switch (get_driver_type()) {
8386 case DRIVER_WCN:
8387 if (wcn_sta_set_width(dut, intf, val) < 0) {
8388 send_resp(dut, conn, SIGMA_ERROR,
8389 "ErrorCode,Failed to set txBandwidth");
8390 return 0;
8391 }
8392 break;
8393 case DRIVER_ATHEROS:
8394 if (ath_set_width(dut, conn, intf, val) < 0) {
8395 send_resp(dut, conn, SIGMA_ERROR,
8396 "ErrorCode,Failed to set txBandwidth");
8397 return 0;
8398 }
8399 break;
8400 default:
8401 sigma_dut_print(dut, DUT_MSG_ERROR,
8402 "Setting txBandwidth not supported");
8403 break;
8404 }
8405 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008406
Arif Hussain9765f7d2018-07-03 08:28:26 -07008407 val = get_param(cmd, "BeamformeeSTS");
8408 if (val) {
Kiran Kumar Lokerebc89d432018-07-10 12:20:13 -07008409 if (sta_set_tx_beamformee(dut, intf, 1)) {
8410 send_resp(dut, conn, SIGMA_ERROR,
8411 "ErrorCode,Failed to set TX beamformee enable");
8412 return 0;
8413 }
8414
Arif Hussain9765f7d2018-07-03 08:28:26 -07008415 if (sta_set_beamformee_sts(dut, intf, atoi(val))) {
8416 send_resp(dut, conn, SIGMA_ERROR,
8417 "ErrorCode,Failed to set BeamformeeSTS");
8418 return 0;
8419 }
8420 }
8421
Arif Hussain68d23f52018-07-11 13:39:08 -07008422 val = get_param(cmd, "Trig_MAC_Padding_Dur");
8423 if (val) {
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07008424#ifdef NL80211_SUPPORT
8425 enum qca_wlan_he_mac_padding_dur set_val;
8426
8427 switch (atoi(val)) {
8428 case 16:
8429 set_val = QCA_WLAN_HE_16US_OF_PROCESS_TIME;
8430 break;
8431 case 8:
8432 set_val = QCA_WLAN_HE_8US_OF_PROCESS_TIME;
8433 break;
8434 default:
8435 set_val = QCA_WLAN_HE_NO_ADDITIONAL_PROCESS_TIME;
8436 break;
8437 }
8438 if (sta_set_mac_padding_duration(dut, intf, set_val)) {
Arif Hussain68d23f52018-07-11 13:39:08 -07008439 send_resp(dut, conn, SIGMA_ERROR,
8440 "ErrorCode,Failed to set MAC padding duration");
8441 return 0;
8442 }
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07008443#else /* NL80211_SUPPORT */
8444 sigma_dut_print(dut, DUT_MSG_ERROR,
8445 "MAC padding duration cannot be changed without NL80211_SUPPORT defined");
8446#endif /* NL80211_SUPPORT */
Arif Hussain68d23f52018-07-11 13:39:08 -07008447 }
8448
Arif Hussain480d5f42019-03-12 14:40:42 -07008449 val = get_param(cmd, "TWT_ReqSupport");
8450 if (val) {
8451 int set_val;
8452
8453 if (strcasecmp(val, "Enable") == 0) {
8454 set_val = 1;
8455 } else if (strcasecmp(val, "Disable") == 0) {
8456 set_val = 0;
8457 } else {
8458 send_resp(dut, conn, SIGMA_ERROR,
8459 "ErrorCode,Invalid TWT_ReqSupport");
8460 return STATUS_SENT;
8461 }
8462
8463 if (sta_set_twt_req_support(dut, intf, set_val)) {
8464 sigma_dut_print(dut, DUT_MSG_ERROR,
8465 "Failed to set TWT req support %d",
8466 set_val);
8467 send_resp(dut, conn, SIGMA_ERROR,
8468 "ErrorCode,Failed to set TWT_ReqSupport");
8469 return STATUS_SENT;
8470 }
8471 }
8472
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07008473 val = get_param(cmd, "MU_EDCA");
8474 if (val && (strcasecmp(val, "Override") == 0)) {
8475 if (sta_set_mu_edca_override(dut, intf, 1)) {
8476 send_resp(dut, conn, SIGMA_ERROR,
8477 "ErrorCode,Failed to set MU EDCA override");
8478 return 0;
8479 }
8480 }
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -07008481
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07008482 val = get_param(cmd, "OMControl");
8483 if (val) {
8484 int set_val = 1;
8485
8486 if (strcasecmp(val, "Enable") == 0)
8487 set_val = 1;
8488 else if (strcasecmp(val, "Disable") == 0)
8489 set_val = 0;
8490
8491 if (sta_set_om_ctrl_supp(dut, intf, set_val)) {
8492 send_resp(dut, conn, SIGMA_ERROR,
8493 "ErrorCode,Failed to set OM ctrl supp");
8494 return 0;
8495 }
8496 }
8497
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -07008498 val = get_param(cmd, "ADDBAResp_BufSize");
8499 if (val) {
8500 int buf_size;
8501
8502 if (strcasecmp(val, "gt64") == 0)
8503 buf_size = 256;
8504 else
8505 buf_size = 64;
8506 if (get_driver_type() == DRIVER_WCN &&
8507 sta_set_addba_buf_size(dut, intf, buf_size)) {
8508 send_resp(dut, conn, SIGMA_ERROR,
8509 "ErrorCode,set addbaresp_buff_size failed");
8510 return 0;
8511 }
8512 }
8513
8514 val = get_param(cmd, "ADDBAReq_BufSize");
8515 if (val) {
8516 int buf_size;
8517
8518 if (strcasecmp(val, "gt64") == 0)
8519 buf_size = 256;
8520 else
8521 buf_size = 64;
8522 if (get_driver_type() == DRIVER_WCN &&
8523 sta_set_addba_buf_size(dut, intf, buf_size)) {
8524 send_resp(dut, conn, SIGMA_ERROR,
8525 "ErrorCode,set addbareq_buff_size failed");
8526 return 0;
8527 }
8528 }
8529
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008530 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
8531}
8532
8533
8534static int sta_set_wireless_60g(struct sigma_dut *dut,
8535 struct sigma_conn *conn,
8536 struct sigma_cmd *cmd)
8537{
8538 const char *dev_role = get_param(cmd, "DevRole");
8539
8540 if (!dev_role) {
8541 send_resp(dut, conn, SIGMA_INVALID,
8542 "ErrorCode,DevRole not specified");
8543 return 0;
8544 }
8545
8546 if (strcasecmp(dev_role, "PCP") == 0)
8547 return sta_set_60g_pcp(dut, conn, cmd);
8548 if (strcasecmp(dev_role, "STA") == 0)
8549 return sta_set_60g_sta(dut, conn, cmd);
8550 send_resp(dut, conn, SIGMA_INVALID,
8551 "ErrorCode,DevRole not supported");
8552 return 0;
8553}
8554
8555
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05308556static int sta_set_wireless_oce(struct sigma_dut *dut, struct sigma_conn *conn,
8557 struct sigma_cmd *cmd)
8558{
8559 int status;
8560 const char *intf = get_param(cmd, "Interface");
8561 const char *val = get_param(cmd, "DevRole");
8562
8563 if (val && strcasecmp(val, "STA-CFON") == 0) {
8564 status = sta_cfon_set_wireless(dut, conn, cmd);
8565 if (status)
8566 return status;
8567 }
8568 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
8569}
8570
8571
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008572static int cmd_sta_set_wireless(struct sigma_dut *dut, struct sigma_conn *conn,
8573 struct sigma_cmd *cmd)
8574{
8575 const char *val;
8576
8577 val = get_param(cmd, "Program");
8578 if (val) {
8579 if (strcasecmp(val, "11n") == 0)
8580 return cmd_sta_set_11n(dut, conn, cmd);
Amarnath Hullur Subramanyam4f860292018-01-31 03:49:35 -08008581 if (strcasecmp(val, "VHT") == 0 || strcasecmp(val, "HE") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008582 return cmd_sta_set_wireless_vht(dut, conn, cmd);
8583 if (strcasecmp(val, "60ghz") == 0)
8584 return sta_set_wireless_60g(dut, conn, cmd);
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05308585 if (strcasecmp(val, "OCE") == 0)
8586 return sta_set_wireless_oce(dut, conn, cmd);
Alexei Avshalom Lazar66bb9972018-12-18 16:01:43 +02008587 /* sta_set_wireless in WPS program is only used for 60G */
8588 if (is_60g_sigma_dut(dut))
8589 return sta_set_wireless_60g(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008590 send_resp(dut, conn, SIGMA_ERROR,
8591 "ErrorCode,Program value not supported");
8592 } else {
8593 send_resp(dut, conn, SIGMA_ERROR,
8594 "ErrorCode,Program argument not available");
8595 }
8596
8597 return 0;
8598}
8599
8600
8601static void ath_sta_inject_frame(struct sigma_dut *dut, const char *intf,
8602 int tid)
8603{
8604 char buf[100];
8605 int tid_to_dscp [] = { 0x00, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0 };
8606
Pradeep Reddy POTTETId31d1322016-10-13 17:22:03 +05308607 if (tid < 0 ||
8608 tid >= (int) (sizeof(tid_to_dscp) / sizeof(tid_to_dscp[0]))) {
8609 sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported TID: %d", tid);
8610 return;
8611 }
8612
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008613 /*
8614 * Two ways to ensure that addba request with a
8615 * non zero TID could be sent out. EV 117296
8616 */
8617 snprintf(buf, sizeof(buf),
8618 "ping -c 8 -Q %d `arp -a | grep wlan0 | awk '{print $2}' | tr -d '()'`",
8619 tid);
8620 if (system(buf) != 0) {
8621 sigma_dut_print(dut, DUT_MSG_ERROR,
8622 "Ping did not send out");
8623 }
8624
8625 snprintf(buf, sizeof(buf),
8626 "iwconfig %s | grep Access | awk '{print $6}' > %s",
8627 intf, VI_QOS_TMP_FILE);
8628 if (system(buf) != 0)
8629 return;
8630
8631 snprintf(buf, sizeof(buf),
8632 "ifconfig %s | grep HWaddr | cut -b 39-56 >> %s",
8633 intf, VI_QOS_TMP_FILE);
8634 if (system(buf) != 0)
8635 sigma_dut_print(dut, DUT_MSG_ERROR, "HWaddr matching failed");
8636
8637 snprintf(buf,sizeof(buf), "sed -n '3,$p' %s >> %s",
8638 VI_QOS_REFFILE, VI_QOS_TMP_FILE);
8639 if (system(buf) != 0) {
8640 sigma_dut_print(dut, DUT_MSG_ERROR,
8641 "VI_QOS_TEMP_FILE generation error failed");
8642 }
8643 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
8644 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
8645 if (system(buf) != 0) {
8646 sigma_dut_print(dut, DUT_MSG_ERROR,
8647 "VI_QOS_FILE generation failed");
8648 }
8649
8650 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
8651 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
8652 if (system(buf) != 0) {
8653 sigma_dut_print(dut, DUT_MSG_ERROR,
8654 "VI_QOS_FILE generation failed");
8655 }
8656
8657 snprintf(buf, sizeof(buf), "ethinject %s %s", intf, VI_QOS_FILE);
8658 if (system(buf) != 0) {
8659 }
8660}
8661
8662
8663static int ath_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
8664 struct sigma_cmd *cmd)
8665{
8666 const char *intf = get_param(cmd, "Interface");
8667 const char *val;
8668 int tid = 0;
8669 char buf[100];
8670
8671 val = get_param(cmd, "TID");
8672 if (val) {
8673 tid = atoi(val);
8674 if (tid)
8675 ath_sta_inject_frame(dut, intf, tid);
8676 }
8677
8678 /* Command sequence for ADDBA request on Peregrine based devices */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008679 run_iwpriv(dut, intf, "setaddbaoper 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008680
8681 snprintf(buf, sizeof(buf), "wifitool %s senddelba 1 %d 1 4", intf, tid);
8682 if (system(buf) != 0) {
8683 sigma_dut_print(dut, DUT_MSG_ERROR,
8684 "wifitool senddelba failed");
8685 }
8686
8687 snprintf(buf, sizeof(buf), "wifitool %s sendaddba 1 %d 64", intf, tid);
8688 if (system(buf) != 0) {
8689 sigma_dut_print(dut, DUT_MSG_ERROR,
8690 "wifitool sendaddba failed");
8691 }
8692
8693 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
8694
8695 return 1;
8696}
8697
8698
Lior David9981b512017-01-20 13:16:40 +02008699#ifdef __linux__
8700
8701static int wil6210_send_addba(struct sigma_dut *dut, const char *dest_mac,
8702 int agg_size)
8703{
8704 char dir[128], buf[128];
8705 FILE *f;
8706 regex_t re;
8707 regmatch_t m[2];
Jouni Malinen3aa72862019-05-29 23:14:51 +03008708 int rc, ret = -1, vring_id, found, res;
Lior David9981b512017-01-20 13:16:40 +02008709
8710 if (wil6210_get_debugfs_dir(dut, dir, sizeof(dir))) {
8711 sigma_dut_print(dut, DUT_MSG_ERROR,
8712 "failed to get wil6210 debugfs dir");
8713 return -1;
8714 }
8715
Jouni Malinen3aa72862019-05-29 23:14:51 +03008716 res = snprintf(buf, sizeof(buf), "%s/vrings", dir);
8717 if (res < 0 || res >= sizeof(buf))
8718 return -1;
Lior David9981b512017-01-20 13:16:40 +02008719 f = fopen(buf, "r");
8720 if (!f) {
8721 sigma_dut_print(dut, DUT_MSG_ERROR, "failed to open: %s", buf);
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +02008722 /* newer wil6210 driver renamed file to "rings" */
Jouni Malinen3aa72862019-05-29 23:14:51 +03008723 res = snprintf(buf, sizeof(buf), "%s/rings", dir);
8724 if (res < 0 || res >= sizeof(buf))
8725 return -1;
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +02008726 f = fopen(buf, "r");
8727 if (!f) {
8728 sigma_dut_print(dut, DUT_MSG_ERROR,
8729 "failed to open: %s", buf);
8730 return -1;
8731 }
Lior David9981b512017-01-20 13:16:40 +02008732 }
8733
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +02008734 /* can be either VRING tx... or RING... */
8735 if (regcomp(&re, "RING tx_[ \t]*([0-9]+)", REG_EXTENDED)) {
Lior David9981b512017-01-20 13:16:40 +02008736 sigma_dut_print(dut, DUT_MSG_ERROR, "regcomp failed");
8737 goto out;
8738 }
8739
8740 /* find TX VRING for the mac address */
8741 found = 0;
8742 while (fgets(buf, sizeof(buf), f)) {
8743 if (strcasestr(buf, dest_mac)) {
8744 found = 1;
8745 break;
8746 }
8747 }
8748
8749 if (!found) {
8750 sigma_dut_print(dut, DUT_MSG_ERROR,
8751 "no TX VRING for %s", dest_mac);
8752 goto out;
8753 }
8754
8755 /* extract VRING ID, "VRING tx_<id> = {" */
8756 if (!fgets(buf, sizeof(buf), f)) {
8757 sigma_dut_print(dut, DUT_MSG_ERROR,
8758 "no VRING start line for %s", dest_mac);
8759 goto out;
8760 }
8761
8762 rc = regexec(&re, buf, 2, m, 0);
8763 regfree(&re);
8764 if (rc || m[1].rm_so < 0) {
8765 sigma_dut_print(dut, DUT_MSG_ERROR,
8766 "no VRING TX ID for %s", dest_mac);
8767 goto out;
8768 }
8769 buf[m[1].rm_eo] = 0;
8770 vring_id = atoi(&buf[m[1].rm_so]);
8771
8772 /* send the addba command */
8773 fclose(f);
Jouni Malinen3aa72862019-05-29 23:14:51 +03008774 res = snprintf(buf, sizeof(buf), "%s/back", dir);
8775 if (res < 0 || res >= sizeof(buf))
8776 return -1;
Lior David9981b512017-01-20 13:16:40 +02008777 f = fopen(buf, "w");
8778 if (!f) {
8779 sigma_dut_print(dut, DUT_MSG_ERROR,
8780 "failed to open: %s", buf);
8781 return -1;
8782 }
8783
8784 fprintf(f, "add %d %d\n", vring_id, agg_size);
8785
8786 ret = 0;
8787
8788out:
8789 fclose(f);
8790
8791 return ret;
8792}
8793
8794
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +02008795int send_addba_60g(struct sigma_dut *dut, struct sigma_conn *conn,
8796 struct sigma_cmd *cmd, const char *mac_param)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008797{
8798 const char *val;
8799 int tid = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008800
8801 val = get_param(cmd, "TID");
8802 if (val) {
8803 tid = atoi(val);
8804 if (tid != 0) {
8805 sigma_dut_print(dut, DUT_MSG_ERROR,
8806 "Ignore TID %d for send_addba use TID 0 for 60g since only 0 required on TX",
8807 tid);
8808 }
8809 }
8810
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +02008811 val = get_param(cmd, mac_param);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008812 if (!val) {
8813 sigma_dut_print(dut, DUT_MSG_ERROR,
8814 "Currently not supporting addba for 60G without Dest_mac");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02008815 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008816 }
8817
Lior David9981b512017-01-20 13:16:40 +02008818 if (wil6210_send_addba(dut, val, dut->back_rcv_buf))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008819 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008820
8821 return 1;
8822}
8823
Lior David9981b512017-01-20 13:16:40 +02008824#endif /* __linux__ */
8825
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008826
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08008827static int wcn_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
8828 struct sigma_cmd *cmd)
8829{
8830#ifdef NL80211_SUPPORT
8831 const char *intf = get_param(cmd, "Interface");
8832 const char *val;
8833 int tid = -1;
8834 int bufsize = 64;
8835 struct nl_msg *msg;
8836 int ret = 0;
8837 struct nlattr *params;
8838 int ifindex;
8839
8840 val = get_param(cmd, "TID");
8841 if (val)
8842 tid = atoi(val);
8843
8844 if (tid == -1) {
8845 send_resp(dut, conn, SIGMA_ERROR,
8846 "ErrorCode,sta_send_addba tid invalid");
8847 return 0;
8848 }
8849
8850 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
8851
8852 ifindex = if_nametoindex(intf);
8853 if (ifindex == 0) {
8854 sigma_dut_print(dut, DUT_MSG_ERROR,
8855 "%s: Index for interface %s failed",
8856 __func__, intf);
8857 send_resp(dut, conn, SIGMA_ERROR,
8858 "ErrorCode,sta_send_addba interface invalid");
8859 return 0;
8860 }
8861
8862 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8863 NL80211_CMD_VENDOR)) ||
8864 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
8865 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
8866 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
8867 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
8868 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8869 nla_put_u8(msg,
8870 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADD_DEL_BA_SESSION,
8871 QCA_WLAN_ADD_BA) ||
8872 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BA_TID,
8873 tid) ||
Kiran Kumar Lokere26e27582018-08-01 16:18:34 -07008874 nla_put_u16(msg,
8875 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE,
8876 bufsize)) {
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08008877 sigma_dut_print(dut, DUT_MSG_ERROR,
8878 "%s: err in adding vendor_cmd and vendor_data",
8879 __func__);
8880 nlmsg_free(msg);
8881 send_resp(dut, conn, SIGMA_ERROR,
8882 "ErrorCode,sta_send_addba err in adding vendor_cmd and vendor_data");
8883 return 0;
8884 }
8885 nla_nest_end(msg, params);
8886
8887 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
8888 if (ret) {
8889 sigma_dut_print(dut, DUT_MSG_ERROR,
8890 "%s: err in send_and_recv_msgs, ret=%d",
8891 __func__, ret);
Sunil Dutt30605592018-05-04 20:35:50 +05308892 if (ret == -EOPNOTSUPP)
8893 return 1;
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08008894 send_resp(dut, conn, SIGMA_ERROR,
8895 "ErrorCode,sta_send_addba err in send_and_recv_msgs");
8896 return 0;
8897 }
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08008898#else /* NL80211_SUPPORT */
8899 sigma_dut_print(dut, DUT_MSG_ERROR,
8900 "sta_send_addba not supported without NL80211_SUPPORT defined");
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08008901#endif /* NL80211_SUPPORT */
Sunil Dutt30605592018-05-04 20:35:50 +05308902
8903 return 1;
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08008904}
8905
8906
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008907static int cmd_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
8908 struct sigma_cmd *cmd)
8909{
8910 switch (get_driver_type()) {
8911 case DRIVER_ATHEROS:
8912 return ath_sta_send_addba(dut, conn, cmd);
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08008913 case DRIVER_WCN:
8914 return wcn_sta_send_addba(dut, conn, cmd);
Lior David9981b512017-01-20 13:16:40 +02008915#ifdef __linux__
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008916 case DRIVER_WIL6210:
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +02008917 return send_addba_60g(dut, conn, cmd, "Dest_mac");
Lior David9981b512017-01-20 13:16:40 +02008918#endif /* __linux__ */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008919 default:
8920 /*
8921 * There is no driver specific implementation for other drivers.
8922 * Ignore the command and report COMPLETE since the following
8923 * throughput test operation will end up sending ADDBA anyway.
8924 */
8925 return 1;
8926 }
8927}
8928
8929
8930int inject_eth_frame(int s, const void *data, size_t len,
8931 unsigned short ethtype, char *dst, char *src)
8932{
8933 struct iovec iov[4] = {
8934 {
8935 .iov_base = dst,
8936 .iov_len = ETH_ALEN,
8937 },
8938 {
8939 .iov_base = src,
8940 .iov_len = ETH_ALEN,
8941 },
8942 {
8943 .iov_base = &ethtype,
8944 .iov_len = sizeof(unsigned short),
8945 },
8946 {
8947 .iov_base = (void *) data,
8948 .iov_len = len,
8949 }
8950 };
8951 struct msghdr msg = {
8952 .msg_name = NULL,
8953 .msg_namelen = 0,
8954 .msg_iov = iov,
8955 .msg_iovlen = 4,
8956 .msg_control = NULL,
8957 .msg_controllen = 0,
8958 .msg_flags = 0,
8959 };
8960
8961 return sendmsg(s, &msg, 0);
8962}
8963
8964#if defined(__linux__) || defined(__QNXNTO__)
8965
8966int inject_frame(int s, const void *data, size_t len, int encrypt)
8967{
8968#define IEEE80211_RADIOTAP_F_WEP 0x04
8969#define IEEE80211_RADIOTAP_F_FRAG 0x08
8970 unsigned char rtap_hdr[] = {
8971 0x00, 0x00, /* radiotap version */
8972 0x0e, 0x00, /* radiotap length */
8973 0x02, 0xc0, 0x00, 0x00, /* bmap: flags, tx and rx flags */
8974 IEEE80211_RADIOTAP_F_FRAG, /* F_FRAG (fragment if required) */
8975 0x00, /* padding */
8976 0x00, 0x00, /* RX and TX flags to indicate that */
8977 0x00, 0x00, /* this is the injected frame directly */
8978 };
8979 struct iovec iov[2] = {
8980 {
8981 .iov_base = &rtap_hdr,
8982 .iov_len = sizeof(rtap_hdr),
8983 },
8984 {
8985 .iov_base = (void *) data,
8986 .iov_len = len,
8987 }
8988 };
8989 struct msghdr msg = {
8990 .msg_name = NULL,
8991 .msg_namelen = 0,
8992 .msg_iov = iov,
8993 .msg_iovlen = 2,
8994 .msg_control = NULL,
8995 .msg_controllen = 0,
8996 .msg_flags = 0,
8997 };
8998
8999 if (encrypt)
9000 rtap_hdr[8] |= IEEE80211_RADIOTAP_F_WEP;
9001
9002 return sendmsg(s, &msg, 0);
9003}
9004
9005
9006int open_monitor(const char *ifname)
9007{
9008#ifdef __QNXNTO__
9009 struct sockaddr_dl ll;
9010 int s;
9011
9012 memset(&ll, 0, sizeof(ll));
9013 ll.sdl_family = AF_LINK;
9014 ll.sdl_index = if_nametoindex(ifname);
9015 if (ll.sdl_index == 0) {
9016 perror("if_nametoindex");
9017 return -1;
9018 }
9019 s = socket(PF_INET, SOCK_RAW, 0);
9020#else /* __QNXNTO__ */
9021 struct sockaddr_ll ll;
9022 int s;
9023
9024 memset(&ll, 0, sizeof(ll));
9025 ll.sll_family = AF_PACKET;
9026 ll.sll_ifindex = if_nametoindex(ifname);
9027 if (ll.sll_ifindex == 0) {
9028 perror("if_nametoindex");
9029 return -1;
9030 }
9031 s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
9032#endif /* __QNXNTO__ */
9033 if (s < 0) {
9034 perror("socket[PF_PACKET,SOCK_RAW]");
9035 return -1;
9036 }
9037
9038 if (bind(s, (struct sockaddr *) &ll, sizeof(ll)) < 0) {
9039 perror("monitor socket bind");
9040 close(s);
9041 return -1;
9042 }
9043
9044 return s;
9045}
9046
9047
9048static int hex2num(char c)
9049{
9050 if (c >= '0' && c <= '9')
9051 return c - '0';
9052 if (c >= 'a' && c <= 'f')
9053 return c - 'a' + 10;
9054 if (c >= 'A' && c <= 'F')
9055 return c - 'A' + 10;
9056 return -1;
9057}
9058
9059
9060int hwaddr_aton(const char *txt, unsigned char *addr)
9061{
9062 int i;
9063
9064 for (i = 0; i < 6; i++) {
9065 int a, b;
9066
9067 a = hex2num(*txt++);
9068 if (a < 0)
9069 return -1;
9070 b = hex2num(*txt++);
9071 if (b < 0)
9072 return -1;
9073 *addr++ = (a << 4) | b;
9074 if (i < 5 && *txt++ != ':')
9075 return -1;
9076 }
9077
9078 return 0;
9079}
9080
9081#endif /* defined(__linux__) || defined(__QNXNTO__) */
9082
9083enum send_frame_type {
9084 DISASSOC, DEAUTH, SAQUERY, AUTH, ASSOCREQ, REASSOCREQ, DLS_REQ
9085};
9086enum send_frame_protection {
9087 CORRECT_KEY, INCORRECT_KEY, UNPROTECTED
9088};
9089
9090
9091static int sta_inject_frame(struct sigma_dut *dut, struct sigma_conn *conn,
9092 enum send_frame_type frame,
9093 enum send_frame_protection protected,
9094 const char *dest)
9095{
9096#ifdef __linux__
9097 unsigned char buf[1000], *pos;
9098 int s, res;
9099 char bssid[20], addr[20];
9100 char result[32], ssid[100];
9101 size_t ssid_len;
9102
9103 if (get_wpa_status(get_station_ifname(), "wpa_state", result,
9104 sizeof(result)) < 0 ||
9105 strncmp(result, "COMPLETED", 9) != 0) {
9106 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Not connected");
9107 return 0;
9108 }
9109
9110 if (get_wpa_status(get_station_ifname(), "bssid", bssid, sizeof(bssid))
9111 < 0) {
9112 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
9113 "current BSSID");
9114 return 0;
9115 }
9116
9117 if (get_wpa_status(get_station_ifname(), "address", addr, sizeof(addr))
9118 < 0) {
9119 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
9120 "own MAC address");
9121 return 0;
9122 }
9123
9124 if (get_wpa_status(get_station_ifname(), "ssid", ssid, sizeof(ssid))
9125 < 0) {
9126 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
9127 "current SSID");
9128 return 0;
9129 }
9130 ssid_len = strlen(ssid);
9131
9132 pos = buf;
9133
9134 /* Frame Control */
9135 switch (frame) {
9136 case DISASSOC:
9137 *pos++ = 0xa0;
9138 break;
9139 case DEAUTH:
9140 *pos++ = 0xc0;
9141 break;
9142 case SAQUERY:
9143 *pos++ = 0xd0;
9144 break;
9145 case AUTH:
9146 *pos++ = 0xb0;
9147 break;
9148 case ASSOCREQ:
9149 *pos++ = 0x00;
9150 break;
9151 case REASSOCREQ:
9152 *pos++ = 0x20;
9153 break;
9154 case DLS_REQ:
9155 *pos++ = 0xd0;
9156 break;
9157 }
9158
9159 if (protected == INCORRECT_KEY)
9160 *pos++ = 0x40; /* Set Protected field to 1 */
9161 else
9162 *pos++ = 0x00;
9163
9164 /* Duration */
9165 *pos++ = 0x00;
9166 *pos++ = 0x00;
9167
9168 /* addr1 = DA (current AP) */
9169 hwaddr_aton(bssid, pos);
9170 pos += 6;
9171 /* addr2 = SA (own address) */
9172 hwaddr_aton(addr, pos);
9173 pos += 6;
9174 /* addr3 = BSSID (current AP) */
9175 hwaddr_aton(bssid, pos);
9176 pos += 6;
9177
9178 /* Seq# (to be filled by driver/mac80211) */
9179 *pos++ = 0x00;
9180 *pos++ = 0x00;
9181
9182 if (protected == INCORRECT_KEY) {
9183 /* CCMP parameters */
9184 memcpy(pos, "\x61\x01\x00\x20\x00\x10\x00\x00", 8);
9185 pos += 8;
9186 }
9187
9188 if (protected == INCORRECT_KEY) {
9189 switch (frame) {
9190 case DEAUTH:
9191 /* Reason code (encrypted) */
9192 memcpy(pos, "\xa7\x39", 2);
9193 pos += 2;
9194 break;
9195 case DISASSOC:
9196 /* Reason code (encrypted) */
9197 memcpy(pos, "\xa7\x39", 2);
9198 pos += 2;
9199 break;
9200 case SAQUERY:
9201 /* Category|Action|TransID (encrypted) */
9202 memcpy(pos, "\x6f\xbd\xe9\x4d", 4);
9203 pos += 4;
9204 break;
9205 default:
9206 return -1;
9207 }
9208
9209 /* CCMP MIC */
9210 memcpy(pos, "\xc8\xd8\x3b\x06\x5d\xb7\x25\x68", 8);
9211 pos += 8;
9212 } else {
9213 switch (frame) {
9214 case DEAUTH:
9215 /* reason code = 8 */
9216 *pos++ = 0x08;
9217 *pos++ = 0x00;
9218 break;
9219 case DISASSOC:
9220 /* reason code = 8 */
9221 *pos++ = 0x08;
9222 *pos++ = 0x00;
9223 break;
9224 case SAQUERY:
9225 /* Category - SA Query */
9226 *pos++ = 0x08;
9227 /* SA query Action - Request */
9228 *pos++ = 0x00;
9229 /* Transaction ID */
9230 *pos++ = 0x12;
9231 *pos++ = 0x34;
9232 break;
9233 case AUTH:
9234 /* Auth Alg (Open) */
9235 *pos++ = 0x00;
9236 *pos++ = 0x00;
9237 /* Seq# */
9238 *pos++ = 0x01;
9239 *pos++ = 0x00;
9240 /* Status code */
9241 *pos++ = 0x00;
9242 *pos++ = 0x00;
9243 break;
9244 case ASSOCREQ:
9245 /* Capability Information */
9246 *pos++ = 0x31;
9247 *pos++ = 0x04;
9248 /* Listen Interval */
9249 *pos++ = 0x0a;
9250 *pos++ = 0x00;
9251 /* SSID */
9252 *pos++ = 0x00;
9253 *pos++ = ssid_len;
9254 memcpy(pos, ssid, ssid_len);
9255 pos += ssid_len;
9256 /* Supported Rates */
9257 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
9258 10);
9259 pos += 10;
9260 /* Extended Supported Rates */
9261 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
9262 pos += 6;
9263 /* RSN */
9264 memcpy(pos, "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00"
9265 "\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x02\xc0"
9266 "\x00\x00\x00\x00\x0f\xac\x06", 28);
9267 pos += 28;
9268 break;
9269 case REASSOCREQ:
9270 /* Capability Information */
9271 *pos++ = 0x31;
9272 *pos++ = 0x04;
9273 /* Listen Interval */
9274 *pos++ = 0x0a;
9275 *pos++ = 0x00;
9276 /* Current AP */
9277 hwaddr_aton(bssid, pos);
9278 pos += 6;
9279 /* SSID */
9280 *pos++ = 0x00;
9281 *pos++ = ssid_len;
9282 memcpy(pos, ssid, ssid_len);
9283 pos += ssid_len;
9284 /* Supported Rates */
9285 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
9286 10);
9287 pos += 10;
9288 /* Extended Supported Rates */
9289 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
9290 pos += 6;
9291 /* RSN */
9292 memcpy(pos, "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00"
9293 "\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x02\xc0"
9294 "\x00\x00\x00\x00\x0f\xac\x06", 28);
9295 pos += 28;
9296 break;
9297 case DLS_REQ:
9298 /* Category - DLS */
9299 *pos++ = 0x02;
9300 /* DLS Action - Request */
9301 *pos++ = 0x00;
9302 /* Destination MACAddress */
9303 if (dest)
9304 hwaddr_aton(dest, pos);
9305 else
9306 memset(pos, 0, 6);
9307 pos += 6;
9308 /* Source MACAddress */
9309 hwaddr_aton(addr, pos);
9310 pos += 6;
9311 /* Capability Information */
9312 *pos++ = 0x10; /* Privacy */
9313 *pos++ = 0x06; /* QoS */
9314 /* DLS Timeout Value */
9315 *pos++ = 0x00;
9316 *pos++ = 0x01;
9317 /* Supported rates */
9318 *pos++ = 0x01;
9319 *pos++ = 0x08;
9320 *pos++ = 0x0c; /* 6 Mbps */
9321 *pos++ = 0x12; /* 9 Mbps */
9322 *pos++ = 0x18; /* 12 Mbps */
9323 *pos++ = 0x24; /* 18 Mbps */
9324 *pos++ = 0x30; /* 24 Mbps */
9325 *pos++ = 0x48; /* 36 Mbps */
9326 *pos++ = 0x60; /* 48 Mbps */
9327 *pos++ = 0x6c; /* 54 Mbps */
9328 /* TODO: Extended Supported Rates */
9329 /* TODO: HT Capabilities */
9330 break;
9331 }
9332 }
9333
9334 s = open_monitor("sigmadut");
9335 if (s < 0) {
9336 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
9337 "monitor socket");
9338 return 0;
9339 }
9340
9341 res = inject_frame(s, buf, pos - buf, protected == CORRECT_KEY);
9342 if (res < 0) {
9343 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
9344 "inject frame");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05309345 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009346 return 0;
9347 }
9348 if (res < pos - buf) {
9349 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Only partial "
9350 "frame sent");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05309351 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009352 return 0;
9353 }
9354
9355 close(s);
9356
9357 return 1;
9358#else /* __linux__ */
9359 send_resp(dut, conn, SIGMA_ERROR, "errorCode,sta_send_frame not "
9360 "yet supported");
9361 return 0;
9362#endif /* __linux__ */
9363}
9364
9365
9366static int cmd_sta_send_frame_tdls(struct sigma_dut *dut,
9367 struct sigma_conn *conn,
9368 struct sigma_cmd *cmd)
9369{
9370 const char *intf = get_param(cmd, "Interface");
9371 const char *sta, *val;
9372 unsigned char addr[ETH_ALEN];
9373 char buf[100];
9374
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +03009375 if (!intf)
9376 return -1;
9377
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009378 sta = get_param(cmd, "peer");
9379 if (sta == NULL)
9380 sta = get_param(cmd, "station");
9381 if (sta == NULL) {
9382 send_resp(dut, conn, SIGMA_ERROR,
9383 "ErrorCode,Missing peer address");
9384 return 0;
9385 }
9386 if (hwaddr_aton(sta, addr) < 0) {
9387 send_resp(dut, conn, SIGMA_ERROR,
9388 "ErrorCode,Invalid peer address");
9389 return 0;
9390 }
9391
9392 val = get_param(cmd, "type");
9393 if (val == NULL)
9394 return -1;
9395
9396 if (strcasecmp(val, "DISCOVERY") == 0) {
9397 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", sta);
9398 if (wpa_command(intf, buf) < 0) {
9399 send_resp(dut, conn, SIGMA_ERROR,
9400 "ErrorCode,Failed to send TDLS discovery");
9401 return 0;
9402 }
9403 return 1;
9404 }
9405
9406 if (strcasecmp(val, "SETUP") == 0) {
9407 int status = 0, timeout = 0;
9408
9409 val = get_param(cmd, "Status");
9410 if (val)
9411 status = atoi(val);
9412
9413 val = get_param(cmd, "Timeout");
9414 if (val)
9415 timeout = atoi(val);
9416
9417 if (status != 0 && status != 37) {
9418 send_resp(dut, conn, SIGMA_ERROR,
9419 "ErrorCode,Unsupported status value");
9420 return 0;
9421 }
9422
9423 if (timeout != 0 && timeout != 301) {
9424 send_resp(dut, conn, SIGMA_ERROR,
9425 "ErrorCode,Unsupported timeout value");
9426 return 0;
9427 }
9428
9429 if (status && timeout) {
9430 send_resp(dut, conn, SIGMA_ERROR,
9431 "ErrorCode,Unsupported timeout+status "
9432 "combination");
9433 return 0;
9434 }
9435
9436 if (status == 37 &&
9437 wpa_command(intf, "SET tdls_testing 0x200")) {
9438 send_resp(dut, conn, SIGMA_ERROR,
9439 "ErrorCode,Failed to enable "
9440 "decline setup response test mode");
9441 return 0;
9442 }
9443
9444 if (timeout == 301) {
9445 int res;
9446 if (dut->no_tpk_expiration)
9447 res = wpa_command(intf,
9448 "SET tdls_testing 0x108");
9449 else
9450 res = wpa_command(intf,
9451 "SET tdls_testing 0x8");
9452 if (res) {
9453 send_resp(dut, conn, SIGMA_ERROR,
9454 "ErrorCode,Failed to set short TPK "
9455 "lifetime");
9456 return 0;
9457 }
9458 }
9459
9460 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", sta);
9461 if (wpa_command(intf, buf) < 0) {
9462 send_resp(dut, conn, SIGMA_ERROR,
9463 "ErrorCode,Failed to send TDLS setup");
9464 return 0;
9465 }
9466 return 1;
9467 }
9468
9469 if (strcasecmp(val, "TEARDOWN") == 0) {
9470 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", sta);
9471 if (wpa_command(intf, buf) < 0) {
9472 send_resp(dut, conn, SIGMA_ERROR,
9473 "ErrorCode,Failed to send TDLS teardown");
9474 return 0;
9475 }
9476 return 1;
9477 }
9478
9479 send_resp(dut, conn, SIGMA_ERROR,
9480 "ErrorCode,Unsupported TDLS frame");
9481 return 0;
9482}
9483
9484
9485static int sta_ap_known(const char *ifname, const char *bssid)
9486{
9487 char buf[4096];
9488
Jouni Malinendd32f192018-09-15 02:55:19 +03009489 snprintf(buf, sizeof(buf), "BSS MASK=1 %s", bssid);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009490 if (wpa_command_resp(ifname, buf, buf, sizeof(buf)) < 0)
9491 return 0;
9492 if (strncmp(buf, "id=", 3) != 0)
9493 return 0;
9494 return 1;
9495}
9496
9497
9498static int sta_scan_ap(struct sigma_dut *dut, const char *ifname,
9499 const char *bssid)
9500{
9501 int res;
9502 struct wpa_ctrl *ctrl;
9503 char buf[256];
9504
9505 if (sta_ap_known(ifname, bssid))
9506 return 0;
9507 sigma_dut_print(dut, DUT_MSG_DEBUG,
9508 "AP not in BSS table - start scan");
9509
9510 ctrl = open_wpa_mon(ifname);
9511 if (ctrl == NULL) {
9512 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
9513 "wpa_supplicant monitor connection");
9514 return -1;
9515 }
9516
9517 if (wpa_command(ifname, "SCAN") < 0) {
9518 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to start scan");
9519 wpa_ctrl_detach(ctrl);
9520 wpa_ctrl_close(ctrl);
9521 return -1;
9522 }
9523
9524 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
9525 buf, sizeof(buf));
9526
9527 wpa_ctrl_detach(ctrl);
9528 wpa_ctrl_close(ctrl);
9529
9530 if (res < 0) {
9531 sigma_dut_print(dut, DUT_MSG_INFO, "Scan did not complete");
9532 return -1;
9533 }
9534
9535 if (sta_ap_known(ifname, bssid))
9536 return 0;
9537 sigma_dut_print(dut, DUT_MSG_INFO, "AP not in BSS table");
9538 return -1;
9539}
9540
9541
9542static int cmd_sta_send_frame_hs2_neighadv(struct sigma_dut *dut,
9543 struct sigma_conn *conn,
9544 struct sigma_cmd *cmd,
9545 const char *intf)
9546{
9547 char buf[200];
9548
9549 snprintf(buf, sizeof(buf), "ndsend 2001:DB8::1 %s", intf);
9550 if (system(buf) != 0) {
9551 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Failed to run "
9552 "ndsend");
9553 return 0;
9554 }
9555
9556 return 1;
9557}
9558
9559
9560static int cmd_sta_send_frame_hs2_neighsolreq(struct sigma_dut *dut,
9561 struct sigma_conn *conn,
9562 struct sigma_cmd *cmd,
9563 const char *intf)
9564{
9565 char buf[200];
9566 const char *ip = get_param(cmd, "SenderIP");
9567
Peng Xu26b356d2017-10-04 17:58:16 -07009568 if (!ip)
9569 return 0;
9570
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009571 snprintf(buf, sizeof(buf), "ndisc6 -nm %s %s -r 4", ip, intf);
9572 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
9573 if (system(buf) == 0) {
9574 sigma_dut_print(dut, DUT_MSG_INFO,
9575 "Neighbor Solicitation got a response "
9576 "for %s@%s", ip, intf);
9577 }
9578
9579 return 1;
9580}
9581
9582
9583static int cmd_sta_send_frame_hs2_arpprobe(struct sigma_dut *dut,
9584 struct sigma_conn *conn,
9585 struct sigma_cmd *cmd,
9586 const char *ifname)
9587{
9588 char buf[200];
9589 const char *ip = get_param(cmd, "SenderIP");
9590
9591 if (ip == NULL) {
9592 send_resp(dut, conn, SIGMA_ERROR,
9593 "ErrorCode,Missing SenderIP parameter");
9594 return 0;
9595 }
9596 snprintf(buf, sizeof(buf), "arping -I %s -D %s -c 4", ifname, ip);
9597 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
9598 if (system(buf) != 0) {
9599 sigma_dut_print(dut, DUT_MSG_INFO, "arping DAD got a response "
9600 "for %s@%s", ip, ifname);
9601 }
9602
9603 return 1;
9604}
9605
9606
9607static int cmd_sta_send_frame_hs2_arpannounce(struct sigma_dut *dut,
9608 struct sigma_conn *conn,
9609 struct sigma_cmd *cmd,
9610 const char *ifname)
9611{
9612 char buf[200];
9613 char ip[16];
9614 int s;
Peng Xub3756882017-10-04 14:39:09 -07009615 struct ifreq ifr;
9616 struct sockaddr_in saddr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009617
9618 s = socket(PF_INET, SOCK_DGRAM, 0);
Peng Xub3756882017-10-04 14:39:09 -07009619 if (s < 0) {
9620 perror("socket");
9621 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009622 }
9623
Peng Xub3756882017-10-04 14:39:09 -07009624 memset(&ifr, 0, sizeof(ifr));
9625 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
9626 if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
9627 sigma_dut_print(dut, DUT_MSG_INFO,
9628 "Failed to get %s IP address: %s",
9629 ifname, strerror(errno));
9630 close(s);
9631 return -1;
9632 }
9633 close(s);
9634
9635 memcpy(&saddr, &ifr.ifr_addr, sizeof(struct sockaddr_in));
9636 strlcpy(ip, inet_ntoa(saddr.sin_addr), sizeof(ip));
9637
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009638 snprintf(buf, sizeof(buf), "arping -I %s -s %s %s -c 4", ifname, ip,
9639 ip);
9640 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
9641 if (system(buf) != 0) {
9642 }
9643
9644 return 1;
9645}
9646
9647
9648static int cmd_sta_send_frame_hs2_arpreply(struct sigma_dut *dut,
9649 struct sigma_conn *conn,
9650 struct sigma_cmd *cmd,
9651 const char *ifname)
9652{
9653 char buf[200], addr[20];
9654 char dst[ETH_ALEN], src[ETH_ALEN];
9655 short ethtype = htons(ETH_P_ARP);
9656 char *pos;
9657 int s, res;
9658 const char *val;
9659 struct sockaddr_in taddr;
9660
9661 val = get_param(cmd, "dest");
9662 if (val)
9663 hwaddr_aton(val, (unsigned char *) dst);
9664
9665 val = get_param(cmd, "DestIP");
9666 if (val)
9667 inet_aton(val, &taddr.sin_addr);
Peng Xu151c9e12017-10-04 14:39:09 -07009668 else
9669 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009670
9671 if (get_wpa_status(get_station_ifname(), "address", addr,
9672 sizeof(addr)) < 0)
9673 return -2;
9674 hwaddr_aton(addr, (unsigned char *) src);
9675
9676 pos = buf;
9677 *pos++ = 0x00;
9678 *pos++ = 0x01;
9679 *pos++ = 0x08;
9680 *pos++ = 0x00;
9681 *pos++ = 0x06;
9682 *pos++ = 0x04;
9683 *pos++ = 0x00;
9684 *pos++ = 0x02;
9685 memcpy(pos, src, ETH_ALEN);
9686 pos += ETH_ALEN;
9687 memcpy(pos, &taddr.sin_addr, 4);
9688 pos += 4;
9689 memcpy(pos, dst, ETH_ALEN);
9690 pos += ETH_ALEN;
9691 memcpy(pos, &taddr.sin_addr, 4);
9692 pos += 4;
9693
9694 s = open_monitor(get_station_ifname());
9695 if (s < 0) {
9696 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
9697 "monitor socket");
9698 return 0;
9699 }
9700
9701 res = inject_eth_frame(s, buf, pos - buf, ethtype, dst, src);
9702 if (res < 0) {
9703 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
9704 "inject frame");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05309705 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009706 return 0;
9707 }
9708
9709 close(s);
9710
9711 return 1;
9712}
9713
9714
9715static int cmd_sta_send_frame_hs2_dls_req(struct sigma_dut *dut,
9716 struct sigma_conn *conn,
9717 struct sigma_cmd *cmd,
9718 const char *intf, const char *dest)
9719{
9720 char buf[100];
9721
9722 if (if_nametoindex("sigmadut") == 0) {
9723 snprintf(buf, sizeof(buf),
9724 "iw dev %s interface add sigmadut type monitor",
9725 get_station_ifname());
9726 if (system(buf) != 0 ||
9727 if_nametoindex("sigmadut") == 0) {
9728 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
9729 "monitor interface with '%s'", buf);
9730 return -2;
9731 }
9732 }
9733
9734 if (system("ifconfig sigmadut up") != 0) {
9735 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
9736 "monitor interface up");
9737 return -2;
9738 }
9739
9740 return sta_inject_frame(dut, conn, DLS_REQ, UNPROTECTED, dest);
9741}
9742
9743
9744static int cmd_sta_send_frame_hs2(struct sigma_dut *dut,
9745 struct sigma_conn *conn,
9746 struct sigma_cmd *cmd)
9747{
9748 const char *intf = get_param(cmd, "Interface");
9749 const char *dest = get_param(cmd, "Dest");
9750 const char *type = get_param(cmd, "FrameName");
9751 const char *val;
9752 char buf[200], *pos, *end;
9753 int count, count2;
9754
9755 if (type == NULL)
9756 type = get_param(cmd, "Type");
9757
9758 if (intf == NULL || dest == NULL || type == NULL)
9759 return -1;
9760
9761 if (strcasecmp(type, "NeighAdv") == 0)
9762 return cmd_sta_send_frame_hs2_neighadv(dut, conn, cmd, intf);
9763
9764 if (strcasecmp(type, "NeighSolicitReq") == 0)
9765 return cmd_sta_send_frame_hs2_neighsolreq(dut, conn, cmd, intf);
9766
9767 if (strcasecmp(type, "ARPProbe") == 0)
9768 return cmd_sta_send_frame_hs2_arpprobe(dut, conn, cmd, intf);
9769
9770 if (strcasecmp(type, "ARPAnnounce") == 0)
9771 return cmd_sta_send_frame_hs2_arpannounce(dut, conn, cmd, intf);
9772
9773 if (strcasecmp(type, "ARPReply") == 0)
9774 return cmd_sta_send_frame_hs2_arpreply(dut, conn, cmd, intf);
9775
9776 if (strcasecmp(type, "DLS-request") == 0 ||
9777 strcasecmp(type, "DLSrequest") == 0)
9778 return cmd_sta_send_frame_hs2_dls_req(dut, conn, cmd, intf,
9779 dest);
9780
9781 if (strcasecmp(type, "ANQPQuery") != 0 &&
9782 strcasecmp(type, "Query") != 0) {
9783 send_resp(dut, conn, SIGMA_ERROR,
9784 "ErrorCode,Unsupported HS 2.0 send frame type");
9785 return 0;
9786 }
9787
9788 if (sta_scan_ap(dut, intf, dest) < 0) {
9789 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not find "
9790 "the requested AP");
9791 return 0;
9792 }
9793
9794 pos = buf;
9795 end = buf + sizeof(buf);
9796 count = 0;
9797 pos += snprintf(pos, end - pos, "ANQP_GET %s ", dest);
9798
9799 val = get_param(cmd, "ANQP_CAP_LIST");
9800 if (val && atoi(val)) {
9801 pos += snprintf(pos, end - pos, "%s257", count > 0 ? "," : "");
9802 count++;
9803 }
9804
9805 val = get_param(cmd, "VENUE_NAME");
9806 if (val && atoi(val)) {
9807 pos += snprintf(pos, end - pos, "%s258", count > 0 ? "," : "");
9808 count++;
9809 }
9810
9811 val = get_param(cmd, "NETWORK_AUTH_TYPE");
9812 if (val && atoi(val)) {
9813 pos += snprintf(pos, end - pos, "%s260", count > 0 ? "," : "");
9814 count++;
9815 }
9816
9817 val = get_param(cmd, "ROAMING_CONS");
9818 if (val && atoi(val)) {
9819 pos += snprintf(pos, end - pos, "%s261", count > 0 ? "," : "");
9820 count++;
9821 }
9822
9823 val = get_param(cmd, "IP_ADDR_TYPE_AVAILABILITY");
9824 if (val && atoi(val)) {
9825 pos += snprintf(pos, end - pos, "%s262", count > 0 ? "," : "");
9826 count++;
9827 }
9828
9829 val = get_param(cmd, "NAI_REALM_LIST");
9830 if (val && atoi(val)) {
9831 pos += snprintf(pos, end - pos, "%s263", count > 0 ? "," : "");
9832 count++;
9833 }
9834
9835 val = get_param(cmd, "3GPP_INFO");
9836 if (val && atoi(val)) {
9837 pos += snprintf(pos, end - pos, "%s264", count > 0 ? "," : "");
9838 count++;
9839 }
9840
9841 val = get_param(cmd, "DOMAIN_LIST");
9842 if (val && atoi(val)) {
9843 pos += snprintf(pos, end - pos, "%s268", count > 0 ? "," : "");
9844 count++;
9845 }
9846
Jouni Malinen34cf9532018-04-29 19:26:33 +03009847 val = get_param(cmd, "Venue_URL");
9848 if (val && atoi(val)) {
9849 pos += snprintf(pos, end - pos, "%s277", count > 0 ? "," : "");
9850 count++;
9851 }
9852
Jouni Malinend3bca5d2018-04-29 17:25:23 +03009853 val = get_param(cmd, "Advice_Of_Charge");
9854 if (val && atoi(val)) {
9855 pos += snprintf(pos, end - pos, "%s278", count > 0 ? "," : "");
9856 count++;
9857 }
9858
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009859 if (count && wpa_command(intf, buf)) {
9860 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,ANQP_GET failed");
9861 return 0;
9862 }
9863
9864 pos = buf;
9865 end = buf + sizeof(buf);
9866 count2 = 0;
9867 pos += snprintf(pos, end - pos, "HS20_ANQP_GET %s ", dest);
9868
9869 val = get_param(cmd, "HS_CAP_LIST");
9870 if (val && atoi(val)) {
9871 pos += snprintf(pos, end - pos, "%s2", count2 > 0 ? "," : "");
9872 count2++;
9873 }
9874
9875 val = get_param(cmd, "OPER_NAME");
9876 if (val && atoi(val)) {
9877 pos += snprintf(pos, end - pos, "%s3", count2 > 0 ? "," : "");
9878 count2++;
9879 }
9880
9881 val = get_param(cmd, "WAN_METRICS");
9882 if (!val)
9883 val = get_param(cmd, "WAN_MAT");
9884 if (!val)
9885 val = get_param(cmd, "WAN_MET");
9886 if (val && atoi(val)) {
9887 pos += snprintf(pos, end - pos, "%s4", count2 > 0 ? "," : "");
9888 count2++;
9889 }
9890
9891 val = get_param(cmd, "CONNECTION_CAPABILITY");
9892 if (val && atoi(val)) {
9893 pos += snprintf(pos, end - pos, "%s5", count2 > 0 ? "," : "");
9894 count2++;
9895 }
9896
9897 val = get_param(cmd, "OP_CLASS");
9898 if (val && atoi(val)) {
9899 pos += snprintf(pos, end - pos, "%s7", count2 > 0 ? "," : "");
9900 count2++;
9901 }
9902
9903 val = get_param(cmd, "OSU_PROVIDER_LIST");
9904 if (val && atoi(val)) {
9905 pos += snprintf(pos, end - pos, "%s8", count2 > 0 ? "," : "");
9906 count2++;
9907 }
9908
Jouni Malinenf67afec2018-04-29 19:24:58 +03009909 val = get_param(cmd, "OPER_ICON_METADATA");
9910 if (!val)
9911 val = get_param(cmd, "OPERATOR_ICON_METADATA");
9912 if (val && atoi(val)) {
9913 pos += snprintf(pos, end - pos, "%s12", count2 > 0 ? "," : "");
9914 count2++;
9915 }
9916
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009917 if (count && count2) {
9918 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before sending out "
9919 "second query");
9920 sleep(1);
9921 }
9922
9923 if (count2 && wpa_command(intf, buf)) {
9924 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,HS20_ANQP_GET "
9925 "failed");
9926 return 0;
9927 }
9928
9929 val = get_param(cmd, "NAI_HOME_REALM_LIST");
9930 if (val) {
9931 if (count || count2) {
9932 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
9933 "sending out second query");
9934 sleep(1);
9935 }
9936
9937 if (strcmp(val, "1") == 0)
9938 val = "mail.example.com";
9939 snprintf(buf, end - pos,
9940 "HS20_GET_NAI_HOME_REALM_LIST %s realm=%s",
9941 dest, val);
9942 if (wpa_command(intf, buf)) {
9943 send_resp(dut, conn, SIGMA_ERROR,
9944 "ErrorCode,HS20_GET_NAI_HOME_REALM_LIST "
9945 "failed");
9946 return 0;
9947 }
9948 }
9949
9950 val = get_param(cmd, "ICON_REQUEST");
9951 if (val) {
9952 if (count || count2) {
9953 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
9954 "sending out second query");
9955 sleep(1);
9956 }
9957
9958 snprintf(buf, end - pos,
9959 "HS20_ICON_REQUEST %s %s", dest, val);
9960 if (wpa_command(intf, buf)) {
9961 send_resp(dut, conn, SIGMA_ERROR,
9962 "ErrorCode,HS20_ICON_REQUEST failed");
9963 return 0;
9964 }
9965 }
9966
9967 return 1;
9968}
9969
9970
9971static int ath_sta_send_frame_vht(struct sigma_dut *dut,
9972 struct sigma_conn *conn,
9973 struct sigma_cmd *cmd)
9974{
9975 const char *val;
9976 char *ifname;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009977 int chwidth, nss;
9978
9979 val = get_param(cmd, "framename");
9980 if (!val)
9981 return -1;
9982 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
9983
9984 /* Command sequence to generate Op mode notification */
9985 if (val && strcasecmp(val, "Op_md_notif_frm") == 0) {
9986 ifname = get_station_ifname();
9987
9988 /* Disable STBC */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07009989 run_iwpriv(dut, ifname, "tx_stbc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009990
9991 /* Extract Channel width */
9992 val = get_param(cmd, "Channel_width");
9993 if (val) {
9994 switch (atoi(val)) {
9995 case 20:
9996 chwidth = 0;
9997 break;
9998 case 40:
9999 chwidth = 1;
10000 break;
10001 case 80:
10002 chwidth = 2;
10003 break;
10004 case 160:
10005 chwidth = 3;
10006 break;
10007 default:
10008 chwidth = 2;
10009 break;
10010 }
10011
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010012 run_iwpriv(dut, ifname, "chwidth %d", chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010013 }
10014
10015 /* Extract NSS */
10016 val = get_param(cmd, "NSS");
10017 if (val) {
10018 switch (atoi(val)) {
10019 case 1:
10020 nss = 1;
10021 break;
10022 case 2:
10023 nss = 3;
10024 break;
10025 case 3:
10026 nss = 7;
10027 break;
10028 default:
10029 /* We do not support NSS > 3 */
10030 nss = 3;
10031 break;
10032 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010033 run_iwpriv(dut, ifname, "rxchainmask %d", nss);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010034 }
10035
10036 /* Opmode notify */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010037 run_iwpriv(dut, ifname, "opmode_notify 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010038 }
10039
10040 return 1;
10041}
10042
10043
10044static int cmd_sta_send_frame_vht(struct sigma_dut *dut,
10045 struct sigma_conn *conn,
10046 struct sigma_cmd *cmd)
10047{
10048 switch (get_driver_type()) {
10049 case DRIVER_ATHEROS:
10050 return ath_sta_send_frame_vht(dut, conn, cmd);
10051 default:
10052 send_resp(dut, conn, SIGMA_ERROR,
10053 "errorCode,Unsupported sta_set_frame(VHT) with the current driver");
10054 return 0;
10055 }
10056}
10057
10058
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070010059static int wcn_sta_send_frame_he(struct sigma_dut *dut, struct sigma_conn *conn,
10060 struct sigma_cmd *cmd)
10061{
10062 const char *val;
10063 const char *intf = get_param(cmd, "Interface");
10064
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +030010065 if (!intf)
10066 return -1;
10067
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070010068 val = get_param(cmd, "framename");
10069 if (!val)
10070 return -1;
10071 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
10072
10073 /* Command sequence to generate Op mode notification */
10074 if (val && strcasecmp(val, "action") == 0) {
10075 val = get_param(cmd, "PPDUTxType");
10076 if (val && strcasecmp(val, "TB") == 0) {
10077 if (sta_set_action_tx_in_he_tb_ppdu(dut, intf, 1)) {
10078 sigma_dut_print(dut, DUT_MSG_ERROR,
10079 "failed to send TB PPDU Tx cfg");
10080 send_resp(dut, conn, SIGMA_ERROR,
10081 "ErrorCode,set TB PPDU Tx cfg failed");
10082 return 0;
10083 }
10084 return 1;
10085 }
10086
10087 sigma_dut_print(dut, DUT_MSG_ERROR,
10088 "Action Tx type is not defined");
10089 }
10090
10091 return 1;
10092}
10093
10094
10095static int cmd_sta_send_frame_he(struct sigma_dut *dut,
10096 struct sigma_conn *conn,
10097 struct sigma_cmd *cmd)
10098{
10099 switch (get_driver_type()) {
10100 case DRIVER_WCN:
10101 return wcn_sta_send_frame_he(dut, conn, cmd);
10102 default:
10103 send_resp(dut, conn, SIGMA_ERROR,
10104 "errorCode,Unsupported sta_set_frame(HE) with the current driver");
10105 return 0;
10106 }
10107}
10108
10109
Lior David0fe101e2017-03-09 16:09:50 +020010110#ifdef __linux__
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030010111
10112static int
10113wil6210_send_p2p_frame_60g(struct sigma_dut *dut, struct sigma_cmd *cmd,
10114 const char *frame_name, const char *dest_mac)
10115{
10116 int isprobereq = strcasecmp(frame_name, "probereq") == 0;
10117 const char *ssid = get_param(cmd, "ssid");
10118 const char *countstr = get_param(cmd, "count");
10119 const char *channelstr = get_param(cmd, "channel");
10120 const char *group_id = get_param(cmd, "groupid");
10121 const char *client_id = get_param(cmd, "clientmac");
10122 int count, channel, freq, i;
10123 const char *fname;
10124 char frame[1024], src_mac[20], group_id_attr[25],
10125 device_macstr[3 * ETH_ALEN], client_mac[ETH_ALEN];
10126 const char *group_ssid;
10127 const int group_ssid_prefix_len = 9;
10128 struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *) frame;
10129 size_t framelen = sizeof(frame);
10130 struct template_frame_tag tags[2];
10131 size_t tags_total = ARRAY_SIZE(tags);
10132 int tag_index, len, dst_len;
10133
10134 if (!countstr || !channelstr) {
10135 sigma_dut_print(dut, DUT_MSG_ERROR,
10136 "Missing argument: count, channel");
10137 return -1;
10138 }
10139 if (isprobereq && !ssid) {
10140 sigma_dut_print(dut, DUT_MSG_ERROR,
10141 "Missing argument: ssid");
10142 return -1;
10143 }
10144 if (!isprobereq && (!group_id || !client_id)) {
10145 sigma_dut_print(dut, DUT_MSG_ERROR,
10146 "Missing argument: group_id, client_id");
10147 return -1;
10148 }
10149
10150 count = atoi(countstr);
10151 channel = atoi(channelstr);
10152 freq = channel_to_freq(dut, channel);
10153
10154 if (!freq) {
10155 sigma_dut_print(dut, DUT_MSG_ERROR,
10156 "invalid channel: %s", channelstr);
10157 return -1;
10158 }
10159
10160 if (isprobereq) {
10161 if (strcasecmp(ssid, "wildcard") == 0) {
10162 fname = "probe_req_wildcard.txt";
10163 } else if (strcasecmp(ssid, "P2P_Wildcard") == 0) {
10164 fname = "probe_req_P2P_Wildcard.txt";
10165 } else {
10166 sigma_dut_print(dut, DUT_MSG_ERROR,
10167 "invalid probe request type");
10168 return -1;
10169 }
10170 } else {
10171 fname = "P2P_device_discovery_req.txt";
10172 }
10173
10174 if (parse_template_frame_file(dut, fname, frame, &framelen,
10175 tags, &tags_total)) {
10176 sigma_dut_print(dut, DUT_MSG_ERROR,
10177 "invalid frame template: %s", fname);
10178 return -1;
10179 }
10180
10181 if (get_wpa_status(get_station_ifname(), "address",
10182 src_mac, sizeof(src_mac)) < 0 ||
10183 parse_mac_address(dut, src_mac, &hdr->addr2[0]) ||
10184 parse_mac_address(dut, dest_mac, &hdr->addr1[0]))
10185 return -1;
10186 /* Use wildcard BSSID, since we are in PBSS */
10187 memset(&hdr->addr3, 0xFF, ETH_ALEN);
10188
10189 if (!isprobereq) {
10190 tag_index = find_template_frame_tag(tags, tags_total, 1);
10191 if (tag_index < 0) {
10192 sigma_dut_print(dut, DUT_MSG_ERROR,
10193 "can't find device id attribute");
10194 return -1;
10195 }
10196 if (parse_mac_address(dut, client_id,
10197 (unsigned char *) client_mac)) {
10198 sigma_dut_print(dut, DUT_MSG_ERROR,
10199 "invalid client_id: %s", client_id);
10200 return -1;
10201 }
10202 if (replace_p2p_attribute(dut, &frame[tags[tag_index].offset],
10203 framelen - tags[tag_index].offset,
10204 IEEE80211_P2P_ATTR_DEVICE_ID,
10205 client_mac, ETH_ALEN)) {
10206 sigma_dut_print(dut, DUT_MSG_ERROR,
10207 "fail to replace device id attribute");
10208 return -1;
10209 }
10210
10211 /*
10212 * group_id arg contains device MAC address followed by
10213 * space and SSID (DIRECT-somessid).
10214 * group id attribute contains device address (6 bytes)
10215 * followed by SSID prefix DIRECT-XX (9 bytes)
10216 */
10217 if (strlen(group_id) < sizeof(device_macstr)) {
10218 sigma_dut_print(dut, DUT_MSG_ERROR,
10219 "group_id arg too short");
10220 return -1;
10221 }
10222 memcpy(device_macstr, group_id, sizeof(device_macstr));
10223 device_macstr[sizeof(device_macstr) - 1] = '\0';
10224 if (parse_mac_address(dut, device_macstr,
10225 (unsigned char *) group_id_attr)) {
10226 sigma_dut_print(dut, DUT_MSG_ERROR,
10227 "fail to parse device address from group_id");
10228 return -1;
10229 }
10230 group_ssid = strchr(group_id, ' ');
10231 if (!group_ssid) {
10232 sigma_dut_print(dut, DUT_MSG_ERROR,
10233 "invalid group_id arg, no ssid");
10234 return -1;
10235 }
10236 group_ssid++;
10237 len = strlen(group_ssid);
10238 if (len < group_ssid_prefix_len) {
10239 sigma_dut_print(dut, DUT_MSG_ERROR,
10240 "group_id SSID too short");
10241 return -1;
10242 }
10243 dst_len = sizeof(group_id_attr) - ETH_ALEN;
10244 if (len > dst_len) {
10245 sigma_dut_print(dut, DUT_MSG_ERROR,
10246 "group_id SSID (%s) too long",
10247 group_ssid);
10248 return -1;
10249 }
10250
10251 memcpy(group_id_attr + ETH_ALEN, group_ssid, len);
10252 tag_index = find_template_frame_tag(tags, tags_total, 2);
10253 if (tag_index < 0) {
10254 sigma_dut_print(dut, DUT_MSG_ERROR,
10255 "can't find group id attribute");
10256 return -1;
10257 }
10258 if (replace_p2p_attribute(dut, &frame[tags[tag_index].offset],
10259 framelen - tags[tag_index].offset,
10260 IEEE80211_P2P_ATTR_GROUP_ID,
10261 group_id_attr,
10262 sizeof(group_id_attr))) {
10263 sigma_dut_print(dut, DUT_MSG_ERROR,
10264 "fail to replace group id attribute");
10265 return -1;
10266 }
10267 }
10268
10269 for (i = 0; i < count; i++) {
10270 if (wil6210_transmit_frame(dut, freq,
10271 WIL_TRANSMIT_FRAME_DEFAULT_ROC,
10272 frame, framelen)) {
10273 sigma_dut_print(dut, DUT_MSG_ERROR,
10274 "fail to transmit probe request frame");
10275 return -1;
10276 }
10277 }
10278
10279 return 0;
10280}
10281
10282
Lior David0fe101e2017-03-09 16:09:50 +020010283int wil6210_send_frame_60g(struct sigma_dut *dut, struct sigma_conn *conn,
10284 struct sigma_cmd *cmd)
10285{
10286 const char *frame_name = get_param(cmd, "framename");
10287 const char *mac = get_param(cmd, "dest_mac");
10288
10289 if (!frame_name || !mac) {
10290 sigma_dut_print(dut, DUT_MSG_ERROR,
10291 "framename and dest_mac must be provided");
10292 return -1;
10293 }
10294
10295 if (strcasecmp(frame_name, "brp") == 0) {
10296 const char *l_rx = get_param(cmd, "L-RX");
10297 int l_rx_i;
10298
10299 if (!l_rx) {
10300 sigma_dut_print(dut, DUT_MSG_ERROR,
10301 "L-RX must be provided");
10302 return -1;
10303 }
10304 l_rx_i = atoi(l_rx);
10305
10306 sigma_dut_print(dut, DUT_MSG_INFO,
10307 "dev_send_frame: BRP-RX, dest_mac %s, L-RX %s",
10308 mac, l_rx);
10309 if (l_rx_i != 16) {
10310 sigma_dut_print(dut, DUT_MSG_ERROR,
10311 "unsupported L-RX: %s", l_rx);
10312 return -1;
10313 }
10314
10315 if (wil6210_send_brp_rx(dut, mac, l_rx_i))
10316 return -1;
10317 } else if (strcasecmp(frame_name, "ssw") == 0) {
10318 sigma_dut_print(dut, DUT_MSG_INFO,
10319 "dev_send_frame: SLS, dest_mac %s", mac);
10320 if (wil6210_send_sls(dut, mac))
10321 return -1;
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030010322 } else if ((strcasecmp(frame_name, "probereq") == 0) ||
10323 (strcasecmp(frame_name, "devdiscreq") == 0)) {
10324 sigma_dut_print(dut, DUT_MSG_INFO,
10325 "dev_send_frame: %s, dest_mac %s", frame_name,
10326 mac);
10327 if (wil6210_send_p2p_frame_60g(dut, cmd, frame_name, mac))
10328 return -1;
Lior David0fe101e2017-03-09 16:09:50 +020010329 } else {
10330 sigma_dut_print(dut, DUT_MSG_ERROR,
10331 "unsupported frame type: %s", frame_name);
10332 return -1;
10333 }
10334
10335 return 1;
10336}
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030010337
Lior David0fe101e2017-03-09 16:09:50 +020010338#endif /* __linux__ */
10339
10340
10341static int cmd_sta_send_frame_60g(struct sigma_dut *dut,
10342 struct sigma_conn *conn,
10343 struct sigma_cmd *cmd)
10344{
10345 switch (get_driver_type()) {
10346#ifdef __linux__
10347 case DRIVER_WIL6210:
10348 return wil6210_send_frame_60g(dut, conn, cmd);
10349#endif /* __linux__ */
10350 default:
10351 send_resp(dut, conn, SIGMA_ERROR,
10352 "errorCode,Unsupported sta_set_frame(60G) with the current driver");
10353 return 0;
10354 }
10355}
10356
10357
Ashwini Patildb59b3c2017-04-13 15:19:23 +053010358static int mbo_send_anqp_query(struct sigma_dut *dut, struct sigma_conn *conn,
10359 const char *intf, struct sigma_cmd *cmd)
10360{
10361 const char *val, *addr;
10362 char buf[100];
10363
10364 addr = get_param(cmd, "DestMac");
10365 if (!addr) {
10366 send_resp(dut, conn, SIGMA_INVALID,
10367 "ErrorCode,AP MAC address is missing");
10368 return 0;
10369 }
10370
10371 val = get_param(cmd, "ANQPQuery_ID");
10372 if (!val) {
10373 send_resp(dut, conn, SIGMA_INVALID,
10374 "ErrorCode,Missing ANQPQuery_ID");
10375 return 0;
10376 }
10377
10378 if (strcasecmp(val, "NeighborReportReq") == 0) {
10379 snprintf(buf, sizeof(buf), "ANQP_GET %s 272", addr);
10380 } else if (strcasecmp(val, "QueryListWithCellPref") == 0) {
10381 snprintf(buf, sizeof(buf), "ANQP_GET %s 272,mbo:2", addr);
10382 } else {
10383 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid ANQPQuery_ID: %s",
10384 val);
10385 send_resp(dut, conn, SIGMA_INVALID,
10386 "ErrorCode,Invalid ANQPQuery_ID");
10387 return 0;
10388 }
10389
Ashwini Patild174f2c2017-04-13 16:49:46 +053010390 /* Set gas_address3 field to IEEE 802.11-2012 standard compliant form
10391 * (Address3 = Wildcard BSSID when sent to not-associated AP;
10392 * if associated, AP BSSID).
10393 */
10394 if (wpa_command(intf, "SET gas_address3 1") < 0) {
10395 send_resp(dut, conn, SIGMA_ERROR,
10396 "ErrorCode,Failed to set gas_address3");
10397 return 0;
10398 }
10399
Ashwini Patildb59b3c2017-04-13 15:19:23 +053010400 if (wpa_command(intf, buf) < 0) {
10401 send_resp(dut, conn, SIGMA_ERROR,
10402 "ErrorCode,Failed to send ANQP query");
10403 return 0;
10404 }
10405
10406 return 1;
10407}
10408
10409
10410static int mbo_cmd_sta_send_frame(struct sigma_dut *dut,
10411 struct sigma_conn *conn,
10412 const char *intf,
10413 struct sigma_cmd *cmd)
10414{
10415 const char *val = get_param(cmd, "FrameName");
10416
10417 if (val && strcasecmp(val, "ANQPQuery") == 0)
10418 return mbo_send_anqp_query(dut, conn, intf, cmd);
10419
10420 return 2;
10421}
10422
10423
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010424int cmd_sta_send_frame(struct sigma_dut *dut, struct sigma_conn *conn,
10425 struct sigma_cmd *cmd)
10426{
10427 const char *intf = get_param(cmd, "Interface");
10428 const char *val;
10429 enum send_frame_type frame;
10430 enum send_frame_protection protected;
10431 char buf[100];
10432 unsigned char addr[ETH_ALEN];
10433 int res;
10434
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +030010435 if (!intf)
10436 return -1;
10437
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010438 val = get_param(cmd, "program");
10439 if (val == NULL)
10440 val = get_param(cmd, "frame");
10441 if (val && strcasecmp(val, "TDLS") == 0)
10442 return cmd_sta_send_frame_tdls(dut, conn, cmd);
10443 if (val && (strcasecmp(val, "HS2") == 0 ||
Jouni Malinen1f6ae642018-06-07 23:56:13 +030010444 strcasecmp(val, "HS2-R2") == 0 ||
10445 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010446 return cmd_sta_send_frame_hs2(dut, conn, cmd);
10447 if (val && strcasecmp(val, "VHT") == 0)
10448 return cmd_sta_send_frame_vht(dut, conn, cmd);
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070010449 if (val && strcasecmp(val, "HE") == 0)
10450 return cmd_sta_send_frame_he(dut, conn, cmd);
priyadharshini gowthamand66913a2016-07-29 15:11:17 -070010451 if (val && strcasecmp(val, "LOC") == 0)
10452 return loc_cmd_sta_send_frame(dut, conn, cmd);
Lior David0fe101e2017-03-09 16:09:50 +020010453 if (val && strcasecmp(val, "60GHz") == 0)
10454 return cmd_sta_send_frame_60g(dut, conn, cmd);
Ashwini Patildb59b3c2017-04-13 15:19:23 +053010455 if (val && strcasecmp(val, "MBO") == 0) {
10456 res = mbo_cmd_sta_send_frame(dut, conn, intf, cmd);
10457 if (res != 2)
10458 return res;
10459 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010460
10461 val = get_param(cmd, "TD_DISC");
10462 if (val) {
10463 if (hwaddr_aton(val, addr) < 0)
10464 return -1;
10465 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", val);
10466 if (wpa_command(intf, buf) < 0) {
10467 send_resp(dut, conn, SIGMA_ERROR,
10468 "ErrorCode,Failed to send TDLS discovery");
10469 return 0;
10470 }
10471 return 1;
10472 }
10473
10474 val = get_param(cmd, "TD_Setup");
10475 if (val) {
10476 if (hwaddr_aton(val, addr) < 0)
10477 return -1;
10478 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", val);
10479 if (wpa_command(intf, buf) < 0) {
10480 send_resp(dut, conn, SIGMA_ERROR,
10481 "ErrorCode,Failed to start TDLS setup");
10482 return 0;
10483 }
10484 return 1;
10485 }
10486
10487 val = get_param(cmd, "TD_TearDown");
10488 if (val) {
10489 if (hwaddr_aton(val, addr) < 0)
10490 return -1;
10491 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", val);
10492 if (wpa_command(intf, buf) < 0) {
10493 send_resp(dut, conn, SIGMA_ERROR,
10494 "ErrorCode,Failed to tear down TDLS link");
10495 return 0;
10496 }
10497 return 1;
10498 }
10499
10500 val = get_param(cmd, "TD_ChannelSwitch");
10501 if (val) {
10502 /* TODO */
10503 send_resp(dut, conn, SIGMA_ERROR,
10504 "ErrorCode,TD_ChannelSwitch not yet supported");
10505 return 0;
10506 }
10507
10508 val = get_param(cmd, "TD_NF");
10509 if (val) {
10510 /* TODO */
10511 send_resp(dut, conn, SIGMA_ERROR,
10512 "ErrorCode,TD_NF not yet supported");
10513 return 0;
10514 }
10515
10516 val = get_param(cmd, "PMFFrameType");
10517 if (val == NULL)
10518 val = get_param(cmd, "FrameName");
10519 if (val == NULL)
10520 val = get_param(cmd, "Type");
10521 if (val == NULL)
10522 return -1;
10523 if (strcasecmp(val, "disassoc") == 0)
10524 frame = DISASSOC;
10525 else if (strcasecmp(val, "deauth") == 0)
10526 frame = DEAUTH;
10527 else if (strcasecmp(val, "saquery") == 0)
10528 frame = SAQUERY;
10529 else if (strcasecmp(val, "auth") == 0)
10530 frame = AUTH;
10531 else if (strcasecmp(val, "assocreq") == 0)
10532 frame = ASSOCREQ;
10533 else if (strcasecmp(val, "reassocreq") == 0)
10534 frame = REASSOCREQ;
10535 else if (strcasecmp(val, "neigreq") == 0) {
10536 sigma_dut_print(dut, DUT_MSG_INFO, "Got neighbor request");
10537
10538 val = get_param(cmd, "ssid");
10539 if (val == NULL)
10540 return -1;
10541
10542 res = send_neighbor_request(dut, intf, val);
10543 if (res) {
10544 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
10545 "Failed to send neighbor report request");
10546 return 0;
10547 }
10548
10549 return 1;
Ashwini Patil5acd7382017-04-13 15:55:04 +053010550 } else if (strcasecmp(val, "transmgmtquery") == 0 ||
10551 strcasecmp(val, "BTMQuery") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010552 sigma_dut_print(dut, DUT_MSG_DEBUG,
10553 "Got Transition Management Query");
10554
Ashwini Patil5acd7382017-04-13 15:55:04 +053010555 res = send_trans_mgmt_query(dut, intf, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010556 if (res) {
10557 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
10558 "Failed to send Transition Management Query");
10559 return 0;
10560 }
10561
10562 return 1;
10563 } else {
10564 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
10565 "PMFFrameType");
10566 return 0;
10567 }
10568
10569 val = get_param(cmd, "PMFProtected");
10570 if (val == NULL)
10571 val = get_param(cmd, "Protected");
10572 if (val == NULL)
10573 return -1;
10574 if (strcasecmp(val, "Correct-key") == 0 ||
10575 strcasecmp(val, "CorrectKey") == 0)
10576 protected = CORRECT_KEY;
10577 else if (strcasecmp(val, "IncorrectKey") == 0)
10578 protected = INCORRECT_KEY;
10579 else if (strcasecmp(val, "Unprotected") == 0)
10580 protected = UNPROTECTED;
10581 else {
10582 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
10583 "PMFProtected");
10584 return 0;
10585 }
10586
10587 if (protected != UNPROTECTED &&
10588 (frame == AUTH || frame == ASSOCREQ || frame == REASSOCREQ)) {
10589 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Impossible "
10590 "PMFProtected for auth/assocreq/reassocreq");
10591 return 0;
10592 }
10593
10594 if (if_nametoindex("sigmadut") == 0) {
10595 snprintf(buf, sizeof(buf),
10596 "iw dev %s interface add sigmadut type monitor",
10597 get_station_ifname());
10598 if (system(buf) != 0 ||
10599 if_nametoindex("sigmadut") == 0) {
10600 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
10601 "monitor interface with '%s'", buf);
10602 return -2;
10603 }
10604 }
10605
10606 if (system("ifconfig sigmadut up") != 0) {
10607 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
10608 "monitor interface up");
10609 return -2;
10610 }
10611
10612 return sta_inject_frame(dut, conn, frame, protected, NULL);
10613}
10614
10615
10616static int cmd_sta_set_parameter_hs2(struct sigma_dut *dut,
10617 struct sigma_conn *conn,
10618 struct sigma_cmd *cmd,
10619 const char *ifname)
10620{
10621 char buf[200];
10622 const char *val;
10623
10624 val = get_param(cmd, "ClearARP");
10625 if (val && atoi(val) == 1) {
10626 snprintf(buf, sizeof(buf), "ip neigh flush dev %s", ifname);
10627 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10628 if (system(buf) != 0) {
10629 send_resp(dut, conn, SIGMA_ERROR,
10630 "errorCode,Failed to clear ARP cache");
10631 return 0;
10632 }
10633 }
10634
10635 return 1;
10636}
10637
10638
10639int cmd_sta_set_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
10640 struct sigma_cmd *cmd)
10641{
10642 const char *intf = get_param(cmd, "Interface");
10643 const char *val;
10644
10645 if (intf == NULL)
10646 return -1;
10647
10648 val = get_param(cmd, "program");
10649 if (val && (strcasecmp(val, "HS2") == 0 ||
Jouni Malinen1f6ae642018-06-07 23:56:13 +030010650 strcasecmp(val, "HS2-R2") == 0 ||
10651 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010652 return cmd_sta_set_parameter_hs2(dut, conn, cmd, intf);
10653
10654 return -1;
10655}
10656
10657
10658static int cmd_sta_set_macaddr(struct sigma_dut *dut, struct sigma_conn *conn,
10659 struct sigma_cmd *cmd)
10660{
10661 const char *intf = get_param(cmd, "Interface");
10662 const char *mac = get_param(cmd, "MAC");
10663
10664 if (intf == NULL || mac == NULL)
10665 return -1;
10666
10667 sigma_dut_print(dut, DUT_MSG_INFO, "Change local MAC address for "
10668 "interface %s to %s", intf, mac);
10669
10670 if (dut->set_macaddr) {
10671 char buf[128];
10672 int res;
10673 if (strcasecmp(mac, "default") == 0) {
10674 res = snprintf(buf, sizeof(buf), "%s",
10675 dut->set_macaddr);
10676 dut->tmp_mac_addr = 0;
10677 } else {
10678 res = snprintf(buf, sizeof(buf), "%s %s",
10679 dut->set_macaddr, mac);
10680 dut->tmp_mac_addr = 1;
10681 }
10682 if (res < 0 || res >= (int) sizeof(buf))
10683 return -1;
10684 if (system(buf) != 0) {
10685 send_resp(dut, conn, SIGMA_ERROR,
10686 "errorCode,Failed to set MAC "
10687 "address");
10688 return 0;
10689 }
10690 return 1;
10691 }
10692
10693 if (strcasecmp(mac, "default") == 0)
10694 return 1;
10695
10696 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
10697 "command");
10698 return 0;
10699}
10700
10701
10702static int iwpriv_tdlsoffchnmode(struct sigma_dut *dut,
10703 struct sigma_conn *conn, const char *intf,
10704 int val)
10705{
10706 char buf[200];
10707 int res;
10708
10709 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchnmode %d",
10710 intf, val);
10711 if (res < 0 || res >= (int) sizeof(buf))
10712 return -1;
10713 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10714 if (system(buf) != 0) {
10715 send_resp(dut, conn, SIGMA_ERROR,
10716 "errorCode,Failed to configure offchannel mode");
10717 return 0;
10718 }
10719
10720 return 1;
10721}
10722
10723
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010724static int off_chan_val(enum sec_ch_offset off)
10725{
10726 switch (off) {
10727 case SEC_CH_NO:
10728 return 0;
10729 case SEC_CH_40ABOVE:
10730 return 40;
10731 case SEC_CH_40BELOW:
10732 return -40;
10733 }
10734
10735 return 0;
10736}
10737
10738
10739static int iwpriv_set_offchan(struct sigma_dut *dut, struct sigma_conn *conn,
10740 const char *intf, int off_ch_num,
10741 enum sec_ch_offset sec)
10742{
10743 char buf[200];
10744 int res;
10745
10746 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchan %d",
10747 intf, off_ch_num);
10748 if (res < 0 || res >= (int) sizeof(buf))
10749 return -1;
10750 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10751 if (system(buf) != 0) {
10752 send_resp(dut, conn, SIGMA_ERROR,
10753 "errorCode,Failed to set offchan");
10754 return 0;
10755 }
10756
10757 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsecchnoffst %d",
10758 intf, off_chan_val(sec));
10759 if (res < 0 || res >= (int) sizeof(buf))
10760 return -1;
10761 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10762 if (system(buf) != 0) {
10763 send_resp(dut, conn, SIGMA_ERROR,
10764 "errorCode,Failed to set sec chan offset");
10765 return 0;
10766 }
10767
10768 return 1;
10769}
10770
10771
10772static int tdls_set_offchannel_offset(struct sigma_dut *dut,
10773 struct sigma_conn *conn,
10774 const char *intf, int off_ch_num,
10775 enum sec_ch_offset sec)
10776{
10777 char buf[200];
10778 int res;
10779
10780 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNEL %d",
10781 off_ch_num);
10782 if (res < 0 || res >= (int) sizeof(buf))
10783 return -1;
10784 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10785
10786 if (wpa_command(intf, buf) < 0) {
10787 send_resp(dut, conn, SIGMA_ERROR,
10788 "ErrorCode,Failed to set offchan");
10789 return 0;
10790 }
10791 res = snprintf(buf, sizeof(buf), "DRIVER TDLSSECONDARYCHANNELOFFSET %d",
10792 off_chan_val(sec));
10793 if (res < 0 || res >= (int) sizeof(buf))
10794 return -1;
10795
10796 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10797
10798 if (wpa_command(intf, buf) < 0) {
10799 send_resp(dut, conn, SIGMA_ERROR,
10800 "ErrorCode,Failed to set sec chan offset");
10801 return 0;
10802 }
10803
10804 return 1;
10805}
10806
10807
10808static int tdls_set_offchannel_mode(struct sigma_dut *dut,
10809 struct sigma_conn *conn,
10810 const char *intf, int val)
10811{
10812 char buf[200];
10813 int res;
10814
10815 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNELMODE %d",
10816 val);
10817 if (res < 0 || res >= (int) sizeof(buf))
10818 return -1;
10819 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10820
10821 if (wpa_command(intf, buf) < 0) {
10822 send_resp(dut, conn, SIGMA_ERROR,
10823 "ErrorCode,Failed to configure offchannel mode");
10824 return 0;
10825 }
10826
10827 return 1;
10828}
10829
10830
10831static int cmd_sta_set_rfeature_tdls(const char *intf, struct sigma_dut *dut,
10832 struct sigma_conn *conn,
10833 struct sigma_cmd *cmd)
10834{
10835 const char *val;
10836 enum {
10837 CHSM_NOT_SET,
10838 CHSM_ENABLE,
10839 CHSM_DISABLE,
10840 CHSM_REJREQ,
10841 CHSM_UNSOLRESP
10842 } chsm = CHSM_NOT_SET;
10843 int off_ch_num = -1;
10844 enum sec_ch_offset sec_ch = SEC_CH_NO;
10845 int res;
10846
10847 val = get_param(cmd, "Uapsd");
10848 if (val) {
10849 char buf[100];
10850 if (strcasecmp(val, "Enable") == 0)
10851 snprintf(buf, sizeof(buf), "SET ps 99");
10852 else if (strcasecmp(val, "Disable") == 0)
10853 snprintf(buf, sizeof(buf), "SET ps 98");
10854 else {
10855 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
10856 "Unsupported uapsd parameter value");
10857 return 0;
10858 }
10859 if (wpa_command(intf, buf)) {
10860 send_resp(dut, conn, SIGMA_ERROR,
10861 "ErrorCode,Failed to change U-APSD "
10862 "powersave mode");
10863 return 0;
10864 }
10865 }
10866
10867 val = get_param(cmd, "TPKTIMER");
10868 if (val && strcasecmp(val, "DISABLE") == 0) {
10869 if (wpa_command(intf, "SET tdls_testing 0x100")) {
10870 send_resp(dut, conn, SIGMA_ERROR,
10871 "ErrorCode,Failed to enable no TPK "
10872 "expiration test mode");
10873 return 0;
10874 }
10875 dut->no_tpk_expiration = 1;
10876 }
10877
10878 val = get_param(cmd, "ChSwitchMode");
10879 if (val) {
10880 if (strcasecmp(val, "Enable") == 0 ||
10881 strcasecmp(val, "Initiate") == 0)
10882 chsm = CHSM_ENABLE;
10883 else if (strcasecmp(val, "Disable") == 0 ||
10884 strcasecmp(val, "passive") == 0)
10885 chsm = CHSM_DISABLE;
10886 else if (strcasecmp(val, "RejReq") == 0)
10887 chsm = CHSM_REJREQ;
10888 else if (strcasecmp(val, "UnSolResp") == 0)
10889 chsm = CHSM_UNSOLRESP;
10890 else {
10891 send_resp(dut, conn, SIGMA_ERROR,
10892 "ErrorCode,Unknown ChSwitchMode value");
10893 return 0;
10894 }
10895 }
10896
10897 val = get_param(cmd, "OffChNum");
10898 if (val) {
10899 off_ch_num = atoi(val);
10900 if (off_ch_num == 0) {
10901 send_resp(dut, conn, SIGMA_ERROR,
10902 "ErrorCode,Invalid OffChNum");
10903 return 0;
10904 }
10905 }
10906
10907 val = get_param(cmd, "SecChOffset");
10908 if (val) {
10909 if (strcmp(val, "20") == 0)
10910 sec_ch = SEC_CH_NO;
10911 else if (strcasecmp(val, "40above") == 0)
10912 sec_ch = SEC_CH_40ABOVE;
10913 else if (strcasecmp(val, "40below") == 0)
10914 sec_ch = SEC_CH_40BELOW;
10915 else {
10916 send_resp(dut, conn, SIGMA_ERROR,
10917 "ErrorCode,Unknown SecChOffset value");
10918 return 0;
10919 }
10920 }
10921
10922 if (chsm == CHSM_NOT_SET) {
10923 /* no offchannel changes requested */
10924 return 1;
10925 }
10926
10927 if (strcmp(intf, get_main_ifname()) != 0 &&
10928 strcmp(intf, get_station_ifname()) != 0) {
10929 send_resp(dut, conn, SIGMA_ERROR,
10930 "ErrorCode,Unknown interface");
10931 return 0;
10932 }
10933
10934 switch (chsm) {
10935 case CHSM_NOT_SET:
Jouni Malinen280f5ba2016-08-29 21:33:10 +030010936 res = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010937 break;
10938 case CHSM_ENABLE:
10939 if (off_ch_num < 0) {
10940 send_resp(dut, conn, SIGMA_ERROR,
10941 "ErrorCode,Missing OffChNum argument");
10942 return 0;
10943 }
10944 if (wifi_chip_type == DRIVER_WCN) {
10945 res = tdls_set_offchannel_offset(dut, conn, intf,
10946 off_ch_num, sec_ch);
10947 } else {
10948 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
10949 sec_ch);
10950 }
10951 if (res != 1)
10952 return res;
10953 if (wifi_chip_type == DRIVER_WCN)
10954 res = tdls_set_offchannel_mode(dut, conn, intf, 1);
10955 else
10956 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 1);
10957 break;
10958 case CHSM_DISABLE:
10959 if (wifi_chip_type == DRIVER_WCN)
10960 res = tdls_set_offchannel_mode(dut, conn, intf, 2);
10961 else
10962 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 2);
10963 break;
10964 case CHSM_REJREQ:
10965 if (wifi_chip_type == DRIVER_WCN)
10966 res = tdls_set_offchannel_mode(dut, conn, intf, 3);
10967 else
10968 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 3);
10969 break;
10970 case CHSM_UNSOLRESP:
10971 if (off_ch_num < 0) {
10972 send_resp(dut, conn, SIGMA_ERROR,
10973 "ErrorCode,Missing OffChNum argument");
10974 return 0;
10975 }
10976 if (wifi_chip_type == DRIVER_WCN) {
10977 res = tdls_set_offchannel_offset(dut, conn, intf,
10978 off_ch_num, sec_ch);
10979 } else {
10980 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
10981 sec_ch);
10982 }
10983 if (res != 1)
10984 return res;
10985 if (wifi_chip_type == DRIVER_WCN)
10986 res = tdls_set_offchannel_mode(dut, conn, intf, 4);
10987 else
10988 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 4);
10989 break;
10990 }
10991
10992 return res;
10993}
10994
10995
10996static int ath_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
10997 struct sigma_conn *conn,
10998 struct sigma_cmd *cmd)
10999{
11000 const char *val;
Srikanth Marepalli5415acf2018-08-27 12:53:11 +053011001 char *token = NULL, *result;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011002
priyadharshini gowthamane5e25172015-12-08 14:53:48 -080011003 novap_reset(dut, intf);
11004
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011005 val = get_param(cmd, "nss_mcs_opt");
11006 if (val) {
11007 /* String (nss_operating_mode; mcs_operating_mode) */
11008 int nss, mcs;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053011009 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011010
11011 token = strdup(val);
11012 if (!token)
11013 return 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053011014 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +053011015 if (!result) {
11016 sigma_dut_print(dut, DUT_MSG_ERROR,
11017 "VHT NSS not specified");
11018 goto failed;
11019 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011020 if (strcasecmp(result, "def") != 0) {
11021 nss = atoi(result);
11022 if (nss == 4)
11023 ath_disable_txbf(dut, intf);
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011024 if (run_iwpriv(dut, intf, "nss %d", nss) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011025 goto failed;
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011026
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011027 }
11028
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053011029 result = strtok_r(NULL, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +053011030 if (!result) {
11031 sigma_dut_print(dut, DUT_MSG_ERROR,
11032 "VHT MCS not specified");
11033 goto failed;
11034 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011035 if (strcasecmp(result, "def") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011036 if (run_iwpriv(dut, intf, "set11NRates 0") < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011037 goto failed;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011038 } else {
11039 mcs = atoi(result);
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011040 if (run_iwpriv(dut, intf, "vhtmcs %d", mcs) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011041 goto failed;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011042 }
11043 /* Channel width gets messed up, fix this */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011044 run_iwpriv(dut, intf, "chwidth %d", dut->chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011045 }
11046
Srikanth Marepalli5415acf2018-08-27 12:53:11 +053011047 free(token);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011048 return 1;
11049failed:
11050 free(token);
11051 return 0;
11052}
11053
11054
11055static int cmd_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
11056 struct sigma_conn *conn,
11057 struct sigma_cmd *cmd)
11058{
11059 switch (get_driver_type()) {
11060 case DRIVER_ATHEROS:
11061 return ath_sta_set_rfeature_vht(intf, dut, conn, cmd);
11062 default:
11063 send_resp(dut, conn, SIGMA_ERROR,
11064 "errorCode,Unsupported sta_set_rfeature(VHT) with the current driver");
11065 return 0;
11066 }
11067}
11068
11069
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011070static int wcn_sta_set_rfeature_he(const char *intf, struct sigma_dut *dut,
11071 struct sigma_conn *conn,
11072 struct sigma_cmd *cmd)
11073{
11074 const char *val;
11075 char *token = NULL, *result;
11076 char buf[60];
11077
11078 val = get_param(cmd, "nss_mcs_opt");
11079 if (val) {
11080 /* String (nss_operating_mode; mcs_operating_mode) */
11081 int nss, mcs, ratecode;
11082 char *saveptr;
11083
11084 token = strdup(val);
11085 if (!token)
11086 return -2;
11087
11088 result = strtok_r(token, ";", &saveptr);
11089 if (!result) {
11090 sigma_dut_print(dut, DUT_MSG_ERROR,
11091 "HE NSS not specified");
11092 goto failed;
11093 }
11094 nss = 1;
11095 if (strcasecmp(result, "def") != 0)
11096 nss = atoi(result);
11097
11098 result = strtok_r(NULL, ";", &saveptr);
11099 if (!result) {
11100 sigma_dut_print(dut, DUT_MSG_ERROR,
11101 "HE MCS not specified");
11102 goto failed;
11103 }
11104 mcs = 7;
11105 if (strcasecmp(result, "def") != 0)
11106 mcs = atoi(result);
11107
Arif Hussain557bf412018-05-25 17:29:36 -070011108 ratecode = 0x20; /* for nss:1 MCS 0 */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011109 if (nss == 2) {
Arif Hussain557bf412018-05-25 17:29:36 -070011110 ratecode = 0x40; /* for nss:2 MCS 0 */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011111 } else if (nss > 2) {
11112 sigma_dut_print(dut, DUT_MSG_ERROR,
11113 "HE NSS %d not supported", nss);
11114 goto failed;
11115 }
11116
Arif Hussain557bf412018-05-25 17:29:36 -070011117 snprintf(buf, sizeof(buf), "iwpriv %s nss %d", intf, nss);
11118 if (system(buf) != 0) {
11119 sigma_dut_print(dut, DUT_MSG_ERROR,
11120 "nss_mcs_opt: iwpriv %s nss %d failed",
11121 intf, nss);
11122 goto failed;
11123 }
Arif Hussainac6c5112018-05-25 17:34:00 -070011124 dut->sta_nss = nss;
Arif Hussain557bf412018-05-25 17:29:36 -070011125
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011126 /* Add the MCS to the ratecode */
11127 if (mcs >= 0 && mcs <= 11) {
11128 ratecode += mcs;
Arif Hussain557bf412018-05-25 17:29:36 -070011129#ifdef NL80211_SUPPORT
11130 if (dut->device_type == STA_testbed) {
11131 enum he_mcs_config mcs_config;
11132 int ret;
11133
11134 if (mcs <= 7)
11135 mcs_config = HE_80_MCS0_7;
11136 else if (mcs <= 9)
11137 mcs_config = HE_80_MCS0_9;
11138 else
11139 mcs_config = HE_80_MCS0_11;
11140 ret = sta_set_he_mcs(dut, intf, mcs_config);
11141 if (ret) {
11142 sigma_dut_print(dut, DUT_MSG_ERROR,
11143 "nss_mcs_opt: mcs setting failed, mcs:%d, mcs_config %d, ret:%d",
11144 mcs, mcs_config, ret);
11145 goto failed;
11146 }
11147 }
11148#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011149 } else {
11150 sigma_dut_print(dut, DUT_MSG_ERROR,
11151 "HE MCS %d not supported", mcs);
11152 goto failed;
11153 }
11154 snprintf(buf, sizeof(buf), "iwpriv %s set_11ax_rate 0x%03x",
11155 intf, ratecode);
11156 if (system(buf) != 0) {
11157 sigma_dut_print(dut, DUT_MSG_ERROR,
11158 "iwpriv setting of 11ax rates failed");
11159 goto failed;
11160 }
11161 free(token);
11162 }
11163
11164 val = get_param(cmd, "GI");
11165 if (val) {
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011166 int fix_rate_sgi;
11167
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011168 if (strcmp(val, "0.8") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070011169 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 9", intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011170 fix_rate_sgi = 1;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011171 } else if (strcmp(val, "1.6") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070011172 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 10",
11173 intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011174 fix_rate_sgi = 2;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011175 } else if (strcmp(val, "3.2") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070011176 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 11",
11177 intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011178 fix_rate_sgi = 3;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011179 } else {
11180 send_resp(dut, conn, SIGMA_ERROR,
11181 "errorCode,GI value not supported");
11182 return 0;
11183 }
11184 if (system(buf) != 0) {
11185 send_resp(dut, conn, SIGMA_ERROR,
11186 "errorCode,Failed to set shortgi");
11187 return 0;
11188 }
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011189 snprintf(buf, sizeof(buf), "iwpriv %s shortgi %d",
11190 intf, fix_rate_sgi);
11191 if (system(buf) != 0) {
11192 send_resp(dut, conn, SIGMA_ERROR,
11193 "errorCode,Failed to set fix rate shortgi");
11194 return STATUS_SENT;
11195 }
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011196 }
11197
Subhani Shaik8e7a3052018-04-24 14:03:00 -070011198 val = get_param(cmd, "LTF");
11199 if (val) {
11200#ifdef NL80211_SUPPORT
11201 if (strcmp(val, "3.2") == 0) {
11202 sta_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_1X);
11203 } if (strcmp(val, "6.4") == 0) {
11204 sta_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_2X);
11205 } else if (strcmp(val, "12.8") == 0) {
11206 sta_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_4X);
11207 } else {
11208 send_resp(dut, conn, SIGMA_ERROR,
11209 "errorCode, LTF value not supported");
11210 return 0;
11211 }
11212#else /* NL80211_SUPPORT */
11213 sigma_dut_print(dut, DUT_MSG_ERROR,
11214 "LTF cannot be set without NL80211_SUPPORT defined");
11215 return -2;
11216#endif /* NL80211_SUPPORT */
11217 }
11218
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -070011219 val = get_param(cmd, "TxSUPPDU");
11220 if (val) {
11221 int set_val = 1;
11222
11223 if (strcasecmp(val, "Enable") == 0)
11224 set_val = 1;
11225 else if (strcasecmp(val, "Disable") == 0)
11226 set_val = 0;
11227
11228 if (sta_set_tx_su_ppdu_cfg(dut, intf, set_val)) {
11229 send_resp(dut, conn, SIGMA_ERROR,
11230 "ErrorCode,Failed to set Tx SU PPDU config");
11231 return 0;
11232 }
11233 }
11234
Arif Hussain480d5f42019-03-12 14:40:42 -070011235 val = get_param(cmd, "TWT_Setup");
11236 if (val) {
11237 if (strcasecmp(val, "Request") == 0) {
11238 if (sta_twt_request(dut, conn, cmd)) {
11239 send_resp(dut, conn, SIGMA_ERROR,
11240 "ErrorCode,sta_twt_request failed");
11241 return STATUS_SENT;
11242 }
11243 } else if (strcasecmp(val, "Teardown") == 0) {
11244 if (sta_twt_teardown(dut, conn, cmd)) {
11245 send_resp(dut, conn, SIGMA_ERROR,
11246 "ErrorCode,sta_twt_teardown failed");
11247 return STATUS_SENT;
11248 }
11249 }
11250 }
11251
Kiran Kumar Lokere50eb2cd2018-12-18 18:31:28 -080011252 val = get_param(cmd, "transmitOMI");
11253 if (val && sta_transmit_omi(dut, conn, cmd)) {
11254 send_resp(dut, conn, SIGMA_ERROR,
11255 "ErrorCode,sta_transmit_omi failed");
11256 return STATUS_SENT;
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -070011257 }
11258
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080011259 val = get_param(cmd, "Powersave");
11260 if (val) {
11261 char buf[60];
11262
11263 if (strcasecmp(val, "off") == 0) {
11264 snprintf(buf, sizeof(buf),
11265 "iwpriv %s setPower 2", intf);
11266 if (system(buf) != 0) {
11267 sigma_dut_print(dut, DUT_MSG_ERROR,
11268 "iwpriv setPower 2 failed");
11269 return 0;
11270 }
11271 } else if (strcasecmp(val, "on") == 0) {
11272 snprintf(buf, sizeof(buf),
11273 "iwpriv %s setPower 1", intf);
11274 if (system(buf) != 0) {
11275 sigma_dut_print(dut, DUT_MSG_ERROR,
11276 "iwpriv setPower 1 failed");
11277 return 0;
11278 }
11279 } else {
11280 sigma_dut_print(dut, DUT_MSG_ERROR,
11281 "Unsupported Powersave value '%s'",
11282 val);
11283 return -1;
11284 }
11285 }
11286
Kiran Kumar Lokere2c4b7ce2019-01-30 12:02:28 -080011287 val = get_param(cmd, "MU_EDCA");
11288 if (val) {
11289 if (strcasecmp(val, "Override") == 0) {
11290 if (sta_set_mu_edca_override(dut, intf, 1)) {
11291 send_resp(dut, conn, SIGMA_ERROR,
11292 "errorCode,MU EDCA override set failed");
11293 return STATUS_SENT;
11294 }
11295 } else if (strcasecmp(val, "Disable") == 0) {
11296 if (sta_set_mu_edca_override(dut, intf, 0)) {
11297 send_resp(dut, conn, SIGMA_ERROR,
11298 "errorCode,MU EDCA override disable failed");
11299 return STATUS_SENT;
11300 }
11301 }
11302 }
11303
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011304 return 1;
11305
11306failed:
11307 free(token);
11308 return -2;
11309}
11310
11311
11312static int cmd_sta_set_rfeature_he(const char *intf, struct sigma_dut *dut,
11313 struct sigma_conn *conn,
11314 struct sigma_cmd *cmd)
11315{
11316 switch (get_driver_type()) {
11317 case DRIVER_WCN:
11318 return wcn_sta_set_rfeature_he(intf, dut, conn, cmd);
11319 default:
11320 send_resp(dut, conn, SIGMA_ERROR,
11321 "errorCode,Unsupported sta_set_rfeature(HE) with the current driver");
11322 return 0;
11323 }
11324}
11325
11326
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080011327static int cmd_sta_set_power_save_he(const char *intf, struct sigma_dut *dut,
11328 struct sigma_conn *conn,
11329 struct sigma_cmd *cmd)
11330{
11331 const char *val;
11332
11333 val = get_param(cmd, "powersave");
11334 if (val) {
11335 char buf[60];
11336
11337 if (strcasecmp(val, "off") == 0) {
11338 snprintf(buf, sizeof(buf), "iwpriv %s setPower 2",
11339 intf);
11340 if (system(buf) != 0) {
11341 sigma_dut_print(dut, DUT_MSG_ERROR,
11342 "iwpriv setPower 2 failed");
11343 return 0;
11344 }
11345 } else if (strcasecmp(val, "on") == 0) {
11346 snprintf(buf, sizeof(buf), "iwpriv %s setPower 1",
11347 intf);
11348 if (system(buf) != 0) {
11349 sigma_dut_print(dut, DUT_MSG_ERROR,
11350 "iwpriv setPower 1 failed");
11351 return 0;
11352 }
11353 } else {
11354 sigma_dut_print(dut, DUT_MSG_ERROR,
11355 "Unsupported power save config");
11356 return -1;
11357 }
11358 return 1;
11359 }
11360
11361 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported command");
11362
11363 return 0;
11364}
11365
11366
Ashwini Patil5acd7382017-04-13 15:55:04 +053011367static int btm_query_candidate_list(struct sigma_dut *dut,
11368 struct sigma_conn *conn,
11369 struct sigma_cmd *cmd)
11370{
11371 const char *bssid, *info, *op_class, *ch, *phy_type, *pref;
11372 int len, ret;
11373 char buf[10];
11374
11375 /*
11376 * Neighbor Report elements format:
11377 * neighbor=<BSSID>,<BSSID Information>,<Operating Class>,
11378 * <Channel Number>,<PHY Type>[,<hexdump of Optional Subelements>]
11379 * eg: neighbor=aa:bb:cc:dd:ee:ff,17,81,6,1,030101
11380 */
11381
11382 bssid = get_param(cmd, "Nebor_BSSID");
11383 if (!bssid) {
11384 send_resp(dut, conn, SIGMA_INVALID,
11385 "errorCode,Nebor_BSSID is missing");
11386 return 0;
11387 }
11388
11389 info = get_param(cmd, "Nebor_Bssid_Info");
11390 if (!info) {
11391 sigma_dut_print(dut, DUT_MSG_INFO,
11392 "Using default value for Nebor_Bssid_Info: %s",
11393 DEFAULT_NEIGHBOR_BSSID_INFO);
11394 info = DEFAULT_NEIGHBOR_BSSID_INFO;
11395 }
11396
11397 op_class = get_param(cmd, "Nebor_Op_Class");
11398 if (!op_class) {
11399 send_resp(dut, conn, SIGMA_INVALID,
11400 "errorCode,Nebor_Op_Class is missing");
11401 return 0;
11402 }
11403
11404 ch = get_param(cmd, "Nebor_Op_Ch");
11405 if (!ch) {
11406 send_resp(dut, conn, SIGMA_INVALID,
11407 "errorCode,Nebor_Op_Ch is missing");
11408 return 0;
11409 }
11410
11411 phy_type = get_param(cmd, "Nebor_Phy_Type");
11412 if (!phy_type) {
11413 sigma_dut_print(dut, DUT_MSG_INFO,
11414 "Using default value for Nebor_Phy_Type: %s",
11415 DEFAULT_NEIGHBOR_PHY_TYPE);
11416 phy_type = DEFAULT_NEIGHBOR_PHY_TYPE;
11417 }
11418
11419 /* Parse optional subelements */
11420 buf[0] = '\0';
11421 pref = get_param(cmd, "Nebor_Pref");
11422 if (pref) {
11423 /* hexdump for preferrence subelement */
11424 ret = snprintf(buf, sizeof(buf), ",0301%02x", atoi(pref));
11425 if (ret < 0 || ret >= (int) sizeof(buf)) {
11426 sigma_dut_print(dut, DUT_MSG_ERROR,
11427 "snprintf failed for optional subelement ret: %d",
11428 ret);
11429 send_resp(dut, conn, SIGMA_ERROR,
11430 "errorCode,snprintf failed for subelement");
11431 return 0;
11432 }
11433 }
11434
11435 if (!dut->btm_query_cand_list) {
11436 dut->btm_query_cand_list = calloc(1, NEIGHBOR_REPORT_SIZE);
11437 if (!dut->btm_query_cand_list) {
11438 send_resp(dut, conn, SIGMA_ERROR,
11439 "errorCode,Failed to allocate memory for btm_query_cand_list");
11440 return 0;
11441 }
11442 }
11443
11444 len = strlen(dut->btm_query_cand_list);
11445 ret = snprintf(dut->btm_query_cand_list + len,
11446 NEIGHBOR_REPORT_SIZE - len, " neighbor=%s,%s,%s,%s,%s%s",
11447 bssid, info, op_class, ch, phy_type, buf);
11448 if (ret < 0 || ret >= NEIGHBOR_REPORT_SIZE - len) {
11449 sigma_dut_print(dut, DUT_MSG_ERROR,
11450 "snprintf failed for neighbor report list ret: %d",
11451 ret);
11452 send_resp(dut, conn, SIGMA_ERROR,
11453 "errorCode,snprintf failed for neighbor report");
11454 free(dut->btm_query_cand_list);
11455 dut->btm_query_cand_list = NULL;
11456 return 0;
11457 }
11458
11459 return 1;
11460}
11461
11462
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020011463int sta_extract_60g_ese(struct sigma_dut *dut, struct sigma_cmd *cmd,
11464 struct sigma_ese_alloc *allocs, int *allocs_size)
11465{
11466 int max_count = *allocs_size;
11467 int count = 0, i;
11468 const char *val;
11469
11470 do {
11471 val = get_param_indexed(cmd, "AllocID", count);
11472 if (val)
11473 count++;
11474 } while (val);
11475
11476 if (count == 0 || count > max_count) {
11477 sigma_dut_print(dut, DUT_MSG_ERROR,
11478 "Invalid number of allocations(%d)", count);
11479 return -1;
11480 }
11481
11482 for (i = 0; i < count; i++) {
11483 val = get_param_indexed(cmd, "PercentBI", i);
11484 if (!val) {
11485 sigma_dut_print(dut, DUT_MSG_ERROR,
11486 "Missing PercentBI parameter at index %d",
11487 i);
11488 return -1;
11489 }
11490 allocs[i].percent_bi = atoi(val);
11491
11492 val = get_param_indexed(cmd, "SrcAID", i);
11493 if (val)
11494 allocs[i].src_aid = strtol(val, NULL, 0);
11495 else
11496 allocs[i].src_aid = ESE_BCAST_AID;
11497
11498 val = get_param_indexed(cmd, "DestAID", i);
11499 if (val)
11500 allocs[i].dst_aid = strtol(val, NULL, 0);
11501 else
11502 allocs[i].dst_aid = ESE_BCAST_AID;
11503
11504 allocs[i].type = ESE_CBAP;
11505 sigma_dut_print(dut, DUT_MSG_INFO,
11506 "Alloc %d PercentBI %d SrcAID %d DstAID %d",
11507 i, allocs[i].percent_bi, allocs[i].src_aid,
11508 allocs[i].dst_aid);
11509 }
11510
11511 *allocs_size = count;
11512 return 0;
11513}
11514
11515
11516static int sta_set_60g_ese(struct sigma_dut *dut, int count,
11517 struct sigma_ese_alloc *allocs)
11518{
11519 switch (get_driver_type()) {
11520#ifdef __linux__
11521 case DRIVER_WIL6210:
11522 if (wil6210_set_ese(dut, count, allocs))
11523 return -1;
11524 return 1;
11525#endif /* __linux__ */
11526 default:
11527 sigma_dut_print(dut, DUT_MSG_ERROR,
11528 "Unsupported sta_set_60g_ese with the current driver");
11529 return -1;
11530 }
11531}
11532
11533
11534static int cmd_sta_set_rfeature_60g(const char *intf, struct sigma_dut *dut,
11535 struct sigma_conn *conn,
11536 struct sigma_cmd *cmd)
11537{
11538 const char *val;
11539
11540 val = get_param(cmd, "ExtSchIE");
11541 if (val && !strcasecmp(val, "Enable")) {
11542 struct sigma_ese_alloc allocs[MAX_ESE_ALLOCS];
11543 int count = MAX_ESE_ALLOCS;
11544
11545 if (sta_extract_60g_ese(dut, cmd, allocs, &count))
11546 return -1;
11547 return sta_set_60g_ese(dut, count, allocs);
11548 }
11549
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +020011550 val = get_param(cmd, "MCS_FixedRate");
11551 if (val) {
11552 int sta_mcs = atoi(val);
11553
11554 sigma_dut_print(dut, DUT_MSG_INFO, "Force STA MCS to %d",
11555 sta_mcs);
11556 wil6210_set_force_mcs(dut, 1, sta_mcs);
11557
Jouni Malinen0e29cf22019-02-19 01:13:21 +020011558 return SUCCESS_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +020011559 }
11560
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020011561 send_resp(dut, conn, SIGMA_ERROR,
11562 "errorCode,Invalid sta_set_rfeature(60G)");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020011563 return STATUS_SENT;
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020011564}
11565
11566
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011567static int cmd_sta_set_rfeature(struct sigma_dut *dut, struct sigma_conn *conn,
11568 struct sigma_cmd *cmd)
11569{
11570 const char *intf = get_param(cmd, "Interface");
11571 const char *prog = get_param(cmd, "Prog");
Ashwini Patil68d02cd2017-01-10 15:39:16 +053011572 const char *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011573
11574 if (intf == NULL || prog == NULL)
11575 return -1;
11576
Ashwini Patil5acd7382017-04-13 15:55:04 +053011577 /* BSS Transition candidate list for BTM query */
11578 val = get_param(cmd, "Nebor_BSSID");
11579 if (val && btm_query_candidate_list(dut, conn, cmd) == 0)
11580 return 0;
11581
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011582 if (strcasecmp(prog, "TDLS") == 0)
11583 return cmd_sta_set_rfeature_tdls(intf, dut, conn, cmd);
11584
11585 if (strcasecmp(prog, "VHT") == 0)
11586 return cmd_sta_set_rfeature_vht(intf, dut, conn, cmd);
11587
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011588 if (strcasecmp(prog, "HE") == 0)
11589 return cmd_sta_set_rfeature_he(intf, dut, conn, cmd);
11590
Ashwini Patil68d02cd2017-01-10 15:39:16 +053011591 if (strcasecmp(prog, "MBO") == 0) {
11592 val = get_param(cmd, "Cellular_Data_Cap");
11593 if (val &&
11594 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
11595 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +053011596
11597 val = get_param(cmd, "Ch_Pref");
11598 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
11599 return 0;
11600
Ashwini Patil68d02cd2017-01-10 15:39:16 +053011601 return 1;
11602 }
11603
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020011604 if (strcasecmp(prog, "60GHz") == 0)
11605 return cmd_sta_set_rfeature_60g(intf, dut, conn, cmd);
11606
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011607 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported Prog");
11608 return 0;
11609}
11610
11611
11612static int cmd_sta_set_radio(struct sigma_dut *dut, struct sigma_conn *conn,
11613 struct sigma_cmd *cmd)
11614{
11615 const char *intf = get_param(cmd, "Interface");
11616 const char *mode = get_param(cmd, "Mode");
11617 int res;
11618
11619 if (intf == NULL || mode == NULL)
11620 return -1;
11621
11622 if (strcasecmp(mode, "On") == 0)
11623 res = wpa_command(intf, "SET radio_disabled 0");
11624 else if (strcasecmp(mode, "Off") == 0)
11625 res = wpa_command(intf, "SET radio_disabled 1");
11626 else
11627 return -1;
11628
11629 if (res) {
11630 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
11631 "radio mode");
11632 return 0;
11633 }
11634
11635 return 1;
11636}
11637
11638
11639static int cmd_sta_set_pwrsave(struct sigma_dut *dut, struct sigma_conn *conn,
11640 struct sigma_cmd *cmd)
11641{
11642 const char *intf = get_param(cmd, "Interface");
11643 const char *mode = get_param(cmd, "Mode");
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020011644 const char *prog = get_param(cmd, "program");
11645 const char *powersave = get_param(cmd, "powersave");
11646 int res = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011647
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020011648 if (intf == NULL)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011649 return -1;
11650
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020011651 if (prog && strcasecmp(prog, "60GHz") == 0) {
11652 /*
11653 * The CAPI mode parameter does not exist in 60G
11654 * unscheduled PS.
11655 */
11656 if (strcasecmp(powersave, "unscheduled") == 0)
11657 res = set_ps(intf, dut, 1);
Alexei Avshalom Lazar2f6fdb42019-02-04 14:16:08 +020011658 } else if (prog && get_driver_type() == DRIVER_WCN &&
11659 strcasecmp(prog, "HE") == 0) {
11660 return cmd_sta_set_power_save_he(intf, dut, conn, cmd);
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020011661 } else {
11662 if (mode == NULL)
11663 return -1;
11664
11665 if (strcasecmp(mode, "On") == 0)
11666 res = set_ps(intf, dut, 1);
11667 else if (strcasecmp(mode, "Off") == 0)
11668 res = set_ps(intf, dut, 0);
11669 else
11670 return -1;
11671 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011672
11673 if (res) {
11674 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
11675 "power save mode");
11676 return 0;
11677 }
11678
11679 return 1;
11680}
11681
11682
11683static int cmd_sta_bssid_pool(struct sigma_dut *dut, struct sigma_conn *conn,
11684 struct sigma_cmd *cmd)
11685{
11686 const char *intf = get_param(cmd, "Interface");
11687 const char *val, *bssid;
11688 int res;
11689 char *buf;
11690 size_t buf_len;
11691
11692 val = get_param(cmd, "BSSID_FILTER");
11693 if (val == NULL)
11694 return -1;
11695
11696 bssid = get_param(cmd, "BSSID_List");
11697 if (atoi(val) == 0 || bssid == NULL) {
11698 /* Disable BSSID filter */
11699 if (wpa_command(intf, "SET bssid_filter ")) {
11700 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed "
11701 "to disable BSSID filter");
11702 return 0;
11703 }
11704
11705 return 1;
11706 }
11707
11708 buf_len = 100 + strlen(bssid);
11709 buf = malloc(buf_len);
11710 if (buf == NULL)
11711 return -1;
11712
11713 snprintf(buf, buf_len, "SET bssid_filter %s", bssid);
11714 res = wpa_command(intf, buf);
11715 free(buf);
11716 if (res) {
11717 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to enable "
11718 "BSSID filter");
11719 return 0;
11720 }
11721
11722 return 1;
11723}
11724
11725
11726static int cmd_sta_reset_parm(struct sigma_dut *dut, struct sigma_conn *conn,
11727 struct sigma_cmd *cmd)
11728{
11729 const char *intf = get_param(cmd, "Interface");
11730 const char *val;
11731
11732 /* TODO: ARP */
11733
11734 val = get_param(cmd, "HS2_CACHE_PROFILE");
11735 if (val && strcasecmp(val, "All") == 0)
11736 hs2_clear_credentials(intf);
11737
11738 return 1;
11739}
11740
11741
11742static int cmd_sta_get_key(struct sigma_dut *dut, struct sigma_conn *conn,
11743 struct sigma_cmd *cmd)
11744{
11745 const char *intf = get_param(cmd, "Interface");
11746 const char *key_type = get_param(cmd, "KeyType");
11747 char buf[100], resp[200];
11748
11749 if (key_type == NULL)
11750 return -1;
11751
11752 if (strcasecmp(key_type, "GTK") == 0) {
11753 if (wpa_command_resp(intf, "GET gtk", buf, sizeof(buf)) < 0 ||
11754 strncmp(buf, "FAIL", 4) == 0) {
11755 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
11756 "not fetch current GTK");
11757 return 0;
11758 }
11759 snprintf(resp, sizeof(resp), "KeyValue,%s", buf);
11760 send_resp(dut, conn, SIGMA_COMPLETE, resp);
11761 return 0;
11762 } else {
11763 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
11764 "KeyType");
11765 return 0;
11766 }
11767
11768 return 1;
11769}
11770
11771
11772static int hs2_set_policy(struct sigma_dut *dut)
11773{
11774#ifdef ANDROID
11775 system("ip rule del prio 23000");
11776 if (system("ip rule add from all lookup main prio 23000") != 0) {
11777 sigma_dut_print(dut, DUT_MSG_ERROR,
11778 "Failed to run:ip rule add from all lookup main prio");
11779 return -1;
11780 }
11781 if (system("ip route flush cache") != 0) {
11782 sigma_dut_print(dut, DUT_MSG_ERROR,
11783 "Failed to run ip route flush cache");
11784 return -1;
11785 }
11786 return 1;
11787#else /* ANDROID */
11788 return 0;
11789#endif /* ANDROID */
11790}
11791
11792
11793static int cmd_sta_hs2_associate(struct sigma_dut *dut,
11794 struct sigma_conn *conn,
11795 struct sigma_cmd *cmd)
11796{
11797 const char *intf = get_param(cmd, "Interface");
11798 const char *val = get_param(cmd, "Ignore_blacklist");
Jouni Malinen439352d2018-09-13 03:42:23 +030011799 const char *band = get_param(cmd, "Band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011800 struct wpa_ctrl *ctrl;
Jouni Malinen3aa72862019-05-29 23:14:51 +030011801 int res, r;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011802 char bssid[20], ssid[40], resp[100], buf[100], blacklisted[100];
11803 int tries = 0;
11804 int ignore_blacklist = 0;
11805 const char *events[] = {
11806 "CTRL-EVENT-CONNECTED",
11807 "INTERWORKING-BLACKLISTED",
11808 "INTERWORKING-NO-MATCH",
11809 NULL
11810 };
11811
11812 start_sta_mode(dut);
11813
Jouni Malinen439352d2018-09-13 03:42:23 +030011814 if (band) {
11815 if (strcmp(band, "2.4") == 0) {
11816 wpa_command(intf, "SET setband 2G");
11817 } else if (strcmp(band, "5") == 0) {
11818 wpa_command(intf, "SET setband 5G");
11819 } else {
11820 send_resp(dut, conn, SIGMA_ERROR,
11821 "errorCode,Unsupported band");
11822 return 0;
11823 }
11824 }
11825
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011826 blacklisted[0] = '\0';
11827 if (val && atoi(val))
11828 ignore_blacklist = 1;
11829
11830try_again:
11831 ctrl = open_wpa_mon(intf);
11832 if (ctrl == NULL) {
11833 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
11834 "wpa_supplicant monitor connection");
11835 return -2;
11836 }
11837
11838 tries++;
11839 if (wpa_command(intf, "INTERWORKING_SELECT auto")) {
11840 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start "
11841 "Interworking connection");
11842 wpa_ctrl_detach(ctrl);
11843 wpa_ctrl_close(ctrl);
11844 return 0;
11845 }
11846
11847 buf[0] = '\0';
11848 while (1) {
11849 char *pos;
11850 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
11851 pos = strstr(buf, "INTERWORKING-BLACKLISTED");
11852 if (!pos)
11853 break;
11854 pos += 25;
11855 sigma_dut_print(dut, DUT_MSG_DEBUG, "Found blacklisted AP: %s",
11856 pos);
11857 if (!blacklisted[0])
11858 memcpy(blacklisted, pos, strlen(pos) + 1);
11859 }
11860
11861 if (ignore_blacklist && blacklisted[0]) {
11862 char *end;
11863 end = strchr(blacklisted, ' ');
11864 if (end)
11865 *end = '\0';
11866 sigma_dut_print(dut, DUT_MSG_DEBUG, "Try to connect to a blacklisted network: %s",
11867 blacklisted);
Jouni Malinen3aa72862019-05-29 23:14:51 +030011868 r = snprintf(buf, sizeof(buf), "INTERWORKING_CONNECT %s",
11869 blacklisted);
11870 if (r < 0 || r >= sizeof(buf) || wpa_command(intf, buf)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011871 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start Interworking connection to blacklisted network");
11872 wpa_ctrl_detach(ctrl);
11873 wpa_ctrl_close(ctrl);
11874 return 0;
11875 }
11876 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
11877 buf, sizeof(buf));
11878 }
11879
11880 wpa_ctrl_detach(ctrl);
11881 wpa_ctrl_close(ctrl);
11882
11883 if (res < 0) {
11884 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
11885 "connect");
11886 return 0;
11887 }
11888
11889 if (strstr(buf, "INTERWORKING-NO-MATCH") ||
11890 strstr(buf, "INTERWORKING-BLACKLISTED")) {
11891 if (tries < 2) {
11892 sigma_dut_print(dut, DUT_MSG_INFO, "No match found - try again to verify no APs were missed in the scan");
11893 goto try_again;
11894 }
11895 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,No network with "
11896 "matching credentials found");
11897 return 0;
11898 }
11899
11900 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
11901 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
11902 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
11903 "get current BSSID/SSID");
11904 return 0;
11905 }
11906
11907 snprintf(resp, sizeof(resp), "SSID,%s,BSSID,%s", ssid, bssid);
11908 send_resp(dut, conn, SIGMA_COMPLETE, resp);
11909 hs2_set_policy(dut);
11910 return 0;
11911}
11912
11913
Jouni Malinenb639f1c2018-09-13 02:39:46 +030011914static int cmd_sta_hs2_venue_info(struct sigma_dut *dut,
11915 struct sigma_conn *conn,
11916 struct sigma_cmd *cmd)
11917{
11918 const char *intf = get_param(cmd, "Interface");
11919 const char *display = get_param(cmd, "Display");
11920 struct wpa_ctrl *ctrl;
11921 char buf[300], params[400], *pos;
11922 char bssid[20];
11923 int info_avail = 0;
11924 unsigned int old_timeout;
11925 int res;
11926
11927 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0) {
11928 send_resp(dut, conn, SIGMA_ERROR,
11929 "ErrorCode,Could not get current BSSID");
11930 return 0;
11931 }
11932 ctrl = open_wpa_mon(intf);
11933 if (!ctrl) {
11934 sigma_dut_print(dut, DUT_MSG_ERROR,
11935 "Failed to open wpa_supplicant monitor connection");
11936 return -2;
11937 }
11938
11939 snprintf(buf, sizeof(buf), "ANQP_GET %s 277", bssid);
11940 wpa_command(intf, buf);
11941
11942 res = get_wpa_cli_event(dut, ctrl, "GAS-QUERY-DONE", buf, sizeof(buf));
11943 if (res < 0) {
11944 send_resp(dut, conn, SIGMA_ERROR,
11945 "ErrorCode,Could not complete GAS query");
11946 goto fail;
11947 }
11948
11949 old_timeout = dut->default_timeout;
11950 dut->default_timeout = 2;
11951 res = get_wpa_cli_event(dut, ctrl, "RX-VENUE-URL", buf, sizeof(buf));
11952 dut->default_timeout = old_timeout;
11953 if (res < 0)
11954 goto done;
11955 pos = strchr(buf, ' ');
11956 if (!pos)
11957 goto done;
11958 pos++;
11959 pos = strchr(pos, ' ');
11960 if (!pos)
11961 goto done;
11962 pos++;
11963 info_avail = 1;
11964 snprintf(params, sizeof(params), "browser %s", pos);
11965
11966 if (display && strcasecmp(display, "Yes") == 0) {
11967 pid_t pid;
11968
11969 pid = fork();
11970 if (pid < 0) {
11971 perror("fork");
11972 return -1;
11973 }
11974
11975 if (pid == 0) {
11976 run_hs20_osu(dut, params);
11977 exit(0);
11978 }
11979 }
11980
11981done:
11982 snprintf(buf, sizeof(buf), "Info_available,%s",
11983 info_avail ? "Yes" : "No");
11984 send_resp(dut, conn, SIGMA_COMPLETE, buf);
11985fail:
11986 wpa_ctrl_detach(ctrl);
11987 wpa_ctrl_close(ctrl);
11988 return 0;
11989}
11990
11991
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011992static int sta_add_credential_uname_pwd(struct sigma_dut *dut,
11993 struct sigma_conn *conn,
11994 const char *ifname,
11995 struct sigma_cmd *cmd)
11996{
11997 const char *val;
11998 int id;
11999
12000 id = add_cred(ifname);
12001 if (id < 0)
12002 return -2;
12003 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
12004
12005 val = get_param(cmd, "prefer");
12006 if (val && atoi(val) > 0)
12007 set_cred(ifname, id, "priority", "1");
12008
12009 val = get_param(cmd, "REALM");
12010 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
12011 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12012 "realm");
12013 return 0;
12014 }
12015
12016 val = get_param(cmd, "HOME_FQDN");
12017 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
12018 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12019 "home_fqdn");
12020 return 0;
12021 }
12022
12023 val = get_param(cmd, "Username");
12024 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
12025 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12026 "username");
12027 return 0;
12028 }
12029
12030 val = get_param(cmd, "Password");
12031 if (val && set_cred_quoted(ifname, id, "password", val) < 0) {
12032 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12033 "password");
12034 return 0;
12035 }
12036
12037 val = get_param(cmd, "ROOT_CA");
12038 if (val) {
12039 char fname[200];
12040 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
12041#ifdef __linux__
12042 if (!file_exists(fname)) {
12043 char msg[300];
12044 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
12045 "file (%s) not found", fname);
12046 send_resp(dut, conn, SIGMA_ERROR, msg);
12047 return 0;
12048 }
12049#endif /* __linux__ */
12050 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
12051 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12052 "not set root CA");
12053 return 0;
12054 }
12055 }
12056
12057 return 1;
12058}
12059
12060
12061static int update_devdetail_imsi(struct sigma_dut *dut, const char *imsi)
12062{
12063 FILE *in, *out;
12064 char buf[500];
12065 int found = 0;
12066
12067 in = fopen("devdetail.xml", "r");
12068 if (in == NULL)
12069 return -1;
12070 out = fopen("devdetail.xml.tmp", "w");
12071 if (out == NULL) {
12072 fclose(in);
12073 return -1;
12074 }
12075
12076 while (fgets(buf, sizeof(buf), in)) {
12077 char *pos = strstr(buf, "<IMSI>");
12078 if (pos) {
12079 sigma_dut_print(dut, DUT_MSG_INFO, "Updated DevDetail IMSI to %s",
12080 imsi);
12081 pos += 6;
12082 *pos = '\0';
12083 fprintf(out, "%s%s</IMSI>\n", buf, imsi);
12084 found++;
12085 } else {
12086 fprintf(out, "%s", buf);
12087 }
12088 }
12089
12090 fclose(out);
12091 fclose(in);
12092 if (found)
12093 rename("devdetail.xml.tmp", "devdetail.xml");
12094 else
12095 unlink("devdetail.xml.tmp");
12096
12097 return 0;
12098}
12099
12100
12101static int sta_add_credential_sim(struct sigma_dut *dut,
12102 struct sigma_conn *conn,
12103 const char *ifname, struct sigma_cmd *cmd)
12104{
12105 const char *val, *imsi = NULL;
12106 int id;
12107 char buf[200];
12108 int res;
12109 const char *pos;
12110 size_t mnc_len;
12111 char plmn_mcc[4];
12112 char plmn_mnc[4];
12113
12114 id = add_cred(ifname);
12115 if (id < 0)
12116 return -2;
12117 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
12118
12119 val = get_param(cmd, "prefer");
12120 if (val && atoi(val) > 0)
12121 set_cred(ifname, id, "priority", "1");
12122
12123 val = get_param(cmd, "PLMN_MCC");
12124 if (val == NULL) {
12125 send_resp(dut, conn, SIGMA_ERROR,
12126 "errorCode,Missing PLMN_MCC");
12127 return 0;
12128 }
12129 if (strlen(val) != 3) {
12130 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MCC");
12131 return 0;
12132 }
12133 snprintf(plmn_mcc, sizeof(plmn_mcc), "%s", val);
12134
12135 val = get_param(cmd, "PLMN_MNC");
12136 if (val == NULL) {
12137 send_resp(dut, conn, SIGMA_ERROR,
12138 "errorCode,Missing PLMN_MNC");
12139 return 0;
12140 }
12141 if (strlen(val) != 2 && strlen(val) != 3) {
12142 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MNC");
12143 return 0;
12144 }
12145 snprintf(plmn_mnc, sizeof(plmn_mnc), "%s", val);
12146
12147 val = get_param(cmd, "IMSI");
12148 if (val == NULL) {
12149 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing SIM "
12150 "IMSI");
12151 return 0;
12152 }
12153
12154 imsi = pos = val;
12155
12156 if (strncmp(plmn_mcc, pos, 3) != 0) {
12157 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MCC mismatch");
12158 return 0;
12159 }
12160 pos += 3;
12161
12162 mnc_len = strlen(plmn_mnc);
12163 if (mnc_len < 2) {
12164 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC not set");
12165 return 0;
12166 }
12167
12168 if (strncmp(plmn_mnc, pos, mnc_len) != 0) {
12169 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC mismatch");
12170 return 0;
12171 }
12172 pos += mnc_len;
12173
12174 res = snprintf(buf, sizeof(buf), "%s%s-%s",plmn_mcc, plmn_mnc, pos);
12175 if (res < 0 || res >= (int) sizeof(buf))
12176 return -1;
12177 if (set_cred_quoted(ifname, id, "imsi", buf) < 0) {
12178 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12179 "not set IMSI");
12180 return 0;
12181 }
12182
12183 val = get_param(cmd, "Password");
12184 if (val && set_cred_quoted(ifname, id, "milenage", val) < 0) {
12185 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12186 "not set password");
12187 return 0;
12188 }
12189
Jouni Malinenba630452018-06-22 11:49:59 +030012190 if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012191 /*
12192 * Set provisioning_sp for the test cases where SIM/USIM
12193 * provisioning is used.
12194 */
12195 if (val && set_cred_quoted(ifname, id, "provisioning_sp",
12196 "wi-fi.org") < 0) {
12197 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12198 "not set provisioning_sp");
12199 return 0;
12200 }
12201
12202 update_devdetail_imsi(dut, imsi);
12203 }
12204
12205 return 1;
12206}
12207
12208
12209static int sta_add_credential_cert(struct sigma_dut *dut,
12210 struct sigma_conn *conn,
12211 const char *ifname,
12212 struct sigma_cmd *cmd)
12213{
12214 const char *val;
12215 int id;
12216
12217 id = add_cred(ifname);
12218 if (id < 0)
12219 return -2;
12220 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
12221
12222 val = get_param(cmd, "prefer");
12223 if (val && atoi(val) > 0)
12224 set_cred(ifname, id, "priority", "1");
12225
12226 val = get_param(cmd, "REALM");
12227 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
12228 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12229 "realm");
12230 return 0;
12231 }
12232
12233 val = get_param(cmd, "HOME_FQDN");
12234 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
12235 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12236 "home_fqdn");
12237 return 0;
12238 }
12239
12240 val = get_param(cmd, "Username");
12241 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
12242 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12243 "username");
12244 return 0;
12245 }
12246
12247 val = get_param(cmd, "clientCertificate");
12248 if (val) {
12249 char fname[200];
12250 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
12251#ifdef __linux__
12252 if (!file_exists(fname)) {
12253 char msg[300];
12254 snprintf(msg, sizeof(msg),
12255 "ErrorCode,clientCertificate "
12256 "file (%s) not found", fname);
12257 send_resp(dut, conn, SIGMA_ERROR, msg);
12258 return 0;
12259 }
12260#endif /* __linux__ */
12261 if (set_cred_quoted(ifname, id, "client_cert", fname) < 0) {
12262 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12263 "not set client_cert");
12264 return 0;
12265 }
12266 if (set_cred_quoted(ifname, id, "private_key", fname) < 0) {
12267 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12268 "not set private_key");
12269 return 0;
12270 }
12271 }
12272
12273 val = get_param(cmd, "ROOT_CA");
12274 if (val) {
12275 char fname[200];
12276 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
12277#ifdef __linux__
12278 if (!file_exists(fname)) {
12279 char msg[300];
12280 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
12281 "file (%s) not found", fname);
12282 send_resp(dut, conn, SIGMA_ERROR, msg);
12283 return 0;
12284 }
12285#endif /* __linux__ */
12286 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
12287 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12288 "not set root CA");
12289 return 0;
12290 }
12291 }
12292
12293 return 1;
12294}
12295
12296
12297static int cmd_sta_add_credential(struct sigma_dut *dut,
12298 struct sigma_conn *conn,
12299 struct sigma_cmd *cmd)
12300{
12301 const char *intf = get_param(cmd, "Interface");
12302 const char *type;
12303
12304 start_sta_mode(dut);
12305
12306 type = get_param(cmd, "Type");
12307 if (!type)
12308 return -1;
12309
12310 if (strcasecmp(type, "uname_pwd") == 0)
12311 return sta_add_credential_uname_pwd(dut, conn, intf, cmd);
12312
12313 if (strcasecmp(type, "sim") == 0)
12314 return sta_add_credential_sim(dut, conn, intf, cmd);
12315
12316 if (strcasecmp(type, "cert") == 0)
12317 return sta_add_credential_cert(dut, conn, intf, cmd);
12318
12319 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported credential "
12320 "type");
12321 return 0;
12322}
12323
12324
12325static int cmd_sta_scan(struct sigma_dut *dut, struct sigma_conn *conn,
12326 struct sigma_cmd *cmd)
12327{
12328 const char *intf = get_param(cmd, "Interface");
vamsi krishna89ad8c62017-09-19 12:51:18 +053012329 const char *val, *bssid, *ssid;
Arif Hussain66a4af02019-02-07 15:04:51 -080012330 char buf[4096];
vamsi krishna89ad8c62017-09-19 12:51:18 +053012331 char ssid_hex[65];
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012332 int res;
12333
Arif Hussain66a4af02019-02-07 15:04:51 -080012334 val = get_param(cmd, "GetParameter");
12335 if (val && strcmp(val, "SSID_BSSID") == 0) {
12336 if (get_wpa_ssid_bssid(dut, get_station_ifname(),
12337 buf, sizeof(buf)) < 0) {
12338 sigma_dut_print(dut, DUT_MSG_ERROR,
12339 "Could not get ssid bssid");
12340 return ERROR_SEND_STATUS;
12341 }
12342
12343 sigma_dut_print(dut, DUT_MSG_INFO, "%s", buf);
12344 send_resp(dut, conn, SIGMA_COMPLETE, buf);
12345 return STATUS_SENT;
12346 }
12347
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012348 val = get_param(cmd, "HESSID");
12349 if (val) {
12350 res = snprintf(buf, sizeof(buf), "SET hessid %s", val);
12351 if (res < 0 || res >= (int) sizeof(buf))
12352 return -1;
12353 wpa_command(intf, buf);
12354 }
12355
12356 val = get_param(cmd, "ACCS_NET_TYPE");
12357 if (val) {
12358 res = snprintf(buf, sizeof(buf), "SET access_network_type %s",
12359 val);
12360 if (res < 0 || res >= (int) sizeof(buf))
12361 return -1;
12362 wpa_command(intf, buf);
12363 }
12364
vamsi krishna89ad8c62017-09-19 12:51:18 +053012365 bssid = get_param(cmd, "Bssid");
12366 ssid = get_param(cmd, "Ssid");
12367
12368 if (ssid) {
12369 if (2 * strlen(ssid) >= sizeof(ssid_hex)) {
12370 send_resp(dut, conn, SIGMA_ERROR,
12371 "ErrorCode,Too long SSID");
12372 return 0;
12373 }
12374 ascii2hexstr(ssid, ssid_hex);
12375 }
12376
12377 res = snprintf(buf, sizeof(buf), "SCAN%s%s%s%s",
12378 bssid ? " bssid=": "",
12379 bssid ? bssid : "",
12380 ssid ? " ssid " : "",
12381 ssid ? ssid_hex : "");
12382 if (res < 0 || res >= (int) sizeof(buf))
12383 return -1;
12384
12385 if (wpa_command(intf, buf)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012386 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not start "
12387 "scan");
12388 return 0;
12389 }
12390
12391 return 1;
12392}
12393
12394
Jouni Malinen5e5d43d2018-01-10 17:29:33 +020012395static int cmd_sta_scan_bss(struct sigma_dut *dut, struct sigma_conn *conn,
12396 struct sigma_cmd *cmd)
12397{
12398 const char *intf = get_param(cmd, "Interface");
12399 const char *bssid;
12400 char buf[4096], *pos;
12401 int freq, chan;
12402 char *ssid;
12403 char resp[100];
12404 int res;
12405 struct wpa_ctrl *ctrl;
12406
12407 bssid = get_param(cmd, "BSSID");
12408 if (!bssid) {
12409 send_resp(dut, conn, SIGMA_INVALID,
12410 "errorCode,BSSID argument is missing");
12411 return 0;
12412 }
12413
12414 ctrl = open_wpa_mon(intf);
12415 if (!ctrl) {
12416 sigma_dut_print(dut, DUT_MSG_ERROR,
12417 "Failed to open wpa_supplicant monitor connection");
12418 return -1;
12419 }
12420
12421 if (wpa_command(intf, "SCAN TYPE=ONLY")) {
12422 send_resp(dut, conn, SIGMA_ERROR,
12423 "errorCode,Could not start scan");
12424 wpa_ctrl_detach(ctrl);
12425 wpa_ctrl_close(ctrl);
12426 return 0;
12427 }
12428
12429 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
12430 buf, sizeof(buf));
12431
12432 wpa_ctrl_detach(ctrl);
12433 wpa_ctrl_close(ctrl);
12434
12435 if (res < 0) {
12436 send_resp(dut, conn, SIGMA_ERROR,
12437 "errorCode,Scan did not complete");
12438 return 0;
12439 }
12440
12441 snprintf(buf, sizeof(buf), "BSS %s", bssid);
12442 if (wpa_command_resp(intf, buf, buf, sizeof(buf)) < 0 ||
12443 strncmp(buf, "id=", 3) != 0) {
12444 send_resp(dut, conn, SIGMA_ERROR,
12445 "errorCode,Specified BSSID not found");
12446 return 0;
12447 }
12448
12449 pos = strstr(buf, "\nfreq=");
12450 if (!pos) {
12451 send_resp(dut, conn, SIGMA_ERROR,
12452 "errorCode,Channel not found");
12453 return 0;
12454 }
12455 freq = atoi(pos + 6);
12456 chan = freq_to_channel(freq);
12457
12458 pos = strstr(buf, "\nssid=");
12459 if (!pos) {
12460 send_resp(dut, conn, SIGMA_ERROR,
12461 "errorCode,SSID not found");
12462 return 0;
12463 }
12464 ssid = pos + 6;
12465 pos = strchr(ssid, '\n');
12466 if (pos)
12467 *pos = '\0';
12468 snprintf(resp, sizeof(resp), "ssid,%s,bsschannel,%d", ssid, chan);
12469 send_resp(dut, conn, SIGMA_COMPLETE, resp);
12470 return 0;
12471}
12472
12473
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012474static int cmd_sta_set_systime(struct sigma_dut *dut, struct sigma_conn *conn,
12475 struct sigma_cmd *cmd)
12476{
12477#ifdef __linux__
12478 struct timeval tv;
12479 struct tm tm;
12480 time_t t;
12481 const char *val;
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +053012482 int v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012483
12484 wpa_command(get_station_ifname(), "PMKSA_FLUSH");
12485
12486 memset(&tm, 0, sizeof(tm));
12487 val = get_param(cmd, "seconds");
12488 if (val)
12489 tm.tm_sec = atoi(val);
12490 val = get_param(cmd, "minutes");
12491 if (val)
12492 tm.tm_min = atoi(val);
12493 val = get_param(cmd, "hours");
12494 if (val)
12495 tm.tm_hour = atoi(val);
12496 val = get_param(cmd, "date");
12497 if (val)
12498 tm.tm_mday = atoi(val);
12499 val = get_param(cmd, "month");
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +053012500 if (val) {
12501 v = atoi(val);
12502 if (v < 1 || v > 12) {
12503 send_resp(dut, conn, SIGMA_INVALID,
12504 "errorCode,Invalid month");
12505 return 0;
12506 }
12507 tm.tm_mon = v - 1;
12508 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012509 val = get_param(cmd, "year");
12510 if (val) {
12511 int year = atoi(val);
12512#ifdef ANDROID
12513 if (year > 2035)
12514 year = 2035; /* years beyond 2035 not supported */
12515#endif /* ANDROID */
12516 tm.tm_year = year - 1900;
12517 }
12518 t = mktime(&tm);
12519 if (t == (time_t) -1) {
12520 send_resp(dut, conn, SIGMA_ERROR,
12521 "errorCode,Invalid date or time");
12522 return 0;
12523 }
12524
12525 memset(&tv, 0, sizeof(tv));
12526 tv.tv_sec = t;
12527
12528 if (settimeofday(&tv, NULL) < 0) {
12529 sigma_dut_print(dut, DUT_MSG_INFO, "settimeofday failed: %s",
12530 strerror(errno));
12531 send_resp(dut, conn, SIGMA_ERROR,
12532 "errorCode,Failed to set time");
12533 return 0;
12534 }
12535
12536 return 1;
12537#endif /* __linux__ */
12538
12539 return -1;
12540}
12541
12542
12543static int cmd_sta_osu(struct sigma_dut *dut, struct sigma_conn *conn,
12544 struct sigma_cmd *cmd)
12545{
12546 const char *intf = get_param(cmd, "Interface");
Jouni Malinen4c8681c2018-09-12 23:28:11 +030012547 const char *name, *osu_ssid, *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012548 int prod_ess_assoc = 1;
Jouni Malinen4c8681c2018-09-12 23:28:11 +030012549 char buf[300], bssid[100], ssid[100];
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012550 int res;
12551 struct wpa_ctrl *ctrl;
12552
12553 name = get_param(cmd, "osuFriendlyName");
Jouni Malinen4c8681c2018-09-12 23:28:11 +030012554 osu_ssid = get_param(cmd, "osu_ssid");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012555
12556 val = get_param(cmd, "ProdESSAssoc");
12557 if (val)
12558 prod_ess_assoc = atoi(val);
12559
12560 kill_dhcp_client(dut, intf);
12561 if (start_dhcp_client(dut, intf) < 0)
12562 return -2;
12563
12564 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger OSU");
12565 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
12566 res = snprintf(buf, sizeof(buf),
Jouni Malinen4c8681c2018-09-12 23:28:11 +030012567 "%s %s%s%s %s%s%s signup osu-ca.pem",
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012568 prod_ess_assoc ? "" : "-N",
12569 name ? "-O'" : "", name ? name : "",
Jouni Malinen4c8681c2018-09-12 23:28:11 +030012570 name ? "'" : "",
12571 osu_ssid ? "-o'" : "", osu_ssid ? osu_ssid : "",
12572 osu_ssid ? "'" : "");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012573
Kanchanapally, Vidyullatha12b66762015-12-31 16:46:42 +053012574 hs2_set_policy(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012575 if (run_hs20_osu(dut, buf) < 0) {
12576 FILE *f;
12577
12578 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to complete OSU");
12579
12580 f = fopen("hs20-osu-client.res", "r");
12581 if (f) {
12582 char resp[400], res[300], *pos;
12583 if (!fgets(res, sizeof(res), f))
12584 res[0] = '\0';
12585 pos = strchr(res, '\n');
12586 if (pos)
12587 *pos = '\0';
12588 fclose(f);
12589 sigma_dut_summary(dut, "hs20-osu-client provisioning failed: %s",
12590 res);
12591 snprintf(resp, sizeof(resp), "notify-send '%s'", res);
12592 if (system(resp) != 0) {
12593 }
12594 snprintf(resp, sizeof(resp),
12595 "SSID,,BSSID,,failureReason,%s", res);
12596 send_resp(dut, conn, SIGMA_COMPLETE, resp);
12597 return 0;
12598 }
12599
12600 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
12601 return 0;
12602 }
12603
12604 if (!prod_ess_assoc)
12605 goto report;
12606
12607 ctrl = open_wpa_mon(intf);
12608 if (ctrl == NULL) {
12609 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
12610 "wpa_supplicant monitor connection");
12611 return -1;
12612 }
12613
12614 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
12615 buf, sizeof(buf));
12616
12617 wpa_ctrl_detach(ctrl);
12618 wpa_ctrl_close(ctrl);
12619
12620 if (res < 0) {
12621 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to connect to "
12622 "network after OSU");
12623 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
12624 return 0;
12625 }
12626
12627report:
12628 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
12629 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
12630 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to get BSSID/SSID");
12631 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
12632 return 0;
12633 }
12634
12635 snprintf(buf, sizeof(buf), "SSID,%s,BSSID,%s", ssid, bssid);
12636 send_resp(dut, conn, SIGMA_COMPLETE, buf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012637 return 0;
12638}
12639
12640
12641static int cmd_sta_policy_update(struct sigma_dut *dut, struct sigma_conn *conn,
12642 struct sigma_cmd *cmd)
12643{
12644 const char *val;
12645 int timeout = 120;
12646
12647 val = get_param(cmd, "PolicyUpdate");
12648 if (val == NULL || atoi(val) == 0)
12649 return 1; /* No operation requested */
12650
12651 val = get_param(cmd, "Timeout");
12652 if (val)
12653 timeout = atoi(val);
12654
12655 if (timeout) {
12656 /* TODO: time out the command and return
12657 * PolicyUpdateStatus,TIMEOUT if needed. */
12658 }
12659
12660 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger policy update");
12661 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
12662 if (run_hs20_osu(dut, "pol_upd fqdn=wi-fi.org") < 0) {
12663 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,FAIL");
12664 return 0;
12665 }
12666
12667 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,SUCCESS");
12668 return 0;
12669}
12670
12671
12672static int cmd_sta_er_config(struct sigma_dut *dut, struct sigma_conn *conn,
12673 struct sigma_cmd *cmd)
12674{
12675 struct wpa_ctrl *ctrl;
12676 const char *intf = get_param(cmd, "Interface");
12677 const char *bssid = get_param(cmd, "Bssid");
12678 const char *ssid = get_param(cmd, "SSID");
12679 const char *security = get_param(cmd, "Security");
12680 const char *passphrase = get_param(cmd, "Passphrase");
12681 const char *pin = get_param(cmd, "PIN");
12682 char buf[1000];
12683 char ssid_hex[200], passphrase_hex[200];
12684 const char *keymgmt, *cipher;
12685
12686 if (intf == NULL)
12687 intf = get_main_ifname();
12688
12689 if (!bssid) {
12690 send_resp(dut, conn, SIGMA_ERROR,
12691 "ErrorCode,Missing Bssid argument");
12692 return 0;
12693 }
12694
12695 if (!ssid) {
12696 send_resp(dut, conn, SIGMA_ERROR,
12697 "ErrorCode,Missing SSID argument");
12698 return 0;
12699 }
12700
12701 if (!security) {
12702 send_resp(dut, conn, SIGMA_ERROR,
12703 "ErrorCode,Missing Security argument");
12704 return 0;
12705 }
12706
12707 if (!passphrase) {
12708 send_resp(dut, conn, SIGMA_ERROR,
12709 "ErrorCode,Missing Passphrase argument");
12710 return 0;
12711 }
12712
12713 if (!pin) {
12714 send_resp(dut, conn, SIGMA_ERROR,
12715 "ErrorCode,Missing PIN argument");
12716 return 0;
12717 }
12718
vamsi krishna8c9c1562017-05-12 15:51:46 +053012719 if (2 * strlen(ssid) >= sizeof(ssid_hex) ||
12720 2 * strlen(passphrase) >= sizeof(passphrase_hex)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012721 send_resp(dut, conn, SIGMA_ERROR,
12722 "ErrorCode,Too long SSID/passphrase");
12723 return 0;
12724 }
12725
12726 ctrl = open_wpa_mon(intf);
12727 if (ctrl == NULL) {
12728 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
12729 "wpa_supplicant monitor connection");
12730 return -2;
12731 }
12732
12733 if (strcasecmp(security, "wpa2-psk") == 0) {
12734 keymgmt = "WPA2PSK";
12735 cipher = "CCMP";
12736 } else {
12737 wpa_ctrl_detach(ctrl);
12738 wpa_ctrl_close(ctrl);
12739 send_resp(dut, conn, SIGMA_ERROR,
12740 "ErrorCode,Unsupported Security value");
12741 return 0;
12742 }
12743
12744 ascii2hexstr(ssid, ssid_hex);
12745 ascii2hexstr(passphrase, passphrase_hex);
12746 snprintf(buf, sizeof(buf), "WPS_REG %s %s %s %s %s %s",
12747 bssid, pin, ssid_hex, keymgmt, cipher, passphrase_hex);
12748
12749 if (wpa_command(intf, buf) < 0) {
12750 wpa_ctrl_detach(ctrl);
12751 wpa_ctrl_close(ctrl);
12752 send_resp(dut, conn, SIGMA_ERROR,
12753 "ErrorCode,Failed to start registrar");
12754 return 0;
12755 }
12756
12757 snprintf(dut->er_oper_bssid, sizeof(dut->er_oper_bssid), "%s", bssid);
12758 dut->er_oper_performed = 1;
12759
12760 return wps_connection_event(dut, conn, ctrl, intf, 0);
12761}
12762
12763
12764static int cmd_sta_wps_connect_pw_token(struct sigma_dut *dut,
12765 struct sigma_conn *conn,
12766 struct sigma_cmd *cmd)
12767{
12768 struct wpa_ctrl *ctrl;
12769 const char *intf = get_param(cmd, "Interface");
12770 const char *bssid = get_param(cmd, "Bssid");
12771 char buf[100];
12772
12773 if (!bssid) {
12774 send_resp(dut, conn, SIGMA_ERROR,
12775 "ErrorCode,Missing Bssid argument");
12776 return 0;
12777 }
12778
12779 ctrl = open_wpa_mon(intf);
12780 if (ctrl == NULL) {
12781 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
12782 "wpa_supplicant monitor connection");
12783 return -2;
12784 }
12785
12786 snprintf(buf, sizeof(buf), "WPS_NFC %s", bssid);
12787
12788 if (wpa_command(intf, buf) < 0) {
12789 wpa_ctrl_detach(ctrl);
12790 wpa_ctrl_close(ctrl);
12791 send_resp(dut, conn, SIGMA_ERROR,
12792 "ErrorCode,Failed to start registrar");
12793 return 0;
12794 }
12795
12796 return wps_connection_event(dut, conn, ctrl, intf, 0);
12797}
12798
12799
vamsi krishna9b144002017-09-20 13:28:13 +053012800static int cmd_start_wps_registration(struct sigma_dut *dut,
12801 struct sigma_conn *conn,
12802 struct sigma_cmd *cmd)
12803{
12804 struct wpa_ctrl *ctrl;
12805 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020012806 const char *network_mode = get_param(cmd, "network_mode");
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020012807 const char *config_method = get_param(cmd, "WPSConfigMethod");
12808 const char *role;
vamsi krishna9b144002017-09-20 13:28:13 +053012809 int res;
12810 char buf[256];
12811 const char *events[] = {
12812 "CTRL-EVENT-CONNECTED",
12813 "WPS-OVERLAP-DETECTED",
12814 "WPS-TIMEOUT",
12815 "WPS-FAIL",
12816 NULL
12817 };
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020012818 int id = 0;
vamsi krishna9b144002017-09-20 13:28:13 +053012819
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020012820 /* 60G WPS tests do not pass Interface parameter */
12821 if (!intf)
12822 intf = get_main_ifname();
12823
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020012824 if (dut->mode == SIGMA_MODE_AP)
12825 return ap_wps_registration(dut, conn, cmd);
12826
12827 if (config_method) {
12828 /* WFA_CS_WPS_PIN_KEYPAD mode is set when using the
12829 * sta_wps_enter_pin before calling start_wps_registration. */
12830 if (strcasecmp(config_method, "PBC") == 0)
12831 dut->wps_method = WFA_CS_WPS_PBC;
12832 }
12833 if (dut->wps_method == WFA_CS_WPS_NOT_READY) {
12834 send_resp(dut, conn, SIGMA_ERROR,
12835 "ErrorCode,WPS parameters not yet set");
12836 return STATUS_SENT;
12837 }
12838
12839 /* Make sure WPS is enabled (also for STA mode) */
12840 dut->wps_disable = 0;
12841
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020012842 if (dut->band == WPS_BAND_60G && network_mode &&
12843 strcasecmp(network_mode, "PBSS") == 0) {
12844 sigma_dut_print(dut, DUT_MSG_DEBUG,
12845 "Set PBSS network mode, network id %d", id);
12846 if (set_network(get_station_ifname(), id, "pbss", "1") < 0)
12847 return -2;
12848 }
12849
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020012850 if (dut->force_rsn_ie) {
12851 sigma_dut_print(dut, DUT_MSG_DEBUG, "Force RSN_IE: %d",
12852 dut->force_rsn_ie);
12853 if (sta_60g_force_rsn_ie(dut, dut->force_rsn_ie) < 0) {
12854 sigma_dut_print(dut, DUT_MSG_INFO,
12855 "Failed to force RSN_IE");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020012856 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020012857 }
12858 }
12859
vamsi krishna9b144002017-09-20 13:28:13 +053012860 ctrl = open_wpa_mon(intf);
12861 if (!ctrl) {
12862 sigma_dut_print(dut, DUT_MSG_ERROR,
12863 "Failed to open wpa_supplicant monitor connection");
12864 return -2;
12865 }
12866
12867 role = get_param(cmd, "WpsRole");
12868 if (!role) {
12869 send_resp(dut, conn, SIGMA_INVALID,
12870 "ErrorCode,WpsRole not provided");
12871 goto fail;
12872 }
12873
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020012874 if (strcasecmp(role, "Enrollee") != 0) {
12875 /* Registrar role for STA not supported */
12876 send_resp(dut, conn, SIGMA_ERROR,
12877 "ErrorCode,Unsupported WpsRole value");
12878 goto fail;
12879 }
12880
12881 if (is_60g_sigma_dut(dut)) {
12882 if (dut->wps_method == WFA_CS_WPS_PBC)
12883 snprintf(buf, sizeof(buf), "WPS_PBC");
12884 else /* WFA_CS_WPS_PIN_KEYPAD */
12885 snprintf(buf, sizeof(buf), "WPS_PIN any %s",
12886 dut->wps_pin);
12887 if (wpa_command(intf, buf) < 0) {
12888 send_resp(dut, conn, SIGMA_ERROR,
12889 "ErrorCode,Failed to start WPS");
vamsi krishna9b144002017-09-20 13:28:13 +053012890 goto fail;
12891 }
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020012892 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
12893 if (res < 0) {
12894 send_resp(dut, conn, SIGMA_ERROR,
12895 "ErrorCode,WPS connection did not complete");
12896 goto fail;
12897 }
12898 if (strstr(buf, "WPS-TIMEOUT")) {
12899 send_resp(dut, conn, SIGMA_COMPLETE, "WpsState,NoPeer");
12900 } else if (strstr(buf, "WPS-OVERLAP-DETECTED")) {
12901 send_resp(dut, conn, SIGMA_COMPLETE,
12902 "WpsState,OverlapSession");
12903 } else if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
12904 send_resp(dut, conn, SIGMA_COMPLETE,
12905 "WpsState,Successful");
12906 } else {
12907 send_resp(dut, conn, SIGMA_COMPLETE,
12908 "WpsState,Failure");
12909 }
12910 } else {
12911 if (dut->wps_method == WFA_CS_WPS_PBC) {
vamsi krishna9b144002017-09-20 13:28:13 +053012912 if (wpa_command(intf, "WPS_PBC") < 0) {
12913 send_resp(dut, conn, SIGMA_ERROR,
12914 "ErrorCode,Failed to enable PBC");
12915 goto fail;
12916 }
12917 } else {
12918 /* TODO: PIN method */
12919 send_resp(dut, conn, SIGMA_ERROR,
12920 "ErrorCode,Unsupported WpsConfigMethod value");
12921 goto fail;
12922 }
12923 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
12924 if (res < 0) {
12925 send_resp(dut, conn, SIGMA_ERROR,
12926 "ErrorCode,WPS connection did not complete");
12927 goto fail;
12928 }
12929 if (strstr(buf, "WPS-TIMEOUT")) {
12930 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,NoPeer");
12931 } else if (strstr(buf, "WPS-OVERLAP-DETECTED")) {
12932 send_resp(dut, conn, SIGMA_ERROR,
12933 "ErrorCode,OverlapSession");
12934 } else if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
12935 send_resp(dut, conn, SIGMA_COMPLETE, "Successful");
12936 } else {
12937 send_resp(dut, conn, SIGMA_ERROR,
12938 "ErrorCode,WPS operation failed");
12939 }
vamsi krishna9b144002017-09-20 13:28:13 +053012940 }
12941
12942fail:
12943 wpa_ctrl_detach(ctrl);
12944 wpa_ctrl_close(ctrl);
12945 return 0;
12946}
12947
12948
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012949static int req_intf(struct sigma_cmd *cmd)
12950{
12951 return get_param(cmd, "interface") == NULL ? -1 : 0;
12952}
12953
12954
12955void sta_register_cmds(void)
12956{
12957 sigma_dut_reg_cmd("sta_get_ip_config", req_intf,
12958 cmd_sta_get_ip_config);
12959 sigma_dut_reg_cmd("sta_set_ip_config", req_intf,
12960 cmd_sta_set_ip_config);
12961 sigma_dut_reg_cmd("sta_get_info", req_intf, cmd_sta_get_info);
12962 sigma_dut_reg_cmd("sta_get_mac_address", req_intf,
12963 cmd_sta_get_mac_address);
12964 sigma_dut_reg_cmd("sta_is_connected", req_intf, cmd_sta_is_connected);
12965 sigma_dut_reg_cmd("sta_verify_ip_connection", req_intf,
12966 cmd_sta_verify_ip_connection);
12967 sigma_dut_reg_cmd("sta_get_bssid", req_intf, cmd_sta_get_bssid);
12968 sigma_dut_reg_cmd("sta_set_encryption", req_intf,
12969 cmd_sta_set_encryption);
12970 sigma_dut_reg_cmd("sta_set_psk", req_intf, cmd_sta_set_psk);
12971 sigma_dut_reg_cmd("sta_set_eaptls", req_intf, cmd_sta_set_eaptls);
12972 sigma_dut_reg_cmd("sta_set_eapttls", req_intf, cmd_sta_set_eapttls);
12973 sigma_dut_reg_cmd("sta_set_eapsim", req_intf, cmd_sta_set_eapsim);
12974 sigma_dut_reg_cmd("sta_set_peap", req_intf, cmd_sta_set_peap);
12975 sigma_dut_reg_cmd("sta_set_eapfast", req_intf, cmd_sta_set_eapfast);
12976 sigma_dut_reg_cmd("sta_set_eapaka", req_intf, cmd_sta_set_eapaka);
12977 sigma_dut_reg_cmd("sta_set_eapakaprime", req_intf,
12978 cmd_sta_set_eapakaprime);
12979 sigma_dut_reg_cmd("sta_set_security", req_intf, cmd_sta_set_security);
12980 sigma_dut_reg_cmd("sta_set_uapsd", req_intf, cmd_sta_set_uapsd);
12981 /* TODO: sta_set_ibss */
12982 /* TODO: sta_set_mode */
12983 sigma_dut_reg_cmd("sta_set_wmm", req_intf, cmd_sta_set_wmm);
12984 sigma_dut_reg_cmd("sta_associate", req_intf, cmd_sta_associate);
12985 /* TODO: sta_up_load */
12986 sigma_dut_reg_cmd("sta_preset_testparameters", req_intf,
12987 cmd_sta_preset_testparameters);
12988 /* TODO: sta_set_system */
12989 sigma_dut_reg_cmd("sta_set_11n", req_intf, cmd_sta_set_11n);
12990 /* TODO: sta_set_rifs_test */
12991 sigma_dut_reg_cmd("sta_set_wireless", req_intf, cmd_sta_set_wireless);
12992 sigma_dut_reg_cmd("sta_send_addba", req_intf, cmd_sta_send_addba);
12993 /* TODO: sta_send_coexist_mgmt */
12994 sigma_dut_reg_cmd("sta_disconnect", req_intf, cmd_sta_disconnect);
12995 sigma_dut_reg_cmd("sta_reassoc", req_intf, cmd_sta_reassoc);
12996 sigma_dut_reg_cmd("sta_reassociate", req_intf, cmd_sta_reassoc);
12997 sigma_dut_reg_cmd("sta_reset_default", req_intf,
12998 cmd_sta_reset_default);
12999 sigma_dut_reg_cmd("sta_send_frame", req_intf, cmd_sta_send_frame);
13000 sigma_dut_reg_cmd("sta_set_macaddr", req_intf, cmd_sta_set_macaddr);
13001 sigma_dut_reg_cmd("sta_set_rfeature", req_intf, cmd_sta_set_rfeature);
13002 sigma_dut_reg_cmd("sta_set_radio", req_intf, cmd_sta_set_radio);
13003 sigma_dut_reg_cmd("sta_set_pwrsave", req_intf, cmd_sta_set_pwrsave);
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020013004 sigma_dut_reg_cmd("sta_set_power_save", req_intf, cmd_sta_set_pwrsave);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013005 sigma_dut_reg_cmd("sta_bssid_pool", req_intf, cmd_sta_bssid_pool);
13006 sigma_dut_reg_cmd("sta_reset_parm", req_intf, cmd_sta_reset_parm);
13007 sigma_dut_reg_cmd("sta_get_key", req_intf, cmd_sta_get_key);
13008 sigma_dut_reg_cmd("sta_hs2_associate", req_intf,
13009 cmd_sta_hs2_associate);
Jouni Malinenb639f1c2018-09-13 02:39:46 +030013010 sigma_dut_reg_cmd("sta_hs2_venue_info", req_intf,
13011 cmd_sta_hs2_venue_info);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013012 sigma_dut_reg_cmd("sta_add_credential", req_intf,
13013 cmd_sta_add_credential);
13014 sigma_dut_reg_cmd("sta_scan", req_intf, cmd_sta_scan);
Jouni Malinen5e5d43d2018-01-10 17:29:33 +020013015 sigma_dut_reg_cmd("sta_scan_bss", req_intf, cmd_sta_scan_bss);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013016 sigma_dut_reg_cmd("sta_set_systime", NULL, cmd_sta_set_systime);
13017 sigma_dut_reg_cmd("sta_osu", req_intf, cmd_sta_osu);
13018 sigma_dut_reg_cmd("sta_policy_update", req_intf, cmd_sta_policy_update);
13019 sigma_dut_reg_cmd("sta_er_config", NULL, cmd_sta_er_config);
13020 sigma_dut_reg_cmd("sta_wps_connect_pw_token", req_intf,
13021 cmd_sta_wps_connect_pw_token);
Jouni Malinen82905202018-04-29 17:20:10 +030013022 sigma_dut_reg_cmd("sta_exec_action", NULL, cmd_sta_exec_action);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013023 sigma_dut_reg_cmd("sta_get_events", req_intf, cmd_sta_get_events);
13024 sigma_dut_reg_cmd("sta_get_parameter", req_intf, cmd_sta_get_parameter);
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020013025 sigma_dut_reg_cmd("start_wps_registration", NULL,
vamsi krishna9b144002017-09-20 13:28:13 +053013026 cmd_start_wps_registration);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013027}