blob: 9e78eb31955b0aa6e8ce9092f997209fa48fe8b4 [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;
325
326 if (length > WIL_WMI_MAX_PAYLOAD) {
327 sigma_dut_print(dut, DUT_MSG_ERROR,
328 "payload too large(%u, max %u)",
329 length, WIL_WMI_MAX_PAYLOAD);
330 return -1;
331 }
332
333 memset(&cmd.hdr, 0, sizeof(cmd.hdr));
334 cmd.hdr.cmd = command;
335 memcpy(cmd.payload, payload, length);
336
337 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
338 sigma_dut_print(dut, DUT_MSG_ERROR,
339 "failed to get wil6210 debugfs dir");
340 return -1;
341 }
342
343 snprintf(fname, sizeof(fname), "%s/wmi_send", buf);
344 f = fopen(fname, "wb");
345 if (!f) {
346 sigma_dut_print(dut, DUT_MSG_ERROR,
347 "failed to open: %s", fname);
348 return -1;
349 }
350
351 towrite = sizeof(cmd.hdr) + length;
352 written = fwrite(&cmd, 1, towrite, f);
353 fclose(f);
354 if (written != towrite) {
355 sigma_dut_print(dut, DUT_MSG_ERROR,
356 "failed to send wmi %u", command);
357 return -1;
358 }
359
360 return 0;
361}
362
363
364static int wil6210_get_sta_info_field(struct sigma_dut *dut, const char *bssid,
365 const char *pattern, unsigned int *field)
366{
367 char buf[128], fname[128];
368 FILE *f;
369 regex_t re;
370 regmatch_t m[2];
371 int rc, ret = -1;
372
373 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
374 sigma_dut_print(dut, DUT_MSG_ERROR,
375 "failed to get wil6210 debugfs dir");
376 return -1;
377 }
378
379 snprintf(fname, sizeof(fname), "%s/stations", buf);
380 f = fopen(fname, "r");
381 if (!f) {
382 sigma_dut_print(dut, DUT_MSG_ERROR,
383 "failed to open: %s", fname);
384 return -1;
385 }
386
387 if (regcomp(&re, pattern, REG_EXTENDED)) {
388 sigma_dut_print(dut, DUT_MSG_ERROR,
389 "regcomp failed: %s", pattern);
390 goto out;
391 }
392
393 /*
394 * find the entry for the mac address
395 * line is of the form: [n] 11:22:33:44:55:66 state AID aid
396 */
397 while (fgets(buf, sizeof(buf), f)) {
398 if (strcasestr(buf, bssid)) {
399 /* extract the field (CID/AID/state) */
400 rc = regexec(&re, buf, 2, m, 0);
401 if (!rc && (m[1].rm_so >= 0)) {
402 buf[m[1].rm_eo] = 0;
403 *field = atoi(&buf[m[1].rm_so]);
404 ret = 0;
405 break;
406 }
407 }
408 }
409
410 regfree(&re);
411 if (ret)
412 sigma_dut_print(dut, DUT_MSG_ERROR,
413 "could not extract field");
414
415out:
416 fclose(f);
417
418 return ret;
419}
420
421
422static int wil6210_get_cid(struct sigma_dut *dut, const char *bssid,
423 unsigned int *cid)
424{
425 const char *pattern = "\\[([0-9]+)\\]";
426
427 return wil6210_get_sta_info_field(dut, bssid, pattern, cid);
428}
429
430
431static int wil6210_send_brp_rx(struct sigma_dut *dut, const char *mac,
432 int l_rx)
433{
Rakesh Sunki556237d2017-03-30 14:49:31 -0700434 struct wil_wmi_bf_trig_cmd cmd;
Lior David0fe101e2017-03-09 16:09:50 +0200435 unsigned int cid;
436
Rakesh Sunki556237d2017-03-30 14:49:31 -0700437 memset(&cmd, 0, sizeof(cmd));
438
Lior David0fe101e2017-03-09 16:09:50 +0200439 if (wil6210_get_cid(dut, mac, &cid))
440 return -1;
441
442 cmd.bf_type = WIL_WMI_BRP_RX;
443 cmd.sta_id = cid;
444 /* training length (l_rx) is ignored, FW always uses length 16 */
445 return wil6210_wmi_send(dut, WIL_WMI_BF_TRIG_CMDID,
446 &cmd, sizeof(cmd));
447}
448
449
450static int wil6210_send_sls(struct sigma_dut *dut, const char *mac)
451{
Rakesh Sunki556237d2017-03-30 14:49:31 -0700452 struct wil_wmi_bf_trig_cmd cmd;
453
454 memset(&cmd, 0, sizeof(cmd));
Lior David0fe101e2017-03-09 16:09:50 +0200455
456 if (parse_mac_address(dut, mac, (unsigned char *)&cmd.dest_mac))
457 return -1;
458
459 cmd.bf_type = WIL_WMI_SLS;
460 return wil6210_wmi_send(dut, WIL_WMI_BF_TRIG_CMDID,
461 &cmd, sizeof(cmd));
462}
463
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +0200464
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +0200465int wil6210_set_ese(struct sigma_dut *dut, int count,
466 struct sigma_ese_alloc *allocs)
467{
468 struct wil_wmi_ese_cfg cmd = { };
469 int i;
470
471 if (count == 0 || count > WIL_WMI_MAX_ESE_SLOTS)
472 return -1;
473
474 if (dut->ap_bcnint <= 0) {
475 sigma_dut_print(dut, DUT_MSG_ERROR,
476 "invalid beacon interval(%d), check test",
477 dut->ap_bcnint);
478 return -1;
479 }
480
481 cmd.ese_advertisment = WIL_WMI_ADVERTISE_ESE_IN_BEACON;
482 cmd.flags = 0x1d;
483 cmd.num_allocs = count;
484 for (i = 0; i < count; i++) {
485 /*
486 * Convert percent from BI (BI specified in milliseconds)
487 * to absolute duration in microseconds.
488 */
489 cmd.slots[i].duration =
490 (allocs[i].percent_bi * dut->ap_bcnint * 1000) / 100;
491 switch (allocs[i].type) {
492 case ESE_CBAP:
493 cmd.slots[i].slot_type = WIL_WMI_ESE_CBAP;
494 break;
495 case ESE_SP:
496 cmd.slots[i].slot_type = WIL_WMI_ESE_SP;
497 break;
498 default:
499 sigma_dut_print(dut, DUT_MSG_ERROR,
500 "invalid slot type(%d) at index %d",
501 allocs[i].type, i);
502 return -1;
503 }
504 cmd.slots[i].src_aid = allocs[i].src_aid;
505 cmd.slots[i].dst_aid = allocs[i].dst_aid;
506 sigma_dut_print(dut, DUT_MSG_INFO,
507 "slot %d, duration %u, type %d, srcAID %u dstAID %u",
508 i, cmd.slots[i].duration,
509 cmd.slots[i].slot_type, cmd.slots[i].src_aid,
510 cmd.slots[i].dst_aid);
511 }
512
513 return wil6210_wmi_send(dut, WIL_WMI_ESE_CFG_CMDID, &cmd, sizeof(cmd));
514}
515
516
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +0200517int wil6210_set_force_mcs(struct sigma_dut *dut, int force, int mcs)
518{
519 struct wil_wmi_force_mcs cmd = { };
520
521 cmd.module_id = WIL_WMI_UT_HW_SYSAPI;
522 cmd.subtype_id = WIL_WMI_UT_FORCE_MCS;
523 cmd.force_enable = (uint32_t) force;
524 cmd.mcs = (uint32_t) mcs;
525
526 return wil6210_wmi_send(dut, WIL_WMI_UNIT_TEST_CMDID,
527 &cmd, sizeof(cmd));
528}
529
530
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +0200531static int wil6210_force_rsn_ie(struct sigma_dut *dut, int state)
532{
533 struct wil_wmi_force_rsn_ie cmd = { };
534
535 cmd.module_id = WIL_WMI_UT_HW_SYSAPI;
536 cmd.subtype_id = WIL_WMI_UT_FORCE_RSN_IE;
537 cmd.state = (uint32_t) state;
538
539 return wil6210_wmi_send(dut, WIL_WMI_UNIT_TEST_CMDID,
540 &cmd, sizeof(cmd));
541}
542
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +0300543
544/*
545 * this function is also used to configure generic remain-on-channel
546 */
547static int wil6210_p2p_cfg(struct sigma_dut *dut, int freq)
548{
549 struct wil_wmi_p2p_cfg_cmd cmd = { };
550 int channel = freq_to_channel(freq);
551
552 if (channel < 0)
553 return -1;
554 cmd.discovery_mode = WMI_DISCOVERY_MODE_NON_OFFLOAD;
555 cmd.channel = channel - 1;
556 cmd.bcon_interval = WIL_DEFAULT_BI;
557 cmd.discovery_mode = WMI_DISCOVERY_MODE_PEER2PEER;
558
559 return wil6210_wmi_send(dut, WIL_WMI_P2P_CFG_CMDID,
560 &cmd, sizeof(cmd));
561}
562
563
564static int wil6210_remain_on_channel(struct sigma_dut *dut, int freq)
565{
566 int ret = wil6210_p2p_cfg(dut, freq);
567
568 if (ret)
569 return ret;
570
571 ret = wil6210_wmi_send(dut, WIL_WMI_START_LISTEN_CMDID, NULL, 0);
572 if (!ret) {
573 /*
574 * wait a bit to allow FW to setup the radio
575 * especially important if we switch channels
576 */
577 usleep(500000);
578 }
579
580 return ret;
581}
582
583
584static int wil6210_stop_discovery(struct sigma_dut *dut)
585{
586 return wil6210_wmi_send(dut, WIL_WMI_DISCOVERY_STOP_CMDID, NULL, 0);
587}
588
589
590static int wil6210_transmit_frame(struct sigma_dut *dut, int freq,
591 int wait_duration,
592 const char *frame, size_t frame_len)
593{
594 char buf[128], fname[128];
595 FILE *f;
596 int res = 0;
597 size_t written;
598
599 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
600 sigma_dut_print(dut, DUT_MSG_ERROR,
601 "failed to get wil6210 debugfs dir");
602 return -1;
603 }
604 snprintf(fname, sizeof(fname), "%s/tx_mgmt", buf);
605
606 if (wil6210_remain_on_channel(dut, freq)) {
607 sigma_dut_print(dut, DUT_MSG_ERROR,
608 "failed to listen on channel");
609 return -1;
610 }
611
612 f = fopen(fname, "wb");
613 if (!f) {
614 sigma_dut_print(dut, DUT_MSG_ERROR,
615 "failed to open: %s", fname);
616 res = -1;
617 goto out_stop;
618 }
619 written = fwrite(frame, 1, frame_len, f);
620 fclose(f);
621
622 if (written != frame_len) {
623 sigma_dut_print(dut, DUT_MSG_ERROR,
624 "failed to transmit frame (got %zd, expected %zd)",
625 written, frame_len);
626 res = -1;
627 goto out_stop;
628 }
629
630 usleep(wait_duration * 1000);
631
632out_stop:
633 wil6210_stop_discovery(dut);
634 return res;
635}
636
637
638static int find_template_frame_tag(struct template_frame_tag *tags,
639 int total_tags, int tag_num)
640{
641 int i;
642
643 for (i = 0; i < total_tags; i++) {
644 if (tag_num == tags[i].num)
645 return i;
646 }
647
648 return -1;
649}
650
651
652static int replace_p2p_attribute(struct sigma_dut *dut, char *buf, size_t len,
653 int id, const char *value, size_t val_len)
654{
655 struct wfa_p2p_attribute *attr = (struct wfa_p2p_attribute *) buf;
656
657 if (len < 3 + val_len) {
658 sigma_dut_print(dut, DUT_MSG_ERROR,
659 "not enough space to replace P2P attribute");
660 return -1;
661 }
662
663 if (attr->len != val_len) {
664 sigma_dut_print(dut, DUT_MSG_ERROR,
665 "attribute length mismatch (need %zu have %hu)",
666 val_len, attr->len);
667 return -1;
668 }
669
670 if (attr->id != id) {
671 sigma_dut_print(dut, DUT_MSG_ERROR,
672 "incorrect attribute id (expected %d actual %d)",
673 id, attr->id);
674 return -1;
675 }
676
677 memcpy(attr->variable, value, val_len);
678
679 return 0;
680}
681
682
683static int parse_template_frame_file(struct sigma_dut *dut, const char *fname,
684 char *buf, size_t *length,
685 struct template_frame_tag *tags,
686 size_t *num_tags)
687{
688 char line[512];
689 FILE *f;
690 size_t offset = 0, tag_index = 0;
691 int num, index;
692 int in_tag = 0, tag_num = 0, tag_offset = 0;
693
694 if (*length < sizeof(struct ieee80211_hdr_3addr)) {
695 sigma_dut_print(dut, DUT_MSG_ERROR,
696 "supplied buffer is too small");
697 return -1;
698 }
699
700 f = fopen(fname, "r");
701 if (!f) {
702 sigma_dut_print(dut, DUT_MSG_ERROR,
703 "failed to open template file %s", fname);
704 return -1;
705 }
706
707 /*
708 * template file format: lines beginning with # are comments and
709 * ignored.
710 * It is possible to tag bytes in the frame to make it easy
711 * to replace fields in the template, espcially if they appear
712 * in variable-sized sections (such as IEs)
713 * This is done by a line beginning with $NUM where NUM is an integer
714 * tag number. It can be followed by space(s) and comment.
715 * The next line is considered the tagged bytes. The parser will fill
716 * the tag number, offset and length of the tagged bytes.
717 * rest of the lines contain frame bytes as sequence of hex digits,
718 * 2 digits for each byte. Spaces are allowed between bytes.
719 * On bytes lines only hex digits and spaces are allowed
720 */
721 while (!feof(f)) {
722 if (!fgets(line, sizeof(line), f))
723 break;
724 index = 0;
725 while (isspace((unsigned char) line[index]))
726 index++;
727 if (!line[index] || line[index] == '#')
728 continue;
729 if (line[index] == '$') {
730 if (tags) {
731 index++;
732 tag_num = strtol(&line[index], NULL, 0);
733 tag_offset = offset;
734 in_tag = 1;
735 }
736 continue;
737 }
738 while (line[index]) {
739 if (isspace((unsigned char) line[index])) {
740 index++;
741 continue;
742 }
743 num = hex_byte(&line[index]);
744 if (num < 0)
745 break;
746 buf[offset++] = num;
747 if (offset == *length)
748 goto out;
749 index += 2;
750 }
751
752 if (in_tag) {
753 if (tag_index < *num_tags) {
754 tags[tag_index].num = tag_num;
755 tags[tag_index].offset = tag_offset;
756 tags[tag_index].len = offset - tag_offset;
757 tag_index++;
758 } else {
759 sigma_dut_print(dut, DUT_MSG_INFO,
760 "too many tags, tag ignored");
761 }
762 in_tag = 0;
763 }
764 }
765
766 if (num_tags)
767 *num_tags = tag_index;
768out:
769 fclose(f);
770 if (offset < sizeof(struct ieee80211_hdr_3addr)) {
771 sigma_dut_print(dut, DUT_MSG_ERROR,
772 "template frame is too small");
773 return -1;
774 }
775
776 *length = offset;
777 return 0;
778}
779
Lior Davidcc88b562017-01-03 18:52:09 +0200780#endif /* __linux__ */
781
782
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200783static void static_ip_file(int proto, const char *addr, const char *mask,
784 const char *gw)
785{
786 if (proto) {
787 FILE *f = fopen("static-ip", "w");
788 if (f) {
789 fprintf(f, "%d %s %s %s\n", proto, addr,
790 mask ? mask : "N/A",
791 gw ? gw : "N/A");
792 fclose(f);
793 }
794 } else {
795 unlink("static-ip");
796 }
797}
798
799
800static int send_neighbor_request(struct sigma_dut *dut, const char *intf,
801 const char *ssid)
802{
803#ifdef __linux__
804 char buf[100];
805
806 snprintf(buf, sizeof(buf), "iwpriv %s neighbor %s",
807 intf, ssid);
808 sigma_dut_print(dut, DUT_MSG_INFO, "Request: %s", buf);
809
810 if (system(buf) != 0) {
811 sigma_dut_print(dut, DUT_MSG_ERROR,
812 "iwpriv neighbor request failed");
813 return -1;
814 }
815
816 sigma_dut_print(dut, DUT_MSG_INFO, "iwpriv neighbor request send");
817
818 return 0;
819#else /* __linux__ */
820 return -1;
821#endif /* __linux__ */
822}
823
824
825static int send_trans_mgmt_query(struct sigma_dut *dut, const char *intf,
Ashwini Patil5acd7382017-04-13 15:55:04 +0530826 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200827{
Ashwini Patil5acd7382017-04-13 15:55:04 +0530828 const char *val;
829 int reason_code = 0;
830 char buf[1024];
831
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200832 /*
833 * In the earlier builds we used WNM_QUERY and in later
834 * builds used WNM_BSS_QUERY.
835 */
836
Ashwini Patil5acd7382017-04-13 15:55:04 +0530837 val = get_param(cmd, "BTMQuery_Reason_Code");
838 if (val)
839 reason_code = atoi(val);
840
841 val = get_param(cmd, "Cand_List");
842 if (val && atoi(val) == 1 && dut->btm_query_cand_list) {
843 snprintf(buf, sizeof(buf), "WNM_BSS_QUERY %d%s", reason_code,
844 dut->btm_query_cand_list);
845 free(dut->btm_query_cand_list);
846 dut->btm_query_cand_list = NULL;
847 } else {
848 snprintf(buf, sizeof(buf), "WNM_BSS_QUERY %d", reason_code);
849 }
850
851 if (wpa_command(intf, buf) != 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200852 sigma_dut_print(dut, DUT_MSG_ERROR,
853 "transition management query failed");
854 return -1;
855 }
856
857 sigma_dut_print(dut, DUT_MSG_DEBUG,
858 "transition management query sent");
859
860 return 0;
861}
862
863
864int is_ip_addr(const char *str)
865{
866 const char *pos = str;
867 struct in_addr addr;
868
869 while (*pos) {
870 if (*pos != '.' && (*pos < '0' || *pos > '9'))
871 return 0;
872 pos++;
873 }
874
875 return inet_aton(str, &addr);
876}
877
878
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200879int get_ip_config(struct sigma_dut *dut, const char *ifname, char *buf,
880 size_t buf_len)
881{
vamsi krishnaa11d0732018-05-16 12:19:48 +0530882 char tmp[256];
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200883 char ip[16], mask[15], dns[16], sec_dns[16];
884 int is_dhcp = 0;
885 int s;
886#ifdef ANDROID
887 char prop[PROPERTY_VALUE_MAX];
vamsi krishnaa11d0732018-05-16 12:19:48 +0530888#else /* ANDROID */
889 FILE *f;
890#ifdef __linux__
891 const char *str_ps;
892#endif /* __linux__ */
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200893#endif /* ANDROID */
894
895 ip[0] = '\0';
896 mask[0] = '\0';
897 dns[0] = '\0';
898 sec_dns[0] = '\0';
899
900 s = socket(PF_INET, SOCK_DGRAM, 0);
901 if (s >= 0) {
902 struct ifreq ifr;
903 struct sockaddr_in saddr;
904
905 memset(&ifr, 0, sizeof(ifr));
Peng Xub8fc5cc2017-05-10 17:27:28 -0700906 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200907 if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
908 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to get "
909 "%s IP address: %s",
910 ifname, strerror(errno));
911 } else {
912 memcpy(&saddr, &ifr.ifr_addr,
913 sizeof(struct sockaddr_in));
Peng Xub8fc5cc2017-05-10 17:27:28 -0700914 strlcpy(ip, inet_ntoa(saddr.sin_addr), sizeof(ip));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200915 }
916
917 if (ioctl(s, SIOCGIFNETMASK, &ifr) == 0) {
918 memcpy(&saddr, &ifr.ifr_addr,
919 sizeof(struct sockaddr_in));
Peng Xub8fc5cc2017-05-10 17:27:28 -0700920 strlcpy(mask, inet_ntoa(saddr.sin_addr), sizeof(mask));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200921 }
922 close(s);
923 }
924
925#ifdef ANDROID
926 snprintf(tmp, sizeof(tmp), "dhcp.%s.pid", ifname);
927 if (property_get(tmp, prop, NULL) != 0 && atoi(prop) > 0) {
928 snprintf(tmp, sizeof(tmp), "dhcp.%s.result", ifname);
929 if (property_get(tmp, prop, NULL) != 0 &&
930 strcmp(prop, "ok") == 0) {
931 snprintf(tmp, sizeof(tmp), "dhcp.%s.ipaddress",
932 ifname);
933 if (property_get(tmp, prop, NULL) != 0 &&
934 strcmp(ip, prop) == 0)
935 is_dhcp = 1;
936 }
937 }
938
939 snprintf(tmp, sizeof(tmp), "dhcp.%s.dns1", ifname);
Peng Xub8fc5cc2017-05-10 17:27:28 -0700940 if (property_get(tmp, prop, NULL) != 0)
941 strlcpy(dns, prop, sizeof(dns));
942 else if (property_get("net.dns1", prop, NULL) != 0)
943 strlcpy(dns, prop, sizeof(dns));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200944
945 snprintf(tmp, sizeof(tmp), "dhcp.%s.dns2", ifname);
Peng Xub8fc5cc2017-05-10 17:27:28 -0700946 if (property_get(tmp, prop, NULL) != 0)
947 strlcpy(sec_dns, prop, sizeof(sec_dns));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200948#else /* ANDROID */
949#ifdef __linux__
Sarvepalli, Rajesh Babua76c6442016-03-18 20:34:26 +0530950 if (get_driver_type() == DRIVER_OPENWRT)
951 str_ps = "ps -w";
952 else
953 str_ps = "ps ax";
954 snprintf(tmp, sizeof(tmp),
955 "%s | grep dhclient | grep -v grep | grep -q %s",
956 str_ps, ifname);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200957 if (system(tmp) == 0)
958 is_dhcp = 1;
959 else {
Sarvepalli, Rajesh Babua76c6442016-03-18 20:34:26 +0530960 snprintf(tmp, sizeof(tmp),
961 "%s | grep udhcpc | grep -v grep | grep -q %s",
962 str_ps, ifname);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200963 if (system(tmp) == 0)
964 is_dhcp = 1;
965 else {
Sarvepalli, Rajesh Babua76c6442016-03-18 20:34:26 +0530966 snprintf(tmp, sizeof(tmp),
967 "%s | grep dhcpcd | grep -v grep | grep -q %s",
968 str_ps, ifname);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200969 if (system(tmp) == 0)
970 is_dhcp = 1;
971 }
972 }
973#endif /* __linux__ */
974
975 f = fopen("/etc/resolv.conf", "r");
976 if (f) {
vamsi krishnaa11d0732018-05-16 12:19:48 +0530977 char *pos, *pos2;
978
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200979 while (fgets(tmp, sizeof(tmp), f)) {
980 if (strncmp(tmp, "nameserver", 10) != 0)
981 continue;
982 pos = tmp + 10;
983 while (*pos == ' ' || *pos == '\t')
984 pos++;
985 pos2 = pos;
986 while (*pos2) {
987 if (*pos2 == '\n' || *pos2 == '\r') {
988 *pos2 = '\0';
989 break;
990 }
991 pos2++;
992 }
Peng Xub8fc5cc2017-05-10 17:27:28 -0700993 if (!dns[0])
994 strlcpy(dns, pos, sizeof(dns));
995 else if (!sec_dns[0])
996 strlcpy(sec_dns, pos, sizeof(sec_dns));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200997 }
998 fclose(f);
999 }
1000#endif /* ANDROID */
1001
1002 snprintf(buf, buf_len, "dhcp,%d,ip,%s,mask,%s,primary-dns,%s",
1003 is_dhcp, ip, mask, dns);
1004 buf[buf_len - 1] = '\0';
1005
1006 return 0;
1007}
1008
1009
1010
1011
1012int get_ipv6_config(struct sigma_dut *dut, const char *ifname, char *buf,
1013 size_t buf_len)
1014{
1015#ifdef __linux__
1016#ifdef ANDROID
1017 char cmd[200], result[1000], *pos, *end;
1018 FILE *f;
1019 size_t len;
1020
1021 snprintf(cmd, sizeof(cmd), "ip addr show dev %s scope global", ifname);
1022 f = popen(cmd, "r");
1023 if (f == NULL)
1024 return -1;
1025 len = fread(result, 1, sizeof(result) - 1, f);
1026 pclose(f);
1027 if (len == 0)
1028 return -1;
1029 result[len] = '\0';
1030 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s result: %s\n", cmd, result);
1031
1032 pos = strstr(result, "inet6 ");
1033 if (pos == NULL)
1034 return -1;
1035 pos += 6;
1036 end = strchr(pos, ' ');
1037 if (end)
1038 *end = '\0';
1039 end = strchr(pos, '/');
1040 if (end)
1041 *end = '\0';
1042 snprintf(buf, buf_len, "ip,%s", pos);
1043 buf[buf_len - 1] = '\0';
1044 return 0;
1045#else /* ANDROID */
1046 struct ifaddrs *ifaddr, *ifa;
1047 int res, found = 0;
1048 char host[NI_MAXHOST];
1049
1050 if (getifaddrs(&ifaddr) < 0) {
1051 perror("getifaddrs");
1052 return -1;
1053 }
1054
1055 for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
1056 if (strcasecmp(ifname, ifa->ifa_name) != 0)
1057 continue;
1058 if (ifa->ifa_addr == NULL ||
1059 ifa->ifa_addr->sa_family != AF_INET6)
1060 continue;
1061
1062 res = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in6),
1063 host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
1064 if (res != 0) {
1065 sigma_dut_print(dut, DUT_MSG_DEBUG, "getnameinfo: %s",
1066 gai_strerror(res));
1067 continue;
1068 }
1069 if (strncmp(host, "fe80::", 6) == 0)
1070 continue; /* skip link-local */
1071
1072 sigma_dut_print(dut, DUT_MSG_DEBUG, "ifaddr: %s", host);
1073 found = 1;
1074 break;
1075 }
1076
1077 freeifaddrs(ifaddr);
1078
1079 if (found) {
1080 char *pos;
1081 pos = strchr(host, '%');
1082 if (pos)
1083 *pos = '\0';
1084 snprintf(buf, buf_len, "ip,%s", host);
1085 buf[buf_len - 1] = '\0';
1086 return 0;
1087 }
1088
1089#endif /* ANDROID */
1090#endif /* __linux__ */
1091 return -1;
1092}
1093
1094
1095static int cmd_sta_get_ip_config(struct sigma_dut *dut,
1096 struct sigma_conn *conn,
1097 struct sigma_cmd *cmd)
1098{
1099 const char *intf = get_param(cmd, "Interface");
1100 const char *ifname;
1101 char buf[200];
1102 const char *val;
1103 int type = 1;
1104
1105 if (intf == NULL)
1106 return -1;
1107
1108 if (strcmp(intf, get_main_ifname()) == 0)
1109 ifname = get_station_ifname();
1110 else
1111 ifname = intf;
1112
1113 /*
1114 * UCC may assume the IP address to be available immediately after
1115 * association without trying to run sta_get_ip_config multiple times.
1116 * Sigma CAPI does not specify this command as a block command that
1117 * would wait for the address to become available, but to pass tests
1118 * more reliably, it looks like such a wait may be needed here.
1119 */
1120 if (wait_ip_addr(dut, ifname, 15) < 0) {
1121 sigma_dut_print(dut, DUT_MSG_INFO, "Could not get IP address "
1122 "for sta_get_ip_config");
1123 /*
1124 * Try to continue anyway since many UCC tests do not really
1125 * care about the return value from here..
1126 */
1127 }
1128
1129 val = get_param(cmd, "Type");
1130 if (val)
1131 type = atoi(val);
1132 if (type == 2 || dut->last_set_ip_config_ipv6) {
1133 int i;
1134
1135 /*
1136 * Since we do not have proper wait for IPv6 addresses, use a
1137 * fixed two second delay here as a workaround for UCC script
1138 * assuming IPv6 address is available when this command returns.
1139 * Some scripts did not use Type,2 properly for IPv6, so include
1140 * also the cases where the previous sta_set_ip_config indicated
1141 * use of IPv6.
1142 */
1143 sigma_dut_print(dut, DUT_MSG_INFO, "Wait up to extra ten seconds in sta_get_ip_config for IPv6 address");
1144 for (i = 0; i < 10; i++) {
1145 sleep(1);
1146 if (get_ipv6_config(dut, ifname, buf, sizeof(buf)) == 0)
1147 {
1148 sigma_dut_print(dut, DUT_MSG_INFO, "Found IPv6 address");
1149 send_resp(dut, conn, SIGMA_COMPLETE, buf);
1150#ifdef ANDROID
1151 sigma_dut_print(dut, DUT_MSG_INFO,
1152 "Adding IPv6 rule on Android");
1153 add_ipv6_rule(dut, intf);
1154#endif /* ANDROID */
1155
1156 return 0;
1157 }
1158 }
1159 }
1160 if (type == 1) {
1161 if (get_ip_config(dut, ifname, buf, sizeof(buf)) < 0)
1162 return -2;
1163 } else if (type == 2) {
1164 if (get_ipv6_config(dut, ifname, buf, sizeof(buf)) < 0)
1165 return -2;
1166 } else {
1167 send_resp(dut, conn, SIGMA_ERROR,
1168 "errorCode,Unsupported address type");
1169 return 0;
1170 }
1171
1172 send_resp(dut, conn, SIGMA_COMPLETE, buf);
1173 return 0;
1174}
1175
1176
1177static void kill_dhcp_client(struct sigma_dut *dut, const char *ifname)
1178{
1179#ifdef __linux__
1180 char buf[200];
1181 char path[128];
1182 struct stat s;
1183
1184#ifdef ANDROID
1185 snprintf(path, sizeof(path), "/data/misc/dhcp/dhcpcd-%s.pid", ifname);
1186#else /* ANDROID */
1187 snprintf(path, sizeof(path), "/var/run/dhclient-%s.pid", ifname);
1188#endif /* ANDROID */
1189 if (stat(path, &s) == 0) {
1190 snprintf(buf, sizeof(buf), "kill `cat %s`", path);
1191 sigma_dut_print(dut, DUT_MSG_INFO,
1192 "Kill previous DHCP client: %s", buf);
1193 if (system(buf) != 0)
1194 sigma_dut_print(dut, DUT_MSG_INFO,
1195 "Failed to kill DHCP client");
1196 unlink(path);
1197 sleep(1);
1198 } else {
1199 snprintf(path, sizeof(path), "/var/run/dhcpcd-%s.pid", ifname);
1200
1201 if (stat(path, &s) == 0) {
1202 snprintf(buf, sizeof(buf), "kill `cat %s`", path);
1203 sigma_dut_print(dut, DUT_MSG_INFO,
1204 "Kill previous DHCP client: %s", buf);
1205 if (system(buf) != 0)
1206 sigma_dut_print(dut, DUT_MSG_INFO,
1207 "Failed to kill DHCP client");
1208 unlink(path);
1209 sleep(1);
1210 }
1211 }
1212#endif /* __linux__ */
1213}
1214
1215
1216static int start_dhcp_client(struct sigma_dut *dut, const char *ifname)
1217{
1218#ifdef __linux__
1219 char buf[200];
1220
1221#ifdef ANDROID
Purushottam Kushwaha46d64262016-08-23 17:57:53 +05301222 if (access("/system/bin/dhcpcd", F_OK) != -1) {
1223 snprintf(buf, sizeof(buf),
1224 "/system/bin/dhcpcd -b %s", ifname);
1225 } else if (access("/system/bin/dhcptool", F_OK) != -1) {
1226 snprintf(buf, sizeof(buf), "/system/bin/dhcptool %s &", ifname);
Ankita Bajaj8454e5d2019-04-05 16:04:55 +05301227 } else if (access("/vendor/bin/dhcpcd", F_OK) != -1) {
1228 snprintf(buf, sizeof(buf), "/vendor/bin/dhcpcd -b %s", ifname);
1229 } else if (access("/vendor/bin/dhcptool", F_OK) != -1) {
1230 snprintf(buf, sizeof(buf), "/vendor/bin/dhcptool %s", ifname);
Purushottam Kushwaha46d64262016-08-23 17:57:53 +05301231 } else {
1232 sigma_dut_print(dut, DUT_MSG_ERROR,
1233 "DHCP client program missing");
1234 return 0;
1235 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001236#else /* ANDROID */
1237 snprintf(buf, sizeof(buf),
1238 "dhclient -nw -pf /var/run/dhclient-%s.pid %s",
1239 ifname, ifname);
1240#endif /* ANDROID */
1241 sigma_dut_print(dut, DUT_MSG_INFO, "Start DHCP client: %s", buf);
1242 if (system(buf) != 0) {
1243 snprintf(buf, sizeof(buf), "dhcpcd -t 0 %s &", ifname);
1244 if (system(buf) != 0) {
1245 sigma_dut_print(dut, DUT_MSG_INFO,
1246 "Failed to start DHCP client");
1247#ifndef ANDROID
1248 return -1;
1249#endif /* ANDROID */
1250 }
1251 }
1252#endif /* __linux__ */
1253
1254 return 0;
1255}
1256
1257
1258static int clear_ip_addr(struct sigma_dut *dut, const char *ifname)
1259{
1260#ifdef __linux__
1261 char buf[200];
1262
1263 snprintf(buf, sizeof(buf), "ip addr flush dev %s", ifname);
1264 if (system(buf) != 0) {
1265 sigma_dut_print(dut, DUT_MSG_INFO,
1266 "Failed to clear IP addresses");
1267 return -1;
1268 }
1269#endif /* __linux__ */
1270
1271 return 0;
1272}
1273
1274
1275#ifdef ANDROID
1276static int add_ipv6_rule(struct sigma_dut *dut, const char *ifname)
1277{
1278 char cmd[200], *result, *pos;
1279 FILE *fp;
Pradeep Reddy POTTETIf58a1fe2016-10-13 17:22:03 +05301280 int tableid;
1281 size_t len, result_len = 1000;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001282
1283 snprintf(cmd, sizeof(cmd), "ip -6 route list table all | grep %s",
1284 ifname);
1285 fp = popen(cmd, "r");
1286 if (fp == NULL)
1287 return -1;
1288
1289 result = malloc(result_len);
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05301290 if (result == NULL) {
1291 fclose(fp);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001292 return -1;
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05301293 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001294
Pradeep Reddy POTTETIf58a1fe2016-10-13 17:22:03 +05301295 len = fread(result, 1, result_len - 1, fp);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001296 fclose(fp);
1297
1298 if (len == 0) {
1299 free(result);
1300 return -1;
1301 }
Pradeep Reddy POTTETIf58a1fe2016-10-13 17:22:03 +05301302 result[len] = '\0';
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001303
1304 pos = strstr(result, "table ");
1305 if (pos == NULL) {
1306 free(result);
1307 return -1;
1308 }
1309
1310 pos += strlen("table ");
1311 tableid = atoi(pos);
1312 if (tableid != 0) {
1313 if (system("ip -6 rule del prio 22000") != 0) {
1314 /* ignore any error */
1315 }
1316 snprintf(cmd, sizeof(cmd),
1317 "ip -6 rule add from all lookup %d prio 22000",
1318 tableid);
1319 if (system(cmd) != 0) {
1320 sigma_dut_print(dut, DUT_MSG_INFO,
1321 "Failed to run %s", cmd);
1322 free(result);
1323 return -1;
1324 }
1325 } else {
1326 sigma_dut_print(dut, DUT_MSG_INFO,
1327 "No Valid Table Id found %s", pos);
1328 free(result);
1329 return -1;
1330 }
1331 free(result);
1332
1333 return 0;
1334}
1335#endif /* ANDROID */
1336
1337
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301338int set_ipv4_addr(struct sigma_dut *dut, const char *ifname,
1339 const char *ip, const char *mask)
1340{
1341 char buf[200];
1342
1343 snprintf(buf, sizeof(buf), "ifconfig %s %s netmask %s",
1344 ifname, ip, mask);
1345 return system(buf) == 0;
1346}
1347
1348
1349int set_ipv4_gw(struct sigma_dut *dut, const char *gw)
1350{
1351 char buf[200];
1352
1353 if (!is_ip_addr(gw)) {
1354 sigma_dut_print(dut, DUT_MSG_DEBUG, "Invalid gw addr - %s", gw);
1355 return -1;
1356 }
1357
1358 snprintf(buf, sizeof(buf), "route add default gw %s", gw);
1359 if (!dut->no_ip_addr_set && system(buf) != 0) {
1360 snprintf(buf, sizeof(buf), "ip ro re default via %s",
1361 gw);
1362 if (system(buf) != 0)
1363 return 0;
1364 }
1365
1366 return 1;
1367}
1368
1369
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001370static int cmd_sta_set_ip_config(struct sigma_dut *dut,
1371 struct sigma_conn *conn,
1372 struct sigma_cmd *cmd)
1373{
1374 const char *intf = get_param(cmd, "Interface");
1375 const char *ifname;
1376 char buf[200];
1377 const char *val, *ip, *mask, *gw;
1378 int type = 1;
1379
1380 if (intf == NULL)
1381 return -1;
1382
1383 if (strcmp(intf, get_main_ifname()) == 0)
1384 ifname = get_station_ifname();
1385 else
1386 ifname = intf;
1387
1388 if (if_nametoindex(ifname) == 0) {
1389 send_resp(dut, conn, SIGMA_ERROR,
1390 "ErrorCode,Unknown interface");
1391 return 0;
1392 }
1393
1394 val = get_param(cmd, "Type");
1395 if (val) {
1396 type = atoi(val);
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301397 if (type < 1 || type > 3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001398 send_resp(dut, conn, SIGMA_ERROR,
1399 "ErrorCode,Unsupported address type");
1400 return 0;
1401 }
1402 }
1403
1404 dut->last_set_ip_config_ipv6 = 0;
1405
1406 val = get_param(cmd, "dhcp");
1407 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "true") == 0)) {
1408 static_ip_file(0, NULL, NULL, NULL);
1409#ifdef __linux__
1410 if (type == 2) {
1411 dut->last_set_ip_config_ipv6 = 1;
1412 sigma_dut_print(dut, DUT_MSG_INFO, "Using IPv6 "
1413 "stateless address autoconfiguration");
1414#ifdef ANDROID
1415 /*
1416 * This sleep is required as the assignment in case of
1417 * Android is taking time and is done by the kernel.
1418 * The subsequent ping for IPv6 is impacting HS20 test
1419 * case.
1420 */
1421 sleep(2);
1422 add_ipv6_rule(dut, intf);
1423#endif /* ANDROID */
1424 /* Assume this happens by default */
1425 return 1;
1426 }
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301427 if (type != 3) {
1428 kill_dhcp_client(dut, ifname);
1429 if (start_dhcp_client(dut, ifname) < 0)
1430 return -2;
1431 } else {
1432 sigma_dut_print(dut, DUT_MSG_DEBUG,
1433 "Using FILS HLP DHCPv4 Rapid Commit");
1434 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001435
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001436 return 1;
1437#endif /* __linux__ */
1438 return -2;
1439 }
1440
1441 ip = get_param(cmd, "ip");
Pradeep Reddy POTTETIb18c5652016-01-18 12:45:37 +05301442 if (!ip) {
1443 send_resp(dut, conn, SIGMA_INVALID,
1444 "ErrorCode,Missing IP address");
1445 return 0;
1446 }
1447
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001448 mask = get_param(cmd, "mask");
Pradeep Reddy POTTETIb18c5652016-01-18 12:45:37 +05301449 if (!mask) {
1450 send_resp(dut, conn, SIGMA_INVALID,
1451 "ErrorCode,Missing subnet mask");
1452 return 0;
1453 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001454
1455 if (type == 2) {
1456 int net = atoi(mask);
1457
1458 if ((net < 0 && net > 64) || !is_ipv6_addr(ip))
1459 return -1;
1460
1461 if (dut->no_ip_addr_set) {
1462 snprintf(buf, sizeof(buf),
1463 "sysctl net.ipv6.conf.%s.disable_ipv6=1",
1464 ifname);
1465 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
1466 if (system(buf) != 0) {
1467 sigma_dut_print(dut, DUT_MSG_DEBUG,
1468 "Failed to disable IPv6 address before association");
1469 }
1470 } else {
1471 snprintf(buf, sizeof(buf),
1472 "ip -6 addr del %s/%s dev %s",
1473 ip, mask, ifname);
1474 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
1475 if (system(buf) != 0) {
1476 /*
1477 * This command may fail if the address being
1478 * deleted does not exist. Inaction here is
1479 * intentional.
1480 */
1481 }
1482
1483 snprintf(buf, sizeof(buf),
1484 "ip -6 addr add %s/%s dev %s",
1485 ip, mask, ifname);
1486 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
1487 if (system(buf) != 0) {
1488 send_resp(dut, conn, SIGMA_ERROR,
1489 "ErrorCode,Failed to set IPv6 address");
1490 return 0;
1491 }
1492 }
1493
1494 dut->last_set_ip_config_ipv6 = 1;
1495 static_ip_file(6, ip, mask, NULL);
1496 return 1;
1497 } else if (type == 1) {
Pradeep Reddy POTTETIb18c5652016-01-18 12:45:37 +05301498 if (!is_ip_addr(ip) || !is_ip_addr(mask))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001499 return -1;
1500 }
1501
1502 kill_dhcp_client(dut, ifname);
1503
1504 if (!dut->no_ip_addr_set) {
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301505 if (!set_ipv4_addr(dut, ifname, ip, mask)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001506 send_resp(dut, conn, SIGMA_ERROR,
1507 "ErrorCode,Failed to set IP address");
1508 return 0;
1509 }
1510 }
1511
1512 gw = get_param(cmd, "defaultGateway");
1513 if (gw) {
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301514 if (set_ipv4_gw(dut, gw) < 1) {
1515 send_resp(dut, conn, SIGMA_ERROR,
1516 "ErrorCode,Failed to set default gateway");
1517 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001518 }
1519 }
1520
1521 val = get_param(cmd, "primary-dns");
1522 if (val) {
1523 /* TODO */
1524 sigma_dut_print(dut, DUT_MSG_INFO, "Ignored primary-dns %s "
1525 "setting", val);
1526 }
1527
1528 val = get_param(cmd, "secondary-dns");
1529 if (val) {
1530 /* TODO */
1531 sigma_dut_print(dut, DUT_MSG_INFO, "Ignored secondary-dns %s "
1532 "setting", val);
1533 }
1534
1535 static_ip_file(4, ip, mask, gw);
1536
1537 return 1;
1538}
1539
1540
1541static int cmd_sta_get_info(struct sigma_dut *dut, struct sigma_conn *conn,
1542 struct sigma_cmd *cmd)
1543{
1544 /* const char *intf = get_param(cmd, "Interface"); */
1545 /* TODO: could report more details here */
1546 send_resp(dut, conn, SIGMA_COMPLETE, "vendor,Atheros");
1547 return 0;
1548}
1549
1550
1551static int cmd_sta_get_mac_address(struct sigma_dut *dut,
1552 struct sigma_conn *conn,
1553 struct sigma_cmd *cmd)
1554{
1555 /* const char *intf = get_param(cmd, "Interface"); */
1556 char addr[20], resp[50];
1557
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05301558 if (dut->dev_role == DEVROLE_STA_CFON)
1559 return sta_cfon_get_mac_address(dut, conn, cmd);
1560
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001561 if (get_wpa_status(get_station_ifname(), "address", addr, sizeof(addr))
1562 < 0)
1563 return -2;
1564
1565 snprintf(resp, sizeof(resp), "mac,%s", addr);
1566 send_resp(dut, conn, SIGMA_COMPLETE, resp);
1567 return 0;
1568}
1569
1570
1571static int cmd_sta_is_connected(struct sigma_dut *dut, struct sigma_conn *conn,
1572 struct sigma_cmd *cmd)
1573{
1574 /* const char *intf = get_param(cmd, "Interface"); */
1575 int connected = 0;
1576 char result[32];
1577 if (get_wpa_status(get_station_ifname(), "wpa_state", result,
1578 sizeof(result)) < 0) {
1579 sigma_dut_print(dut, DUT_MSG_INFO, "Could not get interface "
1580 "%s status", get_station_ifname());
1581 return -2;
1582 }
1583
1584 sigma_dut_print(dut, DUT_MSG_DEBUG, "wpa_state=%s", result);
1585 if (strncmp(result, "COMPLETED", 9) == 0)
1586 connected = 1;
1587
1588 if (connected)
1589 send_resp(dut, conn, SIGMA_COMPLETE, "connected,1");
1590 else
1591 send_resp(dut, conn, SIGMA_COMPLETE, "connected,0");
1592
1593 return 0;
1594}
1595
1596
1597static int cmd_sta_verify_ip_connection(struct sigma_dut *dut,
1598 struct sigma_conn *conn,
1599 struct sigma_cmd *cmd)
1600{
1601 /* const char *intf = get_param(cmd, "Interface"); */
1602 const char *dst, *timeout;
1603 int wait_time = 90;
1604 char buf[100];
1605 int res;
1606
1607 dst = get_param(cmd, "destination");
1608 if (dst == NULL || !is_ip_addr(dst))
1609 return -1;
1610
1611 timeout = get_param(cmd, "timeout");
1612 if (timeout) {
1613 wait_time = atoi(timeout);
1614 if (wait_time < 1)
1615 wait_time = 1;
1616 }
1617
1618 /* TODO: force renewal of IP lease if DHCP is enabled */
1619
1620 snprintf(buf, sizeof(buf), "ping %s -c 3 -W %d", dst, wait_time);
1621 res = system(buf);
1622 sigma_dut_print(dut, DUT_MSG_DEBUG, "ping returned: %d", res);
1623 if (res == 0)
1624 send_resp(dut, conn, SIGMA_COMPLETE, "connected,1");
1625 else if (res == 256)
1626 send_resp(dut, conn, SIGMA_COMPLETE, "connected,0");
1627 else
1628 return -2;
1629
1630 return 0;
1631}
1632
1633
1634static int cmd_sta_get_bssid(struct sigma_dut *dut, struct sigma_conn *conn,
1635 struct sigma_cmd *cmd)
1636{
1637 /* const char *intf = get_param(cmd, "Interface"); */
1638 char bssid[20], resp[50];
1639
1640 if (get_wpa_status(get_station_ifname(), "bssid", bssid, sizeof(bssid))
1641 < 0)
Peng Xub8fc5cc2017-05-10 17:27:28 -07001642 strlcpy(bssid, "00:00:00:00:00:00", sizeof(bssid));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001643
1644 snprintf(resp, sizeof(resp), "bssid,%s", bssid);
1645 send_resp(dut, conn, SIGMA_COMPLETE, resp);
1646 return 0;
1647}
1648
1649
1650#ifdef __SAMSUNG__
1651static int add_use_network(const char *ifname)
1652{
1653 char buf[100];
1654
1655 snprintf(buf, sizeof(buf), "USE_NETWORK ON");
1656 wpa_command(ifname, buf);
1657 return 0;
1658}
1659#endif /* __SAMSUNG__ */
1660
1661
1662static int add_network_common(struct sigma_dut *dut, struct sigma_conn *conn,
1663 const char *ifname, struct sigma_cmd *cmd)
1664{
1665 const char *ssid = get_param(cmd, "ssid");
1666 int id;
1667 const char *val;
1668
1669 if (ssid == NULL)
1670 return -1;
1671
1672 start_sta_mode(dut);
1673
1674#ifdef __SAMSUNG__
1675 add_use_network(ifname);
1676#endif /* __SAMSUNG__ */
1677
1678 id = add_network(ifname);
1679 if (id < 0)
1680 return -2;
1681 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding network %d", id);
1682
1683 if (set_network_quoted(ifname, id, "ssid", ssid) < 0)
1684 return -2;
1685
1686 dut->infra_network_id = id;
1687 snprintf(dut->infra_ssid, sizeof(dut->infra_ssid), "%s", ssid);
1688
1689 val = get_param(cmd, "program");
1690 if (!val)
1691 val = get_param(cmd, "prog");
1692 if (val && strcasecmp(val, "hs2") == 0) {
1693 char buf[100];
1694 snprintf(buf, sizeof(buf), "ENABLE_NETWORK %d no-connect", id);
1695 wpa_command(ifname, buf);
1696
1697 val = get_param(cmd, "prefer");
1698 if (val && atoi(val) > 0)
1699 set_network(ifname, id, "priority", "1");
1700 }
1701
1702 return id;
1703}
1704
1705
1706static int cmd_sta_set_encryption(struct sigma_dut *dut,
1707 struct sigma_conn *conn,
1708 struct sigma_cmd *cmd)
1709{
1710 const char *intf = get_param(cmd, "Interface");
1711 const char *ssid = get_param(cmd, "ssid");
1712 const char *type = get_param(cmd, "encpType");
1713 const char *ifname;
1714 char buf[200];
1715 int id;
1716
1717 if (intf == NULL || ssid == NULL)
1718 return -1;
1719
1720 if (strcmp(intf, get_main_ifname()) == 0)
1721 ifname = get_station_ifname();
1722 else
1723 ifname = intf;
1724
1725 id = add_network_common(dut, conn, ifname, cmd);
1726 if (id < 0)
1727 return id;
1728
1729 if (set_network(ifname, id, "key_mgmt", "NONE") < 0)
1730 return -2;
1731
1732 if (type && strcasecmp(type, "wep") == 0) {
1733 const char *val;
1734 int i;
1735
1736 val = get_param(cmd, "activeKey");
1737 if (val) {
1738 int keyid;
1739 keyid = atoi(val);
1740 if (keyid < 1 || keyid > 4)
1741 return -1;
1742 snprintf(buf, sizeof(buf), "%d", keyid - 1);
1743 if (set_network(ifname, id, "wep_tx_keyidx", buf) < 0)
1744 return -2;
1745 }
1746
1747 for (i = 0; i < 4; i++) {
1748 snprintf(buf, sizeof(buf), "key%d", i + 1);
1749 val = get_param(cmd, buf);
1750 if (val == NULL)
1751 continue;
1752 snprintf(buf, sizeof(buf), "wep_key%d", i);
1753 if (set_network(ifname, id, buf, val) < 0)
1754 return -2;
1755 }
1756 }
1757
1758 return 1;
1759}
1760
1761
Jouni Malinene4fde732019-03-25 22:29:37 +02001762static int set_akm_suites(struct sigma_dut *dut, const char *ifname,
1763 int id, const char *val)
1764{
1765 char key_mgmt[200], *end, *pos;
1766 const char *in_pos = val;
1767
Jouni Malinen8179fee2019-03-28 03:19:47 +02001768 dut->akm_values = 0;
Jouni Malinene4fde732019-03-25 22:29:37 +02001769 pos = key_mgmt;
1770 end = pos + sizeof(key_mgmt);
1771 while (*in_pos) {
1772 int res, akm = atoi(in_pos);
1773 const char *str;
1774
Jouni Malinen8179fee2019-03-28 03:19:47 +02001775 if (akm >= 0 && akm < 32)
1776 dut->akm_values |= 1 << akm;
1777
Jouni Malinene4fde732019-03-25 22:29:37 +02001778 switch (akm) {
1779 case AKM_WPA_EAP:
1780 str = "WPA-EAP";
1781 break;
1782 case AKM_WPA_PSK:
1783 str = "WPA-PSK";
1784 break;
1785 case AKM_FT_EAP:
1786 str = "FT-EAP";
1787 break;
1788 case AKM_FT_PSK:
1789 str = "FT-PSK";
1790 break;
1791 case AKM_EAP_SHA256:
1792 str = "WPA-EAP-SHA256";
1793 break;
1794 case AKM_PSK_SHA256:
1795 str = "WPA-PSK-SHA256";
1796 break;
1797 case AKM_SAE:
1798 str = "SAE";
1799 break;
1800 case AKM_FT_SAE:
1801 str = "FT-SAE";
1802 break;
1803 case AKM_SUITE_B:
1804 str = "WPA-EAP-SUITE-B-192";
1805 break;
1806 case AKM_FT_SUITE_B:
1807 str = "FT-EAP-SHA384";
1808 break;
1809 case AKM_FILS_SHA256:
1810 str = "FILS-SHA256";
1811 break;
1812 case AKM_FILS_SHA384:
1813 str = "FILS-SHA384";
1814 break;
1815 case AKM_FT_FILS_SHA256:
1816 str = "FT-FILS-SHA256";
1817 break;
1818 case AKM_FT_FILS_SHA384:
1819 str = "FT-FILS-SHA384";
1820 break;
1821 default:
1822 sigma_dut_print(dut, DUT_MSG_ERROR,
1823 "Unsupported AKMSuitetype %d", akm);
1824 return -1;
1825 }
1826
1827 res = snprintf(pos, end - pos, "%s%s",
1828 pos == key_mgmt ? "" : " ", str);
1829 if (res < 0 || res >= end - pos)
1830 return -1;
1831 pos += res;
1832
1833 in_pos = strchr(in_pos, ';');
1834 if (!in_pos)
1835 break;
1836 while (*in_pos == ';')
1837 in_pos++;
1838 }
1839 sigma_dut_print(dut, DUT_MSG_DEBUG, "AKMSuiteType %s --> %s",
1840 val, key_mgmt);
1841 return set_network(ifname, id, "key_mgmt", key_mgmt);
1842}
1843
1844
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001845static int set_wpa_common(struct sigma_dut *dut, struct sigma_conn *conn,
1846 const char *ifname, struct sigma_cmd *cmd)
1847{
1848 const char *val;
1849 int id;
Jouni Malinenad395a22017-09-01 21:13:46 +03001850 int cipher_set = 0;
Jouni Malinen47dcc952017-10-09 16:43:24 +03001851 int owe;
Sunil Duttc75a1e62018-01-11 20:47:50 +05301852 int suite_b = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001853
1854 id = add_network_common(dut, conn, ifname, cmd);
1855 if (id < 0)
1856 return id;
1857
Jouni Malinen47dcc952017-10-09 16:43:24 +03001858 val = get_param(cmd, "Type");
1859 owe = val && strcasecmp(val, "OWE") == 0;
1860
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001861 val = get_param(cmd, "keyMgmtType");
Jouni Malinen47dcc952017-10-09 16:43:24 +03001862 if (!val && owe)
1863 val = "OWE";
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001864 if (val == NULL) {
Jouni Malinene4fde732019-03-25 22:29:37 +02001865 /* keyMgmtType is being replaced with AKMSuiteType, so ignore
1866 * this missing parameter and assume proto=WPA2. */
1867 if (set_network(ifname, id, "proto", "WPA2") < 0)
1868 return ERROR_SEND_STATUS;
1869 } else if (strcasecmp(val, "wpa") == 0 ||
1870 strcasecmp(val, "wpa-psk") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001871 if (set_network(ifname, id, "proto", "WPA") < 0)
1872 return -2;
1873 } else if (strcasecmp(val, "wpa2") == 0 ||
1874 strcasecmp(val, "wpa2-psk") == 0 ||
1875 strcasecmp(val, "wpa2-ft") == 0 ||
1876 strcasecmp(val, "wpa2-sha256") == 0) {
1877 if (set_network(ifname, id, "proto", "WPA2") < 0)
1878 return -2;
Pradeep Reddy POTTETI6d04b3b2016-11-15 14:51:26 +05301879 } else if (strcasecmp(val, "wpa2-wpa-psk") == 0 ||
1880 strcasecmp(val, "wpa2-wpa-ent") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001881 if (set_network(ifname, id, "proto", "WPA WPA2") < 0)
1882 return -2;
Jouni Malinenad395a22017-09-01 21:13:46 +03001883 } else if (strcasecmp(val, "SuiteB") == 0) {
Sunil Duttc75a1e62018-01-11 20:47:50 +05301884 suite_b = 1;
Jouni Malinenad395a22017-09-01 21:13:46 +03001885 if (set_network(ifname, id, "proto", "WPA2") < 0)
1886 return -2;
Jouni Malinen47dcc952017-10-09 16:43:24 +03001887 } else if (strcasecmp(val, "OWE") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001888 } else {
1889 send_resp(dut, conn, SIGMA_INVALID, "errorCode,Unrecognized keyMgmtType value");
1890 return 0;
1891 }
1892
1893 val = get_param(cmd, "encpType");
Jouni Malinenad395a22017-09-01 21:13:46 +03001894 if (val) {
1895 cipher_set = 1;
1896 if (strcasecmp(val, "tkip") == 0) {
1897 if (set_network(ifname, id, "pairwise", "TKIP") < 0)
1898 return -2;
1899 } else if (strcasecmp(val, "aes-ccmp") == 0) {
1900 if (set_network(ifname, id, "pairwise", "CCMP") < 0)
1901 return -2;
1902 } else if (strcasecmp(val, "aes-ccmp-tkip") == 0) {
1903 if (set_network(ifname, id, "pairwise",
1904 "CCMP TKIP") < 0)
1905 return -2;
1906 } else if (strcasecmp(val, "aes-gcmp") == 0) {
1907 if (set_network(ifname, id, "pairwise", "GCMP") < 0)
1908 return -2;
1909 if (set_network(ifname, id, "group", "GCMP") < 0)
1910 return -2;
1911 } else {
1912 send_resp(dut, conn, SIGMA_ERROR,
1913 "errorCode,Unrecognized encpType value");
1914 return 0;
1915 }
1916 }
1917
1918 val = get_param(cmd, "PairwiseCipher");
1919 if (val) {
1920 cipher_set = 1;
1921 /* TODO: Support space separated list */
1922 if (strcasecmp(val, "AES-GCMP-256") == 0) {
1923 if (set_network(ifname, id, "pairwise", "GCMP-256") < 0)
1924 return -2;
1925 } else if (strcasecmp(val, "AES-CCMP-256") == 0) {
1926 if (set_network(ifname, id, "pairwise",
1927 "CCMP-256") < 0)
1928 return -2;
1929 } else if (strcasecmp(val, "AES-GCMP-128") == 0) {
1930 if (set_network(ifname, id, "pairwise", "GCMP") < 0)
1931 return -2;
1932 } else if (strcasecmp(val, "AES-CCMP-128") == 0) {
1933 if (set_network(ifname, id, "pairwise", "CCMP") < 0)
1934 return -2;
1935 } else {
1936 send_resp(dut, conn, SIGMA_ERROR,
1937 "errorCode,Unrecognized PairwiseCipher value");
1938 return 0;
1939 }
1940 }
1941
Jouni Malinen47dcc952017-10-09 16:43:24 +03001942 if (!cipher_set && !owe) {
Jouni Malinenad395a22017-09-01 21:13:46 +03001943 send_resp(dut, conn, SIGMA_ERROR,
1944 "errorCode,Missing encpType and PairwiseCipher");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001945 return 0;
1946 }
Jouni Malinenad395a22017-09-01 21:13:46 +03001947
1948 val = get_param(cmd, "GroupCipher");
1949 if (val) {
1950 if (strcasecmp(val, "AES-GCMP-256") == 0) {
1951 if (set_network(ifname, id, "group", "GCMP-256") < 0)
1952 return -2;
1953 } else if (strcasecmp(val, "AES-CCMP-256") == 0) {
1954 if (set_network(ifname, id, "group", "CCMP-256") < 0)
1955 return -2;
1956 } else if (strcasecmp(val, "AES-GCMP-128") == 0) {
1957 if (set_network(ifname, id, "group", "GCMP") < 0)
1958 return -2;
1959 } else if (strcasecmp(val, "AES-CCMP-128") == 0) {
1960 if (set_network(ifname, id, "group", "CCMP") < 0)
1961 return -2;
1962 } else {
1963 send_resp(dut, conn, SIGMA_ERROR,
1964 "errorCode,Unrecognized GroupCipher value");
1965 return 0;
1966 }
1967 }
1968
Jouni Malinen7b239522017-09-14 21:37:18 +03001969 val = get_param(cmd, "GroupMgntCipher");
Jouni Malinenad395a22017-09-01 21:13:46 +03001970 if (val) {
Jouni Malinene8898cb2017-09-26 17:55:26 +03001971 const char *cipher;
1972
1973 if (strcasecmp(val, "BIP-GMAC-256") == 0) {
1974 cipher = "BIP-GMAC-256";
1975 } else if (strcasecmp(val, "BIP-CMAC-256") == 0) {
1976 cipher = "BIP-CMAC-256";
1977 } else if (strcasecmp(val, "BIP-GMAC-128") == 0) {
1978 cipher = "BIP-GMAC-128";
1979 } else if (strcasecmp(val, "BIP-CMAC-128") == 0) {
1980 cipher = "AES-128-CMAC";
1981 } else {
1982 send_resp(dut, conn, SIGMA_INVALID,
1983 "errorCode,Unsupported GroupMgntCipher");
1984 return 0;
1985 }
1986 if (set_network(ifname, id, "group_mgmt", cipher) < 0) {
1987 send_resp(dut, conn, SIGMA_INVALID,
1988 "errorCode,Failed to set GroupMgntCipher");
1989 return 0;
1990 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001991 }
1992
Jouni Malinene4fde732019-03-25 22:29:37 +02001993 val = get_param(cmd, "AKMSuiteType");
1994 if (val && set_akm_suites(dut, ifname, id, val) < 0)
1995 return ERROR_SEND_STATUS;
1996
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001997 dut->sta_pmf = STA_PMF_DISABLED;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05301998
1999 if (dut->program == PROGRAM_OCE) {
2000 dut->sta_pmf = STA_PMF_OPTIONAL;
2001 if (set_network(ifname, id, "ieee80211w", "1") < 0)
2002 return -2;
2003 }
2004
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002005 val = get_param(cmd, "PMF");
2006 if (val) {
2007 if (strcasecmp(val, "Required") == 0 ||
2008 strcasecmp(val, "Forced_Required") == 0) {
2009 dut->sta_pmf = STA_PMF_REQUIRED;
2010 if (set_network(ifname, id, "ieee80211w", "2") < 0)
2011 return -2;
2012 } else if (strcasecmp(val, "Optional") == 0) {
2013 dut->sta_pmf = STA_PMF_OPTIONAL;
2014 if (set_network(ifname, id, "ieee80211w", "1") < 0)
2015 return -2;
2016 } else if (strcasecmp(val, "Disabled") == 0 ||
Kiran Kumar Lokere07da3b22018-12-16 22:42:49 -08002017 strcasecmp(val, "Disable") == 0 ||
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002018 strcasecmp(val, "Forced_Disabled") == 0) {
2019 dut->sta_pmf = STA_PMF_DISABLED;
2020 } else {
2021 send_resp(dut, conn, SIGMA_INVALID, "errorCode,Unrecognized PMF value");
2022 return 0;
2023 }
Sunil Duttc75a1e62018-01-11 20:47:50 +05302024 } else if (owe || suite_b) {
Jouni Malinen1287cd72018-01-04 17:08:01 +02002025 dut->sta_pmf = STA_PMF_REQUIRED;
2026 if (set_network(ifname, id, "ieee80211w", "2") < 0)
2027 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002028 }
2029
2030 return id;
2031}
2032
2033
2034static int cmd_sta_set_psk(struct sigma_dut *dut, struct sigma_conn *conn,
2035 struct sigma_cmd *cmd)
2036{
2037 const char *intf = get_param(cmd, "Interface");
Jouni Malinen992a81e2017-08-22 13:57:47 +03002038 const char *type = get_param(cmd, "Type");
Jouni Malinen1287cd72018-01-04 17:08:01 +02002039 const char *pmf = get_param(cmd, "PMF");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002040 const char *network_mode = get_param(cmd, "network_mode");
Jouni Malinene4fde732019-03-25 22:29:37 +02002041 const char *akm = get_param(cmd, "AKMSuiteType");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002042 const char *ifname, *val, *alg;
2043 int id;
2044
2045 if (intf == NULL)
2046 return -1;
2047
2048 if (strcmp(intf, get_main_ifname()) == 0)
2049 ifname = get_station_ifname();
2050 else
2051 ifname = intf;
2052
2053 id = set_wpa_common(dut, conn, ifname, cmd);
2054 if (id < 0)
2055 return id;
2056
2057 val = get_param(cmd, "keyMgmtType");
2058 alg = get_param(cmd, "micAlg");
2059
Jouni Malinen992a81e2017-08-22 13:57:47 +03002060 if (type && strcasecmp(type, "SAE") == 0) {
Jouni Malinene4fde732019-03-25 22:29:37 +02002061 if (!akm && val && strcasecmp(val, "wpa2-ft") == 0) {
Jouni Malinen992a81e2017-08-22 13:57:47 +03002062 if (set_network(ifname, id, "key_mgmt", "FT-SAE") < 0)
2063 return -2;
Jouni Malinene4fde732019-03-25 22:29:37 +02002064 } else if (!akm) {
Jouni Malinen992a81e2017-08-22 13:57:47 +03002065 if (set_network(ifname, id, "key_mgmt", "SAE") < 0)
2066 return -2;
2067 }
2068 if (wpa_command(ifname, "SET sae_groups ") != 0) {
2069 sigma_dut_print(dut, DUT_MSG_ERROR,
2070 "Failed to clear sae_groups to default");
2071 return -2;
2072 }
Jouni Malinen1287cd72018-01-04 17:08:01 +02002073 if (!pmf) {
2074 dut->sta_pmf = STA_PMF_REQUIRED;
2075 if (set_network(ifname, id, "ieee80211w", "2") < 0)
2076 return -2;
2077 }
Jouni Malinen0ab50f42017-08-31 01:34:59 +03002078 } else if (type && strcasecmp(type, "PSK-SAE") == 0) {
2079 if (val && strcasecmp(val, "wpa2-ft") == 0) {
2080 if (set_network(ifname, id, "key_mgmt",
2081 "FT-SAE FT-PSK") < 0)
2082 return -2;
2083 } else {
2084 if (set_network(ifname, id, "key_mgmt",
2085 "SAE WPA-PSK") < 0)
2086 return -2;
2087 }
2088 if (wpa_command(ifname, "SET sae_groups ") != 0) {
2089 sigma_dut_print(dut, DUT_MSG_ERROR,
2090 "Failed to clear sae_groups to default");
2091 return -2;
2092 }
Jouni Malinen1287cd72018-01-04 17:08:01 +02002093 if (!pmf) {
2094 dut->sta_pmf = STA_PMF_OPTIONAL;
2095 if (set_network(ifname, id, "ieee80211w", "1") < 0)
2096 return -2;
2097 }
Jouni Malinen992a81e2017-08-22 13:57:47 +03002098 } else if (alg && strcasecmp(alg, "SHA-256") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002099 if (set_network(ifname, id, "key_mgmt", "WPA-PSK-SHA256") < 0)
2100 return -2;
2101 } else if (alg && strcasecmp(alg, "SHA-1") == 0) {
2102 if (set_network(ifname, id, "key_mgmt", "WPA-PSK") < 0)
2103 return -2;
Ashwini Patil6dbf7b02017-03-20 13:42:11 +05302104 } else if (val && strcasecmp(val, "wpa2-ft") == 0) {
2105 if (set_network(ifname, id, "key_mgmt", "FT-PSK") < 0)
2106 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002107 } else if ((val && strcasecmp(val, "wpa2-sha256") == 0) ||
2108 dut->sta_pmf == STA_PMF_REQUIRED) {
2109 if (set_network(ifname, id, "key_mgmt",
2110 "WPA-PSK WPA-PSK-SHA256") < 0)
2111 return -2;
Jouni Malinen77ff3f02019-03-28 03:45:40 +02002112 } else if (!akm && dut->sta_pmf == STA_PMF_OPTIONAL) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002113 if (set_network(ifname, id, "key_mgmt",
2114 "WPA-PSK WPA-PSK-SHA256") < 0)
2115 return -2;
Jouni Malinen77ff3f02019-03-28 03:45:40 +02002116 } else if (!akm) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002117 if (set_network(ifname, id, "key_mgmt", "WPA-PSK") < 0)
2118 return -2;
2119 }
2120
2121 val = get_param(cmd, "passPhrase");
2122 if (val == NULL)
2123 return -1;
Jouni Malinen2126f422017-10-11 23:24:33 +03002124 if (type && strcasecmp(type, "SAE") == 0) {
2125 if (set_network_quoted(ifname, id, "sae_password", val) < 0)
2126 return -2;
2127 } else {
2128 if (set_network_quoted(ifname, id, "psk", val) < 0)
2129 return -2;
2130 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002131
Jouni Malinen78d10c42019-03-25 22:34:32 +02002132 val = get_param(cmd, "PasswordId");
2133 if (val && set_network_quoted(ifname, id, "sae_password_id", val) < 0)
2134 return ERROR_SEND_STATUS;
2135
Jouni Malinen992a81e2017-08-22 13:57:47 +03002136 val = get_param(cmd, "ECGroupID");
2137 if (val) {
2138 char buf[50];
2139
2140 snprintf(buf, sizeof(buf), "SET sae_groups %u", atoi(val));
2141 if (wpa_command(ifname, buf) != 0) {
2142 sigma_dut_print(dut, DUT_MSG_ERROR,
2143 "Failed to clear sae_groups");
2144 return -2;
2145 }
2146 }
2147
Jouni Malinen68143132017-09-02 02:34:08 +03002148 val = get_param(cmd, "InvalidSAEElement");
2149 if (val) {
2150 free(dut->sae_commit_override);
2151 dut->sae_commit_override = strdup(val);
2152 }
2153
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002154 if (dut->program == PROGRAM_60GHZ && network_mode &&
2155 strcasecmp(network_mode, "PBSS") == 0 &&
2156 set_network(ifname, id, "pbss", "1") < 0)
2157 return -2;
2158
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002159 return 1;
2160}
2161
2162
2163static int set_eap_common(struct sigma_dut *dut, struct sigma_conn *conn,
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302164 const char *ifname, int username_identity,
2165 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002166{
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302167 const char *val, *alg, *akm;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002168 int id;
2169 char buf[200];
2170#ifdef ANDROID
2171 unsigned char kvalue[KEYSTORE_MESSAGE_SIZE];
2172 int length;
2173#endif /* ANDROID */
Jouni Malinen8179fee2019-03-28 03:19:47 +02002174 int erp = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002175
2176 id = set_wpa_common(dut, conn, ifname, cmd);
2177 if (id < 0)
2178 return id;
2179
2180 val = get_param(cmd, "keyMgmtType");
2181 alg = get_param(cmd, "micAlg");
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302182 akm = get_param(cmd, "AKMSuiteType");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002183
Jouni Malinenad395a22017-09-01 21:13:46 +03002184 if (val && strcasecmp(val, "SuiteB") == 0) {
2185 if (set_network(ifname, id, "key_mgmt", "WPA-EAP-SUITE-B-192") <
2186 0)
2187 return -2;
2188 } else if (alg && strcasecmp(alg, "SHA-256") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002189 if (set_network(ifname, id, "key_mgmt", "WPA-EAP-SHA256") < 0)
2190 return -2;
2191 } else if (alg && strcasecmp(alg, "SHA-1") == 0) {
2192 if (set_network(ifname, id, "key_mgmt", "WPA-EAP") < 0)
2193 return -2;
2194 } else if (val && strcasecmp(val, "wpa2-ft") == 0) {
2195 if (set_network(ifname, id, "key_mgmt", "FT-EAP") < 0)
2196 return -2;
Jouni Malinend6a9d692019-03-28 03:01:24 +02002197 } else if (!akm &&
2198 ((val && strcasecmp(val, "wpa2-sha256") == 0) ||
2199 dut->sta_pmf == STA_PMF_REQUIRED)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002200 if (set_network(ifname, id, "key_mgmt",
2201 "WPA-EAP WPA-EAP-SHA256") < 0)
2202 return -2;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302203 } else if (akm && atoi(akm) == 14) {
2204 if (dut->sta_pmf == STA_PMF_OPTIONAL ||
2205 dut->sta_pmf == STA_PMF_REQUIRED) {
2206 if (set_network(ifname, id, "key_mgmt",
2207 "WPA-EAP-SHA256 FILS-SHA256") < 0)
2208 return -2;
2209 } else {
2210 if (set_network(ifname, id, "key_mgmt",
2211 "WPA-EAP FILS-SHA256") < 0)
2212 return -2;
2213 }
2214
Jouni Malinen8179fee2019-03-28 03:19:47 +02002215 erp = 1;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302216 } else if (akm && atoi(akm) == 15) {
2217 if (dut->sta_pmf == STA_PMF_OPTIONAL ||
2218 dut->sta_pmf == STA_PMF_REQUIRED) {
2219 if (set_network(ifname, id, "key_mgmt",
2220 "WPA-EAP-SHA256 FILS-SHA384") < 0)
2221 return -2;
2222 } else {
2223 if (set_network(ifname, id, "key_mgmt",
2224 "WPA-EAP FILS-SHA384") < 0)
2225 return -2;
2226 }
2227
Jouni Malinen8179fee2019-03-28 03:19:47 +02002228 erp = 1;
Jouni Malinend6a9d692019-03-28 03:01:24 +02002229 } else if (!akm && dut->sta_pmf == STA_PMF_OPTIONAL) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002230 if (set_network(ifname, id, "key_mgmt",
2231 "WPA-EAP WPA-EAP-SHA256") < 0)
2232 return -2;
Jouni Malinend6a9d692019-03-28 03:01:24 +02002233 } else if (!akm) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002234 if (set_network(ifname, id, "key_mgmt", "WPA-EAP") < 0)
2235 return -2;
2236 }
2237
2238 val = get_param(cmd, "trustedRootCA");
2239 if (val) {
2240#ifdef ANDROID
2241 snprintf(buf, sizeof(buf), "CACERT_%s", val);
2242 length = android_keystore_get(ANDROID_KEYSTORE_GET, buf,
2243 kvalue);
2244 if (length > 0) {
2245 sigma_dut_print(dut, DUT_MSG_INFO,
2246 "Use Android keystore [%s]", buf);
2247 snprintf(buf, sizeof(buf), "keystore://CACERT_%s",
2248 val);
2249 goto ca_cert_selected;
2250 }
2251#endif /* ANDROID */
2252
2253 snprintf(buf, sizeof(buf), "%s/%s", sigma_cert_path, val);
2254#ifdef __linux__
2255 if (!file_exists(buf)) {
2256 char msg[300];
2257 snprintf(msg, sizeof(msg), "ErrorCode,trustedRootCA "
2258 "file (%s) not found", buf);
2259 send_resp(dut, conn, SIGMA_ERROR, msg);
2260 return -3;
2261 }
2262#endif /* __linux__ */
2263#ifdef ANDROID
2264ca_cert_selected:
2265#endif /* ANDROID */
2266 if (set_network_quoted(ifname, id, "ca_cert", buf) < 0)
2267 return -2;
2268 }
2269
Jouni Malinen96f84b02019-05-03 12:32:56 +03002270 val = get_param(cmd, "Domain");
2271 if (val && set_network_quoted(ifname, id, "domain_match", val) < 0)
2272 return ERROR_SEND_STATUS;
2273
2274 val = get_param(cmd, "DomainSuffix");
2275 if (val &&
2276 set_network_quoted(ifname, id, "domain_suffix_match", val) < 0)
2277 return ERROR_SEND_STATUS;
2278
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302279 if (username_identity) {
2280 val = get_param(cmd, "username");
2281 if (val) {
2282 if (set_network_quoted(ifname, id, "identity", val) < 0)
2283 return -2;
2284 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002285
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302286 val = get_param(cmd, "password");
2287 if (val) {
2288 if (set_network_quoted(ifname, id, "password", val) < 0)
2289 return -2;
2290 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002291 }
2292
Jouni Malinen8179fee2019-03-28 03:19:47 +02002293 if (dut->akm_values &
2294 ((1 << AKM_FILS_SHA256) |
2295 (1 << AKM_FILS_SHA384) |
2296 (1 << AKM_FT_FILS_SHA256) |
2297 (1 << AKM_FT_FILS_SHA384)))
2298 erp = 1;
2299 if (erp && set_network(ifname, id, "erp", "1") < 0)
2300 return ERROR_SEND_STATUS;
2301
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002302 return id;
2303}
2304
2305
Jouni Malinen5eabb2a2017-10-03 18:17:30 +03002306static int set_tls_cipher(const char *ifname, int id, const char *cipher)
2307{
2308 const char *val;
2309
2310 if (!cipher)
2311 return 0;
2312
2313 if (strcasecmp(cipher, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384") == 0)
2314 val = "ECDHE-ECDSA-AES256-GCM-SHA384";
2315 else if (strcasecmp(cipher,
2316 "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384") == 0)
2317 val = "ECDHE-RSA-AES256-GCM-SHA384";
2318 else if (strcasecmp(cipher, "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384") == 0)
2319 val = "DHE-RSA-AES256-GCM-SHA384";
2320 else if (strcasecmp(cipher,
2321 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256") == 0)
2322 val = "ECDHE-ECDSA-AES128-GCM-SHA256";
2323 else
2324 return -1;
2325
2326 /* Need to clear phase1="tls_suiteb=1" to allow cipher enforcement */
2327 set_network_quoted(ifname, id, "phase1", "");
2328
2329 return set_network_quoted(ifname, id, "openssl_ciphers", val);
2330}
2331
2332
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002333static int cmd_sta_set_eaptls(struct sigma_dut *dut, struct sigma_conn *conn,
2334 struct sigma_cmd *cmd)
2335{
2336 const char *intf = get_param(cmd, "Interface");
2337 const char *ifname, *val;
2338 int id;
2339 char buf[200];
2340#ifdef ANDROID
2341 unsigned char kvalue[KEYSTORE_MESSAGE_SIZE];
2342 int length;
2343 int jb_or_newer = 0;
2344 char prop[PROPERTY_VALUE_MAX];
2345#endif /* ANDROID */
2346
2347 if (intf == NULL)
2348 return -1;
2349
2350 if (strcmp(intf, get_main_ifname()) == 0)
2351 ifname = get_station_ifname();
2352 else
2353 ifname = intf;
2354
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302355 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002356 if (id < 0)
2357 return id;
2358
2359 if (set_network(ifname, id, "eap", "TLS") < 0)
2360 return -2;
2361
Pradeep Reddy POTTETI9f6c2132016-05-05 16:28:19 +05302362 if (!get_param(cmd, "username") &&
2363 set_network_quoted(ifname, id, "identity",
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002364 "wifi-user@wifilabs.local") < 0)
2365 return -2;
2366
2367 val = get_param(cmd, "clientCertificate");
2368 if (val == NULL)
2369 return -1;
2370#ifdef ANDROID
2371 snprintf(buf, sizeof(buf), "USRPKEY_%s", val);
2372 length = android_keystore_get(ANDROID_KEYSTORE_GET, buf, kvalue);
2373 if (length < 0) {
2374 /*
2375 * JB started reporting keystore type mismatches, so retry with
2376 * the GET_PUBKEY command if the generic GET fails.
2377 */
2378 length = android_keystore_get(ANDROID_KEYSTORE_GET_PUBKEY,
2379 buf, kvalue);
2380 }
2381
2382 if (property_get("ro.build.version.release", prop, NULL) != 0) {
2383 sigma_dut_print(dut, DUT_MSG_DEBUG, "Android release %s", prop);
2384 if (strncmp(prop, "4.0", 3) != 0)
2385 jb_or_newer = 1;
2386 } else
2387 jb_or_newer = 1; /* assume newer */
2388
2389 if (jb_or_newer && length > 0) {
2390 sigma_dut_print(dut, DUT_MSG_INFO,
2391 "Use Android keystore [%s]", buf);
2392 if (set_network(ifname, id, "engine", "1") < 0)
2393 return -2;
2394 if (set_network_quoted(ifname, id, "engine_id", "keystore") < 0)
2395 return -2;
2396 snprintf(buf, sizeof(buf), "USRPKEY_%s", val);
2397 if (set_network_quoted(ifname, id, "key_id", buf) < 0)
2398 return -2;
2399 snprintf(buf, sizeof(buf), "keystore://USRCERT_%s", val);
2400 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
2401 return -2;
2402 return 1;
2403 } else if (length > 0) {
2404 sigma_dut_print(dut, DUT_MSG_INFO,
2405 "Use Android keystore [%s]", buf);
2406 snprintf(buf, sizeof(buf), "keystore://USRPKEY_%s", val);
2407 if (set_network_quoted(ifname, id, "private_key", buf) < 0)
2408 return -2;
2409 snprintf(buf, sizeof(buf), "keystore://USRCERT_%s", val);
2410 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
2411 return -2;
2412 return 1;
2413 }
2414#endif /* ANDROID */
2415
2416 snprintf(buf, sizeof(buf), "%s/%s", sigma_cert_path, val);
2417#ifdef __linux__
2418 if (!file_exists(buf)) {
2419 char msg[300];
2420 snprintf(msg, sizeof(msg), "ErrorCode,clientCertificate file "
2421 "(%s) not found", buf);
2422 send_resp(dut, conn, SIGMA_ERROR, msg);
2423 return -3;
2424 }
2425#endif /* __linux__ */
2426 if (set_network_quoted(ifname, id, "private_key", buf) < 0)
2427 return -2;
2428 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
2429 return -2;
2430
2431 if (set_network_quoted(ifname, id, "private_key_passwd", "wifi") < 0)
2432 return -2;
2433
Jouni Malinen5eabb2a2017-10-03 18:17:30 +03002434 val = get_param(cmd, "keyMgmtType");
2435 if (val && strcasecmp(val, "SuiteB") == 0) {
2436 val = get_param(cmd, "CertType");
2437 if (val && strcasecmp(val, "RSA") == 0) {
2438 if (set_network_quoted(ifname, id, "phase1",
2439 "tls_suiteb=1") < 0)
2440 return -2;
2441 } else {
2442 if (set_network_quoted(ifname, id, "openssl_ciphers",
2443 "SUITEB192") < 0)
2444 return -2;
2445 }
2446
2447 val = get_param(cmd, "TLSCipher");
2448 if (set_tls_cipher(ifname, id, val) < 0) {
2449 send_resp(dut, conn, SIGMA_ERROR,
2450 "ErrorCode,Unsupported TLSCipher value");
2451 return -3;
2452 }
2453 }
2454
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002455 return 1;
2456}
2457
2458
2459static int cmd_sta_set_eapttls(struct sigma_dut *dut, struct sigma_conn *conn,
2460 struct sigma_cmd *cmd)
2461{
2462 const char *intf = get_param(cmd, "Interface");
2463 const char *ifname;
2464 int id;
2465
2466 if (intf == NULL)
2467 return -1;
2468
2469 if (strcmp(intf, get_main_ifname()) == 0)
2470 ifname = get_station_ifname();
2471 else
2472 ifname = intf;
2473
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302474 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002475 if (id < 0)
2476 return id;
2477
2478 if (set_network(ifname, id, "eap", "TTLS") < 0) {
2479 send_resp(dut, conn, SIGMA_ERROR,
2480 "errorCode,Failed to set TTLS method");
2481 return 0;
2482 }
2483
2484 if (set_network_quoted(ifname, id, "phase2", "auth=MSCHAPV2") < 0) {
2485 send_resp(dut, conn, SIGMA_ERROR,
2486 "errorCode,Failed to set MSCHAPv2 for TTLS Phase 2");
2487 return 0;
2488 }
2489
2490 return 1;
2491}
2492
2493
2494static int cmd_sta_set_eapsim(struct sigma_dut *dut, struct sigma_conn *conn,
2495 struct sigma_cmd *cmd)
2496{
2497 const char *intf = get_param(cmd, "Interface");
2498 const char *ifname;
2499 int id;
2500
2501 if (intf == NULL)
2502 return -1;
2503
2504 if (strcmp(intf, get_main_ifname()) == 0)
2505 ifname = get_station_ifname();
2506 else
2507 ifname = intf;
2508
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302509 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002510 if (id < 0)
2511 return id;
2512
2513 if (set_network(ifname, id, "eap", "SIM") < 0)
2514 return -2;
2515
2516 return 1;
2517}
2518
2519
2520static int cmd_sta_set_peap(struct sigma_dut *dut, struct sigma_conn *conn,
2521 struct sigma_cmd *cmd)
2522{
2523 const char *intf = get_param(cmd, "Interface");
2524 const char *ifname, *val;
2525 int id;
2526 char buf[100];
2527
2528 if (intf == NULL)
2529 return -1;
2530
2531 if (strcmp(intf, get_main_ifname()) == 0)
2532 ifname = get_station_ifname();
2533 else
2534 ifname = intf;
2535
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302536 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002537 if (id < 0)
2538 return id;
2539
2540 if (set_network(ifname, id, "eap", "PEAP") < 0)
2541 return -2;
2542
2543 val = get_param(cmd, "innerEAP");
2544 if (val) {
2545 if (strcasecmp(val, "MSCHAPv2") == 0) {
2546 if (set_network_quoted(ifname, id, "phase2",
2547 "auth=MSCHAPV2") < 0)
2548 return -2;
2549 } else if (strcasecmp(val, "GTC") == 0) {
2550 if (set_network_quoted(ifname, id, "phase2",
2551 "auth=GTC") < 0)
2552 return -2;
2553 } else
2554 return -1;
2555 }
2556
2557 val = get_param(cmd, "peapVersion");
2558 if (val) {
2559 int ver = atoi(val);
2560 if (ver < 0 || ver > 1)
2561 return -1;
2562 snprintf(buf, sizeof(buf), "peapver=%d", ver);
2563 if (set_network_quoted(ifname, id, "phase1", buf) < 0)
2564 return -2;
2565 }
2566
2567 return 1;
2568}
2569
2570
2571static int cmd_sta_set_eapfast(struct sigma_dut *dut, struct sigma_conn *conn,
2572 struct sigma_cmd *cmd)
2573{
2574 const char *intf = get_param(cmd, "Interface");
2575 const char *ifname, *val;
2576 int id;
2577 char buf[100];
2578
2579 if (intf == NULL)
2580 return -1;
2581
2582 if (strcmp(intf, get_main_ifname()) == 0)
2583 ifname = get_station_ifname();
2584 else
2585 ifname = intf;
2586
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302587 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002588 if (id < 0)
2589 return id;
2590
2591 if (set_network(ifname, id, "eap", "FAST") < 0)
2592 return -2;
2593
2594 val = get_param(cmd, "innerEAP");
2595 if (val) {
2596 if (strcasecmp(val, "MSCHAPV2") == 0) {
2597 if (set_network_quoted(ifname, id, "phase2",
2598 "auth=MSCHAPV2") < 0)
2599 return -2;
2600 } else if (strcasecmp(val, "GTC") == 0) {
2601 if (set_network_quoted(ifname, id, "phase2",
2602 "auth=GTC") < 0)
2603 return -2;
2604 } else
2605 return -1;
2606 }
2607
2608 val = get_param(cmd, "validateServer");
2609 if (val) {
2610 /* TODO */
2611 sigma_dut_print(dut, DUT_MSG_INFO, "Ignored EAP-FAST "
2612 "validateServer=%s", val);
2613 }
2614
2615 val = get_param(cmd, "pacFile");
2616 if (val) {
2617 snprintf(buf, sizeof(buf), "blob://%s", val);
2618 if (set_network_quoted(ifname, id, "pac_file", buf) < 0)
2619 return -2;
2620 }
2621
2622 if (set_network_quoted(ifname, id, "phase1", "fast_provisioning=2") <
2623 0)
2624 return -2;
2625
2626 return 1;
2627}
2628
2629
2630static int cmd_sta_set_eapaka(struct sigma_dut *dut, struct sigma_conn *conn,
2631 struct sigma_cmd *cmd)
2632{
2633 const char *intf = get_param(cmd, "Interface");
2634 const char *ifname;
2635 int id;
2636
2637 if (intf == NULL)
2638 return -1;
2639
2640 if (strcmp(intf, get_main_ifname()) == 0)
2641 ifname = get_station_ifname();
2642 else
2643 ifname = intf;
2644
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302645 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002646 if (id < 0)
2647 return id;
2648
2649 if (set_network(ifname, id, "eap", "AKA") < 0)
2650 return -2;
2651
2652 return 1;
2653}
2654
2655
2656static int cmd_sta_set_eapakaprime(struct sigma_dut *dut,
2657 struct sigma_conn *conn,
2658 struct sigma_cmd *cmd)
2659{
2660 const char *intf = get_param(cmd, "Interface");
2661 const char *ifname;
2662 int id;
2663
2664 if (intf == NULL)
2665 return -1;
2666
2667 if (strcmp(intf, get_main_ifname()) == 0)
2668 ifname = get_station_ifname();
2669 else
2670 ifname = intf;
2671
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302672 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002673 if (id < 0)
2674 return id;
2675
2676 if (set_network(ifname, id, "eap", "AKA'") < 0)
2677 return -2;
2678
2679 return 1;
2680}
2681
2682
2683static int sta_set_open(struct sigma_dut *dut, struct sigma_conn *conn,
2684 struct sigma_cmd *cmd)
2685{
2686 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002687 const char *network_mode = get_param(cmd, "network_mode");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002688 const char *ifname;
2689 int id;
2690
2691 if (strcmp(intf, get_main_ifname()) == 0)
2692 ifname = get_station_ifname();
2693 else
2694 ifname = intf;
2695
2696 id = add_network_common(dut, conn, ifname, cmd);
2697 if (id < 0)
2698 return id;
2699
2700 if (set_network(ifname, id, "key_mgmt", "NONE") < 0)
2701 return -2;
2702
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002703 if (dut->program == PROGRAM_60GHZ && network_mode &&
2704 strcasecmp(network_mode, "PBSS") == 0 &&
2705 set_network(ifname, id, "pbss", "1") < 0)
2706 return -2;
2707
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002708 return 1;
2709}
2710
2711
Jouni Malinen47dcc952017-10-09 16:43:24 +03002712static int sta_set_owe(struct sigma_dut *dut, struct sigma_conn *conn,
2713 struct sigma_cmd *cmd)
2714{
2715 const char *intf = get_param(cmd, "Interface");
2716 const char *ifname, *val;
2717 int id;
2718
2719 if (intf == NULL)
2720 return -1;
2721
2722 if (strcmp(intf, get_main_ifname()) == 0)
2723 ifname = get_station_ifname();
2724 else
2725 ifname = intf;
2726
2727 id = set_wpa_common(dut, conn, ifname, cmd);
2728 if (id < 0)
2729 return id;
2730
2731 if (set_network(ifname, id, "key_mgmt", "OWE") < 0)
2732 return -2;
2733
2734 val = get_param(cmd, "ECGroupID");
Jouni Malinenfac9cad2017-10-10 18:35:55 +03002735 if (val && strcmp(val, "0") == 0) {
2736 if (wpa_command(ifname,
2737 "VENDOR_ELEM_ADD 13 ff23200000783590fb7440e03d5b3b33911f86affdcc6b4411b707846ac4ff08ddc8831ccd") != 0) {
2738 sigma_dut_print(dut, DUT_MSG_ERROR,
2739 "Failed to set OWE DH Param element override");
2740 return -2;
2741 }
2742 } else if (val && set_network(ifname, id, "owe_group", val) < 0) {
Jouni Malinen47dcc952017-10-09 16:43:24 +03002743 sigma_dut_print(dut, DUT_MSG_ERROR,
2744 "Failed to clear owe_group");
2745 return -2;
2746 }
2747
2748 return 1;
2749}
2750
2751
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002752static int cmd_sta_set_security(struct sigma_dut *dut, struct sigma_conn *conn,
2753 struct sigma_cmd *cmd)
2754{
2755 const char *type = get_param(cmd, "Type");
2756
2757 if (type == NULL) {
2758 send_resp(dut, conn, SIGMA_ERROR,
2759 "ErrorCode,Missing Type argument");
2760 return 0;
2761 }
2762
2763 if (strcasecmp(type, "OPEN") == 0)
2764 return sta_set_open(dut, conn, cmd);
Jouni Malinen47dcc952017-10-09 16:43:24 +03002765 if (strcasecmp(type, "OWE") == 0)
2766 return sta_set_owe(dut, conn, cmd);
Jouni Malinen992a81e2017-08-22 13:57:47 +03002767 if (strcasecmp(type, "PSK") == 0 ||
Jouni Malinen0ab50f42017-08-31 01:34:59 +03002768 strcasecmp(type, "PSK-SAE") == 0 ||
Jouni Malinen992a81e2017-08-22 13:57:47 +03002769 strcasecmp(type, "SAE") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002770 return cmd_sta_set_psk(dut, conn, cmd);
2771 if (strcasecmp(type, "EAPTLS") == 0)
2772 return cmd_sta_set_eaptls(dut, conn, cmd);
2773 if (strcasecmp(type, "EAPTTLS") == 0)
2774 return cmd_sta_set_eapttls(dut, conn, cmd);
2775 if (strcasecmp(type, "EAPPEAP") == 0)
2776 return cmd_sta_set_peap(dut, conn, cmd);
2777 if (strcasecmp(type, "EAPSIM") == 0)
2778 return cmd_sta_set_eapsim(dut, conn, cmd);
2779 if (strcasecmp(type, "EAPFAST") == 0)
2780 return cmd_sta_set_eapfast(dut, conn, cmd);
2781 if (strcasecmp(type, "EAPAKA") == 0)
2782 return cmd_sta_set_eapaka(dut, conn, cmd);
2783 if (strcasecmp(type, "EAPAKAPRIME") == 0)
2784 return cmd_sta_set_eapakaprime(dut, conn, cmd);
Amarnath Hullur Subramanyam81b11cd2018-01-30 19:07:17 -08002785 if (strcasecmp(type, "wep") == 0)
2786 return cmd_sta_set_encryption(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002787
2788 send_resp(dut, conn, SIGMA_ERROR,
2789 "ErrorCode,Unsupported Type value");
2790 return 0;
2791}
2792
2793
2794int ath6kl_client_uapsd(struct sigma_dut *dut, const char *intf, int uapsd)
2795{
2796#ifdef __linux__
2797 /* special handling for ath6kl */
2798 char path[128], fname[128], *pos;
2799 ssize_t res;
2800 FILE *f;
2801
2802 snprintf(path, sizeof(path), "/sys/class/net/%s/phy80211", intf);
2803 res = readlink(path, path, sizeof(path));
2804 if (res < 0)
2805 return 0; /* not ath6kl */
2806
2807 if (res >= (int) sizeof(path))
2808 res = sizeof(path) - 1;
2809 path[res] = '\0';
2810 pos = strrchr(path, '/');
2811 if (pos == NULL)
2812 pos = path;
2813 else
2814 pos++;
2815 snprintf(fname, sizeof(fname),
2816 "/sys/kernel/debug/ieee80211/%s/ath6kl/"
2817 "create_qos", pos);
2818 if (!file_exists(fname))
2819 return 0; /* not ath6kl */
2820
2821 if (uapsd) {
2822 f = fopen(fname, "w");
2823 if (f == NULL)
2824 return -1;
2825
2826 sigma_dut_print(dut, DUT_MSG_DEBUG, "Use ath6kl create_qos");
2827 fprintf(f, "4 2 2 1 2 9999999 9999999 9999999 7777777 0 4 "
2828 "45000 200 56789000 56789000 5678900 0 0 9999999 "
2829 "20000 0\n");
2830 fclose(f);
2831 } else {
2832 snprintf(fname, sizeof(fname),
2833 "/sys/kernel/debug/ieee80211/%s/ath6kl/"
2834 "delete_qos", pos);
2835
2836 f = fopen(fname, "w");
2837 if (f == NULL)
2838 return -1;
2839
2840 sigma_dut_print(dut, DUT_MSG_DEBUG, "Use ath6kl delete_qos");
2841 fprintf(f, "2 4\n");
2842 fclose(f);
2843 }
2844#endif /* __linux__ */
2845
2846 return 0;
2847}
2848
2849
2850static int cmd_sta_set_uapsd(struct sigma_dut *dut, struct sigma_conn *conn,
2851 struct sigma_cmd *cmd)
2852{
2853 const char *intf = get_param(cmd, "Interface");
2854 /* const char *ssid = get_param(cmd, "ssid"); */
2855 const char *val;
2856 int max_sp_len = 4;
2857 int ac_be = 1, ac_bk = 1, ac_vi = 1, ac_vo = 1;
2858 char buf[100];
2859 int ret1, ret2;
2860
2861 val = get_param(cmd, "maxSPLength");
2862 if (val) {
2863 max_sp_len = atoi(val);
2864 if (max_sp_len != 0 && max_sp_len != 1 && max_sp_len != 2 &&
2865 max_sp_len != 4)
2866 return -1;
2867 }
2868
2869 val = get_param(cmd, "acBE");
2870 if (val)
2871 ac_be = atoi(val);
2872
2873 val = get_param(cmd, "acBK");
2874 if (val)
2875 ac_bk = atoi(val);
2876
2877 val = get_param(cmd, "acVI");
2878 if (val)
2879 ac_vi = atoi(val);
2880
2881 val = get_param(cmd, "acVO");
2882 if (val)
2883 ac_vo = atoi(val);
2884
2885 dut->client_uapsd = ac_be || ac_bk || ac_vi || ac_vo;
2886
2887 snprintf(buf, sizeof(buf), "P2P_SET client_apsd %d,%d,%d,%d;%d",
2888 ac_be, ac_bk, ac_vi, ac_vo, max_sp_len);
2889 ret1 = wpa_command(intf, buf);
2890
2891 snprintf(buf, sizeof(buf), "SET uapsd %d,%d,%d,%d;%d",
2892 ac_be, ac_bk, ac_vi, ac_vo, max_sp_len);
2893 ret2 = wpa_command(intf, buf);
2894
2895 if (ret1 && ret2) {
2896 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to set client mode "
2897 "UAPSD parameters.");
2898 return -2;
2899 }
2900
2901 if (ath6kl_client_uapsd(dut, intf, dut->client_uapsd) < 0) {
2902 send_resp(dut, conn, SIGMA_ERROR,
2903 "ErrorCode,Failed to set ath6kl QoS parameters");
2904 return 0;
2905 }
2906
2907 return 1;
2908}
2909
2910
2911static int cmd_sta_set_wmm(struct sigma_dut *dut, struct sigma_conn *conn,
2912 struct sigma_cmd *cmd)
2913{
2914 char buf[1000];
2915 const char *intf = get_param(cmd, "Interface");
2916 const char *grp = get_param(cmd, "Group");
2917 const char *act = get_param(cmd, "Action");
2918 const char *tid = get_param(cmd, "Tid");
2919 const char *dir = get_param(cmd, "Direction");
2920 const char *psb = get_param(cmd, "Psb");
2921 const char *up = get_param(cmd, "Up");
2922 const char *fixed = get_param(cmd, "Fixed");
2923 const char *size = get_param(cmd, "Size");
2924 const char *msize = get_param(cmd, "Maxsize");
2925 const char *minsi = get_param(cmd, "Min_srvc_intrvl");
2926 const char *maxsi = get_param(cmd, "Max_srvc_intrvl");
2927 const char *inact = get_param(cmd, "Inactivity");
2928 const char *sus = get_param(cmd, "Suspension");
2929 const char *mindr = get_param(cmd, "Mindatarate");
2930 const char *meandr = get_param(cmd, "Meandatarate");
2931 const char *peakdr = get_param(cmd, "Peakdatarate");
2932 const char *phyrate = get_param(cmd, "Phyrate");
2933 const char *burstsize = get_param(cmd, "Burstsize");
2934 const char *sba = get_param(cmd, "Sba");
2935 int direction;
2936 int handle;
Peng Xu93319622017-10-04 17:58:16 -07002937 float sba_fv = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002938 int fixed_int;
2939 int psb_ts;
2940
2941 if (intf == NULL || grp == NULL || act == NULL )
2942 return -1;
2943
2944 if (strcasecmp(act, "addts") == 0) {
2945 if (tid == NULL || dir == NULL || psb == NULL ||
2946 up == NULL || fixed == NULL || size == NULL)
2947 return -1;
2948
2949 /*
2950 * Note: Sigma CAPI spec lists uplink, downlink, and bidi as the
2951 * possible values, but WMM-AC and V-E test scripts use "UP,
2952 * "DOWN", and "BIDI".
2953 */
2954 if (strcasecmp(dir, "uplink") == 0 ||
2955 strcasecmp(dir, "up") == 0) {
2956 direction = 0;
2957 } else if (strcasecmp(dir, "downlink") == 0 ||
2958 strcasecmp(dir, "down") == 0) {
2959 direction = 1;
2960 } else if (strcasecmp(dir, "bidi") == 0) {
2961 direction = 2;
2962 } else {
2963 sigma_dut_print(dut, DUT_MSG_ERROR,
2964 "Direction %s not supported", dir);
2965 return -1;
2966 }
2967
2968 if (strcasecmp(psb, "legacy") == 0) {
2969 psb_ts = 0;
2970 } else if (strcasecmp(psb, "uapsd") == 0) {
2971 psb_ts = 1;
2972 } else {
2973 sigma_dut_print(dut, DUT_MSG_ERROR,
2974 "PSB %s not supported", psb);
2975 return -1;
2976 }
2977
2978 if (atoi(tid) < 0 || atoi(tid) > 7) {
2979 sigma_dut_print(dut, DUT_MSG_ERROR,
2980 "TID %s not supported", tid);
2981 return -1;
2982 }
2983
2984 if (strcasecmp(fixed, "true") == 0) {
2985 fixed_int = 1;
2986 } else {
2987 fixed_int = 0;
2988 }
2989
Peng Xu93319622017-10-04 17:58:16 -07002990 if (sba)
2991 sba_fv = atof(sba);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002992
2993 dut->dialog_token++;
2994 handle = 7000 + dut->dialog_token;
2995
2996 /*
2997 * size: convert to hex
2998 * maxsi: convert to hex
2999 * mindr: convert to hex
3000 * meandr: convert to hex
3001 * peakdr: convert to hex
3002 * burstsize: convert to hex
3003 * phyrate: convert to hex
3004 * sba: convert to hex with modification
3005 * minsi: convert to integer
3006 * sus: convert to integer
3007 * inact: convert to integer
3008 * maxsi: convert to integer
3009 */
3010
3011 /*
3012 * The Nominal MSDU Size field is 2 octets long and contains an
3013 * unsigned integer that specifies the nominal size, in octets,
3014 * of MSDUs belonging to the traffic under this traffic
3015 * specification and is defined in Figure 16. If the Fixed
3016 * subfield is set to 1, then the size of the MSDU is fixed and
3017 * is indicated by the Size Subfield. If the Fixed subfield is
3018 * set to 0, then the size of the MSDU might not be fixed and
3019 * the Size indicates the nominal MSDU size.
3020 *
3021 * The Surplus Bandwidth Allowance Factor field is 2 octets long
3022 * and specifies the excess allocation of time (and bandwidth)
3023 * over and above the stated rates required to transport an MSDU
3024 * belonging to the traffic in this TSPEC. This field is
3025 * represented as an unsigned binary number with an implicit
3026 * binary point after the leftmost 3 bits. For example, an SBA
3027 * of 1.75 is represented as 0x3800. This field is included to
3028 * account for retransmissions. As such, the value of this field
3029 * must be greater than unity.
3030 */
3031
3032 snprintf(buf, sizeof(buf),
3033 "iwpriv %s addTspec %d %s %d %d %s 0x%X"
3034 " 0x%X 0x%X 0x%X"
3035 " 0x%X 0x%X 0x%X"
3036 " 0x%X %d %d %d %d"
3037 " %d %d",
3038 intf, handle, tid, direction, psb_ts, up,
3039 (unsigned int) ((fixed_int << 15) | atoi(size)),
3040 msize ? atoi(msize) : 0,
3041 mindr ? atoi(mindr) : 0,
3042 meandr ? atoi(meandr) : 0,
3043 peakdr ? atoi(peakdr) : 0,
3044 burstsize ? atoi(burstsize) : 0,
3045 phyrate ? atoi(phyrate) : 0,
3046 sba ? ((unsigned int) (((int) sba_fv << 13) |
3047 (int)((sba_fv - (int) sba_fv) *
3048 8192))) : 0,
3049 minsi ? atoi(minsi) : 0,
3050 sus ? atoi(sus) : 0,
3051 0, 0,
3052 inact ? atoi(inact) : 0,
3053 maxsi ? atoi(maxsi) : 0);
3054
3055 if (system(buf) != 0) {
3056 sigma_dut_print(dut, DUT_MSG_ERROR,
3057 "iwpriv addtspec request failed");
3058 send_resp(dut, conn, SIGMA_ERROR,
3059 "errorCode,Failed to execute addTspec command");
3060 return 0;
3061 }
3062
3063 sigma_dut_print(dut, DUT_MSG_INFO,
3064 "iwpriv addtspec request send");
3065
3066 /* Mapping handle to a TID */
3067 dut->tid_to_handle[atoi(tid)] = handle;
3068 } else if (strcasecmp(act, "delts") == 0) {
3069 if (tid == NULL)
3070 return -1;
3071
3072 if (atoi(tid) < 0 || atoi(tid) > 7) {
3073 sigma_dut_print(dut, DUT_MSG_ERROR,
3074 "TID %s not supported", tid);
3075 send_resp(dut, conn, SIGMA_ERROR,
3076 "errorCode,Unsupported TID");
3077 return 0;
3078 }
3079
3080 handle = dut->tid_to_handle[atoi(tid)];
3081
3082 if (handle < 7000 || handle > 7255) {
3083 /* Invalid handle ie no mapping for that TID */
3084 sigma_dut_print(dut, DUT_MSG_ERROR,
3085 "handle-> %d not found", handle);
3086 }
3087
3088 snprintf(buf, sizeof(buf), "iwpriv %s delTspec %d",
3089 intf, handle);
3090
3091 if (system(buf) != 0) {
3092 sigma_dut_print(dut, DUT_MSG_ERROR,
3093 "iwpriv deltspec request failed");
3094 send_resp(dut, conn, SIGMA_ERROR,
3095 "errorCode,Failed to execute delTspec command");
3096 return 0;
3097 }
3098
3099 sigma_dut_print(dut, DUT_MSG_INFO,
3100 "iwpriv deltspec request send");
3101
3102 dut->tid_to_handle[atoi(tid)] = 0;
3103 } else {
3104 sigma_dut_print(dut, DUT_MSG_ERROR,
3105 "Action type %s not supported", act);
3106 send_resp(dut, conn, SIGMA_ERROR,
3107 "errorCode,Unsupported Action");
3108 return 0;
3109 }
3110
3111 return 1;
3112}
3113
3114
vamsi krishna52e16f92017-08-29 12:37:34 +05303115static int find_network(struct sigma_dut *dut, const char *ssid)
3116{
3117 char list[4096];
3118 char *pos;
3119
3120 sigma_dut_print(dut, DUT_MSG_DEBUG,
3121 "Search for profile based on SSID: '%s'", ssid);
3122 if (wpa_command_resp(get_station_ifname(), "LIST_NETWORKS",
3123 list, sizeof(list)) < 0)
3124 return -1;
3125 pos = strstr(list, ssid);
3126 if (!pos || pos == list || pos[-1] != '\t' || pos[strlen(ssid)] != '\t')
3127 return -1;
3128
3129 while (pos > list && pos[-1] != '\n')
3130 pos--;
3131 dut->infra_network_id = atoi(pos);
3132 snprintf(dut->infra_ssid, sizeof(dut->infra_ssid), "%s", ssid);
3133 return 0;
3134}
3135
3136
Sunil Dutt44595082018-02-12 19:41:45 +05303137#ifdef NL80211_SUPPORT
3138static int sta_config_rsnie(struct sigma_dut *dut, int val)
3139{
3140 struct nl_msg *msg;
3141 int ret;
3142 struct nlattr *params;
3143 int ifindex;
3144
3145 ifindex = if_nametoindex("wlan0");
3146 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
3147 NL80211_CMD_VENDOR)) ||
3148 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
3149 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
3150 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
3151 QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION) ||
3152 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
3153 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE, val)) {
3154 sigma_dut_print(dut, DUT_MSG_ERROR,
3155 "%s: err in adding vendor_cmd and vendor_data",
3156 __func__);
3157 nlmsg_free(msg);
3158 return -1;
3159 }
3160 nla_nest_end(msg, params);
3161
3162 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
3163 if (ret) {
3164 sigma_dut_print(dut, DUT_MSG_ERROR,
3165 "%s: err in send_and_recv_msgs, ret=%d",
3166 __func__, ret);
3167 return ret;
3168 }
3169
3170 return 0;
3171}
3172#endif /* NL80211_SUPPORT */
3173
3174
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003175static int cmd_sta_associate(struct sigma_dut *dut, struct sigma_conn *conn,
3176 struct sigma_cmd *cmd)
3177{
3178 /* const char *intf = get_param(cmd, "Interface"); */
3179 const char *ssid = get_param(cmd, "ssid");
3180 const char *wps_param = get_param(cmd, "WPS");
3181 const char *bssid = get_param(cmd, "bssid");
Jouni Malinen46a19b62017-06-23 14:31:27 +03003182 const char *chan = get_param(cmd, "channel");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02003183 const char *network_mode = get_param(cmd, "network_mode");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003184 int wps = 0;
Jouni Malinen3c367e82017-06-23 17:01:47 +03003185 char buf[1000], extra[50];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003186
3187 if (ssid == NULL)
3188 return -1;
3189
Jouni Malinen3c367e82017-06-23 17:01:47 +03003190 if (dut->rsne_override) {
Sunil Dutt44595082018-02-12 19:41:45 +05303191#ifdef NL80211_SUPPORT
3192 if (get_driver_type() == DRIVER_WCN) {
3193 sta_config_rsnie(dut, 1);
3194 dut->config_rsnie = 1;
3195 }
3196#endif /* NL80211_SUPPORT */
Jouni Malinen3c367e82017-06-23 17:01:47 +03003197 snprintf(buf, sizeof(buf), "TEST_ASSOC_IE %s",
3198 dut->rsne_override);
3199 if (wpa_command(get_station_ifname(), buf) < 0) {
3200 send_resp(dut, conn, SIGMA_ERROR,
3201 "ErrorCode,Failed to set DEV_CONFIGURE_IE RSNE override");
3202 return 0;
3203 }
3204 }
3205
Jouni Malinen68143132017-09-02 02:34:08 +03003206 if (dut->sae_commit_override) {
3207 snprintf(buf, sizeof(buf), "SET sae_commit_override %s",
3208 dut->sae_commit_override);
3209 if (wpa_command(get_station_ifname(), buf) < 0) {
3210 send_resp(dut, conn, SIGMA_ERROR,
3211 "ErrorCode,Failed to set SAE commit override");
3212 return 0;
3213 }
3214 }
Ankita Bajaj1bde7942018-01-09 19:15:01 +05303215#ifdef ANDROID
3216 if (dut->fils_hlp)
3217 process_fils_hlp(dut);
3218#endif /* ANDROID */
Jouni Malinen68143132017-09-02 02:34:08 +03003219
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003220 if (wps_param &&
3221 (strcmp(wps_param, "1") == 0 || strcasecmp(wps_param, "On") == 0))
3222 wps = 1;
3223
3224 if (wps) {
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02003225 if (dut->program == PROGRAM_60GHZ && network_mode &&
3226 strcasecmp(network_mode, "PBSS") == 0 &&
3227 set_network(get_station_ifname(), dut->infra_network_id,
3228 "pbss", "1") < 0)
3229 return -2;
3230
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003231 if (dut->wps_method == WFA_CS_WPS_NOT_READY) {
3232 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,WPS "
3233 "parameters not yet set");
3234 return 0;
3235 }
3236 if (dut->wps_method == WFA_CS_WPS_PBC) {
3237 if (wpa_command(get_station_ifname(), "WPS_PBC") < 0)
3238 return -2;
3239 } else {
3240 snprintf(buf, sizeof(buf), "WPS_PIN any %s",
3241 dut->wps_pin);
3242 if (wpa_command(get_station_ifname(), buf) < 0)
3243 return -2;
3244 }
3245 } else {
vamsi krishna52e16f92017-08-29 12:37:34 +05303246 if (strcmp(ssid, dut->infra_ssid) == 0) {
3247 sigma_dut_print(dut, DUT_MSG_DEBUG,
3248 "sta_associate for the most recently added network");
3249 } else if (find_network(dut, ssid) < 0) {
3250 sigma_dut_print(dut, DUT_MSG_DEBUG,
3251 "sta_associate for a previously stored network profile");
3252 send_resp(dut, conn, SIGMA_ERROR,
3253 "ErrorCode,Profile not found");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003254 return 0;
3255 }
3256
3257 if (bssid &&
3258 set_network(get_station_ifname(), dut->infra_network_id,
3259 "bssid", bssid) < 0) {
3260 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
3261 "Invalid bssid argument");
3262 return 0;
3263 }
3264
Jouni Malinen46a19b62017-06-23 14:31:27 +03003265 extra[0] = '\0';
3266 if (chan)
3267 snprintf(extra, sizeof(extra), " freq=%u",
Alexei Avshalom Lazar093569f2018-11-13 14:08:17 +02003268 channel_to_freq(dut, atoi(chan)));
Jouni Malinen46a19b62017-06-23 14:31:27 +03003269 snprintf(buf, sizeof(buf), "SELECT_NETWORK %d%s",
3270 dut->infra_network_id, extra);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003271 if (wpa_command(get_station_ifname(), buf) < 0) {
3272 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to select "
3273 "network id %d on %s",
3274 dut->infra_network_id,
3275 get_station_ifname());
3276 return -2;
3277 }
3278 }
3279
3280 return 1;
3281}
3282
3283
3284static int run_hs20_osu(struct sigma_dut *dut, const char *params)
3285{
3286 char buf[500], cmd[200];
3287 int res;
3288
3289 /* Use hs20-osu-client file at the current dir, if found; otherwise use
3290 * default path */
3291 res = snprintf(cmd, sizeof(cmd),
3292 "%s -w \"%s\" -r hs20-osu-client.res %s%s -dddKt -f Logs/hs20-osu-client.txt",
3293 file_exists("./hs20-osu-client") ?
3294 "./hs20-osu-client" : "hs20-osu-client",
3295 sigma_wpas_ctrl,
3296 dut->summary_log ? "-s " : "",
3297 dut->summary_log ? dut->summary_log : "");
3298 if (res < 0 || res >= (int) sizeof(cmd))
3299 return -1;
3300
3301 res = snprintf(buf, sizeof(buf), "%s %s", cmd, params);
3302 if (res < 0 || res >= (int) sizeof(buf))
3303 return -1;
3304 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
3305
3306 if (system(buf) != 0) {
3307 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to run: %s", buf);
3308 return -1;
3309 }
3310 sigma_dut_print(dut, DUT_MSG_DEBUG,
3311 "Completed hs20-osu-client operation");
3312
3313 return 0;
3314}
3315
3316
3317static int download_ppsmo(struct sigma_dut *dut,
3318 struct sigma_conn *conn,
3319 const char *intf,
3320 struct sigma_cmd *cmd)
3321{
3322 const char *name, *path, *val;
3323 char url[500], buf[600], fbuf[100];
3324 char *fqdn = NULL;
3325
3326 name = get_param(cmd, "FileName");
3327 path = get_param(cmd, "FilePath");
3328 if (name == NULL || path == NULL)
3329 return -1;
3330
3331 if (strcasecmp(path, "VendorSpecific") == 0) {
3332 snprintf(url, sizeof(url), "PPS/%s", name);
3333 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured PPS MO "
3334 "from the device (%s)", url);
3335 if (!file_exists(url)) {
3336 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
3337 "PPS MO file does not exist");
3338 return 0;
3339 }
3340 snprintf(buf, sizeof(buf), "cp %s pps-tnds.xml", url);
3341 if (system(buf) != 0) {
3342 send_resp(dut, conn, SIGMA_ERROR,
3343 "errorCode,Failed to copy PPS MO");
3344 return 0;
3345 }
3346 } else if (strncasecmp(path, "http:", 5) != 0 &&
3347 strncasecmp(path, "https:", 6) != 0) {
3348 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
3349 "Unsupported FilePath value");
3350 return 0;
3351 } else {
3352 snprintf(url, sizeof(url), "%s/%s", path, name);
3353 sigma_dut_print(dut, DUT_MSG_INFO, "Downloading PPS MO from %s",
3354 url);
3355 snprintf(buf, sizeof(buf), "wget -T 10 -t 3 -O pps-tnds.xml '%s'", url);
3356 remove("pps-tnds.xml");
3357 if (system(buf) != 0) {
3358 send_resp(dut, conn, SIGMA_ERROR,
3359 "errorCode,Failed to download PPS MO");
3360 return 0;
3361 }
3362 }
3363
3364 if (run_hs20_osu(dut, "from_tnds pps-tnds.xml pps.xml") < 0) {
3365 send_resp(dut, conn, SIGMA_ERROR,
3366 "errorCode,Failed to parse downloaded PPSMO");
3367 return 0;
3368 }
3369 unlink("pps-tnds.xml");
3370
3371 val = get_param(cmd, "managementTreeURI");
3372 if (val) {
3373 const char *pos, *end;
3374 sigma_dut_print(dut, DUT_MSG_DEBUG, "managementTreeURI: %s",
3375 val);
3376 if (strncmp(val, "./Wi-Fi/", 8) != 0) {
3377 send_resp(dut, conn, SIGMA_ERROR,
3378 "errorCode,Invalid managementTreeURI prefix");
3379 return 0;
3380 }
3381 pos = val + 8;
3382 end = strchr(pos, '/');
3383 if (end == NULL ||
3384 strcmp(end, "/PerProviderSubscription") != 0) {
3385 send_resp(dut, conn, SIGMA_ERROR,
3386 "errorCode,Invalid managementTreeURI postfix");
3387 return 0;
3388 }
3389 if (end - pos >= (int) sizeof(fbuf)) {
3390 send_resp(dut, conn, SIGMA_ERROR,
3391 "errorCode,Too long FQDN in managementTreeURI");
3392 return 0;
3393 }
3394 memcpy(fbuf, pos, end - pos);
3395 fbuf[end - pos] = '\0';
3396 fqdn = fbuf;
3397 sigma_dut_print(dut, DUT_MSG_INFO,
3398 "FQDN from managementTreeURI: %s", fqdn);
3399 } else if (run_hs20_osu(dut, "get_fqdn pps.xml") == 0) {
3400 FILE *f = fopen("pps-fqdn", "r");
3401 if (f) {
3402 if (fgets(fbuf, sizeof(fbuf), f)) {
3403 fbuf[sizeof(fbuf) - 1] = '\0';
3404 fqdn = fbuf;
3405 sigma_dut_print(dut, DUT_MSG_DEBUG,
3406 "Use FQDN %s", fqdn);
3407 }
3408 fclose(f);
3409 }
3410 }
3411
3412 if (fqdn == NULL) {
3413 send_resp(dut, conn, SIGMA_ERROR,
3414 "errorCode,No FQDN specified");
3415 return 0;
3416 }
3417
3418 mkdir("SP", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
3419 snprintf(buf, sizeof(buf), "SP/%s", fqdn);
3420 mkdir(buf, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
3421
3422 snprintf(buf, sizeof(buf), "SP/%s/pps.xml", fqdn);
3423 if (rename("pps.xml", buf) < 0) {
3424 send_resp(dut, conn, SIGMA_ERROR,
3425 "errorCode,Could not move PPS MO");
3426 return 0;
3427 }
3428
3429 if (strcasecmp(path, "VendorSpecific") == 0) {
3430 snprintf(buf, sizeof(buf), "cp Certs/ca.pem SP/%s/ca.pem",
3431 fqdn);
3432 if (system(buf)) {
3433 send_resp(dut, conn, SIGMA_ERROR,
3434 "errorCode,Failed to copy OSU CA cert");
3435 return 0;
3436 }
3437
3438 snprintf(buf, sizeof(buf),
3439 "cp Certs/aaa-ca.pem SP/%s/aaa-ca.pem",
3440 fqdn);
3441 if (system(buf)) {
3442 send_resp(dut, conn, SIGMA_ERROR,
3443 "errorCode,Failed to copy AAA CA cert");
3444 return 0;
3445 }
3446 } else {
3447 snprintf(buf, sizeof(buf),
3448 "dl_osu_ca SP/%s/pps.xml SP/%s/ca.pem",
3449 fqdn, fqdn);
3450 if (run_hs20_osu(dut, buf) < 0) {
3451 send_resp(dut, conn, SIGMA_ERROR,
3452 "errorCode,Failed to download OSU CA cert");
3453 return 0;
3454 }
3455
3456 snprintf(buf, sizeof(buf),
3457 "dl_aaa_ca SP/%s/pps.xml SP/%s/aaa-ca.pem",
3458 fqdn, fqdn);
3459 if (run_hs20_osu(dut, buf) < 0) {
3460 sigma_dut_print(dut, DUT_MSG_INFO,
3461 "Failed to download AAA CA cert");
3462 }
3463 }
3464
3465 if (file_exists("next-client-cert.pem")) {
3466 snprintf(buf, sizeof(buf), "SP/%s/client-cert.pem", fqdn);
3467 if (rename("next-client-cert.pem", buf) < 0) {
3468 send_resp(dut, conn, SIGMA_ERROR,
3469 "errorCode,Could not move client certificate");
3470 return 0;
3471 }
3472 }
3473
3474 if (file_exists("next-client-key.pem")) {
3475 snprintf(buf, sizeof(buf), "SP/%s/client-key.pem", fqdn);
3476 if (rename("next-client-key.pem", buf) < 0) {
3477 send_resp(dut, conn, SIGMA_ERROR,
3478 "errorCode,Could not move client key");
3479 return 0;
3480 }
3481 }
3482
3483 snprintf(buf, sizeof(buf), "set_pps SP/%s/pps.xml", fqdn);
3484 if (run_hs20_osu(dut, buf) < 0) {
3485 send_resp(dut, conn, SIGMA_ERROR,
3486 "errorCode,Failed to configure credential from "
3487 "PPSMO");
3488 return 0;
3489 }
3490
3491 return 1;
3492}
3493
3494
3495static int download_cert(struct sigma_dut *dut,
3496 struct sigma_conn *conn,
3497 const char *intf,
3498 struct sigma_cmd *cmd)
3499{
3500 const char *name, *path;
3501 char url[500], buf[600];
3502
3503 name = get_param(cmd, "FileName");
3504 path = get_param(cmd, "FilePath");
3505 if (name == NULL || path == NULL)
3506 return -1;
3507
3508 if (strcasecmp(path, "VendorSpecific") == 0) {
3509 snprintf(url, sizeof(url), "Certs/%s-cert.pem", name);
3510 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured client "
3511 "certificate from the device (%s)", url);
3512 if (!file_exists(url)) {
3513 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
3514 "certificate file does not exist");
3515 return 0;
3516 }
3517 snprintf(buf, sizeof(buf), "cp %s next-client-cert.pem", url);
3518 if (system(buf) != 0) {
3519 send_resp(dut, conn, SIGMA_ERROR,
3520 "errorCode,Failed to copy client "
3521 "certificate");
3522 return 0;
3523 }
3524
3525 snprintf(url, sizeof(url), "Certs/%s-key.pem", name);
3526 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured client "
3527 "private key from the device (%s)", url);
3528 if (!file_exists(url)) {
3529 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
3530 "private key file does not exist");
3531 return 0;
3532 }
3533 snprintf(buf, sizeof(buf), "cp %s next-client-key.pem", url);
3534 if (system(buf) != 0) {
3535 send_resp(dut, conn, SIGMA_ERROR,
3536 "errorCode,Failed to copy client key");
3537 return 0;
3538 }
3539 } else if (strncasecmp(path, "http:", 5) != 0 &&
3540 strncasecmp(path, "https:", 6) != 0) {
3541 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
3542 "Unsupported FilePath value");
3543 return 0;
3544 } else {
3545 snprintf(url, sizeof(url), "%s/%s.pem", path, name);
3546 sigma_dut_print(dut, DUT_MSG_INFO, "Downloading client "
3547 "certificate/key from %s", url);
3548 snprintf(buf, sizeof(buf),
3549 "wget -T 10 -t 3 -O next-client-cert.pem '%s'", url);
3550 if (system(buf) != 0) {
3551 send_resp(dut, conn, SIGMA_ERROR,
3552 "errorCode,Failed to download client "
3553 "certificate");
3554 return 0;
3555 }
3556
3557 if (system("cp next-client-cert.pem next-client-key.pem") != 0)
3558 {
3559 send_resp(dut, conn, SIGMA_ERROR,
3560 "errorCode,Failed to copy client key");
3561 return 0;
3562 }
3563 }
3564
3565 return 1;
3566}
3567
3568
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02003569static int cmd_sta_preset_testparameters_60ghz(struct sigma_dut *dut,
3570 struct sigma_conn *conn,
3571 struct sigma_cmd *cmd)
3572{
3573 const char *val;
3574 const char *intf = get_param(cmd, "interface");
3575
3576 if (!intf)
3577 return -1;
3578
3579 val = get_param(cmd, "WscIEFragment");
3580 if (val && strcasecmp(val, "enable") == 0) {
3581 sigma_dut_print(dut, DUT_MSG_DEBUG,
3582 "Enable WSC IE fragmentation");
3583
3584 dut->wsc_fragment = 1;
3585 /* set long attributes to force fragmentation */
3586 if (wpa_command(intf, "SET device_name "
3587 WPS_LONG_DEVICE_NAME) < 0)
3588 return -2;
3589 if (wpa_command(intf, "SET manufacturer "
3590 WPS_LONG_MANUFACTURER) < 0)
3591 return -2;
3592 if (wpa_command(intf, "SET model_name "
3593 WPS_LONG_MODEL_NAME) < 0)
3594 return -2;
3595 if (wpa_command(intf, "SET model_number "
3596 WPS_LONG_MODEL_NUMBER) < 0)
3597 return -2;
3598 if (wpa_command(intf, "SET serial_number "
3599 WPS_LONG_SERIAL_NUMBER) < 0)
3600 return -2;
3601 }
3602
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02003603 val = get_param(cmd, "RSN_IE");
3604 if (val) {
3605 if (strcasecmp(val, "disable") == 0)
3606 dut->force_rsn_ie = FORCE_RSN_IE_REMOVE;
3607 else if (strcasecmp(val, "enable") == 0)
3608 dut->force_rsn_ie = FORCE_RSN_IE_ADD;
3609 }
3610
Alexei Avshalom Lazar744ae8a2019-01-31 17:26:46 +02003611 val = get_param(cmd, "WpsVersion");
3612 if (val)
3613 dut->wps_forced_version = get_wps_forced_version(dut, val);
3614
Alexei Avshalom Lazar2eccf4d2019-01-31 10:03:59 +02003615 val = get_param(cmd, "WscEAPFragment");
3616 if (val && strcasecmp(val, "enable") == 0)
3617 dut->eap_fragment = 1;
3618
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02003619 return 1;
3620}
3621
3622
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003623static int cmd_sta_preset_testparameters_hs2_r2(struct sigma_dut *dut,
3624 struct sigma_conn *conn,
3625 const char *intf,
3626 struct sigma_cmd *cmd)
3627{
3628 const char *val;
3629
3630 val = get_param(cmd, "FileType");
3631 if (val && strcasecmp(val, "PPSMO") == 0)
3632 return download_ppsmo(dut, conn, intf, cmd);
3633 if (val && strcasecmp(val, "CERT") == 0)
3634 return download_cert(dut, conn, intf, cmd);
3635 if (val) {
3636 send_resp(dut, conn, SIGMA_ERROR,
3637 "ErrorCode,Unsupported FileType");
3638 return 0;
3639 }
3640
3641 return 1;
3642}
3643
3644
Ankita Bajaja2cb5672017-10-25 16:08:28 +05303645static int cmd_sta_preset_testparameters_oce(struct sigma_dut *dut,
3646 struct sigma_conn *conn,
3647 const char *intf,
3648 struct sigma_cmd *cmd)
3649{
3650 const char *val;
Ankita Bajaj1bde7942018-01-09 19:15:01 +05303651 char buf[1000];
3652 char text[20];
3653 unsigned char addr[ETH_ALEN];
Ankita Bajaja2cb5672017-10-25 16:08:28 +05303654
3655 val = get_param(cmd, "OCESupport");
3656 if (val && strcasecmp(val, "Disable") == 0) {
3657 if (wpa_command(intf, "SET oce 0") < 0) {
3658 send_resp(dut, conn, SIGMA_ERROR,
3659 "ErrorCode,Failed to disable OCE");
3660 return 0;
3661 }
3662 } else if (val && strcasecmp(val, "Enable") == 0) {
3663 if (wpa_command(intf, "SET oce 1") < 0) {
3664 send_resp(dut, conn, SIGMA_ERROR,
3665 "ErrorCode,Failed to enable OCE");
3666 return 0;
3667 }
3668 }
3669
vamsi krishnaa2799492017-12-05 14:28:01 +05303670 val = get_param(cmd, "FILScap");
3671 if (val && (atoi(val) == 1)) {
3672 if (wpa_command(intf, "SET disable_fils 0") < 0) {
3673 send_resp(dut, conn, SIGMA_ERROR,
3674 "ErrorCode,Failed to enable FILS");
3675 return 0;
3676 }
3677 } else if (val && (atoi(val) == 0)) {
3678 if (wpa_command(intf, "SET disable_fils 1") < 0) {
3679 send_resp(dut, conn, SIGMA_ERROR,
3680 "ErrorCode,Failed to disable FILS");
3681 return 0;
3682 }
3683 }
3684
Ankita Bajaj1bde7942018-01-09 19:15:01 +05303685 val = get_param(cmd, "FILSHLP");
3686 if (val && strcasecmp(val, "Enable") == 0) {
3687 if (get_wpa_status(get_station_ifname(), "address", text,
3688 sizeof(text)) < 0)
3689 return -2;
3690 hwaddr_aton(text, addr);
3691 snprintf(buf, sizeof(buf),
3692 "FILS_HLP_REQ_ADD ff:ff:ff:ff:ff:ff "
3693 "080045100140000040004011399e00000000ffffffff00440043"
3694 "012cb30001010600fd4f46410000000000000000000000000000"
3695 "000000000000"
3696 "%02x%02x%02x%02x%02x%02x"
3697 "0000000000000000000000000000000000000000000000000000"
3698 "0000000000000000000000000000000000000000000000000000"
3699 "0000000000000000000000000000000000000000000000000000"
3700 "0000000000000000000000000000000000000000000000000000"
3701 "0000000000000000000000000000000000000000000000000000"
3702 "0000000000000000000000000000000000000000000000000000"
3703 "0000000000000000000000000000000000000000000000000000"
3704 "0000000000000000000000000000000000000000638253633501"
3705 "013d0701000af549d29b390205dc3c12616e64726f69642d6468"
3706 "63702d382e302e30370a0103060f1a1c333a3b2b5000ff00",
3707 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
3708 if (wpa_command(intf, buf)) {
3709 send_resp(dut, conn, SIGMA_ERROR,
3710 "ErrorCode,Failed to add HLP");
3711 return 0;
3712 }
3713 dut->fils_hlp = 1;
3714 }
3715
Ankita Bajaja2cb5672017-10-25 16:08:28 +05303716 return 1;
3717}
3718
3719
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003720static void ath_sta_set_noack(struct sigma_dut *dut, const char *intf,
3721 const char *val)
3722{
3723 int counter = 0;
3724 char token[50];
3725 char *result;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05303726 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003727
Peng Xub8fc5cc2017-05-10 17:27:28 -07003728 strlcpy(token, val, sizeof(token));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003729 token[sizeof(token) - 1] = '\0';
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05303730 result = strtok_r(token, ":", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003731 while (result) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07003732 if (strcmp(result, "disable") == 0)
3733 run_iwpriv(dut, intf, "noackpolicy %d 1 0", counter);
3734 else
3735 run_iwpriv(dut, intf, "noackpolicy %d 1 1", counter);
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05303736 result = strtok_r(NULL, ":", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003737 counter++;
3738 }
3739}
3740
3741
3742static void ath_sta_set_rts(struct sigma_dut *dut, const char *intf,
3743 const char *val)
3744{
3745 char buf[100];
3746
3747 snprintf(buf, sizeof(buf), "iwconfig %s rts %s", intf, val);
3748 if (system(buf) != 0) {
3749 sigma_dut_print(dut, DUT_MSG_ERROR, "iwconfig RTS failed");
3750 }
3751}
3752
3753
3754static void ath_sta_set_wmm(struct sigma_dut *dut, const char *intf,
3755 const char *val)
3756{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003757 if (strcasecmp(val, "off") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07003758 run_iwpriv(dut, intf, "wmm 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003759 }
3760}
3761
3762
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08003763static int wcn_sta_set_wmm(struct sigma_dut *dut, const char *intf,
3764 const char *val)
3765{
3766#ifdef NL80211_SUPPORT
3767 struct nl_msg *msg;
3768 int ret = 0;
3769 struct nlattr *params;
3770 int ifindex;
3771 int wmmenable = 1;
3772
3773 if (val &&
3774 (strcasecmp(val, "off") == 0 || strcmp(val, "0") == 0))
3775 wmmenable = 0;
3776
3777 ifindex = if_nametoindex(intf);
3778 if (ifindex == 0) {
3779 sigma_dut_print(dut, DUT_MSG_ERROR,
3780 "%s: Index for interface %s failed",
3781 __func__, intf);
3782 return -1;
3783 }
3784
3785 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
3786 NL80211_CMD_VENDOR)) ||
3787 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
3788 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
3789 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
3790 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
3791 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
3792 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WMM_ENABLE,
3793 wmmenable)) {
3794 sigma_dut_print(dut, DUT_MSG_ERROR,
3795 "%s: err in adding vendor_cmd and vendor_data",
3796 __func__);
3797 nlmsg_free(msg);
3798 return -1;
3799 }
3800 nla_nest_end(msg, params);
3801
3802 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
3803 if (ret) {
3804 sigma_dut_print(dut, DUT_MSG_ERROR,
3805 "%s: err in send_and_recv_msgs, ret=%d",
3806 __func__, ret);
3807 }
3808 return ret;
3809#else /* NL80211_SUPPORT */
3810 sigma_dut_print(dut, DUT_MSG_ERROR,
3811 "WMM cannot be changed without NL80211_SUPPORT defined");
3812 return -1;
3813#endif /* NL80211_SUPPORT */
3814}
3815
3816
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003817static void ath_sta_set_sgi(struct sigma_dut *dut, const char *intf,
3818 const char *val)
3819{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003820 int sgi20;
3821
3822 sgi20 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
3823
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07003824 run_iwpriv(dut, intf, "shortgi %d", sgi20);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003825}
3826
3827
3828static void ath_sta_set_11nrates(struct sigma_dut *dut, const char *intf,
3829 const char *val)
3830{
Pradeep Reddy POTTETI67376b72016-10-25 20:08:17 +05303831 int rate_code, v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003832
3833 /* Disable Tx Beam forming when using a fixed rate */
3834 ath_disable_txbf(dut, intf);
3835
Pradeep Reddy POTTETI67376b72016-10-25 20:08:17 +05303836 v = atoi(val);
3837 if (v < 0 || v > 32) {
3838 sigma_dut_print(dut, DUT_MSG_ERROR,
3839 "Invalid Fixed MCS rate: %d", v);
3840 return;
3841 }
3842 rate_code = 0x80 + v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003843
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07003844 run_iwpriv(dut, intf, "set11NRates 0x%x", rate_code);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003845
3846 /* Channel width gets messed up, fix this */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07003847 run_iwpriv(dut, intf, "chwidth %d", dut->chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003848}
3849
3850
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08003851static void iwpriv_sta_set_amsdu(struct sigma_dut *dut, const char *intf,
3852 const char *val)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003853{
3854 char buf[60];
3855
3856 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)
3857 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 2", intf);
3858 else
3859 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 1", intf);
3860
3861 if (system(buf) != 0)
3862 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv amsdu failed");
3863}
3864
3865
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07003866static int iwpriv_sta_set_ampdu(struct sigma_dut *dut, const char *intf,
3867 int ampdu)
3868{
3869 char buf[60];
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08003870 int maxaggregation = 63;
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07003871
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08003872 if (ampdu)
3873 ampdu = maxaggregation;
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07003874 snprintf(buf, sizeof(buf), "iwpriv %s ampdu %d", intf, ampdu);
3875 if (system(buf) != 0) {
3876 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv ampdu failed");
3877 return -1;
3878 }
3879
3880 return 0;
3881}
3882
3883
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003884static void ath_sta_set_stbc(struct sigma_dut *dut, const char *intf,
3885 const char *val)
3886{
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07003887 run_iwpriv(dut, intf, "tx_stbc %s", val);
3888 run_iwpriv(dut, intf, "rx_stbc %s", val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003889}
3890
3891
3892static int wcn_sta_set_cts_width(struct sigma_dut *dut, const char *intf,
3893 const char *val)
3894{
3895 char buf[60];
3896
Peng Xucc317ed2017-05-18 16:44:37 -07003897 if (strcmp(val, "160") == 0) {
3898 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 5", intf);
3899 } else if (strcmp(val, "80") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003900 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 3", intf);
3901 } else if (strcmp(val, "40") == 0) {
3902 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 2", intf);
3903 } else if (strcmp(val, "20") == 0) {
3904 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 1", intf);
3905 } else if (strcasecmp(val, "Auto") == 0) {
3906 buf[0] = '\0';
3907 } else {
3908 sigma_dut_print(dut, DUT_MSG_ERROR,
3909 "WIDTH/CTS_WIDTH value not supported");
3910 return -1;
3911 }
3912
3913 if (buf[0] != '\0' && system(buf) != 0) {
3914 sigma_dut_print(dut, DUT_MSG_ERROR,
3915 "Failed to set WIDTH/CTS_WIDTH");
3916 return -1;
3917 }
3918
3919 return 0;
3920}
3921
3922
3923int ath_set_width(struct sigma_dut *dut, struct sigma_conn *conn,
3924 const char *intf, const char *val)
3925{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003926 if (strcasecmp(val, "Auto") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07003927 run_iwpriv(dut, intf, "chwidth 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003928 dut->chwidth = 0;
3929 } else if (strcasecmp(val, "20") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07003930 run_iwpriv(dut, intf, "chwidth 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003931 dut->chwidth = 0;
3932 } else if (strcasecmp(val, "40") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07003933 run_iwpriv(dut, intf, "chwidth 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003934 dut->chwidth = 1;
3935 } else if (strcasecmp(val, "80") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07003936 run_iwpriv(dut, intf, "chwidth 2");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003937 dut->chwidth = 2;
3938 } else if (strcasecmp(val, "160") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07003939 run_iwpriv(dut, intf, "chwidth 3");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003940 dut->chwidth = 3;
3941 } else {
3942 send_resp(dut, conn, SIGMA_ERROR,
3943 "ErrorCode,WIDTH not supported");
3944 return -1;
3945 }
3946
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003947 return 0;
3948}
3949
3950
3951static int wcn_sta_set_sp_stream(struct sigma_dut *dut, const char *intf,
3952 const char *val)
3953{
3954 char buf[60];
Arif Hussainac6c5112018-05-25 17:34:00 -07003955 int sta_nss;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003956
Amarnath Hullur Subramanyamd5374fa2018-02-25 19:00:24 -08003957 if (strcmp(val, "1SS") == 0 || strcmp(val, "1") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003958 snprintf(buf, sizeof(buf), "iwpriv %s nss 1", intf);
Arif Hussainac6c5112018-05-25 17:34:00 -07003959 sta_nss = 1;
Amarnath Hullur Subramanyamd5374fa2018-02-25 19:00:24 -08003960 } else if (strcmp(val, "2SS") == 0 || strcmp(val, "2") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003961 snprintf(buf, sizeof(buf), "iwpriv %s nss 2", intf);
Arif Hussainac6c5112018-05-25 17:34:00 -07003962 sta_nss = 2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003963 } else {
3964 sigma_dut_print(dut, DUT_MSG_ERROR,
3965 "SP_STREAM value not supported");
3966 return -1;
3967 }
3968
3969 if (system(buf) != 0) {
3970 sigma_dut_print(dut, DUT_MSG_ERROR,
3971 "Failed to set SP_STREAM");
3972 return -1;
3973 }
3974
Arif Hussainac6c5112018-05-25 17:34:00 -07003975 dut->sta_nss = sta_nss;
3976
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003977 return 0;
3978}
3979
3980
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05303981static void wcn_sta_set_stbc(struct sigma_dut *dut, const char *intf,
3982 const char *val)
3983{
3984 char buf[60];
3985
3986 snprintf(buf, sizeof(buf), "iwpriv %s tx_stbc %s", intf, val);
3987 if (system(buf) != 0)
3988 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv tx_stbc failed");
3989
3990 snprintf(buf, sizeof(buf), "iwpriv %s rx_stbc %s", intf, val);
3991 if (system(buf) != 0)
3992 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv rx_stbc failed");
3993}
3994
3995
Ashwini Patil68d02cd2017-01-10 15:39:16 +05303996static int mbo_set_cellular_data_capa(struct sigma_dut *dut,
3997 struct sigma_conn *conn,
3998 const char *intf, int capa)
3999{
4000 char buf[32];
4001
4002 if (capa > 0 && capa < 4) {
4003 snprintf(buf, sizeof(buf), "SET mbo_cell_capa %d", capa);
4004 if (wpa_command(intf, buf) < 0) {
4005 send_resp(dut, conn, SIGMA_ERROR,
4006 "ErrorCode, Failed to set cellular data capability");
4007 return 0;
4008 }
4009 return 1;
4010 }
4011
4012 sigma_dut_print(dut, DUT_MSG_ERROR,
4013 "Invalid Cellular data capability: %d", capa);
4014 send_resp(dut, conn, SIGMA_INVALID,
4015 "ErrorCode,Invalid cellular data capability");
4016 return 0;
4017}
4018
4019
Ashwini Patil9183fdb2017-04-13 16:58:25 +05304020static int mbo_set_roaming(struct sigma_dut *dut, struct sigma_conn *conn,
4021 const char *intf, const char *val)
4022{
4023 if (strcasecmp(val, "Disable") == 0) {
4024 if (wpa_command(intf, "SET roaming 0") < 0) {
4025 send_resp(dut, conn, SIGMA_ERROR,
4026 "ErrorCode,Failed to disable roaming");
4027 return 0;
4028 }
4029 return 1;
4030 }
4031
4032 if (strcasecmp(val, "Enable") == 0) {
4033 if (wpa_command(intf, "SET roaming 1") < 0) {
4034 send_resp(dut, conn, SIGMA_ERROR,
4035 "ErrorCode,Failed to enable roaming");
4036 return 0;
4037 }
4038 return 1;
4039 }
4040
4041 sigma_dut_print(dut, DUT_MSG_ERROR,
4042 "Invalid value provided for roaming: %s", val);
4043 send_resp(dut, conn, SIGMA_INVALID,
4044 "ErrorCode,Unknown value provided for Roaming");
4045 return 0;
4046}
4047
4048
Ashwini Patila75de5a2017-04-13 16:35:05 +05304049static int mbo_set_assoc_disallow(struct sigma_dut *dut,
4050 struct sigma_conn *conn,
4051 const char *intf, const char *val)
4052{
4053 if (strcasecmp(val, "Disable") == 0) {
4054 if (wpa_command(intf, "SET ignore_assoc_disallow 1") < 0) {
4055 send_resp(dut, conn, SIGMA_ERROR,
4056 "ErrorCode,Failed to disable Assoc_disallow");
4057 return 0;
4058 }
4059 return 1;
4060 }
4061
4062 if (strcasecmp(val, "Enable") == 0) {
4063 if (wpa_command(intf, "SET ignore_assoc_disallow 0") < 0) {
4064 send_resp(dut, conn, SIGMA_ERROR,
4065 "ErrorCode,Failed to enable Assoc_disallow");
4066 return 0;
4067 }
4068 return 1;
4069 }
4070
4071 sigma_dut_print(dut, DUT_MSG_ERROR,
4072 "Invalid value provided for Assoc_disallow: %s", val);
4073 send_resp(dut, conn, SIGMA_INVALID,
4074 "ErrorCode,Unknown value provided for Assoc_disallow");
4075 return 0;
4076}
4077
4078
Ashwini Patilc63161e2017-04-13 16:30:23 +05304079static int mbo_set_bss_trans_req(struct sigma_dut *dut, struct sigma_conn *conn,
4080 const char *intf, const char *val)
4081{
4082 if (strcasecmp(val, "Reject") == 0) {
4083 if (wpa_command(intf, "SET reject_btm_req_reason 1") < 0) {
4084 send_resp(dut, conn, SIGMA_ERROR,
4085 "ErrorCode,Failed to Reject BTM Request");
4086 return 0;
4087 }
4088 return 1;
4089 }
4090
4091 if (strcasecmp(val, "Accept") == 0) {
4092 if (wpa_command(intf, "SET reject_btm_req_reason 0") < 0) {
4093 send_resp(dut, conn, SIGMA_ERROR,
4094 "ErrorCode,Failed to Accept BTM Request");
4095 return 0;
4096 }
4097 return 1;
4098 }
4099
4100 sigma_dut_print(dut, DUT_MSG_ERROR,
4101 "Invalid value provided for BSS_Transition: %s", val);
4102 send_resp(dut, conn, SIGMA_INVALID,
4103 "ErrorCode,Unknown value provided for BSS_Transition");
4104 return 0;
4105}
4106
4107
Ashwini Patil00402582017-04-13 12:29:39 +05304108static int mbo_set_non_pref_ch_list(struct sigma_dut *dut,
4109 struct sigma_conn *conn,
4110 const char *intf,
4111 struct sigma_cmd *cmd)
4112{
4113 const char *ch, *pref, *op_class, *reason;
4114 char buf[120];
4115 int len, ret;
4116
4117 pref = get_param(cmd, "Ch_Pref");
4118 if (!pref)
4119 return 1;
4120
4121 if (strcasecmp(pref, "clear") == 0) {
4122 free(dut->non_pref_ch_list);
4123 dut->non_pref_ch_list = NULL;
4124 } else {
4125 op_class = get_param(cmd, "Ch_Op_Class");
4126 if (!op_class) {
4127 send_resp(dut, conn, SIGMA_INVALID,
4128 "ErrorCode,Ch_Op_Class not provided");
4129 return 0;
4130 }
4131
4132 ch = get_param(cmd, "Ch_Pref_Num");
4133 if (!ch) {
4134 send_resp(dut, conn, SIGMA_INVALID,
4135 "ErrorCode,Ch_Pref_Num not provided");
4136 return 0;
4137 }
4138
4139 reason = get_param(cmd, "Ch_Reason_Code");
4140 if (!reason) {
4141 send_resp(dut, conn, SIGMA_INVALID,
4142 "ErrorCode,Ch_Reason_Code not provided");
4143 return 0;
4144 }
4145
4146 if (!dut->non_pref_ch_list) {
4147 dut->non_pref_ch_list =
4148 calloc(1, NON_PREF_CH_LIST_SIZE);
4149 if (!dut->non_pref_ch_list) {
4150 send_resp(dut, conn, SIGMA_ERROR,
4151 "ErrorCode,Failed to allocate memory for non_pref_ch_list");
4152 return 0;
4153 }
4154 }
4155 len = strlen(dut->non_pref_ch_list);
4156 ret = snprintf(dut->non_pref_ch_list + len,
4157 NON_PREF_CH_LIST_SIZE - len,
4158 " %s:%s:%s:%s", op_class, ch, pref, reason);
4159 if (ret > 0 && ret < NON_PREF_CH_LIST_SIZE - len) {
4160 sigma_dut_print(dut, DUT_MSG_DEBUG, "non_pref_list: %s",
4161 dut->non_pref_ch_list);
4162 } else {
4163 sigma_dut_print(dut, DUT_MSG_ERROR,
4164 "snprintf failed for non_pref_list, ret = %d",
4165 ret);
4166 send_resp(dut, conn, SIGMA_ERROR,
4167 "ErrorCode,snprintf failed");
4168 free(dut->non_pref_ch_list);
4169 dut->non_pref_ch_list = NULL;
4170 return 0;
4171 }
4172 }
4173
4174 ret = snprintf(buf, sizeof(buf), "SET non_pref_chan%s",
4175 dut->non_pref_ch_list ? dut->non_pref_ch_list : " ");
4176 if (ret < 0 || ret >= (int) sizeof(buf)) {
4177 sigma_dut_print(dut, DUT_MSG_DEBUG,
4178 "snprintf failed for set non_pref_chan, ret: %d",
4179 ret);
4180 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,snprint failed");
4181 return 0;
4182 }
4183
4184 if (wpa_command(intf, buf) < 0) {
4185 send_resp(dut, conn, SIGMA_ERROR,
4186 "ErrorCode,Failed to set non-preferred channel list");
4187 return 0;
4188 }
4189
4190 return 1;
4191}
4192
4193
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08004194#ifdef NL80211_SUPPORT
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08004195
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08004196static int sta_set_he_htc_supp(struct sigma_dut *dut, const char *intf,
4197 uint8_t cfg)
4198{
4199 struct nl_msg *msg;
4200 int ret = 0;
4201 struct nlattr *params;
4202 int ifindex;
4203
4204 ifindex = if_nametoindex(intf);
4205 if (ifindex == 0) {
4206 sigma_dut_print(dut, DUT_MSG_ERROR,
4207 "%s: Index for interface %s failed",
4208 __func__, intf);
4209 return -1;
4210 }
4211
4212 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4213 NL80211_CMD_VENDOR)) ||
4214 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4215 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4216 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4217 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4218 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4219 nla_put_u8(msg,
4220 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_HTC_HE_SUPP,
4221 cfg)) {
4222 sigma_dut_print(dut, DUT_MSG_ERROR,
4223 "%s: err in adding vendor_cmd and vendor_data",
4224 __func__);
4225 nlmsg_free(msg);
4226 return -1;
4227 }
4228 nla_nest_end(msg, params);
4229
4230 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4231 if (ret) {
4232 sigma_dut_print(dut, DUT_MSG_ERROR,
4233 "%s: err in send_and_recv_msgs, ret=%d",
4234 __func__, ret);
4235 }
4236 return ret;
4237}
4238
4239
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08004240static int sta_set_he_fragmentation(struct sigma_dut *dut, const char *intf,
4241 enum he_fragmentation_val frag)
4242{
4243 struct nl_msg *msg;
4244 int ret = 0;
4245 struct nlattr *params;
4246 int ifindex;
4247
4248 ifindex = if_nametoindex(intf);
4249 if (ifindex == 0) {
4250 sigma_dut_print(dut, DUT_MSG_ERROR,
4251 "%s: Index for interface %s failed",
4252 __func__, intf);
4253 return -1;
4254 }
4255
4256 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4257 NL80211_CMD_VENDOR)) ||
4258 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4259 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4260 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4261 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4262 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4263 nla_put_u8(msg,
4264 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_FRAGMENTATION,
4265 frag)) {
4266 sigma_dut_print(dut, DUT_MSG_ERROR,
4267 "%s: err in adding vendor_cmd and vendor_data",
4268 __func__);
4269 nlmsg_free(msg);
4270 return -1;
4271 }
4272 nla_nest_end(msg, params);
4273
4274 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4275 if (ret) {
4276 sigma_dut_print(dut, DUT_MSG_ERROR,
4277 "%s: err in send_and_recv_msgs, ret=%d",
4278 __func__, ret);
4279 }
4280 return ret;
4281}
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08004282
4283
Subhani Shaik8e7a3052018-04-24 14:03:00 -07004284static int sta_set_he_ltf(struct sigma_dut *dut, const char *intf,
4285 enum qca_wlan_he_ltf_cfg ltf)
4286{
4287 struct nl_msg *msg;
4288 int ret = 0;
4289 struct nlattr *params;
4290 int ifindex;
4291
4292 ifindex = if_nametoindex(intf);
4293 if (ifindex == 0) {
4294 sigma_dut_print(dut, DUT_MSG_ERROR,
4295 "%s: Index for interface %s failed",
4296 __func__, intf);
4297 return -1;
4298 }
4299
4300 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4301 NL80211_CMD_VENDOR)) ||
4302 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4303 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4304 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4305 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4306 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4307 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_LTF,
4308 ltf)) {
4309 sigma_dut_print(dut, DUT_MSG_ERROR,
4310 "%s: err in adding vendor_cmd and vendor_data",
4311 __func__);
4312 nlmsg_free(msg);
4313 return -1;
4314 }
4315 nla_nest_end(msg, params);
4316
4317 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4318 if (ret) {
4319 sigma_dut_print(dut, DUT_MSG_ERROR,
4320 "%s: err in send_and_recv_msgs, ret=%d",
4321 __func__, ret);
4322 }
4323 return ret;
4324}
4325
4326
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08004327static int nlvendor_sta_set_noack(struct sigma_dut *dut, const char *intf,
4328 int noack, enum qca_wlan_ac_type ac)
4329{
4330 struct nl_msg *msg;
4331 int ret = 0;
4332 struct nlattr *params;
4333 int ifindex;
4334
4335 ifindex = if_nametoindex(intf);
4336 if (ifindex == 0) {
4337 sigma_dut_print(dut, DUT_MSG_ERROR,
4338 "%s: Index for interface %s failed",
4339 __func__, intf);
4340 return -1;
4341 }
4342
4343 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4344 NL80211_CMD_VENDOR)) ||
4345 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4346 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4347 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4348 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4349 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4350 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_NO_ACK,
4351 noack) ||
4352 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_NO_ACK_AC,
4353 ac)) {
4354 sigma_dut_print(dut, DUT_MSG_ERROR,
4355 "%s: err in adding vendor_cmd and vendor_data",
4356 __func__);
4357 nlmsg_free(msg);
4358 return -1;
4359 }
4360 nla_nest_end(msg, params);
4361
4362 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4363 if (ret) {
4364 sigma_dut_print(dut, DUT_MSG_ERROR,
4365 "%s: err in send_and_recv_msgs, ret=%d",
4366 __func__, ret);
4367 }
4368 return ret;
4369}
4370
4371
4372static void wcn_sta_set_noack(struct sigma_dut *dut, const char *intf,
4373 const char *val)
4374{
4375 int noack, ret;
4376 char token[100];
4377 char *result;
4378 char *saveptr;
4379 enum qca_wlan_ac_type ac = QCA_WLAN_AC_BE;
4380
4381 strlcpy(token, val, sizeof(token));
4382 token[sizeof(token) - 1] = '\0';
4383 result = strtok_r(token, ":", &saveptr);
4384 while (result) {
4385 noack = strcasecmp(result, "Disable") != 0;
4386 ret = nlvendor_sta_set_noack(dut, intf, noack, ac);
4387 if (ret) {
4388 sigma_dut_print(dut, DUT_MSG_ERROR,
4389 "nlvendor_sta_set_noack failed for ac:%d, ret:%d",
4390 ac, ret);
4391 }
4392 result = strtok_r(NULL, ":", &saveptr);
4393 ac++;
4394 }
4395}
4396
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08004397#endif /* NL80211_SUPPORT */
4398
4399
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004400static int cmd_sta_preset_testparameters(struct sigma_dut *dut,
4401 struct sigma_conn *conn,
4402 struct sigma_cmd *cmd)
4403{
4404 const char *intf = get_param(cmd, "Interface");
4405 const char *val;
4406
4407 val = get_param(cmd, "Program");
Jouni Malinen1f6ae642018-06-07 23:56:13 +03004408 if (val && (strcasecmp(val, "HS2-R2") == 0 ||
4409 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004410 return cmd_sta_preset_testparameters_hs2_r2(dut, conn, intf,
4411 cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004412
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07004413 if (val && strcasecmp(val, "LOC") == 0)
4414 return loc_cmd_sta_preset_testparameters(dut, conn, cmd);
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02004415 if (val && strcasecmp(val, "60GHZ") == 0) {
4416 val = get_param(cmd, "WPS");
4417 if (val && strcasecmp(val, "disable") == 0) {
4418 dut->wps_disable = 1;
4419 sigma_dut_print(dut, DUT_MSG_INFO, "WPS disabled");
4420 } else {
4421 /* wps_disable can have other value from the previous
4422 * test, so make sure it has the correct value.
4423 */
4424 dut->wps_disable = 0;
4425 }
4426
4427 val = get_param(cmd, "P2P");
4428 if (val && strcasecmp(val, "disable") == 0)
4429 sigma_dut_print(dut, DUT_MSG_INFO, "P2P disabled");
4430 }
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07004431
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02004432 if (dut->program == PROGRAM_WPS && dut->band == WPS_BAND_60G)
4433 return cmd_sta_preset_testparameters_60ghz(dut, conn, cmd);
4434
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004435#ifdef ANDROID_NAN
4436 if (val && strcasecmp(val, "NAN") == 0)
4437 return nan_cmd_sta_preset_testparameters(dut, conn, cmd);
4438#endif /* ANDROID_NAN */
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07004439#ifdef MIRACAST
4440 if (val && (strcasecmp(val, "WFD") == 0 ||
4441 strcasecmp(val, "DisplayR2") == 0))
4442 return miracast_preset_testparameters(dut, conn, cmd);
4443#endif /* MIRACAST */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004444
Ashwini Patil68d02cd2017-01-10 15:39:16 +05304445 if (val && strcasecmp(val, "MBO") == 0) {
4446 val = get_param(cmd, "Cellular_Data_Cap");
4447 if (val &&
4448 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
4449 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +05304450
4451 val = get_param(cmd, "Ch_Pref");
4452 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
4453 return 0;
4454
Ashwini Patilc63161e2017-04-13 16:30:23 +05304455 val = get_param(cmd, "BSS_Transition");
4456 if (val && mbo_set_bss_trans_req(dut, conn, intf, val) == 0)
4457 return 0;
4458
Ashwini Patila75de5a2017-04-13 16:35:05 +05304459 val = get_param(cmd, "Assoc_Disallow");
4460 if (val && mbo_set_assoc_disallow(dut, conn, intf, val) == 0)
4461 return 0;
4462
Ashwini Patil9183fdb2017-04-13 16:58:25 +05304463 val = get_param(cmd, "Roaming");
4464 if (val && mbo_set_roaming(dut, conn, intf, val) == 0)
4465 return 0;
4466
Ashwini Patil68d02cd2017-01-10 15:39:16 +05304467 return 1;
4468 }
4469
Ankita Bajaja2cb5672017-10-25 16:08:28 +05304470 if (val && strcasecmp(val, "OCE") == 0)
4471 return cmd_sta_preset_testparameters_oce(dut, conn, intf, cmd);
4472
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004473#if 0
4474 val = get_param(cmd, "Supplicant");
4475 if (val && strcasecmp(val, "Default") != 0) {
4476 send_resp(dut, conn, SIGMA_ERROR,
4477 "ErrorCode,Only default(Vendor) supplicant "
4478 "supported");
4479 return 0;
4480 }
4481#endif
4482
4483 val = get_param(cmd, "RTS");
4484 if (val) {
4485 switch (get_driver_type()) {
4486 case DRIVER_ATHEROS:
4487 ath_sta_set_rts(dut, intf, val);
4488 break;
4489 default:
4490#if 0
4491 send_resp(dut, conn, SIGMA_ERROR,
4492 "ErrorCode,Setting RTS not supported");
4493 return 0;
4494#else
4495 sigma_dut_print(dut, DUT_MSG_DEBUG,
4496 "Setting RTS not supported");
4497 break;
4498#endif
4499 }
4500 }
4501
4502#if 0
4503 val = get_param(cmd, "FRGMNT");
4504 if (val) {
4505 /* TODO */
4506 send_resp(dut, conn, SIGMA_ERROR,
4507 "ErrorCode,Setting FRGMNT not supported");
4508 return 0;
4509 }
4510#endif
4511
4512#if 0
4513 val = get_param(cmd, "Preamble");
4514 if (val) {
4515 /* TODO: Long/Short */
4516 send_resp(dut, conn, SIGMA_ERROR,
4517 "ErrorCode,Setting Preamble not supported");
4518 return 0;
4519 }
4520#endif
4521
4522 val = get_param(cmd, "Mode");
4523 if (val) {
4524 if (strcmp(val, "11b") == 0 ||
4525 strcmp(val, "11g") == 0 ||
4526 strcmp(val, "11a") == 0 ||
4527 strcmp(val, "11n") == 0 ||
4528 strcmp(val, "11ng") == 0 ||
4529 strcmp(val, "11nl") == 0 ||
4530 strcmp(val, "11nl(nabg)") == 0 ||
4531 strcmp(val, "AC") == 0 ||
4532 strcmp(val, "11AC") == 0 ||
4533 strcmp(val, "11ac") == 0 ||
4534 strcmp(val, "11na") == 0 ||
Amarnath Hullur Subramanyamb0db2712018-01-30 19:40:35 -08004535 strcmp(val, "11an") == 0 ||
4536 strcmp(val, "11ax") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004537 /* STA supports all modes by default */
4538 } else {
4539 send_resp(dut, conn, SIGMA_ERROR,
4540 "ErrorCode,Setting Mode not supported");
4541 return 0;
4542 }
Amarnath Hullur Subramanyam97d0e532018-01-31 02:53:02 -08004543
4544 /* Change the mode only in case of testbed for HE program
4545 * and for 11a and 11g modes only. */
4546 if (dut->program == PROGRAM_HE &&
4547 dut->device_type == STA_testbed) {
4548 int phymode;
4549 char buf[60];
4550
4551 if (strcmp(val, "11a") == 0) {
Amarnath Hullur Subramanyam94dfaf02018-03-02 19:26:57 -08004552 phymode = 1; /* IEEE80211_MODE_11A */
4553 } else if (strcmp(val, "11g") == 0) {
4554 phymode = 3; /* IEEE80211_MODE_11G */
4555 } else if (strcmp(val, "11b") == 0) {
4556 phymode = 2; /* IEEE80211_MODE_11B */
4557 } else if (strcmp(val, "11n") == 0 ||
4558 strcmp(val, "11nl") == 0 ||
4559 strcmp(val, "11nl(nabg)") == 0) {
4560 phymode = 22; /* IEEE80211_MODE_11AGN */
4561 } else if (strcmp(val, "11ng") == 0) {
4562 phymode = 13; /* IEEE80211_MODE_11NG_HT40 */
4563 } else if (strcmp(val, "AC") == 0 ||
4564 strcasecmp(val, "11AC") == 0) {
4565 phymode = 19; /* IEEE80211_MODE_11AC_VHT80 */
4566 } else if (strcmp(val, "11na") == 0 ||
4567 strcasecmp(val, "11an") == 0) {
4568 phymode = 14; /* IEEE80211_MODE_11NA_HT40 */
4569 } else if (strcmp(val, "11ax") == 0) {
4570 phymode = 0; /* IEEE80211_MODE_AUTO */
Amarnath Hullur Subramanyam97d0e532018-01-31 02:53:02 -08004571 } else {
4572 sigma_dut_print(dut, DUT_MSG_DEBUG,
4573 "Ignoring mode change for mode: %s",
4574 val);
4575 phymode = -1;
4576 }
4577 if (phymode != -1) {
4578 snprintf(buf, sizeof(buf),
4579 "iwpriv %s setphymode %d",
4580 intf, phymode);
4581 if (system(buf) != 0) {
4582 sigma_dut_print(dut, DUT_MSG_ERROR,
4583 "iwpriv setting of phymode failed");
4584 }
4585 }
4586 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004587 }
4588
4589 val = get_param(cmd, "wmm");
4590 if (val) {
4591 switch (get_driver_type()) {
4592 case DRIVER_ATHEROS:
4593 ath_sta_set_wmm(dut, intf, val);
4594 break;
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08004595 case DRIVER_WCN:
4596 wcn_sta_set_wmm(dut, intf, val);
4597 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004598 default:
4599 sigma_dut_print(dut, DUT_MSG_DEBUG,
4600 "Setting wmm not supported");
4601 break;
4602 }
4603 }
4604
4605 val = get_param(cmd, "Powersave");
4606 if (val) {
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08004607 char buf[60];
4608
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004609 if (strcmp(val, "0") == 0 || strcasecmp(val, "off") == 0) {
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08004610 if (get_driver_type() == DRIVER_WCN) {
4611 snprintf(buf, sizeof(buf),
4612 "iwpriv %s setPower 2", intf);
4613 if (system(buf) != 0) {
4614 sigma_dut_print(dut, DUT_MSG_ERROR,
4615 "iwpriv setPower 2 failed");
4616 return 0;
4617 }
4618 }
4619
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004620 if (wpa_command(get_station_ifname(),
4621 "P2P_SET ps 0") < 0)
4622 return -2;
4623 /* Make sure test modes are disabled */
4624 wpa_command(get_station_ifname(), "P2P_SET ps 98");
4625 wpa_command(get_station_ifname(), "P2P_SET ps 96");
4626 } else if (strcmp(val, "1") == 0 ||
4627 strcasecmp(val, "PSPoll") == 0 ||
4628 strcasecmp(val, "on") == 0) {
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08004629 if (get_driver_type() == DRIVER_WCN) {
4630 snprintf(buf, sizeof(buf),
4631 "iwpriv %s setPower 1", intf);
4632 if (system(buf) != 0) {
4633 sigma_dut_print(dut, DUT_MSG_ERROR,
4634 "iwpriv setPower 1 failed");
4635 return 0;
4636 }
4637 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004638 /* Disable default power save mode */
4639 wpa_command(get_station_ifname(), "P2P_SET ps 0");
4640 /* Enable PS-Poll test mode */
4641 if (wpa_command(get_station_ifname(),
4642 "P2P_SET ps 97") < 0 ||
4643 wpa_command(get_station_ifname(),
4644 "P2P_SET ps 99") < 0)
4645 return -2;
4646 } else if (strcmp(val, "2") == 0 ||
4647 strcasecmp(val, "Fast") == 0) {
4648 /* TODO */
4649 send_resp(dut, conn, SIGMA_ERROR,
4650 "ErrorCode,Powersave=Fast not supported");
4651 return 0;
4652 } else if (strcmp(val, "3") == 0 ||
4653 strcasecmp(val, "PSNonPoll") == 0) {
4654 /* Make sure test modes are disabled */
4655 wpa_command(get_station_ifname(), "P2P_SET ps 98");
4656 wpa_command(get_station_ifname(), "P2P_SET ps 96");
4657
4658 /* Enable default power save mode */
4659 if (wpa_command(get_station_ifname(),
4660 "P2P_SET ps 1") < 0)
4661 return -2;
4662 } else
4663 return -1;
4664 }
4665
4666 val = get_param(cmd, "NoAck");
4667 if (val) {
4668 switch (get_driver_type()) {
4669 case DRIVER_ATHEROS:
4670 ath_sta_set_noack(dut, intf, val);
4671 break;
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08004672#ifdef NL80211_SUPPORT
4673 case DRIVER_WCN:
4674 wcn_sta_set_noack(dut, intf, val);
4675 break;
4676#endif /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004677 default:
4678 send_resp(dut, conn, SIGMA_ERROR,
4679 "ErrorCode,Setting NoAck not supported");
4680 return 0;
4681 }
4682 }
4683
4684 val = get_param(cmd, "IgnoreChswitchProhibit");
4685 if (val) {
4686 /* TODO: Enabled/disabled */
4687 if (strcasecmp(val, "Enabled") == 0) {
4688 send_resp(dut, conn, SIGMA_ERROR,
4689 "ErrorCode,Enabling IgnoreChswitchProhibit "
4690 "not supported");
4691 return 0;
4692 }
4693 }
4694
4695 val = get_param(cmd, "TDLS");
4696 if (val) {
4697 if (strcasecmp(val, "Disabled") == 0) {
4698 if (wpa_command(intf, "SET tdls_disabled 1")) {
4699 send_resp(dut, conn, SIGMA_ERROR,
4700 "ErrorCode,Failed to disable TDLS");
4701 return 0;
4702 }
4703 } else if (strcasecmp(val, "Enabled") == 0) {
4704 if (wpa_command(intf, "SET tdls_disabled 0")) {
4705 send_resp(dut, conn, SIGMA_ERROR,
4706 "ErrorCode,Failed to enable TDLS");
4707 return 0;
4708 }
4709 } else {
4710 send_resp(dut, conn, SIGMA_ERROR,
4711 "ErrorCode,Unsupported TDLS value");
4712 return 0;
4713 }
4714 }
4715
4716 val = get_param(cmd, "TDLSmode");
4717 if (val) {
4718 if (strcasecmp(val, "Default") == 0) {
4719 wpa_command(intf, "SET tdls_testing 0");
4720 } else if (strcasecmp(val, "APProhibit") == 0) {
4721 if (wpa_command(intf, "SET tdls_testing 0x400")) {
4722 send_resp(dut, conn, SIGMA_ERROR,
4723 "ErrorCode,Failed to enable ignore "
4724 "APProhibit TDLS mode");
4725 return 0;
4726 }
4727 } else if (strcasecmp(val, "HiLoMac") == 0) {
4728 /* STA should respond with TDLS setup req for a TDLS
4729 * setup req */
4730 if (wpa_command(intf, "SET tdls_testing 0x80")) {
4731 send_resp(dut, conn, SIGMA_ERROR,
4732 "ErrorCode,Failed to enable HiLoMac "
4733 "TDLS mode");
4734 return 0;
4735 }
4736 } else if (strcasecmp(val, "WeakSecurity") == 0) {
4737 /*
4738 * Since all security modes are enabled by default when
4739 * Sigma control is used, there is no need to do
4740 * anything here.
4741 */
4742 } else if (strcasecmp(val, "ExistLink") == 0) {
4743 /*
4744 * Since we allow new TDLS Setup Request even if there
4745 * is an existing link, nothing needs to be done for
4746 * this.
4747 */
4748 } else {
4749 /* TODO:
4750 * ExistLink: STA should send TDLS setup req even if
4751 * direct link already exists
4752 */
4753 send_resp(dut, conn, SIGMA_ERROR,
4754 "ErrorCode,Unsupported TDLSmode value");
4755 return 0;
4756 }
4757 }
4758
4759 val = get_param(cmd, "FakePubKey");
4760 if (val && atoi(val) && wpa_command(intf, "SET wps_corrupt_pkhash 1")) {
4761 send_resp(dut, conn, SIGMA_ERROR,
4762 "ErrorCode,Failed to enable FakePubKey");
4763 return 0;
4764 }
4765
Amarnath Hullur Subramanyamae1042b2018-02-22 21:52:52 -08004766#ifdef NL80211_SUPPORT
4767 val = get_param(cmd, "FrgmntSupport");
4768 if (val) {
4769 if (strcasecmp(val, "Enable") == 0) {
4770 if (sta_set_he_fragmentation(dut, intf,
4771 HE_FRAG_LEVEL1)) {
4772 send_resp(dut, conn, SIGMA_ERROR,
4773 "ErrorCode,Failed to enable HE Fragmentation");
4774 return 0;
4775 }
4776 } else if (strcasecmp(val, "Disable") == 0) {
4777 if (sta_set_he_fragmentation(dut, intf,
4778 HE_FRAG_DISABLE)) {
4779 send_resp(dut, conn, SIGMA_ERROR,
4780 "ErrorCode,Failed to disable HE Fragmentation");
4781 return 0;
4782 }
4783 }
4784 }
4785#endif /* NL80211_SUPPORT */
4786
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004787 return 1;
4788}
4789
4790
4791static const char * ath_get_radio_name(const char *radio_name)
4792{
4793 if (radio_name == NULL)
4794 return "wifi0";
4795 if (strcmp(radio_name, "wifi1") == 0)
4796 return "wifi1";
4797 if (strcmp(radio_name, "wifi2") == 0)
4798 return "wifi2";
4799 return "wifi0";
4800}
4801
4802
4803static void ath_sta_set_txsp_stream(struct sigma_dut *dut, const char *intf,
4804 const char *val)
4805{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004806 unsigned int vht_mcsmap = 0;
4807 int txchainmask = 0;
4808 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
4809
4810 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
4811 if (dut->testbed_flag_txsp == 1) {
4812 vht_mcsmap = 0xfffc;
4813 dut->testbed_flag_txsp = 0;
4814 } else {
4815 vht_mcsmap = 0xfffe;
4816 }
4817 txchainmask = 1;
4818 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
4819 if (dut->testbed_flag_txsp == 1) {
4820 vht_mcsmap = 0xfff0;
4821 dut->testbed_flag_txsp = 0;
4822 } else {
4823 vht_mcsmap = 0xfffa;
4824 }
4825 txchainmask = 3;
4826 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
4827 if (dut->testbed_flag_txsp == 1) {
4828 vht_mcsmap = 0xffc0;
4829 dut->testbed_flag_txsp = 0;
4830 } else {
4831 vht_mcsmap = 0xffea;
4832 }
4833 txchainmask = 7;
4834 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
4835 if (dut->testbed_flag_txsp == 1) {
4836 vht_mcsmap = 0xff00;
4837 dut->testbed_flag_txsp = 0;
4838 } else {
4839 vht_mcsmap = 0xffaa;
4840 }
4841 txchainmask = 15;
4842 } else {
4843 if (dut->testbed_flag_txsp == 1) {
4844 vht_mcsmap = 0xffc0;
4845 dut->testbed_flag_txsp = 0;
4846 } else {
4847 vht_mcsmap = 0xffea;
4848 }
4849 }
4850
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004851 if (txchainmask)
4852 run_iwpriv(dut, basedev, "txchainmask %d", txchainmask);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004853
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004854 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004855}
4856
4857
4858static void ath_sta_set_rxsp_stream(struct sigma_dut *dut, const char *intf,
4859 const char *val)
4860{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004861 unsigned int vht_mcsmap = 0;
4862 int rxchainmask = 0;
4863 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
4864
4865 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
4866 if (dut->testbed_flag_rxsp == 1) {
4867 vht_mcsmap = 0xfffc;
4868 dut->testbed_flag_rxsp = 0;
4869 } else {
4870 vht_mcsmap = 0xfffe;
4871 }
4872 rxchainmask = 1;
4873 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
4874 if (dut->testbed_flag_rxsp == 1) {
4875 vht_mcsmap = 0xfff0;
4876 dut->testbed_flag_rxsp = 0;
4877 } else {
4878 vht_mcsmap = 0xfffa;
4879 }
4880 rxchainmask = 3;
4881 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
4882 if (dut->testbed_flag_rxsp == 1) {
4883 vht_mcsmap = 0xffc0;
4884 dut->testbed_flag_rxsp = 0;
4885 } else {
4886 vht_mcsmap = 0xffea;
4887 }
4888 rxchainmask = 7;
4889 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
4890 if (dut->testbed_flag_rxsp == 1) {
4891 vht_mcsmap = 0xff00;
4892 dut->testbed_flag_rxsp = 0;
4893 } else {
4894 vht_mcsmap = 0xffaa;
4895 }
4896 rxchainmask = 15;
4897 } else {
4898 if (dut->testbed_flag_rxsp == 1) {
4899 vht_mcsmap = 0xffc0;
4900 dut->testbed_flag_rxsp = 0;
4901 } else {
4902 vht_mcsmap = 0xffea;
4903 }
4904 }
4905
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004906 if (rxchainmask)
4907 run_iwpriv(dut, basedev, "rxchainmask %d", rxchainmask);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004908
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004909 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004910}
4911
4912
4913void ath_set_zero_crc(struct sigma_dut *dut, const char *val)
4914{
4915 if (strcasecmp(val, "enable") == 0) {
4916 if (system("athdiag --set --address=0x2a204 --and=0xbfffffff")
4917 != 0) {
4918 sigma_dut_print(dut, DUT_MSG_ERROR,
4919 "Disable BB_VHTSIGB_CRC_CALC failed");
4920 }
4921
4922 if (system("athdiag --set --address=0x2a204 --or=0x80000000")
4923 != 0) {
4924 sigma_dut_print(dut, DUT_MSG_ERROR,
4925 "Enable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
4926 }
4927 } else {
4928 if (system("athdiag --set --address=0x2a204 --and=0x7fffffff")
4929 != 0) {
4930 sigma_dut_print(dut, DUT_MSG_ERROR,
4931 "Disable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
4932 }
4933
4934 if (system("athdiag --set --address=0x2a204 --or=0x40000000")
4935 != 0) {
4936 sigma_dut_print(dut, DUT_MSG_ERROR,
4937 "Enable BB_VHTSIGB_CRC_CALC failed");
4938 }
4939 }
4940}
4941
4942
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08004943static int wcn_sta_set_width(struct sigma_dut *dut, const char *intf,
4944 const char *val)
4945{
4946 char buf[60];
4947
4948 if (strcmp(val, "20") == 0) {
4949 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 0", intf);
4950 dut->chwidth = 0;
4951 } else if (strcmp(val, "40") == 0) {
4952 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 1", intf);
4953 dut->chwidth = 1;
4954 } else if (strcmp(val, "80") == 0) {
4955 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 2", intf);
4956 dut->chwidth = 2;
Sunil Duttb1cccac2018-05-22 21:03:12 +05304957 } else if (strcasecmp(val, "Auto") == 0) {
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08004958 buf[0] = '\0';
4959 } else {
4960 sigma_dut_print(dut, DUT_MSG_ERROR, "WIDTH %s not supported",
4961 val);
4962 return -1;
4963 }
4964
4965 if (buf[0] != '\0' && system(buf) != 0) {
4966 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv chwidth failed");
4967 return -1;
4968 }
4969
4970 return 0;
4971}
4972
4973
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08004974static int nlvendor_sta_set_addba_reject(struct sigma_dut *dut,
4975 const char *intf, int addbareject)
4976{
4977#ifdef NL80211_SUPPORT
4978 struct nl_msg *msg;
4979 int ret = 0;
4980 struct nlattr *params;
4981 int ifindex;
4982
4983 ifindex = if_nametoindex(intf);
4984 if (ifindex == 0) {
4985 sigma_dut_print(dut, DUT_MSG_ERROR,
4986 "%s: Index for interface %s failed",
4987 __func__, intf);
4988 return -1;
4989 }
4990
4991 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4992 NL80211_CMD_VENDOR)) ||
4993 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4994 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4995 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4996 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4997 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4998 nla_put_u8(msg,
4999 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ACCEPT_ADDBA_REQ,
5000 !addbareject)) {
5001 sigma_dut_print(dut, DUT_MSG_ERROR,
5002 "%s: err in adding vendor_cmd and vendor_data",
5003 __func__);
5004 nlmsg_free(msg);
5005 return -1;
5006 }
5007 nla_nest_end(msg, params);
5008
5009 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5010 if (ret) {
5011 sigma_dut_print(dut, DUT_MSG_ERROR,
5012 "%s: err in send_and_recv_msgs, ret=%d",
5013 __func__, ret);
5014 }
5015 return ret;
5016#else /* NL80211_SUPPORT */
5017 sigma_dut_print(dut, DUT_MSG_ERROR,
5018 "ADDBA_REJECT cannot be set without NL80211_SUPPORT defined");
5019 return -1;
5020#endif /* NL80211_SUPPORT */
5021}
5022
5023
5024static int sta_set_addba_reject(struct sigma_dut *dut, const char *intf,
5025 int addbareject)
5026{
5027 int ret;
5028
5029 switch (get_driver_type()) {
5030 case DRIVER_WCN:
5031 ret = nlvendor_sta_set_addba_reject(dut, intf, addbareject);
5032 if (ret) {
5033 sigma_dut_print(dut, DUT_MSG_ERROR,
5034 "nlvendor_sta_set_addba_reject failed, ret:%d",
5035 ret);
5036 return ret;
5037 }
5038 break;
5039 default:
5040 sigma_dut_print(dut, DUT_MSG_ERROR,
5041 "errorCode,Unsupported ADDBA_REJECT with the current driver");
5042 ret = -1;
5043 break;
5044 }
5045
5046 return ret;
5047}
5048
5049
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08005050static int nlvendor_config_send_addba(struct sigma_dut *dut, const char *intf,
5051 int enable)
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005052{
5053#ifdef NL80211_SUPPORT
5054 struct nl_msg *msg;
5055 int ret = 0;
5056 struct nlattr *params;
5057 int ifindex;
5058
5059 ifindex = if_nametoindex(intf);
5060 if (ifindex == 0) {
5061 sigma_dut_print(dut, DUT_MSG_ERROR,
5062 "%s: Index for interface %s failed",
5063 __func__, intf);
5064 return -1;
5065 }
5066
5067 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
5068 NL80211_CMD_VENDOR)) ||
5069 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
5070 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
5071 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
5072 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
5073 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
5074 nla_put_u8(msg,
5075 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_SEND_ADDBA_REQ,
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08005076 enable)) {
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005077 sigma_dut_print(dut, DUT_MSG_ERROR,
5078 "%s: err in adding vendor_cmd and vendor_data",
5079 __func__);
5080 nlmsg_free(msg);
5081 return -1;
5082 }
5083 nla_nest_end(msg, params);
5084
5085 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5086 if (ret) {
5087 sigma_dut_print(dut, DUT_MSG_ERROR,
5088 "%s: err in send_and_recv_msgs, ret=%d",
5089 __func__, ret);
5090 }
5091 return ret;
5092#else /* NL80211_SUPPORT */
5093 sigma_dut_print(dut, DUT_MSG_ERROR,
5094 "Disable addba not possible without NL80211_SUPPORT defined");
5095 return -1;
5096#endif /* NL80211_SUPPORT */
5097}
5098
5099
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005100static int cmd_sta_set_wireless_common(const char *intf, struct sigma_dut *dut,
5101 struct sigma_conn *conn,
5102 struct sigma_cmd *cmd)
5103{
5104 const char *val;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005105 int ampdu = -1, addbareject = -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005106 char buf[30];
5107
5108 val = get_param(cmd, "40_INTOLERANT");
5109 if (val) {
5110 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
5111 /* TODO: iwpriv ht40intol through wpa_supplicant */
5112 send_resp(dut, conn, SIGMA_ERROR,
5113 "ErrorCode,40_INTOLERANT not supported");
5114 return 0;
5115 }
5116 }
5117
5118 val = get_param(cmd, "ADDBA_REJECT");
5119 if (val) {
5120 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
5121 /* reject any ADDBA with status "decline" */
5122 ampdu = 0;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005123 addbareject = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005124 } else {
5125 /* accept ADDBA */
5126 ampdu = 1;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005127 addbareject = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005128 }
5129 }
5130
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005131 if (addbareject >= 0 &&
5132 sta_set_addba_reject(dut, intf, addbareject) < 0) {
5133 send_resp(dut, conn, SIGMA_ERROR,
5134 "ErrorCode,set addba_reject failed");
5135 return 0;
5136 }
5137
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005138 val = get_param(cmd, "AMPDU");
5139 if (val) {
5140 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
5141 /* enable AMPDU Aggregation */
5142 if (ampdu == 0) {
5143 send_resp(dut, conn, SIGMA_ERROR,
5144 "ErrorCode,Mismatch in "
5145 "addba_reject/ampdu - "
5146 "not supported");
5147 return 0;
5148 }
5149 ampdu = 1;
5150 } else {
5151 /* disable AMPDU Aggregation */
5152 if (ampdu == 1) {
5153 send_resp(dut, conn, SIGMA_ERROR,
5154 "ErrorCode,Mismatch in "
5155 "addba_reject/ampdu - "
5156 "not supported");
5157 return 0;
5158 }
5159 ampdu = 0;
5160 }
5161 }
5162
5163 if (ampdu >= 0) {
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005164 int ret;
5165
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005166 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s A-MPDU aggregation",
5167 ampdu ? "Enabling" : "Disabling");
5168 snprintf(buf, sizeof(buf), "SET ampdu %d", ampdu);
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07005169 if (wpa_command(intf, buf) < 0 &&
5170 iwpriv_sta_set_ampdu(dut, intf, ampdu) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005171 send_resp(dut, conn, SIGMA_ERROR,
5172 "ErrorCode,set aggr failed");
5173 return 0;
5174 }
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005175
5176 if (ampdu == 0) {
5177 /* Disable sending of addba using nl vendor command */
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08005178 ret = nlvendor_config_send_addba(dut, intf, 0);
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005179 if (ret) {
5180 sigma_dut_print(dut, DUT_MSG_ERROR,
5181 "Failed to disable addba, ret:%d",
5182 ret);
5183 }
5184 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005185 }
5186
5187 val = get_param(cmd, "AMSDU");
5188 if (val) {
5189 switch (get_driver_type()) {
5190 case DRIVER_ATHEROS:
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08005191 case DRIVER_WCN:
5192 iwpriv_sta_set_amsdu(dut, intf, val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005193 break;
5194 default:
5195 if (strcmp(val, "1") == 0 ||
5196 strcasecmp(val, "Enable") == 0) {
5197 /* Enable AMSDU Aggregation */
5198 send_resp(dut, conn, SIGMA_ERROR,
5199 "ErrorCode,AMSDU aggregation not supported");
5200 return 0;
5201 }
5202 break;
5203 }
5204 }
5205
5206 val = get_param(cmd, "STBC_RX");
5207 if (val) {
5208 switch (get_driver_type()) {
5209 case DRIVER_ATHEROS:
5210 ath_sta_set_stbc(dut, intf, val);
5211 break;
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05305212 case DRIVER_WCN:
5213 wcn_sta_set_stbc(dut, intf, val);
5214 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005215 default:
5216 send_resp(dut, conn, SIGMA_ERROR,
5217 "ErrorCode,STBC_RX not supported");
5218 return 0;
5219 }
5220 }
5221
5222 val = get_param(cmd, "WIDTH");
5223 if (val) {
5224 switch (get_driver_type()) {
5225 case DRIVER_WCN:
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08005226 if (wcn_sta_set_width(dut, intf, val) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005227 send_resp(dut, conn, SIGMA_ERROR,
5228 "ErrorCode,Failed to set WIDTH");
5229 return 0;
5230 }
5231 break;
5232 case DRIVER_ATHEROS:
5233 if (ath_set_width(dut, conn, intf, val) < 0)
5234 return 0;
5235 break;
5236 default:
5237 sigma_dut_print(dut, DUT_MSG_ERROR,
5238 "Setting WIDTH not supported");
5239 break;
5240 }
5241 }
5242
5243 val = get_param(cmd, "SMPS");
5244 if (val) {
5245 /* TODO: Dynamic/0, Static/1, No Limit/2 */
5246 send_resp(dut, conn, SIGMA_ERROR,
5247 "ErrorCode,SMPS not supported");
5248 return 0;
5249 }
5250
5251 val = get_param(cmd, "TXSP_STREAM");
5252 if (val) {
5253 switch (get_driver_type()) {
5254 case DRIVER_WCN:
5255 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
5256 send_resp(dut, conn, SIGMA_ERROR,
5257 "ErrorCode,Failed to set TXSP_STREAM");
5258 return 0;
5259 }
5260 break;
5261 case DRIVER_ATHEROS:
5262 ath_sta_set_txsp_stream(dut, intf, val);
5263 break;
5264 default:
5265 sigma_dut_print(dut, DUT_MSG_ERROR,
5266 "Setting TXSP_STREAM not supported");
5267 break;
5268 }
5269 }
5270
5271 val = get_param(cmd, "RXSP_STREAM");
5272 if (val) {
5273 switch (get_driver_type()) {
5274 case DRIVER_WCN:
5275 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
5276 send_resp(dut, conn, SIGMA_ERROR,
5277 "ErrorCode,Failed to set RXSP_STREAM");
5278 return 0;
5279 }
5280 break;
5281 case DRIVER_ATHEROS:
5282 ath_sta_set_rxsp_stream(dut, intf, val);
5283 break;
5284 default:
5285 sigma_dut_print(dut, DUT_MSG_ERROR,
5286 "Setting RXSP_STREAM not supported");
5287 break;
5288 }
5289 }
5290
5291 val = get_param(cmd, "DYN_BW_SGNL");
5292 if (val) {
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08005293 switch (get_driver_type()) {
5294 case DRIVER_WCN:
Peng Xuc59afd32016-11-21 15:01:11 -08005295 if (strcasecmp(val, "enable") == 0) {
5296 snprintf(buf, sizeof(buf),
5297 "iwpriv %s cwmenable 1", intf);
5298 if (system(buf) != 0) {
5299 sigma_dut_print(dut, DUT_MSG_ERROR,
5300 "iwpriv cwmenable 1 failed");
5301 return 0;
5302 }
5303 } else if (strcasecmp(val, "disable") == 0) {
5304 snprintf(buf, sizeof(buf),
5305 "iwpriv %s cwmenable 0", intf);
5306 if (system(buf) != 0) {
5307 sigma_dut_print(dut, DUT_MSG_ERROR,
5308 "iwpriv cwmenable 0 failed");
5309 return 0;
5310 }
5311 } else {
5312 sigma_dut_print(dut, DUT_MSG_ERROR,
5313 "Unsupported DYN_BW_SGL");
5314 }
5315
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005316 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 3", intf);
5317 if (system(buf) != 0) {
5318 sigma_dut_print(dut, DUT_MSG_ERROR,
5319 "Failed to set cts_cbw in DYN_BW_SGNL");
5320 return 0;
5321 }
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08005322 break;
5323 case DRIVER_ATHEROS:
priyadharshini gowthamane5e25172015-12-08 14:53:48 -08005324 novap_reset(dut, intf);
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08005325 ath_config_dyn_bw_sig(dut, intf, val);
5326 break;
5327 default:
5328 sigma_dut_print(dut, DUT_MSG_ERROR,
5329 "Failed to set DYN_BW_SGNL");
5330 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005331 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005332 }
5333
5334 val = get_param(cmd, "RTS_FORCE");
5335 if (val) {
priyadharshini gowthamane5e25172015-12-08 14:53:48 -08005336 novap_reset(dut, intf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005337 if (strcasecmp(val, "Enable") == 0) {
5338 snprintf(buf, sizeof(buf), "iwconfig %s rts 64", intf);
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02005339 if (system(buf) != 0) {
5340 sigma_dut_print(dut, DUT_MSG_ERROR,
5341 "Failed to set RTS_FORCE 64");
5342 }
priyadharshini gowthaman270870e2015-12-09 10:10:23 -08005343 snprintf(buf, sizeof(buf),
5344 "wifitool %s beeliner_fw_test 100 1", intf);
5345 if (system(buf) != 0) {
5346 sigma_dut_print(dut, DUT_MSG_ERROR,
5347 "wifitool beeliner_fw_test 100 1 failed");
5348 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005349 } else if (strcasecmp(val, "Disable") == 0) {
5350 snprintf(buf, sizeof(buf), "iwconfig %s rts 2347",
5351 intf);
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02005352 if (system(buf) != 0) {
5353 sigma_dut_print(dut, DUT_MSG_ERROR,
5354 "Failed to set RTS_FORCE 2347");
5355 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005356 } else {
5357 send_resp(dut, conn, SIGMA_ERROR,
5358 "ErrorCode,RTS_FORCE value not supported");
5359 return 0;
5360 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005361 }
5362
5363 val = get_param(cmd, "CTS_WIDTH");
5364 if (val) {
5365 switch (get_driver_type()) {
5366 case DRIVER_WCN:
5367 if (wcn_sta_set_cts_width(dut, intf, val) < 0) {
5368 send_resp(dut, conn, SIGMA_ERROR,
5369 "ErrorCode,Failed to set CTS_WIDTH");
5370 return 0;
5371 }
5372 break;
5373 case DRIVER_ATHEROS:
5374 ath_set_cts_width(dut, intf, val);
5375 break;
5376 default:
5377 sigma_dut_print(dut, DUT_MSG_ERROR,
5378 "Setting CTS_WIDTH not supported");
5379 break;
5380 }
5381 }
5382
5383 val = get_param(cmd, "BW_SGNL");
5384 if (val) {
5385 if (strcasecmp(val, "Enable") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005386 run_iwpriv(dut, intf, "cwmenable 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005387 } else if (strcasecmp(val, "Disable") == 0) {
5388 /* TODO: Disable */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005389 } else {
5390 send_resp(dut, conn, SIGMA_ERROR,
5391 "ErrorCode,BW_SGNL value not supported");
5392 return 0;
5393 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005394 }
5395
5396 val = get_param(cmd, "Band");
5397 if (val) {
5398 if (strcmp(val, "2.4") == 0 || strcmp(val, "5") == 0) {
5399 /* STA supports all bands by default */
5400 } else {
5401 send_resp(dut, conn, SIGMA_ERROR,
5402 "ErrorCode,Unsupported Band");
5403 return 0;
5404 }
5405 }
5406
5407 val = get_param(cmd, "zero_crc");
5408 if (val) {
5409 switch (get_driver_type()) {
5410 case DRIVER_ATHEROS:
5411 ath_set_zero_crc(dut, val);
5412 break;
5413 default:
5414 break;
5415 }
5416 }
5417
5418 return 1;
5419}
5420
5421
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02005422static int sta_set_force_mcs(struct sigma_dut *dut, int force, int mcs)
5423{
5424 switch (get_driver_type()) {
5425#ifdef __linux__
5426 case DRIVER_WIL6210:
5427 return wil6210_set_force_mcs(dut, force, mcs);
5428#endif /* __linux__ */
5429 default:
5430 sigma_dut_print(dut, DUT_MSG_ERROR,
5431 "Unsupported sta_set_force_mcs with the current driver");
5432 return -1;
5433 }
5434}
5435
5436
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02005437static int sta_60g_force_rsn_ie(struct sigma_dut *dut, int state)
5438{
5439 switch (get_driver_type()) {
5440#ifdef __linux__
5441 case DRIVER_WIL6210:
5442 return wil6210_force_rsn_ie(dut, state);
5443#endif /* __linux__ */
5444 default:
5445 sigma_dut_print(dut, DUT_MSG_ERROR,
5446 "Unsupported sta_60g_force_rsn_ie with the current driver");
5447 return -1;
5448 }
5449}
5450
5451
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005452static int sta_set_60g_common(struct sigma_dut *dut, struct sigma_conn *conn,
5453 struct sigma_cmd *cmd)
5454{
5455 const char *val;
5456 char buf[100];
5457
5458 val = get_param(cmd, "MSDUSize");
5459 if (val) {
5460 int mtu;
5461
5462 dut->amsdu_size = atoi(val);
5463 if (dut->amsdu_size > IEEE80211_MAX_DATA_LEN_DMG ||
5464 dut->amsdu_size < IEEE80211_SNAP_LEN_DMG) {
5465 sigma_dut_print(dut, DUT_MSG_ERROR,
5466 "MSDUSize %d is above max %d or below min %d",
5467 dut->amsdu_size,
5468 IEEE80211_MAX_DATA_LEN_DMG,
5469 IEEE80211_SNAP_LEN_DMG);
5470 dut->amsdu_size = 0;
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005471 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005472 }
5473
5474 mtu = dut->amsdu_size - IEEE80211_SNAP_LEN_DMG;
5475 sigma_dut_print(dut, DUT_MSG_DEBUG,
5476 "Setting amsdu_size to %d", mtu);
5477 snprintf(buf, sizeof(buf), "ifconfig %s mtu %d",
5478 get_station_ifname(), mtu);
5479
5480 if (system(buf) != 0) {
5481 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
5482 buf);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005483 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005484 }
5485 }
5486
5487 val = get_param(cmd, "BAckRcvBuf");
5488 if (val) {
5489 dut->back_rcv_buf = atoi(val);
5490 if (dut->back_rcv_buf == 0) {
5491 sigma_dut_print(dut, DUT_MSG_ERROR,
5492 "Failed to convert %s or value is 0",
5493 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005494 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005495 }
5496
5497 sigma_dut_print(dut, DUT_MSG_DEBUG,
5498 "Setting BAckRcvBuf to %s", val);
5499 }
5500
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02005501 val = get_param(cmd, "MCS_FixedRate");
5502 if (val) {
5503 if (sta_set_force_mcs(dut, 1, atoi(val))) {
5504 sigma_dut_print(dut, DUT_MSG_ERROR,
5505 "Failed to force MCS");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005506 return ERROR_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02005507 }
5508 }
5509
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005510 return SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005511}
5512
5513
5514static int sta_pcp_start(struct sigma_dut *dut, struct sigma_conn *conn,
5515 struct sigma_cmd *cmd)
5516{
5517 int net_id;
5518 char *ifname;
5519 const char *val;
5520 char buf[100];
5521
5522 dut->mode = SIGMA_MODE_STATION;
5523 ifname = get_main_ifname();
5524 if (wpa_command(ifname, "PING") != 0) {
5525 sigma_dut_print(dut, DUT_MSG_ERROR, "Supplicant not running");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005526 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005527 }
5528
5529 wpa_command(ifname, "FLUSH");
5530 net_id = add_network_common(dut, conn, ifname, cmd);
5531 if (net_id < 0) {
5532 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add network");
5533 return net_id;
5534 }
5535
5536 /* TODO: mode=2 for the AP; in the future, replace for mode PCP */
5537 if (set_network(ifname, net_id, "mode", "2") < 0) {
5538 sigma_dut_print(dut, DUT_MSG_ERROR,
5539 "Failed to set supplicant network mode");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005540 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005541 }
5542
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02005543 if (set_network(ifname, net_id, "pbss", "1") < 0)
5544 return -2;
5545
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005546 sigma_dut_print(dut, DUT_MSG_DEBUG,
Alexei Avshalom Lazarfd9f1352018-11-13 14:07:58 +02005547 "Supplicant set network with mode 2. network_id %d",
5548 net_id);
5549
5550 if (set_network(ifname, net_id, "wps_disabled", "0") < 0) {
5551 sigma_dut_print(dut, DUT_MSG_INFO,
5552 "Failed to set supplicant to WPS ENABLE");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005553 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarfd9f1352018-11-13 14:07:58 +02005554 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005555
5556 val = get_param(cmd, "Security");
5557 if (val && strcasecmp(val, "OPEN") == 0) {
5558 dut->ap_key_mgmt = AP_OPEN;
5559 if (set_network(ifname, net_id, "key_mgmt", "NONE") < 0) {
5560 sigma_dut_print(dut, DUT_MSG_ERROR,
5561 "Failed to set supplicant to %s security",
5562 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005563 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005564 }
5565 } else if (val && strcasecmp(val, "WPA2-PSK") == 0) {
5566 dut->ap_key_mgmt = AP_WPA2_PSK;
5567 if (set_network(ifname, net_id, "key_mgmt", "WPA-PSK") < 0) {
5568 sigma_dut_print(dut, DUT_MSG_ERROR,
5569 "Failed to set supplicant to %s security",
5570 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005571 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005572 }
5573
5574 if (set_network(ifname, net_id, "proto", "RSN") < 0) {
5575 sigma_dut_print(dut, DUT_MSG_ERROR,
5576 "Failed to set supplicant to proto RSN");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005577 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005578 }
5579 } else if (val) {
5580 sigma_dut_print(dut, DUT_MSG_ERROR,
5581 "Requested Security %s is not supported on 60GHz",
5582 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005583 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005584 }
5585
5586 val = get_param(cmd, "Encrypt");
5587 if (val && strcasecmp(val, "AES-GCMP") == 0) {
5588 if (set_network(ifname, net_id, "pairwise", "GCMP") < 0) {
5589 sigma_dut_print(dut, DUT_MSG_ERROR,
5590 "Failed to set supplicant to pairwise GCMP");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005591 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005592 }
5593 if (set_network(ifname, net_id, "group", "GCMP") < 0) {
5594 sigma_dut_print(dut, DUT_MSG_ERROR,
5595 "Failed to set supplicant to group GCMP");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005596 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005597 }
5598 } else if (val) {
5599 sigma_dut_print(dut, DUT_MSG_ERROR,
5600 "Requested Encrypt %s is not supported on 60 GHz",
5601 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005602 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005603 }
5604
5605 val = get_param(cmd, "PSK");
5606 if (val && set_network_quoted(ifname, net_id, "psk", val) < 0) {
5607 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set psk %s",
5608 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005609 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005610 }
5611
5612 /* Convert 60G channel to freq */
5613 switch (dut->ap_channel) {
5614 case 1:
5615 val = "58320";
5616 break;
5617 case 2:
5618 val = "60480";
5619 break;
5620 case 3:
5621 val = "62640";
5622 break;
5623 default:
5624 sigma_dut_print(dut, DUT_MSG_ERROR,
5625 "Failed to configure channel %d. Not supported",
5626 dut->ap_channel);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005627 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005628 }
5629
5630 if (set_network(ifname, net_id, "frequency", val) < 0) {
5631 sigma_dut_print(dut, DUT_MSG_ERROR,
5632 "Failed to set supplicant network frequency");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005633 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005634 }
5635
Alexei Avshalom Lazar2eccf4d2019-01-31 10:03:59 +02005636 if (dut->eap_fragment) {
5637 sigma_dut_print(dut, DUT_MSG_DEBUG,
5638 "Set EAP fragment size to 128 bytes.");
5639 if (set_network(ifname, net_id, "fragment_size", "128") < 0)
5640 return ERROR_SEND_STATUS;
5641 }
5642
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005643 sigma_dut_print(dut, DUT_MSG_DEBUG,
5644 "Supplicant set network with frequency");
5645
5646 snprintf(buf, sizeof(buf), "SELECT_NETWORK %d", net_id);
5647 if (wpa_command(ifname, buf) < 0) {
5648 sigma_dut_print(dut, DUT_MSG_INFO,
5649 "Failed to select network id %d on %s",
5650 net_id, ifname);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005651 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005652 }
5653
5654 sigma_dut_print(dut, DUT_MSG_DEBUG, "Selected network");
5655
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005656 return SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005657}
5658
5659
Lior David67543f52017-01-03 19:04:22 +02005660static int wil6210_set_abft_len(struct sigma_dut *dut, int abft_len)
5661{
5662 char buf[128], fname[128];
5663 FILE *f;
5664
5665 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
5666 sigma_dut_print(dut, DUT_MSG_ERROR,
5667 "failed to get wil6210 debugfs dir");
5668 return -1;
5669 }
5670
5671 snprintf(fname, sizeof(fname), "%s/abft_len", buf);
5672 f = fopen(fname, "w");
5673 if (!f) {
5674 sigma_dut_print(dut, DUT_MSG_ERROR,
5675 "failed to open: %s", fname);
5676 return -1;
5677 }
5678
5679 fprintf(f, "%d\n", abft_len);
5680 fclose(f);
5681
5682 return 0;
5683}
5684
5685
Alexei Avshalom Lazar49498b82019-01-31 15:16:32 +02005686int sta_set_60g_abft_len(struct sigma_dut *dut, struct sigma_conn *conn,
5687 int abft_len)
Lior David67543f52017-01-03 19:04:22 +02005688{
5689 switch (get_driver_type()) {
5690 case DRIVER_WIL6210:
5691 return wil6210_set_abft_len(dut, abft_len);
5692 default:
5693 sigma_dut_print(dut, DUT_MSG_ERROR,
5694 "set abft_len not supported");
5695 return -1;
5696 }
5697}
5698
5699
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005700static int sta_set_60g_pcp(struct sigma_dut *dut, struct sigma_conn *conn,
5701 struct sigma_cmd *cmd)
5702{
5703 const char *val;
Lior David67543f52017-01-03 19:04:22 +02005704 unsigned int abft_len = 1; /* default is one slot */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005705
5706 if (dut->dev_role != DEVROLE_PCP) {
5707 send_resp(dut, conn, SIGMA_INVALID,
5708 "ErrorCode,Invalid DevRole");
5709 return 0;
5710 }
5711
5712 val = get_param(cmd, "SSID");
5713 if (val) {
5714 if (strlen(val) > sizeof(dut->ap_ssid) - 1) {
5715 send_resp(dut, conn, SIGMA_INVALID,
5716 "ErrorCode,Invalid SSID");
5717 return -1;
5718 }
5719
Peng Xub8fc5cc2017-05-10 17:27:28 -07005720 strlcpy(dut->ap_ssid, val, sizeof(dut->ap_ssid));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005721 }
5722
5723 val = get_param(cmd, "CHANNEL");
5724 if (val) {
5725 const char *pos;
5726
5727 dut->ap_channel = atoi(val);
5728 pos = strchr(val, ';');
5729 if (pos) {
5730 pos++;
5731 dut->ap_channel_1 = atoi(pos);
5732 }
5733 }
5734
5735 switch (dut->ap_channel) {
5736 case 1:
5737 case 2:
5738 case 3:
5739 break;
5740 default:
5741 sigma_dut_print(dut, DUT_MSG_ERROR,
5742 "Channel %d is not supported", dut->ap_channel);
5743 send_resp(dut, conn, SIGMA_ERROR,
5744 "Requested channel is not supported");
5745 return -1;
5746 }
5747
5748 val = get_param(cmd, "BCNINT");
5749 if (val)
5750 dut->ap_bcnint = atoi(val);
5751
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005752 val = get_param(cmd, "AllocType");
5753 if (val) {
5754 send_resp(dut, conn, SIGMA_ERROR,
5755 "ErrorCode,AllocType is not supported yet");
5756 return -1;
5757 }
5758
5759 val = get_param(cmd, "PercentBI");
5760 if (val) {
5761 send_resp(dut, conn, SIGMA_ERROR,
5762 "ErrorCode,PercentBI is not supported yet");
5763 return -1;
5764 }
5765
5766 val = get_param(cmd, "CBAPOnly");
5767 if (val) {
5768 send_resp(dut, conn, SIGMA_ERROR,
5769 "ErrorCode,CBAPOnly is not supported yet");
5770 return -1;
5771 }
5772
5773 val = get_param(cmd, "AMPDU");
5774 if (val) {
5775 if (strcasecmp(val, "Enable") == 0)
5776 dut->ap_ampdu = 1;
5777 else if (strcasecmp(val, "Disable") == 0)
5778 dut->ap_ampdu = 2;
5779 else {
5780 send_resp(dut, conn, SIGMA_ERROR,
5781 "ErrorCode,AMPDU value is not Enable nor Disabled");
5782 return -1;
5783 }
5784 }
5785
5786 val = get_param(cmd, "AMSDU");
5787 if (val) {
5788 if (strcasecmp(val, "Enable") == 0)
5789 dut->ap_amsdu = 1;
5790 else if (strcasecmp(val, "Disable") == 0)
5791 dut->ap_amsdu = 2;
5792 }
5793
5794 val = get_param(cmd, "NumMSDU");
5795 if (val) {
5796 send_resp(dut, conn, SIGMA_ERROR,
5797 "ErrorCode, NumMSDU is not supported yet");
5798 return -1;
5799 }
5800
5801 val = get_param(cmd, "ABFTLRang");
5802 if (val) {
5803 sigma_dut_print(dut, DUT_MSG_DEBUG,
Lior David67543f52017-01-03 19:04:22 +02005804 "ABFTLRang parameter %s", val);
5805 if (strcmp(val, "Gt1") == 0)
5806 abft_len = 2; /* 2 slots in this case */
5807 }
5808
5809 if (sta_set_60g_abft_len(dut, conn, abft_len)) {
5810 send_resp(dut, conn, SIGMA_ERROR,
5811 "ErrorCode, Can't set ABFT length");
5812 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005813 }
5814
5815 if (sta_pcp_start(dut, conn, cmd) < 0) {
5816 send_resp(dut, conn, SIGMA_ERROR,
5817 "ErrorCode, Can't start PCP role");
5818 return -1;
5819 }
5820
5821 return sta_set_60g_common(dut, conn, cmd);
5822}
5823
5824
5825static int sta_set_60g_sta(struct sigma_dut *dut, struct sigma_conn *conn,
5826 struct sigma_cmd *cmd)
5827{
5828 const char *val = get_param(cmd, "DiscoveryMode");
5829
5830 if (dut->dev_role != DEVROLE_STA) {
5831 send_resp(dut, conn, SIGMA_INVALID,
5832 "ErrorCode,Invalid DevRole");
5833 return 0;
5834 }
5835
5836 if (val) {
5837 sigma_dut_print(dut, DUT_MSG_DEBUG, "Discovery: %s", val);
5838 /* Ignore Discovery mode till Driver expose API. */
5839#if 0
5840 if (strcasecmp(val, "1") == 0) {
5841 send_resp(dut, conn, SIGMA_INVALID,
5842 "ErrorCode,DiscoveryMode 1 not supported");
5843 return 0;
5844 }
5845
5846 if (strcasecmp(val, "0") == 0) {
5847 /* OK */
5848 } else {
5849 send_resp(dut, conn, SIGMA_INVALID,
5850 "ErrorCode,DiscoveryMode not supported");
5851 return 0;
5852 }
5853#endif
5854 }
5855
5856 if (start_sta_mode(dut) != 0)
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005857 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005858 return sta_set_60g_common(dut, conn, cmd);
5859}
5860
5861
5862static int cmd_sta_disconnect(struct sigma_dut *dut, struct sigma_conn *conn,
5863 struct sigma_cmd *cmd)
5864{
5865 const char *intf = get_param(cmd, "Interface");
Jouni Malinened77e672018-01-10 16:45:13 +02005866 const char *val = get_param(cmd, "maintain_profile");
vamsi krishnad605c422017-09-20 14:56:31 +05305867
Jouni Malinened77e672018-01-10 16:45:13 +02005868 if (dut->program == PROGRAM_OCE ||
Amarnath Hullur Subramanyamebeda9e2018-01-31 03:21:48 -08005869 dut->program == PROGRAM_HE ||
Jouni Malinened77e672018-01-10 16:45:13 +02005870 (val && atoi(val) == 1)) {
vamsi krishnad605c422017-09-20 14:56:31 +05305871 wpa_command(intf, "DISCONNECT");
5872 return 1;
5873 }
5874
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005875 disconnect_station(dut);
5876 /* Try to ignore old scan results to avoid HS 2.0R2 test case failures
5877 * due to cached results. */
5878 wpa_command(intf, "SET ignore_old_scan_res 1");
5879 wpa_command(intf, "BSS_FLUSH");
5880 return 1;
5881}
5882
5883
5884static int cmd_sta_reassoc(struct sigma_dut *dut, struct sigma_conn *conn,
5885 struct sigma_cmd *cmd)
5886{
5887 const char *intf = get_param(cmd, "Interface");
5888 const char *bssid = get_param(cmd, "bssid");
5889 const char *val = get_param(cmd, "CHANNEL");
5890 struct wpa_ctrl *ctrl;
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05305891 char buf[1000];
Sunil Duttd30ce092018-01-11 23:56:29 +05305892 char result[32];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005893 int res;
5894 int chan = 0;
Ashwini Patil467efef2017-05-25 12:18:27 +05305895 int status = 0;
Sunil Duttd30ce092018-01-11 23:56:29 +05305896 int fastreassoc = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005897
5898 if (bssid == NULL) {
5899 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing bssid "
5900 "argument");
5901 return 0;
5902 }
5903
5904 if (val)
5905 chan = atoi(val);
5906
5907 if (wifi_chip_type != DRIVER_WCN && wifi_chip_type != DRIVER_AR6003) {
5908 /* The current network may be from sta_associate or
5909 * sta_hs2_associate
5910 */
5911 if (set_network(intf, dut->infra_network_id, "bssid", bssid) <
5912 0 ||
5913 set_network(intf, 0, "bssid", bssid) < 0)
5914 return -2;
5915 }
5916
5917 ctrl = open_wpa_mon(intf);
5918 if (ctrl == NULL) {
5919 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
5920 "wpa_supplicant monitor connection");
5921 return -1;
5922 }
5923
Sunil Duttd30ce092018-01-11 23:56:29 +05305924 if (get_wpa_status(get_station_ifname(), "wpa_state", result,
5925 sizeof(result)) < 0 ||
5926 strncmp(result, "COMPLETED", 9) != 0) {
5927 sigma_dut_print(dut, DUT_MSG_DEBUG,
5928 "sta_reassoc: Not connected");
5929 fastreassoc = 0;
5930 }
5931
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05305932 if (dut->rsne_override) {
5933#ifdef NL80211_SUPPORT
5934 if (get_driver_type() == DRIVER_WCN && dut->config_rsnie == 0) {
5935 sta_config_rsnie(dut, 1);
5936 dut->config_rsnie = 1;
5937 }
5938#endif /* NL80211_SUPPORT */
5939 snprintf(buf, sizeof(buf), "TEST_ASSOC_IE %s",
5940 dut->rsne_override);
5941 if (wpa_command(intf, buf) < 0) {
5942 send_resp(dut, conn, SIGMA_ERROR,
5943 "ErrorCode,Failed to set DEV_CONFIGURE_IE RSNE override");
5944 return 0;
5945 }
5946 }
5947
Sunil Duttd30ce092018-01-11 23:56:29 +05305948 if (wifi_chip_type == DRIVER_WCN && fastreassoc) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005949#ifdef ANDROID
Ashwini Patil4c8158f2017-05-25 12:49:21 +05305950 if (chan) {
5951 unsigned int freq;
5952
Alexei Avshalom Lazar093569f2018-11-13 14:08:17 +02005953 freq = channel_to_freq(dut, chan);
Ashwini Patil4c8158f2017-05-25 12:49:21 +05305954 if (!freq) {
5955 sigma_dut_print(dut, DUT_MSG_ERROR,
5956 "Invalid channel number provided: %d",
5957 chan);
5958 send_resp(dut, conn, SIGMA_INVALID,
5959 "ErrorCode,Invalid channel number");
5960 goto close_mon_conn;
5961 }
5962 res = snprintf(buf, sizeof(buf),
5963 "SCAN TYPE=ONLY freq=%d", freq);
5964 } else {
5965 res = snprintf(buf, sizeof(buf), "SCAN TYPE=ONLY");
5966 }
5967 if (res < 0 || res >= (int) sizeof(buf)) {
5968 send_resp(dut, conn, SIGMA_ERROR,
5969 "ErrorCode,snprintf failed");
5970 goto close_mon_conn;
5971 }
5972 if (wpa_command(intf, buf) < 0) {
5973 sigma_dut_print(dut, DUT_MSG_INFO,
5974 "Failed to start scan");
5975 send_resp(dut, conn, SIGMA_ERROR,
5976 "ErrorCode,scan failed");
5977 goto close_mon_conn;
5978 }
5979
5980 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
5981 buf, sizeof(buf));
5982 if (res < 0) {
5983 sigma_dut_print(dut, DUT_MSG_INFO,
5984 "Scan did not complete");
5985 send_resp(dut, conn, SIGMA_ERROR,
5986 "ErrorCode,scan did not complete");
5987 goto close_mon_conn;
5988 }
5989
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005990 if (set_network(intf, dut->infra_network_id, "bssid", "any")
5991 < 0) {
5992 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
5993 "bssid to any during FASTREASSOC");
Ashwini Patil467efef2017-05-25 12:18:27 +05305994 status = -2;
5995 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005996 }
5997 res = snprintf(buf, sizeof(buf), "DRIVER FASTREASSOC %s %d",
5998 bssid, chan);
5999 if (res > 0 && res < (int) sizeof(buf))
6000 res = wpa_command(intf, buf);
6001
6002 if (res < 0 || res >= (int) sizeof(buf)) {
6003 send_resp(dut, conn, SIGMA_ERROR,
6004 "errorCode,Failed to run DRIVER FASTREASSOC");
Ashwini Patil467efef2017-05-25 12:18:27 +05306005 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006006 }
6007#else /* ANDROID */
6008 sigma_dut_print(dut, DUT_MSG_DEBUG,
6009 "Reassoc using iwpriv - skip chan=%d info",
6010 chan);
6011 snprintf(buf, sizeof(buf), "iwpriv %s reassoc", intf);
6012 if (system(buf) != 0) {
6013 sigma_dut_print(dut, DUT_MSG_ERROR, "%s failed", buf);
Ashwini Patil467efef2017-05-25 12:18:27 +05306014 status = -2;
6015 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006016 }
6017#endif /* ANDROID */
6018 sigma_dut_print(dut, DUT_MSG_INFO,
6019 "sta_reassoc: Run %s successful", buf);
6020 } else if (wpa_command(intf, "REASSOCIATE")) {
6021 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
6022 "request reassociation");
Ashwini Patil467efef2017-05-25 12:18:27 +05306023 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006024 }
6025
6026 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
6027 buf, sizeof(buf));
Ashwini Patil467efef2017-05-25 12:18:27 +05306028 if (res < 0) {
6029 sigma_dut_print(dut, DUT_MSG_INFO, "Connection did not complete");
6030 status = -1;
6031 goto close_mon_conn;
6032 }
6033 status = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006034
Ashwini Patil467efef2017-05-25 12:18:27 +05306035close_mon_conn:
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006036 wpa_ctrl_detach(ctrl);
6037 wpa_ctrl_close(ctrl);
Ashwini Patil467efef2017-05-25 12:18:27 +05306038 return status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006039}
6040
6041
6042static void hs2_clear_credentials(const char *intf)
6043{
6044 wpa_command(intf, "REMOVE_CRED all");
6045}
6046
6047
Lior Davidcc88b562017-01-03 18:52:09 +02006048#ifdef __linux__
6049static int wil6210_get_aid(struct sigma_dut *dut, const char *bssid,
6050 unsigned int *aid)
6051{
Lior David0fe101e2017-03-09 16:09:50 +02006052 const char *pattern = "AID[ \t]+([0-9]+)";
Lior Davidcc88b562017-01-03 18:52:09 +02006053
Lior David0fe101e2017-03-09 16:09:50 +02006054 return wil6210_get_sta_info_field(dut, bssid, pattern, aid);
Lior Davidcc88b562017-01-03 18:52:09 +02006055}
6056#endif /* __linux__ */
6057
6058
6059static int sta_get_aid_60g(struct sigma_dut *dut, const char *bssid,
6060 unsigned int *aid)
6061{
6062 switch (get_driver_type()) {
6063#ifdef __linux__
6064 case DRIVER_WIL6210:
6065 return wil6210_get_aid(dut, bssid, aid);
6066#endif /* __linux__ */
6067 default:
6068 sigma_dut_print(dut, DUT_MSG_ERROR, "get AID not supported");
6069 return -1;
6070 }
6071}
6072
6073
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006074static int sta_get_parameter_60g(struct sigma_dut *dut, struct sigma_conn *conn,
6075 struct sigma_cmd *cmd)
6076{
6077 char buf[MAX_CMD_LEN];
6078 char bss_list[MAX_CMD_LEN];
6079 const char *parameter = get_param(cmd, "Parameter");
6080
6081 if (parameter == NULL)
6082 return -1;
6083
Lior Davidcc88b562017-01-03 18:52:09 +02006084 if (strcasecmp(parameter, "AID") == 0) {
6085 unsigned int aid = 0;
6086 char bssid[20];
6087
6088 if (get_wpa_status(get_station_ifname(), "bssid",
6089 bssid, sizeof(bssid)) < 0) {
6090 sigma_dut_print(dut, DUT_MSG_ERROR,
6091 "could not get bssid");
6092 return -2;
6093 }
6094
6095 if (sta_get_aid_60g(dut, bssid, &aid))
6096 return -2;
6097
6098 snprintf(buf, sizeof(buf), "aid,%d", aid);
6099 sigma_dut_print(dut, DUT_MSG_INFO, "%s", buf);
6100 send_resp(dut, conn, SIGMA_COMPLETE, buf);
6101 return 0;
6102 }
6103
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006104 if (strcasecmp(parameter, "DiscoveredDevList") == 0) {
6105 char *bss_line;
6106 char *bss_id = NULL;
6107 const char *ifname = get_param(cmd, "Interface");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05306108 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006109
6110 if (ifname == NULL) {
6111 sigma_dut_print(dut, DUT_MSG_INFO,
6112 "For get DiscoveredDevList need Interface name.");
6113 return -1;
6114 }
6115
6116 /*
6117 * Use "BSS RANGE=ALL MASK=0x2" which provides a list
6118 * of BSSIDs in "bssid=<BSSID>\n"
6119 */
6120 if (wpa_command_resp(ifname, "BSS RANGE=ALL MASK=0x2",
6121 bss_list,
6122 sizeof(bss_list)) < 0) {
6123 sigma_dut_print(dut, DUT_MSG_ERROR,
6124 "Failed to get bss list");
6125 return -1;
6126 }
6127
6128 sigma_dut_print(dut, DUT_MSG_DEBUG,
6129 "bss list for ifname:%s is:%s",
6130 ifname, bss_list);
6131
6132 snprintf(buf, sizeof(buf), "DeviceList");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05306133 bss_line = strtok_r(bss_list, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006134 while (bss_line) {
6135 if (sscanf(bss_line, "bssid=%ms", &bss_id) > 0 &&
6136 bss_id) {
6137 int len;
6138
6139 len = snprintf(buf + strlen(buf),
6140 sizeof(buf) - strlen(buf),
6141 ",%s", bss_id);
6142 free(bss_id);
6143 bss_id = NULL;
6144 if (len < 0) {
6145 sigma_dut_print(dut,
6146 DUT_MSG_ERROR,
6147 "Failed to read BSSID");
6148 send_resp(dut, conn, SIGMA_ERROR,
6149 "ErrorCode,Failed to read BSS ID");
6150 return 0;
6151 }
6152
6153 if ((size_t) len >= sizeof(buf) - strlen(buf)) {
6154 sigma_dut_print(dut,
6155 DUT_MSG_ERROR,
6156 "Response buf too small for list");
6157 send_resp(dut, conn,
6158 SIGMA_ERROR,
6159 "ErrorCode,Response buf too small for list");
6160 return 0;
6161 }
6162 }
6163
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05306164 bss_line = strtok_r(NULL, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006165 }
6166
6167 sigma_dut_print(dut, DUT_MSG_INFO, "DiscoveredDevList is %s",
6168 buf);
6169 send_resp(dut, conn, SIGMA_COMPLETE, buf);
6170 return 0;
6171 }
6172
6173 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
6174 return 0;
6175}
6176
6177
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07006178static int sta_get_parameter_he(struct sigma_dut *dut, struct sigma_conn *conn,
6179 struct sigma_cmd *cmd)
6180{
6181 char buf[MAX_CMD_LEN];
6182 const char *parameter = get_param(cmd, "Parameter");
6183
6184 if (!parameter)
6185 return -1;
6186
6187 if (strcasecmp(parameter, "RSSI") == 0) {
6188 char rssi[10];
6189
6190 if (get_wpa_signal_poll(dut, get_station_ifname(), "RSSI",
6191 rssi, sizeof(rssi)) < 0) {
6192 sigma_dut_print(dut, DUT_MSG_ERROR,
6193 "Could not get RSSI");
6194 return -2;
6195 }
6196
6197 snprintf(buf, sizeof(buf), "rssi,%s", rssi);
6198 sigma_dut_print(dut, DUT_MSG_INFO, "RSSI %s", buf);
6199 send_resp(dut, conn, SIGMA_COMPLETE, buf);
6200 return 0;
6201 }
6202
6203 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
6204 return 0;
6205}
6206
6207
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006208static int cmd_sta_get_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
6209 struct sigma_cmd *cmd)
6210{
6211 const char *program = get_param(cmd, "Program");
6212
6213 if (program == NULL)
6214 return -1;
6215
6216 if (strcasecmp(program, "P2PNFC") == 0)
6217 return p2p_cmd_sta_get_parameter(dut, conn, cmd);
6218
6219 if (strcasecmp(program, "60ghz") == 0)
6220 return sta_get_parameter_60g(dut, conn, cmd);
6221
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07006222 if (strcasecmp(program, "he") == 0)
6223 return sta_get_parameter_he(dut, conn, cmd);
6224
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006225#ifdef ANDROID_NAN
6226 if (strcasecmp(program, "NAN") == 0)
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07006227 return nan_cmd_sta_get_parameter(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006228#endif /* ANDROID_NAN */
6229
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07006230#ifdef MIRACAST
6231 if (strcasecmp(program, "WFD") == 0 ||
6232 strcasecmp(program, "DisplayR2") == 0)
6233 return miracast_cmd_sta_get_parameter(dut, conn, cmd);
6234#endif /* MIRACAST */
6235
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006236 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
6237 return 0;
6238}
6239
6240
6241static void sta_reset_default_ath(struct sigma_dut *dut, const char *intf,
6242 const char *type)
6243{
6244 char buf[100];
6245
6246 if (dut->program == PROGRAM_VHT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006247 run_iwpriv(dut, intf, "chwidth 2");
6248 run_iwpriv(dut, intf, "mode 11ACVHT80");
6249 run_iwpriv(dut, intf, "vhtmcs -1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006250 }
6251
6252 if (dut->program == PROGRAM_HT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006253 run_iwpriv(dut, intf, "chwidth 0");
6254 run_iwpriv(dut, intf, "mode 11naht40");
6255 run_iwpriv(dut, intf, "set11NRates 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006256 }
6257
6258 if (dut->program == PROGRAM_VHT || dut->program == PROGRAM_HT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006259 run_iwpriv(dut, intf, "powersave 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006260
6261 /* Reset CTS width */
6262 snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 54 0",
6263 intf);
6264 if (system(buf) != 0) {
6265 sigma_dut_print(dut, DUT_MSG_ERROR,
6266 "wifitool %s beeliner_fw_test 54 0 failed",
6267 intf);
6268 }
6269
6270 /* Enable Dynamic Bandwidth signalling by default */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006271 run_iwpriv(dut, intf, "cwmenable 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006272
6273 snprintf(buf, sizeof(buf), "iwconfig %s rts 2347", intf);
6274 if (system(buf) != 0) {
6275 sigma_dut_print(dut, DUT_MSG_ERROR,
6276 "iwpriv rts failed");
6277 }
6278 }
6279
6280 if (type && strcasecmp(type, "Testbed") == 0) {
6281 dut->testbed_flag_txsp = 1;
6282 dut->testbed_flag_rxsp = 1;
6283 /* STA has to set spatial stream to 2 per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006284 run_iwpriv(dut, intf, "vht_mcsmap 0xfff0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006285
6286 /* Disable LDPC per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006287 run_iwpriv(dut, intf, "ldpc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006288
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006289 run_iwpriv(dut, intf, "amsdu 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006290
6291 /* TODO: Disable STBC 2x1 transmit and receive */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006292 run_iwpriv(dut, intf, "tx_stbc 0");
6293 run_iwpriv(dut, intf, "rx_stbc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006294
6295 /* STA has to disable Short GI per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006296 run_iwpriv(dut, intf, "shortgi 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006297 }
6298
6299 if (type && strcasecmp(type, "DUT") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006300 run_iwpriv(dut, intf, "nss 3");
Arif Hussainac6c5112018-05-25 17:34:00 -07006301 dut->sta_nss = 3;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006302
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006303 run_iwpriv(dut, intf, "shortgi 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006304 }
6305}
6306
6307
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08006308#ifdef NL80211_SUPPORT
6309static int sta_set_he_mcs(struct sigma_dut *dut, const char *intf,
6310 enum he_mcs_config mcs)
6311{
6312 struct nl_msg *msg;
6313 int ret = 0;
6314 struct nlattr *params;
6315 int ifindex;
6316
6317 ifindex = if_nametoindex(intf);
6318 if (ifindex == 0) {
6319 sigma_dut_print(dut, DUT_MSG_ERROR,
6320 "%s: Index for interface %s failed",
6321 __func__, intf);
6322 return -1;
6323 }
6324
6325 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6326 NL80211_CMD_VENDOR)) ||
6327 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6328 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6329 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6330 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6331 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6332 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MCS,
6333 mcs)) {
6334 sigma_dut_print(dut, DUT_MSG_ERROR,
6335 "%s: err in adding vendor_cmd and vendor_data",
6336 __func__);
6337 nlmsg_free(msg);
6338 return -1;
6339 }
6340 nla_nest_end(msg, params);
6341
6342 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6343 if (ret) {
6344 sigma_dut_print(dut, DUT_MSG_ERROR,
6345 "%s: err in send_and_recv_msgs, ret=%d",
6346 __func__, ret);
6347 }
6348 return ret;
6349}
6350#endif /* NL80211_SUPPORT */
6351
6352
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07006353static int sta_set_action_tx_in_he_tb_ppdu(struct sigma_dut *dut,
6354 const char *intf, int enable)
6355{
6356#ifdef NL80211_SUPPORT
6357 struct nl_msg *msg;
6358 int ret = 0;
6359 struct nlattr *params;
6360 int ifindex;
6361
6362 ifindex = if_nametoindex(intf);
6363 if (ifindex == 0) {
6364 sigma_dut_print(dut, DUT_MSG_ERROR,
6365 "%s: Index for interface %s failed",
6366 __func__, intf);
6367 return -1;
6368 }
6369
6370 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6371 NL80211_CMD_VENDOR)) ||
6372 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6373 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6374 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6375 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6376 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6377 nla_put_u8(msg,
6378 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_ACTION_TX_TB_PPDU,
6379 enable)) {
6380 sigma_dut_print(dut, DUT_MSG_ERROR,
6381 "%s: err in adding vendor_cmd and vendor_data",
6382 __func__);
6383 nlmsg_free(msg);
6384 return -1;
6385 }
6386 nla_nest_end(msg, params);
6387
6388 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6389 if (ret) {
6390 sigma_dut_print(dut, DUT_MSG_ERROR,
6391 "%s: err in send_and_recv_msgs, ret=%d",
6392 __func__, ret);
6393 }
6394 return ret;
6395#else /* NL80211_SUPPORT */
6396 sigma_dut_print(dut, DUT_MSG_ERROR,
6397 "HE action Tx TB PPDU cannot be set without NL80211_SUPPORT defined");
6398 return -1;
6399#endif /* NL80211_SUPPORT */
6400}
6401
6402
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08006403static int sta_set_heconfig_and_wep_tkip(struct sigma_dut *dut,
6404 const char *intf, int enable)
6405{
6406#ifdef NL80211_SUPPORT
6407 struct nl_msg *msg;
6408 int ret = 0;
6409 struct nlattr *params;
6410 int ifindex;
6411
6412 ifindex = if_nametoindex(intf);
6413 if (ifindex == 0) {
6414 sigma_dut_print(dut, DUT_MSG_ERROR,
6415 "%s: Index for interface %s failed",
6416 __func__, intf);
6417 return -1;
6418 }
6419
6420 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6421 NL80211_CMD_VENDOR)) ||
6422 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6423 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6424 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6425 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6426 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6427 nla_put_u8(msg,
6428 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WEP_TKIP_IN_HE,
6429 enable)) {
6430 sigma_dut_print(dut, DUT_MSG_ERROR,
6431 "%s: err in adding vendor_cmd and vendor_data",
6432 __func__);
6433 nlmsg_free(msg);
6434 return -1;
6435 }
6436 nla_nest_end(msg, params);
6437
6438 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6439 if (ret) {
6440 sigma_dut_print(dut, DUT_MSG_ERROR,
6441 "%s: err in send_and_recv_msgs, ret=%d",
6442 __func__, ret);
6443 }
6444 return ret;
6445#else /* NL80211_SUPPORT */
6446 sigma_dut_print(dut, DUT_MSG_ERROR,
6447 "HE config enablement cannot be changed without NL80211_SUPPORT defined");
6448 return -1;
6449#endif /* NL80211_SUPPORT */
6450}
6451
6452
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08006453#ifdef NL80211_SUPPORT
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08006454
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08006455static int sta_set_he_testbed_def(struct sigma_dut *dut,
6456 const char *intf, int cfg)
6457{
6458 struct nl_msg *msg;
6459 int ret = 0;
6460 struct nlattr *params;
6461 int ifindex;
6462
6463 ifindex = if_nametoindex(intf);
6464 if (ifindex == 0) {
6465 sigma_dut_print(dut, DUT_MSG_ERROR,
6466 "%s: Index for interface %s failed",
6467 __func__, intf);
6468 return -1;
6469 }
6470
6471 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6472 NL80211_CMD_VENDOR)) ||
6473 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6474 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6475 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6476 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6477 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6478 nla_put_u8(msg,
6479 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_SET_HE_TESTBED_DEFAULTS,
6480 cfg)) {
6481 sigma_dut_print(dut, DUT_MSG_ERROR,
6482 "%s: err in adding vendor_cmd and vendor_data",
6483 __func__);
6484 nlmsg_free(msg);
6485 return -1;
6486 }
6487 nla_nest_end(msg, params);
6488
6489 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6490 if (ret) {
6491 sigma_dut_print(dut, DUT_MSG_ERROR,
6492 "%s: err in send_and_recv_msgs, ret=%d",
6493 __func__, ret);
6494 }
6495 return ret;
6496}
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08006497
6498
6499static int sta_set_2g_vht_supp(struct sigma_dut *dut, const char *intf, int cfg)
6500{
6501 struct nl_msg *msg;
6502 int ret = 0;
6503 struct nlattr *params;
6504 int ifindex;
6505
6506 ifindex = if_nametoindex(intf);
6507 if (ifindex == 0) {
6508 sigma_dut_print(dut, DUT_MSG_ERROR,
6509 "%s: Index for interface %s failed",
6510 __func__, intf);
6511 return -1;
6512 }
6513
6514 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6515 NL80211_CMD_VENDOR)) ||
6516 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6517 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6518 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6519 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6520 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6521 nla_put_u8(msg,
6522 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_2G_VHT,
6523 cfg)) {
6524 sigma_dut_print(dut, DUT_MSG_ERROR,
6525 "%s: err in adding vendor_cmd and vendor_data",
6526 __func__);
6527 nlmsg_free(msg);
6528 return -1;
6529 }
6530 nla_nest_end(msg, params);
6531
6532 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6533 if (ret) {
6534 sigma_dut_print(dut, DUT_MSG_ERROR,
6535 "%s: err in send_and_recv_msgs, ret=%d",
6536 __func__, ret);
6537 }
6538 return ret;
6539}
6540
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08006541#endif /* NL80211_SUPPORT */
6542
6543
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08006544static int sta_set_addba_buf_size(struct sigma_dut *dut,
6545 const char *intf, int bufsize)
6546{
6547#ifdef NL80211_SUPPORT
6548 struct nl_msg *msg;
6549 int ret = 0;
6550 struct nlattr *params;
6551 int ifindex;
6552
6553 ifindex = if_nametoindex(intf);
6554 if (ifindex == 0) {
6555 sigma_dut_print(dut, DUT_MSG_ERROR,
6556 "%s: Index for interface %s failed",
6557 __func__, intf);
6558 return -1;
6559 }
6560
6561 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6562 NL80211_CMD_VENDOR)) ||
6563 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6564 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6565 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6566 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6567 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
Kiran Kumar Lokere26e27582018-08-01 16:18:34 -07006568 nla_put_u16(msg,
6569 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE,
6570 bufsize)) {
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08006571 sigma_dut_print(dut, DUT_MSG_ERROR,
6572 "%s: err in adding vendor_cmd and vendor_data",
6573 __func__);
6574 nlmsg_free(msg);
6575 return -1;
6576 }
6577 nla_nest_end(msg, params);
6578
6579 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6580 if (ret) {
6581 sigma_dut_print(dut, DUT_MSG_ERROR,
6582 "%s: err in send_and_recv_msgs, ret=%d",
6583 __func__, ret);
6584 }
6585 return ret;
6586#else /* NL80211_SUPPORT */
6587 sigma_dut_print(dut, DUT_MSG_ERROR,
6588 "AddBA bufsize cannot be changed without NL80211_SUPPORT defined");
6589 return -1;
6590#endif /* NL80211_SUPPORT */
6591}
6592
6593
Arif Hussain8d5b27b2018-05-14 14:31:03 -07006594static int sta_set_tx_beamformee(struct sigma_dut *dut, const char *intf,
6595 int enable)
6596{
6597#ifdef NL80211_SUPPORT
6598 struct nl_msg *msg;
6599 int ret = 0;
6600 struct nlattr *params;
6601 int ifindex;
6602
6603 ifindex = if_nametoindex(intf);
6604 if (ifindex == 0) {
6605 sigma_dut_print(dut, DUT_MSG_ERROR,
6606 "%s: Index for interface %s failed",
6607 __func__, intf);
6608 return -1;
6609 }
6610
6611 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6612 NL80211_CMD_VENDOR)) ||
6613 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6614 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6615 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6616 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6617 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6618 nla_put_u8(msg,
6619 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_TX_BEAMFORMEE,
6620 enable)) {
6621 sigma_dut_print(dut, DUT_MSG_ERROR,
6622 "%s: err in adding vendor_cmd and vendor_data",
6623 __func__);
6624 nlmsg_free(msg);
6625 return -1;
6626 }
6627 nla_nest_end(msg, params);
6628
6629 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6630 if (ret) {
6631 sigma_dut_print(dut, DUT_MSG_ERROR,
6632 "%s: err in send_and_recv_msgs, ret=%d",
6633 __func__, ret);
6634 }
6635 return ret;
6636#else /* NL80211_SUPPORT */
6637 sigma_dut_print(dut, DUT_MSG_ERROR,
6638 "tx beamformee cannot be changed without NL80211_SUPPORT defined");
6639 return -1;
6640#endif /* NL80211_SUPPORT */
6641}
6642
6643
Arif Hussain9765f7d2018-07-03 08:28:26 -07006644static int sta_set_beamformee_sts(struct sigma_dut *dut, const char *intf,
6645 int val)
6646{
6647#ifdef NL80211_SUPPORT
6648 struct nl_msg *msg;
6649 int ret = 0;
6650 struct nlattr *params;
6651 int ifindex;
6652
6653 ifindex = if_nametoindex(intf);
6654 if (ifindex == 0) {
6655 sigma_dut_print(dut, DUT_MSG_ERROR,
6656 "%s: Index for interface %s failed, val:%d",
6657 __func__, intf, val);
6658 return -1;
6659 }
6660
6661 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6662 NL80211_CMD_VENDOR)) ||
6663 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6664 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6665 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6666 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6667 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6668 nla_put_u8(msg,
6669 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_BEAMFORMEE_NSTS,
6670 val)) {
6671 sigma_dut_print(dut, DUT_MSG_ERROR,
6672 "%s: err in adding vendor_cmd and vendor_data, val: %d",
6673 __func__, val);
6674 nlmsg_free(msg);
6675 return -1;
6676 }
6677 nla_nest_end(msg, params);
6678
6679 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6680 if (ret) {
6681 sigma_dut_print(dut, DUT_MSG_ERROR,
6682 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
6683 __func__, ret, val);
6684 }
6685 return ret;
6686#else /* NL80211_SUPPORT */
6687 sigma_dut_print(dut, DUT_MSG_ERROR,
6688 "beamformee sts cannot be changed without NL80211_SUPPORT defined");
6689 return -1;
6690#endif /* NL80211_SUPPORT */
6691}
6692
6693
Arif Hussain68d23f52018-07-11 13:39:08 -07006694#ifdef NL80211_SUPPORT
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07006695static int sta_set_mac_padding_duration(struct sigma_dut *dut, const char *intf,
6696 enum qca_wlan_he_mac_padding_dur val)
6697{
Arif Hussain68d23f52018-07-11 13:39:08 -07006698 struct nl_msg *msg;
6699 int ret = 0;
6700 struct nlattr *params;
6701 int ifindex;
6702
6703 ifindex = if_nametoindex(intf);
6704 if (ifindex == 0) {
6705 sigma_dut_print(dut, DUT_MSG_ERROR,
6706 "%s: Index for interface %s failed, val:%d",
6707 __func__, intf, val);
6708 return -1;
6709 }
6710
6711 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6712 NL80211_CMD_VENDOR)) ||
6713 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6714 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6715 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6716 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6717 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6718 nla_put_u8(msg,
6719 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MAC_PADDING_DUR,
6720 val)) {
6721 sigma_dut_print(dut, DUT_MSG_ERROR,
6722 "%s: err in adding vendor_cmd and vendor_data, val: %d",
6723 __func__, val);
6724 nlmsg_free(msg);
6725 return -1;
6726 }
6727 nla_nest_end(msg, params);
6728
6729 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6730 if (ret) {
6731 sigma_dut_print(dut, DUT_MSG_ERROR,
6732 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
6733 __func__, ret, val);
6734 }
6735 return ret;
Arif Hussain68d23f52018-07-11 13:39:08 -07006736}
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07006737#endif /* NL80211_SUPPORT */
Arif Hussain68d23f52018-07-11 13:39:08 -07006738
6739
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07006740static int sta_set_tx_su_ppdu_cfg(struct sigma_dut *dut, const char *intf,
6741 int val)
6742{
6743#ifdef NL80211_SUPPORT
6744 struct nl_msg *msg;
6745 int ret = 0;
6746 struct nlattr *params;
6747 int ifindex;
6748
6749 ifindex = if_nametoindex(intf);
6750 if (ifindex == 0) {
6751 sigma_dut_print(dut, DUT_MSG_ERROR,
6752 "%s: Index for interface %s failed, val:%d",
6753 __func__, intf, val);
6754 return -1;
6755 }
6756
6757 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6758 NL80211_CMD_VENDOR)) ||
6759 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6760 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6761 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6762 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6763 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6764 nla_put_u8(msg,
6765 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_SUPPDU,
6766 val)) {
6767 sigma_dut_print(dut, DUT_MSG_ERROR,
6768 "%s: err in adding vendor_cmd and vendor_data, val: %d",
6769 __func__, val);
6770 nlmsg_free(msg);
6771 return -1;
6772 }
6773 nla_nest_end(msg, params);
6774
6775 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6776 if (ret) {
6777 sigma_dut_print(dut, DUT_MSG_ERROR,
6778 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
6779 __func__, ret, val);
6780 }
6781 return ret;
6782#else /* NL80211_SUPPORT */
6783 sigma_dut_print(dut, DUT_MSG_ERROR,
6784 "Tx SU PPDU cannot be set without NL80211_SUPPORT defined");
6785 return -1;
6786#endif /* NL80211_SUPPORT */
6787}
6788
6789
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07006790#ifdef NL80211_SUPPORT
6791static int sta_set_he_om_ctrl_reset(struct sigma_dut *dut, const char *intf)
6792{
6793 struct nl_msg *msg;
6794 int ret = 0;
6795 struct nlattr *params;
6796 int ifindex;
6797
6798 ifindex = if_nametoindex(intf);
6799 if (ifindex == 0) {
6800 sigma_dut_print(dut, DUT_MSG_ERROR,
6801 "%s: Index for interface %s failed",
6802 __func__, intf);
6803 return -1;
6804 }
6805
6806 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6807 NL80211_CMD_VENDOR)) ||
6808 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6809 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6810 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6811 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6812 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6813 nla_put_flag(msg,
6814 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_CLEAR_HE_OM_CTRL_CONFIG)) {
6815 sigma_dut_print(dut, DUT_MSG_ERROR,
6816 "%s: err in adding vendor_cmd and vendor_data",
6817 __func__);
6818 nlmsg_free(msg);
6819 return -1;
6820 }
6821 nla_nest_end(msg, params);
6822
6823 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6824 if (ret) {
6825 sigma_dut_print(dut, DUT_MSG_ERROR,
6826 "%s: err in send_and_recv_msgs, ret=%d",
6827 __func__, ret);
6828 }
6829 return ret;
6830}
6831#endif /* NL80211_SUPPORT */
6832
6833
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07006834static int sta_set_mu_edca_override(struct sigma_dut *dut, const char *intf,
6835 int val)
6836{
6837#ifdef NL80211_SUPPORT
6838 struct nl_msg *msg;
6839 int ret = 0;
6840 struct nlattr *params;
6841 int ifindex;
6842
6843 ifindex = if_nametoindex(intf);
6844 if (ifindex == 0) {
6845 sigma_dut_print(dut, DUT_MSG_ERROR,
6846 "%s: Index for interface %s failed, val:%d",
6847 __func__, intf, val);
6848 return -1;
6849 }
6850
6851 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6852 NL80211_CMD_VENDOR)) ||
6853 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6854 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6855 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6856 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6857 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6858 nla_put_u8(msg,
6859 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_OVERRIDE_MU_EDCA,
6860 val)) {
6861 sigma_dut_print(dut, DUT_MSG_ERROR,
6862 "%s: err in adding vendor_cmd and vendor_data, val: %d",
6863 __func__, val);
6864 nlmsg_free(msg);
6865 return -1;
6866 }
6867 nla_nest_end(msg, params);
6868
6869 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6870 if (ret) {
6871 sigma_dut_print(dut, DUT_MSG_ERROR,
6872 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
6873 __func__, ret, val);
6874 }
6875 return ret;
6876#else /* NL80211_SUPPORT */
6877 sigma_dut_print(dut, DUT_MSG_ERROR,
6878 "MU EDCA override cannot be changed without NL80211_SUPPORT defined");
6879 return -1;
6880#endif /* NL80211_SUPPORT */
6881}
6882
6883
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07006884static int sta_set_om_ctrl_supp(struct sigma_dut *dut, const char *intf,
6885 int val)
6886{
6887#ifdef NL80211_SUPPORT
6888 struct nl_msg *msg;
6889 int ret = 0;
6890 struct nlattr *params;
6891 int ifindex;
6892
6893 ifindex = if_nametoindex(intf);
6894 if (ifindex == 0) {
6895 sigma_dut_print(dut, DUT_MSG_ERROR,
6896 "%s: Index for interface %s failed, val:%d",
6897 __func__, intf, val);
6898 return -1;
6899 }
6900
6901 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6902 NL80211_CMD_VENDOR)) ||
6903 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6904 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6905 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6906 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6907 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6908 nla_put_u8(msg,
6909 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OM_CTRL_SUPP,
6910 val)) {
6911 sigma_dut_print(dut, DUT_MSG_ERROR,
6912 "%s: err in adding vendor_cmd and vendor_data, val: %d",
6913 __func__, val);
6914 nlmsg_free(msg);
6915 return -1;
6916 }
6917 nla_nest_end(msg, params);
6918
6919 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6920 if (ret) {
6921 sigma_dut_print(dut, DUT_MSG_ERROR,
6922 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
6923 __func__, ret, val);
6924 }
6925 return ret;
6926#else /* NL80211_SUPPORT */
6927 sigma_dut_print(dut, DUT_MSG_ERROR,
6928 "HE OM ctrl cannot be changed without NL80211_SUPPORT defined");
6929 return -1;
6930#endif /* NL80211_SUPPORT */
6931}
6932
6933
Arif Hussain480d5f42019-03-12 14:40:42 -07006934static int sta_set_twt_req_support(struct sigma_dut *dut, const char *intf,
6935 int val)
6936{
6937#ifdef NL80211_SUPPORT
6938 struct nl_msg *msg;
6939 int ret;
6940 struct nlattr *params;
6941 int ifindex;
6942
6943 ifindex = if_nametoindex(intf);
6944 if (ifindex == 0) {
6945 sigma_dut_print(dut, DUT_MSG_ERROR,
6946 "%s: Index for interface %s failed, val:%d",
6947 __func__, intf, val);
6948 return -1;
6949 }
6950
6951 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6952 NL80211_CMD_VENDOR)) ||
6953 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6954 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6955 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6956 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6957 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6958 nla_put_u8(msg,
6959 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TWT_REQ_SUPPORT,
6960 val)) {
6961 sigma_dut_print(dut, DUT_MSG_ERROR,
6962 "%s: err in adding vendor_cmd and vendor_data, val: %d",
6963 __func__, val);
6964 nlmsg_free(msg);
6965 return -1;
6966 }
6967 nla_nest_end(msg, params);
6968
6969 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6970 if (ret) {
6971 sigma_dut_print(dut, DUT_MSG_ERROR,
6972 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
6973 __func__, ret, val);
6974 }
6975 return ret;
6976#else /* NL80211_SUPPORT */
6977 sigma_dut_print(dut, DUT_MSG_ERROR,
6978 "TWT Request cannot be changed without NL80211_SUPPORT defined");
6979 return -1;
6980#endif /* NL80211_SUPPORT */
6981}
6982
6983
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08006984static void sta_reset_default_wcn(struct sigma_dut *dut, const char *intf,
6985 const char *type)
6986{
6987 char buf[60];
6988
6989 if (dut->program == PROGRAM_HE) {
6990 /* resetting phymode to auto in case of HE program */
6991 snprintf(buf, sizeof(buf), "iwpriv %s setphymode 0", intf);
6992 if (system(buf) != 0) {
6993 sigma_dut_print(dut, DUT_MSG_ERROR,
6994 "iwpriv %s setphymode failed", intf);
6995 }
6996
Amarnath Hullur Subramanyam9cecb502018-04-25 13:26:30 -07006997 /* reset the rate to Auto rate */
6998 snprintf(buf, sizeof(buf), "iwpriv %s set_11ax_rate 0xff",
6999 intf);
7000 if (system(buf) != 0) {
7001 sigma_dut_print(dut, DUT_MSG_ERROR,
7002 "iwpriv %s set_11ax_rate 0xff failed",
7003 intf);
7004 }
7005
Kiran Kumar Lokere86cfe3a2018-06-01 11:55:15 -07007006 /* reset the LDPC setting */
7007 snprintf(buf, sizeof(buf), "iwpriv %s ldpc 1", intf);
7008 if (system(buf) != 0) {
7009 sigma_dut_print(dut, DUT_MSG_ERROR,
7010 "iwpriv %s ldpc 1 failed", intf);
7011 }
7012
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08007013 /* reset the power save setting */
7014 snprintf(buf, sizeof(buf), "iwpriv %s setPower 2", intf);
7015 if (system(buf) != 0) {
7016 sigma_dut_print(dut, DUT_MSG_ERROR,
7017 "iwpriv %s setPower 2 failed", intf);
7018 }
7019
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08007020 /* remove all network profiles */
7021 remove_wpa_networks(intf);
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08007022
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08007023 /* Configure ADDBA Req/Rsp buffer size to be 64 */
7024 sta_set_addba_buf_size(dut, intf, 64);
7025
Amarnath Hullur Subramanyam5f32d572018-03-02 00:02:33 -08007026#ifdef NL80211_SUPPORT
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08007027 /* Reset the device HE capabilities to its default supported
7028 * configuration. */
7029 sta_set_he_testbed_def(dut, intf, 0);
7030
Amarnath Hullur Subramanyam5f32d572018-03-02 00:02:33 -08007031 /* Disable noackpolicy for all AC */
7032 if (nlvendor_sta_set_noack(dut, intf, 0, QCA_WLAN_AC_ALL)) {
7033 sigma_dut_print(dut, DUT_MSG_ERROR,
7034 "Disable of noackpolicy for all AC failed");
7035 }
7036#endif /* NL80211_SUPPORT */
7037
Amarnath Hullur Subramanyamb1724a52018-03-07 14:31:46 -08007038 /* Enable WMM by default */
7039 if (wcn_sta_set_wmm(dut, intf, "on")) {
7040 sigma_dut_print(dut, DUT_MSG_ERROR,
7041 "Enable of WMM in sta_reset_default_wcn failed");
7042 }
7043
7044 /* Disable ADDBA_REJECT by default */
7045 if (nlvendor_sta_set_addba_reject(dut, intf, 0)) {
7046 sigma_dut_print(dut, DUT_MSG_ERROR,
7047 "Disable of addba_reject in sta_reset_default_wcn failed");
7048 }
7049
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08007050 /* Enable sending of ADDBA by default */
7051 if (nlvendor_config_send_addba(dut, intf, 1)) {
7052 sigma_dut_print(dut, DUT_MSG_ERROR,
7053 "Enable sending of ADDBA in sta_reset_default_wcn failed");
7054 }
7055
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08007056 /* Enable AMPDU by default */
7057 iwpriv_sta_set_ampdu(dut, intf, 1);
7058
Subhani Shaik8e7a3052018-04-24 14:03:00 -07007059#ifdef NL80211_SUPPORT
7060 if (sta_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_AUTO)) {
7061 sigma_dut_print(dut, DUT_MSG_ERROR,
7062 "Set LTF config to default in sta_reset_default_wcn failed");
7063 }
Arif Hussain9765f7d2018-07-03 08:28:26 -07007064
Kiran Kumar Lokerebad51122018-12-12 19:03:36 -08007065 /* set the beamformee NSTS(maximum number of
7066 * space-time streams) to default DUT config
7067 */
7068 if (sta_set_beamformee_sts(dut, intf, 7)) {
Arif Hussain9765f7d2018-07-03 08:28:26 -07007069 sigma_dut_print(dut, DUT_MSG_ERROR,
7070 "Failed to set BeamformeeSTS");
7071 }
Arif Hussain68d23f52018-07-11 13:39:08 -07007072
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07007073 if (sta_set_mac_padding_duration(
7074 dut, intf,
7075 QCA_WLAN_HE_NO_ADDITIONAL_PROCESS_TIME)) {
Arif Hussain68d23f52018-07-11 13:39:08 -07007076 sigma_dut_print(dut, DUT_MSG_ERROR,
7077 "Failed to set MAC padding duration");
7078 }
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07007079
7080 if (sta_set_mu_edca_override(dut, intf, 0)) {
7081 sigma_dut_print(dut, DUT_MSG_ERROR,
7082 "ErrorCode,Failed to set MU EDCA override disable");
7083 }
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07007084
7085 if (sta_set_om_ctrl_supp(dut, intf, 1)) {
7086 sigma_dut_print(dut, DUT_MSG_ERROR,
7087 "Failed to set OM ctrl supp");
7088 }
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07007089
7090 if (sta_set_tx_su_ppdu_cfg(dut, intf, 1)) {
7091 sigma_dut_print(dut, DUT_MSG_ERROR,
7092 "Failed to set Tx SU PPDU enable");
7093 }
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07007094
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07007095 if (sta_set_action_tx_in_he_tb_ppdu(dut, intf, 0)) {
7096 sigma_dut_print(dut, DUT_MSG_ERROR,
7097 "failed to send TB PPDU Tx cfg");
7098 }
7099
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07007100 if (sta_set_he_om_ctrl_reset(dut, intf)) {
7101 sigma_dut_print(dut, DUT_MSG_ERROR,
7102 "Failed to set OM ctrl reset");
7103 }
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08007104
7105 /* +HTC-HE support default on */
7106 if (sta_set_he_htc_supp(dut, intf, 1)) {
7107 sigma_dut_print(dut, DUT_MSG_ERROR,
7108 "Setting of +HTC-HE support failed");
7109 }
Subhani Shaik8e7a3052018-04-24 14:03:00 -07007110#endif /* NL80211_SUPPORT */
7111
Arif Hussain8d5b27b2018-05-14 14:31:03 -07007112 if (sta_set_tx_beamformee(dut, intf, 1)) {
7113 sigma_dut_print(dut, DUT_MSG_ERROR,
7114 "Set tx beamformee enable by default in sta_reset_default_wcn failed");
7115 }
7116
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08007117 /* Set nss to 1 and MCS 0-7 in case of testbed */
7118 if (type && strcasecmp(type, "Testbed") == 0) {
7119#ifdef NL80211_SUPPORT
7120 int ret;
7121#endif /* NL80211_SUPPORT */
7122
7123 snprintf(buf, sizeof(buf), "iwpriv %s nss 1", intf);
7124 if (system(buf) != 0) {
7125 sigma_dut_print(dut, DUT_MSG_ERROR,
7126 "iwpriv %s nss failed", intf);
7127 }
7128
7129#ifdef NL80211_SUPPORT
7130 ret = sta_set_he_mcs(dut, intf, HE_80_MCS0_7);
7131 if (ret) {
7132 sigma_dut_print(dut, DUT_MSG_ERROR,
7133 "Setting of MCS failed, ret:%d",
7134 ret);
7135 }
7136#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyamc67621d2018-02-04 23:18:01 -08007137
7138 /* Disable STBC as default */
7139 wcn_sta_set_stbc(dut, intf, "0");
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08007140
7141 /* Disable AMSDU as default */
7142 iwpriv_sta_set_amsdu(dut, intf, "0");
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08007143
7144#ifdef NL80211_SUPPORT
7145 /* HE fragmentation default off */
7146 if (sta_set_he_fragmentation(dut, intf,
7147 HE_FRAG_DISABLE)) {
7148 sigma_dut_print(dut, DUT_MSG_ERROR,
7149 "Setting of HE fragmentation failed");
7150 }
Kiran Kumar Lokerebad51122018-12-12 19:03:36 -08007151
7152 /* set the beamformee NSTS(maximum number of
7153 * space-time streams) to default testbed config
7154 */
7155 if (sta_set_beamformee_sts(dut, intf, 3)) {
7156 sigma_dut_print(dut, DUT_MSG_ERROR,
7157 "Failed to set BeamformeeSTS");
7158 }
7159
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08007160 /* +HTC-HE support default off */
7161 if (sta_set_he_htc_supp(dut, intf, 0)) {
7162 sigma_dut_print(dut, DUT_MSG_ERROR,
7163 "Setting of +HTC-HE support failed");
7164 }
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08007165
7166 /* Set device HE capabilities to testbed default
7167 * configuration. */
7168 if (sta_set_he_testbed_def(dut, intf, 1)) {
7169 sigma_dut_print(dut, DUT_MSG_DEBUG,
7170 "Failed to set HE defaults");
7171 }
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08007172
7173 /* Disable VHT support in 2.4 GHz for testbed */
7174 sta_set_2g_vht_supp(dut, intf, 0);
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08007175#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08007176
7177 /* Enable WEP/TKIP with HE capability in testbed */
7178 if (sta_set_heconfig_and_wep_tkip(dut, intf, 1)) {
7179 sigma_dut_print(dut, DUT_MSG_ERROR,
7180 "Enabling HE config with WEP/TKIP failed");
7181 }
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08007182 }
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08007183
7184 /* Defaults in case of DUT */
7185 if (type && strcasecmp(type, "DUT") == 0) {
Arif Hussaind48fcc72018-05-01 18:34:18 -07007186 /* Enable STBC by default */
7187 wcn_sta_set_stbc(dut, intf, "1");
7188
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08007189 /* set nss to 2 */
7190 snprintf(buf, sizeof(buf), "iwpriv %s nss 2", intf);
7191 if (system(buf) != 0) {
7192 sigma_dut_print(dut, DUT_MSG_ERROR,
7193 "iwpriv %s nss 2 failed", intf);
7194 }
Arif Hussainac6c5112018-05-25 17:34:00 -07007195 dut->sta_nss = 2;
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08007196
7197#ifdef NL80211_SUPPORT
Arif Hussainae239842018-05-01 18:20:05 -07007198 /* Set HE_MCS to 0-11 */
7199 if (sta_set_he_mcs(dut, intf, HE_80_MCS0_11)) {
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08007200 sigma_dut_print(dut, DUT_MSG_ERROR,
7201 "Setting of MCS failed");
7202 }
7203#endif /* NL80211_SUPPORT */
7204
7205 /* Disable WEP/TKIP with HE capability in DUT */
7206 if (sta_set_heconfig_and_wep_tkip(dut, intf, 0)) {
7207 sigma_dut_print(dut, DUT_MSG_ERROR,
7208 "Enabling HE config with WEP/TKIP failed");
7209 }
7210 }
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08007211 }
7212}
7213
7214
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007215static int cmd_sta_reset_default(struct sigma_dut *dut,
7216 struct sigma_conn *conn,
7217 struct sigma_cmd *cmd)
7218{
7219 int cmd_sta_p2p_reset(struct sigma_dut *dut, struct sigma_conn *conn,
7220 struct sigma_cmd *cmd);
7221 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007222 const char *band = get_param(cmd, "band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007223 const char *type;
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07007224 const char *program = get_param(cmd, "program");
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05307225 const char *dev_role = get_param(cmd, "DevRole");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007226
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07007227 if (!program)
7228 program = get_param(cmd, "prog");
7229 dut->program = sigma_program_to_enum(program);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007230 dut->device_type = STA_unknown;
7231 type = get_param(cmd, "type");
7232 if (type && strcasecmp(type, "Testbed") == 0)
7233 dut->device_type = STA_testbed;
7234 if (type && strcasecmp(type, "DUT") == 0)
7235 dut->device_type = STA_dut;
7236
7237 if (dut->program == PROGRAM_TDLS) {
7238 /* Clear TDLS testing mode */
7239 wpa_command(intf, "SET tdls_disabled 0");
7240 wpa_command(intf, "SET tdls_testing 0");
7241 dut->no_tpk_expiration = 0;
Pradeep Reddy POTTETI8ce2a232016-10-28 12:17:32 +05307242 if (get_driver_type() == DRIVER_WCN) {
7243 /* Enable the WCN driver in TDLS Explicit trigger mode
7244 */
7245 wpa_command(intf, "SET tdls_external_control 0");
7246 wpa_command(intf, "SET tdls_trigger_control 0");
7247 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007248 }
7249
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07007250#ifdef MIRACAST
7251 if (dut->program == PROGRAM_WFD ||
7252 dut->program == PROGRAM_DISPLAYR2)
7253 miracast_sta_reset_default(dut, conn, cmd);
7254#endif /* MIRACAST */
7255
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007256 switch (get_driver_type()) {
7257 case DRIVER_ATHEROS:
7258 sta_reset_default_ath(dut, intf, type);
7259 break;
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08007260 case DRIVER_WCN:
7261 sta_reset_default_wcn(dut, intf, type);
7262 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007263 default:
7264 break;
7265 }
7266
7267#ifdef ANDROID_NAN
7268 if (dut->program == PROGRAM_NAN)
7269 nan_cmd_sta_reset_default(dut, conn, cmd);
7270#endif /* ANDROID_NAN */
7271
Jouni Malinenba630452018-06-22 11:49:59 +03007272 if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007273 unlink("SP/wi-fi.org/pps.xml");
7274 if (system("rm -r SP/*") != 0) {
7275 }
7276 unlink("next-client-cert.pem");
7277 unlink("next-client-key.pem");
7278 }
7279
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007280 /* For WPS program of the 60 GHz band the band type needs to be saved */
7281 if (dut->program == PROGRAM_WPS) {
7282 if (band && strcasecmp(band, "60GHz") == 0) {
7283 dut->band = WPS_BAND_60G;
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02007284 /* For 60 GHz enable WPS for WPS TCs */
7285 dut->wps_disable = 0;
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007286 } else {
7287 dut->band = WPS_BAND_NON_60G;
7288 }
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02007289 } else if (dut->program == PROGRAM_60GHZ) {
7290 /* For 60 GHz MAC/PHY TCs WPS must be disabled */
7291 dut->wps_disable = 1;
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007292 }
7293
Alexei Avshalom Lazar157ba062018-12-23 16:15:26 +02007294 if (is_60g_sigma_dut(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007295 const char *dev_role = get_param(cmd, "DevRole");
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02007296 char buf[256];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007297
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02007298 sigma_dut_print(dut, DUT_MSG_INFO,
7299 "WPS 60 GHz program, wps_disable = %d",
7300 dut->wps_disable);
7301
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007302 if (!dev_role) {
7303 send_resp(dut, conn, SIGMA_ERROR,
7304 "errorCode,Missing DevRole argument");
7305 return 0;
7306 }
7307
7308 if (strcasecmp(dev_role, "STA") == 0)
7309 dut->dev_role = DEVROLE_STA;
7310 else if (strcasecmp(dev_role, "PCP") == 0)
7311 dut->dev_role = DEVROLE_PCP;
7312 else {
7313 send_resp(dut, conn, SIGMA_ERROR,
7314 "errorCode,Unknown DevRole");
7315 return 0;
7316 }
7317
7318 if (dut->device_type == STA_unknown) {
7319 sigma_dut_print(dut, DUT_MSG_ERROR,
7320 "Device type is not STA testbed or DUT");
7321 send_resp(dut, conn, SIGMA_ERROR,
7322 "errorCode,Unknown device type");
7323 return 0;
7324 }
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02007325
7326 sigma_dut_print(dut, DUT_MSG_DEBUG,
7327 "Setting msdu_size to MAX: 7912");
7328 snprintf(buf, sizeof(buf), "ifconfig %s mtu 7912",
7329 get_station_ifname());
7330
7331 if (system(buf) != 0) {
7332 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
7333 buf);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007334 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02007335 }
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02007336
7337 if (sta_set_force_mcs(dut, 0, 1)) {
7338 sigma_dut_print(dut, DUT_MSG_ERROR,
7339 "Failed to reset force MCS");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007340 return ERROR_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02007341 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007342 }
7343
7344 wpa_command(intf, "WPS_ER_STOP");
7345 wpa_command(intf, "FLUSH");
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05307346 wpa_command(intf, "ERP_FLUSH");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007347 wpa_command(intf, "SET radio_disabled 0");
7348
Alexei Avshalom Lazar744ae8a2019-01-31 17:26:46 +02007349 dut->wps_forced_version = 0;
7350
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007351 if (dut->wsc_fragment) {
7352 dut->wsc_fragment = 0;
7353 wpa_command(intf, "SET device_name Test client");
7354 wpa_command(intf, "SET manufacturer ");
7355 wpa_command(intf, "SET model_name ");
7356 wpa_command(intf, "SET model_number ");
7357 wpa_command(intf, "SET serial_number ");
7358 }
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02007359 if (is_60g_sigma_dut(dut) && dut->force_rsn_ie) {
7360 dut->force_rsn_ie = FORCE_RSN_IE_NONE;
7361 sta_60g_force_rsn_ie(dut, FORCE_RSN_IE_NONE);
7362 }
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007363
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007364 if (dut->tmp_mac_addr && dut->set_macaddr) {
7365 dut->tmp_mac_addr = 0;
7366 if (system(dut->set_macaddr) != 0) {
7367 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to clear "
7368 "temporary MAC address");
7369 }
7370 }
7371
7372 set_ps(intf, dut, 0);
7373
Jouni Malinenba630452018-06-22 11:49:59 +03007374 if (dut->program == PROGRAM_HS2 || dut->program == PROGRAM_HS2_R2 ||
7375 dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007376 wpa_command(intf, "SET interworking 1");
7377 wpa_command(intf, "SET hs20 1");
7378 }
7379
Deepak Dhamdhere0fe0e452017-12-18 14:52:09 -08007380 if (dut->program == PROGRAM_HS2_R2 ||
Jouni Malinenba630452018-06-22 11:49:59 +03007381 dut->program == PROGRAM_HS2_R3 ||
Deepak Dhamdhere0fe0e452017-12-18 14:52:09 -08007382 dut->program == PROGRAM_OCE) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007383 wpa_command(intf, "SET pmf 1");
7384 } else {
7385 wpa_command(intf, "SET pmf 0");
7386 }
7387
7388 hs2_clear_credentials(intf);
7389 wpa_command(intf, "SET hessid 00:00:00:00:00:00");
7390 wpa_command(intf, "SET access_network_type 15");
7391
7392 static_ip_file(0, NULL, NULL, NULL);
7393 kill_dhcp_client(dut, intf);
7394 clear_ip_addr(dut, intf);
7395
7396 dut->er_oper_performed = 0;
7397 dut->er_oper_bssid[0] = '\0';
7398
priyadharshini gowthamanad6cbba2016-10-04 10:39:58 -07007399 if (dut->program == PROGRAM_LOC) {
7400 /* Disable Interworking by default */
7401 wpa_command(get_station_ifname(), "SET interworking 0");
7402 }
7403
Ashwini Patil00402582017-04-13 12:29:39 +05307404 if (dut->program == PROGRAM_MBO) {
7405 free(dut->non_pref_ch_list);
7406 dut->non_pref_ch_list = NULL;
Ashwini Patil5acd7382017-04-13 15:55:04 +05307407 free(dut->btm_query_cand_list);
7408 dut->btm_query_cand_list = NULL;
Ashwini Patilc63161e2017-04-13 16:30:23 +05307409 wpa_command(intf, "SET reject_btm_req_reason 0");
Ashwini Patila75de5a2017-04-13 16:35:05 +05307410 wpa_command(intf, "SET ignore_assoc_disallow 0");
Ashwini Patild174f2c2017-04-13 16:49:46 +05307411 wpa_command(intf, "SET gas_address3 0");
Ashwini Patil9183fdb2017-04-13 16:58:25 +05307412 wpa_command(intf, "SET roaming 1");
Ankita Bajaj1d974552018-09-18 16:56:44 +05307413 wpa_command(intf, "SET interworking 1");
Ashwini Patil00402582017-04-13 12:29:39 +05307414 }
7415
Jouni Malinen3c367e82017-06-23 17:01:47 +03007416 free(dut->rsne_override);
7417 dut->rsne_override = NULL;
7418
Jouni Malinen68143132017-09-02 02:34:08 +03007419 free(dut->sae_commit_override);
7420 dut->sae_commit_override = NULL;
7421
Jouni Malinend86e5822017-08-29 03:55:32 +03007422 dut->dpp_conf_id = -1;
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02007423 free(dut->dpp_peer_uri);
7424 dut->dpp_peer_uri = NULL;
Jouni Malinen63d50412017-11-24 11:55:38 +02007425 dut->dpp_local_bootstrap = -1;
Jouni Malinen5011fb52017-12-05 21:00:15 +02007426 wpa_command(intf, "SET dpp_config_processing 2");
Jouni Malinend86e5822017-08-29 03:55:32 +03007427
Jouni Malinenfac9cad2017-10-10 18:35:55 +03007428 wpa_command(intf, "VENDOR_ELEM_REMOVE 13 *");
7429
vamsi krishnaa2799492017-12-05 14:28:01 +05307430 if (dut->program == PROGRAM_OCE) {
Ankita Bajaja2cb5672017-10-25 16:08:28 +05307431 wpa_command(intf, "SET oce 1");
vamsi krishnaa2799492017-12-05 14:28:01 +05307432 wpa_command(intf, "SET disable_fils 0");
Ankita Bajaj1bde7942018-01-09 19:15:01 +05307433 wpa_command(intf, "FILS_HLP_REQ_FLUSH");
7434 dut->fils_hlp = 0;
7435#ifdef ANDROID
7436 hlp_thread_cleanup(dut);
7437#endif /* ANDROID */
vamsi krishnaa2799492017-12-05 14:28:01 +05307438 }
Ankita Bajaja2cb5672017-10-25 16:08:28 +05307439
Jouni Malinen8179fee2019-03-28 03:19:47 +02007440 dut->akm_values = 0;
7441
Sunil Dutt076081f2018-02-05 19:45:50 +05307442#ifdef NL80211_SUPPORT
Sunil Dutt44595082018-02-12 19:41:45 +05307443 if (get_driver_type() == DRIVER_WCN &&
7444 dut->config_rsnie == 1) {
7445 dut->config_rsnie = 0;
7446 sta_config_rsnie(dut, 0);
Sunil Dutt076081f2018-02-05 19:45:50 +05307447 }
7448#endif /* NL80211_SUPPORT */
7449
Sunil Duttfebf8a82018-02-09 18:50:13 +05307450 if (dev_role && strcasecmp(dev_role, "STA-CFON") == 0) {
7451 dut->dev_role = DEVROLE_STA_CFON;
7452 return sta_cfon_reset_default(dut, conn, cmd);
7453 }
7454
Jouni Malinen439352d2018-09-13 03:42:23 +03007455 wpa_command(intf, "SET setband AUTO");
7456
Sunil Duttfebf8a82018-02-09 18:50:13 +05307457 if (dut->program != PROGRAM_VHT)
7458 return cmd_sta_p2p_reset(dut, conn, cmd);
7459
Priyadharshini Gowthamana7dfd492015-11-09 14:34:08 -08007460 return 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007461}
7462
7463
7464static int cmd_sta_get_events(struct sigma_dut *dut, struct sigma_conn *conn,
7465 struct sigma_cmd *cmd)
7466{
7467 const char *program = get_param(cmd, "Program");
7468
7469 if (program == NULL)
7470 return -1;
7471#ifdef ANDROID_NAN
7472 if (strcasecmp(program, "NAN") == 0)
7473 return nan_cmd_sta_get_events(dut, conn, cmd);
7474#endif /* ANDROID_NAN */
7475 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
7476 return 0;
7477}
7478
7479
Jouni Malinen82905202018-04-29 17:20:10 +03007480static int sta_exec_action_url(struct sigma_dut *dut, struct sigma_conn *conn,
7481 struct sigma_cmd *cmd)
7482{
7483 const char *url = get_param(cmd, "url");
7484 const char *method = get_param(cmd, "method");
7485 pid_t pid;
7486 int status;
7487
7488 if (!url || !method)
7489 return -1;
7490
7491 /* TODO: Add support for method,post */
7492 if (strcasecmp(method, "get") != 0) {
7493 send_resp(dut, conn, SIGMA_ERROR,
7494 "ErrorCode,Unsupported method");
7495 return 0;
7496 }
7497
7498 pid = fork();
7499 if (pid < 0) {
7500 perror("fork");
7501 return -1;
7502 }
7503
7504 if (pid == 0) {
7505 char * argv[5] = { "wget", "-O", "/dev/null",
7506 (char *) url, NULL };
7507
7508 execv("/usr/bin/wget", argv);
7509 perror("execv");
7510 exit(0);
7511 return -1;
7512 }
7513
7514 if (waitpid(pid, &status, 0) < 0) {
7515 perror("waitpid");
7516 return -1;
7517 }
7518
7519 if (WIFEXITED(status)) {
7520 const char *errmsg;
7521
7522 if (WEXITSTATUS(status) == 0)
7523 return 1;
7524 sigma_dut_print(dut, DUT_MSG_INFO, "wget exit status %d",
7525 WEXITSTATUS(status));
7526 switch (WEXITSTATUS(status)) {
7527 case 4:
7528 errmsg = "errmsg,Network failure";
7529 break;
7530 case 8:
7531 errmsg = "errmsg,Server issued an error response";
7532 break;
7533 default:
7534 errmsg = "errmsg,Unknown failure from wget";
7535 break;
7536 }
7537 send_resp(dut, conn, SIGMA_ERROR, errmsg);
7538 return 0;
7539 }
7540
7541 send_resp(dut, conn, SIGMA_ERROR, "errmsg,Unknown failure");
7542 return 0;
7543}
7544
7545
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007546static int cmd_sta_exec_action(struct sigma_dut *dut, struct sigma_conn *conn,
7547 struct sigma_cmd *cmd)
7548{
7549 const char *program = get_param(cmd, "Prog");
7550
Jouni Malinen82905202018-04-29 17:20:10 +03007551 if (program && !get_param(cmd, "interface"))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007552 return -1;
7553#ifdef ANDROID_NAN
Jouni Malinen82905202018-04-29 17:20:10 +03007554 if (program && strcasecmp(program, "NAN") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007555 return nan_cmd_sta_exec_action(dut, conn, cmd);
7556#endif /* ANDROID_NAN */
Jouni Malinen82905202018-04-29 17:20:10 +03007557
7558 if (program && strcasecmp(program, "Loc") == 0)
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07007559 return loc_cmd_sta_exec_action(dut, conn, cmd);
Jouni Malinen82905202018-04-29 17:20:10 +03007560
7561 if (get_param(cmd, "url"))
7562 return sta_exec_action_url(dut, conn, cmd);
7563
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007564 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
7565 return 0;
7566}
7567
7568
7569static int cmd_sta_set_11n(struct sigma_dut *dut, struct sigma_conn *conn,
7570 struct sigma_cmd *cmd)
7571{
7572 const char *intf = get_param(cmd, "Interface");
7573 const char *val, *mcs32, *rate;
7574
7575 val = get_param(cmd, "GREENFIELD");
7576 if (val) {
7577 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
7578 /* Enable GD */
7579 send_resp(dut, conn, SIGMA_ERROR,
7580 "ErrorCode,GF not supported");
7581 return 0;
7582 }
7583 }
7584
7585 val = get_param(cmd, "SGI20");
7586 if (val) {
7587 switch (get_driver_type()) {
7588 case DRIVER_ATHEROS:
7589 ath_sta_set_sgi(dut, intf, val);
7590 break;
7591 default:
7592 send_resp(dut, conn, SIGMA_ERROR,
7593 "ErrorCode,SGI20 not supported");
7594 return 0;
7595 }
7596 }
7597
7598 mcs32 = get_param(cmd, "MCS32"); /* HT Duplicate Mode Enable/Disable */
7599 rate = get_param(cmd, "MCS_FIXEDRATE"); /* Fixed MCS rate (0..31) */
7600 if (mcs32 && rate) {
7601 /* TODO */
7602 send_resp(dut, conn, SIGMA_ERROR,
7603 "ErrorCode,MCS32,MCS_FIXEDRATE not supported");
7604 return 0;
7605 } else if (mcs32 && !rate) {
7606 /* TODO */
7607 send_resp(dut, conn, SIGMA_ERROR,
7608 "ErrorCode,MCS32 not supported");
7609 return 0;
7610 } else if (!mcs32 && rate) {
7611 switch (get_driver_type()) {
7612 case DRIVER_ATHEROS:
priyadharshini gowthamane5e25172015-12-08 14:53:48 -08007613 novap_reset(dut, intf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007614 ath_sta_set_11nrates(dut, intf, rate);
7615 break;
7616 default:
7617 send_resp(dut, conn, SIGMA_ERROR,
7618 "ErrorCode,MCS32_FIXEDRATE not supported");
7619 return 0;
7620 }
7621 }
7622
7623 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
7624}
7625
7626
Arif Hussain7b47d2d2018-05-09 10:44:02 -07007627static void cmd_set_max_he_mcs(struct sigma_dut *dut, const char *intf,
7628 int mcs_config)
7629{
7630#ifdef NL80211_SUPPORT
7631 int ret;
7632
7633 switch (mcs_config) {
7634 case HE_80_MCS0_7:
7635 case HE_80_MCS0_9:
7636 case HE_80_MCS0_11:
7637 ret = sta_set_he_mcs(dut, intf, mcs_config);
7638 if (ret) {
7639 sigma_dut_print(dut, DUT_MSG_ERROR,
7640 "cmd_set_max_he_mcs: Setting of MCS:%d failed, ret:%d",
7641 mcs_config, ret);
7642 }
7643 break;
7644 default:
7645 sigma_dut_print(dut, DUT_MSG_ERROR,
7646 "cmd_set_max_he_mcs: Invalid mcs %d",
7647 mcs_config);
7648 break;
7649 }
7650#else /* NL80211_SUPPORT */
7651 sigma_dut_print(dut, DUT_MSG_ERROR,
7652 "max HE MCS cannot be changed without NL80211_SUPPORT defined");
7653#endif /* NL80211_SUPPORT */
7654}
7655
7656
Arif Hussain480d5f42019-03-12 14:40:42 -07007657static int sta_twt_request(struct sigma_dut *dut, struct sigma_conn *conn,
7658 struct sigma_cmd *cmd)
7659{
7660#ifdef NL80211_SUPPORT
7661 struct nlattr *params;
7662 struct nlattr *attr;
7663 struct nlattr *attr1;
7664 struct nl_msg *msg;
7665 int ifindex, ret;
7666 const char *val;
7667 const char *intf = get_param(cmd, "Interface");
7668 int wake_interval_exp = 10, nominal_min_wake_dur = 255,
7669 wake_interval_mantissa = 512;
7670 int flow_type = 0, twt_trigger = 0, target_wake_time = 0,
7671 protection = 0;
7672
7673 ifindex = if_nametoindex(intf);
7674 if (ifindex == 0) {
7675 sigma_dut_print(dut, DUT_MSG_ERROR,
7676 "%s: Index for interface %s failed",
7677 __func__, intf);
7678 return -1;
7679 }
7680
7681 val = get_param(cmd, "FlowType");
7682 if (val) {
7683 flow_type = atoi(val);
7684 if (flow_type != 0 && flow_type != 1) {
7685 sigma_dut_print(dut, DUT_MSG_ERROR,
7686 "TWT: Invalid FlowType %d", flow_type);
7687 return -1;
7688 }
7689 }
7690
7691 val = get_param(cmd, "TWT_Trigger");
7692 if (val) {
7693 twt_trigger = atoi(val);
7694 if (twt_trigger != 0 && twt_trigger != 1) {
7695 sigma_dut_print(dut, DUT_MSG_ERROR,
7696 "TWT: Invalid TWT_Trigger %d",
7697 twt_trigger);
7698 return -1;
7699 }
7700 }
7701
7702 val = get_param(cmd, "Protection");
7703 if (val) {
7704 protection = atoi(val);
7705 if (protection != 0 && protection != 1) {
7706 sigma_dut_print(dut, DUT_MSG_ERROR,
7707 "TWT: Invalid Protection %d",
7708 protection);
7709 return -1;
7710 }
7711 }
7712
7713 val = get_param(cmd, "TargetWakeTime");
7714 if (val)
7715 target_wake_time = atoi(val);
7716
7717 val = get_param(cmd, "WakeIntervalMantissa");
7718 if (val)
7719 wake_interval_mantissa = atoi(val);
7720
7721 val = get_param(cmd, "WakeIntervalExp");
7722 if (val)
7723 wake_interval_exp = atoi(val);
7724
7725 val = get_param(cmd, "NominalMinWakeDur");
7726 if (val)
7727 nominal_min_wake_dur = atoi(val);
7728
7729 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7730 NL80211_CMD_VENDOR)) ||
7731 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7732 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7733 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7734 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7735 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7736 !(params = nla_nest_start(
7737 msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_SETUP)) ||
7738 !(attr1 = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7739 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_EXP,
7740 wake_interval_exp) ||
7741 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST, 0) ||
7742 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_REQ_TYPE, 1) ||
7743 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TRIGGER,
7744 twt_trigger) ||
7745 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE,
7746 flow_type) ||
7747 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_PROTECTION,
7748 protection) ||
7749 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME,
7750 target_wake_time) ||
7751 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_DURATION,
7752 nominal_min_wake_dur) ||
7753 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_MANTISSA,
7754 wake_interval_mantissa)) {
7755 sigma_dut_print(dut, DUT_MSG_ERROR,
7756 "%s: err in adding vendor_cmd and vendor_data",
7757 __func__);
7758 nlmsg_free(msg);
7759 return -1;
7760 }
7761 nla_nest_end(msg, attr1);
7762 nla_nest_end(msg, params);
7763 nla_nest_end(msg, attr);
7764
7765 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7766 if (ret) {
7767 sigma_dut_print(dut, DUT_MSG_ERROR,
7768 "%s: err in send_and_recv_msgs, ret=%d",
7769 __func__, ret);
7770 }
7771
7772 return ret;
7773#else /* NL80211_SUPPORT */
7774 sigma_dut_print(dut, DUT_MSG_ERROR,
7775 "TWT request cannot be done without NL80211_SUPPORT defined");
7776 return -1;
7777#endif /* NL80211_SUPPORT */
7778}
7779
7780
7781static int sta_twt_teardown(struct sigma_dut *dut, struct sigma_conn *conn,
7782 struct sigma_cmd *cmd)
7783{
7784 #ifdef NL80211_SUPPORT
7785 struct nlattr *params;
7786 struct nlattr *attr;
7787 struct nlattr *attr1;
7788 int ifindex, ret;
7789 struct nl_msg *msg;
7790 const char *intf = get_param(cmd, "Interface");
7791
7792 ifindex = if_nametoindex(intf);
7793 if (ifindex == 0) {
7794 sigma_dut_print(dut, DUT_MSG_ERROR,
7795 "%s: Index for interface %s failed",
7796 __func__, intf);
7797 return -1;
7798 }
7799
7800 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7801 NL80211_CMD_VENDOR)) ||
7802 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7803 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7804 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7805 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7806 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7807 !(params = nla_nest_start(
7808 msg,
7809 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_TERMINATE)) ||
7810 !(attr1 = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7811 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE, 0)) {
7812 sigma_dut_print(dut, DUT_MSG_ERROR,
7813 "%s: err in adding vendor_cmd and vendor_data",
7814 __func__);
7815 nlmsg_free(msg);
7816 return -1;
7817 }
7818 nla_nest_end(msg, attr1);
7819 nla_nest_end(msg, params);
7820 nla_nest_end(msg, attr);
7821
7822 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7823 if (ret) {
7824 sigma_dut_print(dut, DUT_MSG_ERROR,
7825 "%s: err in send_and_recv_msgs, ret=%d",
7826 __func__, ret);
7827 }
7828
7829 return ret;
7830#else /* NL80211_SUPPORT */
7831 sigma_dut_print(dut, DUT_MSG_ERROR,
7832 "TWT teardown cannot be done without NL80211_SUPPORT defined");
7833 return -1;
7834#endif /* NL80211_SUPPORT */
7835}
7836
7837
Kiran Kumar Lokere50eb2cd2018-12-18 18:31:28 -08007838static int sta_transmit_omi(struct sigma_dut *dut, struct sigma_conn *conn,
7839 struct sigma_cmd *cmd)
7840{
7841#ifdef NL80211_SUPPORT
7842 struct nlattr *params;
7843 struct nlattr *attr;
7844 struct nlattr *attr1;
7845 struct nl_msg *msg;
7846 int ifindex, ret;
7847 const char *val;
7848 const char *intf = get_param(cmd, "Interface");
7849 uint8_t rx_nss = 0xFF, ch_bw = 0xFF, tx_nsts = 0xFF, ulmu_dis = 0,
7850 ulmu_data_dis = 0;
7851
7852 ifindex = if_nametoindex(intf);
7853 if (ifindex == 0) {
7854 sigma_dut_print(dut, DUT_MSG_ERROR,
7855 "%s: Index for interface %s failed",
7856 __func__, intf);
7857 return -1;
7858 }
7859 val = get_param(cmd, "OMCtrl_RxNSS");
7860 if (val)
7861 rx_nss = atoi(val);
7862
7863 val = get_param(cmd, "OMCtrl_ChnlWidth");
7864 if (val)
7865 ch_bw = atoi(val);
7866
7867 val = get_param(cmd, "OMCtrl_ULMUDisable");
7868 if (val)
7869 ulmu_dis = atoi(val);
7870
7871 val = get_param(cmd, "OMCtrl_TxNSTS");
7872 if (val)
7873 tx_nsts = atoi(val);
7874
7875 val = get_param(cmd, "OMCtrl_ULMUDataDisable");
7876 if (val)
7877 ulmu_data_dis = atoi(val);
7878
7879 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7880 NL80211_CMD_VENDOR)) ||
7881 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7882 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7883 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7884 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7885 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7886 !(params = nla_nest_start(
7887 msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OMI_TX)) ||
7888 !(attr1 = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7889 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_RX_NSS, rx_nss) ||
7890 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_CH_BW, ch_bw) ||
7891 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_TX_NSTS, tx_nsts) ||
7892 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DATA_DISABLE,
7893 ulmu_data_dis) ||
7894 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DISABLE,
7895 ulmu_dis)) {
7896 sigma_dut_print(dut, DUT_MSG_ERROR,
7897 "%s: err in adding vendor_cmd and vendor_data",
7898 __func__);
7899 nlmsg_free(msg);
7900 return -1;
7901 }
7902 nla_nest_end(msg, attr1);
7903 nla_nest_end(msg, params);
7904 nla_nest_end(msg, attr);
7905
7906 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7907 if (ret) {
7908 sigma_dut_print(dut, DUT_MSG_ERROR,
7909 "%s: err in send_and_recv_msgs, ret=%d",
7910 __func__, ret);
7911 }
7912
7913 return ret;
7914#else /* NL80211_SUPPORT */
7915 sigma_dut_print(dut, DUT_MSG_ERROR,
7916 "OMI TX cannot be processed without NL80211_SUPPORT defined");
7917 return -1;
7918#endif /* NL80211_SUPPORT */
7919}
7920
7921
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007922static int cmd_sta_set_wireless_vht(struct sigma_dut *dut,
7923 struct sigma_conn *conn,
7924 struct sigma_cmd *cmd)
7925{
7926 const char *intf = get_param(cmd, "Interface");
7927 const char *val;
Arif Hussaina37e9552018-06-20 17:05:59 -07007928 const char *program;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007929 int tkip = -1;
7930 int wep = -1;
7931
Arif Hussaina37e9552018-06-20 17:05:59 -07007932 program = get_param(cmd, "Program");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007933 val = get_param(cmd, "SGI80");
7934 if (val) {
7935 int sgi80;
7936
7937 sgi80 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07007938 run_iwpriv(dut, intf, "shortgi %d", sgi80);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007939 }
7940
7941 val = get_param(cmd, "TxBF");
7942 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07007943 switch (get_driver_type()) {
7944 case DRIVER_WCN:
7945 if (sta_set_tx_beamformee(dut, intf, 1)) {
7946 send_resp(dut, conn, SIGMA_ERROR,
7947 "ErrorCode,Failed to set TX beamformee enable");
7948 return 0;
7949 }
7950 break;
7951 case DRIVER_ATHEROS:
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07007952 if (run_iwpriv(dut, intf, "vhtsubfee 1") < 0) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07007953 send_resp(dut, conn, SIGMA_ERROR,
7954 "ErrorCode,Setting vhtsubfee failed");
7955 return 0;
7956 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07007957 if (run_iwpriv(dut, intf, "vhtsubfer 1") < 0) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07007958 send_resp(dut, conn, SIGMA_ERROR,
7959 "ErrorCode,Setting vhtsubfer failed");
7960 return 0;
7961 }
7962 break;
7963 default:
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007964 sigma_dut_print(dut, DUT_MSG_ERROR,
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07007965 "Unsupported driver type");
7966 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007967 }
7968 }
7969
7970 val = get_param(cmd, "MU_TxBF");
7971 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
7972 switch (get_driver_type()) {
7973 case DRIVER_ATHEROS:
7974 ath_sta_set_txsp_stream(dut, intf, "1SS");
7975 ath_sta_set_rxsp_stream(dut, intf, "1SS");
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07007976 run_iwpriv(dut, intf, "vhtmubfee 1");
7977 run_iwpriv(dut, intf, "vhtmubfer 1");
Sunil Duttae9e5d12018-06-29 11:50:47 +05307978 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007979 case DRIVER_WCN:
7980 if (wcn_sta_set_sp_stream(dut, intf, "1SS") < 0) {
7981 send_resp(dut, conn, SIGMA_ERROR,
7982 "ErrorCode,Failed to set RX/TXSP_STREAM");
7983 return 0;
7984 }
Sunil Duttae9e5d12018-06-29 11:50:47 +05307985 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007986 default:
7987 sigma_dut_print(dut, DUT_MSG_ERROR,
7988 "Setting SP_STREAM not supported");
7989 break;
7990 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007991 }
7992
7993 val = get_param(cmd, "LDPC");
7994 if (val) {
7995 int ldpc;
7996
7997 ldpc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07007998 run_iwpriv(dut, intf, "ldpc %d", ldpc);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007999 }
8000
Amarnath Hullur Subramanyam7bae60e2018-01-31 03:46:50 -08008001 val = get_param(cmd, "BCC");
8002 if (val) {
8003 int bcc;
8004
8005 bcc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
8006 /* use LDPC iwpriv itself to set bcc coding, bcc coding
8007 * is mutually exclusive to bcc */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008008 run_iwpriv(dut, intf, "ldpc %d", !bcc);
Amarnath Hullur Subramanyam7bae60e2018-01-31 03:46:50 -08008009 }
8010
Arif Hussain7b47d2d2018-05-09 10:44:02 -07008011 val = get_param(cmd, "MaxHE-MCS_1SS_RxMapLTE80");
8012 if (val && dut->sta_nss == 1)
8013 cmd_set_max_he_mcs(dut, intf, atoi(val));
8014
8015 val = get_param(cmd, "MaxHE-MCS_2SS_RxMapLTE80");
8016 if (val && dut->sta_nss == 2)
8017 cmd_set_max_he_mcs(dut, intf, atoi(val));
8018
Arif Hussainac6c5112018-05-25 17:34:00 -07008019 val = get_param(cmd, "MCS_FixedRate");
8020 if (val) {
8021#ifdef NL80211_SUPPORT
8022 int mcs, ratecode = 0;
8023 enum he_mcs_config mcs_config;
8024 int ret;
Jouni Malinenb9b671d2019-04-26 13:23:17 +03008025 char buf[60];
Arif Hussainac6c5112018-05-25 17:34:00 -07008026
8027 ratecode = (0x07 & dut->sta_nss) << 5;
8028 mcs = atoi(val);
8029 /* Add the MCS to the ratecode */
8030 if (mcs >= 0 && mcs <= 11) {
8031 ratecode += mcs;
8032 if (dut->device_type == STA_testbed &&
8033 mcs > 7 && mcs <= 11) {
8034 if (mcs <= 9)
8035 mcs_config = HE_80_MCS0_9;
8036 else
8037 mcs_config = HE_80_MCS0_11;
8038 ret = sta_set_he_mcs(dut, intf, mcs_config);
8039 if (ret) {
8040 sigma_dut_print(dut, DUT_MSG_ERROR,
8041 "MCS_FixedRate: mcs setting failed, mcs:%d, mcs_config %d, ret:%d",
8042 mcs, mcs_config, ret);
8043 }
8044 }
8045 snprintf(buf, sizeof(buf),
8046 "iwpriv %s set_11ax_rate 0x%03x",
8047 intf, ratecode);
8048 if (system(buf) != 0) {
8049 sigma_dut_print(dut, DUT_MSG_ERROR,
8050 "MCS_FixedRate: iwpriv setting of 11ax rates 0x%03x failed",
8051 ratecode);
8052 }
8053 } else {
8054 sigma_dut_print(dut, DUT_MSG_ERROR,
8055 "MCS_FixedRate: HE MCS %d not supported",
8056 mcs);
8057 }
8058#else /* NL80211_SUPPORT */
8059 sigma_dut_print(dut, DUT_MSG_ERROR,
8060 "MCS_FixedRate cannot be changed without NL80211_SUPPORT defined");
8061#endif /* NL80211_SUPPORT */
8062 }
8063
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008064 val = get_param(cmd, "opt_md_notif_ie");
8065 if (val) {
8066 char *result = NULL;
8067 char delim[] = ";";
8068 char token[30];
8069 int value, config_val = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308070 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008071
Peng Xub8fc5cc2017-05-10 17:27:28 -07008072 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308073 result = strtok_r(token, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008074
8075 /* Extract the NSS information */
8076 if (result) {
8077 value = atoi(result);
8078 switch (value) {
8079 case 1:
8080 config_val = 1;
8081 break;
8082 case 2:
8083 config_val = 3;
8084 break;
8085 case 3:
8086 config_val = 7;
8087 break;
8088 case 4:
8089 config_val = 15;
8090 break;
8091 default:
8092 config_val = 3;
8093 break;
8094 }
8095
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008096 run_iwpriv(dut, intf, "rxchainmask %d", config_val);
8097 run_iwpriv(dut, intf, "txchainmask %d", config_val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008098
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008099 }
8100
8101 /* Extract the channel width information */
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308102 result = strtok_r(NULL, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008103 if (result) {
8104 value = atoi(result);
8105 switch (value) {
8106 case 20:
8107 config_val = 0;
8108 break;
8109 case 40:
8110 config_val = 1;
8111 break;
8112 case 80:
8113 config_val = 2;
8114 break;
8115 case 160:
8116 config_val = 3;
8117 break;
8118 default:
8119 config_val = 2;
8120 break;
8121 }
8122
8123 dut->chwidth = config_val;
8124
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008125 run_iwpriv(dut, intf, "chwidth %d", config_val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008126 }
8127
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008128 run_iwpriv(dut, intf, "opmode_notify 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008129 }
8130
8131 val = get_param(cmd, "nss_mcs_cap");
8132 if (val) {
8133 int nss, mcs;
8134 char token[20];
8135 char *result = NULL;
8136 unsigned int vht_mcsmap = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308137 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008138
Peng Xub8fc5cc2017-05-10 17:27:28 -07008139 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308140 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05308141 if (!result) {
8142 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07008143 "NSS not specified");
8144 send_resp(dut, conn, SIGMA_ERROR,
8145 "errorCode,NSS not specified");
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05308146 return 0;
8147 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008148 nss = atoi(result);
8149
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008150 run_iwpriv(dut, intf, "nss %d", nss);
Arif Hussainac6c5112018-05-25 17:34:00 -07008151 dut->sta_nss = nss;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008152
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308153 result = strtok_r(NULL, ";", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008154 if (result == NULL) {
8155 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07008156 "MCS not specified");
8157 send_resp(dut, conn, SIGMA_ERROR,
8158 "errorCode,MCS not specified");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008159 return 0;
8160 }
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308161 result = strtok_r(result, "-", &saveptr);
8162 result = strtok_r(NULL, "-", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05308163 if (!result) {
8164 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07008165 "MCS not specified");
8166 send_resp(dut, conn, SIGMA_ERROR,
8167 "errorCode,MCS not specified");
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05308168 return 0;
8169 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008170 mcs = atoi(result);
8171
Arif Hussaina37e9552018-06-20 17:05:59 -07008172 if (program && strcasecmp(program, "HE") == 0) {
8173#ifdef NL80211_SUPPORT
8174 enum he_mcs_config mcs_config;
8175 int ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008176
Arif Hussaina37e9552018-06-20 17:05:59 -07008177 if (mcs >= 0 && mcs <= 7) {
8178 mcs_config = HE_80_MCS0_7;
8179 } else if (mcs > 7 && mcs <= 9) {
8180 mcs_config = HE_80_MCS0_9;
8181 } else if (mcs > 9 && mcs <= 11) {
8182 mcs_config = HE_80_MCS0_11;
8183 } else {
8184 sigma_dut_print(dut, DUT_MSG_ERROR,
8185 "nss_mcs_cap: HE: Invalid mcs: %d",
8186 mcs);
8187 send_resp(dut, conn, SIGMA_ERROR,
8188 "errorCode,Invalid MCS");
8189 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008190 }
Arif Hussaina37e9552018-06-20 17:05:59 -07008191
8192 ret = sta_set_he_mcs(dut, intf, mcs_config);
8193 if (ret) {
8194 sigma_dut_print(dut, DUT_MSG_ERROR,
8195 "nss_mcs_cap: HE: Setting of MCS failed, mcs_config: %d, ret: %d",
8196 mcs_config, ret);
8197 send_resp(dut, conn, SIGMA_ERROR,
8198 "errorCode,Failed to set MCS");
8199 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008200 }
Arif Hussaina37e9552018-06-20 17:05:59 -07008201#else /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008202 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07008203 "nss_mcs_cap: HE: MCS cannot be changed without NL80211_SUPPORT defined");
8204#endif /* NL80211_SUPPORT */
8205 } else {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008206 run_iwpriv(dut, intf, "vhtmcs %d", mcs);
Arif Hussaina37e9552018-06-20 17:05:59 -07008207
8208 switch (nss) {
8209 case 1:
8210 switch (mcs) {
8211 case 7:
8212 vht_mcsmap = 0xfffc;
8213 break;
8214 case 8:
8215 vht_mcsmap = 0xfffd;
8216 break;
8217 case 9:
8218 vht_mcsmap = 0xfffe;
8219 break;
8220 default:
8221 vht_mcsmap = 0xfffe;
8222 break;
8223 }
8224 break;
8225 case 2:
8226 switch (mcs) {
8227 case 7:
8228 vht_mcsmap = 0xfff0;
8229 break;
8230 case 8:
8231 vht_mcsmap = 0xfff5;
8232 break;
8233 case 9:
8234 vht_mcsmap = 0xfffa;
8235 break;
8236 default:
8237 vht_mcsmap = 0xfffa;
8238 break;
8239 }
8240 break;
8241 case 3:
8242 switch (mcs) {
8243 case 7:
8244 vht_mcsmap = 0xffc0;
8245 break;
8246 case 8:
8247 vht_mcsmap = 0xffd5;
8248 break;
8249 case 9:
8250 vht_mcsmap = 0xffea;
8251 break;
8252 default:
8253 vht_mcsmap = 0xffea;
8254 break;
8255 }
8256 break;
8257 default:
8258 vht_mcsmap = 0xffea;
8259 break;
8260 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008261 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008262 }
8263 }
8264
8265 /* UNSUPPORTED: val = get_param(cmd, "Tx_lgi_rate"); */
8266
8267 val = get_param(cmd, "Vht_tkip");
8268 if (val)
8269 tkip = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
8270
8271 val = get_param(cmd, "Vht_wep");
8272 if (val)
8273 wep = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
8274
8275 if (tkip != -1 || wep != -1) {
8276 if ((tkip == 1 && wep != 0) || (wep == 1 && tkip != 0)) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008277 run_iwpriv(dut, intf, "htweptkip 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008278 } else if ((tkip == 0 && wep != 1) || (wep == 0 && tkip != 1)) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008279 run_iwpriv(dut, intf, "htweptkip 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008280 } else {
8281 sigma_dut_print(dut, DUT_MSG_ERROR,
8282 "ErrorCode,mixed mode of VHT TKIP/WEP not supported");
8283 return 0;
8284 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008285 }
8286
Arif Hussain55f00da2018-07-03 08:28:26 -07008287 val = get_param(cmd, "txBandwidth");
8288 if (val) {
8289 switch (get_driver_type()) {
8290 case DRIVER_WCN:
8291 if (wcn_sta_set_width(dut, intf, val) < 0) {
8292 send_resp(dut, conn, SIGMA_ERROR,
8293 "ErrorCode,Failed to set txBandwidth");
8294 return 0;
8295 }
8296 break;
8297 case DRIVER_ATHEROS:
8298 if (ath_set_width(dut, conn, intf, val) < 0) {
8299 send_resp(dut, conn, SIGMA_ERROR,
8300 "ErrorCode,Failed to set txBandwidth");
8301 return 0;
8302 }
8303 break;
8304 default:
8305 sigma_dut_print(dut, DUT_MSG_ERROR,
8306 "Setting txBandwidth not supported");
8307 break;
8308 }
8309 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008310
Arif Hussain9765f7d2018-07-03 08:28:26 -07008311 val = get_param(cmd, "BeamformeeSTS");
8312 if (val) {
Kiran Kumar Lokerebc89d432018-07-10 12:20:13 -07008313 if (sta_set_tx_beamformee(dut, intf, 1)) {
8314 send_resp(dut, conn, SIGMA_ERROR,
8315 "ErrorCode,Failed to set TX beamformee enable");
8316 return 0;
8317 }
8318
Arif Hussain9765f7d2018-07-03 08:28:26 -07008319 if (sta_set_beamformee_sts(dut, intf, atoi(val))) {
8320 send_resp(dut, conn, SIGMA_ERROR,
8321 "ErrorCode,Failed to set BeamformeeSTS");
8322 return 0;
8323 }
8324 }
8325
Arif Hussain68d23f52018-07-11 13:39:08 -07008326 val = get_param(cmd, "Trig_MAC_Padding_Dur");
8327 if (val) {
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07008328#ifdef NL80211_SUPPORT
8329 enum qca_wlan_he_mac_padding_dur set_val;
8330
8331 switch (atoi(val)) {
8332 case 16:
8333 set_val = QCA_WLAN_HE_16US_OF_PROCESS_TIME;
8334 break;
8335 case 8:
8336 set_val = QCA_WLAN_HE_8US_OF_PROCESS_TIME;
8337 break;
8338 default:
8339 set_val = QCA_WLAN_HE_NO_ADDITIONAL_PROCESS_TIME;
8340 break;
8341 }
8342 if (sta_set_mac_padding_duration(dut, intf, set_val)) {
Arif Hussain68d23f52018-07-11 13:39:08 -07008343 send_resp(dut, conn, SIGMA_ERROR,
8344 "ErrorCode,Failed to set MAC padding duration");
8345 return 0;
8346 }
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07008347#else /* NL80211_SUPPORT */
8348 sigma_dut_print(dut, DUT_MSG_ERROR,
8349 "MAC padding duration cannot be changed without NL80211_SUPPORT defined");
8350#endif /* NL80211_SUPPORT */
Arif Hussain68d23f52018-07-11 13:39:08 -07008351 }
8352
Arif Hussain480d5f42019-03-12 14:40:42 -07008353 val = get_param(cmd, "TWT_ReqSupport");
8354 if (val) {
8355 int set_val;
8356
8357 if (strcasecmp(val, "Enable") == 0) {
8358 set_val = 1;
8359 } else if (strcasecmp(val, "Disable") == 0) {
8360 set_val = 0;
8361 } else {
8362 send_resp(dut, conn, SIGMA_ERROR,
8363 "ErrorCode,Invalid TWT_ReqSupport");
8364 return STATUS_SENT;
8365 }
8366
8367 if (sta_set_twt_req_support(dut, intf, set_val)) {
8368 sigma_dut_print(dut, DUT_MSG_ERROR,
8369 "Failed to set TWT req support %d",
8370 set_val);
8371 send_resp(dut, conn, SIGMA_ERROR,
8372 "ErrorCode,Failed to set TWT_ReqSupport");
8373 return STATUS_SENT;
8374 }
8375 }
8376
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07008377 val = get_param(cmd, "MU_EDCA");
8378 if (val && (strcasecmp(val, "Override") == 0)) {
8379 if (sta_set_mu_edca_override(dut, intf, 1)) {
8380 send_resp(dut, conn, SIGMA_ERROR,
8381 "ErrorCode,Failed to set MU EDCA override");
8382 return 0;
8383 }
8384 }
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -07008385
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07008386 val = get_param(cmd, "OMControl");
8387 if (val) {
8388 int set_val = 1;
8389
8390 if (strcasecmp(val, "Enable") == 0)
8391 set_val = 1;
8392 else if (strcasecmp(val, "Disable") == 0)
8393 set_val = 0;
8394
8395 if (sta_set_om_ctrl_supp(dut, intf, set_val)) {
8396 send_resp(dut, conn, SIGMA_ERROR,
8397 "ErrorCode,Failed to set OM ctrl supp");
8398 return 0;
8399 }
8400 }
8401
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -07008402 val = get_param(cmd, "ADDBAResp_BufSize");
8403 if (val) {
8404 int buf_size;
8405
8406 if (strcasecmp(val, "gt64") == 0)
8407 buf_size = 256;
8408 else
8409 buf_size = 64;
8410 if (get_driver_type() == DRIVER_WCN &&
8411 sta_set_addba_buf_size(dut, intf, buf_size)) {
8412 send_resp(dut, conn, SIGMA_ERROR,
8413 "ErrorCode,set addbaresp_buff_size failed");
8414 return 0;
8415 }
8416 }
8417
8418 val = get_param(cmd, "ADDBAReq_BufSize");
8419 if (val) {
8420 int buf_size;
8421
8422 if (strcasecmp(val, "gt64") == 0)
8423 buf_size = 256;
8424 else
8425 buf_size = 64;
8426 if (get_driver_type() == DRIVER_WCN &&
8427 sta_set_addba_buf_size(dut, intf, buf_size)) {
8428 send_resp(dut, conn, SIGMA_ERROR,
8429 "ErrorCode,set addbareq_buff_size failed");
8430 return 0;
8431 }
8432 }
8433
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008434 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
8435}
8436
8437
8438static int sta_set_wireless_60g(struct sigma_dut *dut,
8439 struct sigma_conn *conn,
8440 struct sigma_cmd *cmd)
8441{
8442 const char *dev_role = get_param(cmd, "DevRole");
8443
8444 if (!dev_role) {
8445 send_resp(dut, conn, SIGMA_INVALID,
8446 "ErrorCode,DevRole not specified");
8447 return 0;
8448 }
8449
8450 if (strcasecmp(dev_role, "PCP") == 0)
8451 return sta_set_60g_pcp(dut, conn, cmd);
8452 if (strcasecmp(dev_role, "STA") == 0)
8453 return sta_set_60g_sta(dut, conn, cmd);
8454 send_resp(dut, conn, SIGMA_INVALID,
8455 "ErrorCode,DevRole not supported");
8456 return 0;
8457}
8458
8459
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05308460static int sta_set_wireless_oce(struct sigma_dut *dut, struct sigma_conn *conn,
8461 struct sigma_cmd *cmd)
8462{
8463 int status;
8464 const char *intf = get_param(cmd, "Interface");
8465 const char *val = get_param(cmd, "DevRole");
8466
8467 if (val && strcasecmp(val, "STA-CFON") == 0) {
8468 status = sta_cfon_set_wireless(dut, conn, cmd);
8469 if (status)
8470 return status;
8471 }
8472 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
8473}
8474
8475
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008476static int cmd_sta_set_wireless(struct sigma_dut *dut, struct sigma_conn *conn,
8477 struct sigma_cmd *cmd)
8478{
8479 const char *val;
8480
8481 val = get_param(cmd, "Program");
8482 if (val) {
8483 if (strcasecmp(val, "11n") == 0)
8484 return cmd_sta_set_11n(dut, conn, cmd);
Amarnath Hullur Subramanyam4f860292018-01-31 03:49:35 -08008485 if (strcasecmp(val, "VHT") == 0 || strcasecmp(val, "HE") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008486 return cmd_sta_set_wireless_vht(dut, conn, cmd);
8487 if (strcasecmp(val, "60ghz") == 0)
8488 return sta_set_wireless_60g(dut, conn, cmd);
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05308489 if (strcasecmp(val, "OCE") == 0)
8490 return sta_set_wireless_oce(dut, conn, cmd);
Alexei Avshalom Lazar66bb9972018-12-18 16:01:43 +02008491 /* sta_set_wireless in WPS program is only used for 60G */
8492 if (is_60g_sigma_dut(dut))
8493 return sta_set_wireless_60g(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008494 send_resp(dut, conn, SIGMA_ERROR,
8495 "ErrorCode,Program value not supported");
8496 } else {
8497 send_resp(dut, conn, SIGMA_ERROR,
8498 "ErrorCode,Program argument not available");
8499 }
8500
8501 return 0;
8502}
8503
8504
8505static void ath_sta_inject_frame(struct sigma_dut *dut, const char *intf,
8506 int tid)
8507{
8508 char buf[100];
8509 int tid_to_dscp [] = { 0x00, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0 };
8510
Pradeep Reddy POTTETId31d1322016-10-13 17:22:03 +05308511 if (tid < 0 ||
8512 tid >= (int) (sizeof(tid_to_dscp) / sizeof(tid_to_dscp[0]))) {
8513 sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported TID: %d", tid);
8514 return;
8515 }
8516
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008517 /*
8518 * Two ways to ensure that addba request with a
8519 * non zero TID could be sent out. EV 117296
8520 */
8521 snprintf(buf, sizeof(buf),
8522 "ping -c 8 -Q %d `arp -a | grep wlan0 | awk '{print $2}' | tr -d '()'`",
8523 tid);
8524 if (system(buf) != 0) {
8525 sigma_dut_print(dut, DUT_MSG_ERROR,
8526 "Ping did not send out");
8527 }
8528
8529 snprintf(buf, sizeof(buf),
8530 "iwconfig %s | grep Access | awk '{print $6}' > %s",
8531 intf, VI_QOS_TMP_FILE);
8532 if (system(buf) != 0)
8533 return;
8534
8535 snprintf(buf, sizeof(buf),
8536 "ifconfig %s | grep HWaddr | cut -b 39-56 >> %s",
8537 intf, VI_QOS_TMP_FILE);
8538 if (system(buf) != 0)
8539 sigma_dut_print(dut, DUT_MSG_ERROR, "HWaddr matching failed");
8540
8541 snprintf(buf,sizeof(buf), "sed -n '3,$p' %s >> %s",
8542 VI_QOS_REFFILE, VI_QOS_TMP_FILE);
8543 if (system(buf) != 0) {
8544 sigma_dut_print(dut, DUT_MSG_ERROR,
8545 "VI_QOS_TEMP_FILE generation error failed");
8546 }
8547 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
8548 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
8549 if (system(buf) != 0) {
8550 sigma_dut_print(dut, DUT_MSG_ERROR,
8551 "VI_QOS_FILE generation failed");
8552 }
8553
8554 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
8555 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
8556 if (system(buf) != 0) {
8557 sigma_dut_print(dut, DUT_MSG_ERROR,
8558 "VI_QOS_FILE generation failed");
8559 }
8560
8561 snprintf(buf, sizeof(buf), "ethinject %s %s", intf, VI_QOS_FILE);
8562 if (system(buf) != 0) {
8563 }
8564}
8565
8566
8567static int ath_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
8568 struct sigma_cmd *cmd)
8569{
8570 const char *intf = get_param(cmd, "Interface");
8571 const char *val;
8572 int tid = 0;
8573 char buf[100];
8574
8575 val = get_param(cmd, "TID");
8576 if (val) {
8577 tid = atoi(val);
8578 if (tid)
8579 ath_sta_inject_frame(dut, intf, tid);
8580 }
8581
8582 /* Command sequence for ADDBA request on Peregrine based devices */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008583 run_iwpriv(dut, intf, "setaddbaoper 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008584
8585 snprintf(buf, sizeof(buf), "wifitool %s senddelba 1 %d 1 4", intf, tid);
8586 if (system(buf) != 0) {
8587 sigma_dut_print(dut, DUT_MSG_ERROR,
8588 "wifitool senddelba failed");
8589 }
8590
8591 snprintf(buf, sizeof(buf), "wifitool %s sendaddba 1 %d 64", intf, tid);
8592 if (system(buf) != 0) {
8593 sigma_dut_print(dut, DUT_MSG_ERROR,
8594 "wifitool sendaddba failed");
8595 }
8596
8597 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
8598
8599 return 1;
8600}
8601
8602
Lior David9981b512017-01-20 13:16:40 +02008603#ifdef __linux__
8604
8605static int wil6210_send_addba(struct sigma_dut *dut, const char *dest_mac,
8606 int agg_size)
8607{
8608 char dir[128], buf[128];
8609 FILE *f;
8610 regex_t re;
8611 regmatch_t m[2];
8612 int rc, ret = -1, vring_id, found;
8613
8614 if (wil6210_get_debugfs_dir(dut, dir, sizeof(dir))) {
8615 sigma_dut_print(dut, DUT_MSG_ERROR,
8616 "failed to get wil6210 debugfs dir");
8617 return -1;
8618 }
8619
8620 snprintf(buf, sizeof(buf), "%s/vrings", dir);
8621 f = fopen(buf, "r");
8622 if (!f) {
8623 sigma_dut_print(dut, DUT_MSG_ERROR, "failed to open: %s", buf);
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +02008624 /* newer wil6210 driver renamed file to "rings" */
8625 snprintf(buf, sizeof(buf), "%s/rings", dir);
8626 f = fopen(buf, "r");
8627 if (!f) {
8628 sigma_dut_print(dut, DUT_MSG_ERROR,
8629 "failed to open: %s", buf);
8630 return -1;
8631 }
Lior David9981b512017-01-20 13:16:40 +02008632 }
8633
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +02008634 /* can be either VRING tx... or RING... */
8635 if (regcomp(&re, "RING tx_[ \t]*([0-9]+)", REG_EXTENDED)) {
Lior David9981b512017-01-20 13:16:40 +02008636 sigma_dut_print(dut, DUT_MSG_ERROR, "regcomp failed");
8637 goto out;
8638 }
8639
8640 /* find TX VRING for the mac address */
8641 found = 0;
8642 while (fgets(buf, sizeof(buf), f)) {
8643 if (strcasestr(buf, dest_mac)) {
8644 found = 1;
8645 break;
8646 }
8647 }
8648
8649 if (!found) {
8650 sigma_dut_print(dut, DUT_MSG_ERROR,
8651 "no TX VRING for %s", dest_mac);
8652 goto out;
8653 }
8654
8655 /* extract VRING ID, "VRING tx_<id> = {" */
8656 if (!fgets(buf, sizeof(buf), f)) {
8657 sigma_dut_print(dut, DUT_MSG_ERROR,
8658 "no VRING start line for %s", dest_mac);
8659 goto out;
8660 }
8661
8662 rc = regexec(&re, buf, 2, m, 0);
8663 regfree(&re);
8664 if (rc || m[1].rm_so < 0) {
8665 sigma_dut_print(dut, DUT_MSG_ERROR,
8666 "no VRING TX ID for %s", dest_mac);
8667 goto out;
8668 }
8669 buf[m[1].rm_eo] = 0;
8670 vring_id = atoi(&buf[m[1].rm_so]);
8671
8672 /* send the addba command */
8673 fclose(f);
8674 snprintf(buf, sizeof(buf), "%s/back", dir);
8675 f = fopen(buf, "w");
8676 if (!f) {
8677 sigma_dut_print(dut, DUT_MSG_ERROR,
8678 "failed to open: %s", buf);
8679 return -1;
8680 }
8681
8682 fprintf(f, "add %d %d\n", vring_id, agg_size);
8683
8684 ret = 0;
8685
8686out:
8687 fclose(f);
8688
8689 return ret;
8690}
8691
8692
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +02008693int send_addba_60g(struct sigma_dut *dut, struct sigma_conn *conn,
8694 struct sigma_cmd *cmd, const char *mac_param)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008695{
8696 const char *val;
8697 int tid = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008698
8699 val = get_param(cmd, "TID");
8700 if (val) {
8701 tid = atoi(val);
8702 if (tid != 0) {
8703 sigma_dut_print(dut, DUT_MSG_ERROR,
8704 "Ignore TID %d for send_addba use TID 0 for 60g since only 0 required on TX",
8705 tid);
8706 }
8707 }
8708
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +02008709 val = get_param(cmd, mac_param);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008710 if (!val) {
8711 sigma_dut_print(dut, DUT_MSG_ERROR,
8712 "Currently not supporting addba for 60G without Dest_mac");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02008713 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008714 }
8715
Lior David9981b512017-01-20 13:16:40 +02008716 if (wil6210_send_addba(dut, val, dut->back_rcv_buf))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008717 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008718
8719 return 1;
8720}
8721
Lior David9981b512017-01-20 13:16:40 +02008722#endif /* __linux__ */
8723
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008724
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08008725static int wcn_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
8726 struct sigma_cmd *cmd)
8727{
8728#ifdef NL80211_SUPPORT
8729 const char *intf = get_param(cmd, "Interface");
8730 const char *val;
8731 int tid = -1;
8732 int bufsize = 64;
8733 struct nl_msg *msg;
8734 int ret = 0;
8735 struct nlattr *params;
8736 int ifindex;
8737
8738 val = get_param(cmd, "TID");
8739 if (val)
8740 tid = atoi(val);
8741
8742 if (tid == -1) {
8743 send_resp(dut, conn, SIGMA_ERROR,
8744 "ErrorCode,sta_send_addba tid invalid");
8745 return 0;
8746 }
8747
8748 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
8749
8750 ifindex = if_nametoindex(intf);
8751 if (ifindex == 0) {
8752 sigma_dut_print(dut, DUT_MSG_ERROR,
8753 "%s: Index for interface %s failed",
8754 __func__, intf);
8755 send_resp(dut, conn, SIGMA_ERROR,
8756 "ErrorCode,sta_send_addba interface invalid");
8757 return 0;
8758 }
8759
8760 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8761 NL80211_CMD_VENDOR)) ||
8762 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
8763 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
8764 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
8765 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
8766 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8767 nla_put_u8(msg,
8768 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADD_DEL_BA_SESSION,
8769 QCA_WLAN_ADD_BA) ||
8770 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BA_TID,
8771 tid) ||
Kiran Kumar Lokere26e27582018-08-01 16:18:34 -07008772 nla_put_u16(msg,
8773 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE,
8774 bufsize)) {
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08008775 sigma_dut_print(dut, DUT_MSG_ERROR,
8776 "%s: err in adding vendor_cmd and vendor_data",
8777 __func__);
8778 nlmsg_free(msg);
8779 send_resp(dut, conn, SIGMA_ERROR,
8780 "ErrorCode,sta_send_addba err in adding vendor_cmd and vendor_data");
8781 return 0;
8782 }
8783 nla_nest_end(msg, params);
8784
8785 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
8786 if (ret) {
8787 sigma_dut_print(dut, DUT_MSG_ERROR,
8788 "%s: err in send_and_recv_msgs, ret=%d",
8789 __func__, ret);
Sunil Dutt30605592018-05-04 20:35:50 +05308790 if (ret == -EOPNOTSUPP)
8791 return 1;
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08008792 send_resp(dut, conn, SIGMA_ERROR,
8793 "ErrorCode,sta_send_addba err in send_and_recv_msgs");
8794 return 0;
8795 }
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08008796#else /* NL80211_SUPPORT */
8797 sigma_dut_print(dut, DUT_MSG_ERROR,
8798 "sta_send_addba not supported without NL80211_SUPPORT defined");
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08008799#endif /* NL80211_SUPPORT */
Sunil Dutt30605592018-05-04 20:35:50 +05308800
8801 return 1;
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08008802}
8803
8804
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008805static int cmd_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
8806 struct sigma_cmd *cmd)
8807{
8808 switch (get_driver_type()) {
8809 case DRIVER_ATHEROS:
8810 return ath_sta_send_addba(dut, conn, cmd);
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08008811 case DRIVER_WCN:
8812 return wcn_sta_send_addba(dut, conn, cmd);
Lior David9981b512017-01-20 13:16:40 +02008813#ifdef __linux__
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008814 case DRIVER_WIL6210:
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +02008815 return send_addba_60g(dut, conn, cmd, "Dest_mac");
Lior David9981b512017-01-20 13:16:40 +02008816#endif /* __linux__ */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008817 default:
8818 /*
8819 * There is no driver specific implementation for other drivers.
8820 * Ignore the command and report COMPLETE since the following
8821 * throughput test operation will end up sending ADDBA anyway.
8822 */
8823 return 1;
8824 }
8825}
8826
8827
8828int inject_eth_frame(int s, const void *data, size_t len,
8829 unsigned short ethtype, char *dst, char *src)
8830{
8831 struct iovec iov[4] = {
8832 {
8833 .iov_base = dst,
8834 .iov_len = ETH_ALEN,
8835 },
8836 {
8837 .iov_base = src,
8838 .iov_len = ETH_ALEN,
8839 },
8840 {
8841 .iov_base = &ethtype,
8842 .iov_len = sizeof(unsigned short),
8843 },
8844 {
8845 .iov_base = (void *) data,
8846 .iov_len = len,
8847 }
8848 };
8849 struct msghdr msg = {
8850 .msg_name = NULL,
8851 .msg_namelen = 0,
8852 .msg_iov = iov,
8853 .msg_iovlen = 4,
8854 .msg_control = NULL,
8855 .msg_controllen = 0,
8856 .msg_flags = 0,
8857 };
8858
8859 return sendmsg(s, &msg, 0);
8860}
8861
8862#if defined(__linux__) || defined(__QNXNTO__)
8863
8864int inject_frame(int s, const void *data, size_t len, int encrypt)
8865{
8866#define IEEE80211_RADIOTAP_F_WEP 0x04
8867#define IEEE80211_RADIOTAP_F_FRAG 0x08
8868 unsigned char rtap_hdr[] = {
8869 0x00, 0x00, /* radiotap version */
8870 0x0e, 0x00, /* radiotap length */
8871 0x02, 0xc0, 0x00, 0x00, /* bmap: flags, tx and rx flags */
8872 IEEE80211_RADIOTAP_F_FRAG, /* F_FRAG (fragment if required) */
8873 0x00, /* padding */
8874 0x00, 0x00, /* RX and TX flags to indicate that */
8875 0x00, 0x00, /* this is the injected frame directly */
8876 };
8877 struct iovec iov[2] = {
8878 {
8879 .iov_base = &rtap_hdr,
8880 .iov_len = sizeof(rtap_hdr),
8881 },
8882 {
8883 .iov_base = (void *) data,
8884 .iov_len = len,
8885 }
8886 };
8887 struct msghdr msg = {
8888 .msg_name = NULL,
8889 .msg_namelen = 0,
8890 .msg_iov = iov,
8891 .msg_iovlen = 2,
8892 .msg_control = NULL,
8893 .msg_controllen = 0,
8894 .msg_flags = 0,
8895 };
8896
8897 if (encrypt)
8898 rtap_hdr[8] |= IEEE80211_RADIOTAP_F_WEP;
8899
8900 return sendmsg(s, &msg, 0);
8901}
8902
8903
8904int open_monitor(const char *ifname)
8905{
8906#ifdef __QNXNTO__
8907 struct sockaddr_dl ll;
8908 int s;
8909
8910 memset(&ll, 0, sizeof(ll));
8911 ll.sdl_family = AF_LINK;
8912 ll.sdl_index = if_nametoindex(ifname);
8913 if (ll.sdl_index == 0) {
8914 perror("if_nametoindex");
8915 return -1;
8916 }
8917 s = socket(PF_INET, SOCK_RAW, 0);
8918#else /* __QNXNTO__ */
8919 struct sockaddr_ll ll;
8920 int s;
8921
8922 memset(&ll, 0, sizeof(ll));
8923 ll.sll_family = AF_PACKET;
8924 ll.sll_ifindex = if_nametoindex(ifname);
8925 if (ll.sll_ifindex == 0) {
8926 perror("if_nametoindex");
8927 return -1;
8928 }
8929 s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
8930#endif /* __QNXNTO__ */
8931 if (s < 0) {
8932 perror("socket[PF_PACKET,SOCK_RAW]");
8933 return -1;
8934 }
8935
8936 if (bind(s, (struct sockaddr *) &ll, sizeof(ll)) < 0) {
8937 perror("monitor socket bind");
8938 close(s);
8939 return -1;
8940 }
8941
8942 return s;
8943}
8944
8945
8946static int hex2num(char c)
8947{
8948 if (c >= '0' && c <= '9')
8949 return c - '0';
8950 if (c >= 'a' && c <= 'f')
8951 return c - 'a' + 10;
8952 if (c >= 'A' && c <= 'F')
8953 return c - 'A' + 10;
8954 return -1;
8955}
8956
8957
8958int hwaddr_aton(const char *txt, unsigned char *addr)
8959{
8960 int i;
8961
8962 for (i = 0; i < 6; i++) {
8963 int a, b;
8964
8965 a = hex2num(*txt++);
8966 if (a < 0)
8967 return -1;
8968 b = hex2num(*txt++);
8969 if (b < 0)
8970 return -1;
8971 *addr++ = (a << 4) | b;
8972 if (i < 5 && *txt++ != ':')
8973 return -1;
8974 }
8975
8976 return 0;
8977}
8978
8979#endif /* defined(__linux__) || defined(__QNXNTO__) */
8980
8981enum send_frame_type {
8982 DISASSOC, DEAUTH, SAQUERY, AUTH, ASSOCREQ, REASSOCREQ, DLS_REQ
8983};
8984enum send_frame_protection {
8985 CORRECT_KEY, INCORRECT_KEY, UNPROTECTED
8986};
8987
8988
8989static int sta_inject_frame(struct sigma_dut *dut, struct sigma_conn *conn,
8990 enum send_frame_type frame,
8991 enum send_frame_protection protected,
8992 const char *dest)
8993{
8994#ifdef __linux__
8995 unsigned char buf[1000], *pos;
8996 int s, res;
8997 char bssid[20], addr[20];
8998 char result[32], ssid[100];
8999 size_t ssid_len;
9000
9001 if (get_wpa_status(get_station_ifname(), "wpa_state", result,
9002 sizeof(result)) < 0 ||
9003 strncmp(result, "COMPLETED", 9) != 0) {
9004 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Not connected");
9005 return 0;
9006 }
9007
9008 if (get_wpa_status(get_station_ifname(), "bssid", bssid, sizeof(bssid))
9009 < 0) {
9010 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
9011 "current BSSID");
9012 return 0;
9013 }
9014
9015 if (get_wpa_status(get_station_ifname(), "address", addr, sizeof(addr))
9016 < 0) {
9017 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
9018 "own MAC address");
9019 return 0;
9020 }
9021
9022 if (get_wpa_status(get_station_ifname(), "ssid", ssid, sizeof(ssid))
9023 < 0) {
9024 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
9025 "current SSID");
9026 return 0;
9027 }
9028 ssid_len = strlen(ssid);
9029
9030 pos = buf;
9031
9032 /* Frame Control */
9033 switch (frame) {
9034 case DISASSOC:
9035 *pos++ = 0xa0;
9036 break;
9037 case DEAUTH:
9038 *pos++ = 0xc0;
9039 break;
9040 case SAQUERY:
9041 *pos++ = 0xd0;
9042 break;
9043 case AUTH:
9044 *pos++ = 0xb0;
9045 break;
9046 case ASSOCREQ:
9047 *pos++ = 0x00;
9048 break;
9049 case REASSOCREQ:
9050 *pos++ = 0x20;
9051 break;
9052 case DLS_REQ:
9053 *pos++ = 0xd0;
9054 break;
9055 }
9056
9057 if (protected == INCORRECT_KEY)
9058 *pos++ = 0x40; /* Set Protected field to 1 */
9059 else
9060 *pos++ = 0x00;
9061
9062 /* Duration */
9063 *pos++ = 0x00;
9064 *pos++ = 0x00;
9065
9066 /* addr1 = DA (current AP) */
9067 hwaddr_aton(bssid, pos);
9068 pos += 6;
9069 /* addr2 = SA (own address) */
9070 hwaddr_aton(addr, pos);
9071 pos += 6;
9072 /* addr3 = BSSID (current AP) */
9073 hwaddr_aton(bssid, pos);
9074 pos += 6;
9075
9076 /* Seq# (to be filled by driver/mac80211) */
9077 *pos++ = 0x00;
9078 *pos++ = 0x00;
9079
9080 if (protected == INCORRECT_KEY) {
9081 /* CCMP parameters */
9082 memcpy(pos, "\x61\x01\x00\x20\x00\x10\x00\x00", 8);
9083 pos += 8;
9084 }
9085
9086 if (protected == INCORRECT_KEY) {
9087 switch (frame) {
9088 case DEAUTH:
9089 /* Reason code (encrypted) */
9090 memcpy(pos, "\xa7\x39", 2);
9091 pos += 2;
9092 break;
9093 case DISASSOC:
9094 /* Reason code (encrypted) */
9095 memcpy(pos, "\xa7\x39", 2);
9096 pos += 2;
9097 break;
9098 case SAQUERY:
9099 /* Category|Action|TransID (encrypted) */
9100 memcpy(pos, "\x6f\xbd\xe9\x4d", 4);
9101 pos += 4;
9102 break;
9103 default:
9104 return -1;
9105 }
9106
9107 /* CCMP MIC */
9108 memcpy(pos, "\xc8\xd8\x3b\x06\x5d\xb7\x25\x68", 8);
9109 pos += 8;
9110 } else {
9111 switch (frame) {
9112 case DEAUTH:
9113 /* reason code = 8 */
9114 *pos++ = 0x08;
9115 *pos++ = 0x00;
9116 break;
9117 case DISASSOC:
9118 /* reason code = 8 */
9119 *pos++ = 0x08;
9120 *pos++ = 0x00;
9121 break;
9122 case SAQUERY:
9123 /* Category - SA Query */
9124 *pos++ = 0x08;
9125 /* SA query Action - Request */
9126 *pos++ = 0x00;
9127 /* Transaction ID */
9128 *pos++ = 0x12;
9129 *pos++ = 0x34;
9130 break;
9131 case AUTH:
9132 /* Auth Alg (Open) */
9133 *pos++ = 0x00;
9134 *pos++ = 0x00;
9135 /* Seq# */
9136 *pos++ = 0x01;
9137 *pos++ = 0x00;
9138 /* Status code */
9139 *pos++ = 0x00;
9140 *pos++ = 0x00;
9141 break;
9142 case ASSOCREQ:
9143 /* Capability Information */
9144 *pos++ = 0x31;
9145 *pos++ = 0x04;
9146 /* Listen Interval */
9147 *pos++ = 0x0a;
9148 *pos++ = 0x00;
9149 /* SSID */
9150 *pos++ = 0x00;
9151 *pos++ = ssid_len;
9152 memcpy(pos, ssid, ssid_len);
9153 pos += ssid_len;
9154 /* Supported Rates */
9155 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
9156 10);
9157 pos += 10;
9158 /* Extended Supported Rates */
9159 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
9160 pos += 6;
9161 /* RSN */
9162 memcpy(pos, "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00"
9163 "\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x02\xc0"
9164 "\x00\x00\x00\x00\x0f\xac\x06", 28);
9165 pos += 28;
9166 break;
9167 case REASSOCREQ:
9168 /* Capability Information */
9169 *pos++ = 0x31;
9170 *pos++ = 0x04;
9171 /* Listen Interval */
9172 *pos++ = 0x0a;
9173 *pos++ = 0x00;
9174 /* Current AP */
9175 hwaddr_aton(bssid, pos);
9176 pos += 6;
9177 /* SSID */
9178 *pos++ = 0x00;
9179 *pos++ = ssid_len;
9180 memcpy(pos, ssid, ssid_len);
9181 pos += ssid_len;
9182 /* Supported Rates */
9183 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
9184 10);
9185 pos += 10;
9186 /* Extended Supported Rates */
9187 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
9188 pos += 6;
9189 /* RSN */
9190 memcpy(pos, "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00"
9191 "\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x02\xc0"
9192 "\x00\x00\x00\x00\x0f\xac\x06", 28);
9193 pos += 28;
9194 break;
9195 case DLS_REQ:
9196 /* Category - DLS */
9197 *pos++ = 0x02;
9198 /* DLS Action - Request */
9199 *pos++ = 0x00;
9200 /* Destination MACAddress */
9201 if (dest)
9202 hwaddr_aton(dest, pos);
9203 else
9204 memset(pos, 0, 6);
9205 pos += 6;
9206 /* Source MACAddress */
9207 hwaddr_aton(addr, pos);
9208 pos += 6;
9209 /* Capability Information */
9210 *pos++ = 0x10; /* Privacy */
9211 *pos++ = 0x06; /* QoS */
9212 /* DLS Timeout Value */
9213 *pos++ = 0x00;
9214 *pos++ = 0x01;
9215 /* Supported rates */
9216 *pos++ = 0x01;
9217 *pos++ = 0x08;
9218 *pos++ = 0x0c; /* 6 Mbps */
9219 *pos++ = 0x12; /* 9 Mbps */
9220 *pos++ = 0x18; /* 12 Mbps */
9221 *pos++ = 0x24; /* 18 Mbps */
9222 *pos++ = 0x30; /* 24 Mbps */
9223 *pos++ = 0x48; /* 36 Mbps */
9224 *pos++ = 0x60; /* 48 Mbps */
9225 *pos++ = 0x6c; /* 54 Mbps */
9226 /* TODO: Extended Supported Rates */
9227 /* TODO: HT Capabilities */
9228 break;
9229 }
9230 }
9231
9232 s = open_monitor("sigmadut");
9233 if (s < 0) {
9234 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
9235 "monitor socket");
9236 return 0;
9237 }
9238
9239 res = inject_frame(s, buf, pos - buf, protected == CORRECT_KEY);
9240 if (res < 0) {
9241 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
9242 "inject frame");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05309243 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009244 return 0;
9245 }
9246 if (res < pos - buf) {
9247 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Only partial "
9248 "frame sent");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05309249 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009250 return 0;
9251 }
9252
9253 close(s);
9254
9255 return 1;
9256#else /* __linux__ */
9257 send_resp(dut, conn, SIGMA_ERROR, "errorCode,sta_send_frame not "
9258 "yet supported");
9259 return 0;
9260#endif /* __linux__ */
9261}
9262
9263
9264static int cmd_sta_send_frame_tdls(struct sigma_dut *dut,
9265 struct sigma_conn *conn,
9266 struct sigma_cmd *cmd)
9267{
9268 const char *intf = get_param(cmd, "Interface");
9269 const char *sta, *val;
9270 unsigned char addr[ETH_ALEN];
9271 char buf[100];
9272
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +03009273 if (!intf)
9274 return -1;
9275
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009276 sta = get_param(cmd, "peer");
9277 if (sta == NULL)
9278 sta = get_param(cmd, "station");
9279 if (sta == NULL) {
9280 send_resp(dut, conn, SIGMA_ERROR,
9281 "ErrorCode,Missing peer address");
9282 return 0;
9283 }
9284 if (hwaddr_aton(sta, addr) < 0) {
9285 send_resp(dut, conn, SIGMA_ERROR,
9286 "ErrorCode,Invalid peer address");
9287 return 0;
9288 }
9289
9290 val = get_param(cmd, "type");
9291 if (val == NULL)
9292 return -1;
9293
9294 if (strcasecmp(val, "DISCOVERY") == 0) {
9295 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", sta);
9296 if (wpa_command(intf, buf) < 0) {
9297 send_resp(dut, conn, SIGMA_ERROR,
9298 "ErrorCode,Failed to send TDLS discovery");
9299 return 0;
9300 }
9301 return 1;
9302 }
9303
9304 if (strcasecmp(val, "SETUP") == 0) {
9305 int status = 0, timeout = 0;
9306
9307 val = get_param(cmd, "Status");
9308 if (val)
9309 status = atoi(val);
9310
9311 val = get_param(cmd, "Timeout");
9312 if (val)
9313 timeout = atoi(val);
9314
9315 if (status != 0 && status != 37) {
9316 send_resp(dut, conn, SIGMA_ERROR,
9317 "ErrorCode,Unsupported status value");
9318 return 0;
9319 }
9320
9321 if (timeout != 0 && timeout != 301) {
9322 send_resp(dut, conn, SIGMA_ERROR,
9323 "ErrorCode,Unsupported timeout value");
9324 return 0;
9325 }
9326
9327 if (status && timeout) {
9328 send_resp(dut, conn, SIGMA_ERROR,
9329 "ErrorCode,Unsupported timeout+status "
9330 "combination");
9331 return 0;
9332 }
9333
9334 if (status == 37 &&
9335 wpa_command(intf, "SET tdls_testing 0x200")) {
9336 send_resp(dut, conn, SIGMA_ERROR,
9337 "ErrorCode,Failed to enable "
9338 "decline setup response test mode");
9339 return 0;
9340 }
9341
9342 if (timeout == 301) {
9343 int res;
9344 if (dut->no_tpk_expiration)
9345 res = wpa_command(intf,
9346 "SET tdls_testing 0x108");
9347 else
9348 res = wpa_command(intf,
9349 "SET tdls_testing 0x8");
9350 if (res) {
9351 send_resp(dut, conn, SIGMA_ERROR,
9352 "ErrorCode,Failed to set short TPK "
9353 "lifetime");
9354 return 0;
9355 }
9356 }
9357
9358 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", sta);
9359 if (wpa_command(intf, buf) < 0) {
9360 send_resp(dut, conn, SIGMA_ERROR,
9361 "ErrorCode,Failed to send TDLS setup");
9362 return 0;
9363 }
9364 return 1;
9365 }
9366
9367 if (strcasecmp(val, "TEARDOWN") == 0) {
9368 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", sta);
9369 if (wpa_command(intf, buf) < 0) {
9370 send_resp(dut, conn, SIGMA_ERROR,
9371 "ErrorCode,Failed to send TDLS teardown");
9372 return 0;
9373 }
9374 return 1;
9375 }
9376
9377 send_resp(dut, conn, SIGMA_ERROR,
9378 "ErrorCode,Unsupported TDLS frame");
9379 return 0;
9380}
9381
9382
9383static int sta_ap_known(const char *ifname, const char *bssid)
9384{
9385 char buf[4096];
9386
Jouni Malinendd32f192018-09-15 02:55:19 +03009387 snprintf(buf, sizeof(buf), "BSS MASK=1 %s", bssid);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009388 if (wpa_command_resp(ifname, buf, buf, sizeof(buf)) < 0)
9389 return 0;
9390 if (strncmp(buf, "id=", 3) != 0)
9391 return 0;
9392 return 1;
9393}
9394
9395
9396static int sta_scan_ap(struct sigma_dut *dut, const char *ifname,
9397 const char *bssid)
9398{
9399 int res;
9400 struct wpa_ctrl *ctrl;
9401 char buf[256];
9402
9403 if (sta_ap_known(ifname, bssid))
9404 return 0;
9405 sigma_dut_print(dut, DUT_MSG_DEBUG,
9406 "AP not in BSS table - start scan");
9407
9408 ctrl = open_wpa_mon(ifname);
9409 if (ctrl == NULL) {
9410 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
9411 "wpa_supplicant monitor connection");
9412 return -1;
9413 }
9414
9415 if (wpa_command(ifname, "SCAN") < 0) {
9416 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to start scan");
9417 wpa_ctrl_detach(ctrl);
9418 wpa_ctrl_close(ctrl);
9419 return -1;
9420 }
9421
9422 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
9423 buf, sizeof(buf));
9424
9425 wpa_ctrl_detach(ctrl);
9426 wpa_ctrl_close(ctrl);
9427
9428 if (res < 0) {
9429 sigma_dut_print(dut, DUT_MSG_INFO, "Scan did not complete");
9430 return -1;
9431 }
9432
9433 if (sta_ap_known(ifname, bssid))
9434 return 0;
9435 sigma_dut_print(dut, DUT_MSG_INFO, "AP not in BSS table");
9436 return -1;
9437}
9438
9439
9440static int cmd_sta_send_frame_hs2_neighadv(struct sigma_dut *dut,
9441 struct sigma_conn *conn,
9442 struct sigma_cmd *cmd,
9443 const char *intf)
9444{
9445 char buf[200];
9446
9447 snprintf(buf, sizeof(buf), "ndsend 2001:DB8::1 %s", intf);
9448 if (system(buf) != 0) {
9449 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Failed to run "
9450 "ndsend");
9451 return 0;
9452 }
9453
9454 return 1;
9455}
9456
9457
9458static int cmd_sta_send_frame_hs2_neighsolreq(struct sigma_dut *dut,
9459 struct sigma_conn *conn,
9460 struct sigma_cmd *cmd,
9461 const char *intf)
9462{
9463 char buf[200];
9464 const char *ip = get_param(cmd, "SenderIP");
9465
Peng Xu26b356d2017-10-04 17:58:16 -07009466 if (!ip)
9467 return 0;
9468
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009469 snprintf(buf, sizeof(buf), "ndisc6 -nm %s %s -r 4", ip, intf);
9470 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
9471 if (system(buf) == 0) {
9472 sigma_dut_print(dut, DUT_MSG_INFO,
9473 "Neighbor Solicitation got a response "
9474 "for %s@%s", ip, intf);
9475 }
9476
9477 return 1;
9478}
9479
9480
9481static int cmd_sta_send_frame_hs2_arpprobe(struct sigma_dut *dut,
9482 struct sigma_conn *conn,
9483 struct sigma_cmd *cmd,
9484 const char *ifname)
9485{
9486 char buf[200];
9487 const char *ip = get_param(cmd, "SenderIP");
9488
9489 if (ip == NULL) {
9490 send_resp(dut, conn, SIGMA_ERROR,
9491 "ErrorCode,Missing SenderIP parameter");
9492 return 0;
9493 }
9494 snprintf(buf, sizeof(buf), "arping -I %s -D %s -c 4", ifname, ip);
9495 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
9496 if (system(buf) != 0) {
9497 sigma_dut_print(dut, DUT_MSG_INFO, "arping DAD got a response "
9498 "for %s@%s", ip, ifname);
9499 }
9500
9501 return 1;
9502}
9503
9504
9505static int cmd_sta_send_frame_hs2_arpannounce(struct sigma_dut *dut,
9506 struct sigma_conn *conn,
9507 struct sigma_cmd *cmd,
9508 const char *ifname)
9509{
9510 char buf[200];
9511 char ip[16];
9512 int s;
Peng Xub3756882017-10-04 14:39:09 -07009513 struct ifreq ifr;
9514 struct sockaddr_in saddr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009515
9516 s = socket(PF_INET, SOCK_DGRAM, 0);
Peng Xub3756882017-10-04 14:39:09 -07009517 if (s < 0) {
9518 perror("socket");
9519 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009520 }
9521
Peng Xub3756882017-10-04 14:39:09 -07009522 memset(&ifr, 0, sizeof(ifr));
9523 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
9524 if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
9525 sigma_dut_print(dut, DUT_MSG_INFO,
9526 "Failed to get %s IP address: %s",
9527 ifname, strerror(errno));
9528 close(s);
9529 return -1;
9530 }
9531 close(s);
9532
9533 memcpy(&saddr, &ifr.ifr_addr, sizeof(struct sockaddr_in));
9534 strlcpy(ip, inet_ntoa(saddr.sin_addr), sizeof(ip));
9535
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009536 snprintf(buf, sizeof(buf), "arping -I %s -s %s %s -c 4", ifname, ip,
9537 ip);
9538 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
9539 if (system(buf) != 0) {
9540 }
9541
9542 return 1;
9543}
9544
9545
9546static int cmd_sta_send_frame_hs2_arpreply(struct sigma_dut *dut,
9547 struct sigma_conn *conn,
9548 struct sigma_cmd *cmd,
9549 const char *ifname)
9550{
9551 char buf[200], addr[20];
9552 char dst[ETH_ALEN], src[ETH_ALEN];
9553 short ethtype = htons(ETH_P_ARP);
9554 char *pos;
9555 int s, res;
9556 const char *val;
9557 struct sockaddr_in taddr;
9558
9559 val = get_param(cmd, "dest");
9560 if (val)
9561 hwaddr_aton(val, (unsigned char *) dst);
9562
9563 val = get_param(cmd, "DestIP");
9564 if (val)
9565 inet_aton(val, &taddr.sin_addr);
Peng Xu151c9e12017-10-04 14:39:09 -07009566 else
9567 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009568
9569 if (get_wpa_status(get_station_ifname(), "address", addr,
9570 sizeof(addr)) < 0)
9571 return -2;
9572 hwaddr_aton(addr, (unsigned char *) src);
9573
9574 pos = buf;
9575 *pos++ = 0x00;
9576 *pos++ = 0x01;
9577 *pos++ = 0x08;
9578 *pos++ = 0x00;
9579 *pos++ = 0x06;
9580 *pos++ = 0x04;
9581 *pos++ = 0x00;
9582 *pos++ = 0x02;
9583 memcpy(pos, src, ETH_ALEN);
9584 pos += ETH_ALEN;
9585 memcpy(pos, &taddr.sin_addr, 4);
9586 pos += 4;
9587 memcpy(pos, dst, ETH_ALEN);
9588 pos += ETH_ALEN;
9589 memcpy(pos, &taddr.sin_addr, 4);
9590 pos += 4;
9591
9592 s = open_monitor(get_station_ifname());
9593 if (s < 0) {
9594 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
9595 "monitor socket");
9596 return 0;
9597 }
9598
9599 res = inject_eth_frame(s, buf, pos - buf, ethtype, dst, src);
9600 if (res < 0) {
9601 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
9602 "inject frame");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05309603 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009604 return 0;
9605 }
9606
9607 close(s);
9608
9609 return 1;
9610}
9611
9612
9613static int cmd_sta_send_frame_hs2_dls_req(struct sigma_dut *dut,
9614 struct sigma_conn *conn,
9615 struct sigma_cmd *cmd,
9616 const char *intf, const char *dest)
9617{
9618 char buf[100];
9619
9620 if (if_nametoindex("sigmadut") == 0) {
9621 snprintf(buf, sizeof(buf),
9622 "iw dev %s interface add sigmadut type monitor",
9623 get_station_ifname());
9624 if (system(buf) != 0 ||
9625 if_nametoindex("sigmadut") == 0) {
9626 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
9627 "monitor interface with '%s'", buf);
9628 return -2;
9629 }
9630 }
9631
9632 if (system("ifconfig sigmadut up") != 0) {
9633 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
9634 "monitor interface up");
9635 return -2;
9636 }
9637
9638 return sta_inject_frame(dut, conn, DLS_REQ, UNPROTECTED, dest);
9639}
9640
9641
9642static int cmd_sta_send_frame_hs2(struct sigma_dut *dut,
9643 struct sigma_conn *conn,
9644 struct sigma_cmd *cmd)
9645{
9646 const char *intf = get_param(cmd, "Interface");
9647 const char *dest = get_param(cmd, "Dest");
9648 const char *type = get_param(cmd, "FrameName");
9649 const char *val;
9650 char buf[200], *pos, *end;
9651 int count, count2;
9652
9653 if (type == NULL)
9654 type = get_param(cmd, "Type");
9655
9656 if (intf == NULL || dest == NULL || type == NULL)
9657 return -1;
9658
9659 if (strcasecmp(type, "NeighAdv") == 0)
9660 return cmd_sta_send_frame_hs2_neighadv(dut, conn, cmd, intf);
9661
9662 if (strcasecmp(type, "NeighSolicitReq") == 0)
9663 return cmd_sta_send_frame_hs2_neighsolreq(dut, conn, cmd, intf);
9664
9665 if (strcasecmp(type, "ARPProbe") == 0)
9666 return cmd_sta_send_frame_hs2_arpprobe(dut, conn, cmd, intf);
9667
9668 if (strcasecmp(type, "ARPAnnounce") == 0)
9669 return cmd_sta_send_frame_hs2_arpannounce(dut, conn, cmd, intf);
9670
9671 if (strcasecmp(type, "ARPReply") == 0)
9672 return cmd_sta_send_frame_hs2_arpreply(dut, conn, cmd, intf);
9673
9674 if (strcasecmp(type, "DLS-request") == 0 ||
9675 strcasecmp(type, "DLSrequest") == 0)
9676 return cmd_sta_send_frame_hs2_dls_req(dut, conn, cmd, intf,
9677 dest);
9678
9679 if (strcasecmp(type, "ANQPQuery") != 0 &&
9680 strcasecmp(type, "Query") != 0) {
9681 send_resp(dut, conn, SIGMA_ERROR,
9682 "ErrorCode,Unsupported HS 2.0 send frame type");
9683 return 0;
9684 }
9685
9686 if (sta_scan_ap(dut, intf, dest) < 0) {
9687 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not find "
9688 "the requested AP");
9689 return 0;
9690 }
9691
9692 pos = buf;
9693 end = buf + sizeof(buf);
9694 count = 0;
9695 pos += snprintf(pos, end - pos, "ANQP_GET %s ", dest);
9696
9697 val = get_param(cmd, "ANQP_CAP_LIST");
9698 if (val && atoi(val)) {
9699 pos += snprintf(pos, end - pos, "%s257", count > 0 ? "," : "");
9700 count++;
9701 }
9702
9703 val = get_param(cmd, "VENUE_NAME");
9704 if (val && atoi(val)) {
9705 pos += snprintf(pos, end - pos, "%s258", count > 0 ? "," : "");
9706 count++;
9707 }
9708
9709 val = get_param(cmd, "NETWORK_AUTH_TYPE");
9710 if (val && atoi(val)) {
9711 pos += snprintf(pos, end - pos, "%s260", count > 0 ? "," : "");
9712 count++;
9713 }
9714
9715 val = get_param(cmd, "ROAMING_CONS");
9716 if (val && atoi(val)) {
9717 pos += snprintf(pos, end - pos, "%s261", count > 0 ? "," : "");
9718 count++;
9719 }
9720
9721 val = get_param(cmd, "IP_ADDR_TYPE_AVAILABILITY");
9722 if (val && atoi(val)) {
9723 pos += snprintf(pos, end - pos, "%s262", count > 0 ? "," : "");
9724 count++;
9725 }
9726
9727 val = get_param(cmd, "NAI_REALM_LIST");
9728 if (val && atoi(val)) {
9729 pos += snprintf(pos, end - pos, "%s263", count > 0 ? "," : "");
9730 count++;
9731 }
9732
9733 val = get_param(cmd, "3GPP_INFO");
9734 if (val && atoi(val)) {
9735 pos += snprintf(pos, end - pos, "%s264", count > 0 ? "," : "");
9736 count++;
9737 }
9738
9739 val = get_param(cmd, "DOMAIN_LIST");
9740 if (val && atoi(val)) {
9741 pos += snprintf(pos, end - pos, "%s268", count > 0 ? "," : "");
9742 count++;
9743 }
9744
Jouni Malinen34cf9532018-04-29 19:26:33 +03009745 val = get_param(cmd, "Venue_URL");
9746 if (val && atoi(val)) {
9747 pos += snprintf(pos, end - pos, "%s277", count > 0 ? "," : "");
9748 count++;
9749 }
9750
Jouni Malinend3bca5d2018-04-29 17:25:23 +03009751 val = get_param(cmd, "Advice_Of_Charge");
9752 if (val && atoi(val)) {
9753 pos += snprintf(pos, end - pos, "%s278", count > 0 ? "," : "");
9754 count++;
9755 }
9756
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009757 if (count && wpa_command(intf, buf)) {
9758 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,ANQP_GET failed");
9759 return 0;
9760 }
9761
9762 pos = buf;
9763 end = buf + sizeof(buf);
9764 count2 = 0;
9765 pos += snprintf(pos, end - pos, "HS20_ANQP_GET %s ", dest);
9766
9767 val = get_param(cmd, "HS_CAP_LIST");
9768 if (val && atoi(val)) {
9769 pos += snprintf(pos, end - pos, "%s2", count2 > 0 ? "," : "");
9770 count2++;
9771 }
9772
9773 val = get_param(cmd, "OPER_NAME");
9774 if (val && atoi(val)) {
9775 pos += snprintf(pos, end - pos, "%s3", count2 > 0 ? "," : "");
9776 count2++;
9777 }
9778
9779 val = get_param(cmd, "WAN_METRICS");
9780 if (!val)
9781 val = get_param(cmd, "WAN_MAT");
9782 if (!val)
9783 val = get_param(cmd, "WAN_MET");
9784 if (val && atoi(val)) {
9785 pos += snprintf(pos, end - pos, "%s4", count2 > 0 ? "," : "");
9786 count2++;
9787 }
9788
9789 val = get_param(cmd, "CONNECTION_CAPABILITY");
9790 if (val && atoi(val)) {
9791 pos += snprintf(pos, end - pos, "%s5", count2 > 0 ? "," : "");
9792 count2++;
9793 }
9794
9795 val = get_param(cmd, "OP_CLASS");
9796 if (val && atoi(val)) {
9797 pos += snprintf(pos, end - pos, "%s7", count2 > 0 ? "," : "");
9798 count2++;
9799 }
9800
9801 val = get_param(cmd, "OSU_PROVIDER_LIST");
9802 if (val && atoi(val)) {
9803 pos += snprintf(pos, end - pos, "%s8", count2 > 0 ? "," : "");
9804 count2++;
9805 }
9806
Jouni Malinenf67afec2018-04-29 19:24:58 +03009807 val = get_param(cmd, "OPER_ICON_METADATA");
9808 if (!val)
9809 val = get_param(cmd, "OPERATOR_ICON_METADATA");
9810 if (val && atoi(val)) {
9811 pos += snprintf(pos, end - pos, "%s12", count2 > 0 ? "," : "");
9812 count2++;
9813 }
9814
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009815 if (count && count2) {
9816 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before sending out "
9817 "second query");
9818 sleep(1);
9819 }
9820
9821 if (count2 && wpa_command(intf, buf)) {
9822 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,HS20_ANQP_GET "
9823 "failed");
9824 return 0;
9825 }
9826
9827 val = get_param(cmd, "NAI_HOME_REALM_LIST");
9828 if (val) {
9829 if (count || count2) {
9830 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
9831 "sending out second query");
9832 sleep(1);
9833 }
9834
9835 if (strcmp(val, "1") == 0)
9836 val = "mail.example.com";
9837 snprintf(buf, end - pos,
9838 "HS20_GET_NAI_HOME_REALM_LIST %s realm=%s",
9839 dest, val);
9840 if (wpa_command(intf, buf)) {
9841 send_resp(dut, conn, SIGMA_ERROR,
9842 "ErrorCode,HS20_GET_NAI_HOME_REALM_LIST "
9843 "failed");
9844 return 0;
9845 }
9846 }
9847
9848 val = get_param(cmd, "ICON_REQUEST");
9849 if (val) {
9850 if (count || count2) {
9851 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
9852 "sending out second query");
9853 sleep(1);
9854 }
9855
9856 snprintf(buf, end - pos,
9857 "HS20_ICON_REQUEST %s %s", dest, val);
9858 if (wpa_command(intf, buf)) {
9859 send_resp(dut, conn, SIGMA_ERROR,
9860 "ErrorCode,HS20_ICON_REQUEST failed");
9861 return 0;
9862 }
9863 }
9864
9865 return 1;
9866}
9867
9868
9869static int ath_sta_send_frame_vht(struct sigma_dut *dut,
9870 struct sigma_conn *conn,
9871 struct sigma_cmd *cmd)
9872{
9873 const char *val;
9874 char *ifname;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009875 int chwidth, nss;
9876
9877 val = get_param(cmd, "framename");
9878 if (!val)
9879 return -1;
9880 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
9881
9882 /* Command sequence to generate Op mode notification */
9883 if (val && strcasecmp(val, "Op_md_notif_frm") == 0) {
9884 ifname = get_station_ifname();
9885
9886 /* Disable STBC */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07009887 run_iwpriv(dut, ifname, "tx_stbc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009888
9889 /* Extract Channel width */
9890 val = get_param(cmd, "Channel_width");
9891 if (val) {
9892 switch (atoi(val)) {
9893 case 20:
9894 chwidth = 0;
9895 break;
9896 case 40:
9897 chwidth = 1;
9898 break;
9899 case 80:
9900 chwidth = 2;
9901 break;
9902 case 160:
9903 chwidth = 3;
9904 break;
9905 default:
9906 chwidth = 2;
9907 break;
9908 }
9909
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07009910 run_iwpriv(dut, ifname, "chwidth %d", chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009911 }
9912
9913 /* Extract NSS */
9914 val = get_param(cmd, "NSS");
9915 if (val) {
9916 switch (atoi(val)) {
9917 case 1:
9918 nss = 1;
9919 break;
9920 case 2:
9921 nss = 3;
9922 break;
9923 case 3:
9924 nss = 7;
9925 break;
9926 default:
9927 /* We do not support NSS > 3 */
9928 nss = 3;
9929 break;
9930 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07009931 run_iwpriv(dut, ifname, "rxchainmask %d", nss);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009932 }
9933
9934 /* Opmode notify */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07009935 run_iwpriv(dut, ifname, "opmode_notify 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009936 }
9937
9938 return 1;
9939}
9940
9941
9942static int cmd_sta_send_frame_vht(struct sigma_dut *dut,
9943 struct sigma_conn *conn,
9944 struct sigma_cmd *cmd)
9945{
9946 switch (get_driver_type()) {
9947 case DRIVER_ATHEROS:
9948 return ath_sta_send_frame_vht(dut, conn, cmd);
9949 default:
9950 send_resp(dut, conn, SIGMA_ERROR,
9951 "errorCode,Unsupported sta_set_frame(VHT) with the current driver");
9952 return 0;
9953 }
9954}
9955
9956
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07009957static int wcn_sta_send_frame_he(struct sigma_dut *dut, struct sigma_conn *conn,
9958 struct sigma_cmd *cmd)
9959{
9960 const char *val;
9961 const char *intf = get_param(cmd, "Interface");
9962
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +03009963 if (!intf)
9964 return -1;
9965
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07009966 val = get_param(cmd, "framename");
9967 if (!val)
9968 return -1;
9969 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
9970
9971 /* Command sequence to generate Op mode notification */
9972 if (val && strcasecmp(val, "action") == 0) {
9973 val = get_param(cmd, "PPDUTxType");
9974 if (val && strcasecmp(val, "TB") == 0) {
9975 if (sta_set_action_tx_in_he_tb_ppdu(dut, intf, 1)) {
9976 sigma_dut_print(dut, DUT_MSG_ERROR,
9977 "failed to send TB PPDU Tx cfg");
9978 send_resp(dut, conn, SIGMA_ERROR,
9979 "ErrorCode,set TB PPDU Tx cfg failed");
9980 return 0;
9981 }
9982 return 1;
9983 }
9984
9985 sigma_dut_print(dut, DUT_MSG_ERROR,
9986 "Action Tx type is not defined");
9987 }
9988
9989 return 1;
9990}
9991
9992
9993static int cmd_sta_send_frame_he(struct sigma_dut *dut,
9994 struct sigma_conn *conn,
9995 struct sigma_cmd *cmd)
9996{
9997 switch (get_driver_type()) {
9998 case DRIVER_WCN:
9999 return wcn_sta_send_frame_he(dut, conn, cmd);
10000 default:
10001 send_resp(dut, conn, SIGMA_ERROR,
10002 "errorCode,Unsupported sta_set_frame(HE) with the current driver");
10003 return 0;
10004 }
10005}
10006
10007
Lior David0fe101e2017-03-09 16:09:50 +020010008#ifdef __linux__
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030010009
10010static int
10011wil6210_send_p2p_frame_60g(struct sigma_dut *dut, struct sigma_cmd *cmd,
10012 const char *frame_name, const char *dest_mac)
10013{
10014 int isprobereq = strcasecmp(frame_name, "probereq") == 0;
10015 const char *ssid = get_param(cmd, "ssid");
10016 const char *countstr = get_param(cmd, "count");
10017 const char *channelstr = get_param(cmd, "channel");
10018 const char *group_id = get_param(cmd, "groupid");
10019 const char *client_id = get_param(cmd, "clientmac");
10020 int count, channel, freq, i;
10021 const char *fname;
10022 char frame[1024], src_mac[20], group_id_attr[25],
10023 device_macstr[3 * ETH_ALEN], client_mac[ETH_ALEN];
10024 const char *group_ssid;
10025 const int group_ssid_prefix_len = 9;
10026 struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *) frame;
10027 size_t framelen = sizeof(frame);
10028 struct template_frame_tag tags[2];
10029 size_t tags_total = ARRAY_SIZE(tags);
10030 int tag_index, len, dst_len;
10031
10032 if (!countstr || !channelstr) {
10033 sigma_dut_print(dut, DUT_MSG_ERROR,
10034 "Missing argument: count, channel");
10035 return -1;
10036 }
10037 if (isprobereq && !ssid) {
10038 sigma_dut_print(dut, DUT_MSG_ERROR,
10039 "Missing argument: ssid");
10040 return -1;
10041 }
10042 if (!isprobereq && (!group_id || !client_id)) {
10043 sigma_dut_print(dut, DUT_MSG_ERROR,
10044 "Missing argument: group_id, client_id");
10045 return -1;
10046 }
10047
10048 count = atoi(countstr);
10049 channel = atoi(channelstr);
10050 freq = channel_to_freq(dut, channel);
10051
10052 if (!freq) {
10053 sigma_dut_print(dut, DUT_MSG_ERROR,
10054 "invalid channel: %s", channelstr);
10055 return -1;
10056 }
10057
10058 if (isprobereq) {
10059 if (strcasecmp(ssid, "wildcard") == 0) {
10060 fname = "probe_req_wildcard.txt";
10061 } else if (strcasecmp(ssid, "P2P_Wildcard") == 0) {
10062 fname = "probe_req_P2P_Wildcard.txt";
10063 } else {
10064 sigma_dut_print(dut, DUT_MSG_ERROR,
10065 "invalid probe request type");
10066 return -1;
10067 }
10068 } else {
10069 fname = "P2P_device_discovery_req.txt";
10070 }
10071
10072 if (parse_template_frame_file(dut, fname, frame, &framelen,
10073 tags, &tags_total)) {
10074 sigma_dut_print(dut, DUT_MSG_ERROR,
10075 "invalid frame template: %s", fname);
10076 return -1;
10077 }
10078
10079 if (get_wpa_status(get_station_ifname(), "address",
10080 src_mac, sizeof(src_mac)) < 0 ||
10081 parse_mac_address(dut, src_mac, &hdr->addr2[0]) ||
10082 parse_mac_address(dut, dest_mac, &hdr->addr1[0]))
10083 return -1;
10084 /* Use wildcard BSSID, since we are in PBSS */
10085 memset(&hdr->addr3, 0xFF, ETH_ALEN);
10086
10087 if (!isprobereq) {
10088 tag_index = find_template_frame_tag(tags, tags_total, 1);
10089 if (tag_index < 0) {
10090 sigma_dut_print(dut, DUT_MSG_ERROR,
10091 "can't find device id attribute");
10092 return -1;
10093 }
10094 if (parse_mac_address(dut, client_id,
10095 (unsigned char *) client_mac)) {
10096 sigma_dut_print(dut, DUT_MSG_ERROR,
10097 "invalid client_id: %s", client_id);
10098 return -1;
10099 }
10100 if (replace_p2p_attribute(dut, &frame[tags[tag_index].offset],
10101 framelen - tags[tag_index].offset,
10102 IEEE80211_P2P_ATTR_DEVICE_ID,
10103 client_mac, ETH_ALEN)) {
10104 sigma_dut_print(dut, DUT_MSG_ERROR,
10105 "fail to replace device id attribute");
10106 return -1;
10107 }
10108
10109 /*
10110 * group_id arg contains device MAC address followed by
10111 * space and SSID (DIRECT-somessid).
10112 * group id attribute contains device address (6 bytes)
10113 * followed by SSID prefix DIRECT-XX (9 bytes)
10114 */
10115 if (strlen(group_id) < sizeof(device_macstr)) {
10116 sigma_dut_print(dut, DUT_MSG_ERROR,
10117 "group_id arg too short");
10118 return -1;
10119 }
10120 memcpy(device_macstr, group_id, sizeof(device_macstr));
10121 device_macstr[sizeof(device_macstr) - 1] = '\0';
10122 if (parse_mac_address(dut, device_macstr,
10123 (unsigned char *) group_id_attr)) {
10124 sigma_dut_print(dut, DUT_MSG_ERROR,
10125 "fail to parse device address from group_id");
10126 return -1;
10127 }
10128 group_ssid = strchr(group_id, ' ');
10129 if (!group_ssid) {
10130 sigma_dut_print(dut, DUT_MSG_ERROR,
10131 "invalid group_id arg, no ssid");
10132 return -1;
10133 }
10134 group_ssid++;
10135 len = strlen(group_ssid);
10136 if (len < group_ssid_prefix_len) {
10137 sigma_dut_print(dut, DUT_MSG_ERROR,
10138 "group_id SSID too short");
10139 return -1;
10140 }
10141 dst_len = sizeof(group_id_attr) - ETH_ALEN;
10142 if (len > dst_len) {
10143 sigma_dut_print(dut, DUT_MSG_ERROR,
10144 "group_id SSID (%s) too long",
10145 group_ssid);
10146 return -1;
10147 }
10148
10149 memcpy(group_id_attr + ETH_ALEN, group_ssid, len);
10150 tag_index = find_template_frame_tag(tags, tags_total, 2);
10151 if (tag_index < 0) {
10152 sigma_dut_print(dut, DUT_MSG_ERROR,
10153 "can't find group id attribute");
10154 return -1;
10155 }
10156 if (replace_p2p_attribute(dut, &frame[tags[tag_index].offset],
10157 framelen - tags[tag_index].offset,
10158 IEEE80211_P2P_ATTR_GROUP_ID,
10159 group_id_attr,
10160 sizeof(group_id_attr))) {
10161 sigma_dut_print(dut, DUT_MSG_ERROR,
10162 "fail to replace group id attribute");
10163 return -1;
10164 }
10165 }
10166
10167 for (i = 0; i < count; i++) {
10168 if (wil6210_transmit_frame(dut, freq,
10169 WIL_TRANSMIT_FRAME_DEFAULT_ROC,
10170 frame, framelen)) {
10171 sigma_dut_print(dut, DUT_MSG_ERROR,
10172 "fail to transmit probe request frame");
10173 return -1;
10174 }
10175 }
10176
10177 return 0;
10178}
10179
10180
Lior David0fe101e2017-03-09 16:09:50 +020010181int wil6210_send_frame_60g(struct sigma_dut *dut, struct sigma_conn *conn,
10182 struct sigma_cmd *cmd)
10183{
10184 const char *frame_name = get_param(cmd, "framename");
10185 const char *mac = get_param(cmd, "dest_mac");
10186
10187 if (!frame_name || !mac) {
10188 sigma_dut_print(dut, DUT_MSG_ERROR,
10189 "framename and dest_mac must be provided");
10190 return -1;
10191 }
10192
10193 if (strcasecmp(frame_name, "brp") == 0) {
10194 const char *l_rx = get_param(cmd, "L-RX");
10195 int l_rx_i;
10196
10197 if (!l_rx) {
10198 sigma_dut_print(dut, DUT_MSG_ERROR,
10199 "L-RX must be provided");
10200 return -1;
10201 }
10202 l_rx_i = atoi(l_rx);
10203
10204 sigma_dut_print(dut, DUT_MSG_INFO,
10205 "dev_send_frame: BRP-RX, dest_mac %s, L-RX %s",
10206 mac, l_rx);
10207 if (l_rx_i != 16) {
10208 sigma_dut_print(dut, DUT_MSG_ERROR,
10209 "unsupported L-RX: %s", l_rx);
10210 return -1;
10211 }
10212
10213 if (wil6210_send_brp_rx(dut, mac, l_rx_i))
10214 return -1;
10215 } else if (strcasecmp(frame_name, "ssw") == 0) {
10216 sigma_dut_print(dut, DUT_MSG_INFO,
10217 "dev_send_frame: SLS, dest_mac %s", mac);
10218 if (wil6210_send_sls(dut, mac))
10219 return -1;
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030010220 } else if ((strcasecmp(frame_name, "probereq") == 0) ||
10221 (strcasecmp(frame_name, "devdiscreq") == 0)) {
10222 sigma_dut_print(dut, DUT_MSG_INFO,
10223 "dev_send_frame: %s, dest_mac %s", frame_name,
10224 mac);
10225 if (wil6210_send_p2p_frame_60g(dut, cmd, frame_name, mac))
10226 return -1;
Lior David0fe101e2017-03-09 16:09:50 +020010227 } else {
10228 sigma_dut_print(dut, DUT_MSG_ERROR,
10229 "unsupported frame type: %s", frame_name);
10230 return -1;
10231 }
10232
10233 return 1;
10234}
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030010235
Lior David0fe101e2017-03-09 16:09:50 +020010236#endif /* __linux__ */
10237
10238
10239static int cmd_sta_send_frame_60g(struct sigma_dut *dut,
10240 struct sigma_conn *conn,
10241 struct sigma_cmd *cmd)
10242{
10243 switch (get_driver_type()) {
10244#ifdef __linux__
10245 case DRIVER_WIL6210:
10246 return wil6210_send_frame_60g(dut, conn, cmd);
10247#endif /* __linux__ */
10248 default:
10249 send_resp(dut, conn, SIGMA_ERROR,
10250 "errorCode,Unsupported sta_set_frame(60G) with the current driver");
10251 return 0;
10252 }
10253}
10254
10255
Ashwini Patildb59b3c2017-04-13 15:19:23 +053010256static int mbo_send_anqp_query(struct sigma_dut *dut, struct sigma_conn *conn,
10257 const char *intf, struct sigma_cmd *cmd)
10258{
10259 const char *val, *addr;
10260 char buf[100];
10261
10262 addr = get_param(cmd, "DestMac");
10263 if (!addr) {
10264 send_resp(dut, conn, SIGMA_INVALID,
10265 "ErrorCode,AP MAC address is missing");
10266 return 0;
10267 }
10268
10269 val = get_param(cmd, "ANQPQuery_ID");
10270 if (!val) {
10271 send_resp(dut, conn, SIGMA_INVALID,
10272 "ErrorCode,Missing ANQPQuery_ID");
10273 return 0;
10274 }
10275
10276 if (strcasecmp(val, "NeighborReportReq") == 0) {
10277 snprintf(buf, sizeof(buf), "ANQP_GET %s 272", addr);
10278 } else if (strcasecmp(val, "QueryListWithCellPref") == 0) {
10279 snprintf(buf, sizeof(buf), "ANQP_GET %s 272,mbo:2", addr);
10280 } else {
10281 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid ANQPQuery_ID: %s",
10282 val);
10283 send_resp(dut, conn, SIGMA_INVALID,
10284 "ErrorCode,Invalid ANQPQuery_ID");
10285 return 0;
10286 }
10287
Ashwini Patild174f2c2017-04-13 16:49:46 +053010288 /* Set gas_address3 field to IEEE 802.11-2012 standard compliant form
10289 * (Address3 = Wildcard BSSID when sent to not-associated AP;
10290 * if associated, AP BSSID).
10291 */
10292 if (wpa_command(intf, "SET gas_address3 1") < 0) {
10293 send_resp(dut, conn, SIGMA_ERROR,
10294 "ErrorCode,Failed to set gas_address3");
10295 return 0;
10296 }
10297
Ashwini Patildb59b3c2017-04-13 15:19:23 +053010298 if (wpa_command(intf, buf) < 0) {
10299 send_resp(dut, conn, SIGMA_ERROR,
10300 "ErrorCode,Failed to send ANQP query");
10301 return 0;
10302 }
10303
10304 return 1;
10305}
10306
10307
10308static int mbo_cmd_sta_send_frame(struct sigma_dut *dut,
10309 struct sigma_conn *conn,
10310 const char *intf,
10311 struct sigma_cmd *cmd)
10312{
10313 const char *val = get_param(cmd, "FrameName");
10314
10315 if (val && strcasecmp(val, "ANQPQuery") == 0)
10316 return mbo_send_anqp_query(dut, conn, intf, cmd);
10317
10318 return 2;
10319}
10320
10321
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010322int cmd_sta_send_frame(struct sigma_dut *dut, struct sigma_conn *conn,
10323 struct sigma_cmd *cmd)
10324{
10325 const char *intf = get_param(cmd, "Interface");
10326 const char *val;
10327 enum send_frame_type frame;
10328 enum send_frame_protection protected;
10329 char buf[100];
10330 unsigned char addr[ETH_ALEN];
10331 int res;
10332
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +030010333 if (!intf)
10334 return -1;
10335
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010336 val = get_param(cmd, "program");
10337 if (val == NULL)
10338 val = get_param(cmd, "frame");
10339 if (val && strcasecmp(val, "TDLS") == 0)
10340 return cmd_sta_send_frame_tdls(dut, conn, cmd);
10341 if (val && (strcasecmp(val, "HS2") == 0 ||
Jouni Malinen1f6ae642018-06-07 23:56:13 +030010342 strcasecmp(val, "HS2-R2") == 0 ||
10343 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010344 return cmd_sta_send_frame_hs2(dut, conn, cmd);
10345 if (val && strcasecmp(val, "VHT") == 0)
10346 return cmd_sta_send_frame_vht(dut, conn, cmd);
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070010347 if (val && strcasecmp(val, "HE") == 0)
10348 return cmd_sta_send_frame_he(dut, conn, cmd);
priyadharshini gowthamand66913a2016-07-29 15:11:17 -070010349 if (val && strcasecmp(val, "LOC") == 0)
10350 return loc_cmd_sta_send_frame(dut, conn, cmd);
Lior David0fe101e2017-03-09 16:09:50 +020010351 if (val && strcasecmp(val, "60GHz") == 0)
10352 return cmd_sta_send_frame_60g(dut, conn, cmd);
Ashwini Patildb59b3c2017-04-13 15:19:23 +053010353 if (val && strcasecmp(val, "MBO") == 0) {
10354 res = mbo_cmd_sta_send_frame(dut, conn, intf, cmd);
10355 if (res != 2)
10356 return res;
10357 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010358
10359 val = get_param(cmd, "TD_DISC");
10360 if (val) {
10361 if (hwaddr_aton(val, addr) < 0)
10362 return -1;
10363 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", val);
10364 if (wpa_command(intf, buf) < 0) {
10365 send_resp(dut, conn, SIGMA_ERROR,
10366 "ErrorCode,Failed to send TDLS discovery");
10367 return 0;
10368 }
10369 return 1;
10370 }
10371
10372 val = get_param(cmd, "TD_Setup");
10373 if (val) {
10374 if (hwaddr_aton(val, addr) < 0)
10375 return -1;
10376 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", val);
10377 if (wpa_command(intf, buf) < 0) {
10378 send_resp(dut, conn, SIGMA_ERROR,
10379 "ErrorCode,Failed to start TDLS setup");
10380 return 0;
10381 }
10382 return 1;
10383 }
10384
10385 val = get_param(cmd, "TD_TearDown");
10386 if (val) {
10387 if (hwaddr_aton(val, addr) < 0)
10388 return -1;
10389 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", val);
10390 if (wpa_command(intf, buf) < 0) {
10391 send_resp(dut, conn, SIGMA_ERROR,
10392 "ErrorCode,Failed to tear down TDLS link");
10393 return 0;
10394 }
10395 return 1;
10396 }
10397
10398 val = get_param(cmd, "TD_ChannelSwitch");
10399 if (val) {
10400 /* TODO */
10401 send_resp(dut, conn, SIGMA_ERROR,
10402 "ErrorCode,TD_ChannelSwitch not yet supported");
10403 return 0;
10404 }
10405
10406 val = get_param(cmd, "TD_NF");
10407 if (val) {
10408 /* TODO */
10409 send_resp(dut, conn, SIGMA_ERROR,
10410 "ErrorCode,TD_NF not yet supported");
10411 return 0;
10412 }
10413
10414 val = get_param(cmd, "PMFFrameType");
10415 if (val == NULL)
10416 val = get_param(cmd, "FrameName");
10417 if (val == NULL)
10418 val = get_param(cmd, "Type");
10419 if (val == NULL)
10420 return -1;
10421 if (strcasecmp(val, "disassoc") == 0)
10422 frame = DISASSOC;
10423 else if (strcasecmp(val, "deauth") == 0)
10424 frame = DEAUTH;
10425 else if (strcasecmp(val, "saquery") == 0)
10426 frame = SAQUERY;
10427 else if (strcasecmp(val, "auth") == 0)
10428 frame = AUTH;
10429 else if (strcasecmp(val, "assocreq") == 0)
10430 frame = ASSOCREQ;
10431 else if (strcasecmp(val, "reassocreq") == 0)
10432 frame = REASSOCREQ;
10433 else if (strcasecmp(val, "neigreq") == 0) {
10434 sigma_dut_print(dut, DUT_MSG_INFO, "Got neighbor request");
10435
10436 val = get_param(cmd, "ssid");
10437 if (val == NULL)
10438 return -1;
10439
10440 res = send_neighbor_request(dut, intf, val);
10441 if (res) {
10442 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
10443 "Failed to send neighbor report request");
10444 return 0;
10445 }
10446
10447 return 1;
Ashwini Patil5acd7382017-04-13 15:55:04 +053010448 } else if (strcasecmp(val, "transmgmtquery") == 0 ||
10449 strcasecmp(val, "BTMQuery") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010450 sigma_dut_print(dut, DUT_MSG_DEBUG,
10451 "Got Transition Management Query");
10452
Ashwini Patil5acd7382017-04-13 15:55:04 +053010453 res = send_trans_mgmt_query(dut, intf, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010454 if (res) {
10455 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
10456 "Failed to send Transition Management Query");
10457 return 0;
10458 }
10459
10460 return 1;
10461 } else {
10462 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
10463 "PMFFrameType");
10464 return 0;
10465 }
10466
10467 val = get_param(cmd, "PMFProtected");
10468 if (val == NULL)
10469 val = get_param(cmd, "Protected");
10470 if (val == NULL)
10471 return -1;
10472 if (strcasecmp(val, "Correct-key") == 0 ||
10473 strcasecmp(val, "CorrectKey") == 0)
10474 protected = CORRECT_KEY;
10475 else if (strcasecmp(val, "IncorrectKey") == 0)
10476 protected = INCORRECT_KEY;
10477 else if (strcasecmp(val, "Unprotected") == 0)
10478 protected = UNPROTECTED;
10479 else {
10480 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
10481 "PMFProtected");
10482 return 0;
10483 }
10484
10485 if (protected != UNPROTECTED &&
10486 (frame == AUTH || frame == ASSOCREQ || frame == REASSOCREQ)) {
10487 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Impossible "
10488 "PMFProtected for auth/assocreq/reassocreq");
10489 return 0;
10490 }
10491
10492 if (if_nametoindex("sigmadut") == 0) {
10493 snprintf(buf, sizeof(buf),
10494 "iw dev %s interface add sigmadut type monitor",
10495 get_station_ifname());
10496 if (system(buf) != 0 ||
10497 if_nametoindex("sigmadut") == 0) {
10498 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
10499 "monitor interface with '%s'", buf);
10500 return -2;
10501 }
10502 }
10503
10504 if (system("ifconfig sigmadut up") != 0) {
10505 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
10506 "monitor interface up");
10507 return -2;
10508 }
10509
10510 return sta_inject_frame(dut, conn, frame, protected, NULL);
10511}
10512
10513
10514static int cmd_sta_set_parameter_hs2(struct sigma_dut *dut,
10515 struct sigma_conn *conn,
10516 struct sigma_cmd *cmd,
10517 const char *ifname)
10518{
10519 char buf[200];
10520 const char *val;
10521
10522 val = get_param(cmd, "ClearARP");
10523 if (val && atoi(val) == 1) {
10524 snprintf(buf, sizeof(buf), "ip neigh flush dev %s", ifname);
10525 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10526 if (system(buf) != 0) {
10527 send_resp(dut, conn, SIGMA_ERROR,
10528 "errorCode,Failed to clear ARP cache");
10529 return 0;
10530 }
10531 }
10532
10533 return 1;
10534}
10535
10536
10537int cmd_sta_set_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
10538 struct sigma_cmd *cmd)
10539{
10540 const char *intf = get_param(cmd, "Interface");
10541 const char *val;
10542
10543 if (intf == NULL)
10544 return -1;
10545
10546 val = get_param(cmd, "program");
10547 if (val && (strcasecmp(val, "HS2") == 0 ||
Jouni Malinen1f6ae642018-06-07 23:56:13 +030010548 strcasecmp(val, "HS2-R2") == 0 ||
10549 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010550 return cmd_sta_set_parameter_hs2(dut, conn, cmd, intf);
10551
10552 return -1;
10553}
10554
10555
10556static int cmd_sta_set_macaddr(struct sigma_dut *dut, struct sigma_conn *conn,
10557 struct sigma_cmd *cmd)
10558{
10559 const char *intf = get_param(cmd, "Interface");
10560 const char *mac = get_param(cmd, "MAC");
10561
10562 if (intf == NULL || mac == NULL)
10563 return -1;
10564
10565 sigma_dut_print(dut, DUT_MSG_INFO, "Change local MAC address for "
10566 "interface %s to %s", intf, mac);
10567
10568 if (dut->set_macaddr) {
10569 char buf[128];
10570 int res;
10571 if (strcasecmp(mac, "default") == 0) {
10572 res = snprintf(buf, sizeof(buf), "%s",
10573 dut->set_macaddr);
10574 dut->tmp_mac_addr = 0;
10575 } else {
10576 res = snprintf(buf, sizeof(buf), "%s %s",
10577 dut->set_macaddr, mac);
10578 dut->tmp_mac_addr = 1;
10579 }
10580 if (res < 0 || res >= (int) sizeof(buf))
10581 return -1;
10582 if (system(buf) != 0) {
10583 send_resp(dut, conn, SIGMA_ERROR,
10584 "errorCode,Failed to set MAC "
10585 "address");
10586 return 0;
10587 }
10588 return 1;
10589 }
10590
10591 if (strcasecmp(mac, "default") == 0)
10592 return 1;
10593
10594 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
10595 "command");
10596 return 0;
10597}
10598
10599
10600static int iwpriv_tdlsoffchnmode(struct sigma_dut *dut,
10601 struct sigma_conn *conn, const char *intf,
10602 int val)
10603{
10604 char buf[200];
10605 int res;
10606
10607 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchnmode %d",
10608 intf, val);
10609 if (res < 0 || res >= (int) sizeof(buf))
10610 return -1;
10611 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10612 if (system(buf) != 0) {
10613 send_resp(dut, conn, SIGMA_ERROR,
10614 "errorCode,Failed to configure offchannel mode");
10615 return 0;
10616 }
10617
10618 return 1;
10619}
10620
10621
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010622static int off_chan_val(enum sec_ch_offset off)
10623{
10624 switch (off) {
10625 case SEC_CH_NO:
10626 return 0;
10627 case SEC_CH_40ABOVE:
10628 return 40;
10629 case SEC_CH_40BELOW:
10630 return -40;
10631 }
10632
10633 return 0;
10634}
10635
10636
10637static int iwpriv_set_offchan(struct sigma_dut *dut, struct sigma_conn *conn,
10638 const char *intf, int off_ch_num,
10639 enum sec_ch_offset sec)
10640{
10641 char buf[200];
10642 int res;
10643
10644 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchan %d",
10645 intf, off_ch_num);
10646 if (res < 0 || res >= (int) sizeof(buf))
10647 return -1;
10648 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10649 if (system(buf) != 0) {
10650 send_resp(dut, conn, SIGMA_ERROR,
10651 "errorCode,Failed to set offchan");
10652 return 0;
10653 }
10654
10655 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsecchnoffst %d",
10656 intf, off_chan_val(sec));
10657 if (res < 0 || res >= (int) sizeof(buf))
10658 return -1;
10659 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10660 if (system(buf) != 0) {
10661 send_resp(dut, conn, SIGMA_ERROR,
10662 "errorCode,Failed to set sec chan offset");
10663 return 0;
10664 }
10665
10666 return 1;
10667}
10668
10669
10670static int tdls_set_offchannel_offset(struct sigma_dut *dut,
10671 struct sigma_conn *conn,
10672 const char *intf, int off_ch_num,
10673 enum sec_ch_offset sec)
10674{
10675 char buf[200];
10676 int res;
10677
10678 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNEL %d",
10679 off_ch_num);
10680 if (res < 0 || res >= (int) sizeof(buf))
10681 return -1;
10682 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10683
10684 if (wpa_command(intf, buf) < 0) {
10685 send_resp(dut, conn, SIGMA_ERROR,
10686 "ErrorCode,Failed to set offchan");
10687 return 0;
10688 }
10689 res = snprintf(buf, sizeof(buf), "DRIVER TDLSSECONDARYCHANNELOFFSET %d",
10690 off_chan_val(sec));
10691 if (res < 0 || res >= (int) sizeof(buf))
10692 return -1;
10693
10694 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10695
10696 if (wpa_command(intf, buf) < 0) {
10697 send_resp(dut, conn, SIGMA_ERROR,
10698 "ErrorCode,Failed to set sec chan offset");
10699 return 0;
10700 }
10701
10702 return 1;
10703}
10704
10705
10706static int tdls_set_offchannel_mode(struct sigma_dut *dut,
10707 struct sigma_conn *conn,
10708 const char *intf, int val)
10709{
10710 char buf[200];
10711 int res;
10712
10713 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNELMODE %d",
10714 val);
10715 if (res < 0 || res >= (int) sizeof(buf))
10716 return -1;
10717 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10718
10719 if (wpa_command(intf, buf) < 0) {
10720 send_resp(dut, conn, SIGMA_ERROR,
10721 "ErrorCode,Failed to configure offchannel mode");
10722 return 0;
10723 }
10724
10725 return 1;
10726}
10727
10728
10729static int cmd_sta_set_rfeature_tdls(const char *intf, struct sigma_dut *dut,
10730 struct sigma_conn *conn,
10731 struct sigma_cmd *cmd)
10732{
10733 const char *val;
10734 enum {
10735 CHSM_NOT_SET,
10736 CHSM_ENABLE,
10737 CHSM_DISABLE,
10738 CHSM_REJREQ,
10739 CHSM_UNSOLRESP
10740 } chsm = CHSM_NOT_SET;
10741 int off_ch_num = -1;
10742 enum sec_ch_offset sec_ch = SEC_CH_NO;
10743 int res;
10744
10745 val = get_param(cmd, "Uapsd");
10746 if (val) {
10747 char buf[100];
10748 if (strcasecmp(val, "Enable") == 0)
10749 snprintf(buf, sizeof(buf), "SET ps 99");
10750 else if (strcasecmp(val, "Disable") == 0)
10751 snprintf(buf, sizeof(buf), "SET ps 98");
10752 else {
10753 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
10754 "Unsupported uapsd parameter value");
10755 return 0;
10756 }
10757 if (wpa_command(intf, buf)) {
10758 send_resp(dut, conn, SIGMA_ERROR,
10759 "ErrorCode,Failed to change U-APSD "
10760 "powersave mode");
10761 return 0;
10762 }
10763 }
10764
10765 val = get_param(cmd, "TPKTIMER");
10766 if (val && strcasecmp(val, "DISABLE") == 0) {
10767 if (wpa_command(intf, "SET tdls_testing 0x100")) {
10768 send_resp(dut, conn, SIGMA_ERROR,
10769 "ErrorCode,Failed to enable no TPK "
10770 "expiration test mode");
10771 return 0;
10772 }
10773 dut->no_tpk_expiration = 1;
10774 }
10775
10776 val = get_param(cmd, "ChSwitchMode");
10777 if (val) {
10778 if (strcasecmp(val, "Enable") == 0 ||
10779 strcasecmp(val, "Initiate") == 0)
10780 chsm = CHSM_ENABLE;
10781 else if (strcasecmp(val, "Disable") == 0 ||
10782 strcasecmp(val, "passive") == 0)
10783 chsm = CHSM_DISABLE;
10784 else if (strcasecmp(val, "RejReq") == 0)
10785 chsm = CHSM_REJREQ;
10786 else if (strcasecmp(val, "UnSolResp") == 0)
10787 chsm = CHSM_UNSOLRESP;
10788 else {
10789 send_resp(dut, conn, SIGMA_ERROR,
10790 "ErrorCode,Unknown ChSwitchMode value");
10791 return 0;
10792 }
10793 }
10794
10795 val = get_param(cmd, "OffChNum");
10796 if (val) {
10797 off_ch_num = atoi(val);
10798 if (off_ch_num == 0) {
10799 send_resp(dut, conn, SIGMA_ERROR,
10800 "ErrorCode,Invalid OffChNum");
10801 return 0;
10802 }
10803 }
10804
10805 val = get_param(cmd, "SecChOffset");
10806 if (val) {
10807 if (strcmp(val, "20") == 0)
10808 sec_ch = SEC_CH_NO;
10809 else if (strcasecmp(val, "40above") == 0)
10810 sec_ch = SEC_CH_40ABOVE;
10811 else if (strcasecmp(val, "40below") == 0)
10812 sec_ch = SEC_CH_40BELOW;
10813 else {
10814 send_resp(dut, conn, SIGMA_ERROR,
10815 "ErrorCode,Unknown SecChOffset value");
10816 return 0;
10817 }
10818 }
10819
10820 if (chsm == CHSM_NOT_SET) {
10821 /* no offchannel changes requested */
10822 return 1;
10823 }
10824
10825 if (strcmp(intf, get_main_ifname()) != 0 &&
10826 strcmp(intf, get_station_ifname()) != 0) {
10827 send_resp(dut, conn, SIGMA_ERROR,
10828 "ErrorCode,Unknown interface");
10829 return 0;
10830 }
10831
10832 switch (chsm) {
10833 case CHSM_NOT_SET:
Jouni Malinen280f5ba2016-08-29 21:33:10 +030010834 res = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010835 break;
10836 case CHSM_ENABLE:
10837 if (off_ch_num < 0) {
10838 send_resp(dut, conn, SIGMA_ERROR,
10839 "ErrorCode,Missing OffChNum argument");
10840 return 0;
10841 }
10842 if (wifi_chip_type == DRIVER_WCN) {
10843 res = tdls_set_offchannel_offset(dut, conn, intf,
10844 off_ch_num, sec_ch);
10845 } else {
10846 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
10847 sec_ch);
10848 }
10849 if (res != 1)
10850 return res;
10851 if (wifi_chip_type == DRIVER_WCN)
10852 res = tdls_set_offchannel_mode(dut, conn, intf, 1);
10853 else
10854 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 1);
10855 break;
10856 case CHSM_DISABLE:
10857 if (wifi_chip_type == DRIVER_WCN)
10858 res = tdls_set_offchannel_mode(dut, conn, intf, 2);
10859 else
10860 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 2);
10861 break;
10862 case CHSM_REJREQ:
10863 if (wifi_chip_type == DRIVER_WCN)
10864 res = tdls_set_offchannel_mode(dut, conn, intf, 3);
10865 else
10866 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 3);
10867 break;
10868 case CHSM_UNSOLRESP:
10869 if (off_ch_num < 0) {
10870 send_resp(dut, conn, SIGMA_ERROR,
10871 "ErrorCode,Missing OffChNum argument");
10872 return 0;
10873 }
10874 if (wifi_chip_type == DRIVER_WCN) {
10875 res = tdls_set_offchannel_offset(dut, conn, intf,
10876 off_ch_num, sec_ch);
10877 } else {
10878 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
10879 sec_ch);
10880 }
10881 if (res != 1)
10882 return res;
10883 if (wifi_chip_type == DRIVER_WCN)
10884 res = tdls_set_offchannel_mode(dut, conn, intf, 4);
10885 else
10886 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 4);
10887 break;
10888 }
10889
10890 return res;
10891}
10892
10893
10894static int ath_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
10895 struct sigma_conn *conn,
10896 struct sigma_cmd *cmd)
10897{
10898 const char *val;
Srikanth Marepalli5415acf2018-08-27 12:53:11 +053010899 char *token = NULL, *result;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010900
priyadharshini gowthamane5e25172015-12-08 14:53:48 -080010901 novap_reset(dut, intf);
10902
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010903 val = get_param(cmd, "nss_mcs_opt");
10904 if (val) {
10905 /* String (nss_operating_mode; mcs_operating_mode) */
10906 int nss, mcs;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010907 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010908
10909 token = strdup(val);
10910 if (!token)
10911 return 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010912 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +053010913 if (!result) {
10914 sigma_dut_print(dut, DUT_MSG_ERROR,
10915 "VHT NSS not specified");
10916 goto failed;
10917 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010918 if (strcasecmp(result, "def") != 0) {
10919 nss = atoi(result);
10920 if (nss == 4)
10921 ath_disable_txbf(dut, intf);
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010922 if (run_iwpriv(dut, intf, "nss %d", nss) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010923 goto failed;
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010924
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010925 }
10926
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010927 result = strtok_r(NULL, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +053010928 if (!result) {
10929 sigma_dut_print(dut, DUT_MSG_ERROR,
10930 "VHT MCS not specified");
10931 goto failed;
10932 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010933 if (strcasecmp(result, "def") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010934 if (run_iwpriv(dut, intf, "set11NRates 0") < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010935 goto failed;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010936 } else {
10937 mcs = atoi(result);
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010938 if (run_iwpriv(dut, intf, "vhtmcs %d", mcs) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010939 goto failed;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010940 }
10941 /* Channel width gets messed up, fix this */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010942 run_iwpriv(dut, intf, "chwidth %d", dut->chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010943 }
10944
Srikanth Marepalli5415acf2018-08-27 12:53:11 +053010945 free(token);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010946 return 1;
10947failed:
10948 free(token);
10949 return 0;
10950}
10951
10952
10953static int cmd_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
10954 struct sigma_conn *conn,
10955 struct sigma_cmd *cmd)
10956{
10957 switch (get_driver_type()) {
10958 case DRIVER_ATHEROS:
10959 return ath_sta_set_rfeature_vht(intf, dut, conn, cmd);
10960 default:
10961 send_resp(dut, conn, SIGMA_ERROR,
10962 "errorCode,Unsupported sta_set_rfeature(VHT) with the current driver");
10963 return 0;
10964 }
10965}
10966
10967
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080010968static int wcn_sta_set_rfeature_he(const char *intf, struct sigma_dut *dut,
10969 struct sigma_conn *conn,
10970 struct sigma_cmd *cmd)
10971{
10972 const char *val;
10973 char *token = NULL, *result;
10974 char buf[60];
10975
10976 val = get_param(cmd, "nss_mcs_opt");
10977 if (val) {
10978 /* String (nss_operating_mode; mcs_operating_mode) */
10979 int nss, mcs, ratecode;
10980 char *saveptr;
10981
10982 token = strdup(val);
10983 if (!token)
10984 return -2;
10985
10986 result = strtok_r(token, ";", &saveptr);
10987 if (!result) {
10988 sigma_dut_print(dut, DUT_MSG_ERROR,
10989 "HE NSS not specified");
10990 goto failed;
10991 }
10992 nss = 1;
10993 if (strcasecmp(result, "def") != 0)
10994 nss = atoi(result);
10995
10996 result = strtok_r(NULL, ";", &saveptr);
10997 if (!result) {
10998 sigma_dut_print(dut, DUT_MSG_ERROR,
10999 "HE MCS not specified");
11000 goto failed;
11001 }
11002 mcs = 7;
11003 if (strcasecmp(result, "def") != 0)
11004 mcs = atoi(result);
11005
Arif Hussain557bf412018-05-25 17:29:36 -070011006 ratecode = 0x20; /* for nss:1 MCS 0 */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011007 if (nss == 2) {
Arif Hussain557bf412018-05-25 17:29:36 -070011008 ratecode = 0x40; /* for nss:2 MCS 0 */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011009 } else if (nss > 2) {
11010 sigma_dut_print(dut, DUT_MSG_ERROR,
11011 "HE NSS %d not supported", nss);
11012 goto failed;
11013 }
11014
Arif Hussain557bf412018-05-25 17:29:36 -070011015 snprintf(buf, sizeof(buf), "iwpriv %s nss %d", intf, nss);
11016 if (system(buf) != 0) {
11017 sigma_dut_print(dut, DUT_MSG_ERROR,
11018 "nss_mcs_opt: iwpriv %s nss %d failed",
11019 intf, nss);
11020 goto failed;
11021 }
Arif Hussainac6c5112018-05-25 17:34:00 -070011022 dut->sta_nss = nss;
Arif Hussain557bf412018-05-25 17:29:36 -070011023
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011024 /* Add the MCS to the ratecode */
11025 if (mcs >= 0 && mcs <= 11) {
11026 ratecode += mcs;
Arif Hussain557bf412018-05-25 17:29:36 -070011027#ifdef NL80211_SUPPORT
11028 if (dut->device_type == STA_testbed) {
11029 enum he_mcs_config mcs_config;
11030 int ret;
11031
11032 if (mcs <= 7)
11033 mcs_config = HE_80_MCS0_7;
11034 else if (mcs <= 9)
11035 mcs_config = HE_80_MCS0_9;
11036 else
11037 mcs_config = HE_80_MCS0_11;
11038 ret = sta_set_he_mcs(dut, intf, mcs_config);
11039 if (ret) {
11040 sigma_dut_print(dut, DUT_MSG_ERROR,
11041 "nss_mcs_opt: mcs setting failed, mcs:%d, mcs_config %d, ret:%d",
11042 mcs, mcs_config, ret);
11043 goto failed;
11044 }
11045 }
11046#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011047 } else {
11048 sigma_dut_print(dut, DUT_MSG_ERROR,
11049 "HE MCS %d not supported", mcs);
11050 goto failed;
11051 }
11052 snprintf(buf, sizeof(buf), "iwpriv %s set_11ax_rate 0x%03x",
11053 intf, ratecode);
11054 if (system(buf) != 0) {
11055 sigma_dut_print(dut, DUT_MSG_ERROR,
11056 "iwpriv setting of 11ax rates failed");
11057 goto failed;
11058 }
11059 free(token);
11060 }
11061
11062 val = get_param(cmd, "GI");
11063 if (val) {
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011064 int fix_rate_sgi;
11065
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011066 if (strcmp(val, "0.8") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070011067 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 9", intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011068 fix_rate_sgi = 1;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011069 } else if (strcmp(val, "1.6") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070011070 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 10",
11071 intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011072 fix_rate_sgi = 2;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011073 } else if (strcmp(val, "3.2") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070011074 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 11",
11075 intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011076 fix_rate_sgi = 3;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011077 } else {
11078 send_resp(dut, conn, SIGMA_ERROR,
11079 "errorCode,GI value not supported");
11080 return 0;
11081 }
11082 if (system(buf) != 0) {
11083 send_resp(dut, conn, SIGMA_ERROR,
11084 "errorCode,Failed to set shortgi");
11085 return 0;
11086 }
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011087 snprintf(buf, sizeof(buf), "iwpriv %s shortgi %d",
11088 intf, fix_rate_sgi);
11089 if (system(buf) != 0) {
11090 send_resp(dut, conn, SIGMA_ERROR,
11091 "errorCode,Failed to set fix rate shortgi");
11092 return STATUS_SENT;
11093 }
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011094 }
11095
Subhani Shaik8e7a3052018-04-24 14:03:00 -070011096 val = get_param(cmd, "LTF");
11097 if (val) {
11098#ifdef NL80211_SUPPORT
11099 if (strcmp(val, "3.2") == 0) {
11100 sta_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_1X);
11101 } if (strcmp(val, "6.4") == 0) {
11102 sta_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_2X);
11103 } else if (strcmp(val, "12.8") == 0) {
11104 sta_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_4X);
11105 } else {
11106 send_resp(dut, conn, SIGMA_ERROR,
11107 "errorCode, LTF value not supported");
11108 return 0;
11109 }
11110#else /* NL80211_SUPPORT */
11111 sigma_dut_print(dut, DUT_MSG_ERROR,
11112 "LTF cannot be set without NL80211_SUPPORT defined");
11113 return -2;
11114#endif /* NL80211_SUPPORT */
11115 }
11116
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -070011117 val = get_param(cmd, "TxSUPPDU");
11118 if (val) {
11119 int set_val = 1;
11120
11121 if (strcasecmp(val, "Enable") == 0)
11122 set_val = 1;
11123 else if (strcasecmp(val, "Disable") == 0)
11124 set_val = 0;
11125
11126 if (sta_set_tx_su_ppdu_cfg(dut, intf, set_val)) {
11127 send_resp(dut, conn, SIGMA_ERROR,
11128 "ErrorCode,Failed to set Tx SU PPDU config");
11129 return 0;
11130 }
11131 }
11132
Arif Hussain480d5f42019-03-12 14:40:42 -070011133 val = get_param(cmd, "TWT_Setup");
11134 if (val) {
11135 if (strcasecmp(val, "Request") == 0) {
11136 if (sta_twt_request(dut, conn, cmd)) {
11137 send_resp(dut, conn, SIGMA_ERROR,
11138 "ErrorCode,sta_twt_request failed");
11139 return STATUS_SENT;
11140 }
11141 } else if (strcasecmp(val, "Teardown") == 0) {
11142 if (sta_twt_teardown(dut, conn, cmd)) {
11143 send_resp(dut, conn, SIGMA_ERROR,
11144 "ErrorCode,sta_twt_teardown failed");
11145 return STATUS_SENT;
11146 }
11147 }
11148 }
11149
Kiran Kumar Lokere50eb2cd2018-12-18 18:31:28 -080011150 val = get_param(cmd, "transmitOMI");
11151 if (val && sta_transmit_omi(dut, conn, cmd)) {
11152 send_resp(dut, conn, SIGMA_ERROR,
11153 "ErrorCode,sta_transmit_omi failed");
11154 return STATUS_SENT;
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -070011155 }
11156
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080011157 val = get_param(cmd, "Powersave");
11158 if (val) {
11159 char buf[60];
11160
11161 if (strcasecmp(val, "off") == 0) {
11162 snprintf(buf, sizeof(buf),
11163 "iwpriv %s setPower 2", intf);
11164 if (system(buf) != 0) {
11165 sigma_dut_print(dut, DUT_MSG_ERROR,
11166 "iwpriv setPower 2 failed");
11167 return 0;
11168 }
11169 } else if (strcasecmp(val, "on") == 0) {
11170 snprintf(buf, sizeof(buf),
11171 "iwpriv %s setPower 1", intf);
11172 if (system(buf) != 0) {
11173 sigma_dut_print(dut, DUT_MSG_ERROR,
11174 "iwpriv setPower 1 failed");
11175 return 0;
11176 }
11177 } else {
11178 sigma_dut_print(dut, DUT_MSG_ERROR,
11179 "Unsupported Powersave value '%s'",
11180 val);
11181 return -1;
11182 }
11183 }
11184
Kiran Kumar Lokere2c4b7ce2019-01-30 12:02:28 -080011185 val = get_param(cmd, "MU_EDCA");
11186 if (val) {
11187 if (strcasecmp(val, "Override") == 0) {
11188 if (sta_set_mu_edca_override(dut, intf, 1)) {
11189 send_resp(dut, conn, SIGMA_ERROR,
11190 "errorCode,MU EDCA override set failed");
11191 return STATUS_SENT;
11192 }
11193 } else if (strcasecmp(val, "Disable") == 0) {
11194 if (sta_set_mu_edca_override(dut, intf, 0)) {
11195 send_resp(dut, conn, SIGMA_ERROR,
11196 "errorCode,MU EDCA override disable failed");
11197 return STATUS_SENT;
11198 }
11199 }
11200 }
11201
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011202 return 1;
11203
11204failed:
11205 free(token);
11206 return -2;
11207}
11208
11209
11210static int cmd_sta_set_rfeature_he(const char *intf, struct sigma_dut *dut,
11211 struct sigma_conn *conn,
11212 struct sigma_cmd *cmd)
11213{
11214 switch (get_driver_type()) {
11215 case DRIVER_WCN:
11216 return wcn_sta_set_rfeature_he(intf, dut, conn, cmd);
11217 default:
11218 send_resp(dut, conn, SIGMA_ERROR,
11219 "errorCode,Unsupported sta_set_rfeature(HE) with the current driver");
11220 return 0;
11221 }
11222}
11223
11224
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080011225static int cmd_sta_set_power_save_he(const char *intf, struct sigma_dut *dut,
11226 struct sigma_conn *conn,
11227 struct sigma_cmd *cmd)
11228{
11229 const char *val;
11230
11231 val = get_param(cmd, "powersave");
11232 if (val) {
11233 char buf[60];
11234
11235 if (strcasecmp(val, "off") == 0) {
11236 snprintf(buf, sizeof(buf), "iwpriv %s setPower 2",
11237 intf);
11238 if (system(buf) != 0) {
11239 sigma_dut_print(dut, DUT_MSG_ERROR,
11240 "iwpriv setPower 2 failed");
11241 return 0;
11242 }
11243 } else if (strcasecmp(val, "on") == 0) {
11244 snprintf(buf, sizeof(buf), "iwpriv %s setPower 1",
11245 intf);
11246 if (system(buf) != 0) {
11247 sigma_dut_print(dut, DUT_MSG_ERROR,
11248 "iwpriv setPower 1 failed");
11249 return 0;
11250 }
11251 } else {
11252 sigma_dut_print(dut, DUT_MSG_ERROR,
11253 "Unsupported power save config");
11254 return -1;
11255 }
11256 return 1;
11257 }
11258
11259 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported command");
11260
11261 return 0;
11262}
11263
11264
Ashwini Patil5acd7382017-04-13 15:55:04 +053011265static int btm_query_candidate_list(struct sigma_dut *dut,
11266 struct sigma_conn *conn,
11267 struct sigma_cmd *cmd)
11268{
11269 const char *bssid, *info, *op_class, *ch, *phy_type, *pref;
11270 int len, ret;
11271 char buf[10];
11272
11273 /*
11274 * Neighbor Report elements format:
11275 * neighbor=<BSSID>,<BSSID Information>,<Operating Class>,
11276 * <Channel Number>,<PHY Type>[,<hexdump of Optional Subelements>]
11277 * eg: neighbor=aa:bb:cc:dd:ee:ff,17,81,6,1,030101
11278 */
11279
11280 bssid = get_param(cmd, "Nebor_BSSID");
11281 if (!bssid) {
11282 send_resp(dut, conn, SIGMA_INVALID,
11283 "errorCode,Nebor_BSSID is missing");
11284 return 0;
11285 }
11286
11287 info = get_param(cmd, "Nebor_Bssid_Info");
11288 if (!info) {
11289 sigma_dut_print(dut, DUT_MSG_INFO,
11290 "Using default value for Nebor_Bssid_Info: %s",
11291 DEFAULT_NEIGHBOR_BSSID_INFO);
11292 info = DEFAULT_NEIGHBOR_BSSID_INFO;
11293 }
11294
11295 op_class = get_param(cmd, "Nebor_Op_Class");
11296 if (!op_class) {
11297 send_resp(dut, conn, SIGMA_INVALID,
11298 "errorCode,Nebor_Op_Class is missing");
11299 return 0;
11300 }
11301
11302 ch = get_param(cmd, "Nebor_Op_Ch");
11303 if (!ch) {
11304 send_resp(dut, conn, SIGMA_INVALID,
11305 "errorCode,Nebor_Op_Ch is missing");
11306 return 0;
11307 }
11308
11309 phy_type = get_param(cmd, "Nebor_Phy_Type");
11310 if (!phy_type) {
11311 sigma_dut_print(dut, DUT_MSG_INFO,
11312 "Using default value for Nebor_Phy_Type: %s",
11313 DEFAULT_NEIGHBOR_PHY_TYPE);
11314 phy_type = DEFAULT_NEIGHBOR_PHY_TYPE;
11315 }
11316
11317 /* Parse optional subelements */
11318 buf[0] = '\0';
11319 pref = get_param(cmd, "Nebor_Pref");
11320 if (pref) {
11321 /* hexdump for preferrence subelement */
11322 ret = snprintf(buf, sizeof(buf), ",0301%02x", atoi(pref));
11323 if (ret < 0 || ret >= (int) sizeof(buf)) {
11324 sigma_dut_print(dut, DUT_MSG_ERROR,
11325 "snprintf failed for optional subelement ret: %d",
11326 ret);
11327 send_resp(dut, conn, SIGMA_ERROR,
11328 "errorCode,snprintf failed for subelement");
11329 return 0;
11330 }
11331 }
11332
11333 if (!dut->btm_query_cand_list) {
11334 dut->btm_query_cand_list = calloc(1, NEIGHBOR_REPORT_SIZE);
11335 if (!dut->btm_query_cand_list) {
11336 send_resp(dut, conn, SIGMA_ERROR,
11337 "errorCode,Failed to allocate memory for btm_query_cand_list");
11338 return 0;
11339 }
11340 }
11341
11342 len = strlen(dut->btm_query_cand_list);
11343 ret = snprintf(dut->btm_query_cand_list + len,
11344 NEIGHBOR_REPORT_SIZE - len, " neighbor=%s,%s,%s,%s,%s%s",
11345 bssid, info, op_class, ch, phy_type, buf);
11346 if (ret < 0 || ret >= NEIGHBOR_REPORT_SIZE - len) {
11347 sigma_dut_print(dut, DUT_MSG_ERROR,
11348 "snprintf failed for neighbor report list ret: %d",
11349 ret);
11350 send_resp(dut, conn, SIGMA_ERROR,
11351 "errorCode,snprintf failed for neighbor report");
11352 free(dut->btm_query_cand_list);
11353 dut->btm_query_cand_list = NULL;
11354 return 0;
11355 }
11356
11357 return 1;
11358}
11359
11360
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020011361int sta_extract_60g_ese(struct sigma_dut *dut, struct sigma_cmd *cmd,
11362 struct sigma_ese_alloc *allocs, int *allocs_size)
11363{
11364 int max_count = *allocs_size;
11365 int count = 0, i;
11366 const char *val;
11367
11368 do {
11369 val = get_param_indexed(cmd, "AllocID", count);
11370 if (val)
11371 count++;
11372 } while (val);
11373
11374 if (count == 0 || count > max_count) {
11375 sigma_dut_print(dut, DUT_MSG_ERROR,
11376 "Invalid number of allocations(%d)", count);
11377 return -1;
11378 }
11379
11380 for (i = 0; i < count; i++) {
11381 val = get_param_indexed(cmd, "PercentBI", i);
11382 if (!val) {
11383 sigma_dut_print(dut, DUT_MSG_ERROR,
11384 "Missing PercentBI parameter at index %d",
11385 i);
11386 return -1;
11387 }
11388 allocs[i].percent_bi = atoi(val);
11389
11390 val = get_param_indexed(cmd, "SrcAID", i);
11391 if (val)
11392 allocs[i].src_aid = strtol(val, NULL, 0);
11393 else
11394 allocs[i].src_aid = ESE_BCAST_AID;
11395
11396 val = get_param_indexed(cmd, "DestAID", i);
11397 if (val)
11398 allocs[i].dst_aid = strtol(val, NULL, 0);
11399 else
11400 allocs[i].dst_aid = ESE_BCAST_AID;
11401
11402 allocs[i].type = ESE_CBAP;
11403 sigma_dut_print(dut, DUT_MSG_INFO,
11404 "Alloc %d PercentBI %d SrcAID %d DstAID %d",
11405 i, allocs[i].percent_bi, allocs[i].src_aid,
11406 allocs[i].dst_aid);
11407 }
11408
11409 *allocs_size = count;
11410 return 0;
11411}
11412
11413
11414static int sta_set_60g_ese(struct sigma_dut *dut, int count,
11415 struct sigma_ese_alloc *allocs)
11416{
11417 switch (get_driver_type()) {
11418#ifdef __linux__
11419 case DRIVER_WIL6210:
11420 if (wil6210_set_ese(dut, count, allocs))
11421 return -1;
11422 return 1;
11423#endif /* __linux__ */
11424 default:
11425 sigma_dut_print(dut, DUT_MSG_ERROR,
11426 "Unsupported sta_set_60g_ese with the current driver");
11427 return -1;
11428 }
11429}
11430
11431
11432static int cmd_sta_set_rfeature_60g(const char *intf, struct sigma_dut *dut,
11433 struct sigma_conn *conn,
11434 struct sigma_cmd *cmd)
11435{
11436 const char *val;
11437
11438 val = get_param(cmd, "ExtSchIE");
11439 if (val && !strcasecmp(val, "Enable")) {
11440 struct sigma_ese_alloc allocs[MAX_ESE_ALLOCS];
11441 int count = MAX_ESE_ALLOCS;
11442
11443 if (sta_extract_60g_ese(dut, cmd, allocs, &count))
11444 return -1;
11445 return sta_set_60g_ese(dut, count, allocs);
11446 }
11447
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +020011448 val = get_param(cmd, "MCS_FixedRate");
11449 if (val) {
11450 int sta_mcs = atoi(val);
11451
11452 sigma_dut_print(dut, DUT_MSG_INFO, "Force STA MCS to %d",
11453 sta_mcs);
11454 wil6210_set_force_mcs(dut, 1, sta_mcs);
11455
Jouni Malinen0e29cf22019-02-19 01:13:21 +020011456 return SUCCESS_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +020011457 }
11458
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020011459 send_resp(dut, conn, SIGMA_ERROR,
11460 "errorCode,Invalid sta_set_rfeature(60G)");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020011461 return STATUS_SENT;
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020011462}
11463
11464
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011465static int cmd_sta_set_rfeature(struct sigma_dut *dut, struct sigma_conn *conn,
11466 struct sigma_cmd *cmd)
11467{
11468 const char *intf = get_param(cmd, "Interface");
11469 const char *prog = get_param(cmd, "Prog");
Ashwini Patil68d02cd2017-01-10 15:39:16 +053011470 const char *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011471
11472 if (intf == NULL || prog == NULL)
11473 return -1;
11474
Ashwini Patil5acd7382017-04-13 15:55:04 +053011475 /* BSS Transition candidate list for BTM query */
11476 val = get_param(cmd, "Nebor_BSSID");
11477 if (val && btm_query_candidate_list(dut, conn, cmd) == 0)
11478 return 0;
11479
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011480 if (strcasecmp(prog, "TDLS") == 0)
11481 return cmd_sta_set_rfeature_tdls(intf, dut, conn, cmd);
11482
11483 if (strcasecmp(prog, "VHT") == 0)
11484 return cmd_sta_set_rfeature_vht(intf, dut, conn, cmd);
11485
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011486 if (strcasecmp(prog, "HE") == 0)
11487 return cmd_sta_set_rfeature_he(intf, dut, conn, cmd);
11488
Ashwini Patil68d02cd2017-01-10 15:39:16 +053011489 if (strcasecmp(prog, "MBO") == 0) {
11490 val = get_param(cmd, "Cellular_Data_Cap");
11491 if (val &&
11492 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
11493 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +053011494
11495 val = get_param(cmd, "Ch_Pref");
11496 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
11497 return 0;
11498
Ashwini Patil68d02cd2017-01-10 15:39:16 +053011499 return 1;
11500 }
11501
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020011502 if (strcasecmp(prog, "60GHz") == 0)
11503 return cmd_sta_set_rfeature_60g(intf, dut, conn, cmd);
11504
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011505 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported Prog");
11506 return 0;
11507}
11508
11509
11510static int cmd_sta_set_radio(struct sigma_dut *dut, struct sigma_conn *conn,
11511 struct sigma_cmd *cmd)
11512{
11513 const char *intf = get_param(cmd, "Interface");
11514 const char *mode = get_param(cmd, "Mode");
11515 int res;
11516
11517 if (intf == NULL || mode == NULL)
11518 return -1;
11519
11520 if (strcasecmp(mode, "On") == 0)
11521 res = wpa_command(intf, "SET radio_disabled 0");
11522 else if (strcasecmp(mode, "Off") == 0)
11523 res = wpa_command(intf, "SET radio_disabled 1");
11524 else
11525 return -1;
11526
11527 if (res) {
11528 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
11529 "radio mode");
11530 return 0;
11531 }
11532
11533 return 1;
11534}
11535
11536
11537static int cmd_sta_set_pwrsave(struct sigma_dut *dut, struct sigma_conn *conn,
11538 struct sigma_cmd *cmd)
11539{
11540 const char *intf = get_param(cmd, "Interface");
11541 const char *mode = get_param(cmd, "Mode");
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020011542 const char *prog = get_param(cmd, "program");
11543 const char *powersave = get_param(cmd, "powersave");
11544 int res = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011545
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020011546 if (intf == NULL)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011547 return -1;
11548
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020011549 if (prog && strcasecmp(prog, "60GHz") == 0) {
11550 /*
11551 * The CAPI mode parameter does not exist in 60G
11552 * unscheduled PS.
11553 */
11554 if (strcasecmp(powersave, "unscheduled") == 0)
11555 res = set_ps(intf, dut, 1);
Alexei Avshalom Lazar2f6fdb42019-02-04 14:16:08 +020011556 } else if (prog && get_driver_type() == DRIVER_WCN &&
11557 strcasecmp(prog, "HE") == 0) {
11558 return cmd_sta_set_power_save_he(intf, dut, conn, cmd);
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020011559 } else {
11560 if (mode == NULL)
11561 return -1;
11562
11563 if (strcasecmp(mode, "On") == 0)
11564 res = set_ps(intf, dut, 1);
11565 else if (strcasecmp(mode, "Off") == 0)
11566 res = set_ps(intf, dut, 0);
11567 else
11568 return -1;
11569 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011570
11571 if (res) {
11572 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
11573 "power save mode");
11574 return 0;
11575 }
11576
11577 return 1;
11578}
11579
11580
11581static int cmd_sta_bssid_pool(struct sigma_dut *dut, struct sigma_conn *conn,
11582 struct sigma_cmd *cmd)
11583{
11584 const char *intf = get_param(cmd, "Interface");
11585 const char *val, *bssid;
11586 int res;
11587 char *buf;
11588 size_t buf_len;
11589
11590 val = get_param(cmd, "BSSID_FILTER");
11591 if (val == NULL)
11592 return -1;
11593
11594 bssid = get_param(cmd, "BSSID_List");
11595 if (atoi(val) == 0 || bssid == NULL) {
11596 /* Disable BSSID filter */
11597 if (wpa_command(intf, "SET bssid_filter ")) {
11598 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed "
11599 "to disable BSSID filter");
11600 return 0;
11601 }
11602
11603 return 1;
11604 }
11605
11606 buf_len = 100 + strlen(bssid);
11607 buf = malloc(buf_len);
11608 if (buf == NULL)
11609 return -1;
11610
11611 snprintf(buf, buf_len, "SET bssid_filter %s", bssid);
11612 res = wpa_command(intf, buf);
11613 free(buf);
11614 if (res) {
11615 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to enable "
11616 "BSSID filter");
11617 return 0;
11618 }
11619
11620 return 1;
11621}
11622
11623
11624static int cmd_sta_reset_parm(struct sigma_dut *dut, struct sigma_conn *conn,
11625 struct sigma_cmd *cmd)
11626{
11627 const char *intf = get_param(cmd, "Interface");
11628 const char *val;
11629
11630 /* TODO: ARP */
11631
11632 val = get_param(cmd, "HS2_CACHE_PROFILE");
11633 if (val && strcasecmp(val, "All") == 0)
11634 hs2_clear_credentials(intf);
11635
11636 return 1;
11637}
11638
11639
11640static int cmd_sta_get_key(struct sigma_dut *dut, struct sigma_conn *conn,
11641 struct sigma_cmd *cmd)
11642{
11643 const char *intf = get_param(cmd, "Interface");
11644 const char *key_type = get_param(cmd, "KeyType");
11645 char buf[100], resp[200];
11646
11647 if (key_type == NULL)
11648 return -1;
11649
11650 if (strcasecmp(key_type, "GTK") == 0) {
11651 if (wpa_command_resp(intf, "GET gtk", buf, sizeof(buf)) < 0 ||
11652 strncmp(buf, "FAIL", 4) == 0) {
11653 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
11654 "not fetch current GTK");
11655 return 0;
11656 }
11657 snprintf(resp, sizeof(resp), "KeyValue,%s", buf);
11658 send_resp(dut, conn, SIGMA_COMPLETE, resp);
11659 return 0;
11660 } else {
11661 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
11662 "KeyType");
11663 return 0;
11664 }
11665
11666 return 1;
11667}
11668
11669
11670static int hs2_set_policy(struct sigma_dut *dut)
11671{
11672#ifdef ANDROID
11673 system("ip rule del prio 23000");
11674 if (system("ip rule add from all lookup main prio 23000") != 0) {
11675 sigma_dut_print(dut, DUT_MSG_ERROR,
11676 "Failed to run:ip rule add from all lookup main prio");
11677 return -1;
11678 }
11679 if (system("ip route flush cache") != 0) {
11680 sigma_dut_print(dut, DUT_MSG_ERROR,
11681 "Failed to run ip route flush cache");
11682 return -1;
11683 }
11684 return 1;
11685#else /* ANDROID */
11686 return 0;
11687#endif /* ANDROID */
11688}
11689
11690
11691static int cmd_sta_hs2_associate(struct sigma_dut *dut,
11692 struct sigma_conn *conn,
11693 struct sigma_cmd *cmd)
11694{
11695 const char *intf = get_param(cmd, "Interface");
11696 const char *val = get_param(cmd, "Ignore_blacklist");
Jouni Malinen439352d2018-09-13 03:42:23 +030011697 const char *band = get_param(cmd, "Band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011698 struct wpa_ctrl *ctrl;
11699 int res;
11700 char bssid[20], ssid[40], resp[100], buf[100], blacklisted[100];
11701 int tries = 0;
11702 int ignore_blacklist = 0;
11703 const char *events[] = {
11704 "CTRL-EVENT-CONNECTED",
11705 "INTERWORKING-BLACKLISTED",
11706 "INTERWORKING-NO-MATCH",
11707 NULL
11708 };
11709
11710 start_sta_mode(dut);
11711
Jouni Malinen439352d2018-09-13 03:42:23 +030011712 if (band) {
11713 if (strcmp(band, "2.4") == 0) {
11714 wpa_command(intf, "SET setband 2G");
11715 } else if (strcmp(band, "5") == 0) {
11716 wpa_command(intf, "SET setband 5G");
11717 } else {
11718 send_resp(dut, conn, SIGMA_ERROR,
11719 "errorCode,Unsupported band");
11720 return 0;
11721 }
11722 }
11723
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011724 blacklisted[0] = '\0';
11725 if (val && atoi(val))
11726 ignore_blacklist = 1;
11727
11728try_again:
11729 ctrl = open_wpa_mon(intf);
11730 if (ctrl == NULL) {
11731 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
11732 "wpa_supplicant monitor connection");
11733 return -2;
11734 }
11735
11736 tries++;
11737 if (wpa_command(intf, "INTERWORKING_SELECT auto")) {
11738 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start "
11739 "Interworking connection");
11740 wpa_ctrl_detach(ctrl);
11741 wpa_ctrl_close(ctrl);
11742 return 0;
11743 }
11744
11745 buf[0] = '\0';
11746 while (1) {
11747 char *pos;
11748 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
11749 pos = strstr(buf, "INTERWORKING-BLACKLISTED");
11750 if (!pos)
11751 break;
11752 pos += 25;
11753 sigma_dut_print(dut, DUT_MSG_DEBUG, "Found blacklisted AP: %s",
11754 pos);
11755 if (!blacklisted[0])
11756 memcpy(blacklisted, pos, strlen(pos) + 1);
11757 }
11758
11759 if (ignore_blacklist && blacklisted[0]) {
11760 char *end;
11761 end = strchr(blacklisted, ' ');
11762 if (end)
11763 *end = '\0';
11764 sigma_dut_print(dut, DUT_MSG_DEBUG, "Try to connect to a blacklisted network: %s",
11765 blacklisted);
11766 snprintf(buf, sizeof(buf), "INTERWORKING_CONNECT %s",
11767 blacklisted);
11768 if (wpa_command(intf, buf)) {
11769 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start Interworking connection to blacklisted network");
11770 wpa_ctrl_detach(ctrl);
11771 wpa_ctrl_close(ctrl);
11772 return 0;
11773 }
11774 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
11775 buf, sizeof(buf));
11776 }
11777
11778 wpa_ctrl_detach(ctrl);
11779 wpa_ctrl_close(ctrl);
11780
11781 if (res < 0) {
11782 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
11783 "connect");
11784 return 0;
11785 }
11786
11787 if (strstr(buf, "INTERWORKING-NO-MATCH") ||
11788 strstr(buf, "INTERWORKING-BLACKLISTED")) {
11789 if (tries < 2) {
11790 sigma_dut_print(dut, DUT_MSG_INFO, "No match found - try again to verify no APs were missed in the scan");
11791 goto try_again;
11792 }
11793 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,No network with "
11794 "matching credentials found");
11795 return 0;
11796 }
11797
11798 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
11799 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
11800 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
11801 "get current BSSID/SSID");
11802 return 0;
11803 }
11804
11805 snprintf(resp, sizeof(resp), "SSID,%s,BSSID,%s", ssid, bssid);
11806 send_resp(dut, conn, SIGMA_COMPLETE, resp);
11807 hs2_set_policy(dut);
11808 return 0;
11809}
11810
11811
Jouni Malinenb639f1c2018-09-13 02:39:46 +030011812static int cmd_sta_hs2_venue_info(struct sigma_dut *dut,
11813 struct sigma_conn *conn,
11814 struct sigma_cmd *cmd)
11815{
11816 const char *intf = get_param(cmd, "Interface");
11817 const char *display = get_param(cmd, "Display");
11818 struct wpa_ctrl *ctrl;
11819 char buf[300], params[400], *pos;
11820 char bssid[20];
11821 int info_avail = 0;
11822 unsigned int old_timeout;
11823 int res;
11824
11825 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0) {
11826 send_resp(dut, conn, SIGMA_ERROR,
11827 "ErrorCode,Could not get current BSSID");
11828 return 0;
11829 }
11830 ctrl = open_wpa_mon(intf);
11831 if (!ctrl) {
11832 sigma_dut_print(dut, DUT_MSG_ERROR,
11833 "Failed to open wpa_supplicant monitor connection");
11834 return -2;
11835 }
11836
11837 snprintf(buf, sizeof(buf), "ANQP_GET %s 277", bssid);
11838 wpa_command(intf, buf);
11839
11840 res = get_wpa_cli_event(dut, ctrl, "GAS-QUERY-DONE", buf, sizeof(buf));
11841 if (res < 0) {
11842 send_resp(dut, conn, SIGMA_ERROR,
11843 "ErrorCode,Could not complete GAS query");
11844 goto fail;
11845 }
11846
11847 old_timeout = dut->default_timeout;
11848 dut->default_timeout = 2;
11849 res = get_wpa_cli_event(dut, ctrl, "RX-VENUE-URL", buf, sizeof(buf));
11850 dut->default_timeout = old_timeout;
11851 if (res < 0)
11852 goto done;
11853 pos = strchr(buf, ' ');
11854 if (!pos)
11855 goto done;
11856 pos++;
11857 pos = strchr(pos, ' ');
11858 if (!pos)
11859 goto done;
11860 pos++;
11861 info_avail = 1;
11862 snprintf(params, sizeof(params), "browser %s", pos);
11863
11864 if (display && strcasecmp(display, "Yes") == 0) {
11865 pid_t pid;
11866
11867 pid = fork();
11868 if (pid < 0) {
11869 perror("fork");
11870 return -1;
11871 }
11872
11873 if (pid == 0) {
11874 run_hs20_osu(dut, params);
11875 exit(0);
11876 }
11877 }
11878
11879done:
11880 snprintf(buf, sizeof(buf), "Info_available,%s",
11881 info_avail ? "Yes" : "No");
11882 send_resp(dut, conn, SIGMA_COMPLETE, buf);
11883fail:
11884 wpa_ctrl_detach(ctrl);
11885 wpa_ctrl_close(ctrl);
11886 return 0;
11887}
11888
11889
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011890static int sta_add_credential_uname_pwd(struct sigma_dut *dut,
11891 struct sigma_conn *conn,
11892 const char *ifname,
11893 struct sigma_cmd *cmd)
11894{
11895 const char *val;
11896 int id;
11897
11898 id = add_cred(ifname);
11899 if (id < 0)
11900 return -2;
11901 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
11902
11903 val = get_param(cmd, "prefer");
11904 if (val && atoi(val) > 0)
11905 set_cred(ifname, id, "priority", "1");
11906
11907 val = get_param(cmd, "REALM");
11908 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
11909 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
11910 "realm");
11911 return 0;
11912 }
11913
11914 val = get_param(cmd, "HOME_FQDN");
11915 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
11916 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
11917 "home_fqdn");
11918 return 0;
11919 }
11920
11921 val = get_param(cmd, "Username");
11922 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
11923 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
11924 "username");
11925 return 0;
11926 }
11927
11928 val = get_param(cmd, "Password");
11929 if (val && set_cred_quoted(ifname, id, "password", val) < 0) {
11930 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
11931 "password");
11932 return 0;
11933 }
11934
11935 val = get_param(cmd, "ROOT_CA");
11936 if (val) {
11937 char fname[200];
11938 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
11939#ifdef __linux__
11940 if (!file_exists(fname)) {
11941 char msg[300];
11942 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
11943 "file (%s) not found", fname);
11944 send_resp(dut, conn, SIGMA_ERROR, msg);
11945 return 0;
11946 }
11947#endif /* __linux__ */
11948 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
11949 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
11950 "not set root CA");
11951 return 0;
11952 }
11953 }
11954
11955 return 1;
11956}
11957
11958
11959static int update_devdetail_imsi(struct sigma_dut *dut, const char *imsi)
11960{
11961 FILE *in, *out;
11962 char buf[500];
11963 int found = 0;
11964
11965 in = fopen("devdetail.xml", "r");
11966 if (in == NULL)
11967 return -1;
11968 out = fopen("devdetail.xml.tmp", "w");
11969 if (out == NULL) {
11970 fclose(in);
11971 return -1;
11972 }
11973
11974 while (fgets(buf, sizeof(buf), in)) {
11975 char *pos = strstr(buf, "<IMSI>");
11976 if (pos) {
11977 sigma_dut_print(dut, DUT_MSG_INFO, "Updated DevDetail IMSI to %s",
11978 imsi);
11979 pos += 6;
11980 *pos = '\0';
11981 fprintf(out, "%s%s</IMSI>\n", buf, imsi);
11982 found++;
11983 } else {
11984 fprintf(out, "%s", buf);
11985 }
11986 }
11987
11988 fclose(out);
11989 fclose(in);
11990 if (found)
11991 rename("devdetail.xml.tmp", "devdetail.xml");
11992 else
11993 unlink("devdetail.xml.tmp");
11994
11995 return 0;
11996}
11997
11998
11999static int sta_add_credential_sim(struct sigma_dut *dut,
12000 struct sigma_conn *conn,
12001 const char *ifname, struct sigma_cmd *cmd)
12002{
12003 const char *val, *imsi = NULL;
12004 int id;
12005 char buf[200];
12006 int res;
12007 const char *pos;
12008 size_t mnc_len;
12009 char plmn_mcc[4];
12010 char plmn_mnc[4];
12011
12012 id = add_cred(ifname);
12013 if (id < 0)
12014 return -2;
12015 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
12016
12017 val = get_param(cmd, "prefer");
12018 if (val && atoi(val) > 0)
12019 set_cred(ifname, id, "priority", "1");
12020
12021 val = get_param(cmd, "PLMN_MCC");
12022 if (val == NULL) {
12023 send_resp(dut, conn, SIGMA_ERROR,
12024 "errorCode,Missing PLMN_MCC");
12025 return 0;
12026 }
12027 if (strlen(val) != 3) {
12028 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MCC");
12029 return 0;
12030 }
12031 snprintf(plmn_mcc, sizeof(plmn_mcc), "%s", val);
12032
12033 val = get_param(cmd, "PLMN_MNC");
12034 if (val == NULL) {
12035 send_resp(dut, conn, SIGMA_ERROR,
12036 "errorCode,Missing PLMN_MNC");
12037 return 0;
12038 }
12039 if (strlen(val) != 2 && strlen(val) != 3) {
12040 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MNC");
12041 return 0;
12042 }
12043 snprintf(plmn_mnc, sizeof(plmn_mnc), "%s", val);
12044
12045 val = get_param(cmd, "IMSI");
12046 if (val == NULL) {
12047 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing SIM "
12048 "IMSI");
12049 return 0;
12050 }
12051
12052 imsi = pos = val;
12053
12054 if (strncmp(plmn_mcc, pos, 3) != 0) {
12055 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MCC mismatch");
12056 return 0;
12057 }
12058 pos += 3;
12059
12060 mnc_len = strlen(plmn_mnc);
12061 if (mnc_len < 2) {
12062 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC not set");
12063 return 0;
12064 }
12065
12066 if (strncmp(plmn_mnc, pos, mnc_len) != 0) {
12067 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC mismatch");
12068 return 0;
12069 }
12070 pos += mnc_len;
12071
12072 res = snprintf(buf, sizeof(buf), "%s%s-%s",plmn_mcc, plmn_mnc, pos);
12073 if (res < 0 || res >= (int) sizeof(buf))
12074 return -1;
12075 if (set_cred_quoted(ifname, id, "imsi", buf) < 0) {
12076 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12077 "not set IMSI");
12078 return 0;
12079 }
12080
12081 val = get_param(cmd, "Password");
12082 if (val && set_cred_quoted(ifname, id, "milenage", val) < 0) {
12083 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12084 "not set password");
12085 return 0;
12086 }
12087
Jouni Malinenba630452018-06-22 11:49:59 +030012088 if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012089 /*
12090 * Set provisioning_sp for the test cases where SIM/USIM
12091 * provisioning is used.
12092 */
12093 if (val && set_cred_quoted(ifname, id, "provisioning_sp",
12094 "wi-fi.org") < 0) {
12095 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12096 "not set provisioning_sp");
12097 return 0;
12098 }
12099
12100 update_devdetail_imsi(dut, imsi);
12101 }
12102
12103 return 1;
12104}
12105
12106
12107static int sta_add_credential_cert(struct sigma_dut *dut,
12108 struct sigma_conn *conn,
12109 const char *ifname,
12110 struct sigma_cmd *cmd)
12111{
12112 const char *val;
12113 int id;
12114
12115 id = add_cred(ifname);
12116 if (id < 0)
12117 return -2;
12118 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
12119
12120 val = get_param(cmd, "prefer");
12121 if (val && atoi(val) > 0)
12122 set_cred(ifname, id, "priority", "1");
12123
12124 val = get_param(cmd, "REALM");
12125 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
12126 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12127 "realm");
12128 return 0;
12129 }
12130
12131 val = get_param(cmd, "HOME_FQDN");
12132 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
12133 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12134 "home_fqdn");
12135 return 0;
12136 }
12137
12138 val = get_param(cmd, "Username");
12139 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
12140 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12141 "username");
12142 return 0;
12143 }
12144
12145 val = get_param(cmd, "clientCertificate");
12146 if (val) {
12147 char fname[200];
12148 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
12149#ifdef __linux__
12150 if (!file_exists(fname)) {
12151 char msg[300];
12152 snprintf(msg, sizeof(msg),
12153 "ErrorCode,clientCertificate "
12154 "file (%s) not found", fname);
12155 send_resp(dut, conn, SIGMA_ERROR, msg);
12156 return 0;
12157 }
12158#endif /* __linux__ */
12159 if (set_cred_quoted(ifname, id, "client_cert", fname) < 0) {
12160 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12161 "not set client_cert");
12162 return 0;
12163 }
12164 if (set_cred_quoted(ifname, id, "private_key", fname) < 0) {
12165 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12166 "not set private_key");
12167 return 0;
12168 }
12169 }
12170
12171 val = get_param(cmd, "ROOT_CA");
12172 if (val) {
12173 char fname[200];
12174 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
12175#ifdef __linux__
12176 if (!file_exists(fname)) {
12177 char msg[300];
12178 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
12179 "file (%s) not found", fname);
12180 send_resp(dut, conn, SIGMA_ERROR, msg);
12181 return 0;
12182 }
12183#endif /* __linux__ */
12184 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
12185 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12186 "not set root CA");
12187 return 0;
12188 }
12189 }
12190
12191 return 1;
12192}
12193
12194
12195static int cmd_sta_add_credential(struct sigma_dut *dut,
12196 struct sigma_conn *conn,
12197 struct sigma_cmd *cmd)
12198{
12199 const char *intf = get_param(cmd, "Interface");
12200 const char *type;
12201
12202 start_sta_mode(dut);
12203
12204 type = get_param(cmd, "Type");
12205 if (!type)
12206 return -1;
12207
12208 if (strcasecmp(type, "uname_pwd") == 0)
12209 return sta_add_credential_uname_pwd(dut, conn, intf, cmd);
12210
12211 if (strcasecmp(type, "sim") == 0)
12212 return sta_add_credential_sim(dut, conn, intf, cmd);
12213
12214 if (strcasecmp(type, "cert") == 0)
12215 return sta_add_credential_cert(dut, conn, intf, cmd);
12216
12217 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported credential "
12218 "type");
12219 return 0;
12220}
12221
12222
12223static int cmd_sta_scan(struct sigma_dut *dut, struct sigma_conn *conn,
12224 struct sigma_cmd *cmd)
12225{
12226 const char *intf = get_param(cmd, "Interface");
vamsi krishna89ad8c62017-09-19 12:51:18 +053012227 const char *val, *bssid, *ssid;
Arif Hussain66a4af02019-02-07 15:04:51 -080012228 char buf[4096];
vamsi krishna89ad8c62017-09-19 12:51:18 +053012229 char ssid_hex[65];
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012230 int res;
12231
Arif Hussain66a4af02019-02-07 15:04:51 -080012232 val = get_param(cmd, "GetParameter");
12233 if (val && strcmp(val, "SSID_BSSID") == 0) {
12234 if (get_wpa_ssid_bssid(dut, get_station_ifname(),
12235 buf, sizeof(buf)) < 0) {
12236 sigma_dut_print(dut, DUT_MSG_ERROR,
12237 "Could not get ssid bssid");
12238 return ERROR_SEND_STATUS;
12239 }
12240
12241 sigma_dut_print(dut, DUT_MSG_INFO, "%s", buf);
12242 send_resp(dut, conn, SIGMA_COMPLETE, buf);
12243 return STATUS_SENT;
12244 }
12245
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012246 val = get_param(cmd, "HESSID");
12247 if (val) {
12248 res = snprintf(buf, sizeof(buf), "SET hessid %s", val);
12249 if (res < 0 || res >= (int) sizeof(buf))
12250 return -1;
12251 wpa_command(intf, buf);
12252 }
12253
12254 val = get_param(cmd, "ACCS_NET_TYPE");
12255 if (val) {
12256 res = snprintf(buf, sizeof(buf), "SET access_network_type %s",
12257 val);
12258 if (res < 0 || res >= (int) sizeof(buf))
12259 return -1;
12260 wpa_command(intf, buf);
12261 }
12262
vamsi krishna89ad8c62017-09-19 12:51:18 +053012263 bssid = get_param(cmd, "Bssid");
12264 ssid = get_param(cmd, "Ssid");
12265
12266 if (ssid) {
12267 if (2 * strlen(ssid) >= sizeof(ssid_hex)) {
12268 send_resp(dut, conn, SIGMA_ERROR,
12269 "ErrorCode,Too long SSID");
12270 return 0;
12271 }
12272 ascii2hexstr(ssid, ssid_hex);
12273 }
12274
12275 res = snprintf(buf, sizeof(buf), "SCAN%s%s%s%s",
12276 bssid ? " bssid=": "",
12277 bssid ? bssid : "",
12278 ssid ? " ssid " : "",
12279 ssid ? ssid_hex : "");
12280 if (res < 0 || res >= (int) sizeof(buf))
12281 return -1;
12282
12283 if (wpa_command(intf, buf)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012284 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not start "
12285 "scan");
12286 return 0;
12287 }
12288
12289 return 1;
12290}
12291
12292
Jouni Malinen5e5d43d2018-01-10 17:29:33 +020012293static int cmd_sta_scan_bss(struct sigma_dut *dut, struct sigma_conn *conn,
12294 struct sigma_cmd *cmd)
12295{
12296 const char *intf = get_param(cmd, "Interface");
12297 const char *bssid;
12298 char buf[4096], *pos;
12299 int freq, chan;
12300 char *ssid;
12301 char resp[100];
12302 int res;
12303 struct wpa_ctrl *ctrl;
12304
12305 bssid = get_param(cmd, "BSSID");
12306 if (!bssid) {
12307 send_resp(dut, conn, SIGMA_INVALID,
12308 "errorCode,BSSID argument is missing");
12309 return 0;
12310 }
12311
12312 ctrl = open_wpa_mon(intf);
12313 if (!ctrl) {
12314 sigma_dut_print(dut, DUT_MSG_ERROR,
12315 "Failed to open wpa_supplicant monitor connection");
12316 return -1;
12317 }
12318
12319 if (wpa_command(intf, "SCAN TYPE=ONLY")) {
12320 send_resp(dut, conn, SIGMA_ERROR,
12321 "errorCode,Could not start scan");
12322 wpa_ctrl_detach(ctrl);
12323 wpa_ctrl_close(ctrl);
12324 return 0;
12325 }
12326
12327 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
12328 buf, sizeof(buf));
12329
12330 wpa_ctrl_detach(ctrl);
12331 wpa_ctrl_close(ctrl);
12332
12333 if (res < 0) {
12334 send_resp(dut, conn, SIGMA_ERROR,
12335 "errorCode,Scan did not complete");
12336 return 0;
12337 }
12338
12339 snprintf(buf, sizeof(buf), "BSS %s", bssid);
12340 if (wpa_command_resp(intf, buf, buf, sizeof(buf)) < 0 ||
12341 strncmp(buf, "id=", 3) != 0) {
12342 send_resp(dut, conn, SIGMA_ERROR,
12343 "errorCode,Specified BSSID not found");
12344 return 0;
12345 }
12346
12347 pos = strstr(buf, "\nfreq=");
12348 if (!pos) {
12349 send_resp(dut, conn, SIGMA_ERROR,
12350 "errorCode,Channel not found");
12351 return 0;
12352 }
12353 freq = atoi(pos + 6);
12354 chan = freq_to_channel(freq);
12355
12356 pos = strstr(buf, "\nssid=");
12357 if (!pos) {
12358 send_resp(dut, conn, SIGMA_ERROR,
12359 "errorCode,SSID not found");
12360 return 0;
12361 }
12362 ssid = pos + 6;
12363 pos = strchr(ssid, '\n');
12364 if (pos)
12365 *pos = '\0';
12366 snprintf(resp, sizeof(resp), "ssid,%s,bsschannel,%d", ssid, chan);
12367 send_resp(dut, conn, SIGMA_COMPLETE, resp);
12368 return 0;
12369}
12370
12371
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012372static int cmd_sta_set_systime(struct sigma_dut *dut, struct sigma_conn *conn,
12373 struct sigma_cmd *cmd)
12374{
12375#ifdef __linux__
12376 struct timeval tv;
12377 struct tm tm;
12378 time_t t;
12379 const char *val;
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +053012380 int v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012381
12382 wpa_command(get_station_ifname(), "PMKSA_FLUSH");
12383
12384 memset(&tm, 0, sizeof(tm));
12385 val = get_param(cmd, "seconds");
12386 if (val)
12387 tm.tm_sec = atoi(val);
12388 val = get_param(cmd, "minutes");
12389 if (val)
12390 tm.tm_min = atoi(val);
12391 val = get_param(cmd, "hours");
12392 if (val)
12393 tm.tm_hour = atoi(val);
12394 val = get_param(cmd, "date");
12395 if (val)
12396 tm.tm_mday = atoi(val);
12397 val = get_param(cmd, "month");
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +053012398 if (val) {
12399 v = atoi(val);
12400 if (v < 1 || v > 12) {
12401 send_resp(dut, conn, SIGMA_INVALID,
12402 "errorCode,Invalid month");
12403 return 0;
12404 }
12405 tm.tm_mon = v - 1;
12406 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012407 val = get_param(cmd, "year");
12408 if (val) {
12409 int year = atoi(val);
12410#ifdef ANDROID
12411 if (year > 2035)
12412 year = 2035; /* years beyond 2035 not supported */
12413#endif /* ANDROID */
12414 tm.tm_year = year - 1900;
12415 }
12416 t = mktime(&tm);
12417 if (t == (time_t) -1) {
12418 send_resp(dut, conn, SIGMA_ERROR,
12419 "errorCode,Invalid date or time");
12420 return 0;
12421 }
12422
12423 memset(&tv, 0, sizeof(tv));
12424 tv.tv_sec = t;
12425
12426 if (settimeofday(&tv, NULL) < 0) {
12427 sigma_dut_print(dut, DUT_MSG_INFO, "settimeofday failed: %s",
12428 strerror(errno));
12429 send_resp(dut, conn, SIGMA_ERROR,
12430 "errorCode,Failed to set time");
12431 return 0;
12432 }
12433
12434 return 1;
12435#endif /* __linux__ */
12436
12437 return -1;
12438}
12439
12440
12441static int cmd_sta_osu(struct sigma_dut *dut, struct sigma_conn *conn,
12442 struct sigma_cmd *cmd)
12443{
12444 const char *intf = get_param(cmd, "Interface");
Jouni Malinen4c8681c2018-09-12 23:28:11 +030012445 const char *name, *osu_ssid, *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012446 int prod_ess_assoc = 1;
Jouni Malinen4c8681c2018-09-12 23:28:11 +030012447 char buf[300], bssid[100], ssid[100];
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012448 int res;
12449 struct wpa_ctrl *ctrl;
12450
12451 name = get_param(cmd, "osuFriendlyName");
Jouni Malinen4c8681c2018-09-12 23:28:11 +030012452 osu_ssid = get_param(cmd, "osu_ssid");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012453
12454 val = get_param(cmd, "ProdESSAssoc");
12455 if (val)
12456 prod_ess_assoc = atoi(val);
12457
12458 kill_dhcp_client(dut, intf);
12459 if (start_dhcp_client(dut, intf) < 0)
12460 return -2;
12461
12462 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger OSU");
12463 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
12464 res = snprintf(buf, sizeof(buf),
Jouni Malinen4c8681c2018-09-12 23:28:11 +030012465 "%s %s%s%s %s%s%s signup osu-ca.pem",
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012466 prod_ess_assoc ? "" : "-N",
12467 name ? "-O'" : "", name ? name : "",
Jouni Malinen4c8681c2018-09-12 23:28:11 +030012468 name ? "'" : "",
12469 osu_ssid ? "-o'" : "", osu_ssid ? osu_ssid : "",
12470 osu_ssid ? "'" : "");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012471
Kanchanapally, Vidyullatha12b66762015-12-31 16:46:42 +053012472 hs2_set_policy(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012473 if (run_hs20_osu(dut, buf) < 0) {
12474 FILE *f;
12475
12476 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to complete OSU");
12477
12478 f = fopen("hs20-osu-client.res", "r");
12479 if (f) {
12480 char resp[400], res[300], *pos;
12481 if (!fgets(res, sizeof(res), f))
12482 res[0] = '\0';
12483 pos = strchr(res, '\n');
12484 if (pos)
12485 *pos = '\0';
12486 fclose(f);
12487 sigma_dut_summary(dut, "hs20-osu-client provisioning failed: %s",
12488 res);
12489 snprintf(resp, sizeof(resp), "notify-send '%s'", res);
12490 if (system(resp) != 0) {
12491 }
12492 snprintf(resp, sizeof(resp),
12493 "SSID,,BSSID,,failureReason,%s", res);
12494 send_resp(dut, conn, SIGMA_COMPLETE, resp);
12495 return 0;
12496 }
12497
12498 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
12499 return 0;
12500 }
12501
12502 if (!prod_ess_assoc)
12503 goto report;
12504
12505 ctrl = open_wpa_mon(intf);
12506 if (ctrl == NULL) {
12507 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
12508 "wpa_supplicant monitor connection");
12509 return -1;
12510 }
12511
12512 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
12513 buf, sizeof(buf));
12514
12515 wpa_ctrl_detach(ctrl);
12516 wpa_ctrl_close(ctrl);
12517
12518 if (res < 0) {
12519 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to connect to "
12520 "network after OSU");
12521 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
12522 return 0;
12523 }
12524
12525report:
12526 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
12527 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
12528 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to get BSSID/SSID");
12529 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
12530 return 0;
12531 }
12532
12533 snprintf(buf, sizeof(buf), "SSID,%s,BSSID,%s", ssid, bssid);
12534 send_resp(dut, conn, SIGMA_COMPLETE, buf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012535 return 0;
12536}
12537
12538
12539static int cmd_sta_policy_update(struct sigma_dut *dut, struct sigma_conn *conn,
12540 struct sigma_cmd *cmd)
12541{
12542 const char *val;
12543 int timeout = 120;
12544
12545 val = get_param(cmd, "PolicyUpdate");
12546 if (val == NULL || atoi(val) == 0)
12547 return 1; /* No operation requested */
12548
12549 val = get_param(cmd, "Timeout");
12550 if (val)
12551 timeout = atoi(val);
12552
12553 if (timeout) {
12554 /* TODO: time out the command and return
12555 * PolicyUpdateStatus,TIMEOUT if needed. */
12556 }
12557
12558 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger policy update");
12559 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
12560 if (run_hs20_osu(dut, "pol_upd fqdn=wi-fi.org") < 0) {
12561 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,FAIL");
12562 return 0;
12563 }
12564
12565 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,SUCCESS");
12566 return 0;
12567}
12568
12569
12570static int cmd_sta_er_config(struct sigma_dut *dut, struct sigma_conn *conn,
12571 struct sigma_cmd *cmd)
12572{
12573 struct wpa_ctrl *ctrl;
12574 const char *intf = get_param(cmd, "Interface");
12575 const char *bssid = get_param(cmd, "Bssid");
12576 const char *ssid = get_param(cmd, "SSID");
12577 const char *security = get_param(cmd, "Security");
12578 const char *passphrase = get_param(cmd, "Passphrase");
12579 const char *pin = get_param(cmd, "PIN");
12580 char buf[1000];
12581 char ssid_hex[200], passphrase_hex[200];
12582 const char *keymgmt, *cipher;
12583
12584 if (intf == NULL)
12585 intf = get_main_ifname();
12586
12587 if (!bssid) {
12588 send_resp(dut, conn, SIGMA_ERROR,
12589 "ErrorCode,Missing Bssid argument");
12590 return 0;
12591 }
12592
12593 if (!ssid) {
12594 send_resp(dut, conn, SIGMA_ERROR,
12595 "ErrorCode,Missing SSID argument");
12596 return 0;
12597 }
12598
12599 if (!security) {
12600 send_resp(dut, conn, SIGMA_ERROR,
12601 "ErrorCode,Missing Security argument");
12602 return 0;
12603 }
12604
12605 if (!passphrase) {
12606 send_resp(dut, conn, SIGMA_ERROR,
12607 "ErrorCode,Missing Passphrase argument");
12608 return 0;
12609 }
12610
12611 if (!pin) {
12612 send_resp(dut, conn, SIGMA_ERROR,
12613 "ErrorCode,Missing PIN argument");
12614 return 0;
12615 }
12616
vamsi krishna8c9c1562017-05-12 15:51:46 +053012617 if (2 * strlen(ssid) >= sizeof(ssid_hex) ||
12618 2 * strlen(passphrase) >= sizeof(passphrase_hex)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012619 send_resp(dut, conn, SIGMA_ERROR,
12620 "ErrorCode,Too long SSID/passphrase");
12621 return 0;
12622 }
12623
12624 ctrl = open_wpa_mon(intf);
12625 if (ctrl == NULL) {
12626 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
12627 "wpa_supplicant monitor connection");
12628 return -2;
12629 }
12630
12631 if (strcasecmp(security, "wpa2-psk") == 0) {
12632 keymgmt = "WPA2PSK";
12633 cipher = "CCMP";
12634 } else {
12635 wpa_ctrl_detach(ctrl);
12636 wpa_ctrl_close(ctrl);
12637 send_resp(dut, conn, SIGMA_ERROR,
12638 "ErrorCode,Unsupported Security value");
12639 return 0;
12640 }
12641
12642 ascii2hexstr(ssid, ssid_hex);
12643 ascii2hexstr(passphrase, passphrase_hex);
12644 snprintf(buf, sizeof(buf), "WPS_REG %s %s %s %s %s %s",
12645 bssid, pin, ssid_hex, keymgmt, cipher, passphrase_hex);
12646
12647 if (wpa_command(intf, buf) < 0) {
12648 wpa_ctrl_detach(ctrl);
12649 wpa_ctrl_close(ctrl);
12650 send_resp(dut, conn, SIGMA_ERROR,
12651 "ErrorCode,Failed to start registrar");
12652 return 0;
12653 }
12654
12655 snprintf(dut->er_oper_bssid, sizeof(dut->er_oper_bssid), "%s", bssid);
12656 dut->er_oper_performed = 1;
12657
12658 return wps_connection_event(dut, conn, ctrl, intf, 0);
12659}
12660
12661
12662static int cmd_sta_wps_connect_pw_token(struct sigma_dut *dut,
12663 struct sigma_conn *conn,
12664 struct sigma_cmd *cmd)
12665{
12666 struct wpa_ctrl *ctrl;
12667 const char *intf = get_param(cmd, "Interface");
12668 const char *bssid = get_param(cmd, "Bssid");
12669 char buf[100];
12670
12671 if (!bssid) {
12672 send_resp(dut, conn, SIGMA_ERROR,
12673 "ErrorCode,Missing Bssid argument");
12674 return 0;
12675 }
12676
12677 ctrl = open_wpa_mon(intf);
12678 if (ctrl == NULL) {
12679 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
12680 "wpa_supplicant monitor connection");
12681 return -2;
12682 }
12683
12684 snprintf(buf, sizeof(buf), "WPS_NFC %s", bssid);
12685
12686 if (wpa_command(intf, buf) < 0) {
12687 wpa_ctrl_detach(ctrl);
12688 wpa_ctrl_close(ctrl);
12689 send_resp(dut, conn, SIGMA_ERROR,
12690 "ErrorCode,Failed to start registrar");
12691 return 0;
12692 }
12693
12694 return wps_connection_event(dut, conn, ctrl, intf, 0);
12695}
12696
12697
vamsi krishna9b144002017-09-20 13:28:13 +053012698static int cmd_start_wps_registration(struct sigma_dut *dut,
12699 struct sigma_conn *conn,
12700 struct sigma_cmd *cmd)
12701{
12702 struct wpa_ctrl *ctrl;
12703 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020012704 const char *network_mode = get_param(cmd, "network_mode");
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020012705 const char *config_method = get_param(cmd, "WPSConfigMethod");
12706 const char *role;
vamsi krishna9b144002017-09-20 13:28:13 +053012707 int res;
12708 char buf[256];
12709 const char *events[] = {
12710 "CTRL-EVENT-CONNECTED",
12711 "WPS-OVERLAP-DETECTED",
12712 "WPS-TIMEOUT",
12713 "WPS-FAIL",
12714 NULL
12715 };
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020012716 int id = 0;
vamsi krishna9b144002017-09-20 13:28:13 +053012717
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020012718 /* 60G WPS tests do not pass Interface parameter */
12719 if (!intf)
12720 intf = get_main_ifname();
12721
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020012722 if (dut->mode == SIGMA_MODE_AP)
12723 return ap_wps_registration(dut, conn, cmd);
12724
12725 if (config_method) {
12726 /* WFA_CS_WPS_PIN_KEYPAD mode is set when using the
12727 * sta_wps_enter_pin before calling start_wps_registration. */
12728 if (strcasecmp(config_method, "PBC") == 0)
12729 dut->wps_method = WFA_CS_WPS_PBC;
12730 }
12731 if (dut->wps_method == WFA_CS_WPS_NOT_READY) {
12732 send_resp(dut, conn, SIGMA_ERROR,
12733 "ErrorCode,WPS parameters not yet set");
12734 return STATUS_SENT;
12735 }
12736
12737 /* Make sure WPS is enabled (also for STA mode) */
12738 dut->wps_disable = 0;
12739
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020012740 if (dut->band == WPS_BAND_60G && network_mode &&
12741 strcasecmp(network_mode, "PBSS") == 0) {
12742 sigma_dut_print(dut, DUT_MSG_DEBUG,
12743 "Set PBSS network mode, network id %d", id);
12744 if (set_network(get_station_ifname(), id, "pbss", "1") < 0)
12745 return -2;
12746 }
12747
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020012748 if (dut->force_rsn_ie) {
12749 sigma_dut_print(dut, DUT_MSG_DEBUG, "Force RSN_IE: %d",
12750 dut->force_rsn_ie);
12751 if (sta_60g_force_rsn_ie(dut, dut->force_rsn_ie) < 0) {
12752 sigma_dut_print(dut, DUT_MSG_INFO,
12753 "Failed to force RSN_IE");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020012754 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020012755 }
12756 }
12757
vamsi krishna9b144002017-09-20 13:28:13 +053012758 ctrl = open_wpa_mon(intf);
12759 if (!ctrl) {
12760 sigma_dut_print(dut, DUT_MSG_ERROR,
12761 "Failed to open wpa_supplicant monitor connection");
12762 return -2;
12763 }
12764
12765 role = get_param(cmd, "WpsRole");
12766 if (!role) {
12767 send_resp(dut, conn, SIGMA_INVALID,
12768 "ErrorCode,WpsRole not provided");
12769 goto fail;
12770 }
12771
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020012772 if (strcasecmp(role, "Enrollee") != 0) {
12773 /* Registrar role for STA not supported */
12774 send_resp(dut, conn, SIGMA_ERROR,
12775 "ErrorCode,Unsupported WpsRole value");
12776 goto fail;
12777 }
12778
12779 if (is_60g_sigma_dut(dut)) {
12780 if (dut->wps_method == WFA_CS_WPS_PBC)
12781 snprintf(buf, sizeof(buf), "WPS_PBC");
12782 else /* WFA_CS_WPS_PIN_KEYPAD */
12783 snprintf(buf, sizeof(buf), "WPS_PIN any %s",
12784 dut->wps_pin);
12785 if (wpa_command(intf, buf) < 0) {
12786 send_resp(dut, conn, SIGMA_ERROR,
12787 "ErrorCode,Failed to start WPS");
vamsi krishna9b144002017-09-20 13:28:13 +053012788 goto fail;
12789 }
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020012790 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
12791 if (res < 0) {
12792 send_resp(dut, conn, SIGMA_ERROR,
12793 "ErrorCode,WPS connection did not complete");
12794 goto fail;
12795 }
12796 if (strstr(buf, "WPS-TIMEOUT")) {
12797 send_resp(dut, conn, SIGMA_COMPLETE, "WpsState,NoPeer");
12798 } else if (strstr(buf, "WPS-OVERLAP-DETECTED")) {
12799 send_resp(dut, conn, SIGMA_COMPLETE,
12800 "WpsState,OverlapSession");
12801 } else if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
12802 send_resp(dut, conn, SIGMA_COMPLETE,
12803 "WpsState,Successful");
12804 } else {
12805 send_resp(dut, conn, SIGMA_COMPLETE,
12806 "WpsState,Failure");
12807 }
12808 } else {
12809 if (dut->wps_method == WFA_CS_WPS_PBC) {
vamsi krishna9b144002017-09-20 13:28:13 +053012810 if (wpa_command(intf, "WPS_PBC") < 0) {
12811 send_resp(dut, conn, SIGMA_ERROR,
12812 "ErrorCode,Failed to enable PBC");
12813 goto fail;
12814 }
12815 } else {
12816 /* TODO: PIN method */
12817 send_resp(dut, conn, SIGMA_ERROR,
12818 "ErrorCode,Unsupported WpsConfigMethod value");
12819 goto fail;
12820 }
12821 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
12822 if (res < 0) {
12823 send_resp(dut, conn, SIGMA_ERROR,
12824 "ErrorCode,WPS connection did not complete");
12825 goto fail;
12826 }
12827 if (strstr(buf, "WPS-TIMEOUT")) {
12828 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,NoPeer");
12829 } else if (strstr(buf, "WPS-OVERLAP-DETECTED")) {
12830 send_resp(dut, conn, SIGMA_ERROR,
12831 "ErrorCode,OverlapSession");
12832 } else if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
12833 send_resp(dut, conn, SIGMA_COMPLETE, "Successful");
12834 } else {
12835 send_resp(dut, conn, SIGMA_ERROR,
12836 "ErrorCode,WPS operation failed");
12837 }
vamsi krishna9b144002017-09-20 13:28:13 +053012838 }
12839
12840fail:
12841 wpa_ctrl_detach(ctrl);
12842 wpa_ctrl_close(ctrl);
12843 return 0;
12844}
12845
12846
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012847static int req_intf(struct sigma_cmd *cmd)
12848{
12849 return get_param(cmd, "interface") == NULL ? -1 : 0;
12850}
12851
12852
12853void sta_register_cmds(void)
12854{
12855 sigma_dut_reg_cmd("sta_get_ip_config", req_intf,
12856 cmd_sta_get_ip_config);
12857 sigma_dut_reg_cmd("sta_set_ip_config", req_intf,
12858 cmd_sta_set_ip_config);
12859 sigma_dut_reg_cmd("sta_get_info", req_intf, cmd_sta_get_info);
12860 sigma_dut_reg_cmd("sta_get_mac_address", req_intf,
12861 cmd_sta_get_mac_address);
12862 sigma_dut_reg_cmd("sta_is_connected", req_intf, cmd_sta_is_connected);
12863 sigma_dut_reg_cmd("sta_verify_ip_connection", req_intf,
12864 cmd_sta_verify_ip_connection);
12865 sigma_dut_reg_cmd("sta_get_bssid", req_intf, cmd_sta_get_bssid);
12866 sigma_dut_reg_cmd("sta_set_encryption", req_intf,
12867 cmd_sta_set_encryption);
12868 sigma_dut_reg_cmd("sta_set_psk", req_intf, cmd_sta_set_psk);
12869 sigma_dut_reg_cmd("sta_set_eaptls", req_intf, cmd_sta_set_eaptls);
12870 sigma_dut_reg_cmd("sta_set_eapttls", req_intf, cmd_sta_set_eapttls);
12871 sigma_dut_reg_cmd("sta_set_eapsim", req_intf, cmd_sta_set_eapsim);
12872 sigma_dut_reg_cmd("sta_set_peap", req_intf, cmd_sta_set_peap);
12873 sigma_dut_reg_cmd("sta_set_eapfast", req_intf, cmd_sta_set_eapfast);
12874 sigma_dut_reg_cmd("sta_set_eapaka", req_intf, cmd_sta_set_eapaka);
12875 sigma_dut_reg_cmd("sta_set_eapakaprime", req_intf,
12876 cmd_sta_set_eapakaprime);
12877 sigma_dut_reg_cmd("sta_set_security", req_intf, cmd_sta_set_security);
12878 sigma_dut_reg_cmd("sta_set_uapsd", req_intf, cmd_sta_set_uapsd);
12879 /* TODO: sta_set_ibss */
12880 /* TODO: sta_set_mode */
12881 sigma_dut_reg_cmd("sta_set_wmm", req_intf, cmd_sta_set_wmm);
12882 sigma_dut_reg_cmd("sta_associate", req_intf, cmd_sta_associate);
12883 /* TODO: sta_up_load */
12884 sigma_dut_reg_cmd("sta_preset_testparameters", req_intf,
12885 cmd_sta_preset_testparameters);
12886 /* TODO: sta_set_system */
12887 sigma_dut_reg_cmd("sta_set_11n", req_intf, cmd_sta_set_11n);
12888 /* TODO: sta_set_rifs_test */
12889 sigma_dut_reg_cmd("sta_set_wireless", req_intf, cmd_sta_set_wireless);
12890 sigma_dut_reg_cmd("sta_send_addba", req_intf, cmd_sta_send_addba);
12891 /* TODO: sta_send_coexist_mgmt */
12892 sigma_dut_reg_cmd("sta_disconnect", req_intf, cmd_sta_disconnect);
12893 sigma_dut_reg_cmd("sta_reassoc", req_intf, cmd_sta_reassoc);
12894 sigma_dut_reg_cmd("sta_reassociate", req_intf, cmd_sta_reassoc);
12895 sigma_dut_reg_cmd("sta_reset_default", req_intf,
12896 cmd_sta_reset_default);
12897 sigma_dut_reg_cmd("sta_send_frame", req_intf, cmd_sta_send_frame);
12898 sigma_dut_reg_cmd("sta_set_macaddr", req_intf, cmd_sta_set_macaddr);
12899 sigma_dut_reg_cmd("sta_set_rfeature", req_intf, cmd_sta_set_rfeature);
12900 sigma_dut_reg_cmd("sta_set_radio", req_intf, cmd_sta_set_radio);
12901 sigma_dut_reg_cmd("sta_set_pwrsave", req_intf, cmd_sta_set_pwrsave);
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020012902 sigma_dut_reg_cmd("sta_set_power_save", req_intf, cmd_sta_set_pwrsave);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012903 sigma_dut_reg_cmd("sta_bssid_pool", req_intf, cmd_sta_bssid_pool);
12904 sigma_dut_reg_cmd("sta_reset_parm", req_intf, cmd_sta_reset_parm);
12905 sigma_dut_reg_cmd("sta_get_key", req_intf, cmd_sta_get_key);
12906 sigma_dut_reg_cmd("sta_hs2_associate", req_intf,
12907 cmd_sta_hs2_associate);
Jouni Malinenb639f1c2018-09-13 02:39:46 +030012908 sigma_dut_reg_cmd("sta_hs2_venue_info", req_intf,
12909 cmd_sta_hs2_venue_info);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012910 sigma_dut_reg_cmd("sta_add_credential", req_intf,
12911 cmd_sta_add_credential);
12912 sigma_dut_reg_cmd("sta_scan", req_intf, cmd_sta_scan);
Jouni Malinen5e5d43d2018-01-10 17:29:33 +020012913 sigma_dut_reg_cmd("sta_scan_bss", req_intf, cmd_sta_scan_bss);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012914 sigma_dut_reg_cmd("sta_set_systime", NULL, cmd_sta_set_systime);
12915 sigma_dut_reg_cmd("sta_osu", req_intf, cmd_sta_osu);
12916 sigma_dut_reg_cmd("sta_policy_update", req_intf, cmd_sta_policy_update);
12917 sigma_dut_reg_cmd("sta_er_config", NULL, cmd_sta_er_config);
12918 sigma_dut_reg_cmd("sta_wps_connect_pw_token", req_intf,
12919 cmd_sta_wps_connect_pw_token);
Jouni Malinen82905202018-04-29 17:20:10 +030012920 sigma_dut_reg_cmd("sta_exec_action", NULL, cmd_sta_exec_action);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012921 sigma_dut_reg_cmd("sta_get_events", req_intf, cmd_sta_get_events);
12922 sigma_dut_reg_cmd("sta_get_parameter", req_intf, cmd_sta_get_parameter);
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020012923 sigma_dut_reg_cmd("start_wps_registration", NULL,
vamsi krishna9b144002017-09-20 13:28:13 +053012924 cmd_start_wps_registration);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012925}