blob: 45d402e147e1962c7f1298020d400cd70f250b6a [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>
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014#ifdef __linux__
Lior Davidcc88b562017-01-03 18:52:09 +020015#include <regex.h>
16#include <dirent.h>
Jouni Malinencd4e3c32015-10-29 12:39:56 +020017#include <sys/time.h>
18#include <netpacket/packet.h>
19#include <linux/if_ether.h>
20#ifdef ANDROID
21#include <cutils/properties.h>
22#include <android/log.h>
23#include "keystore_get.h"
24#else /* ANDROID */
25#include <ifaddrs.h>
26#endif /* ANDROID */
27#include <netdb.h>
28#endif /* __linux__ */
29#ifdef __QNXNTO__
30#include <net/if_dl.h>
31#endif /* __QNXNTO__ */
32#include "wpa_ctrl.h"
33#include "wpa_helpers.h"
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -070034#include "miracast.h"
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -070035#include "qca-vendor_copy.h"
Jouni Malinencd4e3c32015-10-29 12:39:56 +020036
37/* Temporary files for sta_send_addba */
38#define VI_QOS_TMP_FILE "/tmp/vi-qos.tmp"
39#define VI_QOS_FILE "/tmp/vi-qos.txt"
40#define VI_QOS_REFFILE "/etc/vi-qos.txt"
41
42/*
43 * MTU for Ethernet need to take into account 8-byte SNAP header
44 * to be added when encapsulating Ethernet frame into 802.11
45 */
46#ifndef IEEE80211_MAX_DATA_LEN_DMG
47#define IEEE80211_MAX_DATA_LEN_DMG 7920
48#endif
49#ifndef IEEE80211_SNAP_LEN_DMG
50#define IEEE80211_SNAP_LEN_DMG 8
51#endif
52
Ashwini Patil00402582017-04-13 12:29:39 +053053#define NON_PREF_CH_LIST_SIZE 100
Ashwini Patil5acd7382017-04-13 15:55:04 +053054#define NEIGHBOR_REPORT_SIZE 1000
55#define DEFAULT_NEIGHBOR_BSSID_INFO "17"
56#define DEFAULT_NEIGHBOR_PHY_TYPE "1"
Ashwini Patil00402582017-04-13 12:29:39 +053057
Jouni Malinencd4e3c32015-10-29 12:39:56 +020058extern char *sigma_wpas_ctrl;
59extern char *sigma_cert_path;
60extern enum driver_type wifi_chip_type;
61extern char *sigma_radio_ifname[];
62
Lior David0fe101e2017-03-09 16:09:50 +020063#ifdef __linux__
64#define WIL_WMI_MAX_PAYLOAD 248
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020065#define WIL_WMI_ESE_CFG_CMDID 0xa01
Lior David0fe101e2017-03-09 16:09:50 +020066#define WIL_WMI_BF_TRIG_CMDID 0x83a
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020067#define WIL_WMI_UNIT_TEST_CMDID 0x900
Lior David0fe101e2017-03-09 16:09:50 +020068
69struct wil_wmi_header {
70 uint8_t mid;
71 uint8_t reserved;
72 uint16_t cmd;
73 uint32_t ts;
74} __attribute__((packed));
75
76enum wil_wmi_bf_trig_type {
77 WIL_WMI_SLS,
78 WIL_WMI_BRP_RX,
79 WIL_WMI_BRP_TX,
80};
81
82struct wil_wmi_bf_trig_cmd {
83 /* enum wil_wmi_bf_trig_type */
84 uint32_t bf_type;
85 /* cid when type == WMI_BRP_RX */
86 uint32_t sta_id;
87 uint32_t reserved;
88 /* mac address when type = WIL_WMI_SLS */
89 uint8_t dest_mac[6];
90} __attribute__((packed));
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020091
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020092enum wil_wmi_sched_scheme_advertisment {
93 WIL_WMI_ADVERTISE_ESE_DISABLED,
94 WIL_WMI_ADVERTISE_ESE_IN_BEACON,
95 WIL_WMI_ADVERTISE_ESE_IN_ANNOUNCE_FRAME,
96};
97
98enum wil_wmi_ese_slot_type {
99 WIL_WMI_ESE_SP,
100 WIL_WMI_ESE_CBAP,
101 WIL_WMI_ESE_ANNOUNCE_NO_ACK,
102};
103
104struct wil_wmi_ese_slot {
105 /* offset from start of BI in microseconds */
106 uint32_t tbtt_offset;
107 uint8_t flags;
108 /* enum wil_wmi_ese_slot_type */
109 uint8_t slot_type;
110 /* duration in microseconds */
111 uint16_t duration;
112 /* frame exchange sequence duration, microseconds */
113 uint16_t tx_op;
114 /* time between 2 blocks for periodic allocation(microseconds) */
115 uint16_t period;
116 /* number of blocks in periodic allocation */
117 uint8_t num_blocks;
118 /* for semi-active allocations */
119 uint8_t idle_period;
120 uint8_t src_aid;
121 uint8_t dst_aid;
122 uint32_t reserved;
123} __attribute__((packed));
124
125#define WIL_WMI_MAX_ESE_SLOTS 4
126struct wil_wmi_ese_cfg {
127 uint8_t serial_num;
128 /* wil_wmi_sched_scheme_advertisment */
129 uint8_t ese_advertisment;
130 uint16_t flags;
131 uint8_t num_allocs;
132 uint8_t reserved[3];
133 uint64_t start_tbtt;
134 /* allocations list */
135 struct wil_wmi_ese_slot slots[WIL_WMI_MAX_ESE_SLOTS];
136} __attribute__((packed));
137
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +0200138#define WIL_WMI_UT_FORCE_MCS 6
139struct wil_wmi_force_mcs {
140 /* WIL_WMI_UT_HW_SYSAPI */
141 uint16_t module_id;
142 /* WIL_WMI_UT_FORCE_MCS */
143 uint16_t subtype_id;
144 /* cid (ignored in oob_mode, affects all stations) */
145 uint32_t cid;
146 /* 1 to force MCS, 0 to restore default behavior */
147 uint32_t force_enable;
148 /* MCS index, 0-12 */
149 uint32_t mcs;
150} __attribute__((packed));
151
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +0200152#define WIL_WMI_UT_HW_SYSAPI 10
153#define WIL_WMI_UT_FORCE_RSN_IE 0x29
154struct wil_wmi_force_rsn_ie {
155 /* WIL_WMI_UT_HW_SYSAPI */
156 uint16_t module_id;
157 /* WIL_WMI_UT_FORCE_RSN_IE */
158 uint16_t subtype_id;
159 /* 0 = no change, 1 = remove if exists, 2 = add if does not exist */
160 uint32_t state;
161} __attribute__((packed));
Lior David0fe101e2017-03-09 16:09:50 +0200162#endif /* __linux__ */
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200163
164#ifdef ANDROID
165
166static int add_ipv6_rule(struct sigma_dut *dut, const char *ifname);
167
168#define ANDROID_KEYSTORE_GET 'g'
169#define ANDROID_KEYSTORE_GET_PUBKEY 'b'
170
171static int android_keystore_get(char cmd, const char *key, unsigned char *val)
172{
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200173 /* Android 4.3 changed keystore design, so need to use keystore_get() */
174#ifndef KEYSTORE_MESSAGE_SIZE
175#define KEYSTORE_MESSAGE_SIZE 65535
176#endif /* KEYSTORE_MESSAGE_SIZE */
177
178 ssize_t len;
179 uint8_t *value = NULL;
180
181 __android_log_print(ANDROID_LOG_DEBUG, "sigma_dut",
182 "keystore command '%c' key '%s' --> keystore_get",
183 cmd, key);
184
185 len = keystore_get(key, strlen(key), &value);
186 if (len < 0) {
187 __android_log_print(ANDROID_LOG_DEBUG, "sigma_dut",
188 "keystore_get() failed");
189 return -1;
190 }
191
192 if (len > KEYSTORE_MESSAGE_SIZE)
193 len = KEYSTORE_MESSAGE_SIZE;
194 memcpy(val, value, len);
195 free(value);
196 return len;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200197}
198#endif /* ANDROID */
199
200
201int set_ps(const char *intf, struct sigma_dut *dut, int enabled)
202{
203#ifdef __linux__
204 char buf[100];
205
206 if (wifi_chip_type == DRIVER_WCN) {
207 if (enabled) {
208 snprintf(buf, sizeof(buf), "iwpriv wlan0 dump 906");
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530209 if (system(buf) != 0)
210 goto set_power_save;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200211 } else {
212 snprintf(buf, sizeof(buf), "iwpriv wlan0 dump 905");
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530213 if (system(buf) != 0)
214 goto set_power_save;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200215 snprintf(buf, sizeof(buf), "iwpriv wlan0 dump 912");
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530216 if (system(buf) != 0)
217 goto set_power_save;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200218 }
219
220 return 0;
221 }
222
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530223set_power_save:
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200224 snprintf(buf, sizeof(buf), "./iw dev %s set power_save %s",
225 intf, enabled ? "on" : "off");
226 if (system(buf) != 0) {
227 snprintf(buf, sizeof(buf), "iw dev %s set power_save %s",
228 intf, enabled ? "on" : "off");
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530229 if (system(buf) != 0) {
230 sigma_dut_print(dut, DUT_MSG_ERROR,
231 "Failed to set power save %s",
232 enabled ? "on" : "off");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200233 return -1;
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530234 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200235 }
236
237 return 0;
238#else /* __linux__ */
239 return -1;
240#endif /* __linux__ */
241}
242
243
Lior Davidcc88b562017-01-03 18:52:09 +0200244#ifdef __linux__
Lior David0fe101e2017-03-09 16:09:50 +0200245
Lior Davidcc88b562017-01-03 18:52:09 +0200246static int wil6210_get_debugfs_dir(struct sigma_dut *dut, char *path,
247 size_t len)
248{
249 DIR *dir, *wil_dir;
250 struct dirent *entry;
251 int ret = -1;
252 const char *root_path = "/sys/kernel/debug/ieee80211";
253
254 dir = opendir(root_path);
255 if (!dir)
256 return -2;
257
258 while ((entry = readdir(dir))) {
259 if (strcmp(entry->d_name, ".") == 0 ||
260 strcmp(entry->d_name, "..") == 0)
261 continue;
262
263 if (snprintf(path, len, "%s/%s/wil6210",
264 root_path, entry->d_name) >= (int) len) {
265 ret = -3;
266 break;
267 }
268
269 wil_dir = opendir(path);
270 if (wil_dir) {
271 closedir(wil_dir);
272 ret = 0;
273 break;
274 }
275 }
276
277 closedir(dir);
278 return ret;
279}
Lior David0fe101e2017-03-09 16:09:50 +0200280
281
282static int wil6210_wmi_send(struct sigma_dut *dut, uint16_t command,
283 void *payload, uint16_t length)
284{
285 struct {
286 struct wil_wmi_header hdr;
287 char payload[WIL_WMI_MAX_PAYLOAD];
288 } __attribute__((packed)) cmd;
289 char buf[128], fname[128];
290 size_t towrite, written;
291 FILE *f;
292
293 if (length > WIL_WMI_MAX_PAYLOAD) {
294 sigma_dut_print(dut, DUT_MSG_ERROR,
295 "payload too large(%u, max %u)",
296 length, WIL_WMI_MAX_PAYLOAD);
297 return -1;
298 }
299
300 memset(&cmd.hdr, 0, sizeof(cmd.hdr));
301 cmd.hdr.cmd = command;
302 memcpy(cmd.payload, payload, length);
303
304 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
305 sigma_dut_print(dut, DUT_MSG_ERROR,
306 "failed to get wil6210 debugfs dir");
307 return -1;
308 }
309
310 snprintf(fname, sizeof(fname), "%s/wmi_send", buf);
311 f = fopen(fname, "wb");
312 if (!f) {
313 sigma_dut_print(dut, DUT_MSG_ERROR,
314 "failed to open: %s", fname);
315 return -1;
316 }
317
318 towrite = sizeof(cmd.hdr) + length;
319 written = fwrite(&cmd, 1, towrite, f);
320 fclose(f);
321 if (written != towrite) {
322 sigma_dut_print(dut, DUT_MSG_ERROR,
323 "failed to send wmi %u", command);
324 return -1;
325 }
326
327 return 0;
328}
329
330
331static int wil6210_get_sta_info_field(struct sigma_dut *dut, const char *bssid,
332 const char *pattern, unsigned int *field)
333{
334 char buf[128], fname[128];
335 FILE *f;
336 regex_t re;
337 regmatch_t m[2];
338 int rc, ret = -1;
339
340 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
341 sigma_dut_print(dut, DUT_MSG_ERROR,
342 "failed to get wil6210 debugfs dir");
343 return -1;
344 }
345
346 snprintf(fname, sizeof(fname), "%s/stations", buf);
347 f = fopen(fname, "r");
348 if (!f) {
349 sigma_dut_print(dut, DUT_MSG_ERROR,
350 "failed to open: %s", fname);
351 return -1;
352 }
353
354 if (regcomp(&re, pattern, REG_EXTENDED)) {
355 sigma_dut_print(dut, DUT_MSG_ERROR,
356 "regcomp failed: %s", pattern);
357 goto out;
358 }
359
360 /*
361 * find the entry for the mac address
362 * line is of the form: [n] 11:22:33:44:55:66 state AID aid
363 */
364 while (fgets(buf, sizeof(buf), f)) {
365 if (strcasestr(buf, bssid)) {
366 /* extract the field (CID/AID/state) */
367 rc = regexec(&re, buf, 2, m, 0);
368 if (!rc && (m[1].rm_so >= 0)) {
369 buf[m[1].rm_eo] = 0;
370 *field = atoi(&buf[m[1].rm_so]);
371 ret = 0;
372 break;
373 }
374 }
375 }
376
377 regfree(&re);
378 if (ret)
379 sigma_dut_print(dut, DUT_MSG_ERROR,
380 "could not extract field");
381
382out:
383 fclose(f);
384
385 return ret;
386}
387
388
389static int wil6210_get_cid(struct sigma_dut *dut, const char *bssid,
390 unsigned int *cid)
391{
392 const char *pattern = "\\[([0-9]+)\\]";
393
394 return wil6210_get_sta_info_field(dut, bssid, pattern, cid);
395}
396
397
398static int wil6210_send_brp_rx(struct sigma_dut *dut, const char *mac,
399 int l_rx)
400{
Rakesh Sunki556237d2017-03-30 14:49:31 -0700401 struct wil_wmi_bf_trig_cmd cmd;
Lior David0fe101e2017-03-09 16:09:50 +0200402 unsigned int cid;
403
Rakesh Sunki556237d2017-03-30 14:49:31 -0700404 memset(&cmd, 0, sizeof(cmd));
405
Lior David0fe101e2017-03-09 16:09:50 +0200406 if (wil6210_get_cid(dut, mac, &cid))
407 return -1;
408
409 cmd.bf_type = WIL_WMI_BRP_RX;
410 cmd.sta_id = cid;
411 /* training length (l_rx) is ignored, FW always uses length 16 */
412 return wil6210_wmi_send(dut, WIL_WMI_BF_TRIG_CMDID,
413 &cmd, sizeof(cmd));
414}
415
416
417static int wil6210_send_sls(struct sigma_dut *dut, const char *mac)
418{
Rakesh Sunki556237d2017-03-30 14:49:31 -0700419 struct wil_wmi_bf_trig_cmd cmd;
420
421 memset(&cmd, 0, sizeof(cmd));
Lior David0fe101e2017-03-09 16:09:50 +0200422
423 if (parse_mac_address(dut, mac, (unsigned char *)&cmd.dest_mac))
424 return -1;
425
426 cmd.bf_type = WIL_WMI_SLS;
427 return wil6210_wmi_send(dut, WIL_WMI_BF_TRIG_CMDID,
428 &cmd, sizeof(cmd));
429}
430
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +0200431
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +0200432int wil6210_set_ese(struct sigma_dut *dut, int count,
433 struct sigma_ese_alloc *allocs)
434{
435 struct wil_wmi_ese_cfg cmd = { };
436 int i;
437
438 if (count == 0 || count > WIL_WMI_MAX_ESE_SLOTS)
439 return -1;
440
441 if (dut->ap_bcnint <= 0) {
442 sigma_dut_print(dut, DUT_MSG_ERROR,
443 "invalid beacon interval(%d), check test",
444 dut->ap_bcnint);
445 return -1;
446 }
447
448 cmd.ese_advertisment = WIL_WMI_ADVERTISE_ESE_IN_BEACON;
449 cmd.flags = 0x1d;
450 cmd.num_allocs = count;
451 for (i = 0; i < count; i++) {
452 /*
453 * Convert percent from BI (BI specified in milliseconds)
454 * to absolute duration in microseconds.
455 */
456 cmd.slots[i].duration =
457 (allocs[i].percent_bi * dut->ap_bcnint * 1000) / 100;
458 switch (allocs[i].type) {
459 case ESE_CBAP:
460 cmd.slots[i].slot_type = WIL_WMI_ESE_CBAP;
461 break;
462 case ESE_SP:
463 cmd.slots[i].slot_type = WIL_WMI_ESE_SP;
464 break;
465 default:
466 sigma_dut_print(dut, DUT_MSG_ERROR,
467 "invalid slot type(%d) at index %d",
468 allocs[i].type, i);
469 return -1;
470 }
471 cmd.slots[i].src_aid = allocs[i].src_aid;
472 cmd.slots[i].dst_aid = allocs[i].dst_aid;
473 sigma_dut_print(dut, DUT_MSG_INFO,
474 "slot %d, duration %u, type %d, srcAID %u dstAID %u",
475 i, cmd.slots[i].duration,
476 cmd.slots[i].slot_type, cmd.slots[i].src_aid,
477 cmd.slots[i].dst_aid);
478 }
479
480 return wil6210_wmi_send(dut, WIL_WMI_ESE_CFG_CMDID, &cmd, sizeof(cmd));
481}
482
483
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +0200484int wil6210_set_force_mcs(struct sigma_dut *dut, int force, int mcs)
485{
486 struct wil_wmi_force_mcs cmd = { };
487
488 cmd.module_id = WIL_WMI_UT_HW_SYSAPI;
489 cmd.subtype_id = WIL_WMI_UT_FORCE_MCS;
490 cmd.force_enable = (uint32_t) force;
491 cmd.mcs = (uint32_t) mcs;
492
493 return wil6210_wmi_send(dut, WIL_WMI_UNIT_TEST_CMDID,
494 &cmd, sizeof(cmd));
495}
496
497
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +0200498static int wil6210_force_rsn_ie(struct sigma_dut *dut, int state)
499{
500 struct wil_wmi_force_rsn_ie cmd = { };
501
502 cmd.module_id = WIL_WMI_UT_HW_SYSAPI;
503 cmd.subtype_id = WIL_WMI_UT_FORCE_RSN_IE;
504 cmd.state = (uint32_t) state;
505
506 return wil6210_wmi_send(dut, WIL_WMI_UNIT_TEST_CMDID,
507 &cmd, sizeof(cmd));
508}
509
Lior Davidcc88b562017-01-03 18:52:09 +0200510#endif /* __linux__ */
511
512
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200513static void static_ip_file(int proto, const char *addr, const char *mask,
514 const char *gw)
515{
516 if (proto) {
517 FILE *f = fopen("static-ip", "w");
518 if (f) {
519 fprintf(f, "%d %s %s %s\n", proto, addr,
520 mask ? mask : "N/A",
521 gw ? gw : "N/A");
522 fclose(f);
523 }
524 } else {
525 unlink("static-ip");
526 }
527}
528
529
530static int send_neighbor_request(struct sigma_dut *dut, const char *intf,
531 const char *ssid)
532{
533#ifdef __linux__
534 char buf[100];
535
536 snprintf(buf, sizeof(buf), "iwpriv %s neighbor %s",
537 intf, ssid);
538 sigma_dut_print(dut, DUT_MSG_INFO, "Request: %s", buf);
539
540 if (system(buf) != 0) {
541 sigma_dut_print(dut, DUT_MSG_ERROR,
542 "iwpriv neighbor request failed");
543 return -1;
544 }
545
546 sigma_dut_print(dut, DUT_MSG_INFO, "iwpriv neighbor request send");
547
548 return 0;
549#else /* __linux__ */
550 return -1;
551#endif /* __linux__ */
552}
553
554
555static int send_trans_mgmt_query(struct sigma_dut *dut, const char *intf,
Ashwini Patil5acd7382017-04-13 15:55:04 +0530556 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200557{
Ashwini Patil5acd7382017-04-13 15:55:04 +0530558 const char *val;
559 int reason_code = 0;
560 char buf[1024];
561
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200562 /*
563 * In the earlier builds we used WNM_QUERY and in later
564 * builds used WNM_BSS_QUERY.
565 */
566
Ashwini Patil5acd7382017-04-13 15:55:04 +0530567 val = get_param(cmd, "BTMQuery_Reason_Code");
568 if (val)
569 reason_code = atoi(val);
570
571 val = get_param(cmd, "Cand_List");
572 if (val && atoi(val) == 1 && dut->btm_query_cand_list) {
573 snprintf(buf, sizeof(buf), "WNM_BSS_QUERY %d%s", reason_code,
574 dut->btm_query_cand_list);
575 free(dut->btm_query_cand_list);
576 dut->btm_query_cand_list = NULL;
577 } else {
578 snprintf(buf, sizeof(buf), "WNM_BSS_QUERY %d", reason_code);
579 }
580
581 if (wpa_command(intf, buf) != 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200582 sigma_dut_print(dut, DUT_MSG_ERROR,
583 "transition management query failed");
584 return -1;
585 }
586
587 sigma_dut_print(dut, DUT_MSG_DEBUG,
588 "transition management query sent");
589
590 return 0;
591}
592
593
594int is_ip_addr(const char *str)
595{
596 const char *pos = str;
597 struct in_addr addr;
598
599 while (*pos) {
600 if (*pos != '.' && (*pos < '0' || *pos > '9'))
601 return 0;
602 pos++;
603 }
604
605 return inet_aton(str, &addr);
606}
607
608
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200609int get_ip_config(struct sigma_dut *dut, const char *ifname, char *buf,
610 size_t buf_len)
611{
vamsi krishnaa11d0732018-05-16 12:19:48 +0530612 char tmp[256];
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200613 char ip[16], mask[15], dns[16], sec_dns[16];
614 int is_dhcp = 0;
615 int s;
616#ifdef ANDROID
617 char prop[PROPERTY_VALUE_MAX];
vamsi krishnaa11d0732018-05-16 12:19:48 +0530618#else /* ANDROID */
619 FILE *f;
620#ifdef __linux__
621 const char *str_ps;
622#endif /* __linux__ */
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200623#endif /* ANDROID */
624
625 ip[0] = '\0';
626 mask[0] = '\0';
627 dns[0] = '\0';
628 sec_dns[0] = '\0';
629
630 s = socket(PF_INET, SOCK_DGRAM, 0);
631 if (s >= 0) {
632 struct ifreq ifr;
633 struct sockaddr_in saddr;
634
635 memset(&ifr, 0, sizeof(ifr));
Peng Xub8fc5cc2017-05-10 17:27:28 -0700636 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200637 if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
638 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to get "
639 "%s IP address: %s",
640 ifname, strerror(errno));
641 } else {
642 memcpy(&saddr, &ifr.ifr_addr,
643 sizeof(struct sockaddr_in));
Peng Xub8fc5cc2017-05-10 17:27:28 -0700644 strlcpy(ip, inet_ntoa(saddr.sin_addr), sizeof(ip));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200645 }
646
647 if (ioctl(s, SIOCGIFNETMASK, &ifr) == 0) {
648 memcpy(&saddr, &ifr.ifr_addr,
649 sizeof(struct sockaddr_in));
Peng Xub8fc5cc2017-05-10 17:27:28 -0700650 strlcpy(mask, inet_ntoa(saddr.sin_addr), sizeof(mask));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200651 }
652 close(s);
653 }
654
655#ifdef ANDROID
656 snprintf(tmp, sizeof(tmp), "dhcp.%s.pid", ifname);
657 if (property_get(tmp, prop, NULL) != 0 && atoi(prop) > 0) {
658 snprintf(tmp, sizeof(tmp), "dhcp.%s.result", ifname);
659 if (property_get(tmp, prop, NULL) != 0 &&
660 strcmp(prop, "ok") == 0) {
661 snprintf(tmp, sizeof(tmp), "dhcp.%s.ipaddress",
662 ifname);
663 if (property_get(tmp, prop, NULL) != 0 &&
664 strcmp(ip, prop) == 0)
665 is_dhcp = 1;
666 }
667 }
668
669 snprintf(tmp, sizeof(tmp), "dhcp.%s.dns1", ifname);
Peng Xub8fc5cc2017-05-10 17:27:28 -0700670 if (property_get(tmp, prop, NULL) != 0)
671 strlcpy(dns, prop, sizeof(dns));
672 else if (property_get("net.dns1", prop, NULL) != 0)
673 strlcpy(dns, prop, sizeof(dns));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200674
675 snprintf(tmp, sizeof(tmp), "dhcp.%s.dns2", ifname);
Peng Xub8fc5cc2017-05-10 17:27:28 -0700676 if (property_get(tmp, prop, NULL) != 0)
677 strlcpy(sec_dns, prop, sizeof(sec_dns));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200678#else /* ANDROID */
679#ifdef __linux__
Sarvepalli, Rajesh Babua76c6442016-03-18 20:34:26 +0530680 if (get_driver_type() == DRIVER_OPENWRT)
681 str_ps = "ps -w";
682 else
683 str_ps = "ps ax";
684 snprintf(tmp, sizeof(tmp),
685 "%s | grep dhclient | grep -v grep | grep -q %s",
686 str_ps, ifname);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200687 if (system(tmp) == 0)
688 is_dhcp = 1;
689 else {
Sarvepalli, Rajesh Babua76c6442016-03-18 20:34:26 +0530690 snprintf(tmp, sizeof(tmp),
691 "%s | grep udhcpc | grep -v grep | grep -q %s",
692 str_ps, ifname);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200693 if (system(tmp) == 0)
694 is_dhcp = 1;
695 else {
Sarvepalli, Rajesh Babua76c6442016-03-18 20:34:26 +0530696 snprintf(tmp, sizeof(tmp),
697 "%s | grep dhcpcd | grep -v grep | grep -q %s",
698 str_ps, ifname);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200699 if (system(tmp) == 0)
700 is_dhcp = 1;
701 }
702 }
703#endif /* __linux__ */
704
705 f = fopen("/etc/resolv.conf", "r");
706 if (f) {
vamsi krishnaa11d0732018-05-16 12:19:48 +0530707 char *pos, *pos2;
708
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200709 while (fgets(tmp, sizeof(tmp), f)) {
710 if (strncmp(tmp, "nameserver", 10) != 0)
711 continue;
712 pos = tmp + 10;
713 while (*pos == ' ' || *pos == '\t')
714 pos++;
715 pos2 = pos;
716 while (*pos2) {
717 if (*pos2 == '\n' || *pos2 == '\r') {
718 *pos2 = '\0';
719 break;
720 }
721 pos2++;
722 }
Peng Xub8fc5cc2017-05-10 17:27:28 -0700723 if (!dns[0])
724 strlcpy(dns, pos, sizeof(dns));
725 else if (!sec_dns[0])
726 strlcpy(sec_dns, pos, sizeof(sec_dns));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200727 }
728 fclose(f);
729 }
730#endif /* ANDROID */
731
732 snprintf(buf, buf_len, "dhcp,%d,ip,%s,mask,%s,primary-dns,%s",
733 is_dhcp, ip, mask, dns);
734 buf[buf_len - 1] = '\0';
735
736 return 0;
737}
738
739
740
741
742int get_ipv6_config(struct sigma_dut *dut, const char *ifname, char *buf,
743 size_t buf_len)
744{
745#ifdef __linux__
746#ifdef ANDROID
747 char cmd[200], result[1000], *pos, *end;
748 FILE *f;
749 size_t len;
750
751 snprintf(cmd, sizeof(cmd), "ip addr show dev %s scope global", ifname);
752 f = popen(cmd, "r");
753 if (f == NULL)
754 return -1;
755 len = fread(result, 1, sizeof(result) - 1, f);
756 pclose(f);
757 if (len == 0)
758 return -1;
759 result[len] = '\0';
760 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s result: %s\n", cmd, result);
761
762 pos = strstr(result, "inet6 ");
763 if (pos == NULL)
764 return -1;
765 pos += 6;
766 end = strchr(pos, ' ');
767 if (end)
768 *end = '\0';
769 end = strchr(pos, '/');
770 if (end)
771 *end = '\0';
772 snprintf(buf, buf_len, "ip,%s", pos);
773 buf[buf_len - 1] = '\0';
774 return 0;
775#else /* ANDROID */
776 struct ifaddrs *ifaddr, *ifa;
777 int res, found = 0;
778 char host[NI_MAXHOST];
779
780 if (getifaddrs(&ifaddr) < 0) {
781 perror("getifaddrs");
782 return -1;
783 }
784
785 for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
786 if (strcasecmp(ifname, ifa->ifa_name) != 0)
787 continue;
788 if (ifa->ifa_addr == NULL ||
789 ifa->ifa_addr->sa_family != AF_INET6)
790 continue;
791
792 res = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in6),
793 host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
794 if (res != 0) {
795 sigma_dut_print(dut, DUT_MSG_DEBUG, "getnameinfo: %s",
796 gai_strerror(res));
797 continue;
798 }
799 if (strncmp(host, "fe80::", 6) == 0)
800 continue; /* skip link-local */
801
802 sigma_dut_print(dut, DUT_MSG_DEBUG, "ifaddr: %s", host);
803 found = 1;
804 break;
805 }
806
807 freeifaddrs(ifaddr);
808
809 if (found) {
810 char *pos;
811 pos = strchr(host, '%');
812 if (pos)
813 *pos = '\0';
814 snprintf(buf, buf_len, "ip,%s", host);
815 buf[buf_len - 1] = '\0';
816 return 0;
817 }
818
819#endif /* ANDROID */
820#endif /* __linux__ */
821 return -1;
822}
823
824
825static int cmd_sta_get_ip_config(struct sigma_dut *dut,
826 struct sigma_conn *conn,
827 struct sigma_cmd *cmd)
828{
829 const char *intf = get_param(cmd, "Interface");
830 const char *ifname;
831 char buf[200];
832 const char *val;
833 int type = 1;
834
835 if (intf == NULL)
836 return -1;
837
838 if (strcmp(intf, get_main_ifname()) == 0)
839 ifname = get_station_ifname();
840 else
841 ifname = intf;
842
843 /*
844 * UCC may assume the IP address to be available immediately after
845 * association without trying to run sta_get_ip_config multiple times.
846 * Sigma CAPI does not specify this command as a block command that
847 * would wait for the address to become available, but to pass tests
848 * more reliably, it looks like such a wait may be needed here.
849 */
850 if (wait_ip_addr(dut, ifname, 15) < 0) {
851 sigma_dut_print(dut, DUT_MSG_INFO, "Could not get IP address "
852 "for sta_get_ip_config");
853 /*
854 * Try to continue anyway since many UCC tests do not really
855 * care about the return value from here..
856 */
857 }
858
859 val = get_param(cmd, "Type");
860 if (val)
861 type = atoi(val);
862 if (type == 2 || dut->last_set_ip_config_ipv6) {
863 int i;
864
865 /*
866 * Since we do not have proper wait for IPv6 addresses, use a
867 * fixed two second delay here as a workaround for UCC script
868 * assuming IPv6 address is available when this command returns.
869 * Some scripts did not use Type,2 properly for IPv6, so include
870 * also the cases where the previous sta_set_ip_config indicated
871 * use of IPv6.
872 */
873 sigma_dut_print(dut, DUT_MSG_INFO, "Wait up to extra ten seconds in sta_get_ip_config for IPv6 address");
874 for (i = 0; i < 10; i++) {
875 sleep(1);
876 if (get_ipv6_config(dut, ifname, buf, sizeof(buf)) == 0)
877 {
878 sigma_dut_print(dut, DUT_MSG_INFO, "Found IPv6 address");
879 send_resp(dut, conn, SIGMA_COMPLETE, buf);
880#ifdef ANDROID
881 sigma_dut_print(dut, DUT_MSG_INFO,
882 "Adding IPv6 rule on Android");
883 add_ipv6_rule(dut, intf);
884#endif /* ANDROID */
885
886 return 0;
887 }
888 }
889 }
890 if (type == 1) {
891 if (get_ip_config(dut, ifname, buf, sizeof(buf)) < 0)
892 return -2;
893 } else if (type == 2) {
894 if (get_ipv6_config(dut, ifname, buf, sizeof(buf)) < 0)
895 return -2;
896 } else {
897 send_resp(dut, conn, SIGMA_ERROR,
898 "errorCode,Unsupported address type");
899 return 0;
900 }
901
902 send_resp(dut, conn, SIGMA_COMPLETE, buf);
903 return 0;
904}
905
906
907static void kill_dhcp_client(struct sigma_dut *dut, const char *ifname)
908{
909#ifdef __linux__
910 char buf[200];
911 char path[128];
912 struct stat s;
913
914#ifdef ANDROID
915 snprintf(path, sizeof(path), "/data/misc/dhcp/dhcpcd-%s.pid", ifname);
916#else /* ANDROID */
917 snprintf(path, sizeof(path), "/var/run/dhclient-%s.pid", ifname);
918#endif /* ANDROID */
919 if (stat(path, &s) == 0) {
920 snprintf(buf, sizeof(buf), "kill `cat %s`", path);
921 sigma_dut_print(dut, DUT_MSG_INFO,
922 "Kill previous DHCP client: %s", buf);
923 if (system(buf) != 0)
924 sigma_dut_print(dut, DUT_MSG_INFO,
925 "Failed to kill DHCP client");
926 unlink(path);
927 sleep(1);
928 } else {
929 snprintf(path, sizeof(path), "/var/run/dhcpcd-%s.pid", ifname);
930
931 if (stat(path, &s) == 0) {
932 snprintf(buf, sizeof(buf), "kill `cat %s`", path);
933 sigma_dut_print(dut, DUT_MSG_INFO,
934 "Kill previous DHCP client: %s", buf);
935 if (system(buf) != 0)
936 sigma_dut_print(dut, DUT_MSG_INFO,
937 "Failed to kill DHCP client");
938 unlink(path);
939 sleep(1);
940 }
941 }
942#endif /* __linux__ */
943}
944
945
946static int start_dhcp_client(struct sigma_dut *dut, const char *ifname)
947{
948#ifdef __linux__
949 char buf[200];
950
951#ifdef ANDROID
Purushottam Kushwaha46d64262016-08-23 17:57:53 +0530952 if (access("/system/bin/dhcpcd", F_OK) != -1) {
953 snprintf(buf, sizeof(buf),
954 "/system/bin/dhcpcd -b %s", ifname);
955 } else if (access("/system/bin/dhcptool", F_OK) != -1) {
956 snprintf(buf, sizeof(buf), "/system/bin/dhcptool %s &", ifname);
957 } else {
958 sigma_dut_print(dut, DUT_MSG_ERROR,
959 "DHCP client program missing");
960 return 0;
961 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200962#else /* ANDROID */
963 snprintf(buf, sizeof(buf),
964 "dhclient -nw -pf /var/run/dhclient-%s.pid %s",
965 ifname, ifname);
966#endif /* ANDROID */
967 sigma_dut_print(dut, DUT_MSG_INFO, "Start DHCP client: %s", buf);
968 if (system(buf) != 0) {
969 snprintf(buf, sizeof(buf), "dhcpcd -t 0 %s &", ifname);
970 if (system(buf) != 0) {
971 sigma_dut_print(dut, DUT_MSG_INFO,
972 "Failed to start DHCP client");
973#ifndef ANDROID
974 return -1;
975#endif /* ANDROID */
976 }
977 }
978#endif /* __linux__ */
979
980 return 0;
981}
982
983
984static int clear_ip_addr(struct sigma_dut *dut, const char *ifname)
985{
986#ifdef __linux__
987 char buf[200];
988
989 snprintf(buf, sizeof(buf), "ip addr flush dev %s", ifname);
990 if (system(buf) != 0) {
991 sigma_dut_print(dut, DUT_MSG_INFO,
992 "Failed to clear IP addresses");
993 return -1;
994 }
995#endif /* __linux__ */
996
997 return 0;
998}
999
1000
1001#ifdef ANDROID
1002static int add_ipv6_rule(struct sigma_dut *dut, const char *ifname)
1003{
1004 char cmd[200], *result, *pos;
1005 FILE *fp;
Pradeep Reddy POTTETIf58a1fe2016-10-13 17:22:03 +05301006 int tableid;
1007 size_t len, result_len = 1000;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001008
1009 snprintf(cmd, sizeof(cmd), "ip -6 route list table all | grep %s",
1010 ifname);
1011 fp = popen(cmd, "r");
1012 if (fp == NULL)
1013 return -1;
1014
1015 result = malloc(result_len);
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05301016 if (result == NULL) {
1017 fclose(fp);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001018 return -1;
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05301019 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001020
Pradeep Reddy POTTETIf58a1fe2016-10-13 17:22:03 +05301021 len = fread(result, 1, result_len - 1, fp);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001022 fclose(fp);
1023
1024 if (len == 0) {
1025 free(result);
1026 return -1;
1027 }
Pradeep Reddy POTTETIf58a1fe2016-10-13 17:22:03 +05301028 result[len] = '\0';
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001029
1030 pos = strstr(result, "table ");
1031 if (pos == NULL) {
1032 free(result);
1033 return -1;
1034 }
1035
1036 pos += strlen("table ");
1037 tableid = atoi(pos);
1038 if (tableid != 0) {
1039 if (system("ip -6 rule del prio 22000") != 0) {
1040 /* ignore any error */
1041 }
1042 snprintf(cmd, sizeof(cmd),
1043 "ip -6 rule add from all lookup %d prio 22000",
1044 tableid);
1045 if (system(cmd) != 0) {
1046 sigma_dut_print(dut, DUT_MSG_INFO,
1047 "Failed to run %s", cmd);
1048 free(result);
1049 return -1;
1050 }
1051 } else {
1052 sigma_dut_print(dut, DUT_MSG_INFO,
1053 "No Valid Table Id found %s", pos);
1054 free(result);
1055 return -1;
1056 }
1057 free(result);
1058
1059 return 0;
1060}
1061#endif /* ANDROID */
1062
1063
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301064int set_ipv4_addr(struct sigma_dut *dut, const char *ifname,
1065 const char *ip, const char *mask)
1066{
1067 char buf[200];
1068
1069 snprintf(buf, sizeof(buf), "ifconfig %s %s netmask %s",
1070 ifname, ip, mask);
1071 return system(buf) == 0;
1072}
1073
1074
1075int set_ipv4_gw(struct sigma_dut *dut, const char *gw)
1076{
1077 char buf[200];
1078
1079 if (!is_ip_addr(gw)) {
1080 sigma_dut_print(dut, DUT_MSG_DEBUG, "Invalid gw addr - %s", gw);
1081 return -1;
1082 }
1083
1084 snprintf(buf, sizeof(buf), "route add default gw %s", gw);
1085 if (!dut->no_ip_addr_set && system(buf) != 0) {
1086 snprintf(buf, sizeof(buf), "ip ro re default via %s",
1087 gw);
1088 if (system(buf) != 0)
1089 return 0;
1090 }
1091
1092 return 1;
1093}
1094
1095
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001096static int cmd_sta_set_ip_config(struct sigma_dut *dut,
1097 struct sigma_conn *conn,
1098 struct sigma_cmd *cmd)
1099{
1100 const char *intf = get_param(cmd, "Interface");
1101 const char *ifname;
1102 char buf[200];
1103 const char *val, *ip, *mask, *gw;
1104 int type = 1;
1105
1106 if (intf == NULL)
1107 return -1;
1108
1109 if (strcmp(intf, get_main_ifname()) == 0)
1110 ifname = get_station_ifname();
1111 else
1112 ifname = intf;
1113
1114 if (if_nametoindex(ifname) == 0) {
1115 send_resp(dut, conn, SIGMA_ERROR,
1116 "ErrorCode,Unknown interface");
1117 return 0;
1118 }
1119
1120 val = get_param(cmd, "Type");
1121 if (val) {
1122 type = atoi(val);
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301123 if (type < 1 || type > 3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001124 send_resp(dut, conn, SIGMA_ERROR,
1125 "ErrorCode,Unsupported address type");
1126 return 0;
1127 }
1128 }
1129
1130 dut->last_set_ip_config_ipv6 = 0;
1131
1132 val = get_param(cmd, "dhcp");
1133 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "true") == 0)) {
1134 static_ip_file(0, NULL, NULL, NULL);
1135#ifdef __linux__
1136 if (type == 2) {
1137 dut->last_set_ip_config_ipv6 = 1;
1138 sigma_dut_print(dut, DUT_MSG_INFO, "Using IPv6 "
1139 "stateless address autoconfiguration");
1140#ifdef ANDROID
1141 /*
1142 * This sleep is required as the assignment in case of
1143 * Android is taking time and is done by the kernel.
1144 * The subsequent ping for IPv6 is impacting HS20 test
1145 * case.
1146 */
1147 sleep(2);
1148 add_ipv6_rule(dut, intf);
1149#endif /* ANDROID */
1150 /* Assume this happens by default */
1151 return 1;
1152 }
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301153 if (type != 3) {
1154 kill_dhcp_client(dut, ifname);
1155 if (start_dhcp_client(dut, ifname) < 0)
1156 return -2;
1157 } else {
1158 sigma_dut_print(dut, DUT_MSG_DEBUG,
1159 "Using FILS HLP DHCPv4 Rapid Commit");
1160 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001161
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001162 return 1;
1163#endif /* __linux__ */
1164 return -2;
1165 }
1166
1167 ip = get_param(cmd, "ip");
Pradeep Reddy POTTETIb18c5652016-01-18 12:45:37 +05301168 if (!ip) {
1169 send_resp(dut, conn, SIGMA_INVALID,
1170 "ErrorCode,Missing IP address");
1171 return 0;
1172 }
1173
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001174 mask = get_param(cmd, "mask");
Pradeep Reddy POTTETIb18c5652016-01-18 12:45:37 +05301175 if (!mask) {
1176 send_resp(dut, conn, SIGMA_INVALID,
1177 "ErrorCode,Missing subnet mask");
1178 return 0;
1179 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001180
1181 if (type == 2) {
1182 int net = atoi(mask);
1183
1184 if ((net < 0 && net > 64) || !is_ipv6_addr(ip))
1185 return -1;
1186
1187 if (dut->no_ip_addr_set) {
1188 snprintf(buf, sizeof(buf),
1189 "sysctl net.ipv6.conf.%s.disable_ipv6=1",
1190 ifname);
1191 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
1192 if (system(buf) != 0) {
1193 sigma_dut_print(dut, DUT_MSG_DEBUG,
1194 "Failed to disable IPv6 address before association");
1195 }
1196 } else {
1197 snprintf(buf, sizeof(buf),
1198 "ip -6 addr del %s/%s dev %s",
1199 ip, mask, ifname);
1200 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
1201 if (system(buf) != 0) {
1202 /*
1203 * This command may fail if the address being
1204 * deleted does not exist. Inaction here is
1205 * intentional.
1206 */
1207 }
1208
1209 snprintf(buf, sizeof(buf),
1210 "ip -6 addr add %s/%s dev %s",
1211 ip, mask, ifname);
1212 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
1213 if (system(buf) != 0) {
1214 send_resp(dut, conn, SIGMA_ERROR,
1215 "ErrorCode,Failed to set IPv6 address");
1216 return 0;
1217 }
1218 }
1219
1220 dut->last_set_ip_config_ipv6 = 1;
1221 static_ip_file(6, ip, mask, NULL);
1222 return 1;
1223 } else if (type == 1) {
Pradeep Reddy POTTETIb18c5652016-01-18 12:45:37 +05301224 if (!is_ip_addr(ip) || !is_ip_addr(mask))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001225 return -1;
1226 }
1227
1228 kill_dhcp_client(dut, ifname);
1229
1230 if (!dut->no_ip_addr_set) {
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301231 if (!set_ipv4_addr(dut, ifname, ip, mask)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001232 send_resp(dut, conn, SIGMA_ERROR,
1233 "ErrorCode,Failed to set IP address");
1234 return 0;
1235 }
1236 }
1237
1238 gw = get_param(cmd, "defaultGateway");
1239 if (gw) {
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301240 if (set_ipv4_gw(dut, gw) < 1) {
1241 send_resp(dut, conn, SIGMA_ERROR,
1242 "ErrorCode,Failed to set default gateway");
1243 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001244 }
1245 }
1246
1247 val = get_param(cmd, "primary-dns");
1248 if (val) {
1249 /* TODO */
1250 sigma_dut_print(dut, DUT_MSG_INFO, "Ignored primary-dns %s "
1251 "setting", val);
1252 }
1253
1254 val = get_param(cmd, "secondary-dns");
1255 if (val) {
1256 /* TODO */
1257 sigma_dut_print(dut, DUT_MSG_INFO, "Ignored secondary-dns %s "
1258 "setting", val);
1259 }
1260
1261 static_ip_file(4, ip, mask, gw);
1262
1263 return 1;
1264}
1265
1266
1267static int cmd_sta_get_info(struct sigma_dut *dut, struct sigma_conn *conn,
1268 struct sigma_cmd *cmd)
1269{
1270 /* const char *intf = get_param(cmd, "Interface"); */
1271 /* TODO: could report more details here */
1272 send_resp(dut, conn, SIGMA_COMPLETE, "vendor,Atheros");
1273 return 0;
1274}
1275
1276
1277static int cmd_sta_get_mac_address(struct sigma_dut *dut,
1278 struct sigma_conn *conn,
1279 struct sigma_cmd *cmd)
1280{
1281 /* const char *intf = get_param(cmd, "Interface"); */
1282 char addr[20], resp[50];
1283
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05301284 if (dut->dev_role == DEVROLE_STA_CFON)
1285 return sta_cfon_get_mac_address(dut, conn, cmd);
1286
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001287 if (get_wpa_status(get_station_ifname(), "address", addr, sizeof(addr))
1288 < 0)
1289 return -2;
1290
1291 snprintf(resp, sizeof(resp), "mac,%s", addr);
1292 send_resp(dut, conn, SIGMA_COMPLETE, resp);
1293 return 0;
1294}
1295
1296
1297static int cmd_sta_is_connected(struct sigma_dut *dut, struct sigma_conn *conn,
1298 struct sigma_cmd *cmd)
1299{
1300 /* const char *intf = get_param(cmd, "Interface"); */
1301 int connected = 0;
1302 char result[32];
1303 if (get_wpa_status(get_station_ifname(), "wpa_state", result,
1304 sizeof(result)) < 0) {
1305 sigma_dut_print(dut, DUT_MSG_INFO, "Could not get interface "
1306 "%s status", get_station_ifname());
1307 return -2;
1308 }
1309
1310 sigma_dut_print(dut, DUT_MSG_DEBUG, "wpa_state=%s", result);
1311 if (strncmp(result, "COMPLETED", 9) == 0)
1312 connected = 1;
1313
1314 if (connected)
1315 send_resp(dut, conn, SIGMA_COMPLETE, "connected,1");
1316 else
1317 send_resp(dut, conn, SIGMA_COMPLETE, "connected,0");
1318
1319 return 0;
1320}
1321
1322
1323static int cmd_sta_verify_ip_connection(struct sigma_dut *dut,
1324 struct sigma_conn *conn,
1325 struct sigma_cmd *cmd)
1326{
1327 /* const char *intf = get_param(cmd, "Interface"); */
1328 const char *dst, *timeout;
1329 int wait_time = 90;
1330 char buf[100];
1331 int res;
1332
1333 dst = get_param(cmd, "destination");
1334 if (dst == NULL || !is_ip_addr(dst))
1335 return -1;
1336
1337 timeout = get_param(cmd, "timeout");
1338 if (timeout) {
1339 wait_time = atoi(timeout);
1340 if (wait_time < 1)
1341 wait_time = 1;
1342 }
1343
1344 /* TODO: force renewal of IP lease if DHCP is enabled */
1345
1346 snprintf(buf, sizeof(buf), "ping %s -c 3 -W %d", dst, wait_time);
1347 res = system(buf);
1348 sigma_dut_print(dut, DUT_MSG_DEBUG, "ping returned: %d", res);
1349 if (res == 0)
1350 send_resp(dut, conn, SIGMA_COMPLETE, "connected,1");
1351 else if (res == 256)
1352 send_resp(dut, conn, SIGMA_COMPLETE, "connected,0");
1353 else
1354 return -2;
1355
1356 return 0;
1357}
1358
1359
1360static int cmd_sta_get_bssid(struct sigma_dut *dut, struct sigma_conn *conn,
1361 struct sigma_cmd *cmd)
1362{
1363 /* const char *intf = get_param(cmd, "Interface"); */
1364 char bssid[20], resp[50];
1365
1366 if (get_wpa_status(get_station_ifname(), "bssid", bssid, sizeof(bssid))
1367 < 0)
Peng Xub8fc5cc2017-05-10 17:27:28 -07001368 strlcpy(bssid, "00:00:00:00:00:00", sizeof(bssid));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001369
1370 snprintf(resp, sizeof(resp), "bssid,%s", bssid);
1371 send_resp(dut, conn, SIGMA_COMPLETE, resp);
1372 return 0;
1373}
1374
1375
1376#ifdef __SAMSUNG__
1377static int add_use_network(const char *ifname)
1378{
1379 char buf[100];
1380
1381 snprintf(buf, sizeof(buf), "USE_NETWORK ON");
1382 wpa_command(ifname, buf);
1383 return 0;
1384}
1385#endif /* __SAMSUNG__ */
1386
1387
1388static int add_network_common(struct sigma_dut *dut, struct sigma_conn *conn,
1389 const char *ifname, struct sigma_cmd *cmd)
1390{
1391 const char *ssid = get_param(cmd, "ssid");
1392 int id;
1393 const char *val;
1394
1395 if (ssid == NULL)
1396 return -1;
1397
1398 start_sta_mode(dut);
1399
1400#ifdef __SAMSUNG__
1401 add_use_network(ifname);
1402#endif /* __SAMSUNG__ */
1403
1404 id = add_network(ifname);
1405 if (id < 0)
1406 return -2;
1407 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding network %d", id);
1408
1409 if (set_network_quoted(ifname, id, "ssid", ssid) < 0)
1410 return -2;
1411
1412 dut->infra_network_id = id;
1413 snprintf(dut->infra_ssid, sizeof(dut->infra_ssid), "%s", ssid);
1414
1415 val = get_param(cmd, "program");
1416 if (!val)
1417 val = get_param(cmd, "prog");
1418 if (val && strcasecmp(val, "hs2") == 0) {
1419 char buf[100];
1420 snprintf(buf, sizeof(buf), "ENABLE_NETWORK %d no-connect", id);
1421 wpa_command(ifname, buf);
1422
1423 val = get_param(cmd, "prefer");
1424 if (val && atoi(val) > 0)
1425 set_network(ifname, id, "priority", "1");
1426 }
1427
1428 return id;
1429}
1430
1431
1432static int cmd_sta_set_encryption(struct sigma_dut *dut,
1433 struct sigma_conn *conn,
1434 struct sigma_cmd *cmd)
1435{
1436 const char *intf = get_param(cmd, "Interface");
1437 const char *ssid = get_param(cmd, "ssid");
1438 const char *type = get_param(cmd, "encpType");
1439 const char *ifname;
1440 char buf[200];
1441 int id;
1442
1443 if (intf == NULL || ssid == NULL)
1444 return -1;
1445
1446 if (strcmp(intf, get_main_ifname()) == 0)
1447 ifname = get_station_ifname();
1448 else
1449 ifname = intf;
1450
1451 id = add_network_common(dut, conn, ifname, cmd);
1452 if (id < 0)
1453 return id;
1454
1455 if (set_network(ifname, id, "key_mgmt", "NONE") < 0)
1456 return -2;
1457
1458 if (type && strcasecmp(type, "wep") == 0) {
1459 const char *val;
1460 int i;
1461
1462 val = get_param(cmd, "activeKey");
1463 if (val) {
1464 int keyid;
1465 keyid = atoi(val);
1466 if (keyid < 1 || keyid > 4)
1467 return -1;
1468 snprintf(buf, sizeof(buf), "%d", keyid - 1);
1469 if (set_network(ifname, id, "wep_tx_keyidx", buf) < 0)
1470 return -2;
1471 }
1472
1473 for (i = 0; i < 4; i++) {
1474 snprintf(buf, sizeof(buf), "key%d", i + 1);
1475 val = get_param(cmd, buf);
1476 if (val == NULL)
1477 continue;
1478 snprintf(buf, sizeof(buf), "wep_key%d", i);
1479 if (set_network(ifname, id, buf, val) < 0)
1480 return -2;
1481 }
1482 }
1483
1484 return 1;
1485}
1486
1487
1488static int set_wpa_common(struct sigma_dut *dut, struct sigma_conn *conn,
1489 const char *ifname, struct sigma_cmd *cmd)
1490{
1491 const char *val;
1492 int id;
Jouni Malinenad395a22017-09-01 21:13:46 +03001493 int cipher_set = 0;
Jouni Malinen47dcc952017-10-09 16:43:24 +03001494 int owe;
Sunil Duttc75a1e62018-01-11 20:47:50 +05301495 int suite_b = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001496
1497 id = add_network_common(dut, conn, ifname, cmd);
1498 if (id < 0)
1499 return id;
1500
Jouni Malinen47dcc952017-10-09 16:43:24 +03001501 val = get_param(cmd, "Type");
1502 owe = val && strcasecmp(val, "OWE") == 0;
1503
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001504 val = get_param(cmd, "keyMgmtType");
Jouni Malinen47dcc952017-10-09 16:43:24 +03001505 if (!val && owe)
1506 val = "OWE";
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001507 if (val == NULL) {
1508 send_resp(dut, conn, SIGMA_INVALID, "errorCode,Missing keyMgmtType");
1509 return 0;
1510 }
1511 if (strcasecmp(val, "wpa") == 0 ||
1512 strcasecmp(val, "wpa-psk") == 0) {
1513 if (set_network(ifname, id, "proto", "WPA") < 0)
1514 return -2;
1515 } else if (strcasecmp(val, "wpa2") == 0 ||
1516 strcasecmp(val, "wpa2-psk") == 0 ||
1517 strcasecmp(val, "wpa2-ft") == 0 ||
1518 strcasecmp(val, "wpa2-sha256") == 0) {
1519 if (set_network(ifname, id, "proto", "WPA2") < 0)
1520 return -2;
Pradeep Reddy POTTETI6d04b3b2016-11-15 14:51:26 +05301521 } else if (strcasecmp(val, "wpa2-wpa-psk") == 0 ||
1522 strcasecmp(val, "wpa2-wpa-ent") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001523 if (set_network(ifname, id, "proto", "WPA WPA2") < 0)
1524 return -2;
Jouni Malinenad395a22017-09-01 21:13:46 +03001525 } else if (strcasecmp(val, "SuiteB") == 0) {
Sunil Duttc75a1e62018-01-11 20:47:50 +05301526 suite_b = 1;
Jouni Malinenad395a22017-09-01 21:13:46 +03001527 if (set_network(ifname, id, "proto", "WPA2") < 0)
1528 return -2;
Jouni Malinen47dcc952017-10-09 16:43:24 +03001529 } else if (strcasecmp(val, "OWE") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001530 } else {
1531 send_resp(dut, conn, SIGMA_INVALID, "errorCode,Unrecognized keyMgmtType value");
1532 return 0;
1533 }
1534
1535 val = get_param(cmd, "encpType");
Jouni Malinenad395a22017-09-01 21:13:46 +03001536 if (val) {
1537 cipher_set = 1;
1538 if (strcasecmp(val, "tkip") == 0) {
1539 if (set_network(ifname, id, "pairwise", "TKIP") < 0)
1540 return -2;
1541 } else if (strcasecmp(val, "aes-ccmp") == 0) {
1542 if (set_network(ifname, id, "pairwise", "CCMP") < 0)
1543 return -2;
1544 } else if (strcasecmp(val, "aes-ccmp-tkip") == 0) {
1545 if (set_network(ifname, id, "pairwise",
1546 "CCMP TKIP") < 0)
1547 return -2;
1548 } else if (strcasecmp(val, "aes-gcmp") == 0) {
1549 if (set_network(ifname, id, "pairwise", "GCMP") < 0)
1550 return -2;
1551 if (set_network(ifname, id, "group", "GCMP") < 0)
1552 return -2;
1553 } else {
1554 send_resp(dut, conn, SIGMA_ERROR,
1555 "errorCode,Unrecognized encpType value");
1556 return 0;
1557 }
1558 }
1559
1560 val = get_param(cmd, "PairwiseCipher");
1561 if (val) {
1562 cipher_set = 1;
1563 /* TODO: Support space separated list */
1564 if (strcasecmp(val, "AES-GCMP-256") == 0) {
1565 if (set_network(ifname, id, "pairwise", "GCMP-256") < 0)
1566 return -2;
1567 } else if (strcasecmp(val, "AES-CCMP-256") == 0) {
1568 if (set_network(ifname, id, "pairwise",
1569 "CCMP-256") < 0)
1570 return -2;
1571 } else if (strcasecmp(val, "AES-GCMP-128") == 0) {
1572 if (set_network(ifname, id, "pairwise", "GCMP") < 0)
1573 return -2;
1574 } else if (strcasecmp(val, "AES-CCMP-128") == 0) {
1575 if (set_network(ifname, id, "pairwise", "CCMP") < 0)
1576 return -2;
1577 } else {
1578 send_resp(dut, conn, SIGMA_ERROR,
1579 "errorCode,Unrecognized PairwiseCipher value");
1580 return 0;
1581 }
1582 }
1583
Jouni Malinen47dcc952017-10-09 16:43:24 +03001584 if (!cipher_set && !owe) {
Jouni Malinenad395a22017-09-01 21:13:46 +03001585 send_resp(dut, conn, SIGMA_ERROR,
1586 "errorCode,Missing encpType and PairwiseCipher");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001587 return 0;
1588 }
Jouni Malinenad395a22017-09-01 21:13:46 +03001589
1590 val = get_param(cmd, "GroupCipher");
1591 if (val) {
1592 if (strcasecmp(val, "AES-GCMP-256") == 0) {
1593 if (set_network(ifname, id, "group", "GCMP-256") < 0)
1594 return -2;
1595 } else if (strcasecmp(val, "AES-CCMP-256") == 0) {
1596 if (set_network(ifname, id, "group", "CCMP-256") < 0)
1597 return -2;
1598 } else if (strcasecmp(val, "AES-GCMP-128") == 0) {
1599 if (set_network(ifname, id, "group", "GCMP") < 0)
1600 return -2;
1601 } else if (strcasecmp(val, "AES-CCMP-128") == 0) {
1602 if (set_network(ifname, id, "group", "CCMP") < 0)
1603 return -2;
1604 } else {
1605 send_resp(dut, conn, SIGMA_ERROR,
1606 "errorCode,Unrecognized GroupCipher value");
1607 return 0;
1608 }
1609 }
1610
Jouni Malinen7b239522017-09-14 21:37:18 +03001611 val = get_param(cmd, "GroupMgntCipher");
Jouni Malinenad395a22017-09-01 21:13:46 +03001612 if (val) {
Jouni Malinene8898cb2017-09-26 17:55:26 +03001613 const char *cipher;
1614
1615 if (strcasecmp(val, "BIP-GMAC-256") == 0) {
1616 cipher = "BIP-GMAC-256";
1617 } else if (strcasecmp(val, "BIP-CMAC-256") == 0) {
1618 cipher = "BIP-CMAC-256";
1619 } else if (strcasecmp(val, "BIP-GMAC-128") == 0) {
1620 cipher = "BIP-GMAC-128";
1621 } else if (strcasecmp(val, "BIP-CMAC-128") == 0) {
1622 cipher = "AES-128-CMAC";
1623 } else {
1624 send_resp(dut, conn, SIGMA_INVALID,
1625 "errorCode,Unsupported GroupMgntCipher");
1626 return 0;
1627 }
1628 if (set_network(ifname, id, "group_mgmt", cipher) < 0) {
1629 send_resp(dut, conn, SIGMA_INVALID,
1630 "errorCode,Failed to set GroupMgntCipher");
1631 return 0;
1632 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001633 }
1634
1635 dut->sta_pmf = STA_PMF_DISABLED;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05301636
1637 if (dut->program == PROGRAM_OCE) {
1638 dut->sta_pmf = STA_PMF_OPTIONAL;
1639 if (set_network(ifname, id, "ieee80211w", "1") < 0)
1640 return -2;
1641 }
1642
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001643 val = get_param(cmd, "PMF");
1644 if (val) {
1645 if (strcasecmp(val, "Required") == 0 ||
1646 strcasecmp(val, "Forced_Required") == 0) {
1647 dut->sta_pmf = STA_PMF_REQUIRED;
1648 if (set_network(ifname, id, "ieee80211w", "2") < 0)
1649 return -2;
1650 } else if (strcasecmp(val, "Optional") == 0) {
1651 dut->sta_pmf = STA_PMF_OPTIONAL;
1652 if (set_network(ifname, id, "ieee80211w", "1") < 0)
1653 return -2;
1654 } else if (strcasecmp(val, "Disabled") == 0 ||
Kiran Kumar Lokere07da3b22018-12-16 22:42:49 -08001655 strcasecmp(val, "Disable") == 0 ||
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001656 strcasecmp(val, "Forced_Disabled") == 0) {
1657 dut->sta_pmf = STA_PMF_DISABLED;
1658 } else {
1659 send_resp(dut, conn, SIGMA_INVALID, "errorCode,Unrecognized PMF value");
1660 return 0;
1661 }
Sunil Duttc75a1e62018-01-11 20:47:50 +05301662 } else if (owe || suite_b) {
Jouni Malinen1287cd72018-01-04 17:08:01 +02001663 dut->sta_pmf = STA_PMF_REQUIRED;
1664 if (set_network(ifname, id, "ieee80211w", "2") < 0)
1665 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001666 }
1667
1668 return id;
1669}
1670
1671
1672static int cmd_sta_set_psk(struct sigma_dut *dut, struct sigma_conn *conn,
1673 struct sigma_cmd *cmd)
1674{
1675 const char *intf = get_param(cmd, "Interface");
Jouni Malinen992a81e2017-08-22 13:57:47 +03001676 const char *type = get_param(cmd, "Type");
Jouni Malinen1287cd72018-01-04 17:08:01 +02001677 const char *pmf = get_param(cmd, "PMF");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02001678 const char *network_mode = get_param(cmd, "network_mode");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001679 const char *ifname, *val, *alg;
1680 int id;
1681
1682 if (intf == NULL)
1683 return -1;
1684
1685 if (strcmp(intf, get_main_ifname()) == 0)
1686 ifname = get_station_ifname();
1687 else
1688 ifname = intf;
1689
1690 id = set_wpa_common(dut, conn, ifname, cmd);
1691 if (id < 0)
1692 return id;
1693
1694 val = get_param(cmd, "keyMgmtType");
1695 alg = get_param(cmd, "micAlg");
1696
Jouni Malinen992a81e2017-08-22 13:57:47 +03001697 if (type && strcasecmp(type, "SAE") == 0) {
1698 if (val && strcasecmp(val, "wpa2-ft") == 0) {
1699 if (set_network(ifname, id, "key_mgmt", "FT-SAE") < 0)
1700 return -2;
1701 } else {
1702 if (set_network(ifname, id, "key_mgmt", "SAE") < 0)
1703 return -2;
1704 }
1705 if (wpa_command(ifname, "SET sae_groups ") != 0) {
1706 sigma_dut_print(dut, DUT_MSG_ERROR,
1707 "Failed to clear sae_groups to default");
1708 return -2;
1709 }
Jouni Malinen1287cd72018-01-04 17:08:01 +02001710 if (!pmf) {
1711 dut->sta_pmf = STA_PMF_REQUIRED;
1712 if (set_network(ifname, id, "ieee80211w", "2") < 0)
1713 return -2;
1714 }
Jouni Malinen0ab50f42017-08-31 01:34:59 +03001715 } else if (type && strcasecmp(type, "PSK-SAE") == 0) {
1716 if (val && strcasecmp(val, "wpa2-ft") == 0) {
1717 if (set_network(ifname, id, "key_mgmt",
1718 "FT-SAE FT-PSK") < 0)
1719 return -2;
1720 } else {
1721 if (set_network(ifname, id, "key_mgmt",
1722 "SAE WPA-PSK") < 0)
1723 return -2;
1724 }
1725 if (wpa_command(ifname, "SET sae_groups ") != 0) {
1726 sigma_dut_print(dut, DUT_MSG_ERROR,
1727 "Failed to clear sae_groups to default");
1728 return -2;
1729 }
Jouni Malinen1287cd72018-01-04 17:08:01 +02001730 if (!pmf) {
1731 dut->sta_pmf = STA_PMF_OPTIONAL;
1732 if (set_network(ifname, id, "ieee80211w", "1") < 0)
1733 return -2;
1734 }
Jouni Malinen992a81e2017-08-22 13:57:47 +03001735 } else if (alg && strcasecmp(alg, "SHA-256") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001736 if (set_network(ifname, id, "key_mgmt", "WPA-PSK-SHA256") < 0)
1737 return -2;
1738 } else if (alg && strcasecmp(alg, "SHA-1") == 0) {
1739 if (set_network(ifname, id, "key_mgmt", "WPA-PSK") < 0)
1740 return -2;
Ashwini Patil6dbf7b02017-03-20 13:42:11 +05301741 } else if (val && strcasecmp(val, "wpa2-ft") == 0) {
1742 if (set_network(ifname, id, "key_mgmt", "FT-PSK") < 0)
1743 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001744 } else if ((val && strcasecmp(val, "wpa2-sha256") == 0) ||
1745 dut->sta_pmf == STA_PMF_REQUIRED) {
1746 if (set_network(ifname, id, "key_mgmt",
1747 "WPA-PSK WPA-PSK-SHA256") < 0)
1748 return -2;
1749 } else if (dut->sta_pmf == STA_PMF_OPTIONAL) {
1750 if (set_network(ifname, id, "key_mgmt",
1751 "WPA-PSK WPA-PSK-SHA256") < 0)
1752 return -2;
1753 } else {
1754 if (set_network(ifname, id, "key_mgmt", "WPA-PSK") < 0)
1755 return -2;
1756 }
1757
1758 val = get_param(cmd, "passPhrase");
1759 if (val == NULL)
1760 return -1;
Jouni Malinen2126f422017-10-11 23:24:33 +03001761 if (type && strcasecmp(type, "SAE") == 0) {
1762 if (set_network_quoted(ifname, id, "sae_password", val) < 0)
1763 return -2;
1764 } else {
1765 if (set_network_quoted(ifname, id, "psk", val) < 0)
1766 return -2;
1767 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001768
Jouni Malinen992a81e2017-08-22 13:57:47 +03001769 val = get_param(cmd, "ECGroupID");
1770 if (val) {
1771 char buf[50];
1772
1773 snprintf(buf, sizeof(buf), "SET sae_groups %u", atoi(val));
1774 if (wpa_command(ifname, buf) != 0) {
1775 sigma_dut_print(dut, DUT_MSG_ERROR,
1776 "Failed to clear sae_groups");
1777 return -2;
1778 }
1779 }
1780
Jouni Malinen68143132017-09-02 02:34:08 +03001781 val = get_param(cmd, "InvalidSAEElement");
1782 if (val) {
1783 free(dut->sae_commit_override);
1784 dut->sae_commit_override = strdup(val);
1785 }
1786
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02001787 if (dut->program == PROGRAM_60GHZ && network_mode &&
1788 strcasecmp(network_mode, "PBSS") == 0 &&
1789 set_network(ifname, id, "pbss", "1") < 0)
1790 return -2;
1791
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001792 return 1;
1793}
1794
1795
1796static int set_eap_common(struct sigma_dut *dut, struct sigma_conn *conn,
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05301797 const char *ifname, int username_identity,
1798 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001799{
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05301800 const char *val, *alg, *akm;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001801 int id;
1802 char buf[200];
1803#ifdef ANDROID
1804 unsigned char kvalue[KEYSTORE_MESSAGE_SIZE];
1805 int length;
1806#endif /* ANDROID */
1807
1808 id = set_wpa_common(dut, conn, ifname, cmd);
1809 if (id < 0)
1810 return id;
1811
1812 val = get_param(cmd, "keyMgmtType");
1813 alg = get_param(cmd, "micAlg");
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05301814 akm = get_param(cmd, "AKMSuiteType");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001815
Jouni Malinenad395a22017-09-01 21:13:46 +03001816 if (val && strcasecmp(val, "SuiteB") == 0) {
1817 if (set_network(ifname, id, "key_mgmt", "WPA-EAP-SUITE-B-192") <
1818 0)
1819 return -2;
1820 } else if (alg && strcasecmp(alg, "SHA-256") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001821 if (set_network(ifname, id, "key_mgmt", "WPA-EAP-SHA256") < 0)
1822 return -2;
1823 } else if (alg && strcasecmp(alg, "SHA-1") == 0) {
1824 if (set_network(ifname, id, "key_mgmt", "WPA-EAP") < 0)
1825 return -2;
1826 } else if (val && strcasecmp(val, "wpa2-ft") == 0) {
1827 if (set_network(ifname, id, "key_mgmt", "FT-EAP") < 0)
1828 return -2;
1829 } else if ((val && strcasecmp(val, "wpa2-sha256") == 0) ||
1830 dut->sta_pmf == STA_PMF_REQUIRED) {
1831 if (set_network(ifname, id, "key_mgmt",
1832 "WPA-EAP WPA-EAP-SHA256") < 0)
1833 return -2;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05301834 } else if (akm && atoi(akm) == 14) {
1835 if (dut->sta_pmf == STA_PMF_OPTIONAL ||
1836 dut->sta_pmf == STA_PMF_REQUIRED) {
1837 if (set_network(ifname, id, "key_mgmt",
1838 "WPA-EAP-SHA256 FILS-SHA256") < 0)
1839 return -2;
1840 } else {
1841 if (set_network(ifname, id, "key_mgmt",
1842 "WPA-EAP FILS-SHA256") < 0)
1843 return -2;
1844 }
1845
1846 if (set_network(ifname, id, "erp", "1") < 0)
1847 return -2;
1848 } else if (akm && atoi(akm) == 15) {
1849 if (dut->sta_pmf == STA_PMF_OPTIONAL ||
1850 dut->sta_pmf == STA_PMF_REQUIRED) {
1851 if (set_network(ifname, id, "key_mgmt",
1852 "WPA-EAP-SHA256 FILS-SHA384") < 0)
1853 return -2;
1854 } else {
1855 if (set_network(ifname, id, "key_mgmt",
1856 "WPA-EAP FILS-SHA384") < 0)
1857 return -2;
1858 }
1859
1860 if (set_network(ifname, id, "erp", "1") < 0)
1861 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001862 } else if (dut->sta_pmf == STA_PMF_OPTIONAL) {
1863 if (set_network(ifname, id, "key_mgmt",
1864 "WPA-EAP WPA-EAP-SHA256") < 0)
1865 return -2;
1866 } else {
1867 if (set_network(ifname, id, "key_mgmt", "WPA-EAP") < 0)
1868 return -2;
1869 }
1870
1871 val = get_param(cmd, "trustedRootCA");
1872 if (val) {
1873#ifdef ANDROID
1874 snprintf(buf, sizeof(buf), "CACERT_%s", val);
1875 length = android_keystore_get(ANDROID_KEYSTORE_GET, buf,
1876 kvalue);
1877 if (length > 0) {
1878 sigma_dut_print(dut, DUT_MSG_INFO,
1879 "Use Android keystore [%s]", buf);
1880 snprintf(buf, sizeof(buf), "keystore://CACERT_%s",
1881 val);
1882 goto ca_cert_selected;
1883 }
1884#endif /* ANDROID */
1885
1886 snprintf(buf, sizeof(buf), "%s/%s", sigma_cert_path, val);
1887#ifdef __linux__
1888 if (!file_exists(buf)) {
1889 char msg[300];
1890 snprintf(msg, sizeof(msg), "ErrorCode,trustedRootCA "
1891 "file (%s) not found", buf);
1892 send_resp(dut, conn, SIGMA_ERROR, msg);
1893 return -3;
1894 }
1895#endif /* __linux__ */
1896#ifdef ANDROID
1897ca_cert_selected:
1898#endif /* ANDROID */
1899 if (set_network_quoted(ifname, id, "ca_cert", buf) < 0)
1900 return -2;
1901 }
1902
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05301903 if (username_identity) {
1904 val = get_param(cmd, "username");
1905 if (val) {
1906 if (set_network_quoted(ifname, id, "identity", val) < 0)
1907 return -2;
1908 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001909
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05301910 val = get_param(cmd, "password");
1911 if (val) {
1912 if (set_network_quoted(ifname, id, "password", val) < 0)
1913 return -2;
1914 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001915 }
1916
1917 return id;
1918}
1919
1920
Jouni Malinen5eabb2a2017-10-03 18:17:30 +03001921static int set_tls_cipher(const char *ifname, int id, const char *cipher)
1922{
1923 const char *val;
1924
1925 if (!cipher)
1926 return 0;
1927
1928 if (strcasecmp(cipher, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384") == 0)
1929 val = "ECDHE-ECDSA-AES256-GCM-SHA384";
1930 else if (strcasecmp(cipher,
1931 "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384") == 0)
1932 val = "ECDHE-RSA-AES256-GCM-SHA384";
1933 else if (strcasecmp(cipher, "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384") == 0)
1934 val = "DHE-RSA-AES256-GCM-SHA384";
1935 else if (strcasecmp(cipher,
1936 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256") == 0)
1937 val = "ECDHE-ECDSA-AES128-GCM-SHA256";
1938 else
1939 return -1;
1940
1941 /* Need to clear phase1="tls_suiteb=1" to allow cipher enforcement */
1942 set_network_quoted(ifname, id, "phase1", "");
1943
1944 return set_network_quoted(ifname, id, "openssl_ciphers", val);
1945}
1946
1947
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001948static int cmd_sta_set_eaptls(struct sigma_dut *dut, struct sigma_conn *conn,
1949 struct sigma_cmd *cmd)
1950{
1951 const char *intf = get_param(cmd, "Interface");
1952 const char *ifname, *val;
1953 int id;
1954 char buf[200];
1955#ifdef ANDROID
1956 unsigned char kvalue[KEYSTORE_MESSAGE_SIZE];
1957 int length;
1958 int jb_or_newer = 0;
1959 char prop[PROPERTY_VALUE_MAX];
1960#endif /* ANDROID */
1961
1962 if (intf == NULL)
1963 return -1;
1964
1965 if (strcmp(intf, get_main_ifname()) == 0)
1966 ifname = get_station_ifname();
1967 else
1968 ifname = intf;
1969
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05301970 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001971 if (id < 0)
1972 return id;
1973
1974 if (set_network(ifname, id, "eap", "TLS") < 0)
1975 return -2;
1976
Pradeep Reddy POTTETI9f6c2132016-05-05 16:28:19 +05301977 if (!get_param(cmd, "username") &&
1978 set_network_quoted(ifname, id, "identity",
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001979 "wifi-user@wifilabs.local") < 0)
1980 return -2;
1981
1982 val = get_param(cmd, "clientCertificate");
1983 if (val == NULL)
1984 return -1;
1985#ifdef ANDROID
1986 snprintf(buf, sizeof(buf), "USRPKEY_%s", val);
1987 length = android_keystore_get(ANDROID_KEYSTORE_GET, buf, kvalue);
1988 if (length < 0) {
1989 /*
1990 * JB started reporting keystore type mismatches, so retry with
1991 * the GET_PUBKEY command if the generic GET fails.
1992 */
1993 length = android_keystore_get(ANDROID_KEYSTORE_GET_PUBKEY,
1994 buf, kvalue);
1995 }
1996
1997 if (property_get("ro.build.version.release", prop, NULL) != 0) {
1998 sigma_dut_print(dut, DUT_MSG_DEBUG, "Android release %s", prop);
1999 if (strncmp(prop, "4.0", 3) != 0)
2000 jb_or_newer = 1;
2001 } else
2002 jb_or_newer = 1; /* assume newer */
2003
2004 if (jb_or_newer && length > 0) {
2005 sigma_dut_print(dut, DUT_MSG_INFO,
2006 "Use Android keystore [%s]", buf);
2007 if (set_network(ifname, id, "engine", "1") < 0)
2008 return -2;
2009 if (set_network_quoted(ifname, id, "engine_id", "keystore") < 0)
2010 return -2;
2011 snprintf(buf, sizeof(buf), "USRPKEY_%s", val);
2012 if (set_network_quoted(ifname, id, "key_id", buf) < 0)
2013 return -2;
2014 snprintf(buf, sizeof(buf), "keystore://USRCERT_%s", val);
2015 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
2016 return -2;
2017 return 1;
2018 } else if (length > 0) {
2019 sigma_dut_print(dut, DUT_MSG_INFO,
2020 "Use Android keystore [%s]", buf);
2021 snprintf(buf, sizeof(buf), "keystore://USRPKEY_%s", val);
2022 if (set_network_quoted(ifname, id, "private_key", buf) < 0)
2023 return -2;
2024 snprintf(buf, sizeof(buf), "keystore://USRCERT_%s", val);
2025 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
2026 return -2;
2027 return 1;
2028 }
2029#endif /* ANDROID */
2030
2031 snprintf(buf, sizeof(buf), "%s/%s", sigma_cert_path, val);
2032#ifdef __linux__
2033 if (!file_exists(buf)) {
2034 char msg[300];
2035 snprintf(msg, sizeof(msg), "ErrorCode,clientCertificate file "
2036 "(%s) not found", buf);
2037 send_resp(dut, conn, SIGMA_ERROR, msg);
2038 return -3;
2039 }
2040#endif /* __linux__ */
2041 if (set_network_quoted(ifname, id, "private_key", buf) < 0)
2042 return -2;
2043 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
2044 return -2;
2045
2046 if (set_network_quoted(ifname, id, "private_key_passwd", "wifi") < 0)
2047 return -2;
2048
Jouni Malinen5eabb2a2017-10-03 18:17:30 +03002049 val = get_param(cmd, "keyMgmtType");
2050 if (val && strcasecmp(val, "SuiteB") == 0) {
2051 val = get_param(cmd, "CertType");
2052 if (val && strcasecmp(val, "RSA") == 0) {
2053 if (set_network_quoted(ifname, id, "phase1",
2054 "tls_suiteb=1") < 0)
2055 return -2;
2056 } else {
2057 if (set_network_quoted(ifname, id, "openssl_ciphers",
2058 "SUITEB192") < 0)
2059 return -2;
2060 }
2061
2062 val = get_param(cmd, "TLSCipher");
2063 if (set_tls_cipher(ifname, id, val) < 0) {
2064 send_resp(dut, conn, SIGMA_ERROR,
2065 "ErrorCode,Unsupported TLSCipher value");
2066 return -3;
2067 }
2068 }
2069
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002070 return 1;
2071}
2072
2073
2074static int cmd_sta_set_eapttls(struct sigma_dut *dut, struct sigma_conn *conn,
2075 struct sigma_cmd *cmd)
2076{
2077 const char *intf = get_param(cmd, "Interface");
2078 const char *ifname;
2079 int id;
2080
2081 if (intf == NULL)
2082 return -1;
2083
2084 if (strcmp(intf, get_main_ifname()) == 0)
2085 ifname = get_station_ifname();
2086 else
2087 ifname = intf;
2088
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302089 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002090 if (id < 0)
2091 return id;
2092
2093 if (set_network(ifname, id, "eap", "TTLS") < 0) {
2094 send_resp(dut, conn, SIGMA_ERROR,
2095 "errorCode,Failed to set TTLS method");
2096 return 0;
2097 }
2098
2099 if (set_network_quoted(ifname, id, "phase2", "auth=MSCHAPV2") < 0) {
2100 send_resp(dut, conn, SIGMA_ERROR,
2101 "errorCode,Failed to set MSCHAPv2 for TTLS Phase 2");
2102 return 0;
2103 }
2104
2105 return 1;
2106}
2107
2108
2109static int cmd_sta_set_eapsim(struct sigma_dut *dut, struct sigma_conn *conn,
2110 struct sigma_cmd *cmd)
2111{
2112 const char *intf = get_param(cmd, "Interface");
2113 const char *ifname;
2114 int id;
2115
2116 if (intf == NULL)
2117 return -1;
2118
2119 if (strcmp(intf, get_main_ifname()) == 0)
2120 ifname = get_station_ifname();
2121 else
2122 ifname = intf;
2123
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302124 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002125 if (id < 0)
2126 return id;
2127
2128 if (set_network(ifname, id, "eap", "SIM") < 0)
2129 return -2;
2130
2131 return 1;
2132}
2133
2134
2135static int cmd_sta_set_peap(struct sigma_dut *dut, struct sigma_conn *conn,
2136 struct sigma_cmd *cmd)
2137{
2138 const char *intf = get_param(cmd, "Interface");
2139 const char *ifname, *val;
2140 int id;
2141 char buf[100];
2142
2143 if (intf == NULL)
2144 return -1;
2145
2146 if (strcmp(intf, get_main_ifname()) == 0)
2147 ifname = get_station_ifname();
2148 else
2149 ifname = intf;
2150
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302151 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002152 if (id < 0)
2153 return id;
2154
2155 if (set_network(ifname, id, "eap", "PEAP") < 0)
2156 return -2;
2157
2158 val = get_param(cmd, "innerEAP");
2159 if (val) {
2160 if (strcasecmp(val, "MSCHAPv2") == 0) {
2161 if (set_network_quoted(ifname, id, "phase2",
2162 "auth=MSCHAPV2") < 0)
2163 return -2;
2164 } else if (strcasecmp(val, "GTC") == 0) {
2165 if (set_network_quoted(ifname, id, "phase2",
2166 "auth=GTC") < 0)
2167 return -2;
2168 } else
2169 return -1;
2170 }
2171
2172 val = get_param(cmd, "peapVersion");
2173 if (val) {
2174 int ver = atoi(val);
2175 if (ver < 0 || ver > 1)
2176 return -1;
2177 snprintf(buf, sizeof(buf), "peapver=%d", ver);
2178 if (set_network_quoted(ifname, id, "phase1", buf) < 0)
2179 return -2;
2180 }
2181
2182 return 1;
2183}
2184
2185
2186static int cmd_sta_set_eapfast(struct sigma_dut *dut, struct sigma_conn *conn,
2187 struct sigma_cmd *cmd)
2188{
2189 const char *intf = get_param(cmd, "Interface");
2190 const char *ifname, *val;
2191 int id;
2192 char buf[100];
2193
2194 if (intf == NULL)
2195 return -1;
2196
2197 if (strcmp(intf, get_main_ifname()) == 0)
2198 ifname = get_station_ifname();
2199 else
2200 ifname = intf;
2201
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302202 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002203 if (id < 0)
2204 return id;
2205
2206 if (set_network(ifname, id, "eap", "FAST") < 0)
2207 return -2;
2208
2209 val = get_param(cmd, "innerEAP");
2210 if (val) {
2211 if (strcasecmp(val, "MSCHAPV2") == 0) {
2212 if (set_network_quoted(ifname, id, "phase2",
2213 "auth=MSCHAPV2") < 0)
2214 return -2;
2215 } else if (strcasecmp(val, "GTC") == 0) {
2216 if (set_network_quoted(ifname, id, "phase2",
2217 "auth=GTC") < 0)
2218 return -2;
2219 } else
2220 return -1;
2221 }
2222
2223 val = get_param(cmd, "validateServer");
2224 if (val) {
2225 /* TODO */
2226 sigma_dut_print(dut, DUT_MSG_INFO, "Ignored EAP-FAST "
2227 "validateServer=%s", val);
2228 }
2229
2230 val = get_param(cmd, "pacFile");
2231 if (val) {
2232 snprintf(buf, sizeof(buf), "blob://%s", val);
2233 if (set_network_quoted(ifname, id, "pac_file", buf) < 0)
2234 return -2;
2235 }
2236
2237 if (set_network_quoted(ifname, id, "phase1", "fast_provisioning=2") <
2238 0)
2239 return -2;
2240
2241 return 1;
2242}
2243
2244
2245static int cmd_sta_set_eapaka(struct sigma_dut *dut, struct sigma_conn *conn,
2246 struct sigma_cmd *cmd)
2247{
2248 const char *intf = get_param(cmd, "Interface");
2249 const char *ifname;
2250 int id;
2251
2252 if (intf == NULL)
2253 return -1;
2254
2255 if (strcmp(intf, get_main_ifname()) == 0)
2256 ifname = get_station_ifname();
2257 else
2258 ifname = intf;
2259
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302260 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002261 if (id < 0)
2262 return id;
2263
2264 if (set_network(ifname, id, "eap", "AKA") < 0)
2265 return -2;
2266
2267 return 1;
2268}
2269
2270
2271static int cmd_sta_set_eapakaprime(struct sigma_dut *dut,
2272 struct sigma_conn *conn,
2273 struct sigma_cmd *cmd)
2274{
2275 const char *intf = get_param(cmd, "Interface");
2276 const char *ifname;
2277 int id;
2278
2279 if (intf == NULL)
2280 return -1;
2281
2282 if (strcmp(intf, get_main_ifname()) == 0)
2283 ifname = get_station_ifname();
2284 else
2285 ifname = intf;
2286
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302287 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002288 if (id < 0)
2289 return id;
2290
2291 if (set_network(ifname, id, "eap", "AKA'") < 0)
2292 return -2;
2293
2294 return 1;
2295}
2296
2297
2298static int sta_set_open(struct sigma_dut *dut, struct sigma_conn *conn,
2299 struct sigma_cmd *cmd)
2300{
2301 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002302 const char *network_mode = get_param(cmd, "network_mode");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002303 const char *ifname;
2304 int id;
2305
2306 if (strcmp(intf, get_main_ifname()) == 0)
2307 ifname = get_station_ifname();
2308 else
2309 ifname = intf;
2310
2311 id = add_network_common(dut, conn, ifname, cmd);
2312 if (id < 0)
2313 return id;
2314
2315 if (set_network(ifname, id, "key_mgmt", "NONE") < 0)
2316 return -2;
2317
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002318 if (dut->program == PROGRAM_60GHZ && network_mode &&
2319 strcasecmp(network_mode, "PBSS") == 0 &&
2320 set_network(ifname, id, "pbss", "1") < 0)
2321 return -2;
2322
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002323 return 1;
2324}
2325
2326
Jouni Malinen47dcc952017-10-09 16:43:24 +03002327static int sta_set_owe(struct sigma_dut *dut, struct sigma_conn *conn,
2328 struct sigma_cmd *cmd)
2329{
2330 const char *intf = get_param(cmd, "Interface");
2331 const char *ifname, *val;
2332 int id;
2333
2334 if (intf == NULL)
2335 return -1;
2336
2337 if (strcmp(intf, get_main_ifname()) == 0)
2338 ifname = get_station_ifname();
2339 else
2340 ifname = intf;
2341
2342 id = set_wpa_common(dut, conn, ifname, cmd);
2343 if (id < 0)
2344 return id;
2345
2346 if (set_network(ifname, id, "key_mgmt", "OWE") < 0)
2347 return -2;
2348
2349 val = get_param(cmd, "ECGroupID");
Jouni Malinenfac9cad2017-10-10 18:35:55 +03002350 if (val && strcmp(val, "0") == 0) {
2351 if (wpa_command(ifname,
2352 "VENDOR_ELEM_ADD 13 ff23200000783590fb7440e03d5b3b33911f86affdcc6b4411b707846ac4ff08ddc8831ccd") != 0) {
2353 sigma_dut_print(dut, DUT_MSG_ERROR,
2354 "Failed to set OWE DH Param element override");
2355 return -2;
2356 }
2357 } else if (val && set_network(ifname, id, "owe_group", val) < 0) {
Jouni Malinen47dcc952017-10-09 16:43:24 +03002358 sigma_dut_print(dut, DUT_MSG_ERROR,
2359 "Failed to clear owe_group");
2360 return -2;
2361 }
2362
2363 return 1;
2364}
2365
2366
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002367static int cmd_sta_set_security(struct sigma_dut *dut, struct sigma_conn *conn,
2368 struct sigma_cmd *cmd)
2369{
2370 const char *type = get_param(cmd, "Type");
2371
2372 if (type == NULL) {
2373 send_resp(dut, conn, SIGMA_ERROR,
2374 "ErrorCode,Missing Type argument");
2375 return 0;
2376 }
2377
2378 if (strcasecmp(type, "OPEN") == 0)
2379 return sta_set_open(dut, conn, cmd);
Jouni Malinen47dcc952017-10-09 16:43:24 +03002380 if (strcasecmp(type, "OWE") == 0)
2381 return sta_set_owe(dut, conn, cmd);
Jouni Malinen992a81e2017-08-22 13:57:47 +03002382 if (strcasecmp(type, "PSK") == 0 ||
Jouni Malinen0ab50f42017-08-31 01:34:59 +03002383 strcasecmp(type, "PSK-SAE") == 0 ||
Jouni Malinen992a81e2017-08-22 13:57:47 +03002384 strcasecmp(type, "SAE") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002385 return cmd_sta_set_psk(dut, conn, cmd);
2386 if (strcasecmp(type, "EAPTLS") == 0)
2387 return cmd_sta_set_eaptls(dut, conn, cmd);
2388 if (strcasecmp(type, "EAPTTLS") == 0)
2389 return cmd_sta_set_eapttls(dut, conn, cmd);
2390 if (strcasecmp(type, "EAPPEAP") == 0)
2391 return cmd_sta_set_peap(dut, conn, cmd);
2392 if (strcasecmp(type, "EAPSIM") == 0)
2393 return cmd_sta_set_eapsim(dut, conn, cmd);
2394 if (strcasecmp(type, "EAPFAST") == 0)
2395 return cmd_sta_set_eapfast(dut, conn, cmd);
2396 if (strcasecmp(type, "EAPAKA") == 0)
2397 return cmd_sta_set_eapaka(dut, conn, cmd);
2398 if (strcasecmp(type, "EAPAKAPRIME") == 0)
2399 return cmd_sta_set_eapakaprime(dut, conn, cmd);
Amarnath Hullur Subramanyam81b11cd2018-01-30 19:07:17 -08002400 if (strcasecmp(type, "wep") == 0)
2401 return cmd_sta_set_encryption(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002402
2403 send_resp(dut, conn, SIGMA_ERROR,
2404 "ErrorCode,Unsupported Type value");
2405 return 0;
2406}
2407
2408
2409int ath6kl_client_uapsd(struct sigma_dut *dut, const char *intf, int uapsd)
2410{
2411#ifdef __linux__
2412 /* special handling for ath6kl */
2413 char path[128], fname[128], *pos;
2414 ssize_t res;
2415 FILE *f;
2416
2417 snprintf(path, sizeof(path), "/sys/class/net/%s/phy80211", intf);
2418 res = readlink(path, path, sizeof(path));
2419 if (res < 0)
2420 return 0; /* not ath6kl */
2421
2422 if (res >= (int) sizeof(path))
2423 res = sizeof(path) - 1;
2424 path[res] = '\0';
2425 pos = strrchr(path, '/');
2426 if (pos == NULL)
2427 pos = path;
2428 else
2429 pos++;
2430 snprintf(fname, sizeof(fname),
2431 "/sys/kernel/debug/ieee80211/%s/ath6kl/"
2432 "create_qos", pos);
2433 if (!file_exists(fname))
2434 return 0; /* not ath6kl */
2435
2436 if (uapsd) {
2437 f = fopen(fname, "w");
2438 if (f == NULL)
2439 return -1;
2440
2441 sigma_dut_print(dut, DUT_MSG_DEBUG, "Use ath6kl create_qos");
2442 fprintf(f, "4 2 2 1 2 9999999 9999999 9999999 7777777 0 4 "
2443 "45000 200 56789000 56789000 5678900 0 0 9999999 "
2444 "20000 0\n");
2445 fclose(f);
2446 } else {
2447 snprintf(fname, sizeof(fname),
2448 "/sys/kernel/debug/ieee80211/%s/ath6kl/"
2449 "delete_qos", pos);
2450
2451 f = fopen(fname, "w");
2452 if (f == NULL)
2453 return -1;
2454
2455 sigma_dut_print(dut, DUT_MSG_DEBUG, "Use ath6kl delete_qos");
2456 fprintf(f, "2 4\n");
2457 fclose(f);
2458 }
2459#endif /* __linux__ */
2460
2461 return 0;
2462}
2463
2464
2465static int cmd_sta_set_uapsd(struct sigma_dut *dut, struct sigma_conn *conn,
2466 struct sigma_cmd *cmd)
2467{
2468 const char *intf = get_param(cmd, "Interface");
2469 /* const char *ssid = get_param(cmd, "ssid"); */
2470 const char *val;
2471 int max_sp_len = 4;
2472 int ac_be = 1, ac_bk = 1, ac_vi = 1, ac_vo = 1;
2473 char buf[100];
2474 int ret1, ret2;
2475
2476 val = get_param(cmd, "maxSPLength");
2477 if (val) {
2478 max_sp_len = atoi(val);
2479 if (max_sp_len != 0 && max_sp_len != 1 && max_sp_len != 2 &&
2480 max_sp_len != 4)
2481 return -1;
2482 }
2483
2484 val = get_param(cmd, "acBE");
2485 if (val)
2486 ac_be = atoi(val);
2487
2488 val = get_param(cmd, "acBK");
2489 if (val)
2490 ac_bk = atoi(val);
2491
2492 val = get_param(cmd, "acVI");
2493 if (val)
2494 ac_vi = atoi(val);
2495
2496 val = get_param(cmd, "acVO");
2497 if (val)
2498 ac_vo = atoi(val);
2499
2500 dut->client_uapsd = ac_be || ac_bk || ac_vi || ac_vo;
2501
2502 snprintf(buf, sizeof(buf), "P2P_SET client_apsd %d,%d,%d,%d;%d",
2503 ac_be, ac_bk, ac_vi, ac_vo, max_sp_len);
2504 ret1 = wpa_command(intf, buf);
2505
2506 snprintf(buf, sizeof(buf), "SET uapsd %d,%d,%d,%d;%d",
2507 ac_be, ac_bk, ac_vi, ac_vo, max_sp_len);
2508 ret2 = wpa_command(intf, buf);
2509
2510 if (ret1 && ret2) {
2511 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to set client mode "
2512 "UAPSD parameters.");
2513 return -2;
2514 }
2515
2516 if (ath6kl_client_uapsd(dut, intf, dut->client_uapsd) < 0) {
2517 send_resp(dut, conn, SIGMA_ERROR,
2518 "ErrorCode,Failed to set ath6kl QoS parameters");
2519 return 0;
2520 }
2521
2522 return 1;
2523}
2524
2525
2526static int cmd_sta_set_wmm(struct sigma_dut *dut, struct sigma_conn *conn,
2527 struct sigma_cmd *cmd)
2528{
2529 char buf[1000];
2530 const char *intf = get_param(cmd, "Interface");
2531 const char *grp = get_param(cmd, "Group");
2532 const char *act = get_param(cmd, "Action");
2533 const char *tid = get_param(cmd, "Tid");
2534 const char *dir = get_param(cmd, "Direction");
2535 const char *psb = get_param(cmd, "Psb");
2536 const char *up = get_param(cmd, "Up");
2537 const char *fixed = get_param(cmd, "Fixed");
2538 const char *size = get_param(cmd, "Size");
2539 const char *msize = get_param(cmd, "Maxsize");
2540 const char *minsi = get_param(cmd, "Min_srvc_intrvl");
2541 const char *maxsi = get_param(cmd, "Max_srvc_intrvl");
2542 const char *inact = get_param(cmd, "Inactivity");
2543 const char *sus = get_param(cmd, "Suspension");
2544 const char *mindr = get_param(cmd, "Mindatarate");
2545 const char *meandr = get_param(cmd, "Meandatarate");
2546 const char *peakdr = get_param(cmd, "Peakdatarate");
2547 const char *phyrate = get_param(cmd, "Phyrate");
2548 const char *burstsize = get_param(cmd, "Burstsize");
2549 const char *sba = get_param(cmd, "Sba");
2550 int direction;
2551 int handle;
Peng Xu93319622017-10-04 17:58:16 -07002552 float sba_fv = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002553 int fixed_int;
2554 int psb_ts;
2555
2556 if (intf == NULL || grp == NULL || act == NULL )
2557 return -1;
2558
2559 if (strcasecmp(act, "addts") == 0) {
2560 if (tid == NULL || dir == NULL || psb == NULL ||
2561 up == NULL || fixed == NULL || size == NULL)
2562 return -1;
2563
2564 /*
2565 * Note: Sigma CAPI spec lists uplink, downlink, and bidi as the
2566 * possible values, but WMM-AC and V-E test scripts use "UP,
2567 * "DOWN", and "BIDI".
2568 */
2569 if (strcasecmp(dir, "uplink") == 0 ||
2570 strcasecmp(dir, "up") == 0) {
2571 direction = 0;
2572 } else if (strcasecmp(dir, "downlink") == 0 ||
2573 strcasecmp(dir, "down") == 0) {
2574 direction = 1;
2575 } else if (strcasecmp(dir, "bidi") == 0) {
2576 direction = 2;
2577 } else {
2578 sigma_dut_print(dut, DUT_MSG_ERROR,
2579 "Direction %s not supported", dir);
2580 return -1;
2581 }
2582
2583 if (strcasecmp(psb, "legacy") == 0) {
2584 psb_ts = 0;
2585 } else if (strcasecmp(psb, "uapsd") == 0) {
2586 psb_ts = 1;
2587 } else {
2588 sigma_dut_print(dut, DUT_MSG_ERROR,
2589 "PSB %s not supported", psb);
2590 return -1;
2591 }
2592
2593 if (atoi(tid) < 0 || atoi(tid) > 7) {
2594 sigma_dut_print(dut, DUT_MSG_ERROR,
2595 "TID %s not supported", tid);
2596 return -1;
2597 }
2598
2599 if (strcasecmp(fixed, "true") == 0) {
2600 fixed_int = 1;
2601 } else {
2602 fixed_int = 0;
2603 }
2604
Peng Xu93319622017-10-04 17:58:16 -07002605 if (sba)
2606 sba_fv = atof(sba);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002607
2608 dut->dialog_token++;
2609 handle = 7000 + dut->dialog_token;
2610
2611 /*
2612 * size: convert to hex
2613 * maxsi: convert to hex
2614 * mindr: convert to hex
2615 * meandr: convert to hex
2616 * peakdr: convert to hex
2617 * burstsize: convert to hex
2618 * phyrate: convert to hex
2619 * sba: convert to hex with modification
2620 * minsi: convert to integer
2621 * sus: convert to integer
2622 * inact: convert to integer
2623 * maxsi: convert to integer
2624 */
2625
2626 /*
2627 * The Nominal MSDU Size field is 2 octets long and contains an
2628 * unsigned integer that specifies the nominal size, in octets,
2629 * of MSDUs belonging to the traffic under this traffic
2630 * specification and is defined in Figure 16. If the Fixed
2631 * subfield is set to 1, then the size of the MSDU is fixed and
2632 * is indicated by the Size Subfield. If the Fixed subfield is
2633 * set to 0, then the size of the MSDU might not be fixed and
2634 * the Size indicates the nominal MSDU size.
2635 *
2636 * The Surplus Bandwidth Allowance Factor field is 2 octets long
2637 * and specifies the excess allocation of time (and bandwidth)
2638 * over and above the stated rates required to transport an MSDU
2639 * belonging to the traffic in this TSPEC. This field is
2640 * represented as an unsigned binary number with an implicit
2641 * binary point after the leftmost 3 bits. For example, an SBA
2642 * of 1.75 is represented as 0x3800. This field is included to
2643 * account for retransmissions. As such, the value of this field
2644 * must be greater than unity.
2645 */
2646
2647 snprintf(buf, sizeof(buf),
2648 "iwpriv %s addTspec %d %s %d %d %s 0x%X"
2649 " 0x%X 0x%X 0x%X"
2650 " 0x%X 0x%X 0x%X"
2651 " 0x%X %d %d %d %d"
2652 " %d %d",
2653 intf, handle, tid, direction, psb_ts, up,
2654 (unsigned int) ((fixed_int << 15) | atoi(size)),
2655 msize ? atoi(msize) : 0,
2656 mindr ? atoi(mindr) : 0,
2657 meandr ? atoi(meandr) : 0,
2658 peakdr ? atoi(peakdr) : 0,
2659 burstsize ? atoi(burstsize) : 0,
2660 phyrate ? atoi(phyrate) : 0,
2661 sba ? ((unsigned int) (((int) sba_fv << 13) |
2662 (int)((sba_fv - (int) sba_fv) *
2663 8192))) : 0,
2664 minsi ? atoi(minsi) : 0,
2665 sus ? atoi(sus) : 0,
2666 0, 0,
2667 inact ? atoi(inact) : 0,
2668 maxsi ? atoi(maxsi) : 0);
2669
2670 if (system(buf) != 0) {
2671 sigma_dut_print(dut, DUT_MSG_ERROR,
2672 "iwpriv addtspec request failed");
2673 send_resp(dut, conn, SIGMA_ERROR,
2674 "errorCode,Failed to execute addTspec command");
2675 return 0;
2676 }
2677
2678 sigma_dut_print(dut, DUT_MSG_INFO,
2679 "iwpriv addtspec request send");
2680
2681 /* Mapping handle to a TID */
2682 dut->tid_to_handle[atoi(tid)] = handle;
2683 } else if (strcasecmp(act, "delts") == 0) {
2684 if (tid == NULL)
2685 return -1;
2686
2687 if (atoi(tid) < 0 || atoi(tid) > 7) {
2688 sigma_dut_print(dut, DUT_MSG_ERROR,
2689 "TID %s not supported", tid);
2690 send_resp(dut, conn, SIGMA_ERROR,
2691 "errorCode,Unsupported TID");
2692 return 0;
2693 }
2694
2695 handle = dut->tid_to_handle[atoi(tid)];
2696
2697 if (handle < 7000 || handle > 7255) {
2698 /* Invalid handle ie no mapping for that TID */
2699 sigma_dut_print(dut, DUT_MSG_ERROR,
2700 "handle-> %d not found", handle);
2701 }
2702
2703 snprintf(buf, sizeof(buf), "iwpriv %s delTspec %d",
2704 intf, handle);
2705
2706 if (system(buf) != 0) {
2707 sigma_dut_print(dut, DUT_MSG_ERROR,
2708 "iwpriv deltspec request failed");
2709 send_resp(dut, conn, SIGMA_ERROR,
2710 "errorCode,Failed to execute delTspec command");
2711 return 0;
2712 }
2713
2714 sigma_dut_print(dut, DUT_MSG_INFO,
2715 "iwpriv deltspec request send");
2716
2717 dut->tid_to_handle[atoi(tid)] = 0;
2718 } else {
2719 sigma_dut_print(dut, DUT_MSG_ERROR,
2720 "Action type %s not supported", act);
2721 send_resp(dut, conn, SIGMA_ERROR,
2722 "errorCode,Unsupported Action");
2723 return 0;
2724 }
2725
2726 return 1;
2727}
2728
2729
vamsi krishna52e16f92017-08-29 12:37:34 +05302730static int find_network(struct sigma_dut *dut, const char *ssid)
2731{
2732 char list[4096];
2733 char *pos;
2734
2735 sigma_dut_print(dut, DUT_MSG_DEBUG,
2736 "Search for profile based on SSID: '%s'", ssid);
2737 if (wpa_command_resp(get_station_ifname(), "LIST_NETWORKS",
2738 list, sizeof(list)) < 0)
2739 return -1;
2740 pos = strstr(list, ssid);
2741 if (!pos || pos == list || pos[-1] != '\t' || pos[strlen(ssid)] != '\t')
2742 return -1;
2743
2744 while (pos > list && pos[-1] != '\n')
2745 pos--;
2746 dut->infra_network_id = atoi(pos);
2747 snprintf(dut->infra_ssid, sizeof(dut->infra_ssid), "%s", ssid);
2748 return 0;
2749}
2750
2751
Sunil Dutt44595082018-02-12 19:41:45 +05302752#ifdef NL80211_SUPPORT
2753static int sta_config_rsnie(struct sigma_dut *dut, int val)
2754{
2755 struct nl_msg *msg;
2756 int ret;
2757 struct nlattr *params;
2758 int ifindex;
2759
2760 ifindex = if_nametoindex("wlan0");
2761 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
2762 NL80211_CMD_VENDOR)) ||
2763 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
2764 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
2765 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
2766 QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION) ||
2767 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
2768 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE, val)) {
2769 sigma_dut_print(dut, DUT_MSG_ERROR,
2770 "%s: err in adding vendor_cmd and vendor_data",
2771 __func__);
2772 nlmsg_free(msg);
2773 return -1;
2774 }
2775 nla_nest_end(msg, params);
2776
2777 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
2778 if (ret) {
2779 sigma_dut_print(dut, DUT_MSG_ERROR,
2780 "%s: err in send_and_recv_msgs, ret=%d",
2781 __func__, ret);
2782 return ret;
2783 }
2784
2785 return 0;
2786}
2787#endif /* NL80211_SUPPORT */
2788
2789
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002790static int cmd_sta_associate(struct sigma_dut *dut, struct sigma_conn *conn,
2791 struct sigma_cmd *cmd)
2792{
2793 /* const char *intf = get_param(cmd, "Interface"); */
2794 const char *ssid = get_param(cmd, "ssid");
2795 const char *wps_param = get_param(cmd, "WPS");
2796 const char *bssid = get_param(cmd, "bssid");
Jouni Malinen46a19b62017-06-23 14:31:27 +03002797 const char *chan = get_param(cmd, "channel");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002798 const char *network_mode = get_param(cmd, "network_mode");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002799 int wps = 0;
Jouni Malinen3c367e82017-06-23 17:01:47 +03002800 char buf[1000], extra[50];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002801
2802 if (ssid == NULL)
2803 return -1;
2804
Jouni Malinen3c367e82017-06-23 17:01:47 +03002805 if (dut->rsne_override) {
Sunil Dutt44595082018-02-12 19:41:45 +05302806#ifdef NL80211_SUPPORT
2807 if (get_driver_type() == DRIVER_WCN) {
2808 sta_config_rsnie(dut, 1);
2809 dut->config_rsnie = 1;
2810 }
2811#endif /* NL80211_SUPPORT */
Jouni Malinen3c367e82017-06-23 17:01:47 +03002812 snprintf(buf, sizeof(buf), "TEST_ASSOC_IE %s",
2813 dut->rsne_override);
2814 if (wpa_command(get_station_ifname(), buf) < 0) {
2815 send_resp(dut, conn, SIGMA_ERROR,
2816 "ErrorCode,Failed to set DEV_CONFIGURE_IE RSNE override");
2817 return 0;
2818 }
2819 }
2820
Jouni Malinen68143132017-09-02 02:34:08 +03002821 if (dut->sae_commit_override) {
2822 snprintf(buf, sizeof(buf), "SET sae_commit_override %s",
2823 dut->sae_commit_override);
2824 if (wpa_command(get_station_ifname(), buf) < 0) {
2825 send_resp(dut, conn, SIGMA_ERROR,
2826 "ErrorCode,Failed to set SAE commit override");
2827 return 0;
2828 }
2829 }
Ankita Bajaj1bde7942018-01-09 19:15:01 +05302830#ifdef ANDROID
2831 if (dut->fils_hlp)
2832 process_fils_hlp(dut);
2833#endif /* ANDROID */
Jouni Malinen68143132017-09-02 02:34:08 +03002834
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002835 if (wps_param &&
2836 (strcmp(wps_param, "1") == 0 || strcasecmp(wps_param, "On") == 0))
2837 wps = 1;
2838
2839 if (wps) {
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002840 if (dut->program == PROGRAM_60GHZ && network_mode &&
2841 strcasecmp(network_mode, "PBSS") == 0 &&
2842 set_network(get_station_ifname(), dut->infra_network_id,
2843 "pbss", "1") < 0)
2844 return -2;
2845
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002846 if (dut->wps_method == WFA_CS_WPS_NOT_READY) {
2847 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,WPS "
2848 "parameters not yet set");
2849 return 0;
2850 }
2851 if (dut->wps_method == WFA_CS_WPS_PBC) {
2852 if (wpa_command(get_station_ifname(), "WPS_PBC") < 0)
2853 return -2;
2854 } else {
2855 snprintf(buf, sizeof(buf), "WPS_PIN any %s",
2856 dut->wps_pin);
2857 if (wpa_command(get_station_ifname(), buf) < 0)
2858 return -2;
2859 }
2860 } else {
vamsi krishna52e16f92017-08-29 12:37:34 +05302861 if (strcmp(ssid, dut->infra_ssid) == 0) {
2862 sigma_dut_print(dut, DUT_MSG_DEBUG,
2863 "sta_associate for the most recently added network");
2864 } else if (find_network(dut, ssid) < 0) {
2865 sigma_dut_print(dut, DUT_MSG_DEBUG,
2866 "sta_associate for a previously stored network profile");
2867 send_resp(dut, conn, SIGMA_ERROR,
2868 "ErrorCode,Profile not found");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002869 return 0;
2870 }
2871
2872 if (bssid &&
2873 set_network(get_station_ifname(), dut->infra_network_id,
2874 "bssid", bssid) < 0) {
2875 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
2876 "Invalid bssid argument");
2877 return 0;
2878 }
2879
Jouni Malinen46a19b62017-06-23 14:31:27 +03002880 extra[0] = '\0';
2881 if (chan)
2882 snprintf(extra, sizeof(extra), " freq=%u",
Alexei Avshalom Lazar093569f2018-11-13 14:08:17 +02002883 channel_to_freq(dut, atoi(chan)));
Jouni Malinen46a19b62017-06-23 14:31:27 +03002884 snprintf(buf, sizeof(buf), "SELECT_NETWORK %d%s",
2885 dut->infra_network_id, extra);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002886 if (wpa_command(get_station_ifname(), buf) < 0) {
2887 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to select "
2888 "network id %d on %s",
2889 dut->infra_network_id,
2890 get_station_ifname());
2891 return -2;
2892 }
2893 }
2894
2895 return 1;
2896}
2897
2898
2899static int run_hs20_osu(struct sigma_dut *dut, const char *params)
2900{
2901 char buf[500], cmd[200];
2902 int res;
2903
2904 /* Use hs20-osu-client file at the current dir, if found; otherwise use
2905 * default path */
2906 res = snprintf(cmd, sizeof(cmd),
2907 "%s -w \"%s\" -r hs20-osu-client.res %s%s -dddKt -f Logs/hs20-osu-client.txt",
2908 file_exists("./hs20-osu-client") ?
2909 "./hs20-osu-client" : "hs20-osu-client",
2910 sigma_wpas_ctrl,
2911 dut->summary_log ? "-s " : "",
2912 dut->summary_log ? dut->summary_log : "");
2913 if (res < 0 || res >= (int) sizeof(cmd))
2914 return -1;
2915
2916 res = snprintf(buf, sizeof(buf), "%s %s", cmd, params);
2917 if (res < 0 || res >= (int) sizeof(buf))
2918 return -1;
2919 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
2920
2921 if (system(buf) != 0) {
2922 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to run: %s", buf);
2923 return -1;
2924 }
2925 sigma_dut_print(dut, DUT_MSG_DEBUG,
2926 "Completed hs20-osu-client operation");
2927
2928 return 0;
2929}
2930
2931
2932static int download_ppsmo(struct sigma_dut *dut,
2933 struct sigma_conn *conn,
2934 const char *intf,
2935 struct sigma_cmd *cmd)
2936{
2937 const char *name, *path, *val;
2938 char url[500], buf[600], fbuf[100];
2939 char *fqdn = NULL;
2940
2941 name = get_param(cmd, "FileName");
2942 path = get_param(cmd, "FilePath");
2943 if (name == NULL || path == NULL)
2944 return -1;
2945
2946 if (strcasecmp(path, "VendorSpecific") == 0) {
2947 snprintf(url, sizeof(url), "PPS/%s", name);
2948 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured PPS MO "
2949 "from the device (%s)", url);
2950 if (!file_exists(url)) {
2951 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
2952 "PPS MO file does not exist");
2953 return 0;
2954 }
2955 snprintf(buf, sizeof(buf), "cp %s pps-tnds.xml", url);
2956 if (system(buf) != 0) {
2957 send_resp(dut, conn, SIGMA_ERROR,
2958 "errorCode,Failed to copy PPS MO");
2959 return 0;
2960 }
2961 } else if (strncasecmp(path, "http:", 5) != 0 &&
2962 strncasecmp(path, "https:", 6) != 0) {
2963 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
2964 "Unsupported FilePath value");
2965 return 0;
2966 } else {
2967 snprintf(url, sizeof(url), "%s/%s", path, name);
2968 sigma_dut_print(dut, DUT_MSG_INFO, "Downloading PPS MO from %s",
2969 url);
2970 snprintf(buf, sizeof(buf), "wget -T 10 -t 3 -O pps-tnds.xml '%s'", url);
2971 remove("pps-tnds.xml");
2972 if (system(buf) != 0) {
2973 send_resp(dut, conn, SIGMA_ERROR,
2974 "errorCode,Failed to download PPS MO");
2975 return 0;
2976 }
2977 }
2978
2979 if (run_hs20_osu(dut, "from_tnds pps-tnds.xml pps.xml") < 0) {
2980 send_resp(dut, conn, SIGMA_ERROR,
2981 "errorCode,Failed to parse downloaded PPSMO");
2982 return 0;
2983 }
2984 unlink("pps-tnds.xml");
2985
2986 val = get_param(cmd, "managementTreeURI");
2987 if (val) {
2988 const char *pos, *end;
2989 sigma_dut_print(dut, DUT_MSG_DEBUG, "managementTreeURI: %s",
2990 val);
2991 if (strncmp(val, "./Wi-Fi/", 8) != 0) {
2992 send_resp(dut, conn, SIGMA_ERROR,
2993 "errorCode,Invalid managementTreeURI prefix");
2994 return 0;
2995 }
2996 pos = val + 8;
2997 end = strchr(pos, '/');
2998 if (end == NULL ||
2999 strcmp(end, "/PerProviderSubscription") != 0) {
3000 send_resp(dut, conn, SIGMA_ERROR,
3001 "errorCode,Invalid managementTreeURI postfix");
3002 return 0;
3003 }
3004 if (end - pos >= (int) sizeof(fbuf)) {
3005 send_resp(dut, conn, SIGMA_ERROR,
3006 "errorCode,Too long FQDN in managementTreeURI");
3007 return 0;
3008 }
3009 memcpy(fbuf, pos, end - pos);
3010 fbuf[end - pos] = '\0';
3011 fqdn = fbuf;
3012 sigma_dut_print(dut, DUT_MSG_INFO,
3013 "FQDN from managementTreeURI: %s", fqdn);
3014 } else if (run_hs20_osu(dut, "get_fqdn pps.xml") == 0) {
3015 FILE *f = fopen("pps-fqdn", "r");
3016 if (f) {
3017 if (fgets(fbuf, sizeof(fbuf), f)) {
3018 fbuf[sizeof(fbuf) - 1] = '\0';
3019 fqdn = fbuf;
3020 sigma_dut_print(dut, DUT_MSG_DEBUG,
3021 "Use FQDN %s", fqdn);
3022 }
3023 fclose(f);
3024 }
3025 }
3026
3027 if (fqdn == NULL) {
3028 send_resp(dut, conn, SIGMA_ERROR,
3029 "errorCode,No FQDN specified");
3030 return 0;
3031 }
3032
3033 mkdir("SP", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
3034 snprintf(buf, sizeof(buf), "SP/%s", fqdn);
3035 mkdir(buf, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
3036
3037 snprintf(buf, sizeof(buf), "SP/%s/pps.xml", fqdn);
3038 if (rename("pps.xml", buf) < 0) {
3039 send_resp(dut, conn, SIGMA_ERROR,
3040 "errorCode,Could not move PPS MO");
3041 return 0;
3042 }
3043
3044 if (strcasecmp(path, "VendorSpecific") == 0) {
3045 snprintf(buf, sizeof(buf), "cp Certs/ca.pem SP/%s/ca.pem",
3046 fqdn);
3047 if (system(buf)) {
3048 send_resp(dut, conn, SIGMA_ERROR,
3049 "errorCode,Failed to copy OSU CA cert");
3050 return 0;
3051 }
3052
3053 snprintf(buf, sizeof(buf),
3054 "cp Certs/aaa-ca.pem SP/%s/aaa-ca.pem",
3055 fqdn);
3056 if (system(buf)) {
3057 send_resp(dut, conn, SIGMA_ERROR,
3058 "errorCode,Failed to copy AAA CA cert");
3059 return 0;
3060 }
3061 } else {
3062 snprintf(buf, sizeof(buf),
3063 "dl_osu_ca SP/%s/pps.xml SP/%s/ca.pem",
3064 fqdn, fqdn);
3065 if (run_hs20_osu(dut, buf) < 0) {
3066 send_resp(dut, conn, SIGMA_ERROR,
3067 "errorCode,Failed to download OSU CA cert");
3068 return 0;
3069 }
3070
3071 snprintf(buf, sizeof(buf),
3072 "dl_aaa_ca SP/%s/pps.xml SP/%s/aaa-ca.pem",
3073 fqdn, fqdn);
3074 if (run_hs20_osu(dut, buf) < 0) {
3075 sigma_dut_print(dut, DUT_MSG_INFO,
3076 "Failed to download AAA CA cert");
3077 }
3078 }
3079
3080 if (file_exists("next-client-cert.pem")) {
3081 snprintf(buf, sizeof(buf), "SP/%s/client-cert.pem", fqdn);
3082 if (rename("next-client-cert.pem", buf) < 0) {
3083 send_resp(dut, conn, SIGMA_ERROR,
3084 "errorCode,Could not move client certificate");
3085 return 0;
3086 }
3087 }
3088
3089 if (file_exists("next-client-key.pem")) {
3090 snprintf(buf, sizeof(buf), "SP/%s/client-key.pem", fqdn);
3091 if (rename("next-client-key.pem", buf) < 0) {
3092 send_resp(dut, conn, SIGMA_ERROR,
3093 "errorCode,Could not move client key");
3094 return 0;
3095 }
3096 }
3097
3098 snprintf(buf, sizeof(buf), "set_pps SP/%s/pps.xml", fqdn);
3099 if (run_hs20_osu(dut, buf) < 0) {
3100 send_resp(dut, conn, SIGMA_ERROR,
3101 "errorCode,Failed to configure credential from "
3102 "PPSMO");
3103 return 0;
3104 }
3105
3106 return 1;
3107}
3108
3109
3110static int download_cert(struct sigma_dut *dut,
3111 struct sigma_conn *conn,
3112 const char *intf,
3113 struct sigma_cmd *cmd)
3114{
3115 const char *name, *path;
3116 char url[500], buf[600];
3117
3118 name = get_param(cmd, "FileName");
3119 path = get_param(cmd, "FilePath");
3120 if (name == NULL || path == NULL)
3121 return -1;
3122
3123 if (strcasecmp(path, "VendorSpecific") == 0) {
3124 snprintf(url, sizeof(url), "Certs/%s-cert.pem", name);
3125 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured client "
3126 "certificate from the device (%s)", url);
3127 if (!file_exists(url)) {
3128 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
3129 "certificate file does not exist");
3130 return 0;
3131 }
3132 snprintf(buf, sizeof(buf), "cp %s next-client-cert.pem", url);
3133 if (system(buf) != 0) {
3134 send_resp(dut, conn, SIGMA_ERROR,
3135 "errorCode,Failed to copy client "
3136 "certificate");
3137 return 0;
3138 }
3139
3140 snprintf(url, sizeof(url), "Certs/%s-key.pem", name);
3141 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured client "
3142 "private key from the device (%s)", url);
3143 if (!file_exists(url)) {
3144 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
3145 "private key file does not exist");
3146 return 0;
3147 }
3148 snprintf(buf, sizeof(buf), "cp %s next-client-key.pem", url);
3149 if (system(buf) != 0) {
3150 send_resp(dut, conn, SIGMA_ERROR,
3151 "errorCode,Failed to copy client key");
3152 return 0;
3153 }
3154 } else if (strncasecmp(path, "http:", 5) != 0 &&
3155 strncasecmp(path, "https:", 6) != 0) {
3156 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
3157 "Unsupported FilePath value");
3158 return 0;
3159 } else {
3160 snprintf(url, sizeof(url), "%s/%s.pem", path, name);
3161 sigma_dut_print(dut, DUT_MSG_INFO, "Downloading client "
3162 "certificate/key from %s", url);
3163 snprintf(buf, sizeof(buf),
3164 "wget -T 10 -t 3 -O next-client-cert.pem '%s'", url);
3165 if (system(buf) != 0) {
3166 send_resp(dut, conn, SIGMA_ERROR,
3167 "errorCode,Failed to download client "
3168 "certificate");
3169 return 0;
3170 }
3171
3172 if (system("cp next-client-cert.pem next-client-key.pem") != 0)
3173 {
3174 send_resp(dut, conn, SIGMA_ERROR,
3175 "errorCode,Failed to copy client key");
3176 return 0;
3177 }
3178 }
3179
3180 return 1;
3181}
3182
3183
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02003184static int cmd_sta_preset_testparameters_60ghz(struct sigma_dut *dut,
3185 struct sigma_conn *conn,
3186 struct sigma_cmd *cmd)
3187{
3188 const char *val;
3189 const char *intf = get_param(cmd, "interface");
3190
3191 if (!intf)
3192 return -1;
3193
3194 val = get_param(cmd, "WscIEFragment");
3195 if (val && strcasecmp(val, "enable") == 0) {
3196 sigma_dut_print(dut, DUT_MSG_DEBUG,
3197 "Enable WSC IE fragmentation");
3198
3199 dut->wsc_fragment = 1;
3200 /* set long attributes to force fragmentation */
3201 if (wpa_command(intf, "SET device_name "
3202 WPS_LONG_DEVICE_NAME) < 0)
3203 return -2;
3204 if (wpa_command(intf, "SET manufacturer "
3205 WPS_LONG_MANUFACTURER) < 0)
3206 return -2;
3207 if (wpa_command(intf, "SET model_name "
3208 WPS_LONG_MODEL_NAME) < 0)
3209 return -2;
3210 if (wpa_command(intf, "SET model_number "
3211 WPS_LONG_MODEL_NUMBER) < 0)
3212 return -2;
3213 if (wpa_command(intf, "SET serial_number "
3214 WPS_LONG_SERIAL_NUMBER) < 0)
3215 return -2;
3216 }
3217
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02003218 val = get_param(cmd, "RSN_IE");
3219 if (val) {
3220 if (strcasecmp(val, "disable") == 0)
3221 dut->force_rsn_ie = FORCE_RSN_IE_REMOVE;
3222 else if (strcasecmp(val, "enable") == 0)
3223 dut->force_rsn_ie = FORCE_RSN_IE_ADD;
3224 }
3225
Alexei Avshalom Lazar744ae8a2019-01-31 17:26:46 +02003226 val = get_param(cmd, "WpsVersion");
3227 if (val)
3228 dut->wps_forced_version = get_wps_forced_version(dut, val);
3229
Alexei Avshalom Lazar2eccf4d2019-01-31 10:03:59 +02003230 val = get_param(cmd, "WscEAPFragment");
3231 if (val && strcasecmp(val, "enable") == 0)
3232 dut->eap_fragment = 1;
3233
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02003234 return 1;
3235}
3236
3237
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003238static int cmd_sta_preset_testparameters_hs2_r2(struct sigma_dut *dut,
3239 struct sigma_conn *conn,
3240 const char *intf,
3241 struct sigma_cmd *cmd)
3242{
3243 const char *val;
3244
3245 val = get_param(cmd, "FileType");
3246 if (val && strcasecmp(val, "PPSMO") == 0)
3247 return download_ppsmo(dut, conn, intf, cmd);
3248 if (val && strcasecmp(val, "CERT") == 0)
3249 return download_cert(dut, conn, intf, cmd);
3250 if (val) {
3251 send_resp(dut, conn, SIGMA_ERROR,
3252 "ErrorCode,Unsupported FileType");
3253 return 0;
3254 }
3255
3256 return 1;
3257}
3258
3259
Ankita Bajaja2cb5672017-10-25 16:08:28 +05303260static int cmd_sta_preset_testparameters_oce(struct sigma_dut *dut,
3261 struct sigma_conn *conn,
3262 const char *intf,
3263 struct sigma_cmd *cmd)
3264{
3265 const char *val;
Ankita Bajaj1bde7942018-01-09 19:15:01 +05303266 char buf[1000];
3267 char text[20];
3268 unsigned char addr[ETH_ALEN];
Ankita Bajaja2cb5672017-10-25 16:08:28 +05303269
3270 val = get_param(cmd, "OCESupport");
3271 if (val && strcasecmp(val, "Disable") == 0) {
3272 if (wpa_command(intf, "SET oce 0") < 0) {
3273 send_resp(dut, conn, SIGMA_ERROR,
3274 "ErrorCode,Failed to disable OCE");
3275 return 0;
3276 }
3277 } else if (val && strcasecmp(val, "Enable") == 0) {
3278 if (wpa_command(intf, "SET oce 1") < 0) {
3279 send_resp(dut, conn, SIGMA_ERROR,
3280 "ErrorCode,Failed to enable OCE");
3281 return 0;
3282 }
3283 }
3284
vamsi krishnaa2799492017-12-05 14:28:01 +05303285 val = get_param(cmd, "FILScap");
3286 if (val && (atoi(val) == 1)) {
3287 if (wpa_command(intf, "SET disable_fils 0") < 0) {
3288 send_resp(dut, conn, SIGMA_ERROR,
3289 "ErrorCode,Failed to enable FILS");
3290 return 0;
3291 }
3292 } else if (val && (atoi(val) == 0)) {
3293 if (wpa_command(intf, "SET disable_fils 1") < 0) {
3294 send_resp(dut, conn, SIGMA_ERROR,
3295 "ErrorCode,Failed to disable FILS");
3296 return 0;
3297 }
3298 }
3299
Ankita Bajaj1bde7942018-01-09 19:15:01 +05303300 val = get_param(cmd, "FILSHLP");
3301 if (val && strcasecmp(val, "Enable") == 0) {
3302 if (get_wpa_status(get_station_ifname(), "address", text,
3303 sizeof(text)) < 0)
3304 return -2;
3305 hwaddr_aton(text, addr);
3306 snprintf(buf, sizeof(buf),
3307 "FILS_HLP_REQ_ADD ff:ff:ff:ff:ff:ff "
3308 "080045100140000040004011399e00000000ffffffff00440043"
3309 "012cb30001010600fd4f46410000000000000000000000000000"
3310 "000000000000"
3311 "%02x%02x%02x%02x%02x%02x"
3312 "0000000000000000000000000000000000000000000000000000"
3313 "0000000000000000000000000000000000000000000000000000"
3314 "0000000000000000000000000000000000000000000000000000"
3315 "0000000000000000000000000000000000000000000000000000"
3316 "0000000000000000000000000000000000000000000000000000"
3317 "0000000000000000000000000000000000000000000000000000"
3318 "0000000000000000000000000000000000000000000000000000"
3319 "0000000000000000000000000000000000000000638253633501"
3320 "013d0701000af549d29b390205dc3c12616e64726f69642d6468"
3321 "63702d382e302e30370a0103060f1a1c333a3b2b5000ff00",
3322 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
3323 if (wpa_command(intf, buf)) {
3324 send_resp(dut, conn, SIGMA_ERROR,
3325 "ErrorCode,Failed to add HLP");
3326 return 0;
3327 }
3328 dut->fils_hlp = 1;
3329 }
3330
Ankita Bajaja2cb5672017-10-25 16:08:28 +05303331 return 1;
3332}
3333
3334
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003335static void ath_sta_set_noack(struct sigma_dut *dut, const char *intf,
3336 const char *val)
3337{
3338 int counter = 0;
3339 char token[50];
3340 char *result;
3341 char buf[100];
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05303342 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003343
Peng Xub8fc5cc2017-05-10 17:27:28 -07003344 strlcpy(token, val, sizeof(token));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003345 token[sizeof(token) - 1] = '\0';
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05303346 result = strtok_r(token, ":", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003347 while (result) {
3348 if (strcmp(result, "disable") == 0) {
3349 snprintf(buf, sizeof(buf),
3350 "iwpriv %s noackpolicy %d 1 0",
3351 intf, counter);
3352 } else {
3353 snprintf(buf, sizeof(buf),
3354 "iwpriv %s noackpolicy %d 1 1",
3355 intf, counter);
3356 }
3357 if (system(buf) != 0) {
3358 sigma_dut_print(dut, DUT_MSG_ERROR,
3359 "iwpriv noackpolicy failed");
3360 }
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05303361 result = strtok_r(NULL, ":", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003362 counter++;
3363 }
3364}
3365
3366
3367static void ath_sta_set_rts(struct sigma_dut *dut, const char *intf,
3368 const char *val)
3369{
3370 char buf[100];
3371
3372 snprintf(buf, sizeof(buf), "iwconfig %s rts %s", intf, val);
3373 if (system(buf) != 0) {
3374 sigma_dut_print(dut, DUT_MSG_ERROR, "iwconfig RTS failed");
3375 }
3376}
3377
3378
3379static void ath_sta_set_wmm(struct sigma_dut *dut, const char *intf,
3380 const char *val)
3381{
3382 char buf[100];
3383
3384 if (strcasecmp(val, "off") == 0) {
3385 snprintf(buf, sizeof(buf), "iwpriv %s wmm 0", intf);
3386 if (system(buf) != 0) {
3387 sigma_dut_print(dut, DUT_MSG_ERROR,
3388 "Failed to turn off WMM");
3389 }
3390 }
3391}
3392
3393
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08003394static int wcn_sta_set_wmm(struct sigma_dut *dut, const char *intf,
3395 const char *val)
3396{
3397#ifdef NL80211_SUPPORT
3398 struct nl_msg *msg;
3399 int ret = 0;
3400 struct nlattr *params;
3401 int ifindex;
3402 int wmmenable = 1;
3403
3404 if (val &&
3405 (strcasecmp(val, "off") == 0 || strcmp(val, "0") == 0))
3406 wmmenable = 0;
3407
3408 ifindex = if_nametoindex(intf);
3409 if (ifindex == 0) {
3410 sigma_dut_print(dut, DUT_MSG_ERROR,
3411 "%s: Index for interface %s failed",
3412 __func__, intf);
3413 return -1;
3414 }
3415
3416 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
3417 NL80211_CMD_VENDOR)) ||
3418 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
3419 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
3420 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
3421 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
3422 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
3423 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WMM_ENABLE,
3424 wmmenable)) {
3425 sigma_dut_print(dut, DUT_MSG_ERROR,
3426 "%s: err in adding vendor_cmd and vendor_data",
3427 __func__);
3428 nlmsg_free(msg);
3429 return -1;
3430 }
3431 nla_nest_end(msg, params);
3432
3433 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
3434 if (ret) {
3435 sigma_dut_print(dut, DUT_MSG_ERROR,
3436 "%s: err in send_and_recv_msgs, ret=%d",
3437 __func__, ret);
3438 }
3439 return ret;
3440#else /* NL80211_SUPPORT */
3441 sigma_dut_print(dut, DUT_MSG_ERROR,
3442 "WMM cannot be changed without NL80211_SUPPORT defined");
3443 return -1;
3444#endif /* NL80211_SUPPORT */
3445}
3446
3447
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003448static void ath_sta_set_sgi(struct sigma_dut *dut, const char *intf,
3449 const char *val)
3450{
3451 char buf[100];
3452 int sgi20;
3453
3454 sgi20 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
3455
3456 snprintf(buf, sizeof(buf), "iwpriv %s shortgi %d", intf, sgi20);
3457 if (system(buf) != 0)
3458 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv shortgi failed");
3459}
3460
3461
3462static void ath_sta_set_11nrates(struct sigma_dut *dut, const char *intf,
3463 const char *val)
3464{
3465 char buf[100];
Pradeep Reddy POTTETI67376b72016-10-25 20:08:17 +05303466 int rate_code, v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003467
3468 /* Disable Tx Beam forming when using a fixed rate */
3469 ath_disable_txbf(dut, intf);
3470
Pradeep Reddy POTTETI67376b72016-10-25 20:08:17 +05303471 v = atoi(val);
3472 if (v < 0 || v > 32) {
3473 sigma_dut_print(dut, DUT_MSG_ERROR,
3474 "Invalid Fixed MCS rate: %d", v);
3475 return;
3476 }
3477 rate_code = 0x80 + v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003478
3479 snprintf(buf, sizeof(buf), "iwpriv %s set11NRates 0x%x",
3480 intf, rate_code);
3481 if (system(buf) != 0) {
3482 sigma_dut_print(dut, DUT_MSG_ERROR,
3483 "iwpriv set11NRates failed");
3484 }
3485
3486 /* Channel width gets messed up, fix this */
3487 snprintf(buf, sizeof(buf), "iwpriv %s chwidth %d", intf, dut->chwidth);
3488 if (system(buf) != 0)
3489 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv chwidth failed");
3490}
3491
3492
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08003493static void iwpriv_sta_set_amsdu(struct sigma_dut *dut, const char *intf,
3494 const char *val)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003495{
3496 char buf[60];
3497
3498 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)
3499 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 2", intf);
3500 else
3501 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 1", intf);
3502
3503 if (system(buf) != 0)
3504 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv amsdu failed");
3505}
3506
3507
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07003508static int iwpriv_sta_set_ampdu(struct sigma_dut *dut, const char *intf,
3509 int ampdu)
3510{
3511 char buf[60];
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08003512 int maxaggregation = 63;
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07003513
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08003514 if (ampdu)
3515 ampdu = maxaggregation;
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07003516 snprintf(buf, sizeof(buf), "iwpriv %s ampdu %d", intf, ampdu);
3517 if (system(buf) != 0) {
3518 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv ampdu failed");
3519 return -1;
3520 }
3521
3522 return 0;
3523}
3524
3525
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003526static void ath_sta_set_stbc(struct sigma_dut *dut, const char *intf,
3527 const char *val)
3528{
3529 char buf[60];
3530
3531 snprintf(buf, sizeof(buf), "iwpriv %s tx_stbc %s", intf, val);
3532 if (system(buf) != 0) {
3533 sigma_dut_print(dut, DUT_MSG_ERROR,
3534 "iwpriv tx_stbc failed");
3535 }
3536
3537 snprintf(buf, sizeof(buf), "iwpriv %s rx_stbc %s", intf, val);
3538 if (system(buf) != 0) {
3539 sigma_dut_print(dut, DUT_MSG_ERROR,
3540 "iwpriv rx_stbc failed");
3541 }
3542}
3543
3544
3545static int wcn_sta_set_cts_width(struct sigma_dut *dut, const char *intf,
3546 const char *val)
3547{
3548 char buf[60];
3549
Peng Xucc317ed2017-05-18 16:44:37 -07003550 if (strcmp(val, "160") == 0) {
3551 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 5", intf);
3552 } else if (strcmp(val, "80") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003553 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 3", intf);
3554 } else if (strcmp(val, "40") == 0) {
3555 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 2", intf);
3556 } else if (strcmp(val, "20") == 0) {
3557 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 1", intf);
3558 } else if (strcasecmp(val, "Auto") == 0) {
3559 buf[0] = '\0';
3560 } else {
3561 sigma_dut_print(dut, DUT_MSG_ERROR,
3562 "WIDTH/CTS_WIDTH value not supported");
3563 return -1;
3564 }
3565
3566 if (buf[0] != '\0' && system(buf) != 0) {
3567 sigma_dut_print(dut, DUT_MSG_ERROR,
3568 "Failed to set WIDTH/CTS_WIDTH");
3569 return -1;
3570 }
3571
3572 return 0;
3573}
3574
3575
3576int ath_set_width(struct sigma_dut *dut, struct sigma_conn *conn,
3577 const char *intf, const char *val)
3578{
3579 char buf[60];
3580
3581 if (strcasecmp(val, "Auto") == 0) {
3582 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 0", intf);
3583 dut->chwidth = 0;
3584 } else if (strcasecmp(val, "20") == 0) {
3585 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 0", intf);
3586 dut->chwidth = 0;
3587 } else if (strcasecmp(val, "40") == 0) {
3588 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 1", intf);
3589 dut->chwidth = 1;
3590 } else if (strcasecmp(val, "80") == 0) {
3591 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 2", intf);
3592 dut->chwidth = 2;
3593 } else if (strcasecmp(val, "160") == 0) {
3594 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 3", intf);
3595 dut->chwidth = 3;
3596 } else {
3597 send_resp(dut, conn, SIGMA_ERROR,
3598 "ErrorCode,WIDTH not supported");
3599 return -1;
3600 }
3601
3602 if (system(buf) != 0) {
3603 sigma_dut_print(dut, DUT_MSG_ERROR,
3604 "iwpriv chwidth failed");
3605 }
3606
3607 return 0;
3608}
3609
3610
3611static int wcn_sta_set_sp_stream(struct sigma_dut *dut, const char *intf,
3612 const char *val)
3613{
3614 char buf[60];
Arif Hussainac6c5112018-05-25 17:34:00 -07003615 int sta_nss;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003616
Amarnath Hullur Subramanyamd5374fa2018-02-25 19:00:24 -08003617 if (strcmp(val, "1SS") == 0 || strcmp(val, "1") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003618 snprintf(buf, sizeof(buf), "iwpriv %s nss 1", intf);
Arif Hussainac6c5112018-05-25 17:34:00 -07003619 sta_nss = 1;
Amarnath Hullur Subramanyamd5374fa2018-02-25 19:00:24 -08003620 } else if (strcmp(val, "2SS") == 0 || strcmp(val, "2") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003621 snprintf(buf, sizeof(buf), "iwpriv %s nss 2", intf);
Arif Hussainac6c5112018-05-25 17:34:00 -07003622 sta_nss = 2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003623 } else {
3624 sigma_dut_print(dut, DUT_MSG_ERROR,
3625 "SP_STREAM value not supported");
3626 return -1;
3627 }
3628
3629 if (system(buf) != 0) {
3630 sigma_dut_print(dut, DUT_MSG_ERROR,
3631 "Failed to set SP_STREAM");
3632 return -1;
3633 }
3634
Arif Hussainac6c5112018-05-25 17:34:00 -07003635 dut->sta_nss = sta_nss;
3636
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003637 return 0;
3638}
3639
3640
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05303641static void wcn_sta_set_stbc(struct sigma_dut *dut, const char *intf,
3642 const char *val)
3643{
3644 char buf[60];
3645
3646 snprintf(buf, sizeof(buf), "iwpriv %s tx_stbc %s", intf, val);
3647 if (system(buf) != 0)
3648 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv tx_stbc failed");
3649
3650 snprintf(buf, sizeof(buf), "iwpriv %s rx_stbc %s", intf, val);
3651 if (system(buf) != 0)
3652 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv rx_stbc failed");
3653}
3654
3655
Ashwini Patil68d02cd2017-01-10 15:39:16 +05303656static int mbo_set_cellular_data_capa(struct sigma_dut *dut,
3657 struct sigma_conn *conn,
3658 const char *intf, int capa)
3659{
3660 char buf[32];
3661
3662 if (capa > 0 && capa < 4) {
3663 snprintf(buf, sizeof(buf), "SET mbo_cell_capa %d", capa);
3664 if (wpa_command(intf, buf) < 0) {
3665 send_resp(dut, conn, SIGMA_ERROR,
3666 "ErrorCode, Failed to set cellular data capability");
3667 return 0;
3668 }
3669 return 1;
3670 }
3671
3672 sigma_dut_print(dut, DUT_MSG_ERROR,
3673 "Invalid Cellular data capability: %d", capa);
3674 send_resp(dut, conn, SIGMA_INVALID,
3675 "ErrorCode,Invalid cellular data capability");
3676 return 0;
3677}
3678
3679
Ashwini Patil9183fdb2017-04-13 16:58:25 +05303680static int mbo_set_roaming(struct sigma_dut *dut, struct sigma_conn *conn,
3681 const char *intf, const char *val)
3682{
3683 if (strcasecmp(val, "Disable") == 0) {
3684 if (wpa_command(intf, "SET roaming 0") < 0) {
3685 send_resp(dut, conn, SIGMA_ERROR,
3686 "ErrorCode,Failed to disable roaming");
3687 return 0;
3688 }
3689 return 1;
3690 }
3691
3692 if (strcasecmp(val, "Enable") == 0) {
3693 if (wpa_command(intf, "SET roaming 1") < 0) {
3694 send_resp(dut, conn, SIGMA_ERROR,
3695 "ErrorCode,Failed to enable roaming");
3696 return 0;
3697 }
3698 return 1;
3699 }
3700
3701 sigma_dut_print(dut, DUT_MSG_ERROR,
3702 "Invalid value provided for roaming: %s", val);
3703 send_resp(dut, conn, SIGMA_INVALID,
3704 "ErrorCode,Unknown value provided for Roaming");
3705 return 0;
3706}
3707
3708
Ashwini Patila75de5a2017-04-13 16:35:05 +05303709static int mbo_set_assoc_disallow(struct sigma_dut *dut,
3710 struct sigma_conn *conn,
3711 const char *intf, const char *val)
3712{
3713 if (strcasecmp(val, "Disable") == 0) {
3714 if (wpa_command(intf, "SET ignore_assoc_disallow 1") < 0) {
3715 send_resp(dut, conn, SIGMA_ERROR,
3716 "ErrorCode,Failed to disable Assoc_disallow");
3717 return 0;
3718 }
3719 return 1;
3720 }
3721
3722 if (strcasecmp(val, "Enable") == 0) {
3723 if (wpa_command(intf, "SET ignore_assoc_disallow 0") < 0) {
3724 send_resp(dut, conn, SIGMA_ERROR,
3725 "ErrorCode,Failed to enable Assoc_disallow");
3726 return 0;
3727 }
3728 return 1;
3729 }
3730
3731 sigma_dut_print(dut, DUT_MSG_ERROR,
3732 "Invalid value provided for Assoc_disallow: %s", val);
3733 send_resp(dut, conn, SIGMA_INVALID,
3734 "ErrorCode,Unknown value provided for Assoc_disallow");
3735 return 0;
3736}
3737
3738
Ashwini Patilc63161e2017-04-13 16:30:23 +05303739static int mbo_set_bss_trans_req(struct sigma_dut *dut, struct sigma_conn *conn,
3740 const char *intf, const char *val)
3741{
3742 if (strcasecmp(val, "Reject") == 0) {
3743 if (wpa_command(intf, "SET reject_btm_req_reason 1") < 0) {
3744 send_resp(dut, conn, SIGMA_ERROR,
3745 "ErrorCode,Failed to Reject BTM Request");
3746 return 0;
3747 }
3748 return 1;
3749 }
3750
3751 if (strcasecmp(val, "Accept") == 0) {
3752 if (wpa_command(intf, "SET reject_btm_req_reason 0") < 0) {
3753 send_resp(dut, conn, SIGMA_ERROR,
3754 "ErrorCode,Failed to Accept BTM Request");
3755 return 0;
3756 }
3757 return 1;
3758 }
3759
3760 sigma_dut_print(dut, DUT_MSG_ERROR,
3761 "Invalid value provided for BSS_Transition: %s", val);
3762 send_resp(dut, conn, SIGMA_INVALID,
3763 "ErrorCode,Unknown value provided for BSS_Transition");
3764 return 0;
3765}
3766
3767
Ashwini Patil00402582017-04-13 12:29:39 +05303768static int mbo_set_non_pref_ch_list(struct sigma_dut *dut,
3769 struct sigma_conn *conn,
3770 const char *intf,
3771 struct sigma_cmd *cmd)
3772{
3773 const char *ch, *pref, *op_class, *reason;
3774 char buf[120];
3775 int len, ret;
3776
3777 pref = get_param(cmd, "Ch_Pref");
3778 if (!pref)
3779 return 1;
3780
3781 if (strcasecmp(pref, "clear") == 0) {
3782 free(dut->non_pref_ch_list);
3783 dut->non_pref_ch_list = NULL;
3784 } else {
3785 op_class = get_param(cmd, "Ch_Op_Class");
3786 if (!op_class) {
3787 send_resp(dut, conn, SIGMA_INVALID,
3788 "ErrorCode,Ch_Op_Class not provided");
3789 return 0;
3790 }
3791
3792 ch = get_param(cmd, "Ch_Pref_Num");
3793 if (!ch) {
3794 send_resp(dut, conn, SIGMA_INVALID,
3795 "ErrorCode,Ch_Pref_Num not provided");
3796 return 0;
3797 }
3798
3799 reason = get_param(cmd, "Ch_Reason_Code");
3800 if (!reason) {
3801 send_resp(dut, conn, SIGMA_INVALID,
3802 "ErrorCode,Ch_Reason_Code not provided");
3803 return 0;
3804 }
3805
3806 if (!dut->non_pref_ch_list) {
3807 dut->non_pref_ch_list =
3808 calloc(1, NON_PREF_CH_LIST_SIZE);
3809 if (!dut->non_pref_ch_list) {
3810 send_resp(dut, conn, SIGMA_ERROR,
3811 "ErrorCode,Failed to allocate memory for non_pref_ch_list");
3812 return 0;
3813 }
3814 }
3815 len = strlen(dut->non_pref_ch_list);
3816 ret = snprintf(dut->non_pref_ch_list + len,
3817 NON_PREF_CH_LIST_SIZE - len,
3818 " %s:%s:%s:%s", op_class, ch, pref, reason);
3819 if (ret > 0 && ret < NON_PREF_CH_LIST_SIZE - len) {
3820 sigma_dut_print(dut, DUT_MSG_DEBUG, "non_pref_list: %s",
3821 dut->non_pref_ch_list);
3822 } else {
3823 sigma_dut_print(dut, DUT_MSG_ERROR,
3824 "snprintf failed for non_pref_list, ret = %d",
3825 ret);
3826 send_resp(dut, conn, SIGMA_ERROR,
3827 "ErrorCode,snprintf failed");
3828 free(dut->non_pref_ch_list);
3829 dut->non_pref_ch_list = NULL;
3830 return 0;
3831 }
3832 }
3833
3834 ret = snprintf(buf, sizeof(buf), "SET non_pref_chan%s",
3835 dut->non_pref_ch_list ? dut->non_pref_ch_list : " ");
3836 if (ret < 0 || ret >= (int) sizeof(buf)) {
3837 sigma_dut_print(dut, DUT_MSG_DEBUG,
3838 "snprintf failed for set non_pref_chan, ret: %d",
3839 ret);
3840 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,snprint failed");
3841 return 0;
3842 }
3843
3844 if (wpa_command(intf, buf) < 0) {
3845 send_resp(dut, conn, SIGMA_ERROR,
3846 "ErrorCode,Failed to set non-preferred channel list");
3847 return 0;
3848 }
3849
3850 return 1;
3851}
3852
3853
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08003854#ifdef NL80211_SUPPORT
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08003855
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08003856static int sta_set_he_htc_supp(struct sigma_dut *dut, const char *intf,
3857 uint8_t cfg)
3858{
3859 struct nl_msg *msg;
3860 int ret = 0;
3861 struct nlattr *params;
3862 int ifindex;
3863
3864 ifindex = if_nametoindex(intf);
3865 if (ifindex == 0) {
3866 sigma_dut_print(dut, DUT_MSG_ERROR,
3867 "%s: Index for interface %s failed",
3868 __func__, intf);
3869 return -1;
3870 }
3871
3872 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
3873 NL80211_CMD_VENDOR)) ||
3874 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
3875 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
3876 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
3877 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
3878 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
3879 nla_put_u8(msg,
3880 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_HTC_HE_SUPP,
3881 cfg)) {
3882 sigma_dut_print(dut, DUT_MSG_ERROR,
3883 "%s: err in adding vendor_cmd and vendor_data",
3884 __func__);
3885 nlmsg_free(msg);
3886 return -1;
3887 }
3888 nla_nest_end(msg, params);
3889
3890 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
3891 if (ret) {
3892 sigma_dut_print(dut, DUT_MSG_ERROR,
3893 "%s: err in send_and_recv_msgs, ret=%d",
3894 __func__, ret);
3895 }
3896 return ret;
3897}
3898
3899
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08003900static int sta_set_he_fragmentation(struct sigma_dut *dut, const char *intf,
3901 enum he_fragmentation_val frag)
3902{
3903 struct nl_msg *msg;
3904 int ret = 0;
3905 struct nlattr *params;
3906 int ifindex;
3907
3908 ifindex = if_nametoindex(intf);
3909 if (ifindex == 0) {
3910 sigma_dut_print(dut, DUT_MSG_ERROR,
3911 "%s: Index for interface %s failed",
3912 __func__, intf);
3913 return -1;
3914 }
3915
3916 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
3917 NL80211_CMD_VENDOR)) ||
3918 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
3919 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
3920 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
3921 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
3922 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
3923 nla_put_u8(msg,
3924 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_FRAGMENTATION,
3925 frag)) {
3926 sigma_dut_print(dut, DUT_MSG_ERROR,
3927 "%s: err in adding vendor_cmd and vendor_data",
3928 __func__);
3929 nlmsg_free(msg);
3930 return -1;
3931 }
3932 nla_nest_end(msg, params);
3933
3934 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
3935 if (ret) {
3936 sigma_dut_print(dut, DUT_MSG_ERROR,
3937 "%s: err in send_and_recv_msgs, ret=%d",
3938 __func__, ret);
3939 }
3940 return ret;
3941}
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08003942
3943
Subhani Shaik8e7a3052018-04-24 14:03:00 -07003944static int sta_set_he_ltf(struct sigma_dut *dut, const char *intf,
3945 enum qca_wlan_he_ltf_cfg ltf)
3946{
3947 struct nl_msg *msg;
3948 int ret = 0;
3949 struct nlattr *params;
3950 int ifindex;
3951
3952 ifindex = if_nametoindex(intf);
3953 if (ifindex == 0) {
3954 sigma_dut_print(dut, DUT_MSG_ERROR,
3955 "%s: Index for interface %s failed",
3956 __func__, intf);
3957 return -1;
3958 }
3959
3960 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
3961 NL80211_CMD_VENDOR)) ||
3962 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
3963 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
3964 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
3965 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
3966 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
3967 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_LTF,
3968 ltf)) {
3969 sigma_dut_print(dut, DUT_MSG_ERROR,
3970 "%s: err in adding vendor_cmd and vendor_data",
3971 __func__);
3972 nlmsg_free(msg);
3973 return -1;
3974 }
3975 nla_nest_end(msg, params);
3976
3977 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
3978 if (ret) {
3979 sigma_dut_print(dut, DUT_MSG_ERROR,
3980 "%s: err in send_and_recv_msgs, ret=%d",
3981 __func__, ret);
3982 }
3983 return ret;
3984}
3985
3986
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08003987static int nlvendor_sta_set_noack(struct sigma_dut *dut, const char *intf,
3988 int noack, enum qca_wlan_ac_type ac)
3989{
3990 struct nl_msg *msg;
3991 int ret = 0;
3992 struct nlattr *params;
3993 int ifindex;
3994
3995 ifindex = if_nametoindex(intf);
3996 if (ifindex == 0) {
3997 sigma_dut_print(dut, DUT_MSG_ERROR,
3998 "%s: Index for interface %s failed",
3999 __func__, intf);
4000 return -1;
4001 }
4002
4003 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4004 NL80211_CMD_VENDOR)) ||
4005 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4006 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4007 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4008 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4009 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4010 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_NO_ACK,
4011 noack) ||
4012 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_NO_ACK_AC,
4013 ac)) {
4014 sigma_dut_print(dut, DUT_MSG_ERROR,
4015 "%s: err in adding vendor_cmd and vendor_data",
4016 __func__);
4017 nlmsg_free(msg);
4018 return -1;
4019 }
4020 nla_nest_end(msg, params);
4021
4022 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4023 if (ret) {
4024 sigma_dut_print(dut, DUT_MSG_ERROR,
4025 "%s: err in send_and_recv_msgs, ret=%d",
4026 __func__, ret);
4027 }
4028 return ret;
4029}
4030
4031
4032static void wcn_sta_set_noack(struct sigma_dut *dut, const char *intf,
4033 const char *val)
4034{
4035 int noack, ret;
4036 char token[100];
4037 char *result;
4038 char *saveptr;
4039 enum qca_wlan_ac_type ac = QCA_WLAN_AC_BE;
4040
4041 strlcpy(token, val, sizeof(token));
4042 token[sizeof(token) - 1] = '\0';
4043 result = strtok_r(token, ":", &saveptr);
4044 while (result) {
4045 noack = strcasecmp(result, "Disable") != 0;
4046 ret = nlvendor_sta_set_noack(dut, intf, noack, ac);
4047 if (ret) {
4048 sigma_dut_print(dut, DUT_MSG_ERROR,
4049 "nlvendor_sta_set_noack failed for ac:%d, ret:%d",
4050 ac, ret);
4051 }
4052 result = strtok_r(NULL, ":", &saveptr);
4053 ac++;
4054 }
4055}
4056
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08004057#endif /* NL80211_SUPPORT */
4058
4059
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004060static int cmd_sta_preset_testparameters(struct sigma_dut *dut,
4061 struct sigma_conn *conn,
4062 struct sigma_cmd *cmd)
4063{
4064 const char *intf = get_param(cmd, "Interface");
4065 const char *val;
4066
4067 val = get_param(cmd, "Program");
Jouni Malinen1f6ae642018-06-07 23:56:13 +03004068 if (val && (strcasecmp(val, "HS2-R2") == 0 ||
4069 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004070 return cmd_sta_preset_testparameters_hs2_r2(dut, conn, intf,
4071 cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004072
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07004073 if (val && strcasecmp(val, "LOC") == 0)
4074 return loc_cmd_sta_preset_testparameters(dut, conn, cmd);
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02004075 if (val && strcasecmp(val, "60GHZ") == 0) {
4076 val = get_param(cmd, "WPS");
4077 if (val && strcasecmp(val, "disable") == 0) {
4078 dut->wps_disable = 1;
4079 sigma_dut_print(dut, DUT_MSG_INFO, "WPS disabled");
4080 } else {
4081 /* wps_disable can have other value from the previous
4082 * test, so make sure it has the correct value.
4083 */
4084 dut->wps_disable = 0;
4085 }
4086
4087 val = get_param(cmd, "P2P");
4088 if (val && strcasecmp(val, "disable") == 0)
4089 sigma_dut_print(dut, DUT_MSG_INFO, "P2P disabled");
4090 }
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07004091
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02004092 if (dut->program == PROGRAM_WPS && dut->band == WPS_BAND_60G)
4093 return cmd_sta_preset_testparameters_60ghz(dut, conn, cmd);
4094
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004095#ifdef ANDROID_NAN
4096 if (val && strcasecmp(val, "NAN") == 0)
4097 return nan_cmd_sta_preset_testparameters(dut, conn, cmd);
4098#endif /* ANDROID_NAN */
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07004099#ifdef MIRACAST
4100 if (val && (strcasecmp(val, "WFD") == 0 ||
4101 strcasecmp(val, "DisplayR2") == 0))
4102 return miracast_preset_testparameters(dut, conn, cmd);
4103#endif /* MIRACAST */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004104
Ashwini Patil68d02cd2017-01-10 15:39:16 +05304105 if (val && strcasecmp(val, "MBO") == 0) {
4106 val = get_param(cmd, "Cellular_Data_Cap");
4107 if (val &&
4108 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
4109 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +05304110
4111 val = get_param(cmd, "Ch_Pref");
4112 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
4113 return 0;
4114
Ashwini Patilc63161e2017-04-13 16:30:23 +05304115 val = get_param(cmd, "BSS_Transition");
4116 if (val && mbo_set_bss_trans_req(dut, conn, intf, val) == 0)
4117 return 0;
4118
Ashwini Patila75de5a2017-04-13 16:35:05 +05304119 val = get_param(cmd, "Assoc_Disallow");
4120 if (val && mbo_set_assoc_disallow(dut, conn, intf, val) == 0)
4121 return 0;
4122
Ashwini Patil9183fdb2017-04-13 16:58:25 +05304123 val = get_param(cmd, "Roaming");
4124 if (val && mbo_set_roaming(dut, conn, intf, val) == 0)
4125 return 0;
4126
Ashwini Patil68d02cd2017-01-10 15:39:16 +05304127 return 1;
4128 }
4129
Ankita Bajaja2cb5672017-10-25 16:08:28 +05304130 if (val && strcasecmp(val, "OCE") == 0)
4131 return cmd_sta_preset_testparameters_oce(dut, conn, intf, cmd);
4132
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004133#if 0
4134 val = get_param(cmd, "Supplicant");
4135 if (val && strcasecmp(val, "Default") != 0) {
4136 send_resp(dut, conn, SIGMA_ERROR,
4137 "ErrorCode,Only default(Vendor) supplicant "
4138 "supported");
4139 return 0;
4140 }
4141#endif
4142
4143 val = get_param(cmd, "RTS");
4144 if (val) {
4145 switch (get_driver_type()) {
4146 case DRIVER_ATHEROS:
4147 ath_sta_set_rts(dut, intf, val);
4148 break;
4149 default:
4150#if 0
4151 send_resp(dut, conn, SIGMA_ERROR,
4152 "ErrorCode,Setting RTS not supported");
4153 return 0;
4154#else
4155 sigma_dut_print(dut, DUT_MSG_DEBUG,
4156 "Setting RTS not supported");
4157 break;
4158#endif
4159 }
4160 }
4161
4162#if 0
4163 val = get_param(cmd, "FRGMNT");
4164 if (val) {
4165 /* TODO */
4166 send_resp(dut, conn, SIGMA_ERROR,
4167 "ErrorCode,Setting FRGMNT not supported");
4168 return 0;
4169 }
4170#endif
4171
4172#if 0
4173 val = get_param(cmd, "Preamble");
4174 if (val) {
4175 /* TODO: Long/Short */
4176 send_resp(dut, conn, SIGMA_ERROR,
4177 "ErrorCode,Setting Preamble not supported");
4178 return 0;
4179 }
4180#endif
4181
4182 val = get_param(cmd, "Mode");
4183 if (val) {
4184 if (strcmp(val, "11b") == 0 ||
4185 strcmp(val, "11g") == 0 ||
4186 strcmp(val, "11a") == 0 ||
4187 strcmp(val, "11n") == 0 ||
4188 strcmp(val, "11ng") == 0 ||
4189 strcmp(val, "11nl") == 0 ||
4190 strcmp(val, "11nl(nabg)") == 0 ||
4191 strcmp(val, "AC") == 0 ||
4192 strcmp(val, "11AC") == 0 ||
4193 strcmp(val, "11ac") == 0 ||
4194 strcmp(val, "11na") == 0 ||
Amarnath Hullur Subramanyamb0db2712018-01-30 19:40:35 -08004195 strcmp(val, "11an") == 0 ||
4196 strcmp(val, "11ax") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004197 /* STA supports all modes by default */
4198 } else {
4199 send_resp(dut, conn, SIGMA_ERROR,
4200 "ErrorCode,Setting Mode not supported");
4201 return 0;
4202 }
Amarnath Hullur Subramanyam97d0e532018-01-31 02:53:02 -08004203
4204 /* Change the mode only in case of testbed for HE program
4205 * and for 11a and 11g modes only. */
4206 if (dut->program == PROGRAM_HE &&
4207 dut->device_type == STA_testbed) {
4208 int phymode;
4209 char buf[60];
4210
4211 if (strcmp(val, "11a") == 0) {
Amarnath Hullur Subramanyam94dfaf02018-03-02 19:26:57 -08004212 phymode = 1; /* IEEE80211_MODE_11A */
4213 } else if (strcmp(val, "11g") == 0) {
4214 phymode = 3; /* IEEE80211_MODE_11G */
4215 } else if (strcmp(val, "11b") == 0) {
4216 phymode = 2; /* IEEE80211_MODE_11B */
4217 } else if (strcmp(val, "11n") == 0 ||
4218 strcmp(val, "11nl") == 0 ||
4219 strcmp(val, "11nl(nabg)") == 0) {
4220 phymode = 22; /* IEEE80211_MODE_11AGN */
4221 } else if (strcmp(val, "11ng") == 0) {
4222 phymode = 13; /* IEEE80211_MODE_11NG_HT40 */
4223 } else if (strcmp(val, "AC") == 0 ||
4224 strcasecmp(val, "11AC") == 0) {
4225 phymode = 19; /* IEEE80211_MODE_11AC_VHT80 */
4226 } else if (strcmp(val, "11na") == 0 ||
4227 strcasecmp(val, "11an") == 0) {
4228 phymode = 14; /* IEEE80211_MODE_11NA_HT40 */
4229 } else if (strcmp(val, "11ax") == 0) {
4230 phymode = 0; /* IEEE80211_MODE_AUTO */
Amarnath Hullur Subramanyam97d0e532018-01-31 02:53:02 -08004231 } else {
4232 sigma_dut_print(dut, DUT_MSG_DEBUG,
4233 "Ignoring mode change for mode: %s",
4234 val);
4235 phymode = -1;
4236 }
4237 if (phymode != -1) {
4238 snprintf(buf, sizeof(buf),
4239 "iwpriv %s setphymode %d",
4240 intf, phymode);
4241 if (system(buf) != 0) {
4242 sigma_dut_print(dut, DUT_MSG_ERROR,
4243 "iwpriv setting of phymode failed");
4244 }
4245 }
4246 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004247 }
4248
4249 val = get_param(cmd, "wmm");
4250 if (val) {
4251 switch (get_driver_type()) {
4252 case DRIVER_ATHEROS:
4253 ath_sta_set_wmm(dut, intf, val);
4254 break;
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08004255 case DRIVER_WCN:
4256 wcn_sta_set_wmm(dut, intf, val);
4257 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004258 default:
4259 sigma_dut_print(dut, DUT_MSG_DEBUG,
4260 "Setting wmm not supported");
4261 break;
4262 }
4263 }
4264
4265 val = get_param(cmd, "Powersave");
4266 if (val) {
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08004267 char buf[60];
4268
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004269 if (strcmp(val, "0") == 0 || strcasecmp(val, "off") == 0) {
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08004270 if (get_driver_type() == DRIVER_WCN) {
4271 snprintf(buf, sizeof(buf),
4272 "iwpriv %s setPower 2", intf);
4273 if (system(buf) != 0) {
4274 sigma_dut_print(dut, DUT_MSG_ERROR,
4275 "iwpriv setPower 2 failed");
4276 return 0;
4277 }
4278 }
4279
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004280 if (wpa_command(get_station_ifname(),
4281 "P2P_SET ps 0") < 0)
4282 return -2;
4283 /* Make sure test modes are disabled */
4284 wpa_command(get_station_ifname(), "P2P_SET ps 98");
4285 wpa_command(get_station_ifname(), "P2P_SET ps 96");
4286 } else if (strcmp(val, "1") == 0 ||
4287 strcasecmp(val, "PSPoll") == 0 ||
4288 strcasecmp(val, "on") == 0) {
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08004289 if (get_driver_type() == DRIVER_WCN) {
4290 snprintf(buf, sizeof(buf),
4291 "iwpriv %s setPower 1", intf);
4292 if (system(buf) != 0) {
4293 sigma_dut_print(dut, DUT_MSG_ERROR,
4294 "iwpriv setPower 1 failed");
4295 return 0;
4296 }
4297 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004298 /* Disable default power save mode */
4299 wpa_command(get_station_ifname(), "P2P_SET ps 0");
4300 /* Enable PS-Poll test mode */
4301 if (wpa_command(get_station_ifname(),
4302 "P2P_SET ps 97") < 0 ||
4303 wpa_command(get_station_ifname(),
4304 "P2P_SET ps 99") < 0)
4305 return -2;
4306 } else if (strcmp(val, "2") == 0 ||
4307 strcasecmp(val, "Fast") == 0) {
4308 /* TODO */
4309 send_resp(dut, conn, SIGMA_ERROR,
4310 "ErrorCode,Powersave=Fast not supported");
4311 return 0;
4312 } else if (strcmp(val, "3") == 0 ||
4313 strcasecmp(val, "PSNonPoll") == 0) {
4314 /* Make sure test modes are disabled */
4315 wpa_command(get_station_ifname(), "P2P_SET ps 98");
4316 wpa_command(get_station_ifname(), "P2P_SET ps 96");
4317
4318 /* Enable default power save mode */
4319 if (wpa_command(get_station_ifname(),
4320 "P2P_SET ps 1") < 0)
4321 return -2;
4322 } else
4323 return -1;
4324 }
4325
4326 val = get_param(cmd, "NoAck");
4327 if (val) {
4328 switch (get_driver_type()) {
4329 case DRIVER_ATHEROS:
4330 ath_sta_set_noack(dut, intf, val);
4331 break;
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08004332#ifdef NL80211_SUPPORT
4333 case DRIVER_WCN:
4334 wcn_sta_set_noack(dut, intf, val);
4335 break;
4336#endif /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004337 default:
4338 send_resp(dut, conn, SIGMA_ERROR,
4339 "ErrorCode,Setting NoAck not supported");
4340 return 0;
4341 }
4342 }
4343
4344 val = get_param(cmd, "IgnoreChswitchProhibit");
4345 if (val) {
4346 /* TODO: Enabled/disabled */
4347 if (strcasecmp(val, "Enabled") == 0) {
4348 send_resp(dut, conn, SIGMA_ERROR,
4349 "ErrorCode,Enabling IgnoreChswitchProhibit "
4350 "not supported");
4351 return 0;
4352 }
4353 }
4354
4355 val = get_param(cmd, "TDLS");
4356 if (val) {
4357 if (strcasecmp(val, "Disabled") == 0) {
4358 if (wpa_command(intf, "SET tdls_disabled 1")) {
4359 send_resp(dut, conn, SIGMA_ERROR,
4360 "ErrorCode,Failed to disable TDLS");
4361 return 0;
4362 }
4363 } else if (strcasecmp(val, "Enabled") == 0) {
4364 if (wpa_command(intf, "SET tdls_disabled 0")) {
4365 send_resp(dut, conn, SIGMA_ERROR,
4366 "ErrorCode,Failed to enable TDLS");
4367 return 0;
4368 }
4369 } else {
4370 send_resp(dut, conn, SIGMA_ERROR,
4371 "ErrorCode,Unsupported TDLS value");
4372 return 0;
4373 }
4374 }
4375
4376 val = get_param(cmd, "TDLSmode");
4377 if (val) {
4378 if (strcasecmp(val, "Default") == 0) {
4379 wpa_command(intf, "SET tdls_testing 0");
4380 } else if (strcasecmp(val, "APProhibit") == 0) {
4381 if (wpa_command(intf, "SET tdls_testing 0x400")) {
4382 send_resp(dut, conn, SIGMA_ERROR,
4383 "ErrorCode,Failed to enable ignore "
4384 "APProhibit TDLS mode");
4385 return 0;
4386 }
4387 } else if (strcasecmp(val, "HiLoMac") == 0) {
4388 /* STA should respond with TDLS setup req for a TDLS
4389 * setup req */
4390 if (wpa_command(intf, "SET tdls_testing 0x80")) {
4391 send_resp(dut, conn, SIGMA_ERROR,
4392 "ErrorCode,Failed to enable HiLoMac "
4393 "TDLS mode");
4394 return 0;
4395 }
4396 } else if (strcasecmp(val, "WeakSecurity") == 0) {
4397 /*
4398 * Since all security modes are enabled by default when
4399 * Sigma control is used, there is no need to do
4400 * anything here.
4401 */
4402 } else if (strcasecmp(val, "ExistLink") == 0) {
4403 /*
4404 * Since we allow new TDLS Setup Request even if there
4405 * is an existing link, nothing needs to be done for
4406 * this.
4407 */
4408 } else {
4409 /* TODO:
4410 * ExistLink: STA should send TDLS setup req even if
4411 * direct link already exists
4412 */
4413 send_resp(dut, conn, SIGMA_ERROR,
4414 "ErrorCode,Unsupported TDLSmode value");
4415 return 0;
4416 }
4417 }
4418
4419 val = get_param(cmd, "FakePubKey");
4420 if (val && atoi(val) && wpa_command(intf, "SET wps_corrupt_pkhash 1")) {
4421 send_resp(dut, conn, SIGMA_ERROR,
4422 "ErrorCode,Failed to enable FakePubKey");
4423 return 0;
4424 }
4425
Amarnath Hullur Subramanyamae1042b2018-02-22 21:52:52 -08004426#ifdef NL80211_SUPPORT
4427 val = get_param(cmd, "FrgmntSupport");
4428 if (val) {
4429 if (strcasecmp(val, "Enable") == 0) {
4430 if (sta_set_he_fragmentation(dut, intf,
4431 HE_FRAG_LEVEL1)) {
4432 send_resp(dut, conn, SIGMA_ERROR,
4433 "ErrorCode,Failed to enable HE Fragmentation");
4434 return 0;
4435 }
4436 } else if (strcasecmp(val, "Disable") == 0) {
4437 if (sta_set_he_fragmentation(dut, intf,
4438 HE_FRAG_DISABLE)) {
4439 send_resp(dut, conn, SIGMA_ERROR,
4440 "ErrorCode,Failed to disable HE Fragmentation");
4441 return 0;
4442 }
4443 }
4444 }
4445#endif /* NL80211_SUPPORT */
4446
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004447 return 1;
4448}
4449
4450
4451static const char * ath_get_radio_name(const char *radio_name)
4452{
4453 if (radio_name == NULL)
4454 return "wifi0";
4455 if (strcmp(radio_name, "wifi1") == 0)
4456 return "wifi1";
4457 if (strcmp(radio_name, "wifi2") == 0)
4458 return "wifi2";
4459 return "wifi0";
4460}
4461
4462
4463static void ath_sta_set_txsp_stream(struct sigma_dut *dut, const char *intf,
4464 const char *val)
4465{
4466 char buf[60];
4467 unsigned int vht_mcsmap = 0;
4468 int txchainmask = 0;
4469 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
4470
4471 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
4472 if (dut->testbed_flag_txsp == 1) {
4473 vht_mcsmap = 0xfffc;
4474 dut->testbed_flag_txsp = 0;
4475 } else {
4476 vht_mcsmap = 0xfffe;
4477 }
4478 txchainmask = 1;
4479 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
4480 if (dut->testbed_flag_txsp == 1) {
4481 vht_mcsmap = 0xfff0;
4482 dut->testbed_flag_txsp = 0;
4483 } else {
4484 vht_mcsmap = 0xfffa;
4485 }
4486 txchainmask = 3;
4487 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
4488 if (dut->testbed_flag_txsp == 1) {
4489 vht_mcsmap = 0xffc0;
4490 dut->testbed_flag_txsp = 0;
4491 } else {
4492 vht_mcsmap = 0xffea;
4493 }
4494 txchainmask = 7;
4495 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
4496 if (dut->testbed_flag_txsp == 1) {
4497 vht_mcsmap = 0xff00;
4498 dut->testbed_flag_txsp = 0;
4499 } else {
4500 vht_mcsmap = 0xffaa;
4501 }
4502 txchainmask = 15;
4503 } else {
4504 if (dut->testbed_flag_txsp == 1) {
4505 vht_mcsmap = 0xffc0;
4506 dut->testbed_flag_txsp = 0;
4507 } else {
4508 vht_mcsmap = 0xffea;
4509 }
4510 }
4511
4512 if (txchainmask) {
4513 snprintf(buf, sizeof(buf), "iwpriv %s txchainmask %d",
4514 basedev, txchainmask);
4515 if (system(buf) != 0) {
4516 sigma_dut_print(dut, DUT_MSG_ERROR,
4517 "iwpriv txchainmask failed");
4518 }
4519 }
4520
4521 snprintf(buf, sizeof(buf), "iwpriv %s vht_mcsmap 0x%04x",
4522 intf, vht_mcsmap);
4523 if (system(buf) != 0) {
4524 sigma_dut_print(dut, DUT_MSG_ERROR,
4525 "iwpriv %s vht_mcsmap 0x%04x failed",
4526 intf, vht_mcsmap);
4527 }
4528}
4529
4530
4531static void ath_sta_set_rxsp_stream(struct sigma_dut *dut, const char *intf,
4532 const char *val)
4533{
4534 char buf[60];
4535 unsigned int vht_mcsmap = 0;
4536 int rxchainmask = 0;
4537 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
4538
4539 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
4540 if (dut->testbed_flag_rxsp == 1) {
4541 vht_mcsmap = 0xfffc;
4542 dut->testbed_flag_rxsp = 0;
4543 } else {
4544 vht_mcsmap = 0xfffe;
4545 }
4546 rxchainmask = 1;
4547 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
4548 if (dut->testbed_flag_rxsp == 1) {
4549 vht_mcsmap = 0xfff0;
4550 dut->testbed_flag_rxsp = 0;
4551 } else {
4552 vht_mcsmap = 0xfffa;
4553 }
4554 rxchainmask = 3;
4555 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
4556 if (dut->testbed_flag_rxsp == 1) {
4557 vht_mcsmap = 0xffc0;
4558 dut->testbed_flag_rxsp = 0;
4559 } else {
4560 vht_mcsmap = 0xffea;
4561 }
4562 rxchainmask = 7;
4563 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
4564 if (dut->testbed_flag_rxsp == 1) {
4565 vht_mcsmap = 0xff00;
4566 dut->testbed_flag_rxsp = 0;
4567 } else {
4568 vht_mcsmap = 0xffaa;
4569 }
4570 rxchainmask = 15;
4571 } else {
4572 if (dut->testbed_flag_rxsp == 1) {
4573 vht_mcsmap = 0xffc0;
4574 dut->testbed_flag_rxsp = 0;
4575 } else {
4576 vht_mcsmap = 0xffea;
4577 }
4578 }
4579
4580 if (rxchainmask) {
4581 snprintf(buf, sizeof(buf), "iwpriv %s rxchainmask %d",
4582 basedev, rxchainmask);
4583 if (system(buf) != 0) {
4584 sigma_dut_print(dut, DUT_MSG_ERROR,
4585 "iwpriv rxchainmask failed");
4586 }
4587 }
4588
4589 snprintf(buf, sizeof(buf), "iwpriv %s vht_mcsmap 0x%04x",
4590 intf, vht_mcsmap);
4591 if (system(buf) != 0) {
4592 sigma_dut_print(dut, DUT_MSG_ERROR,
4593 "iwpriv %s vht_mcsmap 0x%04x",
4594 intf, vht_mcsmap);
4595 }
4596}
4597
4598
4599void ath_set_zero_crc(struct sigma_dut *dut, const char *val)
4600{
4601 if (strcasecmp(val, "enable") == 0) {
4602 if (system("athdiag --set --address=0x2a204 --and=0xbfffffff")
4603 != 0) {
4604 sigma_dut_print(dut, DUT_MSG_ERROR,
4605 "Disable BB_VHTSIGB_CRC_CALC failed");
4606 }
4607
4608 if (system("athdiag --set --address=0x2a204 --or=0x80000000")
4609 != 0) {
4610 sigma_dut_print(dut, DUT_MSG_ERROR,
4611 "Enable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
4612 }
4613 } else {
4614 if (system("athdiag --set --address=0x2a204 --and=0x7fffffff")
4615 != 0) {
4616 sigma_dut_print(dut, DUT_MSG_ERROR,
4617 "Disable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
4618 }
4619
4620 if (system("athdiag --set --address=0x2a204 --or=0x40000000")
4621 != 0) {
4622 sigma_dut_print(dut, DUT_MSG_ERROR,
4623 "Enable BB_VHTSIGB_CRC_CALC failed");
4624 }
4625 }
4626}
4627
4628
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08004629static int wcn_sta_set_width(struct sigma_dut *dut, const char *intf,
4630 const char *val)
4631{
4632 char buf[60];
4633
4634 if (strcmp(val, "20") == 0) {
4635 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 0", intf);
4636 dut->chwidth = 0;
4637 } else if (strcmp(val, "40") == 0) {
4638 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 1", intf);
4639 dut->chwidth = 1;
4640 } else if (strcmp(val, "80") == 0) {
4641 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 2", intf);
4642 dut->chwidth = 2;
Sunil Duttb1cccac2018-05-22 21:03:12 +05304643 } else if (strcasecmp(val, "Auto") == 0) {
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08004644 buf[0] = '\0';
4645 } else {
4646 sigma_dut_print(dut, DUT_MSG_ERROR, "WIDTH %s not supported",
4647 val);
4648 return -1;
4649 }
4650
4651 if (buf[0] != '\0' && system(buf) != 0) {
4652 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv chwidth failed");
4653 return -1;
4654 }
4655
4656 return 0;
4657}
4658
4659
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08004660static int nlvendor_sta_set_addba_reject(struct sigma_dut *dut,
4661 const char *intf, int addbareject)
4662{
4663#ifdef NL80211_SUPPORT
4664 struct nl_msg *msg;
4665 int ret = 0;
4666 struct nlattr *params;
4667 int ifindex;
4668
4669 ifindex = if_nametoindex(intf);
4670 if (ifindex == 0) {
4671 sigma_dut_print(dut, DUT_MSG_ERROR,
4672 "%s: Index for interface %s failed",
4673 __func__, intf);
4674 return -1;
4675 }
4676
4677 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4678 NL80211_CMD_VENDOR)) ||
4679 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4680 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4681 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4682 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4683 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4684 nla_put_u8(msg,
4685 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ACCEPT_ADDBA_REQ,
4686 !addbareject)) {
4687 sigma_dut_print(dut, DUT_MSG_ERROR,
4688 "%s: err in adding vendor_cmd and vendor_data",
4689 __func__);
4690 nlmsg_free(msg);
4691 return -1;
4692 }
4693 nla_nest_end(msg, params);
4694
4695 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4696 if (ret) {
4697 sigma_dut_print(dut, DUT_MSG_ERROR,
4698 "%s: err in send_and_recv_msgs, ret=%d",
4699 __func__, ret);
4700 }
4701 return ret;
4702#else /* NL80211_SUPPORT */
4703 sigma_dut_print(dut, DUT_MSG_ERROR,
4704 "ADDBA_REJECT cannot be set without NL80211_SUPPORT defined");
4705 return -1;
4706#endif /* NL80211_SUPPORT */
4707}
4708
4709
4710static int sta_set_addba_reject(struct sigma_dut *dut, const char *intf,
4711 int addbareject)
4712{
4713 int ret;
4714
4715 switch (get_driver_type()) {
4716 case DRIVER_WCN:
4717 ret = nlvendor_sta_set_addba_reject(dut, intf, addbareject);
4718 if (ret) {
4719 sigma_dut_print(dut, DUT_MSG_ERROR,
4720 "nlvendor_sta_set_addba_reject failed, ret:%d",
4721 ret);
4722 return ret;
4723 }
4724 break;
4725 default:
4726 sigma_dut_print(dut, DUT_MSG_ERROR,
4727 "errorCode,Unsupported ADDBA_REJECT with the current driver");
4728 ret = -1;
4729 break;
4730 }
4731
4732 return ret;
4733}
4734
4735
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08004736static int nlvendor_config_send_addba(struct sigma_dut *dut, const char *intf,
4737 int enable)
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08004738{
4739#ifdef NL80211_SUPPORT
4740 struct nl_msg *msg;
4741 int ret = 0;
4742 struct nlattr *params;
4743 int ifindex;
4744
4745 ifindex = if_nametoindex(intf);
4746 if (ifindex == 0) {
4747 sigma_dut_print(dut, DUT_MSG_ERROR,
4748 "%s: Index for interface %s failed",
4749 __func__, intf);
4750 return -1;
4751 }
4752
4753 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4754 NL80211_CMD_VENDOR)) ||
4755 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4756 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4757 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4758 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4759 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4760 nla_put_u8(msg,
4761 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_SEND_ADDBA_REQ,
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08004762 enable)) {
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08004763 sigma_dut_print(dut, DUT_MSG_ERROR,
4764 "%s: err in adding vendor_cmd and vendor_data",
4765 __func__);
4766 nlmsg_free(msg);
4767 return -1;
4768 }
4769 nla_nest_end(msg, params);
4770
4771 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4772 if (ret) {
4773 sigma_dut_print(dut, DUT_MSG_ERROR,
4774 "%s: err in send_and_recv_msgs, ret=%d",
4775 __func__, ret);
4776 }
4777 return ret;
4778#else /* NL80211_SUPPORT */
4779 sigma_dut_print(dut, DUT_MSG_ERROR,
4780 "Disable addba not possible without NL80211_SUPPORT defined");
4781 return -1;
4782#endif /* NL80211_SUPPORT */
4783}
4784
4785
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004786static int cmd_sta_set_wireless_common(const char *intf, struct sigma_dut *dut,
4787 struct sigma_conn *conn,
4788 struct sigma_cmd *cmd)
4789{
4790 const char *val;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08004791 int ampdu = -1, addbareject = -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004792 char buf[30];
4793
4794 val = get_param(cmd, "40_INTOLERANT");
4795 if (val) {
4796 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
4797 /* TODO: iwpriv ht40intol through wpa_supplicant */
4798 send_resp(dut, conn, SIGMA_ERROR,
4799 "ErrorCode,40_INTOLERANT not supported");
4800 return 0;
4801 }
4802 }
4803
4804 val = get_param(cmd, "ADDBA_REJECT");
4805 if (val) {
4806 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
4807 /* reject any ADDBA with status "decline" */
4808 ampdu = 0;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08004809 addbareject = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004810 } else {
4811 /* accept ADDBA */
4812 ampdu = 1;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08004813 addbareject = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004814 }
4815 }
4816
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08004817 if (addbareject >= 0 &&
4818 sta_set_addba_reject(dut, intf, addbareject) < 0) {
4819 send_resp(dut, conn, SIGMA_ERROR,
4820 "ErrorCode,set addba_reject failed");
4821 return 0;
4822 }
4823
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004824 val = get_param(cmd, "AMPDU");
4825 if (val) {
4826 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
4827 /* enable AMPDU Aggregation */
4828 if (ampdu == 0) {
4829 send_resp(dut, conn, SIGMA_ERROR,
4830 "ErrorCode,Mismatch in "
4831 "addba_reject/ampdu - "
4832 "not supported");
4833 return 0;
4834 }
4835 ampdu = 1;
4836 } else {
4837 /* disable AMPDU Aggregation */
4838 if (ampdu == 1) {
4839 send_resp(dut, conn, SIGMA_ERROR,
4840 "ErrorCode,Mismatch in "
4841 "addba_reject/ampdu - "
4842 "not supported");
4843 return 0;
4844 }
4845 ampdu = 0;
4846 }
4847 }
4848
4849 if (ampdu >= 0) {
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08004850 int ret;
4851
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004852 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s A-MPDU aggregation",
4853 ampdu ? "Enabling" : "Disabling");
4854 snprintf(buf, sizeof(buf), "SET ampdu %d", ampdu);
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07004855 if (wpa_command(intf, buf) < 0 &&
4856 iwpriv_sta_set_ampdu(dut, intf, ampdu) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004857 send_resp(dut, conn, SIGMA_ERROR,
4858 "ErrorCode,set aggr failed");
4859 return 0;
4860 }
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08004861
4862 if (ampdu == 0) {
4863 /* Disable sending of addba using nl vendor command */
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08004864 ret = nlvendor_config_send_addba(dut, intf, 0);
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08004865 if (ret) {
4866 sigma_dut_print(dut, DUT_MSG_ERROR,
4867 "Failed to disable addba, ret:%d",
4868 ret);
4869 }
4870 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004871 }
4872
4873 val = get_param(cmd, "AMSDU");
4874 if (val) {
4875 switch (get_driver_type()) {
4876 case DRIVER_ATHEROS:
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08004877 case DRIVER_WCN:
4878 iwpriv_sta_set_amsdu(dut, intf, val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004879 break;
4880 default:
4881 if (strcmp(val, "1") == 0 ||
4882 strcasecmp(val, "Enable") == 0) {
4883 /* Enable AMSDU Aggregation */
4884 send_resp(dut, conn, SIGMA_ERROR,
4885 "ErrorCode,AMSDU aggregation not supported");
4886 return 0;
4887 }
4888 break;
4889 }
4890 }
4891
4892 val = get_param(cmd, "STBC_RX");
4893 if (val) {
4894 switch (get_driver_type()) {
4895 case DRIVER_ATHEROS:
4896 ath_sta_set_stbc(dut, intf, val);
4897 break;
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05304898 case DRIVER_WCN:
4899 wcn_sta_set_stbc(dut, intf, val);
4900 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004901 default:
4902 send_resp(dut, conn, SIGMA_ERROR,
4903 "ErrorCode,STBC_RX not supported");
4904 return 0;
4905 }
4906 }
4907
4908 val = get_param(cmd, "WIDTH");
4909 if (val) {
4910 switch (get_driver_type()) {
4911 case DRIVER_WCN:
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08004912 if (wcn_sta_set_width(dut, intf, val) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004913 send_resp(dut, conn, SIGMA_ERROR,
4914 "ErrorCode,Failed to set WIDTH");
4915 return 0;
4916 }
4917 break;
4918 case DRIVER_ATHEROS:
4919 if (ath_set_width(dut, conn, intf, val) < 0)
4920 return 0;
4921 break;
4922 default:
4923 sigma_dut_print(dut, DUT_MSG_ERROR,
4924 "Setting WIDTH not supported");
4925 break;
4926 }
4927 }
4928
4929 val = get_param(cmd, "SMPS");
4930 if (val) {
4931 /* TODO: Dynamic/0, Static/1, No Limit/2 */
4932 send_resp(dut, conn, SIGMA_ERROR,
4933 "ErrorCode,SMPS not supported");
4934 return 0;
4935 }
4936
4937 val = get_param(cmd, "TXSP_STREAM");
4938 if (val) {
4939 switch (get_driver_type()) {
4940 case DRIVER_WCN:
4941 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
4942 send_resp(dut, conn, SIGMA_ERROR,
4943 "ErrorCode,Failed to set TXSP_STREAM");
4944 return 0;
4945 }
4946 break;
4947 case DRIVER_ATHEROS:
4948 ath_sta_set_txsp_stream(dut, intf, val);
4949 break;
4950 default:
4951 sigma_dut_print(dut, DUT_MSG_ERROR,
4952 "Setting TXSP_STREAM not supported");
4953 break;
4954 }
4955 }
4956
4957 val = get_param(cmd, "RXSP_STREAM");
4958 if (val) {
4959 switch (get_driver_type()) {
4960 case DRIVER_WCN:
4961 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
4962 send_resp(dut, conn, SIGMA_ERROR,
4963 "ErrorCode,Failed to set RXSP_STREAM");
4964 return 0;
4965 }
4966 break;
4967 case DRIVER_ATHEROS:
4968 ath_sta_set_rxsp_stream(dut, intf, val);
4969 break;
4970 default:
4971 sigma_dut_print(dut, DUT_MSG_ERROR,
4972 "Setting RXSP_STREAM not supported");
4973 break;
4974 }
4975 }
4976
4977 val = get_param(cmd, "DYN_BW_SGNL");
4978 if (val) {
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08004979 switch (get_driver_type()) {
4980 case DRIVER_WCN:
Peng Xuc59afd32016-11-21 15:01:11 -08004981 if (strcasecmp(val, "enable") == 0) {
4982 snprintf(buf, sizeof(buf),
4983 "iwpriv %s cwmenable 1", intf);
4984 if (system(buf) != 0) {
4985 sigma_dut_print(dut, DUT_MSG_ERROR,
4986 "iwpriv cwmenable 1 failed");
4987 return 0;
4988 }
4989 } else if (strcasecmp(val, "disable") == 0) {
4990 snprintf(buf, sizeof(buf),
4991 "iwpriv %s cwmenable 0", intf);
4992 if (system(buf) != 0) {
4993 sigma_dut_print(dut, DUT_MSG_ERROR,
4994 "iwpriv cwmenable 0 failed");
4995 return 0;
4996 }
4997 } else {
4998 sigma_dut_print(dut, DUT_MSG_ERROR,
4999 "Unsupported DYN_BW_SGL");
5000 }
5001
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005002 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 3", intf);
5003 if (system(buf) != 0) {
5004 sigma_dut_print(dut, DUT_MSG_ERROR,
5005 "Failed to set cts_cbw in DYN_BW_SGNL");
5006 return 0;
5007 }
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08005008 break;
5009 case DRIVER_ATHEROS:
priyadharshini gowthamane5e25172015-12-08 14:53:48 -08005010 novap_reset(dut, intf);
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08005011 ath_config_dyn_bw_sig(dut, intf, val);
5012 break;
5013 default:
5014 sigma_dut_print(dut, DUT_MSG_ERROR,
5015 "Failed to set DYN_BW_SGNL");
5016 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005017 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005018 }
5019
5020 val = get_param(cmd, "RTS_FORCE");
5021 if (val) {
priyadharshini gowthamane5e25172015-12-08 14:53:48 -08005022 novap_reset(dut, intf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005023 if (strcasecmp(val, "Enable") == 0) {
5024 snprintf(buf, sizeof(buf), "iwconfig %s rts 64", intf);
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02005025 if (system(buf) != 0) {
5026 sigma_dut_print(dut, DUT_MSG_ERROR,
5027 "Failed to set RTS_FORCE 64");
5028 }
priyadharshini gowthaman270870e2015-12-09 10:10:23 -08005029 snprintf(buf, sizeof(buf),
5030 "wifitool %s beeliner_fw_test 100 1", intf);
5031 if (system(buf) != 0) {
5032 sigma_dut_print(dut, DUT_MSG_ERROR,
5033 "wifitool beeliner_fw_test 100 1 failed");
5034 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005035 } else if (strcasecmp(val, "Disable") == 0) {
5036 snprintf(buf, sizeof(buf), "iwconfig %s rts 2347",
5037 intf);
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02005038 if (system(buf) != 0) {
5039 sigma_dut_print(dut, DUT_MSG_ERROR,
5040 "Failed to set RTS_FORCE 2347");
5041 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005042 } else {
5043 send_resp(dut, conn, SIGMA_ERROR,
5044 "ErrorCode,RTS_FORCE value not supported");
5045 return 0;
5046 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005047 }
5048
5049 val = get_param(cmd, "CTS_WIDTH");
5050 if (val) {
5051 switch (get_driver_type()) {
5052 case DRIVER_WCN:
5053 if (wcn_sta_set_cts_width(dut, intf, val) < 0) {
5054 send_resp(dut, conn, SIGMA_ERROR,
5055 "ErrorCode,Failed to set CTS_WIDTH");
5056 return 0;
5057 }
5058 break;
5059 case DRIVER_ATHEROS:
5060 ath_set_cts_width(dut, intf, val);
5061 break;
5062 default:
5063 sigma_dut_print(dut, DUT_MSG_ERROR,
5064 "Setting CTS_WIDTH not supported");
5065 break;
5066 }
5067 }
5068
5069 val = get_param(cmd, "BW_SGNL");
5070 if (val) {
5071 if (strcasecmp(val, "Enable") == 0) {
5072 snprintf(buf, sizeof(buf), "iwpriv %s cwmenable 1",
5073 intf);
5074 } else if (strcasecmp(val, "Disable") == 0) {
5075 /* TODO: Disable */
5076 buf[0] = '\0';
5077 } else {
5078 send_resp(dut, conn, SIGMA_ERROR,
5079 "ErrorCode,BW_SGNL value not supported");
5080 return 0;
5081 }
5082
5083 if (buf[0] != '\0' && system(buf) != 0) {
5084 sigma_dut_print(dut, DUT_MSG_ERROR,
5085 "Failed to set BW_SGNL");
5086 }
5087 }
5088
5089 val = get_param(cmd, "Band");
5090 if (val) {
5091 if (strcmp(val, "2.4") == 0 || strcmp(val, "5") == 0) {
5092 /* STA supports all bands by default */
5093 } else {
5094 send_resp(dut, conn, SIGMA_ERROR,
5095 "ErrorCode,Unsupported Band");
5096 return 0;
5097 }
5098 }
5099
5100 val = get_param(cmd, "zero_crc");
5101 if (val) {
5102 switch (get_driver_type()) {
5103 case DRIVER_ATHEROS:
5104 ath_set_zero_crc(dut, val);
5105 break;
5106 default:
5107 break;
5108 }
5109 }
5110
5111 return 1;
5112}
5113
5114
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02005115static int sta_set_force_mcs(struct sigma_dut *dut, int force, int mcs)
5116{
5117 switch (get_driver_type()) {
5118#ifdef __linux__
5119 case DRIVER_WIL6210:
5120 return wil6210_set_force_mcs(dut, force, mcs);
5121#endif /* __linux__ */
5122 default:
5123 sigma_dut_print(dut, DUT_MSG_ERROR,
5124 "Unsupported sta_set_force_mcs with the current driver");
5125 return -1;
5126 }
5127}
5128
5129
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02005130static int sta_60g_force_rsn_ie(struct sigma_dut *dut, int state)
5131{
5132 switch (get_driver_type()) {
5133#ifdef __linux__
5134 case DRIVER_WIL6210:
5135 return wil6210_force_rsn_ie(dut, state);
5136#endif /* __linux__ */
5137 default:
5138 sigma_dut_print(dut, DUT_MSG_ERROR,
5139 "Unsupported sta_60g_force_rsn_ie with the current driver");
5140 return -1;
5141 }
5142}
5143
5144
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005145static int sta_set_60g_common(struct sigma_dut *dut, struct sigma_conn *conn,
5146 struct sigma_cmd *cmd)
5147{
5148 const char *val;
5149 char buf[100];
5150
5151 val = get_param(cmd, "MSDUSize");
5152 if (val) {
5153 int mtu;
5154
5155 dut->amsdu_size = atoi(val);
5156 if (dut->amsdu_size > IEEE80211_MAX_DATA_LEN_DMG ||
5157 dut->amsdu_size < IEEE80211_SNAP_LEN_DMG) {
5158 sigma_dut_print(dut, DUT_MSG_ERROR,
5159 "MSDUSize %d is above max %d or below min %d",
5160 dut->amsdu_size,
5161 IEEE80211_MAX_DATA_LEN_DMG,
5162 IEEE80211_SNAP_LEN_DMG);
5163 dut->amsdu_size = 0;
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005164 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005165 }
5166
5167 mtu = dut->amsdu_size - IEEE80211_SNAP_LEN_DMG;
5168 sigma_dut_print(dut, DUT_MSG_DEBUG,
5169 "Setting amsdu_size to %d", mtu);
5170 snprintf(buf, sizeof(buf), "ifconfig %s mtu %d",
5171 get_station_ifname(), mtu);
5172
5173 if (system(buf) != 0) {
5174 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
5175 buf);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005176 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005177 }
5178 }
5179
5180 val = get_param(cmd, "BAckRcvBuf");
5181 if (val) {
5182 dut->back_rcv_buf = atoi(val);
5183 if (dut->back_rcv_buf == 0) {
5184 sigma_dut_print(dut, DUT_MSG_ERROR,
5185 "Failed to convert %s or value is 0",
5186 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005187 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005188 }
5189
5190 sigma_dut_print(dut, DUT_MSG_DEBUG,
5191 "Setting BAckRcvBuf to %s", val);
5192 }
5193
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02005194 val = get_param(cmd, "MCS_FixedRate");
5195 if (val) {
5196 if (sta_set_force_mcs(dut, 1, atoi(val))) {
5197 sigma_dut_print(dut, DUT_MSG_ERROR,
5198 "Failed to force MCS");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005199 return ERROR_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02005200 }
5201 }
5202
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005203 return SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005204}
5205
5206
5207static int sta_pcp_start(struct sigma_dut *dut, struct sigma_conn *conn,
5208 struct sigma_cmd *cmd)
5209{
5210 int net_id;
5211 char *ifname;
5212 const char *val;
5213 char buf[100];
5214
5215 dut->mode = SIGMA_MODE_STATION;
5216 ifname = get_main_ifname();
5217 if (wpa_command(ifname, "PING") != 0) {
5218 sigma_dut_print(dut, DUT_MSG_ERROR, "Supplicant not running");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005219 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005220 }
5221
5222 wpa_command(ifname, "FLUSH");
5223 net_id = add_network_common(dut, conn, ifname, cmd);
5224 if (net_id < 0) {
5225 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add network");
5226 return net_id;
5227 }
5228
5229 /* TODO: mode=2 for the AP; in the future, replace for mode PCP */
5230 if (set_network(ifname, net_id, "mode", "2") < 0) {
5231 sigma_dut_print(dut, DUT_MSG_ERROR,
5232 "Failed to set supplicant network mode");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005233 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005234 }
5235
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02005236 if (set_network(ifname, net_id, "pbss", "1") < 0)
5237 return -2;
5238
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005239 sigma_dut_print(dut, DUT_MSG_DEBUG,
Alexei Avshalom Lazarfd9f1352018-11-13 14:07:58 +02005240 "Supplicant set network with mode 2. network_id %d",
5241 net_id);
5242
5243 if (set_network(ifname, net_id, "wps_disabled", "0") < 0) {
5244 sigma_dut_print(dut, DUT_MSG_INFO,
5245 "Failed to set supplicant to WPS ENABLE");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005246 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarfd9f1352018-11-13 14:07:58 +02005247 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005248
5249 val = get_param(cmd, "Security");
5250 if (val && strcasecmp(val, "OPEN") == 0) {
5251 dut->ap_key_mgmt = AP_OPEN;
5252 if (set_network(ifname, net_id, "key_mgmt", "NONE") < 0) {
5253 sigma_dut_print(dut, DUT_MSG_ERROR,
5254 "Failed to set supplicant to %s security",
5255 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005256 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005257 }
5258 } else if (val && strcasecmp(val, "WPA2-PSK") == 0) {
5259 dut->ap_key_mgmt = AP_WPA2_PSK;
5260 if (set_network(ifname, net_id, "key_mgmt", "WPA-PSK") < 0) {
5261 sigma_dut_print(dut, DUT_MSG_ERROR,
5262 "Failed to set supplicant to %s security",
5263 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005264 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005265 }
5266
5267 if (set_network(ifname, net_id, "proto", "RSN") < 0) {
5268 sigma_dut_print(dut, DUT_MSG_ERROR,
5269 "Failed to set supplicant to proto RSN");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005270 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005271 }
5272 } else if (val) {
5273 sigma_dut_print(dut, DUT_MSG_ERROR,
5274 "Requested Security %s is not supported on 60GHz",
5275 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005276 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005277 }
5278
5279 val = get_param(cmd, "Encrypt");
5280 if (val && strcasecmp(val, "AES-GCMP") == 0) {
5281 if (set_network(ifname, net_id, "pairwise", "GCMP") < 0) {
5282 sigma_dut_print(dut, DUT_MSG_ERROR,
5283 "Failed to set supplicant to pairwise GCMP");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005284 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005285 }
5286 if (set_network(ifname, net_id, "group", "GCMP") < 0) {
5287 sigma_dut_print(dut, DUT_MSG_ERROR,
5288 "Failed to set supplicant to group GCMP");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005289 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005290 }
5291 } else if (val) {
5292 sigma_dut_print(dut, DUT_MSG_ERROR,
5293 "Requested Encrypt %s is not supported on 60 GHz",
5294 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005295 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005296 }
5297
5298 val = get_param(cmd, "PSK");
5299 if (val && set_network_quoted(ifname, net_id, "psk", val) < 0) {
5300 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set psk %s",
5301 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005302 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005303 }
5304
5305 /* Convert 60G channel to freq */
5306 switch (dut->ap_channel) {
5307 case 1:
5308 val = "58320";
5309 break;
5310 case 2:
5311 val = "60480";
5312 break;
5313 case 3:
5314 val = "62640";
5315 break;
5316 default:
5317 sigma_dut_print(dut, DUT_MSG_ERROR,
5318 "Failed to configure channel %d. Not supported",
5319 dut->ap_channel);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005320 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005321 }
5322
5323 if (set_network(ifname, net_id, "frequency", val) < 0) {
5324 sigma_dut_print(dut, DUT_MSG_ERROR,
5325 "Failed to set supplicant network frequency");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005326 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005327 }
5328
Alexei Avshalom Lazar2eccf4d2019-01-31 10:03:59 +02005329 if (dut->eap_fragment) {
5330 sigma_dut_print(dut, DUT_MSG_DEBUG,
5331 "Set EAP fragment size to 128 bytes.");
5332 if (set_network(ifname, net_id, "fragment_size", "128") < 0)
5333 return ERROR_SEND_STATUS;
5334 }
5335
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005336 sigma_dut_print(dut, DUT_MSG_DEBUG,
5337 "Supplicant set network with frequency");
5338
5339 snprintf(buf, sizeof(buf), "SELECT_NETWORK %d", net_id);
5340 if (wpa_command(ifname, buf) < 0) {
5341 sigma_dut_print(dut, DUT_MSG_INFO,
5342 "Failed to select network id %d on %s",
5343 net_id, ifname);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005344 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005345 }
5346
5347 sigma_dut_print(dut, DUT_MSG_DEBUG, "Selected network");
5348
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005349 return SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005350}
5351
5352
Lior David67543f52017-01-03 19:04:22 +02005353static int wil6210_set_abft_len(struct sigma_dut *dut, int abft_len)
5354{
5355 char buf[128], fname[128];
5356 FILE *f;
5357
5358 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
5359 sigma_dut_print(dut, DUT_MSG_ERROR,
5360 "failed to get wil6210 debugfs dir");
5361 return -1;
5362 }
5363
5364 snprintf(fname, sizeof(fname), "%s/abft_len", buf);
5365 f = fopen(fname, "w");
5366 if (!f) {
5367 sigma_dut_print(dut, DUT_MSG_ERROR,
5368 "failed to open: %s", fname);
5369 return -1;
5370 }
5371
5372 fprintf(f, "%d\n", abft_len);
5373 fclose(f);
5374
5375 return 0;
5376}
5377
5378
Alexei Avshalom Lazar49498b82019-01-31 15:16:32 +02005379int sta_set_60g_abft_len(struct sigma_dut *dut, struct sigma_conn *conn,
5380 int abft_len)
Lior David67543f52017-01-03 19:04:22 +02005381{
5382 switch (get_driver_type()) {
5383 case DRIVER_WIL6210:
5384 return wil6210_set_abft_len(dut, abft_len);
5385 default:
5386 sigma_dut_print(dut, DUT_MSG_ERROR,
5387 "set abft_len not supported");
5388 return -1;
5389 }
5390}
5391
5392
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005393static int sta_set_60g_pcp(struct sigma_dut *dut, struct sigma_conn *conn,
5394 struct sigma_cmd *cmd)
5395{
5396 const char *val;
Lior David67543f52017-01-03 19:04:22 +02005397 unsigned int abft_len = 1; /* default is one slot */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005398
5399 if (dut->dev_role != DEVROLE_PCP) {
5400 send_resp(dut, conn, SIGMA_INVALID,
5401 "ErrorCode,Invalid DevRole");
5402 return 0;
5403 }
5404
5405 val = get_param(cmd, "SSID");
5406 if (val) {
5407 if (strlen(val) > sizeof(dut->ap_ssid) - 1) {
5408 send_resp(dut, conn, SIGMA_INVALID,
5409 "ErrorCode,Invalid SSID");
5410 return -1;
5411 }
5412
Peng Xub8fc5cc2017-05-10 17:27:28 -07005413 strlcpy(dut->ap_ssid, val, sizeof(dut->ap_ssid));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005414 }
5415
5416 val = get_param(cmd, "CHANNEL");
5417 if (val) {
5418 const char *pos;
5419
5420 dut->ap_channel = atoi(val);
5421 pos = strchr(val, ';');
5422 if (pos) {
5423 pos++;
5424 dut->ap_channel_1 = atoi(pos);
5425 }
5426 }
5427
5428 switch (dut->ap_channel) {
5429 case 1:
5430 case 2:
5431 case 3:
5432 break;
5433 default:
5434 sigma_dut_print(dut, DUT_MSG_ERROR,
5435 "Channel %d is not supported", dut->ap_channel);
5436 send_resp(dut, conn, SIGMA_ERROR,
5437 "Requested channel is not supported");
5438 return -1;
5439 }
5440
5441 val = get_param(cmd, "BCNINT");
5442 if (val)
5443 dut->ap_bcnint = atoi(val);
5444
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005445 val = get_param(cmd, "AllocType");
5446 if (val) {
5447 send_resp(dut, conn, SIGMA_ERROR,
5448 "ErrorCode,AllocType is not supported yet");
5449 return -1;
5450 }
5451
5452 val = get_param(cmd, "PercentBI");
5453 if (val) {
5454 send_resp(dut, conn, SIGMA_ERROR,
5455 "ErrorCode,PercentBI is not supported yet");
5456 return -1;
5457 }
5458
5459 val = get_param(cmd, "CBAPOnly");
5460 if (val) {
5461 send_resp(dut, conn, SIGMA_ERROR,
5462 "ErrorCode,CBAPOnly is not supported yet");
5463 return -1;
5464 }
5465
5466 val = get_param(cmd, "AMPDU");
5467 if (val) {
5468 if (strcasecmp(val, "Enable") == 0)
5469 dut->ap_ampdu = 1;
5470 else if (strcasecmp(val, "Disable") == 0)
5471 dut->ap_ampdu = 2;
5472 else {
5473 send_resp(dut, conn, SIGMA_ERROR,
5474 "ErrorCode,AMPDU value is not Enable nor Disabled");
5475 return -1;
5476 }
5477 }
5478
5479 val = get_param(cmd, "AMSDU");
5480 if (val) {
5481 if (strcasecmp(val, "Enable") == 0)
5482 dut->ap_amsdu = 1;
5483 else if (strcasecmp(val, "Disable") == 0)
5484 dut->ap_amsdu = 2;
5485 }
5486
5487 val = get_param(cmd, "NumMSDU");
5488 if (val) {
5489 send_resp(dut, conn, SIGMA_ERROR,
5490 "ErrorCode, NumMSDU is not supported yet");
5491 return -1;
5492 }
5493
5494 val = get_param(cmd, "ABFTLRang");
5495 if (val) {
5496 sigma_dut_print(dut, DUT_MSG_DEBUG,
Lior David67543f52017-01-03 19:04:22 +02005497 "ABFTLRang parameter %s", val);
5498 if (strcmp(val, "Gt1") == 0)
5499 abft_len = 2; /* 2 slots in this case */
5500 }
5501
5502 if (sta_set_60g_abft_len(dut, conn, abft_len)) {
5503 send_resp(dut, conn, SIGMA_ERROR,
5504 "ErrorCode, Can't set ABFT length");
5505 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005506 }
5507
5508 if (sta_pcp_start(dut, conn, cmd) < 0) {
5509 send_resp(dut, conn, SIGMA_ERROR,
5510 "ErrorCode, Can't start PCP role");
5511 return -1;
5512 }
5513
5514 return sta_set_60g_common(dut, conn, cmd);
5515}
5516
5517
5518static int sta_set_60g_sta(struct sigma_dut *dut, struct sigma_conn *conn,
5519 struct sigma_cmd *cmd)
5520{
5521 const char *val = get_param(cmd, "DiscoveryMode");
5522
5523 if (dut->dev_role != DEVROLE_STA) {
5524 send_resp(dut, conn, SIGMA_INVALID,
5525 "ErrorCode,Invalid DevRole");
5526 return 0;
5527 }
5528
5529 if (val) {
5530 sigma_dut_print(dut, DUT_MSG_DEBUG, "Discovery: %s", val);
5531 /* Ignore Discovery mode till Driver expose API. */
5532#if 0
5533 if (strcasecmp(val, "1") == 0) {
5534 send_resp(dut, conn, SIGMA_INVALID,
5535 "ErrorCode,DiscoveryMode 1 not supported");
5536 return 0;
5537 }
5538
5539 if (strcasecmp(val, "0") == 0) {
5540 /* OK */
5541 } else {
5542 send_resp(dut, conn, SIGMA_INVALID,
5543 "ErrorCode,DiscoveryMode not supported");
5544 return 0;
5545 }
5546#endif
5547 }
5548
5549 if (start_sta_mode(dut) != 0)
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005550 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005551 return sta_set_60g_common(dut, conn, cmd);
5552}
5553
5554
5555static int cmd_sta_disconnect(struct sigma_dut *dut, struct sigma_conn *conn,
5556 struct sigma_cmd *cmd)
5557{
5558 const char *intf = get_param(cmd, "Interface");
Jouni Malinened77e672018-01-10 16:45:13 +02005559 const char *val = get_param(cmd, "maintain_profile");
vamsi krishnad605c422017-09-20 14:56:31 +05305560
Jouni Malinened77e672018-01-10 16:45:13 +02005561 if (dut->program == PROGRAM_OCE ||
Amarnath Hullur Subramanyamebeda9e2018-01-31 03:21:48 -08005562 dut->program == PROGRAM_HE ||
Jouni Malinened77e672018-01-10 16:45:13 +02005563 (val && atoi(val) == 1)) {
vamsi krishnad605c422017-09-20 14:56:31 +05305564 wpa_command(intf, "DISCONNECT");
5565 return 1;
5566 }
5567
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005568 disconnect_station(dut);
5569 /* Try to ignore old scan results to avoid HS 2.0R2 test case failures
5570 * due to cached results. */
5571 wpa_command(intf, "SET ignore_old_scan_res 1");
5572 wpa_command(intf, "BSS_FLUSH");
5573 return 1;
5574}
5575
5576
5577static int cmd_sta_reassoc(struct sigma_dut *dut, struct sigma_conn *conn,
5578 struct sigma_cmd *cmd)
5579{
5580 const char *intf = get_param(cmd, "Interface");
5581 const char *bssid = get_param(cmd, "bssid");
5582 const char *val = get_param(cmd, "CHANNEL");
5583 struct wpa_ctrl *ctrl;
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05305584 char buf[1000];
Sunil Duttd30ce092018-01-11 23:56:29 +05305585 char result[32];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005586 int res;
5587 int chan = 0;
Ashwini Patil467efef2017-05-25 12:18:27 +05305588 int status = 0;
Sunil Duttd30ce092018-01-11 23:56:29 +05305589 int fastreassoc = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005590
5591 if (bssid == NULL) {
5592 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing bssid "
5593 "argument");
5594 return 0;
5595 }
5596
5597 if (val)
5598 chan = atoi(val);
5599
5600 if (wifi_chip_type != DRIVER_WCN && wifi_chip_type != DRIVER_AR6003) {
5601 /* The current network may be from sta_associate or
5602 * sta_hs2_associate
5603 */
5604 if (set_network(intf, dut->infra_network_id, "bssid", bssid) <
5605 0 ||
5606 set_network(intf, 0, "bssid", bssid) < 0)
5607 return -2;
5608 }
5609
5610 ctrl = open_wpa_mon(intf);
5611 if (ctrl == NULL) {
5612 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
5613 "wpa_supplicant monitor connection");
5614 return -1;
5615 }
5616
Sunil Duttd30ce092018-01-11 23:56:29 +05305617 if (get_wpa_status(get_station_ifname(), "wpa_state", result,
5618 sizeof(result)) < 0 ||
5619 strncmp(result, "COMPLETED", 9) != 0) {
5620 sigma_dut_print(dut, DUT_MSG_DEBUG,
5621 "sta_reassoc: Not connected");
5622 fastreassoc = 0;
5623 }
5624
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05305625 if (dut->rsne_override) {
5626#ifdef NL80211_SUPPORT
5627 if (get_driver_type() == DRIVER_WCN && dut->config_rsnie == 0) {
5628 sta_config_rsnie(dut, 1);
5629 dut->config_rsnie = 1;
5630 }
5631#endif /* NL80211_SUPPORT */
5632 snprintf(buf, sizeof(buf), "TEST_ASSOC_IE %s",
5633 dut->rsne_override);
5634 if (wpa_command(intf, buf) < 0) {
5635 send_resp(dut, conn, SIGMA_ERROR,
5636 "ErrorCode,Failed to set DEV_CONFIGURE_IE RSNE override");
5637 return 0;
5638 }
5639 }
5640
Sunil Duttd30ce092018-01-11 23:56:29 +05305641 if (wifi_chip_type == DRIVER_WCN && fastreassoc) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005642#ifdef ANDROID
Ashwini Patil4c8158f2017-05-25 12:49:21 +05305643 if (chan) {
5644 unsigned int freq;
5645
Alexei Avshalom Lazar093569f2018-11-13 14:08:17 +02005646 freq = channel_to_freq(dut, chan);
Ashwini Patil4c8158f2017-05-25 12:49:21 +05305647 if (!freq) {
5648 sigma_dut_print(dut, DUT_MSG_ERROR,
5649 "Invalid channel number provided: %d",
5650 chan);
5651 send_resp(dut, conn, SIGMA_INVALID,
5652 "ErrorCode,Invalid channel number");
5653 goto close_mon_conn;
5654 }
5655 res = snprintf(buf, sizeof(buf),
5656 "SCAN TYPE=ONLY freq=%d", freq);
5657 } else {
5658 res = snprintf(buf, sizeof(buf), "SCAN TYPE=ONLY");
5659 }
5660 if (res < 0 || res >= (int) sizeof(buf)) {
5661 send_resp(dut, conn, SIGMA_ERROR,
5662 "ErrorCode,snprintf failed");
5663 goto close_mon_conn;
5664 }
5665 if (wpa_command(intf, buf) < 0) {
5666 sigma_dut_print(dut, DUT_MSG_INFO,
5667 "Failed to start scan");
5668 send_resp(dut, conn, SIGMA_ERROR,
5669 "ErrorCode,scan failed");
5670 goto close_mon_conn;
5671 }
5672
5673 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
5674 buf, sizeof(buf));
5675 if (res < 0) {
5676 sigma_dut_print(dut, DUT_MSG_INFO,
5677 "Scan did not complete");
5678 send_resp(dut, conn, SIGMA_ERROR,
5679 "ErrorCode,scan did not complete");
5680 goto close_mon_conn;
5681 }
5682
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005683 if (set_network(intf, dut->infra_network_id, "bssid", "any")
5684 < 0) {
5685 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
5686 "bssid to any during FASTREASSOC");
Ashwini Patil467efef2017-05-25 12:18:27 +05305687 status = -2;
5688 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005689 }
5690 res = snprintf(buf, sizeof(buf), "DRIVER FASTREASSOC %s %d",
5691 bssid, chan);
5692 if (res > 0 && res < (int) sizeof(buf))
5693 res = wpa_command(intf, buf);
5694
5695 if (res < 0 || res >= (int) sizeof(buf)) {
5696 send_resp(dut, conn, SIGMA_ERROR,
5697 "errorCode,Failed to run DRIVER FASTREASSOC");
Ashwini Patil467efef2017-05-25 12:18:27 +05305698 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005699 }
5700#else /* ANDROID */
5701 sigma_dut_print(dut, DUT_MSG_DEBUG,
5702 "Reassoc using iwpriv - skip chan=%d info",
5703 chan);
5704 snprintf(buf, sizeof(buf), "iwpriv %s reassoc", intf);
5705 if (system(buf) != 0) {
5706 sigma_dut_print(dut, DUT_MSG_ERROR, "%s failed", buf);
Ashwini Patil467efef2017-05-25 12:18:27 +05305707 status = -2;
5708 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005709 }
5710#endif /* ANDROID */
5711 sigma_dut_print(dut, DUT_MSG_INFO,
5712 "sta_reassoc: Run %s successful", buf);
5713 } else if (wpa_command(intf, "REASSOCIATE")) {
5714 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
5715 "request reassociation");
Ashwini Patil467efef2017-05-25 12:18:27 +05305716 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005717 }
5718
5719 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
5720 buf, sizeof(buf));
Ashwini Patil467efef2017-05-25 12:18:27 +05305721 if (res < 0) {
5722 sigma_dut_print(dut, DUT_MSG_INFO, "Connection did not complete");
5723 status = -1;
5724 goto close_mon_conn;
5725 }
5726 status = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005727
Ashwini Patil467efef2017-05-25 12:18:27 +05305728close_mon_conn:
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005729 wpa_ctrl_detach(ctrl);
5730 wpa_ctrl_close(ctrl);
Ashwini Patil467efef2017-05-25 12:18:27 +05305731 return status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005732}
5733
5734
5735static void hs2_clear_credentials(const char *intf)
5736{
5737 wpa_command(intf, "REMOVE_CRED all");
5738}
5739
5740
Lior Davidcc88b562017-01-03 18:52:09 +02005741#ifdef __linux__
5742static int wil6210_get_aid(struct sigma_dut *dut, const char *bssid,
5743 unsigned int *aid)
5744{
Lior David0fe101e2017-03-09 16:09:50 +02005745 const char *pattern = "AID[ \t]+([0-9]+)";
Lior Davidcc88b562017-01-03 18:52:09 +02005746
Lior David0fe101e2017-03-09 16:09:50 +02005747 return wil6210_get_sta_info_field(dut, bssid, pattern, aid);
Lior Davidcc88b562017-01-03 18:52:09 +02005748}
5749#endif /* __linux__ */
5750
5751
5752static int sta_get_aid_60g(struct sigma_dut *dut, const char *bssid,
5753 unsigned int *aid)
5754{
5755 switch (get_driver_type()) {
5756#ifdef __linux__
5757 case DRIVER_WIL6210:
5758 return wil6210_get_aid(dut, bssid, aid);
5759#endif /* __linux__ */
5760 default:
5761 sigma_dut_print(dut, DUT_MSG_ERROR, "get AID not supported");
5762 return -1;
5763 }
5764}
5765
5766
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005767static int sta_get_parameter_60g(struct sigma_dut *dut, struct sigma_conn *conn,
5768 struct sigma_cmd *cmd)
5769{
5770 char buf[MAX_CMD_LEN];
5771 char bss_list[MAX_CMD_LEN];
5772 const char *parameter = get_param(cmd, "Parameter");
5773
5774 if (parameter == NULL)
5775 return -1;
5776
Lior Davidcc88b562017-01-03 18:52:09 +02005777 if (strcasecmp(parameter, "AID") == 0) {
5778 unsigned int aid = 0;
5779 char bssid[20];
5780
5781 if (get_wpa_status(get_station_ifname(), "bssid",
5782 bssid, sizeof(bssid)) < 0) {
5783 sigma_dut_print(dut, DUT_MSG_ERROR,
5784 "could not get bssid");
5785 return -2;
5786 }
5787
5788 if (sta_get_aid_60g(dut, bssid, &aid))
5789 return -2;
5790
5791 snprintf(buf, sizeof(buf), "aid,%d", aid);
5792 sigma_dut_print(dut, DUT_MSG_INFO, "%s", buf);
5793 send_resp(dut, conn, SIGMA_COMPLETE, buf);
5794 return 0;
5795 }
5796
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005797 if (strcasecmp(parameter, "DiscoveredDevList") == 0) {
5798 char *bss_line;
5799 char *bss_id = NULL;
5800 const char *ifname = get_param(cmd, "Interface");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05305801 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005802
5803 if (ifname == NULL) {
5804 sigma_dut_print(dut, DUT_MSG_INFO,
5805 "For get DiscoveredDevList need Interface name.");
5806 return -1;
5807 }
5808
5809 /*
5810 * Use "BSS RANGE=ALL MASK=0x2" which provides a list
5811 * of BSSIDs in "bssid=<BSSID>\n"
5812 */
5813 if (wpa_command_resp(ifname, "BSS RANGE=ALL MASK=0x2",
5814 bss_list,
5815 sizeof(bss_list)) < 0) {
5816 sigma_dut_print(dut, DUT_MSG_ERROR,
5817 "Failed to get bss list");
5818 return -1;
5819 }
5820
5821 sigma_dut_print(dut, DUT_MSG_DEBUG,
5822 "bss list for ifname:%s is:%s",
5823 ifname, bss_list);
5824
5825 snprintf(buf, sizeof(buf), "DeviceList");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05305826 bss_line = strtok_r(bss_list, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005827 while (bss_line) {
5828 if (sscanf(bss_line, "bssid=%ms", &bss_id) > 0 &&
5829 bss_id) {
5830 int len;
5831
5832 len = snprintf(buf + strlen(buf),
5833 sizeof(buf) - strlen(buf),
5834 ",%s", bss_id);
5835 free(bss_id);
5836 bss_id = NULL;
5837 if (len < 0) {
5838 sigma_dut_print(dut,
5839 DUT_MSG_ERROR,
5840 "Failed to read BSSID");
5841 send_resp(dut, conn, SIGMA_ERROR,
5842 "ErrorCode,Failed to read BSS ID");
5843 return 0;
5844 }
5845
5846 if ((size_t) len >= sizeof(buf) - strlen(buf)) {
5847 sigma_dut_print(dut,
5848 DUT_MSG_ERROR,
5849 "Response buf too small for list");
5850 send_resp(dut, conn,
5851 SIGMA_ERROR,
5852 "ErrorCode,Response buf too small for list");
5853 return 0;
5854 }
5855 }
5856
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05305857 bss_line = strtok_r(NULL, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005858 }
5859
5860 sigma_dut_print(dut, DUT_MSG_INFO, "DiscoveredDevList is %s",
5861 buf);
5862 send_resp(dut, conn, SIGMA_COMPLETE, buf);
5863 return 0;
5864 }
5865
5866 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
5867 return 0;
5868}
5869
5870
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07005871static int sta_get_parameter_he(struct sigma_dut *dut, struct sigma_conn *conn,
5872 struct sigma_cmd *cmd)
5873{
5874 char buf[MAX_CMD_LEN];
5875 const char *parameter = get_param(cmd, "Parameter");
5876
5877 if (!parameter)
5878 return -1;
5879
5880 if (strcasecmp(parameter, "RSSI") == 0) {
5881 char rssi[10];
5882
5883 if (get_wpa_signal_poll(dut, get_station_ifname(), "RSSI",
5884 rssi, sizeof(rssi)) < 0) {
5885 sigma_dut_print(dut, DUT_MSG_ERROR,
5886 "Could not get RSSI");
5887 return -2;
5888 }
5889
5890 snprintf(buf, sizeof(buf), "rssi,%s", rssi);
5891 sigma_dut_print(dut, DUT_MSG_INFO, "RSSI %s", buf);
5892 send_resp(dut, conn, SIGMA_COMPLETE, buf);
5893 return 0;
5894 }
5895
5896 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
5897 return 0;
5898}
5899
5900
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005901static int cmd_sta_get_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
5902 struct sigma_cmd *cmd)
5903{
5904 const char *program = get_param(cmd, "Program");
5905
5906 if (program == NULL)
5907 return -1;
5908
5909 if (strcasecmp(program, "P2PNFC") == 0)
5910 return p2p_cmd_sta_get_parameter(dut, conn, cmd);
5911
5912 if (strcasecmp(program, "60ghz") == 0)
5913 return sta_get_parameter_60g(dut, conn, cmd);
5914
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07005915 if (strcasecmp(program, "he") == 0)
5916 return sta_get_parameter_he(dut, conn, cmd);
5917
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005918#ifdef ANDROID_NAN
5919 if (strcasecmp(program, "NAN") == 0)
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07005920 return nan_cmd_sta_get_parameter(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005921#endif /* ANDROID_NAN */
5922
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07005923#ifdef MIRACAST
5924 if (strcasecmp(program, "WFD") == 0 ||
5925 strcasecmp(program, "DisplayR2") == 0)
5926 return miracast_cmd_sta_get_parameter(dut, conn, cmd);
5927#endif /* MIRACAST */
5928
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005929 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
5930 return 0;
5931}
5932
5933
5934static void sta_reset_default_ath(struct sigma_dut *dut, const char *intf,
5935 const char *type)
5936{
5937 char buf[100];
5938
5939 if (dut->program == PROGRAM_VHT) {
5940 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 2", intf);
5941 if (system(buf) != 0) {
5942 sigma_dut_print(dut, DUT_MSG_ERROR,
5943 "iwpriv %s chwidth failed", intf);
5944 }
5945
5946 snprintf(buf, sizeof(buf), "iwpriv %s mode 11ACVHT80", intf);
5947 if (system(buf) != 0) {
5948 sigma_dut_print(dut, DUT_MSG_ERROR,
5949 "iwpriv %s mode 11ACVHT80 failed",
5950 intf);
5951 }
5952
5953 snprintf(buf, sizeof(buf), "iwpriv %s vhtmcs -1", intf);
5954 if (system(buf) != 0) {
5955 sigma_dut_print(dut, DUT_MSG_ERROR,
5956 "iwpriv %s vhtmcs -1 failed", intf);
5957 }
5958 }
5959
5960 if (dut->program == PROGRAM_HT) {
5961 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 0", intf);
5962 if (system(buf) != 0) {
5963 sigma_dut_print(dut, DUT_MSG_ERROR,
5964 "iwpriv %s chwidth failed", intf);
5965 }
5966
5967 snprintf(buf, sizeof(buf), "iwpriv %s mode 11naht40", intf);
5968 if (system(buf) != 0) {
5969 sigma_dut_print(dut, DUT_MSG_ERROR,
5970 "iwpriv %s mode 11naht40 failed",
5971 intf);
5972 }
5973
5974 snprintf(buf, sizeof(buf), "iwpriv %s set11NRates 0", intf);
5975 if (system(buf) != 0) {
5976 sigma_dut_print(dut, DUT_MSG_ERROR,
5977 "iwpriv set11NRates failed");
5978 }
5979 }
5980
5981 if (dut->program == PROGRAM_VHT || dut->program == PROGRAM_HT) {
5982 snprintf(buf, sizeof(buf), "iwpriv %s powersave 0", intf);
5983 if (system(buf) != 0) {
5984 sigma_dut_print(dut, DUT_MSG_ERROR,
5985 "disabling powersave failed");
5986 }
5987
5988 /* Reset CTS width */
5989 snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 54 0",
5990 intf);
5991 if (system(buf) != 0) {
5992 sigma_dut_print(dut, DUT_MSG_ERROR,
5993 "wifitool %s beeliner_fw_test 54 0 failed",
5994 intf);
5995 }
5996
5997 /* Enable Dynamic Bandwidth signalling by default */
5998 snprintf(buf, sizeof(buf), "iwpriv %s cwmenable 1", intf);
5999 if (system(buf) != 0) {
6000 sigma_dut_print(dut, DUT_MSG_ERROR,
6001 "iwpriv %s cwmenable 1 failed", intf);
6002 }
6003
6004 snprintf(buf, sizeof(buf), "iwconfig %s rts 2347", intf);
6005 if (system(buf) != 0) {
6006 sigma_dut_print(dut, DUT_MSG_ERROR,
6007 "iwpriv rts failed");
6008 }
6009 }
6010
6011 if (type && strcasecmp(type, "Testbed") == 0) {
6012 dut->testbed_flag_txsp = 1;
6013 dut->testbed_flag_rxsp = 1;
6014 /* STA has to set spatial stream to 2 per Appendix H */
6015 snprintf(buf, sizeof(buf), "iwpriv %s vht_mcsmap 0xfff0", intf);
6016 if (system(buf) != 0) {
6017 sigma_dut_print(dut, DUT_MSG_ERROR,
6018 "iwpriv vht_mcsmap failed");
6019 }
6020
6021 /* Disable LDPC per Appendix H */
6022 snprintf(buf, sizeof(buf), "iwpriv %s ldpc 0", intf);
6023 if (system(buf) != 0) {
6024 sigma_dut_print(dut, DUT_MSG_ERROR,
6025 "iwpriv %s ldpc 0 failed", intf);
6026 }
6027
6028 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 1", intf);
6029 if (system(buf) != 0) {
6030 sigma_dut_print(dut, DUT_MSG_ERROR,
6031 "iwpriv amsdu failed");
6032 }
6033
6034 /* TODO: Disable STBC 2x1 transmit and receive */
6035 snprintf(buf, sizeof(buf), "iwpriv %s tx_stbc 0", intf);
6036 if (system(buf) != 0) {
6037 sigma_dut_print(dut, DUT_MSG_ERROR,
6038 "Disable tx_stbc 0 failed");
6039 }
6040
6041 snprintf(buf, sizeof(buf), "iwpriv %s rx_stbc 0", intf);
6042 if (system(buf) != 0) {
6043 sigma_dut_print(dut, DUT_MSG_ERROR,
6044 "Disable rx_stbc 0 failed");
6045 }
6046
6047 /* STA has to disable Short GI per Appendix H */
6048 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 0", intf);
6049 if (system(buf) != 0) {
6050 sigma_dut_print(dut, DUT_MSG_ERROR,
6051 "iwpriv %s shortgi 0 failed", intf);
6052 }
6053 }
6054
6055 if (type && strcasecmp(type, "DUT") == 0) {
6056 snprintf(buf, sizeof(buf), "iwpriv %s nss 3", intf);
6057 if (system(buf) != 0) {
6058 sigma_dut_print(dut, DUT_MSG_ERROR,
6059 "iwpriv %s nss 3 failed", intf);
6060 }
Arif Hussainac6c5112018-05-25 17:34:00 -07006061 dut->sta_nss = 3;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006062
6063 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 1", intf);
6064 if (system(buf) != 0) {
6065 sigma_dut_print(dut, DUT_MSG_ERROR,
6066 "iwpriv %s shortgi 1 failed", intf);
6067 }
6068 }
6069}
6070
6071
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08006072#ifdef NL80211_SUPPORT
6073static int sta_set_he_mcs(struct sigma_dut *dut, const char *intf,
6074 enum he_mcs_config mcs)
6075{
6076 struct nl_msg *msg;
6077 int ret = 0;
6078 struct nlattr *params;
6079 int ifindex;
6080
6081 ifindex = if_nametoindex(intf);
6082 if (ifindex == 0) {
6083 sigma_dut_print(dut, DUT_MSG_ERROR,
6084 "%s: Index for interface %s failed",
6085 __func__, intf);
6086 return -1;
6087 }
6088
6089 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6090 NL80211_CMD_VENDOR)) ||
6091 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6092 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6093 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6094 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6095 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6096 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MCS,
6097 mcs)) {
6098 sigma_dut_print(dut, DUT_MSG_ERROR,
6099 "%s: err in adding vendor_cmd and vendor_data",
6100 __func__);
6101 nlmsg_free(msg);
6102 return -1;
6103 }
6104 nla_nest_end(msg, params);
6105
6106 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6107 if (ret) {
6108 sigma_dut_print(dut, DUT_MSG_ERROR,
6109 "%s: err in send_and_recv_msgs, ret=%d",
6110 __func__, ret);
6111 }
6112 return ret;
6113}
6114#endif /* NL80211_SUPPORT */
6115
6116
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07006117static int sta_set_action_tx_in_he_tb_ppdu(struct sigma_dut *dut,
6118 const char *intf, int enable)
6119{
6120#ifdef NL80211_SUPPORT
6121 struct nl_msg *msg;
6122 int ret = 0;
6123 struct nlattr *params;
6124 int ifindex;
6125
6126 ifindex = if_nametoindex(intf);
6127 if (ifindex == 0) {
6128 sigma_dut_print(dut, DUT_MSG_ERROR,
6129 "%s: Index for interface %s failed",
6130 __func__, intf);
6131 return -1;
6132 }
6133
6134 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6135 NL80211_CMD_VENDOR)) ||
6136 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6137 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6138 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6139 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6140 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6141 nla_put_u8(msg,
6142 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_ACTION_TX_TB_PPDU,
6143 enable)) {
6144 sigma_dut_print(dut, DUT_MSG_ERROR,
6145 "%s: err in adding vendor_cmd and vendor_data",
6146 __func__);
6147 nlmsg_free(msg);
6148 return -1;
6149 }
6150 nla_nest_end(msg, params);
6151
6152 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6153 if (ret) {
6154 sigma_dut_print(dut, DUT_MSG_ERROR,
6155 "%s: err in send_and_recv_msgs, ret=%d",
6156 __func__, ret);
6157 }
6158 return ret;
6159#else /* NL80211_SUPPORT */
6160 sigma_dut_print(dut, DUT_MSG_ERROR,
6161 "HE action Tx TB PPDU cannot be set without NL80211_SUPPORT defined");
6162 return -1;
6163#endif /* NL80211_SUPPORT */
6164}
6165
6166
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08006167static int sta_set_heconfig_and_wep_tkip(struct sigma_dut *dut,
6168 const char *intf, int enable)
6169{
6170#ifdef NL80211_SUPPORT
6171 struct nl_msg *msg;
6172 int ret = 0;
6173 struct nlattr *params;
6174 int ifindex;
6175
6176 ifindex = if_nametoindex(intf);
6177 if (ifindex == 0) {
6178 sigma_dut_print(dut, DUT_MSG_ERROR,
6179 "%s: Index for interface %s failed",
6180 __func__, intf);
6181 return -1;
6182 }
6183
6184 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6185 NL80211_CMD_VENDOR)) ||
6186 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6187 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6188 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6189 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6190 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6191 nla_put_u8(msg,
6192 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WEP_TKIP_IN_HE,
6193 enable)) {
6194 sigma_dut_print(dut, DUT_MSG_ERROR,
6195 "%s: err in adding vendor_cmd and vendor_data",
6196 __func__);
6197 nlmsg_free(msg);
6198 return -1;
6199 }
6200 nla_nest_end(msg, params);
6201
6202 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6203 if (ret) {
6204 sigma_dut_print(dut, DUT_MSG_ERROR,
6205 "%s: err in send_and_recv_msgs, ret=%d",
6206 __func__, ret);
6207 }
6208 return ret;
6209#else /* NL80211_SUPPORT */
6210 sigma_dut_print(dut, DUT_MSG_ERROR,
6211 "HE config enablement cannot be changed without NL80211_SUPPORT defined");
6212 return -1;
6213#endif /* NL80211_SUPPORT */
6214}
6215
6216
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08006217static int sta_set_addba_buf_size(struct sigma_dut *dut,
6218 const char *intf, int bufsize)
6219{
6220#ifdef NL80211_SUPPORT
6221 struct nl_msg *msg;
6222 int ret = 0;
6223 struct nlattr *params;
6224 int ifindex;
6225
6226 ifindex = if_nametoindex(intf);
6227 if (ifindex == 0) {
6228 sigma_dut_print(dut, DUT_MSG_ERROR,
6229 "%s: Index for interface %s failed",
6230 __func__, intf);
6231 return -1;
6232 }
6233
6234 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6235 NL80211_CMD_VENDOR)) ||
6236 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6237 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6238 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6239 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6240 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
Kiran Kumar Lokere26e27582018-08-01 16:18:34 -07006241 nla_put_u16(msg,
6242 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE,
6243 bufsize)) {
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08006244 sigma_dut_print(dut, DUT_MSG_ERROR,
6245 "%s: err in adding vendor_cmd and vendor_data",
6246 __func__);
6247 nlmsg_free(msg);
6248 return -1;
6249 }
6250 nla_nest_end(msg, params);
6251
6252 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6253 if (ret) {
6254 sigma_dut_print(dut, DUT_MSG_ERROR,
6255 "%s: err in send_and_recv_msgs, ret=%d",
6256 __func__, ret);
6257 }
6258 return ret;
6259#else /* NL80211_SUPPORT */
6260 sigma_dut_print(dut, DUT_MSG_ERROR,
6261 "AddBA bufsize cannot be changed without NL80211_SUPPORT defined");
6262 return -1;
6263#endif /* NL80211_SUPPORT */
6264}
6265
6266
Arif Hussain8d5b27b2018-05-14 14:31:03 -07006267static int sta_set_tx_beamformee(struct sigma_dut *dut, const char *intf,
6268 int enable)
6269{
6270#ifdef NL80211_SUPPORT
6271 struct nl_msg *msg;
6272 int ret = 0;
6273 struct nlattr *params;
6274 int ifindex;
6275
6276 ifindex = if_nametoindex(intf);
6277 if (ifindex == 0) {
6278 sigma_dut_print(dut, DUT_MSG_ERROR,
6279 "%s: Index for interface %s failed",
6280 __func__, intf);
6281 return -1;
6282 }
6283
6284 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6285 NL80211_CMD_VENDOR)) ||
6286 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6287 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6288 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6289 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6290 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6291 nla_put_u8(msg,
6292 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_TX_BEAMFORMEE,
6293 enable)) {
6294 sigma_dut_print(dut, DUT_MSG_ERROR,
6295 "%s: err in adding vendor_cmd and vendor_data",
6296 __func__);
6297 nlmsg_free(msg);
6298 return -1;
6299 }
6300 nla_nest_end(msg, params);
6301
6302 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6303 if (ret) {
6304 sigma_dut_print(dut, DUT_MSG_ERROR,
6305 "%s: err in send_and_recv_msgs, ret=%d",
6306 __func__, ret);
6307 }
6308 return ret;
6309#else /* NL80211_SUPPORT */
6310 sigma_dut_print(dut, DUT_MSG_ERROR,
6311 "tx beamformee cannot be changed without NL80211_SUPPORT defined");
6312 return -1;
6313#endif /* NL80211_SUPPORT */
6314}
6315
6316
Arif Hussain9765f7d2018-07-03 08:28:26 -07006317static int sta_set_beamformee_sts(struct sigma_dut *dut, const char *intf,
6318 int val)
6319{
6320#ifdef NL80211_SUPPORT
6321 struct nl_msg *msg;
6322 int ret = 0;
6323 struct nlattr *params;
6324 int ifindex;
6325
6326 ifindex = if_nametoindex(intf);
6327 if (ifindex == 0) {
6328 sigma_dut_print(dut, DUT_MSG_ERROR,
6329 "%s: Index for interface %s failed, val:%d",
6330 __func__, intf, val);
6331 return -1;
6332 }
6333
6334 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6335 NL80211_CMD_VENDOR)) ||
6336 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6337 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6338 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6339 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6340 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6341 nla_put_u8(msg,
6342 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_BEAMFORMEE_NSTS,
6343 val)) {
6344 sigma_dut_print(dut, DUT_MSG_ERROR,
6345 "%s: err in adding vendor_cmd and vendor_data, val: %d",
6346 __func__, val);
6347 nlmsg_free(msg);
6348 return -1;
6349 }
6350 nla_nest_end(msg, params);
6351
6352 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6353 if (ret) {
6354 sigma_dut_print(dut, DUT_MSG_ERROR,
6355 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
6356 __func__, ret, val);
6357 }
6358 return ret;
6359#else /* NL80211_SUPPORT */
6360 sigma_dut_print(dut, DUT_MSG_ERROR,
6361 "beamformee sts cannot be changed without NL80211_SUPPORT defined");
6362 return -1;
6363#endif /* NL80211_SUPPORT */
6364}
6365
6366
Arif Hussain68d23f52018-07-11 13:39:08 -07006367#ifdef NL80211_SUPPORT
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07006368static int sta_set_mac_padding_duration(struct sigma_dut *dut, const char *intf,
6369 enum qca_wlan_he_mac_padding_dur val)
6370{
Arif Hussain68d23f52018-07-11 13:39:08 -07006371 struct nl_msg *msg;
6372 int ret = 0;
6373 struct nlattr *params;
6374 int ifindex;
6375
6376 ifindex = if_nametoindex(intf);
6377 if (ifindex == 0) {
6378 sigma_dut_print(dut, DUT_MSG_ERROR,
6379 "%s: Index for interface %s failed, val:%d",
6380 __func__, intf, val);
6381 return -1;
6382 }
6383
6384 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6385 NL80211_CMD_VENDOR)) ||
6386 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6387 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6388 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6389 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6390 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6391 nla_put_u8(msg,
6392 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MAC_PADDING_DUR,
6393 val)) {
6394 sigma_dut_print(dut, DUT_MSG_ERROR,
6395 "%s: err in adding vendor_cmd and vendor_data, val: %d",
6396 __func__, val);
6397 nlmsg_free(msg);
6398 return -1;
6399 }
6400 nla_nest_end(msg, params);
6401
6402 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6403 if (ret) {
6404 sigma_dut_print(dut, DUT_MSG_ERROR,
6405 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
6406 __func__, ret, val);
6407 }
6408 return ret;
Arif Hussain68d23f52018-07-11 13:39:08 -07006409}
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07006410#endif /* NL80211_SUPPORT */
Arif Hussain68d23f52018-07-11 13:39:08 -07006411
6412
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07006413static int sta_set_tx_su_ppdu_cfg(struct sigma_dut *dut, const char *intf,
6414 int val)
6415{
6416#ifdef NL80211_SUPPORT
6417 struct nl_msg *msg;
6418 int ret = 0;
6419 struct nlattr *params;
6420 int ifindex;
6421
6422 ifindex = if_nametoindex(intf);
6423 if (ifindex == 0) {
6424 sigma_dut_print(dut, DUT_MSG_ERROR,
6425 "%s: Index for interface %s failed, val:%d",
6426 __func__, intf, val);
6427 return -1;
6428 }
6429
6430 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6431 NL80211_CMD_VENDOR)) ||
6432 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6433 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6434 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6435 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6436 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6437 nla_put_u8(msg,
6438 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_SUPPDU,
6439 val)) {
6440 sigma_dut_print(dut, DUT_MSG_ERROR,
6441 "%s: err in adding vendor_cmd and vendor_data, val: %d",
6442 __func__, val);
6443 nlmsg_free(msg);
6444 return -1;
6445 }
6446 nla_nest_end(msg, params);
6447
6448 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6449 if (ret) {
6450 sigma_dut_print(dut, DUT_MSG_ERROR,
6451 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
6452 __func__, ret, val);
6453 }
6454 return ret;
6455#else /* NL80211_SUPPORT */
6456 sigma_dut_print(dut, DUT_MSG_ERROR,
6457 "Tx SU PPDU cannot be set without NL80211_SUPPORT defined");
6458 return -1;
6459#endif /* NL80211_SUPPORT */
6460}
6461
6462
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07006463static int sta_set_he_om_ctrl_nss(struct sigma_dut *dut, const char *intf,
6464 int val)
6465{
6466#ifdef NL80211_SUPPORT
6467 struct nl_msg *msg;
6468 int ret = 0;
6469 struct nlattr *params;
6470 int ifindex;
6471
6472 ifindex = if_nametoindex(intf);
6473 if (ifindex == 0) {
6474 sigma_dut_print(dut, DUT_MSG_ERROR,
6475 "%s: Index for interface %s failed, val:%d",
6476 __func__, intf, val);
6477 return -1;
6478 }
6479
6480 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6481 NL80211_CMD_VENDOR)) ||
6482 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6483 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6484 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6485 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6486 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6487 nla_put_u8(msg,
6488 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OM_CTRL_NSS,
6489 val)) {
6490 sigma_dut_print(dut, DUT_MSG_ERROR,
6491 "%s: err in adding vendor_cmd and vendor_data, val: %d",
6492 __func__, val);
6493 nlmsg_free(msg);
6494 return -1;
6495 }
6496 nla_nest_end(msg, params);
6497
6498 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6499 if (ret) {
6500 sigma_dut_print(dut, DUT_MSG_ERROR,
6501 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
6502 __func__, ret, val);
6503 }
6504 return ret;
6505#else /* NL80211_SUPPORT */
6506 sigma_dut_print(dut, DUT_MSG_ERROR,
6507 "OM CTRL NSS cannot be set without NL80211_SUPPORT defined");
6508 return -1;
6509#endif /* NL80211_SUPPORT */
6510}
6511
6512
6513static int sta_set_he_om_ctrl_bw(struct sigma_dut *dut, const char *intf,
6514 enum qca_wlan_he_om_ctrl_ch_bw val)
6515{
6516#ifdef NL80211_SUPPORT
6517 struct nl_msg *msg;
6518 int ret = 0;
6519 struct nlattr *params;
6520 int ifindex;
6521
6522 ifindex = if_nametoindex(intf);
6523 if (ifindex == 0) {
6524 sigma_dut_print(dut, DUT_MSG_ERROR,
6525 "%s: Index for interface %s failed, val:%d",
6526 __func__, intf, val);
6527 return -1;
6528 }
6529
6530 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6531 NL80211_CMD_VENDOR)) ||
6532 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6533 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6534 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6535 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6536 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6537 nla_put_u8(msg,
6538 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OM_CTRL_BW,
6539 val)) {
6540 sigma_dut_print(dut, DUT_MSG_ERROR,
6541 "%s: err in adding vendor_cmd and vendor_data, val: %d",
6542 __func__, val);
6543 nlmsg_free(msg);
6544 return -1;
6545 }
6546 nla_nest_end(msg, params);
6547
6548 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6549 if (ret) {
6550 sigma_dut_print(dut, DUT_MSG_ERROR,
6551 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
6552 __func__, ret, val);
6553 }
6554 return ret;
6555#else /* NL80211_SUPPORT */
6556 sigma_dut_print(dut, DUT_MSG_ERROR,
6557 "OM CTRL BW cannot be set without NL80211_SUPPORT defined");
6558 return -1;
6559#endif /* NL80211_SUPPORT */
6560}
6561
6562
6563#ifdef NL80211_SUPPORT
6564static int sta_set_he_om_ctrl_reset(struct sigma_dut *dut, const char *intf)
6565{
6566 struct nl_msg *msg;
6567 int ret = 0;
6568 struct nlattr *params;
6569 int ifindex;
6570
6571 ifindex = if_nametoindex(intf);
6572 if (ifindex == 0) {
6573 sigma_dut_print(dut, DUT_MSG_ERROR,
6574 "%s: Index for interface %s failed",
6575 __func__, intf);
6576 return -1;
6577 }
6578
6579 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6580 NL80211_CMD_VENDOR)) ||
6581 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6582 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6583 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6584 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6585 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6586 nla_put_flag(msg,
6587 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_CLEAR_HE_OM_CTRL_CONFIG)) {
6588 sigma_dut_print(dut, DUT_MSG_ERROR,
6589 "%s: err in adding vendor_cmd and vendor_data",
6590 __func__);
6591 nlmsg_free(msg);
6592 return -1;
6593 }
6594 nla_nest_end(msg, params);
6595
6596 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6597 if (ret) {
6598 sigma_dut_print(dut, DUT_MSG_ERROR,
6599 "%s: err in send_and_recv_msgs, ret=%d",
6600 __func__, ret);
6601 }
6602 return ret;
6603}
6604#endif /* NL80211_SUPPORT */
6605
6606
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07006607static int sta_set_mu_edca_override(struct sigma_dut *dut, const char *intf,
6608 int val)
6609{
6610#ifdef NL80211_SUPPORT
6611 struct nl_msg *msg;
6612 int ret = 0;
6613 struct nlattr *params;
6614 int ifindex;
6615
6616 ifindex = if_nametoindex(intf);
6617 if (ifindex == 0) {
6618 sigma_dut_print(dut, DUT_MSG_ERROR,
6619 "%s: Index for interface %s failed, val:%d",
6620 __func__, intf, val);
6621 return -1;
6622 }
6623
6624 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6625 NL80211_CMD_VENDOR)) ||
6626 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6627 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6628 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6629 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6630 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6631 nla_put_u8(msg,
6632 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_OVERRIDE_MU_EDCA,
6633 val)) {
6634 sigma_dut_print(dut, DUT_MSG_ERROR,
6635 "%s: err in adding vendor_cmd and vendor_data, val: %d",
6636 __func__, val);
6637 nlmsg_free(msg);
6638 return -1;
6639 }
6640 nla_nest_end(msg, params);
6641
6642 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6643 if (ret) {
6644 sigma_dut_print(dut, DUT_MSG_ERROR,
6645 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
6646 __func__, ret, val);
6647 }
6648 return ret;
6649#else /* NL80211_SUPPORT */
6650 sigma_dut_print(dut, DUT_MSG_ERROR,
6651 "MU EDCA override cannot be changed without NL80211_SUPPORT defined");
6652 return -1;
6653#endif /* NL80211_SUPPORT */
6654}
6655
6656
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07006657static int sta_set_om_ctrl_supp(struct sigma_dut *dut, const char *intf,
6658 int val)
6659{
6660#ifdef NL80211_SUPPORT
6661 struct nl_msg *msg;
6662 int ret = 0;
6663 struct nlattr *params;
6664 int ifindex;
6665
6666 ifindex = if_nametoindex(intf);
6667 if (ifindex == 0) {
6668 sigma_dut_print(dut, DUT_MSG_ERROR,
6669 "%s: Index for interface %s failed, val:%d",
6670 __func__, intf, val);
6671 return -1;
6672 }
6673
6674 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6675 NL80211_CMD_VENDOR)) ||
6676 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6677 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6678 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6679 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6680 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6681 nla_put_u8(msg,
6682 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OM_CTRL_SUPP,
6683 val)) {
6684 sigma_dut_print(dut, DUT_MSG_ERROR,
6685 "%s: err in adding vendor_cmd and vendor_data, val: %d",
6686 __func__, val);
6687 nlmsg_free(msg);
6688 return -1;
6689 }
6690 nla_nest_end(msg, params);
6691
6692 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6693 if (ret) {
6694 sigma_dut_print(dut, DUT_MSG_ERROR,
6695 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
6696 __func__, ret, val);
6697 }
6698 return ret;
6699#else /* NL80211_SUPPORT */
6700 sigma_dut_print(dut, DUT_MSG_ERROR,
6701 "HE OM ctrl cannot be changed without NL80211_SUPPORT defined");
6702 return -1;
6703#endif /* NL80211_SUPPORT */
6704}
6705
6706
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08006707static void sta_reset_default_wcn(struct sigma_dut *dut, const char *intf,
6708 const char *type)
6709{
6710 char buf[60];
6711
6712 if (dut->program == PROGRAM_HE) {
6713 /* resetting phymode to auto in case of HE program */
6714 snprintf(buf, sizeof(buf), "iwpriv %s setphymode 0", intf);
6715 if (system(buf) != 0) {
6716 sigma_dut_print(dut, DUT_MSG_ERROR,
6717 "iwpriv %s setphymode failed", intf);
6718 }
6719
Amarnath Hullur Subramanyam9cecb502018-04-25 13:26:30 -07006720 /* reset the rate to Auto rate */
6721 snprintf(buf, sizeof(buf), "iwpriv %s set_11ax_rate 0xff",
6722 intf);
6723 if (system(buf) != 0) {
6724 sigma_dut_print(dut, DUT_MSG_ERROR,
6725 "iwpriv %s set_11ax_rate 0xff failed",
6726 intf);
6727 }
6728
Kiran Kumar Lokere86cfe3a2018-06-01 11:55:15 -07006729 /* reset the LDPC setting */
6730 snprintf(buf, sizeof(buf), "iwpriv %s ldpc 1", intf);
6731 if (system(buf) != 0) {
6732 sigma_dut_print(dut, DUT_MSG_ERROR,
6733 "iwpriv %s ldpc 1 failed", intf);
6734 }
6735
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08006736 /* reset the power save setting */
6737 snprintf(buf, sizeof(buf), "iwpriv %s setPower 2", intf);
6738 if (system(buf) != 0) {
6739 sigma_dut_print(dut, DUT_MSG_ERROR,
6740 "iwpriv %s setPower 2 failed", intf);
6741 }
6742
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08006743 /* remove all network profiles */
6744 remove_wpa_networks(intf);
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08006745
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08006746 /* Configure ADDBA Req/Rsp buffer size to be 64 */
6747 sta_set_addba_buf_size(dut, intf, 64);
6748
Amarnath Hullur Subramanyam5f32d572018-03-02 00:02:33 -08006749#ifdef NL80211_SUPPORT
6750 /* Disable noackpolicy for all AC */
6751 if (nlvendor_sta_set_noack(dut, intf, 0, QCA_WLAN_AC_ALL)) {
6752 sigma_dut_print(dut, DUT_MSG_ERROR,
6753 "Disable of noackpolicy for all AC failed");
6754 }
6755#endif /* NL80211_SUPPORT */
6756
Amarnath Hullur Subramanyamb1724a52018-03-07 14:31:46 -08006757 /* Enable WMM by default */
6758 if (wcn_sta_set_wmm(dut, intf, "on")) {
6759 sigma_dut_print(dut, DUT_MSG_ERROR,
6760 "Enable of WMM in sta_reset_default_wcn failed");
6761 }
6762
6763 /* Disable ADDBA_REJECT by default */
6764 if (nlvendor_sta_set_addba_reject(dut, intf, 0)) {
6765 sigma_dut_print(dut, DUT_MSG_ERROR,
6766 "Disable of addba_reject in sta_reset_default_wcn failed");
6767 }
6768
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08006769 /* Enable sending of ADDBA by default */
6770 if (nlvendor_config_send_addba(dut, intf, 1)) {
6771 sigma_dut_print(dut, DUT_MSG_ERROR,
6772 "Enable sending of ADDBA in sta_reset_default_wcn failed");
6773 }
6774
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08006775 /* Enable AMPDU by default */
6776 iwpriv_sta_set_ampdu(dut, intf, 1);
6777
Subhani Shaik8e7a3052018-04-24 14:03:00 -07006778#ifdef NL80211_SUPPORT
6779 if (sta_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_AUTO)) {
6780 sigma_dut_print(dut, DUT_MSG_ERROR,
6781 "Set LTF config to default in sta_reset_default_wcn failed");
6782 }
Arif Hussain9765f7d2018-07-03 08:28:26 -07006783
Kiran Kumar Lokerebad51122018-12-12 19:03:36 -08006784 /* set the beamformee NSTS(maximum number of
6785 * space-time streams) to default DUT config
6786 */
6787 if (sta_set_beamformee_sts(dut, intf, 7)) {
Arif Hussain9765f7d2018-07-03 08:28:26 -07006788 sigma_dut_print(dut, DUT_MSG_ERROR,
6789 "Failed to set BeamformeeSTS");
6790 }
Arif Hussain68d23f52018-07-11 13:39:08 -07006791
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07006792 if (sta_set_mac_padding_duration(
6793 dut, intf,
6794 QCA_WLAN_HE_NO_ADDITIONAL_PROCESS_TIME)) {
Arif Hussain68d23f52018-07-11 13:39:08 -07006795 sigma_dut_print(dut, DUT_MSG_ERROR,
6796 "Failed to set MAC padding duration");
6797 }
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07006798
6799 if (sta_set_mu_edca_override(dut, intf, 0)) {
6800 sigma_dut_print(dut, DUT_MSG_ERROR,
6801 "ErrorCode,Failed to set MU EDCA override disable");
6802 }
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07006803
6804 if (sta_set_om_ctrl_supp(dut, intf, 1)) {
6805 sigma_dut_print(dut, DUT_MSG_ERROR,
6806 "Failed to set OM ctrl supp");
6807 }
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07006808
6809 if (sta_set_tx_su_ppdu_cfg(dut, intf, 1)) {
6810 sigma_dut_print(dut, DUT_MSG_ERROR,
6811 "Failed to set Tx SU PPDU enable");
6812 }
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07006813
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07006814 if (sta_set_action_tx_in_he_tb_ppdu(dut, intf, 0)) {
6815 sigma_dut_print(dut, DUT_MSG_ERROR,
6816 "failed to send TB PPDU Tx cfg");
6817 }
6818
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07006819 if (sta_set_he_om_ctrl_reset(dut, intf)) {
6820 sigma_dut_print(dut, DUT_MSG_ERROR,
6821 "Failed to set OM ctrl reset");
6822 }
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08006823
6824 /* +HTC-HE support default on */
6825 if (sta_set_he_htc_supp(dut, intf, 1)) {
6826 sigma_dut_print(dut, DUT_MSG_ERROR,
6827 "Setting of +HTC-HE support failed");
6828 }
Subhani Shaik8e7a3052018-04-24 14:03:00 -07006829#endif /* NL80211_SUPPORT */
6830
Arif Hussain8d5b27b2018-05-14 14:31:03 -07006831 if (sta_set_tx_beamformee(dut, intf, 1)) {
6832 sigma_dut_print(dut, DUT_MSG_ERROR,
6833 "Set tx beamformee enable by default in sta_reset_default_wcn failed");
6834 }
6835
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08006836 /* Set nss to 1 and MCS 0-7 in case of testbed */
6837 if (type && strcasecmp(type, "Testbed") == 0) {
6838#ifdef NL80211_SUPPORT
6839 int ret;
6840#endif /* NL80211_SUPPORT */
6841
6842 snprintf(buf, sizeof(buf), "iwpriv %s nss 1", intf);
6843 if (system(buf) != 0) {
6844 sigma_dut_print(dut, DUT_MSG_ERROR,
6845 "iwpriv %s nss failed", intf);
6846 }
6847
6848#ifdef NL80211_SUPPORT
6849 ret = sta_set_he_mcs(dut, intf, HE_80_MCS0_7);
6850 if (ret) {
6851 sigma_dut_print(dut, DUT_MSG_ERROR,
6852 "Setting of MCS failed, ret:%d",
6853 ret);
6854 }
6855#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyamc67621d2018-02-04 23:18:01 -08006856
6857 /* Disable STBC as default */
6858 wcn_sta_set_stbc(dut, intf, "0");
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08006859
6860 /* Disable AMSDU as default */
6861 iwpriv_sta_set_amsdu(dut, intf, "0");
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08006862
6863#ifdef NL80211_SUPPORT
6864 /* HE fragmentation default off */
6865 if (sta_set_he_fragmentation(dut, intf,
6866 HE_FRAG_DISABLE)) {
6867 sigma_dut_print(dut, DUT_MSG_ERROR,
6868 "Setting of HE fragmentation failed");
6869 }
Kiran Kumar Lokerebad51122018-12-12 19:03:36 -08006870
6871 /* set the beamformee NSTS(maximum number of
6872 * space-time streams) to default testbed config
6873 */
6874 if (sta_set_beamformee_sts(dut, intf, 3)) {
6875 sigma_dut_print(dut, DUT_MSG_ERROR,
6876 "Failed to set BeamformeeSTS");
6877 }
6878
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08006879 /* +HTC-HE support default off */
6880 if (sta_set_he_htc_supp(dut, intf, 0)) {
6881 sigma_dut_print(dut, DUT_MSG_ERROR,
6882 "Setting of +HTC-HE support failed");
6883 }
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08006884#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08006885
6886 /* Enable WEP/TKIP with HE capability in testbed */
6887 if (sta_set_heconfig_and_wep_tkip(dut, intf, 1)) {
6888 sigma_dut_print(dut, DUT_MSG_ERROR,
6889 "Enabling HE config with WEP/TKIP failed");
6890 }
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08006891 }
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08006892
6893 /* Defaults in case of DUT */
6894 if (type && strcasecmp(type, "DUT") == 0) {
Arif Hussaind48fcc72018-05-01 18:34:18 -07006895 /* Enable STBC by default */
6896 wcn_sta_set_stbc(dut, intf, "1");
6897
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08006898 /* set nss to 2 */
6899 snprintf(buf, sizeof(buf), "iwpriv %s nss 2", intf);
6900 if (system(buf) != 0) {
6901 sigma_dut_print(dut, DUT_MSG_ERROR,
6902 "iwpriv %s nss 2 failed", intf);
6903 }
Arif Hussainac6c5112018-05-25 17:34:00 -07006904 dut->sta_nss = 2;
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08006905
6906#ifdef NL80211_SUPPORT
Arif Hussainae239842018-05-01 18:20:05 -07006907 /* Set HE_MCS to 0-11 */
6908 if (sta_set_he_mcs(dut, intf, HE_80_MCS0_11)) {
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08006909 sigma_dut_print(dut, DUT_MSG_ERROR,
6910 "Setting of MCS failed");
6911 }
6912#endif /* NL80211_SUPPORT */
6913
6914 /* Disable WEP/TKIP with HE capability in DUT */
6915 if (sta_set_heconfig_and_wep_tkip(dut, intf, 0)) {
6916 sigma_dut_print(dut, DUT_MSG_ERROR,
6917 "Enabling HE config with WEP/TKIP failed");
6918 }
6919 }
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08006920 }
6921}
6922
6923
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006924static int cmd_sta_reset_default(struct sigma_dut *dut,
6925 struct sigma_conn *conn,
6926 struct sigma_cmd *cmd)
6927{
6928 int cmd_sta_p2p_reset(struct sigma_dut *dut, struct sigma_conn *conn,
6929 struct sigma_cmd *cmd);
6930 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02006931 const char *band = get_param(cmd, "band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006932 const char *type;
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07006933 const char *program = get_param(cmd, "program");
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05306934 const char *dev_role = get_param(cmd, "DevRole");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006935
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07006936 if (!program)
6937 program = get_param(cmd, "prog");
6938 dut->program = sigma_program_to_enum(program);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006939 dut->device_type = STA_unknown;
6940 type = get_param(cmd, "type");
6941 if (type && strcasecmp(type, "Testbed") == 0)
6942 dut->device_type = STA_testbed;
6943 if (type && strcasecmp(type, "DUT") == 0)
6944 dut->device_type = STA_dut;
6945
6946 if (dut->program == PROGRAM_TDLS) {
6947 /* Clear TDLS testing mode */
6948 wpa_command(intf, "SET tdls_disabled 0");
6949 wpa_command(intf, "SET tdls_testing 0");
6950 dut->no_tpk_expiration = 0;
Pradeep Reddy POTTETI8ce2a232016-10-28 12:17:32 +05306951 if (get_driver_type() == DRIVER_WCN) {
6952 /* Enable the WCN driver in TDLS Explicit trigger mode
6953 */
6954 wpa_command(intf, "SET tdls_external_control 0");
6955 wpa_command(intf, "SET tdls_trigger_control 0");
6956 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006957 }
6958
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07006959#ifdef MIRACAST
6960 if (dut->program == PROGRAM_WFD ||
6961 dut->program == PROGRAM_DISPLAYR2)
6962 miracast_sta_reset_default(dut, conn, cmd);
6963#endif /* MIRACAST */
6964
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006965 switch (get_driver_type()) {
6966 case DRIVER_ATHEROS:
6967 sta_reset_default_ath(dut, intf, type);
6968 break;
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08006969 case DRIVER_WCN:
6970 sta_reset_default_wcn(dut, intf, type);
6971 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006972 default:
6973 break;
6974 }
6975
6976#ifdef ANDROID_NAN
6977 if (dut->program == PROGRAM_NAN)
6978 nan_cmd_sta_reset_default(dut, conn, cmd);
6979#endif /* ANDROID_NAN */
6980
Jouni Malinenba630452018-06-22 11:49:59 +03006981 if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006982 unlink("SP/wi-fi.org/pps.xml");
6983 if (system("rm -r SP/*") != 0) {
6984 }
6985 unlink("next-client-cert.pem");
6986 unlink("next-client-key.pem");
6987 }
6988
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02006989 /* For WPS program of the 60 GHz band the band type needs to be saved */
6990 if (dut->program == PROGRAM_WPS) {
6991 if (band && strcasecmp(band, "60GHz") == 0) {
6992 dut->band = WPS_BAND_60G;
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02006993 /* For 60 GHz enable WPS for WPS TCs */
6994 dut->wps_disable = 0;
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02006995 } else {
6996 dut->band = WPS_BAND_NON_60G;
6997 }
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02006998 } else if (dut->program == PROGRAM_60GHZ) {
6999 /* For 60 GHz MAC/PHY TCs WPS must be disabled */
7000 dut->wps_disable = 1;
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007001 }
7002
Alexei Avshalom Lazar157ba062018-12-23 16:15:26 +02007003 if (is_60g_sigma_dut(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007004 const char *dev_role = get_param(cmd, "DevRole");
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02007005 char buf[256];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007006
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02007007 sigma_dut_print(dut, DUT_MSG_INFO,
7008 "WPS 60 GHz program, wps_disable = %d",
7009 dut->wps_disable);
7010
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007011 if (!dev_role) {
7012 send_resp(dut, conn, SIGMA_ERROR,
7013 "errorCode,Missing DevRole argument");
7014 return 0;
7015 }
7016
7017 if (strcasecmp(dev_role, "STA") == 0)
7018 dut->dev_role = DEVROLE_STA;
7019 else if (strcasecmp(dev_role, "PCP") == 0)
7020 dut->dev_role = DEVROLE_PCP;
7021 else {
7022 send_resp(dut, conn, SIGMA_ERROR,
7023 "errorCode,Unknown DevRole");
7024 return 0;
7025 }
7026
7027 if (dut->device_type == STA_unknown) {
7028 sigma_dut_print(dut, DUT_MSG_ERROR,
7029 "Device type is not STA testbed or DUT");
7030 send_resp(dut, conn, SIGMA_ERROR,
7031 "errorCode,Unknown device type");
7032 return 0;
7033 }
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02007034
7035 sigma_dut_print(dut, DUT_MSG_DEBUG,
7036 "Setting msdu_size to MAX: 7912");
7037 snprintf(buf, sizeof(buf), "ifconfig %s mtu 7912",
7038 get_station_ifname());
7039
7040 if (system(buf) != 0) {
7041 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
7042 buf);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007043 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02007044 }
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02007045
7046 if (sta_set_force_mcs(dut, 0, 1)) {
7047 sigma_dut_print(dut, DUT_MSG_ERROR,
7048 "Failed to reset force MCS");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007049 return ERROR_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02007050 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007051 }
7052
7053 wpa_command(intf, "WPS_ER_STOP");
7054 wpa_command(intf, "FLUSH");
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05307055 wpa_command(intf, "ERP_FLUSH");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007056 wpa_command(intf, "SET radio_disabled 0");
7057
Alexei Avshalom Lazar744ae8a2019-01-31 17:26:46 +02007058 dut->wps_forced_version = 0;
7059
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007060 if (dut->wsc_fragment) {
7061 dut->wsc_fragment = 0;
7062 wpa_command(intf, "SET device_name Test client");
7063 wpa_command(intf, "SET manufacturer ");
7064 wpa_command(intf, "SET model_name ");
7065 wpa_command(intf, "SET model_number ");
7066 wpa_command(intf, "SET serial_number ");
7067 }
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02007068 if (is_60g_sigma_dut(dut) && dut->force_rsn_ie) {
7069 dut->force_rsn_ie = FORCE_RSN_IE_NONE;
7070 sta_60g_force_rsn_ie(dut, FORCE_RSN_IE_NONE);
7071 }
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007072
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007073 if (dut->tmp_mac_addr && dut->set_macaddr) {
7074 dut->tmp_mac_addr = 0;
7075 if (system(dut->set_macaddr) != 0) {
7076 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to clear "
7077 "temporary MAC address");
7078 }
7079 }
7080
7081 set_ps(intf, dut, 0);
7082
Jouni Malinenba630452018-06-22 11:49:59 +03007083 if (dut->program == PROGRAM_HS2 || dut->program == PROGRAM_HS2_R2 ||
7084 dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007085 wpa_command(intf, "SET interworking 1");
7086 wpa_command(intf, "SET hs20 1");
7087 }
7088
Deepak Dhamdhere0fe0e452017-12-18 14:52:09 -08007089 if (dut->program == PROGRAM_HS2_R2 ||
Jouni Malinenba630452018-06-22 11:49:59 +03007090 dut->program == PROGRAM_HS2_R3 ||
Deepak Dhamdhere0fe0e452017-12-18 14:52:09 -08007091 dut->program == PROGRAM_OCE) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007092 wpa_command(intf, "SET pmf 1");
7093 } else {
7094 wpa_command(intf, "SET pmf 0");
7095 }
7096
7097 hs2_clear_credentials(intf);
7098 wpa_command(intf, "SET hessid 00:00:00:00:00:00");
7099 wpa_command(intf, "SET access_network_type 15");
7100
7101 static_ip_file(0, NULL, NULL, NULL);
7102 kill_dhcp_client(dut, intf);
7103 clear_ip_addr(dut, intf);
7104
7105 dut->er_oper_performed = 0;
7106 dut->er_oper_bssid[0] = '\0';
7107
priyadharshini gowthamanad6cbba2016-10-04 10:39:58 -07007108 if (dut->program == PROGRAM_LOC) {
7109 /* Disable Interworking by default */
7110 wpa_command(get_station_ifname(), "SET interworking 0");
7111 }
7112
Ashwini Patil00402582017-04-13 12:29:39 +05307113 if (dut->program == PROGRAM_MBO) {
7114 free(dut->non_pref_ch_list);
7115 dut->non_pref_ch_list = NULL;
Ashwini Patil5acd7382017-04-13 15:55:04 +05307116 free(dut->btm_query_cand_list);
7117 dut->btm_query_cand_list = NULL;
Ashwini Patilc63161e2017-04-13 16:30:23 +05307118 wpa_command(intf, "SET reject_btm_req_reason 0");
Ashwini Patila75de5a2017-04-13 16:35:05 +05307119 wpa_command(intf, "SET ignore_assoc_disallow 0");
Ashwini Patild174f2c2017-04-13 16:49:46 +05307120 wpa_command(intf, "SET gas_address3 0");
Ashwini Patil9183fdb2017-04-13 16:58:25 +05307121 wpa_command(intf, "SET roaming 1");
Ankita Bajaj1d974552018-09-18 16:56:44 +05307122 wpa_command(intf, "SET interworking 1");
Ashwini Patil00402582017-04-13 12:29:39 +05307123 }
7124
Jouni Malinen3c367e82017-06-23 17:01:47 +03007125 free(dut->rsne_override);
7126 dut->rsne_override = NULL;
7127
Jouni Malinen68143132017-09-02 02:34:08 +03007128 free(dut->sae_commit_override);
7129 dut->sae_commit_override = NULL;
7130
Jouni Malinend86e5822017-08-29 03:55:32 +03007131 dut->dpp_conf_id = -1;
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02007132 free(dut->dpp_peer_uri);
7133 dut->dpp_peer_uri = NULL;
Jouni Malinen63d50412017-11-24 11:55:38 +02007134 dut->dpp_local_bootstrap = -1;
Jouni Malinen5011fb52017-12-05 21:00:15 +02007135 wpa_command(intf, "SET dpp_config_processing 2");
Jouni Malinend86e5822017-08-29 03:55:32 +03007136
Jouni Malinenfac9cad2017-10-10 18:35:55 +03007137 wpa_command(intf, "VENDOR_ELEM_REMOVE 13 *");
7138
vamsi krishnaa2799492017-12-05 14:28:01 +05307139 if (dut->program == PROGRAM_OCE) {
Ankita Bajaja2cb5672017-10-25 16:08:28 +05307140 wpa_command(intf, "SET oce 1");
vamsi krishnaa2799492017-12-05 14:28:01 +05307141 wpa_command(intf, "SET disable_fils 0");
Ankita Bajaj1bde7942018-01-09 19:15:01 +05307142 wpa_command(intf, "FILS_HLP_REQ_FLUSH");
7143 dut->fils_hlp = 0;
7144#ifdef ANDROID
7145 hlp_thread_cleanup(dut);
7146#endif /* ANDROID */
vamsi krishnaa2799492017-12-05 14:28:01 +05307147 }
Ankita Bajaja2cb5672017-10-25 16:08:28 +05307148
Sunil Dutt076081f2018-02-05 19:45:50 +05307149#ifdef NL80211_SUPPORT
Sunil Dutt44595082018-02-12 19:41:45 +05307150 if (get_driver_type() == DRIVER_WCN &&
7151 dut->config_rsnie == 1) {
7152 dut->config_rsnie = 0;
7153 sta_config_rsnie(dut, 0);
Sunil Dutt076081f2018-02-05 19:45:50 +05307154 }
7155#endif /* NL80211_SUPPORT */
7156
Sunil Duttfebf8a82018-02-09 18:50:13 +05307157 if (dev_role && strcasecmp(dev_role, "STA-CFON") == 0) {
7158 dut->dev_role = DEVROLE_STA_CFON;
7159 return sta_cfon_reset_default(dut, conn, cmd);
7160 }
7161
Jouni Malinen439352d2018-09-13 03:42:23 +03007162 wpa_command(intf, "SET setband AUTO");
7163
Sunil Duttfebf8a82018-02-09 18:50:13 +05307164 if (dut->program != PROGRAM_VHT)
7165 return cmd_sta_p2p_reset(dut, conn, cmd);
7166
Priyadharshini Gowthamana7dfd492015-11-09 14:34:08 -08007167 return 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007168}
7169
7170
7171static int cmd_sta_get_events(struct sigma_dut *dut, struct sigma_conn *conn,
7172 struct sigma_cmd *cmd)
7173{
7174 const char *program = get_param(cmd, "Program");
7175
7176 if (program == NULL)
7177 return -1;
7178#ifdef ANDROID_NAN
7179 if (strcasecmp(program, "NAN") == 0)
7180 return nan_cmd_sta_get_events(dut, conn, cmd);
7181#endif /* ANDROID_NAN */
7182 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
7183 return 0;
7184}
7185
7186
Jouni Malinen82905202018-04-29 17:20:10 +03007187static int sta_exec_action_url(struct sigma_dut *dut, struct sigma_conn *conn,
7188 struct sigma_cmd *cmd)
7189{
7190 const char *url = get_param(cmd, "url");
7191 const char *method = get_param(cmd, "method");
7192 pid_t pid;
7193 int status;
7194
7195 if (!url || !method)
7196 return -1;
7197
7198 /* TODO: Add support for method,post */
7199 if (strcasecmp(method, "get") != 0) {
7200 send_resp(dut, conn, SIGMA_ERROR,
7201 "ErrorCode,Unsupported method");
7202 return 0;
7203 }
7204
7205 pid = fork();
7206 if (pid < 0) {
7207 perror("fork");
7208 return -1;
7209 }
7210
7211 if (pid == 0) {
7212 char * argv[5] = { "wget", "-O", "/dev/null",
7213 (char *) url, NULL };
7214
7215 execv("/usr/bin/wget", argv);
7216 perror("execv");
7217 exit(0);
7218 return -1;
7219 }
7220
7221 if (waitpid(pid, &status, 0) < 0) {
7222 perror("waitpid");
7223 return -1;
7224 }
7225
7226 if (WIFEXITED(status)) {
7227 const char *errmsg;
7228
7229 if (WEXITSTATUS(status) == 0)
7230 return 1;
7231 sigma_dut_print(dut, DUT_MSG_INFO, "wget exit status %d",
7232 WEXITSTATUS(status));
7233 switch (WEXITSTATUS(status)) {
7234 case 4:
7235 errmsg = "errmsg,Network failure";
7236 break;
7237 case 8:
7238 errmsg = "errmsg,Server issued an error response";
7239 break;
7240 default:
7241 errmsg = "errmsg,Unknown failure from wget";
7242 break;
7243 }
7244 send_resp(dut, conn, SIGMA_ERROR, errmsg);
7245 return 0;
7246 }
7247
7248 send_resp(dut, conn, SIGMA_ERROR, "errmsg,Unknown failure");
7249 return 0;
7250}
7251
7252
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007253static int cmd_sta_exec_action(struct sigma_dut *dut, struct sigma_conn *conn,
7254 struct sigma_cmd *cmd)
7255{
7256 const char *program = get_param(cmd, "Prog");
7257
Jouni Malinen82905202018-04-29 17:20:10 +03007258 if (program && !get_param(cmd, "interface"))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007259 return -1;
7260#ifdef ANDROID_NAN
Jouni Malinen82905202018-04-29 17:20:10 +03007261 if (program && strcasecmp(program, "NAN") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007262 return nan_cmd_sta_exec_action(dut, conn, cmd);
7263#endif /* ANDROID_NAN */
Jouni Malinen82905202018-04-29 17:20:10 +03007264
7265 if (program && strcasecmp(program, "Loc") == 0)
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07007266 return loc_cmd_sta_exec_action(dut, conn, cmd);
Jouni Malinen82905202018-04-29 17:20:10 +03007267
7268 if (get_param(cmd, "url"))
7269 return sta_exec_action_url(dut, conn, cmd);
7270
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007271 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
7272 return 0;
7273}
7274
7275
7276static int cmd_sta_set_11n(struct sigma_dut *dut, struct sigma_conn *conn,
7277 struct sigma_cmd *cmd)
7278{
7279 const char *intf = get_param(cmd, "Interface");
7280 const char *val, *mcs32, *rate;
7281
7282 val = get_param(cmd, "GREENFIELD");
7283 if (val) {
7284 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
7285 /* Enable GD */
7286 send_resp(dut, conn, SIGMA_ERROR,
7287 "ErrorCode,GF not supported");
7288 return 0;
7289 }
7290 }
7291
7292 val = get_param(cmd, "SGI20");
7293 if (val) {
7294 switch (get_driver_type()) {
7295 case DRIVER_ATHEROS:
7296 ath_sta_set_sgi(dut, intf, val);
7297 break;
7298 default:
7299 send_resp(dut, conn, SIGMA_ERROR,
7300 "ErrorCode,SGI20 not supported");
7301 return 0;
7302 }
7303 }
7304
7305 mcs32 = get_param(cmd, "MCS32"); /* HT Duplicate Mode Enable/Disable */
7306 rate = get_param(cmd, "MCS_FIXEDRATE"); /* Fixed MCS rate (0..31) */
7307 if (mcs32 && rate) {
7308 /* TODO */
7309 send_resp(dut, conn, SIGMA_ERROR,
7310 "ErrorCode,MCS32,MCS_FIXEDRATE not supported");
7311 return 0;
7312 } else if (mcs32 && !rate) {
7313 /* TODO */
7314 send_resp(dut, conn, SIGMA_ERROR,
7315 "ErrorCode,MCS32 not supported");
7316 return 0;
7317 } else if (!mcs32 && rate) {
7318 switch (get_driver_type()) {
7319 case DRIVER_ATHEROS:
priyadharshini gowthamane5e25172015-12-08 14:53:48 -08007320 novap_reset(dut, intf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007321 ath_sta_set_11nrates(dut, intf, rate);
7322 break;
7323 default:
7324 send_resp(dut, conn, SIGMA_ERROR,
7325 "ErrorCode,MCS32_FIXEDRATE not supported");
7326 return 0;
7327 }
7328 }
7329
7330 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
7331}
7332
7333
Arif Hussain7b47d2d2018-05-09 10:44:02 -07007334static void cmd_set_max_he_mcs(struct sigma_dut *dut, const char *intf,
7335 int mcs_config)
7336{
7337#ifdef NL80211_SUPPORT
7338 int ret;
7339
7340 switch (mcs_config) {
7341 case HE_80_MCS0_7:
7342 case HE_80_MCS0_9:
7343 case HE_80_MCS0_11:
7344 ret = sta_set_he_mcs(dut, intf, mcs_config);
7345 if (ret) {
7346 sigma_dut_print(dut, DUT_MSG_ERROR,
7347 "cmd_set_max_he_mcs: Setting of MCS:%d failed, ret:%d",
7348 mcs_config, ret);
7349 }
7350 break;
7351 default:
7352 sigma_dut_print(dut, DUT_MSG_ERROR,
7353 "cmd_set_max_he_mcs: Invalid mcs %d",
7354 mcs_config);
7355 break;
7356 }
7357#else /* NL80211_SUPPORT */
7358 sigma_dut_print(dut, DUT_MSG_ERROR,
7359 "max HE MCS cannot be changed without NL80211_SUPPORT defined");
7360#endif /* NL80211_SUPPORT */
7361}
7362
7363
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007364static int cmd_sta_set_wireless_vht(struct sigma_dut *dut,
7365 struct sigma_conn *conn,
7366 struct sigma_cmd *cmd)
7367{
7368 const char *intf = get_param(cmd, "Interface");
7369 const char *val;
Arif Hussaina37e9552018-06-20 17:05:59 -07007370 const char *program;
Arif Hussaind13d6952018-07-02 16:23:47 -07007371 char buf[60];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007372 int tkip = -1;
7373 int wep = -1;
7374
Arif Hussaina37e9552018-06-20 17:05:59 -07007375 program = get_param(cmd, "Program");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007376 val = get_param(cmd, "SGI80");
7377 if (val) {
7378 int sgi80;
7379
7380 sgi80 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
7381 snprintf(buf, sizeof(buf), "iwpriv %s shortgi %d", intf, sgi80);
7382 if (system(buf) != 0) {
7383 sigma_dut_print(dut, DUT_MSG_ERROR,
7384 "iwpriv shortgi failed");
7385 }
7386 }
7387
7388 val = get_param(cmd, "TxBF");
7389 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07007390 switch (get_driver_type()) {
7391 case DRIVER_WCN:
7392 if (sta_set_tx_beamformee(dut, intf, 1)) {
7393 send_resp(dut, conn, SIGMA_ERROR,
7394 "ErrorCode,Failed to set TX beamformee enable");
7395 return 0;
7396 }
7397 break;
7398 case DRIVER_ATHEROS:
7399 snprintf(buf, sizeof(buf), "iwpriv %s vhtsubfee 1",
7400 intf);
7401 if (system(buf) != 0) {
7402 send_resp(dut, conn, SIGMA_ERROR,
7403 "ErrorCode,Setting vhtsubfee failed");
7404 return 0;
7405 }
7406
7407 snprintf(buf, sizeof(buf), "iwpriv %s vhtsubfer 1",
7408 intf);
7409 if (system(buf) != 0) {
7410 send_resp(dut, conn, SIGMA_ERROR,
7411 "ErrorCode,Setting vhtsubfer failed");
7412 return 0;
7413 }
7414 break;
7415 default:
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007416 sigma_dut_print(dut, DUT_MSG_ERROR,
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07007417 "Unsupported driver type");
7418 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007419 }
7420 }
7421
7422 val = get_param(cmd, "MU_TxBF");
7423 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
7424 switch (get_driver_type()) {
7425 case DRIVER_ATHEROS:
7426 ath_sta_set_txsp_stream(dut, intf, "1SS");
7427 ath_sta_set_rxsp_stream(dut, intf, "1SS");
Sunil Duttae9e5d12018-06-29 11:50:47 +05307428 snprintf(buf, sizeof(buf), "iwpriv %s vhtmubfee 1",
7429 intf);
7430 if (system(buf) != 0) {
7431 sigma_dut_print(dut, DUT_MSG_ERROR,
7432 "iwpriv vhtmubfee failed");
7433 }
7434 snprintf(buf, sizeof(buf), "iwpriv %s vhtmubfer 1",
7435 intf);
7436 if (system(buf) != 0) {
7437 sigma_dut_print(dut, DUT_MSG_ERROR,
7438 "iwpriv vhtmubfer failed");
7439 }
7440 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007441 case DRIVER_WCN:
7442 if (wcn_sta_set_sp_stream(dut, intf, "1SS") < 0) {
7443 send_resp(dut, conn, SIGMA_ERROR,
7444 "ErrorCode,Failed to set RX/TXSP_STREAM");
7445 return 0;
7446 }
Sunil Duttae9e5d12018-06-29 11:50:47 +05307447 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007448 default:
7449 sigma_dut_print(dut, DUT_MSG_ERROR,
7450 "Setting SP_STREAM not supported");
7451 break;
7452 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007453 }
7454
7455 val = get_param(cmd, "LDPC");
7456 if (val) {
7457 int ldpc;
7458
7459 ldpc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
7460 snprintf(buf, sizeof(buf), "iwpriv %s ldpc %d", intf, ldpc);
7461 if (system(buf) != 0) {
7462 sigma_dut_print(dut, DUT_MSG_ERROR,
7463 "iwpriv ldpc failed");
7464 }
7465 }
7466
Amarnath Hullur Subramanyam7bae60e2018-01-31 03:46:50 -08007467 val = get_param(cmd, "BCC");
7468 if (val) {
7469 int bcc;
7470
7471 bcc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
7472 /* use LDPC iwpriv itself to set bcc coding, bcc coding
7473 * is mutually exclusive to bcc */
7474 snprintf(buf, sizeof(buf), "iwpriv %s ldpc %d", intf, !bcc);
7475 if (system(buf) != 0) {
7476 sigma_dut_print(dut, DUT_MSG_ERROR,
7477 "Enabling/Disabling of BCC failed");
7478 }
7479 }
7480
Arif Hussain7b47d2d2018-05-09 10:44:02 -07007481 val = get_param(cmd, "MaxHE-MCS_1SS_RxMapLTE80");
7482 if (val && dut->sta_nss == 1)
7483 cmd_set_max_he_mcs(dut, intf, atoi(val));
7484
7485 val = get_param(cmd, "MaxHE-MCS_2SS_RxMapLTE80");
7486 if (val && dut->sta_nss == 2)
7487 cmd_set_max_he_mcs(dut, intf, atoi(val));
7488
Arif Hussainac6c5112018-05-25 17:34:00 -07007489 val = get_param(cmd, "MCS_FixedRate");
7490 if (val) {
7491#ifdef NL80211_SUPPORT
7492 int mcs, ratecode = 0;
7493 enum he_mcs_config mcs_config;
7494 int ret;
7495
7496 ratecode = (0x07 & dut->sta_nss) << 5;
7497 mcs = atoi(val);
7498 /* Add the MCS to the ratecode */
7499 if (mcs >= 0 && mcs <= 11) {
7500 ratecode += mcs;
7501 if (dut->device_type == STA_testbed &&
7502 mcs > 7 && mcs <= 11) {
7503 if (mcs <= 9)
7504 mcs_config = HE_80_MCS0_9;
7505 else
7506 mcs_config = HE_80_MCS0_11;
7507 ret = sta_set_he_mcs(dut, intf, mcs_config);
7508 if (ret) {
7509 sigma_dut_print(dut, DUT_MSG_ERROR,
7510 "MCS_FixedRate: mcs setting failed, mcs:%d, mcs_config %d, ret:%d",
7511 mcs, mcs_config, ret);
7512 }
7513 }
7514 snprintf(buf, sizeof(buf),
7515 "iwpriv %s set_11ax_rate 0x%03x",
7516 intf, ratecode);
7517 if (system(buf) != 0) {
7518 sigma_dut_print(dut, DUT_MSG_ERROR,
7519 "MCS_FixedRate: iwpriv setting of 11ax rates 0x%03x failed",
7520 ratecode);
7521 }
7522 } else {
7523 sigma_dut_print(dut, DUT_MSG_ERROR,
7524 "MCS_FixedRate: HE MCS %d not supported",
7525 mcs);
7526 }
7527#else /* NL80211_SUPPORT */
7528 sigma_dut_print(dut, DUT_MSG_ERROR,
7529 "MCS_FixedRate cannot be changed without NL80211_SUPPORT defined");
7530#endif /* NL80211_SUPPORT */
7531 }
7532
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007533 val = get_param(cmd, "opt_md_notif_ie");
7534 if (val) {
7535 char *result = NULL;
7536 char delim[] = ";";
7537 char token[30];
7538 int value, config_val = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307539 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007540
Peng Xub8fc5cc2017-05-10 17:27:28 -07007541 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307542 result = strtok_r(token, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007543
7544 /* Extract the NSS information */
7545 if (result) {
7546 value = atoi(result);
7547 switch (value) {
7548 case 1:
7549 config_val = 1;
7550 break;
7551 case 2:
7552 config_val = 3;
7553 break;
7554 case 3:
7555 config_val = 7;
7556 break;
7557 case 4:
7558 config_val = 15;
7559 break;
7560 default:
7561 config_val = 3;
7562 break;
7563 }
7564
7565 snprintf(buf, sizeof(buf), "iwpriv %s rxchainmask %d",
7566 intf, config_val);
7567 if (system(buf) != 0) {
7568 sigma_dut_print(dut, DUT_MSG_ERROR,
7569 "iwpriv rxchainmask failed");
7570 }
7571
7572 snprintf(buf, sizeof(buf), "iwpriv %s txchainmask %d",
7573 intf, config_val);
7574 if (system(buf) != 0) {
7575 sigma_dut_print(dut, DUT_MSG_ERROR,
7576 "iwpriv txchainmask failed");
7577 }
7578 }
7579
7580 /* Extract the channel width information */
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307581 result = strtok_r(NULL, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007582 if (result) {
7583 value = atoi(result);
7584 switch (value) {
7585 case 20:
7586 config_val = 0;
7587 break;
7588 case 40:
7589 config_val = 1;
7590 break;
7591 case 80:
7592 config_val = 2;
7593 break;
7594 case 160:
7595 config_val = 3;
7596 break;
7597 default:
7598 config_val = 2;
7599 break;
7600 }
7601
7602 dut->chwidth = config_val;
7603
7604 snprintf(buf, sizeof(buf), "iwpriv %s chwidth %d",
7605 intf, config_val);
7606 if (system(buf) != 0) {
7607 sigma_dut_print(dut, DUT_MSG_ERROR,
7608 "iwpriv chwidth failed");
7609 }
7610 }
7611
7612 snprintf(buf, sizeof(buf), "iwpriv %s opmode_notify 1", intf);
7613 if (system(buf) != 0) {
7614 sigma_dut_print(dut, DUT_MSG_ERROR,
7615 "iwpriv opmode_notify failed");
7616 }
7617 }
7618
7619 val = get_param(cmd, "nss_mcs_cap");
7620 if (val) {
7621 int nss, mcs;
7622 char token[20];
7623 char *result = NULL;
7624 unsigned int vht_mcsmap = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307625 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007626
Peng Xub8fc5cc2017-05-10 17:27:28 -07007627 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307628 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05307629 if (!result) {
7630 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07007631 "NSS not specified");
7632 send_resp(dut, conn, SIGMA_ERROR,
7633 "errorCode,NSS not specified");
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05307634 return 0;
7635 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007636 nss = atoi(result);
7637
7638 snprintf(buf, sizeof(buf), "iwpriv %s nss %d", intf, nss);
7639 if (system(buf) != 0) {
7640 sigma_dut_print(dut, DUT_MSG_ERROR,
7641 "iwpriv nss failed");
7642 }
Arif Hussainac6c5112018-05-25 17:34:00 -07007643 dut->sta_nss = nss;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007644
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307645 result = strtok_r(NULL, ";", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007646 if (result == NULL) {
7647 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07007648 "MCS not specified");
7649 send_resp(dut, conn, SIGMA_ERROR,
7650 "errorCode,MCS not specified");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007651 return 0;
7652 }
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307653 result = strtok_r(result, "-", &saveptr);
7654 result = strtok_r(NULL, "-", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05307655 if (!result) {
7656 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07007657 "MCS not specified");
7658 send_resp(dut, conn, SIGMA_ERROR,
7659 "errorCode,MCS not specified");
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05307660 return 0;
7661 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007662 mcs = atoi(result);
7663
Arif Hussaina37e9552018-06-20 17:05:59 -07007664 if (program && strcasecmp(program, "HE") == 0) {
7665#ifdef NL80211_SUPPORT
7666 enum he_mcs_config mcs_config;
7667 int ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007668
Arif Hussaina37e9552018-06-20 17:05:59 -07007669 if (mcs >= 0 && mcs <= 7) {
7670 mcs_config = HE_80_MCS0_7;
7671 } else if (mcs > 7 && mcs <= 9) {
7672 mcs_config = HE_80_MCS0_9;
7673 } else if (mcs > 9 && mcs <= 11) {
7674 mcs_config = HE_80_MCS0_11;
7675 } else {
7676 sigma_dut_print(dut, DUT_MSG_ERROR,
7677 "nss_mcs_cap: HE: Invalid mcs: %d",
7678 mcs);
7679 send_resp(dut, conn, SIGMA_ERROR,
7680 "errorCode,Invalid MCS");
7681 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007682 }
Arif Hussaina37e9552018-06-20 17:05:59 -07007683
7684 ret = sta_set_he_mcs(dut, intf, mcs_config);
7685 if (ret) {
7686 sigma_dut_print(dut, DUT_MSG_ERROR,
7687 "nss_mcs_cap: HE: Setting of MCS failed, mcs_config: %d, ret: %d",
7688 mcs_config, ret);
7689 send_resp(dut, conn, SIGMA_ERROR,
7690 "errorCode,Failed to set MCS");
7691 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007692 }
Arif Hussaina37e9552018-06-20 17:05:59 -07007693#else /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007694 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07007695 "nss_mcs_cap: HE: MCS cannot be changed without NL80211_SUPPORT defined");
7696#endif /* NL80211_SUPPORT */
7697 } else {
7698 snprintf(buf, sizeof(buf), "iwpriv %s vhtmcs %d",
7699 intf, mcs);
7700 if (system(buf) != 0) {
7701 sigma_dut_print(dut, DUT_MSG_ERROR,
7702 "iwpriv mcs failed");
7703 }
7704
7705 switch (nss) {
7706 case 1:
7707 switch (mcs) {
7708 case 7:
7709 vht_mcsmap = 0xfffc;
7710 break;
7711 case 8:
7712 vht_mcsmap = 0xfffd;
7713 break;
7714 case 9:
7715 vht_mcsmap = 0xfffe;
7716 break;
7717 default:
7718 vht_mcsmap = 0xfffe;
7719 break;
7720 }
7721 break;
7722 case 2:
7723 switch (mcs) {
7724 case 7:
7725 vht_mcsmap = 0xfff0;
7726 break;
7727 case 8:
7728 vht_mcsmap = 0xfff5;
7729 break;
7730 case 9:
7731 vht_mcsmap = 0xfffa;
7732 break;
7733 default:
7734 vht_mcsmap = 0xfffa;
7735 break;
7736 }
7737 break;
7738 case 3:
7739 switch (mcs) {
7740 case 7:
7741 vht_mcsmap = 0xffc0;
7742 break;
7743 case 8:
7744 vht_mcsmap = 0xffd5;
7745 break;
7746 case 9:
7747 vht_mcsmap = 0xffea;
7748 break;
7749 default:
7750 vht_mcsmap = 0xffea;
7751 break;
7752 }
7753 break;
7754 default:
7755 vht_mcsmap = 0xffea;
7756 break;
7757 }
7758 snprintf(buf, sizeof(buf),
7759 "iwpriv %s vht_mcsmap 0x%04x",
7760 intf, vht_mcsmap);
7761 if (system(buf) != 0) {
7762 sigma_dut_print(dut, DUT_MSG_ERROR,
7763 "iwpriv vht_mcsmap failed");
7764 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007765 }
7766 }
7767
7768 /* UNSUPPORTED: val = get_param(cmd, "Tx_lgi_rate"); */
7769
7770 val = get_param(cmd, "Vht_tkip");
7771 if (val)
7772 tkip = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
7773
7774 val = get_param(cmd, "Vht_wep");
7775 if (val)
7776 wep = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
7777
7778 if (tkip != -1 || wep != -1) {
7779 if ((tkip == 1 && wep != 0) || (wep == 1 && tkip != 0)) {
7780 snprintf(buf, sizeof(buf), "iwpriv %s htweptkip 1",
7781 intf);
7782 } else if ((tkip == 0 && wep != 1) || (wep == 0 && tkip != 1)) {
7783 snprintf(buf, sizeof(buf), "iwpriv %s htweptkip 0",
7784 intf);
7785 } else {
7786 sigma_dut_print(dut, DUT_MSG_ERROR,
7787 "ErrorCode,mixed mode of VHT TKIP/WEP not supported");
7788 return 0;
7789 }
7790
7791 if (system(buf) != 0) {
7792 sigma_dut_print(dut, DUT_MSG_ERROR,
7793 "iwpriv htweptkip failed");
7794 }
7795 }
7796
Arif Hussain55f00da2018-07-03 08:28:26 -07007797 val = get_param(cmd, "txBandwidth");
7798 if (val) {
7799 switch (get_driver_type()) {
7800 case DRIVER_WCN:
7801 if (wcn_sta_set_width(dut, intf, val) < 0) {
7802 send_resp(dut, conn, SIGMA_ERROR,
7803 "ErrorCode,Failed to set txBandwidth");
7804 return 0;
7805 }
7806 break;
7807 case DRIVER_ATHEROS:
7808 if (ath_set_width(dut, conn, intf, val) < 0) {
7809 send_resp(dut, conn, SIGMA_ERROR,
7810 "ErrorCode,Failed to set txBandwidth");
7811 return 0;
7812 }
7813 break;
7814 default:
7815 sigma_dut_print(dut, DUT_MSG_ERROR,
7816 "Setting txBandwidth not supported");
7817 break;
7818 }
7819 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007820
Arif Hussain9765f7d2018-07-03 08:28:26 -07007821 val = get_param(cmd, "BeamformeeSTS");
7822 if (val) {
Kiran Kumar Lokerebc89d432018-07-10 12:20:13 -07007823 if (sta_set_tx_beamformee(dut, intf, 1)) {
7824 send_resp(dut, conn, SIGMA_ERROR,
7825 "ErrorCode,Failed to set TX beamformee enable");
7826 return 0;
7827 }
7828
Arif Hussain9765f7d2018-07-03 08:28:26 -07007829 if (sta_set_beamformee_sts(dut, intf, atoi(val))) {
7830 send_resp(dut, conn, SIGMA_ERROR,
7831 "ErrorCode,Failed to set BeamformeeSTS");
7832 return 0;
7833 }
7834 }
7835
Arif Hussain68d23f52018-07-11 13:39:08 -07007836 val = get_param(cmd, "Trig_MAC_Padding_Dur");
7837 if (val) {
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07007838#ifdef NL80211_SUPPORT
7839 enum qca_wlan_he_mac_padding_dur set_val;
7840
7841 switch (atoi(val)) {
7842 case 16:
7843 set_val = QCA_WLAN_HE_16US_OF_PROCESS_TIME;
7844 break;
7845 case 8:
7846 set_val = QCA_WLAN_HE_8US_OF_PROCESS_TIME;
7847 break;
7848 default:
7849 set_val = QCA_WLAN_HE_NO_ADDITIONAL_PROCESS_TIME;
7850 break;
7851 }
7852 if (sta_set_mac_padding_duration(dut, intf, set_val)) {
Arif Hussain68d23f52018-07-11 13:39:08 -07007853 send_resp(dut, conn, SIGMA_ERROR,
7854 "ErrorCode,Failed to set MAC padding duration");
7855 return 0;
7856 }
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07007857#else /* NL80211_SUPPORT */
7858 sigma_dut_print(dut, DUT_MSG_ERROR,
7859 "MAC padding duration cannot be changed without NL80211_SUPPORT defined");
7860#endif /* NL80211_SUPPORT */
Arif Hussain68d23f52018-07-11 13:39:08 -07007861 }
7862
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07007863 val = get_param(cmd, "MU_EDCA");
7864 if (val && (strcasecmp(val, "Override") == 0)) {
7865 if (sta_set_mu_edca_override(dut, intf, 1)) {
7866 send_resp(dut, conn, SIGMA_ERROR,
7867 "ErrorCode,Failed to set MU EDCA override");
7868 return 0;
7869 }
7870 }
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -07007871
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07007872 val = get_param(cmd, "OMControl");
7873 if (val) {
7874 int set_val = 1;
7875
7876 if (strcasecmp(val, "Enable") == 0)
7877 set_val = 1;
7878 else if (strcasecmp(val, "Disable") == 0)
7879 set_val = 0;
7880
7881 if (sta_set_om_ctrl_supp(dut, intf, set_val)) {
7882 send_resp(dut, conn, SIGMA_ERROR,
7883 "ErrorCode,Failed to set OM ctrl supp");
7884 return 0;
7885 }
7886 }
7887
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -07007888 val = get_param(cmd, "ADDBAResp_BufSize");
7889 if (val) {
7890 int buf_size;
7891
7892 if (strcasecmp(val, "gt64") == 0)
7893 buf_size = 256;
7894 else
7895 buf_size = 64;
7896 if (get_driver_type() == DRIVER_WCN &&
7897 sta_set_addba_buf_size(dut, intf, buf_size)) {
7898 send_resp(dut, conn, SIGMA_ERROR,
7899 "ErrorCode,set addbaresp_buff_size failed");
7900 return 0;
7901 }
7902 }
7903
7904 val = get_param(cmd, "ADDBAReq_BufSize");
7905 if (val) {
7906 int buf_size;
7907
7908 if (strcasecmp(val, "gt64") == 0)
7909 buf_size = 256;
7910 else
7911 buf_size = 64;
7912 if (get_driver_type() == DRIVER_WCN &&
7913 sta_set_addba_buf_size(dut, intf, buf_size)) {
7914 send_resp(dut, conn, SIGMA_ERROR,
7915 "ErrorCode,set addbareq_buff_size failed");
7916 return 0;
7917 }
7918 }
7919
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007920 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
7921}
7922
7923
7924static int sta_set_wireless_60g(struct sigma_dut *dut,
7925 struct sigma_conn *conn,
7926 struct sigma_cmd *cmd)
7927{
7928 const char *dev_role = get_param(cmd, "DevRole");
7929
7930 if (!dev_role) {
7931 send_resp(dut, conn, SIGMA_INVALID,
7932 "ErrorCode,DevRole not specified");
7933 return 0;
7934 }
7935
7936 if (strcasecmp(dev_role, "PCP") == 0)
7937 return sta_set_60g_pcp(dut, conn, cmd);
7938 if (strcasecmp(dev_role, "STA") == 0)
7939 return sta_set_60g_sta(dut, conn, cmd);
7940 send_resp(dut, conn, SIGMA_INVALID,
7941 "ErrorCode,DevRole not supported");
7942 return 0;
7943}
7944
7945
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05307946static int sta_set_wireless_oce(struct sigma_dut *dut, struct sigma_conn *conn,
7947 struct sigma_cmd *cmd)
7948{
7949 int status;
7950 const char *intf = get_param(cmd, "Interface");
7951 const char *val = get_param(cmd, "DevRole");
7952
7953 if (val && strcasecmp(val, "STA-CFON") == 0) {
7954 status = sta_cfon_set_wireless(dut, conn, cmd);
7955 if (status)
7956 return status;
7957 }
7958 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
7959}
7960
7961
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007962static int cmd_sta_set_wireless(struct sigma_dut *dut, struct sigma_conn *conn,
7963 struct sigma_cmd *cmd)
7964{
7965 const char *val;
7966
7967 val = get_param(cmd, "Program");
7968 if (val) {
7969 if (strcasecmp(val, "11n") == 0)
7970 return cmd_sta_set_11n(dut, conn, cmd);
Amarnath Hullur Subramanyam4f860292018-01-31 03:49:35 -08007971 if (strcasecmp(val, "VHT") == 0 || strcasecmp(val, "HE") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007972 return cmd_sta_set_wireless_vht(dut, conn, cmd);
7973 if (strcasecmp(val, "60ghz") == 0)
7974 return sta_set_wireless_60g(dut, conn, cmd);
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05307975 if (strcasecmp(val, "OCE") == 0)
7976 return sta_set_wireless_oce(dut, conn, cmd);
Alexei Avshalom Lazar66bb9972018-12-18 16:01:43 +02007977 /* sta_set_wireless in WPS program is only used for 60G */
7978 if (is_60g_sigma_dut(dut))
7979 return sta_set_wireless_60g(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007980 send_resp(dut, conn, SIGMA_ERROR,
7981 "ErrorCode,Program value not supported");
7982 } else {
7983 send_resp(dut, conn, SIGMA_ERROR,
7984 "ErrorCode,Program argument not available");
7985 }
7986
7987 return 0;
7988}
7989
7990
7991static void ath_sta_inject_frame(struct sigma_dut *dut, const char *intf,
7992 int tid)
7993{
7994 char buf[100];
7995 int tid_to_dscp [] = { 0x00, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0 };
7996
Pradeep Reddy POTTETId31d1322016-10-13 17:22:03 +05307997 if (tid < 0 ||
7998 tid >= (int) (sizeof(tid_to_dscp) / sizeof(tid_to_dscp[0]))) {
7999 sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported TID: %d", tid);
8000 return;
8001 }
8002
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008003 /*
8004 * Two ways to ensure that addba request with a
8005 * non zero TID could be sent out. EV 117296
8006 */
8007 snprintf(buf, sizeof(buf),
8008 "ping -c 8 -Q %d `arp -a | grep wlan0 | awk '{print $2}' | tr -d '()'`",
8009 tid);
8010 if (system(buf) != 0) {
8011 sigma_dut_print(dut, DUT_MSG_ERROR,
8012 "Ping did not send out");
8013 }
8014
8015 snprintf(buf, sizeof(buf),
8016 "iwconfig %s | grep Access | awk '{print $6}' > %s",
8017 intf, VI_QOS_TMP_FILE);
8018 if (system(buf) != 0)
8019 return;
8020
8021 snprintf(buf, sizeof(buf),
8022 "ifconfig %s | grep HWaddr | cut -b 39-56 >> %s",
8023 intf, VI_QOS_TMP_FILE);
8024 if (system(buf) != 0)
8025 sigma_dut_print(dut, DUT_MSG_ERROR, "HWaddr matching failed");
8026
8027 snprintf(buf,sizeof(buf), "sed -n '3,$p' %s >> %s",
8028 VI_QOS_REFFILE, VI_QOS_TMP_FILE);
8029 if (system(buf) != 0) {
8030 sigma_dut_print(dut, DUT_MSG_ERROR,
8031 "VI_QOS_TEMP_FILE generation error failed");
8032 }
8033 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
8034 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
8035 if (system(buf) != 0) {
8036 sigma_dut_print(dut, DUT_MSG_ERROR,
8037 "VI_QOS_FILE generation failed");
8038 }
8039
8040 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
8041 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
8042 if (system(buf) != 0) {
8043 sigma_dut_print(dut, DUT_MSG_ERROR,
8044 "VI_QOS_FILE generation failed");
8045 }
8046
8047 snprintf(buf, sizeof(buf), "ethinject %s %s", intf, VI_QOS_FILE);
8048 if (system(buf) != 0) {
8049 }
8050}
8051
8052
8053static int ath_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
8054 struct sigma_cmd *cmd)
8055{
8056 const char *intf = get_param(cmd, "Interface");
8057 const char *val;
8058 int tid = 0;
8059 char buf[100];
8060
8061 val = get_param(cmd, "TID");
8062 if (val) {
8063 tid = atoi(val);
8064 if (tid)
8065 ath_sta_inject_frame(dut, intf, tid);
8066 }
8067
8068 /* Command sequence for ADDBA request on Peregrine based devices */
8069 snprintf(buf, sizeof(buf), "iwpriv %s setaddbaoper 1", intf);
8070 if (system(buf) != 0) {
8071 sigma_dut_print(dut, DUT_MSG_ERROR,
8072 "iwpriv setaddbaoper failed");
8073 }
8074
8075 snprintf(buf, sizeof(buf), "wifitool %s senddelba 1 %d 1 4", intf, tid);
8076 if (system(buf) != 0) {
8077 sigma_dut_print(dut, DUT_MSG_ERROR,
8078 "wifitool senddelba failed");
8079 }
8080
8081 snprintf(buf, sizeof(buf), "wifitool %s sendaddba 1 %d 64", intf, tid);
8082 if (system(buf) != 0) {
8083 sigma_dut_print(dut, DUT_MSG_ERROR,
8084 "wifitool sendaddba failed");
8085 }
8086
8087 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
8088
8089 return 1;
8090}
8091
8092
Lior David9981b512017-01-20 13:16:40 +02008093#ifdef __linux__
8094
8095static int wil6210_send_addba(struct sigma_dut *dut, const char *dest_mac,
8096 int agg_size)
8097{
8098 char dir[128], buf[128];
8099 FILE *f;
8100 regex_t re;
8101 regmatch_t m[2];
8102 int rc, ret = -1, vring_id, found;
8103
8104 if (wil6210_get_debugfs_dir(dut, dir, sizeof(dir))) {
8105 sigma_dut_print(dut, DUT_MSG_ERROR,
8106 "failed to get wil6210 debugfs dir");
8107 return -1;
8108 }
8109
8110 snprintf(buf, sizeof(buf), "%s/vrings", dir);
8111 f = fopen(buf, "r");
8112 if (!f) {
8113 sigma_dut_print(dut, DUT_MSG_ERROR, "failed to open: %s", buf);
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +02008114 /* newer wil6210 driver renamed file to "rings" */
8115 snprintf(buf, sizeof(buf), "%s/rings", dir);
8116 f = fopen(buf, "r");
8117 if (!f) {
8118 sigma_dut_print(dut, DUT_MSG_ERROR,
8119 "failed to open: %s", buf);
8120 return -1;
8121 }
Lior David9981b512017-01-20 13:16:40 +02008122 }
8123
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +02008124 /* can be either VRING tx... or RING... */
8125 if (regcomp(&re, "RING tx_[ \t]*([0-9]+)", REG_EXTENDED)) {
Lior David9981b512017-01-20 13:16:40 +02008126 sigma_dut_print(dut, DUT_MSG_ERROR, "regcomp failed");
8127 goto out;
8128 }
8129
8130 /* find TX VRING for the mac address */
8131 found = 0;
8132 while (fgets(buf, sizeof(buf), f)) {
8133 if (strcasestr(buf, dest_mac)) {
8134 found = 1;
8135 break;
8136 }
8137 }
8138
8139 if (!found) {
8140 sigma_dut_print(dut, DUT_MSG_ERROR,
8141 "no TX VRING for %s", dest_mac);
8142 goto out;
8143 }
8144
8145 /* extract VRING ID, "VRING tx_<id> = {" */
8146 if (!fgets(buf, sizeof(buf), f)) {
8147 sigma_dut_print(dut, DUT_MSG_ERROR,
8148 "no VRING start line for %s", dest_mac);
8149 goto out;
8150 }
8151
8152 rc = regexec(&re, buf, 2, m, 0);
8153 regfree(&re);
8154 if (rc || m[1].rm_so < 0) {
8155 sigma_dut_print(dut, DUT_MSG_ERROR,
8156 "no VRING TX ID for %s", dest_mac);
8157 goto out;
8158 }
8159 buf[m[1].rm_eo] = 0;
8160 vring_id = atoi(&buf[m[1].rm_so]);
8161
8162 /* send the addba command */
8163 fclose(f);
8164 snprintf(buf, sizeof(buf), "%s/back", dir);
8165 f = fopen(buf, "w");
8166 if (!f) {
8167 sigma_dut_print(dut, DUT_MSG_ERROR,
8168 "failed to open: %s", buf);
8169 return -1;
8170 }
8171
8172 fprintf(f, "add %d %d\n", vring_id, agg_size);
8173
8174 ret = 0;
8175
8176out:
8177 fclose(f);
8178
8179 return ret;
8180}
8181
8182
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +02008183int send_addba_60g(struct sigma_dut *dut, struct sigma_conn *conn,
8184 struct sigma_cmd *cmd, const char *mac_param)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008185{
8186 const char *val;
8187 int tid = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008188
8189 val = get_param(cmd, "TID");
8190 if (val) {
8191 tid = atoi(val);
8192 if (tid != 0) {
8193 sigma_dut_print(dut, DUT_MSG_ERROR,
8194 "Ignore TID %d for send_addba use TID 0 for 60g since only 0 required on TX",
8195 tid);
8196 }
8197 }
8198
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +02008199 val = get_param(cmd, mac_param);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008200 if (!val) {
8201 sigma_dut_print(dut, DUT_MSG_ERROR,
8202 "Currently not supporting addba for 60G without Dest_mac");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02008203 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008204 }
8205
Lior David9981b512017-01-20 13:16:40 +02008206 if (wil6210_send_addba(dut, val, dut->back_rcv_buf))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008207 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008208
8209 return 1;
8210}
8211
Lior David9981b512017-01-20 13:16:40 +02008212#endif /* __linux__ */
8213
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008214
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08008215static int wcn_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
8216 struct sigma_cmd *cmd)
8217{
8218#ifdef NL80211_SUPPORT
8219 const char *intf = get_param(cmd, "Interface");
8220 const char *val;
8221 int tid = -1;
8222 int bufsize = 64;
8223 struct nl_msg *msg;
8224 int ret = 0;
8225 struct nlattr *params;
8226 int ifindex;
8227
8228 val = get_param(cmd, "TID");
8229 if (val)
8230 tid = atoi(val);
8231
8232 if (tid == -1) {
8233 send_resp(dut, conn, SIGMA_ERROR,
8234 "ErrorCode,sta_send_addba tid invalid");
8235 return 0;
8236 }
8237
8238 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
8239
8240 ifindex = if_nametoindex(intf);
8241 if (ifindex == 0) {
8242 sigma_dut_print(dut, DUT_MSG_ERROR,
8243 "%s: Index for interface %s failed",
8244 __func__, intf);
8245 send_resp(dut, conn, SIGMA_ERROR,
8246 "ErrorCode,sta_send_addba interface invalid");
8247 return 0;
8248 }
8249
8250 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8251 NL80211_CMD_VENDOR)) ||
8252 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
8253 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
8254 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
8255 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
8256 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8257 nla_put_u8(msg,
8258 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADD_DEL_BA_SESSION,
8259 QCA_WLAN_ADD_BA) ||
8260 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BA_TID,
8261 tid) ||
Kiran Kumar Lokere26e27582018-08-01 16:18:34 -07008262 nla_put_u16(msg,
8263 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE,
8264 bufsize)) {
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08008265 sigma_dut_print(dut, DUT_MSG_ERROR,
8266 "%s: err in adding vendor_cmd and vendor_data",
8267 __func__);
8268 nlmsg_free(msg);
8269 send_resp(dut, conn, SIGMA_ERROR,
8270 "ErrorCode,sta_send_addba err in adding vendor_cmd and vendor_data");
8271 return 0;
8272 }
8273 nla_nest_end(msg, params);
8274
8275 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
8276 if (ret) {
8277 sigma_dut_print(dut, DUT_MSG_ERROR,
8278 "%s: err in send_and_recv_msgs, ret=%d",
8279 __func__, ret);
Sunil Dutt30605592018-05-04 20:35:50 +05308280 if (ret == -EOPNOTSUPP)
8281 return 1;
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08008282 send_resp(dut, conn, SIGMA_ERROR,
8283 "ErrorCode,sta_send_addba err in send_and_recv_msgs");
8284 return 0;
8285 }
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08008286#else /* NL80211_SUPPORT */
8287 sigma_dut_print(dut, DUT_MSG_ERROR,
8288 "sta_send_addba not supported without NL80211_SUPPORT defined");
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08008289#endif /* NL80211_SUPPORT */
Sunil Dutt30605592018-05-04 20:35:50 +05308290
8291 return 1;
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08008292}
8293
8294
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008295static int cmd_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
8296 struct sigma_cmd *cmd)
8297{
8298 switch (get_driver_type()) {
8299 case DRIVER_ATHEROS:
8300 return ath_sta_send_addba(dut, conn, cmd);
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08008301 case DRIVER_WCN:
8302 return wcn_sta_send_addba(dut, conn, cmd);
Lior David9981b512017-01-20 13:16:40 +02008303#ifdef __linux__
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008304 case DRIVER_WIL6210:
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +02008305 return send_addba_60g(dut, conn, cmd, "Dest_mac");
Lior David9981b512017-01-20 13:16:40 +02008306#endif /* __linux__ */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008307 default:
8308 /*
8309 * There is no driver specific implementation for other drivers.
8310 * Ignore the command and report COMPLETE since the following
8311 * throughput test operation will end up sending ADDBA anyway.
8312 */
8313 return 1;
8314 }
8315}
8316
8317
8318int inject_eth_frame(int s, const void *data, size_t len,
8319 unsigned short ethtype, char *dst, char *src)
8320{
8321 struct iovec iov[4] = {
8322 {
8323 .iov_base = dst,
8324 .iov_len = ETH_ALEN,
8325 },
8326 {
8327 .iov_base = src,
8328 .iov_len = ETH_ALEN,
8329 },
8330 {
8331 .iov_base = &ethtype,
8332 .iov_len = sizeof(unsigned short),
8333 },
8334 {
8335 .iov_base = (void *) data,
8336 .iov_len = len,
8337 }
8338 };
8339 struct msghdr msg = {
8340 .msg_name = NULL,
8341 .msg_namelen = 0,
8342 .msg_iov = iov,
8343 .msg_iovlen = 4,
8344 .msg_control = NULL,
8345 .msg_controllen = 0,
8346 .msg_flags = 0,
8347 };
8348
8349 return sendmsg(s, &msg, 0);
8350}
8351
8352#if defined(__linux__) || defined(__QNXNTO__)
8353
8354int inject_frame(int s, const void *data, size_t len, int encrypt)
8355{
8356#define IEEE80211_RADIOTAP_F_WEP 0x04
8357#define IEEE80211_RADIOTAP_F_FRAG 0x08
8358 unsigned char rtap_hdr[] = {
8359 0x00, 0x00, /* radiotap version */
8360 0x0e, 0x00, /* radiotap length */
8361 0x02, 0xc0, 0x00, 0x00, /* bmap: flags, tx and rx flags */
8362 IEEE80211_RADIOTAP_F_FRAG, /* F_FRAG (fragment if required) */
8363 0x00, /* padding */
8364 0x00, 0x00, /* RX and TX flags to indicate that */
8365 0x00, 0x00, /* this is the injected frame directly */
8366 };
8367 struct iovec iov[2] = {
8368 {
8369 .iov_base = &rtap_hdr,
8370 .iov_len = sizeof(rtap_hdr),
8371 },
8372 {
8373 .iov_base = (void *) data,
8374 .iov_len = len,
8375 }
8376 };
8377 struct msghdr msg = {
8378 .msg_name = NULL,
8379 .msg_namelen = 0,
8380 .msg_iov = iov,
8381 .msg_iovlen = 2,
8382 .msg_control = NULL,
8383 .msg_controllen = 0,
8384 .msg_flags = 0,
8385 };
8386
8387 if (encrypt)
8388 rtap_hdr[8] |= IEEE80211_RADIOTAP_F_WEP;
8389
8390 return sendmsg(s, &msg, 0);
8391}
8392
8393
8394int open_monitor(const char *ifname)
8395{
8396#ifdef __QNXNTO__
8397 struct sockaddr_dl ll;
8398 int s;
8399
8400 memset(&ll, 0, sizeof(ll));
8401 ll.sdl_family = AF_LINK;
8402 ll.sdl_index = if_nametoindex(ifname);
8403 if (ll.sdl_index == 0) {
8404 perror("if_nametoindex");
8405 return -1;
8406 }
8407 s = socket(PF_INET, SOCK_RAW, 0);
8408#else /* __QNXNTO__ */
8409 struct sockaddr_ll ll;
8410 int s;
8411
8412 memset(&ll, 0, sizeof(ll));
8413 ll.sll_family = AF_PACKET;
8414 ll.sll_ifindex = if_nametoindex(ifname);
8415 if (ll.sll_ifindex == 0) {
8416 perror("if_nametoindex");
8417 return -1;
8418 }
8419 s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
8420#endif /* __QNXNTO__ */
8421 if (s < 0) {
8422 perror("socket[PF_PACKET,SOCK_RAW]");
8423 return -1;
8424 }
8425
8426 if (bind(s, (struct sockaddr *) &ll, sizeof(ll)) < 0) {
8427 perror("monitor socket bind");
8428 close(s);
8429 return -1;
8430 }
8431
8432 return s;
8433}
8434
8435
8436static int hex2num(char c)
8437{
8438 if (c >= '0' && c <= '9')
8439 return c - '0';
8440 if (c >= 'a' && c <= 'f')
8441 return c - 'a' + 10;
8442 if (c >= 'A' && c <= 'F')
8443 return c - 'A' + 10;
8444 return -1;
8445}
8446
8447
8448int hwaddr_aton(const char *txt, unsigned char *addr)
8449{
8450 int i;
8451
8452 for (i = 0; i < 6; i++) {
8453 int a, b;
8454
8455 a = hex2num(*txt++);
8456 if (a < 0)
8457 return -1;
8458 b = hex2num(*txt++);
8459 if (b < 0)
8460 return -1;
8461 *addr++ = (a << 4) | b;
8462 if (i < 5 && *txt++ != ':')
8463 return -1;
8464 }
8465
8466 return 0;
8467}
8468
8469#endif /* defined(__linux__) || defined(__QNXNTO__) */
8470
8471enum send_frame_type {
8472 DISASSOC, DEAUTH, SAQUERY, AUTH, ASSOCREQ, REASSOCREQ, DLS_REQ
8473};
8474enum send_frame_protection {
8475 CORRECT_KEY, INCORRECT_KEY, UNPROTECTED
8476};
8477
8478
8479static int sta_inject_frame(struct sigma_dut *dut, struct sigma_conn *conn,
8480 enum send_frame_type frame,
8481 enum send_frame_protection protected,
8482 const char *dest)
8483{
8484#ifdef __linux__
8485 unsigned char buf[1000], *pos;
8486 int s, res;
8487 char bssid[20], addr[20];
8488 char result[32], ssid[100];
8489 size_t ssid_len;
8490
8491 if (get_wpa_status(get_station_ifname(), "wpa_state", result,
8492 sizeof(result)) < 0 ||
8493 strncmp(result, "COMPLETED", 9) != 0) {
8494 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Not connected");
8495 return 0;
8496 }
8497
8498 if (get_wpa_status(get_station_ifname(), "bssid", bssid, sizeof(bssid))
8499 < 0) {
8500 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
8501 "current BSSID");
8502 return 0;
8503 }
8504
8505 if (get_wpa_status(get_station_ifname(), "address", addr, sizeof(addr))
8506 < 0) {
8507 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
8508 "own MAC address");
8509 return 0;
8510 }
8511
8512 if (get_wpa_status(get_station_ifname(), "ssid", ssid, sizeof(ssid))
8513 < 0) {
8514 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
8515 "current SSID");
8516 return 0;
8517 }
8518 ssid_len = strlen(ssid);
8519
8520 pos = buf;
8521
8522 /* Frame Control */
8523 switch (frame) {
8524 case DISASSOC:
8525 *pos++ = 0xa0;
8526 break;
8527 case DEAUTH:
8528 *pos++ = 0xc0;
8529 break;
8530 case SAQUERY:
8531 *pos++ = 0xd0;
8532 break;
8533 case AUTH:
8534 *pos++ = 0xb0;
8535 break;
8536 case ASSOCREQ:
8537 *pos++ = 0x00;
8538 break;
8539 case REASSOCREQ:
8540 *pos++ = 0x20;
8541 break;
8542 case DLS_REQ:
8543 *pos++ = 0xd0;
8544 break;
8545 }
8546
8547 if (protected == INCORRECT_KEY)
8548 *pos++ = 0x40; /* Set Protected field to 1 */
8549 else
8550 *pos++ = 0x00;
8551
8552 /* Duration */
8553 *pos++ = 0x00;
8554 *pos++ = 0x00;
8555
8556 /* addr1 = DA (current AP) */
8557 hwaddr_aton(bssid, pos);
8558 pos += 6;
8559 /* addr2 = SA (own address) */
8560 hwaddr_aton(addr, pos);
8561 pos += 6;
8562 /* addr3 = BSSID (current AP) */
8563 hwaddr_aton(bssid, pos);
8564 pos += 6;
8565
8566 /* Seq# (to be filled by driver/mac80211) */
8567 *pos++ = 0x00;
8568 *pos++ = 0x00;
8569
8570 if (protected == INCORRECT_KEY) {
8571 /* CCMP parameters */
8572 memcpy(pos, "\x61\x01\x00\x20\x00\x10\x00\x00", 8);
8573 pos += 8;
8574 }
8575
8576 if (protected == INCORRECT_KEY) {
8577 switch (frame) {
8578 case DEAUTH:
8579 /* Reason code (encrypted) */
8580 memcpy(pos, "\xa7\x39", 2);
8581 pos += 2;
8582 break;
8583 case DISASSOC:
8584 /* Reason code (encrypted) */
8585 memcpy(pos, "\xa7\x39", 2);
8586 pos += 2;
8587 break;
8588 case SAQUERY:
8589 /* Category|Action|TransID (encrypted) */
8590 memcpy(pos, "\x6f\xbd\xe9\x4d", 4);
8591 pos += 4;
8592 break;
8593 default:
8594 return -1;
8595 }
8596
8597 /* CCMP MIC */
8598 memcpy(pos, "\xc8\xd8\x3b\x06\x5d\xb7\x25\x68", 8);
8599 pos += 8;
8600 } else {
8601 switch (frame) {
8602 case DEAUTH:
8603 /* reason code = 8 */
8604 *pos++ = 0x08;
8605 *pos++ = 0x00;
8606 break;
8607 case DISASSOC:
8608 /* reason code = 8 */
8609 *pos++ = 0x08;
8610 *pos++ = 0x00;
8611 break;
8612 case SAQUERY:
8613 /* Category - SA Query */
8614 *pos++ = 0x08;
8615 /* SA query Action - Request */
8616 *pos++ = 0x00;
8617 /* Transaction ID */
8618 *pos++ = 0x12;
8619 *pos++ = 0x34;
8620 break;
8621 case AUTH:
8622 /* Auth Alg (Open) */
8623 *pos++ = 0x00;
8624 *pos++ = 0x00;
8625 /* Seq# */
8626 *pos++ = 0x01;
8627 *pos++ = 0x00;
8628 /* Status code */
8629 *pos++ = 0x00;
8630 *pos++ = 0x00;
8631 break;
8632 case ASSOCREQ:
8633 /* Capability Information */
8634 *pos++ = 0x31;
8635 *pos++ = 0x04;
8636 /* Listen Interval */
8637 *pos++ = 0x0a;
8638 *pos++ = 0x00;
8639 /* SSID */
8640 *pos++ = 0x00;
8641 *pos++ = ssid_len;
8642 memcpy(pos, ssid, ssid_len);
8643 pos += ssid_len;
8644 /* Supported Rates */
8645 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
8646 10);
8647 pos += 10;
8648 /* Extended Supported Rates */
8649 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
8650 pos += 6;
8651 /* RSN */
8652 memcpy(pos, "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00"
8653 "\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x02\xc0"
8654 "\x00\x00\x00\x00\x0f\xac\x06", 28);
8655 pos += 28;
8656 break;
8657 case REASSOCREQ:
8658 /* Capability Information */
8659 *pos++ = 0x31;
8660 *pos++ = 0x04;
8661 /* Listen Interval */
8662 *pos++ = 0x0a;
8663 *pos++ = 0x00;
8664 /* Current AP */
8665 hwaddr_aton(bssid, pos);
8666 pos += 6;
8667 /* SSID */
8668 *pos++ = 0x00;
8669 *pos++ = ssid_len;
8670 memcpy(pos, ssid, ssid_len);
8671 pos += ssid_len;
8672 /* Supported Rates */
8673 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
8674 10);
8675 pos += 10;
8676 /* Extended Supported Rates */
8677 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
8678 pos += 6;
8679 /* RSN */
8680 memcpy(pos, "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00"
8681 "\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x02\xc0"
8682 "\x00\x00\x00\x00\x0f\xac\x06", 28);
8683 pos += 28;
8684 break;
8685 case DLS_REQ:
8686 /* Category - DLS */
8687 *pos++ = 0x02;
8688 /* DLS Action - Request */
8689 *pos++ = 0x00;
8690 /* Destination MACAddress */
8691 if (dest)
8692 hwaddr_aton(dest, pos);
8693 else
8694 memset(pos, 0, 6);
8695 pos += 6;
8696 /* Source MACAddress */
8697 hwaddr_aton(addr, pos);
8698 pos += 6;
8699 /* Capability Information */
8700 *pos++ = 0x10; /* Privacy */
8701 *pos++ = 0x06; /* QoS */
8702 /* DLS Timeout Value */
8703 *pos++ = 0x00;
8704 *pos++ = 0x01;
8705 /* Supported rates */
8706 *pos++ = 0x01;
8707 *pos++ = 0x08;
8708 *pos++ = 0x0c; /* 6 Mbps */
8709 *pos++ = 0x12; /* 9 Mbps */
8710 *pos++ = 0x18; /* 12 Mbps */
8711 *pos++ = 0x24; /* 18 Mbps */
8712 *pos++ = 0x30; /* 24 Mbps */
8713 *pos++ = 0x48; /* 36 Mbps */
8714 *pos++ = 0x60; /* 48 Mbps */
8715 *pos++ = 0x6c; /* 54 Mbps */
8716 /* TODO: Extended Supported Rates */
8717 /* TODO: HT Capabilities */
8718 break;
8719 }
8720 }
8721
8722 s = open_monitor("sigmadut");
8723 if (s < 0) {
8724 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
8725 "monitor socket");
8726 return 0;
8727 }
8728
8729 res = inject_frame(s, buf, pos - buf, protected == CORRECT_KEY);
8730 if (res < 0) {
8731 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
8732 "inject frame");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05308733 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008734 return 0;
8735 }
8736 if (res < pos - buf) {
8737 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Only partial "
8738 "frame sent");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05308739 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008740 return 0;
8741 }
8742
8743 close(s);
8744
8745 return 1;
8746#else /* __linux__ */
8747 send_resp(dut, conn, SIGMA_ERROR, "errorCode,sta_send_frame not "
8748 "yet supported");
8749 return 0;
8750#endif /* __linux__ */
8751}
8752
8753
8754static int cmd_sta_send_frame_tdls(struct sigma_dut *dut,
8755 struct sigma_conn *conn,
8756 struct sigma_cmd *cmd)
8757{
8758 const char *intf = get_param(cmd, "Interface");
8759 const char *sta, *val;
8760 unsigned char addr[ETH_ALEN];
8761 char buf[100];
8762
8763 sta = get_param(cmd, "peer");
8764 if (sta == NULL)
8765 sta = get_param(cmd, "station");
8766 if (sta == NULL) {
8767 send_resp(dut, conn, SIGMA_ERROR,
8768 "ErrorCode,Missing peer address");
8769 return 0;
8770 }
8771 if (hwaddr_aton(sta, addr) < 0) {
8772 send_resp(dut, conn, SIGMA_ERROR,
8773 "ErrorCode,Invalid peer address");
8774 return 0;
8775 }
8776
8777 val = get_param(cmd, "type");
8778 if (val == NULL)
8779 return -1;
8780
8781 if (strcasecmp(val, "DISCOVERY") == 0) {
8782 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", sta);
8783 if (wpa_command(intf, buf) < 0) {
8784 send_resp(dut, conn, SIGMA_ERROR,
8785 "ErrorCode,Failed to send TDLS discovery");
8786 return 0;
8787 }
8788 return 1;
8789 }
8790
8791 if (strcasecmp(val, "SETUP") == 0) {
8792 int status = 0, timeout = 0;
8793
8794 val = get_param(cmd, "Status");
8795 if (val)
8796 status = atoi(val);
8797
8798 val = get_param(cmd, "Timeout");
8799 if (val)
8800 timeout = atoi(val);
8801
8802 if (status != 0 && status != 37) {
8803 send_resp(dut, conn, SIGMA_ERROR,
8804 "ErrorCode,Unsupported status value");
8805 return 0;
8806 }
8807
8808 if (timeout != 0 && timeout != 301) {
8809 send_resp(dut, conn, SIGMA_ERROR,
8810 "ErrorCode,Unsupported timeout value");
8811 return 0;
8812 }
8813
8814 if (status && timeout) {
8815 send_resp(dut, conn, SIGMA_ERROR,
8816 "ErrorCode,Unsupported timeout+status "
8817 "combination");
8818 return 0;
8819 }
8820
8821 if (status == 37 &&
8822 wpa_command(intf, "SET tdls_testing 0x200")) {
8823 send_resp(dut, conn, SIGMA_ERROR,
8824 "ErrorCode,Failed to enable "
8825 "decline setup response test mode");
8826 return 0;
8827 }
8828
8829 if (timeout == 301) {
8830 int res;
8831 if (dut->no_tpk_expiration)
8832 res = wpa_command(intf,
8833 "SET tdls_testing 0x108");
8834 else
8835 res = wpa_command(intf,
8836 "SET tdls_testing 0x8");
8837 if (res) {
8838 send_resp(dut, conn, SIGMA_ERROR,
8839 "ErrorCode,Failed to set short TPK "
8840 "lifetime");
8841 return 0;
8842 }
8843 }
8844
8845 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", sta);
8846 if (wpa_command(intf, buf) < 0) {
8847 send_resp(dut, conn, SIGMA_ERROR,
8848 "ErrorCode,Failed to send TDLS setup");
8849 return 0;
8850 }
8851 return 1;
8852 }
8853
8854 if (strcasecmp(val, "TEARDOWN") == 0) {
8855 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", sta);
8856 if (wpa_command(intf, buf) < 0) {
8857 send_resp(dut, conn, SIGMA_ERROR,
8858 "ErrorCode,Failed to send TDLS teardown");
8859 return 0;
8860 }
8861 return 1;
8862 }
8863
8864 send_resp(dut, conn, SIGMA_ERROR,
8865 "ErrorCode,Unsupported TDLS frame");
8866 return 0;
8867}
8868
8869
8870static int sta_ap_known(const char *ifname, const char *bssid)
8871{
8872 char buf[4096];
8873
Jouni Malinendd32f192018-09-15 02:55:19 +03008874 snprintf(buf, sizeof(buf), "BSS MASK=1 %s", bssid);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008875 if (wpa_command_resp(ifname, buf, buf, sizeof(buf)) < 0)
8876 return 0;
8877 if (strncmp(buf, "id=", 3) != 0)
8878 return 0;
8879 return 1;
8880}
8881
8882
8883static int sta_scan_ap(struct sigma_dut *dut, const char *ifname,
8884 const char *bssid)
8885{
8886 int res;
8887 struct wpa_ctrl *ctrl;
8888 char buf[256];
8889
8890 if (sta_ap_known(ifname, bssid))
8891 return 0;
8892 sigma_dut_print(dut, DUT_MSG_DEBUG,
8893 "AP not in BSS table - start scan");
8894
8895 ctrl = open_wpa_mon(ifname);
8896 if (ctrl == NULL) {
8897 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
8898 "wpa_supplicant monitor connection");
8899 return -1;
8900 }
8901
8902 if (wpa_command(ifname, "SCAN") < 0) {
8903 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to start scan");
8904 wpa_ctrl_detach(ctrl);
8905 wpa_ctrl_close(ctrl);
8906 return -1;
8907 }
8908
8909 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
8910 buf, sizeof(buf));
8911
8912 wpa_ctrl_detach(ctrl);
8913 wpa_ctrl_close(ctrl);
8914
8915 if (res < 0) {
8916 sigma_dut_print(dut, DUT_MSG_INFO, "Scan did not complete");
8917 return -1;
8918 }
8919
8920 if (sta_ap_known(ifname, bssid))
8921 return 0;
8922 sigma_dut_print(dut, DUT_MSG_INFO, "AP not in BSS table");
8923 return -1;
8924}
8925
8926
8927static int cmd_sta_send_frame_hs2_neighadv(struct sigma_dut *dut,
8928 struct sigma_conn *conn,
8929 struct sigma_cmd *cmd,
8930 const char *intf)
8931{
8932 char buf[200];
8933
8934 snprintf(buf, sizeof(buf), "ndsend 2001:DB8::1 %s", intf);
8935 if (system(buf) != 0) {
8936 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Failed to run "
8937 "ndsend");
8938 return 0;
8939 }
8940
8941 return 1;
8942}
8943
8944
8945static int cmd_sta_send_frame_hs2_neighsolreq(struct sigma_dut *dut,
8946 struct sigma_conn *conn,
8947 struct sigma_cmd *cmd,
8948 const char *intf)
8949{
8950 char buf[200];
8951 const char *ip = get_param(cmd, "SenderIP");
8952
Peng Xu26b356d2017-10-04 17:58:16 -07008953 if (!ip)
8954 return 0;
8955
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008956 snprintf(buf, sizeof(buf), "ndisc6 -nm %s %s -r 4", ip, intf);
8957 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
8958 if (system(buf) == 0) {
8959 sigma_dut_print(dut, DUT_MSG_INFO,
8960 "Neighbor Solicitation got a response "
8961 "for %s@%s", ip, intf);
8962 }
8963
8964 return 1;
8965}
8966
8967
8968static int cmd_sta_send_frame_hs2_arpprobe(struct sigma_dut *dut,
8969 struct sigma_conn *conn,
8970 struct sigma_cmd *cmd,
8971 const char *ifname)
8972{
8973 char buf[200];
8974 const char *ip = get_param(cmd, "SenderIP");
8975
8976 if (ip == NULL) {
8977 send_resp(dut, conn, SIGMA_ERROR,
8978 "ErrorCode,Missing SenderIP parameter");
8979 return 0;
8980 }
8981 snprintf(buf, sizeof(buf), "arping -I %s -D %s -c 4", ifname, ip);
8982 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
8983 if (system(buf) != 0) {
8984 sigma_dut_print(dut, DUT_MSG_INFO, "arping DAD got a response "
8985 "for %s@%s", ip, ifname);
8986 }
8987
8988 return 1;
8989}
8990
8991
8992static int cmd_sta_send_frame_hs2_arpannounce(struct sigma_dut *dut,
8993 struct sigma_conn *conn,
8994 struct sigma_cmd *cmd,
8995 const char *ifname)
8996{
8997 char buf[200];
8998 char ip[16];
8999 int s;
Peng Xub3756882017-10-04 14:39:09 -07009000 struct ifreq ifr;
9001 struct sockaddr_in saddr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009002
9003 s = socket(PF_INET, SOCK_DGRAM, 0);
Peng Xub3756882017-10-04 14:39:09 -07009004 if (s < 0) {
9005 perror("socket");
9006 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009007 }
9008
Peng Xub3756882017-10-04 14:39:09 -07009009 memset(&ifr, 0, sizeof(ifr));
9010 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
9011 if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
9012 sigma_dut_print(dut, DUT_MSG_INFO,
9013 "Failed to get %s IP address: %s",
9014 ifname, strerror(errno));
9015 close(s);
9016 return -1;
9017 }
9018 close(s);
9019
9020 memcpy(&saddr, &ifr.ifr_addr, sizeof(struct sockaddr_in));
9021 strlcpy(ip, inet_ntoa(saddr.sin_addr), sizeof(ip));
9022
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009023 snprintf(buf, sizeof(buf), "arping -I %s -s %s %s -c 4", ifname, ip,
9024 ip);
9025 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
9026 if (system(buf) != 0) {
9027 }
9028
9029 return 1;
9030}
9031
9032
9033static int cmd_sta_send_frame_hs2_arpreply(struct sigma_dut *dut,
9034 struct sigma_conn *conn,
9035 struct sigma_cmd *cmd,
9036 const char *ifname)
9037{
9038 char buf[200], addr[20];
9039 char dst[ETH_ALEN], src[ETH_ALEN];
9040 short ethtype = htons(ETH_P_ARP);
9041 char *pos;
9042 int s, res;
9043 const char *val;
9044 struct sockaddr_in taddr;
9045
9046 val = get_param(cmd, "dest");
9047 if (val)
9048 hwaddr_aton(val, (unsigned char *) dst);
9049
9050 val = get_param(cmd, "DestIP");
9051 if (val)
9052 inet_aton(val, &taddr.sin_addr);
Peng Xu151c9e12017-10-04 14:39:09 -07009053 else
9054 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009055
9056 if (get_wpa_status(get_station_ifname(), "address", addr,
9057 sizeof(addr)) < 0)
9058 return -2;
9059 hwaddr_aton(addr, (unsigned char *) src);
9060
9061 pos = buf;
9062 *pos++ = 0x00;
9063 *pos++ = 0x01;
9064 *pos++ = 0x08;
9065 *pos++ = 0x00;
9066 *pos++ = 0x06;
9067 *pos++ = 0x04;
9068 *pos++ = 0x00;
9069 *pos++ = 0x02;
9070 memcpy(pos, src, ETH_ALEN);
9071 pos += ETH_ALEN;
9072 memcpy(pos, &taddr.sin_addr, 4);
9073 pos += 4;
9074 memcpy(pos, dst, ETH_ALEN);
9075 pos += ETH_ALEN;
9076 memcpy(pos, &taddr.sin_addr, 4);
9077 pos += 4;
9078
9079 s = open_monitor(get_station_ifname());
9080 if (s < 0) {
9081 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
9082 "monitor socket");
9083 return 0;
9084 }
9085
9086 res = inject_eth_frame(s, buf, pos - buf, ethtype, dst, src);
9087 if (res < 0) {
9088 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
9089 "inject frame");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05309090 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009091 return 0;
9092 }
9093
9094 close(s);
9095
9096 return 1;
9097}
9098
9099
9100static int cmd_sta_send_frame_hs2_dls_req(struct sigma_dut *dut,
9101 struct sigma_conn *conn,
9102 struct sigma_cmd *cmd,
9103 const char *intf, const char *dest)
9104{
9105 char buf[100];
9106
9107 if (if_nametoindex("sigmadut") == 0) {
9108 snprintf(buf, sizeof(buf),
9109 "iw dev %s interface add sigmadut type monitor",
9110 get_station_ifname());
9111 if (system(buf) != 0 ||
9112 if_nametoindex("sigmadut") == 0) {
9113 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
9114 "monitor interface with '%s'", buf);
9115 return -2;
9116 }
9117 }
9118
9119 if (system("ifconfig sigmadut up") != 0) {
9120 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
9121 "monitor interface up");
9122 return -2;
9123 }
9124
9125 return sta_inject_frame(dut, conn, DLS_REQ, UNPROTECTED, dest);
9126}
9127
9128
9129static int cmd_sta_send_frame_hs2(struct sigma_dut *dut,
9130 struct sigma_conn *conn,
9131 struct sigma_cmd *cmd)
9132{
9133 const char *intf = get_param(cmd, "Interface");
9134 const char *dest = get_param(cmd, "Dest");
9135 const char *type = get_param(cmd, "FrameName");
9136 const char *val;
9137 char buf[200], *pos, *end;
9138 int count, count2;
9139
9140 if (type == NULL)
9141 type = get_param(cmd, "Type");
9142
9143 if (intf == NULL || dest == NULL || type == NULL)
9144 return -1;
9145
9146 if (strcasecmp(type, "NeighAdv") == 0)
9147 return cmd_sta_send_frame_hs2_neighadv(dut, conn, cmd, intf);
9148
9149 if (strcasecmp(type, "NeighSolicitReq") == 0)
9150 return cmd_sta_send_frame_hs2_neighsolreq(dut, conn, cmd, intf);
9151
9152 if (strcasecmp(type, "ARPProbe") == 0)
9153 return cmd_sta_send_frame_hs2_arpprobe(dut, conn, cmd, intf);
9154
9155 if (strcasecmp(type, "ARPAnnounce") == 0)
9156 return cmd_sta_send_frame_hs2_arpannounce(dut, conn, cmd, intf);
9157
9158 if (strcasecmp(type, "ARPReply") == 0)
9159 return cmd_sta_send_frame_hs2_arpreply(dut, conn, cmd, intf);
9160
9161 if (strcasecmp(type, "DLS-request") == 0 ||
9162 strcasecmp(type, "DLSrequest") == 0)
9163 return cmd_sta_send_frame_hs2_dls_req(dut, conn, cmd, intf,
9164 dest);
9165
9166 if (strcasecmp(type, "ANQPQuery") != 0 &&
9167 strcasecmp(type, "Query") != 0) {
9168 send_resp(dut, conn, SIGMA_ERROR,
9169 "ErrorCode,Unsupported HS 2.0 send frame type");
9170 return 0;
9171 }
9172
9173 if (sta_scan_ap(dut, intf, dest) < 0) {
9174 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not find "
9175 "the requested AP");
9176 return 0;
9177 }
9178
9179 pos = buf;
9180 end = buf + sizeof(buf);
9181 count = 0;
9182 pos += snprintf(pos, end - pos, "ANQP_GET %s ", dest);
9183
9184 val = get_param(cmd, "ANQP_CAP_LIST");
9185 if (val && atoi(val)) {
9186 pos += snprintf(pos, end - pos, "%s257", count > 0 ? "," : "");
9187 count++;
9188 }
9189
9190 val = get_param(cmd, "VENUE_NAME");
9191 if (val && atoi(val)) {
9192 pos += snprintf(pos, end - pos, "%s258", count > 0 ? "," : "");
9193 count++;
9194 }
9195
9196 val = get_param(cmd, "NETWORK_AUTH_TYPE");
9197 if (val && atoi(val)) {
9198 pos += snprintf(pos, end - pos, "%s260", count > 0 ? "," : "");
9199 count++;
9200 }
9201
9202 val = get_param(cmd, "ROAMING_CONS");
9203 if (val && atoi(val)) {
9204 pos += snprintf(pos, end - pos, "%s261", count > 0 ? "," : "");
9205 count++;
9206 }
9207
9208 val = get_param(cmd, "IP_ADDR_TYPE_AVAILABILITY");
9209 if (val && atoi(val)) {
9210 pos += snprintf(pos, end - pos, "%s262", count > 0 ? "," : "");
9211 count++;
9212 }
9213
9214 val = get_param(cmd, "NAI_REALM_LIST");
9215 if (val && atoi(val)) {
9216 pos += snprintf(pos, end - pos, "%s263", count > 0 ? "," : "");
9217 count++;
9218 }
9219
9220 val = get_param(cmd, "3GPP_INFO");
9221 if (val && atoi(val)) {
9222 pos += snprintf(pos, end - pos, "%s264", count > 0 ? "," : "");
9223 count++;
9224 }
9225
9226 val = get_param(cmd, "DOMAIN_LIST");
9227 if (val && atoi(val)) {
9228 pos += snprintf(pos, end - pos, "%s268", count > 0 ? "," : "");
9229 count++;
9230 }
9231
Jouni Malinen34cf9532018-04-29 19:26:33 +03009232 val = get_param(cmd, "Venue_URL");
9233 if (val && atoi(val)) {
9234 pos += snprintf(pos, end - pos, "%s277", count > 0 ? "," : "");
9235 count++;
9236 }
9237
Jouni Malinend3bca5d2018-04-29 17:25:23 +03009238 val = get_param(cmd, "Advice_Of_Charge");
9239 if (val && atoi(val)) {
9240 pos += snprintf(pos, end - pos, "%s278", count > 0 ? "," : "");
9241 count++;
9242 }
9243
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009244 if (count && wpa_command(intf, buf)) {
9245 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,ANQP_GET failed");
9246 return 0;
9247 }
9248
9249 pos = buf;
9250 end = buf + sizeof(buf);
9251 count2 = 0;
9252 pos += snprintf(pos, end - pos, "HS20_ANQP_GET %s ", dest);
9253
9254 val = get_param(cmd, "HS_CAP_LIST");
9255 if (val && atoi(val)) {
9256 pos += snprintf(pos, end - pos, "%s2", count2 > 0 ? "," : "");
9257 count2++;
9258 }
9259
9260 val = get_param(cmd, "OPER_NAME");
9261 if (val && atoi(val)) {
9262 pos += snprintf(pos, end - pos, "%s3", count2 > 0 ? "," : "");
9263 count2++;
9264 }
9265
9266 val = get_param(cmd, "WAN_METRICS");
9267 if (!val)
9268 val = get_param(cmd, "WAN_MAT");
9269 if (!val)
9270 val = get_param(cmd, "WAN_MET");
9271 if (val && atoi(val)) {
9272 pos += snprintf(pos, end - pos, "%s4", count2 > 0 ? "," : "");
9273 count2++;
9274 }
9275
9276 val = get_param(cmd, "CONNECTION_CAPABILITY");
9277 if (val && atoi(val)) {
9278 pos += snprintf(pos, end - pos, "%s5", count2 > 0 ? "," : "");
9279 count2++;
9280 }
9281
9282 val = get_param(cmd, "OP_CLASS");
9283 if (val && atoi(val)) {
9284 pos += snprintf(pos, end - pos, "%s7", count2 > 0 ? "," : "");
9285 count2++;
9286 }
9287
9288 val = get_param(cmd, "OSU_PROVIDER_LIST");
9289 if (val && atoi(val)) {
9290 pos += snprintf(pos, end - pos, "%s8", count2 > 0 ? "," : "");
9291 count2++;
9292 }
9293
Jouni Malinenf67afec2018-04-29 19:24:58 +03009294 val = get_param(cmd, "OPER_ICON_METADATA");
9295 if (!val)
9296 val = get_param(cmd, "OPERATOR_ICON_METADATA");
9297 if (val && atoi(val)) {
9298 pos += snprintf(pos, end - pos, "%s12", count2 > 0 ? "," : "");
9299 count2++;
9300 }
9301
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009302 if (count && count2) {
9303 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before sending out "
9304 "second query");
9305 sleep(1);
9306 }
9307
9308 if (count2 && wpa_command(intf, buf)) {
9309 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,HS20_ANQP_GET "
9310 "failed");
9311 return 0;
9312 }
9313
9314 val = get_param(cmd, "NAI_HOME_REALM_LIST");
9315 if (val) {
9316 if (count || count2) {
9317 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
9318 "sending out second query");
9319 sleep(1);
9320 }
9321
9322 if (strcmp(val, "1") == 0)
9323 val = "mail.example.com";
9324 snprintf(buf, end - pos,
9325 "HS20_GET_NAI_HOME_REALM_LIST %s realm=%s",
9326 dest, val);
9327 if (wpa_command(intf, buf)) {
9328 send_resp(dut, conn, SIGMA_ERROR,
9329 "ErrorCode,HS20_GET_NAI_HOME_REALM_LIST "
9330 "failed");
9331 return 0;
9332 }
9333 }
9334
9335 val = get_param(cmd, "ICON_REQUEST");
9336 if (val) {
9337 if (count || count2) {
9338 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
9339 "sending out second query");
9340 sleep(1);
9341 }
9342
9343 snprintf(buf, end - pos,
9344 "HS20_ICON_REQUEST %s %s", dest, val);
9345 if (wpa_command(intf, buf)) {
9346 send_resp(dut, conn, SIGMA_ERROR,
9347 "ErrorCode,HS20_ICON_REQUEST failed");
9348 return 0;
9349 }
9350 }
9351
9352 return 1;
9353}
9354
9355
9356static int ath_sta_send_frame_vht(struct sigma_dut *dut,
9357 struct sigma_conn *conn,
9358 struct sigma_cmd *cmd)
9359{
9360 const char *val;
9361 char *ifname;
9362 char buf[100];
9363 int chwidth, nss;
9364
9365 val = get_param(cmd, "framename");
9366 if (!val)
9367 return -1;
9368 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
9369
9370 /* Command sequence to generate Op mode notification */
9371 if (val && strcasecmp(val, "Op_md_notif_frm") == 0) {
9372 ifname = get_station_ifname();
9373
9374 /* Disable STBC */
9375 snprintf(buf, sizeof(buf),
9376 "iwpriv %s tx_stbc 0", ifname);
9377 if (system(buf) != 0) {
9378 sigma_dut_print(dut, DUT_MSG_ERROR,
9379 "iwpriv tx_stbc 0 failed!");
9380 }
9381
9382 /* Extract Channel width */
9383 val = get_param(cmd, "Channel_width");
9384 if (val) {
9385 switch (atoi(val)) {
9386 case 20:
9387 chwidth = 0;
9388 break;
9389 case 40:
9390 chwidth = 1;
9391 break;
9392 case 80:
9393 chwidth = 2;
9394 break;
9395 case 160:
9396 chwidth = 3;
9397 break;
9398 default:
9399 chwidth = 2;
9400 break;
9401 }
9402
9403 snprintf(buf, sizeof(buf), "iwpriv %s chwidth %d",
9404 ifname, chwidth);
9405 if (system(buf) != 0) {
9406 sigma_dut_print(dut, DUT_MSG_ERROR,
9407 "iwpriv chwidth failed!");
9408 }
9409 }
9410
9411 /* Extract NSS */
9412 val = get_param(cmd, "NSS");
9413 if (val) {
9414 switch (atoi(val)) {
9415 case 1:
9416 nss = 1;
9417 break;
9418 case 2:
9419 nss = 3;
9420 break;
9421 case 3:
9422 nss = 7;
9423 break;
9424 default:
9425 /* We do not support NSS > 3 */
9426 nss = 3;
9427 break;
9428 }
9429 snprintf(buf, sizeof(buf),
9430 "iwpriv %s rxchainmask %d", ifname, nss);
9431 if (system(buf) != 0) {
9432 sigma_dut_print(dut, DUT_MSG_ERROR,
9433 "iwpriv rxchainmask failed!");
9434 }
9435 }
9436
9437 /* Opmode notify */
9438 snprintf(buf, sizeof(buf), "iwpriv %s opmode_notify 1", ifname);
9439 if (system(buf) != 0) {
9440 sigma_dut_print(dut, DUT_MSG_ERROR,
9441 "iwpriv opmode_notify failed!");
9442 } else {
9443 sigma_dut_print(dut, DUT_MSG_INFO,
9444 "Sent out the notify frame!");
9445 }
9446 }
9447
9448 return 1;
9449}
9450
9451
9452static int cmd_sta_send_frame_vht(struct sigma_dut *dut,
9453 struct sigma_conn *conn,
9454 struct sigma_cmd *cmd)
9455{
9456 switch (get_driver_type()) {
9457 case DRIVER_ATHEROS:
9458 return ath_sta_send_frame_vht(dut, conn, cmd);
9459 default:
9460 send_resp(dut, conn, SIGMA_ERROR,
9461 "errorCode,Unsupported sta_set_frame(VHT) with the current driver");
9462 return 0;
9463 }
9464}
9465
9466
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07009467static int wcn_sta_send_frame_he(struct sigma_dut *dut, struct sigma_conn *conn,
9468 struct sigma_cmd *cmd)
9469{
9470 const char *val;
9471 const char *intf = get_param(cmd, "Interface");
9472
9473 val = get_param(cmd, "framename");
9474 if (!val)
9475 return -1;
9476 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
9477
9478 /* Command sequence to generate Op mode notification */
9479 if (val && strcasecmp(val, "action") == 0) {
9480 val = get_param(cmd, "PPDUTxType");
9481 if (val && strcasecmp(val, "TB") == 0) {
9482 if (sta_set_action_tx_in_he_tb_ppdu(dut, intf, 1)) {
9483 sigma_dut_print(dut, DUT_MSG_ERROR,
9484 "failed to send TB PPDU Tx cfg");
9485 send_resp(dut, conn, SIGMA_ERROR,
9486 "ErrorCode,set TB PPDU Tx cfg failed");
9487 return 0;
9488 }
9489 return 1;
9490 }
9491
9492 sigma_dut_print(dut, DUT_MSG_ERROR,
9493 "Action Tx type is not defined");
9494 }
9495
9496 return 1;
9497}
9498
9499
9500static int cmd_sta_send_frame_he(struct sigma_dut *dut,
9501 struct sigma_conn *conn,
9502 struct sigma_cmd *cmd)
9503{
9504 switch (get_driver_type()) {
9505 case DRIVER_WCN:
9506 return wcn_sta_send_frame_he(dut, conn, cmd);
9507 default:
9508 send_resp(dut, conn, SIGMA_ERROR,
9509 "errorCode,Unsupported sta_set_frame(HE) with the current driver");
9510 return 0;
9511 }
9512}
9513
9514
Lior David0fe101e2017-03-09 16:09:50 +02009515#ifdef __linux__
9516int wil6210_send_frame_60g(struct sigma_dut *dut, struct sigma_conn *conn,
9517 struct sigma_cmd *cmd)
9518{
9519 const char *frame_name = get_param(cmd, "framename");
9520 const char *mac = get_param(cmd, "dest_mac");
9521
9522 if (!frame_name || !mac) {
9523 sigma_dut_print(dut, DUT_MSG_ERROR,
9524 "framename and dest_mac must be provided");
9525 return -1;
9526 }
9527
9528 if (strcasecmp(frame_name, "brp") == 0) {
9529 const char *l_rx = get_param(cmd, "L-RX");
9530 int l_rx_i;
9531
9532 if (!l_rx) {
9533 sigma_dut_print(dut, DUT_MSG_ERROR,
9534 "L-RX must be provided");
9535 return -1;
9536 }
9537 l_rx_i = atoi(l_rx);
9538
9539 sigma_dut_print(dut, DUT_MSG_INFO,
9540 "dev_send_frame: BRP-RX, dest_mac %s, L-RX %s",
9541 mac, l_rx);
9542 if (l_rx_i != 16) {
9543 sigma_dut_print(dut, DUT_MSG_ERROR,
9544 "unsupported L-RX: %s", l_rx);
9545 return -1;
9546 }
9547
9548 if (wil6210_send_brp_rx(dut, mac, l_rx_i))
9549 return -1;
9550 } else if (strcasecmp(frame_name, "ssw") == 0) {
9551 sigma_dut_print(dut, DUT_MSG_INFO,
9552 "dev_send_frame: SLS, dest_mac %s", mac);
9553 if (wil6210_send_sls(dut, mac))
9554 return -1;
9555 } else {
9556 sigma_dut_print(dut, DUT_MSG_ERROR,
9557 "unsupported frame type: %s", frame_name);
9558 return -1;
9559 }
9560
9561 return 1;
9562}
9563#endif /* __linux__ */
9564
9565
9566static int cmd_sta_send_frame_60g(struct sigma_dut *dut,
9567 struct sigma_conn *conn,
9568 struct sigma_cmd *cmd)
9569{
9570 switch (get_driver_type()) {
9571#ifdef __linux__
9572 case DRIVER_WIL6210:
9573 return wil6210_send_frame_60g(dut, conn, cmd);
9574#endif /* __linux__ */
9575 default:
9576 send_resp(dut, conn, SIGMA_ERROR,
9577 "errorCode,Unsupported sta_set_frame(60G) with the current driver");
9578 return 0;
9579 }
9580}
9581
9582
Ashwini Patildb59b3c2017-04-13 15:19:23 +05309583static int mbo_send_anqp_query(struct sigma_dut *dut, struct sigma_conn *conn,
9584 const char *intf, struct sigma_cmd *cmd)
9585{
9586 const char *val, *addr;
9587 char buf[100];
9588
9589 addr = get_param(cmd, "DestMac");
9590 if (!addr) {
9591 send_resp(dut, conn, SIGMA_INVALID,
9592 "ErrorCode,AP MAC address is missing");
9593 return 0;
9594 }
9595
9596 val = get_param(cmd, "ANQPQuery_ID");
9597 if (!val) {
9598 send_resp(dut, conn, SIGMA_INVALID,
9599 "ErrorCode,Missing ANQPQuery_ID");
9600 return 0;
9601 }
9602
9603 if (strcasecmp(val, "NeighborReportReq") == 0) {
9604 snprintf(buf, sizeof(buf), "ANQP_GET %s 272", addr);
9605 } else if (strcasecmp(val, "QueryListWithCellPref") == 0) {
9606 snprintf(buf, sizeof(buf), "ANQP_GET %s 272,mbo:2", addr);
9607 } else {
9608 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid ANQPQuery_ID: %s",
9609 val);
9610 send_resp(dut, conn, SIGMA_INVALID,
9611 "ErrorCode,Invalid ANQPQuery_ID");
9612 return 0;
9613 }
9614
Ashwini Patild174f2c2017-04-13 16:49:46 +05309615 /* Set gas_address3 field to IEEE 802.11-2012 standard compliant form
9616 * (Address3 = Wildcard BSSID when sent to not-associated AP;
9617 * if associated, AP BSSID).
9618 */
9619 if (wpa_command(intf, "SET gas_address3 1") < 0) {
9620 send_resp(dut, conn, SIGMA_ERROR,
9621 "ErrorCode,Failed to set gas_address3");
9622 return 0;
9623 }
9624
Ashwini Patildb59b3c2017-04-13 15:19:23 +05309625 if (wpa_command(intf, buf) < 0) {
9626 send_resp(dut, conn, SIGMA_ERROR,
9627 "ErrorCode,Failed to send ANQP query");
9628 return 0;
9629 }
9630
9631 return 1;
9632}
9633
9634
9635static int mbo_cmd_sta_send_frame(struct sigma_dut *dut,
9636 struct sigma_conn *conn,
9637 const char *intf,
9638 struct sigma_cmd *cmd)
9639{
9640 const char *val = get_param(cmd, "FrameName");
9641
9642 if (val && strcasecmp(val, "ANQPQuery") == 0)
9643 return mbo_send_anqp_query(dut, conn, intf, cmd);
9644
9645 return 2;
9646}
9647
9648
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009649int cmd_sta_send_frame(struct sigma_dut *dut, struct sigma_conn *conn,
9650 struct sigma_cmd *cmd)
9651{
9652 const char *intf = get_param(cmd, "Interface");
9653 const char *val;
9654 enum send_frame_type frame;
9655 enum send_frame_protection protected;
9656 char buf[100];
9657 unsigned char addr[ETH_ALEN];
9658 int res;
9659
9660 val = get_param(cmd, "program");
9661 if (val == NULL)
9662 val = get_param(cmd, "frame");
9663 if (val && strcasecmp(val, "TDLS") == 0)
9664 return cmd_sta_send_frame_tdls(dut, conn, cmd);
9665 if (val && (strcasecmp(val, "HS2") == 0 ||
Jouni Malinen1f6ae642018-06-07 23:56:13 +03009666 strcasecmp(val, "HS2-R2") == 0 ||
9667 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009668 return cmd_sta_send_frame_hs2(dut, conn, cmd);
9669 if (val && strcasecmp(val, "VHT") == 0)
9670 return cmd_sta_send_frame_vht(dut, conn, cmd);
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07009671 if (val && strcasecmp(val, "HE") == 0)
9672 return cmd_sta_send_frame_he(dut, conn, cmd);
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07009673 if (val && strcasecmp(val, "LOC") == 0)
9674 return loc_cmd_sta_send_frame(dut, conn, cmd);
Lior David0fe101e2017-03-09 16:09:50 +02009675 if (val && strcasecmp(val, "60GHz") == 0)
9676 return cmd_sta_send_frame_60g(dut, conn, cmd);
Ashwini Patildb59b3c2017-04-13 15:19:23 +05309677 if (val && strcasecmp(val, "MBO") == 0) {
9678 res = mbo_cmd_sta_send_frame(dut, conn, intf, cmd);
9679 if (res != 2)
9680 return res;
9681 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009682
9683 val = get_param(cmd, "TD_DISC");
9684 if (val) {
9685 if (hwaddr_aton(val, addr) < 0)
9686 return -1;
9687 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", val);
9688 if (wpa_command(intf, buf) < 0) {
9689 send_resp(dut, conn, SIGMA_ERROR,
9690 "ErrorCode,Failed to send TDLS discovery");
9691 return 0;
9692 }
9693 return 1;
9694 }
9695
9696 val = get_param(cmd, "TD_Setup");
9697 if (val) {
9698 if (hwaddr_aton(val, addr) < 0)
9699 return -1;
9700 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", val);
9701 if (wpa_command(intf, buf) < 0) {
9702 send_resp(dut, conn, SIGMA_ERROR,
9703 "ErrorCode,Failed to start TDLS setup");
9704 return 0;
9705 }
9706 return 1;
9707 }
9708
9709 val = get_param(cmd, "TD_TearDown");
9710 if (val) {
9711 if (hwaddr_aton(val, addr) < 0)
9712 return -1;
9713 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", val);
9714 if (wpa_command(intf, buf) < 0) {
9715 send_resp(dut, conn, SIGMA_ERROR,
9716 "ErrorCode,Failed to tear down TDLS link");
9717 return 0;
9718 }
9719 return 1;
9720 }
9721
9722 val = get_param(cmd, "TD_ChannelSwitch");
9723 if (val) {
9724 /* TODO */
9725 send_resp(dut, conn, SIGMA_ERROR,
9726 "ErrorCode,TD_ChannelSwitch not yet supported");
9727 return 0;
9728 }
9729
9730 val = get_param(cmd, "TD_NF");
9731 if (val) {
9732 /* TODO */
9733 send_resp(dut, conn, SIGMA_ERROR,
9734 "ErrorCode,TD_NF not yet supported");
9735 return 0;
9736 }
9737
9738 val = get_param(cmd, "PMFFrameType");
9739 if (val == NULL)
9740 val = get_param(cmd, "FrameName");
9741 if (val == NULL)
9742 val = get_param(cmd, "Type");
9743 if (val == NULL)
9744 return -1;
9745 if (strcasecmp(val, "disassoc") == 0)
9746 frame = DISASSOC;
9747 else if (strcasecmp(val, "deauth") == 0)
9748 frame = DEAUTH;
9749 else if (strcasecmp(val, "saquery") == 0)
9750 frame = SAQUERY;
9751 else if (strcasecmp(val, "auth") == 0)
9752 frame = AUTH;
9753 else if (strcasecmp(val, "assocreq") == 0)
9754 frame = ASSOCREQ;
9755 else if (strcasecmp(val, "reassocreq") == 0)
9756 frame = REASSOCREQ;
9757 else if (strcasecmp(val, "neigreq") == 0) {
9758 sigma_dut_print(dut, DUT_MSG_INFO, "Got neighbor request");
9759
9760 val = get_param(cmd, "ssid");
9761 if (val == NULL)
9762 return -1;
9763
9764 res = send_neighbor_request(dut, intf, val);
9765 if (res) {
9766 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
9767 "Failed to send neighbor report request");
9768 return 0;
9769 }
9770
9771 return 1;
Ashwini Patil5acd7382017-04-13 15:55:04 +05309772 } else if (strcasecmp(val, "transmgmtquery") == 0 ||
9773 strcasecmp(val, "BTMQuery") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009774 sigma_dut_print(dut, DUT_MSG_DEBUG,
9775 "Got Transition Management Query");
9776
Ashwini Patil5acd7382017-04-13 15:55:04 +05309777 res = send_trans_mgmt_query(dut, intf, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009778 if (res) {
9779 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
9780 "Failed to send Transition Management Query");
9781 return 0;
9782 }
9783
9784 return 1;
9785 } else {
9786 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
9787 "PMFFrameType");
9788 return 0;
9789 }
9790
9791 val = get_param(cmd, "PMFProtected");
9792 if (val == NULL)
9793 val = get_param(cmd, "Protected");
9794 if (val == NULL)
9795 return -1;
9796 if (strcasecmp(val, "Correct-key") == 0 ||
9797 strcasecmp(val, "CorrectKey") == 0)
9798 protected = CORRECT_KEY;
9799 else if (strcasecmp(val, "IncorrectKey") == 0)
9800 protected = INCORRECT_KEY;
9801 else if (strcasecmp(val, "Unprotected") == 0)
9802 protected = UNPROTECTED;
9803 else {
9804 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
9805 "PMFProtected");
9806 return 0;
9807 }
9808
9809 if (protected != UNPROTECTED &&
9810 (frame == AUTH || frame == ASSOCREQ || frame == REASSOCREQ)) {
9811 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Impossible "
9812 "PMFProtected for auth/assocreq/reassocreq");
9813 return 0;
9814 }
9815
9816 if (if_nametoindex("sigmadut") == 0) {
9817 snprintf(buf, sizeof(buf),
9818 "iw dev %s interface add sigmadut type monitor",
9819 get_station_ifname());
9820 if (system(buf) != 0 ||
9821 if_nametoindex("sigmadut") == 0) {
9822 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
9823 "monitor interface with '%s'", buf);
9824 return -2;
9825 }
9826 }
9827
9828 if (system("ifconfig sigmadut up") != 0) {
9829 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
9830 "monitor interface up");
9831 return -2;
9832 }
9833
9834 return sta_inject_frame(dut, conn, frame, protected, NULL);
9835}
9836
9837
9838static int cmd_sta_set_parameter_hs2(struct sigma_dut *dut,
9839 struct sigma_conn *conn,
9840 struct sigma_cmd *cmd,
9841 const char *ifname)
9842{
9843 char buf[200];
9844 const char *val;
9845
9846 val = get_param(cmd, "ClearARP");
9847 if (val && atoi(val) == 1) {
9848 snprintf(buf, sizeof(buf), "ip neigh flush dev %s", ifname);
9849 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
9850 if (system(buf) != 0) {
9851 send_resp(dut, conn, SIGMA_ERROR,
9852 "errorCode,Failed to clear ARP cache");
9853 return 0;
9854 }
9855 }
9856
9857 return 1;
9858}
9859
9860
9861int cmd_sta_set_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
9862 struct sigma_cmd *cmd)
9863{
9864 const char *intf = get_param(cmd, "Interface");
9865 const char *val;
9866
9867 if (intf == NULL)
9868 return -1;
9869
9870 val = get_param(cmd, "program");
9871 if (val && (strcasecmp(val, "HS2") == 0 ||
Jouni Malinen1f6ae642018-06-07 23:56:13 +03009872 strcasecmp(val, "HS2-R2") == 0 ||
9873 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009874 return cmd_sta_set_parameter_hs2(dut, conn, cmd, intf);
9875
9876 return -1;
9877}
9878
9879
9880static int cmd_sta_set_macaddr(struct sigma_dut *dut, struct sigma_conn *conn,
9881 struct sigma_cmd *cmd)
9882{
9883 const char *intf = get_param(cmd, "Interface");
9884 const char *mac = get_param(cmd, "MAC");
9885
9886 if (intf == NULL || mac == NULL)
9887 return -1;
9888
9889 sigma_dut_print(dut, DUT_MSG_INFO, "Change local MAC address for "
9890 "interface %s to %s", intf, mac);
9891
9892 if (dut->set_macaddr) {
9893 char buf[128];
9894 int res;
9895 if (strcasecmp(mac, "default") == 0) {
9896 res = snprintf(buf, sizeof(buf), "%s",
9897 dut->set_macaddr);
9898 dut->tmp_mac_addr = 0;
9899 } else {
9900 res = snprintf(buf, sizeof(buf), "%s %s",
9901 dut->set_macaddr, mac);
9902 dut->tmp_mac_addr = 1;
9903 }
9904 if (res < 0 || res >= (int) sizeof(buf))
9905 return -1;
9906 if (system(buf) != 0) {
9907 send_resp(dut, conn, SIGMA_ERROR,
9908 "errorCode,Failed to set MAC "
9909 "address");
9910 return 0;
9911 }
9912 return 1;
9913 }
9914
9915 if (strcasecmp(mac, "default") == 0)
9916 return 1;
9917
9918 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
9919 "command");
9920 return 0;
9921}
9922
9923
9924static int iwpriv_tdlsoffchnmode(struct sigma_dut *dut,
9925 struct sigma_conn *conn, const char *intf,
9926 int val)
9927{
9928 char buf[200];
9929 int res;
9930
9931 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchnmode %d",
9932 intf, val);
9933 if (res < 0 || res >= (int) sizeof(buf))
9934 return -1;
9935 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
9936 if (system(buf) != 0) {
9937 send_resp(dut, conn, SIGMA_ERROR,
9938 "errorCode,Failed to configure offchannel mode");
9939 return 0;
9940 }
9941
9942 return 1;
9943}
9944
9945
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009946static int off_chan_val(enum sec_ch_offset off)
9947{
9948 switch (off) {
9949 case SEC_CH_NO:
9950 return 0;
9951 case SEC_CH_40ABOVE:
9952 return 40;
9953 case SEC_CH_40BELOW:
9954 return -40;
9955 }
9956
9957 return 0;
9958}
9959
9960
9961static int iwpriv_set_offchan(struct sigma_dut *dut, struct sigma_conn *conn,
9962 const char *intf, int off_ch_num,
9963 enum sec_ch_offset sec)
9964{
9965 char buf[200];
9966 int res;
9967
9968 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchan %d",
9969 intf, off_ch_num);
9970 if (res < 0 || res >= (int) sizeof(buf))
9971 return -1;
9972 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
9973 if (system(buf) != 0) {
9974 send_resp(dut, conn, SIGMA_ERROR,
9975 "errorCode,Failed to set offchan");
9976 return 0;
9977 }
9978
9979 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsecchnoffst %d",
9980 intf, off_chan_val(sec));
9981 if (res < 0 || res >= (int) sizeof(buf))
9982 return -1;
9983 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
9984 if (system(buf) != 0) {
9985 send_resp(dut, conn, SIGMA_ERROR,
9986 "errorCode,Failed to set sec chan offset");
9987 return 0;
9988 }
9989
9990 return 1;
9991}
9992
9993
9994static int tdls_set_offchannel_offset(struct sigma_dut *dut,
9995 struct sigma_conn *conn,
9996 const char *intf, int off_ch_num,
9997 enum sec_ch_offset sec)
9998{
9999 char buf[200];
10000 int res;
10001
10002 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNEL %d",
10003 off_ch_num);
10004 if (res < 0 || res >= (int) sizeof(buf))
10005 return -1;
10006 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10007
10008 if (wpa_command(intf, buf) < 0) {
10009 send_resp(dut, conn, SIGMA_ERROR,
10010 "ErrorCode,Failed to set offchan");
10011 return 0;
10012 }
10013 res = snprintf(buf, sizeof(buf), "DRIVER TDLSSECONDARYCHANNELOFFSET %d",
10014 off_chan_val(sec));
10015 if (res < 0 || res >= (int) sizeof(buf))
10016 return -1;
10017
10018 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10019
10020 if (wpa_command(intf, buf) < 0) {
10021 send_resp(dut, conn, SIGMA_ERROR,
10022 "ErrorCode,Failed to set sec chan offset");
10023 return 0;
10024 }
10025
10026 return 1;
10027}
10028
10029
10030static int tdls_set_offchannel_mode(struct sigma_dut *dut,
10031 struct sigma_conn *conn,
10032 const char *intf, int val)
10033{
10034 char buf[200];
10035 int res;
10036
10037 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNELMODE %d",
10038 val);
10039 if (res < 0 || res >= (int) sizeof(buf))
10040 return -1;
10041 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10042
10043 if (wpa_command(intf, buf) < 0) {
10044 send_resp(dut, conn, SIGMA_ERROR,
10045 "ErrorCode,Failed to configure offchannel mode");
10046 return 0;
10047 }
10048
10049 return 1;
10050}
10051
10052
10053static int cmd_sta_set_rfeature_tdls(const char *intf, struct sigma_dut *dut,
10054 struct sigma_conn *conn,
10055 struct sigma_cmd *cmd)
10056{
10057 const char *val;
10058 enum {
10059 CHSM_NOT_SET,
10060 CHSM_ENABLE,
10061 CHSM_DISABLE,
10062 CHSM_REJREQ,
10063 CHSM_UNSOLRESP
10064 } chsm = CHSM_NOT_SET;
10065 int off_ch_num = -1;
10066 enum sec_ch_offset sec_ch = SEC_CH_NO;
10067 int res;
10068
10069 val = get_param(cmd, "Uapsd");
10070 if (val) {
10071 char buf[100];
10072 if (strcasecmp(val, "Enable") == 0)
10073 snprintf(buf, sizeof(buf), "SET ps 99");
10074 else if (strcasecmp(val, "Disable") == 0)
10075 snprintf(buf, sizeof(buf), "SET ps 98");
10076 else {
10077 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
10078 "Unsupported uapsd parameter value");
10079 return 0;
10080 }
10081 if (wpa_command(intf, buf)) {
10082 send_resp(dut, conn, SIGMA_ERROR,
10083 "ErrorCode,Failed to change U-APSD "
10084 "powersave mode");
10085 return 0;
10086 }
10087 }
10088
10089 val = get_param(cmd, "TPKTIMER");
10090 if (val && strcasecmp(val, "DISABLE") == 0) {
10091 if (wpa_command(intf, "SET tdls_testing 0x100")) {
10092 send_resp(dut, conn, SIGMA_ERROR,
10093 "ErrorCode,Failed to enable no TPK "
10094 "expiration test mode");
10095 return 0;
10096 }
10097 dut->no_tpk_expiration = 1;
10098 }
10099
10100 val = get_param(cmd, "ChSwitchMode");
10101 if (val) {
10102 if (strcasecmp(val, "Enable") == 0 ||
10103 strcasecmp(val, "Initiate") == 0)
10104 chsm = CHSM_ENABLE;
10105 else if (strcasecmp(val, "Disable") == 0 ||
10106 strcasecmp(val, "passive") == 0)
10107 chsm = CHSM_DISABLE;
10108 else if (strcasecmp(val, "RejReq") == 0)
10109 chsm = CHSM_REJREQ;
10110 else if (strcasecmp(val, "UnSolResp") == 0)
10111 chsm = CHSM_UNSOLRESP;
10112 else {
10113 send_resp(dut, conn, SIGMA_ERROR,
10114 "ErrorCode,Unknown ChSwitchMode value");
10115 return 0;
10116 }
10117 }
10118
10119 val = get_param(cmd, "OffChNum");
10120 if (val) {
10121 off_ch_num = atoi(val);
10122 if (off_ch_num == 0) {
10123 send_resp(dut, conn, SIGMA_ERROR,
10124 "ErrorCode,Invalid OffChNum");
10125 return 0;
10126 }
10127 }
10128
10129 val = get_param(cmd, "SecChOffset");
10130 if (val) {
10131 if (strcmp(val, "20") == 0)
10132 sec_ch = SEC_CH_NO;
10133 else if (strcasecmp(val, "40above") == 0)
10134 sec_ch = SEC_CH_40ABOVE;
10135 else if (strcasecmp(val, "40below") == 0)
10136 sec_ch = SEC_CH_40BELOW;
10137 else {
10138 send_resp(dut, conn, SIGMA_ERROR,
10139 "ErrorCode,Unknown SecChOffset value");
10140 return 0;
10141 }
10142 }
10143
10144 if (chsm == CHSM_NOT_SET) {
10145 /* no offchannel changes requested */
10146 return 1;
10147 }
10148
10149 if (strcmp(intf, get_main_ifname()) != 0 &&
10150 strcmp(intf, get_station_ifname()) != 0) {
10151 send_resp(dut, conn, SIGMA_ERROR,
10152 "ErrorCode,Unknown interface");
10153 return 0;
10154 }
10155
10156 switch (chsm) {
10157 case CHSM_NOT_SET:
Jouni Malinen280f5ba2016-08-29 21:33:10 +030010158 res = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010159 break;
10160 case CHSM_ENABLE:
10161 if (off_ch_num < 0) {
10162 send_resp(dut, conn, SIGMA_ERROR,
10163 "ErrorCode,Missing OffChNum argument");
10164 return 0;
10165 }
10166 if (wifi_chip_type == DRIVER_WCN) {
10167 res = tdls_set_offchannel_offset(dut, conn, intf,
10168 off_ch_num, sec_ch);
10169 } else {
10170 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
10171 sec_ch);
10172 }
10173 if (res != 1)
10174 return res;
10175 if (wifi_chip_type == DRIVER_WCN)
10176 res = tdls_set_offchannel_mode(dut, conn, intf, 1);
10177 else
10178 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 1);
10179 break;
10180 case CHSM_DISABLE:
10181 if (wifi_chip_type == DRIVER_WCN)
10182 res = tdls_set_offchannel_mode(dut, conn, intf, 2);
10183 else
10184 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 2);
10185 break;
10186 case CHSM_REJREQ:
10187 if (wifi_chip_type == DRIVER_WCN)
10188 res = tdls_set_offchannel_mode(dut, conn, intf, 3);
10189 else
10190 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 3);
10191 break;
10192 case CHSM_UNSOLRESP:
10193 if (off_ch_num < 0) {
10194 send_resp(dut, conn, SIGMA_ERROR,
10195 "ErrorCode,Missing OffChNum argument");
10196 return 0;
10197 }
10198 if (wifi_chip_type == DRIVER_WCN) {
10199 res = tdls_set_offchannel_offset(dut, conn, intf,
10200 off_ch_num, sec_ch);
10201 } else {
10202 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
10203 sec_ch);
10204 }
10205 if (res != 1)
10206 return res;
10207 if (wifi_chip_type == DRIVER_WCN)
10208 res = tdls_set_offchannel_mode(dut, conn, intf, 4);
10209 else
10210 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 4);
10211 break;
10212 }
10213
10214 return res;
10215}
10216
10217
10218static int ath_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
10219 struct sigma_conn *conn,
10220 struct sigma_cmd *cmd)
10221{
10222 const char *val;
Srikanth Marepalli5415acf2018-08-27 12:53:11 +053010223 char *token = NULL, *result;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010224
priyadharshini gowthamane5e25172015-12-08 14:53:48 -080010225 novap_reset(dut, intf);
10226
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010227 val = get_param(cmd, "nss_mcs_opt");
10228 if (val) {
10229 /* String (nss_operating_mode; mcs_operating_mode) */
10230 int nss, mcs;
10231 char buf[50];
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010232 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010233
10234 token = strdup(val);
10235 if (!token)
10236 return 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010237 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +053010238 if (!result) {
10239 sigma_dut_print(dut, DUT_MSG_ERROR,
10240 "VHT NSS not specified");
10241 goto failed;
10242 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010243 if (strcasecmp(result, "def") != 0) {
10244 nss = atoi(result);
10245 if (nss == 4)
10246 ath_disable_txbf(dut, intf);
10247 snprintf(buf, sizeof(buf), "iwpriv %s nss %d",
10248 intf, nss);
10249 if (system(buf) != 0) {
10250 sigma_dut_print(dut, DUT_MSG_ERROR,
10251 "iwpriv nss failed");
10252 goto failed;
10253 }
10254 }
10255
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010256 result = strtok_r(NULL, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +053010257 if (!result) {
10258 sigma_dut_print(dut, DUT_MSG_ERROR,
10259 "VHT MCS not specified");
10260 goto failed;
10261 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010262 if (strcasecmp(result, "def") == 0) {
10263 snprintf(buf, sizeof(buf), "iwpriv %s set11NRates 0",
10264 intf);
10265 if (system(buf) != 0) {
10266 sigma_dut_print(dut, DUT_MSG_ERROR,
10267 "iwpriv set11NRates failed");
10268 goto failed;
10269 }
10270
10271 } else {
10272 mcs = atoi(result);
10273 snprintf(buf, sizeof(buf), "iwpriv %s vhtmcs %d",
10274 intf, mcs);
10275 if (system(buf) != 0) {
10276 sigma_dut_print(dut, DUT_MSG_ERROR,
10277 "iwpriv vhtmcs failed");
10278 goto failed;
10279 }
10280 }
10281 /* Channel width gets messed up, fix this */
10282 snprintf(buf, sizeof(buf), "iwpriv %s chwidth %d",
10283 intf, dut->chwidth);
10284 if (system(buf) != 0) {
10285 sigma_dut_print(dut, DUT_MSG_ERROR,
10286 "iwpriv chwidth failed");
10287 }
10288 }
10289
Srikanth Marepalli5415acf2018-08-27 12:53:11 +053010290 free(token);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010291 return 1;
10292failed:
10293 free(token);
10294 return 0;
10295}
10296
10297
10298static int cmd_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
10299 struct sigma_conn *conn,
10300 struct sigma_cmd *cmd)
10301{
10302 switch (get_driver_type()) {
10303 case DRIVER_ATHEROS:
10304 return ath_sta_set_rfeature_vht(intf, dut, conn, cmd);
10305 default:
10306 send_resp(dut, conn, SIGMA_ERROR,
10307 "errorCode,Unsupported sta_set_rfeature(VHT) with the current driver");
10308 return 0;
10309 }
10310}
10311
10312
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080010313static int wcn_sta_set_rfeature_he(const char *intf, struct sigma_dut *dut,
10314 struct sigma_conn *conn,
10315 struct sigma_cmd *cmd)
10316{
10317 const char *val;
10318 char *token = NULL, *result;
10319 char buf[60];
10320
10321 val = get_param(cmd, "nss_mcs_opt");
10322 if (val) {
10323 /* String (nss_operating_mode; mcs_operating_mode) */
10324 int nss, mcs, ratecode;
10325 char *saveptr;
10326
10327 token = strdup(val);
10328 if (!token)
10329 return -2;
10330
10331 result = strtok_r(token, ";", &saveptr);
10332 if (!result) {
10333 sigma_dut_print(dut, DUT_MSG_ERROR,
10334 "HE NSS not specified");
10335 goto failed;
10336 }
10337 nss = 1;
10338 if (strcasecmp(result, "def") != 0)
10339 nss = atoi(result);
10340
10341 result = strtok_r(NULL, ";", &saveptr);
10342 if (!result) {
10343 sigma_dut_print(dut, DUT_MSG_ERROR,
10344 "HE MCS not specified");
10345 goto failed;
10346 }
10347 mcs = 7;
10348 if (strcasecmp(result, "def") != 0)
10349 mcs = atoi(result);
10350
Arif Hussain557bf412018-05-25 17:29:36 -070010351 ratecode = 0x20; /* for nss:1 MCS 0 */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080010352 if (nss == 2) {
Arif Hussain557bf412018-05-25 17:29:36 -070010353 ratecode = 0x40; /* for nss:2 MCS 0 */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080010354 } else if (nss > 2) {
10355 sigma_dut_print(dut, DUT_MSG_ERROR,
10356 "HE NSS %d not supported", nss);
10357 goto failed;
10358 }
10359
Arif Hussain557bf412018-05-25 17:29:36 -070010360 snprintf(buf, sizeof(buf), "iwpriv %s nss %d", intf, nss);
10361 if (system(buf) != 0) {
10362 sigma_dut_print(dut, DUT_MSG_ERROR,
10363 "nss_mcs_opt: iwpriv %s nss %d failed",
10364 intf, nss);
10365 goto failed;
10366 }
Arif Hussainac6c5112018-05-25 17:34:00 -070010367 dut->sta_nss = nss;
Arif Hussain557bf412018-05-25 17:29:36 -070010368
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080010369 /* Add the MCS to the ratecode */
10370 if (mcs >= 0 && mcs <= 11) {
10371 ratecode += mcs;
Arif Hussain557bf412018-05-25 17:29:36 -070010372#ifdef NL80211_SUPPORT
10373 if (dut->device_type == STA_testbed) {
10374 enum he_mcs_config mcs_config;
10375 int ret;
10376
10377 if (mcs <= 7)
10378 mcs_config = HE_80_MCS0_7;
10379 else if (mcs <= 9)
10380 mcs_config = HE_80_MCS0_9;
10381 else
10382 mcs_config = HE_80_MCS0_11;
10383 ret = sta_set_he_mcs(dut, intf, mcs_config);
10384 if (ret) {
10385 sigma_dut_print(dut, DUT_MSG_ERROR,
10386 "nss_mcs_opt: mcs setting failed, mcs:%d, mcs_config %d, ret:%d",
10387 mcs, mcs_config, ret);
10388 goto failed;
10389 }
10390 }
10391#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080010392 } else {
10393 sigma_dut_print(dut, DUT_MSG_ERROR,
10394 "HE MCS %d not supported", mcs);
10395 goto failed;
10396 }
10397 snprintf(buf, sizeof(buf), "iwpriv %s set_11ax_rate 0x%03x",
10398 intf, ratecode);
10399 if (system(buf) != 0) {
10400 sigma_dut_print(dut, DUT_MSG_ERROR,
10401 "iwpriv setting of 11ax rates failed");
10402 goto failed;
10403 }
10404 free(token);
10405 }
10406
10407 val = get_param(cmd, "GI");
10408 if (val) {
10409 if (strcmp(val, "0.8") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070010410 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 9", intf);
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080010411 } else if (strcmp(val, "1.6") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070010412 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 10",
10413 intf);
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080010414 } else if (strcmp(val, "3.2") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070010415 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 11",
10416 intf);
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080010417 } else {
10418 send_resp(dut, conn, SIGMA_ERROR,
10419 "errorCode,GI value not supported");
10420 return 0;
10421 }
10422 if (system(buf) != 0) {
10423 send_resp(dut, conn, SIGMA_ERROR,
10424 "errorCode,Failed to set shortgi");
10425 return 0;
10426 }
10427 }
10428
Subhani Shaik8e7a3052018-04-24 14:03:00 -070010429 val = get_param(cmd, "LTF");
10430 if (val) {
10431#ifdef NL80211_SUPPORT
10432 if (strcmp(val, "3.2") == 0) {
10433 sta_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_1X);
10434 } if (strcmp(val, "6.4") == 0) {
10435 sta_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_2X);
10436 } else if (strcmp(val, "12.8") == 0) {
10437 sta_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_4X);
10438 } else {
10439 send_resp(dut, conn, SIGMA_ERROR,
10440 "errorCode, LTF value not supported");
10441 return 0;
10442 }
10443#else /* NL80211_SUPPORT */
10444 sigma_dut_print(dut, DUT_MSG_ERROR,
10445 "LTF cannot be set without NL80211_SUPPORT defined");
10446 return -2;
10447#endif /* NL80211_SUPPORT */
10448 }
10449
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -070010450 val = get_param(cmd, "TxSUPPDU");
10451 if (val) {
10452 int set_val = 1;
10453
10454 if (strcasecmp(val, "Enable") == 0)
10455 set_val = 1;
10456 else if (strcasecmp(val, "Disable") == 0)
10457 set_val = 0;
10458
10459 if (sta_set_tx_su_ppdu_cfg(dut, intf, set_val)) {
10460 send_resp(dut, conn, SIGMA_ERROR,
10461 "ErrorCode,Failed to set Tx SU PPDU config");
10462 return 0;
10463 }
10464 }
10465
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -070010466 val = get_param(cmd, "OMCtrl_RxNSS");
10467 if (val) {
10468 /*
10469 * OMCtrl_RxNSS uses the IEEE 802.11 standard values for Nss,
10470 * i.e., 0 for 1Nss, 1 for Nss 2, etc. The driver checks for
10471 * the actual Nss value hence add 1 to the set value.
10472 */
10473 int set_val = atoi(val) + 1;
10474
10475 if (sta_set_he_om_ctrl_nss(dut, intf, set_val)) {
10476 send_resp(dut, conn, SIGMA_ERROR,
10477 "ErrorCode,Failed to set OM ctrl NSS config");
10478 return 0;
10479 }
10480 }
10481
10482 val = get_param(cmd, "OMCtrl_ChnlWidth");
10483 if (val) {
10484 int set_val = atoi(val);
10485
10486 if (sta_set_he_om_ctrl_bw(dut, intf,
10487 (enum qca_wlan_he_om_ctrl_ch_bw)
10488 set_val)) {
10489 send_resp(dut, conn, SIGMA_ERROR,
10490 "ErrorCode,Failed to set OM ctrl BW config");
10491 return 0;
10492 }
10493 }
10494
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080010495 val = get_param(cmd, "Powersave");
10496 if (val) {
10497 char buf[60];
10498
10499 if (strcasecmp(val, "off") == 0) {
10500 snprintf(buf, sizeof(buf),
10501 "iwpriv %s setPower 2", intf);
10502 if (system(buf) != 0) {
10503 sigma_dut_print(dut, DUT_MSG_ERROR,
10504 "iwpriv setPower 2 failed");
10505 return 0;
10506 }
10507 } else if (strcasecmp(val, "on") == 0) {
10508 snprintf(buf, sizeof(buf),
10509 "iwpriv %s setPower 1", intf);
10510 if (system(buf) != 0) {
10511 sigma_dut_print(dut, DUT_MSG_ERROR,
10512 "iwpriv setPower 1 failed");
10513 return 0;
10514 }
10515 } else {
10516 sigma_dut_print(dut, DUT_MSG_ERROR,
10517 "Unsupported Powersave value '%s'",
10518 val);
10519 return -1;
10520 }
10521 }
10522
Kiran Kumar Lokere2c4b7ce2019-01-30 12:02:28 -080010523 val = get_param(cmd, "MU_EDCA");
10524 if (val) {
10525 if (strcasecmp(val, "Override") == 0) {
10526 if (sta_set_mu_edca_override(dut, intf, 1)) {
10527 send_resp(dut, conn, SIGMA_ERROR,
10528 "errorCode,MU EDCA override set failed");
10529 return STATUS_SENT;
10530 }
10531 } else if (strcasecmp(val, "Disable") == 0) {
10532 if (sta_set_mu_edca_override(dut, intf, 0)) {
10533 send_resp(dut, conn, SIGMA_ERROR,
10534 "errorCode,MU EDCA override disable failed");
10535 return STATUS_SENT;
10536 }
10537 }
10538 }
10539
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080010540 return 1;
10541
10542failed:
10543 free(token);
10544 return -2;
10545}
10546
10547
10548static int cmd_sta_set_rfeature_he(const char *intf, struct sigma_dut *dut,
10549 struct sigma_conn *conn,
10550 struct sigma_cmd *cmd)
10551{
10552 switch (get_driver_type()) {
10553 case DRIVER_WCN:
10554 return wcn_sta_set_rfeature_he(intf, dut, conn, cmd);
10555 default:
10556 send_resp(dut, conn, SIGMA_ERROR,
10557 "errorCode,Unsupported sta_set_rfeature(HE) with the current driver");
10558 return 0;
10559 }
10560}
10561
10562
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080010563static int cmd_sta_set_power_save_he(const char *intf, struct sigma_dut *dut,
10564 struct sigma_conn *conn,
10565 struct sigma_cmd *cmd)
10566{
10567 const char *val;
10568
10569 val = get_param(cmd, "powersave");
10570 if (val) {
10571 char buf[60];
10572
10573 if (strcasecmp(val, "off") == 0) {
10574 snprintf(buf, sizeof(buf), "iwpriv %s setPower 2",
10575 intf);
10576 if (system(buf) != 0) {
10577 sigma_dut_print(dut, DUT_MSG_ERROR,
10578 "iwpriv setPower 2 failed");
10579 return 0;
10580 }
10581 } else if (strcasecmp(val, "on") == 0) {
10582 snprintf(buf, sizeof(buf), "iwpriv %s setPower 1",
10583 intf);
10584 if (system(buf) != 0) {
10585 sigma_dut_print(dut, DUT_MSG_ERROR,
10586 "iwpriv setPower 1 failed");
10587 return 0;
10588 }
10589 } else {
10590 sigma_dut_print(dut, DUT_MSG_ERROR,
10591 "Unsupported power save config");
10592 return -1;
10593 }
10594 return 1;
10595 }
10596
10597 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported command");
10598
10599 return 0;
10600}
10601
10602
Ashwini Patil5acd7382017-04-13 15:55:04 +053010603static int btm_query_candidate_list(struct sigma_dut *dut,
10604 struct sigma_conn *conn,
10605 struct sigma_cmd *cmd)
10606{
10607 const char *bssid, *info, *op_class, *ch, *phy_type, *pref;
10608 int len, ret;
10609 char buf[10];
10610
10611 /*
10612 * Neighbor Report elements format:
10613 * neighbor=<BSSID>,<BSSID Information>,<Operating Class>,
10614 * <Channel Number>,<PHY Type>[,<hexdump of Optional Subelements>]
10615 * eg: neighbor=aa:bb:cc:dd:ee:ff,17,81,6,1,030101
10616 */
10617
10618 bssid = get_param(cmd, "Nebor_BSSID");
10619 if (!bssid) {
10620 send_resp(dut, conn, SIGMA_INVALID,
10621 "errorCode,Nebor_BSSID is missing");
10622 return 0;
10623 }
10624
10625 info = get_param(cmd, "Nebor_Bssid_Info");
10626 if (!info) {
10627 sigma_dut_print(dut, DUT_MSG_INFO,
10628 "Using default value for Nebor_Bssid_Info: %s",
10629 DEFAULT_NEIGHBOR_BSSID_INFO);
10630 info = DEFAULT_NEIGHBOR_BSSID_INFO;
10631 }
10632
10633 op_class = get_param(cmd, "Nebor_Op_Class");
10634 if (!op_class) {
10635 send_resp(dut, conn, SIGMA_INVALID,
10636 "errorCode,Nebor_Op_Class is missing");
10637 return 0;
10638 }
10639
10640 ch = get_param(cmd, "Nebor_Op_Ch");
10641 if (!ch) {
10642 send_resp(dut, conn, SIGMA_INVALID,
10643 "errorCode,Nebor_Op_Ch is missing");
10644 return 0;
10645 }
10646
10647 phy_type = get_param(cmd, "Nebor_Phy_Type");
10648 if (!phy_type) {
10649 sigma_dut_print(dut, DUT_MSG_INFO,
10650 "Using default value for Nebor_Phy_Type: %s",
10651 DEFAULT_NEIGHBOR_PHY_TYPE);
10652 phy_type = DEFAULT_NEIGHBOR_PHY_TYPE;
10653 }
10654
10655 /* Parse optional subelements */
10656 buf[0] = '\0';
10657 pref = get_param(cmd, "Nebor_Pref");
10658 if (pref) {
10659 /* hexdump for preferrence subelement */
10660 ret = snprintf(buf, sizeof(buf), ",0301%02x", atoi(pref));
10661 if (ret < 0 || ret >= (int) sizeof(buf)) {
10662 sigma_dut_print(dut, DUT_MSG_ERROR,
10663 "snprintf failed for optional subelement ret: %d",
10664 ret);
10665 send_resp(dut, conn, SIGMA_ERROR,
10666 "errorCode,snprintf failed for subelement");
10667 return 0;
10668 }
10669 }
10670
10671 if (!dut->btm_query_cand_list) {
10672 dut->btm_query_cand_list = calloc(1, NEIGHBOR_REPORT_SIZE);
10673 if (!dut->btm_query_cand_list) {
10674 send_resp(dut, conn, SIGMA_ERROR,
10675 "errorCode,Failed to allocate memory for btm_query_cand_list");
10676 return 0;
10677 }
10678 }
10679
10680 len = strlen(dut->btm_query_cand_list);
10681 ret = snprintf(dut->btm_query_cand_list + len,
10682 NEIGHBOR_REPORT_SIZE - len, " neighbor=%s,%s,%s,%s,%s%s",
10683 bssid, info, op_class, ch, phy_type, buf);
10684 if (ret < 0 || ret >= NEIGHBOR_REPORT_SIZE - len) {
10685 sigma_dut_print(dut, DUT_MSG_ERROR,
10686 "snprintf failed for neighbor report list ret: %d",
10687 ret);
10688 send_resp(dut, conn, SIGMA_ERROR,
10689 "errorCode,snprintf failed for neighbor report");
10690 free(dut->btm_query_cand_list);
10691 dut->btm_query_cand_list = NULL;
10692 return 0;
10693 }
10694
10695 return 1;
10696}
10697
10698
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020010699int sta_extract_60g_ese(struct sigma_dut *dut, struct sigma_cmd *cmd,
10700 struct sigma_ese_alloc *allocs, int *allocs_size)
10701{
10702 int max_count = *allocs_size;
10703 int count = 0, i;
10704 const char *val;
10705
10706 do {
10707 val = get_param_indexed(cmd, "AllocID", count);
10708 if (val)
10709 count++;
10710 } while (val);
10711
10712 if (count == 0 || count > max_count) {
10713 sigma_dut_print(dut, DUT_MSG_ERROR,
10714 "Invalid number of allocations(%d)", count);
10715 return -1;
10716 }
10717
10718 for (i = 0; i < count; i++) {
10719 val = get_param_indexed(cmd, "PercentBI", i);
10720 if (!val) {
10721 sigma_dut_print(dut, DUT_MSG_ERROR,
10722 "Missing PercentBI parameter at index %d",
10723 i);
10724 return -1;
10725 }
10726 allocs[i].percent_bi = atoi(val);
10727
10728 val = get_param_indexed(cmd, "SrcAID", i);
10729 if (val)
10730 allocs[i].src_aid = strtol(val, NULL, 0);
10731 else
10732 allocs[i].src_aid = ESE_BCAST_AID;
10733
10734 val = get_param_indexed(cmd, "DestAID", i);
10735 if (val)
10736 allocs[i].dst_aid = strtol(val, NULL, 0);
10737 else
10738 allocs[i].dst_aid = ESE_BCAST_AID;
10739
10740 allocs[i].type = ESE_CBAP;
10741 sigma_dut_print(dut, DUT_MSG_INFO,
10742 "Alloc %d PercentBI %d SrcAID %d DstAID %d",
10743 i, allocs[i].percent_bi, allocs[i].src_aid,
10744 allocs[i].dst_aid);
10745 }
10746
10747 *allocs_size = count;
10748 return 0;
10749}
10750
10751
10752static int sta_set_60g_ese(struct sigma_dut *dut, int count,
10753 struct sigma_ese_alloc *allocs)
10754{
10755 switch (get_driver_type()) {
10756#ifdef __linux__
10757 case DRIVER_WIL6210:
10758 if (wil6210_set_ese(dut, count, allocs))
10759 return -1;
10760 return 1;
10761#endif /* __linux__ */
10762 default:
10763 sigma_dut_print(dut, DUT_MSG_ERROR,
10764 "Unsupported sta_set_60g_ese with the current driver");
10765 return -1;
10766 }
10767}
10768
10769
10770static int cmd_sta_set_rfeature_60g(const char *intf, struct sigma_dut *dut,
10771 struct sigma_conn *conn,
10772 struct sigma_cmd *cmd)
10773{
10774 const char *val;
10775
10776 val = get_param(cmd, "ExtSchIE");
10777 if (val && !strcasecmp(val, "Enable")) {
10778 struct sigma_ese_alloc allocs[MAX_ESE_ALLOCS];
10779 int count = MAX_ESE_ALLOCS;
10780
10781 if (sta_extract_60g_ese(dut, cmd, allocs, &count))
10782 return -1;
10783 return sta_set_60g_ese(dut, count, allocs);
10784 }
10785
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +020010786 val = get_param(cmd, "MCS_FixedRate");
10787 if (val) {
10788 int sta_mcs = atoi(val);
10789
10790 sigma_dut_print(dut, DUT_MSG_INFO, "Force STA MCS to %d",
10791 sta_mcs);
10792 wil6210_set_force_mcs(dut, 1, sta_mcs);
10793
Jouni Malinen0e29cf22019-02-19 01:13:21 +020010794 return SUCCESS_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +020010795 }
10796
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020010797 send_resp(dut, conn, SIGMA_ERROR,
10798 "errorCode,Invalid sta_set_rfeature(60G)");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020010799 return STATUS_SENT;
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020010800}
10801
10802
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010803static int cmd_sta_set_rfeature(struct sigma_dut *dut, struct sigma_conn *conn,
10804 struct sigma_cmd *cmd)
10805{
10806 const char *intf = get_param(cmd, "Interface");
10807 const char *prog = get_param(cmd, "Prog");
Ashwini Patil68d02cd2017-01-10 15:39:16 +053010808 const char *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010809
10810 if (intf == NULL || prog == NULL)
10811 return -1;
10812
Ashwini Patil5acd7382017-04-13 15:55:04 +053010813 /* BSS Transition candidate list for BTM query */
10814 val = get_param(cmd, "Nebor_BSSID");
10815 if (val && btm_query_candidate_list(dut, conn, cmd) == 0)
10816 return 0;
10817
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010818 if (strcasecmp(prog, "TDLS") == 0)
10819 return cmd_sta_set_rfeature_tdls(intf, dut, conn, cmd);
10820
10821 if (strcasecmp(prog, "VHT") == 0)
10822 return cmd_sta_set_rfeature_vht(intf, dut, conn, cmd);
10823
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080010824 if (strcasecmp(prog, "HE") == 0)
10825 return cmd_sta_set_rfeature_he(intf, dut, conn, cmd);
10826
Ashwini Patil68d02cd2017-01-10 15:39:16 +053010827 if (strcasecmp(prog, "MBO") == 0) {
10828 val = get_param(cmd, "Cellular_Data_Cap");
10829 if (val &&
10830 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
10831 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +053010832
10833 val = get_param(cmd, "Ch_Pref");
10834 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
10835 return 0;
10836
Ashwini Patil68d02cd2017-01-10 15:39:16 +053010837 return 1;
10838 }
10839
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020010840 if (strcasecmp(prog, "60GHz") == 0)
10841 return cmd_sta_set_rfeature_60g(intf, dut, conn, cmd);
10842
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010843 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported Prog");
10844 return 0;
10845}
10846
10847
10848static int cmd_sta_set_radio(struct sigma_dut *dut, struct sigma_conn *conn,
10849 struct sigma_cmd *cmd)
10850{
10851 const char *intf = get_param(cmd, "Interface");
10852 const char *mode = get_param(cmd, "Mode");
10853 int res;
10854
10855 if (intf == NULL || mode == NULL)
10856 return -1;
10857
10858 if (strcasecmp(mode, "On") == 0)
10859 res = wpa_command(intf, "SET radio_disabled 0");
10860 else if (strcasecmp(mode, "Off") == 0)
10861 res = wpa_command(intf, "SET radio_disabled 1");
10862 else
10863 return -1;
10864
10865 if (res) {
10866 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
10867 "radio mode");
10868 return 0;
10869 }
10870
10871 return 1;
10872}
10873
10874
10875static int cmd_sta_set_pwrsave(struct sigma_dut *dut, struct sigma_conn *conn,
10876 struct sigma_cmd *cmd)
10877{
10878 const char *intf = get_param(cmd, "Interface");
10879 const char *mode = get_param(cmd, "Mode");
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020010880 const char *prog = get_param(cmd, "program");
10881 const char *powersave = get_param(cmd, "powersave");
10882 int res = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010883
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020010884 if (intf == NULL)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010885 return -1;
10886
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020010887 if (prog && strcasecmp(prog, "60GHz") == 0) {
10888 /*
10889 * The CAPI mode parameter does not exist in 60G
10890 * unscheduled PS.
10891 */
10892 if (strcasecmp(powersave, "unscheduled") == 0)
10893 res = set_ps(intf, dut, 1);
Alexei Avshalom Lazar2f6fdb42019-02-04 14:16:08 +020010894 } else if (prog && get_driver_type() == DRIVER_WCN &&
10895 strcasecmp(prog, "HE") == 0) {
10896 return cmd_sta_set_power_save_he(intf, dut, conn, cmd);
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020010897 } else {
10898 if (mode == NULL)
10899 return -1;
10900
10901 if (strcasecmp(mode, "On") == 0)
10902 res = set_ps(intf, dut, 1);
10903 else if (strcasecmp(mode, "Off") == 0)
10904 res = set_ps(intf, dut, 0);
10905 else
10906 return -1;
10907 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010908
10909 if (res) {
10910 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
10911 "power save mode");
10912 return 0;
10913 }
10914
10915 return 1;
10916}
10917
10918
10919static int cmd_sta_bssid_pool(struct sigma_dut *dut, struct sigma_conn *conn,
10920 struct sigma_cmd *cmd)
10921{
10922 const char *intf = get_param(cmd, "Interface");
10923 const char *val, *bssid;
10924 int res;
10925 char *buf;
10926 size_t buf_len;
10927
10928 val = get_param(cmd, "BSSID_FILTER");
10929 if (val == NULL)
10930 return -1;
10931
10932 bssid = get_param(cmd, "BSSID_List");
10933 if (atoi(val) == 0 || bssid == NULL) {
10934 /* Disable BSSID filter */
10935 if (wpa_command(intf, "SET bssid_filter ")) {
10936 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed "
10937 "to disable BSSID filter");
10938 return 0;
10939 }
10940
10941 return 1;
10942 }
10943
10944 buf_len = 100 + strlen(bssid);
10945 buf = malloc(buf_len);
10946 if (buf == NULL)
10947 return -1;
10948
10949 snprintf(buf, buf_len, "SET bssid_filter %s", bssid);
10950 res = wpa_command(intf, buf);
10951 free(buf);
10952 if (res) {
10953 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to enable "
10954 "BSSID filter");
10955 return 0;
10956 }
10957
10958 return 1;
10959}
10960
10961
10962static int cmd_sta_reset_parm(struct sigma_dut *dut, struct sigma_conn *conn,
10963 struct sigma_cmd *cmd)
10964{
10965 const char *intf = get_param(cmd, "Interface");
10966 const char *val;
10967
10968 /* TODO: ARP */
10969
10970 val = get_param(cmd, "HS2_CACHE_PROFILE");
10971 if (val && strcasecmp(val, "All") == 0)
10972 hs2_clear_credentials(intf);
10973
10974 return 1;
10975}
10976
10977
10978static int cmd_sta_get_key(struct sigma_dut *dut, struct sigma_conn *conn,
10979 struct sigma_cmd *cmd)
10980{
10981 const char *intf = get_param(cmd, "Interface");
10982 const char *key_type = get_param(cmd, "KeyType");
10983 char buf[100], resp[200];
10984
10985 if (key_type == NULL)
10986 return -1;
10987
10988 if (strcasecmp(key_type, "GTK") == 0) {
10989 if (wpa_command_resp(intf, "GET gtk", buf, sizeof(buf)) < 0 ||
10990 strncmp(buf, "FAIL", 4) == 0) {
10991 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
10992 "not fetch current GTK");
10993 return 0;
10994 }
10995 snprintf(resp, sizeof(resp), "KeyValue,%s", buf);
10996 send_resp(dut, conn, SIGMA_COMPLETE, resp);
10997 return 0;
10998 } else {
10999 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
11000 "KeyType");
11001 return 0;
11002 }
11003
11004 return 1;
11005}
11006
11007
11008static int hs2_set_policy(struct sigma_dut *dut)
11009{
11010#ifdef ANDROID
11011 system("ip rule del prio 23000");
11012 if (system("ip rule add from all lookup main prio 23000") != 0) {
11013 sigma_dut_print(dut, DUT_MSG_ERROR,
11014 "Failed to run:ip rule add from all lookup main prio");
11015 return -1;
11016 }
11017 if (system("ip route flush cache") != 0) {
11018 sigma_dut_print(dut, DUT_MSG_ERROR,
11019 "Failed to run ip route flush cache");
11020 return -1;
11021 }
11022 return 1;
11023#else /* ANDROID */
11024 return 0;
11025#endif /* ANDROID */
11026}
11027
11028
11029static int cmd_sta_hs2_associate(struct sigma_dut *dut,
11030 struct sigma_conn *conn,
11031 struct sigma_cmd *cmd)
11032{
11033 const char *intf = get_param(cmd, "Interface");
11034 const char *val = get_param(cmd, "Ignore_blacklist");
Jouni Malinen439352d2018-09-13 03:42:23 +030011035 const char *band = get_param(cmd, "Band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011036 struct wpa_ctrl *ctrl;
11037 int res;
11038 char bssid[20], ssid[40], resp[100], buf[100], blacklisted[100];
11039 int tries = 0;
11040 int ignore_blacklist = 0;
11041 const char *events[] = {
11042 "CTRL-EVENT-CONNECTED",
11043 "INTERWORKING-BLACKLISTED",
11044 "INTERWORKING-NO-MATCH",
11045 NULL
11046 };
11047
11048 start_sta_mode(dut);
11049
Jouni Malinen439352d2018-09-13 03:42:23 +030011050 if (band) {
11051 if (strcmp(band, "2.4") == 0) {
11052 wpa_command(intf, "SET setband 2G");
11053 } else if (strcmp(band, "5") == 0) {
11054 wpa_command(intf, "SET setband 5G");
11055 } else {
11056 send_resp(dut, conn, SIGMA_ERROR,
11057 "errorCode,Unsupported band");
11058 return 0;
11059 }
11060 }
11061
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011062 blacklisted[0] = '\0';
11063 if (val && atoi(val))
11064 ignore_blacklist = 1;
11065
11066try_again:
11067 ctrl = open_wpa_mon(intf);
11068 if (ctrl == NULL) {
11069 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
11070 "wpa_supplicant monitor connection");
11071 return -2;
11072 }
11073
11074 tries++;
11075 if (wpa_command(intf, "INTERWORKING_SELECT auto")) {
11076 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start "
11077 "Interworking connection");
11078 wpa_ctrl_detach(ctrl);
11079 wpa_ctrl_close(ctrl);
11080 return 0;
11081 }
11082
11083 buf[0] = '\0';
11084 while (1) {
11085 char *pos;
11086 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
11087 pos = strstr(buf, "INTERWORKING-BLACKLISTED");
11088 if (!pos)
11089 break;
11090 pos += 25;
11091 sigma_dut_print(dut, DUT_MSG_DEBUG, "Found blacklisted AP: %s",
11092 pos);
11093 if (!blacklisted[0])
11094 memcpy(blacklisted, pos, strlen(pos) + 1);
11095 }
11096
11097 if (ignore_blacklist && blacklisted[0]) {
11098 char *end;
11099 end = strchr(blacklisted, ' ');
11100 if (end)
11101 *end = '\0';
11102 sigma_dut_print(dut, DUT_MSG_DEBUG, "Try to connect to a blacklisted network: %s",
11103 blacklisted);
11104 snprintf(buf, sizeof(buf), "INTERWORKING_CONNECT %s",
11105 blacklisted);
11106 if (wpa_command(intf, buf)) {
11107 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start Interworking connection to blacklisted network");
11108 wpa_ctrl_detach(ctrl);
11109 wpa_ctrl_close(ctrl);
11110 return 0;
11111 }
11112 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
11113 buf, sizeof(buf));
11114 }
11115
11116 wpa_ctrl_detach(ctrl);
11117 wpa_ctrl_close(ctrl);
11118
11119 if (res < 0) {
11120 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
11121 "connect");
11122 return 0;
11123 }
11124
11125 if (strstr(buf, "INTERWORKING-NO-MATCH") ||
11126 strstr(buf, "INTERWORKING-BLACKLISTED")) {
11127 if (tries < 2) {
11128 sigma_dut_print(dut, DUT_MSG_INFO, "No match found - try again to verify no APs were missed in the scan");
11129 goto try_again;
11130 }
11131 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,No network with "
11132 "matching credentials found");
11133 return 0;
11134 }
11135
11136 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
11137 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
11138 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
11139 "get current BSSID/SSID");
11140 return 0;
11141 }
11142
11143 snprintf(resp, sizeof(resp), "SSID,%s,BSSID,%s", ssid, bssid);
11144 send_resp(dut, conn, SIGMA_COMPLETE, resp);
11145 hs2_set_policy(dut);
11146 return 0;
11147}
11148
11149
Jouni Malinenb639f1c2018-09-13 02:39:46 +030011150static int cmd_sta_hs2_venue_info(struct sigma_dut *dut,
11151 struct sigma_conn *conn,
11152 struct sigma_cmd *cmd)
11153{
11154 const char *intf = get_param(cmd, "Interface");
11155 const char *display = get_param(cmd, "Display");
11156 struct wpa_ctrl *ctrl;
11157 char buf[300], params[400], *pos;
11158 char bssid[20];
11159 int info_avail = 0;
11160 unsigned int old_timeout;
11161 int res;
11162
11163 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0) {
11164 send_resp(dut, conn, SIGMA_ERROR,
11165 "ErrorCode,Could not get current BSSID");
11166 return 0;
11167 }
11168 ctrl = open_wpa_mon(intf);
11169 if (!ctrl) {
11170 sigma_dut_print(dut, DUT_MSG_ERROR,
11171 "Failed to open wpa_supplicant monitor connection");
11172 return -2;
11173 }
11174
11175 snprintf(buf, sizeof(buf), "ANQP_GET %s 277", bssid);
11176 wpa_command(intf, buf);
11177
11178 res = get_wpa_cli_event(dut, ctrl, "GAS-QUERY-DONE", buf, sizeof(buf));
11179 if (res < 0) {
11180 send_resp(dut, conn, SIGMA_ERROR,
11181 "ErrorCode,Could not complete GAS query");
11182 goto fail;
11183 }
11184
11185 old_timeout = dut->default_timeout;
11186 dut->default_timeout = 2;
11187 res = get_wpa_cli_event(dut, ctrl, "RX-VENUE-URL", buf, sizeof(buf));
11188 dut->default_timeout = old_timeout;
11189 if (res < 0)
11190 goto done;
11191 pos = strchr(buf, ' ');
11192 if (!pos)
11193 goto done;
11194 pos++;
11195 pos = strchr(pos, ' ');
11196 if (!pos)
11197 goto done;
11198 pos++;
11199 info_avail = 1;
11200 snprintf(params, sizeof(params), "browser %s", pos);
11201
11202 if (display && strcasecmp(display, "Yes") == 0) {
11203 pid_t pid;
11204
11205 pid = fork();
11206 if (pid < 0) {
11207 perror("fork");
11208 return -1;
11209 }
11210
11211 if (pid == 0) {
11212 run_hs20_osu(dut, params);
11213 exit(0);
11214 }
11215 }
11216
11217done:
11218 snprintf(buf, sizeof(buf), "Info_available,%s",
11219 info_avail ? "Yes" : "No");
11220 send_resp(dut, conn, SIGMA_COMPLETE, buf);
11221fail:
11222 wpa_ctrl_detach(ctrl);
11223 wpa_ctrl_close(ctrl);
11224 return 0;
11225}
11226
11227
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011228static int sta_add_credential_uname_pwd(struct sigma_dut *dut,
11229 struct sigma_conn *conn,
11230 const char *ifname,
11231 struct sigma_cmd *cmd)
11232{
11233 const char *val;
11234 int id;
11235
11236 id = add_cred(ifname);
11237 if (id < 0)
11238 return -2;
11239 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
11240
11241 val = get_param(cmd, "prefer");
11242 if (val && atoi(val) > 0)
11243 set_cred(ifname, id, "priority", "1");
11244
11245 val = get_param(cmd, "REALM");
11246 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
11247 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
11248 "realm");
11249 return 0;
11250 }
11251
11252 val = get_param(cmd, "HOME_FQDN");
11253 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
11254 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
11255 "home_fqdn");
11256 return 0;
11257 }
11258
11259 val = get_param(cmd, "Username");
11260 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
11261 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
11262 "username");
11263 return 0;
11264 }
11265
11266 val = get_param(cmd, "Password");
11267 if (val && set_cred_quoted(ifname, id, "password", val) < 0) {
11268 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
11269 "password");
11270 return 0;
11271 }
11272
11273 val = get_param(cmd, "ROOT_CA");
11274 if (val) {
11275 char fname[200];
11276 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
11277#ifdef __linux__
11278 if (!file_exists(fname)) {
11279 char msg[300];
11280 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
11281 "file (%s) not found", fname);
11282 send_resp(dut, conn, SIGMA_ERROR, msg);
11283 return 0;
11284 }
11285#endif /* __linux__ */
11286 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
11287 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
11288 "not set root CA");
11289 return 0;
11290 }
11291 }
11292
11293 return 1;
11294}
11295
11296
11297static int update_devdetail_imsi(struct sigma_dut *dut, const char *imsi)
11298{
11299 FILE *in, *out;
11300 char buf[500];
11301 int found = 0;
11302
11303 in = fopen("devdetail.xml", "r");
11304 if (in == NULL)
11305 return -1;
11306 out = fopen("devdetail.xml.tmp", "w");
11307 if (out == NULL) {
11308 fclose(in);
11309 return -1;
11310 }
11311
11312 while (fgets(buf, sizeof(buf), in)) {
11313 char *pos = strstr(buf, "<IMSI>");
11314 if (pos) {
11315 sigma_dut_print(dut, DUT_MSG_INFO, "Updated DevDetail IMSI to %s",
11316 imsi);
11317 pos += 6;
11318 *pos = '\0';
11319 fprintf(out, "%s%s</IMSI>\n", buf, imsi);
11320 found++;
11321 } else {
11322 fprintf(out, "%s", buf);
11323 }
11324 }
11325
11326 fclose(out);
11327 fclose(in);
11328 if (found)
11329 rename("devdetail.xml.tmp", "devdetail.xml");
11330 else
11331 unlink("devdetail.xml.tmp");
11332
11333 return 0;
11334}
11335
11336
11337static int sta_add_credential_sim(struct sigma_dut *dut,
11338 struct sigma_conn *conn,
11339 const char *ifname, struct sigma_cmd *cmd)
11340{
11341 const char *val, *imsi = NULL;
11342 int id;
11343 char buf[200];
11344 int res;
11345 const char *pos;
11346 size_t mnc_len;
11347 char plmn_mcc[4];
11348 char plmn_mnc[4];
11349
11350 id = add_cred(ifname);
11351 if (id < 0)
11352 return -2;
11353 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
11354
11355 val = get_param(cmd, "prefer");
11356 if (val && atoi(val) > 0)
11357 set_cred(ifname, id, "priority", "1");
11358
11359 val = get_param(cmd, "PLMN_MCC");
11360 if (val == NULL) {
11361 send_resp(dut, conn, SIGMA_ERROR,
11362 "errorCode,Missing PLMN_MCC");
11363 return 0;
11364 }
11365 if (strlen(val) != 3) {
11366 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MCC");
11367 return 0;
11368 }
11369 snprintf(plmn_mcc, sizeof(plmn_mcc), "%s", val);
11370
11371 val = get_param(cmd, "PLMN_MNC");
11372 if (val == NULL) {
11373 send_resp(dut, conn, SIGMA_ERROR,
11374 "errorCode,Missing PLMN_MNC");
11375 return 0;
11376 }
11377 if (strlen(val) != 2 && strlen(val) != 3) {
11378 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MNC");
11379 return 0;
11380 }
11381 snprintf(plmn_mnc, sizeof(plmn_mnc), "%s", val);
11382
11383 val = get_param(cmd, "IMSI");
11384 if (val == NULL) {
11385 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing SIM "
11386 "IMSI");
11387 return 0;
11388 }
11389
11390 imsi = pos = val;
11391
11392 if (strncmp(plmn_mcc, pos, 3) != 0) {
11393 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MCC mismatch");
11394 return 0;
11395 }
11396 pos += 3;
11397
11398 mnc_len = strlen(plmn_mnc);
11399 if (mnc_len < 2) {
11400 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC not set");
11401 return 0;
11402 }
11403
11404 if (strncmp(plmn_mnc, pos, mnc_len) != 0) {
11405 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC mismatch");
11406 return 0;
11407 }
11408 pos += mnc_len;
11409
11410 res = snprintf(buf, sizeof(buf), "%s%s-%s",plmn_mcc, plmn_mnc, pos);
11411 if (res < 0 || res >= (int) sizeof(buf))
11412 return -1;
11413 if (set_cred_quoted(ifname, id, "imsi", buf) < 0) {
11414 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
11415 "not set IMSI");
11416 return 0;
11417 }
11418
11419 val = get_param(cmd, "Password");
11420 if (val && set_cred_quoted(ifname, id, "milenage", val) < 0) {
11421 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
11422 "not set password");
11423 return 0;
11424 }
11425
Jouni Malinenba630452018-06-22 11:49:59 +030011426 if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011427 /*
11428 * Set provisioning_sp for the test cases where SIM/USIM
11429 * provisioning is used.
11430 */
11431 if (val && set_cred_quoted(ifname, id, "provisioning_sp",
11432 "wi-fi.org") < 0) {
11433 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
11434 "not set provisioning_sp");
11435 return 0;
11436 }
11437
11438 update_devdetail_imsi(dut, imsi);
11439 }
11440
11441 return 1;
11442}
11443
11444
11445static int sta_add_credential_cert(struct sigma_dut *dut,
11446 struct sigma_conn *conn,
11447 const char *ifname,
11448 struct sigma_cmd *cmd)
11449{
11450 const char *val;
11451 int id;
11452
11453 id = add_cred(ifname);
11454 if (id < 0)
11455 return -2;
11456 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
11457
11458 val = get_param(cmd, "prefer");
11459 if (val && atoi(val) > 0)
11460 set_cred(ifname, id, "priority", "1");
11461
11462 val = get_param(cmd, "REALM");
11463 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
11464 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
11465 "realm");
11466 return 0;
11467 }
11468
11469 val = get_param(cmd, "HOME_FQDN");
11470 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
11471 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
11472 "home_fqdn");
11473 return 0;
11474 }
11475
11476 val = get_param(cmd, "Username");
11477 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
11478 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
11479 "username");
11480 return 0;
11481 }
11482
11483 val = get_param(cmd, "clientCertificate");
11484 if (val) {
11485 char fname[200];
11486 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
11487#ifdef __linux__
11488 if (!file_exists(fname)) {
11489 char msg[300];
11490 snprintf(msg, sizeof(msg),
11491 "ErrorCode,clientCertificate "
11492 "file (%s) not found", fname);
11493 send_resp(dut, conn, SIGMA_ERROR, msg);
11494 return 0;
11495 }
11496#endif /* __linux__ */
11497 if (set_cred_quoted(ifname, id, "client_cert", fname) < 0) {
11498 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
11499 "not set client_cert");
11500 return 0;
11501 }
11502 if (set_cred_quoted(ifname, id, "private_key", fname) < 0) {
11503 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
11504 "not set private_key");
11505 return 0;
11506 }
11507 }
11508
11509 val = get_param(cmd, "ROOT_CA");
11510 if (val) {
11511 char fname[200];
11512 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
11513#ifdef __linux__
11514 if (!file_exists(fname)) {
11515 char msg[300];
11516 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
11517 "file (%s) not found", fname);
11518 send_resp(dut, conn, SIGMA_ERROR, msg);
11519 return 0;
11520 }
11521#endif /* __linux__ */
11522 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
11523 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
11524 "not set root CA");
11525 return 0;
11526 }
11527 }
11528
11529 return 1;
11530}
11531
11532
11533static int cmd_sta_add_credential(struct sigma_dut *dut,
11534 struct sigma_conn *conn,
11535 struct sigma_cmd *cmd)
11536{
11537 const char *intf = get_param(cmd, "Interface");
11538 const char *type;
11539
11540 start_sta_mode(dut);
11541
11542 type = get_param(cmd, "Type");
11543 if (!type)
11544 return -1;
11545
11546 if (strcasecmp(type, "uname_pwd") == 0)
11547 return sta_add_credential_uname_pwd(dut, conn, intf, cmd);
11548
11549 if (strcasecmp(type, "sim") == 0)
11550 return sta_add_credential_sim(dut, conn, intf, cmd);
11551
11552 if (strcasecmp(type, "cert") == 0)
11553 return sta_add_credential_cert(dut, conn, intf, cmd);
11554
11555 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported credential "
11556 "type");
11557 return 0;
11558}
11559
11560
11561static int cmd_sta_scan(struct sigma_dut *dut, struct sigma_conn *conn,
11562 struct sigma_cmd *cmd)
11563{
11564 const char *intf = get_param(cmd, "Interface");
vamsi krishna89ad8c62017-09-19 12:51:18 +053011565 const char *val, *bssid, *ssid;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011566 char buf[100];
vamsi krishna89ad8c62017-09-19 12:51:18 +053011567 char ssid_hex[65];
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011568 int res;
11569
11570 val = get_param(cmd, "HESSID");
11571 if (val) {
11572 res = snprintf(buf, sizeof(buf), "SET hessid %s", val);
11573 if (res < 0 || res >= (int) sizeof(buf))
11574 return -1;
11575 wpa_command(intf, buf);
11576 }
11577
11578 val = get_param(cmd, "ACCS_NET_TYPE");
11579 if (val) {
11580 res = snprintf(buf, sizeof(buf), "SET access_network_type %s",
11581 val);
11582 if (res < 0 || res >= (int) sizeof(buf))
11583 return -1;
11584 wpa_command(intf, buf);
11585 }
11586
vamsi krishna89ad8c62017-09-19 12:51:18 +053011587 bssid = get_param(cmd, "Bssid");
11588 ssid = get_param(cmd, "Ssid");
11589
11590 if (ssid) {
11591 if (2 * strlen(ssid) >= sizeof(ssid_hex)) {
11592 send_resp(dut, conn, SIGMA_ERROR,
11593 "ErrorCode,Too long SSID");
11594 return 0;
11595 }
11596 ascii2hexstr(ssid, ssid_hex);
11597 }
11598
11599 res = snprintf(buf, sizeof(buf), "SCAN%s%s%s%s",
11600 bssid ? " bssid=": "",
11601 bssid ? bssid : "",
11602 ssid ? " ssid " : "",
11603 ssid ? ssid_hex : "");
11604 if (res < 0 || res >= (int) sizeof(buf))
11605 return -1;
11606
11607 if (wpa_command(intf, buf)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011608 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not start "
11609 "scan");
11610 return 0;
11611 }
11612
11613 return 1;
11614}
11615
11616
Jouni Malinen5e5d43d2018-01-10 17:29:33 +020011617static int cmd_sta_scan_bss(struct sigma_dut *dut, struct sigma_conn *conn,
11618 struct sigma_cmd *cmd)
11619{
11620 const char *intf = get_param(cmd, "Interface");
11621 const char *bssid;
11622 char buf[4096], *pos;
11623 int freq, chan;
11624 char *ssid;
11625 char resp[100];
11626 int res;
11627 struct wpa_ctrl *ctrl;
11628
11629 bssid = get_param(cmd, "BSSID");
11630 if (!bssid) {
11631 send_resp(dut, conn, SIGMA_INVALID,
11632 "errorCode,BSSID argument is missing");
11633 return 0;
11634 }
11635
11636 ctrl = open_wpa_mon(intf);
11637 if (!ctrl) {
11638 sigma_dut_print(dut, DUT_MSG_ERROR,
11639 "Failed to open wpa_supplicant monitor connection");
11640 return -1;
11641 }
11642
11643 if (wpa_command(intf, "SCAN TYPE=ONLY")) {
11644 send_resp(dut, conn, SIGMA_ERROR,
11645 "errorCode,Could not start scan");
11646 wpa_ctrl_detach(ctrl);
11647 wpa_ctrl_close(ctrl);
11648 return 0;
11649 }
11650
11651 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
11652 buf, sizeof(buf));
11653
11654 wpa_ctrl_detach(ctrl);
11655 wpa_ctrl_close(ctrl);
11656
11657 if (res < 0) {
11658 send_resp(dut, conn, SIGMA_ERROR,
11659 "errorCode,Scan did not complete");
11660 return 0;
11661 }
11662
11663 snprintf(buf, sizeof(buf), "BSS %s", bssid);
11664 if (wpa_command_resp(intf, buf, buf, sizeof(buf)) < 0 ||
11665 strncmp(buf, "id=", 3) != 0) {
11666 send_resp(dut, conn, SIGMA_ERROR,
11667 "errorCode,Specified BSSID not found");
11668 return 0;
11669 }
11670
11671 pos = strstr(buf, "\nfreq=");
11672 if (!pos) {
11673 send_resp(dut, conn, SIGMA_ERROR,
11674 "errorCode,Channel not found");
11675 return 0;
11676 }
11677 freq = atoi(pos + 6);
11678 chan = freq_to_channel(freq);
11679
11680 pos = strstr(buf, "\nssid=");
11681 if (!pos) {
11682 send_resp(dut, conn, SIGMA_ERROR,
11683 "errorCode,SSID not found");
11684 return 0;
11685 }
11686 ssid = pos + 6;
11687 pos = strchr(ssid, '\n');
11688 if (pos)
11689 *pos = '\0';
11690 snprintf(resp, sizeof(resp), "ssid,%s,bsschannel,%d", ssid, chan);
11691 send_resp(dut, conn, SIGMA_COMPLETE, resp);
11692 return 0;
11693}
11694
11695
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011696static int cmd_sta_set_systime(struct sigma_dut *dut, struct sigma_conn *conn,
11697 struct sigma_cmd *cmd)
11698{
11699#ifdef __linux__
11700 struct timeval tv;
11701 struct tm tm;
11702 time_t t;
11703 const char *val;
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +053011704 int v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011705
11706 wpa_command(get_station_ifname(), "PMKSA_FLUSH");
11707
11708 memset(&tm, 0, sizeof(tm));
11709 val = get_param(cmd, "seconds");
11710 if (val)
11711 tm.tm_sec = atoi(val);
11712 val = get_param(cmd, "minutes");
11713 if (val)
11714 tm.tm_min = atoi(val);
11715 val = get_param(cmd, "hours");
11716 if (val)
11717 tm.tm_hour = atoi(val);
11718 val = get_param(cmd, "date");
11719 if (val)
11720 tm.tm_mday = atoi(val);
11721 val = get_param(cmd, "month");
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +053011722 if (val) {
11723 v = atoi(val);
11724 if (v < 1 || v > 12) {
11725 send_resp(dut, conn, SIGMA_INVALID,
11726 "errorCode,Invalid month");
11727 return 0;
11728 }
11729 tm.tm_mon = v - 1;
11730 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011731 val = get_param(cmd, "year");
11732 if (val) {
11733 int year = atoi(val);
11734#ifdef ANDROID
11735 if (year > 2035)
11736 year = 2035; /* years beyond 2035 not supported */
11737#endif /* ANDROID */
11738 tm.tm_year = year - 1900;
11739 }
11740 t = mktime(&tm);
11741 if (t == (time_t) -1) {
11742 send_resp(dut, conn, SIGMA_ERROR,
11743 "errorCode,Invalid date or time");
11744 return 0;
11745 }
11746
11747 memset(&tv, 0, sizeof(tv));
11748 tv.tv_sec = t;
11749
11750 if (settimeofday(&tv, NULL) < 0) {
11751 sigma_dut_print(dut, DUT_MSG_INFO, "settimeofday failed: %s",
11752 strerror(errno));
11753 send_resp(dut, conn, SIGMA_ERROR,
11754 "errorCode,Failed to set time");
11755 return 0;
11756 }
11757
11758 return 1;
11759#endif /* __linux__ */
11760
11761 return -1;
11762}
11763
11764
11765static int cmd_sta_osu(struct sigma_dut *dut, struct sigma_conn *conn,
11766 struct sigma_cmd *cmd)
11767{
11768 const char *intf = get_param(cmd, "Interface");
Jouni Malinen4c8681c2018-09-12 23:28:11 +030011769 const char *name, *osu_ssid, *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011770 int prod_ess_assoc = 1;
Jouni Malinen4c8681c2018-09-12 23:28:11 +030011771 char buf[300], bssid[100], ssid[100];
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011772 int res;
11773 struct wpa_ctrl *ctrl;
11774
11775 name = get_param(cmd, "osuFriendlyName");
Jouni Malinen4c8681c2018-09-12 23:28:11 +030011776 osu_ssid = get_param(cmd, "osu_ssid");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011777
11778 val = get_param(cmd, "ProdESSAssoc");
11779 if (val)
11780 prod_ess_assoc = atoi(val);
11781
11782 kill_dhcp_client(dut, intf);
11783 if (start_dhcp_client(dut, intf) < 0)
11784 return -2;
11785
11786 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger OSU");
11787 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
11788 res = snprintf(buf, sizeof(buf),
Jouni Malinen4c8681c2018-09-12 23:28:11 +030011789 "%s %s%s%s %s%s%s signup osu-ca.pem",
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011790 prod_ess_assoc ? "" : "-N",
11791 name ? "-O'" : "", name ? name : "",
Jouni Malinen4c8681c2018-09-12 23:28:11 +030011792 name ? "'" : "",
11793 osu_ssid ? "-o'" : "", osu_ssid ? osu_ssid : "",
11794 osu_ssid ? "'" : "");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011795
Kanchanapally, Vidyullatha12b66762015-12-31 16:46:42 +053011796 hs2_set_policy(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011797 if (run_hs20_osu(dut, buf) < 0) {
11798 FILE *f;
11799
11800 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to complete OSU");
11801
11802 f = fopen("hs20-osu-client.res", "r");
11803 if (f) {
11804 char resp[400], res[300], *pos;
11805 if (!fgets(res, sizeof(res), f))
11806 res[0] = '\0';
11807 pos = strchr(res, '\n');
11808 if (pos)
11809 *pos = '\0';
11810 fclose(f);
11811 sigma_dut_summary(dut, "hs20-osu-client provisioning failed: %s",
11812 res);
11813 snprintf(resp, sizeof(resp), "notify-send '%s'", res);
11814 if (system(resp) != 0) {
11815 }
11816 snprintf(resp, sizeof(resp),
11817 "SSID,,BSSID,,failureReason,%s", res);
11818 send_resp(dut, conn, SIGMA_COMPLETE, resp);
11819 return 0;
11820 }
11821
11822 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
11823 return 0;
11824 }
11825
11826 if (!prod_ess_assoc)
11827 goto report;
11828
11829 ctrl = open_wpa_mon(intf);
11830 if (ctrl == NULL) {
11831 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
11832 "wpa_supplicant monitor connection");
11833 return -1;
11834 }
11835
11836 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
11837 buf, sizeof(buf));
11838
11839 wpa_ctrl_detach(ctrl);
11840 wpa_ctrl_close(ctrl);
11841
11842 if (res < 0) {
11843 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to connect to "
11844 "network after OSU");
11845 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
11846 return 0;
11847 }
11848
11849report:
11850 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
11851 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
11852 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to get BSSID/SSID");
11853 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
11854 return 0;
11855 }
11856
11857 snprintf(buf, sizeof(buf), "SSID,%s,BSSID,%s", ssid, bssid);
11858 send_resp(dut, conn, SIGMA_COMPLETE, buf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011859 return 0;
11860}
11861
11862
11863static int cmd_sta_policy_update(struct sigma_dut *dut, struct sigma_conn *conn,
11864 struct sigma_cmd *cmd)
11865{
11866 const char *val;
11867 int timeout = 120;
11868
11869 val = get_param(cmd, "PolicyUpdate");
11870 if (val == NULL || atoi(val) == 0)
11871 return 1; /* No operation requested */
11872
11873 val = get_param(cmd, "Timeout");
11874 if (val)
11875 timeout = atoi(val);
11876
11877 if (timeout) {
11878 /* TODO: time out the command and return
11879 * PolicyUpdateStatus,TIMEOUT if needed. */
11880 }
11881
11882 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger policy update");
11883 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
11884 if (run_hs20_osu(dut, "pol_upd fqdn=wi-fi.org") < 0) {
11885 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,FAIL");
11886 return 0;
11887 }
11888
11889 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,SUCCESS");
11890 return 0;
11891}
11892
11893
11894static int cmd_sta_er_config(struct sigma_dut *dut, struct sigma_conn *conn,
11895 struct sigma_cmd *cmd)
11896{
11897 struct wpa_ctrl *ctrl;
11898 const char *intf = get_param(cmd, "Interface");
11899 const char *bssid = get_param(cmd, "Bssid");
11900 const char *ssid = get_param(cmd, "SSID");
11901 const char *security = get_param(cmd, "Security");
11902 const char *passphrase = get_param(cmd, "Passphrase");
11903 const char *pin = get_param(cmd, "PIN");
11904 char buf[1000];
11905 char ssid_hex[200], passphrase_hex[200];
11906 const char *keymgmt, *cipher;
11907
11908 if (intf == NULL)
11909 intf = get_main_ifname();
11910
11911 if (!bssid) {
11912 send_resp(dut, conn, SIGMA_ERROR,
11913 "ErrorCode,Missing Bssid argument");
11914 return 0;
11915 }
11916
11917 if (!ssid) {
11918 send_resp(dut, conn, SIGMA_ERROR,
11919 "ErrorCode,Missing SSID argument");
11920 return 0;
11921 }
11922
11923 if (!security) {
11924 send_resp(dut, conn, SIGMA_ERROR,
11925 "ErrorCode,Missing Security argument");
11926 return 0;
11927 }
11928
11929 if (!passphrase) {
11930 send_resp(dut, conn, SIGMA_ERROR,
11931 "ErrorCode,Missing Passphrase argument");
11932 return 0;
11933 }
11934
11935 if (!pin) {
11936 send_resp(dut, conn, SIGMA_ERROR,
11937 "ErrorCode,Missing PIN argument");
11938 return 0;
11939 }
11940
vamsi krishna8c9c1562017-05-12 15:51:46 +053011941 if (2 * strlen(ssid) >= sizeof(ssid_hex) ||
11942 2 * strlen(passphrase) >= sizeof(passphrase_hex)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011943 send_resp(dut, conn, SIGMA_ERROR,
11944 "ErrorCode,Too long SSID/passphrase");
11945 return 0;
11946 }
11947
11948 ctrl = open_wpa_mon(intf);
11949 if (ctrl == NULL) {
11950 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
11951 "wpa_supplicant monitor connection");
11952 return -2;
11953 }
11954
11955 if (strcasecmp(security, "wpa2-psk") == 0) {
11956 keymgmt = "WPA2PSK";
11957 cipher = "CCMP";
11958 } else {
11959 wpa_ctrl_detach(ctrl);
11960 wpa_ctrl_close(ctrl);
11961 send_resp(dut, conn, SIGMA_ERROR,
11962 "ErrorCode,Unsupported Security value");
11963 return 0;
11964 }
11965
11966 ascii2hexstr(ssid, ssid_hex);
11967 ascii2hexstr(passphrase, passphrase_hex);
11968 snprintf(buf, sizeof(buf), "WPS_REG %s %s %s %s %s %s",
11969 bssid, pin, ssid_hex, keymgmt, cipher, passphrase_hex);
11970
11971 if (wpa_command(intf, buf) < 0) {
11972 wpa_ctrl_detach(ctrl);
11973 wpa_ctrl_close(ctrl);
11974 send_resp(dut, conn, SIGMA_ERROR,
11975 "ErrorCode,Failed to start registrar");
11976 return 0;
11977 }
11978
11979 snprintf(dut->er_oper_bssid, sizeof(dut->er_oper_bssid), "%s", bssid);
11980 dut->er_oper_performed = 1;
11981
11982 return wps_connection_event(dut, conn, ctrl, intf, 0);
11983}
11984
11985
11986static int cmd_sta_wps_connect_pw_token(struct sigma_dut *dut,
11987 struct sigma_conn *conn,
11988 struct sigma_cmd *cmd)
11989{
11990 struct wpa_ctrl *ctrl;
11991 const char *intf = get_param(cmd, "Interface");
11992 const char *bssid = get_param(cmd, "Bssid");
11993 char buf[100];
11994
11995 if (!bssid) {
11996 send_resp(dut, conn, SIGMA_ERROR,
11997 "ErrorCode,Missing Bssid argument");
11998 return 0;
11999 }
12000
12001 ctrl = open_wpa_mon(intf);
12002 if (ctrl == NULL) {
12003 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
12004 "wpa_supplicant monitor connection");
12005 return -2;
12006 }
12007
12008 snprintf(buf, sizeof(buf), "WPS_NFC %s", bssid);
12009
12010 if (wpa_command(intf, buf) < 0) {
12011 wpa_ctrl_detach(ctrl);
12012 wpa_ctrl_close(ctrl);
12013 send_resp(dut, conn, SIGMA_ERROR,
12014 "ErrorCode,Failed to start registrar");
12015 return 0;
12016 }
12017
12018 return wps_connection_event(dut, conn, ctrl, intf, 0);
12019}
12020
12021
vamsi krishna9b144002017-09-20 13:28:13 +053012022static int cmd_start_wps_registration(struct sigma_dut *dut,
12023 struct sigma_conn *conn,
12024 struct sigma_cmd *cmd)
12025{
12026 struct wpa_ctrl *ctrl;
12027 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020012028 const char *network_mode = get_param(cmd, "network_mode");
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020012029 const char *config_method = get_param(cmd, "WPSConfigMethod");
12030 const char *role;
vamsi krishna9b144002017-09-20 13:28:13 +053012031 int res;
12032 char buf[256];
12033 const char *events[] = {
12034 "CTRL-EVENT-CONNECTED",
12035 "WPS-OVERLAP-DETECTED",
12036 "WPS-TIMEOUT",
12037 "WPS-FAIL",
12038 NULL
12039 };
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020012040 int id = 0;
vamsi krishna9b144002017-09-20 13:28:13 +053012041
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020012042 /* 60G WPS tests do not pass Interface parameter */
12043 if (!intf)
12044 intf = get_main_ifname();
12045
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020012046 if (dut->mode == SIGMA_MODE_AP)
12047 return ap_wps_registration(dut, conn, cmd);
12048
12049 if (config_method) {
12050 /* WFA_CS_WPS_PIN_KEYPAD mode is set when using the
12051 * sta_wps_enter_pin before calling start_wps_registration. */
12052 if (strcasecmp(config_method, "PBC") == 0)
12053 dut->wps_method = WFA_CS_WPS_PBC;
12054 }
12055 if (dut->wps_method == WFA_CS_WPS_NOT_READY) {
12056 send_resp(dut, conn, SIGMA_ERROR,
12057 "ErrorCode,WPS parameters not yet set");
12058 return STATUS_SENT;
12059 }
12060
12061 /* Make sure WPS is enabled (also for STA mode) */
12062 dut->wps_disable = 0;
12063
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020012064 if (dut->band == WPS_BAND_60G && network_mode &&
12065 strcasecmp(network_mode, "PBSS") == 0) {
12066 sigma_dut_print(dut, DUT_MSG_DEBUG,
12067 "Set PBSS network mode, network id %d", id);
12068 if (set_network(get_station_ifname(), id, "pbss", "1") < 0)
12069 return -2;
12070 }
12071
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020012072 if (dut->force_rsn_ie) {
12073 sigma_dut_print(dut, DUT_MSG_DEBUG, "Force RSN_IE: %d",
12074 dut->force_rsn_ie);
12075 if (sta_60g_force_rsn_ie(dut, dut->force_rsn_ie) < 0) {
12076 sigma_dut_print(dut, DUT_MSG_INFO,
12077 "Failed to force RSN_IE");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020012078 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020012079 }
12080 }
12081
vamsi krishna9b144002017-09-20 13:28:13 +053012082 ctrl = open_wpa_mon(intf);
12083 if (!ctrl) {
12084 sigma_dut_print(dut, DUT_MSG_ERROR,
12085 "Failed to open wpa_supplicant monitor connection");
12086 return -2;
12087 }
12088
12089 role = get_param(cmd, "WpsRole");
12090 if (!role) {
12091 send_resp(dut, conn, SIGMA_INVALID,
12092 "ErrorCode,WpsRole not provided");
12093 goto fail;
12094 }
12095
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020012096 if (strcasecmp(role, "Enrollee") != 0) {
12097 /* Registrar role for STA not supported */
12098 send_resp(dut, conn, SIGMA_ERROR,
12099 "ErrorCode,Unsupported WpsRole value");
12100 goto fail;
12101 }
12102
12103 if (is_60g_sigma_dut(dut)) {
12104 if (dut->wps_method == WFA_CS_WPS_PBC)
12105 snprintf(buf, sizeof(buf), "WPS_PBC");
12106 else /* WFA_CS_WPS_PIN_KEYPAD */
12107 snprintf(buf, sizeof(buf), "WPS_PIN any %s",
12108 dut->wps_pin);
12109 if (wpa_command(intf, buf) < 0) {
12110 send_resp(dut, conn, SIGMA_ERROR,
12111 "ErrorCode,Failed to start WPS");
vamsi krishna9b144002017-09-20 13:28:13 +053012112 goto fail;
12113 }
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020012114 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
12115 if (res < 0) {
12116 send_resp(dut, conn, SIGMA_ERROR,
12117 "ErrorCode,WPS connection did not complete");
12118 goto fail;
12119 }
12120 if (strstr(buf, "WPS-TIMEOUT")) {
12121 send_resp(dut, conn, SIGMA_COMPLETE, "WpsState,NoPeer");
12122 } else if (strstr(buf, "WPS-OVERLAP-DETECTED")) {
12123 send_resp(dut, conn, SIGMA_COMPLETE,
12124 "WpsState,OverlapSession");
12125 } else if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
12126 send_resp(dut, conn, SIGMA_COMPLETE,
12127 "WpsState,Successful");
12128 } else {
12129 send_resp(dut, conn, SIGMA_COMPLETE,
12130 "WpsState,Failure");
12131 }
12132 } else {
12133 if (dut->wps_method == WFA_CS_WPS_PBC) {
vamsi krishna9b144002017-09-20 13:28:13 +053012134 if (wpa_command(intf, "WPS_PBC") < 0) {
12135 send_resp(dut, conn, SIGMA_ERROR,
12136 "ErrorCode,Failed to enable PBC");
12137 goto fail;
12138 }
12139 } else {
12140 /* TODO: PIN method */
12141 send_resp(dut, conn, SIGMA_ERROR,
12142 "ErrorCode,Unsupported WpsConfigMethod value");
12143 goto fail;
12144 }
12145 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
12146 if (res < 0) {
12147 send_resp(dut, conn, SIGMA_ERROR,
12148 "ErrorCode,WPS connection did not complete");
12149 goto fail;
12150 }
12151 if (strstr(buf, "WPS-TIMEOUT")) {
12152 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,NoPeer");
12153 } else if (strstr(buf, "WPS-OVERLAP-DETECTED")) {
12154 send_resp(dut, conn, SIGMA_ERROR,
12155 "ErrorCode,OverlapSession");
12156 } else if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
12157 send_resp(dut, conn, SIGMA_COMPLETE, "Successful");
12158 } else {
12159 send_resp(dut, conn, SIGMA_ERROR,
12160 "ErrorCode,WPS operation failed");
12161 }
vamsi krishna9b144002017-09-20 13:28:13 +053012162 }
12163
12164fail:
12165 wpa_ctrl_detach(ctrl);
12166 wpa_ctrl_close(ctrl);
12167 return 0;
12168}
12169
12170
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012171static int req_intf(struct sigma_cmd *cmd)
12172{
12173 return get_param(cmd, "interface") == NULL ? -1 : 0;
12174}
12175
12176
12177void sta_register_cmds(void)
12178{
12179 sigma_dut_reg_cmd("sta_get_ip_config", req_intf,
12180 cmd_sta_get_ip_config);
12181 sigma_dut_reg_cmd("sta_set_ip_config", req_intf,
12182 cmd_sta_set_ip_config);
12183 sigma_dut_reg_cmd("sta_get_info", req_intf, cmd_sta_get_info);
12184 sigma_dut_reg_cmd("sta_get_mac_address", req_intf,
12185 cmd_sta_get_mac_address);
12186 sigma_dut_reg_cmd("sta_is_connected", req_intf, cmd_sta_is_connected);
12187 sigma_dut_reg_cmd("sta_verify_ip_connection", req_intf,
12188 cmd_sta_verify_ip_connection);
12189 sigma_dut_reg_cmd("sta_get_bssid", req_intf, cmd_sta_get_bssid);
12190 sigma_dut_reg_cmd("sta_set_encryption", req_intf,
12191 cmd_sta_set_encryption);
12192 sigma_dut_reg_cmd("sta_set_psk", req_intf, cmd_sta_set_psk);
12193 sigma_dut_reg_cmd("sta_set_eaptls", req_intf, cmd_sta_set_eaptls);
12194 sigma_dut_reg_cmd("sta_set_eapttls", req_intf, cmd_sta_set_eapttls);
12195 sigma_dut_reg_cmd("sta_set_eapsim", req_intf, cmd_sta_set_eapsim);
12196 sigma_dut_reg_cmd("sta_set_peap", req_intf, cmd_sta_set_peap);
12197 sigma_dut_reg_cmd("sta_set_eapfast", req_intf, cmd_sta_set_eapfast);
12198 sigma_dut_reg_cmd("sta_set_eapaka", req_intf, cmd_sta_set_eapaka);
12199 sigma_dut_reg_cmd("sta_set_eapakaprime", req_intf,
12200 cmd_sta_set_eapakaprime);
12201 sigma_dut_reg_cmd("sta_set_security", req_intf, cmd_sta_set_security);
12202 sigma_dut_reg_cmd("sta_set_uapsd", req_intf, cmd_sta_set_uapsd);
12203 /* TODO: sta_set_ibss */
12204 /* TODO: sta_set_mode */
12205 sigma_dut_reg_cmd("sta_set_wmm", req_intf, cmd_sta_set_wmm);
12206 sigma_dut_reg_cmd("sta_associate", req_intf, cmd_sta_associate);
12207 /* TODO: sta_up_load */
12208 sigma_dut_reg_cmd("sta_preset_testparameters", req_intf,
12209 cmd_sta_preset_testparameters);
12210 /* TODO: sta_set_system */
12211 sigma_dut_reg_cmd("sta_set_11n", req_intf, cmd_sta_set_11n);
12212 /* TODO: sta_set_rifs_test */
12213 sigma_dut_reg_cmd("sta_set_wireless", req_intf, cmd_sta_set_wireless);
12214 sigma_dut_reg_cmd("sta_send_addba", req_intf, cmd_sta_send_addba);
12215 /* TODO: sta_send_coexist_mgmt */
12216 sigma_dut_reg_cmd("sta_disconnect", req_intf, cmd_sta_disconnect);
12217 sigma_dut_reg_cmd("sta_reassoc", req_intf, cmd_sta_reassoc);
12218 sigma_dut_reg_cmd("sta_reassociate", req_intf, cmd_sta_reassoc);
12219 sigma_dut_reg_cmd("sta_reset_default", req_intf,
12220 cmd_sta_reset_default);
12221 sigma_dut_reg_cmd("sta_send_frame", req_intf, cmd_sta_send_frame);
12222 sigma_dut_reg_cmd("sta_set_macaddr", req_intf, cmd_sta_set_macaddr);
12223 sigma_dut_reg_cmd("sta_set_rfeature", req_intf, cmd_sta_set_rfeature);
12224 sigma_dut_reg_cmd("sta_set_radio", req_intf, cmd_sta_set_radio);
12225 sigma_dut_reg_cmd("sta_set_pwrsave", req_intf, cmd_sta_set_pwrsave);
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020012226 sigma_dut_reg_cmd("sta_set_power_save", req_intf, cmd_sta_set_pwrsave);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012227 sigma_dut_reg_cmd("sta_bssid_pool", req_intf, cmd_sta_bssid_pool);
12228 sigma_dut_reg_cmd("sta_reset_parm", req_intf, cmd_sta_reset_parm);
12229 sigma_dut_reg_cmd("sta_get_key", req_intf, cmd_sta_get_key);
12230 sigma_dut_reg_cmd("sta_hs2_associate", req_intf,
12231 cmd_sta_hs2_associate);
Jouni Malinenb639f1c2018-09-13 02:39:46 +030012232 sigma_dut_reg_cmd("sta_hs2_venue_info", req_intf,
12233 cmd_sta_hs2_venue_info);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012234 sigma_dut_reg_cmd("sta_add_credential", req_intf,
12235 cmd_sta_add_credential);
12236 sigma_dut_reg_cmd("sta_scan", req_intf, cmd_sta_scan);
Jouni Malinen5e5d43d2018-01-10 17:29:33 +020012237 sigma_dut_reg_cmd("sta_scan_bss", req_intf, cmd_sta_scan_bss);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012238 sigma_dut_reg_cmd("sta_set_systime", NULL, cmd_sta_set_systime);
12239 sigma_dut_reg_cmd("sta_osu", req_intf, cmd_sta_osu);
12240 sigma_dut_reg_cmd("sta_policy_update", req_intf, cmd_sta_policy_update);
12241 sigma_dut_reg_cmd("sta_er_config", NULL, cmd_sta_er_config);
12242 sigma_dut_reg_cmd("sta_wps_connect_pw_token", req_intf,
12243 cmd_sta_wps_connect_pw_token);
Jouni Malinen82905202018-04-29 17:20:10 +030012244 sigma_dut_reg_cmd("sta_exec_action", NULL, cmd_sta_exec_action);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012245 sigma_dut_reg_cmd("sta_get_events", req_intf, cmd_sta_get_events);
12246 sigma_dut_reg_cmd("sta_get_parameter", req_intf, cmd_sta_get_parameter);
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020012247 sigma_dut_reg_cmd("start_wps_registration", NULL,
vamsi krishna9b144002017-09-20 13:28:13 +053012248 cmd_start_wps_registration);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012249}