blob: ec257c0b30d20c61a20b494de7a26f7bb8990477 [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;
Jouni Malinen53264f62019-05-03 13:04:40 +03002169 char buf[200], buf2[300];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002170#ifdef ANDROID
2171 unsigned char kvalue[KEYSTORE_MESSAGE_SIZE];
2172 int length;
2173#endif /* ANDROID */
Jouni Malinen8179fee2019-03-28 03:19:47 +02002174 int erp = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002175
2176 id = set_wpa_common(dut, conn, ifname, cmd);
2177 if (id < 0)
2178 return id;
2179
2180 val = get_param(cmd, "keyMgmtType");
2181 alg = get_param(cmd, "micAlg");
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302182 akm = get_param(cmd, "AKMSuiteType");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002183
Jouni Malinenad395a22017-09-01 21:13:46 +03002184 if (val && strcasecmp(val, "SuiteB") == 0) {
2185 if (set_network(ifname, id, "key_mgmt", "WPA-EAP-SUITE-B-192") <
2186 0)
2187 return -2;
2188 } else if (alg && strcasecmp(alg, "SHA-256") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002189 if (set_network(ifname, id, "key_mgmt", "WPA-EAP-SHA256") < 0)
2190 return -2;
2191 } else if (alg && strcasecmp(alg, "SHA-1") == 0) {
2192 if (set_network(ifname, id, "key_mgmt", "WPA-EAP") < 0)
2193 return -2;
2194 } else if (val && strcasecmp(val, "wpa2-ft") == 0) {
2195 if (set_network(ifname, id, "key_mgmt", "FT-EAP") < 0)
2196 return -2;
Jouni Malinend6a9d692019-03-28 03:01:24 +02002197 } else if (!akm &&
2198 ((val && strcasecmp(val, "wpa2-sha256") == 0) ||
2199 dut->sta_pmf == STA_PMF_REQUIRED)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002200 if (set_network(ifname, id, "key_mgmt",
2201 "WPA-EAP WPA-EAP-SHA256") < 0)
2202 return -2;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302203 } else if (akm && atoi(akm) == 14) {
2204 if (dut->sta_pmf == STA_PMF_OPTIONAL ||
2205 dut->sta_pmf == STA_PMF_REQUIRED) {
2206 if (set_network(ifname, id, "key_mgmt",
2207 "WPA-EAP-SHA256 FILS-SHA256") < 0)
2208 return -2;
2209 } else {
2210 if (set_network(ifname, id, "key_mgmt",
2211 "WPA-EAP FILS-SHA256") < 0)
2212 return -2;
2213 }
2214
Jouni Malinen8179fee2019-03-28 03:19:47 +02002215 erp = 1;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302216 } else if (akm && atoi(akm) == 15) {
2217 if (dut->sta_pmf == STA_PMF_OPTIONAL ||
2218 dut->sta_pmf == STA_PMF_REQUIRED) {
2219 if (set_network(ifname, id, "key_mgmt",
2220 "WPA-EAP-SHA256 FILS-SHA384") < 0)
2221 return -2;
2222 } else {
2223 if (set_network(ifname, id, "key_mgmt",
2224 "WPA-EAP FILS-SHA384") < 0)
2225 return -2;
2226 }
2227
Jouni Malinen8179fee2019-03-28 03:19:47 +02002228 erp = 1;
Jouni Malinend6a9d692019-03-28 03:01:24 +02002229 } else if (!akm && dut->sta_pmf == STA_PMF_OPTIONAL) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002230 if (set_network(ifname, id, "key_mgmt",
2231 "WPA-EAP WPA-EAP-SHA256") < 0)
2232 return -2;
Jouni Malinend6a9d692019-03-28 03:01:24 +02002233 } else if (!akm) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002234 if (set_network(ifname, id, "key_mgmt", "WPA-EAP") < 0)
2235 return -2;
2236 }
2237
2238 val = get_param(cmd, "trustedRootCA");
2239 if (val) {
2240#ifdef ANDROID
2241 snprintf(buf, sizeof(buf), "CACERT_%s", val);
2242 length = android_keystore_get(ANDROID_KEYSTORE_GET, buf,
2243 kvalue);
2244 if (length > 0) {
2245 sigma_dut_print(dut, DUT_MSG_INFO,
2246 "Use Android keystore [%s]", buf);
2247 snprintf(buf, sizeof(buf), "keystore://CACERT_%s",
2248 val);
2249 goto ca_cert_selected;
2250 }
2251#endif /* ANDROID */
2252
2253 snprintf(buf, sizeof(buf), "%s/%s", sigma_cert_path, val);
2254#ifdef __linux__
2255 if (!file_exists(buf)) {
2256 char msg[300];
2257 snprintf(msg, sizeof(msg), "ErrorCode,trustedRootCA "
2258 "file (%s) not found", buf);
2259 send_resp(dut, conn, SIGMA_ERROR, msg);
2260 return -3;
2261 }
2262#endif /* __linux__ */
2263#ifdef ANDROID
2264ca_cert_selected:
2265#endif /* ANDROID */
2266 if (set_network_quoted(ifname, id, "ca_cert", buf) < 0)
2267 return -2;
2268 }
2269
Jouni Malinen53264f62019-05-03 13:04:40 +03002270 val = get_param(cmd, "ServerCert");
2271 if (val) {
2272 FILE *f;
2273 char *result = NULL, *pos;
2274
2275 snprintf(buf, sizeof(buf), "%s/%s.sha256", sigma_cert_path,
2276 val);
2277 f = fopen(buf, "r");
2278 if (f) {
2279 result = fgets(buf, sizeof(buf), f);
2280 fclose(f);
2281 }
2282 if (!result) {
2283 snprintf(buf2, sizeof(buf2),
2284 "ErrorCode,ServerCert hash could not be read from %s",
2285 buf);
2286 send_resp(dut, conn, SIGMA_ERROR, buf2);
2287 return STATUS_SENT_ERROR;
2288 }
2289 pos = strchr(buf, '\n');
2290 if (pos)
2291 *pos = '\0';
2292 snprintf(buf2, sizeof(buf2), "hash://server/sha256/%s", buf);
2293 if (set_network_quoted(ifname, id, "ca_cert", buf2) < 0)
2294 return ERROR_SEND_STATUS;
2295 }
2296
Jouni Malinen96f84b02019-05-03 12:32:56 +03002297 val = get_param(cmd, "Domain");
2298 if (val && set_network_quoted(ifname, id, "domain_match", val) < 0)
2299 return ERROR_SEND_STATUS;
2300
2301 val = get_param(cmd, "DomainSuffix");
2302 if (val &&
2303 set_network_quoted(ifname, id, "domain_suffix_match", val) < 0)
2304 return ERROR_SEND_STATUS;
2305
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302306 if (username_identity) {
2307 val = get_param(cmd, "username");
2308 if (val) {
2309 if (set_network_quoted(ifname, id, "identity", val) < 0)
2310 return -2;
2311 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002312
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302313 val = get_param(cmd, "password");
2314 if (val) {
2315 if (set_network_quoted(ifname, id, "password", val) < 0)
2316 return -2;
2317 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002318 }
2319
Jouni Malinen8179fee2019-03-28 03:19:47 +02002320 if (dut->akm_values &
2321 ((1 << AKM_FILS_SHA256) |
2322 (1 << AKM_FILS_SHA384) |
2323 (1 << AKM_FT_FILS_SHA256) |
2324 (1 << AKM_FT_FILS_SHA384)))
2325 erp = 1;
2326 if (erp && set_network(ifname, id, "erp", "1") < 0)
2327 return ERROR_SEND_STATUS;
2328
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002329 return id;
2330}
2331
2332
Jouni Malinen5eabb2a2017-10-03 18:17:30 +03002333static int set_tls_cipher(const char *ifname, int id, const char *cipher)
2334{
2335 const char *val;
2336
2337 if (!cipher)
2338 return 0;
2339
2340 if (strcasecmp(cipher, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384") == 0)
2341 val = "ECDHE-ECDSA-AES256-GCM-SHA384";
2342 else if (strcasecmp(cipher,
2343 "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384") == 0)
2344 val = "ECDHE-RSA-AES256-GCM-SHA384";
2345 else if (strcasecmp(cipher, "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384") == 0)
2346 val = "DHE-RSA-AES256-GCM-SHA384";
2347 else if (strcasecmp(cipher,
2348 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256") == 0)
2349 val = "ECDHE-ECDSA-AES128-GCM-SHA256";
2350 else
2351 return -1;
2352
2353 /* Need to clear phase1="tls_suiteb=1" to allow cipher enforcement */
2354 set_network_quoted(ifname, id, "phase1", "");
2355
2356 return set_network_quoted(ifname, id, "openssl_ciphers", val);
2357}
2358
2359
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002360static int cmd_sta_set_eaptls(struct sigma_dut *dut, struct sigma_conn *conn,
2361 struct sigma_cmd *cmd)
2362{
2363 const char *intf = get_param(cmd, "Interface");
2364 const char *ifname, *val;
2365 int id;
2366 char buf[200];
2367#ifdef ANDROID
2368 unsigned char kvalue[KEYSTORE_MESSAGE_SIZE];
2369 int length;
2370 int jb_or_newer = 0;
2371 char prop[PROPERTY_VALUE_MAX];
2372#endif /* ANDROID */
2373
2374 if (intf == NULL)
2375 return -1;
2376
2377 if (strcmp(intf, get_main_ifname()) == 0)
2378 ifname = get_station_ifname();
2379 else
2380 ifname = intf;
2381
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302382 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002383 if (id < 0)
2384 return id;
2385
2386 if (set_network(ifname, id, "eap", "TLS") < 0)
2387 return -2;
2388
Pradeep Reddy POTTETI9f6c2132016-05-05 16:28:19 +05302389 if (!get_param(cmd, "username") &&
2390 set_network_quoted(ifname, id, "identity",
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002391 "wifi-user@wifilabs.local") < 0)
2392 return -2;
2393
2394 val = get_param(cmd, "clientCertificate");
2395 if (val == NULL)
2396 return -1;
2397#ifdef ANDROID
2398 snprintf(buf, sizeof(buf), "USRPKEY_%s", val);
2399 length = android_keystore_get(ANDROID_KEYSTORE_GET, buf, kvalue);
2400 if (length < 0) {
2401 /*
2402 * JB started reporting keystore type mismatches, so retry with
2403 * the GET_PUBKEY command if the generic GET fails.
2404 */
2405 length = android_keystore_get(ANDROID_KEYSTORE_GET_PUBKEY,
2406 buf, kvalue);
2407 }
2408
2409 if (property_get("ro.build.version.release", prop, NULL) != 0) {
2410 sigma_dut_print(dut, DUT_MSG_DEBUG, "Android release %s", prop);
2411 if (strncmp(prop, "4.0", 3) != 0)
2412 jb_or_newer = 1;
2413 } else
2414 jb_or_newer = 1; /* assume newer */
2415
2416 if (jb_or_newer && length > 0) {
2417 sigma_dut_print(dut, DUT_MSG_INFO,
2418 "Use Android keystore [%s]", buf);
2419 if (set_network(ifname, id, "engine", "1") < 0)
2420 return -2;
2421 if (set_network_quoted(ifname, id, "engine_id", "keystore") < 0)
2422 return -2;
2423 snprintf(buf, sizeof(buf), "USRPKEY_%s", val);
2424 if (set_network_quoted(ifname, id, "key_id", buf) < 0)
2425 return -2;
2426 snprintf(buf, sizeof(buf), "keystore://USRCERT_%s", val);
2427 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
2428 return -2;
2429 return 1;
2430 } else if (length > 0) {
2431 sigma_dut_print(dut, DUT_MSG_INFO,
2432 "Use Android keystore [%s]", buf);
2433 snprintf(buf, sizeof(buf), "keystore://USRPKEY_%s", val);
2434 if (set_network_quoted(ifname, id, "private_key", buf) < 0)
2435 return -2;
2436 snprintf(buf, sizeof(buf), "keystore://USRCERT_%s", val);
2437 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
2438 return -2;
2439 return 1;
2440 }
2441#endif /* ANDROID */
2442
2443 snprintf(buf, sizeof(buf), "%s/%s", sigma_cert_path, val);
2444#ifdef __linux__
2445 if (!file_exists(buf)) {
2446 char msg[300];
2447 snprintf(msg, sizeof(msg), "ErrorCode,clientCertificate file "
2448 "(%s) not found", buf);
2449 send_resp(dut, conn, SIGMA_ERROR, msg);
2450 return -3;
2451 }
2452#endif /* __linux__ */
2453 if (set_network_quoted(ifname, id, "private_key", buf) < 0)
2454 return -2;
2455 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
2456 return -2;
2457
2458 if (set_network_quoted(ifname, id, "private_key_passwd", "wifi") < 0)
2459 return -2;
2460
Jouni Malinen5eabb2a2017-10-03 18:17:30 +03002461 val = get_param(cmd, "keyMgmtType");
2462 if (val && strcasecmp(val, "SuiteB") == 0) {
2463 val = get_param(cmd, "CertType");
2464 if (val && strcasecmp(val, "RSA") == 0) {
2465 if (set_network_quoted(ifname, id, "phase1",
2466 "tls_suiteb=1") < 0)
2467 return -2;
2468 } else {
2469 if (set_network_quoted(ifname, id, "openssl_ciphers",
2470 "SUITEB192") < 0)
2471 return -2;
2472 }
2473
2474 val = get_param(cmd, "TLSCipher");
2475 if (set_tls_cipher(ifname, id, val) < 0) {
2476 send_resp(dut, conn, SIGMA_ERROR,
2477 "ErrorCode,Unsupported TLSCipher value");
2478 return -3;
2479 }
2480 }
2481
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002482 return 1;
2483}
2484
2485
2486static int cmd_sta_set_eapttls(struct sigma_dut *dut, struct sigma_conn *conn,
2487 struct sigma_cmd *cmd)
2488{
2489 const char *intf = get_param(cmd, "Interface");
2490 const char *ifname;
2491 int id;
2492
2493 if (intf == NULL)
2494 return -1;
2495
2496 if (strcmp(intf, get_main_ifname()) == 0)
2497 ifname = get_station_ifname();
2498 else
2499 ifname = intf;
2500
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302501 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002502 if (id < 0)
2503 return id;
2504
2505 if (set_network(ifname, id, "eap", "TTLS") < 0) {
2506 send_resp(dut, conn, SIGMA_ERROR,
2507 "errorCode,Failed to set TTLS method");
2508 return 0;
2509 }
2510
2511 if (set_network_quoted(ifname, id, "phase2", "auth=MSCHAPV2") < 0) {
2512 send_resp(dut, conn, SIGMA_ERROR,
2513 "errorCode,Failed to set MSCHAPv2 for TTLS Phase 2");
2514 return 0;
2515 }
2516
2517 return 1;
2518}
2519
2520
2521static int cmd_sta_set_eapsim(struct sigma_dut *dut, struct sigma_conn *conn,
2522 struct sigma_cmd *cmd)
2523{
2524 const char *intf = get_param(cmd, "Interface");
2525 const char *ifname;
2526 int id;
2527
2528 if (intf == NULL)
2529 return -1;
2530
2531 if (strcmp(intf, get_main_ifname()) == 0)
2532 ifname = get_station_ifname();
2533 else
2534 ifname = intf;
2535
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302536 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002537 if (id < 0)
2538 return id;
2539
2540 if (set_network(ifname, id, "eap", "SIM") < 0)
2541 return -2;
2542
2543 return 1;
2544}
2545
2546
2547static int cmd_sta_set_peap(struct sigma_dut *dut, struct sigma_conn *conn,
2548 struct sigma_cmd *cmd)
2549{
2550 const char *intf = get_param(cmd, "Interface");
2551 const char *ifname, *val;
2552 int id;
2553 char buf[100];
2554
2555 if (intf == NULL)
2556 return -1;
2557
2558 if (strcmp(intf, get_main_ifname()) == 0)
2559 ifname = get_station_ifname();
2560 else
2561 ifname = intf;
2562
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302563 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002564 if (id < 0)
2565 return id;
2566
2567 if (set_network(ifname, id, "eap", "PEAP") < 0)
2568 return -2;
2569
2570 val = get_param(cmd, "innerEAP");
2571 if (val) {
2572 if (strcasecmp(val, "MSCHAPv2") == 0) {
2573 if (set_network_quoted(ifname, id, "phase2",
2574 "auth=MSCHAPV2") < 0)
2575 return -2;
2576 } else if (strcasecmp(val, "GTC") == 0) {
2577 if (set_network_quoted(ifname, id, "phase2",
2578 "auth=GTC") < 0)
2579 return -2;
2580 } else
2581 return -1;
2582 }
2583
2584 val = get_param(cmd, "peapVersion");
2585 if (val) {
2586 int ver = atoi(val);
2587 if (ver < 0 || ver > 1)
2588 return -1;
2589 snprintf(buf, sizeof(buf), "peapver=%d", ver);
2590 if (set_network_quoted(ifname, id, "phase1", buf) < 0)
2591 return -2;
2592 }
2593
2594 return 1;
2595}
2596
2597
2598static int cmd_sta_set_eapfast(struct sigma_dut *dut, struct sigma_conn *conn,
2599 struct sigma_cmd *cmd)
2600{
2601 const char *intf = get_param(cmd, "Interface");
2602 const char *ifname, *val;
2603 int id;
2604 char buf[100];
2605
2606 if (intf == NULL)
2607 return -1;
2608
2609 if (strcmp(intf, get_main_ifname()) == 0)
2610 ifname = get_station_ifname();
2611 else
2612 ifname = intf;
2613
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302614 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002615 if (id < 0)
2616 return id;
2617
2618 if (set_network(ifname, id, "eap", "FAST") < 0)
2619 return -2;
2620
2621 val = get_param(cmd, "innerEAP");
2622 if (val) {
2623 if (strcasecmp(val, "MSCHAPV2") == 0) {
2624 if (set_network_quoted(ifname, id, "phase2",
2625 "auth=MSCHAPV2") < 0)
2626 return -2;
2627 } else if (strcasecmp(val, "GTC") == 0) {
2628 if (set_network_quoted(ifname, id, "phase2",
2629 "auth=GTC") < 0)
2630 return -2;
2631 } else
2632 return -1;
2633 }
2634
2635 val = get_param(cmd, "validateServer");
2636 if (val) {
2637 /* TODO */
2638 sigma_dut_print(dut, DUT_MSG_INFO, "Ignored EAP-FAST "
2639 "validateServer=%s", val);
2640 }
2641
2642 val = get_param(cmd, "pacFile");
2643 if (val) {
2644 snprintf(buf, sizeof(buf), "blob://%s", val);
2645 if (set_network_quoted(ifname, id, "pac_file", buf) < 0)
2646 return -2;
2647 }
2648
2649 if (set_network_quoted(ifname, id, "phase1", "fast_provisioning=2") <
2650 0)
2651 return -2;
2652
2653 return 1;
2654}
2655
2656
2657static int cmd_sta_set_eapaka(struct sigma_dut *dut, struct sigma_conn *conn,
2658 struct sigma_cmd *cmd)
2659{
2660 const char *intf = get_param(cmd, "Interface");
2661 const char *ifname;
2662 int id;
2663
2664 if (intf == NULL)
2665 return -1;
2666
2667 if (strcmp(intf, get_main_ifname()) == 0)
2668 ifname = get_station_ifname();
2669 else
2670 ifname = intf;
2671
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302672 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002673 if (id < 0)
2674 return id;
2675
2676 if (set_network(ifname, id, "eap", "AKA") < 0)
2677 return -2;
2678
2679 return 1;
2680}
2681
2682
2683static int cmd_sta_set_eapakaprime(struct sigma_dut *dut,
2684 struct sigma_conn *conn,
2685 struct sigma_cmd *cmd)
2686{
2687 const char *intf = get_param(cmd, "Interface");
2688 const char *ifname;
2689 int id;
2690
2691 if (intf == NULL)
2692 return -1;
2693
2694 if (strcmp(intf, get_main_ifname()) == 0)
2695 ifname = get_station_ifname();
2696 else
2697 ifname = intf;
2698
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302699 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002700 if (id < 0)
2701 return id;
2702
2703 if (set_network(ifname, id, "eap", "AKA'") < 0)
2704 return -2;
2705
2706 return 1;
2707}
2708
2709
2710static int sta_set_open(struct sigma_dut *dut, struct sigma_conn *conn,
2711 struct sigma_cmd *cmd)
2712{
2713 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002714 const char *network_mode = get_param(cmd, "network_mode");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002715 const char *ifname;
2716 int id;
2717
2718 if (strcmp(intf, get_main_ifname()) == 0)
2719 ifname = get_station_ifname();
2720 else
2721 ifname = intf;
2722
2723 id = add_network_common(dut, conn, ifname, cmd);
2724 if (id < 0)
2725 return id;
2726
2727 if (set_network(ifname, id, "key_mgmt", "NONE") < 0)
2728 return -2;
2729
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002730 if (dut->program == PROGRAM_60GHZ && network_mode &&
2731 strcasecmp(network_mode, "PBSS") == 0 &&
2732 set_network(ifname, id, "pbss", "1") < 0)
2733 return -2;
2734
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002735 return 1;
2736}
2737
2738
Jouni Malinen47dcc952017-10-09 16:43:24 +03002739static int sta_set_owe(struct sigma_dut *dut, struct sigma_conn *conn,
2740 struct sigma_cmd *cmd)
2741{
2742 const char *intf = get_param(cmd, "Interface");
2743 const char *ifname, *val;
2744 int id;
2745
2746 if (intf == NULL)
2747 return -1;
2748
2749 if (strcmp(intf, get_main_ifname()) == 0)
2750 ifname = get_station_ifname();
2751 else
2752 ifname = intf;
2753
2754 id = set_wpa_common(dut, conn, ifname, cmd);
2755 if (id < 0)
2756 return id;
2757
2758 if (set_network(ifname, id, "key_mgmt", "OWE") < 0)
2759 return -2;
2760
2761 val = get_param(cmd, "ECGroupID");
Jouni Malinenfac9cad2017-10-10 18:35:55 +03002762 if (val && strcmp(val, "0") == 0) {
2763 if (wpa_command(ifname,
2764 "VENDOR_ELEM_ADD 13 ff23200000783590fb7440e03d5b3b33911f86affdcc6b4411b707846ac4ff08ddc8831ccd") != 0) {
2765 sigma_dut_print(dut, DUT_MSG_ERROR,
2766 "Failed to set OWE DH Param element override");
2767 return -2;
2768 }
2769 } else if (val && set_network(ifname, id, "owe_group", val) < 0) {
Jouni Malinen47dcc952017-10-09 16:43:24 +03002770 sigma_dut_print(dut, DUT_MSG_ERROR,
2771 "Failed to clear owe_group");
2772 return -2;
2773 }
2774
2775 return 1;
2776}
2777
2778
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002779static int cmd_sta_set_security(struct sigma_dut *dut, struct sigma_conn *conn,
2780 struct sigma_cmd *cmd)
2781{
2782 const char *type = get_param(cmd, "Type");
2783
2784 if (type == NULL) {
2785 send_resp(dut, conn, SIGMA_ERROR,
2786 "ErrorCode,Missing Type argument");
2787 return 0;
2788 }
2789
2790 if (strcasecmp(type, "OPEN") == 0)
2791 return sta_set_open(dut, conn, cmd);
Jouni Malinen47dcc952017-10-09 16:43:24 +03002792 if (strcasecmp(type, "OWE") == 0)
2793 return sta_set_owe(dut, conn, cmd);
Jouni Malinen992a81e2017-08-22 13:57:47 +03002794 if (strcasecmp(type, "PSK") == 0 ||
Jouni Malinen0ab50f42017-08-31 01:34:59 +03002795 strcasecmp(type, "PSK-SAE") == 0 ||
Jouni Malinen992a81e2017-08-22 13:57:47 +03002796 strcasecmp(type, "SAE") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002797 return cmd_sta_set_psk(dut, conn, cmd);
2798 if (strcasecmp(type, "EAPTLS") == 0)
2799 return cmd_sta_set_eaptls(dut, conn, cmd);
2800 if (strcasecmp(type, "EAPTTLS") == 0)
2801 return cmd_sta_set_eapttls(dut, conn, cmd);
2802 if (strcasecmp(type, "EAPPEAP") == 0)
2803 return cmd_sta_set_peap(dut, conn, cmd);
2804 if (strcasecmp(type, "EAPSIM") == 0)
2805 return cmd_sta_set_eapsim(dut, conn, cmd);
2806 if (strcasecmp(type, "EAPFAST") == 0)
2807 return cmd_sta_set_eapfast(dut, conn, cmd);
2808 if (strcasecmp(type, "EAPAKA") == 0)
2809 return cmd_sta_set_eapaka(dut, conn, cmd);
2810 if (strcasecmp(type, "EAPAKAPRIME") == 0)
2811 return cmd_sta_set_eapakaprime(dut, conn, cmd);
Amarnath Hullur Subramanyam81b11cd2018-01-30 19:07:17 -08002812 if (strcasecmp(type, "wep") == 0)
2813 return cmd_sta_set_encryption(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002814
2815 send_resp(dut, conn, SIGMA_ERROR,
2816 "ErrorCode,Unsupported Type value");
2817 return 0;
2818}
2819
2820
2821int ath6kl_client_uapsd(struct sigma_dut *dut, const char *intf, int uapsd)
2822{
2823#ifdef __linux__
2824 /* special handling for ath6kl */
2825 char path[128], fname[128], *pos;
2826 ssize_t res;
2827 FILE *f;
2828
Jouni Malinene39cd562019-05-29 23:39:56 +03002829 res = snprintf(fname, sizeof(fname), "/sys/class/net/%s/phy80211",
2830 intf);
2831 if (res < 0 || res >= sizeof(fname))
2832 return 0;
2833 res = readlink(fname, path, sizeof(path));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002834 if (res < 0)
2835 return 0; /* not ath6kl */
2836
2837 if (res >= (int) sizeof(path))
2838 res = sizeof(path) - 1;
2839 path[res] = '\0';
2840 pos = strrchr(path, '/');
2841 if (pos == NULL)
2842 pos = path;
2843 else
2844 pos++;
2845 snprintf(fname, sizeof(fname),
2846 "/sys/kernel/debug/ieee80211/%s/ath6kl/"
2847 "create_qos", pos);
2848 if (!file_exists(fname))
2849 return 0; /* not ath6kl */
2850
2851 if (uapsd) {
2852 f = fopen(fname, "w");
2853 if (f == NULL)
2854 return -1;
2855
2856 sigma_dut_print(dut, DUT_MSG_DEBUG, "Use ath6kl create_qos");
2857 fprintf(f, "4 2 2 1 2 9999999 9999999 9999999 7777777 0 4 "
2858 "45000 200 56789000 56789000 5678900 0 0 9999999 "
2859 "20000 0\n");
2860 fclose(f);
2861 } else {
2862 snprintf(fname, sizeof(fname),
2863 "/sys/kernel/debug/ieee80211/%s/ath6kl/"
2864 "delete_qos", pos);
2865
2866 f = fopen(fname, "w");
2867 if (f == NULL)
2868 return -1;
2869
2870 sigma_dut_print(dut, DUT_MSG_DEBUG, "Use ath6kl delete_qos");
2871 fprintf(f, "2 4\n");
2872 fclose(f);
2873 }
2874#endif /* __linux__ */
2875
2876 return 0;
2877}
2878
2879
2880static int cmd_sta_set_uapsd(struct sigma_dut *dut, struct sigma_conn *conn,
2881 struct sigma_cmd *cmd)
2882{
2883 const char *intf = get_param(cmd, "Interface");
2884 /* const char *ssid = get_param(cmd, "ssid"); */
2885 const char *val;
2886 int max_sp_len = 4;
2887 int ac_be = 1, ac_bk = 1, ac_vi = 1, ac_vo = 1;
2888 char buf[100];
2889 int ret1, ret2;
2890
2891 val = get_param(cmd, "maxSPLength");
2892 if (val) {
2893 max_sp_len = atoi(val);
2894 if (max_sp_len != 0 && max_sp_len != 1 && max_sp_len != 2 &&
2895 max_sp_len != 4)
2896 return -1;
2897 }
2898
2899 val = get_param(cmd, "acBE");
2900 if (val)
2901 ac_be = atoi(val);
2902
2903 val = get_param(cmd, "acBK");
2904 if (val)
2905 ac_bk = atoi(val);
2906
2907 val = get_param(cmd, "acVI");
2908 if (val)
2909 ac_vi = atoi(val);
2910
2911 val = get_param(cmd, "acVO");
2912 if (val)
2913 ac_vo = atoi(val);
2914
2915 dut->client_uapsd = ac_be || ac_bk || ac_vi || ac_vo;
2916
2917 snprintf(buf, sizeof(buf), "P2P_SET client_apsd %d,%d,%d,%d;%d",
2918 ac_be, ac_bk, ac_vi, ac_vo, max_sp_len);
2919 ret1 = wpa_command(intf, buf);
2920
2921 snprintf(buf, sizeof(buf), "SET uapsd %d,%d,%d,%d;%d",
2922 ac_be, ac_bk, ac_vi, ac_vo, max_sp_len);
2923 ret2 = wpa_command(intf, buf);
2924
2925 if (ret1 && ret2) {
2926 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to set client mode "
2927 "UAPSD parameters.");
2928 return -2;
2929 }
2930
2931 if (ath6kl_client_uapsd(dut, intf, dut->client_uapsd) < 0) {
2932 send_resp(dut, conn, SIGMA_ERROR,
2933 "ErrorCode,Failed to set ath6kl QoS parameters");
2934 return 0;
2935 }
2936
2937 return 1;
2938}
2939
2940
2941static int cmd_sta_set_wmm(struct sigma_dut *dut, struct sigma_conn *conn,
2942 struct sigma_cmd *cmd)
2943{
2944 char buf[1000];
2945 const char *intf = get_param(cmd, "Interface");
2946 const char *grp = get_param(cmd, "Group");
2947 const char *act = get_param(cmd, "Action");
2948 const char *tid = get_param(cmd, "Tid");
2949 const char *dir = get_param(cmd, "Direction");
2950 const char *psb = get_param(cmd, "Psb");
2951 const char *up = get_param(cmd, "Up");
2952 const char *fixed = get_param(cmd, "Fixed");
2953 const char *size = get_param(cmd, "Size");
2954 const char *msize = get_param(cmd, "Maxsize");
2955 const char *minsi = get_param(cmd, "Min_srvc_intrvl");
2956 const char *maxsi = get_param(cmd, "Max_srvc_intrvl");
2957 const char *inact = get_param(cmd, "Inactivity");
2958 const char *sus = get_param(cmd, "Suspension");
2959 const char *mindr = get_param(cmd, "Mindatarate");
2960 const char *meandr = get_param(cmd, "Meandatarate");
2961 const char *peakdr = get_param(cmd, "Peakdatarate");
2962 const char *phyrate = get_param(cmd, "Phyrate");
2963 const char *burstsize = get_param(cmd, "Burstsize");
2964 const char *sba = get_param(cmd, "Sba");
2965 int direction;
2966 int handle;
Peng Xu93319622017-10-04 17:58:16 -07002967 float sba_fv = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002968 int fixed_int;
2969 int psb_ts;
2970
2971 if (intf == NULL || grp == NULL || act == NULL )
2972 return -1;
2973
2974 if (strcasecmp(act, "addts") == 0) {
2975 if (tid == NULL || dir == NULL || psb == NULL ||
2976 up == NULL || fixed == NULL || size == NULL)
2977 return -1;
2978
2979 /*
2980 * Note: Sigma CAPI spec lists uplink, downlink, and bidi as the
2981 * possible values, but WMM-AC and V-E test scripts use "UP,
2982 * "DOWN", and "BIDI".
2983 */
2984 if (strcasecmp(dir, "uplink") == 0 ||
2985 strcasecmp(dir, "up") == 0) {
2986 direction = 0;
2987 } else if (strcasecmp(dir, "downlink") == 0 ||
2988 strcasecmp(dir, "down") == 0) {
2989 direction = 1;
2990 } else if (strcasecmp(dir, "bidi") == 0) {
2991 direction = 2;
2992 } else {
2993 sigma_dut_print(dut, DUT_MSG_ERROR,
2994 "Direction %s not supported", dir);
2995 return -1;
2996 }
2997
2998 if (strcasecmp(psb, "legacy") == 0) {
2999 psb_ts = 0;
3000 } else if (strcasecmp(psb, "uapsd") == 0) {
3001 psb_ts = 1;
3002 } else {
3003 sigma_dut_print(dut, DUT_MSG_ERROR,
3004 "PSB %s not supported", psb);
3005 return -1;
3006 }
3007
3008 if (atoi(tid) < 0 || atoi(tid) > 7) {
3009 sigma_dut_print(dut, DUT_MSG_ERROR,
3010 "TID %s not supported", tid);
3011 return -1;
3012 }
3013
3014 if (strcasecmp(fixed, "true") == 0) {
3015 fixed_int = 1;
3016 } else {
3017 fixed_int = 0;
3018 }
3019
Peng Xu93319622017-10-04 17:58:16 -07003020 if (sba)
3021 sba_fv = atof(sba);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003022
3023 dut->dialog_token++;
3024 handle = 7000 + dut->dialog_token;
3025
3026 /*
3027 * size: convert to hex
3028 * maxsi: convert to hex
3029 * mindr: convert to hex
3030 * meandr: convert to hex
3031 * peakdr: convert to hex
3032 * burstsize: convert to hex
3033 * phyrate: convert to hex
3034 * sba: convert to hex with modification
3035 * minsi: convert to integer
3036 * sus: convert to integer
3037 * inact: convert to integer
3038 * maxsi: convert to integer
3039 */
3040
3041 /*
3042 * The Nominal MSDU Size field is 2 octets long and contains an
3043 * unsigned integer that specifies the nominal size, in octets,
3044 * of MSDUs belonging to the traffic under this traffic
3045 * specification and is defined in Figure 16. If the Fixed
3046 * subfield is set to 1, then the size of the MSDU is fixed and
3047 * is indicated by the Size Subfield. If the Fixed subfield is
3048 * set to 0, then the size of the MSDU might not be fixed and
3049 * the Size indicates the nominal MSDU size.
3050 *
3051 * The Surplus Bandwidth Allowance Factor field is 2 octets long
3052 * and specifies the excess allocation of time (and bandwidth)
3053 * over and above the stated rates required to transport an MSDU
3054 * belonging to the traffic in this TSPEC. This field is
3055 * represented as an unsigned binary number with an implicit
3056 * binary point after the leftmost 3 bits. For example, an SBA
3057 * of 1.75 is represented as 0x3800. This field is included to
3058 * account for retransmissions. As such, the value of this field
3059 * must be greater than unity.
3060 */
3061
3062 snprintf(buf, sizeof(buf),
3063 "iwpriv %s addTspec %d %s %d %d %s 0x%X"
3064 " 0x%X 0x%X 0x%X"
3065 " 0x%X 0x%X 0x%X"
3066 " 0x%X %d %d %d %d"
3067 " %d %d",
3068 intf, handle, tid, direction, psb_ts, up,
3069 (unsigned int) ((fixed_int << 15) | atoi(size)),
3070 msize ? atoi(msize) : 0,
3071 mindr ? atoi(mindr) : 0,
3072 meandr ? atoi(meandr) : 0,
3073 peakdr ? atoi(peakdr) : 0,
3074 burstsize ? atoi(burstsize) : 0,
3075 phyrate ? atoi(phyrate) : 0,
3076 sba ? ((unsigned int) (((int) sba_fv << 13) |
3077 (int)((sba_fv - (int) sba_fv) *
3078 8192))) : 0,
3079 minsi ? atoi(minsi) : 0,
3080 sus ? atoi(sus) : 0,
3081 0, 0,
3082 inact ? atoi(inact) : 0,
3083 maxsi ? atoi(maxsi) : 0);
3084
3085 if (system(buf) != 0) {
3086 sigma_dut_print(dut, DUT_MSG_ERROR,
3087 "iwpriv addtspec request failed");
3088 send_resp(dut, conn, SIGMA_ERROR,
3089 "errorCode,Failed to execute addTspec command");
3090 return 0;
3091 }
3092
3093 sigma_dut_print(dut, DUT_MSG_INFO,
3094 "iwpriv addtspec request send");
3095
3096 /* Mapping handle to a TID */
3097 dut->tid_to_handle[atoi(tid)] = handle;
3098 } else if (strcasecmp(act, "delts") == 0) {
3099 if (tid == NULL)
3100 return -1;
3101
3102 if (atoi(tid) < 0 || atoi(tid) > 7) {
3103 sigma_dut_print(dut, DUT_MSG_ERROR,
3104 "TID %s not supported", tid);
3105 send_resp(dut, conn, SIGMA_ERROR,
3106 "errorCode,Unsupported TID");
3107 return 0;
3108 }
3109
3110 handle = dut->tid_to_handle[atoi(tid)];
3111
3112 if (handle < 7000 || handle > 7255) {
3113 /* Invalid handle ie no mapping for that TID */
3114 sigma_dut_print(dut, DUT_MSG_ERROR,
3115 "handle-> %d not found", handle);
3116 }
3117
3118 snprintf(buf, sizeof(buf), "iwpriv %s delTspec %d",
3119 intf, handle);
3120
3121 if (system(buf) != 0) {
3122 sigma_dut_print(dut, DUT_MSG_ERROR,
3123 "iwpriv deltspec request failed");
3124 send_resp(dut, conn, SIGMA_ERROR,
3125 "errorCode,Failed to execute delTspec command");
3126 return 0;
3127 }
3128
3129 sigma_dut_print(dut, DUT_MSG_INFO,
3130 "iwpriv deltspec request send");
3131
3132 dut->tid_to_handle[atoi(tid)] = 0;
3133 } else {
3134 sigma_dut_print(dut, DUT_MSG_ERROR,
3135 "Action type %s not supported", act);
3136 send_resp(dut, conn, SIGMA_ERROR,
3137 "errorCode,Unsupported Action");
3138 return 0;
3139 }
3140
3141 return 1;
3142}
3143
3144
vamsi krishna52e16f92017-08-29 12:37:34 +05303145static int find_network(struct sigma_dut *dut, const char *ssid)
3146{
3147 char list[4096];
3148 char *pos;
3149
3150 sigma_dut_print(dut, DUT_MSG_DEBUG,
3151 "Search for profile based on SSID: '%s'", ssid);
3152 if (wpa_command_resp(get_station_ifname(), "LIST_NETWORKS",
3153 list, sizeof(list)) < 0)
3154 return -1;
3155 pos = strstr(list, ssid);
3156 if (!pos || pos == list || pos[-1] != '\t' || pos[strlen(ssid)] != '\t')
3157 return -1;
3158
3159 while (pos > list && pos[-1] != '\n')
3160 pos--;
3161 dut->infra_network_id = atoi(pos);
3162 snprintf(dut->infra_ssid, sizeof(dut->infra_ssid), "%s", ssid);
3163 return 0;
3164}
3165
3166
Sunil Dutt44595082018-02-12 19:41:45 +05303167#ifdef NL80211_SUPPORT
3168static int sta_config_rsnie(struct sigma_dut *dut, int val)
3169{
3170 struct nl_msg *msg;
3171 int ret;
3172 struct nlattr *params;
3173 int ifindex;
3174
3175 ifindex = if_nametoindex("wlan0");
3176 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
3177 NL80211_CMD_VENDOR)) ||
3178 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
3179 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
3180 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
3181 QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION) ||
3182 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
3183 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE, val)) {
3184 sigma_dut_print(dut, DUT_MSG_ERROR,
3185 "%s: err in adding vendor_cmd and vendor_data",
3186 __func__);
3187 nlmsg_free(msg);
3188 return -1;
3189 }
3190 nla_nest_end(msg, params);
3191
3192 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
3193 if (ret) {
3194 sigma_dut_print(dut, DUT_MSG_ERROR,
3195 "%s: err in send_and_recv_msgs, ret=%d",
3196 __func__, ret);
3197 return ret;
3198 }
3199
3200 return 0;
3201}
3202#endif /* NL80211_SUPPORT */
3203
3204
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003205static int cmd_sta_associate(struct sigma_dut *dut, struct sigma_conn *conn,
3206 struct sigma_cmd *cmd)
3207{
3208 /* const char *intf = get_param(cmd, "Interface"); */
3209 const char *ssid = get_param(cmd, "ssid");
3210 const char *wps_param = get_param(cmd, "WPS");
3211 const char *bssid = get_param(cmd, "bssid");
Jouni Malinen46a19b62017-06-23 14:31:27 +03003212 const char *chan = get_param(cmd, "channel");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02003213 const char *network_mode = get_param(cmd, "network_mode");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003214 int wps = 0;
Jouni Malinen3c367e82017-06-23 17:01:47 +03003215 char buf[1000], extra[50];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003216
3217 if (ssid == NULL)
3218 return -1;
3219
Jouni Malinen3c367e82017-06-23 17:01:47 +03003220 if (dut->rsne_override) {
Sunil Dutt44595082018-02-12 19:41:45 +05303221#ifdef NL80211_SUPPORT
3222 if (get_driver_type() == DRIVER_WCN) {
3223 sta_config_rsnie(dut, 1);
3224 dut->config_rsnie = 1;
3225 }
3226#endif /* NL80211_SUPPORT */
Jouni Malinen3c367e82017-06-23 17:01:47 +03003227 snprintf(buf, sizeof(buf), "TEST_ASSOC_IE %s",
3228 dut->rsne_override);
3229 if (wpa_command(get_station_ifname(), buf) < 0) {
3230 send_resp(dut, conn, SIGMA_ERROR,
3231 "ErrorCode,Failed to set DEV_CONFIGURE_IE RSNE override");
3232 return 0;
3233 }
3234 }
3235
Jouni Malinen68143132017-09-02 02:34:08 +03003236 if (dut->sae_commit_override) {
3237 snprintf(buf, sizeof(buf), "SET sae_commit_override %s",
3238 dut->sae_commit_override);
3239 if (wpa_command(get_station_ifname(), buf) < 0) {
3240 send_resp(dut, conn, SIGMA_ERROR,
3241 "ErrorCode,Failed to set SAE commit override");
3242 return 0;
3243 }
3244 }
Ankita Bajaj1bde7942018-01-09 19:15:01 +05303245#ifdef ANDROID
3246 if (dut->fils_hlp)
3247 process_fils_hlp(dut);
3248#endif /* ANDROID */
Jouni Malinen68143132017-09-02 02:34:08 +03003249
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003250 if (wps_param &&
3251 (strcmp(wps_param, "1") == 0 || strcasecmp(wps_param, "On") == 0))
3252 wps = 1;
3253
3254 if (wps) {
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02003255 if (dut->program == PROGRAM_60GHZ && network_mode &&
3256 strcasecmp(network_mode, "PBSS") == 0 &&
3257 set_network(get_station_ifname(), dut->infra_network_id,
3258 "pbss", "1") < 0)
3259 return -2;
3260
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003261 if (dut->wps_method == WFA_CS_WPS_NOT_READY) {
3262 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,WPS "
3263 "parameters not yet set");
3264 return 0;
3265 }
3266 if (dut->wps_method == WFA_CS_WPS_PBC) {
3267 if (wpa_command(get_station_ifname(), "WPS_PBC") < 0)
3268 return -2;
3269 } else {
3270 snprintf(buf, sizeof(buf), "WPS_PIN any %s",
3271 dut->wps_pin);
3272 if (wpa_command(get_station_ifname(), buf) < 0)
3273 return -2;
3274 }
3275 } else {
vamsi krishna52e16f92017-08-29 12:37:34 +05303276 if (strcmp(ssid, dut->infra_ssid) == 0) {
3277 sigma_dut_print(dut, DUT_MSG_DEBUG,
3278 "sta_associate for the most recently added network");
3279 } else if (find_network(dut, ssid) < 0) {
3280 sigma_dut_print(dut, DUT_MSG_DEBUG,
3281 "sta_associate for a previously stored network profile");
3282 send_resp(dut, conn, SIGMA_ERROR,
3283 "ErrorCode,Profile not found");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003284 return 0;
3285 }
3286
3287 if (bssid &&
3288 set_network(get_station_ifname(), dut->infra_network_id,
3289 "bssid", bssid) < 0) {
3290 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
3291 "Invalid bssid argument");
3292 return 0;
3293 }
3294
Jouni Malinen46a19b62017-06-23 14:31:27 +03003295 extra[0] = '\0';
3296 if (chan)
3297 snprintf(extra, sizeof(extra), " freq=%u",
Alexei Avshalom Lazar093569f2018-11-13 14:08:17 +02003298 channel_to_freq(dut, atoi(chan)));
Jouni Malinen46a19b62017-06-23 14:31:27 +03003299 snprintf(buf, sizeof(buf), "SELECT_NETWORK %d%s",
3300 dut->infra_network_id, extra);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003301 if (wpa_command(get_station_ifname(), buf) < 0) {
3302 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to select "
3303 "network id %d on %s",
3304 dut->infra_network_id,
3305 get_station_ifname());
3306 return -2;
3307 }
3308 }
3309
3310 return 1;
3311}
3312
3313
3314static int run_hs20_osu(struct sigma_dut *dut, const char *params)
3315{
3316 char buf[500], cmd[200];
3317 int res;
3318
3319 /* Use hs20-osu-client file at the current dir, if found; otherwise use
3320 * default path */
3321 res = snprintf(cmd, sizeof(cmd),
3322 "%s -w \"%s\" -r hs20-osu-client.res %s%s -dddKt -f Logs/hs20-osu-client.txt",
3323 file_exists("./hs20-osu-client") ?
3324 "./hs20-osu-client" : "hs20-osu-client",
3325 sigma_wpas_ctrl,
3326 dut->summary_log ? "-s " : "",
3327 dut->summary_log ? dut->summary_log : "");
3328 if (res < 0 || res >= (int) sizeof(cmd))
3329 return -1;
3330
3331 res = snprintf(buf, sizeof(buf), "%s %s", cmd, params);
3332 if (res < 0 || res >= (int) sizeof(buf))
3333 return -1;
3334 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
3335
3336 if (system(buf) != 0) {
3337 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to run: %s", buf);
3338 return -1;
3339 }
3340 sigma_dut_print(dut, DUT_MSG_DEBUG,
3341 "Completed hs20-osu-client operation");
3342
3343 return 0;
3344}
3345
3346
3347static int download_ppsmo(struct sigma_dut *dut,
3348 struct sigma_conn *conn,
3349 const char *intf,
3350 struct sigma_cmd *cmd)
3351{
3352 const char *name, *path, *val;
3353 char url[500], buf[600], fbuf[100];
3354 char *fqdn = NULL;
3355
3356 name = get_param(cmd, "FileName");
3357 path = get_param(cmd, "FilePath");
3358 if (name == NULL || path == NULL)
3359 return -1;
3360
3361 if (strcasecmp(path, "VendorSpecific") == 0) {
3362 snprintf(url, sizeof(url), "PPS/%s", name);
3363 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured PPS MO "
3364 "from the device (%s)", url);
3365 if (!file_exists(url)) {
3366 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
3367 "PPS MO file does not exist");
3368 return 0;
3369 }
3370 snprintf(buf, sizeof(buf), "cp %s pps-tnds.xml", url);
3371 if (system(buf) != 0) {
3372 send_resp(dut, conn, SIGMA_ERROR,
3373 "errorCode,Failed to copy PPS MO");
3374 return 0;
3375 }
3376 } else if (strncasecmp(path, "http:", 5) != 0 &&
3377 strncasecmp(path, "https:", 6) != 0) {
3378 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
3379 "Unsupported FilePath value");
3380 return 0;
3381 } else {
3382 snprintf(url, sizeof(url), "%s/%s", path, name);
3383 sigma_dut_print(dut, DUT_MSG_INFO, "Downloading PPS MO from %s",
3384 url);
3385 snprintf(buf, sizeof(buf), "wget -T 10 -t 3 -O pps-tnds.xml '%s'", url);
3386 remove("pps-tnds.xml");
3387 if (system(buf) != 0) {
3388 send_resp(dut, conn, SIGMA_ERROR,
3389 "errorCode,Failed to download PPS MO");
3390 return 0;
3391 }
3392 }
3393
3394 if (run_hs20_osu(dut, "from_tnds pps-tnds.xml pps.xml") < 0) {
3395 send_resp(dut, conn, SIGMA_ERROR,
3396 "errorCode,Failed to parse downloaded PPSMO");
3397 return 0;
3398 }
3399 unlink("pps-tnds.xml");
3400
3401 val = get_param(cmd, "managementTreeURI");
3402 if (val) {
3403 const char *pos, *end;
3404 sigma_dut_print(dut, DUT_MSG_DEBUG, "managementTreeURI: %s",
3405 val);
3406 if (strncmp(val, "./Wi-Fi/", 8) != 0) {
3407 send_resp(dut, conn, SIGMA_ERROR,
3408 "errorCode,Invalid managementTreeURI prefix");
3409 return 0;
3410 }
3411 pos = val + 8;
3412 end = strchr(pos, '/');
3413 if (end == NULL ||
3414 strcmp(end, "/PerProviderSubscription") != 0) {
3415 send_resp(dut, conn, SIGMA_ERROR,
3416 "errorCode,Invalid managementTreeURI postfix");
3417 return 0;
3418 }
3419 if (end - pos >= (int) sizeof(fbuf)) {
3420 send_resp(dut, conn, SIGMA_ERROR,
3421 "errorCode,Too long FQDN in managementTreeURI");
3422 return 0;
3423 }
3424 memcpy(fbuf, pos, end - pos);
3425 fbuf[end - pos] = '\0';
3426 fqdn = fbuf;
3427 sigma_dut_print(dut, DUT_MSG_INFO,
3428 "FQDN from managementTreeURI: %s", fqdn);
3429 } else if (run_hs20_osu(dut, "get_fqdn pps.xml") == 0) {
3430 FILE *f = fopen("pps-fqdn", "r");
3431 if (f) {
3432 if (fgets(fbuf, sizeof(fbuf), f)) {
3433 fbuf[sizeof(fbuf) - 1] = '\0';
3434 fqdn = fbuf;
3435 sigma_dut_print(dut, DUT_MSG_DEBUG,
3436 "Use FQDN %s", fqdn);
3437 }
3438 fclose(f);
3439 }
3440 }
3441
3442 if (fqdn == NULL) {
3443 send_resp(dut, conn, SIGMA_ERROR,
3444 "errorCode,No FQDN specified");
3445 return 0;
3446 }
3447
3448 mkdir("SP", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
3449 snprintf(buf, sizeof(buf), "SP/%s", fqdn);
3450 mkdir(buf, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
3451
3452 snprintf(buf, sizeof(buf), "SP/%s/pps.xml", fqdn);
3453 if (rename("pps.xml", buf) < 0) {
3454 send_resp(dut, conn, SIGMA_ERROR,
3455 "errorCode,Could not move PPS MO");
3456 return 0;
3457 }
3458
3459 if (strcasecmp(path, "VendorSpecific") == 0) {
3460 snprintf(buf, sizeof(buf), "cp Certs/ca.pem SP/%s/ca.pem",
3461 fqdn);
3462 if (system(buf)) {
3463 send_resp(dut, conn, SIGMA_ERROR,
3464 "errorCode,Failed to copy OSU CA cert");
3465 return 0;
3466 }
3467
3468 snprintf(buf, sizeof(buf),
3469 "cp Certs/aaa-ca.pem SP/%s/aaa-ca.pem",
3470 fqdn);
3471 if (system(buf)) {
3472 send_resp(dut, conn, SIGMA_ERROR,
3473 "errorCode,Failed to copy AAA CA cert");
3474 return 0;
3475 }
3476 } else {
3477 snprintf(buf, sizeof(buf),
3478 "dl_osu_ca SP/%s/pps.xml SP/%s/ca.pem",
3479 fqdn, fqdn);
3480 if (run_hs20_osu(dut, buf) < 0) {
3481 send_resp(dut, conn, SIGMA_ERROR,
3482 "errorCode,Failed to download OSU CA cert");
3483 return 0;
3484 }
3485
3486 snprintf(buf, sizeof(buf),
3487 "dl_aaa_ca SP/%s/pps.xml SP/%s/aaa-ca.pem",
3488 fqdn, fqdn);
3489 if (run_hs20_osu(dut, buf) < 0) {
3490 sigma_dut_print(dut, DUT_MSG_INFO,
3491 "Failed to download AAA CA cert");
3492 }
3493 }
3494
3495 if (file_exists("next-client-cert.pem")) {
3496 snprintf(buf, sizeof(buf), "SP/%s/client-cert.pem", fqdn);
3497 if (rename("next-client-cert.pem", buf) < 0) {
3498 send_resp(dut, conn, SIGMA_ERROR,
3499 "errorCode,Could not move client certificate");
3500 return 0;
3501 }
3502 }
3503
3504 if (file_exists("next-client-key.pem")) {
3505 snprintf(buf, sizeof(buf), "SP/%s/client-key.pem", fqdn);
3506 if (rename("next-client-key.pem", buf) < 0) {
3507 send_resp(dut, conn, SIGMA_ERROR,
3508 "errorCode,Could not move client key");
3509 return 0;
3510 }
3511 }
3512
3513 snprintf(buf, sizeof(buf), "set_pps SP/%s/pps.xml", fqdn);
3514 if (run_hs20_osu(dut, buf) < 0) {
3515 send_resp(dut, conn, SIGMA_ERROR,
3516 "errorCode,Failed to configure credential from "
3517 "PPSMO");
3518 return 0;
3519 }
3520
3521 return 1;
3522}
3523
3524
3525static int download_cert(struct sigma_dut *dut,
3526 struct sigma_conn *conn,
3527 const char *intf,
3528 struct sigma_cmd *cmd)
3529{
3530 const char *name, *path;
3531 char url[500], buf[600];
3532
3533 name = get_param(cmd, "FileName");
3534 path = get_param(cmd, "FilePath");
3535 if (name == NULL || path == NULL)
3536 return -1;
3537
3538 if (strcasecmp(path, "VendorSpecific") == 0) {
3539 snprintf(url, sizeof(url), "Certs/%s-cert.pem", name);
3540 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured client "
3541 "certificate from the device (%s)", url);
3542 if (!file_exists(url)) {
3543 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
3544 "certificate file does not exist");
3545 return 0;
3546 }
3547 snprintf(buf, sizeof(buf), "cp %s next-client-cert.pem", url);
3548 if (system(buf) != 0) {
3549 send_resp(dut, conn, SIGMA_ERROR,
3550 "errorCode,Failed to copy client "
3551 "certificate");
3552 return 0;
3553 }
3554
3555 snprintf(url, sizeof(url), "Certs/%s-key.pem", name);
3556 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured client "
3557 "private key from the device (%s)", url);
3558 if (!file_exists(url)) {
3559 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
3560 "private key file does not exist");
3561 return 0;
3562 }
3563 snprintf(buf, sizeof(buf), "cp %s next-client-key.pem", url);
3564 if (system(buf) != 0) {
3565 send_resp(dut, conn, SIGMA_ERROR,
3566 "errorCode,Failed to copy client key");
3567 return 0;
3568 }
3569 } else if (strncasecmp(path, "http:", 5) != 0 &&
3570 strncasecmp(path, "https:", 6) != 0) {
3571 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
3572 "Unsupported FilePath value");
3573 return 0;
3574 } else {
3575 snprintf(url, sizeof(url), "%s/%s.pem", path, name);
3576 sigma_dut_print(dut, DUT_MSG_INFO, "Downloading client "
3577 "certificate/key from %s", url);
3578 snprintf(buf, sizeof(buf),
3579 "wget -T 10 -t 3 -O next-client-cert.pem '%s'", url);
3580 if (system(buf) != 0) {
3581 send_resp(dut, conn, SIGMA_ERROR,
3582 "errorCode,Failed to download client "
3583 "certificate");
3584 return 0;
3585 }
3586
3587 if (system("cp next-client-cert.pem next-client-key.pem") != 0)
3588 {
3589 send_resp(dut, conn, SIGMA_ERROR,
3590 "errorCode,Failed to copy client key");
3591 return 0;
3592 }
3593 }
3594
3595 return 1;
3596}
3597
3598
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02003599static int cmd_sta_preset_testparameters_60ghz(struct sigma_dut *dut,
3600 struct sigma_conn *conn,
3601 struct sigma_cmd *cmd)
3602{
3603 const char *val;
3604 const char *intf = get_param(cmd, "interface");
3605
3606 if (!intf)
3607 return -1;
3608
3609 val = get_param(cmd, "WscIEFragment");
3610 if (val && strcasecmp(val, "enable") == 0) {
3611 sigma_dut_print(dut, DUT_MSG_DEBUG,
3612 "Enable WSC IE fragmentation");
3613
3614 dut->wsc_fragment = 1;
3615 /* set long attributes to force fragmentation */
3616 if (wpa_command(intf, "SET device_name "
3617 WPS_LONG_DEVICE_NAME) < 0)
3618 return -2;
3619 if (wpa_command(intf, "SET manufacturer "
3620 WPS_LONG_MANUFACTURER) < 0)
3621 return -2;
3622 if (wpa_command(intf, "SET model_name "
3623 WPS_LONG_MODEL_NAME) < 0)
3624 return -2;
3625 if (wpa_command(intf, "SET model_number "
3626 WPS_LONG_MODEL_NUMBER) < 0)
3627 return -2;
3628 if (wpa_command(intf, "SET serial_number "
3629 WPS_LONG_SERIAL_NUMBER) < 0)
3630 return -2;
3631 }
3632
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02003633 val = get_param(cmd, "RSN_IE");
3634 if (val) {
3635 if (strcasecmp(val, "disable") == 0)
3636 dut->force_rsn_ie = FORCE_RSN_IE_REMOVE;
3637 else if (strcasecmp(val, "enable") == 0)
3638 dut->force_rsn_ie = FORCE_RSN_IE_ADD;
3639 }
3640
Alexei Avshalom Lazar744ae8a2019-01-31 17:26:46 +02003641 val = get_param(cmd, "WpsVersion");
3642 if (val)
3643 dut->wps_forced_version = get_wps_forced_version(dut, val);
3644
Alexei Avshalom Lazar2eccf4d2019-01-31 10:03:59 +02003645 val = get_param(cmd, "WscEAPFragment");
3646 if (val && strcasecmp(val, "enable") == 0)
3647 dut->eap_fragment = 1;
3648
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02003649 return 1;
3650}
3651
3652
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003653static int cmd_sta_preset_testparameters_hs2_r2(struct sigma_dut *dut,
3654 struct sigma_conn *conn,
3655 const char *intf,
3656 struct sigma_cmd *cmd)
3657{
3658 const char *val;
3659
3660 val = get_param(cmd, "FileType");
3661 if (val && strcasecmp(val, "PPSMO") == 0)
3662 return download_ppsmo(dut, conn, intf, cmd);
3663 if (val && strcasecmp(val, "CERT") == 0)
3664 return download_cert(dut, conn, intf, cmd);
3665 if (val) {
3666 send_resp(dut, conn, SIGMA_ERROR,
3667 "ErrorCode,Unsupported FileType");
3668 return 0;
3669 }
3670
3671 return 1;
3672}
3673
3674
Ankita Bajaja2cb5672017-10-25 16:08:28 +05303675static int cmd_sta_preset_testparameters_oce(struct sigma_dut *dut,
3676 struct sigma_conn *conn,
3677 const char *intf,
3678 struct sigma_cmd *cmd)
3679{
3680 const char *val;
Ankita Bajaj1bde7942018-01-09 19:15:01 +05303681 char buf[1000];
3682 char text[20];
3683 unsigned char addr[ETH_ALEN];
Ankita Bajaja2cb5672017-10-25 16:08:28 +05303684
3685 val = get_param(cmd, "OCESupport");
3686 if (val && strcasecmp(val, "Disable") == 0) {
3687 if (wpa_command(intf, "SET oce 0") < 0) {
3688 send_resp(dut, conn, SIGMA_ERROR,
3689 "ErrorCode,Failed to disable OCE");
3690 return 0;
3691 }
3692 } else if (val && strcasecmp(val, "Enable") == 0) {
3693 if (wpa_command(intf, "SET oce 1") < 0) {
3694 send_resp(dut, conn, SIGMA_ERROR,
3695 "ErrorCode,Failed to enable OCE");
3696 return 0;
3697 }
3698 }
3699
vamsi krishnaa2799492017-12-05 14:28:01 +05303700 val = get_param(cmd, "FILScap");
3701 if (val && (atoi(val) == 1)) {
3702 if (wpa_command(intf, "SET disable_fils 0") < 0) {
3703 send_resp(dut, conn, SIGMA_ERROR,
3704 "ErrorCode,Failed to enable FILS");
3705 return 0;
3706 }
3707 } else if (val && (atoi(val) == 0)) {
3708 if (wpa_command(intf, "SET disable_fils 1") < 0) {
3709 send_resp(dut, conn, SIGMA_ERROR,
3710 "ErrorCode,Failed to disable FILS");
3711 return 0;
3712 }
3713 }
3714
Ankita Bajaj1bde7942018-01-09 19:15:01 +05303715 val = get_param(cmd, "FILSHLP");
3716 if (val && strcasecmp(val, "Enable") == 0) {
3717 if (get_wpa_status(get_station_ifname(), "address", text,
3718 sizeof(text)) < 0)
3719 return -2;
3720 hwaddr_aton(text, addr);
3721 snprintf(buf, sizeof(buf),
3722 "FILS_HLP_REQ_ADD ff:ff:ff:ff:ff:ff "
3723 "080045100140000040004011399e00000000ffffffff00440043"
3724 "012cb30001010600fd4f46410000000000000000000000000000"
3725 "000000000000"
3726 "%02x%02x%02x%02x%02x%02x"
3727 "0000000000000000000000000000000000000000000000000000"
3728 "0000000000000000000000000000000000000000000000000000"
3729 "0000000000000000000000000000000000000000000000000000"
3730 "0000000000000000000000000000000000000000000000000000"
3731 "0000000000000000000000000000000000000000000000000000"
3732 "0000000000000000000000000000000000000000000000000000"
3733 "0000000000000000000000000000000000000000000000000000"
3734 "0000000000000000000000000000000000000000638253633501"
3735 "013d0701000af549d29b390205dc3c12616e64726f69642d6468"
3736 "63702d382e302e30370a0103060f1a1c333a3b2b5000ff00",
3737 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
3738 if (wpa_command(intf, buf)) {
3739 send_resp(dut, conn, SIGMA_ERROR,
3740 "ErrorCode,Failed to add HLP");
3741 return 0;
3742 }
3743 dut->fils_hlp = 1;
3744 }
3745
Ankita Bajaja2cb5672017-10-25 16:08:28 +05303746 return 1;
3747}
3748
3749
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003750static void ath_sta_set_noack(struct sigma_dut *dut, const char *intf,
3751 const char *val)
3752{
3753 int counter = 0;
3754 char token[50];
3755 char *result;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05303756 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003757
Peng Xub8fc5cc2017-05-10 17:27:28 -07003758 strlcpy(token, val, sizeof(token));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003759 token[sizeof(token) - 1] = '\0';
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05303760 result = strtok_r(token, ":", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003761 while (result) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07003762 if (strcmp(result, "disable") == 0)
3763 run_iwpriv(dut, intf, "noackpolicy %d 1 0", counter);
3764 else
3765 run_iwpriv(dut, intf, "noackpolicy %d 1 1", counter);
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05303766 result = strtok_r(NULL, ":", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003767 counter++;
3768 }
3769}
3770
3771
3772static void ath_sta_set_rts(struct sigma_dut *dut, const char *intf,
3773 const char *val)
3774{
3775 char buf[100];
3776
3777 snprintf(buf, sizeof(buf), "iwconfig %s rts %s", intf, val);
3778 if (system(buf) != 0) {
3779 sigma_dut_print(dut, DUT_MSG_ERROR, "iwconfig RTS failed");
3780 }
3781}
3782
3783
3784static void ath_sta_set_wmm(struct sigma_dut *dut, const char *intf,
3785 const char *val)
3786{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003787 if (strcasecmp(val, "off") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07003788 run_iwpriv(dut, intf, "wmm 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003789 }
3790}
3791
3792
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08003793static int wcn_sta_set_wmm(struct sigma_dut *dut, const char *intf,
3794 const char *val)
3795{
3796#ifdef NL80211_SUPPORT
3797 struct nl_msg *msg;
3798 int ret = 0;
3799 struct nlattr *params;
3800 int ifindex;
3801 int wmmenable = 1;
3802
3803 if (val &&
3804 (strcasecmp(val, "off") == 0 || strcmp(val, "0") == 0))
3805 wmmenable = 0;
3806
3807 ifindex = if_nametoindex(intf);
3808 if (ifindex == 0) {
3809 sigma_dut_print(dut, DUT_MSG_ERROR,
3810 "%s: Index for interface %s failed",
3811 __func__, intf);
3812 return -1;
3813 }
3814
3815 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
3816 NL80211_CMD_VENDOR)) ||
3817 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
3818 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
3819 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
3820 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
3821 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
3822 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WMM_ENABLE,
3823 wmmenable)) {
3824 sigma_dut_print(dut, DUT_MSG_ERROR,
3825 "%s: err in adding vendor_cmd and vendor_data",
3826 __func__);
3827 nlmsg_free(msg);
3828 return -1;
3829 }
3830 nla_nest_end(msg, params);
3831
3832 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
3833 if (ret) {
3834 sigma_dut_print(dut, DUT_MSG_ERROR,
3835 "%s: err in send_and_recv_msgs, ret=%d",
3836 __func__, ret);
3837 }
3838 return ret;
3839#else /* NL80211_SUPPORT */
3840 sigma_dut_print(dut, DUT_MSG_ERROR,
3841 "WMM cannot be changed without NL80211_SUPPORT defined");
3842 return -1;
3843#endif /* NL80211_SUPPORT */
3844}
3845
3846
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003847static void ath_sta_set_sgi(struct sigma_dut *dut, const char *intf,
3848 const char *val)
3849{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003850 int sgi20;
3851
3852 sgi20 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
3853
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07003854 run_iwpriv(dut, intf, "shortgi %d", sgi20);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003855}
3856
3857
3858static void ath_sta_set_11nrates(struct sigma_dut *dut, const char *intf,
3859 const char *val)
3860{
Pradeep Reddy POTTETI67376b72016-10-25 20:08:17 +05303861 int rate_code, v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003862
3863 /* Disable Tx Beam forming when using a fixed rate */
3864 ath_disable_txbf(dut, intf);
3865
Pradeep Reddy POTTETI67376b72016-10-25 20:08:17 +05303866 v = atoi(val);
3867 if (v < 0 || v > 32) {
3868 sigma_dut_print(dut, DUT_MSG_ERROR,
3869 "Invalid Fixed MCS rate: %d", v);
3870 return;
3871 }
3872 rate_code = 0x80 + v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003873
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07003874 run_iwpriv(dut, intf, "set11NRates 0x%x", rate_code);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003875
3876 /* Channel width gets messed up, fix this */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07003877 run_iwpriv(dut, intf, "chwidth %d", dut->chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003878}
3879
3880
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08003881static void iwpriv_sta_set_amsdu(struct sigma_dut *dut, const char *intf,
3882 const char *val)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003883{
3884 char buf[60];
3885
3886 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)
3887 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 2", intf);
3888 else
3889 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 1", intf);
3890
3891 if (system(buf) != 0)
3892 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv amsdu failed");
3893}
3894
3895
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07003896static int iwpriv_sta_set_ampdu(struct sigma_dut *dut, const char *intf,
3897 int ampdu)
3898{
3899 char buf[60];
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08003900 int maxaggregation = 63;
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07003901
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08003902 if (ampdu)
3903 ampdu = maxaggregation;
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07003904 snprintf(buf, sizeof(buf), "iwpriv %s ampdu %d", intf, ampdu);
3905 if (system(buf) != 0) {
3906 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv ampdu failed");
3907 return -1;
3908 }
3909
3910 return 0;
3911}
3912
3913
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003914static void ath_sta_set_stbc(struct sigma_dut *dut, const char *intf,
3915 const char *val)
3916{
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07003917 run_iwpriv(dut, intf, "tx_stbc %s", val);
3918 run_iwpriv(dut, intf, "rx_stbc %s", val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003919}
3920
3921
3922static int wcn_sta_set_cts_width(struct sigma_dut *dut, const char *intf,
3923 const char *val)
3924{
3925 char buf[60];
3926
Peng Xucc317ed2017-05-18 16:44:37 -07003927 if (strcmp(val, "160") == 0) {
3928 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 5", intf);
3929 } else if (strcmp(val, "80") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003930 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 3", intf);
3931 } else if (strcmp(val, "40") == 0) {
3932 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 2", intf);
3933 } else if (strcmp(val, "20") == 0) {
3934 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 1", intf);
3935 } else if (strcasecmp(val, "Auto") == 0) {
3936 buf[0] = '\0';
3937 } else {
3938 sigma_dut_print(dut, DUT_MSG_ERROR,
3939 "WIDTH/CTS_WIDTH value not supported");
3940 return -1;
3941 }
3942
3943 if (buf[0] != '\0' && system(buf) != 0) {
3944 sigma_dut_print(dut, DUT_MSG_ERROR,
3945 "Failed to set WIDTH/CTS_WIDTH");
3946 return -1;
3947 }
3948
3949 return 0;
3950}
3951
3952
3953int ath_set_width(struct sigma_dut *dut, struct sigma_conn *conn,
3954 const char *intf, const char *val)
3955{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003956 if (strcasecmp(val, "Auto") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07003957 run_iwpriv(dut, intf, "chwidth 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003958 dut->chwidth = 0;
3959 } else if (strcasecmp(val, "20") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07003960 run_iwpriv(dut, intf, "chwidth 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003961 dut->chwidth = 0;
3962 } else if (strcasecmp(val, "40") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07003963 run_iwpriv(dut, intf, "chwidth 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003964 dut->chwidth = 1;
3965 } else if (strcasecmp(val, "80") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07003966 run_iwpriv(dut, intf, "chwidth 2");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003967 dut->chwidth = 2;
3968 } else if (strcasecmp(val, "160") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07003969 run_iwpriv(dut, intf, "chwidth 3");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003970 dut->chwidth = 3;
3971 } else {
3972 send_resp(dut, conn, SIGMA_ERROR,
3973 "ErrorCode,WIDTH not supported");
3974 return -1;
3975 }
3976
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003977 return 0;
3978}
3979
3980
3981static int wcn_sta_set_sp_stream(struct sigma_dut *dut, const char *intf,
3982 const char *val)
3983{
3984 char buf[60];
Arif Hussainac6c5112018-05-25 17:34:00 -07003985 int sta_nss;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003986
Amarnath Hullur Subramanyamd5374fa2018-02-25 19:00:24 -08003987 if (strcmp(val, "1SS") == 0 || strcmp(val, "1") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003988 snprintf(buf, sizeof(buf), "iwpriv %s nss 1", intf);
Arif Hussainac6c5112018-05-25 17:34:00 -07003989 sta_nss = 1;
Amarnath Hullur Subramanyamd5374fa2018-02-25 19:00:24 -08003990 } else if (strcmp(val, "2SS") == 0 || strcmp(val, "2") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003991 snprintf(buf, sizeof(buf), "iwpriv %s nss 2", intf);
Arif Hussainac6c5112018-05-25 17:34:00 -07003992 sta_nss = 2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003993 } else {
3994 sigma_dut_print(dut, DUT_MSG_ERROR,
3995 "SP_STREAM value not supported");
3996 return -1;
3997 }
3998
3999 if (system(buf) != 0) {
4000 sigma_dut_print(dut, DUT_MSG_ERROR,
4001 "Failed to set SP_STREAM");
4002 return -1;
4003 }
4004
Arif Hussainac6c5112018-05-25 17:34:00 -07004005 dut->sta_nss = sta_nss;
4006
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004007 return 0;
4008}
4009
4010
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05304011static void wcn_sta_set_stbc(struct sigma_dut *dut, const char *intf,
4012 const char *val)
4013{
4014 char buf[60];
4015
4016 snprintf(buf, sizeof(buf), "iwpriv %s tx_stbc %s", intf, val);
4017 if (system(buf) != 0)
4018 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv tx_stbc failed");
4019
4020 snprintf(buf, sizeof(buf), "iwpriv %s rx_stbc %s", intf, val);
4021 if (system(buf) != 0)
4022 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv rx_stbc failed");
4023}
4024
4025
Ashwini Patil68d02cd2017-01-10 15:39:16 +05304026static int mbo_set_cellular_data_capa(struct sigma_dut *dut,
4027 struct sigma_conn *conn,
4028 const char *intf, int capa)
4029{
4030 char buf[32];
4031
4032 if (capa > 0 && capa < 4) {
4033 snprintf(buf, sizeof(buf), "SET mbo_cell_capa %d", capa);
4034 if (wpa_command(intf, buf) < 0) {
4035 send_resp(dut, conn, SIGMA_ERROR,
4036 "ErrorCode, Failed to set cellular data capability");
4037 return 0;
4038 }
4039 return 1;
4040 }
4041
4042 sigma_dut_print(dut, DUT_MSG_ERROR,
4043 "Invalid Cellular data capability: %d", capa);
4044 send_resp(dut, conn, SIGMA_INVALID,
4045 "ErrorCode,Invalid cellular data capability");
4046 return 0;
4047}
4048
4049
Ashwini Patil9183fdb2017-04-13 16:58:25 +05304050static int mbo_set_roaming(struct sigma_dut *dut, struct sigma_conn *conn,
4051 const char *intf, const char *val)
4052{
4053 if (strcasecmp(val, "Disable") == 0) {
4054 if (wpa_command(intf, "SET roaming 0") < 0) {
4055 send_resp(dut, conn, SIGMA_ERROR,
4056 "ErrorCode,Failed to disable roaming");
4057 return 0;
4058 }
4059 return 1;
4060 }
4061
4062 if (strcasecmp(val, "Enable") == 0) {
4063 if (wpa_command(intf, "SET roaming 1") < 0) {
4064 send_resp(dut, conn, SIGMA_ERROR,
4065 "ErrorCode,Failed to enable roaming");
4066 return 0;
4067 }
4068 return 1;
4069 }
4070
4071 sigma_dut_print(dut, DUT_MSG_ERROR,
4072 "Invalid value provided for roaming: %s", val);
4073 send_resp(dut, conn, SIGMA_INVALID,
4074 "ErrorCode,Unknown value provided for Roaming");
4075 return 0;
4076}
4077
4078
Ashwini Patila75de5a2017-04-13 16:35:05 +05304079static int mbo_set_assoc_disallow(struct sigma_dut *dut,
4080 struct sigma_conn *conn,
4081 const char *intf, const char *val)
4082{
4083 if (strcasecmp(val, "Disable") == 0) {
4084 if (wpa_command(intf, "SET ignore_assoc_disallow 1") < 0) {
4085 send_resp(dut, conn, SIGMA_ERROR,
4086 "ErrorCode,Failed to disable Assoc_disallow");
4087 return 0;
4088 }
4089 return 1;
4090 }
4091
4092 if (strcasecmp(val, "Enable") == 0) {
4093 if (wpa_command(intf, "SET ignore_assoc_disallow 0") < 0) {
4094 send_resp(dut, conn, SIGMA_ERROR,
4095 "ErrorCode,Failed to enable Assoc_disallow");
4096 return 0;
4097 }
4098 return 1;
4099 }
4100
4101 sigma_dut_print(dut, DUT_MSG_ERROR,
4102 "Invalid value provided for Assoc_disallow: %s", val);
4103 send_resp(dut, conn, SIGMA_INVALID,
4104 "ErrorCode,Unknown value provided for Assoc_disallow");
4105 return 0;
4106}
4107
4108
Ashwini Patilc63161e2017-04-13 16:30:23 +05304109static int mbo_set_bss_trans_req(struct sigma_dut *dut, struct sigma_conn *conn,
4110 const char *intf, const char *val)
4111{
4112 if (strcasecmp(val, "Reject") == 0) {
4113 if (wpa_command(intf, "SET reject_btm_req_reason 1") < 0) {
4114 send_resp(dut, conn, SIGMA_ERROR,
4115 "ErrorCode,Failed to Reject BTM Request");
4116 return 0;
4117 }
4118 return 1;
4119 }
4120
4121 if (strcasecmp(val, "Accept") == 0) {
4122 if (wpa_command(intf, "SET reject_btm_req_reason 0") < 0) {
4123 send_resp(dut, conn, SIGMA_ERROR,
4124 "ErrorCode,Failed to Accept BTM Request");
4125 return 0;
4126 }
4127 return 1;
4128 }
4129
4130 sigma_dut_print(dut, DUT_MSG_ERROR,
4131 "Invalid value provided for BSS_Transition: %s", val);
4132 send_resp(dut, conn, SIGMA_INVALID,
4133 "ErrorCode,Unknown value provided for BSS_Transition");
4134 return 0;
4135}
4136
4137
Ashwini Patil00402582017-04-13 12:29:39 +05304138static int mbo_set_non_pref_ch_list(struct sigma_dut *dut,
4139 struct sigma_conn *conn,
4140 const char *intf,
4141 struct sigma_cmd *cmd)
4142{
4143 const char *ch, *pref, *op_class, *reason;
4144 char buf[120];
4145 int len, ret;
4146
4147 pref = get_param(cmd, "Ch_Pref");
4148 if (!pref)
4149 return 1;
4150
4151 if (strcasecmp(pref, "clear") == 0) {
4152 free(dut->non_pref_ch_list);
4153 dut->non_pref_ch_list = NULL;
4154 } else {
4155 op_class = get_param(cmd, "Ch_Op_Class");
4156 if (!op_class) {
4157 send_resp(dut, conn, SIGMA_INVALID,
4158 "ErrorCode,Ch_Op_Class not provided");
4159 return 0;
4160 }
4161
4162 ch = get_param(cmd, "Ch_Pref_Num");
4163 if (!ch) {
4164 send_resp(dut, conn, SIGMA_INVALID,
4165 "ErrorCode,Ch_Pref_Num not provided");
4166 return 0;
4167 }
4168
4169 reason = get_param(cmd, "Ch_Reason_Code");
4170 if (!reason) {
4171 send_resp(dut, conn, SIGMA_INVALID,
4172 "ErrorCode,Ch_Reason_Code not provided");
4173 return 0;
4174 }
4175
4176 if (!dut->non_pref_ch_list) {
4177 dut->non_pref_ch_list =
4178 calloc(1, NON_PREF_CH_LIST_SIZE);
4179 if (!dut->non_pref_ch_list) {
4180 send_resp(dut, conn, SIGMA_ERROR,
4181 "ErrorCode,Failed to allocate memory for non_pref_ch_list");
4182 return 0;
4183 }
4184 }
4185 len = strlen(dut->non_pref_ch_list);
4186 ret = snprintf(dut->non_pref_ch_list + len,
4187 NON_PREF_CH_LIST_SIZE - len,
4188 " %s:%s:%s:%s", op_class, ch, pref, reason);
4189 if (ret > 0 && ret < NON_PREF_CH_LIST_SIZE - len) {
4190 sigma_dut_print(dut, DUT_MSG_DEBUG, "non_pref_list: %s",
4191 dut->non_pref_ch_list);
4192 } else {
4193 sigma_dut_print(dut, DUT_MSG_ERROR,
4194 "snprintf failed for non_pref_list, ret = %d",
4195 ret);
4196 send_resp(dut, conn, SIGMA_ERROR,
4197 "ErrorCode,snprintf failed");
4198 free(dut->non_pref_ch_list);
4199 dut->non_pref_ch_list = NULL;
4200 return 0;
4201 }
4202 }
4203
4204 ret = snprintf(buf, sizeof(buf), "SET non_pref_chan%s",
4205 dut->non_pref_ch_list ? dut->non_pref_ch_list : " ");
4206 if (ret < 0 || ret >= (int) sizeof(buf)) {
4207 sigma_dut_print(dut, DUT_MSG_DEBUG,
4208 "snprintf failed for set non_pref_chan, ret: %d",
4209 ret);
4210 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,snprint failed");
4211 return 0;
4212 }
4213
4214 if (wpa_command(intf, buf) < 0) {
4215 send_resp(dut, conn, SIGMA_ERROR,
4216 "ErrorCode,Failed to set non-preferred channel list");
4217 return 0;
4218 }
4219
4220 return 1;
4221}
4222
4223
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08004224#ifdef NL80211_SUPPORT
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08004225
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08004226static int sta_set_he_htc_supp(struct sigma_dut *dut, const char *intf,
4227 uint8_t cfg)
4228{
4229 struct nl_msg *msg;
4230 int ret = 0;
4231 struct nlattr *params;
4232 int ifindex;
4233
4234 ifindex = if_nametoindex(intf);
4235 if (ifindex == 0) {
4236 sigma_dut_print(dut, DUT_MSG_ERROR,
4237 "%s: Index for interface %s failed",
4238 __func__, intf);
4239 return -1;
4240 }
4241
4242 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4243 NL80211_CMD_VENDOR)) ||
4244 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4245 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4246 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4247 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4248 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4249 nla_put_u8(msg,
4250 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_HTC_HE_SUPP,
4251 cfg)) {
4252 sigma_dut_print(dut, DUT_MSG_ERROR,
4253 "%s: err in adding vendor_cmd and vendor_data",
4254 __func__);
4255 nlmsg_free(msg);
4256 return -1;
4257 }
4258 nla_nest_end(msg, params);
4259
4260 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4261 if (ret) {
4262 sigma_dut_print(dut, DUT_MSG_ERROR,
4263 "%s: err in send_and_recv_msgs, ret=%d",
4264 __func__, ret);
4265 }
4266 return ret;
4267}
4268
4269
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08004270static int sta_set_he_fragmentation(struct sigma_dut *dut, const char *intf,
4271 enum he_fragmentation_val frag)
4272{
4273 struct nl_msg *msg;
4274 int ret = 0;
4275 struct nlattr *params;
4276 int ifindex;
4277
4278 ifindex = if_nametoindex(intf);
4279 if (ifindex == 0) {
4280 sigma_dut_print(dut, DUT_MSG_ERROR,
4281 "%s: Index for interface %s failed",
4282 __func__, intf);
4283 return -1;
4284 }
4285
4286 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4287 NL80211_CMD_VENDOR)) ||
4288 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4289 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4290 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4291 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4292 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4293 nla_put_u8(msg,
4294 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_FRAGMENTATION,
4295 frag)) {
4296 sigma_dut_print(dut, DUT_MSG_ERROR,
4297 "%s: err in adding vendor_cmd and vendor_data",
4298 __func__);
4299 nlmsg_free(msg);
4300 return -1;
4301 }
4302 nla_nest_end(msg, params);
4303
4304 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4305 if (ret) {
4306 sigma_dut_print(dut, DUT_MSG_ERROR,
4307 "%s: err in send_and_recv_msgs, ret=%d",
4308 __func__, ret);
4309 }
4310 return ret;
4311}
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08004312
4313
Subhani Shaik8e7a3052018-04-24 14:03:00 -07004314static int sta_set_he_ltf(struct sigma_dut *dut, const char *intf,
4315 enum qca_wlan_he_ltf_cfg ltf)
4316{
4317 struct nl_msg *msg;
4318 int ret = 0;
4319 struct nlattr *params;
4320 int ifindex;
4321
4322 ifindex = if_nametoindex(intf);
4323 if (ifindex == 0) {
4324 sigma_dut_print(dut, DUT_MSG_ERROR,
4325 "%s: Index for interface %s failed",
4326 __func__, intf);
4327 return -1;
4328 }
4329
4330 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4331 NL80211_CMD_VENDOR)) ||
4332 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4333 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4334 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4335 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4336 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4337 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_LTF,
4338 ltf)) {
4339 sigma_dut_print(dut, DUT_MSG_ERROR,
4340 "%s: err in adding vendor_cmd and vendor_data",
4341 __func__);
4342 nlmsg_free(msg);
4343 return -1;
4344 }
4345 nla_nest_end(msg, params);
4346
4347 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4348 if (ret) {
4349 sigma_dut_print(dut, DUT_MSG_ERROR,
4350 "%s: err in send_and_recv_msgs, ret=%d",
4351 __func__, ret);
4352 }
4353 return ret;
4354}
4355
4356
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08004357static int nlvendor_sta_set_noack(struct sigma_dut *dut, const char *intf,
4358 int noack, enum qca_wlan_ac_type ac)
4359{
4360 struct nl_msg *msg;
4361 int ret = 0;
4362 struct nlattr *params;
4363 int ifindex;
4364
4365 ifindex = if_nametoindex(intf);
4366 if (ifindex == 0) {
4367 sigma_dut_print(dut, DUT_MSG_ERROR,
4368 "%s: Index for interface %s failed",
4369 __func__, intf);
4370 return -1;
4371 }
4372
4373 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4374 NL80211_CMD_VENDOR)) ||
4375 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4376 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4377 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4378 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4379 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4380 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_NO_ACK,
4381 noack) ||
4382 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_NO_ACK_AC,
4383 ac)) {
4384 sigma_dut_print(dut, DUT_MSG_ERROR,
4385 "%s: err in adding vendor_cmd and vendor_data",
4386 __func__);
4387 nlmsg_free(msg);
4388 return -1;
4389 }
4390 nla_nest_end(msg, params);
4391
4392 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4393 if (ret) {
4394 sigma_dut_print(dut, DUT_MSG_ERROR,
4395 "%s: err in send_and_recv_msgs, ret=%d",
4396 __func__, ret);
4397 }
4398 return ret;
4399}
4400
4401
4402static void wcn_sta_set_noack(struct sigma_dut *dut, const char *intf,
4403 const char *val)
4404{
4405 int noack, ret;
4406 char token[100];
4407 char *result;
4408 char *saveptr;
4409 enum qca_wlan_ac_type ac = QCA_WLAN_AC_BE;
4410
4411 strlcpy(token, val, sizeof(token));
4412 token[sizeof(token) - 1] = '\0';
4413 result = strtok_r(token, ":", &saveptr);
4414 while (result) {
4415 noack = strcasecmp(result, "Disable") != 0;
4416 ret = nlvendor_sta_set_noack(dut, intf, noack, ac);
4417 if (ret) {
4418 sigma_dut_print(dut, DUT_MSG_ERROR,
4419 "nlvendor_sta_set_noack failed for ac:%d, ret:%d",
4420 ac, ret);
4421 }
4422 result = strtok_r(NULL, ":", &saveptr);
4423 ac++;
4424 }
4425}
4426
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08004427#endif /* NL80211_SUPPORT */
4428
4429
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004430static int cmd_sta_preset_testparameters(struct sigma_dut *dut,
4431 struct sigma_conn *conn,
4432 struct sigma_cmd *cmd)
4433{
4434 const char *intf = get_param(cmd, "Interface");
4435 const char *val;
4436
4437 val = get_param(cmd, "Program");
Jouni Malinen1f6ae642018-06-07 23:56:13 +03004438 if (val && (strcasecmp(val, "HS2-R2") == 0 ||
4439 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004440 return cmd_sta_preset_testparameters_hs2_r2(dut, conn, intf,
4441 cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004442
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07004443 if (val && strcasecmp(val, "LOC") == 0)
4444 return loc_cmd_sta_preset_testparameters(dut, conn, cmd);
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02004445 if (val && strcasecmp(val, "60GHZ") == 0) {
4446 val = get_param(cmd, "WPS");
4447 if (val && strcasecmp(val, "disable") == 0) {
4448 dut->wps_disable = 1;
4449 sigma_dut_print(dut, DUT_MSG_INFO, "WPS disabled");
4450 } else {
4451 /* wps_disable can have other value from the previous
4452 * test, so make sure it has the correct value.
4453 */
4454 dut->wps_disable = 0;
4455 }
4456
4457 val = get_param(cmd, "P2P");
4458 if (val && strcasecmp(val, "disable") == 0)
4459 sigma_dut_print(dut, DUT_MSG_INFO, "P2P disabled");
4460 }
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07004461
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02004462 if (dut->program == PROGRAM_WPS && dut->band == WPS_BAND_60G)
4463 return cmd_sta_preset_testparameters_60ghz(dut, conn, cmd);
4464
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004465#ifdef ANDROID_NAN
4466 if (val && strcasecmp(val, "NAN") == 0)
4467 return nan_cmd_sta_preset_testparameters(dut, conn, cmd);
4468#endif /* ANDROID_NAN */
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07004469#ifdef MIRACAST
4470 if (val && (strcasecmp(val, "WFD") == 0 ||
4471 strcasecmp(val, "DisplayR2") == 0))
4472 return miracast_preset_testparameters(dut, conn, cmd);
4473#endif /* MIRACAST */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004474
Ashwini Patil68d02cd2017-01-10 15:39:16 +05304475 if (val && strcasecmp(val, "MBO") == 0) {
4476 val = get_param(cmd, "Cellular_Data_Cap");
4477 if (val &&
4478 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
4479 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +05304480
4481 val = get_param(cmd, "Ch_Pref");
4482 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
4483 return 0;
4484
Ashwini Patilc63161e2017-04-13 16:30:23 +05304485 val = get_param(cmd, "BSS_Transition");
4486 if (val && mbo_set_bss_trans_req(dut, conn, intf, val) == 0)
4487 return 0;
4488
Ashwini Patila75de5a2017-04-13 16:35:05 +05304489 val = get_param(cmd, "Assoc_Disallow");
4490 if (val && mbo_set_assoc_disallow(dut, conn, intf, val) == 0)
4491 return 0;
4492
Ashwini Patil9183fdb2017-04-13 16:58:25 +05304493 val = get_param(cmd, "Roaming");
4494 if (val && mbo_set_roaming(dut, conn, intf, val) == 0)
4495 return 0;
4496
Ashwini Patil68d02cd2017-01-10 15:39:16 +05304497 return 1;
4498 }
4499
Ankita Bajaja2cb5672017-10-25 16:08:28 +05304500 if (val && strcasecmp(val, "OCE") == 0)
4501 return cmd_sta_preset_testparameters_oce(dut, conn, intf, cmd);
4502
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004503#if 0
4504 val = get_param(cmd, "Supplicant");
4505 if (val && strcasecmp(val, "Default") != 0) {
4506 send_resp(dut, conn, SIGMA_ERROR,
4507 "ErrorCode,Only default(Vendor) supplicant "
4508 "supported");
4509 return 0;
4510 }
4511#endif
4512
4513 val = get_param(cmd, "RTS");
4514 if (val) {
4515 switch (get_driver_type()) {
4516 case DRIVER_ATHEROS:
4517 ath_sta_set_rts(dut, intf, val);
4518 break;
4519 default:
4520#if 0
4521 send_resp(dut, conn, SIGMA_ERROR,
4522 "ErrorCode,Setting RTS not supported");
4523 return 0;
4524#else
4525 sigma_dut_print(dut, DUT_MSG_DEBUG,
4526 "Setting RTS not supported");
4527 break;
4528#endif
4529 }
4530 }
4531
4532#if 0
4533 val = get_param(cmd, "FRGMNT");
4534 if (val) {
4535 /* TODO */
4536 send_resp(dut, conn, SIGMA_ERROR,
4537 "ErrorCode,Setting FRGMNT not supported");
4538 return 0;
4539 }
4540#endif
4541
4542#if 0
4543 val = get_param(cmd, "Preamble");
4544 if (val) {
4545 /* TODO: Long/Short */
4546 send_resp(dut, conn, SIGMA_ERROR,
4547 "ErrorCode,Setting Preamble not supported");
4548 return 0;
4549 }
4550#endif
4551
4552 val = get_param(cmd, "Mode");
4553 if (val) {
4554 if (strcmp(val, "11b") == 0 ||
4555 strcmp(val, "11g") == 0 ||
4556 strcmp(val, "11a") == 0 ||
4557 strcmp(val, "11n") == 0 ||
4558 strcmp(val, "11ng") == 0 ||
4559 strcmp(val, "11nl") == 0 ||
4560 strcmp(val, "11nl(nabg)") == 0 ||
4561 strcmp(val, "AC") == 0 ||
4562 strcmp(val, "11AC") == 0 ||
4563 strcmp(val, "11ac") == 0 ||
4564 strcmp(val, "11na") == 0 ||
Amarnath Hullur Subramanyamb0db2712018-01-30 19:40:35 -08004565 strcmp(val, "11an") == 0 ||
4566 strcmp(val, "11ax") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004567 /* STA supports all modes by default */
4568 } else {
4569 send_resp(dut, conn, SIGMA_ERROR,
4570 "ErrorCode,Setting Mode not supported");
4571 return 0;
4572 }
Amarnath Hullur Subramanyam97d0e532018-01-31 02:53:02 -08004573
4574 /* Change the mode only in case of testbed for HE program
4575 * and for 11a and 11g modes only. */
4576 if (dut->program == PROGRAM_HE &&
4577 dut->device_type == STA_testbed) {
4578 int phymode;
4579 char buf[60];
4580
4581 if (strcmp(val, "11a") == 0) {
Amarnath Hullur Subramanyam94dfaf02018-03-02 19:26:57 -08004582 phymode = 1; /* IEEE80211_MODE_11A */
4583 } else if (strcmp(val, "11g") == 0) {
4584 phymode = 3; /* IEEE80211_MODE_11G */
4585 } else if (strcmp(val, "11b") == 0) {
4586 phymode = 2; /* IEEE80211_MODE_11B */
4587 } else if (strcmp(val, "11n") == 0 ||
4588 strcmp(val, "11nl") == 0 ||
4589 strcmp(val, "11nl(nabg)") == 0) {
4590 phymode = 22; /* IEEE80211_MODE_11AGN */
4591 } else if (strcmp(val, "11ng") == 0) {
4592 phymode = 13; /* IEEE80211_MODE_11NG_HT40 */
4593 } else if (strcmp(val, "AC") == 0 ||
4594 strcasecmp(val, "11AC") == 0) {
4595 phymode = 19; /* IEEE80211_MODE_11AC_VHT80 */
4596 } else if (strcmp(val, "11na") == 0 ||
4597 strcasecmp(val, "11an") == 0) {
4598 phymode = 14; /* IEEE80211_MODE_11NA_HT40 */
4599 } else if (strcmp(val, "11ax") == 0) {
4600 phymode = 0; /* IEEE80211_MODE_AUTO */
Amarnath Hullur Subramanyam97d0e532018-01-31 02:53:02 -08004601 } else {
4602 sigma_dut_print(dut, DUT_MSG_DEBUG,
4603 "Ignoring mode change for mode: %s",
4604 val);
4605 phymode = -1;
4606 }
4607 if (phymode != -1) {
4608 snprintf(buf, sizeof(buf),
4609 "iwpriv %s setphymode %d",
4610 intf, phymode);
4611 if (system(buf) != 0) {
4612 sigma_dut_print(dut, DUT_MSG_ERROR,
4613 "iwpriv setting of phymode failed");
4614 }
4615 }
4616 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004617 }
4618
4619 val = get_param(cmd, "wmm");
4620 if (val) {
4621 switch (get_driver_type()) {
4622 case DRIVER_ATHEROS:
4623 ath_sta_set_wmm(dut, intf, val);
4624 break;
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08004625 case DRIVER_WCN:
4626 wcn_sta_set_wmm(dut, intf, val);
4627 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004628 default:
4629 sigma_dut_print(dut, DUT_MSG_DEBUG,
4630 "Setting wmm not supported");
4631 break;
4632 }
4633 }
4634
4635 val = get_param(cmd, "Powersave");
4636 if (val) {
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08004637 char buf[60];
4638
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004639 if (strcmp(val, "0") == 0 || strcasecmp(val, "off") == 0) {
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08004640 if (get_driver_type() == DRIVER_WCN) {
4641 snprintf(buf, sizeof(buf),
4642 "iwpriv %s setPower 2", intf);
4643 if (system(buf) != 0) {
4644 sigma_dut_print(dut, DUT_MSG_ERROR,
4645 "iwpriv setPower 2 failed");
4646 return 0;
4647 }
4648 }
4649
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004650 if (wpa_command(get_station_ifname(),
4651 "P2P_SET ps 0") < 0)
4652 return -2;
4653 /* Make sure test modes are disabled */
4654 wpa_command(get_station_ifname(), "P2P_SET ps 98");
4655 wpa_command(get_station_ifname(), "P2P_SET ps 96");
4656 } else if (strcmp(val, "1") == 0 ||
4657 strcasecmp(val, "PSPoll") == 0 ||
4658 strcasecmp(val, "on") == 0) {
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08004659 if (get_driver_type() == DRIVER_WCN) {
4660 snprintf(buf, sizeof(buf),
4661 "iwpriv %s setPower 1", intf);
4662 if (system(buf) != 0) {
4663 sigma_dut_print(dut, DUT_MSG_ERROR,
4664 "iwpriv setPower 1 failed");
4665 return 0;
4666 }
4667 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004668 /* Disable default power save mode */
4669 wpa_command(get_station_ifname(), "P2P_SET ps 0");
4670 /* Enable PS-Poll test mode */
4671 if (wpa_command(get_station_ifname(),
4672 "P2P_SET ps 97") < 0 ||
4673 wpa_command(get_station_ifname(),
4674 "P2P_SET ps 99") < 0)
4675 return -2;
4676 } else if (strcmp(val, "2") == 0 ||
4677 strcasecmp(val, "Fast") == 0) {
4678 /* TODO */
4679 send_resp(dut, conn, SIGMA_ERROR,
4680 "ErrorCode,Powersave=Fast not supported");
4681 return 0;
4682 } else if (strcmp(val, "3") == 0 ||
4683 strcasecmp(val, "PSNonPoll") == 0) {
4684 /* Make sure test modes are disabled */
4685 wpa_command(get_station_ifname(), "P2P_SET ps 98");
4686 wpa_command(get_station_ifname(), "P2P_SET ps 96");
4687
4688 /* Enable default power save mode */
4689 if (wpa_command(get_station_ifname(),
4690 "P2P_SET ps 1") < 0)
4691 return -2;
4692 } else
4693 return -1;
4694 }
4695
4696 val = get_param(cmd, "NoAck");
4697 if (val) {
4698 switch (get_driver_type()) {
4699 case DRIVER_ATHEROS:
4700 ath_sta_set_noack(dut, intf, val);
4701 break;
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08004702#ifdef NL80211_SUPPORT
4703 case DRIVER_WCN:
4704 wcn_sta_set_noack(dut, intf, val);
4705 break;
4706#endif /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004707 default:
4708 send_resp(dut, conn, SIGMA_ERROR,
4709 "ErrorCode,Setting NoAck not supported");
4710 return 0;
4711 }
4712 }
4713
4714 val = get_param(cmd, "IgnoreChswitchProhibit");
4715 if (val) {
4716 /* TODO: Enabled/disabled */
4717 if (strcasecmp(val, "Enabled") == 0) {
4718 send_resp(dut, conn, SIGMA_ERROR,
4719 "ErrorCode,Enabling IgnoreChswitchProhibit "
4720 "not supported");
4721 return 0;
4722 }
4723 }
4724
4725 val = get_param(cmd, "TDLS");
4726 if (val) {
4727 if (strcasecmp(val, "Disabled") == 0) {
4728 if (wpa_command(intf, "SET tdls_disabled 1")) {
4729 send_resp(dut, conn, SIGMA_ERROR,
4730 "ErrorCode,Failed to disable TDLS");
4731 return 0;
4732 }
4733 } else if (strcasecmp(val, "Enabled") == 0) {
4734 if (wpa_command(intf, "SET tdls_disabled 0")) {
4735 send_resp(dut, conn, SIGMA_ERROR,
4736 "ErrorCode,Failed to enable TDLS");
4737 return 0;
4738 }
4739 } else {
4740 send_resp(dut, conn, SIGMA_ERROR,
4741 "ErrorCode,Unsupported TDLS value");
4742 return 0;
4743 }
4744 }
4745
4746 val = get_param(cmd, "TDLSmode");
4747 if (val) {
4748 if (strcasecmp(val, "Default") == 0) {
4749 wpa_command(intf, "SET tdls_testing 0");
4750 } else if (strcasecmp(val, "APProhibit") == 0) {
4751 if (wpa_command(intf, "SET tdls_testing 0x400")) {
4752 send_resp(dut, conn, SIGMA_ERROR,
4753 "ErrorCode,Failed to enable ignore "
4754 "APProhibit TDLS mode");
4755 return 0;
4756 }
4757 } else if (strcasecmp(val, "HiLoMac") == 0) {
4758 /* STA should respond with TDLS setup req for a TDLS
4759 * setup req */
4760 if (wpa_command(intf, "SET tdls_testing 0x80")) {
4761 send_resp(dut, conn, SIGMA_ERROR,
4762 "ErrorCode,Failed to enable HiLoMac "
4763 "TDLS mode");
4764 return 0;
4765 }
4766 } else if (strcasecmp(val, "WeakSecurity") == 0) {
4767 /*
4768 * Since all security modes are enabled by default when
4769 * Sigma control is used, there is no need to do
4770 * anything here.
4771 */
4772 } else if (strcasecmp(val, "ExistLink") == 0) {
4773 /*
4774 * Since we allow new TDLS Setup Request even if there
4775 * is an existing link, nothing needs to be done for
4776 * this.
4777 */
4778 } else {
4779 /* TODO:
4780 * ExistLink: STA should send TDLS setup req even if
4781 * direct link already exists
4782 */
4783 send_resp(dut, conn, SIGMA_ERROR,
4784 "ErrorCode,Unsupported TDLSmode value");
4785 return 0;
4786 }
4787 }
4788
4789 val = get_param(cmd, "FakePubKey");
4790 if (val && atoi(val) && wpa_command(intf, "SET wps_corrupt_pkhash 1")) {
4791 send_resp(dut, conn, SIGMA_ERROR,
4792 "ErrorCode,Failed to enable FakePubKey");
4793 return 0;
4794 }
4795
Amarnath Hullur Subramanyamae1042b2018-02-22 21:52:52 -08004796#ifdef NL80211_SUPPORT
4797 val = get_param(cmd, "FrgmntSupport");
4798 if (val) {
4799 if (strcasecmp(val, "Enable") == 0) {
4800 if (sta_set_he_fragmentation(dut, intf,
4801 HE_FRAG_LEVEL1)) {
4802 send_resp(dut, conn, SIGMA_ERROR,
4803 "ErrorCode,Failed to enable HE Fragmentation");
4804 return 0;
4805 }
4806 } else if (strcasecmp(val, "Disable") == 0) {
4807 if (sta_set_he_fragmentation(dut, intf,
4808 HE_FRAG_DISABLE)) {
4809 send_resp(dut, conn, SIGMA_ERROR,
4810 "ErrorCode,Failed to disable HE Fragmentation");
4811 return 0;
4812 }
4813 }
4814 }
4815#endif /* NL80211_SUPPORT */
4816
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004817 return 1;
4818}
4819
4820
4821static const char * ath_get_radio_name(const char *radio_name)
4822{
4823 if (radio_name == NULL)
4824 return "wifi0";
4825 if (strcmp(radio_name, "wifi1") == 0)
4826 return "wifi1";
4827 if (strcmp(radio_name, "wifi2") == 0)
4828 return "wifi2";
4829 return "wifi0";
4830}
4831
4832
4833static void ath_sta_set_txsp_stream(struct sigma_dut *dut, const char *intf,
4834 const char *val)
4835{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004836 unsigned int vht_mcsmap = 0;
4837 int txchainmask = 0;
4838 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
4839
4840 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
4841 if (dut->testbed_flag_txsp == 1) {
4842 vht_mcsmap = 0xfffc;
4843 dut->testbed_flag_txsp = 0;
4844 } else {
4845 vht_mcsmap = 0xfffe;
4846 }
4847 txchainmask = 1;
4848 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
4849 if (dut->testbed_flag_txsp == 1) {
4850 vht_mcsmap = 0xfff0;
4851 dut->testbed_flag_txsp = 0;
4852 } else {
4853 vht_mcsmap = 0xfffa;
4854 }
4855 txchainmask = 3;
4856 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
4857 if (dut->testbed_flag_txsp == 1) {
4858 vht_mcsmap = 0xffc0;
4859 dut->testbed_flag_txsp = 0;
4860 } else {
4861 vht_mcsmap = 0xffea;
4862 }
4863 txchainmask = 7;
4864 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
4865 if (dut->testbed_flag_txsp == 1) {
4866 vht_mcsmap = 0xff00;
4867 dut->testbed_flag_txsp = 0;
4868 } else {
4869 vht_mcsmap = 0xffaa;
4870 }
4871 txchainmask = 15;
4872 } else {
4873 if (dut->testbed_flag_txsp == 1) {
4874 vht_mcsmap = 0xffc0;
4875 dut->testbed_flag_txsp = 0;
4876 } else {
4877 vht_mcsmap = 0xffea;
4878 }
4879 }
4880
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004881 if (txchainmask)
4882 run_iwpriv(dut, basedev, "txchainmask %d", txchainmask);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004883
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004884 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004885}
4886
4887
4888static void ath_sta_set_rxsp_stream(struct sigma_dut *dut, const char *intf,
4889 const char *val)
4890{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004891 unsigned int vht_mcsmap = 0;
4892 int rxchainmask = 0;
4893 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
4894
4895 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
4896 if (dut->testbed_flag_rxsp == 1) {
4897 vht_mcsmap = 0xfffc;
4898 dut->testbed_flag_rxsp = 0;
4899 } else {
4900 vht_mcsmap = 0xfffe;
4901 }
4902 rxchainmask = 1;
4903 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
4904 if (dut->testbed_flag_rxsp == 1) {
4905 vht_mcsmap = 0xfff0;
4906 dut->testbed_flag_rxsp = 0;
4907 } else {
4908 vht_mcsmap = 0xfffa;
4909 }
4910 rxchainmask = 3;
4911 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
4912 if (dut->testbed_flag_rxsp == 1) {
4913 vht_mcsmap = 0xffc0;
4914 dut->testbed_flag_rxsp = 0;
4915 } else {
4916 vht_mcsmap = 0xffea;
4917 }
4918 rxchainmask = 7;
4919 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
4920 if (dut->testbed_flag_rxsp == 1) {
4921 vht_mcsmap = 0xff00;
4922 dut->testbed_flag_rxsp = 0;
4923 } else {
4924 vht_mcsmap = 0xffaa;
4925 }
4926 rxchainmask = 15;
4927 } else {
4928 if (dut->testbed_flag_rxsp == 1) {
4929 vht_mcsmap = 0xffc0;
4930 dut->testbed_flag_rxsp = 0;
4931 } else {
4932 vht_mcsmap = 0xffea;
4933 }
4934 }
4935
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004936 if (rxchainmask)
4937 run_iwpriv(dut, basedev, "rxchainmask %d", rxchainmask);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004938
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004939 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004940}
4941
4942
4943void ath_set_zero_crc(struct sigma_dut *dut, const char *val)
4944{
4945 if (strcasecmp(val, "enable") == 0) {
4946 if (system("athdiag --set --address=0x2a204 --and=0xbfffffff")
4947 != 0) {
4948 sigma_dut_print(dut, DUT_MSG_ERROR,
4949 "Disable BB_VHTSIGB_CRC_CALC failed");
4950 }
4951
4952 if (system("athdiag --set --address=0x2a204 --or=0x80000000")
4953 != 0) {
4954 sigma_dut_print(dut, DUT_MSG_ERROR,
4955 "Enable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
4956 }
4957 } else {
4958 if (system("athdiag --set --address=0x2a204 --and=0x7fffffff")
4959 != 0) {
4960 sigma_dut_print(dut, DUT_MSG_ERROR,
4961 "Disable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
4962 }
4963
4964 if (system("athdiag --set --address=0x2a204 --or=0x40000000")
4965 != 0) {
4966 sigma_dut_print(dut, DUT_MSG_ERROR,
4967 "Enable BB_VHTSIGB_CRC_CALC failed");
4968 }
4969 }
4970}
4971
4972
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08004973static int wcn_sta_set_width(struct sigma_dut *dut, const char *intf,
4974 const char *val)
4975{
4976 char buf[60];
4977
4978 if (strcmp(val, "20") == 0) {
4979 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 0", intf);
4980 dut->chwidth = 0;
4981 } else if (strcmp(val, "40") == 0) {
4982 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 1", intf);
4983 dut->chwidth = 1;
4984 } else if (strcmp(val, "80") == 0) {
4985 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 2", intf);
4986 dut->chwidth = 2;
Sunil Duttb1cccac2018-05-22 21:03:12 +05304987 } else if (strcasecmp(val, "Auto") == 0) {
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08004988 buf[0] = '\0';
4989 } else {
4990 sigma_dut_print(dut, DUT_MSG_ERROR, "WIDTH %s not supported",
4991 val);
4992 return -1;
4993 }
4994
4995 if (buf[0] != '\0' && system(buf) != 0) {
4996 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv chwidth failed");
4997 return -1;
4998 }
4999
5000 return 0;
5001}
5002
5003
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005004static int nlvendor_sta_set_addba_reject(struct sigma_dut *dut,
5005 const char *intf, int addbareject)
5006{
5007#ifdef NL80211_SUPPORT
5008 struct nl_msg *msg;
5009 int ret = 0;
5010 struct nlattr *params;
5011 int ifindex;
5012
5013 ifindex = if_nametoindex(intf);
5014 if (ifindex == 0) {
5015 sigma_dut_print(dut, DUT_MSG_ERROR,
5016 "%s: Index for interface %s failed",
5017 __func__, intf);
5018 return -1;
5019 }
5020
5021 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
5022 NL80211_CMD_VENDOR)) ||
5023 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
5024 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
5025 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
5026 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
5027 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
5028 nla_put_u8(msg,
5029 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ACCEPT_ADDBA_REQ,
5030 !addbareject)) {
5031 sigma_dut_print(dut, DUT_MSG_ERROR,
5032 "%s: err in adding vendor_cmd and vendor_data",
5033 __func__);
5034 nlmsg_free(msg);
5035 return -1;
5036 }
5037 nla_nest_end(msg, params);
5038
5039 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5040 if (ret) {
5041 sigma_dut_print(dut, DUT_MSG_ERROR,
5042 "%s: err in send_and_recv_msgs, ret=%d",
5043 __func__, ret);
5044 }
5045 return ret;
5046#else /* NL80211_SUPPORT */
5047 sigma_dut_print(dut, DUT_MSG_ERROR,
5048 "ADDBA_REJECT cannot be set without NL80211_SUPPORT defined");
5049 return -1;
5050#endif /* NL80211_SUPPORT */
5051}
5052
5053
5054static int sta_set_addba_reject(struct sigma_dut *dut, const char *intf,
5055 int addbareject)
5056{
5057 int ret;
5058
5059 switch (get_driver_type()) {
5060 case DRIVER_WCN:
5061 ret = nlvendor_sta_set_addba_reject(dut, intf, addbareject);
5062 if (ret) {
5063 sigma_dut_print(dut, DUT_MSG_ERROR,
5064 "nlvendor_sta_set_addba_reject failed, ret:%d",
5065 ret);
5066 return ret;
5067 }
5068 break;
5069 default:
5070 sigma_dut_print(dut, DUT_MSG_ERROR,
5071 "errorCode,Unsupported ADDBA_REJECT with the current driver");
5072 ret = -1;
5073 break;
5074 }
5075
5076 return ret;
5077}
5078
5079
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08005080static int nlvendor_config_send_addba(struct sigma_dut *dut, const char *intf,
5081 int enable)
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005082{
5083#ifdef NL80211_SUPPORT
5084 struct nl_msg *msg;
5085 int ret = 0;
5086 struct nlattr *params;
5087 int ifindex;
5088
5089 ifindex = if_nametoindex(intf);
5090 if (ifindex == 0) {
5091 sigma_dut_print(dut, DUT_MSG_ERROR,
5092 "%s: Index for interface %s failed",
5093 __func__, intf);
5094 return -1;
5095 }
5096
5097 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
5098 NL80211_CMD_VENDOR)) ||
5099 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
5100 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
5101 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
5102 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
5103 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
5104 nla_put_u8(msg,
5105 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_SEND_ADDBA_REQ,
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08005106 enable)) {
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005107 sigma_dut_print(dut, DUT_MSG_ERROR,
5108 "%s: err in adding vendor_cmd and vendor_data",
5109 __func__);
5110 nlmsg_free(msg);
5111 return -1;
5112 }
5113 nla_nest_end(msg, params);
5114
5115 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5116 if (ret) {
5117 sigma_dut_print(dut, DUT_MSG_ERROR,
5118 "%s: err in send_and_recv_msgs, ret=%d",
5119 __func__, ret);
5120 }
5121 return ret;
5122#else /* NL80211_SUPPORT */
5123 sigma_dut_print(dut, DUT_MSG_ERROR,
5124 "Disable addba not possible without NL80211_SUPPORT defined");
5125 return -1;
5126#endif /* NL80211_SUPPORT */
5127}
5128
5129
Veerendranath Jakkamadcd6202019-04-17 12:32:21 +05305130#ifdef NL80211_SUPPORT
5131static int nl80211_sta_set_rts(struct sigma_dut *dut, const char *intf, int val)
5132{
5133 struct nl_msg *msg;
5134 int ret = 0;
5135 int ifindex;
5136
5137 ifindex = if_nametoindex(intf);
5138 if (ifindex == 0) {
5139 sigma_dut_print(dut, DUT_MSG_ERROR,
5140 "%s: Index for interface %s failed",
5141 __func__, intf);
5142 return -1;
5143 }
5144
5145 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
5146 NL80211_CMD_SET_WIPHY)) ||
5147 nla_put_u32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD, val)) {
5148 sigma_dut_print(dut, DUT_MSG_ERROR,
5149 "%s: err in adding RTS threshold",
5150 __func__);
5151 nlmsg_free(msg);
5152 return -1;
5153 }
5154
5155 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5156 if (ret) {
5157 sigma_dut_print(dut, DUT_MSG_ERROR,
5158 "%s: err in send_and_recv_msgs, ret=%d",
5159 __func__, ret);
5160 }
5161 return ret;
5162}
5163#endif /* NL80211_SUPPORT */
5164
5165
5166static int sta_set_rts(struct sigma_dut *dut, const char *intf, int val)
5167{
5168 char buf[100];
5169
5170#ifdef NL80211_SUPPORT
5171 if (nl80211_sta_set_rts(dut, intf, val) == 0)
5172 return 0;
5173 sigma_dut_print(dut, DUT_MSG_DEBUG,
5174 "Fall back to using iwconfig for setting RTS threshold");
5175#endif /* NL80211_SUPPORT */
5176
5177 snprintf(buf, sizeof(buf), "iwconfig %s rts %d", intf, val);
5178 if (system(buf) != 0) {
5179 sigma_dut_print(dut, DUT_MSG_ERROR,
5180 "Failed to set RTS threshold %d", val);
5181 return -1;
5182 }
5183 return 0;
5184}
5185
5186
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005187static int cmd_sta_set_wireless_common(const char *intf, struct sigma_dut *dut,
5188 struct sigma_conn *conn,
5189 struct sigma_cmd *cmd)
5190{
5191 const char *val;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005192 int ampdu = -1, addbareject = -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005193 char buf[30];
5194
5195 val = get_param(cmd, "40_INTOLERANT");
5196 if (val) {
5197 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
5198 /* TODO: iwpriv ht40intol through wpa_supplicant */
5199 send_resp(dut, conn, SIGMA_ERROR,
5200 "ErrorCode,40_INTOLERANT not supported");
5201 return 0;
5202 }
5203 }
5204
5205 val = get_param(cmd, "ADDBA_REJECT");
5206 if (val) {
5207 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
5208 /* reject any ADDBA with status "decline" */
5209 ampdu = 0;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005210 addbareject = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005211 } else {
5212 /* accept ADDBA */
5213 ampdu = 1;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005214 addbareject = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005215 }
5216 }
5217
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005218 if (addbareject >= 0 &&
5219 sta_set_addba_reject(dut, intf, addbareject) < 0) {
5220 send_resp(dut, conn, SIGMA_ERROR,
5221 "ErrorCode,set addba_reject failed");
5222 return 0;
5223 }
5224
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005225 val = get_param(cmd, "AMPDU");
5226 if (val) {
5227 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
5228 /* enable AMPDU Aggregation */
5229 if (ampdu == 0) {
5230 send_resp(dut, conn, SIGMA_ERROR,
5231 "ErrorCode,Mismatch in "
5232 "addba_reject/ampdu - "
5233 "not supported");
5234 return 0;
5235 }
5236 ampdu = 1;
5237 } else {
5238 /* disable AMPDU Aggregation */
5239 if (ampdu == 1) {
5240 send_resp(dut, conn, SIGMA_ERROR,
5241 "ErrorCode,Mismatch in "
5242 "addba_reject/ampdu - "
5243 "not supported");
5244 return 0;
5245 }
5246 ampdu = 0;
5247 }
5248 }
5249
5250 if (ampdu >= 0) {
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005251 int ret;
5252
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005253 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s A-MPDU aggregation",
5254 ampdu ? "Enabling" : "Disabling");
5255 snprintf(buf, sizeof(buf), "SET ampdu %d", ampdu);
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07005256 if (wpa_command(intf, buf) < 0 &&
5257 iwpriv_sta_set_ampdu(dut, intf, ampdu) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005258 send_resp(dut, conn, SIGMA_ERROR,
5259 "ErrorCode,set aggr failed");
5260 return 0;
5261 }
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005262
5263 if (ampdu == 0) {
5264 /* Disable sending of addba using nl vendor command */
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08005265 ret = nlvendor_config_send_addba(dut, intf, 0);
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005266 if (ret) {
5267 sigma_dut_print(dut, DUT_MSG_ERROR,
5268 "Failed to disable addba, ret:%d",
5269 ret);
5270 }
5271 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005272 }
5273
5274 val = get_param(cmd, "AMSDU");
5275 if (val) {
5276 switch (get_driver_type()) {
5277 case DRIVER_ATHEROS:
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08005278 case DRIVER_WCN:
5279 iwpriv_sta_set_amsdu(dut, intf, val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005280 break;
5281 default:
5282 if (strcmp(val, "1") == 0 ||
5283 strcasecmp(val, "Enable") == 0) {
5284 /* Enable AMSDU Aggregation */
5285 send_resp(dut, conn, SIGMA_ERROR,
5286 "ErrorCode,AMSDU aggregation not supported");
5287 return 0;
5288 }
5289 break;
5290 }
5291 }
5292
5293 val = get_param(cmd, "STBC_RX");
5294 if (val) {
5295 switch (get_driver_type()) {
5296 case DRIVER_ATHEROS:
5297 ath_sta_set_stbc(dut, intf, val);
5298 break;
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05305299 case DRIVER_WCN:
5300 wcn_sta_set_stbc(dut, intf, val);
5301 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005302 default:
5303 send_resp(dut, conn, SIGMA_ERROR,
5304 "ErrorCode,STBC_RX not supported");
5305 return 0;
5306 }
5307 }
5308
5309 val = get_param(cmd, "WIDTH");
5310 if (val) {
5311 switch (get_driver_type()) {
5312 case DRIVER_WCN:
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08005313 if (wcn_sta_set_width(dut, intf, val) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005314 send_resp(dut, conn, SIGMA_ERROR,
5315 "ErrorCode,Failed to set WIDTH");
5316 return 0;
5317 }
5318 break;
5319 case DRIVER_ATHEROS:
5320 if (ath_set_width(dut, conn, intf, val) < 0)
5321 return 0;
5322 break;
5323 default:
5324 sigma_dut_print(dut, DUT_MSG_ERROR,
5325 "Setting WIDTH not supported");
5326 break;
5327 }
5328 }
5329
5330 val = get_param(cmd, "SMPS");
5331 if (val) {
5332 /* TODO: Dynamic/0, Static/1, No Limit/2 */
5333 send_resp(dut, conn, SIGMA_ERROR,
5334 "ErrorCode,SMPS not supported");
5335 return 0;
5336 }
5337
5338 val = get_param(cmd, "TXSP_STREAM");
5339 if (val) {
5340 switch (get_driver_type()) {
5341 case DRIVER_WCN:
5342 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
5343 send_resp(dut, conn, SIGMA_ERROR,
5344 "ErrorCode,Failed to set TXSP_STREAM");
5345 return 0;
5346 }
5347 break;
5348 case DRIVER_ATHEROS:
5349 ath_sta_set_txsp_stream(dut, intf, val);
5350 break;
5351 default:
5352 sigma_dut_print(dut, DUT_MSG_ERROR,
5353 "Setting TXSP_STREAM not supported");
5354 break;
5355 }
5356 }
5357
5358 val = get_param(cmd, "RXSP_STREAM");
5359 if (val) {
5360 switch (get_driver_type()) {
5361 case DRIVER_WCN:
5362 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
5363 send_resp(dut, conn, SIGMA_ERROR,
5364 "ErrorCode,Failed to set RXSP_STREAM");
5365 return 0;
5366 }
5367 break;
5368 case DRIVER_ATHEROS:
5369 ath_sta_set_rxsp_stream(dut, intf, val);
5370 break;
5371 default:
5372 sigma_dut_print(dut, DUT_MSG_ERROR,
5373 "Setting RXSP_STREAM not supported");
5374 break;
5375 }
5376 }
5377
5378 val = get_param(cmd, "DYN_BW_SGNL");
5379 if (val) {
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08005380 switch (get_driver_type()) {
5381 case DRIVER_WCN:
Peng Xuc59afd32016-11-21 15:01:11 -08005382 if (strcasecmp(val, "enable") == 0) {
5383 snprintf(buf, sizeof(buf),
5384 "iwpriv %s cwmenable 1", intf);
5385 if (system(buf) != 0) {
5386 sigma_dut_print(dut, DUT_MSG_ERROR,
5387 "iwpriv cwmenable 1 failed");
5388 return 0;
5389 }
5390 } else if (strcasecmp(val, "disable") == 0) {
5391 snprintf(buf, sizeof(buf),
5392 "iwpriv %s cwmenable 0", intf);
5393 if (system(buf) != 0) {
5394 sigma_dut_print(dut, DUT_MSG_ERROR,
5395 "iwpriv cwmenable 0 failed");
5396 return 0;
5397 }
5398 } else {
5399 sigma_dut_print(dut, DUT_MSG_ERROR,
5400 "Unsupported DYN_BW_SGL");
5401 }
5402
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005403 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 3", intf);
5404 if (system(buf) != 0) {
5405 sigma_dut_print(dut, DUT_MSG_ERROR,
5406 "Failed to set cts_cbw in DYN_BW_SGNL");
5407 return 0;
5408 }
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08005409 break;
5410 case DRIVER_ATHEROS:
priyadharshini gowthamane5e25172015-12-08 14:53:48 -08005411 novap_reset(dut, intf);
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08005412 ath_config_dyn_bw_sig(dut, intf, val);
5413 break;
5414 default:
5415 sigma_dut_print(dut, DUT_MSG_ERROR,
5416 "Failed to set DYN_BW_SGNL");
5417 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005418 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005419 }
5420
5421 val = get_param(cmd, "RTS_FORCE");
5422 if (val) {
priyadharshini gowthamane5e25172015-12-08 14:53:48 -08005423 novap_reset(dut, intf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005424 if (strcasecmp(val, "Enable") == 0) {
Veerendranath Jakkamadcd6202019-04-17 12:32:21 +05305425 if (sta_set_rts(dut, intf, 64) != 0) {
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02005426 sigma_dut_print(dut, DUT_MSG_ERROR,
5427 "Failed to set RTS_FORCE 64");
5428 }
priyadharshini gowthaman270870e2015-12-09 10:10:23 -08005429 snprintf(buf, sizeof(buf),
5430 "wifitool %s beeliner_fw_test 100 1", intf);
5431 if (system(buf) != 0) {
5432 sigma_dut_print(dut, DUT_MSG_ERROR,
5433 "wifitool beeliner_fw_test 100 1 failed");
5434 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005435 } else if (strcasecmp(val, "Disable") == 0) {
Veerendranath Jakkamadcd6202019-04-17 12:32:21 +05305436 if (sta_set_rts(dut, intf, 2347) != 0) {
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02005437 sigma_dut_print(dut, DUT_MSG_ERROR,
5438 "Failed to set RTS_FORCE 2347");
5439 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005440 } else {
5441 send_resp(dut, conn, SIGMA_ERROR,
5442 "ErrorCode,RTS_FORCE value not supported");
5443 return 0;
5444 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005445 }
5446
5447 val = get_param(cmd, "CTS_WIDTH");
5448 if (val) {
5449 switch (get_driver_type()) {
5450 case DRIVER_WCN:
5451 if (wcn_sta_set_cts_width(dut, intf, val) < 0) {
5452 send_resp(dut, conn, SIGMA_ERROR,
5453 "ErrorCode,Failed to set CTS_WIDTH");
5454 return 0;
5455 }
5456 break;
5457 case DRIVER_ATHEROS:
5458 ath_set_cts_width(dut, intf, val);
5459 break;
5460 default:
5461 sigma_dut_print(dut, DUT_MSG_ERROR,
5462 "Setting CTS_WIDTH not supported");
5463 break;
5464 }
5465 }
5466
5467 val = get_param(cmd, "BW_SGNL");
5468 if (val) {
5469 if (strcasecmp(val, "Enable") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005470 run_iwpriv(dut, intf, "cwmenable 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005471 } else if (strcasecmp(val, "Disable") == 0) {
5472 /* TODO: Disable */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005473 } else {
5474 send_resp(dut, conn, SIGMA_ERROR,
5475 "ErrorCode,BW_SGNL value not supported");
5476 return 0;
5477 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005478 }
5479
5480 val = get_param(cmd, "Band");
5481 if (val) {
5482 if (strcmp(val, "2.4") == 0 || strcmp(val, "5") == 0) {
5483 /* STA supports all bands by default */
5484 } else {
5485 send_resp(dut, conn, SIGMA_ERROR,
5486 "ErrorCode,Unsupported Band");
5487 return 0;
5488 }
5489 }
5490
5491 val = get_param(cmd, "zero_crc");
5492 if (val) {
5493 switch (get_driver_type()) {
5494 case DRIVER_ATHEROS:
5495 ath_set_zero_crc(dut, val);
5496 break;
5497 default:
5498 break;
5499 }
5500 }
5501
5502 return 1;
5503}
5504
5505
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02005506static int sta_set_force_mcs(struct sigma_dut *dut, int force, int mcs)
5507{
5508 switch (get_driver_type()) {
5509#ifdef __linux__
5510 case DRIVER_WIL6210:
5511 return wil6210_set_force_mcs(dut, force, mcs);
5512#endif /* __linux__ */
5513 default:
5514 sigma_dut_print(dut, DUT_MSG_ERROR,
5515 "Unsupported sta_set_force_mcs with the current driver");
5516 return -1;
5517 }
5518}
5519
5520
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02005521static int sta_60g_force_rsn_ie(struct sigma_dut *dut, int state)
5522{
5523 switch (get_driver_type()) {
5524#ifdef __linux__
5525 case DRIVER_WIL6210:
5526 return wil6210_force_rsn_ie(dut, state);
5527#endif /* __linux__ */
5528 default:
5529 sigma_dut_print(dut, DUT_MSG_ERROR,
5530 "Unsupported sta_60g_force_rsn_ie with the current driver");
5531 return -1;
5532 }
5533}
5534
5535
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005536static int sta_set_60g_common(struct sigma_dut *dut, struct sigma_conn *conn,
5537 struct sigma_cmd *cmd)
5538{
5539 const char *val;
5540 char buf[100];
5541
5542 val = get_param(cmd, "MSDUSize");
5543 if (val) {
5544 int mtu;
5545
5546 dut->amsdu_size = atoi(val);
5547 if (dut->amsdu_size > IEEE80211_MAX_DATA_LEN_DMG ||
5548 dut->amsdu_size < IEEE80211_SNAP_LEN_DMG) {
5549 sigma_dut_print(dut, DUT_MSG_ERROR,
5550 "MSDUSize %d is above max %d or below min %d",
5551 dut->amsdu_size,
5552 IEEE80211_MAX_DATA_LEN_DMG,
5553 IEEE80211_SNAP_LEN_DMG);
5554 dut->amsdu_size = 0;
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005555 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005556 }
5557
5558 mtu = dut->amsdu_size - IEEE80211_SNAP_LEN_DMG;
5559 sigma_dut_print(dut, DUT_MSG_DEBUG,
5560 "Setting amsdu_size to %d", mtu);
5561 snprintf(buf, sizeof(buf), "ifconfig %s mtu %d",
5562 get_station_ifname(), mtu);
5563
5564 if (system(buf) != 0) {
5565 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
5566 buf);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005567 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005568 }
5569 }
5570
5571 val = get_param(cmd, "BAckRcvBuf");
5572 if (val) {
5573 dut->back_rcv_buf = atoi(val);
5574 if (dut->back_rcv_buf == 0) {
5575 sigma_dut_print(dut, DUT_MSG_ERROR,
5576 "Failed to convert %s or value is 0",
5577 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005578 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005579 }
5580
5581 sigma_dut_print(dut, DUT_MSG_DEBUG,
5582 "Setting BAckRcvBuf to %s", val);
5583 }
5584
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02005585 val = get_param(cmd, "MCS_FixedRate");
5586 if (val) {
5587 if (sta_set_force_mcs(dut, 1, atoi(val))) {
5588 sigma_dut_print(dut, DUT_MSG_ERROR,
5589 "Failed to force MCS");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005590 return ERROR_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02005591 }
5592 }
5593
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005594 return SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005595}
5596
5597
5598static int sta_pcp_start(struct sigma_dut *dut, struct sigma_conn *conn,
5599 struct sigma_cmd *cmd)
5600{
5601 int net_id;
5602 char *ifname;
5603 const char *val;
5604 char buf[100];
5605
5606 dut->mode = SIGMA_MODE_STATION;
5607 ifname = get_main_ifname();
5608 if (wpa_command(ifname, "PING") != 0) {
5609 sigma_dut_print(dut, DUT_MSG_ERROR, "Supplicant not running");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005610 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005611 }
5612
5613 wpa_command(ifname, "FLUSH");
5614 net_id = add_network_common(dut, conn, ifname, cmd);
5615 if (net_id < 0) {
5616 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add network");
5617 return net_id;
5618 }
5619
5620 /* TODO: mode=2 for the AP; in the future, replace for mode PCP */
5621 if (set_network(ifname, net_id, "mode", "2") < 0) {
5622 sigma_dut_print(dut, DUT_MSG_ERROR,
5623 "Failed to set supplicant network mode");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005624 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005625 }
5626
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02005627 if (set_network(ifname, net_id, "pbss", "1") < 0)
5628 return -2;
5629
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005630 sigma_dut_print(dut, DUT_MSG_DEBUG,
Alexei Avshalom Lazarfd9f1352018-11-13 14:07:58 +02005631 "Supplicant set network with mode 2. network_id %d",
5632 net_id);
5633
5634 if (set_network(ifname, net_id, "wps_disabled", "0") < 0) {
5635 sigma_dut_print(dut, DUT_MSG_INFO,
5636 "Failed to set supplicant to WPS ENABLE");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005637 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarfd9f1352018-11-13 14:07:58 +02005638 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005639
5640 val = get_param(cmd, "Security");
5641 if (val && strcasecmp(val, "OPEN") == 0) {
5642 dut->ap_key_mgmt = AP_OPEN;
5643 if (set_network(ifname, net_id, "key_mgmt", "NONE") < 0) {
5644 sigma_dut_print(dut, DUT_MSG_ERROR,
5645 "Failed to set supplicant to %s security",
5646 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005647 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005648 }
5649 } else if (val && strcasecmp(val, "WPA2-PSK") == 0) {
5650 dut->ap_key_mgmt = AP_WPA2_PSK;
5651 if (set_network(ifname, net_id, "key_mgmt", "WPA-PSK") < 0) {
5652 sigma_dut_print(dut, DUT_MSG_ERROR,
5653 "Failed to set supplicant to %s security",
5654 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005655 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005656 }
5657
5658 if (set_network(ifname, net_id, "proto", "RSN") < 0) {
5659 sigma_dut_print(dut, DUT_MSG_ERROR,
5660 "Failed to set supplicant to proto RSN");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005661 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005662 }
5663 } else if (val) {
5664 sigma_dut_print(dut, DUT_MSG_ERROR,
5665 "Requested Security %s is not supported on 60GHz",
5666 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005667 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005668 }
5669
5670 val = get_param(cmd, "Encrypt");
5671 if (val && strcasecmp(val, "AES-GCMP") == 0) {
5672 if (set_network(ifname, net_id, "pairwise", "GCMP") < 0) {
5673 sigma_dut_print(dut, DUT_MSG_ERROR,
5674 "Failed to set supplicant to pairwise GCMP");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005675 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005676 }
5677 if (set_network(ifname, net_id, "group", "GCMP") < 0) {
5678 sigma_dut_print(dut, DUT_MSG_ERROR,
5679 "Failed to set supplicant to group GCMP");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005680 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005681 }
5682 } else if (val) {
5683 sigma_dut_print(dut, DUT_MSG_ERROR,
5684 "Requested Encrypt %s is not supported on 60 GHz",
5685 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005686 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005687 }
5688
5689 val = get_param(cmd, "PSK");
5690 if (val && set_network_quoted(ifname, net_id, "psk", val) < 0) {
5691 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set psk %s",
5692 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005693 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005694 }
5695
5696 /* Convert 60G channel to freq */
5697 switch (dut->ap_channel) {
5698 case 1:
5699 val = "58320";
5700 break;
5701 case 2:
5702 val = "60480";
5703 break;
5704 case 3:
5705 val = "62640";
5706 break;
5707 default:
5708 sigma_dut_print(dut, DUT_MSG_ERROR,
5709 "Failed to configure channel %d. Not supported",
5710 dut->ap_channel);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005711 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005712 }
5713
5714 if (set_network(ifname, net_id, "frequency", val) < 0) {
5715 sigma_dut_print(dut, DUT_MSG_ERROR,
5716 "Failed to set supplicant network frequency");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005717 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005718 }
5719
Alexei Avshalom Lazar2eccf4d2019-01-31 10:03:59 +02005720 if (dut->eap_fragment) {
5721 sigma_dut_print(dut, DUT_MSG_DEBUG,
5722 "Set EAP fragment size to 128 bytes.");
5723 if (set_network(ifname, net_id, "fragment_size", "128") < 0)
5724 return ERROR_SEND_STATUS;
5725 }
5726
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005727 sigma_dut_print(dut, DUT_MSG_DEBUG,
5728 "Supplicant set network with frequency");
5729
5730 snprintf(buf, sizeof(buf), "SELECT_NETWORK %d", net_id);
5731 if (wpa_command(ifname, buf) < 0) {
5732 sigma_dut_print(dut, DUT_MSG_INFO,
5733 "Failed to select network id %d on %s",
5734 net_id, ifname);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005735 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005736 }
5737
5738 sigma_dut_print(dut, DUT_MSG_DEBUG, "Selected network");
5739
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005740 return SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005741}
5742
5743
Lior David67543f52017-01-03 19:04:22 +02005744static int wil6210_set_abft_len(struct sigma_dut *dut, int abft_len)
5745{
5746 char buf[128], fname[128];
5747 FILE *f;
5748
5749 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
5750 sigma_dut_print(dut, DUT_MSG_ERROR,
5751 "failed to get wil6210 debugfs dir");
5752 return -1;
5753 }
5754
5755 snprintf(fname, sizeof(fname), "%s/abft_len", buf);
5756 f = fopen(fname, "w");
5757 if (!f) {
5758 sigma_dut_print(dut, DUT_MSG_ERROR,
5759 "failed to open: %s", fname);
5760 return -1;
5761 }
5762
5763 fprintf(f, "%d\n", abft_len);
5764 fclose(f);
5765
5766 return 0;
5767}
5768
5769
Alexei Avshalom Lazar49498b82019-01-31 15:16:32 +02005770int sta_set_60g_abft_len(struct sigma_dut *dut, struct sigma_conn *conn,
5771 int abft_len)
Lior David67543f52017-01-03 19:04:22 +02005772{
5773 switch (get_driver_type()) {
5774 case DRIVER_WIL6210:
5775 return wil6210_set_abft_len(dut, abft_len);
5776 default:
5777 sigma_dut_print(dut, DUT_MSG_ERROR,
5778 "set abft_len not supported");
5779 return -1;
5780 }
5781}
5782
5783
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005784static int sta_set_60g_pcp(struct sigma_dut *dut, struct sigma_conn *conn,
5785 struct sigma_cmd *cmd)
5786{
5787 const char *val;
Lior David67543f52017-01-03 19:04:22 +02005788 unsigned int abft_len = 1; /* default is one slot */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005789
5790 if (dut->dev_role != DEVROLE_PCP) {
5791 send_resp(dut, conn, SIGMA_INVALID,
5792 "ErrorCode,Invalid DevRole");
5793 return 0;
5794 }
5795
5796 val = get_param(cmd, "SSID");
5797 if (val) {
5798 if (strlen(val) > sizeof(dut->ap_ssid) - 1) {
5799 send_resp(dut, conn, SIGMA_INVALID,
5800 "ErrorCode,Invalid SSID");
5801 return -1;
5802 }
5803
Peng Xub8fc5cc2017-05-10 17:27:28 -07005804 strlcpy(dut->ap_ssid, val, sizeof(dut->ap_ssid));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005805 }
5806
5807 val = get_param(cmd, "CHANNEL");
5808 if (val) {
5809 const char *pos;
5810
5811 dut->ap_channel = atoi(val);
5812 pos = strchr(val, ';');
5813 if (pos) {
5814 pos++;
5815 dut->ap_channel_1 = atoi(pos);
5816 }
5817 }
5818
5819 switch (dut->ap_channel) {
5820 case 1:
5821 case 2:
5822 case 3:
5823 break;
5824 default:
5825 sigma_dut_print(dut, DUT_MSG_ERROR,
5826 "Channel %d is not supported", dut->ap_channel);
5827 send_resp(dut, conn, SIGMA_ERROR,
5828 "Requested channel is not supported");
5829 return -1;
5830 }
5831
5832 val = get_param(cmd, "BCNINT");
5833 if (val)
5834 dut->ap_bcnint = atoi(val);
5835
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005836 val = get_param(cmd, "AllocType");
5837 if (val) {
5838 send_resp(dut, conn, SIGMA_ERROR,
5839 "ErrorCode,AllocType is not supported yet");
5840 return -1;
5841 }
5842
5843 val = get_param(cmd, "PercentBI");
5844 if (val) {
5845 send_resp(dut, conn, SIGMA_ERROR,
5846 "ErrorCode,PercentBI is not supported yet");
5847 return -1;
5848 }
5849
5850 val = get_param(cmd, "CBAPOnly");
5851 if (val) {
5852 send_resp(dut, conn, SIGMA_ERROR,
5853 "ErrorCode,CBAPOnly is not supported yet");
5854 return -1;
5855 }
5856
5857 val = get_param(cmd, "AMPDU");
5858 if (val) {
5859 if (strcasecmp(val, "Enable") == 0)
5860 dut->ap_ampdu = 1;
5861 else if (strcasecmp(val, "Disable") == 0)
5862 dut->ap_ampdu = 2;
5863 else {
5864 send_resp(dut, conn, SIGMA_ERROR,
5865 "ErrorCode,AMPDU value is not Enable nor Disabled");
5866 return -1;
5867 }
5868 }
5869
5870 val = get_param(cmd, "AMSDU");
5871 if (val) {
5872 if (strcasecmp(val, "Enable") == 0)
5873 dut->ap_amsdu = 1;
5874 else if (strcasecmp(val, "Disable") == 0)
5875 dut->ap_amsdu = 2;
5876 }
5877
5878 val = get_param(cmd, "NumMSDU");
5879 if (val) {
5880 send_resp(dut, conn, SIGMA_ERROR,
5881 "ErrorCode, NumMSDU is not supported yet");
5882 return -1;
5883 }
5884
5885 val = get_param(cmd, "ABFTLRang");
5886 if (val) {
5887 sigma_dut_print(dut, DUT_MSG_DEBUG,
Lior David67543f52017-01-03 19:04:22 +02005888 "ABFTLRang parameter %s", val);
5889 if (strcmp(val, "Gt1") == 0)
5890 abft_len = 2; /* 2 slots in this case */
5891 }
5892
5893 if (sta_set_60g_abft_len(dut, conn, abft_len)) {
5894 send_resp(dut, conn, SIGMA_ERROR,
5895 "ErrorCode, Can't set ABFT length");
5896 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005897 }
5898
5899 if (sta_pcp_start(dut, conn, cmd) < 0) {
5900 send_resp(dut, conn, SIGMA_ERROR,
5901 "ErrorCode, Can't start PCP role");
5902 return -1;
5903 }
5904
5905 return sta_set_60g_common(dut, conn, cmd);
5906}
5907
5908
5909static int sta_set_60g_sta(struct sigma_dut *dut, struct sigma_conn *conn,
5910 struct sigma_cmd *cmd)
5911{
5912 const char *val = get_param(cmd, "DiscoveryMode");
5913
5914 if (dut->dev_role != DEVROLE_STA) {
5915 send_resp(dut, conn, SIGMA_INVALID,
5916 "ErrorCode,Invalid DevRole");
5917 return 0;
5918 }
5919
5920 if (val) {
5921 sigma_dut_print(dut, DUT_MSG_DEBUG, "Discovery: %s", val);
5922 /* Ignore Discovery mode till Driver expose API. */
5923#if 0
5924 if (strcasecmp(val, "1") == 0) {
5925 send_resp(dut, conn, SIGMA_INVALID,
5926 "ErrorCode,DiscoveryMode 1 not supported");
5927 return 0;
5928 }
5929
5930 if (strcasecmp(val, "0") == 0) {
5931 /* OK */
5932 } else {
5933 send_resp(dut, conn, SIGMA_INVALID,
5934 "ErrorCode,DiscoveryMode not supported");
5935 return 0;
5936 }
5937#endif
5938 }
5939
5940 if (start_sta_mode(dut) != 0)
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005941 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005942 return sta_set_60g_common(dut, conn, cmd);
5943}
5944
5945
5946static int cmd_sta_disconnect(struct sigma_dut *dut, struct sigma_conn *conn,
5947 struct sigma_cmd *cmd)
5948{
5949 const char *intf = get_param(cmd, "Interface");
Jouni Malinened77e672018-01-10 16:45:13 +02005950 const char *val = get_param(cmd, "maintain_profile");
vamsi krishnad605c422017-09-20 14:56:31 +05305951
Jouni Malinened77e672018-01-10 16:45:13 +02005952 if (dut->program == PROGRAM_OCE ||
Amarnath Hullur Subramanyamebeda9e2018-01-31 03:21:48 -08005953 dut->program == PROGRAM_HE ||
Jouni Malinened77e672018-01-10 16:45:13 +02005954 (val && atoi(val) == 1)) {
vamsi krishnad605c422017-09-20 14:56:31 +05305955 wpa_command(intf, "DISCONNECT");
5956 return 1;
5957 }
5958
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005959 disconnect_station(dut);
5960 /* Try to ignore old scan results to avoid HS 2.0R2 test case failures
5961 * due to cached results. */
5962 wpa_command(intf, "SET ignore_old_scan_res 1");
5963 wpa_command(intf, "BSS_FLUSH");
5964 return 1;
5965}
5966
5967
5968static int cmd_sta_reassoc(struct sigma_dut *dut, struct sigma_conn *conn,
5969 struct sigma_cmd *cmd)
5970{
5971 const char *intf = get_param(cmd, "Interface");
5972 const char *bssid = get_param(cmd, "bssid");
5973 const char *val = get_param(cmd, "CHANNEL");
5974 struct wpa_ctrl *ctrl;
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05305975 char buf[1000];
Sunil Duttd30ce092018-01-11 23:56:29 +05305976 char result[32];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005977 int res;
5978 int chan = 0;
Ashwini Patil467efef2017-05-25 12:18:27 +05305979 int status = 0;
Sunil Duttd30ce092018-01-11 23:56:29 +05305980 int fastreassoc = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005981
5982 if (bssid == NULL) {
5983 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing bssid "
5984 "argument");
5985 return 0;
5986 }
5987
5988 if (val)
5989 chan = atoi(val);
5990
5991 if (wifi_chip_type != DRIVER_WCN && wifi_chip_type != DRIVER_AR6003) {
5992 /* The current network may be from sta_associate or
5993 * sta_hs2_associate
5994 */
5995 if (set_network(intf, dut->infra_network_id, "bssid", bssid) <
5996 0 ||
5997 set_network(intf, 0, "bssid", bssid) < 0)
5998 return -2;
5999 }
6000
6001 ctrl = open_wpa_mon(intf);
6002 if (ctrl == NULL) {
6003 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
6004 "wpa_supplicant monitor connection");
6005 return -1;
6006 }
6007
Sunil Duttd30ce092018-01-11 23:56:29 +05306008 if (get_wpa_status(get_station_ifname(), "wpa_state", result,
6009 sizeof(result)) < 0 ||
6010 strncmp(result, "COMPLETED", 9) != 0) {
6011 sigma_dut_print(dut, DUT_MSG_DEBUG,
6012 "sta_reassoc: Not connected");
6013 fastreassoc = 0;
6014 }
6015
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05306016 if (dut->rsne_override) {
6017#ifdef NL80211_SUPPORT
6018 if (get_driver_type() == DRIVER_WCN && dut->config_rsnie == 0) {
6019 sta_config_rsnie(dut, 1);
6020 dut->config_rsnie = 1;
6021 }
6022#endif /* NL80211_SUPPORT */
6023 snprintf(buf, sizeof(buf), "TEST_ASSOC_IE %s",
6024 dut->rsne_override);
6025 if (wpa_command(intf, buf) < 0) {
6026 send_resp(dut, conn, SIGMA_ERROR,
6027 "ErrorCode,Failed to set DEV_CONFIGURE_IE RSNE override");
6028 return 0;
6029 }
6030 }
6031
Sunil Duttd30ce092018-01-11 23:56:29 +05306032 if (wifi_chip_type == DRIVER_WCN && fastreassoc) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006033#ifdef ANDROID
Ashwini Patil4c8158f2017-05-25 12:49:21 +05306034 if (chan) {
6035 unsigned int freq;
6036
Alexei Avshalom Lazar093569f2018-11-13 14:08:17 +02006037 freq = channel_to_freq(dut, chan);
Ashwini Patil4c8158f2017-05-25 12:49:21 +05306038 if (!freq) {
6039 sigma_dut_print(dut, DUT_MSG_ERROR,
6040 "Invalid channel number provided: %d",
6041 chan);
6042 send_resp(dut, conn, SIGMA_INVALID,
6043 "ErrorCode,Invalid channel number");
6044 goto close_mon_conn;
6045 }
6046 res = snprintf(buf, sizeof(buf),
6047 "SCAN TYPE=ONLY freq=%d", freq);
6048 } else {
6049 res = snprintf(buf, sizeof(buf), "SCAN TYPE=ONLY");
6050 }
6051 if (res < 0 || res >= (int) sizeof(buf)) {
6052 send_resp(dut, conn, SIGMA_ERROR,
6053 "ErrorCode,snprintf failed");
6054 goto close_mon_conn;
6055 }
6056 if (wpa_command(intf, buf) < 0) {
6057 sigma_dut_print(dut, DUT_MSG_INFO,
6058 "Failed to start scan");
6059 send_resp(dut, conn, SIGMA_ERROR,
6060 "ErrorCode,scan failed");
6061 goto close_mon_conn;
6062 }
6063
6064 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
6065 buf, sizeof(buf));
6066 if (res < 0) {
6067 sigma_dut_print(dut, DUT_MSG_INFO,
6068 "Scan did not complete");
6069 send_resp(dut, conn, SIGMA_ERROR,
6070 "ErrorCode,scan did not complete");
6071 goto close_mon_conn;
6072 }
6073
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006074 if (set_network(intf, dut->infra_network_id, "bssid", "any")
6075 < 0) {
6076 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
6077 "bssid to any during FASTREASSOC");
Ashwini Patil467efef2017-05-25 12:18:27 +05306078 status = -2;
6079 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006080 }
6081 res = snprintf(buf, sizeof(buf), "DRIVER FASTREASSOC %s %d",
6082 bssid, chan);
6083 if (res > 0 && res < (int) sizeof(buf))
6084 res = wpa_command(intf, buf);
6085
6086 if (res < 0 || res >= (int) sizeof(buf)) {
6087 send_resp(dut, conn, SIGMA_ERROR,
6088 "errorCode,Failed to run DRIVER FASTREASSOC");
Ashwini Patil467efef2017-05-25 12:18:27 +05306089 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006090 }
6091#else /* ANDROID */
6092 sigma_dut_print(dut, DUT_MSG_DEBUG,
6093 "Reassoc using iwpriv - skip chan=%d info",
6094 chan);
6095 snprintf(buf, sizeof(buf), "iwpriv %s reassoc", intf);
6096 if (system(buf) != 0) {
6097 sigma_dut_print(dut, DUT_MSG_ERROR, "%s failed", buf);
Ashwini Patil467efef2017-05-25 12:18:27 +05306098 status = -2;
6099 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006100 }
6101#endif /* ANDROID */
6102 sigma_dut_print(dut, DUT_MSG_INFO,
6103 "sta_reassoc: Run %s successful", buf);
6104 } else if (wpa_command(intf, "REASSOCIATE")) {
6105 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
6106 "request reassociation");
Ashwini Patil467efef2017-05-25 12:18:27 +05306107 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006108 }
6109
6110 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
6111 buf, sizeof(buf));
Ashwini Patil467efef2017-05-25 12:18:27 +05306112 if (res < 0) {
6113 sigma_dut_print(dut, DUT_MSG_INFO, "Connection did not complete");
6114 status = -1;
6115 goto close_mon_conn;
6116 }
6117 status = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006118
Ashwini Patil467efef2017-05-25 12:18:27 +05306119close_mon_conn:
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006120 wpa_ctrl_detach(ctrl);
6121 wpa_ctrl_close(ctrl);
Ashwini Patil467efef2017-05-25 12:18:27 +05306122 return status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006123}
6124
6125
6126static void hs2_clear_credentials(const char *intf)
6127{
6128 wpa_command(intf, "REMOVE_CRED all");
6129}
6130
6131
Lior Davidcc88b562017-01-03 18:52:09 +02006132#ifdef __linux__
6133static int wil6210_get_aid(struct sigma_dut *dut, const char *bssid,
6134 unsigned int *aid)
6135{
Lior David0fe101e2017-03-09 16:09:50 +02006136 const char *pattern = "AID[ \t]+([0-9]+)";
Lior Davidcc88b562017-01-03 18:52:09 +02006137
Lior David0fe101e2017-03-09 16:09:50 +02006138 return wil6210_get_sta_info_field(dut, bssid, pattern, aid);
Lior Davidcc88b562017-01-03 18:52:09 +02006139}
6140#endif /* __linux__ */
6141
6142
6143static int sta_get_aid_60g(struct sigma_dut *dut, const char *bssid,
6144 unsigned int *aid)
6145{
6146 switch (get_driver_type()) {
6147#ifdef __linux__
6148 case DRIVER_WIL6210:
6149 return wil6210_get_aid(dut, bssid, aid);
6150#endif /* __linux__ */
6151 default:
6152 sigma_dut_print(dut, DUT_MSG_ERROR, "get AID not supported");
6153 return -1;
6154 }
6155}
6156
6157
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006158static int sta_get_parameter_60g(struct sigma_dut *dut, struct sigma_conn *conn,
6159 struct sigma_cmd *cmd)
6160{
6161 char buf[MAX_CMD_LEN];
6162 char bss_list[MAX_CMD_LEN];
6163 const char *parameter = get_param(cmd, "Parameter");
6164
6165 if (parameter == NULL)
6166 return -1;
6167
Lior Davidcc88b562017-01-03 18:52:09 +02006168 if (strcasecmp(parameter, "AID") == 0) {
6169 unsigned int aid = 0;
6170 char bssid[20];
6171
6172 if (get_wpa_status(get_station_ifname(), "bssid",
6173 bssid, sizeof(bssid)) < 0) {
6174 sigma_dut_print(dut, DUT_MSG_ERROR,
6175 "could not get bssid");
6176 return -2;
6177 }
6178
6179 if (sta_get_aid_60g(dut, bssid, &aid))
6180 return -2;
6181
6182 snprintf(buf, sizeof(buf), "aid,%d", aid);
6183 sigma_dut_print(dut, DUT_MSG_INFO, "%s", buf);
6184 send_resp(dut, conn, SIGMA_COMPLETE, buf);
6185 return 0;
6186 }
6187
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006188 if (strcasecmp(parameter, "DiscoveredDevList") == 0) {
6189 char *bss_line;
6190 char *bss_id = NULL;
6191 const char *ifname = get_param(cmd, "Interface");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05306192 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006193
6194 if (ifname == NULL) {
6195 sigma_dut_print(dut, DUT_MSG_INFO,
6196 "For get DiscoveredDevList need Interface name.");
6197 return -1;
6198 }
6199
6200 /*
6201 * Use "BSS RANGE=ALL MASK=0x2" which provides a list
6202 * of BSSIDs in "bssid=<BSSID>\n"
6203 */
6204 if (wpa_command_resp(ifname, "BSS RANGE=ALL MASK=0x2",
6205 bss_list,
6206 sizeof(bss_list)) < 0) {
6207 sigma_dut_print(dut, DUT_MSG_ERROR,
6208 "Failed to get bss list");
6209 return -1;
6210 }
6211
6212 sigma_dut_print(dut, DUT_MSG_DEBUG,
6213 "bss list for ifname:%s is:%s",
6214 ifname, bss_list);
6215
6216 snprintf(buf, sizeof(buf), "DeviceList");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05306217 bss_line = strtok_r(bss_list, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006218 while (bss_line) {
6219 if (sscanf(bss_line, "bssid=%ms", &bss_id) > 0 &&
6220 bss_id) {
6221 int len;
6222
6223 len = snprintf(buf + strlen(buf),
6224 sizeof(buf) - strlen(buf),
6225 ",%s", bss_id);
6226 free(bss_id);
6227 bss_id = NULL;
6228 if (len < 0) {
6229 sigma_dut_print(dut,
6230 DUT_MSG_ERROR,
6231 "Failed to read BSSID");
6232 send_resp(dut, conn, SIGMA_ERROR,
6233 "ErrorCode,Failed to read BSS ID");
6234 return 0;
6235 }
6236
6237 if ((size_t) len >= sizeof(buf) - strlen(buf)) {
6238 sigma_dut_print(dut,
6239 DUT_MSG_ERROR,
6240 "Response buf too small for list");
6241 send_resp(dut, conn,
6242 SIGMA_ERROR,
6243 "ErrorCode,Response buf too small for list");
6244 return 0;
6245 }
6246 }
6247
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05306248 bss_line = strtok_r(NULL, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006249 }
6250
6251 sigma_dut_print(dut, DUT_MSG_INFO, "DiscoveredDevList is %s",
6252 buf);
6253 send_resp(dut, conn, SIGMA_COMPLETE, buf);
6254 return 0;
6255 }
6256
6257 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
6258 return 0;
6259}
6260
6261
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07006262static int sta_get_parameter_he(struct sigma_dut *dut, struct sigma_conn *conn,
6263 struct sigma_cmd *cmd)
6264{
6265 char buf[MAX_CMD_LEN];
6266 const char *parameter = get_param(cmd, "Parameter");
6267
6268 if (!parameter)
6269 return -1;
6270
6271 if (strcasecmp(parameter, "RSSI") == 0) {
6272 char rssi[10];
6273
6274 if (get_wpa_signal_poll(dut, get_station_ifname(), "RSSI",
6275 rssi, sizeof(rssi)) < 0) {
6276 sigma_dut_print(dut, DUT_MSG_ERROR,
6277 "Could not get RSSI");
6278 return -2;
6279 }
6280
6281 snprintf(buf, sizeof(buf), "rssi,%s", rssi);
6282 sigma_dut_print(dut, DUT_MSG_INFO, "RSSI %s", buf);
6283 send_resp(dut, conn, SIGMA_COMPLETE, buf);
6284 return 0;
6285 }
6286
6287 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
6288 return 0;
6289}
6290
6291
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006292static int cmd_sta_get_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
6293 struct sigma_cmd *cmd)
6294{
6295 const char *program = get_param(cmd, "Program");
6296
6297 if (program == NULL)
6298 return -1;
6299
6300 if (strcasecmp(program, "P2PNFC") == 0)
6301 return p2p_cmd_sta_get_parameter(dut, conn, cmd);
6302
6303 if (strcasecmp(program, "60ghz") == 0)
6304 return sta_get_parameter_60g(dut, conn, cmd);
6305
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07006306 if (strcasecmp(program, "he") == 0)
6307 return sta_get_parameter_he(dut, conn, cmd);
6308
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006309#ifdef ANDROID_NAN
6310 if (strcasecmp(program, "NAN") == 0)
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07006311 return nan_cmd_sta_get_parameter(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006312#endif /* ANDROID_NAN */
6313
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07006314#ifdef MIRACAST
6315 if (strcasecmp(program, "WFD") == 0 ||
6316 strcasecmp(program, "DisplayR2") == 0)
6317 return miracast_cmd_sta_get_parameter(dut, conn, cmd);
6318#endif /* MIRACAST */
6319
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006320 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
6321 return 0;
6322}
6323
6324
6325static void sta_reset_default_ath(struct sigma_dut *dut, const char *intf,
6326 const char *type)
6327{
6328 char buf[100];
6329
6330 if (dut->program == PROGRAM_VHT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006331 run_iwpriv(dut, intf, "chwidth 2");
6332 run_iwpriv(dut, intf, "mode 11ACVHT80");
6333 run_iwpriv(dut, intf, "vhtmcs -1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006334 }
6335
6336 if (dut->program == PROGRAM_HT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006337 run_iwpriv(dut, intf, "chwidth 0");
6338 run_iwpriv(dut, intf, "mode 11naht40");
6339 run_iwpriv(dut, intf, "set11NRates 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006340 }
6341
6342 if (dut->program == PROGRAM_VHT || dut->program == PROGRAM_HT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006343 run_iwpriv(dut, intf, "powersave 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006344
6345 /* Reset CTS width */
6346 snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 54 0",
6347 intf);
6348 if (system(buf) != 0) {
6349 sigma_dut_print(dut, DUT_MSG_ERROR,
6350 "wifitool %s beeliner_fw_test 54 0 failed",
6351 intf);
6352 }
6353
6354 /* Enable Dynamic Bandwidth signalling by default */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006355 run_iwpriv(dut, intf, "cwmenable 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006356
6357 snprintf(buf, sizeof(buf), "iwconfig %s rts 2347", intf);
6358 if (system(buf) != 0) {
6359 sigma_dut_print(dut, DUT_MSG_ERROR,
6360 "iwpriv rts failed");
6361 }
6362 }
6363
6364 if (type && strcasecmp(type, "Testbed") == 0) {
6365 dut->testbed_flag_txsp = 1;
6366 dut->testbed_flag_rxsp = 1;
6367 /* STA has to set spatial stream to 2 per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006368 run_iwpriv(dut, intf, "vht_mcsmap 0xfff0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006369
6370 /* Disable LDPC per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006371 run_iwpriv(dut, intf, "ldpc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006372
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006373 run_iwpriv(dut, intf, "amsdu 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006374
6375 /* TODO: Disable STBC 2x1 transmit and receive */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006376 run_iwpriv(dut, intf, "tx_stbc 0");
6377 run_iwpriv(dut, intf, "rx_stbc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006378
6379 /* STA has to disable Short GI per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006380 run_iwpriv(dut, intf, "shortgi 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006381 }
6382
6383 if (type && strcasecmp(type, "DUT") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006384 run_iwpriv(dut, intf, "nss 3");
Arif Hussainac6c5112018-05-25 17:34:00 -07006385 dut->sta_nss = 3;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006386
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006387 run_iwpriv(dut, intf, "shortgi 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006388 }
6389}
6390
6391
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08006392#ifdef NL80211_SUPPORT
6393static int sta_set_he_mcs(struct sigma_dut *dut, const char *intf,
6394 enum he_mcs_config mcs)
6395{
6396 struct nl_msg *msg;
6397 int ret = 0;
6398 struct nlattr *params;
6399 int ifindex;
6400
6401 ifindex = if_nametoindex(intf);
6402 if (ifindex == 0) {
6403 sigma_dut_print(dut, DUT_MSG_ERROR,
6404 "%s: Index for interface %s failed",
6405 __func__, intf);
6406 return -1;
6407 }
6408
6409 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6410 NL80211_CMD_VENDOR)) ||
6411 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6412 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6413 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6414 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6415 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6416 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MCS,
6417 mcs)) {
6418 sigma_dut_print(dut, DUT_MSG_ERROR,
6419 "%s: err in adding vendor_cmd and vendor_data",
6420 __func__);
6421 nlmsg_free(msg);
6422 return -1;
6423 }
6424 nla_nest_end(msg, params);
6425
6426 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6427 if (ret) {
6428 sigma_dut_print(dut, DUT_MSG_ERROR,
6429 "%s: err in send_and_recv_msgs, ret=%d",
6430 __func__, ret);
6431 }
6432 return ret;
6433}
6434#endif /* NL80211_SUPPORT */
6435
6436
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07006437static int sta_set_action_tx_in_he_tb_ppdu(struct sigma_dut *dut,
6438 const char *intf, int enable)
6439{
6440#ifdef NL80211_SUPPORT
6441 struct nl_msg *msg;
6442 int ret = 0;
6443 struct nlattr *params;
6444 int ifindex;
6445
6446 ifindex = if_nametoindex(intf);
6447 if (ifindex == 0) {
6448 sigma_dut_print(dut, DUT_MSG_ERROR,
6449 "%s: Index for interface %s failed",
6450 __func__, intf);
6451 return -1;
6452 }
6453
6454 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6455 NL80211_CMD_VENDOR)) ||
6456 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6457 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6458 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6459 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6460 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6461 nla_put_u8(msg,
6462 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_ACTION_TX_TB_PPDU,
6463 enable)) {
6464 sigma_dut_print(dut, DUT_MSG_ERROR,
6465 "%s: err in adding vendor_cmd and vendor_data",
6466 __func__);
6467 nlmsg_free(msg);
6468 return -1;
6469 }
6470 nla_nest_end(msg, params);
6471
6472 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6473 if (ret) {
6474 sigma_dut_print(dut, DUT_MSG_ERROR,
6475 "%s: err in send_and_recv_msgs, ret=%d",
6476 __func__, ret);
6477 }
6478 return ret;
6479#else /* NL80211_SUPPORT */
6480 sigma_dut_print(dut, DUT_MSG_ERROR,
6481 "HE action Tx TB PPDU cannot be set without NL80211_SUPPORT defined");
6482 return -1;
6483#endif /* NL80211_SUPPORT */
6484}
6485
6486
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08006487static int sta_set_heconfig_and_wep_tkip(struct sigma_dut *dut,
6488 const char *intf, int enable)
6489{
6490#ifdef NL80211_SUPPORT
6491 struct nl_msg *msg;
6492 int ret = 0;
6493 struct nlattr *params;
6494 int ifindex;
6495
6496 ifindex = if_nametoindex(intf);
6497 if (ifindex == 0) {
6498 sigma_dut_print(dut, DUT_MSG_ERROR,
6499 "%s: Index for interface %s failed",
6500 __func__, intf);
6501 return -1;
6502 }
6503
6504 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6505 NL80211_CMD_VENDOR)) ||
6506 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6507 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6508 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6509 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6510 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6511 nla_put_u8(msg,
6512 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WEP_TKIP_IN_HE,
6513 enable)) {
6514 sigma_dut_print(dut, DUT_MSG_ERROR,
6515 "%s: err in adding vendor_cmd and vendor_data",
6516 __func__);
6517 nlmsg_free(msg);
6518 return -1;
6519 }
6520 nla_nest_end(msg, params);
6521
6522 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6523 if (ret) {
6524 sigma_dut_print(dut, DUT_MSG_ERROR,
6525 "%s: err in send_and_recv_msgs, ret=%d",
6526 __func__, ret);
6527 }
6528 return ret;
6529#else /* NL80211_SUPPORT */
6530 sigma_dut_print(dut, DUT_MSG_ERROR,
6531 "HE config enablement cannot be changed without NL80211_SUPPORT defined");
6532 return -1;
6533#endif /* NL80211_SUPPORT */
6534}
6535
6536
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08006537#ifdef NL80211_SUPPORT
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08006538
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08006539static int sta_set_he_testbed_def(struct sigma_dut *dut,
6540 const char *intf, int cfg)
6541{
6542 struct nl_msg *msg;
6543 int ret = 0;
6544 struct nlattr *params;
6545 int ifindex;
6546
6547 ifindex = if_nametoindex(intf);
6548 if (ifindex == 0) {
6549 sigma_dut_print(dut, DUT_MSG_ERROR,
6550 "%s: Index for interface %s failed",
6551 __func__, intf);
6552 return -1;
6553 }
6554
6555 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6556 NL80211_CMD_VENDOR)) ||
6557 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6558 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6559 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6560 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6561 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6562 nla_put_u8(msg,
6563 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_SET_HE_TESTBED_DEFAULTS,
6564 cfg)) {
6565 sigma_dut_print(dut, DUT_MSG_ERROR,
6566 "%s: err in adding vendor_cmd and vendor_data",
6567 __func__);
6568 nlmsg_free(msg);
6569 return -1;
6570 }
6571 nla_nest_end(msg, params);
6572
6573 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6574 if (ret) {
6575 sigma_dut_print(dut, DUT_MSG_ERROR,
6576 "%s: err in send_and_recv_msgs, ret=%d",
6577 __func__, ret);
6578 }
6579 return ret;
6580}
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08006581
6582
6583static int sta_set_2g_vht_supp(struct sigma_dut *dut, const char *intf, int cfg)
6584{
6585 struct nl_msg *msg;
6586 int ret = 0;
6587 struct nlattr *params;
6588 int ifindex;
6589
6590 ifindex = if_nametoindex(intf);
6591 if (ifindex == 0) {
6592 sigma_dut_print(dut, DUT_MSG_ERROR,
6593 "%s: Index for interface %s failed",
6594 __func__, intf);
6595 return -1;
6596 }
6597
6598 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6599 NL80211_CMD_VENDOR)) ||
6600 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6601 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6602 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6603 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6604 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6605 nla_put_u8(msg,
6606 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_2G_VHT,
6607 cfg)) {
6608 sigma_dut_print(dut, DUT_MSG_ERROR,
6609 "%s: err in adding vendor_cmd and vendor_data",
6610 __func__);
6611 nlmsg_free(msg);
6612 return -1;
6613 }
6614 nla_nest_end(msg, params);
6615
6616 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6617 if (ret) {
6618 sigma_dut_print(dut, DUT_MSG_ERROR,
6619 "%s: err in send_and_recv_msgs, ret=%d",
6620 __func__, ret);
6621 }
6622 return ret;
6623}
6624
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08006625#endif /* NL80211_SUPPORT */
6626
6627
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08006628static int sta_set_addba_buf_size(struct sigma_dut *dut,
6629 const char *intf, int bufsize)
6630{
6631#ifdef NL80211_SUPPORT
6632 struct nl_msg *msg;
6633 int ret = 0;
6634 struct nlattr *params;
6635 int ifindex;
6636
6637 ifindex = if_nametoindex(intf);
6638 if (ifindex == 0) {
6639 sigma_dut_print(dut, DUT_MSG_ERROR,
6640 "%s: Index for interface %s failed",
6641 __func__, intf);
6642 return -1;
6643 }
6644
6645 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6646 NL80211_CMD_VENDOR)) ||
6647 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6648 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6649 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6650 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6651 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
Kiran Kumar Lokere26e27582018-08-01 16:18:34 -07006652 nla_put_u16(msg,
6653 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE,
6654 bufsize)) {
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08006655 sigma_dut_print(dut, DUT_MSG_ERROR,
6656 "%s: err in adding vendor_cmd and vendor_data",
6657 __func__);
6658 nlmsg_free(msg);
6659 return -1;
6660 }
6661 nla_nest_end(msg, params);
6662
6663 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6664 if (ret) {
6665 sigma_dut_print(dut, DUT_MSG_ERROR,
6666 "%s: err in send_and_recv_msgs, ret=%d",
6667 __func__, ret);
6668 }
6669 return ret;
6670#else /* NL80211_SUPPORT */
6671 sigma_dut_print(dut, DUT_MSG_ERROR,
6672 "AddBA bufsize cannot be changed without NL80211_SUPPORT defined");
6673 return -1;
6674#endif /* NL80211_SUPPORT */
6675}
6676
6677
Arif Hussain8d5b27b2018-05-14 14:31:03 -07006678static int sta_set_tx_beamformee(struct sigma_dut *dut, const char *intf,
6679 int enable)
6680{
6681#ifdef NL80211_SUPPORT
6682 struct nl_msg *msg;
6683 int ret = 0;
6684 struct nlattr *params;
6685 int ifindex;
6686
6687 ifindex = if_nametoindex(intf);
6688 if (ifindex == 0) {
6689 sigma_dut_print(dut, DUT_MSG_ERROR,
6690 "%s: Index for interface %s failed",
6691 __func__, intf);
6692 return -1;
6693 }
6694
6695 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6696 NL80211_CMD_VENDOR)) ||
6697 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6698 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6699 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6700 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6701 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6702 nla_put_u8(msg,
6703 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_TX_BEAMFORMEE,
6704 enable)) {
6705 sigma_dut_print(dut, DUT_MSG_ERROR,
6706 "%s: err in adding vendor_cmd and vendor_data",
6707 __func__);
6708 nlmsg_free(msg);
6709 return -1;
6710 }
6711 nla_nest_end(msg, params);
6712
6713 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6714 if (ret) {
6715 sigma_dut_print(dut, DUT_MSG_ERROR,
6716 "%s: err in send_and_recv_msgs, ret=%d",
6717 __func__, ret);
6718 }
6719 return ret;
6720#else /* NL80211_SUPPORT */
6721 sigma_dut_print(dut, DUT_MSG_ERROR,
6722 "tx beamformee cannot be changed without NL80211_SUPPORT defined");
6723 return -1;
6724#endif /* NL80211_SUPPORT */
6725}
6726
6727
Arif Hussain9765f7d2018-07-03 08:28:26 -07006728static int sta_set_beamformee_sts(struct sigma_dut *dut, const char *intf,
6729 int val)
6730{
6731#ifdef NL80211_SUPPORT
6732 struct nl_msg *msg;
6733 int ret = 0;
6734 struct nlattr *params;
6735 int ifindex;
6736
6737 ifindex = if_nametoindex(intf);
6738 if (ifindex == 0) {
6739 sigma_dut_print(dut, DUT_MSG_ERROR,
6740 "%s: Index for interface %s failed, val:%d",
6741 __func__, intf, val);
6742 return -1;
6743 }
6744
6745 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6746 NL80211_CMD_VENDOR)) ||
6747 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6748 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6749 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6750 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6751 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6752 nla_put_u8(msg,
6753 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_BEAMFORMEE_NSTS,
6754 val)) {
6755 sigma_dut_print(dut, DUT_MSG_ERROR,
6756 "%s: err in adding vendor_cmd and vendor_data, val: %d",
6757 __func__, val);
6758 nlmsg_free(msg);
6759 return -1;
6760 }
6761 nla_nest_end(msg, params);
6762
6763 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6764 if (ret) {
6765 sigma_dut_print(dut, DUT_MSG_ERROR,
6766 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
6767 __func__, ret, val);
6768 }
6769 return ret;
6770#else /* NL80211_SUPPORT */
6771 sigma_dut_print(dut, DUT_MSG_ERROR,
6772 "beamformee sts cannot be changed without NL80211_SUPPORT defined");
6773 return -1;
6774#endif /* NL80211_SUPPORT */
6775}
6776
6777
Arif Hussain68d23f52018-07-11 13:39:08 -07006778#ifdef NL80211_SUPPORT
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07006779static int sta_set_mac_padding_duration(struct sigma_dut *dut, const char *intf,
6780 enum qca_wlan_he_mac_padding_dur val)
6781{
Arif Hussain68d23f52018-07-11 13:39:08 -07006782 struct nl_msg *msg;
6783 int ret = 0;
6784 struct nlattr *params;
6785 int ifindex;
6786
6787 ifindex = if_nametoindex(intf);
6788 if (ifindex == 0) {
6789 sigma_dut_print(dut, DUT_MSG_ERROR,
6790 "%s: Index for interface %s failed, val:%d",
6791 __func__, intf, val);
6792 return -1;
6793 }
6794
6795 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6796 NL80211_CMD_VENDOR)) ||
6797 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6798 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6799 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6800 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6801 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6802 nla_put_u8(msg,
6803 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MAC_PADDING_DUR,
6804 val)) {
6805 sigma_dut_print(dut, DUT_MSG_ERROR,
6806 "%s: err in adding vendor_cmd and vendor_data, val: %d",
6807 __func__, val);
6808 nlmsg_free(msg);
6809 return -1;
6810 }
6811 nla_nest_end(msg, params);
6812
6813 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6814 if (ret) {
6815 sigma_dut_print(dut, DUT_MSG_ERROR,
6816 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
6817 __func__, ret, val);
6818 }
6819 return ret;
Arif Hussain68d23f52018-07-11 13:39:08 -07006820}
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07006821#endif /* NL80211_SUPPORT */
Arif Hussain68d23f52018-07-11 13:39:08 -07006822
6823
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07006824static int sta_set_tx_su_ppdu_cfg(struct sigma_dut *dut, const char *intf,
6825 int val)
6826{
6827#ifdef NL80211_SUPPORT
6828 struct nl_msg *msg;
6829 int ret = 0;
6830 struct nlattr *params;
6831 int ifindex;
6832
6833 ifindex = if_nametoindex(intf);
6834 if (ifindex == 0) {
6835 sigma_dut_print(dut, DUT_MSG_ERROR,
6836 "%s: Index for interface %s failed, val:%d",
6837 __func__, intf, val);
6838 return -1;
6839 }
6840
6841 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6842 NL80211_CMD_VENDOR)) ||
6843 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6844 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6845 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6846 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6847 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6848 nla_put_u8(msg,
6849 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_SUPPDU,
6850 val)) {
6851 sigma_dut_print(dut, DUT_MSG_ERROR,
6852 "%s: err in adding vendor_cmd and vendor_data, val: %d",
6853 __func__, val);
6854 nlmsg_free(msg);
6855 return -1;
6856 }
6857 nla_nest_end(msg, params);
6858
6859 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6860 if (ret) {
6861 sigma_dut_print(dut, DUT_MSG_ERROR,
6862 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
6863 __func__, ret, val);
6864 }
6865 return ret;
6866#else /* NL80211_SUPPORT */
6867 sigma_dut_print(dut, DUT_MSG_ERROR,
6868 "Tx SU PPDU cannot be set without NL80211_SUPPORT defined");
6869 return -1;
6870#endif /* NL80211_SUPPORT */
6871}
6872
6873
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07006874#ifdef NL80211_SUPPORT
6875static int sta_set_he_om_ctrl_reset(struct sigma_dut *dut, const char *intf)
6876{
6877 struct nl_msg *msg;
6878 int ret = 0;
6879 struct nlattr *params;
6880 int ifindex;
6881
6882 ifindex = if_nametoindex(intf);
6883 if (ifindex == 0) {
6884 sigma_dut_print(dut, DUT_MSG_ERROR,
6885 "%s: Index for interface %s failed",
6886 __func__, intf);
6887 return -1;
6888 }
6889
6890 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6891 NL80211_CMD_VENDOR)) ||
6892 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6893 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6894 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6895 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6896 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6897 nla_put_flag(msg,
6898 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_CLEAR_HE_OM_CTRL_CONFIG)) {
6899 sigma_dut_print(dut, DUT_MSG_ERROR,
6900 "%s: err in adding vendor_cmd and vendor_data",
6901 __func__);
6902 nlmsg_free(msg);
6903 return -1;
6904 }
6905 nla_nest_end(msg, params);
6906
6907 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6908 if (ret) {
6909 sigma_dut_print(dut, DUT_MSG_ERROR,
6910 "%s: err in send_and_recv_msgs, ret=%d",
6911 __func__, ret);
6912 }
6913 return ret;
6914}
6915#endif /* NL80211_SUPPORT */
6916
6917
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07006918static int sta_set_mu_edca_override(struct sigma_dut *dut, const char *intf,
6919 int val)
6920{
6921#ifdef NL80211_SUPPORT
6922 struct nl_msg *msg;
6923 int ret = 0;
6924 struct nlattr *params;
6925 int ifindex;
6926
6927 ifindex = if_nametoindex(intf);
6928 if (ifindex == 0) {
6929 sigma_dut_print(dut, DUT_MSG_ERROR,
6930 "%s: Index for interface %s failed, val:%d",
6931 __func__, intf, val);
6932 return -1;
6933 }
6934
6935 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6936 NL80211_CMD_VENDOR)) ||
6937 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6938 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6939 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6940 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6941 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6942 nla_put_u8(msg,
6943 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_OVERRIDE_MU_EDCA,
6944 val)) {
6945 sigma_dut_print(dut, DUT_MSG_ERROR,
6946 "%s: err in adding vendor_cmd and vendor_data, val: %d",
6947 __func__, val);
6948 nlmsg_free(msg);
6949 return -1;
6950 }
6951 nla_nest_end(msg, params);
6952
6953 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6954 if (ret) {
6955 sigma_dut_print(dut, DUT_MSG_ERROR,
6956 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
6957 __func__, ret, val);
6958 }
6959 return ret;
6960#else /* NL80211_SUPPORT */
6961 sigma_dut_print(dut, DUT_MSG_ERROR,
6962 "MU EDCA override cannot be changed without NL80211_SUPPORT defined");
6963 return -1;
6964#endif /* NL80211_SUPPORT */
6965}
6966
6967
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07006968static int sta_set_om_ctrl_supp(struct sigma_dut *dut, const char *intf,
6969 int val)
6970{
6971#ifdef NL80211_SUPPORT
6972 struct nl_msg *msg;
6973 int ret = 0;
6974 struct nlattr *params;
6975 int ifindex;
6976
6977 ifindex = if_nametoindex(intf);
6978 if (ifindex == 0) {
6979 sigma_dut_print(dut, DUT_MSG_ERROR,
6980 "%s: Index for interface %s failed, val:%d",
6981 __func__, intf, val);
6982 return -1;
6983 }
6984
6985 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6986 NL80211_CMD_VENDOR)) ||
6987 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6988 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6989 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6990 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6991 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6992 nla_put_u8(msg,
6993 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OM_CTRL_SUPP,
6994 val)) {
6995 sigma_dut_print(dut, DUT_MSG_ERROR,
6996 "%s: err in adding vendor_cmd and vendor_data, val: %d",
6997 __func__, val);
6998 nlmsg_free(msg);
6999 return -1;
7000 }
7001 nla_nest_end(msg, params);
7002
7003 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7004 if (ret) {
7005 sigma_dut_print(dut, DUT_MSG_ERROR,
7006 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
7007 __func__, ret, val);
7008 }
7009 return ret;
7010#else /* NL80211_SUPPORT */
7011 sigma_dut_print(dut, DUT_MSG_ERROR,
7012 "HE OM ctrl cannot be changed without NL80211_SUPPORT defined");
7013 return -1;
7014#endif /* NL80211_SUPPORT */
7015}
7016
7017
Arif Hussain480d5f42019-03-12 14:40:42 -07007018static int sta_set_twt_req_support(struct sigma_dut *dut, const char *intf,
7019 int val)
7020{
7021#ifdef NL80211_SUPPORT
7022 struct nl_msg *msg;
7023 int ret;
7024 struct nlattr *params;
7025 int ifindex;
7026
7027 ifindex = if_nametoindex(intf);
7028 if (ifindex == 0) {
7029 sigma_dut_print(dut, DUT_MSG_ERROR,
7030 "%s: Index for interface %s failed, val:%d",
7031 __func__, intf, val);
7032 return -1;
7033 }
7034
7035 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7036 NL80211_CMD_VENDOR)) ||
7037 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7038 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7039 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7040 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7041 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7042 nla_put_u8(msg,
7043 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TWT_REQ_SUPPORT,
7044 val)) {
7045 sigma_dut_print(dut, DUT_MSG_ERROR,
7046 "%s: err in adding vendor_cmd and vendor_data, val: %d",
7047 __func__, val);
7048 nlmsg_free(msg);
7049 return -1;
7050 }
7051 nla_nest_end(msg, params);
7052
7053 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7054 if (ret) {
7055 sigma_dut_print(dut, DUT_MSG_ERROR,
7056 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
7057 __func__, ret, val);
7058 }
7059 return ret;
7060#else /* NL80211_SUPPORT */
7061 sigma_dut_print(dut, DUT_MSG_ERROR,
7062 "TWT Request cannot be changed without NL80211_SUPPORT defined");
7063 return -1;
7064#endif /* NL80211_SUPPORT */
7065}
7066
7067
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08007068static void sta_reset_default_wcn(struct sigma_dut *dut, const char *intf,
7069 const char *type)
7070{
7071 char buf[60];
7072
7073 if (dut->program == PROGRAM_HE) {
7074 /* resetting phymode to auto in case of HE program */
7075 snprintf(buf, sizeof(buf), "iwpriv %s setphymode 0", intf);
7076 if (system(buf) != 0) {
7077 sigma_dut_print(dut, DUT_MSG_ERROR,
7078 "iwpriv %s setphymode failed", intf);
7079 }
7080
Amarnath Hullur Subramanyam9cecb502018-04-25 13:26:30 -07007081 /* reset the rate to Auto rate */
7082 snprintf(buf, sizeof(buf), "iwpriv %s set_11ax_rate 0xff",
7083 intf);
7084 if (system(buf) != 0) {
7085 sigma_dut_print(dut, DUT_MSG_ERROR,
7086 "iwpriv %s set_11ax_rate 0xff failed",
7087 intf);
7088 }
7089
Kiran Kumar Lokere86cfe3a2018-06-01 11:55:15 -07007090 /* reset the LDPC setting */
7091 snprintf(buf, sizeof(buf), "iwpriv %s ldpc 1", intf);
7092 if (system(buf) != 0) {
7093 sigma_dut_print(dut, DUT_MSG_ERROR,
7094 "iwpriv %s ldpc 1 failed", intf);
7095 }
7096
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08007097 /* reset the power save setting */
7098 snprintf(buf, sizeof(buf), "iwpriv %s setPower 2", intf);
7099 if (system(buf) != 0) {
7100 sigma_dut_print(dut, DUT_MSG_ERROR,
7101 "iwpriv %s setPower 2 failed", intf);
7102 }
7103
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08007104 /* remove all network profiles */
7105 remove_wpa_networks(intf);
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08007106
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08007107 /* Configure ADDBA Req/Rsp buffer size to be 64 */
7108 sta_set_addba_buf_size(dut, intf, 64);
7109
Amarnath Hullur Subramanyam5f32d572018-03-02 00:02:33 -08007110#ifdef NL80211_SUPPORT
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08007111 /* Reset the device HE capabilities to its default supported
7112 * configuration. */
7113 sta_set_he_testbed_def(dut, intf, 0);
7114
Amarnath Hullur Subramanyam5f32d572018-03-02 00:02:33 -08007115 /* Disable noackpolicy for all AC */
7116 if (nlvendor_sta_set_noack(dut, intf, 0, QCA_WLAN_AC_ALL)) {
7117 sigma_dut_print(dut, DUT_MSG_ERROR,
7118 "Disable of noackpolicy for all AC failed");
7119 }
7120#endif /* NL80211_SUPPORT */
7121
Amarnath Hullur Subramanyamb1724a52018-03-07 14:31:46 -08007122 /* Enable WMM by default */
7123 if (wcn_sta_set_wmm(dut, intf, "on")) {
7124 sigma_dut_print(dut, DUT_MSG_ERROR,
7125 "Enable of WMM in sta_reset_default_wcn failed");
7126 }
7127
7128 /* Disable ADDBA_REJECT by default */
7129 if (nlvendor_sta_set_addba_reject(dut, intf, 0)) {
7130 sigma_dut_print(dut, DUT_MSG_ERROR,
7131 "Disable of addba_reject in sta_reset_default_wcn failed");
7132 }
7133
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08007134 /* Enable sending of ADDBA by default */
7135 if (nlvendor_config_send_addba(dut, intf, 1)) {
7136 sigma_dut_print(dut, DUT_MSG_ERROR,
7137 "Enable sending of ADDBA in sta_reset_default_wcn failed");
7138 }
7139
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08007140 /* Enable AMPDU by default */
7141 iwpriv_sta_set_ampdu(dut, intf, 1);
7142
Subhani Shaik8e7a3052018-04-24 14:03:00 -07007143#ifdef NL80211_SUPPORT
7144 if (sta_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_AUTO)) {
7145 sigma_dut_print(dut, DUT_MSG_ERROR,
7146 "Set LTF config to default in sta_reset_default_wcn failed");
7147 }
Arif Hussain9765f7d2018-07-03 08:28:26 -07007148
Kiran Kumar Lokerebad51122018-12-12 19:03:36 -08007149 /* set the beamformee NSTS(maximum number of
7150 * space-time streams) to default DUT config
7151 */
7152 if (sta_set_beamformee_sts(dut, intf, 7)) {
Arif Hussain9765f7d2018-07-03 08:28:26 -07007153 sigma_dut_print(dut, DUT_MSG_ERROR,
7154 "Failed to set BeamformeeSTS");
7155 }
Arif Hussain68d23f52018-07-11 13:39:08 -07007156
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07007157 if (sta_set_mac_padding_duration(
7158 dut, intf,
7159 QCA_WLAN_HE_NO_ADDITIONAL_PROCESS_TIME)) {
Arif Hussain68d23f52018-07-11 13:39:08 -07007160 sigma_dut_print(dut, DUT_MSG_ERROR,
7161 "Failed to set MAC padding duration");
7162 }
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07007163
7164 if (sta_set_mu_edca_override(dut, intf, 0)) {
7165 sigma_dut_print(dut, DUT_MSG_ERROR,
7166 "ErrorCode,Failed to set MU EDCA override disable");
7167 }
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07007168
7169 if (sta_set_om_ctrl_supp(dut, intf, 1)) {
7170 sigma_dut_print(dut, DUT_MSG_ERROR,
7171 "Failed to set OM ctrl supp");
7172 }
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07007173
7174 if (sta_set_tx_su_ppdu_cfg(dut, intf, 1)) {
7175 sigma_dut_print(dut, DUT_MSG_ERROR,
7176 "Failed to set Tx SU PPDU enable");
7177 }
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07007178
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07007179 if (sta_set_action_tx_in_he_tb_ppdu(dut, intf, 0)) {
7180 sigma_dut_print(dut, DUT_MSG_ERROR,
7181 "failed to send TB PPDU Tx cfg");
7182 }
7183
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07007184 if (sta_set_he_om_ctrl_reset(dut, intf)) {
7185 sigma_dut_print(dut, DUT_MSG_ERROR,
7186 "Failed to set OM ctrl reset");
7187 }
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08007188
7189 /* +HTC-HE support default on */
7190 if (sta_set_he_htc_supp(dut, intf, 1)) {
7191 sigma_dut_print(dut, DUT_MSG_ERROR,
7192 "Setting of +HTC-HE support failed");
7193 }
Subhani Shaik8e7a3052018-04-24 14:03:00 -07007194#endif /* NL80211_SUPPORT */
7195
Arif Hussain8d5b27b2018-05-14 14:31:03 -07007196 if (sta_set_tx_beamformee(dut, intf, 1)) {
7197 sigma_dut_print(dut, DUT_MSG_ERROR,
7198 "Set tx beamformee enable by default in sta_reset_default_wcn failed");
7199 }
7200
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08007201 /* Set nss to 1 and MCS 0-7 in case of testbed */
7202 if (type && strcasecmp(type, "Testbed") == 0) {
7203#ifdef NL80211_SUPPORT
7204 int ret;
7205#endif /* NL80211_SUPPORT */
7206
7207 snprintf(buf, sizeof(buf), "iwpriv %s nss 1", intf);
7208 if (system(buf) != 0) {
7209 sigma_dut_print(dut, DUT_MSG_ERROR,
7210 "iwpriv %s nss failed", intf);
7211 }
7212
7213#ifdef NL80211_SUPPORT
7214 ret = sta_set_he_mcs(dut, intf, HE_80_MCS0_7);
7215 if (ret) {
7216 sigma_dut_print(dut, DUT_MSG_ERROR,
7217 "Setting of MCS failed, ret:%d",
7218 ret);
7219 }
7220#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyamc67621d2018-02-04 23:18:01 -08007221
7222 /* Disable STBC as default */
7223 wcn_sta_set_stbc(dut, intf, "0");
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08007224
7225 /* Disable AMSDU as default */
7226 iwpriv_sta_set_amsdu(dut, intf, "0");
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08007227
7228#ifdef NL80211_SUPPORT
7229 /* HE fragmentation default off */
7230 if (sta_set_he_fragmentation(dut, intf,
7231 HE_FRAG_DISABLE)) {
7232 sigma_dut_print(dut, DUT_MSG_ERROR,
7233 "Setting of HE fragmentation failed");
7234 }
Kiran Kumar Lokerebad51122018-12-12 19:03:36 -08007235
7236 /* set the beamformee NSTS(maximum number of
7237 * space-time streams) to default testbed config
7238 */
7239 if (sta_set_beamformee_sts(dut, intf, 3)) {
7240 sigma_dut_print(dut, DUT_MSG_ERROR,
7241 "Failed to set BeamformeeSTS");
7242 }
7243
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08007244 /* +HTC-HE support default off */
7245 if (sta_set_he_htc_supp(dut, intf, 0)) {
7246 sigma_dut_print(dut, DUT_MSG_ERROR,
7247 "Setting of +HTC-HE support failed");
7248 }
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08007249
7250 /* Set device HE capabilities to testbed default
7251 * configuration. */
7252 if (sta_set_he_testbed_def(dut, intf, 1)) {
7253 sigma_dut_print(dut, DUT_MSG_DEBUG,
7254 "Failed to set HE defaults");
7255 }
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08007256
7257 /* Disable VHT support in 2.4 GHz for testbed */
7258 sta_set_2g_vht_supp(dut, intf, 0);
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08007259#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08007260
7261 /* Enable WEP/TKIP with HE capability in testbed */
7262 if (sta_set_heconfig_and_wep_tkip(dut, intf, 1)) {
7263 sigma_dut_print(dut, DUT_MSG_ERROR,
7264 "Enabling HE config with WEP/TKIP failed");
7265 }
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08007266 }
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08007267
7268 /* Defaults in case of DUT */
7269 if (type && strcasecmp(type, "DUT") == 0) {
Arif Hussaind48fcc72018-05-01 18:34:18 -07007270 /* Enable STBC by default */
7271 wcn_sta_set_stbc(dut, intf, "1");
7272
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08007273 /* set nss to 2 */
7274 snprintf(buf, sizeof(buf), "iwpriv %s nss 2", intf);
7275 if (system(buf) != 0) {
7276 sigma_dut_print(dut, DUT_MSG_ERROR,
7277 "iwpriv %s nss 2 failed", intf);
7278 }
Arif Hussainac6c5112018-05-25 17:34:00 -07007279 dut->sta_nss = 2;
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08007280
7281#ifdef NL80211_SUPPORT
Arif Hussainae239842018-05-01 18:20:05 -07007282 /* Set HE_MCS to 0-11 */
7283 if (sta_set_he_mcs(dut, intf, HE_80_MCS0_11)) {
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08007284 sigma_dut_print(dut, DUT_MSG_ERROR,
7285 "Setting of MCS failed");
7286 }
7287#endif /* NL80211_SUPPORT */
7288
7289 /* Disable WEP/TKIP with HE capability in DUT */
7290 if (sta_set_heconfig_and_wep_tkip(dut, intf, 0)) {
7291 sigma_dut_print(dut, DUT_MSG_ERROR,
7292 "Enabling HE config with WEP/TKIP failed");
7293 }
7294 }
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08007295 }
7296}
7297
7298
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007299static int cmd_sta_reset_default(struct sigma_dut *dut,
7300 struct sigma_conn *conn,
7301 struct sigma_cmd *cmd)
7302{
7303 int cmd_sta_p2p_reset(struct sigma_dut *dut, struct sigma_conn *conn,
7304 struct sigma_cmd *cmd);
7305 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007306 const char *band = get_param(cmd, "band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007307 const char *type;
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07007308 const char *program = get_param(cmd, "program");
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05307309 const char *dev_role = get_param(cmd, "DevRole");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007310
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07007311 if (!program)
7312 program = get_param(cmd, "prog");
7313 dut->program = sigma_program_to_enum(program);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007314 dut->device_type = STA_unknown;
7315 type = get_param(cmd, "type");
7316 if (type && strcasecmp(type, "Testbed") == 0)
7317 dut->device_type = STA_testbed;
7318 if (type && strcasecmp(type, "DUT") == 0)
7319 dut->device_type = STA_dut;
7320
7321 if (dut->program == PROGRAM_TDLS) {
7322 /* Clear TDLS testing mode */
7323 wpa_command(intf, "SET tdls_disabled 0");
7324 wpa_command(intf, "SET tdls_testing 0");
7325 dut->no_tpk_expiration = 0;
Pradeep Reddy POTTETI8ce2a232016-10-28 12:17:32 +05307326 if (get_driver_type() == DRIVER_WCN) {
7327 /* Enable the WCN driver in TDLS Explicit trigger mode
7328 */
7329 wpa_command(intf, "SET tdls_external_control 0");
7330 wpa_command(intf, "SET tdls_trigger_control 0");
7331 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007332 }
7333
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07007334#ifdef MIRACAST
7335 if (dut->program == PROGRAM_WFD ||
7336 dut->program == PROGRAM_DISPLAYR2)
7337 miracast_sta_reset_default(dut, conn, cmd);
7338#endif /* MIRACAST */
7339
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007340 switch (get_driver_type()) {
7341 case DRIVER_ATHEROS:
7342 sta_reset_default_ath(dut, intf, type);
7343 break;
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08007344 case DRIVER_WCN:
7345 sta_reset_default_wcn(dut, intf, type);
7346 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007347 default:
7348 break;
7349 }
7350
7351#ifdef ANDROID_NAN
7352 if (dut->program == PROGRAM_NAN)
7353 nan_cmd_sta_reset_default(dut, conn, cmd);
7354#endif /* ANDROID_NAN */
7355
Jouni Malinenba630452018-06-22 11:49:59 +03007356 if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007357 unlink("SP/wi-fi.org/pps.xml");
7358 if (system("rm -r SP/*") != 0) {
7359 }
7360 unlink("next-client-cert.pem");
7361 unlink("next-client-key.pem");
7362 }
7363
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007364 /* For WPS program of the 60 GHz band the band type needs to be saved */
7365 if (dut->program == PROGRAM_WPS) {
7366 if (band && strcasecmp(band, "60GHz") == 0) {
7367 dut->band = WPS_BAND_60G;
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02007368 /* For 60 GHz enable WPS for WPS TCs */
7369 dut->wps_disable = 0;
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007370 } else {
7371 dut->band = WPS_BAND_NON_60G;
7372 }
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02007373 } else if (dut->program == PROGRAM_60GHZ) {
7374 /* For 60 GHz MAC/PHY TCs WPS must be disabled */
7375 dut->wps_disable = 1;
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007376 }
7377
Alexei Avshalom Lazar157ba062018-12-23 16:15:26 +02007378 if (is_60g_sigma_dut(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007379 const char *dev_role = get_param(cmd, "DevRole");
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02007380 char buf[256];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007381
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02007382 sigma_dut_print(dut, DUT_MSG_INFO,
7383 "WPS 60 GHz program, wps_disable = %d",
7384 dut->wps_disable);
7385
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007386 if (!dev_role) {
7387 send_resp(dut, conn, SIGMA_ERROR,
7388 "errorCode,Missing DevRole argument");
7389 return 0;
7390 }
7391
7392 if (strcasecmp(dev_role, "STA") == 0)
7393 dut->dev_role = DEVROLE_STA;
7394 else if (strcasecmp(dev_role, "PCP") == 0)
7395 dut->dev_role = DEVROLE_PCP;
7396 else {
7397 send_resp(dut, conn, SIGMA_ERROR,
7398 "errorCode,Unknown DevRole");
7399 return 0;
7400 }
7401
7402 if (dut->device_type == STA_unknown) {
7403 sigma_dut_print(dut, DUT_MSG_ERROR,
7404 "Device type is not STA testbed or DUT");
7405 send_resp(dut, conn, SIGMA_ERROR,
7406 "errorCode,Unknown device type");
7407 return 0;
7408 }
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02007409
7410 sigma_dut_print(dut, DUT_MSG_DEBUG,
7411 "Setting msdu_size to MAX: 7912");
7412 snprintf(buf, sizeof(buf), "ifconfig %s mtu 7912",
7413 get_station_ifname());
7414
7415 if (system(buf) != 0) {
7416 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
7417 buf);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007418 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02007419 }
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02007420
7421 if (sta_set_force_mcs(dut, 0, 1)) {
7422 sigma_dut_print(dut, DUT_MSG_ERROR,
7423 "Failed to reset force MCS");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007424 return ERROR_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02007425 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007426 }
7427
7428 wpa_command(intf, "WPS_ER_STOP");
7429 wpa_command(intf, "FLUSH");
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05307430 wpa_command(intf, "ERP_FLUSH");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007431 wpa_command(intf, "SET radio_disabled 0");
7432
Alexei Avshalom Lazar744ae8a2019-01-31 17:26:46 +02007433 dut->wps_forced_version = 0;
7434
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007435 if (dut->wsc_fragment) {
7436 dut->wsc_fragment = 0;
7437 wpa_command(intf, "SET device_name Test client");
7438 wpa_command(intf, "SET manufacturer ");
7439 wpa_command(intf, "SET model_name ");
7440 wpa_command(intf, "SET model_number ");
7441 wpa_command(intf, "SET serial_number ");
7442 }
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02007443 if (is_60g_sigma_dut(dut) && dut->force_rsn_ie) {
7444 dut->force_rsn_ie = FORCE_RSN_IE_NONE;
7445 sta_60g_force_rsn_ie(dut, FORCE_RSN_IE_NONE);
7446 }
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007447
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007448 if (dut->tmp_mac_addr && dut->set_macaddr) {
7449 dut->tmp_mac_addr = 0;
7450 if (system(dut->set_macaddr) != 0) {
7451 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to clear "
7452 "temporary MAC address");
7453 }
7454 }
7455
7456 set_ps(intf, dut, 0);
7457
Jouni Malinenba630452018-06-22 11:49:59 +03007458 if (dut->program == PROGRAM_HS2 || dut->program == PROGRAM_HS2_R2 ||
7459 dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007460 wpa_command(intf, "SET interworking 1");
7461 wpa_command(intf, "SET hs20 1");
7462 }
7463
Deepak Dhamdhere0fe0e452017-12-18 14:52:09 -08007464 if (dut->program == PROGRAM_HS2_R2 ||
Jouni Malinenba630452018-06-22 11:49:59 +03007465 dut->program == PROGRAM_HS2_R3 ||
Deepak Dhamdhere0fe0e452017-12-18 14:52:09 -08007466 dut->program == PROGRAM_OCE) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007467 wpa_command(intf, "SET pmf 1");
7468 } else {
7469 wpa_command(intf, "SET pmf 0");
7470 }
7471
7472 hs2_clear_credentials(intf);
7473 wpa_command(intf, "SET hessid 00:00:00:00:00:00");
7474 wpa_command(intf, "SET access_network_type 15");
7475
7476 static_ip_file(0, NULL, NULL, NULL);
7477 kill_dhcp_client(dut, intf);
7478 clear_ip_addr(dut, intf);
7479
7480 dut->er_oper_performed = 0;
7481 dut->er_oper_bssid[0] = '\0';
7482
priyadharshini gowthamanad6cbba2016-10-04 10:39:58 -07007483 if (dut->program == PROGRAM_LOC) {
7484 /* Disable Interworking by default */
7485 wpa_command(get_station_ifname(), "SET interworking 0");
7486 }
7487
Ashwini Patil00402582017-04-13 12:29:39 +05307488 if (dut->program == PROGRAM_MBO) {
7489 free(dut->non_pref_ch_list);
7490 dut->non_pref_ch_list = NULL;
Ashwini Patil5acd7382017-04-13 15:55:04 +05307491 free(dut->btm_query_cand_list);
7492 dut->btm_query_cand_list = NULL;
Ashwini Patilc63161e2017-04-13 16:30:23 +05307493 wpa_command(intf, "SET reject_btm_req_reason 0");
Ashwini Patila75de5a2017-04-13 16:35:05 +05307494 wpa_command(intf, "SET ignore_assoc_disallow 0");
Ashwini Patild174f2c2017-04-13 16:49:46 +05307495 wpa_command(intf, "SET gas_address3 0");
Ashwini Patil9183fdb2017-04-13 16:58:25 +05307496 wpa_command(intf, "SET roaming 1");
Ankita Bajaj1d974552018-09-18 16:56:44 +05307497 wpa_command(intf, "SET interworking 1");
Ashwini Patil00402582017-04-13 12:29:39 +05307498 }
7499
Jouni Malinen3c367e82017-06-23 17:01:47 +03007500 free(dut->rsne_override);
7501 dut->rsne_override = NULL;
7502
Jouni Malinen68143132017-09-02 02:34:08 +03007503 free(dut->sae_commit_override);
7504 dut->sae_commit_override = NULL;
7505
Jouni Malinend86e5822017-08-29 03:55:32 +03007506 dut->dpp_conf_id = -1;
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02007507 free(dut->dpp_peer_uri);
7508 dut->dpp_peer_uri = NULL;
Jouni Malinen63d50412017-11-24 11:55:38 +02007509 dut->dpp_local_bootstrap = -1;
Jouni Malinen5011fb52017-12-05 21:00:15 +02007510 wpa_command(intf, "SET dpp_config_processing 2");
Jouni Malinend86e5822017-08-29 03:55:32 +03007511
Jouni Malinenfac9cad2017-10-10 18:35:55 +03007512 wpa_command(intf, "VENDOR_ELEM_REMOVE 13 *");
7513
vamsi krishnaa2799492017-12-05 14:28:01 +05307514 if (dut->program == PROGRAM_OCE) {
Ankita Bajaja2cb5672017-10-25 16:08:28 +05307515 wpa_command(intf, "SET oce 1");
vamsi krishnaa2799492017-12-05 14:28:01 +05307516 wpa_command(intf, "SET disable_fils 0");
Ankita Bajaj1bde7942018-01-09 19:15:01 +05307517 wpa_command(intf, "FILS_HLP_REQ_FLUSH");
7518 dut->fils_hlp = 0;
7519#ifdef ANDROID
7520 hlp_thread_cleanup(dut);
7521#endif /* ANDROID */
vamsi krishnaa2799492017-12-05 14:28:01 +05307522 }
Ankita Bajaja2cb5672017-10-25 16:08:28 +05307523
Jouni Malinen8179fee2019-03-28 03:19:47 +02007524 dut->akm_values = 0;
7525
Sunil Dutt076081f2018-02-05 19:45:50 +05307526#ifdef NL80211_SUPPORT
Sunil Dutt44595082018-02-12 19:41:45 +05307527 if (get_driver_type() == DRIVER_WCN &&
7528 dut->config_rsnie == 1) {
7529 dut->config_rsnie = 0;
7530 sta_config_rsnie(dut, 0);
Sunil Dutt076081f2018-02-05 19:45:50 +05307531 }
7532#endif /* NL80211_SUPPORT */
7533
Sunil Duttfebf8a82018-02-09 18:50:13 +05307534 if (dev_role && strcasecmp(dev_role, "STA-CFON") == 0) {
7535 dut->dev_role = DEVROLE_STA_CFON;
7536 return sta_cfon_reset_default(dut, conn, cmd);
7537 }
7538
Jouni Malinen439352d2018-09-13 03:42:23 +03007539 wpa_command(intf, "SET setband AUTO");
7540
Sunil Duttfebf8a82018-02-09 18:50:13 +05307541 if (dut->program != PROGRAM_VHT)
7542 return cmd_sta_p2p_reset(dut, conn, cmd);
7543
Priyadharshini Gowthamana7dfd492015-11-09 14:34:08 -08007544 return 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007545}
7546
7547
7548static int cmd_sta_get_events(struct sigma_dut *dut, struct sigma_conn *conn,
7549 struct sigma_cmd *cmd)
7550{
7551 const char *program = get_param(cmd, "Program");
7552
7553 if (program == NULL)
7554 return -1;
7555#ifdef ANDROID_NAN
7556 if (strcasecmp(program, "NAN") == 0)
7557 return nan_cmd_sta_get_events(dut, conn, cmd);
7558#endif /* ANDROID_NAN */
7559 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
7560 return 0;
7561}
7562
7563
Jouni Malinen82905202018-04-29 17:20:10 +03007564static int sta_exec_action_url(struct sigma_dut *dut, struct sigma_conn *conn,
7565 struct sigma_cmd *cmd)
7566{
7567 const char *url = get_param(cmd, "url");
7568 const char *method = get_param(cmd, "method");
7569 pid_t pid;
7570 int status;
7571
7572 if (!url || !method)
7573 return -1;
7574
7575 /* TODO: Add support for method,post */
7576 if (strcasecmp(method, "get") != 0) {
7577 send_resp(dut, conn, SIGMA_ERROR,
7578 "ErrorCode,Unsupported method");
7579 return 0;
7580 }
7581
7582 pid = fork();
7583 if (pid < 0) {
7584 perror("fork");
7585 return -1;
7586 }
7587
7588 if (pid == 0) {
7589 char * argv[5] = { "wget", "-O", "/dev/null",
7590 (char *) url, NULL };
7591
7592 execv("/usr/bin/wget", argv);
7593 perror("execv");
7594 exit(0);
7595 return -1;
7596 }
7597
7598 if (waitpid(pid, &status, 0) < 0) {
7599 perror("waitpid");
7600 return -1;
7601 }
7602
7603 if (WIFEXITED(status)) {
7604 const char *errmsg;
7605
7606 if (WEXITSTATUS(status) == 0)
7607 return 1;
7608 sigma_dut_print(dut, DUT_MSG_INFO, "wget exit status %d",
7609 WEXITSTATUS(status));
7610 switch (WEXITSTATUS(status)) {
7611 case 4:
7612 errmsg = "errmsg,Network failure";
7613 break;
7614 case 8:
7615 errmsg = "errmsg,Server issued an error response";
7616 break;
7617 default:
7618 errmsg = "errmsg,Unknown failure from wget";
7619 break;
7620 }
7621 send_resp(dut, conn, SIGMA_ERROR, errmsg);
7622 return 0;
7623 }
7624
7625 send_resp(dut, conn, SIGMA_ERROR, "errmsg,Unknown failure");
7626 return 0;
7627}
7628
7629
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007630static int cmd_sta_exec_action(struct sigma_dut *dut, struct sigma_conn *conn,
7631 struct sigma_cmd *cmd)
7632{
7633 const char *program = get_param(cmd, "Prog");
7634
Jouni Malinen82905202018-04-29 17:20:10 +03007635 if (program && !get_param(cmd, "interface"))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007636 return -1;
7637#ifdef ANDROID_NAN
Jouni Malinen82905202018-04-29 17:20:10 +03007638 if (program && strcasecmp(program, "NAN") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007639 return nan_cmd_sta_exec_action(dut, conn, cmd);
7640#endif /* ANDROID_NAN */
Jouni Malinen82905202018-04-29 17:20:10 +03007641
7642 if (program && strcasecmp(program, "Loc") == 0)
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07007643 return loc_cmd_sta_exec_action(dut, conn, cmd);
Jouni Malinen82905202018-04-29 17:20:10 +03007644
7645 if (get_param(cmd, "url"))
7646 return sta_exec_action_url(dut, conn, cmd);
7647
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007648 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
7649 return 0;
7650}
7651
7652
7653static int cmd_sta_set_11n(struct sigma_dut *dut, struct sigma_conn *conn,
7654 struct sigma_cmd *cmd)
7655{
7656 const char *intf = get_param(cmd, "Interface");
7657 const char *val, *mcs32, *rate;
7658
7659 val = get_param(cmd, "GREENFIELD");
7660 if (val) {
7661 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
7662 /* Enable GD */
7663 send_resp(dut, conn, SIGMA_ERROR,
7664 "ErrorCode,GF not supported");
7665 return 0;
7666 }
7667 }
7668
7669 val = get_param(cmd, "SGI20");
7670 if (val) {
7671 switch (get_driver_type()) {
7672 case DRIVER_ATHEROS:
7673 ath_sta_set_sgi(dut, intf, val);
7674 break;
7675 default:
7676 send_resp(dut, conn, SIGMA_ERROR,
7677 "ErrorCode,SGI20 not supported");
7678 return 0;
7679 }
7680 }
7681
7682 mcs32 = get_param(cmd, "MCS32"); /* HT Duplicate Mode Enable/Disable */
7683 rate = get_param(cmd, "MCS_FIXEDRATE"); /* Fixed MCS rate (0..31) */
7684 if (mcs32 && rate) {
7685 /* TODO */
7686 send_resp(dut, conn, SIGMA_ERROR,
7687 "ErrorCode,MCS32,MCS_FIXEDRATE not supported");
7688 return 0;
7689 } else if (mcs32 && !rate) {
7690 /* TODO */
7691 send_resp(dut, conn, SIGMA_ERROR,
7692 "ErrorCode,MCS32 not supported");
7693 return 0;
7694 } else if (!mcs32 && rate) {
7695 switch (get_driver_type()) {
7696 case DRIVER_ATHEROS:
priyadharshini gowthamane5e25172015-12-08 14:53:48 -08007697 novap_reset(dut, intf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007698 ath_sta_set_11nrates(dut, intf, rate);
7699 break;
7700 default:
7701 send_resp(dut, conn, SIGMA_ERROR,
7702 "ErrorCode,MCS32_FIXEDRATE not supported");
7703 return 0;
7704 }
7705 }
7706
7707 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
7708}
7709
7710
Arif Hussain7b47d2d2018-05-09 10:44:02 -07007711static void cmd_set_max_he_mcs(struct sigma_dut *dut, const char *intf,
7712 int mcs_config)
7713{
7714#ifdef NL80211_SUPPORT
7715 int ret;
7716
7717 switch (mcs_config) {
7718 case HE_80_MCS0_7:
7719 case HE_80_MCS0_9:
7720 case HE_80_MCS0_11:
7721 ret = sta_set_he_mcs(dut, intf, mcs_config);
7722 if (ret) {
7723 sigma_dut_print(dut, DUT_MSG_ERROR,
7724 "cmd_set_max_he_mcs: Setting of MCS:%d failed, ret:%d",
7725 mcs_config, ret);
7726 }
7727 break;
7728 default:
7729 sigma_dut_print(dut, DUT_MSG_ERROR,
7730 "cmd_set_max_he_mcs: Invalid mcs %d",
7731 mcs_config);
7732 break;
7733 }
7734#else /* NL80211_SUPPORT */
7735 sigma_dut_print(dut, DUT_MSG_ERROR,
7736 "max HE MCS cannot be changed without NL80211_SUPPORT defined");
7737#endif /* NL80211_SUPPORT */
7738}
7739
7740
Arif Hussain480d5f42019-03-12 14:40:42 -07007741static int sta_twt_request(struct sigma_dut *dut, struct sigma_conn *conn,
7742 struct sigma_cmd *cmd)
7743{
7744#ifdef NL80211_SUPPORT
7745 struct nlattr *params;
7746 struct nlattr *attr;
7747 struct nlattr *attr1;
7748 struct nl_msg *msg;
7749 int ifindex, ret;
7750 const char *val;
7751 const char *intf = get_param(cmd, "Interface");
7752 int wake_interval_exp = 10, nominal_min_wake_dur = 255,
7753 wake_interval_mantissa = 512;
7754 int flow_type = 0, twt_trigger = 0, target_wake_time = 0,
7755 protection = 0;
7756
7757 ifindex = if_nametoindex(intf);
7758 if (ifindex == 0) {
7759 sigma_dut_print(dut, DUT_MSG_ERROR,
7760 "%s: Index for interface %s failed",
7761 __func__, intf);
7762 return -1;
7763 }
7764
7765 val = get_param(cmd, "FlowType");
7766 if (val) {
7767 flow_type = atoi(val);
7768 if (flow_type != 0 && flow_type != 1) {
7769 sigma_dut_print(dut, DUT_MSG_ERROR,
7770 "TWT: Invalid FlowType %d", flow_type);
7771 return -1;
7772 }
7773 }
7774
7775 val = get_param(cmd, "TWT_Trigger");
7776 if (val) {
7777 twt_trigger = atoi(val);
7778 if (twt_trigger != 0 && twt_trigger != 1) {
7779 sigma_dut_print(dut, DUT_MSG_ERROR,
7780 "TWT: Invalid TWT_Trigger %d",
7781 twt_trigger);
7782 return -1;
7783 }
7784 }
7785
7786 val = get_param(cmd, "Protection");
7787 if (val) {
7788 protection = atoi(val);
7789 if (protection != 0 && protection != 1) {
7790 sigma_dut_print(dut, DUT_MSG_ERROR,
7791 "TWT: Invalid Protection %d",
7792 protection);
7793 return -1;
7794 }
7795 }
7796
7797 val = get_param(cmd, "TargetWakeTime");
7798 if (val)
7799 target_wake_time = atoi(val);
7800
7801 val = get_param(cmd, "WakeIntervalMantissa");
7802 if (val)
7803 wake_interval_mantissa = atoi(val);
7804
7805 val = get_param(cmd, "WakeIntervalExp");
7806 if (val)
7807 wake_interval_exp = atoi(val);
7808
7809 val = get_param(cmd, "NominalMinWakeDur");
7810 if (val)
7811 nominal_min_wake_dur = atoi(val);
7812
7813 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7814 NL80211_CMD_VENDOR)) ||
7815 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7816 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7817 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7818 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7819 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7820 !(params = nla_nest_start(
7821 msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_SETUP)) ||
7822 !(attr1 = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7823 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_EXP,
7824 wake_interval_exp) ||
7825 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST, 0) ||
7826 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_REQ_TYPE, 1) ||
7827 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TRIGGER,
7828 twt_trigger) ||
7829 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE,
7830 flow_type) ||
7831 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_PROTECTION,
7832 protection) ||
7833 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME,
7834 target_wake_time) ||
7835 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_DURATION,
7836 nominal_min_wake_dur) ||
7837 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_MANTISSA,
7838 wake_interval_mantissa)) {
7839 sigma_dut_print(dut, DUT_MSG_ERROR,
7840 "%s: err in adding vendor_cmd and vendor_data",
7841 __func__);
7842 nlmsg_free(msg);
7843 return -1;
7844 }
7845 nla_nest_end(msg, attr1);
7846 nla_nest_end(msg, params);
7847 nla_nest_end(msg, attr);
7848
7849 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7850 if (ret) {
7851 sigma_dut_print(dut, DUT_MSG_ERROR,
7852 "%s: err in send_and_recv_msgs, ret=%d",
7853 __func__, ret);
7854 }
7855
7856 return ret;
7857#else /* NL80211_SUPPORT */
7858 sigma_dut_print(dut, DUT_MSG_ERROR,
7859 "TWT request cannot be done without NL80211_SUPPORT defined");
7860 return -1;
7861#endif /* NL80211_SUPPORT */
7862}
7863
7864
7865static int sta_twt_teardown(struct sigma_dut *dut, struct sigma_conn *conn,
7866 struct sigma_cmd *cmd)
7867{
7868 #ifdef NL80211_SUPPORT
7869 struct nlattr *params;
7870 struct nlattr *attr;
7871 struct nlattr *attr1;
7872 int ifindex, ret;
7873 struct nl_msg *msg;
7874 const char *intf = get_param(cmd, "Interface");
7875
7876 ifindex = if_nametoindex(intf);
7877 if (ifindex == 0) {
7878 sigma_dut_print(dut, DUT_MSG_ERROR,
7879 "%s: Index for interface %s failed",
7880 __func__, intf);
7881 return -1;
7882 }
7883
7884 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7885 NL80211_CMD_VENDOR)) ||
7886 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7887 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7888 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7889 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7890 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7891 !(params = nla_nest_start(
7892 msg,
7893 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_TERMINATE)) ||
7894 !(attr1 = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7895 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE, 0)) {
7896 sigma_dut_print(dut, DUT_MSG_ERROR,
7897 "%s: err in adding vendor_cmd and vendor_data",
7898 __func__);
7899 nlmsg_free(msg);
7900 return -1;
7901 }
7902 nla_nest_end(msg, attr1);
7903 nla_nest_end(msg, params);
7904 nla_nest_end(msg, attr);
7905
7906 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7907 if (ret) {
7908 sigma_dut_print(dut, DUT_MSG_ERROR,
7909 "%s: err in send_and_recv_msgs, ret=%d",
7910 __func__, ret);
7911 }
7912
7913 return ret;
7914#else /* NL80211_SUPPORT */
7915 sigma_dut_print(dut, DUT_MSG_ERROR,
7916 "TWT teardown cannot be done without NL80211_SUPPORT defined");
7917 return -1;
7918#endif /* NL80211_SUPPORT */
7919}
7920
7921
Kiran Kumar Lokere50eb2cd2018-12-18 18:31:28 -08007922static int sta_transmit_omi(struct sigma_dut *dut, struct sigma_conn *conn,
7923 struct sigma_cmd *cmd)
7924{
7925#ifdef NL80211_SUPPORT
7926 struct nlattr *params;
7927 struct nlattr *attr;
7928 struct nlattr *attr1;
7929 struct nl_msg *msg;
7930 int ifindex, ret;
7931 const char *val;
7932 const char *intf = get_param(cmd, "Interface");
7933 uint8_t rx_nss = 0xFF, ch_bw = 0xFF, tx_nsts = 0xFF, ulmu_dis = 0,
7934 ulmu_data_dis = 0;
7935
7936 ifindex = if_nametoindex(intf);
7937 if (ifindex == 0) {
7938 sigma_dut_print(dut, DUT_MSG_ERROR,
7939 "%s: Index for interface %s failed",
7940 __func__, intf);
7941 return -1;
7942 }
7943 val = get_param(cmd, "OMCtrl_RxNSS");
7944 if (val)
7945 rx_nss = atoi(val);
7946
7947 val = get_param(cmd, "OMCtrl_ChnlWidth");
7948 if (val)
7949 ch_bw = atoi(val);
7950
7951 val = get_param(cmd, "OMCtrl_ULMUDisable");
7952 if (val)
7953 ulmu_dis = atoi(val);
7954
7955 val = get_param(cmd, "OMCtrl_TxNSTS");
7956 if (val)
7957 tx_nsts = atoi(val);
7958
7959 val = get_param(cmd, "OMCtrl_ULMUDataDisable");
7960 if (val)
7961 ulmu_data_dis = atoi(val);
7962
7963 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7964 NL80211_CMD_VENDOR)) ||
7965 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7966 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7967 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7968 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7969 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7970 !(params = nla_nest_start(
7971 msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OMI_TX)) ||
7972 !(attr1 = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7973 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_RX_NSS, rx_nss) ||
7974 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_CH_BW, ch_bw) ||
7975 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_TX_NSTS, tx_nsts) ||
7976 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DATA_DISABLE,
7977 ulmu_data_dis) ||
7978 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DISABLE,
7979 ulmu_dis)) {
7980 sigma_dut_print(dut, DUT_MSG_ERROR,
7981 "%s: err in adding vendor_cmd and vendor_data",
7982 __func__);
7983 nlmsg_free(msg);
7984 return -1;
7985 }
7986 nla_nest_end(msg, attr1);
7987 nla_nest_end(msg, params);
7988 nla_nest_end(msg, attr);
7989
7990 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7991 if (ret) {
7992 sigma_dut_print(dut, DUT_MSG_ERROR,
7993 "%s: err in send_and_recv_msgs, ret=%d",
7994 __func__, ret);
7995 }
7996
7997 return ret;
7998#else /* NL80211_SUPPORT */
7999 sigma_dut_print(dut, DUT_MSG_ERROR,
8000 "OMI TX cannot be processed without NL80211_SUPPORT defined");
8001 return -1;
8002#endif /* NL80211_SUPPORT */
8003}
8004
8005
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008006static int cmd_sta_set_wireless_vht(struct sigma_dut *dut,
8007 struct sigma_conn *conn,
8008 struct sigma_cmd *cmd)
8009{
8010 const char *intf = get_param(cmd, "Interface");
8011 const char *val;
Arif Hussaina37e9552018-06-20 17:05:59 -07008012 const char *program;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008013 int tkip = -1;
8014 int wep = -1;
8015
Arif Hussaina37e9552018-06-20 17:05:59 -07008016 program = get_param(cmd, "Program");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008017 val = get_param(cmd, "SGI80");
8018 if (val) {
8019 int sgi80;
8020
8021 sgi80 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008022 run_iwpriv(dut, intf, "shortgi %d", sgi80);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008023 }
8024
8025 val = get_param(cmd, "TxBF");
8026 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07008027 switch (get_driver_type()) {
8028 case DRIVER_WCN:
8029 if (sta_set_tx_beamformee(dut, intf, 1)) {
8030 send_resp(dut, conn, SIGMA_ERROR,
8031 "ErrorCode,Failed to set TX beamformee enable");
8032 return 0;
8033 }
8034 break;
8035 case DRIVER_ATHEROS:
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008036 if (run_iwpriv(dut, intf, "vhtsubfee 1") < 0) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07008037 send_resp(dut, conn, SIGMA_ERROR,
8038 "ErrorCode,Setting vhtsubfee failed");
8039 return 0;
8040 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008041 if (run_iwpriv(dut, intf, "vhtsubfer 1") < 0) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07008042 send_resp(dut, conn, SIGMA_ERROR,
8043 "ErrorCode,Setting vhtsubfer failed");
8044 return 0;
8045 }
8046 break;
8047 default:
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008048 sigma_dut_print(dut, DUT_MSG_ERROR,
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07008049 "Unsupported driver type");
8050 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008051 }
8052 }
8053
8054 val = get_param(cmd, "MU_TxBF");
8055 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
8056 switch (get_driver_type()) {
8057 case DRIVER_ATHEROS:
8058 ath_sta_set_txsp_stream(dut, intf, "1SS");
8059 ath_sta_set_rxsp_stream(dut, intf, "1SS");
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008060 run_iwpriv(dut, intf, "vhtmubfee 1");
8061 run_iwpriv(dut, intf, "vhtmubfer 1");
Sunil Duttae9e5d12018-06-29 11:50:47 +05308062 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008063 case DRIVER_WCN:
8064 if (wcn_sta_set_sp_stream(dut, intf, "1SS") < 0) {
8065 send_resp(dut, conn, SIGMA_ERROR,
8066 "ErrorCode,Failed to set RX/TXSP_STREAM");
8067 return 0;
8068 }
Sunil Duttae9e5d12018-06-29 11:50:47 +05308069 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008070 default:
8071 sigma_dut_print(dut, DUT_MSG_ERROR,
8072 "Setting SP_STREAM not supported");
8073 break;
8074 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008075 }
8076
8077 val = get_param(cmd, "LDPC");
8078 if (val) {
8079 int ldpc;
8080
8081 ldpc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008082 run_iwpriv(dut, intf, "ldpc %d", ldpc);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008083 }
8084
Amarnath Hullur Subramanyam7bae60e2018-01-31 03:46:50 -08008085 val = get_param(cmd, "BCC");
8086 if (val) {
8087 int bcc;
8088
8089 bcc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
8090 /* use LDPC iwpriv itself to set bcc coding, bcc coding
8091 * is mutually exclusive to bcc */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008092 run_iwpriv(dut, intf, "ldpc %d", !bcc);
Amarnath Hullur Subramanyam7bae60e2018-01-31 03:46:50 -08008093 }
8094
Arif Hussain7b47d2d2018-05-09 10:44:02 -07008095 val = get_param(cmd, "MaxHE-MCS_1SS_RxMapLTE80");
8096 if (val && dut->sta_nss == 1)
8097 cmd_set_max_he_mcs(dut, intf, atoi(val));
8098
8099 val = get_param(cmd, "MaxHE-MCS_2SS_RxMapLTE80");
8100 if (val && dut->sta_nss == 2)
8101 cmd_set_max_he_mcs(dut, intf, atoi(val));
8102
Arif Hussainac6c5112018-05-25 17:34:00 -07008103 val = get_param(cmd, "MCS_FixedRate");
8104 if (val) {
8105#ifdef NL80211_SUPPORT
8106 int mcs, ratecode = 0;
8107 enum he_mcs_config mcs_config;
8108 int ret;
Jouni Malinenb9b671d2019-04-26 13:23:17 +03008109 char buf[60];
Arif Hussainac6c5112018-05-25 17:34:00 -07008110
8111 ratecode = (0x07 & dut->sta_nss) << 5;
8112 mcs = atoi(val);
8113 /* Add the MCS to the ratecode */
8114 if (mcs >= 0 && mcs <= 11) {
8115 ratecode += mcs;
8116 if (dut->device_type == STA_testbed &&
8117 mcs > 7 && mcs <= 11) {
8118 if (mcs <= 9)
8119 mcs_config = HE_80_MCS0_9;
8120 else
8121 mcs_config = HE_80_MCS0_11;
8122 ret = sta_set_he_mcs(dut, intf, mcs_config);
8123 if (ret) {
8124 sigma_dut_print(dut, DUT_MSG_ERROR,
8125 "MCS_FixedRate: mcs setting failed, mcs:%d, mcs_config %d, ret:%d",
8126 mcs, mcs_config, ret);
8127 }
8128 }
8129 snprintf(buf, sizeof(buf),
8130 "iwpriv %s set_11ax_rate 0x%03x",
8131 intf, ratecode);
8132 if (system(buf) != 0) {
8133 sigma_dut_print(dut, DUT_MSG_ERROR,
8134 "MCS_FixedRate: iwpriv setting of 11ax rates 0x%03x failed",
8135 ratecode);
8136 }
8137 } else {
8138 sigma_dut_print(dut, DUT_MSG_ERROR,
8139 "MCS_FixedRate: HE MCS %d not supported",
8140 mcs);
8141 }
8142#else /* NL80211_SUPPORT */
8143 sigma_dut_print(dut, DUT_MSG_ERROR,
8144 "MCS_FixedRate cannot be changed without NL80211_SUPPORT defined");
8145#endif /* NL80211_SUPPORT */
8146 }
8147
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008148 val = get_param(cmd, "opt_md_notif_ie");
8149 if (val) {
8150 char *result = NULL;
8151 char delim[] = ";";
8152 char token[30];
8153 int value, config_val = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308154 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008155
Peng Xub8fc5cc2017-05-10 17:27:28 -07008156 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308157 result = strtok_r(token, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008158
8159 /* Extract the NSS information */
8160 if (result) {
8161 value = atoi(result);
8162 switch (value) {
8163 case 1:
8164 config_val = 1;
8165 break;
8166 case 2:
8167 config_val = 3;
8168 break;
8169 case 3:
8170 config_val = 7;
8171 break;
8172 case 4:
8173 config_val = 15;
8174 break;
8175 default:
8176 config_val = 3;
8177 break;
8178 }
8179
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008180 run_iwpriv(dut, intf, "rxchainmask %d", config_val);
8181 run_iwpriv(dut, intf, "txchainmask %d", config_val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008182
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008183 }
8184
8185 /* Extract the channel width information */
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308186 result = strtok_r(NULL, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008187 if (result) {
8188 value = atoi(result);
8189 switch (value) {
8190 case 20:
8191 config_val = 0;
8192 break;
8193 case 40:
8194 config_val = 1;
8195 break;
8196 case 80:
8197 config_val = 2;
8198 break;
8199 case 160:
8200 config_val = 3;
8201 break;
8202 default:
8203 config_val = 2;
8204 break;
8205 }
8206
8207 dut->chwidth = config_val;
8208
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008209 run_iwpriv(dut, intf, "chwidth %d", config_val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008210 }
8211
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008212 run_iwpriv(dut, intf, "opmode_notify 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008213 }
8214
8215 val = get_param(cmd, "nss_mcs_cap");
8216 if (val) {
8217 int nss, mcs;
8218 char token[20];
8219 char *result = NULL;
8220 unsigned int vht_mcsmap = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308221 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008222
Peng Xub8fc5cc2017-05-10 17:27:28 -07008223 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308224 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05308225 if (!result) {
8226 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07008227 "NSS not specified");
8228 send_resp(dut, conn, SIGMA_ERROR,
8229 "errorCode,NSS not specified");
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05308230 return 0;
8231 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008232 nss = atoi(result);
8233
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008234 run_iwpriv(dut, intf, "nss %d", nss);
Arif Hussainac6c5112018-05-25 17:34:00 -07008235 dut->sta_nss = nss;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008236
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308237 result = strtok_r(NULL, ";", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008238 if (result == NULL) {
8239 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07008240 "MCS not specified");
8241 send_resp(dut, conn, SIGMA_ERROR,
8242 "errorCode,MCS not specified");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008243 return 0;
8244 }
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308245 result = strtok_r(result, "-", &saveptr);
8246 result = strtok_r(NULL, "-", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05308247 if (!result) {
8248 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07008249 "MCS not specified");
8250 send_resp(dut, conn, SIGMA_ERROR,
8251 "errorCode,MCS not specified");
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05308252 return 0;
8253 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008254 mcs = atoi(result);
8255
Arif Hussaina37e9552018-06-20 17:05:59 -07008256 if (program && strcasecmp(program, "HE") == 0) {
8257#ifdef NL80211_SUPPORT
8258 enum he_mcs_config mcs_config;
8259 int ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008260
Arif Hussaina37e9552018-06-20 17:05:59 -07008261 if (mcs >= 0 && mcs <= 7) {
8262 mcs_config = HE_80_MCS0_7;
8263 } else if (mcs > 7 && mcs <= 9) {
8264 mcs_config = HE_80_MCS0_9;
8265 } else if (mcs > 9 && mcs <= 11) {
8266 mcs_config = HE_80_MCS0_11;
8267 } else {
8268 sigma_dut_print(dut, DUT_MSG_ERROR,
8269 "nss_mcs_cap: HE: Invalid mcs: %d",
8270 mcs);
8271 send_resp(dut, conn, SIGMA_ERROR,
8272 "errorCode,Invalid MCS");
8273 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008274 }
Arif Hussaina37e9552018-06-20 17:05:59 -07008275
8276 ret = sta_set_he_mcs(dut, intf, mcs_config);
8277 if (ret) {
8278 sigma_dut_print(dut, DUT_MSG_ERROR,
8279 "nss_mcs_cap: HE: Setting of MCS failed, mcs_config: %d, ret: %d",
8280 mcs_config, ret);
8281 send_resp(dut, conn, SIGMA_ERROR,
8282 "errorCode,Failed to set MCS");
8283 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008284 }
Arif Hussaina37e9552018-06-20 17:05:59 -07008285#else /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008286 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07008287 "nss_mcs_cap: HE: MCS cannot be changed without NL80211_SUPPORT defined");
8288#endif /* NL80211_SUPPORT */
8289 } else {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008290 run_iwpriv(dut, intf, "vhtmcs %d", mcs);
Arif Hussaina37e9552018-06-20 17:05:59 -07008291
8292 switch (nss) {
8293 case 1:
8294 switch (mcs) {
8295 case 7:
8296 vht_mcsmap = 0xfffc;
8297 break;
8298 case 8:
8299 vht_mcsmap = 0xfffd;
8300 break;
8301 case 9:
8302 vht_mcsmap = 0xfffe;
8303 break;
8304 default:
8305 vht_mcsmap = 0xfffe;
8306 break;
8307 }
8308 break;
8309 case 2:
8310 switch (mcs) {
8311 case 7:
8312 vht_mcsmap = 0xfff0;
8313 break;
8314 case 8:
8315 vht_mcsmap = 0xfff5;
8316 break;
8317 case 9:
8318 vht_mcsmap = 0xfffa;
8319 break;
8320 default:
8321 vht_mcsmap = 0xfffa;
8322 break;
8323 }
8324 break;
8325 case 3:
8326 switch (mcs) {
8327 case 7:
8328 vht_mcsmap = 0xffc0;
8329 break;
8330 case 8:
8331 vht_mcsmap = 0xffd5;
8332 break;
8333 case 9:
8334 vht_mcsmap = 0xffea;
8335 break;
8336 default:
8337 vht_mcsmap = 0xffea;
8338 break;
8339 }
8340 break;
8341 default:
8342 vht_mcsmap = 0xffea;
8343 break;
8344 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008345 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008346 }
8347 }
8348
8349 /* UNSUPPORTED: val = get_param(cmd, "Tx_lgi_rate"); */
8350
8351 val = get_param(cmd, "Vht_tkip");
8352 if (val)
8353 tkip = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
8354
8355 val = get_param(cmd, "Vht_wep");
8356 if (val)
8357 wep = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
8358
8359 if (tkip != -1 || wep != -1) {
8360 if ((tkip == 1 && wep != 0) || (wep == 1 && tkip != 0)) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008361 run_iwpriv(dut, intf, "htweptkip 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008362 } else if ((tkip == 0 && wep != 1) || (wep == 0 && tkip != 1)) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008363 run_iwpriv(dut, intf, "htweptkip 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008364 } else {
8365 sigma_dut_print(dut, DUT_MSG_ERROR,
8366 "ErrorCode,mixed mode of VHT TKIP/WEP not supported");
8367 return 0;
8368 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008369 }
8370
Arif Hussain55f00da2018-07-03 08:28:26 -07008371 val = get_param(cmd, "txBandwidth");
8372 if (val) {
8373 switch (get_driver_type()) {
8374 case DRIVER_WCN:
8375 if (wcn_sta_set_width(dut, intf, val) < 0) {
8376 send_resp(dut, conn, SIGMA_ERROR,
8377 "ErrorCode,Failed to set txBandwidth");
8378 return 0;
8379 }
8380 break;
8381 case DRIVER_ATHEROS:
8382 if (ath_set_width(dut, conn, intf, val) < 0) {
8383 send_resp(dut, conn, SIGMA_ERROR,
8384 "ErrorCode,Failed to set txBandwidth");
8385 return 0;
8386 }
8387 break;
8388 default:
8389 sigma_dut_print(dut, DUT_MSG_ERROR,
8390 "Setting txBandwidth not supported");
8391 break;
8392 }
8393 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008394
Arif Hussain9765f7d2018-07-03 08:28:26 -07008395 val = get_param(cmd, "BeamformeeSTS");
8396 if (val) {
Kiran Kumar Lokerebc89d432018-07-10 12:20:13 -07008397 if (sta_set_tx_beamformee(dut, intf, 1)) {
8398 send_resp(dut, conn, SIGMA_ERROR,
8399 "ErrorCode,Failed to set TX beamformee enable");
8400 return 0;
8401 }
8402
Arif Hussain9765f7d2018-07-03 08:28:26 -07008403 if (sta_set_beamformee_sts(dut, intf, atoi(val))) {
8404 send_resp(dut, conn, SIGMA_ERROR,
8405 "ErrorCode,Failed to set BeamformeeSTS");
8406 return 0;
8407 }
8408 }
8409
Arif Hussain68d23f52018-07-11 13:39:08 -07008410 val = get_param(cmd, "Trig_MAC_Padding_Dur");
8411 if (val) {
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07008412#ifdef NL80211_SUPPORT
8413 enum qca_wlan_he_mac_padding_dur set_val;
8414
8415 switch (atoi(val)) {
8416 case 16:
8417 set_val = QCA_WLAN_HE_16US_OF_PROCESS_TIME;
8418 break;
8419 case 8:
8420 set_val = QCA_WLAN_HE_8US_OF_PROCESS_TIME;
8421 break;
8422 default:
8423 set_val = QCA_WLAN_HE_NO_ADDITIONAL_PROCESS_TIME;
8424 break;
8425 }
8426 if (sta_set_mac_padding_duration(dut, intf, set_val)) {
Arif Hussain68d23f52018-07-11 13:39:08 -07008427 send_resp(dut, conn, SIGMA_ERROR,
8428 "ErrorCode,Failed to set MAC padding duration");
8429 return 0;
8430 }
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07008431#else /* NL80211_SUPPORT */
8432 sigma_dut_print(dut, DUT_MSG_ERROR,
8433 "MAC padding duration cannot be changed without NL80211_SUPPORT defined");
8434#endif /* NL80211_SUPPORT */
Arif Hussain68d23f52018-07-11 13:39:08 -07008435 }
8436
Arif Hussain480d5f42019-03-12 14:40:42 -07008437 val = get_param(cmd, "TWT_ReqSupport");
8438 if (val) {
8439 int set_val;
8440
8441 if (strcasecmp(val, "Enable") == 0) {
8442 set_val = 1;
8443 } else if (strcasecmp(val, "Disable") == 0) {
8444 set_val = 0;
8445 } else {
8446 send_resp(dut, conn, SIGMA_ERROR,
8447 "ErrorCode,Invalid TWT_ReqSupport");
8448 return STATUS_SENT;
8449 }
8450
8451 if (sta_set_twt_req_support(dut, intf, set_val)) {
8452 sigma_dut_print(dut, DUT_MSG_ERROR,
8453 "Failed to set TWT req support %d",
8454 set_val);
8455 send_resp(dut, conn, SIGMA_ERROR,
8456 "ErrorCode,Failed to set TWT_ReqSupport");
8457 return STATUS_SENT;
8458 }
8459 }
8460
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07008461 val = get_param(cmd, "MU_EDCA");
8462 if (val && (strcasecmp(val, "Override") == 0)) {
8463 if (sta_set_mu_edca_override(dut, intf, 1)) {
8464 send_resp(dut, conn, SIGMA_ERROR,
8465 "ErrorCode,Failed to set MU EDCA override");
8466 return 0;
8467 }
8468 }
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -07008469
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07008470 val = get_param(cmd, "OMControl");
8471 if (val) {
8472 int set_val = 1;
8473
8474 if (strcasecmp(val, "Enable") == 0)
8475 set_val = 1;
8476 else if (strcasecmp(val, "Disable") == 0)
8477 set_val = 0;
8478
8479 if (sta_set_om_ctrl_supp(dut, intf, set_val)) {
8480 send_resp(dut, conn, SIGMA_ERROR,
8481 "ErrorCode,Failed to set OM ctrl supp");
8482 return 0;
8483 }
8484 }
8485
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -07008486 val = get_param(cmd, "ADDBAResp_BufSize");
8487 if (val) {
8488 int buf_size;
8489
8490 if (strcasecmp(val, "gt64") == 0)
8491 buf_size = 256;
8492 else
8493 buf_size = 64;
8494 if (get_driver_type() == DRIVER_WCN &&
8495 sta_set_addba_buf_size(dut, intf, buf_size)) {
8496 send_resp(dut, conn, SIGMA_ERROR,
8497 "ErrorCode,set addbaresp_buff_size failed");
8498 return 0;
8499 }
8500 }
8501
8502 val = get_param(cmd, "ADDBAReq_BufSize");
8503 if (val) {
8504 int buf_size;
8505
8506 if (strcasecmp(val, "gt64") == 0)
8507 buf_size = 256;
8508 else
8509 buf_size = 64;
8510 if (get_driver_type() == DRIVER_WCN &&
8511 sta_set_addba_buf_size(dut, intf, buf_size)) {
8512 send_resp(dut, conn, SIGMA_ERROR,
8513 "ErrorCode,set addbareq_buff_size failed");
8514 return 0;
8515 }
8516 }
8517
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008518 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
8519}
8520
8521
8522static int sta_set_wireless_60g(struct sigma_dut *dut,
8523 struct sigma_conn *conn,
8524 struct sigma_cmd *cmd)
8525{
8526 const char *dev_role = get_param(cmd, "DevRole");
8527
8528 if (!dev_role) {
8529 send_resp(dut, conn, SIGMA_INVALID,
8530 "ErrorCode,DevRole not specified");
8531 return 0;
8532 }
8533
8534 if (strcasecmp(dev_role, "PCP") == 0)
8535 return sta_set_60g_pcp(dut, conn, cmd);
8536 if (strcasecmp(dev_role, "STA") == 0)
8537 return sta_set_60g_sta(dut, conn, cmd);
8538 send_resp(dut, conn, SIGMA_INVALID,
8539 "ErrorCode,DevRole not supported");
8540 return 0;
8541}
8542
8543
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05308544static int sta_set_wireless_oce(struct sigma_dut *dut, struct sigma_conn *conn,
8545 struct sigma_cmd *cmd)
8546{
8547 int status;
8548 const char *intf = get_param(cmd, "Interface");
8549 const char *val = get_param(cmd, "DevRole");
8550
8551 if (val && strcasecmp(val, "STA-CFON") == 0) {
8552 status = sta_cfon_set_wireless(dut, conn, cmd);
8553 if (status)
8554 return status;
8555 }
8556 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
8557}
8558
8559
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008560static int cmd_sta_set_wireless(struct sigma_dut *dut, struct sigma_conn *conn,
8561 struct sigma_cmd *cmd)
8562{
8563 const char *val;
8564
8565 val = get_param(cmd, "Program");
8566 if (val) {
8567 if (strcasecmp(val, "11n") == 0)
8568 return cmd_sta_set_11n(dut, conn, cmd);
Amarnath Hullur Subramanyam4f860292018-01-31 03:49:35 -08008569 if (strcasecmp(val, "VHT") == 0 || strcasecmp(val, "HE") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008570 return cmd_sta_set_wireless_vht(dut, conn, cmd);
8571 if (strcasecmp(val, "60ghz") == 0)
8572 return sta_set_wireless_60g(dut, conn, cmd);
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05308573 if (strcasecmp(val, "OCE") == 0)
8574 return sta_set_wireless_oce(dut, conn, cmd);
Alexei Avshalom Lazar66bb9972018-12-18 16:01:43 +02008575 /* sta_set_wireless in WPS program is only used for 60G */
8576 if (is_60g_sigma_dut(dut))
8577 return sta_set_wireless_60g(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008578 send_resp(dut, conn, SIGMA_ERROR,
8579 "ErrorCode,Program value not supported");
8580 } else {
8581 send_resp(dut, conn, SIGMA_ERROR,
8582 "ErrorCode,Program argument not available");
8583 }
8584
8585 return 0;
8586}
8587
8588
8589static void ath_sta_inject_frame(struct sigma_dut *dut, const char *intf,
8590 int tid)
8591{
8592 char buf[100];
8593 int tid_to_dscp [] = { 0x00, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0 };
8594
Pradeep Reddy POTTETId31d1322016-10-13 17:22:03 +05308595 if (tid < 0 ||
8596 tid >= (int) (sizeof(tid_to_dscp) / sizeof(tid_to_dscp[0]))) {
8597 sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported TID: %d", tid);
8598 return;
8599 }
8600
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008601 /*
8602 * Two ways to ensure that addba request with a
8603 * non zero TID could be sent out. EV 117296
8604 */
8605 snprintf(buf, sizeof(buf),
8606 "ping -c 8 -Q %d `arp -a | grep wlan0 | awk '{print $2}' | tr -d '()'`",
8607 tid);
8608 if (system(buf) != 0) {
8609 sigma_dut_print(dut, DUT_MSG_ERROR,
8610 "Ping did not send out");
8611 }
8612
8613 snprintf(buf, sizeof(buf),
8614 "iwconfig %s | grep Access | awk '{print $6}' > %s",
8615 intf, VI_QOS_TMP_FILE);
8616 if (system(buf) != 0)
8617 return;
8618
8619 snprintf(buf, sizeof(buf),
8620 "ifconfig %s | grep HWaddr | cut -b 39-56 >> %s",
8621 intf, VI_QOS_TMP_FILE);
8622 if (system(buf) != 0)
8623 sigma_dut_print(dut, DUT_MSG_ERROR, "HWaddr matching failed");
8624
8625 snprintf(buf,sizeof(buf), "sed -n '3,$p' %s >> %s",
8626 VI_QOS_REFFILE, VI_QOS_TMP_FILE);
8627 if (system(buf) != 0) {
8628 sigma_dut_print(dut, DUT_MSG_ERROR,
8629 "VI_QOS_TEMP_FILE generation error failed");
8630 }
8631 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
8632 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
8633 if (system(buf) != 0) {
8634 sigma_dut_print(dut, DUT_MSG_ERROR,
8635 "VI_QOS_FILE generation failed");
8636 }
8637
8638 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
8639 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
8640 if (system(buf) != 0) {
8641 sigma_dut_print(dut, DUT_MSG_ERROR,
8642 "VI_QOS_FILE generation failed");
8643 }
8644
8645 snprintf(buf, sizeof(buf), "ethinject %s %s", intf, VI_QOS_FILE);
8646 if (system(buf) != 0) {
8647 }
8648}
8649
8650
8651static int ath_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
8652 struct sigma_cmd *cmd)
8653{
8654 const char *intf = get_param(cmd, "Interface");
8655 const char *val;
8656 int tid = 0;
8657 char buf[100];
8658
8659 val = get_param(cmd, "TID");
8660 if (val) {
8661 tid = atoi(val);
8662 if (tid)
8663 ath_sta_inject_frame(dut, intf, tid);
8664 }
8665
8666 /* Command sequence for ADDBA request on Peregrine based devices */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008667 run_iwpriv(dut, intf, "setaddbaoper 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008668
8669 snprintf(buf, sizeof(buf), "wifitool %s senddelba 1 %d 1 4", intf, tid);
8670 if (system(buf) != 0) {
8671 sigma_dut_print(dut, DUT_MSG_ERROR,
8672 "wifitool senddelba failed");
8673 }
8674
8675 snprintf(buf, sizeof(buf), "wifitool %s sendaddba 1 %d 64", intf, tid);
8676 if (system(buf) != 0) {
8677 sigma_dut_print(dut, DUT_MSG_ERROR,
8678 "wifitool sendaddba failed");
8679 }
8680
8681 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
8682
8683 return 1;
8684}
8685
8686
Lior David9981b512017-01-20 13:16:40 +02008687#ifdef __linux__
8688
8689static int wil6210_send_addba(struct sigma_dut *dut, const char *dest_mac,
8690 int agg_size)
8691{
8692 char dir[128], buf[128];
8693 FILE *f;
8694 regex_t re;
8695 regmatch_t m[2];
8696 int rc, ret = -1, vring_id, found;
8697
8698 if (wil6210_get_debugfs_dir(dut, dir, sizeof(dir))) {
8699 sigma_dut_print(dut, DUT_MSG_ERROR,
8700 "failed to get wil6210 debugfs dir");
8701 return -1;
8702 }
8703
8704 snprintf(buf, sizeof(buf), "%s/vrings", dir);
8705 f = fopen(buf, "r");
8706 if (!f) {
8707 sigma_dut_print(dut, DUT_MSG_ERROR, "failed to open: %s", buf);
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +02008708 /* newer wil6210 driver renamed file to "rings" */
8709 snprintf(buf, sizeof(buf), "%s/rings", dir);
8710 f = fopen(buf, "r");
8711 if (!f) {
8712 sigma_dut_print(dut, DUT_MSG_ERROR,
8713 "failed to open: %s", buf);
8714 return -1;
8715 }
Lior David9981b512017-01-20 13:16:40 +02008716 }
8717
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +02008718 /* can be either VRING tx... or RING... */
8719 if (regcomp(&re, "RING tx_[ \t]*([0-9]+)", REG_EXTENDED)) {
Lior David9981b512017-01-20 13:16:40 +02008720 sigma_dut_print(dut, DUT_MSG_ERROR, "regcomp failed");
8721 goto out;
8722 }
8723
8724 /* find TX VRING for the mac address */
8725 found = 0;
8726 while (fgets(buf, sizeof(buf), f)) {
8727 if (strcasestr(buf, dest_mac)) {
8728 found = 1;
8729 break;
8730 }
8731 }
8732
8733 if (!found) {
8734 sigma_dut_print(dut, DUT_MSG_ERROR,
8735 "no TX VRING for %s", dest_mac);
8736 goto out;
8737 }
8738
8739 /* extract VRING ID, "VRING tx_<id> = {" */
8740 if (!fgets(buf, sizeof(buf), f)) {
8741 sigma_dut_print(dut, DUT_MSG_ERROR,
8742 "no VRING start line for %s", dest_mac);
8743 goto out;
8744 }
8745
8746 rc = regexec(&re, buf, 2, m, 0);
8747 regfree(&re);
8748 if (rc || m[1].rm_so < 0) {
8749 sigma_dut_print(dut, DUT_MSG_ERROR,
8750 "no VRING TX ID for %s", dest_mac);
8751 goto out;
8752 }
8753 buf[m[1].rm_eo] = 0;
8754 vring_id = atoi(&buf[m[1].rm_so]);
8755
8756 /* send the addba command */
8757 fclose(f);
8758 snprintf(buf, sizeof(buf), "%s/back", dir);
8759 f = fopen(buf, "w");
8760 if (!f) {
8761 sigma_dut_print(dut, DUT_MSG_ERROR,
8762 "failed to open: %s", buf);
8763 return -1;
8764 }
8765
8766 fprintf(f, "add %d %d\n", vring_id, agg_size);
8767
8768 ret = 0;
8769
8770out:
8771 fclose(f);
8772
8773 return ret;
8774}
8775
8776
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +02008777int send_addba_60g(struct sigma_dut *dut, struct sigma_conn *conn,
8778 struct sigma_cmd *cmd, const char *mac_param)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008779{
8780 const char *val;
8781 int tid = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008782
8783 val = get_param(cmd, "TID");
8784 if (val) {
8785 tid = atoi(val);
8786 if (tid != 0) {
8787 sigma_dut_print(dut, DUT_MSG_ERROR,
8788 "Ignore TID %d for send_addba use TID 0 for 60g since only 0 required on TX",
8789 tid);
8790 }
8791 }
8792
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +02008793 val = get_param(cmd, mac_param);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008794 if (!val) {
8795 sigma_dut_print(dut, DUT_MSG_ERROR,
8796 "Currently not supporting addba for 60G without Dest_mac");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02008797 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008798 }
8799
Lior David9981b512017-01-20 13:16:40 +02008800 if (wil6210_send_addba(dut, val, dut->back_rcv_buf))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008801 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008802
8803 return 1;
8804}
8805
Lior David9981b512017-01-20 13:16:40 +02008806#endif /* __linux__ */
8807
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008808
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08008809static int wcn_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
8810 struct sigma_cmd *cmd)
8811{
8812#ifdef NL80211_SUPPORT
8813 const char *intf = get_param(cmd, "Interface");
8814 const char *val;
8815 int tid = -1;
8816 int bufsize = 64;
8817 struct nl_msg *msg;
8818 int ret = 0;
8819 struct nlattr *params;
8820 int ifindex;
8821
8822 val = get_param(cmd, "TID");
8823 if (val)
8824 tid = atoi(val);
8825
8826 if (tid == -1) {
8827 send_resp(dut, conn, SIGMA_ERROR,
8828 "ErrorCode,sta_send_addba tid invalid");
8829 return 0;
8830 }
8831
8832 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
8833
8834 ifindex = if_nametoindex(intf);
8835 if (ifindex == 0) {
8836 sigma_dut_print(dut, DUT_MSG_ERROR,
8837 "%s: Index for interface %s failed",
8838 __func__, intf);
8839 send_resp(dut, conn, SIGMA_ERROR,
8840 "ErrorCode,sta_send_addba interface invalid");
8841 return 0;
8842 }
8843
8844 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8845 NL80211_CMD_VENDOR)) ||
8846 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
8847 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
8848 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
8849 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
8850 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8851 nla_put_u8(msg,
8852 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADD_DEL_BA_SESSION,
8853 QCA_WLAN_ADD_BA) ||
8854 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BA_TID,
8855 tid) ||
Kiran Kumar Lokere26e27582018-08-01 16:18:34 -07008856 nla_put_u16(msg,
8857 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE,
8858 bufsize)) {
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08008859 sigma_dut_print(dut, DUT_MSG_ERROR,
8860 "%s: err in adding vendor_cmd and vendor_data",
8861 __func__);
8862 nlmsg_free(msg);
8863 send_resp(dut, conn, SIGMA_ERROR,
8864 "ErrorCode,sta_send_addba err in adding vendor_cmd and vendor_data");
8865 return 0;
8866 }
8867 nla_nest_end(msg, params);
8868
8869 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
8870 if (ret) {
8871 sigma_dut_print(dut, DUT_MSG_ERROR,
8872 "%s: err in send_and_recv_msgs, ret=%d",
8873 __func__, ret);
Sunil Dutt30605592018-05-04 20:35:50 +05308874 if (ret == -EOPNOTSUPP)
8875 return 1;
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08008876 send_resp(dut, conn, SIGMA_ERROR,
8877 "ErrorCode,sta_send_addba err in send_and_recv_msgs");
8878 return 0;
8879 }
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08008880#else /* NL80211_SUPPORT */
8881 sigma_dut_print(dut, DUT_MSG_ERROR,
8882 "sta_send_addba not supported without NL80211_SUPPORT defined");
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08008883#endif /* NL80211_SUPPORT */
Sunil Dutt30605592018-05-04 20:35:50 +05308884
8885 return 1;
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08008886}
8887
8888
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008889static int cmd_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
8890 struct sigma_cmd *cmd)
8891{
8892 switch (get_driver_type()) {
8893 case DRIVER_ATHEROS:
8894 return ath_sta_send_addba(dut, conn, cmd);
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08008895 case DRIVER_WCN:
8896 return wcn_sta_send_addba(dut, conn, cmd);
Lior David9981b512017-01-20 13:16:40 +02008897#ifdef __linux__
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008898 case DRIVER_WIL6210:
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +02008899 return send_addba_60g(dut, conn, cmd, "Dest_mac");
Lior David9981b512017-01-20 13:16:40 +02008900#endif /* __linux__ */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008901 default:
8902 /*
8903 * There is no driver specific implementation for other drivers.
8904 * Ignore the command and report COMPLETE since the following
8905 * throughput test operation will end up sending ADDBA anyway.
8906 */
8907 return 1;
8908 }
8909}
8910
8911
8912int inject_eth_frame(int s, const void *data, size_t len,
8913 unsigned short ethtype, char *dst, char *src)
8914{
8915 struct iovec iov[4] = {
8916 {
8917 .iov_base = dst,
8918 .iov_len = ETH_ALEN,
8919 },
8920 {
8921 .iov_base = src,
8922 .iov_len = ETH_ALEN,
8923 },
8924 {
8925 .iov_base = &ethtype,
8926 .iov_len = sizeof(unsigned short),
8927 },
8928 {
8929 .iov_base = (void *) data,
8930 .iov_len = len,
8931 }
8932 };
8933 struct msghdr msg = {
8934 .msg_name = NULL,
8935 .msg_namelen = 0,
8936 .msg_iov = iov,
8937 .msg_iovlen = 4,
8938 .msg_control = NULL,
8939 .msg_controllen = 0,
8940 .msg_flags = 0,
8941 };
8942
8943 return sendmsg(s, &msg, 0);
8944}
8945
8946#if defined(__linux__) || defined(__QNXNTO__)
8947
8948int inject_frame(int s, const void *data, size_t len, int encrypt)
8949{
8950#define IEEE80211_RADIOTAP_F_WEP 0x04
8951#define IEEE80211_RADIOTAP_F_FRAG 0x08
8952 unsigned char rtap_hdr[] = {
8953 0x00, 0x00, /* radiotap version */
8954 0x0e, 0x00, /* radiotap length */
8955 0x02, 0xc0, 0x00, 0x00, /* bmap: flags, tx and rx flags */
8956 IEEE80211_RADIOTAP_F_FRAG, /* F_FRAG (fragment if required) */
8957 0x00, /* padding */
8958 0x00, 0x00, /* RX and TX flags to indicate that */
8959 0x00, 0x00, /* this is the injected frame directly */
8960 };
8961 struct iovec iov[2] = {
8962 {
8963 .iov_base = &rtap_hdr,
8964 .iov_len = sizeof(rtap_hdr),
8965 },
8966 {
8967 .iov_base = (void *) data,
8968 .iov_len = len,
8969 }
8970 };
8971 struct msghdr msg = {
8972 .msg_name = NULL,
8973 .msg_namelen = 0,
8974 .msg_iov = iov,
8975 .msg_iovlen = 2,
8976 .msg_control = NULL,
8977 .msg_controllen = 0,
8978 .msg_flags = 0,
8979 };
8980
8981 if (encrypt)
8982 rtap_hdr[8] |= IEEE80211_RADIOTAP_F_WEP;
8983
8984 return sendmsg(s, &msg, 0);
8985}
8986
8987
8988int open_monitor(const char *ifname)
8989{
8990#ifdef __QNXNTO__
8991 struct sockaddr_dl ll;
8992 int s;
8993
8994 memset(&ll, 0, sizeof(ll));
8995 ll.sdl_family = AF_LINK;
8996 ll.sdl_index = if_nametoindex(ifname);
8997 if (ll.sdl_index == 0) {
8998 perror("if_nametoindex");
8999 return -1;
9000 }
9001 s = socket(PF_INET, SOCK_RAW, 0);
9002#else /* __QNXNTO__ */
9003 struct sockaddr_ll ll;
9004 int s;
9005
9006 memset(&ll, 0, sizeof(ll));
9007 ll.sll_family = AF_PACKET;
9008 ll.sll_ifindex = if_nametoindex(ifname);
9009 if (ll.sll_ifindex == 0) {
9010 perror("if_nametoindex");
9011 return -1;
9012 }
9013 s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
9014#endif /* __QNXNTO__ */
9015 if (s < 0) {
9016 perror("socket[PF_PACKET,SOCK_RAW]");
9017 return -1;
9018 }
9019
9020 if (bind(s, (struct sockaddr *) &ll, sizeof(ll)) < 0) {
9021 perror("monitor socket bind");
9022 close(s);
9023 return -1;
9024 }
9025
9026 return s;
9027}
9028
9029
9030static int hex2num(char c)
9031{
9032 if (c >= '0' && c <= '9')
9033 return c - '0';
9034 if (c >= 'a' && c <= 'f')
9035 return c - 'a' + 10;
9036 if (c >= 'A' && c <= 'F')
9037 return c - 'A' + 10;
9038 return -1;
9039}
9040
9041
9042int hwaddr_aton(const char *txt, unsigned char *addr)
9043{
9044 int i;
9045
9046 for (i = 0; i < 6; i++) {
9047 int a, b;
9048
9049 a = hex2num(*txt++);
9050 if (a < 0)
9051 return -1;
9052 b = hex2num(*txt++);
9053 if (b < 0)
9054 return -1;
9055 *addr++ = (a << 4) | b;
9056 if (i < 5 && *txt++ != ':')
9057 return -1;
9058 }
9059
9060 return 0;
9061}
9062
9063#endif /* defined(__linux__) || defined(__QNXNTO__) */
9064
9065enum send_frame_type {
9066 DISASSOC, DEAUTH, SAQUERY, AUTH, ASSOCREQ, REASSOCREQ, DLS_REQ
9067};
9068enum send_frame_protection {
9069 CORRECT_KEY, INCORRECT_KEY, UNPROTECTED
9070};
9071
9072
9073static int sta_inject_frame(struct sigma_dut *dut, struct sigma_conn *conn,
9074 enum send_frame_type frame,
9075 enum send_frame_protection protected,
9076 const char *dest)
9077{
9078#ifdef __linux__
9079 unsigned char buf[1000], *pos;
9080 int s, res;
9081 char bssid[20], addr[20];
9082 char result[32], ssid[100];
9083 size_t ssid_len;
9084
9085 if (get_wpa_status(get_station_ifname(), "wpa_state", result,
9086 sizeof(result)) < 0 ||
9087 strncmp(result, "COMPLETED", 9) != 0) {
9088 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Not connected");
9089 return 0;
9090 }
9091
9092 if (get_wpa_status(get_station_ifname(), "bssid", bssid, sizeof(bssid))
9093 < 0) {
9094 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
9095 "current BSSID");
9096 return 0;
9097 }
9098
9099 if (get_wpa_status(get_station_ifname(), "address", addr, sizeof(addr))
9100 < 0) {
9101 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
9102 "own MAC address");
9103 return 0;
9104 }
9105
9106 if (get_wpa_status(get_station_ifname(), "ssid", ssid, sizeof(ssid))
9107 < 0) {
9108 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
9109 "current SSID");
9110 return 0;
9111 }
9112 ssid_len = strlen(ssid);
9113
9114 pos = buf;
9115
9116 /* Frame Control */
9117 switch (frame) {
9118 case DISASSOC:
9119 *pos++ = 0xa0;
9120 break;
9121 case DEAUTH:
9122 *pos++ = 0xc0;
9123 break;
9124 case SAQUERY:
9125 *pos++ = 0xd0;
9126 break;
9127 case AUTH:
9128 *pos++ = 0xb0;
9129 break;
9130 case ASSOCREQ:
9131 *pos++ = 0x00;
9132 break;
9133 case REASSOCREQ:
9134 *pos++ = 0x20;
9135 break;
9136 case DLS_REQ:
9137 *pos++ = 0xd0;
9138 break;
9139 }
9140
9141 if (protected == INCORRECT_KEY)
9142 *pos++ = 0x40; /* Set Protected field to 1 */
9143 else
9144 *pos++ = 0x00;
9145
9146 /* Duration */
9147 *pos++ = 0x00;
9148 *pos++ = 0x00;
9149
9150 /* addr1 = DA (current AP) */
9151 hwaddr_aton(bssid, pos);
9152 pos += 6;
9153 /* addr2 = SA (own address) */
9154 hwaddr_aton(addr, pos);
9155 pos += 6;
9156 /* addr3 = BSSID (current AP) */
9157 hwaddr_aton(bssid, pos);
9158 pos += 6;
9159
9160 /* Seq# (to be filled by driver/mac80211) */
9161 *pos++ = 0x00;
9162 *pos++ = 0x00;
9163
9164 if (protected == INCORRECT_KEY) {
9165 /* CCMP parameters */
9166 memcpy(pos, "\x61\x01\x00\x20\x00\x10\x00\x00", 8);
9167 pos += 8;
9168 }
9169
9170 if (protected == INCORRECT_KEY) {
9171 switch (frame) {
9172 case DEAUTH:
9173 /* Reason code (encrypted) */
9174 memcpy(pos, "\xa7\x39", 2);
9175 pos += 2;
9176 break;
9177 case DISASSOC:
9178 /* Reason code (encrypted) */
9179 memcpy(pos, "\xa7\x39", 2);
9180 pos += 2;
9181 break;
9182 case SAQUERY:
9183 /* Category|Action|TransID (encrypted) */
9184 memcpy(pos, "\x6f\xbd\xe9\x4d", 4);
9185 pos += 4;
9186 break;
9187 default:
9188 return -1;
9189 }
9190
9191 /* CCMP MIC */
9192 memcpy(pos, "\xc8\xd8\x3b\x06\x5d\xb7\x25\x68", 8);
9193 pos += 8;
9194 } else {
9195 switch (frame) {
9196 case DEAUTH:
9197 /* reason code = 8 */
9198 *pos++ = 0x08;
9199 *pos++ = 0x00;
9200 break;
9201 case DISASSOC:
9202 /* reason code = 8 */
9203 *pos++ = 0x08;
9204 *pos++ = 0x00;
9205 break;
9206 case SAQUERY:
9207 /* Category - SA Query */
9208 *pos++ = 0x08;
9209 /* SA query Action - Request */
9210 *pos++ = 0x00;
9211 /* Transaction ID */
9212 *pos++ = 0x12;
9213 *pos++ = 0x34;
9214 break;
9215 case AUTH:
9216 /* Auth Alg (Open) */
9217 *pos++ = 0x00;
9218 *pos++ = 0x00;
9219 /* Seq# */
9220 *pos++ = 0x01;
9221 *pos++ = 0x00;
9222 /* Status code */
9223 *pos++ = 0x00;
9224 *pos++ = 0x00;
9225 break;
9226 case ASSOCREQ:
9227 /* Capability Information */
9228 *pos++ = 0x31;
9229 *pos++ = 0x04;
9230 /* Listen Interval */
9231 *pos++ = 0x0a;
9232 *pos++ = 0x00;
9233 /* SSID */
9234 *pos++ = 0x00;
9235 *pos++ = ssid_len;
9236 memcpy(pos, ssid, ssid_len);
9237 pos += ssid_len;
9238 /* Supported Rates */
9239 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
9240 10);
9241 pos += 10;
9242 /* Extended Supported Rates */
9243 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
9244 pos += 6;
9245 /* RSN */
9246 memcpy(pos, "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00"
9247 "\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x02\xc0"
9248 "\x00\x00\x00\x00\x0f\xac\x06", 28);
9249 pos += 28;
9250 break;
9251 case REASSOCREQ:
9252 /* Capability Information */
9253 *pos++ = 0x31;
9254 *pos++ = 0x04;
9255 /* Listen Interval */
9256 *pos++ = 0x0a;
9257 *pos++ = 0x00;
9258 /* Current AP */
9259 hwaddr_aton(bssid, pos);
9260 pos += 6;
9261 /* SSID */
9262 *pos++ = 0x00;
9263 *pos++ = ssid_len;
9264 memcpy(pos, ssid, ssid_len);
9265 pos += ssid_len;
9266 /* Supported Rates */
9267 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
9268 10);
9269 pos += 10;
9270 /* Extended Supported Rates */
9271 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
9272 pos += 6;
9273 /* RSN */
9274 memcpy(pos, "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00"
9275 "\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x02\xc0"
9276 "\x00\x00\x00\x00\x0f\xac\x06", 28);
9277 pos += 28;
9278 break;
9279 case DLS_REQ:
9280 /* Category - DLS */
9281 *pos++ = 0x02;
9282 /* DLS Action - Request */
9283 *pos++ = 0x00;
9284 /* Destination MACAddress */
9285 if (dest)
9286 hwaddr_aton(dest, pos);
9287 else
9288 memset(pos, 0, 6);
9289 pos += 6;
9290 /* Source MACAddress */
9291 hwaddr_aton(addr, pos);
9292 pos += 6;
9293 /* Capability Information */
9294 *pos++ = 0x10; /* Privacy */
9295 *pos++ = 0x06; /* QoS */
9296 /* DLS Timeout Value */
9297 *pos++ = 0x00;
9298 *pos++ = 0x01;
9299 /* Supported rates */
9300 *pos++ = 0x01;
9301 *pos++ = 0x08;
9302 *pos++ = 0x0c; /* 6 Mbps */
9303 *pos++ = 0x12; /* 9 Mbps */
9304 *pos++ = 0x18; /* 12 Mbps */
9305 *pos++ = 0x24; /* 18 Mbps */
9306 *pos++ = 0x30; /* 24 Mbps */
9307 *pos++ = 0x48; /* 36 Mbps */
9308 *pos++ = 0x60; /* 48 Mbps */
9309 *pos++ = 0x6c; /* 54 Mbps */
9310 /* TODO: Extended Supported Rates */
9311 /* TODO: HT Capabilities */
9312 break;
9313 }
9314 }
9315
9316 s = open_monitor("sigmadut");
9317 if (s < 0) {
9318 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
9319 "monitor socket");
9320 return 0;
9321 }
9322
9323 res = inject_frame(s, buf, pos - buf, protected == CORRECT_KEY);
9324 if (res < 0) {
9325 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
9326 "inject frame");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05309327 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009328 return 0;
9329 }
9330 if (res < pos - buf) {
9331 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Only partial "
9332 "frame sent");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05309333 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009334 return 0;
9335 }
9336
9337 close(s);
9338
9339 return 1;
9340#else /* __linux__ */
9341 send_resp(dut, conn, SIGMA_ERROR, "errorCode,sta_send_frame not "
9342 "yet supported");
9343 return 0;
9344#endif /* __linux__ */
9345}
9346
9347
9348static int cmd_sta_send_frame_tdls(struct sigma_dut *dut,
9349 struct sigma_conn *conn,
9350 struct sigma_cmd *cmd)
9351{
9352 const char *intf = get_param(cmd, "Interface");
9353 const char *sta, *val;
9354 unsigned char addr[ETH_ALEN];
9355 char buf[100];
9356
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +03009357 if (!intf)
9358 return -1;
9359
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009360 sta = get_param(cmd, "peer");
9361 if (sta == NULL)
9362 sta = get_param(cmd, "station");
9363 if (sta == NULL) {
9364 send_resp(dut, conn, SIGMA_ERROR,
9365 "ErrorCode,Missing peer address");
9366 return 0;
9367 }
9368 if (hwaddr_aton(sta, addr) < 0) {
9369 send_resp(dut, conn, SIGMA_ERROR,
9370 "ErrorCode,Invalid peer address");
9371 return 0;
9372 }
9373
9374 val = get_param(cmd, "type");
9375 if (val == NULL)
9376 return -1;
9377
9378 if (strcasecmp(val, "DISCOVERY") == 0) {
9379 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", sta);
9380 if (wpa_command(intf, buf) < 0) {
9381 send_resp(dut, conn, SIGMA_ERROR,
9382 "ErrorCode,Failed to send TDLS discovery");
9383 return 0;
9384 }
9385 return 1;
9386 }
9387
9388 if (strcasecmp(val, "SETUP") == 0) {
9389 int status = 0, timeout = 0;
9390
9391 val = get_param(cmd, "Status");
9392 if (val)
9393 status = atoi(val);
9394
9395 val = get_param(cmd, "Timeout");
9396 if (val)
9397 timeout = atoi(val);
9398
9399 if (status != 0 && status != 37) {
9400 send_resp(dut, conn, SIGMA_ERROR,
9401 "ErrorCode,Unsupported status value");
9402 return 0;
9403 }
9404
9405 if (timeout != 0 && timeout != 301) {
9406 send_resp(dut, conn, SIGMA_ERROR,
9407 "ErrorCode,Unsupported timeout value");
9408 return 0;
9409 }
9410
9411 if (status && timeout) {
9412 send_resp(dut, conn, SIGMA_ERROR,
9413 "ErrorCode,Unsupported timeout+status "
9414 "combination");
9415 return 0;
9416 }
9417
9418 if (status == 37 &&
9419 wpa_command(intf, "SET tdls_testing 0x200")) {
9420 send_resp(dut, conn, SIGMA_ERROR,
9421 "ErrorCode,Failed to enable "
9422 "decline setup response test mode");
9423 return 0;
9424 }
9425
9426 if (timeout == 301) {
9427 int res;
9428 if (dut->no_tpk_expiration)
9429 res = wpa_command(intf,
9430 "SET tdls_testing 0x108");
9431 else
9432 res = wpa_command(intf,
9433 "SET tdls_testing 0x8");
9434 if (res) {
9435 send_resp(dut, conn, SIGMA_ERROR,
9436 "ErrorCode,Failed to set short TPK "
9437 "lifetime");
9438 return 0;
9439 }
9440 }
9441
9442 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", sta);
9443 if (wpa_command(intf, buf) < 0) {
9444 send_resp(dut, conn, SIGMA_ERROR,
9445 "ErrorCode,Failed to send TDLS setup");
9446 return 0;
9447 }
9448 return 1;
9449 }
9450
9451 if (strcasecmp(val, "TEARDOWN") == 0) {
9452 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", sta);
9453 if (wpa_command(intf, buf) < 0) {
9454 send_resp(dut, conn, SIGMA_ERROR,
9455 "ErrorCode,Failed to send TDLS teardown");
9456 return 0;
9457 }
9458 return 1;
9459 }
9460
9461 send_resp(dut, conn, SIGMA_ERROR,
9462 "ErrorCode,Unsupported TDLS frame");
9463 return 0;
9464}
9465
9466
9467static int sta_ap_known(const char *ifname, const char *bssid)
9468{
9469 char buf[4096];
9470
Jouni Malinendd32f192018-09-15 02:55:19 +03009471 snprintf(buf, sizeof(buf), "BSS MASK=1 %s", bssid);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009472 if (wpa_command_resp(ifname, buf, buf, sizeof(buf)) < 0)
9473 return 0;
9474 if (strncmp(buf, "id=", 3) != 0)
9475 return 0;
9476 return 1;
9477}
9478
9479
9480static int sta_scan_ap(struct sigma_dut *dut, const char *ifname,
9481 const char *bssid)
9482{
9483 int res;
9484 struct wpa_ctrl *ctrl;
9485 char buf[256];
9486
9487 if (sta_ap_known(ifname, bssid))
9488 return 0;
9489 sigma_dut_print(dut, DUT_MSG_DEBUG,
9490 "AP not in BSS table - start scan");
9491
9492 ctrl = open_wpa_mon(ifname);
9493 if (ctrl == NULL) {
9494 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
9495 "wpa_supplicant monitor connection");
9496 return -1;
9497 }
9498
9499 if (wpa_command(ifname, "SCAN") < 0) {
9500 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to start scan");
9501 wpa_ctrl_detach(ctrl);
9502 wpa_ctrl_close(ctrl);
9503 return -1;
9504 }
9505
9506 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
9507 buf, sizeof(buf));
9508
9509 wpa_ctrl_detach(ctrl);
9510 wpa_ctrl_close(ctrl);
9511
9512 if (res < 0) {
9513 sigma_dut_print(dut, DUT_MSG_INFO, "Scan did not complete");
9514 return -1;
9515 }
9516
9517 if (sta_ap_known(ifname, bssid))
9518 return 0;
9519 sigma_dut_print(dut, DUT_MSG_INFO, "AP not in BSS table");
9520 return -1;
9521}
9522
9523
9524static int cmd_sta_send_frame_hs2_neighadv(struct sigma_dut *dut,
9525 struct sigma_conn *conn,
9526 struct sigma_cmd *cmd,
9527 const char *intf)
9528{
9529 char buf[200];
9530
9531 snprintf(buf, sizeof(buf), "ndsend 2001:DB8::1 %s", intf);
9532 if (system(buf) != 0) {
9533 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Failed to run "
9534 "ndsend");
9535 return 0;
9536 }
9537
9538 return 1;
9539}
9540
9541
9542static int cmd_sta_send_frame_hs2_neighsolreq(struct sigma_dut *dut,
9543 struct sigma_conn *conn,
9544 struct sigma_cmd *cmd,
9545 const char *intf)
9546{
9547 char buf[200];
9548 const char *ip = get_param(cmd, "SenderIP");
9549
Peng Xu26b356d2017-10-04 17:58:16 -07009550 if (!ip)
9551 return 0;
9552
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009553 snprintf(buf, sizeof(buf), "ndisc6 -nm %s %s -r 4", ip, intf);
9554 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
9555 if (system(buf) == 0) {
9556 sigma_dut_print(dut, DUT_MSG_INFO,
9557 "Neighbor Solicitation got a response "
9558 "for %s@%s", ip, intf);
9559 }
9560
9561 return 1;
9562}
9563
9564
9565static int cmd_sta_send_frame_hs2_arpprobe(struct sigma_dut *dut,
9566 struct sigma_conn *conn,
9567 struct sigma_cmd *cmd,
9568 const char *ifname)
9569{
9570 char buf[200];
9571 const char *ip = get_param(cmd, "SenderIP");
9572
9573 if (ip == NULL) {
9574 send_resp(dut, conn, SIGMA_ERROR,
9575 "ErrorCode,Missing SenderIP parameter");
9576 return 0;
9577 }
9578 snprintf(buf, sizeof(buf), "arping -I %s -D %s -c 4", ifname, ip);
9579 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
9580 if (system(buf) != 0) {
9581 sigma_dut_print(dut, DUT_MSG_INFO, "arping DAD got a response "
9582 "for %s@%s", ip, ifname);
9583 }
9584
9585 return 1;
9586}
9587
9588
9589static int cmd_sta_send_frame_hs2_arpannounce(struct sigma_dut *dut,
9590 struct sigma_conn *conn,
9591 struct sigma_cmd *cmd,
9592 const char *ifname)
9593{
9594 char buf[200];
9595 char ip[16];
9596 int s;
Peng Xub3756882017-10-04 14:39:09 -07009597 struct ifreq ifr;
9598 struct sockaddr_in saddr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009599
9600 s = socket(PF_INET, SOCK_DGRAM, 0);
Peng Xub3756882017-10-04 14:39:09 -07009601 if (s < 0) {
9602 perror("socket");
9603 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009604 }
9605
Peng Xub3756882017-10-04 14:39:09 -07009606 memset(&ifr, 0, sizeof(ifr));
9607 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
9608 if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
9609 sigma_dut_print(dut, DUT_MSG_INFO,
9610 "Failed to get %s IP address: %s",
9611 ifname, strerror(errno));
9612 close(s);
9613 return -1;
9614 }
9615 close(s);
9616
9617 memcpy(&saddr, &ifr.ifr_addr, sizeof(struct sockaddr_in));
9618 strlcpy(ip, inet_ntoa(saddr.sin_addr), sizeof(ip));
9619
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009620 snprintf(buf, sizeof(buf), "arping -I %s -s %s %s -c 4", ifname, ip,
9621 ip);
9622 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
9623 if (system(buf) != 0) {
9624 }
9625
9626 return 1;
9627}
9628
9629
9630static int cmd_sta_send_frame_hs2_arpreply(struct sigma_dut *dut,
9631 struct sigma_conn *conn,
9632 struct sigma_cmd *cmd,
9633 const char *ifname)
9634{
9635 char buf[200], addr[20];
9636 char dst[ETH_ALEN], src[ETH_ALEN];
9637 short ethtype = htons(ETH_P_ARP);
9638 char *pos;
9639 int s, res;
9640 const char *val;
9641 struct sockaddr_in taddr;
9642
9643 val = get_param(cmd, "dest");
9644 if (val)
9645 hwaddr_aton(val, (unsigned char *) dst);
9646
9647 val = get_param(cmd, "DestIP");
9648 if (val)
9649 inet_aton(val, &taddr.sin_addr);
Peng Xu151c9e12017-10-04 14:39:09 -07009650 else
9651 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009652
9653 if (get_wpa_status(get_station_ifname(), "address", addr,
9654 sizeof(addr)) < 0)
9655 return -2;
9656 hwaddr_aton(addr, (unsigned char *) src);
9657
9658 pos = buf;
9659 *pos++ = 0x00;
9660 *pos++ = 0x01;
9661 *pos++ = 0x08;
9662 *pos++ = 0x00;
9663 *pos++ = 0x06;
9664 *pos++ = 0x04;
9665 *pos++ = 0x00;
9666 *pos++ = 0x02;
9667 memcpy(pos, src, ETH_ALEN);
9668 pos += ETH_ALEN;
9669 memcpy(pos, &taddr.sin_addr, 4);
9670 pos += 4;
9671 memcpy(pos, dst, ETH_ALEN);
9672 pos += ETH_ALEN;
9673 memcpy(pos, &taddr.sin_addr, 4);
9674 pos += 4;
9675
9676 s = open_monitor(get_station_ifname());
9677 if (s < 0) {
9678 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
9679 "monitor socket");
9680 return 0;
9681 }
9682
9683 res = inject_eth_frame(s, buf, pos - buf, ethtype, dst, src);
9684 if (res < 0) {
9685 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
9686 "inject frame");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05309687 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009688 return 0;
9689 }
9690
9691 close(s);
9692
9693 return 1;
9694}
9695
9696
9697static int cmd_sta_send_frame_hs2_dls_req(struct sigma_dut *dut,
9698 struct sigma_conn *conn,
9699 struct sigma_cmd *cmd,
9700 const char *intf, const char *dest)
9701{
9702 char buf[100];
9703
9704 if (if_nametoindex("sigmadut") == 0) {
9705 snprintf(buf, sizeof(buf),
9706 "iw dev %s interface add sigmadut type monitor",
9707 get_station_ifname());
9708 if (system(buf) != 0 ||
9709 if_nametoindex("sigmadut") == 0) {
9710 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
9711 "monitor interface with '%s'", buf);
9712 return -2;
9713 }
9714 }
9715
9716 if (system("ifconfig sigmadut up") != 0) {
9717 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
9718 "monitor interface up");
9719 return -2;
9720 }
9721
9722 return sta_inject_frame(dut, conn, DLS_REQ, UNPROTECTED, dest);
9723}
9724
9725
9726static int cmd_sta_send_frame_hs2(struct sigma_dut *dut,
9727 struct sigma_conn *conn,
9728 struct sigma_cmd *cmd)
9729{
9730 const char *intf = get_param(cmd, "Interface");
9731 const char *dest = get_param(cmd, "Dest");
9732 const char *type = get_param(cmd, "FrameName");
9733 const char *val;
9734 char buf[200], *pos, *end;
9735 int count, count2;
9736
9737 if (type == NULL)
9738 type = get_param(cmd, "Type");
9739
9740 if (intf == NULL || dest == NULL || type == NULL)
9741 return -1;
9742
9743 if (strcasecmp(type, "NeighAdv") == 0)
9744 return cmd_sta_send_frame_hs2_neighadv(dut, conn, cmd, intf);
9745
9746 if (strcasecmp(type, "NeighSolicitReq") == 0)
9747 return cmd_sta_send_frame_hs2_neighsolreq(dut, conn, cmd, intf);
9748
9749 if (strcasecmp(type, "ARPProbe") == 0)
9750 return cmd_sta_send_frame_hs2_arpprobe(dut, conn, cmd, intf);
9751
9752 if (strcasecmp(type, "ARPAnnounce") == 0)
9753 return cmd_sta_send_frame_hs2_arpannounce(dut, conn, cmd, intf);
9754
9755 if (strcasecmp(type, "ARPReply") == 0)
9756 return cmd_sta_send_frame_hs2_arpreply(dut, conn, cmd, intf);
9757
9758 if (strcasecmp(type, "DLS-request") == 0 ||
9759 strcasecmp(type, "DLSrequest") == 0)
9760 return cmd_sta_send_frame_hs2_dls_req(dut, conn, cmd, intf,
9761 dest);
9762
9763 if (strcasecmp(type, "ANQPQuery") != 0 &&
9764 strcasecmp(type, "Query") != 0) {
9765 send_resp(dut, conn, SIGMA_ERROR,
9766 "ErrorCode,Unsupported HS 2.0 send frame type");
9767 return 0;
9768 }
9769
9770 if (sta_scan_ap(dut, intf, dest) < 0) {
9771 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not find "
9772 "the requested AP");
9773 return 0;
9774 }
9775
9776 pos = buf;
9777 end = buf + sizeof(buf);
9778 count = 0;
9779 pos += snprintf(pos, end - pos, "ANQP_GET %s ", dest);
9780
9781 val = get_param(cmd, "ANQP_CAP_LIST");
9782 if (val && atoi(val)) {
9783 pos += snprintf(pos, end - pos, "%s257", count > 0 ? "," : "");
9784 count++;
9785 }
9786
9787 val = get_param(cmd, "VENUE_NAME");
9788 if (val && atoi(val)) {
9789 pos += snprintf(pos, end - pos, "%s258", count > 0 ? "," : "");
9790 count++;
9791 }
9792
9793 val = get_param(cmd, "NETWORK_AUTH_TYPE");
9794 if (val && atoi(val)) {
9795 pos += snprintf(pos, end - pos, "%s260", count > 0 ? "," : "");
9796 count++;
9797 }
9798
9799 val = get_param(cmd, "ROAMING_CONS");
9800 if (val && atoi(val)) {
9801 pos += snprintf(pos, end - pos, "%s261", count > 0 ? "," : "");
9802 count++;
9803 }
9804
9805 val = get_param(cmd, "IP_ADDR_TYPE_AVAILABILITY");
9806 if (val && atoi(val)) {
9807 pos += snprintf(pos, end - pos, "%s262", count > 0 ? "," : "");
9808 count++;
9809 }
9810
9811 val = get_param(cmd, "NAI_REALM_LIST");
9812 if (val && atoi(val)) {
9813 pos += snprintf(pos, end - pos, "%s263", count > 0 ? "," : "");
9814 count++;
9815 }
9816
9817 val = get_param(cmd, "3GPP_INFO");
9818 if (val && atoi(val)) {
9819 pos += snprintf(pos, end - pos, "%s264", count > 0 ? "," : "");
9820 count++;
9821 }
9822
9823 val = get_param(cmd, "DOMAIN_LIST");
9824 if (val && atoi(val)) {
9825 pos += snprintf(pos, end - pos, "%s268", count > 0 ? "," : "");
9826 count++;
9827 }
9828
Jouni Malinen34cf9532018-04-29 19:26:33 +03009829 val = get_param(cmd, "Venue_URL");
9830 if (val && atoi(val)) {
9831 pos += snprintf(pos, end - pos, "%s277", count > 0 ? "," : "");
9832 count++;
9833 }
9834
Jouni Malinend3bca5d2018-04-29 17:25:23 +03009835 val = get_param(cmd, "Advice_Of_Charge");
9836 if (val && atoi(val)) {
9837 pos += snprintf(pos, end - pos, "%s278", count > 0 ? "," : "");
9838 count++;
9839 }
9840
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009841 if (count && wpa_command(intf, buf)) {
9842 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,ANQP_GET failed");
9843 return 0;
9844 }
9845
9846 pos = buf;
9847 end = buf + sizeof(buf);
9848 count2 = 0;
9849 pos += snprintf(pos, end - pos, "HS20_ANQP_GET %s ", dest);
9850
9851 val = get_param(cmd, "HS_CAP_LIST");
9852 if (val && atoi(val)) {
9853 pos += snprintf(pos, end - pos, "%s2", count2 > 0 ? "," : "");
9854 count2++;
9855 }
9856
9857 val = get_param(cmd, "OPER_NAME");
9858 if (val && atoi(val)) {
9859 pos += snprintf(pos, end - pos, "%s3", count2 > 0 ? "," : "");
9860 count2++;
9861 }
9862
9863 val = get_param(cmd, "WAN_METRICS");
9864 if (!val)
9865 val = get_param(cmd, "WAN_MAT");
9866 if (!val)
9867 val = get_param(cmd, "WAN_MET");
9868 if (val && atoi(val)) {
9869 pos += snprintf(pos, end - pos, "%s4", count2 > 0 ? "," : "");
9870 count2++;
9871 }
9872
9873 val = get_param(cmd, "CONNECTION_CAPABILITY");
9874 if (val && atoi(val)) {
9875 pos += snprintf(pos, end - pos, "%s5", count2 > 0 ? "," : "");
9876 count2++;
9877 }
9878
9879 val = get_param(cmd, "OP_CLASS");
9880 if (val && atoi(val)) {
9881 pos += snprintf(pos, end - pos, "%s7", count2 > 0 ? "," : "");
9882 count2++;
9883 }
9884
9885 val = get_param(cmd, "OSU_PROVIDER_LIST");
9886 if (val && atoi(val)) {
9887 pos += snprintf(pos, end - pos, "%s8", count2 > 0 ? "," : "");
9888 count2++;
9889 }
9890
Jouni Malinenf67afec2018-04-29 19:24:58 +03009891 val = get_param(cmd, "OPER_ICON_METADATA");
9892 if (!val)
9893 val = get_param(cmd, "OPERATOR_ICON_METADATA");
9894 if (val && atoi(val)) {
9895 pos += snprintf(pos, end - pos, "%s12", count2 > 0 ? "," : "");
9896 count2++;
9897 }
9898
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009899 if (count && count2) {
9900 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before sending out "
9901 "second query");
9902 sleep(1);
9903 }
9904
9905 if (count2 && wpa_command(intf, buf)) {
9906 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,HS20_ANQP_GET "
9907 "failed");
9908 return 0;
9909 }
9910
9911 val = get_param(cmd, "NAI_HOME_REALM_LIST");
9912 if (val) {
9913 if (count || count2) {
9914 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
9915 "sending out second query");
9916 sleep(1);
9917 }
9918
9919 if (strcmp(val, "1") == 0)
9920 val = "mail.example.com";
9921 snprintf(buf, end - pos,
9922 "HS20_GET_NAI_HOME_REALM_LIST %s realm=%s",
9923 dest, val);
9924 if (wpa_command(intf, buf)) {
9925 send_resp(dut, conn, SIGMA_ERROR,
9926 "ErrorCode,HS20_GET_NAI_HOME_REALM_LIST "
9927 "failed");
9928 return 0;
9929 }
9930 }
9931
9932 val = get_param(cmd, "ICON_REQUEST");
9933 if (val) {
9934 if (count || count2) {
9935 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
9936 "sending out second query");
9937 sleep(1);
9938 }
9939
9940 snprintf(buf, end - pos,
9941 "HS20_ICON_REQUEST %s %s", dest, val);
9942 if (wpa_command(intf, buf)) {
9943 send_resp(dut, conn, SIGMA_ERROR,
9944 "ErrorCode,HS20_ICON_REQUEST failed");
9945 return 0;
9946 }
9947 }
9948
9949 return 1;
9950}
9951
9952
9953static int ath_sta_send_frame_vht(struct sigma_dut *dut,
9954 struct sigma_conn *conn,
9955 struct sigma_cmd *cmd)
9956{
9957 const char *val;
9958 char *ifname;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009959 int chwidth, nss;
9960
9961 val = get_param(cmd, "framename");
9962 if (!val)
9963 return -1;
9964 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
9965
9966 /* Command sequence to generate Op mode notification */
9967 if (val && strcasecmp(val, "Op_md_notif_frm") == 0) {
9968 ifname = get_station_ifname();
9969
9970 /* Disable STBC */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07009971 run_iwpriv(dut, ifname, "tx_stbc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009972
9973 /* Extract Channel width */
9974 val = get_param(cmd, "Channel_width");
9975 if (val) {
9976 switch (atoi(val)) {
9977 case 20:
9978 chwidth = 0;
9979 break;
9980 case 40:
9981 chwidth = 1;
9982 break;
9983 case 80:
9984 chwidth = 2;
9985 break;
9986 case 160:
9987 chwidth = 3;
9988 break;
9989 default:
9990 chwidth = 2;
9991 break;
9992 }
9993
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07009994 run_iwpriv(dut, ifname, "chwidth %d", chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009995 }
9996
9997 /* Extract NSS */
9998 val = get_param(cmd, "NSS");
9999 if (val) {
10000 switch (atoi(val)) {
10001 case 1:
10002 nss = 1;
10003 break;
10004 case 2:
10005 nss = 3;
10006 break;
10007 case 3:
10008 nss = 7;
10009 break;
10010 default:
10011 /* We do not support NSS > 3 */
10012 nss = 3;
10013 break;
10014 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010015 run_iwpriv(dut, ifname, "rxchainmask %d", nss);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010016 }
10017
10018 /* Opmode notify */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010019 run_iwpriv(dut, ifname, "opmode_notify 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010020 }
10021
10022 return 1;
10023}
10024
10025
10026static int cmd_sta_send_frame_vht(struct sigma_dut *dut,
10027 struct sigma_conn *conn,
10028 struct sigma_cmd *cmd)
10029{
10030 switch (get_driver_type()) {
10031 case DRIVER_ATHEROS:
10032 return ath_sta_send_frame_vht(dut, conn, cmd);
10033 default:
10034 send_resp(dut, conn, SIGMA_ERROR,
10035 "errorCode,Unsupported sta_set_frame(VHT) with the current driver");
10036 return 0;
10037 }
10038}
10039
10040
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070010041static int wcn_sta_send_frame_he(struct sigma_dut *dut, struct sigma_conn *conn,
10042 struct sigma_cmd *cmd)
10043{
10044 const char *val;
10045 const char *intf = get_param(cmd, "Interface");
10046
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +030010047 if (!intf)
10048 return -1;
10049
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070010050 val = get_param(cmd, "framename");
10051 if (!val)
10052 return -1;
10053 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
10054
10055 /* Command sequence to generate Op mode notification */
10056 if (val && strcasecmp(val, "action") == 0) {
10057 val = get_param(cmd, "PPDUTxType");
10058 if (val && strcasecmp(val, "TB") == 0) {
10059 if (sta_set_action_tx_in_he_tb_ppdu(dut, intf, 1)) {
10060 sigma_dut_print(dut, DUT_MSG_ERROR,
10061 "failed to send TB PPDU Tx cfg");
10062 send_resp(dut, conn, SIGMA_ERROR,
10063 "ErrorCode,set TB PPDU Tx cfg failed");
10064 return 0;
10065 }
10066 return 1;
10067 }
10068
10069 sigma_dut_print(dut, DUT_MSG_ERROR,
10070 "Action Tx type is not defined");
10071 }
10072
10073 return 1;
10074}
10075
10076
10077static int cmd_sta_send_frame_he(struct sigma_dut *dut,
10078 struct sigma_conn *conn,
10079 struct sigma_cmd *cmd)
10080{
10081 switch (get_driver_type()) {
10082 case DRIVER_WCN:
10083 return wcn_sta_send_frame_he(dut, conn, cmd);
10084 default:
10085 send_resp(dut, conn, SIGMA_ERROR,
10086 "errorCode,Unsupported sta_set_frame(HE) with the current driver");
10087 return 0;
10088 }
10089}
10090
10091
Lior David0fe101e2017-03-09 16:09:50 +020010092#ifdef __linux__
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030010093
10094static int
10095wil6210_send_p2p_frame_60g(struct sigma_dut *dut, struct sigma_cmd *cmd,
10096 const char *frame_name, const char *dest_mac)
10097{
10098 int isprobereq = strcasecmp(frame_name, "probereq") == 0;
10099 const char *ssid = get_param(cmd, "ssid");
10100 const char *countstr = get_param(cmd, "count");
10101 const char *channelstr = get_param(cmd, "channel");
10102 const char *group_id = get_param(cmd, "groupid");
10103 const char *client_id = get_param(cmd, "clientmac");
10104 int count, channel, freq, i;
10105 const char *fname;
10106 char frame[1024], src_mac[20], group_id_attr[25],
10107 device_macstr[3 * ETH_ALEN], client_mac[ETH_ALEN];
10108 const char *group_ssid;
10109 const int group_ssid_prefix_len = 9;
10110 struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *) frame;
10111 size_t framelen = sizeof(frame);
10112 struct template_frame_tag tags[2];
10113 size_t tags_total = ARRAY_SIZE(tags);
10114 int tag_index, len, dst_len;
10115
10116 if (!countstr || !channelstr) {
10117 sigma_dut_print(dut, DUT_MSG_ERROR,
10118 "Missing argument: count, channel");
10119 return -1;
10120 }
10121 if (isprobereq && !ssid) {
10122 sigma_dut_print(dut, DUT_MSG_ERROR,
10123 "Missing argument: ssid");
10124 return -1;
10125 }
10126 if (!isprobereq && (!group_id || !client_id)) {
10127 sigma_dut_print(dut, DUT_MSG_ERROR,
10128 "Missing argument: group_id, client_id");
10129 return -1;
10130 }
10131
10132 count = atoi(countstr);
10133 channel = atoi(channelstr);
10134 freq = channel_to_freq(dut, channel);
10135
10136 if (!freq) {
10137 sigma_dut_print(dut, DUT_MSG_ERROR,
10138 "invalid channel: %s", channelstr);
10139 return -1;
10140 }
10141
10142 if (isprobereq) {
10143 if (strcasecmp(ssid, "wildcard") == 0) {
10144 fname = "probe_req_wildcard.txt";
10145 } else if (strcasecmp(ssid, "P2P_Wildcard") == 0) {
10146 fname = "probe_req_P2P_Wildcard.txt";
10147 } else {
10148 sigma_dut_print(dut, DUT_MSG_ERROR,
10149 "invalid probe request type");
10150 return -1;
10151 }
10152 } else {
10153 fname = "P2P_device_discovery_req.txt";
10154 }
10155
10156 if (parse_template_frame_file(dut, fname, frame, &framelen,
10157 tags, &tags_total)) {
10158 sigma_dut_print(dut, DUT_MSG_ERROR,
10159 "invalid frame template: %s", fname);
10160 return -1;
10161 }
10162
10163 if (get_wpa_status(get_station_ifname(), "address",
10164 src_mac, sizeof(src_mac)) < 0 ||
10165 parse_mac_address(dut, src_mac, &hdr->addr2[0]) ||
10166 parse_mac_address(dut, dest_mac, &hdr->addr1[0]))
10167 return -1;
10168 /* Use wildcard BSSID, since we are in PBSS */
10169 memset(&hdr->addr3, 0xFF, ETH_ALEN);
10170
10171 if (!isprobereq) {
10172 tag_index = find_template_frame_tag(tags, tags_total, 1);
10173 if (tag_index < 0) {
10174 sigma_dut_print(dut, DUT_MSG_ERROR,
10175 "can't find device id attribute");
10176 return -1;
10177 }
10178 if (parse_mac_address(dut, client_id,
10179 (unsigned char *) client_mac)) {
10180 sigma_dut_print(dut, DUT_MSG_ERROR,
10181 "invalid client_id: %s", client_id);
10182 return -1;
10183 }
10184 if (replace_p2p_attribute(dut, &frame[tags[tag_index].offset],
10185 framelen - tags[tag_index].offset,
10186 IEEE80211_P2P_ATTR_DEVICE_ID,
10187 client_mac, ETH_ALEN)) {
10188 sigma_dut_print(dut, DUT_MSG_ERROR,
10189 "fail to replace device id attribute");
10190 return -1;
10191 }
10192
10193 /*
10194 * group_id arg contains device MAC address followed by
10195 * space and SSID (DIRECT-somessid).
10196 * group id attribute contains device address (6 bytes)
10197 * followed by SSID prefix DIRECT-XX (9 bytes)
10198 */
10199 if (strlen(group_id) < sizeof(device_macstr)) {
10200 sigma_dut_print(dut, DUT_MSG_ERROR,
10201 "group_id arg too short");
10202 return -1;
10203 }
10204 memcpy(device_macstr, group_id, sizeof(device_macstr));
10205 device_macstr[sizeof(device_macstr) - 1] = '\0';
10206 if (parse_mac_address(dut, device_macstr,
10207 (unsigned char *) group_id_attr)) {
10208 sigma_dut_print(dut, DUT_MSG_ERROR,
10209 "fail to parse device address from group_id");
10210 return -1;
10211 }
10212 group_ssid = strchr(group_id, ' ');
10213 if (!group_ssid) {
10214 sigma_dut_print(dut, DUT_MSG_ERROR,
10215 "invalid group_id arg, no ssid");
10216 return -1;
10217 }
10218 group_ssid++;
10219 len = strlen(group_ssid);
10220 if (len < group_ssid_prefix_len) {
10221 sigma_dut_print(dut, DUT_MSG_ERROR,
10222 "group_id SSID too short");
10223 return -1;
10224 }
10225 dst_len = sizeof(group_id_attr) - ETH_ALEN;
10226 if (len > dst_len) {
10227 sigma_dut_print(dut, DUT_MSG_ERROR,
10228 "group_id SSID (%s) too long",
10229 group_ssid);
10230 return -1;
10231 }
10232
10233 memcpy(group_id_attr + ETH_ALEN, group_ssid, len);
10234 tag_index = find_template_frame_tag(tags, tags_total, 2);
10235 if (tag_index < 0) {
10236 sigma_dut_print(dut, DUT_MSG_ERROR,
10237 "can't find group id attribute");
10238 return -1;
10239 }
10240 if (replace_p2p_attribute(dut, &frame[tags[tag_index].offset],
10241 framelen - tags[tag_index].offset,
10242 IEEE80211_P2P_ATTR_GROUP_ID,
10243 group_id_attr,
10244 sizeof(group_id_attr))) {
10245 sigma_dut_print(dut, DUT_MSG_ERROR,
10246 "fail to replace group id attribute");
10247 return -1;
10248 }
10249 }
10250
10251 for (i = 0; i < count; i++) {
10252 if (wil6210_transmit_frame(dut, freq,
10253 WIL_TRANSMIT_FRAME_DEFAULT_ROC,
10254 frame, framelen)) {
10255 sigma_dut_print(dut, DUT_MSG_ERROR,
10256 "fail to transmit probe request frame");
10257 return -1;
10258 }
10259 }
10260
10261 return 0;
10262}
10263
10264
Lior David0fe101e2017-03-09 16:09:50 +020010265int wil6210_send_frame_60g(struct sigma_dut *dut, struct sigma_conn *conn,
10266 struct sigma_cmd *cmd)
10267{
10268 const char *frame_name = get_param(cmd, "framename");
10269 const char *mac = get_param(cmd, "dest_mac");
10270
10271 if (!frame_name || !mac) {
10272 sigma_dut_print(dut, DUT_MSG_ERROR,
10273 "framename and dest_mac must be provided");
10274 return -1;
10275 }
10276
10277 if (strcasecmp(frame_name, "brp") == 0) {
10278 const char *l_rx = get_param(cmd, "L-RX");
10279 int l_rx_i;
10280
10281 if (!l_rx) {
10282 sigma_dut_print(dut, DUT_MSG_ERROR,
10283 "L-RX must be provided");
10284 return -1;
10285 }
10286 l_rx_i = atoi(l_rx);
10287
10288 sigma_dut_print(dut, DUT_MSG_INFO,
10289 "dev_send_frame: BRP-RX, dest_mac %s, L-RX %s",
10290 mac, l_rx);
10291 if (l_rx_i != 16) {
10292 sigma_dut_print(dut, DUT_MSG_ERROR,
10293 "unsupported L-RX: %s", l_rx);
10294 return -1;
10295 }
10296
10297 if (wil6210_send_brp_rx(dut, mac, l_rx_i))
10298 return -1;
10299 } else if (strcasecmp(frame_name, "ssw") == 0) {
10300 sigma_dut_print(dut, DUT_MSG_INFO,
10301 "dev_send_frame: SLS, dest_mac %s", mac);
10302 if (wil6210_send_sls(dut, mac))
10303 return -1;
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030010304 } else if ((strcasecmp(frame_name, "probereq") == 0) ||
10305 (strcasecmp(frame_name, "devdiscreq") == 0)) {
10306 sigma_dut_print(dut, DUT_MSG_INFO,
10307 "dev_send_frame: %s, dest_mac %s", frame_name,
10308 mac);
10309 if (wil6210_send_p2p_frame_60g(dut, cmd, frame_name, mac))
10310 return -1;
Lior David0fe101e2017-03-09 16:09:50 +020010311 } else {
10312 sigma_dut_print(dut, DUT_MSG_ERROR,
10313 "unsupported frame type: %s", frame_name);
10314 return -1;
10315 }
10316
10317 return 1;
10318}
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030010319
Lior David0fe101e2017-03-09 16:09:50 +020010320#endif /* __linux__ */
10321
10322
10323static int cmd_sta_send_frame_60g(struct sigma_dut *dut,
10324 struct sigma_conn *conn,
10325 struct sigma_cmd *cmd)
10326{
10327 switch (get_driver_type()) {
10328#ifdef __linux__
10329 case DRIVER_WIL6210:
10330 return wil6210_send_frame_60g(dut, conn, cmd);
10331#endif /* __linux__ */
10332 default:
10333 send_resp(dut, conn, SIGMA_ERROR,
10334 "errorCode,Unsupported sta_set_frame(60G) with the current driver");
10335 return 0;
10336 }
10337}
10338
10339
Ashwini Patildb59b3c2017-04-13 15:19:23 +053010340static int mbo_send_anqp_query(struct sigma_dut *dut, struct sigma_conn *conn,
10341 const char *intf, struct sigma_cmd *cmd)
10342{
10343 const char *val, *addr;
10344 char buf[100];
10345
10346 addr = get_param(cmd, "DestMac");
10347 if (!addr) {
10348 send_resp(dut, conn, SIGMA_INVALID,
10349 "ErrorCode,AP MAC address is missing");
10350 return 0;
10351 }
10352
10353 val = get_param(cmd, "ANQPQuery_ID");
10354 if (!val) {
10355 send_resp(dut, conn, SIGMA_INVALID,
10356 "ErrorCode,Missing ANQPQuery_ID");
10357 return 0;
10358 }
10359
10360 if (strcasecmp(val, "NeighborReportReq") == 0) {
10361 snprintf(buf, sizeof(buf), "ANQP_GET %s 272", addr);
10362 } else if (strcasecmp(val, "QueryListWithCellPref") == 0) {
10363 snprintf(buf, sizeof(buf), "ANQP_GET %s 272,mbo:2", addr);
10364 } else {
10365 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid ANQPQuery_ID: %s",
10366 val);
10367 send_resp(dut, conn, SIGMA_INVALID,
10368 "ErrorCode,Invalid ANQPQuery_ID");
10369 return 0;
10370 }
10371
Ashwini Patild174f2c2017-04-13 16:49:46 +053010372 /* Set gas_address3 field to IEEE 802.11-2012 standard compliant form
10373 * (Address3 = Wildcard BSSID when sent to not-associated AP;
10374 * if associated, AP BSSID).
10375 */
10376 if (wpa_command(intf, "SET gas_address3 1") < 0) {
10377 send_resp(dut, conn, SIGMA_ERROR,
10378 "ErrorCode,Failed to set gas_address3");
10379 return 0;
10380 }
10381
Ashwini Patildb59b3c2017-04-13 15:19:23 +053010382 if (wpa_command(intf, buf) < 0) {
10383 send_resp(dut, conn, SIGMA_ERROR,
10384 "ErrorCode,Failed to send ANQP query");
10385 return 0;
10386 }
10387
10388 return 1;
10389}
10390
10391
10392static int mbo_cmd_sta_send_frame(struct sigma_dut *dut,
10393 struct sigma_conn *conn,
10394 const char *intf,
10395 struct sigma_cmd *cmd)
10396{
10397 const char *val = get_param(cmd, "FrameName");
10398
10399 if (val && strcasecmp(val, "ANQPQuery") == 0)
10400 return mbo_send_anqp_query(dut, conn, intf, cmd);
10401
10402 return 2;
10403}
10404
10405
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010406int cmd_sta_send_frame(struct sigma_dut *dut, struct sigma_conn *conn,
10407 struct sigma_cmd *cmd)
10408{
10409 const char *intf = get_param(cmd, "Interface");
10410 const char *val;
10411 enum send_frame_type frame;
10412 enum send_frame_protection protected;
10413 char buf[100];
10414 unsigned char addr[ETH_ALEN];
10415 int res;
10416
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +030010417 if (!intf)
10418 return -1;
10419
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010420 val = get_param(cmd, "program");
10421 if (val == NULL)
10422 val = get_param(cmd, "frame");
10423 if (val && strcasecmp(val, "TDLS") == 0)
10424 return cmd_sta_send_frame_tdls(dut, conn, cmd);
10425 if (val && (strcasecmp(val, "HS2") == 0 ||
Jouni Malinen1f6ae642018-06-07 23:56:13 +030010426 strcasecmp(val, "HS2-R2") == 0 ||
10427 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010428 return cmd_sta_send_frame_hs2(dut, conn, cmd);
10429 if (val && strcasecmp(val, "VHT") == 0)
10430 return cmd_sta_send_frame_vht(dut, conn, cmd);
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070010431 if (val && strcasecmp(val, "HE") == 0)
10432 return cmd_sta_send_frame_he(dut, conn, cmd);
priyadharshini gowthamand66913a2016-07-29 15:11:17 -070010433 if (val && strcasecmp(val, "LOC") == 0)
10434 return loc_cmd_sta_send_frame(dut, conn, cmd);
Lior David0fe101e2017-03-09 16:09:50 +020010435 if (val && strcasecmp(val, "60GHz") == 0)
10436 return cmd_sta_send_frame_60g(dut, conn, cmd);
Ashwini Patildb59b3c2017-04-13 15:19:23 +053010437 if (val && strcasecmp(val, "MBO") == 0) {
10438 res = mbo_cmd_sta_send_frame(dut, conn, intf, cmd);
10439 if (res != 2)
10440 return res;
10441 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010442
10443 val = get_param(cmd, "TD_DISC");
10444 if (val) {
10445 if (hwaddr_aton(val, addr) < 0)
10446 return -1;
10447 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", val);
10448 if (wpa_command(intf, buf) < 0) {
10449 send_resp(dut, conn, SIGMA_ERROR,
10450 "ErrorCode,Failed to send TDLS discovery");
10451 return 0;
10452 }
10453 return 1;
10454 }
10455
10456 val = get_param(cmd, "TD_Setup");
10457 if (val) {
10458 if (hwaddr_aton(val, addr) < 0)
10459 return -1;
10460 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", val);
10461 if (wpa_command(intf, buf) < 0) {
10462 send_resp(dut, conn, SIGMA_ERROR,
10463 "ErrorCode,Failed to start TDLS setup");
10464 return 0;
10465 }
10466 return 1;
10467 }
10468
10469 val = get_param(cmd, "TD_TearDown");
10470 if (val) {
10471 if (hwaddr_aton(val, addr) < 0)
10472 return -1;
10473 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", val);
10474 if (wpa_command(intf, buf) < 0) {
10475 send_resp(dut, conn, SIGMA_ERROR,
10476 "ErrorCode,Failed to tear down TDLS link");
10477 return 0;
10478 }
10479 return 1;
10480 }
10481
10482 val = get_param(cmd, "TD_ChannelSwitch");
10483 if (val) {
10484 /* TODO */
10485 send_resp(dut, conn, SIGMA_ERROR,
10486 "ErrorCode,TD_ChannelSwitch not yet supported");
10487 return 0;
10488 }
10489
10490 val = get_param(cmd, "TD_NF");
10491 if (val) {
10492 /* TODO */
10493 send_resp(dut, conn, SIGMA_ERROR,
10494 "ErrorCode,TD_NF not yet supported");
10495 return 0;
10496 }
10497
10498 val = get_param(cmd, "PMFFrameType");
10499 if (val == NULL)
10500 val = get_param(cmd, "FrameName");
10501 if (val == NULL)
10502 val = get_param(cmd, "Type");
10503 if (val == NULL)
10504 return -1;
10505 if (strcasecmp(val, "disassoc") == 0)
10506 frame = DISASSOC;
10507 else if (strcasecmp(val, "deauth") == 0)
10508 frame = DEAUTH;
10509 else if (strcasecmp(val, "saquery") == 0)
10510 frame = SAQUERY;
10511 else if (strcasecmp(val, "auth") == 0)
10512 frame = AUTH;
10513 else if (strcasecmp(val, "assocreq") == 0)
10514 frame = ASSOCREQ;
10515 else if (strcasecmp(val, "reassocreq") == 0)
10516 frame = REASSOCREQ;
10517 else if (strcasecmp(val, "neigreq") == 0) {
10518 sigma_dut_print(dut, DUT_MSG_INFO, "Got neighbor request");
10519
10520 val = get_param(cmd, "ssid");
10521 if (val == NULL)
10522 return -1;
10523
10524 res = send_neighbor_request(dut, intf, val);
10525 if (res) {
10526 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
10527 "Failed to send neighbor report request");
10528 return 0;
10529 }
10530
10531 return 1;
Ashwini Patil5acd7382017-04-13 15:55:04 +053010532 } else if (strcasecmp(val, "transmgmtquery") == 0 ||
10533 strcasecmp(val, "BTMQuery") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010534 sigma_dut_print(dut, DUT_MSG_DEBUG,
10535 "Got Transition Management Query");
10536
Ashwini Patil5acd7382017-04-13 15:55:04 +053010537 res = send_trans_mgmt_query(dut, intf, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010538 if (res) {
10539 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
10540 "Failed to send Transition Management Query");
10541 return 0;
10542 }
10543
10544 return 1;
10545 } else {
10546 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
10547 "PMFFrameType");
10548 return 0;
10549 }
10550
10551 val = get_param(cmd, "PMFProtected");
10552 if (val == NULL)
10553 val = get_param(cmd, "Protected");
10554 if (val == NULL)
10555 return -1;
10556 if (strcasecmp(val, "Correct-key") == 0 ||
10557 strcasecmp(val, "CorrectKey") == 0)
10558 protected = CORRECT_KEY;
10559 else if (strcasecmp(val, "IncorrectKey") == 0)
10560 protected = INCORRECT_KEY;
10561 else if (strcasecmp(val, "Unprotected") == 0)
10562 protected = UNPROTECTED;
10563 else {
10564 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
10565 "PMFProtected");
10566 return 0;
10567 }
10568
10569 if (protected != UNPROTECTED &&
10570 (frame == AUTH || frame == ASSOCREQ || frame == REASSOCREQ)) {
10571 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Impossible "
10572 "PMFProtected for auth/assocreq/reassocreq");
10573 return 0;
10574 }
10575
10576 if (if_nametoindex("sigmadut") == 0) {
10577 snprintf(buf, sizeof(buf),
10578 "iw dev %s interface add sigmadut type monitor",
10579 get_station_ifname());
10580 if (system(buf) != 0 ||
10581 if_nametoindex("sigmadut") == 0) {
10582 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
10583 "monitor interface with '%s'", buf);
10584 return -2;
10585 }
10586 }
10587
10588 if (system("ifconfig sigmadut up") != 0) {
10589 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
10590 "monitor interface up");
10591 return -2;
10592 }
10593
10594 return sta_inject_frame(dut, conn, frame, protected, NULL);
10595}
10596
10597
10598static int cmd_sta_set_parameter_hs2(struct sigma_dut *dut,
10599 struct sigma_conn *conn,
10600 struct sigma_cmd *cmd,
10601 const char *ifname)
10602{
10603 char buf[200];
10604 const char *val;
10605
10606 val = get_param(cmd, "ClearARP");
10607 if (val && atoi(val) == 1) {
10608 snprintf(buf, sizeof(buf), "ip neigh flush dev %s", ifname);
10609 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10610 if (system(buf) != 0) {
10611 send_resp(dut, conn, SIGMA_ERROR,
10612 "errorCode,Failed to clear ARP cache");
10613 return 0;
10614 }
10615 }
10616
10617 return 1;
10618}
10619
10620
10621int cmd_sta_set_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
10622 struct sigma_cmd *cmd)
10623{
10624 const char *intf = get_param(cmd, "Interface");
10625 const char *val;
10626
10627 if (intf == NULL)
10628 return -1;
10629
10630 val = get_param(cmd, "program");
10631 if (val && (strcasecmp(val, "HS2") == 0 ||
Jouni Malinen1f6ae642018-06-07 23:56:13 +030010632 strcasecmp(val, "HS2-R2") == 0 ||
10633 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010634 return cmd_sta_set_parameter_hs2(dut, conn, cmd, intf);
10635
10636 return -1;
10637}
10638
10639
10640static int cmd_sta_set_macaddr(struct sigma_dut *dut, struct sigma_conn *conn,
10641 struct sigma_cmd *cmd)
10642{
10643 const char *intf = get_param(cmd, "Interface");
10644 const char *mac = get_param(cmd, "MAC");
10645
10646 if (intf == NULL || mac == NULL)
10647 return -1;
10648
10649 sigma_dut_print(dut, DUT_MSG_INFO, "Change local MAC address for "
10650 "interface %s to %s", intf, mac);
10651
10652 if (dut->set_macaddr) {
10653 char buf[128];
10654 int res;
10655 if (strcasecmp(mac, "default") == 0) {
10656 res = snprintf(buf, sizeof(buf), "%s",
10657 dut->set_macaddr);
10658 dut->tmp_mac_addr = 0;
10659 } else {
10660 res = snprintf(buf, sizeof(buf), "%s %s",
10661 dut->set_macaddr, mac);
10662 dut->tmp_mac_addr = 1;
10663 }
10664 if (res < 0 || res >= (int) sizeof(buf))
10665 return -1;
10666 if (system(buf) != 0) {
10667 send_resp(dut, conn, SIGMA_ERROR,
10668 "errorCode,Failed to set MAC "
10669 "address");
10670 return 0;
10671 }
10672 return 1;
10673 }
10674
10675 if (strcasecmp(mac, "default") == 0)
10676 return 1;
10677
10678 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
10679 "command");
10680 return 0;
10681}
10682
10683
10684static int iwpriv_tdlsoffchnmode(struct sigma_dut *dut,
10685 struct sigma_conn *conn, const char *intf,
10686 int val)
10687{
10688 char buf[200];
10689 int res;
10690
10691 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchnmode %d",
10692 intf, val);
10693 if (res < 0 || res >= (int) sizeof(buf))
10694 return -1;
10695 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10696 if (system(buf) != 0) {
10697 send_resp(dut, conn, SIGMA_ERROR,
10698 "errorCode,Failed to configure offchannel mode");
10699 return 0;
10700 }
10701
10702 return 1;
10703}
10704
10705
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010706static int off_chan_val(enum sec_ch_offset off)
10707{
10708 switch (off) {
10709 case SEC_CH_NO:
10710 return 0;
10711 case SEC_CH_40ABOVE:
10712 return 40;
10713 case SEC_CH_40BELOW:
10714 return -40;
10715 }
10716
10717 return 0;
10718}
10719
10720
10721static int iwpriv_set_offchan(struct sigma_dut *dut, struct sigma_conn *conn,
10722 const char *intf, int off_ch_num,
10723 enum sec_ch_offset sec)
10724{
10725 char buf[200];
10726 int res;
10727
10728 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchan %d",
10729 intf, off_ch_num);
10730 if (res < 0 || res >= (int) sizeof(buf))
10731 return -1;
10732 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10733 if (system(buf) != 0) {
10734 send_resp(dut, conn, SIGMA_ERROR,
10735 "errorCode,Failed to set offchan");
10736 return 0;
10737 }
10738
10739 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsecchnoffst %d",
10740 intf, off_chan_val(sec));
10741 if (res < 0 || res >= (int) sizeof(buf))
10742 return -1;
10743 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10744 if (system(buf) != 0) {
10745 send_resp(dut, conn, SIGMA_ERROR,
10746 "errorCode,Failed to set sec chan offset");
10747 return 0;
10748 }
10749
10750 return 1;
10751}
10752
10753
10754static int tdls_set_offchannel_offset(struct sigma_dut *dut,
10755 struct sigma_conn *conn,
10756 const char *intf, int off_ch_num,
10757 enum sec_ch_offset sec)
10758{
10759 char buf[200];
10760 int res;
10761
10762 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNEL %d",
10763 off_ch_num);
10764 if (res < 0 || res >= (int) sizeof(buf))
10765 return -1;
10766 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10767
10768 if (wpa_command(intf, buf) < 0) {
10769 send_resp(dut, conn, SIGMA_ERROR,
10770 "ErrorCode,Failed to set offchan");
10771 return 0;
10772 }
10773 res = snprintf(buf, sizeof(buf), "DRIVER TDLSSECONDARYCHANNELOFFSET %d",
10774 off_chan_val(sec));
10775 if (res < 0 || res >= (int) sizeof(buf))
10776 return -1;
10777
10778 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10779
10780 if (wpa_command(intf, buf) < 0) {
10781 send_resp(dut, conn, SIGMA_ERROR,
10782 "ErrorCode,Failed to set sec chan offset");
10783 return 0;
10784 }
10785
10786 return 1;
10787}
10788
10789
10790static int tdls_set_offchannel_mode(struct sigma_dut *dut,
10791 struct sigma_conn *conn,
10792 const char *intf, int val)
10793{
10794 char buf[200];
10795 int res;
10796
10797 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNELMODE %d",
10798 val);
10799 if (res < 0 || res >= (int) sizeof(buf))
10800 return -1;
10801 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10802
10803 if (wpa_command(intf, buf) < 0) {
10804 send_resp(dut, conn, SIGMA_ERROR,
10805 "ErrorCode,Failed to configure offchannel mode");
10806 return 0;
10807 }
10808
10809 return 1;
10810}
10811
10812
10813static int cmd_sta_set_rfeature_tdls(const char *intf, struct sigma_dut *dut,
10814 struct sigma_conn *conn,
10815 struct sigma_cmd *cmd)
10816{
10817 const char *val;
10818 enum {
10819 CHSM_NOT_SET,
10820 CHSM_ENABLE,
10821 CHSM_DISABLE,
10822 CHSM_REJREQ,
10823 CHSM_UNSOLRESP
10824 } chsm = CHSM_NOT_SET;
10825 int off_ch_num = -1;
10826 enum sec_ch_offset sec_ch = SEC_CH_NO;
10827 int res;
10828
10829 val = get_param(cmd, "Uapsd");
10830 if (val) {
10831 char buf[100];
10832 if (strcasecmp(val, "Enable") == 0)
10833 snprintf(buf, sizeof(buf), "SET ps 99");
10834 else if (strcasecmp(val, "Disable") == 0)
10835 snprintf(buf, sizeof(buf), "SET ps 98");
10836 else {
10837 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
10838 "Unsupported uapsd parameter value");
10839 return 0;
10840 }
10841 if (wpa_command(intf, buf)) {
10842 send_resp(dut, conn, SIGMA_ERROR,
10843 "ErrorCode,Failed to change U-APSD "
10844 "powersave mode");
10845 return 0;
10846 }
10847 }
10848
10849 val = get_param(cmd, "TPKTIMER");
10850 if (val && strcasecmp(val, "DISABLE") == 0) {
10851 if (wpa_command(intf, "SET tdls_testing 0x100")) {
10852 send_resp(dut, conn, SIGMA_ERROR,
10853 "ErrorCode,Failed to enable no TPK "
10854 "expiration test mode");
10855 return 0;
10856 }
10857 dut->no_tpk_expiration = 1;
10858 }
10859
10860 val = get_param(cmd, "ChSwitchMode");
10861 if (val) {
10862 if (strcasecmp(val, "Enable") == 0 ||
10863 strcasecmp(val, "Initiate") == 0)
10864 chsm = CHSM_ENABLE;
10865 else if (strcasecmp(val, "Disable") == 0 ||
10866 strcasecmp(val, "passive") == 0)
10867 chsm = CHSM_DISABLE;
10868 else if (strcasecmp(val, "RejReq") == 0)
10869 chsm = CHSM_REJREQ;
10870 else if (strcasecmp(val, "UnSolResp") == 0)
10871 chsm = CHSM_UNSOLRESP;
10872 else {
10873 send_resp(dut, conn, SIGMA_ERROR,
10874 "ErrorCode,Unknown ChSwitchMode value");
10875 return 0;
10876 }
10877 }
10878
10879 val = get_param(cmd, "OffChNum");
10880 if (val) {
10881 off_ch_num = atoi(val);
10882 if (off_ch_num == 0) {
10883 send_resp(dut, conn, SIGMA_ERROR,
10884 "ErrorCode,Invalid OffChNum");
10885 return 0;
10886 }
10887 }
10888
10889 val = get_param(cmd, "SecChOffset");
10890 if (val) {
10891 if (strcmp(val, "20") == 0)
10892 sec_ch = SEC_CH_NO;
10893 else if (strcasecmp(val, "40above") == 0)
10894 sec_ch = SEC_CH_40ABOVE;
10895 else if (strcasecmp(val, "40below") == 0)
10896 sec_ch = SEC_CH_40BELOW;
10897 else {
10898 send_resp(dut, conn, SIGMA_ERROR,
10899 "ErrorCode,Unknown SecChOffset value");
10900 return 0;
10901 }
10902 }
10903
10904 if (chsm == CHSM_NOT_SET) {
10905 /* no offchannel changes requested */
10906 return 1;
10907 }
10908
10909 if (strcmp(intf, get_main_ifname()) != 0 &&
10910 strcmp(intf, get_station_ifname()) != 0) {
10911 send_resp(dut, conn, SIGMA_ERROR,
10912 "ErrorCode,Unknown interface");
10913 return 0;
10914 }
10915
10916 switch (chsm) {
10917 case CHSM_NOT_SET:
Jouni Malinen280f5ba2016-08-29 21:33:10 +030010918 res = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010919 break;
10920 case CHSM_ENABLE:
10921 if (off_ch_num < 0) {
10922 send_resp(dut, conn, SIGMA_ERROR,
10923 "ErrorCode,Missing OffChNum argument");
10924 return 0;
10925 }
10926 if (wifi_chip_type == DRIVER_WCN) {
10927 res = tdls_set_offchannel_offset(dut, conn, intf,
10928 off_ch_num, sec_ch);
10929 } else {
10930 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
10931 sec_ch);
10932 }
10933 if (res != 1)
10934 return res;
10935 if (wifi_chip_type == DRIVER_WCN)
10936 res = tdls_set_offchannel_mode(dut, conn, intf, 1);
10937 else
10938 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 1);
10939 break;
10940 case CHSM_DISABLE:
10941 if (wifi_chip_type == DRIVER_WCN)
10942 res = tdls_set_offchannel_mode(dut, conn, intf, 2);
10943 else
10944 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 2);
10945 break;
10946 case CHSM_REJREQ:
10947 if (wifi_chip_type == DRIVER_WCN)
10948 res = tdls_set_offchannel_mode(dut, conn, intf, 3);
10949 else
10950 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 3);
10951 break;
10952 case CHSM_UNSOLRESP:
10953 if (off_ch_num < 0) {
10954 send_resp(dut, conn, SIGMA_ERROR,
10955 "ErrorCode,Missing OffChNum argument");
10956 return 0;
10957 }
10958 if (wifi_chip_type == DRIVER_WCN) {
10959 res = tdls_set_offchannel_offset(dut, conn, intf,
10960 off_ch_num, sec_ch);
10961 } else {
10962 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
10963 sec_ch);
10964 }
10965 if (res != 1)
10966 return res;
10967 if (wifi_chip_type == DRIVER_WCN)
10968 res = tdls_set_offchannel_mode(dut, conn, intf, 4);
10969 else
10970 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 4);
10971 break;
10972 }
10973
10974 return res;
10975}
10976
10977
10978static int ath_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
10979 struct sigma_conn *conn,
10980 struct sigma_cmd *cmd)
10981{
10982 const char *val;
Srikanth Marepalli5415acf2018-08-27 12:53:11 +053010983 char *token = NULL, *result;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010984
priyadharshini gowthamane5e25172015-12-08 14:53:48 -080010985 novap_reset(dut, intf);
10986
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010987 val = get_param(cmd, "nss_mcs_opt");
10988 if (val) {
10989 /* String (nss_operating_mode; mcs_operating_mode) */
10990 int nss, mcs;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010991 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010992
10993 token = strdup(val);
10994 if (!token)
10995 return 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010996 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +053010997 if (!result) {
10998 sigma_dut_print(dut, DUT_MSG_ERROR,
10999 "VHT NSS not specified");
11000 goto failed;
11001 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011002 if (strcasecmp(result, "def") != 0) {
11003 nss = atoi(result);
11004 if (nss == 4)
11005 ath_disable_txbf(dut, intf);
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011006 if (run_iwpriv(dut, intf, "nss %d", nss) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011007 goto failed;
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011008
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011009 }
11010
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053011011 result = strtok_r(NULL, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +053011012 if (!result) {
11013 sigma_dut_print(dut, DUT_MSG_ERROR,
11014 "VHT MCS not specified");
11015 goto failed;
11016 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011017 if (strcasecmp(result, "def") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011018 if (run_iwpriv(dut, intf, "set11NRates 0") < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011019 goto failed;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011020 } else {
11021 mcs = atoi(result);
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011022 if (run_iwpriv(dut, intf, "vhtmcs %d", mcs) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011023 goto failed;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011024 }
11025 /* Channel width gets messed up, fix this */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011026 run_iwpriv(dut, intf, "chwidth %d", dut->chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011027 }
11028
Srikanth Marepalli5415acf2018-08-27 12:53:11 +053011029 free(token);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011030 return 1;
11031failed:
11032 free(token);
11033 return 0;
11034}
11035
11036
11037static int cmd_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
11038 struct sigma_conn *conn,
11039 struct sigma_cmd *cmd)
11040{
11041 switch (get_driver_type()) {
11042 case DRIVER_ATHEROS:
11043 return ath_sta_set_rfeature_vht(intf, dut, conn, cmd);
11044 default:
11045 send_resp(dut, conn, SIGMA_ERROR,
11046 "errorCode,Unsupported sta_set_rfeature(VHT) with the current driver");
11047 return 0;
11048 }
11049}
11050
11051
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011052static int wcn_sta_set_rfeature_he(const char *intf, struct sigma_dut *dut,
11053 struct sigma_conn *conn,
11054 struct sigma_cmd *cmd)
11055{
11056 const char *val;
11057 char *token = NULL, *result;
11058 char buf[60];
11059
11060 val = get_param(cmd, "nss_mcs_opt");
11061 if (val) {
11062 /* String (nss_operating_mode; mcs_operating_mode) */
11063 int nss, mcs, ratecode;
11064 char *saveptr;
11065
11066 token = strdup(val);
11067 if (!token)
11068 return -2;
11069
11070 result = strtok_r(token, ";", &saveptr);
11071 if (!result) {
11072 sigma_dut_print(dut, DUT_MSG_ERROR,
11073 "HE NSS not specified");
11074 goto failed;
11075 }
11076 nss = 1;
11077 if (strcasecmp(result, "def") != 0)
11078 nss = atoi(result);
11079
11080 result = strtok_r(NULL, ";", &saveptr);
11081 if (!result) {
11082 sigma_dut_print(dut, DUT_MSG_ERROR,
11083 "HE MCS not specified");
11084 goto failed;
11085 }
11086 mcs = 7;
11087 if (strcasecmp(result, "def") != 0)
11088 mcs = atoi(result);
11089
Arif Hussain557bf412018-05-25 17:29:36 -070011090 ratecode = 0x20; /* for nss:1 MCS 0 */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011091 if (nss == 2) {
Arif Hussain557bf412018-05-25 17:29:36 -070011092 ratecode = 0x40; /* for nss:2 MCS 0 */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011093 } else if (nss > 2) {
11094 sigma_dut_print(dut, DUT_MSG_ERROR,
11095 "HE NSS %d not supported", nss);
11096 goto failed;
11097 }
11098
Arif Hussain557bf412018-05-25 17:29:36 -070011099 snprintf(buf, sizeof(buf), "iwpriv %s nss %d", intf, nss);
11100 if (system(buf) != 0) {
11101 sigma_dut_print(dut, DUT_MSG_ERROR,
11102 "nss_mcs_opt: iwpriv %s nss %d failed",
11103 intf, nss);
11104 goto failed;
11105 }
Arif Hussainac6c5112018-05-25 17:34:00 -070011106 dut->sta_nss = nss;
Arif Hussain557bf412018-05-25 17:29:36 -070011107
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011108 /* Add the MCS to the ratecode */
11109 if (mcs >= 0 && mcs <= 11) {
11110 ratecode += mcs;
Arif Hussain557bf412018-05-25 17:29:36 -070011111#ifdef NL80211_SUPPORT
11112 if (dut->device_type == STA_testbed) {
11113 enum he_mcs_config mcs_config;
11114 int ret;
11115
11116 if (mcs <= 7)
11117 mcs_config = HE_80_MCS0_7;
11118 else if (mcs <= 9)
11119 mcs_config = HE_80_MCS0_9;
11120 else
11121 mcs_config = HE_80_MCS0_11;
11122 ret = sta_set_he_mcs(dut, intf, mcs_config);
11123 if (ret) {
11124 sigma_dut_print(dut, DUT_MSG_ERROR,
11125 "nss_mcs_opt: mcs setting failed, mcs:%d, mcs_config %d, ret:%d",
11126 mcs, mcs_config, ret);
11127 goto failed;
11128 }
11129 }
11130#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011131 } else {
11132 sigma_dut_print(dut, DUT_MSG_ERROR,
11133 "HE MCS %d not supported", mcs);
11134 goto failed;
11135 }
11136 snprintf(buf, sizeof(buf), "iwpriv %s set_11ax_rate 0x%03x",
11137 intf, ratecode);
11138 if (system(buf) != 0) {
11139 sigma_dut_print(dut, DUT_MSG_ERROR,
11140 "iwpriv setting of 11ax rates failed");
11141 goto failed;
11142 }
11143 free(token);
11144 }
11145
11146 val = get_param(cmd, "GI");
11147 if (val) {
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011148 int fix_rate_sgi;
11149
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011150 if (strcmp(val, "0.8") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070011151 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 9", intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011152 fix_rate_sgi = 1;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011153 } else if (strcmp(val, "1.6") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070011154 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 10",
11155 intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011156 fix_rate_sgi = 2;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011157 } else if (strcmp(val, "3.2") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070011158 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 11",
11159 intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011160 fix_rate_sgi = 3;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011161 } else {
11162 send_resp(dut, conn, SIGMA_ERROR,
11163 "errorCode,GI value not supported");
11164 return 0;
11165 }
11166 if (system(buf) != 0) {
11167 send_resp(dut, conn, SIGMA_ERROR,
11168 "errorCode,Failed to set shortgi");
11169 return 0;
11170 }
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011171 snprintf(buf, sizeof(buf), "iwpriv %s shortgi %d",
11172 intf, fix_rate_sgi);
11173 if (system(buf) != 0) {
11174 send_resp(dut, conn, SIGMA_ERROR,
11175 "errorCode,Failed to set fix rate shortgi");
11176 return STATUS_SENT;
11177 }
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011178 }
11179
Subhani Shaik8e7a3052018-04-24 14:03:00 -070011180 val = get_param(cmd, "LTF");
11181 if (val) {
11182#ifdef NL80211_SUPPORT
11183 if (strcmp(val, "3.2") == 0) {
11184 sta_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_1X);
11185 } if (strcmp(val, "6.4") == 0) {
11186 sta_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_2X);
11187 } else if (strcmp(val, "12.8") == 0) {
11188 sta_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_4X);
11189 } else {
11190 send_resp(dut, conn, SIGMA_ERROR,
11191 "errorCode, LTF value not supported");
11192 return 0;
11193 }
11194#else /* NL80211_SUPPORT */
11195 sigma_dut_print(dut, DUT_MSG_ERROR,
11196 "LTF cannot be set without NL80211_SUPPORT defined");
11197 return -2;
11198#endif /* NL80211_SUPPORT */
11199 }
11200
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -070011201 val = get_param(cmd, "TxSUPPDU");
11202 if (val) {
11203 int set_val = 1;
11204
11205 if (strcasecmp(val, "Enable") == 0)
11206 set_val = 1;
11207 else if (strcasecmp(val, "Disable") == 0)
11208 set_val = 0;
11209
11210 if (sta_set_tx_su_ppdu_cfg(dut, intf, set_val)) {
11211 send_resp(dut, conn, SIGMA_ERROR,
11212 "ErrorCode,Failed to set Tx SU PPDU config");
11213 return 0;
11214 }
11215 }
11216
Arif Hussain480d5f42019-03-12 14:40:42 -070011217 val = get_param(cmd, "TWT_Setup");
11218 if (val) {
11219 if (strcasecmp(val, "Request") == 0) {
11220 if (sta_twt_request(dut, conn, cmd)) {
11221 send_resp(dut, conn, SIGMA_ERROR,
11222 "ErrorCode,sta_twt_request failed");
11223 return STATUS_SENT;
11224 }
11225 } else if (strcasecmp(val, "Teardown") == 0) {
11226 if (sta_twt_teardown(dut, conn, cmd)) {
11227 send_resp(dut, conn, SIGMA_ERROR,
11228 "ErrorCode,sta_twt_teardown failed");
11229 return STATUS_SENT;
11230 }
11231 }
11232 }
11233
Kiran Kumar Lokere50eb2cd2018-12-18 18:31:28 -080011234 val = get_param(cmd, "transmitOMI");
11235 if (val && sta_transmit_omi(dut, conn, cmd)) {
11236 send_resp(dut, conn, SIGMA_ERROR,
11237 "ErrorCode,sta_transmit_omi failed");
11238 return STATUS_SENT;
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -070011239 }
11240
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080011241 val = get_param(cmd, "Powersave");
11242 if (val) {
11243 char buf[60];
11244
11245 if (strcasecmp(val, "off") == 0) {
11246 snprintf(buf, sizeof(buf),
11247 "iwpriv %s setPower 2", intf);
11248 if (system(buf) != 0) {
11249 sigma_dut_print(dut, DUT_MSG_ERROR,
11250 "iwpriv setPower 2 failed");
11251 return 0;
11252 }
11253 } else if (strcasecmp(val, "on") == 0) {
11254 snprintf(buf, sizeof(buf),
11255 "iwpriv %s setPower 1", intf);
11256 if (system(buf) != 0) {
11257 sigma_dut_print(dut, DUT_MSG_ERROR,
11258 "iwpriv setPower 1 failed");
11259 return 0;
11260 }
11261 } else {
11262 sigma_dut_print(dut, DUT_MSG_ERROR,
11263 "Unsupported Powersave value '%s'",
11264 val);
11265 return -1;
11266 }
11267 }
11268
Kiran Kumar Lokere2c4b7ce2019-01-30 12:02:28 -080011269 val = get_param(cmd, "MU_EDCA");
11270 if (val) {
11271 if (strcasecmp(val, "Override") == 0) {
11272 if (sta_set_mu_edca_override(dut, intf, 1)) {
11273 send_resp(dut, conn, SIGMA_ERROR,
11274 "errorCode,MU EDCA override set failed");
11275 return STATUS_SENT;
11276 }
11277 } else if (strcasecmp(val, "Disable") == 0) {
11278 if (sta_set_mu_edca_override(dut, intf, 0)) {
11279 send_resp(dut, conn, SIGMA_ERROR,
11280 "errorCode,MU EDCA override disable failed");
11281 return STATUS_SENT;
11282 }
11283 }
11284 }
11285
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011286 return 1;
11287
11288failed:
11289 free(token);
11290 return -2;
11291}
11292
11293
11294static int cmd_sta_set_rfeature_he(const char *intf, struct sigma_dut *dut,
11295 struct sigma_conn *conn,
11296 struct sigma_cmd *cmd)
11297{
11298 switch (get_driver_type()) {
11299 case DRIVER_WCN:
11300 return wcn_sta_set_rfeature_he(intf, dut, conn, cmd);
11301 default:
11302 send_resp(dut, conn, SIGMA_ERROR,
11303 "errorCode,Unsupported sta_set_rfeature(HE) with the current driver");
11304 return 0;
11305 }
11306}
11307
11308
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080011309static int cmd_sta_set_power_save_he(const char *intf, struct sigma_dut *dut,
11310 struct sigma_conn *conn,
11311 struct sigma_cmd *cmd)
11312{
11313 const char *val;
11314
11315 val = get_param(cmd, "powersave");
11316 if (val) {
11317 char buf[60];
11318
11319 if (strcasecmp(val, "off") == 0) {
11320 snprintf(buf, sizeof(buf), "iwpriv %s setPower 2",
11321 intf);
11322 if (system(buf) != 0) {
11323 sigma_dut_print(dut, DUT_MSG_ERROR,
11324 "iwpriv setPower 2 failed");
11325 return 0;
11326 }
11327 } else if (strcasecmp(val, "on") == 0) {
11328 snprintf(buf, sizeof(buf), "iwpriv %s setPower 1",
11329 intf);
11330 if (system(buf) != 0) {
11331 sigma_dut_print(dut, DUT_MSG_ERROR,
11332 "iwpriv setPower 1 failed");
11333 return 0;
11334 }
11335 } else {
11336 sigma_dut_print(dut, DUT_MSG_ERROR,
11337 "Unsupported power save config");
11338 return -1;
11339 }
11340 return 1;
11341 }
11342
11343 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported command");
11344
11345 return 0;
11346}
11347
11348
Ashwini Patil5acd7382017-04-13 15:55:04 +053011349static int btm_query_candidate_list(struct sigma_dut *dut,
11350 struct sigma_conn *conn,
11351 struct sigma_cmd *cmd)
11352{
11353 const char *bssid, *info, *op_class, *ch, *phy_type, *pref;
11354 int len, ret;
11355 char buf[10];
11356
11357 /*
11358 * Neighbor Report elements format:
11359 * neighbor=<BSSID>,<BSSID Information>,<Operating Class>,
11360 * <Channel Number>,<PHY Type>[,<hexdump of Optional Subelements>]
11361 * eg: neighbor=aa:bb:cc:dd:ee:ff,17,81,6,1,030101
11362 */
11363
11364 bssid = get_param(cmd, "Nebor_BSSID");
11365 if (!bssid) {
11366 send_resp(dut, conn, SIGMA_INVALID,
11367 "errorCode,Nebor_BSSID is missing");
11368 return 0;
11369 }
11370
11371 info = get_param(cmd, "Nebor_Bssid_Info");
11372 if (!info) {
11373 sigma_dut_print(dut, DUT_MSG_INFO,
11374 "Using default value for Nebor_Bssid_Info: %s",
11375 DEFAULT_NEIGHBOR_BSSID_INFO);
11376 info = DEFAULT_NEIGHBOR_BSSID_INFO;
11377 }
11378
11379 op_class = get_param(cmd, "Nebor_Op_Class");
11380 if (!op_class) {
11381 send_resp(dut, conn, SIGMA_INVALID,
11382 "errorCode,Nebor_Op_Class is missing");
11383 return 0;
11384 }
11385
11386 ch = get_param(cmd, "Nebor_Op_Ch");
11387 if (!ch) {
11388 send_resp(dut, conn, SIGMA_INVALID,
11389 "errorCode,Nebor_Op_Ch is missing");
11390 return 0;
11391 }
11392
11393 phy_type = get_param(cmd, "Nebor_Phy_Type");
11394 if (!phy_type) {
11395 sigma_dut_print(dut, DUT_MSG_INFO,
11396 "Using default value for Nebor_Phy_Type: %s",
11397 DEFAULT_NEIGHBOR_PHY_TYPE);
11398 phy_type = DEFAULT_NEIGHBOR_PHY_TYPE;
11399 }
11400
11401 /* Parse optional subelements */
11402 buf[0] = '\0';
11403 pref = get_param(cmd, "Nebor_Pref");
11404 if (pref) {
11405 /* hexdump for preferrence subelement */
11406 ret = snprintf(buf, sizeof(buf), ",0301%02x", atoi(pref));
11407 if (ret < 0 || ret >= (int) sizeof(buf)) {
11408 sigma_dut_print(dut, DUT_MSG_ERROR,
11409 "snprintf failed for optional subelement ret: %d",
11410 ret);
11411 send_resp(dut, conn, SIGMA_ERROR,
11412 "errorCode,snprintf failed for subelement");
11413 return 0;
11414 }
11415 }
11416
11417 if (!dut->btm_query_cand_list) {
11418 dut->btm_query_cand_list = calloc(1, NEIGHBOR_REPORT_SIZE);
11419 if (!dut->btm_query_cand_list) {
11420 send_resp(dut, conn, SIGMA_ERROR,
11421 "errorCode,Failed to allocate memory for btm_query_cand_list");
11422 return 0;
11423 }
11424 }
11425
11426 len = strlen(dut->btm_query_cand_list);
11427 ret = snprintf(dut->btm_query_cand_list + len,
11428 NEIGHBOR_REPORT_SIZE - len, " neighbor=%s,%s,%s,%s,%s%s",
11429 bssid, info, op_class, ch, phy_type, buf);
11430 if (ret < 0 || ret >= NEIGHBOR_REPORT_SIZE - len) {
11431 sigma_dut_print(dut, DUT_MSG_ERROR,
11432 "snprintf failed for neighbor report list ret: %d",
11433 ret);
11434 send_resp(dut, conn, SIGMA_ERROR,
11435 "errorCode,snprintf failed for neighbor report");
11436 free(dut->btm_query_cand_list);
11437 dut->btm_query_cand_list = NULL;
11438 return 0;
11439 }
11440
11441 return 1;
11442}
11443
11444
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020011445int sta_extract_60g_ese(struct sigma_dut *dut, struct sigma_cmd *cmd,
11446 struct sigma_ese_alloc *allocs, int *allocs_size)
11447{
11448 int max_count = *allocs_size;
11449 int count = 0, i;
11450 const char *val;
11451
11452 do {
11453 val = get_param_indexed(cmd, "AllocID", count);
11454 if (val)
11455 count++;
11456 } while (val);
11457
11458 if (count == 0 || count > max_count) {
11459 sigma_dut_print(dut, DUT_MSG_ERROR,
11460 "Invalid number of allocations(%d)", count);
11461 return -1;
11462 }
11463
11464 for (i = 0; i < count; i++) {
11465 val = get_param_indexed(cmd, "PercentBI", i);
11466 if (!val) {
11467 sigma_dut_print(dut, DUT_MSG_ERROR,
11468 "Missing PercentBI parameter at index %d",
11469 i);
11470 return -1;
11471 }
11472 allocs[i].percent_bi = atoi(val);
11473
11474 val = get_param_indexed(cmd, "SrcAID", i);
11475 if (val)
11476 allocs[i].src_aid = strtol(val, NULL, 0);
11477 else
11478 allocs[i].src_aid = ESE_BCAST_AID;
11479
11480 val = get_param_indexed(cmd, "DestAID", i);
11481 if (val)
11482 allocs[i].dst_aid = strtol(val, NULL, 0);
11483 else
11484 allocs[i].dst_aid = ESE_BCAST_AID;
11485
11486 allocs[i].type = ESE_CBAP;
11487 sigma_dut_print(dut, DUT_MSG_INFO,
11488 "Alloc %d PercentBI %d SrcAID %d DstAID %d",
11489 i, allocs[i].percent_bi, allocs[i].src_aid,
11490 allocs[i].dst_aid);
11491 }
11492
11493 *allocs_size = count;
11494 return 0;
11495}
11496
11497
11498static int sta_set_60g_ese(struct sigma_dut *dut, int count,
11499 struct sigma_ese_alloc *allocs)
11500{
11501 switch (get_driver_type()) {
11502#ifdef __linux__
11503 case DRIVER_WIL6210:
11504 if (wil6210_set_ese(dut, count, allocs))
11505 return -1;
11506 return 1;
11507#endif /* __linux__ */
11508 default:
11509 sigma_dut_print(dut, DUT_MSG_ERROR,
11510 "Unsupported sta_set_60g_ese with the current driver");
11511 return -1;
11512 }
11513}
11514
11515
11516static int cmd_sta_set_rfeature_60g(const char *intf, struct sigma_dut *dut,
11517 struct sigma_conn *conn,
11518 struct sigma_cmd *cmd)
11519{
11520 const char *val;
11521
11522 val = get_param(cmd, "ExtSchIE");
11523 if (val && !strcasecmp(val, "Enable")) {
11524 struct sigma_ese_alloc allocs[MAX_ESE_ALLOCS];
11525 int count = MAX_ESE_ALLOCS;
11526
11527 if (sta_extract_60g_ese(dut, cmd, allocs, &count))
11528 return -1;
11529 return sta_set_60g_ese(dut, count, allocs);
11530 }
11531
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +020011532 val = get_param(cmd, "MCS_FixedRate");
11533 if (val) {
11534 int sta_mcs = atoi(val);
11535
11536 sigma_dut_print(dut, DUT_MSG_INFO, "Force STA MCS to %d",
11537 sta_mcs);
11538 wil6210_set_force_mcs(dut, 1, sta_mcs);
11539
Jouni Malinen0e29cf22019-02-19 01:13:21 +020011540 return SUCCESS_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +020011541 }
11542
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020011543 send_resp(dut, conn, SIGMA_ERROR,
11544 "errorCode,Invalid sta_set_rfeature(60G)");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020011545 return STATUS_SENT;
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020011546}
11547
11548
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011549static int cmd_sta_set_rfeature(struct sigma_dut *dut, struct sigma_conn *conn,
11550 struct sigma_cmd *cmd)
11551{
11552 const char *intf = get_param(cmd, "Interface");
11553 const char *prog = get_param(cmd, "Prog");
Ashwini Patil68d02cd2017-01-10 15:39:16 +053011554 const char *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011555
11556 if (intf == NULL || prog == NULL)
11557 return -1;
11558
Ashwini Patil5acd7382017-04-13 15:55:04 +053011559 /* BSS Transition candidate list for BTM query */
11560 val = get_param(cmd, "Nebor_BSSID");
11561 if (val && btm_query_candidate_list(dut, conn, cmd) == 0)
11562 return 0;
11563
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011564 if (strcasecmp(prog, "TDLS") == 0)
11565 return cmd_sta_set_rfeature_tdls(intf, dut, conn, cmd);
11566
11567 if (strcasecmp(prog, "VHT") == 0)
11568 return cmd_sta_set_rfeature_vht(intf, dut, conn, cmd);
11569
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011570 if (strcasecmp(prog, "HE") == 0)
11571 return cmd_sta_set_rfeature_he(intf, dut, conn, cmd);
11572
Ashwini Patil68d02cd2017-01-10 15:39:16 +053011573 if (strcasecmp(prog, "MBO") == 0) {
11574 val = get_param(cmd, "Cellular_Data_Cap");
11575 if (val &&
11576 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
11577 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +053011578
11579 val = get_param(cmd, "Ch_Pref");
11580 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
11581 return 0;
11582
Ashwini Patil68d02cd2017-01-10 15:39:16 +053011583 return 1;
11584 }
11585
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020011586 if (strcasecmp(prog, "60GHz") == 0)
11587 return cmd_sta_set_rfeature_60g(intf, dut, conn, cmd);
11588
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011589 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported Prog");
11590 return 0;
11591}
11592
11593
11594static int cmd_sta_set_radio(struct sigma_dut *dut, struct sigma_conn *conn,
11595 struct sigma_cmd *cmd)
11596{
11597 const char *intf = get_param(cmd, "Interface");
11598 const char *mode = get_param(cmd, "Mode");
11599 int res;
11600
11601 if (intf == NULL || mode == NULL)
11602 return -1;
11603
11604 if (strcasecmp(mode, "On") == 0)
11605 res = wpa_command(intf, "SET radio_disabled 0");
11606 else if (strcasecmp(mode, "Off") == 0)
11607 res = wpa_command(intf, "SET radio_disabled 1");
11608 else
11609 return -1;
11610
11611 if (res) {
11612 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
11613 "radio mode");
11614 return 0;
11615 }
11616
11617 return 1;
11618}
11619
11620
11621static int cmd_sta_set_pwrsave(struct sigma_dut *dut, struct sigma_conn *conn,
11622 struct sigma_cmd *cmd)
11623{
11624 const char *intf = get_param(cmd, "Interface");
11625 const char *mode = get_param(cmd, "Mode");
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020011626 const char *prog = get_param(cmd, "program");
11627 const char *powersave = get_param(cmd, "powersave");
11628 int res = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011629
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020011630 if (intf == NULL)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011631 return -1;
11632
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020011633 if (prog && strcasecmp(prog, "60GHz") == 0) {
11634 /*
11635 * The CAPI mode parameter does not exist in 60G
11636 * unscheduled PS.
11637 */
11638 if (strcasecmp(powersave, "unscheduled") == 0)
11639 res = set_ps(intf, dut, 1);
Alexei Avshalom Lazar2f6fdb42019-02-04 14:16:08 +020011640 } else if (prog && get_driver_type() == DRIVER_WCN &&
11641 strcasecmp(prog, "HE") == 0) {
11642 return cmd_sta_set_power_save_he(intf, dut, conn, cmd);
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020011643 } else {
11644 if (mode == NULL)
11645 return -1;
11646
11647 if (strcasecmp(mode, "On") == 0)
11648 res = set_ps(intf, dut, 1);
11649 else if (strcasecmp(mode, "Off") == 0)
11650 res = set_ps(intf, dut, 0);
11651 else
11652 return -1;
11653 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011654
11655 if (res) {
11656 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
11657 "power save mode");
11658 return 0;
11659 }
11660
11661 return 1;
11662}
11663
11664
11665static int cmd_sta_bssid_pool(struct sigma_dut *dut, struct sigma_conn *conn,
11666 struct sigma_cmd *cmd)
11667{
11668 const char *intf = get_param(cmd, "Interface");
11669 const char *val, *bssid;
11670 int res;
11671 char *buf;
11672 size_t buf_len;
11673
11674 val = get_param(cmd, "BSSID_FILTER");
11675 if (val == NULL)
11676 return -1;
11677
11678 bssid = get_param(cmd, "BSSID_List");
11679 if (atoi(val) == 0 || bssid == NULL) {
11680 /* Disable BSSID filter */
11681 if (wpa_command(intf, "SET bssid_filter ")) {
11682 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed "
11683 "to disable BSSID filter");
11684 return 0;
11685 }
11686
11687 return 1;
11688 }
11689
11690 buf_len = 100 + strlen(bssid);
11691 buf = malloc(buf_len);
11692 if (buf == NULL)
11693 return -1;
11694
11695 snprintf(buf, buf_len, "SET bssid_filter %s", bssid);
11696 res = wpa_command(intf, buf);
11697 free(buf);
11698 if (res) {
11699 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to enable "
11700 "BSSID filter");
11701 return 0;
11702 }
11703
11704 return 1;
11705}
11706
11707
11708static int cmd_sta_reset_parm(struct sigma_dut *dut, struct sigma_conn *conn,
11709 struct sigma_cmd *cmd)
11710{
11711 const char *intf = get_param(cmd, "Interface");
11712 const char *val;
11713
11714 /* TODO: ARP */
11715
11716 val = get_param(cmd, "HS2_CACHE_PROFILE");
11717 if (val && strcasecmp(val, "All") == 0)
11718 hs2_clear_credentials(intf);
11719
11720 return 1;
11721}
11722
11723
11724static int cmd_sta_get_key(struct sigma_dut *dut, struct sigma_conn *conn,
11725 struct sigma_cmd *cmd)
11726{
11727 const char *intf = get_param(cmd, "Interface");
11728 const char *key_type = get_param(cmd, "KeyType");
11729 char buf[100], resp[200];
11730
11731 if (key_type == NULL)
11732 return -1;
11733
11734 if (strcasecmp(key_type, "GTK") == 0) {
11735 if (wpa_command_resp(intf, "GET gtk", buf, sizeof(buf)) < 0 ||
11736 strncmp(buf, "FAIL", 4) == 0) {
11737 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
11738 "not fetch current GTK");
11739 return 0;
11740 }
11741 snprintf(resp, sizeof(resp), "KeyValue,%s", buf);
11742 send_resp(dut, conn, SIGMA_COMPLETE, resp);
11743 return 0;
11744 } else {
11745 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
11746 "KeyType");
11747 return 0;
11748 }
11749
11750 return 1;
11751}
11752
11753
11754static int hs2_set_policy(struct sigma_dut *dut)
11755{
11756#ifdef ANDROID
11757 system("ip rule del prio 23000");
11758 if (system("ip rule add from all lookup main prio 23000") != 0) {
11759 sigma_dut_print(dut, DUT_MSG_ERROR,
11760 "Failed to run:ip rule add from all lookup main prio");
11761 return -1;
11762 }
11763 if (system("ip route flush cache") != 0) {
11764 sigma_dut_print(dut, DUT_MSG_ERROR,
11765 "Failed to run ip route flush cache");
11766 return -1;
11767 }
11768 return 1;
11769#else /* ANDROID */
11770 return 0;
11771#endif /* ANDROID */
11772}
11773
11774
11775static int cmd_sta_hs2_associate(struct sigma_dut *dut,
11776 struct sigma_conn *conn,
11777 struct sigma_cmd *cmd)
11778{
11779 const char *intf = get_param(cmd, "Interface");
11780 const char *val = get_param(cmd, "Ignore_blacklist");
Jouni Malinen439352d2018-09-13 03:42:23 +030011781 const char *band = get_param(cmd, "Band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011782 struct wpa_ctrl *ctrl;
11783 int res;
11784 char bssid[20], ssid[40], resp[100], buf[100], blacklisted[100];
11785 int tries = 0;
11786 int ignore_blacklist = 0;
11787 const char *events[] = {
11788 "CTRL-EVENT-CONNECTED",
11789 "INTERWORKING-BLACKLISTED",
11790 "INTERWORKING-NO-MATCH",
11791 NULL
11792 };
11793
11794 start_sta_mode(dut);
11795
Jouni Malinen439352d2018-09-13 03:42:23 +030011796 if (band) {
11797 if (strcmp(band, "2.4") == 0) {
11798 wpa_command(intf, "SET setband 2G");
11799 } else if (strcmp(band, "5") == 0) {
11800 wpa_command(intf, "SET setband 5G");
11801 } else {
11802 send_resp(dut, conn, SIGMA_ERROR,
11803 "errorCode,Unsupported band");
11804 return 0;
11805 }
11806 }
11807
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011808 blacklisted[0] = '\0';
11809 if (val && atoi(val))
11810 ignore_blacklist = 1;
11811
11812try_again:
11813 ctrl = open_wpa_mon(intf);
11814 if (ctrl == NULL) {
11815 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
11816 "wpa_supplicant monitor connection");
11817 return -2;
11818 }
11819
11820 tries++;
11821 if (wpa_command(intf, "INTERWORKING_SELECT auto")) {
11822 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start "
11823 "Interworking connection");
11824 wpa_ctrl_detach(ctrl);
11825 wpa_ctrl_close(ctrl);
11826 return 0;
11827 }
11828
11829 buf[0] = '\0';
11830 while (1) {
11831 char *pos;
11832 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
11833 pos = strstr(buf, "INTERWORKING-BLACKLISTED");
11834 if (!pos)
11835 break;
11836 pos += 25;
11837 sigma_dut_print(dut, DUT_MSG_DEBUG, "Found blacklisted AP: %s",
11838 pos);
11839 if (!blacklisted[0])
11840 memcpy(blacklisted, pos, strlen(pos) + 1);
11841 }
11842
11843 if (ignore_blacklist && blacklisted[0]) {
11844 char *end;
11845 end = strchr(blacklisted, ' ');
11846 if (end)
11847 *end = '\0';
11848 sigma_dut_print(dut, DUT_MSG_DEBUG, "Try to connect to a blacklisted network: %s",
11849 blacklisted);
11850 snprintf(buf, sizeof(buf), "INTERWORKING_CONNECT %s",
11851 blacklisted);
11852 if (wpa_command(intf, buf)) {
11853 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start Interworking connection to blacklisted network");
11854 wpa_ctrl_detach(ctrl);
11855 wpa_ctrl_close(ctrl);
11856 return 0;
11857 }
11858 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
11859 buf, sizeof(buf));
11860 }
11861
11862 wpa_ctrl_detach(ctrl);
11863 wpa_ctrl_close(ctrl);
11864
11865 if (res < 0) {
11866 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
11867 "connect");
11868 return 0;
11869 }
11870
11871 if (strstr(buf, "INTERWORKING-NO-MATCH") ||
11872 strstr(buf, "INTERWORKING-BLACKLISTED")) {
11873 if (tries < 2) {
11874 sigma_dut_print(dut, DUT_MSG_INFO, "No match found - try again to verify no APs were missed in the scan");
11875 goto try_again;
11876 }
11877 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,No network with "
11878 "matching credentials found");
11879 return 0;
11880 }
11881
11882 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
11883 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
11884 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
11885 "get current BSSID/SSID");
11886 return 0;
11887 }
11888
11889 snprintf(resp, sizeof(resp), "SSID,%s,BSSID,%s", ssid, bssid);
11890 send_resp(dut, conn, SIGMA_COMPLETE, resp);
11891 hs2_set_policy(dut);
11892 return 0;
11893}
11894
11895
Jouni Malinenb639f1c2018-09-13 02:39:46 +030011896static int cmd_sta_hs2_venue_info(struct sigma_dut *dut,
11897 struct sigma_conn *conn,
11898 struct sigma_cmd *cmd)
11899{
11900 const char *intf = get_param(cmd, "Interface");
11901 const char *display = get_param(cmd, "Display");
11902 struct wpa_ctrl *ctrl;
11903 char buf[300], params[400], *pos;
11904 char bssid[20];
11905 int info_avail = 0;
11906 unsigned int old_timeout;
11907 int res;
11908
11909 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0) {
11910 send_resp(dut, conn, SIGMA_ERROR,
11911 "ErrorCode,Could not get current BSSID");
11912 return 0;
11913 }
11914 ctrl = open_wpa_mon(intf);
11915 if (!ctrl) {
11916 sigma_dut_print(dut, DUT_MSG_ERROR,
11917 "Failed to open wpa_supplicant monitor connection");
11918 return -2;
11919 }
11920
11921 snprintf(buf, sizeof(buf), "ANQP_GET %s 277", bssid);
11922 wpa_command(intf, buf);
11923
11924 res = get_wpa_cli_event(dut, ctrl, "GAS-QUERY-DONE", buf, sizeof(buf));
11925 if (res < 0) {
11926 send_resp(dut, conn, SIGMA_ERROR,
11927 "ErrorCode,Could not complete GAS query");
11928 goto fail;
11929 }
11930
11931 old_timeout = dut->default_timeout;
11932 dut->default_timeout = 2;
11933 res = get_wpa_cli_event(dut, ctrl, "RX-VENUE-URL", buf, sizeof(buf));
11934 dut->default_timeout = old_timeout;
11935 if (res < 0)
11936 goto done;
11937 pos = strchr(buf, ' ');
11938 if (!pos)
11939 goto done;
11940 pos++;
11941 pos = strchr(pos, ' ');
11942 if (!pos)
11943 goto done;
11944 pos++;
11945 info_avail = 1;
11946 snprintf(params, sizeof(params), "browser %s", pos);
11947
11948 if (display && strcasecmp(display, "Yes") == 0) {
11949 pid_t pid;
11950
11951 pid = fork();
11952 if (pid < 0) {
11953 perror("fork");
11954 return -1;
11955 }
11956
11957 if (pid == 0) {
11958 run_hs20_osu(dut, params);
11959 exit(0);
11960 }
11961 }
11962
11963done:
11964 snprintf(buf, sizeof(buf), "Info_available,%s",
11965 info_avail ? "Yes" : "No");
11966 send_resp(dut, conn, SIGMA_COMPLETE, buf);
11967fail:
11968 wpa_ctrl_detach(ctrl);
11969 wpa_ctrl_close(ctrl);
11970 return 0;
11971}
11972
11973
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011974static int sta_add_credential_uname_pwd(struct sigma_dut *dut,
11975 struct sigma_conn *conn,
11976 const char *ifname,
11977 struct sigma_cmd *cmd)
11978{
11979 const char *val;
11980 int id;
11981
11982 id = add_cred(ifname);
11983 if (id < 0)
11984 return -2;
11985 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
11986
11987 val = get_param(cmd, "prefer");
11988 if (val && atoi(val) > 0)
11989 set_cred(ifname, id, "priority", "1");
11990
11991 val = get_param(cmd, "REALM");
11992 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
11993 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
11994 "realm");
11995 return 0;
11996 }
11997
11998 val = get_param(cmd, "HOME_FQDN");
11999 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
12000 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12001 "home_fqdn");
12002 return 0;
12003 }
12004
12005 val = get_param(cmd, "Username");
12006 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
12007 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12008 "username");
12009 return 0;
12010 }
12011
12012 val = get_param(cmd, "Password");
12013 if (val && set_cred_quoted(ifname, id, "password", val) < 0) {
12014 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12015 "password");
12016 return 0;
12017 }
12018
12019 val = get_param(cmd, "ROOT_CA");
12020 if (val) {
12021 char fname[200];
12022 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
12023#ifdef __linux__
12024 if (!file_exists(fname)) {
12025 char msg[300];
12026 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
12027 "file (%s) not found", fname);
12028 send_resp(dut, conn, SIGMA_ERROR, msg);
12029 return 0;
12030 }
12031#endif /* __linux__ */
12032 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
12033 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12034 "not set root CA");
12035 return 0;
12036 }
12037 }
12038
12039 return 1;
12040}
12041
12042
12043static int update_devdetail_imsi(struct sigma_dut *dut, const char *imsi)
12044{
12045 FILE *in, *out;
12046 char buf[500];
12047 int found = 0;
12048
12049 in = fopen("devdetail.xml", "r");
12050 if (in == NULL)
12051 return -1;
12052 out = fopen("devdetail.xml.tmp", "w");
12053 if (out == NULL) {
12054 fclose(in);
12055 return -1;
12056 }
12057
12058 while (fgets(buf, sizeof(buf), in)) {
12059 char *pos = strstr(buf, "<IMSI>");
12060 if (pos) {
12061 sigma_dut_print(dut, DUT_MSG_INFO, "Updated DevDetail IMSI to %s",
12062 imsi);
12063 pos += 6;
12064 *pos = '\0';
12065 fprintf(out, "%s%s</IMSI>\n", buf, imsi);
12066 found++;
12067 } else {
12068 fprintf(out, "%s", buf);
12069 }
12070 }
12071
12072 fclose(out);
12073 fclose(in);
12074 if (found)
12075 rename("devdetail.xml.tmp", "devdetail.xml");
12076 else
12077 unlink("devdetail.xml.tmp");
12078
12079 return 0;
12080}
12081
12082
12083static int sta_add_credential_sim(struct sigma_dut *dut,
12084 struct sigma_conn *conn,
12085 const char *ifname, struct sigma_cmd *cmd)
12086{
12087 const char *val, *imsi = NULL;
12088 int id;
12089 char buf[200];
12090 int res;
12091 const char *pos;
12092 size_t mnc_len;
12093 char plmn_mcc[4];
12094 char plmn_mnc[4];
12095
12096 id = add_cred(ifname);
12097 if (id < 0)
12098 return -2;
12099 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
12100
12101 val = get_param(cmd, "prefer");
12102 if (val && atoi(val) > 0)
12103 set_cred(ifname, id, "priority", "1");
12104
12105 val = get_param(cmd, "PLMN_MCC");
12106 if (val == NULL) {
12107 send_resp(dut, conn, SIGMA_ERROR,
12108 "errorCode,Missing PLMN_MCC");
12109 return 0;
12110 }
12111 if (strlen(val) != 3) {
12112 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MCC");
12113 return 0;
12114 }
12115 snprintf(plmn_mcc, sizeof(plmn_mcc), "%s", val);
12116
12117 val = get_param(cmd, "PLMN_MNC");
12118 if (val == NULL) {
12119 send_resp(dut, conn, SIGMA_ERROR,
12120 "errorCode,Missing PLMN_MNC");
12121 return 0;
12122 }
12123 if (strlen(val) != 2 && strlen(val) != 3) {
12124 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MNC");
12125 return 0;
12126 }
12127 snprintf(plmn_mnc, sizeof(plmn_mnc), "%s", val);
12128
12129 val = get_param(cmd, "IMSI");
12130 if (val == NULL) {
12131 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing SIM "
12132 "IMSI");
12133 return 0;
12134 }
12135
12136 imsi = pos = val;
12137
12138 if (strncmp(plmn_mcc, pos, 3) != 0) {
12139 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MCC mismatch");
12140 return 0;
12141 }
12142 pos += 3;
12143
12144 mnc_len = strlen(plmn_mnc);
12145 if (mnc_len < 2) {
12146 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC not set");
12147 return 0;
12148 }
12149
12150 if (strncmp(plmn_mnc, pos, mnc_len) != 0) {
12151 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC mismatch");
12152 return 0;
12153 }
12154 pos += mnc_len;
12155
12156 res = snprintf(buf, sizeof(buf), "%s%s-%s",plmn_mcc, plmn_mnc, pos);
12157 if (res < 0 || res >= (int) sizeof(buf))
12158 return -1;
12159 if (set_cred_quoted(ifname, id, "imsi", buf) < 0) {
12160 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12161 "not set IMSI");
12162 return 0;
12163 }
12164
12165 val = get_param(cmd, "Password");
12166 if (val && set_cred_quoted(ifname, id, "milenage", val) < 0) {
12167 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12168 "not set password");
12169 return 0;
12170 }
12171
Jouni Malinenba630452018-06-22 11:49:59 +030012172 if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012173 /*
12174 * Set provisioning_sp for the test cases where SIM/USIM
12175 * provisioning is used.
12176 */
12177 if (val && set_cred_quoted(ifname, id, "provisioning_sp",
12178 "wi-fi.org") < 0) {
12179 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12180 "not set provisioning_sp");
12181 return 0;
12182 }
12183
12184 update_devdetail_imsi(dut, imsi);
12185 }
12186
12187 return 1;
12188}
12189
12190
12191static int sta_add_credential_cert(struct sigma_dut *dut,
12192 struct sigma_conn *conn,
12193 const char *ifname,
12194 struct sigma_cmd *cmd)
12195{
12196 const char *val;
12197 int id;
12198
12199 id = add_cred(ifname);
12200 if (id < 0)
12201 return -2;
12202 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
12203
12204 val = get_param(cmd, "prefer");
12205 if (val && atoi(val) > 0)
12206 set_cred(ifname, id, "priority", "1");
12207
12208 val = get_param(cmd, "REALM");
12209 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
12210 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12211 "realm");
12212 return 0;
12213 }
12214
12215 val = get_param(cmd, "HOME_FQDN");
12216 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
12217 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12218 "home_fqdn");
12219 return 0;
12220 }
12221
12222 val = get_param(cmd, "Username");
12223 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
12224 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12225 "username");
12226 return 0;
12227 }
12228
12229 val = get_param(cmd, "clientCertificate");
12230 if (val) {
12231 char fname[200];
12232 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
12233#ifdef __linux__
12234 if (!file_exists(fname)) {
12235 char msg[300];
12236 snprintf(msg, sizeof(msg),
12237 "ErrorCode,clientCertificate "
12238 "file (%s) not found", fname);
12239 send_resp(dut, conn, SIGMA_ERROR, msg);
12240 return 0;
12241 }
12242#endif /* __linux__ */
12243 if (set_cred_quoted(ifname, id, "client_cert", fname) < 0) {
12244 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12245 "not set client_cert");
12246 return 0;
12247 }
12248 if (set_cred_quoted(ifname, id, "private_key", fname) < 0) {
12249 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12250 "not set private_key");
12251 return 0;
12252 }
12253 }
12254
12255 val = get_param(cmd, "ROOT_CA");
12256 if (val) {
12257 char fname[200];
12258 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
12259#ifdef __linux__
12260 if (!file_exists(fname)) {
12261 char msg[300];
12262 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
12263 "file (%s) not found", fname);
12264 send_resp(dut, conn, SIGMA_ERROR, msg);
12265 return 0;
12266 }
12267#endif /* __linux__ */
12268 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
12269 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12270 "not set root CA");
12271 return 0;
12272 }
12273 }
12274
12275 return 1;
12276}
12277
12278
12279static int cmd_sta_add_credential(struct sigma_dut *dut,
12280 struct sigma_conn *conn,
12281 struct sigma_cmd *cmd)
12282{
12283 const char *intf = get_param(cmd, "Interface");
12284 const char *type;
12285
12286 start_sta_mode(dut);
12287
12288 type = get_param(cmd, "Type");
12289 if (!type)
12290 return -1;
12291
12292 if (strcasecmp(type, "uname_pwd") == 0)
12293 return sta_add_credential_uname_pwd(dut, conn, intf, cmd);
12294
12295 if (strcasecmp(type, "sim") == 0)
12296 return sta_add_credential_sim(dut, conn, intf, cmd);
12297
12298 if (strcasecmp(type, "cert") == 0)
12299 return sta_add_credential_cert(dut, conn, intf, cmd);
12300
12301 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported credential "
12302 "type");
12303 return 0;
12304}
12305
12306
12307static int cmd_sta_scan(struct sigma_dut *dut, struct sigma_conn *conn,
12308 struct sigma_cmd *cmd)
12309{
12310 const char *intf = get_param(cmd, "Interface");
vamsi krishna89ad8c62017-09-19 12:51:18 +053012311 const char *val, *bssid, *ssid;
Arif Hussain66a4af02019-02-07 15:04:51 -080012312 char buf[4096];
vamsi krishna89ad8c62017-09-19 12:51:18 +053012313 char ssid_hex[65];
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012314 int res;
12315
Arif Hussain66a4af02019-02-07 15:04:51 -080012316 val = get_param(cmd, "GetParameter");
12317 if (val && strcmp(val, "SSID_BSSID") == 0) {
12318 if (get_wpa_ssid_bssid(dut, get_station_ifname(),
12319 buf, sizeof(buf)) < 0) {
12320 sigma_dut_print(dut, DUT_MSG_ERROR,
12321 "Could not get ssid bssid");
12322 return ERROR_SEND_STATUS;
12323 }
12324
12325 sigma_dut_print(dut, DUT_MSG_INFO, "%s", buf);
12326 send_resp(dut, conn, SIGMA_COMPLETE, buf);
12327 return STATUS_SENT;
12328 }
12329
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012330 val = get_param(cmd, "HESSID");
12331 if (val) {
12332 res = snprintf(buf, sizeof(buf), "SET hessid %s", val);
12333 if (res < 0 || res >= (int) sizeof(buf))
12334 return -1;
12335 wpa_command(intf, buf);
12336 }
12337
12338 val = get_param(cmd, "ACCS_NET_TYPE");
12339 if (val) {
12340 res = snprintf(buf, sizeof(buf), "SET access_network_type %s",
12341 val);
12342 if (res < 0 || res >= (int) sizeof(buf))
12343 return -1;
12344 wpa_command(intf, buf);
12345 }
12346
vamsi krishna89ad8c62017-09-19 12:51:18 +053012347 bssid = get_param(cmd, "Bssid");
12348 ssid = get_param(cmd, "Ssid");
12349
12350 if (ssid) {
12351 if (2 * strlen(ssid) >= sizeof(ssid_hex)) {
12352 send_resp(dut, conn, SIGMA_ERROR,
12353 "ErrorCode,Too long SSID");
12354 return 0;
12355 }
12356 ascii2hexstr(ssid, ssid_hex);
12357 }
12358
12359 res = snprintf(buf, sizeof(buf), "SCAN%s%s%s%s",
12360 bssid ? " bssid=": "",
12361 bssid ? bssid : "",
12362 ssid ? " ssid " : "",
12363 ssid ? ssid_hex : "");
12364 if (res < 0 || res >= (int) sizeof(buf))
12365 return -1;
12366
12367 if (wpa_command(intf, buf)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012368 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not start "
12369 "scan");
12370 return 0;
12371 }
12372
12373 return 1;
12374}
12375
12376
Jouni Malinen5e5d43d2018-01-10 17:29:33 +020012377static int cmd_sta_scan_bss(struct sigma_dut *dut, struct sigma_conn *conn,
12378 struct sigma_cmd *cmd)
12379{
12380 const char *intf = get_param(cmd, "Interface");
12381 const char *bssid;
12382 char buf[4096], *pos;
12383 int freq, chan;
12384 char *ssid;
12385 char resp[100];
12386 int res;
12387 struct wpa_ctrl *ctrl;
12388
12389 bssid = get_param(cmd, "BSSID");
12390 if (!bssid) {
12391 send_resp(dut, conn, SIGMA_INVALID,
12392 "errorCode,BSSID argument is missing");
12393 return 0;
12394 }
12395
12396 ctrl = open_wpa_mon(intf);
12397 if (!ctrl) {
12398 sigma_dut_print(dut, DUT_MSG_ERROR,
12399 "Failed to open wpa_supplicant monitor connection");
12400 return -1;
12401 }
12402
12403 if (wpa_command(intf, "SCAN TYPE=ONLY")) {
12404 send_resp(dut, conn, SIGMA_ERROR,
12405 "errorCode,Could not start scan");
12406 wpa_ctrl_detach(ctrl);
12407 wpa_ctrl_close(ctrl);
12408 return 0;
12409 }
12410
12411 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
12412 buf, sizeof(buf));
12413
12414 wpa_ctrl_detach(ctrl);
12415 wpa_ctrl_close(ctrl);
12416
12417 if (res < 0) {
12418 send_resp(dut, conn, SIGMA_ERROR,
12419 "errorCode,Scan did not complete");
12420 return 0;
12421 }
12422
12423 snprintf(buf, sizeof(buf), "BSS %s", bssid);
12424 if (wpa_command_resp(intf, buf, buf, sizeof(buf)) < 0 ||
12425 strncmp(buf, "id=", 3) != 0) {
12426 send_resp(dut, conn, SIGMA_ERROR,
12427 "errorCode,Specified BSSID not found");
12428 return 0;
12429 }
12430
12431 pos = strstr(buf, "\nfreq=");
12432 if (!pos) {
12433 send_resp(dut, conn, SIGMA_ERROR,
12434 "errorCode,Channel not found");
12435 return 0;
12436 }
12437 freq = atoi(pos + 6);
12438 chan = freq_to_channel(freq);
12439
12440 pos = strstr(buf, "\nssid=");
12441 if (!pos) {
12442 send_resp(dut, conn, SIGMA_ERROR,
12443 "errorCode,SSID not found");
12444 return 0;
12445 }
12446 ssid = pos + 6;
12447 pos = strchr(ssid, '\n');
12448 if (pos)
12449 *pos = '\0';
12450 snprintf(resp, sizeof(resp), "ssid,%s,bsschannel,%d", ssid, chan);
12451 send_resp(dut, conn, SIGMA_COMPLETE, resp);
12452 return 0;
12453}
12454
12455
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012456static int cmd_sta_set_systime(struct sigma_dut *dut, struct sigma_conn *conn,
12457 struct sigma_cmd *cmd)
12458{
12459#ifdef __linux__
12460 struct timeval tv;
12461 struct tm tm;
12462 time_t t;
12463 const char *val;
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +053012464 int v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012465
12466 wpa_command(get_station_ifname(), "PMKSA_FLUSH");
12467
12468 memset(&tm, 0, sizeof(tm));
12469 val = get_param(cmd, "seconds");
12470 if (val)
12471 tm.tm_sec = atoi(val);
12472 val = get_param(cmd, "minutes");
12473 if (val)
12474 tm.tm_min = atoi(val);
12475 val = get_param(cmd, "hours");
12476 if (val)
12477 tm.tm_hour = atoi(val);
12478 val = get_param(cmd, "date");
12479 if (val)
12480 tm.tm_mday = atoi(val);
12481 val = get_param(cmd, "month");
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +053012482 if (val) {
12483 v = atoi(val);
12484 if (v < 1 || v > 12) {
12485 send_resp(dut, conn, SIGMA_INVALID,
12486 "errorCode,Invalid month");
12487 return 0;
12488 }
12489 tm.tm_mon = v - 1;
12490 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012491 val = get_param(cmd, "year");
12492 if (val) {
12493 int year = atoi(val);
12494#ifdef ANDROID
12495 if (year > 2035)
12496 year = 2035; /* years beyond 2035 not supported */
12497#endif /* ANDROID */
12498 tm.tm_year = year - 1900;
12499 }
12500 t = mktime(&tm);
12501 if (t == (time_t) -1) {
12502 send_resp(dut, conn, SIGMA_ERROR,
12503 "errorCode,Invalid date or time");
12504 return 0;
12505 }
12506
12507 memset(&tv, 0, sizeof(tv));
12508 tv.tv_sec = t;
12509
12510 if (settimeofday(&tv, NULL) < 0) {
12511 sigma_dut_print(dut, DUT_MSG_INFO, "settimeofday failed: %s",
12512 strerror(errno));
12513 send_resp(dut, conn, SIGMA_ERROR,
12514 "errorCode,Failed to set time");
12515 return 0;
12516 }
12517
12518 return 1;
12519#endif /* __linux__ */
12520
12521 return -1;
12522}
12523
12524
12525static int cmd_sta_osu(struct sigma_dut *dut, struct sigma_conn *conn,
12526 struct sigma_cmd *cmd)
12527{
12528 const char *intf = get_param(cmd, "Interface");
Jouni Malinen4c8681c2018-09-12 23:28:11 +030012529 const char *name, *osu_ssid, *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012530 int prod_ess_assoc = 1;
Jouni Malinen4c8681c2018-09-12 23:28:11 +030012531 char buf[300], bssid[100], ssid[100];
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012532 int res;
12533 struct wpa_ctrl *ctrl;
12534
12535 name = get_param(cmd, "osuFriendlyName");
Jouni Malinen4c8681c2018-09-12 23:28:11 +030012536 osu_ssid = get_param(cmd, "osu_ssid");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012537
12538 val = get_param(cmd, "ProdESSAssoc");
12539 if (val)
12540 prod_ess_assoc = atoi(val);
12541
12542 kill_dhcp_client(dut, intf);
12543 if (start_dhcp_client(dut, intf) < 0)
12544 return -2;
12545
12546 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger OSU");
12547 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
12548 res = snprintf(buf, sizeof(buf),
Jouni Malinen4c8681c2018-09-12 23:28:11 +030012549 "%s %s%s%s %s%s%s signup osu-ca.pem",
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012550 prod_ess_assoc ? "" : "-N",
12551 name ? "-O'" : "", name ? name : "",
Jouni Malinen4c8681c2018-09-12 23:28:11 +030012552 name ? "'" : "",
12553 osu_ssid ? "-o'" : "", osu_ssid ? osu_ssid : "",
12554 osu_ssid ? "'" : "");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012555
Kanchanapally, Vidyullatha12b66762015-12-31 16:46:42 +053012556 hs2_set_policy(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012557 if (run_hs20_osu(dut, buf) < 0) {
12558 FILE *f;
12559
12560 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to complete OSU");
12561
12562 f = fopen("hs20-osu-client.res", "r");
12563 if (f) {
12564 char resp[400], res[300], *pos;
12565 if (!fgets(res, sizeof(res), f))
12566 res[0] = '\0';
12567 pos = strchr(res, '\n');
12568 if (pos)
12569 *pos = '\0';
12570 fclose(f);
12571 sigma_dut_summary(dut, "hs20-osu-client provisioning failed: %s",
12572 res);
12573 snprintf(resp, sizeof(resp), "notify-send '%s'", res);
12574 if (system(resp) != 0) {
12575 }
12576 snprintf(resp, sizeof(resp),
12577 "SSID,,BSSID,,failureReason,%s", res);
12578 send_resp(dut, conn, SIGMA_COMPLETE, resp);
12579 return 0;
12580 }
12581
12582 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
12583 return 0;
12584 }
12585
12586 if (!prod_ess_assoc)
12587 goto report;
12588
12589 ctrl = open_wpa_mon(intf);
12590 if (ctrl == NULL) {
12591 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
12592 "wpa_supplicant monitor connection");
12593 return -1;
12594 }
12595
12596 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
12597 buf, sizeof(buf));
12598
12599 wpa_ctrl_detach(ctrl);
12600 wpa_ctrl_close(ctrl);
12601
12602 if (res < 0) {
12603 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to connect to "
12604 "network after OSU");
12605 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
12606 return 0;
12607 }
12608
12609report:
12610 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
12611 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
12612 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to get BSSID/SSID");
12613 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
12614 return 0;
12615 }
12616
12617 snprintf(buf, sizeof(buf), "SSID,%s,BSSID,%s", ssid, bssid);
12618 send_resp(dut, conn, SIGMA_COMPLETE, buf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012619 return 0;
12620}
12621
12622
12623static int cmd_sta_policy_update(struct sigma_dut *dut, struct sigma_conn *conn,
12624 struct sigma_cmd *cmd)
12625{
12626 const char *val;
12627 int timeout = 120;
12628
12629 val = get_param(cmd, "PolicyUpdate");
12630 if (val == NULL || atoi(val) == 0)
12631 return 1; /* No operation requested */
12632
12633 val = get_param(cmd, "Timeout");
12634 if (val)
12635 timeout = atoi(val);
12636
12637 if (timeout) {
12638 /* TODO: time out the command and return
12639 * PolicyUpdateStatus,TIMEOUT if needed. */
12640 }
12641
12642 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger policy update");
12643 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
12644 if (run_hs20_osu(dut, "pol_upd fqdn=wi-fi.org") < 0) {
12645 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,FAIL");
12646 return 0;
12647 }
12648
12649 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,SUCCESS");
12650 return 0;
12651}
12652
12653
12654static int cmd_sta_er_config(struct sigma_dut *dut, 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 const char *ssid = get_param(cmd, "SSID");
12661 const char *security = get_param(cmd, "Security");
12662 const char *passphrase = get_param(cmd, "Passphrase");
12663 const char *pin = get_param(cmd, "PIN");
12664 char buf[1000];
12665 char ssid_hex[200], passphrase_hex[200];
12666 const char *keymgmt, *cipher;
12667
12668 if (intf == NULL)
12669 intf = get_main_ifname();
12670
12671 if (!bssid) {
12672 send_resp(dut, conn, SIGMA_ERROR,
12673 "ErrorCode,Missing Bssid argument");
12674 return 0;
12675 }
12676
12677 if (!ssid) {
12678 send_resp(dut, conn, SIGMA_ERROR,
12679 "ErrorCode,Missing SSID argument");
12680 return 0;
12681 }
12682
12683 if (!security) {
12684 send_resp(dut, conn, SIGMA_ERROR,
12685 "ErrorCode,Missing Security argument");
12686 return 0;
12687 }
12688
12689 if (!passphrase) {
12690 send_resp(dut, conn, SIGMA_ERROR,
12691 "ErrorCode,Missing Passphrase argument");
12692 return 0;
12693 }
12694
12695 if (!pin) {
12696 send_resp(dut, conn, SIGMA_ERROR,
12697 "ErrorCode,Missing PIN argument");
12698 return 0;
12699 }
12700
vamsi krishna8c9c1562017-05-12 15:51:46 +053012701 if (2 * strlen(ssid) >= sizeof(ssid_hex) ||
12702 2 * strlen(passphrase) >= sizeof(passphrase_hex)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012703 send_resp(dut, conn, SIGMA_ERROR,
12704 "ErrorCode,Too long SSID/passphrase");
12705 return 0;
12706 }
12707
12708 ctrl = open_wpa_mon(intf);
12709 if (ctrl == NULL) {
12710 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
12711 "wpa_supplicant monitor connection");
12712 return -2;
12713 }
12714
12715 if (strcasecmp(security, "wpa2-psk") == 0) {
12716 keymgmt = "WPA2PSK";
12717 cipher = "CCMP";
12718 } else {
12719 wpa_ctrl_detach(ctrl);
12720 wpa_ctrl_close(ctrl);
12721 send_resp(dut, conn, SIGMA_ERROR,
12722 "ErrorCode,Unsupported Security value");
12723 return 0;
12724 }
12725
12726 ascii2hexstr(ssid, ssid_hex);
12727 ascii2hexstr(passphrase, passphrase_hex);
12728 snprintf(buf, sizeof(buf), "WPS_REG %s %s %s %s %s %s",
12729 bssid, pin, ssid_hex, keymgmt, cipher, passphrase_hex);
12730
12731 if (wpa_command(intf, buf) < 0) {
12732 wpa_ctrl_detach(ctrl);
12733 wpa_ctrl_close(ctrl);
12734 send_resp(dut, conn, SIGMA_ERROR,
12735 "ErrorCode,Failed to start registrar");
12736 return 0;
12737 }
12738
12739 snprintf(dut->er_oper_bssid, sizeof(dut->er_oper_bssid), "%s", bssid);
12740 dut->er_oper_performed = 1;
12741
12742 return wps_connection_event(dut, conn, ctrl, intf, 0);
12743}
12744
12745
12746static int cmd_sta_wps_connect_pw_token(struct sigma_dut *dut,
12747 struct sigma_conn *conn,
12748 struct sigma_cmd *cmd)
12749{
12750 struct wpa_ctrl *ctrl;
12751 const char *intf = get_param(cmd, "Interface");
12752 const char *bssid = get_param(cmd, "Bssid");
12753 char buf[100];
12754
12755 if (!bssid) {
12756 send_resp(dut, conn, SIGMA_ERROR,
12757 "ErrorCode,Missing Bssid argument");
12758 return 0;
12759 }
12760
12761 ctrl = open_wpa_mon(intf);
12762 if (ctrl == NULL) {
12763 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
12764 "wpa_supplicant monitor connection");
12765 return -2;
12766 }
12767
12768 snprintf(buf, sizeof(buf), "WPS_NFC %s", bssid);
12769
12770 if (wpa_command(intf, buf) < 0) {
12771 wpa_ctrl_detach(ctrl);
12772 wpa_ctrl_close(ctrl);
12773 send_resp(dut, conn, SIGMA_ERROR,
12774 "ErrorCode,Failed to start registrar");
12775 return 0;
12776 }
12777
12778 return wps_connection_event(dut, conn, ctrl, intf, 0);
12779}
12780
12781
vamsi krishna9b144002017-09-20 13:28:13 +053012782static int cmd_start_wps_registration(struct sigma_dut *dut,
12783 struct sigma_conn *conn,
12784 struct sigma_cmd *cmd)
12785{
12786 struct wpa_ctrl *ctrl;
12787 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020012788 const char *network_mode = get_param(cmd, "network_mode");
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020012789 const char *config_method = get_param(cmd, "WPSConfigMethod");
12790 const char *role;
vamsi krishna9b144002017-09-20 13:28:13 +053012791 int res;
12792 char buf[256];
12793 const char *events[] = {
12794 "CTRL-EVENT-CONNECTED",
12795 "WPS-OVERLAP-DETECTED",
12796 "WPS-TIMEOUT",
12797 "WPS-FAIL",
12798 NULL
12799 };
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020012800 int id = 0;
vamsi krishna9b144002017-09-20 13:28:13 +053012801
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020012802 /* 60G WPS tests do not pass Interface parameter */
12803 if (!intf)
12804 intf = get_main_ifname();
12805
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020012806 if (dut->mode == SIGMA_MODE_AP)
12807 return ap_wps_registration(dut, conn, cmd);
12808
12809 if (config_method) {
12810 /* WFA_CS_WPS_PIN_KEYPAD mode is set when using the
12811 * sta_wps_enter_pin before calling start_wps_registration. */
12812 if (strcasecmp(config_method, "PBC") == 0)
12813 dut->wps_method = WFA_CS_WPS_PBC;
12814 }
12815 if (dut->wps_method == WFA_CS_WPS_NOT_READY) {
12816 send_resp(dut, conn, SIGMA_ERROR,
12817 "ErrorCode,WPS parameters not yet set");
12818 return STATUS_SENT;
12819 }
12820
12821 /* Make sure WPS is enabled (also for STA mode) */
12822 dut->wps_disable = 0;
12823
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020012824 if (dut->band == WPS_BAND_60G && network_mode &&
12825 strcasecmp(network_mode, "PBSS") == 0) {
12826 sigma_dut_print(dut, DUT_MSG_DEBUG,
12827 "Set PBSS network mode, network id %d", id);
12828 if (set_network(get_station_ifname(), id, "pbss", "1") < 0)
12829 return -2;
12830 }
12831
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020012832 if (dut->force_rsn_ie) {
12833 sigma_dut_print(dut, DUT_MSG_DEBUG, "Force RSN_IE: %d",
12834 dut->force_rsn_ie);
12835 if (sta_60g_force_rsn_ie(dut, dut->force_rsn_ie) < 0) {
12836 sigma_dut_print(dut, DUT_MSG_INFO,
12837 "Failed to force RSN_IE");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020012838 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020012839 }
12840 }
12841
vamsi krishna9b144002017-09-20 13:28:13 +053012842 ctrl = open_wpa_mon(intf);
12843 if (!ctrl) {
12844 sigma_dut_print(dut, DUT_MSG_ERROR,
12845 "Failed to open wpa_supplicant monitor connection");
12846 return -2;
12847 }
12848
12849 role = get_param(cmd, "WpsRole");
12850 if (!role) {
12851 send_resp(dut, conn, SIGMA_INVALID,
12852 "ErrorCode,WpsRole not provided");
12853 goto fail;
12854 }
12855
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020012856 if (strcasecmp(role, "Enrollee") != 0) {
12857 /* Registrar role for STA not supported */
12858 send_resp(dut, conn, SIGMA_ERROR,
12859 "ErrorCode,Unsupported WpsRole value");
12860 goto fail;
12861 }
12862
12863 if (is_60g_sigma_dut(dut)) {
12864 if (dut->wps_method == WFA_CS_WPS_PBC)
12865 snprintf(buf, sizeof(buf), "WPS_PBC");
12866 else /* WFA_CS_WPS_PIN_KEYPAD */
12867 snprintf(buf, sizeof(buf), "WPS_PIN any %s",
12868 dut->wps_pin);
12869 if (wpa_command(intf, buf) < 0) {
12870 send_resp(dut, conn, SIGMA_ERROR,
12871 "ErrorCode,Failed to start WPS");
vamsi krishna9b144002017-09-20 13:28:13 +053012872 goto fail;
12873 }
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020012874 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
12875 if (res < 0) {
12876 send_resp(dut, conn, SIGMA_ERROR,
12877 "ErrorCode,WPS connection did not complete");
12878 goto fail;
12879 }
12880 if (strstr(buf, "WPS-TIMEOUT")) {
12881 send_resp(dut, conn, SIGMA_COMPLETE, "WpsState,NoPeer");
12882 } else if (strstr(buf, "WPS-OVERLAP-DETECTED")) {
12883 send_resp(dut, conn, SIGMA_COMPLETE,
12884 "WpsState,OverlapSession");
12885 } else if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
12886 send_resp(dut, conn, SIGMA_COMPLETE,
12887 "WpsState,Successful");
12888 } else {
12889 send_resp(dut, conn, SIGMA_COMPLETE,
12890 "WpsState,Failure");
12891 }
12892 } else {
12893 if (dut->wps_method == WFA_CS_WPS_PBC) {
vamsi krishna9b144002017-09-20 13:28:13 +053012894 if (wpa_command(intf, "WPS_PBC") < 0) {
12895 send_resp(dut, conn, SIGMA_ERROR,
12896 "ErrorCode,Failed to enable PBC");
12897 goto fail;
12898 }
12899 } else {
12900 /* TODO: PIN method */
12901 send_resp(dut, conn, SIGMA_ERROR,
12902 "ErrorCode,Unsupported WpsConfigMethod value");
12903 goto fail;
12904 }
12905 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
12906 if (res < 0) {
12907 send_resp(dut, conn, SIGMA_ERROR,
12908 "ErrorCode,WPS connection did not complete");
12909 goto fail;
12910 }
12911 if (strstr(buf, "WPS-TIMEOUT")) {
12912 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,NoPeer");
12913 } else if (strstr(buf, "WPS-OVERLAP-DETECTED")) {
12914 send_resp(dut, conn, SIGMA_ERROR,
12915 "ErrorCode,OverlapSession");
12916 } else if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
12917 send_resp(dut, conn, SIGMA_COMPLETE, "Successful");
12918 } else {
12919 send_resp(dut, conn, SIGMA_ERROR,
12920 "ErrorCode,WPS operation failed");
12921 }
vamsi krishna9b144002017-09-20 13:28:13 +053012922 }
12923
12924fail:
12925 wpa_ctrl_detach(ctrl);
12926 wpa_ctrl_close(ctrl);
12927 return 0;
12928}
12929
12930
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012931static int req_intf(struct sigma_cmd *cmd)
12932{
12933 return get_param(cmd, "interface") == NULL ? -1 : 0;
12934}
12935
12936
12937void sta_register_cmds(void)
12938{
12939 sigma_dut_reg_cmd("sta_get_ip_config", req_intf,
12940 cmd_sta_get_ip_config);
12941 sigma_dut_reg_cmd("sta_set_ip_config", req_intf,
12942 cmd_sta_set_ip_config);
12943 sigma_dut_reg_cmd("sta_get_info", req_intf, cmd_sta_get_info);
12944 sigma_dut_reg_cmd("sta_get_mac_address", req_intf,
12945 cmd_sta_get_mac_address);
12946 sigma_dut_reg_cmd("sta_is_connected", req_intf, cmd_sta_is_connected);
12947 sigma_dut_reg_cmd("sta_verify_ip_connection", req_intf,
12948 cmd_sta_verify_ip_connection);
12949 sigma_dut_reg_cmd("sta_get_bssid", req_intf, cmd_sta_get_bssid);
12950 sigma_dut_reg_cmd("sta_set_encryption", req_intf,
12951 cmd_sta_set_encryption);
12952 sigma_dut_reg_cmd("sta_set_psk", req_intf, cmd_sta_set_psk);
12953 sigma_dut_reg_cmd("sta_set_eaptls", req_intf, cmd_sta_set_eaptls);
12954 sigma_dut_reg_cmd("sta_set_eapttls", req_intf, cmd_sta_set_eapttls);
12955 sigma_dut_reg_cmd("sta_set_eapsim", req_intf, cmd_sta_set_eapsim);
12956 sigma_dut_reg_cmd("sta_set_peap", req_intf, cmd_sta_set_peap);
12957 sigma_dut_reg_cmd("sta_set_eapfast", req_intf, cmd_sta_set_eapfast);
12958 sigma_dut_reg_cmd("sta_set_eapaka", req_intf, cmd_sta_set_eapaka);
12959 sigma_dut_reg_cmd("sta_set_eapakaprime", req_intf,
12960 cmd_sta_set_eapakaprime);
12961 sigma_dut_reg_cmd("sta_set_security", req_intf, cmd_sta_set_security);
12962 sigma_dut_reg_cmd("sta_set_uapsd", req_intf, cmd_sta_set_uapsd);
12963 /* TODO: sta_set_ibss */
12964 /* TODO: sta_set_mode */
12965 sigma_dut_reg_cmd("sta_set_wmm", req_intf, cmd_sta_set_wmm);
12966 sigma_dut_reg_cmd("sta_associate", req_intf, cmd_sta_associate);
12967 /* TODO: sta_up_load */
12968 sigma_dut_reg_cmd("sta_preset_testparameters", req_intf,
12969 cmd_sta_preset_testparameters);
12970 /* TODO: sta_set_system */
12971 sigma_dut_reg_cmd("sta_set_11n", req_intf, cmd_sta_set_11n);
12972 /* TODO: sta_set_rifs_test */
12973 sigma_dut_reg_cmd("sta_set_wireless", req_intf, cmd_sta_set_wireless);
12974 sigma_dut_reg_cmd("sta_send_addba", req_intf, cmd_sta_send_addba);
12975 /* TODO: sta_send_coexist_mgmt */
12976 sigma_dut_reg_cmd("sta_disconnect", req_intf, cmd_sta_disconnect);
12977 sigma_dut_reg_cmd("sta_reassoc", req_intf, cmd_sta_reassoc);
12978 sigma_dut_reg_cmd("sta_reassociate", req_intf, cmd_sta_reassoc);
12979 sigma_dut_reg_cmd("sta_reset_default", req_intf,
12980 cmd_sta_reset_default);
12981 sigma_dut_reg_cmd("sta_send_frame", req_intf, cmd_sta_send_frame);
12982 sigma_dut_reg_cmd("sta_set_macaddr", req_intf, cmd_sta_set_macaddr);
12983 sigma_dut_reg_cmd("sta_set_rfeature", req_intf, cmd_sta_set_rfeature);
12984 sigma_dut_reg_cmd("sta_set_radio", req_intf, cmd_sta_set_radio);
12985 sigma_dut_reg_cmd("sta_set_pwrsave", req_intf, cmd_sta_set_pwrsave);
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020012986 sigma_dut_reg_cmd("sta_set_power_save", req_intf, cmd_sta_set_pwrsave);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012987 sigma_dut_reg_cmd("sta_bssid_pool", req_intf, cmd_sta_bssid_pool);
12988 sigma_dut_reg_cmd("sta_reset_parm", req_intf, cmd_sta_reset_parm);
12989 sigma_dut_reg_cmd("sta_get_key", req_intf, cmd_sta_get_key);
12990 sigma_dut_reg_cmd("sta_hs2_associate", req_intf,
12991 cmd_sta_hs2_associate);
Jouni Malinenb639f1c2018-09-13 02:39:46 +030012992 sigma_dut_reg_cmd("sta_hs2_venue_info", req_intf,
12993 cmd_sta_hs2_venue_info);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012994 sigma_dut_reg_cmd("sta_add_credential", req_intf,
12995 cmd_sta_add_credential);
12996 sigma_dut_reg_cmd("sta_scan", req_intf, cmd_sta_scan);
Jouni Malinen5e5d43d2018-01-10 17:29:33 +020012997 sigma_dut_reg_cmd("sta_scan_bss", req_intf, cmd_sta_scan_bss);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012998 sigma_dut_reg_cmd("sta_set_systime", NULL, cmd_sta_set_systime);
12999 sigma_dut_reg_cmd("sta_osu", req_intf, cmd_sta_osu);
13000 sigma_dut_reg_cmd("sta_policy_update", req_intf, cmd_sta_policy_update);
13001 sigma_dut_reg_cmd("sta_er_config", NULL, cmd_sta_er_config);
13002 sigma_dut_reg_cmd("sta_wps_connect_pw_token", req_intf,
13003 cmd_sta_wps_connect_pw_token);
Jouni Malinen82905202018-04-29 17:20:10 +030013004 sigma_dut_reg_cmd("sta_exec_action", NULL, cmd_sta_exec_action);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013005 sigma_dut_reg_cmd("sta_get_events", req_intf, cmd_sta_get_events);
13006 sigma_dut_reg_cmd("sta_get_parameter", req_intf, cmd_sta_get_parameter);
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020013007 sigma_dut_reg_cmd("start_wps_registration", NULL,
vamsi krishna9b144002017-09-20 13:28:13 +053013008 cmd_start_wps_registration);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013009}