blob: e6a1ecee2dc54a60ff600d7c921be221422a3f62 [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"
Jouni Malinencd4e3c32015-10-29 12:39:56 +020035
36/* Temporary files for sta_send_addba */
37#define VI_QOS_TMP_FILE "/tmp/vi-qos.tmp"
38#define VI_QOS_FILE "/tmp/vi-qos.txt"
39#define VI_QOS_REFFILE "/etc/vi-qos.txt"
40
41/*
42 * MTU for Ethernet need to take into account 8-byte SNAP header
43 * to be added when encapsulating Ethernet frame into 802.11
44 */
45#ifndef IEEE80211_MAX_DATA_LEN_DMG
46#define IEEE80211_MAX_DATA_LEN_DMG 7920
47#endif
48#ifndef IEEE80211_SNAP_LEN_DMG
49#define IEEE80211_SNAP_LEN_DMG 8
50#endif
51
Ashwini Patil00402582017-04-13 12:29:39 +053052#define NON_PREF_CH_LIST_SIZE 100
Ashwini Patil5acd7382017-04-13 15:55:04 +053053#define NEIGHBOR_REPORT_SIZE 1000
54#define DEFAULT_NEIGHBOR_BSSID_INFO "17"
55#define DEFAULT_NEIGHBOR_PHY_TYPE "1"
Ashwini Patil00402582017-04-13 12:29:39 +053056
Jouni Malinencd4e3c32015-10-29 12:39:56 +020057extern char *sigma_wpas_ctrl;
58extern char *sigma_cert_path;
59extern enum driver_type wifi_chip_type;
60extern char *sigma_radio_ifname[];
61
Lior David0fe101e2017-03-09 16:09:50 +020062#ifdef __linux__
63#define WIL_WMI_MAX_PAYLOAD 248
64#define WIL_WMI_BF_TRIG_CMDID 0x83a
65
66struct wil_wmi_header {
67 uint8_t mid;
68 uint8_t reserved;
69 uint16_t cmd;
70 uint32_t ts;
71} __attribute__((packed));
72
73enum wil_wmi_bf_trig_type {
74 WIL_WMI_SLS,
75 WIL_WMI_BRP_RX,
76 WIL_WMI_BRP_TX,
77};
78
79struct wil_wmi_bf_trig_cmd {
80 /* enum wil_wmi_bf_trig_type */
81 uint32_t bf_type;
82 /* cid when type == WMI_BRP_RX */
83 uint32_t sta_id;
84 uint32_t reserved;
85 /* mac address when type = WIL_WMI_SLS */
86 uint8_t dest_mac[6];
87} __attribute__((packed));
88#endif /* __linux__ */
Jouni Malinencd4e3c32015-10-29 12:39:56 +020089
90#ifdef ANDROID
91
92static int add_ipv6_rule(struct sigma_dut *dut, const char *ifname);
93
94#define ANDROID_KEYSTORE_GET 'g'
95#define ANDROID_KEYSTORE_GET_PUBKEY 'b'
96
97static int android_keystore_get(char cmd, const char *key, unsigned char *val)
98{
Jouni Malinencd4e3c32015-10-29 12:39:56 +020099 /* Android 4.3 changed keystore design, so need to use keystore_get() */
100#ifndef KEYSTORE_MESSAGE_SIZE
101#define KEYSTORE_MESSAGE_SIZE 65535
102#endif /* KEYSTORE_MESSAGE_SIZE */
103
104 ssize_t len;
105 uint8_t *value = NULL;
106
107 __android_log_print(ANDROID_LOG_DEBUG, "sigma_dut",
108 "keystore command '%c' key '%s' --> keystore_get",
109 cmd, key);
110
111 len = keystore_get(key, strlen(key), &value);
112 if (len < 0) {
113 __android_log_print(ANDROID_LOG_DEBUG, "sigma_dut",
114 "keystore_get() failed");
115 return -1;
116 }
117
118 if (len > KEYSTORE_MESSAGE_SIZE)
119 len = KEYSTORE_MESSAGE_SIZE;
120 memcpy(val, value, len);
121 free(value);
122 return len;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200123}
124#endif /* ANDROID */
125
126
127int set_ps(const char *intf, struct sigma_dut *dut, int enabled)
128{
129#ifdef __linux__
130 char buf[100];
131
132 if (wifi_chip_type == DRIVER_WCN) {
133 if (enabled) {
134 snprintf(buf, sizeof(buf), "iwpriv wlan0 dump 906");
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530135 if (system(buf) != 0)
136 goto set_power_save;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200137 } else {
138 snprintf(buf, sizeof(buf), "iwpriv wlan0 dump 905");
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530139 if (system(buf) != 0)
140 goto set_power_save;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200141 snprintf(buf, sizeof(buf), "iwpriv wlan0 dump 912");
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530142 if (system(buf) != 0)
143 goto set_power_save;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200144 }
145
146 return 0;
147 }
148
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530149set_power_save:
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200150 snprintf(buf, sizeof(buf), "./iw dev %s set power_save %s",
151 intf, enabled ? "on" : "off");
152 if (system(buf) != 0) {
153 snprintf(buf, sizeof(buf), "iw dev %s set power_save %s",
154 intf, enabled ? "on" : "off");
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530155 if (system(buf) != 0) {
156 sigma_dut_print(dut, DUT_MSG_ERROR,
157 "Failed to set power save %s",
158 enabled ? "on" : "off");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200159 return -1;
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530160 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200161 }
162
163 return 0;
164#else /* __linux__ */
165 return -1;
166#endif /* __linux__ */
167}
168
169
Lior Davidcc88b562017-01-03 18:52:09 +0200170#ifdef __linux__
Lior David0fe101e2017-03-09 16:09:50 +0200171
Lior Davidcc88b562017-01-03 18:52:09 +0200172static int wil6210_get_debugfs_dir(struct sigma_dut *dut, char *path,
173 size_t len)
174{
175 DIR *dir, *wil_dir;
176 struct dirent *entry;
177 int ret = -1;
178 const char *root_path = "/sys/kernel/debug/ieee80211";
179
180 dir = opendir(root_path);
181 if (!dir)
182 return -2;
183
184 while ((entry = readdir(dir))) {
185 if (strcmp(entry->d_name, ".") == 0 ||
186 strcmp(entry->d_name, "..") == 0)
187 continue;
188
189 if (snprintf(path, len, "%s/%s/wil6210",
190 root_path, entry->d_name) >= (int) len) {
191 ret = -3;
192 break;
193 }
194
195 wil_dir = opendir(path);
196 if (wil_dir) {
197 closedir(wil_dir);
198 ret = 0;
199 break;
200 }
201 }
202
203 closedir(dir);
204 return ret;
205}
Lior David0fe101e2017-03-09 16:09:50 +0200206
207
208static int wil6210_wmi_send(struct sigma_dut *dut, uint16_t command,
209 void *payload, uint16_t length)
210{
211 struct {
212 struct wil_wmi_header hdr;
213 char payload[WIL_WMI_MAX_PAYLOAD];
214 } __attribute__((packed)) cmd;
215 char buf[128], fname[128];
216 size_t towrite, written;
217 FILE *f;
218
219 if (length > WIL_WMI_MAX_PAYLOAD) {
220 sigma_dut_print(dut, DUT_MSG_ERROR,
221 "payload too large(%u, max %u)",
222 length, WIL_WMI_MAX_PAYLOAD);
223 return -1;
224 }
225
226 memset(&cmd.hdr, 0, sizeof(cmd.hdr));
227 cmd.hdr.cmd = command;
228 memcpy(cmd.payload, payload, length);
229
230 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
231 sigma_dut_print(dut, DUT_MSG_ERROR,
232 "failed to get wil6210 debugfs dir");
233 return -1;
234 }
235
236 snprintf(fname, sizeof(fname), "%s/wmi_send", buf);
237 f = fopen(fname, "wb");
238 if (!f) {
239 sigma_dut_print(dut, DUT_MSG_ERROR,
240 "failed to open: %s", fname);
241 return -1;
242 }
243
244 towrite = sizeof(cmd.hdr) + length;
245 written = fwrite(&cmd, 1, towrite, f);
246 fclose(f);
247 if (written != towrite) {
248 sigma_dut_print(dut, DUT_MSG_ERROR,
249 "failed to send wmi %u", command);
250 return -1;
251 }
252
253 return 0;
254}
255
256
257static int wil6210_get_sta_info_field(struct sigma_dut *dut, const char *bssid,
258 const char *pattern, unsigned int *field)
259{
260 char buf[128], fname[128];
261 FILE *f;
262 regex_t re;
263 regmatch_t m[2];
264 int rc, ret = -1;
265
266 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
267 sigma_dut_print(dut, DUT_MSG_ERROR,
268 "failed to get wil6210 debugfs dir");
269 return -1;
270 }
271
272 snprintf(fname, sizeof(fname), "%s/stations", buf);
273 f = fopen(fname, "r");
274 if (!f) {
275 sigma_dut_print(dut, DUT_MSG_ERROR,
276 "failed to open: %s", fname);
277 return -1;
278 }
279
280 if (regcomp(&re, pattern, REG_EXTENDED)) {
281 sigma_dut_print(dut, DUT_MSG_ERROR,
282 "regcomp failed: %s", pattern);
283 goto out;
284 }
285
286 /*
287 * find the entry for the mac address
288 * line is of the form: [n] 11:22:33:44:55:66 state AID aid
289 */
290 while (fgets(buf, sizeof(buf), f)) {
291 if (strcasestr(buf, bssid)) {
292 /* extract the field (CID/AID/state) */
293 rc = regexec(&re, buf, 2, m, 0);
294 if (!rc && (m[1].rm_so >= 0)) {
295 buf[m[1].rm_eo] = 0;
296 *field = atoi(&buf[m[1].rm_so]);
297 ret = 0;
298 break;
299 }
300 }
301 }
302
303 regfree(&re);
304 if (ret)
305 sigma_dut_print(dut, DUT_MSG_ERROR,
306 "could not extract field");
307
308out:
309 fclose(f);
310
311 return ret;
312}
313
314
315static int wil6210_get_cid(struct sigma_dut *dut, const char *bssid,
316 unsigned int *cid)
317{
318 const char *pattern = "\\[([0-9]+)\\]";
319
320 return wil6210_get_sta_info_field(dut, bssid, pattern, cid);
321}
322
323
324static int wil6210_send_brp_rx(struct sigma_dut *dut, const char *mac,
325 int l_rx)
326{
Rakesh Sunki556237d2017-03-30 14:49:31 -0700327 struct wil_wmi_bf_trig_cmd cmd;
Lior David0fe101e2017-03-09 16:09:50 +0200328 unsigned int cid;
329
Rakesh Sunki556237d2017-03-30 14:49:31 -0700330 memset(&cmd, 0, sizeof(cmd));
331
Lior David0fe101e2017-03-09 16:09:50 +0200332 if (wil6210_get_cid(dut, mac, &cid))
333 return -1;
334
335 cmd.bf_type = WIL_WMI_BRP_RX;
336 cmd.sta_id = cid;
337 /* training length (l_rx) is ignored, FW always uses length 16 */
338 return wil6210_wmi_send(dut, WIL_WMI_BF_TRIG_CMDID,
339 &cmd, sizeof(cmd));
340}
341
342
343static int wil6210_send_sls(struct sigma_dut *dut, const char *mac)
344{
Rakesh Sunki556237d2017-03-30 14:49:31 -0700345 struct wil_wmi_bf_trig_cmd cmd;
346
347 memset(&cmd, 0, sizeof(cmd));
Lior David0fe101e2017-03-09 16:09:50 +0200348
349 if (parse_mac_address(dut, mac, (unsigned char *)&cmd.dest_mac))
350 return -1;
351
352 cmd.bf_type = WIL_WMI_SLS;
353 return wil6210_wmi_send(dut, WIL_WMI_BF_TRIG_CMDID,
354 &cmd, sizeof(cmd));
355}
356
Lior Davidcc88b562017-01-03 18:52:09 +0200357#endif /* __linux__ */
358
359
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200360static void static_ip_file(int proto, const char *addr, const char *mask,
361 const char *gw)
362{
363 if (proto) {
364 FILE *f = fopen("static-ip", "w");
365 if (f) {
366 fprintf(f, "%d %s %s %s\n", proto, addr,
367 mask ? mask : "N/A",
368 gw ? gw : "N/A");
369 fclose(f);
370 }
371 } else {
372 unlink("static-ip");
373 }
374}
375
376
377static int send_neighbor_request(struct sigma_dut *dut, const char *intf,
378 const char *ssid)
379{
380#ifdef __linux__
381 char buf[100];
382
383 snprintf(buf, sizeof(buf), "iwpriv %s neighbor %s",
384 intf, ssid);
385 sigma_dut_print(dut, DUT_MSG_INFO, "Request: %s", buf);
386
387 if (system(buf) != 0) {
388 sigma_dut_print(dut, DUT_MSG_ERROR,
389 "iwpriv neighbor request failed");
390 return -1;
391 }
392
393 sigma_dut_print(dut, DUT_MSG_INFO, "iwpriv neighbor request send");
394
395 return 0;
396#else /* __linux__ */
397 return -1;
398#endif /* __linux__ */
399}
400
401
402static int send_trans_mgmt_query(struct sigma_dut *dut, const char *intf,
Ashwini Patil5acd7382017-04-13 15:55:04 +0530403 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200404{
Ashwini Patil5acd7382017-04-13 15:55:04 +0530405 const char *val;
406 int reason_code = 0;
407 char buf[1024];
408
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200409 /*
410 * In the earlier builds we used WNM_QUERY and in later
411 * builds used WNM_BSS_QUERY.
412 */
413
Ashwini Patil5acd7382017-04-13 15:55:04 +0530414 val = get_param(cmd, "BTMQuery_Reason_Code");
415 if (val)
416 reason_code = atoi(val);
417
418 val = get_param(cmd, "Cand_List");
419 if (val && atoi(val) == 1 && dut->btm_query_cand_list) {
420 snprintf(buf, sizeof(buf), "WNM_BSS_QUERY %d%s", reason_code,
421 dut->btm_query_cand_list);
422 free(dut->btm_query_cand_list);
423 dut->btm_query_cand_list = NULL;
424 } else {
425 snprintf(buf, sizeof(buf), "WNM_BSS_QUERY %d", reason_code);
426 }
427
428 if (wpa_command(intf, buf) != 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200429 sigma_dut_print(dut, DUT_MSG_ERROR,
430 "transition management query failed");
431 return -1;
432 }
433
434 sigma_dut_print(dut, DUT_MSG_DEBUG,
435 "transition management query sent");
436
437 return 0;
438}
439
440
441int is_ip_addr(const char *str)
442{
443 const char *pos = str;
444 struct in_addr addr;
445
446 while (*pos) {
447 if (*pos != '.' && (*pos < '0' || *pos > '9'))
448 return 0;
449 pos++;
450 }
451
452 return inet_aton(str, &addr);
453}
454
455
456int is_ipv6_addr(const char *str)
457{
458 struct sockaddr_in6 addr;
459
460 return inet_pton(AF_INET6, str, &(addr.sin6_addr));
461}
462
463
464int get_ip_config(struct sigma_dut *dut, const char *ifname, char *buf,
465 size_t buf_len)
466{
vamsi krishnaa11d0732018-05-16 12:19:48 +0530467 char tmp[256];
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200468 char ip[16], mask[15], dns[16], sec_dns[16];
469 int is_dhcp = 0;
470 int s;
471#ifdef ANDROID
472 char prop[PROPERTY_VALUE_MAX];
vamsi krishnaa11d0732018-05-16 12:19:48 +0530473#else /* ANDROID */
474 FILE *f;
475#ifdef __linux__
476 const char *str_ps;
477#endif /* __linux__ */
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200478#endif /* ANDROID */
479
480 ip[0] = '\0';
481 mask[0] = '\0';
482 dns[0] = '\0';
483 sec_dns[0] = '\0';
484
485 s = socket(PF_INET, SOCK_DGRAM, 0);
486 if (s >= 0) {
487 struct ifreq ifr;
488 struct sockaddr_in saddr;
489
490 memset(&ifr, 0, sizeof(ifr));
Peng Xub8fc5cc2017-05-10 17:27:28 -0700491 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200492 if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
493 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to get "
494 "%s IP address: %s",
495 ifname, strerror(errno));
496 } else {
497 memcpy(&saddr, &ifr.ifr_addr,
498 sizeof(struct sockaddr_in));
Peng Xub8fc5cc2017-05-10 17:27:28 -0700499 strlcpy(ip, inet_ntoa(saddr.sin_addr), sizeof(ip));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200500 }
501
502 if (ioctl(s, SIOCGIFNETMASK, &ifr) == 0) {
503 memcpy(&saddr, &ifr.ifr_addr,
504 sizeof(struct sockaddr_in));
Peng Xub8fc5cc2017-05-10 17:27:28 -0700505 strlcpy(mask, inet_ntoa(saddr.sin_addr), sizeof(mask));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200506 }
507 close(s);
508 }
509
510#ifdef ANDROID
511 snprintf(tmp, sizeof(tmp), "dhcp.%s.pid", ifname);
512 if (property_get(tmp, prop, NULL) != 0 && atoi(prop) > 0) {
513 snprintf(tmp, sizeof(tmp), "dhcp.%s.result", ifname);
514 if (property_get(tmp, prop, NULL) != 0 &&
515 strcmp(prop, "ok") == 0) {
516 snprintf(tmp, sizeof(tmp), "dhcp.%s.ipaddress",
517 ifname);
518 if (property_get(tmp, prop, NULL) != 0 &&
519 strcmp(ip, prop) == 0)
520 is_dhcp = 1;
521 }
522 }
523
524 snprintf(tmp, sizeof(tmp), "dhcp.%s.dns1", ifname);
Peng Xub8fc5cc2017-05-10 17:27:28 -0700525 if (property_get(tmp, prop, NULL) != 0)
526 strlcpy(dns, prop, sizeof(dns));
527 else if (property_get("net.dns1", prop, NULL) != 0)
528 strlcpy(dns, prop, sizeof(dns));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200529
530 snprintf(tmp, sizeof(tmp), "dhcp.%s.dns2", ifname);
Peng Xub8fc5cc2017-05-10 17:27:28 -0700531 if (property_get(tmp, prop, NULL) != 0)
532 strlcpy(sec_dns, prop, sizeof(sec_dns));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200533#else /* ANDROID */
534#ifdef __linux__
Sarvepalli, Rajesh Babua76c6442016-03-18 20:34:26 +0530535 if (get_driver_type() == DRIVER_OPENWRT)
536 str_ps = "ps -w";
537 else
538 str_ps = "ps ax";
539 snprintf(tmp, sizeof(tmp),
540 "%s | grep dhclient | grep -v grep | grep -q %s",
541 str_ps, ifname);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200542 if (system(tmp) == 0)
543 is_dhcp = 1;
544 else {
Sarvepalli, Rajesh Babua76c6442016-03-18 20:34:26 +0530545 snprintf(tmp, sizeof(tmp),
546 "%s | grep udhcpc | grep -v grep | grep -q %s",
547 str_ps, ifname);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200548 if (system(tmp) == 0)
549 is_dhcp = 1;
550 else {
Sarvepalli, Rajesh Babua76c6442016-03-18 20:34:26 +0530551 snprintf(tmp, sizeof(tmp),
552 "%s | grep dhcpcd | grep -v grep | grep -q %s",
553 str_ps, ifname);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200554 if (system(tmp) == 0)
555 is_dhcp = 1;
556 }
557 }
558#endif /* __linux__ */
559
560 f = fopen("/etc/resolv.conf", "r");
561 if (f) {
vamsi krishnaa11d0732018-05-16 12:19:48 +0530562 char *pos, *pos2;
563
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200564 while (fgets(tmp, sizeof(tmp), f)) {
565 if (strncmp(tmp, "nameserver", 10) != 0)
566 continue;
567 pos = tmp + 10;
568 while (*pos == ' ' || *pos == '\t')
569 pos++;
570 pos2 = pos;
571 while (*pos2) {
572 if (*pos2 == '\n' || *pos2 == '\r') {
573 *pos2 = '\0';
574 break;
575 }
576 pos2++;
577 }
Peng Xub8fc5cc2017-05-10 17:27:28 -0700578 if (!dns[0])
579 strlcpy(dns, pos, sizeof(dns));
580 else if (!sec_dns[0])
581 strlcpy(sec_dns, pos, sizeof(sec_dns));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200582 }
583 fclose(f);
584 }
585#endif /* ANDROID */
586
587 snprintf(buf, buf_len, "dhcp,%d,ip,%s,mask,%s,primary-dns,%s",
588 is_dhcp, ip, mask, dns);
589 buf[buf_len - 1] = '\0';
590
591 return 0;
592}
593
594
595
596
597int get_ipv6_config(struct sigma_dut *dut, const char *ifname, char *buf,
598 size_t buf_len)
599{
600#ifdef __linux__
601#ifdef ANDROID
602 char cmd[200], result[1000], *pos, *end;
603 FILE *f;
604 size_t len;
605
606 snprintf(cmd, sizeof(cmd), "ip addr show dev %s scope global", ifname);
607 f = popen(cmd, "r");
608 if (f == NULL)
609 return -1;
610 len = fread(result, 1, sizeof(result) - 1, f);
611 pclose(f);
612 if (len == 0)
613 return -1;
614 result[len] = '\0';
615 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s result: %s\n", cmd, result);
616
617 pos = strstr(result, "inet6 ");
618 if (pos == NULL)
619 return -1;
620 pos += 6;
621 end = strchr(pos, ' ');
622 if (end)
623 *end = '\0';
624 end = strchr(pos, '/');
625 if (end)
626 *end = '\0';
627 snprintf(buf, buf_len, "ip,%s", pos);
628 buf[buf_len - 1] = '\0';
629 return 0;
630#else /* ANDROID */
631 struct ifaddrs *ifaddr, *ifa;
632 int res, found = 0;
633 char host[NI_MAXHOST];
634
635 if (getifaddrs(&ifaddr) < 0) {
636 perror("getifaddrs");
637 return -1;
638 }
639
640 for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
641 if (strcasecmp(ifname, ifa->ifa_name) != 0)
642 continue;
643 if (ifa->ifa_addr == NULL ||
644 ifa->ifa_addr->sa_family != AF_INET6)
645 continue;
646
647 res = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in6),
648 host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
649 if (res != 0) {
650 sigma_dut_print(dut, DUT_MSG_DEBUG, "getnameinfo: %s",
651 gai_strerror(res));
652 continue;
653 }
654 if (strncmp(host, "fe80::", 6) == 0)
655 continue; /* skip link-local */
656
657 sigma_dut_print(dut, DUT_MSG_DEBUG, "ifaddr: %s", host);
658 found = 1;
659 break;
660 }
661
662 freeifaddrs(ifaddr);
663
664 if (found) {
665 char *pos;
666 pos = strchr(host, '%');
667 if (pos)
668 *pos = '\0';
669 snprintf(buf, buf_len, "ip,%s", host);
670 buf[buf_len - 1] = '\0';
671 return 0;
672 }
673
674#endif /* ANDROID */
675#endif /* __linux__ */
676 return -1;
677}
678
679
680static int cmd_sta_get_ip_config(struct sigma_dut *dut,
681 struct sigma_conn *conn,
682 struct sigma_cmd *cmd)
683{
684 const char *intf = get_param(cmd, "Interface");
685 const char *ifname;
686 char buf[200];
687 const char *val;
688 int type = 1;
689
690 if (intf == NULL)
691 return -1;
692
693 if (strcmp(intf, get_main_ifname()) == 0)
694 ifname = get_station_ifname();
695 else
696 ifname = intf;
697
698 /*
699 * UCC may assume the IP address to be available immediately after
700 * association without trying to run sta_get_ip_config multiple times.
701 * Sigma CAPI does not specify this command as a block command that
702 * would wait for the address to become available, but to pass tests
703 * more reliably, it looks like such a wait may be needed here.
704 */
705 if (wait_ip_addr(dut, ifname, 15) < 0) {
706 sigma_dut_print(dut, DUT_MSG_INFO, "Could not get IP address "
707 "for sta_get_ip_config");
708 /*
709 * Try to continue anyway since many UCC tests do not really
710 * care about the return value from here..
711 */
712 }
713
714 val = get_param(cmd, "Type");
715 if (val)
716 type = atoi(val);
717 if (type == 2 || dut->last_set_ip_config_ipv6) {
718 int i;
719
720 /*
721 * Since we do not have proper wait for IPv6 addresses, use a
722 * fixed two second delay here as a workaround for UCC script
723 * assuming IPv6 address is available when this command returns.
724 * Some scripts did not use Type,2 properly for IPv6, so include
725 * also the cases where the previous sta_set_ip_config indicated
726 * use of IPv6.
727 */
728 sigma_dut_print(dut, DUT_MSG_INFO, "Wait up to extra ten seconds in sta_get_ip_config for IPv6 address");
729 for (i = 0; i < 10; i++) {
730 sleep(1);
731 if (get_ipv6_config(dut, ifname, buf, sizeof(buf)) == 0)
732 {
733 sigma_dut_print(dut, DUT_MSG_INFO, "Found IPv6 address");
734 send_resp(dut, conn, SIGMA_COMPLETE, buf);
735#ifdef ANDROID
736 sigma_dut_print(dut, DUT_MSG_INFO,
737 "Adding IPv6 rule on Android");
738 add_ipv6_rule(dut, intf);
739#endif /* ANDROID */
740
741 return 0;
742 }
743 }
744 }
745 if (type == 1) {
746 if (get_ip_config(dut, ifname, buf, sizeof(buf)) < 0)
747 return -2;
748 } else if (type == 2) {
749 if (get_ipv6_config(dut, ifname, buf, sizeof(buf)) < 0)
750 return -2;
751 } else {
752 send_resp(dut, conn, SIGMA_ERROR,
753 "errorCode,Unsupported address type");
754 return 0;
755 }
756
757 send_resp(dut, conn, SIGMA_COMPLETE, buf);
758 return 0;
759}
760
761
762static void kill_dhcp_client(struct sigma_dut *dut, const char *ifname)
763{
764#ifdef __linux__
765 char buf[200];
766 char path[128];
767 struct stat s;
768
769#ifdef ANDROID
770 snprintf(path, sizeof(path), "/data/misc/dhcp/dhcpcd-%s.pid", ifname);
771#else /* ANDROID */
772 snprintf(path, sizeof(path), "/var/run/dhclient-%s.pid", ifname);
773#endif /* ANDROID */
774 if (stat(path, &s) == 0) {
775 snprintf(buf, sizeof(buf), "kill `cat %s`", path);
776 sigma_dut_print(dut, DUT_MSG_INFO,
777 "Kill previous DHCP client: %s", buf);
778 if (system(buf) != 0)
779 sigma_dut_print(dut, DUT_MSG_INFO,
780 "Failed to kill DHCP client");
781 unlink(path);
782 sleep(1);
783 } else {
784 snprintf(path, sizeof(path), "/var/run/dhcpcd-%s.pid", ifname);
785
786 if (stat(path, &s) == 0) {
787 snprintf(buf, sizeof(buf), "kill `cat %s`", path);
788 sigma_dut_print(dut, DUT_MSG_INFO,
789 "Kill previous DHCP client: %s", buf);
790 if (system(buf) != 0)
791 sigma_dut_print(dut, DUT_MSG_INFO,
792 "Failed to kill DHCP client");
793 unlink(path);
794 sleep(1);
795 }
796 }
797#endif /* __linux__ */
798}
799
800
801static int start_dhcp_client(struct sigma_dut *dut, const char *ifname)
802{
803#ifdef __linux__
804 char buf[200];
805
806#ifdef ANDROID
Purushottam Kushwaha46d64262016-08-23 17:57:53 +0530807 if (access("/system/bin/dhcpcd", F_OK) != -1) {
808 snprintf(buf, sizeof(buf),
809 "/system/bin/dhcpcd -b %s", ifname);
810 } else if (access("/system/bin/dhcptool", F_OK) != -1) {
811 snprintf(buf, sizeof(buf), "/system/bin/dhcptool %s &", ifname);
812 } else {
813 sigma_dut_print(dut, DUT_MSG_ERROR,
814 "DHCP client program missing");
815 return 0;
816 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200817#else /* ANDROID */
818 snprintf(buf, sizeof(buf),
819 "dhclient -nw -pf /var/run/dhclient-%s.pid %s",
820 ifname, ifname);
821#endif /* ANDROID */
822 sigma_dut_print(dut, DUT_MSG_INFO, "Start DHCP client: %s", buf);
823 if (system(buf) != 0) {
824 snprintf(buf, sizeof(buf), "dhcpcd -t 0 %s &", ifname);
825 if (system(buf) != 0) {
826 sigma_dut_print(dut, DUT_MSG_INFO,
827 "Failed to start DHCP client");
828#ifndef ANDROID
829 return -1;
830#endif /* ANDROID */
831 }
832 }
833#endif /* __linux__ */
834
835 return 0;
836}
837
838
839static int clear_ip_addr(struct sigma_dut *dut, const char *ifname)
840{
841#ifdef __linux__
842 char buf[200];
843
844 snprintf(buf, sizeof(buf), "ip addr flush dev %s", ifname);
845 if (system(buf) != 0) {
846 sigma_dut_print(dut, DUT_MSG_INFO,
847 "Failed to clear IP addresses");
848 return -1;
849 }
850#endif /* __linux__ */
851
852 return 0;
853}
854
855
856#ifdef ANDROID
857static int add_ipv6_rule(struct sigma_dut *dut, const char *ifname)
858{
859 char cmd[200], *result, *pos;
860 FILE *fp;
Pradeep Reddy POTTETIf58a1fe2016-10-13 17:22:03 +0530861 int tableid;
862 size_t len, result_len = 1000;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200863
864 snprintf(cmd, sizeof(cmd), "ip -6 route list table all | grep %s",
865 ifname);
866 fp = popen(cmd, "r");
867 if (fp == NULL)
868 return -1;
869
870 result = malloc(result_len);
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +0530871 if (result == NULL) {
872 fclose(fp);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200873 return -1;
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +0530874 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200875
Pradeep Reddy POTTETIf58a1fe2016-10-13 17:22:03 +0530876 len = fread(result, 1, result_len - 1, fp);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200877 fclose(fp);
878
879 if (len == 0) {
880 free(result);
881 return -1;
882 }
Pradeep Reddy POTTETIf58a1fe2016-10-13 17:22:03 +0530883 result[len] = '\0';
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200884
885 pos = strstr(result, "table ");
886 if (pos == NULL) {
887 free(result);
888 return -1;
889 }
890
891 pos += strlen("table ");
892 tableid = atoi(pos);
893 if (tableid != 0) {
894 if (system("ip -6 rule del prio 22000") != 0) {
895 /* ignore any error */
896 }
897 snprintf(cmd, sizeof(cmd),
898 "ip -6 rule add from all lookup %d prio 22000",
899 tableid);
900 if (system(cmd) != 0) {
901 sigma_dut_print(dut, DUT_MSG_INFO,
902 "Failed to run %s", cmd);
903 free(result);
904 return -1;
905 }
906 } else {
907 sigma_dut_print(dut, DUT_MSG_INFO,
908 "No Valid Table Id found %s", pos);
909 free(result);
910 return -1;
911 }
912 free(result);
913
914 return 0;
915}
916#endif /* ANDROID */
917
918
Ankita Bajaj1bde7942018-01-09 19:15:01 +0530919int set_ipv4_addr(struct sigma_dut *dut, const char *ifname,
920 const char *ip, const char *mask)
921{
922 char buf[200];
923
924 snprintf(buf, sizeof(buf), "ifconfig %s %s netmask %s",
925 ifname, ip, mask);
926 return system(buf) == 0;
927}
928
929
930int set_ipv4_gw(struct sigma_dut *dut, const char *gw)
931{
932 char buf[200];
933
934 if (!is_ip_addr(gw)) {
935 sigma_dut_print(dut, DUT_MSG_DEBUG, "Invalid gw addr - %s", gw);
936 return -1;
937 }
938
939 snprintf(buf, sizeof(buf), "route add default gw %s", gw);
940 if (!dut->no_ip_addr_set && system(buf) != 0) {
941 snprintf(buf, sizeof(buf), "ip ro re default via %s",
942 gw);
943 if (system(buf) != 0)
944 return 0;
945 }
946
947 return 1;
948}
949
950
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200951static int cmd_sta_set_ip_config(struct sigma_dut *dut,
952 struct sigma_conn *conn,
953 struct sigma_cmd *cmd)
954{
955 const char *intf = get_param(cmd, "Interface");
956 const char *ifname;
957 char buf[200];
958 const char *val, *ip, *mask, *gw;
959 int type = 1;
960
961 if (intf == NULL)
962 return -1;
963
964 if (strcmp(intf, get_main_ifname()) == 0)
965 ifname = get_station_ifname();
966 else
967 ifname = intf;
968
969 if (if_nametoindex(ifname) == 0) {
970 send_resp(dut, conn, SIGMA_ERROR,
971 "ErrorCode,Unknown interface");
972 return 0;
973 }
974
975 val = get_param(cmd, "Type");
976 if (val) {
977 type = atoi(val);
Ankita Bajaj1bde7942018-01-09 19:15:01 +0530978 if (type < 1 || type > 3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200979 send_resp(dut, conn, SIGMA_ERROR,
980 "ErrorCode,Unsupported address type");
981 return 0;
982 }
983 }
984
985 dut->last_set_ip_config_ipv6 = 0;
986
987 val = get_param(cmd, "dhcp");
988 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "true") == 0)) {
989 static_ip_file(0, NULL, NULL, NULL);
990#ifdef __linux__
991 if (type == 2) {
992 dut->last_set_ip_config_ipv6 = 1;
993 sigma_dut_print(dut, DUT_MSG_INFO, "Using IPv6 "
994 "stateless address autoconfiguration");
995#ifdef ANDROID
996 /*
997 * This sleep is required as the assignment in case of
998 * Android is taking time and is done by the kernel.
999 * The subsequent ping for IPv6 is impacting HS20 test
1000 * case.
1001 */
1002 sleep(2);
1003 add_ipv6_rule(dut, intf);
1004#endif /* ANDROID */
1005 /* Assume this happens by default */
1006 return 1;
1007 }
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301008 if (type != 3) {
1009 kill_dhcp_client(dut, ifname);
1010 if (start_dhcp_client(dut, ifname) < 0)
1011 return -2;
1012 } else {
1013 sigma_dut_print(dut, DUT_MSG_DEBUG,
1014 "Using FILS HLP DHCPv4 Rapid Commit");
1015 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001016
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001017 return 1;
1018#endif /* __linux__ */
1019 return -2;
1020 }
1021
1022 ip = get_param(cmd, "ip");
Pradeep Reddy POTTETIb18c5652016-01-18 12:45:37 +05301023 if (!ip) {
1024 send_resp(dut, conn, SIGMA_INVALID,
1025 "ErrorCode,Missing IP address");
1026 return 0;
1027 }
1028
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001029 mask = get_param(cmd, "mask");
Pradeep Reddy POTTETIb18c5652016-01-18 12:45:37 +05301030 if (!mask) {
1031 send_resp(dut, conn, SIGMA_INVALID,
1032 "ErrorCode,Missing subnet mask");
1033 return 0;
1034 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001035
1036 if (type == 2) {
1037 int net = atoi(mask);
1038
1039 if ((net < 0 && net > 64) || !is_ipv6_addr(ip))
1040 return -1;
1041
1042 if (dut->no_ip_addr_set) {
1043 snprintf(buf, sizeof(buf),
1044 "sysctl net.ipv6.conf.%s.disable_ipv6=1",
1045 ifname);
1046 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
1047 if (system(buf) != 0) {
1048 sigma_dut_print(dut, DUT_MSG_DEBUG,
1049 "Failed to disable IPv6 address before association");
1050 }
1051 } else {
1052 snprintf(buf, sizeof(buf),
1053 "ip -6 addr del %s/%s dev %s",
1054 ip, mask, ifname);
1055 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
1056 if (system(buf) != 0) {
1057 /*
1058 * This command may fail if the address being
1059 * deleted does not exist. Inaction here is
1060 * intentional.
1061 */
1062 }
1063
1064 snprintf(buf, sizeof(buf),
1065 "ip -6 addr add %s/%s dev %s",
1066 ip, mask, ifname);
1067 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
1068 if (system(buf) != 0) {
1069 send_resp(dut, conn, SIGMA_ERROR,
1070 "ErrorCode,Failed to set IPv6 address");
1071 return 0;
1072 }
1073 }
1074
1075 dut->last_set_ip_config_ipv6 = 1;
1076 static_ip_file(6, ip, mask, NULL);
1077 return 1;
1078 } else if (type == 1) {
Pradeep Reddy POTTETIb18c5652016-01-18 12:45:37 +05301079 if (!is_ip_addr(ip) || !is_ip_addr(mask))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001080 return -1;
1081 }
1082
1083 kill_dhcp_client(dut, ifname);
1084
1085 if (!dut->no_ip_addr_set) {
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301086 if (!set_ipv4_addr(dut, ifname, ip, mask)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001087 send_resp(dut, conn, SIGMA_ERROR,
1088 "ErrorCode,Failed to set IP address");
1089 return 0;
1090 }
1091 }
1092
1093 gw = get_param(cmd, "defaultGateway");
1094 if (gw) {
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301095 if (set_ipv4_gw(dut, gw) < 1) {
1096 send_resp(dut, conn, SIGMA_ERROR,
1097 "ErrorCode,Failed to set default gateway");
1098 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001099 }
1100 }
1101
1102 val = get_param(cmd, "primary-dns");
1103 if (val) {
1104 /* TODO */
1105 sigma_dut_print(dut, DUT_MSG_INFO, "Ignored primary-dns %s "
1106 "setting", val);
1107 }
1108
1109 val = get_param(cmd, "secondary-dns");
1110 if (val) {
1111 /* TODO */
1112 sigma_dut_print(dut, DUT_MSG_INFO, "Ignored secondary-dns %s "
1113 "setting", val);
1114 }
1115
1116 static_ip_file(4, ip, mask, gw);
1117
1118 return 1;
1119}
1120
1121
1122static int cmd_sta_get_info(struct sigma_dut *dut, struct sigma_conn *conn,
1123 struct sigma_cmd *cmd)
1124{
1125 /* const char *intf = get_param(cmd, "Interface"); */
1126 /* TODO: could report more details here */
1127 send_resp(dut, conn, SIGMA_COMPLETE, "vendor,Atheros");
1128 return 0;
1129}
1130
1131
1132static int cmd_sta_get_mac_address(struct sigma_dut *dut,
1133 struct sigma_conn *conn,
1134 struct sigma_cmd *cmd)
1135{
1136 /* const char *intf = get_param(cmd, "Interface"); */
1137 char addr[20], resp[50];
1138
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05301139 if (dut->dev_role == DEVROLE_STA_CFON)
1140 return sta_cfon_get_mac_address(dut, conn, cmd);
1141
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001142 if (get_wpa_status(get_station_ifname(), "address", addr, sizeof(addr))
1143 < 0)
1144 return -2;
1145
1146 snprintf(resp, sizeof(resp), "mac,%s", addr);
1147 send_resp(dut, conn, SIGMA_COMPLETE, resp);
1148 return 0;
1149}
1150
1151
1152static int cmd_sta_is_connected(struct sigma_dut *dut, struct sigma_conn *conn,
1153 struct sigma_cmd *cmd)
1154{
1155 /* const char *intf = get_param(cmd, "Interface"); */
1156 int connected = 0;
1157 char result[32];
1158 if (get_wpa_status(get_station_ifname(), "wpa_state", result,
1159 sizeof(result)) < 0) {
1160 sigma_dut_print(dut, DUT_MSG_INFO, "Could not get interface "
1161 "%s status", get_station_ifname());
1162 return -2;
1163 }
1164
1165 sigma_dut_print(dut, DUT_MSG_DEBUG, "wpa_state=%s", result);
1166 if (strncmp(result, "COMPLETED", 9) == 0)
1167 connected = 1;
1168
1169 if (connected)
1170 send_resp(dut, conn, SIGMA_COMPLETE, "connected,1");
1171 else
1172 send_resp(dut, conn, SIGMA_COMPLETE, "connected,0");
1173
1174 return 0;
1175}
1176
1177
1178static int cmd_sta_verify_ip_connection(struct sigma_dut *dut,
1179 struct sigma_conn *conn,
1180 struct sigma_cmd *cmd)
1181{
1182 /* const char *intf = get_param(cmd, "Interface"); */
1183 const char *dst, *timeout;
1184 int wait_time = 90;
1185 char buf[100];
1186 int res;
1187
1188 dst = get_param(cmd, "destination");
1189 if (dst == NULL || !is_ip_addr(dst))
1190 return -1;
1191
1192 timeout = get_param(cmd, "timeout");
1193 if (timeout) {
1194 wait_time = atoi(timeout);
1195 if (wait_time < 1)
1196 wait_time = 1;
1197 }
1198
1199 /* TODO: force renewal of IP lease if DHCP is enabled */
1200
1201 snprintf(buf, sizeof(buf), "ping %s -c 3 -W %d", dst, wait_time);
1202 res = system(buf);
1203 sigma_dut_print(dut, DUT_MSG_DEBUG, "ping returned: %d", res);
1204 if (res == 0)
1205 send_resp(dut, conn, SIGMA_COMPLETE, "connected,1");
1206 else if (res == 256)
1207 send_resp(dut, conn, SIGMA_COMPLETE, "connected,0");
1208 else
1209 return -2;
1210
1211 return 0;
1212}
1213
1214
1215static int cmd_sta_get_bssid(struct sigma_dut *dut, struct sigma_conn *conn,
1216 struct sigma_cmd *cmd)
1217{
1218 /* const char *intf = get_param(cmd, "Interface"); */
1219 char bssid[20], resp[50];
1220
1221 if (get_wpa_status(get_station_ifname(), "bssid", bssid, sizeof(bssid))
1222 < 0)
Peng Xub8fc5cc2017-05-10 17:27:28 -07001223 strlcpy(bssid, "00:00:00:00:00:00", sizeof(bssid));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001224
1225 snprintf(resp, sizeof(resp), "bssid,%s", bssid);
1226 send_resp(dut, conn, SIGMA_COMPLETE, resp);
1227 return 0;
1228}
1229
1230
1231#ifdef __SAMSUNG__
1232static int add_use_network(const char *ifname)
1233{
1234 char buf[100];
1235
1236 snprintf(buf, sizeof(buf), "USE_NETWORK ON");
1237 wpa_command(ifname, buf);
1238 return 0;
1239}
1240#endif /* __SAMSUNG__ */
1241
1242
1243static int add_network_common(struct sigma_dut *dut, struct sigma_conn *conn,
1244 const char *ifname, struct sigma_cmd *cmd)
1245{
1246 const char *ssid = get_param(cmd, "ssid");
1247 int id;
1248 const char *val;
1249
1250 if (ssid == NULL)
1251 return -1;
1252
1253 start_sta_mode(dut);
1254
1255#ifdef __SAMSUNG__
1256 add_use_network(ifname);
1257#endif /* __SAMSUNG__ */
1258
1259 id = add_network(ifname);
1260 if (id < 0)
1261 return -2;
1262 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding network %d", id);
1263
1264 if (set_network_quoted(ifname, id, "ssid", ssid) < 0)
1265 return -2;
1266
1267 dut->infra_network_id = id;
1268 snprintf(dut->infra_ssid, sizeof(dut->infra_ssid), "%s", ssid);
1269
1270 val = get_param(cmd, "program");
1271 if (!val)
1272 val = get_param(cmd, "prog");
1273 if (val && strcasecmp(val, "hs2") == 0) {
1274 char buf[100];
1275 snprintf(buf, sizeof(buf), "ENABLE_NETWORK %d no-connect", id);
1276 wpa_command(ifname, buf);
1277
1278 val = get_param(cmd, "prefer");
1279 if (val && atoi(val) > 0)
1280 set_network(ifname, id, "priority", "1");
1281 }
1282
1283 return id;
1284}
1285
1286
1287static int cmd_sta_set_encryption(struct sigma_dut *dut,
1288 struct sigma_conn *conn,
1289 struct sigma_cmd *cmd)
1290{
1291 const char *intf = get_param(cmd, "Interface");
1292 const char *ssid = get_param(cmd, "ssid");
1293 const char *type = get_param(cmd, "encpType");
1294 const char *ifname;
1295 char buf[200];
1296 int id;
1297
1298 if (intf == NULL || ssid == NULL)
1299 return -1;
1300
1301 if (strcmp(intf, get_main_ifname()) == 0)
1302 ifname = get_station_ifname();
1303 else
1304 ifname = intf;
1305
1306 id = add_network_common(dut, conn, ifname, cmd);
1307 if (id < 0)
1308 return id;
1309
1310 if (set_network(ifname, id, "key_mgmt", "NONE") < 0)
1311 return -2;
1312
1313 if (type && strcasecmp(type, "wep") == 0) {
1314 const char *val;
1315 int i;
1316
1317 val = get_param(cmd, "activeKey");
1318 if (val) {
1319 int keyid;
1320 keyid = atoi(val);
1321 if (keyid < 1 || keyid > 4)
1322 return -1;
1323 snprintf(buf, sizeof(buf), "%d", keyid - 1);
1324 if (set_network(ifname, id, "wep_tx_keyidx", buf) < 0)
1325 return -2;
1326 }
1327
1328 for (i = 0; i < 4; i++) {
1329 snprintf(buf, sizeof(buf), "key%d", i + 1);
1330 val = get_param(cmd, buf);
1331 if (val == NULL)
1332 continue;
1333 snprintf(buf, sizeof(buf), "wep_key%d", i);
1334 if (set_network(ifname, id, buf, val) < 0)
1335 return -2;
1336 }
1337 }
1338
1339 return 1;
1340}
1341
1342
1343static int set_wpa_common(struct sigma_dut *dut, struct sigma_conn *conn,
1344 const char *ifname, struct sigma_cmd *cmd)
1345{
1346 const char *val;
1347 int id;
Jouni Malinenad395a22017-09-01 21:13:46 +03001348 int cipher_set = 0;
Jouni Malinen47dcc952017-10-09 16:43:24 +03001349 int owe;
Sunil Duttc75a1e62018-01-11 20:47:50 +05301350 int suite_b = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001351
1352 id = add_network_common(dut, conn, ifname, cmd);
1353 if (id < 0)
1354 return id;
1355
Jouni Malinen47dcc952017-10-09 16:43:24 +03001356 val = get_param(cmd, "Type");
1357 owe = val && strcasecmp(val, "OWE") == 0;
1358
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001359 val = get_param(cmd, "keyMgmtType");
Jouni Malinen47dcc952017-10-09 16:43:24 +03001360 if (!val && owe)
1361 val = "OWE";
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001362 if (val == NULL) {
1363 send_resp(dut, conn, SIGMA_INVALID, "errorCode,Missing keyMgmtType");
1364 return 0;
1365 }
1366 if (strcasecmp(val, "wpa") == 0 ||
1367 strcasecmp(val, "wpa-psk") == 0) {
1368 if (set_network(ifname, id, "proto", "WPA") < 0)
1369 return -2;
1370 } else if (strcasecmp(val, "wpa2") == 0 ||
1371 strcasecmp(val, "wpa2-psk") == 0 ||
1372 strcasecmp(val, "wpa2-ft") == 0 ||
1373 strcasecmp(val, "wpa2-sha256") == 0) {
1374 if (set_network(ifname, id, "proto", "WPA2") < 0)
1375 return -2;
Pradeep Reddy POTTETI6d04b3b2016-11-15 14:51:26 +05301376 } else if (strcasecmp(val, "wpa2-wpa-psk") == 0 ||
1377 strcasecmp(val, "wpa2-wpa-ent") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001378 if (set_network(ifname, id, "proto", "WPA WPA2") < 0)
1379 return -2;
Jouni Malinenad395a22017-09-01 21:13:46 +03001380 } else if (strcasecmp(val, "SuiteB") == 0) {
Sunil Duttc75a1e62018-01-11 20:47:50 +05301381 suite_b = 1;
Jouni Malinenad395a22017-09-01 21:13:46 +03001382 if (set_network(ifname, id, "proto", "WPA2") < 0)
1383 return -2;
Jouni Malinen47dcc952017-10-09 16:43:24 +03001384 } else if (strcasecmp(val, "OWE") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001385 } else {
1386 send_resp(dut, conn, SIGMA_INVALID, "errorCode,Unrecognized keyMgmtType value");
1387 return 0;
1388 }
1389
1390 val = get_param(cmd, "encpType");
Jouni Malinenad395a22017-09-01 21:13:46 +03001391 if (val) {
1392 cipher_set = 1;
1393 if (strcasecmp(val, "tkip") == 0) {
1394 if (set_network(ifname, id, "pairwise", "TKIP") < 0)
1395 return -2;
1396 } else if (strcasecmp(val, "aes-ccmp") == 0) {
1397 if (set_network(ifname, id, "pairwise", "CCMP") < 0)
1398 return -2;
1399 } else if (strcasecmp(val, "aes-ccmp-tkip") == 0) {
1400 if (set_network(ifname, id, "pairwise",
1401 "CCMP TKIP") < 0)
1402 return -2;
1403 } else if (strcasecmp(val, "aes-gcmp") == 0) {
1404 if (set_network(ifname, id, "pairwise", "GCMP") < 0)
1405 return -2;
1406 if (set_network(ifname, id, "group", "GCMP") < 0)
1407 return -2;
1408 } else {
1409 send_resp(dut, conn, SIGMA_ERROR,
1410 "errorCode,Unrecognized encpType value");
1411 return 0;
1412 }
1413 }
1414
1415 val = get_param(cmd, "PairwiseCipher");
1416 if (val) {
1417 cipher_set = 1;
1418 /* TODO: Support space separated list */
1419 if (strcasecmp(val, "AES-GCMP-256") == 0) {
1420 if (set_network(ifname, id, "pairwise", "GCMP-256") < 0)
1421 return -2;
1422 } else if (strcasecmp(val, "AES-CCMP-256") == 0) {
1423 if (set_network(ifname, id, "pairwise",
1424 "CCMP-256") < 0)
1425 return -2;
1426 } else if (strcasecmp(val, "AES-GCMP-128") == 0) {
1427 if (set_network(ifname, id, "pairwise", "GCMP") < 0)
1428 return -2;
1429 } else if (strcasecmp(val, "AES-CCMP-128") == 0) {
1430 if (set_network(ifname, id, "pairwise", "CCMP") < 0)
1431 return -2;
1432 } else {
1433 send_resp(dut, conn, SIGMA_ERROR,
1434 "errorCode,Unrecognized PairwiseCipher value");
1435 return 0;
1436 }
1437 }
1438
Jouni Malinen47dcc952017-10-09 16:43:24 +03001439 if (!cipher_set && !owe) {
Jouni Malinenad395a22017-09-01 21:13:46 +03001440 send_resp(dut, conn, SIGMA_ERROR,
1441 "errorCode,Missing encpType and PairwiseCipher");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001442 return 0;
1443 }
Jouni Malinenad395a22017-09-01 21:13:46 +03001444
1445 val = get_param(cmd, "GroupCipher");
1446 if (val) {
1447 if (strcasecmp(val, "AES-GCMP-256") == 0) {
1448 if (set_network(ifname, id, "group", "GCMP-256") < 0)
1449 return -2;
1450 } else if (strcasecmp(val, "AES-CCMP-256") == 0) {
1451 if (set_network(ifname, id, "group", "CCMP-256") < 0)
1452 return -2;
1453 } else if (strcasecmp(val, "AES-GCMP-128") == 0) {
1454 if (set_network(ifname, id, "group", "GCMP") < 0)
1455 return -2;
1456 } else if (strcasecmp(val, "AES-CCMP-128") == 0) {
1457 if (set_network(ifname, id, "group", "CCMP") < 0)
1458 return -2;
1459 } else {
1460 send_resp(dut, conn, SIGMA_ERROR,
1461 "errorCode,Unrecognized GroupCipher value");
1462 return 0;
1463 }
1464 }
1465
Jouni Malinen7b239522017-09-14 21:37:18 +03001466 val = get_param(cmd, "GroupMgntCipher");
Jouni Malinenad395a22017-09-01 21:13:46 +03001467 if (val) {
Jouni Malinene8898cb2017-09-26 17:55:26 +03001468 const char *cipher;
1469
1470 if (strcasecmp(val, "BIP-GMAC-256") == 0) {
1471 cipher = "BIP-GMAC-256";
1472 } else if (strcasecmp(val, "BIP-CMAC-256") == 0) {
1473 cipher = "BIP-CMAC-256";
1474 } else if (strcasecmp(val, "BIP-GMAC-128") == 0) {
1475 cipher = "BIP-GMAC-128";
1476 } else if (strcasecmp(val, "BIP-CMAC-128") == 0) {
1477 cipher = "AES-128-CMAC";
1478 } else {
1479 send_resp(dut, conn, SIGMA_INVALID,
1480 "errorCode,Unsupported GroupMgntCipher");
1481 return 0;
1482 }
1483 if (set_network(ifname, id, "group_mgmt", cipher) < 0) {
1484 send_resp(dut, conn, SIGMA_INVALID,
1485 "errorCode,Failed to set GroupMgntCipher");
1486 return 0;
1487 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001488 }
1489
1490 dut->sta_pmf = STA_PMF_DISABLED;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05301491
1492 if (dut->program == PROGRAM_OCE) {
1493 dut->sta_pmf = STA_PMF_OPTIONAL;
1494 if (set_network(ifname, id, "ieee80211w", "1") < 0)
1495 return -2;
1496 }
1497
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001498 val = get_param(cmd, "PMF");
1499 if (val) {
1500 if (strcasecmp(val, "Required") == 0 ||
1501 strcasecmp(val, "Forced_Required") == 0) {
1502 dut->sta_pmf = STA_PMF_REQUIRED;
1503 if (set_network(ifname, id, "ieee80211w", "2") < 0)
1504 return -2;
1505 } else if (strcasecmp(val, "Optional") == 0) {
1506 dut->sta_pmf = STA_PMF_OPTIONAL;
1507 if (set_network(ifname, id, "ieee80211w", "1") < 0)
1508 return -2;
1509 } else if (strcasecmp(val, "Disabled") == 0 ||
1510 strcasecmp(val, "Forced_Disabled") == 0) {
1511 dut->sta_pmf = STA_PMF_DISABLED;
1512 } else {
1513 send_resp(dut, conn, SIGMA_INVALID, "errorCode,Unrecognized PMF value");
1514 return 0;
1515 }
Sunil Duttc75a1e62018-01-11 20:47:50 +05301516 } else if (owe || suite_b) {
Jouni Malinen1287cd72018-01-04 17:08:01 +02001517 dut->sta_pmf = STA_PMF_REQUIRED;
1518 if (set_network(ifname, id, "ieee80211w", "2") < 0)
1519 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001520 }
1521
1522 return id;
1523}
1524
1525
1526static int cmd_sta_set_psk(struct sigma_dut *dut, struct sigma_conn *conn,
1527 struct sigma_cmd *cmd)
1528{
1529 const char *intf = get_param(cmd, "Interface");
Jouni Malinen992a81e2017-08-22 13:57:47 +03001530 const char *type = get_param(cmd, "Type");
Jouni Malinen1287cd72018-01-04 17:08:01 +02001531 const char *pmf = get_param(cmd, "PMF");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001532 const char *ifname, *val, *alg;
1533 int id;
1534
1535 if (intf == NULL)
1536 return -1;
1537
1538 if (strcmp(intf, get_main_ifname()) == 0)
1539 ifname = get_station_ifname();
1540 else
1541 ifname = intf;
1542
1543 id = set_wpa_common(dut, conn, ifname, cmd);
1544 if (id < 0)
1545 return id;
1546
1547 val = get_param(cmd, "keyMgmtType");
1548 alg = get_param(cmd, "micAlg");
1549
Jouni Malinen992a81e2017-08-22 13:57:47 +03001550 if (type && strcasecmp(type, "SAE") == 0) {
1551 if (val && strcasecmp(val, "wpa2-ft") == 0) {
1552 if (set_network(ifname, id, "key_mgmt", "FT-SAE") < 0)
1553 return -2;
1554 } else {
1555 if (set_network(ifname, id, "key_mgmt", "SAE") < 0)
1556 return -2;
1557 }
1558 if (wpa_command(ifname, "SET sae_groups ") != 0) {
1559 sigma_dut_print(dut, DUT_MSG_ERROR,
1560 "Failed to clear sae_groups to default");
1561 return -2;
1562 }
Jouni Malinen1287cd72018-01-04 17:08:01 +02001563 if (!pmf) {
1564 dut->sta_pmf = STA_PMF_REQUIRED;
1565 if (set_network(ifname, id, "ieee80211w", "2") < 0)
1566 return -2;
1567 }
Jouni Malinen0ab50f42017-08-31 01:34:59 +03001568 } else if (type && strcasecmp(type, "PSK-SAE") == 0) {
1569 if (val && strcasecmp(val, "wpa2-ft") == 0) {
1570 if (set_network(ifname, id, "key_mgmt",
1571 "FT-SAE FT-PSK") < 0)
1572 return -2;
1573 } else {
1574 if (set_network(ifname, id, "key_mgmt",
1575 "SAE WPA-PSK") < 0)
1576 return -2;
1577 }
1578 if (wpa_command(ifname, "SET sae_groups ") != 0) {
1579 sigma_dut_print(dut, DUT_MSG_ERROR,
1580 "Failed to clear sae_groups to default");
1581 return -2;
1582 }
Jouni Malinen1287cd72018-01-04 17:08:01 +02001583 if (!pmf) {
1584 dut->sta_pmf = STA_PMF_OPTIONAL;
1585 if (set_network(ifname, id, "ieee80211w", "1") < 0)
1586 return -2;
1587 }
Jouni Malinen992a81e2017-08-22 13:57:47 +03001588 } else if (alg && strcasecmp(alg, "SHA-256") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001589 if (set_network(ifname, id, "key_mgmt", "WPA-PSK-SHA256") < 0)
1590 return -2;
1591 } else if (alg && strcasecmp(alg, "SHA-1") == 0) {
1592 if (set_network(ifname, id, "key_mgmt", "WPA-PSK") < 0)
1593 return -2;
Ashwini Patil6dbf7b02017-03-20 13:42:11 +05301594 } else if (val && strcasecmp(val, "wpa2-ft") == 0) {
1595 if (set_network(ifname, id, "key_mgmt", "FT-PSK") < 0)
1596 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001597 } else if ((val && strcasecmp(val, "wpa2-sha256") == 0) ||
1598 dut->sta_pmf == STA_PMF_REQUIRED) {
1599 if (set_network(ifname, id, "key_mgmt",
1600 "WPA-PSK WPA-PSK-SHA256") < 0)
1601 return -2;
1602 } else if (dut->sta_pmf == STA_PMF_OPTIONAL) {
1603 if (set_network(ifname, id, "key_mgmt",
1604 "WPA-PSK WPA-PSK-SHA256") < 0)
1605 return -2;
1606 } else {
1607 if (set_network(ifname, id, "key_mgmt", "WPA-PSK") < 0)
1608 return -2;
1609 }
1610
1611 val = get_param(cmd, "passPhrase");
1612 if (val == NULL)
1613 return -1;
Jouni Malinen2126f422017-10-11 23:24:33 +03001614 if (type && strcasecmp(type, "SAE") == 0) {
1615 if (set_network_quoted(ifname, id, "sae_password", val) < 0)
1616 return -2;
1617 } else {
1618 if (set_network_quoted(ifname, id, "psk", val) < 0)
1619 return -2;
1620 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001621
Jouni Malinen992a81e2017-08-22 13:57:47 +03001622 val = get_param(cmd, "ECGroupID");
1623 if (val) {
1624 char buf[50];
1625
1626 snprintf(buf, sizeof(buf), "SET sae_groups %u", atoi(val));
1627 if (wpa_command(ifname, buf) != 0) {
1628 sigma_dut_print(dut, DUT_MSG_ERROR,
1629 "Failed to clear sae_groups");
1630 return -2;
1631 }
1632 }
1633
Jouni Malinen68143132017-09-02 02:34:08 +03001634 val = get_param(cmd, "InvalidSAEElement");
1635 if (val) {
1636 free(dut->sae_commit_override);
1637 dut->sae_commit_override = strdup(val);
1638 }
1639
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001640 return 1;
1641}
1642
1643
1644static int set_eap_common(struct sigma_dut *dut, struct sigma_conn *conn,
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05301645 const char *ifname, int username_identity,
1646 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001647{
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05301648 const char *val, *alg, *akm;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001649 int id;
1650 char buf[200];
1651#ifdef ANDROID
1652 unsigned char kvalue[KEYSTORE_MESSAGE_SIZE];
1653 int length;
1654#endif /* ANDROID */
1655
1656 id = set_wpa_common(dut, conn, ifname, cmd);
1657 if (id < 0)
1658 return id;
1659
1660 val = get_param(cmd, "keyMgmtType");
1661 alg = get_param(cmd, "micAlg");
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05301662 akm = get_param(cmd, "AKMSuiteType");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001663
Jouni Malinenad395a22017-09-01 21:13:46 +03001664 if (val && strcasecmp(val, "SuiteB") == 0) {
1665 if (set_network(ifname, id, "key_mgmt", "WPA-EAP-SUITE-B-192") <
1666 0)
1667 return -2;
1668 } else if (alg && strcasecmp(alg, "SHA-256") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001669 if (set_network(ifname, id, "key_mgmt", "WPA-EAP-SHA256") < 0)
1670 return -2;
1671 } else if (alg && strcasecmp(alg, "SHA-1") == 0) {
1672 if (set_network(ifname, id, "key_mgmt", "WPA-EAP") < 0)
1673 return -2;
1674 } else if (val && strcasecmp(val, "wpa2-ft") == 0) {
1675 if (set_network(ifname, id, "key_mgmt", "FT-EAP") < 0)
1676 return -2;
1677 } else if ((val && strcasecmp(val, "wpa2-sha256") == 0) ||
1678 dut->sta_pmf == STA_PMF_REQUIRED) {
1679 if (set_network(ifname, id, "key_mgmt",
1680 "WPA-EAP WPA-EAP-SHA256") < 0)
1681 return -2;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05301682 } else if (akm && atoi(akm) == 14) {
1683 if (dut->sta_pmf == STA_PMF_OPTIONAL ||
1684 dut->sta_pmf == STA_PMF_REQUIRED) {
1685 if (set_network(ifname, id, "key_mgmt",
1686 "WPA-EAP-SHA256 FILS-SHA256") < 0)
1687 return -2;
1688 } else {
1689 if (set_network(ifname, id, "key_mgmt",
1690 "WPA-EAP FILS-SHA256") < 0)
1691 return -2;
1692 }
1693
1694 if (set_network(ifname, id, "erp", "1") < 0)
1695 return -2;
1696 } else if (akm && atoi(akm) == 15) {
1697 if (dut->sta_pmf == STA_PMF_OPTIONAL ||
1698 dut->sta_pmf == STA_PMF_REQUIRED) {
1699 if (set_network(ifname, id, "key_mgmt",
1700 "WPA-EAP-SHA256 FILS-SHA384") < 0)
1701 return -2;
1702 } else {
1703 if (set_network(ifname, id, "key_mgmt",
1704 "WPA-EAP FILS-SHA384") < 0)
1705 return -2;
1706 }
1707
1708 if (set_network(ifname, id, "erp", "1") < 0)
1709 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001710 } else if (dut->sta_pmf == STA_PMF_OPTIONAL) {
1711 if (set_network(ifname, id, "key_mgmt",
1712 "WPA-EAP WPA-EAP-SHA256") < 0)
1713 return -2;
1714 } else {
1715 if (set_network(ifname, id, "key_mgmt", "WPA-EAP") < 0)
1716 return -2;
1717 }
1718
1719 val = get_param(cmd, "trustedRootCA");
1720 if (val) {
1721#ifdef ANDROID
1722 snprintf(buf, sizeof(buf), "CACERT_%s", val);
1723 length = android_keystore_get(ANDROID_KEYSTORE_GET, buf,
1724 kvalue);
1725 if (length > 0) {
1726 sigma_dut_print(dut, DUT_MSG_INFO,
1727 "Use Android keystore [%s]", buf);
1728 snprintf(buf, sizeof(buf), "keystore://CACERT_%s",
1729 val);
1730 goto ca_cert_selected;
1731 }
1732#endif /* ANDROID */
1733
1734 snprintf(buf, sizeof(buf), "%s/%s", sigma_cert_path, val);
1735#ifdef __linux__
1736 if (!file_exists(buf)) {
1737 char msg[300];
1738 snprintf(msg, sizeof(msg), "ErrorCode,trustedRootCA "
1739 "file (%s) not found", buf);
1740 send_resp(dut, conn, SIGMA_ERROR, msg);
1741 return -3;
1742 }
1743#endif /* __linux__ */
1744#ifdef ANDROID
1745ca_cert_selected:
1746#endif /* ANDROID */
1747 if (set_network_quoted(ifname, id, "ca_cert", buf) < 0)
1748 return -2;
1749 }
1750
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05301751 if (username_identity) {
1752 val = get_param(cmd, "username");
1753 if (val) {
1754 if (set_network_quoted(ifname, id, "identity", val) < 0)
1755 return -2;
1756 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001757
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05301758 val = get_param(cmd, "password");
1759 if (val) {
1760 if (set_network_quoted(ifname, id, "password", val) < 0)
1761 return -2;
1762 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001763 }
1764
1765 return id;
1766}
1767
1768
Jouni Malinen5eabb2a2017-10-03 18:17:30 +03001769static int set_tls_cipher(const char *ifname, int id, const char *cipher)
1770{
1771 const char *val;
1772
1773 if (!cipher)
1774 return 0;
1775
1776 if (strcasecmp(cipher, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384") == 0)
1777 val = "ECDHE-ECDSA-AES256-GCM-SHA384";
1778 else if (strcasecmp(cipher,
1779 "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384") == 0)
1780 val = "ECDHE-RSA-AES256-GCM-SHA384";
1781 else if (strcasecmp(cipher, "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384") == 0)
1782 val = "DHE-RSA-AES256-GCM-SHA384";
1783 else if (strcasecmp(cipher,
1784 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256") == 0)
1785 val = "ECDHE-ECDSA-AES128-GCM-SHA256";
1786 else
1787 return -1;
1788
1789 /* Need to clear phase1="tls_suiteb=1" to allow cipher enforcement */
1790 set_network_quoted(ifname, id, "phase1", "");
1791
1792 return set_network_quoted(ifname, id, "openssl_ciphers", val);
1793}
1794
1795
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001796static int cmd_sta_set_eaptls(struct sigma_dut *dut, struct sigma_conn *conn,
1797 struct sigma_cmd *cmd)
1798{
1799 const char *intf = get_param(cmd, "Interface");
1800 const char *ifname, *val;
1801 int id;
1802 char buf[200];
1803#ifdef ANDROID
1804 unsigned char kvalue[KEYSTORE_MESSAGE_SIZE];
1805 int length;
1806 int jb_or_newer = 0;
1807 char prop[PROPERTY_VALUE_MAX];
1808#endif /* ANDROID */
1809
1810 if (intf == NULL)
1811 return -1;
1812
1813 if (strcmp(intf, get_main_ifname()) == 0)
1814 ifname = get_station_ifname();
1815 else
1816 ifname = intf;
1817
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05301818 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001819 if (id < 0)
1820 return id;
1821
1822 if (set_network(ifname, id, "eap", "TLS") < 0)
1823 return -2;
1824
Pradeep Reddy POTTETI9f6c2132016-05-05 16:28:19 +05301825 if (!get_param(cmd, "username") &&
1826 set_network_quoted(ifname, id, "identity",
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001827 "wifi-user@wifilabs.local") < 0)
1828 return -2;
1829
1830 val = get_param(cmd, "clientCertificate");
1831 if (val == NULL)
1832 return -1;
1833#ifdef ANDROID
1834 snprintf(buf, sizeof(buf), "USRPKEY_%s", val);
1835 length = android_keystore_get(ANDROID_KEYSTORE_GET, buf, kvalue);
1836 if (length < 0) {
1837 /*
1838 * JB started reporting keystore type mismatches, so retry with
1839 * the GET_PUBKEY command if the generic GET fails.
1840 */
1841 length = android_keystore_get(ANDROID_KEYSTORE_GET_PUBKEY,
1842 buf, kvalue);
1843 }
1844
1845 if (property_get("ro.build.version.release", prop, NULL) != 0) {
1846 sigma_dut_print(dut, DUT_MSG_DEBUG, "Android release %s", prop);
1847 if (strncmp(prop, "4.0", 3) != 0)
1848 jb_or_newer = 1;
1849 } else
1850 jb_or_newer = 1; /* assume newer */
1851
1852 if (jb_or_newer && length > 0) {
1853 sigma_dut_print(dut, DUT_MSG_INFO,
1854 "Use Android keystore [%s]", buf);
1855 if (set_network(ifname, id, "engine", "1") < 0)
1856 return -2;
1857 if (set_network_quoted(ifname, id, "engine_id", "keystore") < 0)
1858 return -2;
1859 snprintf(buf, sizeof(buf), "USRPKEY_%s", val);
1860 if (set_network_quoted(ifname, id, "key_id", buf) < 0)
1861 return -2;
1862 snprintf(buf, sizeof(buf), "keystore://USRCERT_%s", val);
1863 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
1864 return -2;
1865 return 1;
1866 } else if (length > 0) {
1867 sigma_dut_print(dut, DUT_MSG_INFO,
1868 "Use Android keystore [%s]", buf);
1869 snprintf(buf, sizeof(buf), "keystore://USRPKEY_%s", val);
1870 if (set_network_quoted(ifname, id, "private_key", buf) < 0)
1871 return -2;
1872 snprintf(buf, sizeof(buf), "keystore://USRCERT_%s", val);
1873 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
1874 return -2;
1875 return 1;
1876 }
1877#endif /* ANDROID */
1878
1879 snprintf(buf, sizeof(buf), "%s/%s", sigma_cert_path, val);
1880#ifdef __linux__
1881 if (!file_exists(buf)) {
1882 char msg[300];
1883 snprintf(msg, sizeof(msg), "ErrorCode,clientCertificate file "
1884 "(%s) not found", buf);
1885 send_resp(dut, conn, SIGMA_ERROR, msg);
1886 return -3;
1887 }
1888#endif /* __linux__ */
1889 if (set_network_quoted(ifname, id, "private_key", buf) < 0)
1890 return -2;
1891 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
1892 return -2;
1893
1894 if (set_network_quoted(ifname, id, "private_key_passwd", "wifi") < 0)
1895 return -2;
1896
Jouni Malinen5eabb2a2017-10-03 18:17:30 +03001897 val = get_param(cmd, "keyMgmtType");
1898 if (val && strcasecmp(val, "SuiteB") == 0) {
1899 val = get_param(cmd, "CertType");
1900 if (val && strcasecmp(val, "RSA") == 0) {
1901 if (set_network_quoted(ifname, id, "phase1",
1902 "tls_suiteb=1") < 0)
1903 return -2;
1904 } else {
1905 if (set_network_quoted(ifname, id, "openssl_ciphers",
1906 "SUITEB192") < 0)
1907 return -2;
1908 }
1909
1910 val = get_param(cmd, "TLSCipher");
1911 if (set_tls_cipher(ifname, id, val) < 0) {
1912 send_resp(dut, conn, SIGMA_ERROR,
1913 "ErrorCode,Unsupported TLSCipher value");
1914 return -3;
1915 }
1916 }
1917
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001918 return 1;
1919}
1920
1921
1922static int cmd_sta_set_eapttls(struct sigma_dut *dut, struct sigma_conn *conn,
1923 struct sigma_cmd *cmd)
1924{
1925 const char *intf = get_param(cmd, "Interface");
1926 const char *ifname;
1927 int id;
1928
1929 if (intf == NULL)
1930 return -1;
1931
1932 if (strcmp(intf, get_main_ifname()) == 0)
1933 ifname = get_station_ifname();
1934 else
1935 ifname = intf;
1936
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05301937 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001938 if (id < 0)
1939 return id;
1940
1941 if (set_network(ifname, id, "eap", "TTLS") < 0) {
1942 send_resp(dut, conn, SIGMA_ERROR,
1943 "errorCode,Failed to set TTLS method");
1944 return 0;
1945 }
1946
1947 if (set_network_quoted(ifname, id, "phase2", "auth=MSCHAPV2") < 0) {
1948 send_resp(dut, conn, SIGMA_ERROR,
1949 "errorCode,Failed to set MSCHAPv2 for TTLS Phase 2");
1950 return 0;
1951 }
1952
1953 return 1;
1954}
1955
1956
1957static int cmd_sta_set_eapsim(struct sigma_dut *dut, struct sigma_conn *conn,
1958 struct sigma_cmd *cmd)
1959{
1960 const char *intf = get_param(cmd, "Interface");
1961 const char *ifname;
1962 int id;
1963
1964 if (intf == NULL)
1965 return -1;
1966
1967 if (strcmp(intf, get_main_ifname()) == 0)
1968 ifname = get_station_ifname();
1969 else
1970 ifname = intf;
1971
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05301972 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001973 if (id < 0)
1974 return id;
1975
1976 if (set_network(ifname, id, "eap", "SIM") < 0)
1977 return -2;
1978
1979 return 1;
1980}
1981
1982
1983static int cmd_sta_set_peap(struct sigma_dut *dut, struct sigma_conn *conn,
1984 struct sigma_cmd *cmd)
1985{
1986 const char *intf = get_param(cmd, "Interface");
1987 const char *ifname, *val;
1988 int id;
1989 char buf[100];
1990
1991 if (intf == NULL)
1992 return -1;
1993
1994 if (strcmp(intf, get_main_ifname()) == 0)
1995 ifname = get_station_ifname();
1996 else
1997 ifname = intf;
1998
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05301999 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002000 if (id < 0)
2001 return id;
2002
2003 if (set_network(ifname, id, "eap", "PEAP") < 0)
2004 return -2;
2005
2006 val = get_param(cmd, "innerEAP");
2007 if (val) {
2008 if (strcasecmp(val, "MSCHAPv2") == 0) {
2009 if (set_network_quoted(ifname, id, "phase2",
2010 "auth=MSCHAPV2") < 0)
2011 return -2;
2012 } else if (strcasecmp(val, "GTC") == 0) {
2013 if (set_network_quoted(ifname, id, "phase2",
2014 "auth=GTC") < 0)
2015 return -2;
2016 } else
2017 return -1;
2018 }
2019
2020 val = get_param(cmd, "peapVersion");
2021 if (val) {
2022 int ver = atoi(val);
2023 if (ver < 0 || ver > 1)
2024 return -1;
2025 snprintf(buf, sizeof(buf), "peapver=%d", ver);
2026 if (set_network_quoted(ifname, id, "phase1", buf) < 0)
2027 return -2;
2028 }
2029
2030 return 1;
2031}
2032
2033
2034static int cmd_sta_set_eapfast(struct sigma_dut *dut, struct sigma_conn *conn,
2035 struct sigma_cmd *cmd)
2036{
2037 const char *intf = get_param(cmd, "Interface");
2038 const char *ifname, *val;
2039 int id;
2040 char buf[100];
2041
2042 if (intf == NULL)
2043 return -1;
2044
2045 if (strcmp(intf, get_main_ifname()) == 0)
2046 ifname = get_station_ifname();
2047 else
2048 ifname = intf;
2049
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302050 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002051 if (id < 0)
2052 return id;
2053
2054 if (set_network(ifname, id, "eap", "FAST") < 0)
2055 return -2;
2056
2057 val = get_param(cmd, "innerEAP");
2058 if (val) {
2059 if (strcasecmp(val, "MSCHAPV2") == 0) {
2060 if (set_network_quoted(ifname, id, "phase2",
2061 "auth=MSCHAPV2") < 0)
2062 return -2;
2063 } else if (strcasecmp(val, "GTC") == 0) {
2064 if (set_network_quoted(ifname, id, "phase2",
2065 "auth=GTC") < 0)
2066 return -2;
2067 } else
2068 return -1;
2069 }
2070
2071 val = get_param(cmd, "validateServer");
2072 if (val) {
2073 /* TODO */
2074 sigma_dut_print(dut, DUT_MSG_INFO, "Ignored EAP-FAST "
2075 "validateServer=%s", val);
2076 }
2077
2078 val = get_param(cmd, "pacFile");
2079 if (val) {
2080 snprintf(buf, sizeof(buf), "blob://%s", val);
2081 if (set_network_quoted(ifname, id, "pac_file", buf) < 0)
2082 return -2;
2083 }
2084
2085 if (set_network_quoted(ifname, id, "phase1", "fast_provisioning=2") <
2086 0)
2087 return -2;
2088
2089 return 1;
2090}
2091
2092
2093static int cmd_sta_set_eapaka(struct sigma_dut *dut, struct sigma_conn *conn,
2094 struct sigma_cmd *cmd)
2095{
2096 const char *intf = get_param(cmd, "Interface");
2097 const char *ifname;
2098 int id;
2099
2100 if (intf == NULL)
2101 return -1;
2102
2103 if (strcmp(intf, get_main_ifname()) == 0)
2104 ifname = get_station_ifname();
2105 else
2106 ifname = intf;
2107
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302108 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002109 if (id < 0)
2110 return id;
2111
2112 if (set_network(ifname, id, "eap", "AKA") < 0)
2113 return -2;
2114
2115 return 1;
2116}
2117
2118
2119static int cmd_sta_set_eapakaprime(struct sigma_dut *dut,
2120 struct sigma_conn *conn,
2121 struct sigma_cmd *cmd)
2122{
2123 const char *intf = get_param(cmd, "Interface");
2124 const char *ifname;
2125 int id;
2126
2127 if (intf == NULL)
2128 return -1;
2129
2130 if (strcmp(intf, get_main_ifname()) == 0)
2131 ifname = get_station_ifname();
2132 else
2133 ifname = intf;
2134
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302135 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002136 if (id < 0)
2137 return id;
2138
2139 if (set_network(ifname, id, "eap", "AKA'") < 0)
2140 return -2;
2141
2142 return 1;
2143}
2144
2145
2146static int sta_set_open(struct sigma_dut *dut, struct sigma_conn *conn,
2147 struct sigma_cmd *cmd)
2148{
2149 const char *intf = get_param(cmd, "Interface");
2150 const char *ifname;
2151 int id;
2152
2153 if (strcmp(intf, get_main_ifname()) == 0)
2154 ifname = get_station_ifname();
2155 else
2156 ifname = intf;
2157
2158 id = add_network_common(dut, conn, ifname, cmd);
2159 if (id < 0)
2160 return id;
2161
2162 if (set_network(ifname, id, "key_mgmt", "NONE") < 0)
2163 return -2;
2164
2165 return 1;
2166}
2167
2168
Jouni Malinen47dcc952017-10-09 16:43:24 +03002169static int sta_set_owe(struct sigma_dut *dut, struct sigma_conn *conn,
2170 struct sigma_cmd *cmd)
2171{
2172 const char *intf = get_param(cmd, "Interface");
2173 const char *ifname, *val;
2174 int id;
2175
2176 if (intf == NULL)
2177 return -1;
2178
2179 if (strcmp(intf, get_main_ifname()) == 0)
2180 ifname = get_station_ifname();
2181 else
2182 ifname = intf;
2183
2184 id = set_wpa_common(dut, conn, ifname, cmd);
2185 if (id < 0)
2186 return id;
2187
2188 if (set_network(ifname, id, "key_mgmt", "OWE") < 0)
2189 return -2;
2190
2191 val = get_param(cmd, "ECGroupID");
Jouni Malinenfac9cad2017-10-10 18:35:55 +03002192 if (val && strcmp(val, "0") == 0) {
2193 if (wpa_command(ifname,
2194 "VENDOR_ELEM_ADD 13 ff23200000783590fb7440e03d5b3b33911f86affdcc6b4411b707846ac4ff08ddc8831ccd") != 0) {
2195 sigma_dut_print(dut, DUT_MSG_ERROR,
2196 "Failed to set OWE DH Param element override");
2197 return -2;
2198 }
2199 } else if (val && set_network(ifname, id, "owe_group", val) < 0) {
Jouni Malinen47dcc952017-10-09 16:43:24 +03002200 sigma_dut_print(dut, DUT_MSG_ERROR,
2201 "Failed to clear owe_group");
2202 return -2;
2203 }
2204
2205 return 1;
2206}
2207
2208
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002209static int cmd_sta_set_security(struct sigma_dut *dut, struct sigma_conn *conn,
2210 struct sigma_cmd *cmd)
2211{
2212 const char *type = get_param(cmd, "Type");
2213
2214 if (type == NULL) {
2215 send_resp(dut, conn, SIGMA_ERROR,
2216 "ErrorCode,Missing Type argument");
2217 return 0;
2218 }
2219
2220 if (strcasecmp(type, "OPEN") == 0)
2221 return sta_set_open(dut, conn, cmd);
Jouni Malinen47dcc952017-10-09 16:43:24 +03002222 if (strcasecmp(type, "OWE") == 0)
2223 return sta_set_owe(dut, conn, cmd);
Jouni Malinen992a81e2017-08-22 13:57:47 +03002224 if (strcasecmp(type, "PSK") == 0 ||
Jouni Malinen0ab50f42017-08-31 01:34:59 +03002225 strcasecmp(type, "PSK-SAE") == 0 ||
Jouni Malinen992a81e2017-08-22 13:57:47 +03002226 strcasecmp(type, "SAE") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002227 return cmd_sta_set_psk(dut, conn, cmd);
2228 if (strcasecmp(type, "EAPTLS") == 0)
2229 return cmd_sta_set_eaptls(dut, conn, cmd);
2230 if (strcasecmp(type, "EAPTTLS") == 0)
2231 return cmd_sta_set_eapttls(dut, conn, cmd);
2232 if (strcasecmp(type, "EAPPEAP") == 0)
2233 return cmd_sta_set_peap(dut, conn, cmd);
2234 if (strcasecmp(type, "EAPSIM") == 0)
2235 return cmd_sta_set_eapsim(dut, conn, cmd);
2236 if (strcasecmp(type, "EAPFAST") == 0)
2237 return cmd_sta_set_eapfast(dut, conn, cmd);
2238 if (strcasecmp(type, "EAPAKA") == 0)
2239 return cmd_sta_set_eapaka(dut, conn, cmd);
2240 if (strcasecmp(type, "EAPAKAPRIME") == 0)
2241 return cmd_sta_set_eapakaprime(dut, conn, cmd);
Amarnath Hullur Subramanyam81b11cd2018-01-30 19:07:17 -08002242 if (strcasecmp(type, "wep") == 0)
2243 return cmd_sta_set_encryption(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002244
2245 send_resp(dut, conn, SIGMA_ERROR,
2246 "ErrorCode,Unsupported Type value");
2247 return 0;
2248}
2249
2250
2251int ath6kl_client_uapsd(struct sigma_dut *dut, const char *intf, int uapsd)
2252{
2253#ifdef __linux__
2254 /* special handling for ath6kl */
2255 char path[128], fname[128], *pos;
2256 ssize_t res;
2257 FILE *f;
2258
2259 snprintf(path, sizeof(path), "/sys/class/net/%s/phy80211", intf);
2260 res = readlink(path, path, sizeof(path));
2261 if (res < 0)
2262 return 0; /* not ath6kl */
2263
2264 if (res >= (int) sizeof(path))
2265 res = sizeof(path) - 1;
2266 path[res] = '\0';
2267 pos = strrchr(path, '/');
2268 if (pos == NULL)
2269 pos = path;
2270 else
2271 pos++;
2272 snprintf(fname, sizeof(fname),
2273 "/sys/kernel/debug/ieee80211/%s/ath6kl/"
2274 "create_qos", pos);
2275 if (!file_exists(fname))
2276 return 0; /* not ath6kl */
2277
2278 if (uapsd) {
2279 f = fopen(fname, "w");
2280 if (f == NULL)
2281 return -1;
2282
2283 sigma_dut_print(dut, DUT_MSG_DEBUG, "Use ath6kl create_qos");
2284 fprintf(f, "4 2 2 1 2 9999999 9999999 9999999 7777777 0 4 "
2285 "45000 200 56789000 56789000 5678900 0 0 9999999 "
2286 "20000 0\n");
2287 fclose(f);
2288 } else {
2289 snprintf(fname, sizeof(fname),
2290 "/sys/kernel/debug/ieee80211/%s/ath6kl/"
2291 "delete_qos", pos);
2292
2293 f = fopen(fname, "w");
2294 if (f == NULL)
2295 return -1;
2296
2297 sigma_dut_print(dut, DUT_MSG_DEBUG, "Use ath6kl delete_qos");
2298 fprintf(f, "2 4\n");
2299 fclose(f);
2300 }
2301#endif /* __linux__ */
2302
2303 return 0;
2304}
2305
2306
2307static int cmd_sta_set_uapsd(struct sigma_dut *dut, struct sigma_conn *conn,
2308 struct sigma_cmd *cmd)
2309{
2310 const char *intf = get_param(cmd, "Interface");
2311 /* const char *ssid = get_param(cmd, "ssid"); */
2312 const char *val;
2313 int max_sp_len = 4;
2314 int ac_be = 1, ac_bk = 1, ac_vi = 1, ac_vo = 1;
2315 char buf[100];
2316 int ret1, ret2;
2317
2318 val = get_param(cmd, "maxSPLength");
2319 if (val) {
2320 max_sp_len = atoi(val);
2321 if (max_sp_len != 0 && max_sp_len != 1 && max_sp_len != 2 &&
2322 max_sp_len != 4)
2323 return -1;
2324 }
2325
2326 val = get_param(cmd, "acBE");
2327 if (val)
2328 ac_be = atoi(val);
2329
2330 val = get_param(cmd, "acBK");
2331 if (val)
2332 ac_bk = atoi(val);
2333
2334 val = get_param(cmd, "acVI");
2335 if (val)
2336 ac_vi = atoi(val);
2337
2338 val = get_param(cmd, "acVO");
2339 if (val)
2340 ac_vo = atoi(val);
2341
2342 dut->client_uapsd = ac_be || ac_bk || ac_vi || ac_vo;
2343
2344 snprintf(buf, sizeof(buf), "P2P_SET client_apsd %d,%d,%d,%d;%d",
2345 ac_be, ac_bk, ac_vi, ac_vo, max_sp_len);
2346 ret1 = wpa_command(intf, buf);
2347
2348 snprintf(buf, sizeof(buf), "SET uapsd %d,%d,%d,%d;%d",
2349 ac_be, ac_bk, ac_vi, ac_vo, max_sp_len);
2350 ret2 = wpa_command(intf, buf);
2351
2352 if (ret1 && ret2) {
2353 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to set client mode "
2354 "UAPSD parameters.");
2355 return -2;
2356 }
2357
2358 if (ath6kl_client_uapsd(dut, intf, dut->client_uapsd) < 0) {
2359 send_resp(dut, conn, SIGMA_ERROR,
2360 "ErrorCode,Failed to set ath6kl QoS parameters");
2361 return 0;
2362 }
2363
2364 return 1;
2365}
2366
2367
2368static int cmd_sta_set_wmm(struct sigma_dut *dut, struct sigma_conn *conn,
2369 struct sigma_cmd *cmd)
2370{
2371 char buf[1000];
2372 const char *intf = get_param(cmd, "Interface");
2373 const char *grp = get_param(cmd, "Group");
2374 const char *act = get_param(cmd, "Action");
2375 const char *tid = get_param(cmd, "Tid");
2376 const char *dir = get_param(cmd, "Direction");
2377 const char *psb = get_param(cmd, "Psb");
2378 const char *up = get_param(cmd, "Up");
2379 const char *fixed = get_param(cmd, "Fixed");
2380 const char *size = get_param(cmd, "Size");
2381 const char *msize = get_param(cmd, "Maxsize");
2382 const char *minsi = get_param(cmd, "Min_srvc_intrvl");
2383 const char *maxsi = get_param(cmd, "Max_srvc_intrvl");
2384 const char *inact = get_param(cmd, "Inactivity");
2385 const char *sus = get_param(cmd, "Suspension");
2386 const char *mindr = get_param(cmd, "Mindatarate");
2387 const char *meandr = get_param(cmd, "Meandatarate");
2388 const char *peakdr = get_param(cmd, "Peakdatarate");
2389 const char *phyrate = get_param(cmd, "Phyrate");
2390 const char *burstsize = get_param(cmd, "Burstsize");
2391 const char *sba = get_param(cmd, "Sba");
2392 int direction;
2393 int handle;
Peng Xu93319622017-10-04 17:58:16 -07002394 float sba_fv = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002395 int fixed_int;
2396 int psb_ts;
2397
2398 if (intf == NULL || grp == NULL || act == NULL )
2399 return -1;
2400
2401 if (strcasecmp(act, "addts") == 0) {
2402 if (tid == NULL || dir == NULL || psb == NULL ||
2403 up == NULL || fixed == NULL || size == NULL)
2404 return -1;
2405
2406 /*
2407 * Note: Sigma CAPI spec lists uplink, downlink, and bidi as the
2408 * possible values, but WMM-AC and V-E test scripts use "UP,
2409 * "DOWN", and "BIDI".
2410 */
2411 if (strcasecmp(dir, "uplink") == 0 ||
2412 strcasecmp(dir, "up") == 0) {
2413 direction = 0;
2414 } else if (strcasecmp(dir, "downlink") == 0 ||
2415 strcasecmp(dir, "down") == 0) {
2416 direction = 1;
2417 } else if (strcasecmp(dir, "bidi") == 0) {
2418 direction = 2;
2419 } else {
2420 sigma_dut_print(dut, DUT_MSG_ERROR,
2421 "Direction %s not supported", dir);
2422 return -1;
2423 }
2424
2425 if (strcasecmp(psb, "legacy") == 0) {
2426 psb_ts = 0;
2427 } else if (strcasecmp(psb, "uapsd") == 0) {
2428 psb_ts = 1;
2429 } else {
2430 sigma_dut_print(dut, DUT_MSG_ERROR,
2431 "PSB %s not supported", psb);
2432 return -1;
2433 }
2434
2435 if (atoi(tid) < 0 || atoi(tid) > 7) {
2436 sigma_dut_print(dut, DUT_MSG_ERROR,
2437 "TID %s not supported", tid);
2438 return -1;
2439 }
2440
2441 if (strcasecmp(fixed, "true") == 0) {
2442 fixed_int = 1;
2443 } else {
2444 fixed_int = 0;
2445 }
2446
Peng Xu93319622017-10-04 17:58:16 -07002447 if (sba)
2448 sba_fv = atof(sba);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002449
2450 dut->dialog_token++;
2451 handle = 7000 + dut->dialog_token;
2452
2453 /*
2454 * size: convert to hex
2455 * maxsi: convert to hex
2456 * mindr: convert to hex
2457 * meandr: convert to hex
2458 * peakdr: convert to hex
2459 * burstsize: convert to hex
2460 * phyrate: convert to hex
2461 * sba: convert to hex with modification
2462 * minsi: convert to integer
2463 * sus: convert to integer
2464 * inact: convert to integer
2465 * maxsi: convert to integer
2466 */
2467
2468 /*
2469 * The Nominal MSDU Size field is 2 octets long and contains an
2470 * unsigned integer that specifies the nominal size, in octets,
2471 * of MSDUs belonging to the traffic under this traffic
2472 * specification and is defined in Figure 16. If the Fixed
2473 * subfield is set to 1, then the size of the MSDU is fixed and
2474 * is indicated by the Size Subfield. If the Fixed subfield is
2475 * set to 0, then the size of the MSDU might not be fixed and
2476 * the Size indicates the nominal MSDU size.
2477 *
2478 * The Surplus Bandwidth Allowance Factor field is 2 octets long
2479 * and specifies the excess allocation of time (and bandwidth)
2480 * over and above the stated rates required to transport an MSDU
2481 * belonging to the traffic in this TSPEC. This field is
2482 * represented as an unsigned binary number with an implicit
2483 * binary point after the leftmost 3 bits. For example, an SBA
2484 * of 1.75 is represented as 0x3800. This field is included to
2485 * account for retransmissions. As such, the value of this field
2486 * must be greater than unity.
2487 */
2488
2489 snprintf(buf, sizeof(buf),
2490 "iwpriv %s addTspec %d %s %d %d %s 0x%X"
2491 " 0x%X 0x%X 0x%X"
2492 " 0x%X 0x%X 0x%X"
2493 " 0x%X %d %d %d %d"
2494 " %d %d",
2495 intf, handle, tid, direction, psb_ts, up,
2496 (unsigned int) ((fixed_int << 15) | atoi(size)),
2497 msize ? atoi(msize) : 0,
2498 mindr ? atoi(mindr) : 0,
2499 meandr ? atoi(meandr) : 0,
2500 peakdr ? atoi(peakdr) : 0,
2501 burstsize ? atoi(burstsize) : 0,
2502 phyrate ? atoi(phyrate) : 0,
2503 sba ? ((unsigned int) (((int) sba_fv << 13) |
2504 (int)((sba_fv - (int) sba_fv) *
2505 8192))) : 0,
2506 minsi ? atoi(minsi) : 0,
2507 sus ? atoi(sus) : 0,
2508 0, 0,
2509 inact ? atoi(inact) : 0,
2510 maxsi ? atoi(maxsi) : 0);
2511
2512 if (system(buf) != 0) {
2513 sigma_dut_print(dut, DUT_MSG_ERROR,
2514 "iwpriv addtspec request failed");
2515 send_resp(dut, conn, SIGMA_ERROR,
2516 "errorCode,Failed to execute addTspec command");
2517 return 0;
2518 }
2519
2520 sigma_dut_print(dut, DUT_MSG_INFO,
2521 "iwpriv addtspec request send");
2522
2523 /* Mapping handle to a TID */
2524 dut->tid_to_handle[atoi(tid)] = handle;
2525 } else if (strcasecmp(act, "delts") == 0) {
2526 if (tid == NULL)
2527 return -1;
2528
2529 if (atoi(tid) < 0 || atoi(tid) > 7) {
2530 sigma_dut_print(dut, DUT_MSG_ERROR,
2531 "TID %s not supported", tid);
2532 send_resp(dut, conn, SIGMA_ERROR,
2533 "errorCode,Unsupported TID");
2534 return 0;
2535 }
2536
2537 handle = dut->tid_to_handle[atoi(tid)];
2538
2539 if (handle < 7000 || handle > 7255) {
2540 /* Invalid handle ie no mapping for that TID */
2541 sigma_dut_print(dut, DUT_MSG_ERROR,
2542 "handle-> %d not found", handle);
2543 }
2544
2545 snprintf(buf, sizeof(buf), "iwpriv %s delTspec %d",
2546 intf, handle);
2547
2548 if (system(buf) != 0) {
2549 sigma_dut_print(dut, DUT_MSG_ERROR,
2550 "iwpriv deltspec request failed");
2551 send_resp(dut, conn, SIGMA_ERROR,
2552 "errorCode,Failed to execute delTspec command");
2553 return 0;
2554 }
2555
2556 sigma_dut_print(dut, DUT_MSG_INFO,
2557 "iwpriv deltspec request send");
2558
2559 dut->tid_to_handle[atoi(tid)] = 0;
2560 } else {
2561 sigma_dut_print(dut, DUT_MSG_ERROR,
2562 "Action type %s not supported", act);
2563 send_resp(dut, conn, SIGMA_ERROR,
2564 "errorCode,Unsupported Action");
2565 return 0;
2566 }
2567
2568 return 1;
2569}
2570
2571
vamsi krishna52e16f92017-08-29 12:37:34 +05302572static int find_network(struct sigma_dut *dut, const char *ssid)
2573{
2574 char list[4096];
2575 char *pos;
2576
2577 sigma_dut_print(dut, DUT_MSG_DEBUG,
2578 "Search for profile based on SSID: '%s'", ssid);
2579 if (wpa_command_resp(get_station_ifname(), "LIST_NETWORKS",
2580 list, sizeof(list)) < 0)
2581 return -1;
2582 pos = strstr(list, ssid);
2583 if (!pos || pos == list || pos[-1] != '\t' || pos[strlen(ssid)] != '\t')
2584 return -1;
2585
2586 while (pos > list && pos[-1] != '\n')
2587 pos--;
2588 dut->infra_network_id = atoi(pos);
2589 snprintf(dut->infra_ssid, sizeof(dut->infra_ssid), "%s", ssid);
2590 return 0;
2591}
2592
2593
Sunil Dutt44595082018-02-12 19:41:45 +05302594#ifdef NL80211_SUPPORT
2595static int sta_config_rsnie(struct sigma_dut *dut, int val)
2596{
2597 struct nl_msg *msg;
2598 int ret;
2599 struct nlattr *params;
2600 int ifindex;
2601
2602 ifindex = if_nametoindex("wlan0");
2603 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
2604 NL80211_CMD_VENDOR)) ||
2605 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
2606 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
2607 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
2608 QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION) ||
2609 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
2610 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE, val)) {
2611 sigma_dut_print(dut, DUT_MSG_ERROR,
2612 "%s: err in adding vendor_cmd and vendor_data",
2613 __func__);
2614 nlmsg_free(msg);
2615 return -1;
2616 }
2617 nla_nest_end(msg, params);
2618
2619 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
2620 if (ret) {
2621 sigma_dut_print(dut, DUT_MSG_ERROR,
2622 "%s: err in send_and_recv_msgs, ret=%d",
2623 __func__, ret);
2624 return ret;
2625 }
2626
2627 return 0;
2628}
2629#endif /* NL80211_SUPPORT */
2630
2631
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002632static int cmd_sta_associate(struct sigma_dut *dut, struct sigma_conn *conn,
2633 struct sigma_cmd *cmd)
2634{
2635 /* const char *intf = get_param(cmd, "Interface"); */
2636 const char *ssid = get_param(cmd, "ssid");
2637 const char *wps_param = get_param(cmd, "WPS");
2638 const char *bssid = get_param(cmd, "bssid");
Jouni Malinen46a19b62017-06-23 14:31:27 +03002639 const char *chan = get_param(cmd, "channel");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002640 int wps = 0;
Jouni Malinen3c367e82017-06-23 17:01:47 +03002641 char buf[1000], extra[50];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002642
2643 if (ssid == NULL)
2644 return -1;
2645
Jouni Malinen3c367e82017-06-23 17:01:47 +03002646 if (dut->rsne_override) {
Sunil Dutt44595082018-02-12 19:41:45 +05302647#ifdef NL80211_SUPPORT
2648 if (get_driver_type() == DRIVER_WCN) {
2649 sta_config_rsnie(dut, 1);
2650 dut->config_rsnie = 1;
2651 }
2652#endif /* NL80211_SUPPORT */
Jouni Malinen3c367e82017-06-23 17:01:47 +03002653 snprintf(buf, sizeof(buf), "TEST_ASSOC_IE %s",
2654 dut->rsne_override);
2655 if (wpa_command(get_station_ifname(), buf) < 0) {
2656 send_resp(dut, conn, SIGMA_ERROR,
2657 "ErrorCode,Failed to set DEV_CONFIGURE_IE RSNE override");
2658 return 0;
2659 }
2660 }
2661
Jouni Malinen68143132017-09-02 02:34:08 +03002662 if (dut->sae_commit_override) {
2663 snprintf(buf, sizeof(buf), "SET sae_commit_override %s",
2664 dut->sae_commit_override);
2665 if (wpa_command(get_station_ifname(), buf) < 0) {
2666 send_resp(dut, conn, SIGMA_ERROR,
2667 "ErrorCode,Failed to set SAE commit override");
2668 return 0;
2669 }
2670 }
Ankita Bajaj1bde7942018-01-09 19:15:01 +05302671#ifdef ANDROID
2672 if (dut->fils_hlp)
2673 process_fils_hlp(dut);
2674#endif /* ANDROID */
Jouni Malinen68143132017-09-02 02:34:08 +03002675
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002676 if (wps_param &&
2677 (strcmp(wps_param, "1") == 0 || strcasecmp(wps_param, "On") == 0))
2678 wps = 1;
2679
2680 if (wps) {
2681 if (dut->wps_method == WFA_CS_WPS_NOT_READY) {
2682 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,WPS "
2683 "parameters not yet set");
2684 return 0;
2685 }
2686 if (dut->wps_method == WFA_CS_WPS_PBC) {
2687 if (wpa_command(get_station_ifname(), "WPS_PBC") < 0)
2688 return -2;
2689 } else {
2690 snprintf(buf, sizeof(buf), "WPS_PIN any %s",
2691 dut->wps_pin);
2692 if (wpa_command(get_station_ifname(), buf) < 0)
2693 return -2;
2694 }
2695 } else {
vamsi krishna52e16f92017-08-29 12:37:34 +05302696 if (strcmp(ssid, dut->infra_ssid) == 0) {
2697 sigma_dut_print(dut, DUT_MSG_DEBUG,
2698 "sta_associate for the most recently added network");
2699 } else if (find_network(dut, ssid) < 0) {
2700 sigma_dut_print(dut, DUT_MSG_DEBUG,
2701 "sta_associate for a previously stored network profile");
2702 send_resp(dut, conn, SIGMA_ERROR,
2703 "ErrorCode,Profile not found");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002704 return 0;
2705 }
2706
2707 if (bssid &&
2708 set_network(get_station_ifname(), dut->infra_network_id,
2709 "bssid", bssid) < 0) {
2710 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
2711 "Invalid bssid argument");
2712 return 0;
2713 }
2714
Jouni Malinen46a19b62017-06-23 14:31:27 +03002715 extra[0] = '\0';
2716 if (chan)
2717 snprintf(extra, sizeof(extra), " freq=%u",
2718 channel_to_freq(atoi(chan)));
2719 snprintf(buf, sizeof(buf), "SELECT_NETWORK %d%s",
2720 dut->infra_network_id, extra);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002721 if (wpa_command(get_station_ifname(), buf) < 0) {
2722 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to select "
2723 "network id %d on %s",
2724 dut->infra_network_id,
2725 get_station_ifname());
2726 return -2;
2727 }
2728 }
2729
2730 return 1;
2731}
2732
2733
2734static int run_hs20_osu(struct sigma_dut *dut, const char *params)
2735{
2736 char buf[500], cmd[200];
2737 int res;
2738
2739 /* Use hs20-osu-client file at the current dir, if found; otherwise use
2740 * default path */
2741 res = snprintf(cmd, sizeof(cmd),
2742 "%s -w \"%s\" -r hs20-osu-client.res %s%s -dddKt -f Logs/hs20-osu-client.txt",
2743 file_exists("./hs20-osu-client") ?
2744 "./hs20-osu-client" : "hs20-osu-client",
2745 sigma_wpas_ctrl,
2746 dut->summary_log ? "-s " : "",
2747 dut->summary_log ? dut->summary_log : "");
2748 if (res < 0 || res >= (int) sizeof(cmd))
2749 return -1;
2750
2751 res = snprintf(buf, sizeof(buf), "%s %s", cmd, params);
2752 if (res < 0 || res >= (int) sizeof(buf))
2753 return -1;
2754 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
2755
2756 if (system(buf) != 0) {
2757 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to run: %s", buf);
2758 return -1;
2759 }
2760 sigma_dut_print(dut, DUT_MSG_DEBUG,
2761 "Completed hs20-osu-client operation");
2762
2763 return 0;
2764}
2765
2766
2767static int download_ppsmo(struct sigma_dut *dut,
2768 struct sigma_conn *conn,
2769 const char *intf,
2770 struct sigma_cmd *cmd)
2771{
2772 const char *name, *path, *val;
2773 char url[500], buf[600], fbuf[100];
2774 char *fqdn = NULL;
2775
2776 name = get_param(cmd, "FileName");
2777 path = get_param(cmd, "FilePath");
2778 if (name == NULL || path == NULL)
2779 return -1;
2780
2781 if (strcasecmp(path, "VendorSpecific") == 0) {
2782 snprintf(url, sizeof(url), "PPS/%s", name);
2783 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured PPS MO "
2784 "from the device (%s)", url);
2785 if (!file_exists(url)) {
2786 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
2787 "PPS MO file does not exist");
2788 return 0;
2789 }
2790 snprintf(buf, sizeof(buf), "cp %s pps-tnds.xml", url);
2791 if (system(buf) != 0) {
2792 send_resp(dut, conn, SIGMA_ERROR,
2793 "errorCode,Failed to copy PPS MO");
2794 return 0;
2795 }
2796 } else if (strncasecmp(path, "http:", 5) != 0 &&
2797 strncasecmp(path, "https:", 6) != 0) {
2798 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
2799 "Unsupported FilePath value");
2800 return 0;
2801 } else {
2802 snprintf(url, sizeof(url), "%s/%s", path, name);
2803 sigma_dut_print(dut, DUT_MSG_INFO, "Downloading PPS MO from %s",
2804 url);
2805 snprintf(buf, sizeof(buf), "wget -T 10 -t 3 -O pps-tnds.xml '%s'", url);
2806 remove("pps-tnds.xml");
2807 if (system(buf) != 0) {
2808 send_resp(dut, conn, SIGMA_ERROR,
2809 "errorCode,Failed to download PPS MO");
2810 return 0;
2811 }
2812 }
2813
2814 if (run_hs20_osu(dut, "from_tnds pps-tnds.xml pps.xml") < 0) {
2815 send_resp(dut, conn, SIGMA_ERROR,
2816 "errorCode,Failed to parse downloaded PPSMO");
2817 return 0;
2818 }
2819 unlink("pps-tnds.xml");
2820
2821 val = get_param(cmd, "managementTreeURI");
2822 if (val) {
2823 const char *pos, *end;
2824 sigma_dut_print(dut, DUT_MSG_DEBUG, "managementTreeURI: %s",
2825 val);
2826 if (strncmp(val, "./Wi-Fi/", 8) != 0) {
2827 send_resp(dut, conn, SIGMA_ERROR,
2828 "errorCode,Invalid managementTreeURI prefix");
2829 return 0;
2830 }
2831 pos = val + 8;
2832 end = strchr(pos, '/');
2833 if (end == NULL ||
2834 strcmp(end, "/PerProviderSubscription") != 0) {
2835 send_resp(dut, conn, SIGMA_ERROR,
2836 "errorCode,Invalid managementTreeURI postfix");
2837 return 0;
2838 }
2839 if (end - pos >= (int) sizeof(fbuf)) {
2840 send_resp(dut, conn, SIGMA_ERROR,
2841 "errorCode,Too long FQDN in managementTreeURI");
2842 return 0;
2843 }
2844 memcpy(fbuf, pos, end - pos);
2845 fbuf[end - pos] = '\0';
2846 fqdn = fbuf;
2847 sigma_dut_print(dut, DUT_MSG_INFO,
2848 "FQDN from managementTreeURI: %s", fqdn);
2849 } else if (run_hs20_osu(dut, "get_fqdn pps.xml") == 0) {
2850 FILE *f = fopen("pps-fqdn", "r");
2851 if (f) {
2852 if (fgets(fbuf, sizeof(fbuf), f)) {
2853 fbuf[sizeof(fbuf) - 1] = '\0';
2854 fqdn = fbuf;
2855 sigma_dut_print(dut, DUT_MSG_DEBUG,
2856 "Use FQDN %s", fqdn);
2857 }
2858 fclose(f);
2859 }
2860 }
2861
2862 if (fqdn == NULL) {
2863 send_resp(dut, conn, SIGMA_ERROR,
2864 "errorCode,No FQDN specified");
2865 return 0;
2866 }
2867
2868 mkdir("SP", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
2869 snprintf(buf, sizeof(buf), "SP/%s", fqdn);
2870 mkdir(buf, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
2871
2872 snprintf(buf, sizeof(buf), "SP/%s/pps.xml", fqdn);
2873 if (rename("pps.xml", buf) < 0) {
2874 send_resp(dut, conn, SIGMA_ERROR,
2875 "errorCode,Could not move PPS MO");
2876 return 0;
2877 }
2878
2879 if (strcasecmp(path, "VendorSpecific") == 0) {
2880 snprintf(buf, sizeof(buf), "cp Certs/ca.pem SP/%s/ca.pem",
2881 fqdn);
2882 if (system(buf)) {
2883 send_resp(dut, conn, SIGMA_ERROR,
2884 "errorCode,Failed to copy OSU CA cert");
2885 return 0;
2886 }
2887
2888 snprintf(buf, sizeof(buf),
2889 "cp Certs/aaa-ca.pem SP/%s/aaa-ca.pem",
2890 fqdn);
2891 if (system(buf)) {
2892 send_resp(dut, conn, SIGMA_ERROR,
2893 "errorCode,Failed to copy AAA CA cert");
2894 return 0;
2895 }
2896 } else {
2897 snprintf(buf, sizeof(buf),
2898 "dl_osu_ca SP/%s/pps.xml SP/%s/ca.pem",
2899 fqdn, fqdn);
2900 if (run_hs20_osu(dut, buf) < 0) {
2901 send_resp(dut, conn, SIGMA_ERROR,
2902 "errorCode,Failed to download OSU CA cert");
2903 return 0;
2904 }
2905
2906 snprintf(buf, sizeof(buf),
2907 "dl_aaa_ca SP/%s/pps.xml SP/%s/aaa-ca.pem",
2908 fqdn, fqdn);
2909 if (run_hs20_osu(dut, buf) < 0) {
2910 sigma_dut_print(dut, DUT_MSG_INFO,
2911 "Failed to download AAA CA cert");
2912 }
2913 }
2914
2915 if (file_exists("next-client-cert.pem")) {
2916 snprintf(buf, sizeof(buf), "SP/%s/client-cert.pem", fqdn);
2917 if (rename("next-client-cert.pem", buf) < 0) {
2918 send_resp(dut, conn, SIGMA_ERROR,
2919 "errorCode,Could not move client certificate");
2920 return 0;
2921 }
2922 }
2923
2924 if (file_exists("next-client-key.pem")) {
2925 snprintf(buf, sizeof(buf), "SP/%s/client-key.pem", fqdn);
2926 if (rename("next-client-key.pem", buf) < 0) {
2927 send_resp(dut, conn, SIGMA_ERROR,
2928 "errorCode,Could not move client key");
2929 return 0;
2930 }
2931 }
2932
2933 snprintf(buf, sizeof(buf), "set_pps SP/%s/pps.xml", fqdn);
2934 if (run_hs20_osu(dut, buf) < 0) {
2935 send_resp(dut, conn, SIGMA_ERROR,
2936 "errorCode,Failed to configure credential from "
2937 "PPSMO");
2938 return 0;
2939 }
2940
2941 return 1;
2942}
2943
2944
2945static int download_cert(struct sigma_dut *dut,
2946 struct sigma_conn *conn,
2947 const char *intf,
2948 struct sigma_cmd *cmd)
2949{
2950 const char *name, *path;
2951 char url[500], buf[600];
2952
2953 name = get_param(cmd, "FileName");
2954 path = get_param(cmd, "FilePath");
2955 if (name == NULL || path == NULL)
2956 return -1;
2957
2958 if (strcasecmp(path, "VendorSpecific") == 0) {
2959 snprintf(url, sizeof(url), "Certs/%s-cert.pem", name);
2960 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured client "
2961 "certificate from the device (%s)", url);
2962 if (!file_exists(url)) {
2963 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
2964 "certificate file does not exist");
2965 return 0;
2966 }
2967 snprintf(buf, sizeof(buf), "cp %s next-client-cert.pem", url);
2968 if (system(buf) != 0) {
2969 send_resp(dut, conn, SIGMA_ERROR,
2970 "errorCode,Failed to copy client "
2971 "certificate");
2972 return 0;
2973 }
2974
2975 snprintf(url, sizeof(url), "Certs/%s-key.pem", name);
2976 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured client "
2977 "private key from the device (%s)", url);
2978 if (!file_exists(url)) {
2979 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
2980 "private key file does not exist");
2981 return 0;
2982 }
2983 snprintf(buf, sizeof(buf), "cp %s next-client-key.pem", url);
2984 if (system(buf) != 0) {
2985 send_resp(dut, conn, SIGMA_ERROR,
2986 "errorCode,Failed to copy client key");
2987 return 0;
2988 }
2989 } else if (strncasecmp(path, "http:", 5) != 0 &&
2990 strncasecmp(path, "https:", 6) != 0) {
2991 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
2992 "Unsupported FilePath value");
2993 return 0;
2994 } else {
2995 snprintf(url, sizeof(url), "%s/%s.pem", path, name);
2996 sigma_dut_print(dut, DUT_MSG_INFO, "Downloading client "
2997 "certificate/key from %s", url);
2998 snprintf(buf, sizeof(buf),
2999 "wget -T 10 -t 3 -O next-client-cert.pem '%s'", url);
3000 if (system(buf) != 0) {
3001 send_resp(dut, conn, SIGMA_ERROR,
3002 "errorCode,Failed to download client "
3003 "certificate");
3004 return 0;
3005 }
3006
3007 if (system("cp next-client-cert.pem next-client-key.pem") != 0)
3008 {
3009 send_resp(dut, conn, SIGMA_ERROR,
3010 "errorCode,Failed to copy client key");
3011 return 0;
3012 }
3013 }
3014
3015 return 1;
3016}
3017
3018
3019static int cmd_sta_preset_testparameters_hs2_r2(struct sigma_dut *dut,
3020 struct sigma_conn *conn,
3021 const char *intf,
3022 struct sigma_cmd *cmd)
3023{
3024 const char *val;
3025
3026 val = get_param(cmd, "FileType");
3027 if (val && strcasecmp(val, "PPSMO") == 0)
3028 return download_ppsmo(dut, conn, intf, cmd);
3029 if (val && strcasecmp(val, "CERT") == 0)
3030 return download_cert(dut, conn, intf, cmd);
3031 if (val) {
3032 send_resp(dut, conn, SIGMA_ERROR,
3033 "ErrorCode,Unsupported FileType");
3034 return 0;
3035 }
3036
3037 return 1;
3038}
3039
3040
Ankita Bajaja2cb5672017-10-25 16:08:28 +05303041static int cmd_sta_preset_testparameters_oce(struct sigma_dut *dut,
3042 struct sigma_conn *conn,
3043 const char *intf,
3044 struct sigma_cmd *cmd)
3045{
3046 const char *val;
Ankita Bajaj1bde7942018-01-09 19:15:01 +05303047 char buf[1000];
3048 char text[20];
3049 unsigned char addr[ETH_ALEN];
Ankita Bajaja2cb5672017-10-25 16:08:28 +05303050
3051 val = get_param(cmd, "OCESupport");
3052 if (val && strcasecmp(val, "Disable") == 0) {
3053 if (wpa_command(intf, "SET oce 0") < 0) {
3054 send_resp(dut, conn, SIGMA_ERROR,
3055 "ErrorCode,Failed to disable OCE");
3056 return 0;
3057 }
3058 } else if (val && strcasecmp(val, "Enable") == 0) {
3059 if (wpa_command(intf, "SET oce 1") < 0) {
3060 send_resp(dut, conn, SIGMA_ERROR,
3061 "ErrorCode,Failed to enable OCE");
3062 return 0;
3063 }
3064 }
3065
vamsi krishnaa2799492017-12-05 14:28:01 +05303066 val = get_param(cmd, "FILScap");
3067 if (val && (atoi(val) == 1)) {
3068 if (wpa_command(intf, "SET disable_fils 0") < 0) {
3069 send_resp(dut, conn, SIGMA_ERROR,
3070 "ErrorCode,Failed to enable FILS");
3071 return 0;
3072 }
3073 } else if (val && (atoi(val) == 0)) {
3074 if (wpa_command(intf, "SET disable_fils 1") < 0) {
3075 send_resp(dut, conn, SIGMA_ERROR,
3076 "ErrorCode,Failed to disable FILS");
3077 return 0;
3078 }
3079 }
3080
Ankita Bajaj1bde7942018-01-09 19:15:01 +05303081 val = get_param(cmd, "FILSHLP");
3082 if (val && strcasecmp(val, "Enable") == 0) {
3083 if (get_wpa_status(get_station_ifname(), "address", text,
3084 sizeof(text)) < 0)
3085 return -2;
3086 hwaddr_aton(text, addr);
3087 snprintf(buf, sizeof(buf),
3088 "FILS_HLP_REQ_ADD ff:ff:ff:ff:ff:ff "
3089 "080045100140000040004011399e00000000ffffffff00440043"
3090 "012cb30001010600fd4f46410000000000000000000000000000"
3091 "000000000000"
3092 "%02x%02x%02x%02x%02x%02x"
3093 "0000000000000000000000000000000000000000000000000000"
3094 "0000000000000000000000000000000000000000000000000000"
3095 "0000000000000000000000000000000000000000000000000000"
3096 "0000000000000000000000000000000000000000000000000000"
3097 "0000000000000000000000000000000000000000000000000000"
3098 "0000000000000000000000000000000000000000000000000000"
3099 "0000000000000000000000000000000000000000000000000000"
3100 "0000000000000000000000000000000000000000638253633501"
3101 "013d0701000af549d29b390205dc3c12616e64726f69642d6468"
3102 "63702d382e302e30370a0103060f1a1c333a3b2b5000ff00",
3103 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
3104 if (wpa_command(intf, buf)) {
3105 send_resp(dut, conn, SIGMA_ERROR,
3106 "ErrorCode,Failed to add HLP");
3107 return 0;
3108 }
3109 dut->fils_hlp = 1;
3110 }
3111
Ankita Bajaja2cb5672017-10-25 16:08:28 +05303112 return 1;
3113}
3114
3115
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003116static void ath_sta_set_noack(struct sigma_dut *dut, const char *intf,
3117 const char *val)
3118{
3119 int counter = 0;
3120 char token[50];
3121 char *result;
3122 char buf[100];
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05303123 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003124
Peng Xub8fc5cc2017-05-10 17:27:28 -07003125 strlcpy(token, val, sizeof(token));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003126 token[sizeof(token) - 1] = '\0';
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05303127 result = strtok_r(token, ":", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003128 while (result) {
3129 if (strcmp(result, "disable") == 0) {
3130 snprintf(buf, sizeof(buf),
3131 "iwpriv %s noackpolicy %d 1 0",
3132 intf, counter);
3133 } else {
3134 snprintf(buf, sizeof(buf),
3135 "iwpriv %s noackpolicy %d 1 1",
3136 intf, counter);
3137 }
3138 if (system(buf) != 0) {
3139 sigma_dut_print(dut, DUT_MSG_ERROR,
3140 "iwpriv noackpolicy failed");
3141 }
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05303142 result = strtok_r(NULL, ":", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003143 counter++;
3144 }
3145}
3146
3147
3148static void ath_sta_set_rts(struct sigma_dut *dut, const char *intf,
3149 const char *val)
3150{
3151 char buf[100];
3152
3153 snprintf(buf, sizeof(buf), "iwconfig %s rts %s", intf, val);
3154 if (system(buf) != 0) {
3155 sigma_dut_print(dut, DUT_MSG_ERROR, "iwconfig RTS failed");
3156 }
3157}
3158
3159
3160static void ath_sta_set_wmm(struct sigma_dut *dut, const char *intf,
3161 const char *val)
3162{
3163 char buf[100];
3164
3165 if (strcasecmp(val, "off") == 0) {
3166 snprintf(buf, sizeof(buf), "iwpriv %s wmm 0", intf);
3167 if (system(buf) != 0) {
3168 sigma_dut_print(dut, DUT_MSG_ERROR,
3169 "Failed to turn off WMM");
3170 }
3171 }
3172}
3173
3174
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08003175static int wcn_sta_set_wmm(struct sigma_dut *dut, const char *intf,
3176 const char *val)
3177{
3178#ifdef NL80211_SUPPORT
3179 struct nl_msg *msg;
3180 int ret = 0;
3181 struct nlattr *params;
3182 int ifindex;
3183 int wmmenable = 1;
3184
3185 if (val &&
3186 (strcasecmp(val, "off") == 0 || strcmp(val, "0") == 0))
3187 wmmenable = 0;
3188
3189 ifindex = if_nametoindex(intf);
3190 if (ifindex == 0) {
3191 sigma_dut_print(dut, DUT_MSG_ERROR,
3192 "%s: Index for interface %s failed",
3193 __func__, intf);
3194 return -1;
3195 }
3196
3197 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
3198 NL80211_CMD_VENDOR)) ||
3199 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
3200 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
3201 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
3202 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
3203 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
3204 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WMM_ENABLE,
3205 wmmenable)) {
3206 sigma_dut_print(dut, DUT_MSG_ERROR,
3207 "%s: err in adding vendor_cmd and vendor_data",
3208 __func__);
3209 nlmsg_free(msg);
3210 return -1;
3211 }
3212 nla_nest_end(msg, params);
3213
3214 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
3215 if (ret) {
3216 sigma_dut_print(dut, DUT_MSG_ERROR,
3217 "%s: err in send_and_recv_msgs, ret=%d",
3218 __func__, ret);
3219 }
3220 return ret;
3221#else /* NL80211_SUPPORT */
3222 sigma_dut_print(dut, DUT_MSG_ERROR,
3223 "WMM cannot be changed without NL80211_SUPPORT defined");
3224 return -1;
3225#endif /* NL80211_SUPPORT */
3226}
3227
3228
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003229static void ath_sta_set_sgi(struct sigma_dut *dut, const char *intf,
3230 const char *val)
3231{
3232 char buf[100];
3233 int sgi20;
3234
3235 sgi20 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
3236
3237 snprintf(buf, sizeof(buf), "iwpriv %s shortgi %d", intf, sgi20);
3238 if (system(buf) != 0)
3239 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv shortgi failed");
3240}
3241
3242
3243static void ath_sta_set_11nrates(struct sigma_dut *dut, const char *intf,
3244 const char *val)
3245{
3246 char buf[100];
Pradeep Reddy POTTETI67376b72016-10-25 20:08:17 +05303247 int rate_code, v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003248
3249 /* Disable Tx Beam forming when using a fixed rate */
3250 ath_disable_txbf(dut, intf);
3251
Pradeep Reddy POTTETI67376b72016-10-25 20:08:17 +05303252 v = atoi(val);
3253 if (v < 0 || v > 32) {
3254 sigma_dut_print(dut, DUT_MSG_ERROR,
3255 "Invalid Fixed MCS rate: %d", v);
3256 return;
3257 }
3258 rate_code = 0x80 + v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003259
3260 snprintf(buf, sizeof(buf), "iwpriv %s set11NRates 0x%x",
3261 intf, rate_code);
3262 if (system(buf) != 0) {
3263 sigma_dut_print(dut, DUT_MSG_ERROR,
3264 "iwpriv set11NRates failed");
3265 }
3266
3267 /* Channel width gets messed up, fix this */
3268 snprintf(buf, sizeof(buf), "iwpriv %s chwidth %d", intf, dut->chwidth);
3269 if (system(buf) != 0)
3270 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv chwidth failed");
3271}
3272
3273
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08003274static void iwpriv_sta_set_amsdu(struct sigma_dut *dut, const char *intf,
3275 const char *val)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003276{
3277 char buf[60];
3278
3279 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)
3280 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 2", intf);
3281 else
3282 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 1", intf);
3283
3284 if (system(buf) != 0)
3285 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv amsdu failed");
3286}
3287
3288
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07003289static int iwpriv_sta_set_ampdu(struct sigma_dut *dut, const char *intf,
3290 int ampdu)
3291{
3292 char buf[60];
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08003293 int maxaggregation = 63;
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07003294
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08003295 if (ampdu)
3296 ampdu = maxaggregation;
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07003297 snprintf(buf, sizeof(buf), "iwpriv %s ampdu %d", intf, ampdu);
3298 if (system(buf) != 0) {
3299 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv ampdu failed");
3300 return -1;
3301 }
3302
3303 return 0;
3304}
3305
3306
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003307static void ath_sta_set_stbc(struct sigma_dut *dut, const char *intf,
3308 const char *val)
3309{
3310 char buf[60];
3311
3312 snprintf(buf, sizeof(buf), "iwpriv %s tx_stbc %s", intf, val);
3313 if (system(buf) != 0) {
3314 sigma_dut_print(dut, DUT_MSG_ERROR,
3315 "iwpriv tx_stbc failed");
3316 }
3317
3318 snprintf(buf, sizeof(buf), "iwpriv %s rx_stbc %s", intf, val);
3319 if (system(buf) != 0) {
3320 sigma_dut_print(dut, DUT_MSG_ERROR,
3321 "iwpriv rx_stbc failed");
3322 }
3323}
3324
3325
3326static int wcn_sta_set_cts_width(struct sigma_dut *dut, const char *intf,
3327 const char *val)
3328{
3329 char buf[60];
3330
Peng Xucc317ed2017-05-18 16:44:37 -07003331 if (strcmp(val, "160") == 0) {
3332 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 5", intf);
3333 } else if (strcmp(val, "80") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003334 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 3", intf);
3335 } else if (strcmp(val, "40") == 0) {
3336 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 2", intf);
3337 } else if (strcmp(val, "20") == 0) {
3338 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 1", intf);
3339 } else if (strcasecmp(val, "Auto") == 0) {
3340 buf[0] = '\0';
3341 } else {
3342 sigma_dut_print(dut, DUT_MSG_ERROR,
3343 "WIDTH/CTS_WIDTH value not supported");
3344 return -1;
3345 }
3346
3347 if (buf[0] != '\0' && system(buf) != 0) {
3348 sigma_dut_print(dut, DUT_MSG_ERROR,
3349 "Failed to set WIDTH/CTS_WIDTH");
3350 return -1;
3351 }
3352
3353 return 0;
3354}
3355
3356
3357int ath_set_width(struct sigma_dut *dut, struct sigma_conn *conn,
3358 const char *intf, const char *val)
3359{
3360 char buf[60];
3361
3362 if (strcasecmp(val, "Auto") == 0) {
3363 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 0", intf);
3364 dut->chwidth = 0;
3365 } else if (strcasecmp(val, "20") == 0) {
3366 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 0", intf);
3367 dut->chwidth = 0;
3368 } else if (strcasecmp(val, "40") == 0) {
3369 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 1", intf);
3370 dut->chwidth = 1;
3371 } else if (strcasecmp(val, "80") == 0) {
3372 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 2", intf);
3373 dut->chwidth = 2;
3374 } else if (strcasecmp(val, "160") == 0) {
3375 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 3", intf);
3376 dut->chwidth = 3;
3377 } else {
3378 send_resp(dut, conn, SIGMA_ERROR,
3379 "ErrorCode,WIDTH not supported");
3380 return -1;
3381 }
3382
3383 if (system(buf) != 0) {
3384 sigma_dut_print(dut, DUT_MSG_ERROR,
3385 "iwpriv chwidth failed");
3386 }
3387
3388 return 0;
3389}
3390
3391
3392static int wcn_sta_set_sp_stream(struct sigma_dut *dut, const char *intf,
3393 const char *val)
3394{
3395 char buf[60];
Arif Hussainac6c5112018-05-25 17:34:00 -07003396 int sta_nss;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003397
Amarnath Hullur Subramanyamd5374fa2018-02-25 19:00:24 -08003398 if (strcmp(val, "1SS") == 0 || strcmp(val, "1") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003399 snprintf(buf, sizeof(buf), "iwpriv %s nss 1", intf);
Arif Hussainac6c5112018-05-25 17:34:00 -07003400 sta_nss = 1;
Amarnath Hullur Subramanyamd5374fa2018-02-25 19:00:24 -08003401 } else if (strcmp(val, "2SS") == 0 || strcmp(val, "2") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003402 snprintf(buf, sizeof(buf), "iwpriv %s nss 2", intf);
Arif Hussainac6c5112018-05-25 17:34:00 -07003403 sta_nss = 2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003404 } else {
3405 sigma_dut_print(dut, DUT_MSG_ERROR,
3406 "SP_STREAM value not supported");
3407 return -1;
3408 }
3409
3410 if (system(buf) != 0) {
3411 sigma_dut_print(dut, DUT_MSG_ERROR,
3412 "Failed to set SP_STREAM");
3413 return -1;
3414 }
3415
Arif Hussainac6c5112018-05-25 17:34:00 -07003416 dut->sta_nss = sta_nss;
3417
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003418 return 0;
3419}
3420
3421
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05303422static void wcn_sta_set_stbc(struct sigma_dut *dut, const char *intf,
3423 const char *val)
3424{
3425 char buf[60];
3426
3427 snprintf(buf, sizeof(buf), "iwpriv %s tx_stbc %s", intf, val);
3428 if (system(buf) != 0)
3429 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv tx_stbc failed");
3430
3431 snprintf(buf, sizeof(buf), "iwpriv %s rx_stbc %s", intf, val);
3432 if (system(buf) != 0)
3433 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv rx_stbc failed");
3434}
3435
3436
Ashwini Patil68d02cd2017-01-10 15:39:16 +05303437static int mbo_set_cellular_data_capa(struct sigma_dut *dut,
3438 struct sigma_conn *conn,
3439 const char *intf, int capa)
3440{
3441 char buf[32];
3442
3443 if (capa > 0 && capa < 4) {
3444 snprintf(buf, sizeof(buf), "SET mbo_cell_capa %d", capa);
3445 if (wpa_command(intf, buf) < 0) {
3446 send_resp(dut, conn, SIGMA_ERROR,
3447 "ErrorCode, Failed to set cellular data capability");
3448 return 0;
3449 }
3450 return 1;
3451 }
3452
3453 sigma_dut_print(dut, DUT_MSG_ERROR,
3454 "Invalid Cellular data capability: %d", capa);
3455 send_resp(dut, conn, SIGMA_INVALID,
3456 "ErrorCode,Invalid cellular data capability");
3457 return 0;
3458}
3459
3460
Ashwini Patil9183fdb2017-04-13 16:58:25 +05303461static int mbo_set_roaming(struct sigma_dut *dut, struct sigma_conn *conn,
3462 const char *intf, const char *val)
3463{
3464 if (strcasecmp(val, "Disable") == 0) {
3465 if (wpa_command(intf, "SET roaming 0") < 0) {
3466 send_resp(dut, conn, SIGMA_ERROR,
3467 "ErrorCode,Failed to disable roaming");
3468 return 0;
3469 }
3470 return 1;
3471 }
3472
3473 if (strcasecmp(val, "Enable") == 0) {
3474 if (wpa_command(intf, "SET roaming 1") < 0) {
3475 send_resp(dut, conn, SIGMA_ERROR,
3476 "ErrorCode,Failed to enable roaming");
3477 return 0;
3478 }
3479 return 1;
3480 }
3481
3482 sigma_dut_print(dut, DUT_MSG_ERROR,
3483 "Invalid value provided for roaming: %s", val);
3484 send_resp(dut, conn, SIGMA_INVALID,
3485 "ErrorCode,Unknown value provided for Roaming");
3486 return 0;
3487}
3488
3489
Ashwini Patila75de5a2017-04-13 16:35:05 +05303490static int mbo_set_assoc_disallow(struct sigma_dut *dut,
3491 struct sigma_conn *conn,
3492 const char *intf, const char *val)
3493{
3494 if (strcasecmp(val, "Disable") == 0) {
3495 if (wpa_command(intf, "SET ignore_assoc_disallow 1") < 0) {
3496 send_resp(dut, conn, SIGMA_ERROR,
3497 "ErrorCode,Failed to disable Assoc_disallow");
3498 return 0;
3499 }
3500 return 1;
3501 }
3502
3503 if (strcasecmp(val, "Enable") == 0) {
3504 if (wpa_command(intf, "SET ignore_assoc_disallow 0") < 0) {
3505 send_resp(dut, conn, SIGMA_ERROR,
3506 "ErrorCode,Failed to enable Assoc_disallow");
3507 return 0;
3508 }
3509 return 1;
3510 }
3511
3512 sigma_dut_print(dut, DUT_MSG_ERROR,
3513 "Invalid value provided for Assoc_disallow: %s", val);
3514 send_resp(dut, conn, SIGMA_INVALID,
3515 "ErrorCode,Unknown value provided for Assoc_disallow");
3516 return 0;
3517}
3518
3519
Ashwini Patilc63161e2017-04-13 16:30:23 +05303520static int mbo_set_bss_trans_req(struct sigma_dut *dut, struct sigma_conn *conn,
3521 const char *intf, const char *val)
3522{
3523 if (strcasecmp(val, "Reject") == 0) {
3524 if (wpa_command(intf, "SET reject_btm_req_reason 1") < 0) {
3525 send_resp(dut, conn, SIGMA_ERROR,
3526 "ErrorCode,Failed to Reject BTM Request");
3527 return 0;
3528 }
3529 return 1;
3530 }
3531
3532 if (strcasecmp(val, "Accept") == 0) {
3533 if (wpa_command(intf, "SET reject_btm_req_reason 0") < 0) {
3534 send_resp(dut, conn, SIGMA_ERROR,
3535 "ErrorCode,Failed to Accept BTM Request");
3536 return 0;
3537 }
3538 return 1;
3539 }
3540
3541 sigma_dut_print(dut, DUT_MSG_ERROR,
3542 "Invalid value provided for BSS_Transition: %s", val);
3543 send_resp(dut, conn, SIGMA_INVALID,
3544 "ErrorCode,Unknown value provided for BSS_Transition");
3545 return 0;
3546}
3547
3548
Ashwini Patil00402582017-04-13 12:29:39 +05303549static int mbo_set_non_pref_ch_list(struct sigma_dut *dut,
3550 struct sigma_conn *conn,
3551 const char *intf,
3552 struct sigma_cmd *cmd)
3553{
3554 const char *ch, *pref, *op_class, *reason;
3555 char buf[120];
3556 int len, ret;
3557
3558 pref = get_param(cmd, "Ch_Pref");
3559 if (!pref)
3560 return 1;
3561
3562 if (strcasecmp(pref, "clear") == 0) {
3563 free(dut->non_pref_ch_list);
3564 dut->non_pref_ch_list = NULL;
3565 } else {
3566 op_class = get_param(cmd, "Ch_Op_Class");
3567 if (!op_class) {
3568 send_resp(dut, conn, SIGMA_INVALID,
3569 "ErrorCode,Ch_Op_Class not provided");
3570 return 0;
3571 }
3572
3573 ch = get_param(cmd, "Ch_Pref_Num");
3574 if (!ch) {
3575 send_resp(dut, conn, SIGMA_INVALID,
3576 "ErrorCode,Ch_Pref_Num not provided");
3577 return 0;
3578 }
3579
3580 reason = get_param(cmd, "Ch_Reason_Code");
3581 if (!reason) {
3582 send_resp(dut, conn, SIGMA_INVALID,
3583 "ErrorCode,Ch_Reason_Code not provided");
3584 return 0;
3585 }
3586
3587 if (!dut->non_pref_ch_list) {
3588 dut->non_pref_ch_list =
3589 calloc(1, NON_PREF_CH_LIST_SIZE);
3590 if (!dut->non_pref_ch_list) {
3591 send_resp(dut, conn, SIGMA_ERROR,
3592 "ErrorCode,Failed to allocate memory for non_pref_ch_list");
3593 return 0;
3594 }
3595 }
3596 len = strlen(dut->non_pref_ch_list);
3597 ret = snprintf(dut->non_pref_ch_list + len,
3598 NON_PREF_CH_LIST_SIZE - len,
3599 " %s:%s:%s:%s", op_class, ch, pref, reason);
3600 if (ret > 0 && ret < NON_PREF_CH_LIST_SIZE - len) {
3601 sigma_dut_print(dut, DUT_MSG_DEBUG, "non_pref_list: %s",
3602 dut->non_pref_ch_list);
3603 } else {
3604 sigma_dut_print(dut, DUT_MSG_ERROR,
3605 "snprintf failed for non_pref_list, ret = %d",
3606 ret);
3607 send_resp(dut, conn, SIGMA_ERROR,
3608 "ErrorCode,snprintf failed");
3609 free(dut->non_pref_ch_list);
3610 dut->non_pref_ch_list = NULL;
3611 return 0;
3612 }
3613 }
3614
3615 ret = snprintf(buf, sizeof(buf), "SET non_pref_chan%s",
3616 dut->non_pref_ch_list ? dut->non_pref_ch_list : " ");
3617 if (ret < 0 || ret >= (int) sizeof(buf)) {
3618 sigma_dut_print(dut, DUT_MSG_DEBUG,
3619 "snprintf failed for set non_pref_chan, ret: %d",
3620 ret);
3621 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,snprint failed");
3622 return 0;
3623 }
3624
3625 if (wpa_command(intf, buf) < 0) {
3626 send_resp(dut, conn, SIGMA_ERROR,
3627 "ErrorCode,Failed to set non-preferred channel list");
3628 return 0;
3629 }
3630
3631 return 1;
3632}
3633
3634
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08003635#ifdef NL80211_SUPPORT
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08003636
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08003637static int sta_set_he_fragmentation(struct sigma_dut *dut, const char *intf,
3638 enum he_fragmentation_val frag)
3639{
3640 struct nl_msg *msg;
3641 int ret = 0;
3642 struct nlattr *params;
3643 int ifindex;
3644
3645 ifindex = if_nametoindex(intf);
3646 if (ifindex == 0) {
3647 sigma_dut_print(dut, DUT_MSG_ERROR,
3648 "%s: Index for interface %s failed",
3649 __func__, intf);
3650 return -1;
3651 }
3652
3653 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
3654 NL80211_CMD_VENDOR)) ||
3655 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
3656 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
3657 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
3658 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
3659 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
3660 nla_put_u8(msg,
3661 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_FRAGMENTATION,
3662 frag)) {
3663 sigma_dut_print(dut, DUT_MSG_ERROR,
3664 "%s: err in adding vendor_cmd and vendor_data",
3665 __func__);
3666 nlmsg_free(msg);
3667 return -1;
3668 }
3669 nla_nest_end(msg, params);
3670
3671 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
3672 if (ret) {
3673 sigma_dut_print(dut, DUT_MSG_ERROR,
3674 "%s: err in send_and_recv_msgs, ret=%d",
3675 __func__, ret);
3676 }
3677 return ret;
3678}
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08003679
3680
Subhani Shaik8e7a3052018-04-24 14:03:00 -07003681static int sta_set_he_ltf(struct sigma_dut *dut, const char *intf,
3682 enum qca_wlan_he_ltf_cfg ltf)
3683{
3684 struct nl_msg *msg;
3685 int ret = 0;
3686 struct nlattr *params;
3687 int ifindex;
3688
3689 ifindex = if_nametoindex(intf);
3690 if (ifindex == 0) {
3691 sigma_dut_print(dut, DUT_MSG_ERROR,
3692 "%s: Index for interface %s failed",
3693 __func__, intf);
3694 return -1;
3695 }
3696
3697 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
3698 NL80211_CMD_VENDOR)) ||
3699 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
3700 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
3701 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
3702 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
3703 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
3704 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_LTF,
3705 ltf)) {
3706 sigma_dut_print(dut, DUT_MSG_ERROR,
3707 "%s: err in adding vendor_cmd and vendor_data",
3708 __func__);
3709 nlmsg_free(msg);
3710 return -1;
3711 }
3712 nla_nest_end(msg, params);
3713
3714 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
3715 if (ret) {
3716 sigma_dut_print(dut, DUT_MSG_ERROR,
3717 "%s: err in send_and_recv_msgs, ret=%d",
3718 __func__, ret);
3719 }
3720 return ret;
3721}
3722
3723
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08003724static int nlvendor_sta_set_noack(struct sigma_dut *dut, const char *intf,
3725 int noack, enum qca_wlan_ac_type ac)
3726{
3727 struct nl_msg *msg;
3728 int ret = 0;
3729 struct nlattr *params;
3730 int ifindex;
3731
3732 ifindex = if_nametoindex(intf);
3733 if (ifindex == 0) {
3734 sigma_dut_print(dut, DUT_MSG_ERROR,
3735 "%s: Index for interface %s failed",
3736 __func__, intf);
3737 return -1;
3738 }
3739
3740 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
3741 NL80211_CMD_VENDOR)) ||
3742 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
3743 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
3744 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
3745 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
3746 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
3747 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_NO_ACK,
3748 noack) ||
3749 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_NO_ACK_AC,
3750 ac)) {
3751 sigma_dut_print(dut, DUT_MSG_ERROR,
3752 "%s: err in adding vendor_cmd and vendor_data",
3753 __func__);
3754 nlmsg_free(msg);
3755 return -1;
3756 }
3757 nla_nest_end(msg, params);
3758
3759 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
3760 if (ret) {
3761 sigma_dut_print(dut, DUT_MSG_ERROR,
3762 "%s: err in send_and_recv_msgs, ret=%d",
3763 __func__, ret);
3764 }
3765 return ret;
3766}
3767
3768
3769static void wcn_sta_set_noack(struct sigma_dut *dut, const char *intf,
3770 const char *val)
3771{
3772 int noack, ret;
3773 char token[100];
3774 char *result;
3775 char *saveptr;
3776 enum qca_wlan_ac_type ac = QCA_WLAN_AC_BE;
3777
3778 strlcpy(token, val, sizeof(token));
3779 token[sizeof(token) - 1] = '\0';
3780 result = strtok_r(token, ":", &saveptr);
3781 while (result) {
3782 noack = strcasecmp(result, "Disable") != 0;
3783 ret = nlvendor_sta_set_noack(dut, intf, noack, ac);
3784 if (ret) {
3785 sigma_dut_print(dut, DUT_MSG_ERROR,
3786 "nlvendor_sta_set_noack failed for ac:%d, ret:%d",
3787 ac, ret);
3788 }
3789 result = strtok_r(NULL, ":", &saveptr);
3790 ac++;
3791 }
3792}
3793
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08003794#endif /* NL80211_SUPPORT */
3795
3796
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003797static int cmd_sta_preset_testparameters(struct sigma_dut *dut,
3798 struct sigma_conn *conn,
3799 struct sigma_cmd *cmd)
3800{
3801 const char *intf = get_param(cmd, "Interface");
3802 const char *val;
3803
3804 val = get_param(cmd, "Program");
Peng Xue9fa7952017-05-09 15:59:49 -07003805 if (val && strcasecmp(val, "HS2-R2") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003806 return cmd_sta_preset_testparameters_hs2_r2(dut, conn, intf,
3807 cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003808
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07003809 if (val && strcasecmp(val, "LOC") == 0)
3810 return loc_cmd_sta_preset_testparameters(dut, conn, cmd);
3811
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003812#ifdef ANDROID_NAN
3813 if (val && strcasecmp(val, "NAN") == 0)
3814 return nan_cmd_sta_preset_testparameters(dut, conn, cmd);
3815#endif /* ANDROID_NAN */
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07003816#ifdef MIRACAST
3817 if (val && (strcasecmp(val, "WFD") == 0 ||
3818 strcasecmp(val, "DisplayR2") == 0))
3819 return miracast_preset_testparameters(dut, conn, cmd);
3820#endif /* MIRACAST */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003821
Ashwini Patil68d02cd2017-01-10 15:39:16 +05303822 if (val && strcasecmp(val, "MBO") == 0) {
3823 val = get_param(cmd, "Cellular_Data_Cap");
3824 if (val &&
3825 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
3826 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +05303827
3828 val = get_param(cmd, "Ch_Pref");
3829 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
3830 return 0;
3831
Ashwini Patilc63161e2017-04-13 16:30:23 +05303832 val = get_param(cmd, "BSS_Transition");
3833 if (val && mbo_set_bss_trans_req(dut, conn, intf, val) == 0)
3834 return 0;
3835
Ashwini Patila75de5a2017-04-13 16:35:05 +05303836 val = get_param(cmd, "Assoc_Disallow");
3837 if (val && mbo_set_assoc_disallow(dut, conn, intf, val) == 0)
3838 return 0;
3839
Ashwini Patil9183fdb2017-04-13 16:58:25 +05303840 val = get_param(cmd, "Roaming");
3841 if (val && mbo_set_roaming(dut, conn, intf, val) == 0)
3842 return 0;
3843
Ashwini Patil68d02cd2017-01-10 15:39:16 +05303844 return 1;
3845 }
3846
Ankita Bajaja2cb5672017-10-25 16:08:28 +05303847 if (val && strcasecmp(val, "OCE") == 0)
3848 return cmd_sta_preset_testparameters_oce(dut, conn, intf, cmd);
3849
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003850#if 0
3851 val = get_param(cmd, "Supplicant");
3852 if (val && strcasecmp(val, "Default") != 0) {
3853 send_resp(dut, conn, SIGMA_ERROR,
3854 "ErrorCode,Only default(Vendor) supplicant "
3855 "supported");
3856 return 0;
3857 }
3858#endif
3859
3860 val = get_param(cmd, "RTS");
3861 if (val) {
3862 switch (get_driver_type()) {
3863 case DRIVER_ATHEROS:
3864 ath_sta_set_rts(dut, intf, val);
3865 break;
3866 default:
3867#if 0
3868 send_resp(dut, conn, SIGMA_ERROR,
3869 "ErrorCode,Setting RTS not supported");
3870 return 0;
3871#else
3872 sigma_dut_print(dut, DUT_MSG_DEBUG,
3873 "Setting RTS not supported");
3874 break;
3875#endif
3876 }
3877 }
3878
3879#if 0
3880 val = get_param(cmd, "FRGMNT");
3881 if (val) {
3882 /* TODO */
3883 send_resp(dut, conn, SIGMA_ERROR,
3884 "ErrorCode,Setting FRGMNT not supported");
3885 return 0;
3886 }
3887#endif
3888
3889#if 0
3890 val = get_param(cmd, "Preamble");
3891 if (val) {
3892 /* TODO: Long/Short */
3893 send_resp(dut, conn, SIGMA_ERROR,
3894 "ErrorCode,Setting Preamble not supported");
3895 return 0;
3896 }
3897#endif
3898
3899 val = get_param(cmd, "Mode");
3900 if (val) {
3901 if (strcmp(val, "11b") == 0 ||
3902 strcmp(val, "11g") == 0 ||
3903 strcmp(val, "11a") == 0 ||
3904 strcmp(val, "11n") == 0 ||
3905 strcmp(val, "11ng") == 0 ||
3906 strcmp(val, "11nl") == 0 ||
3907 strcmp(val, "11nl(nabg)") == 0 ||
3908 strcmp(val, "AC") == 0 ||
3909 strcmp(val, "11AC") == 0 ||
3910 strcmp(val, "11ac") == 0 ||
3911 strcmp(val, "11na") == 0 ||
Amarnath Hullur Subramanyamb0db2712018-01-30 19:40:35 -08003912 strcmp(val, "11an") == 0 ||
3913 strcmp(val, "11ax") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003914 /* STA supports all modes by default */
3915 } else {
3916 send_resp(dut, conn, SIGMA_ERROR,
3917 "ErrorCode,Setting Mode not supported");
3918 return 0;
3919 }
Amarnath Hullur Subramanyam97d0e532018-01-31 02:53:02 -08003920
3921 /* Change the mode only in case of testbed for HE program
3922 * and for 11a and 11g modes only. */
3923 if (dut->program == PROGRAM_HE &&
3924 dut->device_type == STA_testbed) {
3925 int phymode;
3926 char buf[60];
3927
3928 if (strcmp(val, "11a") == 0) {
Amarnath Hullur Subramanyam94dfaf02018-03-02 19:26:57 -08003929 phymode = 1; /* IEEE80211_MODE_11A */
3930 } else if (strcmp(val, "11g") == 0) {
3931 phymode = 3; /* IEEE80211_MODE_11G */
3932 } else if (strcmp(val, "11b") == 0) {
3933 phymode = 2; /* IEEE80211_MODE_11B */
3934 } else if (strcmp(val, "11n") == 0 ||
3935 strcmp(val, "11nl") == 0 ||
3936 strcmp(val, "11nl(nabg)") == 0) {
3937 phymode = 22; /* IEEE80211_MODE_11AGN */
3938 } else if (strcmp(val, "11ng") == 0) {
3939 phymode = 13; /* IEEE80211_MODE_11NG_HT40 */
3940 } else if (strcmp(val, "AC") == 0 ||
3941 strcasecmp(val, "11AC") == 0) {
3942 phymode = 19; /* IEEE80211_MODE_11AC_VHT80 */
3943 } else if (strcmp(val, "11na") == 0 ||
3944 strcasecmp(val, "11an") == 0) {
3945 phymode = 14; /* IEEE80211_MODE_11NA_HT40 */
3946 } else if (strcmp(val, "11ax") == 0) {
3947 phymode = 0; /* IEEE80211_MODE_AUTO */
Amarnath Hullur Subramanyam97d0e532018-01-31 02:53:02 -08003948 } else {
3949 sigma_dut_print(dut, DUT_MSG_DEBUG,
3950 "Ignoring mode change for mode: %s",
3951 val);
3952 phymode = -1;
3953 }
3954 if (phymode != -1) {
3955 snprintf(buf, sizeof(buf),
3956 "iwpriv %s setphymode %d",
3957 intf, phymode);
3958 if (system(buf) != 0) {
3959 sigma_dut_print(dut, DUT_MSG_ERROR,
3960 "iwpriv setting of phymode failed");
3961 }
3962 }
3963 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003964 }
3965
3966 val = get_param(cmd, "wmm");
3967 if (val) {
3968 switch (get_driver_type()) {
3969 case DRIVER_ATHEROS:
3970 ath_sta_set_wmm(dut, intf, val);
3971 break;
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08003972 case DRIVER_WCN:
3973 wcn_sta_set_wmm(dut, intf, val);
3974 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003975 default:
3976 sigma_dut_print(dut, DUT_MSG_DEBUG,
3977 "Setting wmm not supported");
3978 break;
3979 }
3980 }
3981
3982 val = get_param(cmd, "Powersave");
3983 if (val) {
3984 if (strcmp(val, "0") == 0 || strcasecmp(val, "off") == 0) {
3985 if (wpa_command(get_station_ifname(),
3986 "P2P_SET ps 0") < 0)
3987 return -2;
3988 /* Make sure test modes are disabled */
3989 wpa_command(get_station_ifname(), "P2P_SET ps 98");
3990 wpa_command(get_station_ifname(), "P2P_SET ps 96");
3991 } else if (strcmp(val, "1") == 0 ||
3992 strcasecmp(val, "PSPoll") == 0 ||
3993 strcasecmp(val, "on") == 0) {
3994 /* Disable default power save mode */
3995 wpa_command(get_station_ifname(), "P2P_SET ps 0");
3996 /* Enable PS-Poll test mode */
3997 if (wpa_command(get_station_ifname(),
3998 "P2P_SET ps 97") < 0 ||
3999 wpa_command(get_station_ifname(),
4000 "P2P_SET ps 99") < 0)
4001 return -2;
4002 } else if (strcmp(val, "2") == 0 ||
4003 strcasecmp(val, "Fast") == 0) {
4004 /* TODO */
4005 send_resp(dut, conn, SIGMA_ERROR,
4006 "ErrorCode,Powersave=Fast not supported");
4007 return 0;
4008 } else if (strcmp(val, "3") == 0 ||
4009 strcasecmp(val, "PSNonPoll") == 0) {
4010 /* Make sure test modes are disabled */
4011 wpa_command(get_station_ifname(), "P2P_SET ps 98");
4012 wpa_command(get_station_ifname(), "P2P_SET ps 96");
4013
4014 /* Enable default power save mode */
4015 if (wpa_command(get_station_ifname(),
4016 "P2P_SET ps 1") < 0)
4017 return -2;
4018 } else
4019 return -1;
4020 }
4021
4022 val = get_param(cmd, "NoAck");
4023 if (val) {
4024 switch (get_driver_type()) {
4025 case DRIVER_ATHEROS:
4026 ath_sta_set_noack(dut, intf, val);
4027 break;
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08004028#ifdef NL80211_SUPPORT
4029 case DRIVER_WCN:
4030 wcn_sta_set_noack(dut, intf, val);
4031 break;
4032#endif /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004033 default:
4034 send_resp(dut, conn, SIGMA_ERROR,
4035 "ErrorCode,Setting NoAck not supported");
4036 return 0;
4037 }
4038 }
4039
4040 val = get_param(cmd, "IgnoreChswitchProhibit");
4041 if (val) {
4042 /* TODO: Enabled/disabled */
4043 if (strcasecmp(val, "Enabled") == 0) {
4044 send_resp(dut, conn, SIGMA_ERROR,
4045 "ErrorCode,Enabling IgnoreChswitchProhibit "
4046 "not supported");
4047 return 0;
4048 }
4049 }
4050
4051 val = get_param(cmd, "TDLS");
4052 if (val) {
4053 if (strcasecmp(val, "Disabled") == 0) {
4054 if (wpa_command(intf, "SET tdls_disabled 1")) {
4055 send_resp(dut, conn, SIGMA_ERROR,
4056 "ErrorCode,Failed to disable TDLS");
4057 return 0;
4058 }
4059 } else if (strcasecmp(val, "Enabled") == 0) {
4060 if (wpa_command(intf, "SET tdls_disabled 0")) {
4061 send_resp(dut, conn, SIGMA_ERROR,
4062 "ErrorCode,Failed to enable TDLS");
4063 return 0;
4064 }
4065 } else {
4066 send_resp(dut, conn, SIGMA_ERROR,
4067 "ErrorCode,Unsupported TDLS value");
4068 return 0;
4069 }
4070 }
4071
4072 val = get_param(cmd, "TDLSmode");
4073 if (val) {
4074 if (strcasecmp(val, "Default") == 0) {
4075 wpa_command(intf, "SET tdls_testing 0");
4076 } else if (strcasecmp(val, "APProhibit") == 0) {
4077 if (wpa_command(intf, "SET tdls_testing 0x400")) {
4078 send_resp(dut, conn, SIGMA_ERROR,
4079 "ErrorCode,Failed to enable ignore "
4080 "APProhibit TDLS mode");
4081 return 0;
4082 }
4083 } else if (strcasecmp(val, "HiLoMac") == 0) {
4084 /* STA should respond with TDLS setup req for a TDLS
4085 * setup req */
4086 if (wpa_command(intf, "SET tdls_testing 0x80")) {
4087 send_resp(dut, conn, SIGMA_ERROR,
4088 "ErrorCode,Failed to enable HiLoMac "
4089 "TDLS mode");
4090 return 0;
4091 }
4092 } else if (strcasecmp(val, "WeakSecurity") == 0) {
4093 /*
4094 * Since all security modes are enabled by default when
4095 * Sigma control is used, there is no need to do
4096 * anything here.
4097 */
4098 } else if (strcasecmp(val, "ExistLink") == 0) {
4099 /*
4100 * Since we allow new TDLS Setup Request even if there
4101 * is an existing link, nothing needs to be done for
4102 * this.
4103 */
4104 } else {
4105 /* TODO:
4106 * ExistLink: STA should send TDLS setup req even if
4107 * direct link already exists
4108 */
4109 send_resp(dut, conn, SIGMA_ERROR,
4110 "ErrorCode,Unsupported TDLSmode value");
4111 return 0;
4112 }
4113 }
4114
4115 val = get_param(cmd, "FakePubKey");
4116 if (val && atoi(val) && wpa_command(intf, "SET wps_corrupt_pkhash 1")) {
4117 send_resp(dut, conn, SIGMA_ERROR,
4118 "ErrorCode,Failed to enable FakePubKey");
4119 return 0;
4120 }
4121
Amarnath Hullur Subramanyamae1042b2018-02-22 21:52:52 -08004122#ifdef NL80211_SUPPORT
4123 val = get_param(cmd, "FrgmntSupport");
4124 if (val) {
4125 if (strcasecmp(val, "Enable") == 0) {
4126 if (sta_set_he_fragmentation(dut, intf,
4127 HE_FRAG_LEVEL1)) {
4128 send_resp(dut, conn, SIGMA_ERROR,
4129 "ErrorCode,Failed to enable HE Fragmentation");
4130 return 0;
4131 }
4132 } else if (strcasecmp(val, "Disable") == 0) {
4133 if (sta_set_he_fragmentation(dut, intf,
4134 HE_FRAG_DISABLE)) {
4135 send_resp(dut, conn, SIGMA_ERROR,
4136 "ErrorCode,Failed to disable HE Fragmentation");
4137 return 0;
4138 }
4139 }
4140 }
4141#endif /* NL80211_SUPPORT */
4142
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004143 return 1;
4144}
4145
4146
4147static const char * ath_get_radio_name(const char *radio_name)
4148{
4149 if (radio_name == NULL)
4150 return "wifi0";
4151 if (strcmp(radio_name, "wifi1") == 0)
4152 return "wifi1";
4153 if (strcmp(radio_name, "wifi2") == 0)
4154 return "wifi2";
4155 return "wifi0";
4156}
4157
4158
4159static void ath_sta_set_txsp_stream(struct sigma_dut *dut, const char *intf,
4160 const char *val)
4161{
4162 char buf[60];
4163 unsigned int vht_mcsmap = 0;
4164 int txchainmask = 0;
4165 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
4166
4167 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
4168 if (dut->testbed_flag_txsp == 1) {
4169 vht_mcsmap = 0xfffc;
4170 dut->testbed_flag_txsp = 0;
4171 } else {
4172 vht_mcsmap = 0xfffe;
4173 }
4174 txchainmask = 1;
4175 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
4176 if (dut->testbed_flag_txsp == 1) {
4177 vht_mcsmap = 0xfff0;
4178 dut->testbed_flag_txsp = 0;
4179 } else {
4180 vht_mcsmap = 0xfffa;
4181 }
4182 txchainmask = 3;
4183 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
4184 if (dut->testbed_flag_txsp == 1) {
4185 vht_mcsmap = 0xffc0;
4186 dut->testbed_flag_txsp = 0;
4187 } else {
4188 vht_mcsmap = 0xffea;
4189 }
4190 txchainmask = 7;
4191 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
4192 if (dut->testbed_flag_txsp == 1) {
4193 vht_mcsmap = 0xff00;
4194 dut->testbed_flag_txsp = 0;
4195 } else {
4196 vht_mcsmap = 0xffaa;
4197 }
4198 txchainmask = 15;
4199 } else {
4200 if (dut->testbed_flag_txsp == 1) {
4201 vht_mcsmap = 0xffc0;
4202 dut->testbed_flag_txsp = 0;
4203 } else {
4204 vht_mcsmap = 0xffea;
4205 }
4206 }
4207
4208 if (txchainmask) {
4209 snprintf(buf, sizeof(buf), "iwpriv %s txchainmask %d",
4210 basedev, txchainmask);
4211 if (system(buf) != 0) {
4212 sigma_dut_print(dut, DUT_MSG_ERROR,
4213 "iwpriv txchainmask failed");
4214 }
4215 }
4216
4217 snprintf(buf, sizeof(buf), "iwpriv %s vht_mcsmap 0x%04x",
4218 intf, vht_mcsmap);
4219 if (system(buf) != 0) {
4220 sigma_dut_print(dut, DUT_MSG_ERROR,
4221 "iwpriv %s vht_mcsmap 0x%04x failed",
4222 intf, vht_mcsmap);
4223 }
4224}
4225
4226
4227static void ath_sta_set_rxsp_stream(struct sigma_dut *dut, const char *intf,
4228 const char *val)
4229{
4230 char buf[60];
4231 unsigned int vht_mcsmap = 0;
4232 int rxchainmask = 0;
4233 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
4234
4235 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
4236 if (dut->testbed_flag_rxsp == 1) {
4237 vht_mcsmap = 0xfffc;
4238 dut->testbed_flag_rxsp = 0;
4239 } else {
4240 vht_mcsmap = 0xfffe;
4241 }
4242 rxchainmask = 1;
4243 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
4244 if (dut->testbed_flag_rxsp == 1) {
4245 vht_mcsmap = 0xfff0;
4246 dut->testbed_flag_rxsp = 0;
4247 } else {
4248 vht_mcsmap = 0xfffa;
4249 }
4250 rxchainmask = 3;
4251 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
4252 if (dut->testbed_flag_rxsp == 1) {
4253 vht_mcsmap = 0xffc0;
4254 dut->testbed_flag_rxsp = 0;
4255 } else {
4256 vht_mcsmap = 0xffea;
4257 }
4258 rxchainmask = 7;
4259 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
4260 if (dut->testbed_flag_rxsp == 1) {
4261 vht_mcsmap = 0xff00;
4262 dut->testbed_flag_rxsp = 0;
4263 } else {
4264 vht_mcsmap = 0xffaa;
4265 }
4266 rxchainmask = 15;
4267 } else {
4268 if (dut->testbed_flag_rxsp == 1) {
4269 vht_mcsmap = 0xffc0;
4270 dut->testbed_flag_rxsp = 0;
4271 } else {
4272 vht_mcsmap = 0xffea;
4273 }
4274 }
4275
4276 if (rxchainmask) {
4277 snprintf(buf, sizeof(buf), "iwpriv %s rxchainmask %d",
4278 basedev, rxchainmask);
4279 if (system(buf) != 0) {
4280 sigma_dut_print(dut, DUT_MSG_ERROR,
4281 "iwpriv rxchainmask failed");
4282 }
4283 }
4284
4285 snprintf(buf, sizeof(buf), "iwpriv %s vht_mcsmap 0x%04x",
4286 intf, vht_mcsmap);
4287 if (system(buf) != 0) {
4288 sigma_dut_print(dut, DUT_MSG_ERROR,
4289 "iwpriv %s vht_mcsmap 0x%04x",
4290 intf, vht_mcsmap);
4291 }
4292}
4293
4294
4295void ath_set_zero_crc(struct sigma_dut *dut, const char *val)
4296{
4297 if (strcasecmp(val, "enable") == 0) {
4298 if (system("athdiag --set --address=0x2a204 --and=0xbfffffff")
4299 != 0) {
4300 sigma_dut_print(dut, DUT_MSG_ERROR,
4301 "Disable BB_VHTSIGB_CRC_CALC failed");
4302 }
4303
4304 if (system("athdiag --set --address=0x2a204 --or=0x80000000")
4305 != 0) {
4306 sigma_dut_print(dut, DUT_MSG_ERROR,
4307 "Enable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
4308 }
4309 } else {
4310 if (system("athdiag --set --address=0x2a204 --and=0x7fffffff")
4311 != 0) {
4312 sigma_dut_print(dut, DUT_MSG_ERROR,
4313 "Disable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
4314 }
4315
4316 if (system("athdiag --set --address=0x2a204 --or=0x40000000")
4317 != 0) {
4318 sigma_dut_print(dut, DUT_MSG_ERROR,
4319 "Enable BB_VHTSIGB_CRC_CALC failed");
4320 }
4321 }
4322}
4323
4324
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08004325static int wcn_sta_set_width(struct sigma_dut *dut, const char *intf,
4326 const char *val)
4327{
4328 char buf[60];
4329
4330 if (strcmp(val, "20") == 0) {
4331 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 0", intf);
4332 dut->chwidth = 0;
4333 } else if (strcmp(val, "40") == 0) {
4334 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 1", intf);
4335 dut->chwidth = 1;
4336 } else if (strcmp(val, "80") == 0) {
4337 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 2", intf);
4338 dut->chwidth = 2;
Sunil Duttb1cccac2018-05-22 21:03:12 +05304339 } else if (strcasecmp(val, "Auto") == 0) {
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08004340 buf[0] = '\0';
4341 } else {
4342 sigma_dut_print(dut, DUT_MSG_ERROR, "WIDTH %s not supported",
4343 val);
4344 return -1;
4345 }
4346
4347 if (buf[0] != '\0' && system(buf) != 0) {
4348 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv chwidth failed");
4349 return -1;
4350 }
4351
4352 return 0;
4353}
4354
4355
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08004356static int nlvendor_sta_set_addba_reject(struct sigma_dut *dut,
4357 const char *intf, int addbareject)
4358{
4359#ifdef NL80211_SUPPORT
4360 struct nl_msg *msg;
4361 int ret = 0;
4362 struct nlattr *params;
4363 int ifindex;
4364
4365 ifindex = if_nametoindex(intf);
4366 if (ifindex == 0) {
4367 sigma_dut_print(dut, DUT_MSG_ERROR,
4368 "%s: Index for interface %s failed",
4369 __func__, intf);
4370 return -1;
4371 }
4372
4373 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4374 NL80211_CMD_VENDOR)) ||
4375 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4376 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4377 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4378 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4379 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4380 nla_put_u8(msg,
4381 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ACCEPT_ADDBA_REQ,
4382 !addbareject)) {
4383 sigma_dut_print(dut, DUT_MSG_ERROR,
4384 "%s: err in adding vendor_cmd and vendor_data",
4385 __func__);
4386 nlmsg_free(msg);
4387 return -1;
4388 }
4389 nla_nest_end(msg, params);
4390
4391 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4392 if (ret) {
4393 sigma_dut_print(dut, DUT_MSG_ERROR,
4394 "%s: err in send_and_recv_msgs, ret=%d",
4395 __func__, ret);
4396 }
4397 return ret;
4398#else /* NL80211_SUPPORT */
4399 sigma_dut_print(dut, DUT_MSG_ERROR,
4400 "ADDBA_REJECT cannot be set without NL80211_SUPPORT defined");
4401 return -1;
4402#endif /* NL80211_SUPPORT */
4403}
4404
4405
4406static int sta_set_addba_reject(struct sigma_dut *dut, const char *intf,
4407 int addbareject)
4408{
4409 int ret;
4410
4411 switch (get_driver_type()) {
4412 case DRIVER_WCN:
4413 ret = nlvendor_sta_set_addba_reject(dut, intf, addbareject);
4414 if (ret) {
4415 sigma_dut_print(dut, DUT_MSG_ERROR,
4416 "nlvendor_sta_set_addba_reject failed, ret:%d",
4417 ret);
4418 return ret;
4419 }
4420 break;
4421 default:
4422 sigma_dut_print(dut, DUT_MSG_ERROR,
4423 "errorCode,Unsupported ADDBA_REJECT with the current driver");
4424 ret = -1;
4425 break;
4426 }
4427
4428 return ret;
4429}
4430
4431
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08004432static int nlvendor_config_send_addba(struct sigma_dut *dut, const char *intf,
4433 int enable)
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08004434{
4435#ifdef NL80211_SUPPORT
4436 struct nl_msg *msg;
4437 int ret = 0;
4438 struct nlattr *params;
4439 int ifindex;
4440
4441 ifindex = if_nametoindex(intf);
4442 if (ifindex == 0) {
4443 sigma_dut_print(dut, DUT_MSG_ERROR,
4444 "%s: Index for interface %s failed",
4445 __func__, intf);
4446 return -1;
4447 }
4448
4449 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4450 NL80211_CMD_VENDOR)) ||
4451 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4452 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4453 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4454 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4455 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4456 nla_put_u8(msg,
4457 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_SEND_ADDBA_REQ,
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08004458 enable)) {
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08004459 sigma_dut_print(dut, DUT_MSG_ERROR,
4460 "%s: err in adding vendor_cmd and vendor_data",
4461 __func__);
4462 nlmsg_free(msg);
4463 return -1;
4464 }
4465 nla_nest_end(msg, params);
4466
4467 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4468 if (ret) {
4469 sigma_dut_print(dut, DUT_MSG_ERROR,
4470 "%s: err in send_and_recv_msgs, ret=%d",
4471 __func__, ret);
4472 }
4473 return ret;
4474#else /* NL80211_SUPPORT */
4475 sigma_dut_print(dut, DUT_MSG_ERROR,
4476 "Disable addba not possible without NL80211_SUPPORT defined");
4477 return -1;
4478#endif /* NL80211_SUPPORT */
4479}
4480
4481
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004482static int cmd_sta_set_wireless_common(const char *intf, struct sigma_dut *dut,
4483 struct sigma_conn *conn,
4484 struct sigma_cmd *cmd)
4485{
4486 const char *val;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08004487 int ampdu = -1, addbareject = -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004488 char buf[30];
4489
4490 val = get_param(cmd, "40_INTOLERANT");
4491 if (val) {
4492 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
4493 /* TODO: iwpriv ht40intol through wpa_supplicant */
4494 send_resp(dut, conn, SIGMA_ERROR,
4495 "ErrorCode,40_INTOLERANT not supported");
4496 return 0;
4497 }
4498 }
4499
4500 val = get_param(cmd, "ADDBA_REJECT");
4501 if (val) {
4502 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
4503 /* reject any ADDBA with status "decline" */
4504 ampdu = 0;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08004505 addbareject = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004506 } else {
4507 /* accept ADDBA */
4508 ampdu = 1;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08004509 addbareject = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004510 }
4511 }
4512
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08004513 if (addbareject >= 0 &&
4514 sta_set_addba_reject(dut, intf, addbareject) < 0) {
4515 send_resp(dut, conn, SIGMA_ERROR,
4516 "ErrorCode,set addba_reject failed");
4517 return 0;
4518 }
4519
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004520 val = get_param(cmd, "AMPDU");
4521 if (val) {
4522 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
4523 /* enable AMPDU Aggregation */
4524 if (ampdu == 0) {
4525 send_resp(dut, conn, SIGMA_ERROR,
4526 "ErrorCode,Mismatch in "
4527 "addba_reject/ampdu - "
4528 "not supported");
4529 return 0;
4530 }
4531 ampdu = 1;
4532 } else {
4533 /* disable AMPDU Aggregation */
4534 if (ampdu == 1) {
4535 send_resp(dut, conn, SIGMA_ERROR,
4536 "ErrorCode,Mismatch in "
4537 "addba_reject/ampdu - "
4538 "not supported");
4539 return 0;
4540 }
4541 ampdu = 0;
4542 }
4543 }
4544
4545 if (ampdu >= 0) {
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08004546 int ret;
4547
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004548 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s A-MPDU aggregation",
4549 ampdu ? "Enabling" : "Disabling");
4550 snprintf(buf, sizeof(buf), "SET ampdu %d", ampdu);
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07004551 if (wpa_command(intf, buf) < 0 &&
4552 iwpriv_sta_set_ampdu(dut, intf, ampdu) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004553 send_resp(dut, conn, SIGMA_ERROR,
4554 "ErrorCode,set aggr failed");
4555 return 0;
4556 }
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08004557
4558 if (ampdu == 0) {
4559 /* Disable sending of addba using nl vendor command */
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08004560 ret = nlvendor_config_send_addba(dut, intf, 0);
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08004561 if (ret) {
4562 sigma_dut_print(dut, DUT_MSG_ERROR,
4563 "Failed to disable addba, ret:%d",
4564 ret);
4565 }
4566 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004567 }
4568
4569 val = get_param(cmd, "AMSDU");
4570 if (val) {
4571 switch (get_driver_type()) {
4572 case DRIVER_ATHEROS:
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08004573 case DRIVER_WCN:
4574 iwpriv_sta_set_amsdu(dut, intf, val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004575 break;
4576 default:
4577 if (strcmp(val, "1") == 0 ||
4578 strcasecmp(val, "Enable") == 0) {
4579 /* Enable AMSDU Aggregation */
4580 send_resp(dut, conn, SIGMA_ERROR,
4581 "ErrorCode,AMSDU aggregation not supported");
4582 return 0;
4583 }
4584 break;
4585 }
4586 }
4587
4588 val = get_param(cmd, "STBC_RX");
4589 if (val) {
4590 switch (get_driver_type()) {
4591 case DRIVER_ATHEROS:
4592 ath_sta_set_stbc(dut, intf, val);
4593 break;
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05304594 case DRIVER_WCN:
4595 wcn_sta_set_stbc(dut, intf, val);
4596 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004597 default:
4598 send_resp(dut, conn, SIGMA_ERROR,
4599 "ErrorCode,STBC_RX not supported");
4600 return 0;
4601 }
4602 }
4603
4604 val = get_param(cmd, "WIDTH");
4605 if (val) {
4606 switch (get_driver_type()) {
4607 case DRIVER_WCN:
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08004608 if (wcn_sta_set_width(dut, intf, val) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004609 send_resp(dut, conn, SIGMA_ERROR,
4610 "ErrorCode,Failed to set WIDTH");
4611 return 0;
4612 }
4613 break;
4614 case DRIVER_ATHEROS:
4615 if (ath_set_width(dut, conn, intf, val) < 0)
4616 return 0;
4617 break;
4618 default:
4619 sigma_dut_print(dut, DUT_MSG_ERROR,
4620 "Setting WIDTH not supported");
4621 break;
4622 }
4623 }
4624
4625 val = get_param(cmd, "SMPS");
4626 if (val) {
4627 /* TODO: Dynamic/0, Static/1, No Limit/2 */
4628 send_resp(dut, conn, SIGMA_ERROR,
4629 "ErrorCode,SMPS not supported");
4630 return 0;
4631 }
4632
4633 val = get_param(cmd, "TXSP_STREAM");
4634 if (val) {
4635 switch (get_driver_type()) {
4636 case DRIVER_WCN:
4637 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
4638 send_resp(dut, conn, SIGMA_ERROR,
4639 "ErrorCode,Failed to set TXSP_STREAM");
4640 return 0;
4641 }
4642 break;
4643 case DRIVER_ATHEROS:
4644 ath_sta_set_txsp_stream(dut, intf, val);
4645 break;
4646 default:
4647 sigma_dut_print(dut, DUT_MSG_ERROR,
4648 "Setting TXSP_STREAM not supported");
4649 break;
4650 }
4651 }
4652
4653 val = get_param(cmd, "RXSP_STREAM");
4654 if (val) {
4655 switch (get_driver_type()) {
4656 case DRIVER_WCN:
4657 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
4658 send_resp(dut, conn, SIGMA_ERROR,
4659 "ErrorCode,Failed to set RXSP_STREAM");
4660 return 0;
4661 }
4662 break;
4663 case DRIVER_ATHEROS:
4664 ath_sta_set_rxsp_stream(dut, intf, val);
4665 break;
4666 default:
4667 sigma_dut_print(dut, DUT_MSG_ERROR,
4668 "Setting RXSP_STREAM not supported");
4669 break;
4670 }
4671 }
4672
4673 val = get_param(cmd, "DYN_BW_SGNL");
4674 if (val) {
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08004675 switch (get_driver_type()) {
4676 case DRIVER_WCN:
Peng Xuc59afd32016-11-21 15:01:11 -08004677 if (strcasecmp(val, "enable") == 0) {
4678 snprintf(buf, sizeof(buf),
4679 "iwpriv %s cwmenable 1", intf);
4680 if (system(buf) != 0) {
4681 sigma_dut_print(dut, DUT_MSG_ERROR,
4682 "iwpriv cwmenable 1 failed");
4683 return 0;
4684 }
4685 } else if (strcasecmp(val, "disable") == 0) {
4686 snprintf(buf, sizeof(buf),
4687 "iwpriv %s cwmenable 0", intf);
4688 if (system(buf) != 0) {
4689 sigma_dut_print(dut, DUT_MSG_ERROR,
4690 "iwpriv cwmenable 0 failed");
4691 return 0;
4692 }
4693 } else {
4694 sigma_dut_print(dut, DUT_MSG_ERROR,
4695 "Unsupported DYN_BW_SGL");
4696 }
4697
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004698 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 3", intf);
4699 if (system(buf) != 0) {
4700 sigma_dut_print(dut, DUT_MSG_ERROR,
4701 "Failed to set cts_cbw in DYN_BW_SGNL");
4702 return 0;
4703 }
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08004704 break;
4705 case DRIVER_ATHEROS:
priyadharshini gowthamane5e25172015-12-08 14:53:48 -08004706 novap_reset(dut, intf);
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08004707 ath_config_dyn_bw_sig(dut, intf, val);
4708 break;
4709 default:
4710 sigma_dut_print(dut, DUT_MSG_ERROR,
4711 "Failed to set DYN_BW_SGNL");
4712 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004713 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004714 }
4715
4716 val = get_param(cmd, "RTS_FORCE");
4717 if (val) {
priyadharshini gowthamane5e25172015-12-08 14:53:48 -08004718 novap_reset(dut, intf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004719 if (strcasecmp(val, "Enable") == 0) {
4720 snprintf(buf, sizeof(buf), "iwconfig %s rts 64", intf);
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02004721 if (system(buf) != 0) {
4722 sigma_dut_print(dut, DUT_MSG_ERROR,
4723 "Failed to set RTS_FORCE 64");
4724 }
priyadharshini gowthaman270870e2015-12-09 10:10:23 -08004725 snprintf(buf, sizeof(buf),
4726 "wifitool %s beeliner_fw_test 100 1", intf);
4727 if (system(buf) != 0) {
4728 sigma_dut_print(dut, DUT_MSG_ERROR,
4729 "wifitool beeliner_fw_test 100 1 failed");
4730 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004731 } else if (strcasecmp(val, "Disable") == 0) {
4732 snprintf(buf, sizeof(buf), "iwconfig %s rts 2347",
4733 intf);
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02004734 if (system(buf) != 0) {
4735 sigma_dut_print(dut, DUT_MSG_ERROR,
4736 "Failed to set RTS_FORCE 2347");
4737 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004738 } else {
4739 send_resp(dut, conn, SIGMA_ERROR,
4740 "ErrorCode,RTS_FORCE value not supported");
4741 return 0;
4742 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004743 }
4744
4745 val = get_param(cmd, "CTS_WIDTH");
4746 if (val) {
4747 switch (get_driver_type()) {
4748 case DRIVER_WCN:
4749 if (wcn_sta_set_cts_width(dut, intf, val) < 0) {
4750 send_resp(dut, conn, SIGMA_ERROR,
4751 "ErrorCode,Failed to set CTS_WIDTH");
4752 return 0;
4753 }
4754 break;
4755 case DRIVER_ATHEROS:
4756 ath_set_cts_width(dut, intf, val);
4757 break;
4758 default:
4759 sigma_dut_print(dut, DUT_MSG_ERROR,
4760 "Setting CTS_WIDTH not supported");
4761 break;
4762 }
4763 }
4764
4765 val = get_param(cmd, "BW_SGNL");
4766 if (val) {
4767 if (strcasecmp(val, "Enable") == 0) {
4768 snprintf(buf, sizeof(buf), "iwpriv %s cwmenable 1",
4769 intf);
4770 } else if (strcasecmp(val, "Disable") == 0) {
4771 /* TODO: Disable */
4772 buf[0] = '\0';
4773 } else {
4774 send_resp(dut, conn, SIGMA_ERROR,
4775 "ErrorCode,BW_SGNL value not supported");
4776 return 0;
4777 }
4778
4779 if (buf[0] != '\0' && system(buf) != 0) {
4780 sigma_dut_print(dut, DUT_MSG_ERROR,
4781 "Failed to set BW_SGNL");
4782 }
4783 }
4784
4785 val = get_param(cmd, "Band");
4786 if (val) {
4787 if (strcmp(val, "2.4") == 0 || strcmp(val, "5") == 0) {
4788 /* STA supports all bands by default */
4789 } else {
4790 send_resp(dut, conn, SIGMA_ERROR,
4791 "ErrorCode,Unsupported Band");
4792 return 0;
4793 }
4794 }
4795
4796 val = get_param(cmd, "zero_crc");
4797 if (val) {
4798 switch (get_driver_type()) {
4799 case DRIVER_ATHEROS:
4800 ath_set_zero_crc(dut, val);
4801 break;
4802 default:
4803 break;
4804 }
4805 }
4806
4807 return 1;
4808}
4809
4810
4811static int sta_set_60g_common(struct sigma_dut *dut, struct sigma_conn *conn,
4812 struct sigma_cmd *cmd)
4813{
4814 const char *val;
4815 char buf[100];
4816
4817 val = get_param(cmd, "MSDUSize");
4818 if (val) {
4819 int mtu;
4820
4821 dut->amsdu_size = atoi(val);
4822 if (dut->amsdu_size > IEEE80211_MAX_DATA_LEN_DMG ||
4823 dut->amsdu_size < IEEE80211_SNAP_LEN_DMG) {
4824 sigma_dut_print(dut, DUT_MSG_ERROR,
4825 "MSDUSize %d is above max %d or below min %d",
4826 dut->amsdu_size,
4827 IEEE80211_MAX_DATA_LEN_DMG,
4828 IEEE80211_SNAP_LEN_DMG);
4829 dut->amsdu_size = 0;
4830 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4831 }
4832
4833 mtu = dut->amsdu_size - IEEE80211_SNAP_LEN_DMG;
4834 sigma_dut_print(dut, DUT_MSG_DEBUG,
4835 "Setting amsdu_size to %d", mtu);
4836 snprintf(buf, sizeof(buf), "ifconfig %s mtu %d",
4837 get_station_ifname(), mtu);
4838
4839 if (system(buf) != 0) {
4840 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
4841 buf);
4842 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4843 }
4844 }
4845
4846 val = get_param(cmd, "BAckRcvBuf");
4847 if (val) {
4848 dut->back_rcv_buf = atoi(val);
4849 if (dut->back_rcv_buf == 0) {
4850 sigma_dut_print(dut, DUT_MSG_ERROR,
4851 "Failed to convert %s or value is 0",
4852 val);
4853 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4854 }
4855
4856 sigma_dut_print(dut, DUT_MSG_DEBUG,
4857 "Setting BAckRcvBuf to %s", val);
4858 }
4859
4860 return SIGMA_DUT_SUCCESS_CALLER_SEND_STATUS;
4861}
4862
4863
4864static int sta_pcp_start(struct sigma_dut *dut, struct sigma_conn *conn,
4865 struct sigma_cmd *cmd)
4866{
4867 int net_id;
4868 char *ifname;
4869 const char *val;
4870 char buf[100];
4871
4872 dut->mode = SIGMA_MODE_STATION;
4873 ifname = get_main_ifname();
4874 if (wpa_command(ifname, "PING") != 0) {
4875 sigma_dut_print(dut, DUT_MSG_ERROR, "Supplicant not running");
4876 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4877 }
4878
4879 wpa_command(ifname, "FLUSH");
4880 net_id = add_network_common(dut, conn, ifname, cmd);
4881 if (net_id < 0) {
4882 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add network");
4883 return net_id;
4884 }
4885
4886 /* TODO: mode=2 for the AP; in the future, replace for mode PCP */
4887 if (set_network(ifname, net_id, "mode", "2") < 0) {
4888 sigma_dut_print(dut, DUT_MSG_ERROR,
4889 "Failed to set supplicant network mode");
4890 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4891 }
4892
4893 sigma_dut_print(dut, DUT_MSG_DEBUG,
4894 "Supplicant set network with mode 2");
4895
4896 val = get_param(cmd, "Security");
4897 if (val && strcasecmp(val, "OPEN") == 0) {
4898 dut->ap_key_mgmt = AP_OPEN;
4899 if (set_network(ifname, net_id, "key_mgmt", "NONE") < 0) {
4900 sigma_dut_print(dut, DUT_MSG_ERROR,
4901 "Failed to set supplicant to %s security",
4902 val);
4903 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4904 }
4905 } else if (val && strcasecmp(val, "WPA2-PSK") == 0) {
4906 dut->ap_key_mgmt = AP_WPA2_PSK;
4907 if (set_network(ifname, net_id, "key_mgmt", "WPA-PSK") < 0) {
4908 sigma_dut_print(dut, DUT_MSG_ERROR,
4909 "Failed to set supplicant to %s security",
4910 val);
4911 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4912 }
4913
4914 if (set_network(ifname, net_id, "proto", "RSN") < 0) {
4915 sigma_dut_print(dut, DUT_MSG_ERROR,
4916 "Failed to set supplicant to proto RSN");
4917 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4918 }
4919 } else if (val) {
4920 sigma_dut_print(dut, DUT_MSG_ERROR,
4921 "Requested Security %s is not supported on 60GHz",
4922 val);
4923 return SIGMA_DUT_INVALID_CALLER_SEND_STATUS;
4924 }
4925
4926 val = get_param(cmd, "Encrypt");
4927 if (val && strcasecmp(val, "AES-GCMP") == 0) {
4928 if (set_network(ifname, net_id, "pairwise", "GCMP") < 0) {
4929 sigma_dut_print(dut, DUT_MSG_ERROR,
4930 "Failed to set supplicant to pairwise GCMP");
4931 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4932 }
4933 if (set_network(ifname, net_id, "group", "GCMP") < 0) {
4934 sigma_dut_print(dut, DUT_MSG_ERROR,
4935 "Failed to set supplicant to group GCMP");
4936 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4937 }
4938 } else if (val) {
4939 sigma_dut_print(dut, DUT_MSG_ERROR,
4940 "Requested Encrypt %s is not supported on 60 GHz",
4941 val);
4942 return SIGMA_DUT_INVALID_CALLER_SEND_STATUS;
4943 }
4944
4945 val = get_param(cmd, "PSK");
4946 if (val && set_network_quoted(ifname, net_id, "psk", val) < 0) {
4947 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set psk %s",
4948 val);
4949 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4950 }
4951
4952 /* Convert 60G channel to freq */
4953 switch (dut->ap_channel) {
4954 case 1:
4955 val = "58320";
4956 break;
4957 case 2:
4958 val = "60480";
4959 break;
4960 case 3:
4961 val = "62640";
4962 break;
4963 default:
4964 sigma_dut_print(dut, DUT_MSG_ERROR,
4965 "Failed to configure channel %d. Not supported",
4966 dut->ap_channel);
4967 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4968 }
4969
4970 if (set_network(ifname, net_id, "frequency", val) < 0) {
4971 sigma_dut_print(dut, DUT_MSG_ERROR,
4972 "Failed to set supplicant network frequency");
4973 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4974 }
4975
4976 sigma_dut_print(dut, DUT_MSG_DEBUG,
4977 "Supplicant set network with frequency");
4978
4979 snprintf(buf, sizeof(buf), "SELECT_NETWORK %d", net_id);
4980 if (wpa_command(ifname, buf) < 0) {
4981 sigma_dut_print(dut, DUT_MSG_INFO,
4982 "Failed to select network id %d on %s",
4983 net_id, ifname);
4984 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4985 }
4986
4987 sigma_dut_print(dut, DUT_MSG_DEBUG, "Selected network");
4988
4989 return SIGMA_DUT_SUCCESS_CALLER_SEND_STATUS;
4990}
4991
4992
Lior David67543f52017-01-03 19:04:22 +02004993static int wil6210_set_abft_len(struct sigma_dut *dut, int abft_len)
4994{
4995 char buf[128], fname[128];
4996 FILE *f;
4997
4998 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
4999 sigma_dut_print(dut, DUT_MSG_ERROR,
5000 "failed to get wil6210 debugfs dir");
5001 return -1;
5002 }
5003
5004 snprintf(fname, sizeof(fname), "%s/abft_len", buf);
5005 f = fopen(fname, "w");
5006 if (!f) {
5007 sigma_dut_print(dut, DUT_MSG_ERROR,
5008 "failed to open: %s", fname);
5009 return -1;
5010 }
5011
5012 fprintf(f, "%d\n", abft_len);
5013 fclose(f);
5014
5015 return 0;
5016}
5017
5018
5019static int sta_set_60g_abft_len(struct sigma_dut *dut, struct sigma_conn *conn,
5020 int abft_len)
5021{
5022 switch (get_driver_type()) {
5023 case DRIVER_WIL6210:
5024 return wil6210_set_abft_len(dut, abft_len);
5025 default:
5026 sigma_dut_print(dut, DUT_MSG_ERROR,
5027 "set abft_len not supported");
5028 return -1;
5029 }
5030}
5031
5032
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005033static int sta_set_60g_pcp(struct sigma_dut *dut, struct sigma_conn *conn,
5034 struct sigma_cmd *cmd)
5035{
5036 const char *val;
Lior David67543f52017-01-03 19:04:22 +02005037 unsigned int abft_len = 1; /* default is one slot */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005038
5039 if (dut->dev_role != DEVROLE_PCP) {
5040 send_resp(dut, conn, SIGMA_INVALID,
5041 "ErrorCode,Invalid DevRole");
5042 return 0;
5043 }
5044
5045 val = get_param(cmd, "SSID");
5046 if (val) {
5047 if (strlen(val) > sizeof(dut->ap_ssid) - 1) {
5048 send_resp(dut, conn, SIGMA_INVALID,
5049 "ErrorCode,Invalid SSID");
5050 return -1;
5051 }
5052
Peng Xub8fc5cc2017-05-10 17:27:28 -07005053 strlcpy(dut->ap_ssid, val, sizeof(dut->ap_ssid));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005054 }
5055
5056 val = get_param(cmd, "CHANNEL");
5057 if (val) {
5058 const char *pos;
5059
5060 dut->ap_channel = atoi(val);
5061 pos = strchr(val, ';');
5062 if (pos) {
5063 pos++;
5064 dut->ap_channel_1 = atoi(pos);
5065 }
5066 }
5067
5068 switch (dut->ap_channel) {
5069 case 1:
5070 case 2:
5071 case 3:
5072 break;
5073 default:
5074 sigma_dut_print(dut, DUT_MSG_ERROR,
5075 "Channel %d is not supported", dut->ap_channel);
5076 send_resp(dut, conn, SIGMA_ERROR,
5077 "Requested channel is not supported");
5078 return -1;
5079 }
5080
5081 val = get_param(cmd, "BCNINT");
5082 if (val)
5083 dut->ap_bcnint = atoi(val);
5084
5085
5086 val = get_param(cmd, "ExtSchIE");
5087 if (val) {
5088 send_resp(dut, conn, SIGMA_ERROR,
5089 "ErrorCode,ExtSchIE is not supported yet");
5090 return -1;
5091 }
5092
5093 val = get_param(cmd, "AllocType");
5094 if (val) {
5095 send_resp(dut, conn, SIGMA_ERROR,
5096 "ErrorCode,AllocType is not supported yet");
5097 return -1;
5098 }
5099
5100 val = get_param(cmd, "PercentBI");
5101 if (val) {
5102 send_resp(dut, conn, SIGMA_ERROR,
5103 "ErrorCode,PercentBI is not supported yet");
5104 return -1;
5105 }
5106
5107 val = get_param(cmd, "CBAPOnly");
5108 if (val) {
5109 send_resp(dut, conn, SIGMA_ERROR,
5110 "ErrorCode,CBAPOnly is not supported yet");
5111 return -1;
5112 }
5113
5114 val = get_param(cmd, "AMPDU");
5115 if (val) {
5116 if (strcasecmp(val, "Enable") == 0)
5117 dut->ap_ampdu = 1;
5118 else if (strcasecmp(val, "Disable") == 0)
5119 dut->ap_ampdu = 2;
5120 else {
5121 send_resp(dut, conn, SIGMA_ERROR,
5122 "ErrorCode,AMPDU value is not Enable nor Disabled");
5123 return -1;
5124 }
5125 }
5126
5127 val = get_param(cmd, "AMSDU");
5128 if (val) {
5129 if (strcasecmp(val, "Enable") == 0)
5130 dut->ap_amsdu = 1;
5131 else if (strcasecmp(val, "Disable") == 0)
5132 dut->ap_amsdu = 2;
5133 }
5134
5135 val = get_param(cmd, "NumMSDU");
5136 if (val) {
5137 send_resp(dut, conn, SIGMA_ERROR,
5138 "ErrorCode, NumMSDU is not supported yet");
5139 return -1;
5140 }
5141
5142 val = get_param(cmd, "ABFTLRang");
5143 if (val) {
5144 sigma_dut_print(dut, DUT_MSG_DEBUG,
Lior David67543f52017-01-03 19:04:22 +02005145 "ABFTLRang parameter %s", val);
5146 if (strcmp(val, "Gt1") == 0)
5147 abft_len = 2; /* 2 slots in this case */
5148 }
5149
5150 if (sta_set_60g_abft_len(dut, conn, abft_len)) {
5151 send_resp(dut, conn, SIGMA_ERROR,
5152 "ErrorCode, Can't set ABFT length");
5153 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005154 }
5155
5156 if (sta_pcp_start(dut, conn, cmd) < 0) {
5157 send_resp(dut, conn, SIGMA_ERROR,
5158 "ErrorCode, Can't start PCP role");
5159 return -1;
5160 }
5161
5162 return sta_set_60g_common(dut, conn, cmd);
5163}
5164
5165
5166static int sta_set_60g_sta(struct sigma_dut *dut, struct sigma_conn *conn,
5167 struct sigma_cmd *cmd)
5168{
5169 const char *val = get_param(cmd, "DiscoveryMode");
5170
5171 if (dut->dev_role != DEVROLE_STA) {
5172 send_resp(dut, conn, SIGMA_INVALID,
5173 "ErrorCode,Invalid DevRole");
5174 return 0;
5175 }
5176
5177 if (val) {
5178 sigma_dut_print(dut, DUT_MSG_DEBUG, "Discovery: %s", val);
5179 /* Ignore Discovery mode till Driver expose API. */
5180#if 0
5181 if (strcasecmp(val, "1") == 0) {
5182 send_resp(dut, conn, SIGMA_INVALID,
5183 "ErrorCode,DiscoveryMode 1 not supported");
5184 return 0;
5185 }
5186
5187 if (strcasecmp(val, "0") == 0) {
5188 /* OK */
5189 } else {
5190 send_resp(dut, conn, SIGMA_INVALID,
5191 "ErrorCode,DiscoveryMode not supported");
5192 return 0;
5193 }
5194#endif
5195 }
5196
5197 if (start_sta_mode(dut) != 0)
5198 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
5199 return sta_set_60g_common(dut, conn, cmd);
5200}
5201
5202
5203static int cmd_sta_disconnect(struct sigma_dut *dut, struct sigma_conn *conn,
5204 struct sigma_cmd *cmd)
5205{
5206 const char *intf = get_param(cmd, "Interface");
Jouni Malinened77e672018-01-10 16:45:13 +02005207 const char *val = get_param(cmd, "maintain_profile");
vamsi krishnad605c422017-09-20 14:56:31 +05305208
Jouni Malinened77e672018-01-10 16:45:13 +02005209 if (dut->program == PROGRAM_OCE ||
Amarnath Hullur Subramanyamebeda9e2018-01-31 03:21:48 -08005210 dut->program == PROGRAM_HE ||
Jouni Malinened77e672018-01-10 16:45:13 +02005211 (val && atoi(val) == 1)) {
vamsi krishnad605c422017-09-20 14:56:31 +05305212 wpa_command(intf, "DISCONNECT");
5213 return 1;
5214 }
5215
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005216 disconnect_station(dut);
5217 /* Try to ignore old scan results to avoid HS 2.0R2 test case failures
5218 * due to cached results. */
5219 wpa_command(intf, "SET ignore_old_scan_res 1");
5220 wpa_command(intf, "BSS_FLUSH");
5221 return 1;
5222}
5223
5224
5225static int cmd_sta_reassoc(struct sigma_dut *dut, struct sigma_conn *conn,
5226 struct sigma_cmd *cmd)
5227{
5228 const char *intf = get_param(cmd, "Interface");
5229 const char *bssid = get_param(cmd, "bssid");
5230 const char *val = get_param(cmd, "CHANNEL");
5231 struct wpa_ctrl *ctrl;
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05305232 char buf[1000];
Sunil Duttd30ce092018-01-11 23:56:29 +05305233 char result[32];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005234 int res;
5235 int chan = 0;
Ashwini Patil467efef2017-05-25 12:18:27 +05305236 int status = 0;
Sunil Duttd30ce092018-01-11 23:56:29 +05305237 int fastreassoc = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005238
5239 if (bssid == NULL) {
5240 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing bssid "
5241 "argument");
5242 return 0;
5243 }
5244
5245 if (val)
5246 chan = atoi(val);
5247
5248 if (wifi_chip_type != DRIVER_WCN && wifi_chip_type != DRIVER_AR6003) {
5249 /* The current network may be from sta_associate or
5250 * sta_hs2_associate
5251 */
5252 if (set_network(intf, dut->infra_network_id, "bssid", bssid) <
5253 0 ||
5254 set_network(intf, 0, "bssid", bssid) < 0)
5255 return -2;
5256 }
5257
5258 ctrl = open_wpa_mon(intf);
5259 if (ctrl == NULL) {
5260 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
5261 "wpa_supplicant monitor connection");
5262 return -1;
5263 }
5264
Sunil Duttd30ce092018-01-11 23:56:29 +05305265 if (get_wpa_status(get_station_ifname(), "wpa_state", result,
5266 sizeof(result)) < 0 ||
5267 strncmp(result, "COMPLETED", 9) != 0) {
5268 sigma_dut_print(dut, DUT_MSG_DEBUG,
5269 "sta_reassoc: Not connected");
5270 fastreassoc = 0;
5271 }
5272
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05305273 if (dut->rsne_override) {
5274#ifdef NL80211_SUPPORT
5275 if (get_driver_type() == DRIVER_WCN && dut->config_rsnie == 0) {
5276 sta_config_rsnie(dut, 1);
5277 dut->config_rsnie = 1;
5278 }
5279#endif /* NL80211_SUPPORT */
5280 snprintf(buf, sizeof(buf), "TEST_ASSOC_IE %s",
5281 dut->rsne_override);
5282 if (wpa_command(intf, buf) < 0) {
5283 send_resp(dut, conn, SIGMA_ERROR,
5284 "ErrorCode,Failed to set DEV_CONFIGURE_IE RSNE override");
5285 return 0;
5286 }
5287 }
5288
Sunil Duttd30ce092018-01-11 23:56:29 +05305289 if (wifi_chip_type == DRIVER_WCN && fastreassoc) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005290#ifdef ANDROID
Ashwini Patil4c8158f2017-05-25 12:49:21 +05305291 if (chan) {
5292 unsigned int freq;
5293
5294 freq = channel_to_freq(chan);
5295 if (!freq) {
5296 sigma_dut_print(dut, DUT_MSG_ERROR,
5297 "Invalid channel number provided: %d",
5298 chan);
5299 send_resp(dut, conn, SIGMA_INVALID,
5300 "ErrorCode,Invalid channel number");
5301 goto close_mon_conn;
5302 }
5303 res = snprintf(buf, sizeof(buf),
5304 "SCAN TYPE=ONLY freq=%d", freq);
5305 } else {
5306 res = snprintf(buf, sizeof(buf), "SCAN TYPE=ONLY");
5307 }
5308 if (res < 0 || res >= (int) sizeof(buf)) {
5309 send_resp(dut, conn, SIGMA_ERROR,
5310 "ErrorCode,snprintf failed");
5311 goto close_mon_conn;
5312 }
5313 if (wpa_command(intf, buf) < 0) {
5314 sigma_dut_print(dut, DUT_MSG_INFO,
5315 "Failed to start scan");
5316 send_resp(dut, conn, SIGMA_ERROR,
5317 "ErrorCode,scan failed");
5318 goto close_mon_conn;
5319 }
5320
5321 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
5322 buf, sizeof(buf));
5323 if (res < 0) {
5324 sigma_dut_print(dut, DUT_MSG_INFO,
5325 "Scan did not complete");
5326 send_resp(dut, conn, SIGMA_ERROR,
5327 "ErrorCode,scan did not complete");
5328 goto close_mon_conn;
5329 }
5330
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005331 if (set_network(intf, dut->infra_network_id, "bssid", "any")
5332 < 0) {
5333 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
5334 "bssid to any during FASTREASSOC");
Ashwini Patil467efef2017-05-25 12:18:27 +05305335 status = -2;
5336 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005337 }
5338 res = snprintf(buf, sizeof(buf), "DRIVER FASTREASSOC %s %d",
5339 bssid, chan);
5340 if (res > 0 && res < (int) sizeof(buf))
5341 res = wpa_command(intf, buf);
5342
5343 if (res < 0 || res >= (int) sizeof(buf)) {
5344 send_resp(dut, conn, SIGMA_ERROR,
5345 "errorCode,Failed to run DRIVER FASTREASSOC");
Ashwini Patil467efef2017-05-25 12:18:27 +05305346 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005347 }
5348#else /* ANDROID */
5349 sigma_dut_print(dut, DUT_MSG_DEBUG,
5350 "Reassoc using iwpriv - skip chan=%d info",
5351 chan);
5352 snprintf(buf, sizeof(buf), "iwpriv %s reassoc", intf);
5353 if (system(buf) != 0) {
5354 sigma_dut_print(dut, DUT_MSG_ERROR, "%s failed", buf);
Ashwini Patil467efef2017-05-25 12:18:27 +05305355 status = -2;
5356 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005357 }
5358#endif /* ANDROID */
5359 sigma_dut_print(dut, DUT_MSG_INFO,
5360 "sta_reassoc: Run %s successful", buf);
5361 } else if (wpa_command(intf, "REASSOCIATE")) {
5362 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
5363 "request reassociation");
Ashwini Patil467efef2017-05-25 12:18:27 +05305364 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005365 }
5366
5367 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
5368 buf, sizeof(buf));
Ashwini Patil467efef2017-05-25 12:18:27 +05305369 if (res < 0) {
5370 sigma_dut_print(dut, DUT_MSG_INFO, "Connection did not complete");
5371 status = -1;
5372 goto close_mon_conn;
5373 }
5374 status = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005375
Ashwini Patil467efef2017-05-25 12:18:27 +05305376close_mon_conn:
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005377 wpa_ctrl_detach(ctrl);
5378 wpa_ctrl_close(ctrl);
Ashwini Patil467efef2017-05-25 12:18:27 +05305379 return status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005380}
5381
5382
5383static void hs2_clear_credentials(const char *intf)
5384{
5385 wpa_command(intf, "REMOVE_CRED all");
5386}
5387
5388
Lior Davidcc88b562017-01-03 18:52:09 +02005389#ifdef __linux__
5390static int wil6210_get_aid(struct sigma_dut *dut, const char *bssid,
5391 unsigned int *aid)
5392{
Lior David0fe101e2017-03-09 16:09:50 +02005393 const char *pattern = "AID[ \t]+([0-9]+)";
Lior Davidcc88b562017-01-03 18:52:09 +02005394
Lior David0fe101e2017-03-09 16:09:50 +02005395 return wil6210_get_sta_info_field(dut, bssid, pattern, aid);
Lior Davidcc88b562017-01-03 18:52:09 +02005396}
5397#endif /* __linux__ */
5398
5399
5400static int sta_get_aid_60g(struct sigma_dut *dut, const char *bssid,
5401 unsigned int *aid)
5402{
5403 switch (get_driver_type()) {
5404#ifdef __linux__
5405 case DRIVER_WIL6210:
5406 return wil6210_get_aid(dut, bssid, aid);
5407#endif /* __linux__ */
5408 default:
5409 sigma_dut_print(dut, DUT_MSG_ERROR, "get AID not supported");
5410 return -1;
5411 }
5412}
5413
5414
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005415static int sta_get_parameter_60g(struct sigma_dut *dut, struct sigma_conn *conn,
5416 struct sigma_cmd *cmd)
5417{
5418 char buf[MAX_CMD_LEN];
5419 char bss_list[MAX_CMD_LEN];
5420 const char *parameter = get_param(cmd, "Parameter");
5421
5422 if (parameter == NULL)
5423 return -1;
5424
Lior Davidcc88b562017-01-03 18:52:09 +02005425 if (strcasecmp(parameter, "AID") == 0) {
5426 unsigned int aid = 0;
5427 char bssid[20];
5428
5429 if (get_wpa_status(get_station_ifname(), "bssid",
5430 bssid, sizeof(bssid)) < 0) {
5431 sigma_dut_print(dut, DUT_MSG_ERROR,
5432 "could not get bssid");
5433 return -2;
5434 }
5435
5436 if (sta_get_aid_60g(dut, bssid, &aid))
5437 return -2;
5438
5439 snprintf(buf, sizeof(buf), "aid,%d", aid);
5440 sigma_dut_print(dut, DUT_MSG_INFO, "%s", buf);
5441 send_resp(dut, conn, SIGMA_COMPLETE, buf);
5442 return 0;
5443 }
5444
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005445 if (strcasecmp(parameter, "DiscoveredDevList") == 0) {
5446 char *bss_line;
5447 char *bss_id = NULL;
5448 const char *ifname = get_param(cmd, "Interface");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05305449 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005450
5451 if (ifname == NULL) {
5452 sigma_dut_print(dut, DUT_MSG_INFO,
5453 "For get DiscoveredDevList need Interface name.");
5454 return -1;
5455 }
5456
5457 /*
5458 * Use "BSS RANGE=ALL MASK=0x2" which provides a list
5459 * of BSSIDs in "bssid=<BSSID>\n"
5460 */
5461 if (wpa_command_resp(ifname, "BSS RANGE=ALL MASK=0x2",
5462 bss_list,
5463 sizeof(bss_list)) < 0) {
5464 sigma_dut_print(dut, DUT_MSG_ERROR,
5465 "Failed to get bss list");
5466 return -1;
5467 }
5468
5469 sigma_dut_print(dut, DUT_MSG_DEBUG,
5470 "bss list for ifname:%s is:%s",
5471 ifname, bss_list);
5472
5473 snprintf(buf, sizeof(buf), "DeviceList");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05305474 bss_line = strtok_r(bss_list, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005475 while (bss_line) {
5476 if (sscanf(bss_line, "bssid=%ms", &bss_id) > 0 &&
5477 bss_id) {
5478 int len;
5479
5480 len = snprintf(buf + strlen(buf),
5481 sizeof(buf) - strlen(buf),
5482 ",%s", bss_id);
5483 free(bss_id);
5484 bss_id = NULL;
5485 if (len < 0) {
5486 sigma_dut_print(dut,
5487 DUT_MSG_ERROR,
5488 "Failed to read BSSID");
5489 send_resp(dut, conn, SIGMA_ERROR,
5490 "ErrorCode,Failed to read BSS ID");
5491 return 0;
5492 }
5493
5494 if ((size_t) len >= sizeof(buf) - strlen(buf)) {
5495 sigma_dut_print(dut,
5496 DUT_MSG_ERROR,
5497 "Response buf too small for list");
5498 send_resp(dut, conn,
5499 SIGMA_ERROR,
5500 "ErrorCode,Response buf too small for list");
5501 return 0;
5502 }
5503 }
5504
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05305505 bss_line = strtok_r(NULL, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005506 }
5507
5508 sigma_dut_print(dut, DUT_MSG_INFO, "DiscoveredDevList is %s",
5509 buf);
5510 send_resp(dut, conn, SIGMA_COMPLETE, buf);
5511 return 0;
5512 }
5513
5514 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
5515 return 0;
5516}
5517
5518
5519static int cmd_sta_get_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
5520 struct sigma_cmd *cmd)
5521{
5522 const char *program = get_param(cmd, "Program");
5523
5524 if (program == NULL)
5525 return -1;
5526
5527 if (strcasecmp(program, "P2PNFC") == 0)
5528 return p2p_cmd_sta_get_parameter(dut, conn, cmd);
5529
5530 if (strcasecmp(program, "60ghz") == 0)
5531 return sta_get_parameter_60g(dut, conn, cmd);
5532
5533#ifdef ANDROID_NAN
5534 if (strcasecmp(program, "NAN") == 0)
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07005535 return nan_cmd_sta_get_parameter(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005536#endif /* ANDROID_NAN */
5537
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07005538#ifdef MIRACAST
5539 if (strcasecmp(program, "WFD") == 0 ||
5540 strcasecmp(program, "DisplayR2") == 0)
5541 return miracast_cmd_sta_get_parameter(dut, conn, cmd);
5542#endif /* MIRACAST */
5543
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005544 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
5545 return 0;
5546}
5547
5548
5549static void sta_reset_default_ath(struct sigma_dut *dut, const char *intf,
5550 const char *type)
5551{
5552 char buf[100];
5553
5554 if (dut->program == PROGRAM_VHT) {
5555 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 2", intf);
5556 if (system(buf) != 0) {
5557 sigma_dut_print(dut, DUT_MSG_ERROR,
5558 "iwpriv %s chwidth failed", intf);
5559 }
5560
5561 snprintf(buf, sizeof(buf), "iwpriv %s mode 11ACVHT80", intf);
5562 if (system(buf) != 0) {
5563 sigma_dut_print(dut, DUT_MSG_ERROR,
5564 "iwpriv %s mode 11ACVHT80 failed",
5565 intf);
5566 }
5567
5568 snprintf(buf, sizeof(buf), "iwpriv %s vhtmcs -1", intf);
5569 if (system(buf) != 0) {
5570 sigma_dut_print(dut, DUT_MSG_ERROR,
5571 "iwpriv %s vhtmcs -1 failed", intf);
5572 }
5573 }
5574
5575 if (dut->program == PROGRAM_HT) {
5576 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 0", intf);
5577 if (system(buf) != 0) {
5578 sigma_dut_print(dut, DUT_MSG_ERROR,
5579 "iwpriv %s chwidth failed", intf);
5580 }
5581
5582 snprintf(buf, sizeof(buf), "iwpriv %s mode 11naht40", intf);
5583 if (system(buf) != 0) {
5584 sigma_dut_print(dut, DUT_MSG_ERROR,
5585 "iwpriv %s mode 11naht40 failed",
5586 intf);
5587 }
5588
5589 snprintf(buf, sizeof(buf), "iwpriv %s set11NRates 0", intf);
5590 if (system(buf) != 0) {
5591 sigma_dut_print(dut, DUT_MSG_ERROR,
5592 "iwpriv set11NRates failed");
5593 }
5594 }
5595
5596 if (dut->program == PROGRAM_VHT || dut->program == PROGRAM_HT) {
5597 snprintf(buf, sizeof(buf), "iwpriv %s powersave 0", intf);
5598 if (system(buf) != 0) {
5599 sigma_dut_print(dut, DUT_MSG_ERROR,
5600 "disabling powersave failed");
5601 }
5602
5603 /* Reset CTS width */
5604 snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 54 0",
5605 intf);
5606 if (system(buf) != 0) {
5607 sigma_dut_print(dut, DUT_MSG_ERROR,
5608 "wifitool %s beeliner_fw_test 54 0 failed",
5609 intf);
5610 }
5611
5612 /* Enable Dynamic Bandwidth signalling by default */
5613 snprintf(buf, sizeof(buf), "iwpriv %s cwmenable 1", intf);
5614 if (system(buf) != 0) {
5615 sigma_dut_print(dut, DUT_MSG_ERROR,
5616 "iwpriv %s cwmenable 1 failed", intf);
5617 }
5618
5619 snprintf(buf, sizeof(buf), "iwconfig %s rts 2347", intf);
5620 if (system(buf) != 0) {
5621 sigma_dut_print(dut, DUT_MSG_ERROR,
5622 "iwpriv rts failed");
5623 }
5624 }
5625
5626 if (type && strcasecmp(type, "Testbed") == 0) {
5627 dut->testbed_flag_txsp = 1;
5628 dut->testbed_flag_rxsp = 1;
5629 /* STA has to set spatial stream to 2 per Appendix H */
5630 snprintf(buf, sizeof(buf), "iwpriv %s vht_mcsmap 0xfff0", intf);
5631 if (system(buf) != 0) {
5632 sigma_dut_print(dut, DUT_MSG_ERROR,
5633 "iwpriv vht_mcsmap failed");
5634 }
5635
5636 /* Disable LDPC per Appendix H */
5637 snprintf(buf, sizeof(buf), "iwpriv %s ldpc 0", intf);
5638 if (system(buf) != 0) {
5639 sigma_dut_print(dut, DUT_MSG_ERROR,
5640 "iwpriv %s ldpc 0 failed", intf);
5641 }
5642
5643 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 1", intf);
5644 if (system(buf) != 0) {
5645 sigma_dut_print(dut, DUT_MSG_ERROR,
5646 "iwpriv amsdu failed");
5647 }
5648
5649 /* TODO: Disable STBC 2x1 transmit and receive */
5650 snprintf(buf, sizeof(buf), "iwpriv %s tx_stbc 0", intf);
5651 if (system(buf) != 0) {
5652 sigma_dut_print(dut, DUT_MSG_ERROR,
5653 "Disable tx_stbc 0 failed");
5654 }
5655
5656 snprintf(buf, sizeof(buf), "iwpriv %s rx_stbc 0", intf);
5657 if (system(buf) != 0) {
5658 sigma_dut_print(dut, DUT_MSG_ERROR,
5659 "Disable rx_stbc 0 failed");
5660 }
5661
5662 /* STA has to disable Short GI per Appendix H */
5663 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 0", intf);
5664 if (system(buf) != 0) {
5665 sigma_dut_print(dut, DUT_MSG_ERROR,
5666 "iwpriv %s shortgi 0 failed", intf);
5667 }
5668 }
5669
5670 if (type && strcasecmp(type, "DUT") == 0) {
5671 snprintf(buf, sizeof(buf), "iwpriv %s nss 3", intf);
5672 if (system(buf) != 0) {
5673 sigma_dut_print(dut, DUT_MSG_ERROR,
5674 "iwpriv %s nss 3 failed", intf);
5675 }
Arif Hussainac6c5112018-05-25 17:34:00 -07005676 dut->sta_nss = 3;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005677
5678 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 1", intf);
5679 if (system(buf) != 0) {
5680 sigma_dut_print(dut, DUT_MSG_ERROR,
5681 "iwpriv %s shortgi 1 failed", intf);
5682 }
5683 }
5684}
5685
5686
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08005687#ifdef NL80211_SUPPORT
5688static int sta_set_he_mcs(struct sigma_dut *dut, const char *intf,
5689 enum he_mcs_config mcs)
5690{
5691 struct nl_msg *msg;
5692 int ret = 0;
5693 struct nlattr *params;
5694 int ifindex;
5695
5696 ifindex = if_nametoindex(intf);
5697 if (ifindex == 0) {
5698 sigma_dut_print(dut, DUT_MSG_ERROR,
5699 "%s: Index for interface %s failed",
5700 __func__, intf);
5701 return -1;
5702 }
5703
5704 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
5705 NL80211_CMD_VENDOR)) ||
5706 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
5707 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
5708 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
5709 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
5710 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
5711 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MCS,
5712 mcs)) {
5713 sigma_dut_print(dut, DUT_MSG_ERROR,
5714 "%s: err in adding vendor_cmd and vendor_data",
5715 __func__);
5716 nlmsg_free(msg);
5717 return -1;
5718 }
5719 nla_nest_end(msg, params);
5720
5721 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5722 if (ret) {
5723 sigma_dut_print(dut, DUT_MSG_ERROR,
5724 "%s: err in send_and_recv_msgs, ret=%d",
5725 __func__, ret);
5726 }
5727 return ret;
5728}
5729#endif /* NL80211_SUPPORT */
5730
5731
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08005732static int sta_set_heconfig_and_wep_tkip(struct sigma_dut *dut,
5733 const char *intf, int enable)
5734{
5735#ifdef NL80211_SUPPORT
5736 struct nl_msg *msg;
5737 int ret = 0;
5738 struct nlattr *params;
5739 int ifindex;
5740
5741 ifindex = if_nametoindex(intf);
5742 if (ifindex == 0) {
5743 sigma_dut_print(dut, DUT_MSG_ERROR,
5744 "%s: Index for interface %s failed",
5745 __func__, intf);
5746 return -1;
5747 }
5748
5749 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
5750 NL80211_CMD_VENDOR)) ||
5751 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
5752 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
5753 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
5754 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
5755 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
5756 nla_put_u8(msg,
5757 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WEP_TKIP_IN_HE,
5758 enable)) {
5759 sigma_dut_print(dut, DUT_MSG_ERROR,
5760 "%s: err in adding vendor_cmd and vendor_data",
5761 __func__);
5762 nlmsg_free(msg);
5763 return -1;
5764 }
5765 nla_nest_end(msg, params);
5766
5767 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5768 if (ret) {
5769 sigma_dut_print(dut, DUT_MSG_ERROR,
5770 "%s: err in send_and_recv_msgs, ret=%d",
5771 __func__, ret);
5772 }
5773 return ret;
5774#else /* NL80211_SUPPORT */
5775 sigma_dut_print(dut, DUT_MSG_ERROR,
5776 "HE config enablement cannot be changed without NL80211_SUPPORT defined");
5777 return -1;
5778#endif /* NL80211_SUPPORT */
5779}
5780
5781
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08005782static int sta_set_addba_buf_size(struct sigma_dut *dut,
5783 const char *intf, int bufsize)
5784{
5785#ifdef NL80211_SUPPORT
5786 struct nl_msg *msg;
5787 int ret = 0;
5788 struct nlattr *params;
5789 int ifindex;
5790
5791 ifindex = if_nametoindex(intf);
5792 if (ifindex == 0) {
5793 sigma_dut_print(dut, DUT_MSG_ERROR,
5794 "%s: Index for interface %s failed",
5795 __func__, intf);
5796 return -1;
5797 }
5798
5799 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
5800 NL80211_CMD_VENDOR)) ||
5801 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
5802 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
5803 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
5804 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
5805 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
5806 nla_put_u8(msg,
5807 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE,
5808 bufsize)) {
5809 sigma_dut_print(dut, DUT_MSG_ERROR,
5810 "%s: err in adding vendor_cmd and vendor_data",
5811 __func__);
5812 nlmsg_free(msg);
5813 return -1;
5814 }
5815 nla_nest_end(msg, params);
5816
5817 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5818 if (ret) {
5819 sigma_dut_print(dut, DUT_MSG_ERROR,
5820 "%s: err in send_and_recv_msgs, ret=%d",
5821 __func__, ret);
5822 }
5823 return ret;
5824#else /* NL80211_SUPPORT */
5825 sigma_dut_print(dut, DUT_MSG_ERROR,
5826 "AddBA bufsize cannot be changed without NL80211_SUPPORT defined");
5827 return -1;
5828#endif /* NL80211_SUPPORT */
5829}
5830
5831
Arif Hussain8d5b27b2018-05-14 14:31:03 -07005832static int sta_set_tx_beamformee(struct sigma_dut *dut, const char *intf,
5833 int enable)
5834{
5835#ifdef NL80211_SUPPORT
5836 struct nl_msg *msg;
5837 int ret = 0;
5838 struct nlattr *params;
5839 int ifindex;
5840
5841 ifindex = if_nametoindex(intf);
5842 if (ifindex == 0) {
5843 sigma_dut_print(dut, DUT_MSG_ERROR,
5844 "%s: Index for interface %s failed",
5845 __func__, intf);
5846 return -1;
5847 }
5848
5849 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
5850 NL80211_CMD_VENDOR)) ||
5851 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
5852 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
5853 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
5854 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
5855 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
5856 nla_put_u8(msg,
5857 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_TX_BEAMFORMEE,
5858 enable)) {
5859 sigma_dut_print(dut, DUT_MSG_ERROR,
5860 "%s: err in adding vendor_cmd and vendor_data",
5861 __func__);
5862 nlmsg_free(msg);
5863 return -1;
5864 }
5865 nla_nest_end(msg, params);
5866
5867 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5868 if (ret) {
5869 sigma_dut_print(dut, DUT_MSG_ERROR,
5870 "%s: err in send_and_recv_msgs, ret=%d",
5871 __func__, ret);
5872 }
5873 return ret;
5874#else /* NL80211_SUPPORT */
5875 sigma_dut_print(dut, DUT_MSG_ERROR,
5876 "tx beamformee cannot be changed without NL80211_SUPPORT defined");
5877 return -1;
5878#endif /* NL80211_SUPPORT */
5879}
5880
5881
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08005882static void sta_reset_default_wcn(struct sigma_dut *dut, const char *intf,
5883 const char *type)
5884{
5885 char buf[60];
5886
5887 if (dut->program == PROGRAM_HE) {
5888 /* resetting phymode to auto in case of HE program */
5889 snprintf(buf, sizeof(buf), "iwpriv %s setphymode 0", intf);
5890 if (system(buf) != 0) {
5891 sigma_dut_print(dut, DUT_MSG_ERROR,
5892 "iwpriv %s setphymode failed", intf);
5893 }
5894
Amarnath Hullur Subramanyam9cecb502018-04-25 13:26:30 -07005895 /* reset the rate to Auto rate */
5896 snprintf(buf, sizeof(buf), "iwpriv %s set_11ax_rate 0xff",
5897 intf);
5898 if (system(buf) != 0) {
5899 sigma_dut_print(dut, DUT_MSG_ERROR,
5900 "iwpriv %s set_11ax_rate 0xff failed",
5901 intf);
5902 }
5903
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08005904 /* remove all network profiles */
5905 remove_wpa_networks(intf);
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08005906
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08005907 /* Configure ADDBA Req/Rsp buffer size to be 64 */
5908 sta_set_addba_buf_size(dut, intf, 64);
5909
Amarnath Hullur Subramanyam5f32d572018-03-02 00:02:33 -08005910#ifdef NL80211_SUPPORT
5911 /* Disable noackpolicy for all AC */
5912 if (nlvendor_sta_set_noack(dut, intf, 0, QCA_WLAN_AC_ALL)) {
5913 sigma_dut_print(dut, DUT_MSG_ERROR,
5914 "Disable of noackpolicy for all AC failed");
5915 }
5916#endif /* NL80211_SUPPORT */
5917
Amarnath Hullur Subramanyamb1724a52018-03-07 14:31:46 -08005918 /* Enable WMM by default */
5919 if (wcn_sta_set_wmm(dut, intf, "on")) {
5920 sigma_dut_print(dut, DUT_MSG_ERROR,
5921 "Enable of WMM in sta_reset_default_wcn failed");
5922 }
5923
5924 /* Disable ADDBA_REJECT by default */
5925 if (nlvendor_sta_set_addba_reject(dut, intf, 0)) {
5926 sigma_dut_print(dut, DUT_MSG_ERROR,
5927 "Disable of addba_reject in sta_reset_default_wcn failed");
5928 }
5929
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08005930 /* Enable sending of ADDBA by default */
5931 if (nlvendor_config_send_addba(dut, intf, 1)) {
5932 sigma_dut_print(dut, DUT_MSG_ERROR,
5933 "Enable sending of ADDBA in sta_reset_default_wcn failed");
5934 }
5935
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08005936 /* Enable AMPDU by default */
5937 iwpriv_sta_set_ampdu(dut, intf, 1);
5938
Subhani Shaik8e7a3052018-04-24 14:03:00 -07005939#ifdef NL80211_SUPPORT
5940 if (sta_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_AUTO)) {
5941 sigma_dut_print(dut, DUT_MSG_ERROR,
5942 "Set LTF config to default in sta_reset_default_wcn failed");
5943 }
5944#endif /* NL80211_SUPPORT */
5945
Arif Hussain8d5b27b2018-05-14 14:31:03 -07005946 if (sta_set_tx_beamformee(dut, intf, 1)) {
5947 sigma_dut_print(dut, DUT_MSG_ERROR,
5948 "Set tx beamformee enable by default in sta_reset_default_wcn failed");
5949 }
5950
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08005951 /* Set nss to 1 and MCS 0-7 in case of testbed */
5952 if (type && strcasecmp(type, "Testbed") == 0) {
5953#ifdef NL80211_SUPPORT
5954 int ret;
5955#endif /* NL80211_SUPPORT */
5956
5957 snprintf(buf, sizeof(buf), "iwpriv %s nss 1", intf);
5958 if (system(buf) != 0) {
5959 sigma_dut_print(dut, DUT_MSG_ERROR,
5960 "iwpriv %s nss failed", intf);
5961 }
5962
5963#ifdef NL80211_SUPPORT
5964 ret = sta_set_he_mcs(dut, intf, HE_80_MCS0_7);
5965 if (ret) {
5966 sigma_dut_print(dut, DUT_MSG_ERROR,
5967 "Setting of MCS failed, ret:%d",
5968 ret);
5969 }
5970#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyamc67621d2018-02-04 23:18:01 -08005971
5972 /* Disable STBC as default */
5973 wcn_sta_set_stbc(dut, intf, "0");
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08005974
5975 /* Disable AMSDU as default */
5976 iwpriv_sta_set_amsdu(dut, intf, "0");
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08005977
5978#ifdef NL80211_SUPPORT
5979 /* HE fragmentation default off */
5980 if (sta_set_he_fragmentation(dut, intf,
5981 HE_FRAG_DISABLE)) {
5982 sigma_dut_print(dut, DUT_MSG_ERROR,
5983 "Setting of HE fragmentation failed");
5984 }
5985#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08005986
5987 /* Enable WEP/TKIP with HE capability in testbed */
5988 if (sta_set_heconfig_and_wep_tkip(dut, intf, 1)) {
5989 sigma_dut_print(dut, DUT_MSG_ERROR,
5990 "Enabling HE config with WEP/TKIP failed");
5991 }
Arif Hussain8d5b27b2018-05-14 14:31:03 -07005992
5993 if (sta_set_tx_beamformee(dut, intf, 0)) {
5994 sigma_dut_print(dut, DUT_MSG_ERROR,
5995 "Set tx beamformee disable by default for testbed in sta_reset_default_wcn failed");
5996 }
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08005997 }
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08005998
5999 /* Defaults in case of DUT */
6000 if (type && strcasecmp(type, "DUT") == 0) {
Arif Hussaind48fcc72018-05-01 18:34:18 -07006001 /* Enable STBC by default */
6002 wcn_sta_set_stbc(dut, intf, "1");
6003
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08006004 /* set nss to 2 */
6005 snprintf(buf, sizeof(buf), "iwpriv %s nss 2", intf);
6006 if (system(buf) != 0) {
6007 sigma_dut_print(dut, DUT_MSG_ERROR,
6008 "iwpriv %s nss 2 failed", intf);
6009 }
Arif Hussainac6c5112018-05-25 17:34:00 -07006010 dut->sta_nss = 2;
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08006011
6012#ifdef NL80211_SUPPORT
Arif Hussainae239842018-05-01 18:20:05 -07006013 /* Set HE_MCS to 0-11 */
6014 if (sta_set_he_mcs(dut, intf, HE_80_MCS0_11)) {
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08006015 sigma_dut_print(dut, DUT_MSG_ERROR,
6016 "Setting of MCS failed");
6017 }
6018#endif /* NL80211_SUPPORT */
6019
6020 /* Disable WEP/TKIP with HE capability in DUT */
6021 if (sta_set_heconfig_and_wep_tkip(dut, intf, 0)) {
6022 sigma_dut_print(dut, DUT_MSG_ERROR,
6023 "Enabling HE config with WEP/TKIP failed");
6024 }
6025 }
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08006026 }
6027}
6028
6029
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006030static int cmd_sta_reset_default(struct sigma_dut *dut,
6031 struct sigma_conn *conn,
6032 struct sigma_cmd *cmd)
6033{
6034 int cmd_sta_p2p_reset(struct sigma_dut *dut, struct sigma_conn *conn,
6035 struct sigma_cmd *cmd);
6036 const char *intf = get_param(cmd, "Interface");
6037 const char *type;
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07006038 const char *program = get_param(cmd, "program");
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05306039 const char *dev_role = get_param(cmd, "DevRole");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006040
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07006041 if (!program)
6042 program = get_param(cmd, "prog");
6043 dut->program = sigma_program_to_enum(program);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006044 dut->device_type = STA_unknown;
6045 type = get_param(cmd, "type");
6046 if (type && strcasecmp(type, "Testbed") == 0)
6047 dut->device_type = STA_testbed;
6048 if (type && strcasecmp(type, "DUT") == 0)
6049 dut->device_type = STA_dut;
6050
6051 if (dut->program == PROGRAM_TDLS) {
6052 /* Clear TDLS testing mode */
6053 wpa_command(intf, "SET tdls_disabled 0");
6054 wpa_command(intf, "SET tdls_testing 0");
6055 dut->no_tpk_expiration = 0;
Pradeep Reddy POTTETI8ce2a232016-10-28 12:17:32 +05306056 if (get_driver_type() == DRIVER_WCN) {
6057 /* Enable the WCN driver in TDLS Explicit trigger mode
6058 */
6059 wpa_command(intf, "SET tdls_external_control 0");
6060 wpa_command(intf, "SET tdls_trigger_control 0");
6061 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006062 }
6063
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07006064#ifdef MIRACAST
6065 if (dut->program == PROGRAM_WFD ||
6066 dut->program == PROGRAM_DISPLAYR2)
6067 miracast_sta_reset_default(dut, conn, cmd);
6068#endif /* MIRACAST */
6069
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006070 switch (get_driver_type()) {
6071 case DRIVER_ATHEROS:
6072 sta_reset_default_ath(dut, intf, type);
6073 break;
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08006074 case DRIVER_WCN:
6075 sta_reset_default_wcn(dut, intf, type);
6076 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006077 default:
6078 break;
6079 }
6080
6081#ifdef ANDROID_NAN
6082 if (dut->program == PROGRAM_NAN)
6083 nan_cmd_sta_reset_default(dut, conn, cmd);
6084#endif /* ANDROID_NAN */
6085
6086 if (dut->program == PROGRAM_HS2_R2) {
6087 unlink("SP/wi-fi.org/pps.xml");
6088 if (system("rm -r SP/*") != 0) {
6089 }
6090 unlink("next-client-cert.pem");
6091 unlink("next-client-key.pem");
6092 }
6093
6094 if (dut->program == PROGRAM_60GHZ) {
6095 const char *dev_role = get_param(cmd, "DevRole");
6096
6097 if (!dev_role) {
6098 send_resp(dut, conn, SIGMA_ERROR,
6099 "errorCode,Missing DevRole argument");
6100 return 0;
6101 }
6102
6103 if (strcasecmp(dev_role, "STA") == 0)
6104 dut->dev_role = DEVROLE_STA;
6105 else if (strcasecmp(dev_role, "PCP") == 0)
6106 dut->dev_role = DEVROLE_PCP;
6107 else {
6108 send_resp(dut, conn, SIGMA_ERROR,
6109 "errorCode,Unknown DevRole");
6110 return 0;
6111 }
6112
6113 if (dut->device_type == STA_unknown) {
6114 sigma_dut_print(dut, DUT_MSG_ERROR,
6115 "Device type is not STA testbed or DUT");
6116 send_resp(dut, conn, SIGMA_ERROR,
6117 "errorCode,Unknown device type");
6118 return 0;
6119 }
6120 }
6121
6122 wpa_command(intf, "WPS_ER_STOP");
6123 wpa_command(intf, "FLUSH");
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05306124 wpa_command(intf, "ERP_FLUSH");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006125 wpa_command(intf, "SET radio_disabled 0");
6126
6127 if (dut->tmp_mac_addr && dut->set_macaddr) {
6128 dut->tmp_mac_addr = 0;
6129 if (system(dut->set_macaddr) != 0) {
6130 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to clear "
6131 "temporary MAC address");
6132 }
6133 }
6134
6135 set_ps(intf, dut, 0);
6136
6137 if (dut->program == PROGRAM_HS2 || dut->program == PROGRAM_HS2_R2) {
6138 wpa_command(intf, "SET interworking 1");
6139 wpa_command(intf, "SET hs20 1");
6140 }
6141
Deepak Dhamdhere0fe0e452017-12-18 14:52:09 -08006142 if (dut->program == PROGRAM_HS2_R2 ||
6143 dut->program == PROGRAM_OCE) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006144 wpa_command(intf, "SET pmf 1");
6145 } else {
6146 wpa_command(intf, "SET pmf 0");
6147 }
6148
6149 hs2_clear_credentials(intf);
6150 wpa_command(intf, "SET hessid 00:00:00:00:00:00");
6151 wpa_command(intf, "SET access_network_type 15");
6152
6153 static_ip_file(0, NULL, NULL, NULL);
6154 kill_dhcp_client(dut, intf);
6155 clear_ip_addr(dut, intf);
6156
6157 dut->er_oper_performed = 0;
6158 dut->er_oper_bssid[0] = '\0';
6159
priyadharshini gowthamanad6cbba2016-10-04 10:39:58 -07006160 if (dut->program == PROGRAM_LOC) {
6161 /* Disable Interworking by default */
6162 wpa_command(get_station_ifname(), "SET interworking 0");
6163 }
6164
Ashwini Patil00402582017-04-13 12:29:39 +05306165 if (dut->program == PROGRAM_MBO) {
6166 free(dut->non_pref_ch_list);
6167 dut->non_pref_ch_list = NULL;
Ashwini Patil5acd7382017-04-13 15:55:04 +05306168 free(dut->btm_query_cand_list);
6169 dut->btm_query_cand_list = NULL;
Ashwini Patilc63161e2017-04-13 16:30:23 +05306170 wpa_command(intf, "SET reject_btm_req_reason 0");
Ashwini Patila75de5a2017-04-13 16:35:05 +05306171 wpa_command(intf, "SET ignore_assoc_disallow 0");
Ashwini Patild174f2c2017-04-13 16:49:46 +05306172 wpa_command(intf, "SET gas_address3 0");
Ashwini Patil9183fdb2017-04-13 16:58:25 +05306173 wpa_command(intf, "SET roaming 1");
Ashwini Patil00402582017-04-13 12:29:39 +05306174 }
6175
Jouni Malinen3c367e82017-06-23 17:01:47 +03006176 free(dut->rsne_override);
6177 dut->rsne_override = NULL;
6178
Jouni Malinen68143132017-09-02 02:34:08 +03006179 free(dut->sae_commit_override);
6180 dut->sae_commit_override = NULL;
6181
Jouni Malinend86e5822017-08-29 03:55:32 +03006182 dut->dpp_conf_id = -1;
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02006183 free(dut->dpp_peer_uri);
6184 dut->dpp_peer_uri = NULL;
Jouni Malinen63d50412017-11-24 11:55:38 +02006185 dut->dpp_local_bootstrap = -1;
Jouni Malinen5011fb52017-12-05 21:00:15 +02006186 wpa_command(intf, "SET dpp_config_processing 2");
Jouni Malinend86e5822017-08-29 03:55:32 +03006187
Jouni Malinenfac9cad2017-10-10 18:35:55 +03006188 wpa_command(intf, "VENDOR_ELEM_REMOVE 13 *");
6189
vamsi krishnaa2799492017-12-05 14:28:01 +05306190 if (dut->program == PROGRAM_OCE) {
Ankita Bajaja2cb5672017-10-25 16:08:28 +05306191 wpa_command(intf, "SET oce 1");
vamsi krishnaa2799492017-12-05 14:28:01 +05306192 wpa_command(intf, "SET disable_fils 0");
Ankita Bajaj1bde7942018-01-09 19:15:01 +05306193 wpa_command(intf, "FILS_HLP_REQ_FLUSH");
6194 dut->fils_hlp = 0;
6195#ifdef ANDROID
6196 hlp_thread_cleanup(dut);
6197#endif /* ANDROID */
vamsi krishnaa2799492017-12-05 14:28:01 +05306198 }
Ankita Bajaja2cb5672017-10-25 16:08:28 +05306199
Sunil Dutt076081f2018-02-05 19:45:50 +05306200#ifdef NL80211_SUPPORT
Sunil Dutt44595082018-02-12 19:41:45 +05306201 if (get_driver_type() == DRIVER_WCN &&
6202 dut->config_rsnie == 1) {
6203 dut->config_rsnie = 0;
6204 sta_config_rsnie(dut, 0);
Sunil Dutt076081f2018-02-05 19:45:50 +05306205 }
6206#endif /* NL80211_SUPPORT */
6207
Sunil Duttfebf8a82018-02-09 18:50:13 +05306208 if (dev_role && strcasecmp(dev_role, "STA-CFON") == 0) {
6209 dut->dev_role = DEVROLE_STA_CFON;
6210 return sta_cfon_reset_default(dut, conn, cmd);
6211 }
6212
6213 if (dut->program != PROGRAM_VHT)
6214 return cmd_sta_p2p_reset(dut, conn, cmd);
6215
Priyadharshini Gowthamana7dfd492015-11-09 14:34:08 -08006216 return 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006217}
6218
6219
6220static int cmd_sta_get_events(struct sigma_dut *dut, struct sigma_conn *conn,
6221 struct sigma_cmd *cmd)
6222{
6223 const char *program = get_param(cmd, "Program");
6224
6225 if (program == NULL)
6226 return -1;
6227#ifdef ANDROID_NAN
6228 if (strcasecmp(program, "NAN") == 0)
6229 return nan_cmd_sta_get_events(dut, conn, cmd);
6230#endif /* ANDROID_NAN */
6231 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
6232 return 0;
6233}
6234
6235
Jouni Malinen82905202018-04-29 17:20:10 +03006236static int sta_exec_action_url(struct sigma_dut *dut, struct sigma_conn *conn,
6237 struct sigma_cmd *cmd)
6238{
6239 const char *url = get_param(cmd, "url");
6240 const char *method = get_param(cmd, "method");
6241 pid_t pid;
6242 int status;
6243
6244 if (!url || !method)
6245 return -1;
6246
6247 /* TODO: Add support for method,post */
6248 if (strcasecmp(method, "get") != 0) {
6249 send_resp(dut, conn, SIGMA_ERROR,
6250 "ErrorCode,Unsupported method");
6251 return 0;
6252 }
6253
6254 pid = fork();
6255 if (pid < 0) {
6256 perror("fork");
6257 return -1;
6258 }
6259
6260 if (pid == 0) {
6261 char * argv[5] = { "wget", "-O", "/dev/null",
6262 (char *) url, NULL };
6263
6264 execv("/usr/bin/wget", argv);
6265 perror("execv");
6266 exit(0);
6267 return -1;
6268 }
6269
6270 if (waitpid(pid, &status, 0) < 0) {
6271 perror("waitpid");
6272 return -1;
6273 }
6274
6275 if (WIFEXITED(status)) {
6276 const char *errmsg;
6277
6278 if (WEXITSTATUS(status) == 0)
6279 return 1;
6280 sigma_dut_print(dut, DUT_MSG_INFO, "wget exit status %d",
6281 WEXITSTATUS(status));
6282 switch (WEXITSTATUS(status)) {
6283 case 4:
6284 errmsg = "errmsg,Network failure";
6285 break;
6286 case 8:
6287 errmsg = "errmsg,Server issued an error response";
6288 break;
6289 default:
6290 errmsg = "errmsg,Unknown failure from wget";
6291 break;
6292 }
6293 send_resp(dut, conn, SIGMA_ERROR, errmsg);
6294 return 0;
6295 }
6296
6297 send_resp(dut, conn, SIGMA_ERROR, "errmsg,Unknown failure");
6298 return 0;
6299}
6300
6301
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006302static int cmd_sta_exec_action(struct sigma_dut *dut, struct sigma_conn *conn,
6303 struct sigma_cmd *cmd)
6304{
6305 const char *program = get_param(cmd, "Prog");
6306
Jouni Malinen82905202018-04-29 17:20:10 +03006307 if (program && !get_param(cmd, "interface"))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006308 return -1;
6309#ifdef ANDROID_NAN
Jouni Malinen82905202018-04-29 17:20:10 +03006310 if (program && strcasecmp(program, "NAN") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006311 return nan_cmd_sta_exec_action(dut, conn, cmd);
6312#endif /* ANDROID_NAN */
Jouni Malinen82905202018-04-29 17:20:10 +03006313
6314 if (program && strcasecmp(program, "Loc") == 0)
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07006315 return loc_cmd_sta_exec_action(dut, conn, cmd);
Jouni Malinen82905202018-04-29 17:20:10 +03006316
6317 if (get_param(cmd, "url"))
6318 return sta_exec_action_url(dut, conn, cmd);
6319
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006320 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
6321 return 0;
6322}
6323
6324
6325static int cmd_sta_set_11n(struct sigma_dut *dut, struct sigma_conn *conn,
6326 struct sigma_cmd *cmd)
6327{
6328 const char *intf = get_param(cmd, "Interface");
6329 const char *val, *mcs32, *rate;
6330
6331 val = get_param(cmd, "GREENFIELD");
6332 if (val) {
6333 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
6334 /* Enable GD */
6335 send_resp(dut, conn, SIGMA_ERROR,
6336 "ErrorCode,GF not supported");
6337 return 0;
6338 }
6339 }
6340
6341 val = get_param(cmd, "SGI20");
6342 if (val) {
6343 switch (get_driver_type()) {
6344 case DRIVER_ATHEROS:
6345 ath_sta_set_sgi(dut, intf, val);
6346 break;
6347 default:
6348 send_resp(dut, conn, SIGMA_ERROR,
6349 "ErrorCode,SGI20 not supported");
6350 return 0;
6351 }
6352 }
6353
6354 mcs32 = get_param(cmd, "MCS32"); /* HT Duplicate Mode Enable/Disable */
6355 rate = get_param(cmd, "MCS_FIXEDRATE"); /* Fixed MCS rate (0..31) */
6356 if (mcs32 && rate) {
6357 /* TODO */
6358 send_resp(dut, conn, SIGMA_ERROR,
6359 "ErrorCode,MCS32,MCS_FIXEDRATE not supported");
6360 return 0;
6361 } else if (mcs32 && !rate) {
6362 /* TODO */
6363 send_resp(dut, conn, SIGMA_ERROR,
6364 "ErrorCode,MCS32 not supported");
6365 return 0;
6366 } else if (!mcs32 && rate) {
6367 switch (get_driver_type()) {
6368 case DRIVER_ATHEROS:
priyadharshini gowthamane5e25172015-12-08 14:53:48 -08006369 novap_reset(dut, intf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006370 ath_sta_set_11nrates(dut, intf, rate);
6371 break;
6372 default:
6373 send_resp(dut, conn, SIGMA_ERROR,
6374 "ErrorCode,MCS32_FIXEDRATE not supported");
6375 return 0;
6376 }
6377 }
6378
6379 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
6380}
6381
6382
Arif Hussain7b47d2d2018-05-09 10:44:02 -07006383static void cmd_set_max_he_mcs(struct sigma_dut *dut, const char *intf,
6384 int mcs_config)
6385{
6386#ifdef NL80211_SUPPORT
6387 int ret;
6388
6389 switch (mcs_config) {
6390 case HE_80_MCS0_7:
6391 case HE_80_MCS0_9:
6392 case HE_80_MCS0_11:
6393 ret = sta_set_he_mcs(dut, intf, mcs_config);
6394 if (ret) {
6395 sigma_dut_print(dut, DUT_MSG_ERROR,
6396 "cmd_set_max_he_mcs: Setting of MCS:%d failed, ret:%d",
6397 mcs_config, ret);
6398 }
6399 break;
6400 default:
6401 sigma_dut_print(dut, DUT_MSG_ERROR,
6402 "cmd_set_max_he_mcs: Invalid mcs %d",
6403 mcs_config);
6404 break;
6405 }
6406#else /* NL80211_SUPPORT */
6407 sigma_dut_print(dut, DUT_MSG_ERROR,
6408 "max HE MCS cannot be changed without NL80211_SUPPORT defined");
6409#endif /* NL80211_SUPPORT */
6410}
6411
6412
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006413static int cmd_sta_set_wireless_vht(struct sigma_dut *dut,
6414 struct sigma_conn *conn,
6415 struct sigma_cmd *cmd)
6416{
6417 const char *intf = get_param(cmd, "Interface");
6418 const char *val;
6419 char buf[30];
6420 int tkip = -1;
6421 int wep = -1;
6422
6423 val = get_param(cmd, "SGI80");
6424 if (val) {
6425 int sgi80;
6426
6427 sgi80 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
6428 snprintf(buf, sizeof(buf), "iwpriv %s shortgi %d", intf, sgi80);
6429 if (system(buf) != 0) {
6430 sigma_dut_print(dut, DUT_MSG_ERROR,
6431 "iwpriv shortgi failed");
6432 }
6433 }
6434
6435 val = get_param(cmd, "TxBF");
6436 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
6437 snprintf(buf, sizeof(buf), "iwpriv %s vhtsubfee 1", intf);
6438 if (system(buf) != 0) {
6439 sigma_dut_print(dut, DUT_MSG_ERROR,
6440 "iwpriv vhtsubfee failed");
6441 }
6442 snprintf(buf, sizeof(buf), "iwpriv %s vhtsubfer 1", intf);
6443 if (system(buf) != 0) {
6444 sigma_dut_print(dut, DUT_MSG_ERROR,
6445 "iwpriv vhtsubfer failed");
6446 }
6447 }
6448
6449 val = get_param(cmd, "MU_TxBF");
6450 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
6451 switch (get_driver_type()) {
6452 case DRIVER_ATHEROS:
6453 ath_sta_set_txsp_stream(dut, intf, "1SS");
6454 ath_sta_set_rxsp_stream(dut, intf, "1SS");
6455 case DRIVER_WCN:
6456 if (wcn_sta_set_sp_stream(dut, intf, "1SS") < 0) {
6457 send_resp(dut, conn, SIGMA_ERROR,
6458 "ErrorCode,Failed to set RX/TXSP_STREAM");
6459 return 0;
6460 }
6461 default:
6462 sigma_dut_print(dut, DUT_MSG_ERROR,
6463 "Setting SP_STREAM not supported");
6464 break;
6465 }
6466 snprintf(buf, sizeof(buf), "iwpriv %s vhtmubfee 1", intf);
6467 if (system(buf) != 0) {
6468 sigma_dut_print(dut, DUT_MSG_ERROR,
6469 "iwpriv vhtmubfee failed");
6470 }
6471 snprintf(buf, sizeof(buf), "iwpriv %s vhtmubfer 1", intf);
6472 if (system(buf) != 0) {
6473 sigma_dut_print(dut, DUT_MSG_ERROR,
6474 "iwpriv vhtmubfer failed");
6475 }
6476 }
6477
6478 val = get_param(cmd, "LDPC");
6479 if (val) {
6480 int ldpc;
6481
6482 ldpc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
6483 snprintf(buf, sizeof(buf), "iwpriv %s ldpc %d", intf, ldpc);
6484 if (system(buf) != 0) {
6485 sigma_dut_print(dut, DUT_MSG_ERROR,
6486 "iwpriv ldpc failed");
6487 }
6488 }
6489
Amarnath Hullur Subramanyam7bae60e2018-01-31 03:46:50 -08006490 val = get_param(cmd, "BCC");
6491 if (val) {
6492 int bcc;
6493
6494 bcc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
6495 /* use LDPC iwpriv itself to set bcc coding, bcc coding
6496 * is mutually exclusive to bcc */
6497 snprintf(buf, sizeof(buf), "iwpriv %s ldpc %d", intf, !bcc);
6498 if (system(buf) != 0) {
6499 sigma_dut_print(dut, DUT_MSG_ERROR,
6500 "Enabling/Disabling of BCC failed");
6501 }
6502 }
6503
Arif Hussain7b47d2d2018-05-09 10:44:02 -07006504 val = get_param(cmd, "MaxHE-MCS_1SS_RxMapLTE80");
6505 if (val && dut->sta_nss == 1)
6506 cmd_set_max_he_mcs(dut, intf, atoi(val));
6507
6508 val = get_param(cmd, "MaxHE-MCS_2SS_RxMapLTE80");
6509 if (val && dut->sta_nss == 2)
6510 cmd_set_max_he_mcs(dut, intf, atoi(val));
6511
Arif Hussainac6c5112018-05-25 17:34:00 -07006512 val = get_param(cmd, "MCS_FixedRate");
6513 if (val) {
6514#ifdef NL80211_SUPPORT
6515 int mcs, ratecode = 0;
6516 enum he_mcs_config mcs_config;
6517 int ret;
6518
6519 ratecode = (0x07 & dut->sta_nss) << 5;
6520 mcs = atoi(val);
6521 /* Add the MCS to the ratecode */
6522 if (mcs >= 0 && mcs <= 11) {
6523 ratecode += mcs;
6524 if (dut->device_type == STA_testbed &&
6525 mcs > 7 && mcs <= 11) {
6526 if (mcs <= 9)
6527 mcs_config = HE_80_MCS0_9;
6528 else
6529 mcs_config = HE_80_MCS0_11;
6530 ret = sta_set_he_mcs(dut, intf, mcs_config);
6531 if (ret) {
6532 sigma_dut_print(dut, DUT_MSG_ERROR,
6533 "MCS_FixedRate: mcs setting failed, mcs:%d, mcs_config %d, ret:%d",
6534 mcs, mcs_config, ret);
6535 }
6536 }
6537 snprintf(buf, sizeof(buf),
6538 "iwpriv %s set_11ax_rate 0x%03x",
6539 intf, ratecode);
6540 if (system(buf) != 0) {
6541 sigma_dut_print(dut, DUT_MSG_ERROR,
6542 "MCS_FixedRate: iwpriv setting of 11ax rates 0x%03x failed",
6543 ratecode);
6544 }
6545 } else {
6546 sigma_dut_print(dut, DUT_MSG_ERROR,
6547 "MCS_FixedRate: HE MCS %d not supported",
6548 mcs);
6549 }
6550#else /* NL80211_SUPPORT */
6551 sigma_dut_print(dut, DUT_MSG_ERROR,
6552 "MCS_FixedRate cannot be changed without NL80211_SUPPORT defined");
6553#endif /* NL80211_SUPPORT */
6554 }
6555
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006556 val = get_param(cmd, "opt_md_notif_ie");
6557 if (val) {
6558 char *result = NULL;
6559 char delim[] = ";";
6560 char token[30];
6561 int value, config_val = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05306562 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006563
Peng Xub8fc5cc2017-05-10 17:27:28 -07006564 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05306565 result = strtok_r(token, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006566
6567 /* Extract the NSS information */
6568 if (result) {
6569 value = atoi(result);
6570 switch (value) {
6571 case 1:
6572 config_val = 1;
6573 break;
6574 case 2:
6575 config_val = 3;
6576 break;
6577 case 3:
6578 config_val = 7;
6579 break;
6580 case 4:
6581 config_val = 15;
6582 break;
6583 default:
6584 config_val = 3;
6585 break;
6586 }
6587
6588 snprintf(buf, sizeof(buf), "iwpriv %s rxchainmask %d",
6589 intf, config_val);
6590 if (system(buf) != 0) {
6591 sigma_dut_print(dut, DUT_MSG_ERROR,
6592 "iwpriv rxchainmask failed");
6593 }
6594
6595 snprintf(buf, sizeof(buf), "iwpriv %s txchainmask %d",
6596 intf, config_val);
6597 if (system(buf) != 0) {
6598 sigma_dut_print(dut, DUT_MSG_ERROR,
6599 "iwpriv txchainmask failed");
6600 }
6601 }
6602
6603 /* Extract the channel width information */
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05306604 result = strtok_r(NULL, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006605 if (result) {
6606 value = atoi(result);
6607 switch (value) {
6608 case 20:
6609 config_val = 0;
6610 break;
6611 case 40:
6612 config_val = 1;
6613 break;
6614 case 80:
6615 config_val = 2;
6616 break;
6617 case 160:
6618 config_val = 3;
6619 break;
6620 default:
6621 config_val = 2;
6622 break;
6623 }
6624
6625 dut->chwidth = config_val;
6626
6627 snprintf(buf, sizeof(buf), "iwpriv %s chwidth %d",
6628 intf, config_val);
6629 if (system(buf) != 0) {
6630 sigma_dut_print(dut, DUT_MSG_ERROR,
6631 "iwpriv chwidth failed");
6632 }
6633 }
6634
6635 snprintf(buf, sizeof(buf), "iwpriv %s opmode_notify 1", intf);
6636 if (system(buf) != 0) {
6637 sigma_dut_print(dut, DUT_MSG_ERROR,
6638 "iwpriv opmode_notify failed");
6639 }
6640 }
6641
6642 val = get_param(cmd, "nss_mcs_cap");
6643 if (val) {
6644 int nss, mcs;
6645 char token[20];
6646 char *result = NULL;
6647 unsigned int vht_mcsmap = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05306648 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006649
Peng Xub8fc5cc2017-05-10 17:27:28 -07006650 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05306651 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05306652 if (!result) {
6653 sigma_dut_print(dut, DUT_MSG_ERROR,
6654 "VHT NSS not specified");
6655 return 0;
6656 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006657 nss = atoi(result);
6658
6659 snprintf(buf, sizeof(buf), "iwpriv %s nss %d", intf, nss);
6660 if (system(buf) != 0) {
6661 sigma_dut_print(dut, DUT_MSG_ERROR,
6662 "iwpriv nss failed");
6663 }
Arif Hussainac6c5112018-05-25 17:34:00 -07006664 dut->sta_nss = nss;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006665
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05306666 result = strtok_r(NULL, ";", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006667 if (result == NULL) {
6668 sigma_dut_print(dut, DUT_MSG_ERROR,
6669 "VHTMCS NOT SPECIFIED!");
6670 return 0;
6671 }
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05306672 result = strtok_r(result, "-", &saveptr);
6673 result = strtok_r(NULL, "-", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05306674 if (!result) {
6675 sigma_dut_print(dut, DUT_MSG_ERROR,
6676 "VHT MCS not specified");
6677 return 0;
6678 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006679 mcs = atoi(result);
6680
6681 snprintf(buf, sizeof(buf), "iwpriv %s vhtmcs %d", intf, mcs);
6682 if (system(buf) != 0) {
6683 sigma_dut_print(dut, DUT_MSG_ERROR,
6684 "iwpriv mcs failed");
6685 }
6686
6687 switch (nss) {
6688 case 1:
6689 switch (mcs) {
6690 case 7:
6691 vht_mcsmap = 0xfffc;
6692 break;
6693 case 8:
6694 vht_mcsmap = 0xfffd;
6695 break;
6696 case 9:
6697 vht_mcsmap = 0xfffe;
6698 break;
6699 default:
6700 vht_mcsmap = 0xfffe;
6701 break;
6702 }
6703 break;
6704 case 2:
6705 switch (mcs) {
6706 case 7:
6707 vht_mcsmap = 0xfff0;
6708 break;
6709 case 8:
6710 vht_mcsmap = 0xfff5;
6711 break;
6712 case 9:
6713 vht_mcsmap = 0xfffa;
6714 break;
6715 default:
6716 vht_mcsmap = 0xfffa;
6717 break;
6718 }
6719 break;
6720 case 3:
6721 switch (mcs) {
6722 case 7:
6723 vht_mcsmap = 0xffc0;
6724 break;
6725 case 8:
6726 vht_mcsmap = 0xffd5;
6727 break;
6728 case 9:
6729 vht_mcsmap = 0xffea;
6730 break;
6731 default:
6732 vht_mcsmap = 0xffea;
6733 break;
6734 }
6735 break;
6736 default:
6737 vht_mcsmap = 0xffea;
6738 break;
6739 }
6740 snprintf(buf, sizeof(buf), "iwpriv %s vht_mcsmap 0x%04x",
6741 intf, vht_mcsmap);
6742 if (system(buf) != 0) {
6743 sigma_dut_print(dut, DUT_MSG_ERROR,
6744 "iwpriv vht_mcsmap failed");
6745 }
6746 }
6747
6748 /* UNSUPPORTED: val = get_param(cmd, "Tx_lgi_rate"); */
6749
6750 val = get_param(cmd, "Vht_tkip");
6751 if (val)
6752 tkip = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
6753
6754 val = get_param(cmd, "Vht_wep");
6755 if (val)
6756 wep = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
6757
6758 if (tkip != -1 || wep != -1) {
6759 if ((tkip == 1 && wep != 0) || (wep == 1 && tkip != 0)) {
6760 snprintf(buf, sizeof(buf), "iwpriv %s htweptkip 1",
6761 intf);
6762 } else if ((tkip == 0 && wep != 1) || (wep == 0 && tkip != 1)) {
6763 snprintf(buf, sizeof(buf), "iwpriv %s htweptkip 0",
6764 intf);
6765 } else {
6766 sigma_dut_print(dut, DUT_MSG_ERROR,
6767 "ErrorCode,mixed mode of VHT TKIP/WEP not supported");
6768 return 0;
6769 }
6770
6771 if (system(buf) != 0) {
6772 sigma_dut_print(dut, DUT_MSG_ERROR,
6773 "iwpriv htweptkip failed");
6774 }
6775 }
6776
6777 val = get_param(cmd, "txBandwidth");
6778 if (val) {
6779 switch (get_driver_type()) {
Amarnath Hullur Subramanyam4f860292018-01-31 03:49:35 -08006780 case DRIVER_WCN:
6781 if (wcn_sta_set_width(dut, intf, val) < 0) {
6782 send_resp(dut, conn, SIGMA_ERROR,
6783 "ErrorCode,Failed to set txBandwidth");
6784 return 0;
6785 }
6786 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006787 case DRIVER_ATHEROS:
6788 if (ath_set_width(dut, conn, intf, val) < 0) {
6789 send_resp(dut, conn, SIGMA_ERROR,
6790 "ErrorCode,Failed to set txBandwidth");
6791 return 0;
6792 }
6793 break;
6794 default:
6795 sigma_dut_print(dut, DUT_MSG_ERROR,
6796 "Setting txBandwidth not supported");
6797 break;
6798 }
6799 }
6800
6801 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
6802}
6803
6804
6805static int sta_set_wireless_60g(struct sigma_dut *dut,
6806 struct sigma_conn *conn,
6807 struct sigma_cmd *cmd)
6808{
6809 const char *dev_role = get_param(cmd, "DevRole");
6810
6811 if (!dev_role) {
6812 send_resp(dut, conn, SIGMA_INVALID,
6813 "ErrorCode,DevRole not specified");
6814 return 0;
6815 }
6816
6817 if (strcasecmp(dev_role, "PCP") == 0)
6818 return sta_set_60g_pcp(dut, conn, cmd);
6819 if (strcasecmp(dev_role, "STA") == 0)
6820 return sta_set_60g_sta(dut, conn, cmd);
6821 send_resp(dut, conn, SIGMA_INVALID,
6822 "ErrorCode,DevRole not supported");
6823 return 0;
6824}
6825
6826
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05306827static int sta_set_wireless_oce(struct sigma_dut *dut, struct sigma_conn *conn,
6828 struct sigma_cmd *cmd)
6829{
6830 int status;
6831 const char *intf = get_param(cmd, "Interface");
6832 const char *val = get_param(cmd, "DevRole");
6833
6834 if (val && strcasecmp(val, "STA-CFON") == 0) {
6835 status = sta_cfon_set_wireless(dut, conn, cmd);
6836 if (status)
6837 return status;
6838 }
6839 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
6840}
6841
6842
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006843static int cmd_sta_set_wireless(struct sigma_dut *dut, struct sigma_conn *conn,
6844 struct sigma_cmd *cmd)
6845{
6846 const char *val;
6847
6848 val = get_param(cmd, "Program");
6849 if (val) {
6850 if (strcasecmp(val, "11n") == 0)
6851 return cmd_sta_set_11n(dut, conn, cmd);
Amarnath Hullur Subramanyam4f860292018-01-31 03:49:35 -08006852 if (strcasecmp(val, "VHT") == 0 || strcasecmp(val, "HE") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006853 return cmd_sta_set_wireless_vht(dut, conn, cmd);
6854 if (strcasecmp(val, "60ghz") == 0)
6855 return sta_set_wireless_60g(dut, conn, cmd);
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05306856 if (strcasecmp(val, "OCE") == 0)
6857 return sta_set_wireless_oce(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006858 send_resp(dut, conn, SIGMA_ERROR,
6859 "ErrorCode,Program value not supported");
6860 } else {
6861 send_resp(dut, conn, SIGMA_ERROR,
6862 "ErrorCode,Program argument not available");
6863 }
6864
6865 return 0;
6866}
6867
6868
6869static void ath_sta_inject_frame(struct sigma_dut *dut, const char *intf,
6870 int tid)
6871{
6872 char buf[100];
6873 int tid_to_dscp [] = { 0x00, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0 };
6874
Pradeep Reddy POTTETId31d1322016-10-13 17:22:03 +05306875 if (tid < 0 ||
6876 tid >= (int) (sizeof(tid_to_dscp) / sizeof(tid_to_dscp[0]))) {
6877 sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported TID: %d", tid);
6878 return;
6879 }
6880
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006881 /*
6882 * Two ways to ensure that addba request with a
6883 * non zero TID could be sent out. EV 117296
6884 */
6885 snprintf(buf, sizeof(buf),
6886 "ping -c 8 -Q %d `arp -a | grep wlan0 | awk '{print $2}' | tr -d '()'`",
6887 tid);
6888 if (system(buf) != 0) {
6889 sigma_dut_print(dut, DUT_MSG_ERROR,
6890 "Ping did not send out");
6891 }
6892
6893 snprintf(buf, sizeof(buf),
6894 "iwconfig %s | grep Access | awk '{print $6}' > %s",
6895 intf, VI_QOS_TMP_FILE);
6896 if (system(buf) != 0)
6897 return;
6898
6899 snprintf(buf, sizeof(buf),
6900 "ifconfig %s | grep HWaddr | cut -b 39-56 >> %s",
6901 intf, VI_QOS_TMP_FILE);
6902 if (system(buf) != 0)
6903 sigma_dut_print(dut, DUT_MSG_ERROR, "HWaddr matching failed");
6904
6905 snprintf(buf,sizeof(buf), "sed -n '3,$p' %s >> %s",
6906 VI_QOS_REFFILE, VI_QOS_TMP_FILE);
6907 if (system(buf) != 0) {
6908 sigma_dut_print(dut, DUT_MSG_ERROR,
6909 "VI_QOS_TEMP_FILE generation error failed");
6910 }
6911 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
6912 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
6913 if (system(buf) != 0) {
6914 sigma_dut_print(dut, DUT_MSG_ERROR,
6915 "VI_QOS_FILE generation failed");
6916 }
6917
6918 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
6919 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
6920 if (system(buf) != 0) {
6921 sigma_dut_print(dut, DUT_MSG_ERROR,
6922 "VI_QOS_FILE generation failed");
6923 }
6924
6925 snprintf(buf, sizeof(buf), "ethinject %s %s", intf, VI_QOS_FILE);
6926 if (system(buf) != 0) {
6927 }
6928}
6929
6930
6931static int ath_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
6932 struct sigma_cmd *cmd)
6933{
6934 const char *intf = get_param(cmd, "Interface");
6935 const char *val;
6936 int tid = 0;
6937 char buf[100];
6938
6939 val = get_param(cmd, "TID");
6940 if (val) {
6941 tid = atoi(val);
6942 if (tid)
6943 ath_sta_inject_frame(dut, intf, tid);
6944 }
6945
6946 /* Command sequence for ADDBA request on Peregrine based devices */
6947 snprintf(buf, sizeof(buf), "iwpriv %s setaddbaoper 1", intf);
6948 if (system(buf) != 0) {
6949 sigma_dut_print(dut, DUT_MSG_ERROR,
6950 "iwpriv setaddbaoper failed");
6951 }
6952
6953 snprintf(buf, sizeof(buf), "wifitool %s senddelba 1 %d 1 4", intf, tid);
6954 if (system(buf) != 0) {
6955 sigma_dut_print(dut, DUT_MSG_ERROR,
6956 "wifitool senddelba failed");
6957 }
6958
6959 snprintf(buf, sizeof(buf), "wifitool %s sendaddba 1 %d 64", intf, tid);
6960 if (system(buf) != 0) {
6961 sigma_dut_print(dut, DUT_MSG_ERROR,
6962 "wifitool sendaddba failed");
6963 }
6964
6965 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
6966
6967 return 1;
6968}
6969
6970
Lior David9981b512017-01-20 13:16:40 +02006971#ifdef __linux__
6972
6973static int wil6210_send_addba(struct sigma_dut *dut, const char *dest_mac,
6974 int agg_size)
6975{
6976 char dir[128], buf[128];
6977 FILE *f;
6978 regex_t re;
6979 regmatch_t m[2];
6980 int rc, ret = -1, vring_id, found;
6981
6982 if (wil6210_get_debugfs_dir(dut, dir, sizeof(dir))) {
6983 sigma_dut_print(dut, DUT_MSG_ERROR,
6984 "failed to get wil6210 debugfs dir");
6985 return -1;
6986 }
6987
6988 snprintf(buf, sizeof(buf), "%s/vrings", dir);
6989 f = fopen(buf, "r");
6990 if (!f) {
6991 sigma_dut_print(dut, DUT_MSG_ERROR, "failed to open: %s", buf);
6992 return -1;
6993 }
6994
6995 if (regcomp(&re, "VRING tx_[ \t]*([0-9]+)", REG_EXTENDED)) {
6996 sigma_dut_print(dut, DUT_MSG_ERROR, "regcomp failed");
6997 goto out;
6998 }
6999
7000 /* find TX VRING for the mac address */
7001 found = 0;
7002 while (fgets(buf, sizeof(buf), f)) {
7003 if (strcasestr(buf, dest_mac)) {
7004 found = 1;
7005 break;
7006 }
7007 }
7008
7009 if (!found) {
7010 sigma_dut_print(dut, DUT_MSG_ERROR,
7011 "no TX VRING for %s", dest_mac);
7012 goto out;
7013 }
7014
7015 /* extract VRING ID, "VRING tx_<id> = {" */
7016 if (!fgets(buf, sizeof(buf), f)) {
7017 sigma_dut_print(dut, DUT_MSG_ERROR,
7018 "no VRING start line for %s", dest_mac);
7019 goto out;
7020 }
7021
7022 rc = regexec(&re, buf, 2, m, 0);
7023 regfree(&re);
7024 if (rc || m[1].rm_so < 0) {
7025 sigma_dut_print(dut, DUT_MSG_ERROR,
7026 "no VRING TX ID for %s", dest_mac);
7027 goto out;
7028 }
7029 buf[m[1].rm_eo] = 0;
7030 vring_id = atoi(&buf[m[1].rm_so]);
7031
7032 /* send the addba command */
7033 fclose(f);
7034 snprintf(buf, sizeof(buf), "%s/back", dir);
7035 f = fopen(buf, "w");
7036 if (!f) {
7037 sigma_dut_print(dut, DUT_MSG_ERROR,
7038 "failed to open: %s", buf);
7039 return -1;
7040 }
7041
7042 fprintf(f, "add %d %d\n", vring_id, agg_size);
7043
7044 ret = 0;
7045
7046out:
7047 fclose(f);
7048
7049 return ret;
7050}
7051
7052
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007053static int send_addba_60g(struct sigma_dut *dut, struct sigma_conn *conn,
7054 struct sigma_cmd *cmd)
7055{
7056 const char *val;
7057 int tid = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007058
7059 val = get_param(cmd, "TID");
7060 if (val) {
7061 tid = atoi(val);
7062 if (tid != 0) {
7063 sigma_dut_print(dut, DUT_MSG_ERROR,
7064 "Ignore TID %d for send_addba use TID 0 for 60g since only 0 required on TX",
7065 tid);
7066 }
7067 }
7068
7069 val = get_param(cmd, "Dest_mac");
7070 if (!val) {
7071 sigma_dut_print(dut, DUT_MSG_ERROR,
7072 "Currently not supporting addba for 60G without Dest_mac");
7073 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
7074 }
7075
Lior David9981b512017-01-20 13:16:40 +02007076 if (wil6210_send_addba(dut, val, dut->back_rcv_buf))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007077 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007078
7079 return 1;
7080}
7081
Lior David9981b512017-01-20 13:16:40 +02007082#endif /* __linux__ */
7083
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007084
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08007085static int wcn_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
7086 struct sigma_cmd *cmd)
7087{
7088#ifdef NL80211_SUPPORT
7089 const char *intf = get_param(cmd, "Interface");
7090 const char *val;
7091 int tid = -1;
7092 int bufsize = 64;
7093 struct nl_msg *msg;
7094 int ret = 0;
7095 struct nlattr *params;
7096 int ifindex;
7097
7098 val = get_param(cmd, "TID");
7099 if (val)
7100 tid = atoi(val);
7101
7102 if (tid == -1) {
7103 send_resp(dut, conn, SIGMA_ERROR,
7104 "ErrorCode,sta_send_addba tid invalid");
7105 return 0;
7106 }
7107
7108 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
7109
7110 ifindex = if_nametoindex(intf);
7111 if (ifindex == 0) {
7112 sigma_dut_print(dut, DUT_MSG_ERROR,
7113 "%s: Index for interface %s failed",
7114 __func__, intf);
7115 send_resp(dut, conn, SIGMA_ERROR,
7116 "ErrorCode,sta_send_addba interface invalid");
7117 return 0;
7118 }
7119
7120 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7121 NL80211_CMD_VENDOR)) ||
7122 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7123 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7124 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7125 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7126 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7127 nla_put_u8(msg,
7128 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADD_DEL_BA_SESSION,
7129 QCA_WLAN_ADD_BA) ||
7130 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BA_TID,
7131 tid) ||
7132 nla_put_u8(msg,
7133 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE,
7134 bufsize)) {
7135 sigma_dut_print(dut, DUT_MSG_ERROR,
7136 "%s: err in adding vendor_cmd and vendor_data",
7137 __func__);
7138 nlmsg_free(msg);
7139 send_resp(dut, conn, SIGMA_ERROR,
7140 "ErrorCode,sta_send_addba err in adding vendor_cmd and vendor_data");
7141 return 0;
7142 }
7143 nla_nest_end(msg, params);
7144
7145 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7146 if (ret) {
7147 sigma_dut_print(dut, DUT_MSG_ERROR,
7148 "%s: err in send_and_recv_msgs, ret=%d",
7149 __func__, ret);
Sunil Dutt30605592018-05-04 20:35:50 +05307150 if (ret == -EOPNOTSUPP)
7151 return 1;
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08007152 send_resp(dut, conn, SIGMA_ERROR,
7153 "ErrorCode,sta_send_addba err in send_and_recv_msgs");
7154 return 0;
7155 }
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08007156#else /* NL80211_SUPPORT */
7157 sigma_dut_print(dut, DUT_MSG_ERROR,
7158 "sta_send_addba not supported without NL80211_SUPPORT defined");
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08007159#endif /* NL80211_SUPPORT */
Sunil Dutt30605592018-05-04 20:35:50 +05307160
7161 return 1;
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08007162}
7163
7164
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007165static int cmd_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
7166 struct sigma_cmd *cmd)
7167{
7168 switch (get_driver_type()) {
7169 case DRIVER_ATHEROS:
7170 return ath_sta_send_addba(dut, conn, cmd);
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08007171 case DRIVER_WCN:
7172 return wcn_sta_send_addba(dut, conn, cmd);
Lior David9981b512017-01-20 13:16:40 +02007173#ifdef __linux__
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007174 case DRIVER_WIL6210:
7175 return send_addba_60g(dut, conn, cmd);
Lior David9981b512017-01-20 13:16:40 +02007176#endif /* __linux__ */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007177 default:
7178 /*
7179 * There is no driver specific implementation for other drivers.
7180 * Ignore the command and report COMPLETE since the following
7181 * throughput test operation will end up sending ADDBA anyway.
7182 */
7183 return 1;
7184 }
7185}
7186
7187
7188int inject_eth_frame(int s, const void *data, size_t len,
7189 unsigned short ethtype, char *dst, char *src)
7190{
7191 struct iovec iov[4] = {
7192 {
7193 .iov_base = dst,
7194 .iov_len = ETH_ALEN,
7195 },
7196 {
7197 .iov_base = src,
7198 .iov_len = ETH_ALEN,
7199 },
7200 {
7201 .iov_base = &ethtype,
7202 .iov_len = sizeof(unsigned short),
7203 },
7204 {
7205 .iov_base = (void *) data,
7206 .iov_len = len,
7207 }
7208 };
7209 struct msghdr msg = {
7210 .msg_name = NULL,
7211 .msg_namelen = 0,
7212 .msg_iov = iov,
7213 .msg_iovlen = 4,
7214 .msg_control = NULL,
7215 .msg_controllen = 0,
7216 .msg_flags = 0,
7217 };
7218
7219 return sendmsg(s, &msg, 0);
7220}
7221
7222#if defined(__linux__) || defined(__QNXNTO__)
7223
7224int inject_frame(int s, const void *data, size_t len, int encrypt)
7225{
7226#define IEEE80211_RADIOTAP_F_WEP 0x04
7227#define IEEE80211_RADIOTAP_F_FRAG 0x08
7228 unsigned char rtap_hdr[] = {
7229 0x00, 0x00, /* radiotap version */
7230 0x0e, 0x00, /* radiotap length */
7231 0x02, 0xc0, 0x00, 0x00, /* bmap: flags, tx and rx flags */
7232 IEEE80211_RADIOTAP_F_FRAG, /* F_FRAG (fragment if required) */
7233 0x00, /* padding */
7234 0x00, 0x00, /* RX and TX flags to indicate that */
7235 0x00, 0x00, /* this is the injected frame directly */
7236 };
7237 struct iovec iov[2] = {
7238 {
7239 .iov_base = &rtap_hdr,
7240 .iov_len = sizeof(rtap_hdr),
7241 },
7242 {
7243 .iov_base = (void *) data,
7244 .iov_len = len,
7245 }
7246 };
7247 struct msghdr msg = {
7248 .msg_name = NULL,
7249 .msg_namelen = 0,
7250 .msg_iov = iov,
7251 .msg_iovlen = 2,
7252 .msg_control = NULL,
7253 .msg_controllen = 0,
7254 .msg_flags = 0,
7255 };
7256
7257 if (encrypt)
7258 rtap_hdr[8] |= IEEE80211_RADIOTAP_F_WEP;
7259
7260 return sendmsg(s, &msg, 0);
7261}
7262
7263
7264int open_monitor(const char *ifname)
7265{
7266#ifdef __QNXNTO__
7267 struct sockaddr_dl ll;
7268 int s;
7269
7270 memset(&ll, 0, sizeof(ll));
7271 ll.sdl_family = AF_LINK;
7272 ll.sdl_index = if_nametoindex(ifname);
7273 if (ll.sdl_index == 0) {
7274 perror("if_nametoindex");
7275 return -1;
7276 }
7277 s = socket(PF_INET, SOCK_RAW, 0);
7278#else /* __QNXNTO__ */
7279 struct sockaddr_ll ll;
7280 int s;
7281
7282 memset(&ll, 0, sizeof(ll));
7283 ll.sll_family = AF_PACKET;
7284 ll.sll_ifindex = if_nametoindex(ifname);
7285 if (ll.sll_ifindex == 0) {
7286 perror("if_nametoindex");
7287 return -1;
7288 }
7289 s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
7290#endif /* __QNXNTO__ */
7291 if (s < 0) {
7292 perror("socket[PF_PACKET,SOCK_RAW]");
7293 return -1;
7294 }
7295
7296 if (bind(s, (struct sockaddr *) &ll, sizeof(ll)) < 0) {
7297 perror("monitor socket bind");
7298 close(s);
7299 return -1;
7300 }
7301
7302 return s;
7303}
7304
7305
7306static int hex2num(char c)
7307{
7308 if (c >= '0' && c <= '9')
7309 return c - '0';
7310 if (c >= 'a' && c <= 'f')
7311 return c - 'a' + 10;
7312 if (c >= 'A' && c <= 'F')
7313 return c - 'A' + 10;
7314 return -1;
7315}
7316
7317
7318int hwaddr_aton(const char *txt, unsigned char *addr)
7319{
7320 int i;
7321
7322 for (i = 0; i < 6; i++) {
7323 int a, b;
7324
7325 a = hex2num(*txt++);
7326 if (a < 0)
7327 return -1;
7328 b = hex2num(*txt++);
7329 if (b < 0)
7330 return -1;
7331 *addr++ = (a << 4) | b;
7332 if (i < 5 && *txt++ != ':')
7333 return -1;
7334 }
7335
7336 return 0;
7337}
7338
7339#endif /* defined(__linux__) || defined(__QNXNTO__) */
7340
7341enum send_frame_type {
7342 DISASSOC, DEAUTH, SAQUERY, AUTH, ASSOCREQ, REASSOCREQ, DLS_REQ
7343};
7344enum send_frame_protection {
7345 CORRECT_KEY, INCORRECT_KEY, UNPROTECTED
7346};
7347
7348
7349static int sta_inject_frame(struct sigma_dut *dut, struct sigma_conn *conn,
7350 enum send_frame_type frame,
7351 enum send_frame_protection protected,
7352 const char *dest)
7353{
7354#ifdef __linux__
7355 unsigned char buf[1000], *pos;
7356 int s, res;
7357 char bssid[20], addr[20];
7358 char result[32], ssid[100];
7359 size_t ssid_len;
7360
7361 if (get_wpa_status(get_station_ifname(), "wpa_state", result,
7362 sizeof(result)) < 0 ||
7363 strncmp(result, "COMPLETED", 9) != 0) {
7364 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Not connected");
7365 return 0;
7366 }
7367
7368 if (get_wpa_status(get_station_ifname(), "bssid", bssid, sizeof(bssid))
7369 < 0) {
7370 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
7371 "current BSSID");
7372 return 0;
7373 }
7374
7375 if (get_wpa_status(get_station_ifname(), "address", addr, sizeof(addr))
7376 < 0) {
7377 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
7378 "own MAC address");
7379 return 0;
7380 }
7381
7382 if (get_wpa_status(get_station_ifname(), "ssid", ssid, sizeof(ssid))
7383 < 0) {
7384 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
7385 "current SSID");
7386 return 0;
7387 }
7388 ssid_len = strlen(ssid);
7389
7390 pos = buf;
7391
7392 /* Frame Control */
7393 switch (frame) {
7394 case DISASSOC:
7395 *pos++ = 0xa0;
7396 break;
7397 case DEAUTH:
7398 *pos++ = 0xc0;
7399 break;
7400 case SAQUERY:
7401 *pos++ = 0xd0;
7402 break;
7403 case AUTH:
7404 *pos++ = 0xb0;
7405 break;
7406 case ASSOCREQ:
7407 *pos++ = 0x00;
7408 break;
7409 case REASSOCREQ:
7410 *pos++ = 0x20;
7411 break;
7412 case DLS_REQ:
7413 *pos++ = 0xd0;
7414 break;
7415 }
7416
7417 if (protected == INCORRECT_KEY)
7418 *pos++ = 0x40; /* Set Protected field to 1 */
7419 else
7420 *pos++ = 0x00;
7421
7422 /* Duration */
7423 *pos++ = 0x00;
7424 *pos++ = 0x00;
7425
7426 /* addr1 = DA (current AP) */
7427 hwaddr_aton(bssid, pos);
7428 pos += 6;
7429 /* addr2 = SA (own address) */
7430 hwaddr_aton(addr, pos);
7431 pos += 6;
7432 /* addr3 = BSSID (current AP) */
7433 hwaddr_aton(bssid, pos);
7434 pos += 6;
7435
7436 /* Seq# (to be filled by driver/mac80211) */
7437 *pos++ = 0x00;
7438 *pos++ = 0x00;
7439
7440 if (protected == INCORRECT_KEY) {
7441 /* CCMP parameters */
7442 memcpy(pos, "\x61\x01\x00\x20\x00\x10\x00\x00", 8);
7443 pos += 8;
7444 }
7445
7446 if (protected == INCORRECT_KEY) {
7447 switch (frame) {
7448 case DEAUTH:
7449 /* Reason code (encrypted) */
7450 memcpy(pos, "\xa7\x39", 2);
7451 pos += 2;
7452 break;
7453 case DISASSOC:
7454 /* Reason code (encrypted) */
7455 memcpy(pos, "\xa7\x39", 2);
7456 pos += 2;
7457 break;
7458 case SAQUERY:
7459 /* Category|Action|TransID (encrypted) */
7460 memcpy(pos, "\x6f\xbd\xe9\x4d", 4);
7461 pos += 4;
7462 break;
7463 default:
7464 return -1;
7465 }
7466
7467 /* CCMP MIC */
7468 memcpy(pos, "\xc8\xd8\x3b\x06\x5d\xb7\x25\x68", 8);
7469 pos += 8;
7470 } else {
7471 switch (frame) {
7472 case DEAUTH:
7473 /* reason code = 8 */
7474 *pos++ = 0x08;
7475 *pos++ = 0x00;
7476 break;
7477 case DISASSOC:
7478 /* reason code = 8 */
7479 *pos++ = 0x08;
7480 *pos++ = 0x00;
7481 break;
7482 case SAQUERY:
7483 /* Category - SA Query */
7484 *pos++ = 0x08;
7485 /* SA query Action - Request */
7486 *pos++ = 0x00;
7487 /* Transaction ID */
7488 *pos++ = 0x12;
7489 *pos++ = 0x34;
7490 break;
7491 case AUTH:
7492 /* Auth Alg (Open) */
7493 *pos++ = 0x00;
7494 *pos++ = 0x00;
7495 /* Seq# */
7496 *pos++ = 0x01;
7497 *pos++ = 0x00;
7498 /* Status code */
7499 *pos++ = 0x00;
7500 *pos++ = 0x00;
7501 break;
7502 case ASSOCREQ:
7503 /* Capability Information */
7504 *pos++ = 0x31;
7505 *pos++ = 0x04;
7506 /* Listen Interval */
7507 *pos++ = 0x0a;
7508 *pos++ = 0x00;
7509 /* SSID */
7510 *pos++ = 0x00;
7511 *pos++ = ssid_len;
7512 memcpy(pos, ssid, ssid_len);
7513 pos += ssid_len;
7514 /* Supported Rates */
7515 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
7516 10);
7517 pos += 10;
7518 /* Extended Supported Rates */
7519 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
7520 pos += 6;
7521 /* RSN */
7522 memcpy(pos, "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00"
7523 "\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x02\xc0"
7524 "\x00\x00\x00\x00\x0f\xac\x06", 28);
7525 pos += 28;
7526 break;
7527 case REASSOCREQ:
7528 /* Capability Information */
7529 *pos++ = 0x31;
7530 *pos++ = 0x04;
7531 /* Listen Interval */
7532 *pos++ = 0x0a;
7533 *pos++ = 0x00;
7534 /* Current AP */
7535 hwaddr_aton(bssid, pos);
7536 pos += 6;
7537 /* SSID */
7538 *pos++ = 0x00;
7539 *pos++ = ssid_len;
7540 memcpy(pos, ssid, ssid_len);
7541 pos += ssid_len;
7542 /* Supported Rates */
7543 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
7544 10);
7545 pos += 10;
7546 /* Extended Supported Rates */
7547 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
7548 pos += 6;
7549 /* RSN */
7550 memcpy(pos, "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00"
7551 "\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x02\xc0"
7552 "\x00\x00\x00\x00\x0f\xac\x06", 28);
7553 pos += 28;
7554 break;
7555 case DLS_REQ:
7556 /* Category - DLS */
7557 *pos++ = 0x02;
7558 /* DLS Action - Request */
7559 *pos++ = 0x00;
7560 /* Destination MACAddress */
7561 if (dest)
7562 hwaddr_aton(dest, pos);
7563 else
7564 memset(pos, 0, 6);
7565 pos += 6;
7566 /* Source MACAddress */
7567 hwaddr_aton(addr, pos);
7568 pos += 6;
7569 /* Capability Information */
7570 *pos++ = 0x10; /* Privacy */
7571 *pos++ = 0x06; /* QoS */
7572 /* DLS Timeout Value */
7573 *pos++ = 0x00;
7574 *pos++ = 0x01;
7575 /* Supported rates */
7576 *pos++ = 0x01;
7577 *pos++ = 0x08;
7578 *pos++ = 0x0c; /* 6 Mbps */
7579 *pos++ = 0x12; /* 9 Mbps */
7580 *pos++ = 0x18; /* 12 Mbps */
7581 *pos++ = 0x24; /* 18 Mbps */
7582 *pos++ = 0x30; /* 24 Mbps */
7583 *pos++ = 0x48; /* 36 Mbps */
7584 *pos++ = 0x60; /* 48 Mbps */
7585 *pos++ = 0x6c; /* 54 Mbps */
7586 /* TODO: Extended Supported Rates */
7587 /* TODO: HT Capabilities */
7588 break;
7589 }
7590 }
7591
7592 s = open_monitor("sigmadut");
7593 if (s < 0) {
7594 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
7595 "monitor socket");
7596 return 0;
7597 }
7598
7599 res = inject_frame(s, buf, pos - buf, protected == CORRECT_KEY);
7600 if (res < 0) {
7601 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
7602 "inject frame");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05307603 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007604 return 0;
7605 }
7606 if (res < pos - buf) {
7607 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Only partial "
7608 "frame sent");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05307609 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007610 return 0;
7611 }
7612
7613 close(s);
7614
7615 return 1;
7616#else /* __linux__ */
7617 send_resp(dut, conn, SIGMA_ERROR, "errorCode,sta_send_frame not "
7618 "yet supported");
7619 return 0;
7620#endif /* __linux__ */
7621}
7622
7623
7624static int cmd_sta_send_frame_tdls(struct sigma_dut *dut,
7625 struct sigma_conn *conn,
7626 struct sigma_cmd *cmd)
7627{
7628 const char *intf = get_param(cmd, "Interface");
7629 const char *sta, *val;
7630 unsigned char addr[ETH_ALEN];
7631 char buf[100];
7632
7633 sta = get_param(cmd, "peer");
7634 if (sta == NULL)
7635 sta = get_param(cmd, "station");
7636 if (sta == NULL) {
7637 send_resp(dut, conn, SIGMA_ERROR,
7638 "ErrorCode,Missing peer address");
7639 return 0;
7640 }
7641 if (hwaddr_aton(sta, addr) < 0) {
7642 send_resp(dut, conn, SIGMA_ERROR,
7643 "ErrorCode,Invalid peer address");
7644 return 0;
7645 }
7646
7647 val = get_param(cmd, "type");
7648 if (val == NULL)
7649 return -1;
7650
7651 if (strcasecmp(val, "DISCOVERY") == 0) {
7652 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", sta);
7653 if (wpa_command(intf, buf) < 0) {
7654 send_resp(dut, conn, SIGMA_ERROR,
7655 "ErrorCode,Failed to send TDLS discovery");
7656 return 0;
7657 }
7658 return 1;
7659 }
7660
7661 if (strcasecmp(val, "SETUP") == 0) {
7662 int status = 0, timeout = 0;
7663
7664 val = get_param(cmd, "Status");
7665 if (val)
7666 status = atoi(val);
7667
7668 val = get_param(cmd, "Timeout");
7669 if (val)
7670 timeout = atoi(val);
7671
7672 if (status != 0 && status != 37) {
7673 send_resp(dut, conn, SIGMA_ERROR,
7674 "ErrorCode,Unsupported status value");
7675 return 0;
7676 }
7677
7678 if (timeout != 0 && timeout != 301) {
7679 send_resp(dut, conn, SIGMA_ERROR,
7680 "ErrorCode,Unsupported timeout value");
7681 return 0;
7682 }
7683
7684 if (status && timeout) {
7685 send_resp(dut, conn, SIGMA_ERROR,
7686 "ErrorCode,Unsupported timeout+status "
7687 "combination");
7688 return 0;
7689 }
7690
7691 if (status == 37 &&
7692 wpa_command(intf, "SET tdls_testing 0x200")) {
7693 send_resp(dut, conn, SIGMA_ERROR,
7694 "ErrorCode,Failed to enable "
7695 "decline setup response test mode");
7696 return 0;
7697 }
7698
7699 if (timeout == 301) {
7700 int res;
7701 if (dut->no_tpk_expiration)
7702 res = wpa_command(intf,
7703 "SET tdls_testing 0x108");
7704 else
7705 res = wpa_command(intf,
7706 "SET tdls_testing 0x8");
7707 if (res) {
7708 send_resp(dut, conn, SIGMA_ERROR,
7709 "ErrorCode,Failed to set short TPK "
7710 "lifetime");
7711 return 0;
7712 }
7713 }
7714
7715 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", sta);
7716 if (wpa_command(intf, buf) < 0) {
7717 send_resp(dut, conn, SIGMA_ERROR,
7718 "ErrorCode,Failed to send TDLS setup");
7719 return 0;
7720 }
7721 return 1;
7722 }
7723
7724 if (strcasecmp(val, "TEARDOWN") == 0) {
7725 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", sta);
7726 if (wpa_command(intf, buf) < 0) {
7727 send_resp(dut, conn, SIGMA_ERROR,
7728 "ErrorCode,Failed to send TDLS teardown");
7729 return 0;
7730 }
7731 return 1;
7732 }
7733
7734 send_resp(dut, conn, SIGMA_ERROR,
7735 "ErrorCode,Unsupported TDLS frame");
7736 return 0;
7737}
7738
7739
7740static int sta_ap_known(const char *ifname, const char *bssid)
7741{
7742 char buf[4096];
7743
7744 snprintf(buf, sizeof(buf), "BSS %s", bssid);
7745 if (wpa_command_resp(ifname, buf, buf, sizeof(buf)) < 0)
7746 return 0;
7747 if (strncmp(buf, "id=", 3) != 0)
7748 return 0;
7749 return 1;
7750}
7751
7752
7753static int sta_scan_ap(struct sigma_dut *dut, const char *ifname,
7754 const char *bssid)
7755{
7756 int res;
7757 struct wpa_ctrl *ctrl;
7758 char buf[256];
7759
7760 if (sta_ap_known(ifname, bssid))
7761 return 0;
7762 sigma_dut_print(dut, DUT_MSG_DEBUG,
7763 "AP not in BSS table - start scan");
7764
7765 ctrl = open_wpa_mon(ifname);
7766 if (ctrl == NULL) {
7767 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
7768 "wpa_supplicant monitor connection");
7769 return -1;
7770 }
7771
7772 if (wpa_command(ifname, "SCAN") < 0) {
7773 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to start scan");
7774 wpa_ctrl_detach(ctrl);
7775 wpa_ctrl_close(ctrl);
7776 return -1;
7777 }
7778
7779 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
7780 buf, sizeof(buf));
7781
7782 wpa_ctrl_detach(ctrl);
7783 wpa_ctrl_close(ctrl);
7784
7785 if (res < 0) {
7786 sigma_dut_print(dut, DUT_MSG_INFO, "Scan did not complete");
7787 return -1;
7788 }
7789
7790 if (sta_ap_known(ifname, bssid))
7791 return 0;
7792 sigma_dut_print(dut, DUT_MSG_INFO, "AP not in BSS table");
7793 return -1;
7794}
7795
7796
7797static int cmd_sta_send_frame_hs2_neighadv(struct sigma_dut *dut,
7798 struct sigma_conn *conn,
7799 struct sigma_cmd *cmd,
7800 const char *intf)
7801{
7802 char buf[200];
7803
7804 snprintf(buf, sizeof(buf), "ndsend 2001:DB8::1 %s", intf);
7805 if (system(buf) != 0) {
7806 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Failed to run "
7807 "ndsend");
7808 return 0;
7809 }
7810
7811 return 1;
7812}
7813
7814
7815static int cmd_sta_send_frame_hs2_neighsolreq(struct sigma_dut *dut,
7816 struct sigma_conn *conn,
7817 struct sigma_cmd *cmd,
7818 const char *intf)
7819{
7820 char buf[200];
7821 const char *ip = get_param(cmd, "SenderIP");
7822
Peng Xu26b356d2017-10-04 17:58:16 -07007823 if (!ip)
7824 return 0;
7825
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007826 snprintf(buf, sizeof(buf), "ndisc6 -nm %s %s -r 4", ip, intf);
7827 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
7828 if (system(buf) == 0) {
7829 sigma_dut_print(dut, DUT_MSG_INFO,
7830 "Neighbor Solicitation got a response "
7831 "for %s@%s", ip, intf);
7832 }
7833
7834 return 1;
7835}
7836
7837
7838static int cmd_sta_send_frame_hs2_arpprobe(struct sigma_dut *dut,
7839 struct sigma_conn *conn,
7840 struct sigma_cmd *cmd,
7841 const char *ifname)
7842{
7843 char buf[200];
7844 const char *ip = get_param(cmd, "SenderIP");
7845
7846 if (ip == NULL) {
7847 send_resp(dut, conn, SIGMA_ERROR,
7848 "ErrorCode,Missing SenderIP parameter");
7849 return 0;
7850 }
7851 snprintf(buf, sizeof(buf), "arping -I %s -D %s -c 4", ifname, ip);
7852 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
7853 if (system(buf) != 0) {
7854 sigma_dut_print(dut, DUT_MSG_INFO, "arping DAD got a response "
7855 "for %s@%s", ip, ifname);
7856 }
7857
7858 return 1;
7859}
7860
7861
7862static int cmd_sta_send_frame_hs2_arpannounce(struct sigma_dut *dut,
7863 struct sigma_conn *conn,
7864 struct sigma_cmd *cmd,
7865 const char *ifname)
7866{
7867 char buf[200];
7868 char ip[16];
7869 int s;
Peng Xub3756882017-10-04 14:39:09 -07007870 struct ifreq ifr;
7871 struct sockaddr_in saddr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007872
7873 s = socket(PF_INET, SOCK_DGRAM, 0);
Peng Xub3756882017-10-04 14:39:09 -07007874 if (s < 0) {
7875 perror("socket");
7876 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007877 }
7878
Peng Xub3756882017-10-04 14:39:09 -07007879 memset(&ifr, 0, sizeof(ifr));
7880 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
7881 if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
7882 sigma_dut_print(dut, DUT_MSG_INFO,
7883 "Failed to get %s IP address: %s",
7884 ifname, strerror(errno));
7885 close(s);
7886 return -1;
7887 }
7888 close(s);
7889
7890 memcpy(&saddr, &ifr.ifr_addr, sizeof(struct sockaddr_in));
7891 strlcpy(ip, inet_ntoa(saddr.sin_addr), sizeof(ip));
7892
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007893 snprintf(buf, sizeof(buf), "arping -I %s -s %s %s -c 4", ifname, ip,
7894 ip);
7895 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
7896 if (system(buf) != 0) {
7897 }
7898
7899 return 1;
7900}
7901
7902
7903static int cmd_sta_send_frame_hs2_arpreply(struct sigma_dut *dut,
7904 struct sigma_conn *conn,
7905 struct sigma_cmd *cmd,
7906 const char *ifname)
7907{
7908 char buf[200], addr[20];
7909 char dst[ETH_ALEN], src[ETH_ALEN];
7910 short ethtype = htons(ETH_P_ARP);
7911 char *pos;
7912 int s, res;
7913 const char *val;
7914 struct sockaddr_in taddr;
7915
7916 val = get_param(cmd, "dest");
7917 if (val)
7918 hwaddr_aton(val, (unsigned char *) dst);
7919
7920 val = get_param(cmd, "DestIP");
7921 if (val)
7922 inet_aton(val, &taddr.sin_addr);
Peng Xu151c9e12017-10-04 14:39:09 -07007923 else
7924 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007925
7926 if (get_wpa_status(get_station_ifname(), "address", addr,
7927 sizeof(addr)) < 0)
7928 return -2;
7929 hwaddr_aton(addr, (unsigned char *) src);
7930
7931 pos = buf;
7932 *pos++ = 0x00;
7933 *pos++ = 0x01;
7934 *pos++ = 0x08;
7935 *pos++ = 0x00;
7936 *pos++ = 0x06;
7937 *pos++ = 0x04;
7938 *pos++ = 0x00;
7939 *pos++ = 0x02;
7940 memcpy(pos, src, ETH_ALEN);
7941 pos += ETH_ALEN;
7942 memcpy(pos, &taddr.sin_addr, 4);
7943 pos += 4;
7944 memcpy(pos, dst, ETH_ALEN);
7945 pos += ETH_ALEN;
7946 memcpy(pos, &taddr.sin_addr, 4);
7947 pos += 4;
7948
7949 s = open_monitor(get_station_ifname());
7950 if (s < 0) {
7951 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
7952 "monitor socket");
7953 return 0;
7954 }
7955
7956 res = inject_eth_frame(s, buf, pos - buf, ethtype, dst, src);
7957 if (res < 0) {
7958 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
7959 "inject frame");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05307960 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007961 return 0;
7962 }
7963
7964 close(s);
7965
7966 return 1;
7967}
7968
7969
7970static int cmd_sta_send_frame_hs2_dls_req(struct sigma_dut *dut,
7971 struct sigma_conn *conn,
7972 struct sigma_cmd *cmd,
7973 const char *intf, const char *dest)
7974{
7975 char buf[100];
7976
7977 if (if_nametoindex("sigmadut") == 0) {
7978 snprintf(buf, sizeof(buf),
7979 "iw dev %s interface add sigmadut type monitor",
7980 get_station_ifname());
7981 if (system(buf) != 0 ||
7982 if_nametoindex("sigmadut") == 0) {
7983 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
7984 "monitor interface with '%s'", buf);
7985 return -2;
7986 }
7987 }
7988
7989 if (system("ifconfig sigmadut up") != 0) {
7990 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
7991 "monitor interface up");
7992 return -2;
7993 }
7994
7995 return sta_inject_frame(dut, conn, DLS_REQ, UNPROTECTED, dest);
7996}
7997
7998
7999static int cmd_sta_send_frame_hs2(struct sigma_dut *dut,
8000 struct sigma_conn *conn,
8001 struct sigma_cmd *cmd)
8002{
8003 const char *intf = get_param(cmd, "Interface");
8004 const char *dest = get_param(cmd, "Dest");
8005 const char *type = get_param(cmd, "FrameName");
8006 const char *val;
8007 char buf[200], *pos, *end;
8008 int count, count2;
8009
8010 if (type == NULL)
8011 type = get_param(cmd, "Type");
8012
8013 if (intf == NULL || dest == NULL || type == NULL)
8014 return -1;
8015
8016 if (strcasecmp(type, "NeighAdv") == 0)
8017 return cmd_sta_send_frame_hs2_neighadv(dut, conn, cmd, intf);
8018
8019 if (strcasecmp(type, "NeighSolicitReq") == 0)
8020 return cmd_sta_send_frame_hs2_neighsolreq(dut, conn, cmd, intf);
8021
8022 if (strcasecmp(type, "ARPProbe") == 0)
8023 return cmd_sta_send_frame_hs2_arpprobe(dut, conn, cmd, intf);
8024
8025 if (strcasecmp(type, "ARPAnnounce") == 0)
8026 return cmd_sta_send_frame_hs2_arpannounce(dut, conn, cmd, intf);
8027
8028 if (strcasecmp(type, "ARPReply") == 0)
8029 return cmd_sta_send_frame_hs2_arpreply(dut, conn, cmd, intf);
8030
8031 if (strcasecmp(type, "DLS-request") == 0 ||
8032 strcasecmp(type, "DLSrequest") == 0)
8033 return cmd_sta_send_frame_hs2_dls_req(dut, conn, cmd, intf,
8034 dest);
8035
8036 if (strcasecmp(type, "ANQPQuery") != 0 &&
8037 strcasecmp(type, "Query") != 0) {
8038 send_resp(dut, conn, SIGMA_ERROR,
8039 "ErrorCode,Unsupported HS 2.0 send frame type");
8040 return 0;
8041 }
8042
8043 if (sta_scan_ap(dut, intf, dest) < 0) {
8044 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not find "
8045 "the requested AP");
8046 return 0;
8047 }
8048
8049 pos = buf;
8050 end = buf + sizeof(buf);
8051 count = 0;
8052 pos += snprintf(pos, end - pos, "ANQP_GET %s ", dest);
8053
8054 val = get_param(cmd, "ANQP_CAP_LIST");
8055 if (val && atoi(val)) {
8056 pos += snprintf(pos, end - pos, "%s257", count > 0 ? "," : "");
8057 count++;
8058 }
8059
8060 val = get_param(cmd, "VENUE_NAME");
8061 if (val && atoi(val)) {
8062 pos += snprintf(pos, end - pos, "%s258", count > 0 ? "," : "");
8063 count++;
8064 }
8065
8066 val = get_param(cmd, "NETWORK_AUTH_TYPE");
8067 if (val && atoi(val)) {
8068 pos += snprintf(pos, end - pos, "%s260", count > 0 ? "," : "");
8069 count++;
8070 }
8071
8072 val = get_param(cmd, "ROAMING_CONS");
8073 if (val && atoi(val)) {
8074 pos += snprintf(pos, end - pos, "%s261", count > 0 ? "," : "");
8075 count++;
8076 }
8077
8078 val = get_param(cmd, "IP_ADDR_TYPE_AVAILABILITY");
8079 if (val && atoi(val)) {
8080 pos += snprintf(pos, end - pos, "%s262", count > 0 ? "," : "");
8081 count++;
8082 }
8083
8084 val = get_param(cmd, "NAI_REALM_LIST");
8085 if (val && atoi(val)) {
8086 pos += snprintf(pos, end - pos, "%s263", count > 0 ? "," : "");
8087 count++;
8088 }
8089
8090 val = get_param(cmd, "3GPP_INFO");
8091 if (val && atoi(val)) {
8092 pos += snprintf(pos, end - pos, "%s264", count > 0 ? "," : "");
8093 count++;
8094 }
8095
8096 val = get_param(cmd, "DOMAIN_LIST");
8097 if (val && atoi(val)) {
8098 pos += snprintf(pos, end - pos, "%s268", count > 0 ? "," : "");
8099 count++;
8100 }
8101
Jouni Malinen34cf9532018-04-29 19:26:33 +03008102 val = get_param(cmd, "Venue_URL");
8103 if (val && atoi(val)) {
8104 pos += snprintf(pos, end - pos, "%s277", count > 0 ? "," : "");
8105 count++;
8106 }
8107
Jouni Malinend3bca5d2018-04-29 17:25:23 +03008108 val = get_param(cmd, "Advice_Of_Charge");
8109 if (val && atoi(val)) {
8110 pos += snprintf(pos, end - pos, "%s278", count > 0 ? "," : "");
8111 count++;
8112 }
8113
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008114 if (count && wpa_command(intf, buf)) {
8115 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,ANQP_GET failed");
8116 return 0;
8117 }
8118
8119 pos = buf;
8120 end = buf + sizeof(buf);
8121 count2 = 0;
8122 pos += snprintf(pos, end - pos, "HS20_ANQP_GET %s ", dest);
8123
8124 val = get_param(cmd, "HS_CAP_LIST");
8125 if (val && atoi(val)) {
8126 pos += snprintf(pos, end - pos, "%s2", count2 > 0 ? "," : "");
8127 count2++;
8128 }
8129
8130 val = get_param(cmd, "OPER_NAME");
8131 if (val && atoi(val)) {
8132 pos += snprintf(pos, end - pos, "%s3", count2 > 0 ? "," : "");
8133 count2++;
8134 }
8135
8136 val = get_param(cmd, "WAN_METRICS");
8137 if (!val)
8138 val = get_param(cmd, "WAN_MAT");
8139 if (!val)
8140 val = get_param(cmd, "WAN_MET");
8141 if (val && atoi(val)) {
8142 pos += snprintf(pos, end - pos, "%s4", count2 > 0 ? "," : "");
8143 count2++;
8144 }
8145
8146 val = get_param(cmd, "CONNECTION_CAPABILITY");
8147 if (val && atoi(val)) {
8148 pos += snprintf(pos, end - pos, "%s5", count2 > 0 ? "," : "");
8149 count2++;
8150 }
8151
8152 val = get_param(cmd, "OP_CLASS");
8153 if (val && atoi(val)) {
8154 pos += snprintf(pos, end - pos, "%s7", count2 > 0 ? "," : "");
8155 count2++;
8156 }
8157
8158 val = get_param(cmd, "OSU_PROVIDER_LIST");
8159 if (val && atoi(val)) {
8160 pos += snprintf(pos, end - pos, "%s8", count2 > 0 ? "," : "");
8161 count2++;
8162 }
8163
Jouni Malinenf67afec2018-04-29 19:24:58 +03008164 val = get_param(cmd, "OPER_ICON_METADATA");
8165 if (!val)
8166 val = get_param(cmd, "OPERATOR_ICON_METADATA");
8167 if (val && atoi(val)) {
8168 pos += snprintf(pos, end - pos, "%s12", count2 > 0 ? "," : "");
8169 count2++;
8170 }
8171
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008172 if (count && count2) {
8173 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before sending out "
8174 "second query");
8175 sleep(1);
8176 }
8177
8178 if (count2 && wpa_command(intf, buf)) {
8179 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,HS20_ANQP_GET "
8180 "failed");
8181 return 0;
8182 }
8183
8184 val = get_param(cmd, "NAI_HOME_REALM_LIST");
8185 if (val) {
8186 if (count || count2) {
8187 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
8188 "sending out second query");
8189 sleep(1);
8190 }
8191
8192 if (strcmp(val, "1") == 0)
8193 val = "mail.example.com";
8194 snprintf(buf, end - pos,
8195 "HS20_GET_NAI_HOME_REALM_LIST %s realm=%s",
8196 dest, val);
8197 if (wpa_command(intf, buf)) {
8198 send_resp(dut, conn, SIGMA_ERROR,
8199 "ErrorCode,HS20_GET_NAI_HOME_REALM_LIST "
8200 "failed");
8201 return 0;
8202 }
8203 }
8204
8205 val = get_param(cmd, "ICON_REQUEST");
8206 if (val) {
8207 if (count || count2) {
8208 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
8209 "sending out second query");
8210 sleep(1);
8211 }
8212
8213 snprintf(buf, end - pos,
8214 "HS20_ICON_REQUEST %s %s", dest, val);
8215 if (wpa_command(intf, buf)) {
8216 send_resp(dut, conn, SIGMA_ERROR,
8217 "ErrorCode,HS20_ICON_REQUEST failed");
8218 return 0;
8219 }
8220 }
8221
8222 return 1;
8223}
8224
8225
8226static int ath_sta_send_frame_vht(struct sigma_dut *dut,
8227 struct sigma_conn *conn,
8228 struct sigma_cmd *cmd)
8229{
8230 const char *val;
8231 char *ifname;
8232 char buf[100];
8233 int chwidth, nss;
8234
8235 val = get_param(cmd, "framename");
8236 if (!val)
8237 return -1;
8238 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
8239
8240 /* Command sequence to generate Op mode notification */
8241 if (val && strcasecmp(val, "Op_md_notif_frm") == 0) {
8242 ifname = get_station_ifname();
8243
8244 /* Disable STBC */
8245 snprintf(buf, sizeof(buf),
8246 "iwpriv %s tx_stbc 0", ifname);
8247 if (system(buf) != 0) {
8248 sigma_dut_print(dut, DUT_MSG_ERROR,
8249 "iwpriv tx_stbc 0 failed!");
8250 }
8251
8252 /* Extract Channel width */
8253 val = get_param(cmd, "Channel_width");
8254 if (val) {
8255 switch (atoi(val)) {
8256 case 20:
8257 chwidth = 0;
8258 break;
8259 case 40:
8260 chwidth = 1;
8261 break;
8262 case 80:
8263 chwidth = 2;
8264 break;
8265 case 160:
8266 chwidth = 3;
8267 break;
8268 default:
8269 chwidth = 2;
8270 break;
8271 }
8272
8273 snprintf(buf, sizeof(buf), "iwpriv %s chwidth %d",
8274 ifname, chwidth);
8275 if (system(buf) != 0) {
8276 sigma_dut_print(dut, DUT_MSG_ERROR,
8277 "iwpriv chwidth failed!");
8278 }
8279 }
8280
8281 /* Extract NSS */
8282 val = get_param(cmd, "NSS");
8283 if (val) {
8284 switch (atoi(val)) {
8285 case 1:
8286 nss = 1;
8287 break;
8288 case 2:
8289 nss = 3;
8290 break;
8291 case 3:
8292 nss = 7;
8293 break;
8294 default:
8295 /* We do not support NSS > 3 */
8296 nss = 3;
8297 break;
8298 }
8299 snprintf(buf, sizeof(buf),
8300 "iwpriv %s rxchainmask %d", ifname, nss);
8301 if (system(buf) != 0) {
8302 sigma_dut_print(dut, DUT_MSG_ERROR,
8303 "iwpriv rxchainmask failed!");
8304 }
8305 }
8306
8307 /* Opmode notify */
8308 snprintf(buf, sizeof(buf), "iwpriv %s opmode_notify 1", ifname);
8309 if (system(buf) != 0) {
8310 sigma_dut_print(dut, DUT_MSG_ERROR,
8311 "iwpriv opmode_notify failed!");
8312 } else {
8313 sigma_dut_print(dut, DUT_MSG_INFO,
8314 "Sent out the notify frame!");
8315 }
8316 }
8317
8318 return 1;
8319}
8320
8321
8322static int cmd_sta_send_frame_vht(struct sigma_dut *dut,
8323 struct sigma_conn *conn,
8324 struct sigma_cmd *cmd)
8325{
8326 switch (get_driver_type()) {
8327 case DRIVER_ATHEROS:
8328 return ath_sta_send_frame_vht(dut, conn, cmd);
8329 default:
8330 send_resp(dut, conn, SIGMA_ERROR,
8331 "errorCode,Unsupported sta_set_frame(VHT) with the current driver");
8332 return 0;
8333 }
8334}
8335
8336
Lior David0fe101e2017-03-09 16:09:50 +02008337#ifdef __linux__
8338int wil6210_send_frame_60g(struct sigma_dut *dut, struct sigma_conn *conn,
8339 struct sigma_cmd *cmd)
8340{
8341 const char *frame_name = get_param(cmd, "framename");
8342 const char *mac = get_param(cmd, "dest_mac");
8343
8344 if (!frame_name || !mac) {
8345 sigma_dut_print(dut, DUT_MSG_ERROR,
8346 "framename and dest_mac must be provided");
8347 return -1;
8348 }
8349
8350 if (strcasecmp(frame_name, "brp") == 0) {
8351 const char *l_rx = get_param(cmd, "L-RX");
8352 int l_rx_i;
8353
8354 if (!l_rx) {
8355 sigma_dut_print(dut, DUT_MSG_ERROR,
8356 "L-RX must be provided");
8357 return -1;
8358 }
8359 l_rx_i = atoi(l_rx);
8360
8361 sigma_dut_print(dut, DUT_MSG_INFO,
8362 "dev_send_frame: BRP-RX, dest_mac %s, L-RX %s",
8363 mac, l_rx);
8364 if (l_rx_i != 16) {
8365 sigma_dut_print(dut, DUT_MSG_ERROR,
8366 "unsupported L-RX: %s", l_rx);
8367 return -1;
8368 }
8369
8370 if (wil6210_send_brp_rx(dut, mac, l_rx_i))
8371 return -1;
8372 } else if (strcasecmp(frame_name, "ssw") == 0) {
8373 sigma_dut_print(dut, DUT_MSG_INFO,
8374 "dev_send_frame: SLS, dest_mac %s", mac);
8375 if (wil6210_send_sls(dut, mac))
8376 return -1;
8377 } else {
8378 sigma_dut_print(dut, DUT_MSG_ERROR,
8379 "unsupported frame type: %s", frame_name);
8380 return -1;
8381 }
8382
8383 return 1;
8384}
8385#endif /* __linux__ */
8386
8387
8388static int cmd_sta_send_frame_60g(struct sigma_dut *dut,
8389 struct sigma_conn *conn,
8390 struct sigma_cmd *cmd)
8391{
8392 switch (get_driver_type()) {
8393#ifdef __linux__
8394 case DRIVER_WIL6210:
8395 return wil6210_send_frame_60g(dut, conn, cmd);
8396#endif /* __linux__ */
8397 default:
8398 send_resp(dut, conn, SIGMA_ERROR,
8399 "errorCode,Unsupported sta_set_frame(60G) with the current driver");
8400 return 0;
8401 }
8402}
8403
8404
Ashwini Patildb59b3c2017-04-13 15:19:23 +05308405static int mbo_send_anqp_query(struct sigma_dut *dut, struct sigma_conn *conn,
8406 const char *intf, struct sigma_cmd *cmd)
8407{
8408 const char *val, *addr;
8409 char buf[100];
8410
8411 addr = get_param(cmd, "DestMac");
8412 if (!addr) {
8413 send_resp(dut, conn, SIGMA_INVALID,
8414 "ErrorCode,AP MAC address is missing");
8415 return 0;
8416 }
8417
8418 val = get_param(cmd, "ANQPQuery_ID");
8419 if (!val) {
8420 send_resp(dut, conn, SIGMA_INVALID,
8421 "ErrorCode,Missing ANQPQuery_ID");
8422 return 0;
8423 }
8424
8425 if (strcasecmp(val, "NeighborReportReq") == 0) {
8426 snprintf(buf, sizeof(buf), "ANQP_GET %s 272", addr);
8427 } else if (strcasecmp(val, "QueryListWithCellPref") == 0) {
8428 snprintf(buf, sizeof(buf), "ANQP_GET %s 272,mbo:2", addr);
8429 } else {
8430 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid ANQPQuery_ID: %s",
8431 val);
8432 send_resp(dut, conn, SIGMA_INVALID,
8433 "ErrorCode,Invalid ANQPQuery_ID");
8434 return 0;
8435 }
8436
Ashwini Patild174f2c2017-04-13 16:49:46 +05308437 /* Set gas_address3 field to IEEE 802.11-2012 standard compliant form
8438 * (Address3 = Wildcard BSSID when sent to not-associated AP;
8439 * if associated, AP BSSID).
8440 */
8441 if (wpa_command(intf, "SET gas_address3 1") < 0) {
8442 send_resp(dut, conn, SIGMA_ERROR,
8443 "ErrorCode,Failed to set gas_address3");
8444 return 0;
8445 }
8446
Ashwini Patildb59b3c2017-04-13 15:19:23 +05308447 if (wpa_command(intf, buf) < 0) {
8448 send_resp(dut, conn, SIGMA_ERROR,
8449 "ErrorCode,Failed to send ANQP query");
8450 return 0;
8451 }
8452
8453 return 1;
8454}
8455
8456
8457static int mbo_cmd_sta_send_frame(struct sigma_dut *dut,
8458 struct sigma_conn *conn,
8459 const char *intf,
8460 struct sigma_cmd *cmd)
8461{
8462 const char *val = get_param(cmd, "FrameName");
8463
8464 if (val && strcasecmp(val, "ANQPQuery") == 0)
8465 return mbo_send_anqp_query(dut, conn, intf, cmd);
8466
8467 return 2;
8468}
8469
8470
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008471int cmd_sta_send_frame(struct sigma_dut *dut, struct sigma_conn *conn,
8472 struct sigma_cmd *cmd)
8473{
8474 const char *intf = get_param(cmd, "Interface");
8475 const char *val;
8476 enum send_frame_type frame;
8477 enum send_frame_protection protected;
8478 char buf[100];
8479 unsigned char addr[ETH_ALEN];
8480 int res;
8481
8482 val = get_param(cmd, "program");
8483 if (val == NULL)
8484 val = get_param(cmd, "frame");
8485 if (val && strcasecmp(val, "TDLS") == 0)
8486 return cmd_sta_send_frame_tdls(dut, conn, cmd);
8487 if (val && (strcasecmp(val, "HS2") == 0 ||
8488 strcasecmp(val, "HS2-R2") == 0))
8489 return cmd_sta_send_frame_hs2(dut, conn, cmd);
8490 if (val && strcasecmp(val, "VHT") == 0)
8491 return cmd_sta_send_frame_vht(dut, conn, cmd);
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07008492 if (val && strcasecmp(val, "LOC") == 0)
8493 return loc_cmd_sta_send_frame(dut, conn, cmd);
Lior David0fe101e2017-03-09 16:09:50 +02008494 if (val && strcasecmp(val, "60GHz") == 0)
8495 return cmd_sta_send_frame_60g(dut, conn, cmd);
Ashwini Patildb59b3c2017-04-13 15:19:23 +05308496 if (val && strcasecmp(val, "MBO") == 0) {
8497 res = mbo_cmd_sta_send_frame(dut, conn, intf, cmd);
8498 if (res != 2)
8499 return res;
8500 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008501
8502 val = get_param(cmd, "TD_DISC");
8503 if (val) {
8504 if (hwaddr_aton(val, addr) < 0)
8505 return -1;
8506 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", val);
8507 if (wpa_command(intf, buf) < 0) {
8508 send_resp(dut, conn, SIGMA_ERROR,
8509 "ErrorCode,Failed to send TDLS discovery");
8510 return 0;
8511 }
8512 return 1;
8513 }
8514
8515 val = get_param(cmd, "TD_Setup");
8516 if (val) {
8517 if (hwaddr_aton(val, addr) < 0)
8518 return -1;
8519 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", val);
8520 if (wpa_command(intf, buf) < 0) {
8521 send_resp(dut, conn, SIGMA_ERROR,
8522 "ErrorCode,Failed to start TDLS setup");
8523 return 0;
8524 }
8525 return 1;
8526 }
8527
8528 val = get_param(cmd, "TD_TearDown");
8529 if (val) {
8530 if (hwaddr_aton(val, addr) < 0)
8531 return -1;
8532 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", val);
8533 if (wpa_command(intf, buf) < 0) {
8534 send_resp(dut, conn, SIGMA_ERROR,
8535 "ErrorCode,Failed to tear down TDLS link");
8536 return 0;
8537 }
8538 return 1;
8539 }
8540
8541 val = get_param(cmd, "TD_ChannelSwitch");
8542 if (val) {
8543 /* TODO */
8544 send_resp(dut, conn, SIGMA_ERROR,
8545 "ErrorCode,TD_ChannelSwitch not yet supported");
8546 return 0;
8547 }
8548
8549 val = get_param(cmd, "TD_NF");
8550 if (val) {
8551 /* TODO */
8552 send_resp(dut, conn, SIGMA_ERROR,
8553 "ErrorCode,TD_NF not yet supported");
8554 return 0;
8555 }
8556
8557 val = get_param(cmd, "PMFFrameType");
8558 if (val == NULL)
8559 val = get_param(cmd, "FrameName");
8560 if (val == NULL)
8561 val = get_param(cmd, "Type");
8562 if (val == NULL)
8563 return -1;
8564 if (strcasecmp(val, "disassoc") == 0)
8565 frame = DISASSOC;
8566 else if (strcasecmp(val, "deauth") == 0)
8567 frame = DEAUTH;
8568 else if (strcasecmp(val, "saquery") == 0)
8569 frame = SAQUERY;
8570 else if (strcasecmp(val, "auth") == 0)
8571 frame = AUTH;
8572 else if (strcasecmp(val, "assocreq") == 0)
8573 frame = ASSOCREQ;
8574 else if (strcasecmp(val, "reassocreq") == 0)
8575 frame = REASSOCREQ;
8576 else if (strcasecmp(val, "neigreq") == 0) {
8577 sigma_dut_print(dut, DUT_MSG_INFO, "Got neighbor request");
8578
8579 val = get_param(cmd, "ssid");
8580 if (val == NULL)
8581 return -1;
8582
8583 res = send_neighbor_request(dut, intf, val);
8584 if (res) {
8585 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
8586 "Failed to send neighbor report request");
8587 return 0;
8588 }
8589
8590 return 1;
Ashwini Patil5acd7382017-04-13 15:55:04 +05308591 } else if (strcasecmp(val, "transmgmtquery") == 0 ||
8592 strcasecmp(val, "BTMQuery") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008593 sigma_dut_print(dut, DUT_MSG_DEBUG,
8594 "Got Transition Management Query");
8595
Ashwini Patil5acd7382017-04-13 15:55:04 +05308596 res = send_trans_mgmt_query(dut, intf, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008597 if (res) {
8598 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
8599 "Failed to send Transition Management Query");
8600 return 0;
8601 }
8602
8603 return 1;
8604 } else {
8605 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
8606 "PMFFrameType");
8607 return 0;
8608 }
8609
8610 val = get_param(cmd, "PMFProtected");
8611 if (val == NULL)
8612 val = get_param(cmd, "Protected");
8613 if (val == NULL)
8614 return -1;
8615 if (strcasecmp(val, "Correct-key") == 0 ||
8616 strcasecmp(val, "CorrectKey") == 0)
8617 protected = CORRECT_KEY;
8618 else if (strcasecmp(val, "IncorrectKey") == 0)
8619 protected = INCORRECT_KEY;
8620 else if (strcasecmp(val, "Unprotected") == 0)
8621 protected = UNPROTECTED;
8622 else {
8623 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
8624 "PMFProtected");
8625 return 0;
8626 }
8627
8628 if (protected != UNPROTECTED &&
8629 (frame == AUTH || frame == ASSOCREQ || frame == REASSOCREQ)) {
8630 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Impossible "
8631 "PMFProtected for auth/assocreq/reassocreq");
8632 return 0;
8633 }
8634
8635 if (if_nametoindex("sigmadut") == 0) {
8636 snprintf(buf, sizeof(buf),
8637 "iw dev %s interface add sigmadut type monitor",
8638 get_station_ifname());
8639 if (system(buf) != 0 ||
8640 if_nametoindex("sigmadut") == 0) {
8641 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
8642 "monitor interface with '%s'", buf);
8643 return -2;
8644 }
8645 }
8646
8647 if (system("ifconfig sigmadut up") != 0) {
8648 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
8649 "monitor interface up");
8650 return -2;
8651 }
8652
8653 return sta_inject_frame(dut, conn, frame, protected, NULL);
8654}
8655
8656
8657static int cmd_sta_set_parameter_hs2(struct sigma_dut *dut,
8658 struct sigma_conn *conn,
8659 struct sigma_cmd *cmd,
8660 const char *ifname)
8661{
8662 char buf[200];
8663 const char *val;
8664
8665 val = get_param(cmd, "ClearARP");
8666 if (val && atoi(val) == 1) {
8667 snprintf(buf, sizeof(buf), "ip neigh flush dev %s", ifname);
8668 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
8669 if (system(buf) != 0) {
8670 send_resp(dut, conn, SIGMA_ERROR,
8671 "errorCode,Failed to clear ARP cache");
8672 return 0;
8673 }
8674 }
8675
8676 return 1;
8677}
8678
8679
8680int cmd_sta_set_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
8681 struct sigma_cmd *cmd)
8682{
8683 const char *intf = get_param(cmd, "Interface");
8684 const char *val;
8685
8686 if (intf == NULL)
8687 return -1;
8688
8689 val = get_param(cmd, "program");
8690 if (val && (strcasecmp(val, "HS2") == 0 ||
8691 strcasecmp(val, "HS2-R2") == 0))
8692 return cmd_sta_set_parameter_hs2(dut, conn, cmd, intf);
8693
8694 return -1;
8695}
8696
8697
8698static int cmd_sta_set_macaddr(struct sigma_dut *dut, struct sigma_conn *conn,
8699 struct sigma_cmd *cmd)
8700{
8701 const char *intf = get_param(cmd, "Interface");
8702 const char *mac = get_param(cmd, "MAC");
8703
8704 if (intf == NULL || mac == NULL)
8705 return -1;
8706
8707 sigma_dut_print(dut, DUT_MSG_INFO, "Change local MAC address for "
8708 "interface %s to %s", intf, mac);
8709
8710 if (dut->set_macaddr) {
8711 char buf[128];
8712 int res;
8713 if (strcasecmp(mac, "default") == 0) {
8714 res = snprintf(buf, sizeof(buf), "%s",
8715 dut->set_macaddr);
8716 dut->tmp_mac_addr = 0;
8717 } else {
8718 res = snprintf(buf, sizeof(buf), "%s %s",
8719 dut->set_macaddr, mac);
8720 dut->tmp_mac_addr = 1;
8721 }
8722 if (res < 0 || res >= (int) sizeof(buf))
8723 return -1;
8724 if (system(buf) != 0) {
8725 send_resp(dut, conn, SIGMA_ERROR,
8726 "errorCode,Failed to set MAC "
8727 "address");
8728 return 0;
8729 }
8730 return 1;
8731 }
8732
8733 if (strcasecmp(mac, "default") == 0)
8734 return 1;
8735
8736 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
8737 "command");
8738 return 0;
8739}
8740
8741
8742static int iwpriv_tdlsoffchnmode(struct sigma_dut *dut,
8743 struct sigma_conn *conn, const char *intf,
8744 int val)
8745{
8746 char buf[200];
8747 int res;
8748
8749 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchnmode %d",
8750 intf, val);
8751 if (res < 0 || res >= (int) sizeof(buf))
8752 return -1;
8753 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
8754 if (system(buf) != 0) {
8755 send_resp(dut, conn, SIGMA_ERROR,
8756 "errorCode,Failed to configure offchannel mode");
8757 return 0;
8758 }
8759
8760 return 1;
8761}
8762
8763
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008764static int off_chan_val(enum sec_ch_offset off)
8765{
8766 switch (off) {
8767 case SEC_CH_NO:
8768 return 0;
8769 case SEC_CH_40ABOVE:
8770 return 40;
8771 case SEC_CH_40BELOW:
8772 return -40;
8773 }
8774
8775 return 0;
8776}
8777
8778
8779static int iwpriv_set_offchan(struct sigma_dut *dut, struct sigma_conn *conn,
8780 const char *intf, int off_ch_num,
8781 enum sec_ch_offset sec)
8782{
8783 char buf[200];
8784 int res;
8785
8786 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchan %d",
8787 intf, off_ch_num);
8788 if (res < 0 || res >= (int) sizeof(buf))
8789 return -1;
8790 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
8791 if (system(buf) != 0) {
8792 send_resp(dut, conn, SIGMA_ERROR,
8793 "errorCode,Failed to set offchan");
8794 return 0;
8795 }
8796
8797 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsecchnoffst %d",
8798 intf, off_chan_val(sec));
8799 if (res < 0 || res >= (int) sizeof(buf))
8800 return -1;
8801 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
8802 if (system(buf) != 0) {
8803 send_resp(dut, conn, SIGMA_ERROR,
8804 "errorCode,Failed to set sec chan offset");
8805 return 0;
8806 }
8807
8808 return 1;
8809}
8810
8811
8812static int tdls_set_offchannel_offset(struct sigma_dut *dut,
8813 struct sigma_conn *conn,
8814 const char *intf, int off_ch_num,
8815 enum sec_ch_offset sec)
8816{
8817 char buf[200];
8818 int res;
8819
8820 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNEL %d",
8821 off_ch_num);
8822 if (res < 0 || res >= (int) sizeof(buf))
8823 return -1;
8824 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
8825
8826 if (wpa_command(intf, buf) < 0) {
8827 send_resp(dut, conn, SIGMA_ERROR,
8828 "ErrorCode,Failed to set offchan");
8829 return 0;
8830 }
8831 res = snprintf(buf, sizeof(buf), "DRIVER TDLSSECONDARYCHANNELOFFSET %d",
8832 off_chan_val(sec));
8833 if (res < 0 || res >= (int) sizeof(buf))
8834 return -1;
8835
8836 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
8837
8838 if (wpa_command(intf, buf) < 0) {
8839 send_resp(dut, conn, SIGMA_ERROR,
8840 "ErrorCode,Failed to set sec chan offset");
8841 return 0;
8842 }
8843
8844 return 1;
8845}
8846
8847
8848static int tdls_set_offchannel_mode(struct sigma_dut *dut,
8849 struct sigma_conn *conn,
8850 const char *intf, int val)
8851{
8852 char buf[200];
8853 int res;
8854
8855 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNELMODE %d",
8856 val);
8857 if (res < 0 || res >= (int) sizeof(buf))
8858 return -1;
8859 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
8860
8861 if (wpa_command(intf, buf) < 0) {
8862 send_resp(dut, conn, SIGMA_ERROR,
8863 "ErrorCode,Failed to configure offchannel mode");
8864 return 0;
8865 }
8866
8867 return 1;
8868}
8869
8870
8871static int cmd_sta_set_rfeature_tdls(const char *intf, struct sigma_dut *dut,
8872 struct sigma_conn *conn,
8873 struct sigma_cmd *cmd)
8874{
8875 const char *val;
8876 enum {
8877 CHSM_NOT_SET,
8878 CHSM_ENABLE,
8879 CHSM_DISABLE,
8880 CHSM_REJREQ,
8881 CHSM_UNSOLRESP
8882 } chsm = CHSM_NOT_SET;
8883 int off_ch_num = -1;
8884 enum sec_ch_offset sec_ch = SEC_CH_NO;
8885 int res;
8886
8887 val = get_param(cmd, "Uapsd");
8888 if (val) {
8889 char buf[100];
8890 if (strcasecmp(val, "Enable") == 0)
8891 snprintf(buf, sizeof(buf), "SET ps 99");
8892 else if (strcasecmp(val, "Disable") == 0)
8893 snprintf(buf, sizeof(buf), "SET ps 98");
8894 else {
8895 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
8896 "Unsupported uapsd parameter value");
8897 return 0;
8898 }
8899 if (wpa_command(intf, buf)) {
8900 send_resp(dut, conn, SIGMA_ERROR,
8901 "ErrorCode,Failed to change U-APSD "
8902 "powersave mode");
8903 return 0;
8904 }
8905 }
8906
8907 val = get_param(cmd, "TPKTIMER");
8908 if (val && strcasecmp(val, "DISABLE") == 0) {
8909 if (wpa_command(intf, "SET tdls_testing 0x100")) {
8910 send_resp(dut, conn, SIGMA_ERROR,
8911 "ErrorCode,Failed to enable no TPK "
8912 "expiration test mode");
8913 return 0;
8914 }
8915 dut->no_tpk_expiration = 1;
8916 }
8917
8918 val = get_param(cmd, "ChSwitchMode");
8919 if (val) {
8920 if (strcasecmp(val, "Enable") == 0 ||
8921 strcasecmp(val, "Initiate") == 0)
8922 chsm = CHSM_ENABLE;
8923 else if (strcasecmp(val, "Disable") == 0 ||
8924 strcasecmp(val, "passive") == 0)
8925 chsm = CHSM_DISABLE;
8926 else if (strcasecmp(val, "RejReq") == 0)
8927 chsm = CHSM_REJREQ;
8928 else if (strcasecmp(val, "UnSolResp") == 0)
8929 chsm = CHSM_UNSOLRESP;
8930 else {
8931 send_resp(dut, conn, SIGMA_ERROR,
8932 "ErrorCode,Unknown ChSwitchMode value");
8933 return 0;
8934 }
8935 }
8936
8937 val = get_param(cmd, "OffChNum");
8938 if (val) {
8939 off_ch_num = atoi(val);
8940 if (off_ch_num == 0) {
8941 send_resp(dut, conn, SIGMA_ERROR,
8942 "ErrorCode,Invalid OffChNum");
8943 return 0;
8944 }
8945 }
8946
8947 val = get_param(cmd, "SecChOffset");
8948 if (val) {
8949 if (strcmp(val, "20") == 0)
8950 sec_ch = SEC_CH_NO;
8951 else if (strcasecmp(val, "40above") == 0)
8952 sec_ch = SEC_CH_40ABOVE;
8953 else if (strcasecmp(val, "40below") == 0)
8954 sec_ch = SEC_CH_40BELOW;
8955 else {
8956 send_resp(dut, conn, SIGMA_ERROR,
8957 "ErrorCode,Unknown SecChOffset value");
8958 return 0;
8959 }
8960 }
8961
8962 if (chsm == CHSM_NOT_SET) {
8963 /* no offchannel changes requested */
8964 return 1;
8965 }
8966
8967 if (strcmp(intf, get_main_ifname()) != 0 &&
8968 strcmp(intf, get_station_ifname()) != 0) {
8969 send_resp(dut, conn, SIGMA_ERROR,
8970 "ErrorCode,Unknown interface");
8971 return 0;
8972 }
8973
8974 switch (chsm) {
8975 case CHSM_NOT_SET:
Jouni Malinen280f5ba2016-08-29 21:33:10 +03008976 res = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008977 break;
8978 case CHSM_ENABLE:
8979 if (off_ch_num < 0) {
8980 send_resp(dut, conn, SIGMA_ERROR,
8981 "ErrorCode,Missing OffChNum argument");
8982 return 0;
8983 }
8984 if (wifi_chip_type == DRIVER_WCN) {
8985 res = tdls_set_offchannel_offset(dut, conn, intf,
8986 off_ch_num, sec_ch);
8987 } else {
8988 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
8989 sec_ch);
8990 }
8991 if (res != 1)
8992 return res;
8993 if (wifi_chip_type == DRIVER_WCN)
8994 res = tdls_set_offchannel_mode(dut, conn, intf, 1);
8995 else
8996 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 1);
8997 break;
8998 case CHSM_DISABLE:
8999 if (wifi_chip_type == DRIVER_WCN)
9000 res = tdls_set_offchannel_mode(dut, conn, intf, 2);
9001 else
9002 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 2);
9003 break;
9004 case CHSM_REJREQ:
9005 if (wifi_chip_type == DRIVER_WCN)
9006 res = tdls_set_offchannel_mode(dut, conn, intf, 3);
9007 else
9008 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 3);
9009 break;
9010 case CHSM_UNSOLRESP:
9011 if (off_ch_num < 0) {
9012 send_resp(dut, conn, SIGMA_ERROR,
9013 "ErrorCode,Missing OffChNum argument");
9014 return 0;
9015 }
9016 if (wifi_chip_type == DRIVER_WCN) {
9017 res = tdls_set_offchannel_offset(dut, conn, intf,
9018 off_ch_num, sec_ch);
9019 } else {
9020 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
9021 sec_ch);
9022 }
9023 if (res != 1)
9024 return res;
9025 if (wifi_chip_type == DRIVER_WCN)
9026 res = tdls_set_offchannel_mode(dut, conn, intf, 4);
9027 else
9028 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 4);
9029 break;
9030 }
9031
9032 return res;
9033}
9034
9035
9036static int ath_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
9037 struct sigma_conn *conn,
9038 struct sigma_cmd *cmd)
9039{
9040 const char *val;
9041 char *token, *result;
9042
priyadharshini gowthamane5e25172015-12-08 14:53:48 -08009043 novap_reset(dut, intf);
9044
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009045 val = get_param(cmd, "nss_mcs_opt");
9046 if (val) {
9047 /* String (nss_operating_mode; mcs_operating_mode) */
9048 int nss, mcs;
9049 char buf[50];
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05309050 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009051
9052 token = strdup(val);
9053 if (!token)
9054 return 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05309055 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +05309056 if (!result) {
9057 sigma_dut_print(dut, DUT_MSG_ERROR,
9058 "VHT NSS not specified");
9059 goto failed;
9060 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009061 if (strcasecmp(result, "def") != 0) {
9062 nss = atoi(result);
9063 if (nss == 4)
9064 ath_disable_txbf(dut, intf);
9065 snprintf(buf, sizeof(buf), "iwpriv %s nss %d",
9066 intf, nss);
9067 if (system(buf) != 0) {
9068 sigma_dut_print(dut, DUT_MSG_ERROR,
9069 "iwpriv nss failed");
9070 goto failed;
9071 }
9072 }
9073
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05309074 result = strtok_r(NULL, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +05309075 if (!result) {
9076 sigma_dut_print(dut, DUT_MSG_ERROR,
9077 "VHT MCS not specified");
9078 goto failed;
9079 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009080 if (strcasecmp(result, "def") == 0) {
9081 snprintf(buf, sizeof(buf), "iwpriv %s set11NRates 0",
9082 intf);
9083 if (system(buf) != 0) {
9084 sigma_dut_print(dut, DUT_MSG_ERROR,
9085 "iwpriv set11NRates failed");
9086 goto failed;
9087 }
9088
9089 } else {
9090 mcs = atoi(result);
9091 snprintf(buf, sizeof(buf), "iwpriv %s vhtmcs %d",
9092 intf, mcs);
9093 if (system(buf) != 0) {
9094 sigma_dut_print(dut, DUT_MSG_ERROR,
9095 "iwpriv vhtmcs failed");
9096 goto failed;
9097 }
9098 }
9099 /* Channel width gets messed up, fix this */
9100 snprintf(buf, sizeof(buf), "iwpriv %s chwidth %d",
9101 intf, dut->chwidth);
9102 if (system(buf) != 0) {
9103 sigma_dut_print(dut, DUT_MSG_ERROR,
9104 "iwpriv chwidth failed");
9105 }
9106 }
9107
9108 return 1;
9109failed:
9110 free(token);
9111 return 0;
9112}
9113
9114
9115static int cmd_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
9116 struct sigma_conn *conn,
9117 struct sigma_cmd *cmd)
9118{
9119 switch (get_driver_type()) {
9120 case DRIVER_ATHEROS:
9121 return ath_sta_set_rfeature_vht(intf, dut, conn, cmd);
9122 default:
9123 send_resp(dut, conn, SIGMA_ERROR,
9124 "errorCode,Unsupported sta_set_rfeature(VHT) with the current driver");
9125 return 0;
9126 }
9127}
9128
9129
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -08009130static int wcn_sta_set_rfeature_he(const char *intf, struct sigma_dut *dut,
9131 struct sigma_conn *conn,
9132 struct sigma_cmd *cmd)
9133{
9134 const char *val;
9135 char *token = NULL, *result;
9136 char buf[60];
9137
9138 val = get_param(cmd, "nss_mcs_opt");
9139 if (val) {
9140 /* String (nss_operating_mode; mcs_operating_mode) */
9141 int nss, mcs, ratecode;
9142 char *saveptr;
9143
9144 token = strdup(val);
9145 if (!token)
9146 return -2;
9147
9148 result = strtok_r(token, ";", &saveptr);
9149 if (!result) {
9150 sigma_dut_print(dut, DUT_MSG_ERROR,
9151 "HE NSS not specified");
9152 goto failed;
9153 }
9154 nss = 1;
9155 if (strcasecmp(result, "def") != 0)
9156 nss = atoi(result);
9157
9158 result = strtok_r(NULL, ";", &saveptr);
9159 if (!result) {
9160 sigma_dut_print(dut, DUT_MSG_ERROR,
9161 "HE MCS not specified");
9162 goto failed;
9163 }
9164 mcs = 7;
9165 if (strcasecmp(result, "def") != 0)
9166 mcs = atoi(result);
9167
Arif Hussain557bf412018-05-25 17:29:36 -07009168 ratecode = 0x20; /* for nss:1 MCS 0 */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -08009169 if (nss == 2) {
Arif Hussain557bf412018-05-25 17:29:36 -07009170 ratecode = 0x40; /* for nss:2 MCS 0 */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -08009171 } else if (nss > 2) {
9172 sigma_dut_print(dut, DUT_MSG_ERROR,
9173 "HE NSS %d not supported", nss);
9174 goto failed;
9175 }
9176
Arif Hussain557bf412018-05-25 17:29:36 -07009177 snprintf(buf, sizeof(buf), "iwpriv %s nss %d", intf, nss);
9178 if (system(buf) != 0) {
9179 sigma_dut_print(dut, DUT_MSG_ERROR,
9180 "nss_mcs_opt: iwpriv %s nss %d failed",
9181 intf, nss);
9182 goto failed;
9183 }
Arif Hussainac6c5112018-05-25 17:34:00 -07009184 dut->sta_nss = nss;
Arif Hussain557bf412018-05-25 17:29:36 -07009185
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -08009186 /* Add the MCS to the ratecode */
9187 if (mcs >= 0 && mcs <= 11) {
9188 ratecode += mcs;
Arif Hussain557bf412018-05-25 17:29:36 -07009189#ifdef NL80211_SUPPORT
9190 if (dut->device_type == STA_testbed) {
9191 enum he_mcs_config mcs_config;
9192 int ret;
9193
9194 if (mcs <= 7)
9195 mcs_config = HE_80_MCS0_7;
9196 else if (mcs <= 9)
9197 mcs_config = HE_80_MCS0_9;
9198 else
9199 mcs_config = HE_80_MCS0_11;
9200 ret = sta_set_he_mcs(dut, intf, mcs_config);
9201 if (ret) {
9202 sigma_dut_print(dut, DUT_MSG_ERROR,
9203 "nss_mcs_opt: mcs setting failed, mcs:%d, mcs_config %d, ret:%d",
9204 mcs, mcs_config, ret);
9205 goto failed;
9206 }
9207 }
9208#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -08009209 } else {
9210 sigma_dut_print(dut, DUT_MSG_ERROR,
9211 "HE MCS %d not supported", mcs);
9212 goto failed;
9213 }
9214 snprintf(buf, sizeof(buf), "iwpriv %s set_11ax_rate 0x%03x",
9215 intf, ratecode);
9216 if (system(buf) != 0) {
9217 sigma_dut_print(dut, DUT_MSG_ERROR,
9218 "iwpriv setting of 11ax rates failed");
9219 goto failed;
9220 }
9221 free(token);
9222 }
9223
9224 val = get_param(cmd, "GI");
9225 if (val) {
9226 if (strcmp(val, "0.8") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -07009227 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 9", intf);
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -08009228 } else if (strcmp(val, "1.6") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -07009229 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 10",
9230 intf);
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -08009231 } else if (strcmp(val, "3.2") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -07009232 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 11",
9233 intf);
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -08009234 } else {
9235 send_resp(dut, conn, SIGMA_ERROR,
9236 "errorCode,GI value not supported");
9237 return 0;
9238 }
9239 if (system(buf) != 0) {
9240 send_resp(dut, conn, SIGMA_ERROR,
9241 "errorCode,Failed to set shortgi");
9242 return 0;
9243 }
9244 }
9245
Subhani Shaik8e7a3052018-04-24 14:03:00 -07009246 val = get_param(cmd, "LTF");
9247 if (val) {
9248#ifdef NL80211_SUPPORT
9249 if (strcmp(val, "3.2") == 0) {
9250 sta_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_1X);
9251 } if (strcmp(val, "6.4") == 0) {
9252 sta_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_2X);
9253 } else if (strcmp(val, "12.8") == 0) {
9254 sta_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_4X);
9255 } else {
9256 send_resp(dut, conn, SIGMA_ERROR,
9257 "errorCode, LTF value not supported");
9258 return 0;
9259 }
9260#else /* NL80211_SUPPORT */
9261 sigma_dut_print(dut, DUT_MSG_ERROR,
9262 "LTF cannot be set without NL80211_SUPPORT defined");
9263 return -2;
9264#endif /* NL80211_SUPPORT */
9265 }
9266
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -08009267 return 1;
9268
9269failed:
9270 free(token);
9271 return -2;
9272}
9273
9274
9275static int cmd_sta_set_rfeature_he(const char *intf, struct sigma_dut *dut,
9276 struct sigma_conn *conn,
9277 struct sigma_cmd *cmd)
9278{
9279 switch (get_driver_type()) {
9280 case DRIVER_WCN:
9281 return wcn_sta_set_rfeature_he(intf, dut, conn, cmd);
9282 default:
9283 send_resp(dut, conn, SIGMA_ERROR,
9284 "errorCode,Unsupported sta_set_rfeature(HE) with the current driver");
9285 return 0;
9286 }
9287}
9288
9289
Ashwini Patil5acd7382017-04-13 15:55:04 +05309290static int btm_query_candidate_list(struct sigma_dut *dut,
9291 struct sigma_conn *conn,
9292 struct sigma_cmd *cmd)
9293{
9294 const char *bssid, *info, *op_class, *ch, *phy_type, *pref;
9295 int len, ret;
9296 char buf[10];
9297
9298 /*
9299 * Neighbor Report elements format:
9300 * neighbor=<BSSID>,<BSSID Information>,<Operating Class>,
9301 * <Channel Number>,<PHY Type>[,<hexdump of Optional Subelements>]
9302 * eg: neighbor=aa:bb:cc:dd:ee:ff,17,81,6,1,030101
9303 */
9304
9305 bssid = get_param(cmd, "Nebor_BSSID");
9306 if (!bssid) {
9307 send_resp(dut, conn, SIGMA_INVALID,
9308 "errorCode,Nebor_BSSID is missing");
9309 return 0;
9310 }
9311
9312 info = get_param(cmd, "Nebor_Bssid_Info");
9313 if (!info) {
9314 sigma_dut_print(dut, DUT_MSG_INFO,
9315 "Using default value for Nebor_Bssid_Info: %s",
9316 DEFAULT_NEIGHBOR_BSSID_INFO);
9317 info = DEFAULT_NEIGHBOR_BSSID_INFO;
9318 }
9319
9320 op_class = get_param(cmd, "Nebor_Op_Class");
9321 if (!op_class) {
9322 send_resp(dut, conn, SIGMA_INVALID,
9323 "errorCode,Nebor_Op_Class is missing");
9324 return 0;
9325 }
9326
9327 ch = get_param(cmd, "Nebor_Op_Ch");
9328 if (!ch) {
9329 send_resp(dut, conn, SIGMA_INVALID,
9330 "errorCode,Nebor_Op_Ch is missing");
9331 return 0;
9332 }
9333
9334 phy_type = get_param(cmd, "Nebor_Phy_Type");
9335 if (!phy_type) {
9336 sigma_dut_print(dut, DUT_MSG_INFO,
9337 "Using default value for Nebor_Phy_Type: %s",
9338 DEFAULT_NEIGHBOR_PHY_TYPE);
9339 phy_type = DEFAULT_NEIGHBOR_PHY_TYPE;
9340 }
9341
9342 /* Parse optional subelements */
9343 buf[0] = '\0';
9344 pref = get_param(cmd, "Nebor_Pref");
9345 if (pref) {
9346 /* hexdump for preferrence subelement */
9347 ret = snprintf(buf, sizeof(buf), ",0301%02x", atoi(pref));
9348 if (ret < 0 || ret >= (int) sizeof(buf)) {
9349 sigma_dut_print(dut, DUT_MSG_ERROR,
9350 "snprintf failed for optional subelement ret: %d",
9351 ret);
9352 send_resp(dut, conn, SIGMA_ERROR,
9353 "errorCode,snprintf failed for subelement");
9354 return 0;
9355 }
9356 }
9357
9358 if (!dut->btm_query_cand_list) {
9359 dut->btm_query_cand_list = calloc(1, NEIGHBOR_REPORT_SIZE);
9360 if (!dut->btm_query_cand_list) {
9361 send_resp(dut, conn, SIGMA_ERROR,
9362 "errorCode,Failed to allocate memory for btm_query_cand_list");
9363 return 0;
9364 }
9365 }
9366
9367 len = strlen(dut->btm_query_cand_list);
9368 ret = snprintf(dut->btm_query_cand_list + len,
9369 NEIGHBOR_REPORT_SIZE - len, " neighbor=%s,%s,%s,%s,%s%s",
9370 bssid, info, op_class, ch, phy_type, buf);
9371 if (ret < 0 || ret >= NEIGHBOR_REPORT_SIZE - len) {
9372 sigma_dut_print(dut, DUT_MSG_ERROR,
9373 "snprintf failed for neighbor report list ret: %d",
9374 ret);
9375 send_resp(dut, conn, SIGMA_ERROR,
9376 "errorCode,snprintf failed for neighbor report");
9377 free(dut->btm_query_cand_list);
9378 dut->btm_query_cand_list = NULL;
9379 return 0;
9380 }
9381
9382 return 1;
9383}
9384
9385
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009386static int cmd_sta_set_rfeature(struct sigma_dut *dut, struct sigma_conn *conn,
9387 struct sigma_cmd *cmd)
9388{
9389 const char *intf = get_param(cmd, "Interface");
9390 const char *prog = get_param(cmd, "Prog");
Ashwini Patil68d02cd2017-01-10 15:39:16 +05309391 const char *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009392
9393 if (intf == NULL || prog == NULL)
9394 return -1;
9395
Ashwini Patil5acd7382017-04-13 15:55:04 +05309396 /* BSS Transition candidate list for BTM query */
9397 val = get_param(cmd, "Nebor_BSSID");
9398 if (val && btm_query_candidate_list(dut, conn, cmd) == 0)
9399 return 0;
9400
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009401 if (strcasecmp(prog, "TDLS") == 0)
9402 return cmd_sta_set_rfeature_tdls(intf, dut, conn, cmd);
9403
9404 if (strcasecmp(prog, "VHT") == 0)
9405 return cmd_sta_set_rfeature_vht(intf, dut, conn, cmd);
9406
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -08009407 if (strcasecmp(prog, "HE") == 0)
9408 return cmd_sta_set_rfeature_he(intf, dut, conn, cmd);
9409
Ashwini Patil68d02cd2017-01-10 15:39:16 +05309410 if (strcasecmp(prog, "MBO") == 0) {
9411 val = get_param(cmd, "Cellular_Data_Cap");
9412 if (val &&
9413 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
9414 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +05309415
9416 val = get_param(cmd, "Ch_Pref");
9417 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
9418 return 0;
9419
Ashwini Patil68d02cd2017-01-10 15:39:16 +05309420 return 1;
9421 }
9422
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009423 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported Prog");
9424 return 0;
9425}
9426
9427
9428static int cmd_sta_set_radio(struct sigma_dut *dut, struct sigma_conn *conn,
9429 struct sigma_cmd *cmd)
9430{
9431 const char *intf = get_param(cmd, "Interface");
9432 const char *mode = get_param(cmd, "Mode");
9433 int res;
9434
9435 if (intf == NULL || mode == NULL)
9436 return -1;
9437
9438 if (strcasecmp(mode, "On") == 0)
9439 res = wpa_command(intf, "SET radio_disabled 0");
9440 else if (strcasecmp(mode, "Off") == 0)
9441 res = wpa_command(intf, "SET radio_disabled 1");
9442 else
9443 return -1;
9444
9445 if (res) {
9446 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
9447 "radio mode");
9448 return 0;
9449 }
9450
9451 return 1;
9452}
9453
9454
9455static int cmd_sta_set_pwrsave(struct sigma_dut *dut, struct sigma_conn *conn,
9456 struct sigma_cmd *cmd)
9457{
9458 const char *intf = get_param(cmd, "Interface");
9459 const char *mode = get_param(cmd, "Mode");
9460 int res;
9461
9462 if (intf == NULL || mode == NULL)
9463 return -1;
9464
9465 if (strcasecmp(mode, "On") == 0)
9466 res = set_ps(intf, dut, 1);
9467 else if (strcasecmp(mode, "Off") == 0)
9468 res = set_ps(intf, dut, 0);
9469 else
9470 return -1;
9471
9472 if (res) {
9473 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
9474 "power save mode");
9475 return 0;
9476 }
9477
9478 return 1;
9479}
9480
9481
9482static int cmd_sta_bssid_pool(struct sigma_dut *dut, struct sigma_conn *conn,
9483 struct sigma_cmd *cmd)
9484{
9485 const char *intf = get_param(cmd, "Interface");
9486 const char *val, *bssid;
9487 int res;
9488 char *buf;
9489 size_t buf_len;
9490
9491 val = get_param(cmd, "BSSID_FILTER");
9492 if (val == NULL)
9493 return -1;
9494
9495 bssid = get_param(cmd, "BSSID_List");
9496 if (atoi(val) == 0 || bssid == NULL) {
9497 /* Disable BSSID filter */
9498 if (wpa_command(intf, "SET bssid_filter ")) {
9499 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed "
9500 "to disable BSSID filter");
9501 return 0;
9502 }
9503
9504 return 1;
9505 }
9506
9507 buf_len = 100 + strlen(bssid);
9508 buf = malloc(buf_len);
9509 if (buf == NULL)
9510 return -1;
9511
9512 snprintf(buf, buf_len, "SET bssid_filter %s", bssid);
9513 res = wpa_command(intf, buf);
9514 free(buf);
9515 if (res) {
9516 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to enable "
9517 "BSSID filter");
9518 return 0;
9519 }
9520
9521 return 1;
9522}
9523
9524
9525static int cmd_sta_reset_parm(struct sigma_dut *dut, struct sigma_conn *conn,
9526 struct sigma_cmd *cmd)
9527{
9528 const char *intf = get_param(cmd, "Interface");
9529 const char *val;
9530
9531 /* TODO: ARP */
9532
9533 val = get_param(cmd, "HS2_CACHE_PROFILE");
9534 if (val && strcasecmp(val, "All") == 0)
9535 hs2_clear_credentials(intf);
9536
9537 return 1;
9538}
9539
9540
9541static int cmd_sta_get_key(struct sigma_dut *dut, struct sigma_conn *conn,
9542 struct sigma_cmd *cmd)
9543{
9544 const char *intf = get_param(cmd, "Interface");
9545 const char *key_type = get_param(cmd, "KeyType");
9546 char buf[100], resp[200];
9547
9548 if (key_type == NULL)
9549 return -1;
9550
9551 if (strcasecmp(key_type, "GTK") == 0) {
9552 if (wpa_command_resp(intf, "GET gtk", buf, sizeof(buf)) < 0 ||
9553 strncmp(buf, "FAIL", 4) == 0) {
9554 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
9555 "not fetch current GTK");
9556 return 0;
9557 }
9558 snprintf(resp, sizeof(resp), "KeyValue,%s", buf);
9559 send_resp(dut, conn, SIGMA_COMPLETE, resp);
9560 return 0;
9561 } else {
9562 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
9563 "KeyType");
9564 return 0;
9565 }
9566
9567 return 1;
9568}
9569
9570
9571static int hs2_set_policy(struct sigma_dut *dut)
9572{
9573#ifdef ANDROID
9574 system("ip rule del prio 23000");
9575 if (system("ip rule add from all lookup main prio 23000") != 0) {
9576 sigma_dut_print(dut, DUT_MSG_ERROR,
9577 "Failed to run:ip rule add from all lookup main prio");
9578 return -1;
9579 }
9580 if (system("ip route flush cache") != 0) {
9581 sigma_dut_print(dut, DUT_MSG_ERROR,
9582 "Failed to run ip route flush cache");
9583 return -1;
9584 }
9585 return 1;
9586#else /* ANDROID */
9587 return 0;
9588#endif /* ANDROID */
9589}
9590
9591
9592static int cmd_sta_hs2_associate(struct sigma_dut *dut,
9593 struct sigma_conn *conn,
9594 struct sigma_cmd *cmd)
9595{
9596 const char *intf = get_param(cmd, "Interface");
9597 const char *val = get_param(cmd, "Ignore_blacklist");
9598 struct wpa_ctrl *ctrl;
9599 int res;
9600 char bssid[20], ssid[40], resp[100], buf[100], blacklisted[100];
9601 int tries = 0;
9602 int ignore_blacklist = 0;
9603 const char *events[] = {
9604 "CTRL-EVENT-CONNECTED",
9605 "INTERWORKING-BLACKLISTED",
9606 "INTERWORKING-NO-MATCH",
9607 NULL
9608 };
9609
9610 start_sta_mode(dut);
9611
9612 blacklisted[0] = '\0';
9613 if (val && atoi(val))
9614 ignore_blacklist = 1;
9615
9616try_again:
9617 ctrl = open_wpa_mon(intf);
9618 if (ctrl == NULL) {
9619 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
9620 "wpa_supplicant monitor connection");
9621 return -2;
9622 }
9623
9624 tries++;
9625 if (wpa_command(intf, "INTERWORKING_SELECT auto")) {
9626 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start "
9627 "Interworking connection");
9628 wpa_ctrl_detach(ctrl);
9629 wpa_ctrl_close(ctrl);
9630 return 0;
9631 }
9632
9633 buf[0] = '\0';
9634 while (1) {
9635 char *pos;
9636 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
9637 pos = strstr(buf, "INTERWORKING-BLACKLISTED");
9638 if (!pos)
9639 break;
9640 pos += 25;
9641 sigma_dut_print(dut, DUT_MSG_DEBUG, "Found blacklisted AP: %s",
9642 pos);
9643 if (!blacklisted[0])
9644 memcpy(blacklisted, pos, strlen(pos) + 1);
9645 }
9646
9647 if (ignore_blacklist && blacklisted[0]) {
9648 char *end;
9649 end = strchr(blacklisted, ' ');
9650 if (end)
9651 *end = '\0';
9652 sigma_dut_print(dut, DUT_MSG_DEBUG, "Try to connect to a blacklisted network: %s",
9653 blacklisted);
9654 snprintf(buf, sizeof(buf), "INTERWORKING_CONNECT %s",
9655 blacklisted);
9656 if (wpa_command(intf, buf)) {
9657 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start Interworking connection to blacklisted network");
9658 wpa_ctrl_detach(ctrl);
9659 wpa_ctrl_close(ctrl);
9660 return 0;
9661 }
9662 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
9663 buf, sizeof(buf));
9664 }
9665
9666 wpa_ctrl_detach(ctrl);
9667 wpa_ctrl_close(ctrl);
9668
9669 if (res < 0) {
9670 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
9671 "connect");
9672 return 0;
9673 }
9674
9675 if (strstr(buf, "INTERWORKING-NO-MATCH") ||
9676 strstr(buf, "INTERWORKING-BLACKLISTED")) {
9677 if (tries < 2) {
9678 sigma_dut_print(dut, DUT_MSG_INFO, "No match found - try again to verify no APs were missed in the scan");
9679 goto try_again;
9680 }
9681 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,No network with "
9682 "matching credentials found");
9683 return 0;
9684 }
9685
9686 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
9687 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
9688 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
9689 "get current BSSID/SSID");
9690 return 0;
9691 }
9692
9693 snprintf(resp, sizeof(resp), "SSID,%s,BSSID,%s", ssid, bssid);
9694 send_resp(dut, conn, SIGMA_COMPLETE, resp);
9695 hs2_set_policy(dut);
9696 return 0;
9697}
9698
9699
9700static int sta_add_credential_uname_pwd(struct sigma_dut *dut,
9701 struct sigma_conn *conn,
9702 const char *ifname,
9703 struct sigma_cmd *cmd)
9704{
9705 const char *val;
9706 int id;
9707
9708 id = add_cred(ifname);
9709 if (id < 0)
9710 return -2;
9711 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
9712
9713 val = get_param(cmd, "prefer");
9714 if (val && atoi(val) > 0)
9715 set_cred(ifname, id, "priority", "1");
9716
9717 val = get_param(cmd, "REALM");
9718 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
9719 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
9720 "realm");
9721 return 0;
9722 }
9723
9724 val = get_param(cmd, "HOME_FQDN");
9725 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
9726 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
9727 "home_fqdn");
9728 return 0;
9729 }
9730
9731 val = get_param(cmd, "Username");
9732 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
9733 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
9734 "username");
9735 return 0;
9736 }
9737
9738 val = get_param(cmd, "Password");
9739 if (val && set_cred_quoted(ifname, id, "password", val) < 0) {
9740 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
9741 "password");
9742 return 0;
9743 }
9744
9745 val = get_param(cmd, "ROOT_CA");
9746 if (val) {
9747 char fname[200];
9748 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
9749#ifdef __linux__
9750 if (!file_exists(fname)) {
9751 char msg[300];
9752 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
9753 "file (%s) not found", fname);
9754 send_resp(dut, conn, SIGMA_ERROR, msg);
9755 return 0;
9756 }
9757#endif /* __linux__ */
9758 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
9759 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
9760 "not set root CA");
9761 return 0;
9762 }
9763 }
9764
9765 return 1;
9766}
9767
9768
9769static int update_devdetail_imsi(struct sigma_dut *dut, const char *imsi)
9770{
9771 FILE *in, *out;
9772 char buf[500];
9773 int found = 0;
9774
9775 in = fopen("devdetail.xml", "r");
9776 if (in == NULL)
9777 return -1;
9778 out = fopen("devdetail.xml.tmp", "w");
9779 if (out == NULL) {
9780 fclose(in);
9781 return -1;
9782 }
9783
9784 while (fgets(buf, sizeof(buf), in)) {
9785 char *pos = strstr(buf, "<IMSI>");
9786 if (pos) {
9787 sigma_dut_print(dut, DUT_MSG_INFO, "Updated DevDetail IMSI to %s",
9788 imsi);
9789 pos += 6;
9790 *pos = '\0';
9791 fprintf(out, "%s%s</IMSI>\n", buf, imsi);
9792 found++;
9793 } else {
9794 fprintf(out, "%s", buf);
9795 }
9796 }
9797
9798 fclose(out);
9799 fclose(in);
9800 if (found)
9801 rename("devdetail.xml.tmp", "devdetail.xml");
9802 else
9803 unlink("devdetail.xml.tmp");
9804
9805 return 0;
9806}
9807
9808
9809static int sta_add_credential_sim(struct sigma_dut *dut,
9810 struct sigma_conn *conn,
9811 const char *ifname, struct sigma_cmd *cmd)
9812{
9813 const char *val, *imsi = NULL;
9814 int id;
9815 char buf[200];
9816 int res;
9817 const char *pos;
9818 size_t mnc_len;
9819 char plmn_mcc[4];
9820 char plmn_mnc[4];
9821
9822 id = add_cred(ifname);
9823 if (id < 0)
9824 return -2;
9825 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
9826
9827 val = get_param(cmd, "prefer");
9828 if (val && atoi(val) > 0)
9829 set_cred(ifname, id, "priority", "1");
9830
9831 val = get_param(cmd, "PLMN_MCC");
9832 if (val == NULL) {
9833 send_resp(dut, conn, SIGMA_ERROR,
9834 "errorCode,Missing PLMN_MCC");
9835 return 0;
9836 }
9837 if (strlen(val) != 3) {
9838 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MCC");
9839 return 0;
9840 }
9841 snprintf(plmn_mcc, sizeof(plmn_mcc), "%s", val);
9842
9843 val = get_param(cmd, "PLMN_MNC");
9844 if (val == NULL) {
9845 send_resp(dut, conn, SIGMA_ERROR,
9846 "errorCode,Missing PLMN_MNC");
9847 return 0;
9848 }
9849 if (strlen(val) != 2 && strlen(val) != 3) {
9850 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MNC");
9851 return 0;
9852 }
9853 snprintf(plmn_mnc, sizeof(plmn_mnc), "%s", val);
9854
9855 val = get_param(cmd, "IMSI");
9856 if (val == NULL) {
9857 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing SIM "
9858 "IMSI");
9859 return 0;
9860 }
9861
9862 imsi = pos = val;
9863
9864 if (strncmp(plmn_mcc, pos, 3) != 0) {
9865 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MCC mismatch");
9866 return 0;
9867 }
9868 pos += 3;
9869
9870 mnc_len = strlen(plmn_mnc);
9871 if (mnc_len < 2) {
9872 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC not set");
9873 return 0;
9874 }
9875
9876 if (strncmp(plmn_mnc, pos, mnc_len) != 0) {
9877 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC mismatch");
9878 return 0;
9879 }
9880 pos += mnc_len;
9881
9882 res = snprintf(buf, sizeof(buf), "%s%s-%s",plmn_mcc, plmn_mnc, pos);
9883 if (res < 0 || res >= (int) sizeof(buf))
9884 return -1;
9885 if (set_cred_quoted(ifname, id, "imsi", buf) < 0) {
9886 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
9887 "not set IMSI");
9888 return 0;
9889 }
9890
9891 val = get_param(cmd, "Password");
9892 if (val && set_cred_quoted(ifname, id, "milenage", val) < 0) {
9893 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
9894 "not set password");
9895 return 0;
9896 }
9897
9898 if (dut->program == PROGRAM_HS2_R2) {
9899 /*
9900 * Set provisioning_sp for the test cases where SIM/USIM
9901 * provisioning is used.
9902 */
9903 if (val && set_cred_quoted(ifname, id, "provisioning_sp",
9904 "wi-fi.org") < 0) {
9905 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
9906 "not set provisioning_sp");
9907 return 0;
9908 }
9909
9910 update_devdetail_imsi(dut, imsi);
9911 }
9912
9913 return 1;
9914}
9915
9916
9917static int sta_add_credential_cert(struct sigma_dut *dut,
9918 struct sigma_conn *conn,
9919 const char *ifname,
9920 struct sigma_cmd *cmd)
9921{
9922 const char *val;
9923 int id;
9924
9925 id = add_cred(ifname);
9926 if (id < 0)
9927 return -2;
9928 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
9929
9930 val = get_param(cmd, "prefer");
9931 if (val && atoi(val) > 0)
9932 set_cred(ifname, id, "priority", "1");
9933
9934 val = get_param(cmd, "REALM");
9935 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
9936 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
9937 "realm");
9938 return 0;
9939 }
9940
9941 val = get_param(cmd, "HOME_FQDN");
9942 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
9943 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
9944 "home_fqdn");
9945 return 0;
9946 }
9947
9948 val = get_param(cmd, "Username");
9949 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
9950 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
9951 "username");
9952 return 0;
9953 }
9954
9955 val = get_param(cmd, "clientCertificate");
9956 if (val) {
9957 char fname[200];
9958 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
9959#ifdef __linux__
9960 if (!file_exists(fname)) {
9961 char msg[300];
9962 snprintf(msg, sizeof(msg),
9963 "ErrorCode,clientCertificate "
9964 "file (%s) not found", fname);
9965 send_resp(dut, conn, SIGMA_ERROR, msg);
9966 return 0;
9967 }
9968#endif /* __linux__ */
9969 if (set_cred_quoted(ifname, id, "client_cert", fname) < 0) {
9970 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
9971 "not set client_cert");
9972 return 0;
9973 }
9974 if (set_cred_quoted(ifname, id, "private_key", fname) < 0) {
9975 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
9976 "not set private_key");
9977 return 0;
9978 }
9979 }
9980
9981 val = get_param(cmd, "ROOT_CA");
9982 if (val) {
9983 char fname[200];
9984 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
9985#ifdef __linux__
9986 if (!file_exists(fname)) {
9987 char msg[300];
9988 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
9989 "file (%s) not found", fname);
9990 send_resp(dut, conn, SIGMA_ERROR, msg);
9991 return 0;
9992 }
9993#endif /* __linux__ */
9994 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
9995 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
9996 "not set root CA");
9997 return 0;
9998 }
9999 }
10000
10001 return 1;
10002}
10003
10004
10005static int cmd_sta_add_credential(struct sigma_dut *dut,
10006 struct sigma_conn *conn,
10007 struct sigma_cmd *cmd)
10008{
10009 const char *intf = get_param(cmd, "Interface");
10010 const char *type;
10011
10012 start_sta_mode(dut);
10013
10014 type = get_param(cmd, "Type");
10015 if (!type)
10016 return -1;
10017
10018 if (strcasecmp(type, "uname_pwd") == 0)
10019 return sta_add_credential_uname_pwd(dut, conn, intf, cmd);
10020
10021 if (strcasecmp(type, "sim") == 0)
10022 return sta_add_credential_sim(dut, conn, intf, cmd);
10023
10024 if (strcasecmp(type, "cert") == 0)
10025 return sta_add_credential_cert(dut, conn, intf, cmd);
10026
10027 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported credential "
10028 "type");
10029 return 0;
10030}
10031
10032
10033static int cmd_sta_scan(struct sigma_dut *dut, struct sigma_conn *conn,
10034 struct sigma_cmd *cmd)
10035{
10036 const char *intf = get_param(cmd, "Interface");
vamsi krishna89ad8c62017-09-19 12:51:18 +053010037 const char *val, *bssid, *ssid;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010038 char buf[100];
vamsi krishna89ad8c62017-09-19 12:51:18 +053010039 char ssid_hex[65];
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010040 int res;
10041
10042 val = get_param(cmd, "HESSID");
10043 if (val) {
10044 res = snprintf(buf, sizeof(buf), "SET hessid %s", val);
10045 if (res < 0 || res >= (int) sizeof(buf))
10046 return -1;
10047 wpa_command(intf, buf);
10048 }
10049
10050 val = get_param(cmd, "ACCS_NET_TYPE");
10051 if (val) {
10052 res = snprintf(buf, sizeof(buf), "SET access_network_type %s",
10053 val);
10054 if (res < 0 || res >= (int) sizeof(buf))
10055 return -1;
10056 wpa_command(intf, buf);
10057 }
10058
vamsi krishna89ad8c62017-09-19 12:51:18 +053010059 bssid = get_param(cmd, "Bssid");
10060 ssid = get_param(cmd, "Ssid");
10061
10062 if (ssid) {
10063 if (2 * strlen(ssid) >= sizeof(ssid_hex)) {
10064 send_resp(dut, conn, SIGMA_ERROR,
10065 "ErrorCode,Too long SSID");
10066 return 0;
10067 }
10068 ascii2hexstr(ssid, ssid_hex);
10069 }
10070
10071 res = snprintf(buf, sizeof(buf), "SCAN%s%s%s%s",
10072 bssid ? " bssid=": "",
10073 bssid ? bssid : "",
10074 ssid ? " ssid " : "",
10075 ssid ? ssid_hex : "");
10076 if (res < 0 || res >= (int) sizeof(buf))
10077 return -1;
10078
10079 if (wpa_command(intf, buf)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010080 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not start "
10081 "scan");
10082 return 0;
10083 }
10084
10085 return 1;
10086}
10087
10088
Jouni Malinen5e5d43d2018-01-10 17:29:33 +020010089static int cmd_sta_scan_bss(struct sigma_dut *dut, struct sigma_conn *conn,
10090 struct sigma_cmd *cmd)
10091{
10092 const char *intf = get_param(cmd, "Interface");
10093 const char *bssid;
10094 char buf[4096], *pos;
10095 int freq, chan;
10096 char *ssid;
10097 char resp[100];
10098 int res;
10099 struct wpa_ctrl *ctrl;
10100
10101 bssid = get_param(cmd, "BSSID");
10102 if (!bssid) {
10103 send_resp(dut, conn, SIGMA_INVALID,
10104 "errorCode,BSSID argument is missing");
10105 return 0;
10106 }
10107
10108 ctrl = open_wpa_mon(intf);
10109 if (!ctrl) {
10110 sigma_dut_print(dut, DUT_MSG_ERROR,
10111 "Failed to open wpa_supplicant monitor connection");
10112 return -1;
10113 }
10114
10115 if (wpa_command(intf, "SCAN TYPE=ONLY")) {
10116 send_resp(dut, conn, SIGMA_ERROR,
10117 "errorCode,Could not start scan");
10118 wpa_ctrl_detach(ctrl);
10119 wpa_ctrl_close(ctrl);
10120 return 0;
10121 }
10122
10123 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
10124 buf, sizeof(buf));
10125
10126 wpa_ctrl_detach(ctrl);
10127 wpa_ctrl_close(ctrl);
10128
10129 if (res < 0) {
10130 send_resp(dut, conn, SIGMA_ERROR,
10131 "errorCode,Scan did not complete");
10132 return 0;
10133 }
10134
10135 snprintf(buf, sizeof(buf), "BSS %s", bssid);
10136 if (wpa_command_resp(intf, buf, buf, sizeof(buf)) < 0 ||
10137 strncmp(buf, "id=", 3) != 0) {
10138 send_resp(dut, conn, SIGMA_ERROR,
10139 "errorCode,Specified BSSID not found");
10140 return 0;
10141 }
10142
10143 pos = strstr(buf, "\nfreq=");
10144 if (!pos) {
10145 send_resp(dut, conn, SIGMA_ERROR,
10146 "errorCode,Channel not found");
10147 return 0;
10148 }
10149 freq = atoi(pos + 6);
10150 chan = freq_to_channel(freq);
10151
10152 pos = strstr(buf, "\nssid=");
10153 if (!pos) {
10154 send_resp(dut, conn, SIGMA_ERROR,
10155 "errorCode,SSID not found");
10156 return 0;
10157 }
10158 ssid = pos + 6;
10159 pos = strchr(ssid, '\n');
10160 if (pos)
10161 *pos = '\0';
10162 snprintf(resp, sizeof(resp), "ssid,%s,bsschannel,%d", ssid, chan);
10163 send_resp(dut, conn, SIGMA_COMPLETE, resp);
10164 return 0;
10165}
10166
10167
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010168static int cmd_sta_set_systime(struct sigma_dut *dut, struct sigma_conn *conn,
10169 struct sigma_cmd *cmd)
10170{
10171#ifdef __linux__
10172 struct timeval tv;
10173 struct tm tm;
10174 time_t t;
10175 const char *val;
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +053010176 int v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010177
10178 wpa_command(get_station_ifname(), "PMKSA_FLUSH");
10179
10180 memset(&tm, 0, sizeof(tm));
10181 val = get_param(cmd, "seconds");
10182 if (val)
10183 tm.tm_sec = atoi(val);
10184 val = get_param(cmd, "minutes");
10185 if (val)
10186 tm.tm_min = atoi(val);
10187 val = get_param(cmd, "hours");
10188 if (val)
10189 tm.tm_hour = atoi(val);
10190 val = get_param(cmd, "date");
10191 if (val)
10192 tm.tm_mday = atoi(val);
10193 val = get_param(cmd, "month");
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +053010194 if (val) {
10195 v = atoi(val);
10196 if (v < 1 || v > 12) {
10197 send_resp(dut, conn, SIGMA_INVALID,
10198 "errorCode,Invalid month");
10199 return 0;
10200 }
10201 tm.tm_mon = v - 1;
10202 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010203 val = get_param(cmd, "year");
10204 if (val) {
10205 int year = atoi(val);
10206#ifdef ANDROID
10207 if (year > 2035)
10208 year = 2035; /* years beyond 2035 not supported */
10209#endif /* ANDROID */
10210 tm.tm_year = year - 1900;
10211 }
10212 t = mktime(&tm);
10213 if (t == (time_t) -1) {
10214 send_resp(dut, conn, SIGMA_ERROR,
10215 "errorCode,Invalid date or time");
10216 return 0;
10217 }
10218
10219 memset(&tv, 0, sizeof(tv));
10220 tv.tv_sec = t;
10221
10222 if (settimeofday(&tv, NULL) < 0) {
10223 sigma_dut_print(dut, DUT_MSG_INFO, "settimeofday failed: %s",
10224 strerror(errno));
10225 send_resp(dut, conn, SIGMA_ERROR,
10226 "errorCode,Failed to set time");
10227 return 0;
10228 }
10229
10230 return 1;
10231#endif /* __linux__ */
10232
10233 return -1;
10234}
10235
10236
10237static int cmd_sta_osu(struct sigma_dut *dut, struct sigma_conn *conn,
10238 struct sigma_cmd *cmd)
10239{
10240 const char *intf = get_param(cmd, "Interface");
10241 const char *name, *val;
10242 int prod_ess_assoc = 1;
10243 char buf[200], bssid[100], ssid[100];
10244 int res;
10245 struct wpa_ctrl *ctrl;
10246
10247 name = get_param(cmd, "osuFriendlyName");
10248
10249 val = get_param(cmd, "ProdESSAssoc");
10250 if (val)
10251 prod_ess_assoc = atoi(val);
10252
10253 kill_dhcp_client(dut, intf);
10254 if (start_dhcp_client(dut, intf) < 0)
10255 return -2;
10256
10257 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger OSU");
10258 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
10259 res = snprintf(buf, sizeof(buf),
10260 "%s %s%s%s signup osu-ca.pem",
10261 prod_ess_assoc ? "" : "-N",
10262 name ? "-O'" : "", name ? name : "",
10263 name ? "'" : "");
10264
Kanchanapally, Vidyullatha12b66762015-12-31 16:46:42 +053010265 hs2_set_policy(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010266 if (run_hs20_osu(dut, buf) < 0) {
10267 FILE *f;
10268
10269 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to complete OSU");
10270
10271 f = fopen("hs20-osu-client.res", "r");
10272 if (f) {
10273 char resp[400], res[300], *pos;
10274 if (!fgets(res, sizeof(res), f))
10275 res[0] = '\0';
10276 pos = strchr(res, '\n');
10277 if (pos)
10278 *pos = '\0';
10279 fclose(f);
10280 sigma_dut_summary(dut, "hs20-osu-client provisioning failed: %s",
10281 res);
10282 snprintf(resp, sizeof(resp), "notify-send '%s'", res);
10283 if (system(resp) != 0) {
10284 }
10285 snprintf(resp, sizeof(resp),
10286 "SSID,,BSSID,,failureReason,%s", res);
10287 send_resp(dut, conn, SIGMA_COMPLETE, resp);
10288 return 0;
10289 }
10290
10291 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
10292 return 0;
10293 }
10294
10295 if (!prod_ess_assoc)
10296 goto report;
10297
10298 ctrl = open_wpa_mon(intf);
10299 if (ctrl == NULL) {
10300 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
10301 "wpa_supplicant monitor connection");
10302 return -1;
10303 }
10304
10305 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
10306 buf, sizeof(buf));
10307
10308 wpa_ctrl_detach(ctrl);
10309 wpa_ctrl_close(ctrl);
10310
10311 if (res < 0) {
10312 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to connect to "
10313 "network after OSU");
10314 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
10315 return 0;
10316 }
10317
10318report:
10319 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
10320 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
10321 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to get BSSID/SSID");
10322 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
10323 return 0;
10324 }
10325
10326 snprintf(buf, sizeof(buf), "SSID,%s,BSSID,%s", ssid, bssid);
10327 send_resp(dut, conn, SIGMA_COMPLETE, buf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010328 return 0;
10329}
10330
10331
10332static int cmd_sta_policy_update(struct sigma_dut *dut, struct sigma_conn *conn,
10333 struct sigma_cmd *cmd)
10334{
10335 const char *val;
10336 int timeout = 120;
10337
10338 val = get_param(cmd, "PolicyUpdate");
10339 if (val == NULL || atoi(val) == 0)
10340 return 1; /* No operation requested */
10341
10342 val = get_param(cmd, "Timeout");
10343 if (val)
10344 timeout = atoi(val);
10345
10346 if (timeout) {
10347 /* TODO: time out the command and return
10348 * PolicyUpdateStatus,TIMEOUT if needed. */
10349 }
10350
10351 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger policy update");
10352 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
10353 if (run_hs20_osu(dut, "pol_upd fqdn=wi-fi.org") < 0) {
10354 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,FAIL");
10355 return 0;
10356 }
10357
10358 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,SUCCESS");
10359 return 0;
10360}
10361
10362
10363static int cmd_sta_er_config(struct sigma_dut *dut, struct sigma_conn *conn,
10364 struct sigma_cmd *cmd)
10365{
10366 struct wpa_ctrl *ctrl;
10367 const char *intf = get_param(cmd, "Interface");
10368 const char *bssid = get_param(cmd, "Bssid");
10369 const char *ssid = get_param(cmd, "SSID");
10370 const char *security = get_param(cmd, "Security");
10371 const char *passphrase = get_param(cmd, "Passphrase");
10372 const char *pin = get_param(cmd, "PIN");
10373 char buf[1000];
10374 char ssid_hex[200], passphrase_hex[200];
10375 const char *keymgmt, *cipher;
10376
10377 if (intf == NULL)
10378 intf = get_main_ifname();
10379
10380 if (!bssid) {
10381 send_resp(dut, conn, SIGMA_ERROR,
10382 "ErrorCode,Missing Bssid argument");
10383 return 0;
10384 }
10385
10386 if (!ssid) {
10387 send_resp(dut, conn, SIGMA_ERROR,
10388 "ErrorCode,Missing SSID argument");
10389 return 0;
10390 }
10391
10392 if (!security) {
10393 send_resp(dut, conn, SIGMA_ERROR,
10394 "ErrorCode,Missing Security argument");
10395 return 0;
10396 }
10397
10398 if (!passphrase) {
10399 send_resp(dut, conn, SIGMA_ERROR,
10400 "ErrorCode,Missing Passphrase argument");
10401 return 0;
10402 }
10403
10404 if (!pin) {
10405 send_resp(dut, conn, SIGMA_ERROR,
10406 "ErrorCode,Missing PIN argument");
10407 return 0;
10408 }
10409
vamsi krishna8c9c1562017-05-12 15:51:46 +053010410 if (2 * strlen(ssid) >= sizeof(ssid_hex) ||
10411 2 * strlen(passphrase) >= sizeof(passphrase_hex)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010412 send_resp(dut, conn, SIGMA_ERROR,
10413 "ErrorCode,Too long SSID/passphrase");
10414 return 0;
10415 }
10416
10417 ctrl = open_wpa_mon(intf);
10418 if (ctrl == NULL) {
10419 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
10420 "wpa_supplicant monitor connection");
10421 return -2;
10422 }
10423
10424 if (strcasecmp(security, "wpa2-psk") == 0) {
10425 keymgmt = "WPA2PSK";
10426 cipher = "CCMP";
10427 } else {
10428 wpa_ctrl_detach(ctrl);
10429 wpa_ctrl_close(ctrl);
10430 send_resp(dut, conn, SIGMA_ERROR,
10431 "ErrorCode,Unsupported Security value");
10432 return 0;
10433 }
10434
10435 ascii2hexstr(ssid, ssid_hex);
10436 ascii2hexstr(passphrase, passphrase_hex);
10437 snprintf(buf, sizeof(buf), "WPS_REG %s %s %s %s %s %s",
10438 bssid, pin, ssid_hex, keymgmt, cipher, passphrase_hex);
10439
10440 if (wpa_command(intf, buf) < 0) {
10441 wpa_ctrl_detach(ctrl);
10442 wpa_ctrl_close(ctrl);
10443 send_resp(dut, conn, SIGMA_ERROR,
10444 "ErrorCode,Failed to start registrar");
10445 return 0;
10446 }
10447
10448 snprintf(dut->er_oper_bssid, sizeof(dut->er_oper_bssid), "%s", bssid);
10449 dut->er_oper_performed = 1;
10450
10451 return wps_connection_event(dut, conn, ctrl, intf, 0);
10452}
10453
10454
10455static int cmd_sta_wps_connect_pw_token(struct sigma_dut *dut,
10456 struct sigma_conn *conn,
10457 struct sigma_cmd *cmd)
10458{
10459 struct wpa_ctrl *ctrl;
10460 const char *intf = get_param(cmd, "Interface");
10461 const char *bssid = get_param(cmd, "Bssid");
10462 char buf[100];
10463
10464 if (!bssid) {
10465 send_resp(dut, conn, SIGMA_ERROR,
10466 "ErrorCode,Missing Bssid argument");
10467 return 0;
10468 }
10469
10470 ctrl = open_wpa_mon(intf);
10471 if (ctrl == NULL) {
10472 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
10473 "wpa_supplicant monitor connection");
10474 return -2;
10475 }
10476
10477 snprintf(buf, sizeof(buf), "WPS_NFC %s", bssid);
10478
10479 if (wpa_command(intf, buf) < 0) {
10480 wpa_ctrl_detach(ctrl);
10481 wpa_ctrl_close(ctrl);
10482 send_resp(dut, conn, SIGMA_ERROR,
10483 "ErrorCode,Failed to start registrar");
10484 return 0;
10485 }
10486
10487 return wps_connection_event(dut, conn, ctrl, intf, 0);
10488}
10489
10490
vamsi krishna9b144002017-09-20 13:28:13 +053010491static int cmd_start_wps_registration(struct sigma_dut *dut,
10492 struct sigma_conn *conn,
10493 struct sigma_cmd *cmd)
10494{
10495 struct wpa_ctrl *ctrl;
10496 const char *intf = get_param(cmd, "Interface");
10497 const char *role, *method;
10498 int res;
10499 char buf[256];
10500 const char *events[] = {
10501 "CTRL-EVENT-CONNECTED",
10502 "WPS-OVERLAP-DETECTED",
10503 "WPS-TIMEOUT",
10504 "WPS-FAIL",
10505 NULL
10506 };
10507
10508 ctrl = open_wpa_mon(intf);
10509 if (!ctrl) {
10510 sigma_dut_print(dut, DUT_MSG_ERROR,
10511 "Failed to open wpa_supplicant monitor connection");
10512 return -2;
10513 }
10514
10515 role = get_param(cmd, "WpsRole");
10516 if (!role) {
10517 send_resp(dut, conn, SIGMA_INVALID,
10518 "ErrorCode,WpsRole not provided");
10519 goto fail;
10520 }
10521
10522 if (strcasecmp(role, "Enrollee") == 0) {
10523 method = get_param(cmd, "WpsConfigMethod");
10524 if (!method) {
10525 send_resp(dut, conn, SIGMA_INVALID,
10526 "ErrorCode,WpsConfigMethod not provided");
10527 goto fail;
10528 }
10529 if (strcasecmp(method, "PBC") == 0) {
10530 if (wpa_command(intf, "WPS_PBC") < 0) {
10531 send_resp(dut, conn, SIGMA_ERROR,
10532 "ErrorCode,Failed to enable PBC");
10533 goto fail;
10534 }
10535 } else {
10536 /* TODO: PIN method */
10537 send_resp(dut, conn, SIGMA_ERROR,
10538 "ErrorCode,Unsupported WpsConfigMethod value");
10539 goto fail;
10540 }
10541 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
10542 if (res < 0) {
10543 send_resp(dut, conn, SIGMA_ERROR,
10544 "ErrorCode,WPS connection did not complete");
10545 goto fail;
10546 }
10547 if (strstr(buf, "WPS-TIMEOUT")) {
10548 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,NoPeer");
10549 } else if (strstr(buf, "WPS-OVERLAP-DETECTED")) {
10550 send_resp(dut, conn, SIGMA_ERROR,
10551 "ErrorCode,OverlapSession");
10552 } else if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
10553 send_resp(dut, conn, SIGMA_COMPLETE, "Successful");
10554 } else {
10555 send_resp(dut, conn, SIGMA_ERROR,
10556 "ErrorCode,WPS operation failed");
10557 }
10558 } else {
10559 /* TODO: Registrar role */
10560 send_resp(dut, conn, SIGMA_ERROR,
10561 "ErrorCode,Unsupported WpsRole value");
10562 }
10563
10564fail:
10565 wpa_ctrl_detach(ctrl);
10566 wpa_ctrl_close(ctrl);
10567 return 0;
10568}
10569
10570
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010571static int req_intf(struct sigma_cmd *cmd)
10572{
10573 return get_param(cmd, "interface") == NULL ? -1 : 0;
10574}
10575
10576
10577void sta_register_cmds(void)
10578{
10579 sigma_dut_reg_cmd("sta_get_ip_config", req_intf,
10580 cmd_sta_get_ip_config);
10581 sigma_dut_reg_cmd("sta_set_ip_config", req_intf,
10582 cmd_sta_set_ip_config);
10583 sigma_dut_reg_cmd("sta_get_info", req_intf, cmd_sta_get_info);
10584 sigma_dut_reg_cmd("sta_get_mac_address", req_intf,
10585 cmd_sta_get_mac_address);
10586 sigma_dut_reg_cmd("sta_is_connected", req_intf, cmd_sta_is_connected);
10587 sigma_dut_reg_cmd("sta_verify_ip_connection", req_intf,
10588 cmd_sta_verify_ip_connection);
10589 sigma_dut_reg_cmd("sta_get_bssid", req_intf, cmd_sta_get_bssid);
10590 sigma_dut_reg_cmd("sta_set_encryption", req_intf,
10591 cmd_sta_set_encryption);
10592 sigma_dut_reg_cmd("sta_set_psk", req_intf, cmd_sta_set_psk);
10593 sigma_dut_reg_cmd("sta_set_eaptls", req_intf, cmd_sta_set_eaptls);
10594 sigma_dut_reg_cmd("sta_set_eapttls", req_intf, cmd_sta_set_eapttls);
10595 sigma_dut_reg_cmd("sta_set_eapsim", req_intf, cmd_sta_set_eapsim);
10596 sigma_dut_reg_cmd("sta_set_peap", req_intf, cmd_sta_set_peap);
10597 sigma_dut_reg_cmd("sta_set_eapfast", req_intf, cmd_sta_set_eapfast);
10598 sigma_dut_reg_cmd("sta_set_eapaka", req_intf, cmd_sta_set_eapaka);
10599 sigma_dut_reg_cmd("sta_set_eapakaprime", req_intf,
10600 cmd_sta_set_eapakaprime);
10601 sigma_dut_reg_cmd("sta_set_security", req_intf, cmd_sta_set_security);
10602 sigma_dut_reg_cmd("sta_set_uapsd", req_intf, cmd_sta_set_uapsd);
10603 /* TODO: sta_set_ibss */
10604 /* TODO: sta_set_mode */
10605 sigma_dut_reg_cmd("sta_set_wmm", req_intf, cmd_sta_set_wmm);
10606 sigma_dut_reg_cmd("sta_associate", req_intf, cmd_sta_associate);
10607 /* TODO: sta_up_load */
10608 sigma_dut_reg_cmd("sta_preset_testparameters", req_intf,
10609 cmd_sta_preset_testparameters);
10610 /* TODO: sta_set_system */
10611 sigma_dut_reg_cmd("sta_set_11n", req_intf, cmd_sta_set_11n);
10612 /* TODO: sta_set_rifs_test */
10613 sigma_dut_reg_cmd("sta_set_wireless", req_intf, cmd_sta_set_wireless);
10614 sigma_dut_reg_cmd("sta_send_addba", req_intf, cmd_sta_send_addba);
10615 /* TODO: sta_send_coexist_mgmt */
10616 sigma_dut_reg_cmd("sta_disconnect", req_intf, cmd_sta_disconnect);
10617 sigma_dut_reg_cmd("sta_reassoc", req_intf, cmd_sta_reassoc);
10618 sigma_dut_reg_cmd("sta_reassociate", req_intf, cmd_sta_reassoc);
10619 sigma_dut_reg_cmd("sta_reset_default", req_intf,
10620 cmd_sta_reset_default);
10621 sigma_dut_reg_cmd("sta_send_frame", req_intf, cmd_sta_send_frame);
10622 sigma_dut_reg_cmd("sta_set_macaddr", req_intf, cmd_sta_set_macaddr);
10623 sigma_dut_reg_cmd("sta_set_rfeature", req_intf, cmd_sta_set_rfeature);
10624 sigma_dut_reg_cmd("sta_set_radio", req_intf, cmd_sta_set_radio);
10625 sigma_dut_reg_cmd("sta_set_pwrsave", req_intf, cmd_sta_set_pwrsave);
10626 sigma_dut_reg_cmd("sta_bssid_pool", req_intf, cmd_sta_bssid_pool);
10627 sigma_dut_reg_cmd("sta_reset_parm", req_intf, cmd_sta_reset_parm);
10628 sigma_dut_reg_cmd("sta_get_key", req_intf, cmd_sta_get_key);
10629 sigma_dut_reg_cmd("sta_hs2_associate", req_intf,
10630 cmd_sta_hs2_associate);
10631 sigma_dut_reg_cmd("sta_add_credential", req_intf,
10632 cmd_sta_add_credential);
10633 sigma_dut_reg_cmd("sta_scan", req_intf, cmd_sta_scan);
Jouni Malinen5e5d43d2018-01-10 17:29:33 +020010634 sigma_dut_reg_cmd("sta_scan_bss", req_intf, cmd_sta_scan_bss);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010635 sigma_dut_reg_cmd("sta_set_systime", NULL, cmd_sta_set_systime);
10636 sigma_dut_reg_cmd("sta_osu", req_intf, cmd_sta_osu);
10637 sigma_dut_reg_cmd("sta_policy_update", req_intf, cmd_sta_policy_update);
10638 sigma_dut_reg_cmd("sta_er_config", NULL, cmd_sta_er_config);
10639 sigma_dut_reg_cmd("sta_wps_connect_pw_token", req_intf,
10640 cmd_sta_wps_connect_pw_token);
Jouni Malinen82905202018-04-29 17:20:10 +030010641 sigma_dut_reg_cmd("sta_exec_action", NULL, cmd_sta_exec_action);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010642 sigma_dut_reg_cmd("sta_get_events", req_intf, cmd_sta_get_events);
10643 sigma_dut_reg_cmd("sta_get_parameter", req_intf, cmd_sta_get_parameter);
vamsi krishna9b144002017-09-20 13:28:13 +053010644 sigma_dut_reg_cmd("start_wps_registration", req_intf,
10645 cmd_start_wps_registration);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010646}