blob: 68d04913a6c84d8cfb8c03a27aa3c571f1b2f66b [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
Jouni Malinenf7222712019-06-13 01:50:21 +03001102static enum sigma_cmd_result cmd_sta_get_ip_config(struct sigma_dut *dut,
1103 struct sigma_conn *conn,
1104 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001105{
1106 const char *intf = get_param(cmd, "Interface");
1107 const char *ifname;
1108 char buf[200];
1109 const char *val;
1110 int type = 1;
1111
1112 if (intf == NULL)
1113 return -1;
1114
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 Malinenf7222712019-06-13 01:50:21 +03001377static enum sigma_cmd_result cmd_sta_set_ip_config(struct sigma_dut *dut,
1378 struct sigma_conn *conn,
1379 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001380{
1381 const char *intf = get_param(cmd, "Interface");
1382 const char *ifname;
1383 char buf[200];
1384 const char *val, *ip, *mask, *gw;
1385 int type = 1;
1386
1387 if (intf == NULL)
1388 return -1;
1389
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
Jouni Malinenf7222712019-06-13 01:50:21 +03001548static enum sigma_cmd_result cmd_sta_get_info(struct sigma_dut *dut,
1549 struct sigma_conn *conn,
1550 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001551{
1552 /* const char *intf = get_param(cmd, "Interface"); */
1553 /* TODO: could report more details here */
1554 send_resp(dut, conn, SIGMA_COMPLETE, "vendor,Atheros");
1555 return 0;
1556}
1557
1558
Jouni Malinenf7222712019-06-13 01:50:21 +03001559static enum sigma_cmd_result cmd_sta_get_mac_address(struct sigma_dut *dut,
1560 struct sigma_conn *conn,
1561 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001562{
1563 /* const char *intf = get_param(cmd, "Interface"); */
1564 char addr[20], resp[50];
1565
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05301566 if (dut->dev_role == DEVROLE_STA_CFON)
1567 return sta_cfon_get_mac_address(dut, conn, cmd);
1568
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001569 if (get_wpa_status(get_station_ifname(), "address", addr, sizeof(addr))
1570 < 0)
1571 return -2;
1572
1573 snprintf(resp, sizeof(resp), "mac,%s", addr);
1574 send_resp(dut, conn, SIGMA_COMPLETE, resp);
1575 return 0;
1576}
1577
1578
Jouni Malinenf7222712019-06-13 01:50:21 +03001579static enum sigma_cmd_result cmd_sta_is_connected(struct sigma_dut *dut,
1580 struct sigma_conn *conn,
1581 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001582{
1583 /* const char *intf = get_param(cmd, "Interface"); */
1584 int connected = 0;
1585 char result[32];
1586 if (get_wpa_status(get_station_ifname(), "wpa_state", result,
1587 sizeof(result)) < 0) {
1588 sigma_dut_print(dut, DUT_MSG_INFO, "Could not get interface "
1589 "%s status", get_station_ifname());
1590 return -2;
1591 }
1592
1593 sigma_dut_print(dut, DUT_MSG_DEBUG, "wpa_state=%s", result);
1594 if (strncmp(result, "COMPLETED", 9) == 0)
1595 connected = 1;
1596
1597 if (connected)
1598 send_resp(dut, conn, SIGMA_COMPLETE, "connected,1");
1599 else
1600 send_resp(dut, conn, SIGMA_COMPLETE, "connected,0");
1601
1602 return 0;
1603}
1604
1605
Jouni Malinenf7222712019-06-13 01:50:21 +03001606static enum sigma_cmd_result
1607cmd_sta_verify_ip_connection(struct sigma_dut *dut, struct sigma_conn *conn,
1608 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001609{
1610 /* const char *intf = get_param(cmd, "Interface"); */
1611 const char *dst, *timeout;
1612 int wait_time = 90;
1613 char buf[100];
1614 int res;
1615
1616 dst = get_param(cmd, "destination");
1617 if (dst == NULL || !is_ip_addr(dst))
1618 return -1;
1619
1620 timeout = get_param(cmd, "timeout");
1621 if (timeout) {
1622 wait_time = atoi(timeout);
1623 if (wait_time < 1)
1624 wait_time = 1;
1625 }
1626
1627 /* TODO: force renewal of IP lease if DHCP is enabled */
1628
1629 snprintf(buf, sizeof(buf), "ping %s -c 3 -W %d", dst, wait_time);
1630 res = system(buf);
1631 sigma_dut_print(dut, DUT_MSG_DEBUG, "ping returned: %d", res);
1632 if (res == 0)
1633 send_resp(dut, conn, SIGMA_COMPLETE, "connected,1");
1634 else if (res == 256)
1635 send_resp(dut, conn, SIGMA_COMPLETE, "connected,0");
1636 else
1637 return -2;
1638
1639 return 0;
1640}
1641
1642
Jouni Malinenf7222712019-06-13 01:50:21 +03001643static enum sigma_cmd_result cmd_sta_get_bssid(struct sigma_dut *dut,
1644 struct sigma_conn *conn,
1645 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001646{
1647 /* const char *intf = get_param(cmd, "Interface"); */
1648 char bssid[20], resp[50];
1649
1650 if (get_wpa_status(get_station_ifname(), "bssid", bssid, sizeof(bssid))
1651 < 0)
Peng Xub8fc5cc2017-05-10 17:27:28 -07001652 strlcpy(bssid, "00:00:00:00:00:00", sizeof(bssid));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001653
1654 snprintf(resp, sizeof(resp), "bssid,%s", bssid);
1655 send_resp(dut, conn, SIGMA_COMPLETE, resp);
1656 return 0;
1657}
1658
1659
1660#ifdef __SAMSUNG__
1661static int add_use_network(const char *ifname)
1662{
1663 char buf[100];
1664
1665 snprintf(buf, sizeof(buf), "USE_NETWORK ON");
1666 wpa_command(ifname, buf);
1667 return 0;
1668}
1669#endif /* __SAMSUNG__ */
1670
1671
1672static int add_network_common(struct sigma_dut *dut, struct sigma_conn *conn,
1673 const char *ifname, struct sigma_cmd *cmd)
1674{
1675 const char *ssid = get_param(cmd, "ssid");
1676 int id;
1677 const char *val;
1678
1679 if (ssid == NULL)
1680 return -1;
1681
1682 start_sta_mode(dut);
1683
1684#ifdef __SAMSUNG__
1685 add_use_network(ifname);
1686#endif /* __SAMSUNG__ */
1687
1688 id = add_network(ifname);
1689 if (id < 0)
1690 return -2;
1691 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding network %d", id);
1692
1693 if (set_network_quoted(ifname, id, "ssid", ssid) < 0)
1694 return -2;
1695
1696 dut->infra_network_id = id;
1697 snprintf(dut->infra_ssid, sizeof(dut->infra_ssid), "%s", ssid);
1698
1699 val = get_param(cmd, "program");
1700 if (!val)
1701 val = get_param(cmd, "prog");
1702 if (val && strcasecmp(val, "hs2") == 0) {
1703 char buf[100];
1704 snprintf(buf, sizeof(buf), "ENABLE_NETWORK %d no-connect", id);
1705 wpa_command(ifname, buf);
1706
1707 val = get_param(cmd, "prefer");
1708 if (val && atoi(val) > 0)
1709 set_network(ifname, id, "priority", "1");
1710 }
1711
1712 return id;
1713}
1714
1715
Jouni Malinenf7222712019-06-13 01:50:21 +03001716static enum sigma_cmd_result cmd_sta_set_encryption(struct sigma_dut *dut,
1717 struct sigma_conn *conn,
1718 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001719{
1720 const char *intf = get_param(cmd, "Interface");
1721 const char *ssid = get_param(cmd, "ssid");
1722 const char *type = get_param(cmd, "encpType");
1723 const char *ifname;
1724 char buf[200];
1725 int id;
1726
1727 if (intf == NULL || ssid == NULL)
1728 return -1;
1729
1730 if (strcmp(intf, get_main_ifname()) == 0)
1731 ifname = get_station_ifname();
1732 else
1733 ifname = intf;
1734
1735 id = add_network_common(dut, conn, ifname, cmd);
1736 if (id < 0)
1737 return id;
1738
1739 if (set_network(ifname, id, "key_mgmt", "NONE") < 0)
1740 return -2;
1741
1742 if (type && strcasecmp(type, "wep") == 0) {
1743 const char *val;
1744 int i;
1745
1746 val = get_param(cmd, "activeKey");
1747 if (val) {
1748 int keyid;
1749 keyid = atoi(val);
1750 if (keyid < 1 || keyid > 4)
1751 return -1;
1752 snprintf(buf, sizeof(buf), "%d", keyid - 1);
1753 if (set_network(ifname, id, "wep_tx_keyidx", buf) < 0)
1754 return -2;
1755 }
1756
1757 for (i = 0; i < 4; i++) {
1758 snprintf(buf, sizeof(buf), "key%d", i + 1);
1759 val = get_param(cmd, buf);
1760 if (val == NULL)
1761 continue;
1762 snprintf(buf, sizeof(buf), "wep_key%d", i);
1763 if (set_network(ifname, id, buf, val) < 0)
1764 return -2;
1765 }
1766 }
1767
1768 return 1;
1769}
1770
1771
Jouni Malinene4fde732019-03-25 22:29:37 +02001772static int set_akm_suites(struct sigma_dut *dut, const char *ifname,
1773 int id, const char *val)
1774{
1775 char key_mgmt[200], *end, *pos;
1776 const char *in_pos = val;
1777
Jouni Malinen8179fee2019-03-28 03:19:47 +02001778 dut->akm_values = 0;
Jouni Malinene4fde732019-03-25 22:29:37 +02001779 pos = key_mgmt;
1780 end = pos + sizeof(key_mgmt);
1781 while (*in_pos) {
1782 int res, akm = atoi(in_pos);
1783 const char *str;
1784
Jouni Malinen8179fee2019-03-28 03:19:47 +02001785 if (akm >= 0 && akm < 32)
1786 dut->akm_values |= 1 << akm;
1787
Jouni Malinene4fde732019-03-25 22:29:37 +02001788 switch (akm) {
1789 case AKM_WPA_EAP:
1790 str = "WPA-EAP";
1791 break;
1792 case AKM_WPA_PSK:
1793 str = "WPA-PSK";
1794 break;
1795 case AKM_FT_EAP:
1796 str = "FT-EAP";
1797 break;
1798 case AKM_FT_PSK:
1799 str = "FT-PSK";
1800 break;
1801 case AKM_EAP_SHA256:
1802 str = "WPA-EAP-SHA256";
1803 break;
1804 case AKM_PSK_SHA256:
1805 str = "WPA-PSK-SHA256";
1806 break;
1807 case AKM_SAE:
1808 str = "SAE";
1809 break;
1810 case AKM_FT_SAE:
1811 str = "FT-SAE";
1812 break;
1813 case AKM_SUITE_B:
1814 str = "WPA-EAP-SUITE-B-192";
1815 break;
1816 case AKM_FT_SUITE_B:
1817 str = "FT-EAP-SHA384";
1818 break;
1819 case AKM_FILS_SHA256:
1820 str = "FILS-SHA256";
1821 break;
1822 case AKM_FILS_SHA384:
1823 str = "FILS-SHA384";
1824 break;
1825 case AKM_FT_FILS_SHA256:
1826 str = "FT-FILS-SHA256";
1827 break;
1828 case AKM_FT_FILS_SHA384:
1829 str = "FT-FILS-SHA384";
1830 break;
1831 default:
1832 sigma_dut_print(dut, DUT_MSG_ERROR,
1833 "Unsupported AKMSuitetype %d", akm);
1834 return -1;
1835 }
1836
1837 res = snprintf(pos, end - pos, "%s%s",
1838 pos == key_mgmt ? "" : " ", str);
1839 if (res < 0 || res >= end - pos)
1840 return -1;
1841 pos += res;
1842
1843 in_pos = strchr(in_pos, ';');
1844 if (!in_pos)
1845 break;
1846 while (*in_pos == ';')
1847 in_pos++;
1848 }
1849 sigma_dut_print(dut, DUT_MSG_DEBUG, "AKMSuiteType %s --> %s",
1850 val, key_mgmt);
1851 return set_network(ifname, id, "key_mgmt", key_mgmt);
1852}
1853
1854
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001855static int set_wpa_common(struct sigma_dut *dut, struct sigma_conn *conn,
1856 const char *ifname, struct sigma_cmd *cmd)
1857{
1858 const char *val;
1859 int id;
Jouni Malinenad395a22017-09-01 21:13:46 +03001860 int cipher_set = 0;
Jouni Malinen47dcc952017-10-09 16:43:24 +03001861 int owe;
Sunil Duttc75a1e62018-01-11 20:47:50 +05301862 int suite_b = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001863
1864 id = add_network_common(dut, conn, ifname, cmd);
1865 if (id < 0)
1866 return id;
1867
Jouni Malinen47dcc952017-10-09 16:43:24 +03001868 val = get_param(cmd, "Type");
1869 owe = val && strcasecmp(val, "OWE") == 0;
1870
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001871 val = get_param(cmd, "keyMgmtType");
Jouni Malinen47dcc952017-10-09 16:43:24 +03001872 if (!val && owe)
1873 val = "OWE";
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001874 if (val == NULL) {
Jouni Malinene4fde732019-03-25 22:29:37 +02001875 /* keyMgmtType is being replaced with AKMSuiteType, so ignore
1876 * this missing parameter and assume proto=WPA2. */
1877 if (set_network(ifname, id, "proto", "WPA2") < 0)
1878 return ERROR_SEND_STATUS;
1879 } else if (strcasecmp(val, "wpa") == 0 ||
1880 strcasecmp(val, "wpa-psk") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001881 if (set_network(ifname, id, "proto", "WPA") < 0)
1882 return -2;
1883 } else if (strcasecmp(val, "wpa2") == 0 ||
1884 strcasecmp(val, "wpa2-psk") == 0 ||
1885 strcasecmp(val, "wpa2-ft") == 0 ||
1886 strcasecmp(val, "wpa2-sha256") == 0) {
1887 if (set_network(ifname, id, "proto", "WPA2") < 0)
1888 return -2;
Pradeep Reddy POTTETI6d04b3b2016-11-15 14:51:26 +05301889 } else if (strcasecmp(val, "wpa2-wpa-psk") == 0 ||
1890 strcasecmp(val, "wpa2-wpa-ent") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001891 if (set_network(ifname, id, "proto", "WPA WPA2") < 0)
1892 return -2;
Jouni Malinenad395a22017-09-01 21:13:46 +03001893 } else if (strcasecmp(val, "SuiteB") == 0) {
Sunil Duttc75a1e62018-01-11 20:47:50 +05301894 suite_b = 1;
Jouni Malinenad395a22017-09-01 21:13:46 +03001895 if (set_network(ifname, id, "proto", "WPA2") < 0)
1896 return -2;
Jouni Malinen47dcc952017-10-09 16:43:24 +03001897 } else if (strcasecmp(val, "OWE") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001898 } else {
1899 send_resp(dut, conn, SIGMA_INVALID, "errorCode,Unrecognized keyMgmtType value");
1900 return 0;
1901 }
1902
1903 val = get_param(cmd, "encpType");
Jouni Malinenad395a22017-09-01 21:13:46 +03001904 if (val) {
1905 cipher_set = 1;
1906 if (strcasecmp(val, "tkip") == 0) {
1907 if (set_network(ifname, id, "pairwise", "TKIP") < 0)
1908 return -2;
1909 } else if (strcasecmp(val, "aes-ccmp") == 0) {
1910 if (set_network(ifname, id, "pairwise", "CCMP") < 0)
1911 return -2;
1912 } else if (strcasecmp(val, "aes-ccmp-tkip") == 0) {
1913 if (set_network(ifname, id, "pairwise",
1914 "CCMP TKIP") < 0)
1915 return -2;
1916 } else if (strcasecmp(val, "aes-gcmp") == 0) {
1917 if (set_network(ifname, id, "pairwise", "GCMP") < 0)
1918 return -2;
1919 if (set_network(ifname, id, "group", "GCMP") < 0)
1920 return -2;
1921 } else {
1922 send_resp(dut, conn, SIGMA_ERROR,
1923 "errorCode,Unrecognized encpType value");
1924 return 0;
1925 }
1926 }
1927
1928 val = get_param(cmd, "PairwiseCipher");
1929 if (val) {
1930 cipher_set = 1;
1931 /* TODO: Support space separated list */
1932 if (strcasecmp(val, "AES-GCMP-256") == 0) {
1933 if (set_network(ifname, id, "pairwise", "GCMP-256") < 0)
1934 return -2;
1935 } else if (strcasecmp(val, "AES-CCMP-256") == 0) {
1936 if (set_network(ifname, id, "pairwise",
1937 "CCMP-256") < 0)
1938 return -2;
1939 } else if (strcasecmp(val, "AES-GCMP-128") == 0) {
1940 if (set_network(ifname, id, "pairwise", "GCMP") < 0)
1941 return -2;
1942 } else if (strcasecmp(val, "AES-CCMP-128") == 0) {
1943 if (set_network(ifname, id, "pairwise", "CCMP") < 0)
1944 return -2;
1945 } else {
1946 send_resp(dut, conn, SIGMA_ERROR,
1947 "errorCode,Unrecognized PairwiseCipher value");
1948 return 0;
1949 }
1950 }
1951
Jouni Malinen47dcc952017-10-09 16:43:24 +03001952 if (!cipher_set && !owe) {
Jouni Malinenad395a22017-09-01 21:13:46 +03001953 send_resp(dut, conn, SIGMA_ERROR,
1954 "errorCode,Missing encpType and PairwiseCipher");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001955 return 0;
1956 }
Jouni Malinenad395a22017-09-01 21:13:46 +03001957
1958 val = get_param(cmd, "GroupCipher");
1959 if (val) {
1960 if (strcasecmp(val, "AES-GCMP-256") == 0) {
1961 if (set_network(ifname, id, "group", "GCMP-256") < 0)
1962 return -2;
1963 } else if (strcasecmp(val, "AES-CCMP-256") == 0) {
1964 if (set_network(ifname, id, "group", "CCMP-256") < 0)
1965 return -2;
1966 } else if (strcasecmp(val, "AES-GCMP-128") == 0) {
1967 if (set_network(ifname, id, "group", "GCMP") < 0)
1968 return -2;
1969 } else if (strcasecmp(val, "AES-CCMP-128") == 0) {
1970 if (set_network(ifname, id, "group", "CCMP") < 0)
1971 return -2;
1972 } else {
1973 send_resp(dut, conn, SIGMA_ERROR,
1974 "errorCode,Unrecognized GroupCipher value");
1975 return 0;
1976 }
1977 }
1978
Jouni Malinen7b239522017-09-14 21:37:18 +03001979 val = get_param(cmd, "GroupMgntCipher");
Jouni Malinenad395a22017-09-01 21:13:46 +03001980 if (val) {
Jouni Malinene8898cb2017-09-26 17:55:26 +03001981 const char *cipher;
1982
1983 if (strcasecmp(val, "BIP-GMAC-256") == 0) {
1984 cipher = "BIP-GMAC-256";
1985 } else if (strcasecmp(val, "BIP-CMAC-256") == 0) {
1986 cipher = "BIP-CMAC-256";
1987 } else if (strcasecmp(val, "BIP-GMAC-128") == 0) {
1988 cipher = "BIP-GMAC-128";
1989 } else if (strcasecmp(val, "BIP-CMAC-128") == 0) {
1990 cipher = "AES-128-CMAC";
1991 } else {
1992 send_resp(dut, conn, SIGMA_INVALID,
1993 "errorCode,Unsupported GroupMgntCipher");
1994 return 0;
1995 }
1996 if (set_network(ifname, id, "group_mgmt", cipher) < 0) {
1997 send_resp(dut, conn, SIGMA_INVALID,
1998 "errorCode,Failed to set GroupMgntCipher");
1999 return 0;
2000 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002001 }
2002
Jouni Malinene4fde732019-03-25 22:29:37 +02002003 val = get_param(cmd, "AKMSuiteType");
2004 if (val && set_akm_suites(dut, ifname, id, val) < 0)
2005 return ERROR_SEND_STATUS;
2006
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002007 dut->sta_pmf = STA_PMF_DISABLED;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302008
2009 if (dut->program == PROGRAM_OCE) {
2010 dut->sta_pmf = STA_PMF_OPTIONAL;
2011 if (set_network(ifname, id, "ieee80211w", "1") < 0)
2012 return -2;
2013 }
2014
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002015 val = get_param(cmd, "PMF");
2016 if (val) {
2017 if (strcasecmp(val, "Required") == 0 ||
2018 strcasecmp(val, "Forced_Required") == 0) {
2019 dut->sta_pmf = STA_PMF_REQUIRED;
2020 if (set_network(ifname, id, "ieee80211w", "2") < 0)
2021 return -2;
2022 } else if (strcasecmp(val, "Optional") == 0) {
2023 dut->sta_pmf = STA_PMF_OPTIONAL;
2024 if (set_network(ifname, id, "ieee80211w", "1") < 0)
2025 return -2;
2026 } else if (strcasecmp(val, "Disabled") == 0 ||
Kiran Kumar Lokere07da3b22018-12-16 22:42:49 -08002027 strcasecmp(val, "Disable") == 0 ||
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002028 strcasecmp(val, "Forced_Disabled") == 0) {
2029 dut->sta_pmf = STA_PMF_DISABLED;
2030 } else {
2031 send_resp(dut, conn, SIGMA_INVALID, "errorCode,Unrecognized PMF value");
2032 return 0;
2033 }
Sunil Duttc75a1e62018-01-11 20:47:50 +05302034 } else if (owe || suite_b) {
Jouni Malinen1287cd72018-01-04 17:08:01 +02002035 dut->sta_pmf = STA_PMF_REQUIRED;
2036 if (set_network(ifname, id, "ieee80211w", "2") < 0)
2037 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002038 }
2039
2040 return id;
2041}
2042
2043
Jouni Malinenf7222712019-06-13 01:50:21 +03002044static enum sigma_cmd_result cmd_sta_set_psk(struct sigma_dut *dut,
2045 struct sigma_conn *conn,
2046 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002047{
2048 const char *intf = get_param(cmd, "Interface");
Jouni Malinen992a81e2017-08-22 13:57:47 +03002049 const char *type = get_param(cmd, "Type");
Jouni Malinen1287cd72018-01-04 17:08:01 +02002050 const char *pmf = get_param(cmd, "PMF");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002051 const char *network_mode = get_param(cmd, "network_mode");
Jouni Malinene4fde732019-03-25 22:29:37 +02002052 const char *akm = get_param(cmd, "AKMSuiteType");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002053 const char *ifname, *val, *alg;
2054 int id;
2055
2056 if (intf == NULL)
2057 return -1;
2058
2059 if (strcmp(intf, get_main_ifname()) == 0)
2060 ifname = get_station_ifname();
2061 else
2062 ifname = intf;
2063
2064 id = set_wpa_common(dut, conn, ifname, cmd);
2065 if (id < 0)
2066 return id;
2067
2068 val = get_param(cmd, "keyMgmtType");
2069 alg = get_param(cmd, "micAlg");
2070
Jouni Malinen992a81e2017-08-22 13:57:47 +03002071 if (type && strcasecmp(type, "SAE") == 0) {
Jouni Malinene4fde732019-03-25 22:29:37 +02002072 if (!akm && val && strcasecmp(val, "wpa2-ft") == 0) {
Jouni Malinen992a81e2017-08-22 13:57:47 +03002073 if (set_network(ifname, id, "key_mgmt", "FT-SAE") < 0)
2074 return -2;
Jouni Malinene4fde732019-03-25 22:29:37 +02002075 } else if (!akm) {
Jouni Malinen992a81e2017-08-22 13:57:47 +03002076 if (set_network(ifname, id, "key_mgmt", "SAE") < 0)
2077 return -2;
2078 }
2079 if (wpa_command(ifname, "SET sae_groups ") != 0) {
2080 sigma_dut_print(dut, DUT_MSG_ERROR,
2081 "Failed to clear sae_groups to default");
2082 return -2;
2083 }
Jouni Malinen1287cd72018-01-04 17:08:01 +02002084 if (!pmf) {
2085 dut->sta_pmf = STA_PMF_REQUIRED;
2086 if (set_network(ifname, id, "ieee80211w", "2") < 0)
2087 return -2;
2088 }
Jouni Malinen0ab50f42017-08-31 01:34:59 +03002089 } else if (type && strcasecmp(type, "PSK-SAE") == 0) {
2090 if (val && strcasecmp(val, "wpa2-ft") == 0) {
2091 if (set_network(ifname, id, "key_mgmt",
2092 "FT-SAE FT-PSK") < 0)
2093 return -2;
Jouni Malinen3b73d872019-06-12 03:13:25 +03002094 } else if (!akm) {
Jouni Malinen0ab50f42017-08-31 01:34:59 +03002095 if (set_network(ifname, id, "key_mgmt",
2096 "SAE WPA-PSK") < 0)
2097 return -2;
2098 }
2099 if (wpa_command(ifname, "SET sae_groups ") != 0) {
2100 sigma_dut_print(dut, DUT_MSG_ERROR,
2101 "Failed to clear sae_groups to default");
2102 return -2;
2103 }
Jouni Malinen1287cd72018-01-04 17:08:01 +02002104 if (!pmf) {
2105 dut->sta_pmf = STA_PMF_OPTIONAL;
2106 if (set_network(ifname, id, "ieee80211w", "1") < 0)
2107 return -2;
2108 }
Jouni Malinen992a81e2017-08-22 13:57:47 +03002109 } else if (alg && strcasecmp(alg, "SHA-256") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002110 if (set_network(ifname, id, "key_mgmt", "WPA-PSK-SHA256") < 0)
2111 return -2;
2112 } else if (alg && strcasecmp(alg, "SHA-1") == 0) {
2113 if (set_network(ifname, id, "key_mgmt", "WPA-PSK") < 0)
2114 return -2;
Ashwini Patil6dbf7b02017-03-20 13:42:11 +05302115 } else if (val && strcasecmp(val, "wpa2-ft") == 0) {
2116 if (set_network(ifname, id, "key_mgmt", "FT-PSK") < 0)
2117 return -2;
Jouni Malinen3b73d872019-06-12 03:13:25 +03002118 } else if (!akm &&
2119 ((val && strcasecmp(val, "wpa2-sha256") == 0) ||
2120 dut->sta_pmf == STA_PMF_REQUIRED)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002121 if (set_network(ifname, id, "key_mgmt",
2122 "WPA-PSK WPA-PSK-SHA256") < 0)
2123 return -2;
Jouni Malinen77ff3f02019-03-28 03:45:40 +02002124 } else if (!akm && dut->sta_pmf == STA_PMF_OPTIONAL) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002125 if (set_network(ifname, id, "key_mgmt",
2126 "WPA-PSK WPA-PSK-SHA256") < 0)
2127 return -2;
Jouni Malinen77ff3f02019-03-28 03:45:40 +02002128 } else if (!akm) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002129 if (set_network(ifname, id, "key_mgmt", "WPA-PSK") < 0)
2130 return -2;
2131 }
2132
2133 val = get_param(cmd, "passPhrase");
2134 if (val == NULL)
2135 return -1;
Jouni Malinen2126f422017-10-11 23:24:33 +03002136 if (type && strcasecmp(type, "SAE") == 0) {
2137 if (set_network_quoted(ifname, id, "sae_password", val) < 0)
2138 return -2;
2139 } else {
2140 if (set_network_quoted(ifname, id, "psk", val) < 0)
2141 return -2;
2142 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002143
Jouni Malinen78d10c42019-03-25 22:34:32 +02002144 val = get_param(cmd, "PasswordId");
2145 if (val && set_network_quoted(ifname, id, "sae_password_id", val) < 0)
2146 return ERROR_SEND_STATUS;
2147
Jouni Malinen992a81e2017-08-22 13:57:47 +03002148 val = get_param(cmd, "ECGroupID");
2149 if (val) {
2150 char buf[50];
2151
2152 snprintf(buf, sizeof(buf), "SET sae_groups %u", atoi(val));
2153 if (wpa_command(ifname, buf) != 0) {
2154 sigma_dut_print(dut, DUT_MSG_ERROR,
2155 "Failed to clear sae_groups");
2156 return -2;
2157 }
2158 }
2159
Jouni Malinen68143132017-09-02 02:34:08 +03002160 val = get_param(cmd, "InvalidSAEElement");
2161 if (val) {
2162 free(dut->sae_commit_override);
2163 dut->sae_commit_override = strdup(val);
2164 }
2165
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002166 if (dut->program == PROGRAM_60GHZ && network_mode &&
2167 strcasecmp(network_mode, "PBSS") == 0 &&
2168 set_network(ifname, id, "pbss", "1") < 0)
2169 return -2;
2170
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002171 return 1;
2172}
2173
2174
2175static int set_eap_common(struct sigma_dut *dut, struct sigma_conn *conn,
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302176 const char *ifname, int username_identity,
2177 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002178{
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302179 const char *val, *alg, *akm;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002180 int id;
Jouni Malinen53264f62019-05-03 13:04:40 +03002181 char buf[200], buf2[300];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002182#ifdef ANDROID
2183 unsigned char kvalue[KEYSTORE_MESSAGE_SIZE];
2184 int length;
2185#endif /* ANDROID */
Jouni Malinen8179fee2019-03-28 03:19:47 +02002186 int erp = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002187
2188 id = set_wpa_common(dut, conn, ifname, cmd);
2189 if (id < 0)
2190 return id;
2191
2192 val = get_param(cmd, "keyMgmtType");
2193 alg = get_param(cmd, "micAlg");
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302194 akm = get_param(cmd, "AKMSuiteType");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002195
Jouni Malinenad395a22017-09-01 21:13:46 +03002196 if (val && strcasecmp(val, "SuiteB") == 0) {
2197 if (set_network(ifname, id, "key_mgmt", "WPA-EAP-SUITE-B-192") <
2198 0)
2199 return -2;
2200 } else if (alg && strcasecmp(alg, "SHA-256") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002201 if (set_network(ifname, id, "key_mgmt", "WPA-EAP-SHA256") < 0)
2202 return -2;
2203 } else if (alg && strcasecmp(alg, "SHA-1") == 0) {
2204 if (set_network(ifname, id, "key_mgmt", "WPA-EAP") < 0)
2205 return -2;
2206 } else if (val && strcasecmp(val, "wpa2-ft") == 0) {
2207 if (set_network(ifname, id, "key_mgmt", "FT-EAP") < 0)
2208 return -2;
Jouni Malinend6a9d692019-03-28 03:01:24 +02002209 } else if (!akm &&
2210 ((val && strcasecmp(val, "wpa2-sha256") == 0) ||
2211 dut->sta_pmf == STA_PMF_REQUIRED)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002212 if (set_network(ifname, id, "key_mgmt",
2213 "WPA-EAP WPA-EAP-SHA256") < 0)
2214 return -2;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302215 } else if (akm && atoi(akm) == 14) {
2216 if (dut->sta_pmf == STA_PMF_OPTIONAL ||
2217 dut->sta_pmf == STA_PMF_REQUIRED) {
2218 if (set_network(ifname, id, "key_mgmt",
2219 "WPA-EAP-SHA256 FILS-SHA256") < 0)
2220 return -2;
2221 } else {
2222 if (set_network(ifname, id, "key_mgmt",
2223 "WPA-EAP FILS-SHA256") < 0)
2224 return -2;
2225 }
2226
Jouni Malinen8179fee2019-03-28 03:19:47 +02002227 erp = 1;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302228 } else if (akm && atoi(akm) == 15) {
2229 if (dut->sta_pmf == STA_PMF_OPTIONAL ||
2230 dut->sta_pmf == STA_PMF_REQUIRED) {
2231 if (set_network(ifname, id, "key_mgmt",
2232 "WPA-EAP-SHA256 FILS-SHA384") < 0)
2233 return -2;
2234 } else {
2235 if (set_network(ifname, id, "key_mgmt",
2236 "WPA-EAP FILS-SHA384") < 0)
2237 return -2;
2238 }
2239
Jouni Malinen8179fee2019-03-28 03:19:47 +02002240 erp = 1;
Jouni Malinend6a9d692019-03-28 03:01:24 +02002241 } else if (!akm && dut->sta_pmf == STA_PMF_OPTIONAL) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002242 if (set_network(ifname, id, "key_mgmt",
2243 "WPA-EAP WPA-EAP-SHA256") < 0)
2244 return -2;
Jouni Malinend6a9d692019-03-28 03:01:24 +02002245 } else if (!akm) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002246 if (set_network(ifname, id, "key_mgmt", "WPA-EAP") < 0)
2247 return -2;
2248 }
2249
2250 val = get_param(cmd, "trustedRootCA");
2251 if (val) {
2252#ifdef ANDROID
2253 snprintf(buf, sizeof(buf), "CACERT_%s", val);
2254 length = android_keystore_get(ANDROID_KEYSTORE_GET, buf,
2255 kvalue);
2256 if (length > 0) {
2257 sigma_dut_print(dut, DUT_MSG_INFO,
2258 "Use Android keystore [%s]", buf);
2259 snprintf(buf, sizeof(buf), "keystore://CACERT_%s",
2260 val);
2261 goto ca_cert_selected;
2262 }
2263#endif /* ANDROID */
2264
2265 snprintf(buf, sizeof(buf), "%s/%s", sigma_cert_path, val);
2266#ifdef __linux__
2267 if (!file_exists(buf)) {
2268 char msg[300];
2269 snprintf(msg, sizeof(msg), "ErrorCode,trustedRootCA "
2270 "file (%s) not found", buf);
2271 send_resp(dut, conn, SIGMA_ERROR, msg);
2272 return -3;
2273 }
2274#endif /* __linux__ */
2275#ifdef ANDROID
2276ca_cert_selected:
2277#endif /* ANDROID */
2278 if (set_network_quoted(ifname, id, "ca_cert", buf) < 0)
2279 return -2;
2280 }
2281
Jouni Malinen53264f62019-05-03 13:04:40 +03002282 val = get_param(cmd, "ServerCert");
2283 if (val) {
2284 FILE *f;
2285 char *result = NULL, *pos;
2286
2287 snprintf(buf, sizeof(buf), "%s/%s.sha256", sigma_cert_path,
2288 val);
2289 f = fopen(buf, "r");
2290 if (f) {
2291 result = fgets(buf, sizeof(buf), f);
2292 fclose(f);
2293 }
2294 if (!result) {
2295 snprintf(buf2, sizeof(buf2),
2296 "ErrorCode,ServerCert hash could not be read from %s",
2297 buf);
2298 send_resp(dut, conn, SIGMA_ERROR, buf2);
2299 return STATUS_SENT_ERROR;
2300 }
2301 pos = strchr(buf, '\n');
2302 if (pos)
2303 *pos = '\0';
2304 snprintf(buf2, sizeof(buf2), "hash://server/sha256/%s", buf);
2305 if (set_network_quoted(ifname, id, "ca_cert", buf2) < 0)
2306 return ERROR_SEND_STATUS;
2307 }
2308
Jouni Malinen96f84b02019-05-03 12:32:56 +03002309 val = get_param(cmd, "Domain");
2310 if (val && set_network_quoted(ifname, id, "domain_match", val) < 0)
2311 return ERROR_SEND_STATUS;
2312
2313 val = get_param(cmd, "DomainSuffix");
2314 if (val &&
2315 set_network_quoted(ifname, id, "domain_suffix_match", val) < 0)
2316 return ERROR_SEND_STATUS;
2317
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302318 if (username_identity) {
2319 val = get_param(cmd, "username");
2320 if (val) {
2321 if (set_network_quoted(ifname, id, "identity", val) < 0)
2322 return -2;
2323 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002324
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302325 val = get_param(cmd, "password");
2326 if (val) {
2327 if (set_network_quoted(ifname, id, "password", val) < 0)
2328 return -2;
2329 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002330 }
2331
Jouni Malinen8179fee2019-03-28 03:19:47 +02002332 if (dut->akm_values &
2333 ((1 << AKM_FILS_SHA256) |
2334 (1 << AKM_FILS_SHA384) |
2335 (1 << AKM_FT_FILS_SHA256) |
2336 (1 << AKM_FT_FILS_SHA384)))
2337 erp = 1;
2338 if (erp && set_network(ifname, id, "erp", "1") < 0)
2339 return ERROR_SEND_STATUS;
2340
Jouni Malinen134fe3c2019-06-12 04:16:49 +03002341 dut->sta_associate_wait_connect = 1;
2342
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002343 return id;
2344}
2345
2346
Jouni Malinen5eabb2a2017-10-03 18:17:30 +03002347static int set_tls_cipher(const char *ifname, int id, const char *cipher)
2348{
2349 const char *val;
2350
2351 if (!cipher)
2352 return 0;
2353
2354 if (strcasecmp(cipher, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384") == 0)
2355 val = "ECDHE-ECDSA-AES256-GCM-SHA384";
2356 else if (strcasecmp(cipher,
2357 "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384") == 0)
2358 val = "ECDHE-RSA-AES256-GCM-SHA384";
2359 else if (strcasecmp(cipher, "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384") == 0)
2360 val = "DHE-RSA-AES256-GCM-SHA384";
2361 else if (strcasecmp(cipher,
2362 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256") == 0)
2363 val = "ECDHE-ECDSA-AES128-GCM-SHA256";
2364 else
2365 return -1;
2366
2367 /* Need to clear phase1="tls_suiteb=1" to allow cipher enforcement */
2368 set_network_quoted(ifname, id, "phase1", "");
2369
2370 return set_network_quoted(ifname, id, "openssl_ciphers", val);
2371}
2372
2373
Jouni Malinenf7222712019-06-13 01:50:21 +03002374static enum sigma_cmd_result cmd_sta_set_eaptls(struct sigma_dut *dut,
2375 struct sigma_conn *conn,
2376 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002377{
2378 const char *intf = get_param(cmd, "Interface");
2379 const char *ifname, *val;
2380 int id;
2381 char buf[200];
2382#ifdef ANDROID
2383 unsigned char kvalue[KEYSTORE_MESSAGE_SIZE];
2384 int length;
2385 int jb_or_newer = 0;
2386 char prop[PROPERTY_VALUE_MAX];
2387#endif /* ANDROID */
2388
2389 if (intf == NULL)
2390 return -1;
2391
2392 if (strcmp(intf, get_main_ifname()) == 0)
2393 ifname = get_station_ifname();
2394 else
2395 ifname = intf;
2396
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302397 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002398 if (id < 0)
2399 return id;
2400
2401 if (set_network(ifname, id, "eap", "TLS") < 0)
2402 return -2;
2403
Pradeep Reddy POTTETI9f6c2132016-05-05 16:28:19 +05302404 if (!get_param(cmd, "username") &&
2405 set_network_quoted(ifname, id, "identity",
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002406 "wifi-user@wifilabs.local") < 0)
2407 return -2;
2408
2409 val = get_param(cmd, "clientCertificate");
2410 if (val == NULL)
2411 return -1;
2412#ifdef ANDROID
2413 snprintf(buf, sizeof(buf), "USRPKEY_%s", val);
2414 length = android_keystore_get(ANDROID_KEYSTORE_GET, buf, kvalue);
2415 if (length < 0) {
2416 /*
2417 * JB started reporting keystore type mismatches, so retry with
2418 * the GET_PUBKEY command if the generic GET fails.
2419 */
2420 length = android_keystore_get(ANDROID_KEYSTORE_GET_PUBKEY,
2421 buf, kvalue);
2422 }
2423
2424 if (property_get("ro.build.version.release", prop, NULL) != 0) {
2425 sigma_dut_print(dut, DUT_MSG_DEBUG, "Android release %s", prop);
2426 if (strncmp(prop, "4.0", 3) != 0)
2427 jb_or_newer = 1;
2428 } else
2429 jb_or_newer = 1; /* assume newer */
2430
2431 if (jb_or_newer && length > 0) {
2432 sigma_dut_print(dut, DUT_MSG_INFO,
2433 "Use Android keystore [%s]", buf);
2434 if (set_network(ifname, id, "engine", "1") < 0)
2435 return -2;
2436 if (set_network_quoted(ifname, id, "engine_id", "keystore") < 0)
2437 return -2;
2438 snprintf(buf, sizeof(buf), "USRPKEY_%s", val);
2439 if (set_network_quoted(ifname, id, "key_id", buf) < 0)
2440 return -2;
2441 snprintf(buf, sizeof(buf), "keystore://USRCERT_%s", val);
2442 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
2443 return -2;
2444 return 1;
2445 } else if (length > 0) {
2446 sigma_dut_print(dut, DUT_MSG_INFO,
2447 "Use Android keystore [%s]", buf);
2448 snprintf(buf, sizeof(buf), "keystore://USRPKEY_%s", val);
2449 if (set_network_quoted(ifname, id, "private_key", buf) < 0)
2450 return -2;
2451 snprintf(buf, sizeof(buf), "keystore://USRCERT_%s", val);
2452 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
2453 return -2;
2454 return 1;
2455 }
2456#endif /* ANDROID */
2457
2458 snprintf(buf, sizeof(buf), "%s/%s", sigma_cert_path, val);
2459#ifdef __linux__
2460 if (!file_exists(buf)) {
2461 char msg[300];
2462 snprintf(msg, sizeof(msg), "ErrorCode,clientCertificate file "
2463 "(%s) not found", buf);
2464 send_resp(dut, conn, SIGMA_ERROR, msg);
2465 return -3;
2466 }
2467#endif /* __linux__ */
2468 if (set_network_quoted(ifname, id, "private_key", buf) < 0)
2469 return -2;
2470 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
2471 return -2;
2472
2473 if (set_network_quoted(ifname, id, "private_key_passwd", "wifi") < 0)
2474 return -2;
2475
Jouni Malinen5eabb2a2017-10-03 18:17:30 +03002476 val = get_param(cmd, "keyMgmtType");
2477 if (val && strcasecmp(val, "SuiteB") == 0) {
2478 val = get_param(cmd, "CertType");
2479 if (val && strcasecmp(val, "RSA") == 0) {
2480 if (set_network_quoted(ifname, id, "phase1",
2481 "tls_suiteb=1") < 0)
2482 return -2;
2483 } else {
2484 if (set_network_quoted(ifname, id, "openssl_ciphers",
2485 "SUITEB192") < 0)
2486 return -2;
2487 }
2488
2489 val = get_param(cmd, "TLSCipher");
2490 if (set_tls_cipher(ifname, id, val) < 0) {
2491 send_resp(dut, conn, SIGMA_ERROR,
2492 "ErrorCode,Unsupported TLSCipher value");
2493 return -3;
2494 }
2495 }
2496
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002497 return 1;
2498}
2499
2500
Jouni Malinenf7222712019-06-13 01:50:21 +03002501static enum sigma_cmd_result cmd_sta_set_eapttls(struct sigma_dut *dut,
2502 struct sigma_conn *conn,
2503 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002504{
2505 const char *intf = get_param(cmd, "Interface");
2506 const char *ifname;
2507 int id;
2508
2509 if (intf == NULL)
2510 return -1;
2511
2512 if (strcmp(intf, get_main_ifname()) == 0)
2513 ifname = get_station_ifname();
2514 else
2515 ifname = intf;
2516
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302517 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002518 if (id < 0)
2519 return id;
2520
2521 if (set_network(ifname, id, "eap", "TTLS") < 0) {
2522 send_resp(dut, conn, SIGMA_ERROR,
2523 "errorCode,Failed to set TTLS method");
2524 return 0;
2525 }
2526
2527 if (set_network_quoted(ifname, id, "phase2", "auth=MSCHAPV2") < 0) {
2528 send_resp(dut, conn, SIGMA_ERROR,
2529 "errorCode,Failed to set MSCHAPv2 for TTLS Phase 2");
2530 return 0;
2531 }
2532
2533 return 1;
2534}
2535
2536
Jouni Malinenf7222712019-06-13 01:50:21 +03002537static enum sigma_cmd_result cmd_sta_set_eapsim(struct sigma_dut *dut,
2538 struct sigma_conn *conn,
2539 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002540{
2541 const char *intf = get_param(cmd, "Interface");
2542 const char *ifname;
2543 int id;
2544
2545 if (intf == NULL)
2546 return -1;
2547
2548 if (strcmp(intf, get_main_ifname()) == 0)
2549 ifname = get_station_ifname();
2550 else
2551 ifname = intf;
2552
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302553 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002554 if (id < 0)
2555 return id;
2556
2557 if (set_network(ifname, id, "eap", "SIM") < 0)
2558 return -2;
2559
2560 return 1;
2561}
2562
2563
Jouni Malinenf7222712019-06-13 01:50:21 +03002564static enum sigma_cmd_result cmd_sta_set_peap(struct sigma_dut *dut,
2565 struct sigma_conn *conn,
2566 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002567{
2568 const char *intf = get_param(cmd, "Interface");
2569 const char *ifname, *val;
2570 int id;
2571 char buf[100];
2572
2573 if (intf == NULL)
2574 return -1;
2575
2576 if (strcmp(intf, get_main_ifname()) == 0)
2577 ifname = get_station_ifname();
2578 else
2579 ifname = intf;
2580
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302581 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002582 if (id < 0)
2583 return id;
2584
2585 if (set_network(ifname, id, "eap", "PEAP") < 0)
2586 return -2;
2587
2588 val = get_param(cmd, "innerEAP");
2589 if (val) {
2590 if (strcasecmp(val, "MSCHAPv2") == 0) {
2591 if (set_network_quoted(ifname, id, "phase2",
2592 "auth=MSCHAPV2") < 0)
2593 return -2;
2594 } else if (strcasecmp(val, "GTC") == 0) {
2595 if (set_network_quoted(ifname, id, "phase2",
2596 "auth=GTC") < 0)
2597 return -2;
2598 } else
2599 return -1;
2600 }
2601
2602 val = get_param(cmd, "peapVersion");
2603 if (val) {
2604 int ver = atoi(val);
2605 if (ver < 0 || ver > 1)
2606 return -1;
2607 snprintf(buf, sizeof(buf), "peapver=%d", ver);
2608 if (set_network_quoted(ifname, id, "phase1", buf) < 0)
2609 return -2;
2610 }
2611
2612 return 1;
2613}
2614
2615
Jouni Malinenf7222712019-06-13 01:50:21 +03002616static enum sigma_cmd_result cmd_sta_set_eapfast(struct sigma_dut *dut,
2617 struct sigma_conn *conn,
2618 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002619{
2620 const char *intf = get_param(cmd, "Interface");
2621 const char *ifname, *val;
2622 int id;
2623 char buf[100];
2624
2625 if (intf == NULL)
2626 return -1;
2627
2628 if (strcmp(intf, get_main_ifname()) == 0)
2629 ifname = get_station_ifname();
2630 else
2631 ifname = intf;
2632
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302633 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002634 if (id < 0)
2635 return id;
2636
2637 if (set_network(ifname, id, "eap", "FAST") < 0)
2638 return -2;
2639
2640 val = get_param(cmd, "innerEAP");
2641 if (val) {
2642 if (strcasecmp(val, "MSCHAPV2") == 0) {
2643 if (set_network_quoted(ifname, id, "phase2",
2644 "auth=MSCHAPV2") < 0)
2645 return -2;
2646 } else if (strcasecmp(val, "GTC") == 0) {
2647 if (set_network_quoted(ifname, id, "phase2",
2648 "auth=GTC") < 0)
2649 return -2;
2650 } else
2651 return -1;
2652 }
2653
2654 val = get_param(cmd, "validateServer");
2655 if (val) {
2656 /* TODO */
2657 sigma_dut_print(dut, DUT_MSG_INFO, "Ignored EAP-FAST "
2658 "validateServer=%s", val);
2659 }
2660
2661 val = get_param(cmd, "pacFile");
2662 if (val) {
2663 snprintf(buf, sizeof(buf), "blob://%s", val);
2664 if (set_network_quoted(ifname, id, "pac_file", buf) < 0)
2665 return -2;
2666 }
2667
2668 if (set_network_quoted(ifname, id, "phase1", "fast_provisioning=2") <
2669 0)
2670 return -2;
2671
2672 return 1;
2673}
2674
2675
Jouni Malinenf7222712019-06-13 01:50:21 +03002676static enum sigma_cmd_result cmd_sta_set_eapaka(struct sigma_dut *dut,
2677 struct sigma_conn *conn,
2678 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002679{
2680 const char *intf = get_param(cmd, "Interface");
2681 const char *ifname;
2682 int id;
2683
2684 if (intf == NULL)
2685 return -1;
2686
2687 if (strcmp(intf, get_main_ifname()) == 0)
2688 ifname = get_station_ifname();
2689 else
2690 ifname = intf;
2691
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302692 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002693 if (id < 0)
2694 return id;
2695
2696 if (set_network(ifname, id, "eap", "AKA") < 0)
2697 return -2;
2698
2699 return 1;
2700}
2701
2702
Jouni Malinenf7222712019-06-13 01:50:21 +03002703static enum sigma_cmd_result cmd_sta_set_eapakaprime(struct sigma_dut *dut,
2704 struct sigma_conn *conn,
2705 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002706{
2707 const char *intf = get_param(cmd, "Interface");
2708 const char *ifname;
2709 int id;
2710
2711 if (intf == NULL)
2712 return -1;
2713
2714 if (strcmp(intf, get_main_ifname()) == 0)
2715 ifname = get_station_ifname();
2716 else
2717 ifname = intf;
2718
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302719 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002720 if (id < 0)
2721 return id;
2722
2723 if (set_network(ifname, id, "eap", "AKA'") < 0)
2724 return -2;
2725
2726 return 1;
2727}
2728
2729
2730static int sta_set_open(struct sigma_dut *dut, struct sigma_conn *conn,
2731 struct sigma_cmd *cmd)
2732{
2733 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002734 const char *network_mode = get_param(cmd, "network_mode");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002735 const char *ifname;
2736 int id;
2737
2738 if (strcmp(intf, get_main_ifname()) == 0)
2739 ifname = get_station_ifname();
2740 else
2741 ifname = intf;
2742
2743 id = add_network_common(dut, conn, ifname, cmd);
2744 if (id < 0)
2745 return id;
2746
2747 if (set_network(ifname, id, "key_mgmt", "NONE") < 0)
2748 return -2;
2749
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002750 if (dut->program == PROGRAM_60GHZ && network_mode &&
2751 strcasecmp(network_mode, "PBSS") == 0 &&
2752 set_network(ifname, id, "pbss", "1") < 0)
2753 return -2;
2754
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002755 return 1;
2756}
2757
2758
Jouni Malinen47dcc952017-10-09 16:43:24 +03002759static int sta_set_owe(struct sigma_dut *dut, struct sigma_conn *conn,
2760 struct sigma_cmd *cmd)
2761{
2762 const char *intf = get_param(cmd, "Interface");
2763 const char *ifname, *val;
2764 int id;
2765
2766 if (intf == NULL)
2767 return -1;
2768
2769 if (strcmp(intf, get_main_ifname()) == 0)
2770 ifname = get_station_ifname();
2771 else
2772 ifname = intf;
2773
2774 id = set_wpa_common(dut, conn, ifname, cmd);
2775 if (id < 0)
2776 return id;
2777
2778 if (set_network(ifname, id, "key_mgmt", "OWE") < 0)
2779 return -2;
2780
2781 val = get_param(cmd, "ECGroupID");
Jouni Malinenfac9cad2017-10-10 18:35:55 +03002782 if (val && strcmp(val, "0") == 0) {
2783 if (wpa_command(ifname,
2784 "VENDOR_ELEM_ADD 13 ff23200000783590fb7440e03d5b3b33911f86affdcc6b4411b707846ac4ff08ddc8831ccd") != 0) {
2785 sigma_dut_print(dut, DUT_MSG_ERROR,
2786 "Failed to set OWE DH Param element override");
2787 return -2;
2788 }
2789 } else if (val && set_network(ifname, id, "owe_group", val) < 0) {
Jouni Malinen47dcc952017-10-09 16:43:24 +03002790 sigma_dut_print(dut, DUT_MSG_ERROR,
2791 "Failed to clear owe_group");
2792 return -2;
2793 }
2794
2795 return 1;
2796}
2797
2798
Jouni Malinenf7222712019-06-13 01:50:21 +03002799static enum sigma_cmd_result cmd_sta_set_security(struct sigma_dut *dut,
2800 struct sigma_conn *conn,
2801 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002802{
2803 const char *type = get_param(cmd, "Type");
2804
2805 if (type == NULL) {
2806 send_resp(dut, conn, SIGMA_ERROR,
2807 "ErrorCode,Missing Type argument");
2808 return 0;
2809 }
2810
2811 if (strcasecmp(type, "OPEN") == 0)
2812 return sta_set_open(dut, conn, cmd);
Jouni Malinen47dcc952017-10-09 16:43:24 +03002813 if (strcasecmp(type, "OWE") == 0)
2814 return sta_set_owe(dut, conn, cmd);
Jouni Malinen992a81e2017-08-22 13:57:47 +03002815 if (strcasecmp(type, "PSK") == 0 ||
Jouni Malinen0ab50f42017-08-31 01:34:59 +03002816 strcasecmp(type, "PSK-SAE") == 0 ||
Jouni Malinen992a81e2017-08-22 13:57:47 +03002817 strcasecmp(type, "SAE") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002818 return cmd_sta_set_psk(dut, conn, cmd);
2819 if (strcasecmp(type, "EAPTLS") == 0)
2820 return cmd_sta_set_eaptls(dut, conn, cmd);
2821 if (strcasecmp(type, "EAPTTLS") == 0)
2822 return cmd_sta_set_eapttls(dut, conn, cmd);
2823 if (strcasecmp(type, "EAPPEAP") == 0)
2824 return cmd_sta_set_peap(dut, conn, cmd);
2825 if (strcasecmp(type, "EAPSIM") == 0)
2826 return cmd_sta_set_eapsim(dut, conn, cmd);
2827 if (strcasecmp(type, "EAPFAST") == 0)
2828 return cmd_sta_set_eapfast(dut, conn, cmd);
2829 if (strcasecmp(type, "EAPAKA") == 0)
2830 return cmd_sta_set_eapaka(dut, conn, cmd);
2831 if (strcasecmp(type, "EAPAKAPRIME") == 0)
2832 return cmd_sta_set_eapakaprime(dut, conn, cmd);
Amarnath Hullur Subramanyam81b11cd2018-01-30 19:07:17 -08002833 if (strcasecmp(type, "wep") == 0)
2834 return cmd_sta_set_encryption(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002835
2836 send_resp(dut, conn, SIGMA_ERROR,
2837 "ErrorCode,Unsupported Type value");
2838 return 0;
2839}
2840
2841
2842int ath6kl_client_uapsd(struct sigma_dut *dut, const char *intf, int uapsd)
2843{
2844#ifdef __linux__
2845 /* special handling for ath6kl */
2846 char path[128], fname[128], *pos;
2847 ssize_t res;
2848 FILE *f;
2849
Jouni Malinene39cd562019-05-29 23:39:56 +03002850 res = snprintf(fname, sizeof(fname), "/sys/class/net/%s/phy80211",
2851 intf);
2852 if (res < 0 || res >= sizeof(fname))
2853 return 0;
2854 res = readlink(fname, path, sizeof(path));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002855 if (res < 0)
2856 return 0; /* not ath6kl */
2857
2858 if (res >= (int) sizeof(path))
2859 res = sizeof(path) - 1;
2860 path[res] = '\0';
2861 pos = strrchr(path, '/');
2862 if (pos == NULL)
2863 pos = path;
2864 else
2865 pos++;
2866 snprintf(fname, sizeof(fname),
2867 "/sys/kernel/debug/ieee80211/%s/ath6kl/"
2868 "create_qos", pos);
2869 if (!file_exists(fname))
2870 return 0; /* not ath6kl */
2871
2872 if (uapsd) {
2873 f = fopen(fname, "w");
2874 if (f == NULL)
2875 return -1;
2876
2877 sigma_dut_print(dut, DUT_MSG_DEBUG, "Use ath6kl create_qos");
2878 fprintf(f, "4 2 2 1 2 9999999 9999999 9999999 7777777 0 4 "
2879 "45000 200 56789000 56789000 5678900 0 0 9999999 "
2880 "20000 0\n");
2881 fclose(f);
2882 } else {
2883 snprintf(fname, sizeof(fname),
2884 "/sys/kernel/debug/ieee80211/%s/ath6kl/"
2885 "delete_qos", pos);
2886
2887 f = fopen(fname, "w");
2888 if (f == NULL)
2889 return -1;
2890
2891 sigma_dut_print(dut, DUT_MSG_DEBUG, "Use ath6kl delete_qos");
2892 fprintf(f, "2 4\n");
2893 fclose(f);
2894 }
2895#endif /* __linux__ */
2896
2897 return 0;
2898}
2899
2900
Jouni Malinenf7222712019-06-13 01:50:21 +03002901static enum sigma_cmd_result cmd_sta_set_uapsd(struct sigma_dut *dut,
2902 struct sigma_conn *conn,
2903 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002904{
2905 const char *intf = get_param(cmd, "Interface");
2906 /* const char *ssid = get_param(cmd, "ssid"); */
2907 const char *val;
2908 int max_sp_len = 4;
2909 int ac_be = 1, ac_bk = 1, ac_vi = 1, ac_vo = 1;
2910 char buf[100];
2911 int ret1, ret2;
2912
2913 val = get_param(cmd, "maxSPLength");
2914 if (val) {
2915 max_sp_len = atoi(val);
2916 if (max_sp_len != 0 && max_sp_len != 1 && max_sp_len != 2 &&
2917 max_sp_len != 4)
2918 return -1;
2919 }
2920
2921 val = get_param(cmd, "acBE");
2922 if (val)
2923 ac_be = atoi(val);
2924
2925 val = get_param(cmd, "acBK");
2926 if (val)
2927 ac_bk = atoi(val);
2928
2929 val = get_param(cmd, "acVI");
2930 if (val)
2931 ac_vi = atoi(val);
2932
2933 val = get_param(cmd, "acVO");
2934 if (val)
2935 ac_vo = atoi(val);
2936
2937 dut->client_uapsd = ac_be || ac_bk || ac_vi || ac_vo;
2938
2939 snprintf(buf, sizeof(buf), "P2P_SET client_apsd %d,%d,%d,%d;%d",
2940 ac_be, ac_bk, ac_vi, ac_vo, max_sp_len);
2941 ret1 = wpa_command(intf, buf);
2942
2943 snprintf(buf, sizeof(buf), "SET uapsd %d,%d,%d,%d;%d",
2944 ac_be, ac_bk, ac_vi, ac_vo, max_sp_len);
2945 ret2 = wpa_command(intf, buf);
2946
2947 if (ret1 && ret2) {
2948 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to set client mode "
2949 "UAPSD parameters.");
2950 return -2;
2951 }
2952
2953 if (ath6kl_client_uapsd(dut, intf, dut->client_uapsd) < 0) {
2954 send_resp(dut, conn, SIGMA_ERROR,
2955 "ErrorCode,Failed to set ath6kl QoS parameters");
2956 return 0;
2957 }
2958
2959 return 1;
2960}
2961
2962
Jouni Malinenf7222712019-06-13 01:50:21 +03002963static enum sigma_cmd_result cmd_sta_set_wmm(struct sigma_dut *dut,
2964 struct sigma_conn *conn,
2965 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002966{
2967 char buf[1000];
2968 const char *intf = get_param(cmd, "Interface");
2969 const char *grp = get_param(cmd, "Group");
2970 const char *act = get_param(cmd, "Action");
2971 const char *tid = get_param(cmd, "Tid");
2972 const char *dir = get_param(cmd, "Direction");
2973 const char *psb = get_param(cmd, "Psb");
2974 const char *up = get_param(cmd, "Up");
2975 const char *fixed = get_param(cmd, "Fixed");
2976 const char *size = get_param(cmd, "Size");
2977 const char *msize = get_param(cmd, "Maxsize");
2978 const char *minsi = get_param(cmd, "Min_srvc_intrvl");
2979 const char *maxsi = get_param(cmd, "Max_srvc_intrvl");
2980 const char *inact = get_param(cmd, "Inactivity");
2981 const char *sus = get_param(cmd, "Suspension");
2982 const char *mindr = get_param(cmd, "Mindatarate");
2983 const char *meandr = get_param(cmd, "Meandatarate");
2984 const char *peakdr = get_param(cmd, "Peakdatarate");
2985 const char *phyrate = get_param(cmd, "Phyrate");
2986 const char *burstsize = get_param(cmd, "Burstsize");
2987 const char *sba = get_param(cmd, "Sba");
2988 int direction;
2989 int handle;
Peng Xu93319622017-10-04 17:58:16 -07002990 float sba_fv = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002991 int fixed_int;
2992 int psb_ts;
2993
2994 if (intf == NULL || grp == NULL || act == NULL )
2995 return -1;
2996
2997 if (strcasecmp(act, "addts") == 0) {
2998 if (tid == NULL || dir == NULL || psb == NULL ||
2999 up == NULL || fixed == NULL || size == NULL)
3000 return -1;
3001
3002 /*
3003 * Note: Sigma CAPI spec lists uplink, downlink, and bidi as the
3004 * possible values, but WMM-AC and V-E test scripts use "UP,
3005 * "DOWN", and "BIDI".
3006 */
3007 if (strcasecmp(dir, "uplink") == 0 ||
3008 strcasecmp(dir, "up") == 0) {
3009 direction = 0;
3010 } else if (strcasecmp(dir, "downlink") == 0 ||
3011 strcasecmp(dir, "down") == 0) {
3012 direction = 1;
3013 } else if (strcasecmp(dir, "bidi") == 0) {
3014 direction = 2;
3015 } else {
3016 sigma_dut_print(dut, DUT_MSG_ERROR,
3017 "Direction %s not supported", dir);
3018 return -1;
3019 }
3020
3021 if (strcasecmp(psb, "legacy") == 0) {
3022 psb_ts = 0;
3023 } else if (strcasecmp(psb, "uapsd") == 0) {
3024 psb_ts = 1;
3025 } else {
3026 sigma_dut_print(dut, DUT_MSG_ERROR,
3027 "PSB %s not supported", psb);
3028 return -1;
3029 }
3030
3031 if (atoi(tid) < 0 || atoi(tid) > 7) {
3032 sigma_dut_print(dut, DUT_MSG_ERROR,
3033 "TID %s not supported", tid);
3034 return -1;
3035 }
3036
3037 if (strcasecmp(fixed, "true") == 0) {
3038 fixed_int = 1;
3039 } else {
3040 fixed_int = 0;
3041 }
3042
Peng Xu93319622017-10-04 17:58:16 -07003043 if (sba)
3044 sba_fv = atof(sba);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003045
3046 dut->dialog_token++;
3047 handle = 7000 + dut->dialog_token;
3048
3049 /*
3050 * size: convert to hex
3051 * maxsi: convert to hex
3052 * mindr: convert to hex
3053 * meandr: convert to hex
3054 * peakdr: convert to hex
3055 * burstsize: convert to hex
3056 * phyrate: convert to hex
3057 * sba: convert to hex with modification
3058 * minsi: convert to integer
3059 * sus: convert to integer
3060 * inact: convert to integer
3061 * maxsi: convert to integer
3062 */
3063
3064 /*
3065 * The Nominal MSDU Size field is 2 octets long and contains an
3066 * unsigned integer that specifies the nominal size, in octets,
3067 * of MSDUs belonging to the traffic under this traffic
3068 * specification and is defined in Figure 16. If the Fixed
3069 * subfield is set to 1, then the size of the MSDU is fixed and
3070 * is indicated by the Size Subfield. If the Fixed subfield is
3071 * set to 0, then the size of the MSDU might not be fixed and
3072 * the Size indicates the nominal MSDU size.
3073 *
3074 * The Surplus Bandwidth Allowance Factor field is 2 octets long
3075 * and specifies the excess allocation of time (and bandwidth)
3076 * over and above the stated rates required to transport an MSDU
3077 * belonging to the traffic in this TSPEC. This field is
3078 * represented as an unsigned binary number with an implicit
3079 * binary point after the leftmost 3 bits. For example, an SBA
3080 * of 1.75 is represented as 0x3800. This field is included to
3081 * account for retransmissions. As such, the value of this field
3082 * must be greater than unity.
3083 */
3084
3085 snprintf(buf, sizeof(buf),
3086 "iwpriv %s addTspec %d %s %d %d %s 0x%X"
3087 " 0x%X 0x%X 0x%X"
3088 " 0x%X 0x%X 0x%X"
3089 " 0x%X %d %d %d %d"
3090 " %d %d",
3091 intf, handle, tid, direction, psb_ts, up,
3092 (unsigned int) ((fixed_int << 15) | atoi(size)),
3093 msize ? atoi(msize) : 0,
3094 mindr ? atoi(mindr) : 0,
3095 meandr ? atoi(meandr) : 0,
3096 peakdr ? atoi(peakdr) : 0,
3097 burstsize ? atoi(burstsize) : 0,
3098 phyrate ? atoi(phyrate) : 0,
3099 sba ? ((unsigned int) (((int) sba_fv << 13) |
3100 (int)((sba_fv - (int) sba_fv) *
3101 8192))) : 0,
3102 minsi ? atoi(minsi) : 0,
3103 sus ? atoi(sus) : 0,
3104 0, 0,
3105 inact ? atoi(inact) : 0,
3106 maxsi ? atoi(maxsi) : 0);
3107
3108 if (system(buf) != 0) {
3109 sigma_dut_print(dut, DUT_MSG_ERROR,
3110 "iwpriv addtspec request failed");
3111 send_resp(dut, conn, SIGMA_ERROR,
3112 "errorCode,Failed to execute addTspec command");
3113 return 0;
3114 }
3115
3116 sigma_dut_print(dut, DUT_MSG_INFO,
3117 "iwpriv addtspec request send");
3118
3119 /* Mapping handle to a TID */
3120 dut->tid_to_handle[atoi(tid)] = handle;
3121 } else if (strcasecmp(act, "delts") == 0) {
3122 if (tid == NULL)
3123 return -1;
3124
3125 if (atoi(tid) < 0 || atoi(tid) > 7) {
3126 sigma_dut_print(dut, DUT_MSG_ERROR,
3127 "TID %s not supported", tid);
3128 send_resp(dut, conn, SIGMA_ERROR,
3129 "errorCode,Unsupported TID");
3130 return 0;
3131 }
3132
3133 handle = dut->tid_to_handle[atoi(tid)];
3134
3135 if (handle < 7000 || handle > 7255) {
3136 /* Invalid handle ie no mapping for that TID */
3137 sigma_dut_print(dut, DUT_MSG_ERROR,
3138 "handle-> %d not found", handle);
3139 }
3140
3141 snprintf(buf, sizeof(buf), "iwpriv %s delTspec %d",
3142 intf, handle);
3143
3144 if (system(buf) != 0) {
3145 sigma_dut_print(dut, DUT_MSG_ERROR,
3146 "iwpriv deltspec request failed");
3147 send_resp(dut, conn, SIGMA_ERROR,
3148 "errorCode,Failed to execute delTspec command");
3149 return 0;
3150 }
3151
3152 sigma_dut_print(dut, DUT_MSG_INFO,
3153 "iwpriv deltspec request send");
3154
3155 dut->tid_to_handle[atoi(tid)] = 0;
3156 } else {
3157 sigma_dut_print(dut, DUT_MSG_ERROR,
3158 "Action type %s not supported", act);
3159 send_resp(dut, conn, SIGMA_ERROR,
3160 "errorCode,Unsupported Action");
3161 return 0;
3162 }
3163
3164 return 1;
3165}
3166
3167
vamsi krishna52e16f92017-08-29 12:37:34 +05303168static int find_network(struct sigma_dut *dut, const char *ssid)
3169{
3170 char list[4096];
3171 char *pos;
3172
3173 sigma_dut_print(dut, DUT_MSG_DEBUG,
3174 "Search for profile based on SSID: '%s'", ssid);
3175 if (wpa_command_resp(get_station_ifname(), "LIST_NETWORKS",
3176 list, sizeof(list)) < 0)
3177 return -1;
3178 pos = strstr(list, ssid);
3179 if (!pos || pos == list || pos[-1] != '\t' || pos[strlen(ssid)] != '\t')
3180 return -1;
3181
3182 while (pos > list && pos[-1] != '\n')
3183 pos--;
3184 dut->infra_network_id = atoi(pos);
3185 snprintf(dut->infra_ssid, sizeof(dut->infra_ssid), "%s", ssid);
3186 return 0;
3187}
3188
3189
Sunil Dutt44595082018-02-12 19:41:45 +05303190#ifdef NL80211_SUPPORT
3191static int sta_config_rsnie(struct sigma_dut *dut, int val)
3192{
3193 struct nl_msg *msg;
3194 int ret;
3195 struct nlattr *params;
3196 int ifindex;
3197
3198 ifindex = if_nametoindex("wlan0");
3199 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
3200 NL80211_CMD_VENDOR)) ||
3201 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
3202 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
3203 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
3204 QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION) ||
3205 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
3206 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE, val)) {
3207 sigma_dut_print(dut, DUT_MSG_ERROR,
3208 "%s: err in adding vendor_cmd and vendor_data",
3209 __func__);
3210 nlmsg_free(msg);
3211 return -1;
3212 }
3213 nla_nest_end(msg, params);
3214
3215 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
3216 if (ret) {
3217 sigma_dut_print(dut, DUT_MSG_ERROR,
3218 "%s: err in send_and_recv_msgs, ret=%d",
3219 __func__, ret);
3220 return ret;
3221 }
3222
3223 return 0;
3224}
3225#endif /* NL80211_SUPPORT */
3226
3227
Jouni Malinenf7222712019-06-13 01:50:21 +03003228static enum sigma_cmd_result cmd_sta_associate(struct sigma_dut *dut,
3229 struct sigma_conn *conn,
3230 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003231{
3232 /* const char *intf = get_param(cmd, "Interface"); */
3233 const char *ssid = get_param(cmd, "ssid");
3234 const char *wps_param = get_param(cmd, "WPS");
3235 const char *bssid = get_param(cmd, "bssid");
Jouni Malinen46a19b62017-06-23 14:31:27 +03003236 const char *chan = get_param(cmd, "channel");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02003237 const char *network_mode = get_param(cmd, "network_mode");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003238 int wps = 0;
Jouni Malinen3c367e82017-06-23 17:01:47 +03003239 char buf[1000], extra[50];
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003240 int e;
3241 enum sigma_cmd_result ret = SUCCESS_SEND_STATUS;
3242 struct wpa_ctrl *ctrl = NULL;
3243 int num_network_not_found = 0;
3244 int num_disconnected = 0;
3245 int tod = -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003246
3247 if (ssid == NULL)
3248 return -1;
3249
Jouni Malinen3c367e82017-06-23 17:01:47 +03003250 if (dut->rsne_override) {
Sunil Dutt44595082018-02-12 19:41:45 +05303251#ifdef NL80211_SUPPORT
3252 if (get_driver_type() == DRIVER_WCN) {
3253 sta_config_rsnie(dut, 1);
3254 dut->config_rsnie = 1;
3255 }
3256#endif /* NL80211_SUPPORT */
Jouni Malinen3c367e82017-06-23 17:01:47 +03003257 snprintf(buf, sizeof(buf), "TEST_ASSOC_IE %s",
3258 dut->rsne_override);
3259 if (wpa_command(get_station_ifname(), buf) < 0) {
3260 send_resp(dut, conn, SIGMA_ERROR,
3261 "ErrorCode,Failed to set DEV_CONFIGURE_IE RSNE override");
3262 return 0;
3263 }
3264 }
3265
Jouni Malinen68143132017-09-02 02:34:08 +03003266 if (dut->sae_commit_override) {
3267 snprintf(buf, sizeof(buf), "SET sae_commit_override %s",
3268 dut->sae_commit_override);
3269 if (wpa_command(get_station_ifname(), buf) < 0) {
3270 send_resp(dut, conn, SIGMA_ERROR,
3271 "ErrorCode,Failed to set SAE commit override");
3272 return 0;
3273 }
3274 }
Ankita Bajaj1bde7942018-01-09 19:15:01 +05303275#ifdef ANDROID
3276 if (dut->fils_hlp)
3277 process_fils_hlp(dut);
3278#endif /* ANDROID */
Jouni Malinen68143132017-09-02 02:34:08 +03003279
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003280 if (wps_param &&
3281 (strcmp(wps_param, "1") == 0 || strcasecmp(wps_param, "On") == 0))
3282 wps = 1;
3283
3284 if (wps) {
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02003285 if (dut->program == PROGRAM_60GHZ && network_mode &&
3286 strcasecmp(network_mode, "PBSS") == 0 &&
3287 set_network(get_station_ifname(), dut->infra_network_id,
3288 "pbss", "1") < 0)
3289 return -2;
3290
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003291 if (dut->wps_method == WFA_CS_WPS_NOT_READY) {
3292 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,WPS "
3293 "parameters not yet set");
3294 return 0;
3295 }
3296 if (dut->wps_method == WFA_CS_WPS_PBC) {
3297 if (wpa_command(get_station_ifname(), "WPS_PBC") < 0)
3298 return -2;
3299 } else {
3300 snprintf(buf, sizeof(buf), "WPS_PIN any %s",
3301 dut->wps_pin);
3302 if (wpa_command(get_station_ifname(), buf) < 0)
3303 return -2;
3304 }
3305 } else {
vamsi krishna52e16f92017-08-29 12:37:34 +05303306 if (strcmp(ssid, dut->infra_ssid) == 0) {
3307 sigma_dut_print(dut, DUT_MSG_DEBUG,
3308 "sta_associate for the most recently added network");
3309 } else if (find_network(dut, ssid) < 0) {
3310 sigma_dut_print(dut, DUT_MSG_DEBUG,
3311 "sta_associate for a previously stored network profile");
3312 send_resp(dut, conn, SIGMA_ERROR,
3313 "ErrorCode,Profile not found");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003314 return 0;
3315 }
3316
3317 if (bssid &&
3318 set_network(get_station_ifname(), dut->infra_network_id,
3319 "bssid", bssid) < 0) {
3320 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
3321 "Invalid bssid argument");
3322 return 0;
3323 }
3324
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003325 if (dut->program == PROGRAM_WPA3 &&
3326 dut->sta_associate_wait_connect) {
3327 ctrl = open_wpa_mon(get_station_ifname());
3328 if (!ctrl)
3329 return ERROR_SEND_STATUS;
3330 }
3331
Jouni Malinen46a19b62017-06-23 14:31:27 +03003332 extra[0] = '\0';
3333 if (chan)
3334 snprintf(extra, sizeof(extra), " freq=%u",
Alexei Avshalom Lazar093569f2018-11-13 14:08:17 +02003335 channel_to_freq(dut, atoi(chan)));
Jouni Malinen46a19b62017-06-23 14:31:27 +03003336 snprintf(buf, sizeof(buf), "SELECT_NETWORK %d%s",
3337 dut->infra_network_id, extra);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003338 if (wpa_command(get_station_ifname(), buf) < 0) {
3339 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to select "
3340 "network id %d on %s",
3341 dut->infra_network_id,
3342 get_station_ifname());
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003343 ret = ERROR_SEND_STATUS;
3344 goto done;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003345 }
3346 }
3347
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003348 if (!ctrl)
3349 return SUCCESS_SEND_STATUS;
3350
3351 /* Wait for connection result to be able to store server certificate
3352 * hash for trust root override testing
3353 * (dev_exec_action,ServerCertTrust). */
3354
3355 for (e = 0; e < 20; e++) {
3356 const char *events[] = {
3357 "CTRL-EVENT-EAP-PEER-CERT",
3358 "CTRL-EVENT-EAP-TLS-CERT-ERROR",
3359 "CTRL-EVENT-DISCONNECTED",
3360 "CTRL-EVENT-CONNECTED",
3361 "CTRL-EVENT-NETWORK-NOT-FOUND",
3362 NULL
3363 };
3364 char buf[1024];
3365 int res;
3366
3367 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
3368 if (res < 0) {
3369 send_resp(dut, conn, SIGMA_ERROR,
3370 "ErrorCode,Association did not complete");
3371 ret = STATUS_SENT_ERROR;
3372 break;
3373 }
3374 sigma_dut_print(dut, DUT_MSG_DEBUG, "Connection event: %s",
3375 buf);
3376
3377 if (strstr(buf, "CTRL-EVENT-EAP-PEER-CERT") &&
3378 strstr(buf, " depth=0")) {
3379 char *pos = strstr(buf, " hash=");
3380
3381 if (pos) {
3382 char *end;
3383
3384 tod = strstr(buf, " tod=1") != NULL;
3385 sigma_dut_print(dut, DUT_MSG_DEBUG,
3386 "Server certificate TOD policy: %d",
3387 tod);
3388
3389 pos += 6;
3390 end = strchr(pos, ' ');
3391 if (end)
3392 *end = '\0';
3393 strlcpy(dut->server_cert_hash, pos,
3394 sizeof(dut->server_cert_hash));
3395 sigma_dut_print(dut, DUT_MSG_DEBUG,
3396 "Server certificate hash: %s",
3397 dut->server_cert_hash);
3398 }
3399 }
3400
3401 if (strstr(buf, "CTRL-EVENT-EAP-TLS-CERT-ERROR")) {
3402 send_resp(dut, conn, SIGMA_COMPLETE,
3403 "Result,TLS server certificate validation failed");
3404 ret = STATUS_SENT_ERROR;
3405 break;
3406 }
3407
3408 if (strstr(buf, "CTRL-EVENT-NETWORK-NOT-FOUND")) {
3409 num_network_not_found++;
3410
3411 if (num_network_not_found > 2) {
3412 send_resp(dut, conn, SIGMA_COMPLETE,
3413 "Result,Network not found");
3414 ret = STATUS_SENT_ERROR;
3415 break;
3416 }
3417 }
3418
3419 if (strstr(buf, "CTRL-EVENT-DISCONNECTED")) {
3420 num_disconnected++;
3421
3422 if (num_disconnected > 2) {
3423 send_resp(dut, conn, SIGMA_COMPLETE,
3424 "Result,Connection failed");
3425 ret = STATUS_SENT_ERROR;
3426 break;
3427 }
3428 }
3429
3430 if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
3431 if (tod >= 0) {
3432 sigma_dut_print(dut, DUT_MSG_DEBUG,
3433 "Network profile TOD policy update: %d -> %d",
3434 dut->sta_tod_policy, tod);
3435 dut->sta_tod_policy = tod;
3436 }
3437 break;
3438 }
3439 }
3440done:
3441 if (ctrl) {
3442 wpa_ctrl_detach(ctrl);
3443 wpa_ctrl_close(ctrl);
3444 }
3445 return ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003446}
3447
3448
3449static int run_hs20_osu(struct sigma_dut *dut, const char *params)
3450{
3451 char buf[500], cmd[200];
3452 int res;
3453
3454 /* Use hs20-osu-client file at the current dir, if found; otherwise use
3455 * default path */
3456 res = snprintf(cmd, sizeof(cmd),
3457 "%s -w \"%s\" -r hs20-osu-client.res %s%s -dddKt -f Logs/hs20-osu-client.txt",
3458 file_exists("./hs20-osu-client") ?
3459 "./hs20-osu-client" : "hs20-osu-client",
3460 sigma_wpas_ctrl,
3461 dut->summary_log ? "-s " : "",
3462 dut->summary_log ? dut->summary_log : "");
3463 if (res < 0 || res >= (int) sizeof(cmd))
3464 return -1;
3465
3466 res = snprintf(buf, sizeof(buf), "%s %s", cmd, params);
3467 if (res < 0 || res >= (int) sizeof(buf))
3468 return -1;
3469 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
3470
3471 if (system(buf) != 0) {
3472 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to run: %s", buf);
3473 return -1;
3474 }
3475 sigma_dut_print(dut, DUT_MSG_DEBUG,
3476 "Completed hs20-osu-client operation");
3477
3478 return 0;
3479}
3480
3481
3482static int download_ppsmo(struct sigma_dut *dut,
3483 struct sigma_conn *conn,
3484 const char *intf,
3485 struct sigma_cmd *cmd)
3486{
3487 const char *name, *path, *val;
3488 char url[500], buf[600], fbuf[100];
3489 char *fqdn = NULL;
3490
3491 name = get_param(cmd, "FileName");
3492 path = get_param(cmd, "FilePath");
3493 if (name == NULL || path == NULL)
3494 return -1;
3495
3496 if (strcasecmp(path, "VendorSpecific") == 0) {
3497 snprintf(url, sizeof(url), "PPS/%s", name);
3498 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured PPS MO "
3499 "from the device (%s)", url);
3500 if (!file_exists(url)) {
3501 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
3502 "PPS MO file does not exist");
3503 return 0;
3504 }
3505 snprintf(buf, sizeof(buf), "cp %s pps-tnds.xml", url);
3506 if (system(buf) != 0) {
3507 send_resp(dut, conn, SIGMA_ERROR,
3508 "errorCode,Failed to copy PPS MO");
3509 return 0;
3510 }
3511 } else if (strncasecmp(path, "http:", 5) != 0 &&
3512 strncasecmp(path, "https:", 6) != 0) {
3513 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
3514 "Unsupported FilePath value");
3515 return 0;
3516 } else {
3517 snprintf(url, sizeof(url), "%s/%s", path, name);
3518 sigma_dut_print(dut, DUT_MSG_INFO, "Downloading PPS MO from %s",
3519 url);
3520 snprintf(buf, sizeof(buf), "wget -T 10 -t 3 -O pps-tnds.xml '%s'", url);
3521 remove("pps-tnds.xml");
3522 if (system(buf) != 0) {
3523 send_resp(dut, conn, SIGMA_ERROR,
3524 "errorCode,Failed to download PPS MO");
3525 return 0;
3526 }
3527 }
3528
3529 if (run_hs20_osu(dut, "from_tnds pps-tnds.xml pps.xml") < 0) {
3530 send_resp(dut, conn, SIGMA_ERROR,
3531 "errorCode,Failed to parse downloaded PPSMO");
3532 return 0;
3533 }
3534 unlink("pps-tnds.xml");
3535
3536 val = get_param(cmd, "managementTreeURI");
3537 if (val) {
3538 const char *pos, *end;
3539 sigma_dut_print(dut, DUT_MSG_DEBUG, "managementTreeURI: %s",
3540 val);
3541 if (strncmp(val, "./Wi-Fi/", 8) != 0) {
3542 send_resp(dut, conn, SIGMA_ERROR,
3543 "errorCode,Invalid managementTreeURI prefix");
3544 return 0;
3545 }
3546 pos = val + 8;
3547 end = strchr(pos, '/');
3548 if (end == NULL ||
3549 strcmp(end, "/PerProviderSubscription") != 0) {
3550 send_resp(dut, conn, SIGMA_ERROR,
3551 "errorCode,Invalid managementTreeURI postfix");
3552 return 0;
3553 }
3554 if (end - pos >= (int) sizeof(fbuf)) {
3555 send_resp(dut, conn, SIGMA_ERROR,
3556 "errorCode,Too long FQDN in managementTreeURI");
3557 return 0;
3558 }
3559 memcpy(fbuf, pos, end - pos);
3560 fbuf[end - pos] = '\0';
3561 fqdn = fbuf;
3562 sigma_dut_print(dut, DUT_MSG_INFO,
3563 "FQDN from managementTreeURI: %s", fqdn);
3564 } else if (run_hs20_osu(dut, "get_fqdn pps.xml") == 0) {
3565 FILE *f = fopen("pps-fqdn", "r");
3566 if (f) {
3567 if (fgets(fbuf, sizeof(fbuf), f)) {
3568 fbuf[sizeof(fbuf) - 1] = '\0';
3569 fqdn = fbuf;
3570 sigma_dut_print(dut, DUT_MSG_DEBUG,
3571 "Use FQDN %s", fqdn);
3572 }
3573 fclose(f);
3574 }
3575 }
3576
3577 if (fqdn == NULL) {
3578 send_resp(dut, conn, SIGMA_ERROR,
3579 "errorCode,No FQDN specified");
3580 return 0;
3581 }
3582
3583 mkdir("SP", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
3584 snprintf(buf, sizeof(buf), "SP/%s", fqdn);
3585 mkdir(buf, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
3586
3587 snprintf(buf, sizeof(buf), "SP/%s/pps.xml", fqdn);
3588 if (rename("pps.xml", buf) < 0) {
3589 send_resp(dut, conn, SIGMA_ERROR,
3590 "errorCode,Could not move PPS MO");
3591 return 0;
3592 }
3593
3594 if (strcasecmp(path, "VendorSpecific") == 0) {
3595 snprintf(buf, sizeof(buf), "cp Certs/ca.pem SP/%s/ca.pem",
3596 fqdn);
3597 if (system(buf)) {
3598 send_resp(dut, conn, SIGMA_ERROR,
3599 "errorCode,Failed to copy OSU CA cert");
3600 return 0;
3601 }
3602
3603 snprintf(buf, sizeof(buf),
3604 "cp Certs/aaa-ca.pem SP/%s/aaa-ca.pem",
3605 fqdn);
3606 if (system(buf)) {
3607 send_resp(dut, conn, SIGMA_ERROR,
3608 "errorCode,Failed to copy AAA CA cert");
3609 return 0;
3610 }
3611 } else {
3612 snprintf(buf, sizeof(buf),
3613 "dl_osu_ca SP/%s/pps.xml SP/%s/ca.pem",
3614 fqdn, fqdn);
3615 if (run_hs20_osu(dut, buf) < 0) {
3616 send_resp(dut, conn, SIGMA_ERROR,
3617 "errorCode,Failed to download OSU CA cert");
3618 return 0;
3619 }
3620
3621 snprintf(buf, sizeof(buf),
3622 "dl_aaa_ca SP/%s/pps.xml SP/%s/aaa-ca.pem",
3623 fqdn, fqdn);
3624 if (run_hs20_osu(dut, buf) < 0) {
3625 sigma_dut_print(dut, DUT_MSG_INFO,
3626 "Failed to download AAA CA cert");
3627 }
3628 }
3629
3630 if (file_exists("next-client-cert.pem")) {
3631 snprintf(buf, sizeof(buf), "SP/%s/client-cert.pem", fqdn);
3632 if (rename("next-client-cert.pem", buf) < 0) {
3633 send_resp(dut, conn, SIGMA_ERROR,
3634 "errorCode,Could not move client certificate");
3635 return 0;
3636 }
3637 }
3638
3639 if (file_exists("next-client-key.pem")) {
3640 snprintf(buf, sizeof(buf), "SP/%s/client-key.pem", fqdn);
3641 if (rename("next-client-key.pem", buf) < 0) {
3642 send_resp(dut, conn, SIGMA_ERROR,
3643 "errorCode,Could not move client key");
3644 return 0;
3645 }
3646 }
3647
3648 snprintf(buf, sizeof(buf), "set_pps SP/%s/pps.xml", fqdn);
3649 if (run_hs20_osu(dut, buf) < 0) {
3650 send_resp(dut, conn, SIGMA_ERROR,
3651 "errorCode,Failed to configure credential from "
3652 "PPSMO");
3653 return 0;
3654 }
3655
3656 return 1;
3657}
3658
3659
3660static int download_cert(struct sigma_dut *dut,
3661 struct sigma_conn *conn,
3662 const char *intf,
3663 struct sigma_cmd *cmd)
3664{
3665 const char *name, *path;
3666 char url[500], buf[600];
3667
3668 name = get_param(cmd, "FileName");
3669 path = get_param(cmd, "FilePath");
3670 if (name == NULL || path == NULL)
3671 return -1;
3672
3673 if (strcasecmp(path, "VendorSpecific") == 0) {
3674 snprintf(url, sizeof(url), "Certs/%s-cert.pem", name);
3675 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured client "
3676 "certificate from the device (%s)", url);
3677 if (!file_exists(url)) {
3678 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
3679 "certificate file does not exist");
3680 return 0;
3681 }
3682 snprintf(buf, sizeof(buf), "cp %s next-client-cert.pem", url);
3683 if (system(buf) != 0) {
3684 send_resp(dut, conn, SIGMA_ERROR,
3685 "errorCode,Failed to copy client "
3686 "certificate");
3687 return 0;
3688 }
3689
3690 snprintf(url, sizeof(url), "Certs/%s-key.pem", name);
3691 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured client "
3692 "private key from the device (%s)", url);
3693 if (!file_exists(url)) {
3694 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
3695 "private key file does not exist");
3696 return 0;
3697 }
3698 snprintf(buf, sizeof(buf), "cp %s next-client-key.pem", url);
3699 if (system(buf) != 0) {
3700 send_resp(dut, conn, SIGMA_ERROR,
3701 "errorCode,Failed to copy client key");
3702 return 0;
3703 }
3704 } else if (strncasecmp(path, "http:", 5) != 0 &&
3705 strncasecmp(path, "https:", 6) != 0) {
3706 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
3707 "Unsupported FilePath value");
3708 return 0;
3709 } else {
3710 snprintf(url, sizeof(url), "%s/%s.pem", path, name);
3711 sigma_dut_print(dut, DUT_MSG_INFO, "Downloading client "
3712 "certificate/key from %s", url);
3713 snprintf(buf, sizeof(buf),
3714 "wget -T 10 -t 3 -O next-client-cert.pem '%s'", url);
3715 if (system(buf) != 0) {
3716 send_resp(dut, conn, SIGMA_ERROR,
3717 "errorCode,Failed to download client "
3718 "certificate");
3719 return 0;
3720 }
3721
3722 if (system("cp next-client-cert.pem next-client-key.pem") != 0)
3723 {
3724 send_resp(dut, conn, SIGMA_ERROR,
3725 "errorCode,Failed to copy client key");
3726 return 0;
3727 }
3728 }
3729
3730 return 1;
3731}
3732
3733
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02003734static int cmd_sta_preset_testparameters_60ghz(struct sigma_dut *dut,
3735 struct sigma_conn *conn,
3736 struct sigma_cmd *cmd)
3737{
3738 const char *val;
3739 const char *intf = get_param(cmd, "interface");
3740
3741 if (!intf)
3742 return -1;
3743
3744 val = get_param(cmd, "WscIEFragment");
3745 if (val && strcasecmp(val, "enable") == 0) {
3746 sigma_dut_print(dut, DUT_MSG_DEBUG,
3747 "Enable WSC IE fragmentation");
3748
3749 dut->wsc_fragment = 1;
3750 /* set long attributes to force fragmentation */
3751 if (wpa_command(intf, "SET device_name "
3752 WPS_LONG_DEVICE_NAME) < 0)
3753 return -2;
3754 if (wpa_command(intf, "SET manufacturer "
3755 WPS_LONG_MANUFACTURER) < 0)
3756 return -2;
3757 if (wpa_command(intf, "SET model_name "
3758 WPS_LONG_MODEL_NAME) < 0)
3759 return -2;
3760 if (wpa_command(intf, "SET model_number "
3761 WPS_LONG_MODEL_NUMBER) < 0)
3762 return -2;
3763 if (wpa_command(intf, "SET serial_number "
3764 WPS_LONG_SERIAL_NUMBER) < 0)
3765 return -2;
3766 }
3767
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02003768 val = get_param(cmd, "RSN_IE");
3769 if (val) {
3770 if (strcasecmp(val, "disable") == 0)
3771 dut->force_rsn_ie = FORCE_RSN_IE_REMOVE;
3772 else if (strcasecmp(val, "enable") == 0)
3773 dut->force_rsn_ie = FORCE_RSN_IE_ADD;
3774 }
3775
Alexei Avshalom Lazar744ae8a2019-01-31 17:26:46 +02003776 val = get_param(cmd, "WpsVersion");
3777 if (val)
3778 dut->wps_forced_version = get_wps_forced_version(dut, val);
3779
Alexei Avshalom Lazar2eccf4d2019-01-31 10:03:59 +02003780 val = get_param(cmd, "WscEAPFragment");
3781 if (val && strcasecmp(val, "enable") == 0)
3782 dut->eap_fragment = 1;
3783
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02003784 return 1;
3785}
3786
3787
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003788static int cmd_sta_preset_testparameters_hs2_r2(struct sigma_dut *dut,
3789 struct sigma_conn *conn,
3790 const char *intf,
3791 struct sigma_cmd *cmd)
3792{
3793 const char *val;
3794
3795 val = get_param(cmd, "FileType");
3796 if (val && strcasecmp(val, "PPSMO") == 0)
3797 return download_ppsmo(dut, conn, intf, cmd);
3798 if (val && strcasecmp(val, "CERT") == 0)
3799 return download_cert(dut, conn, intf, cmd);
3800 if (val) {
3801 send_resp(dut, conn, SIGMA_ERROR,
3802 "ErrorCode,Unsupported FileType");
3803 return 0;
3804 }
3805
3806 return 1;
3807}
3808
3809
Ankita Bajaja2cb5672017-10-25 16:08:28 +05303810static int cmd_sta_preset_testparameters_oce(struct sigma_dut *dut,
3811 struct sigma_conn *conn,
3812 const char *intf,
3813 struct sigma_cmd *cmd)
3814{
3815 const char *val;
Ankita Bajaj1bde7942018-01-09 19:15:01 +05303816 char buf[1000];
3817 char text[20];
3818 unsigned char addr[ETH_ALEN];
Ankita Bajaja2cb5672017-10-25 16:08:28 +05303819
3820 val = get_param(cmd, "OCESupport");
3821 if (val && strcasecmp(val, "Disable") == 0) {
3822 if (wpa_command(intf, "SET oce 0") < 0) {
3823 send_resp(dut, conn, SIGMA_ERROR,
3824 "ErrorCode,Failed to disable OCE");
3825 return 0;
3826 }
3827 } else if (val && strcasecmp(val, "Enable") == 0) {
3828 if (wpa_command(intf, "SET oce 1") < 0) {
3829 send_resp(dut, conn, SIGMA_ERROR,
3830 "ErrorCode,Failed to enable OCE");
3831 return 0;
3832 }
3833 }
3834
vamsi krishnaa2799492017-12-05 14:28:01 +05303835 val = get_param(cmd, "FILScap");
3836 if (val && (atoi(val) == 1)) {
3837 if (wpa_command(intf, "SET disable_fils 0") < 0) {
3838 send_resp(dut, conn, SIGMA_ERROR,
3839 "ErrorCode,Failed to enable FILS");
3840 return 0;
3841 }
3842 } else if (val && (atoi(val) == 0)) {
3843 if (wpa_command(intf, "SET disable_fils 1") < 0) {
3844 send_resp(dut, conn, SIGMA_ERROR,
3845 "ErrorCode,Failed to disable FILS");
3846 return 0;
3847 }
3848 }
3849
Ankita Bajaj1bde7942018-01-09 19:15:01 +05303850 val = get_param(cmd, "FILSHLP");
3851 if (val && strcasecmp(val, "Enable") == 0) {
3852 if (get_wpa_status(get_station_ifname(), "address", text,
3853 sizeof(text)) < 0)
3854 return -2;
3855 hwaddr_aton(text, addr);
3856 snprintf(buf, sizeof(buf),
3857 "FILS_HLP_REQ_ADD ff:ff:ff:ff:ff:ff "
3858 "080045100140000040004011399e00000000ffffffff00440043"
3859 "012cb30001010600fd4f46410000000000000000000000000000"
3860 "000000000000"
3861 "%02x%02x%02x%02x%02x%02x"
3862 "0000000000000000000000000000000000000000000000000000"
3863 "0000000000000000000000000000000000000000000000000000"
3864 "0000000000000000000000000000000000000000000000000000"
3865 "0000000000000000000000000000000000000000000000000000"
3866 "0000000000000000000000000000000000000000000000000000"
3867 "0000000000000000000000000000000000000000000000000000"
3868 "0000000000000000000000000000000000000000000000000000"
3869 "0000000000000000000000000000000000000000638253633501"
3870 "013d0701000af549d29b390205dc3c12616e64726f69642d6468"
3871 "63702d382e302e30370a0103060f1a1c333a3b2b5000ff00",
3872 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
3873 if (wpa_command(intf, buf)) {
3874 send_resp(dut, conn, SIGMA_ERROR,
3875 "ErrorCode,Failed to add HLP");
3876 return 0;
3877 }
3878 dut->fils_hlp = 1;
3879 }
3880
Ankita Bajaja2cb5672017-10-25 16:08:28 +05303881 return 1;
3882}
3883
3884
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003885static void ath_sta_set_noack(struct sigma_dut *dut, const char *intf,
3886 const char *val)
3887{
3888 int counter = 0;
3889 char token[50];
3890 char *result;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05303891 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003892
Peng Xub8fc5cc2017-05-10 17:27:28 -07003893 strlcpy(token, val, sizeof(token));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003894 token[sizeof(token) - 1] = '\0';
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05303895 result = strtok_r(token, ":", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003896 while (result) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07003897 if (strcmp(result, "disable") == 0)
3898 run_iwpriv(dut, intf, "noackpolicy %d 1 0", counter);
3899 else
3900 run_iwpriv(dut, intf, "noackpolicy %d 1 1", counter);
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05303901 result = strtok_r(NULL, ":", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003902 counter++;
3903 }
3904}
3905
3906
3907static void ath_sta_set_rts(struct sigma_dut *dut, const char *intf,
3908 const char *val)
3909{
3910 char buf[100];
3911
3912 snprintf(buf, sizeof(buf), "iwconfig %s rts %s", intf, val);
3913 if (system(buf) != 0) {
3914 sigma_dut_print(dut, DUT_MSG_ERROR, "iwconfig RTS failed");
3915 }
3916}
3917
3918
3919static void ath_sta_set_wmm(struct sigma_dut *dut, const char *intf,
3920 const char *val)
3921{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003922 if (strcasecmp(val, "off") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07003923 run_iwpriv(dut, intf, "wmm 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003924 }
3925}
3926
3927
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08003928static int wcn_sta_set_wmm(struct sigma_dut *dut, const char *intf,
3929 const char *val)
3930{
3931#ifdef NL80211_SUPPORT
3932 struct nl_msg *msg;
3933 int ret = 0;
3934 struct nlattr *params;
3935 int ifindex;
3936 int wmmenable = 1;
3937
3938 if (val &&
3939 (strcasecmp(val, "off") == 0 || strcmp(val, "0") == 0))
3940 wmmenable = 0;
3941
3942 ifindex = if_nametoindex(intf);
3943 if (ifindex == 0) {
3944 sigma_dut_print(dut, DUT_MSG_ERROR,
3945 "%s: Index for interface %s failed",
3946 __func__, intf);
3947 return -1;
3948 }
3949
3950 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
3951 NL80211_CMD_VENDOR)) ||
3952 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
3953 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
3954 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
3955 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
3956 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
3957 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WMM_ENABLE,
3958 wmmenable)) {
3959 sigma_dut_print(dut, DUT_MSG_ERROR,
3960 "%s: err in adding vendor_cmd and vendor_data",
3961 __func__);
3962 nlmsg_free(msg);
3963 return -1;
3964 }
3965 nla_nest_end(msg, params);
3966
3967 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
3968 if (ret) {
3969 sigma_dut_print(dut, DUT_MSG_ERROR,
3970 "%s: err in send_and_recv_msgs, ret=%d",
3971 __func__, ret);
3972 }
3973 return ret;
3974#else /* NL80211_SUPPORT */
3975 sigma_dut_print(dut, DUT_MSG_ERROR,
3976 "WMM cannot be changed without NL80211_SUPPORT defined");
3977 return -1;
3978#endif /* NL80211_SUPPORT */
3979}
3980
3981
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003982static void ath_sta_set_sgi(struct sigma_dut *dut, const char *intf,
3983 const char *val)
3984{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003985 int sgi20;
3986
3987 sgi20 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
3988
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07003989 run_iwpriv(dut, intf, "shortgi %d", sgi20);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003990}
3991
3992
3993static void ath_sta_set_11nrates(struct sigma_dut *dut, const char *intf,
3994 const char *val)
3995{
Pradeep Reddy POTTETI67376b72016-10-25 20:08:17 +05303996 int rate_code, v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003997
3998 /* Disable Tx Beam forming when using a fixed rate */
3999 ath_disable_txbf(dut, intf);
4000
Pradeep Reddy POTTETI67376b72016-10-25 20:08:17 +05304001 v = atoi(val);
4002 if (v < 0 || v > 32) {
4003 sigma_dut_print(dut, DUT_MSG_ERROR,
4004 "Invalid Fixed MCS rate: %d", v);
4005 return;
4006 }
4007 rate_code = 0x80 + v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004008
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004009 run_iwpriv(dut, intf, "set11NRates 0x%x", rate_code);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004010
4011 /* Channel width gets messed up, fix this */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004012 run_iwpriv(dut, intf, "chwidth %d", dut->chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004013}
4014
4015
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08004016static void iwpriv_sta_set_amsdu(struct sigma_dut *dut, const char *intf,
4017 const char *val)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004018{
4019 char buf[60];
4020
4021 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)
4022 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 2", intf);
4023 else
4024 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 1", intf);
4025
4026 if (system(buf) != 0)
4027 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv amsdu failed");
4028}
4029
4030
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07004031static int iwpriv_sta_set_ampdu(struct sigma_dut *dut, const char *intf,
4032 int ampdu)
4033{
4034 char buf[60];
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08004035 int maxaggregation = 63;
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07004036
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08004037 if (ampdu)
4038 ampdu = maxaggregation;
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07004039 snprintf(buf, sizeof(buf), "iwpriv %s ampdu %d", intf, ampdu);
4040 if (system(buf) != 0) {
4041 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv ampdu failed");
4042 return -1;
4043 }
4044
4045 return 0;
4046}
4047
4048
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004049static void ath_sta_set_stbc(struct sigma_dut *dut, const char *intf,
4050 const char *val)
4051{
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004052 run_iwpriv(dut, intf, "tx_stbc %s", val);
4053 run_iwpriv(dut, intf, "rx_stbc %s", val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004054}
4055
4056
4057static int wcn_sta_set_cts_width(struct sigma_dut *dut, const char *intf,
4058 const char *val)
4059{
4060 char buf[60];
4061
Peng Xucc317ed2017-05-18 16:44:37 -07004062 if (strcmp(val, "160") == 0) {
4063 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 5", intf);
4064 } else if (strcmp(val, "80") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004065 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 3", intf);
4066 } else if (strcmp(val, "40") == 0) {
4067 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 2", intf);
4068 } else if (strcmp(val, "20") == 0) {
4069 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 1", intf);
4070 } else if (strcasecmp(val, "Auto") == 0) {
4071 buf[0] = '\0';
4072 } else {
4073 sigma_dut_print(dut, DUT_MSG_ERROR,
4074 "WIDTH/CTS_WIDTH value not supported");
4075 return -1;
4076 }
4077
4078 if (buf[0] != '\0' && system(buf) != 0) {
4079 sigma_dut_print(dut, DUT_MSG_ERROR,
4080 "Failed to set WIDTH/CTS_WIDTH");
4081 return -1;
4082 }
4083
4084 return 0;
4085}
4086
4087
4088int ath_set_width(struct sigma_dut *dut, struct sigma_conn *conn,
4089 const char *intf, const char *val)
4090{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004091 if (strcasecmp(val, "Auto") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004092 run_iwpriv(dut, intf, "chwidth 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004093 dut->chwidth = 0;
4094 } else if (strcasecmp(val, "20") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004095 run_iwpriv(dut, intf, "chwidth 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004096 dut->chwidth = 0;
4097 } else if (strcasecmp(val, "40") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004098 run_iwpriv(dut, intf, "chwidth 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004099 dut->chwidth = 1;
4100 } else if (strcasecmp(val, "80") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004101 run_iwpriv(dut, intf, "chwidth 2");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004102 dut->chwidth = 2;
4103 } else if (strcasecmp(val, "160") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004104 run_iwpriv(dut, intf, "chwidth 3");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004105 dut->chwidth = 3;
4106 } else {
4107 send_resp(dut, conn, SIGMA_ERROR,
4108 "ErrorCode,WIDTH not supported");
4109 return -1;
4110 }
4111
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004112 return 0;
4113}
4114
4115
4116static int wcn_sta_set_sp_stream(struct sigma_dut *dut, const char *intf,
4117 const char *val)
4118{
4119 char buf[60];
Arif Hussainac6c5112018-05-25 17:34:00 -07004120 int sta_nss;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004121
Amarnath Hullur Subramanyamd5374fa2018-02-25 19:00:24 -08004122 if (strcmp(val, "1SS") == 0 || strcmp(val, "1") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004123 snprintf(buf, sizeof(buf), "iwpriv %s nss 1", intf);
Arif Hussainac6c5112018-05-25 17:34:00 -07004124 sta_nss = 1;
Amarnath Hullur Subramanyamd5374fa2018-02-25 19:00:24 -08004125 } else if (strcmp(val, "2SS") == 0 || strcmp(val, "2") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004126 snprintf(buf, sizeof(buf), "iwpriv %s nss 2", intf);
Arif Hussainac6c5112018-05-25 17:34:00 -07004127 sta_nss = 2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004128 } else {
4129 sigma_dut_print(dut, DUT_MSG_ERROR,
4130 "SP_STREAM value not supported");
4131 return -1;
4132 }
4133
4134 if (system(buf) != 0) {
4135 sigma_dut_print(dut, DUT_MSG_ERROR,
4136 "Failed to set SP_STREAM");
4137 return -1;
4138 }
4139
Arif Hussainac6c5112018-05-25 17:34:00 -07004140 dut->sta_nss = sta_nss;
4141
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004142 return 0;
4143}
4144
4145
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05304146static void wcn_sta_set_stbc(struct sigma_dut *dut, const char *intf,
4147 const char *val)
4148{
4149 char buf[60];
4150
4151 snprintf(buf, sizeof(buf), "iwpriv %s tx_stbc %s", intf, val);
4152 if (system(buf) != 0)
4153 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv tx_stbc failed");
4154
4155 snprintf(buf, sizeof(buf), "iwpriv %s rx_stbc %s", intf, val);
4156 if (system(buf) != 0)
4157 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv rx_stbc failed");
4158}
4159
4160
Ashwini Patil68d02cd2017-01-10 15:39:16 +05304161static int mbo_set_cellular_data_capa(struct sigma_dut *dut,
4162 struct sigma_conn *conn,
4163 const char *intf, int capa)
4164{
4165 char buf[32];
4166
4167 if (capa > 0 && capa < 4) {
4168 snprintf(buf, sizeof(buf), "SET mbo_cell_capa %d", capa);
4169 if (wpa_command(intf, buf) < 0) {
4170 send_resp(dut, conn, SIGMA_ERROR,
4171 "ErrorCode, Failed to set cellular data capability");
4172 return 0;
4173 }
4174 return 1;
4175 }
4176
4177 sigma_dut_print(dut, DUT_MSG_ERROR,
4178 "Invalid Cellular data capability: %d", capa);
4179 send_resp(dut, conn, SIGMA_INVALID,
4180 "ErrorCode,Invalid cellular data capability");
4181 return 0;
4182}
4183
4184
Ashwini Patil9183fdb2017-04-13 16:58:25 +05304185static int mbo_set_roaming(struct sigma_dut *dut, struct sigma_conn *conn,
4186 const char *intf, const char *val)
4187{
4188 if (strcasecmp(val, "Disable") == 0) {
4189 if (wpa_command(intf, "SET roaming 0") < 0) {
4190 send_resp(dut, conn, SIGMA_ERROR,
4191 "ErrorCode,Failed to disable roaming");
4192 return 0;
4193 }
4194 return 1;
4195 }
4196
4197 if (strcasecmp(val, "Enable") == 0) {
4198 if (wpa_command(intf, "SET roaming 1") < 0) {
4199 send_resp(dut, conn, SIGMA_ERROR,
4200 "ErrorCode,Failed to enable roaming");
4201 return 0;
4202 }
4203 return 1;
4204 }
4205
4206 sigma_dut_print(dut, DUT_MSG_ERROR,
4207 "Invalid value provided for roaming: %s", val);
4208 send_resp(dut, conn, SIGMA_INVALID,
4209 "ErrorCode,Unknown value provided for Roaming");
4210 return 0;
4211}
4212
4213
Ashwini Patila75de5a2017-04-13 16:35:05 +05304214static int mbo_set_assoc_disallow(struct sigma_dut *dut,
4215 struct sigma_conn *conn,
4216 const char *intf, const char *val)
4217{
4218 if (strcasecmp(val, "Disable") == 0) {
4219 if (wpa_command(intf, "SET ignore_assoc_disallow 1") < 0) {
4220 send_resp(dut, conn, SIGMA_ERROR,
4221 "ErrorCode,Failed to disable Assoc_disallow");
4222 return 0;
4223 }
4224 return 1;
4225 }
4226
4227 if (strcasecmp(val, "Enable") == 0) {
4228 if (wpa_command(intf, "SET ignore_assoc_disallow 0") < 0) {
4229 send_resp(dut, conn, SIGMA_ERROR,
4230 "ErrorCode,Failed to enable Assoc_disallow");
4231 return 0;
4232 }
4233 return 1;
4234 }
4235
4236 sigma_dut_print(dut, DUT_MSG_ERROR,
4237 "Invalid value provided for Assoc_disallow: %s", val);
4238 send_resp(dut, conn, SIGMA_INVALID,
4239 "ErrorCode,Unknown value provided for Assoc_disallow");
4240 return 0;
4241}
4242
4243
Ashwini Patilc63161e2017-04-13 16:30:23 +05304244static int mbo_set_bss_trans_req(struct sigma_dut *dut, struct sigma_conn *conn,
4245 const char *intf, const char *val)
4246{
4247 if (strcasecmp(val, "Reject") == 0) {
4248 if (wpa_command(intf, "SET reject_btm_req_reason 1") < 0) {
4249 send_resp(dut, conn, SIGMA_ERROR,
4250 "ErrorCode,Failed to Reject BTM Request");
4251 return 0;
4252 }
4253 return 1;
4254 }
4255
4256 if (strcasecmp(val, "Accept") == 0) {
4257 if (wpa_command(intf, "SET reject_btm_req_reason 0") < 0) {
4258 send_resp(dut, conn, SIGMA_ERROR,
4259 "ErrorCode,Failed to Accept BTM Request");
4260 return 0;
4261 }
4262 return 1;
4263 }
4264
4265 sigma_dut_print(dut, DUT_MSG_ERROR,
4266 "Invalid value provided for BSS_Transition: %s", val);
4267 send_resp(dut, conn, SIGMA_INVALID,
4268 "ErrorCode,Unknown value provided for BSS_Transition");
4269 return 0;
4270}
4271
4272
Ashwini Patil00402582017-04-13 12:29:39 +05304273static int mbo_set_non_pref_ch_list(struct sigma_dut *dut,
4274 struct sigma_conn *conn,
4275 const char *intf,
4276 struct sigma_cmd *cmd)
4277{
4278 const char *ch, *pref, *op_class, *reason;
4279 char buf[120];
4280 int len, ret;
4281
4282 pref = get_param(cmd, "Ch_Pref");
4283 if (!pref)
4284 return 1;
4285
4286 if (strcasecmp(pref, "clear") == 0) {
4287 free(dut->non_pref_ch_list);
4288 dut->non_pref_ch_list = NULL;
4289 } else {
4290 op_class = get_param(cmd, "Ch_Op_Class");
4291 if (!op_class) {
4292 send_resp(dut, conn, SIGMA_INVALID,
4293 "ErrorCode,Ch_Op_Class not provided");
4294 return 0;
4295 }
4296
4297 ch = get_param(cmd, "Ch_Pref_Num");
4298 if (!ch) {
4299 send_resp(dut, conn, SIGMA_INVALID,
4300 "ErrorCode,Ch_Pref_Num not provided");
4301 return 0;
4302 }
4303
4304 reason = get_param(cmd, "Ch_Reason_Code");
4305 if (!reason) {
4306 send_resp(dut, conn, SIGMA_INVALID,
4307 "ErrorCode,Ch_Reason_Code not provided");
4308 return 0;
4309 }
4310
4311 if (!dut->non_pref_ch_list) {
4312 dut->non_pref_ch_list =
4313 calloc(1, NON_PREF_CH_LIST_SIZE);
4314 if (!dut->non_pref_ch_list) {
4315 send_resp(dut, conn, SIGMA_ERROR,
4316 "ErrorCode,Failed to allocate memory for non_pref_ch_list");
4317 return 0;
4318 }
4319 }
4320 len = strlen(dut->non_pref_ch_list);
4321 ret = snprintf(dut->non_pref_ch_list + len,
4322 NON_PREF_CH_LIST_SIZE - len,
4323 " %s:%s:%s:%s", op_class, ch, pref, reason);
4324 if (ret > 0 && ret < NON_PREF_CH_LIST_SIZE - len) {
4325 sigma_dut_print(dut, DUT_MSG_DEBUG, "non_pref_list: %s",
4326 dut->non_pref_ch_list);
4327 } else {
4328 sigma_dut_print(dut, DUT_MSG_ERROR,
4329 "snprintf failed for non_pref_list, ret = %d",
4330 ret);
4331 send_resp(dut, conn, SIGMA_ERROR,
4332 "ErrorCode,snprintf failed");
4333 free(dut->non_pref_ch_list);
4334 dut->non_pref_ch_list = NULL;
4335 return 0;
4336 }
4337 }
4338
4339 ret = snprintf(buf, sizeof(buf), "SET non_pref_chan%s",
4340 dut->non_pref_ch_list ? dut->non_pref_ch_list : " ");
4341 if (ret < 0 || ret >= (int) sizeof(buf)) {
4342 sigma_dut_print(dut, DUT_MSG_DEBUG,
4343 "snprintf failed for set non_pref_chan, ret: %d",
4344 ret);
4345 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,snprint failed");
4346 return 0;
4347 }
4348
4349 if (wpa_command(intf, buf) < 0) {
4350 send_resp(dut, conn, SIGMA_ERROR,
4351 "ErrorCode,Failed to set non-preferred channel list");
4352 return 0;
4353 }
4354
4355 return 1;
4356}
4357
4358
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08004359#ifdef NL80211_SUPPORT
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08004360
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08004361static int sta_set_he_htc_supp(struct sigma_dut *dut, const char *intf,
4362 uint8_t cfg)
4363{
4364 struct nl_msg *msg;
4365 int ret = 0;
4366 struct nlattr *params;
4367 int ifindex;
4368
4369 ifindex = if_nametoindex(intf);
4370 if (ifindex == 0) {
4371 sigma_dut_print(dut, DUT_MSG_ERROR,
4372 "%s: Index for interface %s failed",
4373 __func__, intf);
4374 return -1;
4375 }
4376
4377 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4378 NL80211_CMD_VENDOR)) ||
4379 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4380 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4381 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4382 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4383 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4384 nla_put_u8(msg,
4385 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_HTC_HE_SUPP,
4386 cfg)) {
4387 sigma_dut_print(dut, DUT_MSG_ERROR,
4388 "%s: err in adding vendor_cmd and vendor_data",
4389 __func__);
4390 nlmsg_free(msg);
4391 return -1;
4392 }
4393 nla_nest_end(msg, params);
4394
4395 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4396 if (ret) {
4397 sigma_dut_print(dut, DUT_MSG_ERROR,
4398 "%s: err in send_and_recv_msgs, ret=%d",
4399 __func__, ret);
4400 }
4401 return ret;
4402}
4403
4404
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08004405static int sta_set_he_fragmentation(struct sigma_dut *dut, const char *intf,
4406 enum he_fragmentation_val frag)
4407{
4408 struct nl_msg *msg;
4409 int ret = 0;
4410 struct nlattr *params;
4411 int ifindex;
4412
4413 ifindex = if_nametoindex(intf);
4414 if (ifindex == 0) {
4415 sigma_dut_print(dut, DUT_MSG_ERROR,
4416 "%s: Index for interface %s failed",
4417 __func__, intf);
4418 return -1;
4419 }
4420
4421 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4422 NL80211_CMD_VENDOR)) ||
4423 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4424 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4425 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4426 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4427 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4428 nla_put_u8(msg,
4429 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_FRAGMENTATION,
4430 frag)) {
4431 sigma_dut_print(dut, DUT_MSG_ERROR,
4432 "%s: err in adding vendor_cmd and vendor_data",
4433 __func__);
4434 nlmsg_free(msg);
4435 return -1;
4436 }
4437 nla_nest_end(msg, params);
4438
4439 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4440 if (ret) {
4441 sigma_dut_print(dut, DUT_MSG_ERROR,
4442 "%s: err in send_and_recv_msgs, ret=%d",
4443 __func__, ret);
4444 }
4445 return ret;
4446}
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08004447
4448
Subhani Shaik8e7a3052018-04-24 14:03:00 -07004449static int sta_set_he_ltf(struct sigma_dut *dut, const char *intf,
4450 enum qca_wlan_he_ltf_cfg ltf)
4451{
4452 struct nl_msg *msg;
4453 int ret = 0;
4454 struct nlattr *params;
4455 int ifindex;
4456
4457 ifindex = if_nametoindex(intf);
4458 if (ifindex == 0) {
4459 sigma_dut_print(dut, DUT_MSG_ERROR,
4460 "%s: Index for interface %s failed",
4461 __func__, intf);
4462 return -1;
4463 }
4464
4465 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4466 NL80211_CMD_VENDOR)) ||
4467 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4468 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4469 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4470 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4471 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4472 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_LTF,
4473 ltf)) {
4474 sigma_dut_print(dut, DUT_MSG_ERROR,
4475 "%s: err in adding vendor_cmd and vendor_data",
4476 __func__);
4477 nlmsg_free(msg);
4478 return -1;
4479 }
4480 nla_nest_end(msg, params);
4481
4482 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4483 if (ret) {
4484 sigma_dut_print(dut, DUT_MSG_ERROR,
4485 "%s: err in send_and_recv_msgs, ret=%d",
4486 __func__, ret);
4487 }
4488 return ret;
4489}
4490
4491
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08004492static int nlvendor_sta_set_noack(struct sigma_dut *dut, const char *intf,
4493 int noack, enum qca_wlan_ac_type ac)
4494{
4495 struct nl_msg *msg;
4496 int ret = 0;
4497 struct nlattr *params;
4498 int ifindex;
4499
4500 ifindex = if_nametoindex(intf);
4501 if (ifindex == 0) {
4502 sigma_dut_print(dut, DUT_MSG_ERROR,
4503 "%s: Index for interface %s failed",
4504 __func__, intf);
4505 return -1;
4506 }
4507
4508 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4509 NL80211_CMD_VENDOR)) ||
4510 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4511 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4512 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4513 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4514 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4515 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_NO_ACK,
4516 noack) ||
4517 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_NO_ACK_AC,
4518 ac)) {
4519 sigma_dut_print(dut, DUT_MSG_ERROR,
4520 "%s: err in adding vendor_cmd and vendor_data",
4521 __func__);
4522 nlmsg_free(msg);
4523 return -1;
4524 }
4525 nla_nest_end(msg, params);
4526
4527 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4528 if (ret) {
4529 sigma_dut_print(dut, DUT_MSG_ERROR,
4530 "%s: err in send_and_recv_msgs, ret=%d",
4531 __func__, ret);
4532 }
4533 return ret;
4534}
4535
4536
4537static void wcn_sta_set_noack(struct sigma_dut *dut, const char *intf,
4538 const char *val)
4539{
4540 int noack, ret;
4541 char token[100];
4542 char *result;
4543 char *saveptr;
4544 enum qca_wlan_ac_type ac = QCA_WLAN_AC_BE;
4545
4546 strlcpy(token, val, sizeof(token));
4547 token[sizeof(token) - 1] = '\0';
4548 result = strtok_r(token, ":", &saveptr);
4549 while (result) {
4550 noack = strcasecmp(result, "Disable") != 0;
4551 ret = nlvendor_sta_set_noack(dut, intf, noack, ac);
4552 if (ret) {
4553 sigma_dut_print(dut, DUT_MSG_ERROR,
4554 "nlvendor_sta_set_noack failed for ac:%d, ret:%d",
4555 ac, ret);
4556 }
4557 result = strtok_r(NULL, ":", &saveptr);
4558 ac++;
4559 }
4560}
4561
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08004562#endif /* NL80211_SUPPORT */
4563
4564
Jouni Malinenf7222712019-06-13 01:50:21 +03004565static enum sigma_cmd_result
4566cmd_sta_preset_testparameters(struct sigma_dut *dut, struct sigma_conn *conn,
4567 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004568{
4569 const char *intf = get_param(cmd, "Interface");
4570 const char *val;
4571
4572 val = get_param(cmd, "Program");
Jouni Malinen1f6ae642018-06-07 23:56:13 +03004573 if (val && (strcasecmp(val, "HS2-R2") == 0 ||
4574 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004575 return cmd_sta_preset_testparameters_hs2_r2(dut, conn, intf,
4576 cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004577
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07004578 if (val && strcasecmp(val, "LOC") == 0)
4579 return loc_cmd_sta_preset_testparameters(dut, conn, cmd);
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02004580 if (val && strcasecmp(val, "60GHZ") == 0) {
4581 val = get_param(cmd, "WPS");
4582 if (val && strcasecmp(val, "disable") == 0) {
4583 dut->wps_disable = 1;
4584 sigma_dut_print(dut, DUT_MSG_INFO, "WPS disabled");
4585 } else {
4586 /* wps_disable can have other value from the previous
4587 * test, so make sure it has the correct value.
4588 */
4589 dut->wps_disable = 0;
4590 }
4591
4592 val = get_param(cmd, "P2P");
4593 if (val && strcasecmp(val, "disable") == 0)
4594 sigma_dut_print(dut, DUT_MSG_INFO, "P2P disabled");
4595 }
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07004596
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02004597 if (dut->program == PROGRAM_WPS && dut->band == WPS_BAND_60G)
4598 return cmd_sta_preset_testparameters_60ghz(dut, conn, cmd);
4599
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004600#ifdef ANDROID_NAN
4601 if (val && strcasecmp(val, "NAN") == 0)
4602 return nan_cmd_sta_preset_testparameters(dut, conn, cmd);
4603#endif /* ANDROID_NAN */
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07004604#ifdef MIRACAST
4605 if (val && (strcasecmp(val, "WFD") == 0 ||
4606 strcasecmp(val, "DisplayR2") == 0))
4607 return miracast_preset_testparameters(dut, conn, cmd);
4608#endif /* MIRACAST */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004609
Ashwini Patil68d02cd2017-01-10 15:39:16 +05304610 if (val && strcasecmp(val, "MBO") == 0) {
4611 val = get_param(cmd, "Cellular_Data_Cap");
4612 if (val &&
4613 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
4614 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +05304615
4616 val = get_param(cmd, "Ch_Pref");
4617 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
4618 return 0;
4619
Ashwini Patilc63161e2017-04-13 16:30:23 +05304620 val = get_param(cmd, "BSS_Transition");
4621 if (val && mbo_set_bss_trans_req(dut, conn, intf, val) == 0)
4622 return 0;
4623
Ashwini Patila75de5a2017-04-13 16:35:05 +05304624 val = get_param(cmd, "Assoc_Disallow");
4625 if (val && mbo_set_assoc_disallow(dut, conn, intf, val) == 0)
4626 return 0;
4627
Ashwini Patil9183fdb2017-04-13 16:58:25 +05304628 val = get_param(cmd, "Roaming");
4629 if (val && mbo_set_roaming(dut, conn, intf, val) == 0)
4630 return 0;
4631
Ashwini Patil68d02cd2017-01-10 15:39:16 +05304632 return 1;
4633 }
4634
Ankita Bajaja2cb5672017-10-25 16:08:28 +05304635 if (val && strcasecmp(val, "OCE") == 0)
4636 return cmd_sta_preset_testparameters_oce(dut, conn, intf, cmd);
4637
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004638#if 0
4639 val = get_param(cmd, "Supplicant");
4640 if (val && strcasecmp(val, "Default") != 0) {
4641 send_resp(dut, conn, SIGMA_ERROR,
4642 "ErrorCode,Only default(Vendor) supplicant "
4643 "supported");
4644 return 0;
4645 }
4646#endif
4647
4648 val = get_param(cmd, "RTS");
4649 if (val) {
4650 switch (get_driver_type()) {
4651 case DRIVER_ATHEROS:
4652 ath_sta_set_rts(dut, intf, val);
4653 break;
4654 default:
4655#if 0
4656 send_resp(dut, conn, SIGMA_ERROR,
4657 "ErrorCode,Setting RTS not supported");
4658 return 0;
4659#else
4660 sigma_dut_print(dut, DUT_MSG_DEBUG,
4661 "Setting RTS not supported");
4662 break;
4663#endif
4664 }
4665 }
4666
4667#if 0
4668 val = get_param(cmd, "FRGMNT");
4669 if (val) {
4670 /* TODO */
4671 send_resp(dut, conn, SIGMA_ERROR,
4672 "ErrorCode,Setting FRGMNT not supported");
4673 return 0;
4674 }
4675#endif
4676
4677#if 0
4678 val = get_param(cmd, "Preamble");
4679 if (val) {
4680 /* TODO: Long/Short */
4681 send_resp(dut, conn, SIGMA_ERROR,
4682 "ErrorCode,Setting Preamble not supported");
4683 return 0;
4684 }
4685#endif
4686
4687 val = get_param(cmd, "Mode");
4688 if (val) {
4689 if (strcmp(val, "11b") == 0 ||
4690 strcmp(val, "11g") == 0 ||
4691 strcmp(val, "11a") == 0 ||
4692 strcmp(val, "11n") == 0 ||
4693 strcmp(val, "11ng") == 0 ||
4694 strcmp(val, "11nl") == 0 ||
4695 strcmp(val, "11nl(nabg)") == 0 ||
4696 strcmp(val, "AC") == 0 ||
4697 strcmp(val, "11AC") == 0 ||
4698 strcmp(val, "11ac") == 0 ||
4699 strcmp(val, "11na") == 0 ||
Amarnath Hullur Subramanyamb0db2712018-01-30 19:40:35 -08004700 strcmp(val, "11an") == 0 ||
4701 strcmp(val, "11ax") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004702 /* STA supports all modes by default */
4703 } else {
4704 send_resp(dut, conn, SIGMA_ERROR,
4705 "ErrorCode,Setting Mode not supported");
4706 return 0;
4707 }
Amarnath Hullur Subramanyam97d0e532018-01-31 02:53:02 -08004708
4709 /* Change the mode only in case of testbed for HE program
4710 * and for 11a and 11g modes only. */
4711 if (dut->program == PROGRAM_HE &&
4712 dut->device_type == STA_testbed) {
4713 int phymode;
4714 char buf[60];
4715
4716 if (strcmp(val, "11a") == 0) {
Amarnath Hullur Subramanyam94dfaf02018-03-02 19:26:57 -08004717 phymode = 1; /* IEEE80211_MODE_11A */
4718 } else if (strcmp(val, "11g") == 0) {
4719 phymode = 3; /* IEEE80211_MODE_11G */
4720 } else if (strcmp(val, "11b") == 0) {
4721 phymode = 2; /* IEEE80211_MODE_11B */
4722 } else if (strcmp(val, "11n") == 0 ||
4723 strcmp(val, "11nl") == 0 ||
4724 strcmp(val, "11nl(nabg)") == 0) {
4725 phymode = 22; /* IEEE80211_MODE_11AGN */
4726 } else if (strcmp(val, "11ng") == 0) {
4727 phymode = 13; /* IEEE80211_MODE_11NG_HT40 */
4728 } else if (strcmp(val, "AC") == 0 ||
4729 strcasecmp(val, "11AC") == 0) {
4730 phymode = 19; /* IEEE80211_MODE_11AC_VHT80 */
4731 } else if (strcmp(val, "11na") == 0 ||
4732 strcasecmp(val, "11an") == 0) {
4733 phymode = 14; /* IEEE80211_MODE_11NA_HT40 */
4734 } else if (strcmp(val, "11ax") == 0) {
4735 phymode = 0; /* IEEE80211_MODE_AUTO */
Amarnath Hullur Subramanyam97d0e532018-01-31 02:53:02 -08004736 } else {
4737 sigma_dut_print(dut, DUT_MSG_DEBUG,
4738 "Ignoring mode change for mode: %s",
4739 val);
4740 phymode = -1;
4741 }
4742 if (phymode != -1) {
4743 snprintf(buf, sizeof(buf),
4744 "iwpriv %s setphymode %d",
4745 intf, phymode);
4746 if (system(buf) != 0) {
4747 sigma_dut_print(dut, DUT_MSG_ERROR,
4748 "iwpriv setting of phymode failed");
4749 }
4750 }
4751 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004752 }
4753
4754 val = get_param(cmd, "wmm");
4755 if (val) {
4756 switch (get_driver_type()) {
4757 case DRIVER_ATHEROS:
4758 ath_sta_set_wmm(dut, intf, val);
4759 break;
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08004760 case DRIVER_WCN:
4761 wcn_sta_set_wmm(dut, intf, val);
4762 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004763 default:
4764 sigma_dut_print(dut, DUT_MSG_DEBUG,
4765 "Setting wmm not supported");
4766 break;
4767 }
4768 }
4769
4770 val = get_param(cmd, "Powersave");
4771 if (val) {
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08004772 char buf[60];
4773
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004774 if (strcmp(val, "0") == 0 || strcasecmp(val, "off") == 0) {
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08004775 if (get_driver_type() == DRIVER_WCN) {
4776 snprintf(buf, sizeof(buf),
4777 "iwpriv %s setPower 2", intf);
4778 if (system(buf) != 0) {
4779 sigma_dut_print(dut, DUT_MSG_ERROR,
4780 "iwpriv setPower 2 failed");
4781 return 0;
4782 }
4783 }
4784
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004785 if (wpa_command(get_station_ifname(),
4786 "P2P_SET ps 0") < 0)
4787 return -2;
4788 /* Make sure test modes are disabled */
4789 wpa_command(get_station_ifname(), "P2P_SET ps 98");
4790 wpa_command(get_station_ifname(), "P2P_SET ps 96");
4791 } else if (strcmp(val, "1") == 0 ||
4792 strcasecmp(val, "PSPoll") == 0 ||
4793 strcasecmp(val, "on") == 0) {
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08004794 if (get_driver_type() == DRIVER_WCN) {
4795 snprintf(buf, sizeof(buf),
4796 "iwpriv %s setPower 1", intf);
4797 if (system(buf) != 0) {
4798 sigma_dut_print(dut, DUT_MSG_ERROR,
4799 "iwpriv setPower 1 failed");
4800 return 0;
4801 }
4802 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004803 /* Disable default power save mode */
4804 wpa_command(get_station_ifname(), "P2P_SET ps 0");
4805 /* Enable PS-Poll test mode */
4806 if (wpa_command(get_station_ifname(),
4807 "P2P_SET ps 97") < 0 ||
4808 wpa_command(get_station_ifname(),
4809 "P2P_SET ps 99") < 0)
4810 return -2;
4811 } else if (strcmp(val, "2") == 0 ||
4812 strcasecmp(val, "Fast") == 0) {
4813 /* TODO */
4814 send_resp(dut, conn, SIGMA_ERROR,
4815 "ErrorCode,Powersave=Fast not supported");
4816 return 0;
4817 } else if (strcmp(val, "3") == 0 ||
4818 strcasecmp(val, "PSNonPoll") == 0) {
4819 /* Make sure test modes are disabled */
4820 wpa_command(get_station_ifname(), "P2P_SET ps 98");
4821 wpa_command(get_station_ifname(), "P2P_SET ps 96");
4822
4823 /* Enable default power save mode */
4824 if (wpa_command(get_station_ifname(),
4825 "P2P_SET ps 1") < 0)
4826 return -2;
4827 } else
4828 return -1;
4829 }
4830
4831 val = get_param(cmd, "NoAck");
4832 if (val) {
4833 switch (get_driver_type()) {
4834 case DRIVER_ATHEROS:
4835 ath_sta_set_noack(dut, intf, val);
4836 break;
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08004837#ifdef NL80211_SUPPORT
4838 case DRIVER_WCN:
4839 wcn_sta_set_noack(dut, intf, val);
4840 break;
4841#endif /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004842 default:
4843 send_resp(dut, conn, SIGMA_ERROR,
4844 "ErrorCode,Setting NoAck not supported");
4845 return 0;
4846 }
4847 }
4848
4849 val = get_param(cmd, "IgnoreChswitchProhibit");
4850 if (val) {
4851 /* TODO: Enabled/disabled */
4852 if (strcasecmp(val, "Enabled") == 0) {
4853 send_resp(dut, conn, SIGMA_ERROR,
4854 "ErrorCode,Enabling IgnoreChswitchProhibit "
4855 "not supported");
4856 return 0;
4857 }
4858 }
4859
4860 val = get_param(cmd, "TDLS");
4861 if (val) {
4862 if (strcasecmp(val, "Disabled") == 0) {
4863 if (wpa_command(intf, "SET tdls_disabled 1")) {
4864 send_resp(dut, conn, SIGMA_ERROR,
4865 "ErrorCode,Failed to disable TDLS");
4866 return 0;
4867 }
4868 } else if (strcasecmp(val, "Enabled") == 0) {
4869 if (wpa_command(intf, "SET tdls_disabled 0")) {
4870 send_resp(dut, conn, SIGMA_ERROR,
4871 "ErrorCode,Failed to enable TDLS");
4872 return 0;
4873 }
4874 } else {
4875 send_resp(dut, conn, SIGMA_ERROR,
4876 "ErrorCode,Unsupported TDLS value");
4877 return 0;
4878 }
4879 }
4880
4881 val = get_param(cmd, "TDLSmode");
4882 if (val) {
4883 if (strcasecmp(val, "Default") == 0) {
4884 wpa_command(intf, "SET tdls_testing 0");
4885 } else if (strcasecmp(val, "APProhibit") == 0) {
4886 if (wpa_command(intf, "SET tdls_testing 0x400")) {
4887 send_resp(dut, conn, SIGMA_ERROR,
4888 "ErrorCode,Failed to enable ignore "
4889 "APProhibit TDLS mode");
4890 return 0;
4891 }
4892 } else if (strcasecmp(val, "HiLoMac") == 0) {
4893 /* STA should respond with TDLS setup req for a TDLS
4894 * setup req */
4895 if (wpa_command(intf, "SET tdls_testing 0x80")) {
4896 send_resp(dut, conn, SIGMA_ERROR,
4897 "ErrorCode,Failed to enable HiLoMac "
4898 "TDLS mode");
4899 return 0;
4900 }
4901 } else if (strcasecmp(val, "WeakSecurity") == 0) {
4902 /*
4903 * Since all security modes are enabled by default when
4904 * Sigma control is used, there is no need to do
4905 * anything here.
4906 */
4907 } else if (strcasecmp(val, "ExistLink") == 0) {
4908 /*
4909 * Since we allow new TDLS Setup Request even if there
4910 * is an existing link, nothing needs to be done for
4911 * this.
4912 */
4913 } else {
4914 /* TODO:
4915 * ExistLink: STA should send TDLS setup req even if
4916 * direct link already exists
4917 */
4918 send_resp(dut, conn, SIGMA_ERROR,
4919 "ErrorCode,Unsupported TDLSmode value");
4920 return 0;
4921 }
4922 }
4923
4924 val = get_param(cmd, "FakePubKey");
4925 if (val && atoi(val) && wpa_command(intf, "SET wps_corrupt_pkhash 1")) {
4926 send_resp(dut, conn, SIGMA_ERROR,
4927 "ErrorCode,Failed to enable FakePubKey");
4928 return 0;
4929 }
4930
Amarnath Hullur Subramanyamae1042b2018-02-22 21:52:52 -08004931#ifdef NL80211_SUPPORT
4932 val = get_param(cmd, "FrgmntSupport");
4933 if (val) {
4934 if (strcasecmp(val, "Enable") == 0) {
4935 if (sta_set_he_fragmentation(dut, intf,
4936 HE_FRAG_LEVEL1)) {
4937 send_resp(dut, conn, SIGMA_ERROR,
4938 "ErrorCode,Failed to enable HE Fragmentation");
4939 return 0;
4940 }
4941 } else if (strcasecmp(val, "Disable") == 0) {
4942 if (sta_set_he_fragmentation(dut, intf,
4943 HE_FRAG_DISABLE)) {
4944 send_resp(dut, conn, SIGMA_ERROR,
4945 "ErrorCode,Failed to disable HE Fragmentation");
4946 return 0;
4947 }
4948 }
4949 }
4950#endif /* NL80211_SUPPORT */
4951
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004952 return 1;
4953}
4954
4955
4956static const char * ath_get_radio_name(const char *radio_name)
4957{
4958 if (radio_name == NULL)
4959 return "wifi0";
4960 if (strcmp(radio_name, "wifi1") == 0)
4961 return "wifi1";
4962 if (strcmp(radio_name, "wifi2") == 0)
4963 return "wifi2";
4964 return "wifi0";
4965}
4966
4967
4968static void ath_sta_set_txsp_stream(struct sigma_dut *dut, const char *intf,
4969 const char *val)
4970{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004971 unsigned int vht_mcsmap = 0;
4972 int txchainmask = 0;
4973 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
4974
4975 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
4976 if (dut->testbed_flag_txsp == 1) {
4977 vht_mcsmap = 0xfffc;
4978 dut->testbed_flag_txsp = 0;
4979 } else {
4980 vht_mcsmap = 0xfffe;
4981 }
4982 txchainmask = 1;
4983 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
4984 if (dut->testbed_flag_txsp == 1) {
4985 vht_mcsmap = 0xfff0;
4986 dut->testbed_flag_txsp = 0;
4987 } else {
4988 vht_mcsmap = 0xfffa;
4989 }
4990 txchainmask = 3;
4991 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
4992 if (dut->testbed_flag_txsp == 1) {
4993 vht_mcsmap = 0xffc0;
4994 dut->testbed_flag_txsp = 0;
4995 } else {
4996 vht_mcsmap = 0xffea;
4997 }
4998 txchainmask = 7;
4999 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
5000 if (dut->testbed_flag_txsp == 1) {
5001 vht_mcsmap = 0xff00;
5002 dut->testbed_flag_txsp = 0;
5003 } else {
5004 vht_mcsmap = 0xffaa;
5005 }
5006 txchainmask = 15;
5007 } else {
5008 if (dut->testbed_flag_txsp == 1) {
5009 vht_mcsmap = 0xffc0;
5010 dut->testbed_flag_txsp = 0;
5011 } else {
5012 vht_mcsmap = 0xffea;
5013 }
5014 }
5015
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005016 if (txchainmask)
5017 run_iwpriv(dut, basedev, "txchainmask %d", txchainmask);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005018
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005019 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005020}
5021
5022
5023static void ath_sta_set_rxsp_stream(struct sigma_dut *dut, const char *intf,
5024 const char *val)
5025{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005026 unsigned int vht_mcsmap = 0;
5027 int rxchainmask = 0;
5028 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
5029
5030 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
5031 if (dut->testbed_flag_rxsp == 1) {
5032 vht_mcsmap = 0xfffc;
5033 dut->testbed_flag_rxsp = 0;
5034 } else {
5035 vht_mcsmap = 0xfffe;
5036 }
5037 rxchainmask = 1;
5038 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
5039 if (dut->testbed_flag_rxsp == 1) {
5040 vht_mcsmap = 0xfff0;
5041 dut->testbed_flag_rxsp = 0;
5042 } else {
5043 vht_mcsmap = 0xfffa;
5044 }
5045 rxchainmask = 3;
5046 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
5047 if (dut->testbed_flag_rxsp == 1) {
5048 vht_mcsmap = 0xffc0;
5049 dut->testbed_flag_rxsp = 0;
5050 } else {
5051 vht_mcsmap = 0xffea;
5052 }
5053 rxchainmask = 7;
5054 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
5055 if (dut->testbed_flag_rxsp == 1) {
5056 vht_mcsmap = 0xff00;
5057 dut->testbed_flag_rxsp = 0;
5058 } else {
5059 vht_mcsmap = 0xffaa;
5060 }
5061 rxchainmask = 15;
5062 } else {
5063 if (dut->testbed_flag_rxsp == 1) {
5064 vht_mcsmap = 0xffc0;
5065 dut->testbed_flag_rxsp = 0;
5066 } else {
5067 vht_mcsmap = 0xffea;
5068 }
5069 }
5070
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005071 if (rxchainmask)
5072 run_iwpriv(dut, basedev, "rxchainmask %d", rxchainmask);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005073
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005074 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005075}
5076
5077
5078void ath_set_zero_crc(struct sigma_dut *dut, const char *val)
5079{
5080 if (strcasecmp(val, "enable") == 0) {
5081 if (system("athdiag --set --address=0x2a204 --and=0xbfffffff")
5082 != 0) {
5083 sigma_dut_print(dut, DUT_MSG_ERROR,
5084 "Disable BB_VHTSIGB_CRC_CALC failed");
5085 }
5086
5087 if (system("athdiag --set --address=0x2a204 --or=0x80000000")
5088 != 0) {
5089 sigma_dut_print(dut, DUT_MSG_ERROR,
5090 "Enable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
5091 }
5092 } else {
5093 if (system("athdiag --set --address=0x2a204 --and=0x7fffffff")
5094 != 0) {
5095 sigma_dut_print(dut, DUT_MSG_ERROR,
5096 "Disable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
5097 }
5098
5099 if (system("athdiag --set --address=0x2a204 --or=0x40000000")
5100 != 0) {
5101 sigma_dut_print(dut, DUT_MSG_ERROR,
5102 "Enable BB_VHTSIGB_CRC_CALC failed");
5103 }
5104 }
5105}
5106
5107
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08005108static int wcn_sta_set_width(struct sigma_dut *dut, const char *intf,
5109 const char *val)
5110{
5111 char buf[60];
5112
5113 if (strcmp(val, "20") == 0) {
5114 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 0", intf);
5115 dut->chwidth = 0;
5116 } else if (strcmp(val, "40") == 0) {
5117 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 1", intf);
5118 dut->chwidth = 1;
5119 } else if (strcmp(val, "80") == 0) {
5120 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 2", intf);
5121 dut->chwidth = 2;
Sunil Duttb1cccac2018-05-22 21:03:12 +05305122 } else if (strcasecmp(val, "Auto") == 0) {
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08005123 buf[0] = '\0';
5124 } else {
5125 sigma_dut_print(dut, DUT_MSG_ERROR, "WIDTH %s not supported",
5126 val);
5127 return -1;
5128 }
5129
5130 if (buf[0] != '\0' && system(buf) != 0) {
5131 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv chwidth failed");
5132 return -1;
5133 }
5134
5135 return 0;
5136}
5137
5138
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005139static int nlvendor_sta_set_addba_reject(struct sigma_dut *dut,
5140 const char *intf, int addbareject)
5141{
5142#ifdef NL80211_SUPPORT
5143 struct nl_msg *msg;
5144 int ret = 0;
5145 struct nlattr *params;
5146 int ifindex;
5147
5148 ifindex = if_nametoindex(intf);
5149 if (ifindex == 0) {
5150 sigma_dut_print(dut, DUT_MSG_ERROR,
5151 "%s: Index for interface %s failed",
5152 __func__, intf);
5153 return -1;
5154 }
5155
5156 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
5157 NL80211_CMD_VENDOR)) ||
5158 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
5159 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
5160 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
5161 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
5162 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
5163 nla_put_u8(msg,
5164 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ACCEPT_ADDBA_REQ,
5165 !addbareject)) {
5166 sigma_dut_print(dut, DUT_MSG_ERROR,
5167 "%s: err in adding vendor_cmd and vendor_data",
5168 __func__);
5169 nlmsg_free(msg);
5170 return -1;
5171 }
5172 nla_nest_end(msg, params);
5173
5174 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5175 if (ret) {
5176 sigma_dut_print(dut, DUT_MSG_ERROR,
5177 "%s: err in send_and_recv_msgs, ret=%d",
5178 __func__, ret);
5179 }
5180 return ret;
5181#else /* NL80211_SUPPORT */
5182 sigma_dut_print(dut, DUT_MSG_ERROR,
5183 "ADDBA_REJECT cannot be set without NL80211_SUPPORT defined");
5184 return -1;
5185#endif /* NL80211_SUPPORT */
5186}
5187
5188
5189static int sta_set_addba_reject(struct sigma_dut *dut, const char *intf,
5190 int addbareject)
5191{
5192 int ret;
5193
5194 switch (get_driver_type()) {
5195 case DRIVER_WCN:
5196 ret = nlvendor_sta_set_addba_reject(dut, intf, addbareject);
5197 if (ret) {
5198 sigma_dut_print(dut, DUT_MSG_ERROR,
5199 "nlvendor_sta_set_addba_reject failed, ret:%d",
5200 ret);
5201 return ret;
5202 }
5203 break;
5204 default:
5205 sigma_dut_print(dut, DUT_MSG_ERROR,
5206 "errorCode,Unsupported ADDBA_REJECT with the current driver");
5207 ret = -1;
5208 break;
5209 }
5210
5211 return ret;
5212}
5213
5214
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08005215static int nlvendor_config_send_addba(struct sigma_dut *dut, const char *intf,
5216 int enable)
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005217{
5218#ifdef NL80211_SUPPORT
5219 struct nl_msg *msg;
5220 int ret = 0;
5221 struct nlattr *params;
5222 int ifindex;
5223
5224 ifindex = if_nametoindex(intf);
5225 if (ifindex == 0) {
5226 sigma_dut_print(dut, DUT_MSG_ERROR,
5227 "%s: Index for interface %s failed",
5228 __func__, intf);
5229 return -1;
5230 }
5231
5232 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
5233 NL80211_CMD_VENDOR)) ||
5234 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
5235 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
5236 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
5237 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
5238 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
5239 nla_put_u8(msg,
5240 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_SEND_ADDBA_REQ,
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08005241 enable)) {
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005242 sigma_dut_print(dut, DUT_MSG_ERROR,
5243 "%s: err in adding vendor_cmd and vendor_data",
5244 __func__);
5245 nlmsg_free(msg);
5246 return -1;
5247 }
5248 nla_nest_end(msg, params);
5249
5250 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5251 if (ret) {
5252 sigma_dut_print(dut, DUT_MSG_ERROR,
5253 "%s: err in send_and_recv_msgs, ret=%d",
5254 __func__, ret);
5255 }
5256 return ret;
5257#else /* NL80211_SUPPORT */
5258 sigma_dut_print(dut, DUT_MSG_ERROR,
5259 "Disable addba not possible without NL80211_SUPPORT defined");
5260 return -1;
5261#endif /* NL80211_SUPPORT */
5262}
5263
5264
Veerendranath Jakkamadcd6202019-04-17 12:32:21 +05305265#ifdef NL80211_SUPPORT
5266static int nl80211_sta_set_rts(struct sigma_dut *dut, const char *intf, int val)
5267{
5268 struct nl_msg *msg;
5269 int ret = 0;
5270 int ifindex;
5271
5272 ifindex = if_nametoindex(intf);
5273 if (ifindex == 0) {
5274 sigma_dut_print(dut, DUT_MSG_ERROR,
5275 "%s: Index for interface %s failed",
5276 __func__, intf);
5277 return -1;
5278 }
5279
5280 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
5281 NL80211_CMD_SET_WIPHY)) ||
5282 nla_put_u32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD, val)) {
5283 sigma_dut_print(dut, DUT_MSG_ERROR,
5284 "%s: err in adding RTS threshold",
5285 __func__);
5286 nlmsg_free(msg);
5287 return -1;
5288 }
5289
5290 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5291 if (ret) {
5292 sigma_dut_print(dut, DUT_MSG_ERROR,
5293 "%s: err in send_and_recv_msgs, ret=%d",
5294 __func__, ret);
5295 }
5296 return ret;
5297}
5298#endif /* NL80211_SUPPORT */
5299
5300
5301static int sta_set_rts(struct sigma_dut *dut, const char *intf, int val)
5302{
5303 char buf[100];
5304
5305#ifdef NL80211_SUPPORT
5306 if (nl80211_sta_set_rts(dut, intf, val) == 0)
5307 return 0;
5308 sigma_dut_print(dut, DUT_MSG_DEBUG,
5309 "Fall back to using iwconfig for setting RTS threshold");
5310#endif /* NL80211_SUPPORT */
5311
5312 snprintf(buf, sizeof(buf), "iwconfig %s rts %d", intf, val);
5313 if (system(buf) != 0) {
5314 sigma_dut_print(dut, DUT_MSG_ERROR,
5315 "Failed to set RTS threshold %d", val);
5316 return -1;
5317 }
5318 return 0;
5319}
5320
5321
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005322static int cmd_sta_set_wireless_common(const char *intf, struct sigma_dut *dut,
5323 struct sigma_conn *conn,
5324 struct sigma_cmd *cmd)
5325{
5326 const char *val;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005327 int ampdu = -1, addbareject = -1;
Jouni Malinen3aa72862019-05-29 23:14:51 +03005328 char buf[128];
5329 int res;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005330
5331 val = get_param(cmd, "40_INTOLERANT");
5332 if (val) {
5333 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
5334 /* TODO: iwpriv ht40intol through wpa_supplicant */
5335 send_resp(dut, conn, SIGMA_ERROR,
5336 "ErrorCode,40_INTOLERANT not supported");
5337 return 0;
5338 }
5339 }
5340
5341 val = get_param(cmd, "ADDBA_REJECT");
5342 if (val) {
5343 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
5344 /* reject any ADDBA with status "decline" */
5345 ampdu = 0;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005346 addbareject = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005347 } else {
5348 /* accept ADDBA */
5349 ampdu = 1;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005350 addbareject = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005351 }
5352 }
5353
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005354 if (addbareject >= 0 &&
5355 sta_set_addba_reject(dut, intf, addbareject) < 0) {
5356 send_resp(dut, conn, SIGMA_ERROR,
5357 "ErrorCode,set addba_reject failed");
5358 return 0;
5359 }
5360
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005361 val = get_param(cmd, "AMPDU");
5362 if (val) {
5363 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
5364 /* enable AMPDU Aggregation */
5365 if (ampdu == 0) {
5366 send_resp(dut, conn, SIGMA_ERROR,
5367 "ErrorCode,Mismatch in "
5368 "addba_reject/ampdu - "
5369 "not supported");
5370 return 0;
5371 }
5372 ampdu = 1;
5373 } else {
5374 /* disable AMPDU Aggregation */
5375 if (ampdu == 1) {
5376 send_resp(dut, conn, SIGMA_ERROR,
5377 "ErrorCode,Mismatch in "
5378 "addba_reject/ampdu - "
5379 "not supported");
5380 return 0;
5381 }
5382 ampdu = 0;
5383 }
5384 }
5385
5386 if (ampdu >= 0) {
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005387 int ret;
5388
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005389 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s A-MPDU aggregation",
5390 ampdu ? "Enabling" : "Disabling");
5391 snprintf(buf, sizeof(buf), "SET ampdu %d", ampdu);
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07005392 if (wpa_command(intf, buf) < 0 &&
5393 iwpriv_sta_set_ampdu(dut, intf, ampdu) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005394 send_resp(dut, conn, SIGMA_ERROR,
5395 "ErrorCode,set aggr failed");
5396 return 0;
5397 }
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005398
5399 if (ampdu == 0) {
5400 /* Disable sending of addba using nl vendor command */
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08005401 ret = nlvendor_config_send_addba(dut, intf, 0);
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005402 if (ret) {
5403 sigma_dut_print(dut, DUT_MSG_ERROR,
5404 "Failed to disable addba, ret:%d",
5405 ret);
5406 }
5407 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005408 }
5409
5410 val = get_param(cmd, "AMSDU");
5411 if (val) {
5412 switch (get_driver_type()) {
5413 case DRIVER_ATHEROS:
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08005414 case DRIVER_WCN:
5415 iwpriv_sta_set_amsdu(dut, intf, val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005416 break;
5417 default:
5418 if (strcmp(val, "1") == 0 ||
5419 strcasecmp(val, "Enable") == 0) {
5420 /* Enable AMSDU Aggregation */
5421 send_resp(dut, conn, SIGMA_ERROR,
5422 "ErrorCode,AMSDU aggregation not supported");
5423 return 0;
5424 }
5425 break;
5426 }
5427 }
5428
5429 val = get_param(cmd, "STBC_RX");
5430 if (val) {
5431 switch (get_driver_type()) {
5432 case DRIVER_ATHEROS:
5433 ath_sta_set_stbc(dut, intf, val);
5434 break;
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05305435 case DRIVER_WCN:
5436 wcn_sta_set_stbc(dut, intf, val);
5437 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005438 default:
5439 send_resp(dut, conn, SIGMA_ERROR,
5440 "ErrorCode,STBC_RX not supported");
5441 return 0;
5442 }
5443 }
5444
5445 val = get_param(cmd, "WIDTH");
5446 if (val) {
5447 switch (get_driver_type()) {
5448 case DRIVER_WCN:
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08005449 if (wcn_sta_set_width(dut, intf, val) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005450 send_resp(dut, conn, SIGMA_ERROR,
5451 "ErrorCode,Failed to set WIDTH");
5452 return 0;
5453 }
5454 break;
5455 case DRIVER_ATHEROS:
5456 if (ath_set_width(dut, conn, intf, val) < 0)
5457 return 0;
5458 break;
5459 default:
5460 sigma_dut_print(dut, DUT_MSG_ERROR,
5461 "Setting WIDTH not supported");
5462 break;
5463 }
5464 }
5465
5466 val = get_param(cmd, "SMPS");
5467 if (val) {
5468 /* TODO: Dynamic/0, Static/1, No Limit/2 */
5469 send_resp(dut, conn, SIGMA_ERROR,
5470 "ErrorCode,SMPS not supported");
5471 return 0;
5472 }
5473
5474 val = get_param(cmd, "TXSP_STREAM");
5475 if (val) {
5476 switch (get_driver_type()) {
5477 case DRIVER_WCN:
5478 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
5479 send_resp(dut, conn, SIGMA_ERROR,
5480 "ErrorCode,Failed to set TXSP_STREAM");
5481 return 0;
5482 }
5483 break;
5484 case DRIVER_ATHEROS:
5485 ath_sta_set_txsp_stream(dut, intf, val);
5486 break;
5487 default:
5488 sigma_dut_print(dut, DUT_MSG_ERROR,
5489 "Setting TXSP_STREAM not supported");
5490 break;
5491 }
5492 }
5493
5494 val = get_param(cmd, "RXSP_STREAM");
5495 if (val) {
5496 switch (get_driver_type()) {
5497 case DRIVER_WCN:
5498 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
5499 send_resp(dut, conn, SIGMA_ERROR,
5500 "ErrorCode,Failed to set RXSP_STREAM");
5501 return 0;
5502 }
5503 break;
5504 case DRIVER_ATHEROS:
5505 ath_sta_set_rxsp_stream(dut, intf, val);
5506 break;
5507 default:
5508 sigma_dut_print(dut, DUT_MSG_ERROR,
5509 "Setting RXSP_STREAM not supported");
5510 break;
5511 }
5512 }
5513
5514 val = get_param(cmd, "DYN_BW_SGNL");
5515 if (val) {
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08005516 switch (get_driver_type()) {
5517 case DRIVER_WCN:
Peng Xuc59afd32016-11-21 15:01:11 -08005518 if (strcasecmp(val, "enable") == 0) {
5519 snprintf(buf, sizeof(buf),
5520 "iwpriv %s cwmenable 1", intf);
5521 if (system(buf) != 0) {
5522 sigma_dut_print(dut, DUT_MSG_ERROR,
5523 "iwpriv cwmenable 1 failed");
5524 return 0;
5525 }
5526 } else if (strcasecmp(val, "disable") == 0) {
5527 snprintf(buf, sizeof(buf),
5528 "iwpriv %s cwmenable 0", intf);
5529 if (system(buf) != 0) {
5530 sigma_dut_print(dut, DUT_MSG_ERROR,
5531 "iwpriv cwmenable 0 failed");
5532 return 0;
5533 }
5534 } else {
5535 sigma_dut_print(dut, DUT_MSG_ERROR,
5536 "Unsupported DYN_BW_SGL");
5537 }
5538
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005539 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 3", intf);
5540 if (system(buf) != 0) {
5541 sigma_dut_print(dut, DUT_MSG_ERROR,
5542 "Failed to set cts_cbw in DYN_BW_SGNL");
5543 return 0;
5544 }
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08005545 break;
5546 case DRIVER_ATHEROS:
priyadharshini gowthamane5e25172015-12-08 14:53:48 -08005547 novap_reset(dut, intf);
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08005548 ath_config_dyn_bw_sig(dut, intf, val);
5549 break;
5550 default:
5551 sigma_dut_print(dut, DUT_MSG_ERROR,
5552 "Failed to set DYN_BW_SGNL");
5553 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005554 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005555 }
5556
5557 val = get_param(cmd, "RTS_FORCE");
5558 if (val) {
priyadharshini gowthamane5e25172015-12-08 14:53:48 -08005559 novap_reset(dut, intf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005560 if (strcasecmp(val, "Enable") == 0) {
Veerendranath Jakkamadcd6202019-04-17 12:32:21 +05305561 if (sta_set_rts(dut, intf, 64) != 0) {
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02005562 sigma_dut_print(dut, DUT_MSG_ERROR,
5563 "Failed to set RTS_FORCE 64");
5564 }
Jouni Malinen3aa72862019-05-29 23:14:51 +03005565 res = snprintf(buf, sizeof(buf),
5566 "wifitool %s beeliner_fw_test 100 1",
5567 intf);
5568 if (res < 0 || res >= sizeof(buf) || system(buf) != 0) {
priyadharshini gowthaman270870e2015-12-09 10:10:23 -08005569 sigma_dut_print(dut, DUT_MSG_ERROR,
5570 "wifitool beeliner_fw_test 100 1 failed");
5571 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005572 } else if (strcasecmp(val, "Disable") == 0) {
Veerendranath Jakkamadcd6202019-04-17 12:32:21 +05305573 if (sta_set_rts(dut, intf, 2347) != 0) {
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02005574 sigma_dut_print(dut, DUT_MSG_ERROR,
5575 "Failed to set RTS_FORCE 2347");
5576 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005577 } else {
5578 send_resp(dut, conn, SIGMA_ERROR,
5579 "ErrorCode,RTS_FORCE value not supported");
5580 return 0;
5581 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005582 }
5583
5584 val = get_param(cmd, "CTS_WIDTH");
5585 if (val) {
5586 switch (get_driver_type()) {
5587 case DRIVER_WCN:
5588 if (wcn_sta_set_cts_width(dut, intf, val) < 0) {
5589 send_resp(dut, conn, SIGMA_ERROR,
5590 "ErrorCode,Failed to set CTS_WIDTH");
5591 return 0;
5592 }
5593 break;
5594 case DRIVER_ATHEROS:
5595 ath_set_cts_width(dut, intf, val);
5596 break;
5597 default:
5598 sigma_dut_print(dut, DUT_MSG_ERROR,
5599 "Setting CTS_WIDTH not supported");
5600 break;
5601 }
5602 }
5603
5604 val = get_param(cmd, "BW_SGNL");
5605 if (val) {
5606 if (strcasecmp(val, "Enable") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005607 run_iwpriv(dut, intf, "cwmenable 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005608 } else if (strcasecmp(val, "Disable") == 0) {
5609 /* TODO: Disable */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005610 } else {
5611 send_resp(dut, conn, SIGMA_ERROR,
5612 "ErrorCode,BW_SGNL value not supported");
5613 return 0;
5614 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005615 }
5616
5617 val = get_param(cmd, "Band");
5618 if (val) {
5619 if (strcmp(val, "2.4") == 0 || strcmp(val, "5") == 0) {
5620 /* STA supports all bands by default */
5621 } else {
5622 send_resp(dut, conn, SIGMA_ERROR,
5623 "ErrorCode,Unsupported Band");
5624 return 0;
5625 }
5626 }
5627
5628 val = get_param(cmd, "zero_crc");
5629 if (val) {
5630 switch (get_driver_type()) {
5631 case DRIVER_ATHEROS:
5632 ath_set_zero_crc(dut, val);
5633 break;
5634 default:
5635 break;
5636 }
5637 }
5638
5639 return 1;
5640}
5641
5642
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02005643static int sta_set_force_mcs(struct sigma_dut *dut, int force, int mcs)
5644{
5645 switch (get_driver_type()) {
5646#ifdef __linux__
5647 case DRIVER_WIL6210:
5648 return wil6210_set_force_mcs(dut, force, mcs);
5649#endif /* __linux__ */
5650 default:
5651 sigma_dut_print(dut, DUT_MSG_ERROR,
5652 "Unsupported sta_set_force_mcs with the current driver");
5653 return -1;
5654 }
5655}
5656
5657
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02005658static int sta_60g_force_rsn_ie(struct sigma_dut *dut, int state)
5659{
5660 switch (get_driver_type()) {
5661#ifdef __linux__
5662 case DRIVER_WIL6210:
5663 return wil6210_force_rsn_ie(dut, state);
5664#endif /* __linux__ */
5665 default:
5666 sigma_dut_print(dut, DUT_MSG_ERROR,
5667 "Unsupported sta_60g_force_rsn_ie with the current driver");
5668 return -1;
5669 }
5670}
5671
5672
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005673static int sta_set_60g_common(struct sigma_dut *dut, struct sigma_conn *conn,
5674 struct sigma_cmd *cmd)
5675{
5676 const char *val;
5677 char buf[100];
5678
5679 val = get_param(cmd, "MSDUSize");
5680 if (val) {
5681 int mtu;
5682
5683 dut->amsdu_size = atoi(val);
5684 if (dut->amsdu_size > IEEE80211_MAX_DATA_LEN_DMG ||
5685 dut->amsdu_size < IEEE80211_SNAP_LEN_DMG) {
5686 sigma_dut_print(dut, DUT_MSG_ERROR,
5687 "MSDUSize %d is above max %d or below min %d",
5688 dut->amsdu_size,
5689 IEEE80211_MAX_DATA_LEN_DMG,
5690 IEEE80211_SNAP_LEN_DMG);
5691 dut->amsdu_size = 0;
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005692 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005693 }
5694
5695 mtu = dut->amsdu_size - IEEE80211_SNAP_LEN_DMG;
5696 sigma_dut_print(dut, DUT_MSG_DEBUG,
5697 "Setting amsdu_size to %d", mtu);
5698 snprintf(buf, sizeof(buf), "ifconfig %s mtu %d",
5699 get_station_ifname(), mtu);
5700
5701 if (system(buf) != 0) {
5702 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
5703 buf);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005704 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005705 }
5706 }
5707
5708 val = get_param(cmd, "BAckRcvBuf");
5709 if (val) {
5710 dut->back_rcv_buf = atoi(val);
5711 if (dut->back_rcv_buf == 0) {
5712 sigma_dut_print(dut, DUT_MSG_ERROR,
5713 "Failed to convert %s or value is 0",
5714 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005715 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005716 }
5717
5718 sigma_dut_print(dut, DUT_MSG_DEBUG,
5719 "Setting BAckRcvBuf to %s", val);
5720 }
5721
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02005722 val = get_param(cmd, "MCS_FixedRate");
5723 if (val) {
5724 if (sta_set_force_mcs(dut, 1, atoi(val))) {
5725 sigma_dut_print(dut, DUT_MSG_ERROR,
5726 "Failed to force MCS");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005727 return ERROR_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02005728 }
5729 }
5730
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005731 return SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005732}
5733
5734
5735static int sta_pcp_start(struct sigma_dut *dut, struct sigma_conn *conn,
5736 struct sigma_cmd *cmd)
5737{
5738 int net_id;
5739 char *ifname;
5740 const char *val;
5741 char buf[100];
5742
5743 dut->mode = SIGMA_MODE_STATION;
5744 ifname = get_main_ifname();
5745 if (wpa_command(ifname, "PING") != 0) {
5746 sigma_dut_print(dut, DUT_MSG_ERROR, "Supplicant not running");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005747 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005748 }
5749
5750 wpa_command(ifname, "FLUSH");
5751 net_id = add_network_common(dut, conn, ifname, cmd);
5752 if (net_id < 0) {
5753 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add network");
5754 return net_id;
5755 }
5756
5757 /* TODO: mode=2 for the AP; in the future, replace for mode PCP */
5758 if (set_network(ifname, net_id, "mode", "2") < 0) {
5759 sigma_dut_print(dut, DUT_MSG_ERROR,
5760 "Failed to set supplicant network mode");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005761 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005762 }
5763
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02005764 if (set_network(ifname, net_id, "pbss", "1") < 0)
5765 return -2;
5766
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005767 sigma_dut_print(dut, DUT_MSG_DEBUG,
Alexei Avshalom Lazarfd9f1352018-11-13 14:07:58 +02005768 "Supplicant set network with mode 2. network_id %d",
5769 net_id);
5770
5771 if (set_network(ifname, net_id, "wps_disabled", "0") < 0) {
5772 sigma_dut_print(dut, DUT_MSG_INFO,
5773 "Failed to set supplicant to WPS ENABLE");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005774 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarfd9f1352018-11-13 14:07:58 +02005775 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005776
5777 val = get_param(cmd, "Security");
5778 if (val && strcasecmp(val, "OPEN") == 0) {
5779 dut->ap_key_mgmt = AP_OPEN;
5780 if (set_network(ifname, net_id, "key_mgmt", "NONE") < 0) {
5781 sigma_dut_print(dut, DUT_MSG_ERROR,
5782 "Failed to set supplicant to %s security",
5783 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005784 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005785 }
5786 } else if (val && strcasecmp(val, "WPA2-PSK") == 0) {
5787 dut->ap_key_mgmt = AP_WPA2_PSK;
5788 if (set_network(ifname, net_id, "key_mgmt", "WPA-PSK") < 0) {
5789 sigma_dut_print(dut, DUT_MSG_ERROR,
5790 "Failed to set supplicant to %s security",
5791 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005792 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005793 }
5794
5795 if (set_network(ifname, net_id, "proto", "RSN") < 0) {
5796 sigma_dut_print(dut, DUT_MSG_ERROR,
5797 "Failed to set supplicant to proto RSN");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005798 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005799 }
5800 } else if (val) {
5801 sigma_dut_print(dut, DUT_MSG_ERROR,
5802 "Requested Security %s is not supported on 60GHz",
5803 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005804 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005805 }
5806
5807 val = get_param(cmd, "Encrypt");
5808 if (val && strcasecmp(val, "AES-GCMP") == 0) {
5809 if (set_network(ifname, net_id, "pairwise", "GCMP") < 0) {
5810 sigma_dut_print(dut, DUT_MSG_ERROR,
5811 "Failed to set supplicant to pairwise GCMP");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005812 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005813 }
5814 if (set_network(ifname, net_id, "group", "GCMP") < 0) {
5815 sigma_dut_print(dut, DUT_MSG_ERROR,
5816 "Failed to set supplicant to group GCMP");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005817 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005818 }
5819 } else if (val) {
5820 sigma_dut_print(dut, DUT_MSG_ERROR,
5821 "Requested Encrypt %s is not supported on 60 GHz",
5822 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005823 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005824 }
5825
5826 val = get_param(cmd, "PSK");
5827 if (val && set_network_quoted(ifname, net_id, "psk", val) < 0) {
5828 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set psk %s",
5829 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005830 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005831 }
5832
5833 /* Convert 60G channel to freq */
5834 switch (dut->ap_channel) {
5835 case 1:
5836 val = "58320";
5837 break;
5838 case 2:
5839 val = "60480";
5840 break;
5841 case 3:
5842 val = "62640";
5843 break;
5844 default:
5845 sigma_dut_print(dut, DUT_MSG_ERROR,
5846 "Failed to configure channel %d. Not supported",
5847 dut->ap_channel);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005848 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005849 }
5850
5851 if (set_network(ifname, net_id, "frequency", val) < 0) {
5852 sigma_dut_print(dut, DUT_MSG_ERROR,
5853 "Failed to set supplicant network frequency");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005854 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005855 }
5856
Alexei Avshalom Lazar2eccf4d2019-01-31 10:03:59 +02005857 if (dut->eap_fragment) {
5858 sigma_dut_print(dut, DUT_MSG_DEBUG,
5859 "Set EAP fragment size to 128 bytes.");
5860 if (set_network(ifname, net_id, "fragment_size", "128") < 0)
5861 return ERROR_SEND_STATUS;
5862 }
5863
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005864 sigma_dut_print(dut, DUT_MSG_DEBUG,
5865 "Supplicant set network with frequency");
5866
5867 snprintf(buf, sizeof(buf), "SELECT_NETWORK %d", net_id);
5868 if (wpa_command(ifname, buf) < 0) {
5869 sigma_dut_print(dut, DUT_MSG_INFO,
5870 "Failed to select network id %d on %s",
5871 net_id, ifname);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005872 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005873 }
5874
5875 sigma_dut_print(dut, DUT_MSG_DEBUG, "Selected network");
5876
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005877 return SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005878}
5879
5880
Lior David67543f52017-01-03 19:04:22 +02005881static int wil6210_set_abft_len(struct sigma_dut *dut, int abft_len)
5882{
5883 char buf[128], fname[128];
5884 FILE *f;
Jouni Malinen3aa72862019-05-29 23:14:51 +03005885 int res;
Lior David67543f52017-01-03 19:04:22 +02005886
5887 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
5888 sigma_dut_print(dut, DUT_MSG_ERROR,
5889 "failed to get wil6210 debugfs dir");
5890 return -1;
5891 }
5892
Jouni Malinen3aa72862019-05-29 23:14:51 +03005893 res = snprintf(fname, sizeof(fname), "%s/abft_len", buf);
5894 if (res < 0 || res >= sizeof(fname))
5895 return -1;
Lior David67543f52017-01-03 19:04:22 +02005896 f = fopen(fname, "w");
5897 if (!f) {
5898 sigma_dut_print(dut, DUT_MSG_ERROR,
5899 "failed to open: %s", fname);
5900 return -1;
5901 }
5902
5903 fprintf(f, "%d\n", abft_len);
5904 fclose(f);
5905
5906 return 0;
5907}
5908
5909
Alexei Avshalom Lazar49498b82019-01-31 15:16:32 +02005910int sta_set_60g_abft_len(struct sigma_dut *dut, struct sigma_conn *conn,
5911 int abft_len)
Lior David67543f52017-01-03 19:04:22 +02005912{
5913 switch (get_driver_type()) {
5914 case DRIVER_WIL6210:
5915 return wil6210_set_abft_len(dut, abft_len);
5916 default:
5917 sigma_dut_print(dut, DUT_MSG_ERROR,
5918 "set abft_len not supported");
5919 return -1;
5920 }
5921}
5922
5923
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005924static int sta_set_60g_pcp(struct sigma_dut *dut, struct sigma_conn *conn,
5925 struct sigma_cmd *cmd)
5926{
5927 const char *val;
Lior David67543f52017-01-03 19:04:22 +02005928 unsigned int abft_len = 1; /* default is one slot */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005929
5930 if (dut->dev_role != DEVROLE_PCP) {
5931 send_resp(dut, conn, SIGMA_INVALID,
5932 "ErrorCode,Invalid DevRole");
5933 return 0;
5934 }
5935
5936 val = get_param(cmd, "SSID");
5937 if (val) {
5938 if (strlen(val) > sizeof(dut->ap_ssid) - 1) {
5939 send_resp(dut, conn, SIGMA_INVALID,
5940 "ErrorCode,Invalid SSID");
5941 return -1;
5942 }
5943
Peng Xub8fc5cc2017-05-10 17:27:28 -07005944 strlcpy(dut->ap_ssid, val, sizeof(dut->ap_ssid));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005945 }
5946
5947 val = get_param(cmd, "CHANNEL");
5948 if (val) {
5949 const char *pos;
5950
5951 dut->ap_channel = atoi(val);
5952 pos = strchr(val, ';');
5953 if (pos) {
5954 pos++;
5955 dut->ap_channel_1 = atoi(pos);
5956 }
5957 }
5958
5959 switch (dut->ap_channel) {
5960 case 1:
5961 case 2:
5962 case 3:
5963 break;
5964 default:
5965 sigma_dut_print(dut, DUT_MSG_ERROR,
5966 "Channel %d is not supported", dut->ap_channel);
5967 send_resp(dut, conn, SIGMA_ERROR,
5968 "Requested channel is not supported");
5969 return -1;
5970 }
5971
5972 val = get_param(cmd, "BCNINT");
5973 if (val)
5974 dut->ap_bcnint = atoi(val);
5975
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005976 val = get_param(cmd, "AllocType");
5977 if (val) {
5978 send_resp(dut, conn, SIGMA_ERROR,
5979 "ErrorCode,AllocType is not supported yet");
5980 return -1;
5981 }
5982
5983 val = get_param(cmd, "PercentBI");
5984 if (val) {
5985 send_resp(dut, conn, SIGMA_ERROR,
5986 "ErrorCode,PercentBI is not supported yet");
5987 return -1;
5988 }
5989
5990 val = get_param(cmd, "CBAPOnly");
5991 if (val) {
5992 send_resp(dut, conn, SIGMA_ERROR,
5993 "ErrorCode,CBAPOnly is not supported yet");
5994 return -1;
5995 }
5996
5997 val = get_param(cmd, "AMPDU");
5998 if (val) {
5999 if (strcasecmp(val, "Enable") == 0)
6000 dut->ap_ampdu = 1;
6001 else if (strcasecmp(val, "Disable") == 0)
6002 dut->ap_ampdu = 2;
6003 else {
6004 send_resp(dut, conn, SIGMA_ERROR,
6005 "ErrorCode,AMPDU value is not Enable nor Disabled");
6006 return -1;
6007 }
6008 }
6009
6010 val = get_param(cmd, "AMSDU");
6011 if (val) {
6012 if (strcasecmp(val, "Enable") == 0)
6013 dut->ap_amsdu = 1;
6014 else if (strcasecmp(val, "Disable") == 0)
6015 dut->ap_amsdu = 2;
6016 }
6017
6018 val = get_param(cmd, "NumMSDU");
6019 if (val) {
6020 send_resp(dut, conn, SIGMA_ERROR,
6021 "ErrorCode, NumMSDU is not supported yet");
6022 return -1;
6023 }
6024
6025 val = get_param(cmd, "ABFTLRang");
6026 if (val) {
6027 sigma_dut_print(dut, DUT_MSG_DEBUG,
Lior David67543f52017-01-03 19:04:22 +02006028 "ABFTLRang parameter %s", val);
6029 if (strcmp(val, "Gt1") == 0)
6030 abft_len = 2; /* 2 slots in this case */
6031 }
6032
6033 if (sta_set_60g_abft_len(dut, conn, abft_len)) {
6034 send_resp(dut, conn, SIGMA_ERROR,
6035 "ErrorCode, Can't set ABFT length");
6036 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006037 }
6038
6039 if (sta_pcp_start(dut, conn, cmd) < 0) {
6040 send_resp(dut, conn, SIGMA_ERROR,
6041 "ErrorCode, Can't start PCP role");
6042 return -1;
6043 }
6044
6045 return sta_set_60g_common(dut, conn, cmd);
6046}
6047
6048
6049static int sta_set_60g_sta(struct sigma_dut *dut, struct sigma_conn *conn,
6050 struct sigma_cmd *cmd)
6051{
6052 const char *val = get_param(cmd, "DiscoveryMode");
6053
6054 if (dut->dev_role != DEVROLE_STA) {
6055 send_resp(dut, conn, SIGMA_INVALID,
6056 "ErrorCode,Invalid DevRole");
6057 return 0;
6058 }
6059
6060 if (val) {
6061 sigma_dut_print(dut, DUT_MSG_DEBUG, "Discovery: %s", val);
6062 /* Ignore Discovery mode till Driver expose API. */
6063#if 0
6064 if (strcasecmp(val, "1") == 0) {
6065 send_resp(dut, conn, SIGMA_INVALID,
6066 "ErrorCode,DiscoveryMode 1 not supported");
6067 return 0;
6068 }
6069
6070 if (strcasecmp(val, "0") == 0) {
6071 /* OK */
6072 } else {
6073 send_resp(dut, conn, SIGMA_INVALID,
6074 "ErrorCode,DiscoveryMode not supported");
6075 return 0;
6076 }
6077#endif
6078 }
6079
6080 if (start_sta_mode(dut) != 0)
Jouni Malinen0e29cf22019-02-19 01:13:21 +02006081 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006082 return sta_set_60g_common(dut, conn, cmd);
6083}
6084
6085
Jouni Malinenf7222712019-06-13 01:50:21 +03006086static enum sigma_cmd_result cmd_sta_disconnect(struct sigma_dut *dut,
6087 struct sigma_conn *conn,
6088 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006089{
6090 const char *intf = get_param(cmd, "Interface");
Jouni Malinened77e672018-01-10 16:45:13 +02006091 const char *val = get_param(cmd, "maintain_profile");
vamsi krishnad605c422017-09-20 14:56:31 +05306092
Jouni Malinened77e672018-01-10 16:45:13 +02006093 if (dut->program == PROGRAM_OCE ||
Amarnath Hullur Subramanyamebeda9e2018-01-31 03:21:48 -08006094 dut->program == PROGRAM_HE ||
Jouni Malinened77e672018-01-10 16:45:13 +02006095 (val && atoi(val) == 1)) {
vamsi krishnad605c422017-09-20 14:56:31 +05306096 wpa_command(intf, "DISCONNECT");
6097 return 1;
6098 }
6099
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006100 disconnect_station(dut);
6101 /* Try to ignore old scan results to avoid HS 2.0R2 test case failures
6102 * due to cached results. */
6103 wpa_command(intf, "SET ignore_old_scan_res 1");
6104 wpa_command(intf, "BSS_FLUSH");
6105 return 1;
6106}
6107
6108
Jouni Malinenf7222712019-06-13 01:50:21 +03006109static enum sigma_cmd_result cmd_sta_reassoc(struct sigma_dut *dut,
6110 struct sigma_conn *conn,
6111 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006112{
6113 const char *intf = get_param(cmd, "Interface");
6114 const char *bssid = get_param(cmd, "bssid");
6115 const char *val = get_param(cmd, "CHANNEL");
6116 struct wpa_ctrl *ctrl;
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05306117 char buf[1000];
Sunil Duttd30ce092018-01-11 23:56:29 +05306118 char result[32];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006119 int res;
6120 int chan = 0;
Ashwini Patil467efef2017-05-25 12:18:27 +05306121 int status = 0;
Sunil Duttd30ce092018-01-11 23:56:29 +05306122 int fastreassoc = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006123
6124 if (bssid == NULL) {
6125 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing bssid "
6126 "argument");
6127 return 0;
6128 }
6129
6130 if (val)
6131 chan = atoi(val);
6132
6133 if (wifi_chip_type != DRIVER_WCN && wifi_chip_type != DRIVER_AR6003) {
6134 /* The current network may be from sta_associate or
6135 * sta_hs2_associate
6136 */
6137 if (set_network(intf, dut->infra_network_id, "bssid", bssid) <
6138 0 ||
6139 set_network(intf, 0, "bssid", bssid) < 0)
6140 return -2;
6141 }
6142
6143 ctrl = open_wpa_mon(intf);
6144 if (ctrl == NULL) {
6145 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
6146 "wpa_supplicant monitor connection");
6147 return -1;
6148 }
6149
Sunil Duttd30ce092018-01-11 23:56:29 +05306150 if (get_wpa_status(get_station_ifname(), "wpa_state", result,
6151 sizeof(result)) < 0 ||
6152 strncmp(result, "COMPLETED", 9) != 0) {
6153 sigma_dut_print(dut, DUT_MSG_DEBUG,
6154 "sta_reassoc: Not connected");
6155 fastreassoc = 0;
6156 }
6157
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05306158 if (dut->rsne_override) {
6159#ifdef NL80211_SUPPORT
6160 if (get_driver_type() == DRIVER_WCN && dut->config_rsnie == 0) {
6161 sta_config_rsnie(dut, 1);
6162 dut->config_rsnie = 1;
6163 }
6164#endif /* NL80211_SUPPORT */
6165 snprintf(buf, sizeof(buf), "TEST_ASSOC_IE %s",
6166 dut->rsne_override);
6167 if (wpa_command(intf, buf) < 0) {
6168 send_resp(dut, conn, SIGMA_ERROR,
6169 "ErrorCode,Failed to set DEV_CONFIGURE_IE RSNE override");
6170 return 0;
6171 }
6172 }
6173
Sunil Duttd30ce092018-01-11 23:56:29 +05306174 if (wifi_chip_type == DRIVER_WCN && fastreassoc) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006175#ifdef ANDROID
Ashwini Patil4c8158f2017-05-25 12:49:21 +05306176 if (chan) {
6177 unsigned int freq;
6178
Alexei Avshalom Lazar093569f2018-11-13 14:08:17 +02006179 freq = channel_to_freq(dut, chan);
Ashwini Patil4c8158f2017-05-25 12:49:21 +05306180 if (!freq) {
6181 sigma_dut_print(dut, DUT_MSG_ERROR,
6182 "Invalid channel number provided: %d",
6183 chan);
6184 send_resp(dut, conn, SIGMA_INVALID,
6185 "ErrorCode,Invalid channel number");
6186 goto close_mon_conn;
6187 }
6188 res = snprintf(buf, sizeof(buf),
6189 "SCAN TYPE=ONLY freq=%d", freq);
6190 } else {
6191 res = snprintf(buf, sizeof(buf), "SCAN TYPE=ONLY");
6192 }
6193 if (res < 0 || res >= (int) sizeof(buf)) {
6194 send_resp(dut, conn, SIGMA_ERROR,
6195 "ErrorCode,snprintf failed");
6196 goto close_mon_conn;
6197 }
6198 if (wpa_command(intf, buf) < 0) {
6199 sigma_dut_print(dut, DUT_MSG_INFO,
6200 "Failed to start scan");
6201 send_resp(dut, conn, SIGMA_ERROR,
6202 "ErrorCode,scan failed");
6203 goto close_mon_conn;
6204 }
6205
6206 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
6207 buf, sizeof(buf));
6208 if (res < 0) {
6209 sigma_dut_print(dut, DUT_MSG_INFO,
6210 "Scan did not complete");
6211 send_resp(dut, conn, SIGMA_ERROR,
6212 "ErrorCode,scan did not complete");
6213 goto close_mon_conn;
6214 }
6215
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006216 if (set_network(intf, dut->infra_network_id, "bssid", "any")
6217 < 0) {
6218 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
6219 "bssid to any during FASTREASSOC");
Ashwini Patil467efef2017-05-25 12:18:27 +05306220 status = -2;
6221 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006222 }
6223 res = snprintf(buf, sizeof(buf), "DRIVER FASTREASSOC %s %d",
6224 bssid, chan);
6225 if (res > 0 && res < (int) sizeof(buf))
6226 res = wpa_command(intf, buf);
6227
6228 if (res < 0 || res >= (int) sizeof(buf)) {
6229 send_resp(dut, conn, SIGMA_ERROR,
6230 "errorCode,Failed to run DRIVER FASTREASSOC");
Ashwini Patil467efef2017-05-25 12:18:27 +05306231 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006232 }
6233#else /* ANDROID */
6234 sigma_dut_print(dut, DUT_MSG_DEBUG,
6235 "Reassoc using iwpriv - skip chan=%d info",
6236 chan);
6237 snprintf(buf, sizeof(buf), "iwpriv %s reassoc", intf);
6238 if (system(buf) != 0) {
6239 sigma_dut_print(dut, DUT_MSG_ERROR, "%s failed", buf);
Ashwini Patil467efef2017-05-25 12:18:27 +05306240 status = -2;
6241 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006242 }
6243#endif /* ANDROID */
6244 sigma_dut_print(dut, DUT_MSG_INFO,
6245 "sta_reassoc: Run %s successful", buf);
6246 } else if (wpa_command(intf, "REASSOCIATE")) {
6247 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
6248 "request reassociation");
Ashwini Patil467efef2017-05-25 12:18:27 +05306249 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006250 }
6251
6252 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
6253 buf, sizeof(buf));
Ashwini Patil467efef2017-05-25 12:18:27 +05306254 if (res < 0) {
6255 sigma_dut_print(dut, DUT_MSG_INFO, "Connection did not complete");
6256 status = -1;
6257 goto close_mon_conn;
6258 }
6259 status = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006260
Ashwini Patil467efef2017-05-25 12:18:27 +05306261close_mon_conn:
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006262 wpa_ctrl_detach(ctrl);
6263 wpa_ctrl_close(ctrl);
Ashwini Patil467efef2017-05-25 12:18:27 +05306264 return status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006265}
6266
6267
6268static void hs2_clear_credentials(const char *intf)
6269{
6270 wpa_command(intf, "REMOVE_CRED all");
6271}
6272
6273
Lior Davidcc88b562017-01-03 18:52:09 +02006274#ifdef __linux__
6275static int wil6210_get_aid(struct sigma_dut *dut, const char *bssid,
6276 unsigned int *aid)
6277{
Lior David0fe101e2017-03-09 16:09:50 +02006278 const char *pattern = "AID[ \t]+([0-9]+)";
Lior Davidcc88b562017-01-03 18:52:09 +02006279
Lior David0fe101e2017-03-09 16:09:50 +02006280 return wil6210_get_sta_info_field(dut, bssid, pattern, aid);
Lior Davidcc88b562017-01-03 18:52:09 +02006281}
6282#endif /* __linux__ */
6283
6284
6285static int sta_get_aid_60g(struct sigma_dut *dut, const char *bssid,
6286 unsigned int *aid)
6287{
6288 switch (get_driver_type()) {
6289#ifdef __linux__
6290 case DRIVER_WIL6210:
6291 return wil6210_get_aid(dut, bssid, aid);
6292#endif /* __linux__ */
6293 default:
6294 sigma_dut_print(dut, DUT_MSG_ERROR, "get AID not supported");
6295 return -1;
6296 }
6297}
6298
6299
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006300static int sta_get_parameter_60g(struct sigma_dut *dut, struct sigma_conn *conn,
6301 struct sigma_cmd *cmd)
6302{
6303 char buf[MAX_CMD_LEN];
6304 char bss_list[MAX_CMD_LEN];
6305 const char *parameter = get_param(cmd, "Parameter");
6306
6307 if (parameter == NULL)
6308 return -1;
6309
Lior Davidcc88b562017-01-03 18:52:09 +02006310 if (strcasecmp(parameter, "AID") == 0) {
6311 unsigned int aid = 0;
6312 char bssid[20];
6313
6314 if (get_wpa_status(get_station_ifname(), "bssid",
6315 bssid, sizeof(bssid)) < 0) {
6316 sigma_dut_print(dut, DUT_MSG_ERROR,
6317 "could not get bssid");
6318 return -2;
6319 }
6320
6321 if (sta_get_aid_60g(dut, bssid, &aid))
6322 return -2;
6323
6324 snprintf(buf, sizeof(buf), "aid,%d", aid);
6325 sigma_dut_print(dut, DUT_MSG_INFO, "%s", buf);
6326 send_resp(dut, conn, SIGMA_COMPLETE, buf);
6327 return 0;
6328 }
6329
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006330 if (strcasecmp(parameter, "DiscoveredDevList") == 0) {
6331 char *bss_line;
6332 char *bss_id = NULL;
6333 const char *ifname = get_param(cmd, "Interface");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05306334 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006335
6336 if (ifname == NULL) {
6337 sigma_dut_print(dut, DUT_MSG_INFO,
6338 "For get DiscoveredDevList need Interface name.");
6339 return -1;
6340 }
6341
6342 /*
6343 * Use "BSS RANGE=ALL MASK=0x2" which provides a list
6344 * of BSSIDs in "bssid=<BSSID>\n"
6345 */
6346 if (wpa_command_resp(ifname, "BSS RANGE=ALL MASK=0x2",
6347 bss_list,
6348 sizeof(bss_list)) < 0) {
6349 sigma_dut_print(dut, DUT_MSG_ERROR,
6350 "Failed to get bss list");
6351 return -1;
6352 }
6353
6354 sigma_dut_print(dut, DUT_MSG_DEBUG,
6355 "bss list for ifname:%s is:%s",
6356 ifname, bss_list);
6357
6358 snprintf(buf, sizeof(buf), "DeviceList");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05306359 bss_line = strtok_r(bss_list, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006360 while (bss_line) {
6361 if (sscanf(bss_line, "bssid=%ms", &bss_id) > 0 &&
6362 bss_id) {
6363 int len;
6364
6365 len = snprintf(buf + strlen(buf),
6366 sizeof(buf) - strlen(buf),
6367 ",%s", bss_id);
6368 free(bss_id);
6369 bss_id = NULL;
6370 if (len < 0) {
6371 sigma_dut_print(dut,
6372 DUT_MSG_ERROR,
6373 "Failed to read BSSID");
6374 send_resp(dut, conn, SIGMA_ERROR,
6375 "ErrorCode,Failed to read BSS ID");
6376 return 0;
6377 }
6378
6379 if ((size_t) len >= sizeof(buf) - strlen(buf)) {
6380 sigma_dut_print(dut,
6381 DUT_MSG_ERROR,
6382 "Response buf too small for list");
6383 send_resp(dut, conn,
6384 SIGMA_ERROR,
6385 "ErrorCode,Response buf too small for list");
6386 return 0;
6387 }
6388 }
6389
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05306390 bss_line = strtok_r(NULL, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006391 }
6392
6393 sigma_dut_print(dut, DUT_MSG_INFO, "DiscoveredDevList is %s",
6394 buf);
6395 send_resp(dut, conn, SIGMA_COMPLETE, buf);
6396 return 0;
6397 }
6398
6399 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
6400 return 0;
6401}
6402
6403
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07006404static int sta_get_parameter_he(struct sigma_dut *dut, struct sigma_conn *conn,
6405 struct sigma_cmd *cmd)
6406{
6407 char buf[MAX_CMD_LEN];
6408 const char *parameter = get_param(cmd, "Parameter");
6409
6410 if (!parameter)
6411 return -1;
6412
6413 if (strcasecmp(parameter, "RSSI") == 0) {
6414 char rssi[10];
6415
6416 if (get_wpa_signal_poll(dut, get_station_ifname(), "RSSI",
6417 rssi, sizeof(rssi)) < 0) {
6418 sigma_dut_print(dut, DUT_MSG_ERROR,
6419 "Could not get RSSI");
6420 return -2;
6421 }
6422
6423 snprintf(buf, sizeof(buf), "rssi,%s", rssi);
6424 sigma_dut_print(dut, DUT_MSG_INFO, "RSSI %s", buf);
6425 send_resp(dut, conn, SIGMA_COMPLETE, buf);
6426 return 0;
6427 }
6428
6429 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
6430 return 0;
6431}
6432
6433
Jouni Malinenf7222712019-06-13 01:50:21 +03006434static enum sigma_cmd_result cmd_sta_get_parameter(struct sigma_dut *dut,
6435 struct sigma_conn *conn,
6436 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006437{
6438 const char *program = get_param(cmd, "Program");
6439
6440 if (program == NULL)
6441 return -1;
6442
6443 if (strcasecmp(program, "P2PNFC") == 0)
6444 return p2p_cmd_sta_get_parameter(dut, conn, cmd);
6445
6446 if (strcasecmp(program, "60ghz") == 0)
6447 return sta_get_parameter_60g(dut, conn, cmd);
6448
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07006449 if (strcasecmp(program, "he") == 0)
6450 return sta_get_parameter_he(dut, conn, cmd);
6451
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006452#ifdef ANDROID_NAN
6453 if (strcasecmp(program, "NAN") == 0)
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07006454 return nan_cmd_sta_get_parameter(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006455#endif /* ANDROID_NAN */
6456
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07006457#ifdef MIRACAST
6458 if (strcasecmp(program, "WFD") == 0 ||
6459 strcasecmp(program, "DisplayR2") == 0)
6460 return miracast_cmd_sta_get_parameter(dut, conn, cmd);
6461#endif /* MIRACAST */
6462
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006463 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
6464 return 0;
6465}
6466
6467
6468static void sta_reset_default_ath(struct sigma_dut *dut, const char *intf,
6469 const char *type)
6470{
6471 char buf[100];
6472
6473 if (dut->program == PROGRAM_VHT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006474 run_iwpriv(dut, intf, "chwidth 2");
6475 run_iwpriv(dut, intf, "mode 11ACVHT80");
6476 run_iwpriv(dut, intf, "vhtmcs -1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006477 }
6478
6479 if (dut->program == PROGRAM_HT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006480 run_iwpriv(dut, intf, "chwidth 0");
6481 run_iwpriv(dut, intf, "mode 11naht40");
6482 run_iwpriv(dut, intf, "set11NRates 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006483 }
6484
6485 if (dut->program == PROGRAM_VHT || dut->program == PROGRAM_HT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006486 run_iwpriv(dut, intf, "powersave 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006487
6488 /* Reset CTS width */
6489 snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 54 0",
6490 intf);
6491 if (system(buf) != 0) {
6492 sigma_dut_print(dut, DUT_MSG_ERROR,
6493 "wifitool %s beeliner_fw_test 54 0 failed",
6494 intf);
6495 }
6496
6497 /* Enable Dynamic Bandwidth signalling by default */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006498 run_iwpriv(dut, intf, "cwmenable 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006499
6500 snprintf(buf, sizeof(buf), "iwconfig %s rts 2347", intf);
6501 if (system(buf) != 0) {
6502 sigma_dut_print(dut, DUT_MSG_ERROR,
6503 "iwpriv rts failed");
6504 }
6505 }
6506
6507 if (type && strcasecmp(type, "Testbed") == 0) {
6508 dut->testbed_flag_txsp = 1;
6509 dut->testbed_flag_rxsp = 1;
6510 /* STA has to set spatial stream to 2 per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006511 run_iwpriv(dut, intf, "vht_mcsmap 0xfff0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006512
6513 /* Disable LDPC per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006514 run_iwpriv(dut, intf, "ldpc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006515
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006516 run_iwpriv(dut, intf, "amsdu 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006517
6518 /* TODO: Disable STBC 2x1 transmit and receive */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006519 run_iwpriv(dut, intf, "tx_stbc 0");
6520 run_iwpriv(dut, intf, "rx_stbc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006521
6522 /* STA has to disable Short GI per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006523 run_iwpriv(dut, intf, "shortgi 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006524 }
6525
6526 if (type && strcasecmp(type, "DUT") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006527 run_iwpriv(dut, intf, "nss 3");
Arif Hussainac6c5112018-05-25 17:34:00 -07006528 dut->sta_nss = 3;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006529
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006530 run_iwpriv(dut, intf, "shortgi 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006531 }
6532}
6533
6534
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08006535#ifdef NL80211_SUPPORT
6536static int sta_set_he_mcs(struct sigma_dut *dut, const char *intf,
6537 enum he_mcs_config mcs)
6538{
6539 struct nl_msg *msg;
6540 int ret = 0;
6541 struct nlattr *params;
6542 int ifindex;
6543
6544 ifindex = if_nametoindex(intf);
6545 if (ifindex == 0) {
6546 sigma_dut_print(dut, DUT_MSG_ERROR,
6547 "%s: Index for interface %s failed",
6548 __func__, intf);
6549 return -1;
6550 }
6551
6552 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6553 NL80211_CMD_VENDOR)) ||
6554 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6555 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6556 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6557 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6558 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6559 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MCS,
6560 mcs)) {
6561 sigma_dut_print(dut, DUT_MSG_ERROR,
6562 "%s: err in adding vendor_cmd and vendor_data",
6563 __func__);
6564 nlmsg_free(msg);
6565 return -1;
6566 }
6567 nla_nest_end(msg, params);
6568
6569 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6570 if (ret) {
6571 sigma_dut_print(dut, DUT_MSG_ERROR,
6572 "%s: err in send_and_recv_msgs, ret=%d",
6573 __func__, ret);
6574 }
6575 return ret;
6576}
6577#endif /* NL80211_SUPPORT */
6578
6579
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07006580static int sta_set_action_tx_in_he_tb_ppdu(struct sigma_dut *dut,
6581 const char *intf, int enable)
6582{
6583#ifdef NL80211_SUPPORT
6584 struct nl_msg *msg;
6585 int ret = 0;
6586 struct nlattr *params;
6587 int ifindex;
6588
6589 ifindex = if_nametoindex(intf);
6590 if (ifindex == 0) {
6591 sigma_dut_print(dut, DUT_MSG_ERROR,
6592 "%s: Index for interface %s failed",
6593 __func__, intf);
6594 return -1;
6595 }
6596
6597 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6598 NL80211_CMD_VENDOR)) ||
6599 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6600 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6601 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6602 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6603 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6604 nla_put_u8(msg,
6605 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_ACTION_TX_TB_PPDU,
6606 enable)) {
6607 sigma_dut_print(dut, DUT_MSG_ERROR,
6608 "%s: err in adding vendor_cmd and vendor_data",
6609 __func__);
6610 nlmsg_free(msg);
6611 return -1;
6612 }
6613 nla_nest_end(msg, params);
6614
6615 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6616 if (ret) {
6617 sigma_dut_print(dut, DUT_MSG_ERROR,
6618 "%s: err in send_and_recv_msgs, ret=%d",
6619 __func__, ret);
6620 }
6621 return ret;
6622#else /* NL80211_SUPPORT */
6623 sigma_dut_print(dut, DUT_MSG_ERROR,
6624 "HE action Tx TB PPDU cannot be set without NL80211_SUPPORT defined");
6625 return -1;
6626#endif /* NL80211_SUPPORT */
6627}
6628
6629
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08006630static int sta_set_heconfig_and_wep_tkip(struct sigma_dut *dut,
6631 const char *intf, int enable)
6632{
6633#ifdef NL80211_SUPPORT
6634 struct nl_msg *msg;
6635 int ret = 0;
6636 struct nlattr *params;
6637 int ifindex;
6638
6639 ifindex = if_nametoindex(intf);
6640 if (ifindex == 0) {
6641 sigma_dut_print(dut, DUT_MSG_ERROR,
6642 "%s: Index for interface %s failed",
6643 __func__, intf);
6644 return -1;
6645 }
6646
6647 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6648 NL80211_CMD_VENDOR)) ||
6649 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6650 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6651 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6652 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6653 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6654 nla_put_u8(msg,
6655 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WEP_TKIP_IN_HE,
6656 enable)) {
6657 sigma_dut_print(dut, DUT_MSG_ERROR,
6658 "%s: err in adding vendor_cmd and vendor_data",
6659 __func__);
6660 nlmsg_free(msg);
6661 return -1;
6662 }
6663 nla_nest_end(msg, params);
6664
6665 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6666 if (ret) {
6667 sigma_dut_print(dut, DUT_MSG_ERROR,
6668 "%s: err in send_and_recv_msgs, ret=%d",
6669 __func__, ret);
6670 }
6671 return ret;
6672#else /* NL80211_SUPPORT */
6673 sigma_dut_print(dut, DUT_MSG_ERROR,
6674 "HE config enablement cannot be changed without NL80211_SUPPORT defined");
6675 return -1;
6676#endif /* NL80211_SUPPORT */
6677}
6678
6679
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08006680#ifdef NL80211_SUPPORT
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08006681
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08006682static int sta_set_he_testbed_def(struct sigma_dut *dut,
6683 const char *intf, int cfg)
6684{
6685 struct nl_msg *msg;
6686 int ret = 0;
6687 struct nlattr *params;
6688 int ifindex;
6689
6690 ifindex = if_nametoindex(intf);
6691 if (ifindex == 0) {
6692 sigma_dut_print(dut, DUT_MSG_ERROR,
6693 "%s: Index for interface %s failed",
6694 __func__, intf);
6695 return -1;
6696 }
6697
6698 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6699 NL80211_CMD_VENDOR)) ||
6700 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6701 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6702 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6703 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6704 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6705 nla_put_u8(msg,
6706 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_SET_HE_TESTBED_DEFAULTS,
6707 cfg)) {
6708 sigma_dut_print(dut, DUT_MSG_ERROR,
6709 "%s: err in adding vendor_cmd and vendor_data",
6710 __func__);
6711 nlmsg_free(msg);
6712 return -1;
6713 }
6714 nla_nest_end(msg, params);
6715
6716 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6717 if (ret) {
6718 sigma_dut_print(dut, DUT_MSG_ERROR,
6719 "%s: err in send_and_recv_msgs, ret=%d",
6720 __func__, ret);
6721 }
6722 return ret;
6723}
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08006724
6725
6726static int sta_set_2g_vht_supp(struct sigma_dut *dut, const char *intf, int cfg)
6727{
6728 struct nl_msg *msg;
6729 int ret = 0;
6730 struct nlattr *params;
6731 int ifindex;
6732
6733 ifindex = if_nametoindex(intf);
6734 if (ifindex == 0) {
6735 sigma_dut_print(dut, DUT_MSG_ERROR,
6736 "%s: Index for interface %s failed",
6737 __func__, intf);
6738 return -1;
6739 }
6740
6741 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6742 NL80211_CMD_VENDOR)) ||
6743 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6744 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6745 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6746 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6747 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6748 nla_put_u8(msg,
6749 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_2G_VHT,
6750 cfg)) {
6751 sigma_dut_print(dut, DUT_MSG_ERROR,
6752 "%s: err in adding vendor_cmd and vendor_data",
6753 __func__);
6754 nlmsg_free(msg);
6755 return -1;
6756 }
6757 nla_nest_end(msg, params);
6758
6759 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6760 if (ret) {
6761 sigma_dut_print(dut, DUT_MSG_ERROR,
6762 "%s: err in send_and_recv_msgs, ret=%d",
6763 __func__, ret);
6764 }
6765 return ret;
6766}
6767
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08006768#endif /* NL80211_SUPPORT */
6769
6770
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08006771static int sta_set_addba_buf_size(struct sigma_dut *dut,
6772 const char *intf, int bufsize)
6773{
6774#ifdef NL80211_SUPPORT
6775 struct nl_msg *msg;
6776 int ret = 0;
6777 struct nlattr *params;
6778 int ifindex;
6779
6780 ifindex = if_nametoindex(intf);
6781 if (ifindex == 0) {
6782 sigma_dut_print(dut, DUT_MSG_ERROR,
6783 "%s: Index for interface %s failed",
6784 __func__, intf);
6785 return -1;
6786 }
6787
6788 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6789 NL80211_CMD_VENDOR)) ||
6790 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6791 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6792 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6793 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6794 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
Kiran Kumar Lokere26e27582018-08-01 16:18:34 -07006795 nla_put_u16(msg,
6796 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE,
6797 bufsize)) {
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08006798 sigma_dut_print(dut, DUT_MSG_ERROR,
6799 "%s: err in adding vendor_cmd and vendor_data",
6800 __func__);
6801 nlmsg_free(msg);
6802 return -1;
6803 }
6804 nla_nest_end(msg, params);
6805
6806 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6807 if (ret) {
6808 sigma_dut_print(dut, DUT_MSG_ERROR,
6809 "%s: err in send_and_recv_msgs, ret=%d",
6810 __func__, ret);
6811 }
6812 return ret;
6813#else /* NL80211_SUPPORT */
6814 sigma_dut_print(dut, DUT_MSG_ERROR,
6815 "AddBA bufsize cannot be changed without NL80211_SUPPORT defined");
6816 return -1;
6817#endif /* NL80211_SUPPORT */
6818}
6819
6820
Arif Hussain8d5b27b2018-05-14 14:31:03 -07006821static int sta_set_tx_beamformee(struct sigma_dut *dut, const char *intf,
6822 int enable)
6823{
6824#ifdef NL80211_SUPPORT
6825 struct nl_msg *msg;
6826 int ret = 0;
6827 struct nlattr *params;
6828 int ifindex;
6829
6830 ifindex = if_nametoindex(intf);
6831 if (ifindex == 0) {
6832 sigma_dut_print(dut, DUT_MSG_ERROR,
6833 "%s: Index for interface %s failed",
6834 __func__, intf);
6835 return -1;
6836 }
6837
6838 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6839 NL80211_CMD_VENDOR)) ||
6840 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6841 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6842 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6843 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6844 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6845 nla_put_u8(msg,
6846 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_TX_BEAMFORMEE,
6847 enable)) {
6848 sigma_dut_print(dut, DUT_MSG_ERROR,
6849 "%s: err in adding vendor_cmd and vendor_data",
6850 __func__);
6851 nlmsg_free(msg);
6852 return -1;
6853 }
6854 nla_nest_end(msg, params);
6855
6856 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6857 if (ret) {
6858 sigma_dut_print(dut, DUT_MSG_ERROR,
6859 "%s: err in send_and_recv_msgs, ret=%d",
6860 __func__, ret);
6861 }
6862 return ret;
6863#else /* NL80211_SUPPORT */
6864 sigma_dut_print(dut, DUT_MSG_ERROR,
6865 "tx beamformee cannot be changed without NL80211_SUPPORT defined");
6866 return -1;
6867#endif /* NL80211_SUPPORT */
6868}
6869
6870
Arif Hussain9765f7d2018-07-03 08:28:26 -07006871static int sta_set_beamformee_sts(struct sigma_dut *dut, const char *intf,
6872 int val)
6873{
6874#ifdef NL80211_SUPPORT
6875 struct nl_msg *msg;
6876 int ret = 0;
6877 struct nlattr *params;
6878 int ifindex;
6879
6880 ifindex = if_nametoindex(intf);
6881 if (ifindex == 0) {
6882 sigma_dut_print(dut, DUT_MSG_ERROR,
6883 "%s: Index for interface %s failed, val:%d",
6884 __func__, intf, val);
6885 return -1;
6886 }
6887
6888 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6889 NL80211_CMD_VENDOR)) ||
6890 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6891 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6892 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6893 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6894 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6895 nla_put_u8(msg,
6896 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_BEAMFORMEE_NSTS,
6897 val)) {
6898 sigma_dut_print(dut, DUT_MSG_ERROR,
6899 "%s: err in adding vendor_cmd and vendor_data, val: %d",
6900 __func__, val);
6901 nlmsg_free(msg);
6902 return -1;
6903 }
6904 nla_nest_end(msg, params);
6905
6906 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6907 if (ret) {
6908 sigma_dut_print(dut, DUT_MSG_ERROR,
6909 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
6910 __func__, ret, val);
6911 }
6912 return ret;
6913#else /* NL80211_SUPPORT */
6914 sigma_dut_print(dut, DUT_MSG_ERROR,
6915 "beamformee sts cannot be changed without NL80211_SUPPORT defined");
6916 return -1;
6917#endif /* NL80211_SUPPORT */
6918}
6919
6920
Arif Hussain68d23f52018-07-11 13:39:08 -07006921#ifdef NL80211_SUPPORT
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07006922static int sta_set_mac_padding_duration(struct sigma_dut *dut, const char *intf,
6923 enum qca_wlan_he_mac_padding_dur val)
6924{
Arif Hussain68d23f52018-07-11 13:39:08 -07006925 struct nl_msg *msg;
6926 int ret = 0;
6927 struct nlattr *params;
6928 int ifindex;
6929
6930 ifindex = if_nametoindex(intf);
6931 if (ifindex == 0) {
6932 sigma_dut_print(dut, DUT_MSG_ERROR,
6933 "%s: Index for interface %s failed, val:%d",
6934 __func__, intf, val);
6935 return -1;
6936 }
6937
6938 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6939 NL80211_CMD_VENDOR)) ||
6940 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6941 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6942 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6943 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6944 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6945 nla_put_u8(msg,
6946 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MAC_PADDING_DUR,
6947 val)) {
6948 sigma_dut_print(dut, DUT_MSG_ERROR,
6949 "%s: err in adding vendor_cmd and vendor_data, val: %d",
6950 __func__, val);
6951 nlmsg_free(msg);
6952 return -1;
6953 }
6954 nla_nest_end(msg, params);
6955
6956 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6957 if (ret) {
6958 sigma_dut_print(dut, DUT_MSG_ERROR,
6959 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
6960 __func__, ret, val);
6961 }
6962 return ret;
Arif Hussain68d23f52018-07-11 13:39:08 -07006963}
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07006964#endif /* NL80211_SUPPORT */
Arif Hussain68d23f52018-07-11 13:39:08 -07006965
6966
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07006967static int sta_set_tx_su_ppdu_cfg(struct sigma_dut *dut, const char *intf,
6968 int val)
6969{
6970#ifdef NL80211_SUPPORT
6971 struct nl_msg *msg;
6972 int ret = 0;
6973 struct nlattr *params;
6974 int ifindex;
6975
6976 ifindex = if_nametoindex(intf);
6977 if (ifindex == 0) {
6978 sigma_dut_print(dut, DUT_MSG_ERROR,
6979 "%s: Index for interface %s failed, val:%d",
6980 __func__, intf, val);
6981 return -1;
6982 }
6983
6984 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6985 NL80211_CMD_VENDOR)) ||
6986 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6987 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6988 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6989 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6990 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6991 nla_put_u8(msg,
6992 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_SUPPDU,
6993 val)) {
6994 sigma_dut_print(dut, DUT_MSG_ERROR,
6995 "%s: err in adding vendor_cmd and vendor_data, val: %d",
6996 __func__, val);
6997 nlmsg_free(msg);
6998 return -1;
6999 }
7000 nla_nest_end(msg, params);
7001
7002 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7003 if (ret) {
7004 sigma_dut_print(dut, DUT_MSG_ERROR,
7005 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
7006 __func__, ret, val);
7007 }
7008 return ret;
7009#else /* NL80211_SUPPORT */
7010 sigma_dut_print(dut, DUT_MSG_ERROR,
7011 "Tx SU PPDU cannot be set without NL80211_SUPPORT defined");
7012 return -1;
7013#endif /* NL80211_SUPPORT */
7014}
7015
7016
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07007017#ifdef NL80211_SUPPORT
7018static int sta_set_he_om_ctrl_reset(struct sigma_dut *dut, const char *intf)
7019{
7020 struct nl_msg *msg;
7021 int ret = 0;
7022 struct nlattr *params;
7023 int ifindex;
7024
7025 ifindex = if_nametoindex(intf);
7026 if (ifindex == 0) {
7027 sigma_dut_print(dut, DUT_MSG_ERROR,
7028 "%s: Index for interface %s failed",
7029 __func__, intf);
7030 return -1;
7031 }
7032
7033 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7034 NL80211_CMD_VENDOR)) ||
7035 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7036 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7037 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7038 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7039 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7040 nla_put_flag(msg,
7041 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_CLEAR_HE_OM_CTRL_CONFIG)) {
7042 sigma_dut_print(dut, DUT_MSG_ERROR,
7043 "%s: err in adding vendor_cmd and vendor_data",
7044 __func__);
7045 nlmsg_free(msg);
7046 return -1;
7047 }
7048 nla_nest_end(msg, params);
7049
7050 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7051 if (ret) {
7052 sigma_dut_print(dut, DUT_MSG_ERROR,
7053 "%s: err in send_and_recv_msgs, ret=%d",
7054 __func__, ret);
7055 }
7056 return ret;
7057}
7058#endif /* NL80211_SUPPORT */
7059
7060
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07007061static int sta_set_mu_edca_override(struct sigma_dut *dut, const char *intf,
7062 int val)
7063{
7064#ifdef NL80211_SUPPORT
7065 struct nl_msg *msg;
7066 int ret = 0;
7067 struct nlattr *params;
7068 int ifindex;
7069
7070 ifindex = if_nametoindex(intf);
7071 if (ifindex == 0) {
7072 sigma_dut_print(dut, DUT_MSG_ERROR,
7073 "%s: Index for interface %s failed, val:%d",
7074 __func__, intf, val);
7075 return -1;
7076 }
7077
7078 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7079 NL80211_CMD_VENDOR)) ||
7080 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7081 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7082 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7083 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7084 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7085 nla_put_u8(msg,
7086 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_OVERRIDE_MU_EDCA,
7087 val)) {
7088 sigma_dut_print(dut, DUT_MSG_ERROR,
7089 "%s: err in adding vendor_cmd and vendor_data, val: %d",
7090 __func__, val);
7091 nlmsg_free(msg);
7092 return -1;
7093 }
7094 nla_nest_end(msg, params);
7095
7096 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7097 if (ret) {
7098 sigma_dut_print(dut, DUT_MSG_ERROR,
7099 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
7100 __func__, ret, val);
7101 }
7102 return ret;
7103#else /* NL80211_SUPPORT */
7104 sigma_dut_print(dut, DUT_MSG_ERROR,
7105 "MU EDCA override cannot be changed without NL80211_SUPPORT defined");
7106 return -1;
7107#endif /* NL80211_SUPPORT */
7108}
7109
7110
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07007111static int sta_set_om_ctrl_supp(struct sigma_dut *dut, const char *intf,
7112 int val)
7113{
7114#ifdef NL80211_SUPPORT
7115 struct nl_msg *msg;
7116 int ret = 0;
7117 struct nlattr *params;
7118 int ifindex;
7119
7120 ifindex = if_nametoindex(intf);
7121 if (ifindex == 0) {
7122 sigma_dut_print(dut, DUT_MSG_ERROR,
7123 "%s: Index for interface %s failed, val:%d",
7124 __func__, intf, val);
7125 return -1;
7126 }
7127
7128 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7129 NL80211_CMD_VENDOR)) ||
7130 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7131 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7132 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7133 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7134 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7135 nla_put_u8(msg,
7136 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OM_CTRL_SUPP,
7137 val)) {
7138 sigma_dut_print(dut, DUT_MSG_ERROR,
7139 "%s: err in adding vendor_cmd and vendor_data, val: %d",
7140 __func__, val);
7141 nlmsg_free(msg);
7142 return -1;
7143 }
7144 nla_nest_end(msg, params);
7145
7146 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7147 if (ret) {
7148 sigma_dut_print(dut, DUT_MSG_ERROR,
7149 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
7150 __func__, ret, val);
7151 }
7152 return ret;
7153#else /* NL80211_SUPPORT */
7154 sigma_dut_print(dut, DUT_MSG_ERROR,
7155 "HE OM ctrl cannot be changed without NL80211_SUPPORT defined");
7156 return -1;
7157#endif /* NL80211_SUPPORT */
7158}
7159
7160
Arif Hussain480d5f42019-03-12 14:40:42 -07007161static int sta_set_twt_req_support(struct sigma_dut *dut, const char *intf,
7162 int val)
7163{
7164#ifdef NL80211_SUPPORT
7165 struct nl_msg *msg;
7166 int ret;
7167 struct nlattr *params;
7168 int ifindex;
7169
7170 ifindex = if_nametoindex(intf);
7171 if (ifindex == 0) {
7172 sigma_dut_print(dut, DUT_MSG_ERROR,
7173 "%s: Index for interface %s failed, val:%d",
7174 __func__, intf, val);
7175 return -1;
7176 }
7177
7178 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7179 NL80211_CMD_VENDOR)) ||
7180 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7181 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7182 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7183 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7184 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7185 nla_put_u8(msg,
7186 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TWT_REQ_SUPPORT,
7187 val)) {
7188 sigma_dut_print(dut, DUT_MSG_ERROR,
7189 "%s: err in adding vendor_cmd and vendor_data, val: %d",
7190 __func__, val);
7191 nlmsg_free(msg);
7192 return -1;
7193 }
7194 nla_nest_end(msg, params);
7195
7196 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7197 if (ret) {
7198 sigma_dut_print(dut, DUT_MSG_ERROR,
7199 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
7200 __func__, ret, val);
7201 }
7202 return ret;
7203#else /* NL80211_SUPPORT */
7204 sigma_dut_print(dut, DUT_MSG_ERROR,
7205 "TWT Request cannot be changed without NL80211_SUPPORT defined");
7206 return -1;
7207#endif /* NL80211_SUPPORT */
7208}
7209
7210
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08007211static void sta_reset_default_wcn(struct sigma_dut *dut, const char *intf,
7212 const char *type)
7213{
7214 char buf[60];
7215
7216 if (dut->program == PROGRAM_HE) {
7217 /* resetting phymode to auto in case of HE program */
7218 snprintf(buf, sizeof(buf), "iwpriv %s setphymode 0", intf);
7219 if (system(buf) != 0) {
7220 sigma_dut_print(dut, DUT_MSG_ERROR,
7221 "iwpriv %s setphymode failed", intf);
7222 }
7223
Amarnath Hullur Subramanyam9cecb502018-04-25 13:26:30 -07007224 /* reset the rate to Auto rate */
7225 snprintf(buf, sizeof(buf), "iwpriv %s set_11ax_rate 0xff",
7226 intf);
7227 if (system(buf) != 0) {
7228 sigma_dut_print(dut, DUT_MSG_ERROR,
7229 "iwpriv %s set_11ax_rate 0xff failed",
7230 intf);
7231 }
7232
Kiran Kumar Lokere86cfe3a2018-06-01 11:55:15 -07007233 /* reset the LDPC setting */
7234 snprintf(buf, sizeof(buf), "iwpriv %s ldpc 1", intf);
7235 if (system(buf) != 0) {
7236 sigma_dut_print(dut, DUT_MSG_ERROR,
7237 "iwpriv %s ldpc 1 failed", intf);
7238 }
7239
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08007240 /* reset the power save setting */
7241 snprintf(buf, sizeof(buf), "iwpriv %s setPower 2", intf);
7242 if (system(buf) != 0) {
7243 sigma_dut_print(dut, DUT_MSG_ERROR,
7244 "iwpriv %s setPower 2 failed", intf);
7245 }
7246
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08007247 /* remove all network profiles */
7248 remove_wpa_networks(intf);
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08007249
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08007250 /* Configure ADDBA Req/Rsp buffer size to be 64 */
7251 sta_set_addba_buf_size(dut, intf, 64);
7252
Amarnath Hullur Subramanyam5f32d572018-03-02 00:02:33 -08007253#ifdef NL80211_SUPPORT
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08007254 /* Reset the device HE capabilities to its default supported
7255 * configuration. */
7256 sta_set_he_testbed_def(dut, intf, 0);
7257
Amarnath Hullur Subramanyam5f32d572018-03-02 00:02:33 -08007258 /* Disable noackpolicy for all AC */
7259 if (nlvendor_sta_set_noack(dut, intf, 0, QCA_WLAN_AC_ALL)) {
7260 sigma_dut_print(dut, DUT_MSG_ERROR,
7261 "Disable of noackpolicy for all AC failed");
7262 }
7263#endif /* NL80211_SUPPORT */
7264
Amarnath Hullur Subramanyamb1724a52018-03-07 14:31:46 -08007265 /* Enable WMM by default */
7266 if (wcn_sta_set_wmm(dut, intf, "on")) {
7267 sigma_dut_print(dut, DUT_MSG_ERROR,
7268 "Enable of WMM in sta_reset_default_wcn failed");
7269 }
7270
7271 /* Disable ADDBA_REJECT by default */
7272 if (nlvendor_sta_set_addba_reject(dut, intf, 0)) {
7273 sigma_dut_print(dut, DUT_MSG_ERROR,
7274 "Disable of addba_reject in sta_reset_default_wcn failed");
7275 }
7276
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08007277 /* Enable sending of ADDBA by default */
7278 if (nlvendor_config_send_addba(dut, intf, 1)) {
7279 sigma_dut_print(dut, DUT_MSG_ERROR,
7280 "Enable sending of ADDBA in sta_reset_default_wcn failed");
7281 }
7282
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08007283 /* Enable AMPDU by default */
7284 iwpriv_sta_set_ampdu(dut, intf, 1);
7285
Subhani Shaik8e7a3052018-04-24 14:03:00 -07007286#ifdef NL80211_SUPPORT
7287 if (sta_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_AUTO)) {
7288 sigma_dut_print(dut, DUT_MSG_ERROR,
7289 "Set LTF config to default in sta_reset_default_wcn failed");
7290 }
Arif Hussain9765f7d2018-07-03 08:28:26 -07007291
Kiran Kumar Lokerebad51122018-12-12 19:03:36 -08007292 /* set the beamformee NSTS(maximum number of
7293 * space-time streams) to default DUT config
7294 */
7295 if (sta_set_beamformee_sts(dut, intf, 7)) {
Arif Hussain9765f7d2018-07-03 08:28:26 -07007296 sigma_dut_print(dut, DUT_MSG_ERROR,
7297 "Failed to set BeamformeeSTS");
7298 }
Arif Hussain68d23f52018-07-11 13:39:08 -07007299
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07007300 if (sta_set_mac_padding_duration(
7301 dut, intf,
7302 QCA_WLAN_HE_NO_ADDITIONAL_PROCESS_TIME)) {
Arif Hussain68d23f52018-07-11 13:39:08 -07007303 sigma_dut_print(dut, DUT_MSG_ERROR,
7304 "Failed to set MAC padding duration");
7305 }
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07007306
7307 if (sta_set_mu_edca_override(dut, intf, 0)) {
7308 sigma_dut_print(dut, DUT_MSG_ERROR,
7309 "ErrorCode,Failed to set MU EDCA override disable");
7310 }
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07007311
7312 if (sta_set_om_ctrl_supp(dut, intf, 1)) {
7313 sigma_dut_print(dut, DUT_MSG_ERROR,
7314 "Failed to set OM ctrl supp");
7315 }
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07007316
7317 if (sta_set_tx_su_ppdu_cfg(dut, intf, 1)) {
7318 sigma_dut_print(dut, DUT_MSG_ERROR,
7319 "Failed to set Tx SU PPDU enable");
7320 }
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07007321
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07007322 if (sta_set_action_tx_in_he_tb_ppdu(dut, intf, 0)) {
7323 sigma_dut_print(dut, DUT_MSG_ERROR,
7324 "failed to send TB PPDU Tx cfg");
7325 }
7326
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07007327 if (sta_set_he_om_ctrl_reset(dut, intf)) {
7328 sigma_dut_print(dut, DUT_MSG_ERROR,
7329 "Failed to set OM ctrl reset");
7330 }
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08007331
7332 /* +HTC-HE support default on */
7333 if (sta_set_he_htc_supp(dut, intf, 1)) {
7334 sigma_dut_print(dut, DUT_MSG_ERROR,
7335 "Setting of +HTC-HE support failed");
7336 }
Subhani Shaik8e7a3052018-04-24 14:03:00 -07007337#endif /* NL80211_SUPPORT */
7338
Arif Hussain8d5b27b2018-05-14 14:31:03 -07007339 if (sta_set_tx_beamformee(dut, intf, 1)) {
7340 sigma_dut_print(dut, DUT_MSG_ERROR,
7341 "Set tx beamformee enable by default in sta_reset_default_wcn failed");
7342 }
7343
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08007344 /* Set nss to 1 and MCS 0-7 in case of testbed */
7345 if (type && strcasecmp(type, "Testbed") == 0) {
7346#ifdef NL80211_SUPPORT
7347 int ret;
7348#endif /* NL80211_SUPPORT */
7349
7350 snprintf(buf, sizeof(buf), "iwpriv %s nss 1", intf);
7351 if (system(buf) != 0) {
7352 sigma_dut_print(dut, DUT_MSG_ERROR,
7353 "iwpriv %s nss failed", intf);
7354 }
7355
7356#ifdef NL80211_SUPPORT
7357 ret = sta_set_he_mcs(dut, intf, HE_80_MCS0_7);
7358 if (ret) {
7359 sigma_dut_print(dut, DUT_MSG_ERROR,
7360 "Setting of MCS failed, ret:%d",
7361 ret);
7362 }
7363#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyamc67621d2018-02-04 23:18:01 -08007364
7365 /* Disable STBC as default */
7366 wcn_sta_set_stbc(dut, intf, "0");
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08007367
7368 /* Disable AMSDU as default */
7369 iwpriv_sta_set_amsdu(dut, intf, "0");
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08007370
7371#ifdef NL80211_SUPPORT
7372 /* HE fragmentation default off */
7373 if (sta_set_he_fragmentation(dut, intf,
7374 HE_FRAG_DISABLE)) {
7375 sigma_dut_print(dut, DUT_MSG_ERROR,
7376 "Setting of HE fragmentation failed");
7377 }
Kiran Kumar Lokerebad51122018-12-12 19:03:36 -08007378
7379 /* set the beamformee NSTS(maximum number of
7380 * space-time streams) to default testbed config
7381 */
7382 if (sta_set_beamformee_sts(dut, intf, 3)) {
7383 sigma_dut_print(dut, DUT_MSG_ERROR,
7384 "Failed to set BeamformeeSTS");
7385 }
7386
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08007387 /* +HTC-HE support default off */
7388 if (sta_set_he_htc_supp(dut, intf, 0)) {
7389 sigma_dut_print(dut, DUT_MSG_ERROR,
7390 "Setting of +HTC-HE support failed");
7391 }
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08007392
7393 /* Set device HE capabilities to testbed default
7394 * configuration. */
7395 if (sta_set_he_testbed_def(dut, intf, 1)) {
7396 sigma_dut_print(dut, DUT_MSG_DEBUG,
7397 "Failed to set HE defaults");
7398 }
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08007399
7400 /* Disable VHT support in 2.4 GHz for testbed */
7401 sta_set_2g_vht_supp(dut, intf, 0);
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08007402#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08007403
7404 /* Enable WEP/TKIP with HE capability in testbed */
7405 if (sta_set_heconfig_and_wep_tkip(dut, intf, 1)) {
7406 sigma_dut_print(dut, DUT_MSG_ERROR,
7407 "Enabling HE config with WEP/TKIP failed");
7408 }
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08007409 }
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08007410
7411 /* Defaults in case of DUT */
7412 if (type && strcasecmp(type, "DUT") == 0) {
Arif Hussaind48fcc72018-05-01 18:34:18 -07007413 /* Enable STBC by default */
7414 wcn_sta_set_stbc(dut, intf, "1");
7415
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08007416 /* set nss to 2 */
7417 snprintf(buf, sizeof(buf), "iwpriv %s nss 2", intf);
7418 if (system(buf) != 0) {
7419 sigma_dut_print(dut, DUT_MSG_ERROR,
7420 "iwpriv %s nss 2 failed", intf);
7421 }
Arif Hussainac6c5112018-05-25 17:34:00 -07007422 dut->sta_nss = 2;
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08007423
7424#ifdef NL80211_SUPPORT
Arif Hussainae239842018-05-01 18:20:05 -07007425 /* Set HE_MCS to 0-11 */
7426 if (sta_set_he_mcs(dut, intf, HE_80_MCS0_11)) {
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08007427 sigma_dut_print(dut, DUT_MSG_ERROR,
7428 "Setting of MCS failed");
7429 }
7430#endif /* NL80211_SUPPORT */
7431
7432 /* Disable WEP/TKIP with HE capability in DUT */
7433 if (sta_set_heconfig_and_wep_tkip(dut, intf, 0)) {
7434 sigma_dut_print(dut, DUT_MSG_ERROR,
7435 "Enabling HE config with WEP/TKIP failed");
7436 }
7437 }
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08007438 }
7439}
7440
7441
Jouni Malinenf7222712019-06-13 01:50:21 +03007442static enum sigma_cmd_result cmd_sta_reset_default(struct sigma_dut *dut,
7443 struct sigma_conn *conn,
7444 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007445{
7446 int cmd_sta_p2p_reset(struct sigma_dut *dut, struct sigma_conn *conn,
7447 struct sigma_cmd *cmd);
7448 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007449 const char *band = get_param(cmd, "band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007450 const char *type;
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07007451 const char *program = get_param(cmd, "program");
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05307452 const char *dev_role = get_param(cmd, "DevRole");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007453
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07007454 if (!program)
7455 program = get_param(cmd, "prog");
7456 dut->program = sigma_program_to_enum(program);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007457 dut->device_type = STA_unknown;
7458 type = get_param(cmd, "type");
7459 if (type && strcasecmp(type, "Testbed") == 0)
7460 dut->device_type = STA_testbed;
7461 if (type && strcasecmp(type, "DUT") == 0)
7462 dut->device_type = STA_dut;
7463
7464 if (dut->program == PROGRAM_TDLS) {
7465 /* Clear TDLS testing mode */
7466 wpa_command(intf, "SET tdls_disabled 0");
7467 wpa_command(intf, "SET tdls_testing 0");
7468 dut->no_tpk_expiration = 0;
Pradeep Reddy POTTETI8ce2a232016-10-28 12:17:32 +05307469 if (get_driver_type() == DRIVER_WCN) {
7470 /* Enable the WCN driver in TDLS Explicit trigger mode
7471 */
7472 wpa_command(intf, "SET tdls_external_control 0");
7473 wpa_command(intf, "SET tdls_trigger_control 0");
7474 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007475 }
7476
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07007477#ifdef MIRACAST
7478 if (dut->program == PROGRAM_WFD ||
7479 dut->program == PROGRAM_DISPLAYR2)
7480 miracast_sta_reset_default(dut, conn, cmd);
7481#endif /* MIRACAST */
7482
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007483 switch (get_driver_type()) {
7484 case DRIVER_ATHEROS:
7485 sta_reset_default_ath(dut, intf, type);
7486 break;
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08007487 case DRIVER_WCN:
7488 sta_reset_default_wcn(dut, intf, type);
7489 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007490 default:
7491 break;
7492 }
7493
7494#ifdef ANDROID_NAN
7495 if (dut->program == PROGRAM_NAN)
7496 nan_cmd_sta_reset_default(dut, conn, cmd);
7497#endif /* ANDROID_NAN */
7498
Jouni Malinenba630452018-06-22 11:49:59 +03007499 if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007500 unlink("SP/wi-fi.org/pps.xml");
7501 if (system("rm -r SP/*") != 0) {
7502 }
7503 unlink("next-client-cert.pem");
7504 unlink("next-client-key.pem");
7505 }
7506
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007507 /* For WPS program of the 60 GHz band the band type needs to be saved */
7508 if (dut->program == PROGRAM_WPS) {
7509 if (band && strcasecmp(band, "60GHz") == 0) {
7510 dut->band = WPS_BAND_60G;
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02007511 /* For 60 GHz enable WPS for WPS TCs */
7512 dut->wps_disable = 0;
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007513 } else {
7514 dut->band = WPS_BAND_NON_60G;
7515 }
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02007516 } else if (dut->program == PROGRAM_60GHZ) {
7517 /* For 60 GHz MAC/PHY TCs WPS must be disabled */
7518 dut->wps_disable = 1;
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007519 }
7520
Alexei Avshalom Lazar157ba062018-12-23 16:15:26 +02007521 if (is_60g_sigma_dut(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007522 const char *dev_role = get_param(cmd, "DevRole");
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02007523 char buf[256];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007524
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02007525 sigma_dut_print(dut, DUT_MSG_INFO,
7526 "WPS 60 GHz program, wps_disable = %d",
7527 dut->wps_disable);
7528
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007529 if (!dev_role) {
7530 send_resp(dut, conn, SIGMA_ERROR,
7531 "errorCode,Missing DevRole argument");
7532 return 0;
7533 }
7534
7535 if (strcasecmp(dev_role, "STA") == 0)
7536 dut->dev_role = DEVROLE_STA;
7537 else if (strcasecmp(dev_role, "PCP") == 0)
7538 dut->dev_role = DEVROLE_PCP;
7539 else {
7540 send_resp(dut, conn, SIGMA_ERROR,
7541 "errorCode,Unknown DevRole");
7542 return 0;
7543 }
7544
7545 if (dut->device_type == STA_unknown) {
7546 sigma_dut_print(dut, DUT_MSG_ERROR,
7547 "Device type is not STA testbed or DUT");
7548 send_resp(dut, conn, SIGMA_ERROR,
7549 "errorCode,Unknown device type");
7550 return 0;
7551 }
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02007552
7553 sigma_dut_print(dut, DUT_MSG_DEBUG,
7554 "Setting msdu_size to MAX: 7912");
7555 snprintf(buf, sizeof(buf), "ifconfig %s mtu 7912",
7556 get_station_ifname());
7557
7558 if (system(buf) != 0) {
7559 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
7560 buf);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007561 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02007562 }
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02007563
7564 if (sta_set_force_mcs(dut, 0, 1)) {
7565 sigma_dut_print(dut, DUT_MSG_ERROR,
7566 "Failed to reset force MCS");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007567 return ERROR_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02007568 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007569 }
7570
7571 wpa_command(intf, "WPS_ER_STOP");
7572 wpa_command(intf, "FLUSH");
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05307573 wpa_command(intf, "ERP_FLUSH");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007574 wpa_command(intf, "SET radio_disabled 0");
7575
Alexei Avshalom Lazar744ae8a2019-01-31 17:26:46 +02007576 dut->wps_forced_version = 0;
7577
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007578 if (dut->wsc_fragment) {
7579 dut->wsc_fragment = 0;
7580 wpa_command(intf, "SET device_name Test client");
7581 wpa_command(intf, "SET manufacturer ");
7582 wpa_command(intf, "SET model_name ");
7583 wpa_command(intf, "SET model_number ");
7584 wpa_command(intf, "SET serial_number ");
7585 }
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02007586 if (is_60g_sigma_dut(dut) && dut->force_rsn_ie) {
7587 dut->force_rsn_ie = FORCE_RSN_IE_NONE;
7588 sta_60g_force_rsn_ie(dut, FORCE_RSN_IE_NONE);
7589 }
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007590
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007591 if (dut->tmp_mac_addr && dut->set_macaddr) {
7592 dut->tmp_mac_addr = 0;
7593 if (system(dut->set_macaddr) != 0) {
7594 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to clear "
7595 "temporary MAC address");
7596 }
7597 }
7598
7599 set_ps(intf, dut, 0);
7600
Jouni Malinenba630452018-06-22 11:49:59 +03007601 if (dut->program == PROGRAM_HS2 || dut->program == PROGRAM_HS2_R2 ||
7602 dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007603 wpa_command(intf, "SET interworking 1");
7604 wpa_command(intf, "SET hs20 1");
7605 }
7606
Deepak Dhamdhere0fe0e452017-12-18 14:52:09 -08007607 if (dut->program == PROGRAM_HS2_R2 ||
Jouni Malinenba630452018-06-22 11:49:59 +03007608 dut->program == PROGRAM_HS2_R3 ||
Deepak Dhamdhere0fe0e452017-12-18 14:52:09 -08007609 dut->program == PROGRAM_OCE) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007610 wpa_command(intf, "SET pmf 1");
7611 } else {
7612 wpa_command(intf, "SET pmf 0");
7613 }
7614
7615 hs2_clear_credentials(intf);
7616 wpa_command(intf, "SET hessid 00:00:00:00:00:00");
7617 wpa_command(intf, "SET access_network_type 15");
7618
7619 static_ip_file(0, NULL, NULL, NULL);
7620 kill_dhcp_client(dut, intf);
7621 clear_ip_addr(dut, intf);
7622
7623 dut->er_oper_performed = 0;
7624 dut->er_oper_bssid[0] = '\0';
7625
priyadharshini gowthamanad6cbba2016-10-04 10:39:58 -07007626 if (dut->program == PROGRAM_LOC) {
7627 /* Disable Interworking by default */
7628 wpa_command(get_station_ifname(), "SET interworking 0");
7629 }
7630
Ashwini Patil00402582017-04-13 12:29:39 +05307631 if (dut->program == PROGRAM_MBO) {
7632 free(dut->non_pref_ch_list);
7633 dut->non_pref_ch_list = NULL;
Ashwini Patil5acd7382017-04-13 15:55:04 +05307634 free(dut->btm_query_cand_list);
7635 dut->btm_query_cand_list = NULL;
Ashwini Patilc63161e2017-04-13 16:30:23 +05307636 wpa_command(intf, "SET reject_btm_req_reason 0");
Ashwini Patila75de5a2017-04-13 16:35:05 +05307637 wpa_command(intf, "SET ignore_assoc_disallow 0");
Ashwini Patild174f2c2017-04-13 16:49:46 +05307638 wpa_command(intf, "SET gas_address3 0");
Ashwini Patil9183fdb2017-04-13 16:58:25 +05307639 wpa_command(intf, "SET roaming 1");
Ankita Bajaj1d974552018-09-18 16:56:44 +05307640 wpa_command(intf, "SET interworking 1");
Ashwini Patil00402582017-04-13 12:29:39 +05307641 }
7642
Jouni Malinen3c367e82017-06-23 17:01:47 +03007643 free(dut->rsne_override);
7644 dut->rsne_override = NULL;
7645
Jouni Malinen68143132017-09-02 02:34:08 +03007646 free(dut->sae_commit_override);
7647 dut->sae_commit_override = NULL;
7648
Jouni Malinen134fe3c2019-06-12 04:16:49 +03007649 dut->sta_associate_wait_connect = 0;
7650 dut->server_cert_hash[0] = '\0';
7651 dut->sta_tod_policy = 0;
7652
Jouni Malinend86e5822017-08-29 03:55:32 +03007653 dut->dpp_conf_id = -1;
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02007654 free(dut->dpp_peer_uri);
7655 dut->dpp_peer_uri = NULL;
Jouni Malinen63d50412017-11-24 11:55:38 +02007656 dut->dpp_local_bootstrap = -1;
Jouni Malinen5011fb52017-12-05 21:00:15 +02007657 wpa_command(intf, "SET dpp_config_processing 2");
Jouni Malinend86e5822017-08-29 03:55:32 +03007658
Jouni Malinenfac9cad2017-10-10 18:35:55 +03007659 wpa_command(intf, "VENDOR_ELEM_REMOVE 13 *");
7660
vamsi krishnaa2799492017-12-05 14:28:01 +05307661 if (dut->program == PROGRAM_OCE) {
Ankita Bajaja2cb5672017-10-25 16:08:28 +05307662 wpa_command(intf, "SET oce 1");
vamsi krishnaa2799492017-12-05 14:28:01 +05307663 wpa_command(intf, "SET disable_fils 0");
Ankita Bajaj1bde7942018-01-09 19:15:01 +05307664 wpa_command(intf, "FILS_HLP_REQ_FLUSH");
7665 dut->fils_hlp = 0;
7666#ifdef ANDROID
7667 hlp_thread_cleanup(dut);
7668#endif /* ANDROID */
vamsi krishnaa2799492017-12-05 14:28:01 +05307669 }
Ankita Bajaja2cb5672017-10-25 16:08:28 +05307670
Jouni Malinen8179fee2019-03-28 03:19:47 +02007671 dut->akm_values = 0;
7672
Sunil Dutt076081f2018-02-05 19:45:50 +05307673#ifdef NL80211_SUPPORT
Sunil Dutt44595082018-02-12 19:41:45 +05307674 if (get_driver_type() == DRIVER_WCN &&
7675 dut->config_rsnie == 1) {
7676 dut->config_rsnie = 0;
7677 sta_config_rsnie(dut, 0);
Sunil Dutt076081f2018-02-05 19:45:50 +05307678 }
7679#endif /* NL80211_SUPPORT */
7680
Sunil Duttfebf8a82018-02-09 18:50:13 +05307681 if (dev_role && strcasecmp(dev_role, "STA-CFON") == 0) {
7682 dut->dev_role = DEVROLE_STA_CFON;
7683 return sta_cfon_reset_default(dut, conn, cmd);
7684 }
7685
Jouni Malinen439352d2018-09-13 03:42:23 +03007686 wpa_command(intf, "SET setband AUTO");
7687
Sunil Duttfebf8a82018-02-09 18:50:13 +05307688 if (dut->program != PROGRAM_VHT)
7689 return cmd_sta_p2p_reset(dut, conn, cmd);
7690
Priyadharshini Gowthamana7dfd492015-11-09 14:34:08 -08007691 return 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007692}
7693
7694
Jouni Malinenf7222712019-06-13 01:50:21 +03007695static enum sigma_cmd_result cmd_sta_get_events(struct sigma_dut *dut,
7696 struct sigma_conn *conn,
7697 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007698{
7699 const char *program = get_param(cmd, "Program");
7700
7701 if (program == NULL)
7702 return -1;
7703#ifdef ANDROID_NAN
7704 if (strcasecmp(program, "NAN") == 0)
7705 return nan_cmd_sta_get_events(dut, conn, cmd);
7706#endif /* ANDROID_NAN */
7707 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
7708 return 0;
7709}
7710
7711
Jouni Malinen82905202018-04-29 17:20:10 +03007712static int sta_exec_action_url(struct sigma_dut *dut, struct sigma_conn *conn,
7713 struct sigma_cmd *cmd)
7714{
7715 const char *url = get_param(cmd, "url");
7716 const char *method = get_param(cmd, "method");
7717 pid_t pid;
7718 int status;
7719
7720 if (!url || !method)
7721 return -1;
7722
7723 /* TODO: Add support for method,post */
7724 if (strcasecmp(method, "get") != 0) {
7725 send_resp(dut, conn, SIGMA_ERROR,
7726 "ErrorCode,Unsupported method");
7727 return 0;
7728 }
7729
7730 pid = fork();
7731 if (pid < 0) {
7732 perror("fork");
7733 return -1;
7734 }
7735
7736 if (pid == 0) {
7737 char * argv[5] = { "wget", "-O", "/dev/null",
7738 (char *) url, NULL };
7739
7740 execv("/usr/bin/wget", argv);
7741 perror("execv");
7742 exit(0);
7743 return -1;
7744 }
7745
7746 if (waitpid(pid, &status, 0) < 0) {
7747 perror("waitpid");
7748 return -1;
7749 }
7750
7751 if (WIFEXITED(status)) {
7752 const char *errmsg;
7753
7754 if (WEXITSTATUS(status) == 0)
7755 return 1;
7756 sigma_dut_print(dut, DUT_MSG_INFO, "wget exit status %d",
7757 WEXITSTATUS(status));
7758 switch (WEXITSTATUS(status)) {
7759 case 4:
7760 errmsg = "errmsg,Network failure";
7761 break;
7762 case 8:
7763 errmsg = "errmsg,Server issued an error response";
7764 break;
7765 default:
7766 errmsg = "errmsg,Unknown failure from wget";
7767 break;
7768 }
7769 send_resp(dut, conn, SIGMA_ERROR, errmsg);
7770 return 0;
7771 }
7772
7773 send_resp(dut, conn, SIGMA_ERROR, "errmsg,Unknown failure");
7774 return 0;
7775}
7776
7777
Jouni Malinenf7222712019-06-13 01:50:21 +03007778static enum sigma_cmd_result cmd_sta_exec_action(struct sigma_dut *dut,
7779 struct sigma_conn *conn,
7780 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007781{
7782 const char *program = get_param(cmd, "Prog");
7783
Jouni Malinen82905202018-04-29 17:20:10 +03007784 if (program && !get_param(cmd, "interface"))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007785 return -1;
7786#ifdef ANDROID_NAN
Jouni Malinen82905202018-04-29 17:20:10 +03007787 if (program && strcasecmp(program, "NAN") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007788 return nan_cmd_sta_exec_action(dut, conn, cmd);
7789#endif /* ANDROID_NAN */
Jouni Malinen82905202018-04-29 17:20:10 +03007790
7791 if (program && strcasecmp(program, "Loc") == 0)
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07007792 return loc_cmd_sta_exec_action(dut, conn, cmd);
Jouni Malinen82905202018-04-29 17:20:10 +03007793
7794 if (get_param(cmd, "url"))
7795 return sta_exec_action_url(dut, conn, cmd);
7796
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007797 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
7798 return 0;
7799}
7800
7801
Jouni Malinenf7222712019-06-13 01:50:21 +03007802static enum sigma_cmd_result cmd_sta_set_11n(struct sigma_dut *dut,
7803 struct sigma_conn *conn,
7804 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007805{
7806 const char *intf = get_param(cmd, "Interface");
7807 const char *val, *mcs32, *rate;
7808
7809 val = get_param(cmd, "GREENFIELD");
7810 if (val) {
7811 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
7812 /* Enable GD */
7813 send_resp(dut, conn, SIGMA_ERROR,
7814 "ErrorCode,GF not supported");
7815 return 0;
7816 }
7817 }
7818
7819 val = get_param(cmd, "SGI20");
7820 if (val) {
7821 switch (get_driver_type()) {
7822 case DRIVER_ATHEROS:
7823 ath_sta_set_sgi(dut, intf, val);
7824 break;
7825 default:
7826 send_resp(dut, conn, SIGMA_ERROR,
7827 "ErrorCode,SGI20 not supported");
7828 return 0;
7829 }
7830 }
7831
7832 mcs32 = get_param(cmd, "MCS32"); /* HT Duplicate Mode Enable/Disable */
7833 rate = get_param(cmd, "MCS_FIXEDRATE"); /* Fixed MCS rate (0..31) */
7834 if (mcs32 && rate) {
7835 /* TODO */
7836 send_resp(dut, conn, SIGMA_ERROR,
7837 "ErrorCode,MCS32,MCS_FIXEDRATE not supported");
7838 return 0;
7839 } else if (mcs32 && !rate) {
7840 /* TODO */
7841 send_resp(dut, conn, SIGMA_ERROR,
7842 "ErrorCode,MCS32 not supported");
7843 return 0;
7844 } else if (!mcs32 && rate) {
7845 switch (get_driver_type()) {
7846 case DRIVER_ATHEROS:
priyadharshini gowthamane5e25172015-12-08 14:53:48 -08007847 novap_reset(dut, intf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007848 ath_sta_set_11nrates(dut, intf, rate);
7849 break;
7850 default:
7851 send_resp(dut, conn, SIGMA_ERROR,
7852 "ErrorCode,MCS32_FIXEDRATE not supported");
7853 return 0;
7854 }
7855 }
7856
7857 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
7858}
7859
7860
Arif Hussain7b47d2d2018-05-09 10:44:02 -07007861static void cmd_set_max_he_mcs(struct sigma_dut *dut, const char *intf,
7862 int mcs_config)
7863{
7864#ifdef NL80211_SUPPORT
7865 int ret;
7866
7867 switch (mcs_config) {
7868 case HE_80_MCS0_7:
7869 case HE_80_MCS0_9:
7870 case HE_80_MCS0_11:
7871 ret = sta_set_he_mcs(dut, intf, mcs_config);
7872 if (ret) {
7873 sigma_dut_print(dut, DUT_MSG_ERROR,
7874 "cmd_set_max_he_mcs: Setting of MCS:%d failed, ret:%d",
7875 mcs_config, ret);
7876 }
7877 break;
7878 default:
7879 sigma_dut_print(dut, DUT_MSG_ERROR,
7880 "cmd_set_max_he_mcs: Invalid mcs %d",
7881 mcs_config);
7882 break;
7883 }
7884#else /* NL80211_SUPPORT */
7885 sigma_dut_print(dut, DUT_MSG_ERROR,
7886 "max HE MCS cannot be changed without NL80211_SUPPORT defined");
7887#endif /* NL80211_SUPPORT */
7888}
7889
7890
Arif Hussain480d5f42019-03-12 14:40:42 -07007891static int sta_twt_request(struct sigma_dut *dut, struct sigma_conn *conn,
7892 struct sigma_cmd *cmd)
7893{
7894#ifdef NL80211_SUPPORT
7895 struct nlattr *params;
7896 struct nlattr *attr;
7897 struct nlattr *attr1;
7898 struct nl_msg *msg;
7899 int ifindex, ret;
7900 const char *val;
7901 const char *intf = get_param(cmd, "Interface");
7902 int wake_interval_exp = 10, nominal_min_wake_dur = 255,
7903 wake_interval_mantissa = 512;
7904 int flow_type = 0, twt_trigger = 0, target_wake_time = 0,
7905 protection = 0;
7906
7907 ifindex = if_nametoindex(intf);
7908 if (ifindex == 0) {
7909 sigma_dut_print(dut, DUT_MSG_ERROR,
7910 "%s: Index for interface %s failed",
7911 __func__, intf);
7912 return -1;
7913 }
7914
7915 val = get_param(cmd, "FlowType");
7916 if (val) {
7917 flow_type = atoi(val);
7918 if (flow_type != 0 && flow_type != 1) {
7919 sigma_dut_print(dut, DUT_MSG_ERROR,
7920 "TWT: Invalid FlowType %d", flow_type);
7921 return -1;
7922 }
7923 }
7924
7925 val = get_param(cmd, "TWT_Trigger");
7926 if (val) {
7927 twt_trigger = atoi(val);
7928 if (twt_trigger != 0 && twt_trigger != 1) {
7929 sigma_dut_print(dut, DUT_MSG_ERROR,
7930 "TWT: Invalid TWT_Trigger %d",
7931 twt_trigger);
7932 return -1;
7933 }
7934 }
7935
7936 val = get_param(cmd, "Protection");
7937 if (val) {
7938 protection = atoi(val);
7939 if (protection != 0 && protection != 1) {
7940 sigma_dut_print(dut, DUT_MSG_ERROR,
7941 "TWT: Invalid Protection %d",
7942 protection);
7943 return -1;
7944 }
7945 }
7946
7947 val = get_param(cmd, "TargetWakeTime");
7948 if (val)
7949 target_wake_time = atoi(val);
7950
7951 val = get_param(cmd, "WakeIntervalMantissa");
7952 if (val)
7953 wake_interval_mantissa = atoi(val);
7954
7955 val = get_param(cmd, "WakeIntervalExp");
7956 if (val)
7957 wake_interval_exp = atoi(val);
7958
7959 val = get_param(cmd, "NominalMinWakeDur");
7960 if (val)
7961 nominal_min_wake_dur = atoi(val);
7962
7963 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7964 NL80211_CMD_VENDOR)) ||
7965 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7966 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7967 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7968 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7969 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7970 !(params = nla_nest_start(
7971 msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_SETUP)) ||
7972 !(attr1 = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7973 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_EXP,
7974 wake_interval_exp) ||
7975 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST, 0) ||
7976 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_REQ_TYPE, 1) ||
7977 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TRIGGER,
7978 twt_trigger) ||
7979 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE,
7980 flow_type) ||
7981 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_PROTECTION,
7982 protection) ||
7983 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME,
7984 target_wake_time) ||
7985 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_DURATION,
7986 nominal_min_wake_dur) ||
7987 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_MANTISSA,
7988 wake_interval_mantissa)) {
7989 sigma_dut_print(dut, DUT_MSG_ERROR,
7990 "%s: err in adding vendor_cmd and vendor_data",
7991 __func__);
7992 nlmsg_free(msg);
7993 return -1;
7994 }
7995 nla_nest_end(msg, attr1);
7996 nla_nest_end(msg, params);
7997 nla_nest_end(msg, attr);
7998
7999 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
8000 if (ret) {
8001 sigma_dut_print(dut, DUT_MSG_ERROR,
8002 "%s: err in send_and_recv_msgs, ret=%d",
8003 __func__, ret);
8004 }
8005
8006 return ret;
8007#else /* NL80211_SUPPORT */
8008 sigma_dut_print(dut, DUT_MSG_ERROR,
8009 "TWT request cannot be done without NL80211_SUPPORT defined");
8010 return -1;
8011#endif /* NL80211_SUPPORT */
8012}
8013
8014
8015static int sta_twt_teardown(struct sigma_dut *dut, struct sigma_conn *conn,
8016 struct sigma_cmd *cmd)
8017{
8018 #ifdef NL80211_SUPPORT
8019 struct nlattr *params;
8020 struct nlattr *attr;
8021 struct nlattr *attr1;
8022 int ifindex, ret;
8023 struct nl_msg *msg;
8024 const char *intf = get_param(cmd, "Interface");
8025
8026 ifindex = if_nametoindex(intf);
8027 if (ifindex == 0) {
8028 sigma_dut_print(dut, DUT_MSG_ERROR,
8029 "%s: Index for interface %s failed",
8030 __func__, intf);
8031 return -1;
8032 }
8033
8034 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8035 NL80211_CMD_VENDOR)) ||
8036 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
8037 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
8038 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
8039 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
8040 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8041 !(params = nla_nest_start(
8042 msg,
8043 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_TERMINATE)) ||
8044 !(attr1 = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8045 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE, 0)) {
8046 sigma_dut_print(dut, DUT_MSG_ERROR,
8047 "%s: err in adding vendor_cmd and vendor_data",
8048 __func__);
8049 nlmsg_free(msg);
8050 return -1;
8051 }
8052 nla_nest_end(msg, attr1);
8053 nla_nest_end(msg, params);
8054 nla_nest_end(msg, attr);
8055
8056 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
8057 if (ret) {
8058 sigma_dut_print(dut, DUT_MSG_ERROR,
8059 "%s: err in send_and_recv_msgs, ret=%d",
8060 __func__, ret);
8061 }
8062
8063 return ret;
8064#else /* NL80211_SUPPORT */
8065 sigma_dut_print(dut, DUT_MSG_ERROR,
8066 "TWT teardown cannot be done without NL80211_SUPPORT defined");
8067 return -1;
8068#endif /* NL80211_SUPPORT */
8069}
8070
8071
Kiran Kumar Lokere50eb2cd2018-12-18 18:31:28 -08008072static int sta_transmit_omi(struct sigma_dut *dut, struct sigma_conn *conn,
8073 struct sigma_cmd *cmd)
8074{
8075#ifdef NL80211_SUPPORT
8076 struct nlattr *params;
8077 struct nlattr *attr;
8078 struct nlattr *attr1;
8079 struct nl_msg *msg;
8080 int ifindex, ret;
8081 const char *val;
8082 const char *intf = get_param(cmd, "Interface");
8083 uint8_t rx_nss = 0xFF, ch_bw = 0xFF, tx_nsts = 0xFF, ulmu_dis = 0,
8084 ulmu_data_dis = 0;
8085
8086 ifindex = if_nametoindex(intf);
8087 if (ifindex == 0) {
8088 sigma_dut_print(dut, DUT_MSG_ERROR,
8089 "%s: Index for interface %s failed",
8090 __func__, intf);
8091 return -1;
8092 }
8093 val = get_param(cmd, "OMCtrl_RxNSS");
8094 if (val)
8095 rx_nss = atoi(val);
8096
8097 val = get_param(cmd, "OMCtrl_ChnlWidth");
8098 if (val)
8099 ch_bw = atoi(val);
8100
8101 val = get_param(cmd, "OMCtrl_ULMUDisable");
8102 if (val)
8103 ulmu_dis = atoi(val);
8104
8105 val = get_param(cmd, "OMCtrl_TxNSTS");
8106 if (val)
8107 tx_nsts = atoi(val);
8108
8109 val = get_param(cmd, "OMCtrl_ULMUDataDisable");
8110 if (val)
8111 ulmu_data_dis = atoi(val);
8112
8113 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8114 NL80211_CMD_VENDOR)) ||
8115 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
8116 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
8117 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
8118 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
8119 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8120 !(params = nla_nest_start(
8121 msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OMI_TX)) ||
8122 !(attr1 = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8123 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_RX_NSS, rx_nss) ||
8124 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_CH_BW, ch_bw) ||
8125 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_TX_NSTS, tx_nsts) ||
8126 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DATA_DISABLE,
8127 ulmu_data_dis) ||
8128 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DISABLE,
8129 ulmu_dis)) {
8130 sigma_dut_print(dut, DUT_MSG_ERROR,
8131 "%s: err in adding vendor_cmd and vendor_data",
8132 __func__);
8133 nlmsg_free(msg);
8134 return -1;
8135 }
8136 nla_nest_end(msg, attr1);
8137 nla_nest_end(msg, params);
8138 nla_nest_end(msg, attr);
8139
8140 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
8141 if (ret) {
8142 sigma_dut_print(dut, DUT_MSG_ERROR,
8143 "%s: err in send_and_recv_msgs, ret=%d",
8144 __func__, ret);
8145 }
8146
8147 return ret;
8148#else /* NL80211_SUPPORT */
8149 sigma_dut_print(dut, DUT_MSG_ERROR,
8150 "OMI TX cannot be processed without NL80211_SUPPORT defined");
8151 return -1;
8152#endif /* NL80211_SUPPORT */
8153}
8154
8155
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008156static int cmd_sta_set_wireless_vht(struct sigma_dut *dut,
8157 struct sigma_conn *conn,
8158 struct sigma_cmd *cmd)
8159{
8160 const char *intf = get_param(cmd, "Interface");
8161 const char *val;
Arif Hussaina37e9552018-06-20 17:05:59 -07008162 const char *program;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008163 int tkip = -1;
8164 int wep = -1;
8165
Arif Hussaina37e9552018-06-20 17:05:59 -07008166 program = get_param(cmd, "Program");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008167 val = get_param(cmd, "SGI80");
8168 if (val) {
8169 int sgi80;
8170
8171 sgi80 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008172 run_iwpriv(dut, intf, "shortgi %d", sgi80);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008173 }
8174
8175 val = get_param(cmd, "TxBF");
8176 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07008177 switch (get_driver_type()) {
8178 case DRIVER_WCN:
8179 if (sta_set_tx_beamformee(dut, intf, 1)) {
8180 send_resp(dut, conn, SIGMA_ERROR,
8181 "ErrorCode,Failed to set TX beamformee enable");
8182 return 0;
8183 }
8184 break;
8185 case DRIVER_ATHEROS:
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008186 if (run_iwpriv(dut, intf, "vhtsubfee 1") < 0) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07008187 send_resp(dut, conn, SIGMA_ERROR,
8188 "ErrorCode,Setting vhtsubfee failed");
8189 return 0;
8190 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008191 if (run_iwpriv(dut, intf, "vhtsubfer 1") < 0) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07008192 send_resp(dut, conn, SIGMA_ERROR,
8193 "ErrorCode,Setting vhtsubfer failed");
8194 return 0;
8195 }
8196 break;
8197 default:
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008198 sigma_dut_print(dut, DUT_MSG_ERROR,
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07008199 "Unsupported driver type");
8200 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008201 }
8202 }
8203
8204 val = get_param(cmd, "MU_TxBF");
8205 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
8206 switch (get_driver_type()) {
8207 case DRIVER_ATHEROS:
8208 ath_sta_set_txsp_stream(dut, intf, "1SS");
8209 ath_sta_set_rxsp_stream(dut, intf, "1SS");
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008210 run_iwpriv(dut, intf, "vhtmubfee 1");
8211 run_iwpriv(dut, intf, "vhtmubfer 1");
Sunil Duttae9e5d12018-06-29 11:50:47 +05308212 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008213 case DRIVER_WCN:
8214 if (wcn_sta_set_sp_stream(dut, intf, "1SS") < 0) {
8215 send_resp(dut, conn, SIGMA_ERROR,
8216 "ErrorCode,Failed to set RX/TXSP_STREAM");
8217 return 0;
8218 }
Sunil Duttae9e5d12018-06-29 11:50:47 +05308219 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008220 default:
8221 sigma_dut_print(dut, DUT_MSG_ERROR,
8222 "Setting SP_STREAM not supported");
8223 break;
8224 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008225 }
8226
8227 val = get_param(cmd, "LDPC");
8228 if (val) {
8229 int ldpc;
8230
8231 ldpc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008232 run_iwpriv(dut, intf, "ldpc %d", ldpc);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008233 }
8234
Amarnath Hullur Subramanyam7bae60e2018-01-31 03:46:50 -08008235 val = get_param(cmd, "BCC");
8236 if (val) {
8237 int bcc;
8238
8239 bcc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
8240 /* use LDPC iwpriv itself to set bcc coding, bcc coding
8241 * is mutually exclusive to bcc */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008242 run_iwpriv(dut, intf, "ldpc %d", !bcc);
Amarnath Hullur Subramanyam7bae60e2018-01-31 03:46:50 -08008243 }
8244
Arif Hussain7b47d2d2018-05-09 10:44:02 -07008245 val = get_param(cmd, "MaxHE-MCS_1SS_RxMapLTE80");
8246 if (val && dut->sta_nss == 1)
8247 cmd_set_max_he_mcs(dut, intf, atoi(val));
8248
8249 val = get_param(cmd, "MaxHE-MCS_2SS_RxMapLTE80");
8250 if (val && dut->sta_nss == 2)
8251 cmd_set_max_he_mcs(dut, intf, atoi(val));
8252
Arif Hussainac6c5112018-05-25 17:34:00 -07008253 val = get_param(cmd, "MCS_FixedRate");
8254 if (val) {
8255#ifdef NL80211_SUPPORT
8256 int mcs, ratecode = 0;
8257 enum he_mcs_config mcs_config;
8258 int ret;
Jouni Malinenb9b671d2019-04-26 13:23:17 +03008259 char buf[60];
Arif Hussainac6c5112018-05-25 17:34:00 -07008260
8261 ratecode = (0x07 & dut->sta_nss) << 5;
8262 mcs = atoi(val);
8263 /* Add the MCS to the ratecode */
8264 if (mcs >= 0 && mcs <= 11) {
8265 ratecode += mcs;
8266 if (dut->device_type == STA_testbed &&
8267 mcs > 7 && mcs <= 11) {
8268 if (mcs <= 9)
8269 mcs_config = HE_80_MCS0_9;
8270 else
8271 mcs_config = HE_80_MCS0_11;
8272 ret = sta_set_he_mcs(dut, intf, mcs_config);
8273 if (ret) {
8274 sigma_dut_print(dut, DUT_MSG_ERROR,
8275 "MCS_FixedRate: mcs setting failed, mcs:%d, mcs_config %d, ret:%d",
8276 mcs, mcs_config, ret);
8277 }
8278 }
8279 snprintf(buf, sizeof(buf),
8280 "iwpriv %s set_11ax_rate 0x%03x",
8281 intf, ratecode);
8282 if (system(buf) != 0) {
8283 sigma_dut_print(dut, DUT_MSG_ERROR,
8284 "MCS_FixedRate: iwpriv setting of 11ax rates 0x%03x failed",
8285 ratecode);
8286 }
8287 } else {
8288 sigma_dut_print(dut, DUT_MSG_ERROR,
8289 "MCS_FixedRate: HE MCS %d not supported",
8290 mcs);
8291 }
8292#else /* NL80211_SUPPORT */
8293 sigma_dut_print(dut, DUT_MSG_ERROR,
8294 "MCS_FixedRate cannot be changed without NL80211_SUPPORT defined");
8295#endif /* NL80211_SUPPORT */
8296 }
8297
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008298 val = get_param(cmd, "opt_md_notif_ie");
8299 if (val) {
8300 char *result = NULL;
8301 char delim[] = ";";
8302 char token[30];
8303 int value, config_val = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308304 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008305
Peng Xub8fc5cc2017-05-10 17:27:28 -07008306 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308307 result = strtok_r(token, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008308
8309 /* Extract the NSS information */
8310 if (result) {
8311 value = atoi(result);
8312 switch (value) {
8313 case 1:
8314 config_val = 1;
8315 break;
8316 case 2:
8317 config_val = 3;
8318 break;
8319 case 3:
8320 config_val = 7;
8321 break;
8322 case 4:
8323 config_val = 15;
8324 break;
8325 default:
8326 config_val = 3;
8327 break;
8328 }
8329
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008330 run_iwpriv(dut, intf, "rxchainmask %d", config_val);
8331 run_iwpriv(dut, intf, "txchainmask %d", config_val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008332
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008333 }
8334
8335 /* Extract the channel width information */
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308336 result = strtok_r(NULL, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008337 if (result) {
8338 value = atoi(result);
8339 switch (value) {
8340 case 20:
8341 config_val = 0;
8342 break;
8343 case 40:
8344 config_val = 1;
8345 break;
8346 case 80:
8347 config_val = 2;
8348 break;
8349 case 160:
8350 config_val = 3;
8351 break;
8352 default:
8353 config_val = 2;
8354 break;
8355 }
8356
8357 dut->chwidth = config_val;
8358
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008359 run_iwpriv(dut, intf, "chwidth %d", config_val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008360 }
8361
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008362 run_iwpriv(dut, intf, "opmode_notify 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008363 }
8364
8365 val = get_param(cmd, "nss_mcs_cap");
8366 if (val) {
8367 int nss, mcs;
8368 char token[20];
8369 char *result = NULL;
8370 unsigned int vht_mcsmap = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308371 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008372
Peng Xub8fc5cc2017-05-10 17:27:28 -07008373 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308374 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05308375 if (!result) {
8376 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07008377 "NSS not specified");
8378 send_resp(dut, conn, SIGMA_ERROR,
8379 "errorCode,NSS not specified");
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05308380 return 0;
8381 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008382 nss = atoi(result);
8383
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008384 run_iwpriv(dut, intf, "nss %d", nss);
Arif Hussainac6c5112018-05-25 17:34:00 -07008385 dut->sta_nss = nss;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008386
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308387 result = strtok_r(NULL, ";", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008388 if (result == NULL) {
8389 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07008390 "MCS not specified");
8391 send_resp(dut, conn, SIGMA_ERROR,
8392 "errorCode,MCS not specified");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008393 return 0;
8394 }
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308395 result = strtok_r(result, "-", &saveptr);
8396 result = strtok_r(NULL, "-", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05308397 if (!result) {
8398 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07008399 "MCS not specified");
8400 send_resp(dut, conn, SIGMA_ERROR,
8401 "errorCode,MCS not specified");
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05308402 return 0;
8403 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008404 mcs = atoi(result);
8405
Arif Hussaina37e9552018-06-20 17:05:59 -07008406 if (program && strcasecmp(program, "HE") == 0) {
8407#ifdef NL80211_SUPPORT
8408 enum he_mcs_config mcs_config;
8409 int ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008410
Arif Hussaina37e9552018-06-20 17:05:59 -07008411 if (mcs >= 0 && mcs <= 7) {
8412 mcs_config = HE_80_MCS0_7;
8413 } else if (mcs > 7 && mcs <= 9) {
8414 mcs_config = HE_80_MCS0_9;
8415 } else if (mcs > 9 && mcs <= 11) {
8416 mcs_config = HE_80_MCS0_11;
8417 } else {
8418 sigma_dut_print(dut, DUT_MSG_ERROR,
8419 "nss_mcs_cap: HE: Invalid mcs: %d",
8420 mcs);
8421 send_resp(dut, conn, SIGMA_ERROR,
8422 "errorCode,Invalid MCS");
8423 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008424 }
Arif Hussaina37e9552018-06-20 17:05:59 -07008425
8426 ret = sta_set_he_mcs(dut, intf, mcs_config);
8427 if (ret) {
8428 sigma_dut_print(dut, DUT_MSG_ERROR,
8429 "nss_mcs_cap: HE: Setting of MCS failed, mcs_config: %d, ret: %d",
8430 mcs_config, ret);
8431 send_resp(dut, conn, SIGMA_ERROR,
8432 "errorCode,Failed to set MCS");
8433 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008434 }
Arif Hussaina37e9552018-06-20 17:05:59 -07008435#else /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008436 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07008437 "nss_mcs_cap: HE: MCS cannot be changed without NL80211_SUPPORT defined");
8438#endif /* NL80211_SUPPORT */
8439 } else {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008440 run_iwpriv(dut, intf, "vhtmcs %d", mcs);
Arif Hussaina37e9552018-06-20 17:05:59 -07008441
8442 switch (nss) {
8443 case 1:
8444 switch (mcs) {
8445 case 7:
8446 vht_mcsmap = 0xfffc;
8447 break;
8448 case 8:
8449 vht_mcsmap = 0xfffd;
8450 break;
8451 case 9:
8452 vht_mcsmap = 0xfffe;
8453 break;
8454 default:
8455 vht_mcsmap = 0xfffe;
8456 break;
8457 }
8458 break;
8459 case 2:
8460 switch (mcs) {
8461 case 7:
8462 vht_mcsmap = 0xfff0;
8463 break;
8464 case 8:
8465 vht_mcsmap = 0xfff5;
8466 break;
8467 case 9:
8468 vht_mcsmap = 0xfffa;
8469 break;
8470 default:
8471 vht_mcsmap = 0xfffa;
8472 break;
8473 }
8474 break;
8475 case 3:
8476 switch (mcs) {
8477 case 7:
8478 vht_mcsmap = 0xffc0;
8479 break;
8480 case 8:
8481 vht_mcsmap = 0xffd5;
8482 break;
8483 case 9:
8484 vht_mcsmap = 0xffea;
8485 break;
8486 default:
8487 vht_mcsmap = 0xffea;
8488 break;
8489 }
8490 break;
8491 default:
8492 vht_mcsmap = 0xffea;
8493 break;
8494 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008495 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008496 }
8497 }
8498
8499 /* UNSUPPORTED: val = get_param(cmd, "Tx_lgi_rate"); */
8500
8501 val = get_param(cmd, "Vht_tkip");
8502 if (val)
8503 tkip = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
8504
8505 val = get_param(cmd, "Vht_wep");
8506 if (val)
8507 wep = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
8508
8509 if (tkip != -1 || wep != -1) {
8510 if ((tkip == 1 && wep != 0) || (wep == 1 && tkip != 0)) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008511 run_iwpriv(dut, intf, "htweptkip 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008512 } else if ((tkip == 0 && wep != 1) || (wep == 0 && tkip != 1)) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008513 run_iwpriv(dut, intf, "htweptkip 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008514 } else {
8515 sigma_dut_print(dut, DUT_MSG_ERROR,
8516 "ErrorCode,mixed mode of VHT TKIP/WEP not supported");
8517 return 0;
8518 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008519 }
8520
Arif Hussain55f00da2018-07-03 08:28:26 -07008521 val = get_param(cmd, "txBandwidth");
8522 if (val) {
8523 switch (get_driver_type()) {
8524 case DRIVER_WCN:
8525 if (wcn_sta_set_width(dut, intf, val) < 0) {
8526 send_resp(dut, conn, SIGMA_ERROR,
8527 "ErrorCode,Failed to set txBandwidth");
8528 return 0;
8529 }
8530 break;
8531 case DRIVER_ATHEROS:
8532 if (ath_set_width(dut, conn, intf, val) < 0) {
8533 send_resp(dut, conn, SIGMA_ERROR,
8534 "ErrorCode,Failed to set txBandwidth");
8535 return 0;
8536 }
8537 break;
8538 default:
8539 sigma_dut_print(dut, DUT_MSG_ERROR,
8540 "Setting txBandwidth not supported");
8541 break;
8542 }
8543 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008544
Arif Hussain9765f7d2018-07-03 08:28:26 -07008545 val = get_param(cmd, "BeamformeeSTS");
8546 if (val) {
Kiran Kumar Lokerebc89d432018-07-10 12:20:13 -07008547 if (sta_set_tx_beamformee(dut, intf, 1)) {
8548 send_resp(dut, conn, SIGMA_ERROR,
8549 "ErrorCode,Failed to set TX beamformee enable");
8550 return 0;
8551 }
8552
Arif Hussain9765f7d2018-07-03 08:28:26 -07008553 if (sta_set_beamformee_sts(dut, intf, atoi(val))) {
8554 send_resp(dut, conn, SIGMA_ERROR,
8555 "ErrorCode,Failed to set BeamformeeSTS");
8556 return 0;
8557 }
8558 }
8559
Arif Hussain68d23f52018-07-11 13:39:08 -07008560 val = get_param(cmd, "Trig_MAC_Padding_Dur");
8561 if (val) {
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07008562#ifdef NL80211_SUPPORT
8563 enum qca_wlan_he_mac_padding_dur set_val;
8564
8565 switch (atoi(val)) {
8566 case 16:
8567 set_val = QCA_WLAN_HE_16US_OF_PROCESS_TIME;
8568 break;
8569 case 8:
8570 set_val = QCA_WLAN_HE_8US_OF_PROCESS_TIME;
8571 break;
8572 default:
8573 set_val = QCA_WLAN_HE_NO_ADDITIONAL_PROCESS_TIME;
8574 break;
8575 }
8576 if (sta_set_mac_padding_duration(dut, intf, set_val)) {
Arif Hussain68d23f52018-07-11 13:39:08 -07008577 send_resp(dut, conn, SIGMA_ERROR,
8578 "ErrorCode,Failed to set MAC padding duration");
8579 return 0;
8580 }
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07008581#else /* NL80211_SUPPORT */
8582 sigma_dut_print(dut, DUT_MSG_ERROR,
8583 "MAC padding duration cannot be changed without NL80211_SUPPORT defined");
8584#endif /* NL80211_SUPPORT */
Arif Hussain68d23f52018-07-11 13:39:08 -07008585 }
8586
Arif Hussain480d5f42019-03-12 14:40:42 -07008587 val = get_param(cmd, "TWT_ReqSupport");
8588 if (val) {
8589 int set_val;
8590
8591 if (strcasecmp(val, "Enable") == 0) {
8592 set_val = 1;
8593 } else if (strcasecmp(val, "Disable") == 0) {
8594 set_val = 0;
8595 } else {
8596 send_resp(dut, conn, SIGMA_ERROR,
8597 "ErrorCode,Invalid TWT_ReqSupport");
8598 return STATUS_SENT;
8599 }
8600
8601 if (sta_set_twt_req_support(dut, intf, set_val)) {
8602 sigma_dut_print(dut, DUT_MSG_ERROR,
8603 "Failed to set TWT req support %d",
8604 set_val);
8605 send_resp(dut, conn, SIGMA_ERROR,
8606 "ErrorCode,Failed to set TWT_ReqSupport");
8607 return STATUS_SENT;
8608 }
8609 }
8610
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07008611 val = get_param(cmd, "MU_EDCA");
8612 if (val && (strcasecmp(val, "Override") == 0)) {
8613 if (sta_set_mu_edca_override(dut, intf, 1)) {
8614 send_resp(dut, conn, SIGMA_ERROR,
8615 "ErrorCode,Failed to set MU EDCA override");
8616 return 0;
8617 }
8618 }
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -07008619
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07008620 val = get_param(cmd, "OMControl");
8621 if (val) {
8622 int set_val = 1;
8623
8624 if (strcasecmp(val, "Enable") == 0)
8625 set_val = 1;
8626 else if (strcasecmp(val, "Disable") == 0)
8627 set_val = 0;
8628
8629 if (sta_set_om_ctrl_supp(dut, intf, set_val)) {
8630 send_resp(dut, conn, SIGMA_ERROR,
8631 "ErrorCode,Failed to set OM ctrl supp");
8632 return 0;
8633 }
8634 }
8635
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -07008636 val = get_param(cmd, "ADDBAResp_BufSize");
8637 if (val) {
8638 int buf_size;
8639
8640 if (strcasecmp(val, "gt64") == 0)
8641 buf_size = 256;
8642 else
8643 buf_size = 64;
8644 if (get_driver_type() == DRIVER_WCN &&
8645 sta_set_addba_buf_size(dut, intf, buf_size)) {
8646 send_resp(dut, conn, SIGMA_ERROR,
8647 "ErrorCode,set addbaresp_buff_size failed");
8648 return 0;
8649 }
8650 }
8651
8652 val = get_param(cmd, "ADDBAReq_BufSize");
8653 if (val) {
8654 int buf_size;
8655
8656 if (strcasecmp(val, "gt64") == 0)
8657 buf_size = 256;
8658 else
8659 buf_size = 64;
8660 if (get_driver_type() == DRIVER_WCN &&
8661 sta_set_addba_buf_size(dut, intf, buf_size)) {
8662 send_resp(dut, conn, SIGMA_ERROR,
8663 "ErrorCode,set addbareq_buff_size failed");
8664 return 0;
8665 }
8666 }
8667
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008668 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
8669}
8670
8671
8672static int sta_set_wireless_60g(struct sigma_dut *dut,
8673 struct sigma_conn *conn,
8674 struct sigma_cmd *cmd)
8675{
8676 const char *dev_role = get_param(cmd, "DevRole");
8677
8678 if (!dev_role) {
8679 send_resp(dut, conn, SIGMA_INVALID,
8680 "ErrorCode,DevRole not specified");
8681 return 0;
8682 }
8683
8684 if (strcasecmp(dev_role, "PCP") == 0)
8685 return sta_set_60g_pcp(dut, conn, cmd);
8686 if (strcasecmp(dev_role, "STA") == 0)
8687 return sta_set_60g_sta(dut, conn, cmd);
8688 send_resp(dut, conn, SIGMA_INVALID,
8689 "ErrorCode,DevRole not supported");
8690 return 0;
8691}
8692
8693
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05308694static int sta_set_wireless_oce(struct sigma_dut *dut, struct sigma_conn *conn,
8695 struct sigma_cmd *cmd)
8696{
8697 int status;
8698 const char *intf = get_param(cmd, "Interface");
8699 const char *val = get_param(cmd, "DevRole");
8700
8701 if (val && strcasecmp(val, "STA-CFON") == 0) {
8702 status = sta_cfon_set_wireless(dut, conn, cmd);
8703 if (status)
8704 return status;
8705 }
8706 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
8707}
8708
8709
Jouni Malinenf7222712019-06-13 01:50:21 +03008710static enum sigma_cmd_result cmd_sta_set_wireless(struct sigma_dut *dut,
8711 struct sigma_conn *conn,
8712 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008713{
8714 const char *val;
8715
8716 val = get_param(cmd, "Program");
8717 if (val) {
8718 if (strcasecmp(val, "11n") == 0)
8719 return cmd_sta_set_11n(dut, conn, cmd);
Amarnath Hullur Subramanyam4f860292018-01-31 03:49:35 -08008720 if (strcasecmp(val, "VHT") == 0 || strcasecmp(val, "HE") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008721 return cmd_sta_set_wireless_vht(dut, conn, cmd);
8722 if (strcasecmp(val, "60ghz") == 0)
8723 return sta_set_wireless_60g(dut, conn, cmd);
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05308724 if (strcasecmp(val, "OCE") == 0)
8725 return sta_set_wireless_oce(dut, conn, cmd);
Alexei Avshalom Lazar66bb9972018-12-18 16:01:43 +02008726 /* sta_set_wireless in WPS program is only used for 60G */
8727 if (is_60g_sigma_dut(dut))
8728 return sta_set_wireless_60g(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008729 send_resp(dut, conn, SIGMA_ERROR,
8730 "ErrorCode,Program value not supported");
8731 } else {
8732 send_resp(dut, conn, SIGMA_ERROR,
8733 "ErrorCode,Program argument not available");
8734 }
8735
8736 return 0;
8737}
8738
8739
8740static void ath_sta_inject_frame(struct sigma_dut *dut, const char *intf,
8741 int tid)
8742{
8743 char buf[100];
8744 int tid_to_dscp [] = { 0x00, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0 };
8745
Pradeep Reddy POTTETId31d1322016-10-13 17:22:03 +05308746 if (tid < 0 ||
8747 tid >= (int) (sizeof(tid_to_dscp) / sizeof(tid_to_dscp[0]))) {
8748 sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported TID: %d", tid);
8749 return;
8750 }
8751
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008752 /*
8753 * Two ways to ensure that addba request with a
8754 * non zero TID could be sent out. EV 117296
8755 */
8756 snprintf(buf, sizeof(buf),
8757 "ping -c 8 -Q %d `arp -a | grep wlan0 | awk '{print $2}' | tr -d '()'`",
8758 tid);
8759 if (system(buf) != 0) {
8760 sigma_dut_print(dut, DUT_MSG_ERROR,
8761 "Ping did not send out");
8762 }
8763
8764 snprintf(buf, sizeof(buf),
8765 "iwconfig %s | grep Access | awk '{print $6}' > %s",
8766 intf, VI_QOS_TMP_FILE);
8767 if (system(buf) != 0)
8768 return;
8769
8770 snprintf(buf, sizeof(buf),
8771 "ifconfig %s | grep HWaddr | cut -b 39-56 >> %s",
8772 intf, VI_QOS_TMP_FILE);
8773 if (system(buf) != 0)
8774 sigma_dut_print(dut, DUT_MSG_ERROR, "HWaddr matching failed");
8775
8776 snprintf(buf,sizeof(buf), "sed -n '3,$p' %s >> %s",
8777 VI_QOS_REFFILE, VI_QOS_TMP_FILE);
8778 if (system(buf) != 0) {
8779 sigma_dut_print(dut, DUT_MSG_ERROR,
8780 "VI_QOS_TEMP_FILE generation error failed");
8781 }
8782 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
8783 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
8784 if (system(buf) != 0) {
8785 sigma_dut_print(dut, DUT_MSG_ERROR,
8786 "VI_QOS_FILE generation failed");
8787 }
8788
8789 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
8790 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
8791 if (system(buf) != 0) {
8792 sigma_dut_print(dut, DUT_MSG_ERROR,
8793 "VI_QOS_FILE generation failed");
8794 }
8795
8796 snprintf(buf, sizeof(buf), "ethinject %s %s", intf, VI_QOS_FILE);
8797 if (system(buf) != 0) {
8798 }
8799}
8800
8801
8802static int ath_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
8803 struct sigma_cmd *cmd)
8804{
8805 const char *intf = get_param(cmd, "Interface");
8806 const char *val;
8807 int tid = 0;
8808 char buf[100];
8809
8810 val = get_param(cmd, "TID");
8811 if (val) {
8812 tid = atoi(val);
8813 if (tid)
8814 ath_sta_inject_frame(dut, intf, tid);
8815 }
8816
8817 /* Command sequence for ADDBA request on Peregrine based devices */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008818 run_iwpriv(dut, intf, "setaddbaoper 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008819
8820 snprintf(buf, sizeof(buf), "wifitool %s senddelba 1 %d 1 4", intf, tid);
8821 if (system(buf) != 0) {
8822 sigma_dut_print(dut, DUT_MSG_ERROR,
8823 "wifitool senddelba failed");
8824 }
8825
8826 snprintf(buf, sizeof(buf), "wifitool %s sendaddba 1 %d 64", intf, tid);
8827 if (system(buf) != 0) {
8828 sigma_dut_print(dut, DUT_MSG_ERROR,
8829 "wifitool sendaddba failed");
8830 }
8831
8832 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
8833
8834 return 1;
8835}
8836
8837
Lior David9981b512017-01-20 13:16:40 +02008838#ifdef __linux__
8839
8840static int wil6210_send_addba(struct sigma_dut *dut, const char *dest_mac,
8841 int agg_size)
8842{
8843 char dir[128], buf[128];
8844 FILE *f;
8845 regex_t re;
8846 regmatch_t m[2];
Jouni Malinen3aa72862019-05-29 23:14:51 +03008847 int rc, ret = -1, vring_id, found, res;
Lior David9981b512017-01-20 13:16:40 +02008848
8849 if (wil6210_get_debugfs_dir(dut, dir, sizeof(dir))) {
8850 sigma_dut_print(dut, DUT_MSG_ERROR,
8851 "failed to get wil6210 debugfs dir");
8852 return -1;
8853 }
8854
Jouni Malinen3aa72862019-05-29 23:14:51 +03008855 res = snprintf(buf, sizeof(buf), "%s/vrings", dir);
8856 if (res < 0 || res >= sizeof(buf))
8857 return -1;
Lior David9981b512017-01-20 13:16:40 +02008858 f = fopen(buf, "r");
8859 if (!f) {
8860 sigma_dut_print(dut, DUT_MSG_ERROR, "failed to open: %s", buf);
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +02008861 /* newer wil6210 driver renamed file to "rings" */
Jouni Malinen3aa72862019-05-29 23:14:51 +03008862 res = snprintf(buf, sizeof(buf), "%s/rings", dir);
8863 if (res < 0 || res >= sizeof(buf))
8864 return -1;
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +02008865 f = fopen(buf, "r");
8866 if (!f) {
8867 sigma_dut_print(dut, DUT_MSG_ERROR,
8868 "failed to open: %s", buf);
8869 return -1;
8870 }
Lior David9981b512017-01-20 13:16:40 +02008871 }
8872
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +02008873 /* can be either VRING tx... or RING... */
8874 if (regcomp(&re, "RING tx_[ \t]*([0-9]+)", REG_EXTENDED)) {
Lior David9981b512017-01-20 13:16:40 +02008875 sigma_dut_print(dut, DUT_MSG_ERROR, "regcomp failed");
8876 goto out;
8877 }
8878
8879 /* find TX VRING for the mac address */
8880 found = 0;
8881 while (fgets(buf, sizeof(buf), f)) {
8882 if (strcasestr(buf, dest_mac)) {
8883 found = 1;
8884 break;
8885 }
8886 }
8887
8888 if (!found) {
8889 sigma_dut_print(dut, DUT_MSG_ERROR,
8890 "no TX VRING for %s", dest_mac);
8891 goto out;
8892 }
8893
8894 /* extract VRING ID, "VRING tx_<id> = {" */
8895 if (!fgets(buf, sizeof(buf), f)) {
8896 sigma_dut_print(dut, DUT_MSG_ERROR,
8897 "no VRING start line for %s", dest_mac);
8898 goto out;
8899 }
8900
8901 rc = regexec(&re, buf, 2, m, 0);
8902 regfree(&re);
8903 if (rc || m[1].rm_so < 0) {
8904 sigma_dut_print(dut, DUT_MSG_ERROR,
8905 "no VRING TX ID for %s", dest_mac);
8906 goto out;
8907 }
8908 buf[m[1].rm_eo] = 0;
8909 vring_id = atoi(&buf[m[1].rm_so]);
8910
8911 /* send the addba command */
8912 fclose(f);
Jouni Malinen3aa72862019-05-29 23:14:51 +03008913 res = snprintf(buf, sizeof(buf), "%s/back", dir);
8914 if (res < 0 || res >= sizeof(buf))
8915 return -1;
Lior David9981b512017-01-20 13:16:40 +02008916 f = fopen(buf, "w");
8917 if (!f) {
8918 sigma_dut_print(dut, DUT_MSG_ERROR,
8919 "failed to open: %s", buf);
8920 return -1;
8921 }
8922
8923 fprintf(f, "add %d %d\n", vring_id, agg_size);
8924
8925 ret = 0;
8926
8927out:
8928 fclose(f);
8929
8930 return ret;
8931}
8932
8933
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +02008934int send_addba_60g(struct sigma_dut *dut, struct sigma_conn *conn,
8935 struct sigma_cmd *cmd, const char *mac_param)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008936{
8937 const char *val;
8938 int tid = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008939
8940 val = get_param(cmd, "TID");
8941 if (val) {
8942 tid = atoi(val);
8943 if (tid != 0) {
8944 sigma_dut_print(dut, DUT_MSG_ERROR,
8945 "Ignore TID %d for send_addba use TID 0 for 60g since only 0 required on TX",
8946 tid);
8947 }
8948 }
8949
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +02008950 val = get_param(cmd, mac_param);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008951 if (!val) {
8952 sigma_dut_print(dut, DUT_MSG_ERROR,
8953 "Currently not supporting addba for 60G without Dest_mac");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02008954 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008955 }
8956
Lior David9981b512017-01-20 13:16:40 +02008957 if (wil6210_send_addba(dut, val, dut->back_rcv_buf))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008958 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008959
8960 return 1;
8961}
8962
Lior David9981b512017-01-20 13:16:40 +02008963#endif /* __linux__ */
8964
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008965
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08008966static int wcn_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
8967 struct sigma_cmd *cmd)
8968{
8969#ifdef NL80211_SUPPORT
8970 const char *intf = get_param(cmd, "Interface");
8971 const char *val;
8972 int tid = -1;
8973 int bufsize = 64;
8974 struct nl_msg *msg;
8975 int ret = 0;
8976 struct nlattr *params;
8977 int ifindex;
8978
8979 val = get_param(cmd, "TID");
8980 if (val)
8981 tid = atoi(val);
8982
8983 if (tid == -1) {
8984 send_resp(dut, conn, SIGMA_ERROR,
8985 "ErrorCode,sta_send_addba tid invalid");
8986 return 0;
8987 }
8988
8989 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
8990
8991 ifindex = if_nametoindex(intf);
8992 if (ifindex == 0) {
8993 sigma_dut_print(dut, DUT_MSG_ERROR,
8994 "%s: Index for interface %s failed",
8995 __func__, intf);
8996 send_resp(dut, conn, SIGMA_ERROR,
8997 "ErrorCode,sta_send_addba interface invalid");
8998 return 0;
8999 }
9000
9001 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
9002 NL80211_CMD_VENDOR)) ||
9003 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
9004 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
9005 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
9006 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
9007 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
9008 nla_put_u8(msg,
9009 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADD_DEL_BA_SESSION,
9010 QCA_WLAN_ADD_BA) ||
9011 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BA_TID,
9012 tid) ||
Kiran Kumar Lokere26e27582018-08-01 16:18:34 -07009013 nla_put_u16(msg,
9014 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE,
9015 bufsize)) {
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009016 sigma_dut_print(dut, DUT_MSG_ERROR,
9017 "%s: err in adding vendor_cmd and vendor_data",
9018 __func__);
9019 nlmsg_free(msg);
9020 send_resp(dut, conn, SIGMA_ERROR,
9021 "ErrorCode,sta_send_addba err in adding vendor_cmd and vendor_data");
9022 return 0;
9023 }
9024 nla_nest_end(msg, params);
9025
9026 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
9027 if (ret) {
9028 sigma_dut_print(dut, DUT_MSG_ERROR,
9029 "%s: err in send_and_recv_msgs, ret=%d",
9030 __func__, ret);
Sunil Dutt30605592018-05-04 20:35:50 +05309031 if (ret == -EOPNOTSUPP)
9032 return 1;
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009033 send_resp(dut, conn, SIGMA_ERROR,
9034 "ErrorCode,sta_send_addba err in send_and_recv_msgs");
9035 return 0;
9036 }
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009037#else /* NL80211_SUPPORT */
9038 sigma_dut_print(dut, DUT_MSG_ERROR,
9039 "sta_send_addba not supported without NL80211_SUPPORT defined");
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009040#endif /* NL80211_SUPPORT */
Sunil Dutt30605592018-05-04 20:35:50 +05309041
9042 return 1;
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009043}
9044
9045
Jouni Malinenf7222712019-06-13 01:50:21 +03009046static enum sigma_cmd_result cmd_sta_send_addba(struct sigma_dut *dut,
9047 struct sigma_conn *conn,
9048 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009049{
9050 switch (get_driver_type()) {
9051 case DRIVER_ATHEROS:
9052 return ath_sta_send_addba(dut, conn, cmd);
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009053 case DRIVER_WCN:
9054 return wcn_sta_send_addba(dut, conn, cmd);
Lior David9981b512017-01-20 13:16:40 +02009055#ifdef __linux__
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009056 case DRIVER_WIL6210:
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +02009057 return send_addba_60g(dut, conn, cmd, "Dest_mac");
Lior David9981b512017-01-20 13:16:40 +02009058#endif /* __linux__ */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009059 default:
9060 /*
9061 * There is no driver specific implementation for other drivers.
9062 * Ignore the command and report COMPLETE since the following
9063 * throughput test operation will end up sending ADDBA anyway.
9064 */
9065 return 1;
9066 }
9067}
9068
9069
9070int inject_eth_frame(int s, const void *data, size_t len,
9071 unsigned short ethtype, char *dst, char *src)
9072{
9073 struct iovec iov[4] = {
9074 {
9075 .iov_base = dst,
9076 .iov_len = ETH_ALEN,
9077 },
9078 {
9079 .iov_base = src,
9080 .iov_len = ETH_ALEN,
9081 },
9082 {
9083 .iov_base = &ethtype,
9084 .iov_len = sizeof(unsigned short),
9085 },
9086 {
9087 .iov_base = (void *) data,
9088 .iov_len = len,
9089 }
9090 };
9091 struct msghdr msg = {
9092 .msg_name = NULL,
9093 .msg_namelen = 0,
9094 .msg_iov = iov,
9095 .msg_iovlen = 4,
9096 .msg_control = NULL,
9097 .msg_controllen = 0,
9098 .msg_flags = 0,
9099 };
9100
9101 return sendmsg(s, &msg, 0);
9102}
9103
9104#if defined(__linux__) || defined(__QNXNTO__)
9105
9106int inject_frame(int s, const void *data, size_t len, int encrypt)
9107{
9108#define IEEE80211_RADIOTAP_F_WEP 0x04
9109#define IEEE80211_RADIOTAP_F_FRAG 0x08
9110 unsigned char rtap_hdr[] = {
9111 0x00, 0x00, /* radiotap version */
9112 0x0e, 0x00, /* radiotap length */
9113 0x02, 0xc0, 0x00, 0x00, /* bmap: flags, tx and rx flags */
9114 IEEE80211_RADIOTAP_F_FRAG, /* F_FRAG (fragment if required) */
9115 0x00, /* padding */
9116 0x00, 0x00, /* RX and TX flags to indicate that */
9117 0x00, 0x00, /* this is the injected frame directly */
9118 };
9119 struct iovec iov[2] = {
9120 {
9121 .iov_base = &rtap_hdr,
9122 .iov_len = sizeof(rtap_hdr),
9123 },
9124 {
9125 .iov_base = (void *) data,
9126 .iov_len = len,
9127 }
9128 };
9129 struct msghdr msg = {
9130 .msg_name = NULL,
9131 .msg_namelen = 0,
9132 .msg_iov = iov,
9133 .msg_iovlen = 2,
9134 .msg_control = NULL,
9135 .msg_controllen = 0,
9136 .msg_flags = 0,
9137 };
9138
9139 if (encrypt)
9140 rtap_hdr[8] |= IEEE80211_RADIOTAP_F_WEP;
9141
9142 return sendmsg(s, &msg, 0);
9143}
9144
9145
9146int open_monitor(const char *ifname)
9147{
9148#ifdef __QNXNTO__
9149 struct sockaddr_dl ll;
9150 int s;
9151
9152 memset(&ll, 0, sizeof(ll));
9153 ll.sdl_family = AF_LINK;
9154 ll.sdl_index = if_nametoindex(ifname);
9155 if (ll.sdl_index == 0) {
9156 perror("if_nametoindex");
9157 return -1;
9158 }
9159 s = socket(PF_INET, SOCK_RAW, 0);
9160#else /* __QNXNTO__ */
9161 struct sockaddr_ll ll;
9162 int s;
9163
9164 memset(&ll, 0, sizeof(ll));
9165 ll.sll_family = AF_PACKET;
9166 ll.sll_ifindex = if_nametoindex(ifname);
9167 if (ll.sll_ifindex == 0) {
9168 perror("if_nametoindex");
9169 return -1;
9170 }
9171 s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
9172#endif /* __QNXNTO__ */
9173 if (s < 0) {
9174 perror("socket[PF_PACKET,SOCK_RAW]");
9175 return -1;
9176 }
9177
9178 if (bind(s, (struct sockaddr *) &ll, sizeof(ll)) < 0) {
9179 perror("monitor socket bind");
9180 close(s);
9181 return -1;
9182 }
9183
9184 return s;
9185}
9186
9187
9188static int hex2num(char c)
9189{
9190 if (c >= '0' && c <= '9')
9191 return c - '0';
9192 if (c >= 'a' && c <= 'f')
9193 return c - 'a' + 10;
9194 if (c >= 'A' && c <= 'F')
9195 return c - 'A' + 10;
9196 return -1;
9197}
9198
9199
9200int hwaddr_aton(const char *txt, unsigned char *addr)
9201{
9202 int i;
9203
9204 for (i = 0; i < 6; i++) {
9205 int a, b;
9206
9207 a = hex2num(*txt++);
9208 if (a < 0)
9209 return -1;
9210 b = hex2num(*txt++);
9211 if (b < 0)
9212 return -1;
9213 *addr++ = (a << 4) | b;
9214 if (i < 5 && *txt++ != ':')
9215 return -1;
9216 }
9217
9218 return 0;
9219}
9220
9221#endif /* defined(__linux__) || defined(__QNXNTO__) */
9222
9223enum send_frame_type {
9224 DISASSOC, DEAUTH, SAQUERY, AUTH, ASSOCREQ, REASSOCREQ, DLS_REQ
9225};
9226enum send_frame_protection {
9227 CORRECT_KEY, INCORRECT_KEY, UNPROTECTED
9228};
9229
9230
9231static int sta_inject_frame(struct sigma_dut *dut, struct sigma_conn *conn,
9232 enum send_frame_type frame,
9233 enum send_frame_protection protected,
9234 const char *dest)
9235{
9236#ifdef __linux__
9237 unsigned char buf[1000], *pos;
9238 int s, res;
9239 char bssid[20], addr[20];
9240 char result[32], ssid[100];
9241 size_t ssid_len;
9242
9243 if (get_wpa_status(get_station_ifname(), "wpa_state", result,
9244 sizeof(result)) < 0 ||
9245 strncmp(result, "COMPLETED", 9) != 0) {
9246 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Not connected");
9247 return 0;
9248 }
9249
9250 if (get_wpa_status(get_station_ifname(), "bssid", bssid, sizeof(bssid))
9251 < 0) {
9252 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
9253 "current BSSID");
9254 return 0;
9255 }
9256
9257 if (get_wpa_status(get_station_ifname(), "address", addr, sizeof(addr))
9258 < 0) {
9259 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
9260 "own MAC address");
9261 return 0;
9262 }
9263
9264 if (get_wpa_status(get_station_ifname(), "ssid", ssid, sizeof(ssid))
9265 < 0) {
9266 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
9267 "current SSID");
9268 return 0;
9269 }
9270 ssid_len = strlen(ssid);
9271
9272 pos = buf;
9273
9274 /* Frame Control */
9275 switch (frame) {
9276 case DISASSOC:
9277 *pos++ = 0xa0;
9278 break;
9279 case DEAUTH:
9280 *pos++ = 0xc0;
9281 break;
9282 case SAQUERY:
9283 *pos++ = 0xd0;
9284 break;
9285 case AUTH:
9286 *pos++ = 0xb0;
9287 break;
9288 case ASSOCREQ:
9289 *pos++ = 0x00;
9290 break;
9291 case REASSOCREQ:
9292 *pos++ = 0x20;
9293 break;
9294 case DLS_REQ:
9295 *pos++ = 0xd0;
9296 break;
9297 }
9298
9299 if (protected == INCORRECT_KEY)
9300 *pos++ = 0x40; /* Set Protected field to 1 */
9301 else
9302 *pos++ = 0x00;
9303
9304 /* Duration */
9305 *pos++ = 0x00;
9306 *pos++ = 0x00;
9307
9308 /* addr1 = DA (current AP) */
9309 hwaddr_aton(bssid, pos);
9310 pos += 6;
9311 /* addr2 = SA (own address) */
9312 hwaddr_aton(addr, pos);
9313 pos += 6;
9314 /* addr3 = BSSID (current AP) */
9315 hwaddr_aton(bssid, pos);
9316 pos += 6;
9317
9318 /* Seq# (to be filled by driver/mac80211) */
9319 *pos++ = 0x00;
9320 *pos++ = 0x00;
9321
9322 if (protected == INCORRECT_KEY) {
9323 /* CCMP parameters */
9324 memcpy(pos, "\x61\x01\x00\x20\x00\x10\x00\x00", 8);
9325 pos += 8;
9326 }
9327
9328 if (protected == INCORRECT_KEY) {
9329 switch (frame) {
9330 case DEAUTH:
9331 /* Reason code (encrypted) */
9332 memcpy(pos, "\xa7\x39", 2);
9333 pos += 2;
9334 break;
9335 case DISASSOC:
9336 /* Reason code (encrypted) */
9337 memcpy(pos, "\xa7\x39", 2);
9338 pos += 2;
9339 break;
9340 case SAQUERY:
9341 /* Category|Action|TransID (encrypted) */
9342 memcpy(pos, "\x6f\xbd\xe9\x4d", 4);
9343 pos += 4;
9344 break;
9345 default:
9346 return -1;
9347 }
9348
9349 /* CCMP MIC */
9350 memcpy(pos, "\xc8\xd8\x3b\x06\x5d\xb7\x25\x68", 8);
9351 pos += 8;
9352 } else {
9353 switch (frame) {
9354 case DEAUTH:
9355 /* reason code = 8 */
9356 *pos++ = 0x08;
9357 *pos++ = 0x00;
9358 break;
9359 case DISASSOC:
9360 /* reason code = 8 */
9361 *pos++ = 0x08;
9362 *pos++ = 0x00;
9363 break;
9364 case SAQUERY:
9365 /* Category - SA Query */
9366 *pos++ = 0x08;
9367 /* SA query Action - Request */
9368 *pos++ = 0x00;
9369 /* Transaction ID */
9370 *pos++ = 0x12;
9371 *pos++ = 0x34;
9372 break;
9373 case AUTH:
9374 /* Auth Alg (Open) */
9375 *pos++ = 0x00;
9376 *pos++ = 0x00;
9377 /* Seq# */
9378 *pos++ = 0x01;
9379 *pos++ = 0x00;
9380 /* Status code */
9381 *pos++ = 0x00;
9382 *pos++ = 0x00;
9383 break;
9384 case ASSOCREQ:
9385 /* Capability Information */
9386 *pos++ = 0x31;
9387 *pos++ = 0x04;
9388 /* Listen Interval */
9389 *pos++ = 0x0a;
9390 *pos++ = 0x00;
9391 /* SSID */
9392 *pos++ = 0x00;
9393 *pos++ = ssid_len;
9394 memcpy(pos, ssid, ssid_len);
9395 pos += ssid_len;
9396 /* Supported Rates */
9397 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
9398 10);
9399 pos += 10;
9400 /* Extended Supported Rates */
9401 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
9402 pos += 6;
9403 /* RSN */
9404 memcpy(pos, "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00"
9405 "\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x02\xc0"
9406 "\x00\x00\x00\x00\x0f\xac\x06", 28);
9407 pos += 28;
9408 break;
9409 case REASSOCREQ:
9410 /* Capability Information */
9411 *pos++ = 0x31;
9412 *pos++ = 0x04;
9413 /* Listen Interval */
9414 *pos++ = 0x0a;
9415 *pos++ = 0x00;
9416 /* Current AP */
9417 hwaddr_aton(bssid, pos);
9418 pos += 6;
9419 /* SSID */
9420 *pos++ = 0x00;
9421 *pos++ = ssid_len;
9422 memcpy(pos, ssid, ssid_len);
9423 pos += ssid_len;
9424 /* Supported Rates */
9425 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
9426 10);
9427 pos += 10;
9428 /* Extended Supported Rates */
9429 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
9430 pos += 6;
9431 /* RSN */
9432 memcpy(pos, "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00"
9433 "\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x02\xc0"
9434 "\x00\x00\x00\x00\x0f\xac\x06", 28);
9435 pos += 28;
9436 break;
9437 case DLS_REQ:
9438 /* Category - DLS */
9439 *pos++ = 0x02;
9440 /* DLS Action - Request */
9441 *pos++ = 0x00;
9442 /* Destination MACAddress */
9443 if (dest)
9444 hwaddr_aton(dest, pos);
9445 else
9446 memset(pos, 0, 6);
9447 pos += 6;
9448 /* Source MACAddress */
9449 hwaddr_aton(addr, pos);
9450 pos += 6;
9451 /* Capability Information */
9452 *pos++ = 0x10; /* Privacy */
9453 *pos++ = 0x06; /* QoS */
9454 /* DLS Timeout Value */
9455 *pos++ = 0x00;
9456 *pos++ = 0x01;
9457 /* Supported rates */
9458 *pos++ = 0x01;
9459 *pos++ = 0x08;
9460 *pos++ = 0x0c; /* 6 Mbps */
9461 *pos++ = 0x12; /* 9 Mbps */
9462 *pos++ = 0x18; /* 12 Mbps */
9463 *pos++ = 0x24; /* 18 Mbps */
9464 *pos++ = 0x30; /* 24 Mbps */
9465 *pos++ = 0x48; /* 36 Mbps */
9466 *pos++ = 0x60; /* 48 Mbps */
9467 *pos++ = 0x6c; /* 54 Mbps */
9468 /* TODO: Extended Supported Rates */
9469 /* TODO: HT Capabilities */
9470 break;
9471 }
9472 }
9473
9474 s = open_monitor("sigmadut");
9475 if (s < 0) {
9476 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
9477 "monitor socket");
9478 return 0;
9479 }
9480
9481 res = inject_frame(s, buf, pos - buf, protected == CORRECT_KEY);
9482 if (res < 0) {
9483 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
9484 "inject frame");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05309485 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009486 return 0;
9487 }
9488 if (res < pos - buf) {
9489 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Only partial "
9490 "frame sent");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05309491 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009492 return 0;
9493 }
9494
9495 close(s);
9496
9497 return 1;
9498#else /* __linux__ */
9499 send_resp(dut, conn, SIGMA_ERROR, "errorCode,sta_send_frame not "
9500 "yet supported");
9501 return 0;
9502#endif /* __linux__ */
9503}
9504
9505
9506static int cmd_sta_send_frame_tdls(struct sigma_dut *dut,
9507 struct sigma_conn *conn,
9508 struct sigma_cmd *cmd)
9509{
9510 const char *intf = get_param(cmd, "Interface");
9511 const char *sta, *val;
9512 unsigned char addr[ETH_ALEN];
9513 char buf[100];
9514
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +03009515 if (!intf)
9516 return -1;
9517
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009518 sta = get_param(cmd, "peer");
9519 if (sta == NULL)
9520 sta = get_param(cmd, "station");
9521 if (sta == NULL) {
9522 send_resp(dut, conn, SIGMA_ERROR,
9523 "ErrorCode,Missing peer address");
9524 return 0;
9525 }
9526 if (hwaddr_aton(sta, addr) < 0) {
9527 send_resp(dut, conn, SIGMA_ERROR,
9528 "ErrorCode,Invalid peer address");
9529 return 0;
9530 }
9531
9532 val = get_param(cmd, "type");
9533 if (val == NULL)
9534 return -1;
9535
9536 if (strcasecmp(val, "DISCOVERY") == 0) {
9537 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", sta);
9538 if (wpa_command(intf, buf) < 0) {
9539 send_resp(dut, conn, SIGMA_ERROR,
9540 "ErrorCode,Failed to send TDLS discovery");
9541 return 0;
9542 }
9543 return 1;
9544 }
9545
9546 if (strcasecmp(val, "SETUP") == 0) {
9547 int status = 0, timeout = 0;
9548
9549 val = get_param(cmd, "Status");
9550 if (val)
9551 status = atoi(val);
9552
9553 val = get_param(cmd, "Timeout");
9554 if (val)
9555 timeout = atoi(val);
9556
9557 if (status != 0 && status != 37) {
9558 send_resp(dut, conn, SIGMA_ERROR,
9559 "ErrorCode,Unsupported status value");
9560 return 0;
9561 }
9562
9563 if (timeout != 0 && timeout != 301) {
9564 send_resp(dut, conn, SIGMA_ERROR,
9565 "ErrorCode,Unsupported timeout value");
9566 return 0;
9567 }
9568
9569 if (status && timeout) {
9570 send_resp(dut, conn, SIGMA_ERROR,
9571 "ErrorCode,Unsupported timeout+status "
9572 "combination");
9573 return 0;
9574 }
9575
9576 if (status == 37 &&
9577 wpa_command(intf, "SET tdls_testing 0x200")) {
9578 send_resp(dut, conn, SIGMA_ERROR,
9579 "ErrorCode,Failed to enable "
9580 "decline setup response test mode");
9581 return 0;
9582 }
9583
9584 if (timeout == 301) {
9585 int res;
9586 if (dut->no_tpk_expiration)
9587 res = wpa_command(intf,
9588 "SET tdls_testing 0x108");
9589 else
9590 res = wpa_command(intf,
9591 "SET tdls_testing 0x8");
9592 if (res) {
9593 send_resp(dut, conn, SIGMA_ERROR,
9594 "ErrorCode,Failed to set short TPK "
9595 "lifetime");
9596 return 0;
9597 }
9598 }
9599
9600 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", sta);
9601 if (wpa_command(intf, buf) < 0) {
9602 send_resp(dut, conn, SIGMA_ERROR,
9603 "ErrorCode,Failed to send TDLS setup");
9604 return 0;
9605 }
9606 return 1;
9607 }
9608
9609 if (strcasecmp(val, "TEARDOWN") == 0) {
9610 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", sta);
9611 if (wpa_command(intf, buf) < 0) {
9612 send_resp(dut, conn, SIGMA_ERROR,
9613 "ErrorCode,Failed to send TDLS teardown");
9614 return 0;
9615 }
9616 return 1;
9617 }
9618
9619 send_resp(dut, conn, SIGMA_ERROR,
9620 "ErrorCode,Unsupported TDLS frame");
9621 return 0;
9622}
9623
9624
9625static int sta_ap_known(const char *ifname, const char *bssid)
9626{
9627 char buf[4096];
9628
Jouni Malinendd32f192018-09-15 02:55:19 +03009629 snprintf(buf, sizeof(buf), "BSS MASK=1 %s", bssid);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009630 if (wpa_command_resp(ifname, buf, buf, sizeof(buf)) < 0)
9631 return 0;
9632 if (strncmp(buf, "id=", 3) != 0)
9633 return 0;
9634 return 1;
9635}
9636
9637
9638static int sta_scan_ap(struct sigma_dut *dut, const char *ifname,
9639 const char *bssid)
9640{
9641 int res;
9642 struct wpa_ctrl *ctrl;
9643 char buf[256];
9644
9645 if (sta_ap_known(ifname, bssid))
9646 return 0;
9647 sigma_dut_print(dut, DUT_MSG_DEBUG,
9648 "AP not in BSS table - start scan");
9649
9650 ctrl = open_wpa_mon(ifname);
9651 if (ctrl == NULL) {
9652 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
9653 "wpa_supplicant monitor connection");
9654 return -1;
9655 }
9656
9657 if (wpa_command(ifname, "SCAN") < 0) {
9658 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to start scan");
9659 wpa_ctrl_detach(ctrl);
9660 wpa_ctrl_close(ctrl);
9661 return -1;
9662 }
9663
9664 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
9665 buf, sizeof(buf));
9666
9667 wpa_ctrl_detach(ctrl);
9668 wpa_ctrl_close(ctrl);
9669
9670 if (res < 0) {
9671 sigma_dut_print(dut, DUT_MSG_INFO, "Scan did not complete");
9672 return -1;
9673 }
9674
9675 if (sta_ap_known(ifname, bssid))
9676 return 0;
9677 sigma_dut_print(dut, DUT_MSG_INFO, "AP not in BSS table");
9678 return -1;
9679}
9680
9681
9682static int cmd_sta_send_frame_hs2_neighadv(struct sigma_dut *dut,
9683 struct sigma_conn *conn,
9684 struct sigma_cmd *cmd,
9685 const char *intf)
9686{
9687 char buf[200];
9688
9689 snprintf(buf, sizeof(buf), "ndsend 2001:DB8::1 %s", intf);
9690 if (system(buf) != 0) {
9691 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Failed to run "
9692 "ndsend");
9693 return 0;
9694 }
9695
9696 return 1;
9697}
9698
9699
9700static int cmd_sta_send_frame_hs2_neighsolreq(struct sigma_dut *dut,
9701 struct sigma_conn *conn,
9702 struct sigma_cmd *cmd,
9703 const char *intf)
9704{
9705 char buf[200];
9706 const char *ip = get_param(cmd, "SenderIP");
9707
Peng Xu26b356d2017-10-04 17:58:16 -07009708 if (!ip)
9709 return 0;
9710
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009711 snprintf(buf, sizeof(buf), "ndisc6 -nm %s %s -r 4", ip, intf);
9712 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
9713 if (system(buf) == 0) {
9714 sigma_dut_print(dut, DUT_MSG_INFO,
9715 "Neighbor Solicitation got a response "
9716 "for %s@%s", ip, intf);
9717 }
9718
9719 return 1;
9720}
9721
9722
9723static int cmd_sta_send_frame_hs2_arpprobe(struct sigma_dut *dut,
9724 struct sigma_conn *conn,
9725 struct sigma_cmd *cmd,
9726 const char *ifname)
9727{
9728 char buf[200];
9729 const char *ip = get_param(cmd, "SenderIP");
9730
9731 if (ip == NULL) {
9732 send_resp(dut, conn, SIGMA_ERROR,
9733 "ErrorCode,Missing SenderIP parameter");
9734 return 0;
9735 }
9736 snprintf(buf, sizeof(buf), "arping -I %s -D %s -c 4", ifname, ip);
9737 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
9738 if (system(buf) != 0) {
9739 sigma_dut_print(dut, DUT_MSG_INFO, "arping DAD got a response "
9740 "for %s@%s", ip, ifname);
9741 }
9742
9743 return 1;
9744}
9745
9746
9747static int cmd_sta_send_frame_hs2_arpannounce(struct sigma_dut *dut,
9748 struct sigma_conn *conn,
9749 struct sigma_cmd *cmd,
9750 const char *ifname)
9751{
9752 char buf[200];
9753 char ip[16];
9754 int s;
Peng Xub3756882017-10-04 14:39:09 -07009755 struct ifreq ifr;
9756 struct sockaddr_in saddr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009757
9758 s = socket(PF_INET, SOCK_DGRAM, 0);
Peng Xub3756882017-10-04 14:39:09 -07009759 if (s < 0) {
9760 perror("socket");
9761 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009762 }
9763
Peng Xub3756882017-10-04 14:39:09 -07009764 memset(&ifr, 0, sizeof(ifr));
9765 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
9766 if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
9767 sigma_dut_print(dut, DUT_MSG_INFO,
9768 "Failed to get %s IP address: %s",
9769 ifname, strerror(errno));
9770 close(s);
9771 return -1;
9772 }
9773 close(s);
9774
9775 memcpy(&saddr, &ifr.ifr_addr, sizeof(struct sockaddr_in));
9776 strlcpy(ip, inet_ntoa(saddr.sin_addr), sizeof(ip));
9777
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009778 snprintf(buf, sizeof(buf), "arping -I %s -s %s %s -c 4", ifname, ip,
9779 ip);
9780 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
9781 if (system(buf) != 0) {
9782 }
9783
9784 return 1;
9785}
9786
9787
9788static int cmd_sta_send_frame_hs2_arpreply(struct sigma_dut *dut,
9789 struct sigma_conn *conn,
9790 struct sigma_cmd *cmd,
9791 const char *ifname)
9792{
9793 char buf[200], addr[20];
9794 char dst[ETH_ALEN], src[ETH_ALEN];
9795 short ethtype = htons(ETH_P_ARP);
9796 char *pos;
9797 int s, res;
9798 const char *val;
9799 struct sockaddr_in taddr;
9800
9801 val = get_param(cmd, "dest");
9802 if (val)
9803 hwaddr_aton(val, (unsigned char *) dst);
9804
9805 val = get_param(cmd, "DestIP");
9806 if (val)
9807 inet_aton(val, &taddr.sin_addr);
Peng Xu151c9e12017-10-04 14:39:09 -07009808 else
9809 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009810
9811 if (get_wpa_status(get_station_ifname(), "address", addr,
9812 sizeof(addr)) < 0)
9813 return -2;
9814 hwaddr_aton(addr, (unsigned char *) src);
9815
9816 pos = buf;
9817 *pos++ = 0x00;
9818 *pos++ = 0x01;
9819 *pos++ = 0x08;
9820 *pos++ = 0x00;
9821 *pos++ = 0x06;
9822 *pos++ = 0x04;
9823 *pos++ = 0x00;
9824 *pos++ = 0x02;
9825 memcpy(pos, src, ETH_ALEN);
9826 pos += ETH_ALEN;
9827 memcpy(pos, &taddr.sin_addr, 4);
9828 pos += 4;
9829 memcpy(pos, dst, ETH_ALEN);
9830 pos += ETH_ALEN;
9831 memcpy(pos, &taddr.sin_addr, 4);
9832 pos += 4;
9833
9834 s = open_monitor(get_station_ifname());
9835 if (s < 0) {
9836 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
9837 "monitor socket");
9838 return 0;
9839 }
9840
9841 res = inject_eth_frame(s, buf, pos - buf, ethtype, dst, src);
9842 if (res < 0) {
9843 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
9844 "inject frame");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05309845 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009846 return 0;
9847 }
9848
9849 close(s);
9850
9851 return 1;
9852}
9853
9854
9855static int cmd_sta_send_frame_hs2_dls_req(struct sigma_dut *dut,
9856 struct sigma_conn *conn,
9857 struct sigma_cmd *cmd,
9858 const char *intf, const char *dest)
9859{
9860 char buf[100];
9861
9862 if (if_nametoindex("sigmadut") == 0) {
9863 snprintf(buf, sizeof(buf),
9864 "iw dev %s interface add sigmadut type monitor",
9865 get_station_ifname());
9866 if (system(buf) != 0 ||
9867 if_nametoindex("sigmadut") == 0) {
9868 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
9869 "monitor interface with '%s'", buf);
9870 return -2;
9871 }
9872 }
9873
9874 if (system("ifconfig sigmadut up") != 0) {
9875 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
9876 "monitor interface up");
9877 return -2;
9878 }
9879
9880 return sta_inject_frame(dut, conn, DLS_REQ, UNPROTECTED, dest);
9881}
9882
9883
9884static int cmd_sta_send_frame_hs2(struct sigma_dut *dut,
9885 struct sigma_conn *conn,
9886 struct sigma_cmd *cmd)
9887{
9888 const char *intf = get_param(cmd, "Interface");
9889 const char *dest = get_param(cmd, "Dest");
9890 const char *type = get_param(cmd, "FrameName");
9891 const char *val;
9892 char buf[200], *pos, *end;
9893 int count, count2;
9894
9895 if (type == NULL)
9896 type = get_param(cmd, "Type");
9897
9898 if (intf == NULL || dest == NULL || type == NULL)
9899 return -1;
9900
9901 if (strcasecmp(type, "NeighAdv") == 0)
9902 return cmd_sta_send_frame_hs2_neighadv(dut, conn, cmd, intf);
9903
9904 if (strcasecmp(type, "NeighSolicitReq") == 0)
9905 return cmd_sta_send_frame_hs2_neighsolreq(dut, conn, cmd, intf);
9906
9907 if (strcasecmp(type, "ARPProbe") == 0)
9908 return cmd_sta_send_frame_hs2_arpprobe(dut, conn, cmd, intf);
9909
9910 if (strcasecmp(type, "ARPAnnounce") == 0)
9911 return cmd_sta_send_frame_hs2_arpannounce(dut, conn, cmd, intf);
9912
9913 if (strcasecmp(type, "ARPReply") == 0)
9914 return cmd_sta_send_frame_hs2_arpreply(dut, conn, cmd, intf);
9915
9916 if (strcasecmp(type, "DLS-request") == 0 ||
9917 strcasecmp(type, "DLSrequest") == 0)
9918 return cmd_sta_send_frame_hs2_dls_req(dut, conn, cmd, intf,
9919 dest);
9920
9921 if (strcasecmp(type, "ANQPQuery") != 0 &&
9922 strcasecmp(type, "Query") != 0) {
9923 send_resp(dut, conn, SIGMA_ERROR,
9924 "ErrorCode,Unsupported HS 2.0 send frame type");
9925 return 0;
9926 }
9927
9928 if (sta_scan_ap(dut, intf, dest) < 0) {
9929 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not find "
9930 "the requested AP");
9931 return 0;
9932 }
9933
9934 pos = buf;
9935 end = buf + sizeof(buf);
9936 count = 0;
9937 pos += snprintf(pos, end - pos, "ANQP_GET %s ", dest);
9938
9939 val = get_param(cmd, "ANQP_CAP_LIST");
9940 if (val && atoi(val)) {
9941 pos += snprintf(pos, end - pos, "%s257", count > 0 ? "," : "");
9942 count++;
9943 }
9944
9945 val = get_param(cmd, "VENUE_NAME");
9946 if (val && atoi(val)) {
9947 pos += snprintf(pos, end - pos, "%s258", count > 0 ? "," : "");
9948 count++;
9949 }
9950
9951 val = get_param(cmd, "NETWORK_AUTH_TYPE");
9952 if (val && atoi(val)) {
9953 pos += snprintf(pos, end - pos, "%s260", count > 0 ? "," : "");
9954 count++;
9955 }
9956
9957 val = get_param(cmd, "ROAMING_CONS");
9958 if (val && atoi(val)) {
9959 pos += snprintf(pos, end - pos, "%s261", count > 0 ? "," : "");
9960 count++;
9961 }
9962
9963 val = get_param(cmd, "IP_ADDR_TYPE_AVAILABILITY");
9964 if (val && atoi(val)) {
9965 pos += snprintf(pos, end - pos, "%s262", count > 0 ? "," : "");
9966 count++;
9967 }
9968
9969 val = get_param(cmd, "NAI_REALM_LIST");
9970 if (val && atoi(val)) {
9971 pos += snprintf(pos, end - pos, "%s263", count > 0 ? "," : "");
9972 count++;
9973 }
9974
9975 val = get_param(cmd, "3GPP_INFO");
9976 if (val && atoi(val)) {
9977 pos += snprintf(pos, end - pos, "%s264", count > 0 ? "," : "");
9978 count++;
9979 }
9980
9981 val = get_param(cmd, "DOMAIN_LIST");
9982 if (val && atoi(val)) {
9983 pos += snprintf(pos, end - pos, "%s268", count > 0 ? "," : "");
9984 count++;
9985 }
9986
Jouni Malinen34cf9532018-04-29 19:26:33 +03009987 val = get_param(cmd, "Venue_URL");
9988 if (val && atoi(val)) {
9989 pos += snprintf(pos, end - pos, "%s277", count > 0 ? "," : "");
9990 count++;
9991 }
9992
Jouni Malinend3bca5d2018-04-29 17:25:23 +03009993 val = get_param(cmd, "Advice_Of_Charge");
9994 if (val && atoi(val)) {
9995 pos += snprintf(pos, end - pos, "%s278", count > 0 ? "," : "");
9996 count++;
9997 }
9998
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009999 if (count && wpa_command(intf, buf)) {
10000 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,ANQP_GET failed");
10001 return 0;
10002 }
10003
10004 pos = buf;
10005 end = buf + sizeof(buf);
10006 count2 = 0;
10007 pos += snprintf(pos, end - pos, "HS20_ANQP_GET %s ", dest);
10008
10009 val = get_param(cmd, "HS_CAP_LIST");
10010 if (val && atoi(val)) {
10011 pos += snprintf(pos, end - pos, "%s2", count2 > 0 ? "," : "");
10012 count2++;
10013 }
10014
10015 val = get_param(cmd, "OPER_NAME");
10016 if (val && atoi(val)) {
10017 pos += snprintf(pos, end - pos, "%s3", count2 > 0 ? "," : "");
10018 count2++;
10019 }
10020
10021 val = get_param(cmd, "WAN_METRICS");
10022 if (!val)
10023 val = get_param(cmd, "WAN_MAT");
10024 if (!val)
10025 val = get_param(cmd, "WAN_MET");
10026 if (val && atoi(val)) {
10027 pos += snprintf(pos, end - pos, "%s4", count2 > 0 ? "," : "");
10028 count2++;
10029 }
10030
10031 val = get_param(cmd, "CONNECTION_CAPABILITY");
10032 if (val && atoi(val)) {
10033 pos += snprintf(pos, end - pos, "%s5", count2 > 0 ? "," : "");
10034 count2++;
10035 }
10036
10037 val = get_param(cmd, "OP_CLASS");
10038 if (val && atoi(val)) {
10039 pos += snprintf(pos, end - pos, "%s7", count2 > 0 ? "," : "");
10040 count2++;
10041 }
10042
10043 val = get_param(cmd, "OSU_PROVIDER_LIST");
10044 if (val && atoi(val)) {
10045 pos += snprintf(pos, end - pos, "%s8", count2 > 0 ? "," : "");
10046 count2++;
10047 }
10048
Jouni Malinenf67afec2018-04-29 19:24:58 +030010049 val = get_param(cmd, "OPER_ICON_METADATA");
10050 if (!val)
10051 val = get_param(cmd, "OPERATOR_ICON_METADATA");
10052 if (val && atoi(val)) {
10053 pos += snprintf(pos, end - pos, "%s12", count2 > 0 ? "," : "");
10054 count2++;
10055 }
10056
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010057 if (count && count2) {
10058 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before sending out "
10059 "second query");
10060 sleep(1);
10061 }
10062
10063 if (count2 && wpa_command(intf, buf)) {
10064 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,HS20_ANQP_GET "
10065 "failed");
10066 return 0;
10067 }
10068
10069 val = get_param(cmd, "NAI_HOME_REALM_LIST");
10070 if (val) {
10071 if (count || count2) {
10072 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
10073 "sending out second query");
10074 sleep(1);
10075 }
10076
10077 if (strcmp(val, "1") == 0)
10078 val = "mail.example.com";
10079 snprintf(buf, end - pos,
10080 "HS20_GET_NAI_HOME_REALM_LIST %s realm=%s",
10081 dest, val);
10082 if (wpa_command(intf, buf)) {
10083 send_resp(dut, conn, SIGMA_ERROR,
10084 "ErrorCode,HS20_GET_NAI_HOME_REALM_LIST "
10085 "failed");
10086 return 0;
10087 }
10088 }
10089
10090 val = get_param(cmd, "ICON_REQUEST");
10091 if (val) {
10092 if (count || count2) {
10093 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
10094 "sending out second query");
10095 sleep(1);
10096 }
10097
10098 snprintf(buf, end - pos,
10099 "HS20_ICON_REQUEST %s %s", dest, val);
10100 if (wpa_command(intf, buf)) {
10101 send_resp(dut, conn, SIGMA_ERROR,
10102 "ErrorCode,HS20_ICON_REQUEST failed");
10103 return 0;
10104 }
10105 }
10106
10107 return 1;
10108}
10109
10110
10111static int ath_sta_send_frame_vht(struct sigma_dut *dut,
10112 struct sigma_conn *conn,
10113 struct sigma_cmd *cmd)
10114{
10115 const char *val;
10116 char *ifname;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010117 int chwidth, nss;
10118
10119 val = get_param(cmd, "framename");
10120 if (!val)
10121 return -1;
10122 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
10123
10124 /* Command sequence to generate Op mode notification */
10125 if (val && strcasecmp(val, "Op_md_notif_frm") == 0) {
10126 ifname = get_station_ifname();
10127
10128 /* Disable STBC */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010129 run_iwpriv(dut, ifname, "tx_stbc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010130
10131 /* Extract Channel width */
10132 val = get_param(cmd, "Channel_width");
10133 if (val) {
10134 switch (atoi(val)) {
10135 case 20:
10136 chwidth = 0;
10137 break;
10138 case 40:
10139 chwidth = 1;
10140 break;
10141 case 80:
10142 chwidth = 2;
10143 break;
10144 case 160:
10145 chwidth = 3;
10146 break;
10147 default:
10148 chwidth = 2;
10149 break;
10150 }
10151
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010152 run_iwpriv(dut, ifname, "chwidth %d", chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010153 }
10154
10155 /* Extract NSS */
10156 val = get_param(cmd, "NSS");
10157 if (val) {
10158 switch (atoi(val)) {
10159 case 1:
10160 nss = 1;
10161 break;
10162 case 2:
10163 nss = 3;
10164 break;
10165 case 3:
10166 nss = 7;
10167 break;
10168 default:
10169 /* We do not support NSS > 3 */
10170 nss = 3;
10171 break;
10172 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010173 run_iwpriv(dut, ifname, "rxchainmask %d", nss);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010174 }
10175
10176 /* Opmode notify */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010177 run_iwpriv(dut, ifname, "opmode_notify 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010178 }
10179
10180 return 1;
10181}
10182
10183
10184static int cmd_sta_send_frame_vht(struct sigma_dut *dut,
10185 struct sigma_conn *conn,
10186 struct sigma_cmd *cmd)
10187{
10188 switch (get_driver_type()) {
10189 case DRIVER_ATHEROS:
10190 return ath_sta_send_frame_vht(dut, conn, cmd);
10191 default:
10192 send_resp(dut, conn, SIGMA_ERROR,
10193 "errorCode,Unsupported sta_set_frame(VHT) with the current driver");
10194 return 0;
10195 }
10196}
10197
10198
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070010199static int wcn_sta_send_frame_he(struct sigma_dut *dut, struct sigma_conn *conn,
10200 struct sigma_cmd *cmd)
10201{
10202 const char *val;
10203 const char *intf = get_param(cmd, "Interface");
10204
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +030010205 if (!intf)
10206 return -1;
10207
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070010208 val = get_param(cmd, "framename");
10209 if (!val)
10210 return -1;
10211 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
10212
10213 /* Command sequence to generate Op mode notification */
10214 if (val && strcasecmp(val, "action") == 0) {
10215 val = get_param(cmd, "PPDUTxType");
10216 if (val && strcasecmp(val, "TB") == 0) {
10217 if (sta_set_action_tx_in_he_tb_ppdu(dut, intf, 1)) {
10218 sigma_dut_print(dut, DUT_MSG_ERROR,
10219 "failed to send TB PPDU Tx cfg");
10220 send_resp(dut, conn, SIGMA_ERROR,
10221 "ErrorCode,set TB PPDU Tx cfg failed");
10222 return 0;
10223 }
10224 return 1;
10225 }
10226
10227 sigma_dut_print(dut, DUT_MSG_ERROR,
10228 "Action Tx type is not defined");
10229 }
10230
10231 return 1;
10232}
10233
10234
10235static int cmd_sta_send_frame_he(struct sigma_dut *dut,
10236 struct sigma_conn *conn,
10237 struct sigma_cmd *cmd)
10238{
10239 switch (get_driver_type()) {
10240 case DRIVER_WCN:
10241 return wcn_sta_send_frame_he(dut, conn, cmd);
10242 default:
10243 send_resp(dut, conn, SIGMA_ERROR,
10244 "errorCode,Unsupported sta_set_frame(HE) with the current driver");
10245 return 0;
10246 }
10247}
10248
10249
Lior David0fe101e2017-03-09 16:09:50 +020010250#ifdef __linux__
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030010251
10252static int
10253wil6210_send_p2p_frame_60g(struct sigma_dut *dut, struct sigma_cmd *cmd,
10254 const char *frame_name, const char *dest_mac)
10255{
10256 int isprobereq = strcasecmp(frame_name, "probereq") == 0;
10257 const char *ssid = get_param(cmd, "ssid");
10258 const char *countstr = get_param(cmd, "count");
10259 const char *channelstr = get_param(cmd, "channel");
10260 const char *group_id = get_param(cmd, "groupid");
10261 const char *client_id = get_param(cmd, "clientmac");
10262 int count, channel, freq, i;
10263 const char *fname;
10264 char frame[1024], src_mac[20], group_id_attr[25],
10265 device_macstr[3 * ETH_ALEN], client_mac[ETH_ALEN];
10266 const char *group_ssid;
10267 const int group_ssid_prefix_len = 9;
10268 struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *) frame;
10269 size_t framelen = sizeof(frame);
10270 struct template_frame_tag tags[2];
10271 size_t tags_total = ARRAY_SIZE(tags);
10272 int tag_index, len, dst_len;
10273
10274 if (!countstr || !channelstr) {
10275 sigma_dut_print(dut, DUT_MSG_ERROR,
10276 "Missing argument: count, channel");
10277 return -1;
10278 }
10279 if (isprobereq && !ssid) {
10280 sigma_dut_print(dut, DUT_MSG_ERROR,
10281 "Missing argument: ssid");
10282 return -1;
10283 }
10284 if (!isprobereq && (!group_id || !client_id)) {
10285 sigma_dut_print(dut, DUT_MSG_ERROR,
10286 "Missing argument: group_id, client_id");
10287 return -1;
10288 }
10289
10290 count = atoi(countstr);
10291 channel = atoi(channelstr);
10292 freq = channel_to_freq(dut, channel);
10293
10294 if (!freq) {
10295 sigma_dut_print(dut, DUT_MSG_ERROR,
10296 "invalid channel: %s", channelstr);
10297 return -1;
10298 }
10299
10300 if (isprobereq) {
10301 if (strcasecmp(ssid, "wildcard") == 0) {
10302 fname = "probe_req_wildcard.txt";
10303 } else if (strcasecmp(ssid, "P2P_Wildcard") == 0) {
10304 fname = "probe_req_P2P_Wildcard.txt";
10305 } else {
10306 sigma_dut_print(dut, DUT_MSG_ERROR,
10307 "invalid probe request type");
10308 return -1;
10309 }
10310 } else {
10311 fname = "P2P_device_discovery_req.txt";
10312 }
10313
10314 if (parse_template_frame_file(dut, fname, frame, &framelen,
10315 tags, &tags_total)) {
10316 sigma_dut_print(dut, DUT_MSG_ERROR,
10317 "invalid frame template: %s", fname);
10318 return -1;
10319 }
10320
10321 if (get_wpa_status(get_station_ifname(), "address",
10322 src_mac, sizeof(src_mac)) < 0 ||
10323 parse_mac_address(dut, src_mac, &hdr->addr2[0]) ||
10324 parse_mac_address(dut, dest_mac, &hdr->addr1[0]))
10325 return -1;
10326 /* Use wildcard BSSID, since we are in PBSS */
10327 memset(&hdr->addr3, 0xFF, ETH_ALEN);
10328
10329 if (!isprobereq) {
10330 tag_index = find_template_frame_tag(tags, tags_total, 1);
10331 if (tag_index < 0) {
10332 sigma_dut_print(dut, DUT_MSG_ERROR,
10333 "can't find device id attribute");
10334 return -1;
10335 }
10336 if (parse_mac_address(dut, client_id,
10337 (unsigned char *) client_mac)) {
10338 sigma_dut_print(dut, DUT_MSG_ERROR,
10339 "invalid client_id: %s", client_id);
10340 return -1;
10341 }
10342 if (replace_p2p_attribute(dut, &frame[tags[tag_index].offset],
10343 framelen - tags[tag_index].offset,
10344 IEEE80211_P2P_ATTR_DEVICE_ID,
10345 client_mac, ETH_ALEN)) {
10346 sigma_dut_print(dut, DUT_MSG_ERROR,
10347 "fail to replace device id attribute");
10348 return -1;
10349 }
10350
10351 /*
10352 * group_id arg contains device MAC address followed by
10353 * space and SSID (DIRECT-somessid).
10354 * group id attribute contains device address (6 bytes)
10355 * followed by SSID prefix DIRECT-XX (9 bytes)
10356 */
10357 if (strlen(group_id) < sizeof(device_macstr)) {
10358 sigma_dut_print(dut, DUT_MSG_ERROR,
10359 "group_id arg too short");
10360 return -1;
10361 }
10362 memcpy(device_macstr, group_id, sizeof(device_macstr));
10363 device_macstr[sizeof(device_macstr) - 1] = '\0';
10364 if (parse_mac_address(dut, device_macstr,
10365 (unsigned char *) group_id_attr)) {
10366 sigma_dut_print(dut, DUT_MSG_ERROR,
10367 "fail to parse device address from group_id");
10368 return -1;
10369 }
10370 group_ssid = strchr(group_id, ' ');
10371 if (!group_ssid) {
10372 sigma_dut_print(dut, DUT_MSG_ERROR,
10373 "invalid group_id arg, no ssid");
10374 return -1;
10375 }
10376 group_ssid++;
10377 len = strlen(group_ssid);
10378 if (len < group_ssid_prefix_len) {
10379 sigma_dut_print(dut, DUT_MSG_ERROR,
10380 "group_id SSID too short");
10381 return -1;
10382 }
10383 dst_len = sizeof(group_id_attr) - ETH_ALEN;
10384 if (len > dst_len) {
10385 sigma_dut_print(dut, DUT_MSG_ERROR,
10386 "group_id SSID (%s) too long",
10387 group_ssid);
10388 return -1;
10389 }
10390
10391 memcpy(group_id_attr + ETH_ALEN, group_ssid, len);
10392 tag_index = find_template_frame_tag(tags, tags_total, 2);
10393 if (tag_index < 0) {
10394 sigma_dut_print(dut, DUT_MSG_ERROR,
10395 "can't find group id attribute");
10396 return -1;
10397 }
10398 if (replace_p2p_attribute(dut, &frame[tags[tag_index].offset],
10399 framelen - tags[tag_index].offset,
10400 IEEE80211_P2P_ATTR_GROUP_ID,
10401 group_id_attr,
10402 sizeof(group_id_attr))) {
10403 sigma_dut_print(dut, DUT_MSG_ERROR,
10404 "fail to replace group id attribute");
10405 return -1;
10406 }
10407 }
10408
10409 for (i = 0; i < count; i++) {
10410 if (wil6210_transmit_frame(dut, freq,
10411 WIL_TRANSMIT_FRAME_DEFAULT_ROC,
10412 frame, framelen)) {
10413 sigma_dut_print(dut, DUT_MSG_ERROR,
10414 "fail to transmit probe request frame");
10415 return -1;
10416 }
10417 }
10418
10419 return 0;
10420}
10421
10422
Lior David0fe101e2017-03-09 16:09:50 +020010423int wil6210_send_frame_60g(struct sigma_dut *dut, struct sigma_conn *conn,
10424 struct sigma_cmd *cmd)
10425{
10426 const char *frame_name = get_param(cmd, "framename");
10427 const char *mac = get_param(cmd, "dest_mac");
10428
10429 if (!frame_name || !mac) {
10430 sigma_dut_print(dut, DUT_MSG_ERROR,
10431 "framename and dest_mac must be provided");
10432 return -1;
10433 }
10434
10435 if (strcasecmp(frame_name, "brp") == 0) {
10436 const char *l_rx = get_param(cmd, "L-RX");
10437 int l_rx_i;
10438
10439 if (!l_rx) {
10440 sigma_dut_print(dut, DUT_MSG_ERROR,
10441 "L-RX must be provided");
10442 return -1;
10443 }
10444 l_rx_i = atoi(l_rx);
10445
10446 sigma_dut_print(dut, DUT_MSG_INFO,
10447 "dev_send_frame: BRP-RX, dest_mac %s, L-RX %s",
10448 mac, l_rx);
10449 if (l_rx_i != 16) {
10450 sigma_dut_print(dut, DUT_MSG_ERROR,
10451 "unsupported L-RX: %s", l_rx);
10452 return -1;
10453 }
10454
10455 if (wil6210_send_brp_rx(dut, mac, l_rx_i))
10456 return -1;
10457 } else if (strcasecmp(frame_name, "ssw") == 0) {
10458 sigma_dut_print(dut, DUT_MSG_INFO,
10459 "dev_send_frame: SLS, dest_mac %s", mac);
10460 if (wil6210_send_sls(dut, mac))
10461 return -1;
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030010462 } else if ((strcasecmp(frame_name, "probereq") == 0) ||
10463 (strcasecmp(frame_name, "devdiscreq") == 0)) {
10464 sigma_dut_print(dut, DUT_MSG_INFO,
10465 "dev_send_frame: %s, dest_mac %s", frame_name,
10466 mac);
10467 if (wil6210_send_p2p_frame_60g(dut, cmd, frame_name, mac))
10468 return -1;
Lior David0fe101e2017-03-09 16:09:50 +020010469 } else {
10470 sigma_dut_print(dut, DUT_MSG_ERROR,
10471 "unsupported frame type: %s", frame_name);
10472 return -1;
10473 }
10474
10475 return 1;
10476}
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030010477
Lior David0fe101e2017-03-09 16:09:50 +020010478#endif /* __linux__ */
10479
10480
10481static int cmd_sta_send_frame_60g(struct sigma_dut *dut,
10482 struct sigma_conn *conn,
10483 struct sigma_cmd *cmd)
10484{
10485 switch (get_driver_type()) {
10486#ifdef __linux__
10487 case DRIVER_WIL6210:
10488 return wil6210_send_frame_60g(dut, conn, cmd);
10489#endif /* __linux__ */
10490 default:
10491 send_resp(dut, conn, SIGMA_ERROR,
10492 "errorCode,Unsupported sta_set_frame(60G) with the current driver");
10493 return 0;
10494 }
10495}
10496
10497
Ashwini Patildb59b3c2017-04-13 15:19:23 +053010498static int mbo_send_anqp_query(struct sigma_dut *dut, struct sigma_conn *conn,
10499 const char *intf, struct sigma_cmd *cmd)
10500{
10501 const char *val, *addr;
10502 char buf[100];
10503
10504 addr = get_param(cmd, "DestMac");
10505 if (!addr) {
10506 send_resp(dut, conn, SIGMA_INVALID,
10507 "ErrorCode,AP MAC address is missing");
10508 return 0;
10509 }
10510
10511 val = get_param(cmd, "ANQPQuery_ID");
10512 if (!val) {
10513 send_resp(dut, conn, SIGMA_INVALID,
10514 "ErrorCode,Missing ANQPQuery_ID");
10515 return 0;
10516 }
10517
10518 if (strcasecmp(val, "NeighborReportReq") == 0) {
10519 snprintf(buf, sizeof(buf), "ANQP_GET %s 272", addr);
10520 } else if (strcasecmp(val, "QueryListWithCellPref") == 0) {
10521 snprintf(buf, sizeof(buf), "ANQP_GET %s 272,mbo:2", addr);
10522 } else {
10523 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid ANQPQuery_ID: %s",
10524 val);
10525 send_resp(dut, conn, SIGMA_INVALID,
10526 "ErrorCode,Invalid ANQPQuery_ID");
10527 return 0;
10528 }
10529
Ashwini Patild174f2c2017-04-13 16:49:46 +053010530 /* Set gas_address3 field to IEEE 802.11-2012 standard compliant form
10531 * (Address3 = Wildcard BSSID when sent to not-associated AP;
10532 * if associated, AP BSSID).
10533 */
10534 if (wpa_command(intf, "SET gas_address3 1") < 0) {
10535 send_resp(dut, conn, SIGMA_ERROR,
10536 "ErrorCode,Failed to set gas_address3");
10537 return 0;
10538 }
10539
Ashwini Patildb59b3c2017-04-13 15:19:23 +053010540 if (wpa_command(intf, buf) < 0) {
10541 send_resp(dut, conn, SIGMA_ERROR,
10542 "ErrorCode,Failed to send ANQP query");
10543 return 0;
10544 }
10545
10546 return 1;
10547}
10548
10549
10550static int mbo_cmd_sta_send_frame(struct sigma_dut *dut,
10551 struct sigma_conn *conn,
10552 const char *intf,
10553 struct sigma_cmd *cmd)
10554{
10555 const char *val = get_param(cmd, "FrameName");
10556
10557 if (val && strcasecmp(val, "ANQPQuery") == 0)
10558 return mbo_send_anqp_query(dut, conn, intf, cmd);
10559
10560 return 2;
10561}
10562
10563
Jouni Malinenf7222712019-06-13 01:50:21 +030010564enum sigma_cmd_result cmd_sta_send_frame(struct sigma_dut *dut,
10565 struct sigma_conn *conn,
10566 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010567{
10568 const char *intf = get_param(cmd, "Interface");
10569 const char *val;
10570 enum send_frame_type frame;
10571 enum send_frame_protection protected;
10572 char buf[100];
10573 unsigned char addr[ETH_ALEN];
10574 int res;
10575
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +030010576 if (!intf)
10577 return -1;
10578
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010579 val = get_param(cmd, "program");
10580 if (val == NULL)
10581 val = get_param(cmd, "frame");
10582 if (val && strcasecmp(val, "TDLS") == 0)
10583 return cmd_sta_send_frame_tdls(dut, conn, cmd);
10584 if (val && (strcasecmp(val, "HS2") == 0 ||
Jouni Malinen1f6ae642018-06-07 23:56:13 +030010585 strcasecmp(val, "HS2-R2") == 0 ||
10586 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010587 return cmd_sta_send_frame_hs2(dut, conn, cmd);
10588 if (val && strcasecmp(val, "VHT") == 0)
10589 return cmd_sta_send_frame_vht(dut, conn, cmd);
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070010590 if (val && strcasecmp(val, "HE") == 0)
10591 return cmd_sta_send_frame_he(dut, conn, cmd);
priyadharshini gowthamand66913a2016-07-29 15:11:17 -070010592 if (val && strcasecmp(val, "LOC") == 0)
10593 return loc_cmd_sta_send_frame(dut, conn, cmd);
Lior David0fe101e2017-03-09 16:09:50 +020010594 if (val && strcasecmp(val, "60GHz") == 0)
10595 return cmd_sta_send_frame_60g(dut, conn, cmd);
Ashwini Patildb59b3c2017-04-13 15:19:23 +053010596 if (val && strcasecmp(val, "MBO") == 0) {
10597 res = mbo_cmd_sta_send_frame(dut, conn, intf, cmd);
10598 if (res != 2)
10599 return res;
10600 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010601
10602 val = get_param(cmd, "TD_DISC");
10603 if (val) {
10604 if (hwaddr_aton(val, addr) < 0)
10605 return -1;
10606 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", val);
10607 if (wpa_command(intf, buf) < 0) {
10608 send_resp(dut, conn, SIGMA_ERROR,
10609 "ErrorCode,Failed to send TDLS discovery");
10610 return 0;
10611 }
10612 return 1;
10613 }
10614
10615 val = get_param(cmd, "TD_Setup");
10616 if (val) {
10617 if (hwaddr_aton(val, addr) < 0)
10618 return -1;
10619 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", val);
10620 if (wpa_command(intf, buf) < 0) {
10621 send_resp(dut, conn, SIGMA_ERROR,
10622 "ErrorCode,Failed to start TDLS setup");
10623 return 0;
10624 }
10625 return 1;
10626 }
10627
10628 val = get_param(cmd, "TD_TearDown");
10629 if (val) {
10630 if (hwaddr_aton(val, addr) < 0)
10631 return -1;
10632 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", val);
10633 if (wpa_command(intf, buf) < 0) {
10634 send_resp(dut, conn, SIGMA_ERROR,
10635 "ErrorCode,Failed to tear down TDLS link");
10636 return 0;
10637 }
10638 return 1;
10639 }
10640
10641 val = get_param(cmd, "TD_ChannelSwitch");
10642 if (val) {
10643 /* TODO */
10644 send_resp(dut, conn, SIGMA_ERROR,
10645 "ErrorCode,TD_ChannelSwitch not yet supported");
10646 return 0;
10647 }
10648
10649 val = get_param(cmd, "TD_NF");
10650 if (val) {
10651 /* TODO */
10652 send_resp(dut, conn, SIGMA_ERROR,
10653 "ErrorCode,TD_NF not yet supported");
10654 return 0;
10655 }
10656
10657 val = get_param(cmd, "PMFFrameType");
10658 if (val == NULL)
10659 val = get_param(cmd, "FrameName");
10660 if (val == NULL)
10661 val = get_param(cmd, "Type");
10662 if (val == NULL)
10663 return -1;
10664 if (strcasecmp(val, "disassoc") == 0)
10665 frame = DISASSOC;
10666 else if (strcasecmp(val, "deauth") == 0)
10667 frame = DEAUTH;
10668 else if (strcasecmp(val, "saquery") == 0)
10669 frame = SAQUERY;
10670 else if (strcasecmp(val, "auth") == 0)
10671 frame = AUTH;
10672 else if (strcasecmp(val, "assocreq") == 0)
10673 frame = ASSOCREQ;
10674 else if (strcasecmp(val, "reassocreq") == 0)
10675 frame = REASSOCREQ;
10676 else if (strcasecmp(val, "neigreq") == 0) {
10677 sigma_dut_print(dut, DUT_MSG_INFO, "Got neighbor request");
10678
10679 val = get_param(cmd, "ssid");
10680 if (val == NULL)
10681 return -1;
10682
10683 res = send_neighbor_request(dut, intf, val);
10684 if (res) {
10685 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
10686 "Failed to send neighbor report request");
10687 return 0;
10688 }
10689
10690 return 1;
Ashwini Patil5acd7382017-04-13 15:55:04 +053010691 } else if (strcasecmp(val, "transmgmtquery") == 0 ||
10692 strcasecmp(val, "BTMQuery") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010693 sigma_dut_print(dut, DUT_MSG_DEBUG,
10694 "Got Transition Management Query");
10695
Ashwini Patil5acd7382017-04-13 15:55:04 +053010696 res = send_trans_mgmt_query(dut, intf, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010697 if (res) {
10698 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
10699 "Failed to send Transition Management Query");
10700 return 0;
10701 }
10702
10703 return 1;
10704 } else {
10705 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
10706 "PMFFrameType");
10707 return 0;
10708 }
10709
10710 val = get_param(cmd, "PMFProtected");
10711 if (val == NULL)
10712 val = get_param(cmd, "Protected");
10713 if (val == NULL)
10714 return -1;
10715 if (strcasecmp(val, "Correct-key") == 0 ||
10716 strcasecmp(val, "CorrectKey") == 0)
10717 protected = CORRECT_KEY;
10718 else if (strcasecmp(val, "IncorrectKey") == 0)
10719 protected = INCORRECT_KEY;
10720 else if (strcasecmp(val, "Unprotected") == 0)
10721 protected = UNPROTECTED;
10722 else {
10723 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
10724 "PMFProtected");
10725 return 0;
10726 }
10727
10728 if (protected != UNPROTECTED &&
10729 (frame == AUTH || frame == ASSOCREQ || frame == REASSOCREQ)) {
10730 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Impossible "
10731 "PMFProtected for auth/assocreq/reassocreq");
10732 return 0;
10733 }
10734
10735 if (if_nametoindex("sigmadut") == 0) {
10736 snprintf(buf, sizeof(buf),
10737 "iw dev %s interface add sigmadut type monitor",
10738 get_station_ifname());
10739 if (system(buf) != 0 ||
10740 if_nametoindex("sigmadut") == 0) {
10741 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
10742 "monitor interface with '%s'", buf);
10743 return -2;
10744 }
10745 }
10746
10747 if (system("ifconfig sigmadut up") != 0) {
10748 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
10749 "monitor interface up");
10750 return -2;
10751 }
10752
10753 return sta_inject_frame(dut, conn, frame, protected, NULL);
10754}
10755
10756
10757static int cmd_sta_set_parameter_hs2(struct sigma_dut *dut,
10758 struct sigma_conn *conn,
10759 struct sigma_cmd *cmd,
10760 const char *ifname)
10761{
10762 char buf[200];
10763 const char *val;
10764
10765 val = get_param(cmd, "ClearARP");
10766 if (val && atoi(val) == 1) {
10767 snprintf(buf, sizeof(buf), "ip neigh flush dev %s", ifname);
10768 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10769 if (system(buf) != 0) {
10770 send_resp(dut, conn, SIGMA_ERROR,
10771 "errorCode,Failed to clear ARP cache");
10772 return 0;
10773 }
10774 }
10775
10776 return 1;
10777}
10778
10779
10780int cmd_sta_set_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
10781 struct sigma_cmd *cmd)
10782{
10783 const char *intf = get_param(cmd, "Interface");
10784 const char *val;
10785
10786 if (intf == NULL)
10787 return -1;
10788
10789 val = get_param(cmd, "program");
10790 if (val && (strcasecmp(val, "HS2") == 0 ||
Jouni Malinen1f6ae642018-06-07 23:56:13 +030010791 strcasecmp(val, "HS2-R2") == 0 ||
10792 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010793 return cmd_sta_set_parameter_hs2(dut, conn, cmd, intf);
10794
10795 return -1;
10796}
10797
10798
Jouni Malinenf7222712019-06-13 01:50:21 +030010799static enum sigma_cmd_result cmd_sta_set_macaddr(struct sigma_dut *dut,
10800 struct sigma_conn *conn,
10801 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010802{
10803 const char *intf = get_param(cmd, "Interface");
10804 const char *mac = get_param(cmd, "MAC");
10805
10806 if (intf == NULL || mac == NULL)
10807 return -1;
10808
10809 sigma_dut_print(dut, DUT_MSG_INFO, "Change local MAC address for "
10810 "interface %s to %s", intf, mac);
10811
10812 if (dut->set_macaddr) {
10813 char buf[128];
10814 int res;
10815 if (strcasecmp(mac, "default") == 0) {
10816 res = snprintf(buf, sizeof(buf), "%s",
10817 dut->set_macaddr);
10818 dut->tmp_mac_addr = 0;
10819 } else {
10820 res = snprintf(buf, sizeof(buf), "%s %s",
10821 dut->set_macaddr, mac);
10822 dut->tmp_mac_addr = 1;
10823 }
10824 if (res < 0 || res >= (int) sizeof(buf))
10825 return -1;
10826 if (system(buf) != 0) {
10827 send_resp(dut, conn, SIGMA_ERROR,
10828 "errorCode,Failed to set MAC "
10829 "address");
10830 return 0;
10831 }
10832 return 1;
10833 }
10834
10835 if (strcasecmp(mac, "default") == 0)
10836 return 1;
10837
10838 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
10839 "command");
10840 return 0;
10841}
10842
10843
10844static int iwpriv_tdlsoffchnmode(struct sigma_dut *dut,
10845 struct sigma_conn *conn, const char *intf,
10846 int val)
10847{
10848 char buf[200];
10849 int res;
10850
10851 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchnmode %d",
10852 intf, val);
10853 if (res < 0 || res >= (int) sizeof(buf))
10854 return -1;
10855 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10856 if (system(buf) != 0) {
10857 send_resp(dut, conn, SIGMA_ERROR,
10858 "errorCode,Failed to configure offchannel mode");
10859 return 0;
10860 }
10861
10862 return 1;
10863}
10864
10865
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010866static int off_chan_val(enum sec_ch_offset off)
10867{
10868 switch (off) {
10869 case SEC_CH_NO:
10870 return 0;
10871 case SEC_CH_40ABOVE:
10872 return 40;
10873 case SEC_CH_40BELOW:
10874 return -40;
10875 }
10876
10877 return 0;
10878}
10879
10880
10881static int iwpriv_set_offchan(struct sigma_dut *dut, struct sigma_conn *conn,
10882 const char *intf, int off_ch_num,
10883 enum sec_ch_offset sec)
10884{
10885 char buf[200];
10886 int res;
10887
10888 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchan %d",
10889 intf, off_ch_num);
10890 if (res < 0 || res >= (int) sizeof(buf))
10891 return -1;
10892 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10893 if (system(buf) != 0) {
10894 send_resp(dut, conn, SIGMA_ERROR,
10895 "errorCode,Failed to set offchan");
10896 return 0;
10897 }
10898
10899 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsecchnoffst %d",
10900 intf, off_chan_val(sec));
10901 if (res < 0 || res >= (int) sizeof(buf))
10902 return -1;
10903 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10904 if (system(buf) != 0) {
10905 send_resp(dut, conn, SIGMA_ERROR,
10906 "errorCode,Failed to set sec chan offset");
10907 return 0;
10908 }
10909
10910 return 1;
10911}
10912
10913
10914static int tdls_set_offchannel_offset(struct sigma_dut *dut,
10915 struct sigma_conn *conn,
10916 const char *intf, int off_ch_num,
10917 enum sec_ch_offset sec)
10918{
10919 char buf[200];
10920 int res;
10921
10922 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNEL %d",
10923 off_ch_num);
10924 if (res < 0 || res >= (int) sizeof(buf))
10925 return -1;
10926 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10927
10928 if (wpa_command(intf, buf) < 0) {
10929 send_resp(dut, conn, SIGMA_ERROR,
10930 "ErrorCode,Failed to set offchan");
10931 return 0;
10932 }
10933 res = snprintf(buf, sizeof(buf), "DRIVER TDLSSECONDARYCHANNELOFFSET %d",
10934 off_chan_val(sec));
10935 if (res < 0 || res >= (int) sizeof(buf))
10936 return -1;
10937
10938 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10939
10940 if (wpa_command(intf, buf) < 0) {
10941 send_resp(dut, conn, SIGMA_ERROR,
10942 "ErrorCode,Failed to set sec chan offset");
10943 return 0;
10944 }
10945
10946 return 1;
10947}
10948
10949
10950static int tdls_set_offchannel_mode(struct sigma_dut *dut,
10951 struct sigma_conn *conn,
10952 const char *intf, int val)
10953{
10954 char buf[200];
10955 int res;
10956
10957 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNELMODE %d",
10958 val);
10959 if (res < 0 || res >= (int) sizeof(buf))
10960 return -1;
10961 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10962
10963 if (wpa_command(intf, buf) < 0) {
10964 send_resp(dut, conn, SIGMA_ERROR,
10965 "ErrorCode,Failed to configure offchannel mode");
10966 return 0;
10967 }
10968
10969 return 1;
10970}
10971
10972
10973static int cmd_sta_set_rfeature_tdls(const char *intf, struct sigma_dut *dut,
10974 struct sigma_conn *conn,
10975 struct sigma_cmd *cmd)
10976{
10977 const char *val;
10978 enum {
10979 CHSM_NOT_SET,
10980 CHSM_ENABLE,
10981 CHSM_DISABLE,
10982 CHSM_REJREQ,
10983 CHSM_UNSOLRESP
10984 } chsm = CHSM_NOT_SET;
10985 int off_ch_num = -1;
10986 enum sec_ch_offset sec_ch = SEC_CH_NO;
10987 int res;
10988
10989 val = get_param(cmd, "Uapsd");
10990 if (val) {
10991 char buf[100];
10992 if (strcasecmp(val, "Enable") == 0)
10993 snprintf(buf, sizeof(buf), "SET ps 99");
10994 else if (strcasecmp(val, "Disable") == 0)
10995 snprintf(buf, sizeof(buf), "SET ps 98");
10996 else {
10997 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
10998 "Unsupported uapsd parameter value");
10999 return 0;
11000 }
11001 if (wpa_command(intf, buf)) {
11002 send_resp(dut, conn, SIGMA_ERROR,
11003 "ErrorCode,Failed to change U-APSD "
11004 "powersave mode");
11005 return 0;
11006 }
11007 }
11008
11009 val = get_param(cmd, "TPKTIMER");
11010 if (val && strcasecmp(val, "DISABLE") == 0) {
11011 if (wpa_command(intf, "SET tdls_testing 0x100")) {
11012 send_resp(dut, conn, SIGMA_ERROR,
11013 "ErrorCode,Failed to enable no TPK "
11014 "expiration test mode");
11015 return 0;
11016 }
11017 dut->no_tpk_expiration = 1;
11018 }
11019
11020 val = get_param(cmd, "ChSwitchMode");
11021 if (val) {
11022 if (strcasecmp(val, "Enable") == 0 ||
11023 strcasecmp(val, "Initiate") == 0)
11024 chsm = CHSM_ENABLE;
11025 else if (strcasecmp(val, "Disable") == 0 ||
11026 strcasecmp(val, "passive") == 0)
11027 chsm = CHSM_DISABLE;
11028 else if (strcasecmp(val, "RejReq") == 0)
11029 chsm = CHSM_REJREQ;
11030 else if (strcasecmp(val, "UnSolResp") == 0)
11031 chsm = CHSM_UNSOLRESP;
11032 else {
11033 send_resp(dut, conn, SIGMA_ERROR,
11034 "ErrorCode,Unknown ChSwitchMode value");
11035 return 0;
11036 }
11037 }
11038
11039 val = get_param(cmd, "OffChNum");
11040 if (val) {
11041 off_ch_num = atoi(val);
11042 if (off_ch_num == 0) {
11043 send_resp(dut, conn, SIGMA_ERROR,
11044 "ErrorCode,Invalid OffChNum");
11045 return 0;
11046 }
11047 }
11048
11049 val = get_param(cmd, "SecChOffset");
11050 if (val) {
11051 if (strcmp(val, "20") == 0)
11052 sec_ch = SEC_CH_NO;
11053 else if (strcasecmp(val, "40above") == 0)
11054 sec_ch = SEC_CH_40ABOVE;
11055 else if (strcasecmp(val, "40below") == 0)
11056 sec_ch = SEC_CH_40BELOW;
11057 else {
11058 send_resp(dut, conn, SIGMA_ERROR,
11059 "ErrorCode,Unknown SecChOffset value");
11060 return 0;
11061 }
11062 }
11063
11064 if (chsm == CHSM_NOT_SET) {
11065 /* no offchannel changes requested */
11066 return 1;
11067 }
11068
11069 if (strcmp(intf, get_main_ifname()) != 0 &&
11070 strcmp(intf, get_station_ifname()) != 0) {
11071 send_resp(dut, conn, SIGMA_ERROR,
11072 "ErrorCode,Unknown interface");
11073 return 0;
11074 }
11075
11076 switch (chsm) {
11077 case CHSM_NOT_SET:
Jouni Malinen280f5ba2016-08-29 21:33:10 +030011078 res = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011079 break;
11080 case CHSM_ENABLE:
11081 if (off_ch_num < 0) {
11082 send_resp(dut, conn, SIGMA_ERROR,
11083 "ErrorCode,Missing OffChNum argument");
11084 return 0;
11085 }
11086 if (wifi_chip_type == DRIVER_WCN) {
11087 res = tdls_set_offchannel_offset(dut, conn, intf,
11088 off_ch_num, sec_ch);
11089 } else {
11090 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
11091 sec_ch);
11092 }
11093 if (res != 1)
11094 return res;
11095 if (wifi_chip_type == DRIVER_WCN)
11096 res = tdls_set_offchannel_mode(dut, conn, intf, 1);
11097 else
11098 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 1);
11099 break;
11100 case CHSM_DISABLE:
11101 if (wifi_chip_type == DRIVER_WCN)
11102 res = tdls_set_offchannel_mode(dut, conn, intf, 2);
11103 else
11104 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 2);
11105 break;
11106 case CHSM_REJREQ:
11107 if (wifi_chip_type == DRIVER_WCN)
11108 res = tdls_set_offchannel_mode(dut, conn, intf, 3);
11109 else
11110 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 3);
11111 break;
11112 case CHSM_UNSOLRESP:
11113 if (off_ch_num < 0) {
11114 send_resp(dut, conn, SIGMA_ERROR,
11115 "ErrorCode,Missing OffChNum argument");
11116 return 0;
11117 }
11118 if (wifi_chip_type == DRIVER_WCN) {
11119 res = tdls_set_offchannel_offset(dut, conn, intf,
11120 off_ch_num, sec_ch);
11121 } else {
11122 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
11123 sec_ch);
11124 }
11125 if (res != 1)
11126 return res;
11127 if (wifi_chip_type == DRIVER_WCN)
11128 res = tdls_set_offchannel_mode(dut, conn, intf, 4);
11129 else
11130 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 4);
11131 break;
11132 }
11133
11134 return res;
11135}
11136
11137
11138static int ath_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
11139 struct sigma_conn *conn,
11140 struct sigma_cmd *cmd)
11141{
11142 const char *val;
Srikanth Marepalli5415acf2018-08-27 12:53:11 +053011143 char *token = NULL, *result;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011144
priyadharshini gowthamane5e25172015-12-08 14:53:48 -080011145 novap_reset(dut, intf);
11146
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011147 val = get_param(cmd, "nss_mcs_opt");
11148 if (val) {
11149 /* String (nss_operating_mode; mcs_operating_mode) */
11150 int nss, mcs;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053011151 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011152
11153 token = strdup(val);
11154 if (!token)
11155 return 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053011156 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +053011157 if (!result) {
11158 sigma_dut_print(dut, DUT_MSG_ERROR,
11159 "VHT NSS not specified");
11160 goto failed;
11161 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011162 if (strcasecmp(result, "def") != 0) {
11163 nss = atoi(result);
11164 if (nss == 4)
11165 ath_disable_txbf(dut, intf);
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011166 if (run_iwpriv(dut, intf, "nss %d", nss) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011167 goto failed;
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011168
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011169 }
11170
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053011171 result = strtok_r(NULL, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +053011172 if (!result) {
11173 sigma_dut_print(dut, DUT_MSG_ERROR,
11174 "VHT MCS not specified");
11175 goto failed;
11176 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011177 if (strcasecmp(result, "def") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011178 if (run_iwpriv(dut, intf, "set11NRates 0") < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011179 goto failed;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011180 } else {
11181 mcs = atoi(result);
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011182 if (run_iwpriv(dut, intf, "vhtmcs %d", mcs) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011183 goto failed;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011184 }
11185 /* Channel width gets messed up, fix this */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011186 run_iwpriv(dut, intf, "chwidth %d", dut->chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011187 }
11188
Srikanth Marepalli5415acf2018-08-27 12:53:11 +053011189 free(token);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011190 return 1;
11191failed:
11192 free(token);
11193 return 0;
11194}
11195
11196
11197static int cmd_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
11198 struct sigma_conn *conn,
11199 struct sigma_cmd *cmd)
11200{
11201 switch (get_driver_type()) {
11202 case DRIVER_ATHEROS:
11203 return ath_sta_set_rfeature_vht(intf, dut, conn, cmd);
11204 default:
11205 send_resp(dut, conn, SIGMA_ERROR,
11206 "errorCode,Unsupported sta_set_rfeature(VHT) with the current driver");
11207 return 0;
11208 }
11209}
11210
11211
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011212static int wcn_sta_set_rfeature_he(const char *intf, struct sigma_dut *dut,
11213 struct sigma_conn *conn,
11214 struct sigma_cmd *cmd)
11215{
11216 const char *val;
11217 char *token = NULL, *result;
11218 char buf[60];
11219
11220 val = get_param(cmd, "nss_mcs_opt");
11221 if (val) {
11222 /* String (nss_operating_mode; mcs_operating_mode) */
11223 int nss, mcs, ratecode;
11224 char *saveptr;
11225
11226 token = strdup(val);
11227 if (!token)
11228 return -2;
11229
11230 result = strtok_r(token, ";", &saveptr);
11231 if (!result) {
11232 sigma_dut_print(dut, DUT_MSG_ERROR,
11233 "HE NSS not specified");
11234 goto failed;
11235 }
11236 nss = 1;
11237 if (strcasecmp(result, "def") != 0)
11238 nss = atoi(result);
11239
11240 result = strtok_r(NULL, ";", &saveptr);
11241 if (!result) {
11242 sigma_dut_print(dut, DUT_MSG_ERROR,
11243 "HE MCS not specified");
11244 goto failed;
11245 }
11246 mcs = 7;
11247 if (strcasecmp(result, "def") != 0)
11248 mcs = atoi(result);
11249
Arif Hussain557bf412018-05-25 17:29:36 -070011250 ratecode = 0x20; /* for nss:1 MCS 0 */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011251 if (nss == 2) {
Arif Hussain557bf412018-05-25 17:29:36 -070011252 ratecode = 0x40; /* for nss:2 MCS 0 */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011253 } else if (nss > 2) {
11254 sigma_dut_print(dut, DUT_MSG_ERROR,
11255 "HE NSS %d not supported", nss);
11256 goto failed;
11257 }
11258
Arif Hussain557bf412018-05-25 17:29:36 -070011259 snprintf(buf, sizeof(buf), "iwpriv %s nss %d", intf, nss);
11260 if (system(buf) != 0) {
11261 sigma_dut_print(dut, DUT_MSG_ERROR,
11262 "nss_mcs_opt: iwpriv %s nss %d failed",
11263 intf, nss);
11264 goto failed;
11265 }
Arif Hussainac6c5112018-05-25 17:34:00 -070011266 dut->sta_nss = nss;
Arif Hussain557bf412018-05-25 17:29:36 -070011267
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011268 /* Add the MCS to the ratecode */
11269 if (mcs >= 0 && mcs <= 11) {
11270 ratecode += mcs;
Arif Hussain557bf412018-05-25 17:29:36 -070011271#ifdef NL80211_SUPPORT
11272 if (dut->device_type == STA_testbed) {
11273 enum he_mcs_config mcs_config;
11274 int ret;
11275
11276 if (mcs <= 7)
11277 mcs_config = HE_80_MCS0_7;
11278 else if (mcs <= 9)
11279 mcs_config = HE_80_MCS0_9;
11280 else
11281 mcs_config = HE_80_MCS0_11;
11282 ret = sta_set_he_mcs(dut, intf, mcs_config);
11283 if (ret) {
11284 sigma_dut_print(dut, DUT_MSG_ERROR,
11285 "nss_mcs_opt: mcs setting failed, mcs:%d, mcs_config %d, ret:%d",
11286 mcs, mcs_config, ret);
11287 goto failed;
11288 }
11289 }
11290#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011291 } else {
11292 sigma_dut_print(dut, DUT_MSG_ERROR,
11293 "HE MCS %d not supported", mcs);
11294 goto failed;
11295 }
11296 snprintf(buf, sizeof(buf), "iwpriv %s set_11ax_rate 0x%03x",
11297 intf, ratecode);
11298 if (system(buf) != 0) {
11299 sigma_dut_print(dut, DUT_MSG_ERROR,
11300 "iwpriv setting of 11ax rates failed");
11301 goto failed;
11302 }
11303 free(token);
11304 }
11305
11306 val = get_param(cmd, "GI");
11307 if (val) {
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011308 int fix_rate_sgi;
11309
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011310 if (strcmp(val, "0.8") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070011311 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 9", intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011312 fix_rate_sgi = 1;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011313 } else if (strcmp(val, "1.6") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070011314 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 10",
11315 intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011316 fix_rate_sgi = 2;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011317 } else if (strcmp(val, "3.2") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070011318 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 11",
11319 intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011320 fix_rate_sgi = 3;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011321 } else {
11322 send_resp(dut, conn, SIGMA_ERROR,
11323 "errorCode,GI value not supported");
11324 return 0;
11325 }
11326 if (system(buf) != 0) {
11327 send_resp(dut, conn, SIGMA_ERROR,
11328 "errorCode,Failed to set shortgi");
11329 return 0;
11330 }
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011331 snprintf(buf, sizeof(buf), "iwpriv %s shortgi %d",
11332 intf, fix_rate_sgi);
11333 if (system(buf) != 0) {
11334 send_resp(dut, conn, SIGMA_ERROR,
11335 "errorCode,Failed to set fix rate shortgi");
11336 return STATUS_SENT;
11337 }
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011338 }
11339
Subhani Shaik8e7a3052018-04-24 14:03:00 -070011340 val = get_param(cmd, "LTF");
11341 if (val) {
11342#ifdef NL80211_SUPPORT
11343 if (strcmp(val, "3.2") == 0) {
11344 sta_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_1X);
11345 } if (strcmp(val, "6.4") == 0) {
11346 sta_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_2X);
11347 } else if (strcmp(val, "12.8") == 0) {
11348 sta_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_4X);
11349 } else {
11350 send_resp(dut, conn, SIGMA_ERROR,
11351 "errorCode, LTF value not supported");
11352 return 0;
11353 }
11354#else /* NL80211_SUPPORT */
11355 sigma_dut_print(dut, DUT_MSG_ERROR,
11356 "LTF cannot be set without NL80211_SUPPORT defined");
11357 return -2;
11358#endif /* NL80211_SUPPORT */
11359 }
11360
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -070011361 val = get_param(cmd, "TxSUPPDU");
11362 if (val) {
11363 int set_val = 1;
11364
11365 if (strcasecmp(val, "Enable") == 0)
11366 set_val = 1;
11367 else if (strcasecmp(val, "Disable") == 0)
11368 set_val = 0;
11369
11370 if (sta_set_tx_su_ppdu_cfg(dut, intf, set_val)) {
11371 send_resp(dut, conn, SIGMA_ERROR,
11372 "ErrorCode,Failed to set Tx SU PPDU config");
11373 return 0;
11374 }
11375 }
11376
Arif Hussain480d5f42019-03-12 14:40:42 -070011377 val = get_param(cmd, "TWT_Setup");
11378 if (val) {
11379 if (strcasecmp(val, "Request") == 0) {
11380 if (sta_twt_request(dut, conn, cmd)) {
11381 send_resp(dut, conn, SIGMA_ERROR,
11382 "ErrorCode,sta_twt_request failed");
11383 return STATUS_SENT;
11384 }
11385 } else if (strcasecmp(val, "Teardown") == 0) {
11386 if (sta_twt_teardown(dut, conn, cmd)) {
11387 send_resp(dut, conn, SIGMA_ERROR,
11388 "ErrorCode,sta_twt_teardown failed");
11389 return STATUS_SENT;
11390 }
11391 }
11392 }
11393
Kiran Kumar Lokere50eb2cd2018-12-18 18:31:28 -080011394 val = get_param(cmd, "transmitOMI");
11395 if (val && sta_transmit_omi(dut, conn, cmd)) {
11396 send_resp(dut, conn, SIGMA_ERROR,
11397 "ErrorCode,sta_transmit_omi failed");
11398 return STATUS_SENT;
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -070011399 }
11400
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080011401 val = get_param(cmd, "Powersave");
11402 if (val) {
11403 char buf[60];
11404
11405 if (strcasecmp(val, "off") == 0) {
11406 snprintf(buf, sizeof(buf),
11407 "iwpriv %s setPower 2", intf);
11408 if (system(buf) != 0) {
11409 sigma_dut_print(dut, DUT_MSG_ERROR,
11410 "iwpriv setPower 2 failed");
11411 return 0;
11412 }
11413 } else if (strcasecmp(val, "on") == 0) {
11414 snprintf(buf, sizeof(buf),
11415 "iwpriv %s setPower 1", intf);
11416 if (system(buf) != 0) {
11417 sigma_dut_print(dut, DUT_MSG_ERROR,
11418 "iwpriv setPower 1 failed");
11419 return 0;
11420 }
11421 } else {
11422 sigma_dut_print(dut, DUT_MSG_ERROR,
11423 "Unsupported Powersave value '%s'",
11424 val);
11425 return -1;
11426 }
11427 }
11428
Kiran Kumar Lokere2c4b7ce2019-01-30 12:02:28 -080011429 val = get_param(cmd, "MU_EDCA");
11430 if (val) {
11431 if (strcasecmp(val, "Override") == 0) {
11432 if (sta_set_mu_edca_override(dut, intf, 1)) {
11433 send_resp(dut, conn, SIGMA_ERROR,
11434 "errorCode,MU EDCA override set failed");
11435 return STATUS_SENT;
11436 }
11437 } else if (strcasecmp(val, "Disable") == 0) {
11438 if (sta_set_mu_edca_override(dut, intf, 0)) {
11439 send_resp(dut, conn, SIGMA_ERROR,
11440 "errorCode,MU EDCA override disable failed");
11441 return STATUS_SENT;
11442 }
11443 }
11444 }
11445
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011446 return 1;
11447
11448failed:
11449 free(token);
11450 return -2;
11451}
11452
11453
11454static int cmd_sta_set_rfeature_he(const char *intf, struct sigma_dut *dut,
11455 struct sigma_conn *conn,
11456 struct sigma_cmd *cmd)
11457{
11458 switch (get_driver_type()) {
11459 case DRIVER_WCN:
11460 return wcn_sta_set_rfeature_he(intf, dut, conn, cmd);
11461 default:
11462 send_resp(dut, conn, SIGMA_ERROR,
11463 "errorCode,Unsupported sta_set_rfeature(HE) with the current driver");
11464 return 0;
11465 }
11466}
11467
11468
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080011469static int cmd_sta_set_power_save_he(const char *intf, struct sigma_dut *dut,
11470 struct sigma_conn *conn,
11471 struct sigma_cmd *cmd)
11472{
11473 const char *val;
11474
11475 val = get_param(cmd, "powersave");
11476 if (val) {
11477 char buf[60];
11478
11479 if (strcasecmp(val, "off") == 0) {
11480 snprintf(buf, sizeof(buf), "iwpriv %s setPower 2",
11481 intf);
11482 if (system(buf) != 0) {
11483 sigma_dut_print(dut, DUT_MSG_ERROR,
11484 "iwpriv setPower 2 failed");
11485 return 0;
11486 }
11487 } else if (strcasecmp(val, "on") == 0) {
11488 snprintf(buf, sizeof(buf), "iwpriv %s setPower 1",
11489 intf);
11490 if (system(buf) != 0) {
11491 sigma_dut_print(dut, DUT_MSG_ERROR,
11492 "iwpriv setPower 1 failed");
11493 return 0;
11494 }
11495 } else {
11496 sigma_dut_print(dut, DUT_MSG_ERROR,
11497 "Unsupported power save config");
11498 return -1;
11499 }
11500 return 1;
11501 }
11502
11503 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported command");
11504
11505 return 0;
11506}
11507
11508
Ashwini Patil5acd7382017-04-13 15:55:04 +053011509static int btm_query_candidate_list(struct sigma_dut *dut,
11510 struct sigma_conn *conn,
11511 struct sigma_cmd *cmd)
11512{
11513 const char *bssid, *info, *op_class, *ch, *phy_type, *pref;
11514 int len, ret;
11515 char buf[10];
11516
11517 /*
11518 * Neighbor Report elements format:
11519 * neighbor=<BSSID>,<BSSID Information>,<Operating Class>,
11520 * <Channel Number>,<PHY Type>[,<hexdump of Optional Subelements>]
11521 * eg: neighbor=aa:bb:cc:dd:ee:ff,17,81,6,1,030101
11522 */
11523
11524 bssid = get_param(cmd, "Nebor_BSSID");
11525 if (!bssid) {
11526 send_resp(dut, conn, SIGMA_INVALID,
11527 "errorCode,Nebor_BSSID is missing");
11528 return 0;
11529 }
11530
11531 info = get_param(cmd, "Nebor_Bssid_Info");
11532 if (!info) {
11533 sigma_dut_print(dut, DUT_MSG_INFO,
11534 "Using default value for Nebor_Bssid_Info: %s",
11535 DEFAULT_NEIGHBOR_BSSID_INFO);
11536 info = DEFAULT_NEIGHBOR_BSSID_INFO;
11537 }
11538
11539 op_class = get_param(cmd, "Nebor_Op_Class");
11540 if (!op_class) {
11541 send_resp(dut, conn, SIGMA_INVALID,
11542 "errorCode,Nebor_Op_Class is missing");
11543 return 0;
11544 }
11545
11546 ch = get_param(cmd, "Nebor_Op_Ch");
11547 if (!ch) {
11548 send_resp(dut, conn, SIGMA_INVALID,
11549 "errorCode,Nebor_Op_Ch is missing");
11550 return 0;
11551 }
11552
11553 phy_type = get_param(cmd, "Nebor_Phy_Type");
11554 if (!phy_type) {
11555 sigma_dut_print(dut, DUT_MSG_INFO,
11556 "Using default value for Nebor_Phy_Type: %s",
11557 DEFAULT_NEIGHBOR_PHY_TYPE);
11558 phy_type = DEFAULT_NEIGHBOR_PHY_TYPE;
11559 }
11560
11561 /* Parse optional subelements */
11562 buf[0] = '\0';
11563 pref = get_param(cmd, "Nebor_Pref");
11564 if (pref) {
11565 /* hexdump for preferrence subelement */
11566 ret = snprintf(buf, sizeof(buf), ",0301%02x", atoi(pref));
11567 if (ret < 0 || ret >= (int) sizeof(buf)) {
11568 sigma_dut_print(dut, DUT_MSG_ERROR,
11569 "snprintf failed for optional subelement ret: %d",
11570 ret);
11571 send_resp(dut, conn, SIGMA_ERROR,
11572 "errorCode,snprintf failed for subelement");
11573 return 0;
11574 }
11575 }
11576
11577 if (!dut->btm_query_cand_list) {
11578 dut->btm_query_cand_list = calloc(1, NEIGHBOR_REPORT_SIZE);
11579 if (!dut->btm_query_cand_list) {
11580 send_resp(dut, conn, SIGMA_ERROR,
11581 "errorCode,Failed to allocate memory for btm_query_cand_list");
11582 return 0;
11583 }
11584 }
11585
11586 len = strlen(dut->btm_query_cand_list);
11587 ret = snprintf(dut->btm_query_cand_list + len,
11588 NEIGHBOR_REPORT_SIZE - len, " neighbor=%s,%s,%s,%s,%s%s",
11589 bssid, info, op_class, ch, phy_type, buf);
11590 if (ret < 0 || ret >= NEIGHBOR_REPORT_SIZE - len) {
11591 sigma_dut_print(dut, DUT_MSG_ERROR,
11592 "snprintf failed for neighbor report list ret: %d",
11593 ret);
11594 send_resp(dut, conn, SIGMA_ERROR,
11595 "errorCode,snprintf failed for neighbor report");
11596 free(dut->btm_query_cand_list);
11597 dut->btm_query_cand_list = NULL;
11598 return 0;
11599 }
11600
11601 return 1;
11602}
11603
11604
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020011605int sta_extract_60g_ese(struct sigma_dut *dut, struct sigma_cmd *cmd,
11606 struct sigma_ese_alloc *allocs, int *allocs_size)
11607{
11608 int max_count = *allocs_size;
11609 int count = 0, i;
11610 const char *val;
11611
11612 do {
11613 val = get_param_indexed(cmd, "AllocID", count);
11614 if (val)
11615 count++;
11616 } while (val);
11617
11618 if (count == 0 || count > max_count) {
11619 sigma_dut_print(dut, DUT_MSG_ERROR,
11620 "Invalid number of allocations(%d)", count);
11621 return -1;
11622 }
11623
11624 for (i = 0; i < count; i++) {
11625 val = get_param_indexed(cmd, "PercentBI", i);
11626 if (!val) {
11627 sigma_dut_print(dut, DUT_MSG_ERROR,
11628 "Missing PercentBI parameter at index %d",
11629 i);
11630 return -1;
11631 }
11632 allocs[i].percent_bi = atoi(val);
11633
11634 val = get_param_indexed(cmd, "SrcAID", i);
11635 if (val)
11636 allocs[i].src_aid = strtol(val, NULL, 0);
11637 else
11638 allocs[i].src_aid = ESE_BCAST_AID;
11639
11640 val = get_param_indexed(cmd, "DestAID", i);
11641 if (val)
11642 allocs[i].dst_aid = strtol(val, NULL, 0);
11643 else
11644 allocs[i].dst_aid = ESE_BCAST_AID;
11645
11646 allocs[i].type = ESE_CBAP;
11647 sigma_dut_print(dut, DUT_MSG_INFO,
11648 "Alloc %d PercentBI %d SrcAID %d DstAID %d",
11649 i, allocs[i].percent_bi, allocs[i].src_aid,
11650 allocs[i].dst_aid);
11651 }
11652
11653 *allocs_size = count;
11654 return 0;
11655}
11656
11657
11658static int sta_set_60g_ese(struct sigma_dut *dut, int count,
11659 struct sigma_ese_alloc *allocs)
11660{
11661 switch (get_driver_type()) {
11662#ifdef __linux__
11663 case DRIVER_WIL6210:
11664 if (wil6210_set_ese(dut, count, allocs))
11665 return -1;
11666 return 1;
11667#endif /* __linux__ */
11668 default:
11669 sigma_dut_print(dut, DUT_MSG_ERROR,
11670 "Unsupported sta_set_60g_ese with the current driver");
11671 return -1;
11672 }
11673}
11674
11675
11676static int cmd_sta_set_rfeature_60g(const char *intf, struct sigma_dut *dut,
11677 struct sigma_conn *conn,
11678 struct sigma_cmd *cmd)
11679{
11680 const char *val;
11681
11682 val = get_param(cmd, "ExtSchIE");
11683 if (val && !strcasecmp(val, "Enable")) {
11684 struct sigma_ese_alloc allocs[MAX_ESE_ALLOCS];
11685 int count = MAX_ESE_ALLOCS;
11686
11687 if (sta_extract_60g_ese(dut, cmd, allocs, &count))
11688 return -1;
11689 return sta_set_60g_ese(dut, count, allocs);
11690 }
11691
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +020011692 val = get_param(cmd, "MCS_FixedRate");
11693 if (val) {
11694 int sta_mcs = atoi(val);
11695
11696 sigma_dut_print(dut, DUT_MSG_INFO, "Force STA MCS to %d",
11697 sta_mcs);
11698 wil6210_set_force_mcs(dut, 1, sta_mcs);
11699
Jouni Malinen0e29cf22019-02-19 01:13:21 +020011700 return SUCCESS_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +020011701 }
11702
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020011703 send_resp(dut, conn, SIGMA_ERROR,
11704 "errorCode,Invalid sta_set_rfeature(60G)");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020011705 return STATUS_SENT;
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020011706}
11707
11708
Jouni Malinenf7222712019-06-13 01:50:21 +030011709static enum sigma_cmd_result cmd_sta_set_rfeature(struct sigma_dut *dut,
11710 struct sigma_conn *conn,
11711 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011712{
11713 const char *intf = get_param(cmd, "Interface");
11714 const char *prog = get_param(cmd, "Prog");
Ashwini Patil68d02cd2017-01-10 15:39:16 +053011715 const char *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011716
11717 if (intf == NULL || prog == NULL)
11718 return -1;
11719
Ashwini Patil5acd7382017-04-13 15:55:04 +053011720 /* BSS Transition candidate list for BTM query */
11721 val = get_param(cmd, "Nebor_BSSID");
11722 if (val && btm_query_candidate_list(dut, conn, cmd) == 0)
11723 return 0;
11724
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011725 if (strcasecmp(prog, "TDLS") == 0)
11726 return cmd_sta_set_rfeature_tdls(intf, dut, conn, cmd);
11727
11728 if (strcasecmp(prog, "VHT") == 0)
11729 return cmd_sta_set_rfeature_vht(intf, dut, conn, cmd);
11730
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011731 if (strcasecmp(prog, "HE") == 0)
11732 return cmd_sta_set_rfeature_he(intf, dut, conn, cmd);
11733
Ashwini Patil68d02cd2017-01-10 15:39:16 +053011734 if (strcasecmp(prog, "MBO") == 0) {
11735 val = get_param(cmd, "Cellular_Data_Cap");
11736 if (val &&
11737 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
11738 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +053011739
11740 val = get_param(cmd, "Ch_Pref");
11741 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
11742 return 0;
11743
Ashwini Patil68d02cd2017-01-10 15:39:16 +053011744 return 1;
11745 }
11746
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020011747 if (strcasecmp(prog, "60GHz") == 0)
11748 return cmd_sta_set_rfeature_60g(intf, dut, conn, cmd);
11749
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011750 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported Prog");
11751 return 0;
11752}
11753
11754
Jouni Malinenf7222712019-06-13 01:50:21 +030011755static enum sigma_cmd_result cmd_sta_set_radio(struct sigma_dut *dut,
11756 struct sigma_conn *conn,
11757 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011758{
11759 const char *intf = get_param(cmd, "Interface");
11760 const char *mode = get_param(cmd, "Mode");
11761 int res;
11762
11763 if (intf == NULL || mode == NULL)
11764 return -1;
11765
11766 if (strcasecmp(mode, "On") == 0)
11767 res = wpa_command(intf, "SET radio_disabled 0");
11768 else if (strcasecmp(mode, "Off") == 0)
11769 res = wpa_command(intf, "SET radio_disabled 1");
11770 else
11771 return -1;
11772
11773 if (res) {
11774 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
11775 "radio mode");
11776 return 0;
11777 }
11778
11779 return 1;
11780}
11781
11782
Jouni Malinenf7222712019-06-13 01:50:21 +030011783static enum sigma_cmd_result cmd_sta_set_pwrsave(struct sigma_dut *dut,
11784 struct sigma_conn *conn,
11785 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011786{
11787 const char *intf = get_param(cmd, "Interface");
11788 const char *mode = get_param(cmd, "Mode");
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020011789 const char *prog = get_param(cmd, "program");
11790 const char *powersave = get_param(cmd, "powersave");
11791 int res = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011792
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020011793 if (intf == NULL)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011794 return -1;
11795
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020011796 if (prog && strcasecmp(prog, "60GHz") == 0) {
11797 /*
11798 * The CAPI mode parameter does not exist in 60G
11799 * unscheduled PS.
11800 */
11801 if (strcasecmp(powersave, "unscheduled") == 0)
11802 res = set_ps(intf, dut, 1);
Alexei Avshalom Lazar2f6fdb42019-02-04 14:16:08 +020011803 } else if (prog && get_driver_type() == DRIVER_WCN &&
11804 strcasecmp(prog, "HE") == 0) {
11805 return cmd_sta_set_power_save_he(intf, dut, conn, cmd);
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020011806 } else {
11807 if (mode == NULL)
11808 return -1;
11809
11810 if (strcasecmp(mode, "On") == 0)
11811 res = set_ps(intf, dut, 1);
11812 else if (strcasecmp(mode, "Off") == 0)
11813 res = set_ps(intf, dut, 0);
11814 else
11815 return -1;
11816 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011817
11818 if (res) {
11819 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
11820 "power save mode");
11821 return 0;
11822 }
11823
11824 return 1;
11825}
11826
11827
Jouni Malinenf7222712019-06-13 01:50:21 +030011828static enum sigma_cmd_result cmd_sta_bssid_pool(struct sigma_dut *dut,
11829 struct sigma_conn *conn,
11830 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011831{
11832 const char *intf = get_param(cmd, "Interface");
11833 const char *val, *bssid;
11834 int res;
11835 char *buf;
11836 size_t buf_len;
11837
11838 val = get_param(cmd, "BSSID_FILTER");
11839 if (val == NULL)
11840 return -1;
11841
11842 bssid = get_param(cmd, "BSSID_List");
11843 if (atoi(val) == 0 || bssid == NULL) {
11844 /* Disable BSSID filter */
11845 if (wpa_command(intf, "SET bssid_filter ")) {
11846 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed "
11847 "to disable BSSID filter");
11848 return 0;
11849 }
11850
11851 return 1;
11852 }
11853
11854 buf_len = 100 + strlen(bssid);
11855 buf = malloc(buf_len);
11856 if (buf == NULL)
11857 return -1;
11858
11859 snprintf(buf, buf_len, "SET bssid_filter %s", bssid);
11860 res = wpa_command(intf, buf);
11861 free(buf);
11862 if (res) {
11863 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to enable "
11864 "BSSID filter");
11865 return 0;
11866 }
11867
11868 return 1;
11869}
11870
11871
Jouni Malinenf7222712019-06-13 01:50:21 +030011872static enum sigma_cmd_result cmd_sta_reset_parm(struct sigma_dut *dut,
11873 struct sigma_conn *conn,
11874 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011875{
11876 const char *intf = get_param(cmd, "Interface");
11877 const char *val;
11878
11879 /* TODO: ARP */
11880
11881 val = get_param(cmd, "HS2_CACHE_PROFILE");
11882 if (val && strcasecmp(val, "All") == 0)
11883 hs2_clear_credentials(intf);
11884
11885 return 1;
11886}
11887
11888
Jouni Malinenf7222712019-06-13 01:50:21 +030011889static enum sigma_cmd_result cmd_sta_get_key(struct sigma_dut *dut,
11890 struct sigma_conn *conn,
11891 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011892{
11893 const char *intf = get_param(cmd, "Interface");
11894 const char *key_type = get_param(cmd, "KeyType");
11895 char buf[100], resp[200];
11896
11897 if (key_type == NULL)
11898 return -1;
11899
11900 if (strcasecmp(key_type, "GTK") == 0) {
11901 if (wpa_command_resp(intf, "GET gtk", buf, sizeof(buf)) < 0 ||
11902 strncmp(buf, "FAIL", 4) == 0) {
11903 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
11904 "not fetch current GTK");
11905 return 0;
11906 }
11907 snprintf(resp, sizeof(resp), "KeyValue,%s", buf);
11908 send_resp(dut, conn, SIGMA_COMPLETE, resp);
11909 return 0;
11910 } else {
11911 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
11912 "KeyType");
11913 return 0;
11914 }
11915
11916 return 1;
11917}
11918
11919
11920static int hs2_set_policy(struct sigma_dut *dut)
11921{
11922#ifdef ANDROID
11923 system("ip rule del prio 23000");
11924 if (system("ip rule add from all lookup main prio 23000") != 0) {
11925 sigma_dut_print(dut, DUT_MSG_ERROR,
11926 "Failed to run:ip rule add from all lookup main prio");
11927 return -1;
11928 }
11929 if (system("ip route flush cache") != 0) {
11930 sigma_dut_print(dut, DUT_MSG_ERROR,
11931 "Failed to run ip route flush cache");
11932 return -1;
11933 }
11934 return 1;
11935#else /* ANDROID */
11936 return 0;
11937#endif /* ANDROID */
11938}
11939
11940
Jouni Malinenf7222712019-06-13 01:50:21 +030011941static enum sigma_cmd_result cmd_sta_hs2_associate(struct sigma_dut *dut,
11942 struct sigma_conn *conn,
11943 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011944{
11945 const char *intf = get_param(cmd, "Interface");
11946 const char *val = get_param(cmd, "Ignore_blacklist");
Jouni Malinen439352d2018-09-13 03:42:23 +030011947 const char *band = get_param(cmd, "Band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011948 struct wpa_ctrl *ctrl;
Jouni Malinen3aa72862019-05-29 23:14:51 +030011949 int res, r;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011950 char bssid[20], ssid[40], resp[100], buf[100], blacklisted[100];
11951 int tries = 0;
11952 int ignore_blacklist = 0;
11953 const char *events[] = {
11954 "CTRL-EVENT-CONNECTED",
11955 "INTERWORKING-BLACKLISTED",
11956 "INTERWORKING-NO-MATCH",
11957 NULL
11958 };
11959
11960 start_sta_mode(dut);
11961
Jouni Malinen439352d2018-09-13 03:42:23 +030011962 if (band) {
11963 if (strcmp(band, "2.4") == 0) {
11964 wpa_command(intf, "SET setband 2G");
11965 } else if (strcmp(band, "5") == 0) {
11966 wpa_command(intf, "SET setband 5G");
11967 } else {
11968 send_resp(dut, conn, SIGMA_ERROR,
11969 "errorCode,Unsupported band");
11970 return 0;
11971 }
11972 }
11973
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011974 blacklisted[0] = '\0';
11975 if (val && atoi(val))
11976 ignore_blacklist = 1;
11977
11978try_again:
11979 ctrl = open_wpa_mon(intf);
11980 if (ctrl == NULL) {
11981 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
11982 "wpa_supplicant monitor connection");
11983 return -2;
11984 }
11985
11986 tries++;
11987 if (wpa_command(intf, "INTERWORKING_SELECT auto")) {
11988 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start "
11989 "Interworking connection");
11990 wpa_ctrl_detach(ctrl);
11991 wpa_ctrl_close(ctrl);
11992 return 0;
11993 }
11994
11995 buf[0] = '\0';
11996 while (1) {
11997 char *pos;
11998 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
11999 pos = strstr(buf, "INTERWORKING-BLACKLISTED");
12000 if (!pos)
12001 break;
12002 pos += 25;
12003 sigma_dut_print(dut, DUT_MSG_DEBUG, "Found blacklisted AP: %s",
12004 pos);
12005 if (!blacklisted[0])
12006 memcpy(blacklisted, pos, strlen(pos) + 1);
12007 }
12008
12009 if (ignore_blacklist && blacklisted[0]) {
12010 char *end;
12011 end = strchr(blacklisted, ' ');
12012 if (end)
12013 *end = '\0';
12014 sigma_dut_print(dut, DUT_MSG_DEBUG, "Try to connect to a blacklisted network: %s",
12015 blacklisted);
Jouni Malinen3aa72862019-05-29 23:14:51 +030012016 r = snprintf(buf, sizeof(buf), "INTERWORKING_CONNECT %s",
12017 blacklisted);
12018 if (r < 0 || r >= sizeof(buf) || wpa_command(intf, buf)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012019 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start Interworking connection to blacklisted network");
12020 wpa_ctrl_detach(ctrl);
12021 wpa_ctrl_close(ctrl);
12022 return 0;
12023 }
12024 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
12025 buf, sizeof(buf));
12026 }
12027
12028 wpa_ctrl_detach(ctrl);
12029 wpa_ctrl_close(ctrl);
12030
12031 if (res < 0) {
12032 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
12033 "connect");
12034 return 0;
12035 }
12036
12037 if (strstr(buf, "INTERWORKING-NO-MATCH") ||
12038 strstr(buf, "INTERWORKING-BLACKLISTED")) {
12039 if (tries < 2) {
12040 sigma_dut_print(dut, DUT_MSG_INFO, "No match found - try again to verify no APs were missed in the scan");
12041 goto try_again;
12042 }
12043 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,No network with "
12044 "matching credentials found");
12045 return 0;
12046 }
12047
12048 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
12049 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
12050 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
12051 "get current BSSID/SSID");
12052 return 0;
12053 }
12054
12055 snprintf(resp, sizeof(resp), "SSID,%s,BSSID,%s", ssid, bssid);
12056 send_resp(dut, conn, SIGMA_COMPLETE, resp);
12057 hs2_set_policy(dut);
12058 return 0;
12059}
12060
12061
Jouni Malinenf7222712019-06-13 01:50:21 +030012062static enum sigma_cmd_result cmd_sta_hs2_venue_info(struct sigma_dut *dut,
12063 struct sigma_conn *conn,
12064 struct sigma_cmd *cmd)
Jouni Malinenb639f1c2018-09-13 02:39:46 +030012065{
12066 const char *intf = get_param(cmd, "Interface");
12067 const char *display = get_param(cmd, "Display");
12068 struct wpa_ctrl *ctrl;
12069 char buf[300], params[400], *pos;
12070 char bssid[20];
12071 int info_avail = 0;
12072 unsigned int old_timeout;
12073 int res;
12074
12075 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0) {
12076 send_resp(dut, conn, SIGMA_ERROR,
12077 "ErrorCode,Could not get current BSSID");
12078 return 0;
12079 }
12080 ctrl = open_wpa_mon(intf);
12081 if (!ctrl) {
12082 sigma_dut_print(dut, DUT_MSG_ERROR,
12083 "Failed to open wpa_supplicant monitor connection");
12084 return -2;
12085 }
12086
12087 snprintf(buf, sizeof(buf), "ANQP_GET %s 277", bssid);
12088 wpa_command(intf, buf);
12089
12090 res = get_wpa_cli_event(dut, ctrl, "GAS-QUERY-DONE", buf, sizeof(buf));
12091 if (res < 0) {
12092 send_resp(dut, conn, SIGMA_ERROR,
12093 "ErrorCode,Could not complete GAS query");
12094 goto fail;
12095 }
12096
12097 old_timeout = dut->default_timeout;
12098 dut->default_timeout = 2;
12099 res = get_wpa_cli_event(dut, ctrl, "RX-VENUE-URL", buf, sizeof(buf));
12100 dut->default_timeout = old_timeout;
12101 if (res < 0)
12102 goto done;
12103 pos = strchr(buf, ' ');
12104 if (!pos)
12105 goto done;
12106 pos++;
12107 pos = strchr(pos, ' ');
12108 if (!pos)
12109 goto done;
12110 pos++;
12111 info_avail = 1;
12112 snprintf(params, sizeof(params), "browser %s", pos);
12113
12114 if (display && strcasecmp(display, "Yes") == 0) {
12115 pid_t pid;
12116
12117 pid = fork();
12118 if (pid < 0) {
12119 perror("fork");
12120 return -1;
12121 }
12122
12123 if (pid == 0) {
12124 run_hs20_osu(dut, params);
12125 exit(0);
12126 }
12127 }
12128
12129done:
12130 snprintf(buf, sizeof(buf), "Info_available,%s",
12131 info_avail ? "Yes" : "No");
12132 send_resp(dut, conn, SIGMA_COMPLETE, buf);
12133fail:
12134 wpa_ctrl_detach(ctrl);
12135 wpa_ctrl_close(ctrl);
12136 return 0;
12137}
12138
12139
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012140static int sta_add_credential_uname_pwd(struct sigma_dut *dut,
12141 struct sigma_conn *conn,
12142 const char *ifname,
12143 struct sigma_cmd *cmd)
12144{
12145 const char *val;
12146 int id;
12147
12148 id = add_cred(ifname);
12149 if (id < 0)
12150 return -2;
12151 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
12152
12153 val = get_param(cmd, "prefer");
12154 if (val && atoi(val) > 0)
12155 set_cred(ifname, id, "priority", "1");
12156
12157 val = get_param(cmd, "REALM");
12158 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
12159 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12160 "realm");
12161 return 0;
12162 }
12163
12164 val = get_param(cmd, "HOME_FQDN");
12165 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
12166 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12167 "home_fqdn");
12168 return 0;
12169 }
12170
12171 val = get_param(cmd, "Username");
12172 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
12173 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12174 "username");
12175 return 0;
12176 }
12177
12178 val = get_param(cmd, "Password");
12179 if (val && set_cred_quoted(ifname, id, "password", val) < 0) {
12180 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12181 "password");
12182 return 0;
12183 }
12184
12185 val = get_param(cmd, "ROOT_CA");
12186 if (val) {
12187 char fname[200];
12188 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
12189#ifdef __linux__
12190 if (!file_exists(fname)) {
12191 char msg[300];
12192 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
12193 "file (%s) not found", fname);
12194 send_resp(dut, conn, SIGMA_ERROR, msg);
12195 return 0;
12196 }
12197#endif /* __linux__ */
12198 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
12199 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12200 "not set root CA");
12201 return 0;
12202 }
12203 }
12204
12205 return 1;
12206}
12207
12208
12209static int update_devdetail_imsi(struct sigma_dut *dut, const char *imsi)
12210{
12211 FILE *in, *out;
12212 char buf[500];
12213 int found = 0;
12214
12215 in = fopen("devdetail.xml", "r");
12216 if (in == NULL)
12217 return -1;
12218 out = fopen("devdetail.xml.tmp", "w");
12219 if (out == NULL) {
12220 fclose(in);
12221 return -1;
12222 }
12223
12224 while (fgets(buf, sizeof(buf), in)) {
12225 char *pos = strstr(buf, "<IMSI>");
12226 if (pos) {
12227 sigma_dut_print(dut, DUT_MSG_INFO, "Updated DevDetail IMSI to %s",
12228 imsi);
12229 pos += 6;
12230 *pos = '\0';
12231 fprintf(out, "%s%s</IMSI>\n", buf, imsi);
12232 found++;
12233 } else {
12234 fprintf(out, "%s", buf);
12235 }
12236 }
12237
12238 fclose(out);
12239 fclose(in);
12240 if (found)
12241 rename("devdetail.xml.tmp", "devdetail.xml");
12242 else
12243 unlink("devdetail.xml.tmp");
12244
12245 return 0;
12246}
12247
12248
12249static int sta_add_credential_sim(struct sigma_dut *dut,
12250 struct sigma_conn *conn,
12251 const char *ifname, struct sigma_cmd *cmd)
12252{
12253 const char *val, *imsi = NULL;
12254 int id;
12255 char buf[200];
12256 int res;
12257 const char *pos;
12258 size_t mnc_len;
12259 char plmn_mcc[4];
12260 char plmn_mnc[4];
12261
12262 id = add_cred(ifname);
12263 if (id < 0)
12264 return -2;
12265 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
12266
12267 val = get_param(cmd, "prefer");
12268 if (val && atoi(val) > 0)
12269 set_cred(ifname, id, "priority", "1");
12270
12271 val = get_param(cmd, "PLMN_MCC");
12272 if (val == NULL) {
12273 send_resp(dut, conn, SIGMA_ERROR,
12274 "errorCode,Missing PLMN_MCC");
12275 return 0;
12276 }
12277 if (strlen(val) != 3) {
12278 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MCC");
12279 return 0;
12280 }
12281 snprintf(plmn_mcc, sizeof(plmn_mcc), "%s", val);
12282
12283 val = get_param(cmd, "PLMN_MNC");
12284 if (val == NULL) {
12285 send_resp(dut, conn, SIGMA_ERROR,
12286 "errorCode,Missing PLMN_MNC");
12287 return 0;
12288 }
12289 if (strlen(val) != 2 && strlen(val) != 3) {
12290 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MNC");
12291 return 0;
12292 }
12293 snprintf(plmn_mnc, sizeof(plmn_mnc), "%s", val);
12294
12295 val = get_param(cmd, "IMSI");
12296 if (val == NULL) {
12297 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing SIM "
12298 "IMSI");
12299 return 0;
12300 }
12301
12302 imsi = pos = val;
12303
12304 if (strncmp(plmn_mcc, pos, 3) != 0) {
12305 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MCC mismatch");
12306 return 0;
12307 }
12308 pos += 3;
12309
12310 mnc_len = strlen(plmn_mnc);
12311 if (mnc_len < 2) {
12312 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC not set");
12313 return 0;
12314 }
12315
12316 if (strncmp(plmn_mnc, pos, mnc_len) != 0) {
12317 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC mismatch");
12318 return 0;
12319 }
12320 pos += mnc_len;
12321
12322 res = snprintf(buf, sizeof(buf), "%s%s-%s",plmn_mcc, plmn_mnc, pos);
12323 if (res < 0 || res >= (int) sizeof(buf))
12324 return -1;
12325 if (set_cred_quoted(ifname, id, "imsi", buf) < 0) {
12326 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12327 "not set IMSI");
12328 return 0;
12329 }
12330
12331 val = get_param(cmd, "Password");
12332 if (val && set_cred_quoted(ifname, id, "milenage", val) < 0) {
12333 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12334 "not set password");
12335 return 0;
12336 }
12337
Jouni Malinenba630452018-06-22 11:49:59 +030012338 if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012339 /*
12340 * Set provisioning_sp for the test cases where SIM/USIM
12341 * provisioning is used.
12342 */
12343 if (val && set_cred_quoted(ifname, id, "provisioning_sp",
12344 "wi-fi.org") < 0) {
12345 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12346 "not set provisioning_sp");
12347 return 0;
12348 }
12349
12350 update_devdetail_imsi(dut, imsi);
12351 }
12352
12353 return 1;
12354}
12355
12356
12357static int sta_add_credential_cert(struct sigma_dut *dut,
12358 struct sigma_conn *conn,
12359 const char *ifname,
12360 struct sigma_cmd *cmd)
12361{
12362 const char *val;
12363 int id;
12364
12365 id = add_cred(ifname);
12366 if (id < 0)
12367 return -2;
12368 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
12369
12370 val = get_param(cmd, "prefer");
12371 if (val && atoi(val) > 0)
12372 set_cred(ifname, id, "priority", "1");
12373
12374 val = get_param(cmd, "REALM");
12375 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
12376 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12377 "realm");
12378 return 0;
12379 }
12380
12381 val = get_param(cmd, "HOME_FQDN");
12382 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
12383 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12384 "home_fqdn");
12385 return 0;
12386 }
12387
12388 val = get_param(cmd, "Username");
12389 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
12390 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12391 "username");
12392 return 0;
12393 }
12394
12395 val = get_param(cmd, "clientCertificate");
12396 if (val) {
12397 char fname[200];
12398 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
12399#ifdef __linux__
12400 if (!file_exists(fname)) {
12401 char msg[300];
12402 snprintf(msg, sizeof(msg),
12403 "ErrorCode,clientCertificate "
12404 "file (%s) not found", fname);
12405 send_resp(dut, conn, SIGMA_ERROR, msg);
12406 return 0;
12407 }
12408#endif /* __linux__ */
12409 if (set_cred_quoted(ifname, id, "client_cert", fname) < 0) {
12410 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12411 "not set client_cert");
12412 return 0;
12413 }
12414 if (set_cred_quoted(ifname, id, "private_key", fname) < 0) {
12415 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12416 "not set private_key");
12417 return 0;
12418 }
12419 }
12420
12421 val = get_param(cmd, "ROOT_CA");
12422 if (val) {
12423 char fname[200];
12424 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
12425#ifdef __linux__
12426 if (!file_exists(fname)) {
12427 char msg[300];
12428 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
12429 "file (%s) not found", fname);
12430 send_resp(dut, conn, SIGMA_ERROR, msg);
12431 return 0;
12432 }
12433#endif /* __linux__ */
12434 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
12435 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12436 "not set root CA");
12437 return 0;
12438 }
12439 }
12440
12441 return 1;
12442}
12443
12444
Jouni Malinenf7222712019-06-13 01:50:21 +030012445static enum sigma_cmd_result cmd_sta_add_credential(struct sigma_dut *dut,
12446 struct sigma_conn *conn,
12447 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012448{
12449 const char *intf = get_param(cmd, "Interface");
12450 const char *type;
12451
12452 start_sta_mode(dut);
12453
12454 type = get_param(cmd, "Type");
12455 if (!type)
12456 return -1;
12457
12458 if (strcasecmp(type, "uname_pwd") == 0)
12459 return sta_add_credential_uname_pwd(dut, conn, intf, cmd);
12460
12461 if (strcasecmp(type, "sim") == 0)
12462 return sta_add_credential_sim(dut, conn, intf, cmd);
12463
12464 if (strcasecmp(type, "cert") == 0)
12465 return sta_add_credential_cert(dut, conn, intf, cmd);
12466
12467 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported credential "
12468 "type");
12469 return 0;
12470}
12471
12472
Jouni Malinenf7222712019-06-13 01:50:21 +030012473static enum sigma_cmd_result cmd_sta_scan(struct sigma_dut *dut,
12474 struct sigma_conn *conn,
12475 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012476{
12477 const char *intf = get_param(cmd, "Interface");
vamsi krishna89ad8c62017-09-19 12:51:18 +053012478 const char *val, *bssid, *ssid;
Arif Hussain66a4af02019-02-07 15:04:51 -080012479 char buf[4096];
vamsi krishna89ad8c62017-09-19 12:51:18 +053012480 char ssid_hex[65];
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012481 int res;
12482
Arif Hussain66a4af02019-02-07 15:04:51 -080012483 val = get_param(cmd, "GetParameter");
12484 if (val && strcmp(val, "SSID_BSSID") == 0) {
12485 if (get_wpa_ssid_bssid(dut, get_station_ifname(),
12486 buf, sizeof(buf)) < 0) {
12487 sigma_dut_print(dut, DUT_MSG_ERROR,
12488 "Could not get ssid bssid");
12489 return ERROR_SEND_STATUS;
12490 }
12491
12492 sigma_dut_print(dut, DUT_MSG_INFO, "%s", buf);
12493 send_resp(dut, conn, SIGMA_COMPLETE, buf);
12494 return STATUS_SENT;
12495 }
12496
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012497 val = get_param(cmd, "HESSID");
12498 if (val) {
12499 res = snprintf(buf, sizeof(buf), "SET hessid %s", val);
12500 if (res < 0 || res >= (int) sizeof(buf))
12501 return -1;
12502 wpa_command(intf, buf);
12503 }
12504
12505 val = get_param(cmd, "ACCS_NET_TYPE");
12506 if (val) {
12507 res = snprintf(buf, sizeof(buf), "SET access_network_type %s",
12508 val);
12509 if (res < 0 || res >= (int) sizeof(buf))
12510 return -1;
12511 wpa_command(intf, buf);
12512 }
12513
vamsi krishna89ad8c62017-09-19 12:51:18 +053012514 bssid = get_param(cmd, "Bssid");
12515 ssid = get_param(cmd, "Ssid");
12516
12517 if (ssid) {
12518 if (2 * strlen(ssid) >= sizeof(ssid_hex)) {
12519 send_resp(dut, conn, SIGMA_ERROR,
12520 "ErrorCode,Too long SSID");
12521 return 0;
12522 }
12523 ascii2hexstr(ssid, ssid_hex);
12524 }
12525
12526 res = snprintf(buf, sizeof(buf), "SCAN%s%s%s%s",
12527 bssid ? " bssid=": "",
12528 bssid ? bssid : "",
12529 ssid ? " ssid " : "",
12530 ssid ? ssid_hex : "");
12531 if (res < 0 || res >= (int) sizeof(buf))
12532 return -1;
12533
12534 if (wpa_command(intf, buf)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012535 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not start "
12536 "scan");
12537 return 0;
12538 }
12539
12540 return 1;
12541}
12542
12543
Jouni Malinenf7222712019-06-13 01:50:21 +030012544static enum sigma_cmd_result cmd_sta_scan_bss(struct sigma_dut *dut,
12545 struct sigma_conn *conn,
12546 struct sigma_cmd *cmd)
Jouni Malinen5e5d43d2018-01-10 17:29:33 +020012547{
12548 const char *intf = get_param(cmd, "Interface");
12549 const char *bssid;
12550 char buf[4096], *pos;
12551 int freq, chan;
12552 char *ssid;
12553 char resp[100];
12554 int res;
12555 struct wpa_ctrl *ctrl;
12556
12557 bssid = get_param(cmd, "BSSID");
12558 if (!bssid) {
12559 send_resp(dut, conn, SIGMA_INVALID,
12560 "errorCode,BSSID argument is missing");
12561 return 0;
12562 }
12563
12564 ctrl = open_wpa_mon(intf);
12565 if (!ctrl) {
12566 sigma_dut_print(dut, DUT_MSG_ERROR,
12567 "Failed to open wpa_supplicant monitor connection");
12568 return -1;
12569 }
12570
12571 if (wpa_command(intf, "SCAN TYPE=ONLY")) {
12572 send_resp(dut, conn, SIGMA_ERROR,
12573 "errorCode,Could not start scan");
12574 wpa_ctrl_detach(ctrl);
12575 wpa_ctrl_close(ctrl);
12576 return 0;
12577 }
12578
12579 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
12580 buf, sizeof(buf));
12581
12582 wpa_ctrl_detach(ctrl);
12583 wpa_ctrl_close(ctrl);
12584
12585 if (res < 0) {
12586 send_resp(dut, conn, SIGMA_ERROR,
12587 "errorCode,Scan did not complete");
12588 return 0;
12589 }
12590
12591 snprintf(buf, sizeof(buf), "BSS %s", bssid);
12592 if (wpa_command_resp(intf, buf, buf, sizeof(buf)) < 0 ||
12593 strncmp(buf, "id=", 3) != 0) {
12594 send_resp(dut, conn, SIGMA_ERROR,
12595 "errorCode,Specified BSSID not found");
12596 return 0;
12597 }
12598
12599 pos = strstr(buf, "\nfreq=");
12600 if (!pos) {
12601 send_resp(dut, conn, SIGMA_ERROR,
12602 "errorCode,Channel not found");
12603 return 0;
12604 }
12605 freq = atoi(pos + 6);
12606 chan = freq_to_channel(freq);
12607
12608 pos = strstr(buf, "\nssid=");
12609 if (!pos) {
12610 send_resp(dut, conn, SIGMA_ERROR,
12611 "errorCode,SSID not found");
12612 return 0;
12613 }
12614 ssid = pos + 6;
12615 pos = strchr(ssid, '\n');
12616 if (pos)
12617 *pos = '\0';
12618 snprintf(resp, sizeof(resp), "ssid,%s,bsschannel,%d", ssid, chan);
12619 send_resp(dut, conn, SIGMA_COMPLETE, resp);
12620 return 0;
12621}
12622
12623
Jouni Malinenf7222712019-06-13 01:50:21 +030012624static enum sigma_cmd_result cmd_sta_set_systime(struct sigma_dut *dut,
12625 struct sigma_conn *conn,
12626 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012627{
12628#ifdef __linux__
12629 struct timeval tv;
12630 struct tm tm;
12631 time_t t;
12632 const char *val;
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +053012633 int v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012634
12635 wpa_command(get_station_ifname(), "PMKSA_FLUSH");
12636
12637 memset(&tm, 0, sizeof(tm));
12638 val = get_param(cmd, "seconds");
12639 if (val)
12640 tm.tm_sec = atoi(val);
12641 val = get_param(cmd, "minutes");
12642 if (val)
12643 tm.tm_min = atoi(val);
12644 val = get_param(cmd, "hours");
12645 if (val)
12646 tm.tm_hour = atoi(val);
12647 val = get_param(cmd, "date");
12648 if (val)
12649 tm.tm_mday = atoi(val);
12650 val = get_param(cmd, "month");
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +053012651 if (val) {
12652 v = atoi(val);
12653 if (v < 1 || v > 12) {
12654 send_resp(dut, conn, SIGMA_INVALID,
12655 "errorCode,Invalid month");
12656 return 0;
12657 }
12658 tm.tm_mon = v - 1;
12659 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012660 val = get_param(cmd, "year");
12661 if (val) {
12662 int year = atoi(val);
12663#ifdef ANDROID
12664 if (year > 2035)
12665 year = 2035; /* years beyond 2035 not supported */
12666#endif /* ANDROID */
12667 tm.tm_year = year - 1900;
12668 }
12669 t = mktime(&tm);
12670 if (t == (time_t) -1) {
12671 send_resp(dut, conn, SIGMA_ERROR,
12672 "errorCode,Invalid date or time");
12673 return 0;
12674 }
12675
12676 memset(&tv, 0, sizeof(tv));
12677 tv.tv_sec = t;
12678
12679 if (settimeofday(&tv, NULL) < 0) {
12680 sigma_dut_print(dut, DUT_MSG_INFO, "settimeofday failed: %s",
12681 strerror(errno));
12682 send_resp(dut, conn, SIGMA_ERROR,
12683 "errorCode,Failed to set time");
12684 return 0;
12685 }
12686
12687 return 1;
12688#endif /* __linux__ */
12689
12690 return -1;
12691}
12692
12693
Jouni Malinenf7222712019-06-13 01:50:21 +030012694static enum sigma_cmd_result cmd_sta_osu(struct sigma_dut *dut,
12695 struct sigma_conn *conn,
12696 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012697{
12698 const char *intf = get_param(cmd, "Interface");
Jouni Malinen4c8681c2018-09-12 23:28:11 +030012699 const char *name, *osu_ssid, *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012700 int prod_ess_assoc = 1;
Jouni Malinen4c8681c2018-09-12 23:28:11 +030012701 char buf[300], bssid[100], ssid[100];
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012702 int res;
12703 struct wpa_ctrl *ctrl;
12704
12705 name = get_param(cmd, "osuFriendlyName");
Jouni Malinen4c8681c2018-09-12 23:28:11 +030012706 osu_ssid = get_param(cmd, "osu_ssid");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012707
12708 val = get_param(cmd, "ProdESSAssoc");
12709 if (val)
12710 prod_ess_assoc = atoi(val);
12711
12712 kill_dhcp_client(dut, intf);
12713 if (start_dhcp_client(dut, intf) < 0)
12714 return -2;
12715
12716 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger OSU");
12717 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
12718 res = snprintf(buf, sizeof(buf),
Jouni Malinen4c8681c2018-09-12 23:28:11 +030012719 "%s %s%s%s %s%s%s signup osu-ca.pem",
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012720 prod_ess_assoc ? "" : "-N",
12721 name ? "-O'" : "", name ? name : "",
Jouni Malinen4c8681c2018-09-12 23:28:11 +030012722 name ? "'" : "",
12723 osu_ssid ? "-o'" : "", osu_ssid ? osu_ssid : "",
12724 osu_ssid ? "'" : "");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012725
Kanchanapally, Vidyullatha12b66762015-12-31 16:46:42 +053012726 hs2_set_policy(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012727 if (run_hs20_osu(dut, buf) < 0) {
12728 FILE *f;
12729
12730 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to complete OSU");
12731
12732 f = fopen("hs20-osu-client.res", "r");
12733 if (f) {
12734 char resp[400], res[300], *pos;
12735 if (!fgets(res, sizeof(res), f))
12736 res[0] = '\0';
12737 pos = strchr(res, '\n');
12738 if (pos)
12739 *pos = '\0';
12740 fclose(f);
12741 sigma_dut_summary(dut, "hs20-osu-client provisioning failed: %s",
12742 res);
12743 snprintf(resp, sizeof(resp), "notify-send '%s'", res);
12744 if (system(resp) != 0) {
12745 }
12746 snprintf(resp, sizeof(resp),
12747 "SSID,,BSSID,,failureReason,%s", res);
12748 send_resp(dut, conn, SIGMA_COMPLETE, resp);
12749 return 0;
12750 }
12751
12752 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
12753 return 0;
12754 }
12755
12756 if (!prod_ess_assoc)
12757 goto report;
12758
12759 ctrl = open_wpa_mon(intf);
12760 if (ctrl == NULL) {
12761 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
12762 "wpa_supplicant monitor connection");
12763 return -1;
12764 }
12765
12766 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
12767 buf, sizeof(buf));
12768
12769 wpa_ctrl_detach(ctrl);
12770 wpa_ctrl_close(ctrl);
12771
12772 if (res < 0) {
12773 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to connect to "
12774 "network after OSU");
12775 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
12776 return 0;
12777 }
12778
12779report:
12780 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
12781 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
12782 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to get BSSID/SSID");
12783 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
12784 return 0;
12785 }
12786
12787 snprintf(buf, sizeof(buf), "SSID,%s,BSSID,%s", ssid, bssid);
12788 send_resp(dut, conn, SIGMA_COMPLETE, buf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012789 return 0;
12790}
12791
12792
Jouni Malinenf7222712019-06-13 01:50:21 +030012793static enum sigma_cmd_result cmd_sta_policy_update(struct sigma_dut *dut,
12794 struct sigma_conn *conn,
12795 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012796{
12797 const char *val;
12798 int timeout = 120;
12799
12800 val = get_param(cmd, "PolicyUpdate");
12801 if (val == NULL || atoi(val) == 0)
12802 return 1; /* No operation requested */
12803
12804 val = get_param(cmd, "Timeout");
12805 if (val)
12806 timeout = atoi(val);
12807
12808 if (timeout) {
12809 /* TODO: time out the command and return
12810 * PolicyUpdateStatus,TIMEOUT if needed. */
12811 }
12812
12813 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger policy update");
12814 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
12815 if (run_hs20_osu(dut, "pol_upd fqdn=wi-fi.org") < 0) {
12816 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,FAIL");
12817 return 0;
12818 }
12819
12820 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,SUCCESS");
12821 return 0;
12822}
12823
12824
Jouni Malinenf7222712019-06-13 01:50:21 +030012825static enum sigma_cmd_result cmd_sta_er_config(struct sigma_dut *dut,
12826 struct sigma_conn *conn,
12827 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012828{
12829 struct wpa_ctrl *ctrl;
12830 const char *intf = get_param(cmd, "Interface");
12831 const char *bssid = get_param(cmd, "Bssid");
12832 const char *ssid = get_param(cmd, "SSID");
12833 const char *security = get_param(cmd, "Security");
12834 const char *passphrase = get_param(cmd, "Passphrase");
12835 const char *pin = get_param(cmd, "PIN");
12836 char buf[1000];
12837 char ssid_hex[200], passphrase_hex[200];
12838 const char *keymgmt, *cipher;
12839
12840 if (intf == NULL)
12841 intf = get_main_ifname();
12842
12843 if (!bssid) {
12844 send_resp(dut, conn, SIGMA_ERROR,
12845 "ErrorCode,Missing Bssid argument");
12846 return 0;
12847 }
12848
12849 if (!ssid) {
12850 send_resp(dut, conn, SIGMA_ERROR,
12851 "ErrorCode,Missing SSID argument");
12852 return 0;
12853 }
12854
12855 if (!security) {
12856 send_resp(dut, conn, SIGMA_ERROR,
12857 "ErrorCode,Missing Security argument");
12858 return 0;
12859 }
12860
12861 if (!passphrase) {
12862 send_resp(dut, conn, SIGMA_ERROR,
12863 "ErrorCode,Missing Passphrase argument");
12864 return 0;
12865 }
12866
12867 if (!pin) {
12868 send_resp(dut, conn, SIGMA_ERROR,
12869 "ErrorCode,Missing PIN argument");
12870 return 0;
12871 }
12872
vamsi krishna8c9c1562017-05-12 15:51:46 +053012873 if (2 * strlen(ssid) >= sizeof(ssid_hex) ||
12874 2 * strlen(passphrase) >= sizeof(passphrase_hex)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012875 send_resp(dut, conn, SIGMA_ERROR,
12876 "ErrorCode,Too long SSID/passphrase");
12877 return 0;
12878 }
12879
12880 ctrl = open_wpa_mon(intf);
12881 if (ctrl == NULL) {
12882 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
12883 "wpa_supplicant monitor connection");
12884 return -2;
12885 }
12886
12887 if (strcasecmp(security, "wpa2-psk") == 0) {
12888 keymgmt = "WPA2PSK";
12889 cipher = "CCMP";
12890 } else {
12891 wpa_ctrl_detach(ctrl);
12892 wpa_ctrl_close(ctrl);
12893 send_resp(dut, conn, SIGMA_ERROR,
12894 "ErrorCode,Unsupported Security value");
12895 return 0;
12896 }
12897
12898 ascii2hexstr(ssid, ssid_hex);
12899 ascii2hexstr(passphrase, passphrase_hex);
12900 snprintf(buf, sizeof(buf), "WPS_REG %s %s %s %s %s %s",
12901 bssid, pin, ssid_hex, keymgmt, cipher, passphrase_hex);
12902
12903 if (wpa_command(intf, buf) < 0) {
12904 wpa_ctrl_detach(ctrl);
12905 wpa_ctrl_close(ctrl);
12906 send_resp(dut, conn, SIGMA_ERROR,
12907 "ErrorCode,Failed to start registrar");
12908 return 0;
12909 }
12910
12911 snprintf(dut->er_oper_bssid, sizeof(dut->er_oper_bssid), "%s", bssid);
12912 dut->er_oper_performed = 1;
12913
12914 return wps_connection_event(dut, conn, ctrl, intf, 0);
12915}
12916
12917
Jouni Malinenf7222712019-06-13 01:50:21 +030012918static enum sigma_cmd_result
12919cmd_sta_wps_connect_pw_token(struct sigma_dut *dut, struct sigma_conn *conn,
12920 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012921{
12922 struct wpa_ctrl *ctrl;
12923 const char *intf = get_param(cmd, "Interface");
12924 const char *bssid = get_param(cmd, "Bssid");
12925 char buf[100];
12926
12927 if (!bssid) {
12928 send_resp(dut, conn, SIGMA_ERROR,
12929 "ErrorCode,Missing Bssid argument");
12930 return 0;
12931 }
12932
12933 ctrl = open_wpa_mon(intf);
12934 if (ctrl == NULL) {
12935 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
12936 "wpa_supplicant monitor connection");
12937 return -2;
12938 }
12939
12940 snprintf(buf, sizeof(buf), "WPS_NFC %s", bssid);
12941
12942 if (wpa_command(intf, buf) < 0) {
12943 wpa_ctrl_detach(ctrl);
12944 wpa_ctrl_close(ctrl);
12945 send_resp(dut, conn, SIGMA_ERROR,
12946 "ErrorCode,Failed to start registrar");
12947 return 0;
12948 }
12949
12950 return wps_connection_event(dut, conn, ctrl, intf, 0);
12951}
12952
12953
Jouni Malinenf7222712019-06-13 01:50:21 +030012954static enum sigma_cmd_result cmd_start_wps_registration(struct sigma_dut *dut,
12955 struct sigma_conn *conn,
12956 struct sigma_cmd *cmd)
vamsi krishna9b144002017-09-20 13:28:13 +053012957{
12958 struct wpa_ctrl *ctrl;
12959 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020012960 const char *network_mode = get_param(cmd, "network_mode");
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020012961 const char *config_method = get_param(cmd, "WPSConfigMethod");
12962 const char *role;
vamsi krishna9b144002017-09-20 13:28:13 +053012963 int res;
12964 char buf[256];
12965 const char *events[] = {
12966 "CTRL-EVENT-CONNECTED",
12967 "WPS-OVERLAP-DETECTED",
12968 "WPS-TIMEOUT",
12969 "WPS-FAIL",
12970 NULL
12971 };
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020012972 int id = 0;
vamsi krishna9b144002017-09-20 13:28:13 +053012973
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020012974 /* 60G WPS tests do not pass Interface parameter */
12975 if (!intf)
12976 intf = get_main_ifname();
12977
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020012978 if (dut->mode == SIGMA_MODE_AP)
12979 return ap_wps_registration(dut, conn, cmd);
12980
12981 if (config_method) {
12982 /* WFA_CS_WPS_PIN_KEYPAD mode is set when using the
12983 * sta_wps_enter_pin before calling start_wps_registration. */
12984 if (strcasecmp(config_method, "PBC") == 0)
12985 dut->wps_method = WFA_CS_WPS_PBC;
12986 }
12987 if (dut->wps_method == WFA_CS_WPS_NOT_READY) {
12988 send_resp(dut, conn, SIGMA_ERROR,
12989 "ErrorCode,WPS parameters not yet set");
12990 return STATUS_SENT;
12991 }
12992
12993 /* Make sure WPS is enabled (also for STA mode) */
12994 dut->wps_disable = 0;
12995
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020012996 if (dut->band == WPS_BAND_60G && network_mode &&
12997 strcasecmp(network_mode, "PBSS") == 0) {
12998 sigma_dut_print(dut, DUT_MSG_DEBUG,
12999 "Set PBSS network mode, network id %d", id);
13000 if (set_network(get_station_ifname(), id, "pbss", "1") < 0)
13001 return -2;
13002 }
13003
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020013004 if (dut->force_rsn_ie) {
13005 sigma_dut_print(dut, DUT_MSG_DEBUG, "Force RSN_IE: %d",
13006 dut->force_rsn_ie);
13007 if (sta_60g_force_rsn_ie(dut, dut->force_rsn_ie) < 0) {
13008 sigma_dut_print(dut, DUT_MSG_INFO,
13009 "Failed to force RSN_IE");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020013010 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020013011 }
13012 }
13013
vamsi krishna9b144002017-09-20 13:28:13 +053013014 ctrl = open_wpa_mon(intf);
13015 if (!ctrl) {
13016 sigma_dut_print(dut, DUT_MSG_ERROR,
13017 "Failed to open wpa_supplicant monitor connection");
13018 return -2;
13019 }
13020
13021 role = get_param(cmd, "WpsRole");
13022 if (!role) {
13023 send_resp(dut, conn, SIGMA_INVALID,
13024 "ErrorCode,WpsRole not provided");
13025 goto fail;
13026 }
13027
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020013028 if (strcasecmp(role, "Enrollee") != 0) {
13029 /* Registrar role for STA not supported */
13030 send_resp(dut, conn, SIGMA_ERROR,
13031 "ErrorCode,Unsupported WpsRole value");
13032 goto fail;
13033 }
13034
13035 if (is_60g_sigma_dut(dut)) {
13036 if (dut->wps_method == WFA_CS_WPS_PBC)
13037 snprintf(buf, sizeof(buf), "WPS_PBC");
13038 else /* WFA_CS_WPS_PIN_KEYPAD */
13039 snprintf(buf, sizeof(buf), "WPS_PIN any %s",
13040 dut->wps_pin);
13041 if (wpa_command(intf, buf) < 0) {
13042 send_resp(dut, conn, SIGMA_ERROR,
13043 "ErrorCode,Failed to start WPS");
vamsi krishna9b144002017-09-20 13:28:13 +053013044 goto fail;
13045 }
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020013046 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
13047 if (res < 0) {
13048 send_resp(dut, conn, SIGMA_ERROR,
13049 "ErrorCode,WPS connection did not complete");
13050 goto fail;
13051 }
13052 if (strstr(buf, "WPS-TIMEOUT")) {
13053 send_resp(dut, conn, SIGMA_COMPLETE, "WpsState,NoPeer");
13054 } else if (strstr(buf, "WPS-OVERLAP-DETECTED")) {
13055 send_resp(dut, conn, SIGMA_COMPLETE,
13056 "WpsState,OverlapSession");
13057 } else if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
13058 send_resp(dut, conn, SIGMA_COMPLETE,
13059 "WpsState,Successful");
13060 } else {
13061 send_resp(dut, conn, SIGMA_COMPLETE,
13062 "WpsState,Failure");
13063 }
13064 } else {
13065 if (dut->wps_method == WFA_CS_WPS_PBC) {
vamsi krishna9b144002017-09-20 13:28:13 +053013066 if (wpa_command(intf, "WPS_PBC") < 0) {
13067 send_resp(dut, conn, SIGMA_ERROR,
13068 "ErrorCode,Failed to enable PBC");
13069 goto fail;
13070 }
13071 } else {
13072 /* TODO: PIN method */
13073 send_resp(dut, conn, SIGMA_ERROR,
13074 "ErrorCode,Unsupported WpsConfigMethod value");
13075 goto fail;
13076 }
13077 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
13078 if (res < 0) {
13079 send_resp(dut, conn, SIGMA_ERROR,
13080 "ErrorCode,WPS connection did not complete");
13081 goto fail;
13082 }
13083 if (strstr(buf, "WPS-TIMEOUT")) {
13084 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,NoPeer");
13085 } else if (strstr(buf, "WPS-OVERLAP-DETECTED")) {
13086 send_resp(dut, conn, SIGMA_ERROR,
13087 "ErrorCode,OverlapSession");
13088 } else if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
13089 send_resp(dut, conn, SIGMA_COMPLETE, "Successful");
13090 } else {
13091 send_resp(dut, conn, SIGMA_ERROR,
13092 "ErrorCode,WPS operation failed");
13093 }
vamsi krishna9b144002017-09-20 13:28:13 +053013094 }
13095
13096fail:
13097 wpa_ctrl_detach(ctrl);
13098 wpa_ctrl_close(ctrl);
13099 return 0;
13100}
13101
13102
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013103static int req_intf(struct sigma_cmd *cmd)
13104{
13105 return get_param(cmd, "interface") == NULL ? -1 : 0;
13106}
13107
13108
13109void sta_register_cmds(void)
13110{
13111 sigma_dut_reg_cmd("sta_get_ip_config", req_intf,
13112 cmd_sta_get_ip_config);
13113 sigma_dut_reg_cmd("sta_set_ip_config", req_intf,
13114 cmd_sta_set_ip_config);
13115 sigma_dut_reg_cmd("sta_get_info", req_intf, cmd_sta_get_info);
13116 sigma_dut_reg_cmd("sta_get_mac_address", req_intf,
13117 cmd_sta_get_mac_address);
13118 sigma_dut_reg_cmd("sta_is_connected", req_intf, cmd_sta_is_connected);
13119 sigma_dut_reg_cmd("sta_verify_ip_connection", req_intf,
13120 cmd_sta_verify_ip_connection);
13121 sigma_dut_reg_cmd("sta_get_bssid", req_intf, cmd_sta_get_bssid);
13122 sigma_dut_reg_cmd("sta_set_encryption", req_intf,
13123 cmd_sta_set_encryption);
13124 sigma_dut_reg_cmd("sta_set_psk", req_intf, cmd_sta_set_psk);
13125 sigma_dut_reg_cmd("sta_set_eaptls", req_intf, cmd_sta_set_eaptls);
13126 sigma_dut_reg_cmd("sta_set_eapttls", req_intf, cmd_sta_set_eapttls);
13127 sigma_dut_reg_cmd("sta_set_eapsim", req_intf, cmd_sta_set_eapsim);
13128 sigma_dut_reg_cmd("sta_set_peap", req_intf, cmd_sta_set_peap);
13129 sigma_dut_reg_cmd("sta_set_eapfast", req_intf, cmd_sta_set_eapfast);
13130 sigma_dut_reg_cmd("sta_set_eapaka", req_intf, cmd_sta_set_eapaka);
13131 sigma_dut_reg_cmd("sta_set_eapakaprime", req_intf,
13132 cmd_sta_set_eapakaprime);
13133 sigma_dut_reg_cmd("sta_set_security", req_intf, cmd_sta_set_security);
13134 sigma_dut_reg_cmd("sta_set_uapsd", req_intf, cmd_sta_set_uapsd);
13135 /* TODO: sta_set_ibss */
13136 /* TODO: sta_set_mode */
13137 sigma_dut_reg_cmd("sta_set_wmm", req_intf, cmd_sta_set_wmm);
13138 sigma_dut_reg_cmd("sta_associate", req_intf, cmd_sta_associate);
13139 /* TODO: sta_up_load */
13140 sigma_dut_reg_cmd("sta_preset_testparameters", req_intf,
13141 cmd_sta_preset_testparameters);
13142 /* TODO: sta_set_system */
13143 sigma_dut_reg_cmd("sta_set_11n", req_intf, cmd_sta_set_11n);
13144 /* TODO: sta_set_rifs_test */
13145 sigma_dut_reg_cmd("sta_set_wireless", req_intf, cmd_sta_set_wireless);
13146 sigma_dut_reg_cmd("sta_send_addba", req_intf, cmd_sta_send_addba);
13147 /* TODO: sta_send_coexist_mgmt */
13148 sigma_dut_reg_cmd("sta_disconnect", req_intf, cmd_sta_disconnect);
13149 sigma_dut_reg_cmd("sta_reassoc", req_intf, cmd_sta_reassoc);
13150 sigma_dut_reg_cmd("sta_reassociate", req_intf, cmd_sta_reassoc);
13151 sigma_dut_reg_cmd("sta_reset_default", req_intf,
13152 cmd_sta_reset_default);
13153 sigma_dut_reg_cmd("sta_send_frame", req_intf, cmd_sta_send_frame);
13154 sigma_dut_reg_cmd("sta_set_macaddr", req_intf, cmd_sta_set_macaddr);
13155 sigma_dut_reg_cmd("sta_set_rfeature", req_intf, cmd_sta_set_rfeature);
13156 sigma_dut_reg_cmd("sta_set_radio", req_intf, cmd_sta_set_radio);
13157 sigma_dut_reg_cmd("sta_set_pwrsave", req_intf, cmd_sta_set_pwrsave);
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020013158 sigma_dut_reg_cmd("sta_set_power_save", req_intf, cmd_sta_set_pwrsave);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013159 sigma_dut_reg_cmd("sta_bssid_pool", req_intf, cmd_sta_bssid_pool);
13160 sigma_dut_reg_cmd("sta_reset_parm", req_intf, cmd_sta_reset_parm);
13161 sigma_dut_reg_cmd("sta_get_key", req_intf, cmd_sta_get_key);
13162 sigma_dut_reg_cmd("sta_hs2_associate", req_intf,
13163 cmd_sta_hs2_associate);
Jouni Malinenb639f1c2018-09-13 02:39:46 +030013164 sigma_dut_reg_cmd("sta_hs2_venue_info", req_intf,
13165 cmd_sta_hs2_venue_info);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013166 sigma_dut_reg_cmd("sta_add_credential", req_intf,
13167 cmd_sta_add_credential);
13168 sigma_dut_reg_cmd("sta_scan", req_intf, cmd_sta_scan);
Jouni Malinen5e5d43d2018-01-10 17:29:33 +020013169 sigma_dut_reg_cmd("sta_scan_bss", req_intf, cmd_sta_scan_bss);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013170 sigma_dut_reg_cmd("sta_set_systime", NULL, cmd_sta_set_systime);
13171 sigma_dut_reg_cmd("sta_osu", req_intf, cmd_sta_osu);
13172 sigma_dut_reg_cmd("sta_policy_update", req_intf, cmd_sta_policy_update);
13173 sigma_dut_reg_cmd("sta_er_config", NULL, cmd_sta_er_config);
13174 sigma_dut_reg_cmd("sta_wps_connect_pw_token", req_intf,
13175 cmd_sta_wps_connect_pw_token);
Jouni Malinen82905202018-04-29 17:20:10 +030013176 sigma_dut_reg_cmd("sta_exec_action", NULL, cmd_sta_exec_action);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013177 sigma_dut_reg_cmd("sta_get_events", req_intf, cmd_sta_get_events);
13178 sigma_dut_reg_cmd("sta_get_parameter", req_intf, cmd_sta_get_parameter);
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020013179 sigma_dut_reg_cmd("start_wps_registration", NULL,
vamsi krishna9b144002017-09-20 13:28:13 +053013180 cmd_start_wps_registration);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013181}