blob: bb8863c0a927ed80b1b7f7a27ccaee29927f1325 [file] [log] [blame]
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001/*
2 * Sigma Control API DUT (station/AP)
3 * Copyright (c) 2010-2011, Atheros Communications, Inc.
Jouni Malinen9d7e31d2017-12-22 18:55:04 +02004 * Copyright (c) 2011-2017, Qualcomm Atheros, Inc.
Jouni Malinenc12ea4a2018-01-05 21:07:10 +02005 * Copyright (c) 2018, The Linux Foundation
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006 * All Rights Reserved.
7 * Licensed under the Clear BSD license. See README for more details.
8 */
9
10#include "sigma_dut.h"
11#include <sys/ioctl.h>
12#include <sys/stat.h>
Jouni Malinen82905202018-04-29 17:20:10 +030013#include <sys/wait.h>
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030014#include <ctype.h>
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015#ifdef __linux__
Lior Davidcc88b562017-01-03 18:52:09 +020016#include <regex.h>
17#include <dirent.h>
Jouni Malinencd4e3c32015-10-29 12:39:56 +020018#include <sys/time.h>
19#include <netpacket/packet.h>
20#include <linux/if_ether.h>
21#ifdef ANDROID
22#include <cutils/properties.h>
23#include <android/log.h>
24#include "keystore_get.h"
25#else /* ANDROID */
26#include <ifaddrs.h>
27#endif /* ANDROID */
28#include <netdb.h>
29#endif /* __linux__ */
30#ifdef __QNXNTO__
31#include <net/if_dl.h>
32#endif /* __QNXNTO__ */
33#include "wpa_ctrl.h"
34#include "wpa_helpers.h"
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -070035#include "miracast.h"
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -070036#include "qca-vendor_copy.h"
Jouni Malinencd4e3c32015-10-29 12:39:56 +020037
38/* Temporary files for sta_send_addba */
39#define VI_QOS_TMP_FILE "/tmp/vi-qos.tmp"
40#define VI_QOS_FILE "/tmp/vi-qos.txt"
41#define VI_QOS_REFFILE "/etc/vi-qos.txt"
42
43/*
44 * MTU for Ethernet need to take into account 8-byte SNAP header
45 * to be added when encapsulating Ethernet frame into 802.11
46 */
47#ifndef IEEE80211_MAX_DATA_LEN_DMG
48#define IEEE80211_MAX_DATA_LEN_DMG 7920
49#endif
50#ifndef IEEE80211_SNAP_LEN_DMG
51#define IEEE80211_SNAP_LEN_DMG 8
52#endif
53
Ashwini Patil00402582017-04-13 12:29:39 +053054#define NON_PREF_CH_LIST_SIZE 100
Ashwini Patil5acd7382017-04-13 15:55:04 +053055#define NEIGHBOR_REPORT_SIZE 1000
56#define DEFAULT_NEIGHBOR_BSSID_INFO "17"
57#define DEFAULT_NEIGHBOR_PHY_TYPE "1"
Ashwini Patil00402582017-04-13 12:29:39 +053058
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030059#define WIL_DEFAULT_BI 100
60
61/* default remain on channel time for transmitting frames (milliseconds) */
62#define WIL_TRANSMIT_FRAME_DEFAULT_ROC 500
63#define IEEE80211_P2P_ATTR_DEVICE_ID 3
64#define IEEE80211_P2P_ATTR_GROUP_ID 15
65
66/* describes tagged bytes in template frame file */
67struct template_frame_tag {
68 int num;
69 int offset;
70 size_t len;
71};
72
Jouni Malinencd4e3c32015-10-29 12:39:56 +020073extern char *sigma_wpas_ctrl;
74extern char *sigma_cert_path;
75extern enum driver_type wifi_chip_type;
76extern char *sigma_radio_ifname[];
77
Lior David0fe101e2017-03-09 16:09:50 +020078#ifdef __linux__
79#define WIL_WMI_MAX_PAYLOAD 248
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020080#define WIL_WMI_ESE_CFG_CMDID 0xa01
Lior David0fe101e2017-03-09 16:09:50 +020081#define WIL_WMI_BF_TRIG_CMDID 0x83a
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020082#define WIL_WMI_UNIT_TEST_CMDID 0x900
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030083#define WIL_WMI_P2P_CFG_CMDID 0x910
84#define WIL_WMI_START_LISTEN_CMDID 0x914
85#define WIL_WMI_DISCOVERY_STOP_CMDID 0x917
Lior David0fe101e2017-03-09 16:09:50 +020086
87struct wil_wmi_header {
88 uint8_t mid;
89 uint8_t reserved;
90 uint16_t cmd;
91 uint32_t ts;
92} __attribute__((packed));
93
94enum wil_wmi_bf_trig_type {
95 WIL_WMI_SLS,
96 WIL_WMI_BRP_RX,
97 WIL_WMI_BRP_TX,
98};
99
100struct wil_wmi_bf_trig_cmd {
101 /* enum wil_wmi_bf_trig_type */
102 uint32_t bf_type;
103 /* cid when type == WMI_BRP_RX */
104 uint32_t sta_id;
105 uint32_t reserved;
106 /* mac address when type = WIL_WMI_SLS */
107 uint8_t dest_mac[6];
108} __attribute__((packed));
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +0200109
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +0200110enum wil_wmi_sched_scheme_advertisment {
111 WIL_WMI_ADVERTISE_ESE_DISABLED,
112 WIL_WMI_ADVERTISE_ESE_IN_BEACON,
113 WIL_WMI_ADVERTISE_ESE_IN_ANNOUNCE_FRAME,
114};
115
116enum wil_wmi_ese_slot_type {
117 WIL_WMI_ESE_SP,
118 WIL_WMI_ESE_CBAP,
119 WIL_WMI_ESE_ANNOUNCE_NO_ACK,
120};
121
122struct wil_wmi_ese_slot {
123 /* offset from start of BI in microseconds */
124 uint32_t tbtt_offset;
125 uint8_t flags;
126 /* enum wil_wmi_ese_slot_type */
127 uint8_t slot_type;
128 /* duration in microseconds */
129 uint16_t duration;
130 /* frame exchange sequence duration, microseconds */
131 uint16_t tx_op;
132 /* time between 2 blocks for periodic allocation(microseconds) */
133 uint16_t period;
134 /* number of blocks in periodic allocation */
135 uint8_t num_blocks;
136 /* for semi-active allocations */
137 uint8_t idle_period;
138 uint8_t src_aid;
139 uint8_t dst_aid;
140 uint32_t reserved;
141} __attribute__((packed));
142
143#define WIL_WMI_MAX_ESE_SLOTS 4
144struct wil_wmi_ese_cfg {
145 uint8_t serial_num;
146 /* wil_wmi_sched_scheme_advertisment */
147 uint8_t ese_advertisment;
148 uint16_t flags;
149 uint8_t num_allocs;
150 uint8_t reserved[3];
151 uint64_t start_tbtt;
152 /* allocations list */
153 struct wil_wmi_ese_slot slots[WIL_WMI_MAX_ESE_SLOTS];
154} __attribute__((packed));
155
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +0200156#define WIL_WMI_UT_FORCE_MCS 6
157struct wil_wmi_force_mcs {
158 /* WIL_WMI_UT_HW_SYSAPI */
159 uint16_t module_id;
160 /* WIL_WMI_UT_FORCE_MCS */
161 uint16_t subtype_id;
162 /* cid (ignored in oob_mode, affects all stations) */
163 uint32_t cid;
164 /* 1 to force MCS, 0 to restore default behavior */
165 uint32_t force_enable;
166 /* MCS index, 0-12 */
167 uint32_t mcs;
168} __attribute__((packed));
169
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +0200170#define WIL_WMI_UT_HW_SYSAPI 10
171#define WIL_WMI_UT_FORCE_RSN_IE 0x29
172struct wil_wmi_force_rsn_ie {
173 /* WIL_WMI_UT_HW_SYSAPI */
174 uint16_t module_id;
175 /* WIL_WMI_UT_FORCE_RSN_IE */
176 uint16_t subtype_id;
177 /* 0 = no change, 1 = remove if exists, 2 = add if does not exist */
178 uint32_t state;
179} __attribute__((packed));
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +0300180
181enum wil_wmi_discovery_mode {
182 WMI_DISCOVERY_MODE_NON_OFFLOAD,
183 WMI_DISCOVERY_MODE_OFFLOAD,
184 WMI_DISCOVERY_MODE_PEER2PEER,
185};
186
187struct wil_wmi_p2p_cfg_cmd {
188 /* enum wil_wmi_discovery_mode */
189 uint8_t discovery_mode;
190 /* 0-based (wireless channel - 1) */
191 uint8_t channel;
192 /* set to WIL_DEFAULT_BI */
193 uint16_t bcon_interval;
194} __attribute__((packed));
Lior David0fe101e2017-03-09 16:09:50 +0200195#endif /* __linux__ */
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200196
197#ifdef ANDROID
198
199static int add_ipv6_rule(struct sigma_dut *dut, const char *ifname);
200
201#define ANDROID_KEYSTORE_GET 'g'
202#define ANDROID_KEYSTORE_GET_PUBKEY 'b'
203
204static int android_keystore_get(char cmd, const char *key, unsigned char *val)
205{
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200206 /* Android 4.3 changed keystore design, so need to use keystore_get() */
207#ifndef KEYSTORE_MESSAGE_SIZE
208#define KEYSTORE_MESSAGE_SIZE 65535
209#endif /* KEYSTORE_MESSAGE_SIZE */
210
211 ssize_t len;
212 uint8_t *value = NULL;
213
214 __android_log_print(ANDROID_LOG_DEBUG, "sigma_dut",
215 "keystore command '%c' key '%s' --> keystore_get",
216 cmd, key);
217
218 len = keystore_get(key, strlen(key), &value);
219 if (len < 0) {
220 __android_log_print(ANDROID_LOG_DEBUG, "sigma_dut",
221 "keystore_get() failed");
222 return -1;
223 }
224
225 if (len > KEYSTORE_MESSAGE_SIZE)
226 len = KEYSTORE_MESSAGE_SIZE;
227 memcpy(val, value, len);
228 free(value);
229 return len;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200230}
231#endif /* ANDROID */
232
233
234int set_ps(const char *intf, struct sigma_dut *dut, int enabled)
235{
236#ifdef __linux__
237 char buf[100];
238
239 if (wifi_chip_type == DRIVER_WCN) {
240 if (enabled) {
241 snprintf(buf, sizeof(buf), "iwpriv wlan0 dump 906");
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530242 if (system(buf) != 0)
243 goto set_power_save;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200244 } else {
245 snprintf(buf, sizeof(buf), "iwpriv wlan0 dump 905");
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530246 if (system(buf) != 0)
247 goto set_power_save;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200248 snprintf(buf, sizeof(buf), "iwpriv wlan0 dump 912");
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530249 if (system(buf) != 0)
250 goto set_power_save;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200251 }
252
253 return 0;
254 }
255
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530256set_power_save:
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200257 snprintf(buf, sizeof(buf), "./iw dev %s set power_save %s",
258 intf, enabled ? "on" : "off");
259 if (system(buf) != 0) {
260 snprintf(buf, sizeof(buf), "iw dev %s set power_save %s",
261 intf, enabled ? "on" : "off");
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530262 if (system(buf) != 0) {
263 sigma_dut_print(dut, DUT_MSG_ERROR,
264 "Failed to set power save %s",
265 enabled ? "on" : "off");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200266 return -1;
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530267 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200268 }
269
270 return 0;
271#else /* __linux__ */
272 return -1;
273#endif /* __linux__ */
274}
275
276
Lior Davidcc88b562017-01-03 18:52:09 +0200277#ifdef __linux__
Lior David0fe101e2017-03-09 16:09:50 +0200278
Lior Davidcc88b562017-01-03 18:52:09 +0200279static int wil6210_get_debugfs_dir(struct sigma_dut *dut, char *path,
280 size_t len)
281{
282 DIR *dir, *wil_dir;
283 struct dirent *entry;
284 int ret = -1;
285 const char *root_path = "/sys/kernel/debug/ieee80211";
286
287 dir = opendir(root_path);
288 if (!dir)
289 return -2;
290
291 while ((entry = readdir(dir))) {
292 if (strcmp(entry->d_name, ".") == 0 ||
293 strcmp(entry->d_name, "..") == 0)
294 continue;
295
296 if (snprintf(path, len, "%s/%s/wil6210",
297 root_path, entry->d_name) >= (int) len) {
298 ret = -3;
299 break;
300 }
301
302 wil_dir = opendir(path);
303 if (wil_dir) {
304 closedir(wil_dir);
305 ret = 0;
306 break;
307 }
308 }
309
310 closedir(dir);
311 return ret;
312}
Lior David0fe101e2017-03-09 16:09:50 +0200313
314
315static int wil6210_wmi_send(struct sigma_dut *dut, uint16_t command,
316 void *payload, uint16_t length)
317{
318 struct {
319 struct wil_wmi_header hdr;
320 char payload[WIL_WMI_MAX_PAYLOAD];
321 } __attribute__((packed)) cmd;
322 char buf[128], fname[128];
323 size_t towrite, written;
324 FILE *f;
Jouni Malinen3aa72862019-05-29 23:14:51 +0300325 int res;
Lior David0fe101e2017-03-09 16:09:50 +0200326
327 if (length > WIL_WMI_MAX_PAYLOAD) {
328 sigma_dut_print(dut, DUT_MSG_ERROR,
329 "payload too large(%u, max %u)",
330 length, WIL_WMI_MAX_PAYLOAD);
331 return -1;
332 }
333
334 memset(&cmd.hdr, 0, sizeof(cmd.hdr));
335 cmd.hdr.cmd = command;
336 memcpy(cmd.payload, payload, length);
337
338 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
339 sigma_dut_print(dut, DUT_MSG_ERROR,
340 "failed to get wil6210 debugfs dir");
341 return -1;
342 }
343
Jouni Malinen3aa72862019-05-29 23:14:51 +0300344 res = snprintf(fname, sizeof(fname), "%s/wmi_send", buf);
345 if (res < 0 || res >= sizeof(fname))
346 return -1;
Lior David0fe101e2017-03-09 16:09:50 +0200347 f = fopen(fname, "wb");
348 if (!f) {
349 sigma_dut_print(dut, DUT_MSG_ERROR,
350 "failed to open: %s", fname);
351 return -1;
352 }
353
354 towrite = sizeof(cmd.hdr) + length;
355 written = fwrite(&cmd, 1, towrite, f);
356 fclose(f);
357 if (written != towrite) {
358 sigma_dut_print(dut, DUT_MSG_ERROR,
359 "failed to send wmi %u", command);
360 return -1;
361 }
362
363 return 0;
364}
365
366
367static int wil6210_get_sta_info_field(struct sigma_dut *dut, const char *bssid,
368 const char *pattern, unsigned int *field)
369{
370 char buf[128], fname[128];
371 FILE *f;
372 regex_t re;
373 regmatch_t m[2];
Jouni Malinen3aa72862019-05-29 23:14:51 +0300374 int rc, ret = -1, res;
Lior David0fe101e2017-03-09 16:09:50 +0200375
376 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
377 sigma_dut_print(dut, DUT_MSG_ERROR,
378 "failed to get wil6210 debugfs dir");
379 return -1;
380 }
381
Jouni Malinen3aa72862019-05-29 23:14:51 +0300382 res = snprintf(fname, sizeof(fname), "%s/stations", buf);
383 if (res < 0 || res >= sizeof(fname))
384 return -1;
Lior David0fe101e2017-03-09 16:09:50 +0200385 f = fopen(fname, "r");
386 if (!f) {
387 sigma_dut_print(dut, DUT_MSG_ERROR,
388 "failed to open: %s", fname);
389 return -1;
390 }
391
392 if (regcomp(&re, pattern, REG_EXTENDED)) {
393 sigma_dut_print(dut, DUT_MSG_ERROR,
394 "regcomp failed: %s", pattern);
395 goto out;
396 }
397
398 /*
399 * find the entry for the mac address
400 * line is of the form: [n] 11:22:33:44:55:66 state AID aid
401 */
402 while (fgets(buf, sizeof(buf), f)) {
403 if (strcasestr(buf, bssid)) {
404 /* extract the field (CID/AID/state) */
405 rc = regexec(&re, buf, 2, m, 0);
406 if (!rc && (m[1].rm_so >= 0)) {
407 buf[m[1].rm_eo] = 0;
408 *field = atoi(&buf[m[1].rm_so]);
409 ret = 0;
410 break;
411 }
412 }
413 }
414
415 regfree(&re);
416 if (ret)
417 sigma_dut_print(dut, DUT_MSG_ERROR,
418 "could not extract field");
419
420out:
421 fclose(f);
422
423 return ret;
424}
425
426
427static int wil6210_get_cid(struct sigma_dut *dut, const char *bssid,
428 unsigned int *cid)
429{
430 const char *pattern = "\\[([0-9]+)\\]";
431
432 return wil6210_get_sta_info_field(dut, bssid, pattern, cid);
433}
434
435
436static int wil6210_send_brp_rx(struct sigma_dut *dut, const char *mac,
437 int l_rx)
438{
Rakesh Sunki556237d2017-03-30 14:49:31 -0700439 struct wil_wmi_bf_trig_cmd cmd;
Lior David0fe101e2017-03-09 16:09:50 +0200440 unsigned int cid;
441
Rakesh Sunki556237d2017-03-30 14:49:31 -0700442 memset(&cmd, 0, sizeof(cmd));
443
Lior David0fe101e2017-03-09 16:09:50 +0200444 if (wil6210_get_cid(dut, mac, &cid))
445 return -1;
446
447 cmd.bf_type = WIL_WMI_BRP_RX;
448 cmd.sta_id = cid;
449 /* training length (l_rx) is ignored, FW always uses length 16 */
450 return wil6210_wmi_send(dut, WIL_WMI_BF_TRIG_CMDID,
451 &cmd, sizeof(cmd));
452}
453
454
455static int wil6210_send_sls(struct sigma_dut *dut, const char *mac)
456{
Rakesh Sunki556237d2017-03-30 14:49:31 -0700457 struct wil_wmi_bf_trig_cmd cmd;
458
459 memset(&cmd, 0, sizeof(cmd));
Lior David0fe101e2017-03-09 16:09:50 +0200460
461 if (parse_mac_address(dut, mac, (unsigned char *)&cmd.dest_mac))
462 return -1;
463
464 cmd.bf_type = WIL_WMI_SLS;
465 return wil6210_wmi_send(dut, WIL_WMI_BF_TRIG_CMDID,
466 &cmd, sizeof(cmd));
467}
468
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +0200469
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +0200470int wil6210_set_ese(struct sigma_dut *dut, int count,
471 struct sigma_ese_alloc *allocs)
472{
473 struct wil_wmi_ese_cfg cmd = { };
474 int i;
475
476 if (count == 0 || count > WIL_WMI_MAX_ESE_SLOTS)
477 return -1;
478
479 if (dut->ap_bcnint <= 0) {
480 sigma_dut_print(dut, DUT_MSG_ERROR,
481 "invalid beacon interval(%d), check test",
482 dut->ap_bcnint);
483 return -1;
484 }
485
486 cmd.ese_advertisment = WIL_WMI_ADVERTISE_ESE_IN_BEACON;
487 cmd.flags = 0x1d;
488 cmd.num_allocs = count;
489 for (i = 0; i < count; i++) {
490 /*
491 * Convert percent from BI (BI specified in milliseconds)
492 * to absolute duration in microseconds.
493 */
494 cmd.slots[i].duration =
495 (allocs[i].percent_bi * dut->ap_bcnint * 1000) / 100;
496 switch (allocs[i].type) {
497 case ESE_CBAP:
498 cmd.slots[i].slot_type = WIL_WMI_ESE_CBAP;
499 break;
500 case ESE_SP:
501 cmd.slots[i].slot_type = WIL_WMI_ESE_SP;
502 break;
503 default:
504 sigma_dut_print(dut, DUT_MSG_ERROR,
505 "invalid slot type(%d) at index %d",
506 allocs[i].type, i);
507 return -1;
508 }
509 cmd.slots[i].src_aid = allocs[i].src_aid;
510 cmd.slots[i].dst_aid = allocs[i].dst_aid;
511 sigma_dut_print(dut, DUT_MSG_INFO,
512 "slot %d, duration %u, type %d, srcAID %u dstAID %u",
513 i, cmd.slots[i].duration,
514 cmd.slots[i].slot_type, cmd.slots[i].src_aid,
515 cmd.slots[i].dst_aid);
516 }
517
518 return wil6210_wmi_send(dut, WIL_WMI_ESE_CFG_CMDID, &cmd, sizeof(cmd));
519}
520
521
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +0200522int wil6210_set_force_mcs(struct sigma_dut *dut, int force, int mcs)
523{
524 struct wil_wmi_force_mcs cmd = { };
525
526 cmd.module_id = WIL_WMI_UT_HW_SYSAPI;
527 cmd.subtype_id = WIL_WMI_UT_FORCE_MCS;
528 cmd.force_enable = (uint32_t) force;
529 cmd.mcs = (uint32_t) mcs;
530
531 return wil6210_wmi_send(dut, WIL_WMI_UNIT_TEST_CMDID,
532 &cmd, sizeof(cmd));
533}
534
535
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +0200536static int wil6210_force_rsn_ie(struct sigma_dut *dut, int state)
537{
538 struct wil_wmi_force_rsn_ie cmd = { };
539
540 cmd.module_id = WIL_WMI_UT_HW_SYSAPI;
541 cmd.subtype_id = WIL_WMI_UT_FORCE_RSN_IE;
542 cmd.state = (uint32_t) state;
543
544 return wil6210_wmi_send(dut, WIL_WMI_UNIT_TEST_CMDID,
545 &cmd, sizeof(cmd));
546}
547
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +0300548
549/*
550 * this function is also used to configure generic remain-on-channel
551 */
552static int wil6210_p2p_cfg(struct sigma_dut *dut, int freq)
553{
554 struct wil_wmi_p2p_cfg_cmd cmd = { };
555 int channel = freq_to_channel(freq);
556
557 if (channel < 0)
558 return -1;
559 cmd.discovery_mode = WMI_DISCOVERY_MODE_NON_OFFLOAD;
560 cmd.channel = channel - 1;
561 cmd.bcon_interval = WIL_DEFAULT_BI;
562 cmd.discovery_mode = WMI_DISCOVERY_MODE_PEER2PEER;
563
564 return wil6210_wmi_send(dut, WIL_WMI_P2P_CFG_CMDID,
565 &cmd, sizeof(cmd));
566}
567
568
569static int wil6210_remain_on_channel(struct sigma_dut *dut, int freq)
570{
571 int ret = wil6210_p2p_cfg(dut, freq);
572
573 if (ret)
574 return ret;
575
576 ret = wil6210_wmi_send(dut, WIL_WMI_START_LISTEN_CMDID, NULL, 0);
577 if (!ret) {
578 /*
579 * wait a bit to allow FW to setup the radio
580 * especially important if we switch channels
581 */
582 usleep(500000);
583 }
584
585 return ret;
586}
587
588
589static int wil6210_stop_discovery(struct sigma_dut *dut)
590{
591 return wil6210_wmi_send(dut, WIL_WMI_DISCOVERY_STOP_CMDID, NULL, 0);
592}
593
594
595static int wil6210_transmit_frame(struct sigma_dut *dut, int freq,
596 int wait_duration,
597 const char *frame, size_t frame_len)
598{
599 char buf[128], fname[128];
600 FILE *f;
Jouni Malinen3aa72862019-05-29 23:14:51 +0300601 int res = 0, r;
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +0300602 size_t written;
603
604 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
605 sigma_dut_print(dut, DUT_MSG_ERROR,
606 "failed to get wil6210 debugfs dir");
607 return -1;
608 }
Jouni Malinen3aa72862019-05-29 23:14:51 +0300609 r = snprintf(fname, sizeof(fname), "%s/tx_mgmt", buf);
610 if (r < 0 || r >= sizeof(fname))
611 return -1;
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +0300612
613 if (wil6210_remain_on_channel(dut, freq)) {
614 sigma_dut_print(dut, DUT_MSG_ERROR,
615 "failed to listen on channel");
616 return -1;
617 }
618
619 f = fopen(fname, "wb");
620 if (!f) {
621 sigma_dut_print(dut, DUT_MSG_ERROR,
622 "failed to open: %s", fname);
623 res = -1;
624 goto out_stop;
625 }
626 written = fwrite(frame, 1, frame_len, f);
627 fclose(f);
628
629 if (written != frame_len) {
630 sigma_dut_print(dut, DUT_MSG_ERROR,
631 "failed to transmit frame (got %zd, expected %zd)",
632 written, frame_len);
633 res = -1;
634 goto out_stop;
635 }
636
637 usleep(wait_duration * 1000);
638
639out_stop:
640 wil6210_stop_discovery(dut);
641 return res;
642}
643
644
645static int find_template_frame_tag(struct template_frame_tag *tags,
646 int total_tags, int tag_num)
647{
648 int i;
649
650 for (i = 0; i < total_tags; i++) {
651 if (tag_num == tags[i].num)
652 return i;
653 }
654
655 return -1;
656}
657
658
659static int replace_p2p_attribute(struct sigma_dut *dut, char *buf, size_t len,
660 int id, const char *value, size_t val_len)
661{
662 struct wfa_p2p_attribute *attr = (struct wfa_p2p_attribute *) buf;
663
664 if (len < 3 + val_len) {
665 sigma_dut_print(dut, DUT_MSG_ERROR,
666 "not enough space to replace P2P attribute");
667 return -1;
668 }
669
670 if (attr->len != val_len) {
671 sigma_dut_print(dut, DUT_MSG_ERROR,
672 "attribute length mismatch (need %zu have %hu)",
673 val_len, attr->len);
674 return -1;
675 }
676
677 if (attr->id != id) {
678 sigma_dut_print(dut, DUT_MSG_ERROR,
679 "incorrect attribute id (expected %d actual %d)",
680 id, attr->id);
681 return -1;
682 }
683
684 memcpy(attr->variable, value, val_len);
685
686 return 0;
687}
688
689
690static int parse_template_frame_file(struct sigma_dut *dut, const char *fname,
691 char *buf, size_t *length,
692 struct template_frame_tag *tags,
693 size_t *num_tags)
694{
695 char line[512];
696 FILE *f;
697 size_t offset = 0, tag_index = 0;
698 int num, index;
699 int in_tag = 0, tag_num = 0, tag_offset = 0;
700
701 if (*length < sizeof(struct ieee80211_hdr_3addr)) {
702 sigma_dut_print(dut, DUT_MSG_ERROR,
703 "supplied buffer is too small");
704 return -1;
705 }
706
707 f = fopen(fname, "r");
708 if (!f) {
709 sigma_dut_print(dut, DUT_MSG_ERROR,
710 "failed to open template file %s", fname);
711 return -1;
712 }
713
714 /*
715 * template file format: lines beginning with # are comments and
716 * ignored.
717 * It is possible to tag bytes in the frame to make it easy
718 * to replace fields in the template, espcially if they appear
719 * in variable-sized sections (such as IEs)
720 * This is done by a line beginning with $NUM where NUM is an integer
721 * tag number. It can be followed by space(s) and comment.
722 * The next line is considered the tagged bytes. The parser will fill
723 * the tag number, offset and length of the tagged bytes.
724 * rest of the lines contain frame bytes as sequence of hex digits,
725 * 2 digits for each byte. Spaces are allowed between bytes.
726 * On bytes lines only hex digits and spaces are allowed
727 */
728 while (!feof(f)) {
729 if (!fgets(line, sizeof(line), f))
730 break;
731 index = 0;
732 while (isspace((unsigned char) line[index]))
733 index++;
734 if (!line[index] || line[index] == '#')
735 continue;
736 if (line[index] == '$') {
737 if (tags) {
738 index++;
739 tag_num = strtol(&line[index], NULL, 0);
740 tag_offset = offset;
741 in_tag = 1;
742 }
743 continue;
744 }
745 while (line[index]) {
746 if (isspace((unsigned char) line[index])) {
747 index++;
748 continue;
749 }
750 num = hex_byte(&line[index]);
751 if (num < 0)
752 break;
753 buf[offset++] = num;
754 if (offset == *length)
755 goto out;
756 index += 2;
757 }
758
759 if (in_tag) {
760 if (tag_index < *num_tags) {
761 tags[tag_index].num = tag_num;
762 tags[tag_index].offset = tag_offset;
763 tags[tag_index].len = offset - tag_offset;
764 tag_index++;
765 } else {
766 sigma_dut_print(dut, DUT_MSG_INFO,
767 "too many tags, tag ignored");
768 }
769 in_tag = 0;
770 }
771 }
772
773 if (num_tags)
774 *num_tags = tag_index;
775out:
776 fclose(f);
777 if (offset < sizeof(struct ieee80211_hdr_3addr)) {
778 sigma_dut_print(dut, DUT_MSG_ERROR,
779 "template frame is too small");
780 return -1;
781 }
782
783 *length = offset;
784 return 0;
785}
786
Lior Davidcc88b562017-01-03 18:52:09 +0200787#endif /* __linux__ */
788
789
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200790static void static_ip_file(int proto, const char *addr, const char *mask,
791 const char *gw)
792{
793 if (proto) {
794 FILE *f = fopen("static-ip", "w");
795 if (f) {
796 fprintf(f, "%d %s %s %s\n", proto, addr,
797 mask ? mask : "N/A",
798 gw ? gw : "N/A");
799 fclose(f);
800 }
801 } else {
802 unlink("static-ip");
803 }
804}
805
806
807static int send_neighbor_request(struct sigma_dut *dut, const char *intf,
808 const char *ssid)
809{
810#ifdef __linux__
811 char buf[100];
812
813 snprintf(buf, sizeof(buf), "iwpriv %s neighbor %s",
814 intf, ssid);
815 sigma_dut_print(dut, DUT_MSG_INFO, "Request: %s", buf);
816
817 if (system(buf) != 0) {
818 sigma_dut_print(dut, DUT_MSG_ERROR,
819 "iwpriv neighbor request failed");
820 return -1;
821 }
822
823 sigma_dut_print(dut, DUT_MSG_INFO, "iwpriv neighbor request send");
824
825 return 0;
826#else /* __linux__ */
827 return -1;
828#endif /* __linux__ */
829}
830
831
832static int send_trans_mgmt_query(struct sigma_dut *dut, const char *intf,
Ashwini Patil5acd7382017-04-13 15:55:04 +0530833 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200834{
Ashwini Patil5acd7382017-04-13 15:55:04 +0530835 const char *val;
836 int reason_code = 0;
837 char buf[1024];
838
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200839 /*
840 * In the earlier builds we used WNM_QUERY and in later
841 * builds used WNM_BSS_QUERY.
842 */
843
Ashwini Patil5acd7382017-04-13 15:55:04 +0530844 val = get_param(cmd, "BTMQuery_Reason_Code");
845 if (val)
846 reason_code = atoi(val);
847
848 val = get_param(cmd, "Cand_List");
849 if (val && atoi(val) == 1 && dut->btm_query_cand_list) {
850 snprintf(buf, sizeof(buf), "WNM_BSS_QUERY %d%s", reason_code,
851 dut->btm_query_cand_list);
852 free(dut->btm_query_cand_list);
853 dut->btm_query_cand_list = NULL;
854 } else {
855 snprintf(buf, sizeof(buf), "WNM_BSS_QUERY %d", reason_code);
856 }
857
858 if (wpa_command(intf, buf) != 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200859 sigma_dut_print(dut, DUT_MSG_ERROR,
860 "transition management query failed");
861 return -1;
862 }
863
864 sigma_dut_print(dut, DUT_MSG_DEBUG,
865 "transition management query sent");
866
867 return 0;
868}
869
870
871int is_ip_addr(const char *str)
872{
873 const char *pos = str;
874 struct in_addr addr;
875
876 while (*pos) {
877 if (*pos != '.' && (*pos < '0' || *pos > '9'))
878 return 0;
879 pos++;
880 }
881
882 return inet_aton(str, &addr);
883}
884
885
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200886int get_ip_config(struct sigma_dut *dut, const char *ifname, char *buf,
887 size_t buf_len)
888{
vamsi krishnaa11d0732018-05-16 12:19:48 +0530889 char tmp[256];
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200890 char ip[16], mask[15], dns[16], sec_dns[16];
891 int is_dhcp = 0;
892 int s;
893#ifdef ANDROID
894 char prop[PROPERTY_VALUE_MAX];
vamsi krishnaa11d0732018-05-16 12:19:48 +0530895#else /* ANDROID */
896 FILE *f;
897#ifdef __linux__
898 const char *str_ps;
899#endif /* __linux__ */
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200900#endif /* ANDROID */
901
902 ip[0] = '\0';
903 mask[0] = '\0';
904 dns[0] = '\0';
905 sec_dns[0] = '\0';
906
907 s = socket(PF_INET, SOCK_DGRAM, 0);
908 if (s >= 0) {
909 struct ifreq ifr;
910 struct sockaddr_in saddr;
911
912 memset(&ifr, 0, sizeof(ifr));
Peng Xub8fc5cc2017-05-10 17:27:28 -0700913 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200914 if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
915 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to get "
916 "%s IP address: %s",
917 ifname, strerror(errno));
918 } else {
919 memcpy(&saddr, &ifr.ifr_addr,
920 sizeof(struct sockaddr_in));
Peng Xub8fc5cc2017-05-10 17:27:28 -0700921 strlcpy(ip, inet_ntoa(saddr.sin_addr), sizeof(ip));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200922 }
923
924 if (ioctl(s, SIOCGIFNETMASK, &ifr) == 0) {
925 memcpy(&saddr, &ifr.ifr_addr,
926 sizeof(struct sockaddr_in));
Peng Xub8fc5cc2017-05-10 17:27:28 -0700927 strlcpy(mask, inet_ntoa(saddr.sin_addr), sizeof(mask));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200928 }
929 close(s);
930 }
931
932#ifdef ANDROID
933 snprintf(tmp, sizeof(tmp), "dhcp.%s.pid", ifname);
934 if (property_get(tmp, prop, NULL) != 0 && atoi(prop) > 0) {
935 snprintf(tmp, sizeof(tmp), "dhcp.%s.result", ifname);
936 if (property_get(tmp, prop, NULL) != 0 &&
937 strcmp(prop, "ok") == 0) {
938 snprintf(tmp, sizeof(tmp), "dhcp.%s.ipaddress",
939 ifname);
940 if (property_get(tmp, prop, NULL) != 0 &&
941 strcmp(ip, prop) == 0)
942 is_dhcp = 1;
943 }
944 }
945
946 snprintf(tmp, sizeof(tmp), "dhcp.%s.dns1", ifname);
Peng Xub8fc5cc2017-05-10 17:27:28 -0700947 if (property_get(tmp, prop, NULL) != 0)
948 strlcpy(dns, prop, sizeof(dns));
949 else if (property_get("net.dns1", prop, NULL) != 0)
950 strlcpy(dns, prop, sizeof(dns));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200951
952 snprintf(tmp, sizeof(tmp), "dhcp.%s.dns2", ifname);
Peng Xub8fc5cc2017-05-10 17:27:28 -0700953 if (property_get(tmp, prop, NULL) != 0)
954 strlcpy(sec_dns, prop, sizeof(sec_dns));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200955#else /* ANDROID */
956#ifdef __linux__
Jouni Malinen016ae6c2019-11-04 17:00:01 +0200957 if (get_driver_type(dut) == DRIVER_OPENWRT)
Sarvepalli, Rajesh Babua76c6442016-03-18 20:34:26 +0530958 str_ps = "ps -w";
959 else
960 str_ps = "ps ax";
961 snprintf(tmp, sizeof(tmp),
962 "%s | grep dhclient | grep -v grep | grep -q %s",
963 str_ps, ifname);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200964 if (system(tmp) == 0)
965 is_dhcp = 1;
966 else {
Sarvepalli, Rajesh Babua76c6442016-03-18 20:34:26 +0530967 snprintf(tmp, sizeof(tmp),
968 "%s | grep udhcpc | grep -v grep | grep -q %s",
969 str_ps, ifname);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200970 if (system(tmp) == 0)
971 is_dhcp = 1;
972 else {
Sarvepalli, Rajesh Babua76c6442016-03-18 20:34:26 +0530973 snprintf(tmp, sizeof(tmp),
974 "%s | grep dhcpcd | grep -v grep | grep -q %s",
975 str_ps, ifname);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200976 if (system(tmp) == 0)
977 is_dhcp = 1;
978 }
979 }
980#endif /* __linux__ */
981
982 f = fopen("/etc/resolv.conf", "r");
983 if (f) {
vamsi krishnaa11d0732018-05-16 12:19:48 +0530984 char *pos, *pos2;
985
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200986 while (fgets(tmp, sizeof(tmp), f)) {
987 if (strncmp(tmp, "nameserver", 10) != 0)
988 continue;
989 pos = tmp + 10;
990 while (*pos == ' ' || *pos == '\t')
991 pos++;
992 pos2 = pos;
993 while (*pos2) {
994 if (*pos2 == '\n' || *pos2 == '\r') {
995 *pos2 = '\0';
996 break;
997 }
998 pos2++;
999 }
Peng Xub8fc5cc2017-05-10 17:27:28 -07001000 if (!dns[0])
1001 strlcpy(dns, pos, sizeof(dns));
1002 else if (!sec_dns[0])
1003 strlcpy(sec_dns, pos, sizeof(sec_dns));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001004 }
1005 fclose(f);
1006 }
1007#endif /* ANDROID */
1008
1009 snprintf(buf, buf_len, "dhcp,%d,ip,%s,mask,%s,primary-dns,%s",
1010 is_dhcp, ip, mask, dns);
1011 buf[buf_len - 1] = '\0';
1012
1013 return 0;
1014}
1015
1016
1017
1018
1019int get_ipv6_config(struct sigma_dut *dut, const char *ifname, char *buf,
1020 size_t buf_len)
1021{
1022#ifdef __linux__
1023#ifdef ANDROID
1024 char cmd[200], result[1000], *pos, *end;
1025 FILE *f;
1026 size_t len;
1027
1028 snprintf(cmd, sizeof(cmd), "ip addr show dev %s scope global", ifname);
1029 f = popen(cmd, "r");
1030 if (f == NULL)
1031 return -1;
1032 len = fread(result, 1, sizeof(result) - 1, f);
1033 pclose(f);
1034 if (len == 0)
1035 return -1;
1036 result[len] = '\0';
1037 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s result: %s\n", cmd, result);
1038
1039 pos = strstr(result, "inet6 ");
1040 if (pos == NULL)
1041 return -1;
1042 pos += 6;
1043 end = strchr(pos, ' ');
1044 if (end)
1045 *end = '\0';
1046 end = strchr(pos, '/');
1047 if (end)
1048 *end = '\0';
1049 snprintf(buf, buf_len, "ip,%s", pos);
1050 buf[buf_len - 1] = '\0';
1051 return 0;
1052#else /* ANDROID */
1053 struct ifaddrs *ifaddr, *ifa;
1054 int res, found = 0;
1055 char host[NI_MAXHOST];
1056
1057 if (getifaddrs(&ifaddr) < 0) {
1058 perror("getifaddrs");
1059 return -1;
1060 }
1061
1062 for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
1063 if (strcasecmp(ifname, ifa->ifa_name) != 0)
1064 continue;
1065 if (ifa->ifa_addr == NULL ||
1066 ifa->ifa_addr->sa_family != AF_INET6)
1067 continue;
1068
1069 res = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in6),
1070 host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
1071 if (res != 0) {
1072 sigma_dut_print(dut, DUT_MSG_DEBUG, "getnameinfo: %s",
1073 gai_strerror(res));
1074 continue;
1075 }
1076 if (strncmp(host, "fe80::", 6) == 0)
1077 continue; /* skip link-local */
1078
1079 sigma_dut_print(dut, DUT_MSG_DEBUG, "ifaddr: %s", host);
1080 found = 1;
1081 break;
1082 }
1083
1084 freeifaddrs(ifaddr);
1085
1086 if (found) {
1087 char *pos;
1088 pos = strchr(host, '%');
1089 if (pos)
1090 *pos = '\0';
1091 snprintf(buf, buf_len, "ip,%s", host);
1092 buf[buf_len - 1] = '\0';
1093 return 0;
1094 }
1095
1096#endif /* ANDROID */
1097#endif /* __linux__ */
1098 return -1;
1099}
1100
1101
Jouni Malinenf7222712019-06-13 01:50:21 +03001102static enum sigma_cmd_result cmd_sta_get_ip_config(struct sigma_dut *dut,
1103 struct sigma_conn *conn,
1104 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001105{
1106 const char *intf = get_param(cmd, "Interface");
1107 const char *ifname;
1108 char buf[200];
1109 const char *val;
1110 int type = 1;
1111
1112 if (intf == NULL)
1113 return -1;
1114
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001115 if (strcmp(intf, get_main_ifname(dut)) == 0)
1116 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001117 else
1118 ifname = intf;
1119
1120 /*
1121 * UCC may assume the IP address to be available immediately after
1122 * association without trying to run sta_get_ip_config multiple times.
1123 * Sigma CAPI does not specify this command as a block command that
1124 * would wait for the address to become available, but to pass tests
1125 * more reliably, it looks like such a wait may be needed here.
1126 */
1127 if (wait_ip_addr(dut, ifname, 15) < 0) {
1128 sigma_dut_print(dut, DUT_MSG_INFO, "Could not get IP address "
1129 "for sta_get_ip_config");
1130 /*
1131 * Try to continue anyway since many UCC tests do not really
1132 * care about the return value from here..
1133 */
1134 }
1135
1136 val = get_param(cmd, "Type");
1137 if (val)
1138 type = atoi(val);
1139 if (type == 2 || dut->last_set_ip_config_ipv6) {
1140 int i;
1141
1142 /*
1143 * Since we do not have proper wait for IPv6 addresses, use a
1144 * fixed two second delay here as a workaround for UCC script
1145 * assuming IPv6 address is available when this command returns.
1146 * Some scripts did not use Type,2 properly for IPv6, so include
1147 * also the cases where the previous sta_set_ip_config indicated
1148 * use of IPv6.
1149 */
1150 sigma_dut_print(dut, DUT_MSG_INFO, "Wait up to extra ten seconds in sta_get_ip_config for IPv6 address");
1151 for (i = 0; i < 10; i++) {
1152 sleep(1);
1153 if (get_ipv6_config(dut, ifname, buf, sizeof(buf)) == 0)
1154 {
1155 sigma_dut_print(dut, DUT_MSG_INFO, "Found IPv6 address");
1156 send_resp(dut, conn, SIGMA_COMPLETE, buf);
1157#ifdef ANDROID
1158 sigma_dut_print(dut, DUT_MSG_INFO,
1159 "Adding IPv6 rule on Android");
1160 add_ipv6_rule(dut, intf);
1161#endif /* ANDROID */
1162
1163 return 0;
1164 }
1165 }
1166 }
1167 if (type == 1) {
1168 if (get_ip_config(dut, ifname, buf, sizeof(buf)) < 0)
1169 return -2;
1170 } else if (type == 2) {
1171 if (get_ipv6_config(dut, ifname, buf, sizeof(buf)) < 0)
1172 return -2;
1173 } else {
1174 send_resp(dut, conn, SIGMA_ERROR,
1175 "errorCode,Unsupported address type");
1176 return 0;
1177 }
1178
1179 send_resp(dut, conn, SIGMA_COMPLETE, buf);
1180 return 0;
1181}
1182
1183
1184static void kill_dhcp_client(struct sigma_dut *dut, const char *ifname)
1185{
1186#ifdef __linux__
1187 char buf[200];
1188 char path[128];
1189 struct stat s;
1190
1191#ifdef ANDROID
1192 snprintf(path, sizeof(path), "/data/misc/dhcp/dhcpcd-%s.pid", ifname);
1193#else /* ANDROID */
1194 snprintf(path, sizeof(path), "/var/run/dhclient-%s.pid", ifname);
1195#endif /* ANDROID */
1196 if (stat(path, &s) == 0) {
1197 snprintf(buf, sizeof(buf), "kill `cat %s`", path);
1198 sigma_dut_print(dut, DUT_MSG_INFO,
1199 "Kill previous DHCP client: %s", buf);
1200 if (system(buf) != 0)
1201 sigma_dut_print(dut, DUT_MSG_INFO,
1202 "Failed to kill DHCP client");
1203 unlink(path);
1204 sleep(1);
1205 } else {
1206 snprintf(path, sizeof(path), "/var/run/dhcpcd-%s.pid", ifname);
1207
1208 if (stat(path, &s) == 0) {
1209 snprintf(buf, sizeof(buf), "kill `cat %s`", path);
1210 sigma_dut_print(dut, DUT_MSG_INFO,
1211 "Kill previous DHCP client: %s", buf);
1212 if (system(buf) != 0)
1213 sigma_dut_print(dut, DUT_MSG_INFO,
1214 "Failed to kill DHCP client");
1215 unlink(path);
1216 sleep(1);
1217 }
1218 }
1219#endif /* __linux__ */
1220}
1221
1222
1223static int start_dhcp_client(struct sigma_dut *dut, const char *ifname)
1224{
1225#ifdef __linux__
1226 char buf[200];
1227
1228#ifdef ANDROID
Purushottam Kushwaha46d64262016-08-23 17:57:53 +05301229 if (access("/system/bin/dhcpcd", F_OK) != -1) {
1230 snprintf(buf, sizeof(buf),
1231 "/system/bin/dhcpcd -b %s", ifname);
1232 } else if (access("/system/bin/dhcptool", F_OK) != -1) {
1233 snprintf(buf, sizeof(buf), "/system/bin/dhcptool %s &", ifname);
Ankita Bajaj8454e5d2019-04-05 16:04:55 +05301234 } else if (access("/vendor/bin/dhcpcd", F_OK) != -1) {
1235 snprintf(buf, sizeof(buf), "/vendor/bin/dhcpcd -b %s", ifname);
1236 } else if (access("/vendor/bin/dhcptool", F_OK) != -1) {
1237 snprintf(buf, sizeof(buf), "/vendor/bin/dhcptool %s", ifname);
Purushottam Kushwaha46d64262016-08-23 17:57:53 +05301238 } else {
1239 sigma_dut_print(dut, DUT_MSG_ERROR,
1240 "DHCP client program missing");
1241 return 0;
1242 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001243#else /* ANDROID */
1244 snprintf(buf, sizeof(buf),
1245 "dhclient -nw -pf /var/run/dhclient-%s.pid %s",
1246 ifname, ifname);
1247#endif /* ANDROID */
1248 sigma_dut_print(dut, DUT_MSG_INFO, "Start DHCP client: %s", buf);
1249 if (system(buf) != 0) {
1250 snprintf(buf, sizeof(buf), "dhcpcd -t 0 %s &", ifname);
1251 if (system(buf) != 0) {
1252 sigma_dut_print(dut, DUT_MSG_INFO,
1253 "Failed to start DHCP client");
1254#ifndef ANDROID
1255 return -1;
1256#endif /* ANDROID */
1257 }
1258 }
1259#endif /* __linux__ */
1260
1261 return 0;
1262}
1263
1264
1265static int clear_ip_addr(struct sigma_dut *dut, const char *ifname)
1266{
1267#ifdef __linux__
1268 char buf[200];
1269
1270 snprintf(buf, sizeof(buf), "ip addr flush dev %s", ifname);
1271 if (system(buf) != 0) {
1272 sigma_dut_print(dut, DUT_MSG_INFO,
1273 "Failed to clear IP addresses");
1274 return -1;
1275 }
1276#endif /* __linux__ */
1277
1278 return 0;
1279}
1280
1281
1282#ifdef ANDROID
1283static int add_ipv6_rule(struct sigma_dut *dut, const char *ifname)
1284{
1285 char cmd[200], *result, *pos;
1286 FILE *fp;
Pradeep Reddy POTTETIf58a1fe2016-10-13 17:22:03 +05301287 int tableid;
1288 size_t len, result_len = 1000;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001289
1290 snprintf(cmd, sizeof(cmd), "ip -6 route list table all | grep %s",
1291 ifname);
1292 fp = popen(cmd, "r");
1293 if (fp == NULL)
1294 return -1;
1295
1296 result = malloc(result_len);
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05301297 if (result == NULL) {
1298 fclose(fp);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001299 return -1;
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05301300 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001301
Pradeep Reddy POTTETIf58a1fe2016-10-13 17:22:03 +05301302 len = fread(result, 1, result_len - 1, fp);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001303 fclose(fp);
1304
1305 if (len == 0) {
1306 free(result);
1307 return -1;
1308 }
Pradeep Reddy POTTETIf58a1fe2016-10-13 17:22:03 +05301309 result[len] = '\0';
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001310
1311 pos = strstr(result, "table ");
1312 if (pos == NULL) {
1313 free(result);
1314 return -1;
1315 }
1316
1317 pos += strlen("table ");
1318 tableid = atoi(pos);
1319 if (tableid != 0) {
1320 if (system("ip -6 rule del prio 22000") != 0) {
1321 /* ignore any error */
1322 }
1323 snprintf(cmd, sizeof(cmd),
1324 "ip -6 rule add from all lookup %d prio 22000",
1325 tableid);
1326 if (system(cmd) != 0) {
1327 sigma_dut_print(dut, DUT_MSG_INFO,
1328 "Failed to run %s", cmd);
1329 free(result);
1330 return -1;
1331 }
1332 } else {
1333 sigma_dut_print(dut, DUT_MSG_INFO,
1334 "No Valid Table Id found %s", pos);
1335 free(result);
1336 return -1;
1337 }
1338 free(result);
1339
1340 return 0;
1341}
1342#endif /* ANDROID */
1343
1344
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301345int set_ipv4_addr(struct sigma_dut *dut, const char *ifname,
1346 const char *ip, const char *mask)
1347{
1348 char buf[200];
1349
1350 snprintf(buf, sizeof(buf), "ifconfig %s %s netmask %s",
1351 ifname, ip, mask);
1352 return system(buf) == 0;
1353}
1354
1355
1356int set_ipv4_gw(struct sigma_dut *dut, const char *gw)
1357{
1358 char buf[200];
1359
1360 if (!is_ip_addr(gw)) {
1361 sigma_dut_print(dut, DUT_MSG_DEBUG, "Invalid gw addr - %s", gw);
1362 return -1;
1363 }
1364
1365 snprintf(buf, sizeof(buf), "route add default gw %s", gw);
1366 if (!dut->no_ip_addr_set && system(buf) != 0) {
1367 snprintf(buf, sizeof(buf), "ip ro re default via %s",
1368 gw);
1369 if (system(buf) != 0)
1370 return 0;
1371 }
1372
1373 return 1;
1374}
1375
1376
Jouni Malinenf7222712019-06-13 01:50:21 +03001377static enum sigma_cmd_result cmd_sta_set_ip_config(struct sigma_dut *dut,
1378 struct sigma_conn *conn,
1379 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001380{
1381 const char *intf = get_param(cmd, "Interface");
1382 const char *ifname;
1383 char buf[200];
1384 const char *val, *ip, *mask, *gw;
1385 int type = 1;
1386
1387 if (intf == NULL)
1388 return -1;
1389
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001390 if (strcmp(intf, get_main_ifname(dut)) == 0)
1391 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001392 else
1393 ifname = intf;
1394
1395 if (if_nametoindex(ifname) == 0) {
1396 send_resp(dut, conn, SIGMA_ERROR,
1397 "ErrorCode,Unknown interface");
1398 return 0;
1399 }
1400
1401 val = get_param(cmd, "Type");
1402 if (val) {
1403 type = atoi(val);
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301404 if (type < 1 || type > 3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001405 send_resp(dut, conn, SIGMA_ERROR,
1406 "ErrorCode,Unsupported address type");
1407 return 0;
1408 }
1409 }
1410
1411 dut->last_set_ip_config_ipv6 = 0;
1412
1413 val = get_param(cmd, "dhcp");
1414 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "true") == 0)) {
1415 static_ip_file(0, NULL, NULL, NULL);
1416#ifdef __linux__
1417 if (type == 2) {
1418 dut->last_set_ip_config_ipv6 = 1;
1419 sigma_dut_print(dut, DUT_MSG_INFO, "Using IPv6 "
1420 "stateless address autoconfiguration");
1421#ifdef ANDROID
1422 /*
1423 * This sleep is required as the assignment in case of
1424 * Android is taking time and is done by the kernel.
1425 * The subsequent ping for IPv6 is impacting HS20 test
1426 * case.
1427 */
1428 sleep(2);
1429 add_ipv6_rule(dut, intf);
1430#endif /* ANDROID */
1431 /* Assume this happens by default */
1432 return 1;
1433 }
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301434 if (type != 3) {
1435 kill_dhcp_client(dut, ifname);
1436 if (start_dhcp_client(dut, ifname) < 0)
1437 return -2;
1438 } else {
1439 sigma_dut_print(dut, DUT_MSG_DEBUG,
1440 "Using FILS HLP DHCPv4 Rapid Commit");
1441 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001442
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001443 return 1;
1444#endif /* __linux__ */
1445 return -2;
1446 }
1447
1448 ip = get_param(cmd, "ip");
Pradeep Reddy POTTETIb18c5652016-01-18 12:45:37 +05301449 if (!ip) {
1450 send_resp(dut, conn, SIGMA_INVALID,
1451 "ErrorCode,Missing IP address");
1452 return 0;
1453 }
1454
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001455 mask = get_param(cmd, "mask");
Pradeep Reddy POTTETIb18c5652016-01-18 12:45:37 +05301456 if (!mask) {
1457 send_resp(dut, conn, SIGMA_INVALID,
1458 "ErrorCode,Missing subnet mask");
1459 return 0;
1460 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001461
1462 if (type == 2) {
1463 int net = atoi(mask);
1464
1465 if ((net < 0 && net > 64) || !is_ipv6_addr(ip))
1466 return -1;
1467
1468 if (dut->no_ip_addr_set) {
1469 snprintf(buf, sizeof(buf),
1470 "sysctl net.ipv6.conf.%s.disable_ipv6=1",
1471 ifname);
1472 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
1473 if (system(buf) != 0) {
1474 sigma_dut_print(dut, DUT_MSG_DEBUG,
1475 "Failed to disable IPv6 address before association");
1476 }
1477 } else {
1478 snprintf(buf, sizeof(buf),
1479 "ip -6 addr del %s/%s dev %s",
1480 ip, mask, ifname);
1481 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
1482 if (system(buf) != 0) {
1483 /*
1484 * This command may fail if the address being
1485 * deleted does not exist. Inaction here is
1486 * intentional.
1487 */
1488 }
1489
1490 snprintf(buf, sizeof(buf),
1491 "ip -6 addr add %s/%s dev %s",
1492 ip, mask, ifname);
1493 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
1494 if (system(buf) != 0) {
1495 send_resp(dut, conn, SIGMA_ERROR,
1496 "ErrorCode,Failed to set IPv6 address");
1497 return 0;
1498 }
1499 }
1500
1501 dut->last_set_ip_config_ipv6 = 1;
1502 static_ip_file(6, ip, mask, NULL);
1503 return 1;
1504 } else if (type == 1) {
Pradeep Reddy POTTETIb18c5652016-01-18 12:45:37 +05301505 if (!is_ip_addr(ip) || !is_ip_addr(mask))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001506 return -1;
1507 }
1508
1509 kill_dhcp_client(dut, ifname);
1510
1511 if (!dut->no_ip_addr_set) {
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301512 if (!set_ipv4_addr(dut, ifname, ip, mask)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001513 send_resp(dut, conn, SIGMA_ERROR,
1514 "ErrorCode,Failed to set IP address");
1515 return 0;
1516 }
1517 }
1518
1519 gw = get_param(cmd, "defaultGateway");
1520 if (gw) {
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301521 if (set_ipv4_gw(dut, gw) < 1) {
1522 send_resp(dut, conn, SIGMA_ERROR,
1523 "ErrorCode,Failed to set default gateway");
1524 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001525 }
1526 }
1527
1528 val = get_param(cmd, "primary-dns");
1529 if (val) {
1530 /* TODO */
1531 sigma_dut_print(dut, DUT_MSG_INFO, "Ignored primary-dns %s "
1532 "setting", val);
1533 }
1534
1535 val = get_param(cmd, "secondary-dns");
1536 if (val) {
1537 /* TODO */
1538 sigma_dut_print(dut, DUT_MSG_INFO, "Ignored secondary-dns %s "
1539 "setting", val);
1540 }
1541
1542 static_ip_file(4, ip, mask, gw);
1543
1544 return 1;
1545}
1546
1547
Jouni Malinenf7222712019-06-13 01:50:21 +03001548static enum sigma_cmd_result cmd_sta_get_info(struct sigma_dut *dut,
1549 struct sigma_conn *conn,
1550 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001551{
1552 /* const char *intf = get_param(cmd, "Interface"); */
1553 /* TODO: could report more details here */
1554 send_resp(dut, conn, SIGMA_COMPLETE, "vendor,Atheros");
1555 return 0;
1556}
1557
1558
Jouni Malinenf7222712019-06-13 01:50:21 +03001559static enum sigma_cmd_result cmd_sta_get_mac_address(struct sigma_dut *dut,
1560 struct sigma_conn *conn,
1561 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001562{
1563 /* const char *intf = get_param(cmd, "Interface"); */
1564 char addr[20], resp[50];
1565
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05301566 if (dut->dev_role == DEVROLE_STA_CFON)
1567 return sta_cfon_get_mac_address(dut, conn, cmd);
1568
Jouni Malinen9540e012019-11-05 17:08:42 +02001569 start_sta_mode(dut);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001570 if (get_wpa_status(get_station_ifname(dut), "address",
1571 addr, sizeof(addr)) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001572 return -2;
1573
1574 snprintf(resp, sizeof(resp), "mac,%s", addr);
1575 send_resp(dut, conn, SIGMA_COMPLETE, resp);
1576 return 0;
1577}
1578
1579
Jouni Malinenf7222712019-06-13 01:50:21 +03001580static enum sigma_cmd_result cmd_sta_is_connected(struct sigma_dut *dut,
1581 struct sigma_conn *conn,
1582 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001583{
1584 /* const char *intf = get_param(cmd, "Interface"); */
1585 int connected = 0;
1586 char result[32];
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001587 if (get_wpa_status(get_station_ifname(dut), "wpa_state", result,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001588 sizeof(result)) < 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001589 sigma_dut_print(dut, DUT_MSG_INFO,
1590 "Could not get interface %s status",
1591 get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001592 return -2;
1593 }
1594
1595 sigma_dut_print(dut, DUT_MSG_DEBUG, "wpa_state=%s", result);
1596 if (strncmp(result, "COMPLETED", 9) == 0)
1597 connected = 1;
1598
1599 if (connected)
1600 send_resp(dut, conn, SIGMA_COMPLETE, "connected,1");
1601 else
1602 send_resp(dut, conn, SIGMA_COMPLETE, "connected,0");
1603
1604 return 0;
1605}
1606
1607
Jouni Malinenf7222712019-06-13 01:50:21 +03001608static enum sigma_cmd_result
1609cmd_sta_verify_ip_connection(struct sigma_dut *dut, struct sigma_conn *conn,
1610 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001611{
1612 /* const char *intf = get_param(cmd, "Interface"); */
1613 const char *dst, *timeout;
1614 int wait_time = 90;
1615 char buf[100];
1616 int res;
1617
1618 dst = get_param(cmd, "destination");
1619 if (dst == NULL || !is_ip_addr(dst))
1620 return -1;
1621
1622 timeout = get_param(cmd, "timeout");
1623 if (timeout) {
1624 wait_time = atoi(timeout);
1625 if (wait_time < 1)
1626 wait_time = 1;
1627 }
1628
1629 /* TODO: force renewal of IP lease if DHCP is enabled */
1630
1631 snprintf(buf, sizeof(buf), "ping %s -c 3 -W %d", dst, wait_time);
1632 res = system(buf);
1633 sigma_dut_print(dut, DUT_MSG_DEBUG, "ping returned: %d", res);
1634 if (res == 0)
1635 send_resp(dut, conn, SIGMA_COMPLETE, "connected,1");
1636 else if (res == 256)
1637 send_resp(dut, conn, SIGMA_COMPLETE, "connected,0");
1638 else
1639 return -2;
1640
1641 return 0;
1642}
1643
1644
Jouni Malinenf7222712019-06-13 01:50:21 +03001645static enum sigma_cmd_result cmd_sta_get_bssid(struct sigma_dut *dut,
1646 struct sigma_conn *conn,
1647 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001648{
1649 /* const char *intf = get_param(cmd, "Interface"); */
1650 char bssid[20], resp[50];
1651
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001652 if (get_wpa_status(get_station_ifname(dut), "bssid",
1653 bssid, sizeof(bssid)) < 0)
Peng Xub8fc5cc2017-05-10 17:27:28 -07001654 strlcpy(bssid, "00:00:00:00:00:00", sizeof(bssid));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001655
1656 snprintf(resp, sizeof(resp), "bssid,%s", bssid);
1657 send_resp(dut, conn, SIGMA_COMPLETE, resp);
1658 return 0;
1659}
1660
1661
1662#ifdef __SAMSUNG__
1663static int add_use_network(const char *ifname)
1664{
1665 char buf[100];
1666
1667 snprintf(buf, sizeof(buf), "USE_NETWORK ON");
1668 wpa_command(ifname, buf);
1669 return 0;
1670}
1671#endif /* __SAMSUNG__ */
1672
1673
1674static int add_network_common(struct sigma_dut *dut, struct sigma_conn *conn,
1675 const char *ifname, struct sigma_cmd *cmd)
1676{
1677 const char *ssid = get_param(cmd, "ssid");
1678 int id;
1679 const char *val;
1680
1681 if (ssid == NULL)
1682 return -1;
1683
1684 start_sta_mode(dut);
1685
1686#ifdef __SAMSUNG__
1687 add_use_network(ifname);
1688#endif /* __SAMSUNG__ */
1689
1690 id = add_network(ifname);
1691 if (id < 0)
1692 return -2;
1693 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding network %d", id);
1694
1695 if (set_network_quoted(ifname, id, "ssid", ssid) < 0)
1696 return -2;
1697
1698 dut->infra_network_id = id;
1699 snprintf(dut->infra_ssid, sizeof(dut->infra_ssid), "%s", ssid);
1700
1701 val = get_param(cmd, "program");
1702 if (!val)
1703 val = get_param(cmd, "prog");
1704 if (val && strcasecmp(val, "hs2") == 0) {
1705 char buf[100];
1706 snprintf(buf, sizeof(buf), "ENABLE_NETWORK %d no-connect", id);
1707 wpa_command(ifname, buf);
1708
1709 val = get_param(cmd, "prefer");
1710 if (val && atoi(val) > 0)
1711 set_network(ifname, id, "priority", "1");
1712 }
1713
1714 return id;
1715}
1716
1717
Jouni Malinenf7222712019-06-13 01:50:21 +03001718static enum sigma_cmd_result cmd_sta_set_encryption(struct sigma_dut *dut,
1719 struct sigma_conn *conn,
1720 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001721{
1722 const char *intf = get_param(cmd, "Interface");
1723 const char *ssid = get_param(cmd, "ssid");
1724 const char *type = get_param(cmd, "encpType");
1725 const char *ifname;
1726 char buf[200];
1727 int id;
1728
1729 if (intf == NULL || ssid == NULL)
1730 return -1;
1731
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001732 if (strcmp(intf, get_main_ifname(dut)) == 0)
1733 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001734 else
1735 ifname = intf;
1736
1737 id = add_network_common(dut, conn, ifname, cmd);
1738 if (id < 0)
1739 return id;
1740
1741 if (set_network(ifname, id, "key_mgmt", "NONE") < 0)
1742 return -2;
1743
1744 if (type && strcasecmp(type, "wep") == 0) {
1745 const char *val;
1746 int i;
1747
1748 val = get_param(cmd, "activeKey");
1749 if (val) {
1750 int keyid;
1751 keyid = atoi(val);
1752 if (keyid < 1 || keyid > 4)
1753 return -1;
1754 snprintf(buf, sizeof(buf), "%d", keyid - 1);
1755 if (set_network(ifname, id, "wep_tx_keyidx", buf) < 0)
1756 return -2;
1757 }
1758
1759 for (i = 0; i < 4; i++) {
1760 snprintf(buf, sizeof(buf), "key%d", i + 1);
1761 val = get_param(cmd, buf);
1762 if (val == NULL)
1763 continue;
1764 snprintf(buf, sizeof(buf), "wep_key%d", i);
1765 if (set_network(ifname, id, buf, val) < 0)
1766 return -2;
1767 }
1768 }
1769
1770 return 1;
1771}
1772
1773
Jouni Malinene4fde732019-03-25 22:29:37 +02001774static int set_akm_suites(struct sigma_dut *dut, const char *ifname,
1775 int id, const char *val)
1776{
1777 char key_mgmt[200], *end, *pos;
1778 const char *in_pos = val;
1779
Jouni Malinen8179fee2019-03-28 03:19:47 +02001780 dut->akm_values = 0;
Jouni Malinene4fde732019-03-25 22:29:37 +02001781 pos = key_mgmt;
1782 end = pos + sizeof(key_mgmt);
1783 while (*in_pos) {
1784 int res, akm = atoi(in_pos);
1785 const char *str;
1786
Jouni Malinen8179fee2019-03-28 03:19:47 +02001787 if (akm >= 0 && akm < 32)
1788 dut->akm_values |= 1 << akm;
1789
Jouni Malinene4fde732019-03-25 22:29:37 +02001790 switch (akm) {
1791 case AKM_WPA_EAP:
1792 str = "WPA-EAP";
1793 break;
1794 case AKM_WPA_PSK:
1795 str = "WPA-PSK";
1796 break;
1797 case AKM_FT_EAP:
1798 str = "FT-EAP";
1799 break;
1800 case AKM_FT_PSK:
1801 str = "FT-PSK";
1802 break;
1803 case AKM_EAP_SHA256:
1804 str = "WPA-EAP-SHA256";
1805 break;
1806 case AKM_PSK_SHA256:
1807 str = "WPA-PSK-SHA256";
1808 break;
1809 case AKM_SAE:
1810 str = "SAE";
1811 break;
1812 case AKM_FT_SAE:
1813 str = "FT-SAE";
1814 break;
1815 case AKM_SUITE_B:
1816 str = "WPA-EAP-SUITE-B-192";
1817 break;
1818 case AKM_FT_SUITE_B:
1819 str = "FT-EAP-SHA384";
1820 break;
1821 case AKM_FILS_SHA256:
1822 str = "FILS-SHA256";
1823 break;
1824 case AKM_FILS_SHA384:
1825 str = "FILS-SHA384";
1826 break;
1827 case AKM_FT_FILS_SHA256:
1828 str = "FT-FILS-SHA256";
1829 break;
1830 case AKM_FT_FILS_SHA384:
1831 str = "FT-FILS-SHA384";
1832 break;
1833 default:
1834 sigma_dut_print(dut, DUT_MSG_ERROR,
1835 "Unsupported AKMSuitetype %d", akm);
1836 return -1;
1837 }
1838
1839 res = snprintf(pos, end - pos, "%s%s",
1840 pos == key_mgmt ? "" : " ", str);
1841 if (res < 0 || res >= end - pos)
1842 return -1;
1843 pos += res;
1844
1845 in_pos = strchr(in_pos, ';');
1846 if (!in_pos)
1847 break;
1848 while (*in_pos == ';')
1849 in_pos++;
1850 }
1851 sigma_dut_print(dut, DUT_MSG_DEBUG, "AKMSuiteType %s --> %s",
1852 val, key_mgmt);
1853 return set_network(ifname, id, "key_mgmt", key_mgmt);
1854}
1855
1856
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001857static int set_wpa_common(struct sigma_dut *dut, struct sigma_conn *conn,
1858 const char *ifname, struct sigma_cmd *cmd)
1859{
1860 const char *val;
1861 int id;
Jouni Malinenad395a22017-09-01 21:13:46 +03001862 int cipher_set = 0;
Jouni Malinen47dcc952017-10-09 16:43:24 +03001863 int owe;
Sunil Duttc75a1e62018-01-11 20:47:50 +05301864 int suite_b = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001865
1866 id = add_network_common(dut, conn, ifname, cmd);
1867 if (id < 0)
1868 return id;
1869
Jouni Malinen47dcc952017-10-09 16:43:24 +03001870 val = get_param(cmd, "Type");
1871 owe = val && strcasecmp(val, "OWE") == 0;
1872
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001873 val = get_param(cmd, "keyMgmtType");
Jouni Malinen47dcc952017-10-09 16:43:24 +03001874 if (!val && owe)
1875 val = "OWE";
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001876 if (val == NULL) {
Jouni Malinene4fde732019-03-25 22:29:37 +02001877 /* keyMgmtType is being replaced with AKMSuiteType, so ignore
1878 * this missing parameter and assume proto=WPA2. */
1879 if (set_network(ifname, id, "proto", "WPA2") < 0)
1880 return ERROR_SEND_STATUS;
1881 } else if (strcasecmp(val, "wpa") == 0 ||
1882 strcasecmp(val, "wpa-psk") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001883 if (set_network(ifname, id, "proto", "WPA") < 0)
1884 return -2;
1885 } else if (strcasecmp(val, "wpa2") == 0 ||
1886 strcasecmp(val, "wpa2-psk") == 0 ||
1887 strcasecmp(val, "wpa2-ft") == 0 ||
1888 strcasecmp(val, "wpa2-sha256") == 0) {
1889 if (set_network(ifname, id, "proto", "WPA2") < 0)
1890 return -2;
Pradeep Reddy POTTETI6d04b3b2016-11-15 14:51:26 +05301891 } else if (strcasecmp(val, "wpa2-wpa-psk") == 0 ||
1892 strcasecmp(val, "wpa2-wpa-ent") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001893 if (set_network(ifname, id, "proto", "WPA WPA2") < 0)
1894 return -2;
Jouni Malinenad395a22017-09-01 21:13:46 +03001895 } else if (strcasecmp(val, "SuiteB") == 0) {
Sunil Duttc75a1e62018-01-11 20:47:50 +05301896 suite_b = 1;
Jouni Malinenad395a22017-09-01 21:13:46 +03001897 if (set_network(ifname, id, "proto", "WPA2") < 0)
1898 return -2;
Jouni Malinen47dcc952017-10-09 16:43:24 +03001899 } else if (strcasecmp(val, "OWE") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001900 } else {
1901 send_resp(dut, conn, SIGMA_INVALID, "errorCode,Unrecognized keyMgmtType value");
1902 return 0;
1903 }
1904
1905 val = get_param(cmd, "encpType");
Jouni Malinenad395a22017-09-01 21:13:46 +03001906 if (val) {
1907 cipher_set = 1;
1908 if (strcasecmp(val, "tkip") == 0) {
1909 if (set_network(ifname, id, "pairwise", "TKIP") < 0)
1910 return -2;
1911 } else if (strcasecmp(val, "aes-ccmp") == 0) {
1912 if (set_network(ifname, id, "pairwise", "CCMP") < 0)
1913 return -2;
1914 } else if (strcasecmp(val, "aes-ccmp-tkip") == 0) {
1915 if (set_network(ifname, id, "pairwise",
1916 "CCMP TKIP") < 0)
1917 return -2;
1918 } else if (strcasecmp(val, "aes-gcmp") == 0) {
1919 if (set_network(ifname, id, "pairwise", "GCMP") < 0)
1920 return -2;
1921 if (set_network(ifname, id, "group", "GCMP") < 0)
1922 return -2;
1923 } else {
1924 send_resp(dut, conn, SIGMA_ERROR,
1925 "errorCode,Unrecognized encpType value");
1926 return 0;
1927 }
1928 }
1929
1930 val = get_param(cmd, "PairwiseCipher");
1931 if (val) {
1932 cipher_set = 1;
1933 /* TODO: Support space separated list */
1934 if (strcasecmp(val, "AES-GCMP-256") == 0) {
1935 if (set_network(ifname, id, "pairwise", "GCMP-256") < 0)
1936 return -2;
1937 } else if (strcasecmp(val, "AES-CCMP-256") == 0) {
1938 if (set_network(ifname, id, "pairwise",
1939 "CCMP-256") < 0)
1940 return -2;
1941 } else if (strcasecmp(val, "AES-GCMP-128") == 0) {
1942 if (set_network(ifname, id, "pairwise", "GCMP") < 0)
1943 return -2;
1944 } else if (strcasecmp(val, "AES-CCMP-128") == 0) {
1945 if (set_network(ifname, id, "pairwise", "CCMP") < 0)
1946 return -2;
1947 } else {
1948 send_resp(dut, conn, SIGMA_ERROR,
1949 "errorCode,Unrecognized PairwiseCipher value");
1950 return 0;
1951 }
1952 }
1953
Jouni Malinen47dcc952017-10-09 16:43:24 +03001954 if (!cipher_set && !owe) {
Jouni Malinenad395a22017-09-01 21:13:46 +03001955 send_resp(dut, conn, SIGMA_ERROR,
1956 "errorCode,Missing encpType and PairwiseCipher");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001957 return 0;
1958 }
Jouni Malinenad395a22017-09-01 21:13:46 +03001959
1960 val = get_param(cmd, "GroupCipher");
1961 if (val) {
1962 if (strcasecmp(val, "AES-GCMP-256") == 0) {
1963 if (set_network(ifname, id, "group", "GCMP-256") < 0)
1964 return -2;
1965 } else if (strcasecmp(val, "AES-CCMP-256") == 0) {
1966 if (set_network(ifname, id, "group", "CCMP-256") < 0)
1967 return -2;
1968 } else if (strcasecmp(val, "AES-GCMP-128") == 0) {
1969 if (set_network(ifname, id, "group", "GCMP") < 0)
1970 return -2;
1971 } else if (strcasecmp(val, "AES-CCMP-128") == 0) {
1972 if (set_network(ifname, id, "group", "CCMP") < 0)
1973 return -2;
1974 } else {
1975 send_resp(dut, conn, SIGMA_ERROR,
1976 "errorCode,Unrecognized GroupCipher value");
1977 return 0;
1978 }
1979 }
1980
Jouni Malinen7b239522017-09-14 21:37:18 +03001981 val = get_param(cmd, "GroupMgntCipher");
Jouni Malinenad395a22017-09-01 21:13:46 +03001982 if (val) {
Jouni Malinene8898cb2017-09-26 17:55:26 +03001983 const char *cipher;
1984
1985 if (strcasecmp(val, "BIP-GMAC-256") == 0) {
1986 cipher = "BIP-GMAC-256";
1987 } else if (strcasecmp(val, "BIP-CMAC-256") == 0) {
1988 cipher = "BIP-CMAC-256";
1989 } else if (strcasecmp(val, "BIP-GMAC-128") == 0) {
1990 cipher = "BIP-GMAC-128";
1991 } else if (strcasecmp(val, "BIP-CMAC-128") == 0) {
1992 cipher = "AES-128-CMAC";
1993 } else {
1994 send_resp(dut, conn, SIGMA_INVALID,
1995 "errorCode,Unsupported GroupMgntCipher");
1996 return 0;
1997 }
1998 if (set_network(ifname, id, "group_mgmt", cipher) < 0) {
1999 send_resp(dut, conn, SIGMA_INVALID,
2000 "errorCode,Failed to set GroupMgntCipher");
2001 return 0;
2002 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002003 }
2004
Jouni Malinene4fde732019-03-25 22:29:37 +02002005 val = get_param(cmd, "AKMSuiteType");
2006 if (val && set_akm_suites(dut, ifname, id, val) < 0)
2007 return ERROR_SEND_STATUS;
2008
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002009 dut->sta_pmf = STA_PMF_DISABLED;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302010
2011 if (dut->program == PROGRAM_OCE) {
2012 dut->sta_pmf = STA_PMF_OPTIONAL;
2013 if (set_network(ifname, id, "ieee80211w", "1") < 0)
2014 return -2;
2015 }
2016
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002017 val = get_param(cmd, "PMF");
2018 if (val) {
2019 if (strcasecmp(val, "Required") == 0 ||
2020 strcasecmp(val, "Forced_Required") == 0) {
2021 dut->sta_pmf = STA_PMF_REQUIRED;
2022 if (set_network(ifname, id, "ieee80211w", "2") < 0)
2023 return -2;
2024 } else if (strcasecmp(val, "Optional") == 0) {
2025 dut->sta_pmf = STA_PMF_OPTIONAL;
2026 if (set_network(ifname, id, "ieee80211w", "1") < 0)
2027 return -2;
2028 } else if (strcasecmp(val, "Disabled") == 0 ||
Kiran Kumar Lokere07da3b22018-12-16 22:42:49 -08002029 strcasecmp(val, "Disable") == 0 ||
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002030 strcasecmp(val, "Forced_Disabled") == 0) {
2031 dut->sta_pmf = STA_PMF_DISABLED;
2032 } else {
2033 send_resp(dut, conn, SIGMA_INVALID, "errorCode,Unrecognized PMF value");
2034 return 0;
2035 }
Sunil Duttc75a1e62018-01-11 20:47:50 +05302036 } else if (owe || suite_b) {
Jouni Malinen1287cd72018-01-04 17:08:01 +02002037 dut->sta_pmf = STA_PMF_REQUIRED;
2038 if (set_network(ifname, id, "ieee80211w", "2") < 0)
2039 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002040 }
2041
2042 return id;
2043}
2044
2045
Jouni Malinenf7222712019-06-13 01:50:21 +03002046static enum sigma_cmd_result cmd_sta_set_psk(struct sigma_dut *dut,
2047 struct sigma_conn *conn,
2048 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002049{
2050 const char *intf = get_param(cmd, "Interface");
Jouni Malinen992a81e2017-08-22 13:57:47 +03002051 const char *type = get_param(cmd, "Type");
Jouni Malinen1287cd72018-01-04 17:08:01 +02002052 const char *pmf = get_param(cmd, "PMF");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002053 const char *network_mode = get_param(cmd, "network_mode");
Jouni Malinene4fde732019-03-25 22:29:37 +02002054 const char *akm = get_param(cmd, "AKMSuiteType");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002055 const char *ifname, *val, *alg;
2056 int id;
Jouni Malinen4b3769d2019-10-10 16:20:29 +03002057 char buf[50];
Jouni Malinen11e55212019-11-22 21:46:59 +02002058 int sae_pwe = -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002059
2060 if (intf == NULL)
2061 return -1;
2062
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002063 if (strcmp(intf, get_main_ifname(dut)) == 0)
2064 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002065 else
2066 ifname = intf;
2067
2068 id = set_wpa_common(dut, conn, ifname, cmd);
2069 if (id < 0)
2070 return id;
2071
2072 val = get_param(cmd, "keyMgmtType");
2073 alg = get_param(cmd, "micAlg");
2074
Jouni Malinen992a81e2017-08-22 13:57:47 +03002075 if (type && strcasecmp(type, "SAE") == 0) {
Jouni Malinene4fde732019-03-25 22:29:37 +02002076 if (!akm && val && strcasecmp(val, "wpa2-ft") == 0) {
Jouni Malinen992a81e2017-08-22 13:57:47 +03002077 if (set_network(ifname, id, "key_mgmt", "FT-SAE") < 0)
2078 return -2;
Jouni Malinene4fde732019-03-25 22:29:37 +02002079 } else if (!akm) {
Jouni Malinen992a81e2017-08-22 13:57:47 +03002080 if (set_network(ifname, id, "key_mgmt", "SAE") < 0)
2081 return -2;
2082 }
2083 if (wpa_command(ifname, "SET sae_groups ") != 0) {
2084 sigma_dut_print(dut, DUT_MSG_ERROR,
2085 "Failed to clear sae_groups to default");
2086 return -2;
2087 }
Jouni Malinen1287cd72018-01-04 17:08:01 +02002088 if (!pmf) {
2089 dut->sta_pmf = STA_PMF_REQUIRED;
2090 if (set_network(ifname, id, "ieee80211w", "2") < 0)
2091 return -2;
2092 }
Jouni Malinen0ab50f42017-08-31 01:34:59 +03002093 } else if (type && strcasecmp(type, "PSK-SAE") == 0) {
2094 if (val && strcasecmp(val, "wpa2-ft") == 0) {
2095 if (set_network(ifname, id, "key_mgmt",
2096 "FT-SAE FT-PSK") < 0)
2097 return -2;
Jouni Malinen3b73d872019-06-12 03:13:25 +03002098 } else if (!akm) {
Jouni Malinen0ab50f42017-08-31 01:34:59 +03002099 if (set_network(ifname, id, "key_mgmt",
2100 "SAE WPA-PSK") < 0)
2101 return -2;
2102 }
2103 if (wpa_command(ifname, "SET sae_groups ") != 0) {
2104 sigma_dut_print(dut, DUT_MSG_ERROR,
2105 "Failed to clear sae_groups to default");
2106 return -2;
2107 }
Jouni Malinen1287cd72018-01-04 17:08:01 +02002108 if (!pmf) {
2109 dut->sta_pmf = STA_PMF_OPTIONAL;
2110 if (set_network(ifname, id, "ieee80211w", "1") < 0)
2111 return -2;
2112 }
Jouni Malinen992a81e2017-08-22 13:57:47 +03002113 } else if (alg && strcasecmp(alg, "SHA-256") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002114 if (set_network(ifname, id, "key_mgmt", "WPA-PSK-SHA256") < 0)
2115 return -2;
2116 } else if (alg && strcasecmp(alg, "SHA-1") == 0) {
2117 if (set_network(ifname, id, "key_mgmt", "WPA-PSK") < 0)
2118 return -2;
Ashwini Patil6dbf7b02017-03-20 13:42:11 +05302119 } else if (val && strcasecmp(val, "wpa2-ft") == 0) {
2120 if (set_network(ifname, id, "key_mgmt", "FT-PSK") < 0)
2121 return -2;
Jouni Malinen3b73d872019-06-12 03:13:25 +03002122 } else if (!akm &&
2123 ((val && strcasecmp(val, "wpa2-sha256") == 0) ||
2124 dut->sta_pmf == STA_PMF_REQUIRED)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002125 if (set_network(ifname, id, "key_mgmt",
2126 "WPA-PSK WPA-PSK-SHA256") < 0)
2127 return -2;
Jouni Malinen77ff3f02019-03-28 03:45:40 +02002128 } else if (!akm && dut->sta_pmf == STA_PMF_OPTIONAL) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002129 if (set_network(ifname, id, "key_mgmt",
2130 "WPA-PSK WPA-PSK-SHA256") < 0)
2131 return -2;
Jouni Malinen77ff3f02019-03-28 03:45:40 +02002132 } else if (!akm) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002133 if (set_network(ifname, id, "key_mgmt", "WPA-PSK") < 0)
2134 return -2;
2135 }
2136
2137 val = get_param(cmd, "passPhrase");
2138 if (val == NULL)
2139 return -1;
Jouni Malinen2126f422017-10-11 23:24:33 +03002140 if (type && strcasecmp(type, "SAE") == 0) {
2141 if (set_network_quoted(ifname, id, "sae_password", val) < 0)
2142 return -2;
2143 } else {
2144 if (set_network_quoted(ifname, id, "psk", val) < 0)
2145 return -2;
2146 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002147
Jouni Malinen78d10c42019-03-25 22:34:32 +02002148 val = get_param(cmd, "PasswordId");
2149 if (val && set_network_quoted(ifname, id, "sae_password_id", val) < 0)
2150 return ERROR_SEND_STATUS;
2151
Jouni Malinen992a81e2017-08-22 13:57:47 +03002152 val = get_param(cmd, "ECGroupID");
2153 if (val) {
Jouni Malinen992a81e2017-08-22 13:57:47 +03002154 snprintf(buf, sizeof(buf), "SET sae_groups %u", atoi(val));
2155 if (wpa_command(ifname, buf) != 0) {
2156 sigma_dut_print(dut, DUT_MSG_ERROR,
2157 "Failed to clear sae_groups");
2158 return -2;
2159 }
2160 }
2161
Jouni Malinen68143132017-09-02 02:34:08 +03002162 val = get_param(cmd, "InvalidSAEElement");
2163 if (val) {
2164 free(dut->sae_commit_override);
2165 dut->sae_commit_override = strdup(val);
2166 }
2167
Jouni Malinen4b3769d2019-10-10 16:20:29 +03002168 val = get_param(cmd, "PMKID_Include");
2169 if (val) {
2170 snprintf(buf, sizeof(buf), "SET sae_pmkid_in_assoc %d",
2171 get_enable_disable(val));
2172 wpa_command(intf, buf);
2173 }
2174
Jouni Malineneeb43d32019-12-06 17:40:07 +02002175 val = get_param(cmd, "IgnoreH2E_RSNXE_BSSMemSel");
2176 if (val) {
2177 snprintf(buf, sizeof(buf), "SET ignore_sae_h2e_only %d",
2178 get_enable_disable(val));
2179 wpa_command(intf, buf);
2180 }
2181
Jouni Malinen11e55212019-11-22 21:46:59 +02002182 val = get_param(cmd, "sae_pwe");
2183 if (val) {
2184 if (strcasecmp(val, "h2e") == 0) {
2185 dut->sae_pwe = SAE_PWE_H2E;
2186 } else if (strcasecmp(val, "loop") == 0) {
2187 dut->sae_pwe = SAE_PWE_LOOP;
2188 } else {
2189 send_resp(dut, conn, SIGMA_ERROR,
2190 "errorCode,Unsupported sae_pwe value");
2191 return STATUS_SENT_ERROR;
2192 }
2193 }
2194 if (dut->sae_pwe == SAE_PWE_LOOP)
2195 sae_pwe = 0;
2196 else if (dut->sae_pwe == SAE_PWE_H2E)
2197 sae_pwe = 1;
2198 else if (dut->sae_h2e_default)
2199 sae_pwe = 2;
2200 snprintf(buf, sizeof(buf), "SET sae_pwe %d", sae_pwe);
2201 if (sae_pwe >= 0 && wpa_command(ifname, buf) != 0)
2202 return ERROR_SEND_STATUS;
2203
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002204 if (dut->program == PROGRAM_60GHZ && network_mode &&
2205 strcasecmp(network_mode, "PBSS") == 0 &&
2206 set_network(ifname, id, "pbss", "1") < 0)
2207 return -2;
2208
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002209 return 1;
2210}
2211
2212
Jouni Malinen8ac93452019-08-14 15:19:13 +03002213static enum sigma_cmd_result set_trust_root_system(struct sigma_dut *dut,
2214 struct sigma_conn *conn,
2215 const char *ifname, int id)
2216{
2217 char buf[200];
2218
2219 snprintf(buf, sizeof(buf), "%s/certs", sigma_cert_path);
2220 if (!file_exists(buf))
2221 strlcpy(buf, "/system/etc/security/cacerts", sizeof(buf));
2222 if (!file_exists(buf))
2223 strlcpy(buf, "/etc/ssl/certs", sizeof(buf));
2224 if (!file_exists(buf)) {
2225 char msg[300];
2226
2227 snprintf(msg, sizeof(msg),
2228 "ErrorCode,trustedRootCA system store (%s) not found",
2229 buf);
2230 send_resp(dut, conn, SIGMA_ERROR, msg);
2231 return STATUS_SENT_ERROR;
2232 }
2233
2234 if (set_network_quoted(ifname, id, "ca_path", buf) < 0)
2235 return ERROR_SEND_STATUS;
2236
2237 return SUCCESS_SEND_STATUS;
2238}
2239
2240
2241static enum sigma_cmd_result set_trust_root(struct sigma_dut *dut,
2242 struct sigma_conn *conn,
2243 const char *ifname, int id,
2244 const char *val)
2245{
2246 char buf[200];
2247#ifdef ANDROID
2248 unsigned char kvalue[KEYSTORE_MESSAGE_SIZE];
2249 int length;
2250#endif /* ANDROID */
2251
2252 if (strcmp(val, "DEFAULT") == 0)
2253 return set_trust_root_system(dut, conn, ifname, id);
2254
2255#ifdef ANDROID
2256 snprintf(buf, sizeof(buf), "CACERT_%s", val);
2257 length = android_keystore_get(ANDROID_KEYSTORE_GET, buf, kvalue);
2258 if (length > 0) {
2259 sigma_dut_print(dut, DUT_MSG_INFO, "Use Android keystore [%s]",
2260 buf);
2261 snprintf(buf, sizeof(buf), "keystore://CACERT_%s", val);
2262 goto ca_cert_selected;
2263 }
2264#endif /* ANDROID */
2265
2266 snprintf(buf, sizeof(buf), "%s/%s", sigma_cert_path, val);
2267#ifdef __linux__
2268 if (!file_exists(buf)) {
2269 char msg[300];
2270
2271 snprintf(msg, sizeof(msg),
2272 "ErrorCode,trustedRootCA file (%s) not found", buf);
2273 send_resp(dut, conn, SIGMA_ERROR, msg);
2274 return STATUS_SENT_ERROR;
2275 }
2276#endif /* __linux__ */
2277#ifdef ANDROID
2278ca_cert_selected:
2279#endif /* ANDROID */
2280 if (set_network_quoted(ifname, id, "ca_cert", buf) < 0)
2281 return ERROR_SEND_STATUS;
2282
2283 return SUCCESS_SEND_STATUS;
2284}
2285
2286
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002287static int set_eap_common(struct sigma_dut *dut, struct sigma_conn *conn,
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302288 const char *ifname, int username_identity,
2289 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002290{
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002291 const char *val, *alg, *akm, *trust_root, *domain, *domain_suffix;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002292 int id;
Jouni Malinen53264f62019-05-03 13:04:40 +03002293 char buf[200], buf2[300];
Jouni Malinen8179fee2019-03-28 03:19:47 +02002294 int erp = 0;
Jouni Malinen8ac93452019-08-14 15:19:13 +03002295 enum sigma_cmd_result res;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002296
2297 id = set_wpa_common(dut, conn, ifname, cmd);
2298 if (id < 0)
2299 return id;
2300
2301 val = get_param(cmd, "keyMgmtType");
2302 alg = get_param(cmd, "micAlg");
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302303 akm = get_param(cmd, "AKMSuiteType");
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002304 trust_root = get_param(cmd, "trustedRootCA");
2305 domain = get_param(cmd, "Domain");
2306 domain_suffix = get_param(cmd, "DomainSuffix");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002307
Jouni Malinenad395a22017-09-01 21:13:46 +03002308 if (val && strcasecmp(val, "SuiteB") == 0) {
2309 if (set_network(ifname, id, "key_mgmt", "WPA-EAP-SUITE-B-192") <
2310 0)
2311 return -2;
2312 } else if (alg && strcasecmp(alg, "SHA-256") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002313 if (set_network(ifname, id, "key_mgmt", "WPA-EAP-SHA256") < 0)
2314 return -2;
2315 } else if (alg && strcasecmp(alg, "SHA-1") == 0) {
2316 if (set_network(ifname, id, "key_mgmt", "WPA-EAP") < 0)
2317 return -2;
2318 } else if (val && strcasecmp(val, "wpa2-ft") == 0) {
2319 if (set_network(ifname, id, "key_mgmt", "FT-EAP") < 0)
2320 return -2;
Jouni Malinend6a9d692019-03-28 03:01:24 +02002321 } else if (!akm &&
2322 ((val && strcasecmp(val, "wpa2-sha256") == 0) ||
2323 dut->sta_pmf == STA_PMF_REQUIRED)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002324 if (set_network(ifname, id, "key_mgmt",
2325 "WPA-EAP WPA-EAP-SHA256") < 0)
2326 return -2;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302327 } else if (akm && atoi(akm) == 14) {
2328 if (dut->sta_pmf == STA_PMF_OPTIONAL ||
2329 dut->sta_pmf == STA_PMF_REQUIRED) {
2330 if (set_network(ifname, id, "key_mgmt",
2331 "WPA-EAP-SHA256 FILS-SHA256") < 0)
2332 return -2;
2333 } else {
2334 if (set_network(ifname, id, "key_mgmt",
2335 "WPA-EAP FILS-SHA256") < 0)
2336 return -2;
2337 }
2338
Jouni Malinen8179fee2019-03-28 03:19:47 +02002339 erp = 1;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302340 } else if (akm && atoi(akm) == 15) {
2341 if (dut->sta_pmf == STA_PMF_OPTIONAL ||
2342 dut->sta_pmf == STA_PMF_REQUIRED) {
2343 if (set_network(ifname, id, "key_mgmt",
2344 "WPA-EAP-SHA256 FILS-SHA384") < 0)
2345 return -2;
2346 } else {
2347 if (set_network(ifname, id, "key_mgmt",
2348 "WPA-EAP FILS-SHA384") < 0)
2349 return -2;
2350 }
2351
Jouni Malinen8179fee2019-03-28 03:19:47 +02002352 erp = 1;
Jouni Malinend6a9d692019-03-28 03:01:24 +02002353 } else if (!akm && dut->sta_pmf == STA_PMF_OPTIONAL) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002354 if (set_network(ifname, id, "key_mgmt",
2355 "WPA-EAP WPA-EAP-SHA256") < 0)
2356 return -2;
Jouni Malinend6a9d692019-03-28 03:01:24 +02002357 } else if (!akm) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002358 if (set_network(ifname, id, "key_mgmt", "WPA-EAP") < 0)
2359 return -2;
2360 }
2361
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002362 if (trust_root) {
2363 if (strcmp(trust_root, "DEFAULT") == 0 && !domain &&
2364 !domain_suffix) {
2365 send_resp(dut, conn, SIGMA_ERROR,
2366 "errorCode,trustRootCA DEFAULT used without specifying Domain or DomainSuffix");
2367 return STATUS_SENT_ERROR;
2368 }
2369 res = set_trust_root(dut, conn, ifname, id, trust_root);
Jouni Malinen8ac93452019-08-14 15:19:13 +03002370 if (res != SUCCESS_SEND_STATUS)
2371 return res;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002372 }
2373
Jouni Malinen53264f62019-05-03 13:04:40 +03002374 val = get_param(cmd, "ServerCert");
2375 if (val) {
2376 FILE *f;
2377 char *result = NULL, *pos;
2378
2379 snprintf(buf, sizeof(buf), "%s/%s.sha256", sigma_cert_path,
2380 val);
2381 f = fopen(buf, "r");
2382 if (f) {
2383 result = fgets(buf, sizeof(buf), f);
2384 fclose(f);
2385 }
2386 if (!result) {
2387 snprintf(buf2, sizeof(buf2),
2388 "ErrorCode,ServerCert hash could not be read from %s",
2389 buf);
2390 send_resp(dut, conn, SIGMA_ERROR, buf2);
2391 return STATUS_SENT_ERROR;
2392 }
2393 pos = strchr(buf, '\n');
2394 if (pos)
2395 *pos = '\0';
2396 snprintf(buf2, sizeof(buf2), "hash://server/sha256/%s", buf);
2397 if (set_network_quoted(ifname, id, "ca_cert", buf2) < 0)
2398 return ERROR_SEND_STATUS;
Jouni Malinen29108dc2019-06-13 23:42:11 +03002399
2400 snprintf(buf, sizeof(buf), "%s/%s.tod", sigma_cert_path, val);
2401 if (file_exists(buf)) {
2402 sigma_dut_print(dut, DUT_MSG_DEBUG,
2403 "TOD policy enabled for the configured ServerCert hash");
2404 dut->sta_tod_policy = 1;
2405 }
Jouni Malinen53264f62019-05-03 13:04:40 +03002406 }
2407
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002408 if (domain &&
2409 set_network_quoted(ifname, id, "domain_match", domain) < 0)
Jouni Malinen96f84b02019-05-03 12:32:56 +03002410 return ERROR_SEND_STATUS;
2411
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002412 if (domain_suffix &&
2413 set_network_quoted(ifname, id, "domain_suffix_match",
2414 domain_suffix) < 0)
Jouni Malinen96f84b02019-05-03 12:32:56 +03002415 return ERROR_SEND_STATUS;
2416
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302417 if (username_identity) {
2418 val = get_param(cmd, "username");
2419 if (val) {
2420 if (set_network_quoted(ifname, id, "identity", val) < 0)
2421 return -2;
2422 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002423
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302424 val = get_param(cmd, "password");
2425 if (val) {
2426 if (set_network_quoted(ifname, id, "password", val) < 0)
2427 return -2;
2428 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002429 }
2430
Jouni Malinen8179fee2019-03-28 03:19:47 +02002431 if (dut->akm_values &
2432 ((1 << AKM_FILS_SHA256) |
2433 (1 << AKM_FILS_SHA384) |
2434 (1 << AKM_FT_FILS_SHA256) |
2435 (1 << AKM_FT_FILS_SHA384)))
2436 erp = 1;
2437 if (erp && set_network(ifname, id, "erp", "1") < 0)
2438 return ERROR_SEND_STATUS;
2439
Jouni Malinen134fe3c2019-06-12 04:16:49 +03002440 dut->sta_associate_wait_connect = 1;
2441
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002442 return id;
2443}
2444
2445
Jouni Malinen5eabb2a2017-10-03 18:17:30 +03002446static int set_tls_cipher(const char *ifname, int id, const char *cipher)
2447{
2448 const char *val;
2449
2450 if (!cipher)
2451 return 0;
2452
2453 if (strcasecmp(cipher, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384") == 0)
2454 val = "ECDHE-ECDSA-AES256-GCM-SHA384";
2455 else if (strcasecmp(cipher,
2456 "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384") == 0)
2457 val = "ECDHE-RSA-AES256-GCM-SHA384";
2458 else if (strcasecmp(cipher, "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384") == 0)
2459 val = "DHE-RSA-AES256-GCM-SHA384";
2460 else if (strcasecmp(cipher,
2461 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256") == 0)
2462 val = "ECDHE-ECDSA-AES128-GCM-SHA256";
2463 else
2464 return -1;
2465
2466 /* Need to clear phase1="tls_suiteb=1" to allow cipher enforcement */
2467 set_network_quoted(ifname, id, "phase1", "");
2468
2469 return set_network_quoted(ifname, id, "openssl_ciphers", val);
2470}
2471
2472
Jouni Malinenf7222712019-06-13 01:50:21 +03002473static enum sigma_cmd_result cmd_sta_set_eaptls(struct sigma_dut *dut,
2474 struct sigma_conn *conn,
2475 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002476{
2477 const char *intf = get_param(cmd, "Interface");
2478 const char *ifname, *val;
2479 int id;
2480 char buf[200];
2481#ifdef ANDROID
2482 unsigned char kvalue[KEYSTORE_MESSAGE_SIZE];
2483 int length;
2484 int jb_or_newer = 0;
2485 char prop[PROPERTY_VALUE_MAX];
2486#endif /* ANDROID */
2487
2488 if (intf == NULL)
2489 return -1;
2490
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002491 if (strcmp(intf, get_main_ifname(dut)) == 0)
2492 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002493 else
2494 ifname = intf;
2495
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302496 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002497 if (id < 0)
2498 return id;
2499
2500 if (set_network(ifname, id, "eap", "TLS") < 0)
2501 return -2;
2502
Pradeep Reddy POTTETI9f6c2132016-05-05 16:28:19 +05302503 if (!get_param(cmd, "username") &&
2504 set_network_quoted(ifname, id, "identity",
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002505 "wifi-user@wifilabs.local") < 0)
2506 return -2;
2507
2508 val = get_param(cmd, "clientCertificate");
2509 if (val == NULL)
2510 return -1;
2511#ifdef ANDROID
2512 snprintf(buf, sizeof(buf), "USRPKEY_%s", val);
2513 length = android_keystore_get(ANDROID_KEYSTORE_GET, buf, kvalue);
2514 if (length < 0) {
2515 /*
2516 * JB started reporting keystore type mismatches, so retry with
2517 * the GET_PUBKEY command if the generic GET fails.
2518 */
2519 length = android_keystore_get(ANDROID_KEYSTORE_GET_PUBKEY,
2520 buf, kvalue);
2521 }
2522
2523 if (property_get("ro.build.version.release", prop, NULL) != 0) {
2524 sigma_dut_print(dut, DUT_MSG_DEBUG, "Android release %s", prop);
2525 if (strncmp(prop, "4.0", 3) != 0)
2526 jb_or_newer = 1;
2527 } else
2528 jb_or_newer = 1; /* assume newer */
2529
2530 if (jb_or_newer && length > 0) {
2531 sigma_dut_print(dut, DUT_MSG_INFO,
2532 "Use Android keystore [%s]", buf);
2533 if (set_network(ifname, id, "engine", "1") < 0)
2534 return -2;
2535 if (set_network_quoted(ifname, id, "engine_id", "keystore") < 0)
2536 return -2;
2537 snprintf(buf, sizeof(buf), "USRPKEY_%s", val);
2538 if (set_network_quoted(ifname, id, "key_id", buf) < 0)
2539 return -2;
2540 snprintf(buf, sizeof(buf), "keystore://USRCERT_%s", val);
2541 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
2542 return -2;
2543 return 1;
2544 } else if (length > 0) {
2545 sigma_dut_print(dut, DUT_MSG_INFO,
2546 "Use Android keystore [%s]", buf);
2547 snprintf(buf, sizeof(buf), "keystore://USRPKEY_%s", val);
2548 if (set_network_quoted(ifname, id, "private_key", buf) < 0)
2549 return -2;
2550 snprintf(buf, sizeof(buf), "keystore://USRCERT_%s", val);
2551 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
2552 return -2;
2553 return 1;
2554 }
2555#endif /* ANDROID */
2556
2557 snprintf(buf, sizeof(buf), "%s/%s", sigma_cert_path, val);
2558#ifdef __linux__
2559 if (!file_exists(buf)) {
2560 char msg[300];
2561 snprintf(msg, sizeof(msg), "ErrorCode,clientCertificate file "
2562 "(%s) not found", buf);
2563 send_resp(dut, conn, SIGMA_ERROR, msg);
2564 return -3;
2565 }
2566#endif /* __linux__ */
2567 if (set_network_quoted(ifname, id, "private_key", buf) < 0)
2568 return -2;
2569 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
2570 return -2;
2571
2572 if (set_network_quoted(ifname, id, "private_key_passwd", "wifi") < 0)
2573 return -2;
2574
Jouni Malinen5eabb2a2017-10-03 18:17:30 +03002575 val = get_param(cmd, "keyMgmtType");
2576 if (val && strcasecmp(val, "SuiteB") == 0) {
2577 val = get_param(cmd, "CertType");
2578 if (val && strcasecmp(val, "RSA") == 0) {
2579 if (set_network_quoted(ifname, id, "phase1",
2580 "tls_suiteb=1") < 0)
2581 return -2;
2582 } else {
2583 if (set_network_quoted(ifname, id, "openssl_ciphers",
2584 "SUITEB192") < 0)
2585 return -2;
2586 }
2587
2588 val = get_param(cmd, "TLSCipher");
2589 if (set_tls_cipher(ifname, id, val) < 0) {
2590 send_resp(dut, conn, SIGMA_ERROR,
2591 "ErrorCode,Unsupported TLSCipher value");
2592 return -3;
2593 }
2594 }
2595
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002596 return 1;
2597}
2598
2599
Jouni Malinenf7222712019-06-13 01:50:21 +03002600static enum sigma_cmd_result cmd_sta_set_eapttls(struct sigma_dut *dut,
2601 struct sigma_conn *conn,
2602 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002603{
2604 const char *intf = get_param(cmd, "Interface");
2605 const char *ifname;
2606 int id;
2607
2608 if (intf == NULL)
2609 return -1;
2610
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002611 if (strcmp(intf, get_main_ifname(dut)) == 0)
2612 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002613 else
2614 ifname = intf;
2615
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302616 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002617 if (id < 0)
2618 return id;
2619
2620 if (set_network(ifname, id, "eap", "TTLS") < 0) {
2621 send_resp(dut, conn, SIGMA_ERROR,
2622 "errorCode,Failed to set TTLS method");
2623 return 0;
2624 }
2625
2626 if (set_network_quoted(ifname, id, "phase2", "auth=MSCHAPV2") < 0) {
2627 send_resp(dut, conn, SIGMA_ERROR,
2628 "errorCode,Failed to set MSCHAPv2 for TTLS Phase 2");
2629 return 0;
2630 }
2631
2632 return 1;
2633}
2634
2635
Jouni Malinenf7222712019-06-13 01:50:21 +03002636static enum sigma_cmd_result cmd_sta_set_eapsim(struct sigma_dut *dut,
2637 struct sigma_conn *conn,
2638 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002639{
2640 const char *intf = get_param(cmd, "Interface");
2641 const char *ifname;
2642 int id;
2643
2644 if (intf == NULL)
2645 return -1;
2646
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002647 if (strcmp(intf, get_main_ifname(dut)) == 0)
2648 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002649 else
2650 ifname = intf;
2651
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302652 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002653 if (id < 0)
2654 return id;
2655
2656 if (set_network(ifname, id, "eap", "SIM") < 0)
2657 return -2;
2658
2659 return 1;
2660}
2661
2662
Jouni Malinenf7222712019-06-13 01:50:21 +03002663static enum sigma_cmd_result cmd_sta_set_peap(struct sigma_dut *dut,
2664 struct sigma_conn *conn,
2665 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002666{
2667 const char *intf = get_param(cmd, "Interface");
2668 const char *ifname, *val;
2669 int id;
2670 char buf[100];
2671
2672 if (intf == NULL)
2673 return -1;
2674
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002675 if (strcmp(intf, get_main_ifname(dut)) == 0)
2676 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002677 else
2678 ifname = intf;
2679
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302680 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002681 if (id < 0)
2682 return id;
2683
2684 if (set_network(ifname, id, "eap", "PEAP") < 0)
2685 return -2;
2686
2687 val = get_param(cmd, "innerEAP");
2688 if (val) {
2689 if (strcasecmp(val, "MSCHAPv2") == 0) {
2690 if (set_network_quoted(ifname, id, "phase2",
2691 "auth=MSCHAPV2") < 0)
2692 return -2;
2693 } else if (strcasecmp(val, "GTC") == 0) {
2694 if (set_network_quoted(ifname, id, "phase2",
2695 "auth=GTC") < 0)
2696 return -2;
2697 } else
2698 return -1;
2699 }
2700
2701 val = get_param(cmd, "peapVersion");
2702 if (val) {
2703 int ver = atoi(val);
2704 if (ver < 0 || ver > 1)
2705 return -1;
2706 snprintf(buf, sizeof(buf), "peapver=%d", ver);
2707 if (set_network_quoted(ifname, id, "phase1", buf) < 0)
2708 return -2;
2709 }
2710
2711 return 1;
2712}
2713
2714
Jouni Malinenf7222712019-06-13 01:50:21 +03002715static enum sigma_cmd_result cmd_sta_set_eapfast(struct sigma_dut *dut,
2716 struct sigma_conn *conn,
2717 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002718{
2719 const char *intf = get_param(cmd, "Interface");
2720 const char *ifname, *val;
2721 int id;
2722 char buf[100];
2723
2724 if (intf == NULL)
2725 return -1;
2726
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002727 if (strcmp(intf, get_main_ifname(dut)) == 0)
2728 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002729 else
2730 ifname = intf;
2731
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302732 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002733 if (id < 0)
2734 return id;
2735
2736 if (set_network(ifname, id, "eap", "FAST") < 0)
2737 return -2;
2738
2739 val = get_param(cmd, "innerEAP");
2740 if (val) {
2741 if (strcasecmp(val, "MSCHAPV2") == 0) {
2742 if (set_network_quoted(ifname, id, "phase2",
2743 "auth=MSCHAPV2") < 0)
2744 return -2;
2745 } else if (strcasecmp(val, "GTC") == 0) {
2746 if (set_network_quoted(ifname, id, "phase2",
2747 "auth=GTC") < 0)
2748 return -2;
2749 } else
2750 return -1;
2751 }
2752
2753 val = get_param(cmd, "validateServer");
2754 if (val) {
2755 /* TODO */
2756 sigma_dut_print(dut, DUT_MSG_INFO, "Ignored EAP-FAST "
2757 "validateServer=%s", val);
2758 }
2759
2760 val = get_param(cmd, "pacFile");
2761 if (val) {
2762 snprintf(buf, sizeof(buf), "blob://%s", val);
2763 if (set_network_quoted(ifname, id, "pac_file", buf) < 0)
2764 return -2;
2765 }
2766
2767 if (set_network_quoted(ifname, id, "phase1", "fast_provisioning=2") <
2768 0)
2769 return -2;
2770
2771 return 1;
2772}
2773
2774
Jouni Malinenf7222712019-06-13 01:50:21 +03002775static enum sigma_cmd_result cmd_sta_set_eapaka(struct sigma_dut *dut,
2776 struct sigma_conn *conn,
2777 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002778{
2779 const char *intf = get_param(cmd, "Interface");
Purushottam Kushwahacdd8cb12019-10-04 11:33:59 +05302780 const char *username = get_param(cmd, "Username");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002781 const char *ifname;
2782 int id;
2783
2784 if (intf == NULL)
2785 return -1;
2786
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002787 if (strcmp(intf, get_main_ifname(dut)) == 0)
2788 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002789 else
2790 ifname = intf;
2791
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302792 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002793 if (id < 0)
2794 return id;
2795
Purushottam Kushwahacdd8cb12019-10-04 11:33:59 +05302796 /* RFC 5448: EAP-AKA' MUST use the leading character "6" (ASCII 36
2797 * hexadecimal).
2798 */
2799 if (username && username[0] == '6') {
2800 if (set_network(ifname, id, "eap", "AKA'") < 0)
2801 return -2;
2802 } else if (set_network(ifname, id, "eap", "AKA") < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002803 return -2;
Purushottam Kushwahacdd8cb12019-10-04 11:33:59 +05302804 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002805
2806 return 1;
2807}
2808
2809
Jouni Malinenf7222712019-06-13 01:50:21 +03002810static enum sigma_cmd_result cmd_sta_set_eapakaprime(struct sigma_dut *dut,
2811 struct sigma_conn *conn,
2812 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002813{
2814 const char *intf = get_param(cmd, "Interface");
2815 const char *ifname;
2816 int id;
2817
2818 if (intf == NULL)
2819 return -1;
2820
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002821 if (strcmp(intf, get_main_ifname(dut)) == 0)
2822 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002823 else
2824 ifname = intf;
2825
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302826 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002827 if (id < 0)
2828 return id;
2829
2830 if (set_network(ifname, id, "eap", "AKA'") < 0)
2831 return -2;
2832
2833 return 1;
2834}
2835
2836
2837static int sta_set_open(struct sigma_dut *dut, struct sigma_conn *conn,
2838 struct sigma_cmd *cmd)
2839{
2840 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002841 const char *network_mode = get_param(cmd, "network_mode");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002842 const char *ifname;
2843 int id;
2844
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002845 if (strcmp(intf, get_main_ifname(dut)) == 0)
2846 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002847 else
2848 ifname = intf;
2849
2850 id = add_network_common(dut, conn, ifname, cmd);
2851 if (id < 0)
2852 return id;
2853
2854 if (set_network(ifname, id, "key_mgmt", "NONE") < 0)
2855 return -2;
2856
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002857 if (dut->program == PROGRAM_60GHZ && network_mode &&
2858 strcasecmp(network_mode, "PBSS") == 0 &&
2859 set_network(ifname, id, "pbss", "1") < 0)
2860 return -2;
2861
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002862 return 1;
2863}
2864
2865
Jouni Malinen47dcc952017-10-09 16:43:24 +03002866static int sta_set_owe(struct sigma_dut *dut, struct sigma_conn *conn,
2867 struct sigma_cmd *cmd)
2868{
2869 const char *intf = get_param(cmd, "Interface");
2870 const char *ifname, *val;
2871 int id;
2872
2873 if (intf == NULL)
2874 return -1;
2875
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002876 if (strcmp(intf, get_main_ifname(dut)) == 0)
2877 ifname = get_station_ifname(dut);
Jouni Malinen47dcc952017-10-09 16:43:24 +03002878 else
2879 ifname = intf;
2880
2881 id = set_wpa_common(dut, conn, ifname, cmd);
2882 if (id < 0)
2883 return id;
2884
2885 if (set_network(ifname, id, "key_mgmt", "OWE") < 0)
2886 return -2;
2887
2888 val = get_param(cmd, "ECGroupID");
Jouni Malinenfac9cad2017-10-10 18:35:55 +03002889 if (val && strcmp(val, "0") == 0) {
2890 if (wpa_command(ifname,
2891 "VENDOR_ELEM_ADD 13 ff23200000783590fb7440e03d5b3b33911f86affdcc6b4411b707846ac4ff08ddc8831ccd") != 0) {
2892 sigma_dut_print(dut, DUT_MSG_ERROR,
2893 "Failed to set OWE DH Param element override");
2894 return -2;
2895 }
2896 } else if (val && set_network(ifname, id, "owe_group", val) < 0) {
Jouni Malinen47dcc952017-10-09 16:43:24 +03002897 sigma_dut_print(dut, DUT_MSG_ERROR,
2898 "Failed to clear owe_group");
2899 return -2;
2900 }
2901
2902 return 1;
2903}
2904
2905
Jouni Malinenf7222712019-06-13 01:50:21 +03002906static enum sigma_cmd_result cmd_sta_set_security(struct sigma_dut *dut,
2907 struct sigma_conn *conn,
2908 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002909{
2910 const char *type = get_param(cmd, "Type");
2911
2912 if (type == NULL) {
2913 send_resp(dut, conn, SIGMA_ERROR,
2914 "ErrorCode,Missing Type argument");
2915 return 0;
2916 }
2917
2918 if (strcasecmp(type, "OPEN") == 0)
2919 return sta_set_open(dut, conn, cmd);
Jouni Malinen47dcc952017-10-09 16:43:24 +03002920 if (strcasecmp(type, "OWE") == 0)
2921 return sta_set_owe(dut, conn, cmd);
Jouni Malinen992a81e2017-08-22 13:57:47 +03002922 if (strcasecmp(type, "PSK") == 0 ||
Jouni Malinen0ab50f42017-08-31 01:34:59 +03002923 strcasecmp(type, "PSK-SAE") == 0 ||
Jouni Malinen992a81e2017-08-22 13:57:47 +03002924 strcasecmp(type, "SAE") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002925 return cmd_sta_set_psk(dut, conn, cmd);
2926 if (strcasecmp(type, "EAPTLS") == 0)
2927 return cmd_sta_set_eaptls(dut, conn, cmd);
2928 if (strcasecmp(type, "EAPTTLS") == 0)
2929 return cmd_sta_set_eapttls(dut, conn, cmd);
2930 if (strcasecmp(type, "EAPPEAP") == 0)
2931 return cmd_sta_set_peap(dut, conn, cmd);
2932 if (strcasecmp(type, "EAPSIM") == 0)
2933 return cmd_sta_set_eapsim(dut, conn, cmd);
2934 if (strcasecmp(type, "EAPFAST") == 0)
2935 return cmd_sta_set_eapfast(dut, conn, cmd);
2936 if (strcasecmp(type, "EAPAKA") == 0)
2937 return cmd_sta_set_eapaka(dut, conn, cmd);
2938 if (strcasecmp(type, "EAPAKAPRIME") == 0)
2939 return cmd_sta_set_eapakaprime(dut, conn, cmd);
Amarnath Hullur Subramanyam81b11cd2018-01-30 19:07:17 -08002940 if (strcasecmp(type, "wep") == 0)
2941 return cmd_sta_set_encryption(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002942
2943 send_resp(dut, conn, SIGMA_ERROR,
2944 "ErrorCode,Unsupported Type value");
2945 return 0;
2946}
2947
2948
2949int ath6kl_client_uapsd(struct sigma_dut *dut, const char *intf, int uapsd)
2950{
2951#ifdef __linux__
2952 /* special handling for ath6kl */
2953 char path[128], fname[128], *pos;
2954 ssize_t res;
2955 FILE *f;
2956
Jouni Malinene39cd562019-05-29 23:39:56 +03002957 res = snprintf(fname, sizeof(fname), "/sys/class/net/%s/phy80211",
2958 intf);
2959 if (res < 0 || res >= sizeof(fname))
2960 return 0;
2961 res = readlink(fname, path, sizeof(path));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002962 if (res < 0)
2963 return 0; /* not ath6kl */
2964
2965 if (res >= (int) sizeof(path))
2966 res = sizeof(path) - 1;
2967 path[res] = '\0';
2968 pos = strrchr(path, '/');
2969 if (pos == NULL)
2970 pos = path;
2971 else
2972 pos++;
2973 snprintf(fname, sizeof(fname),
2974 "/sys/kernel/debug/ieee80211/%s/ath6kl/"
2975 "create_qos", pos);
2976 if (!file_exists(fname))
2977 return 0; /* not ath6kl */
2978
2979 if (uapsd) {
2980 f = fopen(fname, "w");
2981 if (f == NULL)
2982 return -1;
2983
2984 sigma_dut_print(dut, DUT_MSG_DEBUG, "Use ath6kl create_qos");
2985 fprintf(f, "4 2 2 1 2 9999999 9999999 9999999 7777777 0 4 "
2986 "45000 200 56789000 56789000 5678900 0 0 9999999 "
2987 "20000 0\n");
2988 fclose(f);
2989 } else {
2990 snprintf(fname, sizeof(fname),
2991 "/sys/kernel/debug/ieee80211/%s/ath6kl/"
2992 "delete_qos", pos);
2993
2994 f = fopen(fname, "w");
2995 if (f == NULL)
2996 return -1;
2997
2998 sigma_dut_print(dut, DUT_MSG_DEBUG, "Use ath6kl delete_qos");
2999 fprintf(f, "2 4\n");
3000 fclose(f);
3001 }
3002#endif /* __linux__ */
3003
3004 return 0;
3005}
3006
3007
Jouni Malinenf7222712019-06-13 01:50:21 +03003008static enum sigma_cmd_result cmd_sta_set_uapsd(struct sigma_dut *dut,
3009 struct sigma_conn *conn,
3010 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003011{
3012 const char *intf = get_param(cmd, "Interface");
3013 /* const char *ssid = get_param(cmd, "ssid"); */
3014 const char *val;
3015 int max_sp_len = 4;
3016 int ac_be = 1, ac_bk = 1, ac_vi = 1, ac_vo = 1;
3017 char buf[100];
3018 int ret1, ret2;
3019
3020 val = get_param(cmd, "maxSPLength");
3021 if (val) {
3022 max_sp_len = atoi(val);
3023 if (max_sp_len != 0 && max_sp_len != 1 && max_sp_len != 2 &&
3024 max_sp_len != 4)
3025 return -1;
3026 }
3027
3028 val = get_param(cmd, "acBE");
3029 if (val)
3030 ac_be = atoi(val);
3031
3032 val = get_param(cmd, "acBK");
3033 if (val)
3034 ac_bk = atoi(val);
3035
3036 val = get_param(cmd, "acVI");
3037 if (val)
3038 ac_vi = atoi(val);
3039
3040 val = get_param(cmd, "acVO");
3041 if (val)
3042 ac_vo = atoi(val);
3043
3044 dut->client_uapsd = ac_be || ac_bk || ac_vi || ac_vo;
3045
3046 snprintf(buf, sizeof(buf), "P2P_SET client_apsd %d,%d,%d,%d;%d",
3047 ac_be, ac_bk, ac_vi, ac_vo, max_sp_len);
3048 ret1 = wpa_command(intf, buf);
3049
3050 snprintf(buf, sizeof(buf), "SET uapsd %d,%d,%d,%d;%d",
3051 ac_be, ac_bk, ac_vi, ac_vo, max_sp_len);
3052 ret2 = wpa_command(intf, buf);
3053
3054 if (ret1 && ret2) {
3055 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to set client mode "
3056 "UAPSD parameters.");
3057 return -2;
3058 }
3059
3060 if (ath6kl_client_uapsd(dut, intf, dut->client_uapsd) < 0) {
3061 send_resp(dut, conn, SIGMA_ERROR,
3062 "ErrorCode,Failed to set ath6kl QoS parameters");
3063 return 0;
3064 }
3065
3066 return 1;
3067}
3068
3069
Jouni Malinenf7222712019-06-13 01:50:21 +03003070static enum sigma_cmd_result cmd_sta_set_wmm(struct sigma_dut *dut,
3071 struct sigma_conn *conn,
3072 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003073{
3074 char buf[1000];
3075 const char *intf = get_param(cmd, "Interface");
3076 const char *grp = get_param(cmd, "Group");
3077 const char *act = get_param(cmd, "Action");
3078 const char *tid = get_param(cmd, "Tid");
3079 const char *dir = get_param(cmd, "Direction");
3080 const char *psb = get_param(cmd, "Psb");
3081 const char *up = get_param(cmd, "Up");
3082 const char *fixed = get_param(cmd, "Fixed");
3083 const char *size = get_param(cmd, "Size");
3084 const char *msize = get_param(cmd, "Maxsize");
3085 const char *minsi = get_param(cmd, "Min_srvc_intrvl");
3086 const char *maxsi = get_param(cmd, "Max_srvc_intrvl");
3087 const char *inact = get_param(cmd, "Inactivity");
3088 const char *sus = get_param(cmd, "Suspension");
3089 const char *mindr = get_param(cmd, "Mindatarate");
3090 const char *meandr = get_param(cmd, "Meandatarate");
3091 const char *peakdr = get_param(cmd, "Peakdatarate");
3092 const char *phyrate = get_param(cmd, "Phyrate");
3093 const char *burstsize = get_param(cmd, "Burstsize");
3094 const char *sba = get_param(cmd, "Sba");
3095 int direction;
3096 int handle;
Peng Xu93319622017-10-04 17:58:16 -07003097 float sba_fv = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003098 int fixed_int;
3099 int psb_ts;
3100
3101 if (intf == NULL || grp == NULL || act == NULL )
3102 return -1;
3103
3104 if (strcasecmp(act, "addts") == 0) {
3105 if (tid == NULL || dir == NULL || psb == NULL ||
3106 up == NULL || fixed == NULL || size == NULL)
3107 return -1;
3108
3109 /*
3110 * Note: Sigma CAPI spec lists uplink, downlink, and bidi as the
3111 * possible values, but WMM-AC and V-E test scripts use "UP,
3112 * "DOWN", and "BIDI".
3113 */
3114 if (strcasecmp(dir, "uplink") == 0 ||
3115 strcasecmp(dir, "up") == 0) {
3116 direction = 0;
3117 } else if (strcasecmp(dir, "downlink") == 0 ||
3118 strcasecmp(dir, "down") == 0) {
3119 direction = 1;
3120 } else if (strcasecmp(dir, "bidi") == 0) {
3121 direction = 2;
3122 } else {
3123 sigma_dut_print(dut, DUT_MSG_ERROR,
3124 "Direction %s not supported", dir);
3125 return -1;
3126 }
3127
3128 if (strcasecmp(psb, "legacy") == 0) {
3129 psb_ts = 0;
3130 } else if (strcasecmp(psb, "uapsd") == 0) {
3131 psb_ts = 1;
3132 } else {
3133 sigma_dut_print(dut, DUT_MSG_ERROR,
3134 "PSB %s not supported", psb);
3135 return -1;
3136 }
3137
3138 if (atoi(tid) < 0 || atoi(tid) > 7) {
3139 sigma_dut_print(dut, DUT_MSG_ERROR,
3140 "TID %s not supported", tid);
3141 return -1;
3142 }
3143
3144 if (strcasecmp(fixed, "true") == 0) {
3145 fixed_int = 1;
3146 } else {
3147 fixed_int = 0;
3148 }
3149
Peng Xu93319622017-10-04 17:58:16 -07003150 if (sba)
3151 sba_fv = atof(sba);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003152
3153 dut->dialog_token++;
3154 handle = 7000 + dut->dialog_token;
3155
3156 /*
3157 * size: convert to hex
3158 * maxsi: convert to hex
3159 * mindr: convert to hex
3160 * meandr: convert to hex
3161 * peakdr: convert to hex
3162 * burstsize: convert to hex
3163 * phyrate: convert to hex
3164 * sba: convert to hex with modification
3165 * minsi: convert to integer
3166 * sus: convert to integer
3167 * inact: convert to integer
3168 * maxsi: convert to integer
3169 */
3170
3171 /*
3172 * The Nominal MSDU Size field is 2 octets long and contains an
3173 * unsigned integer that specifies the nominal size, in octets,
3174 * of MSDUs belonging to the traffic under this traffic
3175 * specification and is defined in Figure 16. If the Fixed
3176 * subfield is set to 1, then the size of the MSDU is fixed and
3177 * is indicated by the Size Subfield. If the Fixed subfield is
3178 * set to 0, then the size of the MSDU might not be fixed and
3179 * the Size indicates the nominal MSDU size.
3180 *
3181 * The Surplus Bandwidth Allowance Factor field is 2 octets long
3182 * and specifies the excess allocation of time (and bandwidth)
3183 * over and above the stated rates required to transport an MSDU
3184 * belonging to the traffic in this TSPEC. This field is
3185 * represented as an unsigned binary number with an implicit
3186 * binary point after the leftmost 3 bits. For example, an SBA
3187 * of 1.75 is represented as 0x3800. This field is included to
3188 * account for retransmissions. As such, the value of this field
3189 * must be greater than unity.
3190 */
3191
3192 snprintf(buf, sizeof(buf),
3193 "iwpriv %s addTspec %d %s %d %d %s 0x%X"
3194 " 0x%X 0x%X 0x%X"
3195 " 0x%X 0x%X 0x%X"
3196 " 0x%X %d %d %d %d"
3197 " %d %d",
3198 intf, handle, tid, direction, psb_ts, up,
3199 (unsigned int) ((fixed_int << 15) | atoi(size)),
3200 msize ? atoi(msize) : 0,
3201 mindr ? atoi(mindr) : 0,
3202 meandr ? atoi(meandr) : 0,
3203 peakdr ? atoi(peakdr) : 0,
3204 burstsize ? atoi(burstsize) : 0,
3205 phyrate ? atoi(phyrate) : 0,
3206 sba ? ((unsigned int) (((int) sba_fv << 13) |
3207 (int)((sba_fv - (int) sba_fv) *
3208 8192))) : 0,
3209 minsi ? atoi(minsi) : 0,
3210 sus ? atoi(sus) : 0,
3211 0, 0,
3212 inact ? atoi(inact) : 0,
3213 maxsi ? atoi(maxsi) : 0);
3214
3215 if (system(buf) != 0) {
3216 sigma_dut_print(dut, DUT_MSG_ERROR,
3217 "iwpriv addtspec request failed");
3218 send_resp(dut, conn, SIGMA_ERROR,
3219 "errorCode,Failed to execute addTspec command");
3220 return 0;
3221 }
3222
3223 sigma_dut_print(dut, DUT_MSG_INFO,
3224 "iwpriv addtspec request send");
3225
3226 /* Mapping handle to a TID */
3227 dut->tid_to_handle[atoi(tid)] = handle;
3228 } else if (strcasecmp(act, "delts") == 0) {
3229 if (tid == NULL)
3230 return -1;
3231
3232 if (atoi(tid) < 0 || atoi(tid) > 7) {
3233 sigma_dut_print(dut, DUT_MSG_ERROR,
3234 "TID %s not supported", tid);
3235 send_resp(dut, conn, SIGMA_ERROR,
3236 "errorCode,Unsupported TID");
3237 return 0;
3238 }
3239
3240 handle = dut->tid_to_handle[atoi(tid)];
3241
3242 if (handle < 7000 || handle > 7255) {
3243 /* Invalid handle ie no mapping for that TID */
3244 sigma_dut_print(dut, DUT_MSG_ERROR,
3245 "handle-> %d not found", handle);
3246 }
3247
3248 snprintf(buf, sizeof(buf), "iwpriv %s delTspec %d",
3249 intf, handle);
3250
3251 if (system(buf) != 0) {
3252 sigma_dut_print(dut, DUT_MSG_ERROR,
3253 "iwpriv deltspec request failed");
3254 send_resp(dut, conn, SIGMA_ERROR,
3255 "errorCode,Failed to execute delTspec command");
3256 return 0;
3257 }
3258
3259 sigma_dut_print(dut, DUT_MSG_INFO,
3260 "iwpriv deltspec request send");
3261
3262 dut->tid_to_handle[atoi(tid)] = 0;
3263 } else {
3264 sigma_dut_print(dut, DUT_MSG_ERROR,
3265 "Action type %s not supported", act);
3266 send_resp(dut, conn, SIGMA_ERROR,
3267 "errorCode,Unsupported Action");
3268 return 0;
3269 }
3270
3271 return 1;
3272}
3273
3274
vamsi krishna52e16f92017-08-29 12:37:34 +05303275static int find_network(struct sigma_dut *dut, const char *ssid)
3276{
3277 char list[4096];
3278 char *pos;
3279
3280 sigma_dut_print(dut, DUT_MSG_DEBUG,
3281 "Search for profile based on SSID: '%s'", ssid);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003282 if (wpa_command_resp(get_station_ifname(dut), "LIST_NETWORKS",
vamsi krishna52e16f92017-08-29 12:37:34 +05303283 list, sizeof(list)) < 0)
3284 return -1;
3285 pos = strstr(list, ssid);
3286 if (!pos || pos == list || pos[-1] != '\t' || pos[strlen(ssid)] != '\t')
3287 return -1;
3288
3289 while (pos > list && pos[-1] != '\n')
3290 pos--;
3291 dut->infra_network_id = atoi(pos);
3292 snprintf(dut->infra_ssid, sizeof(dut->infra_ssid), "%s", ssid);
3293 return 0;
3294}
3295
3296
Sunil Dutt44595082018-02-12 19:41:45 +05303297#ifdef NL80211_SUPPORT
3298static int sta_config_rsnie(struct sigma_dut *dut, int val)
3299{
3300 struct nl_msg *msg;
3301 int ret;
3302 struct nlattr *params;
3303 int ifindex;
3304
3305 ifindex = if_nametoindex("wlan0");
3306 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
3307 NL80211_CMD_VENDOR)) ||
3308 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
3309 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
3310 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
3311 QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION) ||
3312 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
3313 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE, val)) {
3314 sigma_dut_print(dut, DUT_MSG_ERROR,
3315 "%s: err in adding vendor_cmd and vendor_data",
3316 __func__);
3317 nlmsg_free(msg);
3318 return -1;
3319 }
3320 nla_nest_end(msg, params);
3321
3322 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
3323 if (ret) {
3324 sigma_dut_print(dut, DUT_MSG_ERROR,
3325 "%s: err in send_and_recv_msgs, ret=%d",
3326 __func__, ret);
3327 return ret;
3328 }
3329
3330 return 0;
3331}
3332#endif /* NL80211_SUPPORT */
3333
3334
Jouni Malinenf7222712019-06-13 01:50:21 +03003335static enum sigma_cmd_result cmd_sta_associate(struct sigma_dut *dut,
3336 struct sigma_conn *conn,
3337 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003338{
3339 /* const char *intf = get_param(cmd, "Interface"); */
3340 const char *ssid = get_param(cmd, "ssid");
3341 const char *wps_param = get_param(cmd, "WPS");
3342 const char *bssid = get_param(cmd, "bssid");
Jouni Malinen46a19b62017-06-23 14:31:27 +03003343 const char *chan = get_param(cmd, "channel");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02003344 const char *network_mode = get_param(cmd, "network_mode");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003345 int wps = 0;
Jouni Malinen3c367e82017-06-23 17:01:47 +03003346 char buf[1000], extra[50];
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003347 int e;
3348 enum sigma_cmd_result ret = SUCCESS_SEND_STATUS;
3349 struct wpa_ctrl *ctrl = NULL;
3350 int num_network_not_found = 0;
3351 int num_disconnected = 0;
3352 int tod = -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003353
3354 if (ssid == NULL)
3355 return -1;
3356
Jouni Malinen37d5c692019-08-19 16:56:55 +03003357 dut->server_cert_tod = 0;
3358
Jouni Malinen3c367e82017-06-23 17:01:47 +03003359 if (dut->rsne_override) {
Sunil Dutt44595082018-02-12 19:41:45 +05303360#ifdef NL80211_SUPPORT
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003361 if (get_driver_type(dut) == DRIVER_WCN) {
Sunil Dutt44595082018-02-12 19:41:45 +05303362 sta_config_rsnie(dut, 1);
3363 dut->config_rsnie = 1;
3364 }
3365#endif /* NL80211_SUPPORT */
Jouni Malinen3c367e82017-06-23 17:01:47 +03003366 snprintf(buf, sizeof(buf), "TEST_ASSOC_IE %s",
3367 dut->rsne_override);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003368 if (wpa_command(get_station_ifname(dut), buf) < 0) {
Jouni Malinen3c367e82017-06-23 17:01:47 +03003369 send_resp(dut, conn, SIGMA_ERROR,
3370 "ErrorCode,Failed to set DEV_CONFIGURE_IE RSNE override");
3371 return 0;
3372 }
3373 }
3374
Jouni Malinen68143132017-09-02 02:34:08 +03003375 if (dut->sae_commit_override) {
3376 snprintf(buf, sizeof(buf), "SET sae_commit_override %s",
3377 dut->sae_commit_override);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003378 if (wpa_command(get_station_ifname(dut), buf) < 0) {
Jouni Malinen68143132017-09-02 02:34:08 +03003379 send_resp(dut, conn, SIGMA_ERROR,
3380 "ErrorCode,Failed to set SAE commit override");
3381 return 0;
3382 }
3383 }
Ankita Bajaj1bde7942018-01-09 19:15:01 +05303384#ifdef ANDROID
3385 if (dut->fils_hlp)
3386 process_fils_hlp(dut);
3387#endif /* ANDROID */
Jouni Malinen68143132017-09-02 02:34:08 +03003388
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003389 if (wps_param &&
3390 (strcmp(wps_param, "1") == 0 || strcasecmp(wps_param, "On") == 0))
3391 wps = 1;
3392
3393 if (wps) {
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02003394 if (dut->program == PROGRAM_60GHZ && network_mode &&
3395 strcasecmp(network_mode, "PBSS") == 0 &&
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003396 set_network(get_station_ifname(dut), dut->infra_network_id,
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02003397 "pbss", "1") < 0)
3398 return -2;
3399
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003400 if (dut->wps_method == WFA_CS_WPS_NOT_READY) {
3401 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,WPS "
3402 "parameters not yet set");
3403 return 0;
3404 }
3405 if (dut->wps_method == WFA_CS_WPS_PBC) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003406 if (wpa_command(get_station_ifname(dut), "WPS_PBC") < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003407 return -2;
3408 } else {
3409 snprintf(buf, sizeof(buf), "WPS_PIN any %s",
3410 dut->wps_pin);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003411 if (wpa_command(get_station_ifname(dut), buf) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003412 return -2;
3413 }
3414 } else {
vamsi krishna52e16f92017-08-29 12:37:34 +05303415 if (strcmp(ssid, dut->infra_ssid) == 0) {
3416 sigma_dut_print(dut, DUT_MSG_DEBUG,
3417 "sta_associate for the most recently added network");
3418 } else if (find_network(dut, ssid) < 0) {
3419 sigma_dut_print(dut, DUT_MSG_DEBUG,
3420 "sta_associate for a previously stored network profile");
3421 send_resp(dut, conn, SIGMA_ERROR,
3422 "ErrorCode,Profile not found");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003423 return 0;
3424 }
3425
3426 if (bssid &&
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003427 set_network(get_station_ifname(dut), dut->infra_network_id,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003428 "bssid", bssid) < 0) {
3429 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
3430 "Invalid bssid argument");
3431 return 0;
3432 }
3433
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003434 if (dut->program == PROGRAM_WPA3 &&
3435 dut->sta_associate_wait_connect) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003436 ctrl = open_wpa_mon(get_station_ifname(dut));
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003437 if (!ctrl)
3438 return ERROR_SEND_STATUS;
3439 }
3440
Jouni Malinen46a19b62017-06-23 14:31:27 +03003441 extra[0] = '\0';
3442 if (chan)
3443 snprintf(extra, sizeof(extra), " freq=%u",
Alexei Avshalom Lazar093569f2018-11-13 14:08:17 +02003444 channel_to_freq(dut, atoi(chan)));
Jouni Malinen46a19b62017-06-23 14:31:27 +03003445 snprintf(buf, sizeof(buf), "SELECT_NETWORK %d%s",
3446 dut->infra_network_id, extra);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003447 if (wpa_command(get_station_ifname(dut), buf) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003448 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to select "
3449 "network id %d on %s",
3450 dut->infra_network_id,
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003451 get_station_ifname(dut));
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003452 ret = ERROR_SEND_STATUS;
3453 goto done;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003454 }
3455 }
3456
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003457 if (!ctrl)
3458 return SUCCESS_SEND_STATUS;
3459
3460 /* Wait for connection result to be able to store server certificate
3461 * hash for trust root override testing
3462 * (dev_exec_action,ServerCertTrust). */
3463
3464 for (e = 0; e < 20; e++) {
3465 const char *events[] = {
3466 "CTRL-EVENT-EAP-PEER-CERT",
3467 "CTRL-EVENT-EAP-TLS-CERT-ERROR",
3468 "CTRL-EVENT-DISCONNECTED",
3469 "CTRL-EVENT-CONNECTED",
3470 "CTRL-EVENT-NETWORK-NOT-FOUND",
3471 NULL
3472 };
3473 char buf[1024];
3474 int res;
3475
3476 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
3477 if (res < 0) {
Jouni Malinenf1f16642019-11-15 21:19:04 +02003478 send_resp(dut, conn, SIGMA_COMPLETE,
3479 "Result,Association did not complete");
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003480 ret = STATUS_SENT_ERROR;
3481 break;
3482 }
3483 sigma_dut_print(dut, DUT_MSG_DEBUG, "Connection event: %s",
3484 buf);
3485
3486 if (strstr(buf, "CTRL-EVENT-EAP-PEER-CERT") &&
3487 strstr(buf, " depth=0")) {
3488 char *pos = strstr(buf, " hash=");
3489
3490 if (pos) {
3491 char *end;
3492
Jouni Malinen34b19cb2019-08-16 16:37:17 +03003493 if (strstr(buf, " tod=1"))
3494 tod = 1;
3495 else if (strstr(buf, " tod=2"))
3496 tod = 2;
3497 else
3498 tod = 0;
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003499 sigma_dut_print(dut, DUT_MSG_DEBUG,
3500 "Server certificate TOD policy: %d",
3501 tod);
Jouni Malinen37d5c692019-08-19 16:56:55 +03003502 dut->server_cert_tod = tod;
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003503
3504 pos += 6;
3505 end = strchr(pos, ' ');
3506 if (end)
3507 *end = '\0';
3508 strlcpy(dut->server_cert_hash, pos,
3509 sizeof(dut->server_cert_hash));
3510 sigma_dut_print(dut, DUT_MSG_DEBUG,
3511 "Server certificate hash: %s",
3512 dut->server_cert_hash);
3513 }
3514 }
3515
3516 if (strstr(buf, "CTRL-EVENT-EAP-TLS-CERT-ERROR")) {
3517 send_resp(dut, conn, SIGMA_COMPLETE,
3518 "Result,TLS server certificate validation failed");
3519 ret = STATUS_SENT_ERROR;
3520 break;
3521 }
3522
3523 if (strstr(buf, "CTRL-EVENT-NETWORK-NOT-FOUND")) {
3524 num_network_not_found++;
3525
3526 if (num_network_not_found > 2) {
3527 send_resp(dut, conn, SIGMA_COMPLETE,
3528 "Result,Network not found");
3529 ret = STATUS_SENT_ERROR;
3530 break;
3531 }
3532 }
3533
3534 if (strstr(buf, "CTRL-EVENT-DISCONNECTED")) {
3535 num_disconnected++;
3536
3537 if (num_disconnected > 2) {
3538 send_resp(dut, conn, SIGMA_COMPLETE,
3539 "Result,Connection failed");
3540 ret = STATUS_SENT_ERROR;
3541 break;
3542 }
3543 }
3544
3545 if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
3546 if (tod >= 0) {
3547 sigma_dut_print(dut, DUT_MSG_DEBUG,
3548 "Network profile TOD policy update: %d -> %d",
3549 dut->sta_tod_policy, tod);
3550 dut->sta_tod_policy = tod;
3551 }
3552 break;
3553 }
3554 }
3555done:
3556 if (ctrl) {
3557 wpa_ctrl_detach(ctrl);
3558 wpa_ctrl_close(ctrl);
3559 }
3560 return ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003561}
3562
3563
3564static int run_hs20_osu(struct sigma_dut *dut, const char *params)
3565{
3566 char buf[500], cmd[200];
3567 int res;
3568
3569 /* Use hs20-osu-client file at the current dir, if found; otherwise use
3570 * default path */
3571 res = snprintf(cmd, sizeof(cmd),
3572 "%s -w \"%s\" -r hs20-osu-client.res %s%s -dddKt -f Logs/hs20-osu-client.txt",
3573 file_exists("./hs20-osu-client") ?
3574 "./hs20-osu-client" : "hs20-osu-client",
3575 sigma_wpas_ctrl,
3576 dut->summary_log ? "-s " : "",
3577 dut->summary_log ? dut->summary_log : "");
3578 if (res < 0 || res >= (int) sizeof(cmd))
3579 return -1;
3580
3581 res = snprintf(buf, sizeof(buf), "%s %s", cmd, params);
3582 if (res < 0 || res >= (int) sizeof(buf))
3583 return -1;
3584 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
3585
3586 if (system(buf) != 0) {
3587 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to run: %s", buf);
3588 return -1;
3589 }
3590 sigma_dut_print(dut, DUT_MSG_DEBUG,
3591 "Completed hs20-osu-client operation");
3592
3593 return 0;
3594}
3595
3596
3597static int download_ppsmo(struct sigma_dut *dut,
3598 struct sigma_conn *conn,
3599 const char *intf,
3600 struct sigma_cmd *cmd)
3601{
3602 const char *name, *path, *val;
3603 char url[500], buf[600], fbuf[100];
3604 char *fqdn = NULL;
3605
3606 name = get_param(cmd, "FileName");
3607 path = get_param(cmd, "FilePath");
3608 if (name == NULL || path == NULL)
3609 return -1;
3610
3611 if (strcasecmp(path, "VendorSpecific") == 0) {
3612 snprintf(url, sizeof(url), "PPS/%s", name);
3613 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured PPS MO "
3614 "from the device (%s)", url);
3615 if (!file_exists(url)) {
3616 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
3617 "PPS MO file does not exist");
3618 return 0;
3619 }
3620 snprintf(buf, sizeof(buf), "cp %s pps-tnds.xml", url);
3621 if (system(buf) != 0) {
3622 send_resp(dut, conn, SIGMA_ERROR,
3623 "errorCode,Failed to copy PPS MO");
3624 return 0;
3625 }
3626 } else if (strncasecmp(path, "http:", 5) != 0 &&
3627 strncasecmp(path, "https:", 6) != 0) {
3628 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
3629 "Unsupported FilePath value");
3630 return 0;
3631 } else {
3632 snprintf(url, sizeof(url), "%s/%s", path, name);
3633 sigma_dut_print(dut, DUT_MSG_INFO, "Downloading PPS MO from %s",
3634 url);
3635 snprintf(buf, sizeof(buf), "wget -T 10 -t 3 -O pps-tnds.xml '%s'", url);
3636 remove("pps-tnds.xml");
3637 if (system(buf) != 0) {
3638 send_resp(dut, conn, SIGMA_ERROR,
3639 "errorCode,Failed to download PPS MO");
3640 return 0;
3641 }
3642 }
3643
3644 if (run_hs20_osu(dut, "from_tnds pps-tnds.xml pps.xml") < 0) {
3645 send_resp(dut, conn, SIGMA_ERROR,
3646 "errorCode,Failed to parse downloaded PPSMO");
3647 return 0;
3648 }
3649 unlink("pps-tnds.xml");
3650
3651 val = get_param(cmd, "managementTreeURI");
3652 if (val) {
3653 const char *pos, *end;
3654 sigma_dut_print(dut, DUT_MSG_DEBUG, "managementTreeURI: %s",
3655 val);
3656 if (strncmp(val, "./Wi-Fi/", 8) != 0) {
3657 send_resp(dut, conn, SIGMA_ERROR,
3658 "errorCode,Invalid managementTreeURI prefix");
3659 return 0;
3660 }
3661 pos = val + 8;
3662 end = strchr(pos, '/');
3663 if (end == NULL ||
3664 strcmp(end, "/PerProviderSubscription") != 0) {
3665 send_resp(dut, conn, SIGMA_ERROR,
3666 "errorCode,Invalid managementTreeURI postfix");
3667 return 0;
3668 }
3669 if (end - pos >= (int) sizeof(fbuf)) {
3670 send_resp(dut, conn, SIGMA_ERROR,
3671 "errorCode,Too long FQDN in managementTreeURI");
3672 return 0;
3673 }
3674 memcpy(fbuf, pos, end - pos);
3675 fbuf[end - pos] = '\0';
3676 fqdn = fbuf;
3677 sigma_dut_print(dut, DUT_MSG_INFO,
3678 "FQDN from managementTreeURI: %s", fqdn);
3679 } else if (run_hs20_osu(dut, "get_fqdn pps.xml") == 0) {
3680 FILE *f = fopen("pps-fqdn", "r");
3681 if (f) {
3682 if (fgets(fbuf, sizeof(fbuf), f)) {
3683 fbuf[sizeof(fbuf) - 1] = '\0';
3684 fqdn = fbuf;
3685 sigma_dut_print(dut, DUT_MSG_DEBUG,
3686 "Use FQDN %s", fqdn);
3687 }
3688 fclose(f);
3689 }
3690 }
3691
3692 if (fqdn == NULL) {
3693 send_resp(dut, conn, SIGMA_ERROR,
3694 "errorCode,No FQDN specified");
3695 return 0;
3696 }
3697
3698 mkdir("SP", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
3699 snprintf(buf, sizeof(buf), "SP/%s", fqdn);
3700 mkdir(buf, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
3701
3702 snprintf(buf, sizeof(buf), "SP/%s/pps.xml", fqdn);
3703 if (rename("pps.xml", buf) < 0) {
3704 send_resp(dut, conn, SIGMA_ERROR,
3705 "errorCode,Could not move PPS MO");
3706 return 0;
3707 }
3708
3709 if (strcasecmp(path, "VendorSpecific") == 0) {
3710 snprintf(buf, sizeof(buf), "cp Certs/ca.pem SP/%s/ca.pem",
3711 fqdn);
3712 if (system(buf)) {
3713 send_resp(dut, conn, SIGMA_ERROR,
3714 "errorCode,Failed to copy OSU CA cert");
3715 return 0;
3716 }
3717
3718 snprintf(buf, sizeof(buf),
3719 "cp Certs/aaa-ca.pem SP/%s/aaa-ca.pem",
3720 fqdn);
3721 if (system(buf)) {
3722 send_resp(dut, conn, SIGMA_ERROR,
3723 "errorCode,Failed to copy AAA CA cert");
3724 return 0;
3725 }
3726 } else {
3727 snprintf(buf, sizeof(buf),
3728 "dl_osu_ca SP/%s/pps.xml SP/%s/ca.pem",
3729 fqdn, fqdn);
3730 if (run_hs20_osu(dut, buf) < 0) {
3731 send_resp(dut, conn, SIGMA_ERROR,
3732 "errorCode,Failed to download OSU CA cert");
3733 return 0;
3734 }
3735
3736 snprintf(buf, sizeof(buf),
3737 "dl_aaa_ca SP/%s/pps.xml SP/%s/aaa-ca.pem",
3738 fqdn, fqdn);
3739 if (run_hs20_osu(dut, buf) < 0) {
3740 sigma_dut_print(dut, DUT_MSG_INFO,
3741 "Failed to download AAA CA cert");
3742 }
3743 }
3744
3745 if (file_exists("next-client-cert.pem")) {
3746 snprintf(buf, sizeof(buf), "SP/%s/client-cert.pem", fqdn);
3747 if (rename("next-client-cert.pem", buf) < 0) {
3748 send_resp(dut, conn, SIGMA_ERROR,
3749 "errorCode,Could not move client certificate");
3750 return 0;
3751 }
3752 }
3753
3754 if (file_exists("next-client-key.pem")) {
3755 snprintf(buf, sizeof(buf), "SP/%s/client-key.pem", fqdn);
3756 if (rename("next-client-key.pem", buf) < 0) {
3757 send_resp(dut, conn, SIGMA_ERROR,
3758 "errorCode,Could not move client key");
3759 return 0;
3760 }
3761 }
3762
3763 snprintf(buf, sizeof(buf), "set_pps SP/%s/pps.xml", fqdn);
3764 if (run_hs20_osu(dut, buf) < 0) {
3765 send_resp(dut, conn, SIGMA_ERROR,
3766 "errorCode,Failed to configure credential from "
3767 "PPSMO");
3768 return 0;
3769 }
3770
3771 return 1;
3772}
3773
3774
3775static int download_cert(struct sigma_dut *dut,
3776 struct sigma_conn *conn,
3777 const char *intf,
3778 struct sigma_cmd *cmd)
3779{
3780 const char *name, *path;
3781 char url[500], buf[600];
3782
3783 name = get_param(cmd, "FileName");
3784 path = get_param(cmd, "FilePath");
3785 if (name == NULL || path == NULL)
3786 return -1;
3787
3788 if (strcasecmp(path, "VendorSpecific") == 0) {
3789 snprintf(url, sizeof(url), "Certs/%s-cert.pem", name);
3790 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured client "
3791 "certificate from the device (%s)", url);
3792 if (!file_exists(url)) {
3793 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
3794 "certificate file does not exist");
3795 return 0;
3796 }
3797 snprintf(buf, sizeof(buf), "cp %s next-client-cert.pem", url);
3798 if (system(buf) != 0) {
3799 send_resp(dut, conn, SIGMA_ERROR,
3800 "errorCode,Failed to copy client "
3801 "certificate");
3802 return 0;
3803 }
3804
3805 snprintf(url, sizeof(url), "Certs/%s-key.pem", name);
3806 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured client "
3807 "private key from the device (%s)", url);
3808 if (!file_exists(url)) {
3809 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
3810 "private key file does not exist");
3811 return 0;
3812 }
3813 snprintf(buf, sizeof(buf), "cp %s next-client-key.pem", url);
3814 if (system(buf) != 0) {
3815 send_resp(dut, conn, SIGMA_ERROR,
3816 "errorCode,Failed to copy client key");
3817 return 0;
3818 }
3819 } else if (strncasecmp(path, "http:", 5) != 0 &&
3820 strncasecmp(path, "https:", 6) != 0) {
3821 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
3822 "Unsupported FilePath value");
3823 return 0;
3824 } else {
3825 snprintf(url, sizeof(url), "%s/%s.pem", path, name);
3826 sigma_dut_print(dut, DUT_MSG_INFO, "Downloading client "
3827 "certificate/key from %s", url);
3828 snprintf(buf, sizeof(buf),
3829 "wget -T 10 -t 3 -O next-client-cert.pem '%s'", url);
3830 if (system(buf) != 0) {
3831 send_resp(dut, conn, SIGMA_ERROR,
3832 "errorCode,Failed to download client "
3833 "certificate");
3834 return 0;
3835 }
3836
3837 if (system("cp next-client-cert.pem next-client-key.pem") != 0)
3838 {
3839 send_resp(dut, conn, SIGMA_ERROR,
3840 "errorCode,Failed to copy client key");
3841 return 0;
3842 }
3843 }
3844
3845 return 1;
3846}
3847
3848
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02003849static int cmd_sta_preset_testparameters_60ghz(struct sigma_dut *dut,
3850 struct sigma_conn *conn,
3851 struct sigma_cmd *cmd)
3852{
3853 const char *val;
3854 const char *intf = get_param(cmd, "interface");
3855
3856 if (!intf)
3857 return -1;
3858
3859 val = get_param(cmd, "WscIEFragment");
3860 if (val && strcasecmp(val, "enable") == 0) {
3861 sigma_dut_print(dut, DUT_MSG_DEBUG,
3862 "Enable WSC IE fragmentation");
3863
3864 dut->wsc_fragment = 1;
3865 /* set long attributes to force fragmentation */
3866 if (wpa_command(intf, "SET device_name "
3867 WPS_LONG_DEVICE_NAME) < 0)
3868 return -2;
3869 if (wpa_command(intf, "SET manufacturer "
3870 WPS_LONG_MANUFACTURER) < 0)
3871 return -2;
3872 if (wpa_command(intf, "SET model_name "
3873 WPS_LONG_MODEL_NAME) < 0)
3874 return -2;
3875 if (wpa_command(intf, "SET model_number "
3876 WPS_LONG_MODEL_NUMBER) < 0)
3877 return -2;
3878 if (wpa_command(intf, "SET serial_number "
3879 WPS_LONG_SERIAL_NUMBER) < 0)
3880 return -2;
3881 }
3882
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02003883 val = get_param(cmd, "RSN_IE");
3884 if (val) {
3885 if (strcasecmp(val, "disable") == 0)
3886 dut->force_rsn_ie = FORCE_RSN_IE_REMOVE;
3887 else if (strcasecmp(val, "enable") == 0)
3888 dut->force_rsn_ie = FORCE_RSN_IE_ADD;
3889 }
3890
Alexei Avshalom Lazar744ae8a2019-01-31 17:26:46 +02003891 val = get_param(cmd, "WpsVersion");
3892 if (val)
3893 dut->wps_forced_version = get_wps_forced_version(dut, val);
3894
Alexei Avshalom Lazar2eccf4d2019-01-31 10:03:59 +02003895 val = get_param(cmd, "WscEAPFragment");
3896 if (val && strcasecmp(val, "enable") == 0)
3897 dut->eap_fragment = 1;
3898
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02003899 return 1;
3900}
3901
3902
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003903static int cmd_sta_preset_testparameters_hs2_r2(struct sigma_dut *dut,
3904 struct sigma_conn *conn,
3905 const char *intf,
3906 struct sigma_cmd *cmd)
3907{
3908 const char *val;
3909
3910 val = get_param(cmd, "FileType");
3911 if (val && strcasecmp(val, "PPSMO") == 0)
3912 return download_ppsmo(dut, conn, intf, cmd);
3913 if (val && strcasecmp(val, "CERT") == 0)
3914 return download_cert(dut, conn, intf, cmd);
3915 if (val) {
3916 send_resp(dut, conn, SIGMA_ERROR,
3917 "ErrorCode,Unsupported FileType");
3918 return 0;
3919 }
3920
3921 return 1;
3922}
3923
3924
Ankita Bajaja2cb5672017-10-25 16:08:28 +05303925static int cmd_sta_preset_testparameters_oce(struct sigma_dut *dut,
3926 struct sigma_conn *conn,
3927 const char *intf,
3928 struct sigma_cmd *cmd)
3929{
3930 const char *val;
Ankita Bajaj1bde7942018-01-09 19:15:01 +05303931 char buf[1000];
3932 char text[20];
3933 unsigned char addr[ETH_ALEN];
Ankita Bajaja2cb5672017-10-25 16:08:28 +05303934
3935 val = get_param(cmd, "OCESupport");
3936 if (val && strcasecmp(val, "Disable") == 0) {
3937 if (wpa_command(intf, "SET oce 0") < 0) {
3938 send_resp(dut, conn, SIGMA_ERROR,
3939 "ErrorCode,Failed to disable OCE");
3940 return 0;
3941 }
3942 } else if (val && strcasecmp(val, "Enable") == 0) {
3943 if (wpa_command(intf, "SET oce 1") < 0) {
3944 send_resp(dut, conn, SIGMA_ERROR,
3945 "ErrorCode,Failed to enable OCE");
3946 return 0;
3947 }
3948 }
3949
vamsi krishnaa2799492017-12-05 14:28:01 +05303950 val = get_param(cmd, "FILScap");
3951 if (val && (atoi(val) == 1)) {
3952 if (wpa_command(intf, "SET disable_fils 0") < 0) {
3953 send_resp(dut, conn, SIGMA_ERROR,
3954 "ErrorCode,Failed to enable FILS");
3955 return 0;
3956 }
3957 } else if (val && (atoi(val) == 0)) {
3958 if (wpa_command(intf, "SET disable_fils 1") < 0) {
3959 send_resp(dut, conn, SIGMA_ERROR,
3960 "ErrorCode,Failed to disable FILS");
3961 return 0;
3962 }
3963 }
3964
Ankita Bajaj1bde7942018-01-09 19:15:01 +05303965 val = get_param(cmd, "FILSHLP");
3966 if (val && strcasecmp(val, "Enable") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003967 if (get_wpa_status(get_station_ifname(dut), "address", text,
Ankita Bajaj1bde7942018-01-09 19:15:01 +05303968 sizeof(text)) < 0)
3969 return -2;
3970 hwaddr_aton(text, addr);
3971 snprintf(buf, sizeof(buf),
3972 "FILS_HLP_REQ_ADD ff:ff:ff:ff:ff:ff "
3973 "080045100140000040004011399e00000000ffffffff00440043"
3974 "012cb30001010600fd4f46410000000000000000000000000000"
3975 "000000000000"
3976 "%02x%02x%02x%02x%02x%02x"
3977 "0000000000000000000000000000000000000000000000000000"
3978 "0000000000000000000000000000000000000000000000000000"
3979 "0000000000000000000000000000000000000000000000000000"
3980 "0000000000000000000000000000000000000000000000000000"
3981 "0000000000000000000000000000000000000000000000000000"
3982 "0000000000000000000000000000000000000000000000000000"
3983 "0000000000000000000000000000000000000000000000000000"
3984 "0000000000000000000000000000000000000000638253633501"
3985 "013d0701000af549d29b390205dc3c12616e64726f69642d6468"
3986 "63702d382e302e30370a0103060f1a1c333a3b2b5000ff00",
3987 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
3988 if (wpa_command(intf, buf)) {
3989 send_resp(dut, conn, SIGMA_ERROR,
3990 "ErrorCode,Failed to add HLP");
3991 return 0;
3992 }
3993 dut->fils_hlp = 1;
3994 }
3995
Ankita Bajaja2cb5672017-10-25 16:08:28 +05303996 return 1;
3997}
3998
3999
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004000static void ath_sta_set_noack(struct sigma_dut *dut, const char *intf,
4001 const char *val)
4002{
4003 int counter = 0;
4004 char token[50];
4005 char *result;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05304006 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004007
Peng Xub8fc5cc2017-05-10 17:27:28 -07004008 strlcpy(token, val, sizeof(token));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004009 token[sizeof(token) - 1] = '\0';
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05304010 result = strtok_r(token, ":", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004011 while (result) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004012 if (strcmp(result, "disable") == 0)
4013 run_iwpriv(dut, intf, "noackpolicy %d 1 0", counter);
4014 else
4015 run_iwpriv(dut, intf, "noackpolicy %d 1 1", counter);
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05304016 result = strtok_r(NULL, ":", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004017 counter++;
4018 }
4019}
4020
4021
4022static void ath_sta_set_rts(struct sigma_dut *dut, const char *intf,
4023 const char *val)
4024{
4025 char buf[100];
4026
4027 snprintf(buf, sizeof(buf), "iwconfig %s rts %s", intf, val);
4028 if (system(buf) != 0) {
4029 sigma_dut_print(dut, DUT_MSG_ERROR, "iwconfig RTS failed");
4030 }
4031}
4032
4033
4034static void ath_sta_set_wmm(struct sigma_dut *dut, const char *intf,
4035 const char *val)
4036{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004037 if (strcasecmp(val, "off") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004038 run_iwpriv(dut, intf, "wmm 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004039 }
4040}
4041
4042
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08004043static int wcn_sta_set_wmm(struct sigma_dut *dut, const char *intf,
4044 const char *val)
4045{
4046#ifdef NL80211_SUPPORT
4047 struct nl_msg *msg;
4048 int ret = 0;
4049 struct nlattr *params;
4050 int ifindex;
4051 int wmmenable = 1;
4052
4053 if (val &&
4054 (strcasecmp(val, "off") == 0 || strcmp(val, "0") == 0))
4055 wmmenable = 0;
4056
4057 ifindex = if_nametoindex(intf);
4058 if (ifindex == 0) {
4059 sigma_dut_print(dut, DUT_MSG_ERROR,
4060 "%s: Index for interface %s failed",
4061 __func__, intf);
4062 return -1;
4063 }
4064
4065 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4066 NL80211_CMD_VENDOR)) ||
4067 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4068 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4069 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4070 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4071 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4072 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WMM_ENABLE,
4073 wmmenable)) {
4074 sigma_dut_print(dut, DUT_MSG_ERROR,
4075 "%s: err in adding vendor_cmd and vendor_data",
4076 __func__);
4077 nlmsg_free(msg);
4078 return -1;
4079 }
4080 nla_nest_end(msg, params);
4081
4082 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4083 if (ret) {
4084 sigma_dut_print(dut, DUT_MSG_ERROR,
4085 "%s: err in send_and_recv_msgs, ret=%d",
4086 __func__, ret);
4087 }
4088 return ret;
4089#else /* NL80211_SUPPORT */
4090 sigma_dut_print(dut, DUT_MSG_ERROR,
4091 "WMM cannot be changed without NL80211_SUPPORT defined");
4092 return -1;
4093#endif /* NL80211_SUPPORT */
4094}
4095
4096
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004097static void ath_sta_set_sgi(struct sigma_dut *dut, const char *intf,
4098 const char *val)
4099{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004100 int sgi20;
4101
4102 sgi20 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
4103
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004104 run_iwpriv(dut, intf, "shortgi %d", sgi20);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004105}
4106
4107
4108static void ath_sta_set_11nrates(struct sigma_dut *dut, const char *intf,
4109 const char *val)
4110{
Pradeep Reddy POTTETI67376b72016-10-25 20:08:17 +05304111 int rate_code, v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004112
4113 /* Disable Tx Beam forming when using a fixed rate */
4114 ath_disable_txbf(dut, intf);
4115
Pradeep Reddy POTTETI67376b72016-10-25 20:08:17 +05304116 v = atoi(val);
4117 if (v < 0 || v > 32) {
4118 sigma_dut_print(dut, DUT_MSG_ERROR,
4119 "Invalid Fixed MCS rate: %d", v);
4120 return;
4121 }
4122 rate_code = 0x80 + v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004123
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004124 run_iwpriv(dut, intf, "set11NRates 0x%x", rate_code);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004125
4126 /* Channel width gets messed up, fix this */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004127 run_iwpriv(dut, intf, "chwidth %d", dut->chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004128}
4129
4130
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08004131static void iwpriv_sta_set_amsdu(struct sigma_dut *dut, const char *intf,
4132 const char *val)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004133{
4134 char buf[60];
4135
4136 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)
4137 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 2", intf);
4138 else
4139 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 1", intf);
4140
4141 if (system(buf) != 0)
4142 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv amsdu failed");
4143}
4144
4145
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07004146static int iwpriv_sta_set_ampdu(struct sigma_dut *dut, const char *intf,
4147 int ampdu)
4148{
4149 char buf[60];
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08004150 int maxaggregation = 63;
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07004151
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08004152 if (ampdu)
4153 ampdu = maxaggregation;
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07004154 snprintf(buf, sizeof(buf), "iwpriv %s ampdu %d", intf, ampdu);
4155 if (system(buf) != 0) {
4156 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv ampdu failed");
4157 return -1;
4158 }
4159
4160 return 0;
4161}
4162
4163
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004164static void ath_sta_set_stbc(struct sigma_dut *dut, const char *intf,
4165 const char *val)
4166{
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004167 run_iwpriv(dut, intf, "tx_stbc %s", val);
4168 run_iwpriv(dut, intf, "rx_stbc %s", val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004169}
4170
4171
4172static int wcn_sta_set_cts_width(struct sigma_dut *dut, const char *intf,
4173 const char *val)
4174{
4175 char buf[60];
4176
Peng Xucc317ed2017-05-18 16:44:37 -07004177 if (strcmp(val, "160") == 0) {
4178 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 5", intf);
4179 } else if (strcmp(val, "80") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004180 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 3", intf);
4181 } else if (strcmp(val, "40") == 0) {
4182 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 2", intf);
4183 } else if (strcmp(val, "20") == 0) {
4184 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 1", intf);
4185 } else if (strcasecmp(val, "Auto") == 0) {
4186 buf[0] = '\0';
4187 } else {
4188 sigma_dut_print(dut, DUT_MSG_ERROR,
4189 "WIDTH/CTS_WIDTH value not supported");
4190 return -1;
4191 }
4192
4193 if (buf[0] != '\0' && system(buf) != 0) {
4194 sigma_dut_print(dut, DUT_MSG_ERROR,
4195 "Failed to set WIDTH/CTS_WIDTH");
4196 return -1;
4197 }
4198
4199 return 0;
4200}
4201
4202
4203int ath_set_width(struct sigma_dut *dut, struct sigma_conn *conn,
4204 const char *intf, const char *val)
4205{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004206 if (strcasecmp(val, "Auto") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004207 run_iwpriv(dut, intf, "chwidth 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004208 dut->chwidth = 0;
4209 } else if (strcasecmp(val, "20") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004210 run_iwpriv(dut, intf, "chwidth 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004211 dut->chwidth = 0;
4212 } else if (strcasecmp(val, "40") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004213 run_iwpriv(dut, intf, "chwidth 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004214 dut->chwidth = 1;
4215 } else if (strcasecmp(val, "80") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004216 run_iwpriv(dut, intf, "chwidth 2");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004217 dut->chwidth = 2;
4218 } else if (strcasecmp(val, "160") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004219 run_iwpriv(dut, intf, "chwidth 3");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004220 dut->chwidth = 3;
4221 } else {
4222 send_resp(dut, conn, SIGMA_ERROR,
4223 "ErrorCode,WIDTH not supported");
4224 return -1;
4225 }
4226
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004227 return 0;
4228}
4229
4230
4231static int wcn_sta_set_sp_stream(struct sigma_dut *dut, const char *intf,
4232 const char *val)
4233{
4234 char buf[60];
Arif Hussainac6c5112018-05-25 17:34:00 -07004235 int sta_nss;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004236
Amarnath Hullur Subramanyamd5374fa2018-02-25 19:00:24 -08004237 if (strcmp(val, "1SS") == 0 || strcmp(val, "1") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004238 snprintf(buf, sizeof(buf), "iwpriv %s nss 1", intf);
Arif Hussainac6c5112018-05-25 17:34:00 -07004239 sta_nss = 1;
Amarnath Hullur Subramanyamd5374fa2018-02-25 19:00:24 -08004240 } else if (strcmp(val, "2SS") == 0 || strcmp(val, "2") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004241 snprintf(buf, sizeof(buf), "iwpriv %s nss 2", intf);
Arif Hussainac6c5112018-05-25 17:34:00 -07004242 sta_nss = 2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004243 } else {
4244 sigma_dut_print(dut, DUT_MSG_ERROR,
4245 "SP_STREAM value not supported");
4246 return -1;
4247 }
4248
4249 if (system(buf) != 0) {
4250 sigma_dut_print(dut, DUT_MSG_ERROR,
4251 "Failed to set SP_STREAM");
4252 return -1;
4253 }
4254
Arif Hussainac6c5112018-05-25 17:34:00 -07004255 dut->sta_nss = sta_nss;
4256
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004257 return 0;
4258}
4259
4260
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05304261static void wcn_sta_set_stbc(struct sigma_dut *dut, const char *intf,
4262 const char *val)
4263{
4264 char buf[60];
4265
4266 snprintf(buf, sizeof(buf), "iwpriv %s tx_stbc %s", intf, val);
4267 if (system(buf) != 0)
4268 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv tx_stbc failed");
4269
4270 snprintf(buf, sizeof(buf), "iwpriv %s rx_stbc %s", intf, val);
4271 if (system(buf) != 0)
4272 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv rx_stbc failed");
4273}
4274
4275
Ashwini Patil68d02cd2017-01-10 15:39:16 +05304276static int mbo_set_cellular_data_capa(struct sigma_dut *dut,
4277 struct sigma_conn *conn,
4278 const char *intf, int capa)
4279{
4280 char buf[32];
4281
4282 if (capa > 0 && capa < 4) {
4283 snprintf(buf, sizeof(buf), "SET mbo_cell_capa %d", capa);
4284 if (wpa_command(intf, buf) < 0) {
4285 send_resp(dut, conn, SIGMA_ERROR,
4286 "ErrorCode, Failed to set cellular data capability");
4287 return 0;
4288 }
4289 return 1;
4290 }
4291
4292 sigma_dut_print(dut, DUT_MSG_ERROR,
4293 "Invalid Cellular data capability: %d", capa);
4294 send_resp(dut, conn, SIGMA_INVALID,
4295 "ErrorCode,Invalid cellular data capability");
4296 return 0;
4297}
4298
4299
Ashwini Patil9183fdb2017-04-13 16:58:25 +05304300static int mbo_set_roaming(struct sigma_dut *dut, struct sigma_conn *conn,
4301 const char *intf, const char *val)
4302{
4303 if (strcasecmp(val, "Disable") == 0) {
4304 if (wpa_command(intf, "SET roaming 0") < 0) {
4305 send_resp(dut, conn, SIGMA_ERROR,
4306 "ErrorCode,Failed to disable roaming");
4307 return 0;
4308 }
4309 return 1;
4310 }
4311
4312 if (strcasecmp(val, "Enable") == 0) {
4313 if (wpa_command(intf, "SET roaming 1") < 0) {
4314 send_resp(dut, conn, SIGMA_ERROR,
4315 "ErrorCode,Failed to enable roaming");
4316 return 0;
4317 }
4318 return 1;
4319 }
4320
4321 sigma_dut_print(dut, DUT_MSG_ERROR,
4322 "Invalid value provided for roaming: %s", val);
4323 send_resp(dut, conn, SIGMA_INVALID,
4324 "ErrorCode,Unknown value provided for Roaming");
4325 return 0;
4326}
4327
4328
Ashwini Patila75de5a2017-04-13 16:35:05 +05304329static int mbo_set_assoc_disallow(struct sigma_dut *dut,
4330 struct sigma_conn *conn,
4331 const char *intf, const char *val)
4332{
4333 if (strcasecmp(val, "Disable") == 0) {
4334 if (wpa_command(intf, "SET ignore_assoc_disallow 1") < 0) {
4335 send_resp(dut, conn, SIGMA_ERROR,
4336 "ErrorCode,Failed to disable Assoc_disallow");
4337 return 0;
4338 }
4339 return 1;
4340 }
4341
4342 if (strcasecmp(val, "Enable") == 0) {
4343 if (wpa_command(intf, "SET ignore_assoc_disallow 0") < 0) {
4344 send_resp(dut, conn, SIGMA_ERROR,
4345 "ErrorCode,Failed to enable Assoc_disallow");
4346 return 0;
4347 }
4348 return 1;
4349 }
4350
4351 sigma_dut_print(dut, DUT_MSG_ERROR,
4352 "Invalid value provided for Assoc_disallow: %s", val);
4353 send_resp(dut, conn, SIGMA_INVALID,
4354 "ErrorCode,Unknown value provided for Assoc_disallow");
4355 return 0;
4356}
4357
4358
Ashwini Patilc63161e2017-04-13 16:30:23 +05304359static int mbo_set_bss_trans_req(struct sigma_dut *dut, struct sigma_conn *conn,
4360 const char *intf, const char *val)
4361{
4362 if (strcasecmp(val, "Reject") == 0) {
4363 if (wpa_command(intf, "SET reject_btm_req_reason 1") < 0) {
4364 send_resp(dut, conn, SIGMA_ERROR,
4365 "ErrorCode,Failed to Reject BTM Request");
4366 return 0;
4367 }
4368 return 1;
4369 }
4370
4371 if (strcasecmp(val, "Accept") == 0) {
4372 if (wpa_command(intf, "SET reject_btm_req_reason 0") < 0) {
4373 send_resp(dut, conn, SIGMA_ERROR,
4374 "ErrorCode,Failed to Accept BTM Request");
4375 return 0;
4376 }
4377 return 1;
4378 }
4379
4380 sigma_dut_print(dut, DUT_MSG_ERROR,
4381 "Invalid value provided for BSS_Transition: %s", val);
4382 send_resp(dut, conn, SIGMA_INVALID,
4383 "ErrorCode,Unknown value provided for BSS_Transition");
4384 return 0;
4385}
4386
4387
Ashwini Patil00402582017-04-13 12:29:39 +05304388static int mbo_set_non_pref_ch_list(struct sigma_dut *dut,
4389 struct sigma_conn *conn,
4390 const char *intf,
4391 struct sigma_cmd *cmd)
4392{
4393 const char *ch, *pref, *op_class, *reason;
4394 char buf[120];
4395 int len, ret;
4396
4397 pref = get_param(cmd, "Ch_Pref");
4398 if (!pref)
4399 return 1;
4400
4401 if (strcasecmp(pref, "clear") == 0) {
4402 free(dut->non_pref_ch_list);
4403 dut->non_pref_ch_list = NULL;
4404 } else {
4405 op_class = get_param(cmd, "Ch_Op_Class");
4406 if (!op_class) {
4407 send_resp(dut, conn, SIGMA_INVALID,
4408 "ErrorCode,Ch_Op_Class not provided");
4409 return 0;
4410 }
4411
4412 ch = get_param(cmd, "Ch_Pref_Num");
4413 if (!ch) {
4414 send_resp(dut, conn, SIGMA_INVALID,
4415 "ErrorCode,Ch_Pref_Num not provided");
4416 return 0;
4417 }
4418
4419 reason = get_param(cmd, "Ch_Reason_Code");
4420 if (!reason) {
4421 send_resp(dut, conn, SIGMA_INVALID,
4422 "ErrorCode,Ch_Reason_Code not provided");
4423 return 0;
4424 }
4425
4426 if (!dut->non_pref_ch_list) {
4427 dut->non_pref_ch_list =
4428 calloc(1, NON_PREF_CH_LIST_SIZE);
4429 if (!dut->non_pref_ch_list) {
4430 send_resp(dut, conn, SIGMA_ERROR,
4431 "ErrorCode,Failed to allocate memory for non_pref_ch_list");
4432 return 0;
4433 }
4434 }
4435 len = strlen(dut->non_pref_ch_list);
4436 ret = snprintf(dut->non_pref_ch_list + len,
4437 NON_PREF_CH_LIST_SIZE - len,
4438 " %s:%s:%s:%s", op_class, ch, pref, reason);
4439 if (ret > 0 && ret < NON_PREF_CH_LIST_SIZE - len) {
4440 sigma_dut_print(dut, DUT_MSG_DEBUG, "non_pref_list: %s",
4441 dut->non_pref_ch_list);
4442 } else {
4443 sigma_dut_print(dut, DUT_MSG_ERROR,
4444 "snprintf failed for non_pref_list, ret = %d",
4445 ret);
4446 send_resp(dut, conn, SIGMA_ERROR,
4447 "ErrorCode,snprintf failed");
4448 free(dut->non_pref_ch_list);
4449 dut->non_pref_ch_list = NULL;
4450 return 0;
4451 }
4452 }
4453
4454 ret = snprintf(buf, sizeof(buf), "SET non_pref_chan%s",
4455 dut->non_pref_ch_list ? dut->non_pref_ch_list : " ");
4456 if (ret < 0 || ret >= (int) sizeof(buf)) {
4457 sigma_dut_print(dut, DUT_MSG_DEBUG,
4458 "snprintf failed for set non_pref_chan, ret: %d",
4459 ret);
4460 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,snprint failed");
4461 return 0;
4462 }
4463
4464 if (wpa_command(intf, buf) < 0) {
4465 send_resp(dut, conn, SIGMA_ERROR,
4466 "ErrorCode,Failed to set non-preferred channel list");
4467 return 0;
4468 }
4469
4470 return 1;
4471}
4472
4473
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08004474#ifdef NL80211_SUPPORT
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08004475
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08004476static int sta_set_he_htc_supp(struct sigma_dut *dut, const char *intf,
4477 uint8_t cfg)
4478{
4479 struct nl_msg *msg;
4480 int ret = 0;
4481 struct nlattr *params;
4482 int ifindex;
4483
4484 ifindex = if_nametoindex(intf);
4485 if (ifindex == 0) {
4486 sigma_dut_print(dut, DUT_MSG_ERROR,
4487 "%s: Index for interface %s failed",
4488 __func__, intf);
4489 return -1;
4490 }
4491
4492 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4493 NL80211_CMD_VENDOR)) ||
4494 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4495 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4496 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4497 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4498 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4499 nla_put_u8(msg,
4500 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_HTC_HE_SUPP,
4501 cfg)) {
4502 sigma_dut_print(dut, DUT_MSG_ERROR,
4503 "%s: err in adding vendor_cmd and vendor_data",
4504 __func__);
4505 nlmsg_free(msg);
4506 return -1;
4507 }
4508 nla_nest_end(msg, params);
4509
4510 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4511 if (ret) {
4512 sigma_dut_print(dut, DUT_MSG_ERROR,
4513 "%s: err in send_and_recv_msgs, ret=%d",
4514 __func__, ret);
4515 }
4516 return ret;
4517}
4518
4519
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08004520static int sta_set_he_fragmentation(struct sigma_dut *dut, const char *intf,
4521 enum he_fragmentation_val frag)
4522{
4523 struct nl_msg *msg;
4524 int ret = 0;
4525 struct nlattr *params;
4526 int ifindex;
4527
4528 ifindex = if_nametoindex(intf);
4529 if (ifindex == 0) {
4530 sigma_dut_print(dut, DUT_MSG_ERROR,
4531 "%s: Index for interface %s failed",
4532 __func__, intf);
4533 return -1;
4534 }
4535
4536 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4537 NL80211_CMD_VENDOR)) ||
4538 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4539 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4540 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4541 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4542 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4543 nla_put_u8(msg,
4544 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_FRAGMENTATION,
4545 frag)) {
4546 sigma_dut_print(dut, DUT_MSG_ERROR,
4547 "%s: err in adding vendor_cmd and vendor_data",
4548 __func__);
4549 nlmsg_free(msg);
4550 return -1;
4551 }
4552 nla_nest_end(msg, params);
4553
4554 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4555 if (ret) {
4556 sigma_dut_print(dut, DUT_MSG_ERROR,
4557 "%s: err in send_and_recv_msgs, ret=%d",
4558 __func__, ret);
4559 }
4560 return ret;
4561}
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08004562
4563
Subhani Shaik8e7a3052018-04-24 14:03:00 -07004564static int sta_set_he_ltf(struct sigma_dut *dut, const char *intf,
4565 enum qca_wlan_he_ltf_cfg ltf)
4566{
4567 struct nl_msg *msg;
4568 int ret = 0;
4569 struct nlattr *params;
4570 int ifindex;
4571
4572 ifindex = if_nametoindex(intf);
4573 if (ifindex == 0) {
4574 sigma_dut_print(dut, DUT_MSG_ERROR,
4575 "%s: Index for interface %s failed",
4576 __func__, intf);
4577 return -1;
4578 }
4579
4580 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4581 NL80211_CMD_VENDOR)) ||
4582 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4583 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4584 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4585 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4586 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4587 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_LTF,
4588 ltf)) {
4589 sigma_dut_print(dut, DUT_MSG_ERROR,
4590 "%s: err in adding vendor_cmd and vendor_data",
4591 __func__);
4592 nlmsg_free(msg);
4593 return -1;
4594 }
4595 nla_nest_end(msg, params);
4596
4597 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4598 if (ret) {
4599 sigma_dut_print(dut, DUT_MSG_ERROR,
4600 "%s: err in send_and_recv_msgs, ret=%d",
4601 __func__, ret);
4602 }
4603 return ret;
4604}
4605
4606
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08004607static int nlvendor_sta_set_noack(struct sigma_dut *dut, const char *intf,
4608 int noack, enum qca_wlan_ac_type ac)
4609{
4610 struct nl_msg *msg;
4611 int ret = 0;
4612 struct nlattr *params;
4613 int ifindex;
4614
4615 ifindex = if_nametoindex(intf);
4616 if (ifindex == 0) {
4617 sigma_dut_print(dut, DUT_MSG_ERROR,
4618 "%s: Index for interface %s failed",
4619 __func__, intf);
4620 return -1;
4621 }
4622
4623 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4624 NL80211_CMD_VENDOR)) ||
4625 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4626 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4627 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4628 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4629 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4630 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_NO_ACK,
4631 noack) ||
4632 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_NO_ACK_AC,
4633 ac)) {
4634 sigma_dut_print(dut, DUT_MSG_ERROR,
4635 "%s: err in adding vendor_cmd and vendor_data",
4636 __func__);
4637 nlmsg_free(msg);
4638 return -1;
4639 }
4640 nla_nest_end(msg, params);
4641
4642 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4643 if (ret) {
4644 sigma_dut_print(dut, DUT_MSG_ERROR,
4645 "%s: err in send_and_recv_msgs, ret=%d",
4646 __func__, ret);
4647 }
4648 return ret;
4649}
4650
4651
4652static void wcn_sta_set_noack(struct sigma_dut *dut, const char *intf,
4653 const char *val)
4654{
4655 int noack, ret;
4656 char token[100];
4657 char *result;
4658 char *saveptr;
4659 enum qca_wlan_ac_type ac = QCA_WLAN_AC_BE;
4660
4661 strlcpy(token, val, sizeof(token));
4662 token[sizeof(token) - 1] = '\0';
4663 result = strtok_r(token, ":", &saveptr);
4664 while (result) {
4665 noack = strcasecmp(result, "Disable") != 0;
4666 ret = nlvendor_sta_set_noack(dut, intf, noack, ac);
4667 if (ret) {
4668 sigma_dut_print(dut, DUT_MSG_ERROR,
4669 "nlvendor_sta_set_noack failed for ac:%d, ret:%d",
4670 ac, ret);
4671 }
4672 result = strtok_r(NULL, ":", &saveptr);
4673 ac++;
4674 }
4675}
4676
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08004677#endif /* NL80211_SUPPORT */
4678
4679
Jouni Malinenf7222712019-06-13 01:50:21 +03004680static enum sigma_cmd_result
4681cmd_sta_preset_testparameters(struct sigma_dut *dut, struct sigma_conn *conn,
4682 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004683{
4684 const char *intf = get_param(cmd, "Interface");
4685 const char *val;
4686
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03004687 val = get_param(cmd, "FT_DS");
4688 if (val) {
4689 if (strcasecmp(val, "Enable") == 0) {
4690 dut->sta_ft_ds = 1;
4691 } else if (strcasecmp(val, "Disable") == 0) {
4692 dut->sta_ft_ds = 0;
4693 } else {
4694 send_resp(dut, conn, SIGMA_ERROR,
4695 "errorCode,Unsupported value for FT_DS");
4696 return STATUS_SENT_ERROR;
4697 }
4698 }
4699
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004700 val = get_param(cmd, "Program");
Jouni Malinen1f6ae642018-06-07 23:56:13 +03004701 if (val && (strcasecmp(val, "HS2-R2") == 0 ||
4702 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004703 return cmd_sta_preset_testparameters_hs2_r2(dut, conn, intf,
4704 cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004705
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07004706 if (val && strcasecmp(val, "LOC") == 0)
4707 return loc_cmd_sta_preset_testparameters(dut, conn, cmd);
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02004708 if (val && strcasecmp(val, "60GHZ") == 0) {
4709 val = get_param(cmd, "WPS");
4710 if (val && strcasecmp(val, "disable") == 0) {
4711 dut->wps_disable = 1;
4712 sigma_dut_print(dut, DUT_MSG_INFO, "WPS disabled");
4713 } else {
4714 /* wps_disable can have other value from the previous
4715 * test, so make sure it has the correct value.
4716 */
4717 dut->wps_disable = 0;
4718 }
4719
4720 val = get_param(cmd, "P2P");
4721 if (val && strcasecmp(val, "disable") == 0)
4722 sigma_dut_print(dut, DUT_MSG_INFO, "P2P disabled");
4723 }
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07004724
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02004725 if (dut->program == PROGRAM_WPS && dut->band == WPS_BAND_60G)
4726 return cmd_sta_preset_testparameters_60ghz(dut, conn, cmd);
4727
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004728#ifdef ANDROID_NAN
4729 if (val && strcasecmp(val, "NAN") == 0)
4730 return nan_cmd_sta_preset_testparameters(dut, conn, cmd);
4731#endif /* ANDROID_NAN */
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07004732#ifdef MIRACAST
4733 if (val && (strcasecmp(val, "WFD") == 0 ||
4734 strcasecmp(val, "DisplayR2") == 0))
4735 return miracast_preset_testparameters(dut, conn, cmd);
4736#endif /* MIRACAST */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004737
Ashwini Patil68d02cd2017-01-10 15:39:16 +05304738 if (val && strcasecmp(val, "MBO") == 0) {
4739 val = get_param(cmd, "Cellular_Data_Cap");
4740 if (val &&
4741 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
4742 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +05304743
4744 val = get_param(cmd, "Ch_Pref");
4745 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
4746 return 0;
4747
Ashwini Patilc63161e2017-04-13 16:30:23 +05304748 val = get_param(cmd, "BSS_Transition");
4749 if (val && mbo_set_bss_trans_req(dut, conn, intf, val) == 0)
4750 return 0;
4751
Ashwini Patila75de5a2017-04-13 16:35:05 +05304752 val = get_param(cmd, "Assoc_Disallow");
4753 if (val && mbo_set_assoc_disallow(dut, conn, intf, val) == 0)
4754 return 0;
4755
Ashwini Patil9183fdb2017-04-13 16:58:25 +05304756 val = get_param(cmd, "Roaming");
4757 if (val && mbo_set_roaming(dut, conn, intf, val) == 0)
4758 return 0;
4759
Ashwini Patil68d02cd2017-01-10 15:39:16 +05304760 return 1;
4761 }
4762
Ankita Bajaja2cb5672017-10-25 16:08:28 +05304763 if (val && strcasecmp(val, "OCE") == 0)
4764 return cmd_sta_preset_testparameters_oce(dut, conn, intf, cmd);
4765
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004766#if 0
4767 val = get_param(cmd, "Supplicant");
4768 if (val && strcasecmp(val, "Default") != 0) {
4769 send_resp(dut, conn, SIGMA_ERROR,
4770 "ErrorCode,Only default(Vendor) supplicant "
4771 "supported");
4772 return 0;
4773 }
4774#endif
4775
4776 val = get_param(cmd, "RTS");
4777 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004778 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004779 case DRIVER_ATHEROS:
4780 ath_sta_set_rts(dut, intf, val);
4781 break;
4782 default:
4783#if 0
4784 send_resp(dut, conn, SIGMA_ERROR,
4785 "ErrorCode,Setting RTS not supported");
4786 return 0;
4787#else
4788 sigma_dut_print(dut, DUT_MSG_DEBUG,
4789 "Setting RTS not supported");
4790 break;
4791#endif
4792 }
4793 }
4794
4795#if 0
4796 val = get_param(cmd, "FRGMNT");
4797 if (val) {
4798 /* TODO */
4799 send_resp(dut, conn, SIGMA_ERROR,
4800 "ErrorCode,Setting FRGMNT not supported");
4801 return 0;
4802 }
4803#endif
4804
4805#if 0
4806 val = get_param(cmd, "Preamble");
4807 if (val) {
4808 /* TODO: Long/Short */
4809 send_resp(dut, conn, SIGMA_ERROR,
4810 "ErrorCode,Setting Preamble not supported");
4811 return 0;
4812 }
4813#endif
4814
4815 val = get_param(cmd, "Mode");
4816 if (val) {
4817 if (strcmp(val, "11b") == 0 ||
4818 strcmp(val, "11g") == 0 ||
4819 strcmp(val, "11a") == 0 ||
4820 strcmp(val, "11n") == 0 ||
4821 strcmp(val, "11ng") == 0 ||
4822 strcmp(val, "11nl") == 0 ||
4823 strcmp(val, "11nl(nabg)") == 0 ||
4824 strcmp(val, "AC") == 0 ||
4825 strcmp(val, "11AC") == 0 ||
4826 strcmp(val, "11ac") == 0 ||
4827 strcmp(val, "11na") == 0 ||
Amarnath Hullur Subramanyamb0db2712018-01-30 19:40:35 -08004828 strcmp(val, "11an") == 0 ||
4829 strcmp(val, "11ax") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004830 /* STA supports all modes by default */
4831 } else {
4832 send_resp(dut, conn, SIGMA_ERROR,
4833 "ErrorCode,Setting Mode not supported");
4834 return 0;
4835 }
Amarnath Hullur Subramanyam97d0e532018-01-31 02:53:02 -08004836
4837 /* Change the mode only in case of testbed for HE program
4838 * and for 11a and 11g modes only. */
4839 if (dut->program == PROGRAM_HE &&
4840 dut->device_type == STA_testbed) {
4841 int phymode;
4842 char buf[60];
4843
4844 if (strcmp(val, "11a") == 0) {
Amarnath Hullur Subramanyam94dfaf02018-03-02 19:26:57 -08004845 phymode = 1; /* IEEE80211_MODE_11A */
4846 } else if (strcmp(val, "11g") == 0) {
4847 phymode = 3; /* IEEE80211_MODE_11G */
4848 } else if (strcmp(val, "11b") == 0) {
4849 phymode = 2; /* IEEE80211_MODE_11B */
4850 } else if (strcmp(val, "11n") == 0 ||
4851 strcmp(val, "11nl") == 0 ||
4852 strcmp(val, "11nl(nabg)") == 0) {
4853 phymode = 22; /* IEEE80211_MODE_11AGN */
4854 } else if (strcmp(val, "11ng") == 0) {
4855 phymode = 13; /* IEEE80211_MODE_11NG_HT40 */
4856 } else if (strcmp(val, "AC") == 0 ||
4857 strcasecmp(val, "11AC") == 0) {
4858 phymode = 19; /* IEEE80211_MODE_11AC_VHT80 */
4859 } else if (strcmp(val, "11na") == 0 ||
4860 strcasecmp(val, "11an") == 0) {
4861 phymode = 14; /* IEEE80211_MODE_11NA_HT40 */
4862 } else if (strcmp(val, "11ax") == 0) {
4863 phymode = 0; /* IEEE80211_MODE_AUTO */
Amarnath Hullur Subramanyam97d0e532018-01-31 02:53:02 -08004864 } else {
4865 sigma_dut_print(dut, DUT_MSG_DEBUG,
4866 "Ignoring mode change for mode: %s",
4867 val);
4868 phymode = -1;
4869 }
4870 if (phymode != -1) {
4871 snprintf(buf, sizeof(buf),
4872 "iwpriv %s setphymode %d",
4873 intf, phymode);
4874 if (system(buf) != 0) {
4875 sigma_dut_print(dut, DUT_MSG_ERROR,
4876 "iwpriv setting of phymode failed");
4877 }
4878 }
4879 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004880 }
4881
4882 val = get_param(cmd, "wmm");
4883 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004884 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004885 case DRIVER_ATHEROS:
4886 ath_sta_set_wmm(dut, intf, val);
4887 break;
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08004888 case DRIVER_WCN:
4889 wcn_sta_set_wmm(dut, intf, val);
4890 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004891 default:
4892 sigma_dut_print(dut, DUT_MSG_DEBUG,
4893 "Setting wmm not supported");
4894 break;
4895 }
4896 }
4897
4898 val = get_param(cmd, "Powersave");
4899 if (val) {
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08004900 char buf[60];
4901
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004902 if (strcmp(val, "0") == 0 || strcasecmp(val, "off") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004903 if (get_driver_type(dut) == DRIVER_WCN) {
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08004904 snprintf(buf, sizeof(buf),
4905 "iwpriv %s setPower 2", intf);
4906 if (system(buf) != 0) {
4907 sigma_dut_print(dut, DUT_MSG_ERROR,
4908 "iwpriv setPower 2 failed");
4909 return 0;
4910 }
4911 }
4912
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004913 if (wpa_command(get_station_ifname(dut),
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004914 "P2P_SET ps 0") < 0)
4915 return -2;
4916 /* Make sure test modes are disabled */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004917 wpa_command(get_station_ifname(dut), "P2P_SET ps 98");
4918 wpa_command(get_station_ifname(dut), "P2P_SET ps 96");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004919 } else if (strcmp(val, "1") == 0 ||
4920 strcasecmp(val, "PSPoll") == 0 ||
4921 strcasecmp(val, "on") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004922 if (get_driver_type(dut) == DRIVER_WCN) {
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08004923 snprintf(buf, sizeof(buf),
4924 "iwpriv %s setPower 1", intf);
4925 if (system(buf) != 0) {
4926 sigma_dut_print(dut, DUT_MSG_ERROR,
4927 "iwpriv setPower 1 failed");
4928 return 0;
4929 }
4930 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004931 /* Disable default power save mode */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004932 wpa_command(get_station_ifname(dut), "P2P_SET ps 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004933 /* Enable PS-Poll test mode */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004934 if (wpa_command(get_station_ifname(dut),
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004935 "P2P_SET ps 97") < 0 ||
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004936 wpa_command(get_station_ifname(dut),
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004937 "P2P_SET ps 99") < 0)
4938 return -2;
4939 } else if (strcmp(val, "2") == 0 ||
4940 strcasecmp(val, "Fast") == 0) {
4941 /* TODO */
4942 send_resp(dut, conn, SIGMA_ERROR,
4943 "ErrorCode,Powersave=Fast not supported");
4944 return 0;
4945 } else if (strcmp(val, "3") == 0 ||
4946 strcasecmp(val, "PSNonPoll") == 0) {
4947 /* Make sure test modes are disabled */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004948 wpa_command(get_station_ifname(dut), "P2P_SET ps 98");
4949 wpa_command(get_station_ifname(dut), "P2P_SET ps 96");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004950
4951 /* Enable default power save mode */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004952 if (wpa_command(get_station_ifname(dut),
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004953 "P2P_SET ps 1") < 0)
4954 return -2;
4955 } else
4956 return -1;
4957 }
4958
4959 val = get_param(cmd, "NoAck");
4960 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004961 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004962 case DRIVER_ATHEROS:
4963 ath_sta_set_noack(dut, intf, val);
4964 break;
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08004965#ifdef NL80211_SUPPORT
4966 case DRIVER_WCN:
4967 wcn_sta_set_noack(dut, intf, val);
4968 break;
4969#endif /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004970 default:
4971 send_resp(dut, conn, SIGMA_ERROR,
4972 "ErrorCode,Setting NoAck not supported");
4973 return 0;
4974 }
4975 }
4976
4977 val = get_param(cmd, "IgnoreChswitchProhibit");
4978 if (val) {
4979 /* TODO: Enabled/disabled */
4980 if (strcasecmp(val, "Enabled") == 0) {
4981 send_resp(dut, conn, SIGMA_ERROR,
4982 "ErrorCode,Enabling IgnoreChswitchProhibit "
4983 "not supported");
4984 return 0;
4985 }
4986 }
4987
4988 val = get_param(cmd, "TDLS");
4989 if (val) {
4990 if (strcasecmp(val, "Disabled") == 0) {
4991 if (wpa_command(intf, "SET tdls_disabled 1")) {
4992 send_resp(dut, conn, SIGMA_ERROR,
4993 "ErrorCode,Failed to disable TDLS");
4994 return 0;
4995 }
4996 } else if (strcasecmp(val, "Enabled") == 0) {
4997 if (wpa_command(intf, "SET tdls_disabled 0")) {
4998 send_resp(dut, conn, SIGMA_ERROR,
4999 "ErrorCode,Failed to enable TDLS");
5000 return 0;
5001 }
5002 } else {
5003 send_resp(dut, conn, SIGMA_ERROR,
5004 "ErrorCode,Unsupported TDLS value");
5005 return 0;
5006 }
5007 }
5008
5009 val = get_param(cmd, "TDLSmode");
5010 if (val) {
5011 if (strcasecmp(val, "Default") == 0) {
5012 wpa_command(intf, "SET tdls_testing 0");
5013 } else if (strcasecmp(val, "APProhibit") == 0) {
5014 if (wpa_command(intf, "SET tdls_testing 0x400")) {
5015 send_resp(dut, conn, SIGMA_ERROR,
5016 "ErrorCode,Failed to enable ignore "
5017 "APProhibit TDLS mode");
5018 return 0;
5019 }
5020 } else if (strcasecmp(val, "HiLoMac") == 0) {
5021 /* STA should respond with TDLS setup req for a TDLS
5022 * setup req */
5023 if (wpa_command(intf, "SET tdls_testing 0x80")) {
5024 send_resp(dut, conn, SIGMA_ERROR,
5025 "ErrorCode,Failed to enable HiLoMac "
5026 "TDLS mode");
5027 return 0;
5028 }
5029 } else if (strcasecmp(val, "WeakSecurity") == 0) {
5030 /*
5031 * Since all security modes are enabled by default when
5032 * Sigma control is used, there is no need to do
5033 * anything here.
5034 */
5035 } else if (strcasecmp(val, "ExistLink") == 0) {
5036 /*
5037 * Since we allow new TDLS Setup Request even if there
5038 * is an existing link, nothing needs to be done for
5039 * this.
5040 */
5041 } else {
5042 /* TODO:
5043 * ExistLink: STA should send TDLS setup req even if
5044 * direct link already exists
5045 */
5046 send_resp(dut, conn, SIGMA_ERROR,
5047 "ErrorCode,Unsupported TDLSmode value");
5048 return 0;
5049 }
5050 }
5051
5052 val = get_param(cmd, "FakePubKey");
5053 if (val && atoi(val) && wpa_command(intf, "SET wps_corrupt_pkhash 1")) {
5054 send_resp(dut, conn, SIGMA_ERROR,
5055 "ErrorCode,Failed to enable FakePubKey");
5056 return 0;
5057 }
5058
Amarnath Hullur Subramanyamae1042b2018-02-22 21:52:52 -08005059#ifdef NL80211_SUPPORT
5060 val = get_param(cmd, "FrgmntSupport");
5061 if (val) {
5062 if (strcasecmp(val, "Enable") == 0) {
5063 if (sta_set_he_fragmentation(dut, intf,
5064 HE_FRAG_LEVEL1)) {
5065 send_resp(dut, conn, SIGMA_ERROR,
5066 "ErrorCode,Failed to enable HE Fragmentation");
5067 return 0;
5068 }
5069 } else if (strcasecmp(val, "Disable") == 0) {
5070 if (sta_set_he_fragmentation(dut, intf,
5071 HE_FRAG_DISABLE)) {
5072 send_resp(dut, conn, SIGMA_ERROR,
5073 "ErrorCode,Failed to disable HE Fragmentation");
5074 return 0;
5075 }
5076 }
5077 }
5078#endif /* NL80211_SUPPORT */
5079
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005080 return 1;
5081}
5082
5083
5084static const char * ath_get_radio_name(const char *radio_name)
5085{
5086 if (radio_name == NULL)
5087 return "wifi0";
5088 if (strcmp(radio_name, "wifi1") == 0)
5089 return "wifi1";
5090 if (strcmp(radio_name, "wifi2") == 0)
5091 return "wifi2";
5092 return "wifi0";
5093}
5094
5095
5096static void ath_sta_set_txsp_stream(struct sigma_dut *dut, const char *intf,
5097 const char *val)
5098{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005099 unsigned int vht_mcsmap = 0;
5100 int txchainmask = 0;
5101 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
5102
5103 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
5104 if (dut->testbed_flag_txsp == 1) {
5105 vht_mcsmap = 0xfffc;
5106 dut->testbed_flag_txsp = 0;
5107 } else {
5108 vht_mcsmap = 0xfffe;
5109 }
5110 txchainmask = 1;
5111 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
5112 if (dut->testbed_flag_txsp == 1) {
5113 vht_mcsmap = 0xfff0;
5114 dut->testbed_flag_txsp = 0;
5115 } else {
5116 vht_mcsmap = 0xfffa;
5117 }
5118 txchainmask = 3;
5119 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
5120 if (dut->testbed_flag_txsp == 1) {
5121 vht_mcsmap = 0xffc0;
5122 dut->testbed_flag_txsp = 0;
5123 } else {
5124 vht_mcsmap = 0xffea;
5125 }
5126 txchainmask = 7;
5127 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
5128 if (dut->testbed_flag_txsp == 1) {
5129 vht_mcsmap = 0xff00;
5130 dut->testbed_flag_txsp = 0;
5131 } else {
5132 vht_mcsmap = 0xffaa;
5133 }
5134 txchainmask = 15;
5135 } else {
5136 if (dut->testbed_flag_txsp == 1) {
5137 vht_mcsmap = 0xffc0;
5138 dut->testbed_flag_txsp = 0;
5139 } else {
5140 vht_mcsmap = 0xffea;
5141 }
5142 }
5143
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005144 if (txchainmask)
5145 run_iwpriv(dut, basedev, "txchainmask %d", txchainmask);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005146
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005147 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005148}
5149
5150
5151static void ath_sta_set_rxsp_stream(struct sigma_dut *dut, const char *intf,
5152 const char *val)
5153{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005154 unsigned int vht_mcsmap = 0;
5155 int rxchainmask = 0;
5156 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
5157
5158 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
5159 if (dut->testbed_flag_rxsp == 1) {
5160 vht_mcsmap = 0xfffc;
5161 dut->testbed_flag_rxsp = 0;
5162 } else {
5163 vht_mcsmap = 0xfffe;
5164 }
5165 rxchainmask = 1;
5166 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
5167 if (dut->testbed_flag_rxsp == 1) {
5168 vht_mcsmap = 0xfff0;
5169 dut->testbed_flag_rxsp = 0;
5170 } else {
5171 vht_mcsmap = 0xfffa;
5172 }
5173 rxchainmask = 3;
5174 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
5175 if (dut->testbed_flag_rxsp == 1) {
5176 vht_mcsmap = 0xffc0;
5177 dut->testbed_flag_rxsp = 0;
5178 } else {
5179 vht_mcsmap = 0xffea;
5180 }
5181 rxchainmask = 7;
5182 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
5183 if (dut->testbed_flag_rxsp == 1) {
5184 vht_mcsmap = 0xff00;
5185 dut->testbed_flag_rxsp = 0;
5186 } else {
5187 vht_mcsmap = 0xffaa;
5188 }
5189 rxchainmask = 15;
5190 } else {
5191 if (dut->testbed_flag_rxsp == 1) {
5192 vht_mcsmap = 0xffc0;
5193 dut->testbed_flag_rxsp = 0;
5194 } else {
5195 vht_mcsmap = 0xffea;
5196 }
5197 }
5198
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005199 if (rxchainmask)
5200 run_iwpriv(dut, basedev, "rxchainmask %d", rxchainmask);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005201
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005202 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005203}
5204
5205
5206void ath_set_zero_crc(struct sigma_dut *dut, const char *val)
5207{
5208 if (strcasecmp(val, "enable") == 0) {
5209 if (system("athdiag --set --address=0x2a204 --and=0xbfffffff")
5210 != 0) {
5211 sigma_dut_print(dut, DUT_MSG_ERROR,
5212 "Disable BB_VHTSIGB_CRC_CALC failed");
5213 }
5214
5215 if (system("athdiag --set --address=0x2a204 --or=0x80000000")
5216 != 0) {
5217 sigma_dut_print(dut, DUT_MSG_ERROR,
5218 "Enable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
5219 }
5220 } else {
5221 if (system("athdiag --set --address=0x2a204 --and=0x7fffffff")
5222 != 0) {
5223 sigma_dut_print(dut, DUT_MSG_ERROR,
5224 "Disable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
5225 }
5226
5227 if (system("athdiag --set --address=0x2a204 --or=0x40000000")
5228 != 0) {
5229 sigma_dut_print(dut, DUT_MSG_ERROR,
5230 "Enable BB_VHTSIGB_CRC_CALC failed");
5231 }
5232 }
5233}
5234
5235
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08005236static int wcn_sta_set_width(struct sigma_dut *dut, const char *intf,
5237 const char *val)
5238{
5239 char buf[60];
5240
5241 if (strcmp(val, "20") == 0) {
5242 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 0", intf);
5243 dut->chwidth = 0;
5244 } else if (strcmp(val, "40") == 0) {
5245 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 1", intf);
5246 dut->chwidth = 1;
5247 } else if (strcmp(val, "80") == 0) {
5248 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 2", intf);
5249 dut->chwidth = 2;
Sunil Duttb1cccac2018-05-22 21:03:12 +05305250 } else if (strcasecmp(val, "Auto") == 0) {
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08005251 buf[0] = '\0';
5252 } else {
5253 sigma_dut_print(dut, DUT_MSG_ERROR, "WIDTH %s not supported",
5254 val);
5255 return -1;
5256 }
5257
5258 if (buf[0] != '\0' && system(buf) != 0) {
5259 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv chwidth failed");
5260 return -1;
5261 }
5262
5263 return 0;
5264}
5265
5266
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005267static int nlvendor_sta_set_addba_reject(struct sigma_dut *dut,
5268 const char *intf, int addbareject)
5269{
5270#ifdef NL80211_SUPPORT
5271 struct nl_msg *msg;
5272 int ret = 0;
5273 struct nlattr *params;
5274 int ifindex;
5275
5276 ifindex = if_nametoindex(intf);
5277 if (ifindex == 0) {
5278 sigma_dut_print(dut, DUT_MSG_ERROR,
5279 "%s: Index for interface %s failed",
5280 __func__, intf);
5281 return -1;
5282 }
5283
5284 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
5285 NL80211_CMD_VENDOR)) ||
5286 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
5287 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
5288 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
5289 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
5290 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
5291 nla_put_u8(msg,
5292 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ACCEPT_ADDBA_REQ,
5293 !addbareject)) {
5294 sigma_dut_print(dut, DUT_MSG_ERROR,
5295 "%s: err in adding vendor_cmd and vendor_data",
5296 __func__);
5297 nlmsg_free(msg);
5298 return -1;
5299 }
5300 nla_nest_end(msg, params);
5301
5302 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5303 if (ret) {
5304 sigma_dut_print(dut, DUT_MSG_ERROR,
5305 "%s: err in send_and_recv_msgs, ret=%d",
5306 __func__, ret);
5307 }
5308 return ret;
5309#else /* NL80211_SUPPORT */
5310 sigma_dut_print(dut, DUT_MSG_ERROR,
5311 "ADDBA_REJECT cannot be set without NL80211_SUPPORT defined");
5312 return -1;
5313#endif /* NL80211_SUPPORT */
5314}
5315
5316
5317static int sta_set_addba_reject(struct sigma_dut *dut, const char *intf,
5318 int addbareject)
5319{
5320 int ret;
5321
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005322 switch (get_driver_type(dut)) {
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005323 case DRIVER_WCN:
5324 ret = nlvendor_sta_set_addba_reject(dut, intf, addbareject);
5325 if (ret) {
5326 sigma_dut_print(dut, DUT_MSG_ERROR,
5327 "nlvendor_sta_set_addba_reject failed, ret:%d",
5328 ret);
5329 return ret;
5330 }
5331 break;
5332 default:
5333 sigma_dut_print(dut, DUT_MSG_ERROR,
5334 "errorCode,Unsupported ADDBA_REJECT with the current driver");
5335 ret = -1;
5336 break;
5337 }
5338
5339 return ret;
5340}
5341
5342
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08005343static int nlvendor_config_send_addba(struct sigma_dut *dut, const char *intf,
5344 int enable)
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005345{
5346#ifdef NL80211_SUPPORT
5347 struct nl_msg *msg;
5348 int ret = 0;
5349 struct nlattr *params;
5350 int ifindex;
5351
5352 ifindex = if_nametoindex(intf);
5353 if (ifindex == 0) {
5354 sigma_dut_print(dut, DUT_MSG_ERROR,
5355 "%s: Index for interface %s failed",
5356 __func__, intf);
5357 return -1;
5358 }
5359
5360 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
5361 NL80211_CMD_VENDOR)) ||
5362 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
5363 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
5364 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
5365 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
5366 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
5367 nla_put_u8(msg,
5368 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_SEND_ADDBA_REQ,
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08005369 enable)) {
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005370 sigma_dut_print(dut, DUT_MSG_ERROR,
5371 "%s: err in adding vendor_cmd and vendor_data",
5372 __func__);
5373 nlmsg_free(msg);
5374 return -1;
5375 }
5376 nla_nest_end(msg, params);
5377
5378 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5379 if (ret) {
5380 sigma_dut_print(dut, DUT_MSG_ERROR,
5381 "%s: err in send_and_recv_msgs, ret=%d",
5382 __func__, ret);
5383 }
5384 return ret;
5385#else /* NL80211_SUPPORT */
5386 sigma_dut_print(dut, DUT_MSG_ERROR,
5387 "Disable addba not possible without NL80211_SUPPORT defined");
5388 return -1;
5389#endif /* NL80211_SUPPORT */
5390}
5391
5392
Veerendranath Jakkamadcd6202019-04-17 12:32:21 +05305393#ifdef NL80211_SUPPORT
5394static int nl80211_sta_set_rts(struct sigma_dut *dut, const char *intf, int val)
5395{
5396 struct nl_msg *msg;
5397 int ret = 0;
5398 int ifindex;
5399
5400 ifindex = if_nametoindex(intf);
5401 if (ifindex == 0) {
5402 sigma_dut_print(dut, DUT_MSG_ERROR,
5403 "%s: Index for interface %s failed",
5404 __func__, intf);
5405 return -1;
5406 }
5407
5408 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
5409 NL80211_CMD_SET_WIPHY)) ||
5410 nla_put_u32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD, val)) {
5411 sigma_dut_print(dut, DUT_MSG_ERROR,
5412 "%s: err in adding RTS threshold",
5413 __func__);
5414 nlmsg_free(msg);
5415 return -1;
5416 }
5417
5418 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5419 if (ret) {
5420 sigma_dut_print(dut, DUT_MSG_ERROR,
5421 "%s: err in send_and_recv_msgs, ret=%d",
5422 __func__, ret);
5423 }
5424 return ret;
5425}
5426#endif /* NL80211_SUPPORT */
5427
5428
5429static int sta_set_rts(struct sigma_dut *dut, const char *intf, int val)
5430{
5431 char buf[100];
5432
5433#ifdef NL80211_SUPPORT
5434 if (nl80211_sta_set_rts(dut, intf, val) == 0)
5435 return 0;
5436 sigma_dut_print(dut, DUT_MSG_DEBUG,
5437 "Fall back to using iwconfig for setting RTS threshold");
5438#endif /* NL80211_SUPPORT */
5439
5440 snprintf(buf, sizeof(buf), "iwconfig %s rts %d", intf, val);
5441 if (system(buf) != 0) {
5442 sigma_dut_print(dut, DUT_MSG_ERROR,
5443 "Failed to set RTS threshold %d", val);
5444 return -1;
5445 }
5446 return 0;
5447}
5448
5449
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005450static int cmd_sta_set_wireless_common(const char *intf, struct sigma_dut *dut,
5451 struct sigma_conn *conn,
5452 struct sigma_cmd *cmd)
5453{
5454 const char *val;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005455 int ampdu = -1, addbareject = -1;
Jouni Malinen3aa72862019-05-29 23:14:51 +03005456 char buf[128];
5457 int res;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005458
5459 val = get_param(cmd, "40_INTOLERANT");
5460 if (val) {
5461 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
5462 /* TODO: iwpriv ht40intol through wpa_supplicant */
5463 send_resp(dut, conn, SIGMA_ERROR,
5464 "ErrorCode,40_INTOLERANT not supported");
5465 return 0;
5466 }
5467 }
5468
5469 val = get_param(cmd, "ADDBA_REJECT");
5470 if (val) {
5471 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
5472 /* reject any ADDBA with status "decline" */
5473 ampdu = 0;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005474 addbareject = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005475 } else {
5476 /* accept ADDBA */
5477 ampdu = 1;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005478 addbareject = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005479 }
5480 }
5481
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005482 if (addbareject >= 0 &&
5483 sta_set_addba_reject(dut, intf, addbareject) < 0) {
5484 send_resp(dut, conn, SIGMA_ERROR,
5485 "ErrorCode,set addba_reject failed");
5486 return 0;
5487 }
5488
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005489 val = get_param(cmd, "AMPDU");
5490 if (val) {
5491 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
5492 /* enable AMPDU Aggregation */
5493 if (ampdu == 0) {
5494 send_resp(dut, conn, SIGMA_ERROR,
5495 "ErrorCode,Mismatch in "
5496 "addba_reject/ampdu - "
5497 "not supported");
5498 return 0;
5499 }
5500 ampdu = 1;
5501 } else {
5502 /* disable AMPDU Aggregation */
5503 if (ampdu == 1) {
5504 send_resp(dut, conn, SIGMA_ERROR,
5505 "ErrorCode,Mismatch in "
5506 "addba_reject/ampdu - "
5507 "not supported");
5508 return 0;
5509 }
5510 ampdu = 0;
5511 }
5512 }
5513
5514 if (ampdu >= 0) {
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005515 int ret;
5516
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005517 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s A-MPDU aggregation",
5518 ampdu ? "Enabling" : "Disabling");
5519 snprintf(buf, sizeof(buf), "SET ampdu %d", ampdu);
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07005520 if (wpa_command(intf, buf) < 0 &&
5521 iwpriv_sta_set_ampdu(dut, intf, ampdu) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005522 send_resp(dut, conn, SIGMA_ERROR,
5523 "ErrorCode,set aggr failed");
5524 return 0;
5525 }
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005526
5527 if (ampdu == 0) {
5528 /* Disable sending of addba using nl vendor command */
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08005529 ret = nlvendor_config_send_addba(dut, intf, 0);
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005530 if (ret) {
5531 sigma_dut_print(dut, DUT_MSG_ERROR,
5532 "Failed to disable addba, ret:%d",
5533 ret);
5534 }
5535 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005536 }
5537
5538 val = get_param(cmd, "AMSDU");
5539 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005540 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005541 case DRIVER_ATHEROS:
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08005542 case DRIVER_WCN:
5543 iwpriv_sta_set_amsdu(dut, intf, val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005544 break;
5545 default:
5546 if (strcmp(val, "1") == 0 ||
5547 strcasecmp(val, "Enable") == 0) {
5548 /* Enable AMSDU Aggregation */
5549 send_resp(dut, conn, SIGMA_ERROR,
5550 "ErrorCode,AMSDU aggregation not supported");
5551 return 0;
5552 }
5553 break;
5554 }
5555 }
5556
5557 val = get_param(cmd, "STBC_RX");
5558 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005559 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005560 case DRIVER_ATHEROS:
5561 ath_sta_set_stbc(dut, intf, val);
5562 break;
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05305563 case DRIVER_WCN:
5564 wcn_sta_set_stbc(dut, intf, val);
5565 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005566 default:
5567 send_resp(dut, conn, SIGMA_ERROR,
5568 "ErrorCode,STBC_RX not supported");
5569 return 0;
5570 }
5571 }
5572
5573 val = get_param(cmd, "WIDTH");
5574 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005575 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005576 case DRIVER_WCN:
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08005577 if (wcn_sta_set_width(dut, intf, val) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005578 send_resp(dut, conn, SIGMA_ERROR,
5579 "ErrorCode,Failed to set WIDTH");
5580 return 0;
5581 }
5582 break;
5583 case DRIVER_ATHEROS:
5584 if (ath_set_width(dut, conn, intf, val) < 0)
5585 return 0;
5586 break;
5587 default:
5588 sigma_dut_print(dut, DUT_MSG_ERROR,
5589 "Setting WIDTH not supported");
5590 break;
5591 }
5592 }
5593
5594 val = get_param(cmd, "SMPS");
5595 if (val) {
5596 /* TODO: Dynamic/0, Static/1, No Limit/2 */
5597 send_resp(dut, conn, SIGMA_ERROR,
5598 "ErrorCode,SMPS not supported");
5599 return 0;
5600 }
5601
5602 val = get_param(cmd, "TXSP_STREAM");
5603 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005604 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005605 case DRIVER_WCN:
5606 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
5607 send_resp(dut, conn, SIGMA_ERROR,
5608 "ErrorCode,Failed to set TXSP_STREAM");
5609 return 0;
5610 }
5611 break;
5612 case DRIVER_ATHEROS:
5613 ath_sta_set_txsp_stream(dut, intf, val);
5614 break;
5615 default:
5616 sigma_dut_print(dut, DUT_MSG_ERROR,
5617 "Setting TXSP_STREAM not supported");
5618 break;
5619 }
5620 }
5621
5622 val = get_param(cmd, "RXSP_STREAM");
5623 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005624 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005625 case DRIVER_WCN:
5626 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
5627 send_resp(dut, conn, SIGMA_ERROR,
5628 "ErrorCode,Failed to set RXSP_STREAM");
5629 return 0;
5630 }
5631 break;
5632 case DRIVER_ATHEROS:
5633 ath_sta_set_rxsp_stream(dut, intf, val);
5634 break;
5635 default:
5636 sigma_dut_print(dut, DUT_MSG_ERROR,
5637 "Setting RXSP_STREAM not supported");
5638 break;
5639 }
5640 }
5641
5642 val = get_param(cmd, "DYN_BW_SGNL");
5643 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005644 switch (get_driver_type(dut)) {
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08005645 case DRIVER_WCN:
Peng Xuc59afd32016-11-21 15:01:11 -08005646 if (strcasecmp(val, "enable") == 0) {
5647 snprintf(buf, sizeof(buf),
5648 "iwpriv %s cwmenable 1", intf);
5649 if (system(buf) != 0) {
5650 sigma_dut_print(dut, DUT_MSG_ERROR,
5651 "iwpriv cwmenable 1 failed");
5652 return 0;
5653 }
5654 } else if (strcasecmp(val, "disable") == 0) {
5655 snprintf(buf, sizeof(buf),
5656 "iwpriv %s cwmenable 0", intf);
5657 if (system(buf) != 0) {
5658 sigma_dut_print(dut, DUT_MSG_ERROR,
5659 "iwpriv cwmenable 0 failed");
5660 return 0;
5661 }
5662 } else {
5663 sigma_dut_print(dut, DUT_MSG_ERROR,
5664 "Unsupported DYN_BW_SGL");
5665 }
5666
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005667 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 3", intf);
5668 if (system(buf) != 0) {
5669 sigma_dut_print(dut, DUT_MSG_ERROR,
5670 "Failed to set cts_cbw in DYN_BW_SGNL");
5671 return 0;
5672 }
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08005673 break;
5674 case DRIVER_ATHEROS:
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -07005675 novap_reset(dut, intf, 1);
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08005676 ath_config_dyn_bw_sig(dut, intf, val);
5677 break;
5678 default:
5679 sigma_dut_print(dut, DUT_MSG_ERROR,
5680 "Failed to set DYN_BW_SGNL");
5681 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005682 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005683 }
5684
5685 val = get_param(cmd, "RTS_FORCE");
5686 if (val) {
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -07005687 novap_reset(dut, intf, 1);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005688 if (strcasecmp(val, "Enable") == 0) {
Veerendranath Jakkamadcd6202019-04-17 12:32:21 +05305689 if (sta_set_rts(dut, intf, 64) != 0) {
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02005690 sigma_dut_print(dut, DUT_MSG_ERROR,
5691 "Failed to set RTS_FORCE 64");
5692 }
Jouni Malinen3aa72862019-05-29 23:14:51 +03005693 res = snprintf(buf, sizeof(buf),
5694 "wifitool %s beeliner_fw_test 100 1",
5695 intf);
5696 if (res < 0 || res >= sizeof(buf) || system(buf) != 0) {
priyadharshini gowthaman270870e2015-12-09 10:10:23 -08005697 sigma_dut_print(dut, DUT_MSG_ERROR,
5698 "wifitool beeliner_fw_test 100 1 failed");
5699 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005700 } else if (strcasecmp(val, "Disable") == 0) {
Veerendranath Jakkamadcd6202019-04-17 12:32:21 +05305701 if (sta_set_rts(dut, intf, 2347) != 0) {
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02005702 sigma_dut_print(dut, DUT_MSG_ERROR,
5703 "Failed to set RTS_FORCE 2347");
5704 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005705 } else {
5706 send_resp(dut, conn, SIGMA_ERROR,
5707 "ErrorCode,RTS_FORCE value not supported");
5708 return 0;
5709 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005710 }
5711
5712 val = get_param(cmd, "CTS_WIDTH");
5713 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005714 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005715 case DRIVER_WCN:
5716 if (wcn_sta_set_cts_width(dut, intf, val) < 0) {
5717 send_resp(dut, conn, SIGMA_ERROR,
5718 "ErrorCode,Failed to set CTS_WIDTH");
5719 return 0;
5720 }
5721 break;
5722 case DRIVER_ATHEROS:
5723 ath_set_cts_width(dut, intf, val);
5724 break;
5725 default:
5726 sigma_dut_print(dut, DUT_MSG_ERROR,
5727 "Setting CTS_WIDTH not supported");
5728 break;
5729 }
5730 }
5731
5732 val = get_param(cmd, "BW_SGNL");
5733 if (val) {
5734 if (strcasecmp(val, "Enable") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005735 run_iwpriv(dut, intf, "cwmenable 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005736 } else if (strcasecmp(val, "Disable") == 0) {
5737 /* TODO: Disable */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005738 } else {
5739 send_resp(dut, conn, SIGMA_ERROR,
5740 "ErrorCode,BW_SGNL value not supported");
5741 return 0;
5742 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005743 }
5744
5745 val = get_param(cmd, "Band");
5746 if (val) {
5747 if (strcmp(val, "2.4") == 0 || strcmp(val, "5") == 0) {
5748 /* STA supports all bands by default */
5749 } else {
5750 send_resp(dut, conn, SIGMA_ERROR,
5751 "ErrorCode,Unsupported Band");
5752 return 0;
5753 }
5754 }
5755
5756 val = get_param(cmd, "zero_crc");
5757 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005758 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005759 case DRIVER_ATHEROS:
5760 ath_set_zero_crc(dut, val);
5761 break;
5762 default:
5763 break;
5764 }
5765 }
5766
5767 return 1;
5768}
5769
5770
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02005771static int sta_set_force_mcs(struct sigma_dut *dut, int force, int mcs)
5772{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005773 switch (get_driver_type(dut)) {
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02005774#ifdef __linux__
5775 case DRIVER_WIL6210:
5776 return wil6210_set_force_mcs(dut, force, mcs);
5777#endif /* __linux__ */
5778 default:
5779 sigma_dut_print(dut, DUT_MSG_ERROR,
5780 "Unsupported sta_set_force_mcs with the current driver");
5781 return -1;
5782 }
5783}
5784
5785
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02005786static int sta_60g_force_rsn_ie(struct sigma_dut *dut, int state)
5787{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005788 switch (get_driver_type(dut)) {
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02005789#ifdef __linux__
5790 case DRIVER_WIL6210:
5791 return wil6210_force_rsn_ie(dut, state);
5792#endif /* __linux__ */
5793 default:
5794 sigma_dut_print(dut, DUT_MSG_ERROR,
5795 "Unsupported sta_60g_force_rsn_ie with the current driver");
5796 return -1;
5797 }
5798}
5799
5800
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005801static int sta_set_60g_common(struct sigma_dut *dut, struct sigma_conn *conn,
5802 struct sigma_cmd *cmd)
5803{
5804 const char *val;
5805 char buf[100];
5806
5807 val = get_param(cmd, "MSDUSize");
5808 if (val) {
5809 int mtu;
5810
5811 dut->amsdu_size = atoi(val);
5812 if (dut->amsdu_size > IEEE80211_MAX_DATA_LEN_DMG ||
5813 dut->amsdu_size < IEEE80211_SNAP_LEN_DMG) {
5814 sigma_dut_print(dut, DUT_MSG_ERROR,
5815 "MSDUSize %d is above max %d or below min %d",
5816 dut->amsdu_size,
5817 IEEE80211_MAX_DATA_LEN_DMG,
5818 IEEE80211_SNAP_LEN_DMG);
5819 dut->amsdu_size = 0;
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005820 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005821 }
5822
5823 mtu = dut->amsdu_size - IEEE80211_SNAP_LEN_DMG;
5824 sigma_dut_print(dut, DUT_MSG_DEBUG,
5825 "Setting amsdu_size to %d", mtu);
5826 snprintf(buf, sizeof(buf), "ifconfig %s mtu %d",
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005827 get_station_ifname(dut), mtu);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005828
5829 if (system(buf) != 0) {
5830 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
5831 buf);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005832 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005833 }
5834 }
5835
5836 val = get_param(cmd, "BAckRcvBuf");
5837 if (val) {
5838 dut->back_rcv_buf = atoi(val);
5839 if (dut->back_rcv_buf == 0) {
5840 sigma_dut_print(dut, DUT_MSG_ERROR,
5841 "Failed to convert %s or value is 0",
5842 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005843 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005844 }
5845
5846 sigma_dut_print(dut, DUT_MSG_DEBUG,
5847 "Setting BAckRcvBuf to %s", val);
5848 }
5849
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02005850 val = get_param(cmd, "MCS_FixedRate");
5851 if (val) {
5852 if (sta_set_force_mcs(dut, 1, atoi(val))) {
5853 sigma_dut_print(dut, DUT_MSG_ERROR,
5854 "Failed to force MCS");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005855 return ERROR_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02005856 }
5857 }
5858
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005859 return SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005860}
5861
5862
5863static int sta_pcp_start(struct sigma_dut *dut, struct sigma_conn *conn,
5864 struct sigma_cmd *cmd)
5865{
5866 int net_id;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005867 const char *ifname;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005868 const char *val;
5869 char buf[100];
5870
5871 dut->mode = SIGMA_MODE_STATION;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005872 ifname = get_main_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005873 if (wpa_command(ifname, "PING") != 0) {
5874 sigma_dut_print(dut, DUT_MSG_ERROR, "Supplicant not running");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005875 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005876 }
5877
5878 wpa_command(ifname, "FLUSH");
5879 net_id = add_network_common(dut, conn, ifname, cmd);
5880 if (net_id < 0) {
5881 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add network");
5882 return net_id;
5883 }
5884
5885 /* TODO: mode=2 for the AP; in the future, replace for mode PCP */
5886 if (set_network(ifname, net_id, "mode", "2") < 0) {
5887 sigma_dut_print(dut, DUT_MSG_ERROR,
5888 "Failed to set supplicant network mode");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005889 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005890 }
5891
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02005892 if (set_network(ifname, net_id, "pbss", "1") < 0)
5893 return -2;
5894
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005895 sigma_dut_print(dut, DUT_MSG_DEBUG,
Alexei Avshalom Lazarfd9f1352018-11-13 14:07:58 +02005896 "Supplicant set network with mode 2. network_id %d",
5897 net_id);
5898
5899 if (set_network(ifname, net_id, "wps_disabled", "0") < 0) {
5900 sigma_dut_print(dut, DUT_MSG_INFO,
5901 "Failed to set supplicant to WPS ENABLE");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005902 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarfd9f1352018-11-13 14:07:58 +02005903 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005904
5905 val = get_param(cmd, "Security");
5906 if (val && strcasecmp(val, "OPEN") == 0) {
5907 dut->ap_key_mgmt = AP_OPEN;
5908 if (set_network(ifname, net_id, "key_mgmt", "NONE") < 0) {
5909 sigma_dut_print(dut, DUT_MSG_ERROR,
5910 "Failed to set supplicant to %s security",
5911 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005912 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005913 }
5914 } else if (val && strcasecmp(val, "WPA2-PSK") == 0) {
5915 dut->ap_key_mgmt = AP_WPA2_PSK;
5916 if (set_network(ifname, net_id, "key_mgmt", "WPA-PSK") < 0) {
5917 sigma_dut_print(dut, DUT_MSG_ERROR,
5918 "Failed to set supplicant to %s security",
5919 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005920 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005921 }
5922
5923 if (set_network(ifname, net_id, "proto", "RSN") < 0) {
5924 sigma_dut_print(dut, DUT_MSG_ERROR,
5925 "Failed to set supplicant to proto RSN");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005926 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005927 }
5928 } else if (val) {
5929 sigma_dut_print(dut, DUT_MSG_ERROR,
5930 "Requested Security %s is not supported on 60GHz",
5931 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005932 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005933 }
5934
5935 val = get_param(cmd, "Encrypt");
5936 if (val && strcasecmp(val, "AES-GCMP") == 0) {
5937 if (set_network(ifname, net_id, "pairwise", "GCMP") < 0) {
5938 sigma_dut_print(dut, DUT_MSG_ERROR,
5939 "Failed to set supplicant to pairwise GCMP");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005940 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005941 }
5942 if (set_network(ifname, net_id, "group", "GCMP") < 0) {
5943 sigma_dut_print(dut, DUT_MSG_ERROR,
5944 "Failed to set supplicant to group GCMP");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005945 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005946 }
5947 } else if (val) {
5948 sigma_dut_print(dut, DUT_MSG_ERROR,
5949 "Requested Encrypt %s is not supported on 60 GHz",
5950 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005951 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005952 }
5953
5954 val = get_param(cmd, "PSK");
5955 if (val && set_network_quoted(ifname, net_id, "psk", val) < 0) {
5956 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set psk %s",
5957 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005958 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005959 }
5960
5961 /* Convert 60G channel to freq */
5962 switch (dut->ap_channel) {
5963 case 1:
5964 val = "58320";
5965 break;
5966 case 2:
5967 val = "60480";
5968 break;
5969 case 3:
5970 val = "62640";
5971 break;
5972 default:
5973 sigma_dut_print(dut, DUT_MSG_ERROR,
5974 "Failed to configure channel %d. Not supported",
5975 dut->ap_channel);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005976 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005977 }
5978
5979 if (set_network(ifname, net_id, "frequency", val) < 0) {
5980 sigma_dut_print(dut, DUT_MSG_ERROR,
5981 "Failed to set supplicant network frequency");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005982 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005983 }
5984
Alexei Avshalom Lazar2eccf4d2019-01-31 10:03:59 +02005985 if (dut->eap_fragment) {
5986 sigma_dut_print(dut, DUT_MSG_DEBUG,
5987 "Set EAP fragment size to 128 bytes.");
5988 if (set_network(ifname, net_id, "fragment_size", "128") < 0)
5989 return ERROR_SEND_STATUS;
5990 }
5991
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005992 sigma_dut_print(dut, DUT_MSG_DEBUG,
5993 "Supplicant set network with frequency");
5994
5995 snprintf(buf, sizeof(buf), "SELECT_NETWORK %d", net_id);
5996 if (wpa_command(ifname, buf) < 0) {
5997 sigma_dut_print(dut, DUT_MSG_INFO,
5998 "Failed to select network id %d on %s",
5999 net_id, ifname);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02006000 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006001 }
6002
6003 sigma_dut_print(dut, DUT_MSG_DEBUG, "Selected network");
6004
Jouni Malinen0e29cf22019-02-19 01:13:21 +02006005 return SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006006}
6007
6008
Lior David67543f52017-01-03 19:04:22 +02006009static int wil6210_set_abft_len(struct sigma_dut *dut, int abft_len)
6010{
6011 char buf[128], fname[128];
6012 FILE *f;
Jouni Malinen3aa72862019-05-29 23:14:51 +03006013 int res;
Lior David67543f52017-01-03 19:04:22 +02006014
6015 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
6016 sigma_dut_print(dut, DUT_MSG_ERROR,
6017 "failed to get wil6210 debugfs dir");
6018 return -1;
6019 }
6020
Jouni Malinen3aa72862019-05-29 23:14:51 +03006021 res = snprintf(fname, sizeof(fname), "%s/abft_len", buf);
6022 if (res < 0 || res >= sizeof(fname))
6023 return -1;
Lior David67543f52017-01-03 19:04:22 +02006024 f = fopen(fname, "w");
6025 if (!f) {
6026 sigma_dut_print(dut, DUT_MSG_ERROR,
6027 "failed to open: %s", fname);
6028 return -1;
6029 }
6030
6031 fprintf(f, "%d\n", abft_len);
6032 fclose(f);
6033
6034 return 0;
6035}
6036
6037
Alexei Avshalom Lazar49498b82019-01-31 15:16:32 +02006038int sta_set_60g_abft_len(struct sigma_dut *dut, struct sigma_conn *conn,
6039 int abft_len)
Lior David67543f52017-01-03 19:04:22 +02006040{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006041 switch (get_driver_type(dut)) {
Lior David67543f52017-01-03 19:04:22 +02006042 case DRIVER_WIL6210:
6043 return wil6210_set_abft_len(dut, abft_len);
6044 default:
6045 sigma_dut_print(dut, DUT_MSG_ERROR,
6046 "set abft_len not supported");
6047 return -1;
6048 }
6049}
6050
6051
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006052static int sta_set_60g_pcp(struct sigma_dut *dut, struct sigma_conn *conn,
6053 struct sigma_cmd *cmd)
6054{
6055 const char *val;
Lior David67543f52017-01-03 19:04:22 +02006056 unsigned int abft_len = 1; /* default is one slot */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006057
6058 if (dut->dev_role != DEVROLE_PCP) {
6059 send_resp(dut, conn, SIGMA_INVALID,
6060 "ErrorCode,Invalid DevRole");
6061 return 0;
6062 }
6063
6064 val = get_param(cmd, "SSID");
6065 if (val) {
6066 if (strlen(val) > sizeof(dut->ap_ssid) - 1) {
6067 send_resp(dut, conn, SIGMA_INVALID,
6068 "ErrorCode,Invalid SSID");
6069 return -1;
6070 }
6071
Peng Xub8fc5cc2017-05-10 17:27:28 -07006072 strlcpy(dut->ap_ssid, val, sizeof(dut->ap_ssid));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006073 }
6074
6075 val = get_param(cmd, "CHANNEL");
6076 if (val) {
6077 const char *pos;
6078
6079 dut->ap_channel = atoi(val);
6080 pos = strchr(val, ';');
6081 if (pos) {
6082 pos++;
6083 dut->ap_channel_1 = atoi(pos);
6084 }
6085 }
6086
6087 switch (dut->ap_channel) {
6088 case 1:
6089 case 2:
6090 case 3:
6091 break;
6092 default:
6093 sigma_dut_print(dut, DUT_MSG_ERROR,
6094 "Channel %d is not supported", dut->ap_channel);
6095 send_resp(dut, conn, SIGMA_ERROR,
6096 "Requested channel is not supported");
6097 return -1;
6098 }
6099
6100 val = get_param(cmd, "BCNINT");
6101 if (val)
6102 dut->ap_bcnint = atoi(val);
6103
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006104 val = get_param(cmd, "AllocType");
6105 if (val) {
6106 send_resp(dut, conn, SIGMA_ERROR,
6107 "ErrorCode,AllocType is not supported yet");
6108 return -1;
6109 }
6110
6111 val = get_param(cmd, "PercentBI");
6112 if (val) {
6113 send_resp(dut, conn, SIGMA_ERROR,
6114 "ErrorCode,PercentBI is not supported yet");
6115 return -1;
6116 }
6117
6118 val = get_param(cmd, "CBAPOnly");
6119 if (val) {
6120 send_resp(dut, conn, SIGMA_ERROR,
6121 "ErrorCode,CBAPOnly is not supported yet");
6122 return -1;
6123 }
6124
6125 val = get_param(cmd, "AMPDU");
6126 if (val) {
6127 if (strcasecmp(val, "Enable") == 0)
6128 dut->ap_ampdu = 1;
6129 else if (strcasecmp(val, "Disable") == 0)
6130 dut->ap_ampdu = 2;
6131 else {
6132 send_resp(dut, conn, SIGMA_ERROR,
6133 "ErrorCode,AMPDU value is not Enable nor Disabled");
6134 return -1;
6135 }
6136 }
6137
6138 val = get_param(cmd, "AMSDU");
6139 if (val) {
6140 if (strcasecmp(val, "Enable") == 0)
6141 dut->ap_amsdu = 1;
6142 else if (strcasecmp(val, "Disable") == 0)
6143 dut->ap_amsdu = 2;
6144 }
6145
6146 val = get_param(cmd, "NumMSDU");
6147 if (val) {
6148 send_resp(dut, conn, SIGMA_ERROR,
6149 "ErrorCode, NumMSDU is not supported yet");
6150 return -1;
6151 }
6152
6153 val = get_param(cmd, "ABFTLRang");
6154 if (val) {
6155 sigma_dut_print(dut, DUT_MSG_DEBUG,
Lior David67543f52017-01-03 19:04:22 +02006156 "ABFTLRang parameter %s", val);
6157 if (strcmp(val, "Gt1") == 0)
6158 abft_len = 2; /* 2 slots in this case */
6159 }
6160
6161 if (sta_set_60g_abft_len(dut, conn, abft_len)) {
6162 send_resp(dut, conn, SIGMA_ERROR,
6163 "ErrorCode, Can't set ABFT length");
6164 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006165 }
6166
6167 if (sta_pcp_start(dut, conn, cmd) < 0) {
6168 send_resp(dut, conn, SIGMA_ERROR,
6169 "ErrorCode, Can't start PCP role");
6170 return -1;
6171 }
6172
6173 return sta_set_60g_common(dut, conn, cmd);
6174}
6175
6176
6177static int sta_set_60g_sta(struct sigma_dut *dut, struct sigma_conn *conn,
6178 struct sigma_cmd *cmd)
6179{
6180 const char *val = get_param(cmd, "DiscoveryMode");
6181
6182 if (dut->dev_role != DEVROLE_STA) {
6183 send_resp(dut, conn, SIGMA_INVALID,
6184 "ErrorCode,Invalid DevRole");
6185 return 0;
6186 }
6187
6188 if (val) {
6189 sigma_dut_print(dut, DUT_MSG_DEBUG, "Discovery: %s", val);
6190 /* Ignore Discovery mode till Driver expose API. */
6191#if 0
6192 if (strcasecmp(val, "1") == 0) {
6193 send_resp(dut, conn, SIGMA_INVALID,
6194 "ErrorCode,DiscoveryMode 1 not supported");
6195 return 0;
6196 }
6197
6198 if (strcasecmp(val, "0") == 0) {
6199 /* OK */
6200 } else {
6201 send_resp(dut, conn, SIGMA_INVALID,
6202 "ErrorCode,DiscoveryMode not supported");
6203 return 0;
6204 }
6205#endif
6206 }
6207
6208 if (start_sta_mode(dut) != 0)
Jouni Malinen0e29cf22019-02-19 01:13:21 +02006209 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006210 return sta_set_60g_common(dut, conn, cmd);
6211}
6212
6213
Jouni Malinenf7222712019-06-13 01:50:21 +03006214static enum sigma_cmd_result cmd_sta_disconnect(struct sigma_dut *dut,
6215 struct sigma_conn *conn,
6216 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006217{
6218 const char *intf = get_param(cmd, "Interface");
Jouni Malinened77e672018-01-10 16:45:13 +02006219 const char *val = get_param(cmd, "maintain_profile");
vamsi krishnad605c422017-09-20 14:56:31 +05306220
Jouni Malinened77e672018-01-10 16:45:13 +02006221 if (dut->program == PROGRAM_OCE ||
Amarnath Hullur Subramanyamebeda9e2018-01-31 03:21:48 -08006222 dut->program == PROGRAM_HE ||
Jouni Malinened77e672018-01-10 16:45:13 +02006223 (val && atoi(val) == 1)) {
vamsi krishnad605c422017-09-20 14:56:31 +05306224 wpa_command(intf, "DISCONNECT");
6225 return 1;
6226 }
6227
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006228 disconnect_station(dut);
6229 /* Try to ignore old scan results to avoid HS 2.0R2 test case failures
6230 * due to cached results. */
6231 wpa_command(intf, "SET ignore_old_scan_res 1");
6232 wpa_command(intf, "BSS_FLUSH");
6233 return 1;
6234}
6235
6236
Jouni Malinenf7222712019-06-13 01:50:21 +03006237static enum sigma_cmd_result cmd_sta_reassoc(struct sigma_dut *dut,
6238 struct sigma_conn *conn,
6239 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006240{
6241 const char *intf = get_param(cmd, "Interface");
6242 const char *bssid = get_param(cmd, "bssid");
6243 const char *val = get_param(cmd, "CHANNEL");
6244 struct wpa_ctrl *ctrl;
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05306245 char buf[1000];
Sunil Duttd30ce092018-01-11 23:56:29 +05306246 char result[32];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006247 int res;
6248 int chan = 0;
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006249 enum sigma_cmd_result status = STATUS_SENT;
Sunil Duttd30ce092018-01-11 23:56:29 +05306250 int fastreassoc = 1;
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006251 int ft_ds = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006252
6253 if (bssid == NULL) {
6254 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing bssid "
6255 "argument");
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006256 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006257 }
6258
6259 if (val)
6260 chan = atoi(val);
6261
6262 if (wifi_chip_type != DRIVER_WCN && wifi_chip_type != DRIVER_AR6003) {
6263 /* The current network may be from sta_associate or
6264 * sta_hs2_associate
6265 */
6266 if (set_network(intf, dut->infra_network_id, "bssid", bssid) <
6267 0 ||
6268 set_network(intf, 0, "bssid", bssid) < 0)
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006269 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006270 }
6271
6272 ctrl = open_wpa_mon(intf);
6273 if (ctrl == NULL) {
6274 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
6275 "wpa_supplicant monitor connection");
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006276 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006277 }
6278
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006279 if (get_wpa_status(get_station_ifname(dut), "wpa_state", result,
Sunil Duttd30ce092018-01-11 23:56:29 +05306280 sizeof(result)) < 0 ||
6281 strncmp(result, "COMPLETED", 9) != 0) {
6282 sigma_dut_print(dut, DUT_MSG_DEBUG,
6283 "sta_reassoc: Not connected");
6284 fastreassoc = 0;
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006285 } else if (dut->sta_ft_ds) {
6286 sigma_dut_print(dut, DUT_MSG_DEBUG,
6287 "sta_reassoc: Use FT-over-DS");
6288 ft_ds = 1;
Sunil Duttd30ce092018-01-11 23:56:29 +05306289 }
6290
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05306291 if (dut->rsne_override) {
6292#ifdef NL80211_SUPPORT
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006293 if (get_driver_type(dut) == DRIVER_WCN &&
6294 dut->config_rsnie == 0) {
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05306295 sta_config_rsnie(dut, 1);
6296 dut->config_rsnie = 1;
6297 }
6298#endif /* NL80211_SUPPORT */
6299 snprintf(buf, sizeof(buf), "TEST_ASSOC_IE %s",
6300 dut->rsne_override);
6301 if (wpa_command(intf, buf) < 0) {
6302 send_resp(dut, conn, SIGMA_ERROR,
6303 "ErrorCode,Failed to set DEV_CONFIGURE_IE RSNE override");
6304 return 0;
6305 }
6306 }
6307
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006308 if (ft_ds) {
6309 if (chan) {
6310 unsigned int freq;
6311
6312 freq = channel_to_freq(dut, chan);
6313 if (!freq) {
6314 sigma_dut_print(dut, DUT_MSG_ERROR,
6315 "Invalid channel number provided: %d",
6316 chan);
6317 send_resp(dut, conn, SIGMA_INVALID,
6318 "ErrorCode,Invalid channel number");
6319 goto close_mon_conn;
6320 }
6321 res = snprintf(buf, sizeof(buf),
6322 "SCAN TYPE=ONLY freq=%d", freq);
6323 } else {
6324 res = snprintf(buf, sizeof(buf), "SCAN TYPE=ONLY");
6325 }
6326 if (res < 0 || res >= (int) sizeof(buf)) {
6327 send_resp(dut, conn, SIGMA_ERROR,
6328 "ErrorCode,snprintf failed");
6329 goto close_mon_conn;
6330 }
6331 if (wpa_command(intf, buf) < 0) {
6332 sigma_dut_print(dut, DUT_MSG_INFO,
6333 "Failed to start scan");
6334 send_resp(dut, conn, SIGMA_ERROR,
6335 "ErrorCode,scan failed");
6336 goto close_mon_conn;
6337 }
6338
6339 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
6340 buf, sizeof(buf));
6341 if (res < 0) {
6342 sigma_dut_print(dut, DUT_MSG_INFO,
6343 "Scan did not complete");
6344 send_resp(dut, conn, SIGMA_ERROR,
6345 "ErrorCode,scan did not complete");
6346 goto close_mon_conn;
6347 }
6348
6349 res = snprintf(buf, sizeof(buf), "FT_DS %s", bssid);
6350 if (res > 0 && res < (int) sizeof(buf))
6351 res = wpa_command(intf, buf);
6352
6353 if (res < 0 || res >= (int) sizeof(buf)) {
6354 send_resp(dut, conn, SIGMA_ERROR,
6355 "errorCode,FT_DS command failed");
6356 status = STATUS_SENT_ERROR;
6357 goto close_mon_conn;
6358 }
6359 } else if (wifi_chip_type == DRIVER_WCN && fastreassoc) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006360#ifdef ANDROID
Ashwini Patil4c8158f2017-05-25 12:49:21 +05306361 if (chan) {
6362 unsigned int freq;
6363
Alexei Avshalom Lazar093569f2018-11-13 14:08:17 +02006364 freq = channel_to_freq(dut, chan);
Ashwini Patil4c8158f2017-05-25 12:49:21 +05306365 if (!freq) {
6366 sigma_dut_print(dut, DUT_MSG_ERROR,
6367 "Invalid channel number provided: %d",
6368 chan);
6369 send_resp(dut, conn, SIGMA_INVALID,
6370 "ErrorCode,Invalid channel number");
6371 goto close_mon_conn;
6372 }
6373 res = snprintf(buf, sizeof(buf),
6374 "SCAN TYPE=ONLY freq=%d", freq);
6375 } else {
6376 res = snprintf(buf, sizeof(buf), "SCAN TYPE=ONLY");
6377 }
6378 if (res < 0 || res >= (int) sizeof(buf)) {
6379 send_resp(dut, conn, SIGMA_ERROR,
6380 "ErrorCode,snprintf failed");
6381 goto close_mon_conn;
6382 }
6383 if (wpa_command(intf, buf) < 0) {
6384 sigma_dut_print(dut, DUT_MSG_INFO,
6385 "Failed to start scan");
6386 send_resp(dut, conn, SIGMA_ERROR,
6387 "ErrorCode,scan failed");
6388 goto close_mon_conn;
6389 }
6390
6391 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
6392 buf, sizeof(buf));
6393 if (res < 0) {
6394 sigma_dut_print(dut, DUT_MSG_INFO,
6395 "Scan did not complete");
6396 send_resp(dut, conn, SIGMA_ERROR,
6397 "ErrorCode,scan did not complete");
6398 goto close_mon_conn;
6399 }
6400
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006401 if (set_network(intf, dut->infra_network_id, "bssid", "any")
6402 < 0) {
6403 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
6404 "bssid to any during FASTREASSOC");
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006405 status = ERROR_SEND_STATUS;
Ashwini Patil467efef2017-05-25 12:18:27 +05306406 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006407 }
6408 res = snprintf(buf, sizeof(buf), "DRIVER FASTREASSOC %s %d",
6409 bssid, chan);
6410 if (res > 0 && res < (int) sizeof(buf))
6411 res = wpa_command(intf, buf);
6412
6413 if (res < 0 || res >= (int) sizeof(buf)) {
6414 send_resp(dut, conn, SIGMA_ERROR,
6415 "errorCode,Failed to run DRIVER FASTREASSOC");
Ashwini Patil467efef2017-05-25 12:18:27 +05306416 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006417 }
6418#else /* ANDROID */
6419 sigma_dut_print(dut, DUT_MSG_DEBUG,
6420 "Reassoc using iwpriv - skip chan=%d info",
6421 chan);
6422 snprintf(buf, sizeof(buf), "iwpriv %s reassoc", intf);
6423 if (system(buf) != 0) {
6424 sigma_dut_print(dut, DUT_MSG_ERROR, "%s failed", buf);
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006425 status = ERROR_SEND_STATUS;
Ashwini Patil467efef2017-05-25 12:18:27 +05306426 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006427 }
6428#endif /* ANDROID */
6429 sigma_dut_print(dut, DUT_MSG_INFO,
6430 "sta_reassoc: Run %s successful", buf);
6431 } else if (wpa_command(intf, "REASSOCIATE")) {
6432 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
6433 "request reassociation");
Ashwini Patil467efef2017-05-25 12:18:27 +05306434 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006435 }
6436
6437 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
6438 buf, sizeof(buf));
Ashwini Patil467efef2017-05-25 12:18:27 +05306439 if (res < 0) {
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006440 send_resp(dut, conn, SIGMA_ERROR,
6441 "errorCode,Connection did not complete");
6442 status = STATUS_SENT_ERROR;
Ashwini Patil467efef2017-05-25 12:18:27 +05306443 goto close_mon_conn;
6444 }
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006445 status = SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006446
Ashwini Patil467efef2017-05-25 12:18:27 +05306447close_mon_conn:
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006448 wpa_ctrl_detach(ctrl);
6449 wpa_ctrl_close(ctrl);
Ashwini Patil467efef2017-05-25 12:18:27 +05306450 return status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006451}
6452
6453
6454static void hs2_clear_credentials(const char *intf)
6455{
6456 wpa_command(intf, "REMOVE_CRED all");
6457}
6458
6459
Lior Davidcc88b562017-01-03 18:52:09 +02006460#ifdef __linux__
6461static int wil6210_get_aid(struct sigma_dut *dut, const char *bssid,
6462 unsigned int *aid)
6463{
Lior David0fe101e2017-03-09 16:09:50 +02006464 const char *pattern = "AID[ \t]+([0-9]+)";
Lior Davidcc88b562017-01-03 18:52:09 +02006465
Lior David0fe101e2017-03-09 16:09:50 +02006466 return wil6210_get_sta_info_field(dut, bssid, pattern, aid);
Lior Davidcc88b562017-01-03 18:52:09 +02006467}
6468#endif /* __linux__ */
6469
6470
6471static int sta_get_aid_60g(struct sigma_dut *dut, const char *bssid,
6472 unsigned int *aid)
6473{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006474 switch (get_driver_type(dut)) {
Lior Davidcc88b562017-01-03 18:52:09 +02006475#ifdef __linux__
6476 case DRIVER_WIL6210:
6477 return wil6210_get_aid(dut, bssid, aid);
6478#endif /* __linux__ */
6479 default:
6480 sigma_dut_print(dut, DUT_MSG_ERROR, "get AID not supported");
6481 return -1;
6482 }
6483}
6484
6485
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006486static int sta_get_parameter_60g(struct sigma_dut *dut, struct sigma_conn *conn,
6487 struct sigma_cmd *cmd)
6488{
6489 char buf[MAX_CMD_LEN];
6490 char bss_list[MAX_CMD_LEN];
6491 const char *parameter = get_param(cmd, "Parameter");
6492
6493 if (parameter == NULL)
6494 return -1;
6495
Lior Davidcc88b562017-01-03 18:52:09 +02006496 if (strcasecmp(parameter, "AID") == 0) {
6497 unsigned int aid = 0;
6498 char bssid[20];
6499
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006500 if (get_wpa_status(get_station_ifname(dut), "bssid",
Lior Davidcc88b562017-01-03 18:52:09 +02006501 bssid, sizeof(bssid)) < 0) {
6502 sigma_dut_print(dut, DUT_MSG_ERROR,
6503 "could not get bssid");
6504 return -2;
6505 }
6506
6507 if (sta_get_aid_60g(dut, bssid, &aid))
6508 return -2;
6509
6510 snprintf(buf, sizeof(buf), "aid,%d", aid);
6511 sigma_dut_print(dut, DUT_MSG_INFO, "%s", buf);
6512 send_resp(dut, conn, SIGMA_COMPLETE, buf);
6513 return 0;
6514 }
6515
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006516 if (strcasecmp(parameter, "DiscoveredDevList") == 0) {
6517 char *bss_line;
6518 char *bss_id = NULL;
6519 const char *ifname = get_param(cmd, "Interface");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05306520 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006521
6522 if (ifname == NULL) {
6523 sigma_dut_print(dut, DUT_MSG_INFO,
6524 "For get DiscoveredDevList need Interface name.");
6525 return -1;
6526 }
6527
6528 /*
6529 * Use "BSS RANGE=ALL MASK=0x2" which provides a list
6530 * of BSSIDs in "bssid=<BSSID>\n"
6531 */
6532 if (wpa_command_resp(ifname, "BSS RANGE=ALL MASK=0x2",
6533 bss_list,
6534 sizeof(bss_list)) < 0) {
6535 sigma_dut_print(dut, DUT_MSG_ERROR,
6536 "Failed to get bss list");
6537 return -1;
6538 }
6539
6540 sigma_dut_print(dut, DUT_MSG_DEBUG,
6541 "bss list for ifname:%s is:%s",
6542 ifname, bss_list);
6543
6544 snprintf(buf, sizeof(buf), "DeviceList");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05306545 bss_line = strtok_r(bss_list, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006546 while (bss_line) {
6547 if (sscanf(bss_line, "bssid=%ms", &bss_id) > 0 &&
6548 bss_id) {
6549 int len;
6550
6551 len = snprintf(buf + strlen(buf),
6552 sizeof(buf) - strlen(buf),
6553 ",%s", bss_id);
6554 free(bss_id);
6555 bss_id = NULL;
6556 if (len < 0) {
6557 sigma_dut_print(dut,
6558 DUT_MSG_ERROR,
6559 "Failed to read BSSID");
6560 send_resp(dut, conn, SIGMA_ERROR,
6561 "ErrorCode,Failed to read BSS ID");
6562 return 0;
6563 }
6564
6565 if ((size_t) len >= sizeof(buf) - strlen(buf)) {
6566 sigma_dut_print(dut,
6567 DUT_MSG_ERROR,
6568 "Response buf too small for list");
6569 send_resp(dut, conn,
6570 SIGMA_ERROR,
6571 "ErrorCode,Response buf too small for list");
6572 return 0;
6573 }
6574 }
6575
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05306576 bss_line = strtok_r(NULL, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006577 }
6578
6579 sigma_dut_print(dut, DUT_MSG_INFO, "DiscoveredDevList is %s",
6580 buf);
6581 send_resp(dut, conn, SIGMA_COMPLETE, buf);
6582 return 0;
6583 }
6584
6585 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
6586 return 0;
6587}
6588
6589
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07006590static int sta_get_parameter_he(struct sigma_dut *dut, struct sigma_conn *conn,
6591 struct sigma_cmd *cmd)
6592{
6593 char buf[MAX_CMD_LEN];
6594 const char *parameter = get_param(cmd, "Parameter");
6595
6596 if (!parameter)
6597 return -1;
6598
6599 if (strcasecmp(parameter, "RSSI") == 0) {
6600 char rssi[10];
6601
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006602 if (get_wpa_signal_poll(dut, get_station_ifname(dut), "RSSI",
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07006603 rssi, sizeof(rssi)) < 0) {
6604 sigma_dut_print(dut, DUT_MSG_ERROR,
6605 "Could not get RSSI");
6606 return -2;
6607 }
6608
6609 snprintf(buf, sizeof(buf), "rssi,%s", rssi);
6610 sigma_dut_print(dut, DUT_MSG_INFO, "RSSI %s", buf);
6611 send_resp(dut, conn, SIGMA_COMPLETE, buf);
6612 return 0;
6613 }
6614
6615 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
6616 return 0;
6617}
6618
6619
Jouni Malinenf7222712019-06-13 01:50:21 +03006620static enum sigma_cmd_result cmd_sta_get_parameter(struct sigma_dut *dut,
6621 struct sigma_conn *conn,
6622 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006623{
6624 const char *program = get_param(cmd, "Program");
6625
6626 if (program == NULL)
6627 return -1;
6628
6629 if (strcasecmp(program, "P2PNFC") == 0)
6630 return p2p_cmd_sta_get_parameter(dut, conn, cmd);
6631
6632 if (strcasecmp(program, "60ghz") == 0)
6633 return sta_get_parameter_60g(dut, conn, cmd);
6634
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07006635 if (strcasecmp(program, "he") == 0)
6636 return sta_get_parameter_he(dut, conn, cmd);
6637
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006638#ifdef ANDROID_NAN
6639 if (strcasecmp(program, "NAN") == 0)
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07006640 return nan_cmd_sta_get_parameter(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006641#endif /* ANDROID_NAN */
6642
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07006643#ifdef MIRACAST
6644 if (strcasecmp(program, "WFD") == 0 ||
6645 strcasecmp(program, "DisplayR2") == 0)
6646 return miracast_cmd_sta_get_parameter(dut, conn, cmd);
6647#endif /* MIRACAST */
6648
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006649 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
6650 return 0;
6651}
6652
6653
6654static void sta_reset_default_ath(struct sigma_dut *dut, const char *intf,
6655 const char *type)
6656{
6657 char buf[100];
6658
6659 if (dut->program == PROGRAM_VHT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006660 run_iwpriv(dut, intf, "chwidth 2");
6661 run_iwpriv(dut, intf, "mode 11ACVHT80");
6662 run_iwpriv(dut, intf, "vhtmcs -1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006663 }
6664
6665 if (dut->program == PROGRAM_HT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006666 run_iwpriv(dut, intf, "chwidth 0");
6667 run_iwpriv(dut, intf, "mode 11naht40");
6668 run_iwpriv(dut, intf, "set11NRates 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006669 }
6670
6671 if (dut->program == PROGRAM_VHT || dut->program == PROGRAM_HT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006672 run_iwpriv(dut, intf, "powersave 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006673
6674 /* Reset CTS width */
6675 snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 54 0",
6676 intf);
6677 if (system(buf) != 0) {
6678 sigma_dut_print(dut, DUT_MSG_ERROR,
6679 "wifitool %s beeliner_fw_test 54 0 failed",
6680 intf);
6681 }
6682
6683 /* Enable Dynamic Bandwidth signalling by default */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006684 run_iwpriv(dut, intf, "cwmenable 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006685
6686 snprintf(buf, sizeof(buf), "iwconfig %s rts 2347", intf);
6687 if (system(buf) != 0) {
6688 sigma_dut_print(dut, DUT_MSG_ERROR,
6689 "iwpriv rts failed");
6690 }
6691 }
6692
6693 if (type && strcasecmp(type, "Testbed") == 0) {
6694 dut->testbed_flag_txsp = 1;
6695 dut->testbed_flag_rxsp = 1;
6696 /* STA has to set spatial stream to 2 per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006697 run_iwpriv(dut, intf, "vht_mcsmap 0xfff0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006698
6699 /* Disable LDPC per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006700 run_iwpriv(dut, intf, "ldpc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006701
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006702 run_iwpriv(dut, intf, "amsdu 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006703
6704 /* TODO: Disable STBC 2x1 transmit and receive */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006705 run_iwpriv(dut, intf, "tx_stbc 0");
6706 run_iwpriv(dut, intf, "rx_stbc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006707
6708 /* STA has to disable Short GI per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006709 run_iwpriv(dut, intf, "shortgi 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006710 }
6711
6712 if (type && strcasecmp(type, "DUT") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006713 run_iwpriv(dut, intf, "nss 3");
Arif Hussainac6c5112018-05-25 17:34:00 -07006714 dut->sta_nss = 3;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006715
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006716 run_iwpriv(dut, intf, "shortgi 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006717 }
6718}
6719
6720
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08006721#ifdef NL80211_SUPPORT
6722static int sta_set_he_mcs(struct sigma_dut *dut, const char *intf,
6723 enum he_mcs_config mcs)
6724{
6725 struct nl_msg *msg;
6726 int ret = 0;
6727 struct nlattr *params;
6728 int ifindex;
6729
6730 ifindex = if_nametoindex(intf);
6731 if (ifindex == 0) {
6732 sigma_dut_print(dut, DUT_MSG_ERROR,
6733 "%s: Index for interface %s failed",
6734 __func__, intf);
6735 return -1;
6736 }
6737
6738 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6739 NL80211_CMD_VENDOR)) ||
6740 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6741 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6742 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6743 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6744 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6745 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MCS,
6746 mcs)) {
6747 sigma_dut_print(dut, DUT_MSG_ERROR,
6748 "%s: err in adding vendor_cmd and vendor_data",
6749 __func__);
6750 nlmsg_free(msg);
6751 return -1;
6752 }
6753 nla_nest_end(msg, params);
6754
6755 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6756 if (ret) {
6757 sigma_dut_print(dut, DUT_MSG_ERROR,
6758 "%s: err in send_and_recv_msgs, ret=%d",
6759 __func__, ret);
6760 }
6761 return ret;
6762}
6763#endif /* NL80211_SUPPORT */
6764
6765
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07006766static int sta_set_action_tx_in_he_tb_ppdu(struct sigma_dut *dut,
6767 const char *intf, int enable)
6768{
6769#ifdef NL80211_SUPPORT
6770 struct nl_msg *msg;
6771 int ret = 0;
6772 struct nlattr *params;
6773 int ifindex;
6774
6775 ifindex = if_nametoindex(intf);
6776 if (ifindex == 0) {
6777 sigma_dut_print(dut, DUT_MSG_ERROR,
6778 "%s: Index for interface %s failed",
6779 __func__, intf);
6780 return -1;
6781 }
6782
6783 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6784 NL80211_CMD_VENDOR)) ||
6785 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6786 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6787 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6788 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6789 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6790 nla_put_u8(msg,
6791 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_ACTION_TX_TB_PPDU,
6792 enable)) {
6793 sigma_dut_print(dut, DUT_MSG_ERROR,
6794 "%s: err in adding vendor_cmd and vendor_data",
6795 __func__);
6796 nlmsg_free(msg);
6797 return -1;
6798 }
6799 nla_nest_end(msg, params);
6800
6801 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6802 if (ret) {
6803 sigma_dut_print(dut, DUT_MSG_ERROR,
6804 "%s: err in send_and_recv_msgs, ret=%d",
6805 __func__, ret);
6806 }
6807 return ret;
6808#else /* NL80211_SUPPORT */
6809 sigma_dut_print(dut, DUT_MSG_ERROR,
6810 "HE action Tx TB PPDU cannot be set without NL80211_SUPPORT defined");
6811 return -1;
6812#endif /* NL80211_SUPPORT */
6813}
6814
6815
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08006816static int sta_set_heconfig_and_wep_tkip(struct sigma_dut *dut,
6817 const char *intf, int enable)
6818{
6819#ifdef NL80211_SUPPORT
6820 struct nl_msg *msg;
6821 int ret = 0;
6822 struct nlattr *params;
6823 int ifindex;
6824
6825 ifindex = if_nametoindex(intf);
6826 if (ifindex == 0) {
6827 sigma_dut_print(dut, DUT_MSG_ERROR,
6828 "%s: Index for interface %s failed",
6829 __func__, intf);
6830 return -1;
6831 }
6832
6833 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6834 NL80211_CMD_VENDOR)) ||
6835 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6836 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6837 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6838 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6839 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6840 nla_put_u8(msg,
6841 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WEP_TKIP_IN_HE,
6842 enable)) {
6843 sigma_dut_print(dut, DUT_MSG_ERROR,
6844 "%s: err in adding vendor_cmd and vendor_data",
6845 __func__);
6846 nlmsg_free(msg);
6847 return -1;
6848 }
6849 nla_nest_end(msg, params);
6850
6851 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6852 if (ret) {
6853 sigma_dut_print(dut, DUT_MSG_ERROR,
6854 "%s: err in send_and_recv_msgs, ret=%d",
6855 __func__, ret);
6856 }
6857 return ret;
6858#else /* NL80211_SUPPORT */
6859 sigma_dut_print(dut, DUT_MSG_ERROR,
6860 "HE config enablement cannot be changed without NL80211_SUPPORT defined");
6861 return -1;
6862#endif /* NL80211_SUPPORT */
6863}
6864
6865
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08006866#ifdef NL80211_SUPPORT
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08006867
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08006868static int sta_set_he_testbed_def(struct sigma_dut *dut,
6869 const char *intf, int cfg)
6870{
6871 struct nl_msg *msg;
6872 int ret = 0;
6873 struct nlattr *params;
6874 int ifindex;
6875
6876 ifindex = if_nametoindex(intf);
6877 if (ifindex == 0) {
6878 sigma_dut_print(dut, DUT_MSG_ERROR,
6879 "%s: Index for interface %s failed",
6880 __func__, intf);
6881 return -1;
6882 }
6883
6884 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6885 NL80211_CMD_VENDOR)) ||
6886 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6887 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6888 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6889 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6890 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6891 nla_put_u8(msg,
6892 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_SET_HE_TESTBED_DEFAULTS,
6893 cfg)) {
6894 sigma_dut_print(dut, DUT_MSG_ERROR,
6895 "%s: err in adding vendor_cmd and vendor_data",
6896 __func__);
6897 nlmsg_free(msg);
6898 return -1;
6899 }
6900 nla_nest_end(msg, params);
6901
6902 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6903 if (ret) {
6904 sigma_dut_print(dut, DUT_MSG_ERROR,
6905 "%s: err in send_and_recv_msgs, ret=%d",
6906 __func__, ret);
6907 }
6908 return ret;
6909}
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08006910
6911
6912static int sta_set_2g_vht_supp(struct sigma_dut *dut, const char *intf, int cfg)
6913{
6914 struct nl_msg *msg;
6915 int ret = 0;
6916 struct nlattr *params;
6917 int ifindex;
6918
6919 ifindex = if_nametoindex(intf);
6920 if (ifindex == 0) {
6921 sigma_dut_print(dut, DUT_MSG_ERROR,
6922 "%s: Index for interface %s failed",
6923 __func__, intf);
6924 return -1;
6925 }
6926
6927 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6928 NL80211_CMD_VENDOR)) ||
6929 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6930 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6931 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6932 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6933 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6934 nla_put_u8(msg,
6935 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_2G_VHT,
6936 cfg)) {
6937 sigma_dut_print(dut, DUT_MSG_ERROR,
6938 "%s: err in adding vendor_cmd and vendor_data",
6939 __func__);
6940 nlmsg_free(msg);
6941 return -1;
6942 }
6943 nla_nest_end(msg, params);
6944
6945 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6946 if (ret) {
6947 sigma_dut_print(dut, DUT_MSG_ERROR,
6948 "%s: err in send_and_recv_msgs, ret=%d",
6949 __func__, ret);
6950 }
6951 return ret;
6952}
6953
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08006954#endif /* NL80211_SUPPORT */
6955
6956
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08006957static int sta_set_addba_buf_size(struct sigma_dut *dut,
6958 const char *intf, int bufsize)
6959{
6960#ifdef NL80211_SUPPORT
6961 struct nl_msg *msg;
6962 int ret = 0;
6963 struct nlattr *params;
6964 int ifindex;
6965
6966 ifindex = if_nametoindex(intf);
6967 if (ifindex == 0) {
6968 sigma_dut_print(dut, DUT_MSG_ERROR,
6969 "%s: Index for interface %s failed",
6970 __func__, intf);
6971 return -1;
6972 }
6973
6974 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6975 NL80211_CMD_VENDOR)) ||
6976 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6977 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6978 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6979 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6980 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
Kiran Kumar Lokere26e27582018-08-01 16:18:34 -07006981 nla_put_u16(msg,
6982 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE,
6983 bufsize)) {
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08006984 sigma_dut_print(dut, DUT_MSG_ERROR,
6985 "%s: err in adding vendor_cmd and vendor_data",
6986 __func__);
6987 nlmsg_free(msg);
6988 return -1;
6989 }
6990 nla_nest_end(msg, params);
6991
6992 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6993 if (ret) {
6994 sigma_dut_print(dut, DUT_MSG_ERROR,
6995 "%s: err in send_and_recv_msgs, ret=%d",
6996 __func__, ret);
6997 }
6998 return ret;
6999#else /* NL80211_SUPPORT */
7000 sigma_dut_print(dut, DUT_MSG_ERROR,
7001 "AddBA bufsize cannot be changed without NL80211_SUPPORT defined");
7002 return -1;
7003#endif /* NL80211_SUPPORT */
7004}
7005
7006
Arif Hussain8d5b27b2018-05-14 14:31:03 -07007007static int sta_set_tx_beamformee(struct sigma_dut *dut, const char *intf,
7008 int enable)
7009{
7010#ifdef NL80211_SUPPORT
7011 struct nl_msg *msg;
7012 int ret = 0;
7013 struct nlattr *params;
7014 int ifindex;
7015
7016 ifindex = if_nametoindex(intf);
7017 if (ifindex == 0) {
7018 sigma_dut_print(dut, DUT_MSG_ERROR,
7019 "%s: Index for interface %s failed",
7020 __func__, intf);
7021 return -1;
7022 }
7023
7024 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7025 NL80211_CMD_VENDOR)) ||
7026 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7027 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7028 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7029 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7030 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7031 nla_put_u8(msg,
7032 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_TX_BEAMFORMEE,
7033 enable)) {
7034 sigma_dut_print(dut, DUT_MSG_ERROR,
7035 "%s: err in adding vendor_cmd and vendor_data",
7036 __func__);
7037 nlmsg_free(msg);
7038 return -1;
7039 }
7040 nla_nest_end(msg, params);
7041
7042 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7043 if (ret) {
7044 sigma_dut_print(dut, DUT_MSG_ERROR,
7045 "%s: err in send_and_recv_msgs, ret=%d",
7046 __func__, ret);
7047 }
7048 return ret;
7049#else /* NL80211_SUPPORT */
7050 sigma_dut_print(dut, DUT_MSG_ERROR,
7051 "tx beamformee cannot be changed without NL80211_SUPPORT defined");
7052 return -1;
7053#endif /* NL80211_SUPPORT */
7054}
7055
7056
Arif Hussain9765f7d2018-07-03 08:28:26 -07007057static int sta_set_beamformee_sts(struct sigma_dut *dut, const char *intf,
7058 int val)
7059{
7060#ifdef NL80211_SUPPORT
7061 struct nl_msg *msg;
7062 int ret = 0;
7063 struct nlattr *params;
7064 int ifindex;
7065
7066 ifindex = if_nametoindex(intf);
7067 if (ifindex == 0) {
7068 sigma_dut_print(dut, DUT_MSG_ERROR,
7069 "%s: Index for interface %s failed, val:%d",
7070 __func__, intf, val);
7071 return -1;
7072 }
7073
7074 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7075 NL80211_CMD_VENDOR)) ||
7076 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7077 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7078 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7079 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7080 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7081 nla_put_u8(msg,
7082 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_BEAMFORMEE_NSTS,
7083 val)) {
7084 sigma_dut_print(dut, DUT_MSG_ERROR,
7085 "%s: err in adding vendor_cmd and vendor_data, val: %d",
7086 __func__, val);
7087 nlmsg_free(msg);
7088 return -1;
7089 }
7090 nla_nest_end(msg, params);
7091
7092 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7093 if (ret) {
7094 sigma_dut_print(dut, DUT_MSG_ERROR,
7095 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
7096 __func__, ret, val);
7097 }
7098 return ret;
7099#else /* NL80211_SUPPORT */
7100 sigma_dut_print(dut, DUT_MSG_ERROR,
7101 "beamformee sts cannot be changed without NL80211_SUPPORT defined");
7102 return -1;
7103#endif /* NL80211_SUPPORT */
7104}
7105
7106
Arif Hussain68d23f52018-07-11 13:39:08 -07007107#ifdef NL80211_SUPPORT
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07007108static int sta_set_mac_padding_duration(struct sigma_dut *dut, const char *intf,
7109 enum qca_wlan_he_mac_padding_dur val)
7110{
Arif Hussain68d23f52018-07-11 13:39:08 -07007111 struct nl_msg *msg;
7112 int ret = 0;
7113 struct nlattr *params;
7114 int ifindex;
7115
7116 ifindex = if_nametoindex(intf);
7117 if (ifindex == 0) {
7118 sigma_dut_print(dut, DUT_MSG_ERROR,
7119 "%s: Index for interface %s failed, val:%d",
7120 __func__, intf, val);
7121 return -1;
7122 }
7123
7124 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7125 NL80211_CMD_VENDOR)) ||
7126 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7127 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7128 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7129 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7130 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7131 nla_put_u8(msg,
7132 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MAC_PADDING_DUR,
7133 val)) {
7134 sigma_dut_print(dut, DUT_MSG_ERROR,
7135 "%s: err in adding vendor_cmd and vendor_data, val: %d",
7136 __func__, val);
7137 nlmsg_free(msg);
7138 return -1;
7139 }
7140 nla_nest_end(msg, params);
7141
7142 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7143 if (ret) {
7144 sigma_dut_print(dut, DUT_MSG_ERROR,
7145 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
7146 __func__, ret, val);
7147 }
7148 return ret;
Arif Hussain68d23f52018-07-11 13:39:08 -07007149}
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07007150#endif /* NL80211_SUPPORT */
Arif Hussain68d23f52018-07-11 13:39:08 -07007151
7152
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07007153static int sta_set_tx_su_ppdu_cfg(struct sigma_dut *dut, const char *intf,
7154 int val)
7155{
7156#ifdef NL80211_SUPPORT
7157 struct nl_msg *msg;
7158 int ret = 0;
7159 struct nlattr *params;
7160 int ifindex;
7161
7162 ifindex = if_nametoindex(intf);
7163 if (ifindex == 0) {
7164 sigma_dut_print(dut, DUT_MSG_ERROR,
7165 "%s: Index for interface %s failed, val:%d",
7166 __func__, intf, val);
7167 return -1;
7168 }
7169
7170 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7171 NL80211_CMD_VENDOR)) ||
7172 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7173 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7174 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7175 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7176 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7177 nla_put_u8(msg,
7178 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_SUPPDU,
7179 val)) {
7180 sigma_dut_print(dut, DUT_MSG_ERROR,
7181 "%s: err in adding vendor_cmd and vendor_data, val: %d",
7182 __func__, val);
7183 nlmsg_free(msg);
7184 return -1;
7185 }
7186 nla_nest_end(msg, params);
7187
7188 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7189 if (ret) {
7190 sigma_dut_print(dut, DUT_MSG_ERROR,
7191 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
7192 __func__, ret, val);
7193 }
7194 return ret;
7195#else /* NL80211_SUPPORT */
7196 sigma_dut_print(dut, DUT_MSG_ERROR,
7197 "Tx SU PPDU cannot be set without NL80211_SUPPORT defined");
7198 return -1;
7199#endif /* NL80211_SUPPORT */
7200}
7201
7202
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07007203#ifdef NL80211_SUPPORT
7204static int sta_set_he_om_ctrl_reset(struct sigma_dut *dut, const char *intf)
7205{
7206 struct nl_msg *msg;
7207 int ret = 0;
7208 struct nlattr *params;
7209 int ifindex;
7210
7211 ifindex = if_nametoindex(intf);
7212 if (ifindex == 0) {
7213 sigma_dut_print(dut, DUT_MSG_ERROR,
7214 "%s: Index for interface %s failed",
7215 __func__, intf);
7216 return -1;
7217 }
7218
7219 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7220 NL80211_CMD_VENDOR)) ||
7221 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7222 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7223 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7224 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7225 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7226 nla_put_flag(msg,
7227 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_CLEAR_HE_OM_CTRL_CONFIG)) {
7228 sigma_dut_print(dut, DUT_MSG_ERROR,
7229 "%s: err in adding vendor_cmd and vendor_data",
7230 __func__);
7231 nlmsg_free(msg);
7232 return -1;
7233 }
7234 nla_nest_end(msg, params);
7235
7236 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7237 if (ret) {
7238 sigma_dut_print(dut, DUT_MSG_ERROR,
7239 "%s: err in send_and_recv_msgs, ret=%d",
7240 __func__, ret);
7241 }
7242 return ret;
7243}
7244#endif /* NL80211_SUPPORT */
7245
7246
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07007247static int sta_set_mu_edca_override(struct sigma_dut *dut, const char *intf,
7248 int val)
7249{
7250#ifdef NL80211_SUPPORT
7251 struct nl_msg *msg;
7252 int ret = 0;
7253 struct nlattr *params;
7254 int ifindex;
7255
7256 ifindex = if_nametoindex(intf);
7257 if (ifindex == 0) {
7258 sigma_dut_print(dut, DUT_MSG_ERROR,
7259 "%s: Index for interface %s failed, val:%d",
7260 __func__, intf, val);
7261 return -1;
7262 }
7263
7264 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7265 NL80211_CMD_VENDOR)) ||
7266 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7267 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7268 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7269 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7270 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7271 nla_put_u8(msg,
7272 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_OVERRIDE_MU_EDCA,
7273 val)) {
7274 sigma_dut_print(dut, DUT_MSG_ERROR,
7275 "%s: err in adding vendor_cmd and vendor_data, val: %d",
7276 __func__, val);
7277 nlmsg_free(msg);
7278 return -1;
7279 }
7280 nla_nest_end(msg, params);
7281
7282 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7283 if (ret) {
7284 sigma_dut_print(dut, DUT_MSG_ERROR,
7285 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
7286 __func__, ret, val);
7287 }
7288 return ret;
7289#else /* NL80211_SUPPORT */
7290 sigma_dut_print(dut, DUT_MSG_ERROR,
7291 "MU EDCA override cannot be changed without NL80211_SUPPORT defined");
7292 return -1;
7293#endif /* NL80211_SUPPORT */
7294}
7295
7296
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07007297static int sta_set_om_ctrl_supp(struct sigma_dut *dut, const char *intf,
7298 int val)
7299{
7300#ifdef NL80211_SUPPORT
7301 struct nl_msg *msg;
7302 int ret = 0;
7303 struct nlattr *params;
7304 int ifindex;
7305
7306 ifindex = if_nametoindex(intf);
7307 if (ifindex == 0) {
7308 sigma_dut_print(dut, DUT_MSG_ERROR,
7309 "%s: Index for interface %s failed, val:%d",
7310 __func__, intf, val);
7311 return -1;
7312 }
7313
7314 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7315 NL80211_CMD_VENDOR)) ||
7316 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7317 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7318 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7319 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7320 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7321 nla_put_u8(msg,
7322 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OM_CTRL_SUPP,
7323 val)) {
7324 sigma_dut_print(dut, DUT_MSG_ERROR,
7325 "%s: err in adding vendor_cmd and vendor_data, val: %d",
7326 __func__, val);
7327 nlmsg_free(msg);
7328 return -1;
7329 }
7330 nla_nest_end(msg, params);
7331
7332 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7333 if (ret) {
7334 sigma_dut_print(dut, DUT_MSG_ERROR,
7335 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
7336 __func__, ret, val);
7337 }
7338 return ret;
7339#else /* NL80211_SUPPORT */
7340 sigma_dut_print(dut, DUT_MSG_ERROR,
7341 "HE OM ctrl cannot be changed without NL80211_SUPPORT defined");
7342 return -1;
7343#endif /* NL80211_SUPPORT */
7344}
7345
7346
Arif Hussain480d5f42019-03-12 14:40:42 -07007347static int sta_set_twt_req_support(struct sigma_dut *dut, const char *intf,
7348 int val)
7349{
7350#ifdef NL80211_SUPPORT
7351 struct nl_msg *msg;
7352 int ret;
7353 struct nlattr *params;
7354 int ifindex;
7355
7356 ifindex = if_nametoindex(intf);
7357 if (ifindex == 0) {
7358 sigma_dut_print(dut, DUT_MSG_ERROR,
7359 "%s: Index for interface %s failed, val:%d",
7360 __func__, intf, val);
7361 return -1;
7362 }
7363
7364 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7365 NL80211_CMD_VENDOR)) ||
7366 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7367 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7368 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7369 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7370 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7371 nla_put_u8(msg,
7372 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TWT_REQ_SUPPORT,
7373 val)) {
7374 sigma_dut_print(dut, DUT_MSG_ERROR,
7375 "%s: err in adding vendor_cmd and vendor_data, val: %d",
7376 __func__, val);
7377 nlmsg_free(msg);
7378 return -1;
7379 }
7380 nla_nest_end(msg, params);
7381
7382 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7383 if (ret) {
7384 sigma_dut_print(dut, DUT_MSG_ERROR,
7385 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
7386 __func__, ret, val);
7387 }
7388 return ret;
7389#else /* NL80211_SUPPORT */
7390 sigma_dut_print(dut, DUT_MSG_ERROR,
7391 "TWT Request cannot be changed without NL80211_SUPPORT defined");
7392 return -1;
7393#endif /* NL80211_SUPPORT */
7394}
7395
7396
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08007397static void sta_reset_default_wcn(struct sigma_dut *dut, const char *intf,
7398 const char *type)
7399{
7400 char buf[60];
7401
7402 if (dut->program == PROGRAM_HE) {
7403 /* resetting phymode to auto in case of HE program */
7404 snprintf(buf, sizeof(buf), "iwpriv %s setphymode 0", intf);
7405 if (system(buf) != 0) {
7406 sigma_dut_print(dut, DUT_MSG_ERROR,
7407 "iwpriv %s setphymode failed", intf);
7408 }
7409
Amarnath Hullur Subramanyam9cecb502018-04-25 13:26:30 -07007410 /* reset the rate to Auto rate */
7411 snprintf(buf, sizeof(buf), "iwpriv %s set_11ax_rate 0xff",
7412 intf);
7413 if (system(buf) != 0) {
7414 sigma_dut_print(dut, DUT_MSG_ERROR,
7415 "iwpriv %s set_11ax_rate 0xff failed",
7416 intf);
7417 }
7418
Kiran Kumar Lokere86cfe3a2018-06-01 11:55:15 -07007419 /* reset the LDPC setting */
7420 snprintf(buf, sizeof(buf), "iwpriv %s ldpc 1", intf);
7421 if (system(buf) != 0) {
7422 sigma_dut_print(dut, DUT_MSG_ERROR,
7423 "iwpriv %s ldpc 1 failed", intf);
7424 }
7425
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08007426 /* reset the power save setting */
7427 snprintf(buf, sizeof(buf), "iwpriv %s setPower 2", intf);
7428 if (system(buf) != 0) {
7429 sigma_dut_print(dut, DUT_MSG_ERROR,
7430 "iwpriv %s setPower 2 failed", intf);
7431 }
7432
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08007433 /* remove all network profiles */
7434 remove_wpa_networks(intf);
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08007435
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08007436 /* Configure ADDBA Req/Rsp buffer size to be 64 */
7437 sta_set_addba_buf_size(dut, intf, 64);
7438
Amarnath Hullur Subramanyam5f32d572018-03-02 00:02:33 -08007439#ifdef NL80211_SUPPORT
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08007440 /* Reset the device HE capabilities to its default supported
7441 * configuration. */
7442 sta_set_he_testbed_def(dut, intf, 0);
7443
Amarnath Hullur Subramanyam5f32d572018-03-02 00:02:33 -08007444 /* Disable noackpolicy for all AC */
7445 if (nlvendor_sta_set_noack(dut, intf, 0, QCA_WLAN_AC_ALL)) {
7446 sigma_dut_print(dut, DUT_MSG_ERROR,
7447 "Disable of noackpolicy for all AC failed");
7448 }
7449#endif /* NL80211_SUPPORT */
7450
Amarnath Hullur Subramanyamb1724a52018-03-07 14:31:46 -08007451 /* Enable WMM by default */
7452 if (wcn_sta_set_wmm(dut, intf, "on")) {
7453 sigma_dut_print(dut, DUT_MSG_ERROR,
7454 "Enable of WMM in sta_reset_default_wcn failed");
7455 }
7456
7457 /* Disable ADDBA_REJECT by default */
7458 if (nlvendor_sta_set_addba_reject(dut, intf, 0)) {
7459 sigma_dut_print(dut, DUT_MSG_ERROR,
7460 "Disable of addba_reject in sta_reset_default_wcn failed");
7461 }
7462
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08007463 /* Enable sending of ADDBA by default */
7464 if (nlvendor_config_send_addba(dut, intf, 1)) {
7465 sigma_dut_print(dut, DUT_MSG_ERROR,
7466 "Enable sending of ADDBA in sta_reset_default_wcn failed");
7467 }
7468
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08007469 /* Enable AMPDU by default */
7470 iwpriv_sta_set_ampdu(dut, intf, 1);
7471
Subhani Shaik8e7a3052018-04-24 14:03:00 -07007472#ifdef NL80211_SUPPORT
7473 if (sta_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_AUTO)) {
7474 sigma_dut_print(dut, DUT_MSG_ERROR,
7475 "Set LTF config to default in sta_reset_default_wcn failed");
7476 }
Arif Hussain9765f7d2018-07-03 08:28:26 -07007477
Kiran Kumar Lokerebad51122018-12-12 19:03:36 -08007478 /* set the beamformee NSTS(maximum number of
7479 * space-time streams) to default DUT config
7480 */
7481 if (sta_set_beamformee_sts(dut, intf, 7)) {
Arif Hussain9765f7d2018-07-03 08:28:26 -07007482 sigma_dut_print(dut, DUT_MSG_ERROR,
7483 "Failed to set BeamformeeSTS");
7484 }
Arif Hussain68d23f52018-07-11 13:39:08 -07007485
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07007486 if (sta_set_mac_padding_duration(
7487 dut, intf,
7488 QCA_WLAN_HE_NO_ADDITIONAL_PROCESS_TIME)) {
Arif Hussain68d23f52018-07-11 13:39:08 -07007489 sigma_dut_print(dut, DUT_MSG_ERROR,
7490 "Failed to set MAC padding duration");
7491 }
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07007492
7493 if (sta_set_mu_edca_override(dut, intf, 0)) {
7494 sigma_dut_print(dut, DUT_MSG_ERROR,
7495 "ErrorCode,Failed to set MU EDCA override disable");
7496 }
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07007497
7498 if (sta_set_om_ctrl_supp(dut, intf, 1)) {
7499 sigma_dut_print(dut, DUT_MSG_ERROR,
7500 "Failed to set OM ctrl supp");
7501 }
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07007502
7503 if (sta_set_tx_su_ppdu_cfg(dut, intf, 1)) {
7504 sigma_dut_print(dut, DUT_MSG_ERROR,
7505 "Failed to set Tx SU PPDU enable");
7506 }
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07007507
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07007508 if (sta_set_action_tx_in_he_tb_ppdu(dut, intf, 0)) {
7509 sigma_dut_print(dut, DUT_MSG_ERROR,
7510 "failed to send TB PPDU Tx cfg");
7511 }
7512
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07007513 if (sta_set_he_om_ctrl_reset(dut, intf)) {
7514 sigma_dut_print(dut, DUT_MSG_ERROR,
7515 "Failed to set OM ctrl reset");
7516 }
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08007517
7518 /* +HTC-HE support default on */
7519 if (sta_set_he_htc_supp(dut, intf, 1)) {
7520 sigma_dut_print(dut, DUT_MSG_ERROR,
7521 "Setting of +HTC-HE support failed");
7522 }
Subhani Shaik8e7a3052018-04-24 14:03:00 -07007523#endif /* NL80211_SUPPORT */
7524
Arif Hussain8d5b27b2018-05-14 14:31:03 -07007525 if (sta_set_tx_beamformee(dut, intf, 1)) {
7526 sigma_dut_print(dut, DUT_MSG_ERROR,
7527 "Set tx beamformee enable by default in sta_reset_default_wcn failed");
7528 }
7529
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08007530 /* Set nss to 1 and MCS 0-7 in case of testbed */
7531 if (type && strcasecmp(type, "Testbed") == 0) {
7532#ifdef NL80211_SUPPORT
7533 int ret;
7534#endif /* NL80211_SUPPORT */
7535
7536 snprintf(buf, sizeof(buf), "iwpriv %s nss 1", intf);
7537 if (system(buf) != 0) {
7538 sigma_dut_print(dut, DUT_MSG_ERROR,
7539 "iwpriv %s nss failed", intf);
7540 }
7541
7542#ifdef NL80211_SUPPORT
7543 ret = sta_set_he_mcs(dut, intf, HE_80_MCS0_7);
7544 if (ret) {
7545 sigma_dut_print(dut, DUT_MSG_ERROR,
7546 "Setting of MCS failed, ret:%d",
7547 ret);
7548 }
7549#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyamc67621d2018-02-04 23:18:01 -08007550
7551 /* Disable STBC as default */
7552 wcn_sta_set_stbc(dut, intf, "0");
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08007553
7554 /* Disable AMSDU as default */
7555 iwpriv_sta_set_amsdu(dut, intf, "0");
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08007556
7557#ifdef NL80211_SUPPORT
7558 /* HE fragmentation default off */
7559 if (sta_set_he_fragmentation(dut, intf,
7560 HE_FRAG_DISABLE)) {
7561 sigma_dut_print(dut, DUT_MSG_ERROR,
7562 "Setting of HE fragmentation failed");
7563 }
Kiran Kumar Lokerebad51122018-12-12 19:03:36 -08007564
7565 /* set the beamformee NSTS(maximum number of
7566 * space-time streams) to default testbed config
7567 */
7568 if (sta_set_beamformee_sts(dut, intf, 3)) {
7569 sigma_dut_print(dut, DUT_MSG_ERROR,
7570 "Failed to set BeamformeeSTS");
7571 }
7572
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08007573 /* +HTC-HE support default off */
7574 if (sta_set_he_htc_supp(dut, intf, 0)) {
7575 sigma_dut_print(dut, DUT_MSG_ERROR,
7576 "Setting of +HTC-HE support failed");
7577 }
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08007578
7579 /* Set device HE capabilities to testbed default
7580 * configuration. */
7581 if (sta_set_he_testbed_def(dut, intf, 1)) {
7582 sigma_dut_print(dut, DUT_MSG_DEBUG,
7583 "Failed to set HE defaults");
7584 }
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08007585
7586 /* Disable VHT support in 2.4 GHz for testbed */
7587 sta_set_2g_vht_supp(dut, intf, 0);
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08007588#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08007589
7590 /* Enable WEP/TKIP with HE capability in testbed */
7591 if (sta_set_heconfig_and_wep_tkip(dut, intf, 1)) {
7592 sigma_dut_print(dut, DUT_MSG_ERROR,
7593 "Enabling HE config with WEP/TKIP failed");
7594 }
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08007595 }
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08007596
7597 /* Defaults in case of DUT */
7598 if (type && strcasecmp(type, "DUT") == 0) {
Arif Hussaind48fcc72018-05-01 18:34:18 -07007599 /* Enable STBC by default */
7600 wcn_sta_set_stbc(dut, intf, "1");
7601
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08007602 /* set nss to 2 */
7603 snprintf(buf, sizeof(buf), "iwpriv %s nss 2", intf);
7604 if (system(buf) != 0) {
7605 sigma_dut_print(dut, DUT_MSG_ERROR,
7606 "iwpriv %s nss 2 failed", intf);
7607 }
Arif Hussainac6c5112018-05-25 17:34:00 -07007608 dut->sta_nss = 2;
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08007609
7610#ifdef NL80211_SUPPORT
Arif Hussainae239842018-05-01 18:20:05 -07007611 /* Set HE_MCS to 0-11 */
7612 if (sta_set_he_mcs(dut, intf, HE_80_MCS0_11)) {
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08007613 sigma_dut_print(dut, DUT_MSG_ERROR,
7614 "Setting of MCS failed");
7615 }
7616#endif /* NL80211_SUPPORT */
7617
7618 /* Disable WEP/TKIP with HE capability in DUT */
7619 if (sta_set_heconfig_and_wep_tkip(dut, intf, 0)) {
7620 sigma_dut_print(dut, DUT_MSG_ERROR,
7621 "Enabling HE config with WEP/TKIP failed");
7622 }
7623 }
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08007624 }
7625}
7626
7627
Jouni Malinenf7222712019-06-13 01:50:21 +03007628static enum sigma_cmd_result cmd_sta_reset_default(struct sigma_dut *dut,
7629 struct sigma_conn *conn,
7630 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007631{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007632 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007633 const char *band = get_param(cmd, "band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007634 const char *type;
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07007635 const char *program = get_param(cmd, "program");
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05307636 const char *dev_role = get_param(cmd, "DevRole");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007637
Jouni Malinenb21f0542019-11-04 17:53:38 +02007638 if (dut->station_ifname_2g &&
7639 strcmp(dut->station_ifname_2g, intf) == 0)
7640 dut->use_5g = 0;
7641 else if (dut->station_ifname_5g &&
7642 strcmp(dut->station_ifname_5g, intf) == 0)
7643 dut->use_5g = 1;
7644
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07007645 if (!program)
7646 program = get_param(cmd, "prog");
7647 dut->program = sigma_program_to_enum(program);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007648 dut->device_type = STA_unknown;
7649 type = get_param(cmd, "type");
7650 if (type && strcasecmp(type, "Testbed") == 0)
7651 dut->device_type = STA_testbed;
7652 if (type && strcasecmp(type, "DUT") == 0)
7653 dut->device_type = STA_dut;
7654
7655 if (dut->program == PROGRAM_TDLS) {
7656 /* Clear TDLS testing mode */
7657 wpa_command(intf, "SET tdls_disabled 0");
7658 wpa_command(intf, "SET tdls_testing 0");
7659 dut->no_tpk_expiration = 0;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007660 if (get_driver_type(dut) == DRIVER_WCN) {
Pradeep Reddy POTTETI8ce2a232016-10-28 12:17:32 +05307661 /* Enable the WCN driver in TDLS Explicit trigger mode
7662 */
7663 wpa_command(intf, "SET tdls_external_control 0");
7664 wpa_command(intf, "SET tdls_trigger_control 0");
7665 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007666 }
7667
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07007668#ifdef MIRACAST
7669 if (dut->program == PROGRAM_WFD ||
7670 dut->program == PROGRAM_DISPLAYR2)
7671 miracast_sta_reset_default(dut, conn, cmd);
7672#endif /* MIRACAST */
7673
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007674 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007675 case DRIVER_ATHEROS:
7676 sta_reset_default_ath(dut, intf, type);
7677 break;
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08007678 case DRIVER_WCN:
7679 sta_reset_default_wcn(dut, intf, type);
7680 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007681 default:
7682 break;
7683 }
7684
7685#ifdef ANDROID_NAN
7686 if (dut->program == PROGRAM_NAN)
7687 nan_cmd_sta_reset_default(dut, conn, cmd);
7688#endif /* ANDROID_NAN */
7689
Vinay Gannevaram3b9fdd32019-06-14 17:55:44 +05307690 if (dut->program == PROGRAM_LOC &&
7691 lowi_cmd_sta_reset_default(dut, conn, cmd) < 0)
7692 return ERROR_SEND_STATUS;
7693
Jouni Malinenba630452018-06-22 11:49:59 +03007694 if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007695 unlink("SP/wi-fi.org/pps.xml");
7696 if (system("rm -r SP/*") != 0) {
7697 }
7698 unlink("next-client-cert.pem");
7699 unlink("next-client-key.pem");
7700 }
7701
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007702 /* For WPS program of the 60 GHz band the band type needs to be saved */
7703 if (dut->program == PROGRAM_WPS) {
7704 if (band && strcasecmp(band, "60GHz") == 0) {
7705 dut->band = WPS_BAND_60G;
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02007706 /* For 60 GHz enable WPS for WPS TCs */
7707 dut->wps_disable = 0;
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007708 } else {
7709 dut->band = WPS_BAND_NON_60G;
7710 }
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02007711 } else if (dut->program == PROGRAM_60GHZ) {
7712 /* For 60 GHz MAC/PHY TCs WPS must be disabled */
7713 dut->wps_disable = 1;
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007714 }
7715
Alexei Avshalom Lazar157ba062018-12-23 16:15:26 +02007716 if (is_60g_sigma_dut(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007717 const char *dev_role = get_param(cmd, "DevRole");
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02007718 char buf[256];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007719
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02007720 sigma_dut_print(dut, DUT_MSG_INFO,
7721 "WPS 60 GHz program, wps_disable = %d",
7722 dut->wps_disable);
7723
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007724 if (!dev_role) {
7725 send_resp(dut, conn, SIGMA_ERROR,
7726 "errorCode,Missing DevRole argument");
7727 return 0;
7728 }
7729
7730 if (strcasecmp(dev_role, "STA") == 0)
7731 dut->dev_role = DEVROLE_STA;
7732 else if (strcasecmp(dev_role, "PCP") == 0)
7733 dut->dev_role = DEVROLE_PCP;
7734 else {
7735 send_resp(dut, conn, SIGMA_ERROR,
7736 "errorCode,Unknown DevRole");
7737 return 0;
7738 }
7739
7740 if (dut->device_type == STA_unknown) {
7741 sigma_dut_print(dut, DUT_MSG_ERROR,
7742 "Device type is not STA testbed or DUT");
7743 send_resp(dut, conn, SIGMA_ERROR,
7744 "errorCode,Unknown device type");
7745 return 0;
7746 }
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02007747
7748 sigma_dut_print(dut, DUT_MSG_DEBUG,
7749 "Setting msdu_size to MAX: 7912");
7750 snprintf(buf, sizeof(buf), "ifconfig %s mtu 7912",
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007751 get_station_ifname(dut));
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02007752
7753 if (system(buf) != 0) {
7754 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
7755 buf);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007756 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02007757 }
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02007758
7759 if (sta_set_force_mcs(dut, 0, 1)) {
7760 sigma_dut_print(dut, DUT_MSG_ERROR,
7761 "Failed to reset force MCS");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007762 return ERROR_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02007763 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007764 }
7765
7766 wpa_command(intf, "WPS_ER_STOP");
7767 wpa_command(intf, "FLUSH");
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05307768 wpa_command(intf, "ERP_FLUSH");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007769 wpa_command(intf, "SET radio_disabled 0");
7770
Alexei Avshalom Lazar744ae8a2019-01-31 17:26:46 +02007771 dut->wps_forced_version = 0;
7772
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007773 if (dut->wsc_fragment) {
7774 dut->wsc_fragment = 0;
7775 wpa_command(intf, "SET device_name Test client");
7776 wpa_command(intf, "SET manufacturer ");
7777 wpa_command(intf, "SET model_name ");
7778 wpa_command(intf, "SET model_number ");
7779 wpa_command(intf, "SET serial_number ");
7780 }
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02007781 if (is_60g_sigma_dut(dut) && dut->force_rsn_ie) {
7782 dut->force_rsn_ie = FORCE_RSN_IE_NONE;
7783 sta_60g_force_rsn_ie(dut, FORCE_RSN_IE_NONE);
7784 }
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007785
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007786 if (dut->tmp_mac_addr && dut->set_macaddr) {
7787 dut->tmp_mac_addr = 0;
7788 if (system(dut->set_macaddr) != 0) {
7789 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to clear "
7790 "temporary MAC address");
7791 }
7792 }
7793
7794 set_ps(intf, dut, 0);
7795
Jouni Malinenba630452018-06-22 11:49:59 +03007796 if (dut->program == PROGRAM_HS2 || dut->program == PROGRAM_HS2_R2 ||
7797 dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007798 wpa_command(intf, "SET interworking 1");
7799 wpa_command(intf, "SET hs20 1");
7800 }
7801
Deepak Dhamdhere0fe0e452017-12-18 14:52:09 -08007802 if (dut->program == PROGRAM_HS2_R2 ||
Jouni Malinenba630452018-06-22 11:49:59 +03007803 dut->program == PROGRAM_HS2_R3 ||
Deepak Dhamdhere0fe0e452017-12-18 14:52:09 -08007804 dut->program == PROGRAM_OCE) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007805 wpa_command(intf, "SET pmf 1");
7806 } else {
7807 wpa_command(intf, "SET pmf 0");
7808 }
7809
7810 hs2_clear_credentials(intf);
7811 wpa_command(intf, "SET hessid 00:00:00:00:00:00");
7812 wpa_command(intf, "SET access_network_type 15");
7813
7814 static_ip_file(0, NULL, NULL, NULL);
7815 kill_dhcp_client(dut, intf);
7816 clear_ip_addr(dut, intf);
7817
7818 dut->er_oper_performed = 0;
7819 dut->er_oper_bssid[0] = '\0';
7820
priyadharshini gowthamanad6cbba2016-10-04 10:39:58 -07007821 if (dut->program == PROGRAM_LOC) {
7822 /* Disable Interworking by default */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007823 wpa_command(get_station_ifname(dut), "SET interworking 0");
priyadharshini gowthamanad6cbba2016-10-04 10:39:58 -07007824 }
7825
Ashwini Patil00402582017-04-13 12:29:39 +05307826 if (dut->program == PROGRAM_MBO) {
7827 free(dut->non_pref_ch_list);
7828 dut->non_pref_ch_list = NULL;
Ashwini Patil5acd7382017-04-13 15:55:04 +05307829 free(dut->btm_query_cand_list);
7830 dut->btm_query_cand_list = NULL;
Ashwini Patilc63161e2017-04-13 16:30:23 +05307831 wpa_command(intf, "SET reject_btm_req_reason 0");
Ashwini Patila75de5a2017-04-13 16:35:05 +05307832 wpa_command(intf, "SET ignore_assoc_disallow 0");
Ashwini Patild174f2c2017-04-13 16:49:46 +05307833 wpa_command(intf, "SET gas_address3 0");
Ashwini Patil9183fdb2017-04-13 16:58:25 +05307834 wpa_command(intf, "SET roaming 1");
Ankita Bajaj1d974552018-09-18 16:56:44 +05307835 wpa_command(intf, "SET interworking 1");
Ashwini Patil00402582017-04-13 12:29:39 +05307836 }
7837
Jouni Malinen3c367e82017-06-23 17:01:47 +03007838 free(dut->rsne_override);
7839 dut->rsne_override = NULL;
7840
Jouni Malinen68143132017-09-02 02:34:08 +03007841 free(dut->sae_commit_override);
7842 dut->sae_commit_override = NULL;
Jouni Malinen4b3769d2019-10-10 16:20:29 +03007843 wpa_command(intf, "SET sae_pmkid_in_assoc 0");
Jouni Malinen11e55212019-11-22 21:46:59 +02007844 dut->sae_pwe = SAE_PWE_DEFAULT;
Jouni Malinen68143132017-09-02 02:34:08 +03007845
Jouni Malinen134fe3c2019-06-12 04:16:49 +03007846 dut->sta_associate_wait_connect = 0;
7847 dut->server_cert_hash[0] = '\0';
Jouni Malinen37d5c692019-08-19 16:56:55 +03007848 dut->server_cert_tod = 0;
Jouni Malinen134fe3c2019-06-12 04:16:49 +03007849 dut->sta_tod_policy = 0;
7850
Jouni Malinend86e5822017-08-29 03:55:32 +03007851 dut->dpp_conf_id = -1;
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02007852 free(dut->dpp_peer_uri);
7853 dut->dpp_peer_uri = NULL;
Jouni Malinen63d50412017-11-24 11:55:38 +02007854 dut->dpp_local_bootstrap = -1;
Jouni Malinen5011fb52017-12-05 21:00:15 +02007855 wpa_command(intf, "SET dpp_config_processing 2");
Jouni Malinend86e5822017-08-29 03:55:32 +03007856
Jouni Malinenfac9cad2017-10-10 18:35:55 +03007857 wpa_command(intf, "VENDOR_ELEM_REMOVE 13 *");
7858
vamsi krishnaa2799492017-12-05 14:28:01 +05307859 if (dut->program == PROGRAM_OCE) {
Ankita Bajaja2cb5672017-10-25 16:08:28 +05307860 wpa_command(intf, "SET oce 1");
vamsi krishnaa2799492017-12-05 14:28:01 +05307861 wpa_command(intf, "SET disable_fils 0");
Ankita Bajaj1bde7942018-01-09 19:15:01 +05307862 wpa_command(intf, "FILS_HLP_REQ_FLUSH");
7863 dut->fils_hlp = 0;
7864#ifdef ANDROID
7865 hlp_thread_cleanup(dut);
7866#endif /* ANDROID */
vamsi krishnaa2799492017-12-05 14:28:01 +05307867 }
Ankita Bajaja2cb5672017-10-25 16:08:28 +05307868
Jouni Malinen8179fee2019-03-28 03:19:47 +02007869 dut->akm_values = 0;
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007870 dut->sta_ft_ds = 0;
Jouni Malinen8179fee2019-03-28 03:19:47 +02007871
Sunil Dutt076081f2018-02-05 19:45:50 +05307872#ifdef NL80211_SUPPORT
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007873 if (get_driver_type(dut) == DRIVER_WCN &&
Sunil Dutt44595082018-02-12 19:41:45 +05307874 dut->config_rsnie == 1) {
7875 dut->config_rsnie = 0;
7876 sta_config_rsnie(dut, 0);
Sunil Dutt076081f2018-02-05 19:45:50 +05307877 }
7878#endif /* NL80211_SUPPORT */
7879
Sunil Duttfebf8a82018-02-09 18:50:13 +05307880 if (dev_role && strcasecmp(dev_role, "STA-CFON") == 0) {
7881 dut->dev_role = DEVROLE_STA_CFON;
7882 return sta_cfon_reset_default(dut, conn, cmd);
7883 }
7884
Jouni Malinen439352d2018-09-13 03:42:23 +03007885 wpa_command(intf, "SET setband AUTO");
7886
Sunil Duttfebf8a82018-02-09 18:50:13 +05307887 if (dut->program != PROGRAM_VHT)
7888 return cmd_sta_p2p_reset(dut, conn, cmd);
7889
Priyadharshini Gowthamana7dfd492015-11-09 14:34:08 -08007890 return 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007891}
7892
7893
Jouni Malinenf7222712019-06-13 01:50:21 +03007894static enum sigma_cmd_result cmd_sta_get_events(struct sigma_dut *dut,
7895 struct sigma_conn *conn,
7896 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007897{
7898 const char *program = get_param(cmd, "Program");
7899
7900 if (program == NULL)
7901 return -1;
7902#ifdef ANDROID_NAN
7903 if (strcasecmp(program, "NAN") == 0)
7904 return nan_cmd_sta_get_events(dut, conn, cmd);
7905#endif /* ANDROID_NAN */
7906 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
7907 return 0;
7908}
7909
7910
Jouni Malinen82905202018-04-29 17:20:10 +03007911static int sta_exec_action_url(struct sigma_dut *dut, struct sigma_conn *conn,
7912 struct sigma_cmd *cmd)
7913{
7914 const char *url = get_param(cmd, "url");
7915 const char *method = get_param(cmd, "method");
7916 pid_t pid;
7917 int status;
7918
7919 if (!url || !method)
7920 return -1;
7921
7922 /* TODO: Add support for method,post */
7923 if (strcasecmp(method, "get") != 0) {
7924 send_resp(dut, conn, SIGMA_ERROR,
7925 "ErrorCode,Unsupported method");
7926 return 0;
7927 }
7928
7929 pid = fork();
7930 if (pid < 0) {
7931 perror("fork");
7932 return -1;
7933 }
7934
7935 if (pid == 0) {
7936 char * argv[5] = { "wget", "-O", "/dev/null",
7937 (char *) url, NULL };
7938
7939 execv("/usr/bin/wget", argv);
7940 perror("execv");
7941 exit(0);
7942 return -1;
7943 }
7944
7945 if (waitpid(pid, &status, 0) < 0) {
7946 perror("waitpid");
7947 return -1;
7948 }
7949
7950 if (WIFEXITED(status)) {
7951 const char *errmsg;
7952
7953 if (WEXITSTATUS(status) == 0)
7954 return 1;
7955 sigma_dut_print(dut, DUT_MSG_INFO, "wget exit status %d",
7956 WEXITSTATUS(status));
7957 switch (WEXITSTATUS(status)) {
7958 case 4:
7959 errmsg = "errmsg,Network failure";
7960 break;
7961 case 8:
7962 errmsg = "errmsg,Server issued an error response";
7963 break;
7964 default:
7965 errmsg = "errmsg,Unknown failure from wget";
7966 break;
7967 }
7968 send_resp(dut, conn, SIGMA_ERROR, errmsg);
7969 return 0;
7970 }
7971
7972 send_resp(dut, conn, SIGMA_ERROR, "errmsg,Unknown failure");
7973 return 0;
7974}
7975
7976
Jouni Malinenf7222712019-06-13 01:50:21 +03007977static enum sigma_cmd_result cmd_sta_exec_action(struct sigma_dut *dut,
7978 struct sigma_conn *conn,
7979 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007980{
7981 const char *program = get_param(cmd, "Prog");
7982
Jouni Malinen82905202018-04-29 17:20:10 +03007983 if (program && !get_param(cmd, "interface"))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007984 return -1;
7985#ifdef ANDROID_NAN
Jouni Malinen82905202018-04-29 17:20:10 +03007986 if (program && strcasecmp(program, "NAN") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007987 return nan_cmd_sta_exec_action(dut, conn, cmd);
7988#endif /* ANDROID_NAN */
Jouni Malinen82905202018-04-29 17:20:10 +03007989
7990 if (program && strcasecmp(program, "Loc") == 0)
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07007991 return loc_cmd_sta_exec_action(dut, conn, cmd);
Jouni Malinen82905202018-04-29 17:20:10 +03007992
7993 if (get_param(cmd, "url"))
7994 return sta_exec_action_url(dut, conn, cmd);
7995
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007996 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
7997 return 0;
7998}
7999
8000
Jouni Malinenf7222712019-06-13 01:50:21 +03008001static enum sigma_cmd_result cmd_sta_set_11n(struct sigma_dut *dut,
8002 struct sigma_conn *conn,
8003 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008004{
8005 const char *intf = get_param(cmd, "Interface");
8006 const char *val, *mcs32, *rate;
8007
8008 val = get_param(cmd, "GREENFIELD");
8009 if (val) {
8010 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
8011 /* Enable GD */
8012 send_resp(dut, conn, SIGMA_ERROR,
8013 "ErrorCode,GF not supported");
8014 return 0;
8015 }
8016 }
8017
8018 val = get_param(cmd, "SGI20");
8019 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02008020 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008021 case DRIVER_ATHEROS:
8022 ath_sta_set_sgi(dut, intf, val);
8023 break;
8024 default:
8025 send_resp(dut, conn, SIGMA_ERROR,
8026 "ErrorCode,SGI20 not supported");
8027 return 0;
8028 }
8029 }
8030
8031 mcs32 = get_param(cmd, "MCS32"); /* HT Duplicate Mode Enable/Disable */
8032 rate = get_param(cmd, "MCS_FIXEDRATE"); /* Fixed MCS rate (0..31) */
8033 if (mcs32 && rate) {
8034 /* TODO */
8035 send_resp(dut, conn, SIGMA_ERROR,
8036 "ErrorCode,MCS32,MCS_FIXEDRATE not supported");
8037 return 0;
8038 } else if (mcs32 && !rate) {
8039 /* TODO */
8040 send_resp(dut, conn, SIGMA_ERROR,
8041 "ErrorCode,MCS32 not supported");
8042 return 0;
8043 } else if (!mcs32 && rate) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02008044 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008045 case DRIVER_ATHEROS:
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -07008046 novap_reset(dut, intf, 1);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008047 ath_sta_set_11nrates(dut, intf, rate);
8048 break;
8049 default:
8050 send_resp(dut, conn, SIGMA_ERROR,
8051 "ErrorCode,MCS32_FIXEDRATE not supported");
8052 return 0;
8053 }
8054 }
8055
8056 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
8057}
8058
8059
Arif Hussain7b47d2d2018-05-09 10:44:02 -07008060static void cmd_set_max_he_mcs(struct sigma_dut *dut, const char *intf,
8061 int mcs_config)
8062{
8063#ifdef NL80211_SUPPORT
8064 int ret;
8065
8066 switch (mcs_config) {
8067 case HE_80_MCS0_7:
8068 case HE_80_MCS0_9:
8069 case HE_80_MCS0_11:
8070 ret = sta_set_he_mcs(dut, intf, mcs_config);
8071 if (ret) {
8072 sigma_dut_print(dut, DUT_MSG_ERROR,
8073 "cmd_set_max_he_mcs: Setting of MCS:%d failed, ret:%d",
8074 mcs_config, ret);
8075 }
8076 break;
8077 default:
8078 sigma_dut_print(dut, DUT_MSG_ERROR,
8079 "cmd_set_max_he_mcs: Invalid mcs %d",
8080 mcs_config);
8081 break;
8082 }
8083#else /* NL80211_SUPPORT */
8084 sigma_dut_print(dut, DUT_MSG_ERROR,
8085 "max HE MCS cannot be changed without NL80211_SUPPORT defined");
8086#endif /* NL80211_SUPPORT */
8087}
8088
8089
Arif Hussain480d5f42019-03-12 14:40:42 -07008090static int sta_twt_request(struct sigma_dut *dut, struct sigma_conn *conn,
8091 struct sigma_cmd *cmd)
8092{
8093#ifdef NL80211_SUPPORT
8094 struct nlattr *params;
8095 struct nlattr *attr;
8096 struct nlattr *attr1;
8097 struct nl_msg *msg;
8098 int ifindex, ret;
8099 const char *val;
8100 const char *intf = get_param(cmd, "Interface");
8101 int wake_interval_exp = 10, nominal_min_wake_dur = 255,
8102 wake_interval_mantissa = 512;
8103 int flow_type = 0, twt_trigger = 0, target_wake_time = 0,
8104 protection = 0;
8105
8106 ifindex = if_nametoindex(intf);
8107 if (ifindex == 0) {
8108 sigma_dut_print(dut, DUT_MSG_ERROR,
8109 "%s: Index for interface %s failed",
8110 __func__, intf);
8111 return -1;
8112 }
8113
8114 val = get_param(cmd, "FlowType");
8115 if (val) {
8116 flow_type = atoi(val);
8117 if (flow_type != 0 && flow_type != 1) {
8118 sigma_dut_print(dut, DUT_MSG_ERROR,
8119 "TWT: Invalid FlowType %d", flow_type);
8120 return -1;
8121 }
8122 }
8123
8124 val = get_param(cmd, "TWT_Trigger");
8125 if (val) {
8126 twt_trigger = atoi(val);
8127 if (twt_trigger != 0 && twt_trigger != 1) {
8128 sigma_dut_print(dut, DUT_MSG_ERROR,
8129 "TWT: Invalid TWT_Trigger %d",
8130 twt_trigger);
8131 return -1;
8132 }
8133 }
8134
8135 val = get_param(cmd, "Protection");
8136 if (val) {
8137 protection = atoi(val);
8138 if (protection != 0 && protection != 1) {
8139 sigma_dut_print(dut, DUT_MSG_ERROR,
8140 "TWT: Invalid Protection %d",
8141 protection);
8142 return -1;
8143 }
8144 }
8145
8146 val = get_param(cmd, "TargetWakeTime");
8147 if (val)
8148 target_wake_time = atoi(val);
8149
8150 val = get_param(cmd, "WakeIntervalMantissa");
8151 if (val)
8152 wake_interval_mantissa = atoi(val);
8153
8154 val = get_param(cmd, "WakeIntervalExp");
8155 if (val)
8156 wake_interval_exp = atoi(val);
8157
8158 val = get_param(cmd, "NominalMinWakeDur");
8159 if (val)
8160 nominal_min_wake_dur = atoi(val);
8161
8162 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8163 NL80211_CMD_VENDOR)) ||
8164 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
8165 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
8166 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
8167 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
8168 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8169 !(params = nla_nest_start(
8170 msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_SETUP)) ||
8171 !(attr1 = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8172 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_EXP,
8173 wake_interval_exp) ||
Arif Hussain480d5f42019-03-12 14:40:42 -07008174 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_REQ_TYPE, 1) ||
Kiran Kumar Lokere2cffae52019-09-26 18:44:15 -07008175 (twt_trigger &&
8176 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TRIGGER)) ||
Arif Hussain480d5f42019-03-12 14:40:42 -07008177 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE,
8178 flow_type) ||
Kiran Kumar Lokere2cffae52019-09-26 18:44:15 -07008179 (protection &&
8180 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_PROTECTION)) ||
Arif Hussain480d5f42019-03-12 14:40:42 -07008181 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME,
8182 target_wake_time) ||
8183 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_DURATION,
8184 nominal_min_wake_dur) ||
8185 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_MANTISSA,
8186 wake_interval_mantissa)) {
8187 sigma_dut_print(dut, DUT_MSG_ERROR,
8188 "%s: err in adding vendor_cmd and vendor_data",
8189 __func__);
8190 nlmsg_free(msg);
8191 return -1;
8192 }
8193 nla_nest_end(msg, attr1);
8194 nla_nest_end(msg, params);
8195 nla_nest_end(msg, attr);
8196
8197 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
8198 if (ret) {
8199 sigma_dut_print(dut, DUT_MSG_ERROR,
8200 "%s: err in send_and_recv_msgs, ret=%d",
8201 __func__, ret);
8202 }
8203
8204 return ret;
8205#else /* NL80211_SUPPORT */
8206 sigma_dut_print(dut, DUT_MSG_ERROR,
8207 "TWT request cannot be done without NL80211_SUPPORT defined");
8208 return -1;
8209#endif /* NL80211_SUPPORT */
8210}
8211
8212
8213static int sta_twt_teardown(struct sigma_dut *dut, struct sigma_conn *conn,
8214 struct sigma_cmd *cmd)
8215{
8216 #ifdef NL80211_SUPPORT
8217 struct nlattr *params;
8218 struct nlattr *attr;
8219 struct nlattr *attr1;
8220 int ifindex, ret;
8221 struct nl_msg *msg;
8222 const char *intf = get_param(cmd, "Interface");
8223
8224 ifindex = if_nametoindex(intf);
8225 if (ifindex == 0) {
8226 sigma_dut_print(dut, DUT_MSG_ERROR,
8227 "%s: Index for interface %s failed",
8228 __func__, intf);
8229 return -1;
8230 }
8231
8232 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8233 NL80211_CMD_VENDOR)) ||
8234 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
8235 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
8236 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
8237 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
8238 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8239 !(params = nla_nest_start(
8240 msg,
8241 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_TERMINATE)) ||
8242 !(attr1 = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8243 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE, 0)) {
8244 sigma_dut_print(dut, DUT_MSG_ERROR,
8245 "%s: err in adding vendor_cmd and vendor_data",
8246 __func__);
8247 nlmsg_free(msg);
8248 return -1;
8249 }
8250 nla_nest_end(msg, attr1);
8251 nla_nest_end(msg, params);
8252 nla_nest_end(msg, attr);
8253
8254 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
8255 if (ret) {
8256 sigma_dut_print(dut, DUT_MSG_ERROR,
8257 "%s: err in send_and_recv_msgs, ret=%d",
8258 __func__, ret);
8259 }
8260
8261 return ret;
8262#else /* NL80211_SUPPORT */
8263 sigma_dut_print(dut, DUT_MSG_ERROR,
8264 "TWT teardown cannot be done without NL80211_SUPPORT defined");
8265 return -1;
8266#endif /* NL80211_SUPPORT */
8267}
8268
8269
Kiran Kumar Lokere50eb2cd2018-12-18 18:31:28 -08008270static int sta_transmit_omi(struct sigma_dut *dut, struct sigma_conn *conn,
8271 struct sigma_cmd *cmd)
8272{
8273#ifdef NL80211_SUPPORT
8274 struct nlattr *params;
8275 struct nlattr *attr;
8276 struct nlattr *attr1;
8277 struct nl_msg *msg;
8278 int ifindex, ret;
8279 const char *val;
8280 const char *intf = get_param(cmd, "Interface");
8281 uint8_t rx_nss = 0xFF, ch_bw = 0xFF, tx_nsts = 0xFF, ulmu_dis = 0,
8282 ulmu_data_dis = 0;
8283
8284 ifindex = if_nametoindex(intf);
8285 if (ifindex == 0) {
8286 sigma_dut_print(dut, DUT_MSG_ERROR,
8287 "%s: Index for interface %s failed",
8288 __func__, intf);
8289 return -1;
8290 }
8291 val = get_param(cmd, "OMCtrl_RxNSS");
8292 if (val)
8293 rx_nss = atoi(val);
8294
8295 val = get_param(cmd, "OMCtrl_ChnlWidth");
8296 if (val)
8297 ch_bw = atoi(val);
8298
8299 val = get_param(cmd, "OMCtrl_ULMUDisable");
8300 if (val)
8301 ulmu_dis = atoi(val);
8302
8303 val = get_param(cmd, "OMCtrl_TxNSTS");
8304 if (val)
8305 tx_nsts = atoi(val);
8306
8307 val = get_param(cmd, "OMCtrl_ULMUDataDisable");
8308 if (val)
8309 ulmu_data_dis = atoi(val);
8310
8311 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8312 NL80211_CMD_VENDOR)) ||
8313 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
8314 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
8315 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
8316 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
8317 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8318 !(params = nla_nest_start(
8319 msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OMI_TX)) ||
8320 !(attr1 = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8321 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_RX_NSS, rx_nss) ||
8322 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_CH_BW, ch_bw) ||
8323 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_TX_NSTS, tx_nsts) ||
8324 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DATA_DISABLE,
8325 ulmu_data_dis) ||
8326 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DISABLE,
8327 ulmu_dis)) {
8328 sigma_dut_print(dut, DUT_MSG_ERROR,
8329 "%s: err in adding vendor_cmd and vendor_data",
8330 __func__);
8331 nlmsg_free(msg);
8332 return -1;
8333 }
8334 nla_nest_end(msg, attr1);
8335 nla_nest_end(msg, params);
8336 nla_nest_end(msg, attr);
8337
8338 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
8339 if (ret) {
8340 sigma_dut_print(dut, DUT_MSG_ERROR,
8341 "%s: err in send_and_recv_msgs, ret=%d",
8342 __func__, ret);
8343 }
8344
8345 return ret;
8346#else /* NL80211_SUPPORT */
8347 sigma_dut_print(dut, DUT_MSG_ERROR,
8348 "OMI TX cannot be processed without NL80211_SUPPORT defined");
8349 return -1;
8350#endif /* NL80211_SUPPORT */
8351}
8352
8353
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008354static int cmd_sta_set_wireless_vht(struct sigma_dut *dut,
8355 struct sigma_conn *conn,
8356 struct sigma_cmd *cmd)
8357{
8358 const char *intf = get_param(cmd, "Interface");
8359 const char *val;
Arif Hussaina37e9552018-06-20 17:05:59 -07008360 const char *program;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008361 int tkip = -1;
8362 int wep = -1;
8363
Arif Hussaina37e9552018-06-20 17:05:59 -07008364 program = get_param(cmd, "Program");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008365 val = get_param(cmd, "SGI80");
8366 if (val) {
8367 int sgi80;
8368
8369 sgi80 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008370 run_iwpriv(dut, intf, "shortgi %d", sgi80);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008371 }
8372
8373 val = get_param(cmd, "TxBF");
8374 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02008375 switch (get_driver_type(dut)) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07008376 case DRIVER_WCN:
8377 if (sta_set_tx_beamformee(dut, intf, 1)) {
8378 send_resp(dut, conn, SIGMA_ERROR,
8379 "ErrorCode,Failed to set TX beamformee enable");
8380 return 0;
8381 }
8382 break;
8383 case DRIVER_ATHEROS:
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008384 if (run_iwpriv(dut, intf, "vhtsubfee 1") < 0) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07008385 send_resp(dut, conn, SIGMA_ERROR,
8386 "ErrorCode,Setting vhtsubfee failed");
8387 return 0;
8388 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008389 if (run_iwpriv(dut, intf, "vhtsubfer 1") < 0) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07008390 send_resp(dut, conn, SIGMA_ERROR,
8391 "ErrorCode,Setting vhtsubfer failed");
8392 return 0;
8393 }
8394 break;
8395 default:
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008396 sigma_dut_print(dut, DUT_MSG_ERROR,
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07008397 "Unsupported driver type");
8398 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008399 }
8400 }
8401
8402 val = get_param(cmd, "MU_TxBF");
8403 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02008404 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008405 case DRIVER_ATHEROS:
8406 ath_sta_set_txsp_stream(dut, intf, "1SS");
8407 ath_sta_set_rxsp_stream(dut, intf, "1SS");
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008408 run_iwpriv(dut, intf, "vhtmubfee 1");
8409 run_iwpriv(dut, intf, "vhtmubfer 1");
Sunil Duttae9e5d12018-06-29 11:50:47 +05308410 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008411 case DRIVER_WCN:
8412 if (wcn_sta_set_sp_stream(dut, intf, "1SS") < 0) {
8413 send_resp(dut, conn, SIGMA_ERROR,
8414 "ErrorCode,Failed to set RX/TXSP_STREAM");
8415 return 0;
8416 }
Sunil Duttae9e5d12018-06-29 11:50:47 +05308417 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008418 default:
8419 sigma_dut_print(dut, DUT_MSG_ERROR,
8420 "Setting SP_STREAM not supported");
8421 break;
8422 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008423 }
8424
8425 val = get_param(cmd, "LDPC");
8426 if (val) {
8427 int ldpc;
8428
8429 ldpc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008430 run_iwpriv(dut, intf, "ldpc %d", ldpc);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008431 }
8432
Amarnath Hullur Subramanyam7bae60e2018-01-31 03:46:50 -08008433 val = get_param(cmd, "BCC");
8434 if (val) {
8435 int bcc;
8436
8437 bcc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
8438 /* use LDPC iwpriv itself to set bcc coding, bcc coding
8439 * is mutually exclusive to bcc */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008440 run_iwpriv(dut, intf, "ldpc %d", !bcc);
Amarnath Hullur Subramanyam7bae60e2018-01-31 03:46:50 -08008441 }
8442
Arif Hussain7b47d2d2018-05-09 10:44:02 -07008443 val = get_param(cmd, "MaxHE-MCS_1SS_RxMapLTE80");
8444 if (val && dut->sta_nss == 1)
8445 cmd_set_max_he_mcs(dut, intf, atoi(val));
8446
8447 val = get_param(cmd, "MaxHE-MCS_2SS_RxMapLTE80");
8448 if (val && dut->sta_nss == 2)
8449 cmd_set_max_he_mcs(dut, intf, atoi(val));
8450
Arif Hussainac6c5112018-05-25 17:34:00 -07008451 val = get_param(cmd, "MCS_FixedRate");
8452 if (val) {
8453#ifdef NL80211_SUPPORT
8454 int mcs, ratecode = 0;
8455 enum he_mcs_config mcs_config;
8456 int ret;
Jouni Malinenb9b671d2019-04-26 13:23:17 +03008457 char buf[60];
Arif Hussainac6c5112018-05-25 17:34:00 -07008458
8459 ratecode = (0x07 & dut->sta_nss) << 5;
8460 mcs = atoi(val);
8461 /* Add the MCS to the ratecode */
8462 if (mcs >= 0 && mcs <= 11) {
8463 ratecode += mcs;
8464 if (dut->device_type == STA_testbed &&
8465 mcs > 7 && mcs <= 11) {
8466 if (mcs <= 9)
8467 mcs_config = HE_80_MCS0_9;
8468 else
8469 mcs_config = HE_80_MCS0_11;
8470 ret = sta_set_he_mcs(dut, intf, mcs_config);
8471 if (ret) {
8472 sigma_dut_print(dut, DUT_MSG_ERROR,
8473 "MCS_FixedRate: mcs setting failed, mcs:%d, mcs_config %d, ret:%d",
8474 mcs, mcs_config, ret);
8475 }
8476 }
8477 snprintf(buf, sizeof(buf),
8478 "iwpriv %s set_11ax_rate 0x%03x",
8479 intf, ratecode);
8480 if (system(buf) != 0) {
8481 sigma_dut_print(dut, DUT_MSG_ERROR,
8482 "MCS_FixedRate: iwpriv setting of 11ax rates 0x%03x failed",
8483 ratecode);
8484 }
8485 } else {
8486 sigma_dut_print(dut, DUT_MSG_ERROR,
8487 "MCS_FixedRate: HE MCS %d not supported",
8488 mcs);
8489 }
8490#else /* NL80211_SUPPORT */
8491 sigma_dut_print(dut, DUT_MSG_ERROR,
8492 "MCS_FixedRate cannot be changed without NL80211_SUPPORT defined");
8493#endif /* NL80211_SUPPORT */
8494 }
8495
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008496 val = get_param(cmd, "opt_md_notif_ie");
8497 if (val) {
8498 char *result = NULL;
8499 char delim[] = ";";
8500 char token[30];
8501 int value, config_val = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308502 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008503
Peng Xub8fc5cc2017-05-10 17:27:28 -07008504 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308505 result = strtok_r(token, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008506
8507 /* Extract the NSS information */
8508 if (result) {
8509 value = atoi(result);
8510 switch (value) {
8511 case 1:
8512 config_val = 1;
8513 break;
8514 case 2:
8515 config_val = 3;
8516 break;
8517 case 3:
8518 config_val = 7;
8519 break;
8520 case 4:
8521 config_val = 15;
8522 break;
8523 default:
8524 config_val = 3;
8525 break;
8526 }
8527
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008528 run_iwpriv(dut, intf, "rxchainmask %d", config_val);
8529 run_iwpriv(dut, intf, "txchainmask %d", config_val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008530
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008531 }
8532
8533 /* Extract the channel width information */
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308534 result = strtok_r(NULL, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008535 if (result) {
8536 value = atoi(result);
8537 switch (value) {
8538 case 20:
8539 config_val = 0;
8540 break;
8541 case 40:
8542 config_val = 1;
8543 break;
8544 case 80:
8545 config_val = 2;
8546 break;
8547 case 160:
8548 config_val = 3;
8549 break;
8550 default:
8551 config_val = 2;
8552 break;
8553 }
8554
8555 dut->chwidth = config_val;
8556
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008557 run_iwpriv(dut, intf, "chwidth %d", config_val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008558 }
8559
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008560 run_iwpriv(dut, intf, "opmode_notify 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008561 }
8562
8563 val = get_param(cmd, "nss_mcs_cap");
8564 if (val) {
8565 int nss, mcs;
8566 char token[20];
8567 char *result = NULL;
8568 unsigned int vht_mcsmap = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308569 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008570
Peng Xub8fc5cc2017-05-10 17:27:28 -07008571 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308572 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05308573 if (!result) {
8574 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07008575 "NSS not specified");
8576 send_resp(dut, conn, SIGMA_ERROR,
8577 "errorCode,NSS not specified");
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05308578 return 0;
8579 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008580 nss = atoi(result);
8581
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008582 run_iwpriv(dut, intf, "nss %d", nss);
Arif Hussainac6c5112018-05-25 17:34:00 -07008583 dut->sta_nss = nss;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008584
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308585 result = strtok_r(NULL, ";", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008586 if (result == NULL) {
8587 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07008588 "MCS not specified");
8589 send_resp(dut, conn, SIGMA_ERROR,
8590 "errorCode,MCS not specified");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008591 return 0;
8592 }
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308593 result = strtok_r(result, "-", &saveptr);
8594 result = strtok_r(NULL, "-", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05308595 if (!result) {
8596 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07008597 "MCS not specified");
8598 send_resp(dut, conn, SIGMA_ERROR,
8599 "errorCode,MCS not specified");
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05308600 return 0;
8601 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008602 mcs = atoi(result);
8603
Arif Hussaina37e9552018-06-20 17:05:59 -07008604 if (program && strcasecmp(program, "HE") == 0) {
8605#ifdef NL80211_SUPPORT
8606 enum he_mcs_config mcs_config;
8607 int ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008608
Arif Hussaina37e9552018-06-20 17:05:59 -07008609 if (mcs >= 0 && mcs <= 7) {
8610 mcs_config = HE_80_MCS0_7;
8611 } else if (mcs > 7 && mcs <= 9) {
8612 mcs_config = HE_80_MCS0_9;
8613 } else if (mcs > 9 && mcs <= 11) {
8614 mcs_config = HE_80_MCS0_11;
8615 } else {
8616 sigma_dut_print(dut, DUT_MSG_ERROR,
8617 "nss_mcs_cap: HE: Invalid mcs: %d",
8618 mcs);
8619 send_resp(dut, conn, SIGMA_ERROR,
8620 "errorCode,Invalid MCS");
8621 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008622 }
Arif Hussaina37e9552018-06-20 17:05:59 -07008623
8624 ret = sta_set_he_mcs(dut, intf, mcs_config);
8625 if (ret) {
8626 sigma_dut_print(dut, DUT_MSG_ERROR,
8627 "nss_mcs_cap: HE: Setting of MCS failed, mcs_config: %d, ret: %d",
8628 mcs_config, ret);
8629 send_resp(dut, conn, SIGMA_ERROR,
8630 "errorCode,Failed to set MCS");
8631 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008632 }
Arif Hussaina37e9552018-06-20 17:05:59 -07008633#else /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008634 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07008635 "nss_mcs_cap: HE: MCS cannot be changed without NL80211_SUPPORT defined");
8636#endif /* NL80211_SUPPORT */
8637 } else {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008638 run_iwpriv(dut, intf, "vhtmcs %d", mcs);
Arif Hussaina37e9552018-06-20 17:05:59 -07008639
8640 switch (nss) {
8641 case 1:
8642 switch (mcs) {
8643 case 7:
8644 vht_mcsmap = 0xfffc;
8645 break;
8646 case 8:
8647 vht_mcsmap = 0xfffd;
8648 break;
8649 case 9:
8650 vht_mcsmap = 0xfffe;
8651 break;
8652 default:
8653 vht_mcsmap = 0xfffe;
8654 break;
8655 }
8656 break;
8657 case 2:
8658 switch (mcs) {
8659 case 7:
8660 vht_mcsmap = 0xfff0;
8661 break;
8662 case 8:
8663 vht_mcsmap = 0xfff5;
8664 break;
8665 case 9:
8666 vht_mcsmap = 0xfffa;
8667 break;
8668 default:
8669 vht_mcsmap = 0xfffa;
8670 break;
8671 }
8672 break;
8673 case 3:
8674 switch (mcs) {
8675 case 7:
8676 vht_mcsmap = 0xffc0;
8677 break;
8678 case 8:
8679 vht_mcsmap = 0xffd5;
8680 break;
8681 case 9:
8682 vht_mcsmap = 0xffea;
8683 break;
8684 default:
8685 vht_mcsmap = 0xffea;
8686 break;
8687 }
8688 break;
8689 default:
8690 vht_mcsmap = 0xffea;
8691 break;
8692 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008693 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008694 }
8695 }
8696
8697 /* UNSUPPORTED: val = get_param(cmd, "Tx_lgi_rate"); */
8698
8699 val = get_param(cmd, "Vht_tkip");
8700 if (val)
8701 tkip = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
8702
8703 val = get_param(cmd, "Vht_wep");
8704 if (val)
8705 wep = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
8706
8707 if (tkip != -1 || wep != -1) {
8708 if ((tkip == 1 && wep != 0) || (wep == 1 && tkip != 0)) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008709 run_iwpriv(dut, intf, "htweptkip 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008710 } else if ((tkip == 0 && wep != 1) || (wep == 0 && tkip != 1)) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008711 run_iwpriv(dut, intf, "htweptkip 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008712 } else {
8713 sigma_dut_print(dut, DUT_MSG_ERROR,
8714 "ErrorCode,mixed mode of VHT TKIP/WEP not supported");
8715 return 0;
8716 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008717 }
8718
Arif Hussain55f00da2018-07-03 08:28:26 -07008719 val = get_param(cmd, "txBandwidth");
8720 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02008721 switch (get_driver_type(dut)) {
Arif Hussain55f00da2018-07-03 08:28:26 -07008722 case DRIVER_WCN:
8723 if (wcn_sta_set_width(dut, intf, val) < 0) {
8724 send_resp(dut, conn, SIGMA_ERROR,
8725 "ErrorCode,Failed to set txBandwidth");
8726 return 0;
8727 }
8728 break;
8729 case DRIVER_ATHEROS:
8730 if (ath_set_width(dut, conn, intf, val) < 0) {
8731 send_resp(dut, conn, SIGMA_ERROR,
8732 "ErrorCode,Failed to set txBandwidth");
8733 return 0;
8734 }
8735 break;
8736 default:
8737 sigma_dut_print(dut, DUT_MSG_ERROR,
8738 "Setting txBandwidth not supported");
8739 break;
8740 }
8741 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008742
Arif Hussain9765f7d2018-07-03 08:28:26 -07008743 val = get_param(cmd, "BeamformeeSTS");
8744 if (val) {
Kiran Kumar Lokerebc89d432018-07-10 12:20:13 -07008745 if (sta_set_tx_beamformee(dut, intf, 1)) {
8746 send_resp(dut, conn, SIGMA_ERROR,
8747 "ErrorCode,Failed to set TX beamformee enable");
8748 return 0;
8749 }
8750
Arif Hussain9765f7d2018-07-03 08:28:26 -07008751 if (sta_set_beamformee_sts(dut, intf, atoi(val))) {
8752 send_resp(dut, conn, SIGMA_ERROR,
8753 "ErrorCode,Failed to set BeamformeeSTS");
8754 return 0;
8755 }
8756 }
8757
Arif Hussain68d23f52018-07-11 13:39:08 -07008758 val = get_param(cmd, "Trig_MAC_Padding_Dur");
8759 if (val) {
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07008760#ifdef NL80211_SUPPORT
8761 enum qca_wlan_he_mac_padding_dur set_val;
8762
8763 switch (atoi(val)) {
8764 case 16:
8765 set_val = QCA_WLAN_HE_16US_OF_PROCESS_TIME;
8766 break;
8767 case 8:
8768 set_val = QCA_WLAN_HE_8US_OF_PROCESS_TIME;
8769 break;
8770 default:
8771 set_val = QCA_WLAN_HE_NO_ADDITIONAL_PROCESS_TIME;
8772 break;
8773 }
8774 if (sta_set_mac_padding_duration(dut, intf, set_val)) {
Arif Hussain68d23f52018-07-11 13:39:08 -07008775 send_resp(dut, conn, SIGMA_ERROR,
8776 "ErrorCode,Failed to set MAC padding duration");
8777 return 0;
8778 }
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07008779#else /* NL80211_SUPPORT */
8780 sigma_dut_print(dut, DUT_MSG_ERROR,
8781 "MAC padding duration cannot be changed without NL80211_SUPPORT defined");
8782#endif /* NL80211_SUPPORT */
Arif Hussain68d23f52018-07-11 13:39:08 -07008783 }
8784
Arif Hussain480d5f42019-03-12 14:40:42 -07008785 val = get_param(cmd, "TWT_ReqSupport");
8786 if (val) {
8787 int set_val;
8788
8789 if (strcasecmp(val, "Enable") == 0) {
8790 set_val = 1;
8791 } else if (strcasecmp(val, "Disable") == 0) {
8792 set_val = 0;
8793 } else {
8794 send_resp(dut, conn, SIGMA_ERROR,
8795 "ErrorCode,Invalid TWT_ReqSupport");
8796 return STATUS_SENT;
8797 }
8798
8799 if (sta_set_twt_req_support(dut, intf, set_val)) {
8800 sigma_dut_print(dut, DUT_MSG_ERROR,
8801 "Failed to set TWT req support %d",
8802 set_val);
8803 send_resp(dut, conn, SIGMA_ERROR,
8804 "ErrorCode,Failed to set TWT_ReqSupport");
8805 return STATUS_SENT;
8806 }
8807 }
8808
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07008809 val = get_param(cmd, "MU_EDCA");
8810 if (val && (strcasecmp(val, "Override") == 0)) {
8811 if (sta_set_mu_edca_override(dut, intf, 1)) {
8812 send_resp(dut, conn, SIGMA_ERROR,
8813 "ErrorCode,Failed to set MU EDCA override");
8814 return 0;
8815 }
8816 }
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -07008817
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07008818 val = get_param(cmd, "OMControl");
8819 if (val) {
8820 int set_val = 1;
8821
8822 if (strcasecmp(val, "Enable") == 0)
8823 set_val = 1;
8824 else if (strcasecmp(val, "Disable") == 0)
8825 set_val = 0;
8826
8827 if (sta_set_om_ctrl_supp(dut, intf, set_val)) {
8828 send_resp(dut, conn, SIGMA_ERROR,
8829 "ErrorCode,Failed to set OM ctrl supp");
8830 return 0;
8831 }
8832 }
8833
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -07008834 val = get_param(cmd, "ADDBAResp_BufSize");
8835 if (val) {
8836 int buf_size;
8837
8838 if (strcasecmp(val, "gt64") == 0)
8839 buf_size = 256;
8840 else
8841 buf_size = 64;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02008842 if (get_driver_type(dut) == DRIVER_WCN &&
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -07008843 sta_set_addba_buf_size(dut, intf, buf_size)) {
8844 send_resp(dut, conn, SIGMA_ERROR,
8845 "ErrorCode,set addbaresp_buff_size failed");
8846 return 0;
8847 }
8848 }
8849
8850 val = get_param(cmd, "ADDBAReq_BufSize");
8851 if (val) {
8852 int buf_size;
8853
8854 if (strcasecmp(val, "gt64") == 0)
8855 buf_size = 256;
8856 else
8857 buf_size = 64;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02008858 if (get_driver_type(dut) == DRIVER_WCN &&
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -07008859 sta_set_addba_buf_size(dut, intf, buf_size)) {
8860 send_resp(dut, conn, SIGMA_ERROR,
8861 "ErrorCode,set addbareq_buff_size failed");
8862 return 0;
8863 }
8864 }
8865
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008866 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
8867}
8868
8869
8870static int sta_set_wireless_60g(struct sigma_dut *dut,
8871 struct sigma_conn *conn,
8872 struct sigma_cmd *cmd)
8873{
8874 const char *dev_role = get_param(cmd, "DevRole");
8875
8876 if (!dev_role) {
8877 send_resp(dut, conn, SIGMA_INVALID,
8878 "ErrorCode,DevRole not specified");
8879 return 0;
8880 }
8881
8882 if (strcasecmp(dev_role, "PCP") == 0)
8883 return sta_set_60g_pcp(dut, conn, cmd);
8884 if (strcasecmp(dev_role, "STA") == 0)
8885 return sta_set_60g_sta(dut, conn, cmd);
8886 send_resp(dut, conn, SIGMA_INVALID,
8887 "ErrorCode,DevRole not supported");
8888 return 0;
8889}
8890
8891
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05308892static int sta_set_wireless_oce(struct sigma_dut *dut, struct sigma_conn *conn,
8893 struct sigma_cmd *cmd)
8894{
8895 int status;
8896 const char *intf = get_param(cmd, "Interface");
8897 const char *val = get_param(cmd, "DevRole");
8898
8899 if (val && strcasecmp(val, "STA-CFON") == 0) {
8900 status = sta_cfon_set_wireless(dut, conn, cmd);
8901 if (status)
8902 return status;
8903 }
8904 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
8905}
8906
8907
Jouni Malinenf7222712019-06-13 01:50:21 +03008908static enum sigma_cmd_result cmd_sta_set_wireless(struct sigma_dut *dut,
8909 struct sigma_conn *conn,
8910 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008911{
8912 const char *val;
8913
8914 val = get_param(cmd, "Program");
8915 if (val) {
8916 if (strcasecmp(val, "11n") == 0)
8917 return cmd_sta_set_11n(dut, conn, cmd);
Amarnath Hullur Subramanyam4f860292018-01-31 03:49:35 -08008918 if (strcasecmp(val, "VHT") == 0 || strcasecmp(val, "HE") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008919 return cmd_sta_set_wireless_vht(dut, conn, cmd);
8920 if (strcasecmp(val, "60ghz") == 0)
8921 return sta_set_wireless_60g(dut, conn, cmd);
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05308922 if (strcasecmp(val, "OCE") == 0)
8923 return sta_set_wireless_oce(dut, conn, cmd);
Alexei Avshalom Lazar66bb9972018-12-18 16:01:43 +02008924 /* sta_set_wireless in WPS program is only used for 60G */
8925 if (is_60g_sigma_dut(dut))
8926 return sta_set_wireless_60g(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008927 send_resp(dut, conn, SIGMA_ERROR,
8928 "ErrorCode,Program value not supported");
8929 } else {
8930 send_resp(dut, conn, SIGMA_ERROR,
8931 "ErrorCode,Program argument not available");
8932 }
8933
8934 return 0;
8935}
8936
8937
8938static void ath_sta_inject_frame(struct sigma_dut *dut, const char *intf,
8939 int tid)
8940{
8941 char buf[100];
8942 int tid_to_dscp [] = { 0x00, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0 };
8943
Pradeep Reddy POTTETId31d1322016-10-13 17:22:03 +05308944 if (tid < 0 ||
8945 tid >= (int) (sizeof(tid_to_dscp) / sizeof(tid_to_dscp[0]))) {
8946 sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported TID: %d", tid);
8947 return;
8948 }
8949
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008950 /*
8951 * Two ways to ensure that addba request with a
8952 * non zero TID could be sent out. EV 117296
8953 */
8954 snprintf(buf, sizeof(buf),
8955 "ping -c 8 -Q %d `arp -a | grep wlan0 | awk '{print $2}' | tr -d '()'`",
8956 tid);
8957 if (system(buf) != 0) {
8958 sigma_dut_print(dut, DUT_MSG_ERROR,
8959 "Ping did not send out");
8960 }
8961
8962 snprintf(buf, sizeof(buf),
8963 "iwconfig %s | grep Access | awk '{print $6}' > %s",
8964 intf, VI_QOS_TMP_FILE);
8965 if (system(buf) != 0)
8966 return;
8967
8968 snprintf(buf, sizeof(buf),
8969 "ifconfig %s | grep HWaddr | cut -b 39-56 >> %s",
8970 intf, VI_QOS_TMP_FILE);
8971 if (system(buf) != 0)
8972 sigma_dut_print(dut, DUT_MSG_ERROR, "HWaddr matching failed");
8973
8974 snprintf(buf,sizeof(buf), "sed -n '3,$p' %s >> %s",
8975 VI_QOS_REFFILE, VI_QOS_TMP_FILE);
8976 if (system(buf) != 0) {
8977 sigma_dut_print(dut, DUT_MSG_ERROR,
8978 "VI_QOS_TEMP_FILE generation error failed");
8979 }
8980 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
8981 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
8982 if (system(buf) != 0) {
8983 sigma_dut_print(dut, DUT_MSG_ERROR,
8984 "VI_QOS_FILE generation failed");
8985 }
8986
8987 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
8988 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
8989 if (system(buf) != 0) {
8990 sigma_dut_print(dut, DUT_MSG_ERROR,
8991 "VI_QOS_FILE generation failed");
8992 }
8993
8994 snprintf(buf, sizeof(buf), "ethinject %s %s", intf, VI_QOS_FILE);
8995 if (system(buf) != 0) {
8996 }
8997}
8998
8999
9000static int ath_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
9001 struct sigma_cmd *cmd)
9002{
9003 const char *intf = get_param(cmd, "Interface");
9004 const char *val;
9005 int tid = 0;
9006 char buf[100];
9007
9008 val = get_param(cmd, "TID");
9009 if (val) {
9010 tid = atoi(val);
9011 if (tid)
9012 ath_sta_inject_frame(dut, intf, tid);
9013 }
9014
9015 /* Command sequence for ADDBA request on Peregrine based devices */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07009016 run_iwpriv(dut, intf, "setaddbaoper 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009017
9018 snprintf(buf, sizeof(buf), "wifitool %s senddelba 1 %d 1 4", intf, tid);
9019 if (system(buf) != 0) {
9020 sigma_dut_print(dut, DUT_MSG_ERROR,
9021 "wifitool senddelba failed");
9022 }
9023
9024 snprintf(buf, sizeof(buf), "wifitool %s sendaddba 1 %d 64", intf, tid);
9025 if (system(buf) != 0) {
9026 sigma_dut_print(dut, DUT_MSG_ERROR,
9027 "wifitool sendaddba failed");
9028 }
9029
9030 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
9031
9032 return 1;
9033}
9034
9035
Lior David9981b512017-01-20 13:16:40 +02009036#ifdef __linux__
9037
9038static int wil6210_send_addba(struct sigma_dut *dut, const char *dest_mac,
9039 int agg_size)
9040{
9041 char dir[128], buf[128];
9042 FILE *f;
9043 regex_t re;
9044 regmatch_t m[2];
Jouni Malinen3aa72862019-05-29 23:14:51 +03009045 int rc, ret = -1, vring_id, found, res;
Lior David9981b512017-01-20 13:16:40 +02009046
9047 if (wil6210_get_debugfs_dir(dut, dir, sizeof(dir))) {
9048 sigma_dut_print(dut, DUT_MSG_ERROR,
9049 "failed to get wil6210 debugfs dir");
9050 return -1;
9051 }
9052
Jouni Malinen3aa72862019-05-29 23:14:51 +03009053 res = snprintf(buf, sizeof(buf), "%s/vrings", dir);
9054 if (res < 0 || res >= sizeof(buf))
9055 return -1;
Lior David9981b512017-01-20 13:16:40 +02009056 f = fopen(buf, "r");
9057 if (!f) {
9058 sigma_dut_print(dut, DUT_MSG_ERROR, "failed to open: %s", buf);
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +02009059 /* newer wil6210 driver renamed file to "rings" */
Jouni Malinen3aa72862019-05-29 23:14:51 +03009060 res = snprintf(buf, sizeof(buf), "%s/rings", dir);
9061 if (res < 0 || res >= sizeof(buf))
9062 return -1;
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +02009063 f = fopen(buf, "r");
9064 if (!f) {
9065 sigma_dut_print(dut, DUT_MSG_ERROR,
9066 "failed to open: %s", buf);
9067 return -1;
9068 }
Lior David9981b512017-01-20 13:16:40 +02009069 }
9070
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +02009071 /* can be either VRING tx... or RING... */
9072 if (regcomp(&re, "RING tx_[ \t]*([0-9]+)", REG_EXTENDED)) {
Lior David9981b512017-01-20 13:16:40 +02009073 sigma_dut_print(dut, DUT_MSG_ERROR, "regcomp failed");
9074 goto out;
9075 }
9076
9077 /* find TX VRING for the mac address */
9078 found = 0;
9079 while (fgets(buf, sizeof(buf), f)) {
9080 if (strcasestr(buf, dest_mac)) {
9081 found = 1;
9082 break;
9083 }
9084 }
9085
9086 if (!found) {
9087 sigma_dut_print(dut, DUT_MSG_ERROR,
9088 "no TX VRING for %s", dest_mac);
9089 goto out;
9090 }
9091
9092 /* extract VRING ID, "VRING tx_<id> = {" */
9093 if (!fgets(buf, sizeof(buf), f)) {
9094 sigma_dut_print(dut, DUT_MSG_ERROR,
9095 "no VRING start line for %s", dest_mac);
9096 goto out;
9097 }
9098
9099 rc = regexec(&re, buf, 2, m, 0);
9100 regfree(&re);
9101 if (rc || m[1].rm_so < 0) {
9102 sigma_dut_print(dut, DUT_MSG_ERROR,
9103 "no VRING TX ID for %s", dest_mac);
9104 goto out;
9105 }
9106 buf[m[1].rm_eo] = 0;
9107 vring_id = atoi(&buf[m[1].rm_so]);
9108
9109 /* send the addba command */
9110 fclose(f);
Jouni Malinen3aa72862019-05-29 23:14:51 +03009111 res = snprintf(buf, sizeof(buf), "%s/back", dir);
9112 if (res < 0 || res >= sizeof(buf))
9113 return -1;
Lior David9981b512017-01-20 13:16:40 +02009114 f = fopen(buf, "w");
9115 if (!f) {
9116 sigma_dut_print(dut, DUT_MSG_ERROR,
9117 "failed to open: %s", buf);
9118 return -1;
9119 }
9120
9121 fprintf(f, "add %d %d\n", vring_id, agg_size);
9122
9123 ret = 0;
9124
9125out:
9126 fclose(f);
9127
9128 return ret;
9129}
9130
9131
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +02009132int send_addba_60g(struct sigma_dut *dut, struct sigma_conn *conn,
9133 struct sigma_cmd *cmd, const char *mac_param)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009134{
9135 const char *val;
9136 int tid = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009137
9138 val = get_param(cmd, "TID");
9139 if (val) {
9140 tid = atoi(val);
9141 if (tid != 0) {
9142 sigma_dut_print(dut, DUT_MSG_ERROR,
9143 "Ignore TID %d for send_addba use TID 0 for 60g since only 0 required on TX",
9144 tid);
9145 }
9146 }
9147
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +02009148 val = get_param(cmd, mac_param);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009149 if (!val) {
9150 sigma_dut_print(dut, DUT_MSG_ERROR,
9151 "Currently not supporting addba for 60G without Dest_mac");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02009152 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009153 }
9154
Lior David9981b512017-01-20 13:16:40 +02009155 if (wil6210_send_addba(dut, val, dut->back_rcv_buf))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009156 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009157
9158 return 1;
9159}
9160
Lior David9981b512017-01-20 13:16:40 +02009161#endif /* __linux__ */
9162
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009163
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009164static int wcn_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
9165 struct sigma_cmd *cmd)
9166{
9167#ifdef NL80211_SUPPORT
9168 const char *intf = get_param(cmd, "Interface");
9169 const char *val;
9170 int tid = -1;
9171 int bufsize = 64;
9172 struct nl_msg *msg;
9173 int ret = 0;
9174 struct nlattr *params;
9175 int ifindex;
9176
9177 val = get_param(cmd, "TID");
9178 if (val)
9179 tid = atoi(val);
9180
9181 if (tid == -1) {
9182 send_resp(dut, conn, SIGMA_ERROR,
9183 "ErrorCode,sta_send_addba tid invalid");
9184 return 0;
9185 }
9186
9187 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
9188
9189 ifindex = if_nametoindex(intf);
9190 if (ifindex == 0) {
9191 sigma_dut_print(dut, DUT_MSG_ERROR,
9192 "%s: Index for interface %s failed",
9193 __func__, intf);
9194 send_resp(dut, conn, SIGMA_ERROR,
9195 "ErrorCode,sta_send_addba interface invalid");
9196 return 0;
9197 }
9198
9199 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
9200 NL80211_CMD_VENDOR)) ||
9201 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
9202 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
9203 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
9204 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
9205 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
9206 nla_put_u8(msg,
9207 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADD_DEL_BA_SESSION,
9208 QCA_WLAN_ADD_BA) ||
9209 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BA_TID,
9210 tid) ||
Kiran Kumar Lokere26e27582018-08-01 16:18:34 -07009211 nla_put_u16(msg,
9212 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE,
9213 bufsize)) {
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009214 sigma_dut_print(dut, DUT_MSG_ERROR,
9215 "%s: err in adding vendor_cmd and vendor_data",
9216 __func__);
9217 nlmsg_free(msg);
9218 send_resp(dut, conn, SIGMA_ERROR,
9219 "ErrorCode,sta_send_addba err in adding vendor_cmd and vendor_data");
9220 return 0;
9221 }
9222 nla_nest_end(msg, params);
9223
9224 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
9225 if (ret) {
9226 sigma_dut_print(dut, DUT_MSG_ERROR,
9227 "%s: err in send_and_recv_msgs, ret=%d",
9228 __func__, ret);
Sunil Dutt30605592018-05-04 20:35:50 +05309229 if (ret == -EOPNOTSUPP)
9230 return 1;
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009231 send_resp(dut, conn, SIGMA_ERROR,
9232 "ErrorCode,sta_send_addba err in send_and_recv_msgs");
9233 return 0;
9234 }
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009235#else /* NL80211_SUPPORT */
9236 sigma_dut_print(dut, DUT_MSG_ERROR,
9237 "sta_send_addba not supported without NL80211_SUPPORT defined");
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009238#endif /* NL80211_SUPPORT */
Sunil Dutt30605592018-05-04 20:35:50 +05309239
9240 return 1;
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009241}
9242
9243
Jouni Malinenf7222712019-06-13 01:50:21 +03009244static enum sigma_cmd_result cmd_sta_send_addba(struct sigma_dut *dut,
9245 struct sigma_conn *conn,
9246 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009247{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009248 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009249 case DRIVER_ATHEROS:
9250 return ath_sta_send_addba(dut, conn, cmd);
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009251 case DRIVER_WCN:
9252 return wcn_sta_send_addba(dut, conn, cmd);
Lior David9981b512017-01-20 13:16:40 +02009253#ifdef __linux__
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009254 case DRIVER_WIL6210:
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +02009255 return send_addba_60g(dut, conn, cmd, "Dest_mac");
Lior David9981b512017-01-20 13:16:40 +02009256#endif /* __linux__ */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009257 default:
9258 /*
9259 * There is no driver specific implementation for other drivers.
9260 * Ignore the command and report COMPLETE since the following
9261 * throughput test operation will end up sending ADDBA anyway.
9262 */
9263 return 1;
9264 }
9265}
9266
9267
9268int inject_eth_frame(int s, const void *data, size_t len,
9269 unsigned short ethtype, char *dst, char *src)
9270{
9271 struct iovec iov[4] = {
9272 {
9273 .iov_base = dst,
9274 .iov_len = ETH_ALEN,
9275 },
9276 {
9277 .iov_base = src,
9278 .iov_len = ETH_ALEN,
9279 },
9280 {
9281 .iov_base = &ethtype,
9282 .iov_len = sizeof(unsigned short),
9283 },
9284 {
9285 .iov_base = (void *) data,
9286 .iov_len = len,
9287 }
9288 };
9289 struct msghdr msg = {
9290 .msg_name = NULL,
9291 .msg_namelen = 0,
9292 .msg_iov = iov,
9293 .msg_iovlen = 4,
9294 .msg_control = NULL,
9295 .msg_controllen = 0,
9296 .msg_flags = 0,
9297 };
9298
9299 return sendmsg(s, &msg, 0);
9300}
9301
9302#if defined(__linux__) || defined(__QNXNTO__)
9303
9304int inject_frame(int s, const void *data, size_t len, int encrypt)
9305{
9306#define IEEE80211_RADIOTAP_F_WEP 0x04
9307#define IEEE80211_RADIOTAP_F_FRAG 0x08
9308 unsigned char rtap_hdr[] = {
9309 0x00, 0x00, /* radiotap version */
9310 0x0e, 0x00, /* radiotap length */
9311 0x02, 0xc0, 0x00, 0x00, /* bmap: flags, tx and rx flags */
9312 IEEE80211_RADIOTAP_F_FRAG, /* F_FRAG (fragment if required) */
9313 0x00, /* padding */
9314 0x00, 0x00, /* RX and TX flags to indicate that */
9315 0x00, 0x00, /* this is the injected frame directly */
9316 };
9317 struct iovec iov[2] = {
9318 {
9319 .iov_base = &rtap_hdr,
9320 .iov_len = sizeof(rtap_hdr),
9321 },
9322 {
9323 .iov_base = (void *) data,
9324 .iov_len = len,
9325 }
9326 };
9327 struct msghdr msg = {
9328 .msg_name = NULL,
9329 .msg_namelen = 0,
9330 .msg_iov = iov,
9331 .msg_iovlen = 2,
9332 .msg_control = NULL,
9333 .msg_controllen = 0,
9334 .msg_flags = 0,
9335 };
9336
9337 if (encrypt)
9338 rtap_hdr[8] |= IEEE80211_RADIOTAP_F_WEP;
9339
9340 return sendmsg(s, &msg, 0);
9341}
9342
9343
9344int open_monitor(const char *ifname)
9345{
9346#ifdef __QNXNTO__
9347 struct sockaddr_dl ll;
9348 int s;
9349
9350 memset(&ll, 0, sizeof(ll));
9351 ll.sdl_family = AF_LINK;
9352 ll.sdl_index = if_nametoindex(ifname);
9353 if (ll.sdl_index == 0) {
9354 perror("if_nametoindex");
9355 return -1;
9356 }
9357 s = socket(PF_INET, SOCK_RAW, 0);
9358#else /* __QNXNTO__ */
9359 struct sockaddr_ll ll;
9360 int s;
9361
9362 memset(&ll, 0, sizeof(ll));
9363 ll.sll_family = AF_PACKET;
9364 ll.sll_ifindex = if_nametoindex(ifname);
9365 if (ll.sll_ifindex == 0) {
9366 perror("if_nametoindex");
9367 return -1;
9368 }
9369 s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
9370#endif /* __QNXNTO__ */
9371 if (s < 0) {
9372 perror("socket[PF_PACKET,SOCK_RAW]");
9373 return -1;
9374 }
9375
9376 if (bind(s, (struct sockaddr *) &ll, sizeof(ll)) < 0) {
9377 perror("monitor socket bind");
9378 close(s);
9379 return -1;
9380 }
9381
9382 return s;
9383}
9384
9385
9386static int hex2num(char c)
9387{
9388 if (c >= '0' && c <= '9')
9389 return c - '0';
9390 if (c >= 'a' && c <= 'f')
9391 return c - 'a' + 10;
9392 if (c >= 'A' && c <= 'F')
9393 return c - 'A' + 10;
9394 return -1;
9395}
9396
9397
9398int hwaddr_aton(const char *txt, unsigned char *addr)
9399{
9400 int i;
9401
9402 for (i = 0; i < 6; i++) {
9403 int a, b;
9404
9405 a = hex2num(*txt++);
9406 if (a < 0)
9407 return -1;
9408 b = hex2num(*txt++);
9409 if (b < 0)
9410 return -1;
9411 *addr++ = (a << 4) | b;
9412 if (i < 5 && *txt++ != ':')
9413 return -1;
9414 }
9415
9416 return 0;
9417}
9418
9419#endif /* defined(__linux__) || defined(__QNXNTO__) */
9420
9421enum send_frame_type {
9422 DISASSOC, DEAUTH, SAQUERY, AUTH, ASSOCREQ, REASSOCREQ, DLS_REQ
9423};
9424enum send_frame_protection {
9425 CORRECT_KEY, INCORRECT_KEY, UNPROTECTED
9426};
9427
9428
9429static int sta_inject_frame(struct sigma_dut *dut, struct sigma_conn *conn,
9430 enum send_frame_type frame,
9431 enum send_frame_protection protected,
9432 const char *dest)
9433{
9434#ifdef __linux__
9435 unsigned char buf[1000], *pos;
9436 int s, res;
9437 char bssid[20], addr[20];
9438 char result[32], ssid[100];
9439 size_t ssid_len;
9440
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009441 if (get_wpa_status(get_station_ifname(dut), "wpa_state", result,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009442 sizeof(result)) < 0 ||
9443 strncmp(result, "COMPLETED", 9) != 0) {
9444 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Not connected");
9445 return 0;
9446 }
9447
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009448 if (get_wpa_status(get_station_ifname(dut), "bssid",
9449 bssid, sizeof(bssid)) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009450 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
9451 "current BSSID");
9452 return 0;
9453 }
9454
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009455 if (get_wpa_status(get_station_ifname(dut), "address",
9456 addr, sizeof(addr)) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009457 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
9458 "own MAC address");
9459 return 0;
9460 }
9461
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009462 if (get_wpa_status(get_station_ifname(dut), "ssid", ssid, sizeof(ssid))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009463 < 0) {
9464 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
9465 "current SSID");
9466 return 0;
9467 }
9468 ssid_len = strlen(ssid);
9469
9470 pos = buf;
9471
9472 /* Frame Control */
9473 switch (frame) {
9474 case DISASSOC:
9475 *pos++ = 0xa0;
9476 break;
9477 case DEAUTH:
9478 *pos++ = 0xc0;
9479 break;
9480 case SAQUERY:
9481 *pos++ = 0xd0;
9482 break;
9483 case AUTH:
9484 *pos++ = 0xb0;
9485 break;
9486 case ASSOCREQ:
9487 *pos++ = 0x00;
9488 break;
9489 case REASSOCREQ:
9490 *pos++ = 0x20;
9491 break;
9492 case DLS_REQ:
9493 *pos++ = 0xd0;
9494 break;
9495 }
9496
9497 if (protected == INCORRECT_KEY)
9498 *pos++ = 0x40; /* Set Protected field to 1 */
9499 else
9500 *pos++ = 0x00;
9501
9502 /* Duration */
9503 *pos++ = 0x00;
9504 *pos++ = 0x00;
9505
9506 /* addr1 = DA (current AP) */
9507 hwaddr_aton(bssid, pos);
9508 pos += 6;
9509 /* addr2 = SA (own address) */
9510 hwaddr_aton(addr, pos);
9511 pos += 6;
9512 /* addr3 = BSSID (current AP) */
9513 hwaddr_aton(bssid, pos);
9514 pos += 6;
9515
9516 /* Seq# (to be filled by driver/mac80211) */
9517 *pos++ = 0x00;
9518 *pos++ = 0x00;
9519
9520 if (protected == INCORRECT_KEY) {
9521 /* CCMP parameters */
9522 memcpy(pos, "\x61\x01\x00\x20\x00\x10\x00\x00", 8);
9523 pos += 8;
9524 }
9525
9526 if (protected == INCORRECT_KEY) {
9527 switch (frame) {
9528 case DEAUTH:
9529 /* Reason code (encrypted) */
9530 memcpy(pos, "\xa7\x39", 2);
9531 pos += 2;
9532 break;
9533 case DISASSOC:
9534 /* Reason code (encrypted) */
9535 memcpy(pos, "\xa7\x39", 2);
9536 pos += 2;
9537 break;
9538 case SAQUERY:
9539 /* Category|Action|TransID (encrypted) */
9540 memcpy(pos, "\x6f\xbd\xe9\x4d", 4);
9541 pos += 4;
9542 break;
9543 default:
9544 return -1;
9545 }
9546
9547 /* CCMP MIC */
9548 memcpy(pos, "\xc8\xd8\x3b\x06\x5d\xb7\x25\x68", 8);
9549 pos += 8;
9550 } else {
9551 switch (frame) {
9552 case DEAUTH:
9553 /* reason code = 8 */
9554 *pos++ = 0x08;
9555 *pos++ = 0x00;
9556 break;
9557 case DISASSOC:
9558 /* reason code = 8 */
9559 *pos++ = 0x08;
9560 *pos++ = 0x00;
9561 break;
9562 case SAQUERY:
9563 /* Category - SA Query */
9564 *pos++ = 0x08;
9565 /* SA query Action - Request */
9566 *pos++ = 0x00;
9567 /* Transaction ID */
9568 *pos++ = 0x12;
9569 *pos++ = 0x34;
9570 break;
9571 case AUTH:
9572 /* Auth Alg (Open) */
9573 *pos++ = 0x00;
9574 *pos++ = 0x00;
9575 /* Seq# */
9576 *pos++ = 0x01;
9577 *pos++ = 0x00;
9578 /* Status code */
9579 *pos++ = 0x00;
9580 *pos++ = 0x00;
9581 break;
9582 case ASSOCREQ:
9583 /* Capability Information */
9584 *pos++ = 0x31;
9585 *pos++ = 0x04;
9586 /* Listen Interval */
9587 *pos++ = 0x0a;
9588 *pos++ = 0x00;
9589 /* SSID */
9590 *pos++ = 0x00;
9591 *pos++ = ssid_len;
9592 memcpy(pos, ssid, ssid_len);
9593 pos += ssid_len;
9594 /* Supported Rates */
9595 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
9596 10);
9597 pos += 10;
9598 /* Extended Supported Rates */
9599 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
9600 pos += 6;
9601 /* RSN */
9602 memcpy(pos, "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00"
9603 "\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x02\xc0"
9604 "\x00\x00\x00\x00\x0f\xac\x06", 28);
9605 pos += 28;
9606 break;
9607 case REASSOCREQ:
9608 /* Capability Information */
9609 *pos++ = 0x31;
9610 *pos++ = 0x04;
9611 /* Listen Interval */
9612 *pos++ = 0x0a;
9613 *pos++ = 0x00;
9614 /* Current AP */
9615 hwaddr_aton(bssid, pos);
9616 pos += 6;
9617 /* SSID */
9618 *pos++ = 0x00;
9619 *pos++ = ssid_len;
9620 memcpy(pos, ssid, ssid_len);
9621 pos += ssid_len;
9622 /* Supported Rates */
9623 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
9624 10);
9625 pos += 10;
9626 /* Extended Supported Rates */
9627 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
9628 pos += 6;
9629 /* RSN */
9630 memcpy(pos, "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00"
9631 "\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x02\xc0"
9632 "\x00\x00\x00\x00\x0f\xac\x06", 28);
9633 pos += 28;
9634 break;
9635 case DLS_REQ:
9636 /* Category - DLS */
9637 *pos++ = 0x02;
9638 /* DLS Action - Request */
9639 *pos++ = 0x00;
9640 /* Destination MACAddress */
9641 if (dest)
9642 hwaddr_aton(dest, pos);
9643 else
9644 memset(pos, 0, 6);
9645 pos += 6;
9646 /* Source MACAddress */
9647 hwaddr_aton(addr, pos);
9648 pos += 6;
9649 /* Capability Information */
9650 *pos++ = 0x10; /* Privacy */
9651 *pos++ = 0x06; /* QoS */
9652 /* DLS Timeout Value */
9653 *pos++ = 0x00;
9654 *pos++ = 0x01;
9655 /* Supported rates */
9656 *pos++ = 0x01;
9657 *pos++ = 0x08;
9658 *pos++ = 0x0c; /* 6 Mbps */
9659 *pos++ = 0x12; /* 9 Mbps */
9660 *pos++ = 0x18; /* 12 Mbps */
9661 *pos++ = 0x24; /* 18 Mbps */
9662 *pos++ = 0x30; /* 24 Mbps */
9663 *pos++ = 0x48; /* 36 Mbps */
9664 *pos++ = 0x60; /* 48 Mbps */
9665 *pos++ = 0x6c; /* 54 Mbps */
9666 /* TODO: Extended Supported Rates */
9667 /* TODO: HT Capabilities */
9668 break;
9669 }
9670 }
9671
9672 s = open_monitor("sigmadut");
9673 if (s < 0) {
9674 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
9675 "monitor socket");
9676 return 0;
9677 }
9678
9679 res = inject_frame(s, buf, pos - buf, protected == CORRECT_KEY);
9680 if (res < 0) {
9681 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
9682 "inject frame");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05309683 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009684 return 0;
9685 }
9686 if (res < pos - buf) {
9687 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Only partial "
9688 "frame sent");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05309689 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009690 return 0;
9691 }
9692
9693 close(s);
9694
9695 return 1;
9696#else /* __linux__ */
9697 send_resp(dut, conn, SIGMA_ERROR, "errorCode,sta_send_frame not "
9698 "yet supported");
9699 return 0;
9700#endif /* __linux__ */
9701}
9702
9703
9704static int cmd_sta_send_frame_tdls(struct sigma_dut *dut,
9705 struct sigma_conn *conn,
9706 struct sigma_cmd *cmd)
9707{
9708 const char *intf = get_param(cmd, "Interface");
9709 const char *sta, *val;
9710 unsigned char addr[ETH_ALEN];
9711 char buf[100];
9712
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +03009713 if (!intf)
9714 return -1;
9715
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009716 sta = get_param(cmd, "peer");
9717 if (sta == NULL)
9718 sta = get_param(cmd, "station");
9719 if (sta == NULL) {
9720 send_resp(dut, conn, SIGMA_ERROR,
9721 "ErrorCode,Missing peer address");
9722 return 0;
9723 }
9724 if (hwaddr_aton(sta, addr) < 0) {
9725 send_resp(dut, conn, SIGMA_ERROR,
9726 "ErrorCode,Invalid peer address");
9727 return 0;
9728 }
9729
9730 val = get_param(cmd, "type");
9731 if (val == NULL)
9732 return -1;
9733
9734 if (strcasecmp(val, "DISCOVERY") == 0) {
9735 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", sta);
9736 if (wpa_command(intf, buf) < 0) {
9737 send_resp(dut, conn, SIGMA_ERROR,
9738 "ErrorCode,Failed to send TDLS discovery");
9739 return 0;
9740 }
9741 return 1;
9742 }
9743
9744 if (strcasecmp(val, "SETUP") == 0) {
9745 int status = 0, timeout = 0;
9746
9747 val = get_param(cmd, "Status");
9748 if (val)
9749 status = atoi(val);
9750
9751 val = get_param(cmd, "Timeout");
9752 if (val)
9753 timeout = atoi(val);
9754
9755 if (status != 0 && status != 37) {
9756 send_resp(dut, conn, SIGMA_ERROR,
9757 "ErrorCode,Unsupported status value");
9758 return 0;
9759 }
9760
9761 if (timeout != 0 && timeout != 301) {
9762 send_resp(dut, conn, SIGMA_ERROR,
9763 "ErrorCode,Unsupported timeout value");
9764 return 0;
9765 }
9766
9767 if (status && timeout) {
9768 send_resp(dut, conn, SIGMA_ERROR,
9769 "ErrorCode,Unsupported timeout+status "
9770 "combination");
9771 return 0;
9772 }
9773
9774 if (status == 37 &&
9775 wpa_command(intf, "SET tdls_testing 0x200")) {
9776 send_resp(dut, conn, SIGMA_ERROR,
9777 "ErrorCode,Failed to enable "
9778 "decline setup response test mode");
9779 return 0;
9780 }
9781
9782 if (timeout == 301) {
9783 int res;
9784 if (dut->no_tpk_expiration)
9785 res = wpa_command(intf,
9786 "SET tdls_testing 0x108");
9787 else
9788 res = wpa_command(intf,
9789 "SET tdls_testing 0x8");
9790 if (res) {
9791 send_resp(dut, conn, SIGMA_ERROR,
9792 "ErrorCode,Failed to set short TPK "
9793 "lifetime");
9794 return 0;
9795 }
9796 }
9797
9798 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", sta);
9799 if (wpa_command(intf, buf) < 0) {
9800 send_resp(dut, conn, SIGMA_ERROR,
9801 "ErrorCode,Failed to send TDLS setup");
9802 return 0;
9803 }
9804 return 1;
9805 }
9806
9807 if (strcasecmp(val, "TEARDOWN") == 0) {
9808 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", sta);
9809 if (wpa_command(intf, buf) < 0) {
9810 send_resp(dut, conn, SIGMA_ERROR,
9811 "ErrorCode,Failed to send TDLS teardown");
9812 return 0;
9813 }
9814 return 1;
9815 }
9816
9817 send_resp(dut, conn, SIGMA_ERROR,
9818 "ErrorCode,Unsupported TDLS frame");
9819 return 0;
9820}
9821
9822
9823static int sta_ap_known(const char *ifname, const char *bssid)
9824{
9825 char buf[4096];
9826
Jouni Malinendd32f192018-09-15 02:55:19 +03009827 snprintf(buf, sizeof(buf), "BSS MASK=1 %s", bssid);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009828 if (wpa_command_resp(ifname, buf, buf, sizeof(buf)) < 0)
9829 return 0;
9830 if (strncmp(buf, "id=", 3) != 0)
9831 return 0;
9832 return 1;
9833}
9834
9835
9836static int sta_scan_ap(struct sigma_dut *dut, const char *ifname,
9837 const char *bssid)
9838{
9839 int res;
9840 struct wpa_ctrl *ctrl;
9841 char buf[256];
9842
9843 if (sta_ap_known(ifname, bssid))
9844 return 0;
9845 sigma_dut_print(dut, DUT_MSG_DEBUG,
9846 "AP not in BSS table - start scan");
9847
9848 ctrl = open_wpa_mon(ifname);
9849 if (ctrl == NULL) {
9850 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
9851 "wpa_supplicant monitor connection");
9852 return -1;
9853 }
9854
9855 if (wpa_command(ifname, "SCAN") < 0) {
9856 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to start scan");
9857 wpa_ctrl_detach(ctrl);
9858 wpa_ctrl_close(ctrl);
9859 return -1;
9860 }
9861
9862 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
9863 buf, sizeof(buf));
9864
9865 wpa_ctrl_detach(ctrl);
9866 wpa_ctrl_close(ctrl);
9867
9868 if (res < 0) {
9869 sigma_dut_print(dut, DUT_MSG_INFO, "Scan did not complete");
9870 return -1;
9871 }
9872
9873 if (sta_ap_known(ifname, bssid))
9874 return 0;
9875 sigma_dut_print(dut, DUT_MSG_INFO, "AP not in BSS table");
9876 return -1;
9877}
9878
9879
9880static int cmd_sta_send_frame_hs2_neighadv(struct sigma_dut *dut,
9881 struct sigma_conn *conn,
9882 struct sigma_cmd *cmd,
9883 const char *intf)
9884{
9885 char buf[200];
9886
9887 snprintf(buf, sizeof(buf), "ndsend 2001:DB8::1 %s", intf);
9888 if (system(buf) != 0) {
9889 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Failed to run "
9890 "ndsend");
9891 return 0;
9892 }
9893
9894 return 1;
9895}
9896
9897
9898static int cmd_sta_send_frame_hs2_neighsolreq(struct sigma_dut *dut,
9899 struct sigma_conn *conn,
9900 struct sigma_cmd *cmd,
9901 const char *intf)
9902{
9903 char buf[200];
9904 const char *ip = get_param(cmd, "SenderIP");
9905
Peng Xu26b356d2017-10-04 17:58:16 -07009906 if (!ip)
9907 return 0;
9908
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009909 snprintf(buf, sizeof(buf), "ndisc6 -nm %s %s -r 4", ip, intf);
9910 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
9911 if (system(buf) == 0) {
9912 sigma_dut_print(dut, DUT_MSG_INFO,
9913 "Neighbor Solicitation got a response "
9914 "for %s@%s", ip, intf);
9915 }
9916
9917 return 1;
9918}
9919
9920
9921static int cmd_sta_send_frame_hs2_arpprobe(struct sigma_dut *dut,
9922 struct sigma_conn *conn,
9923 struct sigma_cmd *cmd,
9924 const char *ifname)
9925{
9926 char buf[200];
9927 const char *ip = get_param(cmd, "SenderIP");
9928
9929 if (ip == NULL) {
9930 send_resp(dut, conn, SIGMA_ERROR,
9931 "ErrorCode,Missing SenderIP parameter");
9932 return 0;
9933 }
9934 snprintf(buf, sizeof(buf), "arping -I %s -D %s -c 4", ifname, ip);
9935 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
9936 if (system(buf) != 0) {
9937 sigma_dut_print(dut, DUT_MSG_INFO, "arping DAD got a response "
9938 "for %s@%s", ip, ifname);
9939 }
9940
9941 return 1;
9942}
9943
9944
9945static int cmd_sta_send_frame_hs2_arpannounce(struct sigma_dut *dut,
9946 struct sigma_conn *conn,
9947 struct sigma_cmd *cmd,
9948 const char *ifname)
9949{
9950 char buf[200];
9951 char ip[16];
9952 int s;
Peng Xub3756882017-10-04 14:39:09 -07009953 struct ifreq ifr;
9954 struct sockaddr_in saddr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009955
9956 s = socket(PF_INET, SOCK_DGRAM, 0);
Peng Xub3756882017-10-04 14:39:09 -07009957 if (s < 0) {
9958 perror("socket");
9959 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009960 }
9961
Peng Xub3756882017-10-04 14:39:09 -07009962 memset(&ifr, 0, sizeof(ifr));
9963 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
9964 if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
9965 sigma_dut_print(dut, DUT_MSG_INFO,
9966 "Failed to get %s IP address: %s",
9967 ifname, strerror(errno));
9968 close(s);
9969 return -1;
9970 }
9971 close(s);
9972
9973 memcpy(&saddr, &ifr.ifr_addr, sizeof(struct sockaddr_in));
9974 strlcpy(ip, inet_ntoa(saddr.sin_addr), sizeof(ip));
9975
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009976 snprintf(buf, sizeof(buf), "arping -I %s -s %s %s -c 4", ifname, ip,
9977 ip);
9978 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
9979 if (system(buf) != 0) {
9980 }
9981
9982 return 1;
9983}
9984
9985
9986static int cmd_sta_send_frame_hs2_arpreply(struct sigma_dut *dut,
9987 struct sigma_conn *conn,
9988 struct sigma_cmd *cmd,
9989 const char *ifname)
9990{
9991 char buf[200], addr[20];
9992 char dst[ETH_ALEN], src[ETH_ALEN];
9993 short ethtype = htons(ETH_P_ARP);
9994 char *pos;
9995 int s, res;
9996 const char *val;
9997 struct sockaddr_in taddr;
9998
9999 val = get_param(cmd, "dest");
10000 if (val)
10001 hwaddr_aton(val, (unsigned char *) dst);
10002
10003 val = get_param(cmd, "DestIP");
10004 if (val)
10005 inet_aton(val, &taddr.sin_addr);
Peng Xu151c9e12017-10-04 14:39:09 -070010006 else
10007 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010008
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010009 if (get_wpa_status(get_station_ifname(dut), "address", addr,
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010010 sizeof(addr)) < 0)
10011 return -2;
10012 hwaddr_aton(addr, (unsigned char *) src);
10013
10014 pos = buf;
10015 *pos++ = 0x00;
10016 *pos++ = 0x01;
10017 *pos++ = 0x08;
10018 *pos++ = 0x00;
10019 *pos++ = 0x06;
10020 *pos++ = 0x04;
10021 *pos++ = 0x00;
10022 *pos++ = 0x02;
10023 memcpy(pos, src, ETH_ALEN);
10024 pos += ETH_ALEN;
10025 memcpy(pos, &taddr.sin_addr, 4);
10026 pos += 4;
10027 memcpy(pos, dst, ETH_ALEN);
10028 pos += ETH_ALEN;
10029 memcpy(pos, &taddr.sin_addr, 4);
10030 pos += 4;
10031
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010032 s = open_monitor(get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010033 if (s < 0) {
10034 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
10035 "monitor socket");
10036 return 0;
10037 }
10038
10039 res = inject_eth_frame(s, buf, pos - buf, ethtype, dst, src);
10040 if (res < 0) {
10041 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
10042 "inject frame");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +053010043 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010044 return 0;
10045 }
10046
10047 close(s);
10048
10049 return 1;
10050}
10051
10052
10053static int cmd_sta_send_frame_hs2_dls_req(struct sigma_dut *dut,
10054 struct sigma_conn *conn,
10055 struct sigma_cmd *cmd,
10056 const char *intf, const char *dest)
10057{
10058 char buf[100];
10059
10060 if (if_nametoindex("sigmadut") == 0) {
10061 snprintf(buf, sizeof(buf),
10062 "iw dev %s interface add sigmadut type monitor",
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010063 get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010064 if (system(buf) != 0 ||
10065 if_nametoindex("sigmadut") == 0) {
10066 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
10067 "monitor interface with '%s'", buf);
10068 return -2;
10069 }
10070 }
10071
10072 if (system("ifconfig sigmadut up") != 0) {
10073 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
10074 "monitor interface up");
10075 return -2;
10076 }
10077
10078 return sta_inject_frame(dut, conn, DLS_REQ, UNPROTECTED, dest);
10079}
10080
10081
10082static int cmd_sta_send_frame_hs2(struct sigma_dut *dut,
10083 struct sigma_conn *conn,
10084 struct sigma_cmd *cmd)
10085{
10086 const char *intf = get_param(cmd, "Interface");
10087 const char *dest = get_param(cmd, "Dest");
10088 const char *type = get_param(cmd, "FrameName");
10089 const char *val;
10090 char buf[200], *pos, *end;
10091 int count, count2;
10092
10093 if (type == NULL)
10094 type = get_param(cmd, "Type");
10095
10096 if (intf == NULL || dest == NULL || type == NULL)
10097 return -1;
10098
10099 if (strcasecmp(type, "NeighAdv") == 0)
10100 return cmd_sta_send_frame_hs2_neighadv(dut, conn, cmd, intf);
10101
10102 if (strcasecmp(type, "NeighSolicitReq") == 0)
10103 return cmd_sta_send_frame_hs2_neighsolreq(dut, conn, cmd, intf);
10104
10105 if (strcasecmp(type, "ARPProbe") == 0)
10106 return cmd_sta_send_frame_hs2_arpprobe(dut, conn, cmd, intf);
10107
10108 if (strcasecmp(type, "ARPAnnounce") == 0)
10109 return cmd_sta_send_frame_hs2_arpannounce(dut, conn, cmd, intf);
10110
10111 if (strcasecmp(type, "ARPReply") == 0)
10112 return cmd_sta_send_frame_hs2_arpreply(dut, conn, cmd, intf);
10113
10114 if (strcasecmp(type, "DLS-request") == 0 ||
10115 strcasecmp(type, "DLSrequest") == 0)
10116 return cmd_sta_send_frame_hs2_dls_req(dut, conn, cmd, intf,
10117 dest);
10118
10119 if (strcasecmp(type, "ANQPQuery") != 0 &&
10120 strcasecmp(type, "Query") != 0) {
10121 send_resp(dut, conn, SIGMA_ERROR,
10122 "ErrorCode,Unsupported HS 2.0 send frame type");
10123 return 0;
10124 }
10125
10126 if (sta_scan_ap(dut, intf, dest) < 0) {
10127 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not find "
10128 "the requested AP");
10129 return 0;
10130 }
10131
10132 pos = buf;
10133 end = buf + sizeof(buf);
10134 count = 0;
10135 pos += snprintf(pos, end - pos, "ANQP_GET %s ", dest);
10136
10137 val = get_param(cmd, "ANQP_CAP_LIST");
10138 if (val && atoi(val)) {
10139 pos += snprintf(pos, end - pos, "%s257", count > 0 ? "," : "");
10140 count++;
10141 }
10142
10143 val = get_param(cmd, "VENUE_NAME");
10144 if (val && atoi(val)) {
10145 pos += snprintf(pos, end - pos, "%s258", count > 0 ? "," : "");
10146 count++;
10147 }
10148
10149 val = get_param(cmd, "NETWORK_AUTH_TYPE");
10150 if (val && atoi(val)) {
10151 pos += snprintf(pos, end - pos, "%s260", count > 0 ? "," : "");
10152 count++;
10153 }
10154
10155 val = get_param(cmd, "ROAMING_CONS");
10156 if (val && atoi(val)) {
10157 pos += snprintf(pos, end - pos, "%s261", count > 0 ? "," : "");
10158 count++;
10159 }
10160
10161 val = get_param(cmd, "IP_ADDR_TYPE_AVAILABILITY");
10162 if (val && atoi(val)) {
10163 pos += snprintf(pos, end - pos, "%s262", count > 0 ? "," : "");
10164 count++;
10165 }
10166
10167 val = get_param(cmd, "NAI_REALM_LIST");
10168 if (val && atoi(val)) {
10169 pos += snprintf(pos, end - pos, "%s263", count > 0 ? "," : "");
10170 count++;
10171 }
10172
10173 val = get_param(cmd, "3GPP_INFO");
10174 if (val && atoi(val)) {
10175 pos += snprintf(pos, end - pos, "%s264", count > 0 ? "," : "");
10176 count++;
10177 }
10178
10179 val = get_param(cmd, "DOMAIN_LIST");
10180 if (val && atoi(val)) {
10181 pos += snprintf(pos, end - pos, "%s268", count > 0 ? "," : "");
10182 count++;
10183 }
10184
Jouni Malinen34cf9532018-04-29 19:26:33 +030010185 val = get_param(cmd, "Venue_URL");
10186 if (val && atoi(val)) {
10187 pos += snprintf(pos, end - pos, "%s277", count > 0 ? "," : "");
10188 count++;
10189 }
10190
Jouni Malinend3bca5d2018-04-29 17:25:23 +030010191 val = get_param(cmd, "Advice_Of_Charge");
10192 if (val && atoi(val)) {
10193 pos += snprintf(pos, end - pos, "%s278", count > 0 ? "," : "");
10194 count++;
10195 }
10196
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010197 if (count && wpa_command(intf, buf)) {
10198 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,ANQP_GET failed");
10199 return 0;
10200 }
10201
10202 pos = buf;
10203 end = buf + sizeof(buf);
10204 count2 = 0;
10205 pos += snprintf(pos, end - pos, "HS20_ANQP_GET %s ", dest);
10206
10207 val = get_param(cmd, "HS_CAP_LIST");
10208 if (val && atoi(val)) {
10209 pos += snprintf(pos, end - pos, "%s2", count2 > 0 ? "," : "");
10210 count2++;
10211 }
10212
10213 val = get_param(cmd, "OPER_NAME");
10214 if (val && atoi(val)) {
10215 pos += snprintf(pos, end - pos, "%s3", count2 > 0 ? "," : "");
10216 count2++;
10217 }
10218
10219 val = get_param(cmd, "WAN_METRICS");
10220 if (!val)
10221 val = get_param(cmd, "WAN_MAT");
10222 if (!val)
10223 val = get_param(cmd, "WAN_MET");
10224 if (val && atoi(val)) {
10225 pos += snprintf(pos, end - pos, "%s4", count2 > 0 ? "," : "");
10226 count2++;
10227 }
10228
10229 val = get_param(cmd, "CONNECTION_CAPABILITY");
10230 if (val && atoi(val)) {
10231 pos += snprintf(pos, end - pos, "%s5", count2 > 0 ? "," : "");
10232 count2++;
10233 }
10234
10235 val = get_param(cmd, "OP_CLASS");
10236 if (val && atoi(val)) {
10237 pos += snprintf(pos, end - pos, "%s7", count2 > 0 ? "," : "");
10238 count2++;
10239 }
10240
10241 val = get_param(cmd, "OSU_PROVIDER_LIST");
10242 if (val && atoi(val)) {
10243 pos += snprintf(pos, end - pos, "%s8", count2 > 0 ? "," : "");
10244 count2++;
10245 }
10246
Jouni Malinenf67afec2018-04-29 19:24:58 +030010247 val = get_param(cmd, "OPER_ICON_METADATA");
10248 if (!val)
10249 val = get_param(cmd, "OPERATOR_ICON_METADATA");
10250 if (val && atoi(val)) {
10251 pos += snprintf(pos, end - pos, "%s12", count2 > 0 ? "," : "");
10252 count2++;
10253 }
10254
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010255 if (count && count2) {
10256 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before sending out "
10257 "second query");
10258 sleep(1);
10259 }
10260
10261 if (count2 && wpa_command(intf, buf)) {
10262 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,HS20_ANQP_GET "
10263 "failed");
10264 return 0;
10265 }
10266
10267 val = get_param(cmd, "NAI_HOME_REALM_LIST");
10268 if (val) {
10269 if (count || count2) {
10270 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
10271 "sending out second query");
10272 sleep(1);
10273 }
10274
10275 if (strcmp(val, "1") == 0)
10276 val = "mail.example.com";
10277 snprintf(buf, end - pos,
10278 "HS20_GET_NAI_HOME_REALM_LIST %s realm=%s",
10279 dest, val);
10280 if (wpa_command(intf, buf)) {
10281 send_resp(dut, conn, SIGMA_ERROR,
10282 "ErrorCode,HS20_GET_NAI_HOME_REALM_LIST "
10283 "failed");
10284 return 0;
10285 }
10286 }
10287
10288 val = get_param(cmd, "ICON_REQUEST");
10289 if (val) {
10290 if (count || count2) {
10291 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
10292 "sending out second query");
10293 sleep(1);
10294 }
10295
10296 snprintf(buf, end - pos,
10297 "HS20_ICON_REQUEST %s %s", dest, val);
10298 if (wpa_command(intf, buf)) {
10299 send_resp(dut, conn, SIGMA_ERROR,
10300 "ErrorCode,HS20_ICON_REQUEST failed");
10301 return 0;
10302 }
10303 }
10304
10305 return 1;
10306}
10307
10308
10309static int ath_sta_send_frame_vht(struct sigma_dut *dut,
10310 struct sigma_conn *conn,
10311 struct sigma_cmd *cmd)
10312{
10313 const char *val;
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010314 const char *ifname;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010315 int chwidth, nss;
10316
10317 val = get_param(cmd, "framename");
10318 if (!val)
10319 return -1;
10320 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
10321
10322 /* Command sequence to generate Op mode notification */
10323 if (val && strcasecmp(val, "Op_md_notif_frm") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010324 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010325
10326 /* Disable STBC */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010327 run_iwpriv(dut, ifname, "tx_stbc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010328
10329 /* Extract Channel width */
10330 val = get_param(cmd, "Channel_width");
10331 if (val) {
10332 switch (atoi(val)) {
10333 case 20:
10334 chwidth = 0;
10335 break;
10336 case 40:
10337 chwidth = 1;
10338 break;
10339 case 80:
10340 chwidth = 2;
10341 break;
10342 case 160:
10343 chwidth = 3;
10344 break;
10345 default:
10346 chwidth = 2;
10347 break;
10348 }
10349
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010350 run_iwpriv(dut, ifname, "chwidth %d", chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010351 }
10352
10353 /* Extract NSS */
10354 val = get_param(cmd, "NSS");
10355 if (val) {
10356 switch (atoi(val)) {
10357 case 1:
10358 nss = 1;
10359 break;
10360 case 2:
10361 nss = 3;
10362 break;
10363 case 3:
10364 nss = 7;
10365 break;
10366 default:
10367 /* We do not support NSS > 3 */
10368 nss = 3;
10369 break;
10370 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010371 run_iwpriv(dut, ifname, "rxchainmask %d", nss);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010372 }
10373
10374 /* Opmode notify */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010375 run_iwpriv(dut, ifname, "opmode_notify 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010376 }
10377
10378 return 1;
10379}
10380
10381
10382static int cmd_sta_send_frame_vht(struct sigma_dut *dut,
10383 struct sigma_conn *conn,
10384 struct sigma_cmd *cmd)
10385{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010386 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010387 case DRIVER_ATHEROS:
10388 return ath_sta_send_frame_vht(dut, conn, cmd);
10389 default:
10390 send_resp(dut, conn, SIGMA_ERROR,
10391 "errorCode,Unsupported sta_set_frame(VHT) with the current driver");
10392 return 0;
10393 }
10394}
10395
10396
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070010397static int wcn_sta_send_frame_he(struct sigma_dut *dut, struct sigma_conn *conn,
10398 struct sigma_cmd *cmd)
10399{
10400 const char *val;
10401 const char *intf = get_param(cmd, "Interface");
10402
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +030010403 if (!intf)
10404 return -1;
10405
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070010406 val = get_param(cmd, "framename");
10407 if (!val)
10408 return -1;
10409 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
10410
10411 /* Command sequence to generate Op mode notification */
10412 if (val && strcasecmp(val, "action") == 0) {
10413 val = get_param(cmd, "PPDUTxType");
10414 if (val && strcasecmp(val, "TB") == 0) {
10415 if (sta_set_action_tx_in_he_tb_ppdu(dut, intf, 1)) {
10416 sigma_dut_print(dut, DUT_MSG_ERROR,
10417 "failed to send TB PPDU Tx cfg");
10418 send_resp(dut, conn, SIGMA_ERROR,
10419 "ErrorCode,set TB PPDU Tx cfg failed");
10420 return 0;
10421 }
10422 return 1;
10423 }
10424
10425 sigma_dut_print(dut, DUT_MSG_ERROR,
10426 "Action Tx type is not defined");
10427 }
10428
10429 return 1;
10430}
10431
10432
10433static int cmd_sta_send_frame_he(struct sigma_dut *dut,
10434 struct sigma_conn *conn,
10435 struct sigma_cmd *cmd)
10436{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010437 switch (get_driver_type(dut)) {
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070010438 case DRIVER_WCN:
10439 return wcn_sta_send_frame_he(dut, conn, cmd);
10440 default:
10441 send_resp(dut, conn, SIGMA_ERROR,
10442 "errorCode,Unsupported sta_set_frame(HE) with the current driver");
10443 return 0;
10444 }
10445}
10446
10447
Lior David0fe101e2017-03-09 16:09:50 +020010448#ifdef __linux__
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030010449
10450static int
10451wil6210_send_p2p_frame_60g(struct sigma_dut *dut, struct sigma_cmd *cmd,
10452 const char *frame_name, const char *dest_mac)
10453{
10454 int isprobereq = strcasecmp(frame_name, "probereq") == 0;
10455 const char *ssid = get_param(cmd, "ssid");
10456 const char *countstr = get_param(cmd, "count");
10457 const char *channelstr = get_param(cmd, "channel");
10458 const char *group_id = get_param(cmd, "groupid");
10459 const char *client_id = get_param(cmd, "clientmac");
10460 int count, channel, freq, i;
10461 const char *fname;
10462 char frame[1024], src_mac[20], group_id_attr[25],
10463 device_macstr[3 * ETH_ALEN], client_mac[ETH_ALEN];
10464 const char *group_ssid;
10465 const int group_ssid_prefix_len = 9;
10466 struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *) frame;
10467 size_t framelen = sizeof(frame);
10468 struct template_frame_tag tags[2];
10469 size_t tags_total = ARRAY_SIZE(tags);
10470 int tag_index, len, dst_len;
10471
10472 if (!countstr || !channelstr) {
10473 sigma_dut_print(dut, DUT_MSG_ERROR,
10474 "Missing argument: count, channel");
10475 return -1;
10476 }
10477 if (isprobereq && !ssid) {
10478 sigma_dut_print(dut, DUT_MSG_ERROR,
10479 "Missing argument: ssid");
10480 return -1;
10481 }
10482 if (!isprobereq && (!group_id || !client_id)) {
10483 sigma_dut_print(dut, DUT_MSG_ERROR,
10484 "Missing argument: group_id, client_id");
10485 return -1;
10486 }
10487
10488 count = atoi(countstr);
10489 channel = atoi(channelstr);
10490 freq = channel_to_freq(dut, channel);
10491
10492 if (!freq) {
10493 sigma_dut_print(dut, DUT_MSG_ERROR,
10494 "invalid channel: %s", channelstr);
10495 return -1;
10496 }
10497
10498 if (isprobereq) {
10499 if (strcasecmp(ssid, "wildcard") == 0) {
10500 fname = "probe_req_wildcard.txt";
10501 } else if (strcasecmp(ssid, "P2P_Wildcard") == 0) {
10502 fname = "probe_req_P2P_Wildcard.txt";
10503 } else {
10504 sigma_dut_print(dut, DUT_MSG_ERROR,
10505 "invalid probe request type");
10506 return -1;
10507 }
10508 } else {
10509 fname = "P2P_device_discovery_req.txt";
10510 }
10511
10512 if (parse_template_frame_file(dut, fname, frame, &framelen,
10513 tags, &tags_total)) {
10514 sigma_dut_print(dut, DUT_MSG_ERROR,
10515 "invalid frame template: %s", fname);
10516 return -1;
10517 }
10518
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010519 if (get_wpa_status(get_station_ifname(dut), "address",
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030010520 src_mac, sizeof(src_mac)) < 0 ||
10521 parse_mac_address(dut, src_mac, &hdr->addr2[0]) ||
10522 parse_mac_address(dut, dest_mac, &hdr->addr1[0]))
10523 return -1;
10524 /* Use wildcard BSSID, since we are in PBSS */
10525 memset(&hdr->addr3, 0xFF, ETH_ALEN);
10526
10527 if (!isprobereq) {
10528 tag_index = find_template_frame_tag(tags, tags_total, 1);
10529 if (tag_index < 0) {
10530 sigma_dut_print(dut, DUT_MSG_ERROR,
10531 "can't find device id attribute");
10532 return -1;
10533 }
10534 if (parse_mac_address(dut, client_id,
10535 (unsigned char *) client_mac)) {
10536 sigma_dut_print(dut, DUT_MSG_ERROR,
10537 "invalid client_id: %s", client_id);
10538 return -1;
10539 }
10540 if (replace_p2p_attribute(dut, &frame[tags[tag_index].offset],
10541 framelen - tags[tag_index].offset,
10542 IEEE80211_P2P_ATTR_DEVICE_ID,
10543 client_mac, ETH_ALEN)) {
10544 sigma_dut_print(dut, DUT_MSG_ERROR,
10545 "fail to replace device id attribute");
10546 return -1;
10547 }
10548
10549 /*
10550 * group_id arg contains device MAC address followed by
10551 * space and SSID (DIRECT-somessid).
10552 * group id attribute contains device address (6 bytes)
10553 * followed by SSID prefix DIRECT-XX (9 bytes)
10554 */
10555 if (strlen(group_id) < sizeof(device_macstr)) {
10556 sigma_dut_print(dut, DUT_MSG_ERROR,
10557 "group_id arg too short");
10558 return -1;
10559 }
10560 memcpy(device_macstr, group_id, sizeof(device_macstr));
10561 device_macstr[sizeof(device_macstr) - 1] = '\0';
10562 if (parse_mac_address(dut, device_macstr,
10563 (unsigned char *) group_id_attr)) {
10564 sigma_dut_print(dut, DUT_MSG_ERROR,
10565 "fail to parse device address from group_id");
10566 return -1;
10567 }
10568 group_ssid = strchr(group_id, ' ');
10569 if (!group_ssid) {
10570 sigma_dut_print(dut, DUT_MSG_ERROR,
10571 "invalid group_id arg, no ssid");
10572 return -1;
10573 }
10574 group_ssid++;
10575 len = strlen(group_ssid);
10576 if (len < group_ssid_prefix_len) {
10577 sigma_dut_print(dut, DUT_MSG_ERROR,
10578 "group_id SSID too short");
10579 return -1;
10580 }
10581 dst_len = sizeof(group_id_attr) - ETH_ALEN;
10582 if (len > dst_len) {
10583 sigma_dut_print(dut, DUT_MSG_ERROR,
10584 "group_id SSID (%s) too long",
10585 group_ssid);
10586 return -1;
10587 }
10588
10589 memcpy(group_id_attr + ETH_ALEN, group_ssid, len);
10590 tag_index = find_template_frame_tag(tags, tags_total, 2);
10591 if (tag_index < 0) {
10592 sigma_dut_print(dut, DUT_MSG_ERROR,
10593 "can't find group id attribute");
10594 return -1;
10595 }
10596 if (replace_p2p_attribute(dut, &frame[tags[tag_index].offset],
10597 framelen - tags[tag_index].offset,
10598 IEEE80211_P2P_ATTR_GROUP_ID,
10599 group_id_attr,
10600 sizeof(group_id_attr))) {
10601 sigma_dut_print(dut, DUT_MSG_ERROR,
10602 "fail to replace group id attribute");
10603 return -1;
10604 }
10605 }
10606
10607 for (i = 0; i < count; i++) {
10608 if (wil6210_transmit_frame(dut, freq,
10609 WIL_TRANSMIT_FRAME_DEFAULT_ROC,
10610 frame, framelen)) {
10611 sigma_dut_print(dut, DUT_MSG_ERROR,
10612 "fail to transmit probe request frame");
10613 return -1;
10614 }
10615 }
10616
10617 return 0;
10618}
10619
10620
Lior David0fe101e2017-03-09 16:09:50 +020010621int wil6210_send_frame_60g(struct sigma_dut *dut, struct sigma_conn *conn,
10622 struct sigma_cmd *cmd)
10623{
10624 const char *frame_name = get_param(cmd, "framename");
10625 const char *mac = get_param(cmd, "dest_mac");
10626
10627 if (!frame_name || !mac) {
10628 sigma_dut_print(dut, DUT_MSG_ERROR,
10629 "framename and dest_mac must be provided");
10630 return -1;
10631 }
10632
10633 if (strcasecmp(frame_name, "brp") == 0) {
10634 const char *l_rx = get_param(cmd, "L-RX");
10635 int l_rx_i;
10636
10637 if (!l_rx) {
10638 sigma_dut_print(dut, DUT_MSG_ERROR,
10639 "L-RX must be provided");
10640 return -1;
10641 }
10642 l_rx_i = atoi(l_rx);
10643
10644 sigma_dut_print(dut, DUT_MSG_INFO,
10645 "dev_send_frame: BRP-RX, dest_mac %s, L-RX %s",
10646 mac, l_rx);
10647 if (l_rx_i != 16) {
10648 sigma_dut_print(dut, DUT_MSG_ERROR,
10649 "unsupported L-RX: %s", l_rx);
10650 return -1;
10651 }
10652
10653 if (wil6210_send_brp_rx(dut, mac, l_rx_i))
10654 return -1;
10655 } else if (strcasecmp(frame_name, "ssw") == 0) {
10656 sigma_dut_print(dut, DUT_MSG_INFO,
10657 "dev_send_frame: SLS, dest_mac %s", mac);
10658 if (wil6210_send_sls(dut, mac))
10659 return -1;
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030010660 } else if ((strcasecmp(frame_name, "probereq") == 0) ||
10661 (strcasecmp(frame_name, "devdiscreq") == 0)) {
10662 sigma_dut_print(dut, DUT_MSG_INFO,
10663 "dev_send_frame: %s, dest_mac %s", frame_name,
10664 mac);
10665 if (wil6210_send_p2p_frame_60g(dut, cmd, frame_name, mac))
10666 return -1;
Lior David0fe101e2017-03-09 16:09:50 +020010667 } else {
10668 sigma_dut_print(dut, DUT_MSG_ERROR,
10669 "unsupported frame type: %s", frame_name);
10670 return -1;
10671 }
10672
10673 return 1;
10674}
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030010675
Lior David0fe101e2017-03-09 16:09:50 +020010676#endif /* __linux__ */
10677
10678
10679static int cmd_sta_send_frame_60g(struct sigma_dut *dut,
10680 struct sigma_conn *conn,
10681 struct sigma_cmd *cmd)
10682{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010683 switch (get_driver_type(dut)) {
Lior David0fe101e2017-03-09 16:09:50 +020010684#ifdef __linux__
10685 case DRIVER_WIL6210:
10686 return wil6210_send_frame_60g(dut, conn, cmd);
10687#endif /* __linux__ */
10688 default:
10689 send_resp(dut, conn, SIGMA_ERROR,
10690 "errorCode,Unsupported sta_set_frame(60G) with the current driver");
10691 return 0;
10692 }
10693}
10694
10695
Ashwini Patildb59b3c2017-04-13 15:19:23 +053010696static int mbo_send_anqp_query(struct sigma_dut *dut, struct sigma_conn *conn,
10697 const char *intf, struct sigma_cmd *cmd)
10698{
10699 const char *val, *addr;
10700 char buf[100];
10701
10702 addr = get_param(cmd, "DestMac");
10703 if (!addr) {
10704 send_resp(dut, conn, SIGMA_INVALID,
10705 "ErrorCode,AP MAC address is missing");
10706 return 0;
10707 }
10708
10709 val = get_param(cmd, "ANQPQuery_ID");
10710 if (!val) {
10711 send_resp(dut, conn, SIGMA_INVALID,
10712 "ErrorCode,Missing ANQPQuery_ID");
10713 return 0;
10714 }
10715
10716 if (strcasecmp(val, "NeighborReportReq") == 0) {
10717 snprintf(buf, sizeof(buf), "ANQP_GET %s 272", addr);
10718 } else if (strcasecmp(val, "QueryListWithCellPref") == 0) {
10719 snprintf(buf, sizeof(buf), "ANQP_GET %s 272,mbo:2", addr);
10720 } else {
10721 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid ANQPQuery_ID: %s",
10722 val);
10723 send_resp(dut, conn, SIGMA_INVALID,
10724 "ErrorCode,Invalid ANQPQuery_ID");
10725 return 0;
10726 }
10727
Ashwini Patild174f2c2017-04-13 16:49:46 +053010728 /* Set gas_address3 field to IEEE 802.11-2012 standard compliant form
10729 * (Address3 = Wildcard BSSID when sent to not-associated AP;
10730 * if associated, AP BSSID).
10731 */
10732 if (wpa_command(intf, "SET gas_address3 1") < 0) {
10733 send_resp(dut, conn, SIGMA_ERROR,
10734 "ErrorCode,Failed to set gas_address3");
10735 return 0;
10736 }
10737
Ashwini Patildb59b3c2017-04-13 15:19:23 +053010738 if (wpa_command(intf, buf) < 0) {
10739 send_resp(dut, conn, SIGMA_ERROR,
10740 "ErrorCode,Failed to send ANQP query");
10741 return 0;
10742 }
10743
10744 return 1;
10745}
10746
10747
10748static int mbo_cmd_sta_send_frame(struct sigma_dut *dut,
10749 struct sigma_conn *conn,
10750 const char *intf,
10751 struct sigma_cmd *cmd)
10752{
10753 const char *val = get_param(cmd, "FrameName");
10754
10755 if (val && strcasecmp(val, "ANQPQuery") == 0)
10756 return mbo_send_anqp_query(dut, conn, intf, cmd);
10757
10758 return 2;
10759}
10760
10761
Jouni Malinenf7222712019-06-13 01:50:21 +030010762enum sigma_cmd_result cmd_sta_send_frame(struct sigma_dut *dut,
10763 struct sigma_conn *conn,
10764 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010765{
10766 const char *intf = get_param(cmd, "Interface");
10767 const char *val;
10768 enum send_frame_type frame;
10769 enum send_frame_protection protected;
10770 char buf[100];
10771 unsigned char addr[ETH_ALEN];
10772 int res;
10773
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +030010774 if (!intf)
10775 return -1;
10776
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010777 val = get_param(cmd, "program");
10778 if (val == NULL)
10779 val = get_param(cmd, "frame");
10780 if (val && strcasecmp(val, "TDLS") == 0)
10781 return cmd_sta_send_frame_tdls(dut, conn, cmd);
10782 if (val && (strcasecmp(val, "HS2") == 0 ||
Jouni Malinen1f6ae642018-06-07 23:56:13 +030010783 strcasecmp(val, "HS2-R2") == 0 ||
10784 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010785 return cmd_sta_send_frame_hs2(dut, conn, cmd);
10786 if (val && strcasecmp(val, "VHT") == 0)
10787 return cmd_sta_send_frame_vht(dut, conn, cmd);
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070010788 if (val && strcasecmp(val, "HE") == 0)
10789 return cmd_sta_send_frame_he(dut, conn, cmd);
priyadharshini gowthamand66913a2016-07-29 15:11:17 -070010790 if (val && strcasecmp(val, "LOC") == 0)
10791 return loc_cmd_sta_send_frame(dut, conn, cmd);
Lior David0fe101e2017-03-09 16:09:50 +020010792 if (val && strcasecmp(val, "60GHz") == 0)
10793 return cmd_sta_send_frame_60g(dut, conn, cmd);
Ashwini Patildb59b3c2017-04-13 15:19:23 +053010794 if (val && strcasecmp(val, "MBO") == 0) {
10795 res = mbo_cmd_sta_send_frame(dut, conn, intf, cmd);
10796 if (res != 2)
10797 return res;
10798 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010799
10800 val = get_param(cmd, "TD_DISC");
10801 if (val) {
10802 if (hwaddr_aton(val, addr) < 0)
10803 return -1;
10804 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", val);
10805 if (wpa_command(intf, buf) < 0) {
10806 send_resp(dut, conn, SIGMA_ERROR,
10807 "ErrorCode,Failed to send TDLS discovery");
10808 return 0;
10809 }
10810 return 1;
10811 }
10812
10813 val = get_param(cmd, "TD_Setup");
10814 if (val) {
10815 if (hwaddr_aton(val, addr) < 0)
10816 return -1;
10817 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", val);
10818 if (wpa_command(intf, buf) < 0) {
10819 send_resp(dut, conn, SIGMA_ERROR,
10820 "ErrorCode,Failed to start TDLS setup");
10821 return 0;
10822 }
10823 return 1;
10824 }
10825
10826 val = get_param(cmd, "TD_TearDown");
10827 if (val) {
10828 if (hwaddr_aton(val, addr) < 0)
10829 return -1;
10830 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", val);
10831 if (wpa_command(intf, buf) < 0) {
10832 send_resp(dut, conn, SIGMA_ERROR,
10833 "ErrorCode,Failed to tear down TDLS link");
10834 return 0;
10835 }
10836 return 1;
10837 }
10838
10839 val = get_param(cmd, "TD_ChannelSwitch");
10840 if (val) {
10841 /* TODO */
10842 send_resp(dut, conn, SIGMA_ERROR,
10843 "ErrorCode,TD_ChannelSwitch not yet supported");
10844 return 0;
10845 }
10846
10847 val = get_param(cmd, "TD_NF");
10848 if (val) {
10849 /* TODO */
10850 send_resp(dut, conn, SIGMA_ERROR,
10851 "ErrorCode,TD_NF not yet supported");
10852 return 0;
10853 }
10854
10855 val = get_param(cmd, "PMFFrameType");
10856 if (val == NULL)
10857 val = get_param(cmd, "FrameName");
10858 if (val == NULL)
10859 val = get_param(cmd, "Type");
10860 if (val == NULL)
10861 return -1;
10862 if (strcasecmp(val, "disassoc") == 0)
10863 frame = DISASSOC;
10864 else if (strcasecmp(val, "deauth") == 0)
10865 frame = DEAUTH;
10866 else if (strcasecmp(val, "saquery") == 0)
10867 frame = SAQUERY;
10868 else if (strcasecmp(val, "auth") == 0)
10869 frame = AUTH;
10870 else if (strcasecmp(val, "assocreq") == 0)
10871 frame = ASSOCREQ;
10872 else if (strcasecmp(val, "reassocreq") == 0)
10873 frame = REASSOCREQ;
10874 else if (strcasecmp(val, "neigreq") == 0) {
10875 sigma_dut_print(dut, DUT_MSG_INFO, "Got neighbor request");
10876
10877 val = get_param(cmd, "ssid");
10878 if (val == NULL)
10879 return -1;
10880
10881 res = send_neighbor_request(dut, intf, val);
10882 if (res) {
10883 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
10884 "Failed to send neighbor report request");
10885 return 0;
10886 }
10887
10888 return 1;
Ashwini Patil5acd7382017-04-13 15:55:04 +053010889 } else if (strcasecmp(val, "transmgmtquery") == 0 ||
10890 strcasecmp(val, "BTMQuery") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010891 sigma_dut_print(dut, DUT_MSG_DEBUG,
10892 "Got Transition Management Query");
10893
Ashwini Patil5acd7382017-04-13 15:55:04 +053010894 res = send_trans_mgmt_query(dut, intf, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010895 if (res) {
10896 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
10897 "Failed to send Transition Management Query");
10898 return 0;
10899 }
10900
10901 return 1;
10902 } else {
10903 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
10904 "PMFFrameType");
10905 return 0;
10906 }
10907
10908 val = get_param(cmd, "PMFProtected");
10909 if (val == NULL)
10910 val = get_param(cmd, "Protected");
10911 if (val == NULL)
10912 return -1;
10913 if (strcasecmp(val, "Correct-key") == 0 ||
10914 strcasecmp(val, "CorrectKey") == 0)
10915 protected = CORRECT_KEY;
10916 else if (strcasecmp(val, "IncorrectKey") == 0)
10917 protected = INCORRECT_KEY;
10918 else if (strcasecmp(val, "Unprotected") == 0)
10919 protected = UNPROTECTED;
10920 else {
10921 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
10922 "PMFProtected");
10923 return 0;
10924 }
10925
10926 if (protected != UNPROTECTED &&
10927 (frame == AUTH || frame == ASSOCREQ || frame == REASSOCREQ)) {
10928 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Impossible "
10929 "PMFProtected for auth/assocreq/reassocreq");
10930 return 0;
10931 }
10932
10933 if (if_nametoindex("sigmadut") == 0) {
10934 snprintf(buf, sizeof(buf),
10935 "iw dev %s interface add sigmadut type monitor",
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010936 get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010937 if (system(buf) != 0 ||
10938 if_nametoindex("sigmadut") == 0) {
10939 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
10940 "monitor interface with '%s'", buf);
10941 return -2;
10942 }
10943 }
10944
10945 if (system("ifconfig sigmadut up") != 0) {
10946 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
10947 "monitor interface up");
10948 return -2;
10949 }
10950
10951 return sta_inject_frame(dut, conn, frame, protected, NULL);
10952}
10953
10954
10955static int cmd_sta_set_parameter_hs2(struct sigma_dut *dut,
10956 struct sigma_conn *conn,
10957 struct sigma_cmd *cmd,
10958 const char *ifname)
10959{
10960 char buf[200];
10961 const char *val;
10962
10963 val = get_param(cmd, "ClearARP");
10964 if (val && atoi(val) == 1) {
10965 snprintf(buf, sizeof(buf), "ip neigh flush dev %s", ifname);
10966 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10967 if (system(buf) != 0) {
10968 send_resp(dut, conn, SIGMA_ERROR,
10969 "errorCode,Failed to clear ARP cache");
10970 return 0;
10971 }
10972 }
10973
10974 return 1;
10975}
10976
10977
10978int cmd_sta_set_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
10979 struct sigma_cmd *cmd)
10980{
10981 const char *intf = get_param(cmd, "Interface");
10982 const char *val;
10983
10984 if (intf == NULL)
10985 return -1;
10986
10987 val = get_param(cmd, "program");
10988 if (val && (strcasecmp(val, "HS2") == 0 ||
Jouni Malinen1f6ae642018-06-07 23:56:13 +030010989 strcasecmp(val, "HS2-R2") == 0 ||
10990 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010991 return cmd_sta_set_parameter_hs2(dut, conn, cmd, intf);
10992
10993 return -1;
10994}
10995
10996
Jouni Malinenf7222712019-06-13 01:50:21 +030010997static enum sigma_cmd_result cmd_sta_set_macaddr(struct sigma_dut *dut,
10998 struct sigma_conn *conn,
10999 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011000{
11001 const char *intf = get_param(cmd, "Interface");
11002 const char *mac = get_param(cmd, "MAC");
11003
11004 if (intf == NULL || mac == NULL)
11005 return -1;
11006
11007 sigma_dut_print(dut, DUT_MSG_INFO, "Change local MAC address for "
11008 "interface %s to %s", intf, mac);
11009
11010 if (dut->set_macaddr) {
11011 char buf[128];
11012 int res;
11013 if (strcasecmp(mac, "default") == 0) {
11014 res = snprintf(buf, sizeof(buf), "%s",
11015 dut->set_macaddr);
11016 dut->tmp_mac_addr = 0;
11017 } else {
11018 res = snprintf(buf, sizeof(buf), "%s %s",
11019 dut->set_macaddr, mac);
11020 dut->tmp_mac_addr = 1;
11021 }
11022 if (res < 0 || res >= (int) sizeof(buf))
11023 return -1;
11024 if (system(buf) != 0) {
11025 send_resp(dut, conn, SIGMA_ERROR,
11026 "errorCode,Failed to set MAC "
11027 "address");
11028 return 0;
11029 }
11030 return 1;
11031 }
11032
11033 if (strcasecmp(mac, "default") == 0)
11034 return 1;
11035
11036 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
11037 "command");
11038 return 0;
11039}
11040
11041
11042static int iwpriv_tdlsoffchnmode(struct sigma_dut *dut,
11043 struct sigma_conn *conn, const char *intf,
11044 int val)
11045{
11046 char buf[200];
11047 int res;
11048
11049 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchnmode %d",
11050 intf, val);
11051 if (res < 0 || res >= (int) sizeof(buf))
11052 return -1;
11053 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
11054 if (system(buf) != 0) {
11055 send_resp(dut, conn, SIGMA_ERROR,
11056 "errorCode,Failed to configure offchannel mode");
11057 return 0;
11058 }
11059
11060 return 1;
11061}
11062
11063
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011064static int off_chan_val(enum sec_ch_offset off)
11065{
11066 switch (off) {
11067 case SEC_CH_NO:
11068 return 0;
11069 case SEC_CH_40ABOVE:
11070 return 40;
11071 case SEC_CH_40BELOW:
11072 return -40;
11073 }
11074
11075 return 0;
11076}
11077
11078
11079static int iwpriv_set_offchan(struct sigma_dut *dut, struct sigma_conn *conn,
11080 const char *intf, int off_ch_num,
11081 enum sec_ch_offset sec)
11082{
11083 char buf[200];
11084 int res;
11085
11086 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchan %d",
11087 intf, off_ch_num);
11088 if (res < 0 || res >= (int) sizeof(buf))
11089 return -1;
11090 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
11091 if (system(buf) != 0) {
11092 send_resp(dut, conn, SIGMA_ERROR,
11093 "errorCode,Failed to set offchan");
11094 return 0;
11095 }
11096
11097 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsecchnoffst %d",
11098 intf, off_chan_val(sec));
11099 if (res < 0 || res >= (int) sizeof(buf))
11100 return -1;
11101 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
11102 if (system(buf) != 0) {
11103 send_resp(dut, conn, SIGMA_ERROR,
11104 "errorCode,Failed to set sec chan offset");
11105 return 0;
11106 }
11107
11108 return 1;
11109}
11110
11111
11112static int tdls_set_offchannel_offset(struct sigma_dut *dut,
11113 struct sigma_conn *conn,
11114 const char *intf, int off_ch_num,
11115 enum sec_ch_offset sec)
11116{
11117 char buf[200];
11118 int res;
11119
11120 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNEL %d",
11121 off_ch_num);
11122 if (res < 0 || res >= (int) sizeof(buf))
11123 return -1;
11124 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
11125
11126 if (wpa_command(intf, buf) < 0) {
11127 send_resp(dut, conn, SIGMA_ERROR,
11128 "ErrorCode,Failed to set offchan");
11129 return 0;
11130 }
11131 res = snprintf(buf, sizeof(buf), "DRIVER TDLSSECONDARYCHANNELOFFSET %d",
11132 off_chan_val(sec));
11133 if (res < 0 || res >= (int) sizeof(buf))
11134 return -1;
11135
11136 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
11137
11138 if (wpa_command(intf, buf) < 0) {
11139 send_resp(dut, conn, SIGMA_ERROR,
11140 "ErrorCode,Failed to set sec chan offset");
11141 return 0;
11142 }
11143
11144 return 1;
11145}
11146
11147
11148static int tdls_set_offchannel_mode(struct sigma_dut *dut,
11149 struct sigma_conn *conn,
11150 const char *intf, int val)
11151{
11152 char buf[200];
11153 int res;
11154
11155 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNELMODE %d",
11156 val);
11157 if (res < 0 || res >= (int) sizeof(buf))
11158 return -1;
11159 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
11160
11161 if (wpa_command(intf, buf) < 0) {
11162 send_resp(dut, conn, SIGMA_ERROR,
11163 "ErrorCode,Failed to configure offchannel mode");
11164 return 0;
11165 }
11166
11167 return 1;
11168}
11169
11170
11171static int cmd_sta_set_rfeature_tdls(const char *intf, struct sigma_dut *dut,
11172 struct sigma_conn *conn,
11173 struct sigma_cmd *cmd)
11174{
11175 const char *val;
11176 enum {
11177 CHSM_NOT_SET,
11178 CHSM_ENABLE,
11179 CHSM_DISABLE,
11180 CHSM_REJREQ,
11181 CHSM_UNSOLRESP
11182 } chsm = CHSM_NOT_SET;
11183 int off_ch_num = -1;
11184 enum sec_ch_offset sec_ch = SEC_CH_NO;
11185 int res;
11186
11187 val = get_param(cmd, "Uapsd");
11188 if (val) {
11189 char buf[100];
11190 if (strcasecmp(val, "Enable") == 0)
11191 snprintf(buf, sizeof(buf), "SET ps 99");
11192 else if (strcasecmp(val, "Disable") == 0)
11193 snprintf(buf, sizeof(buf), "SET ps 98");
11194 else {
11195 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
11196 "Unsupported uapsd parameter value");
11197 return 0;
11198 }
11199 if (wpa_command(intf, buf)) {
11200 send_resp(dut, conn, SIGMA_ERROR,
11201 "ErrorCode,Failed to change U-APSD "
11202 "powersave mode");
11203 return 0;
11204 }
11205 }
11206
11207 val = get_param(cmd, "TPKTIMER");
11208 if (val && strcasecmp(val, "DISABLE") == 0) {
11209 if (wpa_command(intf, "SET tdls_testing 0x100")) {
11210 send_resp(dut, conn, SIGMA_ERROR,
11211 "ErrorCode,Failed to enable no TPK "
11212 "expiration test mode");
11213 return 0;
11214 }
11215 dut->no_tpk_expiration = 1;
11216 }
11217
11218 val = get_param(cmd, "ChSwitchMode");
11219 if (val) {
11220 if (strcasecmp(val, "Enable") == 0 ||
11221 strcasecmp(val, "Initiate") == 0)
11222 chsm = CHSM_ENABLE;
11223 else if (strcasecmp(val, "Disable") == 0 ||
11224 strcasecmp(val, "passive") == 0)
11225 chsm = CHSM_DISABLE;
11226 else if (strcasecmp(val, "RejReq") == 0)
11227 chsm = CHSM_REJREQ;
11228 else if (strcasecmp(val, "UnSolResp") == 0)
11229 chsm = CHSM_UNSOLRESP;
11230 else {
11231 send_resp(dut, conn, SIGMA_ERROR,
11232 "ErrorCode,Unknown ChSwitchMode value");
11233 return 0;
11234 }
11235 }
11236
11237 val = get_param(cmd, "OffChNum");
11238 if (val) {
11239 off_ch_num = atoi(val);
11240 if (off_ch_num == 0) {
11241 send_resp(dut, conn, SIGMA_ERROR,
11242 "ErrorCode,Invalid OffChNum");
11243 return 0;
11244 }
11245 }
11246
11247 val = get_param(cmd, "SecChOffset");
11248 if (val) {
11249 if (strcmp(val, "20") == 0)
11250 sec_ch = SEC_CH_NO;
11251 else if (strcasecmp(val, "40above") == 0)
11252 sec_ch = SEC_CH_40ABOVE;
11253 else if (strcasecmp(val, "40below") == 0)
11254 sec_ch = SEC_CH_40BELOW;
11255 else {
11256 send_resp(dut, conn, SIGMA_ERROR,
11257 "ErrorCode,Unknown SecChOffset value");
11258 return 0;
11259 }
11260 }
11261
11262 if (chsm == CHSM_NOT_SET) {
11263 /* no offchannel changes requested */
11264 return 1;
11265 }
11266
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011267 if (strcmp(intf, get_main_ifname(dut)) != 0 &&
11268 strcmp(intf, get_station_ifname(dut)) != 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011269 send_resp(dut, conn, SIGMA_ERROR,
11270 "ErrorCode,Unknown interface");
11271 return 0;
11272 }
11273
11274 switch (chsm) {
11275 case CHSM_NOT_SET:
Jouni Malinen280f5ba2016-08-29 21:33:10 +030011276 res = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011277 break;
11278 case CHSM_ENABLE:
11279 if (off_ch_num < 0) {
11280 send_resp(dut, conn, SIGMA_ERROR,
11281 "ErrorCode,Missing OffChNum argument");
11282 return 0;
11283 }
11284 if (wifi_chip_type == DRIVER_WCN) {
11285 res = tdls_set_offchannel_offset(dut, conn, intf,
11286 off_ch_num, sec_ch);
11287 } else {
11288 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
11289 sec_ch);
11290 }
11291 if (res != 1)
11292 return res;
11293 if (wifi_chip_type == DRIVER_WCN)
11294 res = tdls_set_offchannel_mode(dut, conn, intf, 1);
11295 else
11296 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 1);
11297 break;
11298 case CHSM_DISABLE:
11299 if (wifi_chip_type == DRIVER_WCN)
11300 res = tdls_set_offchannel_mode(dut, conn, intf, 2);
11301 else
11302 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 2);
11303 break;
11304 case CHSM_REJREQ:
11305 if (wifi_chip_type == DRIVER_WCN)
11306 res = tdls_set_offchannel_mode(dut, conn, intf, 3);
11307 else
11308 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 3);
11309 break;
11310 case CHSM_UNSOLRESP:
11311 if (off_ch_num < 0) {
11312 send_resp(dut, conn, SIGMA_ERROR,
11313 "ErrorCode,Missing OffChNum argument");
11314 return 0;
11315 }
11316 if (wifi_chip_type == DRIVER_WCN) {
11317 res = tdls_set_offchannel_offset(dut, conn, intf,
11318 off_ch_num, sec_ch);
11319 } else {
11320 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
11321 sec_ch);
11322 }
11323 if (res != 1)
11324 return res;
11325 if (wifi_chip_type == DRIVER_WCN)
11326 res = tdls_set_offchannel_mode(dut, conn, intf, 4);
11327 else
11328 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 4);
11329 break;
11330 }
11331
11332 return res;
11333}
11334
11335
11336static int ath_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
11337 struct sigma_conn *conn,
11338 struct sigma_cmd *cmd)
11339{
11340 const char *val;
Srikanth Marepalli5415acf2018-08-27 12:53:11 +053011341 char *token = NULL, *result;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011342
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -070011343 novap_reset(dut, intf, 1);
priyadharshini gowthamane5e25172015-12-08 14:53:48 -080011344
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011345 val = get_param(cmd, "nss_mcs_opt");
11346 if (val) {
11347 /* String (nss_operating_mode; mcs_operating_mode) */
11348 int nss, mcs;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053011349 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011350
11351 token = strdup(val);
11352 if (!token)
11353 return 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053011354 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +053011355 if (!result) {
11356 sigma_dut_print(dut, DUT_MSG_ERROR,
11357 "VHT NSS not specified");
11358 goto failed;
11359 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011360 if (strcasecmp(result, "def") != 0) {
11361 nss = atoi(result);
11362 if (nss == 4)
11363 ath_disable_txbf(dut, intf);
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011364 if (run_iwpriv(dut, intf, "nss %d", nss) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011365 goto failed;
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011366
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011367 }
11368
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053011369 result = strtok_r(NULL, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +053011370 if (!result) {
11371 sigma_dut_print(dut, DUT_MSG_ERROR,
11372 "VHT MCS not specified");
11373 goto failed;
11374 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011375 if (strcasecmp(result, "def") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011376 if (run_iwpriv(dut, intf, "set11NRates 0") < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011377 goto failed;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011378 } else {
11379 mcs = atoi(result);
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011380 if (run_iwpriv(dut, intf, "vhtmcs %d", mcs) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011381 goto failed;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011382 }
11383 /* Channel width gets messed up, fix this */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011384 run_iwpriv(dut, intf, "chwidth %d", dut->chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011385 }
11386
Srikanth Marepalli5415acf2018-08-27 12:53:11 +053011387 free(token);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011388 return 1;
11389failed:
11390 free(token);
11391 return 0;
11392}
11393
11394
11395static int cmd_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
11396 struct sigma_conn *conn,
11397 struct sigma_cmd *cmd)
11398{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011399 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011400 case DRIVER_ATHEROS:
11401 return ath_sta_set_rfeature_vht(intf, dut, conn, cmd);
11402 default:
11403 send_resp(dut, conn, SIGMA_ERROR,
11404 "errorCode,Unsupported sta_set_rfeature(VHT) with the current driver");
11405 return 0;
11406 }
11407}
11408
11409
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011410static int wcn_sta_set_rfeature_he(const char *intf, struct sigma_dut *dut,
11411 struct sigma_conn *conn,
11412 struct sigma_cmd *cmd)
11413{
11414 const char *val;
11415 char *token = NULL, *result;
11416 char buf[60];
11417
11418 val = get_param(cmd, "nss_mcs_opt");
11419 if (val) {
11420 /* String (nss_operating_mode; mcs_operating_mode) */
11421 int nss, mcs, ratecode;
11422 char *saveptr;
11423
11424 token = strdup(val);
11425 if (!token)
11426 return -2;
11427
11428 result = strtok_r(token, ";", &saveptr);
11429 if (!result) {
11430 sigma_dut_print(dut, DUT_MSG_ERROR,
11431 "HE NSS not specified");
11432 goto failed;
11433 }
11434 nss = 1;
11435 if (strcasecmp(result, "def") != 0)
11436 nss = atoi(result);
11437
11438 result = strtok_r(NULL, ";", &saveptr);
11439 if (!result) {
11440 sigma_dut_print(dut, DUT_MSG_ERROR,
11441 "HE MCS not specified");
11442 goto failed;
11443 }
11444 mcs = 7;
11445 if (strcasecmp(result, "def") != 0)
11446 mcs = atoi(result);
11447
Arif Hussain557bf412018-05-25 17:29:36 -070011448 ratecode = 0x20; /* for nss:1 MCS 0 */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011449 if (nss == 2) {
Arif Hussain557bf412018-05-25 17:29:36 -070011450 ratecode = 0x40; /* for nss:2 MCS 0 */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011451 } else if (nss > 2) {
11452 sigma_dut_print(dut, DUT_MSG_ERROR,
11453 "HE NSS %d not supported", nss);
11454 goto failed;
11455 }
11456
Arif Hussain557bf412018-05-25 17:29:36 -070011457 snprintf(buf, sizeof(buf), "iwpriv %s nss %d", intf, nss);
11458 if (system(buf) != 0) {
11459 sigma_dut_print(dut, DUT_MSG_ERROR,
11460 "nss_mcs_opt: iwpriv %s nss %d failed",
11461 intf, nss);
11462 goto failed;
11463 }
Arif Hussainac6c5112018-05-25 17:34:00 -070011464 dut->sta_nss = nss;
Arif Hussain557bf412018-05-25 17:29:36 -070011465
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011466 /* Add the MCS to the ratecode */
11467 if (mcs >= 0 && mcs <= 11) {
11468 ratecode += mcs;
Arif Hussain557bf412018-05-25 17:29:36 -070011469#ifdef NL80211_SUPPORT
11470 if (dut->device_type == STA_testbed) {
11471 enum he_mcs_config mcs_config;
11472 int ret;
11473
11474 if (mcs <= 7)
11475 mcs_config = HE_80_MCS0_7;
11476 else if (mcs <= 9)
11477 mcs_config = HE_80_MCS0_9;
11478 else
11479 mcs_config = HE_80_MCS0_11;
11480 ret = sta_set_he_mcs(dut, intf, mcs_config);
11481 if (ret) {
11482 sigma_dut_print(dut, DUT_MSG_ERROR,
11483 "nss_mcs_opt: mcs setting failed, mcs:%d, mcs_config %d, ret:%d",
11484 mcs, mcs_config, ret);
11485 goto failed;
11486 }
11487 }
11488#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011489 } else {
11490 sigma_dut_print(dut, DUT_MSG_ERROR,
11491 "HE MCS %d not supported", mcs);
11492 goto failed;
11493 }
11494 snprintf(buf, sizeof(buf), "iwpriv %s set_11ax_rate 0x%03x",
11495 intf, ratecode);
11496 if (system(buf) != 0) {
11497 sigma_dut_print(dut, DUT_MSG_ERROR,
11498 "iwpriv setting of 11ax rates failed");
11499 goto failed;
11500 }
11501 free(token);
11502 }
11503
11504 val = get_param(cmd, "GI");
11505 if (val) {
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011506 int fix_rate_sgi;
11507
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011508 if (strcmp(val, "0.8") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070011509 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 9", intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011510 fix_rate_sgi = 1;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011511 } else if (strcmp(val, "1.6") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070011512 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 10",
11513 intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011514 fix_rate_sgi = 2;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011515 } else if (strcmp(val, "3.2") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070011516 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 11",
11517 intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011518 fix_rate_sgi = 3;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011519 } else {
11520 send_resp(dut, conn, SIGMA_ERROR,
11521 "errorCode,GI value not supported");
11522 return 0;
11523 }
11524 if (system(buf) != 0) {
11525 send_resp(dut, conn, SIGMA_ERROR,
11526 "errorCode,Failed to set shortgi");
11527 return 0;
11528 }
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011529 snprintf(buf, sizeof(buf), "iwpriv %s shortgi %d",
11530 intf, fix_rate_sgi);
11531 if (system(buf) != 0) {
11532 send_resp(dut, conn, SIGMA_ERROR,
11533 "errorCode,Failed to set fix rate shortgi");
11534 return STATUS_SENT;
11535 }
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011536 }
11537
Subhani Shaik8e7a3052018-04-24 14:03:00 -070011538 val = get_param(cmd, "LTF");
11539 if (val) {
11540#ifdef NL80211_SUPPORT
11541 if (strcmp(val, "3.2") == 0) {
11542 sta_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_1X);
11543 } if (strcmp(val, "6.4") == 0) {
11544 sta_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_2X);
11545 } else if (strcmp(val, "12.8") == 0) {
11546 sta_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_4X);
11547 } else {
11548 send_resp(dut, conn, SIGMA_ERROR,
11549 "errorCode, LTF value not supported");
11550 return 0;
11551 }
11552#else /* NL80211_SUPPORT */
11553 sigma_dut_print(dut, DUT_MSG_ERROR,
11554 "LTF cannot be set without NL80211_SUPPORT defined");
11555 return -2;
11556#endif /* NL80211_SUPPORT */
11557 }
11558
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -070011559 val = get_param(cmd, "TxSUPPDU");
11560 if (val) {
11561 int set_val = 1;
11562
11563 if (strcasecmp(val, "Enable") == 0)
11564 set_val = 1;
11565 else if (strcasecmp(val, "Disable") == 0)
11566 set_val = 0;
11567
11568 if (sta_set_tx_su_ppdu_cfg(dut, intf, set_val)) {
11569 send_resp(dut, conn, SIGMA_ERROR,
11570 "ErrorCode,Failed to set Tx SU PPDU config");
11571 return 0;
11572 }
11573 }
11574
Arif Hussain480d5f42019-03-12 14:40:42 -070011575 val = get_param(cmd, "TWT_Setup");
11576 if (val) {
11577 if (strcasecmp(val, "Request") == 0) {
11578 if (sta_twt_request(dut, conn, cmd)) {
11579 send_resp(dut, conn, SIGMA_ERROR,
11580 "ErrorCode,sta_twt_request failed");
11581 return STATUS_SENT;
11582 }
11583 } else if (strcasecmp(val, "Teardown") == 0) {
11584 if (sta_twt_teardown(dut, conn, cmd)) {
11585 send_resp(dut, conn, SIGMA_ERROR,
11586 "ErrorCode,sta_twt_teardown failed");
11587 return STATUS_SENT;
11588 }
11589 }
11590 }
11591
Kiran Kumar Lokere50eb2cd2018-12-18 18:31:28 -080011592 val = get_param(cmd, "transmitOMI");
11593 if (val && sta_transmit_omi(dut, conn, cmd)) {
11594 send_resp(dut, conn, SIGMA_ERROR,
11595 "ErrorCode,sta_transmit_omi failed");
11596 return STATUS_SENT;
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -070011597 }
11598
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080011599 val = get_param(cmd, "Powersave");
11600 if (val) {
11601 char buf[60];
11602
11603 if (strcasecmp(val, "off") == 0) {
11604 snprintf(buf, sizeof(buf),
11605 "iwpriv %s setPower 2", intf);
11606 if (system(buf) != 0) {
11607 sigma_dut_print(dut, DUT_MSG_ERROR,
11608 "iwpriv setPower 2 failed");
11609 return 0;
11610 }
11611 } else if (strcasecmp(val, "on") == 0) {
11612 snprintf(buf, sizeof(buf),
11613 "iwpriv %s setPower 1", intf);
11614 if (system(buf) != 0) {
11615 sigma_dut_print(dut, DUT_MSG_ERROR,
11616 "iwpriv setPower 1 failed");
11617 return 0;
11618 }
11619 } else {
11620 sigma_dut_print(dut, DUT_MSG_ERROR,
11621 "Unsupported Powersave value '%s'",
11622 val);
11623 return -1;
11624 }
11625 }
11626
Kiran Kumar Lokere2c4b7ce2019-01-30 12:02:28 -080011627 val = get_param(cmd, "MU_EDCA");
11628 if (val) {
11629 if (strcasecmp(val, "Override") == 0) {
11630 if (sta_set_mu_edca_override(dut, intf, 1)) {
11631 send_resp(dut, conn, SIGMA_ERROR,
11632 "errorCode,MU EDCA override set failed");
11633 return STATUS_SENT;
11634 }
11635 } else if (strcasecmp(val, "Disable") == 0) {
11636 if (sta_set_mu_edca_override(dut, intf, 0)) {
11637 send_resp(dut, conn, SIGMA_ERROR,
11638 "errorCode,MU EDCA override disable failed");
11639 return STATUS_SENT;
11640 }
11641 }
11642 }
11643
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011644 return 1;
11645
11646failed:
11647 free(token);
11648 return -2;
11649}
11650
11651
11652static int cmd_sta_set_rfeature_he(const char *intf, struct sigma_dut *dut,
11653 struct sigma_conn *conn,
11654 struct sigma_cmd *cmd)
11655{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011656 switch (get_driver_type(dut)) {
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011657 case DRIVER_WCN:
11658 return wcn_sta_set_rfeature_he(intf, dut, conn, cmd);
11659 default:
11660 send_resp(dut, conn, SIGMA_ERROR,
11661 "errorCode,Unsupported sta_set_rfeature(HE) with the current driver");
11662 return 0;
11663 }
11664}
11665
11666
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080011667static int cmd_sta_set_power_save_he(const char *intf, struct sigma_dut *dut,
11668 struct sigma_conn *conn,
11669 struct sigma_cmd *cmd)
11670{
11671 const char *val;
11672
11673 val = get_param(cmd, "powersave");
11674 if (val) {
11675 char buf[60];
11676
11677 if (strcasecmp(val, "off") == 0) {
11678 snprintf(buf, sizeof(buf), "iwpriv %s setPower 2",
11679 intf);
11680 if (system(buf) != 0) {
11681 sigma_dut_print(dut, DUT_MSG_ERROR,
11682 "iwpriv setPower 2 failed");
11683 return 0;
11684 }
11685 } else if (strcasecmp(val, "on") == 0) {
11686 snprintf(buf, sizeof(buf), "iwpriv %s setPower 1",
11687 intf);
11688 if (system(buf) != 0) {
11689 sigma_dut_print(dut, DUT_MSG_ERROR,
11690 "iwpriv setPower 1 failed");
11691 return 0;
11692 }
11693 } else {
11694 sigma_dut_print(dut, DUT_MSG_ERROR,
11695 "Unsupported power save config");
11696 return -1;
11697 }
11698 return 1;
11699 }
11700
11701 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported command");
11702
11703 return 0;
11704}
11705
11706
Ashwini Patil5acd7382017-04-13 15:55:04 +053011707static int btm_query_candidate_list(struct sigma_dut *dut,
11708 struct sigma_conn *conn,
11709 struct sigma_cmd *cmd)
11710{
11711 const char *bssid, *info, *op_class, *ch, *phy_type, *pref;
11712 int len, ret;
11713 char buf[10];
11714
11715 /*
11716 * Neighbor Report elements format:
11717 * neighbor=<BSSID>,<BSSID Information>,<Operating Class>,
11718 * <Channel Number>,<PHY Type>[,<hexdump of Optional Subelements>]
11719 * eg: neighbor=aa:bb:cc:dd:ee:ff,17,81,6,1,030101
11720 */
11721
11722 bssid = get_param(cmd, "Nebor_BSSID");
11723 if (!bssid) {
11724 send_resp(dut, conn, SIGMA_INVALID,
11725 "errorCode,Nebor_BSSID is missing");
11726 return 0;
11727 }
11728
11729 info = get_param(cmd, "Nebor_Bssid_Info");
11730 if (!info) {
11731 sigma_dut_print(dut, DUT_MSG_INFO,
11732 "Using default value for Nebor_Bssid_Info: %s",
11733 DEFAULT_NEIGHBOR_BSSID_INFO);
11734 info = DEFAULT_NEIGHBOR_BSSID_INFO;
11735 }
11736
11737 op_class = get_param(cmd, "Nebor_Op_Class");
11738 if (!op_class) {
11739 send_resp(dut, conn, SIGMA_INVALID,
11740 "errorCode,Nebor_Op_Class is missing");
11741 return 0;
11742 }
11743
11744 ch = get_param(cmd, "Nebor_Op_Ch");
11745 if (!ch) {
11746 send_resp(dut, conn, SIGMA_INVALID,
11747 "errorCode,Nebor_Op_Ch is missing");
11748 return 0;
11749 }
11750
11751 phy_type = get_param(cmd, "Nebor_Phy_Type");
11752 if (!phy_type) {
11753 sigma_dut_print(dut, DUT_MSG_INFO,
11754 "Using default value for Nebor_Phy_Type: %s",
11755 DEFAULT_NEIGHBOR_PHY_TYPE);
11756 phy_type = DEFAULT_NEIGHBOR_PHY_TYPE;
11757 }
11758
11759 /* Parse optional subelements */
11760 buf[0] = '\0';
11761 pref = get_param(cmd, "Nebor_Pref");
11762 if (pref) {
11763 /* hexdump for preferrence subelement */
11764 ret = snprintf(buf, sizeof(buf), ",0301%02x", atoi(pref));
11765 if (ret < 0 || ret >= (int) sizeof(buf)) {
11766 sigma_dut_print(dut, DUT_MSG_ERROR,
11767 "snprintf failed for optional subelement ret: %d",
11768 ret);
11769 send_resp(dut, conn, SIGMA_ERROR,
11770 "errorCode,snprintf failed for subelement");
11771 return 0;
11772 }
11773 }
11774
11775 if (!dut->btm_query_cand_list) {
11776 dut->btm_query_cand_list = calloc(1, NEIGHBOR_REPORT_SIZE);
11777 if (!dut->btm_query_cand_list) {
11778 send_resp(dut, conn, SIGMA_ERROR,
11779 "errorCode,Failed to allocate memory for btm_query_cand_list");
11780 return 0;
11781 }
11782 }
11783
11784 len = strlen(dut->btm_query_cand_list);
11785 ret = snprintf(dut->btm_query_cand_list + len,
11786 NEIGHBOR_REPORT_SIZE - len, " neighbor=%s,%s,%s,%s,%s%s",
11787 bssid, info, op_class, ch, phy_type, buf);
11788 if (ret < 0 || ret >= NEIGHBOR_REPORT_SIZE - len) {
11789 sigma_dut_print(dut, DUT_MSG_ERROR,
11790 "snprintf failed for neighbor report list ret: %d",
11791 ret);
11792 send_resp(dut, conn, SIGMA_ERROR,
11793 "errorCode,snprintf failed for neighbor report");
11794 free(dut->btm_query_cand_list);
11795 dut->btm_query_cand_list = NULL;
11796 return 0;
11797 }
11798
11799 return 1;
11800}
11801
11802
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020011803int sta_extract_60g_ese(struct sigma_dut *dut, struct sigma_cmd *cmd,
11804 struct sigma_ese_alloc *allocs, int *allocs_size)
11805{
11806 int max_count = *allocs_size;
11807 int count = 0, i;
11808 const char *val;
11809
11810 do {
11811 val = get_param_indexed(cmd, "AllocID", count);
11812 if (val)
11813 count++;
11814 } while (val);
11815
11816 if (count == 0 || count > max_count) {
11817 sigma_dut_print(dut, DUT_MSG_ERROR,
11818 "Invalid number of allocations(%d)", count);
11819 return -1;
11820 }
11821
11822 for (i = 0; i < count; i++) {
11823 val = get_param_indexed(cmd, "PercentBI", i);
11824 if (!val) {
11825 sigma_dut_print(dut, DUT_MSG_ERROR,
11826 "Missing PercentBI parameter at index %d",
11827 i);
11828 return -1;
11829 }
11830 allocs[i].percent_bi = atoi(val);
11831
11832 val = get_param_indexed(cmd, "SrcAID", i);
11833 if (val)
11834 allocs[i].src_aid = strtol(val, NULL, 0);
11835 else
11836 allocs[i].src_aid = ESE_BCAST_AID;
11837
11838 val = get_param_indexed(cmd, "DestAID", i);
11839 if (val)
11840 allocs[i].dst_aid = strtol(val, NULL, 0);
11841 else
11842 allocs[i].dst_aid = ESE_BCAST_AID;
11843
11844 allocs[i].type = ESE_CBAP;
11845 sigma_dut_print(dut, DUT_MSG_INFO,
11846 "Alloc %d PercentBI %d SrcAID %d DstAID %d",
11847 i, allocs[i].percent_bi, allocs[i].src_aid,
11848 allocs[i].dst_aid);
11849 }
11850
11851 *allocs_size = count;
11852 return 0;
11853}
11854
11855
11856static int sta_set_60g_ese(struct sigma_dut *dut, int count,
11857 struct sigma_ese_alloc *allocs)
11858{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011859 switch (get_driver_type(dut)) {
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020011860#ifdef __linux__
11861 case DRIVER_WIL6210:
11862 if (wil6210_set_ese(dut, count, allocs))
11863 return -1;
11864 return 1;
11865#endif /* __linux__ */
11866 default:
11867 sigma_dut_print(dut, DUT_MSG_ERROR,
11868 "Unsupported sta_set_60g_ese with the current driver");
11869 return -1;
11870 }
11871}
11872
11873
11874static int cmd_sta_set_rfeature_60g(const char *intf, struct sigma_dut *dut,
11875 struct sigma_conn *conn,
11876 struct sigma_cmd *cmd)
11877{
11878 const char *val;
11879
11880 val = get_param(cmd, "ExtSchIE");
11881 if (val && !strcasecmp(val, "Enable")) {
11882 struct sigma_ese_alloc allocs[MAX_ESE_ALLOCS];
11883 int count = MAX_ESE_ALLOCS;
11884
11885 if (sta_extract_60g_ese(dut, cmd, allocs, &count))
11886 return -1;
11887 return sta_set_60g_ese(dut, count, allocs);
11888 }
11889
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +020011890 val = get_param(cmd, "MCS_FixedRate");
11891 if (val) {
11892 int sta_mcs = atoi(val);
11893
11894 sigma_dut_print(dut, DUT_MSG_INFO, "Force STA MCS to %d",
11895 sta_mcs);
11896 wil6210_set_force_mcs(dut, 1, sta_mcs);
11897
Jouni Malinen0e29cf22019-02-19 01:13:21 +020011898 return SUCCESS_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +020011899 }
11900
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020011901 send_resp(dut, conn, SIGMA_ERROR,
11902 "errorCode,Invalid sta_set_rfeature(60G)");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020011903 return STATUS_SENT;
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020011904}
11905
11906
Jouni Malinenf7222712019-06-13 01:50:21 +030011907static enum sigma_cmd_result cmd_sta_set_rfeature(struct sigma_dut *dut,
11908 struct sigma_conn *conn,
11909 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011910{
11911 const char *intf = get_param(cmd, "Interface");
11912 const char *prog = get_param(cmd, "Prog");
Ashwini Patil68d02cd2017-01-10 15:39:16 +053011913 const char *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011914
11915 if (intf == NULL || prog == NULL)
11916 return -1;
11917
Ashwini Patil5acd7382017-04-13 15:55:04 +053011918 /* BSS Transition candidate list for BTM query */
11919 val = get_param(cmd, "Nebor_BSSID");
11920 if (val && btm_query_candidate_list(dut, conn, cmd) == 0)
11921 return 0;
11922
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011923 if (strcasecmp(prog, "TDLS") == 0)
11924 return cmd_sta_set_rfeature_tdls(intf, dut, conn, cmd);
11925
11926 if (strcasecmp(prog, "VHT") == 0)
11927 return cmd_sta_set_rfeature_vht(intf, dut, conn, cmd);
11928
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011929 if (strcasecmp(prog, "HE") == 0)
11930 return cmd_sta_set_rfeature_he(intf, dut, conn, cmd);
11931
Ashwini Patil68d02cd2017-01-10 15:39:16 +053011932 if (strcasecmp(prog, "MBO") == 0) {
11933 val = get_param(cmd, "Cellular_Data_Cap");
11934 if (val &&
11935 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
11936 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +053011937
11938 val = get_param(cmd, "Ch_Pref");
11939 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
11940 return 0;
11941
Ashwini Patil68d02cd2017-01-10 15:39:16 +053011942 return 1;
11943 }
11944
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020011945 if (strcasecmp(prog, "60GHz") == 0)
11946 return cmd_sta_set_rfeature_60g(intf, dut, conn, cmd);
11947
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011948 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported Prog");
11949 return 0;
11950}
11951
11952
Jouni Malinenf7222712019-06-13 01:50:21 +030011953static enum sigma_cmd_result cmd_sta_set_radio(struct sigma_dut *dut,
11954 struct sigma_conn *conn,
11955 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011956{
11957 const char *intf = get_param(cmd, "Interface");
11958 const char *mode = get_param(cmd, "Mode");
11959 int res;
11960
11961 if (intf == NULL || mode == NULL)
11962 return -1;
11963
11964 if (strcasecmp(mode, "On") == 0)
11965 res = wpa_command(intf, "SET radio_disabled 0");
11966 else if (strcasecmp(mode, "Off") == 0)
11967 res = wpa_command(intf, "SET radio_disabled 1");
11968 else
11969 return -1;
11970
11971 if (res) {
11972 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
11973 "radio mode");
11974 return 0;
11975 }
11976
11977 return 1;
11978}
11979
11980
Jouni Malinenf7222712019-06-13 01:50:21 +030011981static enum sigma_cmd_result cmd_sta_set_pwrsave(struct sigma_dut *dut,
11982 struct sigma_conn *conn,
11983 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011984{
11985 const char *intf = get_param(cmd, "Interface");
11986 const char *mode = get_param(cmd, "Mode");
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020011987 const char *prog = get_param(cmd, "program");
11988 const char *powersave = get_param(cmd, "powersave");
11989 int res = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011990
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020011991 if (intf == NULL)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011992 return -1;
11993
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020011994 if (prog && strcasecmp(prog, "60GHz") == 0) {
11995 /*
11996 * The CAPI mode parameter does not exist in 60G
11997 * unscheduled PS.
11998 */
Hu Wang5dc3ff12019-06-14 15:14:26 +080011999 if (powersave && strcasecmp(powersave, "unscheduled") == 0)
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020012000 res = set_ps(intf, dut, 1);
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012001 } else if (prog && get_driver_type(dut) == DRIVER_WCN &&
Alexei Avshalom Lazar2f6fdb42019-02-04 14:16:08 +020012002 strcasecmp(prog, "HE") == 0) {
12003 return cmd_sta_set_power_save_he(intf, dut, conn, cmd);
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020012004 } else {
12005 if (mode == NULL)
12006 return -1;
12007
12008 if (strcasecmp(mode, "On") == 0)
12009 res = set_ps(intf, dut, 1);
12010 else if (strcasecmp(mode, "Off") == 0)
12011 res = set_ps(intf, dut, 0);
12012 else
12013 return -1;
12014 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012015
12016 if (res) {
12017 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
12018 "power save mode");
12019 return 0;
12020 }
12021
12022 return 1;
12023}
12024
12025
Jouni Malinenf7222712019-06-13 01:50:21 +030012026static enum sigma_cmd_result cmd_sta_bssid_pool(struct sigma_dut *dut,
12027 struct sigma_conn *conn,
12028 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012029{
12030 const char *intf = get_param(cmd, "Interface");
12031 const char *val, *bssid;
12032 int res;
12033 char *buf;
12034 size_t buf_len;
12035
12036 val = get_param(cmd, "BSSID_FILTER");
12037 if (val == NULL)
12038 return -1;
12039
12040 bssid = get_param(cmd, "BSSID_List");
12041 if (atoi(val) == 0 || bssid == NULL) {
12042 /* Disable BSSID filter */
12043 if (wpa_command(intf, "SET bssid_filter ")) {
12044 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed "
12045 "to disable BSSID filter");
12046 return 0;
12047 }
12048
12049 return 1;
12050 }
12051
12052 buf_len = 100 + strlen(bssid);
12053 buf = malloc(buf_len);
12054 if (buf == NULL)
12055 return -1;
12056
12057 snprintf(buf, buf_len, "SET bssid_filter %s", bssid);
12058 res = wpa_command(intf, buf);
12059 free(buf);
12060 if (res) {
12061 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to enable "
12062 "BSSID filter");
12063 return 0;
12064 }
12065
12066 return 1;
12067}
12068
12069
Jouni Malinenf7222712019-06-13 01:50:21 +030012070static enum sigma_cmd_result cmd_sta_reset_parm(struct sigma_dut *dut,
12071 struct sigma_conn *conn,
12072 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012073{
12074 const char *intf = get_param(cmd, "Interface");
12075 const char *val;
12076
12077 /* TODO: ARP */
12078
12079 val = get_param(cmd, "HS2_CACHE_PROFILE");
12080 if (val && strcasecmp(val, "All") == 0)
12081 hs2_clear_credentials(intf);
12082
12083 return 1;
12084}
12085
12086
Jouni Malinenf7222712019-06-13 01:50:21 +030012087static enum sigma_cmd_result cmd_sta_get_key(struct sigma_dut *dut,
12088 struct sigma_conn *conn,
12089 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012090{
12091 const char *intf = get_param(cmd, "Interface");
12092 const char *key_type = get_param(cmd, "KeyType");
12093 char buf[100], resp[200];
12094
12095 if (key_type == NULL)
12096 return -1;
12097
12098 if (strcasecmp(key_type, "GTK") == 0) {
12099 if (wpa_command_resp(intf, "GET gtk", buf, sizeof(buf)) < 0 ||
12100 strncmp(buf, "FAIL", 4) == 0) {
12101 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12102 "not fetch current GTK");
12103 return 0;
12104 }
12105 snprintf(resp, sizeof(resp), "KeyValue,%s", buf);
12106 send_resp(dut, conn, SIGMA_COMPLETE, resp);
12107 return 0;
12108 } else {
12109 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
12110 "KeyType");
12111 return 0;
12112 }
12113
12114 return 1;
12115}
12116
12117
12118static int hs2_set_policy(struct sigma_dut *dut)
12119{
12120#ifdef ANDROID
12121 system("ip rule del prio 23000");
12122 if (system("ip rule add from all lookup main prio 23000") != 0) {
12123 sigma_dut_print(dut, DUT_MSG_ERROR,
12124 "Failed to run:ip rule add from all lookup main prio");
12125 return -1;
12126 }
12127 if (system("ip route flush cache") != 0) {
12128 sigma_dut_print(dut, DUT_MSG_ERROR,
12129 "Failed to run ip route flush cache");
12130 return -1;
12131 }
12132 return 1;
12133#else /* ANDROID */
12134 return 0;
12135#endif /* ANDROID */
12136}
12137
12138
Jouni Malinenf7222712019-06-13 01:50:21 +030012139static enum sigma_cmd_result cmd_sta_hs2_associate(struct sigma_dut *dut,
12140 struct sigma_conn *conn,
12141 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012142{
12143 const char *intf = get_param(cmd, "Interface");
12144 const char *val = get_param(cmd, "Ignore_blacklist");
Jouni Malinen439352d2018-09-13 03:42:23 +030012145 const char *band = get_param(cmd, "Band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012146 struct wpa_ctrl *ctrl;
Jouni Malinen3aa72862019-05-29 23:14:51 +030012147 int res, r;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012148 char bssid[20], ssid[40], resp[100], buf[100], blacklisted[100];
12149 int tries = 0;
12150 int ignore_blacklist = 0;
12151 const char *events[] = {
12152 "CTRL-EVENT-CONNECTED",
12153 "INTERWORKING-BLACKLISTED",
12154 "INTERWORKING-NO-MATCH",
12155 NULL
12156 };
12157
12158 start_sta_mode(dut);
12159
Jouni Malinen439352d2018-09-13 03:42:23 +030012160 if (band) {
12161 if (strcmp(band, "2.4") == 0) {
12162 wpa_command(intf, "SET setband 2G");
12163 } else if (strcmp(band, "5") == 0) {
12164 wpa_command(intf, "SET setband 5G");
12165 } else {
12166 send_resp(dut, conn, SIGMA_ERROR,
12167 "errorCode,Unsupported band");
12168 return 0;
12169 }
12170 }
12171
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012172 blacklisted[0] = '\0';
12173 if (val && atoi(val))
12174 ignore_blacklist = 1;
12175
12176try_again:
12177 ctrl = open_wpa_mon(intf);
12178 if (ctrl == NULL) {
12179 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
12180 "wpa_supplicant monitor connection");
12181 return -2;
12182 }
12183
12184 tries++;
12185 if (wpa_command(intf, "INTERWORKING_SELECT auto")) {
12186 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start "
12187 "Interworking connection");
12188 wpa_ctrl_detach(ctrl);
12189 wpa_ctrl_close(ctrl);
12190 return 0;
12191 }
12192
12193 buf[0] = '\0';
12194 while (1) {
12195 char *pos;
12196 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
12197 pos = strstr(buf, "INTERWORKING-BLACKLISTED");
12198 if (!pos)
12199 break;
12200 pos += 25;
12201 sigma_dut_print(dut, DUT_MSG_DEBUG, "Found blacklisted AP: %s",
12202 pos);
12203 if (!blacklisted[0])
12204 memcpy(blacklisted, pos, strlen(pos) + 1);
12205 }
12206
12207 if (ignore_blacklist && blacklisted[0]) {
12208 char *end;
12209 end = strchr(blacklisted, ' ');
12210 if (end)
12211 *end = '\0';
12212 sigma_dut_print(dut, DUT_MSG_DEBUG, "Try to connect to a blacklisted network: %s",
12213 blacklisted);
Jouni Malinen3aa72862019-05-29 23:14:51 +030012214 r = snprintf(buf, sizeof(buf), "INTERWORKING_CONNECT %s",
12215 blacklisted);
12216 if (r < 0 || r >= sizeof(buf) || wpa_command(intf, buf)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012217 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start Interworking connection to blacklisted network");
12218 wpa_ctrl_detach(ctrl);
12219 wpa_ctrl_close(ctrl);
12220 return 0;
12221 }
12222 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
12223 buf, sizeof(buf));
12224 }
12225
12226 wpa_ctrl_detach(ctrl);
12227 wpa_ctrl_close(ctrl);
12228
12229 if (res < 0) {
12230 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
12231 "connect");
12232 return 0;
12233 }
12234
12235 if (strstr(buf, "INTERWORKING-NO-MATCH") ||
12236 strstr(buf, "INTERWORKING-BLACKLISTED")) {
12237 if (tries < 2) {
12238 sigma_dut_print(dut, DUT_MSG_INFO, "No match found - try again to verify no APs were missed in the scan");
12239 goto try_again;
12240 }
12241 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,No network with "
12242 "matching credentials found");
12243 return 0;
12244 }
12245
12246 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
12247 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
12248 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
12249 "get current BSSID/SSID");
12250 return 0;
12251 }
12252
12253 snprintf(resp, sizeof(resp), "SSID,%s,BSSID,%s", ssid, bssid);
12254 send_resp(dut, conn, SIGMA_COMPLETE, resp);
12255 hs2_set_policy(dut);
12256 return 0;
12257}
12258
12259
Jouni Malinenf7222712019-06-13 01:50:21 +030012260static enum sigma_cmd_result cmd_sta_hs2_venue_info(struct sigma_dut *dut,
12261 struct sigma_conn *conn,
12262 struct sigma_cmd *cmd)
Jouni Malinenb639f1c2018-09-13 02:39:46 +030012263{
12264 const char *intf = get_param(cmd, "Interface");
12265 const char *display = get_param(cmd, "Display");
12266 struct wpa_ctrl *ctrl;
12267 char buf[300], params[400], *pos;
12268 char bssid[20];
12269 int info_avail = 0;
12270 unsigned int old_timeout;
12271 int res;
12272
12273 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0) {
12274 send_resp(dut, conn, SIGMA_ERROR,
12275 "ErrorCode,Could not get current BSSID");
12276 return 0;
12277 }
12278 ctrl = open_wpa_mon(intf);
12279 if (!ctrl) {
12280 sigma_dut_print(dut, DUT_MSG_ERROR,
12281 "Failed to open wpa_supplicant monitor connection");
12282 return -2;
12283 }
12284
12285 snprintf(buf, sizeof(buf), "ANQP_GET %s 277", bssid);
12286 wpa_command(intf, buf);
12287
12288 res = get_wpa_cli_event(dut, ctrl, "GAS-QUERY-DONE", buf, sizeof(buf));
12289 if (res < 0) {
12290 send_resp(dut, conn, SIGMA_ERROR,
12291 "ErrorCode,Could not complete GAS query");
12292 goto fail;
12293 }
12294
12295 old_timeout = dut->default_timeout;
12296 dut->default_timeout = 2;
12297 res = get_wpa_cli_event(dut, ctrl, "RX-VENUE-URL", buf, sizeof(buf));
12298 dut->default_timeout = old_timeout;
12299 if (res < 0)
12300 goto done;
12301 pos = strchr(buf, ' ');
12302 if (!pos)
12303 goto done;
12304 pos++;
12305 pos = strchr(pos, ' ');
12306 if (!pos)
12307 goto done;
12308 pos++;
12309 info_avail = 1;
12310 snprintf(params, sizeof(params), "browser %s", pos);
12311
12312 if (display && strcasecmp(display, "Yes") == 0) {
12313 pid_t pid;
12314
12315 pid = fork();
12316 if (pid < 0) {
12317 perror("fork");
12318 return -1;
12319 }
12320
12321 if (pid == 0) {
12322 run_hs20_osu(dut, params);
12323 exit(0);
12324 }
12325 }
12326
12327done:
12328 snprintf(buf, sizeof(buf), "Info_available,%s",
12329 info_avail ? "Yes" : "No");
12330 send_resp(dut, conn, SIGMA_COMPLETE, buf);
12331fail:
12332 wpa_ctrl_detach(ctrl);
12333 wpa_ctrl_close(ctrl);
12334 return 0;
12335}
12336
12337
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012338static int sta_add_credential_uname_pwd(struct sigma_dut *dut,
12339 struct sigma_conn *conn,
12340 const char *ifname,
12341 struct sigma_cmd *cmd)
12342{
12343 const char *val;
12344 int id;
12345
12346 id = add_cred(ifname);
12347 if (id < 0)
12348 return -2;
12349 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
12350
12351 val = get_param(cmd, "prefer");
12352 if (val && atoi(val) > 0)
12353 set_cred(ifname, id, "priority", "1");
12354
12355 val = get_param(cmd, "REALM");
12356 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
12357 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12358 "realm");
12359 return 0;
12360 }
12361
12362 val = get_param(cmd, "HOME_FQDN");
12363 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
12364 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12365 "home_fqdn");
12366 return 0;
12367 }
12368
12369 val = get_param(cmd, "Username");
12370 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
12371 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12372 "username");
12373 return 0;
12374 }
12375
12376 val = get_param(cmd, "Password");
12377 if (val && set_cred_quoted(ifname, id, "password", val) < 0) {
12378 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12379 "password");
12380 return 0;
12381 }
12382
12383 val = get_param(cmd, "ROOT_CA");
12384 if (val) {
12385 char fname[200];
12386 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
12387#ifdef __linux__
12388 if (!file_exists(fname)) {
12389 char msg[300];
12390 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
12391 "file (%s) not found", fname);
12392 send_resp(dut, conn, SIGMA_ERROR, msg);
12393 return 0;
12394 }
12395#endif /* __linux__ */
12396 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
12397 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12398 "not set root CA");
12399 return 0;
12400 }
12401 }
12402
12403 return 1;
12404}
12405
12406
12407static int update_devdetail_imsi(struct sigma_dut *dut, const char *imsi)
12408{
12409 FILE *in, *out;
12410 char buf[500];
12411 int found = 0;
12412
12413 in = fopen("devdetail.xml", "r");
12414 if (in == NULL)
12415 return -1;
12416 out = fopen("devdetail.xml.tmp", "w");
12417 if (out == NULL) {
12418 fclose(in);
12419 return -1;
12420 }
12421
12422 while (fgets(buf, sizeof(buf), in)) {
12423 char *pos = strstr(buf, "<IMSI>");
12424 if (pos) {
12425 sigma_dut_print(dut, DUT_MSG_INFO, "Updated DevDetail IMSI to %s",
12426 imsi);
12427 pos += 6;
12428 *pos = '\0';
12429 fprintf(out, "%s%s</IMSI>\n", buf, imsi);
12430 found++;
12431 } else {
12432 fprintf(out, "%s", buf);
12433 }
12434 }
12435
12436 fclose(out);
12437 fclose(in);
12438 if (found)
12439 rename("devdetail.xml.tmp", "devdetail.xml");
12440 else
12441 unlink("devdetail.xml.tmp");
12442
12443 return 0;
12444}
12445
12446
12447static int sta_add_credential_sim(struct sigma_dut *dut,
12448 struct sigma_conn *conn,
12449 const char *ifname, struct sigma_cmd *cmd)
12450{
12451 const char *val, *imsi = NULL;
12452 int id;
12453 char buf[200];
12454 int res;
12455 const char *pos;
12456 size_t mnc_len;
12457 char plmn_mcc[4];
12458 char plmn_mnc[4];
12459
12460 id = add_cred(ifname);
12461 if (id < 0)
12462 return -2;
12463 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
12464
12465 val = get_param(cmd, "prefer");
12466 if (val && atoi(val) > 0)
12467 set_cred(ifname, id, "priority", "1");
12468
12469 val = get_param(cmd, "PLMN_MCC");
12470 if (val == NULL) {
12471 send_resp(dut, conn, SIGMA_ERROR,
12472 "errorCode,Missing PLMN_MCC");
12473 return 0;
12474 }
12475 if (strlen(val) != 3) {
12476 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MCC");
12477 return 0;
12478 }
12479 snprintf(plmn_mcc, sizeof(plmn_mcc), "%s", val);
12480
12481 val = get_param(cmd, "PLMN_MNC");
12482 if (val == NULL) {
12483 send_resp(dut, conn, SIGMA_ERROR,
12484 "errorCode,Missing PLMN_MNC");
12485 return 0;
12486 }
12487 if (strlen(val) != 2 && strlen(val) != 3) {
12488 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MNC");
12489 return 0;
12490 }
12491 snprintf(plmn_mnc, sizeof(plmn_mnc), "%s", val);
12492
12493 val = get_param(cmd, "IMSI");
12494 if (val == NULL) {
12495 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing SIM "
12496 "IMSI");
12497 return 0;
12498 }
12499
12500 imsi = pos = val;
12501
12502 if (strncmp(plmn_mcc, pos, 3) != 0) {
12503 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MCC mismatch");
12504 return 0;
12505 }
12506 pos += 3;
12507
12508 mnc_len = strlen(plmn_mnc);
12509 if (mnc_len < 2) {
12510 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC not set");
12511 return 0;
12512 }
12513
12514 if (strncmp(plmn_mnc, pos, mnc_len) != 0) {
12515 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC mismatch");
12516 return 0;
12517 }
12518 pos += mnc_len;
12519
12520 res = snprintf(buf, sizeof(buf), "%s%s-%s",plmn_mcc, plmn_mnc, pos);
12521 if (res < 0 || res >= (int) sizeof(buf))
12522 return -1;
12523 if (set_cred_quoted(ifname, id, "imsi", buf) < 0) {
12524 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12525 "not set IMSI");
12526 return 0;
12527 }
12528
12529 val = get_param(cmd, "Password");
12530 if (val && set_cred_quoted(ifname, id, "milenage", val) < 0) {
12531 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12532 "not set password");
12533 return 0;
12534 }
12535
Jouni Malinenba630452018-06-22 11:49:59 +030012536 if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012537 /*
12538 * Set provisioning_sp for the test cases where SIM/USIM
12539 * provisioning is used.
12540 */
12541 if (val && set_cred_quoted(ifname, id, "provisioning_sp",
12542 "wi-fi.org") < 0) {
12543 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12544 "not set provisioning_sp");
12545 return 0;
12546 }
12547
12548 update_devdetail_imsi(dut, imsi);
12549 }
12550
12551 return 1;
12552}
12553
12554
12555static int sta_add_credential_cert(struct sigma_dut *dut,
12556 struct sigma_conn *conn,
12557 const char *ifname,
12558 struct sigma_cmd *cmd)
12559{
12560 const char *val;
12561 int id;
12562
12563 id = add_cred(ifname);
12564 if (id < 0)
12565 return -2;
12566 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
12567
12568 val = get_param(cmd, "prefer");
12569 if (val && atoi(val) > 0)
12570 set_cred(ifname, id, "priority", "1");
12571
12572 val = get_param(cmd, "REALM");
12573 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
12574 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12575 "realm");
12576 return 0;
12577 }
12578
12579 val = get_param(cmd, "HOME_FQDN");
12580 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
12581 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12582 "home_fqdn");
12583 return 0;
12584 }
12585
12586 val = get_param(cmd, "Username");
12587 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
12588 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12589 "username");
12590 return 0;
12591 }
12592
12593 val = get_param(cmd, "clientCertificate");
12594 if (val) {
12595 char fname[200];
12596 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
12597#ifdef __linux__
12598 if (!file_exists(fname)) {
12599 char msg[300];
12600 snprintf(msg, sizeof(msg),
12601 "ErrorCode,clientCertificate "
12602 "file (%s) not found", fname);
12603 send_resp(dut, conn, SIGMA_ERROR, msg);
12604 return 0;
12605 }
12606#endif /* __linux__ */
12607 if (set_cred_quoted(ifname, id, "client_cert", fname) < 0) {
12608 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12609 "not set client_cert");
12610 return 0;
12611 }
12612 if (set_cred_quoted(ifname, id, "private_key", fname) < 0) {
12613 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12614 "not set private_key");
12615 return 0;
12616 }
12617 }
12618
12619 val = get_param(cmd, "ROOT_CA");
12620 if (val) {
12621 char fname[200];
12622 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
12623#ifdef __linux__
12624 if (!file_exists(fname)) {
12625 char msg[300];
12626 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
12627 "file (%s) not found", fname);
12628 send_resp(dut, conn, SIGMA_ERROR, msg);
12629 return 0;
12630 }
12631#endif /* __linux__ */
12632 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
12633 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12634 "not set root CA");
12635 return 0;
12636 }
12637 }
12638
12639 return 1;
12640}
12641
12642
Jouni Malinenf7222712019-06-13 01:50:21 +030012643static enum sigma_cmd_result cmd_sta_add_credential(struct sigma_dut *dut,
12644 struct sigma_conn *conn,
12645 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012646{
12647 const char *intf = get_param(cmd, "Interface");
12648 const char *type;
12649
12650 start_sta_mode(dut);
12651
12652 type = get_param(cmd, "Type");
12653 if (!type)
12654 return -1;
12655
12656 if (strcasecmp(type, "uname_pwd") == 0)
12657 return sta_add_credential_uname_pwd(dut, conn, intf, cmd);
12658
12659 if (strcasecmp(type, "sim") == 0)
12660 return sta_add_credential_sim(dut, conn, intf, cmd);
12661
12662 if (strcasecmp(type, "cert") == 0)
12663 return sta_add_credential_cert(dut, conn, intf, cmd);
12664
12665 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported credential "
12666 "type");
12667 return 0;
12668}
12669
12670
Jouni Malinenf7222712019-06-13 01:50:21 +030012671static enum sigma_cmd_result cmd_sta_scan(struct sigma_dut *dut,
12672 struct sigma_conn *conn,
12673 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012674{
12675 const char *intf = get_param(cmd, "Interface");
vamsi krishna89ad8c62017-09-19 12:51:18 +053012676 const char *val, *bssid, *ssid;
Arif Hussain66a4af02019-02-07 15:04:51 -080012677 char buf[4096];
vamsi krishna89ad8c62017-09-19 12:51:18 +053012678 char ssid_hex[65];
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012679 int res;
12680
Jouni Malinen8c1abeb2019-11-06 18:48:34 +020012681 start_sta_mode(dut);
12682
Arif Hussain66a4af02019-02-07 15:04:51 -080012683 val = get_param(cmd, "GetParameter");
12684 if (val && strcmp(val, "SSID_BSSID") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012685 if (get_wpa_ssid_bssid(dut, get_station_ifname(dut),
Arif Hussain66a4af02019-02-07 15:04:51 -080012686 buf, sizeof(buf)) < 0) {
12687 sigma_dut_print(dut, DUT_MSG_ERROR,
12688 "Could not get ssid bssid");
12689 return ERROR_SEND_STATUS;
12690 }
12691
12692 sigma_dut_print(dut, DUT_MSG_INFO, "%s", buf);
12693 send_resp(dut, conn, SIGMA_COMPLETE, buf);
12694 return STATUS_SENT;
12695 }
12696
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012697 val = get_param(cmd, "HESSID");
12698 if (val) {
12699 res = snprintf(buf, sizeof(buf), "SET hessid %s", val);
12700 if (res < 0 || res >= (int) sizeof(buf))
12701 return -1;
12702 wpa_command(intf, buf);
12703 }
12704
12705 val = get_param(cmd, "ACCS_NET_TYPE");
12706 if (val) {
12707 res = snprintf(buf, sizeof(buf), "SET access_network_type %s",
12708 val);
12709 if (res < 0 || res >= (int) sizeof(buf))
12710 return -1;
12711 wpa_command(intf, buf);
12712 }
12713
vamsi krishna89ad8c62017-09-19 12:51:18 +053012714 bssid = get_param(cmd, "Bssid");
12715 ssid = get_param(cmd, "Ssid");
12716
12717 if (ssid) {
12718 if (2 * strlen(ssid) >= sizeof(ssid_hex)) {
12719 send_resp(dut, conn, SIGMA_ERROR,
12720 "ErrorCode,Too long SSID");
12721 return 0;
12722 }
12723 ascii2hexstr(ssid, ssid_hex);
12724 }
12725
12726 res = snprintf(buf, sizeof(buf), "SCAN%s%s%s%s",
12727 bssid ? " bssid=": "",
12728 bssid ? bssid : "",
12729 ssid ? " ssid " : "",
12730 ssid ? ssid_hex : "");
12731 if (res < 0 || res >= (int) sizeof(buf))
12732 return -1;
12733
12734 if (wpa_command(intf, buf)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012735 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not start "
12736 "scan");
12737 return 0;
12738 }
12739
12740 return 1;
12741}
12742
12743
Jouni Malinenf7222712019-06-13 01:50:21 +030012744static enum sigma_cmd_result cmd_sta_scan_bss(struct sigma_dut *dut,
12745 struct sigma_conn *conn,
12746 struct sigma_cmd *cmd)
Jouni Malinen5e5d43d2018-01-10 17:29:33 +020012747{
12748 const char *intf = get_param(cmd, "Interface");
12749 const char *bssid;
12750 char buf[4096], *pos;
12751 int freq, chan;
12752 char *ssid;
12753 char resp[100];
12754 int res;
12755 struct wpa_ctrl *ctrl;
12756
12757 bssid = get_param(cmd, "BSSID");
12758 if (!bssid) {
12759 send_resp(dut, conn, SIGMA_INVALID,
12760 "errorCode,BSSID argument is missing");
12761 return 0;
12762 }
12763
12764 ctrl = open_wpa_mon(intf);
12765 if (!ctrl) {
12766 sigma_dut_print(dut, DUT_MSG_ERROR,
12767 "Failed to open wpa_supplicant monitor connection");
12768 return -1;
12769 }
12770
12771 if (wpa_command(intf, "SCAN TYPE=ONLY")) {
12772 send_resp(dut, conn, SIGMA_ERROR,
12773 "errorCode,Could not start scan");
12774 wpa_ctrl_detach(ctrl);
12775 wpa_ctrl_close(ctrl);
12776 return 0;
12777 }
12778
12779 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
12780 buf, sizeof(buf));
12781
12782 wpa_ctrl_detach(ctrl);
12783 wpa_ctrl_close(ctrl);
12784
12785 if (res < 0) {
12786 send_resp(dut, conn, SIGMA_ERROR,
12787 "errorCode,Scan did not complete");
12788 return 0;
12789 }
12790
12791 snprintf(buf, sizeof(buf), "BSS %s", bssid);
12792 if (wpa_command_resp(intf, buf, buf, sizeof(buf)) < 0 ||
12793 strncmp(buf, "id=", 3) != 0) {
12794 send_resp(dut, conn, SIGMA_ERROR,
12795 "errorCode,Specified BSSID not found");
12796 return 0;
12797 }
12798
12799 pos = strstr(buf, "\nfreq=");
12800 if (!pos) {
12801 send_resp(dut, conn, SIGMA_ERROR,
12802 "errorCode,Channel not found");
12803 return 0;
12804 }
12805 freq = atoi(pos + 6);
12806 chan = freq_to_channel(freq);
12807
12808 pos = strstr(buf, "\nssid=");
12809 if (!pos) {
12810 send_resp(dut, conn, SIGMA_ERROR,
12811 "errorCode,SSID not found");
12812 return 0;
12813 }
12814 ssid = pos + 6;
12815 pos = strchr(ssid, '\n');
12816 if (pos)
12817 *pos = '\0';
12818 snprintf(resp, sizeof(resp), "ssid,%s,bsschannel,%d", ssid, chan);
12819 send_resp(dut, conn, SIGMA_COMPLETE, resp);
12820 return 0;
12821}
12822
12823
Jouni Malinenf7222712019-06-13 01:50:21 +030012824static enum sigma_cmd_result cmd_sta_set_systime(struct sigma_dut *dut,
12825 struct sigma_conn *conn,
12826 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012827{
12828#ifdef __linux__
12829 struct timeval tv;
12830 struct tm tm;
12831 time_t t;
12832 const char *val;
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +053012833 int v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012834
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012835 wpa_command(get_station_ifname(dut), "PMKSA_FLUSH");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012836
12837 memset(&tm, 0, sizeof(tm));
12838 val = get_param(cmd, "seconds");
12839 if (val)
12840 tm.tm_sec = atoi(val);
12841 val = get_param(cmd, "minutes");
12842 if (val)
12843 tm.tm_min = atoi(val);
12844 val = get_param(cmd, "hours");
12845 if (val)
12846 tm.tm_hour = atoi(val);
12847 val = get_param(cmd, "date");
12848 if (val)
12849 tm.tm_mday = atoi(val);
12850 val = get_param(cmd, "month");
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +053012851 if (val) {
12852 v = atoi(val);
12853 if (v < 1 || v > 12) {
12854 send_resp(dut, conn, SIGMA_INVALID,
12855 "errorCode,Invalid month");
12856 return 0;
12857 }
12858 tm.tm_mon = v - 1;
12859 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012860 val = get_param(cmd, "year");
12861 if (val) {
12862 int year = atoi(val);
12863#ifdef ANDROID
12864 if (year > 2035)
12865 year = 2035; /* years beyond 2035 not supported */
12866#endif /* ANDROID */
12867 tm.tm_year = year - 1900;
12868 }
12869 t = mktime(&tm);
12870 if (t == (time_t) -1) {
12871 send_resp(dut, conn, SIGMA_ERROR,
12872 "errorCode,Invalid date or time");
12873 return 0;
12874 }
12875
12876 memset(&tv, 0, sizeof(tv));
12877 tv.tv_sec = t;
12878
12879 if (settimeofday(&tv, NULL) < 0) {
12880 sigma_dut_print(dut, DUT_MSG_INFO, "settimeofday failed: %s",
12881 strerror(errno));
12882 send_resp(dut, conn, SIGMA_ERROR,
12883 "errorCode,Failed to set time");
12884 return 0;
12885 }
12886
12887 return 1;
12888#endif /* __linux__ */
12889
12890 return -1;
12891}
12892
12893
Jouni Malinenf7222712019-06-13 01:50:21 +030012894static enum sigma_cmd_result cmd_sta_osu(struct sigma_dut *dut,
12895 struct sigma_conn *conn,
12896 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012897{
12898 const char *intf = get_param(cmd, "Interface");
Jouni Malinen4c8681c2018-09-12 23:28:11 +030012899 const char *name, *osu_ssid, *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012900 int prod_ess_assoc = 1;
Jouni Malinen4c8681c2018-09-12 23:28:11 +030012901 char buf[300], bssid[100], ssid[100];
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012902 int res;
12903 struct wpa_ctrl *ctrl;
12904
12905 name = get_param(cmd, "osuFriendlyName");
Jouni Malinen4c8681c2018-09-12 23:28:11 +030012906 osu_ssid = get_param(cmd, "osu_ssid");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012907
12908 val = get_param(cmd, "ProdESSAssoc");
12909 if (val)
12910 prod_ess_assoc = atoi(val);
12911
12912 kill_dhcp_client(dut, intf);
12913 if (start_dhcp_client(dut, intf) < 0)
12914 return -2;
12915
12916 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger OSU");
12917 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
12918 res = snprintf(buf, sizeof(buf),
Jouni Malinen4c8681c2018-09-12 23:28:11 +030012919 "%s %s%s%s %s%s%s signup osu-ca.pem",
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012920 prod_ess_assoc ? "" : "-N",
12921 name ? "-O'" : "", name ? name : "",
Jouni Malinen4c8681c2018-09-12 23:28:11 +030012922 name ? "'" : "",
12923 osu_ssid ? "-o'" : "", osu_ssid ? osu_ssid : "",
12924 osu_ssid ? "'" : "");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012925
Kanchanapally, Vidyullatha12b66762015-12-31 16:46:42 +053012926 hs2_set_policy(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012927 if (run_hs20_osu(dut, buf) < 0) {
12928 FILE *f;
12929
12930 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to complete OSU");
12931
12932 f = fopen("hs20-osu-client.res", "r");
12933 if (f) {
12934 char resp[400], res[300], *pos;
12935 if (!fgets(res, sizeof(res), f))
12936 res[0] = '\0';
12937 pos = strchr(res, '\n');
12938 if (pos)
12939 *pos = '\0';
12940 fclose(f);
12941 sigma_dut_summary(dut, "hs20-osu-client provisioning failed: %s",
12942 res);
12943 snprintf(resp, sizeof(resp), "notify-send '%s'", res);
12944 if (system(resp) != 0) {
12945 }
12946 snprintf(resp, sizeof(resp),
12947 "SSID,,BSSID,,failureReason,%s", res);
12948 send_resp(dut, conn, SIGMA_COMPLETE, resp);
12949 return 0;
12950 }
12951
12952 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
12953 return 0;
12954 }
12955
12956 if (!prod_ess_assoc)
12957 goto report;
12958
12959 ctrl = open_wpa_mon(intf);
12960 if (ctrl == NULL) {
12961 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
12962 "wpa_supplicant monitor connection");
12963 return -1;
12964 }
12965
12966 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
12967 buf, sizeof(buf));
12968
12969 wpa_ctrl_detach(ctrl);
12970 wpa_ctrl_close(ctrl);
12971
12972 if (res < 0) {
12973 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to connect to "
12974 "network after OSU");
12975 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
12976 return 0;
12977 }
12978
12979report:
12980 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
12981 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
12982 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to get BSSID/SSID");
12983 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
12984 return 0;
12985 }
12986
12987 snprintf(buf, sizeof(buf), "SSID,%s,BSSID,%s", ssid, bssid);
12988 send_resp(dut, conn, SIGMA_COMPLETE, buf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012989 return 0;
12990}
12991
12992
Jouni Malinenf7222712019-06-13 01:50:21 +030012993static enum sigma_cmd_result cmd_sta_policy_update(struct sigma_dut *dut,
12994 struct sigma_conn *conn,
12995 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012996{
12997 const char *val;
12998 int timeout = 120;
12999
13000 val = get_param(cmd, "PolicyUpdate");
13001 if (val == NULL || atoi(val) == 0)
13002 return 1; /* No operation requested */
13003
13004 val = get_param(cmd, "Timeout");
13005 if (val)
13006 timeout = atoi(val);
13007
13008 if (timeout) {
13009 /* TODO: time out the command and return
13010 * PolicyUpdateStatus,TIMEOUT if needed. */
13011 }
13012
13013 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger policy update");
13014 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
13015 if (run_hs20_osu(dut, "pol_upd fqdn=wi-fi.org") < 0) {
13016 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,FAIL");
13017 return 0;
13018 }
13019
13020 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,SUCCESS");
13021 return 0;
13022}
13023
13024
Jouni Malinenf7222712019-06-13 01:50:21 +030013025static enum sigma_cmd_result cmd_sta_er_config(struct sigma_dut *dut,
13026 struct sigma_conn *conn,
13027 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013028{
13029 struct wpa_ctrl *ctrl;
13030 const char *intf = get_param(cmd, "Interface");
13031 const char *bssid = get_param(cmd, "Bssid");
13032 const char *ssid = get_param(cmd, "SSID");
13033 const char *security = get_param(cmd, "Security");
13034 const char *passphrase = get_param(cmd, "Passphrase");
13035 const char *pin = get_param(cmd, "PIN");
13036 char buf[1000];
13037 char ssid_hex[200], passphrase_hex[200];
13038 const char *keymgmt, *cipher;
13039
13040 if (intf == NULL)
Jouni Malinen016ae6c2019-11-04 17:00:01 +020013041 intf = get_main_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013042
13043 if (!bssid) {
13044 send_resp(dut, conn, SIGMA_ERROR,
13045 "ErrorCode,Missing Bssid argument");
13046 return 0;
13047 }
13048
13049 if (!ssid) {
13050 send_resp(dut, conn, SIGMA_ERROR,
13051 "ErrorCode,Missing SSID argument");
13052 return 0;
13053 }
13054
13055 if (!security) {
13056 send_resp(dut, conn, SIGMA_ERROR,
13057 "ErrorCode,Missing Security argument");
13058 return 0;
13059 }
13060
13061 if (!passphrase) {
13062 send_resp(dut, conn, SIGMA_ERROR,
13063 "ErrorCode,Missing Passphrase argument");
13064 return 0;
13065 }
13066
13067 if (!pin) {
13068 send_resp(dut, conn, SIGMA_ERROR,
13069 "ErrorCode,Missing PIN argument");
13070 return 0;
13071 }
13072
vamsi krishna8c9c1562017-05-12 15:51:46 +053013073 if (2 * strlen(ssid) >= sizeof(ssid_hex) ||
13074 2 * strlen(passphrase) >= sizeof(passphrase_hex)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013075 send_resp(dut, conn, SIGMA_ERROR,
13076 "ErrorCode,Too long SSID/passphrase");
13077 return 0;
13078 }
13079
13080 ctrl = open_wpa_mon(intf);
13081 if (ctrl == NULL) {
13082 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
13083 "wpa_supplicant monitor connection");
13084 return -2;
13085 }
13086
13087 if (strcasecmp(security, "wpa2-psk") == 0) {
13088 keymgmt = "WPA2PSK";
13089 cipher = "CCMP";
13090 } else {
13091 wpa_ctrl_detach(ctrl);
13092 wpa_ctrl_close(ctrl);
13093 send_resp(dut, conn, SIGMA_ERROR,
13094 "ErrorCode,Unsupported Security value");
13095 return 0;
13096 }
13097
13098 ascii2hexstr(ssid, ssid_hex);
13099 ascii2hexstr(passphrase, passphrase_hex);
13100 snprintf(buf, sizeof(buf), "WPS_REG %s %s %s %s %s %s",
13101 bssid, pin, ssid_hex, keymgmt, cipher, passphrase_hex);
13102
13103 if (wpa_command(intf, buf) < 0) {
13104 wpa_ctrl_detach(ctrl);
13105 wpa_ctrl_close(ctrl);
13106 send_resp(dut, conn, SIGMA_ERROR,
13107 "ErrorCode,Failed to start registrar");
13108 return 0;
13109 }
13110
13111 snprintf(dut->er_oper_bssid, sizeof(dut->er_oper_bssid), "%s", bssid);
13112 dut->er_oper_performed = 1;
13113
13114 return wps_connection_event(dut, conn, ctrl, intf, 0);
13115}
13116
13117
Jouni Malinenf7222712019-06-13 01:50:21 +030013118static enum sigma_cmd_result
13119cmd_sta_wps_connect_pw_token(struct sigma_dut *dut, struct sigma_conn *conn,
13120 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013121{
13122 struct wpa_ctrl *ctrl;
13123 const char *intf = get_param(cmd, "Interface");
13124 const char *bssid = get_param(cmd, "Bssid");
13125 char buf[100];
13126
13127 if (!bssid) {
13128 send_resp(dut, conn, SIGMA_ERROR,
13129 "ErrorCode,Missing Bssid argument");
13130 return 0;
13131 }
13132
13133 ctrl = open_wpa_mon(intf);
13134 if (ctrl == NULL) {
13135 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
13136 "wpa_supplicant monitor connection");
13137 return -2;
13138 }
13139
13140 snprintf(buf, sizeof(buf), "WPS_NFC %s", bssid);
13141
13142 if (wpa_command(intf, buf) < 0) {
13143 wpa_ctrl_detach(ctrl);
13144 wpa_ctrl_close(ctrl);
13145 send_resp(dut, conn, SIGMA_ERROR,
13146 "ErrorCode,Failed to start registrar");
13147 return 0;
13148 }
13149
13150 return wps_connection_event(dut, conn, ctrl, intf, 0);
13151}
13152
13153
Jouni Malinenf7222712019-06-13 01:50:21 +030013154static enum sigma_cmd_result cmd_start_wps_registration(struct sigma_dut *dut,
13155 struct sigma_conn *conn,
13156 struct sigma_cmd *cmd)
vamsi krishna9b144002017-09-20 13:28:13 +053013157{
13158 struct wpa_ctrl *ctrl;
13159 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020013160 const char *network_mode = get_param(cmd, "network_mode");
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020013161 const char *config_method = get_param(cmd, "WPSConfigMethod");
13162 const char *role;
vamsi krishna9b144002017-09-20 13:28:13 +053013163 int res;
13164 char buf[256];
13165 const char *events[] = {
13166 "CTRL-EVENT-CONNECTED",
13167 "WPS-OVERLAP-DETECTED",
13168 "WPS-TIMEOUT",
13169 "WPS-FAIL",
13170 NULL
13171 };
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020013172 int id = 0;
vamsi krishna9b144002017-09-20 13:28:13 +053013173
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020013174 /* 60G WPS tests do not pass Interface parameter */
13175 if (!intf)
Jouni Malinen016ae6c2019-11-04 17:00:01 +020013176 intf = get_main_ifname(dut);
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020013177
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020013178 if (dut->mode == SIGMA_MODE_AP)
13179 return ap_wps_registration(dut, conn, cmd);
13180
13181 if (config_method) {
13182 /* WFA_CS_WPS_PIN_KEYPAD mode is set when using the
13183 * sta_wps_enter_pin before calling start_wps_registration. */
13184 if (strcasecmp(config_method, "PBC") == 0)
13185 dut->wps_method = WFA_CS_WPS_PBC;
13186 }
13187 if (dut->wps_method == WFA_CS_WPS_NOT_READY) {
13188 send_resp(dut, conn, SIGMA_ERROR,
13189 "ErrorCode,WPS parameters not yet set");
13190 return STATUS_SENT;
13191 }
13192
13193 /* Make sure WPS is enabled (also for STA mode) */
13194 dut->wps_disable = 0;
13195
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020013196 if (dut->band == WPS_BAND_60G && network_mode &&
13197 strcasecmp(network_mode, "PBSS") == 0) {
13198 sigma_dut_print(dut, DUT_MSG_DEBUG,
13199 "Set PBSS network mode, network id %d", id);
Jouni Malinen016ae6c2019-11-04 17:00:01 +020013200 if (set_network(get_station_ifname(dut), id, "pbss", "1") < 0)
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020013201 return -2;
13202 }
13203
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020013204 if (dut->force_rsn_ie) {
13205 sigma_dut_print(dut, DUT_MSG_DEBUG, "Force RSN_IE: %d",
13206 dut->force_rsn_ie);
13207 if (sta_60g_force_rsn_ie(dut, dut->force_rsn_ie) < 0) {
13208 sigma_dut_print(dut, DUT_MSG_INFO,
13209 "Failed to force RSN_IE");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020013210 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020013211 }
13212 }
13213
vamsi krishna9b144002017-09-20 13:28:13 +053013214 ctrl = open_wpa_mon(intf);
13215 if (!ctrl) {
13216 sigma_dut_print(dut, DUT_MSG_ERROR,
13217 "Failed to open wpa_supplicant monitor connection");
13218 return -2;
13219 }
13220
13221 role = get_param(cmd, "WpsRole");
13222 if (!role) {
13223 send_resp(dut, conn, SIGMA_INVALID,
13224 "ErrorCode,WpsRole not provided");
13225 goto fail;
13226 }
13227
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020013228 if (strcasecmp(role, "Enrollee") != 0) {
13229 /* Registrar role for STA not supported */
13230 send_resp(dut, conn, SIGMA_ERROR,
13231 "ErrorCode,Unsupported WpsRole value");
13232 goto fail;
13233 }
13234
13235 if (is_60g_sigma_dut(dut)) {
13236 if (dut->wps_method == WFA_CS_WPS_PBC)
13237 snprintf(buf, sizeof(buf), "WPS_PBC");
13238 else /* WFA_CS_WPS_PIN_KEYPAD */
13239 snprintf(buf, sizeof(buf), "WPS_PIN any %s",
13240 dut->wps_pin);
13241 if (wpa_command(intf, buf) < 0) {
13242 send_resp(dut, conn, SIGMA_ERROR,
13243 "ErrorCode,Failed to start WPS");
vamsi krishna9b144002017-09-20 13:28:13 +053013244 goto fail;
13245 }
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020013246 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
13247 if (res < 0) {
13248 send_resp(dut, conn, SIGMA_ERROR,
13249 "ErrorCode,WPS connection did not complete");
13250 goto fail;
13251 }
13252 if (strstr(buf, "WPS-TIMEOUT")) {
13253 send_resp(dut, conn, SIGMA_COMPLETE, "WpsState,NoPeer");
13254 } else if (strstr(buf, "WPS-OVERLAP-DETECTED")) {
13255 send_resp(dut, conn, SIGMA_COMPLETE,
13256 "WpsState,OverlapSession");
13257 } else if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
13258 send_resp(dut, conn, SIGMA_COMPLETE,
13259 "WpsState,Successful");
13260 } else {
13261 send_resp(dut, conn, SIGMA_COMPLETE,
13262 "WpsState,Failure");
13263 }
13264 } else {
13265 if (dut->wps_method == WFA_CS_WPS_PBC) {
vamsi krishna9b144002017-09-20 13:28:13 +053013266 if (wpa_command(intf, "WPS_PBC") < 0) {
13267 send_resp(dut, conn, SIGMA_ERROR,
13268 "ErrorCode,Failed to enable PBC");
13269 goto fail;
13270 }
13271 } else {
13272 /* TODO: PIN method */
13273 send_resp(dut, conn, SIGMA_ERROR,
13274 "ErrorCode,Unsupported WpsConfigMethod value");
13275 goto fail;
13276 }
13277 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
13278 if (res < 0) {
13279 send_resp(dut, conn, SIGMA_ERROR,
13280 "ErrorCode,WPS connection did not complete");
13281 goto fail;
13282 }
13283 if (strstr(buf, "WPS-TIMEOUT")) {
13284 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,NoPeer");
13285 } else if (strstr(buf, "WPS-OVERLAP-DETECTED")) {
13286 send_resp(dut, conn, SIGMA_ERROR,
13287 "ErrorCode,OverlapSession");
13288 } else if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
13289 send_resp(dut, conn, SIGMA_COMPLETE, "Successful");
13290 } else {
13291 send_resp(dut, conn, SIGMA_ERROR,
13292 "ErrorCode,WPS operation failed");
13293 }
vamsi krishna9b144002017-09-20 13:28:13 +053013294 }
13295
13296fail:
13297 wpa_ctrl_detach(ctrl);
13298 wpa_ctrl_close(ctrl);
13299 return 0;
13300}
13301
13302
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013303static int req_intf(struct sigma_cmd *cmd)
13304{
13305 return get_param(cmd, "interface") == NULL ? -1 : 0;
13306}
13307
13308
13309void sta_register_cmds(void)
13310{
13311 sigma_dut_reg_cmd("sta_get_ip_config", req_intf,
13312 cmd_sta_get_ip_config);
13313 sigma_dut_reg_cmd("sta_set_ip_config", req_intf,
13314 cmd_sta_set_ip_config);
13315 sigma_dut_reg_cmd("sta_get_info", req_intf, cmd_sta_get_info);
13316 sigma_dut_reg_cmd("sta_get_mac_address", req_intf,
13317 cmd_sta_get_mac_address);
13318 sigma_dut_reg_cmd("sta_is_connected", req_intf, cmd_sta_is_connected);
13319 sigma_dut_reg_cmd("sta_verify_ip_connection", req_intf,
13320 cmd_sta_verify_ip_connection);
13321 sigma_dut_reg_cmd("sta_get_bssid", req_intf, cmd_sta_get_bssid);
13322 sigma_dut_reg_cmd("sta_set_encryption", req_intf,
13323 cmd_sta_set_encryption);
13324 sigma_dut_reg_cmd("sta_set_psk", req_intf, cmd_sta_set_psk);
13325 sigma_dut_reg_cmd("sta_set_eaptls", req_intf, cmd_sta_set_eaptls);
13326 sigma_dut_reg_cmd("sta_set_eapttls", req_intf, cmd_sta_set_eapttls);
13327 sigma_dut_reg_cmd("sta_set_eapsim", req_intf, cmd_sta_set_eapsim);
13328 sigma_dut_reg_cmd("sta_set_peap", req_intf, cmd_sta_set_peap);
13329 sigma_dut_reg_cmd("sta_set_eapfast", req_intf, cmd_sta_set_eapfast);
13330 sigma_dut_reg_cmd("sta_set_eapaka", req_intf, cmd_sta_set_eapaka);
13331 sigma_dut_reg_cmd("sta_set_eapakaprime", req_intf,
13332 cmd_sta_set_eapakaprime);
13333 sigma_dut_reg_cmd("sta_set_security", req_intf, cmd_sta_set_security);
13334 sigma_dut_reg_cmd("sta_set_uapsd", req_intf, cmd_sta_set_uapsd);
13335 /* TODO: sta_set_ibss */
13336 /* TODO: sta_set_mode */
13337 sigma_dut_reg_cmd("sta_set_wmm", req_intf, cmd_sta_set_wmm);
13338 sigma_dut_reg_cmd("sta_associate", req_intf, cmd_sta_associate);
13339 /* TODO: sta_up_load */
13340 sigma_dut_reg_cmd("sta_preset_testparameters", req_intf,
13341 cmd_sta_preset_testparameters);
13342 /* TODO: sta_set_system */
13343 sigma_dut_reg_cmd("sta_set_11n", req_intf, cmd_sta_set_11n);
13344 /* TODO: sta_set_rifs_test */
13345 sigma_dut_reg_cmd("sta_set_wireless", req_intf, cmd_sta_set_wireless);
13346 sigma_dut_reg_cmd("sta_send_addba", req_intf, cmd_sta_send_addba);
13347 /* TODO: sta_send_coexist_mgmt */
13348 sigma_dut_reg_cmd("sta_disconnect", req_intf, cmd_sta_disconnect);
13349 sigma_dut_reg_cmd("sta_reassoc", req_intf, cmd_sta_reassoc);
13350 sigma_dut_reg_cmd("sta_reassociate", req_intf, cmd_sta_reassoc);
13351 sigma_dut_reg_cmd("sta_reset_default", req_intf,
13352 cmd_sta_reset_default);
13353 sigma_dut_reg_cmd("sta_send_frame", req_intf, cmd_sta_send_frame);
13354 sigma_dut_reg_cmd("sta_set_macaddr", req_intf, cmd_sta_set_macaddr);
13355 sigma_dut_reg_cmd("sta_set_rfeature", req_intf, cmd_sta_set_rfeature);
13356 sigma_dut_reg_cmd("sta_set_radio", req_intf, cmd_sta_set_radio);
13357 sigma_dut_reg_cmd("sta_set_pwrsave", req_intf, cmd_sta_set_pwrsave);
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020013358 sigma_dut_reg_cmd("sta_set_power_save", req_intf, cmd_sta_set_pwrsave);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013359 sigma_dut_reg_cmd("sta_bssid_pool", req_intf, cmd_sta_bssid_pool);
13360 sigma_dut_reg_cmd("sta_reset_parm", req_intf, cmd_sta_reset_parm);
13361 sigma_dut_reg_cmd("sta_get_key", req_intf, cmd_sta_get_key);
13362 sigma_dut_reg_cmd("sta_hs2_associate", req_intf,
13363 cmd_sta_hs2_associate);
Jouni Malinenb639f1c2018-09-13 02:39:46 +030013364 sigma_dut_reg_cmd("sta_hs2_venue_info", req_intf,
13365 cmd_sta_hs2_venue_info);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013366 sigma_dut_reg_cmd("sta_add_credential", req_intf,
13367 cmd_sta_add_credential);
13368 sigma_dut_reg_cmd("sta_scan", req_intf, cmd_sta_scan);
Jouni Malinen5e5d43d2018-01-10 17:29:33 +020013369 sigma_dut_reg_cmd("sta_scan_bss", req_intf, cmd_sta_scan_bss);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013370 sigma_dut_reg_cmd("sta_set_systime", NULL, cmd_sta_set_systime);
13371 sigma_dut_reg_cmd("sta_osu", req_intf, cmd_sta_osu);
13372 sigma_dut_reg_cmd("sta_policy_update", req_intf, cmd_sta_policy_update);
13373 sigma_dut_reg_cmd("sta_er_config", NULL, cmd_sta_er_config);
13374 sigma_dut_reg_cmd("sta_wps_connect_pw_token", req_intf,
13375 cmd_sta_wps_connect_pw_token);
Jouni Malinen82905202018-04-29 17:20:10 +030013376 sigma_dut_reg_cmd("sta_exec_action", NULL, cmd_sta_exec_action);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013377 sigma_dut_reg_cmd("sta_get_events", req_intf, cmd_sta_get_events);
13378 sigma_dut_reg_cmd("sta_get_parameter", req_intf, cmd_sta_get_parameter);
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020013379 sigma_dut_reg_cmd("start_wps_registration", NULL,
vamsi krishna9b144002017-09-20 13:28:13 +053013380 cmd_start_wps_registration);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013381}