blob: bcf9f4516f725bda1e1ebee3b5aa2b6e2b3c6c61 [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
Jouni Malinen8ac93452019-08-14 15:19:13 +03002175static enum sigma_cmd_result set_trust_root_system(struct sigma_dut *dut,
2176 struct sigma_conn *conn,
2177 const char *ifname, int id)
2178{
2179 char buf[200];
2180
2181 snprintf(buf, sizeof(buf), "%s/certs", sigma_cert_path);
2182 if (!file_exists(buf))
2183 strlcpy(buf, "/system/etc/security/cacerts", sizeof(buf));
2184 if (!file_exists(buf))
2185 strlcpy(buf, "/etc/ssl/certs", sizeof(buf));
2186 if (!file_exists(buf)) {
2187 char msg[300];
2188
2189 snprintf(msg, sizeof(msg),
2190 "ErrorCode,trustedRootCA system store (%s) not found",
2191 buf);
2192 send_resp(dut, conn, SIGMA_ERROR, msg);
2193 return STATUS_SENT_ERROR;
2194 }
2195
2196 if (set_network_quoted(ifname, id, "ca_path", buf) < 0)
2197 return ERROR_SEND_STATUS;
2198
2199 return SUCCESS_SEND_STATUS;
2200}
2201
2202
2203static enum sigma_cmd_result set_trust_root(struct sigma_dut *dut,
2204 struct sigma_conn *conn,
2205 const char *ifname, int id,
2206 const char *val)
2207{
2208 char buf[200];
2209#ifdef ANDROID
2210 unsigned char kvalue[KEYSTORE_MESSAGE_SIZE];
2211 int length;
2212#endif /* ANDROID */
2213
2214 if (strcmp(val, "DEFAULT") == 0)
2215 return set_trust_root_system(dut, conn, ifname, id);
2216
2217#ifdef ANDROID
2218 snprintf(buf, sizeof(buf), "CACERT_%s", val);
2219 length = android_keystore_get(ANDROID_KEYSTORE_GET, buf, kvalue);
2220 if (length > 0) {
2221 sigma_dut_print(dut, DUT_MSG_INFO, "Use Android keystore [%s]",
2222 buf);
2223 snprintf(buf, sizeof(buf), "keystore://CACERT_%s", val);
2224 goto ca_cert_selected;
2225 }
2226#endif /* ANDROID */
2227
2228 snprintf(buf, sizeof(buf), "%s/%s", sigma_cert_path, val);
2229#ifdef __linux__
2230 if (!file_exists(buf)) {
2231 char msg[300];
2232
2233 snprintf(msg, sizeof(msg),
2234 "ErrorCode,trustedRootCA file (%s) not found", buf);
2235 send_resp(dut, conn, SIGMA_ERROR, msg);
2236 return STATUS_SENT_ERROR;
2237 }
2238#endif /* __linux__ */
2239#ifdef ANDROID
2240ca_cert_selected:
2241#endif /* ANDROID */
2242 if (set_network_quoted(ifname, id, "ca_cert", buf) < 0)
2243 return ERROR_SEND_STATUS;
2244
2245 return SUCCESS_SEND_STATUS;
2246}
2247
2248
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002249static int set_eap_common(struct sigma_dut *dut, struct sigma_conn *conn,
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302250 const char *ifname, int username_identity,
2251 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002252{
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302253 const char *val, *alg, *akm;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002254 int id;
Jouni Malinen53264f62019-05-03 13:04:40 +03002255 char buf[200], buf2[300];
Jouni Malinen8179fee2019-03-28 03:19:47 +02002256 int erp = 0;
Jouni Malinen8ac93452019-08-14 15:19:13 +03002257 enum sigma_cmd_result res;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002258
2259 id = set_wpa_common(dut, conn, ifname, cmd);
2260 if (id < 0)
2261 return id;
2262
2263 val = get_param(cmd, "keyMgmtType");
2264 alg = get_param(cmd, "micAlg");
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302265 akm = get_param(cmd, "AKMSuiteType");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002266
Jouni Malinenad395a22017-09-01 21:13:46 +03002267 if (val && strcasecmp(val, "SuiteB") == 0) {
2268 if (set_network(ifname, id, "key_mgmt", "WPA-EAP-SUITE-B-192") <
2269 0)
2270 return -2;
2271 } else if (alg && strcasecmp(alg, "SHA-256") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002272 if (set_network(ifname, id, "key_mgmt", "WPA-EAP-SHA256") < 0)
2273 return -2;
2274 } else if (alg && strcasecmp(alg, "SHA-1") == 0) {
2275 if (set_network(ifname, id, "key_mgmt", "WPA-EAP") < 0)
2276 return -2;
2277 } else if (val && strcasecmp(val, "wpa2-ft") == 0) {
2278 if (set_network(ifname, id, "key_mgmt", "FT-EAP") < 0)
2279 return -2;
Jouni Malinend6a9d692019-03-28 03:01:24 +02002280 } else if (!akm &&
2281 ((val && strcasecmp(val, "wpa2-sha256") == 0) ||
2282 dut->sta_pmf == STA_PMF_REQUIRED)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002283 if (set_network(ifname, id, "key_mgmt",
2284 "WPA-EAP WPA-EAP-SHA256") < 0)
2285 return -2;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302286 } else if (akm && atoi(akm) == 14) {
2287 if (dut->sta_pmf == STA_PMF_OPTIONAL ||
2288 dut->sta_pmf == STA_PMF_REQUIRED) {
2289 if (set_network(ifname, id, "key_mgmt",
2290 "WPA-EAP-SHA256 FILS-SHA256") < 0)
2291 return -2;
2292 } else {
2293 if (set_network(ifname, id, "key_mgmt",
2294 "WPA-EAP FILS-SHA256") < 0)
2295 return -2;
2296 }
2297
Jouni Malinen8179fee2019-03-28 03:19:47 +02002298 erp = 1;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302299 } else if (akm && atoi(akm) == 15) {
2300 if (dut->sta_pmf == STA_PMF_OPTIONAL ||
2301 dut->sta_pmf == STA_PMF_REQUIRED) {
2302 if (set_network(ifname, id, "key_mgmt",
2303 "WPA-EAP-SHA256 FILS-SHA384") < 0)
2304 return -2;
2305 } else {
2306 if (set_network(ifname, id, "key_mgmt",
2307 "WPA-EAP FILS-SHA384") < 0)
2308 return -2;
2309 }
2310
Jouni Malinen8179fee2019-03-28 03:19:47 +02002311 erp = 1;
Jouni Malinend6a9d692019-03-28 03:01:24 +02002312 } else if (!akm && dut->sta_pmf == STA_PMF_OPTIONAL) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002313 if (set_network(ifname, id, "key_mgmt",
2314 "WPA-EAP WPA-EAP-SHA256") < 0)
2315 return -2;
Jouni Malinend6a9d692019-03-28 03:01:24 +02002316 } else if (!akm) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002317 if (set_network(ifname, id, "key_mgmt", "WPA-EAP") < 0)
2318 return -2;
2319 }
2320
2321 val = get_param(cmd, "trustedRootCA");
2322 if (val) {
Jouni Malinen8ac93452019-08-14 15:19:13 +03002323 res = set_trust_root(dut, conn, ifname, id, val);
2324 if (res != SUCCESS_SEND_STATUS)
2325 return res;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002326 }
2327
Jouni Malinen53264f62019-05-03 13:04:40 +03002328 val = get_param(cmd, "ServerCert");
2329 if (val) {
2330 FILE *f;
2331 char *result = NULL, *pos;
2332
2333 snprintf(buf, sizeof(buf), "%s/%s.sha256", sigma_cert_path,
2334 val);
2335 f = fopen(buf, "r");
2336 if (f) {
2337 result = fgets(buf, sizeof(buf), f);
2338 fclose(f);
2339 }
2340 if (!result) {
2341 snprintf(buf2, sizeof(buf2),
2342 "ErrorCode,ServerCert hash could not be read from %s",
2343 buf);
2344 send_resp(dut, conn, SIGMA_ERROR, buf2);
2345 return STATUS_SENT_ERROR;
2346 }
2347 pos = strchr(buf, '\n');
2348 if (pos)
2349 *pos = '\0';
2350 snprintf(buf2, sizeof(buf2), "hash://server/sha256/%s", buf);
2351 if (set_network_quoted(ifname, id, "ca_cert", buf2) < 0)
2352 return ERROR_SEND_STATUS;
Jouni Malinen29108dc2019-06-13 23:42:11 +03002353
2354 snprintf(buf, sizeof(buf), "%s/%s.tod", sigma_cert_path, val);
2355 if (file_exists(buf)) {
2356 sigma_dut_print(dut, DUT_MSG_DEBUG,
2357 "TOD policy enabled for the configured ServerCert hash");
2358 dut->sta_tod_policy = 1;
2359 }
Jouni Malinen53264f62019-05-03 13:04:40 +03002360 }
2361
Jouni Malinen96f84b02019-05-03 12:32:56 +03002362 val = get_param(cmd, "Domain");
2363 if (val && set_network_quoted(ifname, id, "domain_match", val) < 0)
2364 return ERROR_SEND_STATUS;
2365
2366 val = get_param(cmd, "DomainSuffix");
2367 if (val &&
2368 set_network_quoted(ifname, id, "domain_suffix_match", val) < 0)
2369 return ERROR_SEND_STATUS;
2370
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302371 if (username_identity) {
2372 val = get_param(cmd, "username");
2373 if (val) {
2374 if (set_network_quoted(ifname, id, "identity", val) < 0)
2375 return -2;
2376 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002377
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302378 val = get_param(cmd, "password");
2379 if (val) {
2380 if (set_network_quoted(ifname, id, "password", val) < 0)
2381 return -2;
2382 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002383 }
2384
Jouni Malinen8179fee2019-03-28 03:19:47 +02002385 if (dut->akm_values &
2386 ((1 << AKM_FILS_SHA256) |
2387 (1 << AKM_FILS_SHA384) |
2388 (1 << AKM_FT_FILS_SHA256) |
2389 (1 << AKM_FT_FILS_SHA384)))
2390 erp = 1;
2391 if (erp && set_network(ifname, id, "erp", "1") < 0)
2392 return ERROR_SEND_STATUS;
2393
Jouni Malinen134fe3c2019-06-12 04:16:49 +03002394 dut->sta_associate_wait_connect = 1;
2395
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002396 return id;
2397}
2398
2399
Jouni Malinen5eabb2a2017-10-03 18:17:30 +03002400static int set_tls_cipher(const char *ifname, int id, const char *cipher)
2401{
2402 const char *val;
2403
2404 if (!cipher)
2405 return 0;
2406
2407 if (strcasecmp(cipher, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384") == 0)
2408 val = "ECDHE-ECDSA-AES256-GCM-SHA384";
2409 else if (strcasecmp(cipher,
2410 "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384") == 0)
2411 val = "ECDHE-RSA-AES256-GCM-SHA384";
2412 else if (strcasecmp(cipher, "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384") == 0)
2413 val = "DHE-RSA-AES256-GCM-SHA384";
2414 else if (strcasecmp(cipher,
2415 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256") == 0)
2416 val = "ECDHE-ECDSA-AES128-GCM-SHA256";
2417 else
2418 return -1;
2419
2420 /* Need to clear phase1="tls_suiteb=1" to allow cipher enforcement */
2421 set_network_quoted(ifname, id, "phase1", "");
2422
2423 return set_network_quoted(ifname, id, "openssl_ciphers", val);
2424}
2425
2426
Jouni Malinenf7222712019-06-13 01:50:21 +03002427static enum sigma_cmd_result cmd_sta_set_eaptls(struct sigma_dut *dut,
2428 struct sigma_conn *conn,
2429 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002430{
2431 const char *intf = get_param(cmd, "Interface");
2432 const char *ifname, *val;
2433 int id;
2434 char buf[200];
2435#ifdef ANDROID
2436 unsigned char kvalue[KEYSTORE_MESSAGE_SIZE];
2437 int length;
2438 int jb_or_newer = 0;
2439 char prop[PROPERTY_VALUE_MAX];
2440#endif /* ANDROID */
2441
2442 if (intf == NULL)
2443 return -1;
2444
2445 if (strcmp(intf, get_main_ifname()) == 0)
2446 ifname = get_station_ifname();
2447 else
2448 ifname = intf;
2449
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302450 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002451 if (id < 0)
2452 return id;
2453
2454 if (set_network(ifname, id, "eap", "TLS") < 0)
2455 return -2;
2456
Pradeep Reddy POTTETI9f6c2132016-05-05 16:28:19 +05302457 if (!get_param(cmd, "username") &&
2458 set_network_quoted(ifname, id, "identity",
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002459 "wifi-user@wifilabs.local") < 0)
2460 return -2;
2461
2462 val = get_param(cmd, "clientCertificate");
2463 if (val == NULL)
2464 return -1;
2465#ifdef ANDROID
2466 snprintf(buf, sizeof(buf), "USRPKEY_%s", val);
2467 length = android_keystore_get(ANDROID_KEYSTORE_GET, buf, kvalue);
2468 if (length < 0) {
2469 /*
2470 * JB started reporting keystore type mismatches, so retry with
2471 * the GET_PUBKEY command if the generic GET fails.
2472 */
2473 length = android_keystore_get(ANDROID_KEYSTORE_GET_PUBKEY,
2474 buf, kvalue);
2475 }
2476
2477 if (property_get("ro.build.version.release", prop, NULL) != 0) {
2478 sigma_dut_print(dut, DUT_MSG_DEBUG, "Android release %s", prop);
2479 if (strncmp(prop, "4.0", 3) != 0)
2480 jb_or_newer = 1;
2481 } else
2482 jb_or_newer = 1; /* assume newer */
2483
2484 if (jb_or_newer && length > 0) {
2485 sigma_dut_print(dut, DUT_MSG_INFO,
2486 "Use Android keystore [%s]", buf);
2487 if (set_network(ifname, id, "engine", "1") < 0)
2488 return -2;
2489 if (set_network_quoted(ifname, id, "engine_id", "keystore") < 0)
2490 return -2;
2491 snprintf(buf, sizeof(buf), "USRPKEY_%s", val);
2492 if (set_network_quoted(ifname, id, "key_id", buf) < 0)
2493 return -2;
2494 snprintf(buf, sizeof(buf), "keystore://USRCERT_%s", val);
2495 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
2496 return -2;
2497 return 1;
2498 } else if (length > 0) {
2499 sigma_dut_print(dut, DUT_MSG_INFO,
2500 "Use Android keystore [%s]", buf);
2501 snprintf(buf, sizeof(buf), "keystore://USRPKEY_%s", val);
2502 if (set_network_quoted(ifname, id, "private_key", buf) < 0)
2503 return -2;
2504 snprintf(buf, sizeof(buf), "keystore://USRCERT_%s", val);
2505 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
2506 return -2;
2507 return 1;
2508 }
2509#endif /* ANDROID */
2510
2511 snprintf(buf, sizeof(buf), "%s/%s", sigma_cert_path, val);
2512#ifdef __linux__
2513 if (!file_exists(buf)) {
2514 char msg[300];
2515 snprintf(msg, sizeof(msg), "ErrorCode,clientCertificate file "
2516 "(%s) not found", buf);
2517 send_resp(dut, conn, SIGMA_ERROR, msg);
2518 return -3;
2519 }
2520#endif /* __linux__ */
2521 if (set_network_quoted(ifname, id, "private_key", buf) < 0)
2522 return -2;
2523 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
2524 return -2;
2525
2526 if (set_network_quoted(ifname, id, "private_key_passwd", "wifi") < 0)
2527 return -2;
2528
Jouni Malinen5eabb2a2017-10-03 18:17:30 +03002529 val = get_param(cmd, "keyMgmtType");
2530 if (val && strcasecmp(val, "SuiteB") == 0) {
2531 val = get_param(cmd, "CertType");
2532 if (val && strcasecmp(val, "RSA") == 0) {
2533 if (set_network_quoted(ifname, id, "phase1",
2534 "tls_suiteb=1") < 0)
2535 return -2;
2536 } else {
2537 if (set_network_quoted(ifname, id, "openssl_ciphers",
2538 "SUITEB192") < 0)
2539 return -2;
2540 }
2541
2542 val = get_param(cmd, "TLSCipher");
2543 if (set_tls_cipher(ifname, id, val) < 0) {
2544 send_resp(dut, conn, SIGMA_ERROR,
2545 "ErrorCode,Unsupported TLSCipher value");
2546 return -3;
2547 }
2548 }
2549
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002550 return 1;
2551}
2552
2553
Jouni Malinenf7222712019-06-13 01:50:21 +03002554static enum sigma_cmd_result cmd_sta_set_eapttls(struct sigma_dut *dut,
2555 struct sigma_conn *conn,
2556 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002557{
2558 const char *intf = get_param(cmd, "Interface");
2559 const char *ifname;
2560 int id;
2561
2562 if (intf == NULL)
2563 return -1;
2564
2565 if (strcmp(intf, get_main_ifname()) == 0)
2566 ifname = get_station_ifname();
2567 else
2568 ifname = intf;
2569
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302570 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002571 if (id < 0)
2572 return id;
2573
2574 if (set_network(ifname, id, "eap", "TTLS") < 0) {
2575 send_resp(dut, conn, SIGMA_ERROR,
2576 "errorCode,Failed to set TTLS method");
2577 return 0;
2578 }
2579
2580 if (set_network_quoted(ifname, id, "phase2", "auth=MSCHAPV2") < 0) {
2581 send_resp(dut, conn, SIGMA_ERROR,
2582 "errorCode,Failed to set MSCHAPv2 for TTLS Phase 2");
2583 return 0;
2584 }
2585
2586 return 1;
2587}
2588
2589
Jouni Malinenf7222712019-06-13 01:50:21 +03002590static enum sigma_cmd_result cmd_sta_set_eapsim(struct sigma_dut *dut,
2591 struct sigma_conn *conn,
2592 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002593{
2594 const char *intf = get_param(cmd, "Interface");
2595 const char *ifname;
2596 int id;
2597
2598 if (intf == NULL)
2599 return -1;
2600
2601 if (strcmp(intf, get_main_ifname()) == 0)
2602 ifname = get_station_ifname();
2603 else
2604 ifname = intf;
2605
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302606 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002607 if (id < 0)
2608 return id;
2609
2610 if (set_network(ifname, id, "eap", "SIM") < 0)
2611 return -2;
2612
2613 return 1;
2614}
2615
2616
Jouni Malinenf7222712019-06-13 01:50:21 +03002617static enum sigma_cmd_result cmd_sta_set_peap(struct sigma_dut *dut,
2618 struct sigma_conn *conn,
2619 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002620{
2621 const char *intf = get_param(cmd, "Interface");
2622 const char *ifname, *val;
2623 int id;
2624 char buf[100];
2625
2626 if (intf == NULL)
2627 return -1;
2628
2629 if (strcmp(intf, get_main_ifname()) == 0)
2630 ifname = get_station_ifname();
2631 else
2632 ifname = intf;
2633
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302634 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002635 if (id < 0)
2636 return id;
2637
2638 if (set_network(ifname, id, "eap", "PEAP") < 0)
2639 return -2;
2640
2641 val = get_param(cmd, "innerEAP");
2642 if (val) {
2643 if (strcasecmp(val, "MSCHAPv2") == 0) {
2644 if (set_network_quoted(ifname, id, "phase2",
2645 "auth=MSCHAPV2") < 0)
2646 return -2;
2647 } else if (strcasecmp(val, "GTC") == 0) {
2648 if (set_network_quoted(ifname, id, "phase2",
2649 "auth=GTC") < 0)
2650 return -2;
2651 } else
2652 return -1;
2653 }
2654
2655 val = get_param(cmd, "peapVersion");
2656 if (val) {
2657 int ver = atoi(val);
2658 if (ver < 0 || ver > 1)
2659 return -1;
2660 snprintf(buf, sizeof(buf), "peapver=%d", ver);
2661 if (set_network_quoted(ifname, id, "phase1", buf) < 0)
2662 return -2;
2663 }
2664
2665 return 1;
2666}
2667
2668
Jouni Malinenf7222712019-06-13 01:50:21 +03002669static enum sigma_cmd_result cmd_sta_set_eapfast(struct sigma_dut *dut,
2670 struct sigma_conn *conn,
2671 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002672{
2673 const char *intf = get_param(cmd, "Interface");
2674 const char *ifname, *val;
2675 int id;
2676 char buf[100];
2677
2678 if (intf == NULL)
2679 return -1;
2680
2681 if (strcmp(intf, get_main_ifname()) == 0)
2682 ifname = get_station_ifname();
2683 else
2684 ifname = intf;
2685
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302686 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002687 if (id < 0)
2688 return id;
2689
2690 if (set_network(ifname, id, "eap", "FAST") < 0)
2691 return -2;
2692
2693 val = get_param(cmd, "innerEAP");
2694 if (val) {
2695 if (strcasecmp(val, "MSCHAPV2") == 0) {
2696 if (set_network_quoted(ifname, id, "phase2",
2697 "auth=MSCHAPV2") < 0)
2698 return -2;
2699 } else if (strcasecmp(val, "GTC") == 0) {
2700 if (set_network_quoted(ifname, id, "phase2",
2701 "auth=GTC") < 0)
2702 return -2;
2703 } else
2704 return -1;
2705 }
2706
2707 val = get_param(cmd, "validateServer");
2708 if (val) {
2709 /* TODO */
2710 sigma_dut_print(dut, DUT_MSG_INFO, "Ignored EAP-FAST "
2711 "validateServer=%s", val);
2712 }
2713
2714 val = get_param(cmd, "pacFile");
2715 if (val) {
2716 snprintf(buf, sizeof(buf), "blob://%s", val);
2717 if (set_network_quoted(ifname, id, "pac_file", buf) < 0)
2718 return -2;
2719 }
2720
2721 if (set_network_quoted(ifname, id, "phase1", "fast_provisioning=2") <
2722 0)
2723 return -2;
2724
2725 return 1;
2726}
2727
2728
Jouni Malinenf7222712019-06-13 01:50:21 +03002729static enum sigma_cmd_result cmd_sta_set_eapaka(struct sigma_dut *dut,
2730 struct sigma_conn *conn,
2731 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002732{
2733 const char *intf = get_param(cmd, "Interface");
2734 const char *ifname;
2735 int id;
2736
2737 if (intf == NULL)
2738 return -1;
2739
2740 if (strcmp(intf, get_main_ifname()) == 0)
2741 ifname = get_station_ifname();
2742 else
2743 ifname = intf;
2744
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302745 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002746 if (id < 0)
2747 return id;
2748
2749 if (set_network(ifname, id, "eap", "AKA") < 0)
2750 return -2;
2751
2752 return 1;
2753}
2754
2755
Jouni Malinenf7222712019-06-13 01:50:21 +03002756static enum sigma_cmd_result cmd_sta_set_eapakaprime(struct sigma_dut *dut,
2757 struct sigma_conn *conn,
2758 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002759{
2760 const char *intf = get_param(cmd, "Interface");
2761 const char *ifname;
2762 int id;
2763
2764 if (intf == NULL)
2765 return -1;
2766
2767 if (strcmp(intf, get_main_ifname()) == 0)
2768 ifname = get_station_ifname();
2769 else
2770 ifname = intf;
2771
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302772 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002773 if (id < 0)
2774 return id;
2775
2776 if (set_network(ifname, id, "eap", "AKA'") < 0)
2777 return -2;
2778
2779 return 1;
2780}
2781
2782
2783static int sta_set_open(struct sigma_dut *dut, struct sigma_conn *conn,
2784 struct sigma_cmd *cmd)
2785{
2786 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002787 const char *network_mode = get_param(cmd, "network_mode");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002788 const char *ifname;
2789 int id;
2790
2791 if (strcmp(intf, get_main_ifname()) == 0)
2792 ifname = get_station_ifname();
2793 else
2794 ifname = intf;
2795
2796 id = add_network_common(dut, conn, ifname, cmd);
2797 if (id < 0)
2798 return id;
2799
2800 if (set_network(ifname, id, "key_mgmt", "NONE") < 0)
2801 return -2;
2802
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002803 if (dut->program == PROGRAM_60GHZ && network_mode &&
2804 strcasecmp(network_mode, "PBSS") == 0 &&
2805 set_network(ifname, id, "pbss", "1") < 0)
2806 return -2;
2807
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002808 return 1;
2809}
2810
2811
Jouni Malinen47dcc952017-10-09 16:43:24 +03002812static int sta_set_owe(struct sigma_dut *dut, struct sigma_conn *conn,
2813 struct sigma_cmd *cmd)
2814{
2815 const char *intf = get_param(cmd, "Interface");
2816 const char *ifname, *val;
2817 int id;
2818
2819 if (intf == NULL)
2820 return -1;
2821
2822 if (strcmp(intf, get_main_ifname()) == 0)
2823 ifname = get_station_ifname();
2824 else
2825 ifname = intf;
2826
2827 id = set_wpa_common(dut, conn, ifname, cmd);
2828 if (id < 0)
2829 return id;
2830
2831 if (set_network(ifname, id, "key_mgmt", "OWE") < 0)
2832 return -2;
2833
2834 val = get_param(cmd, "ECGroupID");
Jouni Malinenfac9cad2017-10-10 18:35:55 +03002835 if (val && strcmp(val, "0") == 0) {
2836 if (wpa_command(ifname,
2837 "VENDOR_ELEM_ADD 13 ff23200000783590fb7440e03d5b3b33911f86affdcc6b4411b707846ac4ff08ddc8831ccd") != 0) {
2838 sigma_dut_print(dut, DUT_MSG_ERROR,
2839 "Failed to set OWE DH Param element override");
2840 return -2;
2841 }
2842 } else if (val && set_network(ifname, id, "owe_group", val) < 0) {
Jouni Malinen47dcc952017-10-09 16:43:24 +03002843 sigma_dut_print(dut, DUT_MSG_ERROR,
2844 "Failed to clear owe_group");
2845 return -2;
2846 }
2847
2848 return 1;
2849}
2850
2851
Jouni Malinenf7222712019-06-13 01:50:21 +03002852static enum sigma_cmd_result cmd_sta_set_security(struct sigma_dut *dut,
2853 struct sigma_conn *conn,
2854 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002855{
2856 const char *type = get_param(cmd, "Type");
2857
2858 if (type == NULL) {
2859 send_resp(dut, conn, SIGMA_ERROR,
2860 "ErrorCode,Missing Type argument");
2861 return 0;
2862 }
2863
2864 if (strcasecmp(type, "OPEN") == 0)
2865 return sta_set_open(dut, conn, cmd);
Jouni Malinen47dcc952017-10-09 16:43:24 +03002866 if (strcasecmp(type, "OWE") == 0)
2867 return sta_set_owe(dut, conn, cmd);
Jouni Malinen992a81e2017-08-22 13:57:47 +03002868 if (strcasecmp(type, "PSK") == 0 ||
Jouni Malinen0ab50f42017-08-31 01:34:59 +03002869 strcasecmp(type, "PSK-SAE") == 0 ||
Jouni Malinen992a81e2017-08-22 13:57:47 +03002870 strcasecmp(type, "SAE") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002871 return cmd_sta_set_psk(dut, conn, cmd);
2872 if (strcasecmp(type, "EAPTLS") == 0)
2873 return cmd_sta_set_eaptls(dut, conn, cmd);
2874 if (strcasecmp(type, "EAPTTLS") == 0)
2875 return cmd_sta_set_eapttls(dut, conn, cmd);
2876 if (strcasecmp(type, "EAPPEAP") == 0)
2877 return cmd_sta_set_peap(dut, conn, cmd);
2878 if (strcasecmp(type, "EAPSIM") == 0)
2879 return cmd_sta_set_eapsim(dut, conn, cmd);
2880 if (strcasecmp(type, "EAPFAST") == 0)
2881 return cmd_sta_set_eapfast(dut, conn, cmd);
2882 if (strcasecmp(type, "EAPAKA") == 0)
2883 return cmd_sta_set_eapaka(dut, conn, cmd);
2884 if (strcasecmp(type, "EAPAKAPRIME") == 0)
2885 return cmd_sta_set_eapakaprime(dut, conn, cmd);
Amarnath Hullur Subramanyam81b11cd2018-01-30 19:07:17 -08002886 if (strcasecmp(type, "wep") == 0)
2887 return cmd_sta_set_encryption(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002888
2889 send_resp(dut, conn, SIGMA_ERROR,
2890 "ErrorCode,Unsupported Type value");
2891 return 0;
2892}
2893
2894
2895int ath6kl_client_uapsd(struct sigma_dut *dut, const char *intf, int uapsd)
2896{
2897#ifdef __linux__
2898 /* special handling for ath6kl */
2899 char path[128], fname[128], *pos;
2900 ssize_t res;
2901 FILE *f;
2902
Jouni Malinene39cd562019-05-29 23:39:56 +03002903 res = snprintf(fname, sizeof(fname), "/sys/class/net/%s/phy80211",
2904 intf);
2905 if (res < 0 || res >= sizeof(fname))
2906 return 0;
2907 res = readlink(fname, path, sizeof(path));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002908 if (res < 0)
2909 return 0; /* not ath6kl */
2910
2911 if (res >= (int) sizeof(path))
2912 res = sizeof(path) - 1;
2913 path[res] = '\0';
2914 pos = strrchr(path, '/');
2915 if (pos == NULL)
2916 pos = path;
2917 else
2918 pos++;
2919 snprintf(fname, sizeof(fname),
2920 "/sys/kernel/debug/ieee80211/%s/ath6kl/"
2921 "create_qos", pos);
2922 if (!file_exists(fname))
2923 return 0; /* not ath6kl */
2924
2925 if (uapsd) {
2926 f = fopen(fname, "w");
2927 if (f == NULL)
2928 return -1;
2929
2930 sigma_dut_print(dut, DUT_MSG_DEBUG, "Use ath6kl create_qos");
2931 fprintf(f, "4 2 2 1 2 9999999 9999999 9999999 7777777 0 4 "
2932 "45000 200 56789000 56789000 5678900 0 0 9999999 "
2933 "20000 0\n");
2934 fclose(f);
2935 } else {
2936 snprintf(fname, sizeof(fname),
2937 "/sys/kernel/debug/ieee80211/%s/ath6kl/"
2938 "delete_qos", pos);
2939
2940 f = fopen(fname, "w");
2941 if (f == NULL)
2942 return -1;
2943
2944 sigma_dut_print(dut, DUT_MSG_DEBUG, "Use ath6kl delete_qos");
2945 fprintf(f, "2 4\n");
2946 fclose(f);
2947 }
2948#endif /* __linux__ */
2949
2950 return 0;
2951}
2952
2953
Jouni Malinenf7222712019-06-13 01:50:21 +03002954static enum sigma_cmd_result cmd_sta_set_uapsd(struct sigma_dut *dut,
2955 struct sigma_conn *conn,
2956 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002957{
2958 const char *intf = get_param(cmd, "Interface");
2959 /* const char *ssid = get_param(cmd, "ssid"); */
2960 const char *val;
2961 int max_sp_len = 4;
2962 int ac_be = 1, ac_bk = 1, ac_vi = 1, ac_vo = 1;
2963 char buf[100];
2964 int ret1, ret2;
2965
2966 val = get_param(cmd, "maxSPLength");
2967 if (val) {
2968 max_sp_len = atoi(val);
2969 if (max_sp_len != 0 && max_sp_len != 1 && max_sp_len != 2 &&
2970 max_sp_len != 4)
2971 return -1;
2972 }
2973
2974 val = get_param(cmd, "acBE");
2975 if (val)
2976 ac_be = atoi(val);
2977
2978 val = get_param(cmd, "acBK");
2979 if (val)
2980 ac_bk = atoi(val);
2981
2982 val = get_param(cmd, "acVI");
2983 if (val)
2984 ac_vi = atoi(val);
2985
2986 val = get_param(cmd, "acVO");
2987 if (val)
2988 ac_vo = atoi(val);
2989
2990 dut->client_uapsd = ac_be || ac_bk || ac_vi || ac_vo;
2991
2992 snprintf(buf, sizeof(buf), "P2P_SET client_apsd %d,%d,%d,%d;%d",
2993 ac_be, ac_bk, ac_vi, ac_vo, max_sp_len);
2994 ret1 = wpa_command(intf, buf);
2995
2996 snprintf(buf, sizeof(buf), "SET uapsd %d,%d,%d,%d;%d",
2997 ac_be, ac_bk, ac_vi, ac_vo, max_sp_len);
2998 ret2 = wpa_command(intf, buf);
2999
3000 if (ret1 && ret2) {
3001 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to set client mode "
3002 "UAPSD parameters.");
3003 return -2;
3004 }
3005
3006 if (ath6kl_client_uapsd(dut, intf, dut->client_uapsd) < 0) {
3007 send_resp(dut, conn, SIGMA_ERROR,
3008 "ErrorCode,Failed to set ath6kl QoS parameters");
3009 return 0;
3010 }
3011
3012 return 1;
3013}
3014
3015
Jouni Malinenf7222712019-06-13 01:50:21 +03003016static enum sigma_cmd_result cmd_sta_set_wmm(struct sigma_dut *dut,
3017 struct sigma_conn *conn,
3018 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003019{
3020 char buf[1000];
3021 const char *intf = get_param(cmd, "Interface");
3022 const char *grp = get_param(cmd, "Group");
3023 const char *act = get_param(cmd, "Action");
3024 const char *tid = get_param(cmd, "Tid");
3025 const char *dir = get_param(cmd, "Direction");
3026 const char *psb = get_param(cmd, "Psb");
3027 const char *up = get_param(cmd, "Up");
3028 const char *fixed = get_param(cmd, "Fixed");
3029 const char *size = get_param(cmd, "Size");
3030 const char *msize = get_param(cmd, "Maxsize");
3031 const char *minsi = get_param(cmd, "Min_srvc_intrvl");
3032 const char *maxsi = get_param(cmd, "Max_srvc_intrvl");
3033 const char *inact = get_param(cmd, "Inactivity");
3034 const char *sus = get_param(cmd, "Suspension");
3035 const char *mindr = get_param(cmd, "Mindatarate");
3036 const char *meandr = get_param(cmd, "Meandatarate");
3037 const char *peakdr = get_param(cmd, "Peakdatarate");
3038 const char *phyrate = get_param(cmd, "Phyrate");
3039 const char *burstsize = get_param(cmd, "Burstsize");
3040 const char *sba = get_param(cmd, "Sba");
3041 int direction;
3042 int handle;
Peng Xu93319622017-10-04 17:58:16 -07003043 float sba_fv = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003044 int fixed_int;
3045 int psb_ts;
3046
3047 if (intf == NULL || grp == NULL || act == NULL )
3048 return -1;
3049
3050 if (strcasecmp(act, "addts") == 0) {
3051 if (tid == NULL || dir == NULL || psb == NULL ||
3052 up == NULL || fixed == NULL || size == NULL)
3053 return -1;
3054
3055 /*
3056 * Note: Sigma CAPI spec lists uplink, downlink, and bidi as the
3057 * possible values, but WMM-AC and V-E test scripts use "UP,
3058 * "DOWN", and "BIDI".
3059 */
3060 if (strcasecmp(dir, "uplink") == 0 ||
3061 strcasecmp(dir, "up") == 0) {
3062 direction = 0;
3063 } else if (strcasecmp(dir, "downlink") == 0 ||
3064 strcasecmp(dir, "down") == 0) {
3065 direction = 1;
3066 } else if (strcasecmp(dir, "bidi") == 0) {
3067 direction = 2;
3068 } else {
3069 sigma_dut_print(dut, DUT_MSG_ERROR,
3070 "Direction %s not supported", dir);
3071 return -1;
3072 }
3073
3074 if (strcasecmp(psb, "legacy") == 0) {
3075 psb_ts = 0;
3076 } else if (strcasecmp(psb, "uapsd") == 0) {
3077 psb_ts = 1;
3078 } else {
3079 sigma_dut_print(dut, DUT_MSG_ERROR,
3080 "PSB %s not supported", psb);
3081 return -1;
3082 }
3083
3084 if (atoi(tid) < 0 || atoi(tid) > 7) {
3085 sigma_dut_print(dut, DUT_MSG_ERROR,
3086 "TID %s not supported", tid);
3087 return -1;
3088 }
3089
3090 if (strcasecmp(fixed, "true") == 0) {
3091 fixed_int = 1;
3092 } else {
3093 fixed_int = 0;
3094 }
3095
Peng Xu93319622017-10-04 17:58:16 -07003096 if (sba)
3097 sba_fv = atof(sba);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003098
3099 dut->dialog_token++;
3100 handle = 7000 + dut->dialog_token;
3101
3102 /*
3103 * size: convert to hex
3104 * maxsi: convert to hex
3105 * mindr: convert to hex
3106 * meandr: convert to hex
3107 * peakdr: convert to hex
3108 * burstsize: convert to hex
3109 * phyrate: convert to hex
3110 * sba: convert to hex with modification
3111 * minsi: convert to integer
3112 * sus: convert to integer
3113 * inact: convert to integer
3114 * maxsi: convert to integer
3115 */
3116
3117 /*
3118 * The Nominal MSDU Size field is 2 octets long and contains an
3119 * unsigned integer that specifies the nominal size, in octets,
3120 * of MSDUs belonging to the traffic under this traffic
3121 * specification and is defined in Figure 16. If the Fixed
3122 * subfield is set to 1, then the size of the MSDU is fixed and
3123 * is indicated by the Size Subfield. If the Fixed subfield is
3124 * set to 0, then the size of the MSDU might not be fixed and
3125 * the Size indicates the nominal MSDU size.
3126 *
3127 * The Surplus Bandwidth Allowance Factor field is 2 octets long
3128 * and specifies the excess allocation of time (and bandwidth)
3129 * over and above the stated rates required to transport an MSDU
3130 * belonging to the traffic in this TSPEC. This field is
3131 * represented as an unsigned binary number with an implicit
3132 * binary point after the leftmost 3 bits. For example, an SBA
3133 * of 1.75 is represented as 0x3800. This field is included to
3134 * account for retransmissions. As such, the value of this field
3135 * must be greater than unity.
3136 */
3137
3138 snprintf(buf, sizeof(buf),
3139 "iwpriv %s addTspec %d %s %d %d %s 0x%X"
3140 " 0x%X 0x%X 0x%X"
3141 " 0x%X 0x%X 0x%X"
3142 " 0x%X %d %d %d %d"
3143 " %d %d",
3144 intf, handle, tid, direction, psb_ts, up,
3145 (unsigned int) ((fixed_int << 15) | atoi(size)),
3146 msize ? atoi(msize) : 0,
3147 mindr ? atoi(mindr) : 0,
3148 meandr ? atoi(meandr) : 0,
3149 peakdr ? atoi(peakdr) : 0,
3150 burstsize ? atoi(burstsize) : 0,
3151 phyrate ? atoi(phyrate) : 0,
3152 sba ? ((unsigned int) (((int) sba_fv << 13) |
3153 (int)((sba_fv - (int) sba_fv) *
3154 8192))) : 0,
3155 minsi ? atoi(minsi) : 0,
3156 sus ? atoi(sus) : 0,
3157 0, 0,
3158 inact ? atoi(inact) : 0,
3159 maxsi ? atoi(maxsi) : 0);
3160
3161 if (system(buf) != 0) {
3162 sigma_dut_print(dut, DUT_MSG_ERROR,
3163 "iwpriv addtspec request failed");
3164 send_resp(dut, conn, SIGMA_ERROR,
3165 "errorCode,Failed to execute addTspec command");
3166 return 0;
3167 }
3168
3169 sigma_dut_print(dut, DUT_MSG_INFO,
3170 "iwpriv addtspec request send");
3171
3172 /* Mapping handle to a TID */
3173 dut->tid_to_handle[atoi(tid)] = handle;
3174 } else if (strcasecmp(act, "delts") == 0) {
3175 if (tid == NULL)
3176 return -1;
3177
3178 if (atoi(tid) < 0 || atoi(tid) > 7) {
3179 sigma_dut_print(dut, DUT_MSG_ERROR,
3180 "TID %s not supported", tid);
3181 send_resp(dut, conn, SIGMA_ERROR,
3182 "errorCode,Unsupported TID");
3183 return 0;
3184 }
3185
3186 handle = dut->tid_to_handle[atoi(tid)];
3187
3188 if (handle < 7000 || handle > 7255) {
3189 /* Invalid handle ie no mapping for that TID */
3190 sigma_dut_print(dut, DUT_MSG_ERROR,
3191 "handle-> %d not found", handle);
3192 }
3193
3194 snprintf(buf, sizeof(buf), "iwpriv %s delTspec %d",
3195 intf, handle);
3196
3197 if (system(buf) != 0) {
3198 sigma_dut_print(dut, DUT_MSG_ERROR,
3199 "iwpriv deltspec request failed");
3200 send_resp(dut, conn, SIGMA_ERROR,
3201 "errorCode,Failed to execute delTspec command");
3202 return 0;
3203 }
3204
3205 sigma_dut_print(dut, DUT_MSG_INFO,
3206 "iwpriv deltspec request send");
3207
3208 dut->tid_to_handle[atoi(tid)] = 0;
3209 } else {
3210 sigma_dut_print(dut, DUT_MSG_ERROR,
3211 "Action type %s not supported", act);
3212 send_resp(dut, conn, SIGMA_ERROR,
3213 "errorCode,Unsupported Action");
3214 return 0;
3215 }
3216
3217 return 1;
3218}
3219
3220
vamsi krishna52e16f92017-08-29 12:37:34 +05303221static int find_network(struct sigma_dut *dut, const char *ssid)
3222{
3223 char list[4096];
3224 char *pos;
3225
3226 sigma_dut_print(dut, DUT_MSG_DEBUG,
3227 "Search for profile based on SSID: '%s'", ssid);
3228 if (wpa_command_resp(get_station_ifname(), "LIST_NETWORKS",
3229 list, sizeof(list)) < 0)
3230 return -1;
3231 pos = strstr(list, ssid);
3232 if (!pos || pos == list || pos[-1] != '\t' || pos[strlen(ssid)] != '\t')
3233 return -1;
3234
3235 while (pos > list && pos[-1] != '\n')
3236 pos--;
3237 dut->infra_network_id = atoi(pos);
3238 snprintf(dut->infra_ssid, sizeof(dut->infra_ssid), "%s", ssid);
3239 return 0;
3240}
3241
3242
Sunil Dutt44595082018-02-12 19:41:45 +05303243#ifdef NL80211_SUPPORT
3244static int sta_config_rsnie(struct sigma_dut *dut, int val)
3245{
3246 struct nl_msg *msg;
3247 int ret;
3248 struct nlattr *params;
3249 int ifindex;
3250
3251 ifindex = if_nametoindex("wlan0");
3252 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
3253 NL80211_CMD_VENDOR)) ||
3254 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
3255 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
3256 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
3257 QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION) ||
3258 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
3259 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE, val)) {
3260 sigma_dut_print(dut, DUT_MSG_ERROR,
3261 "%s: err in adding vendor_cmd and vendor_data",
3262 __func__);
3263 nlmsg_free(msg);
3264 return -1;
3265 }
3266 nla_nest_end(msg, params);
3267
3268 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
3269 if (ret) {
3270 sigma_dut_print(dut, DUT_MSG_ERROR,
3271 "%s: err in send_and_recv_msgs, ret=%d",
3272 __func__, ret);
3273 return ret;
3274 }
3275
3276 return 0;
3277}
3278#endif /* NL80211_SUPPORT */
3279
3280
Jouni Malinenf7222712019-06-13 01:50:21 +03003281static enum sigma_cmd_result cmd_sta_associate(struct sigma_dut *dut,
3282 struct sigma_conn *conn,
3283 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003284{
3285 /* const char *intf = get_param(cmd, "Interface"); */
3286 const char *ssid = get_param(cmd, "ssid");
3287 const char *wps_param = get_param(cmd, "WPS");
3288 const char *bssid = get_param(cmd, "bssid");
Jouni Malinen46a19b62017-06-23 14:31:27 +03003289 const char *chan = get_param(cmd, "channel");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02003290 const char *network_mode = get_param(cmd, "network_mode");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003291 int wps = 0;
Jouni Malinen3c367e82017-06-23 17:01:47 +03003292 char buf[1000], extra[50];
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003293 int e;
3294 enum sigma_cmd_result ret = SUCCESS_SEND_STATUS;
3295 struct wpa_ctrl *ctrl = NULL;
3296 int num_network_not_found = 0;
3297 int num_disconnected = 0;
3298 int tod = -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003299
3300 if (ssid == NULL)
3301 return -1;
3302
Jouni Malinen3c367e82017-06-23 17:01:47 +03003303 if (dut->rsne_override) {
Sunil Dutt44595082018-02-12 19:41:45 +05303304#ifdef NL80211_SUPPORT
3305 if (get_driver_type() == DRIVER_WCN) {
3306 sta_config_rsnie(dut, 1);
3307 dut->config_rsnie = 1;
3308 }
3309#endif /* NL80211_SUPPORT */
Jouni Malinen3c367e82017-06-23 17:01:47 +03003310 snprintf(buf, sizeof(buf), "TEST_ASSOC_IE %s",
3311 dut->rsne_override);
3312 if (wpa_command(get_station_ifname(), buf) < 0) {
3313 send_resp(dut, conn, SIGMA_ERROR,
3314 "ErrorCode,Failed to set DEV_CONFIGURE_IE RSNE override");
3315 return 0;
3316 }
3317 }
3318
Jouni Malinen68143132017-09-02 02:34:08 +03003319 if (dut->sae_commit_override) {
3320 snprintf(buf, sizeof(buf), "SET sae_commit_override %s",
3321 dut->sae_commit_override);
3322 if (wpa_command(get_station_ifname(), buf) < 0) {
3323 send_resp(dut, conn, SIGMA_ERROR,
3324 "ErrorCode,Failed to set SAE commit override");
3325 return 0;
3326 }
3327 }
Ankita Bajaj1bde7942018-01-09 19:15:01 +05303328#ifdef ANDROID
3329 if (dut->fils_hlp)
3330 process_fils_hlp(dut);
3331#endif /* ANDROID */
Jouni Malinen68143132017-09-02 02:34:08 +03003332
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003333 if (wps_param &&
3334 (strcmp(wps_param, "1") == 0 || strcasecmp(wps_param, "On") == 0))
3335 wps = 1;
3336
3337 if (wps) {
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02003338 if (dut->program == PROGRAM_60GHZ && network_mode &&
3339 strcasecmp(network_mode, "PBSS") == 0 &&
3340 set_network(get_station_ifname(), dut->infra_network_id,
3341 "pbss", "1") < 0)
3342 return -2;
3343
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003344 if (dut->wps_method == WFA_CS_WPS_NOT_READY) {
3345 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,WPS "
3346 "parameters not yet set");
3347 return 0;
3348 }
3349 if (dut->wps_method == WFA_CS_WPS_PBC) {
3350 if (wpa_command(get_station_ifname(), "WPS_PBC") < 0)
3351 return -2;
3352 } else {
3353 snprintf(buf, sizeof(buf), "WPS_PIN any %s",
3354 dut->wps_pin);
3355 if (wpa_command(get_station_ifname(), buf) < 0)
3356 return -2;
3357 }
3358 } else {
vamsi krishna52e16f92017-08-29 12:37:34 +05303359 if (strcmp(ssid, dut->infra_ssid) == 0) {
3360 sigma_dut_print(dut, DUT_MSG_DEBUG,
3361 "sta_associate for the most recently added network");
3362 } else if (find_network(dut, ssid) < 0) {
3363 sigma_dut_print(dut, DUT_MSG_DEBUG,
3364 "sta_associate for a previously stored network profile");
3365 send_resp(dut, conn, SIGMA_ERROR,
3366 "ErrorCode,Profile not found");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003367 return 0;
3368 }
3369
3370 if (bssid &&
3371 set_network(get_station_ifname(), dut->infra_network_id,
3372 "bssid", bssid) < 0) {
3373 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
3374 "Invalid bssid argument");
3375 return 0;
3376 }
3377
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003378 if (dut->program == PROGRAM_WPA3 &&
3379 dut->sta_associate_wait_connect) {
3380 ctrl = open_wpa_mon(get_station_ifname());
3381 if (!ctrl)
3382 return ERROR_SEND_STATUS;
3383 }
3384
Jouni Malinen46a19b62017-06-23 14:31:27 +03003385 extra[0] = '\0';
3386 if (chan)
3387 snprintf(extra, sizeof(extra), " freq=%u",
Alexei Avshalom Lazar093569f2018-11-13 14:08:17 +02003388 channel_to_freq(dut, atoi(chan)));
Jouni Malinen46a19b62017-06-23 14:31:27 +03003389 snprintf(buf, sizeof(buf), "SELECT_NETWORK %d%s",
3390 dut->infra_network_id, extra);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003391 if (wpa_command(get_station_ifname(), buf) < 0) {
3392 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to select "
3393 "network id %d on %s",
3394 dut->infra_network_id,
3395 get_station_ifname());
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003396 ret = ERROR_SEND_STATUS;
3397 goto done;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003398 }
3399 }
3400
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003401 if (!ctrl)
3402 return SUCCESS_SEND_STATUS;
3403
3404 /* Wait for connection result to be able to store server certificate
3405 * hash for trust root override testing
3406 * (dev_exec_action,ServerCertTrust). */
3407
3408 for (e = 0; e < 20; e++) {
3409 const char *events[] = {
3410 "CTRL-EVENT-EAP-PEER-CERT",
3411 "CTRL-EVENT-EAP-TLS-CERT-ERROR",
3412 "CTRL-EVENT-DISCONNECTED",
3413 "CTRL-EVENT-CONNECTED",
3414 "CTRL-EVENT-NETWORK-NOT-FOUND",
3415 NULL
3416 };
3417 char buf[1024];
3418 int res;
3419
3420 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
3421 if (res < 0) {
3422 send_resp(dut, conn, SIGMA_ERROR,
3423 "ErrorCode,Association did not complete");
3424 ret = STATUS_SENT_ERROR;
3425 break;
3426 }
3427 sigma_dut_print(dut, DUT_MSG_DEBUG, "Connection event: %s",
3428 buf);
3429
3430 if (strstr(buf, "CTRL-EVENT-EAP-PEER-CERT") &&
3431 strstr(buf, " depth=0")) {
3432 char *pos = strstr(buf, " hash=");
3433
3434 if (pos) {
3435 char *end;
3436
Jouni Malinen34b19cb2019-08-16 16:37:17 +03003437 if (strstr(buf, " tod=1"))
3438 tod = 1;
3439 else if (strstr(buf, " tod=2"))
3440 tod = 2;
3441 else
3442 tod = 0;
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003443 sigma_dut_print(dut, DUT_MSG_DEBUG,
3444 "Server certificate TOD policy: %d",
3445 tod);
3446
3447 pos += 6;
3448 end = strchr(pos, ' ');
3449 if (end)
3450 *end = '\0';
3451 strlcpy(dut->server_cert_hash, pos,
3452 sizeof(dut->server_cert_hash));
3453 sigma_dut_print(dut, DUT_MSG_DEBUG,
3454 "Server certificate hash: %s",
3455 dut->server_cert_hash);
3456 }
3457 }
3458
3459 if (strstr(buf, "CTRL-EVENT-EAP-TLS-CERT-ERROR")) {
3460 send_resp(dut, conn, SIGMA_COMPLETE,
3461 "Result,TLS server certificate validation failed");
3462 ret = STATUS_SENT_ERROR;
3463 break;
3464 }
3465
3466 if (strstr(buf, "CTRL-EVENT-NETWORK-NOT-FOUND")) {
3467 num_network_not_found++;
3468
3469 if (num_network_not_found > 2) {
3470 send_resp(dut, conn, SIGMA_COMPLETE,
3471 "Result,Network not found");
3472 ret = STATUS_SENT_ERROR;
3473 break;
3474 }
3475 }
3476
3477 if (strstr(buf, "CTRL-EVENT-DISCONNECTED")) {
3478 num_disconnected++;
3479
3480 if (num_disconnected > 2) {
3481 send_resp(dut, conn, SIGMA_COMPLETE,
3482 "Result,Connection failed");
3483 ret = STATUS_SENT_ERROR;
3484 break;
3485 }
3486 }
3487
3488 if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
3489 if (tod >= 0) {
3490 sigma_dut_print(dut, DUT_MSG_DEBUG,
3491 "Network profile TOD policy update: %d -> %d",
3492 dut->sta_tod_policy, tod);
3493 dut->sta_tod_policy = tod;
3494 }
3495 break;
3496 }
3497 }
3498done:
3499 if (ctrl) {
3500 wpa_ctrl_detach(ctrl);
3501 wpa_ctrl_close(ctrl);
3502 }
3503 return ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003504}
3505
3506
3507static int run_hs20_osu(struct sigma_dut *dut, const char *params)
3508{
3509 char buf[500], cmd[200];
3510 int res;
3511
3512 /* Use hs20-osu-client file at the current dir, if found; otherwise use
3513 * default path */
3514 res = snprintf(cmd, sizeof(cmd),
3515 "%s -w \"%s\" -r hs20-osu-client.res %s%s -dddKt -f Logs/hs20-osu-client.txt",
3516 file_exists("./hs20-osu-client") ?
3517 "./hs20-osu-client" : "hs20-osu-client",
3518 sigma_wpas_ctrl,
3519 dut->summary_log ? "-s " : "",
3520 dut->summary_log ? dut->summary_log : "");
3521 if (res < 0 || res >= (int) sizeof(cmd))
3522 return -1;
3523
3524 res = snprintf(buf, sizeof(buf), "%s %s", cmd, params);
3525 if (res < 0 || res >= (int) sizeof(buf))
3526 return -1;
3527 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
3528
3529 if (system(buf) != 0) {
3530 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to run: %s", buf);
3531 return -1;
3532 }
3533 sigma_dut_print(dut, DUT_MSG_DEBUG,
3534 "Completed hs20-osu-client operation");
3535
3536 return 0;
3537}
3538
3539
3540static int download_ppsmo(struct sigma_dut *dut,
3541 struct sigma_conn *conn,
3542 const char *intf,
3543 struct sigma_cmd *cmd)
3544{
3545 const char *name, *path, *val;
3546 char url[500], buf[600], fbuf[100];
3547 char *fqdn = NULL;
3548
3549 name = get_param(cmd, "FileName");
3550 path = get_param(cmd, "FilePath");
3551 if (name == NULL || path == NULL)
3552 return -1;
3553
3554 if (strcasecmp(path, "VendorSpecific") == 0) {
3555 snprintf(url, sizeof(url), "PPS/%s", name);
3556 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured PPS MO "
3557 "from the device (%s)", url);
3558 if (!file_exists(url)) {
3559 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
3560 "PPS MO file does not exist");
3561 return 0;
3562 }
3563 snprintf(buf, sizeof(buf), "cp %s pps-tnds.xml", url);
3564 if (system(buf) != 0) {
3565 send_resp(dut, conn, SIGMA_ERROR,
3566 "errorCode,Failed to copy PPS MO");
3567 return 0;
3568 }
3569 } else if (strncasecmp(path, "http:", 5) != 0 &&
3570 strncasecmp(path, "https:", 6) != 0) {
3571 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
3572 "Unsupported FilePath value");
3573 return 0;
3574 } else {
3575 snprintf(url, sizeof(url), "%s/%s", path, name);
3576 sigma_dut_print(dut, DUT_MSG_INFO, "Downloading PPS MO from %s",
3577 url);
3578 snprintf(buf, sizeof(buf), "wget -T 10 -t 3 -O pps-tnds.xml '%s'", url);
3579 remove("pps-tnds.xml");
3580 if (system(buf) != 0) {
3581 send_resp(dut, conn, SIGMA_ERROR,
3582 "errorCode,Failed to download PPS MO");
3583 return 0;
3584 }
3585 }
3586
3587 if (run_hs20_osu(dut, "from_tnds pps-tnds.xml pps.xml") < 0) {
3588 send_resp(dut, conn, SIGMA_ERROR,
3589 "errorCode,Failed to parse downloaded PPSMO");
3590 return 0;
3591 }
3592 unlink("pps-tnds.xml");
3593
3594 val = get_param(cmd, "managementTreeURI");
3595 if (val) {
3596 const char *pos, *end;
3597 sigma_dut_print(dut, DUT_MSG_DEBUG, "managementTreeURI: %s",
3598 val);
3599 if (strncmp(val, "./Wi-Fi/", 8) != 0) {
3600 send_resp(dut, conn, SIGMA_ERROR,
3601 "errorCode,Invalid managementTreeURI prefix");
3602 return 0;
3603 }
3604 pos = val + 8;
3605 end = strchr(pos, '/');
3606 if (end == NULL ||
3607 strcmp(end, "/PerProviderSubscription") != 0) {
3608 send_resp(dut, conn, SIGMA_ERROR,
3609 "errorCode,Invalid managementTreeURI postfix");
3610 return 0;
3611 }
3612 if (end - pos >= (int) sizeof(fbuf)) {
3613 send_resp(dut, conn, SIGMA_ERROR,
3614 "errorCode,Too long FQDN in managementTreeURI");
3615 return 0;
3616 }
3617 memcpy(fbuf, pos, end - pos);
3618 fbuf[end - pos] = '\0';
3619 fqdn = fbuf;
3620 sigma_dut_print(dut, DUT_MSG_INFO,
3621 "FQDN from managementTreeURI: %s", fqdn);
3622 } else if (run_hs20_osu(dut, "get_fqdn pps.xml") == 0) {
3623 FILE *f = fopen("pps-fqdn", "r");
3624 if (f) {
3625 if (fgets(fbuf, sizeof(fbuf), f)) {
3626 fbuf[sizeof(fbuf) - 1] = '\0';
3627 fqdn = fbuf;
3628 sigma_dut_print(dut, DUT_MSG_DEBUG,
3629 "Use FQDN %s", fqdn);
3630 }
3631 fclose(f);
3632 }
3633 }
3634
3635 if (fqdn == NULL) {
3636 send_resp(dut, conn, SIGMA_ERROR,
3637 "errorCode,No FQDN specified");
3638 return 0;
3639 }
3640
3641 mkdir("SP", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
3642 snprintf(buf, sizeof(buf), "SP/%s", fqdn);
3643 mkdir(buf, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
3644
3645 snprintf(buf, sizeof(buf), "SP/%s/pps.xml", fqdn);
3646 if (rename("pps.xml", buf) < 0) {
3647 send_resp(dut, conn, SIGMA_ERROR,
3648 "errorCode,Could not move PPS MO");
3649 return 0;
3650 }
3651
3652 if (strcasecmp(path, "VendorSpecific") == 0) {
3653 snprintf(buf, sizeof(buf), "cp Certs/ca.pem SP/%s/ca.pem",
3654 fqdn);
3655 if (system(buf)) {
3656 send_resp(dut, conn, SIGMA_ERROR,
3657 "errorCode,Failed to copy OSU CA cert");
3658 return 0;
3659 }
3660
3661 snprintf(buf, sizeof(buf),
3662 "cp Certs/aaa-ca.pem SP/%s/aaa-ca.pem",
3663 fqdn);
3664 if (system(buf)) {
3665 send_resp(dut, conn, SIGMA_ERROR,
3666 "errorCode,Failed to copy AAA CA cert");
3667 return 0;
3668 }
3669 } else {
3670 snprintf(buf, sizeof(buf),
3671 "dl_osu_ca SP/%s/pps.xml SP/%s/ca.pem",
3672 fqdn, fqdn);
3673 if (run_hs20_osu(dut, buf) < 0) {
3674 send_resp(dut, conn, SIGMA_ERROR,
3675 "errorCode,Failed to download OSU CA cert");
3676 return 0;
3677 }
3678
3679 snprintf(buf, sizeof(buf),
3680 "dl_aaa_ca SP/%s/pps.xml SP/%s/aaa-ca.pem",
3681 fqdn, fqdn);
3682 if (run_hs20_osu(dut, buf) < 0) {
3683 sigma_dut_print(dut, DUT_MSG_INFO,
3684 "Failed to download AAA CA cert");
3685 }
3686 }
3687
3688 if (file_exists("next-client-cert.pem")) {
3689 snprintf(buf, sizeof(buf), "SP/%s/client-cert.pem", fqdn);
3690 if (rename("next-client-cert.pem", buf) < 0) {
3691 send_resp(dut, conn, SIGMA_ERROR,
3692 "errorCode,Could not move client certificate");
3693 return 0;
3694 }
3695 }
3696
3697 if (file_exists("next-client-key.pem")) {
3698 snprintf(buf, sizeof(buf), "SP/%s/client-key.pem", fqdn);
3699 if (rename("next-client-key.pem", buf) < 0) {
3700 send_resp(dut, conn, SIGMA_ERROR,
3701 "errorCode,Could not move client key");
3702 return 0;
3703 }
3704 }
3705
3706 snprintf(buf, sizeof(buf), "set_pps SP/%s/pps.xml", fqdn);
3707 if (run_hs20_osu(dut, buf) < 0) {
3708 send_resp(dut, conn, SIGMA_ERROR,
3709 "errorCode,Failed to configure credential from "
3710 "PPSMO");
3711 return 0;
3712 }
3713
3714 return 1;
3715}
3716
3717
3718static int download_cert(struct sigma_dut *dut,
3719 struct sigma_conn *conn,
3720 const char *intf,
3721 struct sigma_cmd *cmd)
3722{
3723 const char *name, *path;
3724 char url[500], buf[600];
3725
3726 name = get_param(cmd, "FileName");
3727 path = get_param(cmd, "FilePath");
3728 if (name == NULL || path == NULL)
3729 return -1;
3730
3731 if (strcasecmp(path, "VendorSpecific") == 0) {
3732 snprintf(url, sizeof(url), "Certs/%s-cert.pem", name);
3733 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured client "
3734 "certificate from the device (%s)", url);
3735 if (!file_exists(url)) {
3736 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
3737 "certificate file does not exist");
3738 return 0;
3739 }
3740 snprintf(buf, sizeof(buf), "cp %s next-client-cert.pem", url);
3741 if (system(buf) != 0) {
3742 send_resp(dut, conn, SIGMA_ERROR,
3743 "errorCode,Failed to copy client "
3744 "certificate");
3745 return 0;
3746 }
3747
3748 snprintf(url, sizeof(url), "Certs/%s-key.pem", name);
3749 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured client "
3750 "private key from the device (%s)", url);
3751 if (!file_exists(url)) {
3752 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
3753 "private key file does not exist");
3754 return 0;
3755 }
3756 snprintf(buf, sizeof(buf), "cp %s next-client-key.pem", url);
3757 if (system(buf) != 0) {
3758 send_resp(dut, conn, SIGMA_ERROR,
3759 "errorCode,Failed to copy client key");
3760 return 0;
3761 }
3762 } else if (strncasecmp(path, "http:", 5) != 0 &&
3763 strncasecmp(path, "https:", 6) != 0) {
3764 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
3765 "Unsupported FilePath value");
3766 return 0;
3767 } else {
3768 snprintf(url, sizeof(url), "%s/%s.pem", path, name);
3769 sigma_dut_print(dut, DUT_MSG_INFO, "Downloading client "
3770 "certificate/key from %s", url);
3771 snprintf(buf, sizeof(buf),
3772 "wget -T 10 -t 3 -O next-client-cert.pem '%s'", url);
3773 if (system(buf) != 0) {
3774 send_resp(dut, conn, SIGMA_ERROR,
3775 "errorCode,Failed to download client "
3776 "certificate");
3777 return 0;
3778 }
3779
3780 if (system("cp next-client-cert.pem next-client-key.pem") != 0)
3781 {
3782 send_resp(dut, conn, SIGMA_ERROR,
3783 "errorCode,Failed to copy client key");
3784 return 0;
3785 }
3786 }
3787
3788 return 1;
3789}
3790
3791
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02003792static int cmd_sta_preset_testparameters_60ghz(struct sigma_dut *dut,
3793 struct sigma_conn *conn,
3794 struct sigma_cmd *cmd)
3795{
3796 const char *val;
3797 const char *intf = get_param(cmd, "interface");
3798
3799 if (!intf)
3800 return -1;
3801
3802 val = get_param(cmd, "WscIEFragment");
3803 if (val && strcasecmp(val, "enable") == 0) {
3804 sigma_dut_print(dut, DUT_MSG_DEBUG,
3805 "Enable WSC IE fragmentation");
3806
3807 dut->wsc_fragment = 1;
3808 /* set long attributes to force fragmentation */
3809 if (wpa_command(intf, "SET device_name "
3810 WPS_LONG_DEVICE_NAME) < 0)
3811 return -2;
3812 if (wpa_command(intf, "SET manufacturer "
3813 WPS_LONG_MANUFACTURER) < 0)
3814 return -2;
3815 if (wpa_command(intf, "SET model_name "
3816 WPS_LONG_MODEL_NAME) < 0)
3817 return -2;
3818 if (wpa_command(intf, "SET model_number "
3819 WPS_LONG_MODEL_NUMBER) < 0)
3820 return -2;
3821 if (wpa_command(intf, "SET serial_number "
3822 WPS_LONG_SERIAL_NUMBER) < 0)
3823 return -2;
3824 }
3825
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02003826 val = get_param(cmd, "RSN_IE");
3827 if (val) {
3828 if (strcasecmp(val, "disable") == 0)
3829 dut->force_rsn_ie = FORCE_RSN_IE_REMOVE;
3830 else if (strcasecmp(val, "enable") == 0)
3831 dut->force_rsn_ie = FORCE_RSN_IE_ADD;
3832 }
3833
Alexei Avshalom Lazar744ae8a2019-01-31 17:26:46 +02003834 val = get_param(cmd, "WpsVersion");
3835 if (val)
3836 dut->wps_forced_version = get_wps_forced_version(dut, val);
3837
Alexei Avshalom Lazar2eccf4d2019-01-31 10:03:59 +02003838 val = get_param(cmd, "WscEAPFragment");
3839 if (val && strcasecmp(val, "enable") == 0)
3840 dut->eap_fragment = 1;
3841
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02003842 return 1;
3843}
3844
3845
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003846static int cmd_sta_preset_testparameters_hs2_r2(struct sigma_dut *dut,
3847 struct sigma_conn *conn,
3848 const char *intf,
3849 struct sigma_cmd *cmd)
3850{
3851 const char *val;
3852
3853 val = get_param(cmd, "FileType");
3854 if (val && strcasecmp(val, "PPSMO") == 0)
3855 return download_ppsmo(dut, conn, intf, cmd);
3856 if (val && strcasecmp(val, "CERT") == 0)
3857 return download_cert(dut, conn, intf, cmd);
3858 if (val) {
3859 send_resp(dut, conn, SIGMA_ERROR,
3860 "ErrorCode,Unsupported FileType");
3861 return 0;
3862 }
3863
3864 return 1;
3865}
3866
3867
Ankita Bajaja2cb5672017-10-25 16:08:28 +05303868static int cmd_sta_preset_testparameters_oce(struct sigma_dut *dut,
3869 struct sigma_conn *conn,
3870 const char *intf,
3871 struct sigma_cmd *cmd)
3872{
3873 const char *val;
Ankita Bajaj1bde7942018-01-09 19:15:01 +05303874 char buf[1000];
3875 char text[20];
3876 unsigned char addr[ETH_ALEN];
Ankita Bajaja2cb5672017-10-25 16:08:28 +05303877
3878 val = get_param(cmd, "OCESupport");
3879 if (val && strcasecmp(val, "Disable") == 0) {
3880 if (wpa_command(intf, "SET oce 0") < 0) {
3881 send_resp(dut, conn, SIGMA_ERROR,
3882 "ErrorCode,Failed to disable OCE");
3883 return 0;
3884 }
3885 } else if (val && strcasecmp(val, "Enable") == 0) {
3886 if (wpa_command(intf, "SET oce 1") < 0) {
3887 send_resp(dut, conn, SIGMA_ERROR,
3888 "ErrorCode,Failed to enable OCE");
3889 return 0;
3890 }
3891 }
3892
vamsi krishnaa2799492017-12-05 14:28:01 +05303893 val = get_param(cmd, "FILScap");
3894 if (val && (atoi(val) == 1)) {
3895 if (wpa_command(intf, "SET disable_fils 0") < 0) {
3896 send_resp(dut, conn, SIGMA_ERROR,
3897 "ErrorCode,Failed to enable FILS");
3898 return 0;
3899 }
3900 } else if (val && (atoi(val) == 0)) {
3901 if (wpa_command(intf, "SET disable_fils 1") < 0) {
3902 send_resp(dut, conn, SIGMA_ERROR,
3903 "ErrorCode,Failed to disable FILS");
3904 return 0;
3905 }
3906 }
3907
Ankita Bajaj1bde7942018-01-09 19:15:01 +05303908 val = get_param(cmd, "FILSHLP");
3909 if (val && strcasecmp(val, "Enable") == 0) {
3910 if (get_wpa_status(get_station_ifname(), "address", text,
3911 sizeof(text)) < 0)
3912 return -2;
3913 hwaddr_aton(text, addr);
3914 snprintf(buf, sizeof(buf),
3915 "FILS_HLP_REQ_ADD ff:ff:ff:ff:ff:ff "
3916 "080045100140000040004011399e00000000ffffffff00440043"
3917 "012cb30001010600fd4f46410000000000000000000000000000"
3918 "000000000000"
3919 "%02x%02x%02x%02x%02x%02x"
3920 "0000000000000000000000000000000000000000000000000000"
3921 "0000000000000000000000000000000000000000000000000000"
3922 "0000000000000000000000000000000000000000000000000000"
3923 "0000000000000000000000000000000000000000000000000000"
3924 "0000000000000000000000000000000000000000000000000000"
3925 "0000000000000000000000000000000000000000000000000000"
3926 "0000000000000000000000000000000000000000000000000000"
3927 "0000000000000000000000000000000000000000638253633501"
3928 "013d0701000af549d29b390205dc3c12616e64726f69642d6468"
3929 "63702d382e302e30370a0103060f1a1c333a3b2b5000ff00",
3930 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
3931 if (wpa_command(intf, buf)) {
3932 send_resp(dut, conn, SIGMA_ERROR,
3933 "ErrorCode,Failed to add HLP");
3934 return 0;
3935 }
3936 dut->fils_hlp = 1;
3937 }
3938
Ankita Bajaja2cb5672017-10-25 16:08:28 +05303939 return 1;
3940}
3941
3942
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003943static void ath_sta_set_noack(struct sigma_dut *dut, const char *intf,
3944 const char *val)
3945{
3946 int counter = 0;
3947 char token[50];
3948 char *result;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05303949 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003950
Peng Xub8fc5cc2017-05-10 17:27:28 -07003951 strlcpy(token, val, sizeof(token));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003952 token[sizeof(token) - 1] = '\0';
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05303953 result = strtok_r(token, ":", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003954 while (result) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07003955 if (strcmp(result, "disable") == 0)
3956 run_iwpriv(dut, intf, "noackpolicy %d 1 0", counter);
3957 else
3958 run_iwpriv(dut, intf, "noackpolicy %d 1 1", counter);
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05303959 result = strtok_r(NULL, ":", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003960 counter++;
3961 }
3962}
3963
3964
3965static void ath_sta_set_rts(struct sigma_dut *dut, const char *intf,
3966 const char *val)
3967{
3968 char buf[100];
3969
3970 snprintf(buf, sizeof(buf), "iwconfig %s rts %s", intf, val);
3971 if (system(buf) != 0) {
3972 sigma_dut_print(dut, DUT_MSG_ERROR, "iwconfig RTS failed");
3973 }
3974}
3975
3976
3977static void ath_sta_set_wmm(struct sigma_dut *dut, const char *intf,
3978 const char *val)
3979{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003980 if (strcasecmp(val, "off") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07003981 run_iwpriv(dut, intf, "wmm 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003982 }
3983}
3984
3985
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08003986static int wcn_sta_set_wmm(struct sigma_dut *dut, const char *intf,
3987 const char *val)
3988{
3989#ifdef NL80211_SUPPORT
3990 struct nl_msg *msg;
3991 int ret = 0;
3992 struct nlattr *params;
3993 int ifindex;
3994 int wmmenable = 1;
3995
3996 if (val &&
3997 (strcasecmp(val, "off") == 0 || strcmp(val, "0") == 0))
3998 wmmenable = 0;
3999
4000 ifindex = if_nametoindex(intf);
4001 if (ifindex == 0) {
4002 sigma_dut_print(dut, DUT_MSG_ERROR,
4003 "%s: Index for interface %s failed",
4004 __func__, intf);
4005 return -1;
4006 }
4007
4008 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4009 NL80211_CMD_VENDOR)) ||
4010 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4011 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4012 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4013 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4014 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4015 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WMM_ENABLE,
4016 wmmenable)) {
4017 sigma_dut_print(dut, DUT_MSG_ERROR,
4018 "%s: err in adding vendor_cmd and vendor_data",
4019 __func__);
4020 nlmsg_free(msg);
4021 return -1;
4022 }
4023 nla_nest_end(msg, params);
4024
4025 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4026 if (ret) {
4027 sigma_dut_print(dut, DUT_MSG_ERROR,
4028 "%s: err in send_and_recv_msgs, ret=%d",
4029 __func__, ret);
4030 }
4031 return ret;
4032#else /* NL80211_SUPPORT */
4033 sigma_dut_print(dut, DUT_MSG_ERROR,
4034 "WMM cannot be changed without NL80211_SUPPORT defined");
4035 return -1;
4036#endif /* NL80211_SUPPORT */
4037}
4038
4039
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004040static void ath_sta_set_sgi(struct sigma_dut *dut, const char *intf,
4041 const char *val)
4042{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004043 int sgi20;
4044
4045 sgi20 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
4046
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004047 run_iwpriv(dut, intf, "shortgi %d", sgi20);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004048}
4049
4050
4051static void ath_sta_set_11nrates(struct sigma_dut *dut, const char *intf,
4052 const char *val)
4053{
Pradeep Reddy POTTETI67376b72016-10-25 20:08:17 +05304054 int rate_code, v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004055
4056 /* Disable Tx Beam forming when using a fixed rate */
4057 ath_disable_txbf(dut, intf);
4058
Pradeep Reddy POTTETI67376b72016-10-25 20:08:17 +05304059 v = atoi(val);
4060 if (v < 0 || v > 32) {
4061 sigma_dut_print(dut, DUT_MSG_ERROR,
4062 "Invalid Fixed MCS rate: %d", v);
4063 return;
4064 }
4065 rate_code = 0x80 + v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004066
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004067 run_iwpriv(dut, intf, "set11NRates 0x%x", rate_code);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004068
4069 /* Channel width gets messed up, fix this */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004070 run_iwpriv(dut, intf, "chwidth %d", dut->chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004071}
4072
4073
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08004074static void iwpriv_sta_set_amsdu(struct sigma_dut *dut, const char *intf,
4075 const char *val)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004076{
4077 char buf[60];
4078
4079 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)
4080 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 2", intf);
4081 else
4082 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 1", intf);
4083
4084 if (system(buf) != 0)
4085 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv amsdu failed");
4086}
4087
4088
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07004089static int iwpriv_sta_set_ampdu(struct sigma_dut *dut, const char *intf,
4090 int ampdu)
4091{
4092 char buf[60];
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08004093 int maxaggregation = 63;
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07004094
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08004095 if (ampdu)
4096 ampdu = maxaggregation;
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07004097 snprintf(buf, sizeof(buf), "iwpriv %s ampdu %d", intf, ampdu);
4098 if (system(buf) != 0) {
4099 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv ampdu failed");
4100 return -1;
4101 }
4102
4103 return 0;
4104}
4105
4106
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004107static void ath_sta_set_stbc(struct sigma_dut *dut, const char *intf,
4108 const char *val)
4109{
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004110 run_iwpriv(dut, intf, "tx_stbc %s", val);
4111 run_iwpriv(dut, intf, "rx_stbc %s", val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004112}
4113
4114
4115static int wcn_sta_set_cts_width(struct sigma_dut *dut, const char *intf,
4116 const char *val)
4117{
4118 char buf[60];
4119
Peng Xucc317ed2017-05-18 16:44:37 -07004120 if (strcmp(val, "160") == 0) {
4121 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 5", intf);
4122 } else if (strcmp(val, "80") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004123 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 3", intf);
4124 } else if (strcmp(val, "40") == 0) {
4125 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 2", intf);
4126 } else if (strcmp(val, "20") == 0) {
4127 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 1", intf);
4128 } else if (strcasecmp(val, "Auto") == 0) {
4129 buf[0] = '\0';
4130 } else {
4131 sigma_dut_print(dut, DUT_MSG_ERROR,
4132 "WIDTH/CTS_WIDTH value not supported");
4133 return -1;
4134 }
4135
4136 if (buf[0] != '\0' && system(buf) != 0) {
4137 sigma_dut_print(dut, DUT_MSG_ERROR,
4138 "Failed to set WIDTH/CTS_WIDTH");
4139 return -1;
4140 }
4141
4142 return 0;
4143}
4144
4145
4146int ath_set_width(struct sigma_dut *dut, struct sigma_conn *conn,
4147 const char *intf, const char *val)
4148{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004149 if (strcasecmp(val, "Auto") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004150 run_iwpriv(dut, intf, "chwidth 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004151 dut->chwidth = 0;
4152 } else if (strcasecmp(val, "20") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004153 run_iwpriv(dut, intf, "chwidth 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004154 dut->chwidth = 0;
4155 } else if (strcasecmp(val, "40") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004156 run_iwpriv(dut, intf, "chwidth 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004157 dut->chwidth = 1;
4158 } else if (strcasecmp(val, "80") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004159 run_iwpriv(dut, intf, "chwidth 2");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004160 dut->chwidth = 2;
4161 } else if (strcasecmp(val, "160") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004162 run_iwpriv(dut, intf, "chwidth 3");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004163 dut->chwidth = 3;
4164 } else {
4165 send_resp(dut, conn, SIGMA_ERROR,
4166 "ErrorCode,WIDTH not supported");
4167 return -1;
4168 }
4169
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004170 return 0;
4171}
4172
4173
4174static int wcn_sta_set_sp_stream(struct sigma_dut *dut, const char *intf,
4175 const char *val)
4176{
4177 char buf[60];
Arif Hussainac6c5112018-05-25 17:34:00 -07004178 int sta_nss;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004179
Amarnath Hullur Subramanyamd5374fa2018-02-25 19:00:24 -08004180 if (strcmp(val, "1SS") == 0 || strcmp(val, "1") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004181 snprintf(buf, sizeof(buf), "iwpriv %s nss 1", intf);
Arif Hussainac6c5112018-05-25 17:34:00 -07004182 sta_nss = 1;
Amarnath Hullur Subramanyamd5374fa2018-02-25 19:00:24 -08004183 } else if (strcmp(val, "2SS") == 0 || strcmp(val, "2") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004184 snprintf(buf, sizeof(buf), "iwpriv %s nss 2", intf);
Arif Hussainac6c5112018-05-25 17:34:00 -07004185 sta_nss = 2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004186 } else {
4187 sigma_dut_print(dut, DUT_MSG_ERROR,
4188 "SP_STREAM value not supported");
4189 return -1;
4190 }
4191
4192 if (system(buf) != 0) {
4193 sigma_dut_print(dut, DUT_MSG_ERROR,
4194 "Failed to set SP_STREAM");
4195 return -1;
4196 }
4197
Arif Hussainac6c5112018-05-25 17:34:00 -07004198 dut->sta_nss = sta_nss;
4199
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004200 return 0;
4201}
4202
4203
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05304204static void wcn_sta_set_stbc(struct sigma_dut *dut, const char *intf,
4205 const char *val)
4206{
4207 char buf[60];
4208
4209 snprintf(buf, sizeof(buf), "iwpriv %s tx_stbc %s", intf, val);
4210 if (system(buf) != 0)
4211 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv tx_stbc failed");
4212
4213 snprintf(buf, sizeof(buf), "iwpriv %s rx_stbc %s", intf, val);
4214 if (system(buf) != 0)
4215 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv rx_stbc failed");
4216}
4217
4218
Ashwini Patil68d02cd2017-01-10 15:39:16 +05304219static int mbo_set_cellular_data_capa(struct sigma_dut *dut,
4220 struct sigma_conn *conn,
4221 const char *intf, int capa)
4222{
4223 char buf[32];
4224
4225 if (capa > 0 && capa < 4) {
4226 snprintf(buf, sizeof(buf), "SET mbo_cell_capa %d", capa);
4227 if (wpa_command(intf, buf) < 0) {
4228 send_resp(dut, conn, SIGMA_ERROR,
4229 "ErrorCode, Failed to set cellular data capability");
4230 return 0;
4231 }
4232 return 1;
4233 }
4234
4235 sigma_dut_print(dut, DUT_MSG_ERROR,
4236 "Invalid Cellular data capability: %d", capa);
4237 send_resp(dut, conn, SIGMA_INVALID,
4238 "ErrorCode,Invalid cellular data capability");
4239 return 0;
4240}
4241
4242
Ashwini Patil9183fdb2017-04-13 16:58:25 +05304243static int mbo_set_roaming(struct sigma_dut *dut, struct sigma_conn *conn,
4244 const char *intf, const char *val)
4245{
4246 if (strcasecmp(val, "Disable") == 0) {
4247 if (wpa_command(intf, "SET roaming 0") < 0) {
4248 send_resp(dut, conn, SIGMA_ERROR,
4249 "ErrorCode,Failed to disable roaming");
4250 return 0;
4251 }
4252 return 1;
4253 }
4254
4255 if (strcasecmp(val, "Enable") == 0) {
4256 if (wpa_command(intf, "SET roaming 1") < 0) {
4257 send_resp(dut, conn, SIGMA_ERROR,
4258 "ErrorCode,Failed to enable roaming");
4259 return 0;
4260 }
4261 return 1;
4262 }
4263
4264 sigma_dut_print(dut, DUT_MSG_ERROR,
4265 "Invalid value provided for roaming: %s", val);
4266 send_resp(dut, conn, SIGMA_INVALID,
4267 "ErrorCode,Unknown value provided for Roaming");
4268 return 0;
4269}
4270
4271
Ashwini Patila75de5a2017-04-13 16:35:05 +05304272static int mbo_set_assoc_disallow(struct sigma_dut *dut,
4273 struct sigma_conn *conn,
4274 const char *intf, const char *val)
4275{
4276 if (strcasecmp(val, "Disable") == 0) {
4277 if (wpa_command(intf, "SET ignore_assoc_disallow 1") < 0) {
4278 send_resp(dut, conn, SIGMA_ERROR,
4279 "ErrorCode,Failed to disable Assoc_disallow");
4280 return 0;
4281 }
4282 return 1;
4283 }
4284
4285 if (strcasecmp(val, "Enable") == 0) {
4286 if (wpa_command(intf, "SET ignore_assoc_disallow 0") < 0) {
4287 send_resp(dut, conn, SIGMA_ERROR,
4288 "ErrorCode,Failed to enable Assoc_disallow");
4289 return 0;
4290 }
4291 return 1;
4292 }
4293
4294 sigma_dut_print(dut, DUT_MSG_ERROR,
4295 "Invalid value provided for Assoc_disallow: %s", val);
4296 send_resp(dut, conn, SIGMA_INVALID,
4297 "ErrorCode,Unknown value provided for Assoc_disallow");
4298 return 0;
4299}
4300
4301
Ashwini Patilc63161e2017-04-13 16:30:23 +05304302static int mbo_set_bss_trans_req(struct sigma_dut *dut, struct sigma_conn *conn,
4303 const char *intf, const char *val)
4304{
4305 if (strcasecmp(val, "Reject") == 0) {
4306 if (wpa_command(intf, "SET reject_btm_req_reason 1") < 0) {
4307 send_resp(dut, conn, SIGMA_ERROR,
4308 "ErrorCode,Failed to Reject BTM Request");
4309 return 0;
4310 }
4311 return 1;
4312 }
4313
4314 if (strcasecmp(val, "Accept") == 0) {
4315 if (wpa_command(intf, "SET reject_btm_req_reason 0") < 0) {
4316 send_resp(dut, conn, SIGMA_ERROR,
4317 "ErrorCode,Failed to Accept BTM Request");
4318 return 0;
4319 }
4320 return 1;
4321 }
4322
4323 sigma_dut_print(dut, DUT_MSG_ERROR,
4324 "Invalid value provided for BSS_Transition: %s", val);
4325 send_resp(dut, conn, SIGMA_INVALID,
4326 "ErrorCode,Unknown value provided for BSS_Transition");
4327 return 0;
4328}
4329
4330
Ashwini Patil00402582017-04-13 12:29:39 +05304331static int mbo_set_non_pref_ch_list(struct sigma_dut *dut,
4332 struct sigma_conn *conn,
4333 const char *intf,
4334 struct sigma_cmd *cmd)
4335{
4336 const char *ch, *pref, *op_class, *reason;
4337 char buf[120];
4338 int len, ret;
4339
4340 pref = get_param(cmd, "Ch_Pref");
4341 if (!pref)
4342 return 1;
4343
4344 if (strcasecmp(pref, "clear") == 0) {
4345 free(dut->non_pref_ch_list);
4346 dut->non_pref_ch_list = NULL;
4347 } else {
4348 op_class = get_param(cmd, "Ch_Op_Class");
4349 if (!op_class) {
4350 send_resp(dut, conn, SIGMA_INVALID,
4351 "ErrorCode,Ch_Op_Class not provided");
4352 return 0;
4353 }
4354
4355 ch = get_param(cmd, "Ch_Pref_Num");
4356 if (!ch) {
4357 send_resp(dut, conn, SIGMA_INVALID,
4358 "ErrorCode,Ch_Pref_Num not provided");
4359 return 0;
4360 }
4361
4362 reason = get_param(cmd, "Ch_Reason_Code");
4363 if (!reason) {
4364 send_resp(dut, conn, SIGMA_INVALID,
4365 "ErrorCode,Ch_Reason_Code not provided");
4366 return 0;
4367 }
4368
4369 if (!dut->non_pref_ch_list) {
4370 dut->non_pref_ch_list =
4371 calloc(1, NON_PREF_CH_LIST_SIZE);
4372 if (!dut->non_pref_ch_list) {
4373 send_resp(dut, conn, SIGMA_ERROR,
4374 "ErrorCode,Failed to allocate memory for non_pref_ch_list");
4375 return 0;
4376 }
4377 }
4378 len = strlen(dut->non_pref_ch_list);
4379 ret = snprintf(dut->non_pref_ch_list + len,
4380 NON_PREF_CH_LIST_SIZE - len,
4381 " %s:%s:%s:%s", op_class, ch, pref, reason);
4382 if (ret > 0 && ret < NON_PREF_CH_LIST_SIZE - len) {
4383 sigma_dut_print(dut, DUT_MSG_DEBUG, "non_pref_list: %s",
4384 dut->non_pref_ch_list);
4385 } else {
4386 sigma_dut_print(dut, DUT_MSG_ERROR,
4387 "snprintf failed for non_pref_list, ret = %d",
4388 ret);
4389 send_resp(dut, conn, SIGMA_ERROR,
4390 "ErrorCode,snprintf failed");
4391 free(dut->non_pref_ch_list);
4392 dut->non_pref_ch_list = NULL;
4393 return 0;
4394 }
4395 }
4396
4397 ret = snprintf(buf, sizeof(buf), "SET non_pref_chan%s",
4398 dut->non_pref_ch_list ? dut->non_pref_ch_list : " ");
4399 if (ret < 0 || ret >= (int) sizeof(buf)) {
4400 sigma_dut_print(dut, DUT_MSG_DEBUG,
4401 "snprintf failed for set non_pref_chan, ret: %d",
4402 ret);
4403 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,snprint failed");
4404 return 0;
4405 }
4406
4407 if (wpa_command(intf, buf) < 0) {
4408 send_resp(dut, conn, SIGMA_ERROR,
4409 "ErrorCode,Failed to set non-preferred channel list");
4410 return 0;
4411 }
4412
4413 return 1;
4414}
4415
4416
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08004417#ifdef NL80211_SUPPORT
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08004418
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08004419static int sta_set_he_htc_supp(struct sigma_dut *dut, const char *intf,
4420 uint8_t cfg)
4421{
4422 struct nl_msg *msg;
4423 int ret = 0;
4424 struct nlattr *params;
4425 int ifindex;
4426
4427 ifindex = if_nametoindex(intf);
4428 if (ifindex == 0) {
4429 sigma_dut_print(dut, DUT_MSG_ERROR,
4430 "%s: Index for interface %s failed",
4431 __func__, intf);
4432 return -1;
4433 }
4434
4435 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4436 NL80211_CMD_VENDOR)) ||
4437 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4438 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4439 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4440 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4441 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4442 nla_put_u8(msg,
4443 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_HTC_HE_SUPP,
4444 cfg)) {
4445 sigma_dut_print(dut, DUT_MSG_ERROR,
4446 "%s: err in adding vendor_cmd and vendor_data",
4447 __func__);
4448 nlmsg_free(msg);
4449 return -1;
4450 }
4451 nla_nest_end(msg, params);
4452
4453 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4454 if (ret) {
4455 sigma_dut_print(dut, DUT_MSG_ERROR,
4456 "%s: err in send_and_recv_msgs, ret=%d",
4457 __func__, ret);
4458 }
4459 return ret;
4460}
4461
4462
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08004463static int sta_set_he_fragmentation(struct sigma_dut *dut, const char *intf,
4464 enum he_fragmentation_val frag)
4465{
4466 struct nl_msg *msg;
4467 int ret = 0;
4468 struct nlattr *params;
4469 int ifindex;
4470
4471 ifindex = if_nametoindex(intf);
4472 if (ifindex == 0) {
4473 sigma_dut_print(dut, DUT_MSG_ERROR,
4474 "%s: Index for interface %s failed",
4475 __func__, intf);
4476 return -1;
4477 }
4478
4479 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4480 NL80211_CMD_VENDOR)) ||
4481 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4482 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4483 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4484 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4485 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4486 nla_put_u8(msg,
4487 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_FRAGMENTATION,
4488 frag)) {
4489 sigma_dut_print(dut, DUT_MSG_ERROR,
4490 "%s: err in adding vendor_cmd and vendor_data",
4491 __func__);
4492 nlmsg_free(msg);
4493 return -1;
4494 }
4495 nla_nest_end(msg, params);
4496
4497 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4498 if (ret) {
4499 sigma_dut_print(dut, DUT_MSG_ERROR,
4500 "%s: err in send_and_recv_msgs, ret=%d",
4501 __func__, ret);
4502 }
4503 return ret;
4504}
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08004505
4506
Subhani Shaik8e7a3052018-04-24 14:03:00 -07004507static int sta_set_he_ltf(struct sigma_dut *dut, const char *intf,
4508 enum qca_wlan_he_ltf_cfg ltf)
4509{
4510 struct nl_msg *msg;
4511 int ret = 0;
4512 struct nlattr *params;
4513 int ifindex;
4514
4515 ifindex = if_nametoindex(intf);
4516 if (ifindex == 0) {
4517 sigma_dut_print(dut, DUT_MSG_ERROR,
4518 "%s: Index for interface %s failed",
4519 __func__, intf);
4520 return -1;
4521 }
4522
4523 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4524 NL80211_CMD_VENDOR)) ||
4525 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4526 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4527 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4528 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4529 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4530 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_LTF,
4531 ltf)) {
4532 sigma_dut_print(dut, DUT_MSG_ERROR,
4533 "%s: err in adding vendor_cmd and vendor_data",
4534 __func__);
4535 nlmsg_free(msg);
4536 return -1;
4537 }
4538 nla_nest_end(msg, params);
4539
4540 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4541 if (ret) {
4542 sigma_dut_print(dut, DUT_MSG_ERROR,
4543 "%s: err in send_and_recv_msgs, ret=%d",
4544 __func__, ret);
4545 }
4546 return ret;
4547}
4548
4549
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08004550static int nlvendor_sta_set_noack(struct sigma_dut *dut, const char *intf,
4551 int noack, enum qca_wlan_ac_type ac)
4552{
4553 struct nl_msg *msg;
4554 int ret = 0;
4555 struct nlattr *params;
4556 int ifindex;
4557
4558 ifindex = if_nametoindex(intf);
4559 if (ifindex == 0) {
4560 sigma_dut_print(dut, DUT_MSG_ERROR,
4561 "%s: Index for interface %s failed",
4562 __func__, intf);
4563 return -1;
4564 }
4565
4566 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4567 NL80211_CMD_VENDOR)) ||
4568 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4569 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4570 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4571 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4572 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4573 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_NO_ACK,
4574 noack) ||
4575 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_NO_ACK_AC,
4576 ac)) {
4577 sigma_dut_print(dut, DUT_MSG_ERROR,
4578 "%s: err in adding vendor_cmd and vendor_data",
4579 __func__);
4580 nlmsg_free(msg);
4581 return -1;
4582 }
4583 nla_nest_end(msg, params);
4584
4585 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4586 if (ret) {
4587 sigma_dut_print(dut, DUT_MSG_ERROR,
4588 "%s: err in send_and_recv_msgs, ret=%d",
4589 __func__, ret);
4590 }
4591 return ret;
4592}
4593
4594
4595static void wcn_sta_set_noack(struct sigma_dut *dut, const char *intf,
4596 const char *val)
4597{
4598 int noack, ret;
4599 char token[100];
4600 char *result;
4601 char *saveptr;
4602 enum qca_wlan_ac_type ac = QCA_WLAN_AC_BE;
4603
4604 strlcpy(token, val, sizeof(token));
4605 token[sizeof(token) - 1] = '\0';
4606 result = strtok_r(token, ":", &saveptr);
4607 while (result) {
4608 noack = strcasecmp(result, "Disable") != 0;
4609 ret = nlvendor_sta_set_noack(dut, intf, noack, ac);
4610 if (ret) {
4611 sigma_dut_print(dut, DUT_MSG_ERROR,
4612 "nlvendor_sta_set_noack failed for ac:%d, ret:%d",
4613 ac, ret);
4614 }
4615 result = strtok_r(NULL, ":", &saveptr);
4616 ac++;
4617 }
4618}
4619
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08004620#endif /* NL80211_SUPPORT */
4621
4622
Jouni Malinenf7222712019-06-13 01:50:21 +03004623static enum sigma_cmd_result
4624cmd_sta_preset_testparameters(struct sigma_dut *dut, struct sigma_conn *conn,
4625 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004626{
4627 const char *intf = get_param(cmd, "Interface");
4628 const char *val;
4629
4630 val = get_param(cmd, "Program");
Jouni Malinen1f6ae642018-06-07 23:56:13 +03004631 if (val && (strcasecmp(val, "HS2-R2") == 0 ||
4632 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004633 return cmd_sta_preset_testparameters_hs2_r2(dut, conn, intf,
4634 cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004635
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07004636 if (val && strcasecmp(val, "LOC") == 0)
4637 return loc_cmd_sta_preset_testparameters(dut, conn, cmd);
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02004638 if (val && strcasecmp(val, "60GHZ") == 0) {
4639 val = get_param(cmd, "WPS");
4640 if (val && strcasecmp(val, "disable") == 0) {
4641 dut->wps_disable = 1;
4642 sigma_dut_print(dut, DUT_MSG_INFO, "WPS disabled");
4643 } else {
4644 /* wps_disable can have other value from the previous
4645 * test, so make sure it has the correct value.
4646 */
4647 dut->wps_disable = 0;
4648 }
4649
4650 val = get_param(cmd, "P2P");
4651 if (val && strcasecmp(val, "disable") == 0)
4652 sigma_dut_print(dut, DUT_MSG_INFO, "P2P disabled");
4653 }
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07004654
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02004655 if (dut->program == PROGRAM_WPS && dut->band == WPS_BAND_60G)
4656 return cmd_sta_preset_testparameters_60ghz(dut, conn, cmd);
4657
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004658#ifdef ANDROID_NAN
4659 if (val && strcasecmp(val, "NAN") == 0)
4660 return nan_cmd_sta_preset_testparameters(dut, conn, cmd);
4661#endif /* ANDROID_NAN */
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07004662#ifdef MIRACAST
4663 if (val && (strcasecmp(val, "WFD") == 0 ||
4664 strcasecmp(val, "DisplayR2") == 0))
4665 return miracast_preset_testparameters(dut, conn, cmd);
4666#endif /* MIRACAST */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004667
Ashwini Patil68d02cd2017-01-10 15:39:16 +05304668 if (val && strcasecmp(val, "MBO") == 0) {
4669 val = get_param(cmd, "Cellular_Data_Cap");
4670 if (val &&
4671 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
4672 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +05304673
4674 val = get_param(cmd, "Ch_Pref");
4675 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
4676 return 0;
4677
Ashwini Patilc63161e2017-04-13 16:30:23 +05304678 val = get_param(cmd, "BSS_Transition");
4679 if (val && mbo_set_bss_trans_req(dut, conn, intf, val) == 0)
4680 return 0;
4681
Ashwini Patila75de5a2017-04-13 16:35:05 +05304682 val = get_param(cmd, "Assoc_Disallow");
4683 if (val && mbo_set_assoc_disallow(dut, conn, intf, val) == 0)
4684 return 0;
4685
Ashwini Patil9183fdb2017-04-13 16:58:25 +05304686 val = get_param(cmd, "Roaming");
4687 if (val && mbo_set_roaming(dut, conn, intf, val) == 0)
4688 return 0;
4689
Ashwini Patil68d02cd2017-01-10 15:39:16 +05304690 return 1;
4691 }
4692
Ankita Bajaja2cb5672017-10-25 16:08:28 +05304693 if (val && strcasecmp(val, "OCE") == 0)
4694 return cmd_sta_preset_testparameters_oce(dut, conn, intf, cmd);
4695
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004696#if 0
4697 val = get_param(cmd, "Supplicant");
4698 if (val && strcasecmp(val, "Default") != 0) {
4699 send_resp(dut, conn, SIGMA_ERROR,
4700 "ErrorCode,Only default(Vendor) supplicant "
4701 "supported");
4702 return 0;
4703 }
4704#endif
4705
4706 val = get_param(cmd, "RTS");
4707 if (val) {
4708 switch (get_driver_type()) {
4709 case DRIVER_ATHEROS:
4710 ath_sta_set_rts(dut, intf, val);
4711 break;
4712 default:
4713#if 0
4714 send_resp(dut, conn, SIGMA_ERROR,
4715 "ErrorCode,Setting RTS not supported");
4716 return 0;
4717#else
4718 sigma_dut_print(dut, DUT_MSG_DEBUG,
4719 "Setting RTS not supported");
4720 break;
4721#endif
4722 }
4723 }
4724
4725#if 0
4726 val = get_param(cmd, "FRGMNT");
4727 if (val) {
4728 /* TODO */
4729 send_resp(dut, conn, SIGMA_ERROR,
4730 "ErrorCode,Setting FRGMNT not supported");
4731 return 0;
4732 }
4733#endif
4734
4735#if 0
4736 val = get_param(cmd, "Preamble");
4737 if (val) {
4738 /* TODO: Long/Short */
4739 send_resp(dut, conn, SIGMA_ERROR,
4740 "ErrorCode,Setting Preamble not supported");
4741 return 0;
4742 }
4743#endif
4744
4745 val = get_param(cmd, "Mode");
4746 if (val) {
4747 if (strcmp(val, "11b") == 0 ||
4748 strcmp(val, "11g") == 0 ||
4749 strcmp(val, "11a") == 0 ||
4750 strcmp(val, "11n") == 0 ||
4751 strcmp(val, "11ng") == 0 ||
4752 strcmp(val, "11nl") == 0 ||
4753 strcmp(val, "11nl(nabg)") == 0 ||
4754 strcmp(val, "AC") == 0 ||
4755 strcmp(val, "11AC") == 0 ||
4756 strcmp(val, "11ac") == 0 ||
4757 strcmp(val, "11na") == 0 ||
Amarnath Hullur Subramanyamb0db2712018-01-30 19:40:35 -08004758 strcmp(val, "11an") == 0 ||
4759 strcmp(val, "11ax") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004760 /* STA supports all modes by default */
4761 } else {
4762 send_resp(dut, conn, SIGMA_ERROR,
4763 "ErrorCode,Setting Mode not supported");
4764 return 0;
4765 }
Amarnath Hullur Subramanyam97d0e532018-01-31 02:53:02 -08004766
4767 /* Change the mode only in case of testbed for HE program
4768 * and for 11a and 11g modes only. */
4769 if (dut->program == PROGRAM_HE &&
4770 dut->device_type == STA_testbed) {
4771 int phymode;
4772 char buf[60];
4773
4774 if (strcmp(val, "11a") == 0) {
Amarnath Hullur Subramanyam94dfaf02018-03-02 19:26:57 -08004775 phymode = 1; /* IEEE80211_MODE_11A */
4776 } else if (strcmp(val, "11g") == 0) {
4777 phymode = 3; /* IEEE80211_MODE_11G */
4778 } else if (strcmp(val, "11b") == 0) {
4779 phymode = 2; /* IEEE80211_MODE_11B */
4780 } else if (strcmp(val, "11n") == 0 ||
4781 strcmp(val, "11nl") == 0 ||
4782 strcmp(val, "11nl(nabg)") == 0) {
4783 phymode = 22; /* IEEE80211_MODE_11AGN */
4784 } else if (strcmp(val, "11ng") == 0) {
4785 phymode = 13; /* IEEE80211_MODE_11NG_HT40 */
4786 } else if (strcmp(val, "AC") == 0 ||
4787 strcasecmp(val, "11AC") == 0) {
4788 phymode = 19; /* IEEE80211_MODE_11AC_VHT80 */
4789 } else if (strcmp(val, "11na") == 0 ||
4790 strcasecmp(val, "11an") == 0) {
4791 phymode = 14; /* IEEE80211_MODE_11NA_HT40 */
4792 } else if (strcmp(val, "11ax") == 0) {
4793 phymode = 0; /* IEEE80211_MODE_AUTO */
Amarnath Hullur Subramanyam97d0e532018-01-31 02:53:02 -08004794 } else {
4795 sigma_dut_print(dut, DUT_MSG_DEBUG,
4796 "Ignoring mode change for mode: %s",
4797 val);
4798 phymode = -1;
4799 }
4800 if (phymode != -1) {
4801 snprintf(buf, sizeof(buf),
4802 "iwpriv %s setphymode %d",
4803 intf, phymode);
4804 if (system(buf) != 0) {
4805 sigma_dut_print(dut, DUT_MSG_ERROR,
4806 "iwpriv setting of phymode failed");
4807 }
4808 }
4809 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004810 }
4811
4812 val = get_param(cmd, "wmm");
4813 if (val) {
4814 switch (get_driver_type()) {
4815 case DRIVER_ATHEROS:
4816 ath_sta_set_wmm(dut, intf, val);
4817 break;
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08004818 case DRIVER_WCN:
4819 wcn_sta_set_wmm(dut, intf, val);
4820 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004821 default:
4822 sigma_dut_print(dut, DUT_MSG_DEBUG,
4823 "Setting wmm not supported");
4824 break;
4825 }
4826 }
4827
4828 val = get_param(cmd, "Powersave");
4829 if (val) {
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08004830 char buf[60];
4831
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004832 if (strcmp(val, "0") == 0 || strcasecmp(val, "off") == 0) {
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08004833 if (get_driver_type() == DRIVER_WCN) {
4834 snprintf(buf, sizeof(buf),
4835 "iwpriv %s setPower 2", intf);
4836 if (system(buf) != 0) {
4837 sigma_dut_print(dut, DUT_MSG_ERROR,
4838 "iwpriv setPower 2 failed");
4839 return 0;
4840 }
4841 }
4842
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004843 if (wpa_command(get_station_ifname(),
4844 "P2P_SET ps 0") < 0)
4845 return -2;
4846 /* Make sure test modes are disabled */
4847 wpa_command(get_station_ifname(), "P2P_SET ps 98");
4848 wpa_command(get_station_ifname(), "P2P_SET ps 96");
4849 } else if (strcmp(val, "1") == 0 ||
4850 strcasecmp(val, "PSPoll") == 0 ||
4851 strcasecmp(val, "on") == 0) {
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08004852 if (get_driver_type() == DRIVER_WCN) {
4853 snprintf(buf, sizeof(buf),
4854 "iwpriv %s setPower 1", intf);
4855 if (system(buf) != 0) {
4856 sigma_dut_print(dut, DUT_MSG_ERROR,
4857 "iwpriv setPower 1 failed");
4858 return 0;
4859 }
4860 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004861 /* Disable default power save mode */
4862 wpa_command(get_station_ifname(), "P2P_SET ps 0");
4863 /* Enable PS-Poll test mode */
4864 if (wpa_command(get_station_ifname(),
4865 "P2P_SET ps 97") < 0 ||
4866 wpa_command(get_station_ifname(),
4867 "P2P_SET ps 99") < 0)
4868 return -2;
4869 } else if (strcmp(val, "2") == 0 ||
4870 strcasecmp(val, "Fast") == 0) {
4871 /* TODO */
4872 send_resp(dut, conn, SIGMA_ERROR,
4873 "ErrorCode,Powersave=Fast not supported");
4874 return 0;
4875 } else if (strcmp(val, "3") == 0 ||
4876 strcasecmp(val, "PSNonPoll") == 0) {
4877 /* Make sure test modes are disabled */
4878 wpa_command(get_station_ifname(), "P2P_SET ps 98");
4879 wpa_command(get_station_ifname(), "P2P_SET ps 96");
4880
4881 /* Enable default power save mode */
4882 if (wpa_command(get_station_ifname(),
4883 "P2P_SET ps 1") < 0)
4884 return -2;
4885 } else
4886 return -1;
4887 }
4888
4889 val = get_param(cmd, "NoAck");
4890 if (val) {
4891 switch (get_driver_type()) {
4892 case DRIVER_ATHEROS:
4893 ath_sta_set_noack(dut, intf, val);
4894 break;
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08004895#ifdef NL80211_SUPPORT
4896 case DRIVER_WCN:
4897 wcn_sta_set_noack(dut, intf, val);
4898 break;
4899#endif /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004900 default:
4901 send_resp(dut, conn, SIGMA_ERROR,
4902 "ErrorCode,Setting NoAck not supported");
4903 return 0;
4904 }
4905 }
4906
4907 val = get_param(cmd, "IgnoreChswitchProhibit");
4908 if (val) {
4909 /* TODO: Enabled/disabled */
4910 if (strcasecmp(val, "Enabled") == 0) {
4911 send_resp(dut, conn, SIGMA_ERROR,
4912 "ErrorCode,Enabling IgnoreChswitchProhibit "
4913 "not supported");
4914 return 0;
4915 }
4916 }
4917
4918 val = get_param(cmd, "TDLS");
4919 if (val) {
4920 if (strcasecmp(val, "Disabled") == 0) {
4921 if (wpa_command(intf, "SET tdls_disabled 1")) {
4922 send_resp(dut, conn, SIGMA_ERROR,
4923 "ErrorCode,Failed to disable TDLS");
4924 return 0;
4925 }
4926 } else if (strcasecmp(val, "Enabled") == 0) {
4927 if (wpa_command(intf, "SET tdls_disabled 0")) {
4928 send_resp(dut, conn, SIGMA_ERROR,
4929 "ErrorCode,Failed to enable TDLS");
4930 return 0;
4931 }
4932 } else {
4933 send_resp(dut, conn, SIGMA_ERROR,
4934 "ErrorCode,Unsupported TDLS value");
4935 return 0;
4936 }
4937 }
4938
4939 val = get_param(cmd, "TDLSmode");
4940 if (val) {
4941 if (strcasecmp(val, "Default") == 0) {
4942 wpa_command(intf, "SET tdls_testing 0");
4943 } else if (strcasecmp(val, "APProhibit") == 0) {
4944 if (wpa_command(intf, "SET tdls_testing 0x400")) {
4945 send_resp(dut, conn, SIGMA_ERROR,
4946 "ErrorCode,Failed to enable ignore "
4947 "APProhibit TDLS mode");
4948 return 0;
4949 }
4950 } else if (strcasecmp(val, "HiLoMac") == 0) {
4951 /* STA should respond with TDLS setup req for a TDLS
4952 * setup req */
4953 if (wpa_command(intf, "SET tdls_testing 0x80")) {
4954 send_resp(dut, conn, SIGMA_ERROR,
4955 "ErrorCode,Failed to enable HiLoMac "
4956 "TDLS mode");
4957 return 0;
4958 }
4959 } else if (strcasecmp(val, "WeakSecurity") == 0) {
4960 /*
4961 * Since all security modes are enabled by default when
4962 * Sigma control is used, there is no need to do
4963 * anything here.
4964 */
4965 } else if (strcasecmp(val, "ExistLink") == 0) {
4966 /*
4967 * Since we allow new TDLS Setup Request even if there
4968 * is an existing link, nothing needs to be done for
4969 * this.
4970 */
4971 } else {
4972 /* TODO:
4973 * ExistLink: STA should send TDLS setup req even if
4974 * direct link already exists
4975 */
4976 send_resp(dut, conn, SIGMA_ERROR,
4977 "ErrorCode,Unsupported TDLSmode value");
4978 return 0;
4979 }
4980 }
4981
4982 val = get_param(cmd, "FakePubKey");
4983 if (val && atoi(val) && wpa_command(intf, "SET wps_corrupt_pkhash 1")) {
4984 send_resp(dut, conn, SIGMA_ERROR,
4985 "ErrorCode,Failed to enable FakePubKey");
4986 return 0;
4987 }
4988
Amarnath Hullur Subramanyamae1042b2018-02-22 21:52:52 -08004989#ifdef NL80211_SUPPORT
4990 val = get_param(cmd, "FrgmntSupport");
4991 if (val) {
4992 if (strcasecmp(val, "Enable") == 0) {
4993 if (sta_set_he_fragmentation(dut, intf,
4994 HE_FRAG_LEVEL1)) {
4995 send_resp(dut, conn, SIGMA_ERROR,
4996 "ErrorCode,Failed to enable HE Fragmentation");
4997 return 0;
4998 }
4999 } else if (strcasecmp(val, "Disable") == 0) {
5000 if (sta_set_he_fragmentation(dut, intf,
5001 HE_FRAG_DISABLE)) {
5002 send_resp(dut, conn, SIGMA_ERROR,
5003 "ErrorCode,Failed to disable HE Fragmentation");
5004 return 0;
5005 }
5006 }
5007 }
5008#endif /* NL80211_SUPPORT */
5009
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005010 return 1;
5011}
5012
5013
5014static const char * ath_get_radio_name(const char *radio_name)
5015{
5016 if (radio_name == NULL)
5017 return "wifi0";
5018 if (strcmp(radio_name, "wifi1") == 0)
5019 return "wifi1";
5020 if (strcmp(radio_name, "wifi2") == 0)
5021 return "wifi2";
5022 return "wifi0";
5023}
5024
5025
5026static void ath_sta_set_txsp_stream(struct sigma_dut *dut, const char *intf,
5027 const char *val)
5028{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005029 unsigned int vht_mcsmap = 0;
5030 int txchainmask = 0;
5031 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
5032
5033 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
5034 if (dut->testbed_flag_txsp == 1) {
5035 vht_mcsmap = 0xfffc;
5036 dut->testbed_flag_txsp = 0;
5037 } else {
5038 vht_mcsmap = 0xfffe;
5039 }
5040 txchainmask = 1;
5041 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
5042 if (dut->testbed_flag_txsp == 1) {
5043 vht_mcsmap = 0xfff0;
5044 dut->testbed_flag_txsp = 0;
5045 } else {
5046 vht_mcsmap = 0xfffa;
5047 }
5048 txchainmask = 3;
5049 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
5050 if (dut->testbed_flag_txsp == 1) {
5051 vht_mcsmap = 0xffc0;
5052 dut->testbed_flag_txsp = 0;
5053 } else {
5054 vht_mcsmap = 0xffea;
5055 }
5056 txchainmask = 7;
5057 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
5058 if (dut->testbed_flag_txsp == 1) {
5059 vht_mcsmap = 0xff00;
5060 dut->testbed_flag_txsp = 0;
5061 } else {
5062 vht_mcsmap = 0xffaa;
5063 }
5064 txchainmask = 15;
5065 } else {
5066 if (dut->testbed_flag_txsp == 1) {
5067 vht_mcsmap = 0xffc0;
5068 dut->testbed_flag_txsp = 0;
5069 } else {
5070 vht_mcsmap = 0xffea;
5071 }
5072 }
5073
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005074 if (txchainmask)
5075 run_iwpriv(dut, basedev, "txchainmask %d", txchainmask);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005076
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005077 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005078}
5079
5080
5081static void ath_sta_set_rxsp_stream(struct sigma_dut *dut, const char *intf,
5082 const char *val)
5083{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005084 unsigned int vht_mcsmap = 0;
5085 int rxchainmask = 0;
5086 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
5087
5088 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
5089 if (dut->testbed_flag_rxsp == 1) {
5090 vht_mcsmap = 0xfffc;
5091 dut->testbed_flag_rxsp = 0;
5092 } else {
5093 vht_mcsmap = 0xfffe;
5094 }
5095 rxchainmask = 1;
5096 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
5097 if (dut->testbed_flag_rxsp == 1) {
5098 vht_mcsmap = 0xfff0;
5099 dut->testbed_flag_rxsp = 0;
5100 } else {
5101 vht_mcsmap = 0xfffa;
5102 }
5103 rxchainmask = 3;
5104 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
5105 if (dut->testbed_flag_rxsp == 1) {
5106 vht_mcsmap = 0xffc0;
5107 dut->testbed_flag_rxsp = 0;
5108 } else {
5109 vht_mcsmap = 0xffea;
5110 }
5111 rxchainmask = 7;
5112 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
5113 if (dut->testbed_flag_rxsp == 1) {
5114 vht_mcsmap = 0xff00;
5115 dut->testbed_flag_rxsp = 0;
5116 } else {
5117 vht_mcsmap = 0xffaa;
5118 }
5119 rxchainmask = 15;
5120 } else {
5121 if (dut->testbed_flag_rxsp == 1) {
5122 vht_mcsmap = 0xffc0;
5123 dut->testbed_flag_rxsp = 0;
5124 } else {
5125 vht_mcsmap = 0xffea;
5126 }
5127 }
5128
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005129 if (rxchainmask)
5130 run_iwpriv(dut, basedev, "rxchainmask %d", rxchainmask);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005131
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005132 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005133}
5134
5135
5136void ath_set_zero_crc(struct sigma_dut *dut, const char *val)
5137{
5138 if (strcasecmp(val, "enable") == 0) {
5139 if (system("athdiag --set --address=0x2a204 --and=0xbfffffff")
5140 != 0) {
5141 sigma_dut_print(dut, DUT_MSG_ERROR,
5142 "Disable BB_VHTSIGB_CRC_CALC failed");
5143 }
5144
5145 if (system("athdiag --set --address=0x2a204 --or=0x80000000")
5146 != 0) {
5147 sigma_dut_print(dut, DUT_MSG_ERROR,
5148 "Enable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
5149 }
5150 } else {
5151 if (system("athdiag --set --address=0x2a204 --and=0x7fffffff")
5152 != 0) {
5153 sigma_dut_print(dut, DUT_MSG_ERROR,
5154 "Disable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
5155 }
5156
5157 if (system("athdiag --set --address=0x2a204 --or=0x40000000")
5158 != 0) {
5159 sigma_dut_print(dut, DUT_MSG_ERROR,
5160 "Enable BB_VHTSIGB_CRC_CALC failed");
5161 }
5162 }
5163}
5164
5165
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08005166static int wcn_sta_set_width(struct sigma_dut *dut, const char *intf,
5167 const char *val)
5168{
5169 char buf[60];
5170
5171 if (strcmp(val, "20") == 0) {
5172 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 0", intf);
5173 dut->chwidth = 0;
5174 } else if (strcmp(val, "40") == 0) {
5175 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 1", intf);
5176 dut->chwidth = 1;
5177 } else if (strcmp(val, "80") == 0) {
5178 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 2", intf);
5179 dut->chwidth = 2;
Sunil Duttb1cccac2018-05-22 21:03:12 +05305180 } else if (strcasecmp(val, "Auto") == 0) {
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08005181 buf[0] = '\0';
5182 } else {
5183 sigma_dut_print(dut, DUT_MSG_ERROR, "WIDTH %s not supported",
5184 val);
5185 return -1;
5186 }
5187
5188 if (buf[0] != '\0' && system(buf) != 0) {
5189 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv chwidth failed");
5190 return -1;
5191 }
5192
5193 return 0;
5194}
5195
5196
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005197static int nlvendor_sta_set_addba_reject(struct sigma_dut *dut,
5198 const char *intf, int addbareject)
5199{
5200#ifdef NL80211_SUPPORT
5201 struct nl_msg *msg;
5202 int ret = 0;
5203 struct nlattr *params;
5204 int ifindex;
5205
5206 ifindex = if_nametoindex(intf);
5207 if (ifindex == 0) {
5208 sigma_dut_print(dut, DUT_MSG_ERROR,
5209 "%s: Index for interface %s failed",
5210 __func__, intf);
5211 return -1;
5212 }
5213
5214 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
5215 NL80211_CMD_VENDOR)) ||
5216 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
5217 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
5218 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
5219 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
5220 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
5221 nla_put_u8(msg,
5222 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ACCEPT_ADDBA_REQ,
5223 !addbareject)) {
5224 sigma_dut_print(dut, DUT_MSG_ERROR,
5225 "%s: err in adding vendor_cmd and vendor_data",
5226 __func__);
5227 nlmsg_free(msg);
5228 return -1;
5229 }
5230 nla_nest_end(msg, params);
5231
5232 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5233 if (ret) {
5234 sigma_dut_print(dut, DUT_MSG_ERROR,
5235 "%s: err in send_and_recv_msgs, ret=%d",
5236 __func__, ret);
5237 }
5238 return ret;
5239#else /* NL80211_SUPPORT */
5240 sigma_dut_print(dut, DUT_MSG_ERROR,
5241 "ADDBA_REJECT cannot be set without NL80211_SUPPORT defined");
5242 return -1;
5243#endif /* NL80211_SUPPORT */
5244}
5245
5246
5247static int sta_set_addba_reject(struct sigma_dut *dut, const char *intf,
5248 int addbareject)
5249{
5250 int ret;
5251
5252 switch (get_driver_type()) {
5253 case DRIVER_WCN:
5254 ret = nlvendor_sta_set_addba_reject(dut, intf, addbareject);
5255 if (ret) {
5256 sigma_dut_print(dut, DUT_MSG_ERROR,
5257 "nlvendor_sta_set_addba_reject failed, ret:%d",
5258 ret);
5259 return ret;
5260 }
5261 break;
5262 default:
5263 sigma_dut_print(dut, DUT_MSG_ERROR,
5264 "errorCode,Unsupported ADDBA_REJECT with the current driver");
5265 ret = -1;
5266 break;
5267 }
5268
5269 return ret;
5270}
5271
5272
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08005273static int nlvendor_config_send_addba(struct sigma_dut *dut, const char *intf,
5274 int enable)
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005275{
5276#ifdef NL80211_SUPPORT
5277 struct nl_msg *msg;
5278 int ret = 0;
5279 struct nlattr *params;
5280 int ifindex;
5281
5282 ifindex = if_nametoindex(intf);
5283 if (ifindex == 0) {
5284 sigma_dut_print(dut, DUT_MSG_ERROR,
5285 "%s: Index for interface %s failed",
5286 __func__, intf);
5287 return -1;
5288 }
5289
5290 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
5291 NL80211_CMD_VENDOR)) ||
5292 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
5293 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
5294 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
5295 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
5296 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
5297 nla_put_u8(msg,
5298 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_SEND_ADDBA_REQ,
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08005299 enable)) {
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005300 sigma_dut_print(dut, DUT_MSG_ERROR,
5301 "%s: err in adding vendor_cmd and vendor_data",
5302 __func__);
5303 nlmsg_free(msg);
5304 return -1;
5305 }
5306 nla_nest_end(msg, params);
5307
5308 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5309 if (ret) {
5310 sigma_dut_print(dut, DUT_MSG_ERROR,
5311 "%s: err in send_and_recv_msgs, ret=%d",
5312 __func__, ret);
5313 }
5314 return ret;
5315#else /* NL80211_SUPPORT */
5316 sigma_dut_print(dut, DUT_MSG_ERROR,
5317 "Disable addba not possible without NL80211_SUPPORT defined");
5318 return -1;
5319#endif /* NL80211_SUPPORT */
5320}
5321
5322
Veerendranath Jakkamadcd6202019-04-17 12:32:21 +05305323#ifdef NL80211_SUPPORT
5324static int nl80211_sta_set_rts(struct sigma_dut *dut, const char *intf, int val)
5325{
5326 struct nl_msg *msg;
5327 int ret = 0;
5328 int ifindex;
5329
5330 ifindex = if_nametoindex(intf);
5331 if (ifindex == 0) {
5332 sigma_dut_print(dut, DUT_MSG_ERROR,
5333 "%s: Index for interface %s failed",
5334 __func__, intf);
5335 return -1;
5336 }
5337
5338 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
5339 NL80211_CMD_SET_WIPHY)) ||
5340 nla_put_u32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD, val)) {
5341 sigma_dut_print(dut, DUT_MSG_ERROR,
5342 "%s: err in adding RTS threshold",
5343 __func__);
5344 nlmsg_free(msg);
5345 return -1;
5346 }
5347
5348 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5349 if (ret) {
5350 sigma_dut_print(dut, DUT_MSG_ERROR,
5351 "%s: err in send_and_recv_msgs, ret=%d",
5352 __func__, ret);
5353 }
5354 return ret;
5355}
5356#endif /* NL80211_SUPPORT */
5357
5358
5359static int sta_set_rts(struct sigma_dut *dut, const char *intf, int val)
5360{
5361 char buf[100];
5362
5363#ifdef NL80211_SUPPORT
5364 if (nl80211_sta_set_rts(dut, intf, val) == 0)
5365 return 0;
5366 sigma_dut_print(dut, DUT_MSG_DEBUG,
5367 "Fall back to using iwconfig for setting RTS threshold");
5368#endif /* NL80211_SUPPORT */
5369
5370 snprintf(buf, sizeof(buf), "iwconfig %s rts %d", intf, val);
5371 if (system(buf) != 0) {
5372 sigma_dut_print(dut, DUT_MSG_ERROR,
5373 "Failed to set RTS threshold %d", val);
5374 return -1;
5375 }
5376 return 0;
5377}
5378
5379
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005380static int cmd_sta_set_wireless_common(const char *intf, struct sigma_dut *dut,
5381 struct sigma_conn *conn,
5382 struct sigma_cmd *cmd)
5383{
5384 const char *val;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005385 int ampdu = -1, addbareject = -1;
Jouni Malinen3aa72862019-05-29 23:14:51 +03005386 char buf[128];
5387 int res;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005388
5389 val = get_param(cmd, "40_INTOLERANT");
5390 if (val) {
5391 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
5392 /* TODO: iwpriv ht40intol through wpa_supplicant */
5393 send_resp(dut, conn, SIGMA_ERROR,
5394 "ErrorCode,40_INTOLERANT not supported");
5395 return 0;
5396 }
5397 }
5398
5399 val = get_param(cmd, "ADDBA_REJECT");
5400 if (val) {
5401 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
5402 /* reject any ADDBA with status "decline" */
5403 ampdu = 0;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005404 addbareject = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005405 } else {
5406 /* accept ADDBA */
5407 ampdu = 1;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005408 addbareject = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005409 }
5410 }
5411
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005412 if (addbareject >= 0 &&
5413 sta_set_addba_reject(dut, intf, addbareject) < 0) {
5414 send_resp(dut, conn, SIGMA_ERROR,
5415 "ErrorCode,set addba_reject failed");
5416 return 0;
5417 }
5418
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005419 val = get_param(cmd, "AMPDU");
5420 if (val) {
5421 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
5422 /* enable AMPDU Aggregation */
5423 if (ampdu == 0) {
5424 send_resp(dut, conn, SIGMA_ERROR,
5425 "ErrorCode,Mismatch in "
5426 "addba_reject/ampdu - "
5427 "not supported");
5428 return 0;
5429 }
5430 ampdu = 1;
5431 } else {
5432 /* disable AMPDU Aggregation */
5433 if (ampdu == 1) {
5434 send_resp(dut, conn, SIGMA_ERROR,
5435 "ErrorCode,Mismatch in "
5436 "addba_reject/ampdu - "
5437 "not supported");
5438 return 0;
5439 }
5440 ampdu = 0;
5441 }
5442 }
5443
5444 if (ampdu >= 0) {
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005445 int ret;
5446
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005447 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s A-MPDU aggregation",
5448 ampdu ? "Enabling" : "Disabling");
5449 snprintf(buf, sizeof(buf), "SET ampdu %d", ampdu);
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07005450 if (wpa_command(intf, buf) < 0 &&
5451 iwpriv_sta_set_ampdu(dut, intf, ampdu) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005452 send_resp(dut, conn, SIGMA_ERROR,
5453 "ErrorCode,set aggr failed");
5454 return 0;
5455 }
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005456
5457 if (ampdu == 0) {
5458 /* Disable sending of addba using nl vendor command */
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08005459 ret = nlvendor_config_send_addba(dut, intf, 0);
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005460 if (ret) {
5461 sigma_dut_print(dut, DUT_MSG_ERROR,
5462 "Failed to disable addba, ret:%d",
5463 ret);
5464 }
5465 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005466 }
5467
5468 val = get_param(cmd, "AMSDU");
5469 if (val) {
5470 switch (get_driver_type()) {
5471 case DRIVER_ATHEROS:
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08005472 case DRIVER_WCN:
5473 iwpriv_sta_set_amsdu(dut, intf, val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005474 break;
5475 default:
5476 if (strcmp(val, "1") == 0 ||
5477 strcasecmp(val, "Enable") == 0) {
5478 /* Enable AMSDU Aggregation */
5479 send_resp(dut, conn, SIGMA_ERROR,
5480 "ErrorCode,AMSDU aggregation not supported");
5481 return 0;
5482 }
5483 break;
5484 }
5485 }
5486
5487 val = get_param(cmd, "STBC_RX");
5488 if (val) {
5489 switch (get_driver_type()) {
5490 case DRIVER_ATHEROS:
5491 ath_sta_set_stbc(dut, intf, val);
5492 break;
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05305493 case DRIVER_WCN:
5494 wcn_sta_set_stbc(dut, intf, val);
5495 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005496 default:
5497 send_resp(dut, conn, SIGMA_ERROR,
5498 "ErrorCode,STBC_RX not supported");
5499 return 0;
5500 }
5501 }
5502
5503 val = get_param(cmd, "WIDTH");
5504 if (val) {
5505 switch (get_driver_type()) {
5506 case DRIVER_WCN:
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08005507 if (wcn_sta_set_width(dut, intf, val) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005508 send_resp(dut, conn, SIGMA_ERROR,
5509 "ErrorCode,Failed to set WIDTH");
5510 return 0;
5511 }
5512 break;
5513 case DRIVER_ATHEROS:
5514 if (ath_set_width(dut, conn, intf, val) < 0)
5515 return 0;
5516 break;
5517 default:
5518 sigma_dut_print(dut, DUT_MSG_ERROR,
5519 "Setting WIDTH not supported");
5520 break;
5521 }
5522 }
5523
5524 val = get_param(cmd, "SMPS");
5525 if (val) {
5526 /* TODO: Dynamic/0, Static/1, No Limit/2 */
5527 send_resp(dut, conn, SIGMA_ERROR,
5528 "ErrorCode,SMPS not supported");
5529 return 0;
5530 }
5531
5532 val = get_param(cmd, "TXSP_STREAM");
5533 if (val) {
5534 switch (get_driver_type()) {
5535 case DRIVER_WCN:
5536 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
5537 send_resp(dut, conn, SIGMA_ERROR,
5538 "ErrorCode,Failed to set TXSP_STREAM");
5539 return 0;
5540 }
5541 break;
5542 case DRIVER_ATHEROS:
5543 ath_sta_set_txsp_stream(dut, intf, val);
5544 break;
5545 default:
5546 sigma_dut_print(dut, DUT_MSG_ERROR,
5547 "Setting TXSP_STREAM not supported");
5548 break;
5549 }
5550 }
5551
5552 val = get_param(cmd, "RXSP_STREAM");
5553 if (val) {
5554 switch (get_driver_type()) {
5555 case DRIVER_WCN:
5556 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
5557 send_resp(dut, conn, SIGMA_ERROR,
5558 "ErrorCode,Failed to set RXSP_STREAM");
5559 return 0;
5560 }
5561 break;
5562 case DRIVER_ATHEROS:
5563 ath_sta_set_rxsp_stream(dut, intf, val);
5564 break;
5565 default:
5566 sigma_dut_print(dut, DUT_MSG_ERROR,
5567 "Setting RXSP_STREAM not supported");
5568 break;
5569 }
5570 }
5571
5572 val = get_param(cmd, "DYN_BW_SGNL");
5573 if (val) {
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08005574 switch (get_driver_type()) {
5575 case DRIVER_WCN:
Peng Xuc59afd32016-11-21 15:01:11 -08005576 if (strcasecmp(val, "enable") == 0) {
5577 snprintf(buf, sizeof(buf),
5578 "iwpriv %s cwmenable 1", intf);
5579 if (system(buf) != 0) {
5580 sigma_dut_print(dut, DUT_MSG_ERROR,
5581 "iwpriv cwmenable 1 failed");
5582 return 0;
5583 }
5584 } else if (strcasecmp(val, "disable") == 0) {
5585 snprintf(buf, sizeof(buf),
5586 "iwpriv %s cwmenable 0", intf);
5587 if (system(buf) != 0) {
5588 sigma_dut_print(dut, DUT_MSG_ERROR,
5589 "iwpriv cwmenable 0 failed");
5590 return 0;
5591 }
5592 } else {
5593 sigma_dut_print(dut, DUT_MSG_ERROR,
5594 "Unsupported DYN_BW_SGL");
5595 }
5596
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005597 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 3", intf);
5598 if (system(buf) != 0) {
5599 sigma_dut_print(dut, DUT_MSG_ERROR,
5600 "Failed to set cts_cbw in DYN_BW_SGNL");
5601 return 0;
5602 }
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08005603 break;
5604 case DRIVER_ATHEROS:
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -07005605 novap_reset(dut, intf, 1);
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08005606 ath_config_dyn_bw_sig(dut, intf, val);
5607 break;
5608 default:
5609 sigma_dut_print(dut, DUT_MSG_ERROR,
5610 "Failed to set DYN_BW_SGNL");
5611 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005612 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005613 }
5614
5615 val = get_param(cmd, "RTS_FORCE");
5616 if (val) {
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -07005617 novap_reset(dut, intf, 1);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005618 if (strcasecmp(val, "Enable") == 0) {
Veerendranath Jakkamadcd6202019-04-17 12:32:21 +05305619 if (sta_set_rts(dut, intf, 64) != 0) {
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02005620 sigma_dut_print(dut, DUT_MSG_ERROR,
5621 "Failed to set RTS_FORCE 64");
5622 }
Jouni Malinen3aa72862019-05-29 23:14:51 +03005623 res = snprintf(buf, sizeof(buf),
5624 "wifitool %s beeliner_fw_test 100 1",
5625 intf);
5626 if (res < 0 || res >= sizeof(buf) || system(buf) != 0) {
priyadharshini gowthaman270870e2015-12-09 10:10:23 -08005627 sigma_dut_print(dut, DUT_MSG_ERROR,
5628 "wifitool beeliner_fw_test 100 1 failed");
5629 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005630 } else if (strcasecmp(val, "Disable") == 0) {
Veerendranath Jakkamadcd6202019-04-17 12:32:21 +05305631 if (sta_set_rts(dut, intf, 2347) != 0) {
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02005632 sigma_dut_print(dut, DUT_MSG_ERROR,
5633 "Failed to set RTS_FORCE 2347");
5634 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005635 } else {
5636 send_resp(dut, conn, SIGMA_ERROR,
5637 "ErrorCode,RTS_FORCE value not supported");
5638 return 0;
5639 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005640 }
5641
5642 val = get_param(cmd, "CTS_WIDTH");
5643 if (val) {
5644 switch (get_driver_type()) {
5645 case DRIVER_WCN:
5646 if (wcn_sta_set_cts_width(dut, intf, val) < 0) {
5647 send_resp(dut, conn, SIGMA_ERROR,
5648 "ErrorCode,Failed to set CTS_WIDTH");
5649 return 0;
5650 }
5651 break;
5652 case DRIVER_ATHEROS:
5653 ath_set_cts_width(dut, intf, val);
5654 break;
5655 default:
5656 sigma_dut_print(dut, DUT_MSG_ERROR,
5657 "Setting CTS_WIDTH not supported");
5658 break;
5659 }
5660 }
5661
5662 val = get_param(cmd, "BW_SGNL");
5663 if (val) {
5664 if (strcasecmp(val, "Enable") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005665 run_iwpriv(dut, intf, "cwmenable 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005666 } else if (strcasecmp(val, "Disable") == 0) {
5667 /* TODO: Disable */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005668 } else {
5669 send_resp(dut, conn, SIGMA_ERROR,
5670 "ErrorCode,BW_SGNL value not supported");
5671 return 0;
5672 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005673 }
5674
5675 val = get_param(cmd, "Band");
5676 if (val) {
5677 if (strcmp(val, "2.4") == 0 || strcmp(val, "5") == 0) {
5678 /* STA supports all bands by default */
5679 } else {
5680 send_resp(dut, conn, SIGMA_ERROR,
5681 "ErrorCode,Unsupported Band");
5682 return 0;
5683 }
5684 }
5685
5686 val = get_param(cmd, "zero_crc");
5687 if (val) {
5688 switch (get_driver_type()) {
5689 case DRIVER_ATHEROS:
5690 ath_set_zero_crc(dut, val);
5691 break;
5692 default:
5693 break;
5694 }
5695 }
5696
5697 return 1;
5698}
5699
5700
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02005701static int sta_set_force_mcs(struct sigma_dut *dut, int force, int mcs)
5702{
5703 switch (get_driver_type()) {
5704#ifdef __linux__
5705 case DRIVER_WIL6210:
5706 return wil6210_set_force_mcs(dut, force, mcs);
5707#endif /* __linux__ */
5708 default:
5709 sigma_dut_print(dut, DUT_MSG_ERROR,
5710 "Unsupported sta_set_force_mcs with the current driver");
5711 return -1;
5712 }
5713}
5714
5715
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02005716static int sta_60g_force_rsn_ie(struct sigma_dut *dut, int state)
5717{
5718 switch (get_driver_type()) {
5719#ifdef __linux__
5720 case DRIVER_WIL6210:
5721 return wil6210_force_rsn_ie(dut, state);
5722#endif /* __linux__ */
5723 default:
5724 sigma_dut_print(dut, DUT_MSG_ERROR,
5725 "Unsupported sta_60g_force_rsn_ie with the current driver");
5726 return -1;
5727 }
5728}
5729
5730
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005731static int sta_set_60g_common(struct sigma_dut *dut, struct sigma_conn *conn,
5732 struct sigma_cmd *cmd)
5733{
5734 const char *val;
5735 char buf[100];
5736
5737 val = get_param(cmd, "MSDUSize");
5738 if (val) {
5739 int mtu;
5740
5741 dut->amsdu_size = atoi(val);
5742 if (dut->amsdu_size > IEEE80211_MAX_DATA_LEN_DMG ||
5743 dut->amsdu_size < IEEE80211_SNAP_LEN_DMG) {
5744 sigma_dut_print(dut, DUT_MSG_ERROR,
5745 "MSDUSize %d is above max %d or below min %d",
5746 dut->amsdu_size,
5747 IEEE80211_MAX_DATA_LEN_DMG,
5748 IEEE80211_SNAP_LEN_DMG);
5749 dut->amsdu_size = 0;
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005750 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005751 }
5752
5753 mtu = dut->amsdu_size - IEEE80211_SNAP_LEN_DMG;
5754 sigma_dut_print(dut, DUT_MSG_DEBUG,
5755 "Setting amsdu_size to %d", mtu);
5756 snprintf(buf, sizeof(buf), "ifconfig %s mtu %d",
5757 get_station_ifname(), mtu);
5758
5759 if (system(buf) != 0) {
5760 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
5761 buf);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005762 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005763 }
5764 }
5765
5766 val = get_param(cmd, "BAckRcvBuf");
5767 if (val) {
5768 dut->back_rcv_buf = atoi(val);
5769 if (dut->back_rcv_buf == 0) {
5770 sigma_dut_print(dut, DUT_MSG_ERROR,
5771 "Failed to convert %s or value is 0",
5772 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005773 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005774 }
5775
5776 sigma_dut_print(dut, DUT_MSG_DEBUG,
5777 "Setting BAckRcvBuf to %s", val);
5778 }
5779
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02005780 val = get_param(cmd, "MCS_FixedRate");
5781 if (val) {
5782 if (sta_set_force_mcs(dut, 1, atoi(val))) {
5783 sigma_dut_print(dut, DUT_MSG_ERROR,
5784 "Failed to force MCS");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005785 return ERROR_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02005786 }
5787 }
5788
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005789 return SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005790}
5791
5792
5793static int sta_pcp_start(struct sigma_dut *dut, struct sigma_conn *conn,
5794 struct sigma_cmd *cmd)
5795{
5796 int net_id;
5797 char *ifname;
5798 const char *val;
5799 char buf[100];
5800
5801 dut->mode = SIGMA_MODE_STATION;
5802 ifname = get_main_ifname();
5803 if (wpa_command(ifname, "PING") != 0) {
5804 sigma_dut_print(dut, DUT_MSG_ERROR, "Supplicant not running");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005805 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005806 }
5807
5808 wpa_command(ifname, "FLUSH");
5809 net_id = add_network_common(dut, conn, ifname, cmd);
5810 if (net_id < 0) {
5811 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add network");
5812 return net_id;
5813 }
5814
5815 /* TODO: mode=2 for the AP; in the future, replace for mode PCP */
5816 if (set_network(ifname, net_id, "mode", "2") < 0) {
5817 sigma_dut_print(dut, DUT_MSG_ERROR,
5818 "Failed to set supplicant network mode");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005819 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005820 }
5821
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02005822 if (set_network(ifname, net_id, "pbss", "1") < 0)
5823 return -2;
5824
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005825 sigma_dut_print(dut, DUT_MSG_DEBUG,
Alexei Avshalom Lazarfd9f1352018-11-13 14:07:58 +02005826 "Supplicant set network with mode 2. network_id %d",
5827 net_id);
5828
5829 if (set_network(ifname, net_id, "wps_disabled", "0") < 0) {
5830 sigma_dut_print(dut, DUT_MSG_INFO,
5831 "Failed to set supplicant to WPS ENABLE");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005832 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarfd9f1352018-11-13 14:07:58 +02005833 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005834
5835 val = get_param(cmd, "Security");
5836 if (val && strcasecmp(val, "OPEN") == 0) {
5837 dut->ap_key_mgmt = AP_OPEN;
5838 if (set_network(ifname, net_id, "key_mgmt", "NONE") < 0) {
5839 sigma_dut_print(dut, DUT_MSG_ERROR,
5840 "Failed to set supplicant to %s security",
5841 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005842 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005843 }
5844 } else if (val && strcasecmp(val, "WPA2-PSK") == 0) {
5845 dut->ap_key_mgmt = AP_WPA2_PSK;
5846 if (set_network(ifname, net_id, "key_mgmt", "WPA-PSK") < 0) {
5847 sigma_dut_print(dut, DUT_MSG_ERROR,
5848 "Failed to set supplicant to %s security",
5849 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005850 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005851 }
5852
5853 if (set_network(ifname, net_id, "proto", "RSN") < 0) {
5854 sigma_dut_print(dut, DUT_MSG_ERROR,
5855 "Failed to set supplicant to proto RSN");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005856 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005857 }
5858 } else if (val) {
5859 sigma_dut_print(dut, DUT_MSG_ERROR,
5860 "Requested Security %s is not supported on 60GHz",
5861 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005862 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005863 }
5864
5865 val = get_param(cmd, "Encrypt");
5866 if (val && strcasecmp(val, "AES-GCMP") == 0) {
5867 if (set_network(ifname, net_id, "pairwise", "GCMP") < 0) {
5868 sigma_dut_print(dut, DUT_MSG_ERROR,
5869 "Failed to set supplicant to pairwise GCMP");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005870 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005871 }
5872 if (set_network(ifname, net_id, "group", "GCMP") < 0) {
5873 sigma_dut_print(dut, DUT_MSG_ERROR,
5874 "Failed to set supplicant to group GCMP");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005875 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005876 }
5877 } else if (val) {
5878 sigma_dut_print(dut, DUT_MSG_ERROR,
5879 "Requested Encrypt %s is not supported on 60 GHz",
5880 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005881 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005882 }
5883
5884 val = get_param(cmd, "PSK");
5885 if (val && set_network_quoted(ifname, net_id, "psk", val) < 0) {
5886 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set psk %s",
5887 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005888 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005889 }
5890
5891 /* Convert 60G channel to freq */
5892 switch (dut->ap_channel) {
5893 case 1:
5894 val = "58320";
5895 break;
5896 case 2:
5897 val = "60480";
5898 break;
5899 case 3:
5900 val = "62640";
5901 break;
5902 default:
5903 sigma_dut_print(dut, DUT_MSG_ERROR,
5904 "Failed to configure channel %d. Not supported",
5905 dut->ap_channel);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005906 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005907 }
5908
5909 if (set_network(ifname, net_id, "frequency", val) < 0) {
5910 sigma_dut_print(dut, DUT_MSG_ERROR,
5911 "Failed to set supplicant network frequency");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005912 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005913 }
5914
Alexei Avshalom Lazar2eccf4d2019-01-31 10:03:59 +02005915 if (dut->eap_fragment) {
5916 sigma_dut_print(dut, DUT_MSG_DEBUG,
5917 "Set EAP fragment size to 128 bytes.");
5918 if (set_network(ifname, net_id, "fragment_size", "128") < 0)
5919 return ERROR_SEND_STATUS;
5920 }
5921
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005922 sigma_dut_print(dut, DUT_MSG_DEBUG,
5923 "Supplicant set network with frequency");
5924
5925 snprintf(buf, sizeof(buf), "SELECT_NETWORK %d", net_id);
5926 if (wpa_command(ifname, buf) < 0) {
5927 sigma_dut_print(dut, DUT_MSG_INFO,
5928 "Failed to select network id %d on %s",
5929 net_id, ifname);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005930 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005931 }
5932
5933 sigma_dut_print(dut, DUT_MSG_DEBUG, "Selected network");
5934
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005935 return SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005936}
5937
5938
Lior David67543f52017-01-03 19:04:22 +02005939static int wil6210_set_abft_len(struct sigma_dut *dut, int abft_len)
5940{
5941 char buf[128], fname[128];
5942 FILE *f;
Jouni Malinen3aa72862019-05-29 23:14:51 +03005943 int res;
Lior David67543f52017-01-03 19:04:22 +02005944
5945 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
5946 sigma_dut_print(dut, DUT_MSG_ERROR,
5947 "failed to get wil6210 debugfs dir");
5948 return -1;
5949 }
5950
Jouni Malinen3aa72862019-05-29 23:14:51 +03005951 res = snprintf(fname, sizeof(fname), "%s/abft_len", buf);
5952 if (res < 0 || res >= sizeof(fname))
5953 return -1;
Lior David67543f52017-01-03 19:04:22 +02005954 f = fopen(fname, "w");
5955 if (!f) {
5956 sigma_dut_print(dut, DUT_MSG_ERROR,
5957 "failed to open: %s", fname);
5958 return -1;
5959 }
5960
5961 fprintf(f, "%d\n", abft_len);
5962 fclose(f);
5963
5964 return 0;
5965}
5966
5967
Alexei Avshalom Lazar49498b82019-01-31 15:16:32 +02005968int sta_set_60g_abft_len(struct sigma_dut *dut, struct sigma_conn *conn,
5969 int abft_len)
Lior David67543f52017-01-03 19:04:22 +02005970{
5971 switch (get_driver_type()) {
5972 case DRIVER_WIL6210:
5973 return wil6210_set_abft_len(dut, abft_len);
5974 default:
5975 sigma_dut_print(dut, DUT_MSG_ERROR,
5976 "set abft_len not supported");
5977 return -1;
5978 }
5979}
5980
5981
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005982static int sta_set_60g_pcp(struct sigma_dut *dut, struct sigma_conn *conn,
5983 struct sigma_cmd *cmd)
5984{
5985 const char *val;
Lior David67543f52017-01-03 19:04:22 +02005986 unsigned int abft_len = 1; /* default is one slot */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005987
5988 if (dut->dev_role != DEVROLE_PCP) {
5989 send_resp(dut, conn, SIGMA_INVALID,
5990 "ErrorCode,Invalid DevRole");
5991 return 0;
5992 }
5993
5994 val = get_param(cmd, "SSID");
5995 if (val) {
5996 if (strlen(val) > sizeof(dut->ap_ssid) - 1) {
5997 send_resp(dut, conn, SIGMA_INVALID,
5998 "ErrorCode,Invalid SSID");
5999 return -1;
6000 }
6001
Peng Xub8fc5cc2017-05-10 17:27:28 -07006002 strlcpy(dut->ap_ssid, val, sizeof(dut->ap_ssid));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006003 }
6004
6005 val = get_param(cmd, "CHANNEL");
6006 if (val) {
6007 const char *pos;
6008
6009 dut->ap_channel = atoi(val);
6010 pos = strchr(val, ';');
6011 if (pos) {
6012 pos++;
6013 dut->ap_channel_1 = atoi(pos);
6014 }
6015 }
6016
6017 switch (dut->ap_channel) {
6018 case 1:
6019 case 2:
6020 case 3:
6021 break;
6022 default:
6023 sigma_dut_print(dut, DUT_MSG_ERROR,
6024 "Channel %d is not supported", dut->ap_channel);
6025 send_resp(dut, conn, SIGMA_ERROR,
6026 "Requested channel is not supported");
6027 return -1;
6028 }
6029
6030 val = get_param(cmd, "BCNINT");
6031 if (val)
6032 dut->ap_bcnint = atoi(val);
6033
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006034 val = get_param(cmd, "AllocType");
6035 if (val) {
6036 send_resp(dut, conn, SIGMA_ERROR,
6037 "ErrorCode,AllocType is not supported yet");
6038 return -1;
6039 }
6040
6041 val = get_param(cmd, "PercentBI");
6042 if (val) {
6043 send_resp(dut, conn, SIGMA_ERROR,
6044 "ErrorCode,PercentBI is not supported yet");
6045 return -1;
6046 }
6047
6048 val = get_param(cmd, "CBAPOnly");
6049 if (val) {
6050 send_resp(dut, conn, SIGMA_ERROR,
6051 "ErrorCode,CBAPOnly is not supported yet");
6052 return -1;
6053 }
6054
6055 val = get_param(cmd, "AMPDU");
6056 if (val) {
6057 if (strcasecmp(val, "Enable") == 0)
6058 dut->ap_ampdu = 1;
6059 else if (strcasecmp(val, "Disable") == 0)
6060 dut->ap_ampdu = 2;
6061 else {
6062 send_resp(dut, conn, SIGMA_ERROR,
6063 "ErrorCode,AMPDU value is not Enable nor Disabled");
6064 return -1;
6065 }
6066 }
6067
6068 val = get_param(cmd, "AMSDU");
6069 if (val) {
6070 if (strcasecmp(val, "Enable") == 0)
6071 dut->ap_amsdu = 1;
6072 else if (strcasecmp(val, "Disable") == 0)
6073 dut->ap_amsdu = 2;
6074 }
6075
6076 val = get_param(cmd, "NumMSDU");
6077 if (val) {
6078 send_resp(dut, conn, SIGMA_ERROR,
6079 "ErrorCode, NumMSDU is not supported yet");
6080 return -1;
6081 }
6082
6083 val = get_param(cmd, "ABFTLRang");
6084 if (val) {
6085 sigma_dut_print(dut, DUT_MSG_DEBUG,
Lior David67543f52017-01-03 19:04:22 +02006086 "ABFTLRang parameter %s", val);
6087 if (strcmp(val, "Gt1") == 0)
6088 abft_len = 2; /* 2 slots in this case */
6089 }
6090
6091 if (sta_set_60g_abft_len(dut, conn, abft_len)) {
6092 send_resp(dut, conn, SIGMA_ERROR,
6093 "ErrorCode, Can't set ABFT length");
6094 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006095 }
6096
6097 if (sta_pcp_start(dut, conn, cmd) < 0) {
6098 send_resp(dut, conn, SIGMA_ERROR,
6099 "ErrorCode, Can't start PCP role");
6100 return -1;
6101 }
6102
6103 return sta_set_60g_common(dut, conn, cmd);
6104}
6105
6106
6107static int sta_set_60g_sta(struct sigma_dut *dut, struct sigma_conn *conn,
6108 struct sigma_cmd *cmd)
6109{
6110 const char *val = get_param(cmd, "DiscoveryMode");
6111
6112 if (dut->dev_role != DEVROLE_STA) {
6113 send_resp(dut, conn, SIGMA_INVALID,
6114 "ErrorCode,Invalid DevRole");
6115 return 0;
6116 }
6117
6118 if (val) {
6119 sigma_dut_print(dut, DUT_MSG_DEBUG, "Discovery: %s", val);
6120 /* Ignore Discovery mode till Driver expose API. */
6121#if 0
6122 if (strcasecmp(val, "1") == 0) {
6123 send_resp(dut, conn, SIGMA_INVALID,
6124 "ErrorCode,DiscoveryMode 1 not supported");
6125 return 0;
6126 }
6127
6128 if (strcasecmp(val, "0") == 0) {
6129 /* OK */
6130 } else {
6131 send_resp(dut, conn, SIGMA_INVALID,
6132 "ErrorCode,DiscoveryMode not supported");
6133 return 0;
6134 }
6135#endif
6136 }
6137
6138 if (start_sta_mode(dut) != 0)
Jouni Malinen0e29cf22019-02-19 01:13:21 +02006139 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006140 return sta_set_60g_common(dut, conn, cmd);
6141}
6142
6143
Jouni Malinenf7222712019-06-13 01:50:21 +03006144static enum sigma_cmd_result cmd_sta_disconnect(struct sigma_dut *dut,
6145 struct sigma_conn *conn,
6146 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006147{
6148 const char *intf = get_param(cmd, "Interface");
Jouni Malinened77e672018-01-10 16:45:13 +02006149 const char *val = get_param(cmd, "maintain_profile");
vamsi krishnad605c422017-09-20 14:56:31 +05306150
Jouni Malinened77e672018-01-10 16:45:13 +02006151 if (dut->program == PROGRAM_OCE ||
Amarnath Hullur Subramanyamebeda9e2018-01-31 03:21:48 -08006152 dut->program == PROGRAM_HE ||
Jouni Malinened77e672018-01-10 16:45:13 +02006153 (val && atoi(val) == 1)) {
vamsi krishnad605c422017-09-20 14:56:31 +05306154 wpa_command(intf, "DISCONNECT");
6155 return 1;
6156 }
6157
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006158 disconnect_station(dut);
6159 /* Try to ignore old scan results to avoid HS 2.0R2 test case failures
6160 * due to cached results. */
6161 wpa_command(intf, "SET ignore_old_scan_res 1");
6162 wpa_command(intf, "BSS_FLUSH");
6163 return 1;
6164}
6165
6166
Jouni Malinenf7222712019-06-13 01:50:21 +03006167static enum sigma_cmd_result cmd_sta_reassoc(struct sigma_dut *dut,
6168 struct sigma_conn *conn,
6169 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006170{
6171 const char *intf = get_param(cmd, "Interface");
6172 const char *bssid = get_param(cmd, "bssid");
6173 const char *val = get_param(cmd, "CHANNEL");
6174 struct wpa_ctrl *ctrl;
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05306175 char buf[1000];
Sunil Duttd30ce092018-01-11 23:56:29 +05306176 char result[32];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006177 int res;
6178 int chan = 0;
Ashwini Patil467efef2017-05-25 12:18:27 +05306179 int status = 0;
Sunil Duttd30ce092018-01-11 23:56:29 +05306180 int fastreassoc = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006181
6182 if (bssid == NULL) {
6183 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing bssid "
6184 "argument");
6185 return 0;
6186 }
6187
6188 if (val)
6189 chan = atoi(val);
6190
6191 if (wifi_chip_type != DRIVER_WCN && wifi_chip_type != DRIVER_AR6003) {
6192 /* The current network may be from sta_associate or
6193 * sta_hs2_associate
6194 */
6195 if (set_network(intf, dut->infra_network_id, "bssid", bssid) <
6196 0 ||
6197 set_network(intf, 0, "bssid", bssid) < 0)
6198 return -2;
6199 }
6200
6201 ctrl = open_wpa_mon(intf);
6202 if (ctrl == NULL) {
6203 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
6204 "wpa_supplicant monitor connection");
6205 return -1;
6206 }
6207
Sunil Duttd30ce092018-01-11 23:56:29 +05306208 if (get_wpa_status(get_station_ifname(), "wpa_state", result,
6209 sizeof(result)) < 0 ||
6210 strncmp(result, "COMPLETED", 9) != 0) {
6211 sigma_dut_print(dut, DUT_MSG_DEBUG,
6212 "sta_reassoc: Not connected");
6213 fastreassoc = 0;
6214 }
6215
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05306216 if (dut->rsne_override) {
6217#ifdef NL80211_SUPPORT
6218 if (get_driver_type() == DRIVER_WCN && dut->config_rsnie == 0) {
6219 sta_config_rsnie(dut, 1);
6220 dut->config_rsnie = 1;
6221 }
6222#endif /* NL80211_SUPPORT */
6223 snprintf(buf, sizeof(buf), "TEST_ASSOC_IE %s",
6224 dut->rsne_override);
6225 if (wpa_command(intf, buf) < 0) {
6226 send_resp(dut, conn, SIGMA_ERROR,
6227 "ErrorCode,Failed to set DEV_CONFIGURE_IE RSNE override");
6228 return 0;
6229 }
6230 }
6231
Sunil Duttd30ce092018-01-11 23:56:29 +05306232 if (wifi_chip_type == DRIVER_WCN && fastreassoc) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006233#ifdef ANDROID
Ashwini Patil4c8158f2017-05-25 12:49:21 +05306234 if (chan) {
6235 unsigned int freq;
6236
Alexei Avshalom Lazar093569f2018-11-13 14:08:17 +02006237 freq = channel_to_freq(dut, chan);
Ashwini Patil4c8158f2017-05-25 12:49:21 +05306238 if (!freq) {
6239 sigma_dut_print(dut, DUT_MSG_ERROR,
6240 "Invalid channel number provided: %d",
6241 chan);
6242 send_resp(dut, conn, SIGMA_INVALID,
6243 "ErrorCode,Invalid channel number");
6244 goto close_mon_conn;
6245 }
6246 res = snprintf(buf, sizeof(buf),
6247 "SCAN TYPE=ONLY freq=%d", freq);
6248 } else {
6249 res = snprintf(buf, sizeof(buf), "SCAN TYPE=ONLY");
6250 }
6251 if (res < 0 || res >= (int) sizeof(buf)) {
6252 send_resp(dut, conn, SIGMA_ERROR,
6253 "ErrorCode,snprintf failed");
6254 goto close_mon_conn;
6255 }
6256 if (wpa_command(intf, buf) < 0) {
6257 sigma_dut_print(dut, DUT_MSG_INFO,
6258 "Failed to start scan");
6259 send_resp(dut, conn, SIGMA_ERROR,
6260 "ErrorCode,scan failed");
6261 goto close_mon_conn;
6262 }
6263
6264 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
6265 buf, sizeof(buf));
6266 if (res < 0) {
6267 sigma_dut_print(dut, DUT_MSG_INFO,
6268 "Scan did not complete");
6269 send_resp(dut, conn, SIGMA_ERROR,
6270 "ErrorCode,scan did not complete");
6271 goto close_mon_conn;
6272 }
6273
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006274 if (set_network(intf, dut->infra_network_id, "bssid", "any")
6275 < 0) {
6276 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
6277 "bssid to any during FASTREASSOC");
Ashwini Patil467efef2017-05-25 12:18:27 +05306278 status = -2;
6279 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006280 }
6281 res = snprintf(buf, sizeof(buf), "DRIVER FASTREASSOC %s %d",
6282 bssid, chan);
6283 if (res > 0 && res < (int) sizeof(buf))
6284 res = wpa_command(intf, buf);
6285
6286 if (res < 0 || res >= (int) sizeof(buf)) {
6287 send_resp(dut, conn, SIGMA_ERROR,
6288 "errorCode,Failed to run DRIVER FASTREASSOC");
Ashwini Patil467efef2017-05-25 12:18:27 +05306289 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006290 }
6291#else /* ANDROID */
6292 sigma_dut_print(dut, DUT_MSG_DEBUG,
6293 "Reassoc using iwpriv - skip chan=%d info",
6294 chan);
6295 snprintf(buf, sizeof(buf), "iwpriv %s reassoc", intf);
6296 if (system(buf) != 0) {
6297 sigma_dut_print(dut, DUT_MSG_ERROR, "%s failed", buf);
Ashwini Patil467efef2017-05-25 12:18:27 +05306298 status = -2;
6299 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006300 }
6301#endif /* ANDROID */
6302 sigma_dut_print(dut, DUT_MSG_INFO,
6303 "sta_reassoc: Run %s successful", buf);
6304 } else if (wpa_command(intf, "REASSOCIATE")) {
6305 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
6306 "request reassociation");
Ashwini Patil467efef2017-05-25 12:18:27 +05306307 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006308 }
6309
6310 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
6311 buf, sizeof(buf));
Ashwini Patil467efef2017-05-25 12:18:27 +05306312 if (res < 0) {
6313 sigma_dut_print(dut, DUT_MSG_INFO, "Connection did not complete");
6314 status = -1;
6315 goto close_mon_conn;
6316 }
6317 status = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006318
Ashwini Patil467efef2017-05-25 12:18:27 +05306319close_mon_conn:
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006320 wpa_ctrl_detach(ctrl);
6321 wpa_ctrl_close(ctrl);
Ashwini Patil467efef2017-05-25 12:18:27 +05306322 return status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006323}
6324
6325
6326static void hs2_clear_credentials(const char *intf)
6327{
6328 wpa_command(intf, "REMOVE_CRED all");
6329}
6330
6331
Lior Davidcc88b562017-01-03 18:52:09 +02006332#ifdef __linux__
6333static int wil6210_get_aid(struct sigma_dut *dut, const char *bssid,
6334 unsigned int *aid)
6335{
Lior David0fe101e2017-03-09 16:09:50 +02006336 const char *pattern = "AID[ \t]+([0-9]+)";
Lior Davidcc88b562017-01-03 18:52:09 +02006337
Lior David0fe101e2017-03-09 16:09:50 +02006338 return wil6210_get_sta_info_field(dut, bssid, pattern, aid);
Lior Davidcc88b562017-01-03 18:52:09 +02006339}
6340#endif /* __linux__ */
6341
6342
6343static int sta_get_aid_60g(struct sigma_dut *dut, const char *bssid,
6344 unsigned int *aid)
6345{
6346 switch (get_driver_type()) {
6347#ifdef __linux__
6348 case DRIVER_WIL6210:
6349 return wil6210_get_aid(dut, bssid, aid);
6350#endif /* __linux__ */
6351 default:
6352 sigma_dut_print(dut, DUT_MSG_ERROR, "get AID not supported");
6353 return -1;
6354 }
6355}
6356
6357
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006358static int sta_get_parameter_60g(struct sigma_dut *dut, struct sigma_conn *conn,
6359 struct sigma_cmd *cmd)
6360{
6361 char buf[MAX_CMD_LEN];
6362 char bss_list[MAX_CMD_LEN];
6363 const char *parameter = get_param(cmd, "Parameter");
6364
6365 if (parameter == NULL)
6366 return -1;
6367
Lior Davidcc88b562017-01-03 18:52:09 +02006368 if (strcasecmp(parameter, "AID") == 0) {
6369 unsigned int aid = 0;
6370 char bssid[20];
6371
6372 if (get_wpa_status(get_station_ifname(), "bssid",
6373 bssid, sizeof(bssid)) < 0) {
6374 sigma_dut_print(dut, DUT_MSG_ERROR,
6375 "could not get bssid");
6376 return -2;
6377 }
6378
6379 if (sta_get_aid_60g(dut, bssid, &aid))
6380 return -2;
6381
6382 snprintf(buf, sizeof(buf), "aid,%d", aid);
6383 sigma_dut_print(dut, DUT_MSG_INFO, "%s", buf);
6384 send_resp(dut, conn, SIGMA_COMPLETE, buf);
6385 return 0;
6386 }
6387
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006388 if (strcasecmp(parameter, "DiscoveredDevList") == 0) {
6389 char *bss_line;
6390 char *bss_id = NULL;
6391 const char *ifname = get_param(cmd, "Interface");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05306392 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006393
6394 if (ifname == NULL) {
6395 sigma_dut_print(dut, DUT_MSG_INFO,
6396 "For get DiscoveredDevList need Interface name.");
6397 return -1;
6398 }
6399
6400 /*
6401 * Use "BSS RANGE=ALL MASK=0x2" which provides a list
6402 * of BSSIDs in "bssid=<BSSID>\n"
6403 */
6404 if (wpa_command_resp(ifname, "BSS RANGE=ALL MASK=0x2",
6405 bss_list,
6406 sizeof(bss_list)) < 0) {
6407 sigma_dut_print(dut, DUT_MSG_ERROR,
6408 "Failed to get bss list");
6409 return -1;
6410 }
6411
6412 sigma_dut_print(dut, DUT_MSG_DEBUG,
6413 "bss list for ifname:%s is:%s",
6414 ifname, bss_list);
6415
6416 snprintf(buf, sizeof(buf), "DeviceList");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05306417 bss_line = strtok_r(bss_list, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006418 while (bss_line) {
6419 if (sscanf(bss_line, "bssid=%ms", &bss_id) > 0 &&
6420 bss_id) {
6421 int len;
6422
6423 len = snprintf(buf + strlen(buf),
6424 sizeof(buf) - strlen(buf),
6425 ",%s", bss_id);
6426 free(bss_id);
6427 bss_id = NULL;
6428 if (len < 0) {
6429 sigma_dut_print(dut,
6430 DUT_MSG_ERROR,
6431 "Failed to read BSSID");
6432 send_resp(dut, conn, SIGMA_ERROR,
6433 "ErrorCode,Failed to read BSS ID");
6434 return 0;
6435 }
6436
6437 if ((size_t) len >= sizeof(buf) - strlen(buf)) {
6438 sigma_dut_print(dut,
6439 DUT_MSG_ERROR,
6440 "Response buf too small for list");
6441 send_resp(dut, conn,
6442 SIGMA_ERROR,
6443 "ErrorCode,Response buf too small for list");
6444 return 0;
6445 }
6446 }
6447
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05306448 bss_line = strtok_r(NULL, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006449 }
6450
6451 sigma_dut_print(dut, DUT_MSG_INFO, "DiscoveredDevList is %s",
6452 buf);
6453 send_resp(dut, conn, SIGMA_COMPLETE, buf);
6454 return 0;
6455 }
6456
6457 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
6458 return 0;
6459}
6460
6461
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07006462static int sta_get_parameter_he(struct sigma_dut *dut, struct sigma_conn *conn,
6463 struct sigma_cmd *cmd)
6464{
6465 char buf[MAX_CMD_LEN];
6466 const char *parameter = get_param(cmd, "Parameter");
6467
6468 if (!parameter)
6469 return -1;
6470
6471 if (strcasecmp(parameter, "RSSI") == 0) {
6472 char rssi[10];
6473
6474 if (get_wpa_signal_poll(dut, get_station_ifname(), "RSSI",
6475 rssi, sizeof(rssi)) < 0) {
6476 sigma_dut_print(dut, DUT_MSG_ERROR,
6477 "Could not get RSSI");
6478 return -2;
6479 }
6480
6481 snprintf(buf, sizeof(buf), "rssi,%s", rssi);
6482 sigma_dut_print(dut, DUT_MSG_INFO, "RSSI %s", buf);
6483 send_resp(dut, conn, SIGMA_COMPLETE, buf);
6484 return 0;
6485 }
6486
6487 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
6488 return 0;
6489}
6490
6491
Jouni Malinenf7222712019-06-13 01:50:21 +03006492static enum sigma_cmd_result cmd_sta_get_parameter(struct sigma_dut *dut,
6493 struct sigma_conn *conn,
6494 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006495{
6496 const char *program = get_param(cmd, "Program");
6497
6498 if (program == NULL)
6499 return -1;
6500
6501 if (strcasecmp(program, "P2PNFC") == 0)
6502 return p2p_cmd_sta_get_parameter(dut, conn, cmd);
6503
6504 if (strcasecmp(program, "60ghz") == 0)
6505 return sta_get_parameter_60g(dut, conn, cmd);
6506
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07006507 if (strcasecmp(program, "he") == 0)
6508 return sta_get_parameter_he(dut, conn, cmd);
6509
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006510#ifdef ANDROID_NAN
6511 if (strcasecmp(program, "NAN") == 0)
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07006512 return nan_cmd_sta_get_parameter(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006513#endif /* ANDROID_NAN */
6514
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07006515#ifdef MIRACAST
6516 if (strcasecmp(program, "WFD") == 0 ||
6517 strcasecmp(program, "DisplayR2") == 0)
6518 return miracast_cmd_sta_get_parameter(dut, conn, cmd);
6519#endif /* MIRACAST */
6520
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006521 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
6522 return 0;
6523}
6524
6525
6526static void sta_reset_default_ath(struct sigma_dut *dut, const char *intf,
6527 const char *type)
6528{
6529 char buf[100];
6530
6531 if (dut->program == PROGRAM_VHT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006532 run_iwpriv(dut, intf, "chwidth 2");
6533 run_iwpriv(dut, intf, "mode 11ACVHT80");
6534 run_iwpriv(dut, intf, "vhtmcs -1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006535 }
6536
6537 if (dut->program == PROGRAM_HT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006538 run_iwpriv(dut, intf, "chwidth 0");
6539 run_iwpriv(dut, intf, "mode 11naht40");
6540 run_iwpriv(dut, intf, "set11NRates 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006541 }
6542
6543 if (dut->program == PROGRAM_VHT || dut->program == PROGRAM_HT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006544 run_iwpriv(dut, intf, "powersave 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006545
6546 /* Reset CTS width */
6547 snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 54 0",
6548 intf);
6549 if (system(buf) != 0) {
6550 sigma_dut_print(dut, DUT_MSG_ERROR,
6551 "wifitool %s beeliner_fw_test 54 0 failed",
6552 intf);
6553 }
6554
6555 /* Enable Dynamic Bandwidth signalling by default */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006556 run_iwpriv(dut, intf, "cwmenable 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006557
6558 snprintf(buf, sizeof(buf), "iwconfig %s rts 2347", intf);
6559 if (system(buf) != 0) {
6560 sigma_dut_print(dut, DUT_MSG_ERROR,
6561 "iwpriv rts failed");
6562 }
6563 }
6564
6565 if (type && strcasecmp(type, "Testbed") == 0) {
6566 dut->testbed_flag_txsp = 1;
6567 dut->testbed_flag_rxsp = 1;
6568 /* STA has to set spatial stream to 2 per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006569 run_iwpriv(dut, intf, "vht_mcsmap 0xfff0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006570
6571 /* Disable LDPC per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006572 run_iwpriv(dut, intf, "ldpc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006573
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006574 run_iwpriv(dut, intf, "amsdu 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006575
6576 /* TODO: Disable STBC 2x1 transmit and receive */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006577 run_iwpriv(dut, intf, "tx_stbc 0");
6578 run_iwpriv(dut, intf, "rx_stbc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006579
6580 /* STA has to disable Short GI per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006581 run_iwpriv(dut, intf, "shortgi 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006582 }
6583
6584 if (type && strcasecmp(type, "DUT") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006585 run_iwpriv(dut, intf, "nss 3");
Arif Hussainac6c5112018-05-25 17:34:00 -07006586 dut->sta_nss = 3;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006587
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006588 run_iwpriv(dut, intf, "shortgi 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006589 }
6590}
6591
6592
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08006593#ifdef NL80211_SUPPORT
6594static int sta_set_he_mcs(struct sigma_dut *dut, const char *intf,
6595 enum he_mcs_config mcs)
6596{
6597 struct nl_msg *msg;
6598 int ret = 0;
6599 struct nlattr *params;
6600 int ifindex;
6601
6602 ifindex = if_nametoindex(intf);
6603 if (ifindex == 0) {
6604 sigma_dut_print(dut, DUT_MSG_ERROR,
6605 "%s: Index for interface %s failed",
6606 __func__, intf);
6607 return -1;
6608 }
6609
6610 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6611 NL80211_CMD_VENDOR)) ||
6612 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6613 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6614 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6615 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6616 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6617 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MCS,
6618 mcs)) {
6619 sigma_dut_print(dut, DUT_MSG_ERROR,
6620 "%s: err in adding vendor_cmd and vendor_data",
6621 __func__);
6622 nlmsg_free(msg);
6623 return -1;
6624 }
6625 nla_nest_end(msg, params);
6626
6627 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6628 if (ret) {
6629 sigma_dut_print(dut, DUT_MSG_ERROR,
6630 "%s: err in send_and_recv_msgs, ret=%d",
6631 __func__, ret);
6632 }
6633 return ret;
6634}
6635#endif /* NL80211_SUPPORT */
6636
6637
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07006638static int sta_set_action_tx_in_he_tb_ppdu(struct sigma_dut *dut,
6639 const char *intf, int enable)
6640{
6641#ifdef NL80211_SUPPORT
6642 struct nl_msg *msg;
6643 int ret = 0;
6644 struct nlattr *params;
6645 int ifindex;
6646
6647 ifindex = if_nametoindex(intf);
6648 if (ifindex == 0) {
6649 sigma_dut_print(dut, DUT_MSG_ERROR,
6650 "%s: Index for interface %s failed",
6651 __func__, intf);
6652 return -1;
6653 }
6654
6655 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6656 NL80211_CMD_VENDOR)) ||
6657 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6658 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6659 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6660 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6661 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6662 nla_put_u8(msg,
6663 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_ACTION_TX_TB_PPDU,
6664 enable)) {
6665 sigma_dut_print(dut, DUT_MSG_ERROR,
6666 "%s: err in adding vendor_cmd and vendor_data",
6667 __func__);
6668 nlmsg_free(msg);
6669 return -1;
6670 }
6671 nla_nest_end(msg, params);
6672
6673 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6674 if (ret) {
6675 sigma_dut_print(dut, DUT_MSG_ERROR,
6676 "%s: err in send_and_recv_msgs, ret=%d",
6677 __func__, ret);
6678 }
6679 return ret;
6680#else /* NL80211_SUPPORT */
6681 sigma_dut_print(dut, DUT_MSG_ERROR,
6682 "HE action Tx TB PPDU cannot be set without NL80211_SUPPORT defined");
6683 return -1;
6684#endif /* NL80211_SUPPORT */
6685}
6686
6687
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08006688static int sta_set_heconfig_and_wep_tkip(struct sigma_dut *dut,
6689 const char *intf, int enable)
6690{
6691#ifdef NL80211_SUPPORT
6692 struct nl_msg *msg;
6693 int ret = 0;
6694 struct nlattr *params;
6695 int ifindex;
6696
6697 ifindex = if_nametoindex(intf);
6698 if (ifindex == 0) {
6699 sigma_dut_print(dut, DUT_MSG_ERROR,
6700 "%s: Index for interface %s failed",
6701 __func__, intf);
6702 return -1;
6703 }
6704
6705 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6706 NL80211_CMD_VENDOR)) ||
6707 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6708 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6709 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6710 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6711 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6712 nla_put_u8(msg,
6713 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WEP_TKIP_IN_HE,
6714 enable)) {
6715 sigma_dut_print(dut, DUT_MSG_ERROR,
6716 "%s: err in adding vendor_cmd and vendor_data",
6717 __func__);
6718 nlmsg_free(msg);
6719 return -1;
6720 }
6721 nla_nest_end(msg, params);
6722
6723 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6724 if (ret) {
6725 sigma_dut_print(dut, DUT_MSG_ERROR,
6726 "%s: err in send_and_recv_msgs, ret=%d",
6727 __func__, ret);
6728 }
6729 return ret;
6730#else /* NL80211_SUPPORT */
6731 sigma_dut_print(dut, DUT_MSG_ERROR,
6732 "HE config enablement cannot be changed without NL80211_SUPPORT defined");
6733 return -1;
6734#endif /* NL80211_SUPPORT */
6735}
6736
6737
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08006738#ifdef NL80211_SUPPORT
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08006739
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08006740static int sta_set_he_testbed_def(struct sigma_dut *dut,
6741 const char *intf, int cfg)
6742{
6743 struct nl_msg *msg;
6744 int ret = 0;
6745 struct nlattr *params;
6746 int ifindex;
6747
6748 ifindex = if_nametoindex(intf);
6749 if (ifindex == 0) {
6750 sigma_dut_print(dut, DUT_MSG_ERROR,
6751 "%s: Index for interface %s failed",
6752 __func__, intf);
6753 return -1;
6754 }
6755
6756 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6757 NL80211_CMD_VENDOR)) ||
6758 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6759 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6760 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6761 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6762 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6763 nla_put_u8(msg,
6764 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_SET_HE_TESTBED_DEFAULTS,
6765 cfg)) {
6766 sigma_dut_print(dut, DUT_MSG_ERROR,
6767 "%s: err in adding vendor_cmd and vendor_data",
6768 __func__);
6769 nlmsg_free(msg);
6770 return -1;
6771 }
6772 nla_nest_end(msg, params);
6773
6774 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6775 if (ret) {
6776 sigma_dut_print(dut, DUT_MSG_ERROR,
6777 "%s: err in send_and_recv_msgs, ret=%d",
6778 __func__, ret);
6779 }
6780 return ret;
6781}
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08006782
6783
6784static int sta_set_2g_vht_supp(struct sigma_dut *dut, const char *intf, int cfg)
6785{
6786 struct nl_msg *msg;
6787 int ret = 0;
6788 struct nlattr *params;
6789 int ifindex;
6790
6791 ifindex = if_nametoindex(intf);
6792 if (ifindex == 0) {
6793 sigma_dut_print(dut, DUT_MSG_ERROR,
6794 "%s: Index for interface %s failed",
6795 __func__, intf);
6796 return -1;
6797 }
6798
6799 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6800 NL80211_CMD_VENDOR)) ||
6801 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6802 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6803 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6804 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6805 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6806 nla_put_u8(msg,
6807 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_2G_VHT,
6808 cfg)) {
6809 sigma_dut_print(dut, DUT_MSG_ERROR,
6810 "%s: err in adding vendor_cmd and vendor_data",
6811 __func__);
6812 nlmsg_free(msg);
6813 return -1;
6814 }
6815 nla_nest_end(msg, params);
6816
6817 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6818 if (ret) {
6819 sigma_dut_print(dut, DUT_MSG_ERROR,
6820 "%s: err in send_and_recv_msgs, ret=%d",
6821 __func__, ret);
6822 }
6823 return ret;
6824}
6825
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08006826#endif /* NL80211_SUPPORT */
6827
6828
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08006829static int sta_set_addba_buf_size(struct sigma_dut *dut,
6830 const char *intf, int bufsize)
6831{
6832#ifdef NL80211_SUPPORT
6833 struct nl_msg *msg;
6834 int ret = 0;
6835 struct nlattr *params;
6836 int ifindex;
6837
6838 ifindex = if_nametoindex(intf);
6839 if (ifindex == 0) {
6840 sigma_dut_print(dut, DUT_MSG_ERROR,
6841 "%s: Index for interface %s failed",
6842 __func__, intf);
6843 return -1;
6844 }
6845
6846 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6847 NL80211_CMD_VENDOR)) ||
6848 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6849 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6850 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6851 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6852 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
Kiran Kumar Lokere26e27582018-08-01 16:18:34 -07006853 nla_put_u16(msg,
6854 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE,
6855 bufsize)) {
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08006856 sigma_dut_print(dut, DUT_MSG_ERROR,
6857 "%s: err in adding vendor_cmd and vendor_data",
6858 __func__);
6859 nlmsg_free(msg);
6860 return -1;
6861 }
6862 nla_nest_end(msg, params);
6863
6864 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6865 if (ret) {
6866 sigma_dut_print(dut, DUT_MSG_ERROR,
6867 "%s: err in send_and_recv_msgs, ret=%d",
6868 __func__, ret);
6869 }
6870 return ret;
6871#else /* NL80211_SUPPORT */
6872 sigma_dut_print(dut, DUT_MSG_ERROR,
6873 "AddBA bufsize cannot be changed without NL80211_SUPPORT defined");
6874 return -1;
6875#endif /* NL80211_SUPPORT */
6876}
6877
6878
Arif Hussain8d5b27b2018-05-14 14:31:03 -07006879static int sta_set_tx_beamformee(struct sigma_dut *dut, const char *intf,
6880 int enable)
6881{
6882#ifdef NL80211_SUPPORT
6883 struct nl_msg *msg;
6884 int ret = 0;
6885 struct nlattr *params;
6886 int ifindex;
6887
6888 ifindex = if_nametoindex(intf);
6889 if (ifindex == 0) {
6890 sigma_dut_print(dut, DUT_MSG_ERROR,
6891 "%s: Index for interface %s failed",
6892 __func__, intf);
6893 return -1;
6894 }
6895
6896 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6897 NL80211_CMD_VENDOR)) ||
6898 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6899 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6900 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6901 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6902 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6903 nla_put_u8(msg,
6904 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_TX_BEAMFORMEE,
6905 enable)) {
6906 sigma_dut_print(dut, DUT_MSG_ERROR,
6907 "%s: err in adding vendor_cmd and vendor_data",
6908 __func__);
6909 nlmsg_free(msg);
6910 return -1;
6911 }
6912 nla_nest_end(msg, params);
6913
6914 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6915 if (ret) {
6916 sigma_dut_print(dut, DUT_MSG_ERROR,
6917 "%s: err in send_and_recv_msgs, ret=%d",
6918 __func__, ret);
6919 }
6920 return ret;
6921#else /* NL80211_SUPPORT */
6922 sigma_dut_print(dut, DUT_MSG_ERROR,
6923 "tx beamformee cannot be changed without NL80211_SUPPORT defined");
6924 return -1;
6925#endif /* NL80211_SUPPORT */
6926}
6927
6928
Arif Hussain9765f7d2018-07-03 08:28:26 -07006929static int sta_set_beamformee_sts(struct sigma_dut *dut, const char *intf,
6930 int val)
6931{
6932#ifdef NL80211_SUPPORT
6933 struct nl_msg *msg;
6934 int ret = 0;
6935 struct nlattr *params;
6936 int ifindex;
6937
6938 ifindex = if_nametoindex(intf);
6939 if (ifindex == 0) {
6940 sigma_dut_print(dut, DUT_MSG_ERROR,
6941 "%s: Index for interface %s failed, val:%d",
6942 __func__, intf, val);
6943 return -1;
6944 }
6945
6946 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6947 NL80211_CMD_VENDOR)) ||
6948 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6949 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6950 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6951 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6952 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6953 nla_put_u8(msg,
6954 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_BEAMFORMEE_NSTS,
6955 val)) {
6956 sigma_dut_print(dut, DUT_MSG_ERROR,
6957 "%s: err in adding vendor_cmd and vendor_data, val: %d",
6958 __func__, val);
6959 nlmsg_free(msg);
6960 return -1;
6961 }
6962 nla_nest_end(msg, params);
6963
6964 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6965 if (ret) {
6966 sigma_dut_print(dut, DUT_MSG_ERROR,
6967 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
6968 __func__, ret, val);
6969 }
6970 return ret;
6971#else /* NL80211_SUPPORT */
6972 sigma_dut_print(dut, DUT_MSG_ERROR,
6973 "beamformee sts cannot be changed without NL80211_SUPPORT defined");
6974 return -1;
6975#endif /* NL80211_SUPPORT */
6976}
6977
6978
Arif Hussain68d23f52018-07-11 13:39:08 -07006979#ifdef NL80211_SUPPORT
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07006980static int sta_set_mac_padding_duration(struct sigma_dut *dut, const char *intf,
6981 enum qca_wlan_he_mac_padding_dur val)
6982{
Arif Hussain68d23f52018-07-11 13:39:08 -07006983 struct nl_msg *msg;
6984 int ret = 0;
6985 struct nlattr *params;
6986 int ifindex;
6987
6988 ifindex = if_nametoindex(intf);
6989 if (ifindex == 0) {
6990 sigma_dut_print(dut, DUT_MSG_ERROR,
6991 "%s: Index for interface %s failed, val:%d",
6992 __func__, intf, val);
6993 return -1;
6994 }
6995
6996 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6997 NL80211_CMD_VENDOR)) ||
6998 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6999 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7000 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7001 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7002 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7003 nla_put_u8(msg,
7004 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MAC_PADDING_DUR,
7005 val)) {
7006 sigma_dut_print(dut, DUT_MSG_ERROR,
7007 "%s: err in adding vendor_cmd and vendor_data, val: %d",
7008 __func__, val);
7009 nlmsg_free(msg);
7010 return -1;
7011 }
7012 nla_nest_end(msg, params);
7013
7014 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7015 if (ret) {
7016 sigma_dut_print(dut, DUT_MSG_ERROR,
7017 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
7018 __func__, ret, val);
7019 }
7020 return ret;
Arif Hussain68d23f52018-07-11 13:39:08 -07007021}
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07007022#endif /* NL80211_SUPPORT */
Arif Hussain68d23f52018-07-11 13:39:08 -07007023
7024
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07007025static int sta_set_tx_su_ppdu_cfg(struct sigma_dut *dut, const char *intf,
7026 int val)
7027{
7028#ifdef NL80211_SUPPORT
7029 struct nl_msg *msg;
7030 int ret = 0;
7031 struct nlattr *params;
7032 int ifindex;
7033
7034 ifindex = if_nametoindex(intf);
7035 if (ifindex == 0) {
7036 sigma_dut_print(dut, DUT_MSG_ERROR,
7037 "%s: Index for interface %s failed, val:%d",
7038 __func__, intf, val);
7039 return -1;
7040 }
7041
7042 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7043 NL80211_CMD_VENDOR)) ||
7044 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7045 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7046 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7047 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7048 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7049 nla_put_u8(msg,
7050 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_SUPPDU,
7051 val)) {
7052 sigma_dut_print(dut, DUT_MSG_ERROR,
7053 "%s: err in adding vendor_cmd and vendor_data, val: %d",
7054 __func__, val);
7055 nlmsg_free(msg);
7056 return -1;
7057 }
7058 nla_nest_end(msg, params);
7059
7060 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7061 if (ret) {
7062 sigma_dut_print(dut, DUT_MSG_ERROR,
7063 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
7064 __func__, ret, val);
7065 }
7066 return ret;
7067#else /* NL80211_SUPPORT */
7068 sigma_dut_print(dut, DUT_MSG_ERROR,
7069 "Tx SU PPDU cannot be set without NL80211_SUPPORT defined");
7070 return -1;
7071#endif /* NL80211_SUPPORT */
7072}
7073
7074
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07007075#ifdef NL80211_SUPPORT
7076static int sta_set_he_om_ctrl_reset(struct sigma_dut *dut, const char *intf)
7077{
7078 struct nl_msg *msg;
7079 int ret = 0;
7080 struct nlattr *params;
7081 int ifindex;
7082
7083 ifindex = if_nametoindex(intf);
7084 if (ifindex == 0) {
7085 sigma_dut_print(dut, DUT_MSG_ERROR,
7086 "%s: Index for interface %s failed",
7087 __func__, intf);
7088 return -1;
7089 }
7090
7091 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7092 NL80211_CMD_VENDOR)) ||
7093 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7094 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7095 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7096 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7097 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7098 nla_put_flag(msg,
7099 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_CLEAR_HE_OM_CTRL_CONFIG)) {
7100 sigma_dut_print(dut, DUT_MSG_ERROR,
7101 "%s: err in adding vendor_cmd and vendor_data",
7102 __func__);
7103 nlmsg_free(msg);
7104 return -1;
7105 }
7106 nla_nest_end(msg, params);
7107
7108 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7109 if (ret) {
7110 sigma_dut_print(dut, DUT_MSG_ERROR,
7111 "%s: err in send_and_recv_msgs, ret=%d",
7112 __func__, ret);
7113 }
7114 return ret;
7115}
7116#endif /* NL80211_SUPPORT */
7117
7118
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07007119static int sta_set_mu_edca_override(struct sigma_dut *dut, const char *intf,
7120 int val)
7121{
7122#ifdef NL80211_SUPPORT
7123 struct nl_msg *msg;
7124 int ret = 0;
7125 struct nlattr *params;
7126 int ifindex;
7127
7128 ifindex = if_nametoindex(intf);
7129 if (ifindex == 0) {
7130 sigma_dut_print(dut, DUT_MSG_ERROR,
7131 "%s: Index for interface %s failed, val:%d",
7132 __func__, intf, val);
7133 return -1;
7134 }
7135
7136 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7137 NL80211_CMD_VENDOR)) ||
7138 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7139 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7140 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7141 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7142 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7143 nla_put_u8(msg,
7144 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_OVERRIDE_MU_EDCA,
7145 val)) {
7146 sigma_dut_print(dut, DUT_MSG_ERROR,
7147 "%s: err in adding vendor_cmd and vendor_data, val: %d",
7148 __func__, val);
7149 nlmsg_free(msg);
7150 return -1;
7151 }
7152 nla_nest_end(msg, params);
7153
7154 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7155 if (ret) {
7156 sigma_dut_print(dut, DUT_MSG_ERROR,
7157 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
7158 __func__, ret, val);
7159 }
7160 return ret;
7161#else /* NL80211_SUPPORT */
7162 sigma_dut_print(dut, DUT_MSG_ERROR,
7163 "MU EDCA override cannot be changed without NL80211_SUPPORT defined");
7164 return -1;
7165#endif /* NL80211_SUPPORT */
7166}
7167
7168
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07007169static int sta_set_om_ctrl_supp(struct sigma_dut *dut, const char *intf,
7170 int val)
7171{
7172#ifdef NL80211_SUPPORT
7173 struct nl_msg *msg;
7174 int ret = 0;
7175 struct nlattr *params;
7176 int ifindex;
7177
7178 ifindex = if_nametoindex(intf);
7179 if (ifindex == 0) {
7180 sigma_dut_print(dut, DUT_MSG_ERROR,
7181 "%s: Index for interface %s failed, val:%d",
7182 __func__, intf, val);
7183 return -1;
7184 }
7185
7186 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7187 NL80211_CMD_VENDOR)) ||
7188 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7189 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7190 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7191 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7192 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7193 nla_put_u8(msg,
7194 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OM_CTRL_SUPP,
7195 val)) {
7196 sigma_dut_print(dut, DUT_MSG_ERROR,
7197 "%s: err in adding vendor_cmd and vendor_data, val: %d",
7198 __func__, val);
7199 nlmsg_free(msg);
7200 return -1;
7201 }
7202 nla_nest_end(msg, params);
7203
7204 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7205 if (ret) {
7206 sigma_dut_print(dut, DUT_MSG_ERROR,
7207 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
7208 __func__, ret, val);
7209 }
7210 return ret;
7211#else /* NL80211_SUPPORT */
7212 sigma_dut_print(dut, DUT_MSG_ERROR,
7213 "HE OM ctrl cannot be changed without NL80211_SUPPORT defined");
7214 return -1;
7215#endif /* NL80211_SUPPORT */
7216}
7217
7218
Arif Hussain480d5f42019-03-12 14:40:42 -07007219static int sta_set_twt_req_support(struct sigma_dut *dut, const char *intf,
7220 int val)
7221{
7222#ifdef NL80211_SUPPORT
7223 struct nl_msg *msg;
7224 int ret;
7225 struct nlattr *params;
7226 int ifindex;
7227
7228 ifindex = if_nametoindex(intf);
7229 if (ifindex == 0) {
7230 sigma_dut_print(dut, DUT_MSG_ERROR,
7231 "%s: Index for interface %s failed, val:%d",
7232 __func__, intf, val);
7233 return -1;
7234 }
7235
7236 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7237 NL80211_CMD_VENDOR)) ||
7238 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7239 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7240 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7241 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7242 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7243 nla_put_u8(msg,
7244 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TWT_REQ_SUPPORT,
7245 val)) {
7246 sigma_dut_print(dut, DUT_MSG_ERROR,
7247 "%s: err in adding vendor_cmd and vendor_data, val: %d",
7248 __func__, val);
7249 nlmsg_free(msg);
7250 return -1;
7251 }
7252 nla_nest_end(msg, params);
7253
7254 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7255 if (ret) {
7256 sigma_dut_print(dut, DUT_MSG_ERROR,
7257 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
7258 __func__, ret, val);
7259 }
7260 return ret;
7261#else /* NL80211_SUPPORT */
7262 sigma_dut_print(dut, DUT_MSG_ERROR,
7263 "TWT Request cannot be changed without NL80211_SUPPORT defined");
7264 return -1;
7265#endif /* NL80211_SUPPORT */
7266}
7267
7268
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08007269static void sta_reset_default_wcn(struct sigma_dut *dut, const char *intf,
7270 const char *type)
7271{
7272 char buf[60];
7273
7274 if (dut->program == PROGRAM_HE) {
7275 /* resetting phymode to auto in case of HE program */
7276 snprintf(buf, sizeof(buf), "iwpriv %s setphymode 0", intf);
7277 if (system(buf) != 0) {
7278 sigma_dut_print(dut, DUT_MSG_ERROR,
7279 "iwpriv %s setphymode failed", intf);
7280 }
7281
Amarnath Hullur Subramanyam9cecb502018-04-25 13:26:30 -07007282 /* reset the rate to Auto rate */
7283 snprintf(buf, sizeof(buf), "iwpriv %s set_11ax_rate 0xff",
7284 intf);
7285 if (system(buf) != 0) {
7286 sigma_dut_print(dut, DUT_MSG_ERROR,
7287 "iwpriv %s set_11ax_rate 0xff failed",
7288 intf);
7289 }
7290
Kiran Kumar Lokere86cfe3a2018-06-01 11:55:15 -07007291 /* reset the LDPC setting */
7292 snprintf(buf, sizeof(buf), "iwpriv %s ldpc 1", intf);
7293 if (system(buf) != 0) {
7294 sigma_dut_print(dut, DUT_MSG_ERROR,
7295 "iwpriv %s ldpc 1 failed", intf);
7296 }
7297
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08007298 /* reset the power save setting */
7299 snprintf(buf, sizeof(buf), "iwpriv %s setPower 2", intf);
7300 if (system(buf) != 0) {
7301 sigma_dut_print(dut, DUT_MSG_ERROR,
7302 "iwpriv %s setPower 2 failed", intf);
7303 }
7304
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08007305 /* remove all network profiles */
7306 remove_wpa_networks(intf);
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08007307
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08007308 /* Configure ADDBA Req/Rsp buffer size to be 64 */
7309 sta_set_addba_buf_size(dut, intf, 64);
7310
Amarnath Hullur Subramanyam5f32d572018-03-02 00:02:33 -08007311#ifdef NL80211_SUPPORT
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08007312 /* Reset the device HE capabilities to its default supported
7313 * configuration. */
7314 sta_set_he_testbed_def(dut, intf, 0);
7315
Amarnath Hullur Subramanyam5f32d572018-03-02 00:02:33 -08007316 /* Disable noackpolicy for all AC */
7317 if (nlvendor_sta_set_noack(dut, intf, 0, QCA_WLAN_AC_ALL)) {
7318 sigma_dut_print(dut, DUT_MSG_ERROR,
7319 "Disable of noackpolicy for all AC failed");
7320 }
7321#endif /* NL80211_SUPPORT */
7322
Amarnath Hullur Subramanyamb1724a52018-03-07 14:31:46 -08007323 /* Enable WMM by default */
7324 if (wcn_sta_set_wmm(dut, intf, "on")) {
7325 sigma_dut_print(dut, DUT_MSG_ERROR,
7326 "Enable of WMM in sta_reset_default_wcn failed");
7327 }
7328
7329 /* Disable ADDBA_REJECT by default */
7330 if (nlvendor_sta_set_addba_reject(dut, intf, 0)) {
7331 sigma_dut_print(dut, DUT_MSG_ERROR,
7332 "Disable of addba_reject in sta_reset_default_wcn failed");
7333 }
7334
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08007335 /* Enable sending of ADDBA by default */
7336 if (nlvendor_config_send_addba(dut, intf, 1)) {
7337 sigma_dut_print(dut, DUT_MSG_ERROR,
7338 "Enable sending of ADDBA in sta_reset_default_wcn failed");
7339 }
7340
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08007341 /* Enable AMPDU by default */
7342 iwpriv_sta_set_ampdu(dut, intf, 1);
7343
Subhani Shaik8e7a3052018-04-24 14:03:00 -07007344#ifdef NL80211_SUPPORT
7345 if (sta_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_AUTO)) {
7346 sigma_dut_print(dut, DUT_MSG_ERROR,
7347 "Set LTF config to default in sta_reset_default_wcn failed");
7348 }
Arif Hussain9765f7d2018-07-03 08:28:26 -07007349
Kiran Kumar Lokerebad51122018-12-12 19:03:36 -08007350 /* set the beamformee NSTS(maximum number of
7351 * space-time streams) to default DUT config
7352 */
7353 if (sta_set_beamformee_sts(dut, intf, 7)) {
Arif Hussain9765f7d2018-07-03 08:28:26 -07007354 sigma_dut_print(dut, DUT_MSG_ERROR,
7355 "Failed to set BeamformeeSTS");
7356 }
Arif Hussain68d23f52018-07-11 13:39:08 -07007357
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07007358 if (sta_set_mac_padding_duration(
7359 dut, intf,
7360 QCA_WLAN_HE_NO_ADDITIONAL_PROCESS_TIME)) {
Arif Hussain68d23f52018-07-11 13:39:08 -07007361 sigma_dut_print(dut, DUT_MSG_ERROR,
7362 "Failed to set MAC padding duration");
7363 }
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07007364
7365 if (sta_set_mu_edca_override(dut, intf, 0)) {
7366 sigma_dut_print(dut, DUT_MSG_ERROR,
7367 "ErrorCode,Failed to set MU EDCA override disable");
7368 }
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07007369
7370 if (sta_set_om_ctrl_supp(dut, intf, 1)) {
7371 sigma_dut_print(dut, DUT_MSG_ERROR,
7372 "Failed to set OM ctrl supp");
7373 }
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07007374
7375 if (sta_set_tx_su_ppdu_cfg(dut, intf, 1)) {
7376 sigma_dut_print(dut, DUT_MSG_ERROR,
7377 "Failed to set Tx SU PPDU enable");
7378 }
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07007379
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07007380 if (sta_set_action_tx_in_he_tb_ppdu(dut, intf, 0)) {
7381 sigma_dut_print(dut, DUT_MSG_ERROR,
7382 "failed to send TB PPDU Tx cfg");
7383 }
7384
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07007385 if (sta_set_he_om_ctrl_reset(dut, intf)) {
7386 sigma_dut_print(dut, DUT_MSG_ERROR,
7387 "Failed to set OM ctrl reset");
7388 }
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08007389
7390 /* +HTC-HE support default on */
7391 if (sta_set_he_htc_supp(dut, intf, 1)) {
7392 sigma_dut_print(dut, DUT_MSG_ERROR,
7393 "Setting of +HTC-HE support failed");
7394 }
Subhani Shaik8e7a3052018-04-24 14:03:00 -07007395#endif /* NL80211_SUPPORT */
7396
Arif Hussain8d5b27b2018-05-14 14:31:03 -07007397 if (sta_set_tx_beamformee(dut, intf, 1)) {
7398 sigma_dut_print(dut, DUT_MSG_ERROR,
7399 "Set tx beamformee enable by default in sta_reset_default_wcn failed");
7400 }
7401
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08007402 /* Set nss to 1 and MCS 0-7 in case of testbed */
7403 if (type && strcasecmp(type, "Testbed") == 0) {
7404#ifdef NL80211_SUPPORT
7405 int ret;
7406#endif /* NL80211_SUPPORT */
7407
7408 snprintf(buf, sizeof(buf), "iwpriv %s nss 1", intf);
7409 if (system(buf) != 0) {
7410 sigma_dut_print(dut, DUT_MSG_ERROR,
7411 "iwpriv %s nss failed", intf);
7412 }
7413
7414#ifdef NL80211_SUPPORT
7415 ret = sta_set_he_mcs(dut, intf, HE_80_MCS0_7);
7416 if (ret) {
7417 sigma_dut_print(dut, DUT_MSG_ERROR,
7418 "Setting of MCS failed, ret:%d",
7419 ret);
7420 }
7421#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyamc67621d2018-02-04 23:18:01 -08007422
7423 /* Disable STBC as default */
7424 wcn_sta_set_stbc(dut, intf, "0");
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08007425
7426 /* Disable AMSDU as default */
7427 iwpriv_sta_set_amsdu(dut, intf, "0");
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08007428
7429#ifdef NL80211_SUPPORT
7430 /* HE fragmentation default off */
7431 if (sta_set_he_fragmentation(dut, intf,
7432 HE_FRAG_DISABLE)) {
7433 sigma_dut_print(dut, DUT_MSG_ERROR,
7434 "Setting of HE fragmentation failed");
7435 }
Kiran Kumar Lokerebad51122018-12-12 19:03:36 -08007436
7437 /* set the beamformee NSTS(maximum number of
7438 * space-time streams) to default testbed config
7439 */
7440 if (sta_set_beamformee_sts(dut, intf, 3)) {
7441 sigma_dut_print(dut, DUT_MSG_ERROR,
7442 "Failed to set BeamformeeSTS");
7443 }
7444
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08007445 /* +HTC-HE support default off */
7446 if (sta_set_he_htc_supp(dut, intf, 0)) {
7447 sigma_dut_print(dut, DUT_MSG_ERROR,
7448 "Setting of +HTC-HE support failed");
7449 }
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08007450
7451 /* Set device HE capabilities to testbed default
7452 * configuration. */
7453 if (sta_set_he_testbed_def(dut, intf, 1)) {
7454 sigma_dut_print(dut, DUT_MSG_DEBUG,
7455 "Failed to set HE defaults");
7456 }
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08007457
7458 /* Disable VHT support in 2.4 GHz for testbed */
7459 sta_set_2g_vht_supp(dut, intf, 0);
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08007460#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08007461
7462 /* Enable WEP/TKIP with HE capability in testbed */
7463 if (sta_set_heconfig_and_wep_tkip(dut, intf, 1)) {
7464 sigma_dut_print(dut, DUT_MSG_ERROR,
7465 "Enabling HE config with WEP/TKIP failed");
7466 }
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08007467 }
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08007468
7469 /* Defaults in case of DUT */
7470 if (type && strcasecmp(type, "DUT") == 0) {
Arif Hussaind48fcc72018-05-01 18:34:18 -07007471 /* Enable STBC by default */
7472 wcn_sta_set_stbc(dut, intf, "1");
7473
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08007474 /* set nss to 2 */
7475 snprintf(buf, sizeof(buf), "iwpriv %s nss 2", intf);
7476 if (system(buf) != 0) {
7477 sigma_dut_print(dut, DUT_MSG_ERROR,
7478 "iwpriv %s nss 2 failed", intf);
7479 }
Arif Hussainac6c5112018-05-25 17:34:00 -07007480 dut->sta_nss = 2;
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08007481
7482#ifdef NL80211_SUPPORT
Arif Hussainae239842018-05-01 18:20:05 -07007483 /* Set HE_MCS to 0-11 */
7484 if (sta_set_he_mcs(dut, intf, HE_80_MCS0_11)) {
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08007485 sigma_dut_print(dut, DUT_MSG_ERROR,
7486 "Setting of MCS failed");
7487 }
7488#endif /* NL80211_SUPPORT */
7489
7490 /* Disable WEP/TKIP with HE capability in DUT */
7491 if (sta_set_heconfig_and_wep_tkip(dut, intf, 0)) {
7492 sigma_dut_print(dut, DUT_MSG_ERROR,
7493 "Enabling HE config with WEP/TKIP failed");
7494 }
7495 }
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08007496 }
7497}
7498
7499
Jouni Malinenf7222712019-06-13 01:50:21 +03007500static enum sigma_cmd_result cmd_sta_reset_default(struct sigma_dut *dut,
7501 struct sigma_conn *conn,
7502 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007503{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007504 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007505 const char *band = get_param(cmd, "band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007506 const char *type;
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07007507 const char *program = get_param(cmd, "program");
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05307508 const char *dev_role = get_param(cmd, "DevRole");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007509
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07007510 if (!program)
7511 program = get_param(cmd, "prog");
7512 dut->program = sigma_program_to_enum(program);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007513 dut->device_type = STA_unknown;
7514 type = get_param(cmd, "type");
7515 if (type && strcasecmp(type, "Testbed") == 0)
7516 dut->device_type = STA_testbed;
7517 if (type && strcasecmp(type, "DUT") == 0)
7518 dut->device_type = STA_dut;
7519
7520 if (dut->program == PROGRAM_TDLS) {
7521 /* Clear TDLS testing mode */
7522 wpa_command(intf, "SET tdls_disabled 0");
7523 wpa_command(intf, "SET tdls_testing 0");
7524 dut->no_tpk_expiration = 0;
Pradeep Reddy POTTETI8ce2a232016-10-28 12:17:32 +05307525 if (get_driver_type() == DRIVER_WCN) {
7526 /* Enable the WCN driver in TDLS Explicit trigger mode
7527 */
7528 wpa_command(intf, "SET tdls_external_control 0");
7529 wpa_command(intf, "SET tdls_trigger_control 0");
7530 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007531 }
7532
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07007533#ifdef MIRACAST
7534 if (dut->program == PROGRAM_WFD ||
7535 dut->program == PROGRAM_DISPLAYR2)
7536 miracast_sta_reset_default(dut, conn, cmd);
7537#endif /* MIRACAST */
7538
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007539 switch (get_driver_type()) {
7540 case DRIVER_ATHEROS:
7541 sta_reset_default_ath(dut, intf, type);
7542 break;
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08007543 case DRIVER_WCN:
7544 sta_reset_default_wcn(dut, intf, type);
7545 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007546 default:
7547 break;
7548 }
7549
7550#ifdef ANDROID_NAN
7551 if (dut->program == PROGRAM_NAN)
7552 nan_cmd_sta_reset_default(dut, conn, cmd);
7553#endif /* ANDROID_NAN */
7554
Vinay Gannevaram3b9fdd32019-06-14 17:55:44 +05307555 if (dut->program == PROGRAM_LOC &&
7556 lowi_cmd_sta_reset_default(dut, conn, cmd) < 0)
7557 return ERROR_SEND_STATUS;
7558
Jouni Malinenba630452018-06-22 11:49:59 +03007559 if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007560 unlink("SP/wi-fi.org/pps.xml");
7561 if (system("rm -r SP/*") != 0) {
7562 }
7563 unlink("next-client-cert.pem");
7564 unlink("next-client-key.pem");
7565 }
7566
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007567 /* For WPS program of the 60 GHz band the band type needs to be saved */
7568 if (dut->program == PROGRAM_WPS) {
7569 if (band && strcasecmp(band, "60GHz") == 0) {
7570 dut->band = WPS_BAND_60G;
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02007571 /* For 60 GHz enable WPS for WPS TCs */
7572 dut->wps_disable = 0;
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007573 } else {
7574 dut->band = WPS_BAND_NON_60G;
7575 }
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02007576 } else if (dut->program == PROGRAM_60GHZ) {
7577 /* For 60 GHz MAC/PHY TCs WPS must be disabled */
7578 dut->wps_disable = 1;
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007579 }
7580
Alexei Avshalom Lazar157ba062018-12-23 16:15:26 +02007581 if (is_60g_sigma_dut(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007582 const char *dev_role = get_param(cmd, "DevRole");
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02007583 char buf[256];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007584
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02007585 sigma_dut_print(dut, DUT_MSG_INFO,
7586 "WPS 60 GHz program, wps_disable = %d",
7587 dut->wps_disable);
7588
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007589 if (!dev_role) {
7590 send_resp(dut, conn, SIGMA_ERROR,
7591 "errorCode,Missing DevRole argument");
7592 return 0;
7593 }
7594
7595 if (strcasecmp(dev_role, "STA") == 0)
7596 dut->dev_role = DEVROLE_STA;
7597 else if (strcasecmp(dev_role, "PCP") == 0)
7598 dut->dev_role = DEVROLE_PCP;
7599 else {
7600 send_resp(dut, conn, SIGMA_ERROR,
7601 "errorCode,Unknown DevRole");
7602 return 0;
7603 }
7604
7605 if (dut->device_type == STA_unknown) {
7606 sigma_dut_print(dut, DUT_MSG_ERROR,
7607 "Device type is not STA testbed or DUT");
7608 send_resp(dut, conn, SIGMA_ERROR,
7609 "errorCode,Unknown device type");
7610 return 0;
7611 }
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02007612
7613 sigma_dut_print(dut, DUT_MSG_DEBUG,
7614 "Setting msdu_size to MAX: 7912");
7615 snprintf(buf, sizeof(buf), "ifconfig %s mtu 7912",
7616 get_station_ifname());
7617
7618 if (system(buf) != 0) {
7619 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
7620 buf);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007621 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02007622 }
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02007623
7624 if (sta_set_force_mcs(dut, 0, 1)) {
7625 sigma_dut_print(dut, DUT_MSG_ERROR,
7626 "Failed to reset force MCS");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007627 return ERROR_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02007628 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007629 }
7630
7631 wpa_command(intf, "WPS_ER_STOP");
7632 wpa_command(intf, "FLUSH");
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05307633 wpa_command(intf, "ERP_FLUSH");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007634 wpa_command(intf, "SET radio_disabled 0");
7635
Alexei Avshalom Lazar744ae8a2019-01-31 17:26:46 +02007636 dut->wps_forced_version = 0;
7637
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007638 if (dut->wsc_fragment) {
7639 dut->wsc_fragment = 0;
7640 wpa_command(intf, "SET device_name Test client");
7641 wpa_command(intf, "SET manufacturer ");
7642 wpa_command(intf, "SET model_name ");
7643 wpa_command(intf, "SET model_number ");
7644 wpa_command(intf, "SET serial_number ");
7645 }
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02007646 if (is_60g_sigma_dut(dut) && dut->force_rsn_ie) {
7647 dut->force_rsn_ie = FORCE_RSN_IE_NONE;
7648 sta_60g_force_rsn_ie(dut, FORCE_RSN_IE_NONE);
7649 }
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007650
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007651 if (dut->tmp_mac_addr && dut->set_macaddr) {
7652 dut->tmp_mac_addr = 0;
7653 if (system(dut->set_macaddr) != 0) {
7654 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to clear "
7655 "temporary MAC address");
7656 }
7657 }
7658
7659 set_ps(intf, dut, 0);
7660
Jouni Malinenba630452018-06-22 11:49:59 +03007661 if (dut->program == PROGRAM_HS2 || dut->program == PROGRAM_HS2_R2 ||
7662 dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007663 wpa_command(intf, "SET interworking 1");
7664 wpa_command(intf, "SET hs20 1");
7665 }
7666
Deepak Dhamdhere0fe0e452017-12-18 14:52:09 -08007667 if (dut->program == PROGRAM_HS2_R2 ||
Jouni Malinenba630452018-06-22 11:49:59 +03007668 dut->program == PROGRAM_HS2_R3 ||
Deepak Dhamdhere0fe0e452017-12-18 14:52:09 -08007669 dut->program == PROGRAM_OCE) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007670 wpa_command(intf, "SET pmf 1");
7671 } else {
7672 wpa_command(intf, "SET pmf 0");
7673 }
7674
7675 hs2_clear_credentials(intf);
7676 wpa_command(intf, "SET hessid 00:00:00:00:00:00");
7677 wpa_command(intf, "SET access_network_type 15");
7678
7679 static_ip_file(0, NULL, NULL, NULL);
7680 kill_dhcp_client(dut, intf);
7681 clear_ip_addr(dut, intf);
7682
7683 dut->er_oper_performed = 0;
7684 dut->er_oper_bssid[0] = '\0';
7685
priyadharshini gowthamanad6cbba2016-10-04 10:39:58 -07007686 if (dut->program == PROGRAM_LOC) {
7687 /* Disable Interworking by default */
7688 wpa_command(get_station_ifname(), "SET interworking 0");
7689 }
7690
Ashwini Patil00402582017-04-13 12:29:39 +05307691 if (dut->program == PROGRAM_MBO) {
7692 free(dut->non_pref_ch_list);
7693 dut->non_pref_ch_list = NULL;
Ashwini Patil5acd7382017-04-13 15:55:04 +05307694 free(dut->btm_query_cand_list);
7695 dut->btm_query_cand_list = NULL;
Ashwini Patilc63161e2017-04-13 16:30:23 +05307696 wpa_command(intf, "SET reject_btm_req_reason 0");
Ashwini Patila75de5a2017-04-13 16:35:05 +05307697 wpa_command(intf, "SET ignore_assoc_disallow 0");
Ashwini Patild174f2c2017-04-13 16:49:46 +05307698 wpa_command(intf, "SET gas_address3 0");
Ashwini Patil9183fdb2017-04-13 16:58:25 +05307699 wpa_command(intf, "SET roaming 1");
Ankita Bajaj1d974552018-09-18 16:56:44 +05307700 wpa_command(intf, "SET interworking 1");
Ashwini Patil00402582017-04-13 12:29:39 +05307701 }
7702
Jouni Malinen3c367e82017-06-23 17:01:47 +03007703 free(dut->rsne_override);
7704 dut->rsne_override = NULL;
7705
Jouni Malinen68143132017-09-02 02:34:08 +03007706 free(dut->sae_commit_override);
7707 dut->sae_commit_override = NULL;
7708
Jouni Malinen134fe3c2019-06-12 04:16:49 +03007709 dut->sta_associate_wait_connect = 0;
7710 dut->server_cert_hash[0] = '\0';
7711 dut->sta_tod_policy = 0;
7712
Jouni Malinend86e5822017-08-29 03:55:32 +03007713 dut->dpp_conf_id = -1;
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02007714 free(dut->dpp_peer_uri);
7715 dut->dpp_peer_uri = NULL;
Jouni Malinen63d50412017-11-24 11:55:38 +02007716 dut->dpp_local_bootstrap = -1;
Jouni Malinen5011fb52017-12-05 21:00:15 +02007717 wpa_command(intf, "SET dpp_config_processing 2");
Jouni Malinend86e5822017-08-29 03:55:32 +03007718
Jouni Malinenfac9cad2017-10-10 18:35:55 +03007719 wpa_command(intf, "VENDOR_ELEM_REMOVE 13 *");
7720
vamsi krishnaa2799492017-12-05 14:28:01 +05307721 if (dut->program == PROGRAM_OCE) {
Ankita Bajaja2cb5672017-10-25 16:08:28 +05307722 wpa_command(intf, "SET oce 1");
vamsi krishnaa2799492017-12-05 14:28:01 +05307723 wpa_command(intf, "SET disable_fils 0");
Ankita Bajaj1bde7942018-01-09 19:15:01 +05307724 wpa_command(intf, "FILS_HLP_REQ_FLUSH");
7725 dut->fils_hlp = 0;
7726#ifdef ANDROID
7727 hlp_thread_cleanup(dut);
7728#endif /* ANDROID */
vamsi krishnaa2799492017-12-05 14:28:01 +05307729 }
Ankita Bajaja2cb5672017-10-25 16:08:28 +05307730
Jouni Malinen8179fee2019-03-28 03:19:47 +02007731 dut->akm_values = 0;
7732
Sunil Dutt076081f2018-02-05 19:45:50 +05307733#ifdef NL80211_SUPPORT
Sunil Dutt44595082018-02-12 19:41:45 +05307734 if (get_driver_type() == DRIVER_WCN &&
7735 dut->config_rsnie == 1) {
7736 dut->config_rsnie = 0;
7737 sta_config_rsnie(dut, 0);
Sunil Dutt076081f2018-02-05 19:45:50 +05307738 }
7739#endif /* NL80211_SUPPORT */
7740
Sunil Duttfebf8a82018-02-09 18:50:13 +05307741 if (dev_role && strcasecmp(dev_role, "STA-CFON") == 0) {
7742 dut->dev_role = DEVROLE_STA_CFON;
7743 return sta_cfon_reset_default(dut, conn, cmd);
7744 }
7745
Jouni Malinen439352d2018-09-13 03:42:23 +03007746 wpa_command(intf, "SET setband AUTO");
7747
Sunil Duttfebf8a82018-02-09 18:50:13 +05307748 if (dut->program != PROGRAM_VHT)
7749 return cmd_sta_p2p_reset(dut, conn, cmd);
7750
Priyadharshini Gowthamana7dfd492015-11-09 14:34:08 -08007751 return 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007752}
7753
7754
Jouni Malinenf7222712019-06-13 01:50:21 +03007755static enum sigma_cmd_result cmd_sta_get_events(struct sigma_dut *dut,
7756 struct sigma_conn *conn,
7757 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007758{
7759 const char *program = get_param(cmd, "Program");
7760
7761 if (program == NULL)
7762 return -1;
7763#ifdef ANDROID_NAN
7764 if (strcasecmp(program, "NAN") == 0)
7765 return nan_cmd_sta_get_events(dut, conn, cmd);
7766#endif /* ANDROID_NAN */
7767 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
7768 return 0;
7769}
7770
7771
Jouni Malinen82905202018-04-29 17:20:10 +03007772static int sta_exec_action_url(struct sigma_dut *dut, struct sigma_conn *conn,
7773 struct sigma_cmd *cmd)
7774{
7775 const char *url = get_param(cmd, "url");
7776 const char *method = get_param(cmd, "method");
7777 pid_t pid;
7778 int status;
7779
7780 if (!url || !method)
7781 return -1;
7782
7783 /* TODO: Add support for method,post */
7784 if (strcasecmp(method, "get") != 0) {
7785 send_resp(dut, conn, SIGMA_ERROR,
7786 "ErrorCode,Unsupported method");
7787 return 0;
7788 }
7789
7790 pid = fork();
7791 if (pid < 0) {
7792 perror("fork");
7793 return -1;
7794 }
7795
7796 if (pid == 0) {
7797 char * argv[5] = { "wget", "-O", "/dev/null",
7798 (char *) url, NULL };
7799
7800 execv("/usr/bin/wget", argv);
7801 perror("execv");
7802 exit(0);
7803 return -1;
7804 }
7805
7806 if (waitpid(pid, &status, 0) < 0) {
7807 perror("waitpid");
7808 return -1;
7809 }
7810
7811 if (WIFEXITED(status)) {
7812 const char *errmsg;
7813
7814 if (WEXITSTATUS(status) == 0)
7815 return 1;
7816 sigma_dut_print(dut, DUT_MSG_INFO, "wget exit status %d",
7817 WEXITSTATUS(status));
7818 switch (WEXITSTATUS(status)) {
7819 case 4:
7820 errmsg = "errmsg,Network failure";
7821 break;
7822 case 8:
7823 errmsg = "errmsg,Server issued an error response";
7824 break;
7825 default:
7826 errmsg = "errmsg,Unknown failure from wget";
7827 break;
7828 }
7829 send_resp(dut, conn, SIGMA_ERROR, errmsg);
7830 return 0;
7831 }
7832
7833 send_resp(dut, conn, SIGMA_ERROR, "errmsg,Unknown failure");
7834 return 0;
7835}
7836
7837
Jouni Malinenf7222712019-06-13 01:50:21 +03007838static enum sigma_cmd_result cmd_sta_exec_action(struct sigma_dut *dut,
7839 struct sigma_conn *conn,
7840 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007841{
7842 const char *program = get_param(cmd, "Prog");
7843
Jouni Malinen82905202018-04-29 17:20:10 +03007844 if (program && !get_param(cmd, "interface"))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007845 return -1;
7846#ifdef ANDROID_NAN
Jouni Malinen82905202018-04-29 17:20:10 +03007847 if (program && strcasecmp(program, "NAN") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007848 return nan_cmd_sta_exec_action(dut, conn, cmd);
7849#endif /* ANDROID_NAN */
Jouni Malinen82905202018-04-29 17:20:10 +03007850
7851 if (program && strcasecmp(program, "Loc") == 0)
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07007852 return loc_cmd_sta_exec_action(dut, conn, cmd);
Jouni Malinen82905202018-04-29 17:20:10 +03007853
7854 if (get_param(cmd, "url"))
7855 return sta_exec_action_url(dut, conn, cmd);
7856
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007857 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
7858 return 0;
7859}
7860
7861
Jouni Malinenf7222712019-06-13 01:50:21 +03007862static enum sigma_cmd_result cmd_sta_set_11n(struct sigma_dut *dut,
7863 struct sigma_conn *conn,
7864 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007865{
7866 const char *intf = get_param(cmd, "Interface");
7867 const char *val, *mcs32, *rate;
7868
7869 val = get_param(cmd, "GREENFIELD");
7870 if (val) {
7871 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
7872 /* Enable GD */
7873 send_resp(dut, conn, SIGMA_ERROR,
7874 "ErrorCode,GF not supported");
7875 return 0;
7876 }
7877 }
7878
7879 val = get_param(cmd, "SGI20");
7880 if (val) {
7881 switch (get_driver_type()) {
7882 case DRIVER_ATHEROS:
7883 ath_sta_set_sgi(dut, intf, val);
7884 break;
7885 default:
7886 send_resp(dut, conn, SIGMA_ERROR,
7887 "ErrorCode,SGI20 not supported");
7888 return 0;
7889 }
7890 }
7891
7892 mcs32 = get_param(cmd, "MCS32"); /* HT Duplicate Mode Enable/Disable */
7893 rate = get_param(cmd, "MCS_FIXEDRATE"); /* Fixed MCS rate (0..31) */
7894 if (mcs32 && rate) {
7895 /* TODO */
7896 send_resp(dut, conn, SIGMA_ERROR,
7897 "ErrorCode,MCS32,MCS_FIXEDRATE not supported");
7898 return 0;
7899 } else if (mcs32 && !rate) {
7900 /* TODO */
7901 send_resp(dut, conn, SIGMA_ERROR,
7902 "ErrorCode,MCS32 not supported");
7903 return 0;
7904 } else if (!mcs32 && rate) {
7905 switch (get_driver_type()) {
7906 case DRIVER_ATHEROS:
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -07007907 novap_reset(dut, intf, 1);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007908 ath_sta_set_11nrates(dut, intf, rate);
7909 break;
7910 default:
7911 send_resp(dut, conn, SIGMA_ERROR,
7912 "ErrorCode,MCS32_FIXEDRATE not supported");
7913 return 0;
7914 }
7915 }
7916
7917 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
7918}
7919
7920
Arif Hussain7b47d2d2018-05-09 10:44:02 -07007921static void cmd_set_max_he_mcs(struct sigma_dut *dut, const char *intf,
7922 int mcs_config)
7923{
7924#ifdef NL80211_SUPPORT
7925 int ret;
7926
7927 switch (mcs_config) {
7928 case HE_80_MCS0_7:
7929 case HE_80_MCS0_9:
7930 case HE_80_MCS0_11:
7931 ret = sta_set_he_mcs(dut, intf, mcs_config);
7932 if (ret) {
7933 sigma_dut_print(dut, DUT_MSG_ERROR,
7934 "cmd_set_max_he_mcs: Setting of MCS:%d failed, ret:%d",
7935 mcs_config, ret);
7936 }
7937 break;
7938 default:
7939 sigma_dut_print(dut, DUT_MSG_ERROR,
7940 "cmd_set_max_he_mcs: Invalid mcs %d",
7941 mcs_config);
7942 break;
7943 }
7944#else /* NL80211_SUPPORT */
7945 sigma_dut_print(dut, DUT_MSG_ERROR,
7946 "max HE MCS cannot be changed without NL80211_SUPPORT defined");
7947#endif /* NL80211_SUPPORT */
7948}
7949
7950
Arif Hussain480d5f42019-03-12 14:40:42 -07007951static int sta_twt_request(struct sigma_dut *dut, struct sigma_conn *conn,
7952 struct sigma_cmd *cmd)
7953{
7954#ifdef NL80211_SUPPORT
7955 struct nlattr *params;
7956 struct nlattr *attr;
7957 struct nlattr *attr1;
7958 struct nl_msg *msg;
7959 int ifindex, ret;
7960 const char *val;
7961 const char *intf = get_param(cmd, "Interface");
7962 int wake_interval_exp = 10, nominal_min_wake_dur = 255,
7963 wake_interval_mantissa = 512;
7964 int flow_type = 0, twt_trigger = 0, target_wake_time = 0,
7965 protection = 0;
7966
7967 ifindex = if_nametoindex(intf);
7968 if (ifindex == 0) {
7969 sigma_dut_print(dut, DUT_MSG_ERROR,
7970 "%s: Index for interface %s failed",
7971 __func__, intf);
7972 return -1;
7973 }
7974
7975 val = get_param(cmd, "FlowType");
7976 if (val) {
7977 flow_type = atoi(val);
7978 if (flow_type != 0 && flow_type != 1) {
7979 sigma_dut_print(dut, DUT_MSG_ERROR,
7980 "TWT: Invalid FlowType %d", flow_type);
7981 return -1;
7982 }
7983 }
7984
7985 val = get_param(cmd, "TWT_Trigger");
7986 if (val) {
7987 twt_trigger = atoi(val);
7988 if (twt_trigger != 0 && twt_trigger != 1) {
7989 sigma_dut_print(dut, DUT_MSG_ERROR,
7990 "TWT: Invalid TWT_Trigger %d",
7991 twt_trigger);
7992 return -1;
7993 }
7994 }
7995
7996 val = get_param(cmd, "Protection");
7997 if (val) {
7998 protection = atoi(val);
7999 if (protection != 0 && protection != 1) {
8000 sigma_dut_print(dut, DUT_MSG_ERROR,
8001 "TWT: Invalid Protection %d",
8002 protection);
8003 return -1;
8004 }
8005 }
8006
8007 val = get_param(cmd, "TargetWakeTime");
8008 if (val)
8009 target_wake_time = atoi(val);
8010
8011 val = get_param(cmd, "WakeIntervalMantissa");
8012 if (val)
8013 wake_interval_mantissa = atoi(val);
8014
8015 val = get_param(cmd, "WakeIntervalExp");
8016 if (val)
8017 wake_interval_exp = atoi(val);
8018
8019 val = get_param(cmd, "NominalMinWakeDur");
8020 if (val)
8021 nominal_min_wake_dur = atoi(val);
8022
8023 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8024 NL80211_CMD_VENDOR)) ||
8025 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
8026 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
8027 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
8028 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
8029 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8030 !(params = nla_nest_start(
8031 msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_SETUP)) ||
8032 !(attr1 = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8033 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_EXP,
8034 wake_interval_exp) ||
8035 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST, 0) ||
8036 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_REQ_TYPE, 1) ||
8037 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TRIGGER,
8038 twt_trigger) ||
8039 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE,
8040 flow_type) ||
8041 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_PROTECTION,
8042 protection) ||
8043 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME,
8044 target_wake_time) ||
8045 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_DURATION,
8046 nominal_min_wake_dur) ||
8047 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_MANTISSA,
8048 wake_interval_mantissa)) {
8049 sigma_dut_print(dut, DUT_MSG_ERROR,
8050 "%s: err in adding vendor_cmd and vendor_data",
8051 __func__);
8052 nlmsg_free(msg);
8053 return -1;
8054 }
8055 nla_nest_end(msg, attr1);
8056 nla_nest_end(msg, params);
8057 nla_nest_end(msg, attr);
8058
8059 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
8060 if (ret) {
8061 sigma_dut_print(dut, DUT_MSG_ERROR,
8062 "%s: err in send_and_recv_msgs, ret=%d",
8063 __func__, ret);
8064 }
8065
8066 return ret;
8067#else /* NL80211_SUPPORT */
8068 sigma_dut_print(dut, DUT_MSG_ERROR,
8069 "TWT request cannot be done without NL80211_SUPPORT defined");
8070 return -1;
8071#endif /* NL80211_SUPPORT */
8072}
8073
8074
8075static int sta_twt_teardown(struct sigma_dut *dut, struct sigma_conn *conn,
8076 struct sigma_cmd *cmd)
8077{
8078 #ifdef NL80211_SUPPORT
8079 struct nlattr *params;
8080 struct nlattr *attr;
8081 struct nlattr *attr1;
8082 int ifindex, ret;
8083 struct nl_msg *msg;
8084 const char *intf = get_param(cmd, "Interface");
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
8094 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8095 NL80211_CMD_VENDOR)) ||
8096 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
8097 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
8098 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
8099 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
8100 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8101 !(params = nla_nest_start(
8102 msg,
8103 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_TERMINATE)) ||
8104 !(attr1 = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8105 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE, 0)) {
8106 sigma_dut_print(dut, DUT_MSG_ERROR,
8107 "%s: err in adding vendor_cmd and vendor_data",
8108 __func__);
8109 nlmsg_free(msg);
8110 return -1;
8111 }
8112 nla_nest_end(msg, attr1);
8113 nla_nest_end(msg, params);
8114 nla_nest_end(msg, attr);
8115
8116 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
8117 if (ret) {
8118 sigma_dut_print(dut, DUT_MSG_ERROR,
8119 "%s: err in send_and_recv_msgs, ret=%d",
8120 __func__, ret);
8121 }
8122
8123 return ret;
8124#else /* NL80211_SUPPORT */
8125 sigma_dut_print(dut, DUT_MSG_ERROR,
8126 "TWT teardown cannot be done without NL80211_SUPPORT defined");
8127 return -1;
8128#endif /* NL80211_SUPPORT */
8129}
8130
8131
Kiran Kumar Lokere50eb2cd2018-12-18 18:31:28 -08008132static int sta_transmit_omi(struct sigma_dut *dut, struct sigma_conn *conn,
8133 struct sigma_cmd *cmd)
8134{
8135#ifdef NL80211_SUPPORT
8136 struct nlattr *params;
8137 struct nlattr *attr;
8138 struct nlattr *attr1;
8139 struct nl_msg *msg;
8140 int ifindex, ret;
8141 const char *val;
8142 const char *intf = get_param(cmd, "Interface");
8143 uint8_t rx_nss = 0xFF, ch_bw = 0xFF, tx_nsts = 0xFF, ulmu_dis = 0,
8144 ulmu_data_dis = 0;
8145
8146 ifindex = if_nametoindex(intf);
8147 if (ifindex == 0) {
8148 sigma_dut_print(dut, DUT_MSG_ERROR,
8149 "%s: Index for interface %s failed",
8150 __func__, intf);
8151 return -1;
8152 }
8153 val = get_param(cmd, "OMCtrl_RxNSS");
8154 if (val)
8155 rx_nss = atoi(val);
8156
8157 val = get_param(cmd, "OMCtrl_ChnlWidth");
8158 if (val)
8159 ch_bw = atoi(val);
8160
8161 val = get_param(cmd, "OMCtrl_ULMUDisable");
8162 if (val)
8163 ulmu_dis = atoi(val);
8164
8165 val = get_param(cmd, "OMCtrl_TxNSTS");
8166 if (val)
8167 tx_nsts = atoi(val);
8168
8169 val = get_param(cmd, "OMCtrl_ULMUDataDisable");
8170 if (val)
8171 ulmu_data_dis = atoi(val);
8172
8173 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8174 NL80211_CMD_VENDOR)) ||
8175 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
8176 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
8177 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
8178 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
8179 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8180 !(params = nla_nest_start(
8181 msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OMI_TX)) ||
8182 !(attr1 = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8183 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_RX_NSS, rx_nss) ||
8184 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_CH_BW, ch_bw) ||
8185 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_TX_NSTS, tx_nsts) ||
8186 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DATA_DISABLE,
8187 ulmu_data_dis) ||
8188 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DISABLE,
8189 ulmu_dis)) {
8190 sigma_dut_print(dut, DUT_MSG_ERROR,
8191 "%s: err in adding vendor_cmd and vendor_data",
8192 __func__);
8193 nlmsg_free(msg);
8194 return -1;
8195 }
8196 nla_nest_end(msg, attr1);
8197 nla_nest_end(msg, params);
8198 nla_nest_end(msg, attr);
8199
8200 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
8201 if (ret) {
8202 sigma_dut_print(dut, DUT_MSG_ERROR,
8203 "%s: err in send_and_recv_msgs, ret=%d",
8204 __func__, ret);
8205 }
8206
8207 return ret;
8208#else /* NL80211_SUPPORT */
8209 sigma_dut_print(dut, DUT_MSG_ERROR,
8210 "OMI TX cannot be processed without NL80211_SUPPORT defined");
8211 return -1;
8212#endif /* NL80211_SUPPORT */
8213}
8214
8215
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008216static int cmd_sta_set_wireless_vht(struct sigma_dut *dut,
8217 struct sigma_conn *conn,
8218 struct sigma_cmd *cmd)
8219{
8220 const char *intf = get_param(cmd, "Interface");
8221 const char *val;
Arif Hussaina37e9552018-06-20 17:05:59 -07008222 const char *program;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008223 int tkip = -1;
8224 int wep = -1;
8225
Arif Hussaina37e9552018-06-20 17:05:59 -07008226 program = get_param(cmd, "Program");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008227 val = get_param(cmd, "SGI80");
8228 if (val) {
8229 int sgi80;
8230
8231 sgi80 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008232 run_iwpriv(dut, intf, "shortgi %d", sgi80);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008233 }
8234
8235 val = get_param(cmd, "TxBF");
8236 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07008237 switch (get_driver_type()) {
8238 case DRIVER_WCN:
8239 if (sta_set_tx_beamformee(dut, intf, 1)) {
8240 send_resp(dut, conn, SIGMA_ERROR,
8241 "ErrorCode,Failed to set TX beamformee enable");
8242 return 0;
8243 }
8244 break;
8245 case DRIVER_ATHEROS:
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008246 if (run_iwpriv(dut, intf, "vhtsubfee 1") < 0) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07008247 send_resp(dut, conn, SIGMA_ERROR,
8248 "ErrorCode,Setting vhtsubfee failed");
8249 return 0;
8250 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008251 if (run_iwpriv(dut, intf, "vhtsubfer 1") < 0) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07008252 send_resp(dut, conn, SIGMA_ERROR,
8253 "ErrorCode,Setting vhtsubfer failed");
8254 return 0;
8255 }
8256 break;
8257 default:
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008258 sigma_dut_print(dut, DUT_MSG_ERROR,
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07008259 "Unsupported driver type");
8260 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008261 }
8262 }
8263
8264 val = get_param(cmd, "MU_TxBF");
8265 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
8266 switch (get_driver_type()) {
8267 case DRIVER_ATHEROS:
8268 ath_sta_set_txsp_stream(dut, intf, "1SS");
8269 ath_sta_set_rxsp_stream(dut, intf, "1SS");
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008270 run_iwpriv(dut, intf, "vhtmubfee 1");
8271 run_iwpriv(dut, intf, "vhtmubfer 1");
Sunil Duttae9e5d12018-06-29 11:50:47 +05308272 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008273 case DRIVER_WCN:
8274 if (wcn_sta_set_sp_stream(dut, intf, "1SS") < 0) {
8275 send_resp(dut, conn, SIGMA_ERROR,
8276 "ErrorCode,Failed to set RX/TXSP_STREAM");
8277 return 0;
8278 }
Sunil Duttae9e5d12018-06-29 11:50:47 +05308279 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008280 default:
8281 sigma_dut_print(dut, DUT_MSG_ERROR,
8282 "Setting SP_STREAM not supported");
8283 break;
8284 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008285 }
8286
8287 val = get_param(cmd, "LDPC");
8288 if (val) {
8289 int ldpc;
8290
8291 ldpc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008292 run_iwpriv(dut, intf, "ldpc %d", ldpc);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008293 }
8294
Amarnath Hullur Subramanyam7bae60e2018-01-31 03:46:50 -08008295 val = get_param(cmd, "BCC");
8296 if (val) {
8297 int bcc;
8298
8299 bcc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
8300 /* use LDPC iwpriv itself to set bcc coding, bcc coding
8301 * is mutually exclusive to bcc */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008302 run_iwpriv(dut, intf, "ldpc %d", !bcc);
Amarnath Hullur Subramanyam7bae60e2018-01-31 03:46:50 -08008303 }
8304
Arif Hussain7b47d2d2018-05-09 10:44:02 -07008305 val = get_param(cmd, "MaxHE-MCS_1SS_RxMapLTE80");
8306 if (val && dut->sta_nss == 1)
8307 cmd_set_max_he_mcs(dut, intf, atoi(val));
8308
8309 val = get_param(cmd, "MaxHE-MCS_2SS_RxMapLTE80");
8310 if (val && dut->sta_nss == 2)
8311 cmd_set_max_he_mcs(dut, intf, atoi(val));
8312
Arif Hussainac6c5112018-05-25 17:34:00 -07008313 val = get_param(cmd, "MCS_FixedRate");
8314 if (val) {
8315#ifdef NL80211_SUPPORT
8316 int mcs, ratecode = 0;
8317 enum he_mcs_config mcs_config;
8318 int ret;
Jouni Malinenb9b671d2019-04-26 13:23:17 +03008319 char buf[60];
Arif Hussainac6c5112018-05-25 17:34:00 -07008320
8321 ratecode = (0x07 & dut->sta_nss) << 5;
8322 mcs = atoi(val);
8323 /* Add the MCS to the ratecode */
8324 if (mcs >= 0 && mcs <= 11) {
8325 ratecode += mcs;
8326 if (dut->device_type == STA_testbed &&
8327 mcs > 7 && mcs <= 11) {
8328 if (mcs <= 9)
8329 mcs_config = HE_80_MCS0_9;
8330 else
8331 mcs_config = HE_80_MCS0_11;
8332 ret = sta_set_he_mcs(dut, intf, mcs_config);
8333 if (ret) {
8334 sigma_dut_print(dut, DUT_MSG_ERROR,
8335 "MCS_FixedRate: mcs setting failed, mcs:%d, mcs_config %d, ret:%d",
8336 mcs, mcs_config, ret);
8337 }
8338 }
8339 snprintf(buf, sizeof(buf),
8340 "iwpriv %s set_11ax_rate 0x%03x",
8341 intf, ratecode);
8342 if (system(buf) != 0) {
8343 sigma_dut_print(dut, DUT_MSG_ERROR,
8344 "MCS_FixedRate: iwpriv setting of 11ax rates 0x%03x failed",
8345 ratecode);
8346 }
8347 } else {
8348 sigma_dut_print(dut, DUT_MSG_ERROR,
8349 "MCS_FixedRate: HE MCS %d not supported",
8350 mcs);
8351 }
8352#else /* NL80211_SUPPORT */
8353 sigma_dut_print(dut, DUT_MSG_ERROR,
8354 "MCS_FixedRate cannot be changed without NL80211_SUPPORT defined");
8355#endif /* NL80211_SUPPORT */
8356 }
8357
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008358 val = get_param(cmd, "opt_md_notif_ie");
8359 if (val) {
8360 char *result = NULL;
8361 char delim[] = ";";
8362 char token[30];
8363 int value, config_val = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308364 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008365
Peng Xub8fc5cc2017-05-10 17:27:28 -07008366 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308367 result = strtok_r(token, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008368
8369 /* Extract the NSS information */
8370 if (result) {
8371 value = atoi(result);
8372 switch (value) {
8373 case 1:
8374 config_val = 1;
8375 break;
8376 case 2:
8377 config_val = 3;
8378 break;
8379 case 3:
8380 config_val = 7;
8381 break;
8382 case 4:
8383 config_val = 15;
8384 break;
8385 default:
8386 config_val = 3;
8387 break;
8388 }
8389
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008390 run_iwpriv(dut, intf, "rxchainmask %d", config_val);
8391 run_iwpriv(dut, intf, "txchainmask %d", config_val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008392
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008393 }
8394
8395 /* Extract the channel width information */
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308396 result = strtok_r(NULL, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008397 if (result) {
8398 value = atoi(result);
8399 switch (value) {
8400 case 20:
8401 config_val = 0;
8402 break;
8403 case 40:
8404 config_val = 1;
8405 break;
8406 case 80:
8407 config_val = 2;
8408 break;
8409 case 160:
8410 config_val = 3;
8411 break;
8412 default:
8413 config_val = 2;
8414 break;
8415 }
8416
8417 dut->chwidth = config_val;
8418
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008419 run_iwpriv(dut, intf, "chwidth %d", config_val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008420 }
8421
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008422 run_iwpriv(dut, intf, "opmode_notify 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008423 }
8424
8425 val = get_param(cmd, "nss_mcs_cap");
8426 if (val) {
8427 int nss, mcs;
8428 char token[20];
8429 char *result = NULL;
8430 unsigned int vht_mcsmap = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308431 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008432
Peng Xub8fc5cc2017-05-10 17:27:28 -07008433 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308434 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05308435 if (!result) {
8436 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07008437 "NSS not specified");
8438 send_resp(dut, conn, SIGMA_ERROR,
8439 "errorCode,NSS not specified");
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05308440 return 0;
8441 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008442 nss = atoi(result);
8443
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008444 run_iwpriv(dut, intf, "nss %d", nss);
Arif Hussainac6c5112018-05-25 17:34:00 -07008445 dut->sta_nss = nss;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008446
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308447 result = strtok_r(NULL, ";", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008448 if (result == NULL) {
8449 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07008450 "MCS not specified");
8451 send_resp(dut, conn, SIGMA_ERROR,
8452 "errorCode,MCS not specified");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008453 return 0;
8454 }
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308455 result = strtok_r(result, "-", &saveptr);
8456 result = strtok_r(NULL, "-", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05308457 if (!result) {
8458 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07008459 "MCS not specified");
8460 send_resp(dut, conn, SIGMA_ERROR,
8461 "errorCode,MCS not specified");
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05308462 return 0;
8463 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008464 mcs = atoi(result);
8465
Arif Hussaina37e9552018-06-20 17:05:59 -07008466 if (program && strcasecmp(program, "HE") == 0) {
8467#ifdef NL80211_SUPPORT
8468 enum he_mcs_config mcs_config;
8469 int ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008470
Arif Hussaina37e9552018-06-20 17:05:59 -07008471 if (mcs >= 0 && mcs <= 7) {
8472 mcs_config = HE_80_MCS0_7;
8473 } else if (mcs > 7 && mcs <= 9) {
8474 mcs_config = HE_80_MCS0_9;
8475 } else if (mcs > 9 && mcs <= 11) {
8476 mcs_config = HE_80_MCS0_11;
8477 } else {
8478 sigma_dut_print(dut, DUT_MSG_ERROR,
8479 "nss_mcs_cap: HE: Invalid mcs: %d",
8480 mcs);
8481 send_resp(dut, conn, SIGMA_ERROR,
8482 "errorCode,Invalid MCS");
8483 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008484 }
Arif Hussaina37e9552018-06-20 17:05:59 -07008485
8486 ret = sta_set_he_mcs(dut, intf, mcs_config);
8487 if (ret) {
8488 sigma_dut_print(dut, DUT_MSG_ERROR,
8489 "nss_mcs_cap: HE: Setting of MCS failed, mcs_config: %d, ret: %d",
8490 mcs_config, ret);
8491 send_resp(dut, conn, SIGMA_ERROR,
8492 "errorCode,Failed to set MCS");
8493 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008494 }
Arif Hussaina37e9552018-06-20 17:05:59 -07008495#else /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008496 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07008497 "nss_mcs_cap: HE: MCS cannot be changed without NL80211_SUPPORT defined");
8498#endif /* NL80211_SUPPORT */
8499 } else {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008500 run_iwpriv(dut, intf, "vhtmcs %d", mcs);
Arif Hussaina37e9552018-06-20 17:05:59 -07008501
8502 switch (nss) {
8503 case 1:
8504 switch (mcs) {
8505 case 7:
8506 vht_mcsmap = 0xfffc;
8507 break;
8508 case 8:
8509 vht_mcsmap = 0xfffd;
8510 break;
8511 case 9:
8512 vht_mcsmap = 0xfffe;
8513 break;
8514 default:
8515 vht_mcsmap = 0xfffe;
8516 break;
8517 }
8518 break;
8519 case 2:
8520 switch (mcs) {
8521 case 7:
8522 vht_mcsmap = 0xfff0;
8523 break;
8524 case 8:
8525 vht_mcsmap = 0xfff5;
8526 break;
8527 case 9:
8528 vht_mcsmap = 0xfffa;
8529 break;
8530 default:
8531 vht_mcsmap = 0xfffa;
8532 break;
8533 }
8534 break;
8535 case 3:
8536 switch (mcs) {
8537 case 7:
8538 vht_mcsmap = 0xffc0;
8539 break;
8540 case 8:
8541 vht_mcsmap = 0xffd5;
8542 break;
8543 case 9:
8544 vht_mcsmap = 0xffea;
8545 break;
8546 default:
8547 vht_mcsmap = 0xffea;
8548 break;
8549 }
8550 break;
8551 default:
8552 vht_mcsmap = 0xffea;
8553 break;
8554 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008555 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008556 }
8557 }
8558
8559 /* UNSUPPORTED: val = get_param(cmd, "Tx_lgi_rate"); */
8560
8561 val = get_param(cmd, "Vht_tkip");
8562 if (val)
8563 tkip = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
8564
8565 val = get_param(cmd, "Vht_wep");
8566 if (val)
8567 wep = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
8568
8569 if (tkip != -1 || wep != -1) {
8570 if ((tkip == 1 && wep != 0) || (wep == 1 && tkip != 0)) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008571 run_iwpriv(dut, intf, "htweptkip 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008572 } else if ((tkip == 0 && wep != 1) || (wep == 0 && tkip != 1)) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008573 run_iwpriv(dut, intf, "htweptkip 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008574 } else {
8575 sigma_dut_print(dut, DUT_MSG_ERROR,
8576 "ErrorCode,mixed mode of VHT TKIP/WEP not supported");
8577 return 0;
8578 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008579 }
8580
Arif Hussain55f00da2018-07-03 08:28:26 -07008581 val = get_param(cmd, "txBandwidth");
8582 if (val) {
8583 switch (get_driver_type()) {
8584 case DRIVER_WCN:
8585 if (wcn_sta_set_width(dut, intf, val) < 0) {
8586 send_resp(dut, conn, SIGMA_ERROR,
8587 "ErrorCode,Failed to set txBandwidth");
8588 return 0;
8589 }
8590 break;
8591 case DRIVER_ATHEROS:
8592 if (ath_set_width(dut, conn, intf, val) < 0) {
8593 send_resp(dut, conn, SIGMA_ERROR,
8594 "ErrorCode,Failed to set txBandwidth");
8595 return 0;
8596 }
8597 break;
8598 default:
8599 sigma_dut_print(dut, DUT_MSG_ERROR,
8600 "Setting txBandwidth not supported");
8601 break;
8602 }
8603 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008604
Arif Hussain9765f7d2018-07-03 08:28:26 -07008605 val = get_param(cmd, "BeamformeeSTS");
8606 if (val) {
Kiran Kumar Lokerebc89d432018-07-10 12:20:13 -07008607 if (sta_set_tx_beamformee(dut, intf, 1)) {
8608 send_resp(dut, conn, SIGMA_ERROR,
8609 "ErrorCode,Failed to set TX beamformee enable");
8610 return 0;
8611 }
8612
Arif Hussain9765f7d2018-07-03 08:28:26 -07008613 if (sta_set_beamformee_sts(dut, intf, atoi(val))) {
8614 send_resp(dut, conn, SIGMA_ERROR,
8615 "ErrorCode,Failed to set BeamformeeSTS");
8616 return 0;
8617 }
8618 }
8619
Arif Hussain68d23f52018-07-11 13:39:08 -07008620 val = get_param(cmd, "Trig_MAC_Padding_Dur");
8621 if (val) {
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07008622#ifdef NL80211_SUPPORT
8623 enum qca_wlan_he_mac_padding_dur set_val;
8624
8625 switch (atoi(val)) {
8626 case 16:
8627 set_val = QCA_WLAN_HE_16US_OF_PROCESS_TIME;
8628 break;
8629 case 8:
8630 set_val = QCA_WLAN_HE_8US_OF_PROCESS_TIME;
8631 break;
8632 default:
8633 set_val = QCA_WLAN_HE_NO_ADDITIONAL_PROCESS_TIME;
8634 break;
8635 }
8636 if (sta_set_mac_padding_duration(dut, intf, set_val)) {
Arif Hussain68d23f52018-07-11 13:39:08 -07008637 send_resp(dut, conn, SIGMA_ERROR,
8638 "ErrorCode,Failed to set MAC padding duration");
8639 return 0;
8640 }
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07008641#else /* NL80211_SUPPORT */
8642 sigma_dut_print(dut, DUT_MSG_ERROR,
8643 "MAC padding duration cannot be changed without NL80211_SUPPORT defined");
8644#endif /* NL80211_SUPPORT */
Arif Hussain68d23f52018-07-11 13:39:08 -07008645 }
8646
Arif Hussain480d5f42019-03-12 14:40:42 -07008647 val = get_param(cmd, "TWT_ReqSupport");
8648 if (val) {
8649 int set_val;
8650
8651 if (strcasecmp(val, "Enable") == 0) {
8652 set_val = 1;
8653 } else if (strcasecmp(val, "Disable") == 0) {
8654 set_val = 0;
8655 } else {
8656 send_resp(dut, conn, SIGMA_ERROR,
8657 "ErrorCode,Invalid TWT_ReqSupport");
8658 return STATUS_SENT;
8659 }
8660
8661 if (sta_set_twt_req_support(dut, intf, set_val)) {
8662 sigma_dut_print(dut, DUT_MSG_ERROR,
8663 "Failed to set TWT req support %d",
8664 set_val);
8665 send_resp(dut, conn, SIGMA_ERROR,
8666 "ErrorCode,Failed to set TWT_ReqSupport");
8667 return STATUS_SENT;
8668 }
8669 }
8670
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07008671 val = get_param(cmd, "MU_EDCA");
8672 if (val && (strcasecmp(val, "Override") == 0)) {
8673 if (sta_set_mu_edca_override(dut, intf, 1)) {
8674 send_resp(dut, conn, SIGMA_ERROR,
8675 "ErrorCode,Failed to set MU EDCA override");
8676 return 0;
8677 }
8678 }
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -07008679
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07008680 val = get_param(cmd, "OMControl");
8681 if (val) {
8682 int set_val = 1;
8683
8684 if (strcasecmp(val, "Enable") == 0)
8685 set_val = 1;
8686 else if (strcasecmp(val, "Disable") == 0)
8687 set_val = 0;
8688
8689 if (sta_set_om_ctrl_supp(dut, intf, set_val)) {
8690 send_resp(dut, conn, SIGMA_ERROR,
8691 "ErrorCode,Failed to set OM ctrl supp");
8692 return 0;
8693 }
8694 }
8695
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -07008696 val = get_param(cmd, "ADDBAResp_BufSize");
8697 if (val) {
8698 int buf_size;
8699
8700 if (strcasecmp(val, "gt64") == 0)
8701 buf_size = 256;
8702 else
8703 buf_size = 64;
8704 if (get_driver_type() == DRIVER_WCN &&
8705 sta_set_addba_buf_size(dut, intf, buf_size)) {
8706 send_resp(dut, conn, SIGMA_ERROR,
8707 "ErrorCode,set addbaresp_buff_size failed");
8708 return 0;
8709 }
8710 }
8711
8712 val = get_param(cmd, "ADDBAReq_BufSize");
8713 if (val) {
8714 int buf_size;
8715
8716 if (strcasecmp(val, "gt64") == 0)
8717 buf_size = 256;
8718 else
8719 buf_size = 64;
8720 if (get_driver_type() == DRIVER_WCN &&
8721 sta_set_addba_buf_size(dut, intf, buf_size)) {
8722 send_resp(dut, conn, SIGMA_ERROR,
8723 "ErrorCode,set addbareq_buff_size failed");
8724 return 0;
8725 }
8726 }
8727
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008728 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
8729}
8730
8731
8732static int sta_set_wireless_60g(struct sigma_dut *dut,
8733 struct sigma_conn *conn,
8734 struct sigma_cmd *cmd)
8735{
8736 const char *dev_role = get_param(cmd, "DevRole");
8737
8738 if (!dev_role) {
8739 send_resp(dut, conn, SIGMA_INVALID,
8740 "ErrorCode,DevRole not specified");
8741 return 0;
8742 }
8743
8744 if (strcasecmp(dev_role, "PCP") == 0)
8745 return sta_set_60g_pcp(dut, conn, cmd);
8746 if (strcasecmp(dev_role, "STA") == 0)
8747 return sta_set_60g_sta(dut, conn, cmd);
8748 send_resp(dut, conn, SIGMA_INVALID,
8749 "ErrorCode,DevRole not supported");
8750 return 0;
8751}
8752
8753
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05308754static int sta_set_wireless_oce(struct sigma_dut *dut, struct sigma_conn *conn,
8755 struct sigma_cmd *cmd)
8756{
8757 int status;
8758 const char *intf = get_param(cmd, "Interface");
8759 const char *val = get_param(cmd, "DevRole");
8760
8761 if (val && strcasecmp(val, "STA-CFON") == 0) {
8762 status = sta_cfon_set_wireless(dut, conn, cmd);
8763 if (status)
8764 return status;
8765 }
8766 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
8767}
8768
8769
Jouni Malinenf7222712019-06-13 01:50:21 +03008770static enum sigma_cmd_result cmd_sta_set_wireless(struct sigma_dut *dut,
8771 struct sigma_conn *conn,
8772 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008773{
8774 const char *val;
8775
8776 val = get_param(cmd, "Program");
8777 if (val) {
8778 if (strcasecmp(val, "11n") == 0)
8779 return cmd_sta_set_11n(dut, conn, cmd);
Amarnath Hullur Subramanyam4f860292018-01-31 03:49:35 -08008780 if (strcasecmp(val, "VHT") == 0 || strcasecmp(val, "HE") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008781 return cmd_sta_set_wireless_vht(dut, conn, cmd);
8782 if (strcasecmp(val, "60ghz") == 0)
8783 return sta_set_wireless_60g(dut, conn, cmd);
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05308784 if (strcasecmp(val, "OCE") == 0)
8785 return sta_set_wireless_oce(dut, conn, cmd);
Alexei Avshalom Lazar66bb9972018-12-18 16:01:43 +02008786 /* sta_set_wireless in WPS program is only used for 60G */
8787 if (is_60g_sigma_dut(dut))
8788 return sta_set_wireless_60g(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008789 send_resp(dut, conn, SIGMA_ERROR,
8790 "ErrorCode,Program value not supported");
8791 } else {
8792 send_resp(dut, conn, SIGMA_ERROR,
8793 "ErrorCode,Program argument not available");
8794 }
8795
8796 return 0;
8797}
8798
8799
8800static void ath_sta_inject_frame(struct sigma_dut *dut, const char *intf,
8801 int tid)
8802{
8803 char buf[100];
8804 int tid_to_dscp [] = { 0x00, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0 };
8805
Pradeep Reddy POTTETId31d1322016-10-13 17:22:03 +05308806 if (tid < 0 ||
8807 tid >= (int) (sizeof(tid_to_dscp) / sizeof(tid_to_dscp[0]))) {
8808 sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported TID: %d", tid);
8809 return;
8810 }
8811
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008812 /*
8813 * Two ways to ensure that addba request with a
8814 * non zero TID could be sent out. EV 117296
8815 */
8816 snprintf(buf, sizeof(buf),
8817 "ping -c 8 -Q %d `arp -a | grep wlan0 | awk '{print $2}' | tr -d '()'`",
8818 tid);
8819 if (system(buf) != 0) {
8820 sigma_dut_print(dut, DUT_MSG_ERROR,
8821 "Ping did not send out");
8822 }
8823
8824 snprintf(buf, sizeof(buf),
8825 "iwconfig %s | grep Access | awk '{print $6}' > %s",
8826 intf, VI_QOS_TMP_FILE);
8827 if (system(buf) != 0)
8828 return;
8829
8830 snprintf(buf, sizeof(buf),
8831 "ifconfig %s | grep HWaddr | cut -b 39-56 >> %s",
8832 intf, VI_QOS_TMP_FILE);
8833 if (system(buf) != 0)
8834 sigma_dut_print(dut, DUT_MSG_ERROR, "HWaddr matching failed");
8835
8836 snprintf(buf,sizeof(buf), "sed -n '3,$p' %s >> %s",
8837 VI_QOS_REFFILE, VI_QOS_TMP_FILE);
8838 if (system(buf) != 0) {
8839 sigma_dut_print(dut, DUT_MSG_ERROR,
8840 "VI_QOS_TEMP_FILE generation error failed");
8841 }
8842 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
8843 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
8844 if (system(buf) != 0) {
8845 sigma_dut_print(dut, DUT_MSG_ERROR,
8846 "VI_QOS_FILE generation failed");
8847 }
8848
8849 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
8850 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
8851 if (system(buf) != 0) {
8852 sigma_dut_print(dut, DUT_MSG_ERROR,
8853 "VI_QOS_FILE generation failed");
8854 }
8855
8856 snprintf(buf, sizeof(buf), "ethinject %s %s", intf, VI_QOS_FILE);
8857 if (system(buf) != 0) {
8858 }
8859}
8860
8861
8862static int ath_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
8863 struct sigma_cmd *cmd)
8864{
8865 const char *intf = get_param(cmd, "Interface");
8866 const char *val;
8867 int tid = 0;
8868 char buf[100];
8869
8870 val = get_param(cmd, "TID");
8871 if (val) {
8872 tid = atoi(val);
8873 if (tid)
8874 ath_sta_inject_frame(dut, intf, tid);
8875 }
8876
8877 /* Command sequence for ADDBA request on Peregrine based devices */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008878 run_iwpriv(dut, intf, "setaddbaoper 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008879
8880 snprintf(buf, sizeof(buf), "wifitool %s senddelba 1 %d 1 4", intf, tid);
8881 if (system(buf) != 0) {
8882 sigma_dut_print(dut, DUT_MSG_ERROR,
8883 "wifitool senddelba failed");
8884 }
8885
8886 snprintf(buf, sizeof(buf), "wifitool %s sendaddba 1 %d 64", intf, tid);
8887 if (system(buf) != 0) {
8888 sigma_dut_print(dut, DUT_MSG_ERROR,
8889 "wifitool sendaddba failed");
8890 }
8891
8892 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
8893
8894 return 1;
8895}
8896
8897
Lior David9981b512017-01-20 13:16:40 +02008898#ifdef __linux__
8899
8900static int wil6210_send_addba(struct sigma_dut *dut, const char *dest_mac,
8901 int agg_size)
8902{
8903 char dir[128], buf[128];
8904 FILE *f;
8905 regex_t re;
8906 regmatch_t m[2];
Jouni Malinen3aa72862019-05-29 23:14:51 +03008907 int rc, ret = -1, vring_id, found, res;
Lior David9981b512017-01-20 13:16:40 +02008908
8909 if (wil6210_get_debugfs_dir(dut, dir, sizeof(dir))) {
8910 sigma_dut_print(dut, DUT_MSG_ERROR,
8911 "failed to get wil6210 debugfs dir");
8912 return -1;
8913 }
8914
Jouni Malinen3aa72862019-05-29 23:14:51 +03008915 res = snprintf(buf, sizeof(buf), "%s/vrings", dir);
8916 if (res < 0 || res >= sizeof(buf))
8917 return -1;
Lior David9981b512017-01-20 13:16:40 +02008918 f = fopen(buf, "r");
8919 if (!f) {
8920 sigma_dut_print(dut, DUT_MSG_ERROR, "failed to open: %s", buf);
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +02008921 /* newer wil6210 driver renamed file to "rings" */
Jouni Malinen3aa72862019-05-29 23:14:51 +03008922 res = snprintf(buf, sizeof(buf), "%s/rings", dir);
8923 if (res < 0 || res >= sizeof(buf))
8924 return -1;
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +02008925 f = fopen(buf, "r");
8926 if (!f) {
8927 sigma_dut_print(dut, DUT_MSG_ERROR,
8928 "failed to open: %s", buf);
8929 return -1;
8930 }
Lior David9981b512017-01-20 13:16:40 +02008931 }
8932
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +02008933 /* can be either VRING tx... or RING... */
8934 if (regcomp(&re, "RING tx_[ \t]*([0-9]+)", REG_EXTENDED)) {
Lior David9981b512017-01-20 13:16:40 +02008935 sigma_dut_print(dut, DUT_MSG_ERROR, "regcomp failed");
8936 goto out;
8937 }
8938
8939 /* find TX VRING for the mac address */
8940 found = 0;
8941 while (fgets(buf, sizeof(buf), f)) {
8942 if (strcasestr(buf, dest_mac)) {
8943 found = 1;
8944 break;
8945 }
8946 }
8947
8948 if (!found) {
8949 sigma_dut_print(dut, DUT_MSG_ERROR,
8950 "no TX VRING for %s", dest_mac);
8951 goto out;
8952 }
8953
8954 /* extract VRING ID, "VRING tx_<id> = {" */
8955 if (!fgets(buf, sizeof(buf), f)) {
8956 sigma_dut_print(dut, DUT_MSG_ERROR,
8957 "no VRING start line for %s", dest_mac);
8958 goto out;
8959 }
8960
8961 rc = regexec(&re, buf, 2, m, 0);
8962 regfree(&re);
8963 if (rc || m[1].rm_so < 0) {
8964 sigma_dut_print(dut, DUT_MSG_ERROR,
8965 "no VRING TX ID for %s", dest_mac);
8966 goto out;
8967 }
8968 buf[m[1].rm_eo] = 0;
8969 vring_id = atoi(&buf[m[1].rm_so]);
8970
8971 /* send the addba command */
8972 fclose(f);
Jouni Malinen3aa72862019-05-29 23:14:51 +03008973 res = snprintf(buf, sizeof(buf), "%s/back", dir);
8974 if (res < 0 || res >= sizeof(buf))
8975 return -1;
Lior David9981b512017-01-20 13:16:40 +02008976 f = fopen(buf, "w");
8977 if (!f) {
8978 sigma_dut_print(dut, DUT_MSG_ERROR,
8979 "failed to open: %s", buf);
8980 return -1;
8981 }
8982
8983 fprintf(f, "add %d %d\n", vring_id, agg_size);
8984
8985 ret = 0;
8986
8987out:
8988 fclose(f);
8989
8990 return ret;
8991}
8992
8993
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +02008994int send_addba_60g(struct sigma_dut *dut, struct sigma_conn *conn,
8995 struct sigma_cmd *cmd, const char *mac_param)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008996{
8997 const char *val;
8998 int tid = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008999
9000 val = get_param(cmd, "TID");
9001 if (val) {
9002 tid = atoi(val);
9003 if (tid != 0) {
9004 sigma_dut_print(dut, DUT_MSG_ERROR,
9005 "Ignore TID %d for send_addba use TID 0 for 60g since only 0 required on TX",
9006 tid);
9007 }
9008 }
9009
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +02009010 val = get_param(cmd, mac_param);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009011 if (!val) {
9012 sigma_dut_print(dut, DUT_MSG_ERROR,
9013 "Currently not supporting addba for 60G without Dest_mac");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02009014 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009015 }
9016
Lior David9981b512017-01-20 13:16:40 +02009017 if (wil6210_send_addba(dut, val, dut->back_rcv_buf))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009018 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009019
9020 return 1;
9021}
9022
Lior David9981b512017-01-20 13:16:40 +02009023#endif /* __linux__ */
9024
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009025
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009026static int wcn_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
9027 struct sigma_cmd *cmd)
9028{
9029#ifdef NL80211_SUPPORT
9030 const char *intf = get_param(cmd, "Interface");
9031 const char *val;
9032 int tid = -1;
9033 int bufsize = 64;
9034 struct nl_msg *msg;
9035 int ret = 0;
9036 struct nlattr *params;
9037 int ifindex;
9038
9039 val = get_param(cmd, "TID");
9040 if (val)
9041 tid = atoi(val);
9042
9043 if (tid == -1) {
9044 send_resp(dut, conn, SIGMA_ERROR,
9045 "ErrorCode,sta_send_addba tid invalid");
9046 return 0;
9047 }
9048
9049 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
9050
9051 ifindex = if_nametoindex(intf);
9052 if (ifindex == 0) {
9053 sigma_dut_print(dut, DUT_MSG_ERROR,
9054 "%s: Index for interface %s failed",
9055 __func__, intf);
9056 send_resp(dut, conn, SIGMA_ERROR,
9057 "ErrorCode,sta_send_addba interface invalid");
9058 return 0;
9059 }
9060
9061 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
9062 NL80211_CMD_VENDOR)) ||
9063 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
9064 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
9065 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
9066 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
9067 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
9068 nla_put_u8(msg,
9069 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADD_DEL_BA_SESSION,
9070 QCA_WLAN_ADD_BA) ||
9071 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BA_TID,
9072 tid) ||
Kiran Kumar Lokere26e27582018-08-01 16:18:34 -07009073 nla_put_u16(msg,
9074 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE,
9075 bufsize)) {
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009076 sigma_dut_print(dut, DUT_MSG_ERROR,
9077 "%s: err in adding vendor_cmd and vendor_data",
9078 __func__);
9079 nlmsg_free(msg);
9080 send_resp(dut, conn, SIGMA_ERROR,
9081 "ErrorCode,sta_send_addba err in adding vendor_cmd and vendor_data");
9082 return 0;
9083 }
9084 nla_nest_end(msg, params);
9085
9086 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
9087 if (ret) {
9088 sigma_dut_print(dut, DUT_MSG_ERROR,
9089 "%s: err in send_and_recv_msgs, ret=%d",
9090 __func__, ret);
Sunil Dutt30605592018-05-04 20:35:50 +05309091 if (ret == -EOPNOTSUPP)
9092 return 1;
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009093 send_resp(dut, conn, SIGMA_ERROR,
9094 "ErrorCode,sta_send_addba err in send_and_recv_msgs");
9095 return 0;
9096 }
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009097#else /* NL80211_SUPPORT */
9098 sigma_dut_print(dut, DUT_MSG_ERROR,
9099 "sta_send_addba not supported without NL80211_SUPPORT defined");
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009100#endif /* NL80211_SUPPORT */
Sunil Dutt30605592018-05-04 20:35:50 +05309101
9102 return 1;
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009103}
9104
9105
Jouni Malinenf7222712019-06-13 01:50:21 +03009106static enum sigma_cmd_result cmd_sta_send_addba(struct sigma_dut *dut,
9107 struct sigma_conn *conn,
9108 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009109{
9110 switch (get_driver_type()) {
9111 case DRIVER_ATHEROS:
9112 return ath_sta_send_addba(dut, conn, cmd);
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009113 case DRIVER_WCN:
9114 return wcn_sta_send_addba(dut, conn, cmd);
Lior David9981b512017-01-20 13:16:40 +02009115#ifdef __linux__
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009116 case DRIVER_WIL6210:
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +02009117 return send_addba_60g(dut, conn, cmd, "Dest_mac");
Lior David9981b512017-01-20 13:16:40 +02009118#endif /* __linux__ */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009119 default:
9120 /*
9121 * There is no driver specific implementation for other drivers.
9122 * Ignore the command and report COMPLETE since the following
9123 * throughput test operation will end up sending ADDBA anyway.
9124 */
9125 return 1;
9126 }
9127}
9128
9129
9130int inject_eth_frame(int s, const void *data, size_t len,
9131 unsigned short ethtype, char *dst, char *src)
9132{
9133 struct iovec iov[4] = {
9134 {
9135 .iov_base = dst,
9136 .iov_len = ETH_ALEN,
9137 },
9138 {
9139 .iov_base = src,
9140 .iov_len = ETH_ALEN,
9141 },
9142 {
9143 .iov_base = &ethtype,
9144 .iov_len = sizeof(unsigned short),
9145 },
9146 {
9147 .iov_base = (void *) data,
9148 .iov_len = len,
9149 }
9150 };
9151 struct msghdr msg = {
9152 .msg_name = NULL,
9153 .msg_namelen = 0,
9154 .msg_iov = iov,
9155 .msg_iovlen = 4,
9156 .msg_control = NULL,
9157 .msg_controllen = 0,
9158 .msg_flags = 0,
9159 };
9160
9161 return sendmsg(s, &msg, 0);
9162}
9163
9164#if defined(__linux__) || defined(__QNXNTO__)
9165
9166int inject_frame(int s, const void *data, size_t len, int encrypt)
9167{
9168#define IEEE80211_RADIOTAP_F_WEP 0x04
9169#define IEEE80211_RADIOTAP_F_FRAG 0x08
9170 unsigned char rtap_hdr[] = {
9171 0x00, 0x00, /* radiotap version */
9172 0x0e, 0x00, /* radiotap length */
9173 0x02, 0xc0, 0x00, 0x00, /* bmap: flags, tx and rx flags */
9174 IEEE80211_RADIOTAP_F_FRAG, /* F_FRAG (fragment if required) */
9175 0x00, /* padding */
9176 0x00, 0x00, /* RX and TX flags to indicate that */
9177 0x00, 0x00, /* this is the injected frame directly */
9178 };
9179 struct iovec iov[2] = {
9180 {
9181 .iov_base = &rtap_hdr,
9182 .iov_len = sizeof(rtap_hdr),
9183 },
9184 {
9185 .iov_base = (void *) data,
9186 .iov_len = len,
9187 }
9188 };
9189 struct msghdr msg = {
9190 .msg_name = NULL,
9191 .msg_namelen = 0,
9192 .msg_iov = iov,
9193 .msg_iovlen = 2,
9194 .msg_control = NULL,
9195 .msg_controllen = 0,
9196 .msg_flags = 0,
9197 };
9198
9199 if (encrypt)
9200 rtap_hdr[8] |= IEEE80211_RADIOTAP_F_WEP;
9201
9202 return sendmsg(s, &msg, 0);
9203}
9204
9205
9206int open_monitor(const char *ifname)
9207{
9208#ifdef __QNXNTO__
9209 struct sockaddr_dl ll;
9210 int s;
9211
9212 memset(&ll, 0, sizeof(ll));
9213 ll.sdl_family = AF_LINK;
9214 ll.sdl_index = if_nametoindex(ifname);
9215 if (ll.sdl_index == 0) {
9216 perror("if_nametoindex");
9217 return -1;
9218 }
9219 s = socket(PF_INET, SOCK_RAW, 0);
9220#else /* __QNXNTO__ */
9221 struct sockaddr_ll ll;
9222 int s;
9223
9224 memset(&ll, 0, sizeof(ll));
9225 ll.sll_family = AF_PACKET;
9226 ll.sll_ifindex = if_nametoindex(ifname);
9227 if (ll.sll_ifindex == 0) {
9228 perror("if_nametoindex");
9229 return -1;
9230 }
9231 s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
9232#endif /* __QNXNTO__ */
9233 if (s < 0) {
9234 perror("socket[PF_PACKET,SOCK_RAW]");
9235 return -1;
9236 }
9237
9238 if (bind(s, (struct sockaddr *) &ll, sizeof(ll)) < 0) {
9239 perror("monitor socket bind");
9240 close(s);
9241 return -1;
9242 }
9243
9244 return s;
9245}
9246
9247
9248static int hex2num(char c)
9249{
9250 if (c >= '0' && c <= '9')
9251 return c - '0';
9252 if (c >= 'a' && c <= 'f')
9253 return c - 'a' + 10;
9254 if (c >= 'A' && c <= 'F')
9255 return c - 'A' + 10;
9256 return -1;
9257}
9258
9259
9260int hwaddr_aton(const char *txt, unsigned char *addr)
9261{
9262 int i;
9263
9264 for (i = 0; i < 6; i++) {
9265 int a, b;
9266
9267 a = hex2num(*txt++);
9268 if (a < 0)
9269 return -1;
9270 b = hex2num(*txt++);
9271 if (b < 0)
9272 return -1;
9273 *addr++ = (a << 4) | b;
9274 if (i < 5 && *txt++ != ':')
9275 return -1;
9276 }
9277
9278 return 0;
9279}
9280
9281#endif /* defined(__linux__) || defined(__QNXNTO__) */
9282
9283enum send_frame_type {
9284 DISASSOC, DEAUTH, SAQUERY, AUTH, ASSOCREQ, REASSOCREQ, DLS_REQ
9285};
9286enum send_frame_protection {
9287 CORRECT_KEY, INCORRECT_KEY, UNPROTECTED
9288};
9289
9290
9291static int sta_inject_frame(struct sigma_dut *dut, struct sigma_conn *conn,
9292 enum send_frame_type frame,
9293 enum send_frame_protection protected,
9294 const char *dest)
9295{
9296#ifdef __linux__
9297 unsigned char buf[1000], *pos;
9298 int s, res;
9299 char bssid[20], addr[20];
9300 char result[32], ssid[100];
9301 size_t ssid_len;
9302
9303 if (get_wpa_status(get_station_ifname(), "wpa_state", result,
9304 sizeof(result)) < 0 ||
9305 strncmp(result, "COMPLETED", 9) != 0) {
9306 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Not connected");
9307 return 0;
9308 }
9309
9310 if (get_wpa_status(get_station_ifname(), "bssid", bssid, sizeof(bssid))
9311 < 0) {
9312 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
9313 "current BSSID");
9314 return 0;
9315 }
9316
9317 if (get_wpa_status(get_station_ifname(), "address", addr, sizeof(addr))
9318 < 0) {
9319 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
9320 "own MAC address");
9321 return 0;
9322 }
9323
9324 if (get_wpa_status(get_station_ifname(), "ssid", ssid, sizeof(ssid))
9325 < 0) {
9326 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
9327 "current SSID");
9328 return 0;
9329 }
9330 ssid_len = strlen(ssid);
9331
9332 pos = buf;
9333
9334 /* Frame Control */
9335 switch (frame) {
9336 case DISASSOC:
9337 *pos++ = 0xa0;
9338 break;
9339 case DEAUTH:
9340 *pos++ = 0xc0;
9341 break;
9342 case SAQUERY:
9343 *pos++ = 0xd0;
9344 break;
9345 case AUTH:
9346 *pos++ = 0xb0;
9347 break;
9348 case ASSOCREQ:
9349 *pos++ = 0x00;
9350 break;
9351 case REASSOCREQ:
9352 *pos++ = 0x20;
9353 break;
9354 case DLS_REQ:
9355 *pos++ = 0xd0;
9356 break;
9357 }
9358
9359 if (protected == INCORRECT_KEY)
9360 *pos++ = 0x40; /* Set Protected field to 1 */
9361 else
9362 *pos++ = 0x00;
9363
9364 /* Duration */
9365 *pos++ = 0x00;
9366 *pos++ = 0x00;
9367
9368 /* addr1 = DA (current AP) */
9369 hwaddr_aton(bssid, pos);
9370 pos += 6;
9371 /* addr2 = SA (own address) */
9372 hwaddr_aton(addr, pos);
9373 pos += 6;
9374 /* addr3 = BSSID (current AP) */
9375 hwaddr_aton(bssid, pos);
9376 pos += 6;
9377
9378 /* Seq# (to be filled by driver/mac80211) */
9379 *pos++ = 0x00;
9380 *pos++ = 0x00;
9381
9382 if (protected == INCORRECT_KEY) {
9383 /* CCMP parameters */
9384 memcpy(pos, "\x61\x01\x00\x20\x00\x10\x00\x00", 8);
9385 pos += 8;
9386 }
9387
9388 if (protected == INCORRECT_KEY) {
9389 switch (frame) {
9390 case DEAUTH:
9391 /* Reason code (encrypted) */
9392 memcpy(pos, "\xa7\x39", 2);
9393 pos += 2;
9394 break;
9395 case DISASSOC:
9396 /* Reason code (encrypted) */
9397 memcpy(pos, "\xa7\x39", 2);
9398 pos += 2;
9399 break;
9400 case SAQUERY:
9401 /* Category|Action|TransID (encrypted) */
9402 memcpy(pos, "\x6f\xbd\xe9\x4d", 4);
9403 pos += 4;
9404 break;
9405 default:
9406 return -1;
9407 }
9408
9409 /* CCMP MIC */
9410 memcpy(pos, "\xc8\xd8\x3b\x06\x5d\xb7\x25\x68", 8);
9411 pos += 8;
9412 } else {
9413 switch (frame) {
9414 case DEAUTH:
9415 /* reason code = 8 */
9416 *pos++ = 0x08;
9417 *pos++ = 0x00;
9418 break;
9419 case DISASSOC:
9420 /* reason code = 8 */
9421 *pos++ = 0x08;
9422 *pos++ = 0x00;
9423 break;
9424 case SAQUERY:
9425 /* Category - SA Query */
9426 *pos++ = 0x08;
9427 /* SA query Action - Request */
9428 *pos++ = 0x00;
9429 /* Transaction ID */
9430 *pos++ = 0x12;
9431 *pos++ = 0x34;
9432 break;
9433 case AUTH:
9434 /* Auth Alg (Open) */
9435 *pos++ = 0x00;
9436 *pos++ = 0x00;
9437 /* Seq# */
9438 *pos++ = 0x01;
9439 *pos++ = 0x00;
9440 /* Status code */
9441 *pos++ = 0x00;
9442 *pos++ = 0x00;
9443 break;
9444 case ASSOCREQ:
9445 /* Capability Information */
9446 *pos++ = 0x31;
9447 *pos++ = 0x04;
9448 /* Listen Interval */
9449 *pos++ = 0x0a;
9450 *pos++ = 0x00;
9451 /* SSID */
9452 *pos++ = 0x00;
9453 *pos++ = ssid_len;
9454 memcpy(pos, ssid, ssid_len);
9455 pos += ssid_len;
9456 /* Supported Rates */
9457 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
9458 10);
9459 pos += 10;
9460 /* Extended Supported Rates */
9461 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
9462 pos += 6;
9463 /* RSN */
9464 memcpy(pos, "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00"
9465 "\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x02\xc0"
9466 "\x00\x00\x00\x00\x0f\xac\x06", 28);
9467 pos += 28;
9468 break;
9469 case REASSOCREQ:
9470 /* Capability Information */
9471 *pos++ = 0x31;
9472 *pos++ = 0x04;
9473 /* Listen Interval */
9474 *pos++ = 0x0a;
9475 *pos++ = 0x00;
9476 /* Current AP */
9477 hwaddr_aton(bssid, pos);
9478 pos += 6;
9479 /* SSID */
9480 *pos++ = 0x00;
9481 *pos++ = ssid_len;
9482 memcpy(pos, ssid, ssid_len);
9483 pos += ssid_len;
9484 /* Supported Rates */
9485 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
9486 10);
9487 pos += 10;
9488 /* Extended Supported Rates */
9489 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
9490 pos += 6;
9491 /* RSN */
9492 memcpy(pos, "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00"
9493 "\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x02\xc0"
9494 "\x00\x00\x00\x00\x0f\xac\x06", 28);
9495 pos += 28;
9496 break;
9497 case DLS_REQ:
9498 /* Category - DLS */
9499 *pos++ = 0x02;
9500 /* DLS Action - Request */
9501 *pos++ = 0x00;
9502 /* Destination MACAddress */
9503 if (dest)
9504 hwaddr_aton(dest, pos);
9505 else
9506 memset(pos, 0, 6);
9507 pos += 6;
9508 /* Source MACAddress */
9509 hwaddr_aton(addr, pos);
9510 pos += 6;
9511 /* Capability Information */
9512 *pos++ = 0x10; /* Privacy */
9513 *pos++ = 0x06; /* QoS */
9514 /* DLS Timeout Value */
9515 *pos++ = 0x00;
9516 *pos++ = 0x01;
9517 /* Supported rates */
9518 *pos++ = 0x01;
9519 *pos++ = 0x08;
9520 *pos++ = 0x0c; /* 6 Mbps */
9521 *pos++ = 0x12; /* 9 Mbps */
9522 *pos++ = 0x18; /* 12 Mbps */
9523 *pos++ = 0x24; /* 18 Mbps */
9524 *pos++ = 0x30; /* 24 Mbps */
9525 *pos++ = 0x48; /* 36 Mbps */
9526 *pos++ = 0x60; /* 48 Mbps */
9527 *pos++ = 0x6c; /* 54 Mbps */
9528 /* TODO: Extended Supported Rates */
9529 /* TODO: HT Capabilities */
9530 break;
9531 }
9532 }
9533
9534 s = open_monitor("sigmadut");
9535 if (s < 0) {
9536 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
9537 "monitor socket");
9538 return 0;
9539 }
9540
9541 res = inject_frame(s, buf, pos - buf, protected == CORRECT_KEY);
9542 if (res < 0) {
9543 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
9544 "inject frame");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05309545 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009546 return 0;
9547 }
9548 if (res < pos - buf) {
9549 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Only partial "
9550 "frame sent");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05309551 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009552 return 0;
9553 }
9554
9555 close(s);
9556
9557 return 1;
9558#else /* __linux__ */
9559 send_resp(dut, conn, SIGMA_ERROR, "errorCode,sta_send_frame not "
9560 "yet supported");
9561 return 0;
9562#endif /* __linux__ */
9563}
9564
9565
9566static int cmd_sta_send_frame_tdls(struct sigma_dut *dut,
9567 struct sigma_conn *conn,
9568 struct sigma_cmd *cmd)
9569{
9570 const char *intf = get_param(cmd, "Interface");
9571 const char *sta, *val;
9572 unsigned char addr[ETH_ALEN];
9573 char buf[100];
9574
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +03009575 if (!intf)
9576 return -1;
9577
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009578 sta = get_param(cmd, "peer");
9579 if (sta == NULL)
9580 sta = get_param(cmd, "station");
9581 if (sta == NULL) {
9582 send_resp(dut, conn, SIGMA_ERROR,
9583 "ErrorCode,Missing peer address");
9584 return 0;
9585 }
9586 if (hwaddr_aton(sta, addr) < 0) {
9587 send_resp(dut, conn, SIGMA_ERROR,
9588 "ErrorCode,Invalid peer address");
9589 return 0;
9590 }
9591
9592 val = get_param(cmd, "type");
9593 if (val == NULL)
9594 return -1;
9595
9596 if (strcasecmp(val, "DISCOVERY") == 0) {
9597 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", sta);
9598 if (wpa_command(intf, buf) < 0) {
9599 send_resp(dut, conn, SIGMA_ERROR,
9600 "ErrorCode,Failed to send TDLS discovery");
9601 return 0;
9602 }
9603 return 1;
9604 }
9605
9606 if (strcasecmp(val, "SETUP") == 0) {
9607 int status = 0, timeout = 0;
9608
9609 val = get_param(cmd, "Status");
9610 if (val)
9611 status = atoi(val);
9612
9613 val = get_param(cmd, "Timeout");
9614 if (val)
9615 timeout = atoi(val);
9616
9617 if (status != 0 && status != 37) {
9618 send_resp(dut, conn, SIGMA_ERROR,
9619 "ErrorCode,Unsupported status value");
9620 return 0;
9621 }
9622
9623 if (timeout != 0 && timeout != 301) {
9624 send_resp(dut, conn, SIGMA_ERROR,
9625 "ErrorCode,Unsupported timeout value");
9626 return 0;
9627 }
9628
9629 if (status && timeout) {
9630 send_resp(dut, conn, SIGMA_ERROR,
9631 "ErrorCode,Unsupported timeout+status "
9632 "combination");
9633 return 0;
9634 }
9635
9636 if (status == 37 &&
9637 wpa_command(intf, "SET tdls_testing 0x200")) {
9638 send_resp(dut, conn, SIGMA_ERROR,
9639 "ErrorCode,Failed to enable "
9640 "decline setup response test mode");
9641 return 0;
9642 }
9643
9644 if (timeout == 301) {
9645 int res;
9646 if (dut->no_tpk_expiration)
9647 res = wpa_command(intf,
9648 "SET tdls_testing 0x108");
9649 else
9650 res = wpa_command(intf,
9651 "SET tdls_testing 0x8");
9652 if (res) {
9653 send_resp(dut, conn, SIGMA_ERROR,
9654 "ErrorCode,Failed to set short TPK "
9655 "lifetime");
9656 return 0;
9657 }
9658 }
9659
9660 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", sta);
9661 if (wpa_command(intf, buf) < 0) {
9662 send_resp(dut, conn, SIGMA_ERROR,
9663 "ErrorCode,Failed to send TDLS setup");
9664 return 0;
9665 }
9666 return 1;
9667 }
9668
9669 if (strcasecmp(val, "TEARDOWN") == 0) {
9670 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", sta);
9671 if (wpa_command(intf, buf) < 0) {
9672 send_resp(dut, conn, SIGMA_ERROR,
9673 "ErrorCode,Failed to send TDLS teardown");
9674 return 0;
9675 }
9676 return 1;
9677 }
9678
9679 send_resp(dut, conn, SIGMA_ERROR,
9680 "ErrorCode,Unsupported TDLS frame");
9681 return 0;
9682}
9683
9684
9685static int sta_ap_known(const char *ifname, const char *bssid)
9686{
9687 char buf[4096];
9688
Jouni Malinendd32f192018-09-15 02:55:19 +03009689 snprintf(buf, sizeof(buf), "BSS MASK=1 %s", bssid);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009690 if (wpa_command_resp(ifname, buf, buf, sizeof(buf)) < 0)
9691 return 0;
9692 if (strncmp(buf, "id=", 3) != 0)
9693 return 0;
9694 return 1;
9695}
9696
9697
9698static int sta_scan_ap(struct sigma_dut *dut, const char *ifname,
9699 const char *bssid)
9700{
9701 int res;
9702 struct wpa_ctrl *ctrl;
9703 char buf[256];
9704
9705 if (sta_ap_known(ifname, bssid))
9706 return 0;
9707 sigma_dut_print(dut, DUT_MSG_DEBUG,
9708 "AP not in BSS table - start scan");
9709
9710 ctrl = open_wpa_mon(ifname);
9711 if (ctrl == NULL) {
9712 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
9713 "wpa_supplicant monitor connection");
9714 return -1;
9715 }
9716
9717 if (wpa_command(ifname, "SCAN") < 0) {
9718 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to start scan");
9719 wpa_ctrl_detach(ctrl);
9720 wpa_ctrl_close(ctrl);
9721 return -1;
9722 }
9723
9724 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
9725 buf, sizeof(buf));
9726
9727 wpa_ctrl_detach(ctrl);
9728 wpa_ctrl_close(ctrl);
9729
9730 if (res < 0) {
9731 sigma_dut_print(dut, DUT_MSG_INFO, "Scan did not complete");
9732 return -1;
9733 }
9734
9735 if (sta_ap_known(ifname, bssid))
9736 return 0;
9737 sigma_dut_print(dut, DUT_MSG_INFO, "AP not in BSS table");
9738 return -1;
9739}
9740
9741
9742static int cmd_sta_send_frame_hs2_neighadv(struct sigma_dut *dut,
9743 struct sigma_conn *conn,
9744 struct sigma_cmd *cmd,
9745 const char *intf)
9746{
9747 char buf[200];
9748
9749 snprintf(buf, sizeof(buf), "ndsend 2001:DB8::1 %s", intf);
9750 if (system(buf) != 0) {
9751 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Failed to run "
9752 "ndsend");
9753 return 0;
9754 }
9755
9756 return 1;
9757}
9758
9759
9760static int cmd_sta_send_frame_hs2_neighsolreq(struct sigma_dut *dut,
9761 struct sigma_conn *conn,
9762 struct sigma_cmd *cmd,
9763 const char *intf)
9764{
9765 char buf[200];
9766 const char *ip = get_param(cmd, "SenderIP");
9767
Peng Xu26b356d2017-10-04 17:58:16 -07009768 if (!ip)
9769 return 0;
9770
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009771 snprintf(buf, sizeof(buf), "ndisc6 -nm %s %s -r 4", ip, intf);
9772 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
9773 if (system(buf) == 0) {
9774 sigma_dut_print(dut, DUT_MSG_INFO,
9775 "Neighbor Solicitation got a response "
9776 "for %s@%s", ip, intf);
9777 }
9778
9779 return 1;
9780}
9781
9782
9783static int cmd_sta_send_frame_hs2_arpprobe(struct sigma_dut *dut,
9784 struct sigma_conn *conn,
9785 struct sigma_cmd *cmd,
9786 const char *ifname)
9787{
9788 char buf[200];
9789 const char *ip = get_param(cmd, "SenderIP");
9790
9791 if (ip == NULL) {
9792 send_resp(dut, conn, SIGMA_ERROR,
9793 "ErrorCode,Missing SenderIP parameter");
9794 return 0;
9795 }
9796 snprintf(buf, sizeof(buf), "arping -I %s -D %s -c 4", ifname, ip);
9797 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
9798 if (system(buf) != 0) {
9799 sigma_dut_print(dut, DUT_MSG_INFO, "arping DAD got a response "
9800 "for %s@%s", ip, ifname);
9801 }
9802
9803 return 1;
9804}
9805
9806
9807static int cmd_sta_send_frame_hs2_arpannounce(struct sigma_dut *dut,
9808 struct sigma_conn *conn,
9809 struct sigma_cmd *cmd,
9810 const char *ifname)
9811{
9812 char buf[200];
9813 char ip[16];
9814 int s;
Peng Xub3756882017-10-04 14:39:09 -07009815 struct ifreq ifr;
9816 struct sockaddr_in saddr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009817
9818 s = socket(PF_INET, SOCK_DGRAM, 0);
Peng Xub3756882017-10-04 14:39:09 -07009819 if (s < 0) {
9820 perror("socket");
9821 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009822 }
9823
Peng Xub3756882017-10-04 14:39:09 -07009824 memset(&ifr, 0, sizeof(ifr));
9825 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
9826 if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
9827 sigma_dut_print(dut, DUT_MSG_INFO,
9828 "Failed to get %s IP address: %s",
9829 ifname, strerror(errno));
9830 close(s);
9831 return -1;
9832 }
9833 close(s);
9834
9835 memcpy(&saddr, &ifr.ifr_addr, sizeof(struct sockaddr_in));
9836 strlcpy(ip, inet_ntoa(saddr.sin_addr), sizeof(ip));
9837
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009838 snprintf(buf, sizeof(buf), "arping -I %s -s %s %s -c 4", ifname, ip,
9839 ip);
9840 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
9841 if (system(buf) != 0) {
9842 }
9843
9844 return 1;
9845}
9846
9847
9848static int cmd_sta_send_frame_hs2_arpreply(struct sigma_dut *dut,
9849 struct sigma_conn *conn,
9850 struct sigma_cmd *cmd,
9851 const char *ifname)
9852{
9853 char buf[200], addr[20];
9854 char dst[ETH_ALEN], src[ETH_ALEN];
9855 short ethtype = htons(ETH_P_ARP);
9856 char *pos;
9857 int s, res;
9858 const char *val;
9859 struct sockaddr_in taddr;
9860
9861 val = get_param(cmd, "dest");
9862 if (val)
9863 hwaddr_aton(val, (unsigned char *) dst);
9864
9865 val = get_param(cmd, "DestIP");
9866 if (val)
9867 inet_aton(val, &taddr.sin_addr);
Peng Xu151c9e12017-10-04 14:39:09 -07009868 else
9869 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009870
9871 if (get_wpa_status(get_station_ifname(), "address", addr,
9872 sizeof(addr)) < 0)
9873 return -2;
9874 hwaddr_aton(addr, (unsigned char *) src);
9875
9876 pos = buf;
9877 *pos++ = 0x00;
9878 *pos++ = 0x01;
9879 *pos++ = 0x08;
9880 *pos++ = 0x00;
9881 *pos++ = 0x06;
9882 *pos++ = 0x04;
9883 *pos++ = 0x00;
9884 *pos++ = 0x02;
9885 memcpy(pos, src, ETH_ALEN);
9886 pos += ETH_ALEN;
9887 memcpy(pos, &taddr.sin_addr, 4);
9888 pos += 4;
9889 memcpy(pos, dst, ETH_ALEN);
9890 pos += ETH_ALEN;
9891 memcpy(pos, &taddr.sin_addr, 4);
9892 pos += 4;
9893
9894 s = open_monitor(get_station_ifname());
9895 if (s < 0) {
9896 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
9897 "monitor socket");
9898 return 0;
9899 }
9900
9901 res = inject_eth_frame(s, buf, pos - buf, ethtype, dst, src);
9902 if (res < 0) {
9903 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
9904 "inject frame");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05309905 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009906 return 0;
9907 }
9908
9909 close(s);
9910
9911 return 1;
9912}
9913
9914
9915static int cmd_sta_send_frame_hs2_dls_req(struct sigma_dut *dut,
9916 struct sigma_conn *conn,
9917 struct sigma_cmd *cmd,
9918 const char *intf, const char *dest)
9919{
9920 char buf[100];
9921
9922 if (if_nametoindex("sigmadut") == 0) {
9923 snprintf(buf, sizeof(buf),
9924 "iw dev %s interface add sigmadut type monitor",
9925 get_station_ifname());
9926 if (system(buf) != 0 ||
9927 if_nametoindex("sigmadut") == 0) {
9928 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
9929 "monitor interface with '%s'", buf);
9930 return -2;
9931 }
9932 }
9933
9934 if (system("ifconfig sigmadut up") != 0) {
9935 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
9936 "monitor interface up");
9937 return -2;
9938 }
9939
9940 return sta_inject_frame(dut, conn, DLS_REQ, UNPROTECTED, dest);
9941}
9942
9943
9944static int cmd_sta_send_frame_hs2(struct sigma_dut *dut,
9945 struct sigma_conn *conn,
9946 struct sigma_cmd *cmd)
9947{
9948 const char *intf = get_param(cmd, "Interface");
9949 const char *dest = get_param(cmd, "Dest");
9950 const char *type = get_param(cmd, "FrameName");
9951 const char *val;
9952 char buf[200], *pos, *end;
9953 int count, count2;
9954
9955 if (type == NULL)
9956 type = get_param(cmd, "Type");
9957
9958 if (intf == NULL || dest == NULL || type == NULL)
9959 return -1;
9960
9961 if (strcasecmp(type, "NeighAdv") == 0)
9962 return cmd_sta_send_frame_hs2_neighadv(dut, conn, cmd, intf);
9963
9964 if (strcasecmp(type, "NeighSolicitReq") == 0)
9965 return cmd_sta_send_frame_hs2_neighsolreq(dut, conn, cmd, intf);
9966
9967 if (strcasecmp(type, "ARPProbe") == 0)
9968 return cmd_sta_send_frame_hs2_arpprobe(dut, conn, cmd, intf);
9969
9970 if (strcasecmp(type, "ARPAnnounce") == 0)
9971 return cmd_sta_send_frame_hs2_arpannounce(dut, conn, cmd, intf);
9972
9973 if (strcasecmp(type, "ARPReply") == 0)
9974 return cmd_sta_send_frame_hs2_arpreply(dut, conn, cmd, intf);
9975
9976 if (strcasecmp(type, "DLS-request") == 0 ||
9977 strcasecmp(type, "DLSrequest") == 0)
9978 return cmd_sta_send_frame_hs2_dls_req(dut, conn, cmd, intf,
9979 dest);
9980
9981 if (strcasecmp(type, "ANQPQuery") != 0 &&
9982 strcasecmp(type, "Query") != 0) {
9983 send_resp(dut, conn, SIGMA_ERROR,
9984 "ErrorCode,Unsupported HS 2.0 send frame type");
9985 return 0;
9986 }
9987
9988 if (sta_scan_ap(dut, intf, dest) < 0) {
9989 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not find "
9990 "the requested AP");
9991 return 0;
9992 }
9993
9994 pos = buf;
9995 end = buf + sizeof(buf);
9996 count = 0;
9997 pos += snprintf(pos, end - pos, "ANQP_GET %s ", dest);
9998
9999 val = get_param(cmd, "ANQP_CAP_LIST");
10000 if (val && atoi(val)) {
10001 pos += snprintf(pos, end - pos, "%s257", count > 0 ? "," : "");
10002 count++;
10003 }
10004
10005 val = get_param(cmd, "VENUE_NAME");
10006 if (val && atoi(val)) {
10007 pos += snprintf(pos, end - pos, "%s258", count > 0 ? "," : "");
10008 count++;
10009 }
10010
10011 val = get_param(cmd, "NETWORK_AUTH_TYPE");
10012 if (val && atoi(val)) {
10013 pos += snprintf(pos, end - pos, "%s260", count > 0 ? "," : "");
10014 count++;
10015 }
10016
10017 val = get_param(cmd, "ROAMING_CONS");
10018 if (val && atoi(val)) {
10019 pos += snprintf(pos, end - pos, "%s261", count > 0 ? "," : "");
10020 count++;
10021 }
10022
10023 val = get_param(cmd, "IP_ADDR_TYPE_AVAILABILITY");
10024 if (val && atoi(val)) {
10025 pos += snprintf(pos, end - pos, "%s262", count > 0 ? "," : "");
10026 count++;
10027 }
10028
10029 val = get_param(cmd, "NAI_REALM_LIST");
10030 if (val && atoi(val)) {
10031 pos += snprintf(pos, end - pos, "%s263", count > 0 ? "," : "");
10032 count++;
10033 }
10034
10035 val = get_param(cmd, "3GPP_INFO");
10036 if (val && atoi(val)) {
10037 pos += snprintf(pos, end - pos, "%s264", count > 0 ? "," : "");
10038 count++;
10039 }
10040
10041 val = get_param(cmd, "DOMAIN_LIST");
10042 if (val && atoi(val)) {
10043 pos += snprintf(pos, end - pos, "%s268", count > 0 ? "," : "");
10044 count++;
10045 }
10046
Jouni Malinen34cf9532018-04-29 19:26:33 +030010047 val = get_param(cmd, "Venue_URL");
10048 if (val && atoi(val)) {
10049 pos += snprintf(pos, end - pos, "%s277", count > 0 ? "," : "");
10050 count++;
10051 }
10052
Jouni Malinend3bca5d2018-04-29 17:25:23 +030010053 val = get_param(cmd, "Advice_Of_Charge");
10054 if (val && atoi(val)) {
10055 pos += snprintf(pos, end - pos, "%s278", count > 0 ? "," : "");
10056 count++;
10057 }
10058
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010059 if (count && wpa_command(intf, buf)) {
10060 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,ANQP_GET failed");
10061 return 0;
10062 }
10063
10064 pos = buf;
10065 end = buf + sizeof(buf);
10066 count2 = 0;
10067 pos += snprintf(pos, end - pos, "HS20_ANQP_GET %s ", dest);
10068
10069 val = get_param(cmd, "HS_CAP_LIST");
10070 if (val && atoi(val)) {
10071 pos += snprintf(pos, end - pos, "%s2", count2 > 0 ? "," : "");
10072 count2++;
10073 }
10074
10075 val = get_param(cmd, "OPER_NAME");
10076 if (val && atoi(val)) {
10077 pos += snprintf(pos, end - pos, "%s3", count2 > 0 ? "," : "");
10078 count2++;
10079 }
10080
10081 val = get_param(cmd, "WAN_METRICS");
10082 if (!val)
10083 val = get_param(cmd, "WAN_MAT");
10084 if (!val)
10085 val = get_param(cmd, "WAN_MET");
10086 if (val && atoi(val)) {
10087 pos += snprintf(pos, end - pos, "%s4", count2 > 0 ? "," : "");
10088 count2++;
10089 }
10090
10091 val = get_param(cmd, "CONNECTION_CAPABILITY");
10092 if (val && atoi(val)) {
10093 pos += snprintf(pos, end - pos, "%s5", count2 > 0 ? "," : "");
10094 count2++;
10095 }
10096
10097 val = get_param(cmd, "OP_CLASS");
10098 if (val && atoi(val)) {
10099 pos += snprintf(pos, end - pos, "%s7", count2 > 0 ? "," : "");
10100 count2++;
10101 }
10102
10103 val = get_param(cmd, "OSU_PROVIDER_LIST");
10104 if (val && atoi(val)) {
10105 pos += snprintf(pos, end - pos, "%s8", count2 > 0 ? "," : "");
10106 count2++;
10107 }
10108
Jouni Malinenf67afec2018-04-29 19:24:58 +030010109 val = get_param(cmd, "OPER_ICON_METADATA");
10110 if (!val)
10111 val = get_param(cmd, "OPERATOR_ICON_METADATA");
10112 if (val && atoi(val)) {
10113 pos += snprintf(pos, end - pos, "%s12", count2 > 0 ? "," : "");
10114 count2++;
10115 }
10116
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010117 if (count && count2) {
10118 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before sending out "
10119 "second query");
10120 sleep(1);
10121 }
10122
10123 if (count2 && wpa_command(intf, buf)) {
10124 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,HS20_ANQP_GET "
10125 "failed");
10126 return 0;
10127 }
10128
10129 val = get_param(cmd, "NAI_HOME_REALM_LIST");
10130 if (val) {
10131 if (count || count2) {
10132 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
10133 "sending out second query");
10134 sleep(1);
10135 }
10136
10137 if (strcmp(val, "1") == 0)
10138 val = "mail.example.com";
10139 snprintf(buf, end - pos,
10140 "HS20_GET_NAI_HOME_REALM_LIST %s realm=%s",
10141 dest, val);
10142 if (wpa_command(intf, buf)) {
10143 send_resp(dut, conn, SIGMA_ERROR,
10144 "ErrorCode,HS20_GET_NAI_HOME_REALM_LIST "
10145 "failed");
10146 return 0;
10147 }
10148 }
10149
10150 val = get_param(cmd, "ICON_REQUEST");
10151 if (val) {
10152 if (count || count2) {
10153 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
10154 "sending out second query");
10155 sleep(1);
10156 }
10157
10158 snprintf(buf, end - pos,
10159 "HS20_ICON_REQUEST %s %s", dest, val);
10160 if (wpa_command(intf, buf)) {
10161 send_resp(dut, conn, SIGMA_ERROR,
10162 "ErrorCode,HS20_ICON_REQUEST failed");
10163 return 0;
10164 }
10165 }
10166
10167 return 1;
10168}
10169
10170
10171static int ath_sta_send_frame_vht(struct sigma_dut *dut,
10172 struct sigma_conn *conn,
10173 struct sigma_cmd *cmd)
10174{
10175 const char *val;
10176 char *ifname;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010177 int chwidth, nss;
10178
10179 val = get_param(cmd, "framename");
10180 if (!val)
10181 return -1;
10182 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
10183
10184 /* Command sequence to generate Op mode notification */
10185 if (val && strcasecmp(val, "Op_md_notif_frm") == 0) {
10186 ifname = get_station_ifname();
10187
10188 /* Disable STBC */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010189 run_iwpriv(dut, ifname, "tx_stbc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010190
10191 /* Extract Channel width */
10192 val = get_param(cmd, "Channel_width");
10193 if (val) {
10194 switch (atoi(val)) {
10195 case 20:
10196 chwidth = 0;
10197 break;
10198 case 40:
10199 chwidth = 1;
10200 break;
10201 case 80:
10202 chwidth = 2;
10203 break;
10204 case 160:
10205 chwidth = 3;
10206 break;
10207 default:
10208 chwidth = 2;
10209 break;
10210 }
10211
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010212 run_iwpriv(dut, ifname, "chwidth %d", chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010213 }
10214
10215 /* Extract NSS */
10216 val = get_param(cmd, "NSS");
10217 if (val) {
10218 switch (atoi(val)) {
10219 case 1:
10220 nss = 1;
10221 break;
10222 case 2:
10223 nss = 3;
10224 break;
10225 case 3:
10226 nss = 7;
10227 break;
10228 default:
10229 /* We do not support NSS > 3 */
10230 nss = 3;
10231 break;
10232 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010233 run_iwpriv(dut, ifname, "rxchainmask %d", nss);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010234 }
10235
10236 /* Opmode notify */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010237 run_iwpriv(dut, ifname, "opmode_notify 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010238 }
10239
10240 return 1;
10241}
10242
10243
10244static int cmd_sta_send_frame_vht(struct sigma_dut *dut,
10245 struct sigma_conn *conn,
10246 struct sigma_cmd *cmd)
10247{
10248 switch (get_driver_type()) {
10249 case DRIVER_ATHEROS:
10250 return ath_sta_send_frame_vht(dut, conn, cmd);
10251 default:
10252 send_resp(dut, conn, SIGMA_ERROR,
10253 "errorCode,Unsupported sta_set_frame(VHT) with the current driver");
10254 return 0;
10255 }
10256}
10257
10258
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070010259static int wcn_sta_send_frame_he(struct sigma_dut *dut, struct sigma_conn *conn,
10260 struct sigma_cmd *cmd)
10261{
10262 const char *val;
10263 const char *intf = get_param(cmd, "Interface");
10264
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +030010265 if (!intf)
10266 return -1;
10267
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070010268 val = get_param(cmd, "framename");
10269 if (!val)
10270 return -1;
10271 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
10272
10273 /* Command sequence to generate Op mode notification */
10274 if (val && strcasecmp(val, "action") == 0) {
10275 val = get_param(cmd, "PPDUTxType");
10276 if (val && strcasecmp(val, "TB") == 0) {
10277 if (sta_set_action_tx_in_he_tb_ppdu(dut, intf, 1)) {
10278 sigma_dut_print(dut, DUT_MSG_ERROR,
10279 "failed to send TB PPDU Tx cfg");
10280 send_resp(dut, conn, SIGMA_ERROR,
10281 "ErrorCode,set TB PPDU Tx cfg failed");
10282 return 0;
10283 }
10284 return 1;
10285 }
10286
10287 sigma_dut_print(dut, DUT_MSG_ERROR,
10288 "Action Tx type is not defined");
10289 }
10290
10291 return 1;
10292}
10293
10294
10295static int cmd_sta_send_frame_he(struct sigma_dut *dut,
10296 struct sigma_conn *conn,
10297 struct sigma_cmd *cmd)
10298{
10299 switch (get_driver_type()) {
10300 case DRIVER_WCN:
10301 return wcn_sta_send_frame_he(dut, conn, cmd);
10302 default:
10303 send_resp(dut, conn, SIGMA_ERROR,
10304 "errorCode,Unsupported sta_set_frame(HE) with the current driver");
10305 return 0;
10306 }
10307}
10308
10309
Lior David0fe101e2017-03-09 16:09:50 +020010310#ifdef __linux__
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030010311
10312static int
10313wil6210_send_p2p_frame_60g(struct sigma_dut *dut, struct sigma_cmd *cmd,
10314 const char *frame_name, const char *dest_mac)
10315{
10316 int isprobereq = strcasecmp(frame_name, "probereq") == 0;
10317 const char *ssid = get_param(cmd, "ssid");
10318 const char *countstr = get_param(cmd, "count");
10319 const char *channelstr = get_param(cmd, "channel");
10320 const char *group_id = get_param(cmd, "groupid");
10321 const char *client_id = get_param(cmd, "clientmac");
10322 int count, channel, freq, i;
10323 const char *fname;
10324 char frame[1024], src_mac[20], group_id_attr[25],
10325 device_macstr[3 * ETH_ALEN], client_mac[ETH_ALEN];
10326 const char *group_ssid;
10327 const int group_ssid_prefix_len = 9;
10328 struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *) frame;
10329 size_t framelen = sizeof(frame);
10330 struct template_frame_tag tags[2];
10331 size_t tags_total = ARRAY_SIZE(tags);
10332 int tag_index, len, dst_len;
10333
10334 if (!countstr || !channelstr) {
10335 sigma_dut_print(dut, DUT_MSG_ERROR,
10336 "Missing argument: count, channel");
10337 return -1;
10338 }
10339 if (isprobereq && !ssid) {
10340 sigma_dut_print(dut, DUT_MSG_ERROR,
10341 "Missing argument: ssid");
10342 return -1;
10343 }
10344 if (!isprobereq && (!group_id || !client_id)) {
10345 sigma_dut_print(dut, DUT_MSG_ERROR,
10346 "Missing argument: group_id, client_id");
10347 return -1;
10348 }
10349
10350 count = atoi(countstr);
10351 channel = atoi(channelstr);
10352 freq = channel_to_freq(dut, channel);
10353
10354 if (!freq) {
10355 sigma_dut_print(dut, DUT_MSG_ERROR,
10356 "invalid channel: %s", channelstr);
10357 return -1;
10358 }
10359
10360 if (isprobereq) {
10361 if (strcasecmp(ssid, "wildcard") == 0) {
10362 fname = "probe_req_wildcard.txt";
10363 } else if (strcasecmp(ssid, "P2P_Wildcard") == 0) {
10364 fname = "probe_req_P2P_Wildcard.txt";
10365 } else {
10366 sigma_dut_print(dut, DUT_MSG_ERROR,
10367 "invalid probe request type");
10368 return -1;
10369 }
10370 } else {
10371 fname = "P2P_device_discovery_req.txt";
10372 }
10373
10374 if (parse_template_frame_file(dut, fname, frame, &framelen,
10375 tags, &tags_total)) {
10376 sigma_dut_print(dut, DUT_MSG_ERROR,
10377 "invalid frame template: %s", fname);
10378 return -1;
10379 }
10380
10381 if (get_wpa_status(get_station_ifname(), "address",
10382 src_mac, sizeof(src_mac)) < 0 ||
10383 parse_mac_address(dut, src_mac, &hdr->addr2[0]) ||
10384 parse_mac_address(dut, dest_mac, &hdr->addr1[0]))
10385 return -1;
10386 /* Use wildcard BSSID, since we are in PBSS */
10387 memset(&hdr->addr3, 0xFF, ETH_ALEN);
10388
10389 if (!isprobereq) {
10390 tag_index = find_template_frame_tag(tags, tags_total, 1);
10391 if (tag_index < 0) {
10392 sigma_dut_print(dut, DUT_MSG_ERROR,
10393 "can't find device id attribute");
10394 return -1;
10395 }
10396 if (parse_mac_address(dut, client_id,
10397 (unsigned char *) client_mac)) {
10398 sigma_dut_print(dut, DUT_MSG_ERROR,
10399 "invalid client_id: %s", client_id);
10400 return -1;
10401 }
10402 if (replace_p2p_attribute(dut, &frame[tags[tag_index].offset],
10403 framelen - tags[tag_index].offset,
10404 IEEE80211_P2P_ATTR_DEVICE_ID,
10405 client_mac, ETH_ALEN)) {
10406 sigma_dut_print(dut, DUT_MSG_ERROR,
10407 "fail to replace device id attribute");
10408 return -1;
10409 }
10410
10411 /*
10412 * group_id arg contains device MAC address followed by
10413 * space and SSID (DIRECT-somessid).
10414 * group id attribute contains device address (6 bytes)
10415 * followed by SSID prefix DIRECT-XX (9 bytes)
10416 */
10417 if (strlen(group_id) < sizeof(device_macstr)) {
10418 sigma_dut_print(dut, DUT_MSG_ERROR,
10419 "group_id arg too short");
10420 return -1;
10421 }
10422 memcpy(device_macstr, group_id, sizeof(device_macstr));
10423 device_macstr[sizeof(device_macstr) - 1] = '\0';
10424 if (parse_mac_address(dut, device_macstr,
10425 (unsigned char *) group_id_attr)) {
10426 sigma_dut_print(dut, DUT_MSG_ERROR,
10427 "fail to parse device address from group_id");
10428 return -1;
10429 }
10430 group_ssid = strchr(group_id, ' ');
10431 if (!group_ssid) {
10432 sigma_dut_print(dut, DUT_MSG_ERROR,
10433 "invalid group_id arg, no ssid");
10434 return -1;
10435 }
10436 group_ssid++;
10437 len = strlen(group_ssid);
10438 if (len < group_ssid_prefix_len) {
10439 sigma_dut_print(dut, DUT_MSG_ERROR,
10440 "group_id SSID too short");
10441 return -1;
10442 }
10443 dst_len = sizeof(group_id_attr) - ETH_ALEN;
10444 if (len > dst_len) {
10445 sigma_dut_print(dut, DUT_MSG_ERROR,
10446 "group_id SSID (%s) too long",
10447 group_ssid);
10448 return -1;
10449 }
10450
10451 memcpy(group_id_attr + ETH_ALEN, group_ssid, len);
10452 tag_index = find_template_frame_tag(tags, tags_total, 2);
10453 if (tag_index < 0) {
10454 sigma_dut_print(dut, DUT_MSG_ERROR,
10455 "can't find group id attribute");
10456 return -1;
10457 }
10458 if (replace_p2p_attribute(dut, &frame[tags[tag_index].offset],
10459 framelen - tags[tag_index].offset,
10460 IEEE80211_P2P_ATTR_GROUP_ID,
10461 group_id_attr,
10462 sizeof(group_id_attr))) {
10463 sigma_dut_print(dut, DUT_MSG_ERROR,
10464 "fail to replace group id attribute");
10465 return -1;
10466 }
10467 }
10468
10469 for (i = 0; i < count; i++) {
10470 if (wil6210_transmit_frame(dut, freq,
10471 WIL_TRANSMIT_FRAME_DEFAULT_ROC,
10472 frame, framelen)) {
10473 sigma_dut_print(dut, DUT_MSG_ERROR,
10474 "fail to transmit probe request frame");
10475 return -1;
10476 }
10477 }
10478
10479 return 0;
10480}
10481
10482
Lior David0fe101e2017-03-09 16:09:50 +020010483int wil6210_send_frame_60g(struct sigma_dut *dut, struct sigma_conn *conn,
10484 struct sigma_cmd *cmd)
10485{
10486 const char *frame_name = get_param(cmd, "framename");
10487 const char *mac = get_param(cmd, "dest_mac");
10488
10489 if (!frame_name || !mac) {
10490 sigma_dut_print(dut, DUT_MSG_ERROR,
10491 "framename and dest_mac must be provided");
10492 return -1;
10493 }
10494
10495 if (strcasecmp(frame_name, "brp") == 0) {
10496 const char *l_rx = get_param(cmd, "L-RX");
10497 int l_rx_i;
10498
10499 if (!l_rx) {
10500 sigma_dut_print(dut, DUT_MSG_ERROR,
10501 "L-RX must be provided");
10502 return -1;
10503 }
10504 l_rx_i = atoi(l_rx);
10505
10506 sigma_dut_print(dut, DUT_MSG_INFO,
10507 "dev_send_frame: BRP-RX, dest_mac %s, L-RX %s",
10508 mac, l_rx);
10509 if (l_rx_i != 16) {
10510 sigma_dut_print(dut, DUT_MSG_ERROR,
10511 "unsupported L-RX: %s", l_rx);
10512 return -1;
10513 }
10514
10515 if (wil6210_send_brp_rx(dut, mac, l_rx_i))
10516 return -1;
10517 } else if (strcasecmp(frame_name, "ssw") == 0) {
10518 sigma_dut_print(dut, DUT_MSG_INFO,
10519 "dev_send_frame: SLS, dest_mac %s", mac);
10520 if (wil6210_send_sls(dut, mac))
10521 return -1;
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030010522 } else if ((strcasecmp(frame_name, "probereq") == 0) ||
10523 (strcasecmp(frame_name, "devdiscreq") == 0)) {
10524 sigma_dut_print(dut, DUT_MSG_INFO,
10525 "dev_send_frame: %s, dest_mac %s", frame_name,
10526 mac);
10527 if (wil6210_send_p2p_frame_60g(dut, cmd, frame_name, mac))
10528 return -1;
Lior David0fe101e2017-03-09 16:09:50 +020010529 } else {
10530 sigma_dut_print(dut, DUT_MSG_ERROR,
10531 "unsupported frame type: %s", frame_name);
10532 return -1;
10533 }
10534
10535 return 1;
10536}
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030010537
Lior David0fe101e2017-03-09 16:09:50 +020010538#endif /* __linux__ */
10539
10540
10541static int cmd_sta_send_frame_60g(struct sigma_dut *dut,
10542 struct sigma_conn *conn,
10543 struct sigma_cmd *cmd)
10544{
10545 switch (get_driver_type()) {
10546#ifdef __linux__
10547 case DRIVER_WIL6210:
10548 return wil6210_send_frame_60g(dut, conn, cmd);
10549#endif /* __linux__ */
10550 default:
10551 send_resp(dut, conn, SIGMA_ERROR,
10552 "errorCode,Unsupported sta_set_frame(60G) with the current driver");
10553 return 0;
10554 }
10555}
10556
10557
Ashwini Patildb59b3c2017-04-13 15:19:23 +053010558static int mbo_send_anqp_query(struct sigma_dut *dut, struct sigma_conn *conn,
10559 const char *intf, struct sigma_cmd *cmd)
10560{
10561 const char *val, *addr;
10562 char buf[100];
10563
10564 addr = get_param(cmd, "DestMac");
10565 if (!addr) {
10566 send_resp(dut, conn, SIGMA_INVALID,
10567 "ErrorCode,AP MAC address is missing");
10568 return 0;
10569 }
10570
10571 val = get_param(cmd, "ANQPQuery_ID");
10572 if (!val) {
10573 send_resp(dut, conn, SIGMA_INVALID,
10574 "ErrorCode,Missing ANQPQuery_ID");
10575 return 0;
10576 }
10577
10578 if (strcasecmp(val, "NeighborReportReq") == 0) {
10579 snprintf(buf, sizeof(buf), "ANQP_GET %s 272", addr);
10580 } else if (strcasecmp(val, "QueryListWithCellPref") == 0) {
10581 snprintf(buf, sizeof(buf), "ANQP_GET %s 272,mbo:2", addr);
10582 } else {
10583 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid ANQPQuery_ID: %s",
10584 val);
10585 send_resp(dut, conn, SIGMA_INVALID,
10586 "ErrorCode,Invalid ANQPQuery_ID");
10587 return 0;
10588 }
10589
Ashwini Patild174f2c2017-04-13 16:49:46 +053010590 /* Set gas_address3 field to IEEE 802.11-2012 standard compliant form
10591 * (Address3 = Wildcard BSSID when sent to not-associated AP;
10592 * if associated, AP BSSID).
10593 */
10594 if (wpa_command(intf, "SET gas_address3 1") < 0) {
10595 send_resp(dut, conn, SIGMA_ERROR,
10596 "ErrorCode,Failed to set gas_address3");
10597 return 0;
10598 }
10599
Ashwini Patildb59b3c2017-04-13 15:19:23 +053010600 if (wpa_command(intf, buf) < 0) {
10601 send_resp(dut, conn, SIGMA_ERROR,
10602 "ErrorCode,Failed to send ANQP query");
10603 return 0;
10604 }
10605
10606 return 1;
10607}
10608
10609
10610static int mbo_cmd_sta_send_frame(struct sigma_dut *dut,
10611 struct sigma_conn *conn,
10612 const char *intf,
10613 struct sigma_cmd *cmd)
10614{
10615 const char *val = get_param(cmd, "FrameName");
10616
10617 if (val && strcasecmp(val, "ANQPQuery") == 0)
10618 return mbo_send_anqp_query(dut, conn, intf, cmd);
10619
10620 return 2;
10621}
10622
10623
Jouni Malinenf7222712019-06-13 01:50:21 +030010624enum sigma_cmd_result cmd_sta_send_frame(struct sigma_dut *dut,
10625 struct sigma_conn *conn,
10626 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010627{
10628 const char *intf = get_param(cmd, "Interface");
10629 const char *val;
10630 enum send_frame_type frame;
10631 enum send_frame_protection protected;
10632 char buf[100];
10633 unsigned char addr[ETH_ALEN];
10634 int res;
10635
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +030010636 if (!intf)
10637 return -1;
10638
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010639 val = get_param(cmd, "program");
10640 if (val == NULL)
10641 val = get_param(cmd, "frame");
10642 if (val && strcasecmp(val, "TDLS") == 0)
10643 return cmd_sta_send_frame_tdls(dut, conn, cmd);
10644 if (val && (strcasecmp(val, "HS2") == 0 ||
Jouni Malinen1f6ae642018-06-07 23:56:13 +030010645 strcasecmp(val, "HS2-R2") == 0 ||
10646 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010647 return cmd_sta_send_frame_hs2(dut, conn, cmd);
10648 if (val && strcasecmp(val, "VHT") == 0)
10649 return cmd_sta_send_frame_vht(dut, conn, cmd);
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070010650 if (val && strcasecmp(val, "HE") == 0)
10651 return cmd_sta_send_frame_he(dut, conn, cmd);
priyadharshini gowthamand66913a2016-07-29 15:11:17 -070010652 if (val && strcasecmp(val, "LOC") == 0)
10653 return loc_cmd_sta_send_frame(dut, conn, cmd);
Lior David0fe101e2017-03-09 16:09:50 +020010654 if (val && strcasecmp(val, "60GHz") == 0)
10655 return cmd_sta_send_frame_60g(dut, conn, cmd);
Ashwini Patildb59b3c2017-04-13 15:19:23 +053010656 if (val && strcasecmp(val, "MBO") == 0) {
10657 res = mbo_cmd_sta_send_frame(dut, conn, intf, cmd);
10658 if (res != 2)
10659 return res;
10660 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010661
10662 val = get_param(cmd, "TD_DISC");
10663 if (val) {
10664 if (hwaddr_aton(val, addr) < 0)
10665 return -1;
10666 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", val);
10667 if (wpa_command(intf, buf) < 0) {
10668 send_resp(dut, conn, SIGMA_ERROR,
10669 "ErrorCode,Failed to send TDLS discovery");
10670 return 0;
10671 }
10672 return 1;
10673 }
10674
10675 val = get_param(cmd, "TD_Setup");
10676 if (val) {
10677 if (hwaddr_aton(val, addr) < 0)
10678 return -1;
10679 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", val);
10680 if (wpa_command(intf, buf) < 0) {
10681 send_resp(dut, conn, SIGMA_ERROR,
10682 "ErrorCode,Failed to start TDLS setup");
10683 return 0;
10684 }
10685 return 1;
10686 }
10687
10688 val = get_param(cmd, "TD_TearDown");
10689 if (val) {
10690 if (hwaddr_aton(val, addr) < 0)
10691 return -1;
10692 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", val);
10693 if (wpa_command(intf, buf) < 0) {
10694 send_resp(dut, conn, SIGMA_ERROR,
10695 "ErrorCode,Failed to tear down TDLS link");
10696 return 0;
10697 }
10698 return 1;
10699 }
10700
10701 val = get_param(cmd, "TD_ChannelSwitch");
10702 if (val) {
10703 /* TODO */
10704 send_resp(dut, conn, SIGMA_ERROR,
10705 "ErrorCode,TD_ChannelSwitch not yet supported");
10706 return 0;
10707 }
10708
10709 val = get_param(cmd, "TD_NF");
10710 if (val) {
10711 /* TODO */
10712 send_resp(dut, conn, SIGMA_ERROR,
10713 "ErrorCode,TD_NF not yet supported");
10714 return 0;
10715 }
10716
10717 val = get_param(cmd, "PMFFrameType");
10718 if (val == NULL)
10719 val = get_param(cmd, "FrameName");
10720 if (val == NULL)
10721 val = get_param(cmd, "Type");
10722 if (val == NULL)
10723 return -1;
10724 if (strcasecmp(val, "disassoc") == 0)
10725 frame = DISASSOC;
10726 else if (strcasecmp(val, "deauth") == 0)
10727 frame = DEAUTH;
10728 else if (strcasecmp(val, "saquery") == 0)
10729 frame = SAQUERY;
10730 else if (strcasecmp(val, "auth") == 0)
10731 frame = AUTH;
10732 else if (strcasecmp(val, "assocreq") == 0)
10733 frame = ASSOCREQ;
10734 else if (strcasecmp(val, "reassocreq") == 0)
10735 frame = REASSOCREQ;
10736 else if (strcasecmp(val, "neigreq") == 0) {
10737 sigma_dut_print(dut, DUT_MSG_INFO, "Got neighbor request");
10738
10739 val = get_param(cmd, "ssid");
10740 if (val == NULL)
10741 return -1;
10742
10743 res = send_neighbor_request(dut, intf, val);
10744 if (res) {
10745 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
10746 "Failed to send neighbor report request");
10747 return 0;
10748 }
10749
10750 return 1;
Ashwini Patil5acd7382017-04-13 15:55:04 +053010751 } else if (strcasecmp(val, "transmgmtquery") == 0 ||
10752 strcasecmp(val, "BTMQuery") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010753 sigma_dut_print(dut, DUT_MSG_DEBUG,
10754 "Got Transition Management Query");
10755
Ashwini Patil5acd7382017-04-13 15:55:04 +053010756 res = send_trans_mgmt_query(dut, intf, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010757 if (res) {
10758 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
10759 "Failed to send Transition Management Query");
10760 return 0;
10761 }
10762
10763 return 1;
10764 } else {
10765 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
10766 "PMFFrameType");
10767 return 0;
10768 }
10769
10770 val = get_param(cmd, "PMFProtected");
10771 if (val == NULL)
10772 val = get_param(cmd, "Protected");
10773 if (val == NULL)
10774 return -1;
10775 if (strcasecmp(val, "Correct-key") == 0 ||
10776 strcasecmp(val, "CorrectKey") == 0)
10777 protected = CORRECT_KEY;
10778 else if (strcasecmp(val, "IncorrectKey") == 0)
10779 protected = INCORRECT_KEY;
10780 else if (strcasecmp(val, "Unprotected") == 0)
10781 protected = UNPROTECTED;
10782 else {
10783 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
10784 "PMFProtected");
10785 return 0;
10786 }
10787
10788 if (protected != UNPROTECTED &&
10789 (frame == AUTH || frame == ASSOCREQ || frame == REASSOCREQ)) {
10790 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Impossible "
10791 "PMFProtected for auth/assocreq/reassocreq");
10792 return 0;
10793 }
10794
10795 if (if_nametoindex("sigmadut") == 0) {
10796 snprintf(buf, sizeof(buf),
10797 "iw dev %s interface add sigmadut type monitor",
10798 get_station_ifname());
10799 if (system(buf) != 0 ||
10800 if_nametoindex("sigmadut") == 0) {
10801 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
10802 "monitor interface with '%s'", buf);
10803 return -2;
10804 }
10805 }
10806
10807 if (system("ifconfig sigmadut up") != 0) {
10808 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
10809 "monitor interface up");
10810 return -2;
10811 }
10812
10813 return sta_inject_frame(dut, conn, frame, protected, NULL);
10814}
10815
10816
10817static int cmd_sta_set_parameter_hs2(struct sigma_dut *dut,
10818 struct sigma_conn *conn,
10819 struct sigma_cmd *cmd,
10820 const char *ifname)
10821{
10822 char buf[200];
10823 const char *val;
10824
10825 val = get_param(cmd, "ClearARP");
10826 if (val && atoi(val) == 1) {
10827 snprintf(buf, sizeof(buf), "ip neigh flush dev %s", ifname);
10828 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10829 if (system(buf) != 0) {
10830 send_resp(dut, conn, SIGMA_ERROR,
10831 "errorCode,Failed to clear ARP cache");
10832 return 0;
10833 }
10834 }
10835
10836 return 1;
10837}
10838
10839
10840int cmd_sta_set_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
10841 struct sigma_cmd *cmd)
10842{
10843 const char *intf = get_param(cmd, "Interface");
10844 const char *val;
10845
10846 if (intf == NULL)
10847 return -1;
10848
10849 val = get_param(cmd, "program");
10850 if (val && (strcasecmp(val, "HS2") == 0 ||
Jouni Malinen1f6ae642018-06-07 23:56:13 +030010851 strcasecmp(val, "HS2-R2") == 0 ||
10852 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010853 return cmd_sta_set_parameter_hs2(dut, conn, cmd, intf);
10854
10855 return -1;
10856}
10857
10858
Jouni Malinenf7222712019-06-13 01:50:21 +030010859static enum sigma_cmd_result cmd_sta_set_macaddr(struct sigma_dut *dut,
10860 struct sigma_conn *conn,
10861 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010862{
10863 const char *intf = get_param(cmd, "Interface");
10864 const char *mac = get_param(cmd, "MAC");
10865
10866 if (intf == NULL || mac == NULL)
10867 return -1;
10868
10869 sigma_dut_print(dut, DUT_MSG_INFO, "Change local MAC address for "
10870 "interface %s to %s", intf, mac);
10871
10872 if (dut->set_macaddr) {
10873 char buf[128];
10874 int res;
10875 if (strcasecmp(mac, "default") == 0) {
10876 res = snprintf(buf, sizeof(buf), "%s",
10877 dut->set_macaddr);
10878 dut->tmp_mac_addr = 0;
10879 } else {
10880 res = snprintf(buf, sizeof(buf), "%s %s",
10881 dut->set_macaddr, mac);
10882 dut->tmp_mac_addr = 1;
10883 }
10884 if (res < 0 || res >= (int) sizeof(buf))
10885 return -1;
10886 if (system(buf) != 0) {
10887 send_resp(dut, conn, SIGMA_ERROR,
10888 "errorCode,Failed to set MAC "
10889 "address");
10890 return 0;
10891 }
10892 return 1;
10893 }
10894
10895 if (strcasecmp(mac, "default") == 0)
10896 return 1;
10897
10898 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
10899 "command");
10900 return 0;
10901}
10902
10903
10904static int iwpriv_tdlsoffchnmode(struct sigma_dut *dut,
10905 struct sigma_conn *conn, const char *intf,
10906 int val)
10907{
10908 char buf[200];
10909 int res;
10910
10911 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchnmode %d",
10912 intf, val);
10913 if (res < 0 || res >= (int) sizeof(buf))
10914 return -1;
10915 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10916 if (system(buf) != 0) {
10917 send_resp(dut, conn, SIGMA_ERROR,
10918 "errorCode,Failed to configure offchannel mode");
10919 return 0;
10920 }
10921
10922 return 1;
10923}
10924
10925
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010926static int off_chan_val(enum sec_ch_offset off)
10927{
10928 switch (off) {
10929 case SEC_CH_NO:
10930 return 0;
10931 case SEC_CH_40ABOVE:
10932 return 40;
10933 case SEC_CH_40BELOW:
10934 return -40;
10935 }
10936
10937 return 0;
10938}
10939
10940
10941static int iwpriv_set_offchan(struct sigma_dut *dut, struct sigma_conn *conn,
10942 const char *intf, int off_ch_num,
10943 enum sec_ch_offset sec)
10944{
10945 char buf[200];
10946 int res;
10947
10948 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchan %d",
10949 intf, off_ch_num);
10950 if (res < 0 || res >= (int) sizeof(buf))
10951 return -1;
10952 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10953 if (system(buf) != 0) {
10954 send_resp(dut, conn, SIGMA_ERROR,
10955 "errorCode,Failed to set offchan");
10956 return 0;
10957 }
10958
10959 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsecchnoffst %d",
10960 intf, off_chan_val(sec));
10961 if (res < 0 || res >= (int) sizeof(buf))
10962 return -1;
10963 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10964 if (system(buf) != 0) {
10965 send_resp(dut, conn, SIGMA_ERROR,
10966 "errorCode,Failed to set sec chan offset");
10967 return 0;
10968 }
10969
10970 return 1;
10971}
10972
10973
10974static int tdls_set_offchannel_offset(struct sigma_dut *dut,
10975 struct sigma_conn *conn,
10976 const char *intf, int off_ch_num,
10977 enum sec_ch_offset sec)
10978{
10979 char buf[200];
10980 int res;
10981
10982 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNEL %d",
10983 off_ch_num);
10984 if (res < 0 || res >= (int) sizeof(buf))
10985 return -1;
10986 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10987
10988 if (wpa_command(intf, buf) < 0) {
10989 send_resp(dut, conn, SIGMA_ERROR,
10990 "ErrorCode,Failed to set offchan");
10991 return 0;
10992 }
10993 res = snprintf(buf, sizeof(buf), "DRIVER TDLSSECONDARYCHANNELOFFSET %d",
10994 off_chan_val(sec));
10995 if (res < 0 || res >= (int) sizeof(buf))
10996 return -1;
10997
10998 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10999
11000 if (wpa_command(intf, buf) < 0) {
11001 send_resp(dut, conn, SIGMA_ERROR,
11002 "ErrorCode,Failed to set sec chan offset");
11003 return 0;
11004 }
11005
11006 return 1;
11007}
11008
11009
11010static int tdls_set_offchannel_mode(struct sigma_dut *dut,
11011 struct sigma_conn *conn,
11012 const char *intf, int val)
11013{
11014 char buf[200];
11015 int res;
11016
11017 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNELMODE %d",
11018 val);
11019 if (res < 0 || res >= (int) sizeof(buf))
11020 return -1;
11021 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
11022
11023 if (wpa_command(intf, buf) < 0) {
11024 send_resp(dut, conn, SIGMA_ERROR,
11025 "ErrorCode,Failed to configure offchannel mode");
11026 return 0;
11027 }
11028
11029 return 1;
11030}
11031
11032
11033static int cmd_sta_set_rfeature_tdls(const char *intf, struct sigma_dut *dut,
11034 struct sigma_conn *conn,
11035 struct sigma_cmd *cmd)
11036{
11037 const char *val;
11038 enum {
11039 CHSM_NOT_SET,
11040 CHSM_ENABLE,
11041 CHSM_DISABLE,
11042 CHSM_REJREQ,
11043 CHSM_UNSOLRESP
11044 } chsm = CHSM_NOT_SET;
11045 int off_ch_num = -1;
11046 enum sec_ch_offset sec_ch = SEC_CH_NO;
11047 int res;
11048
11049 val = get_param(cmd, "Uapsd");
11050 if (val) {
11051 char buf[100];
11052 if (strcasecmp(val, "Enable") == 0)
11053 snprintf(buf, sizeof(buf), "SET ps 99");
11054 else if (strcasecmp(val, "Disable") == 0)
11055 snprintf(buf, sizeof(buf), "SET ps 98");
11056 else {
11057 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
11058 "Unsupported uapsd parameter value");
11059 return 0;
11060 }
11061 if (wpa_command(intf, buf)) {
11062 send_resp(dut, conn, SIGMA_ERROR,
11063 "ErrorCode,Failed to change U-APSD "
11064 "powersave mode");
11065 return 0;
11066 }
11067 }
11068
11069 val = get_param(cmd, "TPKTIMER");
11070 if (val && strcasecmp(val, "DISABLE") == 0) {
11071 if (wpa_command(intf, "SET tdls_testing 0x100")) {
11072 send_resp(dut, conn, SIGMA_ERROR,
11073 "ErrorCode,Failed to enable no TPK "
11074 "expiration test mode");
11075 return 0;
11076 }
11077 dut->no_tpk_expiration = 1;
11078 }
11079
11080 val = get_param(cmd, "ChSwitchMode");
11081 if (val) {
11082 if (strcasecmp(val, "Enable") == 0 ||
11083 strcasecmp(val, "Initiate") == 0)
11084 chsm = CHSM_ENABLE;
11085 else if (strcasecmp(val, "Disable") == 0 ||
11086 strcasecmp(val, "passive") == 0)
11087 chsm = CHSM_DISABLE;
11088 else if (strcasecmp(val, "RejReq") == 0)
11089 chsm = CHSM_REJREQ;
11090 else if (strcasecmp(val, "UnSolResp") == 0)
11091 chsm = CHSM_UNSOLRESP;
11092 else {
11093 send_resp(dut, conn, SIGMA_ERROR,
11094 "ErrorCode,Unknown ChSwitchMode value");
11095 return 0;
11096 }
11097 }
11098
11099 val = get_param(cmd, "OffChNum");
11100 if (val) {
11101 off_ch_num = atoi(val);
11102 if (off_ch_num == 0) {
11103 send_resp(dut, conn, SIGMA_ERROR,
11104 "ErrorCode,Invalid OffChNum");
11105 return 0;
11106 }
11107 }
11108
11109 val = get_param(cmd, "SecChOffset");
11110 if (val) {
11111 if (strcmp(val, "20") == 0)
11112 sec_ch = SEC_CH_NO;
11113 else if (strcasecmp(val, "40above") == 0)
11114 sec_ch = SEC_CH_40ABOVE;
11115 else if (strcasecmp(val, "40below") == 0)
11116 sec_ch = SEC_CH_40BELOW;
11117 else {
11118 send_resp(dut, conn, SIGMA_ERROR,
11119 "ErrorCode,Unknown SecChOffset value");
11120 return 0;
11121 }
11122 }
11123
11124 if (chsm == CHSM_NOT_SET) {
11125 /* no offchannel changes requested */
11126 return 1;
11127 }
11128
11129 if (strcmp(intf, get_main_ifname()) != 0 &&
11130 strcmp(intf, get_station_ifname()) != 0) {
11131 send_resp(dut, conn, SIGMA_ERROR,
11132 "ErrorCode,Unknown interface");
11133 return 0;
11134 }
11135
11136 switch (chsm) {
11137 case CHSM_NOT_SET:
Jouni Malinen280f5ba2016-08-29 21:33:10 +030011138 res = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011139 break;
11140 case CHSM_ENABLE:
11141 if (off_ch_num < 0) {
11142 send_resp(dut, conn, SIGMA_ERROR,
11143 "ErrorCode,Missing OffChNum argument");
11144 return 0;
11145 }
11146 if (wifi_chip_type == DRIVER_WCN) {
11147 res = tdls_set_offchannel_offset(dut, conn, intf,
11148 off_ch_num, sec_ch);
11149 } else {
11150 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
11151 sec_ch);
11152 }
11153 if (res != 1)
11154 return res;
11155 if (wifi_chip_type == DRIVER_WCN)
11156 res = tdls_set_offchannel_mode(dut, conn, intf, 1);
11157 else
11158 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 1);
11159 break;
11160 case CHSM_DISABLE:
11161 if (wifi_chip_type == DRIVER_WCN)
11162 res = tdls_set_offchannel_mode(dut, conn, intf, 2);
11163 else
11164 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 2);
11165 break;
11166 case CHSM_REJREQ:
11167 if (wifi_chip_type == DRIVER_WCN)
11168 res = tdls_set_offchannel_mode(dut, conn, intf, 3);
11169 else
11170 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 3);
11171 break;
11172 case CHSM_UNSOLRESP:
11173 if (off_ch_num < 0) {
11174 send_resp(dut, conn, SIGMA_ERROR,
11175 "ErrorCode,Missing OffChNum argument");
11176 return 0;
11177 }
11178 if (wifi_chip_type == DRIVER_WCN) {
11179 res = tdls_set_offchannel_offset(dut, conn, intf,
11180 off_ch_num, sec_ch);
11181 } else {
11182 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
11183 sec_ch);
11184 }
11185 if (res != 1)
11186 return res;
11187 if (wifi_chip_type == DRIVER_WCN)
11188 res = tdls_set_offchannel_mode(dut, conn, intf, 4);
11189 else
11190 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 4);
11191 break;
11192 }
11193
11194 return res;
11195}
11196
11197
11198static int ath_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
11199 struct sigma_conn *conn,
11200 struct sigma_cmd *cmd)
11201{
11202 const char *val;
Srikanth Marepalli5415acf2018-08-27 12:53:11 +053011203 char *token = NULL, *result;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011204
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -070011205 novap_reset(dut, intf, 1);
priyadharshini gowthamane5e25172015-12-08 14:53:48 -080011206
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011207 val = get_param(cmd, "nss_mcs_opt");
11208 if (val) {
11209 /* String (nss_operating_mode; mcs_operating_mode) */
11210 int nss, mcs;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053011211 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011212
11213 token = strdup(val);
11214 if (!token)
11215 return 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053011216 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +053011217 if (!result) {
11218 sigma_dut_print(dut, DUT_MSG_ERROR,
11219 "VHT NSS not specified");
11220 goto failed;
11221 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011222 if (strcasecmp(result, "def") != 0) {
11223 nss = atoi(result);
11224 if (nss == 4)
11225 ath_disable_txbf(dut, intf);
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011226 if (run_iwpriv(dut, intf, "nss %d", nss) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011227 goto failed;
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011228
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011229 }
11230
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053011231 result = strtok_r(NULL, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +053011232 if (!result) {
11233 sigma_dut_print(dut, DUT_MSG_ERROR,
11234 "VHT MCS not specified");
11235 goto failed;
11236 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011237 if (strcasecmp(result, "def") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011238 if (run_iwpriv(dut, intf, "set11NRates 0") < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011239 goto failed;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011240 } else {
11241 mcs = atoi(result);
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011242 if (run_iwpriv(dut, intf, "vhtmcs %d", mcs) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011243 goto failed;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011244 }
11245 /* Channel width gets messed up, fix this */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011246 run_iwpriv(dut, intf, "chwidth %d", dut->chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011247 }
11248
Srikanth Marepalli5415acf2018-08-27 12:53:11 +053011249 free(token);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011250 return 1;
11251failed:
11252 free(token);
11253 return 0;
11254}
11255
11256
11257static int cmd_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
11258 struct sigma_conn *conn,
11259 struct sigma_cmd *cmd)
11260{
11261 switch (get_driver_type()) {
11262 case DRIVER_ATHEROS:
11263 return ath_sta_set_rfeature_vht(intf, dut, conn, cmd);
11264 default:
11265 send_resp(dut, conn, SIGMA_ERROR,
11266 "errorCode,Unsupported sta_set_rfeature(VHT) with the current driver");
11267 return 0;
11268 }
11269}
11270
11271
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011272static int wcn_sta_set_rfeature_he(const char *intf, struct sigma_dut *dut,
11273 struct sigma_conn *conn,
11274 struct sigma_cmd *cmd)
11275{
11276 const char *val;
11277 char *token = NULL, *result;
11278 char buf[60];
11279
11280 val = get_param(cmd, "nss_mcs_opt");
11281 if (val) {
11282 /* String (nss_operating_mode; mcs_operating_mode) */
11283 int nss, mcs, ratecode;
11284 char *saveptr;
11285
11286 token = strdup(val);
11287 if (!token)
11288 return -2;
11289
11290 result = strtok_r(token, ";", &saveptr);
11291 if (!result) {
11292 sigma_dut_print(dut, DUT_MSG_ERROR,
11293 "HE NSS not specified");
11294 goto failed;
11295 }
11296 nss = 1;
11297 if (strcasecmp(result, "def") != 0)
11298 nss = atoi(result);
11299
11300 result = strtok_r(NULL, ";", &saveptr);
11301 if (!result) {
11302 sigma_dut_print(dut, DUT_MSG_ERROR,
11303 "HE MCS not specified");
11304 goto failed;
11305 }
11306 mcs = 7;
11307 if (strcasecmp(result, "def") != 0)
11308 mcs = atoi(result);
11309
Arif Hussain557bf412018-05-25 17:29:36 -070011310 ratecode = 0x20; /* for nss:1 MCS 0 */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011311 if (nss == 2) {
Arif Hussain557bf412018-05-25 17:29:36 -070011312 ratecode = 0x40; /* for nss:2 MCS 0 */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011313 } else if (nss > 2) {
11314 sigma_dut_print(dut, DUT_MSG_ERROR,
11315 "HE NSS %d not supported", nss);
11316 goto failed;
11317 }
11318
Arif Hussain557bf412018-05-25 17:29:36 -070011319 snprintf(buf, sizeof(buf), "iwpriv %s nss %d", intf, nss);
11320 if (system(buf) != 0) {
11321 sigma_dut_print(dut, DUT_MSG_ERROR,
11322 "nss_mcs_opt: iwpriv %s nss %d failed",
11323 intf, nss);
11324 goto failed;
11325 }
Arif Hussainac6c5112018-05-25 17:34:00 -070011326 dut->sta_nss = nss;
Arif Hussain557bf412018-05-25 17:29:36 -070011327
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011328 /* Add the MCS to the ratecode */
11329 if (mcs >= 0 && mcs <= 11) {
11330 ratecode += mcs;
Arif Hussain557bf412018-05-25 17:29:36 -070011331#ifdef NL80211_SUPPORT
11332 if (dut->device_type == STA_testbed) {
11333 enum he_mcs_config mcs_config;
11334 int ret;
11335
11336 if (mcs <= 7)
11337 mcs_config = HE_80_MCS0_7;
11338 else if (mcs <= 9)
11339 mcs_config = HE_80_MCS0_9;
11340 else
11341 mcs_config = HE_80_MCS0_11;
11342 ret = sta_set_he_mcs(dut, intf, mcs_config);
11343 if (ret) {
11344 sigma_dut_print(dut, DUT_MSG_ERROR,
11345 "nss_mcs_opt: mcs setting failed, mcs:%d, mcs_config %d, ret:%d",
11346 mcs, mcs_config, ret);
11347 goto failed;
11348 }
11349 }
11350#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011351 } else {
11352 sigma_dut_print(dut, DUT_MSG_ERROR,
11353 "HE MCS %d not supported", mcs);
11354 goto failed;
11355 }
11356 snprintf(buf, sizeof(buf), "iwpriv %s set_11ax_rate 0x%03x",
11357 intf, ratecode);
11358 if (system(buf) != 0) {
11359 sigma_dut_print(dut, DUT_MSG_ERROR,
11360 "iwpriv setting of 11ax rates failed");
11361 goto failed;
11362 }
11363 free(token);
11364 }
11365
11366 val = get_param(cmd, "GI");
11367 if (val) {
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011368 int fix_rate_sgi;
11369
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011370 if (strcmp(val, "0.8") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070011371 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 9", intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011372 fix_rate_sgi = 1;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011373 } else if (strcmp(val, "1.6") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070011374 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 10",
11375 intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011376 fix_rate_sgi = 2;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011377 } else if (strcmp(val, "3.2") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070011378 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 11",
11379 intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011380 fix_rate_sgi = 3;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011381 } else {
11382 send_resp(dut, conn, SIGMA_ERROR,
11383 "errorCode,GI value not supported");
11384 return 0;
11385 }
11386 if (system(buf) != 0) {
11387 send_resp(dut, conn, SIGMA_ERROR,
11388 "errorCode,Failed to set shortgi");
11389 return 0;
11390 }
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011391 snprintf(buf, sizeof(buf), "iwpriv %s shortgi %d",
11392 intf, fix_rate_sgi);
11393 if (system(buf) != 0) {
11394 send_resp(dut, conn, SIGMA_ERROR,
11395 "errorCode,Failed to set fix rate shortgi");
11396 return STATUS_SENT;
11397 }
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011398 }
11399
Subhani Shaik8e7a3052018-04-24 14:03:00 -070011400 val = get_param(cmd, "LTF");
11401 if (val) {
11402#ifdef NL80211_SUPPORT
11403 if (strcmp(val, "3.2") == 0) {
11404 sta_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_1X);
11405 } if (strcmp(val, "6.4") == 0) {
11406 sta_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_2X);
11407 } else if (strcmp(val, "12.8") == 0) {
11408 sta_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_4X);
11409 } else {
11410 send_resp(dut, conn, SIGMA_ERROR,
11411 "errorCode, LTF value not supported");
11412 return 0;
11413 }
11414#else /* NL80211_SUPPORT */
11415 sigma_dut_print(dut, DUT_MSG_ERROR,
11416 "LTF cannot be set without NL80211_SUPPORT defined");
11417 return -2;
11418#endif /* NL80211_SUPPORT */
11419 }
11420
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -070011421 val = get_param(cmd, "TxSUPPDU");
11422 if (val) {
11423 int set_val = 1;
11424
11425 if (strcasecmp(val, "Enable") == 0)
11426 set_val = 1;
11427 else if (strcasecmp(val, "Disable") == 0)
11428 set_val = 0;
11429
11430 if (sta_set_tx_su_ppdu_cfg(dut, intf, set_val)) {
11431 send_resp(dut, conn, SIGMA_ERROR,
11432 "ErrorCode,Failed to set Tx SU PPDU config");
11433 return 0;
11434 }
11435 }
11436
Arif Hussain480d5f42019-03-12 14:40:42 -070011437 val = get_param(cmd, "TWT_Setup");
11438 if (val) {
11439 if (strcasecmp(val, "Request") == 0) {
11440 if (sta_twt_request(dut, conn, cmd)) {
11441 send_resp(dut, conn, SIGMA_ERROR,
11442 "ErrorCode,sta_twt_request failed");
11443 return STATUS_SENT;
11444 }
11445 } else if (strcasecmp(val, "Teardown") == 0) {
11446 if (sta_twt_teardown(dut, conn, cmd)) {
11447 send_resp(dut, conn, SIGMA_ERROR,
11448 "ErrorCode,sta_twt_teardown failed");
11449 return STATUS_SENT;
11450 }
11451 }
11452 }
11453
Kiran Kumar Lokere50eb2cd2018-12-18 18:31:28 -080011454 val = get_param(cmd, "transmitOMI");
11455 if (val && sta_transmit_omi(dut, conn, cmd)) {
11456 send_resp(dut, conn, SIGMA_ERROR,
11457 "ErrorCode,sta_transmit_omi failed");
11458 return STATUS_SENT;
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -070011459 }
11460
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080011461 val = get_param(cmd, "Powersave");
11462 if (val) {
11463 char buf[60];
11464
11465 if (strcasecmp(val, "off") == 0) {
11466 snprintf(buf, sizeof(buf),
11467 "iwpriv %s setPower 2", intf);
11468 if (system(buf) != 0) {
11469 sigma_dut_print(dut, DUT_MSG_ERROR,
11470 "iwpriv setPower 2 failed");
11471 return 0;
11472 }
11473 } else if (strcasecmp(val, "on") == 0) {
11474 snprintf(buf, sizeof(buf),
11475 "iwpriv %s setPower 1", intf);
11476 if (system(buf) != 0) {
11477 sigma_dut_print(dut, DUT_MSG_ERROR,
11478 "iwpriv setPower 1 failed");
11479 return 0;
11480 }
11481 } else {
11482 sigma_dut_print(dut, DUT_MSG_ERROR,
11483 "Unsupported Powersave value '%s'",
11484 val);
11485 return -1;
11486 }
11487 }
11488
Kiran Kumar Lokere2c4b7ce2019-01-30 12:02:28 -080011489 val = get_param(cmd, "MU_EDCA");
11490 if (val) {
11491 if (strcasecmp(val, "Override") == 0) {
11492 if (sta_set_mu_edca_override(dut, intf, 1)) {
11493 send_resp(dut, conn, SIGMA_ERROR,
11494 "errorCode,MU EDCA override set failed");
11495 return STATUS_SENT;
11496 }
11497 } else if (strcasecmp(val, "Disable") == 0) {
11498 if (sta_set_mu_edca_override(dut, intf, 0)) {
11499 send_resp(dut, conn, SIGMA_ERROR,
11500 "errorCode,MU EDCA override disable failed");
11501 return STATUS_SENT;
11502 }
11503 }
11504 }
11505
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011506 return 1;
11507
11508failed:
11509 free(token);
11510 return -2;
11511}
11512
11513
11514static int cmd_sta_set_rfeature_he(const char *intf, struct sigma_dut *dut,
11515 struct sigma_conn *conn,
11516 struct sigma_cmd *cmd)
11517{
11518 switch (get_driver_type()) {
11519 case DRIVER_WCN:
11520 return wcn_sta_set_rfeature_he(intf, dut, conn, cmd);
11521 default:
11522 send_resp(dut, conn, SIGMA_ERROR,
11523 "errorCode,Unsupported sta_set_rfeature(HE) with the current driver");
11524 return 0;
11525 }
11526}
11527
11528
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080011529static int cmd_sta_set_power_save_he(const char *intf, struct sigma_dut *dut,
11530 struct sigma_conn *conn,
11531 struct sigma_cmd *cmd)
11532{
11533 const char *val;
11534
11535 val = get_param(cmd, "powersave");
11536 if (val) {
11537 char buf[60];
11538
11539 if (strcasecmp(val, "off") == 0) {
11540 snprintf(buf, sizeof(buf), "iwpriv %s setPower 2",
11541 intf);
11542 if (system(buf) != 0) {
11543 sigma_dut_print(dut, DUT_MSG_ERROR,
11544 "iwpriv setPower 2 failed");
11545 return 0;
11546 }
11547 } else if (strcasecmp(val, "on") == 0) {
11548 snprintf(buf, sizeof(buf), "iwpriv %s setPower 1",
11549 intf);
11550 if (system(buf) != 0) {
11551 sigma_dut_print(dut, DUT_MSG_ERROR,
11552 "iwpriv setPower 1 failed");
11553 return 0;
11554 }
11555 } else {
11556 sigma_dut_print(dut, DUT_MSG_ERROR,
11557 "Unsupported power save config");
11558 return -1;
11559 }
11560 return 1;
11561 }
11562
11563 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported command");
11564
11565 return 0;
11566}
11567
11568
Ashwini Patil5acd7382017-04-13 15:55:04 +053011569static int btm_query_candidate_list(struct sigma_dut *dut,
11570 struct sigma_conn *conn,
11571 struct sigma_cmd *cmd)
11572{
11573 const char *bssid, *info, *op_class, *ch, *phy_type, *pref;
11574 int len, ret;
11575 char buf[10];
11576
11577 /*
11578 * Neighbor Report elements format:
11579 * neighbor=<BSSID>,<BSSID Information>,<Operating Class>,
11580 * <Channel Number>,<PHY Type>[,<hexdump of Optional Subelements>]
11581 * eg: neighbor=aa:bb:cc:dd:ee:ff,17,81,6,1,030101
11582 */
11583
11584 bssid = get_param(cmd, "Nebor_BSSID");
11585 if (!bssid) {
11586 send_resp(dut, conn, SIGMA_INVALID,
11587 "errorCode,Nebor_BSSID is missing");
11588 return 0;
11589 }
11590
11591 info = get_param(cmd, "Nebor_Bssid_Info");
11592 if (!info) {
11593 sigma_dut_print(dut, DUT_MSG_INFO,
11594 "Using default value for Nebor_Bssid_Info: %s",
11595 DEFAULT_NEIGHBOR_BSSID_INFO);
11596 info = DEFAULT_NEIGHBOR_BSSID_INFO;
11597 }
11598
11599 op_class = get_param(cmd, "Nebor_Op_Class");
11600 if (!op_class) {
11601 send_resp(dut, conn, SIGMA_INVALID,
11602 "errorCode,Nebor_Op_Class is missing");
11603 return 0;
11604 }
11605
11606 ch = get_param(cmd, "Nebor_Op_Ch");
11607 if (!ch) {
11608 send_resp(dut, conn, SIGMA_INVALID,
11609 "errorCode,Nebor_Op_Ch is missing");
11610 return 0;
11611 }
11612
11613 phy_type = get_param(cmd, "Nebor_Phy_Type");
11614 if (!phy_type) {
11615 sigma_dut_print(dut, DUT_MSG_INFO,
11616 "Using default value for Nebor_Phy_Type: %s",
11617 DEFAULT_NEIGHBOR_PHY_TYPE);
11618 phy_type = DEFAULT_NEIGHBOR_PHY_TYPE;
11619 }
11620
11621 /* Parse optional subelements */
11622 buf[0] = '\0';
11623 pref = get_param(cmd, "Nebor_Pref");
11624 if (pref) {
11625 /* hexdump for preferrence subelement */
11626 ret = snprintf(buf, sizeof(buf), ",0301%02x", atoi(pref));
11627 if (ret < 0 || ret >= (int) sizeof(buf)) {
11628 sigma_dut_print(dut, DUT_MSG_ERROR,
11629 "snprintf failed for optional subelement ret: %d",
11630 ret);
11631 send_resp(dut, conn, SIGMA_ERROR,
11632 "errorCode,snprintf failed for subelement");
11633 return 0;
11634 }
11635 }
11636
11637 if (!dut->btm_query_cand_list) {
11638 dut->btm_query_cand_list = calloc(1, NEIGHBOR_REPORT_SIZE);
11639 if (!dut->btm_query_cand_list) {
11640 send_resp(dut, conn, SIGMA_ERROR,
11641 "errorCode,Failed to allocate memory for btm_query_cand_list");
11642 return 0;
11643 }
11644 }
11645
11646 len = strlen(dut->btm_query_cand_list);
11647 ret = snprintf(dut->btm_query_cand_list + len,
11648 NEIGHBOR_REPORT_SIZE - len, " neighbor=%s,%s,%s,%s,%s%s",
11649 bssid, info, op_class, ch, phy_type, buf);
11650 if (ret < 0 || ret >= NEIGHBOR_REPORT_SIZE - len) {
11651 sigma_dut_print(dut, DUT_MSG_ERROR,
11652 "snprintf failed for neighbor report list ret: %d",
11653 ret);
11654 send_resp(dut, conn, SIGMA_ERROR,
11655 "errorCode,snprintf failed for neighbor report");
11656 free(dut->btm_query_cand_list);
11657 dut->btm_query_cand_list = NULL;
11658 return 0;
11659 }
11660
11661 return 1;
11662}
11663
11664
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020011665int sta_extract_60g_ese(struct sigma_dut *dut, struct sigma_cmd *cmd,
11666 struct sigma_ese_alloc *allocs, int *allocs_size)
11667{
11668 int max_count = *allocs_size;
11669 int count = 0, i;
11670 const char *val;
11671
11672 do {
11673 val = get_param_indexed(cmd, "AllocID", count);
11674 if (val)
11675 count++;
11676 } while (val);
11677
11678 if (count == 0 || count > max_count) {
11679 sigma_dut_print(dut, DUT_MSG_ERROR,
11680 "Invalid number of allocations(%d)", count);
11681 return -1;
11682 }
11683
11684 for (i = 0; i < count; i++) {
11685 val = get_param_indexed(cmd, "PercentBI", i);
11686 if (!val) {
11687 sigma_dut_print(dut, DUT_MSG_ERROR,
11688 "Missing PercentBI parameter at index %d",
11689 i);
11690 return -1;
11691 }
11692 allocs[i].percent_bi = atoi(val);
11693
11694 val = get_param_indexed(cmd, "SrcAID", i);
11695 if (val)
11696 allocs[i].src_aid = strtol(val, NULL, 0);
11697 else
11698 allocs[i].src_aid = ESE_BCAST_AID;
11699
11700 val = get_param_indexed(cmd, "DestAID", i);
11701 if (val)
11702 allocs[i].dst_aid = strtol(val, NULL, 0);
11703 else
11704 allocs[i].dst_aid = ESE_BCAST_AID;
11705
11706 allocs[i].type = ESE_CBAP;
11707 sigma_dut_print(dut, DUT_MSG_INFO,
11708 "Alloc %d PercentBI %d SrcAID %d DstAID %d",
11709 i, allocs[i].percent_bi, allocs[i].src_aid,
11710 allocs[i].dst_aid);
11711 }
11712
11713 *allocs_size = count;
11714 return 0;
11715}
11716
11717
11718static int sta_set_60g_ese(struct sigma_dut *dut, int count,
11719 struct sigma_ese_alloc *allocs)
11720{
11721 switch (get_driver_type()) {
11722#ifdef __linux__
11723 case DRIVER_WIL6210:
11724 if (wil6210_set_ese(dut, count, allocs))
11725 return -1;
11726 return 1;
11727#endif /* __linux__ */
11728 default:
11729 sigma_dut_print(dut, DUT_MSG_ERROR,
11730 "Unsupported sta_set_60g_ese with the current driver");
11731 return -1;
11732 }
11733}
11734
11735
11736static int cmd_sta_set_rfeature_60g(const char *intf, struct sigma_dut *dut,
11737 struct sigma_conn *conn,
11738 struct sigma_cmd *cmd)
11739{
11740 const char *val;
11741
11742 val = get_param(cmd, "ExtSchIE");
11743 if (val && !strcasecmp(val, "Enable")) {
11744 struct sigma_ese_alloc allocs[MAX_ESE_ALLOCS];
11745 int count = MAX_ESE_ALLOCS;
11746
11747 if (sta_extract_60g_ese(dut, cmd, allocs, &count))
11748 return -1;
11749 return sta_set_60g_ese(dut, count, allocs);
11750 }
11751
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +020011752 val = get_param(cmd, "MCS_FixedRate");
11753 if (val) {
11754 int sta_mcs = atoi(val);
11755
11756 sigma_dut_print(dut, DUT_MSG_INFO, "Force STA MCS to %d",
11757 sta_mcs);
11758 wil6210_set_force_mcs(dut, 1, sta_mcs);
11759
Jouni Malinen0e29cf22019-02-19 01:13:21 +020011760 return SUCCESS_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +020011761 }
11762
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020011763 send_resp(dut, conn, SIGMA_ERROR,
11764 "errorCode,Invalid sta_set_rfeature(60G)");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020011765 return STATUS_SENT;
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020011766}
11767
11768
Jouni Malinenf7222712019-06-13 01:50:21 +030011769static enum sigma_cmd_result cmd_sta_set_rfeature(struct sigma_dut *dut,
11770 struct sigma_conn *conn,
11771 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011772{
11773 const char *intf = get_param(cmd, "Interface");
11774 const char *prog = get_param(cmd, "Prog");
Ashwini Patil68d02cd2017-01-10 15:39:16 +053011775 const char *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011776
11777 if (intf == NULL || prog == NULL)
11778 return -1;
11779
Ashwini Patil5acd7382017-04-13 15:55:04 +053011780 /* BSS Transition candidate list for BTM query */
11781 val = get_param(cmd, "Nebor_BSSID");
11782 if (val && btm_query_candidate_list(dut, conn, cmd) == 0)
11783 return 0;
11784
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011785 if (strcasecmp(prog, "TDLS") == 0)
11786 return cmd_sta_set_rfeature_tdls(intf, dut, conn, cmd);
11787
11788 if (strcasecmp(prog, "VHT") == 0)
11789 return cmd_sta_set_rfeature_vht(intf, dut, conn, cmd);
11790
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011791 if (strcasecmp(prog, "HE") == 0)
11792 return cmd_sta_set_rfeature_he(intf, dut, conn, cmd);
11793
Ashwini Patil68d02cd2017-01-10 15:39:16 +053011794 if (strcasecmp(prog, "MBO") == 0) {
11795 val = get_param(cmd, "Cellular_Data_Cap");
11796 if (val &&
11797 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
11798 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +053011799
11800 val = get_param(cmd, "Ch_Pref");
11801 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
11802 return 0;
11803
Ashwini Patil68d02cd2017-01-10 15:39:16 +053011804 return 1;
11805 }
11806
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020011807 if (strcasecmp(prog, "60GHz") == 0)
11808 return cmd_sta_set_rfeature_60g(intf, dut, conn, cmd);
11809
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011810 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported Prog");
11811 return 0;
11812}
11813
11814
Jouni Malinenf7222712019-06-13 01:50:21 +030011815static enum sigma_cmd_result cmd_sta_set_radio(struct sigma_dut *dut,
11816 struct sigma_conn *conn,
11817 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011818{
11819 const char *intf = get_param(cmd, "Interface");
11820 const char *mode = get_param(cmd, "Mode");
11821 int res;
11822
11823 if (intf == NULL || mode == NULL)
11824 return -1;
11825
11826 if (strcasecmp(mode, "On") == 0)
11827 res = wpa_command(intf, "SET radio_disabled 0");
11828 else if (strcasecmp(mode, "Off") == 0)
11829 res = wpa_command(intf, "SET radio_disabled 1");
11830 else
11831 return -1;
11832
11833 if (res) {
11834 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
11835 "radio mode");
11836 return 0;
11837 }
11838
11839 return 1;
11840}
11841
11842
Jouni Malinenf7222712019-06-13 01:50:21 +030011843static enum sigma_cmd_result cmd_sta_set_pwrsave(struct sigma_dut *dut,
11844 struct sigma_conn *conn,
11845 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011846{
11847 const char *intf = get_param(cmd, "Interface");
11848 const char *mode = get_param(cmd, "Mode");
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020011849 const char *prog = get_param(cmd, "program");
11850 const char *powersave = get_param(cmd, "powersave");
11851 int res = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011852
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020011853 if (intf == NULL)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011854 return -1;
11855
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020011856 if (prog && strcasecmp(prog, "60GHz") == 0) {
11857 /*
11858 * The CAPI mode parameter does not exist in 60G
11859 * unscheduled PS.
11860 */
Hu Wang5dc3ff12019-06-14 15:14:26 +080011861 if (powersave && strcasecmp(powersave, "unscheduled") == 0)
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020011862 res = set_ps(intf, dut, 1);
Alexei Avshalom Lazar2f6fdb42019-02-04 14:16:08 +020011863 } else if (prog && get_driver_type() == DRIVER_WCN &&
11864 strcasecmp(prog, "HE") == 0) {
11865 return cmd_sta_set_power_save_he(intf, dut, conn, cmd);
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020011866 } else {
11867 if (mode == NULL)
11868 return -1;
11869
11870 if (strcasecmp(mode, "On") == 0)
11871 res = set_ps(intf, dut, 1);
11872 else if (strcasecmp(mode, "Off") == 0)
11873 res = set_ps(intf, dut, 0);
11874 else
11875 return -1;
11876 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011877
11878 if (res) {
11879 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
11880 "power save mode");
11881 return 0;
11882 }
11883
11884 return 1;
11885}
11886
11887
Jouni Malinenf7222712019-06-13 01:50:21 +030011888static enum sigma_cmd_result cmd_sta_bssid_pool(struct sigma_dut *dut,
11889 struct sigma_conn *conn,
11890 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011891{
11892 const char *intf = get_param(cmd, "Interface");
11893 const char *val, *bssid;
11894 int res;
11895 char *buf;
11896 size_t buf_len;
11897
11898 val = get_param(cmd, "BSSID_FILTER");
11899 if (val == NULL)
11900 return -1;
11901
11902 bssid = get_param(cmd, "BSSID_List");
11903 if (atoi(val) == 0 || bssid == NULL) {
11904 /* Disable BSSID filter */
11905 if (wpa_command(intf, "SET bssid_filter ")) {
11906 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed "
11907 "to disable BSSID filter");
11908 return 0;
11909 }
11910
11911 return 1;
11912 }
11913
11914 buf_len = 100 + strlen(bssid);
11915 buf = malloc(buf_len);
11916 if (buf == NULL)
11917 return -1;
11918
11919 snprintf(buf, buf_len, "SET bssid_filter %s", bssid);
11920 res = wpa_command(intf, buf);
11921 free(buf);
11922 if (res) {
11923 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to enable "
11924 "BSSID filter");
11925 return 0;
11926 }
11927
11928 return 1;
11929}
11930
11931
Jouni Malinenf7222712019-06-13 01:50:21 +030011932static enum sigma_cmd_result cmd_sta_reset_parm(struct sigma_dut *dut,
11933 struct sigma_conn *conn,
11934 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011935{
11936 const char *intf = get_param(cmd, "Interface");
11937 const char *val;
11938
11939 /* TODO: ARP */
11940
11941 val = get_param(cmd, "HS2_CACHE_PROFILE");
11942 if (val && strcasecmp(val, "All") == 0)
11943 hs2_clear_credentials(intf);
11944
11945 return 1;
11946}
11947
11948
Jouni Malinenf7222712019-06-13 01:50:21 +030011949static enum sigma_cmd_result cmd_sta_get_key(struct sigma_dut *dut,
11950 struct sigma_conn *conn,
11951 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011952{
11953 const char *intf = get_param(cmd, "Interface");
11954 const char *key_type = get_param(cmd, "KeyType");
11955 char buf[100], resp[200];
11956
11957 if (key_type == NULL)
11958 return -1;
11959
11960 if (strcasecmp(key_type, "GTK") == 0) {
11961 if (wpa_command_resp(intf, "GET gtk", buf, sizeof(buf)) < 0 ||
11962 strncmp(buf, "FAIL", 4) == 0) {
11963 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
11964 "not fetch current GTK");
11965 return 0;
11966 }
11967 snprintf(resp, sizeof(resp), "KeyValue,%s", buf);
11968 send_resp(dut, conn, SIGMA_COMPLETE, resp);
11969 return 0;
11970 } else {
11971 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
11972 "KeyType");
11973 return 0;
11974 }
11975
11976 return 1;
11977}
11978
11979
11980static int hs2_set_policy(struct sigma_dut *dut)
11981{
11982#ifdef ANDROID
11983 system("ip rule del prio 23000");
11984 if (system("ip rule add from all lookup main prio 23000") != 0) {
11985 sigma_dut_print(dut, DUT_MSG_ERROR,
11986 "Failed to run:ip rule add from all lookup main prio");
11987 return -1;
11988 }
11989 if (system("ip route flush cache") != 0) {
11990 sigma_dut_print(dut, DUT_MSG_ERROR,
11991 "Failed to run ip route flush cache");
11992 return -1;
11993 }
11994 return 1;
11995#else /* ANDROID */
11996 return 0;
11997#endif /* ANDROID */
11998}
11999
12000
Jouni Malinenf7222712019-06-13 01:50:21 +030012001static enum sigma_cmd_result cmd_sta_hs2_associate(struct sigma_dut *dut,
12002 struct sigma_conn *conn,
12003 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012004{
12005 const char *intf = get_param(cmd, "Interface");
12006 const char *val = get_param(cmd, "Ignore_blacklist");
Jouni Malinen439352d2018-09-13 03:42:23 +030012007 const char *band = get_param(cmd, "Band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012008 struct wpa_ctrl *ctrl;
Jouni Malinen3aa72862019-05-29 23:14:51 +030012009 int res, r;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012010 char bssid[20], ssid[40], resp[100], buf[100], blacklisted[100];
12011 int tries = 0;
12012 int ignore_blacklist = 0;
12013 const char *events[] = {
12014 "CTRL-EVENT-CONNECTED",
12015 "INTERWORKING-BLACKLISTED",
12016 "INTERWORKING-NO-MATCH",
12017 NULL
12018 };
12019
12020 start_sta_mode(dut);
12021
Jouni Malinen439352d2018-09-13 03:42:23 +030012022 if (band) {
12023 if (strcmp(band, "2.4") == 0) {
12024 wpa_command(intf, "SET setband 2G");
12025 } else if (strcmp(band, "5") == 0) {
12026 wpa_command(intf, "SET setband 5G");
12027 } else {
12028 send_resp(dut, conn, SIGMA_ERROR,
12029 "errorCode,Unsupported band");
12030 return 0;
12031 }
12032 }
12033
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012034 blacklisted[0] = '\0';
12035 if (val && atoi(val))
12036 ignore_blacklist = 1;
12037
12038try_again:
12039 ctrl = open_wpa_mon(intf);
12040 if (ctrl == NULL) {
12041 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
12042 "wpa_supplicant monitor connection");
12043 return -2;
12044 }
12045
12046 tries++;
12047 if (wpa_command(intf, "INTERWORKING_SELECT auto")) {
12048 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start "
12049 "Interworking connection");
12050 wpa_ctrl_detach(ctrl);
12051 wpa_ctrl_close(ctrl);
12052 return 0;
12053 }
12054
12055 buf[0] = '\0';
12056 while (1) {
12057 char *pos;
12058 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
12059 pos = strstr(buf, "INTERWORKING-BLACKLISTED");
12060 if (!pos)
12061 break;
12062 pos += 25;
12063 sigma_dut_print(dut, DUT_MSG_DEBUG, "Found blacklisted AP: %s",
12064 pos);
12065 if (!blacklisted[0])
12066 memcpy(blacklisted, pos, strlen(pos) + 1);
12067 }
12068
12069 if (ignore_blacklist && blacklisted[0]) {
12070 char *end;
12071 end = strchr(blacklisted, ' ');
12072 if (end)
12073 *end = '\0';
12074 sigma_dut_print(dut, DUT_MSG_DEBUG, "Try to connect to a blacklisted network: %s",
12075 blacklisted);
Jouni Malinen3aa72862019-05-29 23:14:51 +030012076 r = snprintf(buf, sizeof(buf), "INTERWORKING_CONNECT %s",
12077 blacklisted);
12078 if (r < 0 || r >= sizeof(buf) || wpa_command(intf, buf)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012079 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start Interworking connection to blacklisted network");
12080 wpa_ctrl_detach(ctrl);
12081 wpa_ctrl_close(ctrl);
12082 return 0;
12083 }
12084 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
12085 buf, sizeof(buf));
12086 }
12087
12088 wpa_ctrl_detach(ctrl);
12089 wpa_ctrl_close(ctrl);
12090
12091 if (res < 0) {
12092 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
12093 "connect");
12094 return 0;
12095 }
12096
12097 if (strstr(buf, "INTERWORKING-NO-MATCH") ||
12098 strstr(buf, "INTERWORKING-BLACKLISTED")) {
12099 if (tries < 2) {
12100 sigma_dut_print(dut, DUT_MSG_INFO, "No match found - try again to verify no APs were missed in the scan");
12101 goto try_again;
12102 }
12103 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,No network with "
12104 "matching credentials found");
12105 return 0;
12106 }
12107
12108 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
12109 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
12110 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
12111 "get current BSSID/SSID");
12112 return 0;
12113 }
12114
12115 snprintf(resp, sizeof(resp), "SSID,%s,BSSID,%s", ssid, bssid);
12116 send_resp(dut, conn, SIGMA_COMPLETE, resp);
12117 hs2_set_policy(dut);
12118 return 0;
12119}
12120
12121
Jouni Malinenf7222712019-06-13 01:50:21 +030012122static enum sigma_cmd_result cmd_sta_hs2_venue_info(struct sigma_dut *dut,
12123 struct sigma_conn *conn,
12124 struct sigma_cmd *cmd)
Jouni Malinenb639f1c2018-09-13 02:39:46 +030012125{
12126 const char *intf = get_param(cmd, "Interface");
12127 const char *display = get_param(cmd, "Display");
12128 struct wpa_ctrl *ctrl;
12129 char buf[300], params[400], *pos;
12130 char bssid[20];
12131 int info_avail = 0;
12132 unsigned int old_timeout;
12133 int res;
12134
12135 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0) {
12136 send_resp(dut, conn, SIGMA_ERROR,
12137 "ErrorCode,Could not get current BSSID");
12138 return 0;
12139 }
12140 ctrl = open_wpa_mon(intf);
12141 if (!ctrl) {
12142 sigma_dut_print(dut, DUT_MSG_ERROR,
12143 "Failed to open wpa_supplicant monitor connection");
12144 return -2;
12145 }
12146
12147 snprintf(buf, sizeof(buf), "ANQP_GET %s 277", bssid);
12148 wpa_command(intf, buf);
12149
12150 res = get_wpa_cli_event(dut, ctrl, "GAS-QUERY-DONE", buf, sizeof(buf));
12151 if (res < 0) {
12152 send_resp(dut, conn, SIGMA_ERROR,
12153 "ErrorCode,Could not complete GAS query");
12154 goto fail;
12155 }
12156
12157 old_timeout = dut->default_timeout;
12158 dut->default_timeout = 2;
12159 res = get_wpa_cli_event(dut, ctrl, "RX-VENUE-URL", buf, sizeof(buf));
12160 dut->default_timeout = old_timeout;
12161 if (res < 0)
12162 goto done;
12163 pos = strchr(buf, ' ');
12164 if (!pos)
12165 goto done;
12166 pos++;
12167 pos = strchr(pos, ' ');
12168 if (!pos)
12169 goto done;
12170 pos++;
12171 info_avail = 1;
12172 snprintf(params, sizeof(params), "browser %s", pos);
12173
12174 if (display && strcasecmp(display, "Yes") == 0) {
12175 pid_t pid;
12176
12177 pid = fork();
12178 if (pid < 0) {
12179 perror("fork");
12180 return -1;
12181 }
12182
12183 if (pid == 0) {
12184 run_hs20_osu(dut, params);
12185 exit(0);
12186 }
12187 }
12188
12189done:
12190 snprintf(buf, sizeof(buf), "Info_available,%s",
12191 info_avail ? "Yes" : "No");
12192 send_resp(dut, conn, SIGMA_COMPLETE, buf);
12193fail:
12194 wpa_ctrl_detach(ctrl);
12195 wpa_ctrl_close(ctrl);
12196 return 0;
12197}
12198
12199
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012200static int sta_add_credential_uname_pwd(struct sigma_dut *dut,
12201 struct sigma_conn *conn,
12202 const char *ifname,
12203 struct sigma_cmd *cmd)
12204{
12205 const char *val;
12206 int id;
12207
12208 id = add_cred(ifname);
12209 if (id < 0)
12210 return -2;
12211 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
12212
12213 val = get_param(cmd, "prefer");
12214 if (val && atoi(val) > 0)
12215 set_cred(ifname, id, "priority", "1");
12216
12217 val = get_param(cmd, "REALM");
12218 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
12219 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12220 "realm");
12221 return 0;
12222 }
12223
12224 val = get_param(cmd, "HOME_FQDN");
12225 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
12226 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12227 "home_fqdn");
12228 return 0;
12229 }
12230
12231 val = get_param(cmd, "Username");
12232 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
12233 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12234 "username");
12235 return 0;
12236 }
12237
12238 val = get_param(cmd, "Password");
12239 if (val && set_cred_quoted(ifname, id, "password", val) < 0) {
12240 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12241 "password");
12242 return 0;
12243 }
12244
12245 val = get_param(cmd, "ROOT_CA");
12246 if (val) {
12247 char fname[200];
12248 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
12249#ifdef __linux__
12250 if (!file_exists(fname)) {
12251 char msg[300];
12252 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
12253 "file (%s) not found", fname);
12254 send_resp(dut, conn, SIGMA_ERROR, msg);
12255 return 0;
12256 }
12257#endif /* __linux__ */
12258 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
12259 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12260 "not set root CA");
12261 return 0;
12262 }
12263 }
12264
12265 return 1;
12266}
12267
12268
12269static int update_devdetail_imsi(struct sigma_dut *dut, const char *imsi)
12270{
12271 FILE *in, *out;
12272 char buf[500];
12273 int found = 0;
12274
12275 in = fopen("devdetail.xml", "r");
12276 if (in == NULL)
12277 return -1;
12278 out = fopen("devdetail.xml.tmp", "w");
12279 if (out == NULL) {
12280 fclose(in);
12281 return -1;
12282 }
12283
12284 while (fgets(buf, sizeof(buf), in)) {
12285 char *pos = strstr(buf, "<IMSI>");
12286 if (pos) {
12287 sigma_dut_print(dut, DUT_MSG_INFO, "Updated DevDetail IMSI to %s",
12288 imsi);
12289 pos += 6;
12290 *pos = '\0';
12291 fprintf(out, "%s%s</IMSI>\n", buf, imsi);
12292 found++;
12293 } else {
12294 fprintf(out, "%s", buf);
12295 }
12296 }
12297
12298 fclose(out);
12299 fclose(in);
12300 if (found)
12301 rename("devdetail.xml.tmp", "devdetail.xml");
12302 else
12303 unlink("devdetail.xml.tmp");
12304
12305 return 0;
12306}
12307
12308
12309static int sta_add_credential_sim(struct sigma_dut *dut,
12310 struct sigma_conn *conn,
12311 const char *ifname, struct sigma_cmd *cmd)
12312{
12313 const char *val, *imsi = NULL;
12314 int id;
12315 char buf[200];
12316 int res;
12317 const char *pos;
12318 size_t mnc_len;
12319 char plmn_mcc[4];
12320 char plmn_mnc[4];
12321
12322 id = add_cred(ifname);
12323 if (id < 0)
12324 return -2;
12325 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
12326
12327 val = get_param(cmd, "prefer");
12328 if (val && atoi(val) > 0)
12329 set_cred(ifname, id, "priority", "1");
12330
12331 val = get_param(cmd, "PLMN_MCC");
12332 if (val == NULL) {
12333 send_resp(dut, conn, SIGMA_ERROR,
12334 "errorCode,Missing PLMN_MCC");
12335 return 0;
12336 }
12337 if (strlen(val) != 3) {
12338 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MCC");
12339 return 0;
12340 }
12341 snprintf(plmn_mcc, sizeof(plmn_mcc), "%s", val);
12342
12343 val = get_param(cmd, "PLMN_MNC");
12344 if (val == NULL) {
12345 send_resp(dut, conn, SIGMA_ERROR,
12346 "errorCode,Missing PLMN_MNC");
12347 return 0;
12348 }
12349 if (strlen(val) != 2 && strlen(val) != 3) {
12350 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MNC");
12351 return 0;
12352 }
12353 snprintf(plmn_mnc, sizeof(plmn_mnc), "%s", val);
12354
12355 val = get_param(cmd, "IMSI");
12356 if (val == NULL) {
12357 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing SIM "
12358 "IMSI");
12359 return 0;
12360 }
12361
12362 imsi = pos = val;
12363
12364 if (strncmp(plmn_mcc, pos, 3) != 0) {
12365 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MCC mismatch");
12366 return 0;
12367 }
12368 pos += 3;
12369
12370 mnc_len = strlen(plmn_mnc);
12371 if (mnc_len < 2) {
12372 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC not set");
12373 return 0;
12374 }
12375
12376 if (strncmp(plmn_mnc, pos, mnc_len) != 0) {
12377 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC mismatch");
12378 return 0;
12379 }
12380 pos += mnc_len;
12381
12382 res = snprintf(buf, sizeof(buf), "%s%s-%s",plmn_mcc, plmn_mnc, pos);
12383 if (res < 0 || res >= (int) sizeof(buf))
12384 return -1;
12385 if (set_cred_quoted(ifname, id, "imsi", buf) < 0) {
12386 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12387 "not set IMSI");
12388 return 0;
12389 }
12390
12391 val = get_param(cmd, "Password");
12392 if (val && set_cred_quoted(ifname, id, "milenage", val) < 0) {
12393 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12394 "not set password");
12395 return 0;
12396 }
12397
Jouni Malinenba630452018-06-22 11:49:59 +030012398 if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012399 /*
12400 * Set provisioning_sp for the test cases where SIM/USIM
12401 * provisioning is used.
12402 */
12403 if (val && set_cred_quoted(ifname, id, "provisioning_sp",
12404 "wi-fi.org") < 0) {
12405 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12406 "not set provisioning_sp");
12407 return 0;
12408 }
12409
12410 update_devdetail_imsi(dut, imsi);
12411 }
12412
12413 return 1;
12414}
12415
12416
12417static int sta_add_credential_cert(struct sigma_dut *dut,
12418 struct sigma_conn *conn,
12419 const char *ifname,
12420 struct sigma_cmd *cmd)
12421{
12422 const char *val;
12423 int id;
12424
12425 id = add_cred(ifname);
12426 if (id < 0)
12427 return -2;
12428 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
12429
12430 val = get_param(cmd, "prefer");
12431 if (val && atoi(val) > 0)
12432 set_cred(ifname, id, "priority", "1");
12433
12434 val = get_param(cmd, "REALM");
12435 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
12436 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12437 "realm");
12438 return 0;
12439 }
12440
12441 val = get_param(cmd, "HOME_FQDN");
12442 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
12443 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12444 "home_fqdn");
12445 return 0;
12446 }
12447
12448 val = get_param(cmd, "Username");
12449 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
12450 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12451 "username");
12452 return 0;
12453 }
12454
12455 val = get_param(cmd, "clientCertificate");
12456 if (val) {
12457 char fname[200];
12458 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
12459#ifdef __linux__
12460 if (!file_exists(fname)) {
12461 char msg[300];
12462 snprintf(msg, sizeof(msg),
12463 "ErrorCode,clientCertificate "
12464 "file (%s) not found", fname);
12465 send_resp(dut, conn, SIGMA_ERROR, msg);
12466 return 0;
12467 }
12468#endif /* __linux__ */
12469 if (set_cred_quoted(ifname, id, "client_cert", fname) < 0) {
12470 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12471 "not set client_cert");
12472 return 0;
12473 }
12474 if (set_cred_quoted(ifname, id, "private_key", fname) < 0) {
12475 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12476 "not set private_key");
12477 return 0;
12478 }
12479 }
12480
12481 val = get_param(cmd, "ROOT_CA");
12482 if (val) {
12483 char fname[200];
12484 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
12485#ifdef __linux__
12486 if (!file_exists(fname)) {
12487 char msg[300];
12488 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
12489 "file (%s) not found", fname);
12490 send_resp(dut, conn, SIGMA_ERROR, msg);
12491 return 0;
12492 }
12493#endif /* __linux__ */
12494 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
12495 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12496 "not set root CA");
12497 return 0;
12498 }
12499 }
12500
12501 return 1;
12502}
12503
12504
Jouni Malinenf7222712019-06-13 01:50:21 +030012505static enum sigma_cmd_result cmd_sta_add_credential(struct sigma_dut *dut,
12506 struct sigma_conn *conn,
12507 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012508{
12509 const char *intf = get_param(cmd, "Interface");
12510 const char *type;
12511
12512 start_sta_mode(dut);
12513
12514 type = get_param(cmd, "Type");
12515 if (!type)
12516 return -1;
12517
12518 if (strcasecmp(type, "uname_pwd") == 0)
12519 return sta_add_credential_uname_pwd(dut, conn, intf, cmd);
12520
12521 if (strcasecmp(type, "sim") == 0)
12522 return sta_add_credential_sim(dut, conn, intf, cmd);
12523
12524 if (strcasecmp(type, "cert") == 0)
12525 return sta_add_credential_cert(dut, conn, intf, cmd);
12526
12527 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported credential "
12528 "type");
12529 return 0;
12530}
12531
12532
Jouni Malinenf7222712019-06-13 01:50:21 +030012533static enum sigma_cmd_result cmd_sta_scan(struct sigma_dut *dut,
12534 struct sigma_conn *conn,
12535 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012536{
12537 const char *intf = get_param(cmd, "Interface");
vamsi krishna89ad8c62017-09-19 12:51:18 +053012538 const char *val, *bssid, *ssid;
Arif Hussain66a4af02019-02-07 15:04:51 -080012539 char buf[4096];
vamsi krishna89ad8c62017-09-19 12:51:18 +053012540 char ssid_hex[65];
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012541 int res;
12542
Arif Hussain66a4af02019-02-07 15:04:51 -080012543 val = get_param(cmd, "GetParameter");
12544 if (val && strcmp(val, "SSID_BSSID") == 0) {
12545 if (get_wpa_ssid_bssid(dut, get_station_ifname(),
12546 buf, sizeof(buf)) < 0) {
12547 sigma_dut_print(dut, DUT_MSG_ERROR,
12548 "Could not get ssid bssid");
12549 return ERROR_SEND_STATUS;
12550 }
12551
12552 sigma_dut_print(dut, DUT_MSG_INFO, "%s", buf);
12553 send_resp(dut, conn, SIGMA_COMPLETE, buf);
12554 return STATUS_SENT;
12555 }
12556
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012557 val = get_param(cmd, "HESSID");
12558 if (val) {
12559 res = snprintf(buf, sizeof(buf), "SET hessid %s", val);
12560 if (res < 0 || res >= (int) sizeof(buf))
12561 return -1;
12562 wpa_command(intf, buf);
12563 }
12564
12565 val = get_param(cmd, "ACCS_NET_TYPE");
12566 if (val) {
12567 res = snprintf(buf, sizeof(buf), "SET access_network_type %s",
12568 val);
12569 if (res < 0 || res >= (int) sizeof(buf))
12570 return -1;
12571 wpa_command(intf, buf);
12572 }
12573
vamsi krishna89ad8c62017-09-19 12:51:18 +053012574 bssid = get_param(cmd, "Bssid");
12575 ssid = get_param(cmd, "Ssid");
12576
12577 if (ssid) {
12578 if (2 * strlen(ssid) >= sizeof(ssid_hex)) {
12579 send_resp(dut, conn, SIGMA_ERROR,
12580 "ErrorCode,Too long SSID");
12581 return 0;
12582 }
12583 ascii2hexstr(ssid, ssid_hex);
12584 }
12585
12586 res = snprintf(buf, sizeof(buf), "SCAN%s%s%s%s",
12587 bssid ? " bssid=": "",
12588 bssid ? bssid : "",
12589 ssid ? " ssid " : "",
12590 ssid ? ssid_hex : "");
12591 if (res < 0 || res >= (int) sizeof(buf))
12592 return -1;
12593
12594 if (wpa_command(intf, buf)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012595 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not start "
12596 "scan");
12597 return 0;
12598 }
12599
12600 return 1;
12601}
12602
12603
Jouni Malinenf7222712019-06-13 01:50:21 +030012604static enum sigma_cmd_result cmd_sta_scan_bss(struct sigma_dut *dut,
12605 struct sigma_conn *conn,
12606 struct sigma_cmd *cmd)
Jouni Malinen5e5d43d2018-01-10 17:29:33 +020012607{
12608 const char *intf = get_param(cmd, "Interface");
12609 const char *bssid;
12610 char buf[4096], *pos;
12611 int freq, chan;
12612 char *ssid;
12613 char resp[100];
12614 int res;
12615 struct wpa_ctrl *ctrl;
12616
12617 bssid = get_param(cmd, "BSSID");
12618 if (!bssid) {
12619 send_resp(dut, conn, SIGMA_INVALID,
12620 "errorCode,BSSID argument is missing");
12621 return 0;
12622 }
12623
12624 ctrl = open_wpa_mon(intf);
12625 if (!ctrl) {
12626 sigma_dut_print(dut, DUT_MSG_ERROR,
12627 "Failed to open wpa_supplicant monitor connection");
12628 return -1;
12629 }
12630
12631 if (wpa_command(intf, "SCAN TYPE=ONLY")) {
12632 send_resp(dut, conn, SIGMA_ERROR,
12633 "errorCode,Could not start scan");
12634 wpa_ctrl_detach(ctrl);
12635 wpa_ctrl_close(ctrl);
12636 return 0;
12637 }
12638
12639 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
12640 buf, sizeof(buf));
12641
12642 wpa_ctrl_detach(ctrl);
12643 wpa_ctrl_close(ctrl);
12644
12645 if (res < 0) {
12646 send_resp(dut, conn, SIGMA_ERROR,
12647 "errorCode,Scan did not complete");
12648 return 0;
12649 }
12650
12651 snprintf(buf, sizeof(buf), "BSS %s", bssid);
12652 if (wpa_command_resp(intf, buf, buf, sizeof(buf)) < 0 ||
12653 strncmp(buf, "id=", 3) != 0) {
12654 send_resp(dut, conn, SIGMA_ERROR,
12655 "errorCode,Specified BSSID not found");
12656 return 0;
12657 }
12658
12659 pos = strstr(buf, "\nfreq=");
12660 if (!pos) {
12661 send_resp(dut, conn, SIGMA_ERROR,
12662 "errorCode,Channel not found");
12663 return 0;
12664 }
12665 freq = atoi(pos + 6);
12666 chan = freq_to_channel(freq);
12667
12668 pos = strstr(buf, "\nssid=");
12669 if (!pos) {
12670 send_resp(dut, conn, SIGMA_ERROR,
12671 "errorCode,SSID not found");
12672 return 0;
12673 }
12674 ssid = pos + 6;
12675 pos = strchr(ssid, '\n');
12676 if (pos)
12677 *pos = '\0';
12678 snprintf(resp, sizeof(resp), "ssid,%s,bsschannel,%d", ssid, chan);
12679 send_resp(dut, conn, SIGMA_COMPLETE, resp);
12680 return 0;
12681}
12682
12683
Jouni Malinenf7222712019-06-13 01:50:21 +030012684static enum sigma_cmd_result cmd_sta_set_systime(struct sigma_dut *dut,
12685 struct sigma_conn *conn,
12686 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012687{
12688#ifdef __linux__
12689 struct timeval tv;
12690 struct tm tm;
12691 time_t t;
12692 const char *val;
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +053012693 int v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012694
12695 wpa_command(get_station_ifname(), "PMKSA_FLUSH");
12696
12697 memset(&tm, 0, sizeof(tm));
12698 val = get_param(cmd, "seconds");
12699 if (val)
12700 tm.tm_sec = atoi(val);
12701 val = get_param(cmd, "minutes");
12702 if (val)
12703 tm.tm_min = atoi(val);
12704 val = get_param(cmd, "hours");
12705 if (val)
12706 tm.tm_hour = atoi(val);
12707 val = get_param(cmd, "date");
12708 if (val)
12709 tm.tm_mday = atoi(val);
12710 val = get_param(cmd, "month");
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +053012711 if (val) {
12712 v = atoi(val);
12713 if (v < 1 || v > 12) {
12714 send_resp(dut, conn, SIGMA_INVALID,
12715 "errorCode,Invalid month");
12716 return 0;
12717 }
12718 tm.tm_mon = v - 1;
12719 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012720 val = get_param(cmd, "year");
12721 if (val) {
12722 int year = atoi(val);
12723#ifdef ANDROID
12724 if (year > 2035)
12725 year = 2035; /* years beyond 2035 not supported */
12726#endif /* ANDROID */
12727 tm.tm_year = year - 1900;
12728 }
12729 t = mktime(&tm);
12730 if (t == (time_t) -1) {
12731 send_resp(dut, conn, SIGMA_ERROR,
12732 "errorCode,Invalid date or time");
12733 return 0;
12734 }
12735
12736 memset(&tv, 0, sizeof(tv));
12737 tv.tv_sec = t;
12738
12739 if (settimeofday(&tv, NULL) < 0) {
12740 sigma_dut_print(dut, DUT_MSG_INFO, "settimeofday failed: %s",
12741 strerror(errno));
12742 send_resp(dut, conn, SIGMA_ERROR,
12743 "errorCode,Failed to set time");
12744 return 0;
12745 }
12746
12747 return 1;
12748#endif /* __linux__ */
12749
12750 return -1;
12751}
12752
12753
Jouni Malinenf7222712019-06-13 01:50:21 +030012754static enum sigma_cmd_result cmd_sta_osu(struct sigma_dut *dut,
12755 struct sigma_conn *conn,
12756 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012757{
12758 const char *intf = get_param(cmd, "Interface");
Jouni Malinen4c8681c2018-09-12 23:28:11 +030012759 const char *name, *osu_ssid, *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012760 int prod_ess_assoc = 1;
Jouni Malinen4c8681c2018-09-12 23:28:11 +030012761 char buf[300], bssid[100], ssid[100];
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012762 int res;
12763 struct wpa_ctrl *ctrl;
12764
12765 name = get_param(cmd, "osuFriendlyName");
Jouni Malinen4c8681c2018-09-12 23:28:11 +030012766 osu_ssid = get_param(cmd, "osu_ssid");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012767
12768 val = get_param(cmd, "ProdESSAssoc");
12769 if (val)
12770 prod_ess_assoc = atoi(val);
12771
12772 kill_dhcp_client(dut, intf);
12773 if (start_dhcp_client(dut, intf) < 0)
12774 return -2;
12775
12776 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger OSU");
12777 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
12778 res = snprintf(buf, sizeof(buf),
Jouni Malinen4c8681c2018-09-12 23:28:11 +030012779 "%s %s%s%s %s%s%s signup osu-ca.pem",
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012780 prod_ess_assoc ? "" : "-N",
12781 name ? "-O'" : "", name ? name : "",
Jouni Malinen4c8681c2018-09-12 23:28:11 +030012782 name ? "'" : "",
12783 osu_ssid ? "-o'" : "", osu_ssid ? osu_ssid : "",
12784 osu_ssid ? "'" : "");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012785
Kanchanapally, Vidyullatha12b66762015-12-31 16:46:42 +053012786 hs2_set_policy(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012787 if (run_hs20_osu(dut, buf) < 0) {
12788 FILE *f;
12789
12790 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to complete OSU");
12791
12792 f = fopen("hs20-osu-client.res", "r");
12793 if (f) {
12794 char resp[400], res[300], *pos;
12795 if (!fgets(res, sizeof(res), f))
12796 res[0] = '\0';
12797 pos = strchr(res, '\n');
12798 if (pos)
12799 *pos = '\0';
12800 fclose(f);
12801 sigma_dut_summary(dut, "hs20-osu-client provisioning failed: %s",
12802 res);
12803 snprintf(resp, sizeof(resp), "notify-send '%s'", res);
12804 if (system(resp) != 0) {
12805 }
12806 snprintf(resp, sizeof(resp),
12807 "SSID,,BSSID,,failureReason,%s", res);
12808 send_resp(dut, conn, SIGMA_COMPLETE, resp);
12809 return 0;
12810 }
12811
12812 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
12813 return 0;
12814 }
12815
12816 if (!prod_ess_assoc)
12817 goto report;
12818
12819 ctrl = open_wpa_mon(intf);
12820 if (ctrl == NULL) {
12821 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
12822 "wpa_supplicant monitor connection");
12823 return -1;
12824 }
12825
12826 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
12827 buf, sizeof(buf));
12828
12829 wpa_ctrl_detach(ctrl);
12830 wpa_ctrl_close(ctrl);
12831
12832 if (res < 0) {
12833 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to connect to "
12834 "network after OSU");
12835 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
12836 return 0;
12837 }
12838
12839report:
12840 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
12841 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
12842 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to get BSSID/SSID");
12843 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
12844 return 0;
12845 }
12846
12847 snprintf(buf, sizeof(buf), "SSID,%s,BSSID,%s", ssid, bssid);
12848 send_resp(dut, conn, SIGMA_COMPLETE, buf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012849 return 0;
12850}
12851
12852
Jouni Malinenf7222712019-06-13 01:50:21 +030012853static enum sigma_cmd_result cmd_sta_policy_update(struct sigma_dut *dut,
12854 struct sigma_conn *conn,
12855 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012856{
12857 const char *val;
12858 int timeout = 120;
12859
12860 val = get_param(cmd, "PolicyUpdate");
12861 if (val == NULL || atoi(val) == 0)
12862 return 1; /* No operation requested */
12863
12864 val = get_param(cmd, "Timeout");
12865 if (val)
12866 timeout = atoi(val);
12867
12868 if (timeout) {
12869 /* TODO: time out the command and return
12870 * PolicyUpdateStatus,TIMEOUT if needed. */
12871 }
12872
12873 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger policy update");
12874 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
12875 if (run_hs20_osu(dut, "pol_upd fqdn=wi-fi.org") < 0) {
12876 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,FAIL");
12877 return 0;
12878 }
12879
12880 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,SUCCESS");
12881 return 0;
12882}
12883
12884
Jouni Malinenf7222712019-06-13 01:50:21 +030012885static enum sigma_cmd_result cmd_sta_er_config(struct sigma_dut *dut,
12886 struct sigma_conn *conn,
12887 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012888{
12889 struct wpa_ctrl *ctrl;
12890 const char *intf = get_param(cmd, "Interface");
12891 const char *bssid = get_param(cmd, "Bssid");
12892 const char *ssid = get_param(cmd, "SSID");
12893 const char *security = get_param(cmd, "Security");
12894 const char *passphrase = get_param(cmd, "Passphrase");
12895 const char *pin = get_param(cmd, "PIN");
12896 char buf[1000];
12897 char ssid_hex[200], passphrase_hex[200];
12898 const char *keymgmt, *cipher;
12899
12900 if (intf == NULL)
12901 intf = get_main_ifname();
12902
12903 if (!bssid) {
12904 send_resp(dut, conn, SIGMA_ERROR,
12905 "ErrorCode,Missing Bssid argument");
12906 return 0;
12907 }
12908
12909 if (!ssid) {
12910 send_resp(dut, conn, SIGMA_ERROR,
12911 "ErrorCode,Missing SSID argument");
12912 return 0;
12913 }
12914
12915 if (!security) {
12916 send_resp(dut, conn, SIGMA_ERROR,
12917 "ErrorCode,Missing Security argument");
12918 return 0;
12919 }
12920
12921 if (!passphrase) {
12922 send_resp(dut, conn, SIGMA_ERROR,
12923 "ErrorCode,Missing Passphrase argument");
12924 return 0;
12925 }
12926
12927 if (!pin) {
12928 send_resp(dut, conn, SIGMA_ERROR,
12929 "ErrorCode,Missing PIN argument");
12930 return 0;
12931 }
12932
vamsi krishna8c9c1562017-05-12 15:51:46 +053012933 if (2 * strlen(ssid) >= sizeof(ssid_hex) ||
12934 2 * strlen(passphrase) >= sizeof(passphrase_hex)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012935 send_resp(dut, conn, SIGMA_ERROR,
12936 "ErrorCode,Too long SSID/passphrase");
12937 return 0;
12938 }
12939
12940 ctrl = open_wpa_mon(intf);
12941 if (ctrl == NULL) {
12942 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
12943 "wpa_supplicant monitor connection");
12944 return -2;
12945 }
12946
12947 if (strcasecmp(security, "wpa2-psk") == 0) {
12948 keymgmt = "WPA2PSK";
12949 cipher = "CCMP";
12950 } else {
12951 wpa_ctrl_detach(ctrl);
12952 wpa_ctrl_close(ctrl);
12953 send_resp(dut, conn, SIGMA_ERROR,
12954 "ErrorCode,Unsupported Security value");
12955 return 0;
12956 }
12957
12958 ascii2hexstr(ssid, ssid_hex);
12959 ascii2hexstr(passphrase, passphrase_hex);
12960 snprintf(buf, sizeof(buf), "WPS_REG %s %s %s %s %s %s",
12961 bssid, pin, ssid_hex, keymgmt, cipher, passphrase_hex);
12962
12963 if (wpa_command(intf, buf) < 0) {
12964 wpa_ctrl_detach(ctrl);
12965 wpa_ctrl_close(ctrl);
12966 send_resp(dut, conn, SIGMA_ERROR,
12967 "ErrorCode,Failed to start registrar");
12968 return 0;
12969 }
12970
12971 snprintf(dut->er_oper_bssid, sizeof(dut->er_oper_bssid), "%s", bssid);
12972 dut->er_oper_performed = 1;
12973
12974 return wps_connection_event(dut, conn, ctrl, intf, 0);
12975}
12976
12977
Jouni Malinenf7222712019-06-13 01:50:21 +030012978static enum sigma_cmd_result
12979cmd_sta_wps_connect_pw_token(struct sigma_dut *dut, struct sigma_conn *conn,
12980 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012981{
12982 struct wpa_ctrl *ctrl;
12983 const char *intf = get_param(cmd, "Interface");
12984 const char *bssid = get_param(cmd, "Bssid");
12985 char buf[100];
12986
12987 if (!bssid) {
12988 send_resp(dut, conn, SIGMA_ERROR,
12989 "ErrorCode,Missing Bssid argument");
12990 return 0;
12991 }
12992
12993 ctrl = open_wpa_mon(intf);
12994 if (ctrl == NULL) {
12995 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
12996 "wpa_supplicant monitor connection");
12997 return -2;
12998 }
12999
13000 snprintf(buf, sizeof(buf), "WPS_NFC %s", bssid);
13001
13002 if (wpa_command(intf, buf) < 0) {
13003 wpa_ctrl_detach(ctrl);
13004 wpa_ctrl_close(ctrl);
13005 send_resp(dut, conn, SIGMA_ERROR,
13006 "ErrorCode,Failed to start registrar");
13007 return 0;
13008 }
13009
13010 return wps_connection_event(dut, conn, ctrl, intf, 0);
13011}
13012
13013
Jouni Malinenf7222712019-06-13 01:50:21 +030013014static enum sigma_cmd_result cmd_start_wps_registration(struct sigma_dut *dut,
13015 struct sigma_conn *conn,
13016 struct sigma_cmd *cmd)
vamsi krishna9b144002017-09-20 13:28:13 +053013017{
13018 struct wpa_ctrl *ctrl;
13019 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020013020 const char *network_mode = get_param(cmd, "network_mode");
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020013021 const char *config_method = get_param(cmd, "WPSConfigMethod");
13022 const char *role;
vamsi krishna9b144002017-09-20 13:28:13 +053013023 int res;
13024 char buf[256];
13025 const char *events[] = {
13026 "CTRL-EVENT-CONNECTED",
13027 "WPS-OVERLAP-DETECTED",
13028 "WPS-TIMEOUT",
13029 "WPS-FAIL",
13030 NULL
13031 };
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020013032 int id = 0;
vamsi krishna9b144002017-09-20 13:28:13 +053013033
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020013034 /* 60G WPS tests do not pass Interface parameter */
13035 if (!intf)
13036 intf = get_main_ifname();
13037
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020013038 if (dut->mode == SIGMA_MODE_AP)
13039 return ap_wps_registration(dut, conn, cmd);
13040
13041 if (config_method) {
13042 /* WFA_CS_WPS_PIN_KEYPAD mode is set when using the
13043 * sta_wps_enter_pin before calling start_wps_registration. */
13044 if (strcasecmp(config_method, "PBC") == 0)
13045 dut->wps_method = WFA_CS_WPS_PBC;
13046 }
13047 if (dut->wps_method == WFA_CS_WPS_NOT_READY) {
13048 send_resp(dut, conn, SIGMA_ERROR,
13049 "ErrorCode,WPS parameters not yet set");
13050 return STATUS_SENT;
13051 }
13052
13053 /* Make sure WPS is enabled (also for STA mode) */
13054 dut->wps_disable = 0;
13055
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020013056 if (dut->band == WPS_BAND_60G && network_mode &&
13057 strcasecmp(network_mode, "PBSS") == 0) {
13058 sigma_dut_print(dut, DUT_MSG_DEBUG,
13059 "Set PBSS network mode, network id %d", id);
13060 if (set_network(get_station_ifname(), id, "pbss", "1") < 0)
13061 return -2;
13062 }
13063
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020013064 if (dut->force_rsn_ie) {
13065 sigma_dut_print(dut, DUT_MSG_DEBUG, "Force RSN_IE: %d",
13066 dut->force_rsn_ie);
13067 if (sta_60g_force_rsn_ie(dut, dut->force_rsn_ie) < 0) {
13068 sigma_dut_print(dut, DUT_MSG_INFO,
13069 "Failed to force RSN_IE");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020013070 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020013071 }
13072 }
13073
vamsi krishna9b144002017-09-20 13:28:13 +053013074 ctrl = open_wpa_mon(intf);
13075 if (!ctrl) {
13076 sigma_dut_print(dut, DUT_MSG_ERROR,
13077 "Failed to open wpa_supplicant monitor connection");
13078 return -2;
13079 }
13080
13081 role = get_param(cmd, "WpsRole");
13082 if (!role) {
13083 send_resp(dut, conn, SIGMA_INVALID,
13084 "ErrorCode,WpsRole not provided");
13085 goto fail;
13086 }
13087
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020013088 if (strcasecmp(role, "Enrollee") != 0) {
13089 /* Registrar role for STA not supported */
13090 send_resp(dut, conn, SIGMA_ERROR,
13091 "ErrorCode,Unsupported WpsRole value");
13092 goto fail;
13093 }
13094
13095 if (is_60g_sigma_dut(dut)) {
13096 if (dut->wps_method == WFA_CS_WPS_PBC)
13097 snprintf(buf, sizeof(buf), "WPS_PBC");
13098 else /* WFA_CS_WPS_PIN_KEYPAD */
13099 snprintf(buf, sizeof(buf), "WPS_PIN any %s",
13100 dut->wps_pin);
13101 if (wpa_command(intf, buf) < 0) {
13102 send_resp(dut, conn, SIGMA_ERROR,
13103 "ErrorCode,Failed to start WPS");
vamsi krishna9b144002017-09-20 13:28:13 +053013104 goto fail;
13105 }
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020013106 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
13107 if (res < 0) {
13108 send_resp(dut, conn, SIGMA_ERROR,
13109 "ErrorCode,WPS connection did not complete");
13110 goto fail;
13111 }
13112 if (strstr(buf, "WPS-TIMEOUT")) {
13113 send_resp(dut, conn, SIGMA_COMPLETE, "WpsState,NoPeer");
13114 } else if (strstr(buf, "WPS-OVERLAP-DETECTED")) {
13115 send_resp(dut, conn, SIGMA_COMPLETE,
13116 "WpsState,OverlapSession");
13117 } else if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
13118 send_resp(dut, conn, SIGMA_COMPLETE,
13119 "WpsState,Successful");
13120 } else {
13121 send_resp(dut, conn, SIGMA_COMPLETE,
13122 "WpsState,Failure");
13123 }
13124 } else {
13125 if (dut->wps_method == WFA_CS_WPS_PBC) {
vamsi krishna9b144002017-09-20 13:28:13 +053013126 if (wpa_command(intf, "WPS_PBC") < 0) {
13127 send_resp(dut, conn, SIGMA_ERROR,
13128 "ErrorCode,Failed to enable PBC");
13129 goto fail;
13130 }
13131 } else {
13132 /* TODO: PIN method */
13133 send_resp(dut, conn, SIGMA_ERROR,
13134 "ErrorCode,Unsupported WpsConfigMethod value");
13135 goto fail;
13136 }
13137 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
13138 if (res < 0) {
13139 send_resp(dut, conn, SIGMA_ERROR,
13140 "ErrorCode,WPS connection did not complete");
13141 goto fail;
13142 }
13143 if (strstr(buf, "WPS-TIMEOUT")) {
13144 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,NoPeer");
13145 } else if (strstr(buf, "WPS-OVERLAP-DETECTED")) {
13146 send_resp(dut, conn, SIGMA_ERROR,
13147 "ErrorCode,OverlapSession");
13148 } else if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
13149 send_resp(dut, conn, SIGMA_COMPLETE, "Successful");
13150 } else {
13151 send_resp(dut, conn, SIGMA_ERROR,
13152 "ErrorCode,WPS operation failed");
13153 }
vamsi krishna9b144002017-09-20 13:28:13 +053013154 }
13155
13156fail:
13157 wpa_ctrl_detach(ctrl);
13158 wpa_ctrl_close(ctrl);
13159 return 0;
13160}
13161
13162
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013163static int req_intf(struct sigma_cmd *cmd)
13164{
13165 return get_param(cmd, "interface") == NULL ? -1 : 0;
13166}
13167
13168
13169void sta_register_cmds(void)
13170{
13171 sigma_dut_reg_cmd("sta_get_ip_config", req_intf,
13172 cmd_sta_get_ip_config);
13173 sigma_dut_reg_cmd("sta_set_ip_config", req_intf,
13174 cmd_sta_set_ip_config);
13175 sigma_dut_reg_cmd("sta_get_info", req_intf, cmd_sta_get_info);
13176 sigma_dut_reg_cmd("sta_get_mac_address", req_intf,
13177 cmd_sta_get_mac_address);
13178 sigma_dut_reg_cmd("sta_is_connected", req_intf, cmd_sta_is_connected);
13179 sigma_dut_reg_cmd("sta_verify_ip_connection", req_intf,
13180 cmd_sta_verify_ip_connection);
13181 sigma_dut_reg_cmd("sta_get_bssid", req_intf, cmd_sta_get_bssid);
13182 sigma_dut_reg_cmd("sta_set_encryption", req_intf,
13183 cmd_sta_set_encryption);
13184 sigma_dut_reg_cmd("sta_set_psk", req_intf, cmd_sta_set_psk);
13185 sigma_dut_reg_cmd("sta_set_eaptls", req_intf, cmd_sta_set_eaptls);
13186 sigma_dut_reg_cmd("sta_set_eapttls", req_intf, cmd_sta_set_eapttls);
13187 sigma_dut_reg_cmd("sta_set_eapsim", req_intf, cmd_sta_set_eapsim);
13188 sigma_dut_reg_cmd("sta_set_peap", req_intf, cmd_sta_set_peap);
13189 sigma_dut_reg_cmd("sta_set_eapfast", req_intf, cmd_sta_set_eapfast);
13190 sigma_dut_reg_cmd("sta_set_eapaka", req_intf, cmd_sta_set_eapaka);
13191 sigma_dut_reg_cmd("sta_set_eapakaprime", req_intf,
13192 cmd_sta_set_eapakaprime);
13193 sigma_dut_reg_cmd("sta_set_security", req_intf, cmd_sta_set_security);
13194 sigma_dut_reg_cmd("sta_set_uapsd", req_intf, cmd_sta_set_uapsd);
13195 /* TODO: sta_set_ibss */
13196 /* TODO: sta_set_mode */
13197 sigma_dut_reg_cmd("sta_set_wmm", req_intf, cmd_sta_set_wmm);
13198 sigma_dut_reg_cmd("sta_associate", req_intf, cmd_sta_associate);
13199 /* TODO: sta_up_load */
13200 sigma_dut_reg_cmd("sta_preset_testparameters", req_intf,
13201 cmd_sta_preset_testparameters);
13202 /* TODO: sta_set_system */
13203 sigma_dut_reg_cmd("sta_set_11n", req_intf, cmd_sta_set_11n);
13204 /* TODO: sta_set_rifs_test */
13205 sigma_dut_reg_cmd("sta_set_wireless", req_intf, cmd_sta_set_wireless);
13206 sigma_dut_reg_cmd("sta_send_addba", req_intf, cmd_sta_send_addba);
13207 /* TODO: sta_send_coexist_mgmt */
13208 sigma_dut_reg_cmd("sta_disconnect", req_intf, cmd_sta_disconnect);
13209 sigma_dut_reg_cmd("sta_reassoc", req_intf, cmd_sta_reassoc);
13210 sigma_dut_reg_cmd("sta_reassociate", req_intf, cmd_sta_reassoc);
13211 sigma_dut_reg_cmd("sta_reset_default", req_intf,
13212 cmd_sta_reset_default);
13213 sigma_dut_reg_cmd("sta_send_frame", req_intf, cmd_sta_send_frame);
13214 sigma_dut_reg_cmd("sta_set_macaddr", req_intf, cmd_sta_set_macaddr);
13215 sigma_dut_reg_cmd("sta_set_rfeature", req_intf, cmd_sta_set_rfeature);
13216 sigma_dut_reg_cmd("sta_set_radio", req_intf, cmd_sta_set_radio);
13217 sigma_dut_reg_cmd("sta_set_pwrsave", req_intf, cmd_sta_set_pwrsave);
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020013218 sigma_dut_reg_cmd("sta_set_power_save", req_intf, cmd_sta_set_pwrsave);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013219 sigma_dut_reg_cmd("sta_bssid_pool", req_intf, cmd_sta_bssid_pool);
13220 sigma_dut_reg_cmd("sta_reset_parm", req_intf, cmd_sta_reset_parm);
13221 sigma_dut_reg_cmd("sta_get_key", req_intf, cmd_sta_get_key);
13222 sigma_dut_reg_cmd("sta_hs2_associate", req_intf,
13223 cmd_sta_hs2_associate);
Jouni Malinenb639f1c2018-09-13 02:39:46 +030013224 sigma_dut_reg_cmd("sta_hs2_venue_info", req_intf,
13225 cmd_sta_hs2_venue_info);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013226 sigma_dut_reg_cmd("sta_add_credential", req_intf,
13227 cmd_sta_add_credential);
13228 sigma_dut_reg_cmd("sta_scan", req_intf, cmd_sta_scan);
Jouni Malinen5e5d43d2018-01-10 17:29:33 +020013229 sigma_dut_reg_cmd("sta_scan_bss", req_intf, cmd_sta_scan_bss);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013230 sigma_dut_reg_cmd("sta_set_systime", NULL, cmd_sta_set_systime);
13231 sigma_dut_reg_cmd("sta_osu", req_intf, cmd_sta_osu);
13232 sigma_dut_reg_cmd("sta_policy_update", req_intf, cmd_sta_policy_update);
13233 sigma_dut_reg_cmd("sta_er_config", NULL, cmd_sta_er_config);
13234 sigma_dut_reg_cmd("sta_wps_connect_pw_token", req_intf,
13235 cmd_sta_wps_connect_pw_token);
Jouni Malinen82905202018-04-29 17:20:10 +030013236 sigma_dut_reg_cmd("sta_exec_action", NULL, cmd_sta_exec_action);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013237 sigma_dut_reg_cmd("sta_get_events", req_intf, cmd_sta_get_events);
13238 sigma_dut_reg_cmd("sta_get_parameter", req_intf, cmd_sta_get_parameter);
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020013239 sigma_dut_reg_cmd("start_wps_registration", NULL,
vamsi krishna9b144002017-09-20 13:28:13 +053013240 cmd_start_wps_registration);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013241}