blob: 9e3f95b3b7426cc8f0fb8ad9f761c1e1b3d3e62b [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
Vinita S. Malooa8b62722020-04-23 01:45:41 +0530234static int set_power_save_wcn(struct sigma_dut *dut, const char *intf, int ps)
235{
236 char buf[100];
237
238 snprintf(buf, sizeof(buf), "iwpriv %s setPower %d", intf, ps);
239 if (system(buf) != 0) {
240 sigma_dut_print(dut, DUT_MSG_ERROR,
241 "iwpriv setPower %d failed", ps);
242 return -1;
243 }
244 return 0;
245}
246
247
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200248int set_ps(const char *intf, struct sigma_dut *dut, int enabled)
249{
250#ifdef __linux__
251 char buf[100];
252
253 if (wifi_chip_type == DRIVER_WCN) {
254 if (enabled) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +0530255 if (set_power_save_wcn(dut, intf, 1) < 0) {
Purushottam Kushwaha304561d2019-12-23 16:57:18 +0530256 snprintf(buf, sizeof(buf),
257 "iwpriv wlan0 dump 906");
258 if (system(buf) != 0)
259 goto set_power_save;
260 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200261 } else {
Vinita S. Malooa8b62722020-04-23 01:45:41 +0530262 if (set_power_save_wcn(dut, intf, 2) < 0) {
Purushottam Kushwaha304561d2019-12-23 16:57:18 +0530263 snprintf(buf, sizeof(buf),
264 "iwpriv wlan0 dump 905");
265 if (system(buf) != 0)
266 goto set_power_save;
267 snprintf(buf, sizeof(buf),
268 "iwpriv wlan0 dump 912");
269 if (system(buf) != 0)
270 goto set_power_save;
271 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200272 }
273
274 return 0;
275 }
276
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530277set_power_save:
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200278 snprintf(buf, sizeof(buf), "./iw dev %s set power_save %s",
279 intf, enabled ? "on" : "off");
280 if (system(buf) != 0) {
281 snprintf(buf, sizeof(buf), "iw dev %s set power_save %s",
282 intf, enabled ? "on" : "off");
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530283 if (system(buf) != 0) {
284 sigma_dut_print(dut, DUT_MSG_ERROR,
285 "Failed to set power save %s",
286 enabled ? "on" : "off");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200287 return -1;
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530288 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200289 }
290
291 return 0;
292#else /* __linux__ */
293 return -1;
294#endif /* __linux__ */
295}
296
297
Lior Davidcc88b562017-01-03 18:52:09 +0200298#ifdef __linux__
Lior David0fe101e2017-03-09 16:09:50 +0200299
Lior Davidcc88b562017-01-03 18:52:09 +0200300static int wil6210_get_debugfs_dir(struct sigma_dut *dut, char *path,
301 size_t len)
302{
303 DIR *dir, *wil_dir;
304 struct dirent *entry;
305 int ret = -1;
306 const char *root_path = "/sys/kernel/debug/ieee80211";
307
308 dir = opendir(root_path);
309 if (!dir)
310 return -2;
311
312 while ((entry = readdir(dir))) {
313 if (strcmp(entry->d_name, ".") == 0 ||
314 strcmp(entry->d_name, "..") == 0)
315 continue;
316
317 if (snprintf(path, len, "%s/%s/wil6210",
318 root_path, entry->d_name) >= (int) len) {
319 ret = -3;
320 break;
321 }
322
323 wil_dir = opendir(path);
324 if (wil_dir) {
325 closedir(wil_dir);
326 ret = 0;
327 break;
328 }
329 }
330
331 closedir(dir);
332 return ret;
333}
Lior David0fe101e2017-03-09 16:09:50 +0200334
335
336static int wil6210_wmi_send(struct sigma_dut *dut, uint16_t command,
337 void *payload, uint16_t length)
338{
339 struct {
340 struct wil_wmi_header hdr;
341 char payload[WIL_WMI_MAX_PAYLOAD];
342 } __attribute__((packed)) cmd;
343 char buf[128], fname[128];
344 size_t towrite, written;
345 FILE *f;
Jouni Malinen3aa72862019-05-29 23:14:51 +0300346 int res;
Lior David0fe101e2017-03-09 16:09:50 +0200347
348 if (length > WIL_WMI_MAX_PAYLOAD) {
349 sigma_dut_print(dut, DUT_MSG_ERROR,
350 "payload too large(%u, max %u)",
351 length, WIL_WMI_MAX_PAYLOAD);
352 return -1;
353 }
354
355 memset(&cmd.hdr, 0, sizeof(cmd.hdr));
356 cmd.hdr.cmd = command;
357 memcpy(cmd.payload, payload, length);
358
359 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
360 sigma_dut_print(dut, DUT_MSG_ERROR,
361 "failed to get wil6210 debugfs dir");
362 return -1;
363 }
364
Jouni Malinen3aa72862019-05-29 23:14:51 +0300365 res = snprintf(fname, sizeof(fname), "%s/wmi_send", buf);
366 if (res < 0 || res >= sizeof(fname))
367 return -1;
Lior David0fe101e2017-03-09 16:09:50 +0200368 f = fopen(fname, "wb");
369 if (!f) {
370 sigma_dut_print(dut, DUT_MSG_ERROR,
371 "failed to open: %s", fname);
372 return -1;
373 }
374
375 towrite = sizeof(cmd.hdr) + length;
376 written = fwrite(&cmd, 1, towrite, f);
377 fclose(f);
378 if (written != towrite) {
379 sigma_dut_print(dut, DUT_MSG_ERROR,
380 "failed to send wmi %u", command);
381 return -1;
382 }
383
384 return 0;
385}
386
387
388static int wil6210_get_sta_info_field(struct sigma_dut *dut, const char *bssid,
389 const char *pattern, unsigned int *field)
390{
391 char buf[128], fname[128];
392 FILE *f;
393 regex_t re;
394 regmatch_t m[2];
Jouni Malinen3aa72862019-05-29 23:14:51 +0300395 int rc, ret = -1, res;
Lior David0fe101e2017-03-09 16:09:50 +0200396
397 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
398 sigma_dut_print(dut, DUT_MSG_ERROR,
399 "failed to get wil6210 debugfs dir");
400 return -1;
401 }
402
Jouni Malinen3aa72862019-05-29 23:14:51 +0300403 res = snprintf(fname, sizeof(fname), "%s/stations", buf);
404 if (res < 0 || res >= sizeof(fname))
405 return -1;
Lior David0fe101e2017-03-09 16:09:50 +0200406 f = fopen(fname, "r");
407 if (!f) {
408 sigma_dut_print(dut, DUT_MSG_ERROR,
409 "failed to open: %s", fname);
410 return -1;
411 }
412
413 if (regcomp(&re, pattern, REG_EXTENDED)) {
414 sigma_dut_print(dut, DUT_MSG_ERROR,
415 "regcomp failed: %s", pattern);
416 goto out;
417 }
418
419 /*
420 * find the entry for the mac address
421 * line is of the form: [n] 11:22:33:44:55:66 state AID aid
422 */
423 while (fgets(buf, sizeof(buf), f)) {
424 if (strcasestr(buf, bssid)) {
425 /* extract the field (CID/AID/state) */
426 rc = regexec(&re, buf, 2, m, 0);
427 if (!rc && (m[1].rm_so >= 0)) {
428 buf[m[1].rm_eo] = 0;
429 *field = atoi(&buf[m[1].rm_so]);
430 ret = 0;
431 break;
432 }
433 }
434 }
435
436 regfree(&re);
437 if (ret)
438 sigma_dut_print(dut, DUT_MSG_ERROR,
439 "could not extract field");
440
441out:
442 fclose(f);
443
444 return ret;
445}
446
447
448static int wil6210_get_cid(struct sigma_dut *dut, const char *bssid,
449 unsigned int *cid)
450{
451 const char *pattern = "\\[([0-9]+)\\]";
452
453 return wil6210_get_sta_info_field(dut, bssid, pattern, cid);
454}
455
456
457static int wil6210_send_brp_rx(struct sigma_dut *dut, const char *mac,
458 int l_rx)
459{
Rakesh Sunki556237d2017-03-30 14:49:31 -0700460 struct wil_wmi_bf_trig_cmd cmd;
Lior David0fe101e2017-03-09 16:09:50 +0200461 unsigned int cid;
462
Rakesh Sunki556237d2017-03-30 14:49:31 -0700463 memset(&cmd, 0, sizeof(cmd));
464
Lior David0fe101e2017-03-09 16:09:50 +0200465 if (wil6210_get_cid(dut, mac, &cid))
466 return -1;
467
468 cmd.bf_type = WIL_WMI_BRP_RX;
469 cmd.sta_id = cid;
470 /* training length (l_rx) is ignored, FW always uses length 16 */
471 return wil6210_wmi_send(dut, WIL_WMI_BF_TRIG_CMDID,
472 &cmd, sizeof(cmd));
473}
474
475
476static int wil6210_send_sls(struct sigma_dut *dut, const char *mac)
477{
Rakesh Sunki556237d2017-03-30 14:49:31 -0700478 struct wil_wmi_bf_trig_cmd cmd;
479
480 memset(&cmd, 0, sizeof(cmd));
Lior David0fe101e2017-03-09 16:09:50 +0200481
482 if (parse_mac_address(dut, mac, (unsigned char *)&cmd.dest_mac))
483 return -1;
484
485 cmd.bf_type = WIL_WMI_SLS;
486 return wil6210_wmi_send(dut, WIL_WMI_BF_TRIG_CMDID,
487 &cmd, sizeof(cmd));
488}
489
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +0200490
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +0200491int wil6210_set_ese(struct sigma_dut *dut, int count,
492 struct sigma_ese_alloc *allocs)
493{
494 struct wil_wmi_ese_cfg cmd = { };
495 int i;
496
497 if (count == 0 || count > WIL_WMI_MAX_ESE_SLOTS)
498 return -1;
499
500 if (dut->ap_bcnint <= 0) {
501 sigma_dut_print(dut, DUT_MSG_ERROR,
502 "invalid beacon interval(%d), check test",
503 dut->ap_bcnint);
504 return -1;
505 }
506
507 cmd.ese_advertisment = WIL_WMI_ADVERTISE_ESE_IN_BEACON;
508 cmd.flags = 0x1d;
509 cmd.num_allocs = count;
510 for (i = 0; i < count; i++) {
511 /*
512 * Convert percent from BI (BI specified in milliseconds)
513 * to absolute duration in microseconds.
514 */
515 cmd.slots[i].duration =
516 (allocs[i].percent_bi * dut->ap_bcnint * 1000) / 100;
517 switch (allocs[i].type) {
518 case ESE_CBAP:
519 cmd.slots[i].slot_type = WIL_WMI_ESE_CBAP;
520 break;
521 case ESE_SP:
522 cmd.slots[i].slot_type = WIL_WMI_ESE_SP;
523 break;
524 default:
525 sigma_dut_print(dut, DUT_MSG_ERROR,
526 "invalid slot type(%d) at index %d",
527 allocs[i].type, i);
528 return -1;
529 }
530 cmd.slots[i].src_aid = allocs[i].src_aid;
531 cmd.slots[i].dst_aid = allocs[i].dst_aid;
532 sigma_dut_print(dut, DUT_MSG_INFO,
533 "slot %d, duration %u, type %d, srcAID %u dstAID %u",
534 i, cmd.slots[i].duration,
535 cmd.slots[i].slot_type, cmd.slots[i].src_aid,
536 cmd.slots[i].dst_aid);
537 }
538
539 return wil6210_wmi_send(dut, WIL_WMI_ESE_CFG_CMDID, &cmd, sizeof(cmd));
540}
541
542
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +0200543int wil6210_set_force_mcs(struct sigma_dut *dut, int force, int mcs)
544{
545 struct wil_wmi_force_mcs cmd = { };
546
547 cmd.module_id = WIL_WMI_UT_HW_SYSAPI;
548 cmd.subtype_id = WIL_WMI_UT_FORCE_MCS;
549 cmd.force_enable = (uint32_t) force;
550 cmd.mcs = (uint32_t) mcs;
551
552 return wil6210_wmi_send(dut, WIL_WMI_UNIT_TEST_CMDID,
553 &cmd, sizeof(cmd));
554}
555
556
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +0200557static int wil6210_force_rsn_ie(struct sigma_dut *dut, int state)
558{
559 struct wil_wmi_force_rsn_ie cmd = { };
560
561 cmd.module_id = WIL_WMI_UT_HW_SYSAPI;
562 cmd.subtype_id = WIL_WMI_UT_FORCE_RSN_IE;
563 cmd.state = (uint32_t) state;
564
565 return wil6210_wmi_send(dut, WIL_WMI_UNIT_TEST_CMDID,
566 &cmd, sizeof(cmd));
567}
568
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +0300569
570/*
571 * this function is also used to configure generic remain-on-channel
572 */
573static int wil6210_p2p_cfg(struct sigma_dut *dut, int freq)
574{
575 struct wil_wmi_p2p_cfg_cmd cmd = { };
576 int channel = freq_to_channel(freq);
577
578 if (channel < 0)
579 return -1;
580 cmd.discovery_mode = WMI_DISCOVERY_MODE_NON_OFFLOAD;
581 cmd.channel = channel - 1;
582 cmd.bcon_interval = WIL_DEFAULT_BI;
583 cmd.discovery_mode = WMI_DISCOVERY_MODE_PEER2PEER;
584
585 return wil6210_wmi_send(dut, WIL_WMI_P2P_CFG_CMDID,
586 &cmd, sizeof(cmd));
587}
588
589
590static int wil6210_remain_on_channel(struct sigma_dut *dut, int freq)
591{
592 int ret = wil6210_p2p_cfg(dut, freq);
593
594 if (ret)
595 return ret;
596
597 ret = wil6210_wmi_send(dut, WIL_WMI_START_LISTEN_CMDID, NULL, 0);
598 if (!ret) {
599 /*
600 * wait a bit to allow FW to setup the radio
601 * especially important if we switch channels
602 */
603 usleep(500000);
604 }
605
606 return ret;
607}
608
609
610static int wil6210_stop_discovery(struct sigma_dut *dut)
611{
612 return wil6210_wmi_send(dut, WIL_WMI_DISCOVERY_STOP_CMDID, NULL, 0);
613}
614
615
616static int wil6210_transmit_frame(struct sigma_dut *dut, int freq,
617 int wait_duration,
618 const char *frame, size_t frame_len)
619{
620 char buf[128], fname[128];
621 FILE *f;
Jouni Malinen3aa72862019-05-29 23:14:51 +0300622 int res = 0, r;
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +0300623 size_t written;
624
625 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
626 sigma_dut_print(dut, DUT_MSG_ERROR,
627 "failed to get wil6210 debugfs dir");
628 return -1;
629 }
Jouni Malinen3aa72862019-05-29 23:14:51 +0300630 r = snprintf(fname, sizeof(fname), "%s/tx_mgmt", buf);
631 if (r < 0 || r >= sizeof(fname))
632 return -1;
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +0300633
634 if (wil6210_remain_on_channel(dut, freq)) {
635 sigma_dut_print(dut, DUT_MSG_ERROR,
636 "failed to listen on channel");
637 return -1;
638 }
639
640 f = fopen(fname, "wb");
641 if (!f) {
642 sigma_dut_print(dut, DUT_MSG_ERROR,
643 "failed to open: %s", fname);
644 res = -1;
645 goto out_stop;
646 }
647 written = fwrite(frame, 1, frame_len, f);
648 fclose(f);
649
650 if (written != frame_len) {
651 sigma_dut_print(dut, DUT_MSG_ERROR,
652 "failed to transmit frame (got %zd, expected %zd)",
653 written, frame_len);
654 res = -1;
655 goto out_stop;
656 }
657
658 usleep(wait_duration * 1000);
659
660out_stop:
661 wil6210_stop_discovery(dut);
662 return res;
663}
664
665
666static int find_template_frame_tag(struct template_frame_tag *tags,
667 int total_tags, int tag_num)
668{
669 int i;
670
671 for (i = 0; i < total_tags; i++) {
672 if (tag_num == tags[i].num)
673 return i;
674 }
675
676 return -1;
677}
678
679
680static int replace_p2p_attribute(struct sigma_dut *dut, char *buf, size_t len,
681 int id, const char *value, size_t val_len)
682{
683 struct wfa_p2p_attribute *attr = (struct wfa_p2p_attribute *) buf;
684
685 if (len < 3 + val_len) {
686 sigma_dut_print(dut, DUT_MSG_ERROR,
687 "not enough space to replace P2P attribute");
688 return -1;
689 }
690
691 if (attr->len != val_len) {
692 sigma_dut_print(dut, DUT_MSG_ERROR,
693 "attribute length mismatch (need %zu have %hu)",
694 val_len, attr->len);
695 return -1;
696 }
697
698 if (attr->id != id) {
699 sigma_dut_print(dut, DUT_MSG_ERROR,
700 "incorrect attribute id (expected %d actual %d)",
701 id, attr->id);
702 return -1;
703 }
704
705 memcpy(attr->variable, value, val_len);
706
707 return 0;
708}
709
710
711static int parse_template_frame_file(struct sigma_dut *dut, const char *fname,
712 char *buf, size_t *length,
713 struct template_frame_tag *tags,
714 size_t *num_tags)
715{
716 char line[512];
717 FILE *f;
718 size_t offset = 0, tag_index = 0;
719 int num, index;
720 int in_tag = 0, tag_num = 0, tag_offset = 0;
721
722 if (*length < sizeof(struct ieee80211_hdr_3addr)) {
723 sigma_dut_print(dut, DUT_MSG_ERROR,
724 "supplied buffer is too small");
725 return -1;
726 }
727
728 f = fopen(fname, "r");
729 if (!f) {
730 sigma_dut_print(dut, DUT_MSG_ERROR,
731 "failed to open template file %s", fname);
732 return -1;
733 }
734
735 /*
736 * template file format: lines beginning with # are comments and
737 * ignored.
738 * It is possible to tag bytes in the frame to make it easy
739 * to replace fields in the template, espcially if they appear
740 * in variable-sized sections (such as IEs)
741 * This is done by a line beginning with $NUM where NUM is an integer
742 * tag number. It can be followed by space(s) and comment.
743 * The next line is considered the tagged bytes. The parser will fill
744 * the tag number, offset and length of the tagged bytes.
745 * rest of the lines contain frame bytes as sequence of hex digits,
746 * 2 digits for each byte. Spaces are allowed between bytes.
747 * On bytes lines only hex digits and spaces are allowed
748 */
749 while (!feof(f)) {
750 if (!fgets(line, sizeof(line), f))
751 break;
752 index = 0;
753 while (isspace((unsigned char) line[index]))
754 index++;
755 if (!line[index] || line[index] == '#')
756 continue;
757 if (line[index] == '$') {
758 if (tags) {
759 index++;
760 tag_num = strtol(&line[index], NULL, 0);
761 tag_offset = offset;
762 in_tag = 1;
763 }
764 continue;
765 }
766 while (line[index]) {
767 if (isspace((unsigned char) line[index])) {
768 index++;
769 continue;
770 }
771 num = hex_byte(&line[index]);
772 if (num < 0)
773 break;
774 buf[offset++] = num;
775 if (offset == *length)
776 goto out;
777 index += 2;
778 }
779
780 if (in_tag) {
781 if (tag_index < *num_tags) {
782 tags[tag_index].num = tag_num;
783 tags[tag_index].offset = tag_offset;
784 tags[tag_index].len = offset - tag_offset;
785 tag_index++;
786 } else {
787 sigma_dut_print(dut, DUT_MSG_INFO,
788 "too many tags, tag ignored");
789 }
790 in_tag = 0;
791 }
792 }
793
794 if (num_tags)
795 *num_tags = tag_index;
796out:
797 fclose(f);
798 if (offset < sizeof(struct ieee80211_hdr_3addr)) {
799 sigma_dut_print(dut, DUT_MSG_ERROR,
800 "template frame is too small");
801 return -1;
802 }
803
804 *length = offset;
805 return 0;
806}
807
Lior Davidcc88b562017-01-03 18:52:09 +0200808#endif /* __linux__ */
809
810
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200811static void static_ip_file(int proto, const char *addr, const char *mask,
812 const char *gw)
813{
814 if (proto) {
815 FILE *f = fopen("static-ip", "w");
816 if (f) {
817 fprintf(f, "%d %s %s %s\n", proto, addr,
818 mask ? mask : "N/A",
819 gw ? gw : "N/A");
820 fclose(f);
821 }
822 } else {
823 unlink("static-ip");
824 }
825}
826
827
828static int send_neighbor_request(struct sigma_dut *dut, const char *intf,
829 const char *ssid)
830{
831#ifdef __linux__
832 char buf[100];
833
834 snprintf(buf, sizeof(buf), "iwpriv %s neighbor %s",
835 intf, ssid);
836 sigma_dut_print(dut, DUT_MSG_INFO, "Request: %s", buf);
837
838 if (system(buf) != 0) {
839 sigma_dut_print(dut, DUT_MSG_ERROR,
840 "iwpriv neighbor request failed");
841 return -1;
842 }
843
844 sigma_dut_print(dut, DUT_MSG_INFO, "iwpriv neighbor request send");
845
846 return 0;
847#else /* __linux__ */
848 return -1;
849#endif /* __linux__ */
850}
851
852
853static int send_trans_mgmt_query(struct sigma_dut *dut, const char *intf,
Ashwini Patil5acd7382017-04-13 15:55:04 +0530854 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200855{
Ashwini Patil5acd7382017-04-13 15:55:04 +0530856 const char *val;
857 int reason_code = 0;
858 char buf[1024];
859
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200860 /*
861 * In the earlier builds we used WNM_QUERY and in later
862 * builds used WNM_BSS_QUERY.
863 */
864
Ashwini Patil5acd7382017-04-13 15:55:04 +0530865 val = get_param(cmd, "BTMQuery_Reason_Code");
866 if (val)
867 reason_code = atoi(val);
868
869 val = get_param(cmd, "Cand_List");
870 if (val && atoi(val) == 1 && dut->btm_query_cand_list) {
871 snprintf(buf, sizeof(buf), "WNM_BSS_QUERY %d%s", reason_code,
872 dut->btm_query_cand_list);
873 free(dut->btm_query_cand_list);
874 dut->btm_query_cand_list = NULL;
875 } else {
876 snprintf(buf, sizeof(buf), "WNM_BSS_QUERY %d", reason_code);
877 }
878
879 if (wpa_command(intf, buf) != 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200880 sigma_dut_print(dut, DUT_MSG_ERROR,
881 "transition management query failed");
882 return -1;
883 }
884
885 sigma_dut_print(dut, DUT_MSG_DEBUG,
886 "transition management query sent");
887
888 return 0;
889}
890
891
892int is_ip_addr(const char *str)
893{
894 const char *pos = str;
895 struct in_addr addr;
896
897 while (*pos) {
898 if (*pos != '.' && (*pos < '0' || *pos > '9'))
899 return 0;
900 pos++;
901 }
902
903 return inet_aton(str, &addr);
904}
905
906
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200907int get_ip_config(struct sigma_dut *dut, const char *ifname, char *buf,
908 size_t buf_len)
909{
vamsi krishnaa11d0732018-05-16 12:19:48 +0530910 char tmp[256];
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200911 char ip[16], mask[15], dns[16], sec_dns[16];
912 int is_dhcp = 0;
913 int s;
914#ifdef ANDROID
915 char prop[PROPERTY_VALUE_MAX];
vamsi krishnaa11d0732018-05-16 12:19:48 +0530916#else /* ANDROID */
917 FILE *f;
918#ifdef __linux__
919 const char *str_ps;
920#endif /* __linux__ */
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200921#endif /* ANDROID */
922
923 ip[0] = '\0';
924 mask[0] = '\0';
925 dns[0] = '\0';
926 sec_dns[0] = '\0';
927
928 s = socket(PF_INET, SOCK_DGRAM, 0);
929 if (s >= 0) {
930 struct ifreq ifr;
931 struct sockaddr_in saddr;
932
933 memset(&ifr, 0, sizeof(ifr));
Peng Xub8fc5cc2017-05-10 17:27:28 -0700934 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200935 if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
936 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to get "
937 "%s IP address: %s",
938 ifname, strerror(errno));
939 } else {
940 memcpy(&saddr, &ifr.ifr_addr,
941 sizeof(struct sockaddr_in));
Peng Xub8fc5cc2017-05-10 17:27:28 -0700942 strlcpy(ip, inet_ntoa(saddr.sin_addr), sizeof(ip));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200943 }
944
945 if (ioctl(s, SIOCGIFNETMASK, &ifr) == 0) {
946 memcpy(&saddr, &ifr.ifr_addr,
947 sizeof(struct sockaddr_in));
Peng Xub8fc5cc2017-05-10 17:27:28 -0700948 strlcpy(mask, inet_ntoa(saddr.sin_addr), sizeof(mask));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200949 }
950 close(s);
951 }
952
953#ifdef ANDROID
954 snprintf(tmp, sizeof(tmp), "dhcp.%s.pid", ifname);
955 if (property_get(tmp, prop, NULL) != 0 && atoi(prop) > 0) {
956 snprintf(tmp, sizeof(tmp), "dhcp.%s.result", ifname);
957 if (property_get(tmp, prop, NULL) != 0 &&
958 strcmp(prop, "ok") == 0) {
959 snprintf(tmp, sizeof(tmp), "dhcp.%s.ipaddress",
960 ifname);
961 if (property_get(tmp, prop, NULL) != 0 &&
962 strcmp(ip, prop) == 0)
963 is_dhcp = 1;
964 }
965 }
966
967 snprintf(tmp, sizeof(tmp), "dhcp.%s.dns1", ifname);
Peng Xub8fc5cc2017-05-10 17:27:28 -0700968 if (property_get(tmp, prop, NULL) != 0)
969 strlcpy(dns, prop, sizeof(dns));
970 else if (property_get("net.dns1", prop, NULL) != 0)
971 strlcpy(dns, prop, sizeof(dns));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200972
973 snprintf(tmp, sizeof(tmp), "dhcp.%s.dns2", ifname);
Peng Xub8fc5cc2017-05-10 17:27:28 -0700974 if (property_get(tmp, prop, NULL) != 0)
975 strlcpy(sec_dns, prop, sizeof(sec_dns));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200976#else /* ANDROID */
977#ifdef __linux__
Jouni Malinen016ae6c2019-11-04 17:00:01 +0200978 if (get_driver_type(dut) == DRIVER_OPENWRT)
Sarvepalli, Rajesh Babua76c6442016-03-18 20:34:26 +0530979 str_ps = "ps -w";
980 else
981 str_ps = "ps ax";
982 snprintf(tmp, sizeof(tmp),
983 "%s | grep dhclient | grep -v grep | grep -q %s",
984 str_ps, ifname);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200985 if (system(tmp) == 0)
986 is_dhcp = 1;
987 else {
Sarvepalli, Rajesh Babua76c6442016-03-18 20:34:26 +0530988 snprintf(tmp, sizeof(tmp),
989 "%s | grep udhcpc | grep -v grep | grep -q %s",
990 str_ps, ifname);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200991 if (system(tmp) == 0)
992 is_dhcp = 1;
993 else {
Sarvepalli, Rajesh Babua76c6442016-03-18 20:34:26 +0530994 snprintf(tmp, sizeof(tmp),
995 "%s | grep dhcpcd | grep -v grep | grep -q %s",
996 str_ps, ifname);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200997 if (system(tmp) == 0)
998 is_dhcp = 1;
999 }
1000 }
1001#endif /* __linux__ */
1002
1003 f = fopen("/etc/resolv.conf", "r");
1004 if (f) {
vamsi krishnaa11d0732018-05-16 12:19:48 +05301005 char *pos, *pos2;
1006
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001007 while (fgets(tmp, sizeof(tmp), f)) {
1008 if (strncmp(tmp, "nameserver", 10) != 0)
1009 continue;
1010 pos = tmp + 10;
1011 while (*pos == ' ' || *pos == '\t')
1012 pos++;
1013 pos2 = pos;
1014 while (*pos2) {
1015 if (*pos2 == '\n' || *pos2 == '\r') {
1016 *pos2 = '\0';
1017 break;
1018 }
1019 pos2++;
1020 }
Peng Xub8fc5cc2017-05-10 17:27:28 -07001021 if (!dns[0])
1022 strlcpy(dns, pos, sizeof(dns));
1023 else if (!sec_dns[0])
1024 strlcpy(sec_dns, pos, sizeof(sec_dns));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001025 }
1026 fclose(f);
1027 }
1028#endif /* ANDROID */
1029
1030 snprintf(buf, buf_len, "dhcp,%d,ip,%s,mask,%s,primary-dns,%s",
1031 is_dhcp, ip, mask, dns);
1032 buf[buf_len - 1] = '\0';
1033
1034 return 0;
1035}
1036
1037
1038
1039
1040int get_ipv6_config(struct sigma_dut *dut, const char *ifname, char *buf,
1041 size_t buf_len)
1042{
1043#ifdef __linux__
1044#ifdef ANDROID
1045 char cmd[200], result[1000], *pos, *end;
1046 FILE *f;
1047 size_t len;
1048
1049 snprintf(cmd, sizeof(cmd), "ip addr show dev %s scope global", ifname);
1050 f = popen(cmd, "r");
1051 if (f == NULL)
1052 return -1;
1053 len = fread(result, 1, sizeof(result) - 1, f);
1054 pclose(f);
1055 if (len == 0)
1056 return -1;
1057 result[len] = '\0';
1058 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s result: %s\n", cmd, result);
1059
1060 pos = strstr(result, "inet6 ");
1061 if (pos == NULL)
1062 return -1;
1063 pos += 6;
1064 end = strchr(pos, ' ');
1065 if (end)
1066 *end = '\0';
1067 end = strchr(pos, '/');
1068 if (end)
1069 *end = '\0';
1070 snprintf(buf, buf_len, "ip,%s", pos);
1071 buf[buf_len - 1] = '\0';
1072 return 0;
1073#else /* ANDROID */
1074 struct ifaddrs *ifaddr, *ifa;
1075 int res, found = 0;
1076 char host[NI_MAXHOST];
1077
1078 if (getifaddrs(&ifaddr) < 0) {
1079 perror("getifaddrs");
1080 return -1;
1081 }
1082
1083 for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
1084 if (strcasecmp(ifname, ifa->ifa_name) != 0)
1085 continue;
1086 if (ifa->ifa_addr == NULL ||
1087 ifa->ifa_addr->sa_family != AF_INET6)
1088 continue;
1089
1090 res = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in6),
1091 host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
1092 if (res != 0) {
1093 sigma_dut_print(dut, DUT_MSG_DEBUG, "getnameinfo: %s",
1094 gai_strerror(res));
1095 continue;
1096 }
1097 if (strncmp(host, "fe80::", 6) == 0)
1098 continue; /* skip link-local */
1099
1100 sigma_dut_print(dut, DUT_MSG_DEBUG, "ifaddr: %s", host);
1101 found = 1;
1102 break;
1103 }
1104
1105 freeifaddrs(ifaddr);
1106
1107 if (found) {
1108 char *pos;
1109 pos = strchr(host, '%');
1110 if (pos)
1111 *pos = '\0';
1112 snprintf(buf, buf_len, "ip,%s", host);
1113 buf[buf_len - 1] = '\0';
1114 return 0;
1115 }
1116
1117#endif /* ANDROID */
1118#endif /* __linux__ */
1119 return -1;
1120}
1121
1122
Jouni Malinenf7222712019-06-13 01:50:21 +03001123static enum sigma_cmd_result cmd_sta_get_ip_config(struct sigma_dut *dut,
1124 struct sigma_conn *conn,
1125 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001126{
1127 const char *intf = get_param(cmd, "Interface");
1128 const char *ifname;
1129 char buf[200];
1130 const char *val;
1131 int type = 1;
1132
1133 if (intf == NULL)
1134 return -1;
1135
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001136 if (strcmp(intf, get_main_ifname(dut)) == 0)
1137 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001138 else
1139 ifname = intf;
1140
1141 /*
1142 * UCC may assume the IP address to be available immediately after
1143 * association without trying to run sta_get_ip_config multiple times.
1144 * Sigma CAPI does not specify this command as a block command that
1145 * would wait for the address to become available, but to pass tests
1146 * more reliably, it looks like such a wait may be needed here.
1147 */
1148 if (wait_ip_addr(dut, ifname, 15) < 0) {
1149 sigma_dut_print(dut, DUT_MSG_INFO, "Could not get IP address "
1150 "for sta_get_ip_config");
1151 /*
1152 * Try to continue anyway since many UCC tests do not really
1153 * care about the return value from here..
1154 */
1155 }
1156
1157 val = get_param(cmd, "Type");
1158 if (val)
1159 type = atoi(val);
1160 if (type == 2 || dut->last_set_ip_config_ipv6) {
1161 int i;
1162
1163 /*
1164 * Since we do not have proper wait for IPv6 addresses, use a
1165 * fixed two second delay here as a workaround for UCC script
1166 * assuming IPv6 address is available when this command returns.
1167 * Some scripts did not use Type,2 properly for IPv6, so include
1168 * also the cases where the previous sta_set_ip_config indicated
1169 * use of IPv6.
1170 */
1171 sigma_dut_print(dut, DUT_MSG_INFO, "Wait up to extra ten seconds in sta_get_ip_config for IPv6 address");
1172 for (i = 0; i < 10; i++) {
1173 sleep(1);
1174 if (get_ipv6_config(dut, ifname, buf, sizeof(buf)) == 0)
1175 {
1176 sigma_dut_print(dut, DUT_MSG_INFO, "Found IPv6 address");
1177 send_resp(dut, conn, SIGMA_COMPLETE, buf);
1178#ifdef ANDROID
1179 sigma_dut_print(dut, DUT_MSG_INFO,
1180 "Adding IPv6 rule on Android");
1181 add_ipv6_rule(dut, intf);
1182#endif /* ANDROID */
1183
1184 return 0;
1185 }
1186 }
1187 }
1188 if (type == 1) {
1189 if (get_ip_config(dut, ifname, buf, sizeof(buf)) < 0)
1190 return -2;
1191 } else if (type == 2) {
1192 if (get_ipv6_config(dut, ifname, buf, sizeof(buf)) < 0)
1193 return -2;
1194 } else {
1195 send_resp(dut, conn, SIGMA_ERROR,
1196 "errorCode,Unsupported address type");
1197 return 0;
1198 }
1199
1200 send_resp(dut, conn, SIGMA_COMPLETE, buf);
1201 return 0;
1202}
1203
1204
1205static void kill_dhcp_client(struct sigma_dut *dut, const char *ifname)
1206{
1207#ifdef __linux__
1208 char buf[200];
1209 char path[128];
1210 struct stat s;
1211
1212#ifdef ANDROID
1213 snprintf(path, sizeof(path), "/data/misc/dhcp/dhcpcd-%s.pid", ifname);
1214#else /* ANDROID */
1215 snprintf(path, sizeof(path), "/var/run/dhclient-%s.pid", ifname);
1216#endif /* ANDROID */
1217 if (stat(path, &s) == 0) {
1218 snprintf(buf, sizeof(buf), "kill `cat %s`", path);
1219 sigma_dut_print(dut, DUT_MSG_INFO,
1220 "Kill previous DHCP client: %s", buf);
1221 if (system(buf) != 0)
1222 sigma_dut_print(dut, DUT_MSG_INFO,
1223 "Failed to kill DHCP client");
1224 unlink(path);
1225 sleep(1);
1226 } else {
1227 snprintf(path, sizeof(path), "/var/run/dhcpcd-%s.pid", ifname);
1228
1229 if (stat(path, &s) == 0) {
1230 snprintf(buf, sizeof(buf), "kill `cat %s`", path);
1231 sigma_dut_print(dut, DUT_MSG_INFO,
1232 "Kill previous DHCP client: %s", buf);
1233 if (system(buf) != 0)
1234 sigma_dut_print(dut, DUT_MSG_INFO,
1235 "Failed to kill DHCP client");
1236 unlink(path);
1237 sleep(1);
1238 }
1239 }
1240#endif /* __linux__ */
1241}
1242
1243
1244static int start_dhcp_client(struct sigma_dut *dut, const char *ifname)
1245{
1246#ifdef __linux__
1247 char buf[200];
1248
1249#ifdef ANDROID
Purushottam Kushwaha46d64262016-08-23 17:57:53 +05301250 if (access("/system/bin/dhcpcd", F_OK) != -1) {
1251 snprintf(buf, sizeof(buf),
1252 "/system/bin/dhcpcd -b %s", ifname);
1253 } else if (access("/system/bin/dhcptool", F_OK) != -1) {
1254 snprintf(buf, sizeof(buf), "/system/bin/dhcptool %s &", ifname);
Ankita Bajaj8454e5d2019-04-05 16:04:55 +05301255 } else if (access("/vendor/bin/dhcpcd", F_OK) != -1) {
1256 snprintf(buf, sizeof(buf), "/vendor/bin/dhcpcd -b %s", ifname);
1257 } else if (access("/vendor/bin/dhcptool", F_OK) != -1) {
1258 snprintf(buf, sizeof(buf), "/vendor/bin/dhcptool %s", ifname);
Purushottam Kushwaha46d64262016-08-23 17:57:53 +05301259 } else {
1260 sigma_dut_print(dut, DUT_MSG_ERROR,
1261 "DHCP client program missing");
1262 return 0;
1263 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001264#else /* ANDROID */
1265 snprintf(buf, sizeof(buf),
1266 "dhclient -nw -pf /var/run/dhclient-%s.pid %s",
1267 ifname, ifname);
1268#endif /* ANDROID */
1269 sigma_dut_print(dut, DUT_MSG_INFO, "Start DHCP client: %s", buf);
1270 if (system(buf) != 0) {
1271 snprintf(buf, sizeof(buf), "dhcpcd -t 0 %s &", ifname);
1272 if (system(buf) != 0) {
1273 sigma_dut_print(dut, DUT_MSG_INFO,
1274 "Failed to start DHCP client");
1275#ifndef ANDROID
1276 return -1;
1277#endif /* ANDROID */
1278 }
1279 }
1280#endif /* __linux__ */
1281
1282 return 0;
1283}
1284
1285
1286static int clear_ip_addr(struct sigma_dut *dut, const char *ifname)
1287{
1288#ifdef __linux__
1289 char buf[200];
1290
1291 snprintf(buf, sizeof(buf), "ip addr flush dev %s", ifname);
1292 if (system(buf) != 0) {
1293 sigma_dut_print(dut, DUT_MSG_INFO,
1294 "Failed to clear IP addresses");
1295 return -1;
1296 }
1297#endif /* __linux__ */
1298
1299 return 0;
1300}
1301
1302
1303#ifdef ANDROID
1304static int add_ipv6_rule(struct sigma_dut *dut, const char *ifname)
1305{
1306 char cmd[200], *result, *pos;
1307 FILE *fp;
Pradeep Reddy POTTETIf58a1fe2016-10-13 17:22:03 +05301308 int tableid;
1309 size_t len, result_len = 1000;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001310
1311 snprintf(cmd, sizeof(cmd), "ip -6 route list table all | grep %s",
1312 ifname);
1313 fp = popen(cmd, "r");
1314 if (fp == NULL)
1315 return -1;
1316
1317 result = malloc(result_len);
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05301318 if (result == NULL) {
1319 fclose(fp);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001320 return -1;
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05301321 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001322
Pradeep Reddy POTTETIf58a1fe2016-10-13 17:22:03 +05301323 len = fread(result, 1, result_len - 1, fp);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001324 fclose(fp);
1325
1326 if (len == 0) {
1327 free(result);
1328 return -1;
1329 }
Pradeep Reddy POTTETIf58a1fe2016-10-13 17:22:03 +05301330 result[len] = '\0';
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001331
1332 pos = strstr(result, "table ");
1333 if (pos == NULL) {
1334 free(result);
1335 return -1;
1336 }
1337
1338 pos += strlen("table ");
1339 tableid = atoi(pos);
1340 if (tableid != 0) {
1341 if (system("ip -6 rule del prio 22000") != 0) {
1342 /* ignore any error */
1343 }
1344 snprintf(cmd, sizeof(cmd),
1345 "ip -6 rule add from all lookup %d prio 22000",
1346 tableid);
1347 if (system(cmd) != 0) {
1348 sigma_dut_print(dut, DUT_MSG_INFO,
1349 "Failed to run %s", cmd);
1350 free(result);
1351 return -1;
1352 }
1353 } else {
1354 sigma_dut_print(dut, DUT_MSG_INFO,
1355 "No Valid Table Id found %s", pos);
1356 free(result);
1357 return -1;
1358 }
1359 free(result);
1360
1361 return 0;
1362}
1363#endif /* ANDROID */
1364
1365
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301366int set_ipv4_addr(struct sigma_dut *dut, const char *ifname,
1367 const char *ip, const char *mask)
1368{
1369 char buf[200];
1370
1371 snprintf(buf, sizeof(buf), "ifconfig %s %s netmask %s",
1372 ifname, ip, mask);
1373 return system(buf) == 0;
1374}
1375
1376
1377int set_ipv4_gw(struct sigma_dut *dut, const char *gw)
1378{
1379 char buf[200];
1380
1381 if (!is_ip_addr(gw)) {
1382 sigma_dut_print(dut, DUT_MSG_DEBUG, "Invalid gw addr - %s", gw);
1383 return -1;
1384 }
1385
1386 snprintf(buf, sizeof(buf), "route add default gw %s", gw);
1387 if (!dut->no_ip_addr_set && system(buf) != 0) {
1388 snprintf(buf, sizeof(buf), "ip ro re default via %s",
1389 gw);
1390 if (system(buf) != 0)
1391 return 0;
1392 }
1393
1394 return 1;
1395}
1396
1397
Jouni Malinenf7222712019-06-13 01:50:21 +03001398static enum sigma_cmd_result cmd_sta_set_ip_config(struct sigma_dut *dut,
1399 struct sigma_conn *conn,
1400 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001401{
1402 const char *intf = get_param(cmd, "Interface");
1403 const char *ifname;
1404 char buf[200];
1405 const char *val, *ip, *mask, *gw;
1406 int type = 1;
1407
1408 if (intf == NULL)
1409 return -1;
1410
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001411 if (strcmp(intf, get_main_ifname(dut)) == 0)
1412 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001413 else
1414 ifname = intf;
1415
1416 if (if_nametoindex(ifname) == 0) {
1417 send_resp(dut, conn, SIGMA_ERROR,
1418 "ErrorCode,Unknown interface");
1419 return 0;
1420 }
1421
1422 val = get_param(cmd, "Type");
1423 if (val) {
1424 type = atoi(val);
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301425 if (type < 1 || type > 3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001426 send_resp(dut, conn, SIGMA_ERROR,
1427 "ErrorCode,Unsupported address type");
1428 return 0;
1429 }
1430 }
1431
1432 dut->last_set_ip_config_ipv6 = 0;
1433
1434 val = get_param(cmd, "dhcp");
1435 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "true") == 0)) {
1436 static_ip_file(0, NULL, NULL, NULL);
1437#ifdef __linux__
1438 if (type == 2) {
1439 dut->last_set_ip_config_ipv6 = 1;
1440 sigma_dut_print(dut, DUT_MSG_INFO, "Using IPv6 "
1441 "stateless address autoconfiguration");
1442#ifdef ANDROID
1443 /*
1444 * This sleep is required as the assignment in case of
1445 * Android is taking time and is done by the kernel.
1446 * The subsequent ping for IPv6 is impacting HS20 test
1447 * case.
1448 */
1449 sleep(2);
1450 add_ipv6_rule(dut, intf);
1451#endif /* ANDROID */
1452 /* Assume this happens by default */
1453 return 1;
1454 }
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301455 if (type != 3) {
1456 kill_dhcp_client(dut, ifname);
1457 if (start_dhcp_client(dut, ifname) < 0)
1458 return -2;
1459 } else {
1460 sigma_dut_print(dut, DUT_MSG_DEBUG,
1461 "Using FILS HLP DHCPv4 Rapid Commit");
1462 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001463
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001464 return 1;
1465#endif /* __linux__ */
1466 return -2;
1467 }
1468
1469 ip = get_param(cmd, "ip");
Pradeep Reddy POTTETIb18c5652016-01-18 12:45:37 +05301470 if (!ip) {
1471 send_resp(dut, conn, SIGMA_INVALID,
1472 "ErrorCode,Missing IP address");
1473 return 0;
1474 }
1475
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001476 mask = get_param(cmd, "mask");
Pradeep Reddy POTTETIb18c5652016-01-18 12:45:37 +05301477 if (!mask) {
1478 send_resp(dut, conn, SIGMA_INVALID,
1479 "ErrorCode,Missing subnet mask");
1480 return 0;
1481 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001482
1483 if (type == 2) {
1484 int net = atoi(mask);
1485
1486 if ((net < 0 && net > 64) || !is_ipv6_addr(ip))
1487 return -1;
1488
1489 if (dut->no_ip_addr_set) {
1490 snprintf(buf, sizeof(buf),
1491 "sysctl net.ipv6.conf.%s.disable_ipv6=1",
1492 ifname);
1493 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
1494 if (system(buf) != 0) {
1495 sigma_dut_print(dut, DUT_MSG_DEBUG,
1496 "Failed to disable IPv6 address before association");
1497 }
1498 } else {
1499 snprintf(buf, sizeof(buf),
1500 "ip -6 addr del %s/%s dev %s",
1501 ip, mask, ifname);
1502 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
1503 if (system(buf) != 0) {
1504 /*
1505 * This command may fail if the address being
1506 * deleted does not exist. Inaction here is
1507 * intentional.
1508 */
1509 }
1510
1511 snprintf(buf, sizeof(buf),
1512 "ip -6 addr add %s/%s dev %s",
1513 ip, mask, ifname);
1514 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
1515 if (system(buf) != 0) {
1516 send_resp(dut, conn, SIGMA_ERROR,
1517 "ErrorCode,Failed to set IPv6 address");
1518 return 0;
1519 }
1520 }
1521
1522 dut->last_set_ip_config_ipv6 = 1;
1523 static_ip_file(6, ip, mask, NULL);
1524 return 1;
1525 } else if (type == 1) {
Pradeep Reddy POTTETIb18c5652016-01-18 12:45:37 +05301526 if (!is_ip_addr(ip) || !is_ip_addr(mask))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001527 return -1;
1528 }
1529
1530 kill_dhcp_client(dut, ifname);
1531
1532 if (!dut->no_ip_addr_set) {
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301533 if (!set_ipv4_addr(dut, ifname, ip, mask)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001534 send_resp(dut, conn, SIGMA_ERROR,
1535 "ErrorCode,Failed to set IP address");
1536 return 0;
1537 }
1538 }
1539
1540 gw = get_param(cmd, "defaultGateway");
1541 if (gw) {
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301542 if (set_ipv4_gw(dut, gw) < 1) {
1543 send_resp(dut, conn, SIGMA_ERROR,
1544 "ErrorCode,Failed to set default gateway");
1545 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001546 }
1547 }
1548
1549 val = get_param(cmd, "primary-dns");
1550 if (val) {
1551 /* TODO */
1552 sigma_dut_print(dut, DUT_MSG_INFO, "Ignored primary-dns %s "
1553 "setting", val);
1554 }
1555
1556 val = get_param(cmd, "secondary-dns");
1557 if (val) {
1558 /* TODO */
1559 sigma_dut_print(dut, DUT_MSG_INFO, "Ignored secondary-dns %s "
1560 "setting", val);
1561 }
1562
1563 static_ip_file(4, ip, mask, gw);
1564
1565 return 1;
1566}
1567
1568
Jouni Malinenf7222712019-06-13 01:50:21 +03001569static enum sigma_cmd_result cmd_sta_get_info(struct sigma_dut *dut,
1570 struct sigma_conn *conn,
1571 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001572{
1573 /* const char *intf = get_param(cmd, "Interface"); */
1574 /* TODO: could report more details here */
1575 send_resp(dut, conn, SIGMA_COMPLETE, "vendor,Atheros");
1576 return 0;
1577}
1578
1579
Jouni Malinenf7222712019-06-13 01:50:21 +03001580static enum sigma_cmd_result cmd_sta_get_mac_address(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 char addr[20], resp[50];
1586
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05301587 if (dut->dev_role == DEVROLE_STA_CFON)
1588 return sta_cfon_get_mac_address(dut, conn, cmd);
1589
Jouni Malinen9540e012019-11-05 17:08:42 +02001590 start_sta_mode(dut);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001591 if (get_wpa_status(get_station_ifname(dut), "address",
1592 addr, sizeof(addr)) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001593 return -2;
1594
1595 snprintf(resp, sizeof(resp), "mac,%s", addr);
1596 send_resp(dut, conn, SIGMA_COMPLETE, resp);
1597 return 0;
1598}
1599
1600
Jouni Malinenf7222712019-06-13 01:50:21 +03001601static enum sigma_cmd_result cmd_sta_is_connected(struct sigma_dut *dut,
1602 struct sigma_conn *conn,
1603 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001604{
1605 /* const char *intf = get_param(cmd, "Interface"); */
1606 int connected = 0;
1607 char result[32];
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001608 if (get_wpa_status(get_station_ifname(dut), "wpa_state", result,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001609 sizeof(result)) < 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001610 sigma_dut_print(dut, DUT_MSG_INFO,
1611 "Could not get interface %s status",
1612 get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001613 return -2;
1614 }
1615
1616 sigma_dut_print(dut, DUT_MSG_DEBUG, "wpa_state=%s", result);
1617 if (strncmp(result, "COMPLETED", 9) == 0)
1618 connected = 1;
1619
1620 if (connected)
1621 send_resp(dut, conn, SIGMA_COMPLETE, "connected,1");
1622 else
1623 send_resp(dut, conn, SIGMA_COMPLETE, "connected,0");
1624
1625 return 0;
1626}
1627
1628
Jouni Malinenf7222712019-06-13 01:50:21 +03001629static enum sigma_cmd_result
1630cmd_sta_verify_ip_connection(struct sigma_dut *dut, struct sigma_conn *conn,
1631 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001632{
1633 /* const char *intf = get_param(cmd, "Interface"); */
1634 const char *dst, *timeout;
1635 int wait_time = 90;
1636 char buf[100];
1637 int res;
1638
1639 dst = get_param(cmd, "destination");
1640 if (dst == NULL || !is_ip_addr(dst))
1641 return -1;
1642
1643 timeout = get_param(cmd, "timeout");
1644 if (timeout) {
1645 wait_time = atoi(timeout);
1646 if (wait_time < 1)
1647 wait_time = 1;
1648 }
1649
1650 /* TODO: force renewal of IP lease if DHCP is enabled */
1651
1652 snprintf(buf, sizeof(buf), "ping %s -c 3 -W %d", dst, wait_time);
1653 res = system(buf);
1654 sigma_dut_print(dut, DUT_MSG_DEBUG, "ping returned: %d", res);
1655 if (res == 0)
1656 send_resp(dut, conn, SIGMA_COMPLETE, "connected,1");
1657 else if (res == 256)
1658 send_resp(dut, conn, SIGMA_COMPLETE, "connected,0");
1659 else
1660 return -2;
1661
1662 return 0;
1663}
1664
1665
Jouni Malinenf7222712019-06-13 01:50:21 +03001666static enum sigma_cmd_result cmd_sta_get_bssid(struct sigma_dut *dut,
1667 struct sigma_conn *conn,
1668 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001669{
1670 /* const char *intf = get_param(cmd, "Interface"); */
1671 char bssid[20], resp[50];
1672
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001673 if (get_wpa_status(get_station_ifname(dut), "bssid",
1674 bssid, sizeof(bssid)) < 0)
Peng Xub8fc5cc2017-05-10 17:27:28 -07001675 strlcpy(bssid, "00:00:00:00:00:00", sizeof(bssid));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001676
1677 snprintf(resp, sizeof(resp), "bssid,%s", bssid);
1678 send_resp(dut, conn, SIGMA_COMPLETE, resp);
1679 return 0;
1680}
1681
1682
1683#ifdef __SAMSUNG__
1684static int add_use_network(const char *ifname)
1685{
1686 char buf[100];
1687
1688 snprintf(buf, sizeof(buf), "USE_NETWORK ON");
1689 wpa_command(ifname, buf);
1690 return 0;
1691}
1692#endif /* __SAMSUNG__ */
1693
1694
1695static int add_network_common(struct sigma_dut *dut, struct sigma_conn *conn,
1696 const char *ifname, struct sigma_cmd *cmd)
1697{
1698 const char *ssid = get_param(cmd, "ssid");
1699 int id;
1700 const char *val;
1701
1702 if (ssid == NULL)
1703 return -1;
1704
1705 start_sta_mode(dut);
1706
1707#ifdef __SAMSUNG__
1708 add_use_network(ifname);
1709#endif /* __SAMSUNG__ */
1710
1711 id = add_network(ifname);
1712 if (id < 0)
1713 return -2;
1714 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding network %d", id);
1715
1716 if (set_network_quoted(ifname, id, "ssid", ssid) < 0)
1717 return -2;
1718
1719 dut->infra_network_id = id;
1720 snprintf(dut->infra_ssid, sizeof(dut->infra_ssid), "%s", ssid);
1721
1722 val = get_param(cmd, "program");
1723 if (!val)
1724 val = get_param(cmd, "prog");
1725 if (val && strcasecmp(val, "hs2") == 0) {
1726 char buf[100];
1727 snprintf(buf, sizeof(buf), "ENABLE_NETWORK %d no-connect", id);
1728 wpa_command(ifname, buf);
1729
1730 val = get_param(cmd, "prefer");
1731 if (val && atoi(val) > 0)
1732 set_network(ifname, id, "priority", "1");
1733 }
1734
1735 return id;
1736}
1737
1738
Jouni Malinenf7222712019-06-13 01:50:21 +03001739static enum sigma_cmd_result cmd_sta_set_encryption(struct sigma_dut *dut,
1740 struct sigma_conn *conn,
1741 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001742{
1743 const char *intf = get_param(cmd, "Interface");
1744 const char *ssid = get_param(cmd, "ssid");
1745 const char *type = get_param(cmd, "encpType");
1746 const char *ifname;
1747 char buf[200];
1748 int id;
1749
1750 if (intf == NULL || ssid == NULL)
1751 return -1;
1752
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001753 if (strcmp(intf, get_main_ifname(dut)) == 0)
1754 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001755 else
1756 ifname = intf;
1757
1758 id = add_network_common(dut, conn, ifname, cmd);
1759 if (id < 0)
1760 return id;
1761
1762 if (set_network(ifname, id, "key_mgmt", "NONE") < 0)
1763 return -2;
1764
1765 if (type && strcasecmp(type, "wep") == 0) {
1766 const char *val;
1767 int i;
1768
1769 val = get_param(cmd, "activeKey");
1770 if (val) {
1771 int keyid;
1772 keyid = atoi(val);
1773 if (keyid < 1 || keyid > 4)
1774 return -1;
1775 snprintf(buf, sizeof(buf), "%d", keyid - 1);
1776 if (set_network(ifname, id, "wep_tx_keyidx", buf) < 0)
1777 return -2;
1778 }
1779
1780 for (i = 0; i < 4; i++) {
1781 snprintf(buf, sizeof(buf), "key%d", i + 1);
1782 val = get_param(cmd, buf);
1783 if (val == NULL)
1784 continue;
1785 snprintf(buf, sizeof(buf), "wep_key%d", i);
1786 if (set_network(ifname, id, buf, val) < 0)
1787 return -2;
1788 }
1789 }
1790
1791 return 1;
1792}
1793
1794
Jouni Malinene4fde732019-03-25 22:29:37 +02001795static int set_akm_suites(struct sigma_dut *dut, const char *ifname,
1796 int id, const char *val)
1797{
1798 char key_mgmt[200], *end, *pos;
1799 const char *in_pos = val;
1800
Jouni Malinen8179fee2019-03-28 03:19:47 +02001801 dut->akm_values = 0;
Jouni Malinene4fde732019-03-25 22:29:37 +02001802 pos = key_mgmt;
1803 end = pos + sizeof(key_mgmt);
1804 while (*in_pos) {
1805 int res, akm = atoi(in_pos);
1806 const char *str;
1807
Jouni Malinen8179fee2019-03-28 03:19:47 +02001808 if (akm >= 0 && akm < 32)
1809 dut->akm_values |= 1 << akm;
1810
Jouni Malinene4fde732019-03-25 22:29:37 +02001811 switch (akm) {
1812 case AKM_WPA_EAP:
1813 str = "WPA-EAP";
1814 break;
1815 case AKM_WPA_PSK:
1816 str = "WPA-PSK";
1817 break;
1818 case AKM_FT_EAP:
1819 str = "FT-EAP";
1820 break;
1821 case AKM_FT_PSK:
1822 str = "FT-PSK";
1823 break;
1824 case AKM_EAP_SHA256:
1825 str = "WPA-EAP-SHA256";
1826 break;
1827 case AKM_PSK_SHA256:
1828 str = "WPA-PSK-SHA256";
1829 break;
1830 case AKM_SAE:
1831 str = "SAE";
1832 break;
1833 case AKM_FT_SAE:
1834 str = "FT-SAE";
1835 break;
1836 case AKM_SUITE_B:
1837 str = "WPA-EAP-SUITE-B-192";
1838 break;
1839 case AKM_FT_SUITE_B:
1840 str = "FT-EAP-SHA384";
1841 break;
1842 case AKM_FILS_SHA256:
1843 str = "FILS-SHA256";
1844 break;
1845 case AKM_FILS_SHA384:
1846 str = "FILS-SHA384";
1847 break;
1848 case AKM_FT_FILS_SHA256:
1849 str = "FT-FILS-SHA256";
1850 break;
1851 case AKM_FT_FILS_SHA384:
1852 str = "FT-FILS-SHA384";
1853 break;
1854 default:
1855 sigma_dut_print(dut, DUT_MSG_ERROR,
1856 "Unsupported AKMSuitetype %d", akm);
1857 return -1;
1858 }
1859
1860 res = snprintf(pos, end - pos, "%s%s",
1861 pos == key_mgmt ? "" : " ", str);
1862 if (res < 0 || res >= end - pos)
1863 return -1;
1864 pos += res;
1865
1866 in_pos = strchr(in_pos, ';');
1867 if (!in_pos)
1868 break;
1869 while (*in_pos == ';')
1870 in_pos++;
1871 }
1872 sigma_dut_print(dut, DUT_MSG_DEBUG, "AKMSuiteType %s --> %s",
1873 val, key_mgmt);
1874 return set_network(ifname, id, "key_mgmt", key_mgmt);
1875}
1876
1877
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001878static int set_wpa_common(struct sigma_dut *dut, struct sigma_conn *conn,
1879 const char *ifname, struct sigma_cmd *cmd)
1880{
1881 const char *val;
1882 int id;
Jouni Malinenad395a22017-09-01 21:13:46 +03001883 int cipher_set = 0;
Jouni Malinen47dcc952017-10-09 16:43:24 +03001884 int owe;
Sunil Duttc75a1e62018-01-11 20:47:50 +05301885 int suite_b = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001886
1887 id = add_network_common(dut, conn, ifname, cmd);
1888 if (id < 0)
1889 return id;
1890
Jouni Malinen47dcc952017-10-09 16:43:24 +03001891 val = get_param(cmd, "Type");
1892 owe = val && strcasecmp(val, "OWE") == 0;
1893
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001894 val = get_param(cmd, "keyMgmtType");
Jouni Malinen47dcc952017-10-09 16:43:24 +03001895 if (!val && owe)
1896 val = "OWE";
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001897 if (val == NULL) {
Jouni Malinene4fde732019-03-25 22:29:37 +02001898 /* keyMgmtType is being replaced with AKMSuiteType, so ignore
1899 * this missing parameter and assume proto=WPA2. */
1900 if (set_network(ifname, id, "proto", "WPA2") < 0)
1901 return ERROR_SEND_STATUS;
1902 } else if (strcasecmp(val, "wpa") == 0 ||
1903 strcasecmp(val, "wpa-psk") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001904 if (set_network(ifname, id, "proto", "WPA") < 0)
1905 return -2;
1906 } else if (strcasecmp(val, "wpa2") == 0 ||
1907 strcasecmp(val, "wpa2-psk") == 0 ||
1908 strcasecmp(val, "wpa2-ft") == 0 ||
1909 strcasecmp(val, "wpa2-sha256") == 0) {
1910 if (set_network(ifname, id, "proto", "WPA2") < 0)
1911 return -2;
Pradeep Reddy POTTETI6d04b3b2016-11-15 14:51:26 +05301912 } else if (strcasecmp(val, "wpa2-wpa-psk") == 0 ||
1913 strcasecmp(val, "wpa2-wpa-ent") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001914 if (set_network(ifname, id, "proto", "WPA WPA2") < 0)
1915 return -2;
Jouni Malinenad395a22017-09-01 21:13:46 +03001916 } else if (strcasecmp(val, "SuiteB") == 0) {
Sunil Duttc75a1e62018-01-11 20:47:50 +05301917 suite_b = 1;
Jouni Malinenad395a22017-09-01 21:13:46 +03001918 if (set_network(ifname, id, "proto", "WPA2") < 0)
1919 return -2;
Jouni Malinen47dcc952017-10-09 16:43:24 +03001920 } else if (strcasecmp(val, "OWE") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001921 } else {
1922 send_resp(dut, conn, SIGMA_INVALID, "errorCode,Unrecognized keyMgmtType value");
1923 return 0;
1924 }
1925
1926 val = get_param(cmd, "encpType");
Jouni Malinenad395a22017-09-01 21:13:46 +03001927 if (val) {
1928 cipher_set = 1;
1929 if (strcasecmp(val, "tkip") == 0) {
1930 if (set_network(ifname, id, "pairwise", "TKIP") < 0)
1931 return -2;
1932 } else if (strcasecmp(val, "aes-ccmp") == 0) {
1933 if (set_network(ifname, id, "pairwise", "CCMP") < 0)
1934 return -2;
1935 } else if (strcasecmp(val, "aes-ccmp-tkip") == 0) {
1936 if (set_network(ifname, id, "pairwise",
1937 "CCMP TKIP") < 0)
1938 return -2;
1939 } else if (strcasecmp(val, "aes-gcmp") == 0) {
1940 if (set_network(ifname, id, "pairwise", "GCMP") < 0)
1941 return -2;
1942 if (set_network(ifname, id, "group", "GCMP") < 0)
1943 return -2;
1944 } else {
1945 send_resp(dut, conn, SIGMA_ERROR,
1946 "errorCode,Unrecognized encpType value");
1947 return 0;
1948 }
1949 }
1950
1951 val = get_param(cmd, "PairwiseCipher");
1952 if (val) {
1953 cipher_set = 1;
1954 /* TODO: Support space separated list */
1955 if (strcasecmp(val, "AES-GCMP-256") == 0) {
1956 if (set_network(ifname, id, "pairwise", "GCMP-256") < 0)
1957 return -2;
1958 } else if (strcasecmp(val, "AES-CCMP-256") == 0) {
1959 if (set_network(ifname, id, "pairwise",
1960 "CCMP-256") < 0)
1961 return -2;
1962 } else if (strcasecmp(val, "AES-GCMP-128") == 0) {
1963 if (set_network(ifname, id, "pairwise", "GCMP") < 0)
1964 return -2;
1965 } else if (strcasecmp(val, "AES-CCMP-128") == 0) {
1966 if (set_network(ifname, id, "pairwise", "CCMP") < 0)
1967 return -2;
1968 } else {
1969 send_resp(dut, conn, SIGMA_ERROR,
1970 "errorCode,Unrecognized PairwiseCipher value");
1971 return 0;
1972 }
1973 }
1974
Jouni Malinen47dcc952017-10-09 16:43:24 +03001975 if (!cipher_set && !owe) {
Jouni Malinenad395a22017-09-01 21:13:46 +03001976 send_resp(dut, conn, SIGMA_ERROR,
1977 "errorCode,Missing encpType and PairwiseCipher");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001978 return 0;
1979 }
Jouni Malinenad395a22017-09-01 21:13:46 +03001980
1981 val = get_param(cmd, "GroupCipher");
1982 if (val) {
1983 if (strcasecmp(val, "AES-GCMP-256") == 0) {
1984 if (set_network(ifname, id, "group", "GCMP-256") < 0)
1985 return -2;
1986 } else if (strcasecmp(val, "AES-CCMP-256") == 0) {
1987 if (set_network(ifname, id, "group", "CCMP-256") < 0)
1988 return -2;
1989 } else if (strcasecmp(val, "AES-GCMP-128") == 0) {
1990 if (set_network(ifname, id, "group", "GCMP") < 0)
1991 return -2;
1992 } else if (strcasecmp(val, "AES-CCMP-128") == 0) {
1993 if (set_network(ifname, id, "group", "CCMP") < 0)
1994 return -2;
1995 } else {
1996 send_resp(dut, conn, SIGMA_ERROR,
1997 "errorCode,Unrecognized GroupCipher value");
1998 return 0;
1999 }
2000 }
2001
Jouni Malinen7b239522017-09-14 21:37:18 +03002002 val = get_param(cmd, "GroupMgntCipher");
Jouni Malinenad395a22017-09-01 21:13:46 +03002003 if (val) {
Jouni Malinene8898cb2017-09-26 17:55:26 +03002004 const char *cipher;
2005
2006 if (strcasecmp(val, "BIP-GMAC-256") == 0) {
2007 cipher = "BIP-GMAC-256";
2008 } else if (strcasecmp(val, "BIP-CMAC-256") == 0) {
2009 cipher = "BIP-CMAC-256";
2010 } else if (strcasecmp(val, "BIP-GMAC-128") == 0) {
2011 cipher = "BIP-GMAC-128";
2012 } else if (strcasecmp(val, "BIP-CMAC-128") == 0) {
2013 cipher = "AES-128-CMAC";
2014 } else {
2015 send_resp(dut, conn, SIGMA_INVALID,
2016 "errorCode,Unsupported GroupMgntCipher");
2017 return 0;
2018 }
2019 if (set_network(ifname, id, "group_mgmt", cipher) < 0) {
2020 send_resp(dut, conn, SIGMA_INVALID,
2021 "errorCode,Failed to set GroupMgntCipher");
2022 return 0;
2023 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002024 }
2025
Jouni Malinene4fde732019-03-25 22:29:37 +02002026 val = get_param(cmd, "AKMSuiteType");
2027 if (val && set_akm_suites(dut, ifname, id, val) < 0)
2028 return ERROR_SEND_STATUS;
2029
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002030 dut->sta_pmf = STA_PMF_DISABLED;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302031
2032 if (dut->program == PROGRAM_OCE) {
2033 dut->sta_pmf = STA_PMF_OPTIONAL;
2034 if (set_network(ifname, id, "ieee80211w", "1") < 0)
2035 return -2;
2036 }
2037
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002038 val = get_param(cmd, "PMF");
2039 if (val) {
2040 if (strcasecmp(val, "Required") == 0 ||
2041 strcasecmp(val, "Forced_Required") == 0) {
2042 dut->sta_pmf = STA_PMF_REQUIRED;
2043 if (set_network(ifname, id, "ieee80211w", "2") < 0)
2044 return -2;
2045 } else if (strcasecmp(val, "Optional") == 0) {
2046 dut->sta_pmf = STA_PMF_OPTIONAL;
2047 if (set_network(ifname, id, "ieee80211w", "1") < 0)
2048 return -2;
2049 } else if (strcasecmp(val, "Disabled") == 0 ||
Kiran Kumar Lokere07da3b22018-12-16 22:42:49 -08002050 strcasecmp(val, "Disable") == 0 ||
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002051 strcasecmp(val, "Forced_Disabled") == 0) {
2052 dut->sta_pmf = STA_PMF_DISABLED;
2053 } else {
2054 send_resp(dut, conn, SIGMA_INVALID, "errorCode,Unrecognized PMF value");
2055 return 0;
2056 }
Sunil Duttc75a1e62018-01-11 20:47:50 +05302057 } else if (owe || suite_b) {
Jouni Malinen1287cd72018-01-04 17:08:01 +02002058 dut->sta_pmf = STA_PMF_REQUIRED;
2059 if (set_network(ifname, id, "ieee80211w", "2") < 0)
2060 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002061 }
2062
Jouni Malinen0165c7f2020-03-26 11:51:58 +02002063 val = get_param(cmd, "BeaconProtection");
2064 if (val && atoi(val) == 1 &&
2065 set_network(ifname, id, "beacon_prot", "1") < 0)
2066 return ERROR_SEND_STATUS;
2067
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002068 return id;
2069}
2070
2071
Jouni Malinenf7222712019-06-13 01:50:21 +03002072static enum sigma_cmd_result cmd_sta_set_psk(struct sigma_dut *dut,
2073 struct sigma_conn *conn,
2074 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002075{
2076 const char *intf = get_param(cmd, "Interface");
Jouni Malinen992a81e2017-08-22 13:57:47 +03002077 const char *type = get_param(cmd, "Type");
Jouni Malinen1287cd72018-01-04 17:08:01 +02002078 const char *pmf = get_param(cmd, "PMF");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002079 const char *network_mode = get_param(cmd, "network_mode");
Jouni Malinene4fde732019-03-25 22:29:37 +02002080 const char *akm = get_param(cmd, "AKMSuiteType");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002081 const char *ifname, *val, *alg;
2082 int id;
Jouni Malinen4b3769d2019-10-10 16:20:29 +03002083 char buf[50];
Jouni Malinen11e55212019-11-22 21:46:59 +02002084 int sae_pwe = -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002085
2086 if (intf == NULL)
2087 return -1;
2088
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002089 if (strcmp(intf, get_main_ifname(dut)) == 0)
2090 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002091 else
2092 ifname = intf;
2093
2094 id = set_wpa_common(dut, conn, ifname, cmd);
2095 if (id < 0)
2096 return id;
2097
2098 val = get_param(cmd, "keyMgmtType");
2099 alg = get_param(cmd, "micAlg");
2100
Jouni Malinen992a81e2017-08-22 13:57:47 +03002101 if (type && strcasecmp(type, "SAE") == 0) {
Jouni Malinene4fde732019-03-25 22:29:37 +02002102 if (!akm && val && strcasecmp(val, "wpa2-ft") == 0) {
Jouni Malinen992a81e2017-08-22 13:57:47 +03002103 if (set_network(ifname, id, "key_mgmt", "FT-SAE") < 0)
2104 return -2;
Jouni Malinene4fde732019-03-25 22:29:37 +02002105 } else if (!akm) {
Jouni Malinen992a81e2017-08-22 13:57:47 +03002106 if (set_network(ifname, id, "key_mgmt", "SAE") < 0)
2107 return -2;
2108 }
2109 if (wpa_command(ifname, "SET sae_groups ") != 0) {
2110 sigma_dut_print(dut, DUT_MSG_ERROR,
2111 "Failed to clear sae_groups to default");
2112 return -2;
2113 }
Jouni Malinen1287cd72018-01-04 17:08:01 +02002114 if (!pmf) {
2115 dut->sta_pmf = STA_PMF_REQUIRED;
2116 if (set_network(ifname, id, "ieee80211w", "2") < 0)
2117 return -2;
2118 }
Jouni Malinen0ab50f42017-08-31 01:34:59 +03002119 } else if (type && strcasecmp(type, "PSK-SAE") == 0) {
2120 if (val && strcasecmp(val, "wpa2-ft") == 0) {
2121 if (set_network(ifname, id, "key_mgmt",
2122 "FT-SAE FT-PSK") < 0)
2123 return -2;
Jouni Malinen3b73d872019-06-12 03:13:25 +03002124 } else if (!akm) {
Jouni Malinen0ab50f42017-08-31 01:34:59 +03002125 if (set_network(ifname, id, "key_mgmt",
2126 "SAE WPA-PSK") < 0)
2127 return -2;
2128 }
2129 if (wpa_command(ifname, "SET sae_groups ") != 0) {
2130 sigma_dut_print(dut, DUT_MSG_ERROR,
2131 "Failed to clear sae_groups to default");
2132 return -2;
2133 }
Jouni Malinen1287cd72018-01-04 17:08:01 +02002134 if (!pmf) {
2135 dut->sta_pmf = STA_PMF_OPTIONAL;
2136 if (set_network(ifname, id, "ieee80211w", "1") < 0)
2137 return -2;
2138 }
Jouni Malinen992a81e2017-08-22 13:57:47 +03002139 } else if (alg && strcasecmp(alg, "SHA-256") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002140 if (set_network(ifname, id, "key_mgmt", "WPA-PSK-SHA256") < 0)
2141 return -2;
2142 } else if (alg && strcasecmp(alg, "SHA-1") == 0) {
2143 if (set_network(ifname, id, "key_mgmt", "WPA-PSK") < 0)
2144 return -2;
Ashwini Patil6dbf7b02017-03-20 13:42:11 +05302145 } else if (val && strcasecmp(val, "wpa2-ft") == 0) {
2146 if (set_network(ifname, id, "key_mgmt", "FT-PSK") < 0)
2147 return -2;
Jouni Malinen3b73d872019-06-12 03:13:25 +03002148 } else if (!akm &&
2149 ((val && strcasecmp(val, "wpa2-sha256") == 0) ||
2150 dut->sta_pmf == STA_PMF_REQUIRED)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002151 if (set_network(ifname, id, "key_mgmt",
2152 "WPA-PSK WPA-PSK-SHA256") < 0)
2153 return -2;
Jouni Malinen77ff3f02019-03-28 03:45:40 +02002154 } else if (!akm && dut->sta_pmf == STA_PMF_OPTIONAL) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002155 if (set_network(ifname, id, "key_mgmt",
2156 "WPA-PSK WPA-PSK-SHA256") < 0)
2157 return -2;
Jouni Malinen77ff3f02019-03-28 03:45:40 +02002158 } else if (!akm) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002159 if (set_network(ifname, id, "key_mgmt", "WPA-PSK") < 0)
2160 return -2;
2161 }
2162
2163 val = get_param(cmd, "passPhrase");
2164 if (val == NULL)
2165 return -1;
Jouni Malinen2126f422017-10-11 23:24:33 +03002166 if (type && strcasecmp(type, "SAE") == 0) {
2167 if (set_network_quoted(ifname, id, "sae_password", val) < 0)
2168 return -2;
2169 } else {
2170 if (set_network_quoted(ifname, id, "psk", val) < 0)
2171 return -2;
2172 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002173
Jouni Malinen78d10c42019-03-25 22:34:32 +02002174 val = get_param(cmd, "PasswordId");
2175 if (val && set_network_quoted(ifname, id, "sae_password_id", val) < 0)
2176 return ERROR_SEND_STATUS;
2177
Jouni Malinen992a81e2017-08-22 13:57:47 +03002178 val = get_param(cmd, "ECGroupID");
2179 if (val) {
Jouni Malinenb54f0df2019-12-12 01:57:29 +02002180 snprintf(buf, sizeof(buf), "SET sae_groups %s", val);
Jouni Malinen992a81e2017-08-22 13:57:47 +03002181 if (wpa_command(ifname, buf) != 0) {
2182 sigma_dut_print(dut, DUT_MSG_ERROR,
2183 "Failed to clear sae_groups");
2184 return -2;
2185 }
2186 }
2187
Jouni Malinen68143132017-09-02 02:34:08 +03002188 val = get_param(cmd, "InvalidSAEElement");
2189 if (val) {
2190 free(dut->sae_commit_override);
2191 dut->sae_commit_override = strdup(val);
2192 }
2193
Jouni Malinen4b3769d2019-10-10 16:20:29 +03002194 val = get_param(cmd, "PMKID_Include");
2195 if (val) {
2196 snprintf(buf, sizeof(buf), "SET sae_pmkid_in_assoc %d",
2197 get_enable_disable(val));
2198 wpa_command(intf, buf);
2199 }
2200
Jouni Malineneeb43d32019-12-06 17:40:07 +02002201 val = get_param(cmd, "IgnoreH2E_RSNXE_BSSMemSel");
2202 if (val) {
2203 snprintf(buf, sizeof(buf), "SET ignore_sae_h2e_only %d",
2204 get_enable_disable(val));
2205 wpa_command(intf, buf);
2206 }
2207
Jouni Malinenf2348d22019-12-07 11:52:55 +02002208 val = get_param(cmd, "ECGroupID_RGE");
2209 if (val) {
2210 snprintf(buf, sizeof(buf), "SET extra_sae_rejected_groups %s",
2211 val);
2212 wpa_command(intf, buf);
2213 }
2214
Jouni Malinen99e55022019-12-07 13:59:41 +02002215 val = get_param(cmd, "RSNXE_Content");
2216 if (val) {
2217 const char *param;
2218
2219 if (strncasecmp(val, "AssocReq:", 9) == 0) {
2220 val += 9;
2221 param = "rsnxe_override_assoc";
2222 } else if (strncasecmp(val, "EapolM2:", 8) == 0) {
2223 val += 8;
2224 param = "rsnxe_override_eapol";
2225 } else {
2226 send_resp(dut, conn, SIGMA_ERROR,
2227 "errorCode,Unsupported RSNXE_Content value");
2228 return STATUS_SENT_ERROR;
2229 }
2230 snprintf(buf, sizeof(buf), "SET %s %s", param, val);
2231 wpa_command(intf, buf);
2232 }
2233
Jouni Malinen11e55212019-11-22 21:46:59 +02002234 val = get_param(cmd, "sae_pwe");
2235 if (val) {
2236 if (strcasecmp(val, "h2e") == 0) {
2237 dut->sae_pwe = SAE_PWE_H2E;
Jouni Malinen7244a412019-12-07 11:54:10 +02002238 } else if (strcasecmp(val, "loop") == 0 ||
2239 strcasecmp(val, "looping") == 0) {
Jouni Malinen11e55212019-11-22 21:46:59 +02002240 dut->sae_pwe = SAE_PWE_LOOP;
2241 } else {
2242 send_resp(dut, conn, SIGMA_ERROR,
2243 "errorCode,Unsupported sae_pwe value");
2244 return STATUS_SENT_ERROR;
2245 }
2246 }
Vinita S. Maloo6d7454f2020-04-02 15:03:26 +05302247
2248 val = get_param(cmd, "Clear_RSNXE");
2249 if (val && strcmp(val, "1") == 0 &&
2250 (wpa_command(intf, "SET rsnxe_override_assoc ") ||
2251 wpa_command(intf, "SET rsnxe_override_eapol "))) {
2252 send_resp(dut, conn, SIGMA_ERROR,
2253 "errorCode,Failed to clear RSNXE");
2254 return ERROR_SEND_STATUS;
2255 }
2256
Jouni Malinenc0078772020-03-04 21:23:16 +02002257 if (dut->sae_pwe == SAE_PWE_LOOP && get_param(cmd, "PasswordId"))
2258 sae_pwe = 3;
2259 else if (dut->sae_pwe == SAE_PWE_LOOP)
Jouni Malinen11e55212019-11-22 21:46:59 +02002260 sae_pwe = 0;
2261 else if (dut->sae_pwe == SAE_PWE_H2E)
2262 sae_pwe = 1;
2263 else if (dut->sae_h2e_default)
2264 sae_pwe = 2;
2265 snprintf(buf, sizeof(buf), "SET sae_pwe %d", sae_pwe);
2266 if (sae_pwe >= 0 && wpa_command(ifname, buf) != 0)
2267 return ERROR_SEND_STATUS;
2268
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002269 if (dut->program == PROGRAM_60GHZ && network_mode &&
2270 strcasecmp(network_mode, "PBSS") == 0 &&
2271 set_network(ifname, id, "pbss", "1") < 0)
2272 return -2;
2273
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002274 return 1;
2275}
2276
2277
Jouni Malinen8ac93452019-08-14 15:19:13 +03002278static enum sigma_cmd_result set_trust_root_system(struct sigma_dut *dut,
2279 struct sigma_conn *conn,
2280 const char *ifname, int id)
2281{
2282 char buf[200];
2283
2284 snprintf(buf, sizeof(buf), "%s/certs", sigma_cert_path);
2285 if (!file_exists(buf))
2286 strlcpy(buf, "/system/etc/security/cacerts", sizeof(buf));
2287 if (!file_exists(buf))
2288 strlcpy(buf, "/etc/ssl/certs", sizeof(buf));
2289 if (!file_exists(buf)) {
2290 char msg[300];
2291
2292 snprintf(msg, sizeof(msg),
2293 "ErrorCode,trustedRootCA system store (%s) not found",
2294 buf);
2295 send_resp(dut, conn, SIGMA_ERROR, msg);
2296 return STATUS_SENT_ERROR;
2297 }
2298
2299 if (set_network_quoted(ifname, id, "ca_path", buf) < 0)
2300 return ERROR_SEND_STATUS;
2301
2302 return SUCCESS_SEND_STATUS;
2303}
2304
2305
2306static enum sigma_cmd_result set_trust_root(struct sigma_dut *dut,
2307 struct sigma_conn *conn,
2308 const char *ifname, int id,
2309 const char *val)
2310{
2311 char buf[200];
2312#ifdef ANDROID
2313 unsigned char kvalue[KEYSTORE_MESSAGE_SIZE];
2314 int length;
2315#endif /* ANDROID */
2316
2317 if (strcmp(val, "DEFAULT") == 0)
2318 return set_trust_root_system(dut, conn, ifname, id);
2319
2320#ifdef ANDROID
2321 snprintf(buf, sizeof(buf), "CACERT_%s", val);
2322 length = android_keystore_get(ANDROID_KEYSTORE_GET, buf, kvalue);
2323 if (length > 0) {
2324 sigma_dut_print(dut, DUT_MSG_INFO, "Use Android keystore [%s]",
2325 buf);
2326 snprintf(buf, sizeof(buf), "keystore://CACERT_%s", val);
2327 goto ca_cert_selected;
2328 }
2329#endif /* ANDROID */
2330
2331 snprintf(buf, sizeof(buf), "%s/%s", sigma_cert_path, val);
2332#ifdef __linux__
2333 if (!file_exists(buf)) {
2334 char msg[300];
2335
2336 snprintf(msg, sizeof(msg),
2337 "ErrorCode,trustedRootCA file (%s) not found", buf);
2338 send_resp(dut, conn, SIGMA_ERROR, msg);
2339 return STATUS_SENT_ERROR;
2340 }
2341#endif /* __linux__ */
2342#ifdef ANDROID
2343ca_cert_selected:
2344#endif /* ANDROID */
2345 if (set_network_quoted(ifname, id, "ca_cert", buf) < 0)
2346 return ERROR_SEND_STATUS;
2347
2348 return SUCCESS_SEND_STATUS;
2349}
2350
2351
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002352static int set_eap_common(struct sigma_dut *dut, struct sigma_conn *conn,
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302353 const char *ifname, int username_identity,
2354 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002355{
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002356 const char *val, *alg, *akm, *trust_root, *domain, *domain_suffix;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002357 int id;
Jouni Malinen53264f62019-05-03 13:04:40 +03002358 char buf[200], buf2[300];
Jouni Malinen8179fee2019-03-28 03:19:47 +02002359 int erp = 0;
Jouni Malinen8ac93452019-08-14 15:19:13 +03002360 enum sigma_cmd_result res;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002361
2362 id = set_wpa_common(dut, conn, ifname, cmd);
2363 if (id < 0)
2364 return id;
2365
2366 val = get_param(cmd, "keyMgmtType");
2367 alg = get_param(cmd, "micAlg");
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302368 akm = get_param(cmd, "AKMSuiteType");
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002369 trust_root = get_param(cmd, "trustedRootCA");
2370 domain = get_param(cmd, "Domain");
2371 domain_suffix = get_param(cmd, "DomainSuffix");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002372
Jouni Malinenad395a22017-09-01 21:13:46 +03002373 if (val && strcasecmp(val, "SuiteB") == 0) {
2374 if (set_network(ifname, id, "key_mgmt", "WPA-EAP-SUITE-B-192") <
2375 0)
2376 return -2;
2377 } else if (alg && strcasecmp(alg, "SHA-256") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002378 if (set_network(ifname, id, "key_mgmt", "WPA-EAP-SHA256") < 0)
2379 return -2;
2380 } else if (alg && strcasecmp(alg, "SHA-1") == 0) {
2381 if (set_network(ifname, id, "key_mgmt", "WPA-EAP") < 0)
2382 return -2;
2383 } else if (val && strcasecmp(val, "wpa2-ft") == 0) {
2384 if (set_network(ifname, id, "key_mgmt", "FT-EAP") < 0)
2385 return -2;
Jouni Malinend6a9d692019-03-28 03:01:24 +02002386 } else if (!akm &&
2387 ((val && strcasecmp(val, "wpa2-sha256") == 0) ||
2388 dut->sta_pmf == STA_PMF_REQUIRED)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002389 if (set_network(ifname, id, "key_mgmt",
2390 "WPA-EAP WPA-EAP-SHA256") < 0)
2391 return -2;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302392 } else if (akm && atoi(akm) == 14) {
2393 if (dut->sta_pmf == STA_PMF_OPTIONAL ||
2394 dut->sta_pmf == STA_PMF_REQUIRED) {
2395 if (set_network(ifname, id, "key_mgmt",
2396 "WPA-EAP-SHA256 FILS-SHA256") < 0)
2397 return -2;
2398 } else {
2399 if (set_network(ifname, id, "key_mgmt",
2400 "WPA-EAP FILS-SHA256") < 0)
2401 return -2;
2402 }
2403
Jouni Malinen8179fee2019-03-28 03:19:47 +02002404 erp = 1;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302405 } else if (akm && atoi(akm) == 15) {
2406 if (dut->sta_pmf == STA_PMF_OPTIONAL ||
2407 dut->sta_pmf == STA_PMF_REQUIRED) {
2408 if (set_network(ifname, id, "key_mgmt",
2409 "WPA-EAP-SHA256 FILS-SHA384") < 0)
2410 return -2;
2411 } else {
2412 if (set_network(ifname, id, "key_mgmt",
2413 "WPA-EAP FILS-SHA384") < 0)
2414 return -2;
2415 }
2416
Jouni Malinen8179fee2019-03-28 03:19:47 +02002417 erp = 1;
Jouni Malinend6a9d692019-03-28 03:01:24 +02002418 } else if (!akm && dut->sta_pmf == STA_PMF_OPTIONAL) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002419 if (set_network(ifname, id, "key_mgmt",
2420 "WPA-EAP WPA-EAP-SHA256") < 0)
2421 return -2;
Jouni Malinend6a9d692019-03-28 03:01:24 +02002422 } else if (!akm) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002423 if (set_network(ifname, id, "key_mgmt", "WPA-EAP") < 0)
2424 return -2;
2425 }
2426
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002427 if (trust_root) {
2428 if (strcmp(trust_root, "DEFAULT") == 0 && !domain &&
2429 !domain_suffix) {
2430 send_resp(dut, conn, SIGMA_ERROR,
2431 "errorCode,trustRootCA DEFAULT used without specifying Domain or DomainSuffix");
2432 return STATUS_SENT_ERROR;
2433 }
2434 res = set_trust_root(dut, conn, ifname, id, trust_root);
Jouni Malinen8ac93452019-08-14 15:19:13 +03002435 if (res != SUCCESS_SEND_STATUS)
2436 return res;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002437 }
2438
Jouni Malinen53264f62019-05-03 13:04:40 +03002439 val = get_param(cmd, "ServerCert");
2440 if (val) {
2441 FILE *f;
2442 char *result = NULL, *pos;
2443
2444 snprintf(buf, sizeof(buf), "%s/%s.sha256", sigma_cert_path,
2445 val);
2446 f = fopen(buf, "r");
2447 if (f) {
2448 result = fgets(buf, sizeof(buf), f);
2449 fclose(f);
2450 }
2451 if (!result) {
2452 snprintf(buf2, sizeof(buf2),
2453 "ErrorCode,ServerCert hash could not be read from %s",
2454 buf);
2455 send_resp(dut, conn, SIGMA_ERROR, buf2);
2456 return STATUS_SENT_ERROR;
2457 }
2458 pos = strchr(buf, '\n');
2459 if (pos)
2460 *pos = '\0';
2461 snprintf(buf2, sizeof(buf2), "hash://server/sha256/%s", buf);
2462 if (set_network_quoted(ifname, id, "ca_cert", buf2) < 0)
2463 return ERROR_SEND_STATUS;
Jouni Malinen29108dc2019-06-13 23:42:11 +03002464
2465 snprintf(buf, sizeof(buf), "%s/%s.tod", sigma_cert_path, val);
2466 if (file_exists(buf)) {
2467 sigma_dut_print(dut, DUT_MSG_DEBUG,
2468 "TOD policy enabled for the configured ServerCert hash");
2469 dut->sta_tod_policy = 1;
2470 }
Jouni Malinen53264f62019-05-03 13:04:40 +03002471 }
2472
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002473 if (domain &&
2474 set_network_quoted(ifname, id, "domain_match", domain) < 0)
Jouni Malinen96f84b02019-05-03 12:32:56 +03002475 return ERROR_SEND_STATUS;
2476
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002477 if (domain_suffix &&
2478 set_network_quoted(ifname, id, "domain_suffix_match",
2479 domain_suffix) < 0)
Jouni Malinen96f84b02019-05-03 12:32:56 +03002480 return ERROR_SEND_STATUS;
2481
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302482 if (username_identity) {
2483 val = get_param(cmd, "username");
2484 if (val) {
2485 if (set_network_quoted(ifname, id, "identity", val) < 0)
2486 return -2;
2487 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002488
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302489 val = get_param(cmd, "password");
2490 if (val) {
2491 if (set_network_quoted(ifname, id, "password", val) < 0)
2492 return -2;
2493 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002494 }
2495
Jouni Malinen8179fee2019-03-28 03:19:47 +02002496 if (dut->akm_values &
2497 ((1 << AKM_FILS_SHA256) |
2498 (1 << AKM_FILS_SHA384) |
2499 (1 << AKM_FT_FILS_SHA256) |
2500 (1 << AKM_FT_FILS_SHA384)))
2501 erp = 1;
2502 if (erp && set_network(ifname, id, "erp", "1") < 0)
2503 return ERROR_SEND_STATUS;
2504
Jouni Malinen134fe3c2019-06-12 04:16:49 +03002505 dut->sta_associate_wait_connect = 1;
2506
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002507 return id;
2508}
2509
2510
Jouni Malinen5eabb2a2017-10-03 18:17:30 +03002511static int set_tls_cipher(const char *ifname, int id, const char *cipher)
2512{
2513 const char *val;
2514
2515 if (!cipher)
2516 return 0;
2517
2518 if (strcasecmp(cipher, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384") == 0)
2519 val = "ECDHE-ECDSA-AES256-GCM-SHA384";
2520 else if (strcasecmp(cipher,
2521 "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384") == 0)
2522 val = "ECDHE-RSA-AES256-GCM-SHA384";
2523 else if (strcasecmp(cipher, "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384") == 0)
2524 val = "DHE-RSA-AES256-GCM-SHA384";
2525 else if (strcasecmp(cipher,
2526 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256") == 0)
2527 val = "ECDHE-ECDSA-AES128-GCM-SHA256";
2528 else
2529 return -1;
2530
2531 /* Need to clear phase1="tls_suiteb=1" to allow cipher enforcement */
2532 set_network_quoted(ifname, id, "phase1", "");
2533
2534 return set_network_quoted(ifname, id, "openssl_ciphers", val);
2535}
2536
2537
Jouni Malinenf7222712019-06-13 01:50:21 +03002538static enum sigma_cmd_result cmd_sta_set_eaptls(struct sigma_dut *dut,
2539 struct sigma_conn *conn,
2540 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002541{
2542 const char *intf = get_param(cmd, "Interface");
2543 const char *ifname, *val;
2544 int id;
2545 char buf[200];
2546#ifdef ANDROID
2547 unsigned char kvalue[KEYSTORE_MESSAGE_SIZE];
2548 int length;
2549 int jb_or_newer = 0;
2550 char prop[PROPERTY_VALUE_MAX];
2551#endif /* ANDROID */
2552
2553 if (intf == NULL)
2554 return -1;
2555
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002556 if (strcmp(intf, get_main_ifname(dut)) == 0)
2557 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002558 else
2559 ifname = intf;
2560
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302561 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002562 if (id < 0)
2563 return id;
2564
2565 if (set_network(ifname, id, "eap", "TLS") < 0)
2566 return -2;
2567
Pradeep Reddy POTTETI9f6c2132016-05-05 16:28:19 +05302568 if (!get_param(cmd, "username") &&
2569 set_network_quoted(ifname, id, "identity",
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002570 "wifi-user@wifilabs.local") < 0)
2571 return -2;
2572
2573 val = get_param(cmd, "clientCertificate");
2574 if (val == NULL)
2575 return -1;
2576#ifdef ANDROID
2577 snprintf(buf, sizeof(buf), "USRPKEY_%s", val);
2578 length = android_keystore_get(ANDROID_KEYSTORE_GET, buf, kvalue);
2579 if (length < 0) {
2580 /*
2581 * JB started reporting keystore type mismatches, so retry with
2582 * the GET_PUBKEY command if the generic GET fails.
2583 */
2584 length = android_keystore_get(ANDROID_KEYSTORE_GET_PUBKEY,
2585 buf, kvalue);
2586 }
2587
2588 if (property_get("ro.build.version.release", prop, NULL) != 0) {
2589 sigma_dut_print(dut, DUT_MSG_DEBUG, "Android release %s", prop);
2590 if (strncmp(prop, "4.0", 3) != 0)
2591 jb_or_newer = 1;
2592 } else
2593 jb_or_newer = 1; /* assume newer */
2594
2595 if (jb_or_newer && length > 0) {
2596 sigma_dut_print(dut, DUT_MSG_INFO,
2597 "Use Android keystore [%s]", buf);
2598 if (set_network(ifname, id, "engine", "1") < 0)
2599 return -2;
2600 if (set_network_quoted(ifname, id, "engine_id", "keystore") < 0)
2601 return -2;
2602 snprintf(buf, sizeof(buf), "USRPKEY_%s", val);
2603 if (set_network_quoted(ifname, id, "key_id", buf) < 0)
2604 return -2;
2605 snprintf(buf, sizeof(buf), "keystore://USRCERT_%s", val);
2606 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
2607 return -2;
2608 return 1;
2609 } else if (length > 0) {
2610 sigma_dut_print(dut, DUT_MSG_INFO,
2611 "Use Android keystore [%s]", buf);
2612 snprintf(buf, sizeof(buf), "keystore://USRPKEY_%s", val);
2613 if (set_network_quoted(ifname, id, "private_key", buf) < 0)
2614 return -2;
2615 snprintf(buf, sizeof(buf), "keystore://USRCERT_%s", val);
2616 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
2617 return -2;
2618 return 1;
2619 }
2620#endif /* ANDROID */
2621
2622 snprintf(buf, sizeof(buf), "%s/%s", sigma_cert_path, val);
2623#ifdef __linux__
2624 if (!file_exists(buf)) {
2625 char msg[300];
2626 snprintf(msg, sizeof(msg), "ErrorCode,clientCertificate file "
2627 "(%s) not found", buf);
2628 send_resp(dut, conn, SIGMA_ERROR, msg);
2629 return -3;
2630 }
2631#endif /* __linux__ */
2632 if (set_network_quoted(ifname, id, "private_key", buf) < 0)
2633 return -2;
2634 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
2635 return -2;
2636
2637 if (set_network_quoted(ifname, id, "private_key_passwd", "wifi") < 0)
2638 return -2;
2639
Jouni Malinen5eabb2a2017-10-03 18:17:30 +03002640 val = get_param(cmd, "keyMgmtType");
2641 if (val && strcasecmp(val, "SuiteB") == 0) {
2642 val = get_param(cmd, "CertType");
2643 if (val && strcasecmp(val, "RSA") == 0) {
2644 if (set_network_quoted(ifname, id, "phase1",
2645 "tls_suiteb=1") < 0)
2646 return -2;
2647 } else {
2648 if (set_network_quoted(ifname, id, "openssl_ciphers",
2649 "SUITEB192") < 0)
2650 return -2;
2651 }
2652
2653 val = get_param(cmd, "TLSCipher");
2654 if (set_tls_cipher(ifname, id, val) < 0) {
2655 send_resp(dut, conn, SIGMA_ERROR,
2656 "ErrorCode,Unsupported TLSCipher value");
2657 return -3;
2658 }
2659 }
2660
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002661 return 1;
2662}
2663
2664
Jouni Malinenf7222712019-06-13 01:50:21 +03002665static enum sigma_cmd_result cmd_sta_set_eapttls(struct sigma_dut *dut,
2666 struct sigma_conn *conn,
2667 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002668{
2669 const char *intf = get_param(cmd, "Interface");
2670 const char *ifname;
2671 int id;
2672
2673 if (intf == NULL)
2674 return -1;
2675
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002676 if (strcmp(intf, get_main_ifname(dut)) == 0)
2677 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002678 else
2679 ifname = intf;
2680
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302681 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002682 if (id < 0)
2683 return id;
2684
2685 if (set_network(ifname, id, "eap", "TTLS") < 0) {
2686 send_resp(dut, conn, SIGMA_ERROR,
2687 "errorCode,Failed to set TTLS method");
2688 return 0;
2689 }
2690
2691 if (set_network_quoted(ifname, id, "phase2", "auth=MSCHAPV2") < 0) {
2692 send_resp(dut, conn, SIGMA_ERROR,
2693 "errorCode,Failed to set MSCHAPv2 for TTLS Phase 2");
2694 return 0;
2695 }
2696
2697 return 1;
2698}
2699
2700
Jouni Malinenf7222712019-06-13 01:50:21 +03002701static enum sigma_cmd_result cmd_sta_set_eapsim(struct sigma_dut *dut,
2702 struct sigma_conn *conn,
2703 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002704{
2705 const char *intf = get_param(cmd, "Interface");
2706 const char *ifname;
2707 int id;
2708
2709 if (intf == NULL)
2710 return -1;
2711
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002712 if (strcmp(intf, get_main_ifname(dut)) == 0)
2713 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002714 else
2715 ifname = intf;
2716
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302717 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002718 if (id < 0)
2719 return id;
2720
2721 if (set_network(ifname, id, "eap", "SIM") < 0)
2722 return -2;
2723
2724 return 1;
2725}
2726
2727
Jouni Malinenf7222712019-06-13 01:50:21 +03002728static enum sigma_cmd_result cmd_sta_set_peap(struct sigma_dut *dut,
2729 struct sigma_conn *conn,
2730 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002731{
2732 const char *intf = get_param(cmd, "Interface");
2733 const char *ifname, *val;
2734 int id;
2735 char buf[100];
2736
2737 if (intf == NULL)
2738 return -1;
2739
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002740 if (strcmp(intf, get_main_ifname(dut)) == 0)
2741 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002742 else
2743 ifname = intf;
2744
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302745 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002746 if (id < 0)
2747 return id;
2748
2749 if (set_network(ifname, id, "eap", "PEAP") < 0)
2750 return -2;
2751
2752 val = get_param(cmd, "innerEAP");
2753 if (val) {
2754 if (strcasecmp(val, "MSCHAPv2") == 0) {
2755 if (set_network_quoted(ifname, id, "phase2",
2756 "auth=MSCHAPV2") < 0)
2757 return -2;
2758 } else if (strcasecmp(val, "GTC") == 0) {
2759 if (set_network_quoted(ifname, id, "phase2",
2760 "auth=GTC") < 0)
2761 return -2;
2762 } else
2763 return -1;
2764 }
2765
2766 val = get_param(cmd, "peapVersion");
2767 if (val) {
2768 int ver = atoi(val);
2769 if (ver < 0 || ver > 1)
2770 return -1;
2771 snprintf(buf, sizeof(buf), "peapver=%d", ver);
2772 if (set_network_quoted(ifname, id, "phase1", buf) < 0)
2773 return -2;
2774 }
2775
2776 return 1;
2777}
2778
2779
Jouni Malinenf7222712019-06-13 01:50:21 +03002780static enum sigma_cmd_result cmd_sta_set_eapfast(struct sigma_dut *dut,
2781 struct sigma_conn *conn,
2782 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002783{
2784 const char *intf = get_param(cmd, "Interface");
2785 const char *ifname, *val;
2786 int id;
2787 char buf[100];
2788
2789 if (intf == NULL)
2790 return -1;
2791
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002792 if (strcmp(intf, get_main_ifname(dut)) == 0)
2793 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002794 else
2795 ifname = intf;
2796
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302797 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002798 if (id < 0)
2799 return id;
2800
2801 if (set_network(ifname, id, "eap", "FAST") < 0)
2802 return -2;
2803
2804 val = get_param(cmd, "innerEAP");
2805 if (val) {
2806 if (strcasecmp(val, "MSCHAPV2") == 0) {
2807 if (set_network_quoted(ifname, id, "phase2",
2808 "auth=MSCHAPV2") < 0)
2809 return -2;
2810 } else if (strcasecmp(val, "GTC") == 0) {
2811 if (set_network_quoted(ifname, id, "phase2",
2812 "auth=GTC") < 0)
2813 return -2;
2814 } else
2815 return -1;
2816 }
2817
2818 val = get_param(cmd, "validateServer");
2819 if (val) {
2820 /* TODO */
2821 sigma_dut_print(dut, DUT_MSG_INFO, "Ignored EAP-FAST "
2822 "validateServer=%s", val);
2823 }
2824
2825 val = get_param(cmd, "pacFile");
2826 if (val) {
2827 snprintf(buf, sizeof(buf), "blob://%s", val);
2828 if (set_network_quoted(ifname, id, "pac_file", buf) < 0)
2829 return -2;
2830 }
2831
2832 if (set_network_quoted(ifname, id, "phase1", "fast_provisioning=2") <
2833 0)
2834 return -2;
2835
2836 return 1;
2837}
2838
2839
Jouni Malinenf7222712019-06-13 01:50:21 +03002840static enum sigma_cmd_result cmd_sta_set_eapaka(struct sigma_dut *dut,
2841 struct sigma_conn *conn,
2842 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002843{
2844 const char *intf = get_param(cmd, "Interface");
Purushottam Kushwahacdd8cb12019-10-04 11:33:59 +05302845 const char *username = get_param(cmd, "Username");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002846 const char *ifname;
2847 int id;
2848
2849 if (intf == NULL)
2850 return -1;
2851
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002852 if (strcmp(intf, get_main_ifname(dut)) == 0)
2853 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002854 else
2855 ifname = intf;
2856
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302857 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002858 if (id < 0)
2859 return id;
2860
Purushottam Kushwahacdd8cb12019-10-04 11:33:59 +05302861 /* RFC 5448: EAP-AKA' MUST use the leading character "6" (ASCII 36
2862 * hexadecimal).
2863 */
2864 if (username && username[0] == '6') {
2865 if (set_network(ifname, id, "eap", "AKA'") < 0)
2866 return -2;
2867 } else if (set_network(ifname, id, "eap", "AKA") < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002868 return -2;
Purushottam Kushwahacdd8cb12019-10-04 11:33:59 +05302869 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002870
2871 return 1;
2872}
2873
2874
Jouni Malinenf7222712019-06-13 01:50:21 +03002875static enum sigma_cmd_result cmd_sta_set_eapakaprime(struct sigma_dut *dut,
2876 struct sigma_conn *conn,
2877 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002878{
2879 const char *intf = get_param(cmd, "Interface");
2880 const char *ifname;
2881 int id;
2882
2883 if (intf == NULL)
2884 return -1;
2885
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002886 if (strcmp(intf, get_main_ifname(dut)) == 0)
2887 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002888 else
2889 ifname = intf;
2890
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302891 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002892 if (id < 0)
2893 return id;
2894
2895 if (set_network(ifname, id, "eap", "AKA'") < 0)
2896 return -2;
2897
2898 return 1;
2899}
2900
2901
2902static int sta_set_open(struct sigma_dut *dut, struct sigma_conn *conn,
2903 struct sigma_cmd *cmd)
2904{
2905 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002906 const char *network_mode = get_param(cmd, "network_mode");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002907 const char *ifname;
2908 int id;
2909
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002910 if (strcmp(intf, get_main_ifname(dut)) == 0)
2911 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002912 else
2913 ifname = intf;
2914
2915 id = add_network_common(dut, conn, ifname, cmd);
2916 if (id < 0)
2917 return id;
2918
2919 if (set_network(ifname, id, "key_mgmt", "NONE") < 0)
2920 return -2;
2921
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002922 if (dut->program == PROGRAM_60GHZ && network_mode &&
2923 strcasecmp(network_mode, "PBSS") == 0 &&
2924 set_network(ifname, id, "pbss", "1") < 0)
2925 return -2;
2926
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002927 return 1;
2928}
2929
2930
Jouni Malinen47dcc952017-10-09 16:43:24 +03002931static int sta_set_owe(struct sigma_dut *dut, struct sigma_conn *conn,
2932 struct sigma_cmd *cmd)
2933{
2934 const char *intf = get_param(cmd, "Interface");
2935 const char *ifname, *val;
2936 int id;
2937
2938 if (intf == NULL)
2939 return -1;
2940
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002941 if (strcmp(intf, get_main_ifname(dut)) == 0)
2942 ifname = get_station_ifname(dut);
Jouni Malinen47dcc952017-10-09 16:43:24 +03002943 else
2944 ifname = intf;
2945
2946 id = set_wpa_common(dut, conn, ifname, cmd);
2947 if (id < 0)
2948 return id;
2949
2950 if (set_network(ifname, id, "key_mgmt", "OWE") < 0)
2951 return -2;
2952
2953 val = get_param(cmd, "ECGroupID");
Jouni Malinenfac9cad2017-10-10 18:35:55 +03002954 if (val && strcmp(val, "0") == 0) {
2955 if (wpa_command(ifname,
2956 "VENDOR_ELEM_ADD 13 ff23200000783590fb7440e03d5b3b33911f86affdcc6b4411b707846ac4ff08ddc8831ccd") != 0) {
2957 sigma_dut_print(dut, DUT_MSG_ERROR,
2958 "Failed to set OWE DH Param element override");
2959 return -2;
2960 }
Hu Wang6010ce72020-03-05 19:33:53 +08002961 } else if (val &&
2962 (set_network(ifname, id, "owe_group", val) < 0 ||
2963 (dut->owe_ptk_workaround &&
2964 set_network(ifname, id, "owe_ptk_workaround", "1") < 0))) {
Jouni Malinen47dcc952017-10-09 16:43:24 +03002965 sigma_dut_print(dut, DUT_MSG_ERROR,
Hu Wang6010ce72020-03-05 19:33:53 +08002966 "Failed to set owe_group");
Jouni Malinen47dcc952017-10-09 16:43:24 +03002967 return -2;
2968 }
2969
2970 return 1;
2971}
2972
2973
Jouni Malinenf7222712019-06-13 01:50:21 +03002974static enum sigma_cmd_result cmd_sta_set_security(struct sigma_dut *dut,
2975 struct sigma_conn *conn,
2976 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002977{
2978 const char *type = get_param(cmd, "Type");
2979
2980 if (type == NULL) {
2981 send_resp(dut, conn, SIGMA_ERROR,
2982 "ErrorCode,Missing Type argument");
2983 return 0;
2984 }
2985
2986 if (strcasecmp(type, "OPEN") == 0)
2987 return sta_set_open(dut, conn, cmd);
Jouni Malinen47dcc952017-10-09 16:43:24 +03002988 if (strcasecmp(type, "OWE") == 0)
2989 return sta_set_owe(dut, conn, cmd);
Jouni Malinen992a81e2017-08-22 13:57:47 +03002990 if (strcasecmp(type, "PSK") == 0 ||
Jouni Malinen0ab50f42017-08-31 01:34:59 +03002991 strcasecmp(type, "PSK-SAE") == 0 ||
Jouni Malinen992a81e2017-08-22 13:57:47 +03002992 strcasecmp(type, "SAE") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002993 return cmd_sta_set_psk(dut, conn, cmd);
2994 if (strcasecmp(type, "EAPTLS") == 0)
2995 return cmd_sta_set_eaptls(dut, conn, cmd);
2996 if (strcasecmp(type, "EAPTTLS") == 0)
2997 return cmd_sta_set_eapttls(dut, conn, cmd);
2998 if (strcasecmp(type, "EAPPEAP") == 0)
2999 return cmd_sta_set_peap(dut, conn, cmd);
3000 if (strcasecmp(type, "EAPSIM") == 0)
3001 return cmd_sta_set_eapsim(dut, conn, cmd);
3002 if (strcasecmp(type, "EAPFAST") == 0)
3003 return cmd_sta_set_eapfast(dut, conn, cmd);
3004 if (strcasecmp(type, "EAPAKA") == 0)
3005 return cmd_sta_set_eapaka(dut, conn, cmd);
3006 if (strcasecmp(type, "EAPAKAPRIME") == 0)
3007 return cmd_sta_set_eapakaprime(dut, conn, cmd);
Amarnath Hullur Subramanyam81b11cd2018-01-30 19:07:17 -08003008 if (strcasecmp(type, "wep") == 0)
3009 return cmd_sta_set_encryption(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003010
3011 send_resp(dut, conn, SIGMA_ERROR,
3012 "ErrorCode,Unsupported Type value");
3013 return 0;
3014}
3015
3016
3017int ath6kl_client_uapsd(struct sigma_dut *dut, const char *intf, int uapsd)
3018{
3019#ifdef __linux__
3020 /* special handling for ath6kl */
3021 char path[128], fname[128], *pos;
3022 ssize_t res;
3023 FILE *f;
3024
Jouni Malinene39cd562019-05-29 23:39:56 +03003025 res = snprintf(fname, sizeof(fname), "/sys/class/net/%s/phy80211",
3026 intf);
3027 if (res < 0 || res >= sizeof(fname))
3028 return 0;
3029 res = readlink(fname, path, sizeof(path));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003030 if (res < 0)
3031 return 0; /* not ath6kl */
3032
3033 if (res >= (int) sizeof(path))
3034 res = sizeof(path) - 1;
3035 path[res] = '\0';
3036 pos = strrchr(path, '/');
3037 if (pos == NULL)
3038 pos = path;
3039 else
3040 pos++;
Jouni Malinen77dda642020-01-07 11:21:55 +02003041 res = snprintf(fname, sizeof(fname),
3042 "/sys/kernel/debug/ieee80211/%s/ath6kl/"
3043 "create_qos", pos);
3044 if (res < 0 || res >= sizeof(fname) || !file_exists(fname))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003045 return 0; /* not ath6kl */
3046
3047 if (uapsd) {
3048 f = fopen(fname, "w");
3049 if (f == NULL)
3050 return -1;
3051
3052 sigma_dut_print(dut, DUT_MSG_DEBUG, "Use ath6kl create_qos");
3053 fprintf(f, "4 2 2 1 2 9999999 9999999 9999999 7777777 0 4 "
3054 "45000 200 56789000 56789000 5678900 0 0 9999999 "
3055 "20000 0\n");
3056 fclose(f);
3057 } else {
Jouni Malinen77dda642020-01-07 11:21:55 +02003058 res = snprintf(fname, sizeof(fname),
3059 "/sys/kernel/debug/ieee80211/%s/ath6kl/"
3060 "delete_qos", pos);
3061 if (res < 0 || res >= sizeof(fname))
3062 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003063
3064 f = fopen(fname, "w");
3065 if (f == NULL)
3066 return -1;
3067
3068 sigma_dut_print(dut, DUT_MSG_DEBUG, "Use ath6kl delete_qos");
3069 fprintf(f, "2 4\n");
3070 fclose(f);
3071 }
3072#endif /* __linux__ */
3073
3074 return 0;
3075}
3076
3077
Jouni Malinenf7222712019-06-13 01:50:21 +03003078static enum sigma_cmd_result cmd_sta_set_uapsd(struct sigma_dut *dut,
3079 struct sigma_conn *conn,
3080 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003081{
3082 const char *intf = get_param(cmd, "Interface");
3083 /* const char *ssid = get_param(cmd, "ssid"); */
3084 const char *val;
3085 int max_sp_len = 4;
3086 int ac_be = 1, ac_bk = 1, ac_vi = 1, ac_vo = 1;
3087 char buf[100];
3088 int ret1, ret2;
3089
3090 val = get_param(cmd, "maxSPLength");
3091 if (val) {
3092 max_sp_len = atoi(val);
3093 if (max_sp_len != 0 && max_sp_len != 1 && max_sp_len != 2 &&
3094 max_sp_len != 4)
3095 return -1;
3096 }
3097
3098 val = get_param(cmd, "acBE");
3099 if (val)
3100 ac_be = atoi(val);
3101
3102 val = get_param(cmd, "acBK");
3103 if (val)
3104 ac_bk = atoi(val);
3105
3106 val = get_param(cmd, "acVI");
3107 if (val)
3108 ac_vi = atoi(val);
3109
3110 val = get_param(cmd, "acVO");
3111 if (val)
3112 ac_vo = atoi(val);
3113
3114 dut->client_uapsd = ac_be || ac_bk || ac_vi || ac_vo;
3115
3116 snprintf(buf, sizeof(buf), "P2P_SET client_apsd %d,%d,%d,%d;%d",
3117 ac_be, ac_bk, ac_vi, ac_vo, max_sp_len);
3118 ret1 = wpa_command(intf, buf);
3119
3120 snprintf(buf, sizeof(buf), "SET uapsd %d,%d,%d,%d;%d",
3121 ac_be, ac_bk, ac_vi, ac_vo, max_sp_len);
3122 ret2 = wpa_command(intf, buf);
3123
3124 if (ret1 && ret2) {
3125 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to set client mode "
3126 "UAPSD parameters.");
3127 return -2;
3128 }
3129
3130 if (ath6kl_client_uapsd(dut, intf, dut->client_uapsd) < 0) {
3131 send_resp(dut, conn, SIGMA_ERROR,
3132 "ErrorCode,Failed to set ath6kl QoS parameters");
3133 return 0;
3134 }
3135
3136 return 1;
3137}
3138
3139
Jouni Malinenf7222712019-06-13 01:50:21 +03003140static enum sigma_cmd_result cmd_sta_set_wmm(struct sigma_dut *dut,
3141 struct sigma_conn *conn,
3142 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003143{
3144 char buf[1000];
3145 const char *intf = get_param(cmd, "Interface");
3146 const char *grp = get_param(cmd, "Group");
3147 const char *act = get_param(cmd, "Action");
3148 const char *tid = get_param(cmd, "Tid");
3149 const char *dir = get_param(cmd, "Direction");
3150 const char *psb = get_param(cmd, "Psb");
3151 const char *up = get_param(cmd, "Up");
3152 const char *fixed = get_param(cmd, "Fixed");
3153 const char *size = get_param(cmd, "Size");
3154 const char *msize = get_param(cmd, "Maxsize");
3155 const char *minsi = get_param(cmd, "Min_srvc_intrvl");
3156 const char *maxsi = get_param(cmd, "Max_srvc_intrvl");
3157 const char *inact = get_param(cmd, "Inactivity");
3158 const char *sus = get_param(cmd, "Suspension");
3159 const char *mindr = get_param(cmd, "Mindatarate");
3160 const char *meandr = get_param(cmd, "Meandatarate");
3161 const char *peakdr = get_param(cmd, "Peakdatarate");
3162 const char *phyrate = get_param(cmd, "Phyrate");
3163 const char *burstsize = get_param(cmd, "Burstsize");
3164 const char *sba = get_param(cmd, "Sba");
3165 int direction;
3166 int handle;
Peng Xu93319622017-10-04 17:58:16 -07003167 float sba_fv = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003168 int fixed_int;
3169 int psb_ts;
3170
3171 if (intf == NULL || grp == NULL || act == NULL )
3172 return -1;
3173
3174 if (strcasecmp(act, "addts") == 0) {
3175 if (tid == NULL || dir == NULL || psb == NULL ||
3176 up == NULL || fixed == NULL || size == NULL)
3177 return -1;
3178
3179 /*
3180 * Note: Sigma CAPI spec lists uplink, downlink, and bidi as the
3181 * possible values, but WMM-AC and V-E test scripts use "UP,
3182 * "DOWN", and "BIDI".
3183 */
3184 if (strcasecmp(dir, "uplink") == 0 ||
3185 strcasecmp(dir, "up") == 0) {
3186 direction = 0;
3187 } else if (strcasecmp(dir, "downlink") == 0 ||
3188 strcasecmp(dir, "down") == 0) {
3189 direction = 1;
3190 } else if (strcasecmp(dir, "bidi") == 0) {
3191 direction = 2;
3192 } else {
3193 sigma_dut_print(dut, DUT_MSG_ERROR,
3194 "Direction %s not supported", dir);
3195 return -1;
3196 }
3197
3198 if (strcasecmp(psb, "legacy") == 0) {
3199 psb_ts = 0;
3200 } else if (strcasecmp(psb, "uapsd") == 0) {
3201 psb_ts = 1;
3202 } else {
3203 sigma_dut_print(dut, DUT_MSG_ERROR,
3204 "PSB %s not supported", psb);
3205 return -1;
3206 }
3207
3208 if (atoi(tid) < 0 || atoi(tid) > 7) {
3209 sigma_dut_print(dut, DUT_MSG_ERROR,
3210 "TID %s not supported", tid);
3211 return -1;
3212 }
3213
3214 if (strcasecmp(fixed, "true") == 0) {
3215 fixed_int = 1;
3216 } else {
3217 fixed_int = 0;
3218 }
3219
Peng Xu93319622017-10-04 17:58:16 -07003220 if (sba)
3221 sba_fv = atof(sba);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003222
3223 dut->dialog_token++;
3224 handle = 7000 + dut->dialog_token;
3225
3226 /*
3227 * size: convert to hex
3228 * maxsi: convert to hex
3229 * mindr: convert to hex
3230 * meandr: convert to hex
3231 * peakdr: convert to hex
3232 * burstsize: convert to hex
3233 * phyrate: convert to hex
3234 * sba: convert to hex with modification
3235 * minsi: convert to integer
3236 * sus: convert to integer
3237 * inact: convert to integer
3238 * maxsi: convert to integer
3239 */
3240
3241 /*
3242 * The Nominal MSDU Size field is 2 octets long and contains an
3243 * unsigned integer that specifies the nominal size, in octets,
3244 * of MSDUs belonging to the traffic under this traffic
3245 * specification and is defined in Figure 16. If the Fixed
3246 * subfield is set to 1, then the size of the MSDU is fixed and
3247 * is indicated by the Size Subfield. If the Fixed subfield is
3248 * set to 0, then the size of the MSDU might not be fixed and
3249 * the Size indicates the nominal MSDU size.
3250 *
3251 * The Surplus Bandwidth Allowance Factor field is 2 octets long
3252 * and specifies the excess allocation of time (and bandwidth)
3253 * over and above the stated rates required to transport an MSDU
3254 * belonging to the traffic in this TSPEC. This field is
3255 * represented as an unsigned binary number with an implicit
3256 * binary point after the leftmost 3 bits. For example, an SBA
3257 * of 1.75 is represented as 0x3800. This field is included to
3258 * account for retransmissions. As such, the value of this field
3259 * must be greater than unity.
3260 */
3261
3262 snprintf(buf, sizeof(buf),
3263 "iwpriv %s addTspec %d %s %d %d %s 0x%X"
3264 " 0x%X 0x%X 0x%X"
3265 " 0x%X 0x%X 0x%X"
3266 " 0x%X %d %d %d %d"
3267 " %d %d",
3268 intf, handle, tid, direction, psb_ts, up,
3269 (unsigned int) ((fixed_int << 15) | atoi(size)),
3270 msize ? atoi(msize) : 0,
3271 mindr ? atoi(mindr) : 0,
3272 meandr ? atoi(meandr) : 0,
3273 peakdr ? atoi(peakdr) : 0,
3274 burstsize ? atoi(burstsize) : 0,
3275 phyrate ? atoi(phyrate) : 0,
3276 sba ? ((unsigned int) (((int) sba_fv << 13) |
3277 (int)((sba_fv - (int) sba_fv) *
3278 8192))) : 0,
3279 minsi ? atoi(minsi) : 0,
3280 sus ? atoi(sus) : 0,
3281 0, 0,
3282 inact ? atoi(inact) : 0,
3283 maxsi ? atoi(maxsi) : 0);
3284
3285 if (system(buf) != 0) {
3286 sigma_dut_print(dut, DUT_MSG_ERROR,
3287 "iwpriv addtspec request failed");
3288 send_resp(dut, conn, SIGMA_ERROR,
3289 "errorCode,Failed to execute addTspec command");
3290 return 0;
3291 }
3292
3293 sigma_dut_print(dut, DUT_MSG_INFO,
3294 "iwpriv addtspec request send");
3295
3296 /* Mapping handle to a TID */
3297 dut->tid_to_handle[atoi(tid)] = handle;
3298 } else if (strcasecmp(act, "delts") == 0) {
3299 if (tid == NULL)
3300 return -1;
3301
3302 if (atoi(tid) < 0 || atoi(tid) > 7) {
3303 sigma_dut_print(dut, DUT_MSG_ERROR,
3304 "TID %s not supported", tid);
3305 send_resp(dut, conn, SIGMA_ERROR,
3306 "errorCode,Unsupported TID");
3307 return 0;
3308 }
3309
3310 handle = dut->tid_to_handle[atoi(tid)];
3311
3312 if (handle < 7000 || handle > 7255) {
3313 /* Invalid handle ie no mapping for that TID */
3314 sigma_dut_print(dut, DUT_MSG_ERROR,
3315 "handle-> %d not found", handle);
3316 }
3317
3318 snprintf(buf, sizeof(buf), "iwpriv %s delTspec %d",
3319 intf, handle);
3320
3321 if (system(buf) != 0) {
3322 sigma_dut_print(dut, DUT_MSG_ERROR,
3323 "iwpriv deltspec request failed");
3324 send_resp(dut, conn, SIGMA_ERROR,
3325 "errorCode,Failed to execute delTspec command");
3326 return 0;
3327 }
3328
3329 sigma_dut_print(dut, DUT_MSG_INFO,
3330 "iwpriv deltspec request send");
3331
3332 dut->tid_to_handle[atoi(tid)] = 0;
3333 } else {
3334 sigma_dut_print(dut, DUT_MSG_ERROR,
3335 "Action type %s not supported", act);
3336 send_resp(dut, conn, SIGMA_ERROR,
3337 "errorCode,Unsupported Action");
3338 return 0;
3339 }
3340
3341 return 1;
3342}
3343
3344
vamsi krishna52e16f92017-08-29 12:37:34 +05303345static int find_network(struct sigma_dut *dut, const char *ssid)
3346{
3347 char list[4096];
3348 char *pos;
3349
3350 sigma_dut_print(dut, DUT_MSG_DEBUG,
3351 "Search for profile based on SSID: '%s'", ssid);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003352 if (wpa_command_resp(get_station_ifname(dut), "LIST_NETWORKS",
vamsi krishna52e16f92017-08-29 12:37:34 +05303353 list, sizeof(list)) < 0)
3354 return -1;
3355 pos = strstr(list, ssid);
3356 if (!pos || pos == list || pos[-1] != '\t' || pos[strlen(ssid)] != '\t')
3357 return -1;
3358
3359 while (pos > list && pos[-1] != '\n')
3360 pos--;
3361 dut->infra_network_id = atoi(pos);
3362 snprintf(dut->infra_ssid, sizeof(dut->infra_ssid), "%s", ssid);
3363 return 0;
3364}
3365
3366
Sunil Dutt44595082018-02-12 19:41:45 +05303367#ifdef NL80211_SUPPORT
3368static int sta_config_rsnie(struct sigma_dut *dut, int val)
3369{
3370 struct nl_msg *msg;
3371 int ret;
3372 struct nlattr *params;
3373 int ifindex;
3374
3375 ifindex = if_nametoindex("wlan0");
3376 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
3377 NL80211_CMD_VENDOR)) ||
3378 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
3379 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
3380 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
3381 QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION) ||
3382 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
3383 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE, val)) {
3384 sigma_dut_print(dut, DUT_MSG_ERROR,
3385 "%s: err in adding vendor_cmd and vendor_data",
3386 __func__);
3387 nlmsg_free(msg);
3388 return -1;
3389 }
3390 nla_nest_end(msg, params);
3391
3392 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
3393 if (ret) {
3394 sigma_dut_print(dut, DUT_MSG_ERROR,
3395 "%s: err in send_and_recv_msgs, ret=%d",
3396 __func__, ret);
3397 return ret;
3398 }
3399
3400 return 0;
3401}
3402#endif /* NL80211_SUPPORT */
3403
3404
Jouni Malinenf7222712019-06-13 01:50:21 +03003405static enum sigma_cmd_result cmd_sta_associate(struct sigma_dut *dut,
3406 struct sigma_conn *conn,
3407 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003408{
3409 /* const char *intf = get_param(cmd, "Interface"); */
3410 const char *ssid = get_param(cmd, "ssid");
3411 const char *wps_param = get_param(cmd, "WPS");
3412 const char *bssid = get_param(cmd, "bssid");
Jouni Malinen46a19b62017-06-23 14:31:27 +03003413 const char *chan = get_param(cmd, "channel");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02003414 const char *network_mode = get_param(cmd, "network_mode");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003415 int wps = 0;
Jouni Malinen3c367e82017-06-23 17:01:47 +03003416 char buf[1000], extra[50];
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003417 int e;
3418 enum sigma_cmd_result ret = SUCCESS_SEND_STATUS;
3419 struct wpa_ctrl *ctrl = NULL;
3420 int num_network_not_found = 0;
3421 int num_disconnected = 0;
3422 int tod = -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003423
3424 if (ssid == NULL)
3425 return -1;
3426
Jouni Malinen37d5c692019-08-19 16:56:55 +03003427 dut->server_cert_tod = 0;
3428
Jouni Malinen3c367e82017-06-23 17:01:47 +03003429 if (dut->rsne_override) {
Sunil Dutt44595082018-02-12 19:41:45 +05303430#ifdef NL80211_SUPPORT
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003431 if (get_driver_type(dut) == DRIVER_WCN) {
Sunil Dutt44595082018-02-12 19:41:45 +05303432 sta_config_rsnie(dut, 1);
3433 dut->config_rsnie = 1;
3434 }
3435#endif /* NL80211_SUPPORT */
Jouni Malinen3c367e82017-06-23 17:01:47 +03003436 snprintf(buf, sizeof(buf), "TEST_ASSOC_IE %s",
3437 dut->rsne_override);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003438 if (wpa_command(get_station_ifname(dut), buf) < 0) {
Jouni Malinen3c367e82017-06-23 17:01:47 +03003439 send_resp(dut, conn, SIGMA_ERROR,
3440 "ErrorCode,Failed to set DEV_CONFIGURE_IE RSNE override");
3441 return 0;
3442 }
3443 }
3444
Jouni Malinen68143132017-09-02 02:34:08 +03003445 if (dut->sae_commit_override) {
3446 snprintf(buf, sizeof(buf), "SET sae_commit_override %s",
3447 dut->sae_commit_override);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003448 if (wpa_command(get_station_ifname(dut), buf) < 0) {
Jouni Malinen68143132017-09-02 02:34:08 +03003449 send_resp(dut, conn, SIGMA_ERROR,
3450 "ErrorCode,Failed to set SAE commit override");
3451 return 0;
3452 }
3453 }
Ankita Bajaj1bde7942018-01-09 19:15:01 +05303454#ifdef ANDROID
3455 if (dut->fils_hlp)
3456 process_fils_hlp(dut);
3457#endif /* ANDROID */
Jouni Malinen68143132017-09-02 02:34:08 +03003458
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003459 if (wps_param &&
3460 (strcmp(wps_param, "1") == 0 || strcasecmp(wps_param, "On") == 0))
3461 wps = 1;
3462
3463 if (wps) {
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02003464 if (dut->program == PROGRAM_60GHZ && network_mode &&
3465 strcasecmp(network_mode, "PBSS") == 0 &&
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003466 set_network(get_station_ifname(dut), dut->infra_network_id,
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02003467 "pbss", "1") < 0)
3468 return -2;
3469
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003470 if (dut->wps_method == WFA_CS_WPS_NOT_READY) {
3471 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,WPS "
3472 "parameters not yet set");
3473 return 0;
3474 }
3475 if (dut->wps_method == WFA_CS_WPS_PBC) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003476 if (wpa_command(get_station_ifname(dut), "WPS_PBC") < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003477 return -2;
3478 } else {
3479 snprintf(buf, sizeof(buf), "WPS_PIN any %s",
3480 dut->wps_pin);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003481 if (wpa_command(get_station_ifname(dut), buf) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003482 return -2;
3483 }
3484 } else {
vamsi krishna52e16f92017-08-29 12:37:34 +05303485 if (strcmp(ssid, dut->infra_ssid) == 0) {
3486 sigma_dut_print(dut, DUT_MSG_DEBUG,
3487 "sta_associate for the most recently added network");
3488 } else if (find_network(dut, ssid) < 0) {
3489 sigma_dut_print(dut, DUT_MSG_DEBUG,
3490 "sta_associate for a previously stored network profile");
3491 send_resp(dut, conn, SIGMA_ERROR,
3492 "ErrorCode,Profile not found");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003493 return 0;
3494 }
3495
3496 if (bssid &&
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003497 set_network(get_station_ifname(dut), dut->infra_network_id,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003498 "bssid", bssid) < 0) {
3499 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
3500 "Invalid bssid argument");
3501 return 0;
3502 }
3503
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003504 if (dut->program == PROGRAM_WPA3 &&
3505 dut->sta_associate_wait_connect) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003506 ctrl = open_wpa_mon(get_station_ifname(dut));
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003507 if (!ctrl)
3508 return ERROR_SEND_STATUS;
3509 }
3510
Jouni Malinen46a19b62017-06-23 14:31:27 +03003511 extra[0] = '\0';
3512 if (chan)
3513 snprintf(extra, sizeof(extra), " freq=%u",
Alexei Avshalom Lazar093569f2018-11-13 14:08:17 +02003514 channel_to_freq(dut, atoi(chan)));
Jouni Malinen46a19b62017-06-23 14:31:27 +03003515 snprintf(buf, sizeof(buf), "SELECT_NETWORK %d%s",
3516 dut->infra_network_id, extra);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003517 if (wpa_command(get_station_ifname(dut), buf) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003518 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to select "
3519 "network id %d on %s",
3520 dut->infra_network_id,
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003521 get_station_ifname(dut));
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003522 ret = ERROR_SEND_STATUS;
3523 goto done;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003524 }
3525 }
3526
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003527 if (!ctrl)
3528 return SUCCESS_SEND_STATUS;
3529
3530 /* Wait for connection result to be able to store server certificate
3531 * hash for trust root override testing
3532 * (dev_exec_action,ServerCertTrust). */
3533
3534 for (e = 0; e < 20; e++) {
3535 const char *events[] = {
3536 "CTRL-EVENT-EAP-PEER-CERT",
3537 "CTRL-EVENT-EAP-TLS-CERT-ERROR",
3538 "CTRL-EVENT-DISCONNECTED",
3539 "CTRL-EVENT-CONNECTED",
3540 "CTRL-EVENT-NETWORK-NOT-FOUND",
3541 NULL
3542 };
3543 char buf[1024];
3544 int res;
3545
3546 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
3547 if (res < 0) {
Jouni Malinenf1f16642019-11-15 21:19:04 +02003548 send_resp(dut, conn, SIGMA_COMPLETE,
3549 "Result,Association did not complete");
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003550 ret = STATUS_SENT_ERROR;
3551 break;
3552 }
3553 sigma_dut_print(dut, DUT_MSG_DEBUG, "Connection event: %s",
3554 buf);
3555
3556 if (strstr(buf, "CTRL-EVENT-EAP-PEER-CERT") &&
3557 strstr(buf, " depth=0")) {
3558 char *pos = strstr(buf, " hash=");
3559
3560 if (pos) {
3561 char *end;
3562
Jouni Malinen34b19cb2019-08-16 16:37:17 +03003563 if (strstr(buf, " tod=1"))
3564 tod = 1;
3565 else if (strstr(buf, " tod=2"))
3566 tod = 2;
3567 else
3568 tod = 0;
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003569 sigma_dut_print(dut, DUT_MSG_DEBUG,
3570 "Server certificate TOD policy: %d",
3571 tod);
Jouni Malinen37d5c692019-08-19 16:56:55 +03003572 dut->server_cert_tod = tod;
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003573
3574 pos += 6;
3575 end = strchr(pos, ' ');
3576 if (end)
3577 *end = '\0';
3578 strlcpy(dut->server_cert_hash, pos,
3579 sizeof(dut->server_cert_hash));
3580 sigma_dut_print(dut, DUT_MSG_DEBUG,
3581 "Server certificate hash: %s",
3582 dut->server_cert_hash);
3583 }
3584 }
3585
3586 if (strstr(buf, "CTRL-EVENT-EAP-TLS-CERT-ERROR")) {
3587 send_resp(dut, conn, SIGMA_COMPLETE,
3588 "Result,TLS server certificate validation failed");
3589 ret = STATUS_SENT_ERROR;
3590 break;
3591 }
3592
3593 if (strstr(buf, "CTRL-EVENT-NETWORK-NOT-FOUND")) {
3594 num_network_not_found++;
3595
3596 if (num_network_not_found > 2) {
3597 send_resp(dut, conn, SIGMA_COMPLETE,
3598 "Result,Network not found");
3599 ret = STATUS_SENT_ERROR;
3600 break;
3601 }
3602 }
3603
3604 if (strstr(buf, "CTRL-EVENT-DISCONNECTED")) {
3605 num_disconnected++;
3606
3607 if (num_disconnected > 2) {
3608 send_resp(dut, conn, SIGMA_COMPLETE,
3609 "Result,Connection failed");
3610 ret = STATUS_SENT_ERROR;
3611 break;
3612 }
3613 }
3614
3615 if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
3616 if (tod >= 0) {
3617 sigma_dut_print(dut, DUT_MSG_DEBUG,
3618 "Network profile TOD policy update: %d -> %d",
3619 dut->sta_tod_policy, tod);
3620 dut->sta_tod_policy = tod;
3621 }
3622 break;
3623 }
3624 }
3625done:
3626 if (ctrl) {
3627 wpa_ctrl_detach(ctrl);
3628 wpa_ctrl_close(ctrl);
3629 }
3630 return ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003631}
3632
3633
3634static int run_hs20_osu(struct sigma_dut *dut, const char *params)
3635{
3636 char buf[500], cmd[200];
3637 int res;
3638
3639 /* Use hs20-osu-client file at the current dir, if found; otherwise use
3640 * default path */
3641 res = snprintf(cmd, sizeof(cmd),
3642 "%s -w \"%s\" -r hs20-osu-client.res %s%s -dddKt -f Logs/hs20-osu-client.txt",
3643 file_exists("./hs20-osu-client") ?
3644 "./hs20-osu-client" : "hs20-osu-client",
3645 sigma_wpas_ctrl,
3646 dut->summary_log ? "-s " : "",
3647 dut->summary_log ? dut->summary_log : "");
3648 if (res < 0 || res >= (int) sizeof(cmd))
3649 return -1;
3650
3651 res = snprintf(buf, sizeof(buf), "%s %s", cmd, params);
3652 if (res < 0 || res >= (int) sizeof(buf))
3653 return -1;
3654 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
3655
3656 if (system(buf) != 0) {
3657 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to run: %s", buf);
3658 return -1;
3659 }
3660 sigma_dut_print(dut, DUT_MSG_DEBUG,
3661 "Completed hs20-osu-client operation");
3662
3663 return 0;
3664}
3665
3666
3667static int download_ppsmo(struct sigma_dut *dut,
3668 struct sigma_conn *conn,
3669 const char *intf,
3670 struct sigma_cmd *cmd)
3671{
3672 const char *name, *path, *val;
3673 char url[500], buf[600], fbuf[100];
3674 char *fqdn = NULL;
3675
3676 name = get_param(cmd, "FileName");
3677 path = get_param(cmd, "FilePath");
3678 if (name == NULL || path == NULL)
3679 return -1;
3680
3681 if (strcasecmp(path, "VendorSpecific") == 0) {
3682 snprintf(url, sizeof(url), "PPS/%s", name);
3683 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured PPS MO "
3684 "from the device (%s)", url);
3685 if (!file_exists(url)) {
3686 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
3687 "PPS MO file does not exist");
3688 return 0;
3689 }
3690 snprintf(buf, sizeof(buf), "cp %s pps-tnds.xml", url);
3691 if (system(buf) != 0) {
3692 send_resp(dut, conn, SIGMA_ERROR,
3693 "errorCode,Failed to copy PPS MO");
3694 return 0;
3695 }
3696 } else if (strncasecmp(path, "http:", 5) != 0 &&
3697 strncasecmp(path, "https:", 6) != 0) {
3698 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
3699 "Unsupported FilePath value");
3700 return 0;
3701 } else {
3702 snprintf(url, sizeof(url), "%s/%s", path, name);
3703 sigma_dut_print(dut, DUT_MSG_INFO, "Downloading PPS MO from %s",
3704 url);
3705 snprintf(buf, sizeof(buf), "wget -T 10 -t 3 -O pps-tnds.xml '%s'", url);
3706 remove("pps-tnds.xml");
3707 if (system(buf) != 0) {
3708 send_resp(dut, conn, SIGMA_ERROR,
3709 "errorCode,Failed to download PPS MO");
3710 return 0;
3711 }
3712 }
3713
3714 if (run_hs20_osu(dut, "from_tnds pps-tnds.xml pps.xml") < 0) {
3715 send_resp(dut, conn, SIGMA_ERROR,
3716 "errorCode,Failed to parse downloaded PPSMO");
3717 return 0;
3718 }
3719 unlink("pps-tnds.xml");
3720
3721 val = get_param(cmd, "managementTreeURI");
3722 if (val) {
3723 const char *pos, *end;
3724 sigma_dut_print(dut, DUT_MSG_DEBUG, "managementTreeURI: %s",
3725 val);
3726 if (strncmp(val, "./Wi-Fi/", 8) != 0) {
3727 send_resp(dut, conn, SIGMA_ERROR,
3728 "errorCode,Invalid managementTreeURI prefix");
3729 return 0;
3730 }
3731 pos = val + 8;
3732 end = strchr(pos, '/');
3733 if (end == NULL ||
3734 strcmp(end, "/PerProviderSubscription") != 0) {
3735 send_resp(dut, conn, SIGMA_ERROR,
3736 "errorCode,Invalid managementTreeURI postfix");
3737 return 0;
3738 }
3739 if (end - pos >= (int) sizeof(fbuf)) {
3740 send_resp(dut, conn, SIGMA_ERROR,
3741 "errorCode,Too long FQDN in managementTreeURI");
3742 return 0;
3743 }
3744 memcpy(fbuf, pos, end - pos);
3745 fbuf[end - pos] = '\0';
3746 fqdn = fbuf;
3747 sigma_dut_print(dut, DUT_MSG_INFO,
3748 "FQDN from managementTreeURI: %s", fqdn);
3749 } else if (run_hs20_osu(dut, "get_fqdn pps.xml") == 0) {
3750 FILE *f = fopen("pps-fqdn", "r");
3751 if (f) {
3752 if (fgets(fbuf, sizeof(fbuf), f)) {
3753 fbuf[sizeof(fbuf) - 1] = '\0';
3754 fqdn = fbuf;
3755 sigma_dut_print(dut, DUT_MSG_DEBUG,
3756 "Use FQDN %s", fqdn);
3757 }
3758 fclose(f);
3759 }
3760 }
3761
3762 if (fqdn == NULL) {
3763 send_resp(dut, conn, SIGMA_ERROR,
3764 "errorCode,No FQDN specified");
3765 return 0;
3766 }
3767
3768 mkdir("SP", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
3769 snprintf(buf, sizeof(buf), "SP/%s", fqdn);
3770 mkdir(buf, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
3771
3772 snprintf(buf, sizeof(buf), "SP/%s/pps.xml", fqdn);
3773 if (rename("pps.xml", buf) < 0) {
3774 send_resp(dut, conn, SIGMA_ERROR,
3775 "errorCode,Could not move PPS MO");
3776 return 0;
3777 }
3778
3779 if (strcasecmp(path, "VendorSpecific") == 0) {
3780 snprintf(buf, sizeof(buf), "cp Certs/ca.pem SP/%s/ca.pem",
3781 fqdn);
3782 if (system(buf)) {
3783 send_resp(dut, conn, SIGMA_ERROR,
3784 "errorCode,Failed to copy OSU CA cert");
3785 return 0;
3786 }
3787
3788 snprintf(buf, sizeof(buf),
3789 "cp Certs/aaa-ca.pem SP/%s/aaa-ca.pem",
3790 fqdn);
3791 if (system(buf)) {
3792 send_resp(dut, conn, SIGMA_ERROR,
3793 "errorCode,Failed to copy AAA CA cert");
3794 return 0;
3795 }
3796 } else {
3797 snprintf(buf, sizeof(buf),
3798 "dl_osu_ca SP/%s/pps.xml SP/%s/ca.pem",
3799 fqdn, fqdn);
3800 if (run_hs20_osu(dut, buf) < 0) {
3801 send_resp(dut, conn, SIGMA_ERROR,
3802 "errorCode,Failed to download OSU CA cert");
3803 return 0;
3804 }
3805
3806 snprintf(buf, sizeof(buf),
3807 "dl_aaa_ca SP/%s/pps.xml SP/%s/aaa-ca.pem",
3808 fqdn, fqdn);
3809 if (run_hs20_osu(dut, buf) < 0) {
3810 sigma_dut_print(dut, DUT_MSG_INFO,
3811 "Failed to download AAA CA cert");
3812 }
3813 }
3814
3815 if (file_exists("next-client-cert.pem")) {
3816 snprintf(buf, sizeof(buf), "SP/%s/client-cert.pem", fqdn);
3817 if (rename("next-client-cert.pem", buf) < 0) {
3818 send_resp(dut, conn, SIGMA_ERROR,
3819 "errorCode,Could not move client certificate");
3820 return 0;
3821 }
3822 }
3823
3824 if (file_exists("next-client-key.pem")) {
3825 snprintf(buf, sizeof(buf), "SP/%s/client-key.pem", fqdn);
3826 if (rename("next-client-key.pem", buf) < 0) {
3827 send_resp(dut, conn, SIGMA_ERROR,
3828 "errorCode,Could not move client key");
3829 return 0;
3830 }
3831 }
3832
3833 snprintf(buf, sizeof(buf), "set_pps SP/%s/pps.xml", fqdn);
3834 if (run_hs20_osu(dut, buf) < 0) {
3835 send_resp(dut, conn, SIGMA_ERROR,
3836 "errorCode,Failed to configure credential from "
3837 "PPSMO");
3838 return 0;
3839 }
3840
3841 return 1;
3842}
3843
3844
3845static int download_cert(struct sigma_dut *dut,
3846 struct sigma_conn *conn,
3847 const char *intf,
3848 struct sigma_cmd *cmd)
3849{
3850 const char *name, *path;
3851 char url[500], buf[600];
3852
3853 name = get_param(cmd, "FileName");
3854 path = get_param(cmd, "FilePath");
3855 if (name == NULL || path == NULL)
3856 return -1;
3857
3858 if (strcasecmp(path, "VendorSpecific") == 0) {
3859 snprintf(url, sizeof(url), "Certs/%s-cert.pem", name);
3860 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured client "
3861 "certificate from the device (%s)", url);
3862 if (!file_exists(url)) {
3863 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
3864 "certificate file does not exist");
3865 return 0;
3866 }
3867 snprintf(buf, sizeof(buf), "cp %s next-client-cert.pem", url);
3868 if (system(buf) != 0) {
3869 send_resp(dut, conn, SIGMA_ERROR,
3870 "errorCode,Failed to copy client "
3871 "certificate");
3872 return 0;
3873 }
3874
3875 snprintf(url, sizeof(url), "Certs/%s-key.pem", name);
3876 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured client "
3877 "private key from the device (%s)", url);
3878 if (!file_exists(url)) {
3879 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
3880 "private key file does not exist");
3881 return 0;
3882 }
3883 snprintf(buf, sizeof(buf), "cp %s next-client-key.pem", url);
3884 if (system(buf) != 0) {
3885 send_resp(dut, conn, SIGMA_ERROR,
3886 "errorCode,Failed to copy client key");
3887 return 0;
3888 }
3889 } else if (strncasecmp(path, "http:", 5) != 0 &&
3890 strncasecmp(path, "https:", 6) != 0) {
3891 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
3892 "Unsupported FilePath value");
3893 return 0;
3894 } else {
3895 snprintf(url, sizeof(url), "%s/%s.pem", path, name);
3896 sigma_dut_print(dut, DUT_MSG_INFO, "Downloading client "
3897 "certificate/key from %s", url);
3898 snprintf(buf, sizeof(buf),
3899 "wget -T 10 -t 3 -O next-client-cert.pem '%s'", url);
3900 if (system(buf) != 0) {
3901 send_resp(dut, conn, SIGMA_ERROR,
3902 "errorCode,Failed to download client "
3903 "certificate");
3904 return 0;
3905 }
3906
3907 if (system("cp next-client-cert.pem next-client-key.pem") != 0)
3908 {
3909 send_resp(dut, conn, SIGMA_ERROR,
3910 "errorCode,Failed to copy client key");
3911 return 0;
3912 }
3913 }
3914
3915 return 1;
3916}
3917
3918
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02003919static int cmd_sta_preset_testparameters_60ghz(struct sigma_dut *dut,
3920 struct sigma_conn *conn,
3921 struct sigma_cmd *cmd)
3922{
3923 const char *val;
3924 const char *intf = get_param(cmd, "interface");
3925
3926 if (!intf)
3927 return -1;
3928
3929 val = get_param(cmd, "WscIEFragment");
3930 if (val && strcasecmp(val, "enable") == 0) {
3931 sigma_dut_print(dut, DUT_MSG_DEBUG,
3932 "Enable WSC IE fragmentation");
3933
3934 dut->wsc_fragment = 1;
3935 /* set long attributes to force fragmentation */
3936 if (wpa_command(intf, "SET device_name "
3937 WPS_LONG_DEVICE_NAME) < 0)
3938 return -2;
3939 if (wpa_command(intf, "SET manufacturer "
3940 WPS_LONG_MANUFACTURER) < 0)
3941 return -2;
3942 if (wpa_command(intf, "SET model_name "
3943 WPS_LONG_MODEL_NAME) < 0)
3944 return -2;
3945 if (wpa_command(intf, "SET model_number "
3946 WPS_LONG_MODEL_NUMBER) < 0)
3947 return -2;
3948 if (wpa_command(intf, "SET serial_number "
3949 WPS_LONG_SERIAL_NUMBER) < 0)
3950 return -2;
3951 }
3952
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02003953 val = get_param(cmd, "RSN_IE");
3954 if (val) {
3955 if (strcasecmp(val, "disable") == 0)
3956 dut->force_rsn_ie = FORCE_RSN_IE_REMOVE;
3957 else if (strcasecmp(val, "enable") == 0)
3958 dut->force_rsn_ie = FORCE_RSN_IE_ADD;
3959 }
3960
Alexei Avshalom Lazar744ae8a2019-01-31 17:26:46 +02003961 val = get_param(cmd, "WpsVersion");
3962 if (val)
3963 dut->wps_forced_version = get_wps_forced_version(dut, val);
3964
Alexei Avshalom Lazar2eccf4d2019-01-31 10:03:59 +02003965 val = get_param(cmd, "WscEAPFragment");
3966 if (val && strcasecmp(val, "enable") == 0)
3967 dut->eap_fragment = 1;
3968
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02003969 return 1;
3970}
3971
3972
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003973static int cmd_sta_preset_testparameters_hs2_r2(struct sigma_dut *dut,
3974 struct sigma_conn *conn,
3975 const char *intf,
3976 struct sigma_cmd *cmd)
3977{
3978 const char *val;
3979
3980 val = get_param(cmd, "FileType");
3981 if (val && strcasecmp(val, "PPSMO") == 0)
3982 return download_ppsmo(dut, conn, intf, cmd);
3983 if (val && strcasecmp(val, "CERT") == 0)
3984 return download_cert(dut, conn, intf, cmd);
3985 if (val) {
3986 send_resp(dut, conn, SIGMA_ERROR,
3987 "ErrorCode,Unsupported FileType");
3988 return 0;
3989 }
3990
3991 return 1;
3992}
3993
3994
Ankita Bajaja2cb5672017-10-25 16:08:28 +05303995static int cmd_sta_preset_testparameters_oce(struct sigma_dut *dut,
3996 struct sigma_conn *conn,
3997 const char *intf,
3998 struct sigma_cmd *cmd)
3999{
4000 const char *val;
Ankita Bajaj1bde7942018-01-09 19:15:01 +05304001 char buf[1000];
4002 char text[20];
4003 unsigned char addr[ETH_ALEN];
Ankita Bajaja2cb5672017-10-25 16:08:28 +05304004
4005 val = get_param(cmd, "OCESupport");
4006 if (val && strcasecmp(val, "Disable") == 0) {
4007 if (wpa_command(intf, "SET oce 0") < 0) {
4008 send_resp(dut, conn, SIGMA_ERROR,
4009 "ErrorCode,Failed to disable OCE");
4010 return 0;
4011 }
4012 } else if (val && strcasecmp(val, "Enable") == 0) {
4013 if (wpa_command(intf, "SET oce 1") < 0) {
4014 send_resp(dut, conn, SIGMA_ERROR,
4015 "ErrorCode,Failed to enable OCE");
4016 return 0;
4017 }
4018 }
4019
vamsi krishnaa2799492017-12-05 14:28:01 +05304020 val = get_param(cmd, "FILScap");
4021 if (val && (atoi(val) == 1)) {
4022 if (wpa_command(intf, "SET disable_fils 0") < 0) {
4023 send_resp(dut, conn, SIGMA_ERROR,
4024 "ErrorCode,Failed to enable FILS");
4025 return 0;
4026 }
4027 } else if (val && (atoi(val) == 0)) {
4028 if (wpa_command(intf, "SET disable_fils 1") < 0) {
4029 send_resp(dut, conn, SIGMA_ERROR,
4030 "ErrorCode,Failed to disable FILS");
4031 return 0;
4032 }
4033 }
4034
Ankita Bajaj1bde7942018-01-09 19:15:01 +05304035 val = get_param(cmd, "FILSHLP");
4036 if (val && strcasecmp(val, "Enable") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004037 if (get_wpa_status(get_station_ifname(dut), "address", text,
Ankita Bajaj1bde7942018-01-09 19:15:01 +05304038 sizeof(text)) < 0)
4039 return -2;
4040 hwaddr_aton(text, addr);
4041 snprintf(buf, sizeof(buf),
4042 "FILS_HLP_REQ_ADD ff:ff:ff:ff:ff:ff "
4043 "080045100140000040004011399e00000000ffffffff00440043"
4044 "012cb30001010600fd4f46410000000000000000000000000000"
4045 "000000000000"
4046 "%02x%02x%02x%02x%02x%02x"
4047 "0000000000000000000000000000000000000000000000000000"
4048 "0000000000000000000000000000000000000000000000000000"
4049 "0000000000000000000000000000000000000000000000000000"
4050 "0000000000000000000000000000000000000000000000000000"
4051 "0000000000000000000000000000000000000000000000000000"
4052 "0000000000000000000000000000000000000000000000000000"
4053 "0000000000000000000000000000000000000000000000000000"
4054 "0000000000000000000000000000000000000000638253633501"
4055 "013d0701000af549d29b390205dc3c12616e64726f69642d6468"
4056 "63702d382e302e30370a0103060f1a1c333a3b2b5000ff00",
4057 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
4058 if (wpa_command(intf, buf)) {
4059 send_resp(dut, conn, SIGMA_ERROR,
4060 "ErrorCode,Failed to add HLP");
4061 return 0;
4062 }
4063 dut->fils_hlp = 1;
4064 }
4065
Ankita Bajaja2cb5672017-10-25 16:08:28 +05304066 return 1;
4067}
4068
4069
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004070static void ath_sta_set_noack(struct sigma_dut *dut, const char *intf,
4071 const char *val)
4072{
4073 int counter = 0;
4074 char token[50];
4075 char *result;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05304076 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004077
Peng Xub8fc5cc2017-05-10 17:27:28 -07004078 strlcpy(token, val, sizeof(token));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004079 token[sizeof(token) - 1] = '\0';
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05304080 result = strtok_r(token, ":", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004081 while (result) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004082 if (strcmp(result, "disable") == 0)
4083 run_iwpriv(dut, intf, "noackpolicy %d 1 0", counter);
4084 else
4085 run_iwpriv(dut, intf, "noackpolicy %d 1 1", counter);
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05304086 result = strtok_r(NULL, ":", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004087 counter++;
4088 }
4089}
4090
4091
4092static void ath_sta_set_rts(struct sigma_dut *dut, const char *intf,
4093 const char *val)
4094{
4095 char buf[100];
4096
4097 snprintf(buf, sizeof(buf), "iwconfig %s rts %s", intf, val);
4098 if (system(buf) != 0) {
4099 sigma_dut_print(dut, DUT_MSG_ERROR, "iwconfig RTS failed");
4100 }
4101}
4102
4103
4104static void ath_sta_set_wmm(struct sigma_dut *dut, const char *intf,
4105 const char *val)
4106{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004107 if (strcasecmp(val, "off") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004108 run_iwpriv(dut, intf, "wmm 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004109 }
4110}
4111
4112
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08004113static int wcn_sta_set_wmm(struct sigma_dut *dut, const char *intf,
4114 const char *val)
4115{
4116#ifdef NL80211_SUPPORT
4117 struct nl_msg *msg;
4118 int ret = 0;
4119 struct nlattr *params;
4120 int ifindex;
4121 int wmmenable = 1;
4122
4123 if (val &&
4124 (strcasecmp(val, "off") == 0 || strcmp(val, "0") == 0))
4125 wmmenable = 0;
4126
4127 ifindex = if_nametoindex(intf);
4128 if (ifindex == 0) {
4129 sigma_dut_print(dut, DUT_MSG_ERROR,
4130 "%s: Index for interface %s failed",
4131 __func__, intf);
4132 return -1;
4133 }
4134
4135 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4136 NL80211_CMD_VENDOR)) ||
4137 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4138 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4139 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4140 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4141 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4142 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WMM_ENABLE,
4143 wmmenable)) {
4144 sigma_dut_print(dut, DUT_MSG_ERROR,
4145 "%s: err in adding vendor_cmd and vendor_data",
4146 __func__);
4147 nlmsg_free(msg);
4148 return -1;
4149 }
4150 nla_nest_end(msg, params);
4151
4152 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4153 if (ret) {
4154 sigma_dut_print(dut, DUT_MSG_ERROR,
4155 "%s: err in send_and_recv_msgs, ret=%d",
4156 __func__, ret);
4157 }
4158 return ret;
4159#else /* NL80211_SUPPORT */
4160 sigma_dut_print(dut, DUT_MSG_ERROR,
4161 "WMM cannot be changed without NL80211_SUPPORT defined");
4162 return -1;
4163#endif /* NL80211_SUPPORT */
4164}
4165
4166
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004167static void ath_sta_set_sgi(struct sigma_dut *dut, const char *intf,
4168 const char *val)
4169{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004170 int sgi20;
4171
4172 sgi20 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
4173
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004174 run_iwpriv(dut, intf, "shortgi %d", sgi20);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004175}
4176
4177
4178static void ath_sta_set_11nrates(struct sigma_dut *dut, const char *intf,
4179 const char *val)
4180{
Pradeep Reddy POTTETI67376b72016-10-25 20:08:17 +05304181 int rate_code, v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004182
4183 /* Disable Tx Beam forming when using a fixed rate */
4184 ath_disable_txbf(dut, intf);
4185
Pradeep Reddy POTTETI67376b72016-10-25 20:08:17 +05304186 v = atoi(val);
4187 if (v < 0 || v > 32) {
4188 sigma_dut_print(dut, DUT_MSG_ERROR,
4189 "Invalid Fixed MCS rate: %d", v);
4190 return;
4191 }
4192 rate_code = 0x80 + v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004193
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004194 run_iwpriv(dut, intf, "set11NRates 0x%x", rate_code);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004195
4196 /* Channel width gets messed up, fix this */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004197 run_iwpriv(dut, intf, "chwidth %d", dut->chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004198}
4199
4200
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08004201static void iwpriv_sta_set_amsdu(struct sigma_dut *dut, const char *intf,
4202 const char *val)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004203{
4204 char buf[60];
4205
4206 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)
4207 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 2", intf);
4208 else
4209 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 1", intf);
4210
4211 if (system(buf) != 0)
4212 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv amsdu failed");
4213}
4214
4215
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07004216static int iwpriv_sta_set_ampdu(struct sigma_dut *dut, const char *intf,
4217 int ampdu)
4218{
4219 char buf[60];
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08004220 int maxaggregation = 63;
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07004221
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08004222 if (ampdu)
4223 ampdu = maxaggregation;
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07004224 snprintf(buf, sizeof(buf), "iwpriv %s ampdu %d", intf, ampdu);
4225 if (system(buf) != 0) {
4226 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv ampdu failed");
4227 return -1;
4228 }
4229
4230 return 0;
4231}
4232
4233
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004234static void ath_sta_set_stbc(struct sigma_dut *dut, const char *intf,
4235 const char *val)
4236{
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004237 run_iwpriv(dut, intf, "tx_stbc %s", val);
4238 run_iwpriv(dut, intf, "rx_stbc %s", val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004239}
4240
4241
4242static int wcn_sta_set_cts_width(struct sigma_dut *dut, const char *intf,
4243 const char *val)
4244{
4245 char buf[60];
4246
Peng Xucc317ed2017-05-18 16:44:37 -07004247 if (strcmp(val, "160") == 0) {
4248 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 5", intf);
4249 } else if (strcmp(val, "80") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004250 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 3", intf);
4251 } else if (strcmp(val, "40") == 0) {
4252 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 2", intf);
4253 } else if (strcmp(val, "20") == 0) {
4254 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 1", intf);
4255 } else if (strcasecmp(val, "Auto") == 0) {
4256 buf[0] = '\0';
4257 } else {
4258 sigma_dut_print(dut, DUT_MSG_ERROR,
4259 "WIDTH/CTS_WIDTH value not supported");
4260 return -1;
4261 }
4262
4263 if (buf[0] != '\0' && system(buf) != 0) {
4264 sigma_dut_print(dut, DUT_MSG_ERROR,
4265 "Failed to set WIDTH/CTS_WIDTH");
4266 return -1;
4267 }
4268
4269 return 0;
4270}
4271
4272
4273int ath_set_width(struct sigma_dut *dut, struct sigma_conn *conn,
4274 const char *intf, const char *val)
4275{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004276 if (strcasecmp(val, "Auto") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004277 run_iwpriv(dut, intf, "chwidth 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004278 dut->chwidth = 0;
4279 } else if (strcasecmp(val, "20") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004280 run_iwpriv(dut, intf, "chwidth 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004281 dut->chwidth = 0;
4282 } else if (strcasecmp(val, "40") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004283 run_iwpriv(dut, intf, "chwidth 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004284 dut->chwidth = 1;
4285 } else if (strcasecmp(val, "80") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004286 run_iwpriv(dut, intf, "chwidth 2");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004287 dut->chwidth = 2;
4288 } else if (strcasecmp(val, "160") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004289 run_iwpriv(dut, intf, "chwidth 3");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004290 dut->chwidth = 3;
4291 } else {
4292 send_resp(dut, conn, SIGMA_ERROR,
4293 "ErrorCode,WIDTH not supported");
4294 return -1;
4295 }
4296
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004297 return 0;
4298}
4299
4300
4301static int wcn_sta_set_sp_stream(struct sigma_dut *dut, const char *intf,
4302 const char *val)
4303{
4304 char buf[60];
Arif Hussainac6c5112018-05-25 17:34:00 -07004305 int sta_nss;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004306
Amarnath Hullur Subramanyamd5374fa2018-02-25 19:00:24 -08004307 if (strcmp(val, "1SS") == 0 || strcmp(val, "1") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004308 snprintf(buf, sizeof(buf), "iwpriv %s nss 1", intf);
Arif Hussainac6c5112018-05-25 17:34:00 -07004309 sta_nss = 1;
Amarnath Hullur Subramanyamd5374fa2018-02-25 19:00:24 -08004310 } else if (strcmp(val, "2SS") == 0 || strcmp(val, "2") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004311 snprintf(buf, sizeof(buf), "iwpriv %s nss 2", intf);
Arif Hussainac6c5112018-05-25 17:34:00 -07004312 sta_nss = 2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004313 } else {
4314 sigma_dut_print(dut, DUT_MSG_ERROR,
4315 "SP_STREAM value not supported");
4316 return -1;
4317 }
4318
4319 if (system(buf) != 0) {
4320 sigma_dut_print(dut, DUT_MSG_ERROR,
4321 "Failed to set SP_STREAM");
4322 return -1;
4323 }
4324
Arif Hussainac6c5112018-05-25 17:34:00 -07004325 dut->sta_nss = sta_nss;
4326
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004327 return 0;
4328}
4329
4330
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05304331static void wcn_sta_set_stbc(struct sigma_dut *dut, const char *intf,
4332 const char *val)
4333{
4334 char buf[60];
4335
4336 snprintf(buf, sizeof(buf), "iwpriv %s tx_stbc %s", intf, val);
4337 if (system(buf) != 0)
4338 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv tx_stbc failed");
4339
4340 snprintf(buf, sizeof(buf), "iwpriv %s rx_stbc %s", intf, val);
4341 if (system(buf) != 0)
4342 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv rx_stbc failed");
4343}
4344
4345
Ashwini Patil68d02cd2017-01-10 15:39:16 +05304346static int mbo_set_cellular_data_capa(struct sigma_dut *dut,
4347 struct sigma_conn *conn,
4348 const char *intf, int capa)
4349{
4350 char buf[32];
4351
4352 if (capa > 0 && capa < 4) {
4353 snprintf(buf, sizeof(buf), "SET mbo_cell_capa %d", capa);
4354 if (wpa_command(intf, buf) < 0) {
4355 send_resp(dut, conn, SIGMA_ERROR,
4356 "ErrorCode, Failed to set cellular data capability");
4357 return 0;
4358 }
4359 return 1;
4360 }
4361
4362 sigma_dut_print(dut, DUT_MSG_ERROR,
4363 "Invalid Cellular data capability: %d", capa);
4364 send_resp(dut, conn, SIGMA_INVALID,
4365 "ErrorCode,Invalid cellular data capability");
4366 return 0;
4367}
4368
4369
Ashwini Patil9183fdb2017-04-13 16:58:25 +05304370static int mbo_set_roaming(struct sigma_dut *dut, struct sigma_conn *conn,
4371 const char *intf, const char *val)
4372{
4373 if (strcasecmp(val, "Disable") == 0) {
4374 if (wpa_command(intf, "SET roaming 0") < 0) {
4375 send_resp(dut, conn, SIGMA_ERROR,
4376 "ErrorCode,Failed to disable roaming");
4377 return 0;
4378 }
4379 return 1;
4380 }
4381
4382 if (strcasecmp(val, "Enable") == 0) {
4383 if (wpa_command(intf, "SET roaming 1") < 0) {
4384 send_resp(dut, conn, SIGMA_ERROR,
4385 "ErrorCode,Failed to enable roaming");
4386 return 0;
4387 }
4388 return 1;
4389 }
4390
4391 sigma_dut_print(dut, DUT_MSG_ERROR,
4392 "Invalid value provided for roaming: %s", val);
4393 send_resp(dut, conn, SIGMA_INVALID,
4394 "ErrorCode,Unknown value provided for Roaming");
4395 return 0;
4396}
4397
4398
Ashwini Patila75de5a2017-04-13 16:35:05 +05304399static int mbo_set_assoc_disallow(struct sigma_dut *dut,
4400 struct sigma_conn *conn,
4401 const char *intf, const char *val)
4402{
4403 if (strcasecmp(val, "Disable") == 0) {
4404 if (wpa_command(intf, "SET ignore_assoc_disallow 1") < 0) {
4405 send_resp(dut, conn, SIGMA_ERROR,
4406 "ErrorCode,Failed to disable Assoc_disallow");
4407 return 0;
4408 }
4409 return 1;
4410 }
4411
4412 if (strcasecmp(val, "Enable") == 0) {
4413 if (wpa_command(intf, "SET ignore_assoc_disallow 0") < 0) {
4414 send_resp(dut, conn, SIGMA_ERROR,
4415 "ErrorCode,Failed to enable Assoc_disallow");
4416 return 0;
4417 }
4418 return 1;
4419 }
4420
4421 sigma_dut_print(dut, DUT_MSG_ERROR,
4422 "Invalid value provided for Assoc_disallow: %s", val);
4423 send_resp(dut, conn, SIGMA_INVALID,
4424 "ErrorCode,Unknown value provided for Assoc_disallow");
4425 return 0;
4426}
4427
4428
Ashwini Patilc63161e2017-04-13 16:30:23 +05304429static int mbo_set_bss_trans_req(struct sigma_dut *dut, struct sigma_conn *conn,
4430 const char *intf, const char *val)
4431{
4432 if (strcasecmp(val, "Reject") == 0) {
4433 if (wpa_command(intf, "SET reject_btm_req_reason 1") < 0) {
4434 send_resp(dut, conn, SIGMA_ERROR,
4435 "ErrorCode,Failed to Reject BTM Request");
4436 return 0;
4437 }
4438 return 1;
4439 }
4440
4441 if (strcasecmp(val, "Accept") == 0) {
4442 if (wpa_command(intf, "SET reject_btm_req_reason 0") < 0) {
4443 send_resp(dut, conn, SIGMA_ERROR,
4444 "ErrorCode,Failed to Accept BTM Request");
4445 return 0;
4446 }
4447 return 1;
4448 }
4449
4450 sigma_dut_print(dut, DUT_MSG_ERROR,
4451 "Invalid value provided for BSS_Transition: %s", val);
4452 send_resp(dut, conn, SIGMA_INVALID,
4453 "ErrorCode,Unknown value provided for BSS_Transition");
4454 return 0;
4455}
4456
4457
Ashwini Patil00402582017-04-13 12:29:39 +05304458static int mbo_set_non_pref_ch_list(struct sigma_dut *dut,
4459 struct sigma_conn *conn,
4460 const char *intf,
4461 struct sigma_cmd *cmd)
4462{
4463 const char *ch, *pref, *op_class, *reason;
4464 char buf[120];
4465 int len, ret;
4466
4467 pref = get_param(cmd, "Ch_Pref");
4468 if (!pref)
4469 return 1;
4470
4471 if (strcasecmp(pref, "clear") == 0) {
4472 free(dut->non_pref_ch_list);
4473 dut->non_pref_ch_list = NULL;
4474 } else {
4475 op_class = get_param(cmd, "Ch_Op_Class");
4476 if (!op_class) {
4477 send_resp(dut, conn, SIGMA_INVALID,
4478 "ErrorCode,Ch_Op_Class not provided");
4479 return 0;
4480 }
4481
4482 ch = get_param(cmd, "Ch_Pref_Num");
4483 if (!ch) {
4484 send_resp(dut, conn, SIGMA_INVALID,
4485 "ErrorCode,Ch_Pref_Num not provided");
4486 return 0;
4487 }
4488
4489 reason = get_param(cmd, "Ch_Reason_Code");
4490 if (!reason) {
4491 send_resp(dut, conn, SIGMA_INVALID,
4492 "ErrorCode,Ch_Reason_Code not provided");
4493 return 0;
4494 }
4495
4496 if (!dut->non_pref_ch_list) {
4497 dut->non_pref_ch_list =
4498 calloc(1, NON_PREF_CH_LIST_SIZE);
4499 if (!dut->non_pref_ch_list) {
4500 send_resp(dut, conn, SIGMA_ERROR,
4501 "ErrorCode,Failed to allocate memory for non_pref_ch_list");
4502 return 0;
4503 }
4504 }
4505 len = strlen(dut->non_pref_ch_list);
4506 ret = snprintf(dut->non_pref_ch_list + len,
4507 NON_PREF_CH_LIST_SIZE - len,
4508 " %s:%s:%s:%s", op_class, ch, pref, reason);
4509 if (ret > 0 && ret < NON_PREF_CH_LIST_SIZE - len) {
4510 sigma_dut_print(dut, DUT_MSG_DEBUG, "non_pref_list: %s",
4511 dut->non_pref_ch_list);
4512 } else {
4513 sigma_dut_print(dut, DUT_MSG_ERROR,
4514 "snprintf failed for non_pref_list, ret = %d",
4515 ret);
4516 send_resp(dut, conn, SIGMA_ERROR,
4517 "ErrorCode,snprintf failed");
4518 free(dut->non_pref_ch_list);
4519 dut->non_pref_ch_list = NULL;
4520 return 0;
4521 }
4522 }
4523
4524 ret = snprintf(buf, sizeof(buf), "SET non_pref_chan%s",
4525 dut->non_pref_ch_list ? dut->non_pref_ch_list : " ");
4526 if (ret < 0 || ret >= (int) sizeof(buf)) {
4527 sigma_dut_print(dut, DUT_MSG_DEBUG,
4528 "snprintf failed for set non_pref_chan, ret: %d",
4529 ret);
4530 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,snprint failed");
4531 return 0;
4532 }
4533
4534 if (wpa_command(intf, buf) < 0) {
4535 send_resp(dut, conn, SIGMA_ERROR,
4536 "ErrorCode,Failed to set non-preferred channel list");
4537 return 0;
4538 }
4539
4540 return 1;
4541}
4542
4543
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08004544#ifdef NL80211_SUPPORT
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08004545
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08004546static int sta_set_he_htc_supp(struct sigma_dut *dut, const char *intf,
4547 uint8_t cfg)
4548{
4549 struct nl_msg *msg;
4550 int ret = 0;
4551 struct nlattr *params;
4552 int ifindex;
4553
4554 ifindex = if_nametoindex(intf);
4555 if (ifindex == 0) {
4556 sigma_dut_print(dut, DUT_MSG_ERROR,
4557 "%s: Index for interface %s failed",
4558 __func__, intf);
4559 return -1;
4560 }
4561
4562 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4563 NL80211_CMD_VENDOR)) ||
4564 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4565 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4566 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4567 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4568 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4569 nla_put_u8(msg,
4570 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_HTC_HE_SUPP,
4571 cfg)) {
4572 sigma_dut_print(dut, DUT_MSG_ERROR,
4573 "%s: err in adding vendor_cmd and vendor_data",
4574 __func__);
4575 nlmsg_free(msg);
4576 return -1;
4577 }
4578 nla_nest_end(msg, params);
4579
4580 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4581 if (ret) {
4582 sigma_dut_print(dut, DUT_MSG_ERROR,
4583 "%s: err in send_and_recv_msgs, ret=%d",
4584 __func__, ret);
4585 }
4586 return ret;
4587}
4588
4589
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08004590static int sta_set_he_fragmentation(struct sigma_dut *dut, const char *intf,
4591 enum he_fragmentation_val frag)
4592{
4593 struct nl_msg *msg;
4594 int ret = 0;
4595 struct nlattr *params;
4596 int ifindex;
4597
4598 ifindex = if_nametoindex(intf);
4599 if (ifindex == 0) {
4600 sigma_dut_print(dut, DUT_MSG_ERROR,
4601 "%s: Index for interface %s failed",
4602 __func__, intf);
4603 return -1;
4604 }
4605
4606 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4607 NL80211_CMD_VENDOR)) ||
4608 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4609 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4610 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4611 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4612 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4613 nla_put_u8(msg,
4614 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_FRAGMENTATION,
4615 frag)) {
4616 sigma_dut_print(dut, DUT_MSG_ERROR,
4617 "%s: err in adding vendor_cmd and vendor_data",
4618 __func__);
4619 nlmsg_free(msg);
4620 return -1;
4621 }
4622 nla_nest_end(msg, params);
4623
4624 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4625 if (ret) {
4626 sigma_dut_print(dut, DUT_MSG_ERROR,
4627 "%s: err in send_and_recv_msgs, ret=%d",
4628 __func__, ret);
4629 }
4630 return ret;
4631}
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08004632
4633
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -08004634int wcn_set_he_ltf(struct sigma_dut *dut, const char *intf,
4635 enum qca_wlan_he_ltf_cfg ltf)
Subhani Shaik8e7a3052018-04-24 14:03:00 -07004636{
4637 struct nl_msg *msg;
4638 int ret = 0;
4639 struct nlattr *params;
4640 int ifindex;
4641
4642 ifindex = if_nametoindex(intf);
4643 if (ifindex == 0) {
4644 sigma_dut_print(dut, DUT_MSG_ERROR,
4645 "%s: Index for interface %s failed",
4646 __func__, intf);
4647 return -1;
4648 }
4649
4650 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4651 NL80211_CMD_VENDOR)) ||
4652 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4653 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4654 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4655 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4656 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4657 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_LTF,
4658 ltf)) {
4659 sigma_dut_print(dut, DUT_MSG_ERROR,
4660 "%s: err in adding vendor_cmd and vendor_data",
4661 __func__);
4662 nlmsg_free(msg);
4663 return -1;
4664 }
4665 nla_nest_end(msg, params);
4666
4667 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4668 if (ret) {
4669 sigma_dut_print(dut, DUT_MSG_ERROR,
4670 "%s: err in send_and_recv_msgs, ret=%d",
4671 __func__, ret);
4672 }
4673 return ret;
4674}
4675
4676
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08004677static int nlvendor_sta_set_noack(struct sigma_dut *dut, const char *intf,
4678 int noack, enum qca_wlan_ac_type ac)
4679{
4680 struct nl_msg *msg;
4681 int ret = 0;
4682 struct nlattr *params;
4683 int ifindex;
4684
4685 ifindex = if_nametoindex(intf);
4686 if (ifindex == 0) {
4687 sigma_dut_print(dut, DUT_MSG_ERROR,
4688 "%s: Index for interface %s failed",
4689 __func__, intf);
4690 return -1;
4691 }
4692
4693 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4694 NL80211_CMD_VENDOR)) ||
4695 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4696 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4697 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4698 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4699 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4700 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_NO_ACK,
4701 noack) ||
4702 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_NO_ACK_AC,
4703 ac)) {
4704 sigma_dut_print(dut, DUT_MSG_ERROR,
4705 "%s: err in adding vendor_cmd and vendor_data",
4706 __func__);
4707 nlmsg_free(msg);
4708 return -1;
4709 }
4710 nla_nest_end(msg, params);
4711
4712 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4713 if (ret) {
4714 sigma_dut_print(dut, DUT_MSG_ERROR,
4715 "%s: err in send_and_recv_msgs, ret=%d",
4716 __func__, ret);
4717 }
4718 return ret;
4719}
4720
4721
4722static void wcn_sta_set_noack(struct sigma_dut *dut, const char *intf,
4723 const char *val)
4724{
4725 int noack, ret;
4726 char token[100];
4727 char *result;
4728 char *saveptr;
4729 enum qca_wlan_ac_type ac = QCA_WLAN_AC_BE;
4730
4731 strlcpy(token, val, sizeof(token));
4732 token[sizeof(token) - 1] = '\0';
4733 result = strtok_r(token, ":", &saveptr);
4734 while (result) {
4735 noack = strcasecmp(result, "Disable") != 0;
4736 ret = nlvendor_sta_set_noack(dut, intf, noack, ac);
4737 if (ret) {
4738 sigma_dut_print(dut, DUT_MSG_ERROR,
4739 "nlvendor_sta_set_noack failed for ac:%d, ret:%d",
4740 ac, ret);
4741 }
4742 result = strtok_r(NULL, ":", &saveptr);
4743 ac++;
4744 }
4745}
4746
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08004747#endif /* NL80211_SUPPORT */
4748
4749
Jouni Malinenf7222712019-06-13 01:50:21 +03004750static enum sigma_cmd_result
4751cmd_sta_preset_testparameters(struct sigma_dut *dut, struct sigma_conn *conn,
4752 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004753{
4754 const char *intf = get_param(cmd, "Interface");
4755 const char *val;
4756
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03004757 val = get_param(cmd, "FT_DS");
4758 if (val) {
4759 if (strcasecmp(val, "Enable") == 0) {
4760 dut->sta_ft_ds = 1;
4761 } else if (strcasecmp(val, "Disable") == 0) {
4762 dut->sta_ft_ds = 0;
4763 } else {
4764 send_resp(dut, conn, SIGMA_ERROR,
4765 "errorCode,Unsupported value for FT_DS");
4766 return STATUS_SENT_ERROR;
4767 }
4768 }
4769
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004770 val = get_param(cmd, "Program");
Jouni Malinen1f6ae642018-06-07 23:56:13 +03004771 if (val && (strcasecmp(val, "HS2-R2") == 0 ||
4772 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004773 return cmd_sta_preset_testparameters_hs2_r2(dut, conn, intf,
4774 cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004775
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07004776 if (val && strcasecmp(val, "LOC") == 0)
4777 return loc_cmd_sta_preset_testparameters(dut, conn, cmd);
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02004778 if (val && strcasecmp(val, "60GHZ") == 0) {
4779 val = get_param(cmd, "WPS");
4780 if (val && strcasecmp(val, "disable") == 0) {
4781 dut->wps_disable = 1;
4782 sigma_dut_print(dut, DUT_MSG_INFO, "WPS disabled");
4783 } else {
4784 /* wps_disable can have other value from the previous
4785 * test, so make sure it has the correct value.
4786 */
4787 dut->wps_disable = 0;
4788 }
4789
4790 val = get_param(cmd, "P2P");
4791 if (val && strcasecmp(val, "disable") == 0)
4792 sigma_dut_print(dut, DUT_MSG_INFO, "P2P disabled");
4793 }
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07004794
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02004795 if (dut->program == PROGRAM_WPS && dut->band == WPS_BAND_60G)
4796 return cmd_sta_preset_testparameters_60ghz(dut, conn, cmd);
4797
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004798#ifdef ANDROID_NAN
4799 if (val && strcasecmp(val, "NAN") == 0)
4800 return nan_cmd_sta_preset_testparameters(dut, conn, cmd);
4801#endif /* ANDROID_NAN */
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07004802#ifdef MIRACAST
4803 if (val && (strcasecmp(val, "WFD") == 0 ||
4804 strcasecmp(val, "DisplayR2") == 0))
4805 return miracast_preset_testparameters(dut, conn, cmd);
4806#endif /* MIRACAST */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004807
Ashwini Patil68d02cd2017-01-10 15:39:16 +05304808 if (val && strcasecmp(val, "MBO") == 0) {
4809 val = get_param(cmd, "Cellular_Data_Cap");
4810 if (val &&
4811 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
4812 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +05304813
4814 val = get_param(cmd, "Ch_Pref");
4815 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
4816 return 0;
4817
Ashwini Patilc63161e2017-04-13 16:30:23 +05304818 val = get_param(cmd, "BSS_Transition");
4819 if (val && mbo_set_bss_trans_req(dut, conn, intf, val) == 0)
4820 return 0;
4821
Ashwini Patila75de5a2017-04-13 16:35:05 +05304822 val = get_param(cmd, "Assoc_Disallow");
4823 if (val && mbo_set_assoc_disallow(dut, conn, intf, val) == 0)
4824 return 0;
4825
Ashwini Patil9183fdb2017-04-13 16:58:25 +05304826 val = get_param(cmd, "Roaming");
4827 if (val && mbo_set_roaming(dut, conn, intf, val) == 0)
4828 return 0;
4829
Ashwini Patil68d02cd2017-01-10 15:39:16 +05304830 return 1;
4831 }
4832
Ankita Bajaja2cb5672017-10-25 16:08:28 +05304833 if (val && strcasecmp(val, "OCE") == 0)
4834 return cmd_sta_preset_testparameters_oce(dut, conn, intf, cmd);
4835
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004836#if 0
4837 val = get_param(cmd, "Supplicant");
4838 if (val && strcasecmp(val, "Default") != 0) {
4839 send_resp(dut, conn, SIGMA_ERROR,
4840 "ErrorCode,Only default(Vendor) supplicant "
4841 "supported");
4842 return 0;
4843 }
4844#endif
4845
4846 val = get_param(cmd, "RTS");
4847 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004848 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004849 case DRIVER_ATHEROS:
4850 ath_sta_set_rts(dut, intf, val);
4851 break;
4852 default:
4853#if 0
4854 send_resp(dut, conn, SIGMA_ERROR,
4855 "ErrorCode,Setting RTS not supported");
4856 return 0;
4857#else
4858 sigma_dut_print(dut, DUT_MSG_DEBUG,
4859 "Setting RTS not supported");
4860 break;
4861#endif
4862 }
4863 }
4864
4865#if 0
4866 val = get_param(cmd, "FRGMNT");
4867 if (val) {
4868 /* TODO */
4869 send_resp(dut, conn, SIGMA_ERROR,
4870 "ErrorCode,Setting FRGMNT not supported");
4871 return 0;
4872 }
4873#endif
4874
4875#if 0
4876 val = get_param(cmd, "Preamble");
4877 if (val) {
4878 /* TODO: Long/Short */
4879 send_resp(dut, conn, SIGMA_ERROR,
4880 "ErrorCode,Setting Preamble not supported");
4881 return 0;
4882 }
4883#endif
4884
4885 val = get_param(cmd, "Mode");
4886 if (val) {
4887 if (strcmp(val, "11b") == 0 ||
4888 strcmp(val, "11g") == 0 ||
4889 strcmp(val, "11a") == 0 ||
4890 strcmp(val, "11n") == 0 ||
4891 strcmp(val, "11ng") == 0 ||
4892 strcmp(val, "11nl") == 0 ||
4893 strcmp(val, "11nl(nabg)") == 0 ||
4894 strcmp(val, "AC") == 0 ||
4895 strcmp(val, "11AC") == 0 ||
4896 strcmp(val, "11ac") == 0 ||
4897 strcmp(val, "11na") == 0 ||
Amarnath Hullur Subramanyamb0db2712018-01-30 19:40:35 -08004898 strcmp(val, "11an") == 0 ||
4899 strcmp(val, "11ax") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004900 /* STA supports all modes by default */
4901 } else {
4902 send_resp(dut, conn, SIGMA_ERROR,
4903 "ErrorCode,Setting Mode not supported");
4904 return 0;
4905 }
Amarnath Hullur Subramanyam97d0e532018-01-31 02:53:02 -08004906
4907 /* Change the mode only in case of testbed for HE program
4908 * and for 11a and 11g modes only. */
4909 if (dut->program == PROGRAM_HE &&
4910 dut->device_type == STA_testbed) {
4911 int phymode;
4912 char buf[60];
4913
4914 if (strcmp(val, "11a") == 0) {
Amarnath Hullur Subramanyam94dfaf02018-03-02 19:26:57 -08004915 phymode = 1; /* IEEE80211_MODE_11A */
4916 } else if (strcmp(val, "11g") == 0) {
4917 phymode = 3; /* IEEE80211_MODE_11G */
4918 } else if (strcmp(val, "11b") == 0) {
4919 phymode = 2; /* IEEE80211_MODE_11B */
4920 } else if (strcmp(val, "11n") == 0 ||
4921 strcmp(val, "11nl") == 0 ||
4922 strcmp(val, "11nl(nabg)") == 0) {
4923 phymode = 22; /* IEEE80211_MODE_11AGN */
4924 } else if (strcmp(val, "11ng") == 0) {
4925 phymode = 13; /* IEEE80211_MODE_11NG_HT40 */
4926 } else if (strcmp(val, "AC") == 0 ||
4927 strcasecmp(val, "11AC") == 0) {
4928 phymode = 19; /* IEEE80211_MODE_11AC_VHT80 */
4929 } else if (strcmp(val, "11na") == 0 ||
4930 strcasecmp(val, "11an") == 0) {
4931 phymode = 14; /* IEEE80211_MODE_11NA_HT40 */
4932 } else if (strcmp(val, "11ax") == 0) {
4933 phymode = 0; /* IEEE80211_MODE_AUTO */
Amarnath Hullur Subramanyam97d0e532018-01-31 02:53:02 -08004934 } else {
4935 sigma_dut_print(dut, DUT_MSG_DEBUG,
4936 "Ignoring mode change for mode: %s",
4937 val);
4938 phymode = -1;
4939 }
4940 if (phymode != -1) {
4941 snprintf(buf, sizeof(buf),
4942 "iwpriv %s setphymode %d",
4943 intf, phymode);
4944 if (system(buf) != 0) {
4945 sigma_dut_print(dut, DUT_MSG_ERROR,
4946 "iwpriv setting of phymode failed");
4947 }
4948 }
4949 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004950 }
4951
4952 val = get_param(cmd, "wmm");
4953 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004954 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004955 case DRIVER_ATHEROS:
4956 ath_sta_set_wmm(dut, intf, val);
4957 break;
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08004958 case DRIVER_WCN:
4959 wcn_sta_set_wmm(dut, intf, val);
4960 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004961 default:
4962 sigma_dut_print(dut, DUT_MSG_DEBUG,
4963 "Setting wmm not supported");
4964 break;
4965 }
4966 }
4967
4968 val = get_param(cmd, "Powersave");
4969 if (val) {
4970 if (strcmp(val, "0") == 0 || strcasecmp(val, "off") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004971 if (get_driver_type(dut) == DRIVER_WCN) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +05304972 if (set_power_save_wcn(dut, intf, 2) < 0)
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08004973 return 0;
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08004974 }
4975
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004976 if (wpa_command(get_station_ifname(dut),
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004977 "P2P_SET ps 0") < 0)
4978 return -2;
4979 /* Make sure test modes are disabled */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004980 wpa_command(get_station_ifname(dut), "P2P_SET ps 98");
4981 wpa_command(get_station_ifname(dut), "P2P_SET ps 96");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004982 } else if (strcmp(val, "1") == 0 ||
4983 strcasecmp(val, "PSPoll") == 0 ||
4984 strcasecmp(val, "on") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004985 if (get_driver_type(dut) == DRIVER_WCN) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +05304986 if (set_power_save_wcn(dut, intf, 1) < 0)
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08004987 return 0;
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08004988 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004989 /* Disable default power save mode */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004990 wpa_command(get_station_ifname(dut), "P2P_SET ps 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004991 /* Enable PS-Poll test mode */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004992 if (wpa_command(get_station_ifname(dut),
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004993 "P2P_SET ps 97") < 0 ||
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004994 wpa_command(get_station_ifname(dut),
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004995 "P2P_SET ps 99") < 0)
4996 return -2;
4997 } else if (strcmp(val, "2") == 0 ||
4998 strcasecmp(val, "Fast") == 0) {
4999 /* TODO */
5000 send_resp(dut, conn, SIGMA_ERROR,
5001 "ErrorCode,Powersave=Fast not supported");
5002 return 0;
5003 } else if (strcmp(val, "3") == 0 ||
5004 strcasecmp(val, "PSNonPoll") == 0) {
5005 /* Make sure test modes are disabled */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005006 wpa_command(get_station_ifname(dut), "P2P_SET ps 98");
5007 wpa_command(get_station_ifname(dut), "P2P_SET ps 96");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005008
5009 /* Enable default power save mode */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005010 if (wpa_command(get_station_ifname(dut),
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005011 "P2P_SET ps 1") < 0)
5012 return -2;
5013 } else
5014 return -1;
5015 }
5016
5017 val = get_param(cmd, "NoAck");
5018 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005019 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005020 case DRIVER_ATHEROS:
5021 ath_sta_set_noack(dut, intf, val);
5022 break;
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08005023#ifdef NL80211_SUPPORT
5024 case DRIVER_WCN:
5025 wcn_sta_set_noack(dut, intf, val);
5026 break;
5027#endif /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005028 default:
5029 send_resp(dut, conn, SIGMA_ERROR,
5030 "ErrorCode,Setting NoAck not supported");
5031 return 0;
5032 }
5033 }
5034
5035 val = get_param(cmd, "IgnoreChswitchProhibit");
5036 if (val) {
5037 /* TODO: Enabled/disabled */
5038 if (strcasecmp(val, "Enabled") == 0) {
5039 send_resp(dut, conn, SIGMA_ERROR,
5040 "ErrorCode,Enabling IgnoreChswitchProhibit "
5041 "not supported");
5042 return 0;
5043 }
5044 }
5045
5046 val = get_param(cmd, "TDLS");
5047 if (val) {
5048 if (strcasecmp(val, "Disabled") == 0) {
5049 if (wpa_command(intf, "SET tdls_disabled 1")) {
5050 send_resp(dut, conn, SIGMA_ERROR,
5051 "ErrorCode,Failed to disable TDLS");
5052 return 0;
5053 }
5054 } else if (strcasecmp(val, "Enabled") == 0) {
5055 if (wpa_command(intf, "SET tdls_disabled 0")) {
5056 send_resp(dut, conn, SIGMA_ERROR,
5057 "ErrorCode,Failed to enable TDLS");
5058 return 0;
5059 }
5060 } else {
5061 send_resp(dut, conn, SIGMA_ERROR,
5062 "ErrorCode,Unsupported TDLS value");
5063 return 0;
5064 }
5065 }
5066
5067 val = get_param(cmd, "TDLSmode");
5068 if (val) {
5069 if (strcasecmp(val, "Default") == 0) {
5070 wpa_command(intf, "SET tdls_testing 0");
5071 } else if (strcasecmp(val, "APProhibit") == 0) {
5072 if (wpa_command(intf, "SET tdls_testing 0x400")) {
5073 send_resp(dut, conn, SIGMA_ERROR,
5074 "ErrorCode,Failed to enable ignore "
5075 "APProhibit TDLS mode");
5076 return 0;
5077 }
5078 } else if (strcasecmp(val, "HiLoMac") == 0) {
5079 /* STA should respond with TDLS setup req for a TDLS
5080 * setup req */
5081 if (wpa_command(intf, "SET tdls_testing 0x80")) {
5082 send_resp(dut, conn, SIGMA_ERROR,
5083 "ErrorCode,Failed to enable HiLoMac "
5084 "TDLS mode");
5085 return 0;
5086 }
5087 } else if (strcasecmp(val, "WeakSecurity") == 0) {
5088 /*
5089 * Since all security modes are enabled by default when
5090 * Sigma control is used, there is no need to do
5091 * anything here.
5092 */
5093 } else if (strcasecmp(val, "ExistLink") == 0) {
5094 /*
5095 * Since we allow new TDLS Setup Request even if there
5096 * is an existing link, nothing needs to be done for
5097 * this.
5098 */
5099 } else {
5100 /* TODO:
5101 * ExistLink: STA should send TDLS setup req even if
5102 * direct link already exists
5103 */
5104 send_resp(dut, conn, SIGMA_ERROR,
5105 "ErrorCode,Unsupported TDLSmode value");
5106 return 0;
5107 }
5108 }
5109
5110 val = get_param(cmd, "FakePubKey");
5111 if (val && atoi(val) && wpa_command(intf, "SET wps_corrupt_pkhash 1")) {
5112 send_resp(dut, conn, SIGMA_ERROR,
5113 "ErrorCode,Failed to enable FakePubKey");
5114 return 0;
5115 }
5116
Amarnath Hullur Subramanyamae1042b2018-02-22 21:52:52 -08005117#ifdef NL80211_SUPPORT
5118 val = get_param(cmd, "FrgmntSupport");
5119 if (val) {
5120 if (strcasecmp(val, "Enable") == 0) {
5121 if (sta_set_he_fragmentation(dut, intf,
5122 HE_FRAG_LEVEL1)) {
5123 send_resp(dut, conn, SIGMA_ERROR,
5124 "ErrorCode,Failed to enable HE Fragmentation");
5125 return 0;
5126 }
5127 } else if (strcasecmp(val, "Disable") == 0) {
5128 if (sta_set_he_fragmentation(dut, intf,
5129 HE_FRAG_DISABLE)) {
5130 send_resp(dut, conn, SIGMA_ERROR,
5131 "ErrorCode,Failed to disable HE Fragmentation");
5132 return 0;
5133 }
5134 }
5135 }
5136#endif /* NL80211_SUPPORT */
5137
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005138 return 1;
5139}
5140
5141
5142static const char * ath_get_radio_name(const char *radio_name)
5143{
5144 if (radio_name == NULL)
5145 return "wifi0";
5146 if (strcmp(radio_name, "wifi1") == 0)
5147 return "wifi1";
5148 if (strcmp(radio_name, "wifi2") == 0)
5149 return "wifi2";
5150 return "wifi0";
5151}
5152
5153
5154static void ath_sta_set_txsp_stream(struct sigma_dut *dut, const char *intf,
5155 const char *val)
5156{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005157 unsigned int vht_mcsmap = 0;
5158 int txchainmask = 0;
5159 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
5160
5161 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
5162 if (dut->testbed_flag_txsp == 1) {
5163 vht_mcsmap = 0xfffc;
5164 dut->testbed_flag_txsp = 0;
5165 } else {
5166 vht_mcsmap = 0xfffe;
5167 }
5168 txchainmask = 1;
5169 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
5170 if (dut->testbed_flag_txsp == 1) {
5171 vht_mcsmap = 0xfff0;
5172 dut->testbed_flag_txsp = 0;
5173 } else {
5174 vht_mcsmap = 0xfffa;
5175 }
5176 txchainmask = 3;
5177 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
5178 if (dut->testbed_flag_txsp == 1) {
5179 vht_mcsmap = 0xffc0;
5180 dut->testbed_flag_txsp = 0;
5181 } else {
5182 vht_mcsmap = 0xffea;
5183 }
5184 txchainmask = 7;
5185 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
5186 if (dut->testbed_flag_txsp == 1) {
5187 vht_mcsmap = 0xff00;
5188 dut->testbed_flag_txsp = 0;
5189 } else {
5190 vht_mcsmap = 0xffaa;
5191 }
5192 txchainmask = 15;
5193 } else {
5194 if (dut->testbed_flag_txsp == 1) {
5195 vht_mcsmap = 0xffc0;
5196 dut->testbed_flag_txsp = 0;
5197 } else {
5198 vht_mcsmap = 0xffea;
5199 }
5200 }
5201
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005202 if (txchainmask)
5203 run_iwpriv(dut, basedev, "txchainmask %d", txchainmask);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005204
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005205 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005206}
5207
5208
5209static void ath_sta_set_rxsp_stream(struct sigma_dut *dut, const char *intf,
5210 const char *val)
5211{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005212 unsigned int vht_mcsmap = 0;
5213 int rxchainmask = 0;
5214 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
5215
5216 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
5217 if (dut->testbed_flag_rxsp == 1) {
5218 vht_mcsmap = 0xfffc;
5219 dut->testbed_flag_rxsp = 0;
5220 } else {
5221 vht_mcsmap = 0xfffe;
5222 }
5223 rxchainmask = 1;
5224 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
5225 if (dut->testbed_flag_rxsp == 1) {
5226 vht_mcsmap = 0xfff0;
5227 dut->testbed_flag_rxsp = 0;
5228 } else {
5229 vht_mcsmap = 0xfffa;
5230 }
5231 rxchainmask = 3;
5232 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
5233 if (dut->testbed_flag_rxsp == 1) {
5234 vht_mcsmap = 0xffc0;
5235 dut->testbed_flag_rxsp = 0;
5236 } else {
5237 vht_mcsmap = 0xffea;
5238 }
5239 rxchainmask = 7;
5240 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
5241 if (dut->testbed_flag_rxsp == 1) {
5242 vht_mcsmap = 0xff00;
5243 dut->testbed_flag_rxsp = 0;
5244 } else {
5245 vht_mcsmap = 0xffaa;
5246 }
5247 rxchainmask = 15;
5248 } else {
5249 if (dut->testbed_flag_rxsp == 1) {
5250 vht_mcsmap = 0xffc0;
5251 dut->testbed_flag_rxsp = 0;
5252 } else {
5253 vht_mcsmap = 0xffea;
5254 }
5255 }
5256
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005257 if (rxchainmask)
5258 run_iwpriv(dut, basedev, "rxchainmask %d", rxchainmask);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005259
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005260 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005261}
5262
5263
5264void ath_set_zero_crc(struct sigma_dut *dut, const char *val)
5265{
5266 if (strcasecmp(val, "enable") == 0) {
5267 if (system("athdiag --set --address=0x2a204 --and=0xbfffffff")
5268 != 0) {
5269 sigma_dut_print(dut, DUT_MSG_ERROR,
5270 "Disable BB_VHTSIGB_CRC_CALC failed");
5271 }
5272
5273 if (system("athdiag --set --address=0x2a204 --or=0x80000000")
5274 != 0) {
5275 sigma_dut_print(dut, DUT_MSG_ERROR,
5276 "Enable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
5277 }
5278 } else {
5279 if (system("athdiag --set --address=0x2a204 --and=0x7fffffff")
5280 != 0) {
5281 sigma_dut_print(dut, DUT_MSG_ERROR,
5282 "Disable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
5283 }
5284
5285 if (system("athdiag --set --address=0x2a204 --or=0x40000000")
5286 != 0) {
5287 sigma_dut_print(dut, DUT_MSG_ERROR,
5288 "Enable BB_VHTSIGB_CRC_CALC failed");
5289 }
5290 }
5291}
5292
5293
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08005294static int wcn_sta_set_width(struct sigma_dut *dut, const char *intf,
5295 const char *val)
5296{
5297 char buf[60];
5298
5299 if (strcmp(val, "20") == 0) {
5300 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 0", intf);
5301 dut->chwidth = 0;
5302 } else if (strcmp(val, "40") == 0) {
5303 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 1", intf);
5304 dut->chwidth = 1;
5305 } else if (strcmp(val, "80") == 0) {
5306 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 2", intf);
5307 dut->chwidth = 2;
Sunil Duttb1cccac2018-05-22 21:03:12 +05305308 } else if (strcasecmp(val, "Auto") == 0) {
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08005309 buf[0] = '\0';
5310 } else {
5311 sigma_dut_print(dut, DUT_MSG_ERROR, "WIDTH %s not supported",
5312 val);
5313 return -1;
5314 }
5315
5316 if (buf[0] != '\0' && system(buf) != 0) {
5317 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv chwidth failed");
5318 return -1;
5319 }
5320
5321 return 0;
5322}
5323
5324
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005325static int nlvendor_sta_set_addba_reject(struct sigma_dut *dut,
5326 const char *intf, int addbareject)
5327{
5328#ifdef NL80211_SUPPORT
5329 struct nl_msg *msg;
5330 int ret = 0;
5331 struct nlattr *params;
5332 int ifindex;
5333
5334 ifindex = if_nametoindex(intf);
5335 if (ifindex == 0) {
5336 sigma_dut_print(dut, DUT_MSG_ERROR,
5337 "%s: Index for interface %s failed",
5338 __func__, intf);
5339 return -1;
5340 }
5341
5342 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
5343 NL80211_CMD_VENDOR)) ||
5344 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
5345 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
5346 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
5347 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
5348 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
5349 nla_put_u8(msg,
5350 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ACCEPT_ADDBA_REQ,
5351 !addbareject)) {
5352 sigma_dut_print(dut, DUT_MSG_ERROR,
5353 "%s: err in adding vendor_cmd and vendor_data",
5354 __func__);
5355 nlmsg_free(msg);
5356 return -1;
5357 }
5358 nla_nest_end(msg, params);
5359
5360 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5361 if (ret) {
5362 sigma_dut_print(dut, DUT_MSG_ERROR,
5363 "%s: err in send_and_recv_msgs, ret=%d",
5364 __func__, ret);
5365 }
5366 return ret;
5367#else /* NL80211_SUPPORT */
5368 sigma_dut_print(dut, DUT_MSG_ERROR,
5369 "ADDBA_REJECT cannot be set without NL80211_SUPPORT defined");
5370 return -1;
5371#endif /* NL80211_SUPPORT */
5372}
5373
5374
5375static int sta_set_addba_reject(struct sigma_dut *dut, const char *intf,
5376 int addbareject)
5377{
5378 int ret;
5379
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005380 switch (get_driver_type(dut)) {
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005381 case DRIVER_WCN:
5382 ret = nlvendor_sta_set_addba_reject(dut, intf, addbareject);
5383 if (ret) {
5384 sigma_dut_print(dut, DUT_MSG_ERROR,
5385 "nlvendor_sta_set_addba_reject failed, ret:%d",
5386 ret);
5387 return ret;
5388 }
5389 break;
5390 default:
5391 sigma_dut_print(dut, DUT_MSG_ERROR,
5392 "errorCode,Unsupported ADDBA_REJECT with the current driver");
5393 ret = -1;
5394 break;
5395 }
5396
5397 return ret;
5398}
5399
5400
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08005401static int nlvendor_config_send_addba(struct sigma_dut *dut, const char *intf,
5402 int enable)
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005403{
5404#ifdef NL80211_SUPPORT
5405 struct nl_msg *msg;
5406 int ret = 0;
5407 struct nlattr *params;
5408 int ifindex;
5409
5410 ifindex = if_nametoindex(intf);
5411 if (ifindex == 0) {
5412 sigma_dut_print(dut, DUT_MSG_ERROR,
5413 "%s: Index for interface %s failed",
5414 __func__, intf);
5415 return -1;
5416 }
5417
5418 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
5419 NL80211_CMD_VENDOR)) ||
5420 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
5421 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
5422 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
5423 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
5424 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
5425 nla_put_u8(msg,
5426 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_SEND_ADDBA_REQ,
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08005427 enable)) {
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005428 sigma_dut_print(dut, DUT_MSG_ERROR,
5429 "%s: err in adding vendor_cmd and vendor_data",
5430 __func__);
5431 nlmsg_free(msg);
5432 return -1;
5433 }
5434 nla_nest_end(msg, params);
5435
5436 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5437 if (ret) {
5438 sigma_dut_print(dut, DUT_MSG_ERROR,
5439 "%s: err in send_and_recv_msgs, ret=%d",
5440 __func__, ret);
5441 }
5442 return ret;
5443#else /* NL80211_SUPPORT */
5444 sigma_dut_print(dut, DUT_MSG_ERROR,
5445 "Disable addba not possible without NL80211_SUPPORT defined");
5446 return -1;
5447#endif /* NL80211_SUPPORT */
5448}
5449
5450
Veerendranath Jakkamadcd6202019-04-17 12:32:21 +05305451#ifdef NL80211_SUPPORT
5452static int nl80211_sta_set_rts(struct sigma_dut *dut, const char *intf, int val)
5453{
5454 struct nl_msg *msg;
5455 int ret = 0;
5456 int ifindex;
5457
5458 ifindex = if_nametoindex(intf);
5459 if (ifindex == 0) {
5460 sigma_dut_print(dut, DUT_MSG_ERROR,
5461 "%s: Index for interface %s failed",
5462 __func__, intf);
5463 return -1;
5464 }
5465
5466 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
5467 NL80211_CMD_SET_WIPHY)) ||
5468 nla_put_u32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD, val)) {
5469 sigma_dut_print(dut, DUT_MSG_ERROR,
5470 "%s: err in adding RTS threshold",
5471 __func__);
5472 nlmsg_free(msg);
5473 return -1;
5474 }
5475
5476 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5477 if (ret) {
5478 sigma_dut_print(dut, DUT_MSG_ERROR,
5479 "%s: err in send_and_recv_msgs, ret=%d",
5480 __func__, ret);
5481 }
5482 return ret;
5483}
5484#endif /* NL80211_SUPPORT */
5485
5486
5487static int sta_set_rts(struct sigma_dut *dut, const char *intf, int val)
5488{
5489 char buf[100];
5490
5491#ifdef NL80211_SUPPORT
5492 if (nl80211_sta_set_rts(dut, intf, val) == 0)
5493 return 0;
5494 sigma_dut_print(dut, DUT_MSG_DEBUG,
5495 "Fall back to using iwconfig for setting RTS threshold");
5496#endif /* NL80211_SUPPORT */
5497
5498 snprintf(buf, sizeof(buf), "iwconfig %s rts %d", intf, val);
5499 if (system(buf) != 0) {
5500 sigma_dut_print(dut, DUT_MSG_ERROR,
5501 "Failed to set RTS threshold %d", val);
5502 return -1;
5503 }
5504 return 0;
5505}
5506
5507
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005508static int cmd_sta_set_wireless_common(const char *intf, struct sigma_dut *dut,
5509 struct sigma_conn *conn,
5510 struct sigma_cmd *cmd)
5511{
5512 const char *val;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005513 int ampdu = -1, addbareject = -1;
Jouni Malinen3aa72862019-05-29 23:14:51 +03005514 char buf[128];
5515 int res;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005516
5517 val = get_param(cmd, "40_INTOLERANT");
5518 if (val) {
5519 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
5520 /* TODO: iwpriv ht40intol through wpa_supplicant */
5521 send_resp(dut, conn, SIGMA_ERROR,
5522 "ErrorCode,40_INTOLERANT not supported");
5523 return 0;
5524 }
5525 }
5526
5527 val = get_param(cmd, "ADDBA_REJECT");
5528 if (val) {
5529 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
5530 /* reject any ADDBA with status "decline" */
5531 ampdu = 0;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005532 addbareject = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005533 } else {
5534 /* accept ADDBA */
5535 ampdu = 1;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005536 addbareject = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005537 }
5538 }
5539
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005540 if (addbareject >= 0 &&
5541 sta_set_addba_reject(dut, intf, addbareject) < 0) {
5542 send_resp(dut, conn, SIGMA_ERROR,
5543 "ErrorCode,set addba_reject failed");
5544 return 0;
5545 }
5546
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005547 val = get_param(cmd, "AMPDU");
5548 if (val) {
5549 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
5550 /* enable AMPDU Aggregation */
5551 if (ampdu == 0) {
5552 send_resp(dut, conn, SIGMA_ERROR,
5553 "ErrorCode,Mismatch in "
5554 "addba_reject/ampdu - "
5555 "not supported");
5556 return 0;
5557 }
5558 ampdu = 1;
5559 } else {
5560 /* disable AMPDU Aggregation */
5561 if (ampdu == 1) {
5562 send_resp(dut, conn, SIGMA_ERROR,
5563 "ErrorCode,Mismatch in "
5564 "addba_reject/ampdu - "
5565 "not supported");
5566 return 0;
5567 }
5568 ampdu = 0;
5569 }
5570 }
5571
5572 if (ampdu >= 0) {
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005573 int ret;
5574
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005575 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s A-MPDU aggregation",
5576 ampdu ? "Enabling" : "Disabling");
5577 snprintf(buf, sizeof(buf), "SET ampdu %d", ampdu);
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07005578 if (wpa_command(intf, buf) < 0 &&
5579 iwpriv_sta_set_ampdu(dut, intf, ampdu) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005580 send_resp(dut, conn, SIGMA_ERROR,
5581 "ErrorCode,set aggr failed");
5582 return 0;
5583 }
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005584
5585 if (ampdu == 0) {
5586 /* Disable sending of addba using nl vendor command */
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08005587 ret = nlvendor_config_send_addba(dut, intf, 0);
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005588 if (ret) {
5589 sigma_dut_print(dut, DUT_MSG_ERROR,
5590 "Failed to disable addba, ret:%d",
5591 ret);
5592 }
5593 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005594 }
5595
5596 val = get_param(cmd, "AMSDU");
5597 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005598 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005599 case DRIVER_ATHEROS:
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08005600 case DRIVER_WCN:
5601 iwpriv_sta_set_amsdu(dut, intf, val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005602 break;
5603 default:
5604 if (strcmp(val, "1") == 0 ||
5605 strcasecmp(val, "Enable") == 0) {
5606 /* Enable AMSDU Aggregation */
5607 send_resp(dut, conn, SIGMA_ERROR,
5608 "ErrorCode,AMSDU aggregation not supported");
5609 return 0;
5610 }
5611 break;
5612 }
5613 }
5614
5615 val = get_param(cmd, "STBC_RX");
5616 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005617 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005618 case DRIVER_ATHEROS:
5619 ath_sta_set_stbc(dut, intf, val);
5620 break;
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05305621 case DRIVER_WCN:
5622 wcn_sta_set_stbc(dut, intf, val);
5623 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005624 default:
5625 send_resp(dut, conn, SIGMA_ERROR,
5626 "ErrorCode,STBC_RX not supported");
5627 return 0;
5628 }
5629 }
5630
5631 val = get_param(cmd, "WIDTH");
5632 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005633 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005634 case DRIVER_WCN:
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08005635 if (wcn_sta_set_width(dut, intf, val) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005636 send_resp(dut, conn, SIGMA_ERROR,
5637 "ErrorCode,Failed to set WIDTH");
5638 return 0;
5639 }
5640 break;
5641 case DRIVER_ATHEROS:
5642 if (ath_set_width(dut, conn, intf, val) < 0)
5643 return 0;
5644 break;
5645 default:
5646 sigma_dut_print(dut, DUT_MSG_ERROR,
5647 "Setting WIDTH not supported");
5648 break;
5649 }
5650 }
5651
5652 val = get_param(cmd, "SMPS");
5653 if (val) {
5654 /* TODO: Dynamic/0, Static/1, No Limit/2 */
5655 send_resp(dut, conn, SIGMA_ERROR,
5656 "ErrorCode,SMPS not supported");
5657 return 0;
5658 }
5659
5660 val = get_param(cmd, "TXSP_STREAM");
5661 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005662 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005663 case DRIVER_WCN:
5664 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
5665 send_resp(dut, conn, SIGMA_ERROR,
5666 "ErrorCode,Failed to set TXSP_STREAM");
5667 return 0;
5668 }
5669 break;
5670 case DRIVER_ATHEROS:
5671 ath_sta_set_txsp_stream(dut, intf, val);
5672 break;
5673 default:
5674 sigma_dut_print(dut, DUT_MSG_ERROR,
5675 "Setting TXSP_STREAM not supported");
5676 break;
5677 }
5678 }
5679
5680 val = get_param(cmd, "RXSP_STREAM");
5681 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005682 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005683 case DRIVER_WCN:
5684 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
5685 send_resp(dut, conn, SIGMA_ERROR,
5686 "ErrorCode,Failed to set RXSP_STREAM");
5687 return 0;
5688 }
5689 break;
5690 case DRIVER_ATHEROS:
5691 ath_sta_set_rxsp_stream(dut, intf, val);
5692 break;
5693 default:
5694 sigma_dut_print(dut, DUT_MSG_ERROR,
5695 "Setting RXSP_STREAM not supported");
5696 break;
5697 }
5698 }
5699
5700 val = get_param(cmd, "DYN_BW_SGNL");
5701 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005702 switch (get_driver_type(dut)) {
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08005703 case DRIVER_WCN:
Peng Xuc59afd32016-11-21 15:01:11 -08005704 if (strcasecmp(val, "enable") == 0) {
5705 snprintf(buf, sizeof(buf),
5706 "iwpriv %s cwmenable 1", intf);
5707 if (system(buf) != 0) {
5708 sigma_dut_print(dut, DUT_MSG_ERROR,
5709 "iwpriv cwmenable 1 failed");
5710 return 0;
5711 }
5712 } else if (strcasecmp(val, "disable") == 0) {
5713 snprintf(buf, sizeof(buf),
5714 "iwpriv %s cwmenable 0", intf);
5715 if (system(buf) != 0) {
5716 sigma_dut_print(dut, DUT_MSG_ERROR,
5717 "iwpriv cwmenable 0 failed");
5718 return 0;
5719 }
5720 } else {
5721 sigma_dut_print(dut, DUT_MSG_ERROR,
5722 "Unsupported DYN_BW_SGL");
5723 }
5724
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005725 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 3", intf);
5726 if (system(buf) != 0) {
5727 sigma_dut_print(dut, DUT_MSG_ERROR,
5728 "Failed to set cts_cbw in DYN_BW_SGNL");
5729 return 0;
5730 }
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08005731 break;
5732 case DRIVER_ATHEROS:
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -07005733 novap_reset(dut, intf, 1);
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08005734 ath_config_dyn_bw_sig(dut, intf, val);
5735 break;
5736 default:
5737 sigma_dut_print(dut, DUT_MSG_ERROR,
5738 "Failed to set DYN_BW_SGNL");
5739 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005740 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005741 }
5742
5743 val = get_param(cmd, "RTS_FORCE");
5744 if (val) {
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -07005745 novap_reset(dut, intf, 1);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005746 if (strcasecmp(val, "Enable") == 0) {
Veerendranath Jakkamadcd6202019-04-17 12:32:21 +05305747 if (sta_set_rts(dut, intf, 64) != 0) {
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02005748 sigma_dut_print(dut, DUT_MSG_ERROR,
5749 "Failed to set RTS_FORCE 64");
5750 }
Jouni Malinen3aa72862019-05-29 23:14:51 +03005751 res = snprintf(buf, sizeof(buf),
5752 "wifitool %s beeliner_fw_test 100 1",
5753 intf);
5754 if (res < 0 || res >= sizeof(buf) || system(buf) != 0) {
priyadharshini gowthaman270870e2015-12-09 10:10:23 -08005755 sigma_dut_print(dut, DUT_MSG_ERROR,
5756 "wifitool beeliner_fw_test 100 1 failed");
5757 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005758 } else if (strcasecmp(val, "Disable") == 0) {
Veerendranath Jakkamadcd6202019-04-17 12:32:21 +05305759 if (sta_set_rts(dut, intf, 2347) != 0) {
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02005760 sigma_dut_print(dut, DUT_MSG_ERROR,
5761 "Failed to set RTS_FORCE 2347");
5762 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005763 } else {
5764 send_resp(dut, conn, SIGMA_ERROR,
5765 "ErrorCode,RTS_FORCE value not supported");
5766 return 0;
5767 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005768 }
5769
5770 val = get_param(cmd, "CTS_WIDTH");
5771 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005772 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005773 case DRIVER_WCN:
5774 if (wcn_sta_set_cts_width(dut, intf, val) < 0) {
5775 send_resp(dut, conn, SIGMA_ERROR,
5776 "ErrorCode,Failed to set CTS_WIDTH");
5777 return 0;
5778 }
5779 break;
5780 case DRIVER_ATHEROS:
5781 ath_set_cts_width(dut, intf, val);
5782 break;
5783 default:
5784 sigma_dut_print(dut, DUT_MSG_ERROR,
5785 "Setting CTS_WIDTH not supported");
5786 break;
5787 }
5788 }
5789
5790 val = get_param(cmd, "BW_SGNL");
5791 if (val) {
5792 if (strcasecmp(val, "Enable") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005793 run_iwpriv(dut, intf, "cwmenable 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005794 } else if (strcasecmp(val, "Disable") == 0) {
5795 /* TODO: Disable */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005796 } else {
5797 send_resp(dut, conn, SIGMA_ERROR,
5798 "ErrorCode,BW_SGNL value not supported");
5799 return 0;
5800 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005801 }
5802
5803 val = get_param(cmd, "Band");
5804 if (val) {
5805 if (strcmp(val, "2.4") == 0 || strcmp(val, "5") == 0) {
5806 /* STA supports all bands by default */
5807 } else {
5808 send_resp(dut, conn, SIGMA_ERROR,
5809 "ErrorCode,Unsupported Band");
5810 return 0;
5811 }
5812 }
5813
5814 val = get_param(cmd, "zero_crc");
5815 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005816 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005817 case DRIVER_ATHEROS:
5818 ath_set_zero_crc(dut, val);
5819 break;
5820 default:
5821 break;
5822 }
5823 }
5824
5825 return 1;
5826}
5827
5828
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02005829static int sta_set_force_mcs(struct sigma_dut *dut, int force, int mcs)
5830{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005831 switch (get_driver_type(dut)) {
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02005832#ifdef __linux__
5833 case DRIVER_WIL6210:
5834 return wil6210_set_force_mcs(dut, force, mcs);
5835#endif /* __linux__ */
5836 default:
5837 sigma_dut_print(dut, DUT_MSG_ERROR,
5838 "Unsupported sta_set_force_mcs with the current driver");
5839 return -1;
5840 }
5841}
5842
5843
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02005844static int sta_60g_force_rsn_ie(struct sigma_dut *dut, int state)
5845{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005846 switch (get_driver_type(dut)) {
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02005847#ifdef __linux__
5848 case DRIVER_WIL6210:
5849 return wil6210_force_rsn_ie(dut, state);
5850#endif /* __linux__ */
5851 default:
5852 sigma_dut_print(dut, DUT_MSG_ERROR,
5853 "Unsupported sta_60g_force_rsn_ie with the current driver");
5854 return -1;
5855 }
5856}
5857
5858
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005859static int sta_set_60g_common(struct sigma_dut *dut, struct sigma_conn *conn,
5860 struct sigma_cmd *cmd)
5861{
5862 const char *val;
5863 char buf[100];
5864
5865 val = get_param(cmd, "MSDUSize");
5866 if (val) {
5867 int mtu;
5868
5869 dut->amsdu_size = atoi(val);
5870 if (dut->amsdu_size > IEEE80211_MAX_DATA_LEN_DMG ||
5871 dut->amsdu_size < IEEE80211_SNAP_LEN_DMG) {
5872 sigma_dut_print(dut, DUT_MSG_ERROR,
5873 "MSDUSize %d is above max %d or below min %d",
5874 dut->amsdu_size,
5875 IEEE80211_MAX_DATA_LEN_DMG,
5876 IEEE80211_SNAP_LEN_DMG);
5877 dut->amsdu_size = 0;
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005878 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005879 }
5880
5881 mtu = dut->amsdu_size - IEEE80211_SNAP_LEN_DMG;
5882 sigma_dut_print(dut, DUT_MSG_DEBUG,
5883 "Setting amsdu_size to %d", mtu);
5884 snprintf(buf, sizeof(buf), "ifconfig %s mtu %d",
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005885 get_station_ifname(dut), mtu);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005886
5887 if (system(buf) != 0) {
5888 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
5889 buf);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005890 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005891 }
5892 }
5893
5894 val = get_param(cmd, "BAckRcvBuf");
5895 if (val) {
5896 dut->back_rcv_buf = atoi(val);
5897 if (dut->back_rcv_buf == 0) {
5898 sigma_dut_print(dut, DUT_MSG_ERROR,
5899 "Failed to convert %s or value is 0",
5900 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005901 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005902 }
5903
5904 sigma_dut_print(dut, DUT_MSG_DEBUG,
5905 "Setting BAckRcvBuf to %s", val);
5906 }
5907
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02005908 val = get_param(cmd, "MCS_FixedRate");
5909 if (val) {
5910 if (sta_set_force_mcs(dut, 1, atoi(val))) {
5911 sigma_dut_print(dut, DUT_MSG_ERROR,
5912 "Failed to force MCS");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005913 return ERROR_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02005914 }
5915 }
5916
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005917 return SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005918}
5919
5920
5921static int sta_pcp_start(struct sigma_dut *dut, struct sigma_conn *conn,
5922 struct sigma_cmd *cmd)
5923{
5924 int net_id;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005925 const char *ifname;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005926 const char *val;
5927 char buf[100];
5928
5929 dut->mode = SIGMA_MODE_STATION;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005930 ifname = get_main_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005931 if (wpa_command(ifname, "PING") != 0) {
5932 sigma_dut_print(dut, DUT_MSG_ERROR, "Supplicant not running");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005933 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005934 }
5935
5936 wpa_command(ifname, "FLUSH");
5937 net_id = add_network_common(dut, conn, ifname, cmd);
5938 if (net_id < 0) {
5939 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add network");
5940 return net_id;
5941 }
5942
5943 /* TODO: mode=2 for the AP; in the future, replace for mode PCP */
5944 if (set_network(ifname, net_id, "mode", "2") < 0) {
5945 sigma_dut_print(dut, DUT_MSG_ERROR,
5946 "Failed to set supplicant network mode");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005947 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005948 }
5949
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02005950 if (set_network(ifname, net_id, "pbss", "1") < 0)
5951 return -2;
5952
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005953 sigma_dut_print(dut, DUT_MSG_DEBUG,
Alexei Avshalom Lazarfd9f1352018-11-13 14:07:58 +02005954 "Supplicant set network with mode 2. network_id %d",
5955 net_id);
5956
5957 if (set_network(ifname, net_id, "wps_disabled", "0") < 0) {
5958 sigma_dut_print(dut, DUT_MSG_INFO,
5959 "Failed to set supplicant to WPS ENABLE");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005960 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarfd9f1352018-11-13 14:07:58 +02005961 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005962
5963 val = get_param(cmd, "Security");
5964 if (val && strcasecmp(val, "OPEN") == 0) {
5965 dut->ap_key_mgmt = AP_OPEN;
5966 if (set_network(ifname, net_id, "key_mgmt", "NONE") < 0) {
5967 sigma_dut_print(dut, DUT_MSG_ERROR,
5968 "Failed to set supplicant to %s security",
5969 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005970 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005971 }
5972 } else if (val && strcasecmp(val, "WPA2-PSK") == 0) {
5973 dut->ap_key_mgmt = AP_WPA2_PSK;
5974 if (set_network(ifname, net_id, "key_mgmt", "WPA-PSK") < 0) {
5975 sigma_dut_print(dut, DUT_MSG_ERROR,
5976 "Failed to set supplicant to %s security",
5977 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005978 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005979 }
5980
5981 if (set_network(ifname, net_id, "proto", "RSN") < 0) {
5982 sigma_dut_print(dut, DUT_MSG_ERROR,
5983 "Failed to set supplicant to proto RSN");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005984 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005985 }
5986 } else if (val) {
5987 sigma_dut_print(dut, DUT_MSG_ERROR,
5988 "Requested Security %s is not supported on 60GHz",
5989 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005990 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005991 }
5992
5993 val = get_param(cmd, "Encrypt");
5994 if (val && strcasecmp(val, "AES-GCMP") == 0) {
5995 if (set_network(ifname, net_id, "pairwise", "GCMP") < 0) {
5996 sigma_dut_print(dut, DUT_MSG_ERROR,
5997 "Failed to set supplicant to pairwise GCMP");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005998 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005999 }
6000 if (set_network(ifname, net_id, "group", "GCMP") < 0) {
6001 sigma_dut_print(dut, DUT_MSG_ERROR,
6002 "Failed to set supplicant to group GCMP");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02006003 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006004 }
6005 } else if (val) {
6006 sigma_dut_print(dut, DUT_MSG_ERROR,
6007 "Requested Encrypt %s is not supported on 60 GHz",
6008 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02006009 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006010 }
6011
6012 val = get_param(cmd, "PSK");
6013 if (val && set_network_quoted(ifname, net_id, "psk", val) < 0) {
6014 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set psk %s",
6015 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02006016 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006017 }
6018
6019 /* Convert 60G channel to freq */
6020 switch (dut->ap_channel) {
6021 case 1:
6022 val = "58320";
6023 break;
6024 case 2:
6025 val = "60480";
6026 break;
6027 case 3:
6028 val = "62640";
6029 break;
6030 default:
6031 sigma_dut_print(dut, DUT_MSG_ERROR,
6032 "Failed to configure channel %d. Not supported",
6033 dut->ap_channel);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02006034 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006035 }
6036
6037 if (set_network(ifname, net_id, "frequency", val) < 0) {
6038 sigma_dut_print(dut, DUT_MSG_ERROR,
6039 "Failed to set supplicant network frequency");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02006040 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006041 }
6042
Alexei Avshalom Lazar2eccf4d2019-01-31 10:03:59 +02006043 if (dut->eap_fragment) {
6044 sigma_dut_print(dut, DUT_MSG_DEBUG,
6045 "Set EAP fragment size to 128 bytes.");
6046 if (set_network(ifname, net_id, "fragment_size", "128") < 0)
6047 return ERROR_SEND_STATUS;
6048 }
6049
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006050 sigma_dut_print(dut, DUT_MSG_DEBUG,
6051 "Supplicant set network with frequency");
6052
6053 snprintf(buf, sizeof(buf), "SELECT_NETWORK %d", net_id);
6054 if (wpa_command(ifname, buf) < 0) {
6055 sigma_dut_print(dut, DUT_MSG_INFO,
6056 "Failed to select network id %d on %s",
6057 net_id, ifname);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02006058 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006059 }
6060
6061 sigma_dut_print(dut, DUT_MSG_DEBUG, "Selected network");
6062
Jouni Malinen0e29cf22019-02-19 01:13:21 +02006063 return SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006064}
6065
6066
Lior David67543f52017-01-03 19:04:22 +02006067static int wil6210_set_abft_len(struct sigma_dut *dut, int abft_len)
6068{
6069 char buf[128], fname[128];
6070 FILE *f;
Jouni Malinen3aa72862019-05-29 23:14:51 +03006071 int res;
Lior David67543f52017-01-03 19:04:22 +02006072
6073 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
6074 sigma_dut_print(dut, DUT_MSG_ERROR,
6075 "failed to get wil6210 debugfs dir");
6076 return -1;
6077 }
6078
Jouni Malinen3aa72862019-05-29 23:14:51 +03006079 res = snprintf(fname, sizeof(fname), "%s/abft_len", buf);
6080 if (res < 0 || res >= sizeof(fname))
6081 return -1;
Lior David67543f52017-01-03 19:04:22 +02006082 f = fopen(fname, "w");
6083 if (!f) {
6084 sigma_dut_print(dut, DUT_MSG_ERROR,
6085 "failed to open: %s", fname);
6086 return -1;
6087 }
6088
6089 fprintf(f, "%d\n", abft_len);
6090 fclose(f);
6091
6092 return 0;
6093}
6094
6095
Alexei Avshalom Lazar49498b82019-01-31 15:16:32 +02006096int sta_set_60g_abft_len(struct sigma_dut *dut, struct sigma_conn *conn,
6097 int abft_len)
Lior David67543f52017-01-03 19:04:22 +02006098{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006099 switch (get_driver_type(dut)) {
Lior David67543f52017-01-03 19:04:22 +02006100 case DRIVER_WIL6210:
6101 return wil6210_set_abft_len(dut, abft_len);
6102 default:
6103 sigma_dut_print(dut, DUT_MSG_ERROR,
6104 "set abft_len not supported");
6105 return -1;
6106 }
6107}
6108
6109
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006110static int sta_set_60g_pcp(struct sigma_dut *dut, struct sigma_conn *conn,
6111 struct sigma_cmd *cmd)
6112{
6113 const char *val;
Lior David67543f52017-01-03 19:04:22 +02006114 unsigned int abft_len = 1; /* default is one slot */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006115
6116 if (dut->dev_role != DEVROLE_PCP) {
6117 send_resp(dut, conn, SIGMA_INVALID,
6118 "ErrorCode,Invalid DevRole");
6119 return 0;
6120 }
6121
6122 val = get_param(cmd, "SSID");
6123 if (val) {
6124 if (strlen(val) > sizeof(dut->ap_ssid) - 1) {
6125 send_resp(dut, conn, SIGMA_INVALID,
6126 "ErrorCode,Invalid SSID");
6127 return -1;
6128 }
6129
Peng Xub8fc5cc2017-05-10 17:27:28 -07006130 strlcpy(dut->ap_ssid, val, sizeof(dut->ap_ssid));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006131 }
6132
6133 val = get_param(cmd, "CHANNEL");
6134 if (val) {
6135 const char *pos;
6136
6137 dut->ap_channel = atoi(val);
6138 pos = strchr(val, ';');
6139 if (pos) {
6140 pos++;
6141 dut->ap_channel_1 = atoi(pos);
6142 }
6143 }
6144
6145 switch (dut->ap_channel) {
6146 case 1:
6147 case 2:
6148 case 3:
6149 break;
6150 default:
6151 sigma_dut_print(dut, DUT_MSG_ERROR,
6152 "Channel %d is not supported", dut->ap_channel);
6153 send_resp(dut, conn, SIGMA_ERROR,
6154 "Requested channel is not supported");
6155 return -1;
6156 }
6157
6158 val = get_param(cmd, "BCNINT");
6159 if (val)
6160 dut->ap_bcnint = atoi(val);
6161
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006162 val = get_param(cmd, "AllocType");
6163 if (val) {
6164 send_resp(dut, conn, SIGMA_ERROR,
6165 "ErrorCode,AllocType is not supported yet");
6166 return -1;
6167 }
6168
6169 val = get_param(cmd, "PercentBI");
6170 if (val) {
6171 send_resp(dut, conn, SIGMA_ERROR,
6172 "ErrorCode,PercentBI is not supported yet");
6173 return -1;
6174 }
6175
6176 val = get_param(cmd, "CBAPOnly");
6177 if (val) {
6178 send_resp(dut, conn, SIGMA_ERROR,
6179 "ErrorCode,CBAPOnly is not supported yet");
6180 return -1;
6181 }
6182
6183 val = get_param(cmd, "AMPDU");
6184 if (val) {
6185 if (strcasecmp(val, "Enable") == 0)
6186 dut->ap_ampdu = 1;
6187 else if (strcasecmp(val, "Disable") == 0)
6188 dut->ap_ampdu = 2;
6189 else {
6190 send_resp(dut, conn, SIGMA_ERROR,
6191 "ErrorCode,AMPDU value is not Enable nor Disabled");
6192 return -1;
6193 }
6194 }
6195
6196 val = get_param(cmd, "AMSDU");
6197 if (val) {
6198 if (strcasecmp(val, "Enable") == 0)
6199 dut->ap_amsdu = 1;
6200 else if (strcasecmp(val, "Disable") == 0)
6201 dut->ap_amsdu = 2;
6202 }
6203
6204 val = get_param(cmd, "NumMSDU");
6205 if (val) {
6206 send_resp(dut, conn, SIGMA_ERROR,
6207 "ErrorCode, NumMSDU is not supported yet");
6208 return -1;
6209 }
6210
6211 val = get_param(cmd, "ABFTLRang");
6212 if (val) {
6213 sigma_dut_print(dut, DUT_MSG_DEBUG,
Lior David67543f52017-01-03 19:04:22 +02006214 "ABFTLRang parameter %s", val);
6215 if (strcmp(val, "Gt1") == 0)
6216 abft_len = 2; /* 2 slots in this case */
6217 }
6218
6219 if (sta_set_60g_abft_len(dut, conn, abft_len)) {
6220 send_resp(dut, conn, SIGMA_ERROR,
6221 "ErrorCode, Can't set ABFT length");
6222 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006223 }
6224
6225 if (sta_pcp_start(dut, conn, cmd) < 0) {
6226 send_resp(dut, conn, SIGMA_ERROR,
6227 "ErrorCode, Can't start PCP role");
6228 return -1;
6229 }
6230
6231 return sta_set_60g_common(dut, conn, cmd);
6232}
6233
6234
6235static int sta_set_60g_sta(struct sigma_dut *dut, struct sigma_conn *conn,
6236 struct sigma_cmd *cmd)
6237{
6238 const char *val = get_param(cmd, "DiscoveryMode");
6239
6240 if (dut->dev_role != DEVROLE_STA) {
6241 send_resp(dut, conn, SIGMA_INVALID,
6242 "ErrorCode,Invalid DevRole");
6243 return 0;
6244 }
6245
6246 if (val) {
6247 sigma_dut_print(dut, DUT_MSG_DEBUG, "Discovery: %s", val);
6248 /* Ignore Discovery mode till Driver expose API. */
6249#if 0
6250 if (strcasecmp(val, "1") == 0) {
6251 send_resp(dut, conn, SIGMA_INVALID,
6252 "ErrorCode,DiscoveryMode 1 not supported");
6253 return 0;
6254 }
6255
6256 if (strcasecmp(val, "0") == 0) {
6257 /* OK */
6258 } else {
6259 send_resp(dut, conn, SIGMA_INVALID,
6260 "ErrorCode,DiscoveryMode not supported");
6261 return 0;
6262 }
6263#endif
6264 }
6265
6266 if (start_sta_mode(dut) != 0)
Jouni Malinen0e29cf22019-02-19 01:13:21 +02006267 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006268 return sta_set_60g_common(dut, conn, cmd);
6269}
6270
6271
Jouni Malinenf7222712019-06-13 01:50:21 +03006272static enum sigma_cmd_result cmd_sta_disconnect(struct sigma_dut *dut,
6273 struct sigma_conn *conn,
6274 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006275{
6276 const char *intf = get_param(cmd, "Interface");
Jouni Malinened77e672018-01-10 16:45:13 +02006277 const char *val = get_param(cmd, "maintain_profile");
vamsi krishnad605c422017-09-20 14:56:31 +05306278
Jouni Malinened77e672018-01-10 16:45:13 +02006279 if (dut->program == PROGRAM_OCE ||
Amarnath Hullur Subramanyamebeda9e2018-01-31 03:21:48 -08006280 dut->program == PROGRAM_HE ||
Jouni Malinened77e672018-01-10 16:45:13 +02006281 (val && atoi(val) == 1)) {
vamsi krishnad605c422017-09-20 14:56:31 +05306282 wpa_command(intf, "DISCONNECT");
6283 return 1;
6284 }
6285
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006286 disconnect_station(dut);
6287 /* Try to ignore old scan results to avoid HS 2.0R2 test case failures
6288 * due to cached results. */
6289 wpa_command(intf, "SET ignore_old_scan_res 1");
6290 wpa_command(intf, "BSS_FLUSH");
6291 return 1;
6292}
6293
6294
Jouni Malinenf7222712019-06-13 01:50:21 +03006295static enum sigma_cmd_result cmd_sta_reassoc(struct sigma_dut *dut,
6296 struct sigma_conn *conn,
6297 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006298{
6299 const char *intf = get_param(cmd, "Interface");
6300 const char *bssid = get_param(cmd, "bssid");
6301 const char *val = get_param(cmd, "CHANNEL");
6302 struct wpa_ctrl *ctrl;
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05306303 char buf[1000];
Sunil Duttd30ce092018-01-11 23:56:29 +05306304 char result[32];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006305 int res;
6306 int chan = 0;
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006307 enum sigma_cmd_result status = STATUS_SENT;
Sunil Duttd30ce092018-01-11 23:56:29 +05306308 int fastreassoc = 1;
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006309 int ft_ds = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006310
6311 if (bssid == NULL) {
6312 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing bssid "
6313 "argument");
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006314 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006315 }
6316
6317 if (val)
6318 chan = atoi(val);
6319
6320 if (wifi_chip_type != DRIVER_WCN && wifi_chip_type != DRIVER_AR6003) {
6321 /* The current network may be from sta_associate or
6322 * sta_hs2_associate
6323 */
6324 if (set_network(intf, dut->infra_network_id, "bssid", bssid) <
6325 0 ||
6326 set_network(intf, 0, "bssid", bssid) < 0)
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006327 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006328 }
6329
6330 ctrl = open_wpa_mon(intf);
6331 if (ctrl == NULL) {
6332 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
6333 "wpa_supplicant monitor connection");
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006334 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006335 }
6336
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006337 if (get_wpa_status(get_station_ifname(dut), "wpa_state", result,
Sunil Duttd30ce092018-01-11 23:56:29 +05306338 sizeof(result)) < 0 ||
6339 strncmp(result, "COMPLETED", 9) != 0) {
6340 sigma_dut_print(dut, DUT_MSG_DEBUG,
6341 "sta_reassoc: Not connected");
6342 fastreassoc = 0;
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006343 } else if (dut->sta_ft_ds) {
6344 sigma_dut_print(dut, DUT_MSG_DEBUG,
6345 "sta_reassoc: Use FT-over-DS");
6346 ft_ds = 1;
Sunil Duttd30ce092018-01-11 23:56:29 +05306347 }
6348
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05306349 if (dut->rsne_override) {
6350#ifdef NL80211_SUPPORT
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006351 if (get_driver_type(dut) == DRIVER_WCN &&
6352 dut->config_rsnie == 0) {
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05306353 sta_config_rsnie(dut, 1);
6354 dut->config_rsnie = 1;
6355 }
6356#endif /* NL80211_SUPPORT */
6357 snprintf(buf, sizeof(buf), "TEST_ASSOC_IE %s",
6358 dut->rsne_override);
6359 if (wpa_command(intf, buf) < 0) {
6360 send_resp(dut, conn, SIGMA_ERROR,
6361 "ErrorCode,Failed to set DEV_CONFIGURE_IE RSNE override");
6362 return 0;
6363 }
6364 }
6365
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006366 if (ft_ds) {
6367 if (chan) {
6368 unsigned int freq;
6369
6370 freq = channel_to_freq(dut, chan);
6371 if (!freq) {
6372 sigma_dut_print(dut, DUT_MSG_ERROR,
6373 "Invalid channel number provided: %d",
6374 chan);
6375 send_resp(dut, conn, SIGMA_INVALID,
6376 "ErrorCode,Invalid channel number");
6377 goto close_mon_conn;
6378 }
6379 res = snprintf(buf, sizeof(buf),
6380 "SCAN TYPE=ONLY freq=%d", freq);
6381 } else {
6382 res = snprintf(buf, sizeof(buf), "SCAN TYPE=ONLY");
6383 }
6384 if (res < 0 || res >= (int) sizeof(buf)) {
6385 send_resp(dut, conn, SIGMA_ERROR,
6386 "ErrorCode,snprintf failed");
6387 goto close_mon_conn;
6388 }
6389 if (wpa_command(intf, buf) < 0) {
6390 sigma_dut_print(dut, DUT_MSG_INFO,
6391 "Failed to start scan");
6392 send_resp(dut, conn, SIGMA_ERROR,
6393 "ErrorCode,scan failed");
6394 goto close_mon_conn;
6395 }
6396
6397 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
6398 buf, sizeof(buf));
6399 if (res < 0) {
6400 sigma_dut_print(dut, DUT_MSG_INFO,
6401 "Scan did not complete");
6402 send_resp(dut, conn, SIGMA_ERROR,
6403 "ErrorCode,scan did not complete");
6404 goto close_mon_conn;
6405 }
6406
6407 res = snprintf(buf, sizeof(buf), "FT_DS %s", bssid);
6408 if (res > 0 && res < (int) sizeof(buf))
6409 res = wpa_command(intf, buf);
6410
6411 if (res < 0 || res >= (int) sizeof(buf)) {
6412 send_resp(dut, conn, SIGMA_ERROR,
6413 "errorCode,FT_DS command failed");
6414 status = STATUS_SENT_ERROR;
6415 goto close_mon_conn;
6416 }
6417 } else if (wifi_chip_type == DRIVER_WCN && fastreassoc) {
Ashwini Patil4c8158f2017-05-25 12:49:21 +05306418 if (chan) {
6419 unsigned int freq;
6420
Alexei Avshalom Lazar093569f2018-11-13 14:08:17 +02006421 freq = channel_to_freq(dut, chan);
Ashwini Patil4c8158f2017-05-25 12:49:21 +05306422 if (!freq) {
6423 sigma_dut_print(dut, DUT_MSG_ERROR,
6424 "Invalid channel number provided: %d",
6425 chan);
6426 send_resp(dut, conn, SIGMA_INVALID,
6427 "ErrorCode,Invalid channel number");
6428 goto close_mon_conn;
6429 }
6430 res = snprintf(buf, sizeof(buf),
6431 "SCAN TYPE=ONLY freq=%d", freq);
6432 } else {
6433 res = snprintf(buf, sizeof(buf), "SCAN TYPE=ONLY");
6434 }
6435 if (res < 0 || res >= (int) sizeof(buf)) {
6436 send_resp(dut, conn, SIGMA_ERROR,
6437 "ErrorCode,snprintf failed");
6438 goto close_mon_conn;
6439 }
6440 if (wpa_command(intf, buf) < 0) {
6441 sigma_dut_print(dut, DUT_MSG_INFO,
6442 "Failed to start scan");
6443 send_resp(dut, conn, SIGMA_ERROR,
6444 "ErrorCode,scan failed");
6445 goto close_mon_conn;
6446 }
6447
6448 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
6449 buf, sizeof(buf));
6450 if (res < 0) {
6451 sigma_dut_print(dut, DUT_MSG_INFO,
6452 "Scan did not complete");
6453 send_resp(dut, conn, SIGMA_ERROR,
6454 "ErrorCode,scan did not complete");
6455 goto close_mon_conn;
6456 }
6457
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006458 if (set_network(intf, dut->infra_network_id, "bssid", "any")
6459 < 0) {
6460 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
6461 "bssid to any during FASTREASSOC");
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006462 status = ERROR_SEND_STATUS;
Ashwini Patil467efef2017-05-25 12:18:27 +05306463 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006464 }
Vinita Maloo54b78cf2020-03-30 12:18:19 +05306465 res = snprintf(buf, sizeof(buf), "FASTREASSOC %s %d",
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006466 bssid, chan);
Vinita Maloo54b78cf2020-03-30 12:18:19 +05306467 if (res < 0 || res >= (int) sizeof(buf) ||
6468 wcn_driver_cmd(intf, buf) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006469 send_resp(dut, conn, SIGMA_ERROR,
Vinita Maloo54b78cf2020-03-30 12:18:19 +05306470 "errorCode,Failed to run FASTREASSOC");
Ashwini Patil467efef2017-05-25 12:18:27 +05306471 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006472 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006473 sigma_dut_print(dut, DUT_MSG_INFO,
6474 "sta_reassoc: Run %s successful", buf);
6475 } else if (wpa_command(intf, "REASSOCIATE")) {
6476 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
6477 "request reassociation");
Ashwini Patil467efef2017-05-25 12:18:27 +05306478 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006479 }
6480
6481 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
6482 buf, sizeof(buf));
Ashwini Patil467efef2017-05-25 12:18:27 +05306483 if (res < 0) {
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006484 send_resp(dut, conn, SIGMA_ERROR,
6485 "errorCode,Connection did not complete");
6486 status = STATUS_SENT_ERROR;
Ashwini Patil467efef2017-05-25 12:18:27 +05306487 goto close_mon_conn;
6488 }
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006489 status = SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006490
Ashwini Patil467efef2017-05-25 12:18:27 +05306491close_mon_conn:
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006492 wpa_ctrl_detach(ctrl);
6493 wpa_ctrl_close(ctrl);
Ashwini Patil467efef2017-05-25 12:18:27 +05306494 return status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006495}
6496
6497
6498static void hs2_clear_credentials(const char *intf)
6499{
6500 wpa_command(intf, "REMOVE_CRED all");
6501}
6502
6503
Lior Davidcc88b562017-01-03 18:52:09 +02006504#ifdef __linux__
6505static int wil6210_get_aid(struct sigma_dut *dut, const char *bssid,
6506 unsigned int *aid)
6507{
Lior David0fe101e2017-03-09 16:09:50 +02006508 const char *pattern = "AID[ \t]+([0-9]+)";
Lior Davidcc88b562017-01-03 18:52:09 +02006509
Lior David0fe101e2017-03-09 16:09:50 +02006510 return wil6210_get_sta_info_field(dut, bssid, pattern, aid);
Lior Davidcc88b562017-01-03 18:52:09 +02006511}
6512#endif /* __linux__ */
6513
6514
6515static int sta_get_aid_60g(struct sigma_dut *dut, const char *bssid,
6516 unsigned int *aid)
6517{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006518 switch (get_driver_type(dut)) {
Lior Davidcc88b562017-01-03 18:52:09 +02006519#ifdef __linux__
6520 case DRIVER_WIL6210:
6521 return wil6210_get_aid(dut, bssid, aid);
6522#endif /* __linux__ */
6523 default:
6524 sigma_dut_print(dut, DUT_MSG_ERROR, "get AID not supported");
6525 return -1;
6526 }
6527}
6528
6529
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006530static int sta_get_parameter_60g(struct sigma_dut *dut, struct sigma_conn *conn,
6531 struct sigma_cmd *cmd)
6532{
6533 char buf[MAX_CMD_LEN];
6534 char bss_list[MAX_CMD_LEN];
6535 const char *parameter = get_param(cmd, "Parameter");
6536
6537 if (parameter == NULL)
6538 return -1;
6539
Lior Davidcc88b562017-01-03 18:52:09 +02006540 if (strcasecmp(parameter, "AID") == 0) {
6541 unsigned int aid = 0;
6542 char bssid[20];
6543
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006544 if (get_wpa_status(get_station_ifname(dut), "bssid",
Lior Davidcc88b562017-01-03 18:52:09 +02006545 bssid, sizeof(bssid)) < 0) {
6546 sigma_dut_print(dut, DUT_MSG_ERROR,
6547 "could not get bssid");
6548 return -2;
6549 }
6550
6551 if (sta_get_aid_60g(dut, bssid, &aid))
6552 return -2;
6553
6554 snprintf(buf, sizeof(buf), "aid,%d", aid);
6555 sigma_dut_print(dut, DUT_MSG_INFO, "%s", buf);
6556 send_resp(dut, conn, SIGMA_COMPLETE, buf);
6557 return 0;
6558 }
6559
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006560 if (strcasecmp(parameter, "DiscoveredDevList") == 0) {
6561 char *bss_line;
6562 char *bss_id = NULL;
6563 const char *ifname = get_param(cmd, "Interface");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05306564 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006565
6566 if (ifname == NULL) {
6567 sigma_dut_print(dut, DUT_MSG_INFO,
6568 "For get DiscoveredDevList need Interface name.");
6569 return -1;
6570 }
6571
6572 /*
6573 * Use "BSS RANGE=ALL MASK=0x2" which provides a list
6574 * of BSSIDs in "bssid=<BSSID>\n"
6575 */
6576 if (wpa_command_resp(ifname, "BSS RANGE=ALL MASK=0x2",
6577 bss_list,
6578 sizeof(bss_list)) < 0) {
6579 sigma_dut_print(dut, DUT_MSG_ERROR,
6580 "Failed to get bss list");
6581 return -1;
6582 }
6583
6584 sigma_dut_print(dut, DUT_MSG_DEBUG,
6585 "bss list for ifname:%s is:%s",
6586 ifname, bss_list);
6587
6588 snprintf(buf, sizeof(buf), "DeviceList");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05306589 bss_line = strtok_r(bss_list, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006590 while (bss_line) {
6591 if (sscanf(bss_line, "bssid=%ms", &bss_id) > 0 &&
6592 bss_id) {
6593 int len;
6594
6595 len = snprintf(buf + strlen(buf),
6596 sizeof(buf) - strlen(buf),
6597 ",%s", bss_id);
6598 free(bss_id);
6599 bss_id = NULL;
6600 if (len < 0) {
6601 sigma_dut_print(dut,
6602 DUT_MSG_ERROR,
6603 "Failed to read BSSID");
6604 send_resp(dut, conn, SIGMA_ERROR,
6605 "ErrorCode,Failed to read BSS ID");
6606 return 0;
6607 }
6608
6609 if ((size_t) len >= sizeof(buf) - strlen(buf)) {
6610 sigma_dut_print(dut,
6611 DUT_MSG_ERROR,
6612 "Response buf too small for list");
6613 send_resp(dut, conn,
6614 SIGMA_ERROR,
6615 "ErrorCode,Response buf too small for list");
6616 return 0;
6617 }
6618 }
6619
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05306620 bss_line = strtok_r(NULL, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006621 }
6622
6623 sigma_dut_print(dut, DUT_MSG_INFO, "DiscoveredDevList is %s",
6624 buf);
6625 send_resp(dut, conn, SIGMA_COMPLETE, buf);
6626 return 0;
6627 }
6628
6629 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
6630 return 0;
6631}
6632
6633
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07006634static int sta_get_parameter_he(struct sigma_dut *dut, struct sigma_conn *conn,
6635 struct sigma_cmd *cmd)
6636{
6637 char buf[MAX_CMD_LEN];
6638 const char *parameter = get_param(cmd, "Parameter");
6639
6640 if (!parameter)
6641 return -1;
6642
6643 if (strcasecmp(parameter, "RSSI") == 0) {
6644 char rssi[10];
6645
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006646 if (get_wpa_signal_poll(dut, get_station_ifname(dut), "RSSI",
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07006647 rssi, sizeof(rssi)) < 0) {
6648 sigma_dut_print(dut, DUT_MSG_ERROR,
6649 "Could not get RSSI");
6650 return -2;
6651 }
6652
6653 snprintf(buf, sizeof(buf), "rssi,%s", rssi);
6654 sigma_dut_print(dut, DUT_MSG_INFO, "RSSI %s", buf);
6655 send_resp(dut, conn, SIGMA_COMPLETE, buf);
6656 return 0;
6657 }
6658
6659 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
6660 return 0;
6661}
6662
6663
Jouni Malinenca0abd32020-02-09 20:18:10 +02006664static enum sigma_cmd_result sta_get_pmk(struct sigma_dut *dut,
6665 struct sigma_conn *conn,
6666 struct sigma_cmd *cmd)
6667{
6668 const char *intf = get_param(cmd, "Interface");
6669 char buf[4096], bssid[20], resp[200], *pos, *tmp;
6670
6671 snprintf(buf, sizeof(buf), "PMKSA_GET %d", dut->infra_network_id);
6672 if (wpa_command_resp(intf, buf, buf, sizeof(buf)) < 0 ||
6673 strncmp(buf, "UNKNOWN COMMAND", 15) == 0) {
6674 send_resp(dut, conn, SIGMA_ERROR,
6675 "ErrorCode,PMKSA_GET not supported");
6676 return STATUS_SENT_ERROR;
6677 }
6678
6679 if (strncmp(buf, "FAIL", 4) == 0 ||
6680 get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0) {
6681 send_resp(dut, conn, SIGMA_ERROR,
6682 "ErrorCode,Could not find current network");
6683 return STATUS_SENT_ERROR;
6684 }
6685
6686 pos = buf;
6687 while (pos) {
6688 if (strncmp(pos, bssid, 17) == 0) {
6689 pos = strchr(pos, ' ');
6690 if (!pos)
Mohammad Asaad Akram956bfc32020-04-08 16:26:18 +05306691 break;
Jouni Malinenca0abd32020-02-09 20:18:10 +02006692 pos++;
6693 pos = strchr(pos, ' ');
6694 if (!pos)
Mohammad Asaad Akram956bfc32020-04-08 16:26:18 +05306695 break;
Jouni Malinenca0abd32020-02-09 20:18:10 +02006696 pos++;
6697 tmp = strchr(pos, ' ');
6698 if (!tmp)
Mohammad Asaad Akram956bfc32020-04-08 16:26:18 +05306699 break;
Jouni Malinenca0abd32020-02-09 20:18:10 +02006700 *tmp = '\0';
6701 break;
6702 }
Jouni Malinenca0abd32020-02-09 20:18:10 +02006703 pos = strchr(pos, '\n');
6704 if (pos)
6705 pos++;
6706 }
6707
6708 if (!pos) {
6709 send_resp(dut, conn, SIGMA_ERROR,
6710 "ErrorCode,PMK not available");
6711 return STATUS_SENT_ERROR;
6712 }
6713
6714 snprintf(resp, sizeof(resp), "PMK,%s", pos);
6715 send_resp(dut, conn, SIGMA_COMPLETE, resp);
6716 return STATUS_SENT;
6717}
6718
6719
Jouni Malinenf7222712019-06-13 01:50:21 +03006720static enum sigma_cmd_result cmd_sta_get_parameter(struct sigma_dut *dut,
6721 struct sigma_conn *conn,
6722 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006723{
6724 const char *program = get_param(cmd, "Program");
Jouni Malinenca0abd32020-02-09 20:18:10 +02006725 const char *parameter = get_param(cmd, "Parameter");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006726
Jouni Malinenca0abd32020-02-09 20:18:10 +02006727 if (!parameter)
6728 return INVALID_SEND_STATUS;
6729
6730 if (strcasecmp(parameter, "PMK") == 0)
6731 return sta_get_pmk(dut, conn, cmd);
6732
6733 if (!program)
6734 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006735
6736 if (strcasecmp(program, "P2PNFC") == 0)
6737 return p2p_cmd_sta_get_parameter(dut, conn, cmd);
6738
6739 if (strcasecmp(program, "60ghz") == 0)
6740 return sta_get_parameter_60g(dut, conn, cmd);
6741
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07006742 if (strcasecmp(program, "he") == 0)
6743 return sta_get_parameter_he(dut, conn, cmd);
6744
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006745#ifdef ANDROID_NAN
6746 if (strcasecmp(program, "NAN") == 0)
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07006747 return nan_cmd_sta_get_parameter(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006748#endif /* ANDROID_NAN */
6749
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07006750#ifdef MIRACAST
6751 if (strcasecmp(program, "WFD") == 0 ||
6752 strcasecmp(program, "DisplayR2") == 0)
6753 return miracast_cmd_sta_get_parameter(dut, conn, cmd);
6754#endif /* MIRACAST */
6755
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006756 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
6757 return 0;
6758}
6759
6760
6761static void sta_reset_default_ath(struct sigma_dut *dut, const char *intf,
6762 const char *type)
6763{
6764 char buf[100];
6765
6766 if (dut->program == PROGRAM_VHT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006767 run_iwpriv(dut, intf, "chwidth 2");
6768 run_iwpriv(dut, intf, "mode 11ACVHT80");
6769 run_iwpriv(dut, intf, "vhtmcs -1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006770 }
6771
6772 if (dut->program == PROGRAM_HT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006773 run_iwpriv(dut, intf, "chwidth 0");
6774 run_iwpriv(dut, intf, "mode 11naht40");
6775 run_iwpriv(dut, intf, "set11NRates 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006776 }
6777
6778 if (dut->program == PROGRAM_VHT || dut->program == PROGRAM_HT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006779 run_iwpriv(dut, intf, "powersave 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006780
6781 /* Reset CTS width */
6782 snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 54 0",
6783 intf);
6784 if (system(buf) != 0) {
6785 sigma_dut_print(dut, DUT_MSG_ERROR,
6786 "wifitool %s beeliner_fw_test 54 0 failed",
6787 intf);
6788 }
6789
6790 /* Enable Dynamic Bandwidth signalling by default */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006791 run_iwpriv(dut, intf, "cwmenable 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006792
6793 snprintf(buf, sizeof(buf), "iwconfig %s rts 2347", intf);
6794 if (system(buf) != 0) {
6795 sigma_dut_print(dut, DUT_MSG_ERROR,
6796 "iwpriv rts failed");
6797 }
6798 }
6799
6800 if (type && strcasecmp(type, "Testbed") == 0) {
6801 dut->testbed_flag_txsp = 1;
6802 dut->testbed_flag_rxsp = 1;
6803 /* STA has to set spatial stream to 2 per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006804 run_iwpriv(dut, intf, "vht_mcsmap 0xfff0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006805
6806 /* Disable LDPC per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006807 run_iwpriv(dut, intf, "ldpc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006808
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006809 run_iwpriv(dut, intf, "amsdu 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006810
6811 /* TODO: Disable STBC 2x1 transmit and receive */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006812 run_iwpriv(dut, intf, "tx_stbc 0");
6813 run_iwpriv(dut, intf, "rx_stbc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006814
6815 /* STA has to disable Short GI per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006816 run_iwpriv(dut, intf, "shortgi 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006817 }
6818
6819 if (type && strcasecmp(type, "DUT") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006820 run_iwpriv(dut, intf, "nss 3");
Arif Hussainac6c5112018-05-25 17:34:00 -07006821 dut->sta_nss = 3;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006822
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006823 run_iwpriv(dut, intf, "shortgi 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006824 }
6825}
6826
6827
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08006828#ifdef NL80211_SUPPORT
6829static int sta_set_he_mcs(struct sigma_dut *dut, const char *intf,
6830 enum he_mcs_config mcs)
6831{
6832 struct nl_msg *msg;
6833 int ret = 0;
6834 struct nlattr *params;
6835 int ifindex;
6836
6837 ifindex = if_nametoindex(intf);
6838 if (ifindex == 0) {
6839 sigma_dut_print(dut, DUT_MSG_ERROR,
6840 "%s: Index for interface %s failed",
6841 __func__, intf);
6842 return -1;
6843 }
6844
6845 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6846 NL80211_CMD_VENDOR)) ||
6847 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6848 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6849 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6850 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6851 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6852 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MCS,
6853 mcs)) {
6854 sigma_dut_print(dut, DUT_MSG_ERROR,
6855 "%s: err in adding vendor_cmd and vendor_data",
6856 __func__);
6857 nlmsg_free(msg);
6858 return -1;
6859 }
6860 nla_nest_end(msg, params);
6861
6862 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6863 if (ret) {
6864 sigma_dut_print(dut, DUT_MSG_ERROR,
6865 "%s: err in send_and_recv_msgs, ret=%d",
6866 __func__, ret);
6867 }
6868 return ret;
6869}
6870#endif /* NL80211_SUPPORT */
6871
6872
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07006873static int sta_set_action_tx_in_he_tb_ppdu(struct sigma_dut *dut,
6874 const char *intf, int enable)
6875{
6876#ifdef NL80211_SUPPORT
6877 struct nl_msg *msg;
6878 int ret = 0;
6879 struct nlattr *params;
6880 int ifindex;
6881
6882 ifindex = if_nametoindex(intf);
6883 if (ifindex == 0) {
6884 sigma_dut_print(dut, DUT_MSG_ERROR,
6885 "%s: Index for interface %s failed",
6886 __func__, intf);
6887 return -1;
6888 }
6889
6890 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6891 NL80211_CMD_VENDOR)) ||
6892 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6893 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6894 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6895 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6896 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6897 nla_put_u8(msg,
6898 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_ACTION_TX_TB_PPDU,
6899 enable)) {
6900 sigma_dut_print(dut, DUT_MSG_ERROR,
6901 "%s: err in adding vendor_cmd and vendor_data",
6902 __func__);
6903 nlmsg_free(msg);
6904 return -1;
6905 }
6906 nla_nest_end(msg, params);
6907
6908 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6909 if (ret) {
6910 sigma_dut_print(dut, DUT_MSG_ERROR,
6911 "%s: err in send_and_recv_msgs, ret=%d",
6912 __func__, ret);
6913 }
6914 return ret;
6915#else /* NL80211_SUPPORT */
6916 sigma_dut_print(dut, DUT_MSG_ERROR,
6917 "HE action Tx TB PPDU cannot be set without NL80211_SUPPORT defined");
6918 return -1;
6919#endif /* NL80211_SUPPORT */
6920}
6921
6922
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08006923static int sta_set_heconfig_and_wep_tkip(struct sigma_dut *dut,
6924 const char *intf, int enable)
6925{
6926#ifdef NL80211_SUPPORT
6927 struct nl_msg *msg;
6928 int ret = 0;
6929 struct nlattr *params;
6930 int ifindex;
6931
6932 ifindex = if_nametoindex(intf);
6933 if (ifindex == 0) {
6934 sigma_dut_print(dut, DUT_MSG_ERROR,
6935 "%s: Index for interface %s failed",
6936 __func__, intf);
6937 return -1;
6938 }
6939
6940 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6941 NL80211_CMD_VENDOR)) ||
6942 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6943 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6944 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6945 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6946 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6947 nla_put_u8(msg,
6948 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WEP_TKIP_IN_HE,
6949 enable)) {
6950 sigma_dut_print(dut, DUT_MSG_ERROR,
6951 "%s: err in adding vendor_cmd and vendor_data",
6952 __func__);
6953 nlmsg_free(msg);
6954 return -1;
6955 }
6956 nla_nest_end(msg, params);
6957
6958 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6959 if (ret) {
6960 sigma_dut_print(dut, DUT_MSG_ERROR,
6961 "%s: err in send_and_recv_msgs, ret=%d",
6962 __func__, ret);
6963 }
6964 return ret;
6965#else /* NL80211_SUPPORT */
6966 sigma_dut_print(dut, DUT_MSG_ERROR,
6967 "HE config enablement cannot be changed without NL80211_SUPPORT defined");
6968 return -1;
6969#endif /* NL80211_SUPPORT */
6970}
6971
6972
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08006973#ifdef NL80211_SUPPORT
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08006974
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08006975static int sta_set_he_testbed_def(struct sigma_dut *dut,
6976 const char *intf, int cfg)
6977{
6978 struct nl_msg *msg;
6979 int ret = 0;
6980 struct nlattr *params;
6981 int ifindex;
6982
6983 ifindex = if_nametoindex(intf);
6984 if (ifindex == 0) {
6985 sigma_dut_print(dut, DUT_MSG_ERROR,
6986 "%s: Index for interface %s failed",
6987 __func__, intf);
6988 return -1;
6989 }
6990
6991 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6992 NL80211_CMD_VENDOR)) ||
6993 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6994 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6995 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6996 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6997 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6998 nla_put_u8(msg,
6999 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_SET_HE_TESTBED_DEFAULTS,
7000 cfg)) {
7001 sigma_dut_print(dut, DUT_MSG_ERROR,
7002 "%s: err in adding vendor_cmd and vendor_data",
7003 __func__);
7004 nlmsg_free(msg);
7005 return -1;
7006 }
7007 nla_nest_end(msg, params);
7008
7009 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7010 if (ret) {
7011 sigma_dut_print(dut, DUT_MSG_ERROR,
7012 "%s: err in send_and_recv_msgs, ret=%d",
7013 __func__, ret);
7014 }
7015 return ret;
7016}
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08007017
7018
7019static int sta_set_2g_vht_supp(struct sigma_dut *dut, const char *intf, int cfg)
7020{
7021 struct nl_msg *msg;
7022 int ret = 0;
7023 struct nlattr *params;
7024 int ifindex;
7025
7026 ifindex = if_nametoindex(intf);
7027 if (ifindex == 0) {
7028 sigma_dut_print(dut, DUT_MSG_ERROR,
7029 "%s: Index for interface %s failed",
7030 __func__, intf);
7031 return -1;
7032 }
7033
7034 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7035 NL80211_CMD_VENDOR)) ||
7036 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7037 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7038 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7039 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7040 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7041 nla_put_u8(msg,
7042 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_2G_VHT,
7043 cfg)) {
7044 sigma_dut_print(dut, DUT_MSG_ERROR,
7045 "%s: err in adding vendor_cmd and vendor_data",
7046 __func__);
7047 nlmsg_free(msg);
7048 return -1;
7049 }
7050 nla_nest_end(msg, params);
7051
7052 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7053 if (ret) {
7054 sigma_dut_print(dut, DUT_MSG_ERROR,
7055 "%s: err in send_and_recv_msgs, ret=%d",
7056 __func__, ret);
7057 }
7058 return ret;
7059}
7060
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08007061#endif /* NL80211_SUPPORT */
7062
7063
Qiwei Caib6806972020-01-15 13:52:11 +08007064int sta_set_addba_buf_size(struct sigma_dut *dut,
7065 const char *intf, int bufsize)
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08007066{
7067#ifdef NL80211_SUPPORT
7068 struct nl_msg *msg;
7069 int ret = 0;
7070 struct nlattr *params;
7071 int ifindex;
7072
7073 ifindex = if_nametoindex(intf);
7074 if (ifindex == 0) {
7075 sigma_dut_print(dut, DUT_MSG_ERROR,
7076 "%s: Index for interface %s failed",
7077 __func__, intf);
7078 return -1;
7079 }
7080
7081 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7082 NL80211_CMD_VENDOR)) ||
7083 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7084 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7085 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7086 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7087 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
Kiran Kumar Lokere26e27582018-08-01 16:18:34 -07007088 nla_put_u16(msg,
7089 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE,
7090 bufsize)) {
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08007091 sigma_dut_print(dut, DUT_MSG_ERROR,
7092 "%s: err in adding vendor_cmd and vendor_data",
7093 __func__);
7094 nlmsg_free(msg);
7095 return -1;
7096 }
7097 nla_nest_end(msg, params);
7098
7099 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7100 if (ret) {
7101 sigma_dut_print(dut, DUT_MSG_ERROR,
7102 "%s: err in send_and_recv_msgs, ret=%d",
7103 __func__, ret);
7104 }
7105 return ret;
7106#else /* NL80211_SUPPORT */
7107 sigma_dut_print(dut, DUT_MSG_ERROR,
7108 "AddBA bufsize cannot be changed without NL80211_SUPPORT defined");
7109 return -1;
7110#endif /* NL80211_SUPPORT */
7111}
7112
7113
Arif Hussain8d5b27b2018-05-14 14:31:03 -07007114static int sta_set_tx_beamformee(struct sigma_dut *dut, const char *intf,
7115 int enable)
7116{
7117#ifdef NL80211_SUPPORT
7118 struct nl_msg *msg;
7119 int ret = 0;
7120 struct nlattr *params;
7121 int ifindex;
7122
7123 ifindex = if_nametoindex(intf);
7124 if (ifindex == 0) {
7125 sigma_dut_print(dut, DUT_MSG_ERROR,
7126 "%s: Index for interface %s failed",
7127 __func__, intf);
7128 return -1;
7129 }
7130
7131 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7132 NL80211_CMD_VENDOR)) ||
7133 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7134 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7135 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7136 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7137 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7138 nla_put_u8(msg,
7139 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_TX_BEAMFORMEE,
7140 enable)) {
7141 sigma_dut_print(dut, DUT_MSG_ERROR,
7142 "%s: err in adding vendor_cmd and vendor_data",
7143 __func__);
7144 nlmsg_free(msg);
7145 return -1;
7146 }
7147 nla_nest_end(msg, params);
7148
7149 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7150 if (ret) {
7151 sigma_dut_print(dut, DUT_MSG_ERROR,
7152 "%s: err in send_and_recv_msgs, ret=%d",
7153 __func__, ret);
7154 }
7155 return ret;
7156#else /* NL80211_SUPPORT */
7157 sigma_dut_print(dut, DUT_MSG_ERROR,
7158 "tx beamformee cannot be changed without NL80211_SUPPORT defined");
7159 return -1;
7160#endif /* NL80211_SUPPORT */
7161}
7162
7163
Arif Hussain9765f7d2018-07-03 08:28:26 -07007164static int sta_set_beamformee_sts(struct sigma_dut *dut, const char *intf,
7165 int val)
7166{
7167#ifdef NL80211_SUPPORT
7168 struct nl_msg *msg;
7169 int ret = 0;
7170 struct nlattr *params;
7171 int ifindex;
7172
7173 ifindex = if_nametoindex(intf);
7174 if (ifindex == 0) {
7175 sigma_dut_print(dut, DUT_MSG_ERROR,
7176 "%s: Index for interface %s failed, val:%d",
7177 __func__, intf, val);
7178 return -1;
7179 }
7180
7181 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7182 NL80211_CMD_VENDOR)) ||
7183 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7184 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7185 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7186 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7187 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7188 nla_put_u8(msg,
7189 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_BEAMFORMEE_NSTS,
7190 val)) {
7191 sigma_dut_print(dut, DUT_MSG_ERROR,
7192 "%s: err in adding vendor_cmd and vendor_data, val: %d",
7193 __func__, val);
7194 nlmsg_free(msg);
7195 return -1;
7196 }
7197 nla_nest_end(msg, params);
7198
7199 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7200 if (ret) {
7201 sigma_dut_print(dut, DUT_MSG_ERROR,
7202 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
7203 __func__, ret, val);
7204 }
7205 return ret;
7206#else /* NL80211_SUPPORT */
7207 sigma_dut_print(dut, DUT_MSG_ERROR,
7208 "beamformee sts cannot be changed without NL80211_SUPPORT defined");
7209 return -1;
7210#endif /* NL80211_SUPPORT */
7211}
7212
7213
Arif Hussain68d23f52018-07-11 13:39:08 -07007214#ifdef NL80211_SUPPORT
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07007215static int sta_set_mac_padding_duration(struct sigma_dut *dut, const char *intf,
7216 enum qca_wlan_he_mac_padding_dur val)
7217{
Arif Hussain68d23f52018-07-11 13:39:08 -07007218 struct nl_msg *msg;
7219 int ret = 0;
7220 struct nlattr *params;
7221 int ifindex;
7222
7223 ifindex = if_nametoindex(intf);
7224 if (ifindex == 0) {
7225 sigma_dut_print(dut, DUT_MSG_ERROR,
7226 "%s: Index for interface %s failed, val:%d",
7227 __func__, intf, val);
7228 return -1;
7229 }
7230
7231 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7232 NL80211_CMD_VENDOR)) ||
7233 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7234 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7235 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7236 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7237 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7238 nla_put_u8(msg,
7239 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MAC_PADDING_DUR,
7240 val)) {
7241 sigma_dut_print(dut, DUT_MSG_ERROR,
7242 "%s: err in adding vendor_cmd and vendor_data, val: %d",
7243 __func__, val);
7244 nlmsg_free(msg);
7245 return -1;
7246 }
7247 nla_nest_end(msg, params);
7248
7249 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7250 if (ret) {
7251 sigma_dut_print(dut, DUT_MSG_ERROR,
7252 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
7253 __func__, ret, val);
7254 }
7255 return ret;
Arif Hussain68d23f52018-07-11 13:39:08 -07007256}
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07007257#endif /* NL80211_SUPPORT */
Arif Hussain68d23f52018-07-11 13:39:08 -07007258
7259
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07007260static int sta_set_tx_su_ppdu_cfg(struct sigma_dut *dut, const char *intf,
7261 int val)
7262{
7263#ifdef NL80211_SUPPORT
7264 struct nl_msg *msg;
7265 int ret = 0;
7266 struct nlattr *params;
7267 int ifindex;
7268
7269 ifindex = if_nametoindex(intf);
7270 if (ifindex == 0) {
7271 sigma_dut_print(dut, DUT_MSG_ERROR,
7272 "%s: Index for interface %s failed, val:%d",
7273 __func__, intf, val);
7274 return -1;
7275 }
7276
7277 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7278 NL80211_CMD_VENDOR)) ||
7279 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7280 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7281 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7282 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7283 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7284 nla_put_u8(msg,
7285 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_SUPPDU,
7286 val)) {
7287 sigma_dut_print(dut, DUT_MSG_ERROR,
7288 "%s: err in adding vendor_cmd and vendor_data, val: %d",
7289 __func__, val);
7290 nlmsg_free(msg);
7291 return -1;
7292 }
7293 nla_nest_end(msg, params);
7294
7295 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7296 if (ret) {
7297 sigma_dut_print(dut, DUT_MSG_ERROR,
7298 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
7299 __func__, ret, val);
7300 }
7301 return ret;
7302#else /* NL80211_SUPPORT */
7303 sigma_dut_print(dut, DUT_MSG_ERROR,
7304 "Tx SU PPDU cannot be set without NL80211_SUPPORT defined");
7305 return -1;
7306#endif /* NL80211_SUPPORT */
7307}
7308
7309
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07007310#ifdef NL80211_SUPPORT
7311static int sta_set_he_om_ctrl_reset(struct sigma_dut *dut, const char *intf)
7312{
7313 struct nl_msg *msg;
7314 int ret = 0;
7315 struct nlattr *params;
7316 int ifindex;
7317
7318 ifindex = if_nametoindex(intf);
7319 if (ifindex == 0) {
7320 sigma_dut_print(dut, DUT_MSG_ERROR,
7321 "%s: Index for interface %s failed",
7322 __func__, intf);
7323 return -1;
7324 }
7325
7326 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7327 NL80211_CMD_VENDOR)) ||
7328 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7329 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7330 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7331 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7332 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7333 nla_put_flag(msg,
7334 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_CLEAR_HE_OM_CTRL_CONFIG)) {
7335 sigma_dut_print(dut, DUT_MSG_ERROR,
7336 "%s: err in adding vendor_cmd and vendor_data",
7337 __func__);
7338 nlmsg_free(msg);
7339 return -1;
7340 }
7341 nla_nest_end(msg, params);
7342
7343 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7344 if (ret) {
7345 sigma_dut_print(dut, DUT_MSG_ERROR,
7346 "%s: err in send_and_recv_msgs, ret=%d",
7347 __func__, ret);
7348 }
7349 return ret;
7350}
7351#endif /* NL80211_SUPPORT */
7352
7353
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07007354static int sta_set_mu_edca_override(struct sigma_dut *dut, const char *intf,
7355 int val)
7356{
7357#ifdef NL80211_SUPPORT
7358 struct nl_msg *msg;
7359 int ret = 0;
7360 struct nlattr *params;
7361 int ifindex;
7362
7363 ifindex = if_nametoindex(intf);
7364 if (ifindex == 0) {
7365 sigma_dut_print(dut, DUT_MSG_ERROR,
7366 "%s: Index for interface %s failed, val:%d",
7367 __func__, intf, val);
7368 return -1;
7369 }
7370
7371 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7372 NL80211_CMD_VENDOR)) ||
7373 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7374 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7375 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7376 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7377 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7378 nla_put_u8(msg,
7379 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_OVERRIDE_MU_EDCA,
7380 val)) {
7381 sigma_dut_print(dut, DUT_MSG_ERROR,
7382 "%s: err in adding vendor_cmd and vendor_data, val: %d",
7383 __func__, val);
7384 nlmsg_free(msg);
7385 return -1;
7386 }
7387 nla_nest_end(msg, params);
7388
7389 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7390 if (ret) {
7391 sigma_dut_print(dut, DUT_MSG_ERROR,
7392 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
7393 __func__, ret, val);
7394 }
7395 return ret;
7396#else /* NL80211_SUPPORT */
7397 sigma_dut_print(dut, DUT_MSG_ERROR,
7398 "MU EDCA override cannot be changed without NL80211_SUPPORT defined");
7399 return -1;
7400#endif /* NL80211_SUPPORT */
7401}
7402
7403
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07007404static int sta_set_om_ctrl_supp(struct sigma_dut *dut, const char *intf,
7405 int val)
7406{
7407#ifdef NL80211_SUPPORT
7408 struct nl_msg *msg;
7409 int ret = 0;
7410 struct nlattr *params;
7411 int ifindex;
7412
7413 ifindex = if_nametoindex(intf);
7414 if (ifindex == 0) {
7415 sigma_dut_print(dut, DUT_MSG_ERROR,
7416 "%s: Index for interface %s failed, val:%d",
7417 __func__, intf, val);
7418 return -1;
7419 }
7420
7421 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7422 NL80211_CMD_VENDOR)) ||
7423 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7424 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7425 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7426 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7427 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7428 nla_put_u8(msg,
7429 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OM_CTRL_SUPP,
7430 val)) {
7431 sigma_dut_print(dut, DUT_MSG_ERROR,
7432 "%s: err in adding vendor_cmd and vendor_data, val: %d",
7433 __func__, val);
7434 nlmsg_free(msg);
7435 return -1;
7436 }
7437 nla_nest_end(msg, params);
7438
7439 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7440 if (ret) {
7441 sigma_dut_print(dut, DUT_MSG_ERROR,
7442 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
7443 __func__, ret, val);
7444 }
7445 return ret;
7446#else /* NL80211_SUPPORT */
7447 sigma_dut_print(dut, DUT_MSG_ERROR,
7448 "HE OM ctrl cannot be changed without NL80211_SUPPORT defined");
7449 return -1;
7450#endif /* NL80211_SUPPORT */
7451}
7452
7453
Arif Hussain480d5f42019-03-12 14:40:42 -07007454static int sta_set_twt_req_support(struct sigma_dut *dut, const char *intf,
7455 int val)
7456{
7457#ifdef NL80211_SUPPORT
7458 struct nl_msg *msg;
7459 int ret;
7460 struct nlattr *params;
7461 int ifindex;
7462
7463 ifindex = if_nametoindex(intf);
7464 if (ifindex == 0) {
7465 sigma_dut_print(dut, DUT_MSG_ERROR,
7466 "%s: Index for interface %s failed, val:%d",
7467 __func__, intf, val);
7468 return -1;
7469 }
7470
7471 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7472 NL80211_CMD_VENDOR)) ||
7473 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7474 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7475 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7476 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7477 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7478 nla_put_u8(msg,
7479 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TWT_REQ_SUPPORT,
7480 val)) {
7481 sigma_dut_print(dut, DUT_MSG_ERROR,
7482 "%s: err in adding vendor_cmd and vendor_data, val: %d",
7483 __func__, val);
7484 nlmsg_free(msg);
7485 return -1;
7486 }
7487 nla_nest_end(msg, params);
7488
7489 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7490 if (ret) {
7491 sigma_dut_print(dut, DUT_MSG_ERROR,
7492 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
7493 __func__, ret, val);
7494 }
7495 return ret;
7496#else /* NL80211_SUPPORT */
7497 sigma_dut_print(dut, DUT_MSG_ERROR,
7498 "TWT Request cannot be changed without NL80211_SUPPORT defined");
7499 return -1;
7500#endif /* NL80211_SUPPORT */
7501}
7502
7503
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08007504static void sta_reset_default_wcn(struct sigma_dut *dut, const char *intf,
7505 const char *type)
7506{
7507 char buf[60];
7508
7509 if (dut->program == PROGRAM_HE) {
7510 /* resetting phymode to auto in case of HE program */
7511 snprintf(buf, sizeof(buf), "iwpriv %s setphymode 0", intf);
7512 if (system(buf) != 0) {
7513 sigma_dut_print(dut, DUT_MSG_ERROR,
7514 "iwpriv %s setphymode failed", intf);
7515 }
7516
Amarnath Hullur Subramanyam9cecb502018-04-25 13:26:30 -07007517 /* reset the rate to Auto rate */
7518 snprintf(buf, sizeof(buf), "iwpriv %s set_11ax_rate 0xff",
7519 intf);
7520 if (system(buf) != 0) {
7521 sigma_dut_print(dut, DUT_MSG_ERROR,
7522 "iwpriv %s set_11ax_rate 0xff failed",
7523 intf);
7524 }
7525
Kiran Kumar Lokere86cfe3a2018-06-01 11:55:15 -07007526 /* reset the LDPC setting */
7527 snprintf(buf, sizeof(buf), "iwpriv %s ldpc 1", intf);
7528 if (system(buf) != 0) {
7529 sigma_dut_print(dut, DUT_MSG_ERROR,
7530 "iwpriv %s ldpc 1 failed", intf);
7531 }
7532
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08007533 /* reset the power save setting */
Vinita S. Malooa8b62722020-04-23 01:45:41 +05307534 set_power_save_wcn(dut, intf, 2);
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08007535
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08007536 /* remove all network profiles */
7537 remove_wpa_networks(intf);
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08007538
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08007539 /* Configure ADDBA Req/Rsp buffer size to be 64 */
7540 sta_set_addba_buf_size(dut, intf, 64);
7541
Amarnath Hullur Subramanyam5f32d572018-03-02 00:02:33 -08007542#ifdef NL80211_SUPPORT
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08007543 /* Reset the device HE capabilities to its default supported
7544 * configuration. */
7545 sta_set_he_testbed_def(dut, intf, 0);
7546
Amarnath Hullur Subramanyam5f32d572018-03-02 00:02:33 -08007547 /* Disable noackpolicy for all AC */
7548 if (nlvendor_sta_set_noack(dut, intf, 0, QCA_WLAN_AC_ALL)) {
7549 sigma_dut_print(dut, DUT_MSG_ERROR,
7550 "Disable of noackpolicy for all AC failed");
7551 }
7552#endif /* NL80211_SUPPORT */
7553
Amarnath Hullur Subramanyamb1724a52018-03-07 14:31:46 -08007554 /* Enable WMM by default */
7555 if (wcn_sta_set_wmm(dut, intf, "on")) {
7556 sigma_dut_print(dut, DUT_MSG_ERROR,
7557 "Enable of WMM in sta_reset_default_wcn failed");
7558 }
7559
7560 /* Disable ADDBA_REJECT by default */
7561 if (nlvendor_sta_set_addba_reject(dut, intf, 0)) {
7562 sigma_dut_print(dut, DUT_MSG_ERROR,
7563 "Disable of addba_reject in sta_reset_default_wcn failed");
7564 }
7565
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08007566 /* Enable sending of ADDBA by default */
7567 if (nlvendor_config_send_addba(dut, intf, 1)) {
7568 sigma_dut_print(dut, DUT_MSG_ERROR,
7569 "Enable sending of ADDBA in sta_reset_default_wcn failed");
7570 }
7571
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08007572 /* Enable AMPDU by default */
7573 iwpriv_sta_set_ampdu(dut, intf, 1);
7574
Subhani Shaik8e7a3052018-04-24 14:03:00 -07007575#ifdef NL80211_SUPPORT
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -08007576 if (wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_AUTO)) {
Subhani Shaik8e7a3052018-04-24 14:03:00 -07007577 sigma_dut_print(dut, DUT_MSG_ERROR,
7578 "Set LTF config to default in sta_reset_default_wcn failed");
7579 }
Arif Hussain9765f7d2018-07-03 08:28:26 -07007580
Kiran Kumar Lokerebad51122018-12-12 19:03:36 -08007581 /* set the beamformee NSTS(maximum number of
7582 * space-time streams) to default DUT config
7583 */
7584 if (sta_set_beamformee_sts(dut, intf, 7)) {
Arif Hussain9765f7d2018-07-03 08:28:26 -07007585 sigma_dut_print(dut, DUT_MSG_ERROR,
7586 "Failed to set BeamformeeSTS");
7587 }
Arif Hussain68d23f52018-07-11 13:39:08 -07007588
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07007589 if (sta_set_mac_padding_duration(
7590 dut, intf,
7591 QCA_WLAN_HE_NO_ADDITIONAL_PROCESS_TIME)) {
Arif Hussain68d23f52018-07-11 13:39:08 -07007592 sigma_dut_print(dut, DUT_MSG_ERROR,
7593 "Failed to set MAC padding duration");
7594 }
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07007595
7596 if (sta_set_mu_edca_override(dut, intf, 0)) {
7597 sigma_dut_print(dut, DUT_MSG_ERROR,
7598 "ErrorCode,Failed to set MU EDCA override disable");
7599 }
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07007600
7601 if (sta_set_om_ctrl_supp(dut, intf, 1)) {
7602 sigma_dut_print(dut, DUT_MSG_ERROR,
7603 "Failed to set OM ctrl supp");
7604 }
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07007605
7606 if (sta_set_tx_su_ppdu_cfg(dut, intf, 1)) {
7607 sigma_dut_print(dut, DUT_MSG_ERROR,
7608 "Failed to set Tx SU PPDU enable");
7609 }
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07007610
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07007611 if (sta_set_action_tx_in_he_tb_ppdu(dut, intf, 0)) {
7612 sigma_dut_print(dut, DUT_MSG_ERROR,
7613 "failed to send TB PPDU Tx cfg");
7614 }
7615
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07007616 if (sta_set_he_om_ctrl_reset(dut, intf)) {
7617 sigma_dut_print(dut, DUT_MSG_ERROR,
7618 "Failed to set OM ctrl reset");
7619 }
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08007620
7621 /* +HTC-HE support default on */
7622 if (sta_set_he_htc_supp(dut, intf, 1)) {
7623 sigma_dut_print(dut, DUT_MSG_ERROR,
7624 "Setting of +HTC-HE support failed");
7625 }
Subhani Shaik8e7a3052018-04-24 14:03:00 -07007626#endif /* NL80211_SUPPORT */
7627
Arif Hussain8d5b27b2018-05-14 14:31:03 -07007628 if (sta_set_tx_beamformee(dut, intf, 1)) {
7629 sigma_dut_print(dut, DUT_MSG_ERROR,
7630 "Set tx beamformee enable by default in sta_reset_default_wcn failed");
7631 }
7632
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08007633 /* Set nss to 1 and MCS 0-7 in case of testbed */
7634 if (type && strcasecmp(type, "Testbed") == 0) {
7635#ifdef NL80211_SUPPORT
7636 int ret;
7637#endif /* NL80211_SUPPORT */
7638
7639 snprintf(buf, sizeof(buf), "iwpriv %s nss 1", intf);
7640 if (system(buf) != 0) {
7641 sigma_dut_print(dut, DUT_MSG_ERROR,
7642 "iwpriv %s nss failed", intf);
7643 }
7644
7645#ifdef NL80211_SUPPORT
7646 ret = sta_set_he_mcs(dut, intf, HE_80_MCS0_7);
7647 if (ret) {
7648 sigma_dut_print(dut, DUT_MSG_ERROR,
7649 "Setting of MCS failed, ret:%d",
7650 ret);
7651 }
7652#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyamc67621d2018-02-04 23:18:01 -08007653
7654 /* Disable STBC as default */
7655 wcn_sta_set_stbc(dut, intf, "0");
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08007656
7657 /* Disable AMSDU as default */
7658 iwpriv_sta_set_amsdu(dut, intf, "0");
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08007659
7660#ifdef NL80211_SUPPORT
7661 /* HE fragmentation default off */
7662 if (sta_set_he_fragmentation(dut, intf,
7663 HE_FRAG_DISABLE)) {
7664 sigma_dut_print(dut, DUT_MSG_ERROR,
7665 "Setting of HE fragmentation failed");
7666 }
Kiran Kumar Lokerebad51122018-12-12 19:03:36 -08007667
7668 /* set the beamformee NSTS(maximum number of
7669 * space-time streams) to default testbed config
7670 */
7671 if (sta_set_beamformee_sts(dut, intf, 3)) {
7672 sigma_dut_print(dut, DUT_MSG_ERROR,
7673 "Failed to set BeamformeeSTS");
7674 }
7675
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08007676 /* +HTC-HE support default off */
7677 if (sta_set_he_htc_supp(dut, intf, 0)) {
7678 sigma_dut_print(dut, DUT_MSG_ERROR,
7679 "Setting of +HTC-HE support failed");
7680 }
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08007681
7682 /* Set device HE capabilities to testbed default
7683 * configuration. */
7684 if (sta_set_he_testbed_def(dut, intf, 1)) {
7685 sigma_dut_print(dut, DUT_MSG_DEBUG,
7686 "Failed to set HE defaults");
7687 }
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08007688
7689 /* Disable VHT support in 2.4 GHz for testbed */
7690 sta_set_2g_vht_supp(dut, intf, 0);
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08007691#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08007692
7693 /* Enable WEP/TKIP with HE capability in testbed */
7694 if (sta_set_heconfig_and_wep_tkip(dut, intf, 1)) {
7695 sigma_dut_print(dut, DUT_MSG_ERROR,
7696 "Enabling HE config with WEP/TKIP failed");
7697 }
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08007698 }
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08007699
7700 /* Defaults in case of DUT */
7701 if (type && strcasecmp(type, "DUT") == 0) {
Arif Hussaind48fcc72018-05-01 18:34:18 -07007702 /* Enable STBC by default */
7703 wcn_sta_set_stbc(dut, intf, "1");
7704
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08007705 /* set nss to 2 */
7706 snprintf(buf, sizeof(buf), "iwpriv %s nss 2", intf);
7707 if (system(buf) != 0) {
7708 sigma_dut_print(dut, DUT_MSG_ERROR,
7709 "iwpriv %s nss 2 failed", intf);
7710 }
Arif Hussainac6c5112018-05-25 17:34:00 -07007711 dut->sta_nss = 2;
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08007712
7713#ifdef NL80211_SUPPORT
Arif Hussainae239842018-05-01 18:20:05 -07007714 /* Set HE_MCS to 0-11 */
7715 if (sta_set_he_mcs(dut, intf, HE_80_MCS0_11)) {
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08007716 sigma_dut_print(dut, DUT_MSG_ERROR,
7717 "Setting of MCS failed");
7718 }
7719#endif /* NL80211_SUPPORT */
7720
7721 /* Disable WEP/TKIP with HE capability in DUT */
7722 if (sta_set_heconfig_and_wep_tkip(dut, intf, 0)) {
7723 sigma_dut_print(dut, DUT_MSG_ERROR,
7724 "Enabling HE config with WEP/TKIP failed");
7725 }
7726 }
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08007727 }
7728}
7729
7730
Jouni Malinenf7222712019-06-13 01:50:21 +03007731static enum sigma_cmd_result cmd_sta_reset_default(struct sigma_dut *dut,
7732 struct sigma_conn *conn,
7733 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007734{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007735 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007736 const char *band = get_param(cmd, "band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007737 const char *type;
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07007738 const char *program = get_param(cmd, "program");
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05307739 const char *dev_role = get_param(cmd, "DevRole");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007740
Jouni Malinenb21f0542019-11-04 17:53:38 +02007741 if (dut->station_ifname_2g &&
7742 strcmp(dut->station_ifname_2g, intf) == 0)
7743 dut->use_5g = 0;
7744 else if (dut->station_ifname_5g &&
7745 strcmp(dut->station_ifname_5g, intf) == 0)
7746 dut->use_5g = 1;
7747
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07007748 if (!program)
7749 program = get_param(cmd, "prog");
7750 dut->program = sigma_program_to_enum(program);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007751 dut->device_type = STA_unknown;
7752 type = get_param(cmd, "type");
7753 if (type && strcasecmp(type, "Testbed") == 0)
7754 dut->device_type = STA_testbed;
7755 if (type && strcasecmp(type, "DUT") == 0)
7756 dut->device_type = STA_dut;
7757
7758 if (dut->program == PROGRAM_TDLS) {
7759 /* Clear TDLS testing mode */
7760 wpa_command(intf, "SET tdls_disabled 0");
7761 wpa_command(intf, "SET tdls_testing 0");
7762 dut->no_tpk_expiration = 0;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007763 if (get_driver_type(dut) == DRIVER_WCN) {
Pradeep Reddy POTTETI8ce2a232016-10-28 12:17:32 +05307764 /* Enable the WCN driver in TDLS Explicit trigger mode
7765 */
7766 wpa_command(intf, "SET tdls_external_control 0");
7767 wpa_command(intf, "SET tdls_trigger_control 0");
7768 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007769 }
7770
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07007771#ifdef MIRACAST
7772 if (dut->program == PROGRAM_WFD ||
7773 dut->program == PROGRAM_DISPLAYR2)
7774 miracast_sta_reset_default(dut, conn, cmd);
7775#endif /* MIRACAST */
7776
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007777 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007778 case DRIVER_ATHEROS:
7779 sta_reset_default_ath(dut, intf, type);
7780 break;
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08007781 case DRIVER_WCN:
7782 sta_reset_default_wcn(dut, intf, type);
7783 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007784 default:
7785 break;
7786 }
7787
7788#ifdef ANDROID_NAN
7789 if (dut->program == PROGRAM_NAN)
7790 nan_cmd_sta_reset_default(dut, conn, cmd);
7791#endif /* ANDROID_NAN */
7792
Vinay Gannevaram3b9fdd32019-06-14 17:55:44 +05307793 if (dut->program == PROGRAM_LOC &&
7794 lowi_cmd_sta_reset_default(dut, conn, cmd) < 0)
7795 return ERROR_SEND_STATUS;
7796
Jouni Malinenba630452018-06-22 11:49:59 +03007797 if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007798 unlink("SP/wi-fi.org/pps.xml");
7799 if (system("rm -r SP/*") != 0) {
7800 }
7801 unlink("next-client-cert.pem");
7802 unlink("next-client-key.pem");
7803 }
7804
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007805 /* For WPS program of the 60 GHz band the band type needs to be saved */
7806 if (dut->program == PROGRAM_WPS) {
7807 if (band && strcasecmp(band, "60GHz") == 0) {
7808 dut->band = WPS_BAND_60G;
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02007809 /* For 60 GHz enable WPS for WPS TCs */
7810 dut->wps_disable = 0;
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007811 } else {
7812 dut->band = WPS_BAND_NON_60G;
7813 }
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02007814 } else if (dut->program == PROGRAM_60GHZ) {
7815 /* For 60 GHz MAC/PHY TCs WPS must be disabled */
7816 dut->wps_disable = 1;
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007817 }
7818
Alexei Avshalom Lazar157ba062018-12-23 16:15:26 +02007819 if (is_60g_sigma_dut(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007820 const char *dev_role = get_param(cmd, "DevRole");
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02007821 char buf[256];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007822
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02007823 sigma_dut_print(dut, DUT_MSG_INFO,
7824 "WPS 60 GHz program, wps_disable = %d",
7825 dut->wps_disable);
7826
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007827 if (!dev_role) {
7828 send_resp(dut, conn, SIGMA_ERROR,
7829 "errorCode,Missing DevRole argument");
7830 return 0;
7831 }
7832
7833 if (strcasecmp(dev_role, "STA") == 0)
7834 dut->dev_role = DEVROLE_STA;
7835 else if (strcasecmp(dev_role, "PCP") == 0)
7836 dut->dev_role = DEVROLE_PCP;
7837 else {
7838 send_resp(dut, conn, SIGMA_ERROR,
7839 "errorCode,Unknown DevRole");
7840 return 0;
7841 }
7842
7843 if (dut->device_type == STA_unknown) {
7844 sigma_dut_print(dut, DUT_MSG_ERROR,
7845 "Device type is not STA testbed or DUT");
7846 send_resp(dut, conn, SIGMA_ERROR,
7847 "errorCode,Unknown device type");
7848 return 0;
7849 }
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02007850
7851 sigma_dut_print(dut, DUT_MSG_DEBUG,
7852 "Setting msdu_size to MAX: 7912");
7853 snprintf(buf, sizeof(buf), "ifconfig %s mtu 7912",
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007854 get_station_ifname(dut));
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02007855
7856 if (system(buf) != 0) {
7857 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
7858 buf);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007859 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02007860 }
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02007861
7862 if (sta_set_force_mcs(dut, 0, 1)) {
7863 sigma_dut_print(dut, DUT_MSG_ERROR,
7864 "Failed to reset force MCS");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007865 return ERROR_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02007866 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007867 }
7868
7869 wpa_command(intf, "WPS_ER_STOP");
7870 wpa_command(intf, "FLUSH");
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05307871 wpa_command(intf, "ERP_FLUSH");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007872 wpa_command(intf, "SET radio_disabled 0");
7873
Alexei Avshalom Lazar744ae8a2019-01-31 17:26:46 +02007874 dut->wps_forced_version = 0;
7875
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007876 if (dut->wsc_fragment) {
7877 dut->wsc_fragment = 0;
7878 wpa_command(intf, "SET device_name Test client");
7879 wpa_command(intf, "SET manufacturer ");
7880 wpa_command(intf, "SET model_name ");
7881 wpa_command(intf, "SET model_number ");
7882 wpa_command(intf, "SET serial_number ");
7883 }
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02007884 if (is_60g_sigma_dut(dut) && dut->force_rsn_ie) {
7885 dut->force_rsn_ie = FORCE_RSN_IE_NONE;
7886 sta_60g_force_rsn_ie(dut, FORCE_RSN_IE_NONE);
7887 }
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007888
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007889 if (dut->tmp_mac_addr && dut->set_macaddr) {
7890 dut->tmp_mac_addr = 0;
7891 if (system(dut->set_macaddr) != 0) {
7892 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to clear "
7893 "temporary MAC address");
7894 }
7895 }
7896
7897 set_ps(intf, dut, 0);
7898
Jouni Malinenba630452018-06-22 11:49:59 +03007899 if (dut->program == PROGRAM_HS2 || dut->program == PROGRAM_HS2_R2 ||
7900 dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007901 wpa_command(intf, "SET interworking 1");
7902 wpa_command(intf, "SET hs20 1");
7903 }
7904
Deepak Dhamdhere0fe0e452017-12-18 14:52:09 -08007905 if (dut->program == PROGRAM_HS2_R2 ||
Jouni Malinenba630452018-06-22 11:49:59 +03007906 dut->program == PROGRAM_HS2_R3 ||
Deepak Dhamdhere0fe0e452017-12-18 14:52:09 -08007907 dut->program == PROGRAM_OCE) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007908 wpa_command(intf, "SET pmf 1");
7909 } else {
7910 wpa_command(intf, "SET pmf 0");
7911 }
7912
7913 hs2_clear_credentials(intf);
7914 wpa_command(intf, "SET hessid 00:00:00:00:00:00");
7915 wpa_command(intf, "SET access_network_type 15");
7916
7917 static_ip_file(0, NULL, NULL, NULL);
7918 kill_dhcp_client(dut, intf);
7919 clear_ip_addr(dut, intf);
7920
7921 dut->er_oper_performed = 0;
7922 dut->er_oper_bssid[0] = '\0';
7923
priyadharshini gowthamanad6cbba2016-10-04 10:39:58 -07007924 if (dut->program == PROGRAM_LOC) {
7925 /* Disable Interworking by default */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007926 wpa_command(get_station_ifname(dut), "SET interworking 0");
priyadharshini gowthamanad6cbba2016-10-04 10:39:58 -07007927 }
7928
Ashwini Patil00402582017-04-13 12:29:39 +05307929 if (dut->program == PROGRAM_MBO) {
7930 free(dut->non_pref_ch_list);
7931 dut->non_pref_ch_list = NULL;
Ashwini Patil5acd7382017-04-13 15:55:04 +05307932 free(dut->btm_query_cand_list);
7933 dut->btm_query_cand_list = NULL;
Ashwini Patilc63161e2017-04-13 16:30:23 +05307934 wpa_command(intf, "SET reject_btm_req_reason 0");
Ashwini Patila75de5a2017-04-13 16:35:05 +05307935 wpa_command(intf, "SET ignore_assoc_disallow 0");
Ashwini Patild174f2c2017-04-13 16:49:46 +05307936 wpa_command(intf, "SET gas_address3 0");
Ashwini Patil9183fdb2017-04-13 16:58:25 +05307937 wpa_command(intf, "SET roaming 1");
Ankita Bajaj1d974552018-09-18 16:56:44 +05307938 wpa_command(intf, "SET interworking 1");
Ashwini Patil00402582017-04-13 12:29:39 +05307939 }
7940
Jouni Malinen3c367e82017-06-23 17:01:47 +03007941 free(dut->rsne_override);
7942 dut->rsne_override = NULL;
7943
Jouni Malinen68143132017-09-02 02:34:08 +03007944 free(dut->sae_commit_override);
7945 dut->sae_commit_override = NULL;
Jouni Malinen4b3769d2019-10-10 16:20:29 +03007946 wpa_command(intf, "SET sae_pmkid_in_assoc 0");
Jouni Malinen11e55212019-11-22 21:46:59 +02007947 dut->sae_pwe = SAE_PWE_DEFAULT;
Jouni Malinen68143132017-09-02 02:34:08 +03007948
Jouni Malinen134fe3c2019-06-12 04:16:49 +03007949 dut->sta_associate_wait_connect = 0;
7950 dut->server_cert_hash[0] = '\0';
Jouni Malinen37d5c692019-08-19 16:56:55 +03007951 dut->server_cert_tod = 0;
Jouni Malinen134fe3c2019-06-12 04:16:49 +03007952 dut->sta_tod_policy = 0;
7953
Jouni Malinend86e5822017-08-29 03:55:32 +03007954 dut->dpp_conf_id = -1;
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02007955 free(dut->dpp_peer_uri);
7956 dut->dpp_peer_uri = NULL;
Jouni Malinen63d50412017-11-24 11:55:38 +02007957 dut->dpp_local_bootstrap = -1;
Jouni Malinen5011fb52017-12-05 21:00:15 +02007958 wpa_command(intf, "SET dpp_config_processing 2");
Jouni Malinen90776b12020-05-04 15:34:46 +03007959 wpa_command(intf, "SET dpp_mud_url ");
Jouni Malinend86e5822017-08-29 03:55:32 +03007960
Jouni Malinenfac9cad2017-10-10 18:35:55 +03007961 wpa_command(intf, "VENDOR_ELEM_REMOVE 13 *");
7962
vamsi krishnaa2799492017-12-05 14:28:01 +05307963 if (dut->program == PROGRAM_OCE) {
Ankita Bajaja2cb5672017-10-25 16:08:28 +05307964 wpa_command(intf, "SET oce 1");
vamsi krishnaa2799492017-12-05 14:28:01 +05307965 wpa_command(intf, "SET disable_fils 0");
Ankita Bajaj1bde7942018-01-09 19:15:01 +05307966 wpa_command(intf, "FILS_HLP_REQ_FLUSH");
7967 dut->fils_hlp = 0;
7968#ifdef ANDROID
7969 hlp_thread_cleanup(dut);
7970#endif /* ANDROID */
vamsi krishnaa2799492017-12-05 14:28:01 +05307971 }
Ankita Bajaja2cb5672017-10-25 16:08:28 +05307972
Vamsi Krishnaf642d6a2020-03-27 12:33:14 +05307973 if (dut->program == PROGRAM_QM)
7974 wpa_command(intf, "SET interworking 1");
7975
Jouni Malinen8179fee2019-03-28 03:19:47 +02007976 dut->akm_values = 0;
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007977 dut->sta_ft_ds = 0;
Jouni Malinen8179fee2019-03-28 03:19:47 +02007978
Sunil Dutt076081f2018-02-05 19:45:50 +05307979#ifdef NL80211_SUPPORT
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007980 if (get_driver_type(dut) == DRIVER_WCN &&
Sunil Dutt44595082018-02-12 19:41:45 +05307981 dut->config_rsnie == 1) {
7982 dut->config_rsnie = 0;
7983 sta_config_rsnie(dut, 0);
Sunil Dutt076081f2018-02-05 19:45:50 +05307984 }
7985#endif /* NL80211_SUPPORT */
7986
Sunil Duttfebf8a82018-02-09 18:50:13 +05307987 if (dev_role && strcasecmp(dev_role, "STA-CFON") == 0) {
7988 dut->dev_role = DEVROLE_STA_CFON;
7989 return sta_cfon_reset_default(dut, conn, cmd);
7990 }
7991
Jouni Malinen439352d2018-09-13 03:42:23 +03007992 wpa_command(intf, "SET setband AUTO");
7993
Sunil Duttfebf8a82018-02-09 18:50:13 +05307994 if (dut->program != PROGRAM_VHT)
7995 return cmd_sta_p2p_reset(dut, conn, cmd);
7996
Priyadharshini Gowthamana7dfd492015-11-09 14:34:08 -08007997 return 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007998}
7999
8000
Jouni Malinenf7222712019-06-13 01:50:21 +03008001static enum sigma_cmd_result cmd_sta_get_events(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 *program = get_param(cmd, "Program");
8006
8007 if (program == NULL)
8008 return -1;
8009#ifdef ANDROID_NAN
8010 if (strcasecmp(program, "NAN") == 0)
8011 return nan_cmd_sta_get_events(dut, conn, cmd);
8012#endif /* ANDROID_NAN */
8013 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
8014 return 0;
8015}
8016
8017
Jouni Malinen82905202018-04-29 17:20:10 +03008018static int sta_exec_action_url(struct sigma_dut *dut, struct sigma_conn *conn,
8019 struct sigma_cmd *cmd)
8020{
8021 const char *url = get_param(cmd, "url");
8022 const char *method = get_param(cmd, "method");
8023 pid_t pid;
8024 int status;
8025
8026 if (!url || !method)
8027 return -1;
8028
8029 /* TODO: Add support for method,post */
8030 if (strcasecmp(method, "get") != 0) {
8031 send_resp(dut, conn, SIGMA_ERROR,
8032 "ErrorCode,Unsupported method");
8033 return 0;
8034 }
8035
8036 pid = fork();
8037 if (pid < 0) {
8038 perror("fork");
8039 return -1;
8040 }
8041
8042 if (pid == 0) {
8043 char * argv[5] = { "wget", "-O", "/dev/null",
8044 (char *) url, NULL };
8045
8046 execv("/usr/bin/wget", argv);
8047 perror("execv");
8048 exit(0);
8049 return -1;
8050 }
8051
8052 if (waitpid(pid, &status, 0) < 0) {
8053 perror("waitpid");
8054 return -1;
8055 }
8056
8057 if (WIFEXITED(status)) {
8058 const char *errmsg;
8059
8060 if (WEXITSTATUS(status) == 0)
8061 return 1;
8062 sigma_dut_print(dut, DUT_MSG_INFO, "wget exit status %d",
8063 WEXITSTATUS(status));
8064 switch (WEXITSTATUS(status)) {
8065 case 4:
8066 errmsg = "errmsg,Network failure";
8067 break;
8068 case 8:
8069 errmsg = "errmsg,Server issued an error response";
8070 break;
8071 default:
8072 errmsg = "errmsg,Unknown failure from wget";
8073 break;
8074 }
8075 send_resp(dut, conn, SIGMA_ERROR, errmsg);
8076 return 0;
8077 }
8078
8079 send_resp(dut, conn, SIGMA_ERROR, "errmsg,Unknown failure");
8080 return 0;
8081}
8082
8083
Jouni Malinenf7222712019-06-13 01:50:21 +03008084static enum sigma_cmd_result cmd_sta_exec_action(struct sigma_dut *dut,
8085 struct sigma_conn *conn,
8086 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008087{
8088 const char *program = get_param(cmd, "Prog");
8089
Jouni Malinen82905202018-04-29 17:20:10 +03008090 if (program && !get_param(cmd, "interface"))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008091 return -1;
8092#ifdef ANDROID_NAN
Jouni Malinen82905202018-04-29 17:20:10 +03008093 if (program && strcasecmp(program, "NAN") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008094 return nan_cmd_sta_exec_action(dut, conn, cmd);
8095#endif /* ANDROID_NAN */
Jouni Malinen82905202018-04-29 17:20:10 +03008096
8097 if (program && strcasecmp(program, "Loc") == 0)
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07008098 return loc_cmd_sta_exec_action(dut, conn, cmd);
Jouni Malinen82905202018-04-29 17:20:10 +03008099
8100 if (get_param(cmd, "url"))
8101 return sta_exec_action_url(dut, conn, cmd);
8102
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008103 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
8104 return 0;
8105}
8106
8107
Jouni Malinenf7222712019-06-13 01:50:21 +03008108static enum sigma_cmd_result cmd_sta_set_11n(struct sigma_dut *dut,
8109 struct sigma_conn *conn,
8110 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008111{
8112 const char *intf = get_param(cmd, "Interface");
8113 const char *val, *mcs32, *rate;
8114
8115 val = get_param(cmd, "GREENFIELD");
8116 if (val) {
8117 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
8118 /* Enable GD */
8119 send_resp(dut, conn, SIGMA_ERROR,
8120 "ErrorCode,GF not supported");
8121 return 0;
8122 }
8123 }
8124
8125 val = get_param(cmd, "SGI20");
8126 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02008127 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008128 case DRIVER_ATHEROS:
8129 ath_sta_set_sgi(dut, intf, val);
8130 break;
8131 default:
8132 send_resp(dut, conn, SIGMA_ERROR,
8133 "ErrorCode,SGI20 not supported");
8134 return 0;
8135 }
8136 }
8137
8138 mcs32 = get_param(cmd, "MCS32"); /* HT Duplicate Mode Enable/Disable */
8139 rate = get_param(cmd, "MCS_FIXEDRATE"); /* Fixed MCS rate (0..31) */
8140 if (mcs32 && rate) {
8141 /* TODO */
8142 send_resp(dut, conn, SIGMA_ERROR,
8143 "ErrorCode,MCS32,MCS_FIXEDRATE not supported");
8144 return 0;
8145 } else if (mcs32 && !rate) {
8146 /* TODO */
8147 send_resp(dut, conn, SIGMA_ERROR,
8148 "ErrorCode,MCS32 not supported");
8149 return 0;
8150 } else if (!mcs32 && rate) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02008151 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008152 case DRIVER_ATHEROS:
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -07008153 novap_reset(dut, intf, 1);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008154 ath_sta_set_11nrates(dut, intf, rate);
8155 break;
8156 default:
8157 send_resp(dut, conn, SIGMA_ERROR,
8158 "ErrorCode,MCS32_FIXEDRATE not supported");
8159 return 0;
8160 }
8161 }
8162
8163 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
8164}
8165
8166
Arif Hussain7b47d2d2018-05-09 10:44:02 -07008167static void cmd_set_max_he_mcs(struct sigma_dut *dut, const char *intf,
8168 int mcs_config)
8169{
8170#ifdef NL80211_SUPPORT
8171 int ret;
8172
8173 switch (mcs_config) {
8174 case HE_80_MCS0_7:
8175 case HE_80_MCS0_9:
8176 case HE_80_MCS0_11:
8177 ret = sta_set_he_mcs(dut, intf, mcs_config);
8178 if (ret) {
8179 sigma_dut_print(dut, DUT_MSG_ERROR,
8180 "cmd_set_max_he_mcs: Setting of MCS:%d failed, ret:%d",
8181 mcs_config, ret);
8182 }
8183 break;
8184 default:
8185 sigma_dut_print(dut, DUT_MSG_ERROR,
8186 "cmd_set_max_he_mcs: Invalid mcs %d",
8187 mcs_config);
8188 break;
8189 }
8190#else /* NL80211_SUPPORT */
8191 sigma_dut_print(dut, DUT_MSG_ERROR,
8192 "max HE MCS cannot be changed without NL80211_SUPPORT defined");
8193#endif /* NL80211_SUPPORT */
8194}
8195
8196
Arif Hussain480d5f42019-03-12 14:40:42 -07008197static int sta_twt_request(struct sigma_dut *dut, struct sigma_conn *conn,
8198 struct sigma_cmd *cmd)
8199{
8200#ifdef NL80211_SUPPORT
8201 struct nlattr *params;
8202 struct nlattr *attr;
8203 struct nlattr *attr1;
8204 struct nl_msg *msg;
8205 int ifindex, ret;
8206 const char *val;
8207 const char *intf = get_param(cmd, "Interface");
8208 int wake_interval_exp = 10, nominal_min_wake_dur = 255,
8209 wake_interval_mantissa = 512;
8210 int flow_type = 0, twt_trigger = 0, target_wake_time = 0,
8211 protection = 0;
8212
8213 ifindex = if_nametoindex(intf);
8214 if (ifindex == 0) {
8215 sigma_dut_print(dut, DUT_MSG_ERROR,
8216 "%s: Index for interface %s failed",
8217 __func__, intf);
8218 return -1;
8219 }
8220
8221 val = get_param(cmd, "FlowType");
8222 if (val) {
8223 flow_type = atoi(val);
8224 if (flow_type != 0 && flow_type != 1) {
8225 sigma_dut_print(dut, DUT_MSG_ERROR,
8226 "TWT: Invalid FlowType %d", flow_type);
8227 return -1;
8228 }
8229 }
8230
8231 val = get_param(cmd, "TWT_Trigger");
8232 if (val) {
8233 twt_trigger = atoi(val);
8234 if (twt_trigger != 0 && twt_trigger != 1) {
8235 sigma_dut_print(dut, DUT_MSG_ERROR,
8236 "TWT: Invalid TWT_Trigger %d",
8237 twt_trigger);
8238 return -1;
8239 }
8240 }
8241
8242 val = get_param(cmd, "Protection");
8243 if (val) {
8244 protection = atoi(val);
8245 if (protection != 0 && protection != 1) {
8246 sigma_dut_print(dut, DUT_MSG_ERROR,
8247 "TWT: Invalid Protection %d",
8248 protection);
8249 return -1;
8250 }
8251 }
8252
8253 val = get_param(cmd, "TargetWakeTime");
8254 if (val)
8255 target_wake_time = atoi(val);
8256
8257 val = get_param(cmd, "WakeIntervalMantissa");
8258 if (val)
8259 wake_interval_mantissa = atoi(val);
8260
8261 val = get_param(cmd, "WakeIntervalExp");
8262 if (val)
8263 wake_interval_exp = atoi(val);
8264
8265 val = get_param(cmd, "NominalMinWakeDur");
8266 if (val)
8267 nominal_min_wake_dur = atoi(val);
8268
8269 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8270 NL80211_CMD_VENDOR)) ||
8271 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
8272 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
8273 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
8274 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
8275 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8276 !(params = nla_nest_start(
8277 msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_SETUP)) ||
8278 !(attr1 = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8279 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_EXP,
8280 wake_interval_exp) ||
Arif Hussain480d5f42019-03-12 14:40:42 -07008281 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_REQ_TYPE, 1) ||
Kiran Kumar Lokere2cffae52019-09-26 18:44:15 -07008282 (twt_trigger &&
8283 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TRIGGER)) ||
Arif Hussain480d5f42019-03-12 14:40:42 -07008284 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE,
8285 flow_type) ||
Kiran Kumar Lokere2cffae52019-09-26 18:44:15 -07008286 (protection &&
8287 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_PROTECTION)) ||
Arif Hussain480d5f42019-03-12 14:40:42 -07008288 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME,
8289 target_wake_time) ||
8290 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_DURATION,
8291 nominal_min_wake_dur) ||
8292 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_MANTISSA,
8293 wake_interval_mantissa)) {
8294 sigma_dut_print(dut, DUT_MSG_ERROR,
8295 "%s: err in adding vendor_cmd and vendor_data",
8296 __func__);
8297 nlmsg_free(msg);
8298 return -1;
8299 }
8300 nla_nest_end(msg, attr1);
8301 nla_nest_end(msg, params);
8302 nla_nest_end(msg, attr);
8303
8304 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
8305 if (ret) {
8306 sigma_dut_print(dut, DUT_MSG_ERROR,
8307 "%s: err in send_and_recv_msgs, ret=%d",
8308 __func__, ret);
8309 }
8310
8311 return ret;
8312#else /* NL80211_SUPPORT */
8313 sigma_dut_print(dut, DUT_MSG_ERROR,
8314 "TWT request cannot be done without NL80211_SUPPORT defined");
8315 return -1;
8316#endif /* NL80211_SUPPORT */
8317}
8318
8319
8320static int sta_twt_teardown(struct sigma_dut *dut, struct sigma_conn *conn,
8321 struct sigma_cmd *cmd)
8322{
8323 #ifdef NL80211_SUPPORT
8324 struct nlattr *params;
8325 struct nlattr *attr;
8326 struct nlattr *attr1;
8327 int ifindex, ret;
8328 struct nl_msg *msg;
8329 const char *intf = get_param(cmd, "Interface");
8330
8331 ifindex = if_nametoindex(intf);
8332 if (ifindex == 0) {
8333 sigma_dut_print(dut, DUT_MSG_ERROR,
8334 "%s: Index for interface %s failed",
8335 __func__, intf);
8336 return -1;
8337 }
8338
8339 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8340 NL80211_CMD_VENDOR)) ||
8341 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
8342 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
8343 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
8344 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
8345 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8346 !(params = nla_nest_start(
8347 msg,
8348 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_TERMINATE)) ||
8349 !(attr1 = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8350 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE, 0)) {
8351 sigma_dut_print(dut, DUT_MSG_ERROR,
8352 "%s: err in adding vendor_cmd and vendor_data",
8353 __func__);
8354 nlmsg_free(msg);
8355 return -1;
8356 }
8357 nla_nest_end(msg, attr1);
8358 nla_nest_end(msg, params);
8359 nla_nest_end(msg, attr);
8360
8361 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
8362 if (ret) {
8363 sigma_dut_print(dut, DUT_MSG_ERROR,
8364 "%s: err in send_and_recv_msgs, ret=%d",
8365 __func__, ret);
8366 }
8367
8368 return ret;
8369#else /* NL80211_SUPPORT */
8370 sigma_dut_print(dut, DUT_MSG_ERROR,
8371 "TWT teardown cannot be done without NL80211_SUPPORT defined");
8372 return -1;
8373#endif /* NL80211_SUPPORT */
8374}
8375
8376
Kiran Kumar Lokere50eb2cd2018-12-18 18:31:28 -08008377static int sta_transmit_omi(struct sigma_dut *dut, struct sigma_conn *conn,
8378 struct sigma_cmd *cmd)
8379{
8380#ifdef NL80211_SUPPORT
8381 struct nlattr *params;
8382 struct nlattr *attr;
8383 struct nlattr *attr1;
8384 struct nl_msg *msg;
8385 int ifindex, ret;
8386 const char *val;
8387 const char *intf = get_param(cmd, "Interface");
8388 uint8_t rx_nss = 0xFF, ch_bw = 0xFF, tx_nsts = 0xFF, ulmu_dis = 0,
8389 ulmu_data_dis = 0;
8390
8391 ifindex = if_nametoindex(intf);
8392 if (ifindex == 0) {
8393 sigma_dut_print(dut, DUT_MSG_ERROR,
8394 "%s: Index for interface %s failed",
8395 __func__, intf);
8396 return -1;
8397 }
8398 val = get_param(cmd, "OMCtrl_RxNSS");
8399 if (val)
8400 rx_nss = atoi(val);
8401
8402 val = get_param(cmd, "OMCtrl_ChnlWidth");
8403 if (val)
8404 ch_bw = atoi(val);
8405
8406 val = get_param(cmd, "OMCtrl_ULMUDisable");
8407 if (val)
8408 ulmu_dis = atoi(val);
8409
8410 val = get_param(cmd, "OMCtrl_TxNSTS");
8411 if (val)
8412 tx_nsts = atoi(val);
8413
8414 val = get_param(cmd, "OMCtrl_ULMUDataDisable");
8415 if (val)
8416 ulmu_data_dis = atoi(val);
8417
8418 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8419 NL80211_CMD_VENDOR)) ||
8420 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
8421 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
8422 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
8423 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
8424 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8425 !(params = nla_nest_start(
8426 msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OMI_TX)) ||
8427 !(attr1 = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8428 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_RX_NSS, rx_nss) ||
8429 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_CH_BW, ch_bw) ||
8430 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_TX_NSTS, tx_nsts) ||
8431 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DATA_DISABLE,
8432 ulmu_data_dis) ||
8433 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DISABLE,
8434 ulmu_dis)) {
8435 sigma_dut_print(dut, DUT_MSG_ERROR,
8436 "%s: err in adding vendor_cmd and vendor_data",
8437 __func__);
8438 nlmsg_free(msg);
8439 return -1;
8440 }
8441 nla_nest_end(msg, attr1);
8442 nla_nest_end(msg, params);
8443 nla_nest_end(msg, attr);
8444
8445 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
8446 if (ret) {
8447 sigma_dut_print(dut, DUT_MSG_ERROR,
8448 "%s: err in send_and_recv_msgs, ret=%d",
8449 __func__, ret);
8450 }
8451
8452 return ret;
8453#else /* NL80211_SUPPORT */
8454 sigma_dut_print(dut, DUT_MSG_ERROR,
8455 "OMI TX cannot be processed without NL80211_SUPPORT defined");
8456 return -1;
8457#endif /* NL80211_SUPPORT */
8458}
8459
8460
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008461static int cmd_sta_set_wireless_vht(struct sigma_dut *dut,
8462 struct sigma_conn *conn,
8463 struct sigma_cmd *cmd)
8464{
8465 const char *intf = get_param(cmd, "Interface");
8466 const char *val;
Arif Hussaina37e9552018-06-20 17:05:59 -07008467 const char *program;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008468 int tkip = -1;
8469 int wep = -1;
8470
Arif Hussaina37e9552018-06-20 17:05:59 -07008471 program = get_param(cmd, "Program");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008472 val = get_param(cmd, "SGI80");
8473 if (val) {
8474 int sgi80;
8475
8476 sgi80 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008477 run_iwpriv(dut, intf, "shortgi %d", sgi80);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008478 }
8479
8480 val = get_param(cmd, "TxBF");
8481 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02008482 switch (get_driver_type(dut)) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07008483 case DRIVER_WCN:
8484 if (sta_set_tx_beamformee(dut, intf, 1)) {
8485 send_resp(dut, conn, SIGMA_ERROR,
8486 "ErrorCode,Failed to set TX beamformee enable");
8487 return 0;
8488 }
8489 break;
8490 case DRIVER_ATHEROS:
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008491 if (run_iwpriv(dut, intf, "vhtsubfee 1") < 0) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07008492 send_resp(dut, conn, SIGMA_ERROR,
8493 "ErrorCode,Setting vhtsubfee failed");
8494 return 0;
8495 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008496 if (run_iwpriv(dut, intf, "vhtsubfer 1") < 0) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07008497 send_resp(dut, conn, SIGMA_ERROR,
8498 "ErrorCode,Setting vhtsubfer failed");
8499 return 0;
8500 }
8501 break;
8502 default:
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008503 sigma_dut_print(dut, DUT_MSG_ERROR,
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07008504 "Unsupported driver type");
8505 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008506 }
8507 }
8508
8509 val = get_param(cmd, "MU_TxBF");
8510 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02008511 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008512 case DRIVER_ATHEROS:
8513 ath_sta_set_txsp_stream(dut, intf, "1SS");
8514 ath_sta_set_rxsp_stream(dut, intf, "1SS");
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008515 run_iwpriv(dut, intf, "vhtmubfee 1");
8516 run_iwpriv(dut, intf, "vhtmubfer 1");
Sunil Duttae9e5d12018-06-29 11:50:47 +05308517 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008518 case DRIVER_WCN:
8519 if (wcn_sta_set_sp_stream(dut, intf, "1SS") < 0) {
8520 send_resp(dut, conn, SIGMA_ERROR,
8521 "ErrorCode,Failed to set RX/TXSP_STREAM");
8522 return 0;
8523 }
Sunil Duttae9e5d12018-06-29 11:50:47 +05308524 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008525 default:
8526 sigma_dut_print(dut, DUT_MSG_ERROR,
8527 "Setting SP_STREAM not supported");
8528 break;
8529 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008530 }
8531
8532 val = get_param(cmd, "LDPC");
8533 if (val) {
8534 int ldpc;
8535
8536 ldpc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008537 run_iwpriv(dut, intf, "ldpc %d", ldpc);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008538 }
8539
Amarnath Hullur Subramanyam7bae60e2018-01-31 03:46:50 -08008540 val = get_param(cmd, "BCC");
8541 if (val) {
8542 int bcc;
8543
8544 bcc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
8545 /* use LDPC iwpriv itself to set bcc coding, bcc coding
8546 * is mutually exclusive to bcc */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008547 run_iwpriv(dut, intf, "ldpc %d", !bcc);
Amarnath Hullur Subramanyam7bae60e2018-01-31 03:46:50 -08008548 }
8549
Arif Hussain7b47d2d2018-05-09 10:44:02 -07008550 val = get_param(cmd, "MaxHE-MCS_1SS_RxMapLTE80");
8551 if (val && dut->sta_nss == 1)
8552 cmd_set_max_he_mcs(dut, intf, atoi(val));
8553
8554 val = get_param(cmd, "MaxHE-MCS_2SS_RxMapLTE80");
8555 if (val && dut->sta_nss == 2)
8556 cmd_set_max_he_mcs(dut, intf, atoi(val));
8557
Arif Hussainac6c5112018-05-25 17:34:00 -07008558 val = get_param(cmd, "MCS_FixedRate");
8559 if (val) {
8560#ifdef NL80211_SUPPORT
8561 int mcs, ratecode = 0;
8562 enum he_mcs_config mcs_config;
8563 int ret;
Jouni Malinenb9b671d2019-04-26 13:23:17 +03008564 char buf[60];
Arif Hussainac6c5112018-05-25 17:34:00 -07008565
8566 ratecode = (0x07 & dut->sta_nss) << 5;
8567 mcs = atoi(val);
8568 /* Add the MCS to the ratecode */
8569 if (mcs >= 0 && mcs <= 11) {
8570 ratecode += mcs;
8571 if (dut->device_type == STA_testbed &&
8572 mcs > 7 && mcs <= 11) {
8573 if (mcs <= 9)
8574 mcs_config = HE_80_MCS0_9;
8575 else
8576 mcs_config = HE_80_MCS0_11;
8577 ret = sta_set_he_mcs(dut, intf, mcs_config);
8578 if (ret) {
8579 sigma_dut_print(dut, DUT_MSG_ERROR,
8580 "MCS_FixedRate: mcs setting failed, mcs:%d, mcs_config %d, ret:%d",
8581 mcs, mcs_config, ret);
8582 }
8583 }
8584 snprintf(buf, sizeof(buf),
8585 "iwpriv %s set_11ax_rate 0x%03x",
8586 intf, ratecode);
8587 if (system(buf) != 0) {
8588 sigma_dut_print(dut, DUT_MSG_ERROR,
8589 "MCS_FixedRate: iwpriv setting of 11ax rates 0x%03x failed",
8590 ratecode);
8591 }
8592 } else {
8593 sigma_dut_print(dut, DUT_MSG_ERROR,
8594 "MCS_FixedRate: HE MCS %d not supported",
8595 mcs);
8596 }
8597#else /* NL80211_SUPPORT */
8598 sigma_dut_print(dut, DUT_MSG_ERROR,
8599 "MCS_FixedRate cannot be changed without NL80211_SUPPORT defined");
8600#endif /* NL80211_SUPPORT */
8601 }
8602
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008603 val = get_param(cmd, "opt_md_notif_ie");
8604 if (val) {
8605 char *result = NULL;
8606 char delim[] = ";";
8607 char token[30];
8608 int value, config_val = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308609 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008610
Peng Xub8fc5cc2017-05-10 17:27:28 -07008611 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308612 result = strtok_r(token, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008613
8614 /* Extract the NSS information */
8615 if (result) {
8616 value = atoi(result);
8617 switch (value) {
8618 case 1:
8619 config_val = 1;
8620 break;
8621 case 2:
8622 config_val = 3;
8623 break;
8624 case 3:
8625 config_val = 7;
8626 break;
8627 case 4:
8628 config_val = 15;
8629 break;
8630 default:
8631 config_val = 3;
8632 break;
8633 }
8634
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008635 run_iwpriv(dut, intf, "rxchainmask %d", config_val);
8636 run_iwpriv(dut, intf, "txchainmask %d", config_val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008637
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008638 }
8639
8640 /* Extract the channel width information */
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308641 result = strtok_r(NULL, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008642 if (result) {
8643 value = atoi(result);
8644 switch (value) {
8645 case 20:
8646 config_val = 0;
8647 break;
8648 case 40:
8649 config_val = 1;
8650 break;
8651 case 80:
8652 config_val = 2;
8653 break;
8654 case 160:
8655 config_val = 3;
8656 break;
8657 default:
8658 config_val = 2;
8659 break;
8660 }
8661
8662 dut->chwidth = config_val;
8663
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008664 run_iwpriv(dut, intf, "chwidth %d", config_val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008665 }
8666
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008667 run_iwpriv(dut, intf, "opmode_notify 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008668 }
8669
8670 val = get_param(cmd, "nss_mcs_cap");
8671 if (val) {
8672 int nss, mcs;
8673 char token[20];
8674 char *result = NULL;
8675 unsigned int vht_mcsmap = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308676 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008677
Peng Xub8fc5cc2017-05-10 17:27:28 -07008678 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308679 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05308680 if (!result) {
8681 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07008682 "NSS not specified");
8683 send_resp(dut, conn, SIGMA_ERROR,
8684 "errorCode,NSS not specified");
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05308685 return 0;
8686 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008687 nss = atoi(result);
8688
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008689 run_iwpriv(dut, intf, "nss %d", nss);
Arif Hussainac6c5112018-05-25 17:34:00 -07008690 dut->sta_nss = nss;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008691
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308692 result = strtok_r(NULL, ";", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008693 if (result == NULL) {
8694 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07008695 "MCS not specified");
8696 send_resp(dut, conn, SIGMA_ERROR,
8697 "errorCode,MCS not specified");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008698 return 0;
8699 }
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308700 result = strtok_r(result, "-", &saveptr);
8701 result = strtok_r(NULL, "-", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05308702 if (!result) {
8703 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07008704 "MCS not specified");
8705 send_resp(dut, conn, SIGMA_ERROR,
8706 "errorCode,MCS not specified");
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05308707 return 0;
8708 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008709 mcs = atoi(result);
8710
Arif Hussaina37e9552018-06-20 17:05:59 -07008711 if (program && strcasecmp(program, "HE") == 0) {
8712#ifdef NL80211_SUPPORT
8713 enum he_mcs_config mcs_config;
8714 int ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008715
Arif Hussaina37e9552018-06-20 17:05:59 -07008716 if (mcs >= 0 && mcs <= 7) {
8717 mcs_config = HE_80_MCS0_7;
8718 } else if (mcs > 7 && mcs <= 9) {
8719 mcs_config = HE_80_MCS0_9;
8720 } else if (mcs > 9 && mcs <= 11) {
8721 mcs_config = HE_80_MCS0_11;
8722 } else {
8723 sigma_dut_print(dut, DUT_MSG_ERROR,
8724 "nss_mcs_cap: HE: Invalid mcs: %d",
8725 mcs);
8726 send_resp(dut, conn, SIGMA_ERROR,
8727 "errorCode,Invalid MCS");
8728 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008729 }
Arif Hussaina37e9552018-06-20 17:05:59 -07008730
8731 ret = sta_set_he_mcs(dut, intf, mcs_config);
8732 if (ret) {
8733 sigma_dut_print(dut, DUT_MSG_ERROR,
8734 "nss_mcs_cap: HE: Setting of MCS failed, mcs_config: %d, ret: %d",
8735 mcs_config, ret);
8736 send_resp(dut, conn, SIGMA_ERROR,
8737 "errorCode,Failed to set MCS");
8738 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008739 }
Arif Hussaina37e9552018-06-20 17:05:59 -07008740#else /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008741 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07008742 "nss_mcs_cap: HE: MCS cannot be changed without NL80211_SUPPORT defined");
8743#endif /* NL80211_SUPPORT */
8744 } else {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008745 run_iwpriv(dut, intf, "vhtmcs %d", mcs);
Arif Hussaina37e9552018-06-20 17:05:59 -07008746
8747 switch (nss) {
8748 case 1:
8749 switch (mcs) {
8750 case 7:
8751 vht_mcsmap = 0xfffc;
8752 break;
8753 case 8:
8754 vht_mcsmap = 0xfffd;
8755 break;
8756 case 9:
8757 vht_mcsmap = 0xfffe;
8758 break;
8759 default:
8760 vht_mcsmap = 0xfffe;
8761 break;
8762 }
8763 break;
8764 case 2:
8765 switch (mcs) {
8766 case 7:
8767 vht_mcsmap = 0xfff0;
8768 break;
8769 case 8:
8770 vht_mcsmap = 0xfff5;
8771 break;
8772 case 9:
8773 vht_mcsmap = 0xfffa;
8774 break;
8775 default:
8776 vht_mcsmap = 0xfffa;
8777 break;
8778 }
8779 break;
8780 case 3:
8781 switch (mcs) {
8782 case 7:
8783 vht_mcsmap = 0xffc0;
8784 break;
8785 case 8:
8786 vht_mcsmap = 0xffd5;
8787 break;
8788 case 9:
8789 vht_mcsmap = 0xffea;
8790 break;
8791 default:
8792 vht_mcsmap = 0xffea;
8793 break;
8794 }
8795 break;
8796 default:
8797 vht_mcsmap = 0xffea;
8798 break;
8799 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008800 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008801 }
8802 }
8803
8804 /* UNSUPPORTED: val = get_param(cmd, "Tx_lgi_rate"); */
8805
8806 val = get_param(cmd, "Vht_tkip");
8807 if (val)
8808 tkip = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
8809
8810 val = get_param(cmd, "Vht_wep");
8811 if (val)
8812 wep = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
8813
8814 if (tkip != -1 || wep != -1) {
8815 if ((tkip == 1 && wep != 0) || (wep == 1 && tkip != 0)) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008816 run_iwpriv(dut, intf, "htweptkip 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008817 } else if ((tkip == 0 && wep != 1) || (wep == 0 && tkip != 1)) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008818 run_iwpriv(dut, intf, "htweptkip 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008819 } else {
8820 sigma_dut_print(dut, DUT_MSG_ERROR,
8821 "ErrorCode,mixed mode of VHT TKIP/WEP not supported");
8822 return 0;
8823 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008824 }
8825
Arif Hussain55f00da2018-07-03 08:28:26 -07008826 val = get_param(cmd, "txBandwidth");
8827 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02008828 switch (get_driver_type(dut)) {
Arif Hussain55f00da2018-07-03 08:28:26 -07008829 case DRIVER_WCN:
8830 if (wcn_sta_set_width(dut, intf, val) < 0) {
8831 send_resp(dut, conn, SIGMA_ERROR,
8832 "ErrorCode,Failed to set txBandwidth");
8833 return 0;
8834 }
8835 break;
8836 case DRIVER_ATHEROS:
8837 if (ath_set_width(dut, conn, intf, val) < 0) {
8838 send_resp(dut, conn, SIGMA_ERROR,
8839 "ErrorCode,Failed to set txBandwidth");
8840 return 0;
8841 }
8842 break;
8843 default:
8844 sigma_dut_print(dut, DUT_MSG_ERROR,
8845 "Setting txBandwidth not supported");
8846 break;
8847 }
8848 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008849
Arif Hussain9765f7d2018-07-03 08:28:26 -07008850 val = get_param(cmd, "BeamformeeSTS");
8851 if (val) {
Kiran Kumar Lokerebc89d432018-07-10 12:20:13 -07008852 if (sta_set_tx_beamformee(dut, intf, 1)) {
8853 send_resp(dut, conn, SIGMA_ERROR,
8854 "ErrorCode,Failed to set TX beamformee enable");
8855 return 0;
8856 }
8857
Arif Hussain9765f7d2018-07-03 08:28:26 -07008858 if (sta_set_beamformee_sts(dut, intf, atoi(val))) {
8859 send_resp(dut, conn, SIGMA_ERROR,
8860 "ErrorCode,Failed to set BeamformeeSTS");
8861 return 0;
8862 }
8863 }
8864
Arif Hussain68d23f52018-07-11 13:39:08 -07008865 val = get_param(cmd, "Trig_MAC_Padding_Dur");
8866 if (val) {
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07008867#ifdef NL80211_SUPPORT
8868 enum qca_wlan_he_mac_padding_dur set_val;
8869
8870 switch (atoi(val)) {
8871 case 16:
8872 set_val = QCA_WLAN_HE_16US_OF_PROCESS_TIME;
8873 break;
8874 case 8:
8875 set_val = QCA_WLAN_HE_8US_OF_PROCESS_TIME;
8876 break;
8877 default:
8878 set_val = QCA_WLAN_HE_NO_ADDITIONAL_PROCESS_TIME;
8879 break;
8880 }
8881 if (sta_set_mac_padding_duration(dut, intf, set_val)) {
Arif Hussain68d23f52018-07-11 13:39:08 -07008882 send_resp(dut, conn, SIGMA_ERROR,
8883 "ErrorCode,Failed to set MAC padding duration");
8884 return 0;
8885 }
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07008886#else /* NL80211_SUPPORT */
8887 sigma_dut_print(dut, DUT_MSG_ERROR,
8888 "MAC padding duration cannot be changed without NL80211_SUPPORT defined");
8889#endif /* NL80211_SUPPORT */
Arif Hussain68d23f52018-07-11 13:39:08 -07008890 }
8891
Arif Hussain480d5f42019-03-12 14:40:42 -07008892 val = get_param(cmd, "TWT_ReqSupport");
8893 if (val) {
8894 int set_val;
8895
8896 if (strcasecmp(val, "Enable") == 0) {
8897 set_val = 1;
8898 } else if (strcasecmp(val, "Disable") == 0) {
8899 set_val = 0;
8900 } else {
8901 send_resp(dut, conn, SIGMA_ERROR,
8902 "ErrorCode,Invalid TWT_ReqSupport");
8903 return STATUS_SENT;
8904 }
8905
8906 if (sta_set_twt_req_support(dut, intf, set_val)) {
8907 sigma_dut_print(dut, DUT_MSG_ERROR,
8908 "Failed to set TWT req support %d",
8909 set_val);
8910 send_resp(dut, conn, SIGMA_ERROR,
8911 "ErrorCode,Failed to set TWT_ReqSupport");
8912 return STATUS_SENT;
8913 }
8914 }
8915
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07008916 val = get_param(cmd, "MU_EDCA");
8917 if (val && (strcasecmp(val, "Override") == 0)) {
8918 if (sta_set_mu_edca_override(dut, intf, 1)) {
8919 send_resp(dut, conn, SIGMA_ERROR,
8920 "ErrorCode,Failed to set MU EDCA override");
8921 return 0;
8922 }
8923 }
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -07008924
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07008925 val = get_param(cmd, "OMControl");
8926 if (val) {
8927 int set_val = 1;
8928
8929 if (strcasecmp(val, "Enable") == 0)
8930 set_val = 1;
8931 else if (strcasecmp(val, "Disable") == 0)
8932 set_val = 0;
8933
8934 if (sta_set_om_ctrl_supp(dut, intf, set_val)) {
8935 send_resp(dut, conn, SIGMA_ERROR,
8936 "ErrorCode,Failed to set OM ctrl supp");
8937 return 0;
8938 }
8939 }
8940
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -07008941 val = get_param(cmd, "ADDBAResp_BufSize");
8942 if (val) {
8943 int buf_size;
8944
8945 if (strcasecmp(val, "gt64") == 0)
8946 buf_size = 256;
8947 else
8948 buf_size = 64;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02008949 if (get_driver_type(dut) == DRIVER_WCN &&
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -07008950 sta_set_addba_buf_size(dut, intf, buf_size)) {
8951 send_resp(dut, conn, SIGMA_ERROR,
8952 "ErrorCode,set addbaresp_buff_size failed");
8953 return 0;
8954 }
8955 }
8956
8957 val = get_param(cmd, "ADDBAReq_BufSize");
8958 if (val) {
8959 int buf_size;
8960
8961 if (strcasecmp(val, "gt64") == 0)
8962 buf_size = 256;
8963 else
8964 buf_size = 64;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02008965 if (get_driver_type(dut) == DRIVER_WCN &&
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -07008966 sta_set_addba_buf_size(dut, intf, buf_size)) {
8967 send_resp(dut, conn, SIGMA_ERROR,
8968 "ErrorCode,set addbareq_buff_size failed");
8969 return 0;
8970 }
8971 }
8972
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008973 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
8974}
8975
8976
8977static int sta_set_wireless_60g(struct sigma_dut *dut,
8978 struct sigma_conn *conn,
8979 struct sigma_cmd *cmd)
8980{
8981 const char *dev_role = get_param(cmd, "DevRole");
8982
8983 if (!dev_role) {
8984 send_resp(dut, conn, SIGMA_INVALID,
8985 "ErrorCode,DevRole not specified");
8986 return 0;
8987 }
8988
8989 if (strcasecmp(dev_role, "PCP") == 0)
8990 return sta_set_60g_pcp(dut, conn, cmd);
8991 if (strcasecmp(dev_role, "STA") == 0)
8992 return sta_set_60g_sta(dut, conn, cmd);
8993 send_resp(dut, conn, SIGMA_INVALID,
8994 "ErrorCode,DevRole not supported");
8995 return 0;
8996}
8997
8998
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05308999static int sta_set_wireless_oce(struct sigma_dut *dut, struct sigma_conn *conn,
9000 struct sigma_cmd *cmd)
9001{
9002 int status;
9003 const char *intf = get_param(cmd, "Interface");
9004 const char *val = get_param(cmd, "DevRole");
9005
9006 if (val && strcasecmp(val, "STA-CFON") == 0) {
9007 status = sta_cfon_set_wireless(dut, conn, cmd);
9008 if (status)
9009 return status;
9010 }
9011 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
9012}
9013
9014
Jouni Malinenf7222712019-06-13 01:50:21 +03009015static enum sigma_cmd_result cmd_sta_set_wireless(struct sigma_dut *dut,
9016 struct sigma_conn *conn,
9017 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009018{
9019 const char *val;
9020
9021 val = get_param(cmd, "Program");
9022 if (val) {
9023 if (strcasecmp(val, "11n") == 0)
9024 return cmd_sta_set_11n(dut, conn, cmd);
Amarnath Hullur Subramanyam4f860292018-01-31 03:49:35 -08009025 if (strcasecmp(val, "VHT") == 0 || strcasecmp(val, "HE") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009026 return cmd_sta_set_wireless_vht(dut, conn, cmd);
9027 if (strcasecmp(val, "60ghz") == 0)
9028 return sta_set_wireless_60g(dut, conn, cmd);
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05309029 if (strcasecmp(val, "OCE") == 0)
9030 return sta_set_wireless_oce(dut, conn, cmd);
Alexei Avshalom Lazar66bb9972018-12-18 16:01:43 +02009031 /* sta_set_wireless in WPS program is only used for 60G */
9032 if (is_60g_sigma_dut(dut))
9033 return sta_set_wireless_60g(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009034 send_resp(dut, conn, SIGMA_ERROR,
9035 "ErrorCode,Program value not supported");
9036 } else {
9037 send_resp(dut, conn, SIGMA_ERROR,
9038 "ErrorCode,Program argument not available");
9039 }
9040
9041 return 0;
9042}
9043
9044
9045static void ath_sta_inject_frame(struct sigma_dut *dut, const char *intf,
9046 int tid)
9047{
9048 char buf[100];
9049 int tid_to_dscp [] = { 0x00, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0 };
9050
Pradeep Reddy POTTETId31d1322016-10-13 17:22:03 +05309051 if (tid < 0 ||
9052 tid >= (int) (sizeof(tid_to_dscp) / sizeof(tid_to_dscp[0]))) {
9053 sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported TID: %d", tid);
9054 return;
9055 }
9056
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009057 /*
9058 * Two ways to ensure that addba request with a
9059 * non zero TID could be sent out. EV 117296
9060 */
9061 snprintf(buf, sizeof(buf),
9062 "ping -c 8 -Q %d `arp -a | grep wlan0 | awk '{print $2}' | tr -d '()'`",
9063 tid);
9064 if (system(buf) != 0) {
9065 sigma_dut_print(dut, DUT_MSG_ERROR,
9066 "Ping did not send out");
9067 }
9068
9069 snprintf(buf, sizeof(buf),
9070 "iwconfig %s | grep Access | awk '{print $6}' > %s",
9071 intf, VI_QOS_TMP_FILE);
9072 if (system(buf) != 0)
9073 return;
9074
9075 snprintf(buf, sizeof(buf),
9076 "ifconfig %s | grep HWaddr | cut -b 39-56 >> %s",
9077 intf, VI_QOS_TMP_FILE);
9078 if (system(buf) != 0)
9079 sigma_dut_print(dut, DUT_MSG_ERROR, "HWaddr matching failed");
9080
9081 snprintf(buf,sizeof(buf), "sed -n '3,$p' %s >> %s",
9082 VI_QOS_REFFILE, VI_QOS_TMP_FILE);
9083 if (system(buf) != 0) {
9084 sigma_dut_print(dut, DUT_MSG_ERROR,
9085 "VI_QOS_TEMP_FILE generation error failed");
9086 }
9087 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
9088 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
9089 if (system(buf) != 0) {
9090 sigma_dut_print(dut, DUT_MSG_ERROR,
9091 "VI_QOS_FILE generation failed");
9092 }
9093
9094 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
9095 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
9096 if (system(buf) != 0) {
9097 sigma_dut_print(dut, DUT_MSG_ERROR,
9098 "VI_QOS_FILE generation failed");
9099 }
9100
9101 snprintf(buf, sizeof(buf), "ethinject %s %s", intf, VI_QOS_FILE);
9102 if (system(buf) != 0) {
9103 }
9104}
9105
9106
9107static int ath_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
9108 struct sigma_cmd *cmd)
9109{
9110 const char *intf = get_param(cmd, "Interface");
9111 const char *val;
9112 int tid = 0;
9113 char buf[100];
9114
9115 val = get_param(cmd, "TID");
9116 if (val) {
9117 tid = atoi(val);
9118 if (tid)
9119 ath_sta_inject_frame(dut, intf, tid);
9120 }
9121
9122 /* Command sequence for ADDBA request on Peregrine based devices */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07009123 run_iwpriv(dut, intf, "setaddbaoper 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009124
9125 snprintf(buf, sizeof(buf), "wifitool %s senddelba 1 %d 1 4", intf, tid);
9126 if (system(buf) != 0) {
9127 sigma_dut_print(dut, DUT_MSG_ERROR,
9128 "wifitool senddelba failed");
9129 }
9130
9131 snprintf(buf, sizeof(buf), "wifitool %s sendaddba 1 %d 64", intf, tid);
9132 if (system(buf) != 0) {
9133 sigma_dut_print(dut, DUT_MSG_ERROR,
9134 "wifitool sendaddba failed");
9135 }
9136
9137 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
9138
9139 return 1;
9140}
9141
9142
Lior David9981b512017-01-20 13:16:40 +02009143#ifdef __linux__
9144
9145static int wil6210_send_addba(struct sigma_dut *dut, const char *dest_mac,
9146 int agg_size)
9147{
9148 char dir[128], buf[128];
9149 FILE *f;
9150 regex_t re;
9151 regmatch_t m[2];
Jouni Malinen3aa72862019-05-29 23:14:51 +03009152 int rc, ret = -1, vring_id, found, res;
Lior David9981b512017-01-20 13:16:40 +02009153
9154 if (wil6210_get_debugfs_dir(dut, dir, sizeof(dir))) {
9155 sigma_dut_print(dut, DUT_MSG_ERROR,
9156 "failed to get wil6210 debugfs dir");
9157 return -1;
9158 }
9159
Jouni Malinen3aa72862019-05-29 23:14:51 +03009160 res = snprintf(buf, sizeof(buf), "%s/vrings", dir);
9161 if (res < 0 || res >= sizeof(buf))
9162 return -1;
Lior David9981b512017-01-20 13:16:40 +02009163 f = fopen(buf, "r");
9164 if (!f) {
9165 sigma_dut_print(dut, DUT_MSG_ERROR, "failed to open: %s", buf);
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +02009166 /* newer wil6210 driver renamed file to "rings" */
Jouni Malinen3aa72862019-05-29 23:14:51 +03009167 res = snprintf(buf, sizeof(buf), "%s/rings", dir);
9168 if (res < 0 || res >= sizeof(buf))
9169 return -1;
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +02009170 f = fopen(buf, "r");
9171 if (!f) {
9172 sigma_dut_print(dut, DUT_MSG_ERROR,
9173 "failed to open: %s", buf);
9174 return -1;
9175 }
Lior David9981b512017-01-20 13:16:40 +02009176 }
9177
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +02009178 /* can be either VRING tx... or RING... */
9179 if (regcomp(&re, "RING tx_[ \t]*([0-9]+)", REG_EXTENDED)) {
Lior David9981b512017-01-20 13:16:40 +02009180 sigma_dut_print(dut, DUT_MSG_ERROR, "regcomp failed");
9181 goto out;
9182 }
9183
9184 /* find TX VRING for the mac address */
9185 found = 0;
9186 while (fgets(buf, sizeof(buf), f)) {
9187 if (strcasestr(buf, dest_mac)) {
9188 found = 1;
9189 break;
9190 }
9191 }
9192
9193 if (!found) {
9194 sigma_dut_print(dut, DUT_MSG_ERROR,
9195 "no TX VRING for %s", dest_mac);
9196 goto out;
9197 }
9198
9199 /* extract VRING ID, "VRING tx_<id> = {" */
9200 if (!fgets(buf, sizeof(buf), f)) {
9201 sigma_dut_print(dut, DUT_MSG_ERROR,
9202 "no VRING start line for %s", dest_mac);
9203 goto out;
9204 }
9205
9206 rc = regexec(&re, buf, 2, m, 0);
9207 regfree(&re);
9208 if (rc || m[1].rm_so < 0) {
9209 sigma_dut_print(dut, DUT_MSG_ERROR,
9210 "no VRING TX ID for %s", dest_mac);
9211 goto out;
9212 }
9213 buf[m[1].rm_eo] = 0;
9214 vring_id = atoi(&buf[m[1].rm_so]);
9215
9216 /* send the addba command */
9217 fclose(f);
Jouni Malinen3aa72862019-05-29 23:14:51 +03009218 res = snprintf(buf, sizeof(buf), "%s/back", dir);
9219 if (res < 0 || res >= sizeof(buf))
9220 return -1;
Lior David9981b512017-01-20 13:16:40 +02009221 f = fopen(buf, "w");
9222 if (!f) {
9223 sigma_dut_print(dut, DUT_MSG_ERROR,
9224 "failed to open: %s", buf);
9225 return -1;
9226 }
9227
9228 fprintf(f, "add %d %d\n", vring_id, agg_size);
9229
9230 ret = 0;
9231
9232out:
9233 fclose(f);
9234
9235 return ret;
9236}
9237
9238
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +02009239int send_addba_60g(struct sigma_dut *dut, struct sigma_conn *conn,
9240 struct sigma_cmd *cmd, const char *mac_param)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009241{
9242 const char *val;
9243 int tid = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009244
9245 val = get_param(cmd, "TID");
9246 if (val) {
9247 tid = atoi(val);
9248 if (tid != 0) {
9249 sigma_dut_print(dut, DUT_MSG_ERROR,
9250 "Ignore TID %d for send_addba use TID 0 for 60g since only 0 required on TX",
9251 tid);
9252 }
9253 }
9254
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +02009255 val = get_param(cmd, mac_param);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009256 if (!val) {
9257 sigma_dut_print(dut, DUT_MSG_ERROR,
9258 "Currently not supporting addba for 60G without Dest_mac");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02009259 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009260 }
9261
Lior David9981b512017-01-20 13:16:40 +02009262 if (wil6210_send_addba(dut, val, dut->back_rcv_buf))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009263 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009264
9265 return 1;
9266}
9267
Lior David9981b512017-01-20 13:16:40 +02009268#endif /* __linux__ */
9269
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009270
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009271static int wcn_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
9272 struct sigma_cmd *cmd)
9273{
9274#ifdef NL80211_SUPPORT
9275 const char *intf = get_param(cmd, "Interface");
9276 const char *val;
9277 int tid = -1;
9278 int bufsize = 64;
9279 struct nl_msg *msg;
9280 int ret = 0;
9281 struct nlattr *params;
9282 int ifindex;
9283
9284 val = get_param(cmd, "TID");
9285 if (val)
9286 tid = atoi(val);
9287
9288 if (tid == -1) {
9289 send_resp(dut, conn, SIGMA_ERROR,
9290 "ErrorCode,sta_send_addba tid invalid");
9291 return 0;
9292 }
9293
9294 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
9295
9296 ifindex = if_nametoindex(intf);
9297 if (ifindex == 0) {
9298 sigma_dut_print(dut, DUT_MSG_ERROR,
9299 "%s: Index for interface %s failed",
9300 __func__, intf);
9301 send_resp(dut, conn, SIGMA_ERROR,
9302 "ErrorCode,sta_send_addba interface invalid");
9303 return 0;
9304 }
9305
9306 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
9307 NL80211_CMD_VENDOR)) ||
9308 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
9309 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
9310 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
9311 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
9312 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
9313 nla_put_u8(msg,
9314 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADD_DEL_BA_SESSION,
9315 QCA_WLAN_ADD_BA) ||
9316 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BA_TID,
9317 tid) ||
Kiran Kumar Lokere26e27582018-08-01 16:18:34 -07009318 nla_put_u16(msg,
9319 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE,
9320 bufsize)) {
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009321 sigma_dut_print(dut, DUT_MSG_ERROR,
9322 "%s: err in adding vendor_cmd and vendor_data",
9323 __func__);
9324 nlmsg_free(msg);
9325 send_resp(dut, conn, SIGMA_ERROR,
9326 "ErrorCode,sta_send_addba err in adding vendor_cmd and vendor_data");
9327 return 0;
9328 }
9329 nla_nest_end(msg, params);
9330
9331 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
9332 if (ret) {
9333 sigma_dut_print(dut, DUT_MSG_ERROR,
9334 "%s: err in send_and_recv_msgs, ret=%d",
9335 __func__, ret);
Sunil Dutt30605592018-05-04 20:35:50 +05309336 if (ret == -EOPNOTSUPP)
9337 return 1;
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009338 send_resp(dut, conn, SIGMA_ERROR,
9339 "ErrorCode,sta_send_addba err in send_and_recv_msgs");
9340 return 0;
9341 }
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009342#else /* NL80211_SUPPORT */
9343 sigma_dut_print(dut, DUT_MSG_ERROR,
9344 "sta_send_addba not supported without NL80211_SUPPORT defined");
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009345#endif /* NL80211_SUPPORT */
Sunil Dutt30605592018-05-04 20:35:50 +05309346
9347 return 1;
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009348}
9349
9350
Jouni Malinenf7222712019-06-13 01:50:21 +03009351static enum sigma_cmd_result cmd_sta_send_addba(struct sigma_dut *dut,
9352 struct sigma_conn *conn,
9353 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009354{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009355 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009356 case DRIVER_ATHEROS:
9357 return ath_sta_send_addba(dut, conn, cmd);
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009358 case DRIVER_WCN:
9359 return wcn_sta_send_addba(dut, conn, cmd);
Lior David9981b512017-01-20 13:16:40 +02009360#ifdef __linux__
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009361 case DRIVER_WIL6210:
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +02009362 return send_addba_60g(dut, conn, cmd, "Dest_mac");
Lior David9981b512017-01-20 13:16:40 +02009363#endif /* __linux__ */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009364 default:
9365 /*
9366 * There is no driver specific implementation for other drivers.
9367 * Ignore the command and report COMPLETE since the following
9368 * throughput test operation will end up sending ADDBA anyway.
9369 */
9370 return 1;
9371 }
9372}
9373
9374
9375int inject_eth_frame(int s, const void *data, size_t len,
9376 unsigned short ethtype, char *dst, char *src)
9377{
9378 struct iovec iov[4] = {
9379 {
9380 .iov_base = dst,
9381 .iov_len = ETH_ALEN,
9382 },
9383 {
9384 .iov_base = src,
9385 .iov_len = ETH_ALEN,
9386 },
9387 {
9388 .iov_base = &ethtype,
9389 .iov_len = sizeof(unsigned short),
9390 },
9391 {
9392 .iov_base = (void *) data,
9393 .iov_len = len,
9394 }
9395 };
9396 struct msghdr msg = {
9397 .msg_name = NULL,
9398 .msg_namelen = 0,
9399 .msg_iov = iov,
9400 .msg_iovlen = 4,
9401 .msg_control = NULL,
9402 .msg_controllen = 0,
9403 .msg_flags = 0,
9404 };
9405
9406 return sendmsg(s, &msg, 0);
9407}
9408
9409#if defined(__linux__) || defined(__QNXNTO__)
9410
9411int inject_frame(int s, const void *data, size_t len, int encrypt)
9412{
9413#define IEEE80211_RADIOTAP_F_WEP 0x04
9414#define IEEE80211_RADIOTAP_F_FRAG 0x08
9415 unsigned char rtap_hdr[] = {
9416 0x00, 0x00, /* radiotap version */
9417 0x0e, 0x00, /* radiotap length */
9418 0x02, 0xc0, 0x00, 0x00, /* bmap: flags, tx and rx flags */
9419 IEEE80211_RADIOTAP_F_FRAG, /* F_FRAG (fragment if required) */
9420 0x00, /* padding */
9421 0x00, 0x00, /* RX and TX flags to indicate that */
9422 0x00, 0x00, /* this is the injected frame directly */
9423 };
9424 struct iovec iov[2] = {
9425 {
9426 .iov_base = &rtap_hdr,
9427 .iov_len = sizeof(rtap_hdr),
9428 },
9429 {
9430 .iov_base = (void *) data,
9431 .iov_len = len,
9432 }
9433 };
9434 struct msghdr msg = {
9435 .msg_name = NULL,
9436 .msg_namelen = 0,
9437 .msg_iov = iov,
9438 .msg_iovlen = 2,
9439 .msg_control = NULL,
9440 .msg_controllen = 0,
9441 .msg_flags = 0,
9442 };
9443
9444 if (encrypt)
9445 rtap_hdr[8] |= IEEE80211_RADIOTAP_F_WEP;
9446
9447 return sendmsg(s, &msg, 0);
9448}
9449
9450
9451int open_monitor(const char *ifname)
9452{
9453#ifdef __QNXNTO__
9454 struct sockaddr_dl ll;
9455 int s;
9456
9457 memset(&ll, 0, sizeof(ll));
9458 ll.sdl_family = AF_LINK;
9459 ll.sdl_index = if_nametoindex(ifname);
9460 if (ll.sdl_index == 0) {
9461 perror("if_nametoindex");
9462 return -1;
9463 }
9464 s = socket(PF_INET, SOCK_RAW, 0);
9465#else /* __QNXNTO__ */
9466 struct sockaddr_ll ll;
9467 int s;
9468
9469 memset(&ll, 0, sizeof(ll));
9470 ll.sll_family = AF_PACKET;
9471 ll.sll_ifindex = if_nametoindex(ifname);
9472 if (ll.sll_ifindex == 0) {
9473 perror("if_nametoindex");
9474 return -1;
9475 }
9476 s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
9477#endif /* __QNXNTO__ */
9478 if (s < 0) {
9479 perror("socket[PF_PACKET,SOCK_RAW]");
9480 return -1;
9481 }
9482
9483 if (bind(s, (struct sockaddr *) &ll, sizeof(ll)) < 0) {
9484 perror("monitor socket bind");
9485 close(s);
9486 return -1;
9487 }
9488
9489 return s;
9490}
9491
9492
9493static int hex2num(char c)
9494{
9495 if (c >= '0' && c <= '9')
9496 return c - '0';
9497 if (c >= 'a' && c <= 'f')
9498 return c - 'a' + 10;
9499 if (c >= 'A' && c <= 'F')
9500 return c - 'A' + 10;
9501 return -1;
9502}
9503
9504
9505int hwaddr_aton(const char *txt, unsigned char *addr)
9506{
9507 int i;
9508
9509 for (i = 0; i < 6; i++) {
9510 int a, b;
9511
9512 a = hex2num(*txt++);
9513 if (a < 0)
9514 return -1;
9515 b = hex2num(*txt++);
9516 if (b < 0)
9517 return -1;
9518 *addr++ = (a << 4) | b;
9519 if (i < 5 && *txt++ != ':')
9520 return -1;
9521 }
9522
9523 return 0;
9524}
9525
9526#endif /* defined(__linux__) || defined(__QNXNTO__) */
9527
9528enum send_frame_type {
9529 DISASSOC, DEAUTH, SAQUERY, AUTH, ASSOCREQ, REASSOCREQ, DLS_REQ
9530};
9531enum send_frame_protection {
9532 CORRECT_KEY, INCORRECT_KEY, UNPROTECTED
9533};
9534
9535
9536static int sta_inject_frame(struct sigma_dut *dut, struct sigma_conn *conn,
9537 enum send_frame_type frame,
9538 enum send_frame_protection protected,
9539 const char *dest)
9540{
9541#ifdef __linux__
9542 unsigned char buf[1000], *pos;
9543 int s, res;
9544 char bssid[20], addr[20];
9545 char result[32], ssid[100];
9546 size_t ssid_len;
9547
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009548 if (get_wpa_status(get_station_ifname(dut), "wpa_state", result,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009549 sizeof(result)) < 0 ||
9550 strncmp(result, "COMPLETED", 9) != 0) {
9551 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Not connected");
9552 return 0;
9553 }
9554
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009555 if (get_wpa_status(get_station_ifname(dut), "bssid",
9556 bssid, sizeof(bssid)) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009557 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
9558 "current BSSID");
9559 return 0;
9560 }
9561
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009562 if (get_wpa_status(get_station_ifname(dut), "address",
9563 addr, sizeof(addr)) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009564 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
9565 "own MAC address");
9566 return 0;
9567 }
9568
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009569 if (get_wpa_status(get_station_ifname(dut), "ssid", ssid, sizeof(ssid))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009570 < 0) {
9571 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
9572 "current SSID");
9573 return 0;
9574 }
9575 ssid_len = strlen(ssid);
9576
9577 pos = buf;
9578
9579 /* Frame Control */
9580 switch (frame) {
9581 case DISASSOC:
9582 *pos++ = 0xa0;
9583 break;
9584 case DEAUTH:
9585 *pos++ = 0xc0;
9586 break;
9587 case SAQUERY:
9588 *pos++ = 0xd0;
9589 break;
9590 case AUTH:
9591 *pos++ = 0xb0;
9592 break;
9593 case ASSOCREQ:
9594 *pos++ = 0x00;
9595 break;
9596 case REASSOCREQ:
9597 *pos++ = 0x20;
9598 break;
9599 case DLS_REQ:
9600 *pos++ = 0xd0;
9601 break;
9602 }
9603
9604 if (protected == INCORRECT_KEY)
9605 *pos++ = 0x40; /* Set Protected field to 1 */
9606 else
9607 *pos++ = 0x00;
9608
9609 /* Duration */
9610 *pos++ = 0x00;
9611 *pos++ = 0x00;
9612
9613 /* addr1 = DA (current AP) */
9614 hwaddr_aton(bssid, pos);
9615 pos += 6;
9616 /* addr2 = SA (own address) */
9617 hwaddr_aton(addr, pos);
9618 pos += 6;
9619 /* addr3 = BSSID (current AP) */
9620 hwaddr_aton(bssid, pos);
9621 pos += 6;
9622
9623 /* Seq# (to be filled by driver/mac80211) */
9624 *pos++ = 0x00;
9625 *pos++ = 0x00;
9626
9627 if (protected == INCORRECT_KEY) {
9628 /* CCMP parameters */
9629 memcpy(pos, "\x61\x01\x00\x20\x00\x10\x00\x00", 8);
9630 pos += 8;
9631 }
9632
9633 if (protected == INCORRECT_KEY) {
9634 switch (frame) {
9635 case DEAUTH:
9636 /* Reason code (encrypted) */
9637 memcpy(pos, "\xa7\x39", 2);
9638 pos += 2;
9639 break;
9640 case DISASSOC:
9641 /* Reason code (encrypted) */
9642 memcpy(pos, "\xa7\x39", 2);
9643 pos += 2;
9644 break;
9645 case SAQUERY:
9646 /* Category|Action|TransID (encrypted) */
9647 memcpy(pos, "\x6f\xbd\xe9\x4d", 4);
9648 pos += 4;
9649 break;
9650 default:
9651 return -1;
9652 }
9653
9654 /* CCMP MIC */
9655 memcpy(pos, "\xc8\xd8\x3b\x06\x5d\xb7\x25\x68", 8);
9656 pos += 8;
9657 } else {
9658 switch (frame) {
9659 case DEAUTH:
9660 /* reason code = 8 */
9661 *pos++ = 0x08;
9662 *pos++ = 0x00;
9663 break;
9664 case DISASSOC:
9665 /* reason code = 8 */
9666 *pos++ = 0x08;
9667 *pos++ = 0x00;
9668 break;
9669 case SAQUERY:
9670 /* Category - SA Query */
9671 *pos++ = 0x08;
9672 /* SA query Action - Request */
9673 *pos++ = 0x00;
9674 /* Transaction ID */
9675 *pos++ = 0x12;
9676 *pos++ = 0x34;
9677 break;
9678 case AUTH:
9679 /* Auth Alg (Open) */
9680 *pos++ = 0x00;
9681 *pos++ = 0x00;
9682 /* Seq# */
9683 *pos++ = 0x01;
9684 *pos++ = 0x00;
9685 /* Status code */
9686 *pos++ = 0x00;
9687 *pos++ = 0x00;
9688 break;
9689 case ASSOCREQ:
9690 /* Capability Information */
9691 *pos++ = 0x31;
9692 *pos++ = 0x04;
9693 /* Listen Interval */
9694 *pos++ = 0x0a;
9695 *pos++ = 0x00;
9696 /* SSID */
9697 *pos++ = 0x00;
9698 *pos++ = ssid_len;
9699 memcpy(pos, ssid, ssid_len);
9700 pos += ssid_len;
9701 /* Supported Rates */
9702 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
9703 10);
9704 pos += 10;
9705 /* Extended Supported Rates */
9706 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
9707 pos += 6;
9708 /* RSN */
9709 memcpy(pos, "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00"
9710 "\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x02\xc0"
9711 "\x00\x00\x00\x00\x0f\xac\x06", 28);
9712 pos += 28;
9713 break;
9714 case REASSOCREQ:
9715 /* Capability Information */
9716 *pos++ = 0x31;
9717 *pos++ = 0x04;
9718 /* Listen Interval */
9719 *pos++ = 0x0a;
9720 *pos++ = 0x00;
9721 /* Current AP */
9722 hwaddr_aton(bssid, pos);
9723 pos += 6;
9724 /* SSID */
9725 *pos++ = 0x00;
9726 *pos++ = ssid_len;
9727 memcpy(pos, ssid, ssid_len);
9728 pos += ssid_len;
9729 /* Supported Rates */
9730 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
9731 10);
9732 pos += 10;
9733 /* Extended Supported Rates */
9734 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
9735 pos += 6;
9736 /* RSN */
9737 memcpy(pos, "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00"
9738 "\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x02\xc0"
9739 "\x00\x00\x00\x00\x0f\xac\x06", 28);
9740 pos += 28;
9741 break;
9742 case DLS_REQ:
9743 /* Category - DLS */
9744 *pos++ = 0x02;
9745 /* DLS Action - Request */
9746 *pos++ = 0x00;
9747 /* Destination MACAddress */
9748 if (dest)
9749 hwaddr_aton(dest, pos);
9750 else
9751 memset(pos, 0, 6);
9752 pos += 6;
9753 /* Source MACAddress */
9754 hwaddr_aton(addr, pos);
9755 pos += 6;
9756 /* Capability Information */
9757 *pos++ = 0x10; /* Privacy */
9758 *pos++ = 0x06; /* QoS */
9759 /* DLS Timeout Value */
9760 *pos++ = 0x00;
9761 *pos++ = 0x01;
9762 /* Supported rates */
9763 *pos++ = 0x01;
9764 *pos++ = 0x08;
9765 *pos++ = 0x0c; /* 6 Mbps */
9766 *pos++ = 0x12; /* 9 Mbps */
9767 *pos++ = 0x18; /* 12 Mbps */
9768 *pos++ = 0x24; /* 18 Mbps */
9769 *pos++ = 0x30; /* 24 Mbps */
9770 *pos++ = 0x48; /* 36 Mbps */
9771 *pos++ = 0x60; /* 48 Mbps */
9772 *pos++ = 0x6c; /* 54 Mbps */
9773 /* TODO: Extended Supported Rates */
9774 /* TODO: HT Capabilities */
9775 break;
9776 }
9777 }
9778
9779 s = open_monitor("sigmadut");
9780 if (s < 0) {
9781 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
9782 "monitor socket");
9783 return 0;
9784 }
9785
9786 res = inject_frame(s, buf, pos - buf, protected == CORRECT_KEY);
9787 if (res < 0) {
9788 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
9789 "inject frame");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05309790 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009791 return 0;
9792 }
9793 if (res < pos - buf) {
9794 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Only partial "
9795 "frame sent");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05309796 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009797 return 0;
9798 }
9799
9800 close(s);
9801
9802 return 1;
9803#else /* __linux__ */
9804 send_resp(dut, conn, SIGMA_ERROR, "errorCode,sta_send_frame not "
9805 "yet supported");
9806 return 0;
9807#endif /* __linux__ */
9808}
9809
9810
9811static int cmd_sta_send_frame_tdls(struct sigma_dut *dut,
9812 struct sigma_conn *conn,
9813 struct sigma_cmd *cmd)
9814{
9815 const char *intf = get_param(cmd, "Interface");
9816 const char *sta, *val;
9817 unsigned char addr[ETH_ALEN];
9818 char buf[100];
9819
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +03009820 if (!intf)
9821 return -1;
9822
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009823 sta = get_param(cmd, "peer");
9824 if (sta == NULL)
9825 sta = get_param(cmd, "station");
9826 if (sta == NULL) {
9827 send_resp(dut, conn, SIGMA_ERROR,
9828 "ErrorCode,Missing peer address");
9829 return 0;
9830 }
9831 if (hwaddr_aton(sta, addr) < 0) {
9832 send_resp(dut, conn, SIGMA_ERROR,
9833 "ErrorCode,Invalid peer address");
9834 return 0;
9835 }
9836
9837 val = get_param(cmd, "type");
9838 if (val == NULL)
9839 return -1;
9840
9841 if (strcasecmp(val, "DISCOVERY") == 0) {
9842 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", sta);
9843 if (wpa_command(intf, buf) < 0) {
9844 send_resp(dut, conn, SIGMA_ERROR,
9845 "ErrorCode,Failed to send TDLS discovery");
9846 return 0;
9847 }
9848 return 1;
9849 }
9850
9851 if (strcasecmp(val, "SETUP") == 0) {
9852 int status = 0, timeout = 0;
9853
9854 val = get_param(cmd, "Status");
9855 if (val)
9856 status = atoi(val);
9857
9858 val = get_param(cmd, "Timeout");
9859 if (val)
9860 timeout = atoi(val);
9861
9862 if (status != 0 && status != 37) {
9863 send_resp(dut, conn, SIGMA_ERROR,
9864 "ErrorCode,Unsupported status value");
9865 return 0;
9866 }
9867
9868 if (timeout != 0 && timeout != 301) {
9869 send_resp(dut, conn, SIGMA_ERROR,
9870 "ErrorCode,Unsupported timeout value");
9871 return 0;
9872 }
9873
9874 if (status && timeout) {
9875 send_resp(dut, conn, SIGMA_ERROR,
9876 "ErrorCode,Unsupported timeout+status "
9877 "combination");
9878 return 0;
9879 }
9880
9881 if (status == 37 &&
9882 wpa_command(intf, "SET tdls_testing 0x200")) {
9883 send_resp(dut, conn, SIGMA_ERROR,
9884 "ErrorCode,Failed to enable "
9885 "decline setup response test mode");
9886 return 0;
9887 }
9888
9889 if (timeout == 301) {
9890 int res;
9891 if (dut->no_tpk_expiration)
9892 res = wpa_command(intf,
9893 "SET tdls_testing 0x108");
9894 else
9895 res = wpa_command(intf,
9896 "SET tdls_testing 0x8");
9897 if (res) {
9898 send_resp(dut, conn, SIGMA_ERROR,
9899 "ErrorCode,Failed to set short TPK "
9900 "lifetime");
9901 return 0;
9902 }
9903 }
9904
9905 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", sta);
9906 if (wpa_command(intf, buf) < 0) {
9907 send_resp(dut, conn, SIGMA_ERROR,
9908 "ErrorCode,Failed to send TDLS setup");
9909 return 0;
9910 }
9911 return 1;
9912 }
9913
9914 if (strcasecmp(val, "TEARDOWN") == 0) {
9915 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", sta);
9916 if (wpa_command(intf, buf) < 0) {
9917 send_resp(dut, conn, SIGMA_ERROR,
9918 "ErrorCode,Failed to send TDLS teardown");
9919 return 0;
9920 }
9921 return 1;
9922 }
9923
9924 send_resp(dut, conn, SIGMA_ERROR,
9925 "ErrorCode,Unsupported TDLS frame");
9926 return 0;
9927}
9928
9929
9930static int sta_ap_known(const char *ifname, const char *bssid)
9931{
9932 char buf[4096];
9933
Jouni Malinendd32f192018-09-15 02:55:19 +03009934 snprintf(buf, sizeof(buf), "BSS MASK=1 %s", bssid);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009935 if (wpa_command_resp(ifname, buf, buf, sizeof(buf)) < 0)
9936 return 0;
9937 if (strncmp(buf, "id=", 3) != 0)
9938 return 0;
9939 return 1;
9940}
9941
9942
9943static int sta_scan_ap(struct sigma_dut *dut, const char *ifname,
9944 const char *bssid)
9945{
9946 int res;
9947 struct wpa_ctrl *ctrl;
9948 char buf[256];
9949
9950 if (sta_ap_known(ifname, bssid))
9951 return 0;
9952 sigma_dut_print(dut, DUT_MSG_DEBUG,
9953 "AP not in BSS table - start scan");
9954
9955 ctrl = open_wpa_mon(ifname);
9956 if (ctrl == NULL) {
9957 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
9958 "wpa_supplicant monitor connection");
9959 return -1;
9960 }
9961
9962 if (wpa_command(ifname, "SCAN") < 0) {
9963 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to start scan");
9964 wpa_ctrl_detach(ctrl);
9965 wpa_ctrl_close(ctrl);
9966 return -1;
9967 }
9968
9969 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
9970 buf, sizeof(buf));
9971
9972 wpa_ctrl_detach(ctrl);
9973 wpa_ctrl_close(ctrl);
9974
9975 if (res < 0) {
9976 sigma_dut_print(dut, DUT_MSG_INFO, "Scan did not complete");
9977 return -1;
9978 }
9979
9980 if (sta_ap_known(ifname, bssid))
9981 return 0;
9982 sigma_dut_print(dut, DUT_MSG_INFO, "AP not in BSS table");
9983 return -1;
9984}
9985
9986
9987static int cmd_sta_send_frame_hs2_neighadv(struct sigma_dut *dut,
9988 struct sigma_conn *conn,
9989 struct sigma_cmd *cmd,
9990 const char *intf)
9991{
9992 char buf[200];
9993
9994 snprintf(buf, sizeof(buf), "ndsend 2001:DB8::1 %s", intf);
9995 if (system(buf) != 0) {
9996 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Failed to run "
9997 "ndsend");
9998 return 0;
9999 }
10000
10001 return 1;
10002}
10003
10004
10005static int cmd_sta_send_frame_hs2_neighsolreq(struct sigma_dut *dut,
10006 struct sigma_conn *conn,
10007 struct sigma_cmd *cmd,
10008 const char *intf)
10009{
10010 char buf[200];
10011 const char *ip = get_param(cmd, "SenderIP");
10012
Peng Xu26b356d2017-10-04 17:58:16 -070010013 if (!ip)
10014 return 0;
10015
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010016 snprintf(buf, sizeof(buf), "ndisc6 -nm %s %s -r 4", ip, intf);
10017 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10018 if (system(buf) == 0) {
10019 sigma_dut_print(dut, DUT_MSG_INFO,
10020 "Neighbor Solicitation got a response "
10021 "for %s@%s", ip, intf);
10022 }
10023
10024 return 1;
10025}
10026
10027
10028static int cmd_sta_send_frame_hs2_arpprobe(struct sigma_dut *dut,
10029 struct sigma_conn *conn,
10030 struct sigma_cmd *cmd,
10031 const char *ifname)
10032{
10033 char buf[200];
10034 const char *ip = get_param(cmd, "SenderIP");
10035
10036 if (ip == NULL) {
10037 send_resp(dut, conn, SIGMA_ERROR,
10038 "ErrorCode,Missing SenderIP parameter");
10039 return 0;
10040 }
10041 snprintf(buf, sizeof(buf), "arping -I %s -D %s -c 4", ifname, ip);
10042 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10043 if (system(buf) != 0) {
10044 sigma_dut_print(dut, DUT_MSG_INFO, "arping DAD got a response "
10045 "for %s@%s", ip, ifname);
10046 }
10047
10048 return 1;
10049}
10050
10051
10052static int cmd_sta_send_frame_hs2_arpannounce(struct sigma_dut *dut,
10053 struct sigma_conn *conn,
10054 struct sigma_cmd *cmd,
10055 const char *ifname)
10056{
10057 char buf[200];
10058 char ip[16];
10059 int s;
Peng Xub3756882017-10-04 14:39:09 -070010060 struct ifreq ifr;
10061 struct sockaddr_in saddr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010062
10063 s = socket(PF_INET, SOCK_DGRAM, 0);
Peng Xub3756882017-10-04 14:39:09 -070010064 if (s < 0) {
10065 perror("socket");
10066 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010067 }
10068
Peng Xub3756882017-10-04 14:39:09 -070010069 memset(&ifr, 0, sizeof(ifr));
10070 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
10071 if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
10072 sigma_dut_print(dut, DUT_MSG_INFO,
10073 "Failed to get %s IP address: %s",
10074 ifname, strerror(errno));
10075 close(s);
10076 return -1;
10077 }
10078 close(s);
10079
10080 memcpy(&saddr, &ifr.ifr_addr, sizeof(struct sockaddr_in));
10081 strlcpy(ip, inet_ntoa(saddr.sin_addr), sizeof(ip));
10082
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010083 snprintf(buf, sizeof(buf), "arping -I %s -s %s %s -c 4", ifname, ip,
10084 ip);
10085 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10086 if (system(buf) != 0) {
10087 }
10088
10089 return 1;
10090}
10091
10092
10093static int cmd_sta_send_frame_hs2_arpreply(struct sigma_dut *dut,
10094 struct sigma_conn *conn,
10095 struct sigma_cmd *cmd,
10096 const char *ifname)
10097{
10098 char buf[200], addr[20];
10099 char dst[ETH_ALEN], src[ETH_ALEN];
10100 short ethtype = htons(ETH_P_ARP);
10101 char *pos;
10102 int s, res;
10103 const char *val;
10104 struct sockaddr_in taddr;
10105
10106 val = get_param(cmd, "dest");
10107 if (val)
10108 hwaddr_aton(val, (unsigned char *) dst);
10109
10110 val = get_param(cmd, "DestIP");
10111 if (val)
10112 inet_aton(val, &taddr.sin_addr);
Peng Xu151c9e12017-10-04 14:39:09 -070010113 else
10114 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010115
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010116 if (get_wpa_status(get_station_ifname(dut), "address", addr,
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010117 sizeof(addr)) < 0)
10118 return -2;
10119 hwaddr_aton(addr, (unsigned char *) src);
10120
10121 pos = buf;
10122 *pos++ = 0x00;
10123 *pos++ = 0x01;
10124 *pos++ = 0x08;
10125 *pos++ = 0x00;
10126 *pos++ = 0x06;
10127 *pos++ = 0x04;
10128 *pos++ = 0x00;
10129 *pos++ = 0x02;
10130 memcpy(pos, src, ETH_ALEN);
10131 pos += ETH_ALEN;
10132 memcpy(pos, &taddr.sin_addr, 4);
10133 pos += 4;
10134 memcpy(pos, dst, ETH_ALEN);
10135 pos += ETH_ALEN;
10136 memcpy(pos, &taddr.sin_addr, 4);
10137 pos += 4;
10138
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010139 s = open_monitor(get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010140 if (s < 0) {
10141 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
10142 "monitor socket");
10143 return 0;
10144 }
10145
10146 res = inject_eth_frame(s, buf, pos - buf, ethtype, dst, src);
10147 if (res < 0) {
10148 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
10149 "inject frame");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +053010150 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010151 return 0;
10152 }
10153
10154 close(s);
10155
10156 return 1;
10157}
10158
10159
10160static int cmd_sta_send_frame_hs2_dls_req(struct sigma_dut *dut,
10161 struct sigma_conn *conn,
10162 struct sigma_cmd *cmd,
10163 const char *intf, const char *dest)
10164{
10165 char buf[100];
10166
10167 if (if_nametoindex("sigmadut") == 0) {
10168 snprintf(buf, sizeof(buf),
10169 "iw dev %s interface add sigmadut type monitor",
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010170 get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010171 if (system(buf) != 0 ||
10172 if_nametoindex("sigmadut") == 0) {
10173 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
10174 "monitor interface with '%s'", buf);
10175 return -2;
10176 }
10177 }
10178
10179 if (system("ifconfig sigmadut up") != 0) {
10180 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
10181 "monitor interface up");
10182 return -2;
10183 }
10184
10185 return sta_inject_frame(dut, conn, DLS_REQ, UNPROTECTED, dest);
10186}
10187
10188
10189static int cmd_sta_send_frame_hs2(struct sigma_dut *dut,
10190 struct sigma_conn *conn,
10191 struct sigma_cmd *cmd)
10192{
10193 const char *intf = get_param(cmd, "Interface");
10194 const char *dest = get_param(cmd, "Dest");
10195 const char *type = get_param(cmd, "FrameName");
10196 const char *val;
10197 char buf[200], *pos, *end;
10198 int count, count2;
10199
10200 if (type == NULL)
10201 type = get_param(cmd, "Type");
10202
10203 if (intf == NULL || dest == NULL || type == NULL)
10204 return -1;
10205
10206 if (strcasecmp(type, "NeighAdv") == 0)
10207 return cmd_sta_send_frame_hs2_neighadv(dut, conn, cmd, intf);
10208
10209 if (strcasecmp(type, "NeighSolicitReq") == 0)
10210 return cmd_sta_send_frame_hs2_neighsolreq(dut, conn, cmd, intf);
10211
10212 if (strcasecmp(type, "ARPProbe") == 0)
10213 return cmd_sta_send_frame_hs2_arpprobe(dut, conn, cmd, intf);
10214
10215 if (strcasecmp(type, "ARPAnnounce") == 0)
10216 return cmd_sta_send_frame_hs2_arpannounce(dut, conn, cmd, intf);
10217
10218 if (strcasecmp(type, "ARPReply") == 0)
10219 return cmd_sta_send_frame_hs2_arpreply(dut, conn, cmd, intf);
10220
10221 if (strcasecmp(type, "DLS-request") == 0 ||
10222 strcasecmp(type, "DLSrequest") == 0)
10223 return cmd_sta_send_frame_hs2_dls_req(dut, conn, cmd, intf,
10224 dest);
10225
10226 if (strcasecmp(type, "ANQPQuery") != 0 &&
10227 strcasecmp(type, "Query") != 0) {
10228 send_resp(dut, conn, SIGMA_ERROR,
10229 "ErrorCode,Unsupported HS 2.0 send frame type");
10230 return 0;
10231 }
10232
10233 if (sta_scan_ap(dut, intf, dest) < 0) {
10234 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not find "
10235 "the requested AP");
10236 return 0;
10237 }
10238
10239 pos = buf;
10240 end = buf + sizeof(buf);
10241 count = 0;
10242 pos += snprintf(pos, end - pos, "ANQP_GET %s ", dest);
10243
10244 val = get_param(cmd, "ANQP_CAP_LIST");
10245 if (val && atoi(val)) {
10246 pos += snprintf(pos, end - pos, "%s257", count > 0 ? "," : "");
10247 count++;
10248 }
10249
10250 val = get_param(cmd, "VENUE_NAME");
10251 if (val && atoi(val)) {
10252 pos += snprintf(pos, end - pos, "%s258", count > 0 ? "," : "");
10253 count++;
10254 }
10255
10256 val = get_param(cmd, "NETWORK_AUTH_TYPE");
10257 if (val && atoi(val)) {
10258 pos += snprintf(pos, end - pos, "%s260", count > 0 ? "," : "");
10259 count++;
10260 }
10261
10262 val = get_param(cmd, "ROAMING_CONS");
10263 if (val && atoi(val)) {
10264 pos += snprintf(pos, end - pos, "%s261", count > 0 ? "," : "");
10265 count++;
10266 }
10267
10268 val = get_param(cmd, "IP_ADDR_TYPE_AVAILABILITY");
10269 if (val && atoi(val)) {
10270 pos += snprintf(pos, end - pos, "%s262", count > 0 ? "," : "");
10271 count++;
10272 }
10273
10274 val = get_param(cmd, "NAI_REALM_LIST");
10275 if (val && atoi(val)) {
10276 pos += snprintf(pos, end - pos, "%s263", count > 0 ? "," : "");
10277 count++;
10278 }
10279
10280 val = get_param(cmd, "3GPP_INFO");
10281 if (val && atoi(val)) {
10282 pos += snprintf(pos, end - pos, "%s264", count > 0 ? "," : "");
10283 count++;
10284 }
10285
10286 val = get_param(cmd, "DOMAIN_LIST");
10287 if (val && atoi(val)) {
10288 pos += snprintf(pos, end - pos, "%s268", count > 0 ? "," : "");
10289 count++;
10290 }
10291
Jouni Malinen34cf9532018-04-29 19:26:33 +030010292 val = get_param(cmd, "Venue_URL");
10293 if (val && atoi(val)) {
10294 pos += snprintf(pos, end - pos, "%s277", count > 0 ? "," : "");
10295 count++;
10296 }
10297
Jouni Malinend3bca5d2018-04-29 17:25:23 +030010298 val = get_param(cmd, "Advice_Of_Charge");
10299 if (val && atoi(val)) {
10300 pos += snprintf(pos, end - pos, "%s278", count > 0 ? "," : "");
10301 count++;
10302 }
10303
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010304 if (count && wpa_command(intf, buf)) {
10305 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,ANQP_GET failed");
10306 return 0;
10307 }
10308
10309 pos = buf;
10310 end = buf + sizeof(buf);
10311 count2 = 0;
10312 pos += snprintf(pos, end - pos, "HS20_ANQP_GET %s ", dest);
10313
10314 val = get_param(cmd, "HS_CAP_LIST");
10315 if (val && atoi(val)) {
10316 pos += snprintf(pos, end - pos, "%s2", count2 > 0 ? "," : "");
10317 count2++;
10318 }
10319
10320 val = get_param(cmd, "OPER_NAME");
10321 if (val && atoi(val)) {
10322 pos += snprintf(pos, end - pos, "%s3", count2 > 0 ? "," : "");
10323 count2++;
10324 }
10325
10326 val = get_param(cmd, "WAN_METRICS");
10327 if (!val)
10328 val = get_param(cmd, "WAN_MAT");
10329 if (!val)
10330 val = get_param(cmd, "WAN_MET");
10331 if (val && atoi(val)) {
10332 pos += snprintf(pos, end - pos, "%s4", count2 > 0 ? "," : "");
10333 count2++;
10334 }
10335
10336 val = get_param(cmd, "CONNECTION_CAPABILITY");
10337 if (val && atoi(val)) {
10338 pos += snprintf(pos, end - pos, "%s5", count2 > 0 ? "," : "");
10339 count2++;
10340 }
10341
10342 val = get_param(cmd, "OP_CLASS");
10343 if (val && atoi(val)) {
10344 pos += snprintf(pos, end - pos, "%s7", count2 > 0 ? "," : "");
10345 count2++;
10346 }
10347
10348 val = get_param(cmd, "OSU_PROVIDER_LIST");
10349 if (val && atoi(val)) {
10350 pos += snprintf(pos, end - pos, "%s8", count2 > 0 ? "," : "");
10351 count2++;
10352 }
10353
Jouni Malinenf67afec2018-04-29 19:24:58 +030010354 val = get_param(cmd, "OPER_ICON_METADATA");
10355 if (!val)
10356 val = get_param(cmd, "OPERATOR_ICON_METADATA");
10357 if (val && atoi(val)) {
10358 pos += snprintf(pos, end - pos, "%s12", count2 > 0 ? "," : "");
10359 count2++;
10360 }
10361
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010362 if (count && count2) {
10363 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before sending out "
10364 "second query");
10365 sleep(1);
10366 }
10367
10368 if (count2 && wpa_command(intf, buf)) {
10369 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,HS20_ANQP_GET "
10370 "failed");
10371 return 0;
10372 }
10373
10374 val = get_param(cmd, "NAI_HOME_REALM_LIST");
10375 if (val) {
10376 if (count || count2) {
10377 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
10378 "sending out second query");
10379 sleep(1);
10380 }
10381
10382 if (strcmp(val, "1") == 0)
10383 val = "mail.example.com";
10384 snprintf(buf, end - pos,
10385 "HS20_GET_NAI_HOME_REALM_LIST %s realm=%s",
10386 dest, val);
10387 if (wpa_command(intf, buf)) {
10388 send_resp(dut, conn, SIGMA_ERROR,
10389 "ErrorCode,HS20_GET_NAI_HOME_REALM_LIST "
10390 "failed");
10391 return 0;
10392 }
10393 }
10394
10395 val = get_param(cmd, "ICON_REQUEST");
10396 if (val) {
10397 if (count || count2) {
10398 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
10399 "sending out second query");
10400 sleep(1);
10401 }
10402
10403 snprintf(buf, end - pos,
10404 "HS20_ICON_REQUEST %s %s", dest, val);
10405 if (wpa_command(intf, buf)) {
10406 send_resp(dut, conn, SIGMA_ERROR,
10407 "ErrorCode,HS20_ICON_REQUEST failed");
10408 return 0;
10409 }
10410 }
10411
10412 return 1;
10413}
10414
10415
10416static int ath_sta_send_frame_vht(struct sigma_dut *dut,
10417 struct sigma_conn *conn,
10418 struct sigma_cmd *cmd)
10419{
10420 const char *val;
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010421 const char *ifname;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010422 int chwidth, nss;
10423
10424 val = get_param(cmd, "framename");
10425 if (!val)
10426 return -1;
10427 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
10428
10429 /* Command sequence to generate Op mode notification */
10430 if (val && strcasecmp(val, "Op_md_notif_frm") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010431 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010432
10433 /* Disable STBC */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010434 run_iwpriv(dut, ifname, "tx_stbc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010435
10436 /* Extract Channel width */
10437 val = get_param(cmd, "Channel_width");
10438 if (val) {
10439 switch (atoi(val)) {
10440 case 20:
10441 chwidth = 0;
10442 break;
10443 case 40:
10444 chwidth = 1;
10445 break;
10446 case 80:
10447 chwidth = 2;
10448 break;
10449 case 160:
10450 chwidth = 3;
10451 break;
10452 default:
10453 chwidth = 2;
10454 break;
10455 }
10456
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010457 run_iwpriv(dut, ifname, "chwidth %d", chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010458 }
10459
10460 /* Extract NSS */
10461 val = get_param(cmd, "NSS");
10462 if (val) {
10463 switch (atoi(val)) {
10464 case 1:
10465 nss = 1;
10466 break;
10467 case 2:
10468 nss = 3;
10469 break;
10470 case 3:
10471 nss = 7;
10472 break;
10473 default:
10474 /* We do not support NSS > 3 */
10475 nss = 3;
10476 break;
10477 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010478 run_iwpriv(dut, ifname, "rxchainmask %d", nss);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010479 }
10480
10481 /* Opmode notify */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010482 run_iwpriv(dut, ifname, "opmode_notify 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010483 }
10484
10485 return 1;
10486}
10487
10488
10489static int cmd_sta_send_frame_vht(struct sigma_dut *dut,
10490 struct sigma_conn *conn,
10491 struct sigma_cmd *cmd)
10492{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010493 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010494 case DRIVER_ATHEROS:
10495 return ath_sta_send_frame_vht(dut, conn, cmd);
10496 default:
10497 send_resp(dut, conn, SIGMA_ERROR,
10498 "errorCode,Unsupported sta_set_frame(VHT) with the current driver");
10499 return 0;
10500 }
10501}
10502
10503
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070010504static int wcn_sta_send_frame_he(struct sigma_dut *dut, struct sigma_conn *conn,
10505 struct sigma_cmd *cmd)
10506{
10507 const char *val;
10508 const char *intf = get_param(cmd, "Interface");
10509
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +030010510 if (!intf)
10511 return -1;
10512
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070010513 val = get_param(cmd, "framename");
10514 if (!val)
10515 return -1;
10516 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
10517
10518 /* Command sequence to generate Op mode notification */
10519 if (val && strcasecmp(val, "action") == 0) {
10520 val = get_param(cmd, "PPDUTxType");
10521 if (val && strcasecmp(val, "TB") == 0) {
10522 if (sta_set_action_tx_in_he_tb_ppdu(dut, intf, 1)) {
10523 sigma_dut_print(dut, DUT_MSG_ERROR,
10524 "failed to send TB PPDU Tx cfg");
10525 send_resp(dut, conn, SIGMA_ERROR,
10526 "ErrorCode,set TB PPDU Tx cfg failed");
10527 return 0;
10528 }
10529 return 1;
10530 }
10531
10532 sigma_dut_print(dut, DUT_MSG_ERROR,
10533 "Action Tx type is not defined");
10534 }
10535
10536 return 1;
10537}
10538
10539
10540static int cmd_sta_send_frame_he(struct sigma_dut *dut,
10541 struct sigma_conn *conn,
10542 struct sigma_cmd *cmd)
10543{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010544 switch (get_driver_type(dut)) {
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070010545 case DRIVER_WCN:
10546 return wcn_sta_send_frame_he(dut, conn, cmd);
10547 default:
10548 send_resp(dut, conn, SIGMA_ERROR,
10549 "errorCode,Unsupported sta_set_frame(HE) with the current driver");
10550 return 0;
10551 }
10552}
10553
10554
Lior David0fe101e2017-03-09 16:09:50 +020010555#ifdef __linux__
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030010556
10557static int
10558wil6210_send_p2p_frame_60g(struct sigma_dut *dut, struct sigma_cmd *cmd,
10559 const char *frame_name, const char *dest_mac)
10560{
10561 int isprobereq = strcasecmp(frame_name, "probereq") == 0;
10562 const char *ssid = get_param(cmd, "ssid");
10563 const char *countstr = get_param(cmd, "count");
10564 const char *channelstr = get_param(cmd, "channel");
10565 const char *group_id = get_param(cmd, "groupid");
10566 const char *client_id = get_param(cmd, "clientmac");
10567 int count, channel, freq, i;
10568 const char *fname;
10569 char frame[1024], src_mac[20], group_id_attr[25],
10570 device_macstr[3 * ETH_ALEN], client_mac[ETH_ALEN];
10571 const char *group_ssid;
10572 const int group_ssid_prefix_len = 9;
10573 struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *) frame;
10574 size_t framelen = sizeof(frame);
10575 struct template_frame_tag tags[2];
10576 size_t tags_total = ARRAY_SIZE(tags);
10577 int tag_index, len, dst_len;
10578
10579 if (!countstr || !channelstr) {
10580 sigma_dut_print(dut, DUT_MSG_ERROR,
10581 "Missing argument: count, channel");
10582 return -1;
10583 }
10584 if (isprobereq && !ssid) {
10585 sigma_dut_print(dut, DUT_MSG_ERROR,
10586 "Missing argument: ssid");
10587 return -1;
10588 }
10589 if (!isprobereq && (!group_id || !client_id)) {
10590 sigma_dut_print(dut, DUT_MSG_ERROR,
10591 "Missing argument: group_id, client_id");
10592 return -1;
10593 }
10594
10595 count = atoi(countstr);
10596 channel = atoi(channelstr);
10597 freq = channel_to_freq(dut, channel);
10598
10599 if (!freq) {
10600 sigma_dut_print(dut, DUT_MSG_ERROR,
10601 "invalid channel: %s", channelstr);
10602 return -1;
10603 }
10604
10605 if (isprobereq) {
10606 if (strcasecmp(ssid, "wildcard") == 0) {
10607 fname = "probe_req_wildcard.txt";
10608 } else if (strcasecmp(ssid, "P2P_Wildcard") == 0) {
10609 fname = "probe_req_P2P_Wildcard.txt";
10610 } else {
10611 sigma_dut_print(dut, DUT_MSG_ERROR,
10612 "invalid probe request type");
10613 return -1;
10614 }
10615 } else {
10616 fname = "P2P_device_discovery_req.txt";
10617 }
10618
10619 if (parse_template_frame_file(dut, fname, frame, &framelen,
10620 tags, &tags_total)) {
10621 sigma_dut_print(dut, DUT_MSG_ERROR,
10622 "invalid frame template: %s", fname);
10623 return -1;
10624 }
10625
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010626 if (get_wpa_status(get_station_ifname(dut), "address",
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030010627 src_mac, sizeof(src_mac)) < 0 ||
10628 parse_mac_address(dut, src_mac, &hdr->addr2[0]) ||
10629 parse_mac_address(dut, dest_mac, &hdr->addr1[0]))
10630 return -1;
10631 /* Use wildcard BSSID, since we are in PBSS */
10632 memset(&hdr->addr3, 0xFF, ETH_ALEN);
10633
10634 if (!isprobereq) {
10635 tag_index = find_template_frame_tag(tags, tags_total, 1);
10636 if (tag_index < 0) {
10637 sigma_dut_print(dut, DUT_MSG_ERROR,
10638 "can't find device id attribute");
10639 return -1;
10640 }
10641 if (parse_mac_address(dut, client_id,
10642 (unsigned char *) client_mac)) {
10643 sigma_dut_print(dut, DUT_MSG_ERROR,
10644 "invalid client_id: %s", client_id);
10645 return -1;
10646 }
10647 if (replace_p2p_attribute(dut, &frame[tags[tag_index].offset],
10648 framelen - tags[tag_index].offset,
10649 IEEE80211_P2P_ATTR_DEVICE_ID,
10650 client_mac, ETH_ALEN)) {
10651 sigma_dut_print(dut, DUT_MSG_ERROR,
10652 "fail to replace device id attribute");
10653 return -1;
10654 }
10655
10656 /*
10657 * group_id arg contains device MAC address followed by
10658 * space and SSID (DIRECT-somessid).
10659 * group id attribute contains device address (6 bytes)
10660 * followed by SSID prefix DIRECT-XX (9 bytes)
10661 */
10662 if (strlen(group_id) < sizeof(device_macstr)) {
10663 sigma_dut_print(dut, DUT_MSG_ERROR,
10664 "group_id arg too short");
10665 return -1;
10666 }
10667 memcpy(device_macstr, group_id, sizeof(device_macstr));
10668 device_macstr[sizeof(device_macstr) - 1] = '\0';
10669 if (parse_mac_address(dut, device_macstr,
10670 (unsigned char *) group_id_attr)) {
10671 sigma_dut_print(dut, DUT_MSG_ERROR,
10672 "fail to parse device address from group_id");
10673 return -1;
10674 }
10675 group_ssid = strchr(group_id, ' ');
10676 if (!group_ssid) {
10677 sigma_dut_print(dut, DUT_MSG_ERROR,
10678 "invalid group_id arg, no ssid");
10679 return -1;
10680 }
10681 group_ssid++;
10682 len = strlen(group_ssid);
10683 if (len < group_ssid_prefix_len) {
10684 sigma_dut_print(dut, DUT_MSG_ERROR,
10685 "group_id SSID too short");
10686 return -1;
10687 }
10688 dst_len = sizeof(group_id_attr) - ETH_ALEN;
10689 if (len > dst_len) {
10690 sigma_dut_print(dut, DUT_MSG_ERROR,
10691 "group_id SSID (%s) too long",
10692 group_ssid);
10693 return -1;
10694 }
10695
10696 memcpy(group_id_attr + ETH_ALEN, group_ssid, len);
10697 tag_index = find_template_frame_tag(tags, tags_total, 2);
10698 if (tag_index < 0) {
10699 sigma_dut_print(dut, DUT_MSG_ERROR,
10700 "can't find group id attribute");
10701 return -1;
10702 }
10703 if (replace_p2p_attribute(dut, &frame[tags[tag_index].offset],
10704 framelen - tags[tag_index].offset,
10705 IEEE80211_P2P_ATTR_GROUP_ID,
10706 group_id_attr,
10707 sizeof(group_id_attr))) {
10708 sigma_dut_print(dut, DUT_MSG_ERROR,
10709 "fail to replace group id attribute");
10710 return -1;
10711 }
10712 }
10713
10714 for (i = 0; i < count; i++) {
10715 if (wil6210_transmit_frame(dut, freq,
10716 WIL_TRANSMIT_FRAME_DEFAULT_ROC,
10717 frame, framelen)) {
10718 sigma_dut_print(dut, DUT_MSG_ERROR,
10719 "fail to transmit probe request frame");
10720 return -1;
10721 }
10722 }
10723
10724 return 0;
10725}
10726
10727
Lior David0fe101e2017-03-09 16:09:50 +020010728int wil6210_send_frame_60g(struct sigma_dut *dut, struct sigma_conn *conn,
10729 struct sigma_cmd *cmd)
10730{
10731 const char *frame_name = get_param(cmd, "framename");
10732 const char *mac = get_param(cmd, "dest_mac");
10733
10734 if (!frame_name || !mac) {
10735 sigma_dut_print(dut, DUT_MSG_ERROR,
10736 "framename and dest_mac must be provided");
10737 return -1;
10738 }
10739
10740 if (strcasecmp(frame_name, "brp") == 0) {
10741 const char *l_rx = get_param(cmd, "L-RX");
10742 int l_rx_i;
10743
10744 if (!l_rx) {
10745 sigma_dut_print(dut, DUT_MSG_ERROR,
10746 "L-RX must be provided");
10747 return -1;
10748 }
10749 l_rx_i = atoi(l_rx);
10750
10751 sigma_dut_print(dut, DUT_MSG_INFO,
10752 "dev_send_frame: BRP-RX, dest_mac %s, L-RX %s",
10753 mac, l_rx);
10754 if (l_rx_i != 16) {
10755 sigma_dut_print(dut, DUT_MSG_ERROR,
10756 "unsupported L-RX: %s", l_rx);
10757 return -1;
10758 }
10759
10760 if (wil6210_send_brp_rx(dut, mac, l_rx_i))
10761 return -1;
10762 } else if (strcasecmp(frame_name, "ssw") == 0) {
10763 sigma_dut_print(dut, DUT_MSG_INFO,
10764 "dev_send_frame: SLS, dest_mac %s", mac);
10765 if (wil6210_send_sls(dut, mac))
10766 return -1;
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030010767 } else if ((strcasecmp(frame_name, "probereq") == 0) ||
10768 (strcasecmp(frame_name, "devdiscreq") == 0)) {
10769 sigma_dut_print(dut, DUT_MSG_INFO,
10770 "dev_send_frame: %s, dest_mac %s", frame_name,
10771 mac);
10772 if (wil6210_send_p2p_frame_60g(dut, cmd, frame_name, mac))
10773 return -1;
Lior David0fe101e2017-03-09 16:09:50 +020010774 } else {
10775 sigma_dut_print(dut, DUT_MSG_ERROR,
10776 "unsupported frame type: %s", frame_name);
10777 return -1;
10778 }
10779
10780 return 1;
10781}
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030010782
Lior David0fe101e2017-03-09 16:09:50 +020010783#endif /* __linux__ */
10784
10785
10786static int cmd_sta_send_frame_60g(struct sigma_dut *dut,
10787 struct sigma_conn *conn,
10788 struct sigma_cmd *cmd)
10789{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010790 switch (get_driver_type(dut)) {
Lior David0fe101e2017-03-09 16:09:50 +020010791#ifdef __linux__
10792 case DRIVER_WIL6210:
10793 return wil6210_send_frame_60g(dut, conn, cmd);
10794#endif /* __linux__ */
10795 default:
10796 send_resp(dut, conn, SIGMA_ERROR,
10797 "errorCode,Unsupported sta_set_frame(60G) with the current driver");
10798 return 0;
10799 }
10800}
10801
10802
Ashwini Patildb59b3c2017-04-13 15:19:23 +053010803static int mbo_send_anqp_query(struct sigma_dut *dut, struct sigma_conn *conn,
10804 const char *intf, struct sigma_cmd *cmd)
10805{
10806 const char *val, *addr;
10807 char buf[100];
10808
10809 addr = get_param(cmd, "DestMac");
10810 if (!addr) {
10811 send_resp(dut, conn, SIGMA_INVALID,
10812 "ErrorCode,AP MAC address is missing");
10813 return 0;
10814 }
10815
10816 val = get_param(cmd, "ANQPQuery_ID");
10817 if (!val) {
10818 send_resp(dut, conn, SIGMA_INVALID,
10819 "ErrorCode,Missing ANQPQuery_ID");
10820 return 0;
10821 }
10822
10823 if (strcasecmp(val, "NeighborReportReq") == 0) {
10824 snprintf(buf, sizeof(buf), "ANQP_GET %s 272", addr);
10825 } else if (strcasecmp(val, "QueryListWithCellPref") == 0) {
10826 snprintf(buf, sizeof(buf), "ANQP_GET %s 272,mbo:2", addr);
10827 } else {
10828 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid ANQPQuery_ID: %s",
10829 val);
10830 send_resp(dut, conn, SIGMA_INVALID,
10831 "ErrorCode,Invalid ANQPQuery_ID");
10832 return 0;
10833 }
10834
Ashwini Patild174f2c2017-04-13 16:49:46 +053010835 /* Set gas_address3 field to IEEE 802.11-2012 standard compliant form
10836 * (Address3 = Wildcard BSSID when sent to not-associated AP;
10837 * if associated, AP BSSID).
10838 */
10839 if (wpa_command(intf, "SET gas_address3 1") < 0) {
10840 send_resp(dut, conn, SIGMA_ERROR,
10841 "ErrorCode,Failed to set gas_address3");
10842 return 0;
10843 }
10844
Ashwini Patildb59b3c2017-04-13 15:19:23 +053010845 if (wpa_command(intf, buf) < 0) {
10846 send_resp(dut, conn, SIGMA_ERROR,
10847 "ErrorCode,Failed to send ANQP query");
10848 return 0;
10849 }
10850
10851 return 1;
10852}
10853
10854
10855static int mbo_cmd_sta_send_frame(struct sigma_dut *dut,
10856 struct sigma_conn *conn,
10857 const char *intf,
10858 struct sigma_cmd *cmd)
10859{
10860 const char *val = get_param(cmd, "FrameName");
10861
10862 if (val && strcasecmp(val, "ANQPQuery") == 0)
10863 return mbo_send_anqp_query(dut, conn, intf, cmd);
10864
10865 return 2;
10866}
10867
10868
Jouni Malinenf7222712019-06-13 01:50:21 +030010869enum sigma_cmd_result cmd_sta_send_frame(struct sigma_dut *dut,
10870 struct sigma_conn *conn,
10871 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010872{
10873 const char *intf = get_param(cmd, "Interface");
10874 const char *val;
10875 enum send_frame_type frame;
10876 enum send_frame_protection protected;
10877 char buf[100];
10878 unsigned char addr[ETH_ALEN];
10879 int res;
10880
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +030010881 if (!intf)
10882 return -1;
10883
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010884 val = get_param(cmd, "program");
10885 if (val == NULL)
10886 val = get_param(cmd, "frame");
10887 if (val && strcasecmp(val, "TDLS") == 0)
10888 return cmd_sta_send_frame_tdls(dut, conn, cmd);
10889 if (val && (strcasecmp(val, "HS2") == 0 ||
Jouni Malinen1f6ae642018-06-07 23:56:13 +030010890 strcasecmp(val, "HS2-R2") == 0 ||
10891 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010892 return cmd_sta_send_frame_hs2(dut, conn, cmd);
10893 if (val && strcasecmp(val, "VHT") == 0)
10894 return cmd_sta_send_frame_vht(dut, conn, cmd);
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070010895 if (val && strcasecmp(val, "HE") == 0)
10896 return cmd_sta_send_frame_he(dut, conn, cmd);
priyadharshini gowthamand66913a2016-07-29 15:11:17 -070010897 if (val && strcasecmp(val, "LOC") == 0)
10898 return loc_cmd_sta_send_frame(dut, conn, cmd);
Lior David0fe101e2017-03-09 16:09:50 +020010899 if (val && strcasecmp(val, "60GHz") == 0)
10900 return cmd_sta_send_frame_60g(dut, conn, cmd);
Ashwini Patildb59b3c2017-04-13 15:19:23 +053010901 if (val && strcasecmp(val, "MBO") == 0) {
10902 res = mbo_cmd_sta_send_frame(dut, conn, intf, cmd);
10903 if (res != 2)
10904 return res;
10905 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010906
10907 val = get_param(cmd, "TD_DISC");
10908 if (val) {
10909 if (hwaddr_aton(val, addr) < 0)
10910 return -1;
10911 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", val);
10912 if (wpa_command(intf, buf) < 0) {
10913 send_resp(dut, conn, SIGMA_ERROR,
10914 "ErrorCode,Failed to send TDLS discovery");
10915 return 0;
10916 }
10917 return 1;
10918 }
10919
10920 val = get_param(cmd, "TD_Setup");
10921 if (val) {
10922 if (hwaddr_aton(val, addr) < 0)
10923 return -1;
10924 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", val);
10925 if (wpa_command(intf, buf) < 0) {
10926 send_resp(dut, conn, SIGMA_ERROR,
10927 "ErrorCode,Failed to start TDLS setup");
10928 return 0;
10929 }
10930 return 1;
10931 }
10932
10933 val = get_param(cmd, "TD_TearDown");
10934 if (val) {
10935 if (hwaddr_aton(val, addr) < 0)
10936 return -1;
10937 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", val);
10938 if (wpa_command(intf, buf) < 0) {
10939 send_resp(dut, conn, SIGMA_ERROR,
10940 "ErrorCode,Failed to tear down TDLS link");
10941 return 0;
10942 }
10943 return 1;
10944 }
10945
10946 val = get_param(cmd, "TD_ChannelSwitch");
10947 if (val) {
10948 /* TODO */
10949 send_resp(dut, conn, SIGMA_ERROR,
10950 "ErrorCode,TD_ChannelSwitch not yet supported");
10951 return 0;
10952 }
10953
10954 val = get_param(cmd, "TD_NF");
10955 if (val) {
10956 /* TODO */
10957 send_resp(dut, conn, SIGMA_ERROR,
10958 "ErrorCode,TD_NF not yet supported");
10959 return 0;
10960 }
10961
10962 val = get_param(cmd, "PMFFrameType");
10963 if (val == NULL)
10964 val = get_param(cmd, "FrameName");
10965 if (val == NULL)
10966 val = get_param(cmd, "Type");
10967 if (val == NULL)
10968 return -1;
10969 if (strcasecmp(val, "disassoc") == 0)
10970 frame = DISASSOC;
10971 else if (strcasecmp(val, "deauth") == 0)
10972 frame = DEAUTH;
10973 else if (strcasecmp(val, "saquery") == 0)
10974 frame = SAQUERY;
10975 else if (strcasecmp(val, "auth") == 0)
10976 frame = AUTH;
10977 else if (strcasecmp(val, "assocreq") == 0)
10978 frame = ASSOCREQ;
10979 else if (strcasecmp(val, "reassocreq") == 0)
10980 frame = REASSOCREQ;
10981 else if (strcasecmp(val, "neigreq") == 0) {
10982 sigma_dut_print(dut, DUT_MSG_INFO, "Got neighbor request");
10983
10984 val = get_param(cmd, "ssid");
10985 if (val == NULL)
10986 return -1;
10987
10988 res = send_neighbor_request(dut, intf, val);
10989 if (res) {
10990 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
10991 "Failed to send neighbor report request");
10992 return 0;
10993 }
10994
10995 return 1;
Ashwini Patil5acd7382017-04-13 15:55:04 +053010996 } else if (strcasecmp(val, "transmgmtquery") == 0 ||
10997 strcasecmp(val, "BTMQuery") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010998 sigma_dut_print(dut, DUT_MSG_DEBUG,
10999 "Got Transition Management Query");
11000
Ashwini Patil5acd7382017-04-13 15:55:04 +053011001 res = send_trans_mgmt_query(dut, intf, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011002 if (res) {
11003 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
11004 "Failed to send Transition Management Query");
11005 return 0;
11006 }
11007
11008 return 1;
11009 } else {
11010 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
11011 "PMFFrameType");
11012 return 0;
11013 }
11014
11015 val = get_param(cmd, "PMFProtected");
11016 if (val == NULL)
11017 val = get_param(cmd, "Protected");
11018 if (val == NULL)
11019 return -1;
11020 if (strcasecmp(val, "Correct-key") == 0 ||
11021 strcasecmp(val, "CorrectKey") == 0)
11022 protected = CORRECT_KEY;
11023 else if (strcasecmp(val, "IncorrectKey") == 0)
11024 protected = INCORRECT_KEY;
11025 else if (strcasecmp(val, "Unprotected") == 0)
11026 protected = UNPROTECTED;
11027 else {
11028 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
11029 "PMFProtected");
11030 return 0;
11031 }
11032
11033 if (protected != UNPROTECTED &&
11034 (frame == AUTH || frame == ASSOCREQ || frame == REASSOCREQ)) {
11035 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Impossible "
11036 "PMFProtected for auth/assocreq/reassocreq");
11037 return 0;
11038 }
11039
11040 if (if_nametoindex("sigmadut") == 0) {
11041 snprintf(buf, sizeof(buf),
11042 "iw dev %s interface add sigmadut type monitor",
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011043 get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011044 if (system(buf) != 0 ||
11045 if_nametoindex("sigmadut") == 0) {
11046 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
11047 "monitor interface with '%s'", buf);
11048 return -2;
11049 }
11050 }
11051
11052 if (system("ifconfig sigmadut up") != 0) {
11053 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
11054 "monitor interface up");
11055 return -2;
11056 }
11057
11058 return sta_inject_frame(dut, conn, frame, protected, NULL);
11059}
11060
11061
11062static int cmd_sta_set_parameter_hs2(struct sigma_dut *dut,
11063 struct sigma_conn *conn,
11064 struct sigma_cmd *cmd,
11065 const char *ifname)
11066{
11067 char buf[200];
11068 const char *val;
11069
11070 val = get_param(cmd, "ClearARP");
11071 if (val && atoi(val) == 1) {
11072 snprintf(buf, sizeof(buf), "ip neigh flush dev %s", ifname);
11073 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
11074 if (system(buf) != 0) {
11075 send_resp(dut, conn, SIGMA_ERROR,
11076 "errorCode,Failed to clear ARP cache");
11077 return 0;
11078 }
11079 }
11080
11081 return 1;
11082}
11083
11084
11085int cmd_sta_set_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
11086 struct sigma_cmd *cmd)
11087{
11088 const char *intf = get_param(cmd, "Interface");
11089 const char *val;
11090
11091 if (intf == NULL)
11092 return -1;
11093
11094 val = get_param(cmd, "program");
11095 if (val && (strcasecmp(val, "HS2") == 0 ||
Jouni Malinen1f6ae642018-06-07 23:56:13 +030011096 strcasecmp(val, "HS2-R2") == 0 ||
11097 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011098 return cmd_sta_set_parameter_hs2(dut, conn, cmd, intf);
11099
11100 return -1;
11101}
11102
11103
Jouni Malinenf7222712019-06-13 01:50:21 +030011104static enum sigma_cmd_result cmd_sta_set_macaddr(struct sigma_dut *dut,
11105 struct sigma_conn *conn,
11106 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011107{
11108 const char *intf = get_param(cmd, "Interface");
11109 const char *mac = get_param(cmd, "MAC");
11110
11111 if (intf == NULL || mac == NULL)
11112 return -1;
11113
11114 sigma_dut_print(dut, DUT_MSG_INFO, "Change local MAC address for "
11115 "interface %s to %s", intf, mac);
11116
11117 if (dut->set_macaddr) {
11118 char buf[128];
11119 int res;
11120 if (strcasecmp(mac, "default") == 0) {
11121 res = snprintf(buf, sizeof(buf), "%s",
11122 dut->set_macaddr);
11123 dut->tmp_mac_addr = 0;
11124 } else {
11125 res = snprintf(buf, sizeof(buf), "%s %s",
11126 dut->set_macaddr, mac);
11127 dut->tmp_mac_addr = 1;
11128 }
11129 if (res < 0 || res >= (int) sizeof(buf))
11130 return -1;
11131 if (system(buf) != 0) {
11132 send_resp(dut, conn, SIGMA_ERROR,
11133 "errorCode,Failed to set MAC "
11134 "address");
11135 return 0;
11136 }
11137 return 1;
11138 }
11139
11140 if (strcasecmp(mac, "default") == 0)
11141 return 1;
11142
11143 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
11144 "command");
11145 return 0;
11146}
11147
11148
11149static int iwpriv_tdlsoffchnmode(struct sigma_dut *dut,
11150 struct sigma_conn *conn, const char *intf,
11151 int val)
11152{
11153 char buf[200];
11154 int res;
11155
11156 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchnmode %d",
11157 intf, val);
11158 if (res < 0 || res >= (int) sizeof(buf))
11159 return -1;
11160 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
11161 if (system(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
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011171static int off_chan_val(enum sec_ch_offset off)
11172{
11173 switch (off) {
11174 case SEC_CH_NO:
11175 return 0;
11176 case SEC_CH_40ABOVE:
11177 return 40;
11178 case SEC_CH_40BELOW:
11179 return -40;
11180 }
11181
11182 return 0;
11183}
11184
11185
11186static int iwpriv_set_offchan(struct sigma_dut *dut, struct sigma_conn *conn,
11187 const char *intf, int off_ch_num,
11188 enum sec_ch_offset sec)
11189{
11190 char buf[200];
11191 int res;
11192
11193 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchan %d",
11194 intf, off_ch_num);
11195 if (res < 0 || res >= (int) sizeof(buf))
11196 return -1;
11197 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
11198 if (system(buf) != 0) {
11199 send_resp(dut, conn, SIGMA_ERROR,
11200 "errorCode,Failed to set offchan");
11201 return 0;
11202 }
11203
11204 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsecchnoffst %d",
11205 intf, off_chan_val(sec));
11206 if (res < 0 || res >= (int) sizeof(buf))
11207 return -1;
11208 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
11209 if (system(buf) != 0) {
11210 send_resp(dut, conn, SIGMA_ERROR,
11211 "errorCode,Failed to set sec chan offset");
11212 return 0;
11213 }
11214
11215 return 1;
11216}
11217
11218
11219static int tdls_set_offchannel_offset(struct sigma_dut *dut,
11220 struct sigma_conn *conn,
11221 const char *intf, int off_ch_num,
11222 enum sec_ch_offset sec)
11223{
11224 char buf[200];
11225 int res;
11226
11227 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNEL %d",
11228 off_ch_num);
11229 if (res < 0 || res >= (int) sizeof(buf))
11230 return -1;
11231 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
11232
11233 if (wpa_command(intf, buf) < 0) {
11234 send_resp(dut, conn, SIGMA_ERROR,
11235 "ErrorCode,Failed to set offchan");
11236 return 0;
11237 }
11238 res = snprintf(buf, sizeof(buf), "DRIVER TDLSSECONDARYCHANNELOFFSET %d",
11239 off_chan_val(sec));
11240 if (res < 0 || res >= (int) sizeof(buf))
11241 return -1;
11242
11243 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
11244
11245 if (wpa_command(intf, buf) < 0) {
11246 send_resp(dut, conn, SIGMA_ERROR,
11247 "ErrorCode,Failed to set sec chan offset");
11248 return 0;
11249 }
11250
11251 return 1;
11252}
11253
11254
11255static int tdls_set_offchannel_mode(struct sigma_dut *dut,
11256 struct sigma_conn *conn,
11257 const char *intf, int val)
11258{
11259 char buf[200];
11260 int res;
11261
11262 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNELMODE %d",
11263 val);
11264 if (res < 0 || res >= (int) sizeof(buf))
11265 return -1;
11266 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
11267
11268 if (wpa_command(intf, buf) < 0) {
11269 send_resp(dut, conn, SIGMA_ERROR,
11270 "ErrorCode,Failed to configure offchannel mode");
11271 return 0;
11272 }
11273
11274 return 1;
11275}
11276
11277
11278static int cmd_sta_set_rfeature_tdls(const char *intf, struct sigma_dut *dut,
11279 struct sigma_conn *conn,
11280 struct sigma_cmd *cmd)
11281{
11282 const char *val;
11283 enum {
11284 CHSM_NOT_SET,
11285 CHSM_ENABLE,
11286 CHSM_DISABLE,
11287 CHSM_REJREQ,
11288 CHSM_UNSOLRESP
11289 } chsm = CHSM_NOT_SET;
11290 int off_ch_num = -1;
11291 enum sec_ch_offset sec_ch = SEC_CH_NO;
11292 int res;
11293
11294 val = get_param(cmd, "Uapsd");
11295 if (val) {
11296 char buf[100];
11297 if (strcasecmp(val, "Enable") == 0)
11298 snprintf(buf, sizeof(buf), "SET ps 99");
11299 else if (strcasecmp(val, "Disable") == 0)
11300 snprintf(buf, sizeof(buf), "SET ps 98");
11301 else {
11302 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
11303 "Unsupported uapsd parameter value");
11304 return 0;
11305 }
11306 if (wpa_command(intf, buf)) {
11307 send_resp(dut, conn, SIGMA_ERROR,
11308 "ErrorCode,Failed to change U-APSD "
11309 "powersave mode");
11310 return 0;
11311 }
11312 }
11313
11314 val = get_param(cmd, "TPKTIMER");
11315 if (val && strcasecmp(val, "DISABLE") == 0) {
11316 if (wpa_command(intf, "SET tdls_testing 0x100")) {
11317 send_resp(dut, conn, SIGMA_ERROR,
11318 "ErrorCode,Failed to enable no TPK "
11319 "expiration test mode");
11320 return 0;
11321 }
11322 dut->no_tpk_expiration = 1;
11323 }
11324
11325 val = get_param(cmd, "ChSwitchMode");
11326 if (val) {
11327 if (strcasecmp(val, "Enable") == 0 ||
11328 strcasecmp(val, "Initiate") == 0)
11329 chsm = CHSM_ENABLE;
11330 else if (strcasecmp(val, "Disable") == 0 ||
11331 strcasecmp(val, "passive") == 0)
11332 chsm = CHSM_DISABLE;
11333 else if (strcasecmp(val, "RejReq") == 0)
11334 chsm = CHSM_REJREQ;
11335 else if (strcasecmp(val, "UnSolResp") == 0)
11336 chsm = CHSM_UNSOLRESP;
11337 else {
11338 send_resp(dut, conn, SIGMA_ERROR,
11339 "ErrorCode,Unknown ChSwitchMode value");
11340 return 0;
11341 }
11342 }
11343
11344 val = get_param(cmd, "OffChNum");
11345 if (val) {
11346 off_ch_num = atoi(val);
11347 if (off_ch_num == 0) {
11348 send_resp(dut, conn, SIGMA_ERROR,
11349 "ErrorCode,Invalid OffChNum");
11350 return 0;
11351 }
11352 }
11353
11354 val = get_param(cmd, "SecChOffset");
11355 if (val) {
11356 if (strcmp(val, "20") == 0)
11357 sec_ch = SEC_CH_NO;
11358 else if (strcasecmp(val, "40above") == 0)
11359 sec_ch = SEC_CH_40ABOVE;
11360 else if (strcasecmp(val, "40below") == 0)
11361 sec_ch = SEC_CH_40BELOW;
11362 else {
11363 send_resp(dut, conn, SIGMA_ERROR,
11364 "ErrorCode,Unknown SecChOffset value");
11365 return 0;
11366 }
11367 }
11368
11369 if (chsm == CHSM_NOT_SET) {
11370 /* no offchannel changes requested */
11371 return 1;
11372 }
11373
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011374 if (strcmp(intf, get_main_ifname(dut)) != 0 &&
11375 strcmp(intf, get_station_ifname(dut)) != 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011376 send_resp(dut, conn, SIGMA_ERROR,
11377 "ErrorCode,Unknown interface");
11378 return 0;
11379 }
11380
11381 switch (chsm) {
11382 case CHSM_NOT_SET:
Jouni Malinen280f5ba2016-08-29 21:33:10 +030011383 res = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011384 break;
11385 case CHSM_ENABLE:
11386 if (off_ch_num < 0) {
11387 send_resp(dut, conn, SIGMA_ERROR,
11388 "ErrorCode,Missing OffChNum argument");
11389 return 0;
11390 }
11391 if (wifi_chip_type == DRIVER_WCN) {
11392 res = tdls_set_offchannel_offset(dut, conn, intf,
11393 off_ch_num, sec_ch);
11394 } else {
11395 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
11396 sec_ch);
11397 }
11398 if (res != 1)
11399 return res;
11400 if (wifi_chip_type == DRIVER_WCN)
11401 res = tdls_set_offchannel_mode(dut, conn, intf, 1);
11402 else
11403 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 1);
11404 break;
11405 case CHSM_DISABLE:
11406 if (wifi_chip_type == DRIVER_WCN)
11407 res = tdls_set_offchannel_mode(dut, conn, intf, 2);
11408 else
11409 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 2);
11410 break;
11411 case CHSM_REJREQ:
11412 if (wifi_chip_type == DRIVER_WCN)
11413 res = tdls_set_offchannel_mode(dut, conn, intf, 3);
11414 else
11415 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 3);
11416 break;
11417 case CHSM_UNSOLRESP:
11418 if (off_ch_num < 0) {
11419 send_resp(dut, conn, SIGMA_ERROR,
11420 "ErrorCode,Missing OffChNum argument");
11421 return 0;
11422 }
11423 if (wifi_chip_type == DRIVER_WCN) {
11424 res = tdls_set_offchannel_offset(dut, conn, intf,
11425 off_ch_num, sec_ch);
11426 } else {
11427 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
11428 sec_ch);
11429 }
11430 if (res != 1)
11431 return res;
11432 if (wifi_chip_type == DRIVER_WCN)
11433 res = tdls_set_offchannel_mode(dut, conn, intf, 4);
11434 else
11435 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 4);
11436 break;
11437 }
11438
11439 return res;
11440}
11441
11442
11443static int ath_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
11444 struct sigma_conn *conn,
11445 struct sigma_cmd *cmd)
11446{
11447 const char *val;
Srikanth Marepalli5415acf2018-08-27 12:53:11 +053011448 char *token = NULL, *result;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011449
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -070011450 novap_reset(dut, intf, 1);
priyadharshini gowthamane5e25172015-12-08 14:53:48 -080011451
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011452 val = get_param(cmd, "nss_mcs_opt");
11453 if (val) {
11454 /* String (nss_operating_mode; mcs_operating_mode) */
11455 int nss, mcs;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053011456 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011457
11458 token = strdup(val);
11459 if (!token)
11460 return 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053011461 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +053011462 if (!result) {
11463 sigma_dut_print(dut, DUT_MSG_ERROR,
11464 "VHT NSS not specified");
11465 goto failed;
11466 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011467 if (strcasecmp(result, "def") != 0) {
11468 nss = atoi(result);
11469 if (nss == 4)
11470 ath_disable_txbf(dut, intf);
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011471 if (run_iwpriv(dut, intf, "nss %d", nss) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011472 goto failed;
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011473
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011474 }
11475
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053011476 result = strtok_r(NULL, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +053011477 if (!result) {
11478 sigma_dut_print(dut, DUT_MSG_ERROR,
11479 "VHT MCS not specified");
11480 goto failed;
11481 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011482 if (strcasecmp(result, "def") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011483 if (run_iwpriv(dut, intf, "set11NRates 0") < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011484 goto failed;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011485 } else {
11486 mcs = atoi(result);
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011487 if (run_iwpriv(dut, intf, "vhtmcs %d", mcs) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011488 goto failed;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011489 }
11490 /* Channel width gets messed up, fix this */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011491 run_iwpriv(dut, intf, "chwidth %d", dut->chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011492 }
11493
Srikanth Marepalli5415acf2018-08-27 12:53:11 +053011494 free(token);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011495 return 1;
11496failed:
11497 free(token);
11498 return 0;
11499}
11500
11501
11502static int cmd_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
11503 struct sigma_conn *conn,
11504 struct sigma_cmd *cmd)
11505{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011506 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011507 case DRIVER_ATHEROS:
11508 return ath_sta_set_rfeature_vht(intf, dut, conn, cmd);
11509 default:
11510 send_resp(dut, conn, SIGMA_ERROR,
11511 "errorCode,Unsupported sta_set_rfeature(VHT) with the current driver");
11512 return 0;
11513 }
11514}
11515
11516
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011517static int wcn_sta_set_rfeature_he(const char *intf, struct sigma_dut *dut,
11518 struct sigma_conn *conn,
11519 struct sigma_cmd *cmd)
11520{
11521 const char *val;
11522 char *token = NULL, *result;
11523 char buf[60];
11524
11525 val = get_param(cmd, "nss_mcs_opt");
11526 if (val) {
11527 /* String (nss_operating_mode; mcs_operating_mode) */
11528 int nss, mcs, ratecode;
11529 char *saveptr;
11530
11531 token = strdup(val);
11532 if (!token)
11533 return -2;
11534
11535 result = strtok_r(token, ";", &saveptr);
11536 if (!result) {
11537 sigma_dut_print(dut, DUT_MSG_ERROR,
11538 "HE NSS not specified");
11539 goto failed;
11540 }
11541 nss = 1;
11542 if (strcasecmp(result, "def") != 0)
11543 nss = atoi(result);
11544
11545 result = strtok_r(NULL, ";", &saveptr);
11546 if (!result) {
11547 sigma_dut_print(dut, DUT_MSG_ERROR,
11548 "HE MCS not specified");
11549 goto failed;
11550 }
11551 mcs = 7;
11552 if (strcasecmp(result, "def") != 0)
11553 mcs = atoi(result);
11554
Arif Hussain557bf412018-05-25 17:29:36 -070011555 ratecode = 0x20; /* for nss:1 MCS 0 */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011556 if (nss == 2) {
Arif Hussain557bf412018-05-25 17:29:36 -070011557 ratecode = 0x40; /* for nss:2 MCS 0 */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011558 } else if (nss > 2) {
11559 sigma_dut_print(dut, DUT_MSG_ERROR,
11560 "HE NSS %d not supported", nss);
11561 goto failed;
11562 }
11563
Arif Hussain557bf412018-05-25 17:29:36 -070011564 snprintf(buf, sizeof(buf), "iwpriv %s nss %d", intf, nss);
11565 if (system(buf) != 0) {
11566 sigma_dut_print(dut, DUT_MSG_ERROR,
11567 "nss_mcs_opt: iwpriv %s nss %d failed",
11568 intf, nss);
11569 goto failed;
11570 }
Arif Hussainac6c5112018-05-25 17:34:00 -070011571 dut->sta_nss = nss;
Arif Hussain557bf412018-05-25 17:29:36 -070011572
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011573 /* Add the MCS to the ratecode */
11574 if (mcs >= 0 && mcs <= 11) {
11575 ratecode += mcs;
Arif Hussain557bf412018-05-25 17:29:36 -070011576#ifdef NL80211_SUPPORT
11577 if (dut->device_type == STA_testbed) {
11578 enum he_mcs_config mcs_config;
11579 int ret;
11580
11581 if (mcs <= 7)
11582 mcs_config = HE_80_MCS0_7;
11583 else if (mcs <= 9)
11584 mcs_config = HE_80_MCS0_9;
11585 else
11586 mcs_config = HE_80_MCS0_11;
11587 ret = sta_set_he_mcs(dut, intf, mcs_config);
11588 if (ret) {
11589 sigma_dut_print(dut, DUT_MSG_ERROR,
11590 "nss_mcs_opt: mcs setting failed, mcs:%d, mcs_config %d, ret:%d",
11591 mcs, mcs_config, ret);
11592 goto failed;
11593 }
11594 }
11595#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011596 } else {
11597 sigma_dut_print(dut, DUT_MSG_ERROR,
11598 "HE MCS %d not supported", mcs);
11599 goto failed;
11600 }
11601 snprintf(buf, sizeof(buf), "iwpriv %s set_11ax_rate 0x%03x",
11602 intf, ratecode);
11603 if (system(buf) != 0) {
11604 sigma_dut_print(dut, DUT_MSG_ERROR,
11605 "iwpriv setting of 11ax rates failed");
11606 goto failed;
11607 }
11608 free(token);
11609 }
11610
11611 val = get_param(cmd, "GI");
11612 if (val) {
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011613 int fix_rate_sgi;
11614
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011615 if (strcmp(val, "0.8") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070011616 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 9", intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011617 fix_rate_sgi = 1;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011618 } else if (strcmp(val, "1.6") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070011619 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 10",
11620 intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011621 fix_rate_sgi = 2;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011622 } else if (strcmp(val, "3.2") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070011623 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 11",
11624 intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011625 fix_rate_sgi = 3;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011626 } else {
11627 send_resp(dut, conn, SIGMA_ERROR,
11628 "errorCode,GI value not supported");
11629 return 0;
11630 }
11631 if (system(buf) != 0) {
11632 send_resp(dut, conn, SIGMA_ERROR,
11633 "errorCode,Failed to set shortgi");
11634 return 0;
11635 }
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011636 snprintf(buf, sizeof(buf), "iwpriv %s shortgi %d",
11637 intf, fix_rate_sgi);
11638 if (system(buf) != 0) {
11639 send_resp(dut, conn, SIGMA_ERROR,
11640 "errorCode,Failed to set fix rate shortgi");
11641 return STATUS_SENT;
11642 }
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011643 }
11644
Subhani Shaik8e7a3052018-04-24 14:03:00 -070011645 val = get_param(cmd, "LTF");
11646 if (val) {
11647#ifdef NL80211_SUPPORT
11648 if (strcmp(val, "3.2") == 0) {
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -080011649 wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_1X);
Subhani Shaik8e7a3052018-04-24 14:03:00 -070011650 } if (strcmp(val, "6.4") == 0) {
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -080011651 wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_2X);
Subhani Shaik8e7a3052018-04-24 14:03:00 -070011652 } else if (strcmp(val, "12.8") == 0) {
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -080011653 wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_4X);
Subhani Shaik8e7a3052018-04-24 14:03:00 -070011654 } else {
11655 send_resp(dut, conn, SIGMA_ERROR,
11656 "errorCode, LTF value not supported");
11657 return 0;
11658 }
11659#else /* NL80211_SUPPORT */
11660 sigma_dut_print(dut, DUT_MSG_ERROR,
11661 "LTF cannot be set without NL80211_SUPPORT defined");
11662 return -2;
11663#endif /* NL80211_SUPPORT */
11664 }
11665
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -070011666 val = get_param(cmd, "TxSUPPDU");
11667 if (val) {
11668 int set_val = 1;
11669
11670 if (strcasecmp(val, "Enable") == 0)
11671 set_val = 1;
11672 else if (strcasecmp(val, "Disable") == 0)
11673 set_val = 0;
11674
11675 if (sta_set_tx_su_ppdu_cfg(dut, intf, set_val)) {
11676 send_resp(dut, conn, SIGMA_ERROR,
11677 "ErrorCode,Failed to set Tx SU PPDU config");
11678 return 0;
11679 }
11680 }
11681
Arif Hussain480d5f42019-03-12 14:40:42 -070011682 val = get_param(cmd, "TWT_Setup");
11683 if (val) {
11684 if (strcasecmp(val, "Request") == 0) {
11685 if (sta_twt_request(dut, conn, cmd)) {
11686 send_resp(dut, conn, SIGMA_ERROR,
11687 "ErrorCode,sta_twt_request failed");
11688 return STATUS_SENT;
11689 }
11690 } else if (strcasecmp(val, "Teardown") == 0) {
11691 if (sta_twt_teardown(dut, conn, cmd)) {
11692 send_resp(dut, conn, SIGMA_ERROR,
11693 "ErrorCode,sta_twt_teardown failed");
11694 return STATUS_SENT;
11695 }
11696 }
11697 }
11698
Kiran Kumar Lokere50eb2cd2018-12-18 18:31:28 -080011699 val = get_param(cmd, "transmitOMI");
11700 if (val && sta_transmit_omi(dut, conn, cmd)) {
11701 send_resp(dut, conn, SIGMA_ERROR,
11702 "ErrorCode,sta_transmit_omi failed");
11703 return STATUS_SENT;
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -070011704 }
11705
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080011706 val = get_param(cmd, "Powersave");
11707 if (val) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053011708 int ps;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080011709
11710 if (strcasecmp(val, "off") == 0) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053011711 ps = 2;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080011712 } else if (strcasecmp(val, "on") == 0) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053011713 ps = 1;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080011714 } else {
11715 sigma_dut_print(dut, DUT_MSG_ERROR,
11716 "Unsupported Powersave value '%s'",
11717 val);
11718 return -1;
11719 }
Vinita S. Malooa8b62722020-04-23 01:45:41 +053011720 if (set_power_save_wcn(dut, intf, ps) < 0)
11721 return 0;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080011722 }
11723
Kiran Kumar Lokere2c4b7ce2019-01-30 12:02:28 -080011724 val = get_param(cmd, "MU_EDCA");
11725 if (val) {
11726 if (strcasecmp(val, "Override") == 0) {
11727 if (sta_set_mu_edca_override(dut, intf, 1)) {
11728 send_resp(dut, conn, SIGMA_ERROR,
11729 "errorCode,MU EDCA override set failed");
11730 return STATUS_SENT;
11731 }
11732 } else if (strcasecmp(val, "Disable") == 0) {
11733 if (sta_set_mu_edca_override(dut, intf, 0)) {
11734 send_resp(dut, conn, SIGMA_ERROR,
11735 "errorCode,MU EDCA override disable failed");
11736 return STATUS_SENT;
11737 }
11738 }
11739 }
11740
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011741 return 1;
11742
11743failed:
11744 free(token);
11745 return -2;
11746}
11747
11748
11749static int cmd_sta_set_rfeature_he(const char *intf, struct sigma_dut *dut,
11750 struct sigma_conn *conn,
11751 struct sigma_cmd *cmd)
11752{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011753 switch (get_driver_type(dut)) {
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011754 case DRIVER_WCN:
11755 return wcn_sta_set_rfeature_he(intf, dut, conn, cmd);
11756 default:
11757 send_resp(dut, conn, SIGMA_ERROR,
11758 "errorCode,Unsupported sta_set_rfeature(HE) with the current driver");
11759 return 0;
11760 }
11761}
11762
11763
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080011764static int cmd_sta_set_power_save_he(const char *intf, struct sigma_dut *dut,
11765 struct sigma_conn *conn,
11766 struct sigma_cmd *cmd)
11767{
11768 const char *val;
11769
11770 val = get_param(cmd, "powersave");
11771 if (val) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053011772 int ps;
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080011773
11774 if (strcasecmp(val, "off") == 0) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053011775 ps = 2;
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080011776 } else if (strcasecmp(val, "on") == 0) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053011777 ps = 1;
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080011778 } else {
11779 sigma_dut_print(dut, DUT_MSG_ERROR,
11780 "Unsupported power save config");
11781 return -1;
11782 }
Vinita S. Malooa8b62722020-04-23 01:45:41 +053011783 if (set_power_save_wcn(dut, intf, ps) < 0)
11784 return 0;
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080011785 return 1;
11786 }
11787
11788 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported command");
11789
11790 return 0;
11791}
11792
11793
Ashwini Patil5acd7382017-04-13 15:55:04 +053011794static int btm_query_candidate_list(struct sigma_dut *dut,
11795 struct sigma_conn *conn,
11796 struct sigma_cmd *cmd)
11797{
11798 const char *bssid, *info, *op_class, *ch, *phy_type, *pref;
11799 int len, ret;
11800 char buf[10];
11801
11802 /*
11803 * Neighbor Report elements format:
11804 * neighbor=<BSSID>,<BSSID Information>,<Operating Class>,
11805 * <Channel Number>,<PHY Type>[,<hexdump of Optional Subelements>]
11806 * eg: neighbor=aa:bb:cc:dd:ee:ff,17,81,6,1,030101
11807 */
11808
11809 bssid = get_param(cmd, "Nebor_BSSID");
11810 if (!bssid) {
11811 send_resp(dut, conn, SIGMA_INVALID,
11812 "errorCode,Nebor_BSSID is missing");
11813 return 0;
11814 }
11815
11816 info = get_param(cmd, "Nebor_Bssid_Info");
11817 if (!info) {
11818 sigma_dut_print(dut, DUT_MSG_INFO,
11819 "Using default value for Nebor_Bssid_Info: %s",
11820 DEFAULT_NEIGHBOR_BSSID_INFO);
11821 info = DEFAULT_NEIGHBOR_BSSID_INFO;
11822 }
11823
11824 op_class = get_param(cmd, "Nebor_Op_Class");
11825 if (!op_class) {
11826 send_resp(dut, conn, SIGMA_INVALID,
11827 "errorCode,Nebor_Op_Class is missing");
11828 return 0;
11829 }
11830
11831 ch = get_param(cmd, "Nebor_Op_Ch");
11832 if (!ch) {
11833 send_resp(dut, conn, SIGMA_INVALID,
11834 "errorCode,Nebor_Op_Ch is missing");
11835 return 0;
11836 }
11837
11838 phy_type = get_param(cmd, "Nebor_Phy_Type");
11839 if (!phy_type) {
11840 sigma_dut_print(dut, DUT_MSG_INFO,
11841 "Using default value for Nebor_Phy_Type: %s",
11842 DEFAULT_NEIGHBOR_PHY_TYPE);
11843 phy_type = DEFAULT_NEIGHBOR_PHY_TYPE;
11844 }
11845
11846 /* Parse optional subelements */
11847 buf[0] = '\0';
11848 pref = get_param(cmd, "Nebor_Pref");
11849 if (pref) {
11850 /* hexdump for preferrence subelement */
11851 ret = snprintf(buf, sizeof(buf), ",0301%02x", atoi(pref));
11852 if (ret < 0 || ret >= (int) sizeof(buf)) {
11853 sigma_dut_print(dut, DUT_MSG_ERROR,
11854 "snprintf failed for optional subelement ret: %d",
11855 ret);
11856 send_resp(dut, conn, SIGMA_ERROR,
11857 "errorCode,snprintf failed for subelement");
11858 return 0;
11859 }
11860 }
11861
11862 if (!dut->btm_query_cand_list) {
11863 dut->btm_query_cand_list = calloc(1, NEIGHBOR_REPORT_SIZE);
11864 if (!dut->btm_query_cand_list) {
11865 send_resp(dut, conn, SIGMA_ERROR,
11866 "errorCode,Failed to allocate memory for btm_query_cand_list");
11867 return 0;
11868 }
11869 }
11870
11871 len = strlen(dut->btm_query_cand_list);
11872 ret = snprintf(dut->btm_query_cand_list + len,
11873 NEIGHBOR_REPORT_SIZE - len, " neighbor=%s,%s,%s,%s,%s%s",
11874 bssid, info, op_class, ch, phy_type, buf);
11875 if (ret < 0 || ret >= NEIGHBOR_REPORT_SIZE - len) {
11876 sigma_dut_print(dut, DUT_MSG_ERROR,
11877 "snprintf failed for neighbor report list ret: %d",
11878 ret);
11879 send_resp(dut, conn, SIGMA_ERROR,
11880 "errorCode,snprintf failed for neighbor report");
11881 free(dut->btm_query_cand_list);
11882 dut->btm_query_cand_list = NULL;
11883 return 0;
11884 }
11885
11886 return 1;
11887}
11888
11889
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020011890int sta_extract_60g_ese(struct sigma_dut *dut, struct sigma_cmd *cmd,
11891 struct sigma_ese_alloc *allocs, int *allocs_size)
11892{
11893 int max_count = *allocs_size;
11894 int count = 0, i;
11895 const char *val;
11896
11897 do {
11898 val = get_param_indexed(cmd, "AllocID", count);
11899 if (val)
11900 count++;
11901 } while (val);
11902
11903 if (count == 0 || count > max_count) {
11904 sigma_dut_print(dut, DUT_MSG_ERROR,
11905 "Invalid number of allocations(%d)", count);
11906 return -1;
11907 }
11908
11909 for (i = 0; i < count; i++) {
11910 val = get_param_indexed(cmd, "PercentBI", i);
11911 if (!val) {
11912 sigma_dut_print(dut, DUT_MSG_ERROR,
11913 "Missing PercentBI parameter at index %d",
11914 i);
11915 return -1;
11916 }
11917 allocs[i].percent_bi = atoi(val);
11918
11919 val = get_param_indexed(cmd, "SrcAID", i);
11920 if (val)
11921 allocs[i].src_aid = strtol(val, NULL, 0);
11922 else
11923 allocs[i].src_aid = ESE_BCAST_AID;
11924
11925 val = get_param_indexed(cmd, "DestAID", i);
11926 if (val)
11927 allocs[i].dst_aid = strtol(val, NULL, 0);
11928 else
11929 allocs[i].dst_aid = ESE_BCAST_AID;
11930
11931 allocs[i].type = ESE_CBAP;
11932 sigma_dut_print(dut, DUT_MSG_INFO,
11933 "Alloc %d PercentBI %d SrcAID %d DstAID %d",
11934 i, allocs[i].percent_bi, allocs[i].src_aid,
11935 allocs[i].dst_aid);
11936 }
11937
11938 *allocs_size = count;
11939 return 0;
11940}
11941
11942
11943static int sta_set_60g_ese(struct sigma_dut *dut, int count,
11944 struct sigma_ese_alloc *allocs)
11945{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011946 switch (get_driver_type(dut)) {
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020011947#ifdef __linux__
11948 case DRIVER_WIL6210:
11949 if (wil6210_set_ese(dut, count, allocs))
11950 return -1;
11951 return 1;
11952#endif /* __linux__ */
11953 default:
11954 sigma_dut_print(dut, DUT_MSG_ERROR,
11955 "Unsupported sta_set_60g_ese with the current driver");
11956 return -1;
11957 }
11958}
11959
11960
11961static int cmd_sta_set_rfeature_60g(const char *intf, struct sigma_dut *dut,
11962 struct sigma_conn *conn,
11963 struct sigma_cmd *cmd)
11964{
11965 const char *val;
11966
11967 val = get_param(cmd, "ExtSchIE");
11968 if (val && !strcasecmp(val, "Enable")) {
11969 struct sigma_ese_alloc allocs[MAX_ESE_ALLOCS];
11970 int count = MAX_ESE_ALLOCS;
11971
11972 if (sta_extract_60g_ese(dut, cmd, allocs, &count))
11973 return -1;
11974 return sta_set_60g_ese(dut, count, allocs);
11975 }
11976
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +020011977 val = get_param(cmd, "MCS_FixedRate");
11978 if (val) {
11979 int sta_mcs = atoi(val);
11980
11981 sigma_dut_print(dut, DUT_MSG_INFO, "Force STA MCS to %d",
11982 sta_mcs);
11983 wil6210_set_force_mcs(dut, 1, sta_mcs);
11984
Jouni Malinen0e29cf22019-02-19 01:13:21 +020011985 return SUCCESS_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +020011986 }
11987
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020011988 send_resp(dut, conn, SIGMA_ERROR,
11989 "errorCode,Invalid sta_set_rfeature(60G)");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020011990 return STATUS_SENT;
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020011991}
11992
11993
Jouni Malinen6250cb02020-04-15 13:54:45 +030011994static enum sigma_cmd_result
11995cmd_sta_set_rfeature_wpa3(const char *intf, struct sigma_dut *dut,
11996 struct sigma_conn *conn,
11997 struct sigma_cmd *cmd)
11998{
11999 const char *val;
12000
Veerendranath Jakkam30bf9072020-04-16 14:37:57 +053012001 val = get_param(cmd, "ReassocReq_RSNXE_Used");
Jouni Malinen6250cb02020-04-15 13:54:45 +030012002 if (val && atoi(val) == 1) {
12003 if (wpa_command(intf, "SET ft_rsnxe_used 1") < 0) {
12004 send_resp(dut, conn, SIGMA_ERROR,
12005 "errorCode,Failed to set ft_rsnxe_used");
12006 return STATUS_SENT_ERROR;
12007 }
12008 return SUCCESS_SEND_STATUS;
12009 }
12010 send_resp(dut, conn, SIGMA_ERROR,
12011 "errorCode,Unsupported WPA3 rfeature");
12012 return STATUS_SENT_ERROR;
12013}
12014
12015
Jouni Malinenf7222712019-06-13 01:50:21 +030012016static enum sigma_cmd_result cmd_sta_set_rfeature(struct sigma_dut *dut,
12017 struct sigma_conn *conn,
12018 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012019{
12020 const char *intf = get_param(cmd, "Interface");
12021 const char *prog = get_param(cmd, "Prog");
Ashwini Patil68d02cd2017-01-10 15:39:16 +053012022 const char *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012023
12024 if (intf == NULL || prog == NULL)
12025 return -1;
12026
Ashwini Patil5acd7382017-04-13 15:55:04 +053012027 /* BSS Transition candidate list for BTM query */
12028 val = get_param(cmd, "Nebor_BSSID");
12029 if (val && btm_query_candidate_list(dut, conn, cmd) == 0)
12030 return 0;
12031
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012032 if (strcasecmp(prog, "TDLS") == 0)
12033 return cmd_sta_set_rfeature_tdls(intf, dut, conn, cmd);
12034
12035 if (strcasecmp(prog, "VHT") == 0)
12036 return cmd_sta_set_rfeature_vht(intf, dut, conn, cmd);
12037
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080012038 if (strcasecmp(prog, "HE") == 0)
12039 return cmd_sta_set_rfeature_he(intf, dut, conn, cmd);
12040
Ashwini Patil68d02cd2017-01-10 15:39:16 +053012041 if (strcasecmp(prog, "MBO") == 0) {
12042 val = get_param(cmd, "Cellular_Data_Cap");
12043 if (val &&
12044 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
12045 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +053012046
12047 val = get_param(cmd, "Ch_Pref");
12048 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
12049 return 0;
12050
Ashwini Patil68d02cd2017-01-10 15:39:16 +053012051 return 1;
12052 }
12053
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020012054 if (strcasecmp(prog, "60GHz") == 0)
12055 return cmd_sta_set_rfeature_60g(intf, dut, conn, cmd);
12056
Jouni Malinen6250cb02020-04-15 13:54:45 +030012057 if (strcasecmp(prog, "WPA3") == 0)
12058 return cmd_sta_set_rfeature_wpa3(intf, dut, conn, cmd);
12059
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012060 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported Prog");
12061 return 0;
12062}
12063
12064
Jouni Malinenf7222712019-06-13 01:50:21 +030012065static enum sigma_cmd_result cmd_sta_set_radio(struct sigma_dut *dut,
12066 struct sigma_conn *conn,
12067 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012068{
12069 const char *intf = get_param(cmd, "Interface");
12070 const char *mode = get_param(cmd, "Mode");
12071 int res;
12072
12073 if (intf == NULL || mode == NULL)
12074 return -1;
12075
12076 if (strcasecmp(mode, "On") == 0)
12077 res = wpa_command(intf, "SET radio_disabled 0");
12078 else if (strcasecmp(mode, "Off") == 0)
12079 res = wpa_command(intf, "SET radio_disabled 1");
12080 else
12081 return -1;
12082
12083 if (res) {
12084 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
12085 "radio mode");
12086 return 0;
12087 }
12088
12089 return 1;
12090}
12091
12092
Jouni Malinenf7222712019-06-13 01:50:21 +030012093static enum sigma_cmd_result cmd_sta_set_pwrsave(struct sigma_dut *dut,
12094 struct sigma_conn *conn,
12095 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012096{
12097 const char *intf = get_param(cmd, "Interface");
12098 const char *mode = get_param(cmd, "Mode");
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020012099 const char *prog = get_param(cmd, "program");
12100 const char *powersave = get_param(cmd, "powersave");
12101 int res = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012102
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020012103 if (intf == NULL)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012104 return -1;
12105
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020012106 if (prog && strcasecmp(prog, "60GHz") == 0) {
12107 /*
12108 * The CAPI mode parameter does not exist in 60G
12109 * unscheduled PS.
12110 */
Hu Wang5dc3ff12019-06-14 15:14:26 +080012111 if (powersave && strcasecmp(powersave, "unscheduled") == 0)
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020012112 res = set_ps(intf, dut, 1);
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012113 } else if (prog && get_driver_type(dut) == DRIVER_WCN &&
Alexei Avshalom Lazar2f6fdb42019-02-04 14:16:08 +020012114 strcasecmp(prog, "HE") == 0) {
12115 return cmd_sta_set_power_save_he(intf, dut, conn, cmd);
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020012116 } else {
12117 if (mode == NULL)
12118 return -1;
12119
12120 if (strcasecmp(mode, "On") == 0)
12121 res = set_ps(intf, dut, 1);
12122 else if (strcasecmp(mode, "Off") == 0)
12123 res = set_ps(intf, dut, 0);
12124 else
12125 return -1;
12126 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012127
12128 if (res) {
12129 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
12130 "power save mode");
12131 return 0;
12132 }
12133
12134 return 1;
12135}
12136
12137
Jouni Malinenf7222712019-06-13 01:50:21 +030012138static enum sigma_cmd_result cmd_sta_bssid_pool(struct sigma_dut *dut,
12139 struct sigma_conn *conn,
12140 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012141{
12142 const char *intf = get_param(cmd, "Interface");
12143 const char *val, *bssid;
12144 int res;
12145 char *buf;
12146 size_t buf_len;
12147
12148 val = get_param(cmd, "BSSID_FILTER");
12149 if (val == NULL)
12150 return -1;
12151
12152 bssid = get_param(cmd, "BSSID_List");
12153 if (atoi(val) == 0 || bssid == NULL) {
12154 /* Disable BSSID filter */
12155 if (wpa_command(intf, "SET bssid_filter ")) {
12156 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed "
12157 "to disable BSSID filter");
12158 return 0;
12159 }
12160
12161 return 1;
12162 }
12163
12164 buf_len = 100 + strlen(bssid);
12165 buf = malloc(buf_len);
12166 if (buf == NULL)
12167 return -1;
12168
12169 snprintf(buf, buf_len, "SET bssid_filter %s", bssid);
12170 res = wpa_command(intf, buf);
12171 free(buf);
12172 if (res) {
12173 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to enable "
12174 "BSSID filter");
12175 return 0;
12176 }
12177
12178 return 1;
12179}
12180
12181
Jouni Malinenf7222712019-06-13 01:50:21 +030012182static enum sigma_cmd_result cmd_sta_reset_parm(struct sigma_dut *dut,
12183 struct sigma_conn *conn,
12184 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012185{
12186 const char *intf = get_param(cmd, "Interface");
12187 const char *val;
12188
12189 /* TODO: ARP */
12190
12191 val = get_param(cmd, "HS2_CACHE_PROFILE");
12192 if (val && strcasecmp(val, "All") == 0)
12193 hs2_clear_credentials(intf);
12194
12195 return 1;
12196}
12197
12198
Jouni Malinenf7222712019-06-13 01:50:21 +030012199static enum sigma_cmd_result cmd_sta_get_key(struct sigma_dut *dut,
12200 struct sigma_conn *conn,
12201 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012202{
12203 const char *intf = get_param(cmd, "Interface");
12204 const char *key_type = get_param(cmd, "KeyType");
12205 char buf[100], resp[200];
12206
12207 if (key_type == NULL)
12208 return -1;
12209
12210 if (strcasecmp(key_type, "GTK") == 0) {
12211 if (wpa_command_resp(intf, "GET gtk", buf, sizeof(buf)) < 0 ||
12212 strncmp(buf, "FAIL", 4) == 0) {
12213 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12214 "not fetch current GTK");
12215 return 0;
12216 }
12217 snprintf(resp, sizeof(resp), "KeyValue,%s", buf);
12218 send_resp(dut, conn, SIGMA_COMPLETE, resp);
12219 return 0;
12220 } else {
12221 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
12222 "KeyType");
12223 return 0;
12224 }
12225
12226 return 1;
12227}
12228
12229
12230static int hs2_set_policy(struct sigma_dut *dut)
12231{
12232#ifdef ANDROID
12233 system("ip rule del prio 23000");
12234 if (system("ip rule add from all lookup main prio 23000") != 0) {
12235 sigma_dut_print(dut, DUT_MSG_ERROR,
12236 "Failed to run:ip rule add from all lookup main prio");
12237 return -1;
12238 }
12239 if (system("ip route flush cache") != 0) {
12240 sigma_dut_print(dut, DUT_MSG_ERROR,
12241 "Failed to run ip route flush cache");
12242 return -1;
12243 }
12244 return 1;
12245#else /* ANDROID */
12246 return 0;
12247#endif /* ANDROID */
12248}
12249
12250
Jouni Malinenf7222712019-06-13 01:50:21 +030012251static enum sigma_cmd_result cmd_sta_hs2_associate(struct sigma_dut *dut,
12252 struct sigma_conn *conn,
12253 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012254{
12255 const char *intf = get_param(cmd, "Interface");
12256 const char *val = get_param(cmd, "Ignore_blacklist");
Jouni Malinen439352d2018-09-13 03:42:23 +030012257 const char *band = get_param(cmd, "Band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012258 struct wpa_ctrl *ctrl;
Jouni Malinen3aa72862019-05-29 23:14:51 +030012259 int res, r;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012260 char bssid[20], ssid[40], resp[100], buf[100], blacklisted[100];
12261 int tries = 0;
12262 int ignore_blacklist = 0;
12263 const char *events[] = {
12264 "CTRL-EVENT-CONNECTED",
12265 "INTERWORKING-BLACKLISTED",
12266 "INTERWORKING-NO-MATCH",
12267 NULL
12268 };
12269
12270 start_sta_mode(dut);
12271
Jouni Malinen439352d2018-09-13 03:42:23 +030012272 if (band) {
12273 if (strcmp(band, "2.4") == 0) {
12274 wpa_command(intf, "SET setband 2G");
12275 } else if (strcmp(band, "5") == 0) {
12276 wpa_command(intf, "SET setband 5G");
12277 } else {
12278 send_resp(dut, conn, SIGMA_ERROR,
12279 "errorCode,Unsupported band");
12280 return 0;
12281 }
12282 }
12283
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012284 blacklisted[0] = '\0';
12285 if (val && atoi(val))
12286 ignore_blacklist = 1;
12287
12288try_again:
12289 ctrl = open_wpa_mon(intf);
12290 if (ctrl == NULL) {
12291 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
12292 "wpa_supplicant monitor connection");
12293 return -2;
12294 }
12295
12296 tries++;
12297 if (wpa_command(intf, "INTERWORKING_SELECT auto")) {
12298 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start "
12299 "Interworking connection");
12300 wpa_ctrl_detach(ctrl);
12301 wpa_ctrl_close(ctrl);
12302 return 0;
12303 }
12304
12305 buf[0] = '\0';
12306 while (1) {
12307 char *pos;
12308 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
12309 pos = strstr(buf, "INTERWORKING-BLACKLISTED");
12310 if (!pos)
12311 break;
12312 pos += 25;
12313 sigma_dut_print(dut, DUT_MSG_DEBUG, "Found blacklisted AP: %s",
12314 pos);
12315 if (!blacklisted[0])
12316 memcpy(blacklisted, pos, strlen(pos) + 1);
12317 }
12318
12319 if (ignore_blacklist && blacklisted[0]) {
12320 char *end;
12321 end = strchr(blacklisted, ' ');
12322 if (end)
12323 *end = '\0';
12324 sigma_dut_print(dut, DUT_MSG_DEBUG, "Try to connect to a blacklisted network: %s",
12325 blacklisted);
Jouni Malinen3aa72862019-05-29 23:14:51 +030012326 r = snprintf(buf, sizeof(buf), "INTERWORKING_CONNECT %s",
12327 blacklisted);
12328 if (r < 0 || r >= sizeof(buf) || wpa_command(intf, buf)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012329 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start Interworking connection to blacklisted network");
12330 wpa_ctrl_detach(ctrl);
12331 wpa_ctrl_close(ctrl);
12332 return 0;
12333 }
12334 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
12335 buf, sizeof(buf));
12336 }
12337
12338 wpa_ctrl_detach(ctrl);
12339 wpa_ctrl_close(ctrl);
12340
12341 if (res < 0) {
12342 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
12343 "connect");
12344 return 0;
12345 }
12346
12347 if (strstr(buf, "INTERWORKING-NO-MATCH") ||
12348 strstr(buf, "INTERWORKING-BLACKLISTED")) {
12349 if (tries < 2) {
12350 sigma_dut_print(dut, DUT_MSG_INFO, "No match found - try again to verify no APs were missed in the scan");
12351 goto try_again;
12352 }
12353 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,No network with "
12354 "matching credentials found");
12355 return 0;
12356 }
12357
12358 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
12359 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
12360 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
12361 "get current BSSID/SSID");
12362 return 0;
12363 }
12364
12365 snprintf(resp, sizeof(resp), "SSID,%s,BSSID,%s", ssid, bssid);
12366 send_resp(dut, conn, SIGMA_COMPLETE, resp);
12367 hs2_set_policy(dut);
12368 return 0;
12369}
12370
12371
Jouni Malinenf7222712019-06-13 01:50:21 +030012372static enum sigma_cmd_result cmd_sta_hs2_venue_info(struct sigma_dut *dut,
12373 struct sigma_conn *conn,
12374 struct sigma_cmd *cmd)
Jouni Malinenb639f1c2018-09-13 02:39:46 +030012375{
12376 const char *intf = get_param(cmd, "Interface");
12377 const char *display = get_param(cmd, "Display");
12378 struct wpa_ctrl *ctrl;
12379 char buf[300], params[400], *pos;
12380 char bssid[20];
12381 int info_avail = 0;
12382 unsigned int old_timeout;
12383 int res;
12384
12385 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0) {
12386 send_resp(dut, conn, SIGMA_ERROR,
12387 "ErrorCode,Could not get current BSSID");
12388 return 0;
12389 }
12390 ctrl = open_wpa_mon(intf);
12391 if (!ctrl) {
12392 sigma_dut_print(dut, DUT_MSG_ERROR,
12393 "Failed to open wpa_supplicant monitor connection");
12394 return -2;
12395 }
12396
12397 snprintf(buf, sizeof(buf), "ANQP_GET %s 277", bssid);
12398 wpa_command(intf, buf);
12399
12400 res = get_wpa_cli_event(dut, ctrl, "GAS-QUERY-DONE", buf, sizeof(buf));
12401 if (res < 0) {
12402 send_resp(dut, conn, SIGMA_ERROR,
12403 "ErrorCode,Could not complete GAS query");
12404 goto fail;
12405 }
12406
12407 old_timeout = dut->default_timeout;
12408 dut->default_timeout = 2;
12409 res = get_wpa_cli_event(dut, ctrl, "RX-VENUE-URL", buf, sizeof(buf));
12410 dut->default_timeout = old_timeout;
12411 if (res < 0)
12412 goto done;
12413 pos = strchr(buf, ' ');
12414 if (!pos)
12415 goto done;
12416 pos++;
12417 pos = strchr(pos, ' ');
12418 if (!pos)
12419 goto done;
12420 pos++;
12421 info_avail = 1;
12422 snprintf(params, sizeof(params), "browser %s", pos);
12423
12424 if (display && strcasecmp(display, "Yes") == 0) {
12425 pid_t pid;
12426
12427 pid = fork();
12428 if (pid < 0) {
12429 perror("fork");
12430 return -1;
12431 }
12432
12433 if (pid == 0) {
12434 run_hs20_osu(dut, params);
12435 exit(0);
12436 }
12437 }
12438
12439done:
12440 snprintf(buf, sizeof(buf), "Info_available,%s",
12441 info_avail ? "Yes" : "No");
12442 send_resp(dut, conn, SIGMA_COMPLETE, buf);
12443fail:
12444 wpa_ctrl_detach(ctrl);
12445 wpa_ctrl_close(ctrl);
12446 return 0;
12447}
12448
12449
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012450static int sta_add_credential_uname_pwd(struct sigma_dut *dut,
12451 struct sigma_conn *conn,
12452 const char *ifname,
12453 struct sigma_cmd *cmd)
12454{
12455 const char *val;
12456 int id;
12457
12458 id = add_cred(ifname);
12459 if (id < 0)
12460 return -2;
12461 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
12462
12463 val = get_param(cmd, "prefer");
12464 if (val && atoi(val) > 0)
12465 set_cred(ifname, id, "priority", "1");
12466
12467 val = get_param(cmd, "REALM");
12468 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
12469 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12470 "realm");
12471 return 0;
12472 }
12473
12474 val = get_param(cmd, "HOME_FQDN");
12475 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
12476 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12477 "home_fqdn");
12478 return 0;
12479 }
12480
12481 val = get_param(cmd, "Username");
12482 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
12483 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12484 "username");
12485 return 0;
12486 }
12487
12488 val = get_param(cmd, "Password");
12489 if (val && set_cred_quoted(ifname, id, "password", val) < 0) {
12490 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12491 "password");
12492 return 0;
12493 }
12494
12495 val = get_param(cmd, "ROOT_CA");
12496 if (val) {
12497 char fname[200];
12498 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
12499#ifdef __linux__
12500 if (!file_exists(fname)) {
12501 char msg[300];
12502 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
12503 "file (%s) not found", fname);
12504 send_resp(dut, conn, SIGMA_ERROR, msg);
12505 return 0;
12506 }
12507#endif /* __linux__ */
12508 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
12509 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12510 "not set root CA");
12511 return 0;
12512 }
12513 }
12514
12515 return 1;
12516}
12517
12518
12519static int update_devdetail_imsi(struct sigma_dut *dut, const char *imsi)
12520{
12521 FILE *in, *out;
12522 char buf[500];
12523 int found = 0;
12524
12525 in = fopen("devdetail.xml", "r");
12526 if (in == NULL)
12527 return -1;
12528 out = fopen("devdetail.xml.tmp", "w");
12529 if (out == NULL) {
12530 fclose(in);
12531 return -1;
12532 }
12533
12534 while (fgets(buf, sizeof(buf), in)) {
12535 char *pos = strstr(buf, "<IMSI>");
12536 if (pos) {
12537 sigma_dut_print(dut, DUT_MSG_INFO, "Updated DevDetail IMSI to %s",
12538 imsi);
12539 pos += 6;
12540 *pos = '\0';
12541 fprintf(out, "%s%s</IMSI>\n", buf, imsi);
12542 found++;
12543 } else {
12544 fprintf(out, "%s", buf);
12545 }
12546 }
12547
12548 fclose(out);
12549 fclose(in);
12550 if (found)
12551 rename("devdetail.xml.tmp", "devdetail.xml");
12552 else
12553 unlink("devdetail.xml.tmp");
12554
12555 return 0;
12556}
12557
12558
12559static int sta_add_credential_sim(struct sigma_dut *dut,
12560 struct sigma_conn *conn,
12561 const char *ifname, struct sigma_cmd *cmd)
12562{
12563 const char *val, *imsi = NULL;
12564 int id;
12565 char buf[200];
12566 int res;
12567 const char *pos;
12568 size_t mnc_len;
12569 char plmn_mcc[4];
12570 char plmn_mnc[4];
12571
12572 id = add_cred(ifname);
12573 if (id < 0)
12574 return -2;
12575 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
12576
12577 val = get_param(cmd, "prefer");
12578 if (val && atoi(val) > 0)
12579 set_cred(ifname, id, "priority", "1");
12580
12581 val = get_param(cmd, "PLMN_MCC");
12582 if (val == NULL) {
12583 send_resp(dut, conn, SIGMA_ERROR,
12584 "errorCode,Missing PLMN_MCC");
12585 return 0;
12586 }
12587 if (strlen(val) != 3) {
12588 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MCC");
12589 return 0;
12590 }
12591 snprintf(plmn_mcc, sizeof(plmn_mcc), "%s", val);
12592
12593 val = get_param(cmd, "PLMN_MNC");
12594 if (val == NULL) {
12595 send_resp(dut, conn, SIGMA_ERROR,
12596 "errorCode,Missing PLMN_MNC");
12597 return 0;
12598 }
12599 if (strlen(val) != 2 && strlen(val) != 3) {
12600 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MNC");
12601 return 0;
12602 }
12603 snprintf(plmn_mnc, sizeof(plmn_mnc), "%s", val);
12604
12605 val = get_param(cmd, "IMSI");
12606 if (val == NULL) {
12607 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing SIM "
12608 "IMSI");
12609 return 0;
12610 }
12611
12612 imsi = pos = val;
12613
12614 if (strncmp(plmn_mcc, pos, 3) != 0) {
12615 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MCC mismatch");
12616 return 0;
12617 }
12618 pos += 3;
12619
12620 mnc_len = strlen(plmn_mnc);
12621 if (mnc_len < 2) {
12622 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC not set");
12623 return 0;
12624 }
12625
12626 if (strncmp(plmn_mnc, pos, mnc_len) != 0) {
12627 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC mismatch");
12628 return 0;
12629 }
12630 pos += mnc_len;
12631
12632 res = snprintf(buf, sizeof(buf), "%s%s-%s",plmn_mcc, plmn_mnc, pos);
12633 if (res < 0 || res >= (int) sizeof(buf))
12634 return -1;
12635 if (set_cred_quoted(ifname, id, "imsi", buf) < 0) {
12636 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12637 "not set IMSI");
12638 return 0;
12639 }
12640
12641 val = get_param(cmd, "Password");
12642 if (val && set_cred_quoted(ifname, id, "milenage", val) < 0) {
12643 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12644 "not set password");
12645 return 0;
12646 }
12647
Jouni Malinenba630452018-06-22 11:49:59 +030012648 if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012649 /*
12650 * Set provisioning_sp for the test cases where SIM/USIM
12651 * provisioning is used.
12652 */
12653 if (val && set_cred_quoted(ifname, id, "provisioning_sp",
12654 "wi-fi.org") < 0) {
12655 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12656 "not set provisioning_sp");
12657 return 0;
12658 }
12659
12660 update_devdetail_imsi(dut, imsi);
12661 }
12662
12663 return 1;
12664}
12665
12666
12667static int sta_add_credential_cert(struct sigma_dut *dut,
12668 struct sigma_conn *conn,
12669 const char *ifname,
12670 struct sigma_cmd *cmd)
12671{
12672 const char *val;
12673 int id;
12674
12675 id = add_cred(ifname);
12676 if (id < 0)
12677 return -2;
12678 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
12679
12680 val = get_param(cmd, "prefer");
12681 if (val && atoi(val) > 0)
12682 set_cred(ifname, id, "priority", "1");
12683
12684 val = get_param(cmd, "REALM");
12685 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
12686 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12687 "realm");
12688 return 0;
12689 }
12690
12691 val = get_param(cmd, "HOME_FQDN");
12692 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
12693 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12694 "home_fqdn");
12695 return 0;
12696 }
12697
12698 val = get_param(cmd, "Username");
12699 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
12700 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12701 "username");
12702 return 0;
12703 }
12704
12705 val = get_param(cmd, "clientCertificate");
12706 if (val) {
12707 char fname[200];
12708 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
12709#ifdef __linux__
12710 if (!file_exists(fname)) {
12711 char msg[300];
12712 snprintf(msg, sizeof(msg),
12713 "ErrorCode,clientCertificate "
12714 "file (%s) not found", fname);
12715 send_resp(dut, conn, SIGMA_ERROR, msg);
12716 return 0;
12717 }
12718#endif /* __linux__ */
12719 if (set_cred_quoted(ifname, id, "client_cert", fname) < 0) {
12720 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12721 "not set client_cert");
12722 return 0;
12723 }
12724 if (set_cred_quoted(ifname, id, "private_key", fname) < 0) {
12725 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12726 "not set private_key");
12727 return 0;
12728 }
12729 }
12730
12731 val = get_param(cmd, "ROOT_CA");
12732 if (val) {
12733 char fname[200];
12734 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
12735#ifdef __linux__
12736 if (!file_exists(fname)) {
12737 char msg[300];
12738 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
12739 "file (%s) not found", fname);
12740 send_resp(dut, conn, SIGMA_ERROR, msg);
12741 return 0;
12742 }
12743#endif /* __linux__ */
12744 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
12745 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12746 "not set root CA");
12747 return 0;
12748 }
12749 }
12750
12751 return 1;
12752}
12753
12754
Jouni Malinenf7222712019-06-13 01:50:21 +030012755static enum sigma_cmd_result cmd_sta_add_credential(struct sigma_dut *dut,
12756 struct sigma_conn *conn,
12757 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012758{
12759 const char *intf = get_param(cmd, "Interface");
12760 const char *type;
12761
12762 start_sta_mode(dut);
12763
12764 type = get_param(cmd, "Type");
12765 if (!type)
12766 return -1;
12767
12768 if (strcasecmp(type, "uname_pwd") == 0)
12769 return sta_add_credential_uname_pwd(dut, conn, intf, cmd);
12770
12771 if (strcasecmp(type, "sim") == 0)
12772 return sta_add_credential_sim(dut, conn, intf, cmd);
12773
12774 if (strcasecmp(type, "cert") == 0)
12775 return sta_add_credential_cert(dut, conn, intf, cmd);
12776
12777 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported credential "
12778 "type");
12779 return 0;
12780}
12781
12782
Jouni Malinenf7222712019-06-13 01:50:21 +030012783static enum sigma_cmd_result cmd_sta_scan(struct sigma_dut *dut,
12784 struct sigma_conn *conn,
12785 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012786{
12787 const char *intf = get_param(cmd, "Interface");
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080012788 const char *val, *bssid, *ssid, *scan_freq, *short_ssid;
Arif Hussain66a4af02019-02-07 15:04:51 -080012789 char buf[4096];
vamsi krishna89ad8c62017-09-19 12:51:18 +053012790 char ssid_hex[65];
Kiran Kumar Lokere3399af22020-03-04 16:31:56 -080012791 int wildcard_ssid = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012792 int res;
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080012793 enum sigma_cmd_result status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012794
Jouni Malinen8c1abeb2019-11-06 18:48:34 +020012795 start_sta_mode(dut);
12796
Arif Hussain66a4af02019-02-07 15:04:51 -080012797 val = get_param(cmd, "GetParameter");
12798 if (val && strcmp(val, "SSID_BSSID") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012799 if (get_wpa_ssid_bssid(dut, get_station_ifname(dut),
Arif Hussain66a4af02019-02-07 15:04:51 -080012800 buf, sizeof(buf)) < 0) {
12801 sigma_dut_print(dut, DUT_MSG_ERROR,
12802 "Could not get ssid bssid");
12803 return ERROR_SEND_STATUS;
12804 }
12805
12806 sigma_dut_print(dut, DUT_MSG_INFO, "%s", buf);
12807 send_resp(dut, conn, SIGMA_COMPLETE, buf);
12808 return STATUS_SENT;
12809 }
12810
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012811 val = get_param(cmd, "HESSID");
12812 if (val) {
12813 res = snprintf(buf, sizeof(buf), "SET hessid %s", val);
12814 if (res < 0 || res >= (int) sizeof(buf))
12815 return -1;
12816 wpa_command(intf, buf);
12817 }
12818
12819 val = get_param(cmd, "ACCS_NET_TYPE");
12820 if (val) {
12821 res = snprintf(buf, sizeof(buf), "SET access_network_type %s",
12822 val);
12823 if (res < 0 || res >= (int) sizeof(buf))
12824 return -1;
12825 wpa_command(intf, buf);
12826 }
12827
vamsi krishna89ad8c62017-09-19 12:51:18 +053012828 bssid = get_param(cmd, "Bssid");
12829 ssid = get_param(cmd, "Ssid");
12830
Kiran Kumar Lokere3399af22020-03-04 16:31:56 -080012831 if (ssid && strcasecmp(ssid, "ZeroLength") == 0 &&
12832 dut->device_type == STA_testbed) {
12833 ssid = NULL;
12834 wildcard_ssid = 1;
12835 }
12836
vamsi krishna89ad8c62017-09-19 12:51:18 +053012837 if (ssid) {
12838 if (2 * strlen(ssid) >= sizeof(ssid_hex)) {
12839 send_resp(dut, conn, SIGMA_ERROR,
12840 "ErrorCode,Too long SSID");
12841 return 0;
12842 }
12843 ascii2hexstr(ssid, ssid_hex);
12844 }
12845
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080012846 short_ssid = get_param(cmd, "ShortSSID");
12847 if (short_ssid) {
12848 uint32_t short_ssid_hex;
12849
12850 short_ssid_hex = strtoul(short_ssid, NULL, 16);
12851 short_ssid_hex = ((short_ssid_hex & 0xFF) << 24) |
12852 (((short_ssid_hex >> 8) & 0xFF) << 16) |
12853 (((short_ssid_hex >> 16) & 0xFF) << 8) |
12854 ((short_ssid_hex >> 24) & 0xFF);
12855
12856 res = snprintf(buf, sizeof(buf),
12857 "VENDOR_ELEM_ADD 14 ff053a%08x",
12858 short_ssid_hex);
12859 if (res < 0 || res >= (int) sizeof(buf) ||
12860 wpa_command(intf, buf)) {
12861 send_resp(dut, conn, SIGMA_ERROR,
12862 "errorCode,Failed to add short SSID");
12863 return STATUS_SENT_ERROR;
12864 }
12865 }
12866
Kiran Kumar Lokerec0deb482020-03-04 16:35:06 -080012867 scan_freq = get_param(cmd, "ChnlFreq");
12868
12869 res = snprintf(buf, sizeof(buf), "SCAN%s%s%s%s%s%s%s",
vamsi krishna89ad8c62017-09-19 12:51:18 +053012870 bssid ? " bssid=": "",
12871 bssid ? bssid : "",
12872 ssid ? " ssid " : "",
Kiran Kumar Lokere3399af22020-03-04 16:31:56 -080012873 ssid ? ssid_hex : "",
Kiran Kumar Lokerec0deb482020-03-04 16:35:06 -080012874 wildcard_ssid ? " wildcard_ssid=1" : "",
12875 scan_freq ? " freq=" : "",
12876 scan_freq ? scan_freq : "");
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080012877 if (res < 0 || res >= (int) sizeof(buf)) {
12878 send_resp(dut, conn, SIGMA_ERROR,
12879 "errorCode,Could not build scan command");
12880 status = STATUS_SENT_ERROR;
12881 goto remove_s_ssid;
12882 }
vamsi krishna89ad8c62017-09-19 12:51:18 +053012883
12884 if (wpa_command(intf, buf)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012885 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not start "
12886 "scan");
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080012887 status = STATUS_SENT_ERROR;
12888 } else {
12889 status = SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012890 }
12891
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080012892remove_s_ssid:
12893 if (short_ssid && wpa_command(intf, "VENDOR_ELEM_REMOVE 14 *"))
12894 sigma_dut_print(dut, DUT_MSG_ERROR,
12895 "Failed to delete vendor element");
12896
12897 return status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012898}
12899
12900
Jouni Malinenf7222712019-06-13 01:50:21 +030012901static enum sigma_cmd_result cmd_sta_scan_bss(struct sigma_dut *dut,
12902 struct sigma_conn *conn,
12903 struct sigma_cmd *cmd)
Jouni Malinen5e5d43d2018-01-10 17:29:33 +020012904{
12905 const char *intf = get_param(cmd, "Interface");
12906 const char *bssid;
12907 char buf[4096], *pos;
12908 int freq, chan;
12909 char *ssid;
12910 char resp[100];
12911 int res;
12912 struct wpa_ctrl *ctrl;
12913
12914 bssid = get_param(cmd, "BSSID");
12915 if (!bssid) {
12916 send_resp(dut, conn, SIGMA_INVALID,
12917 "errorCode,BSSID argument is missing");
12918 return 0;
12919 }
12920
12921 ctrl = open_wpa_mon(intf);
12922 if (!ctrl) {
12923 sigma_dut_print(dut, DUT_MSG_ERROR,
12924 "Failed to open wpa_supplicant monitor connection");
12925 return -1;
12926 }
12927
12928 if (wpa_command(intf, "SCAN TYPE=ONLY")) {
12929 send_resp(dut, conn, SIGMA_ERROR,
12930 "errorCode,Could not start scan");
12931 wpa_ctrl_detach(ctrl);
12932 wpa_ctrl_close(ctrl);
12933 return 0;
12934 }
12935
12936 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
12937 buf, sizeof(buf));
12938
12939 wpa_ctrl_detach(ctrl);
12940 wpa_ctrl_close(ctrl);
12941
12942 if (res < 0) {
12943 send_resp(dut, conn, SIGMA_ERROR,
12944 "errorCode,Scan did not complete");
12945 return 0;
12946 }
12947
12948 snprintf(buf, sizeof(buf), "BSS %s", bssid);
12949 if (wpa_command_resp(intf, buf, buf, sizeof(buf)) < 0 ||
12950 strncmp(buf, "id=", 3) != 0) {
12951 send_resp(dut, conn, SIGMA_ERROR,
12952 "errorCode,Specified BSSID not found");
12953 return 0;
12954 }
12955
12956 pos = strstr(buf, "\nfreq=");
12957 if (!pos) {
12958 send_resp(dut, conn, SIGMA_ERROR,
12959 "errorCode,Channel not found");
12960 return 0;
12961 }
12962 freq = atoi(pos + 6);
12963 chan = freq_to_channel(freq);
12964
12965 pos = strstr(buf, "\nssid=");
12966 if (!pos) {
12967 send_resp(dut, conn, SIGMA_ERROR,
12968 "errorCode,SSID not found");
12969 return 0;
12970 }
12971 ssid = pos + 6;
12972 pos = strchr(ssid, '\n');
12973 if (pos)
12974 *pos = '\0';
12975 snprintf(resp, sizeof(resp), "ssid,%s,bsschannel,%d", ssid, chan);
12976 send_resp(dut, conn, SIGMA_COMPLETE, resp);
12977 return 0;
12978}
12979
12980
Jouni Malinenf7222712019-06-13 01:50:21 +030012981static enum sigma_cmd_result cmd_sta_set_systime(struct sigma_dut *dut,
12982 struct sigma_conn *conn,
12983 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012984{
12985#ifdef __linux__
12986 struct timeval tv;
12987 struct tm tm;
12988 time_t t;
12989 const char *val;
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +053012990 int v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012991
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012992 wpa_command(get_station_ifname(dut), "PMKSA_FLUSH");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012993
12994 memset(&tm, 0, sizeof(tm));
12995 val = get_param(cmd, "seconds");
12996 if (val)
12997 tm.tm_sec = atoi(val);
12998 val = get_param(cmd, "minutes");
12999 if (val)
13000 tm.tm_min = atoi(val);
13001 val = get_param(cmd, "hours");
13002 if (val)
13003 tm.tm_hour = atoi(val);
13004 val = get_param(cmd, "date");
13005 if (val)
13006 tm.tm_mday = atoi(val);
13007 val = get_param(cmd, "month");
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +053013008 if (val) {
13009 v = atoi(val);
13010 if (v < 1 || v > 12) {
13011 send_resp(dut, conn, SIGMA_INVALID,
13012 "errorCode,Invalid month");
13013 return 0;
13014 }
13015 tm.tm_mon = v - 1;
13016 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013017 val = get_param(cmd, "year");
13018 if (val) {
13019 int year = atoi(val);
13020#ifdef ANDROID
13021 if (year > 2035)
13022 year = 2035; /* years beyond 2035 not supported */
13023#endif /* ANDROID */
13024 tm.tm_year = year - 1900;
13025 }
13026 t = mktime(&tm);
13027 if (t == (time_t) -1) {
13028 send_resp(dut, conn, SIGMA_ERROR,
13029 "errorCode,Invalid date or time");
13030 return 0;
13031 }
13032
13033 memset(&tv, 0, sizeof(tv));
13034 tv.tv_sec = t;
13035
13036 if (settimeofday(&tv, NULL) < 0) {
13037 sigma_dut_print(dut, DUT_MSG_INFO, "settimeofday failed: %s",
13038 strerror(errno));
13039 send_resp(dut, conn, SIGMA_ERROR,
13040 "errorCode,Failed to set time");
13041 return 0;
13042 }
13043
13044 return 1;
13045#endif /* __linux__ */
13046
13047 return -1;
13048}
13049
13050
Jouni Malinenf7222712019-06-13 01:50:21 +030013051static enum sigma_cmd_result cmd_sta_osu(struct sigma_dut *dut,
13052 struct sigma_conn *conn,
13053 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013054{
13055 const char *intf = get_param(cmd, "Interface");
Jouni Malinen4c8681c2018-09-12 23:28:11 +030013056 const char *name, *osu_ssid, *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013057 int prod_ess_assoc = 1;
Jouni Malinen4c8681c2018-09-12 23:28:11 +030013058 char buf[300], bssid[100], ssid[100];
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013059 int res;
13060 struct wpa_ctrl *ctrl;
13061
13062 name = get_param(cmd, "osuFriendlyName");
Jouni Malinen4c8681c2018-09-12 23:28:11 +030013063 osu_ssid = get_param(cmd, "osu_ssid");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013064
13065 val = get_param(cmd, "ProdESSAssoc");
13066 if (val)
13067 prod_ess_assoc = atoi(val);
13068
13069 kill_dhcp_client(dut, intf);
13070 if (start_dhcp_client(dut, intf) < 0)
13071 return -2;
13072
13073 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger OSU");
13074 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
13075 res = snprintf(buf, sizeof(buf),
Jouni Malinen4c8681c2018-09-12 23:28:11 +030013076 "%s %s%s%s %s%s%s signup osu-ca.pem",
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013077 prod_ess_assoc ? "" : "-N",
13078 name ? "-O'" : "", name ? name : "",
Jouni Malinen4c8681c2018-09-12 23:28:11 +030013079 name ? "'" : "",
13080 osu_ssid ? "-o'" : "", osu_ssid ? osu_ssid : "",
13081 osu_ssid ? "'" : "");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013082
Kanchanapally, Vidyullatha12b66762015-12-31 16:46:42 +053013083 hs2_set_policy(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013084 if (run_hs20_osu(dut, buf) < 0) {
13085 FILE *f;
13086
13087 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to complete OSU");
13088
13089 f = fopen("hs20-osu-client.res", "r");
13090 if (f) {
13091 char resp[400], res[300], *pos;
13092 if (!fgets(res, sizeof(res), f))
13093 res[0] = '\0';
13094 pos = strchr(res, '\n');
13095 if (pos)
13096 *pos = '\0';
13097 fclose(f);
13098 sigma_dut_summary(dut, "hs20-osu-client provisioning failed: %s",
13099 res);
13100 snprintf(resp, sizeof(resp), "notify-send '%s'", res);
13101 if (system(resp) != 0) {
13102 }
13103 snprintf(resp, sizeof(resp),
13104 "SSID,,BSSID,,failureReason,%s", res);
13105 send_resp(dut, conn, SIGMA_COMPLETE, resp);
13106 return 0;
13107 }
13108
13109 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
13110 return 0;
13111 }
13112
13113 if (!prod_ess_assoc)
13114 goto report;
13115
13116 ctrl = open_wpa_mon(intf);
13117 if (ctrl == NULL) {
13118 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
13119 "wpa_supplicant monitor connection");
13120 return -1;
13121 }
13122
13123 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
13124 buf, sizeof(buf));
13125
13126 wpa_ctrl_detach(ctrl);
13127 wpa_ctrl_close(ctrl);
13128
13129 if (res < 0) {
13130 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to connect to "
13131 "network after OSU");
13132 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
13133 return 0;
13134 }
13135
13136report:
13137 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
13138 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
13139 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to get BSSID/SSID");
13140 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
13141 return 0;
13142 }
13143
13144 snprintf(buf, sizeof(buf), "SSID,%s,BSSID,%s", ssid, bssid);
13145 send_resp(dut, conn, SIGMA_COMPLETE, buf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013146 return 0;
13147}
13148
13149
Jouni Malinenf7222712019-06-13 01:50:21 +030013150static enum sigma_cmd_result cmd_sta_policy_update(struct sigma_dut *dut,
13151 struct sigma_conn *conn,
13152 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013153{
13154 const char *val;
13155 int timeout = 120;
13156
13157 val = get_param(cmd, "PolicyUpdate");
13158 if (val == NULL || atoi(val) == 0)
13159 return 1; /* No operation requested */
13160
13161 val = get_param(cmd, "Timeout");
13162 if (val)
13163 timeout = atoi(val);
13164
13165 if (timeout) {
13166 /* TODO: time out the command and return
13167 * PolicyUpdateStatus,TIMEOUT if needed. */
13168 }
13169
13170 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger policy update");
13171 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
13172 if (run_hs20_osu(dut, "pol_upd fqdn=wi-fi.org") < 0) {
13173 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,FAIL");
13174 return 0;
13175 }
13176
13177 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,SUCCESS");
13178 return 0;
13179}
13180
13181
Jouni Malinenf7222712019-06-13 01:50:21 +030013182static enum sigma_cmd_result cmd_sta_er_config(struct sigma_dut *dut,
13183 struct sigma_conn *conn,
13184 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013185{
13186 struct wpa_ctrl *ctrl;
13187 const char *intf = get_param(cmd, "Interface");
13188 const char *bssid = get_param(cmd, "Bssid");
13189 const char *ssid = get_param(cmd, "SSID");
13190 const char *security = get_param(cmd, "Security");
13191 const char *passphrase = get_param(cmd, "Passphrase");
13192 const char *pin = get_param(cmd, "PIN");
13193 char buf[1000];
13194 char ssid_hex[200], passphrase_hex[200];
13195 const char *keymgmt, *cipher;
13196
13197 if (intf == NULL)
Jouni Malinen016ae6c2019-11-04 17:00:01 +020013198 intf = get_main_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013199
13200 if (!bssid) {
13201 send_resp(dut, conn, SIGMA_ERROR,
13202 "ErrorCode,Missing Bssid argument");
13203 return 0;
13204 }
13205
13206 if (!ssid) {
13207 send_resp(dut, conn, SIGMA_ERROR,
13208 "ErrorCode,Missing SSID argument");
13209 return 0;
13210 }
13211
13212 if (!security) {
13213 send_resp(dut, conn, SIGMA_ERROR,
13214 "ErrorCode,Missing Security argument");
13215 return 0;
13216 }
13217
13218 if (!passphrase) {
13219 send_resp(dut, conn, SIGMA_ERROR,
13220 "ErrorCode,Missing Passphrase argument");
13221 return 0;
13222 }
13223
13224 if (!pin) {
13225 send_resp(dut, conn, SIGMA_ERROR,
13226 "ErrorCode,Missing PIN argument");
13227 return 0;
13228 }
13229
vamsi krishna8c9c1562017-05-12 15:51:46 +053013230 if (2 * strlen(ssid) >= sizeof(ssid_hex) ||
13231 2 * strlen(passphrase) >= sizeof(passphrase_hex)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013232 send_resp(dut, conn, SIGMA_ERROR,
13233 "ErrorCode,Too long SSID/passphrase");
13234 return 0;
13235 }
13236
13237 ctrl = open_wpa_mon(intf);
13238 if (ctrl == NULL) {
13239 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
13240 "wpa_supplicant monitor connection");
13241 return -2;
13242 }
13243
13244 if (strcasecmp(security, "wpa2-psk") == 0) {
13245 keymgmt = "WPA2PSK";
13246 cipher = "CCMP";
13247 } else {
13248 wpa_ctrl_detach(ctrl);
13249 wpa_ctrl_close(ctrl);
13250 send_resp(dut, conn, SIGMA_ERROR,
13251 "ErrorCode,Unsupported Security value");
13252 return 0;
13253 }
13254
13255 ascii2hexstr(ssid, ssid_hex);
13256 ascii2hexstr(passphrase, passphrase_hex);
13257 snprintf(buf, sizeof(buf), "WPS_REG %s %s %s %s %s %s",
13258 bssid, pin, ssid_hex, keymgmt, cipher, passphrase_hex);
13259
13260 if (wpa_command(intf, buf) < 0) {
13261 wpa_ctrl_detach(ctrl);
13262 wpa_ctrl_close(ctrl);
13263 send_resp(dut, conn, SIGMA_ERROR,
13264 "ErrorCode,Failed to start registrar");
13265 return 0;
13266 }
13267
13268 snprintf(dut->er_oper_bssid, sizeof(dut->er_oper_bssid), "%s", bssid);
13269 dut->er_oper_performed = 1;
13270
13271 return wps_connection_event(dut, conn, ctrl, intf, 0);
13272}
13273
13274
Jouni Malinenf7222712019-06-13 01:50:21 +030013275static enum sigma_cmd_result
13276cmd_sta_wps_connect_pw_token(struct sigma_dut *dut, struct sigma_conn *conn,
13277 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013278{
13279 struct wpa_ctrl *ctrl;
13280 const char *intf = get_param(cmd, "Interface");
13281 const char *bssid = get_param(cmd, "Bssid");
13282 char buf[100];
13283
13284 if (!bssid) {
13285 send_resp(dut, conn, SIGMA_ERROR,
13286 "ErrorCode,Missing Bssid argument");
13287 return 0;
13288 }
13289
13290 ctrl = open_wpa_mon(intf);
13291 if (ctrl == NULL) {
13292 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
13293 "wpa_supplicant monitor connection");
13294 return -2;
13295 }
13296
13297 snprintf(buf, sizeof(buf), "WPS_NFC %s", bssid);
13298
13299 if (wpa_command(intf, buf) < 0) {
13300 wpa_ctrl_detach(ctrl);
13301 wpa_ctrl_close(ctrl);
13302 send_resp(dut, conn, SIGMA_ERROR,
13303 "ErrorCode,Failed to start registrar");
13304 return 0;
13305 }
13306
13307 return wps_connection_event(dut, conn, ctrl, intf, 0);
13308}
13309
13310
Jouni Malinenf7222712019-06-13 01:50:21 +030013311static enum sigma_cmd_result cmd_start_wps_registration(struct sigma_dut *dut,
13312 struct sigma_conn *conn,
13313 struct sigma_cmd *cmd)
vamsi krishna9b144002017-09-20 13:28:13 +053013314{
13315 struct wpa_ctrl *ctrl;
13316 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020013317 const char *network_mode = get_param(cmd, "network_mode");
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020013318 const char *config_method = get_param(cmd, "WPSConfigMethod");
13319 const char *role;
vamsi krishna9b144002017-09-20 13:28:13 +053013320 int res;
13321 char buf[256];
13322 const char *events[] = {
13323 "CTRL-EVENT-CONNECTED",
13324 "WPS-OVERLAP-DETECTED",
13325 "WPS-TIMEOUT",
13326 "WPS-FAIL",
13327 NULL
13328 };
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020013329 int id = 0;
vamsi krishna9b144002017-09-20 13:28:13 +053013330
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020013331 /* 60G WPS tests do not pass Interface parameter */
13332 if (!intf)
Jouni Malinen016ae6c2019-11-04 17:00:01 +020013333 intf = get_main_ifname(dut);
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020013334
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020013335 if (dut->mode == SIGMA_MODE_AP)
13336 return ap_wps_registration(dut, conn, cmd);
13337
13338 if (config_method) {
13339 /* WFA_CS_WPS_PIN_KEYPAD mode is set when using the
13340 * sta_wps_enter_pin before calling start_wps_registration. */
13341 if (strcasecmp(config_method, "PBC") == 0)
13342 dut->wps_method = WFA_CS_WPS_PBC;
13343 }
13344 if (dut->wps_method == WFA_CS_WPS_NOT_READY) {
13345 send_resp(dut, conn, SIGMA_ERROR,
13346 "ErrorCode,WPS parameters not yet set");
13347 return STATUS_SENT;
13348 }
13349
13350 /* Make sure WPS is enabled (also for STA mode) */
13351 dut->wps_disable = 0;
13352
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020013353 if (dut->band == WPS_BAND_60G && network_mode &&
13354 strcasecmp(network_mode, "PBSS") == 0) {
13355 sigma_dut_print(dut, DUT_MSG_DEBUG,
13356 "Set PBSS network mode, network id %d", id);
Jouni Malinen016ae6c2019-11-04 17:00:01 +020013357 if (set_network(get_station_ifname(dut), id, "pbss", "1") < 0)
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020013358 return -2;
13359 }
13360
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020013361 if (dut->force_rsn_ie) {
13362 sigma_dut_print(dut, DUT_MSG_DEBUG, "Force RSN_IE: %d",
13363 dut->force_rsn_ie);
13364 if (sta_60g_force_rsn_ie(dut, dut->force_rsn_ie) < 0) {
13365 sigma_dut_print(dut, DUT_MSG_INFO,
13366 "Failed to force RSN_IE");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020013367 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020013368 }
13369 }
13370
vamsi krishna9b144002017-09-20 13:28:13 +053013371 ctrl = open_wpa_mon(intf);
13372 if (!ctrl) {
13373 sigma_dut_print(dut, DUT_MSG_ERROR,
13374 "Failed to open wpa_supplicant monitor connection");
13375 return -2;
13376 }
13377
13378 role = get_param(cmd, "WpsRole");
13379 if (!role) {
13380 send_resp(dut, conn, SIGMA_INVALID,
13381 "ErrorCode,WpsRole not provided");
13382 goto fail;
13383 }
13384
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020013385 if (strcasecmp(role, "Enrollee") != 0) {
13386 /* Registrar role for STA not supported */
13387 send_resp(dut, conn, SIGMA_ERROR,
13388 "ErrorCode,Unsupported WpsRole value");
13389 goto fail;
13390 }
13391
13392 if (is_60g_sigma_dut(dut)) {
13393 if (dut->wps_method == WFA_CS_WPS_PBC)
13394 snprintf(buf, sizeof(buf), "WPS_PBC");
13395 else /* WFA_CS_WPS_PIN_KEYPAD */
13396 snprintf(buf, sizeof(buf), "WPS_PIN any %s",
13397 dut->wps_pin);
13398 if (wpa_command(intf, buf) < 0) {
13399 send_resp(dut, conn, SIGMA_ERROR,
13400 "ErrorCode,Failed to start WPS");
vamsi krishna9b144002017-09-20 13:28:13 +053013401 goto fail;
13402 }
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020013403 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
13404 if (res < 0) {
13405 send_resp(dut, conn, SIGMA_ERROR,
13406 "ErrorCode,WPS connection did not complete");
13407 goto fail;
13408 }
13409 if (strstr(buf, "WPS-TIMEOUT")) {
13410 send_resp(dut, conn, SIGMA_COMPLETE, "WpsState,NoPeer");
13411 } else if (strstr(buf, "WPS-OVERLAP-DETECTED")) {
13412 send_resp(dut, conn, SIGMA_COMPLETE,
13413 "WpsState,OverlapSession");
13414 } else if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
13415 send_resp(dut, conn, SIGMA_COMPLETE,
13416 "WpsState,Successful");
13417 } else {
13418 send_resp(dut, conn, SIGMA_COMPLETE,
13419 "WpsState,Failure");
13420 }
13421 } else {
13422 if (dut->wps_method == WFA_CS_WPS_PBC) {
vamsi krishna9b144002017-09-20 13:28:13 +053013423 if (wpa_command(intf, "WPS_PBC") < 0) {
13424 send_resp(dut, conn, SIGMA_ERROR,
13425 "ErrorCode,Failed to enable PBC");
13426 goto fail;
13427 }
13428 } else {
13429 /* TODO: PIN method */
13430 send_resp(dut, conn, SIGMA_ERROR,
13431 "ErrorCode,Unsupported WpsConfigMethod value");
13432 goto fail;
13433 }
13434 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
13435 if (res < 0) {
13436 send_resp(dut, conn, SIGMA_ERROR,
13437 "ErrorCode,WPS connection did not complete");
13438 goto fail;
13439 }
13440 if (strstr(buf, "WPS-TIMEOUT")) {
13441 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,NoPeer");
13442 } else if (strstr(buf, "WPS-OVERLAP-DETECTED")) {
13443 send_resp(dut, conn, SIGMA_ERROR,
13444 "ErrorCode,OverlapSession");
13445 } else if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
13446 send_resp(dut, conn, SIGMA_COMPLETE, "Successful");
13447 } else {
13448 send_resp(dut, conn, SIGMA_ERROR,
13449 "ErrorCode,WPS operation failed");
13450 }
vamsi krishna9b144002017-09-20 13:28:13 +053013451 }
13452
13453fail:
13454 wpa_ctrl_detach(ctrl);
13455 wpa_ctrl_close(ctrl);
13456 return 0;
13457}
13458
13459
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013460static int req_intf(struct sigma_cmd *cmd)
13461{
13462 return get_param(cmd, "interface") == NULL ? -1 : 0;
13463}
13464
13465
13466void sta_register_cmds(void)
13467{
13468 sigma_dut_reg_cmd("sta_get_ip_config", req_intf,
13469 cmd_sta_get_ip_config);
13470 sigma_dut_reg_cmd("sta_set_ip_config", req_intf,
13471 cmd_sta_set_ip_config);
13472 sigma_dut_reg_cmd("sta_get_info", req_intf, cmd_sta_get_info);
13473 sigma_dut_reg_cmd("sta_get_mac_address", req_intf,
13474 cmd_sta_get_mac_address);
13475 sigma_dut_reg_cmd("sta_is_connected", req_intf, cmd_sta_is_connected);
13476 sigma_dut_reg_cmd("sta_verify_ip_connection", req_intf,
13477 cmd_sta_verify_ip_connection);
13478 sigma_dut_reg_cmd("sta_get_bssid", req_intf, cmd_sta_get_bssid);
13479 sigma_dut_reg_cmd("sta_set_encryption", req_intf,
13480 cmd_sta_set_encryption);
13481 sigma_dut_reg_cmd("sta_set_psk", req_intf, cmd_sta_set_psk);
13482 sigma_dut_reg_cmd("sta_set_eaptls", req_intf, cmd_sta_set_eaptls);
13483 sigma_dut_reg_cmd("sta_set_eapttls", req_intf, cmd_sta_set_eapttls);
13484 sigma_dut_reg_cmd("sta_set_eapsim", req_intf, cmd_sta_set_eapsim);
13485 sigma_dut_reg_cmd("sta_set_peap", req_intf, cmd_sta_set_peap);
13486 sigma_dut_reg_cmd("sta_set_eapfast", req_intf, cmd_sta_set_eapfast);
13487 sigma_dut_reg_cmd("sta_set_eapaka", req_intf, cmd_sta_set_eapaka);
13488 sigma_dut_reg_cmd("sta_set_eapakaprime", req_intf,
13489 cmd_sta_set_eapakaprime);
13490 sigma_dut_reg_cmd("sta_set_security", req_intf, cmd_sta_set_security);
13491 sigma_dut_reg_cmd("sta_set_uapsd", req_intf, cmd_sta_set_uapsd);
13492 /* TODO: sta_set_ibss */
13493 /* TODO: sta_set_mode */
13494 sigma_dut_reg_cmd("sta_set_wmm", req_intf, cmd_sta_set_wmm);
13495 sigma_dut_reg_cmd("sta_associate", req_intf, cmd_sta_associate);
13496 /* TODO: sta_up_load */
13497 sigma_dut_reg_cmd("sta_preset_testparameters", req_intf,
13498 cmd_sta_preset_testparameters);
13499 /* TODO: sta_set_system */
13500 sigma_dut_reg_cmd("sta_set_11n", req_intf, cmd_sta_set_11n);
13501 /* TODO: sta_set_rifs_test */
13502 sigma_dut_reg_cmd("sta_set_wireless", req_intf, cmd_sta_set_wireless);
13503 sigma_dut_reg_cmd("sta_send_addba", req_intf, cmd_sta_send_addba);
13504 /* TODO: sta_send_coexist_mgmt */
13505 sigma_dut_reg_cmd("sta_disconnect", req_intf, cmd_sta_disconnect);
13506 sigma_dut_reg_cmd("sta_reassoc", req_intf, cmd_sta_reassoc);
13507 sigma_dut_reg_cmd("sta_reassociate", req_intf, cmd_sta_reassoc);
13508 sigma_dut_reg_cmd("sta_reset_default", req_intf,
13509 cmd_sta_reset_default);
13510 sigma_dut_reg_cmd("sta_send_frame", req_intf, cmd_sta_send_frame);
13511 sigma_dut_reg_cmd("sta_set_macaddr", req_intf, cmd_sta_set_macaddr);
13512 sigma_dut_reg_cmd("sta_set_rfeature", req_intf, cmd_sta_set_rfeature);
13513 sigma_dut_reg_cmd("sta_set_radio", req_intf, cmd_sta_set_radio);
13514 sigma_dut_reg_cmd("sta_set_pwrsave", req_intf, cmd_sta_set_pwrsave);
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020013515 sigma_dut_reg_cmd("sta_set_power_save", req_intf, cmd_sta_set_pwrsave);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013516 sigma_dut_reg_cmd("sta_bssid_pool", req_intf, cmd_sta_bssid_pool);
13517 sigma_dut_reg_cmd("sta_reset_parm", req_intf, cmd_sta_reset_parm);
13518 sigma_dut_reg_cmd("sta_get_key", req_intf, cmd_sta_get_key);
13519 sigma_dut_reg_cmd("sta_hs2_associate", req_intf,
13520 cmd_sta_hs2_associate);
Jouni Malinenb639f1c2018-09-13 02:39:46 +030013521 sigma_dut_reg_cmd("sta_hs2_venue_info", req_intf,
13522 cmd_sta_hs2_venue_info);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013523 sigma_dut_reg_cmd("sta_add_credential", req_intf,
13524 cmd_sta_add_credential);
13525 sigma_dut_reg_cmd("sta_scan", req_intf, cmd_sta_scan);
Jouni Malinen5e5d43d2018-01-10 17:29:33 +020013526 sigma_dut_reg_cmd("sta_scan_bss", req_intf, cmd_sta_scan_bss);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013527 sigma_dut_reg_cmd("sta_set_systime", NULL, cmd_sta_set_systime);
13528 sigma_dut_reg_cmd("sta_osu", req_intf, cmd_sta_osu);
13529 sigma_dut_reg_cmd("sta_policy_update", req_intf, cmd_sta_policy_update);
13530 sigma_dut_reg_cmd("sta_er_config", NULL, cmd_sta_er_config);
13531 sigma_dut_reg_cmd("sta_wps_connect_pw_token", req_intf,
13532 cmd_sta_wps_connect_pw_token);
Jouni Malinen82905202018-04-29 17:20:10 +030013533 sigma_dut_reg_cmd("sta_exec_action", NULL, cmd_sta_exec_action);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013534 sigma_dut_reg_cmd("sta_get_events", req_intf, cmd_sta_get_events);
13535 sigma_dut_reg_cmd("sta_get_parameter", req_intf, cmd_sta_get_parameter);
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020013536 sigma_dut_reg_cmd("start_wps_registration", NULL,
vamsi krishna9b144002017-09-20 13:28:13 +053013537 cmd_start_wps_registration);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013538}