blob: 33be911e798030698f8135849dabf22049863c42 [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
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302270 if (username_identity) {
2271 val = get_param(cmd, "username");
2272 if (val) {
2273 if (set_network_quoted(ifname, id, "identity", val) < 0)
2274 return -2;
2275 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002276
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302277 val = get_param(cmd, "password");
2278 if (val) {
2279 if (set_network_quoted(ifname, id, "password", val) < 0)
2280 return -2;
2281 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002282 }
2283
Jouni Malinen8179fee2019-03-28 03:19:47 +02002284 if (dut->akm_values &
2285 ((1 << AKM_FILS_SHA256) |
2286 (1 << AKM_FILS_SHA384) |
2287 (1 << AKM_FT_FILS_SHA256) |
2288 (1 << AKM_FT_FILS_SHA384)))
2289 erp = 1;
2290 if (erp && set_network(ifname, id, "erp", "1") < 0)
2291 return ERROR_SEND_STATUS;
2292
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002293 return id;
2294}
2295
2296
Jouni Malinen5eabb2a2017-10-03 18:17:30 +03002297static int set_tls_cipher(const char *ifname, int id, const char *cipher)
2298{
2299 const char *val;
2300
2301 if (!cipher)
2302 return 0;
2303
2304 if (strcasecmp(cipher, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384") == 0)
2305 val = "ECDHE-ECDSA-AES256-GCM-SHA384";
2306 else if (strcasecmp(cipher,
2307 "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384") == 0)
2308 val = "ECDHE-RSA-AES256-GCM-SHA384";
2309 else if (strcasecmp(cipher, "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384") == 0)
2310 val = "DHE-RSA-AES256-GCM-SHA384";
2311 else if (strcasecmp(cipher,
2312 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256") == 0)
2313 val = "ECDHE-ECDSA-AES128-GCM-SHA256";
2314 else
2315 return -1;
2316
2317 /* Need to clear phase1="tls_suiteb=1" to allow cipher enforcement */
2318 set_network_quoted(ifname, id, "phase1", "");
2319
2320 return set_network_quoted(ifname, id, "openssl_ciphers", val);
2321}
2322
2323
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002324static int cmd_sta_set_eaptls(struct sigma_dut *dut, struct sigma_conn *conn,
2325 struct sigma_cmd *cmd)
2326{
2327 const char *intf = get_param(cmd, "Interface");
2328 const char *ifname, *val;
2329 int id;
2330 char buf[200];
2331#ifdef ANDROID
2332 unsigned char kvalue[KEYSTORE_MESSAGE_SIZE];
2333 int length;
2334 int jb_or_newer = 0;
2335 char prop[PROPERTY_VALUE_MAX];
2336#endif /* ANDROID */
2337
2338 if (intf == NULL)
2339 return -1;
2340
2341 if (strcmp(intf, get_main_ifname()) == 0)
2342 ifname = get_station_ifname();
2343 else
2344 ifname = intf;
2345
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302346 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002347 if (id < 0)
2348 return id;
2349
2350 if (set_network(ifname, id, "eap", "TLS") < 0)
2351 return -2;
2352
Pradeep Reddy POTTETI9f6c2132016-05-05 16:28:19 +05302353 if (!get_param(cmd, "username") &&
2354 set_network_quoted(ifname, id, "identity",
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002355 "wifi-user@wifilabs.local") < 0)
2356 return -2;
2357
2358 val = get_param(cmd, "clientCertificate");
2359 if (val == NULL)
2360 return -1;
2361#ifdef ANDROID
2362 snprintf(buf, sizeof(buf), "USRPKEY_%s", val);
2363 length = android_keystore_get(ANDROID_KEYSTORE_GET, buf, kvalue);
2364 if (length < 0) {
2365 /*
2366 * JB started reporting keystore type mismatches, so retry with
2367 * the GET_PUBKEY command if the generic GET fails.
2368 */
2369 length = android_keystore_get(ANDROID_KEYSTORE_GET_PUBKEY,
2370 buf, kvalue);
2371 }
2372
2373 if (property_get("ro.build.version.release", prop, NULL) != 0) {
2374 sigma_dut_print(dut, DUT_MSG_DEBUG, "Android release %s", prop);
2375 if (strncmp(prop, "4.0", 3) != 0)
2376 jb_or_newer = 1;
2377 } else
2378 jb_or_newer = 1; /* assume newer */
2379
2380 if (jb_or_newer && length > 0) {
2381 sigma_dut_print(dut, DUT_MSG_INFO,
2382 "Use Android keystore [%s]", buf);
2383 if (set_network(ifname, id, "engine", "1") < 0)
2384 return -2;
2385 if (set_network_quoted(ifname, id, "engine_id", "keystore") < 0)
2386 return -2;
2387 snprintf(buf, sizeof(buf), "USRPKEY_%s", val);
2388 if (set_network_quoted(ifname, id, "key_id", buf) < 0)
2389 return -2;
2390 snprintf(buf, sizeof(buf), "keystore://USRCERT_%s", val);
2391 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
2392 return -2;
2393 return 1;
2394 } else if (length > 0) {
2395 sigma_dut_print(dut, DUT_MSG_INFO,
2396 "Use Android keystore [%s]", buf);
2397 snprintf(buf, sizeof(buf), "keystore://USRPKEY_%s", val);
2398 if (set_network_quoted(ifname, id, "private_key", buf) < 0)
2399 return -2;
2400 snprintf(buf, sizeof(buf), "keystore://USRCERT_%s", val);
2401 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
2402 return -2;
2403 return 1;
2404 }
2405#endif /* ANDROID */
2406
2407 snprintf(buf, sizeof(buf), "%s/%s", sigma_cert_path, val);
2408#ifdef __linux__
2409 if (!file_exists(buf)) {
2410 char msg[300];
2411 snprintf(msg, sizeof(msg), "ErrorCode,clientCertificate file "
2412 "(%s) not found", buf);
2413 send_resp(dut, conn, SIGMA_ERROR, msg);
2414 return -3;
2415 }
2416#endif /* __linux__ */
2417 if (set_network_quoted(ifname, id, "private_key", buf) < 0)
2418 return -2;
2419 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
2420 return -2;
2421
2422 if (set_network_quoted(ifname, id, "private_key_passwd", "wifi") < 0)
2423 return -2;
2424
Jouni Malinen5eabb2a2017-10-03 18:17:30 +03002425 val = get_param(cmd, "keyMgmtType");
2426 if (val && strcasecmp(val, "SuiteB") == 0) {
2427 val = get_param(cmd, "CertType");
2428 if (val && strcasecmp(val, "RSA") == 0) {
2429 if (set_network_quoted(ifname, id, "phase1",
2430 "tls_suiteb=1") < 0)
2431 return -2;
2432 } else {
2433 if (set_network_quoted(ifname, id, "openssl_ciphers",
2434 "SUITEB192") < 0)
2435 return -2;
2436 }
2437
2438 val = get_param(cmd, "TLSCipher");
2439 if (set_tls_cipher(ifname, id, val) < 0) {
2440 send_resp(dut, conn, SIGMA_ERROR,
2441 "ErrorCode,Unsupported TLSCipher value");
2442 return -3;
2443 }
2444 }
2445
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002446 return 1;
2447}
2448
2449
2450static int cmd_sta_set_eapttls(struct sigma_dut *dut, struct sigma_conn *conn,
2451 struct sigma_cmd *cmd)
2452{
2453 const char *intf = get_param(cmd, "Interface");
2454 const char *ifname;
2455 int id;
2456
2457 if (intf == NULL)
2458 return -1;
2459
2460 if (strcmp(intf, get_main_ifname()) == 0)
2461 ifname = get_station_ifname();
2462 else
2463 ifname = intf;
2464
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302465 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002466 if (id < 0)
2467 return id;
2468
2469 if (set_network(ifname, id, "eap", "TTLS") < 0) {
2470 send_resp(dut, conn, SIGMA_ERROR,
2471 "errorCode,Failed to set TTLS method");
2472 return 0;
2473 }
2474
2475 if (set_network_quoted(ifname, id, "phase2", "auth=MSCHAPV2") < 0) {
2476 send_resp(dut, conn, SIGMA_ERROR,
2477 "errorCode,Failed to set MSCHAPv2 for TTLS Phase 2");
2478 return 0;
2479 }
2480
2481 return 1;
2482}
2483
2484
2485static int cmd_sta_set_eapsim(struct sigma_dut *dut, struct sigma_conn *conn,
2486 struct sigma_cmd *cmd)
2487{
2488 const char *intf = get_param(cmd, "Interface");
2489 const char *ifname;
2490 int id;
2491
2492 if (intf == NULL)
2493 return -1;
2494
2495 if (strcmp(intf, get_main_ifname()) == 0)
2496 ifname = get_station_ifname();
2497 else
2498 ifname = intf;
2499
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302500 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002501 if (id < 0)
2502 return id;
2503
2504 if (set_network(ifname, id, "eap", "SIM") < 0)
2505 return -2;
2506
2507 return 1;
2508}
2509
2510
2511static int cmd_sta_set_peap(struct sigma_dut *dut, struct sigma_conn *conn,
2512 struct sigma_cmd *cmd)
2513{
2514 const char *intf = get_param(cmd, "Interface");
2515 const char *ifname, *val;
2516 int id;
2517 char buf[100];
2518
2519 if (intf == NULL)
2520 return -1;
2521
2522 if (strcmp(intf, get_main_ifname()) == 0)
2523 ifname = get_station_ifname();
2524 else
2525 ifname = intf;
2526
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302527 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002528 if (id < 0)
2529 return id;
2530
2531 if (set_network(ifname, id, "eap", "PEAP") < 0)
2532 return -2;
2533
2534 val = get_param(cmd, "innerEAP");
2535 if (val) {
2536 if (strcasecmp(val, "MSCHAPv2") == 0) {
2537 if (set_network_quoted(ifname, id, "phase2",
2538 "auth=MSCHAPV2") < 0)
2539 return -2;
2540 } else if (strcasecmp(val, "GTC") == 0) {
2541 if (set_network_quoted(ifname, id, "phase2",
2542 "auth=GTC") < 0)
2543 return -2;
2544 } else
2545 return -1;
2546 }
2547
2548 val = get_param(cmd, "peapVersion");
2549 if (val) {
2550 int ver = atoi(val);
2551 if (ver < 0 || ver > 1)
2552 return -1;
2553 snprintf(buf, sizeof(buf), "peapver=%d", ver);
2554 if (set_network_quoted(ifname, id, "phase1", buf) < 0)
2555 return -2;
2556 }
2557
2558 return 1;
2559}
2560
2561
2562static int cmd_sta_set_eapfast(struct sigma_dut *dut, struct sigma_conn *conn,
2563 struct sigma_cmd *cmd)
2564{
2565 const char *intf = get_param(cmd, "Interface");
2566 const char *ifname, *val;
2567 int id;
2568 char buf[100];
2569
2570 if (intf == NULL)
2571 return -1;
2572
2573 if (strcmp(intf, get_main_ifname()) == 0)
2574 ifname = get_station_ifname();
2575 else
2576 ifname = intf;
2577
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302578 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002579 if (id < 0)
2580 return id;
2581
2582 if (set_network(ifname, id, "eap", "FAST") < 0)
2583 return -2;
2584
2585 val = get_param(cmd, "innerEAP");
2586 if (val) {
2587 if (strcasecmp(val, "MSCHAPV2") == 0) {
2588 if (set_network_quoted(ifname, id, "phase2",
2589 "auth=MSCHAPV2") < 0)
2590 return -2;
2591 } else if (strcasecmp(val, "GTC") == 0) {
2592 if (set_network_quoted(ifname, id, "phase2",
2593 "auth=GTC") < 0)
2594 return -2;
2595 } else
2596 return -1;
2597 }
2598
2599 val = get_param(cmd, "validateServer");
2600 if (val) {
2601 /* TODO */
2602 sigma_dut_print(dut, DUT_MSG_INFO, "Ignored EAP-FAST "
2603 "validateServer=%s", val);
2604 }
2605
2606 val = get_param(cmd, "pacFile");
2607 if (val) {
2608 snprintf(buf, sizeof(buf), "blob://%s", val);
2609 if (set_network_quoted(ifname, id, "pac_file", buf) < 0)
2610 return -2;
2611 }
2612
2613 if (set_network_quoted(ifname, id, "phase1", "fast_provisioning=2") <
2614 0)
2615 return -2;
2616
2617 return 1;
2618}
2619
2620
2621static int cmd_sta_set_eapaka(struct sigma_dut *dut, struct sigma_conn *conn,
2622 struct sigma_cmd *cmd)
2623{
2624 const char *intf = get_param(cmd, "Interface");
2625 const char *ifname;
2626 int id;
2627
2628 if (intf == NULL)
2629 return -1;
2630
2631 if (strcmp(intf, get_main_ifname()) == 0)
2632 ifname = get_station_ifname();
2633 else
2634 ifname = intf;
2635
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302636 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002637 if (id < 0)
2638 return id;
2639
2640 if (set_network(ifname, id, "eap", "AKA") < 0)
2641 return -2;
2642
2643 return 1;
2644}
2645
2646
2647static int cmd_sta_set_eapakaprime(struct sigma_dut *dut,
2648 struct sigma_conn *conn,
2649 struct sigma_cmd *cmd)
2650{
2651 const char *intf = get_param(cmd, "Interface");
2652 const char *ifname;
2653 int id;
2654
2655 if (intf == NULL)
2656 return -1;
2657
2658 if (strcmp(intf, get_main_ifname()) == 0)
2659 ifname = get_station_ifname();
2660 else
2661 ifname = intf;
2662
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302663 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002664 if (id < 0)
2665 return id;
2666
2667 if (set_network(ifname, id, "eap", "AKA'") < 0)
2668 return -2;
2669
2670 return 1;
2671}
2672
2673
2674static int sta_set_open(struct sigma_dut *dut, struct sigma_conn *conn,
2675 struct sigma_cmd *cmd)
2676{
2677 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002678 const char *network_mode = get_param(cmd, "network_mode");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002679 const char *ifname;
2680 int id;
2681
2682 if (strcmp(intf, get_main_ifname()) == 0)
2683 ifname = get_station_ifname();
2684 else
2685 ifname = intf;
2686
2687 id = add_network_common(dut, conn, ifname, cmd);
2688 if (id < 0)
2689 return id;
2690
2691 if (set_network(ifname, id, "key_mgmt", "NONE") < 0)
2692 return -2;
2693
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002694 if (dut->program == PROGRAM_60GHZ && network_mode &&
2695 strcasecmp(network_mode, "PBSS") == 0 &&
2696 set_network(ifname, id, "pbss", "1") < 0)
2697 return -2;
2698
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002699 return 1;
2700}
2701
2702
Jouni Malinen47dcc952017-10-09 16:43:24 +03002703static int sta_set_owe(struct sigma_dut *dut, struct sigma_conn *conn,
2704 struct sigma_cmd *cmd)
2705{
2706 const char *intf = get_param(cmd, "Interface");
2707 const char *ifname, *val;
2708 int id;
2709
2710 if (intf == NULL)
2711 return -1;
2712
2713 if (strcmp(intf, get_main_ifname()) == 0)
2714 ifname = get_station_ifname();
2715 else
2716 ifname = intf;
2717
2718 id = set_wpa_common(dut, conn, ifname, cmd);
2719 if (id < 0)
2720 return id;
2721
2722 if (set_network(ifname, id, "key_mgmt", "OWE") < 0)
2723 return -2;
2724
2725 val = get_param(cmd, "ECGroupID");
Jouni Malinenfac9cad2017-10-10 18:35:55 +03002726 if (val && strcmp(val, "0") == 0) {
2727 if (wpa_command(ifname,
2728 "VENDOR_ELEM_ADD 13 ff23200000783590fb7440e03d5b3b33911f86affdcc6b4411b707846ac4ff08ddc8831ccd") != 0) {
2729 sigma_dut_print(dut, DUT_MSG_ERROR,
2730 "Failed to set OWE DH Param element override");
2731 return -2;
2732 }
2733 } else if (val && set_network(ifname, id, "owe_group", val) < 0) {
Jouni Malinen47dcc952017-10-09 16:43:24 +03002734 sigma_dut_print(dut, DUT_MSG_ERROR,
2735 "Failed to clear owe_group");
2736 return -2;
2737 }
2738
2739 return 1;
2740}
2741
2742
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002743static int cmd_sta_set_security(struct sigma_dut *dut, struct sigma_conn *conn,
2744 struct sigma_cmd *cmd)
2745{
2746 const char *type = get_param(cmd, "Type");
2747
2748 if (type == NULL) {
2749 send_resp(dut, conn, SIGMA_ERROR,
2750 "ErrorCode,Missing Type argument");
2751 return 0;
2752 }
2753
2754 if (strcasecmp(type, "OPEN") == 0)
2755 return sta_set_open(dut, conn, cmd);
Jouni Malinen47dcc952017-10-09 16:43:24 +03002756 if (strcasecmp(type, "OWE") == 0)
2757 return sta_set_owe(dut, conn, cmd);
Jouni Malinen992a81e2017-08-22 13:57:47 +03002758 if (strcasecmp(type, "PSK") == 0 ||
Jouni Malinen0ab50f42017-08-31 01:34:59 +03002759 strcasecmp(type, "PSK-SAE") == 0 ||
Jouni Malinen992a81e2017-08-22 13:57:47 +03002760 strcasecmp(type, "SAE") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002761 return cmd_sta_set_psk(dut, conn, cmd);
2762 if (strcasecmp(type, "EAPTLS") == 0)
2763 return cmd_sta_set_eaptls(dut, conn, cmd);
2764 if (strcasecmp(type, "EAPTTLS") == 0)
2765 return cmd_sta_set_eapttls(dut, conn, cmd);
2766 if (strcasecmp(type, "EAPPEAP") == 0)
2767 return cmd_sta_set_peap(dut, conn, cmd);
2768 if (strcasecmp(type, "EAPSIM") == 0)
2769 return cmd_sta_set_eapsim(dut, conn, cmd);
2770 if (strcasecmp(type, "EAPFAST") == 0)
2771 return cmd_sta_set_eapfast(dut, conn, cmd);
2772 if (strcasecmp(type, "EAPAKA") == 0)
2773 return cmd_sta_set_eapaka(dut, conn, cmd);
2774 if (strcasecmp(type, "EAPAKAPRIME") == 0)
2775 return cmd_sta_set_eapakaprime(dut, conn, cmd);
Amarnath Hullur Subramanyam81b11cd2018-01-30 19:07:17 -08002776 if (strcasecmp(type, "wep") == 0)
2777 return cmd_sta_set_encryption(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002778
2779 send_resp(dut, conn, SIGMA_ERROR,
2780 "ErrorCode,Unsupported Type value");
2781 return 0;
2782}
2783
2784
2785int ath6kl_client_uapsd(struct sigma_dut *dut, const char *intf, int uapsd)
2786{
2787#ifdef __linux__
2788 /* special handling for ath6kl */
2789 char path[128], fname[128], *pos;
2790 ssize_t res;
2791 FILE *f;
2792
2793 snprintf(path, sizeof(path), "/sys/class/net/%s/phy80211", intf);
2794 res = readlink(path, path, sizeof(path));
2795 if (res < 0)
2796 return 0; /* not ath6kl */
2797
2798 if (res >= (int) sizeof(path))
2799 res = sizeof(path) - 1;
2800 path[res] = '\0';
2801 pos = strrchr(path, '/');
2802 if (pos == NULL)
2803 pos = path;
2804 else
2805 pos++;
2806 snprintf(fname, sizeof(fname),
2807 "/sys/kernel/debug/ieee80211/%s/ath6kl/"
2808 "create_qos", pos);
2809 if (!file_exists(fname))
2810 return 0; /* not ath6kl */
2811
2812 if (uapsd) {
2813 f = fopen(fname, "w");
2814 if (f == NULL)
2815 return -1;
2816
2817 sigma_dut_print(dut, DUT_MSG_DEBUG, "Use ath6kl create_qos");
2818 fprintf(f, "4 2 2 1 2 9999999 9999999 9999999 7777777 0 4 "
2819 "45000 200 56789000 56789000 5678900 0 0 9999999 "
2820 "20000 0\n");
2821 fclose(f);
2822 } else {
2823 snprintf(fname, sizeof(fname),
2824 "/sys/kernel/debug/ieee80211/%s/ath6kl/"
2825 "delete_qos", pos);
2826
2827 f = fopen(fname, "w");
2828 if (f == NULL)
2829 return -1;
2830
2831 sigma_dut_print(dut, DUT_MSG_DEBUG, "Use ath6kl delete_qos");
2832 fprintf(f, "2 4\n");
2833 fclose(f);
2834 }
2835#endif /* __linux__ */
2836
2837 return 0;
2838}
2839
2840
2841static int cmd_sta_set_uapsd(struct sigma_dut *dut, struct sigma_conn *conn,
2842 struct sigma_cmd *cmd)
2843{
2844 const char *intf = get_param(cmd, "Interface");
2845 /* const char *ssid = get_param(cmd, "ssid"); */
2846 const char *val;
2847 int max_sp_len = 4;
2848 int ac_be = 1, ac_bk = 1, ac_vi = 1, ac_vo = 1;
2849 char buf[100];
2850 int ret1, ret2;
2851
2852 val = get_param(cmd, "maxSPLength");
2853 if (val) {
2854 max_sp_len = atoi(val);
2855 if (max_sp_len != 0 && max_sp_len != 1 && max_sp_len != 2 &&
2856 max_sp_len != 4)
2857 return -1;
2858 }
2859
2860 val = get_param(cmd, "acBE");
2861 if (val)
2862 ac_be = atoi(val);
2863
2864 val = get_param(cmd, "acBK");
2865 if (val)
2866 ac_bk = atoi(val);
2867
2868 val = get_param(cmd, "acVI");
2869 if (val)
2870 ac_vi = atoi(val);
2871
2872 val = get_param(cmd, "acVO");
2873 if (val)
2874 ac_vo = atoi(val);
2875
2876 dut->client_uapsd = ac_be || ac_bk || ac_vi || ac_vo;
2877
2878 snprintf(buf, sizeof(buf), "P2P_SET client_apsd %d,%d,%d,%d;%d",
2879 ac_be, ac_bk, ac_vi, ac_vo, max_sp_len);
2880 ret1 = wpa_command(intf, buf);
2881
2882 snprintf(buf, sizeof(buf), "SET uapsd %d,%d,%d,%d;%d",
2883 ac_be, ac_bk, ac_vi, ac_vo, max_sp_len);
2884 ret2 = wpa_command(intf, buf);
2885
2886 if (ret1 && ret2) {
2887 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to set client mode "
2888 "UAPSD parameters.");
2889 return -2;
2890 }
2891
2892 if (ath6kl_client_uapsd(dut, intf, dut->client_uapsd) < 0) {
2893 send_resp(dut, conn, SIGMA_ERROR,
2894 "ErrorCode,Failed to set ath6kl QoS parameters");
2895 return 0;
2896 }
2897
2898 return 1;
2899}
2900
2901
2902static int cmd_sta_set_wmm(struct sigma_dut *dut, struct sigma_conn *conn,
2903 struct sigma_cmd *cmd)
2904{
2905 char buf[1000];
2906 const char *intf = get_param(cmd, "Interface");
2907 const char *grp = get_param(cmd, "Group");
2908 const char *act = get_param(cmd, "Action");
2909 const char *tid = get_param(cmd, "Tid");
2910 const char *dir = get_param(cmd, "Direction");
2911 const char *psb = get_param(cmd, "Psb");
2912 const char *up = get_param(cmd, "Up");
2913 const char *fixed = get_param(cmd, "Fixed");
2914 const char *size = get_param(cmd, "Size");
2915 const char *msize = get_param(cmd, "Maxsize");
2916 const char *minsi = get_param(cmd, "Min_srvc_intrvl");
2917 const char *maxsi = get_param(cmd, "Max_srvc_intrvl");
2918 const char *inact = get_param(cmd, "Inactivity");
2919 const char *sus = get_param(cmd, "Suspension");
2920 const char *mindr = get_param(cmd, "Mindatarate");
2921 const char *meandr = get_param(cmd, "Meandatarate");
2922 const char *peakdr = get_param(cmd, "Peakdatarate");
2923 const char *phyrate = get_param(cmd, "Phyrate");
2924 const char *burstsize = get_param(cmd, "Burstsize");
2925 const char *sba = get_param(cmd, "Sba");
2926 int direction;
2927 int handle;
Peng Xu93319622017-10-04 17:58:16 -07002928 float sba_fv = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002929 int fixed_int;
2930 int psb_ts;
2931
2932 if (intf == NULL || grp == NULL || act == NULL )
2933 return -1;
2934
2935 if (strcasecmp(act, "addts") == 0) {
2936 if (tid == NULL || dir == NULL || psb == NULL ||
2937 up == NULL || fixed == NULL || size == NULL)
2938 return -1;
2939
2940 /*
2941 * Note: Sigma CAPI spec lists uplink, downlink, and bidi as the
2942 * possible values, but WMM-AC and V-E test scripts use "UP,
2943 * "DOWN", and "BIDI".
2944 */
2945 if (strcasecmp(dir, "uplink") == 0 ||
2946 strcasecmp(dir, "up") == 0) {
2947 direction = 0;
2948 } else if (strcasecmp(dir, "downlink") == 0 ||
2949 strcasecmp(dir, "down") == 0) {
2950 direction = 1;
2951 } else if (strcasecmp(dir, "bidi") == 0) {
2952 direction = 2;
2953 } else {
2954 sigma_dut_print(dut, DUT_MSG_ERROR,
2955 "Direction %s not supported", dir);
2956 return -1;
2957 }
2958
2959 if (strcasecmp(psb, "legacy") == 0) {
2960 psb_ts = 0;
2961 } else if (strcasecmp(psb, "uapsd") == 0) {
2962 psb_ts = 1;
2963 } else {
2964 sigma_dut_print(dut, DUT_MSG_ERROR,
2965 "PSB %s not supported", psb);
2966 return -1;
2967 }
2968
2969 if (atoi(tid) < 0 || atoi(tid) > 7) {
2970 sigma_dut_print(dut, DUT_MSG_ERROR,
2971 "TID %s not supported", tid);
2972 return -1;
2973 }
2974
2975 if (strcasecmp(fixed, "true") == 0) {
2976 fixed_int = 1;
2977 } else {
2978 fixed_int = 0;
2979 }
2980
Peng Xu93319622017-10-04 17:58:16 -07002981 if (sba)
2982 sba_fv = atof(sba);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002983
2984 dut->dialog_token++;
2985 handle = 7000 + dut->dialog_token;
2986
2987 /*
2988 * size: convert to hex
2989 * maxsi: convert to hex
2990 * mindr: convert to hex
2991 * meandr: convert to hex
2992 * peakdr: convert to hex
2993 * burstsize: convert to hex
2994 * phyrate: convert to hex
2995 * sba: convert to hex with modification
2996 * minsi: convert to integer
2997 * sus: convert to integer
2998 * inact: convert to integer
2999 * maxsi: convert to integer
3000 */
3001
3002 /*
3003 * The Nominal MSDU Size field is 2 octets long and contains an
3004 * unsigned integer that specifies the nominal size, in octets,
3005 * of MSDUs belonging to the traffic under this traffic
3006 * specification and is defined in Figure 16. If the Fixed
3007 * subfield is set to 1, then the size of the MSDU is fixed and
3008 * is indicated by the Size Subfield. If the Fixed subfield is
3009 * set to 0, then the size of the MSDU might not be fixed and
3010 * the Size indicates the nominal MSDU size.
3011 *
3012 * The Surplus Bandwidth Allowance Factor field is 2 octets long
3013 * and specifies the excess allocation of time (and bandwidth)
3014 * over and above the stated rates required to transport an MSDU
3015 * belonging to the traffic in this TSPEC. This field is
3016 * represented as an unsigned binary number with an implicit
3017 * binary point after the leftmost 3 bits. For example, an SBA
3018 * of 1.75 is represented as 0x3800. This field is included to
3019 * account for retransmissions. As such, the value of this field
3020 * must be greater than unity.
3021 */
3022
3023 snprintf(buf, sizeof(buf),
3024 "iwpriv %s addTspec %d %s %d %d %s 0x%X"
3025 " 0x%X 0x%X 0x%X"
3026 " 0x%X 0x%X 0x%X"
3027 " 0x%X %d %d %d %d"
3028 " %d %d",
3029 intf, handle, tid, direction, psb_ts, up,
3030 (unsigned int) ((fixed_int << 15) | atoi(size)),
3031 msize ? atoi(msize) : 0,
3032 mindr ? atoi(mindr) : 0,
3033 meandr ? atoi(meandr) : 0,
3034 peakdr ? atoi(peakdr) : 0,
3035 burstsize ? atoi(burstsize) : 0,
3036 phyrate ? atoi(phyrate) : 0,
3037 sba ? ((unsigned int) (((int) sba_fv << 13) |
3038 (int)((sba_fv - (int) sba_fv) *
3039 8192))) : 0,
3040 minsi ? atoi(minsi) : 0,
3041 sus ? atoi(sus) : 0,
3042 0, 0,
3043 inact ? atoi(inact) : 0,
3044 maxsi ? atoi(maxsi) : 0);
3045
3046 if (system(buf) != 0) {
3047 sigma_dut_print(dut, DUT_MSG_ERROR,
3048 "iwpriv addtspec request failed");
3049 send_resp(dut, conn, SIGMA_ERROR,
3050 "errorCode,Failed to execute addTspec command");
3051 return 0;
3052 }
3053
3054 sigma_dut_print(dut, DUT_MSG_INFO,
3055 "iwpriv addtspec request send");
3056
3057 /* Mapping handle to a TID */
3058 dut->tid_to_handle[atoi(tid)] = handle;
3059 } else if (strcasecmp(act, "delts") == 0) {
3060 if (tid == NULL)
3061 return -1;
3062
3063 if (atoi(tid) < 0 || atoi(tid) > 7) {
3064 sigma_dut_print(dut, DUT_MSG_ERROR,
3065 "TID %s not supported", tid);
3066 send_resp(dut, conn, SIGMA_ERROR,
3067 "errorCode,Unsupported TID");
3068 return 0;
3069 }
3070
3071 handle = dut->tid_to_handle[atoi(tid)];
3072
3073 if (handle < 7000 || handle > 7255) {
3074 /* Invalid handle ie no mapping for that TID */
3075 sigma_dut_print(dut, DUT_MSG_ERROR,
3076 "handle-> %d not found", handle);
3077 }
3078
3079 snprintf(buf, sizeof(buf), "iwpriv %s delTspec %d",
3080 intf, handle);
3081
3082 if (system(buf) != 0) {
3083 sigma_dut_print(dut, DUT_MSG_ERROR,
3084 "iwpriv deltspec request failed");
3085 send_resp(dut, conn, SIGMA_ERROR,
3086 "errorCode,Failed to execute delTspec command");
3087 return 0;
3088 }
3089
3090 sigma_dut_print(dut, DUT_MSG_INFO,
3091 "iwpriv deltspec request send");
3092
3093 dut->tid_to_handle[atoi(tid)] = 0;
3094 } else {
3095 sigma_dut_print(dut, DUT_MSG_ERROR,
3096 "Action type %s not supported", act);
3097 send_resp(dut, conn, SIGMA_ERROR,
3098 "errorCode,Unsupported Action");
3099 return 0;
3100 }
3101
3102 return 1;
3103}
3104
3105
vamsi krishna52e16f92017-08-29 12:37:34 +05303106static int find_network(struct sigma_dut *dut, const char *ssid)
3107{
3108 char list[4096];
3109 char *pos;
3110
3111 sigma_dut_print(dut, DUT_MSG_DEBUG,
3112 "Search for profile based on SSID: '%s'", ssid);
3113 if (wpa_command_resp(get_station_ifname(), "LIST_NETWORKS",
3114 list, sizeof(list)) < 0)
3115 return -1;
3116 pos = strstr(list, ssid);
3117 if (!pos || pos == list || pos[-1] != '\t' || pos[strlen(ssid)] != '\t')
3118 return -1;
3119
3120 while (pos > list && pos[-1] != '\n')
3121 pos--;
3122 dut->infra_network_id = atoi(pos);
3123 snprintf(dut->infra_ssid, sizeof(dut->infra_ssid), "%s", ssid);
3124 return 0;
3125}
3126
3127
Sunil Dutt44595082018-02-12 19:41:45 +05303128#ifdef NL80211_SUPPORT
3129static int sta_config_rsnie(struct sigma_dut *dut, int val)
3130{
3131 struct nl_msg *msg;
3132 int ret;
3133 struct nlattr *params;
3134 int ifindex;
3135
3136 ifindex = if_nametoindex("wlan0");
3137 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
3138 NL80211_CMD_VENDOR)) ||
3139 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
3140 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
3141 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
3142 QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION) ||
3143 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
3144 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE, val)) {
3145 sigma_dut_print(dut, DUT_MSG_ERROR,
3146 "%s: err in adding vendor_cmd and vendor_data",
3147 __func__);
3148 nlmsg_free(msg);
3149 return -1;
3150 }
3151 nla_nest_end(msg, params);
3152
3153 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
3154 if (ret) {
3155 sigma_dut_print(dut, DUT_MSG_ERROR,
3156 "%s: err in send_and_recv_msgs, ret=%d",
3157 __func__, ret);
3158 return ret;
3159 }
3160
3161 return 0;
3162}
3163#endif /* NL80211_SUPPORT */
3164
3165
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003166static int cmd_sta_associate(struct sigma_dut *dut, struct sigma_conn *conn,
3167 struct sigma_cmd *cmd)
3168{
3169 /* const char *intf = get_param(cmd, "Interface"); */
3170 const char *ssid = get_param(cmd, "ssid");
3171 const char *wps_param = get_param(cmd, "WPS");
3172 const char *bssid = get_param(cmd, "bssid");
Jouni Malinen46a19b62017-06-23 14:31:27 +03003173 const char *chan = get_param(cmd, "channel");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02003174 const char *network_mode = get_param(cmd, "network_mode");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003175 int wps = 0;
Jouni Malinen3c367e82017-06-23 17:01:47 +03003176 char buf[1000], extra[50];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003177
3178 if (ssid == NULL)
3179 return -1;
3180
Jouni Malinen3c367e82017-06-23 17:01:47 +03003181 if (dut->rsne_override) {
Sunil Dutt44595082018-02-12 19:41:45 +05303182#ifdef NL80211_SUPPORT
3183 if (get_driver_type() == DRIVER_WCN) {
3184 sta_config_rsnie(dut, 1);
3185 dut->config_rsnie = 1;
3186 }
3187#endif /* NL80211_SUPPORT */
Jouni Malinen3c367e82017-06-23 17:01:47 +03003188 snprintf(buf, sizeof(buf), "TEST_ASSOC_IE %s",
3189 dut->rsne_override);
3190 if (wpa_command(get_station_ifname(), buf) < 0) {
3191 send_resp(dut, conn, SIGMA_ERROR,
3192 "ErrorCode,Failed to set DEV_CONFIGURE_IE RSNE override");
3193 return 0;
3194 }
3195 }
3196
Jouni Malinen68143132017-09-02 02:34:08 +03003197 if (dut->sae_commit_override) {
3198 snprintf(buf, sizeof(buf), "SET sae_commit_override %s",
3199 dut->sae_commit_override);
3200 if (wpa_command(get_station_ifname(), buf) < 0) {
3201 send_resp(dut, conn, SIGMA_ERROR,
3202 "ErrorCode,Failed to set SAE commit override");
3203 return 0;
3204 }
3205 }
Ankita Bajaj1bde7942018-01-09 19:15:01 +05303206#ifdef ANDROID
3207 if (dut->fils_hlp)
3208 process_fils_hlp(dut);
3209#endif /* ANDROID */
Jouni Malinen68143132017-09-02 02:34:08 +03003210
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003211 if (wps_param &&
3212 (strcmp(wps_param, "1") == 0 || strcasecmp(wps_param, "On") == 0))
3213 wps = 1;
3214
3215 if (wps) {
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02003216 if (dut->program == PROGRAM_60GHZ && network_mode &&
3217 strcasecmp(network_mode, "PBSS") == 0 &&
3218 set_network(get_station_ifname(), dut->infra_network_id,
3219 "pbss", "1") < 0)
3220 return -2;
3221
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003222 if (dut->wps_method == WFA_CS_WPS_NOT_READY) {
3223 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,WPS "
3224 "parameters not yet set");
3225 return 0;
3226 }
3227 if (dut->wps_method == WFA_CS_WPS_PBC) {
3228 if (wpa_command(get_station_ifname(), "WPS_PBC") < 0)
3229 return -2;
3230 } else {
3231 snprintf(buf, sizeof(buf), "WPS_PIN any %s",
3232 dut->wps_pin);
3233 if (wpa_command(get_station_ifname(), buf) < 0)
3234 return -2;
3235 }
3236 } else {
vamsi krishna52e16f92017-08-29 12:37:34 +05303237 if (strcmp(ssid, dut->infra_ssid) == 0) {
3238 sigma_dut_print(dut, DUT_MSG_DEBUG,
3239 "sta_associate for the most recently added network");
3240 } else if (find_network(dut, ssid) < 0) {
3241 sigma_dut_print(dut, DUT_MSG_DEBUG,
3242 "sta_associate for a previously stored network profile");
3243 send_resp(dut, conn, SIGMA_ERROR,
3244 "ErrorCode,Profile not found");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003245 return 0;
3246 }
3247
3248 if (bssid &&
3249 set_network(get_station_ifname(), dut->infra_network_id,
3250 "bssid", bssid) < 0) {
3251 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
3252 "Invalid bssid argument");
3253 return 0;
3254 }
3255
Jouni Malinen46a19b62017-06-23 14:31:27 +03003256 extra[0] = '\0';
3257 if (chan)
3258 snprintf(extra, sizeof(extra), " freq=%u",
Alexei Avshalom Lazar093569f2018-11-13 14:08:17 +02003259 channel_to_freq(dut, atoi(chan)));
Jouni Malinen46a19b62017-06-23 14:31:27 +03003260 snprintf(buf, sizeof(buf), "SELECT_NETWORK %d%s",
3261 dut->infra_network_id, extra);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003262 if (wpa_command(get_station_ifname(), buf) < 0) {
3263 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to select "
3264 "network id %d on %s",
3265 dut->infra_network_id,
3266 get_station_ifname());
3267 return -2;
3268 }
3269 }
3270
3271 return 1;
3272}
3273
3274
3275static int run_hs20_osu(struct sigma_dut *dut, const char *params)
3276{
3277 char buf[500], cmd[200];
3278 int res;
3279
3280 /* Use hs20-osu-client file at the current dir, if found; otherwise use
3281 * default path */
3282 res = snprintf(cmd, sizeof(cmd),
3283 "%s -w \"%s\" -r hs20-osu-client.res %s%s -dddKt -f Logs/hs20-osu-client.txt",
3284 file_exists("./hs20-osu-client") ?
3285 "./hs20-osu-client" : "hs20-osu-client",
3286 sigma_wpas_ctrl,
3287 dut->summary_log ? "-s " : "",
3288 dut->summary_log ? dut->summary_log : "");
3289 if (res < 0 || res >= (int) sizeof(cmd))
3290 return -1;
3291
3292 res = snprintf(buf, sizeof(buf), "%s %s", cmd, params);
3293 if (res < 0 || res >= (int) sizeof(buf))
3294 return -1;
3295 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
3296
3297 if (system(buf) != 0) {
3298 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to run: %s", buf);
3299 return -1;
3300 }
3301 sigma_dut_print(dut, DUT_MSG_DEBUG,
3302 "Completed hs20-osu-client operation");
3303
3304 return 0;
3305}
3306
3307
3308static int download_ppsmo(struct sigma_dut *dut,
3309 struct sigma_conn *conn,
3310 const char *intf,
3311 struct sigma_cmd *cmd)
3312{
3313 const char *name, *path, *val;
3314 char url[500], buf[600], fbuf[100];
3315 char *fqdn = NULL;
3316
3317 name = get_param(cmd, "FileName");
3318 path = get_param(cmd, "FilePath");
3319 if (name == NULL || path == NULL)
3320 return -1;
3321
3322 if (strcasecmp(path, "VendorSpecific") == 0) {
3323 snprintf(url, sizeof(url), "PPS/%s", name);
3324 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured PPS MO "
3325 "from the device (%s)", url);
3326 if (!file_exists(url)) {
3327 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
3328 "PPS MO file does not exist");
3329 return 0;
3330 }
3331 snprintf(buf, sizeof(buf), "cp %s pps-tnds.xml", url);
3332 if (system(buf) != 0) {
3333 send_resp(dut, conn, SIGMA_ERROR,
3334 "errorCode,Failed to copy PPS MO");
3335 return 0;
3336 }
3337 } else if (strncasecmp(path, "http:", 5) != 0 &&
3338 strncasecmp(path, "https:", 6) != 0) {
3339 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
3340 "Unsupported FilePath value");
3341 return 0;
3342 } else {
3343 snprintf(url, sizeof(url), "%s/%s", path, name);
3344 sigma_dut_print(dut, DUT_MSG_INFO, "Downloading PPS MO from %s",
3345 url);
3346 snprintf(buf, sizeof(buf), "wget -T 10 -t 3 -O pps-tnds.xml '%s'", url);
3347 remove("pps-tnds.xml");
3348 if (system(buf) != 0) {
3349 send_resp(dut, conn, SIGMA_ERROR,
3350 "errorCode,Failed to download PPS MO");
3351 return 0;
3352 }
3353 }
3354
3355 if (run_hs20_osu(dut, "from_tnds pps-tnds.xml pps.xml") < 0) {
3356 send_resp(dut, conn, SIGMA_ERROR,
3357 "errorCode,Failed to parse downloaded PPSMO");
3358 return 0;
3359 }
3360 unlink("pps-tnds.xml");
3361
3362 val = get_param(cmd, "managementTreeURI");
3363 if (val) {
3364 const char *pos, *end;
3365 sigma_dut_print(dut, DUT_MSG_DEBUG, "managementTreeURI: %s",
3366 val);
3367 if (strncmp(val, "./Wi-Fi/", 8) != 0) {
3368 send_resp(dut, conn, SIGMA_ERROR,
3369 "errorCode,Invalid managementTreeURI prefix");
3370 return 0;
3371 }
3372 pos = val + 8;
3373 end = strchr(pos, '/');
3374 if (end == NULL ||
3375 strcmp(end, "/PerProviderSubscription") != 0) {
3376 send_resp(dut, conn, SIGMA_ERROR,
3377 "errorCode,Invalid managementTreeURI postfix");
3378 return 0;
3379 }
3380 if (end - pos >= (int) sizeof(fbuf)) {
3381 send_resp(dut, conn, SIGMA_ERROR,
3382 "errorCode,Too long FQDN in managementTreeURI");
3383 return 0;
3384 }
3385 memcpy(fbuf, pos, end - pos);
3386 fbuf[end - pos] = '\0';
3387 fqdn = fbuf;
3388 sigma_dut_print(dut, DUT_MSG_INFO,
3389 "FQDN from managementTreeURI: %s", fqdn);
3390 } else if (run_hs20_osu(dut, "get_fqdn pps.xml") == 0) {
3391 FILE *f = fopen("pps-fqdn", "r");
3392 if (f) {
3393 if (fgets(fbuf, sizeof(fbuf), f)) {
3394 fbuf[sizeof(fbuf) - 1] = '\0';
3395 fqdn = fbuf;
3396 sigma_dut_print(dut, DUT_MSG_DEBUG,
3397 "Use FQDN %s", fqdn);
3398 }
3399 fclose(f);
3400 }
3401 }
3402
3403 if (fqdn == NULL) {
3404 send_resp(dut, conn, SIGMA_ERROR,
3405 "errorCode,No FQDN specified");
3406 return 0;
3407 }
3408
3409 mkdir("SP", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
3410 snprintf(buf, sizeof(buf), "SP/%s", fqdn);
3411 mkdir(buf, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
3412
3413 snprintf(buf, sizeof(buf), "SP/%s/pps.xml", fqdn);
3414 if (rename("pps.xml", buf) < 0) {
3415 send_resp(dut, conn, SIGMA_ERROR,
3416 "errorCode,Could not move PPS MO");
3417 return 0;
3418 }
3419
3420 if (strcasecmp(path, "VendorSpecific") == 0) {
3421 snprintf(buf, sizeof(buf), "cp Certs/ca.pem SP/%s/ca.pem",
3422 fqdn);
3423 if (system(buf)) {
3424 send_resp(dut, conn, SIGMA_ERROR,
3425 "errorCode,Failed to copy OSU CA cert");
3426 return 0;
3427 }
3428
3429 snprintf(buf, sizeof(buf),
3430 "cp Certs/aaa-ca.pem SP/%s/aaa-ca.pem",
3431 fqdn);
3432 if (system(buf)) {
3433 send_resp(dut, conn, SIGMA_ERROR,
3434 "errorCode,Failed to copy AAA CA cert");
3435 return 0;
3436 }
3437 } else {
3438 snprintf(buf, sizeof(buf),
3439 "dl_osu_ca SP/%s/pps.xml SP/%s/ca.pem",
3440 fqdn, fqdn);
3441 if (run_hs20_osu(dut, buf) < 0) {
3442 send_resp(dut, conn, SIGMA_ERROR,
3443 "errorCode,Failed to download OSU CA cert");
3444 return 0;
3445 }
3446
3447 snprintf(buf, sizeof(buf),
3448 "dl_aaa_ca SP/%s/pps.xml SP/%s/aaa-ca.pem",
3449 fqdn, fqdn);
3450 if (run_hs20_osu(dut, buf) < 0) {
3451 sigma_dut_print(dut, DUT_MSG_INFO,
3452 "Failed to download AAA CA cert");
3453 }
3454 }
3455
3456 if (file_exists("next-client-cert.pem")) {
3457 snprintf(buf, sizeof(buf), "SP/%s/client-cert.pem", fqdn);
3458 if (rename("next-client-cert.pem", buf) < 0) {
3459 send_resp(dut, conn, SIGMA_ERROR,
3460 "errorCode,Could not move client certificate");
3461 return 0;
3462 }
3463 }
3464
3465 if (file_exists("next-client-key.pem")) {
3466 snprintf(buf, sizeof(buf), "SP/%s/client-key.pem", fqdn);
3467 if (rename("next-client-key.pem", buf) < 0) {
3468 send_resp(dut, conn, SIGMA_ERROR,
3469 "errorCode,Could not move client key");
3470 return 0;
3471 }
3472 }
3473
3474 snprintf(buf, sizeof(buf), "set_pps SP/%s/pps.xml", fqdn);
3475 if (run_hs20_osu(dut, buf) < 0) {
3476 send_resp(dut, conn, SIGMA_ERROR,
3477 "errorCode,Failed to configure credential from "
3478 "PPSMO");
3479 return 0;
3480 }
3481
3482 return 1;
3483}
3484
3485
3486static int download_cert(struct sigma_dut *dut,
3487 struct sigma_conn *conn,
3488 const char *intf,
3489 struct sigma_cmd *cmd)
3490{
3491 const char *name, *path;
3492 char url[500], buf[600];
3493
3494 name = get_param(cmd, "FileName");
3495 path = get_param(cmd, "FilePath");
3496 if (name == NULL || path == NULL)
3497 return -1;
3498
3499 if (strcasecmp(path, "VendorSpecific") == 0) {
3500 snprintf(url, sizeof(url), "Certs/%s-cert.pem", name);
3501 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured client "
3502 "certificate from the device (%s)", url);
3503 if (!file_exists(url)) {
3504 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
3505 "certificate file does not exist");
3506 return 0;
3507 }
3508 snprintf(buf, sizeof(buf), "cp %s next-client-cert.pem", url);
3509 if (system(buf) != 0) {
3510 send_resp(dut, conn, SIGMA_ERROR,
3511 "errorCode,Failed to copy client "
3512 "certificate");
3513 return 0;
3514 }
3515
3516 snprintf(url, sizeof(url), "Certs/%s-key.pem", name);
3517 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured client "
3518 "private key from the device (%s)", url);
3519 if (!file_exists(url)) {
3520 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
3521 "private key file does not exist");
3522 return 0;
3523 }
3524 snprintf(buf, sizeof(buf), "cp %s next-client-key.pem", url);
3525 if (system(buf) != 0) {
3526 send_resp(dut, conn, SIGMA_ERROR,
3527 "errorCode,Failed to copy client key");
3528 return 0;
3529 }
3530 } else if (strncasecmp(path, "http:", 5) != 0 &&
3531 strncasecmp(path, "https:", 6) != 0) {
3532 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
3533 "Unsupported FilePath value");
3534 return 0;
3535 } else {
3536 snprintf(url, sizeof(url), "%s/%s.pem", path, name);
3537 sigma_dut_print(dut, DUT_MSG_INFO, "Downloading client "
3538 "certificate/key from %s", url);
3539 snprintf(buf, sizeof(buf),
3540 "wget -T 10 -t 3 -O next-client-cert.pem '%s'", url);
3541 if (system(buf) != 0) {
3542 send_resp(dut, conn, SIGMA_ERROR,
3543 "errorCode,Failed to download client "
3544 "certificate");
3545 return 0;
3546 }
3547
3548 if (system("cp next-client-cert.pem next-client-key.pem") != 0)
3549 {
3550 send_resp(dut, conn, SIGMA_ERROR,
3551 "errorCode,Failed to copy client key");
3552 return 0;
3553 }
3554 }
3555
3556 return 1;
3557}
3558
3559
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02003560static int cmd_sta_preset_testparameters_60ghz(struct sigma_dut *dut,
3561 struct sigma_conn *conn,
3562 struct sigma_cmd *cmd)
3563{
3564 const char *val;
3565 const char *intf = get_param(cmd, "interface");
3566
3567 if (!intf)
3568 return -1;
3569
3570 val = get_param(cmd, "WscIEFragment");
3571 if (val && strcasecmp(val, "enable") == 0) {
3572 sigma_dut_print(dut, DUT_MSG_DEBUG,
3573 "Enable WSC IE fragmentation");
3574
3575 dut->wsc_fragment = 1;
3576 /* set long attributes to force fragmentation */
3577 if (wpa_command(intf, "SET device_name "
3578 WPS_LONG_DEVICE_NAME) < 0)
3579 return -2;
3580 if (wpa_command(intf, "SET manufacturer "
3581 WPS_LONG_MANUFACTURER) < 0)
3582 return -2;
3583 if (wpa_command(intf, "SET model_name "
3584 WPS_LONG_MODEL_NAME) < 0)
3585 return -2;
3586 if (wpa_command(intf, "SET model_number "
3587 WPS_LONG_MODEL_NUMBER) < 0)
3588 return -2;
3589 if (wpa_command(intf, "SET serial_number "
3590 WPS_LONG_SERIAL_NUMBER) < 0)
3591 return -2;
3592 }
3593
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02003594 val = get_param(cmd, "RSN_IE");
3595 if (val) {
3596 if (strcasecmp(val, "disable") == 0)
3597 dut->force_rsn_ie = FORCE_RSN_IE_REMOVE;
3598 else if (strcasecmp(val, "enable") == 0)
3599 dut->force_rsn_ie = FORCE_RSN_IE_ADD;
3600 }
3601
Alexei Avshalom Lazar744ae8a2019-01-31 17:26:46 +02003602 val = get_param(cmd, "WpsVersion");
3603 if (val)
3604 dut->wps_forced_version = get_wps_forced_version(dut, val);
3605
Alexei Avshalom Lazar2eccf4d2019-01-31 10:03:59 +02003606 val = get_param(cmd, "WscEAPFragment");
3607 if (val && strcasecmp(val, "enable") == 0)
3608 dut->eap_fragment = 1;
3609
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02003610 return 1;
3611}
3612
3613
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003614static int cmd_sta_preset_testparameters_hs2_r2(struct sigma_dut *dut,
3615 struct sigma_conn *conn,
3616 const char *intf,
3617 struct sigma_cmd *cmd)
3618{
3619 const char *val;
3620
3621 val = get_param(cmd, "FileType");
3622 if (val && strcasecmp(val, "PPSMO") == 0)
3623 return download_ppsmo(dut, conn, intf, cmd);
3624 if (val && strcasecmp(val, "CERT") == 0)
3625 return download_cert(dut, conn, intf, cmd);
3626 if (val) {
3627 send_resp(dut, conn, SIGMA_ERROR,
3628 "ErrorCode,Unsupported FileType");
3629 return 0;
3630 }
3631
3632 return 1;
3633}
3634
3635
Ankita Bajaja2cb5672017-10-25 16:08:28 +05303636static int cmd_sta_preset_testparameters_oce(struct sigma_dut *dut,
3637 struct sigma_conn *conn,
3638 const char *intf,
3639 struct sigma_cmd *cmd)
3640{
3641 const char *val;
Ankita Bajaj1bde7942018-01-09 19:15:01 +05303642 char buf[1000];
3643 char text[20];
3644 unsigned char addr[ETH_ALEN];
Ankita Bajaja2cb5672017-10-25 16:08:28 +05303645
3646 val = get_param(cmd, "OCESupport");
3647 if (val && strcasecmp(val, "Disable") == 0) {
3648 if (wpa_command(intf, "SET oce 0") < 0) {
3649 send_resp(dut, conn, SIGMA_ERROR,
3650 "ErrorCode,Failed to disable OCE");
3651 return 0;
3652 }
3653 } else if (val && strcasecmp(val, "Enable") == 0) {
3654 if (wpa_command(intf, "SET oce 1") < 0) {
3655 send_resp(dut, conn, SIGMA_ERROR,
3656 "ErrorCode,Failed to enable OCE");
3657 return 0;
3658 }
3659 }
3660
vamsi krishnaa2799492017-12-05 14:28:01 +05303661 val = get_param(cmd, "FILScap");
3662 if (val && (atoi(val) == 1)) {
3663 if (wpa_command(intf, "SET disable_fils 0") < 0) {
3664 send_resp(dut, conn, SIGMA_ERROR,
3665 "ErrorCode,Failed to enable FILS");
3666 return 0;
3667 }
3668 } else if (val && (atoi(val) == 0)) {
3669 if (wpa_command(intf, "SET disable_fils 1") < 0) {
3670 send_resp(dut, conn, SIGMA_ERROR,
3671 "ErrorCode,Failed to disable FILS");
3672 return 0;
3673 }
3674 }
3675
Ankita Bajaj1bde7942018-01-09 19:15:01 +05303676 val = get_param(cmd, "FILSHLP");
3677 if (val && strcasecmp(val, "Enable") == 0) {
3678 if (get_wpa_status(get_station_ifname(), "address", text,
3679 sizeof(text)) < 0)
3680 return -2;
3681 hwaddr_aton(text, addr);
3682 snprintf(buf, sizeof(buf),
3683 "FILS_HLP_REQ_ADD ff:ff:ff:ff:ff:ff "
3684 "080045100140000040004011399e00000000ffffffff00440043"
3685 "012cb30001010600fd4f46410000000000000000000000000000"
3686 "000000000000"
3687 "%02x%02x%02x%02x%02x%02x"
3688 "0000000000000000000000000000000000000000000000000000"
3689 "0000000000000000000000000000000000000000000000000000"
3690 "0000000000000000000000000000000000000000000000000000"
3691 "0000000000000000000000000000000000000000000000000000"
3692 "0000000000000000000000000000000000000000000000000000"
3693 "0000000000000000000000000000000000000000000000000000"
3694 "0000000000000000000000000000000000000000000000000000"
3695 "0000000000000000000000000000000000000000638253633501"
3696 "013d0701000af549d29b390205dc3c12616e64726f69642d6468"
3697 "63702d382e302e30370a0103060f1a1c333a3b2b5000ff00",
3698 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
3699 if (wpa_command(intf, buf)) {
3700 send_resp(dut, conn, SIGMA_ERROR,
3701 "ErrorCode,Failed to add HLP");
3702 return 0;
3703 }
3704 dut->fils_hlp = 1;
3705 }
3706
Ankita Bajaja2cb5672017-10-25 16:08:28 +05303707 return 1;
3708}
3709
3710
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003711static void ath_sta_set_noack(struct sigma_dut *dut, const char *intf,
3712 const char *val)
3713{
3714 int counter = 0;
3715 char token[50];
3716 char *result;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05303717 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003718
Peng Xub8fc5cc2017-05-10 17:27:28 -07003719 strlcpy(token, val, sizeof(token));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003720 token[sizeof(token) - 1] = '\0';
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05303721 result = strtok_r(token, ":", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003722 while (result) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07003723 if (strcmp(result, "disable") == 0)
3724 run_iwpriv(dut, intf, "noackpolicy %d 1 0", counter);
3725 else
3726 run_iwpriv(dut, intf, "noackpolicy %d 1 1", counter);
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05303727 result = strtok_r(NULL, ":", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003728 counter++;
3729 }
3730}
3731
3732
3733static void ath_sta_set_rts(struct sigma_dut *dut, const char *intf,
3734 const char *val)
3735{
3736 char buf[100];
3737
3738 snprintf(buf, sizeof(buf), "iwconfig %s rts %s", intf, val);
3739 if (system(buf) != 0) {
3740 sigma_dut_print(dut, DUT_MSG_ERROR, "iwconfig RTS failed");
3741 }
3742}
3743
3744
3745static void ath_sta_set_wmm(struct sigma_dut *dut, const char *intf,
3746 const char *val)
3747{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003748 if (strcasecmp(val, "off") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07003749 run_iwpriv(dut, intf, "wmm 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003750 }
3751}
3752
3753
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08003754static int wcn_sta_set_wmm(struct sigma_dut *dut, const char *intf,
3755 const char *val)
3756{
3757#ifdef NL80211_SUPPORT
3758 struct nl_msg *msg;
3759 int ret = 0;
3760 struct nlattr *params;
3761 int ifindex;
3762 int wmmenable = 1;
3763
3764 if (val &&
3765 (strcasecmp(val, "off") == 0 || strcmp(val, "0") == 0))
3766 wmmenable = 0;
3767
3768 ifindex = if_nametoindex(intf);
3769 if (ifindex == 0) {
3770 sigma_dut_print(dut, DUT_MSG_ERROR,
3771 "%s: Index for interface %s failed",
3772 __func__, intf);
3773 return -1;
3774 }
3775
3776 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
3777 NL80211_CMD_VENDOR)) ||
3778 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
3779 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
3780 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
3781 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
3782 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
3783 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WMM_ENABLE,
3784 wmmenable)) {
3785 sigma_dut_print(dut, DUT_MSG_ERROR,
3786 "%s: err in adding vendor_cmd and vendor_data",
3787 __func__);
3788 nlmsg_free(msg);
3789 return -1;
3790 }
3791 nla_nest_end(msg, params);
3792
3793 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
3794 if (ret) {
3795 sigma_dut_print(dut, DUT_MSG_ERROR,
3796 "%s: err in send_and_recv_msgs, ret=%d",
3797 __func__, ret);
3798 }
3799 return ret;
3800#else /* NL80211_SUPPORT */
3801 sigma_dut_print(dut, DUT_MSG_ERROR,
3802 "WMM cannot be changed without NL80211_SUPPORT defined");
3803 return -1;
3804#endif /* NL80211_SUPPORT */
3805}
3806
3807
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003808static void ath_sta_set_sgi(struct sigma_dut *dut, const char *intf,
3809 const char *val)
3810{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003811 int sgi20;
3812
3813 sgi20 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
3814
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07003815 run_iwpriv(dut, intf, "shortgi %d", sgi20);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003816}
3817
3818
3819static void ath_sta_set_11nrates(struct sigma_dut *dut, const char *intf,
3820 const char *val)
3821{
Pradeep Reddy POTTETI67376b72016-10-25 20:08:17 +05303822 int rate_code, v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003823
3824 /* Disable Tx Beam forming when using a fixed rate */
3825 ath_disable_txbf(dut, intf);
3826
Pradeep Reddy POTTETI67376b72016-10-25 20:08:17 +05303827 v = atoi(val);
3828 if (v < 0 || v > 32) {
3829 sigma_dut_print(dut, DUT_MSG_ERROR,
3830 "Invalid Fixed MCS rate: %d", v);
3831 return;
3832 }
3833 rate_code = 0x80 + v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003834
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07003835 run_iwpriv(dut, intf, "set11NRates 0x%x", rate_code);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003836
3837 /* Channel width gets messed up, fix this */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07003838 run_iwpriv(dut, intf, "chwidth %d", dut->chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003839}
3840
3841
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08003842static void iwpriv_sta_set_amsdu(struct sigma_dut *dut, const char *intf,
3843 const char *val)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003844{
3845 char buf[60];
3846
3847 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)
3848 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 2", intf);
3849 else
3850 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 1", intf);
3851
3852 if (system(buf) != 0)
3853 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv amsdu failed");
3854}
3855
3856
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07003857static int iwpriv_sta_set_ampdu(struct sigma_dut *dut, const char *intf,
3858 int ampdu)
3859{
3860 char buf[60];
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08003861 int maxaggregation = 63;
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07003862
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08003863 if (ampdu)
3864 ampdu = maxaggregation;
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07003865 snprintf(buf, sizeof(buf), "iwpriv %s ampdu %d", intf, ampdu);
3866 if (system(buf) != 0) {
3867 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv ampdu failed");
3868 return -1;
3869 }
3870
3871 return 0;
3872}
3873
3874
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003875static void ath_sta_set_stbc(struct sigma_dut *dut, const char *intf,
3876 const char *val)
3877{
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07003878 run_iwpriv(dut, intf, "tx_stbc %s", val);
3879 run_iwpriv(dut, intf, "rx_stbc %s", val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003880}
3881
3882
3883static int wcn_sta_set_cts_width(struct sigma_dut *dut, const char *intf,
3884 const char *val)
3885{
3886 char buf[60];
3887
Peng Xucc317ed2017-05-18 16:44:37 -07003888 if (strcmp(val, "160") == 0) {
3889 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 5", intf);
3890 } else if (strcmp(val, "80") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003891 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 3", intf);
3892 } else if (strcmp(val, "40") == 0) {
3893 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 2", intf);
3894 } else if (strcmp(val, "20") == 0) {
3895 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 1", intf);
3896 } else if (strcasecmp(val, "Auto") == 0) {
3897 buf[0] = '\0';
3898 } else {
3899 sigma_dut_print(dut, DUT_MSG_ERROR,
3900 "WIDTH/CTS_WIDTH value not supported");
3901 return -1;
3902 }
3903
3904 if (buf[0] != '\0' && system(buf) != 0) {
3905 sigma_dut_print(dut, DUT_MSG_ERROR,
3906 "Failed to set WIDTH/CTS_WIDTH");
3907 return -1;
3908 }
3909
3910 return 0;
3911}
3912
3913
3914int ath_set_width(struct sigma_dut *dut, struct sigma_conn *conn,
3915 const char *intf, const char *val)
3916{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003917 if (strcasecmp(val, "Auto") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07003918 run_iwpriv(dut, intf, "chwidth 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003919 dut->chwidth = 0;
3920 } else if (strcasecmp(val, "20") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07003921 run_iwpriv(dut, intf, "chwidth 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003922 dut->chwidth = 0;
3923 } else if (strcasecmp(val, "40") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07003924 run_iwpriv(dut, intf, "chwidth 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003925 dut->chwidth = 1;
3926 } else if (strcasecmp(val, "80") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07003927 run_iwpriv(dut, intf, "chwidth 2");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003928 dut->chwidth = 2;
3929 } else if (strcasecmp(val, "160") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07003930 run_iwpriv(dut, intf, "chwidth 3");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003931 dut->chwidth = 3;
3932 } else {
3933 send_resp(dut, conn, SIGMA_ERROR,
3934 "ErrorCode,WIDTH not supported");
3935 return -1;
3936 }
3937
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003938 return 0;
3939}
3940
3941
3942static int wcn_sta_set_sp_stream(struct sigma_dut *dut, const char *intf,
3943 const char *val)
3944{
3945 char buf[60];
Arif Hussainac6c5112018-05-25 17:34:00 -07003946 int sta_nss;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003947
Amarnath Hullur Subramanyamd5374fa2018-02-25 19:00:24 -08003948 if (strcmp(val, "1SS") == 0 || strcmp(val, "1") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003949 snprintf(buf, sizeof(buf), "iwpriv %s nss 1", intf);
Arif Hussainac6c5112018-05-25 17:34:00 -07003950 sta_nss = 1;
Amarnath Hullur Subramanyamd5374fa2018-02-25 19:00:24 -08003951 } else if (strcmp(val, "2SS") == 0 || strcmp(val, "2") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003952 snprintf(buf, sizeof(buf), "iwpriv %s nss 2", intf);
Arif Hussainac6c5112018-05-25 17:34:00 -07003953 sta_nss = 2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003954 } else {
3955 sigma_dut_print(dut, DUT_MSG_ERROR,
3956 "SP_STREAM value not supported");
3957 return -1;
3958 }
3959
3960 if (system(buf) != 0) {
3961 sigma_dut_print(dut, DUT_MSG_ERROR,
3962 "Failed to set SP_STREAM");
3963 return -1;
3964 }
3965
Arif Hussainac6c5112018-05-25 17:34:00 -07003966 dut->sta_nss = sta_nss;
3967
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003968 return 0;
3969}
3970
3971
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05303972static void wcn_sta_set_stbc(struct sigma_dut *dut, const char *intf,
3973 const char *val)
3974{
3975 char buf[60];
3976
3977 snprintf(buf, sizeof(buf), "iwpriv %s tx_stbc %s", intf, val);
3978 if (system(buf) != 0)
3979 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv tx_stbc failed");
3980
3981 snprintf(buf, sizeof(buf), "iwpriv %s rx_stbc %s", intf, val);
3982 if (system(buf) != 0)
3983 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv rx_stbc failed");
3984}
3985
3986
Ashwini Patil68d02cd2017-01-10 15:39:16 +05303987static int mbo_set_cellular_data_capa(struct sigma_dut *dut,
3988 struct sigma_conn *conn,
3989 const char *intf, int capa)
3990{
3991 char buf[32];
3992
3993 if (capa > 0 && capa < 4) {
3994 snprintf(buf, sizeof(buf), "SET mbo_cell_capa %d", capa);
3995 if (wpa_command(intf, buf) < 0) {
3996 send_resp(dut, conn, SIGMA_ERROR,
3997 "ErrorCode, Failed to set cellular data capability");
3998 return 0;
3999 }
4000 return 1;
4001 }
4002
4003 sigma_dut_print(dut, DUT_MSG_ERROR,
4004 "Invalid Cellular data capability: %d", capa);
4005 send_resp(dut, conn, SIGMA_INVALID,
4006 "ErrorCode,Invalid cellular data capability");
4007 return 0;
4008}
4009
4010
Ashwini Patil9183fdb2017-04-13 16:58:25 +05304011static int mbo_set_roaming(struct sigma_dut *dut, struct sigma_conn *conn,
4012 const char *intf, const char *val)
4013{
4014 if (strcasecmp(val, "Disable") == 0) {
4015 if (wpa_command(intf, "SET roaming 0") < 0) {
4016 send_resp(dut, conn, SIGMA_ERROR,
4017 "ErrorCode,Failed to disable roaming");
4018 return 0;
4019 }
4020 return 1;
4021 }
4022
4023 if (strcasecmp(val, "Enable") == 0) {
4024 if (wpa_command(intf, "SET roaming 1") < 0) {
4025 send_resp(dut, conn, SIGMA_ERROR,
4026 "ErrorCode,Failed to enable roaming");
4027 return 0;
4028 }
4029 return 1;
4030 }
4031
4032 sigma_dut_print(dut, DUT_MSG_ERROR,
4033 "Invalid value provided for roaming: %s", val);
4034 send_resp(dut, conn, SIGMA_INVALID,
4035 "ErrorCode,Unknown value provided for Roaming");
4036 return 0;
4037}
4038
4039
Ashwini Patila75de5a2017-04-13 16:35:05 +05304040static int mbo_set_assoc_disallow(struct sigma_dut *dut,
4041 struct sigma_conn *conn,
4042 const char *intf, const char *val)
4043{
4044 if (strcasecmp(val, "Disable") == 0) {
4045 if (wpa_command(intf, "SET ignore_assoc_disallow 1") < 0) {
4046 send_resp(dut, conn, SIGMA_ERROR,
4047 "ErrorCode,Failed to disable Assoc_disallow");
4048 return 0;
4049 }
4050 return 1;
4051 }
4052
4053 if (strcasecmp(val, "Enable") == 0) {
4054 if (wpa_command(intf, "SET ignore_assoc_disallow 0") < 0) {
4055 send_resp(dut, conn, SIGMA_ERROR,
4056 "ErrorCode,Failed to enable Assoc_disallow");
4057 return 0;
4058 }
4059 return 1;
4060 }
4061
4062 sigma_dut_print(dut, DUT_MSG_ERROR,
4063 "Invalid value provided for Assoc_disallow: %s", val);
4064 send_resp(dut, conn, SIGMA_INVALID,
4065 "ErrorCode,Unknown value provided for Assoc_disallow");
4066 return 0;
4067}
4068
4069
Ashwini Patilc63161e2017-04-13 16:30:23 +05304070static int mbo_set_bss_trans_req(struct sigma_dut *dut, struct sigma_conn *conn,
4071 const char *intf, const char *val)
4072{
4073 if (strcasecmp(val, "Reject") == 0) {
4074 if (wpa_command(intf, "SET reject_btm_req_reason 1") < 0) {
4075 send_resp(dut, conn, SIGMA_ERROR,
4076 "ErrorCode,Failed to Reject BTM Request");
4077 return 0;
4078 }
4079 return 1;
4080 }
4081
4082 if (strcasecmp(val, "Accept") == 0) {
4083 if (wpa_command(intf, "SET reject_btm_req_reason 0") < 0) {
4084 send_resp(dut, conn, SIGMA_ERROR,
4085 "ErrorCode,Failed to Accept BTM Request");
4086 return 0;
4087 }
4088 return 1;
4089 }
4090
4091 sigma_dut_print(dut, DUT_MSG_ERROR,
4092 "Invalid value provided for BSS_Transition: %s", val);
4093 send_resp(dut, conn, SIGMA_INVALID,
4094 "ErrorCode,Unknown value provided for BSS_Transition");
4095 return 0;
4096}
4097
4098
Ashwini Patil00402582017-04-13 12:29:39 +05304099static int mbo_set_non_pref_ch_list(struct sigma_dut *dut,
4100 struct sigma_conn *conn,
4101 const char *intf,
4102 struct sigma_cmd *cmd)
4103{
4104 const char *ch, *pref, *op_class, *reason;
4105 char buf[120];
4106 int len, ret;
4107
4108 pref = get_param(cmd, "Ch_Pref");
4109 if (!pref)
4110 return 1;
4111
4112 if (strcasecmp(pref, "clear") == 0) {
4113 free(dut->non_pref_ch_list);
4114 dut->non_pref_ch_list = NULL;
4115 } else {
4116 op_class = get_param(cmd, "Ch_Op_Class");
4117 if (!op_class) {
4118 send_resp(dut, conn, SIGMA_INVALID,
4119 "ErrorCode,Ch_Op_Class not provided");
4120 return 0;
4121 }
4122
4123 ch = get_param(cmd, "Ch_Pref_Num");
4124 if (!ch) {
4125 send_resp(dut, conn, SIGMA_INVALID,
4126 "ErrorCode,Ch_Pref_Num not provided");
4127 return 0;
4128 }
4129
4130 reason = get_param(cmd, "Ch_Reason_Code");
4131 if (!reason) {
4132 send_resp(dut, conn, SIGMA_INVALID,
4133 "ErrorCode,Ch_Reason_Code not provided");
4134 return 0;
4135 }
4136
4137 if (!dut->non_pref_ch_list) {
4138 dut->non_pref_ch_list =
4139 calloc(1, NON_PREF_CH_LIST_SIZE);
4140 if (!dut->non_pref_ch_list) {
4141 send_resp(dut, conn, SIGMA_ERROR,
4142 "ErrorCode,Failed to allocate memory for non_pref_ch_list");
4143 return 0;
4144 }
4145 }
4146 len = strlen(dut->non_pref_ch_list);
4147 ret = snprintf(dut->non_pref_ch_list + len,
4148 NON_PREF_CH_LIST_SIZE - len,
4149 " %s:%s:%s:%s", op_class, ch, pref, reason);
4150 if (ret > 0 && ret < NON_PREF_CH_LIST_SIZE - len) {
4151 sigma_dut_print(dut, DUT_MSG_DEBUG, "non_pref_list: %s",
4152 dut->non_pref_ch_list);
4153 } else {
4154 sigma_dut_print(dut, DUT_MSG_ERROR,
4155 "snprintf failed for non_pref_list, ret = %d",
4156 ret);
4157 send_resp(dut, conn, SIGMA_ERROR,
4158 "ErrorCode,snprintf failed");
4159 free(dut->non_pref_ch_list);
4160 dut->non_pref_ch_list = NULL;
4161 return 0;
4162 }
4163 }
4164
4165 ret = snprintf(buf, sizeof(buf), "SET non_pref_chan%s",
4166 dut->non_pref_ch_list ? dut->non_pref_ch_list : " ");
4167 if (ret < 0 || ret >= (int) sizeof(buf)) {
4168 sigma_dut_print(dut, DUT_MSG_DEBUG,
4169 "snprintf failed for set non_pref_chan, ret: %d",
4170 ret);
4171 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,snprint failed");
4172 return 0;
4173 }
4174
4175 if (wpa_command(intf, buf) < 0) {
4176 send_resp(dut, conn, SIGMA_ERROR,
4177 "ErrorCode,Failed to set non-preferred channel list");
4178 return 0;
4179 }
4180
4181 return 1;
4182}
4183
4184
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08004185#ifdef NL80211_SUPPORT
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08004186
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08004187static int sta_set_he_htc_supp(struct sigma_dut *dut, const char *intf,
4188 uint8_t cfg)
4189{
4190 struct nl_msg *msg;
4191 int ret = 0;
4192 struct nlattr *params;
4193 int ifindex;
4194
4195 ifindex = if_nametoindex(intf);
4196 if (ifindex == 0) {
4197 sigma_dut_print(dut, DUT_MSG_ERROR,
4198 "%s: Index for interface %s failed",
4199 __func__, intf);
4200 return -1;
4201 }
4202
4203 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4204 NL80211_CMD_VENDOR)) ||
4205 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4206 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4207 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4208 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4209 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4210 nla_put_u8(msg,
4211 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_HTC_HE_SUPP,
4212 cfg)) {
4213 sigma_dut_print(dut, DUT_MSG_ERROR,
4214 "%s: err in adding vendor_cmd and vendor_data",
4215 __func__);
4216 nlmsg_free(msg);
4217 return -1;
4218 }
4219 nla_nest_end(msg, params);
4220
4221 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4222 if (ret) {
4223 sigma_dut_print(dut, DUT_MSG_ERROR,
4224 "%s: err in send_and_recv_msgs, ret=%d",
4225 __func__, ret);
4226 }
4227 return ret;
4228}
4229
4230
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08004231static int sta_set_he_fragmentation(struct sigma_dut *dut, const char *intf,
4232 enum he_fragmentation_val frag)
4233{
4234 struct nl_msg *msg;
4235 int ret = 0;
4236 struct nlattr *params;
4237 int ifindex;
4238
4239 ifindex = if_nametoindex(intf);
4240 if (ifindex == 0) {
4241 sigma_dut_print(dut, DUT_MSG_ERROR,
4242 "%s: Index for interface %s failed",
4243 __func__, intf);
4244 return -1;
4245 }
4246
4247 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4248 NL80211_CMD_VENDOR)) ||
4249 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4250 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4251 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4252 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4253 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4254 nla_put_u8(msg,
4255 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_FRAGMENTATION,
4256 frag)) {
4257 sigma_dut_print(dut, DUT_MSG_ERROR,
4258 "%s: err in adding vendor_cmd and vendor_data",
4259 __func__);
4260 nlmsg_free(msg);
4261 return -1;
4262 }
4263 nla_nest_end(msg, params);
4264
4265 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4266 if (ret) {
4267 sigma_dut_print(dut, DUT_MSG_ERROR,
4268 "%s: err in send_and_recv_msgs, ret=%d",
4269 __func__, ret);
4270 }
4271 return ret;
4272}
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08004273
4274
Subhani Shaik8e7a3052018-04-24 14:03:00 -07004275static int sta_set_he_ltf(struct sigma_dut *dut, const char *intf,
4276 enum qca_wlan_he_ltf_cfg ltf)
4277{
4278 struct nl_msg *msg;
4279 int ret = 0;
4280 struct nlattr *params;
4281 int ifindex;
4282
4283 ifindex = if_nametoindex(intf);
4284 if (ifindex == 0) {
4285 sigma_dut_print(dut, DUT_MSG_ERROR,
4286 "%s: Index for interface %s failed",
4287 __func__, intf);
4288 return -1;
4289 }
4290
4291 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4292 NL80211_CMD_VENDOR)) ||
4293 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4294 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4295 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4296 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4297 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4298 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_LTF,
4299 ltf)) {
4300 sigma_dut_print(dut, DUT_MSG_ERROR,
4301 "%s: err in adding vendor_cmd and vendor_data",
4302 __func__);
4303 nlmsg_free(msg);
4304 return -1;
4305 }
4306 nla_nest_end(msg, params);
4307
4308 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4309 if (ret) {
4310 sigma_dut_print(dut, DUT_MSG_ERROR,
4311 "%s: err in send_and_recv_msgs, ret=%d",
4312 __func__, ret);
4313 }
4314 return ret;
4315}
4316
4317
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08004318static int nlvendor_sta_set_noack(struct sigma_dut *dut, const char *intf,
4319 int noack, enum qca_wlan_ac_type ac)
4320{
4321 struct nl_msg *msg;
4322 int ret = 0;
4323 struct nlattr *params;
4324 int ifindex;
4325
4326 ifindex = if_nametoindex(intf);
4327 if (ifindex == 0) {
4328 sigma_dut_print(dut, DUT_MSG_ERROR,
4329 "%s: Index for interface %s failed",
4330 __func__, intf);
4331 return -1;
4332 }
4333
4334 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4335 NL80211_CMD_VENDOR)) ||
4336 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4337 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4338 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4339 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4340 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4341 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_NO_ACK,
4342 noack) ||
4343 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_NO_ACK_AC,
4344 ac)) {
4345 sigma_dut_print(dut, DUT_MSG_ERROR,
4346 "%s: err in adding vendor_cmd and vendor_data",
4347 __func__);
4348 nlmsg_free(msg);
4349 return -1;
4350 }
4351 nla_nest_end(msg, params);
4352
4353 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4354 if (ret) {
4355 sigma_dut_print(dut, DUT_MSG_ERROR,
4356 "%s: err in send_and_recv_msgs, ret=%d",
4357 __func__, ret);
4358 }
4359 return ret;
4360}
4361
4362
4363static void wcn_sta_set_noack(struct sigma_dut *dut, const char *intf,
4364 const char *val)
4365{
4366 int noack, ret;
4367 char token[100];
4368 char *result;
4369 char *saveptr;
4370 enum qca_wlan_ac_type ac = QCA_WLAN_AC_BE;
4371
4372 strlcpy(token, val, sizeof(token));
4373 token[sizeof(token) - 1] = '\0';
4374 result = strtok_r(token, ":", &saveptr);
4375 while (result) {
4376 noack = strcasecmp(result, "Disable") != 0;
4377 ret = nlvendor_sta_set_noack(dut, intf, noack, ac);
4378 if (ret) {
4379 sigma_dut_print(dut, DUT_MSG_ERROR,
4380 "nlvendor_sta_set_noack failed for ac:%d, ret:%d",
4381 ac, ret);
4382 }
4383 result = strtok_r(NULL, ":", &saveptr);
4384 ac++;
4385 }
4386}
4387
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08004388#endif /* NL80211_SUPPORT */
4389
4390
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004391static int cmd_sta_preset_testparameters(struct sigma_dut *dut,
4392 struct sigma_conn *conn,
4393 struct sigma_cmd *cmd)
4394{
4395 const char *intf = get_param(cmd, "Interface");
4396 const char *val;
4397
4398 val = get_param(cmd, "Program");
Jouni Malinen1f6ae642018-06-07 23:56:13 +03004399 if (val && (strcasecmp(val, "HS2-R2") == 0 ||
4400 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004401 return cmd_sta_preset_testparameters_hs2_r2(dut, conn, intf,
4402 cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004403
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07004404 if (val && strcasecmp(val, "LOC") == 0)
4405 return loc_cmd_sta_preset_testparameters(dut, conn, cmd);
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02004406 if (val && strcasecmp(val, "60GHZ") == 0) {
4407 val = get_param(cmd, "WPS");
4408 if (val && strcasecmp(val, "disable") == 0) {
4409 dut->wps_disable = 1;
4410 sigma_dut_print(dut, DUT_MSG_INFO, "WPS disabled");
4411 } else {
4412 /* wps_disable can have other value from the previous
4413 * test, so make sure it has the correct value.
4414 */
4415 dut->wps_disable = 0;
4416 }
4417
4418 val = get_param(cmd, "P2P");
4419 if (val && strcasecmp(val, "disable") == 0)
4420 sigma_dut_print(dut, DUT_MSG_INFO, "P2P disabled");
4421 }
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07004422
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02004423 if (dut->program == PROGRAM_WPS && dut->band == WPS_BAND_60G)
4424 return cmd_sta_preset_testparameters_60ghz(dut, conn, cmd);
4425
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004426#ifdef ANDROID_NAN
4427 if (val && strcasecmp(val, "NAN") == 0)
4428 return nan_cmd_sta_preset_testparameters(dut, conn, cmd);
4429#endif /* ANDROID_NAN */
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07004430#ifdef MIRACAST
4431 if (val && (strcasecmp(val, "WFD") == 0 ||
4432 strcasecmp(val, "DisplayR2") == 0))
4433 return miracast_preset_testparameters(dut, conn, cmd);
4434#endif /* MIRACAST */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004435
Ashwini Patil68d02cd2017-01-10 15:39:16 +05304436 if (val && strcasecmp(val, "MBO") == 0) {
4437 val = get_param(cmd, "Cellular_Data_Cap");
4438 if (val &&
4439 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
4440 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +05304441
4442 val = get_param(cmd, "Ch_Pref");
4443 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
4444 return 0;
4445
Ashwini Patilc63161e2017-04-13 16:30:23 +05304446 val = get_param(cmd, "BSS_Transition");
4447 if (val && mbo_set_bss_trans_req(dut, conn, intf, val) == 0)
4448 return 0;
4449
Ashwini Patila75de5a2017-04-13 16:35:05 +05304450 val = get_param(cmd, "Assoc_Disallow");
4451 if (val && mbo_set_assoc_disallow(dut, conn, intf, val) == 0)
4452 return 0;
4453
Ashwini Patil9183fdb2017-04-13 16:58:25 +05304454 val = get_param(cmd, "Roaming");
4455 if (val && mbo_set_roaming(dut, conn, intf, val) == 0)
4456 return 0;
4457
Ashwini Patil68d02cd2017-01-10 15:39:16 +05304458 return 1;
4459 }
4460
Ankita Bajaja2cb5672017-10-25 16:08:28 +05304461 if (val && strcasecmp(val, "OCE") == 0)
4462 return cmd_sta_preset_testparameters_oce(dut, conn, intf, cmd);
4463
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004464#if 0
4465 val = get_param(cmd, "Supplicant");
4466 if (val && strcasecmp(val, "Default") != 0) {
4467 send_resp(dut, conn, SIGMA_ERROR,
4468 "ErrorCode,Only default(Vendor) supplicant "
4469 "supported");
4470 return 0;
4471 }
4472#endif
4473
4474 val = get_param(cmd, "RTS");
4475 if (val) {
4476 switch (get_driver_type()) {
4477 case DRIVER_ATHEROS:
4478 ath_sta_set_rts(dut, intf, val);
4479 break;
4480 default:
4481#if 0
4482 send_resp(dut, conn, SIGMA_ERROR,
4483 "ErrorCode,Setting RTS not supported");
4484 return 0;
4485#else
4486 sigma_dut_print(dut, DUT_MSG_DEBUG,
4487 "Setting RTS not supported");
4488 break;
4489#endif
4490 }
4491 }
4492
4493#if 0
4494 val = get_param(cmd, "FRGMNT");
4495 if (val) {
4496 /* TODO */
4497 send_resp(dut, conn, SIGMA_ERROR,
4498 "ErrorCode,Setting FRGMNT not supported");
4499 return 0;
4500 }
4501#endif
4502
4503#if 0
4504 val = get_param(cmd, "Preamble");
4505 if (val) {
4506 /* TODO: Long/Short */
4507 send_resp(dut, conn, SIGMA_ERROR,
4508 "ErrorCode,Setting Preamble not supported");
4509 return 0;
4510 }
4511#endif
4512
4513 val = get_param(cmd, "Mode");
4514 if (val) {
4515 if (strcmp(val, "11b") == 0 ||
4516 strcmp(val, "11g") == 0 ||
4517 strcmp(val, "11a") == 0 ||
4518 strcmp(val, "11n") == 0 ||
4519 strcmp(val, "11ng") == 0 ||
4520 strcmp(val, "11nl") == 0 ||
4521 strcmp(val, "11nl(nabg)") == 0 ||
4522 strcmp(val, "AC") == 0 ||
4523 strcmp(val, "11AC") == 0 ||
4524 strcmp(val, "11ac") == 0 ||
4525 strcmp(val, "11na") == 0 ||
Amarnath Hullur Subramanyamb0db2712018-01-30 19:40:35 -08004526 strcmp(val, "11an") == 0 ||
4527 strcmp(val, "11ax") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004528 /* STA supports all modes by default */
4529 } else {
4530 send_resp(dut, conn, SIGMA_ERROR,
4531 "ErrorCode,Setting Mode not supported");
4532 return 0;
4533 }
Amarnath Hullur Subramanyam97d0e532018-01-31 02:53:02 -08004534
4535 /* Change the mode only in case of testbed for HE program
4536 * and for 11a and 11g modes only. */
4537 if (dut->program == PROGRAM_HE &&
4538 dut->device_type == STA_testbed) {
4539 int phymode;
4540 char buf[60];
4541
4542 if (strcmp(val, "11a") == 0) {
Amarnath Hullur Subramanyam94dfaf02018-03-02 19:26:57 -08004543 phymode = 1; /* IEEE80211_MODE_11A */
4544 } else if (strcmp(val, "11g") == 0) {
4545 phymode = 3; /* IEEE80211_MODE_11G */
4546 } else if (strcmp(val, "11b") == 0) {
4547 phymode = 2; /* IEEE80211_MODE_11B */
4548 } else if (strcmp(val, "11n") == 0 ||
4549 strcmp(val, "11nl") == 0 ||
4550 strcmp(val, "11nl(nabg)") == 0) {
4551 phymode = 22; /* IEEE80211_MODE_11AGN */
4552 } else if (strcmp(val, "11ng") == 0) {
4553 phymode = 13; /* IEEE80211_MODE_11NG_HT40 */
4554 } else if (strcmp(val, "AC") == 0 ||
4555 strcasecmp(val, "11AC") == 0) {
4556 phymode = 19; /* IEEE80211_MODE_11AC_VHT80 */
4557 } else if (strcmp(val, "11na") == 0 ||
4558 strcasecmp(val, "11an") == 0) {
4559 phymode = 14; /* IEEE80211_MODE_11NA_HT40 */
4560 } else if (strcmp(val, "11ax") == 0) {
4561 phymode = 0; /* IEEE80211_MODE_AUTO */
Amarnath Hullur Subramanyam97d0e532018-01-31 02:53:02 -08004562 } else {
4563 sigma_dut_print(dut, DUT_MSG_DEBUG,
4564 "Ignoring mode change for mode: %s",
4565 val);
4566 phymode = -1;
4567 }
4568 if (phymode != -1) {
4569 snprintf(buf, sizeof(buf),
4570 "iwpriv %s setphymode %d",
4571 intf, phymode);
4572 if (system(buf) != 0) {
4573 sigma_dut_print(dut, DUT_MSG_ERROR,
4574 "iwpriv setting of phymode failed");
4575 }
4576 }
4577 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004578 }
4579
4580 val = get_param(cmd, "wmm");
4581 if (val) {
4582 switch (get_driver_type()) {
4583 case DRIVER_ATHEROS:
4584 ath_sta_set_wmm(dut, intf, val);
4585 break;
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08004586 case DRIVER_WCN:
4587 wcn_sta_set_wmm(dut, intf, val);
4588 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004589 default:
4590 sigma_dut_print(dut, DUT_MSG_DEBUG,
4591 "Setting wmm not supported");
4592 break;
4593 }
4594 }
4595
4596 val = get_param(cmd, "Powersave");
4597 if (val) {
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08004598 char buf[60];
4599
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004600 if (strcmp(val, "0") == 0 || strcasecmp(val, "off") == 0) {
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08004601 if (get_driver_type() == DRIVER_WCN) {
4602 snprintf(buf, sizeof(buf),
4603 "iwpriv %s setPower 2", intf);
4604 if (system(buf) != 0) {
4605 sigma_dut_print(dut, DUT_MSG_ERROR,
4606 "iwpriv setPower 2 failed");
4607 return 0;
4608 }
4609 }
4610
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004611 if (wpa_command(get_station_ifname(),
4612 "P2P_SET ps 0") < 0)
4613 return -2;
4614 /* Make sure test modes are disabled */
4615 wpa_command(get_station_ifname(), "P2P_SET ps 98");
4616 wpa_command(get_station_ifname(), "P2P_SET ps 96");
4617 } else if (strcmp(val, "1") == 0 ||
4618 strcasecmp(val, "PSPoll") == 0 ||
4619 strcasecmp(val, "on") == 0) {
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08004620 if (get_driver_type() == DRIVER_WCN) {
4621 snprintf(buf, sizeof(buf),
4622 "iwpriv %s setPower 1", intf);
4623 if (system(buf) != 0) {
4624 sigma_dut_print(dut, DUT_MSG_ERROR,
4625 "iwpriv setPower 1 failed");
4626 return 0;
4627 }
4628 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004629 /* Disable default power save mode */
4630 wpa_command(get_station_ifname(), "P2P_SET ps 0");
4631 /* Enable PS-Poll test mode */
4632 if (wpa_command(get_station_ifname(),
4633 "P2P_SET ps 97") < 0 ||
4634 wpa_command(get_station_ifname(),
4635 "P2P_SET ps 99") < 0)
4636 return -2;
4637 } else if (strcmp(val, "2") == 0 ||
4638 strcasecmp(val, "Fast") == 0) {
4639 /* TODO */
4640 send_resp(dut, conn, SIGMA_ERROR,
4641 "ErrorCode,Powersave=Fast not supported");
4642 return 0;
4643 } else if (strcmp(val, "3") == 0 ||
4644 strcasecmp(val, "PSNonPoll") == 0) {
4645 /* Make sure test modes are disabled */
4646 wpa_command(get_station_ifname(), "P2P_SET ps 98");
4647 wpa_command(get_station_ifname(), "P2P_SET ps 96");
4648
4649 /* Enable default power save mode */
4650 if (wpa_command(get_station_ifname(),
4651 "P2P_SET ps 1") < 0)
4652 return -2;
4653 } else
4654 return -1;
4655 }
4656
4657 val = get_param(cmd, "NoAck");
4658 if (val) {
4659 switch (get_driver_type()) {
4660 case DRIVER_ATHEROS:
4661 ath_sta_set_noack(dut, intf, val);
4662 break;
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08004663#ifdef NL80211_SUPPORT
4664 case DRIVER_WCN:
4665 wcn_sta_set_noack(dut, intf, val);
4666 break;
4667#endif /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004668 default:
4669 send_resp(dut, conn, SIGMA_ERROR,
4670 "ErrorCode,Setting NoAck not supported");
4671 return 0;
4672 }
4673 }
4674
4675 val = get_param(cmd, "IgnoreChswitchProhibit");
4676 if (val) {
4677 /* TODO: Enabled/disabled */
4678 if (strcasecmp(val, "Enabled") == 0) {
4679 send_resp(dut, conn, SIGMA_ERROR,
4680 "ErrorCode,Enabling IgnoreChswitchProhibit "
4681 "not supported");
4682 return 0;
4683 }
4684 }
4685
4686 val = get_param(cmd, "TDLS");
4687 if (val) {
4688 if (strcasecmp(val, "Disabled") == 0) {
4689 if (wpa_command(intf, "SET tdls_disabled 1")) {
4690 send_resp(dut, conn, SIGMA_ERROR,
4691 "ErrorCode,Failed to disable TDLS");
4692 return 0;
4693 }
4694 } else if (strcasecmp(val, "Enabled") == 0) {
4695 if (wpa_command(intf, "SET tdls_disabled 0")) {
4696 send_resp(dut, conn, SIGMA_ERROR,
4697 "ErrorCode,Failed to enable TDLS");
4698 return 0;
4699 }
4700 } else {
4701 send_resp(dut, conn, SIGMA_ERROR,
4702 "ErrorCode,Unsupported TDLS value");
4703 return 0;
4704 }
4705 }
4706
4707 val = get_param(cmd, "TDLSmode");
4708 if (val) {
4709 if (strcasecmp(val, "Default") == 0) {
4710 wpa_command(intf, "SET tdls_testing 0");
4711 } else if (strcasecmp(val, "APProhibit") == 0) {
4712 if (wpa_command(intf, "SET tdls_testing 0x400")) {
4713 send_resp(dut, conn, SIGMA_ERROR,
4714 "ErrorCode,Failed to enable ignore "
4715 "APProhibit TDLS mode");
4716 return 0;
4717 }
4718 } else if (strcasecmp(val, "HiLoMac") == 0) {
4719 /* STA should respond with TDLS setup req for a TDLS
4720 * setup req */
4721 if (wpa_command(intf, "SET tdls_testing 0x80")) {
4722 send_resp(dut, conn, SIGMA_ERROR,
4723 "ErrorCode,Failed to enable HiLoMac "
4724 "TDLS mode");
4725 return 0;
4726 }
4727 } else if (strcasecmp(val, "WeakSecurity") == 0) {
4728 /*
4729 * Since all security modes are enabled by default when
4730 * Sigma control is used, there is no need to do
4731 * anything here.
4732 */
4733 } else if (strcasecmp(val, "ExistLink") == 0) {
4734 /*
4735 * Since we allow new TDLS Setup Request even if there
4736 * is an existing link, nothing needs to be done for
4737 * this.
4738 */
4739 } else {
4740 /* TODO:
4741 * ExistLink: STA should send TDLS setup req even if
4742 * direct link already exists
4743 */
4744 send_resp(dut, conn, SIGMA_ERROR,
4745 "ErrorCode,Unsupported TDLSmode value");
4746 return 0;
4747 }
4748 }
4749
4750 val = get_param(cmd, "FakePubKey");
4751 if (val && atoi(val) && wpa_command(intf, "SET wps_corrupt_pkhash 1")) {
4752 send_resp(dut, conn, SIGMA_ERROR,
4753 "ErrorCode,Failed to enable FakePubKey");
4754 return 0;
4755 }
4756
Amarnath Hullur Subramanyamae1042b2018-02-22 21:52:52 -08004757#ifdef NL80211_SUPPORT
4758 val = get_param(cmd, "FrgmntSupport");
4759 if (val) {
4760 if (strcasecmp(val, "Enable") == 0) {
4761 if (sta_set_he_fragmentation(dut, intf,
4762 HE_FRAG_LEVEL1)) {
4763 send_resp(dut, conn, SIGMA_ERROR,
4764 "ErrorCode,Failed to enable HE Fragmentation");
4765 return 0;
4766 }
4767 } else if (strcasecmp(val, "Disable") == 0) {
4768 if (sta_set_he_fragmentation(dut, intf,
4769 HE_FRAG_DISABLE)) {
4770 send_resp(dut, conn, SIGMA_ERROR,
4771 "ErrorCode,Failed to disable HE Fragmentation");
4772 return 0;
4773 }
4774 }
4775 }
4776#endif /* NL80211_SUPPORT */
4777
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004778 return 1;
4779}
4780
4781
4782static const char * ath_get_radio_name(const char *radio_name)
4783{
4784 if (radio_name == NULL)
4785 return "wifi0";
4786 if (strcmp(radio_name, "wifi1") == 0)
4787 return "wifi1";
4788 if (strcmp(radio_name, "wifi2") == 0)
4789 return "wifi2";
4790 return "wifi0";
4791}
4792
4793
4794static void ath_sta_set_txsp_stream(struct sigma_dut *dut, const char *intf,
4795 const char *val)
4796{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004797 unsigned int vht_mcsmap = 0;
4798 int txchainmask = 0;
4799 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
4800
4801 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
4802 if (dut->testbed_flag_txsp == 1) {
4803 vht_mcsmap = 0xfffc;
4804 dut->testbed_flag_txsp = 0;
4805 } else {
4806 vht_mcsmap = 0xfffe;
4807 }
4808 txchainmask = 1;
4809 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
4810 if (dut->testbed_flag_txsp == 1) {
4811 vht_mcsmap = 0xfff0;
4812 dut->testbed_flag_txsp = 0;
4813 } else {
4814 vht_mcsmap = 0xfffa;
4815 }
4816 txchainmask = 3;
4817 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
4818 if (dut->testbed_flag_txsp == 1) {
4819 vht_mcsmap = 0xffc0;
4820 dut->testbed_flag_txsp = 0;
4821 } else {
4822 vht_mcsmap = 0xffea;
4823 }
4824 txchainmask = 7;
4825 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
4826 if (dut->testbed_flag_txsp == 1) {
4827 vht_mcsmap = 0xff00;
4828 dut->testbed_flag_txsp = 0;
4829 } else {
4830 vht_mcsmap = 0xffaa;
4831 }
4832 txchainmask = 15;
4833 } else {
4834 if (dut->testbed_flag_txsp == 1) {
4835 vht_mcsmap = 0xffc0;
4836 dut->testbed_flag_txsp = 0;
4837 } else {
4838 vht_mcsmap = 0xffea;
4839 }
4840 }
4841
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004842 if (txchainmask)
4843 run_iwpriv(dut, basedev, "txchainmask %d", txchainmask);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004844
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004845 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004846}
4847
4848
4849static void ath_sta_set_rxsp_stream(struct sigma_dut *dut, const char *intf,
4850 const char *val)
4851{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004852 unsigned int vht_mcsmap = 0;
4853 int rxchainmask = 0;
4854 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
4855
4856 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
4857 if (dut->testbed_flag_rxsp == 1) {
4858 vht_mcsmap = 0xfffc;
4859 dut->testbed_flag_rxsp = 0;
4860 } else {
4861 vht_mcsmap = 0xfffe;
4862 }
4863 rxchainmask = 1;
4864 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
4865 if (dut->testbed_flag_rxsp == 1) {
4866 vht_mcsmap = 0xfff0;
4867 dut->testbed_flag_rxsp = 0;
4868 } else {
4869 vht_mcsmap = 0xfffa;
4870 }
4871 rxchainmask = 3;
4872 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
4873 if (dut->testbed_flag_rxsp == 1) {
4874 vht_mcsmap = 0xffc0;
4875 dut->testbed_flag_rxsp = 0;
4876 } else {
4877 vht_mcsmap = 0xffea;
4878 }
4879 rxchainmask = 7;
4880 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
4881 if (dut->testbed_flag_rxsp == 1) {
4882 vht_mcsmap = 0xff00;
4883 dut->testbed_flag_rxsp = 0;
4884 } else {
4885 vht_mcsmap = 0xffaa;
4886 }
4887 rxchainmask = 15;
4888 } else {
4889 if (dut->testbed_flag_rxsp == 1) {
4890 vht_mcsmap = 0xffc0;
4891 dut->testbed_flag_rxsp = 0;
4892 } else {
4893 vht_mcsmap = 0xffea;
4894 }
4895 }
4896
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004897 if (rxchainmask)
4898 run_iwpriv(dut, basedev, "rxchainmask %d", rxchainmask);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004899
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004900 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004901}
4902
4903
4904void ath_set_zero_crc(struct sigma_dut *dut, const char *val)
4905{
4906 if (strcasecmp(val, "enable") == 0) {
4907 if (system("athdiag --set --address=0x2a204 --and=0xbfffffff")
4908 != 0) {
4909 sigma_dut_print(dut, DUT_MSG_ERROR,
4910 "Disable BB_VHTSIGB_CRC_CALC failed");
4911 }
4912
4913 if (system("athdiag --set --address=0x2a204 --or=0x80000000")
4914 != 0) {
4915 sigma_dut_print(dut, DUT_MSG_ERROR,
4916 "Enable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
4917 }
4918 } else {
4919 if (system("athdiag --set --address=0x2a204 --and=0x7fffffff")
4920 != 0) {
4921 sigma_dut_print(dut, DUT_MSG_ERROR,
4922 "Disable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
4923 }
4924
4925 if (system("athdiag --set --address=0x2a204 --or=0x40000000")
4926 != 0) {
4927 sigma_dut_print(dut, DUT_MSG_ERROR,
4928 "Enable BB_VHTSIGB_CRC_CALC failed");
4929 }
4930 }
4931}
4932
4933
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08004934static int wcn_sta_set_width(struct sigma_dut *dut, const char *intf,
4935 const char *val)
4936{
4937 char buf[60];
4938
4939 if (strcmp(val, "20") == 0) {
4940 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 0", intf);
4941 dut->chwidth = 0;
4942 } else if (strcmp(val, "40") == 0) {
4943 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 1", intf);
4944 dut->chwidth = 1;
4945 } else if (strcmp(val, "80") == 0) {
4946 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 2", intf);
4947 dut->chwidth = 2;
Sunil Duttb1cccac2018-05-22 21:03:12 +05304948 } else if (strcasecmp(val, "Auto") == 0) {
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08004949 buf[0] = '\0';
4950 } else {
4951 sigma_dut_print(dut, DUT_MSG_ERROR, "WIDTH %s not supported",
4952 val);
4953 return -1;
4954 }
4955
4956 if (buf[0] != '\0' && system(buf) != 0) {
4957 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv chwidth failed");
4958 return -1;
4959 }
4960
4961 return 0;
4962}
4963
4964
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08004965static int nlvendor_sta_set_addba_reject(struct sigma_dut *dut,
4966 const char *intf, int addbareject)
4967{
4968#ifdef NL80211_SUPPORT
4969 struct nl_msg *msg;
4970 int ret = 0;
4971 struct nlattr *params;
4972 int ifindex;
4973
4974 ifindex = if_nametoindex(intf);
4975 if (ifindex == 0) {
4976 sigma_dut_print(dut, DUT_MSG_ERROR,
4977 "%s: Index for interface %s failed",
4978 __func__, intf);
4979 return -1;
4980 }
4981
4982 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4983 NL80211_CMD_VENDOR)) ||
4984 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4985 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4986 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4987 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4988 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4989 nla_put_u8(msg,
4990 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ACCEPT_ADDBA_REQ,
4991 !addbareject)) {
4992 sigma_dut_print(dut, DUT_MSG_ERROR,
4993 "%s: err in adding vendor_cmd and vendor_data",
4994 __func__);
4995 nlmsg_free(msg);
4996 return -1;
4997 }
4998 nla_nest_end(msg, params);
4999
5000 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5001 if (ret) {
5002 sigma_dut_print(dut, DUT_MSG_ERROR,
5003 "%s: err in send_and_recv_msgs, ret=%d",
5004 __func__, ret);
5005 }
5006 return ret;
5007#else /* NL80211_SUPPORT */
5008 sigma_dut_print(dut, DUT_MSG_ERROR,
5009 "ADDBA_REJECT cannot be set without NL80211_SUPPORT defined");
5010 return -1;
5011#endif /* NL80211_SUPPORT */
5012}
5013
5014
5015static int sta_set_addba_reject(struct sigma_dut *dut, const char *intf,
5016 int addbareject)
5017{
5018 int ret;
5019
5020 switch (get_driver_type()) {
5021 case DRIVER_WCN:
5022 ret = nlvendor_sta_set_addba_reject(dut, intf, addbareject);
5023 if (ret) {
5024 sigma_dut_print(dut, DUT_MSG_ERROR,
5025 "nlvendor_sta_set_addba_reject failed, ret:%d",
5026 ret);
5027 return ret;
5028 }
5029 break;
5030 default:
5031 sigma_dut_print(dut, DUT_MSG_ERROR,
5032 "errorCode,Unsupported ADDBA_REJECT with the current driver");
5033 ret = -1;
5034 break;
5035 }
5036
5037 return ret;
5038}
5039
5040
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08005041static int nlvendor_config_send_addba(struct sigma_dut *dut, const char *intf,
5042 int enable)
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005043{
5044#ifdef NL80211_SUPPORT
5045 struct nl_msg *msg;
5046 int ret = 0;
5047 struct nlattr *params;
5048 int ifindex;
5049
5050 ifindex = if_nametoindex(intf);
5051 if (ifindex == 0) {
5052 sigma_dut_print(dut, DUT_MSG_ERROR,
5053 "%s: Index for interface %s failed",
5054 __func__, intf);
5055 return -1;
5056 }
5057
5058 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
5059 NL80211_CMD_VENDOR)) ||
5060 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
5061 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
5062 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
5063 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
5064 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
5065 nla_put_u8(msg,
5066 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_SEND_ADDBA_REQ,
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08005067 enable)) {
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005068 sigma_dut_print(dut, DUT_MSG_ERROR,
5069 "%s: err in adding vendor_cmd and vendor_data",
5070 __func__);
5071 nlmsg_free(msg);
5072 return -1;
5073 }
5074 nla_nest_end(msg, params);
5075
5076 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5077 if (ret) {
5078 sigma_dut_print(dut, DUT_MSG_ERROR,
5079 "%s: err in send_and_recv_msgs, ret=%d",
5080 __func__, ret);
5081 }
5082 return ret;
5083#else /* NL80211_SUPPORT */
5084 sigma_dut_print(dut, DUT_MSG_ERROR,
5085 "Disable addba not possible without NL80211_SUPPORT defined");
5086 return -1;
5087#endif /* NL80211_SUPPORT */
5088}
5089
5090
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005091static int cmd_sta_set_wireless_common(const char *intf, struct sigma_dut *dut,
5092 struct sigma_conn *conn,
5093 struct sigma_cmd *cmd)
5094{
5095 const char *val;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005096 int ampdu = -1, addbareject = -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005097 char buf[30];
5098
5099 val = get_param(cmd, "40_INTOLERANT");
5100 if (val) {
5101 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
5102 /* TODO: iwpriv ht40intol through wpa_supplicant */
5103 send_resp(dut, conn, SIGMA_ERROR,
5104 "ErrorCode,40_INTOLERANT not supported");
5105 return 0;
5106 }
5107 }
5108
5109 val = get_param(cmd, "ADDBA_REJECT");
5110 if (val) {
5111 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
5112 /* reject any ADDBA with status "decline" */
5113 ampdu = 0;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005114 addbareject = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005115 } else {
5116 /* accept ADDBA */
5117 ampdu = 1;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005118 addbareject = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005119 }
5120 }
5121
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005122 if (addbareject >= 0 &&
5123 sta_set_addba_reject(dut, intf, addbareject) < 0) {
5124 send_resp(dut, conn, SIGMA_ERROR,
5125 "ErrorCode,set addba_reject failed");
5126 return 0;
5127 }
5128
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005129 val = get_param(cmd, "AMPDU");
5130 if (val) {
5131 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
5132 /* enable AMPDU Aggregation */
5133 if (ampdu == 0) {
5134 send_resp(dut, conn, SIGMA_ERROR,
5135 "ErrorCode,Mismatch in "
5136 "addba_reject/ampdu - "
5137 "not supported");
5138 return 0;
5139 }
5140 ampdu = 1;
5141 } else {
5142 /* disable AMPDU Aggregation */
5143 if (ampdu == 1) {
5144 send_resp(dut, conn, SIGMA_ERROR,
5145 "ErrorCode,Mismatch in "
5146 "addba_reject/ampdu - "
5147 "not supported");
5148 return 0;
5149 }
5150 ampdu = 0;
5151 }
5152 }
5153
5154 if (ampdu >= 0) {
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005155 int ret;
5156
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005157 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s A-MPDU aggregation",
5158 ampdu ? "Enabling" : "Disabling");
5159 snprintf(buf, sizeof(buf), "SET ampdu %d", ampdu);
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07005160 if (wpa_command(intf, buf) < 0 &&
5161 iwpriv_sta_set_ampdu(dut, intf, ampdu) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005162 send_resp(dut, conn, SIGMA_ERROR,
5163 "ErrorCode,set aggr failed");
5164 return 0;
5165 }
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005166
5167 if (ampdu == 0) {
5168 /* Disable sending of addba using nl vendor command */
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08005169 ret = nlvendor_config_send_addba(dut, intf, 0);
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005170 if (ret) {
5171 sigma_dut_print(dut, DUT_MSG_ERROR,
5172 "Failed to disable addba, ret:%d",
5173 ret);
5174 }
5175 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005176 }
5177
5178 val = get_param(cmd, "AMSDU");
5179 if (val) {
5180 switch (get_driver_type()) {
5181 case DRIVER_ATHEROS:
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08005182 case DRIVER_WCN:
5183 iwpriv_sta_set_amsdu(dut, intf, val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005184 break;
5185 default:
5186 if (strcmp(val, "1") == 0 ||
5187 strcasecmp(val, "Enable") == 0) {
5188 /* Enable AMSDU Aggregation */
5189 send_resp(dut, conn, SIGMA_ERROR,
5190 "ErrorCode,AMSDU aggregation not supported");
5191 return 0;
5192 }
5193 break;
5194 }
5195 }
5196
5197 val = get_param(cmd, "STBC_RX");
5198 if (val) {
5199 switch (get_driver_type()) {
5200 case DRIVER_ATHEROS:
5201 ath_sta_set_stbc(dut, intf, val);
5202 break;
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05305203 case DRIVER_WCN:
5204 wcn_sta_set_stbc(dut, intf, val);
5205 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005206 default:
5207 send_resp(dut, conn, SIGMA_ERROR,
5208 "ErrorCode,STBC_RX not supported");
5209 return 0;
5210 }
5211 }
5212
5213 val = get_param(cmd, "WIDTH");
5214 if (val) {
5215 switch (get_driver_type()) {
5216 case DRIVER_WCN:
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08005217 if (wcn_sta_set_width(dut, intf, val) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005218 send_resp(dut, conn, SIGMA_ERROR,
5219 "ErrorCode,Failed to set WIDTH");
5220 return 0;
5221 }
5222 break;
5223 case DRIVER_ATHEROS:
5224 if (ath_set_width(dut, conn, intf, val) < 0)
5225 return 0;
5226 break;
5227 default:
5228 sigma_dut_print(dut, DUT_MSG_ERROR,
5229 "Setting WIDTH not supported");
5230 break;
5231 }
5232 }
5233
5234 val = get_param(cmd, "SMPS");
5235 if (val) {
5236 /* TODO: Dynamic/0, Static/1, No Limit/2 */
5237 send_resp(dut, conn, SIGMA_ERROR,
5238 "ErrorCode,SMPS not supported");
5239 return 0;
5240 }
5241
5242 val = get_param(cmd, "TXSP_STREAM");
5243 if (val) {
5244 switch (get_driver_type()) {
5245 case DRIVER_WCN:
5246 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
5247 send_resp(dut, conn, SIGMA_ERROR,
5248 "ErrorCode,Failed to set TXSP_STREAM");
5249 return 0;
5250 }
5251 break;
5252 case DRIVER_ATHEROS:
5253 ath_sta_set_txsp_stream(dut, intf, val);
5254 break;
5255 default:
5256 sigma_dut_print(dut, DUT_MSG_ERROR,
5257 "Setting TXSP_STREAM not supported");
5258 break;
5259 }
5260 }
5261
5262 val = get_param(cmd, "RXSP_STREAM");
5263 if (val) {
5264 switch (get_driver_type()) {
5265 case DRIVER_WCN:
5266 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
5267 send_resp(dut, conn, SIGMA_ERROR,
5268 "ErrorCode,Failed to set RXSP_STREAM");
5269 return 0;
5270 }
5271 break;
5272 case DRIVER_ATHEROS:
5273 ath_sta_set_rxsp_stream(dut, intf, val);
5274 break;
5275 default:
5276 sigma_dut_print(dut, DUT_MSG_ERROR,
5277 "Setting RXSP_STREAM not supported");
5278 break;
5279 }
5280 }
5281
5282 val = get_param(cmd, "DYN_BW_SGNL");
5283 if (val) {
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08005284 switch (get_driver_type()) {
5285 case DRIVER_WCN:
Peng Xuc59afd32016-11-21 15:01:11 -08005286 if (strcasecmp(val, "enable") == 0) {
5287 snprintf(buf, sizeof(buf),
5288 "iwpriv %s cwmenable 1", intf);
5289 if (system(buf) != 0) {
5290 sigma_dut_print(dut, DUT_MSG_ERROR,
5291 "iwpriv cwmenable 1 failed");
5292 return 0;
5293 }
5294 } else if (strcasecmp(val, "disable") == 0) {
5295 snprintf(buf, sizeof(buf),
5296 "iwpriv %s cwmenable 0", intf);
5297 if (system(buf) != 0) {
5298 sigma_dut_print(dut, DUT_MSG_ERROR,
5299 "iwpriv cwmenable 0 failed");
5300 return 0;
5301 }
5302 } else {
5303 sigma_dut_print(dut, DUT_MSG_ERROR,
5304 "Unsupported DYN_BW_SGL");
5305 }
5306
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005307 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 3", intf);
5308 if (system(buf) != 0) {
5309 sigma_dut_print(dut, DUT_MSG_ERROR,
5310 "Failed to set cts_cbw in DYN_BW_SGNL");
5311 return 0;
5312 }
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08005313 break;
5314 case DRIVER_ATHEROS:
priyadharshini gowthamane5e25172015-12-08 14:53:48 -08005315 novap_reset(dut, intf);
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08005316 ath_config_dyn_bw_sig(dut, intf, val);
5317 break;
5318 default:
5319 sigma_dut_print(dut, DUT_MSG_ERROR,
5320 "Failed to set DYN_BW_SGNL");
5321 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005322 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005323 }
5324
5325 val = get_param(cmd, "RTS_FORCE");
5326 if (val) {
priyadharshini gowthamane5e25172015-12-08 14:53:48 -08005327 novap_reset(dut, intf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005328 if (strcasecmp(val, "Enable") == 0) {
5329 snprintf(buf, sizeof(buf), "iwconfig %s rts 64", intf);
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02005330 if (system(buf) != 0) {
5331 sigma_dut_print(dut, DUT_MSG_ERROR,
5332 "Failed to set RTS_FORCE 64");
5333 }
priyadharshini gowthaman270870e2015-12-09 10:10:23 -08005334 snprintf(buf, sizeof(buf),
5335 "wifitool %s beeliner_fw_test 100 1", intf);
5336 if (system(buf) != 0) {
5337 sigma_dut_print(dut, DUT_MSG_ERROR,
5338 "wifitool beeliner_fw_test 100 1 failed");
5339 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005340 } else if (strcasecmp(val, "Disable") == 0) {
5341 snprintf(buf, sizeof(buf), "iwconfig %s rts 2347",
5342 intf);
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02005343 if (system(buf) != 0) {
5344 sigma_dut_print(dut, DUT_MSG_ERROR,
5345 "Failed to set RTS_FORCE 2347");
5346 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005347 } else {
5348 send_resp(dut, conn, SIGMA_ERROR,
5349 "ErrorCode,RTS_FORCE value not supported");
5350 return 0;
5351 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005352 }
5353
5354 val = get_param(cmd, "CTS_WIDTH");
5355 if (val) {
5356 switch (get_driver_type()) {
5357 case DRIVER_WCN:
5358 if (wcn_sta_set_cts_width(dut, intf, val) < 0) {
5359 send_resp(dut, conn, SIGMA_ERROR,
5360 "ErrorCode,Failed to set CTS_WIDTH");
5361 return 0;
5362 }
5363 break;
5364 case DRIVER_ATHEROS:
5365 ath_set_cts_width(dut, intf, val);
5366 break;
5367 default:
5368 sigma_dut_print(dut, DUT_MSG_ERROR,
5369 "Setting CTS_WIDTH not supported");
5370 break;
5371 }
5372 }
5373
5374 val = get_param(cmd, "BW_SGNL");
5375 if (val) {
5376 if (strcasecmp(val, "Enable") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005377 run_iwpriv(dut, intf, "cwmenable 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005378 } else if (strcasecmp(val, "Disable") == 0) {
5379 /* TODO: Disable */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005380 } else {
5381 send_resp(dut, conn, SIGMA_ERROR,
5382 "ErrorCode,BW_SGNL value not supported");
5383 return 0;
5384 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005385 }
5386
5387 val = get_param(cmd, "Band");
5388 if (val) {
5389 if (strcmp(val, "2.4") == 0 || strcmp(val, "5") == 0) {
5390 /* STA supports all bands by default */
5391 } else {
5392 send_resp(dut, conn, SIGMA_ERROR,
5393 "ErrorCode,Unsupported Band");
5394 return 0;
5395 }
5396 }
5397
5398 val = get_param(cmd, "zero_crc");
5399 if (val) {
5400 switch (get_driver_type()) {
5401 case DRIVER_ATHEROS:
5402 ath_set_zero_crc(dut, val);
5403 break;
5404 default:
5405 break;
5406 }
5407 }
5408
5409 return 1;
5410}
5411
5412
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02005413static int sta_set_force_mcs(struct sigma_dut *dut, int force, int mcs)
5414{
5415 switch (get_driver_type()) {
5416#ifdef __linux__
5417 case DRIVER_WIL6210:
5418 return wil6210_set_force_mcs(dut, force, mcs);
5419#endif /* __linux__ */
5420 default:
5421 sigma_dut_print(dut, DUT_MSG_ERROR,
5422 "Unsupported sta_set_force_mcs with the current driver");
5423 return -1;
5424 }
5425}
5426
5427
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02005428static int sta_60g_force_rsn_ie(struct sigma_dut *dut, int state)
5429{
5430 switch (get_driver_type()) {
5431#ifdef __linux__
5432 case DRIVER_WIL6210:
5433 return wil6210_force_rsn_ie(dut, state);
5434#endif /* __linux__ */
5435 default:
5436 sigma_dut_print(dut, DUT_MSG_ERROR,
5437 "Unsupported sta_60g_force_rsn_ie with the current driver");
5438 return -1;
5439 }
5440}
5441
5442
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005443static int sta_set_60g_common(struct sigma_dut *dut, struct sigma_conn *conn,
5444 struct sigma_cmd *cmd)
5445{
5446 const char *val;
5447 char buf[100];
5448
5449 val = get_param(cmd, "MSDUSize");
5450 if (val) {
5451 int mtu;
5452
5453 dut->amsdu_size = atoi(val);
5454 if (dut->amsdu_size > IEEE80211_MAX_DATA_LEN_DMG ||
5455 dut->amsdu_size < IEEE80211_SNAP_LEN_DMG) {
5456 sigma_dut_print(dut, DUT_MSG_ERROR,
5457 "MSDUSize %d is above max %d or below min %d",
5458 dut->amsdu_size,
5459 IEEE80211_MAX_DATA_LEN_DMG,
5460 IEEE80211_SNAP_LEN_DMG);
5461 dut->amsdu_size = 0;
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005462 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005463 }
5464
5465 mtu = dut->amsdu_size - IEEE80211_SNAP_LEN_DMG;
5466 sigma_dut_print(dut, DUT_MSG_DEBUG,
5467 "Setting amsdu_size to %d", mtu);
5468 snprintf(buf, sizeof(buf), "ifconfig %s mtu %d",
5469 get_station_ifname(), mtu);
5470
5471 if (system(buf) != 0) {
5472 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
5473 buf);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005474 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005475 }
5476 }
5477
5478 val = get_param(cmd, "BAckRcvBuf");
5479 if (val) {
5480 dut->back_rcv_buf = atoi(val);
5481 if (dut->back_rcv_buf == 0) {
5482 sigma_dut_print(dut, DUT_MSG_ERROR,
5483 "Failed to convert %s or value is 0",
5484 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005485 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005486 }
5487
5488 sigma_dut_print(dut, DUT_MSG_DEBUG,
5489 "Setting BAckRcvBuf to %s", val);
5490 }
5491
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02005492 val = get_param(cmd, "MCS_FixedRate");
5493 if (val) {
5494 if (sta_set_force_mcs(dut, 1, atoi(val))) {
5495 sigma_dut_print(dut, DUT_MSG_ERROR,
5496 "Failed to force MCS");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005497 return ERROR_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02005498 }
5499 }
5500
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005501 return SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005502}
5503
5504
5505static int sta_pcp_start(struct sigma_dut *dut, struct sigma_conn *conn,
5506 struct sigma_cmd *cmd)
5507{
5508 int net_id;
5509 char *ifname;
5510 const char *val;
5511 char buf[100];
5512
5513 dut->mode = SIGMA_MODE_STATION;
5514 ifname = get_main_ifname();
5515 if (wpa_command(ifname, "PING") != 0) {
5516 sigma_dut_print(dut, DUT_MSG_ERROR, "Supplicant not running");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005517 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005518 }
5519
5520 wpa_command(ifname, "FLUSH");
5521 net_id = add_network_common(dut, conn, ifname, cmd);
5522 if (net_id < 0) {
5523 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add network");
5524 return net_id;
5525 }
5526
5527 /* TODO: mode=2 for the AP; in the future, replace for mode PCP */
5528 if (set_network(ifname, net_id, "mode", "2") < 0) {
5529 sigma_dut_print(dut, DUT_MSG_ERROR,
5530 "Failed to set supplicant network mode");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005531 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005532 }
5533
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02005534 if (set_network(ifname, net_id, "pbss", "1") < 0)
5535 return -2;
5536
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005537 sigma_dut_print(dut, DUT_MSG_DEBUG,
Alexei Avshalom Lazarfd9f1352018-11-13 14:07:58 +02005538 "Supplicant set network with mode 2. network_id %d",
5539 net_id);
5540
5541 if (set_network(ifname, net_id, "wps_disabled", "0") < 0) {
5542 sigma_dut_print(dut, DUT_MSG_INFO,
5543 "Failed to set supplicant to WPS ENABLE");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005544 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarfd9f1352018-11-13 14:07:58 +02005545 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005546
5547 val = get_param(cmd, "Security");
5548 if (val && strcasecmp(val, "OPEN") == 0) {
5549 dut->ap_key_mgmt = AP_OPEN;
5550 if (set_network(ifname, net_id, "key_mgmt", "NONE") < 0) {
5551 sigma_dut_print(dut, DUT_MSG_ERROR,
5552 "Failed to set supplicant to %s security",
5553 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005554 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005555 }
5556 } else if (val && strcasecmp(val, "WPA2-PSK") == 0) {
5557 dut->ap_key_mgmt = AP_WPA2_PSK;
5558 if (set_network(ifname, net_id, "key_mgmt", "WPA-PSK") < 0) {
5559 sigma_dut_print(dut, DUT_MSG_ERROR,
5560 "Failed to set supplicant to %s security",
5561 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005562 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005563 }
5564
5565 if (set_network(ifname, net_id, "proto", "RSN") < 0) {
5566 sigma_dut_print(dut, DUT_MSG_ERROR,
5567 "Failed to set supplicant to proto RSN");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005568 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005569 }
5570 } else if (val) {
5571 sigma_dut_print(dut, DUT_MSG_ERROR,
5572 "Requested Security %s is not supported on 60GHz",
5573 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005574 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005575 }
5576
5577 val = get_param(cmd, "Encrypt");
5578 if (val && strcasecmp(val, "AES-GCMP") == 0) {
5579 if (set_network(ifname, net_id, "pairwise", "GCMP") < 0) {
5580 sigma_dut_print(dut, DUT_MSG_ERROR,
5581 "Failed to set supplicant to pairwise GCMP");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005582 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005583 }
5584 if (set_network(ifname, net_id, "group", "GCMP") < 0) {
5585 sigma_dut_print(dut, DUT_MSG_ERROR,
5586 "Failed to set supplicant to group GCMP");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005587 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005588 }
5589 } else if (val) {
5590 sigma_dut_print(dut, DUT_MSG_ERROR,
5591 "Requested Encrypt %s is not supported on 60 GHz",
5592 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005593 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005594 }
5595
5596 val = get_param(cmd, "PSK");
5597 if (val && set_network_quoted(ifname, net_id, "psk", val) < 0) {
5598 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set psk %s",
5599 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005600 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005601 }
5602
5603 /* Convert 60G channel to freq */
5604 switch (dut->ap_channel) {
5605 case 1:
5606 val = "58320";
5607 break;
5608 case 2:
5609 val = "60480";
5610 break;
5611 case 3:
5612 val = "62640";
5613 break;
5614 default:
5615 sigma_dut_print(dut, DUT_MSG_ERROR,
5616 "Failed to configure channel %d. Not supported",
5617 dut->ap_channel);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005618 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005619 }
5620
5621 if (set_network(ifname, net_id, "frequency", val) < 0) {
5622 sigma_dut_print(dut, DUT_MSG_ERROR,
5623 "Failed to set supplicant network frequency");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005624 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005625 }
5626
Alexei Avshalom Lazar2eccf4d2019-01-31 10:03:59 +02005627 if (dut->eap_fragment) {
5628 sigma_dut_print(dut, DUT_MSG_DEBUG,
5629 "Set EAP fragment size to 128 bytes.");
5630 if (set_network(ifname, net_id, "fragment_size", "128") < 0)
5631 return ERROR_SEND_STATUS;
5632 }
5633
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005634 sigma_dut_print(dut, DUT_MSG_DEBUG,
5635 "Supplicant set network with frequency");
5636
5637 snprintf(buf, sizeof(buf), "SELECT_NETWORK %d", net_id);
5638 if (wpa_command(ifname, buf) < 0) {
5639 sigma_dut_print(dut, DUT_MSG_INFO,
5640 "Failed to select network id %d on %s",
5641 net_id, ifname);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005642 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005643 }
5644
5645 sigma_dut_print(dut, DUT_MSG_DEBUG, "Selected network");
5646
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005647 return SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005648}
5649
5650
Lior David67543f52017-01-03 19:04:22 +02005651static int wil6210_set_abft_len(struct sigma_dut *dut, int abft_len)
5652{
5653 char buf[128], fname[128];
5654 FILE *f;
5655
5656 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
5657 sigma_dut_print(dut, DUT_MSG_ERROR,
5658 "failed to get wil6210 debugfs dir");
5659 return -1;
5660 }
5661
5662 snprintf(fname, sizeof(fname), "%s/abft_len", buf);
5663 f = fopen(fname, "w");
5664 if (!f) {
5665 sigma_dut_print(dut, DUT_MSG_ERROR,
5666 "failed to open: %s", fname);
5667 return -1;
5668 }
5669
5670 fprintf(f, "%d\n", abft_len);
5671 fclose(f);
5672
5673 return 0;
5674}
5675
5676
Alexei Avshalom Lazar49498b82019-01-31 15:16:32 +02005677int sta_set_60g_abft_len(struct sigma_dut *dut, struct sigma_conn *conn,
5678 int abft_len)
Lior David67543f52017-01-03 19:04:22 +02005679{
5680 switch (get_driver_type()) {
5681 case DRIVER_WIL6210:
5682 return wil6210_set_abft_len(dut, abft_len);
5683 default:
5684 sigma_dut_print(dut, DUT_MSG_ERROR,
5685 "set abft_len not supported");
5686 return -1;
5687 }
5688}
5689
5690
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005691static int sta_set_60g_pcp(struct sigma_dut *dut, struct sigma_conn *conn,
5692 struct sigma_cmd *cmd)
5693{
5694 const char *val;
Lior David67543f52017-01-03 19:04:22 +02005695 unsigned int abft_len = 1; /* default is one slot */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005696
5697 if (dut->dev_role != DEVROLE_PCP) {
5698 send_resp(dut, conn, SIGMA_INVALID,
5699 "ErrorCode,Invalid DevRole");
5700 return 0;
5701 }
5702
5703 val = get_param(cmd, "SSID");
5704 if (val) {
5705 if (strlen(val) > sizeof(dut->ap_ssid) - 1) {
5706 send_resp(dut, conn, SIGMA_INVALID,
5707 "ErrorCode,Invalid SSID");
5708 return -1;
5709 }
5710
Peng Xub8fc5cc2017-05-10 17:27:28 -07005711 strlcpy(dut->ap_ssid, val, sizeof(dut->ap_ssid));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005712 }
5713
5714 val = get_param(cmd, "CHANNEL");
5715 if (val) {
5716 const char *pos;
5717
5718 dut->ap_channel = atoi(val);
5719 pos = strchr(val, ';');
5720 if (pos) {
5721 pos++;
5722 dut->ap_channel_1 = atoi(pos);
5723 }
5724 }
5725
5726 switch (dut->ap_channel) {
5727 case 1:
5728 case 2:
5729 case 3:
5730 break;
5731 default:
5732 sigma_dut_print(dut, DUT_MSG_ERROR,
5733 "Channel %d is not supported", dut->ap_channel);
5734 send_resp(dut, conn, SIGMA_ERROR,
5735 "Requested channel is not supported");
5736 return -1;
5737 }
5738
5739 val = get_param(cmd, "BCNINT");
5740 if (val)
5741 dut->ap_bcnint = atoi(val);
5742
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005743 val = get_param(cmd, "AllocType");
5744 if (val) {
5745 send_resp(dut, conn, SIGMA_ERROR,
5746 "ErrorCode,AllocType is not supported yet");
5747 return -1;
5748 }
5749
5750 val = get_param(cmd, "PercentBI");
5751 if (val) {
5752 send_resp(dut, conn, SIGMA_ERROR,
5753 "ErrorCode,PercentBI is not supported yet");
5754 return -1;
5755 }
5756
5757 val = get_param(cmd, "CBAPOnly");
5758 if (val) {
5759 send_resp(dut, conn, SIGMA_ERROR,
5760 "ErrorCode,CBAPOnly is not supported yet");
5761 return -1;
5762 }
5763
5764 val = get_param(cmd, "AMPDU");
5765 if (val) {
5766 if (strcasecmp(val, "Enable") == 0)
5767 dut->ap_ampdu = 1;
5768 else if (strcasecmp(val, "Disable") == 0)
5769 dut->ap_ampdu = 2;
5770 else {
5771 send_resp(dut, conn, SIGMA_ERROR,
5772 "ErrorCode,AMPDU value is not Enable nor Disabled");
5773 return -1;
5774 }
5775 }
5776
5777 val = get_param(cmd, "AMSDU");
5778 if (val) {
5779 if (strcasecmp(val, "Enable") == 0)
5780 dut->ap_amsdu = 1;
5781 else if (strcasecmp(val, "Disable") == 0)
5782 dut->ap_amsdu = 2;
5783 }
5784
5785 val = get_param(cmd, "NumMSDU");
5786 if (val) {
5787 send_resp(dut, conn, SIGMA_ERROR,
5788 "ErrorCode, NumMSDU is not supported yet");
5789 return -1;
5790 }
5791
5792 val = get_param(cmd, "ABFTLRang");
5793 if (val) {
5794 sigma_dut_print(dut, DUT_MSG_DEBUG,
Lior David67543f52017-01-03 19:04:22 +02005795 "ABFTLRang parameter %s", val);
5796 if (strcmp(val, "Gt1") == 0)
5797 abft_len = 2; /* 2 slots in this case */
5798 }
5799
5800 if (sta_set_60g_abft_len(dut, conn, abft_len)) {
5801 send_resp(dut, conn, SIGMA_ERROR,
5802 "ErrorCode, Can't set ABFT length");
5803 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005804 }
5805
5806 if (sta_pcp_start(dut, conn, cmd) < 0) {
5807 send_resp(dut, conn, SIGMA_ERROR,
5808 "ErrorCode, Can't start PCP role");
5809 return -1;
5810 }
5811
5812 return sta_set_60g_common(dut, conn, cmd);
5813}
5814
5815
5816static int sta_set_60g_sta(struct sigma_dut *dut, struct sigma_conn *conn,
5817 struct sigma_cmd *cmd)
5818{
5819 const char *val = get_param(cmd, "DiscoveryMode");
5820
5821 if (dut->dev_role != DEVROLE_STA) {
5822 send_resp(dut, conn, SIGMA_INVALID,
5823 "ErrorCode,Invalid DevRole");
5824 return 0;
5825 }
5826
5827 if (val) {
5828 sigma_dut_print(dut, DUT_MSG_DEBUG, "Discovery: %s", val);
5829 /* Ignore Discovery mode till Driver expose API. */
5830#if 0
5831 if (strcasecmp(val, "1") == 0) {
5832 send_resp(dut, conn, SIGMA_INVALID,
5833 "ErrorCode,DiscoveryMode 1 not supported");
5834 return 0;
5835 }
5836
5837 if (strcasecmp(val, "0") == 0) {
5838 /* OK */
5839 } else {
5840 send_resp(dut, conn, SIGMA_INVALID,
5841 "ErrorCode,DiscoveryMode not supported");
5842 return 0;
5843 }
5844#endif
5845 }
5846
5847 if (start_sta_mode(dut) != 0)
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005848 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005849 return sta_set_60g_common(dut, conn, cmd);
5850}
5851
5852
5853static int cmd_sta_disconnect(struct sigma_dut *dut, struct sigma_conn *conn,
5854 struct sigma_cmd *cmd)
5855{
5856 const char *intf = get_param(cmd, "Interface");
Jouni Malinened77e672018-01-10 16:45:13 +02005857 const char *val = get_param(cmd, "maintain_profile");
vamsi krishnad605c422017-09-20 14:56:31 +05305858
Jouni Malinened77e672018-01-10 16:45:13 +02005859 if (dut->program == PROGRAM_OCE ||
Amarnath Hullur Subramanyamebeda9e2018-01-31 03:21:48 -08005860 dut->program == PROGRAM_HE ||
Jouni Malinened77e672018-01-10 16:45:13 +02005861 (val && atoi(val) == 1)) {
vamsi krishnad605c422017-09-20 14:56:31 +05305862 wpa_command(intf, "DISCONNECT");
5863 return 1;
5864 }
5865
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005866 disconnect_station(dut);
5867 /* Try to ignore old scan results to avoid HS 2.0R2 test case failures
5868 * due to cached results. */
5869 wpa_command(intf, "SET ignore_old_scan_res 1");
5870 wpa_command(intf, "BSS_FLUSH");
5871 return 1;
5872}
5873
5874
5875static int cmd_sta_reassoc(struct sigma_dut *dut, struct sigma_conn *conn,
5876 struct sigma_cmd *cmd)
5877{
5878 const char *intf = get_param(cmd, "Interface");
5879 const char *bssid = get_param(cmd, "bssid");
5880 const char *val = get_param(cmd, "CHANNEL");
5881 struct wpa_ctrl *ctrl;
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05305882 char buf[1000];
Sunil Duttd30ce092018-01-11 23:56:29 +05305883 char result[32];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005884 int res;
5885 int chan = 0;
Ashwini Patil467efef2017-05-25 12:18:27 +05305886 int status = 0;
Sunil Duttd30ce092018-01-11 23:56:29 +05305887 int fastreassoc = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005888
5889 if (bssid == NULL) {
5890 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing bssid "
5891 "argument");
5892 return 0;
5893 }
5894
5895 if (val)
5896 chan = atoi(val);
5897
5898 if (wifi_chip_type != DRIVER_WCN && wifi_chip_type != DRIVER_AR6003) {
5899 /* The current network may be from sta_associate or
5900 * sta_hs2_associate
5901 */
5902 if (set_network(intf, dut->infra_network_id, "bssid", bssid) <
5903 0 ||
5904 set_network(intf, 0, "bssid", bssid) < 0)
5905 return -2;
5906 }
5907
5908 ctrl = open_wpa_mon(intf);
5909 if (ctrl == NULL) {
5910 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
5911 "wpa_supplicant monitor connection");
5912 return -1;
5913 }
5914
Sunil Duttd30ce092018-01-11 23:56:29 +05305915 if (get_wpa_status(get_station_ifname(), "wpa_state", result,
5916 sizeof(result)) < 0 ||
5917 strncmp(result, "COMPLETED", 9) != 0) {
5918 sigma_dut_print(dut, DUT_MSG_DEBUG,
5919 "sta_reassoc: Not connected");
5920 fastreassoc = 0;
5921 }
5922
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05305923 if (dut->rsne_override) {
5924#ifdef NL80211_SUPPORT
5925 if (get_driver_type() == DRIVER_WCN && dut->config_rsnie == 0) {
5926 sta_config_rsnie(dut, 1);
5927 dut->config_rsnie = 1;
5928 }
5929#endif /* NL80211_SUPPORT */
5930 snprintf(buf, sizeof(buf), "TEST_ASSOC_IE %s",
5931 dut->rsne_override);
5932 if (wpa_command(intf, buf) < 0) {
5933 send_resp(dut, conn, SIGMA_ERROR,
5934 "ErrorCode,Failed to set DEV_CONFIGURE_IE RSNE override");
5935 return 0;
5936 }
5937 }
5938
Sunil Duttd30ce092018-01-11 23:56:29 +05305939 if (wifi_chip_type == DRIVER_WCN && fastreassoc) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005940#ifdef ANDROID
Ashwini Patil4c8158f2017-05-25 12:49:21 +05305941 if (chan) {
5942 unsigned int freq;
5943
Alexei Avshalom Lazar093569f2018-11-13 14:08:17 +02005944 freq = channel_to_freq(dut, chan);
Ashwini Patil4c8158f2017-05-25 12:49:21 +05305945 if (!freq) {
5946 sigma_dut_print(dut, DUT_MSG_ERROR,
5947 "Invalid channel number provided: %d",
5948 chan);
5949 send_resp(dut, conn, SIGMA_INVALID,
5950 "ErrorCode,Invalid channel number");
5951 goto close_mon_conn;
5952 }
5953 res = snprintf(buf, sizeof(buf),
5954 "SCAN TYPE=ONLY freq=%d", freq);
5955 } else {
5956 res = snprintf(buf, sizeof(buf), "SCAN TYPE=ONLY");
5957 }
5958 if (res < 0 || res >= (int) sizeof(buf)) {
5959 send_resp(dut, conn, SIGMA_ERROR,
5960 "ErrorCode,snprintf failed");
5961 goto close_mon_conn;
5962 }
5963 if (wpa_command(intf, buf) < 0) {
5964 sigma_dut_print(dut, DUT_MSG_INFO,
5965 "Failed to start scan");
5966 send_resp(dut, conn, SIGMA_ERROR,
5967 "ErrorCode,scan failed");
5968 goto close_mon_conn;
5969 }
5970
5971 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
5972 buf, sizeof(buf));
5973 if (res < 0) {
5974 sigma_dut_print(dut, DUT_MSG_INFO,
5975 "Scan did not complete");
5976 send_resp(dut, conn, SIGMA_ERROR,
5977 "ErrorCode,scan did not complete");
5978 goto close_mon_conn;
5979 }
5980
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005981 if (set_network(intf, dut->infra_network_id, "bssid", "any")
5982 < 0) {
5983 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
5984 "bssid to any during FASTREASSOC");
Ashwini Patil467efef2017-05-25 12:18:27 +05305985 status = -2;
5986 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005987 }
5988 res = snprintf(buf, sizeof(buf), "DRIVER FASTREASSOC %s %d",
5989 bssid, chan);
5990 if (res > 0 && res < (int) sizeof(buf))
5991 res = wpa_command(intf, buf);
5992
5993 if (res < 0 || res >= (int) sizeof(buf)) {
5994 send_resp(dut, conn, SIGMA_ERROR,
5995 "errorCode,Failed to run DRIVER FASTREASSOC");
Ashwini Patil467efef2017-05-25 12:18:27 +05305996 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005997 }
5998#else /* ANDROID */
5999 sigma_dut_print(dut, DUT_MSG_DEBUG,
6000 "Reassoc using iwpriv - skip chan=%d info",
6001 chan);
6002 snprintf(buf, sizeof(buf), "iwpriv %s reassoc", intf);
6003 if (system(buf) != 0) {
6004 sigma_dut_print(dut, DUT_MSG_ERROR, "%s failed", buf);
Ashwini Patil467efef2017-05-25 12:18:27 +05306005 status = -2;
6006 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006007 }
6008#endif /* ANDROID */
6009 sigma_dut_print(dut, DUT_MSG_INFO,
6010 "sta_reassoc: Run %s successful", buf);
6011 } else if (wpa_command(intf, "REASSOCIATE")) {
6012 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
6013 "request reassociation");
Ashwini Patil467efef2017-05-25 12:18:27 +05306014 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006015 }
6016
6017 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
6018 buf, sizeof(buf));
Ashwini Patil467efef2017-05-25 12:18:27 +05306019 if (res < 0) {
6020 sigma_dut_print(dut, DUT_MSG_INFO, "Connection did not complete");
6021 status = -1;
6022 goto close_mon_conn;
6023 }
6024 status = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006025
Ashwini Patil467efef2017-05-25 12:18:27 +05306026close_mon_conn:
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006027 wpa_ctrl_detach(ctrl);
6028 wpa_ctrl_close(ctrl);
Ashwini Patil467efef2017-05-25 12:18:27 +05306029 return status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006030}
6031
6032
6033static void hs2_clear_credentials(const char *intf)
6034{
6035 wpa_command(intf, "REMOVE_CRED all");
6036}
6037
6038
Lior Davidcc88b562017-01-03 18:52:09 +02006039#ifdef __linux__
6040static int wil6210_get_aid(struct sigma_dut *dut, const char *bssid,
6041 unsigned int *aid)
6042{
Lior David0fe101e2017-03-09 16:09:50 +02006043 const char *pattern = "AID[ \t]+([0-9]+)";
Lior Davidcc88b562017-01-03 18:52:09 +02006044
Lior David0fe101e2017-03-09 16:09:50 +02006045 return wil6210_get_sta_info_field(dut, bssid, pattern, aid);
Lior Davidcc88b562017-01-03 18:52:09 +02006046}
6047#endif /* __linux__ */
6048
6049
6050static int sta_get_aid_60g(struct sigma_dut *dut, const char *bssid,
6051 unsigned int *aid)
6052{
6053 switch (get_driver_type()) {
6054#ifdef __linux__
6055 case DRIVER_WIL6210:
6056 return wil6210_get_aid(dut, bssid, aid);
6057#endif /* __linux__ */
6058 default:
6059 sigma_dut_print(dut, DUT_MSG_ERROR, "get AID not supported");
6060 return -1;
6061 }
6062}
6063
6064
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006065static int sta_get_parameter_60g(struct sigma_dut *dut, struct sigma_conn *conn,
6066 struct sigma_cmd *cmd)
6067{
6068 char buf[MAX_CMD_LEN];
6069 char bss_list[MAX_CMD_LEN];
6070 const char *parameter = get_param(cmd, "Parameter");
6071
6072 if (parameter == NULL)
6073 return -1;
6074
Lior Davidcc88b562017-01-03 18:52:09 +02006075 if (strcasecmp(parameter, "AID") == 0) {
6076 unsigned int aid = 0;
6077 char bssid[20];
6078
6079 if (get_wpa_status(get_station_ifname(), "bssid",
6080 bssid, sizeof(bssid)) < 0) {
6081 sigma_dut_print(dut, DUT_MSG_ERROR,
6082 "could not get bssid");
6083 return -2;
6084 }
6085
6086 if (sta_get_aid_60g(dut, bssid, &aid))
6087 return -2;
6088
6089 snprintf(buf, sizeof(buf), "aid,%d", aid);
6090 sigma_dut_print(dut, DUT_MSG_INFO, "%s", buf);
6091 send_resp(dut, conn, SIGMA_COMPLETE, buf);
6092 return 0;
6093 }
6094
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006095 if (strcasecmp(parameter, "DiscoveredDevList") == 0) {
6096 char *bss_line;
6097 char *bss_id = NULL;
6098 const char *ifname = get_param(cmd, "Interface");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05306099 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006100
6101 if (ifname == NULL) {
6102 sigma_dut_print(dut, DUT_MSG_INFO,
6103 "For get DiscoveredDevList need Interface name.");
6104 return -1;
6105 }
6106
6107 /*
6108 * Use "BSS RANGE=ALL MASK=0x2" which provides a list
6109 * of BSSIDs in "bssid=<BSSID>\n"
6110 */
6111 if (wpa_command_resp(ifname, "BSS RANGE=ALL MASK=0x2",
6112 bss_list,
6113 sizeof(bss_list)) < 0) {
6114 sigma_dut_print(dut, DUT_MSG_ERROR,
6115 "Failed to get bss list");
6116 return -1;
6117 }
6118
6119 sigma_dut_print(dut, DUT_MSG_DEBUG,
6120 "bss list for ifname:%s is:%s",
6121 ifname, bss_list);
6122
6123 snprintf(buf, sizeof(buf), "DeviceList");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05306124 bss_line = strtok_r(bss_list, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006125 while (bss_line) {
6126 if (sscanf(bss_line, "bssid=%ms", &bss_id) > 0 &&
6127 bss_id) {
6128 int len;
6129
6130 len = snprintf(buf + strlen(buf),
6131 sizeof(buf) - strlen(buf),
6132 ",%s", bss_id);
6133 free(bss_id);
6134 bss_id = NULL;
6135 if (len < 0) {
6136 sigma_dut_print(dut,
6137 DUT_MSG_ERROR,
6138 "Failed to read BSSID");
6139 send_resp(dut, conn, SIGMA_ERROR,
6140 "ErrorCode,Failed to read BSS ID");
6141 return 0;
6142 }
6143
6144 if ((size_t) len >= sizeof(buf) - strlen(buf)) {
6145 sigma_dut_print(dut,
6146 DUT_MSG_ERROR,
6147 "Response buf too small for list");
6148 send_resp(dut, conn,
6149 SIGMA_ERROR,
6150 "ErrorCode,Response buf too small for list");
6151 return 0;
6152 }
6153 }
6154
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05306155 bss_line = strtok_r(NULL, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006156 }
6157
6158 sigma_dut_print(dut, DUT_MSG_INFO, "DiscoveredDevList is %s",
6159 buf);
6160 send_resp(dut, conn, SIGMA_COMPLETE, buf);
6161 return 0;
6162 }
6163
6164 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
6165 return 0;
6166}
6167
6168
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07006169static int sta_get_parameter_he(struct sigma_dut *dut, struct sigma_conn *conn,
6170 struct sigma_cmd *cmd)
6171{
6172 char buf[MAX_CMD_LEN];
6173 const char *parameter = get_param(cmd, "Parameter");
6174
6175 if (!parameter)
6176 return -1;
6177
6178 if (strcasecmp(parameter, "RSSI") == 0) {
6179 char rssi[10];
6180
6181 if (get_wpa_signal_poll(dut, get_station_ifname(), "RSSI",
6182 rssi, sizeof(rssi)) < 0) {
6183 sigma_dut_print(dut, DUT_MSG_ERROR,
6184 "Could not get RSSI");
6185 return -2;
6186 }
6187
6188 snprintf(buf, sizeof(buf), "rssi,%s", rssi);
6189 sigma_dut_print(dut, DUT_MSG_INFO, "RSSI %s", buf);
6190 send_resp(dut, conn, SIGMA_COMPLETE, buf);
6191 return 0;
6192 }
6193
6194 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
6195 return 0;
6196}
6197
6198
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006199static int cmd_sta_get_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
6200 struct sigma_cmd *cmd)
6201{
6202 const char *program = get_param(cmd, "Program");
6203
6204 if (program == NULL)
6205 return -1;
6206
6207 if (strcasecmp(program, "P2PNFC") == 0)
6208 return p2p_cmd_sta_get_parameter(dut, conn, cmd);
6209
6210 if (strcasecmp(program, "60ghz") == 0)
6211 return sta_get_parameter_60g(dut, conn, cmd);
6212
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07006213 if (strcasecmp(program, "he") == 0)
6214 return sta_get_parameter_he(dut, conn, cmd);
6215
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006216#ifdef ANDROID_NAN
6217 if (strcasecmp(program, "NAN") == 0)
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07006218 return nan_cmd_sta_get_parameter(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006219#endif /* ANDROID_NAN */
6220
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07006221#ifdef MIRACAST
6222 if (strcasecmp(program, "WFD") == 0 ||
6223 strcasecmp(program, "DisplayR2") == 0)
6224 return miracast_cmd_sta_get_parameter(dut, conn, cmd);
6225#endif /* MIRACAST */
6226
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006227 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
6228 return 0;
6229}
6230
6231
6232static void sta_reset_default_ath(struct sigma_dut *dut, const char *intf,
6233 const char *type)
6234{
6235 char buf[100];
6236
6237 if (dut->program == PROGRAM_VHT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006238 run_iwpriv(dut, intf, "chwidth 2");
6239 run_iwpriv(dut, intf, "mode 11ACVHT80");
6240 run_iwpriv(dut, intf, "vhtmcs -1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006241 }
6242
6243 if (dut->program == PROGRAM_HT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006244 run_iwpriv(dut, intf, "chwidth 0");
6245 run_iwpriv(dut, intf, "mode 11naht40");
6246 run_iwpriv(dut, intf, "set11NRates 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006247 }
6248
6249 if (dut->program == PROGRAM_VHT || dut->program == PROGRAM_HT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006250 run_iwpriv(dut, intf, "powersave 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006251
6252 /* Reset CTS width */
6253 snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 54 0",
6254 intf);
6255 if (system(buf) != 0) {
6256 sigma_dut_print(dut, DUT_MSG_ERROR,
6257 "wifitool %s beeliner_fw_test 54 0 failed",
6258 intf);
6259 }
6260
6261 /* Enable Dynamic Bandwidth signalling by default */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006262 run_iwpriv(dut, intf, "cwmenable 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006263
6264 snprintf(buf, sizeof(buf), "iwconfig %s rts 2347", intf);
6265 if (system(buf) != 0) {
6266 sigma_dut_print(dut, DUT_MSG_ERROR,
6267 "iwpriv rts failed");
6268 }
6269 }
6270
6271 if (type && strcasecmp(type, "Testbed") == 0) {
6272 dut->testbed_flag_txsp = 1;
6273 dut->testbed_flag_rxsp = 1;
6274 /* STA has to set spatial stream to 2 per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006275 run_iwpriv(dut, intf, "vht_mcsmap 0xfff0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006276
6277 /* Disable LDPC per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006278 run_iwpriv(dut, intf, "ldpc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006279
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006280 run_iwpriv(dut, intf, "amsdu 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006281
6282 /* TODO: Disable STBC 2x1 transmit and receive */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006283 run_iwpriv(dut, intf, "tx_stbc 0");
6284 run_iwpriv(dut, intf, "rx_stbc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006285
6286 /* STA has to disable Short GI per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006287 run_iwpriv(dut, intf, "shortgi 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006288 }
6289
6290 if (type && strcasecmp(type, "DUT") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006291 run_iwpriv(dut, intf, "nss 3");
Arif Hussainac6c5112018-05-25 17:34:00 -07006292 dut->sta_nss = 3;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006293
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006294 run_iwpriv(dut, intf, "shortgi 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006295 }
6296}
6297
6298
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08006299#ifdef NL80211_SUPPORT
6300static int sta_set_he_mcs(struct sigma_dut *dut, const char *intf,
6301 enum he_mcs_config mcs)
6302{
6303 struct nl_msg *msg;
6304 int ret = 0;
6305 struct nlattr *params;
6306 int ifindex;
6307
6308 ifindex = if_nametoindex(intf);
6309 if (ifindex == 0) {
6310 sigma_dut_print(dut, DUT_MSG_ERROR,
6311 "%s: Index for interface %s failed",
6312 __func__, intf);
6313 return -1;
6314 }
6315
6316 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6317 NL80211_CMD_VENDOR)) ||
6318 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6319 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6320 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6321 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6322 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6323 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MCS,
6324 mcs)) {
6325 sigma_dut_print(dut, DUT_MSG_ERROR,
6326 "%s: err in adding vendor_cmd and vendor_data",
6327 __func__);
6328 nlmsg_free(msg);
6329 return -1;
6330 }
6331 nla_nest_end(msg, params);
6332
6333 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6334 if (ret) {
6335 sigma_dut_print(dut, DUT_MSG_ERROR,
6336 "%s: err in send_and_recv_msgs, ret=%d",
6337 __func__, ret);
6338 }
6339 return ret;
6340}
6341#endif /* NL80211_SUPPORT */
6342
6343
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07006344static int sta_set_action_tx_in_he_tb_ppdu(struct sigma_dut *dut,
6345 const char *intf, int enable)
6346{
6347#ifdef NL80211_SUPPORT
6348 struct nl_msg *msg;
6349 int ret = 0;
6350 struct nlattr *params;
6351 int ifindex;
6352
6353 ifindex = if_nametoindex(intf);
6354 if (ifindex == 0) {
6355 sigma_dut_print(dut, DUT_MSG_ERROR,
6356 "%s: Index for interface %s failed",
6357 __func__, intf);
6358 return -1;
6359 }
6360
6361 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6362 NL80211_CMD_VENDOR)) ||
6363 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6364 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6365 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6366 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6367 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6368 nla_put_u8(msg,
6369 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_ACTION_TX_TB_PPDU,
6370 enable)) {
6371 sigma_dut_print(dut, DUT_MSG_ERROR,
6372 "%s: err in adding vendor_cmd and vendor_data",
6373 __func__);
6374 nlmsg_free(msg);
6375 return -1;
6376 }
6377 nla_nest_end(msg, params);
6378
6379 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6380 if (ret) {
6381 sigma_dut_print(dut, DUT_MSG_ERROR,
6382 "%s: err in send_and_recv_msgs, ret=%d",
6383 __func__, ret);
6384 }
6385 return ret;
6386#else /* NL80211_SUPPORT */
6387 sigma_dut_print(dut, DUT_MSG_ERROR,
6388 "HE action Tx TB PPDU cannot be set without NL80211_SUPPORT defined");
6389 return -1;
6390#endif /* NL80211_SUPPORT */
6391}
6392
6393
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08006394static int sta_set_heconfig_and_wep_tkip(struct sigma_dut *dut,
6395 const char *intf, int enable)
6396{
6397#ifdef NL80211_SUPPORT
6398 struct nl_msg *msg;
6399 int ret = 0;
6400 struct nlattr *params;
6401 int ifindex;
6402
6403 ifindex = if_nametoindex(intf);
6404 if (ifindex == 0) {
6405 sigma_dut_print(dut, DUT_MSG_ERROR,
6406 "%s: Index for interface %s failed",
6407 __func__, intf);
6408 return -1;
6409 }
6410
6411 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6412 NL80211_CMD_VENDOR)) ||
6413 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6414 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6415 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6416 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6417 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6418 nla_put_u8(msg,
6419 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WEP_TKIP_IN_HE,
6420 enable)) {
6421 sigma_dut_print(dut, DUT_MSG_ERROR,
6422 "%s: err in adding vendor_cmd and vendor_data",
6423 __func__);
6424 nlmsg_free(msg);
6425 return -1;
6426 }
6427 nla_nest_end(msg, params);
6428
6429 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6430 if (ret) {
6431 sigma_dut_print(dut, DUT_MSG_ERROR,
6432 "%s: err in send_and_recv_msgs, ret=%d",
6433 __func__, ret);
6434 }
6435 return ret;
6436#else /* NL80211_SUPPORT */
6437 sigma_dut_print(dut, DUT_MSG_ERROR,
6438 "HE config enablement cannot be changed without NL80211_SUPPORT defined");
6439 return -1;
6440#endif /* NL80211_SUPPORT */
6441}
6442
6443
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08006444#ifdef NL80211_SUPPORT
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08006445
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08006446static int sta_set_he_testbed_def(struct sigma_dut *dut,
6447 const char *intf, int cfg)
6448{
6449 struct nl_msg *msg;
6450 int ret = 0;
6451 struct nlattr *params;
6452 int ifindex;
6453
6454 ifindex = if_nametoindex(intf);
6455 if (ifindex == 0) {
6456 sigma_dut_print(dut, DUT_MSG_ERROR,
6457 "%s: Index for interface %s failed",
6458 __func__, intf);
6459 return -1;
6460 }
6461
6462 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6463 NL80211_CMD_VENDOR)) ||
6464 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6465 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6466 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6467 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6468 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6469 nla_put_u8(msg,
6470 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_SET_HE_TESTBED_DEFAULTS,
6471 cfg)) {
6472 sigma_dut_print(dut, DUT_MSG_ERROR,
6473 "%s: err in adding vendor_cmd and vendor_data",
6474 __func__);
6475 nlmsg_free(msg);
6476 return -1;
6477 }
6478 nla_nest_end(msg, params);
6479
6480 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6481 if (ret) {
6482 sigma_dut_print(dut, DUT_MSG_ERROR,
6483 "%s: err in send_and_recv_msgs, ret=%d",
6484 __func__, ret);
6485 }
6486 return ret;
6487}
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08006488
6489
6490static int sta_set_2g_vht_supp(struct sigma_dut *dut, const char *intf, int cfg)
6491{
6492 struct nl_msg *msg;
6493 int ret = 0;
6494 struct nlattr *params;
6495 int ifindex;
6496
6497 ifindex = if_nametoindex(intf);
6498 if (ifindex == 0) {
6499 sigma_dut_print(dut, DUT_MSG_ERROR,
6500 "%s: Index for interface %s failed",
6501 __func__, intf);
6502 return -1;
6503 }
6504
6505 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6506 NL80211_CMD_VENDOR)) ||
6507 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6508 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6509 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6510 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6511 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6512 nla_put_u8(msg,
6513 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_2G_VHT,
6514 cfg)) {
6515 sigma_dut_print(dut, DUT_MSG_ERROR,
6516 "%s: err in adding vendor_cmd and vendor_data",
6517 __func__);
6518 nlmsg_free(msg);
6519 return -1;
6520 }
6521 nla_nest_end(msg, params);
6522
6523 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6524 if (ret) {
6525 sigma_dut_print(dut, DUT_MSG_ERROR,
6526 "%s: err in send_and_recv_msgs, ret=%d",
6527 __func__, ret);
6528 }
6529 return ret;
6530}
6531
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08006532#endif /* NL80211_SUPPORT */
6533
6534
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08006535static int sta_set_addba_buf_size(struct sigma_dut *dut,
6536 const char *intf, int bufsize)
6537{
6538#ifdef NL80211_SUPPORT
6539 struct nl_msg *msg;
6540 int ret = 0;
6541 struct nlattr *params;
6542 int ifindex;
6543
6544 ifindex = if_nametoindex(intf);
6545 if (ifindex == 0) {
6546 sigma_dut_print(dut, DUT_MSG_ERROR,
6547 "%s: Index for interface %s failed",
6548 __func__, intf);
6549 return -1;
6550 }
6551
6552 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6553 NL80211_CMD_VENDOR)) ||
6554 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6555 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6556 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6557 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6558 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
Kiran Kumar Lokere26e27582018-08-01 16:18:34 -07006559 nla_put_u16(msg,
6560 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE,
6561 bufsize)) {
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08006562 sigma_dut_print(dut, DUT_MSG_ERROR,
6563 "%s: err in adding vendor_cmd and vendor_data",
6564 __func__);
6565 nlmsg_free(msg);
6566 return -1;
6567 }
6568 nla_nest_end(msg, params);
6569
6570 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6571 if (ret) {
6572 sigma_dut_print(dut, DUT_MSG_ERROR,
6573 "%s: err in send_and_recv_msgs, ret=%d",
6574 __func__, ret);
6575 }
6576 return ret;
6577#else /* NL80211_SUPPORT */
6578 sigma_dut_print(dut, DUT_MSG_ERROR,
6579 "AddBA bufsize cannot be changed without NL80211_SUPPORT defined");
6580 return -1;
6581#endif /* NL80211_SUPPORT */
6582}
6583
6584
Arif Hussain8d5b27b2018-05-14 14:31:03 -07006585static int sta_set_tx_beamformee(struct sigma_dut *dut, const char *intf,
6586 int enable)
6587{
6588#ifdef NL80211_SUPPORT
6589 struct nl_msg *msg;
6590 int ret = 0;
6591 struct nlattr *params;
6592 int ifindex;
6593
6594 ifindex = if_nametoindex(intf);
6595 if (ifindex == 0) {
6596 sigma_dut_print(dut, DUT_MSG_ERROR,
6597 "%s: Index for interface %s failed",
6598 __func__, intf);
6599 return -1;
6600 }
6601
6602 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6603 NL80211_CMD_VENDOR)) ||
6604 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6605 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6606 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6607 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6608 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6609 nla_put_u8(msg,
6610 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_TX_BEAMFORMEE,
6611 enable)) {
6612 sigma_dut_print(dut, DUT_MSG_ERROR,
6613 "%s: err in adding vendor_cmd and vendor_data",
6614 __func__);
6615 nlmsg_free(msg);
6616 return -1;
6617 }
6618 nla_nest_end(msg, params);
6619
6620 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6621 if (ret) {
6622 sigma_dut_print(dut, DUT_MSG_ERROR,
6623 "%s: err in send_and_recv_msgs, ret=%d",
6624 __func__, ret);
6625 }
6626 return ret;
6627#else /* NL80211_SUPPORT */
6628 sigma_dut_print(dut, DUT_MSG_ERROR,
6629 "tx beamformee cannot be changed without NL80211_SUPPORT defined");
6630 return -1;
6631#endif /* NL80211_SUPPORT */
6632}
6633
6634
Arif Hussain9765f7d2018-07-03 08:28:26 -07006635static int sta_set_beamformee_sts(struct sigma_dut *dut, const char *intf,
6636 int val)
6637{
6638#ifdef NL80211_SUPPORT
6639 struct nl_msg *msg;
6640 int ret = 0;
6641 struct nlattr *params;
6642 int ifindex;
6643
6644 ifindex = if_nametoindex(intf);
6645 if (ifindex == 0) {
6646 sigma_dut_print(dut, DUT_MSG_ERROR,
6647 "%s: Index for interface %s failed, val:%d",
6648 __func__, intf, val);
6649 return -1;
6650 }
6651
6652 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6653 NL80211_CMD_VENDOR)) ||
6654 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6655 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6656 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6657 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6658 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6659 nla_put_u8(msg,
6660 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_BEAMFORMEE_NSTS,
6661 val)) {
6662 sigma_dut_print(dut, DUT_MSG_ERROR,
6663 "%s: err in adding vendor_cmd and vendor_data, val: %d",
6664 __func__, val);
6665 nlmsg_free(msg);
6666 return -1;
6667 }
6668 nla_nest_end(msg, params);
6669
6670 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6671 if (ret) {
6672 sigma_dut_print(dut, DUT_MSG_ERROR,
6673 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
6674 __func__, ret, val);
6675 }
6676 return ret;
6677#else /* NL80211_SUPPORT */
6678 sigma_dut_print(dut, DUT_MSG_ERROR,
6679 "beamformee sts cannot be changed without NL80211_SUPPORT defined");
6680 return -1;
6681#endif /* NL80211_SUPPORT */
6682}
6683
6684
Arif Hussain68d23f52018-07-11 13:39:08 -07006685#ifdef NL80211_SUPPORT
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07006686static int sta_set_mac_padding_duration(struct sigma_dut *dut, const char *intf,
6687 enum qca_wlan_he_mac_padding_dur val)
6688{
Arif Hussain68d23f52018-07-11 13:39:08 -07006689 struct nl_msg *msg;
6690 int ret = 0;
6691 struct nlattr *params;
6692 int ifindex;
6693
6694 ifindex = if_nametoindex(intf);
6695 if (ifindex == 0) {
6696 sigma_dut_print(dut, DUT_MSG_ERROR,
6697 "%s: Index for interface %s failed, val:%d",
6698 __func__, intf, val);
6699 return -1;
6700 }
6701
6702 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6703 NL80211_CMD_VENDOR)) ||
6704 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6705 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6706 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6707 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6708 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6709 nla_put_u8(msg,
6710 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MAC_PADDING_DUR,
6711 val)) {
6712 sigma_dut_print(dut, DUT_MSG_ERROR,
6713 "%s: err in adding vendor_cmd and vendor_data, val: %d",
6714 __func__, val);
6715 nlmsg_free(msg);
6716 return -1;
6717 }
6718 nla_nest_end(msg, params);
6719
6720 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6721 if (ret) {
6722 sigma_dut_print(dut, DUT_MSG_ERROR,
6723 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
6724 __func__, ret, val);
6725 }
6726 return ret;
Arif Hussain68d23f52018-07-11 13:39:08 -07006727}
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07006728#endif /* NL80211_SUPPORT */
Arif Hussain68d23f52018-07-11 13:39:08 -07006729
6730
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07006731static int sta_set_tx_su_ppdu_cfg(struct sigma_dut *dut, const char *intf,
6732 int val)
6733{
6734#ifdef NL80211_SUPPORT
6735 struct nl_msg *msg;
6736 int ret = 0;
6737 struct nlattr *params;
6738 int ifindex;
6739
6740 ifindex = if_nametoindex(intf);
6741 if (ifindex == 0) {
6742 sigma_dut_print(dut, DUT_MSG_ERROR,
6743 "%s: Index for interface %s failed, val:%d",
6744 __func__, intf, val);
6745 return -1;
6746 }
6747
6748 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6749 NL80211_CMD_VENDOR)) ||
6750 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6751 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6752 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6753 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6754 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6755 nla_put_u8(msg,
6756 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_SUPPDU,
6757 val)) {
6758 sigma_dut_print(dut, DUT_MSG_ERROR,
6759 "%s: err in adding vendor_cmd and vendor_data, val: %d",
6760 __func__, val);
6761 nlmsg_free(msg);
6762 return -1;
6763 }
6764 nla_nest_end(msg, params);
6765
6766 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6767 if (ret) {
6768 sigma_dut_print(dut, DUT_MSG_ERROR,
6769 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
6770 __func__, ret, val);
6771 }
6772 return ret;
6773#else /* NL80211_SUPPORT */
6774 sigma_dut_print(dut, DUT_MSG_ERROR,
6775 "Tx SU PPDU cannot be set without NL80211_SUPPORT defined");
6776 return -1;
6777#endif /* NL80211_SUPPORT */
6778}
6779
6780
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07006781#ifdef NL80211_SUPPORT
6782static int sta_set_he_om_ctrl_reset(struct sigma_dut *dut, const char *intf)
6783{
6784 struct nl_msg *msg;
6785 int ret = 0;
6786 struct nlattr *params;
6787 int ifindex;
6788
6789 ifindex = if_nametoindex(intf);
6790 if (ifindex == 0) {
6791 sigma_dut_print(dut, DUT_MSG_ERROR,
6792 "%s: Index for interface %s failed",
6793 __func__, intf);
6794 return -1;
6795 }
6796
6797 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6798 NL80211_CMD_VENDOR)) ||
6799 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6800 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6801 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6802 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6803 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6804 nla_put_flag(msg,
6805 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_CLEAR_HE_OM_CTRL_CONFIG)) {
6806 sigma_dut_print(dut, DUT_MSG_ERROR,
6807 "%s: err in adding vendor_cmd and vendor_data",
6808 __func__);
6809 nlmsg_free(msg);
6810 return -1;
6811 }
6812 nla_nest_end(msg, params);
6813
6814 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6815 if (ret) {
6816 sigma_dut_print(dut, DUT_MSG_ERROR,
6817 "%s: err in send_and_recv_msgs, ret=%d",
6818 __func__, ret);
6819 }
6820 return ret;
6821}
6822#endif /* NL80211_SUPPORT */
6823
6824
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07006825static int sta_set_mu_edca_override(struct sigma_dut *dut, const char *intf,
6826 int val)
6827{
6828#ifdef NL80211_SUPPORT
6829 struct nl_msg *msg;
6830 int ret = 0;
6831 struct nlattr *params;
6832 int ifindex;
6833
6834 ifindex = if_nametoindex(intf);
6835 if (ifindex == 0) {
6836 sigma_dut_print(dut, DUT_MSG_ERROR,
6837 "%s: Index for interface %s failed, val:%d",
6838 __func__, intf, val);
6839 return -1;
6840 }
6841
6842 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6843 NL80211_CMD_VENDOR)) ||
6844 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6845 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6846 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6847 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6848 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6849 nla_put_u8(msg,
6850 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_OVERRIDE_MU_EDCA,
6851 val)) {
6852 sigma_dut_print(dut, DUT_MSG_ERROR,
6853 "%s: err in adding vendor_cmd and vendor_data, val: %d",
6854 __func__, val);
6855 nlmsg_free(msg);
6856 return -1;
6857 }
6858 nla_nest_end(msg, params);
6859
6860 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6861 if (ret) {
6862 sigma_dut_print(dut, DUT_MSG_ERROR,
6863 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
6864 __func__, ret, val);
6865 }
6866 return ret;
6867#else /* NL80211_SUPPORT */
6868 sigma_dut_print(dut, DUT_MSG_ERROR,
6869 "MU EDCA override cannot be changed without NL80211_SUPPORT defined");
6870 return -1;
6871#endif /* NL80211_SUPPORT */
6872}
6873
6874
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07006875static int sta_set_om_ctrl_supp(struct sigma_dut *dut, const char *intf,
6876 int val)
6877{
6878#ifdef NL80211_SUPPORT
6879 struct nl_msg *msg;
6880 int ret = 0;
6881 struct nlattr *params;
6882 int ifindex;
6883
6884 ifindex = if_nametoindex(intf);
6885 if (ifindex == 0) {
6886 sigma_dut_print(dut, DUT_MSG_ERROR,
6887 "%s: Index for interface %s failed, val:%d",
6888 __func__, intf, val);
6889 return -1;
6890 }
6891
6892 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6893 NL80211_CMD_VENDOR)) ||
6894 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6895 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6896 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6897 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6898 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6899 nla_put_u8(msg,
6900 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OM_CTRL_SUPP,
6901 val)) {
6902 sigma_dut_print(dut, DUT_MSG_ERROR,
6903 "%s: err in adding vendor_cmd and vendor_data, val: %d",
6904 __func__, val);
6905 nlmsg_free(msg);
6906 return -1;
6907 }
6908 nla_nest_end(msg, params);
6909
6910 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6911 if (ret) {
6912 sigma_dut_print(dut, DUT_MSG_ERROR,
6913 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
6914 __func__, ret, val);
6915 }
6916 return ret;
6917#else /* NL80211_SUPPORT */
6918 sigma_dut_print(dut, DUT_MSG_ERROR,
6919 "HE OM ctrl cannot be changed without NL80211_SUPPORT defined");
6920 return -1;
6921#endif /* NL80211_SUPPORT */
6922}
6923
6924
Arif Hussain480d5f42019-03-12 14:40:42 -07006925static int sta_set_twt_req_support(struct sigma_dut *dut, const char *intf,
6926 int val)
6927{
6928#ifdef NL80211_SUPPORT
6929 struct nl_msg *msg;
6930 int ret;
6931 struct nlattr *params;
6932 int ifindex;
6933
6934 ifindex = if_nametoindex(intf);
6935 if (ifindex == 0) {
6936 sigma_dut_print(dut, DUT_MSG_ERROR,
6937 "%s: Index for interface %s failed, val:%d",
6938 __func__, intf, val);
6939 return -1;
6940 }
6941
6942 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6943 NL80211_CMD_VENDOR)) ||
6944 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6945 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6946 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6947 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6948 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6949 nla_put_u8(msg,
6950 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TWT_REQ_SUPPORT,
6951 val)) {
6952 sigma_dut_print(dut, DUT_MSG_ERROR,
6953 "%s: err in adding vendor_cmd and vendor_data, val: %d",
6954 __func__, val);
6955 nlmsg_free(msg);
6956 return -1;
6957 }
6958 nla_nest_end(msg, params);
6959
6960 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6961 if (ret) {
6962 sigma_dut_print(dut, DUT_MSG_ERROR,
6963 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
6964 __func__, ret, val);
6965 }
6966 return ret;
6967#else /* NL80211_SUPPORT */
6968 sigma_dut_print(dut, DUT_MSG_ERROR,
6969 "TWT Request cannot be changed without NL80211_SUPPORT defined");
6970 return -1;
6971#endif /* NL80211_SUPPORT */
6972}
6973
6974
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08006975static void sta_reset_default_wcn(struct sigma_dut *dut, const char *intf,
6976 const char *type)
6977{
6978 char buf[60];
6979
6980 if (dut->program == PROGRAM_HE) {
6981 /* resetting phymode to auto in case of HE program */
6982 snprintf(buf, sizeof(buf), "iwpriv %s setphymode 0", intf);
6983 if (system(buf) != 0) {
6984 sigma_dut_print(dut, DUT_MSG_ERROR,
6985 "iwpriv %s setphymode failed", intf);
6986 }
6987
Amarnath Hullur Subramanyam9cecb502018-04-25 13:26:30 -07006988 /* reset the rate to Auto rate */
6989 snprintf(buf, sizeof(buf), "iwpriv %s set_11ax_rate 0xff",
6990 intf);
6991 if (system(buf) != 0) {
6992 sigma_dut_print(dut, DUT_MSG_ERROR,
6993 "iwpriv %s set_11ax_rate 0xff failed",
6994 intf);
6995 }
6996
Kiran Kumar Lokere86cfe3a2018-06-01 11:55:15 -07006997 /* reset the LDPC setting */
6998 snprintf(buf, sizeof(buf), "iwpriv %s ldpc 1", intf);
6999 if (system(buf) != 0) {
7000 sigma_dut_print(dut, DUT_MSG_ERROR,
7001 "iwpriv %s ldpc 1 failed", intf);
7002 }
7003
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08007004 /* reset the power save setting */
7005 snprintf(buf, sizeof(buf), "iwpriv %s setPower 2", intf);
7006 if (system(buf) != 0) {
7007 sigma_dut_print(dut, DUT_MSG_ERROR,
7008 "iwpriv %s setPower 2 failed", intf);
7009 }
7010
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08007011 /* remove all network profiles */
7012 remove_wpa_networks(intf);
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08007013
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08007014 /* Configure ADDBA Req/Rsp buffer size to be 64 */
7015 sta_set_addba_buf_size(dut, intf, 64);
7016
Amarnath Hullur Subramanyam5f32d572018-03-02 00:02:33 -08007017#ifdef NL80211_SUPPORT
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08007018 /* Reset the device HE capabilities to its default supported
7019 * configuration. */
7020 sta_set_he_testbed_def(dut, intf, 0);
7021
Amarnath Hullur Subramanyam5f32d572018-03-02 00:02:33 -08007022 /* Disable noackpolicy for all AC */
7023 if (nlvendor_sta_set_noack(dut, intf, 0, QCA_WLAN_AC_ALL)) {
7024 sigma_dut_print(dut, DUT_MSG_ERROR,
7025 "Disable of noackpolicy for all AC failed");
7026 }
7027#endif /* NL80211_SUPPORT */
7028
Amarnath Hullur Subramanyamb1724a52018-03-07 14:31:46 -08007029 /* Enable WMM by default */
7030 if (wcn_sta_set_wmm(dut, intf, "on")) {
7031 sigma_dut_print(dut, DUT_MSG_ERROR,
7032 "Enable of WMM in sta_reset_default_wcn failed");
7033 }
7034
7035 /* Disable ADDBA_REJECT by default */
7036 if (nlvendor_sta_set_addba_reject(dut, intf, 0)) {
7037 sigma_dut_print(dut, DUT_MSG_ERROR,
7038 "Disable of addba_reject in sta_reset_default_wcn failed");
7039 }
7040
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08007041 /* Enable sending of ADDBA by default */
7042 if (nlvendor_config_send_addba(dut, intf, 1)) {
7043 sigma_dut_print(dut, DUT_MSG_ERROR,
7044 "Enable sending of ADDBA in sta_reset_default_wcn failed");
7045 }
7046
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08007047 /* Enable AMPDU by default */
7048 iwpriv_sta_set_ampdu(dut, intf, 1);
7049
Subhani Shaik8e7a3052018-04-24 14:03:00 -07007050#ifdef NL80211_SUPPORT
7051 if (sta_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_AUTO)) {
7052 sigma_dut_print(dut, DUT_MSG_ERROR,
7053 "Set LTF config to default in sta_reset_default_wcn failed");
7054 }
Arif Hussain9765f7d2018-07-03 08:28:26 -07007055
Kiran Kumar Lokerebad51122018-12-12 19:03:36 -08007056 /* set the beamformee NSTS(maximum number of
7057 * space-time streams) to default DUT config
7058 */
7059 if (sta_set_beamformee_sts(dut, intf, 7)) {
Arif Hussain9765f7d2018-07-03 08:28:26 -07007060 sigma_dut_print(dut, DUT_MSG_ERROR,
7061 "Failed to set BeamformeeSTS");
7062 }
Arif Hussain68d23f52018-07-11 13:39:08 -07007063
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07007064 if (sta_set_mac_padding_duration(
7065 dut, intf,
7066 QCA_WLAN_HE_NO_ADDITIONAL_PROCESS_TIME)) {
Arif Hussain68d23f52018-07-11 13:39:08 -07007067 sigma_dut_print(dut, DUT_MSG_ERROR,
7068 "Failed to set MAC padding duration");
7069 }
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07007070
7071 if (sta_set_mu_edca_override(dut, intf, 0)) {
7072 sigma_dut_print(dut, DUT_MSG_ERROR,
7073 "ErrorCode,Failed to set MU EDCA override disable");
7074 }
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07007075
7076 if (sta_set_om_ctrl_supp(dut, intf, 1)) {
7077 sigma_dut_print(dut, DUT_MSG_ERROR,
7078 "Failed to set OM ctrl supp");
7079 }
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07007080
7081 if (sta_set_tx_su_ppdu_cfg(dut, intf, 1)) {
7082 sigma_dut_print(dut, DUT_MSG_ERROR,
7083 "Failed to set Tx SU PPDU enable");
7084 }
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07007085
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07007086 if (sta_set_action_tx_in_he_tb_ppdu(dut, intf, 0)) {
7087 sigma_dut_print(dut, DUT_MSG_ERROR,
7088 "failed to send TB PPDU Tx cfg");
7089 }
7090
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07007091 if (sta_set_he_om_ctrl_reset(dut, intf)) {
7092 sigma_dut_print(dut, DUT_MSG_ERROR,
7093 "Failed to set OM ctrl reset");
7094 }
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08007095
7096 /* +HTC-HE support default on */
7097 if (sta_set_he_htc_supp(dut, intf, 1)) {
7098 sigma_dut_print(dut, DUT_MSG_ERROR,
7099 "Setting of +HTC-HE support failed");
7100 }
Subhani Shaik8e7a3052018-04-24 14:03:00 -07007101#endif /* NL80211_SUPPORT */
7102
Arif Hussain8d5b27b2018-05-14 14:31:03 -07007103 if (sta_set_tx_beamformee(dut, intf, 1)) {
7104 sigma_dut_print(dut, DUT_MSG_ERROR,
7105 "Set tx beamformee enable by default in sta_reset_default_wcn failed");
7106 }
7107
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08007108 /* Set nss to 1 and MCS 0-7 in case of testbed */
7109 if (type && strcasecmp(type, "Testbed") == 0) {
7110#ifdef NL80211_SUPPORT
7111 int ret;
7112#endif /* NL80211_SUPPORT */
7113
7114 snprintf(buf, sizeof(buf), "iwpriv %s nss 1", intf);
7115 if (system(buf) != 0) {
7116 sigma_dut_print(dut, DUT_MSG_ERROR,
7117 "iwpriv %s nss failed", intf);
7118 }
7119
7120#ifdef NL80211_SUPPORT
7121 ret = sta_set_he_mcs(dut, intf, HE_80_MCS0_7);
7122 if (ret) {
7123 sigma_dut_print(dut, DUT_MSG_ERROR,
7124 "Setting of MCS failed, ret:%d",
7125 ret);
7126 }
7127#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyamc67621d2018-02-04 23:18:01 -08007128
7129 /* Disable STBC as default */
7130 wcn_sta_set_stbc(dut, intf, "0");
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08007131
7132 /* Disable AMSDU as default */
7133 iwpriv_sta_set_amsdu(dut, intf, "0");
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08007134
7135#ifdef NL80211_SUPPORT
7136 /* HE fragmentation default off */
7137 if (sta_set_he_fragmentation(dut, intf,
7138 HE_FRAG_DISABLE)) {
7139 sigma_dut_print(dut, DUT_MSG_ERROR,
7140 "Setting of HE fragmentation failed");
7141 }
Kiran Kumar Lokerebad51122018-12-12 19:03:36 -08007142
7143 /* set the beamformee NSTS(maximum number of
7144 * space-time streams) to default testbed config
7145 */
7146 if (sta_set_beamformee_sts(dut, intf, 3)) {
7147 sigma_dut_print(dut, DUT_MSG_ERROR,
7148 "Failed to set BeamformeeSTS");
7149 }
7150
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08007151 /* +HTC-HE support default off */
7152 if (sta_set_he_htc_supp(dut, intf, 0)) {
7153 sigma_dut_print(dut, DUT_MSG_ERROR,
7154 "Setting of +HTC-HE support failed");
7155 }
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08007156
7157 /* Set device HE capabilities to testbed default
7158 * configuration. */
7159 if (sta_set_he_testbed_def(dut, intf, 1)) {
7160 sigma_dut_print(dut, DUT_MSG_DEBUG,
7161 "Failed to set HE defaults");
7162 }
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08007163
7164 /* Disable VHT support in 2.4 GHz for testbed */
7165 sta_set_2g_vht_supp(dut, intf, 0);
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08007166#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08007167
7168 /* Enable WEP/TKIP with HE capability in testbed */
7169 if (sta_set_heconfig_and_wep_tkip(dut, intf, 1)) {
7170 sigma_dut_print(dut, DUT_MSG_ERROR,
7171 "Enabling HE config with WEP/TKIP failed");
7172 }
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08007173 }
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08007174
7175 /* Defaults in case of DUT */
7176 if (type && strcasecmp(type, "DUT") == 0) {
Arif Hussaind48fcc72018-05-01 18:34:18 -07007177 /* Enable STBC by default */
7178 wcn_sta_set_stbc(dut, intf, "1");
7179
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08007180 /* set nss to 2 */
7181 snprintf(buf, sizeof(buf), "iwpriv %s nss 2", intf);
7182 if (system(buf) != 0) {
7183 sigma_dut_print(dut, DUT_MSG_ERROR,
7184 "iwpriv %s nss 2 failed", intf);
7185 }
Arif Hussainac6c5112018-05-25 17:34:00 -07007186 dut->sta_nss = 2;
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08007187
7188#ifdef NL80211_SUPPORT
Arif Hussainae239842018-05-01 18:20:05 -07007189 /* Set HE_MCS to 0-11 */
7190 if (sta_set_he_mcs(dut, intf, HE_80_MCS0_11)) {
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08007191 sigma_dut_print(dut, DUT_MSG_ERROR,
7192 "Setting of MCS failed");
7193 }
7194#endif /* NL80211_SUPPORT */
7195
7196 /* Disable WEP/TKIP with HE capability in DUT */
7197 if (sta_set_heconfig_and_wep_tkip(dut, intf, 0)) {
7198 sigma_dut_print(dut, DUT_MSG_ERROR,
7199 "Enabling HE config with WEP/TKIP failed");
7200 }
7201 }
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08007202 }
7203}
7204
7205
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007206static int cmd_sta_reset_default(struct sigma_dut *dut,
7207 struct sigma_conn *conn,
7208 struct sigma_cmd *cmd)
7209{
7210 int cmd_sta_p2p_reset(struct sigma_dut *dut, struct sigma_conn *conn,
7211 struct sigma_cmd *cmd);
7212 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007213 const char *band = get_param(cmd, "band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007214 const char *type;
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07007215 const char *program = get_param(cmd, "program");
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05307216 const char *dev_role = get_param(cmd, "DevRole");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007217
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07007218 if (!program)
7219 program = get_param(cmd, "prog");
7220 dut->program = sigma_program_to_enum(program);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007221 dut->device_type = STA_unknown;
7222 type = get_param(cmd, "type");
7223 if (type && strcasecmp(type, "Testbed") == 0)
7224 dut->device_type = STA_testbed;
7225 if (type && strcasecmp(type, "DUT") == 0)
7226 dut->device_type = STA_dut;
7227
7228 if (dut->program == PROGRAM_TDLS) {
7229 /* Clear TDLS testing mode */
7230 wpa_command(intf, "SET tdls_disabled 0");
7231 wpa_command(intf, "SET tdls_testing 0");
7232 dut->no_tpk_expiration = 0;
Pradeep Reddy POTTETI8ce2a232016-10-28 12:17:32 +05307233 if (get_driver_type() == DRIVER_WCN) {
7234 /* Enable the WCN driver in TDLS Explicit trigger mode
7235 */
7236 wpa_command(intf, "SET tdls_external_control 0");
7237 wpa_command(intf, "SET tdls_trigger_control 0");
7238 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007239 }
7240
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07007241#ifdef MIRACAST
7242 if (dut->program == PROGRAM_WFD ||
7243 dut->program == PROGRAM_DISPLAYR2)
7244 miracast_sta_reset_default(dut, conn, cmd);
7245#endif /* MIRACAST */
7246
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007247 switch (get_driver_type()) {
7248 case DRIVER_ATHEROS:
7249 sta_reset_default_ath(dut, intf, type);
7250 break;
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08007251 case DRIVER_WCN:
7252 sta_reset_default_wcn(dut, intf, type);
7253 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007254 default:
7255 break;
7256 }
7257
7258#ifdef ANDROID_NAN
7259 if (dut->program == PROGRAM_NAN)
7260 nan_cmd_sta_reset_default(dut, conn, cmd);
7261#endif /* ANDROID_NAN */
7262
Jouni Malinenba630452018-06-22 11:49:59 +03007263 if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007264 unlink("SP/wi-fi.org/pps.xml");
7265 if (system("rm -r SP/*") != 0) {
7266 }
7267 unlink("next-client-cert.pem");
7268 unlink("next-client-key.pem");
7269 }
7270
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007271 /* For WPS program of the 60 GHz band the band type needs to be saved */
7272 if (dut->program == PROGRAM_WPS) {
7273 if (band && strcasecmp(band, "60GHz") == 0) {
7274 dut->band = WPS_BAND_60G;
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02007275 /* For 60 GHz enable WPS for WPS TCs */
7276 dut->wps_disable = 0;
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007277 } else {
7278 dut->band = WPS_BAND_NON_60G;
7279 }
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02007280 } else if (dut->program == PROGRAM_60GHZ) {
7281 /* For 60 GHz MAC/PHY TCs WPS must be disabled */
7282 dut->wps_disable = 1;
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007283 }
7284
Alexei Avshalom Lazar157ba062018-12-23 16:15:26 +02007285 if (is_60g_sigma_dut(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007286 const char *dev_role = get_param(cmd, "DevRole");
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02007287 char buf[256];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007288
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02007289 sigma_dut_print(dut, DUT_MSG_INFO,
7290 "WPS 60 GHz program, wps_disable = %d",
7291 dut->wps_disable);
7292
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007293 if (!dev_role) {
7294 send_resp(dut, conn, SIGMA_ERROR,
7295 "errorCode,Missing DevRole argument");
7296 return 0;
7297 }
7298
7299 if (strcasecmp(dev_role, "STA") == 0)
7300 dut->dev_role = DEVROLE_STA;
7301 else if (strcasecmp(dev_role, "PCP") == 0)
7302 dut->dev_role = DEVROLE_PCP;
7303 else {
7304 send_resp(dut, conn, SIGMA_ERROR,
7305 "errorCode,Unknown DevRole");
7306 return 0;
7307 }
7308
7309 if (dut->device_type == STA_unknown) {
7310 sigma_dut_print(dut, DUT_MSG_ERROR,
7311 "Device type is not STA testbed or DUT");
7312 send_resp(dut, conn, SIGMA_ERROR,
7313 "errorCode,Unknown device type");
7314 return 0;
7315 }
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02007316
7317 sigma_dut_print(dut, DUT_MSG_DEBUG,
7318 "Setting msdu_size to MAX: 7912");
7319 snprintf(buf, sizeof(buf), "ifconfig %s mtu 7912",
7320 get_station_ifname());
7321
7322 if (system(buf) != 0) {
7323 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
7324 buf);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007325 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02007326 }
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02007327
7328 if (sta_set_force_mcs(dut, 0, 1)) {
7329 sigma_dut_print(dut, DUT_MSG_ERROR,
7330 "Failed to reset force MCS");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007331 return ERROR_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02007332 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007333 }
7334
7335 wpa_command(intf, "WPS_ER_STOP");
7336 wpa_command(intf, "FLUSH");
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05307337 wpa_command(intf, "ERP_FLUSH");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007338 wpa_command(intf, "SET radio_disabled 0");
7339
Alexei Avshalom Lazar744ae8a2019-01-31 17:26:46 +02007340 dut->wps_forced_version = 0;
7341
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007342 if (dut->wsc_fragment) {
7343 dut->wsc_fragment = 0;
7344 wpa_command(intf, "SET device_name Test client");
7345 wpa_command(intf, "SET manufacturer ");
7346 wpa_command(intf, "SET model_name ");
7347 wpa_command(intf, "SET model_number ");
7348 wpa_command(intf, "SET serial_number ");
7349 }
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02007350 if (is_60g_sigma_dut(dut) && dut->force_rsn_ie) {
7351 dut->force_rsn_ie = FORCE_RSN_IE_NONE;
7352 sta_60g_force_rsn_ie(dut, FORCE_RSN_IE_NONE);
7353 }
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007354
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007355 if (dut->tmp_mac_addr && dut->set_macaddr) {
7356 dut->tmp_mac_addr = 0;
7357 if (system(dut->set_macaddr) != 0) {
7358 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to clear "
7359 "temporary MAC address");
7360 }
7361 }
7362
7363 set_ps(intf, dut, 0);
7364
Jouni Malinenba630452018-06-22 11:49:59 +03007365 if (dut->program == PROGRAM_HS2 || dut->program == PROGRAM_HS2_R2 ||
7366 dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007367 wpa_command(intf, "SET interworking 1");
7368 wpa_command(intf, "SET hs20 1");
7369 }
7370
Deepak Dhamdhere0fe0e452017-12-18 14:52:09 -08007371 if (dut->program == PROGRAM_HS2_R2 ||
Jouni Malinenba630452018-06-22 11:49:59 +03007372 dut->program == PROGRAM_HS2_R3 ||
Deepak Dhamdhere0fe0e452017-12-18 14:52:09 -08007373 dut->program == PROGRAM_OCE) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007374 wpa_command(intf, "SET pmf 1");
7375 } else {
7376 wpa_command(intf, "SET pmf 0");
7377 }
7378
7379 hs2_clear_credentials(intf);
7380 wpa_command(intf, "SET hessid 00:00:00:00:00:00");
7381 wpa_command(intf, "SET access_network_type 15");
7382
7383 static_ip_file(0, NULL, NULL, NULL);
7384 kill_dhcp_client(dut, intf);
7385 clear_ip_addr(dut, intf);
7386
7387 dut->er_oper_performed = 0;
7388 dut->er_oper_bssid[0] = '\0';
7389
priyadharshini gowthamanad6cbba2016-10-04 10:39:58 -07007390 if (dut->program == PROGRAM_LOC) {
7391 /* Disable Interworking by default */
7392 wpa_command(get_station_ifname(), "SET interworking 0");
7393 }
7394
Ashwini Patil00402582017-04-13 12:29:39 +05307395 if (dut->program == PROGRAM_MBO) {
7396 free(dut->non_pref_ch_list);
7397 dut->non_pref_ch_list = NULL;
Ashwini Patil5acd7382017-04-13 15:55:04 +05307398 free(dut->btm_query_cand_list);
7399 dut->btm_query_cand_list = NULL;
Ashwini Patilc63161e2017-04-13 16:30:23 +05307400 wpa_command(intf, "SET reject_btm_req_reason 0");
Ashwini Patila75de5a2017-04-13 16:35:05 +05307401 wpa_command(intf, "SET ignore_assoc_disallow 0");
Ashwini Patild174f2c2017-04-13 16:49:46 +05307402 wpa_command(intf, "SET gas_address3 0");
Ashwini Patil9183fdb2017-04-13 16:58:25 +05307403 wpa_command(intf, "SET roaming 1");
Ankita Bajaj1d974552018-09-18 16:56:44 +05307404 wpa_command(intf, "SET interworking 1");
Ashwini Patil00402582017-04-13 12:29:39 +05307405 }
7406
Jouni Malinen3c367e82017-06-23 17:01:47 +03007407 free(dut->rsne_override);
7408 dut->rsne_override = NULL;
7409
Jouni Malinen68143132017-09-02 02:34:08 +03007410 free(dut->sae_commit_override);
7411 dut->sae_commit_override = NULL;
7412
Jouni Malinend86e5822017-08-29 03:55:32 +03007413 dut->dpp_conf_id = -1;
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02007414 free(dut->dpp_peer_uri);
7415 dut->dpp_peer_uri = NULL;
Jouni Malinen63d50412017-11-24 11:55:38 +02007416 dut->dpp_local_bootstrap = -1;
Jouni Malinen5011fb52017-12-05 21:00:15 +02007417 wpa_command(intf, "SET dpp_config_processing 2");
Jouni Malinend86e5822017-08-29 03:55:32 +03007418
Jouni Malinenfac9cad2017-10-10 18:35:55 +03007419 wpa_command(intf, "VENDOR_ELEM_REMOVE 13 *");
7420
vamsi krishnaa2799492017-12-05 14:28:01 +05307421 if (dut->program == PROGRAM_OCE) {
Ankita Bajaja2cb5672017-10-25 16:08:28 +05307422 wpa_command(intf, "SET oce 1");
vamsi krishnaa2799492017-12-05 14:28:01 +05307423 wpa_command(intf, "SET disable_fils 0");
Ankita Bajaj1bde7942018-01-09 19:15:01 +05307424 wpa_command(intf, "FILS_HLP_REQ_FLUSH");
7425 dut->fils_hlp = 0;
7426#ifdef ANDROID
7427 hlp_thread_cleanup(dut);
7428#endif /* ANDROID */
vamsi krishnaa2799492017-12-05 14:28:01 +05307429 }
Ankita Bajaja2cb5672017-10-25 16:08:28 +05307430
Jouni Malinen8179fee2019-03-28 03:19:47 +02007431 dut->akm_values = 0;
7432
Sunil Dutt076081f2018-02-05 19:45:50 +05307433#ifdef NL80211_SUPPORT
Sunil Dutt44595082018-02-12 19:41:45 +05307434 if (get_driver_type() == DRIVER_WCN &&
7435 dut->config_rsnie == 1) {
7436 dut->config_rsnie = 0;
7437 sta_config_rsnie(dut, 0);
Sunil Dutt076081f2018-02-05 19:45:50 +05307438 }
7439#endif /* NL80211_SUPPORT */
7440
Sunil Duttfebf8a82018-02-09 18:50:13 +05307441 if (dev_role && strcasecmp(dev_role, "STA-CFON") == 0) {
7442 dut->dev_role = DEVROLE_STA_CFON;
7443 return sta_cfon_reset_default(dut, conn, cmd);
7444 }
7445
Jouni Malinen439352d2018-09-13 03:42:23 +03007446 wpa_command(intf, "SET setband AUTO");
7447
Sunil Duttfebf8a82018-02-09 18:50:13 +05307448 if (dut->program != PROGRAM_VHT)
7449 return cmd_sta_p2p_reset(dut, conn, cmd);
7450
Priyadharshini Gowthamana7dfd492015-11-09 14:34:08 -08007451 return 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007452}
7453
7454
7455static int cmd_sta_get_events(struct sigma_dut *dut, struct sigma_conn *conn,
7456 struct sigma_cmd *cmd)
7457{
7458 const char *program = get_param(cmd, "Program");
7459
7460 if (program == NULL)
7461 return -1;
7462#ifdef ANDROID_NAN
7463 if (strcasecmp(program, "NAN") == 0)
7464 return nan_cmd_sta_get_events(dut, conn, cmd);
7465#endif /* ANDROID_NAN */
7466 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
7467 return 0;
7468}
7469
7470
Jouni Malinen82905202018-04-29 17:20:10 +03007471static int sta_exec_action_url(struct sigma_dut *dut, struct sigma_conn *conn,
7472 struct sigma_cmd *cmd)
7473{
7474 const char *url = get_param(cmd, "url");
7475 const char *method = get_param(cmd, "method");
7476 pid_t pid;
7477 int status;
7478
7479 if (!url || !method)
7480 return -1;
7481
7482 /* TODO: Add support for method,post */
7483 if (strcasecmp(method, "get") != 0) {
7484 send_resp(dut, conn, SIGMA_ERROR,
7485 "ErrorCode,Unsupported method");
7486 return 0;
7487 }
7488
7489 pid = fork();
7490 if (pid < 0) {
7491 perror("fork");
7492 return -1;
7493 }
7494
7495 if (pid == 0) {
7496 char * argv[5] = { "wget", "-O", "/dev/null",
7497 (char *) url, NULL };
7498
7499 execv("/usr/bin/wget", argv);
7500 perror("execv");
7501 exit(0);
7502 return -1;
7503 }
7504
7505 if (waitpid(pid, &status, 0) < 0) {
7506 perror("waitpid");
7507 return -1;
7508 }
7509
7510 if (WIFEXITED(status)) {
7511 const char *errmsg;
7512
7513 if (WEXITSTATUS(status) == 0)
7514 return 1;
7515 sigma_dut_print(dut, DUT_MSG_INFO, "wget exit status %d",
7516 WEXITSTATUS(status));
7517 switch (WEXITSTATUS(status)) {
7518 case 4:
7519 errmsg = "errmsg,Network failure";
7520 break;
7521 case 8:
7522 errmsg = "errmsg,Server issued an error response";
7523 break;
7524 default:
7525 errmsg = "errmsg,Unknown failure from wget";
7526 break;
7527 }
7528 send_resp(dut, conn, SIGMA_ERROR, errmsg);
7529 return 0;
7530 }
7531
7532 send_resp(dut, conn, SIGMA_ERROR, "errmsg,Unknown failure");
7533 return 0;
7534}
7535
7536
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007537static int cmd_sta_exec_action(struct sigma_dut *dut, struct sigma_conn *conn,
7538 struct sigma_cmd *cmd)
7539{
7540 const char *program = get_param(cmd, "Prog");
7541
Jouni Malinen82905202018-04-29 17:20:10 +03007542 if (program && !get_param(cmd, "interface"))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007543 return -1;
7544#ifdef ANDROID_NAN
Jouni Malinen82905202018-04-29 17:20:10 +03007545 if (program && strcasecmp(program, "NAN") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007546 return nan_cmd_sta_exec_action(dut, conn, cmd);
7547#endif /* ANDROID_NAN */
Jouni Malinen82905202018-04-29 17:20:10 +03007548
7549 if (program && strcasecmp(program, "Loc") == 0)
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07007550 return loc_cmd_sta_exec_action(dut, conn, cmd);
Jouni Malinen82905202018-04-29 17:20:10 +03007551
7552 if (get_param(cmd, "url"))
7553 return sta_exec_action_url(dut, conn, cmd);
7554
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007555 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
7556 return 0;
7557}
7558
7559
7560static int cmd_sta_set_11n(struct sigma_dut *dut, struct sigma_conn *conn,
7561 struct sigma_cmd *cmd)
7562{
7563 const char *intf = get_param(cmd, "Interface");
7564 const char *val, *mcs32, *rate;
7565
7566 val = get_param(cmd, "GREENFIELD");
7567 if (val) {
7568 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
7569 /* Enable GD */
7570 send_resp(dut, conn, SIGMA_ERROR,
7571 "ErrorCode,GF not supported");
7572 return 0;
7573 }
7574 }
7575
7576 val = get_param(cmd, "SGI20");
7577 if (val) {
7578 switch (get_driver_type()) {
7579 case DRIVER_ATHEROS:
7580 ath_sta_set_sgi(dut, intf, val);
7581 break;
7582 default:
7583 send_resp(dut, conn, SIGMA_ERROR,
7584 "ErrorCode,SGI20 not supported");
7585 return 0;
7586 }
7587 }
7588
7589 mcs32 = get_param(cmd, "MCS32"); /* HT Duplicate Mode Enable/Disable */
7590 rate = get_param(cmd, "MCS_FIXEDRATE"); /* Fixed MCS rate (0..31) */
7591 if (mcs32 && rate) {
7592 /* TODO */
7593 send_resp(dut, conn, SIGMA_ERROR,
7594 "ErrorCode,MCS32,MCS_FIXEDRATE not supported");
7595 return 0;
7596 } else if (mcs32 && !rate) {
7597 /* TODO */
7598 send_resp(dut, conn, SIGMA_ERROR,
7599 "ErrorCode,MCS32 not supported");
7600 return 0;
7601 } else if (!mcs32 && rate) {
7602 switch (get_driver_type()) {
7603 case DRIVER_ATHEROS:
priyadharshini gowthamane5e25172015-12-08 14:53:48 -08007604 novap_reset(dut, intf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007605 ath_sta_set_11nrates(dut, intf, rate);
7606 break;
7607 default:
7608 send_resp(dut, conn, SIGMA_ERROR,
7609 "ErrorCode,MCS32_FIXEDRATE not supported");
7610 return 0;
7611 }
7612 }
7613
7614 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
7615}
7616
7617
Arif Hussain7b47d2d2018-05-09 10:44:02 -07007618static void cmd_set_max_he_mcs(struct sigma_dut *dut, const char *intf,
7619 int mcs_config)
7620{
7621#ifdef NL80211_SUPPORT
7622 int ret;
7623
7624 switch (mcs_config) {
7625 case HE_80_MCS0_7:
7626 case HE_80_MCS0_9:
7627 case HE_80_MCS0_11:
7628 ret = sta_set_he_mcs(dut, intf, mcs_config);
7629 if (ret) {
7630 sigma_dut_print(dut, DUT_MSG_ERROR,
7631 "cmd_set_max_he_mcs: Setting of MCS:%d failed, ret:%d",
7632 mcs_config, ret);
7633 }
7634 break;
7635 default:
7636 sigma_dut_print(dut, DUT_MSG_ERROR,
7637 "cmd_set_max_he_mcs: Invalid mcs %d",
7638 mcs_config);
7639 break;
7640 }
7641#else /* NL80211_SUPPORT */
7642 sigma_dut_print(dut, DUT_MSG_ERROR,
7643 "max HE MCS cannot be changed without NL80211_SUPPORT defined");
7644#endif /* NL80211_SUPPORT */
7645}
7646
7647
Arif Hussain480d5f42019-03-12 14:40:42 -07007648static int sta_twt_request(struct sigma_dut *dut, struct sigma_conn *conn,
7649 struct sigma_cmd *cmd)
7650{
7651#ifdef NL80211_SUPPORT
7652 struct nlattr *params;
7653 struct nlattr *attr;
7654 struct nlattr *attr1;
7655 struct nl_msg *msg;
7656 int ifindex, ret;
7657 const char *val;
7658 const char *intf = get_param(cmd, "Interface");
7659 int wake_interval_exp = 10, nominal_min_wake_dur = 255,
7660 wake_interval_mantissa = 512;
7661 int flow_type = 0, twt_trigger = 0, target_wake_time = 0,
7662 protection = 0;
7663
7664 ifindex = if_nametoindex(intf);
7665 if (ifindex == 0) {
7666 sigma_dut_print(dut, DUT_MSG_ERROR,
7667 "%s: Index for interface %s failed",
7668 __func__, intf);
7669 return -1;
7670 }
7671
7672 val = get_param(cmd, "FlowType");
7673 if (val) {
7674 flow_type = atoi(val);
7675 if (flow_type != 0 && flow_type != 1) {
7676 sigma_dut_print(dut, DUT_MSG_ERROR,
7677 "TWT: Invalid FlowType %d", flow_type);
7678 return -1;
7679 }
7680 }
7681
7682 val = get_param(cmd, "TWT_Trigger");
7683 if (val) {
7684 twt_trigger = atoi(val);
7685 if (twt_trigger != 0 && twt_trigger != 1) {
7686 sigma_dut_print(dut, DUT_MSG_ERROR,
7687 "TWT: Invalid TWT_Trigger %d",
7688 twt_trigger);
7689 return -1;
7690 }
7691 }
7692
7693 val = get_param(cmd, "Protection");
7694 if (val) {
7695 protection = atoi(val);
7696 if (protection != 0 && protection != 1) {
7697 sigma_dut_print(dut, DUT_MSG_ERROR,
7698 "TWT: Invalid Protection %d",
7699 protection);
7700 return -1;
7701 }
7702 }
7703
7704 val = get_param(cmd, "TargetWakeTime");
7705 if (val)
7706 target_wake_time = atoi(val);
7707
7708 val = get_param(cmd, "WakeIntervalMantissa");
7709 if (val)
7710 wake_interval_mantissa = atoi(val);
7711
7712 val = get_param(cmd, "WakeIntervalExp");
7713 if (val)
7714 wake_interval_exp = atoi(val);
7715
7716 val = get_param(cmd, "NominalMinWakeDur");
7717 if (val)
7718 nominal_min_wake_dur = atoi(val);
7719
7720 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7721 NL80211_CMD_VENDOR)) ||
7722 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7723 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7724 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7725 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7726 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7727 !(params = nla_nest_start(
7728 msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_SETUP)) ||
7729 !(attr1 = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7730 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_EXP,
7731 wake_interval_exp) ||
7732 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST, 0) ||
7733 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_REQ_TYPE, 1) ||
7734 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TRIGGER,
7735 twt_trigger) ||
7736 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE,
7737 flow_type) ||
7738 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_PROTECTION,
7739 protection) ||
7740 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME,
7741 target_wake_time) ||
7742 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_DURATION,
7743 nominal_min_wake_dur) ||
7744 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_MANTISSA,
7745 wake_interval_mantissa)) {
7746 sigma_dut_print(dut, DUT_MSG_ERROR,
7747 "%s: err in adding vendor_cmd and vendor_data",
7748 __func__);
7749 nlmsg_free(msg);
7750 return -1;
7751 }
7752 nla_nest_end(msg, attr1);
7753 nla_nest_end(msg, params);
7754 nla_nest_end(msg, attr);
7755
7756 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7757 if (ret) {
7758 sigma_dut_print(dut, DUT_MSG_ERROR,
7759 "%s: err in send_and_recv_msgs, ret=%d",
7760 __func__, ret);
7761 }
7762
7763 return ret;
7764#else /* NL80211_SUPPORT */
7765 sigma_dut_print(dut, DUT_MSG_ERROR,
7766 "TWT request cannot be done without NL80211_SUPPORT defined");
7767 return -1;
7768#endif /* NL80211_SUPPORT */
7769}
7770
7771
7772static int sta_twt_teardown(struct sigma_dut *dut, struct sigma_conn *conn,
7773 struct sigma_cmd *cmd)
7774{
7775 #ifdef NL80211_SUPPORT
7776 struct nlattr *params;
7777 struct nlattr *attr;
7778 struct nlattr *attr1;
7779 int ifindex, ret;
7780 struct nl_msg *msg;
7781 const char *intf = get_param(cmd, "Interface");
7782
7783 ifindex = if_nametoindex(intf);
7784 if (ifindex == 0) {
7785 sigma_dut_print(dut, DUT_MSG_ERROR,
7786 "%s: Index for interface %s failed",
7787 __func__, intf);
7788 return -1;
7789 }
7790
7791 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7792 NL80211_CMD_VENDOR)) ||
7793 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7794 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7795 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7796 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7797 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7798 !(params = nla_nest_start(
7799 msg,
7800 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_TERMINATE)) ||
7801 !(attr1 = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7802 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE, 0)) {
7803 sigma_dut_print(dut, DUT_MSG_ERROR,
7804 "%s: err in adding vendor_cmd and vendor_data",
7805 __func__);
7806 nlmsg_free(msg);
7807 return -1;
7808 }
7809 nla_nest_end(msg, attr1);
7810 nla_nest_end(msg, params);
7811 nla_nest_end(msg, attr);
7812
7813 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7814 if (ret) {
7815 sigma_dut_print(dut, DUT_MSG_ERROR,
7816 "%s: err in send_and_recv_msgs, ret=%d",
7817 __func__, ret);
7818 }
7819
7820 return ret;
7821#else /* NL80211_SUPPORT */
7822 sigma_dut_print(dut, DUT_MSG_ERROR,
7823 "TWT teardown cannot be done without NL80211_SUPPORT defined");
7824 return -1;
7825#endif /* NL80211_SUPPORT */
7826}
7827
7828
Kiran Kumar Lokere50eb2cd2018-12-18 18:31:28 -08007829static int sta_transmit_omi(struct sigma_dut *dut, struct sigma_conn *conn,
7830 struct sigma_cmd *cmd)
7831{
7832#ifdef NL80211_SUPPORT
7833 struct nlattr *params;
7834 struct nlattr *attr;
7835 struct nlattr *attr1;
7836 struct nl_msg *msg;
7837 int ifindex, ret;
7838 const char *val;
7839 const char *intf = get_param(cmd, "Interface");
7840 uint8_t rx_nss = 0xFF, ch_bw = 0xFF, tx_nsts = 0xFF, ulmu_dis = 0,
7841 ulmu_data_dis = 0;
7842
7843 ifindex = if_nametoindex(intf);
7844 if (ifindex == 0) {
7845 sigma_dut_print(dut, DUT_MSG_ERROR,
7846 "%s: Index for interface %s failed",
7847 __func__, intf);
7848 return -1;
7849 }
7850 val = get_param(cmd, "OMCtrl_RxNSS");
7851 if (val)
7852 rx_nss = atoi(val);
7853
7854 val = get_param(cmd, "OMCtrl_ChnlWidth");
7855 if (val)
7856 ch_bw = atoi(val);
7857
7858 val = get_param(cmd, "OMCtrl_ULMUDisable");
7859 if (val)
7860 ulmu_dis = atoi(val);
7861
7862 val = get_param(cmd, "OMCtrl_TxNSTS");
7863 if (val)
7864 tx_nsts = atoi(val);
7865
7866 val = get_param(cmd, "OMCtrl_ULMUDataDisable");
7867 if (val)
7868 ulmu_data_dis = atoi(val);
7869
7870 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7871 NL80211_CMD_VENDOR)) ||
7872 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7873 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7874 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7875 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7876 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7877 !(params = nla_nest_start(
7878 msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OMI_TX)) ||
7879 !(attr1 = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7880 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_RX_NSS, rx_nss) ||
7881 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_CH_BW, ch_bw) ||
7882 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_TX_NSTS, tx_nsts) ||
7883 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DATA_DISABLE,
7884 ulmu_data_dis) ||
7885 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DISABLE,
7886 ulmu_dis)) {
7887 sigma_dut_print(dut, DUT_MSG_ERROR,
7888 "%s: err in adding vendor_cmd and vendor_data",
7889 __func__);
7890 nlmsg_free(msg);
7891 return -1;
7892 }
7893 nla_nest_end(msg, attr1);
7894 nla_nest_end(msg, params);
7895 nla_nest_end(msg, attr);
7896
7897 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7898 if (ret) {
7899 sigma_dut_print(dut, DUT_MSG_ERROR,
7900 "%s: err in send_and_recv_msgs, ret=%d",
7901 __func__, ret);
7902 }
7903
7904 return ret;
7905#else /* NL80211_SUPPORT */
7906 sigma_dut_print(dut, DUT_MSG_ERROR,
7907 "OMI TX cannot be processed without NL80211_SUPPORT defined");
7908 return -1;
7909#endif /* NL80211_SUPPORT */
7910}
7911
7912
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007913static int cmd_sta_set_wireless_vht(struct sigma_dut *dut,
7914 struct sigma_conn *conn,
7915 struct sigma_cmd *cmd)
7916{
7917 const char *intf = get_param(cmd, "Interface");
7918 const char *val;
Arif Hussaina37e9552018-06-20 17:05:59 -07007919 const char *program;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007920 int tkip = -1;
7921 int wep = -1;
7922
Arif Hussaina37e9552018-06-20 17:05:59 -07007923 program = get_param(cmd, "Program");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007924 val = get_param(cmd, "SGI80");
7925 if (val) {
7926 int sgi80;
7927
7928 sgi80 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07007929 run_iwpriv(dut, intf, "shortgi %d", sgi80);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007930 }
7931
7932 val = get_param(cmd, "TxBF");
7933 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07007934 switch (get_driver_type()) {
7935 case DRIVER_WCN:
7936 if (sta_set_tx_beamformee(dut, intf, 1)) {
7937 send_resp(dut, conn, SIGMA_ERROR,
7938 "ErrorCode,Failed to set TX beamformee enable");
7939 return 0;
7940 }
7941 break;
7942 case DRIVER_ATHEROS:
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07007943 if (run_iwpriv(dut, intf, "vhtsubfee 1") < 0) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07007944 send_resp(dut, conn, SIGMA_ERROR,
7945 "ErrorCode,Setting vhtsubfee failed");
7946 return 0;
7947 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07007948 if (run_iwpriv(dut, intf, "vhtsubfer 1") < 0) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07007949 send_resp(dut, conn, SIGMA_ERROR,
7950 "ErrorCode,Setting vhtsubfer failed");
7951 return 0;
7952 }
7953 break;
7954 default:
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007955 sigma_dut_print(dut, DUT_MSG_ERROR,
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07007956 "Unsupported driver type");
7957 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007958 }
7959 }
7960
7961 val = get_param(cmd, "MU_TxBF");
7962 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
7963 switch (get_driver_type()) {
7964 case DRIVER_ATHEROS:
7965 ath_sta_set_txsp_stream(dut, intf, "1SS");
7966 ath_sta_set_rxsp_stream(dut, intf, "1SS");
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07007967 run_iwpriv(dut, intf, "vhtmubfee 1");
7968 run_iwpriv(dut, intf, "vhtmubfer 1");
Sunil Duttae9e5d12018-06-29 11:50:47 +05307969 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007970 case DRIVER_WCN:
7971 if (wcn_sta_set_sp_stream(dut, intf, "1SS") < 0) {
7972 send_resp(dut, conn, SIGMA_ERROR,
7973 "ErrorCode,Failed to set RX/TXSP_STREAM");
7974 return 0;
7975 }
Sunil Duttae9e5d12018-06-29 11:50:47 +05307976 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007977 default:
7978 sigma_dut_print(dut, DUT_MSG_ERROR,
7979 "Setting SP_STREAM not supported");
7980 break;
7981 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007982 }
7983
7984 val = get_param(cmd, "LDPC");
7985 if (val) {
7986 int ldpc;
7987
7988 ldpc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07007989 run_iwpriv(dut, intf, "ldpc %d", ldpc);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007990 }
7991
Amarnath Hullur Subramanyam7bae60e2018-01-31 03:46:50 -08007992 val = get_param(cmd, "BCC");
7993 if (val) {
7994 int bcc;
7995
7996 bcc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
7997 /* use LDPC iwpriv itself to set bcc coding, bcc coding
7998 * is mutually exclusive to bcc */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07007999 run_iwpriv(dut, intf, "ldpc %d", !bcc);
Amarnath Hullur Subramanyam7bae60e2018-01-31 03:46:50 -08008000 }
8001
Arif Hussain7b47d2d2018-05-09 10:44:02 -07008002 val = get_param(cmd, "MaxHE-MCS_1SS_RxMapLTE80");
8003 if (val && dut->sta_nss == 1)
8004 cmd_set_max_he_mcs(dut, intf, atoi(val));
8005
8006 val = get_param(cmd, "MaxHE-MCS_2SS_RxMapLTE80");
8007 if (val && dut->sta_nss == 2)
8008 cmd_set_max_he_mcs(dut, intf, atoi(val));
8009
Arif Hussainac6c5112018-05-25 17:34:00 -07008010 val = get_param(cmd, "MCS_FixedRate");
8011 if (val) {
8012#ifdef NL80211_SUPPORT
8013 int mcs, ratecode = 0;
8014 enum he_mcs_config mcs_config;
8015 int ret;
Jouni Malinenb9b671d2019-04-26 13:23:17 +03008016 char buf[60];
Arif Hussainac6c5112018-05-25 17:34:00 -07008017
8018 ratecode = (0x07 & dut->sta_nss) << 5;
8019 mcs = atoi(val);
8020 /* Add the MCS to the ratecode */
8021 if (mcs >= 0 && mcs <= 11) {
8022 ratecode += mcs;
8023 if (dut->device_type == STA_testbed &&
8024 mcs > 7 && mcs <= 11) {
8025 if (mcs <= 9)
8026 mcs_config = HE_80_MCS0_9;
8027 else
8028 mcs_config = HE_80_MCS0_11;
8029 ret = sta_set_he_mcs(dut, intf, mcs_config);
8030 if (ret) {
8031 sigma_dut_print(dut, DUT_MSG_ERROR,
8032 "MCS_FixedRate: mcs setting failed, mcs:%d, mcs_config %d, ret:%d",
8033 mcs, mcs_config, ret);
8034 }
8035 }
8036 snprintf(buf, sizeof(buf),
8037 "iwpriv %s set_11ax_rate 0x%03x",
8038 intf, ratecode);
8039 if (system(buf) != 0) {
8040 sigma_dut_print(dut, DUT_MSG_ERROR,
8041 "MCS_FixedRate: iwpriv setting of 11ax rates 0x%03x failed",
8042 ratecode);
8043 }
8044 } else {
8045 sigma_dut_print(dut, DUT_MSG_ERROR,
8046 "MCS_FixedRate: HE MCS %d not supported",
8047 mcs);
8048 }
8049#else /* NL80211_SUPPORT */
8050 sigma_dut_print(dut, DUT_MSG_ERROR,
8051 "MCS_FixedRate cannot be changed without NL80211_SUPPORT defined");
8052#endif /* NL80211_SUPPORT */
8053 }
8054
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008055 val = get_param(cmd, "opt_md_notif_ie");
8056 if (val) {
8057 char *result = NULL;
8058 char delim[] = ";";
8059 char token[30];
8060 int value, config_val = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308061 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008062
Peng Xub8fc5cc2017-05-10 17:27:28 -07008063 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308064 result = strtok_r(token, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008065
8066 /* Extract the NSS information */
8067 if (result) {
8068 value = atoi(result);
8069 switch (value) {
8070 case 1:
8071 config_val = 1;
8072 break;
8073 case 2:
8074 config_val = 3;
8075 break;
8076 case 3:
8077 config_val = 7;
8078 break;
8079 case 4:
8080 config_val = 15;
8081 break;
8082 default:
8083 config_val = 3;
8084 break;
8085 }
8086
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008087 run_iwpriv(dut, intf, "rxchainmask %d", config_val);
8088 run_iwpriv(dut, intf, "txchainmask %d", config_val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008089
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008090 }
8091
8092 /* Extract the channel width information */
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308093 result = strtok_r(NULL, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008094 if (result) {
8095 value = atoi(result);
8096 switch (value) {
8097 case 20:
8098 config_val = 0;
8099 break;
8100 case 40:
8101 config_val = 1;
8102 break;
8103 case 80:
8104 config_val = 2;
8105 break;
8106 case 160:
8107 config_val = 3;
8108 break;
8109 default:
8110 config_val = 2;
8111 break;
8112 }
8113
8114 dut->chwidth = config_val;
8115
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008116 run_iwpriv(dut, intf, "chwidth %d", config_val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008117 }
8118
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008119 run_iwpriv(dut, intf, "opmode_notify 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008120 }
8121
8122 val = get_param(cmd, "nss_mcs_cap");
8123 if (val) {
8124 int nss, mcs;
8125 char token[20];
8126 char *result = NULL;
8127 unsigned int vht_mcsmap = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308128 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008129
Peng Xub8fc5cc2017-05-10 17:27:28 -07008130 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308131 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05308132 if (!result) {
8133 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07008134 "NSS not specified");
8135 send_resp(dut, conn, SIGMA_ERROR,
8136 "errorCode,NSS not specified");
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05308137 return 0;
8138 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008139 nss = atoi(result);
8140
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008141 run_iwpriv(dut, intf, "nss %d", nss);
Arif Hussainac6c5112018-05-25 17:34:00 -07008142 dut->sta_nss = nss;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008143
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308144 result = strtok_r(NULL, ";", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008145 if (result == NULL) {
8146 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07008147 "MCS not specified");
8148 send_resp(dut, conn, SIGMA_ERROR,
8149 "errorCode,MCS not specified");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008150 return 0;
8151 }
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308152 result = strtok_r(result, "-", &saveptr);
8153 result = strtok_r(NULL, "-", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05308154 if (!result) {
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");
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05308159 return 0;
8160 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008161 mcs = atoi(result);
8162
Arif Hussaina37e9552018-06-20 17:05:59 -07008163 if (program && strcasecmp(program, "HE") == 0) {
8164#ifdef NL80211_SUPPORT
8165 enum he_mcs_config mcs_config;
8166 int ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008167
Arif Hussaina37e9552018-06-20 17:05:59 -07008168 if (mcs >= 0 && mcs <= 7) {
8169 mcs_config = HE_80_MCS0_7;
8170 } else if (mcs > 7 && mcs <= 9) {
8171 mcs_config = HE_80_MCS0_9;
8172 } else if (mcs > 9 && mcs <= 11) {
8173 mcs_config = HE_80_MCS0_11;
8174 } else {
8175 sigma_dut_print(dut, DUT_MSG_ERROR,
8176 "nss_mcs_cap: HE: Invalid mcs: %d",
8177 mcs);
8178 send_resp(dut, conn, SIGMA_ERROR,
8179 "errorCode,Invalid MCS");
8180 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008181 }
Arif Hussaina37e9552018-06-20 17:05:59 -07008182
8183 ret = sta_set_he_mcs(dut, intf, mcs_config);
8184 if (ret) {
8185 sigma_dut_print(dut, DUT_MSG_ERROR,
8186 "nss_mcs_cap: HE: Setting of MCS failed, mcs_config: %d, ret: %d",
8187 mcs_config, ret);
8188 send_resp(dut, conn, SIGMA_ERROR,
8189 "errorCode,Failed to set MCS");
8190 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008191 }
Arif Hussaina37e9552018-06-20 17:05:59 -07008192#else /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008193 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07008194 "nss_mcs_cap: HE: MCS cannot be changed without NL80211_SUPPORT defined");
8195#endif /* NL80211_SUPPORT */
8196 } else {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008197 run_iwpriv(dut, intf, "vhtmcs %d", mcs);
Arif Hussaina37e9552018-06-20 17:05:59 -07008198
8199 switch (nss) {
8200 case 1:
8201 switch (mcs) {
8202 case 7:
8203 vht_mcsmap = 0xfffc;
8204 break;
8205 case 8:
8206 vht_mcsmap = 0xfffd;
8207 break;
8208 case 9:
8209 vht_mcsmap = 0xfffe;
8210 break;
8211 default:
8212 vht_mcsmap = 0xfffe;
8213 break;
8214 }
8215 break;
8216 case 2:
8217 switch (mcs) {
8218 case 7:
8219 vht_mcsmap = 0xfff0;
8220 break;
8221 case 8:
8222 vht_mcsmap = 0xfff5;
8223 break;
8224 case 9:
8225 vht_mcsmap = 0xfffa;
8226 break;
8227 default:
8228 vht_mcsmap = 0xfffa;
8229 break;
8230 }
8231 break;
8232 case 3:
8233 switch (mcs) {
8234 case 7:
8235 vht_mcsmap = 0xffc0;
8236 break;
8237 case 8:
8238 vht_mcsmap = 0xffd5;
8239 break;
8240 case 9:
8241 vht_mcsmap = 0xffea;
8242 break;
8243 default:
8244 vht_mcsmap = 0xffea;
8245 break;
8246 }
8247 break;
8248 default:
8249 vht_mcsmap = 0xffea;
8250 break;
8251 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008252 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008253 }
8254 }
8255
8256 /* UNSUPPORTED: val = get_param(cmd, "Tx_lgi_rate"); */
8257
8258 val = get_param(cmd, "Vht_tkip");
8259 if (val)
8260 tkip = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
8261
8262 val = get_param(cmd, "Vht_wep");
8263 if (val)
8264 wep = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
8265
8266 if (tkip != -1 || wep != -1) {
8267 if ((tkip == 1 && wep != 0) || (wep == 1 && tkip != 0)) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008268 run_iwpriv(dut, intf, "htweptkip 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008269 } else if ((tkip == 0 && wep != 1) || (wep == 0 && tkip != 1)) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008270 run_iwpriv(dut, intf, "htweptkip 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008271 } else {
8272 sigma_dut_print(dut, DUT_MSG_ERROR,
8273 "ErrorCode,mixed mode of VHT TKIP/WEP not supported");
8274 return 0;
8275 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008276 }
8277
Arif Hussain55f00da2018-07-03 08:28:26 -07008278 val = get_param(cmd, "txBandwidth");
8279 if (val) {
8280 switch (get_driver_type()) {
8281 case DRIVER_WCN:
8282 if (wcn_sta_set_width(dut, intf, val) < 0) {
8283 send_resp(dut, conn, SIGMA_ERROR,
8284 "ErrorCode,Failed to set txBandwidth");
8285 return 0;
8286 }
8287 break;
8288 case DRIVER_ATHEROS:
8289 if (ath_set_width(dut, conn, intf, val) < 0) {
8290 send_resp(dut, conn, SIGMA_ERROR,
8291 "ErrorCode,Failed to set txBandwidth");
8292 return 0;
8293 }
8294 break;
8295 default:
8296 sigma_dut_print(dut, DUT_MSG_ERROR,
8297 "Setting txBandwidth not supported");
8298 break;
8299 }
8300 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008301
Arif Hussain9765f7d2018-07-03 08:28:26 -07008302 val = get_param(cmd, "BeamformeeSTS");
8303 if (val) {
Kiran Kumar Lokerebc89d432018-07-10 12:20:13 -07008304 if (sta_set_tx_beamformee(dut, intf, 1)) {
8305 send_resp(dut, conn, SIGMA_ERROR,
8306 "ErrorCode,Failed to set TX beamformee enable");
8307 return 0;
8308 }
8309
Arif Hussain9765f7d2018-07-03 08:28:26 -07008310 if (sta_set_beamformee_sts(dut, intf, atoi(val))) {
8311 send_resp(dut, conn, SIGMA_ERROR,
8312 "ErrorCode,Failed to set BeamformeeSTS");
8313 return 0;
8314 }
8315 }
8316
Arif Hussain68d23f52018-07-11 13:39:08 -07008317 val = get_param(cmd, "Trig_MAC_Padding_Dur");
8318 if (val) {
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07008319#ifdef NL80211_SUPPORT
8320 enum qca_wlan_he_mac_padding_dur set_val;
8321
8322 switch (atoi(val)) {
8323 case 16:
8324 set_val = QCA_WLAN_HE_16US_OF_PROCESS_TIME;
8325 break;
8326 case 8:
8327 set_val = QCA_WLAN_HE_8US_OF_PROCESS_TIME;
8328 break;
8329 default:
8330 set_val = QCA_WLAN_HE_NO_ADDITIONAL_PROCESS_TIME;
8331 break;
8332 }
8333 if (sta_set_mac_padding_duration(dut, intf, set_val)) {
Arif Hussain68d23f52018-07-11 13:39:08 -07008334 send_resp(dut, conn, SIGMA_ERROR,
8335 "ErrorCode,Failed to set MAC padding duration");
8336 return 0;
8337 }
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07008338#else /* NL80211_SUPPORT */
8339 sigma_dut_print(dut, DUT_MSG_ERROR,
8340 "MAC padding duration cannot be changed without NL80211_SUPPORT defined");
8341#endif /* NL80211_SUPPORT */
Arif Hussain68d23f52018-07-11 13:39:08 -07008342 }
8343
Arif Hussain480d5f42019-03-12 14:40:42 -07008344 val = get_param(cmd, "TWT_ReqSupport");
8345 if (val) {
8346 int set_val;
8347
8348 if (strcasecmp(val, "Enable") == 0) {
8349 set_val = 1;
8350 } else if (strcasecmp(val, "Disable") == 0) {
8351 set_val = 0;
8352 } else {
8353 send_resp(dut, conn, SIGMA_ERROR,
8354 "ErrorCode,Invalid TWT_ReqSupport");
8355 return STATUS_SENT;
8356 }
8357
8358 if (sta_set_twt_req_support(dut, intf, set_val)) {
8359 sigma_dut_print(dut, DUT_MSG_ERROR,
8360 "Failed to set TWT req support %d",
8361 set_val);
8362 send_resp(dut, conn, SIGMA_ERROR,
8363 "ErrorCode,Failed to set TWT_ReqSupport");
8364 return STATUS_SENT;
8365 }
8366 }
8367
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07008368 val = get_param(cmd, "MU_EDCA");
8369 if (val && (strcasecmp(val, "Override") == 0)) {
8370 if (sta_set_mu_edca_override(dut, intf, 1)) {
8371 send_resp(dut, conn, SIGMA_ERROR,
8372 "ErrorCode,Failed to set MU EDCA override");
8373 return 0;
8374 }
8375 }
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -07008376
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07008377 val = get_param(cmd, "OMControl");
8378 if (val) {
8379 int set_val = 1;
8380
8381 if (strcasecmp(val, "Enable") == 0)
8382 set_val = 1;
8383 else if (strcasecmp(val, "Disable") == 0)
8384 set_val = 0;
8385
8386 if (sta_set_om_ctrl_supp(dut, intf, set_val)) {
8387 send_resp(dut, conn, SIGMA_ERROR,
8388 "ErrorCode,Failed to set OM ctrl supp");
8389 return 0;
8390 }
8391 }
8392
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -07008393 val = get_param(cmd, "ADDBAResp_BufSize");
8394 if (val) {
8395 int buf_size;
8396
8397 if (strcasecmp(val, "gt64") == 0)
8398 buf_size = 256;
8399 else
8400 buf_size = 64;
8401 if (get_driver_type() == DRIVER_WCN &&
8402 sta_set_addba_buf_size(dut, intf, buf_size)) {
8403 send_resp(dut, conn, SIGMA_ERROR,
8404 "ErrorCode,set addbaresp_buff_size failed");
8405 return 0;
8406 }
8407 }
8408
8409 val = get_param(cmd, "ADDBAReq_BufSize");
8410 if (val) {
8411 int buf_size;
8412
8413 if (strcasecmp(val, "gt64") == 0)
8414 buf_size = 256;
8415 else
8416 buf_size = 64;
8417 if (get_driver_type() == DRIVER_WCN &&
8418 sta_set_addba_buf_size(dut, intf, buf_size)) {
8419 send_resp(dut, conn, SIGMA_ERROR,
8420 "ErrorCode,set addbareq_buff_size failed");
8421 return 0;
8422 }
8423 }
8424
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008425 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
8426}
8427
8428
8429static int sta_set_wireless_60g(struct sigma_dut *dut,
8430 struct sigma_conn *conn,
8431 struct sigma_cmd *cmd)
8432{
8433 const char *dev_role = get_param(cmd, "DevRole");
8434
8435 if (!dev_role) {
8436 send_resp(dut, conn, SIGMA_INVALID,
8437 "ErrorCode,DevRole not specified");
8438 return 0;
8439 }
8440
8441 if (strcasecmp(dev_role, "PCP") == 0)
8442 return sta_set_60g_pcp(dut, conn, cmd);
8443 if (strcasecmp(dev_role, "STA") == 0)
8444 return sta_set_60g_sta(dut, conn, cmd);
8445 send_resp(dut, conn, SIGMA_INVALID,
8446 "ErrorCode,DevRole not supported");
8447 return 0;
8448}
8449
8450
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05308451static int sta_set_wireless_oce(struct sigma_dut *dut, struct sigma_conn *conn,
8452 struct sigma_cmd *cmd)
8453{
8454 int status;
8455 const char *intf = get_param(cmd, "Interface");
8456 const char *val = get_param(cmd, "DevRole");
8457
8458 if (val && strcasecmp(val, "STA-CFON") == 0) {
8459 status = sta_cfon_set_wireless(dut, conn, cmd);
8460 if (status)
8461 return status;
8462 }
8463 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
8464}
8465
8466
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008467static int cmd_sta_set_wireless(struct sigma_dut *dut, struct sigma_conn *conn,
8468 struct sigma_cmd *cmd)
8469{
8470 const char *val;
8471
8472 val = get_param(cmd, "Program");
8473 if (val) {
8474 if (strcasecmp(val, "11n") == 0)
8475 return cmd_sta_set_11n(dut, conn, cmd);
Amarnath Hullur Subramanyam4f860292018-01-31 03:49:35 -08008476 if (strcasecmp(val, "VHT") == 0 || strcasecmp(val, "HE") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008477 return cmd_sta_set_wireless_vht(dut, conn, cmd);
8478 if (strcasecmp(val, "60ghz") == 0)
8479 return sta_set_wireless_60g(dut, conn, cmd);
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05308480 if (strcasecmp(val, "OCE") == 0)
8481 return sta_set_wireless_oce(dut, conn, cmd);
Alexei Avshalom Lazar66bb9972018-12-18 16:01:43 +02008482 /* sta_set_wireless in WPS program is only used for 60G */
8483 if (is_60g_sigma_dut(dut))
8484 return sta_set_wireless_60g(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008485 send_resp(dut, conn, SIGMA_ERROR,
8486 "ErrorCode,Program value not supported");
8487 } else {
8488 send_resp(dut, conn, SIGMA_ERROR,
8489 "ErrorCode,Program argument not available");
8490 }
8491
8492 return 0;
8493}
8494
8495
8496static void ath_sta_inject_frame(struct sigma_dut *dut, const char *intf,
8497 int tid)
8498{
8499 char buf[100];
8500 int tid_to_dscp [] = { 0x00, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0 };
8501
Pradeep Reddy POTTETId31d1322016-10-13 17:22:03 +05308502 if (tid < 0 ||
8503 tid >= (int) (sizeof(tid_to_dscp) / sizeof(tid_to_dscp[0]))) {
8504 sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported TID: %d", tid);
8505 return;
8506 }
8507
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008508 /*
8509 * Two ways to ensure that addba request with a
8510 * non zero TID could be sent out. EV 117296
8511 */
8512 snprintf(buf, sizeof(buf),
8513 "ping -c 8 -Q %d `arp -a | grep wlan0 | awk '{print $2}' | tr -d '()'`",
8514 tid);
8515 if (system(buf) != 0) {
8516 sigma_dut_print(dut, DUT_MSG_ERROR,
8517 "Ping did not send out");
8518 }
8519
8520 snprintf(buf, sizeof(buf),
8521 "iwconfig %s | grep Access | awk '{print $6}' > %s",
8522 intf, VI_QOS_TMP_FILE);
8523 if (system(buf) != 0)
8524 return;
8525
8526 snprintf(buf, sizeof(buf),
8527 "ifconfig %s | grep HWaddr | cut -b 39-56 >> %s",
8528 intf, VI_QOS_TMP_FILE);
8529 if (system(buf) != 0)
8530 sigma_dut_print(dut, DUT_MSG_ERROR, "HWaddr matching failed");
8531
8532 snprintf(buf,sizeof(buf), "sed -n '3,$p' %s >> %s",
8533 VI_QOS_REFFILE, VI_QOS_TMP_FILE);
8534 if (system(buf) != 0) {
8535 sigma_dut_print(dut, DUT_MSG_ERROR,
8536 "VI_QOS_TEMP_FILE generation error failed");
8537 }
8538 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
8539 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
8540 if (system(buf) != 0) {
8541 sigma_dut_print(dut, DUT_MSG_ERROR,
8542 "VI_QOS_FILE generation failed");
8543 }
8544
8545 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
8546 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
8547 if (system(buf) != 0) {
8548 sigma_dut_print(dut, DUT_MSG_ERROR,
8549 "VI_QOS_FILE generation failed");
8550 }
8551
8552 snprintf(buf, sizeof(buf), "ethinject %s %s", intf, VI_QOS_FILE);
8553 if (system(buf) != 0) {
8554 }
8555}
8556
8557
8558static int ath_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
8559 struct sigma_cmd *cmd)
8560{
8561 const char *intf = get_param(cmd, "Interface");
8562 const char *val;
8563 int tid = 0;
8564 char buf[100];
8565
8566 val = get_param(cmd, "TID");
8567 if (val) {
8568 tid = atoi(val);
8569 if (tid)
8570 ath_sta_inject_frame(dut, intf, tid);
8571 }
8572
8573 /* Command sequence for ADDBA request on Peregrine based devices */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008574 run_iwpriv(dut, intf, "setaddbaoper 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008575
8576 snprintf(buf, sizeof(buf), "wifitool %s senddelba 1 %d 1 4", intf, tid);
8577 if (system(buf) != 0) {
8578 sigma_dut_print(dut, DUT_MSG_ERROR,
8579 "wifitool senddelba failed");
8580 }
8581
8582 snprintf(buf, sizeof(buf), "wifitool %s sendaddba 1 %d 64", intf, tid);
8583 if (system(buf) != 0) {
8584 sigma_dut_print(dut, DUT_MSG_ERROR,
8585 "wifitool sendaddba failed");
8586 }
8587
8588 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
8589
8590 return 1;
8591}
8592
8593
Lior David9981b512017-01-20 13:16:40 +02008594#ifdef __linux__
8595
8596static int wil6210_send_addba(struct sigma_dut *dut, const char *dest_mac,
8597 int agg_size)
8598{
8599 char dir[128], buf[128];
8600 FILE *f;
8601 regex_t re;
8602 regmatch_t m[2];
8603 int rc, ret = -1, vring_id, found;
8604
8605 if (wil6210_get_debugfs_dir(dut, dir, sizeof(dir))) {
8606 sigma_dut_print(dut, DUT_MSG_ERROR,
8607 "failed to get wil6210 debugfs dir");
8608 return -1;
8609 }
8610
8611 snprintf(buf, sizeof(buf), "%s/vrings", dir);
8612 f = fopen(buf, "r");
8613 if (!f) {
8614 sigma_dut_print(dut, DUT_MSG_ERROR, "failed to open: %s", buf);
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +02008615 /* newer wil6210 driver renamed file to "rings" */
8616 snprintf(buf, sizeof(buf), "%s/rings", dir);
8617 f = fopen(buf, "r");
8618 if (!f) {
8619 sigma_dut_print(dut, DUT_MSG_ERROR,
8620 "failed to open: %s", buf);
8621 return -1;
8622 }
Lior David9981b512017-01-20 13:16:40 +02008623 }
8624
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +02008625 /* can be either VRING tx... or RING... */
8626 if (regcomp(&re, "RING tx_[ \t]*([0-9]+)", REG_EXTENDED)) {
Lior David9981b512017-01-20 13:16:40 +02008627 sigma_dut_print(dut, DUT_MSG_ERROR, "regcomp failed");
8628 goto out;
8629 }
8630
8631 /* find TX VRING for the mac address */
8632 found = 0;
8633 while (fgets(buf, sizeof(buf), f)) {
8634 if (strcasestr(buf, dest_mac)) {
8635 found = 1;
8636 break;
8637 }
8638 }
8639
8640 if (!found) {
8641 sigma_dut_print(dut, DUT_MSG_ERROR,
8642 "no TX VRING for %s", dest_mac);
8643 goto out;
8644 }
8645
8646 /* extract VRING ID, "VRING tx_<id> = {" */
8647 if (!fgets(buf, sizeof(buf), f)) {
8648 sigma_dut_print(dut, DUT_MSG_ERROR,
8649 "no VRING start line for %s", dest_mac);
8650 goto out;
8651 }
8652
8653 rc = regexec(&re, buf, 2, m, 0);
8654 regfree(&re);
8655 if (rc || m[1].rm_so < 0) {
8656 sigma_dut_print(dut, DUT_MSG_ERROR,
8657 "no VRING TX ID for %s", dest_mac);
8658 goto out;
8659 }
8660 buf[m[1].rm_eo] = 0;
8661 vring_id = atoi(&buf[m[1].rm_so]);
8662
8663 /* send the addba command */
8664 fclose(f);
8665 snprintf(buf, sizeof(buf), "%s/back", dir);
8666 f = fopen(buf, "w");
8667 if (!f) {
8668 sigma_dut_print(dut, DUT_MSG_ERROR,
8669 "failed to open: %s", buf);
8670 return -1;
8671 }
8672
8673 fprintf(f, "add %d %d\n", vring_id, agg_size);
8674
8675 ret = 0;
8676
8677out:
8678 fclose(f);
8679
8680 return ret;
8681}
8682
8683
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +02008684int send_addba_60g(struct sigma_dut *dut, struct sigma_conn *conn,
8685 struct sigma_cmd *cmd, const char *mac_param)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008686{
8687 const char *val;
8688 int tid = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008689
8690 val = get_param(cmd, "TID");
8691 if (val) {
8692 tid = atoi(val);
8693 if (tid != 0) {
8694 sigma_dut_print(dut, DUT_MSG_ERROR,
8695 "Ignore TID %d for send_addba use TID 0 for 60g since only 0 required on TX",
8696 tid);
8697 }
8698 }
8699
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +02008700 val = get_param(cmd, mac_param);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008701 if (!val) {
8702 sigma_dut_print(dut, DUT_MSG_ERROR,
8703 "Currently not supporting addba for 60G without Dest_mac");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02008704 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008705 }
8706
Lior David9981b512017-01-20 13:16:40 +02008707 if (wil6210_send_addba(dut, val, dut->back_rcv_buf))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008708 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008709
8710 return 1;
8711}
8712
Lior David9981b512017-01-20 13:16:40 +02008713#endif /* __linux__ */
8714
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008715
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08008716static int wcn_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
8717 struct sigma_cmd *cmd)
8718{
8719#ifdef NL80211_SUPPORT
8720 const char *intf = get_param(cmd, "Interface");
8721 const char *val;
8722 int tid = -1;
8723 int bufsize = 64;
8724 struct nl_msg *msg;
8725 int ret = 0;
8726 struct nlattr *params;
8727 int ifindex;
8728
8729 val = get_param(cmd, "TID");
8730 if (val)
8731 tid = atoi(val);
8732
8733 if (tid == -1) {
8734 send_resp(dut, conn, SIGMA_ERROR,
8735 "ErrorCode,sta_send_addba tid invalid");
8736 return 0;
8737 }
8738
8739 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
8740
8741 ifindex = if_nametoindex(intf);
8742 if (ifindex == 0) {
8743 sigma_dut_print(dut, DUT_MSG_ERROR,
8744 "%s: Index for interface %s failed",
8745 __func__, intf);
8746 send_resp(dut, conn, SIGMA_ERROR,
8747 "ErrorCode,sta_send_addba interface invalid");
8748 return 0;
8749 }
8750
8751 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8752 NL80211_CMD_VENDOR)) ||
8753 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
8754 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
8755 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
8756 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
8757 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8758 nla_put_u8(msg,
8759 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADD_DEL_BA_SESSION,
8760 QCA_WLAN_ADD_BA) ||
8761 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BA_TID,
8762 tid) ||
Kiran Kumar Lokere26e27582018-08-01 16:18:34 -07008763 nla_put_u16(msg,
8764 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE,
8765 bufsize)) {
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08008766 sigma_dut_print(dut, DUT_MSG_ERROR,
8767 "%s: err in adding vendor_cmd and vendor_data",
8768 __func__);
8769 nlmsg_free(msg);
8770 send_resp(dut, conn, SIGMA_ERROR,
8771 "ErrorCode,sta_send_addba err in adding vendor_cmd and vendor_data");
8772 return 0;
8773 }
8774 nla_nest_end(msg, params);
8775
8776 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
8777 if (ret) {
8778 sigma_dut_print(dut, DUT_MSG_ERROR,
8779 "%s: err in send_and_recv_msgs, ret=%d",
8780 __func__, ret);
Sunil Dutt30605592018-05-04 20:35:50 +05308781 if (ret == -EOPNOTSUPP)
8782 return 1;
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08008783 send_resp(dut, conn, SIGMA_ERROR,
8784 "ErrorCode,sta_send_addba err in send_and_recv_msgs");
8785 return 0;
8786 }
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08008787#else /* NL80211_SUPPORT */
8788 sigma_dut_print(dut, DUT_MSG_ERROR,
8789 "sta_send_addba not supported without NL80211_SUPPORT defined");
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08008790#endif /* NL80211_SUPPORT */
Sunil Dutt30605592018-05-04 20:35:50 +05308791
8792 return 1;
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08008793}
8794
8795
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008796static int cmd_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
8797 struct sigma_cmd *cmd)
8798{
8799 switch (get_driver_type()) {
8800 case DRIVER_ATHEROS:
8801 return ath_sta_send_addba(dut, conn, cmd);
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08008802 case DRIVER_WCN:
8803 return wcn_sta_send_addba(dut, conn, cmd);
Lior David9981b512017-01-20 13:16:40 +02008804#ifdef __linux__
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008805 case DRIVER_WIL6210:
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +02008806 return send_addba_60g(dut, conn, cmd, "Dest_mac");
Lior David9981b512017-01-20 13:16:40 +02008807#endif /* __linux__ */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008808 default:
8809 /*
8810 * There is no driver specific implementation for other drivers.
8811 * Ignore the command and report COMPLETE since the following
8812 * throughput test operation will end up sending ADDBA anyway.
8813 */
8814 return 1;
8815 }
8816}
8817
8818
8819int inject_eth_frame(int s, const void *data, size_t len,
8820 unsigned short ethtype, char *dst, char *src)
8821{
8822 struct iovec iov[4] = {
8823 {
8824 .iov_base = dst,
8825 .iov_len = ETH_ALEN,
8826 },
8827 {
8828 .iov_base = src,
8829 .iov_len = ETH_ALEN,
8830 },
8831 {
8832 .iov_base = &ethtype,
8833 .iov_len = sizeof(unsigned short),
8834 },
8835 {
8836 .iov_base = (void *) data,
8837 .iov_len = len,
8838 }
8839 };
8840 struct msghdr msg = {
8841 .msg_name = NULL,
8842 .msg_namelen = 0,
8843 .msg_iov = iov,
8844 .msg_iovlen = 4,
8845 .msg_control = NULL,
8846 .msg_controllen = 0,
8847 .msg_flags = 0,
8848 };
8849
8850 return sendmsg(s, &msg, 0);
8851}
8852
8853#if defined(__linux__) || defined(__QNXNTO__)
8854
8855int inject_frame(int s, const void *data, size_t len, int encrypt)
8856{
8857#define IEEE80211_RADIOTAP_F_WEP 0x04
8858#define IEEE80211_RADIOTAP_F_FRAG 0x08
8859 unsigned char rtap_hdr[] = {
8860 0x00, 0x00, /* radiotap version */
8861 0x0e, 0x00, /* radiotap length */
8862 0x02, 0xc0, 0x00, 0x00, /* bmap: flags, tx and rx flags */
8863 IEEE80211_RADIOTAP_F_FRAG, /* F_FRAG (fragment if required) */
8864 0x00, /* padding */
8865 0x00, 0x00, /* RX and TX flags to indicate that */
8866 0x00, 0x00, /* this is the injected frame directly */
8867 };
8868 struct iovec iov[2] = {
8869 {
8870 .iov_base = &rtap_hdr,
8871 .iov_len = sizeof(rtap_hdr),
8872 },
8873 {
8874 .iov_base = (void *) data,
8875 .iov_len = len,
8876 }
8877 };
8878 struct msghdr msg = {
8879 .msg_name = NULL,
8880 .msg_namelen = 0,
8881 .msg_iov = iov,
8882 .msg_iovlen = 2,
8883 .msg_control = NULL,
8884 .msg_controllen = 0,
8885 .msg_flags = 0,
8886 };
8887
8888 if (encrypt)
8889 rtap_hdr[8] |= IEEE80211_RADIOTAP_F_WEP;
8890
8891 return sendmsg(s, &msg, 0);
8892}
8893
8894
8895int open_monitor(const char *ifname)
8896{
8897#ifdef __QNXNTO__
8898 struct sockaddr_dl ll;
8899 int s;
8900
8901 memset(&ll, 0, sizeof(ll));
8902 ll.sdl_family = AF_LINK;
8903 ll.sdl_index = if_nametoindex(ifname);
8904 if (ll.sdl_index == 0) {
8905 perror("if_nametoindex");
8906 return -1;
8907 }
8908 s = socket(PF_INET, SOCK_RAW, 0);
8909#else /* __QNXNTO__ */
8910 struct sockaddr_ll ll;
8911 int s;
8912
8913 memset(&ll, 0, sizeof(ll));
8914 ll.sll_family = AF_PACKET;
8915 ll.sll_ifindex = if_nametoindex(ifname);
8916 if (ll.sll_ifindex == 0) {
8917 perror("if_nametoindex");
8918 return -1;
8919 }
8920 s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
8921#endif /* __QNXNTO__ */
8922 if (s < 0) {
8923 perror("socket[PF_PACKET,SOCK_RAW]");
8924 return -1;
8925 }
8926
8927 if (bind(s, (struct sockaddr *) &ll, sizeof(ll)) < 0) {
8928 perror("monitor socket bind");
8929 close(s);
8930 return -1;
8931 }
8932
8933 return s;
8934}
8935
8936
8937static int hex2num(char c)
8938{
8939 if (c >= '0' && c <= '9')
8940 return c - '0';
8941 if (c >= 'a' && c <= 'f')
8942 return c - 'a' + 10;
8943 if (c >= 'A' && c <= 'F')
8944 return c - 'A' + 10;
8945 return -1;
8946}
8947
8948
8949int hwaddr_aton(const char *txt, unsigned char *addr)
8950{
8951 int i;
8952
8953 for (i = 0; i < 6; i++) {
8954 int a, b;
8955
8956 a = hex2num(*txt++);
8957 if (a < 0)
8958 return -1;
8959 b = hex2num(*txt++);
8960 if (b < 0)
8961 return -1;
8962 *addr++ = (a << 4) | b;
8963 if (i < 5 && *txt++ != ':')
8964 return -1;
8965 }
8966
8967 return 0;
8968}
8969
8970#endif /* defined(__linux__) || defined(__QNXNTO__) */
8971
8972enum send_frame_type {
8973 DISASSOC, DEAUTH, SAQUERY, AUTH, ASSOCREQ, REASSOCREQ, DLS_REQ
8974};
8975enum send_frame_protection {
8976 CORRECT_KEY, INCORRECT_KEY, UNPROTECTED
8977};
8978
8979
8980static int sta_inject_frame(struct sigma_dut *dut, struct sigma_conn *conn,
8981 enum send_frame_type frame,
8982 enum send_frame_protection protected,
8983 const char *dest)
8984{
8985#ifdef __linux__
8986 unsigned char buf[1000], *pos;
8987 int s, res;
8988 char bssid[20], addr[20];
8989 char result[32], ssid[100];
8990 size_t ssid_len;
8991
8992 if (get_wpa_status(get_station_ifname(), "wpa_state", result,
8993 sizeof(result)) < 0 ||
8994 strncmp(result, "COMPLETED", 9) != 0) {
8995 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Not connected");
8996 return 0;
8997 }
8998
8999 if (get_wpa_status(get_station_ifname(), "bssid", bssid, sizeof(bssid))
9000 < 0) {
9001 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
9002 "current BSSID");
9003 return 0;
9004 }
9005
9006 if (get_wpa_status(get_station_ifname(), "address", addr, sizeof(addr))
9007 < 0) {
9008 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
9009 "own MAC address");
9010 return 0;
9011 }
9012
9013 if (get_wpa_status(get_station_ifname(), "ssid", ssid, sizeof(ssid))
9014 < 0) {
9015 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
9016 "current SSID");
9017 return 0;
9018 }
9019 ssid_len = strlen(ssid);
9020
9021 pos = buf;
9022
9023 /* Frame Control */
9024 switch (frame) {
9025 case DISASSOC:
9026 *pos++ = 0xa0;
9027 break;
9028 case DEAUTH:
9029 *pos++ = 0xc0;
9030 break;
9031 case SAQUERY:
9032 *pos++ = 0xd0;
9033 break;
9034 case AUTH:
9035 *pos++ = 0xb0;
9036 break;
9037 case ASSOCREQ:
9038 *pos++ = 0x00;
9039 break;
9040 case REASSOCREQ:
9041 *pos++ = 0x20;
9042 break;
9043 case DLS_REQ:
9044 *pos++ = 0xd0;
9045 break;
9046 }
9047
9048 if (protected == INCORRECT_KEY)
9049 *pos++ = 0x40; /* Set Protected field to 1 */
9050 else
9051 *pos++ = 0x00;
9052
9053 /* Duration */
9054 *pos++ = 0x00;
9055 *pos++ = 0x00;
9056
9057 /* addr1 = DA (current AP) */
9058 hwaddr_aton(bssid, pos);
9059 pos += 6;
9060 /* addr2 = SA (own address) */
9061 hwaddr_aton(addr, pos);
9062 pos += 6;
9063 /* addr3 = BSSID (current AP) */
9064 hwaddr_aton(bssid, pos);
9065 pos += 6;
9066
9067 /* Seq# (to be filled by driver/mac80211) */
9068 *pos++ = 0x00;
9069 *pos++ = 0x00;
9070
9071 if (protected == INCORRECT_KEY) {
9072 /* CCMP parameters */
9073 memcpy(pos, "\x61\x01\x00\x20\x00\x10\x00\x00", 8);
9074 pos += 8;
9075 }
9076
9077 if (protected == INCORRECT_KEY) {
9078 switch (frame) {
9079 case DEAUTH:
9080 /* Reason code (encrypted) */
9081 memcpy(pos, "\xa7\x39", 2);
9082 pos += 2;
9083 break;
9084 case DISASSOC:
9085 /* Reason code (encrypted) */
9086 memcpy(pos, "\xa7\x39", 2);
9087 pos += 2;
9088 break;
9089 case SAQUERY:
9090 /* Category|Action|TransID (encrypted) */
9091 memcpy(pos, "\x6f\xbd\xe9\x4d", 4);
9092 pos += 4;
9093 break;
9094 default:
9095 return -1;
9096 }
9097
9098 /* CCMP MIC */
9099 memcpy(pos, "\xc8\xd8\x3b\x06\x5d\xb7\x25\x68", 8);
9100 pos += 8;
9101 } else {
9102 switch (frame) {
9103 case DEAUTH:
9104 /* reason code = 8 */
9105 *pos++ = 0x08;
9106 *pos++ = 0x00;
9107 break;
9108 case DISASSOC:
9109 /* reason code = 8 */
9110 *pos++ = 0x08;
9111 *pos++ = 0x00;
9112 break;
9113 case SAQUERY:
9114 /* Category - SA Query */
9115 *pos++ = 0x08;
9116 /* SA query Action - Request */
9117 *pos++ = 0x00;
9118 /* Transaction ID */
9119 *pos++ = 0x12;
9120 *pos++ = 0x34;
9121 break;
9122 case AUTH:
9123 /* Auth Alg (Open) */
9124 *pos++ = 0x00;
9125 *pos++ = 0x00;
9126 /* Seq# */
9127 *pos++ = 0x01;
9128 *pos++ = 0x00;
9129 /* Status code */
9130 *pos++ = 0x00;
9131 *pos++ = 0x00;
9132 break;
9133 case ASSOCREQ:
9134 /* Capability Information */
9135 *pos++ = 0x31;
9136 *pos++ = 0x04;
9137 /* Listen Interval */
9138 *pos++ = 0x0a;
9139 *pos++ = 0x00;
9140 /* SSID */
9141 *pos++ = 0x00;
9142 *pos++ = ssid_len;
9143 memcpy(pos, ssid, ssid_len);
9144 pos += ssid_len;
9145 /* Supported Rates */
9146 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
9147 10);
9148 pos += 10;
9149 /* Extended Supported Rates */
9150 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
9151 pos += 6;
9152 /* RSN */
9153 memcpy(pos, "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00"
9154 "\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x02\xc0"
9155 "\x00\x00\x00\x00\x0f\xac\x06", 28);
9156 pos += 28;
9157 break;
9158 case REASSOCREQ:
9159 /* Capability Information */
9160 *pos++ = 0x31;
9161 *pos++ = 0x04;
9162 /* Listen Interval */
9163 *pos++ = 0x0a;
9164 *pos++ = 0x00;
9165 /* Current AP */
9166 hwaddr_aton(bssid, pos);
9167 pos += 6;
9168 /* SSID */
9169 *pos++ = 0x00;
9170 *pos++ = ssid_len;
9171 memcpy(pos, ssid, ssid_len);
9172 pos += ssid_len;
9173 /* Supported Rates */
9174 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
9175 10);
9176 pos += 10;
9177 /* Extended Supported Rates */
9178 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
9179 pos += 6;
9180 /* RSN */
9181 memcpy(pos, "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00"
9182 "\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x02\xc0"
9183 "\x00\x00\x00\x00\x0f\xac\x06", 28);
9184 pos += 28;
9185 break;
9186 case DLS_REQ:
9187 /* Category - DLS */
9188 *pos++ = 0x02;
9189 /* DLS Action - Request */
9190 *pos++ = 0x00;
9191 /* Destination MACAddress */
9192 if (dest)
9193 hwaddr_aton(dest, pos);
9194 else
9195 memset(pos, 0, 6);
9196 pos += 6;
9197 /* Source MACAddress */
9198 hwaddr_aton(addr, pos);
9199 pos += 6;
9200 /* Capability Information */
9201 *pos++ = 0x10; /* Privacy */
9202 *pos++ = 0x06; /* QoS */
9203 /* DLS Timeout Value */
9204 *pos++ = 0x00;
9205 *pos++ = 0x01;
9206 /* Supported rates */
9207 *pos++ = 0x01;
9208 *pos++ = 0x08;
9209 *pos++ = 0x0c; /* 6 Mbps */
9210 *pos++ = 0x12; /* 9 Mbps */
9211 *pos++ = 0x18; /* 12 Mbps */
9212 *pos++ = 0x24; /* 18 Mbps */
9213 *pos++ = 0x30; /* 24 Mbps */
9214 *pos++ = 0x48; /* 36 Mbps */
9215 *pos++ = 0x60; /* 48 Mbps */
9216 *pos++ = 0x6c; /* 54 Mbps */
9217 /* TODO: Extended Supported Rates */
9218 /* TODO: HT Capabilities */
9219 break;
9220 }
9221 }
9222
9223 s = open_monitor("sigmadut");
9224 if (s < 0) {
9225 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
9226 "monitor socket");
9227 return 0;
9228 }
9229
9230 res = inject_frame(s, buf, pos - buf, protected == CORRECT_KEY);
9231 if (res < 0) {
9232 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
9233 "inject frame");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05309234 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009235 return 0;
9236 }
9237 if (res < pos - buf) {
9238 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Only partial "
9239 "frame sent");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05309240 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009241 return 0;
9242 }
9243
9244 close(s);
9245
9246 return 1;
9247#else /* __linux__ */
9248 send_resp(dut, conn, SIGMA_ERROR, "errorCode,sta_send_frame not "
9249 "yet supported");
9250 return 0;
9251#endif /* __linux__ */
9252}
9253
9254
9255static int cmd_sta_send_frame_tdls(struct sigma_dut *dut,
9256 struct sigma_conn *conn,
9257 struct sigma_cmd *cmd)
9258{
9259 const char *intf = get_param(cmd, "Interface");
9260 const char *sta, *val;
9261 unsigned char addr[ETH_ALEN];
9262 char buf[100];
9263
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +03009264 if (!intf)
9265 return -1;
9266
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009267 sta = get_param(cmd, "peer");
9268 if (sta == NULL)
9269 sta = get_param(cmd, "station");
9270 if (sta == NULL) {
9271 send_resp(dut, conn, SIGMA_ERROR,
9272 "ErrorCode,Missing peer address");
9273 return 0;
9274 }
9275 if (hwaddr_aton(sta, addr) < 0) {
9276 send_resp(dut, conn, SIGMA_ERROR,
9277 "ErrorCode,Invalid peer address");
9278 return 0;
9279 }
9280
9281 val = get_param(cmd, "type");
9282 if (val == NULL)
9283 return -1;
9284
9285 if (strcasecmp(val, "DISCOVERY") == 0) {
9286 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", sta);
9287 if (wpa_command(intf, buf) < 0) {
9288 send_resp(dut, conn, SIGMA_ERROR,
9289 "ErrorCode,Failed to send TDLS discovery");
9290 return 0;
9291 }
9292 return 1;
9293 }
9294
9295 if (strcasecmp(val, "SETUP") == 0) {
9296 int status = 0, timeout = 0;
9297
9298 val = get_param(cmd, "Status");
9299 if (val)
9300 status = atoi(val);
9301
9302 val = get_param(cmd, "Timeout");
9303 if (val)
9304 timeout = atoi(val);
9305
9306 if (status != 0 && status != 37) {
9307 send_resp(dut, conn, SIGMA_ERROR,
9308 "ErrorCode,Unsupported status value");
9309 return 0;
9310 }
9311
9312 if (timeout != 0 && timeout != 301) {
9313 send_resp(dut, conn, SIGMA_ERROR,
9314 "ErrorCode,Unsupported timeout value");
9315 return 0;
9316 }
9317
9318 if (status && timeout) {
9319 send_resp(dut, conn, SIGMA_ERROR,
9320 "ErrorCode,Unsupported timeout+status "
9321 "combination");
9322 return 0;
9323 }
9324
9325 if (status == 37 &&
9326 wpa_command(intf, "SET tdls_testing 0x200")) {
9327 send_resp(dut, conn, SIGMA_ERROR,
9328 "ErrorCode,Failed to enable "
9329 "decline setup response test mode");
9330 return 0;
9331 }
9332
9333 if (timeout == 301) {
9334 int res;
9335 if (dut->no_tpk_expiration)
9336 res = wpa_command(intf,
9337 "SET tdls_testing 0x108");
9338 else
9339 res = wpa_command(intf,
9340 "SET tdls_testing 0x8");
9341 if (res) {
9342 send_resp(dut, conn, SIGMA_ERROR,
9343 "ErrorCode,Failed to set short TPK "
9344 "lifetime");
9345 return 0;
9346 }
9347 }
9348
9349 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", sta);
9350 if (wpa_command(intf, buf) < 0) {
9351 send_resp(dut, conn, SIGMA_ERROR,
9352 "ErrorCode,Failed to send TDLS setup");
9353 return 0;
9354 }
9355 return 1;
9356 }
9357
9358 if (strcasecmp(val, "TEARDOWN") == 0) {
9359 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", sta);
9360 if (wpa_command(intf, buf) < 0) {
9361 send_resp(dut, conn, SIGMA_ERROR,
9362 "ErrorCode,Failed to send TDLS teardown");
9363 return 0;
9364 }
9365 return 1;
9366 }
9367
9368 send_resp(dut, conn, SIGMA_ERROR,
9369 "ErrorCode,Unsupported TDLS frame");
9370 return 0;
9371}
9372
9373
9374static int sta_ap_known(const char *ifname, const char *bssid)
9375{
9376 char buf[4096];
9377
Jouni Malinendd32f192018-09-15 02:55:19 +03009378 snprintf(buf, sizeof(buf), "BSS MASK=1 %s", bssid);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009379 if (wpa_command_resp(ifname, buf, buf, sizeof(buf)) < 0)
9380 return 0;
9381 if (strncmp(buf, "id=", 3) != 0)
9382 return 0;
9383 return 1;
9384}
9385
9386
9387static int sta_scan_ap(struct sigma_dut *dut, const char *ifname,
9388 const char *bssid)
9389{
9390 int res;
9391 struct wpa_ctrl *ctrl;
9392 char buf[256];
9393
9394 if (sta_ap_known(ifname, bssid))
9395 return 0;
9396 sigma_dut_print(dut, DUT_MSG_DEBUG,
9397 "AP not in BSS table - start scan");
9398
9399 ctrl = open_wpa_mon(ifname);
9400 if (ctrl == NULL) {
9401 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
9402 "wpa_supplicant monitor connection");
9403 return -1;
9404 }
9405
9406 if (wpa_command(ifname, "SCAN") < 0) {
9407 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to start scan");
9408 wpa_ctrl_detach(ctrl);
9409 wpa_ctrl_close(ctrl);
9410 return -1;
9411 }
9412
9413 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
9414 buf, sizeof(buf));
9415
9416 wpa_ctrl_detach(ctrl);
9417 wpa_ctrl_close(ctrl);
9418
9419 if (res < 0) {
9420 sigma_dut_print(dut, DUT_MSG_INFO, "Scan did not complete");
9421 return -1;
9422 }
9423
9424 if (sta_ap_known(ifname, bssid))
9425 return 0;
9426 sigma_dut_print(dut, DUT_MSG_INFO, "AP not in BSS table");
9427 return -1;
9428}
9429
9430
9431static int cmd_sta_send_frame_hs2_neighadv(struct sigma_dut *dut,
9432 struct sigma_conn *conn,
9433 struct sigma_cmd *cmd,
9434 const char *intf)
9435{
9436 char buf[200];
9437
9438 snprintf(buf, sizeof(buf), "ndsend 2001:DB8::1 %s", intf);
9439 if (system(buf) != 0) {
9440 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Failed to run "
9441 "ndsend");
9442 return 0;
9443 }
9444
9445 return 1;
9446}
9447
9448
9449static int cmd_sta_send_frame_hs2_neighsolreq(struct sigma_dut *dut,
9450 struct sigma_conn *conn,
9451 struct sigma_cmd *cmd,
9452 const char *intf)
9453{
9454 char buf[200];
9455 const char *ip = get_param(cmd, "SenderIP");
9456
Peng Xu26b356d2017-10-04 17:58:16 -07009457 if (!ip)
9458 return 0;
9459
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009460 snprintf(buf, sizeof(buf), "ndisc6 -nm %s %s -r 4", ip, intf);
9461 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
9462 if (system(buf) == 0) {
9463 sigma_dut_print(dut, DUT_MSG_INFO,
9464 "Neighbor Solicitation got a response "
9465 "for %s@%s", ip, intf);
9466 }
9467
9468 return 1;
9469}
9470
9471
9472static int cmd_sta_send_frame_hs2_arpprobe(struct sigma_dut *dut,
9473 struct sigma_conn *conn,
9474 struct sigma_cmd *cmd,
9475 const char *ifname)
9476{
9477 char buf[200];
9478 const char *ip = get_param(cmd, "SenderIP");
9479
9480 if (ip == NULL) {
9481 send_resp(dut, conn, SIGMA_ERROR,
9482 "ErrorCode,Missing SenderIP parameter");
9483 return 0;
9484 }
9485 snprintf(buf, sizeof(buf), "arping -I %s -D %s -c 4", ifname, ip);
9486 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
9487 if (system(buf) != 0) {
9488 sigma_dut_print(dut, DUT_MSG_INFO, "arping DAD got a response "
9489 "for %s@%s", ip, ifname);
9490 }
9491
9492 return 1;
9493}
9494
9495
9496static int cmd_sta_send_frame_hs2_arpannounce(struct sigma_dut *dut,
9497 struct sigma_conn *conn,
9498 struct sigma_cmd *cmd,
9499 const char *ifname)
9500{
9501 char buf[200];
9502 char ip[16];
9503 int s;
Peng Xub3756882017-10-04 14:39:09 -07009504 struct ifreq ifr;
9505 struct sockaddr_in saddr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009506
9507 s = socket(PF_INET, SOCK_DGRAM, 0);
Peng Xub3756882017-10-04 14:39:09 -07009508 if (s < 0) {
9509 perror("socket");
9510 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009511 }
9512
Peng Xub3756882017-10-04 14:39:09 -07009513 memset(&ifr, 0, sizeof(ifr));
9514 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
9515 if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
9516 sigma_dut_print(dut, DUT_MSG_INFO,
9517 "Failed to get %s IP address: %s",
9518 ifname, strerror(errno));
9519 close(s);
9520 return -1;
9521 }
9522 close(s);
9523
9524 memcpy(&saddr, &ifr.ifr_addr, sizeof(struct sockaddr_in));
9525 strlcpy(ip, inet_ntoa(saddr.sin_addr), sizeof(ip));
9526
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009527 snprintf(buf, sizeof(buf), "arping -I %s -s %s %s -c 4", ifname, ip,
9528 ip);
9529 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
9530 if (system(buf) != 0) {
9531 }
9532
9533 return 1;
9534}
9535
9536
9537static int cmd_sta_send_frame_hs2_arpreply(struct sigma_dut *dut,
9538 struct sigma_conn *conn,
9539 struct sigma_cmd *cmd,
9540 const char *ifname)
9541{
9542 char buf[200], addr[20];
9543 char dst[ETH_ALEN], src[ETH_ALEN];
9544 short ethtype = htons(ETH_P_ARP);
9545 char *pos;
9546 int s, res;
9547 const char *val;
9548 struct sockaddr_in taddr;
9549
9550 val = get_param(cmd, "dest");
9551 if (val)
9552 hwaddr_aton(val, (unsigned char *) dst);
9553
9554 val = get_param(cmd, "DestIP");
9555 if (val)
9556 inet_aton(val, &taddr.sin_addr);
Peng Xu151c9e12017-10-04 14:39:09 -07009557 else
9558 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009559
9560 if (get_wpa_status(get_station_ifname(), "address", addr,
9561 sizeof(addr)) < 0)
9562 return -2;
9563 hwaddr_aton(addr, (unsigned char *) src);
9564
9565 pos = buf;
9566 *pos++ = 0x00;
9567 *pos++ = 0x01;
9568 *pos++ = 0x08;
9569 *pos++ = 0x00;
9570 *pos++ = 0x06;
9571 *pos++ = 0x04;
9572 *pos++ = 0x00;
9573 *pos++ = 0x02;
9574 memcpy(pos, src, ETH_ALEN);
9575 pos += ETH_ALEN;
9576 memcpy(pos, &taddr.sin_addr, 4);
9577 pos += 4;
9578 memcpy(pos, dst, ETH_ALEN);
9579 pos += ETH_ALEN;
9580 memcpy(pos, &taddr.sin_addr, 4);
9581 pos += 4;
9582
9583 s = open_monitor(get_station_ifname());
9584 if (s < 0) {
9585 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
9586 "monitor socket");
9587 return 0;
9588 }
9589
9590 res = inject_eth_frame(s, buf, pos - buf, ethtype, dst, src);
9591 if (res < 0) {
9592 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
9593 "inject frame");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05309594 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009595 return 0;
9596 }
9597
9598 close(s);
9599
9600 return 1;
9601}
9602
9603
9604static int cmd_sta_send_frame_hs2_dls_req(struct sigma_dut *dut,
9605 struct sigma_conn *conn,
9606 struct sigma_cmd *cmd,
9607 const char *intf, const char *dest)
9608{
9609 char buf[100];
9610
9611 if (if_nametoindex("sigmadut") == 0) {
9612 snprintf(buf, sizeof(buf),
9613 "iw dev %s interface add sigmadut type monitor",
9614 get_station_ifname());
9615 if (system(buf) != 0 ||
9616 if_nametoindex("sigmadut") == 0) {
9617 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
9618 "monitor interface with '%s'", buf);
9619 return -2;
9620 }
9621 }
9622
9623 if (system("ifconfig sigmadut up") != 0) {
9624 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
9625 "monitor interface up");
9626 return -2;
9627 }
9628
9629 return sta_inject_frame(dut, conn, DLS_REQ, UNPROTECTED, dest);
9630}
9631
9632
9633static int cmd_sta_send_frame_hs2(struct sigma_dut *dut,
9634 struct sigma_conn *conn,
9635 struct sigma_cmd *cmd)
9636{
9637 const char *intf = get_param(cmd, "Interface");
9638 const char *dest = get_param(cmd, "Dest");
9639 const char *type = get_param(cmd, "FrameName");
9640 const char *val;
9641 char buf[200], *pos, *end;
9642 int count, count2;
9643
9644 if (type == NULL)
9645 type = get_param(cmd, "Type");
9646
9647 if (intf == NULL || dest == NULL || type == NULL)
9648 return -1;
9649
9650 if (strcasecmp(type, "NeighAdv") == 0)
9651 return cmd_sta_send_frame_hs2_neighadv(dut, conn, cmd, intf);
9652
9653 if (strcasecmp(type, "NeighSolicitReq") == 0)
9654 return cmd_sta_send_frame_hs2_neighsolreq(dut, conn, cmd, intf);
9655
9656 if (strcasecmp(type, "ARPProbe") == 0)
9657 return cmd_sta_send_frame_hs2_arpprobe(dut, conn, cmd, intf);
9658
9659 if (strcasecmp(type, "ARPAnnounce") == 0)
9660 return cmd_sta_send_frame_hs2_arpannounce(dut, conn, cmd, intf);
9661
9662 if (strcasecmp(type, "ARPReply") == 0)
9663 return cmd_sta_send_frame_hs2_arpreply(dut, conn, cmd, intf);
9664
9665 if (strcasecmp(type, "DLS-request") == 0 ||
9666 strcasecmp(type, "DLSrequest") == 0)
9667 return cmd_sta_send_frame_hs2_dls_req(dut, conn, cmd, intf,
9668 dest);
9669
9670 if (strcasecmp(type, "ANQPQuery") != 0 &&
9671 strcasecmp(type, "Query") != 0) {
9672 send_resp(dut, conn, SIGMA_ERROR,
9673 "ErrorCode,Unsupported HS 2.0 send frame type");
9674 return 0;
9675 }
9676
9677 if (sta_scan_ap(dut, intf, dest) < 0) {
9678 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not find "
9679 "the requested AP");
9680 return 0;
9681 }
9682
9683 pos = buf;
9684 end = buf + sizeof(buf);
9685 count = 0;
9686 pos += snprintf(pos, end - pos, "ANQP_GET %s ", dest);
9687
9688 val = get_param(cmd, "ANQP_CAP_LIST");
9689 if (val && atoi(val)) {
9690 pos += snprintf(pos, end - pos, "%s257", count > 0 ? "," : "");
9691 count++;
9692 }
9693
9694 val = get_param(cmd, "VENUE_NAME");
9695 if (val && atoi(val)) {
9696 pos += snprintf(pos, end - pos, "%s258", count > 0 ? "," : "");
9697 count++;
9698 }
9699
9700 val = get_param(cmd, "NETWORK_AUTH_TYPE");
9701 if (val && atoi(val)) {
9702 pos += snprintf(pos, end - pos, "%s260", count > 0 ? "," : "");
9703 count++;
9704 }
9705
9706 val = get_param(cmd, "ROAMING_CONS");
9707 if (val && atoi(val)) {
9708 pos += snprintf(pos, end - pos, "%s261", count > 0 ? "," : "");
9709 count++;
9710 }
9711
9712 val = get_param(cmd, "IP_ADDR_TYPE_AVAILABILITY");
9713 if (val && atoi(val)) {
9714 pos += snprintf(pos, end - pos, "%s262", count > 0 ? "," : "");
9715 count++;
9716 }
9717
9718 val = get_param(cmd, "NAI_REALM_LIST");
9719 if (val && atoi(val)) {
9720 pos += snprintf(pos, end - pos, "%s263", count > 0 ? "," : "");
9721 count++;
9722 }
9723
9724 val = get_param(cmd, "3GPP_INFO");
9725 if (val && atoi(val)) {
9726 pos += snprintf(pos, end - pos, "%s264", count > 0 ? "," : "");
9727 count++;
9728 }
9729
9730 val = get_param(cmd, "DOMAIN_LIST");
9731 if (val && atoi(val)) {
9732 pos += snprintf(pos, end - pos, "%s268", count > 0 ? "," : "");
9733 count++;
9734 }
9735
Jouni Malinen34cf9532018-04-29 19:26:33 +03009736 val = get_param(cmd, "Venue_URL");
9737 if (val && atoi(val)) {
9738 pos += snprintf(pos, end - pos, "%s277", count > 0 ? "," : "");
9739 count++;
9740 }
9741
Jouni Malinend3bca5d2018-04-29 17:25:23 +03009742 val = get_param(cmd, "Advice_Of_Charge");
9743 if (val && atoi(val)) {
9744 pos += snprintf(pos, end - pos, "%s278", count > 0 ? "," : "");
9745 count++;
9746 }
9747
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009748 if (count && wpa_command(intf, buf)) {
9749 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,ANQP_GET failed");
9750 return 0;
9751 }
9752
9753 pos = buf;
9754 end = buf + sizeof(buf);
9755 count2 = 0;
9756 pos += snprintf(pos, end - pos, "HS20_ANQP_GET %s ", dest);
9757
9758 val = get_param(cmd, "HS_CAP_LIST");
9759 if (val && atoi(val)) {
9760 pos += snprintf(pos, end - pos, "%s2", count2 > 0 ? "," : "");
9761 count2++;
9762 }
9763
9764 val = get_param(cmd, "OPER_NAME");
9765 if (val && atoi(val)) {
9766 pos += snprintf(pos, end - pos, "%s3", count2 > 0 ? "," : "");
9767 count2++;
9768 }
9769
9770 val = get_param(cmd, "WAN_METRICS");
9771 if (!val)
9772 val = get_param(cmd, "WAN_MAT");
9773 if (!val)
9774 val = get_param(cmd, "WAN_MET");
9775 if (val && atoi(val)) {
9776 pos += snprintf(pos, end - pos, "%s4", count2 > 0 ? "," : "");
9777 count2++;
9778 }
9779
9780 val = get_param(cmd, "CONNECTION_CAPABILITY");
9781 if (val && atoi(val)) {
9782 pos += snprintf(pos, end - pos, "%s5", count2 > 0 ? "," : "");
9783 count2++;
9784 }
9785
9786 val = get_param(cmd, "OP_CLASS");
9787 if (val && atoi(val)) {
9788 pos += snprintf(pos, end - pos, "%s7", count2 > 0 ? "," : "");
9789 count2++;
9790 }
9791
9792 val = get_param(cmd, "OSU_PROVIDER_LIST");
9793 if (val && atoi(val)) {
9794 pos += snprintf(pos, end - pos, "%s8", count2 > 0 ? "," : "");
9795 count2++;
9796 }
9797
Jouni Malinenf67afec2018-04-29 19:24:58 +03009798 val = get_param(cmd, "OPER_ICON_METADATA");
9799 if (!val)
9800 val = get_param(cmd, "OPERATOR_ICON_METADATA");
9801 if (val && atoi(val)) {
9802 pos += snprintf(pos, end - pos, "%s12", count2 > 0 ? "," : "");
9803 count2++;
9804 }
9805
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009806 if (count && count2) {
9807 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before sending out "
9808 "second query");
9809 sleep(1);
9810 }
9811
9812 if (count2 && wpa_command(intf, buf)) {
9813 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,HS20_ANQP_GET "
9814 "failed");
9815 return 0;
9816 }
9817
9818 val = get_param(cmd, "NAI_HOME_REALM_LIST");
9819 if (val) {
9820 if (count || count2) {
9821 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
9822 "sending out second query");
9823 sleep(1);
9824 }
9825
9826 if (strcmp(val, "1") == 0)
9827 val = "mail.example.com";
9828 snprintf(buf, end - pos,
9829 "HS20_GET_NAI_HOME_REALM_LIST %s realm=%s",
9830 dest, val);
9831 if (wpa_command(intf, buf)) {
9832 send_resp(dut, conn, SIGMA_ERROR,
9833 "ErrorCode,HS20_GET_NAI_HOME_REALM_LIST "
9834 "failed");
9835 return 0;
9836 }
9837 }
9838
9839 val = get_param(cmd, "ICON_REQUEST");
9840 if (val) {
9841 if (count || count2) {
9842 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
9843 "sending out second query");
9844 sleep(1);
9845 }
9846
9847 snprintf(buf, end - pos,
9848 "HS20_ICON_REQUEST %s %s", dest, val);
9849 if (wpa_command(intf, buf)) {
9850 send_resp(dut, conn, SIGMA_ERROR,
9851 "ErrorCode,HS20_ICON_REQUEST failed");
9852 return 0;
9853 }
9854 }
9855
9856 return 1;
9857}
9858
9859
9860static int ath_sta_send_frame_vht(struct sigma_dut *dut,
9861 struct sigma_conn *conn,
9862 struct sigma_cmd *cmd)
9863{
9864 const char *val;
9865 char *ifname;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009866 int chwidth, nss;
9867
9868 val = get_param(cmd, "framename");
9869 if (!val)
9870 return -1;
9871 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
9872
9873 /* Command sequence to generate Op mode notification */
9874 if (val && strcasecmp(val, "Op_md_notif_frm") == 0) {
9875 ifname = get_station_ifname();
9876
9877 /* Disable STBC */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07009878 run_iwpriv(dut, ifname, "tx_stbc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009879
9880 /* Extract Channel width */
9881 val = get_param(cmd, "Channel_width");
9882 if (val) {
9883 switch (atoi(val)) {
9884 case 20:
9885 chwidth = 0;
9886 break;
9887 case 40:
9888 chwidth = 1;
9889 break;
9890 case 80:
9891 chwidth = 2;
9892 break;
9893 case 160:
9894 chwidth = 3;
9895 break;
9896 default:
9897 chwidth = 2;
9898 break;
9899 }
9900
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07009901 run_iwpriv(dut, ifname, "chwidth %d", chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009902 }
9903
9904 /* Extract NSS */
9905 val = get_param(cmd, "NSS");
9906 if (val) {
9907 switch (atoi(val)) {
9908 case 1:
9909 nss = 1;
9910 break;
9911 case 2:
9912 nss = 3;
9913 break;
9914 case 3:
9915 nss = 7;
9916 break;
9917 default:
9918 /* We do not support NSS > 3 */
9919 nss = 3;
9920 break;
9921 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07009922 run_iwpriv(dut, ifname, "rxchainmask %d", nss);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009923 }
9924
9925 /* Opmode notify */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07009926 run_iwpriv(dut, ifname, "opmode_notify 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009927 }
9928
9929 return 1;
9930}
9931
9932
9933static int cmd_sta_send_frame_vht(struct sigma_dut *dut,
9934 struct sigma_conn *conn,
9935 struct sigma_cmd *cmd)
9936{
9937 switch (get_driver_type()) {
9938 case DRIVER_ATHEROS:
9939 return ath_sta_send_frame_vht(dut, conn, cmd);
9940 default:
9941 send_resp(dut, conn, SIGMA_ERROR,
9942 "errorCode,Unsupported sta_set_frame(VHT) with the current driver");
9943 return 0;
9944 }
9945}
9946
9947
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07009948static int wcn_sta_send_frame_he(struct sigma_dut *dut, struct sigma_conn *conn,
9949 struct sigma_cmd *cmd)
9950{
9951 const char *val;
9952 const char *intf = get_param(cmd, "Interface");
9953
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +03009954 if (!intf)
9955 return -1;
9956
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07009957 val = get_param(cmd, "framename");
9958 if (!val)
9959 return -1;
9960 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
9961
9962 /* Command sequence to generate Op mode notification */
9963 if (val && strcasecmp(val, "action") == 0) {
9964 val = get_param(cmd, "PPDUTxType");
9965 if (val && strcasecmp(val, "TB") == 0) {
9966 if (sta_set_action_tx_in_he_tb_ppdu(dut, intf, 1)) {
9967 sigma_dut_print(dut, DUT_MSG_ERROR,
9968 "failed to send TB PPDU Tx cfg");
9969 send_resp(dut, conn, SIGMA_ERROR,
9970 "ErrorCode,set TB PPDU Tx cfg failed");
9971 return 0;
9972 }
9973 return 1;
9974 }
9975
9976 sigma_dut_print(dut, DUT_MSG_ERROR,
9977 "Action Tx type is not defined");
9978 }
9979
9980 return 1;
9981}
9982
9983
9984static int cmd_sta_send_frame_he(struct sigma_dut *dut,
9985 struct sigma_conn *conn,
9986 struct sigma_cmd *cmd)
9987{
9988 switch (get_driver_type()) {
9989 case DRIVER_WCN:
9990 return wcn_sta_send_frame_he(dut, conn, cmd);
9991 default:
9992 send_resp(dut, conn, SIGMA_ERROR,
9993 "errorCode,Unsupported sta_set_frame(HE) with the current driver");
9994 return 0;
9995 }
9996}
9997
9998
Lior David0fe101e2017-03-09 16:09:50 +02009999#ifdef __linux__
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030010000
10001static int
10002wil6210_send_p2p_frame_60g(struct sigma_dut *dut, struct sigma_cmd *cmd,
10003 const char *frame_name, const char *dest_mac)
10004{
10005 int isprobereq = strcasecmp(frame_name, "probereq") == 0;
10006 const char *ssid = get_param(cmd, "ssid");
10007 const char *countstr = get_param(cmd, "count");
10008 const char *channelstr = get_param(cmd, "channel");
10009 const char *group_id = get_param(cmd, "groupid");
10010 const char *client_id = get_param(cmd, "clientmac");
10011 int count, channel, freq, i;
10012 const char *fname;
10013 char frame[1024], src_mac[20], group_id_attr[25],
10014 device_macstr[3 * ETH_ALEN], client_mac[ETH_ALEN];
10015 const char *group_ssid;
10016 const int group_ssid_prefix_len = 9;
10017 struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *) frame;
10018 size_t framelen = sizeof(frame);
10019 struct template_frame_tag tags[2];
10020 size_t tags_total = ARRAY_SIZE(tags);
10021 int tag_index, len, dst_len;
10022
10023 if (!countstr || !channelstr) {
10024 sigma_dut_print(dut, DUT_MSG_ERROR,
10025 "Missing argument: count, channel");
10026 return -1;
10027 }
10028 if (isprobereq && !ssid) {
10029 sigma_dut_print(dut, DUT_MSG_ERROR,
10030 "Missing argument: ssid");
10031 return -1;
10032 }
10033 if (!isprobereq && (!group_id || !client_id)) {
10034 sigma_dut_print(dut, DUT_MSG_ERROR,
10035 "Missing argument: group_id, client_id");
10036 return -1;
10037 }
10038
10039 count = atoi(countstr);
10040 channel = atoi(channelstr);
10041 freq = channel_to_freq(dut, channel);
10042
10043 if (!freq) {
10044 sigma_dut_print(dut, DUT_MSG_ERROR,
10045 "invalid channel: %s", channelstr);
10046 return -1;
10047 }
10048
10049 if (isprobereq) {
10050 if (strcasecmp(ssid, "wildcard") == 0) {
10051 fname = "probe_req_wildcard.txt";
10052 } else if (strcasecmp(ssid, "P2P_Wildcard") == 0) {
10053 fname = "probe_req_P2P_Wildcard.txt";
10054 } else {
10055 sigma_dut_print(dut, DUT_MSG_ERROR,
10056 "invalid probe request type");
10057 return -1;
10058 }
10059 } else {
10060 fname = "P2P_device_discovery_req.txt";
10061 }
10062
10063 if (parse_template_frame_file(dut, fname, frame, &framelen,
10064 tags, &tags_total)) {
10065 sigma_dut_print(dut, DUT_MSG_ERROR,
10066 "invalid frame template: %s", fname);
10067 return -1;
10068 }
10069
10070 if (get_wpa_status(get_station_ifname(), "address",
10071 src_mac, sizeof(src_mac)) < 0 ||
10072 parse_mac_address(dut, src_mac, &hdr->addr2[0]) ||
10073 parse_mac_address(dut, dest_mac, &hdr->addr1[0]))
10074 return -1;
10075 /* Use wildcard BSSID, since we are in PBSS */
10076 memset(&hdr->addr3, 0xFF, ETH_ALEN);
10077
10078 if (!isprobereq) {
10079 tag_index = find_template_frame_tag(tags, tags_total, 1);
10080 if (tag_index < 0) {
10081 sigma_dut_print(dut, DUT_MSG_ERROR,
10082 "can't find device id attribute");
10083 return -1;
10084 }
10085 if (parse_mac_address(dut, client_id,
10086 (unsigned char *) client_mac)) {
10087 sigma_dut_print(dut, DUT_MSG_ERROR,
10088 "invalid client_id: %s", client_id);
10089 return -1;
10090 }
10091 if (replace_p2p_attribute(dut, &frame[tags[tag_index].offset],
10092 framelen - tags[tag_index].offset,
10093 IEEE80211_P2P_ATTR_DEVICE_ID,
10094 client_mac, ETH_ALEN)) {
10095 sigma_dut_print(dut, DUT_MSG_ERROR,
10096 "fail to replace device id attribute");
10097 return -1;
10098 }
10099
10100 /*
10101 * group_id arg contains device MAC address followed by
10102 * space and SSID (DIRECT-somessid).
10103 * group id attribute contains device address (6 bytes)
10104 * followed by SSID prefix DIRECT-XX (9 bytes)
10105 */
10106 if (strlen(group_id) < sizeof(device_macstr)) {
10107 sigma_dut_print(dut, DUT_MSG_ERROR,
10108 "group_id arg too short");
10109 return -1;
10110 }
10111 memcpy(device_macstr, group_id, sizeof(device_macstr));
10112 device_macstr[sizeof(device_macstr) - 1] = '\0';
10113 if (parse_mac_address(dut, device_macstr,
10114 (unsigned char *) group_id_attr)) {
10115 sigma_dut_print(dut, DUT_MSG_ERROR,
10116 "fail to parse device address from group_id");
10117 return -1;
10118 }
10119 group_ssid = strchr(group_id, ' ');
10120 if (!group_ssid) {
10121 sigma_dut_print(dut, DUT_MSG_ERROR,
10122 "invalid group_id arg, no ssid");
10123 return -1;
10124 }
10125 group_ssid++;
10126 len = strlen(group_ssid);
10127 if (len < group_ssid_prefix_len) {
10128 sigma_dut_print(dut, DUT_MSG_ERROR,
10129 "group_id SSID too short");
10130 return -1;
10131 }
10132 dst_len = sizeof(group_id_attr) - ETH_ALEN;
10133 if (len > dst_len) {
10134 sigma_dut_print(dut, DUT_MSG_ERROR,
10135 "group_id SSID (%s) too long",
10136 group_ssid);
10137 return -1;
10138 }
10139
10140 memcpy(group_id_attr + ETH_ALEN, group_ssid, len);
10141 tag_index = find_template_frame_tag(tags, tags_total, 2);
10142 if (tag_index < 0) {
10143 sigma_dut_print(dut, DUT_MSG_ERROR,
10144 "can't find group id attribute");
10145 return -1;
10146 }
10147 if (replace_p2p_attribute(dut, &frame[tags[tag_index].offset],
10148 framelen - tags[tag_index].offset,
10149 IEEE80211_P2P_ATTR_GROUP_ID,
10150 group_id_attr,
10151 sizeof(group_id_attr))) {
10152 sigma_dut_print(dut, DUT_MSG_ERROR,
10153 "fail to replace group id attribute");
10154 return -1;
10155 }
10156 }
10157
10158 for (i = 0; i < count; i++) {
10159 if (wil6210_transmit_frame(dut, freq,
10160 WIL_TRANSMIT_FRAME_DEFAULT_ROC,
10161 frame, framelen)) {
10162 sigma_dut_print(dut, DUT_MSG_ERROR,
10163 "fail to transmit probe request frame");
10164 return -1;
10165 }
10166 }
10167
10168 return 0;
10169}
10170
10171
Lior David0fe101e2017-03-09 16:09:50 +020010172int wil6210_send_frame_60g(struct sigma_dut *dut, struct sigma_conn *conn,
10173 struct sigma_cmd *cmd)
10174{
10175 const char *frame_name = get_param(cmd, "framename");
10176 const char *mac = get_param(cmd, "dest_mac");
10177
10178 if (!frame_name || !mac) {
10179 sigma_dut_print(dut, DUT_MSG_ERROR,
10180 "framename and dest_mac must be provided");
10181 return -1;
10182 }
10183
10184 if (strcasecmp(frame_name, "brp") == 0) {
10185 const char *l_rx = get_param(cmd, "L-RX");
10186 int l_rx_i;
10187
10188 if (!l_rx) {
10189 sigma_dut_print(dut, DUT_MSG_ERROR,
10190 "L-RX must be provided");
10191 return -1;
10192 }
10193 l_rx_i = atoi(l_rx);
10194
10195 sigma_dut_print(dut, DUT_MSG_INFO,
10196 "dev_send_frame: BRP-RX, dest_mac %s, L-RX %s",
10197 mac, l_rx);
10198 if (l_rx_i != 16) {
10199 sigma_dut_print(dut, DUT_MSG_ERROR,
10200 "unsupported L-RX: %s", l_rx);
10201 return -1;
10202 }
10203
10204 if (wil6210_send_brp_rx(dut, mac, l_rx_i))
10205 return -1;
10206 } else if (strcasecmp(frame_name, "ssw") == 0) {
10207 sigma_dut_print(dut, DUT_MSG_INFO,
10208 "dev_send_frame: SLS, dest_mac %s", mac);
10209 if (wil6210_send_sls(dut, mac))
10210 return -1;
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030010211 } else if ((strcasecmp(frame_name, "probereq") == 0) ||
10212 (strcasecmp(frame_name, "devdiscreq") == 0)) {
10213 sigma_dut_print(dut, DUT_MSG_INFO,
10214 "dev_send_frame: %s, dest_mac %s", frame_name,
10215 mac);
10216 if (wil6210_send_p2p_frame_60g(dut, cmd, frame_name, mac))
10217 return -1;
Lior David0fe101e2017-03-09 16:09:50 +020010218 } else {
10219 sigma_dut_print(dut, DUT_MSG_ERROR,
10220 "unsupported frame type: %s", frame_name);
10221 return -1;
10222 }
10223
10224 return 1;
10225}
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030010226
Lior David0fe101e2017-03-09 16:09:50 +020010227#endif /* __linux__ */
10228
10229
10230static int cmd_sta_send_frame_60g(struct sigma_dut *dut,
10231 struct sigma_conn *conn,
10232 struct sigma_cmd *cmd)
10233{
10234 switch (get_driver_type()) {
10235#ifdef __linux__
10236 case DRIVER_WIL6210:
10237 return wil6210_send_frame_60g(dut, conn, cmd);
10238#endif /* __linux__ */
10239 default:
10240 send_resp(dut, conn, SIGMA_ERROR,
10241 "errorCode,Unsupported sta_set_frame(60G) with the current driver");
10242 return 0;
10243 }
10244}
10245
10246
Ashwini Patildb59b3c2017-04-13 15:19:23 +053010247static int mbo_send_anqp_query(struct sigma_dut *dut, struct sigma_conn *conn,
10248 const char *intf, struct sigma_cmd *cmd)
10249{
10250 const char *val, *addr;
10251 char buf[100];
10252
10253 addr = get_param(cmd, "DestMac");
10254 if (!addr) {
10255 send_resp(dut, conn, SIGMA_INVALID,
10256 "ErrorCode,AP MAC address is missing");
10257 return 0;
10258 }
10259
10260 val = get_param(cmd, "ANQPQuery_ID");
10261 if (!val) {
10262 send_resp(dut, conn, SIGMA_INVALID,
10263 "ErrorCode,Missing ANQPQuery_ID");
10264 return 0;
10265 }
10266
10267 if (strcasecmp(val, "NeighborReportReq") == 0) {
10268 snprintf(buf, sizeof(buf), "ANQP_GET %s 272", addr);
10269 } else if (strcasecmp(val, "QueryListWithCellPref") == 0) {
10270 snprintf(buf, sizeof(buf), "ANQP_GET %s 272,mbo:2", addr);
10271 } else {
10272 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid ANQPQuery_ID: %s",
10273 val);
10274 send_resp(dut, conn, SIGMA_INVALID,
10275 "ErrorCode,Invalid ANQPQuery_ID");
10276 return 0;
10277 }
10278
Ashwini Patild174f2c2017-04-13 16:49:46 +053010279 /* Set gas_address3 field to IEEE 802.11-2012 standard compliant form
10280 * (Address3 = Wildcard BSSID when sent to not-associated AP;
10281 * if associated, AP BSSID).
10282 */
10283 if (wpa_command(intf, "SET gas_address3 1") < 0) {
10284 send_resp(dut, conn, SIGMA_ERROR,
10285 "ErrorCode,Failed to set gas_address3");
10286 return 0;
10287 }
10288
Ashwini Patildb59b3c2017-04-13 15:19:23 +053010289 if (wpa_command(intf, buf) < 0) {
10290 send_resp(dut, conn, SIGMA_ERROR,
10291 "ErrorCode,Failed to send ANQP query");
10292 return 0;
10293 }
10294
10295 return 1;
10296}
10297
10298
10299static int mbo_cmd_sta_send_frame(struct sigma_dut *dut,
10300 struct sigma_conn *conn,
10301 const char *intf,
10302 struct sigma_cmd *cmd)
10303{
10304 const char *val = get_param(cmd, "FrameName");
10305
10306 if (val && strcasecmp(val, "ANQPQuery") == 0)
10307 return mbo_send_anqp_query(dut, conn, intf, cmd);
10308
10309 return 2;
10310}
10311
10312
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010313int cmd_sta_send_frame(struct sigma_dut *dut, struct sigma_conn *conn,
10314 struct sigma_cmd *cmd)
10315{
10316 const char *intf = get_param(cmd, "Interface");
10317 const char *val;
10318 enum send_frame_type frame;
10319 enum send_frame_protection protected;
10320 char buf[100];
10321 unsigned char addr[ETH_ALEN];
10322 int res;
10323
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +030010324 if (!intf)
10325 return -1;
10326
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010327 val = get_param(cmd, "program");
10328 if (val == NULL)
10329 val = get_param(cmd, "frame");
10330 if (val && strcasecmp(val, "TDLS") == 0)
10331 return cmd_sta_send_frame_tdls(dut, conn, cmd);
10332 if (val && (strcasecmp(val, "HS2") == 0 ||
Jouni Malinen1f6ae642018-06-07 23:56:13 +030010333 strcasecmp(val, "HS2-R2") == 0 ||
10334 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010335 return cmd_sta_send_frame_hs2(dut, conn, cmd);
10336 if (val && strcasecmp(val, "VHT") == 0)
10337 return cmd_sta_send_frame_vht(dut, conn, cmd);
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070010338 if (val && strcasecmp(val, "HE") == 0)
10339 return cmd_sta_send_frame_he(dut, conn, cmd);
priyadharshini gowthamand66913a2016-07-29 15:11:17 -070010340 if (val && strcasecmp(val, "LOC") == 0)
10341 return loc_cmd_sta_send_frame(dut, conn, cmd);
Lior David0fe101e2017-03-09 16:09:50 +020010342 if (val && strcasecmp(val, "60GHz") == 0)
10343 return cmd_sta_send_frame_60g(dut, conn, cmd);
Ashwini Patildb59b3c2017-04-13 15:19:23 +053010344 if (val && strcasecmp(val, "MBO") == 0) {
10345 res = mbo_cmd_sta_send_frame(dut, conn, intf, cmd);
10346 if (res != 2)
10347 return res;
10348 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010349
10350 val = get_param(cmd, "TD_DISC");
10351 if (val) {
10352 if (hwaddr_aton(val, addr) < 0)
10353 return -1;
10354 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", val);
10355 if (wpa_command(intf, buf) < 0) {
10356 send_resp(dut, conn, SIGMA_ERROR,
10357 "ErrorCode,Failed to send TDLS discovery");
10358 return 0;
10359 }
10360 return 1;
10361 }
10362
10363 val = get_param(cmd, "TD_Setup");
10364 if (val) {
10365 if (hwaddr_aton(val, addr) < 0)
10366 return -1;
10367 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", val);
10368 if (wpa_command(intf, buf) < 0) {
10369 send_resp(dut, conn, SIGMA_ERROR,
10370 "ErrorCode,Failed to start TDLS setup");
10371 return 0;
10372 }
10373 return 1;
10374 }
10375
10376 val = get_param(cmd, "TD_TearDown");
10377 if (val) {
10378 if (hwaddr_aton(val, addr) < 0)
10379 return -1;
10380 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", val);
10381 if (wpa_command(intf, buf) < 0) {
10382 send_resp(dut, conn, SIGMA_ERROR,
10383 "ErrorCode,Failed to tear down TDLS link");
10384 return 0;
10385 }
10386 return 1;
10387 }
10388
10389 val = get_param(cmd, "TD_ChannelSwitch");
10390 if (val) {
10391 /* TODO */
10392 send_resp(dut, conn, SIGMA_ERROR,
10393 "ErrorCode,TD_ChannelSwitch not yet supported");
10394 return 0;
10395 }
10396
10397 val = get_param(cmd, "TD_NF");
10398 if (val) {
10399 /* TODO */
10400 send_resp(dut, conn, SIGMA_ERROR,
10401 "ErrorCode,TD_NF not yet supported");
10402 return 0;
10403 }
10404
10405 val = get_param(cmd, "PMFFrameType");
10406 if (val == NULL)
10407 val = get_param(cmd, "FrameName");
10408 if (val == NULL)
10409 val = get_param(cmd, "Type");
10410 if (val == NULL)
10411 return -1;
10412 if (strcasecmp(val, "disassoc") == 0)
10413 frame = DISASSOC;
10414 else if (strcasecmp(val, "deauth") == 0)
10415 frame = DEAUTH;
10416 else if (strcasecmp(val, "saquery") == 0)
10417 frame = SAQUERY;
10418 else if (strcasecmp(val, "auth") == 0)
10419 frame = AUTH;
10420 else if (strcasecmp(val, "assocreq") == 0)
10421 frame = ASSOCREQ;
10422 else if (strcasecmp(val, "reassocreq") == 0)
10423 frame = REASSOCREQ;
10424 else if (strcasecmp(val, "neigreq") == 0) {
10425 sigma_dut_print(dut, DUT_MSG_INFO, "Got neighbor request");
10426
10427 val = get_param(cmd, "ssid");
10428 if (val == NULL)
10429 return -1;
10430
10431 res = send_neighbor_request(dut, intf, val);
10432 if (res) {
10433 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
10434 "Failed to send neighbor report request");
10435 return 0;
10436 }
10437
10438 return 1;
Ashwini Patil5acd7382017-04-13 15:55:04 +053010439 } else if (strcasecmp(val, "transmgmtquery") == 0 ||
10440 strcasecmp(val, "BTMQuery") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010441 sigma_dut_print(dut, DUT_MSG_DEBUG,
10442 "Got Transition Management Query");
10443
Ashwini Patil5acd7382017-04-13 15:55:04 +053010444 res = send_trans_mgmt_query(dut, intf, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010445 if (res) {
10446 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
10447 "Failed to send Transition Management Query");
10448 return 0;
10449 }
10450
10451 return 1;
10452 } else {
10453 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
10454 "PMFFrameType");
10455 return 0;
10456 }
10457
10458 val = get_param(cmd, "PMFProtected");
10459 if (val == NULL)
10460 val = get_param(cmd, "Protected");
10461 if (val == NULL)
10462 return -1;
10463 if (strcasecmp(val, "Correct-key") == 0 ||
10464 strcasecmp(val, "CorrectKey") == 0)
10465 protected = CORRECT_KEY;
10466 else if (strcasecmp(val, "IncorrectKey") == 0)
10467 protected = INCORRECT_KEY;
10468 else if (strcasecmp(val, "Unprotected") == 0)
10469 protected = UNPROTECTED;
10470 else {
10471 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
10472 "PMFProtected");
10473 return 0;
10474 }
10475
10476 if (protected != UNPROTECTED &&
10477 (frame == AUTH || frame == ASSOCREQ || frame == REASSOCREQ)) {
10478 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Impossible "
10479 "PMFProtected for auth/assocreq/reassocreq");
10480 return 0;
10481 }
10482
10483 if (if_nametoindex("sigmadut") == 0) {
10484 snprintf(buf, sizeof(buf),
10485 "iw dev %s interface add sigmadut type monitor",
10486 get_station_ifname());
10487 if (system(buf) != 0 ||
10488 if_nametoindex("sigmadut") == 0) {
10489 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
10490 "monitor interface with '%s'", buf);
10491 return -2;
10492 }
10493 }
10494
10495 if (system("ifconfig sigmadut up") != 0) {
10496 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
10497 "monitor interface up");
10498 return -2;
10499 }
10500
10501 return sta_inject_frame(dut, conn, frame, protected, NULL);
10502}
10503
10504
10505static int cmd_sta_set_parameter_hs2(struct sigma_dut *dut,
10506 struct sigma_conn *conn,
10507 struct sigma_cmd *cmd,
10508 const char *ifname)
10509{
10510 char buf[200];
10511 const char *val;
10512
10513 val = get_param(cmd, "ClearARP");
10514 if (val && atoi(val) == 1) {
10515 snprintf(buf, sizeof(buf), "ip neigh flush dev %s", ifname);
10516 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10517 if (system(buf) != 0) {
10518 send_resp(dut, conn, SIGMA_ERROR,
10519 "errorCode,Failed to clear ARP cache");
10520 return 0;
10521 }
10522 }
10523
10524 return 1;
10525}
10526
10527
10528int cmd_sta_set_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
10529 struct sigma_cmd *cmd)
10530{
10531 const char *intf = get_param(cmd, "Interface");
10532 const char *val;
10533
10534 if (intf == NULL)
10535 return -1;
10536
10537 val = get_param(cmd, "program");
10538 if (val && (strcasecmp(val, "HS2") == 0 ||
Jouni Malinen1f6ae642018-06-07 23:56:13 +030010539 strcasecmp(val, "HS2-R2") == 0 ||
10540 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010541 return cmd_sta_set_parameter_hs2(dut, conn, cmd, intf);
10542
10543 return -1;
10544}
10545
10546
10547static int cmd_sta_set_macaddr(struct sigma_dut *dut, struct sigma_conn *conn,
10548 struct sigma_cmd *cmd)
10549{
10550 const char *intf = get_param(cmd, "Interface");
10551 const char *mac = get_param(cmd, "MAC");
10552
10553 if (intf == NULL || mac == NULL)
10554 return -1;
10555
10556 sigma_dut_print(dut, DUT_MSG_INFO, "Change local MAC address for "
10557 "interface %s to %s", intf, mac);
10558
10559 if (dut->set_macaddr) {
10560 char buf[128];
10561 int res;
10562 if (strcasecmp(mac, "default") == 0) {
10563 res = snprintf(buf, sizeof(buf), "%s",
10564 dut->set_macaddr);
10565 dut->tmp_mac_addr = 0;
10566 } else {
10567 res = snprintf(buf, sizeof(buf), "%s %s",
10568 dut->set_macaddr, mac);
10569 dut->tmp_mac_addr = 1;
10570 }
10571 if (res < 0 || res >= (int) sizeof(buf))
10572 return -1;
10573 if (system(buf) != 0) {
10574 send_resp(dut, conn, SIGMA_ERROR,
10575 "errorCode,Failed to set MAC "
10576 "address");
10577 return 0;
10578 }
10579 return 1;
10580 }
10581
10582 if (strcasecmp(mac, "default") == 0)
10583 return 1;
10584
10585 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
10586 "command");
10587 return 0;
10588}
10589
10590
10591static int iwpriv_tdlsoffchnmode(struct sigma_dut *dut,
10592 struct sigma_conn *conn, const char *intf,
10593 int val)
10594{
10595 char buf[200];
10596 int res;
10597
10598 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchnmode %d",
10599 intf, val);
10600 if (res < 0 || res >= (int) sizeof(buf))
10601 return -1;
10602 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10603 if (system(buf) != 0) {
10604 send_resp(dut, conn, SIGMA_ERROR,
10605 "errorCode,Failed to configure offchannel mode");
10606 return 0;
10607 }
10608
10609 return 1;
10610}
10611
10612
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010613static int off_chan_val(enum sec_ch_offset off)
10614{
10615 switch (off) {
10616 case SEC_CH_NO:
10617 return 0;
10618 case SEC_CH_40ABOVE:
10619 return 40;
10620 case SEC_CH_40BELOW:
10621 return -40;
10622 }
10623
10624 return 0;
10625}
10626
10627
10628static int iwpriv_set_offchan(struct sigma_dut *dut, struct sigma_conn *conn,
10629 const char *intf, int off_ch_num,
10630 enum sec_ch_offset sec)
10631{
10632 char buf[200];
10633 int res;
10634
10635 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchan %d",
10636 intf, off_ch_num);
10637 if (res < 0 || res >= (int) sizeof(buf))
10638 return -1;
10639 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10640 if (system(buf) != 0) {
10641 send_resp(dut, conn, SIGMA_ERROR,
10642 "errorCode,Failed to set offchan");
10643 return 0;
10644 }
10645
10646 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsecchnoffst %d",
10647 intf, off_chan_val(sec));
10648 if (res < 0 || res >= (int) sizeof(buf))
10649 return -1;
10650 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10651 if (system(buf) != 0) {
10652 send_resp(dut, conn, SIGMA_ERROR,
10653 "errorCode,Failed to set sec chan offset");
10654 return 0;
10655 }
10656
10657 return 1;
10658}
10659
10660
10661static int tdls_set_offchannel_offset(struct sigma_dut *dut,
10662 struct sigma_conn *conn,
10663 const char *intf, int off_ch_num,
10664 enum sec_ch_offset sec)
10665{
10666 char buf[200];
10667 int res;
10668
10669 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNEL %d",
10670 off_ch_num);
10671 if (res < 0 || res >= (int) sizeof(buf))
10672 return -1;
10673 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10674
10675 if (wpa_command(intf, buf) < 0) {
10676 send_resp(dut, conn, SIGMA_ERROR,
10677 "ErrorCode,Failed to set offchan");
10678 return 0;
10679 }
10680 res = snprintf(buf, sizeof(buf), "DRIVER TDLSSECONDARYCHANNELOFFSET %d",
10681 off_chan_val(sec));
10682 if (res < 0 || res >= (int) sizeof(buf))
10683 return -1;
10684
10685 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10686
10687 if (wpa_command(intf, buf) < 0) {
10688 send_resp(dut, conn, SIGMA_ERROR,
10689 "ErrorCode,Failed to set sec chan offset");
10690 return 0;
10691 }
10692
10693 return 1;
10694}
10695
10696
10697static int tdls_set_offchannel_mode(struct sigma_dut *dut,
10698 struct sigma_conn *conn,
10699 const char *intf, int val)
10700{
10701 char buf[200];
10702 int res;
10703
10704 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNELMODE %d",
10705 val);
10706 if (res < 0 || res >= (int) sizeof(buf))
10707 return -1;
10708 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10709
10710 if (wpa_command(intf, buf) < 0) {
10711 send_resp(dut, conn, SIGMA_ERROR,
10712 "ErrorCode,Failed to configure offchannel mode");
10713 return 0;
10714 }
10715
10716 return 1;
10717}
10718
10719
10720static int cmd_sta_set_rfeature_tdls(const char *intf, struct sigma_dut *dut,
10721 struct sigma_conn *conn,
10722 struct sigma_cmd *cmd)
10723{
10724 const char *val;
10725 enum {
10726 CHSM_NOT_SET,
10727 CHSM_ENABLE,
10728 CHSM_DISABLE,
10729 CHSM_REJREQ,
10730 CHSM_UNSOLRESP
10731 } chsm = CHSM_NOT_SET;
10732 int off_ch_num = -1;
10733 enum sec_ch_offset sec_ch = SEC_CH_NO;
10734 int res;
10735
10736 val = get_param(cmd, "Uapsd");
10737 if (val) {
10738 char buf[100];
10739 if (strcasecmp(val, "Enable") == 0)
10740 snprintf(buf, sizeof(buf), "SET ps 99");
10741 else if (strcasecmp(val, "Disable") == 0)
10742 snprintf(buf, sizeof(buf), "SET ps 98");
10743 else {
10744 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
10745 "Unsupported uapsd parameter value");
10746 return 0;
10747 }
10748 if (wpa_command(intf, buf)) {
10749 send_resp(dut, conn, SIGMA_ERROR,
10750 "ErrorCode,Failed to change U-APSD "
10751 "powersave mode");
10752 return 0;
10753 }
10754 }
10755
10756 val = get_param(cmd, "TPKTIMER");
10757 if (val && strcasecmp(val, "DISABLE") == 0) {
10758 if (wpa_command(intf, "SET tdls_testing 0x100")) {
10759 send_resp(dut, conn, SIGMA_ERROR,
10760 "ErrorCode,Failed to enable no TPK "
10761 "expiration test mode");
10762 return 0;
10763 }
10764 dut->no_tpk_expiration = 1;
10765 }
10766
10767 val = get_param(cmd, "ChSwitchMode");
10768 if (val) {
10769 if (strcasecmp(val, "Enable") == 0 ||
10770 strcasecmp(val, "Initiate") == 0)
10771 chsm = CHSM_ENABLE;
10772 else if (strcasecmp(val, "Disable") == 0 ||
10773 strcasecmp(val, "passive") == 0)
10774 chsm = CHSM_DISABLE;
10775 else if (strcasecmp(val, "RejReq") == 0)
10776 chsm = CHSM_REJREQ;
10777 else if (strcasecmp(val, "UnSolResp") == 0)
10778 chsm = CHSM_UNSOLRESP;
10779 else {
10780 send_resp(dut, conn, SIGMA_ERROR,
10781 "ErrorCode,Unknown ChSwitchMode value");
10782 return 0;
10783 }
10784 }
10785
10786 val = get_param(cmd, "OffChNum");
10787 if (val) {
10788 off_ch_num = atoi(val);
10789 if (off_ch_num == 0) {
10790 send_resp(dut, conn, SIGMA_ERROR,
10791 "ErrorCode,Invalid OffChNum");
10792 return 0;
10793 }
10794 }
10795
10796 val = get_param(cmd, "SecChOffset");
10797 if (val) {
10798 if (strcmp(val, "20") == 0)
10799 sec_ch = SEC_CH_NO;
10800 else if (strcasecmp(val, "40above") == 0)
10801 sec_ch = SEC_CH_40ABOVE;
10802 else if (strcasecmp(val, "40below") == 0)
10803 sec_ch = SEC_CH_40BELOW;
10804 else {
10805 send_resp(dut, conn, SIGMA_ERROR,
10806 "ErrorCode,Unknown SecChOffset value");
10807 return 0;
10808 }
10809 }
10810
10811 if (chsm == CHSM_NOT_SET) {
10812 /* no offchannel changes requested */
10813 return 1;
10814 }
10815
10816 if (strcmp(intf, get_main_ifname()) != 0 &&
10817 strcmp(intf, get_station_ifname()) != 0) {
10818 send_resp(dut, conn, SIGMA_ERROR,
10819 "ErrorCode,Unknown interface");
10820 return 0;
10821 }
10822
10823 switch (chsm) {
10824 case CHSM_NOT_SET:
Jouni Malinen280f5ba2016-08-29 21:33:10 +030010825 res = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010826 break;
10827 case CHSM_ENABLE:
10828 if (off_ch_num < 0) {
10829 send_resp(dut, conn, SIGMA_ERROR,
10830 "ErrorCode,Missing OffChNum argument");
10831 return 0;
10832 }
10833 if (wifi_chip_type == DRIVER_WCN) {
10834 res = tdls_set_offchannel_offset(dut, conn, intf,
10835 off_ch_num, sec_ch);
10836 } else {
10837 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
10838 sec_ch);
10839 }
10840 if (res != 1)
10841 return res;
10842 if (wifi_chip_type == DRIVER_WCN)
10843 res = tdls_set_offchannel_mode(dut, conn, intf, 1);
10844 else
10845 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 1);
10846 break;
10847 case CHSM_DISABLE:
10848 if (wifi_chip_type == DRIVER_WCN)
10849 res = tdls_set_offchannel_mode(dut, conn, intf, 2);
10850 else
10851 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 2);
10852 break;
10853 case CHSM_REJREQ:
10854 if (wifi_chip_type == DRIVER_WCN)
10855 res = tdls_set_offchannel_mode(dut, conn, intf, 3);
10856 else
10857 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 3);
10858 break;
10859 case CHSM_UNSOLRESP:
10860 if (off_ch_num < 0) {
10861 send_resp(dut, conn, SIGMA_ERROR,
10862 "ErrorCode,Missing OffChNum argument");
10863 return 0;
10864 }
10865 if (wifi_chip_type == DRIVER_WCN) {
10866 res = tdls_set_offchannel_offset(dut, conn, intf,
10867 off_ch_num, sec_ch);
10868 } else {
10869 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
10870 sec_ch);
10871 }
10872 if (res != 1)
10873 return res;
10874 if (wifi_chip_type == DRIVER_WCN)
10875 res = tdls_set_offchannel_mode(dut, conn, intf, 4);
10876 else
10877 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 4);
10878 break;
10879 }
10880
10881 return res;
10882}
10883
10884
10885static int ath_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
10886 struct sigma_conn *conn,
10887 struct sigma_cmd *cmd)
10888{
10889 const char *val;
Srikanth Marepalli5415acf2018-08-27 12:53:11 +053010890 char *token = NULL, *result;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010891
priyadharshini gowthamane5e25172015-12-08 14:53:48 -080010892 novap_reset(dut, intf);
10893
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010894 val = get_param(cmd, "nss_mcs_opt");
10895 if (val) {
10896 /* String (nss_operating_mode; mcs_operating_mode) */
10897 int nss, mcs;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010898 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010899
10900 token = strdup(val);
10901 if (!token)
10902 return 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010903 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +053010904 if (!result) {
10905 sigma_dut_print(dut, DUT_MSG_ERROR,
10906 "VHT NSS not specified");
10907 goto failed;
10908 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010909 if (strcasecmp(result, "def") != 0) {
10910 nss = atoi(result);
10911 if (nss == 4)
10912 ath_disable_txbf(dut, intf);
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010913 if (run_iwpriv(dut, intf, "nss %d", nss) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010914 goto failed;
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010915
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010916 }
10917
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010918 result = strtok_r(NULL, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +053010919 if (!result) {
10920 sigma_dut_print(dut, DUT_MSG_ERROR,
10921 "VHT MCS not specified");
10922 goto failed;
10923 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010924 if (strcasecmp(result, "def") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010925 if (run_iwpriv(dut, intf, "set11NRates 0") < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010926 goto failed;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010927 } else {
10928 mcs = atoi(result);
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010929 if (run_iwpriv(dut, intf, "vhtmcs %d", mcs) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010930 goto failed;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010931 }
10932 /* Channel width gets messed up, fix this */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010933 run_iwpriv(dut, intf, "chwidth %d", dut->chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010934 }
10935
Srikanth Marepalli5415acf2018-08-27 12:53:11 +053010936 free(token);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010937 return 1;
10938failed:
10939 free(token);
10940 return 0;
10941}
10942
10943
10944static int cmd_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
10945 struct sigma_conn *conn,
10946 struct sigma_cmd *cmd)
10947{
10948 switch (get_driver_type()) {
10949 case DRIVER_ATHEROS:
10950 return ath_sta_set_rfeature_vht(intf, dut, conn, cmd);
10951 default:
10952 send_resp(dut, conn, SIGMA_ERROR,
10953 "errorCode,Unsupported sta_set_rfeature(VHT) with the current driver");
10954 return 0;
10955 }
10956}
10957
10958
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080010959static int wcn_sta_set_rfeature_he(const char *intf, struct sigma_dut *dut,
10960 struct sigma_conn *conn,
10961 struct sigma_cmd *cmd)
10962{
10963 const char *val;
10964 char *token = NULL, *result;
10965 char buf[60];
10966
10967 val = get_param(cmd, "nss_mcs_opt");
10968 if (val) {
10969 /* String (nss_operating_mode; mcs_operating_mode) */
10970 int nss, mcs, ratecode;
10971 char *saveptr;
10972
10973 token = strdup(val);
10974 if (!token)
10975 return -2;
10976
10977 result = strtok_r(token, ";", &saveptr);
10978 if (!result) {
10979 sigma_dut_print(dut, DUT_MSG_ERROR,
10980 "HE NSS not specified");
10981 goto failed;
10982 }
10983 nss = 1;
10984 if (strcasecmp(result, "def") != 0)
10985 nss = atoi(result);
10986
10987 result = strtok_r(NULL, ";", &saveptr);
10988 if (!result) {
10989 sigma_dut_print(dut, DUT_MSG_ERROR,
10990 "HE MCS not specified");
10991 goto failed;
10992 }
10993 mcs = 7;
10994 if (strcasecmp(result, "def") != 0)
10995 mcs = atoi(result);
10996
Arif Hussain557bf412018-05-25 17:29:36 -070010997 ratecode = 0x20; /* for nss:1 MCS 0 */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080010998 if (nss == 2) {
Arif Hussain557bf412018-05-25 17:29:36 -070010999 ratecode = 0x40; /* for nss:2 MCS 0 */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011000 } else if (nss > 2) {
11001 sigma_dut_print(dut, DUT_MSG_ERROR,
11002 "HE NSS %d not supported", nss);
11003 goto failed;
11004 }
11005
Arif Hussain557bf412018-05-25 17:29:36 -070011006 snprintf(buf, sizeof(buf), "iwpriv %s nss %d", intf, nss);
11007 if (system(buf) != 0) {
11008 sigma_dut_print(dut, DUT_MSG_ERROR,
11009 "nss_mcs_opt: iwpriv %s nss %d failed",
11010 intf, nss);
11011 goto failed;
11012 }
Arif Hussainac6c5112018-05-25 17:34:00 -070011013 dut->sta_nss = nss;
Arif Hussain557bf412018-05-25 17:29:36 -070011014
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011015 /* Add the MCS to the ratecode */
11016 if (mcs >= 0 && mcs <= 11) {
11017 ratecode += mcs;
Arif Hussain557bf412018-05-25 17:29:36 -070011018#ifdef NL80211_SUPPORT
11019 if (dut->device_type == STA_testbed) {
11020 enum he_mcs_config mcs_config;
11021 int ret;
11022
11023 if (mcs <= 7)
11024 mcs_config = HE_80_MCS0_7;
11025 else if (mcs <= 9)
11026 mcs_config = HE_80_MCS0_9;
11027 else
11028 mcs_config = HE_80_MCS0_11;
11029 ret = sta_set_he_mcs(dut, intf, mcs_config);
11030 if (ret) {
11031 sigma_dut_print(dut, DUT_MSG_ERROR,
11032 "nss_mcs_opt: mcs setting failed, mcs:%d, mcs_config %d, ret:%d",
11033 mcs, mcs_config, ret);
11034 goto failed;
11035 }
11036 }
11037#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011038 } else {
11039 sigma_dut_print(dut, DUT_MSG_ERROR,
11040 "HE MCS %d not supported", mcs);
11041 goto failed;
11042 }
11043 snprintf(buf, sizeof(buf), "iwpriv %s set_11ax_rate 0x%03x",
11044 intf, ratecode);
11045 if (system(buf) != 0) {
11046 sigma_dut_print(dut, DUT_MSG_ERROR,
11047 "iwpriv setting of 11ax rates failed");
11048 goto failed;
11049 }
11050 free(token);
11051 }
11052
11053 val = get_param(cmd, "GI");
11054 if (val) {
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011055 int fix_rate_sgi;
11056
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011057 if (strcmp(val, "0.8") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070011058 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 9", intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011059 fix_rate_sgi = 1;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011060 } else if (strcmp(val, "1.6") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070011061 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 10",
11062 intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011063 fix_rate_sgi = 2;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011064 } else if (strcmp(val, "3.2") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070011065 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 11",
11066 intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011067 fix_rate_sgi = 3;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011068 } else {
11069 send_resp(dut, conn, SIGMA_ERROR,
11070 "errorCode,GI value not supported");
11071 return 0;
11072 }
11073 if (system(buf) != 0) {
11074 send_resp(dut, conn, SIGMA_ERROR,
11075 "errorCode,Failed to set shortgi");
11076 return 0;
11077 }
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011078 snprintf(buf, sizeof(buf), "iwpriv %s shortgi %d",
11079 intf, fix_rate_sgi);
11080 if (system(buf) != 0) {
11081 send_resp(dut, conn, SIGMA_ERROR,
11082 "errorCode,Failed to set fix rate shortgi");
11083 return STATUS_SENT;
11084 }
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011085 }
11086
Subhani Shaik8e7a3052018-04-24 14:03:00 -070011087 val = get_param(cmd, "LTF");
11088 if (val) {
11089#ifdef NL80211_SUPPORT
11090 if (strcmp(val, "3.2") == 0) {
11091 sta_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_1X);
11092 } if (strcmp(val, "6.4") == 0) {
11093 sta_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_2X);
11094 } else if (strcmp(val, "12.8") == 0) {
11095 sta_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_4X);
11096 } else {
11097 send_resp(dut, conn, SIGMA_ERROR,
11098 "errorCode, LTF value not supported");
11099 return 0;
11100 }
11101#else /* NL80211_SUPPORT */
11102 sigma_dut_print(dut, DUT_MSG_ERROR,
11103 "LTF cannot be set without NL80211_SUPPORT defined");
11104 return -2;
11105#endif /* NL80211_SUPPORT */
11106 }
11107
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -070011108 val = get_param(cmd, "TxSUPPDU");
11109 if (val) {
11110 int set_val = 1;
11111
11112 if (strcasecmp(val, "Enable") == 0)
11113 set_val = 1;
11114 else if (strcasecmp(val, "Disable") == 0)
11115 set_val = 0;
11116
11117 if (sta_set_tx_su_ppdu_cfg(dut, intf, set_val)) {
11118 send_resp(dut, conn, SIGMA_ERROR,
11119 "ErrorCode,Failed to set Tx SU PPDU config");
11120 return 0;
11121 }
11122 }
11123
Arif Hussain480d5f42019-03-12 14:40:42 -070011124 val = get_param(cmd, "TWT_Setup");
11125 if (val) {
11126 if (strcasecmp(val, "Request") == 0) {
11127 if (sta_twt_request(dut, conn, cmd)) {
11128 send_resp(dut, conn, SIGMA_ERROR,
11129 "ErrorCode,sta_twt_request failed");
11130 return STATUS_SENT;
11131 }
11132 } else if (strcasecmp(val, "Teardown") == 0) {
11133 if (sta_twt_teardown(dut, conn, cmd)) {
11134 send_resp(dut, conn, SIGMA_ERROR,
11135 "ErrorCode,sta_twt_teardown failed");
11136 return STATUS_SENT;
11137 }
11138 }
11139 }
11140
Kiran Kumar Lokere50eb2cd2018-12-18 18:31:28 -080011141 val = get_param(cmd, "transmitOMI");
11142 if (val && sta_transmit_omi(dut, conn, cmd)) {
11143 send_resp(dut, conn, SIGMA_ERROR,
11144 "ErrorCode,sta_transmit_omi failed");
11145 return STATUS_SENT;
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -070011146 }
11147
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080011148 val = get_param(cmd, "Powersave");
11149 if (val) {
11150 char buf[60];
11151
11152 if (strcasecmp(val, "off") == 0) {
11153 snprintf(buf, sizeof(buf),
11154 "iwpriv %s setPower 2", intf);
11155 if (system(buf) != 0) {
11156 sigma_dut_print(dut, DUT_MSG_ERROR,
11157 "iwpriv setPower 2 failed");
11158 return 0;
11159 }
11160 } else if (strcasecmp(val, "on") == 0) {
11161 snprintf(buf, sizeof(buf),
11162 "iwpriv %s setPower 1", intf);
11163 if (system(buf) != 0) {
11164 sigma_dut_print(dut, DUT_MSG_ERROR,
11165 "iwpriv setPower 1 failed");
11166 return 0;
11167 }
11168 } else {
11169 sigma_dut_print(dut, DUT_MSG_ERROR,
11170 "Unsupported Powersave value '%s'",
11171 val);
11172 return -1;
11173 }
11174 }
11175
Kiran Kumar Lokere2c4b7ce2019-01-30 12:02:28 -080011176 val = get_param(cmd, "MU_EDCA");
11177 if (val) {
11178 if (strcasecmp(val, "Override") == 0) {
11179 if (sta_set_mu_edca_override(dut, intf, 1)) {
11180 send_resp(dut, conn, SIGMA_ERROR,
11181 "errorCode,MU EDCA override set failed");
11182 return STATUS_SENT;
11183 }
11184 } else if (strcasecmp(val, "Disable") == 0) {
11185 if (sta_set_mu_edca_override(dut, intf, 0)) {
11186 send_resp(dut, conn, SIGMA_ERROR,
11187 "errorCode,MU EDCA override disable failed");
11188 return STATUS_SENT;
11189 }
11190 }
11191 }
11192
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011193 return 1;
11194
11195failed:
11196 free(token);
11197 return -2;
11198}
11199
11200
11201static int cmd_sta_set_rfeature_he(const char *intf, struct sigma_dut *dut,
11202 struct sigma_conn *conn,
11203 struct sigma_cmd *cmd)
11204{
11205 switch (get_driver_type()) {
11206 case DRIVER_WCN:
11207 return wcn_sta_set_rfeature_he(intf, dut, conn, cmd);
11208 default:
11209 send_resp(dut, conn, SIGMA_ERROR,
11210 "errorCode,Unsupported sta_set_rfeature(HE) with the current driver");
11211 return 0;
11212 }
11213}
11214
11215
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080011216static int cmd_sta_set_power_save_he(const char *intf, struct sigma_dut *dut,
11217 struct sigma_conn *conn,
11218 struct sigma_cmd *cmd)
11219{
11220 const char *val;
11221
11222 val = get_param(cmd, "powersave");
11223 if (val) {
11224 char buf[60];
11225
11226 if (strcasecmp(val, "off") == 0) {
11227 snprintf(buf, sizeof(buf), "iwpriv %s setPower 2",
11228 intf);
11229 if (system(buf) != 0) {
11230 sigma_dut_print(dut, DUT_MSG_ERROR,
11231 "iwpriv setPower 2 failed");
11232 return 0;
11233 }
11234 } else if (strcasecmp(val, "on") == 0) {
11235 snprintf(buf, sizeof(buf), "iwpriv %s setPower 1",
11236 intf);
11237 if (system(buf) != 0) {
11238 sigma_dut_print(dut, DUT_MSG_ERROR,
11239 "iwpriv setPower 1 failed");
11240 return 0;
11241 }
11242 } else {
11243 sigma_dut_print(dut, DUT_MSG_ERROR,
11244 "Unsupported power save config");
11245 return -1;
11246 }
11247 return 1;
11248 }
11249
11250 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported command");
11251
11252 return 0;
11253}
11254
11255
Ashwini Patil5acd7382017-04-13 15:55:04 +053011256static int btm_query_candidate_list(struct sigma_dut *dut,
11257 struct sigma_conn *conn,
11258 struct sigma_cmd *cmd)
11259{
11260 const char *bssid, *info, *op_class, *ch, *phy_type, *pref;
11261 int len, ret;
11262 char buf[10];
11263
11264 /*
11265 * Neighbor Report elements format:
11266 * neighbor=<BSSID>,<BSSID Information>,<Operating Class>,
11267 * <Channel Number>,<PHY Type>[,<hexdump of Optional Subelements>]
11268 * eg: neighbor=aa:bb:cc:dd:ee:ff,17,81,6,1,030101
11269 */
11270
11271 bssid = get_param(cmd, "Nebor_BSSID");
11272 if (!bssid) {
11273 send_resp(dut, conn, SIGMA_INVALID,
11274 "errorCode,Nebor_BSSID is missing");
11275 return 0;
11276 }
11277
11278 info = get_param(cmd, "Nebor_Bssid_Info");
11279 if (!info) {
11280 sigma_dut_print(dut, DUT_MSG_INFO,
11281 "Using default value for Nebor_Bssid_Info: %s",
11282 DEFAULT_NEIGHBOR_BSSID_INFO);
11283 info = DEFAULT_NEIGHBOR_BSSID_INFO;
11284 }
11285
11286 op_class = get_param(cmd, "Nebor_Op_Class");
11287 if (!op_class) {
11288 send_resp(dut, conn, SIGMA_INVALID,
11289 "errorCode,Nebor_Op_Class is missing");
11290 return 0;
11291 }
11292
11293 ch = get_param(cmd, "Nebor_Op_Ch");
11294 if (!ch) {
11295 send_resp(dut, conn, SIGMA_INVALID,
11296 "errorCode,Nebor_Op_Ch is missing");
11297 return 0;
11298 }
11299
11300 phy_type = get_param(cmd, "Nebor_Phy_Type");
11301 if (!phy_type) {
11302 sigma_dut_print(dut, DUT_MSG_INFO,
11303 "Using default value for Nebor_Phy_Type: %s",
11304 DEFAULT_NEIGHBOR_PHY_TYPE);
11305 phy_type = DEFAULT_NEIGHBOR_PHY_TYPE;
11306 }
11307
11308 /* Parse optional subelements */
11309 buf[0] = '\0';
11310 pref = get_param(cmd, "Nebor_Pref");
11311 if (pref) {
11312 /* hexdump for preferrence subelement */
11313 ret = snprintf(buf, sizeof(buf), ",0301%02x", atoi(pref));
11314 if (ret < 0 || ret >= (int) sizeof(buf)) {
11315 sigma_dut_print(dut, DUT_MSG_ERROR,
11316 "snprintf failed for optional subelement ret: %d",
11317 ret);
11318 send_resp(dut, conn, SIGMA_ERROR,
11319 "errorCode,snprintf failed for subelement");
11320 return 0;
11321 }
11322 }
11323
11324 if (!dut->btm_query_cand_list) {
11325 dut->btm_query_cand_list = calloc(1, NEIGHBOR_REPORT_SIZE);
11326 if (!dut->btm_query_cand_list) {
11327 send_resp(dut, conn, SIGMA_ERROR,
11328 "errorCode,Failed to allocate memory for btm_query_cand_list");
11329 return 0;
11330 }
11331 }
11332
11333 len = strlen(dut->btm_query_cand_list);
11334 ret = snprintf(dut->btm_query_cand_list + len,
11335 NEIGHBOR_REPORT_SIZE - len, " neighbor=%s,%s,%s,%s,%s%s",
11336 bssid, info, op_class, ch, phy_type, buf);
11337 if (ret < 0 || ret >= NEIGHBOR_REPORT_SIZE - len) {
11338 sigma_dut_print(dut, DUT_MSG_ERROR,
11339 "snprintf failed for neighbor report list ret: %d",
11340 ret);
11341 send_resp(dut, conn, SIGMA_ERROR,
11342 "errorCode,snprintf failed for neighbor report");
11343 free(dut->btm_query_cand_list);
11344 dut->btm_query_cand_list = NULL;
11345 return 0;
11346 }
11347
11348 return 1;
11349}
11350
11351
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020011352int sta_extract_60g_ese(struct sigma_dut *dut, struct sigma_cmd *cmd,
11353 struct sigma_ese_alloc *allocs, int *allocs_size)
11354{
11355 int max_count = *allocs_size;
11356 int count = 0, i;
11357 const char *val;
11358
11359 do {
11360 val = get_param_indexed(cmd, "AllocID", count);
11361 if (val)
11362 count++;
11363 } while (val);
11364
11365 if (count == 0 || count > max_count) {
11366 sigma_dut_print(dut, DUT_MSG_ERROR,
11367 "Invalid number of allocations(%d)", count);
11368 return -1;
11369 }
11370
11371 for (i = 0; i < count; i++) {
11372 val = get_param_indexed(cmd, "PercentBI", i);
11373 if (!val) {
11374 sigma_dut_print(dut, DUT_MSG_ERROR,
11375 "Missing PercentBI parameter at index %d",
11376 i);
11377 return -1;
11378 }
11379 allocs[i].percent_bi = atoi(val);
11380
11381 val = get_param_indexed(cmd, "SrcAID", i);
11382 if (val)
11383 allocs[i].src_aid = strtol(val, NULL, 0);
11384 else
11385 allocs[i].src_aid = ESE_BCAST_AID;
11386
11387 val = get_param_indexed(cmd, "DestAID", i);
11388 if (val)
11389 allocs[i].dst_aid = strtol(val, NULL, 0);
11390 else
11391 allocs[i].dst_aid = ESE_BCAST_AID;
11392
11393 allocs[i].type = ESE_CBAP;
11394 sigma_dut_print(dut, DUT_MSG_INFO,
11395 "Alloc %d PercentBI %d SrcAID %d DstAID %d",
11396 i, allocs[i].percent_bi, allocs[i].src_aid,
11397 allocs[i].dst_aid);
11398 }
11399
11400 *allocs_size = count;
11401 return 0;
11402}
11403
11404
11405static int sta_set_60g_ese(struct sigma_dut *dut, int count,
11406 struct sigma_ese_alloc *allocs)
11407{
11408 switch (get_driver_type()) {
11409#ifdef __linux__
11410 case DRIVER_WIL6210:
11411 if (wil6210_set_ese(dut, count, allocs))
11412 return -1;
11413 return 1;
11414#endif /* __linux__ */
11415 default:
11416 sigma_dut_print(dut, DUT_MSG_ERROR,
11417 "Unsupported sta_set_60g_ese with the current driver");
11418 return -1;
11419 }
11420}
11421
11422
11423static int cmd_sta_set_rfeature_60g(const char *intf, struct sigma_dut *dut,
11424 struct sigma_conn *conn,
11425 struct sigma_cmd *cmd)
11426{
11427 const char *val;
11428
11429 val = get_param(cmd, "ExtSchIE");
11430 if (val && !strcasecmp(val, "Enable")) {
11431 struct sigma_ese_alloc allocs[MAX_ESE_ALLOCS];
11432 int count = MAX_ESE_ALLOCS;
11433
11434 if (sta_extract_60g_ese(dut, cmd, allocs, &count))
11435 return -1;
11436 return sta_set_60g_ese(dut, count, allocs);
11437 }
11438
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +020011439 val = get_param(cmd, "MCS_FixedRate");
11440 if (val) {
11441 int sta_mcs = atoi(val);
11442
11443 sigma_dut_print(dut, DUT_MSG_INFO, "Force STA MCS to %d",
11444 sta_mcs);
11445 wil6210_set_force_mcs(dut, 1, sta_mcs);
11446
Jouni Malinen0e29cf22019-02-19 01:13:21 +020011447 return SUCCESS_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +020011448 }
11449
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020011450 send_resp(dut, conn, SIGMA_ERROR,
11451 "errorCode,Invalid sta_set_rfeature(60G)");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020011452 return STATUS_SENT;
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020011453}
11454
11455
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011456static int cmd_sta_set_rfeature(struct sigma_dut *dut, struct sigma_conn *conn,
11457 struct sigma_cmd *cmd)
11458{
11459 const char *intf = get_param(cmd, "Interface");
11460 const char *prog = get_param(cmd, "Prog");
Ashwini Patil68d02cd2017-01-10 15:39:16 +053011461 const char *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011462
11463 if (intf == NULL || prog == NULL)
11464 return -1;
11465
Ashwini Patil5acd7382017-04-13 15:55:04 +053011466 /* BSS Transition candidate list for BTM query */
11467 val = get_param(cmd, "Nebor_BSSID");
11468 if (val && btm_query_candidate_list(dut, conn, cmd) == 0)
11469 return 0;
11470
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011471 if (strcasecmp(prog, "TDLS") == 0)
11472 return cmd_sta_set_rfeature_tdls(intf, dut, conn, cmd);
11473
11474 if (strcasecmp(prog, "VHT") == 0)
11475 return cmd_sta_set_rfeature_vht(intf, dut, conn, cmd);
11476
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011477 if (strcasecmp(prog, "HE") == 0)
11478 return cmd_sta_set_rfeature_he(intf, dut, conn, cmd);
11479
Ashwini Patil68d02cd2017-01-10 15:39:16 +053011480 if (strcasecmp(prog, "MBO") == 0) {
11481 val = get_param(cmd, "Cellular_Data_Cap");
11482 if (val &&
11483 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
11484 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +053011485
11486 val = get_param(cmd, "Ch_Pref");
11487 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
11488 return 0;
11489
Ashwini Patil68d02cd2017-01-10 15:39:16 +053011490 return 1;
11491 }
11492
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020011493 if (strcasecmp(prog, "60GHz") == 0)
11494 return cmd_sta_set_rfeature_60g(intf, dut, conn, cmd);
11495
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011496 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported Prog");
11497 return 0;
11498}
11499
11500
11501static int cmd_sta_set_radio(struct sigma_dut *dut, struct sigma_conn *conn,
11502 struct sigma_cmd *cmd)
11503{
11504 const char *intf = get_param(cmd, "Interface");
11505 const char *mode = get_param(cmd, "Mode");
11506 int res;
11507
11508 if (intf == NULL || mode == NULL)
11509 return -1;
11510
11511 if (strcasecmp(mode, "On") == 0)
11512 res = wpa_command(intf, "SET radio_disabled 0");
11513 else if (strcasecmp(mode, "Off") == 0)
11514 res = wpa_command(intf, "SET radio_disabled 1");
11515 else
11516 return -1;
11517
11518 if (res) {
11519 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
11520 "radio mode");
11521 return 0;
11522 }
11523
11524 return 1;
11525}
11526
11527
11528static int cmd_sta_set_pwrsave(struct sigma_dut *dut, struct sigma_conn *conn,
11529 struct sigma_cmd *cmd)
11530{
11531 const char *intf = get_param(cmd, "Interface");
11532 const char *mode = get_param(cmd, "Mode");
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020011533 const char *prog = get_param(cmd, "program");
11534 const char *powersave = get_param(cmd, "powersave");
11535 int res = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011536
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020011537 if (intf == NULL)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011538 return -1;
11539
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020011540 if (prog && strcasecmp(prog, "60GHz") == 0) {
11541 /*
11542 * The CAPI mode parameter does not exist in 60G
11543 * unscheduled PS.
11544 */
11545 if (strcasecmp(powersave, "unscheduled") == 0)
11546 res = set_ps(intf, dut, 1);
Alexei Avshalom Lazar2f6fdb42019-02-04 14:16:08 +020011547 } else if (prog && get_driver_type() == DRIVER_WCN &&
11548 strcasecmp(prog, "HE") == 0) {
11549 return cmd_sta_set_power_save_he(intf, dut, conn, cmd);
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020011550 } else {
11551 if (mode == NULL)
11552 return -1;
11553
11554 if (strcasecmp(mode, "On") == 0)
11555 res = set_ps(intf, dut, 1);
11556 else if (strcasecmp(mode, "Off") == 0)
11557 res = set_ps(intf, dut, 0);
11558 else
11559 return -1;
11560 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011561
11562 if (res) {
11563 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
11564 "power save mode");
11565 return 0;
11566 }
11567
11568 return 1;
11569}
11570
11571
11572static int cmd_sta_bssid_pool(struct sigma_dut *dut, struct sigma_conn *conn,
11573 struct sigma_cmd *cmd)
11574{
11575 const char *intf = get_param(cmd, "Interface");
11576 const char *val, *bssid;
11577 int res;
11578 char *buf;
11579 size_t buf_len;
11580
11581 val = get_param(cmd, "BSSID_FILTER");
11582 if (val == NULL)
11583 return -1;
11584
11585 bssid = get_param(cmd, "BSSID_List");
11586 if (atoi(val) == 0 || bssid == NULL) {
11587 /* Disable BSSID filter */
11588 if (wpa_command(intf, "SET bssid_filter ")) {
11589 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed "
11590 "to disable BSSID filter");
11591 return 0;
11592 }
11593
11594 return 1;
11595 }
11596
11597 buf_len = 100 + strlen(bssid);
11598 buf = malloc(buf_len);
11599 if (buf == NULL)
11600 return -1;
11601
11602 snprintf(buf, buf_len, "SET bssid_filter %s", bssid);
11603 res = wpa_command(intf, buf);
11604 free(buf);
11605 if (res) {
11606 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to enable "
11607 "BSSID filter");
11608 return 0;
11609 }
11610
11611 return 1;
11612}
11613
11614
11615static int cmd_sta_reset_parm(struct sigma_dut *dut, struct sigma_conn *conn,
11616 struct sigma_cmd *cmd)
11617{
11618 const char *intf = get_param(cmd, "Interface");
11619 const char *val;
11620
11621 /* TODO: ARP */
11622
11623 val = get_param(cmd, "HS2_CACHE_PROFILE");
11624 if (val && strcasecmp(val, "All") == 0)
11625 hs2_clear_credentials(intf);
11626
11627 return 1;
11628}
11629
11630
11631static int cmd_sta_get_key(struct sigma_dut *dut, struct sigma_conn *conn,
11632 struct sigma_cmd *cmd)
11633{
11634 const char *intf = get_param(cmd, "Interface");
11635 const char *key_type = get_param(cmd, "KeyType");
11636 char buf[100], resp[200];
11637
11638 if (key_type == NULL)
11639 return -1;
11640
11641 if (strcasecmp(key_type, "GTK") == 0) {
11642 if (wpa_command_resp(intf, "GET gtk", buf, sizeof(buf)) < 0 ||
11643 strncmp(buf, "FAIL", 4) == 0) {
11644 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
11645 "not fetch current GTK");
11646 return 0;
11647 }
11648 snprintf(resp, sizeof(resp), "KeyValue,%s", buf);
11649 send_resp(dut, conn, SIGMA_COMPLETE, resp);
11650 return 0;
11651 } else {
11652 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
11653 "KeyType");
11654 return 0;
11655 }
11656
11657 return 1;
11658}
11659
11660
11661static int hs2_set_policy(struct sigma_dut *dut)
11662{
11663#ifdef ANDROID
11664 system("ip rule del prio 23000");
11665 if (system("ip rule add from all lookup main prio 23000") != 0) {
11666 sigma_dut_print(dut, DUT_MSG_ERROR,
11667 "Failed to run:ip rule add from all lookup main prio");
11668 return -1;
11669 }
11670 if (system("ip route flush cache") != 0) {
11671 sigma_dut_print(dut, DUT_MSG_ERROR,
11672 "Failed to run ip route flush cache");
11673 return -1;
11674 }
11675 return 1;
11676#else /* ANDROID */
11677 return 0;
11678#endif /* ANDROID */
11679}
11680
11681
11682static int cmd_sta_hs2_associate(struct sigma_dut *dut,
11683 struct sigma_conn *conn,
11684 struct sigma_cmd *cmd)
11685{
11686 const char *intf = get_param(cmd, "Interface");
11687 const char *val = get_param(cmd, "Ignore_blacklist");
Jouni Malinen439352d2018-09-13 03:42:23 +030011688 const char *band = get_param(cmd, "Band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011689 struct wpa_ctrl *ctrl;
11690 int res;
11691 char bssid[20], ssid[40], resp[100], buf[100], blacklisted[100];
11692 int tries = 0;
11693 int ignore_blacklist = 0;
11694 const char *events[] = {
11695 "CTRL-EVENT-CONNECTED",
11696 "INTERWORKING-BLACKLISTED",
11697 "INTERWORKING-NO-MATCH",
11698 NULL
11699 };
11700
11701 start_sta_mode(dut);
11702
Jouni Malinen439352d2018-09-13 03:42:23 +030011703 if (band) {
11704 if (strcmp(band, "2.4") == 0) {
11705 wpa_command(intf, "SET setband 2G");
11706 } else if (strcmp(band, "5") == 0) {
11707 wpa_command(intf, "SET setband 5G");
11708 } else {
11709 send_resp(dut, conn, SIGMA_ERROR,
11710 "errorCode,Unsupported band");
11711 return 0;
11712 }
11713 }
11714
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011715 blacklisted[0] = '\0';
11716 if (val && atoi(val))
11717 ignore_blacklist = 1;
11718
11719try_again:
11720 ctrl = open_wpa_mon(intf);
11721 if (ctrl == NULL) {
11722 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
11723 "wpa_supplicant monitor connection");
11724 return -2;
11725 }
11726
11727 tries++;
11728 if (wpa_command(intf, "INTERWORKING_SELECT auto")) {
11729 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start "
11730 "Interworking connection");
11731 wpa_ctrl_detach(ctrl);
11732 wpa_ctrl_close(ctrl);
11733 return 0;
11734 }
11735
11736 buf[0] = '\0';
11737 while (1) {
11738 char *pos;
11739 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
11740 pos = strstr(buf, "INTERWORKING-BLACKLISTED");
11741 if (!pos)
11742 break;
11743 pos += 25;
11744 sigma_dut_print(dut, DUT_MSG_DEBUG, "Found blacklisted AP: %s",
11745 pos);
11746 if (!blacklisted[0])
11747 memcpy(blacklisted, pos, strlen(pos) + 1);
11748 }
11749
11750 if (ignore_blacklist && blacklisted[0]) {
11751 char *end;
11752 end = strchr(blacklisted, ' ');
11753 if (end)
11754 *end = '\0';
11755 sigma_dut_print(dut, DUT_MSG_DEBUG, "Try to connect to a blacklisted network: %s",
11756 blacklisted);
11757 snprintf(buf, sizeof(buf), "INTERWORKING_CONNECT %s",
11758 blacklisted);
11759 if (wpa_command(intf, buf)) {
11760 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start Interworking connection to blacklisted network");
11761 wpa_ctrl_detach(ctrl);
11762 wpa_ctrl_close(ctrl);
11763 return 0;
11764 }
11765 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
11766 buf, sizeof(buf));
11767 }
11768
11769 wpa_ctrl_detach(ctrl);
11770 wpa_ctrl_close(ctrl);
11771
11772 if (res < 0) {
11773 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
11774 "connect");
11775 return 0;
11776 }
11777
11778 if (strstr(buf, "INTERWORKING-NO-MATCH") ||
11779 strstr(buf, "INTERWORKING-BLACKLISTED")) {
11780 if (tries < 2) {
11781 sigma_dut_print(dut, DUT_MSG_INFO, "No match found - try again to verify no APs were missed in the scan");
11782 goto try_again;
11783 }
11784 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,No network with "
11785 "matching credentials found");
11786 return 0;
11787 }
11788
11789 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
11790 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
11791 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
11792 "get current BSSID/SSID");
11793 return 0;
11794 }
11795
11796 snprintf(resp, sizeof(resp), "SSID,%s,BSSID,%s", ssid, bssid);
11797 send_resp(dut, conn, SIGMA_COMPLETE, resp);
11798 hs2_set_policy(dut);
11799 return 0;
11800}
11801
11802
Jouni Malinenb639f1c2018-09-13 02:39:46 +030011803static int cmd_sta_hs2_venue_info(struct sigma_dut *dut,
11804 struct sigma_conn *conn,
11805 struct sigma_cmd *cmd)
11806{
11807 const char *intf = get_param(cmd, "Interface");
11808 const char *display = get_param(cmd, "Display");
11809 struct wpa_ctrl *ctrl;
11810 char buf[300], params[400], *pos;
11811 char bssid[20];
11812 int info_avail = 0;
11813 unsigned int old_timeout;
11814 int res;
11815
11816 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0) {
11817 send_resp(dut, conn, SIGMA_ERROR,
11818 "ErrorCode,Could not get current BSSID");
11819 return 0;
11820 }
11821 ctrl = open_wpa_mon(intf);
11822 if (!ctrl) {
11823 sigma_dut_print(dut, DUT_MSG_ERROR,
11824 "Failed to open wpa_supplicant monitor connection");
11825 return -2;
11826 }
11827
11828 snprintf(buf, sizeof(buf), "ANQP_GET %s 277", bssid);
11829 wpa_command(intf, buf);
11830
11831 res = get_wpa_cli_event(dut, ctrl, "GAS-QUERY-DONE", buf, sizeof(buf));
11832 if (res < 0) {
11833 send_resp(dut, conn, SIGMA_ERROR,
11834 "ErrorCode,Could not complete GAS query");
11835 goto fail;
11836 }
11837
11838 old_timeout = dut->default_timeout;
11839 dut->default_timeout = 2;
11840 res = get_wpa_cli_event(dut, ctrl, "RX-VENUE-URL", buf, sizeof(buf));
11841 dut->default_timeout = old_timeout;
11842 if (res < 0)
11843 goto done;
11844 pos = strchr(buf, ' ');
11845 if (!pos)
11846 goto done;
11847 pos++;
11848 pos = strchr(pos, ' ');
11849 if (!pos)
11850 goto done;
11851 pos++;
11852 info_avail = 1;
11853 snprintf(params, sizeof(params), "browser %s", pos);
11854
11855 if (display && strcasecmp(display, "Yes") == 0) {
11856 pid_t pid;
11857
11858 pid = fork();
11859 if (pid < 0) {
11860 perror("fork");
11861 return -1;
11862 }
11863
11864 if (pid == 0) {
11865 run_hs20_osu(dut, params);
11866 exit(0);
11867 }
11868 }
11869
11870done:
11871 snprintf(buf, sizeof(buf), "Info_available,%s",
11872 info_avail ? "Yes" : "No");
11873 send_resp(dut, conn, SIGMA_COMPLETE, buf);
11874fail:
11875 wpa_ctrl_detach(ctrl);
11876 wpa_ctrl_close(ctrl);
11877 return 0;
11878}
11879
11880
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011881static int sta_add_credential_uname_pwd(struct sigma_dut *dut,
11882 struct sigma_conn *conn,
11883 const char *ifname,
11884 struct sigma_cmd *cmd)
11885{
11886 const char *val;
11887 int id;
11888
11889 id = add_cred(ifname);
11890 if (id < 0)
11891 return -2;
11892 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
11893
11894 val = get_param(cmd, "prefer");
11895 if (val && atoi(val) > 0)
11896 set_cred(ifname, id, "priority", "1");
11897
11898 val = get_param(cmd, "REALM");
11899 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
11900 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
11901 "realm");
11902 return 0;
11903 }
11904
11905 val = get_param(cmd, "HOME_FQDN");
11906 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
11907 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
11908 "home_fqdn");
11909 return 0;
11910 }
11911
11912 val = get_param(cmd, "Username");
11913 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
11914 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
11915 "username");
11916 return 0;
11917 }
11918
11919 val = get_param(cmd, "Password");
11920 if (val && set_cred_quoted(ifname, id, "password", val) < 0) {
11921 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
11922 "password");
11923 return 0;
11924 }
11925
11926 val = get_param(cmd, "ROOT_CA");
11927 if (val) {
11928 char fname[200];
11929 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
11930#ifdef __linux__
11931 if (!file_exists(fname)) {
11932 char msg[300];
11933 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
11934 "file (%s) not found", fname);
11935 send_resp(dut, conn, SIGMA_ERROR, msg);
11936 return 0;
11937 }
11938#endif /* __linux__ */
11939 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
11940 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
11941 "not set root CA");
11942 return 0;
11943 }
11944 }
11945
11946 return 1;
11947}
11948
11949
11950static int update_devdetail_imsi(struct sigma_dut *dut, const char *imsi)
11951{
11952 FILE *in, *out;
11953 char buf[500];
11954 int found = 0;
11955
11956 in = fopen("devdetail.xml", "r");
11957 if (in == NULL)
11958 return -1;
11959 out = fopen("devdetail.xml.tmp", "w");
11960 if (out == NULL) {
11961 fclose(in);
11962 return -1;
11963 }
11964
11965 while (fgets(buf, sizeof(buf), in)) {
11966 char *pos = strstr(buf, "<IMSI>");
11967 if (pos) {
11968 sigma_dut_print(dut, DUT_MSG_INFO, "Updated DevDetail IMSI to %s",
11969 imsi);
11970 pos += 6;
11971 *pos = '\0';
11972 fprintf(out, "%s%s</IMSI>\n", buf, imsi);
11973 found++;
11974 } else {
11975 fprintf(out, "%s", buf);
11976 }
11977 }
11978
11979 fclose(out);
11980 fclose(in);
11981 if (found)
11982 rename("devdetail.xml.tmp", "devdetail.xml");
11983 else
11984 unlink("devdetail.xml.tmp");
11985
11986 return 0;
11987}
11988
11989
11990static int sta_add_credential_sim(struct sigma_dut *dut,
11991 struct sigma_conn *conn,
11992 const char *ifname, struct sigma_cmd *cmd)
11993{
11994 const char *val, *imsi = NULL;
11995 int id;
11996 char buf[200];
11997 int res;
11998 const char *pos;
11999 size_t mnc_len;
12000 char plmn_mcc[4];
12001 char plmn_mnc[4];
12002
12003 id = add_cred(ifname);
12004 if (id < 0)
12005 return -2;
12006 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
12007
12008 val = get_param(cmd, "prefer");
12009 if (val && atoi(val) > 0)
12010 set_cred(ifname, id, "priority", "1");
12011
12012 val = get_param(cmd, "PLMN_MCC");
12013 if (val == NULL) {
12014 send_resp(dut, conn, SIGMA_ERROR,
12015 "errorCode,Missing PLMN_MCC");
12016 return 0;
12017 }
12018 if (strlen(val) != 3) {
12019 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MCC");
12020 return 0;
12021 }
12022 snprintf(plmn_mcc, sizeof(plmn_mcc), "%s", val);
12023
12024 val = get_param(cmd, "PLMN_MNC");
12025 if (val == NULL) {
12026 send_resp(dut, conn, SIGMA_ERROR,
12027 "errorCode,Missing PLMN_MNC");
12028 return 0;
12029 }
12030 if (strlen(val) != 2 && strlen(val) != 3) {
12031 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MNC");
12032 return 0;
12033 }
12034 snprintf(plmn_mnc, sizeof(plmn_mnc), "%s", val);
12035
12036 val = get_param(cmd, "IMSI");
12037 if (val == NULL) {
12038 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing SIM "
12039 "IMSI");
12040 return 0;
12041 }
12042
12043 imsi = pos = val;
12044
12045 if (strncmp(plmn_mcc, pos, 3) != 0) {
12046 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MCC mismatch");
12047 return 0;
12048 }
12049 pos += 3;
12050
12051 mnc_len = strlen(plmn_mnc);
12052 if (mnc_len < 2) {
12053 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC not set");
12054 return 0;
12055 }
12056
12057 if (strncmp(plmn_mnc, pos, mnc_len) != 0) {
12058 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC mismatch");
12059 return 0;
12060 }
12061 pos += mnc_len;
12062
12063 res = snprintf(buf, sizeof(buf), "%s%s-%s",plmn_mcc, plmn_mnc, pos);
12064 if (res < 0 || res >= (int) sizeof(buf))
12065 return -1;
12066 if (set_cred_quoted(ifname, id, "imsi", buf) < 0) {
12067 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12068 "not set IMSI");
12069 return 0;
12070 }
12071
12072 val = get_param(cmd, "Password");
12073 if (val && set_cred_quoted(ifname, id, "milenage", val) < 0) {
12074 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12075 "not set password");
12076 return 0;
12077 }
12078
Jouni Malinenba630452018-06-22 11:49:59 +030012079 if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012080 /*
12081 * Set provisioning_sp for the test cases where SIM/USIM
12082 * provisioning is used.
12083 */
12084 if (val && set_cred_quoted(ifname, id, "provisioning_sp",
12085 "wi-fi.org") < 0) {
12086 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12087 "not set provisioning_sp");
12088 return 0;
12089 }
12090
12091 update_devdetail_imsi(dut, imsi);
12092 }
12093
12094 return 1;
12095}
12096
12097
12098static int sta_add_credential_cert(struct sigma_dut *dut,
12099 struct sigma_conn *conn,
12100 const char *ifname,
12101 struct sigma_cmd *cmd)
12102{
12103 const char *val;
12104 int id;
12105
12106 id = add_cred(ifname);
12107 if (id < 0)
12108 return -2;
12109 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
12110
12111 val = get_param(cmd, "prefer");
12112 if (val && atoi(val) > 0)
12113 set_cred(ifname, id, "priority", "1");
12114
12115 val = get_param(cmd, "REALM");
12116 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
12117 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12118 "realm");
12119 return 0;
12120 }
12121
12122 val = get_param(cmd, "HOME_FQDN");
12123 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
12124 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12125 "home_fqdn");
12126 return 0;
12127 }
12128
12129 val = get_param(cmd, "Username");
12130 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
12131 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12132 "username");
12133 return 0;
12134 }
12135
12136 val = get_param(cmd, "clientCertificate");
12137 if (val) {
12138 char fname[200];
12139 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
12140#ifdef __linux__
12141 if (!file_exists(fname)) {
12142 char msg[300];
12143 snprintf(msg, sizeof(msg),
12144 "ErrorCode,clientCertificate "
12145 "file (%s) not found", fname);
12146 send_resp(dut, conn, SIGMA_ERROR, msg);
12147 return 0;
12148 }
12149#endif /* __linux__ */
12150 if (set_cred_quoted(ifname, id, "client_cert", fname) < 0) {
12151 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12152 "not set client_cert");
12153 return 0;
12154 }
12155 if (set_cred_quoted(ifname, id, "private_key", fname) < 0) {
12156 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12157 "not set private_key");
12158 return 0;
12159 }
12160 }
12161
12162 val = get_param(cmd, "ROOT_CA");
12163 if (val) {
12164 char fname[200];
12165 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
12166#ifdef __linux__
12167 if (!file_exists(fname)) {
12168 char msg[300];
12169 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
12170 "file (%s) not found", fname);
12171 send_resp(dut, conn, SIGMA_ERROR, msg);
12172 return 0;
12173 }
12174#endif /* __linux__ */
12175 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
12176 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12177 "not set root CA");
12178 return 0;
12179 }
12180 }
12181
12182 return 1;
12183}
12184
12185
12186static int cmd_sta_add_credential(struct sigma_dut *dut,
12187 struct sigma_conn *conn,
12188 struct sigma_cmd *cmd)
12189{
12190 const char *intf = get_param(cmd, "Interface");
12191 const char *type;
12192
12193 start_sta_mode(dut);
12194
12195 type = get_param(cmd, "Type");
12196 if (!type)
12197 return -1;
12198
12199 if (strcasecmp(type, "uname_pwd") == 0)
12200 return sta_add_credential_uname_pwd(dut, conn, intf, cmd);
12201
12202 if (strcasecmp(type, "sim") == 0)
12203 return sta_add_credential_sim(dut, conn, intf, cmd);
12204
12205 if (strcasecmp(type, "cert") == 0)
12206 return sta_add_credential_cert(dut, conn, intf, cmd);
12207
12208 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported credential "
12209 "type");
12210 return 0;
12211}
12212
12213
12214static int cmd_sta_scan(struct sigma_dut *dut, struct sigma_conn *conn,
12215 struct sigma_cmd *cmd)
12216{
12217 const char *intf = get_param(cmd, "Interface");
vamsi krishna89ad8c62017-09-19 12:51:18 +053012218 const char *val, *bssid, *ssid;
Arif Hussain66a4af02019-02-07 15:04:51 -080012219 char buf[4096];
vamsi krishna89ad8c62017-09-19 12:51:18 +053012220 char ssid_hex[65];
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012221 int res;
12222
Arif Hussain66a4af02019-02-07 15:04:51 -080012223 val = get_param(cmd, "GetParameter");
12224 if (val && strcmp(val, "SSID_BSSID") == 0) {
12225 if (get_wpa_ssid_bssid(dut, get_station_ifname(),
12226 buf, sizeof(buf)) < 0) {
12227 sigma_dut_print(dut, DUT_MSG_ERROR,
12228 "Could not get ssid bssid");
12229 return ERROR_SEND_STATUS;
12230 }
12231
12232 sigma_dut_print(dut, DUT_MSG_INFO, "%s", buf);
12233 send_resp(dut, conn, SIGMA_COMPLETE, buf);
12234 return STATUS_SENT;
12235 }
12236
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012237 val = get_param(cmd, "HESSID");
12238 if (val) {
12239 res = snprintf(buf, sizeof(buf), "SET hessid %s", val);
12240 if (res < 0 || res >= (int) sizeof(buf))
12241 return -1;
12242 wpa_command(intf, buf);
12243 }
12244
12245 val = get_param(cmd, "ACCS_NET_TYPE");
12246 if (val) {
12247 res = snprintf(buf, sizeof(buf), "SET access_network_type %s",
12248 val);
12249 if (res < 0 || res >= (int) sizeof(buf))
12250 return -1;
12251 wpa_command(intf, buf);
12252 }
12253
vamsi krishna89ad8c62017-09-19 12:51:18 +053012254 bssid = get_param(cmd, "Bssid");
12255 ssid = get_param(cmd, "Ssid");
12256
12257 if (ssid) {
12258 if (2 * strlen(ssid) >= sizeof(ssid_hex)) {
12259 send_resp(dut, conn, SIGMA_ERROR,
12260 "ErrorCode,Too long SSID");
12261 return 0;
12262 }
12263 ascii2hexstr(ssid, ssid_hex);
12264 }
12265
12266 res = snprintf(buf, sizeof(buf), "SCAN%s%s%s%s",
12267 bssid ? " bssid=": "",
12268 bssid ? bssid : "",
12269 ssid ? " ssid " : "",
12270 ssid ? ssid_hex : "");
12271 if (res < 0 || res >= (int) sizeof(buf))
12272 return -1;
12273
12274 if (wpa_command(intf, buf)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012275 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not start "
12276 "scan");
12277 return 0;
12278 }
12279
12280 return 1;
12281}
12282
12283
Jouni Malinen5e5d43d2018-01-10 17:29:33 +020012284static int cmd_sta_scan_bss(struct sigma_dut *dut, struct sigma_conn *conn,
12285 struct sigma_cmd *cmd)
12286{
12287 const char *intf = get_param(cmd, "Interface");
12288 const char *bssid;
12289 char buf[4096], *pos;
12290 int freq, chan;
12291 char *ssid;
12292 char resp[100];
12293 int res;
12294 struct wpa_ctrl *ctrl;
12295
12296 bssid = get_param(cmd, "BSSID");
12297 if (!bssid) {
12298 send_resp(dut, conn, SIGMA_INVALID,
12299 "errorCode,BSSID argument is missing");
12300 return 0;
12301 }
12302
12303 ctrl = open_wpa_mon(intf);
12304 if (!ctrl) {
12305 sigma_dut_print(dut, DUT_MSG_ERROR,
12306 "Failed to open wpa_supplicant monitor connection");
12307 return -1;
12308 }
12309
12310 if (wpa_command(intf, "SCAN TYPE=ONLY")) {
12311 send_resp(dut, conn, SIGMA_ERROR,
12312 "errorCode,Could not start scan");
12313 wpa_ctrl_detach(ctrl);
12314 wpa_ctrl_close(ctrl);
12315 return 0;
12316 }
12317
12318 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
12319 buf, sizeof(buf));
12320
12321 wpa_ctrl_detach(ctrl);
12322 wpa_ctrl_close(ctrl);
12323
12324 if (res < 0) {
12325 send_resp(dut, conn, SIGMA_ERROR,
12326 "errorCode,Scan did not complete");
12327 return 0;
12328 }
12329
12330 snprintf(buf, sizeof(buf), "BSS %s", bssid);
12331 if (wpa_command_resp(intf, buf, buf, sizeof(buf)) < 0 ||
12332 strncmp(buf, "id=", 3) != 0) {
12333 send_resp(dut, conn, SIGMA_ERROR,
12334 "errorCode,Specified BSSID not found");
12335 return 0;
12336 }
12337
12338 pos = strstr(buf, "\nfreq=");
12339 if (!pos) {
12340 send_resp(dut, conn, SIGMA_ERROR,
12341 "errorCode,Channel not found");
12342 return 0;
12343 }
12344 freq = atoi(pos + 6);
12345 chan = freq_to_channel(freq);
12346
12347 pos = strstr(buf, "\nssid=");
12348 if (!pos) {
12349 send_resp(dut, conn, SIGMA_ERROR,
12350 "errorCode,SSID not found");
12351 return 0;
12352 }
12353 ssid = pos + 6;
12354 pos = strchr(ssid, '\n');
12355 if (pos)
12356 *pos = '\0';
12357 snprintf(resp, sizeof(resp), "ssid,%s,bsschannel,%d", ssid, chan);
12358 send_resp(dut, conn, SIGMA_COMPLETE, resp);
12359 return 0;
12360}
12361
12362
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012363static int cmd_sta_set_systime(struct sigma_dut *dut, struct sigma_conn *conn,
12364 struct sigma_cmd *cmd)
12365{
12366#ifdef __linux__
12367 struct timeval tv;
12368 struct tm tm;
12369 time_t t;
12370 const char *val;
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +053012371 int v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012372
12373 wpa_command(get_station_ifname(), "PMKSA_FLUSH");
12374
12375 memset(&tm, 0, sizeof(tm));
12376 val = get_param(cmd, "seconds");
12377 if (val)
12378 tm.tm_sec = atoi(val);
12379 val = get_param(cmd, "minutes");
12380 if (val)
12381 tm.tm_min = atoi(val);
12382 val = get_param(cmd, "hours");
12383 if (val)
12384 tm.tm_hour = atoi(val);
12385 val = get_param(cmd, "date");
12386 if (val)
12387 tm.tm_mday = atoi(val);
12388 val = get_param(cmd, "month");
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +053012389 if (val) {
12390 v = atoi(val);
12391 if (v < 1 || v > 12) {
12392 send_resp(dut, conn, SIGMA_INVALID,
12393 "errorCode,Invalid month");
12394 return 0;
12395 }
12396 tm.tm_mon = v - 1;
12397 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012398 val = get_param(cmd, "year");
12399 if (val) {
12400 int year = atoi(val);
12401#ifdef ANDROID
12402 if (year > 2035)
12403 year = 2035; /* years beyond 2035 not supported */
12404#endif /* ANDROID */
12405 tm.tm_year = year - 1900;
12406 }
12407 t = mktime(&tm);
12408 if (t == (time_t) -1) {
12409 send_resp(dut, conn, SIGMA_ERROR,
12410 "errorCode,Invalid date or time");
12411 return 0;
12412 }
12413
12414 memset(&tv, 0, sizeof(tv));
12415 tv.tv_sec = t;
12416
12417 if (settimeofday(&tv, NULL) < 0) {
12418 sigma_dut_print(dut, DUT_MSG_INFO, "settimeofday failed: %s",
12419 strerror(errno));
12420 send_resp(dut, conn, SIGMA_ERROR,
12421 "errorCode,Failed to set time");
12422 return 0;
12423 }
12424
12425 return 1;
12426#endif /* __linux__ */
12427
12428 return -1;
12429}
12430
12431
12432static int cmd_sta_osu(struct sigma_dut *dut, struct sigma_conn *conn,
12433 struct sigma_cmd *cmd)
12434{
12435 const char *intf = get_param(cmd, "Interface");
Jouni Malinen4c8681c2018-09-12 23:28:11 +030012436 const char *name, *osu_ssid, *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012437 int prod_ess_assoc = 1;
Jouni Malinen4c8681c2018-09-12 23:28:11 +030012438 char buf[300], bssid[100], ssid[100];
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012439 int res;
12440 struct wpa_ctrl *ctrl;
12441
12442 name = get_param(cmd, "osuFriendlyName");
Jouni Malinen4c8681c2018-09-12 23:28:11 +030012443 osu_ssid = get_param(cmd, "osu_ssid");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012444
12445 val = get_param(cmd, "ProdESSAssoc");
12446 if (val)
12447 prod_ess_assoc = atoi(val);
12448
12449 kill_dhcp_client(dut, intf);
12450 if (start_dhcp_client(dut, intf) < 0)
12451 return -2;
12452
12453 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger OSU");
12454 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
12455 res = snprintf(buf, sizeof(buf),
Jouni Malinen4c8681c2018-09-12 23:28:11 +030012456 "%s %s%s%s %s%s%s signup osu-ca.pem",
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012457 prod_ess_assoc ? "" : "-N",
12458 name ? "-O'" : "", name ? name : "",
Jouni Malinen4c8681c2018-09-12 23:28:11 +030012459 name ? "'" : "",
12460 osu_ssid ? "-o'" : "", osu_ssid ? osu_ssid : "",
12461 osu_ssid ? "'" : "");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012462
Kanchanapally, Vidyullatha12b66762015-12-31 16:46:42 +053012463 hs2_set_policy(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012464 if (run_hs20_osu(dut, buf) < 0) {
12465 FILE *f;
12466
12467 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to complete OSU");
12468
12469 f = fopen("hs20-osu-client.res", "r");
12470 if (f) {
12471 char resp[400], res[300], *pos;
12472 if (!fgets(res, sizeof(res), f))
12473 res[0] = '\0';
12474 pos = strchr(res, '\n');
12475 if (pos)
12476 *pos = '\0';
12477 fclose(f);
12478 sigma_dut_summary(dut, "hs20-osu-client provisioning failed: %s",
12479 res);
12480 snprintf(resp, sizeof(resp), "notify-send '%s'", res);
12481 if (system(resp) != 0) {
12482 }
12483 snprintf(resp, sizeof(resp),
12484 "SSID,,BSSID,,failureReason,%s", res);
12485 send_resp(dut, conn, SIGMA_COMPLETE, resp);
12486 return 0;
12487 }
12488
12489 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
12490 return 0;
12491 }
12492
12493 if (!prod_ess_assoc)
12494 goto report;
12495
12496 ctrl = open_wpa_mon(intf);
12497 if (ctrl == NULL) {
12498 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
12499 "wpa_supplicant monitor connection");
12500 return -1;
12501 }
12502
12503 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
12504 buf, sizeof(buf));
12505
12506 wpa_ctrl_detach(ctrl);
12507 wpa_ctrl_close(ctrl);
12508
12509 if (res < 0) {
12510 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to connect to "
12511 "network after OSU");
12512 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
12513 return 0;
12514 }
12515
12516report:
12517 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
12518 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
12519 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to get BSSID/SSID");
12520 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
12521 return 0;
12522 }
12523
12524 snprintf(buf, sizeof(buf), "SSID,%s,BSSID,%s", ssid, bssid);
12525 send_resp(dut, conn, SIGMA_COMPLETE, buf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012526 return 0;
12527}
12528
12529
12530static int cmd_sta_policy_update(struct sigma_dut *dut, struct sigma_conn *conn,
12531 struct sigma_cmd *cmd)
12532{
12533 const char *val;
12534 int timeout = 120;
12535
12536 val = get_param(cmd, "PolicyUpdate");
12537 if (val == NULL || atoi(val) == 0)
12538 return 1; /* No operation requested */
12539
12540 val = get_param(cmd, "Timeout");
12541 if (val)
12542 timeout = atoi(val);
12543
12544 if (timeout) {
12545 /* TODO: time out the command and return
12546 * PolicyUpdateStatus,TIMEOUT if needed. */
12547 }
12548
12549 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger policy update");
12550 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
12551 if (run_hs20_osu(dut, "pol_upd fqdn=wi-fi.org") < 0) {
12552 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,FAIL");
12553 return 0;
12554 }
12555
12556 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,SUCCESS");
12557 return 0;
12558}
12559
12560
12561static int cmd_sta_er_config(struct sigma_dut *dut, struct sigma_conn *conn,
12562 struct sigma_cmd *cmd)
12563{
12564 struct wpa_ctrl *ctrl;
12565 const char *intf = get_param(cmd, "Interface");
12566 const char *bssid = get_param(cmd, "Bssid");
12567 const char *ssid = get_param(cmd, "SSID");
12568 const char *security = get_param(cmd, "Security");
12569 const char *passphrase = get_param(cmd, "Passphrase");
12570 const char *pin = get_param(cmd, "PIN");
12571 char buf[1000];
12572 char ssid_hex[200], passphrase_hex[200];
12573 const char *keymgmt, *cipher;
12574
12575 if (intf == NULL)
12576 intf = get_main_ifname();
12577
12578 if (!bssid) {
12579 send_resp(dut, conn, SIGMA_ERROR,
12580 "ErrorCode,Missing Bssid argument");
12581 return 0;
12582 }
12583
12584 if (!ssid) {
12585 send_resp(dut, conn, SIGMA_ERROR,
12586 "ErrorCode,Missing SSID argument");
12587 return 0;
12588 }
12589
12590 if (!security) {
12591 send_resp(dut, conn, SIGMA_ERROR,
12592 "ErrorCode,Missing Security argument");
12593 return 0;
12594 }
12595
12596 if (!passphrase) {
12597 send_resp(dut, conn, SIGMA_ERROR,
12598 "ErrorCode,Missing Passphrase argument");
12599 return 0;
12600 }
12601
12602 if (!pin) {
12603 send_resp(dut, conn, SIGMA_ERROR,
12604 "ErrorCode,Missing PIN argument");
12605 return 0;
12606 }
12607
vamsi krishna8c9c1562017-05-12 15:51:46 +053012608 if (2 * strlen(ssid) >= sizeof(ssid_hex) ||
12609 2 * strlen(passphrase) >= sizeof(passphrase_hex)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012610 send_resp(dut, conn, SIGMA_ERROR,
12611 "ErrorCode,Too long SSID/passphrase");
12612 return 0;
12613 }
12614
12615 ctrl = open_wpa_mon(intf);
12616 if (ctrl == NULL) {
12617 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
12618 "wpa_supplicant monitor connection");
12619 return -2;
12620 }
12621
12622 if (strcasecmp(security, "wpa2-psk") == 0) {
12623 keymgmt = "WPA2PSK";
12624 cipher = "CCMP";
12625 } else {
12626 wpa_ctrl_detach(ctrl);
12627 wpa_ctrl_close(ctrl);
12628 send_resp(dut, conn, SIGMA_ERROR,
12629 "ErrorCode,Unsupported Security value");
12630 return 0;
12631 }
12632
12633 ascii2hexstr(ssid, ssid_hex);
12634 ascii2hexstr(passphrase, passphrase_hex);
12635 snprintf(buf, sizeof(buf), "WPS_REG %s %s %s %s %s %s",
12636 bssid, pin, ssid_hex, keymgmt, cipher, passphrase_hex);
12637
12638 if (wpa_command(intf, buf) < 0) {
12639 wpa_ctrl_detach(ctrl);
12640 wpa_ctrl_close(ctrl);
12641 send_resp(dut, conn, SIGMA_ERROR,
12642 "ErrorCode,Failed to start registrar");
12643 return 0;
12644 }
12645
12646 snprintf(dut->er_oper_bssid, sizeof(dut->er_oper_bssid), "%s", bssid);
12647 dut->er_oper_performed = 1;
12648
12649 return wps_connection_event(dut, conn, ctrl, intf, 0);
12650}
12651
12652
12653static int cmd_sta_wps_connect_pw_token(struct sigma_dut *dut,
12654 struct sigma_conn *conn,
12655 struct sigma_cmd *cmd)
12656{
12657 struct wpa_ctrl *ctrl;
12658 const char *intf = get_param(cmd, "Interface");
12659 const char *bssid = get_param(cmd, "Bssid");
12660 char buf[100];
12661
12662 if (!bssid) {
12663 send_resp(dut, conn, SIGMA_ERROR,
12664 "ErrorCode,Missing Bssid argument");
12665 return 0;
12666 }
12667
12668 ctrl = open_wpa_mon(intf);
12669 if (ctrl == NULL) {
12670 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
12671 "wpa_supplicant monitor connection");
12672 return -2;
12673 }
12674
12675 snprintf(buf, sizeof(buf), "WPS_NFC %s", bssid);
12676
12677 if (wpa_command(intf, buf) < 0) {
12678 wpa_ctrl_detach(ctrl);
12679 wpa_ctrl_close(ctrl);
12680 send_resp(dut, conn, SIGMA_ERROR,
12681 "ErrorCode,Failed to start registrar");
12682 return 0;
12683 }
12684
12685 return wps_connection_event(dut, conn, ctrl, intf, 0);
12686}
12687
12688
vamsi krishna9b144002017-09-20 13:28:13 +053012689static int cmd_start_wps_registration(struct sigma_dut *dut,
12690 struct sigma_conn *conn,
12691 struct sigma_cmd *cmd)
12692{
12693 struct wpa_ctrl *ctrl;
12694 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020012695 const char *network_mode = get_param(cmd, "network_mode");
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020012696 const char *config_method = get_param(cmd, "WPSConfigMethod");
12697 const char *role;
vamsi krishna9b144002017-09-20 13:28:13 +053012698 int res;
12699 char buf[256];
12700 const char *events[] = {
12701 "CTRL-EVENT-CONNECTED",
12702 "WPS-OVERLAP-DETECTED",
12703 "WPS-TIMEOUT",
12704 "WPS-FAIL",
12705 NULL
12706 };
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020012707 int id = 0;
vamsi krishna9b144002017-09-20 13:28:13 +053012708
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020012709 /* 60G WPS tests do not pass Interface parameter */
12710 if (!intf)
12711 intf = get_main_ifname();
12712
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020012713 if (dut->mode == SIGMA_MODE_AP)
12714 return ap_wps_registration(dut, conn, cmd);
12715
12716 if (config_method) {
12717 /* WFA_CS_WPS_PIN_KEYPAD mode is set when using the
12718 * sta_wps_enter_pin before calling start_wps_registration. */
12719 if (strcasecmp(config_method, "PBC") == 0)
12720 dut->wps_method = WFA_CS_WPS_PBC;
12721 }
12722 if (dut->wps_method == WFA_CS_WPS_NOT_READY) {
12723 send_resp(dut, conn, SIGMA_ERROR,
12724 "ErrorCode,WPS parameters not yet set");
12725 return STATUS_SENT;
12726 }
12727
12728 /* Make sure WPS is enabled (also for STA mode) */
12729 dut->wps_disable = 0;
12730
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020012731 if (dut->band == WPS_BAND_60G && network_mode &&
12732 strcasecmp(network_mode, "PBSS") == 0) {
12733 sigma_dut_print(dut, DUT_MSG_DEBUG,
12734 "Set PBSS network mode, network id %d", id);
12735 if (set_network(get_station_ifname(), id, "pbss", "1") < 0)
12736 return -2;
12737 }
12738
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020012739 if (dut->force_rsn_ie) {
12740 sigma_dut_print(dut, DUT_MSG_DEBUG, "Force RSN_IE: %d",
12741 dut->force_rsn_ie);
12742 if (sta_60g_force_rsn_ie(dut, dut->force_rsn_ie) < 0) {
12743 sigma_dut_print(dut, DUT_MSG_INFO,
12744 "Failed to force RSN_IE");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020012745 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020012746 }
12747 }
12748
vamsi krishna9b144002017-09-20 13:28:13 +053012749 ctrl = open_wpa_mon(intf);
12750 if (!ctrl) {
12751 sigma_dut_print(dut, DUT_MSG_ERROR,
12752 "Failed to open wpa_supplicant monitor connection");
12753 return -2;
12754 }
12755
12756 role = get_param(cmd, "WpsRole");
12757 if (!role) {
12758 send_resp(dut, conn, SIGMA_INVALID,
12759 "ErrorCode,WpsRole not provided");
12760 goto fail;
12761 }
12762
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020012763 if (strcasecmp(role, "Enrollee") != 0) {
12764 /* Registrar role for STA not supported */
12765 send_resp(dut, conn, SIGMA_ERROR,
12766 "ErrorCode,Unsupported WpsRole value");
12767 goto fail;
12768 }
12769
12770 if (is_60g_sigma_dut(dut)) {
12771 if (dut->wps_method == WFA_CS_WPS_PBC)
12772 snprintf(buf, sizeof(buf), "WPS_PBC");
12773 else /* WFA_CS_WPS_PIN_KEYPAD */
12774 snprintf(buf, sizeof(buf), "WPS_PIN any %s",
12775 dut->wps_pin);
12776 if (wpa_command(intf, buf) < 0) {
12777 send_resp(dut, conn, SIGMA_ERROR,
12778 "ErrorCode,Failed to start WPS");
vamsi krishna9b144002017-09-20 13:28:13 +053012779 goto fail;
12780 }
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020012781 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
12782 if (res < 0) {
12783 send_resp(dut, conn, SIGMA_ERROR,
12784 "ErrorCode,WPS connection did not complete");
12785 goto fail;
12786 }
12787 if (strstr(buf, "WPS-TIMEOUT")) {
12788 send_resp(dut, conn, SIGMA_COMPLETE, "WpsState,NoPeer");
12789 } else if (strstr(buf, "WPS-OVERLAP-DETECTED")) {
12790 send_resp(dut, conn, SIGMA_COMPLETE,
12791 "WpsState,OverlapSession");
12792 } else if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
12793 send_resp(dut, conn, SIGMA_COMPLETE,
12794 "WpsState,Successful");
12795 } else {
12796 send_resp(dut, conn, SIGMA_COMPLETE,
12797 "WpsState,Failure");
12798 }
12799 } else {
12800 if (dut->wps_method == WFA_CS_WPS_PBC) {
vamsi krishna9b144002017-09-20 13:28:13 +053012801 if (wpa_command(intf, "WPS_PBC") < 0) {
12802 send_resp(dut, conn, SIGMA_ERROR,
12803 "ErrorCode,Failed to enable PBC");
12804 goto fail;
12805 }
12806 } else {
12807 /* TODO: PIN method */
12808 send_resp(dut, conn, SIGMA_ERROR,
12809 "ErrorCode,Unsupported WpsConfigMethod value");
12810 goto fail;
12811 }
12812 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
12813 if (res < 0) {
12814 send_resp(dut, conn, SIGMA_ERROR,
12815 "ErrorCode,WPS connection did not complete");
12816 goto fail;
12817 }
12818 if (strstr(buf, "WPS-TIMEOUT")) {
12819 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,NoPeer");
12820 } else if (strstr(buf, "WPS-OVERLAP-DETECTED")) {
12821 send_resp(dut, conn, SIGMA_ERROR,
12822 "ErrorCode,OverlapSession");
12823 } else if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
12824 send_resp(dut, conn, SIGMA_COMPLETE, "Successful");
12825 } else {
12826 send_resp(dut, conn, SIGMA_ERROR,
12827 "ErrorCode,WPS operation failed");
12828 }
vamsi krishna9b144002017-09-20 13:28:13 +053012829 }
12830
12831fail:
12832 wpa_ctrl_detach(ctrl);
12833 wpa_ctrl_close(ctrl);
12834 return 0;
12835}
12836
12837
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012838static int req_intf(struct sigma_cmd *cmd)
12839{
12840 return get_param(cmd, "interface") == NULL ? -1 : 0;
12841}
12842
12843
12844void sta_register_cmds(void)
12845{
12846 sigma_dut_reg_cmd("sta_get_ip_config", req_intf,
12847 cmd_sta_get_ip_config);
12848 sigma_dut_reg_cmd("sta_set_ip_config", req_intf,
12849 cmd_sta_set_ip_config);
12850 sigma_dut_reg_cmd("sta_get_info", req_intf, cmd_sta_get_info);
12851 sigma_dut_reg_cmd("sta_get_mac_address", req_intf,
12852 cmd_sta_get_mac_address);
12853 sigma_dut_reg_cmd("sta_is_connected", req_intf, cmd_sta_is_connected);
12854 sigma_dut_reg_cmd("sta_verify_ip_connection", req_intf,
12855 cmd_sta_verify_ip_connection);
12856 sigma_dut_reg_cmd("sta_get_bssid", req_intf, cmd_sta_get_bssid);
12857 sigma_dut_reg_cmd("sta_set_encryption", req_intf,
12858 cmd_sta_set_encryption);
12859 sigma_dut_reg_cmd("sta_set_psk", req_intf, cmd_sta_set_psk);
12860 sigma_dut_reg_cmd("sta_set_eaptls", req_intf, cmd_sta_set_eaptls);
12861 sigma_dut_reg_cmd("sta_set_eapttls", req_intf, cmd_sta_set_eapttls);
12862 sigma_dut_reg_cmd("sta_set_eapsim", req_intf, cmd_sta_set_eapsim);
12863 sigma_dut_reg_cmd("sta_set_peap", req_intf, cmd_sta_set_peap);
12864 sigma_dut_reg_cmd("sta_set_eapfast", req_intf, cmd_sta_set_eapfast);
12865 sigma_dut_reg_cmd("sta_set_eapaka", req_intf, cmd_sta_set_eapaka);
12866 sigma_dut_reg_cmd("sta_set_eapakaprime", req_intf,
12867 cmd_sta_set_eapakaprime);
12868 sigma_dut_reg_cmd("sta_set_security", req_intf, cmd_sta_set_security);
12869 sigma_dut_reg_cmd("sta_set_uapsd", req_intf, cmd_sta_set_uapsd);
12870 /* TODO: sta_set_ibss */
12871 /* TODO: sta_set_mode */
12872 sigma_dut_reg_cmd("sta_set_wmm", req_intf, cmd_sta_set_wmm);
12873 sigma_dut_reg_cmd("sta_associate", req_intf, cmd_sta_associate);
12874 /* TODO: sta_up_load */
12875 sigma_dut_reg_cmd("sta_preset_testparameters", req_intf,
12876 cmd_sta_preset_testparameters);
12877 /* TODO: sta_set_system */
12878 sigma_dut_reg_cmd("sta_set_11n", req_intf, cmd_sta_set_11n);
12879 /* TODO: sta_set_rifs_test */
12880 sigma_dut_reg_cmd("sta_set_wireless", req_intf, cmd_sta_set_wireless);
12881 sigma_dut_reg_cmd("sta_send_addba", req_intf, cmd_sta_send_addba);
12882 /* TODO: sta_send_coexist_mgmt */
12883 sigma_dut_reg_cmd("sta_disconnect", req_intf, cmd_sta_disconnect);
12884 sigma_dut_reg_cmd("sta_reassoc", req_intf, cmd_sta_reassoc);
12885 sigma_dut_reg_cmd("sta_reassociate", req_intf, cmd_sta_reassoc);
12886 sigma_dut_reg_cmd("sta_reset_default", req_intf,
12887 cmd_sta_reset_default);
12888 sigma_dut_reg_cmd("sta_send_frame", req_intf, cmd_sta_send_frame);
12889 sigma_dut_reg_cmd("sta_set_macaddr", req_intf, cmd_sta_set_macaddr);
12890 sigma_dut_reg_cmd("sta_set_rfeature", req_intf, cmd_sta_set_rfeature);
12891 sigma_dut_reg_cmd("sta_set_radio", req_intf, cmd_sta_set_radio);
12892 sigma_dut_reg_cmd("sta_set_pwrsave", req_intf, cmd_sta_set_pwrsave);
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020012893 sigma_dut_reg_cmd("sta_set_power_save", req_intf, cmd_sta_set_pwrsave);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012894 sigma_dut_reg_cmd("sta_bssid_pool", req_intf, cmd_sta_bssid_pool);
12895 sigma_dut_reg_cmd("sta_reset_parm", req_intf, cmd_sta_reset_parm);
12896 sigma_dut_reg_cmd("sta_get_key", req_intf, cmd_sta_get_key);
12897 sigma_dut_reg_cmd("sta_hs2_associate", req_intf,
12898 cmd_sta_hs2_associate);
Jouni Malinenb639f1c2018-09-13 02:39:46 +030012899 sigma_dut_reg_cmd("sta_hs2_venue_info", req_intf,
12900 cmd_sta_hs2_venue_info);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012901 sigma_dut_reg_cmd("sta_add_credential", req_intf,
12902 cmd_sta_add_credential);
12903 sigma_dut_reg_cmd("sta_scan", req_intf, cmd_sta_scan);
Jouni Malinen5e5d43d2018-01-10 17:29:33 +020012904 sigma_dut_reg_cmd("sta_scan_bss", req_intf, cmd_sta_scan_bss);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012905 sigma_dut_reg_cmd("sta_set_systime", NULL, cmd_sta_set_systime);
12906 sigma_dut_reg_cmd("sta_osu", req_intf, cmd_sta_osu);
12907 sigma_dut_reg_cmd("sta_policy_update", req_intf, cmd_sta_policy_update);
12908 sigma_dut_reg_cmd("sta_er_config", NULL, cmd_sta_er_config);
12909 sigma_dut_reg_cmd("sta_wps_connect_pw_token", req_intf,
12910 cmd_sta_wps_connect_pw_token);
Jouni Malinen82905202018-04-29 17:20:10 +030012911 sigma_dut_reg_cmd("sta_exec_action", NULL, cmd_sta_exec_action);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012912 sigma_dut_reg_cmd("sta_get_events", req_intf, cmd_sta_get_events);
12913 sigma_dut_reg_cmd("sta_get_parameter", req_intf, cmd_sta_get_parameter);
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020012914 sigma_dut_reg_cmd("start_wps_registration", NULL,
vamsi krishna9b144002017-09-20 13:28:13 +053012915 cmd_start_wps_registration);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012916}