blob: 47eb03d91a95aff55087126ffa3d33eabab1705b [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>
13#ifdef __linux__
Lior Davidcc88b562017-01-03 18:52:09 +020014#include <regex.h>
15#include <dirent.h>
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016#include <sys/time.h>
17#include <netpacket/packet.h>
18#include <linux/if_ether.h>
19#ifdef ANDROID
20#include <cutils/properties.h>
21#include <android/log.h>
22#include "keystore_get.h"
23#else /* ANDROID */
24#include <ifaddrs.h>
25#endif /* ANDROID */
26#include <netdb.h>
27#endif /* __linux__ */
28#ifdef __QNXNTO__
29#include <net/if_dl.h>
30#endif /* __QNXNTO__ */
31#include "wpa_ctrl.h"
32#include "wpa_helpers.h"
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -070033#include "miracast.h"
Jouni Malinencd4e3c32015-10-29 12:39:56 +020034
35/* Temporary files for sta_send_addba */
36#define VI_QOS_TMP_FILE "/tmp/vi-qos.tmp"
37#define VI_QOS_FILE "/tmp/vi-qos.txt"
38#define VI_QOS_REFFILE "/etc/vi-qos.txt"
39
40/*
41 * MTU for Ethernet need to take into account 8-byte SNAP header
42 * to be added when encapsulating Ethernet frame into 802.11
43 */
44#ifndef IEEE80211_MAX_DATA_LEN_DMG
45#define IEEE80211_MAX_DATA_LEN_DMG 7920
46#endif
47#ifndef IEEE80211_SNAP_LEN_DMG
48#define IEEE80211_SNAP_LEN_DMG 8
49#endif
50
Ashwini Patil00402582017-04-13 12:29:39 +053051#define NON_PREF_CH_LIST_SIZE 100
Ashwini Patil5acd7382017-04-13 15:55:04 +053052#define NEIGHBOR_REPORT_SIZE 1000
53#define DEFAULT_NEIGHBOR_BSSID_INFO "17"
54#define DEFAULT_NEIGHBOR_PHY_TYPE "1"
Ashwini Patil00402582017-04-13 12:29:39 +053055
Jouni Malinencd4e3c32015-10-29 12:39:56 +020056extern char *sigma_wpas_ctrl;
57extern char *sigma_cert_path;
58extern enum driver_type wifi_chip_type;
59extern char *sigma_radio_ifname[];
60
Lior David0fe101e2017-03-09 16:09:50 +020061#ifdef __linux__
62#define WIL_WMI_MAX_PAYLOAD 248
63#define WIL_WMI_BF_TRIG_CMDID 0x83a
64
65struct wil_wmi_header {
66 uint8_t mid;
67 uint8_t reserved;
68 uint16_t cmd;
69 uint32_t ts;
70} __attribute__((packed));
71
72enum wil_wmi_bf_trig_type {
73 WIL_WMI_SLS,
74 WIL_WMI_BRP_RX,
75 WIL_WMI_BRP_TX,
76};
77
78struct wil_wmi_bf_trig_cmd {
79 /* enum wil_wmi_bf_trig_type */
80 uint32_t bf_type;
81 /* cid when type == WMI_BRP_RX */
82 uint32_t sta_id;
83 uint32_t reserved;
84 /* mac address when type = WIL_WMI_SLS */
85 uint8_t dest_mac[6];
86} __attribute__((packed));
87#endif /* __linux__ */
Jouni Malinencd4e3c32015-10-29 12:39:56 +020088
89#ifdef ANDROID
90
91static int add_ipv6_rule(struct sigma_dut *dut, const char *ifname);
92
93#define ANDROID_KEYSTORE_GET 'g'
94#define ANDROID_KEYSTORE_GET_PUBKEY 'b'
95
96static int android_keystore_get(char cmd, const char *key, unsigned char *val)
97{
Jouni Malinencd4e3c32015-10-29 12:39:56 +020098 /* Android 4.3 changed keystore design, so need to use keystore_get() */
99#ifndef KEYSTORE_MESSAGE_SIZE
100#define KEYSTORE_MESSAGE_SIZE 65535
101#endif /* KEYSTORE_MESSAGE_SIZE */
102
103 ssize_t len;
104 uint8_t *value = NULL;
105
106 __android_log_print(ANDROID_LOG_DEBUG, "sigma_dut",
107 "keystore command '%c' key '%s' --> keystore_get",
108 cmd, key);
109
110 len = keystore_get(key, strlen(key), &value);
111 if (len < 0) {
112 __android_log_print(ANDROID_LOG_DEBUG, "sigma_dut",
113 "keystore_get() failed");
114 return -1;
115 }
116
117 if (len > KEYSTORE_MESSAGE_SIZE)
118 len = KEYSTORE_MESSAGE_SIZE;
119 memcpy(val, value, len);
120 free(value);
121 return len;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200122}
123#endif /* ANDROID */
124
125
126int set_ps(const char *intf, struct sigma_dut *dut, int enabled)
127{
128#ifdef __linux__
129 char buf[100];
130
131 if (wifi_chip_type == DRIVER_WCN) {
132 if (enabled) {
133 snprintf(buf, sizeof(buf), "iwpriv wlan0 dump 906");
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530134 if (system(buf) != 0)
135 goto set_power_save;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200136 } else {
137 snprintf(buf, sizeof(buf), "iwpriv wlan0 dump 905");
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530138 if (system(buf) != 0)
139 goto set_power_save;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200140 snprintf(buf, sizeof(buf), "iwpriv wlan0 dump 912");
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530141 if (system(buf) != 0)
142 goto set_power_save;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200143 }
144
145 return 0;
146 }
147
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530148set_power_save:
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200149 snprintf(buf, sizeof(buf), "./iw dev %s set power_save %s",
150 intf, enabled ? "on" : "off");
151 if (system(buf) != 0) {
152 snprintf(buf, sizeof(buf), "iw dev %s set power_save %s",
153 intf, enabled ? "on" : "off");
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530154 if (system(buf) != 0) {
155 sigma_dut_print(dut, DUT_MSG_ERROR,
156 "Failed to set power save %s",
157 enabled ? "on" : "off");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200158 return -1;
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530159 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200160 }
161
162 return 0;
163#else /* __linux__ */
164 return -1;
165#endif /* __linux__ */
166}
167
168
Lior Davidcc88b562017-01-03 18:52:09 +0200169#ifdef __linux__
Lior David0fe101e2017-03-09 16:09:50 +0200170
Lior Davidcc88b562017-01-03 18:52:09 +0200171static int wil6210_get_debugfs_dir(struct sigma_dut *dut, char *path,
172 size_t len)
173{
174 DIR *dir, *wil_dir;
175 struct dirent *entry;
176 int ret = -1;
177 const char *root_path = "/sys/kernel/debug/ieee80211";
178
179 dir = opendir(root_path);
180 if (!dir)
181 return -2;
182
183 while ((entry = readdir(dir))) {
184 if (strcmp(entry->d_name, ".") == 0 ||
185 strcmp(entry->d_name, "..") == 0)
186 continue;
187
188 if (snprintf(path, len, "%s/%s/wil6210",
189 root_path, entry->d_name) >= (int) len) {
190 ret = -3;
191 break;
192 }
193
194 wil_dir = opendir(path);
195 if (wil_dir) {
196 closedir(wil_dir);
197 ret = 0;
198 break;
199 }
200 }
201
202 closedir(dir);
203 return ret;
204}
Lior David0fe101e2017-03-09 16:09:50 +0200205
206
207static int wil6210_wmi_send(struct sigma_dut *dut, uint16_t command,
208 void *payload, uint16_t length)
209{
210 struct {
211 struct wil_wmi_header hdr;
212 char payload[WIL_WMI_MAX_PAYLOAD];
213 } __attribute__((packed)) cmd;
214 char buf[128], fname[128];
215 size_t towrite, written;
216 FILE *f;
217
218 if (length > WIL_WMI_MAX_PAYLOAD) {
219 sigma_dut_print(dut, DUT_MSG_ERROR,
220 "payload too large(%u, max %u)",
221 length, WIL_WMI_MAX_PAYLOAD);
222 return -1;
223 }
224
225 memset(&cmd.hdr, 0, sizeof(cmd.hdr));
226 cmd.hdr.cmd = command;
227 memcpy(cmd.payload, payload, length);
228
229 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
230 sigma_dut_print(dut, DUT_MSG_ERROR,
231 "failed to get wil6210 debugfs dir");
232 return -1;
233 }
234
235 snprintf(fname, sizeof(fname), "%s/wmi_send", buf);
236 f = fopen(fname, "wb");
237 if (!f) {
238 sigma_dut_print(dut, DUT_MSG_ERROR,
239 "failed to open: %s", fname);
240 return -1;
241 }
242
243 towrite = sizeof(cmd.hdr) + length;
244 written = fwrite(&cmd, 1, towrite, f);
245 fclose(f);
246 if (written != towrite) {
247 sigma_dut_print(dut, DUT_MSG_ERROR,
248 "failed to send wmi %u", command);
249 return -1;
250 }
251
252 return 0;
253}
254
255
256static int wil6210_get_sta_info_field(struct sigma_dut *dut, const char *bssid,
257 const char *pattern, unsigned int *field)
258{
259 char buf[128], fname[128];
260 FILE *f;
261 regex_t re;
262 regmatch_t m[2];
263 int rc, ret = -1;
264
265 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
266 sigma_dut_print(dut, DUT_MSG_ERROR,
267 "failed to get wil6210 debugfs dir");
268 return -1;
269 }
270
271 snprintf(fname, sizeof(fname), "%s/stations", buf);
272 f = fopen(fname, "r");
273 if (!f) {
274 sigma_dut_print(dut, DUT_MSG_ERROR,
275 "failed to open: %s", fname);
276 return -1;
277 }
278
279 if (regcomp(&re, pattern, REG_EXTENDED)) {
280 sigma_dut_print(dut, DUT_MSG_ERROR,
281 "regcomp failed: %s", pattern);
282 goto out;
283 }
284
285 /*
286 * find the entry for the mac address
287 * line is of the form: [n] 11:22:33:44:55:66 state AID aid
288 */
289 while (fgets(buf, sizeof(buf), f)) {
290 if (strcasestr(buf, bssid)) {
291 /* extract the field (CID/AID/state) */
292 rc = regexec(&re, buf, 2, m, 0);
293 if (!rc && (m[1].rm_so >= 0)) {
294 buf[m[1].rm_eo] = 0;
295 *field = atoi(&buf[m[1].rm_so]);
296 ret = 0;
297 break;
298 }
299 }
300 }
301
302 regfree(&re);
303 if (ret)
304 sigma_dut_print(dut, DUT_MSG_ERROR,
305 "could not extract field");
306
307out:
308 fclose(f);
309
310 return ret;
311}
312
313
314static int wil6210_get_cid(struct sigma_dut *dut, const char *bssid,
315 unsigned int *cid)
316{
317 const char *pattern = "\\[([0-9]+)\\]";
318
319 return wil6210_get_sta_info_field(dut, bssid, pattern, cid);
320}
321
322
323static int wil6210_send_brp_rx(struct sigma_dut *dut, const char *mac,
324 int l_rx)
325{
Rakesh Sunki556237d2017-03-30 14:49:31 -0700326 struct wil_wmi_bf_trig_cmd cmd;
Lior David0fe101e2017-03-09 16:09:50 +0200327 unsigned int cid;
328
Rakesh Sunki556237d2017-03-30 14:49:31 -0700329 memset(&cmd, 0, sizeof(cmd));
330
Lior David0fe101e2017-03-09 16:09:50 +0200331 if (wil6210_get_cid(dut, mac, &cid))
332 return -1;
333
334 cmd.bf_type = WIL_WMI_BRP_RX;
335 cmd.sta_id = cid;
336 /* training length (l_rx) is ignored, FW always uses length 16 */
337 return wil6210_wmi_send(dut, WIL_WMI_BF_TRIG_CMDID,
338 &cmd, sizeof(cmd));
339}
340
341
342static int wil6210_send_sls(struct sigma_dut *dut, const char *mac)
343{
Rakesh Sunki556237d2017-03-30 14:49:31 -0700344 struct wil_wmi_bf_trig_cmd cmd;
345
346 memset(&cmd, 0, sizeof(cmd));
Lior David0fe101e2017-03-09 16:09:50 +0200347
348 if (parse_mac_address(dut, mac, (unsigned char *)&cmd.dest_mac))
349 return -1;
350
351 cmd.bf_type = WIL_WMI_SLS;
352 return wil6210_wmi_send(dut, WIL_WMI_BF_TRIG_CMDID,
353 &cmd, sizeof(cmd));
354}
355
Lior Davidcc88b562017-01-03 18:52:09 +0200356#endif /* __linux__ */
357
358
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200359static void static_ip_file(int proto, const char *addr, const char *mask,
360 const char *gw)
361{
362 if (proto) {
363 FILE *f = fopen("static-ip", "w");
364 if (f) {
365 fprintf(f, "%d %s %s %s\n", proto, addr,
366 mask ? mask : "N/A",
367 gw ? gw : "N/A");
368 fclose(f);
369 }
370 } else {
371 unlink("static-ip");
372 }
373}
374
375
376static int send_neighbor_request(struct sigma_dut *dut, const char *intf,
377 const char *ssid)
378{
379#ifdef __linux__
380 char buf[100];
381
382 snprintf(buf, sizeof(buf), "iwpriv %s neighbor %s",
383 intf, ssid);
384 sigma_dut_print(dut, DUT_MSG_INFO, "Request: %s", buf);
385
386 if (system(buf) != 0) {
387 sigma_dut_print(dut, DUT_MSG_ERROR,
388 "iwpriv neighbor request failed");
389 return -1;
390 }
391
392 sigma_dut_print(dut, DUT_MSG_INFO, "iwpriv neighbor request send");
393
394 return 0;
395#else /* __linux__ */
396 return -1;
397#endif /* __linux__ */
398}
399
400
401static int send_trans_mgmt_query(struct sigma_dut *dut, const char *intf,
Ashwini Patil5acd7382017-04-13 15:55:04 +0530402 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200403{
Ashwini Patil5acd7382017-04-13 15:55:04 +0530404 const char *val;
405 int reason_code = 0;
406 char buf[1024];
407
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200408 /*
409 * In the earlier builds we used WNM_QUERY and in later
410 * builds used WNM_BSS_QUERY.
411 */
412
Ashwini Patil5acd7382017-04-13 15:55:04 +0530413 val = get_param(cmd, "BTMQuery_Reason_Code");
414 if (val)
415 reason_code = atoi(val);
416
417 val = get_param(cmd, "Cand_List");
418 if (val && atoi(val) == 1 && dut->btm_query_cand_list) {
419 snprintf(buf, sizeof(buf), "WNM_BSS_QUERY %d%s", reason_code,
420 dut->btm_query_cand_list);
421 free(dut->btm_query_cand_list);
422 dut->btm_query_cand_list = NULL;
423 } else {
424 snprintf(buf, sizeof(buf), "WNM_BSS_QUERY %d", reason_code);
425 }
426
427 if (wpa_command(intf, buf) != 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200428 sigma_dut_print(dut, DUT_MSG_ERROR,
429 "transition management query failed");
430 return -1;
431 }
432
433 sigma_dut_print(dut, DUT_MSG_DEBUG,
434 "transition management query sent");
435
436 return 0;
437}
438
439
440int is_ip_addr(const char *str)
441{
442 const char *pos = str;
443 struct in_addr addr;
444
445 while (*pos) {
446 if (*pos != '.' && (*pos < '0' || *pos > '9'))
447 return 0;
448 pos++;
449 }
450
451 return inet_aton(str, &addr);
452}
453
454
455int is_ipv6_addr(const char *str)
456{
457 struct sockaddr_in6 addr;
458
459 return inet_pton(AF_INET6, str, &(addr.sin6_addr));
460}
461
462
463int get_ip_config(struct sigma_dut *dut, const char *ifname, char *buf,
464 size_t buf_len)
465{
466 char tmp[256], *pos, *pos2;
467 FILE *f;
468 char ip[16], mask[15], dns[16], sec_dns[16];
Sarvepalli, Rajesh Babua76c6442016-03-18 20:34:26 +0530469 const char *str_ps;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200470 int is_dhcp = 0;
471 int s;
472#ifdef ANDROID
473 char prop[PROPERTY_VALUE_MAX];
474#endif /* ANDROID */
475
476 ip[0] = '\0';
477 mask[0] = '\0';
478 dns[0] = '\0';
479 sec_dns[0] = '\0';
480
481 s = socket(PF_INET, SOCK_DGRAM, 0);
482 if (s >= 0) {
483 struct ifreq ifr;
484 struct sockaddr_in saddr;
485
486 memset(&ifr, 0, sizeof(ifr));
Peng Xub8fc5cc2017-05-10 17:27:28 -0700487 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200488 if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
489 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to get "
490 "%s IP address: %s",
491 ifname, strerror(errno));
492 } else {
493 memcpy(&saddr, &ifr.ifr_addr,
494 sizeof(struct sockaddr_in));
Peng Xub8fc5cc2017-05-10 17:27:28 -0700495 strlcpy(ip, inet_ntoa(saddr.sin_addr), sizeof(ip));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200496 }
497
498 if (ioctl(s, SIOCGIFNETMASK, &ifr) == 0) {
499 memcpy(&saddr, &ifr.ifr_addr,
500 sizeof(struct sockaddr_in));
Peng Xub8fc5cc2017-05-10 17:27:28 -0700501 strlcpy(mask, inet_ntoa(saddr.sin_addr), sizeof(mask));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200502 }
503 close(s);
504 }
505
506#ifdef ANDROID
507 snprintf(tmp, sizeof(tmp), "dhcp.%s.pid", ifname);
508 if (property_get(tmp, prop, NULL) != 0 && atoi(prop) > 0) {
509 snprintf(tmp, sizeof(tmp), "dhcp.%s.result", ifname);
510 if (property_get(tmp, prop, NULL) != 0 &&
511 strcmp(prop, "ok") == 0) {
512 snprintf(tmp, sizeof(tmp), "dhcp.%s.ipaddress",
513 ifname);
514 if (property_get(tmp, prop, NULL) != 0 &&
515 strcmp(ip, prop) == 0)
516 is_dhcp = 1;
517 }
518 }
519
520 snprintf(tmp, sizeof(tmp), "dhcp.%s.dns1", ifname);
Peng Xub8fc5cc2017-05-10 17:27:28 -0700521 if (property_get(tmp, prop, NULL) != 0)
522 strlcpy(dns, prop, sizeof(dns));
523 else if (property_get("net.dns1", prop, NULL) != 0)
524 strlcpy(dns, prop, sizeof(dns));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200525
526 snprintf(tmp, sizeof(tmp), "dhcp.%s.dns2", ifname);
Peng Xub8fc5cc2017-05-10 17:27:28 -0700527 if (property_get(tmp, prop, NULL) != 0)
528 strlcpy(sec_dns, prop, sizeof(sec_dns));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200529#else /* ANDROID */
530#ifdef __linux__
Sarvepalli, Rajesh Babua76c6442016-03-18 20:34:26 +0530531 if (get_driver_type() == DRIVER_OPENWRT)
532 str_ps = "ps -w";
533 else
534 str_ps = "ps ax";
535 snprintf(tmp, sizeof(tmp),
536 "%s | grep dhclient | grep -v grep | grep -q %s",
537 str_ps, ifname);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200538 if (system(tmp) == 0)
539 is_dhcp = 1;
540 else {
Sarvepalli, Rajesh Babua76c6442016-03-18 20:34:26 +0530541 snprintf(tmp, sizeof(tmp),
542 "%s | grep udhcpc | grep -v grep | grep -q %s",
543 str_ps, ifname);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200544 if (system(tmp) == 0)
545 is_dhcp = 1;
546 else {
Sarvepalli, Rajesh Babua76c6442016-03-18 20:34:26 +0530547 snprintf(tmp, sizeof(tmp),
548 "%s | grep dhcpcd | grep -v grep | grep -q %s",
549 str_ps, ifname);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200550 if (system(tmp) == 0)
551 is_dhcp = 1;
552 }
553 }
554#endif /* __linux__ */
555
556 f = fopen("/etc/resolv.conf", "r");
557 if (f) {
558 while (fgets(tmp, sizeof(tmp), f)) {
559 if (strncmp(tmp, "nameserver", 10) != 0)
560 continue;
561 pos = tmp + 10;
562 while (*pos == ' ' || *pos == '\t')
563 pos++;
564 pos2 = pos;
565 while (*pos2) {
566 if (*pos2 == '\n' || *pos2 == '\r') {
567 *pos2 = '\0';
568 break;
569 }
570 pos2++;
571 }
Peng Xub8fc5cc2017-05-10 17:27:28 -0700572 if (!dns[0])
573 strlcpy(dns, pos, sizeof(dns));
574 else if (!sec_dns[0])
575 strlcpy(sec_dns, pos, sizeof(sec_dns));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200576 }
577 fclose(f);
578 }
579#endif /* ANDROID */
580
581 snprintf(buf, buf_len, "dhcp,%d,ip,%s,mask,%s,primary-dns,%s",
582 is_dhcp, ip, mask, dns);
583 buf[buf_len - 1] = '\0';
584
585 return 0;
586}
587
588
589
590
591int get_ipv6_config(struct sigma_dut *dut, const char *ifname, char *buf,
592 size_t buf_len)
593{
594#ifdef __linux__
595#ifdef ANDROID
596 char cmd[200], result[1000], *pos, *end;
597 FILE *f;
598 size_t len;
599
600 snprintf(cmd, sizeof(cmd), "ip addr show dev %s scope global", ifname);
601 f = popen(cmd, "r");
602 if (f == NULL)
603 return -1;
604 len = fread(result, 1, sizeof(result) - 1, f);
605 pclose(f);
606 if (len == 0)
607 return -1;
608 result[len] = '\0';
609 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s result: %s\n", cmd, result);
610
611 pos = strstr(result, "inet6 ");
612 if (pos == NULL)
613 return -1;
614 pos += 6;
615 end = strchr(pos, ' ');
616 if (end)
617 *end = '\0';
618 end = strchr(pos, '/');
619 if (end)
620 *end = '\0';
621 snprintf(buf, buf_len, "ip,%s", pos);
622 buf[buf_len - 1] = '\0';
623 return 0;
624#else /* ANDROID */
625 struct ifaddrs *ifaddr, *ifa;
626 int res, found = 0;
627 char host[NI_MAXHOST];
628
629 if (getifaddrs(&ifaddr) < 0) {
630 perror("getifaddrs");
631 return -1;
632 }
633
634 for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
635 if (strcasecmp(ifname, ifa->ifa_name) != 0)
636 continue;
637 if (ifa->ifa_addr == NULL ||
638 ifa->ifa_addr->sa_family != AF_INET6)
639 continue;
640
641 res = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in6),
642 host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
643 if (res != 0) {
644 sigma_dut_print(dut, DUT_MSG_DEBUG, "getnameinfo: %s",
645 gai_strerror(res));
646 continue;
647 }
648 if (strncmp(host, "fe80::", 6) == 0)
649 continue; /* skip link-local */
650
651 sigma_dut_print(dut, DUT_MSG_DEBUG, "ifaddr: %s", host);
652 found = 1;
653 break;
654 }
655
656 freeifaddrs(ifaddr);
657
658 if (found) {
659 char *pos;
660 pos = strchr(host, '%');
661 if (pos)
662 *pos = '\0';
663 snprintf(buf, buf_len, "ip,%s", host);
664 buf[buf_len - 1] = '\0';
665 return 0;
666 }
667
668#endif /* ANDROID */
669#endif /* __linux__ */
670 return -1;
671}
672
673
674static int cmd_sta_get_ip_config(struct sigma_dut *dut,
675 struct sigma_conn *conn,
676 struct sigma_cmd *cmd)
677{
678 const char *intf = get_param(cmd, "Interface");
679 const char *ifname;
680 char buf[200];
681 const char *val;
682 int type = 1;
683
684 if (intf == NULL)
685 return -1;
686
687 if (strcmp(intf, get_main_ifname()) == 0)
688 ifname = get_station_ifname();
689 else
690 ifname = intf;
691
692 /*
693 * UCC may assume the IP address to be available immediately after
694 * association without trying to run sta_get_ip_config multiple times.
695 * Sigma CAPI does not specify this command as a block command that
696 * would wait for the address to become available, but to pass tests
697 * more reliably, it looks like such a wait may be needed here.
698 */
699 if (wait_ip_addr(dut, ifname, 15) < 0) {
700 sigma_dut_print(dut, DUT_MSG_INFO, "Could not get IP address "
701 "for sta_get_ip_config");
702 /*
703 * Try to continue anyway since many UCC tests do not really
704 * care about the return value from here..
705 */
706 }
707
708 val = get_param(cmd, "Type");
709 if (val)
710 type = atoi(val);
711 if (type == 2 || dut->last_set_ip_config_ipv6) {
712 int i;
713
714 /*
715 * Since we do not have proper wait for IPv6 addresses, use a
716 * fixed two second delay here as a workaround for UCC script
717 * assuming IPv6 address is available when this command returns.
718 * Some scripts did not use Type,2 properly for IPv6, so include
719 * also the cases where the previous sta_set_ip_config indicated
720 * use of IPv6.
721 */
722 sigma_dut_print(dut, DUT_MSG_INFO, "Wait up to extra ten seconds in sta_get_ip_config for IPv6 address");
723 for (i = 0; i < 10; i++) {
724 sleep(1);
725 if (get_ipv6_config(dut, ifname, buf, sizeof(buf)) == 0)
726 {
727 sigma_dut_print(dut, DUT_MSG_INFO, "Found IPv6 address");
728 send_resp(dut, conn, SIGMA_COMPLETE, buf);
729#ifdef ANDROID
730 sigma_dut_print(dut, DUT_MSG_INFO,
731 "Adding IPv6 rule on Android");
732 add_ipv6_rule(dut, intf);
733#endif /* ANDROID */
734
735 return 0;
736 }
737 }
738 }
739 if (type == 1) {
740 if (get_ip_config(dut, ifname, buf, sizeof(buf)) < 0)
741 return -2;
742 } else if (type == 2) {
743 if (get_ipv6_config(dut, ifname, buf, sizeof(buf)) < 0)
744 return -2;
745 } else {
746 send_resp(dut, conn, SIGMA_ERROR,
747 "errorCode,Unsupported address type");
748 return 0;
749 }
750
751 send_resp(dut, conn, SIGMA_COMPLETE, buf);
752 return 0;
753}
754
755
756static void kill_dhcp_client(struct sigma_dut *dut, const char *ifname)
757{
758#ifdef __linux__
759 char buf[200];
760 char path[128];
761 struct stat s;
762
763#ifdef ANDROID
764 snprintf(path, sizeof(path), "/data/misc/dhcp/dhcpcd-%s.pid", ifname);
765#else /* ANDROID */
766 snprintf(path, sizeof(path), "/var/run/dhclient-%s.pid", ifname);
767#endif /* ANDROID */
768 if (stat(path, &s) == 0) {
769 snprintf(buf, sizeof(buf), "kill `cat %s`", path);
770 sigma_dut_print(dut, DUT_MSG_INFO,
771 "Kill previous DHCP client: %s", buf);
772 if (system(buf) != 0)
773 sigma_dut_print(dut, DUT_MSG_INFO,
774 "Failed to kill DHCP client");
775 unlink(path);
776 sleep(1);
777 } else {
778 snprintf(path, sizeof(path), "/var/run/dhcpcd-%s.pid", ifname);
779
780 if (stat(path, &s) == 0) {
781 snprintf(buf, sizeof(buf), "kill `cat %s`", path);
782 sigma_dut_print(dut, DUT_MSG_INFO,
783 "Kill previous DHCP client: %s", buf);
784 if (system(buf) != 0)
785 sigma_dut_print(dut, DUT_MSG_INFO,
786 "Failed to kill DHCP client");
787 unlink(path);
788 sleep(1);
789 }
790 }
791#endif /* __linux__ */
792}
793
794
795static int start_dhcp_client(struct sigma_dut *dut, const char *ifname)
796{
797#ifdef __linux__
798 char buf[200];
799
800#ifdef ANDROID
Purushottam Kushwaha46d64262016-08-23 17:57:53 +0530801 if (access("/system/bin/dhcpcd", F_OK) != -1) {
802 snprintf(buf, sizeof(buf),
803 "/system/bin/dhcpcd -b %s", ifname);
804 } else if (access("/system/bin/dhcptool", F_OK) != -1) {
805 snprintf(buf, sizeof(buf), "/system/bin/dhcptool %s &", ifname);
806 } else {
807 sigma_dut_print(dut, DUT_MSG_ERROR,
808 "DHCP client program missing");
809 return 0;
810 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200811#else /* ANDROID */
812 snprintf(buf, sizeof(buf),
813 "dhclient -nw -pf /var/run/dhclient-%s.pid %s",
814 ifname, ifname);
815#endif /* ANDROID */
816 sigma_dut_print(dut, DUT_MSG_INFO, "Start DHCP client: %s", buf);
817 if (system(buf) != 0) {
818 snprintf(buf, sizeof(buf), "dhcpcd -t 0 %s &", ifname);
819 if (system(buf) != 0) {
820 sigma_dut_print(dut, DUT_MSG_INFO,
821 "Failed to start DHCP client");
822#ifndef ANDROID
823 return -1;
824#endif /* ANDROID */
825 }
826 }
827#endif /* __linux__ */
828
829 return 0;
830}
831
832
833static int clear_ip_addr(struct sigma_dut *dut, const char *ifname)
834{
835#ifdef __linux__
836 char buf[200];
837
838 snprintf(buf, sizeof(buf), "ip addr flush dev %s", ifname);
839 if (system(buf) != 0) {
840 sigma_dut_print(dut, DUT_MSG_INFO,
841 "Failed to clear IP addresses");
842 return -1;
843 }
844#endif /* __linux__ */
845
846 return 0;
847}
848
849
850#ifdef ANDROID
851static int add_ipv6_rule(struct sigma_dut *dut, const char *ifname)
852{
853 char cmd[200], *result, *pos;
854 FILE *fp;
Pradeep Reddy POTTETIf58a1fe2016-10-13 17:22:03 +0530855 int tableid;
856 size_t len, result_len = 1000;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200857
858 snprintf(cmd, sizeof(cmd), "ip -6 route list table all | grep %s",
859 ifname);
860 fp = popen(cmd, "r");
861 if (fp == NULL)
862 return -1;
863
864 result = malloc(result_len);
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +0530865 if (result == NULL) {
866 fclose(fp);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200867 return -1;
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +0530868 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200869
Pradeep Reddy POTTETIf58a1fe2016-10-13 17:22:03 +0530870 len = fread(result, 1, result_len - 1, fp);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200871 fclose(fp);
872
873 if (len == 0) {
874 free(result);
875 return -1;
876 }
Pradeep Reddy POTTETIf58a1fe2016-10-13 17:22:03 +0530877 result[len] = '\0';
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200878
879 pos = strstr(result, "table ");
880 if (pos == NULL) {
881 free(result);
882 return -1;
883 }
884
885 pos += strlen("table ");
886 tableid = atoi(pos);
887 if (tableid != 0) {
888 if (system("ip -6 rule del prio 22000") != 0) {
889 /* ignore any error */
890 }
891 snprintf(cmd, sizeof(cmd),
892 "ip -6 rule add from all lookup %d prio 22000",
893 tableid);
894 if (system(cmd) != 0) {
895 sigma_dut_print(dut, DUT_MSG_INFO,
896 "Failed to run %s", cmd);
897 free(result);
898 return -1;
899 }
900 } else {
901 sigma_dut_print(dut, DUT_MSG_INFO,
902 "No Valid Table Id found %s", pos);
903 free(result);
904 return -1;
905 }
906 free(result);
907
908 return 0;
909}
910#endif /* ANDROID */
911
912
Ankita Bajaj1bde7942018-01-09 19:15:01 +0530913int set_ipv4_addr(struct sigma_dut *dut, const char *ifname,
914 const char *ip, const char *mask)
915{
916 char buf[200];
917
918 snprintf(buf, sizeof(buf), "ifconfig %s %s netmask %s",
919 ifname, ip, mask);
920 return system(buf) == 0;
921}
922
923
924int set_ipv4_gw(struct sigma_dut *dut, const char *gw)
925{
926 char buf[200];
927
928 if (!is_ip_addr(gw)) {
929 sigma_dut_print(dut, DUT_MSG_DEBUG, "Invalid gw addr - %s", gw);
930 return -1;
931 }
932
933 snprintf(buf, sizeof(buf), "route add default gw %s", gw);
934 if (!dut->no_ip_addr_set && system(buf) != 0) {
935 snprintf(buf, sizeof(buf), "ip ro re default via %s",
936 gw);
937 if (system(buf) != 0)
938 return 0;
939 }
940
941 return 1;
942}
943
944
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200945static int cmd_sta_set_ip_config(struct sigma_dut *dut,
946 struct sigma_conn *conn,
947 struct sigma_cmd *cmd)
948{
949 const char *intf = get_param(cmd, "Interface");
950 const char *ifname;
951 char buf[200];
952 const char *val, *ip, *mask, *gw;
953 int type = 1;
954
955 if (intf == NULL)
956 return -1;
957
958 if (strcmp(intf, get_main_ifname()) == 0)
959 ifname = get_station_ifname();
960 else
961 ifname = intf;
962
963 if (if_nametoindex(ifname) == 0) {
964 send_resp(dut, conn, SIGMA_ERROR,
965 "ErrorCode,Unknown interface");
966 return 0;
967 }
968
969 val = get_param(cmd, "Type");
970 if (val) {
971 type = atoi(val);
Ankita Bajaj1bde7942018-01-09 19:15:01 +0530972 if (type < 1 || type > 3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200973 send_resp(dut, conn, SIGMA_ERROR,
974 "ErrorCode,Unsupported address type");
975 return 0;
976 }
977 }
978
979 dut->last_set_ip_config_ipv6 = 0;
980
981 val = get_param(cmd, "dhcp");
982 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "true") == 0)) {
983 static_ip_file(0, NULL, NULL, NULL);
984#ifdef __linux__
985 if (type == 2) {
986 dut->last_set_ip_config_ipv6 = 1;
987 sigma_dut_print(dut, DUT_MSG_INFO, "Using IPv6 "
988 "stateless address autoconfiguration");
989#ifdef ANDROID
990 /*
991 * This sleep is required as the assignment in case of
992 * Android is taking time and is done by the kernel.
993 * The subsequent ping for IPv6 is impacting HS20 test
994 * case.
995 */
996 sleep(2);
997 add_ipv6_rule(dut, intf);
998#endif /* ANDROID */
999 /* Assume this happens by default */
1000 return 1;
1001 }
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301002 if (type != 3) {
1003 kill_dhcp_client(dut, ifname);
1004 if (start_dhcp_client(dut, ifname) < 0)
1005 return -2;
1006 } else {
1007 sigma_dut_print(dut, DUT_MSG_DEBUG,
1008 "Using FILS HLP DHCPv4 Rapid Commit");
1009 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001010
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001011 return 1;
1012#endif /* __linux__ */
1013 return -2;
1014 }
1015
1016 ip = get_param(cmd, "ip");
Pradeep Reddy POTTETIb18c5652016-01-18 12:45:37 +05301017 if (!ip) {
1018 send_resp(dut, conn, SIGMA_INVALID,
1019 "ErrorCode,Missing IP address");
1020 return 0;
1021 }
1022
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001023 mask = get_param(cmd, "mask");
Pradeep Reddy POTTETIb18c5652016-01-18 12:45:37 +05301024 if (!mask) {
1025 send_resp(dut, conn, SIGMA_INVALID,
1026 "ErrorCode,Missing subnet mask");
1027 return 0;
1028 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001029
1030 if (type == 2) {
1031 int net = atoi(mask);
1032
1033 if ((net < 0 && net > 64) || !is_ipv6_addr(ip))
1034 return -1;
1035
1036 if (dut->no_ip_addr_set) {
1037 snprintf(buf, sizeof(buf),
1038 "sysctl net.ipv6.conf.%s.disable_ipv6=1",
1039 ifname);
1040 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
1041 if (system(buf) != 0) {
1042 sigma_dut_print(dut, DUT_MSG_DEBUG,
1043 "Failed to disable IPv6 address before association");
1044 }
1045 } else {
1046 snprintf(buf, sizeof(buf),
1047 "ip -6 addr del %s/%s dev %s",
1048 ip, mask, ifname);
1049 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
1050 if (system(buf) != 0) {
1051 /*
1052 * This command may fail if the address being
1053 * deleted does not exist. Inaction here is
1054 * intentional.
1055 */
1056 }
1057
1058 snprintf(buf, sizeof(buf),
1059 "ip -6 addr add %s/%s dev %s",
1060 ip, mask, ifname);
1061 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
1062 if (system(buf) != 0) {
1063 send_resp(dut, conn, SIGMA_ERROR,
1064 "ErrorCode,Failed to set IPv6 address");
1065 return 0;
1066 }
1067 }
1068
1069 dut->last_set_ip_config_ipv6 = 1;
1070 static_ip_file(6, ip, mask, NULL);
1071 return 1;
1072 } else if (type == 1) {
Pradeep Reddy POTTETIb18c5652016-01-18 12:45:37 +05301073 if (!is_ip_addr(ip) || !is_ip_addr(mask))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001074 return -1;
1075 }
1076
1077 kill_dhcp_client(dut, ifname);
1078
1079 if (!dut->no_ip_addr_set) {
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301080 if (!set_ipv4_addr(dut, ifname, ip, mask)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001081 send_resp(dut, conn, SIGMA_ERROR,
1082 "ErrorCode,Failed to set IP address");
1083 return 0;
1084 }
1085 }
1086
1087 gw = get_param(cmd, "defaultGateway");
1088 if (gw) {
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301089 if (set_ipv4_gw(dut, gw) < 1) {
1090 send_resp(dut, conn, SIGMA_ERROR,
1091 "ErrorCode,Failed to set default gateway");
1092 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001093 }
1094 }
1095
1096 val = get_param(cmd, "primary-dns");
1097 if (val) {
1098 /* TODO */
1099 sigma_dut_print(dut, DUT_MSG_INFO, "Ignored primary-dns %s "
1100 "setting", val);
1101 }
1102
1103 val = get_param(cmd, "secondary-dns");
1104 if (val) {
1105 /* TODO */
1106 sigma_dut_print(dut, DUT_MSG_INFO, "Ignored secondary-dns %s "
1107 "setting", val);
1108 }
1109
1110 static_ip_file(4, ip, mask, gw);
1111
1112 return 1;
1113}
1114
1115
1116static int cmd_sta_get_info(struct sigma_dut *dut, struct sigma_conn *conn,
1117 struct sigma_cmd *cmd)
1118{
1119 /* const char *intf = get_param(cmd, "Interface"); */
1120 /* TODO: could report more details here */
1121 send_resp(dut, conn, SIGMA_COMPLETE, "vendor,Atheros");
1122 return 0;
1123}
1124
1125
1126static int cmd_sta_get_mac_address(struct sigma_dut *dut,
1127 struct sigma_conn *conn,
1128 struct sigma_cmd *cmd)
1129{
1130 /* const char *intf = get_param(cmd, "Interface"); */
1131 char addr[20], resp[50];
1132
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05301133 if (dut->dev_role == DEVROLE_STA_CFON)
1134 return sta_cfon_get_mac_address(dut, conn, cmd);
1135
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001136 if (get_wpa_status(get_station_ifname(), "address", addr, sizeof(addr))
1137 < 0)
1138 return -2;
1139
1140 snprintf(resp, sizeof(resp), "mac,%s", addr);
1141 send_resp(dut, conn, SIGMA_COMPLETE, resp);
1142 return 0;
1143}
1144
1145
1146static int cmd_sta_is_connected(struct sigma_dut *dut, struct sigma_conn *conn,
1147 struct sigma_cmd *cmd)
1148{
1149 /* const char *intf = get_param(cmd, "Interface"); */
1150 int connected = 0;
1151 char result[32];
1152 if (get_wpa_status(get_station_ifname(), "wpa_state", result,
1153 sizeof(result)) < 0) {
1154 sigma_dut_print(dut, DUT_MSG_INFO, "Could not get interface "
1155 "%s status", get_station_ifname());
1156 return -2;
1157 }
1158
1159 sigma_dut_print(dut, DUT_MSG_DEBUG, "wpa_state=%s", result);
1160 if (strncmp(result, "COMPLETED", 9) == 0)
1161 connected = 1;
1162
1163 if (connected)
1164 send_resp(dut, conn, SIGMA_COMPLETE, "connected,1");
1165 else
1166 send_resp(dut, conn, SIGMA_COMPLETE, "connected,0");
1167
1168 return 0;
1169}
1170
1171
1172static int cmd_sta_verify_ip_connection(struct sigma_dut *dut,
1173 struct sigma_conn *conn,
1174 struct sigma_cmd *cmd)
1175{
1176 /* const char *intf = get_param(cmd, "Interface"); */
1177 const char *dst, *timeout;
1178 int wait_time = 90;
1179 char buf[100];
1180 int res;
1181
1182 dst = get_param(cmd, "destination");
1183 if (dst == NULL || !is_ip_addr(dst))
1184 return -1;
1185
1186 timeout = get_param(cmd, "timeout");
1187 if (timeout) {
1188 wait_time = atoi(timeout);
1189 if (wait_time < 1)
1190 wait_time = 1;
1191 }
1192
1193 /* TODO: force renewal of IP lease if DHCP is enabled */
1194
1195 snprintf(buf, sizeof(buf), "ping %s -c 3 -W %d", dst, wait_time);
1196 res = system(buf);
1197 sigma_dut_print(dut, DUT_MSG_DEBUG, "ping returned: %d", res);
1198 if (res == 0)
1199 send_resp(dut, conn, SIGMA_COMPLETE, "connected,1");
1200 else if (res == 256)
1201 send_resp(dut, conn, SIGMA_COMPLETE, "connected,0");
1202 else
1203 return -2;
1204
1205 return 0;
1206}
1207
1208
1209static int cmd_sta_get_bssid(struct sigma_dut *dut, struct sigma_conn *conn,
1210 struct sigma_cmd *cmd)
1211{
1212 /* const char *intf = get_param(cmd, "Interface"); */
1213 char bssid[20], resp[50];
1214
1215 if (get_wpa_status(get_station_ifname(), "bssid", bssid, sizeof(bssid))
1216 < 0)
Peng Xub8fc5cc2017-05-10 17:27:28 -07001217 strlcpy(bssid, "00:00:00:00:00:00", sizeof(bssid));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001218
1219 snprintf(resp, sizeof(resp), "bssid,%s", bssid);
1220 send_resp(dut, conn, SIGMA_COMPLETE, resp);
1221 return 0;
1222}
1223
1224
1225#ifdef __SAMSUNG__
1226static int add_use_network(const char *ifname)
1227{
1228 char buf[100];
1229
1230 snprintf(buf, sizeof(buf), "USE_NETWORK ON");
1231 wpa_command(ifname, buf);
1232 return 0;
1233}
1234#endif /* __SAMSUNG__ */
1235
1236
1237static int add_network_common(struct sigma_dut *dut, struct sigma_conn *conn,
1238 const char *ifname, struct sigma_cmd *cmd)
1239{
1240 const char *ssid = get_param(cmd, "ssid");
1241 int id;
1242 const char *val;
1243
1244 if (ssid == NULL)
1245 return -1;
1246
1247 start_sta_mode(dut);
1248
1249#ifdef __SAMSUNG__
1250 add_use_network(ifname);
1251#endif /* __SAMSUNG__ */
1252
1253 id = add_network(ifname);
1254 if (id < 0)
1255 return -2;
1256 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding network %d", id);
1257
1258 if (set_network_quoted(ifname, id, "ssid", ssid) < 0)
1259 return -2;
1260
1261 dut->infra_network_id = id;
1262 snprintf(dut->infra_ssid, sizeof(dut->infra_ssid), "%s", ssid);
1263
1264 val = get_param(cmd, "program");
1265 if (!val)
1266 val = get_param(cmd, "prog");
1267 if (val && strcasecmp(val, "hs2") == 0) {
1268 char buf[100];
1269 snprintf(buf, sizeof(buf), "ENABLE_NETWORK %d no-connect", id);
1270 wpa_command(ifname, buf);
1271
1272 val = get_param(cmd, "prefer");
1273 if (val && atoi(val) > 0)
1274 set_network(ifname, id, "priority", "1");
1275 }
1276
1277 return id;
1278}
1279
1280
1281static int cmd_sta_set_encryption(struct sigma_dut *dut,
1282 struct sigma_conn *conn,
1283 struct sigma_cmd *cmd)
1284{
1285 const char *intf = get_param(cmd, "Interface");
1286 const char *ssid = get_param(cmd, "ssid");
1287 const char *type = get_param(cmd, "encpType");
1288 const char *ifname;
1289 char buf[200];
1290 int id;
1291
1292 if (intf == NULL || ssid == NULL)
1293 return -1;
1294
1295 if (strcmp(intf, get_main_ifname()) == 0)
1296 ifname = get_station_ifname();
1297 else
1298 ifname = intf;
1299
1300 id = add_network_common(dut, conn, ifname, cmd);
1301 if (id < 0)
1302 return id;
1303
1304 if (set_network(ifname, id, "key_mgmt", "NONE") < 0)
1305 return -2;
1306
1307 if (type && strcasecmp(type, "wep") == 0) {
1308 const char *val;
1309 int i;
1310
1311 val = get_param(cmd, "activeKey");
1312 if (val) {
1313 int keyid;
1314 keyid = atoi(val);
1315 if (keyid < 1 || keyid > 4)
1316 return -1;
1317 snprintf(buf, sizeof(buf), "%d", keyid - 1);
1318 if (set_network(ifname, id, "wep_tx_keyidx", buf) < 0)
1319 return -2;
1320 }
1321
1322 for (i = 0; i < 4; i++) {
1323 snprintf(buf, sizeof(buf), "key%d", i + 1);
1324 val = get_param(cmd, buf);
1325 if (val == NULL)
1326 continue;
1327 snprintf(buf, sizeof(buf), "wep_key%d", i);
1328 if (set_network(ifname, id, buf, val) < 0)
1329 return -2;
1330 }
1331 }
1332
1333 return 1;
1334}
1335
1336
1337static int set_wpa_common(struct sigma_dut *dut, struct sigma_conn *conn,
1338 const char *ifname, struct sigma_cmd *cmd)
1339{
1340 const char *val;
1341 int id;
Jouni Malinenad395a22017-09-01 21:13:46 +03001342 int cipher_set = 0;
Jouni Malinen47dcc952017-10-09 16:43:24 +03001343 int owe;
Sunil Duttc75a1e62018-01-11 20:47:50 +05301344 int suite_b = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001345
1346 id = add_network_common(dut, conn, ifname, cmd);
1347 if (id < 0)
1348 return id;
1349
Jouni Malinen47dcc952017-10-09 16:43:24 +03001350 val = get_param(cmd, "Type");
1351 owe = val && strcasecmp(val, "OWE") == 0;
1352
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001353 val = get_param(cmd, "keyMgmtType");
Jouni Malinen47dcc952017-10-09 16:43:24 +03001354 if (!val && owe)
1355 val = "OWE";
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001356 if (val == NULL) {
1357 send_resp(dut, conn, SIGMA_INVALID, "errorCode,Missing keyMgmtType");
1358 return 0;
1359 }
1360 if (strcasecmp(val, "wpa") == 0 ||
1361 strcasecmp(val, "wpa-psk") == 0) {
1362 if (set_network(ifname, id, "proto", "WPA") < 0)
1363 return -2;
1364 } else if (strcasecmp(val, "wpa2") == 0 ||
1365 strcasecmp(val, "wpa2-psk") == 0 ||
1366 strcasecmp(val, "wpa2-ft") == 0 ||
1367 strcasecmp(val, "wpa2-sha256") == 0) {
1368 if (set_network(ifname, id, "proto", "WPA2") < 0)
1369 return -2;
Pradeep Reddy POTTETI6d04b3b2016-11-15 14:51:26 +05301370 } else if (strcasecmp(val, "wpa2-wpa-psk") == 0 ||
1371 strcasecmp(val, "wpa2-wpa-ent") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001372 if (set_network(ifname, id, "proto", "WPA WPA2") < 0)
1373 return -2;
Jouni Malinenad395a22017-09-01 21:13:46 +03001374 } else if (strcasecmp(val, "SuiteB") == 0) {
Sunil Duttc75a1e62018-01-11 20:47:50 +05301375 suite_b = 1;
Jouni Malinenad395a22017-09-01 21:13:46 +03001376 if (set_network(ifname, id, "proto", "WPA2") < 0)
1377 return -2;
Jouni Malinen47dcc952017-10-09 16:43:24 +03001378 } else if (strcasecmp(val, "OWE") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001379 } else {
1380 send_resp(dut, conn, SIGMA_INVALID, "errorCode,Unrecognized keyMgmtType value");
1381 return 0;
1382 }
1383
1384 val = get_param(cmd, "encpType");
Jouni Malinenad395a22017-09-01 21:13:46 +03001385 if (val) {
1386 cipher_set = 1;
1387 if (strcasecmp(val, "tkip") == 0) {
1388 if (set_network(ifname, id, "pairwise", "TKIP") < 0)
1389 return -2;
1390 } else if (strcasecmp(val, "aes-ccmp") == 0) {
1391 if (set_network(ifname, id, "pairwise", "CCMP") < 0)
1392 return -2;
1393 } else if (strcasecmp(val, "aes-ccmp-tkip") == 0) {
1394 if (set_network(ifname, id, "pairwise",
1395 "CCMP TKIP") < 0)
1396 return -2;
1397 } else if (strcasecmp(val, "aes-gcmp") == 0) {
1398 if (set_network(ifname, id, "pairwise", "GCMP") < 0)
1399 return -2;
1400 if (set_network(ifname, id, "group", "GCMP") < 0)
1401 return -2;
1402 } else {
1403 send_resp(dut, conn, SIGMA_ERROR,
1404 "errorCode,Unrecognized encpType value");
1405 return 0;
1406 }
1407 }
1408
1409 val = get_param(cmd, "PairwiseCipher");
1410 if (val) {
1411 cipher_set = 1;
1412 /* TODO: Support space separated list */
1413 if (strcasecmp(val, "AES-GCMP-256") == 0) {
1414 if (set_network(ifname, id, "pairwise", "GCMP-256") < 0)
1415 return -2;
1416 } else if (strcasecmp(val, "AES-CCMP-256") == 0) {
1417 if (set_network(ifname, id, "pairwise",
1418 "CCMP-256") < 0)
1419 return -2;
1420 } else if (strcasecmp(val, "AES-GCMP-128") == 0) {
1421 if (set_network(ifname, id, "pairwise", "GCMP") < 0)
1422 return -2;
1423 } else if (strcasecmp(val, "AES-CCMP-128") == 0) {
1424 if (set_network(ifname, id, "pairwise", "CCMP") < 0)
1425 return -2;
1426 } else {
1427 send_resp(dut, conn, SIGMA_ERROR,
1428 "errorCode,Unrecognized PairwiseCipher value");
1429 return 0;
1430 }
1431 }
1432
Jouni Malinen47dcc952017-10-09 16:43:24 +03001433 if (!cipher_set && !owe) {
Jouni Malinenad395a22017-09-01 21:13:46 +03001434 send_resp(dut, conn, SIGMA_ERROR,
1435 "errorCode,Missing encpType and PairwiseCipher");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001436 return 0;
1437 }
Jouni Malinenad395a22017-09-01 21:13:46 +03001438
1439 val = get_param(cmd, "GroupCipher");
1440 if (val) {
1441 if (strcasecmp(val, "AES-GCMP-256") == 0) {
1442 if (set_network(ifname, id, "group", "GCMP-256") < 0)
1443 return -2;
1444 } else if (strcasecmp(val, "AES-CCMP-256") == 0) {
1445 if (set_network(ifname, id, "group", "CCMP-256") < 0)
1446 return -2;
1447 } else if (strcasecmp(val, "AES-GCMP-128") == 0) {
1448 if (set_network(ifname, id, "group", "GCMP") < 0)
1449 return -2;
1450 } else if (strcasecmp(val, "AES-CCMP-128") == 0) {
1451 if (set_network(ifname, id, "group", "CCMP") < 0)
1452 return -2;
1453 } else {
1454 send_resp(dut, conn, SIGMA_ERROR,
1455 "errorCode,Unrecognized GroupCipher value");
1456 return 0;
1457 }
1458 }
1459
Jouni Malinen7b239522017-09-14 21:37:18 +03001460 val = get_param(cmd, "GroupMgntCipher");
Jouni Malinenad395a22017-09-01 21:13:46 +03001461 if (val) {
Jouni Malinene8898cb2017-09-26 17:55:26 +03001462 const char *cipher;
1463
1464 if (strcasecmp(val, "BIP-GMAC-256") == 0) {
1465 cipher = "BIP-GMAC-256";
1466 } else if (strcasecmp(val, "BIP-CMAC-256") == 0) {
1467 cipher = "BIP-CMAC-256";
1468 } else if (strcasecmp(val, "BIP-GMAC-128") == 0) {
1469 cipher = "BIP-GMAC-128";
1470 } else if (strcasecmp(val, "BIP-CMAC-128") == 0) {
1471 cipher = "AES-128-CMAC";
1472 } else {
1473 send_resp(dut, conn, SIGMA_INVALID,
1474 "errorCode,Unsupported GroupMgntCipher");
1475 return 0;
1476 }
1477 if (set_network(ifname, id, "group_mgmt", cipher) < 0) {
1478 send_resp(dut, conn, SIGMA_INVALID,
1479 "errorCode,Failed to set GroupMgntCipher");
1480 return 0;
1481 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001482 }
1483
1484 dut->sta_pmf = STA_PMF_DISABLED;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05301485
1486 if (dut->program == PROGRAM_OCE) {
1487 dut->sta_pmf = STA_PMF_OPTIONAL;
1488 if (set_network(ifname, id, "ieee80211w", "1") < 0)
1489 return -2;
1490 }
1491
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001492 val = get_param(cmd, "PMF");
1493 if (val) {
1494 if (strcasecmp(val, "Required") == 0 ||
1495 strcasecmp(val, "Forced_Required") == 0) {
1496 dut->sta_pmf = STA_PMF_REQUIRED;
1497 if (set_network(ifname, id, "ieee80211w", "2") < 0)
1498 return -2;
1499 } else if (strcasecmp(val, "Optional") == 0) {
1500 dut->sta_pmf = STA_PMF_OPTIONAL;
1501 if (set_network(ifname, id, "ieee80211w", "1") < 0)
1502 return -2;
1503 } else if (strcasecmp(val, "Disabled") == 0 ||
1504 strcasecmp(val, "Forced_Disabled") == 0) {
1505 dut->sta_pmf = STA_PMF_DISABLED;
1506 } else {
1507 send_resp(dut, conn, SIGMA_INVALID, "errorCode,Unrecognized PMF value");
1508 return 0;
1509 }
Sunil Duttc75a1e62018-01-11 20:47:50 +05301510 } else if (owe || suite_b) {
Jouni Malinen1287cd72018-01-04 17:08:01 +02001511 dut->sta_pmf = STA_PMF_REQUIRED;
1512 if (set_network(ifname, id, "ieee80211w", "2") < 0)
1513 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001514 }
1515
1516 return id;
1517}
1518
1519
1520static int cmd_sta_set_psk(struct sigma_dut *dut, struct sigma_conn *conn,
1521 struct sigma_cmd *cmd)
1522{
1523 const char *intf = get_param(cmd, "Interface");
Jouni Malinen992a81e2017-08-22 13:57:47 +03001524 const char *type = get_param(cmd, "Type");
Jouni Malinen1287cd72018-01-04 17:08:01 +02001525 const char *pmf = get_param(cmd, "PMF");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001526 const char *ifname, *val, *alg;
1527 int id;
1528
1529 if (intf == NULL)
1530 return -1;
1531
1532 if (strcmp(intf, get_main_ifname()) == 0)
1533 ifname = get_station_ifname();
1534 else
1535 ifname = intf;
1536
1537 id = set_wpa_common(dut, conn, ifname, cmd);
1538 if (id < 0)
1539 return id;
1540
1541 val = get_param(cmd, "keyMgmtType");
1542 alg = get_param(cmd, "micAlg");
1543
Jouni Malinen992a81e2017-08-22 13:57:47 +03001544 if (type && strcasecmp(type, "SAE") == 0) {
1545 if (val && strcasecmp(val, "wpa2-ft") == 0) {
1546 if (set_network(ifname, id, "key_mgmt", "FT-SAE") < 0)
1547 return -2;
1548 } else {
1549 if (set_network(ifname, id, "key_mgmt", "SAE") < 0)
1550 return -2;
1551 }
1552 if (wpa_command(ifname, "SET sae_groups ") != 0) {
1553 sigma_dut_print(dut, DUT_MSG_ERROR,
1554 "Failed to clear sae_groups to default");
1555 return -2;
1556 }
Jouni Malinen1287cd72018-01-04 17:08:01 +02001557 if (!pmf) {
1558 dut->sta_pmf = STA_PMF_REQUIRED;
1559 if (set_network(ifname, id, "ieee80211w", "2") < 0)
1560 return -2;
1561 }
Jouni Malinen0ab50f42017-08-31 01:34:59 +03001562 } else if (type && strcasecmp(type, "PSK-SAE") == 0) {
1563 if (val && strcasecmp(val, "wpa2-ft") == 0) {
1564 if (set_network(ifname, id, "key_mgmt",
1565 "FT-SAE FT-PSK") < 0)
1566 return -2;
1567 } else {
1568 if (set_network(ifname, id, "key_mgmt",
1569 "SAE WPA-PSK") < 0)
1570 return -2;
1571 }
1572 if (wpa_command(ifname, "SET sae_groups ") != 0) {
1573 sigma_dut_print(dut, DUT_MSG_ERROR,
1574 "Failed to clear sae_groups to default");
1575 return -2;
1576 }
Jouni Malinen1287cd72018-01-04 17:08:01 +02001577 if (!pmf) {
1578 dut->sta_pmf = STA_PMF_OPTIONAL;
1579 if (set_network(ifname, id, "ieee80211w", "1") < 0)
1580 return -2;
1581 }
Jouni Malinen992a81e2017-08-22 13:57:47 +03001582 } else if (alg && strcasecmp(alg, "SHA-256") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001583 if (set_network(ifname, id, "key_mgmt", "WPA-PSK-SHA256") < 0)
1584 return -2;
1585 } else if (alg && strcasecmp(alg, "SHA-1") == 0) {
1586 if (set_network(ifname, id, "key_mgmt", "WPA-PSK") < 0)
1587 return -2;
Ashwini Patil6dbf7b02017-03-20 13:42:11 +05301588 } else if (val && strcasecmp(val, "wpa2-ft") == 0) {
1589 if (set_network(ifname, id, "key_mgmt", "FT-PSK") < 0)
1590 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001591 } else if ((val && strcasecmp(val, "wpa2-sha256") == 0) ||
1592 dut->sta_pmf == STA_PMF_REQUIRED) {
1593 if (set_network(ifname, id, "key_mgmt",
1594 "WPA-PSK WPA-PSK-SHA256") < 0)
1595 return -2;
1596 } else if (dut->sta_pmf == STA_PMF_OPTIONAL) {
1597 if (set_network(ifname, id, "key_mgmt",
1598 "WPA-PSK WPA-PSK-SHA256") < 0)
1599 return -2;
1600 } else {
1601 if (set_network(ifname, id, "key_mgmt", "WPA-PSK") < 0)
1602 return -2;
1603 }
1604
1605 val = get_param(cmd, "passPhrase");
1606 if (val == NULL)
1607 return -1;
Jouni Malinen2126f422017-10-11 23:24:33 +03001608 if (type && strcasecmp(type, "SAE") == 0) {
1609 if (set_network_quoted(ifname, id, "sae_password", val) < 0)
1610 return -2;
1611 } else {
1612 if (set_network_quoted(ifname, id, "psk", val) < 0)
1613 return -2;
1614 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001615
Jouni Malinen992a81e2017-08-22 13:57:47 +03001616 val = get_param(cmd, "ECGroupID");
1617 if (val) {
1618 char buf[50];
1619
1620 snprintf(buf, sizeof(buf), "SET sae_groups %u", atoi(val));
1621 if (wpa_command(ifname, buf) != 0) {
1622 sigma_dut_print(dut, DUT_MSG_ERROR,
1623 "Failed to clear sae_groups");
1624 return -2;
1625 }
1626 }
1627
Jouni Malinen68143132017-09-02 02:34:08 +03001628 val = get_param(cmd, "InvalidSAEElement");
1629 if (val) {
1630 free(dut->sae_commit_override);
1631 dut->sae_commit_override = strdup(val);
1632 }
1633
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001634 return 1;
1635}
1636
1637
1638static int set_eap_common(struct sigma_dut *dut, struct sigma_conn *conn,
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05301639 const char *ifname, int username_identity,
1640 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001641{
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05301642 const char *val, *alg, *akm;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001643 int id;
1644 char buf[200];
1645#ifdef ANDROID
1646 unsigned char kvalue[KEYSTORE_MESSAGE_SIZE];
1647 int length;
1648#endif /* ANDROID */
1649
1650 id = set_wpa_common(dut, conn, ifname, cmd);
1651 if (id < 0)
1652 return id;
1653
1654 val = get_param(cmd, "keyMgmtType");
1655 alg = get_param(cmd, "micAlg");
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05301656 akm = get_param(cmd, "AKMSuiteType");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001657
Jouni Malinenad395a22017-09-01 21:13:46 +03001658 if (val && strcasecmp(val, "SuiteB") == 0) {
1659 if (set_network(ifname, id, "key_mgmt", "WPA-EAP-SUITE-B-192") <
1660 0)
1661 return -2;
1662 } else if (alg && strcasecmp(alg, "SHA-256") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001663 if (set_network(ifname, id, "key_mgmt", "WPA-EAP-SHA256") < 0)
1664 return -2;
1665 } else if (alg && strcasecmp(alg, "SHA-1") == 0) {
1666 if (set_network(ifname, id, "key_mgmt", "WPA-EAP") < 0)
1667 return -2;
1668 } else if (val && strcasecmp(val, "wpa2-ft") == 0) {
1669 if (set_network(ifname, id, "key_mgmt", "FT-EAP") < 0)
1670 return -2;
1671 } else if ((val && strcasecmp(val, "wpa2-sha256") == 0) ||
1672 dut->sta_pmf == STA_PMF_REQUIRED) {
1673 if (set_network(ifname, id, "key_mgmt",
1674 "WPA-EAP WPA-EAP-SHA256") < 0)
1675 return -2;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05301676 } else if (akm && atoi(akm) == 14) {
1677 if (dut->sta_pmf == STA_PMF_OPTIONAL ||
1678 dut->sta_pmf == STA_PMF_REQUIRED) {
1679 if (set_network(ifname, id, "key_mgmt",
1680 "WPA-EAP-SHA256 FILS-SHA256") < 0)
1681 return -2;
1682 } else {
1683 if (set_network(ifname, id, "key_mgmt",
1684 "WPA-EAP FILS-SHA256") < 0)
1685 return -2;
1686 }
1687
1688 if (set_network(ifname, id, "erp", "1") < 0)
1689 return -2;
1690 } else if (akm && atoi(akm) == 15) {
1691 if (dut->sta_pmf == STA_PMF_OPTIONAL ||
1692 dut->sta_pmf == STA_PMF_REQUIRED) {
1693 if (set_network(ifname, id, "key_mgmt",
1694 "WPA-EAP-SHA256 FILS-SHA384") < 0)
1695 return -2;
1696 } else {
1697 if (set_network(ifname, id, "key_mgmt",
1698 "WPA-EAP FILS-SHA384") < 0)
1699 return -2;
1700 }
1701
1702 if (set_network(ifname, id, "erp", "1") < 0)
1703 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001704 } else if (dut->sta_pmf == STA_PMF_OPTIONAL) {
1705 if (set_network(ifname, id, "key_mgmt",
1706 "WPA-EAP WPA-EAP-SHA256") < 0)
1707 return -2;
1708 } else {
1709 if (set_network(ifname, id, "key_mgmt", "WPA-EAP") < 0)
1710 return -2;
1711 }
1712
1713 val = get_param(cmd, "trustedRootCA");
1714 if (val) {
1715#ifdef ANDROID
1716 snprintf(buf, sizeof(buf), "CACERT_%s", val);
1717 length = android_keystore_get(ANDROID_KEYSTORE_GET, buf,
1718 kvalue);
1719 if (length > 0) {
1720 sigma_dut_print(dut, DUT_MSG_INFO,
1721 "Use Android keystore [%s]", buf);
1722 snprintf(buf, sizeof(buf), "keystore://CACERT_%s",
1723 val);
1724 goto ca_cert_selected;
1725 }
1726#endif /* ANDROID */
1727
1728 snprintf(buf, sizeof(buf), "%s/%s", sigma_cert_path, val);
1729#ifdef __linux__
1730 if (!file_exists(buf)) {
1731 char msg[300];
1732 snprintf(msg, sizeof(msg), "ErrorCode,trustedRootCA "
1733 "file (%s) not found", buf);
1734 send_resp(dut, conn, SIGMA_ERROR, msg);
1735 return -3;
1736 }
1737#endif /* __linux__ */
1738#ifdef ANDROID
1739ca_cert_selected:
1740#endif /* ANDROID */
1741 if (set_network_quoted(ifname, id, "ca_cert", buf) < 0)
1742 return -2;
1743 }
1744
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05301745 if (username_identity) {
1746 val = get_param(cmd, "username");
1747 if (val) {
1748 if (set_network_quoted(ifname, id, "identity", val) < 0)
1749 return -2;
1750 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001751
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05301752 val = get_param(cmd, "password");
1753 if (val) {
1754 if (set_network_quoted(ifname, id, "password", val) < 0)
1755 return -2;
1756 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001757 }
1758
1759 return id;
1760}
1761
1762
Jouni Malinen5eabb2a2017-10-03 18:17:30 +03001763static int set_tls_cipher(const char *ifname, int id, const char *cipher)
1764{
1765 const char *val;
1766
1767 if (!cipher)
1768 return 0;
1769
1770 if (strcasecmp(cipher, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384") == 0)
1771 val = "ECDHE-ECDSA-AES256-GCM-SHA384";
1772 else if (strcasecmp(cipher,
1773 "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384") == 0)
1774 val = "ECDHE-RSA-AES256-GCM-SHA384";
1775 else if (strcasecmp(cipher, "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384") == 0)
1776 val = "DHE-RSA-AES256-GCM-SHA384";
1777 else if (strcasecmp(cipher,
1778 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256") == 0)
1779 val = "ECDHE-ECDSA-AES128-GCM-SHA256";
1780 else
1781 return -1;
1782
1783 /* Need to clear phase1="tls_suiteb=1" to allow cipher enforcement */
1784 set_network_quoted(ifname, id, "phase1", "");
1785
1786 return set_network_quoted(ifname, id, "openssl_ciphers", val);
1787}
1788
1789
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001790static int cmd_sta_set_eaptls(struct sigma_dut *dut, struct sigma_conn *conn,
1791 struct sigma_cmd *cmd)
1792{
1793 const char *intf = get_param(cmd, "Interface");
1794 const char *ifname, *val;
1795 int id;
1796 char buf[200];
1797#ifdef ANDROID
1798 unsigned char kvalue[KEYSTORE_MESSAGE_SIZE];
1799 int length;
1800 int jb_or_newer = 0;
1801 char prop[PROPERTY_VALUE_MAX];
1802#endif /* ANDROID */
1803
1804 if (intf == NULL)
1805 return -1;
1806
1807 if (strcmp(intf, get_main_ifname()) == 0)
1808 ifname = get_station_ifname();
1809 else
1810 ifname = intf;
1811
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05301812 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001813 if (id < 0)
1814 return id;
1815
1816 if (set_network(ifname, id, "eap", "TLS") < 0)
1817 return -2;
1818
Pradeep Reddy POTTETI9f6c2132016-05-05 16:28:19 +05301819 if (!get_param(cmd, "username") &&
1820 set_network_quoted(ifname, id, "identity",
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001821 "wifi-user@wifilabs.local") < 0)
1822 return -2;
1823
1824 val = get_param(cmd, "clientCertificate");
1825 if (val == NULL)
1826 return -1;
1827#ifdef ANDROID
1828 snprintf(buf, sizeof(buf), "USRPKEY_%s", val);
1829 length = android_keystore_get(ANDROID_KEYSTORE_GET, buf, kvalue);
1830 if (length < 0) {
1831 /*
1832 * JB started reporting keystore type mismatches, so retry with
1833 * the GET_PUBKEY command if the generic GET fails.
1834 */
1835 length = android_keystore_get(ANDROID_KEYSTORE_GET_PUBKEY,
1836 buf, kvalue);
1837 }
1838
1839 if (property_get("ro.build.version.release", prop, NULL) != 0) {
1840 sigma_dut_print(dut, DUT_MSG_DEBUG, "Android release %s", prop);
1841 if (strncmp(prop, "4.0", 3) != 0)
1842 jb_or_newer = 1;
1843 } else
1844 jb_or_newer = 1; /* assume newer */
1845
1846 if (jb_or_newer && length > 0) {
1847 sigma_dut_print(dut, DUT_MSG_INFO,
1848 "Use Android keystore [%s]", buf);
1849 if (set_network(ifname, id, "engine", "1") < 0)
1850 return -2;
1851 if (set_network_quoted(ifname, id, "engine_id", "keystore") < 0)
1852 return -2;
1853 snprintf(buf, sizeof(buf), "USRPKEY_%s", val);
1854 if (set_network_quoted(ifname, id, "key_id", buf) < 0)
1855 return -2;
1856 snprintf(buf, sizeof(buf), "keystore://USRCERT_%s", val);
1857 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
1858 return -2;
1859 return 1;
1860 } else if (length > 0) {
1861 sigma_dut_print(dut, DUT_MSG_INFO,
1862 "Use Android keystore [%s]", buf);
1863 snprintf(buf, sizeof(buf), "keystore://USRPKEY_%s", val);
1864 if (set_network_quoted(ifname, id, "private_key", buf) < 0)
1865 return -2;
1866 snprintf(buf, sizeof(buf), "keystore://USRCERT_%s", val);
1867 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
1868 return -2;
1869 return 1;
1870 }
1871#endif /* ANDROID */
1872
1873 snprintf(buf, sizeof(buf), "%s/%s", sigma_cert_path, val);
1874#ifdef __linux__
1875 if (!file_exists(buf)) {
1876 char msg[300];
1877 snprintf(msg, sizeof(msg), "ErrorCode,clientCertificate file "
1878 "(%s) not found", buf);
1879 send_resp(dut, conn, SIGMA_ERROR, msg);
1880 return -3;
1881 }
1882#endif /* __linux__ */
1883 if (set_network_quoted(ifname, id, "private_key", buf) < 0)
1884 return -2;
1885 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
1886 return -2;
1887
1888 if (set_network_quoted(ifname, id, "private_key_passwd", "wifi") < 0)
1889 return -2;
1890
Jouni Malinen5eabb2a2017-10-03 18:17:30 +03001891 val = get_param(cmd, "keyMgmtType");
1892 if (val && strcasecmp(val, "SuiteB") == 0) {
1893 val = get_param(cmd, "CertType");
1894 if (val && strcasecmp(val, "RSA") == 0) {
1895 if (set_network_quoted(ifname, id, "phase1",
1896 "tls_suiteb=1") < 0)
1897 return -2;
1898 } else {
1899 if (set_network_quoted(ifname, id, "openssl_ciphers",
1900 "SUITEB192") < 0)
1901 return -2;
1902 }
1903
1904 val = get_param(cmd, "TLSCipher");
1905 if (set_tls_cipher(ifname, id, val) < 0) {
1906 send_resp(dut, conn, SIGMA_ERROR,
1907 "ErrorCode,Unsupported TLSCipher value");
1908 return -3;
1909 }
1910 }
1911
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001912 return 1;
1913}
1914
1915
1916static int cmd_sta_set_eapttls(struct sigma_dut *dut, struct sigma_conn *conn,
1917 struct sigma_cmd *cmd)
1918{
1919 const char *intf = get_param(cmd, "Interface");
1920 const char *ifname;
1921 int id;
1922
1923 if (intf == NULL)
1924 return -1;
1925
1926 if (strcmp(intf, get_main_ifname()) == 0)
1927 ifname = get_station_ifname();
1928 else
1929 ifname = intf;
1930
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05301931 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001932 if (id < 0)
1933 return id;
1934
1935 if (set_network(ifname, id, "eap", "TTLS") < 0) {
1936 send_resp(dut, conn, SIGMA_ERROR,
1937 "errorCode,Failed to set TTLS method");
1938 return 0;
1939 }
1940
1941 if (set_network_quoted(ifname, id, "phase2", "auth=MSCHAPV2") < 0) {
1942 send_resp(dut, conn, SIGMA_ERROR,
1943 "errorCode,Failed to set MSCHAPv2 for TTLS Phase 2");
1944 return 0;
1945 }
1946
1947 return 1;
1948}
1949
1950
1951static int cmd_sta_set_eapsim(struct sigma_dut *dut, struct sigma_conn *conn,
1952 struct sigma_cmd *cmd)
1953{
1954 const char *intf = get_param(cmd, "Interface");
1955 const char *ifname;
1956 int id;
1957
1958 if (intf == NULL)
1959 return -1;
1960
1961 if (strcmp(intf, get_main_ifname()) == 0)
1962 ifname = get_station_ifname();
1963 else
1964 ifname = intf;
1965
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05301966 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001967 if (id < 0)
1968 return id;
1969
1970 if (set_network(ifname, id, "eap", "SIM") < 0)
1971 return -2;
1972
1973 return 1;
1974}
1975
1976
1977static int cmd_sta_set_peap(struct sigma_dut *dut, struct sigma_conn *conn,
1978 struct sigma_cmd *cmd)
1979{
1980 const char *intf = get_param(cmd, "Interface");
1981 const char *ifname, *val;
1982 int id;
1983 char buf[100];
1984
1985 if (intf == NULL)
1986 return -1;
1987
1988 if (strcmp(intf, get_main_ifname()) == 0)
1989 ifname = get_station_ifname();
1990 else
1991 ifname = intf;
1992
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05301993 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001994 if (id < 0)
1995 return id;
1996
1997 if (set_network(ifname, id, "eap", "PEAP") < 0)
1998 return -2;
1999
2000 val = get_param(cmd, "innerEAP");
2001 if (val) {
2002 if (strcasecmp(val, "MSCHAPv2") == 0) {
2003 if (set_network_quoted(ifname, id, "phase2",
2004 "auth=MSCHAPV2") < 0)
2005 return -2;
2006 } else if (strcasecmp(val, "GTC") == 0) {
2007 if (set_network_quoted(ifname, id, "phase2",
2008 "auth=GTC") < 0)
2009 return -2;
2010 } else
2011 return -1;
2012 }
2013
2014 val = get_param(cmd, "peapVersion");
2015 if (val) {
2016 int ver = atoi(val);
2017 if (ver < 0 || ver > 1)
2018 return -1;
2019 snprintf(buf, sizeof(buf), "peapver=%d", ver);
2020 if (set_network_quoted(ifname, id, "phase1", buf) < 0)
2021 return -2;
2022 }
2023
2024 return 1;
2025}
2026
2027
2028static int cmd_sta_set_eapfast(struct sigma_dut *dut, struct sigma_conn *conn,
2029 struct sigma_cmd *cmd)
2030{
2031 const char *intf = get_param(cmd, "Interface");
2032 const char *ifname, *val;
2033 int id;
2034 char buf[100];
2035
2036 if (intf == NULL)
2037 return -1;
2038
2039 if (strcmp(intf, get_main_ifname()) == 0)
2040 ifname = get_station_ifname();
2041 else
2042 ifname = intf;
2043
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302044 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002045 if (id < 0)
2046 return id;
2047
2048 if (set_network(ifname, id, "eap", "FAST") < 0)
2049 return -2;
2050
2051 val = get_param(cmd, "innerEAP");
2052 if (val) {
2053 if (strcasecmp(val, "MSCHAPV2") == 0) {
2054 if (set_network_quoted(ifname, id, "phase2",
2055 "auth=MSCHAPV2") < 0)
2056 return -2;
2057 } else if (strcasecmp(val, "GTC") == 0) {
2058 if (set_network_quoted(ifname, id, "phase2",
2059 "auth=GTC") < 0)
2060 return -2;
2061 } else
2062 return -1;
2063 }
2064
2065 val = get_param(cmd, "validateServer");
2066 if (val) {
2067 /* TODO */
2068 sigma_dut_print(dut, DUT_MSG_INFO, "Ignored EAP-FAST "
2069 "validateServer=%s", val);
2070 }
2071
2072 val = get_param(cmd, "pacFile");
2073 if (val) {
2074 snprintf(buf, sizeof(buf), "blob://%s", val);
2075 if (set_network_quoted(ifname, id, "pac_file", buf) < 0)
2076 return -2;
2077 }
2078
2079 if (set_network_quoted(ifname, id, "phase1", "fast_provisioning=2") <
2080 0)
2081 return -2;
2082
2083 return 1;
2084}
2085
2086
2087static int cmd_sta_set_eapaka(struct sigma_dut *dut, struct sigma_conn *conn,
2088 struct sigma_cmd *cmd)
2089{
2090 const char *intf = get_param(cmd, "Interface");
2091 const char *ifname;
2092 int id;
2093
2094 if (intf == NULL)
2095 return -1;
2096
2097 if (strcmp(intf, get_main_ifname()) == 0)
2098 ifname = get_station_ifname();
2099 else
2100 ifname = intf;
2101
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302102 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002103 if (id < 0)
2104 return id;
2105
2106 if (set_network(ifname, id, "eap", "AKA") < 0)
2107 return -2;
2108
2109 return 1;
2110}
2111
2112
2113static int cmd_sta_set_eapakaprime(struct sigma_dut *dut,
2114 struct sigma_conn *conn,
2115 struct sigma_cmd *cmd)
2116{
2117 const char *intf = get_param(cmd, "Interface");
2118 const char *ifname;
2119 int id;
2120
2121 if (intf == NULL)
2122 return -1;
2123
2124 if (strcmp(intf, get_main_ifname()) == 0)
2125 ifname = get_station_ifname();
2126 else
2127 ifname = intf;
2128
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302129 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002130 if (id < 0)
2131 return id;
2132
2133 if (set_network(ifname, id, "eap", "AKA'") < 0)
2134 return -2;
2135
2136 return 1;
2137}
2138
2139
2140static int sta_set_open(struct sigma_dut *dut, struct sigma_conn *conn,
2141 struct sigma_cmd *cmd)
2142{
2143 const char *intf = get_param(cmd, "Interface");
2144 const char *ifname;
2145 int id;
2146
2147 if (strcmp(intf, get_main_ifname()) == 0)
2148 ifname = get_station_ifname();
2149 else
2150 ifname = intf;
2151
2152 id = add_network_common(dut, conn, ifname, cmd);
2153 if (id < 0)
2154 return id;
2155
2156 if (set_network(ifname, id, "key_mgmt", "NONE") < 0)
2157 return -2;
2158
2159 return 1;
2160}
2161
2162
Jouni Malinen47dcc952017-10-09 16:43:24 +03002163static int sta_set_owe(struct sigma_dut *dut, struct sigma_conn *conn,
2164 struct sigma_cmd *cmd)
2165{
2166 const char *intf = get_param(cmd, "Interface");
2167 const char *ifname, *val;
2168 int id;
2169
2170 if (intf == NULL)
2171 return -1;
2172
2173 if (strcmp(intf, get_main_ifname()) == 0)
2174 ifname = get_station_ifname();
2175 else
2176 ifname = intf;
2177
2178 id = set_wpa_common(dut, conn, ifname, cmd);
2179 if (id < 0)
2180 return id;
2181
2182 if (set_network(ifname, id, "key_mgmt", "OWE") < 0)
2183 return -2;
2184
2185 val = get_param(cmd, "ECGroupID");
Jouni Malinenfac9cad2017-10-10 18:35:55 +03002186 if (val && strcmp(val, "0") == 0) {
2187 if (wpa_command(ifname,
2188 "VENDOR_ELEM_ADD 13 ff23200000783590fb7440e03d5b3b33911f86affdcc6b4411b707846ac4ff08ddc8831ccd") != 0) {
2189 sigma_dut_print(dut, DUT_MSG_ERROR,
2190 "Failed to set OWE DH Param element override");
2191 return -2;
2192 }
2193 } else if (val && set_network(ifname, id, "owe_group", val) < 0) {
Jouni Malinen47dcc952017-10-09 16:43:24 +03002194 sigma_dut_print(dut, DUT_MSG_ERROR,
2195 "Failed to clear owe_group");
2196 return -2;
2197 }
2198
2199 return 1;
2200}
2201
2202
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002203static int cmd_sta_set_security(struct sigma_dut *dut, struct sigma_conn *conn,
2204 struct sigma_cmd *cmd)
2205{
2206 const char *type = get_param(cmd, "Type");
2207
2208 if (type == NULL) {
2209 send_resp(dut, conn, SIGMA_ERROR,
2210 "ErrorCode,Missing Type argument");
2211 return 0;
2212 }
2213
2214 if (strcasecmp(type, "OPEN") == 0)
2215 return sta_set_open(dut, conn, cmd);
Jouni Malinen47dcc952017-10-09 16:43:24 +03002216 if (strcasecmp(type, "OWE") == 0)
2217 return sta_set_owe(dut, conn, cmd);
Jouni Malinen992a81e2017-08-22 13:57:47 +03002218 if (strcasecmp(type, "PSK") == 0 ||
Jouni Malinen0ab50f42017-08-31 01:34:59 +03002219 strcasecmp(type, "PSK-SAE") == 0 ||
Jouni Malinen992a81e2017-08-22 13:57:47 +03002220 strcasecmp(type, "SAE") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002221 return cmd_sta_set_psk(dut, conn, cmd);
2222 if (strcasecmp(type, "EAPTLS") == 0)
2223 return cmd_sta_set_eaptls(dut, conn, cmd);
2224 if (strcasecmp(type, "EAPTTLS") == 0)
2225 return cmd_sta_set_eapttls(dut, conn, cmd);
2226 if (strcasecmp(type, "EAPPEAP") == 0)
2227 return cmd_sta_set_peap(dut, conn, cmd);
2228 if (strcasecmp(type, "EAPSIM") == 0)
2229 return cmd_sta_set_eapsim(dut, conn, cmd);
2230 if (strcasecmp(type, "EAPFAST") == 0)
2231 return cmd_sta_set_eapfast(dut, conn, cmd);
2232 if (strcasecmp(type, "EAPAKA") == 0)
2233 return cmd_sta_set_eapaka(dut, conn, cmd);
2234 if (strcasecmp(type, "EAPAKAPRIME") == 0)
2235 return cmd_sta_set_eapakaprime(dut, conn, cmd);
2236
2237 send_resp(dut, conn, SIGMA_ERROR,
2238 "ErrorCode,Unsupported Type value");
2239 return 0;
2240}
2241
2242
2243int ath6kl_client_uapsd(struct sigma_dut *dut, const char *intf, int uapsd)
2244{
2245#ifdef __linux__
2246 /* special handling for ath6kl */
2247 char path[128], fname[128], *pos;
2248 ssize_t res;
2249 FILE *f;
2250
2251 snprintf(path, sizeof(path), "/sys/class/net/%s/phy80211", intf);
2252 res = readlink(path, path, sizeof(path));
2253 if (res < 0)
2254 return 0; /* not ath6kl */
2255
2256 if (res >= (int) sizeof(path))
2257 res = sizeof(path) - 1;
2258 path[res] = '\0';
2259 pos = strrchr(path, '/');
2260 if (pos == NULL)
2261 pos = path;
2262 else
2263 pos++;
2264 snprintf(fname, sizeof(fname),
2265 "/sys/kernel/debug/ieee80211/%s/ath6kl/"
2266 "create_qos", pos);
2267 if (!file_exists(fname))
2268 return 0; /* not ath6kl */
2269
2270 if (uapsd) {
2271 f = fopen(fname, "w");
2272 if (f == NULL)
2273 return -1;
2274
2275 sigma_dut_print(dut, DUT_MSG_DEBUG, "Use ath6kl create_qos");
2276 fprintf(f, "4 2 2 1 2 9999999 9999999 9999999 7777777 0 4 "
2277 "45000 200 56789000 56789000 5678900 0 0 9999999 "
2278 "20000 0\n");
2279 fclose(f);
2280 } else {
2281 snprintf(fname, sizeof(fname),
2282 "/sys/kernel/debug/ieee80211/%s/ath6kl/"
2283 "delete_qos", pos);
2284
2285 f = fopen(fname, "w");
2286 if (f == NULL)
2287 return -1;
2288
2289 sigma_dut_print(dut, DUT_MSG_DEBUG, "Use ath6kl delete_qos");
2290 fprintf(f, "2 4\n");
2291 fclose(f);
2292 }
2293#endif /* __linux__ */
2294
2295 return 0;
2296}
2297
2298
2299static int cmd_sta_set_uapsd(struct sigma_dut *dut, struct sigma_conn *conn,
2300 struct sigma_cmd *cmd)
2301{
2302 const char *intf = get_param(cmd, "Interface");
2303 /* const char *ssid = get_param(cmd, "ssid"); */
2304 const char *val;
2305 int max_sp_len = 4;
2306 int ac_be = 1, ac_bk = 1, ac_vi = 1, ac_vo = 1;
2307 char buf[100];
2308 int ret1, ret2;
2309
2310 val = get_param(cmd, "maxSPLength");
2311 if (val) {
2312 max_sp_len = atoi(val);
2313 if (max_sp_len != 0 && max_sp_len != 1 && max_sp_len != 2 &&
2314 max_sp_len != 4)
2315 return -1;
2316 }
2317
2318 val = get_param(cmd, "acBE");
2319 if (val)
2320 ac_be = atoi(val);
2321
2322 val = get_param(cmd, "acBK");
2323 if (val)
2324 ac_bk = atoi(val);
2325
2326 val = get_param(cmd, "acVI");
2327 if (val)
2328 ac_vi = atoi(val);
2329
2330 val = get_param(cmd, "acVO");
2331 if (val)
2332 ac_vo = atoi(val);
2333
2334 dut->client_uapsd = ac_be || ac_bk || ac_vi || ac_vo;
2335
2336 snprintf(buf, sizeof(buf), "P2P_SET client_apsd %d,%d,%d,%d;%d",
2337 ac_be, ac_bk, ac_vi, ac_vo, max_sp_len);
2338 ret1 = wpa_command(intf, buf);
2339
2340 snprintf(buf, sizeof(buf), "SET uapsd %d,%d,%d,%d;%d",
2341 ac_be, ac_bk, ac_vi, ac_vo, max_sp_len);
2342 ret2 = wpa_command(intf, buf);
2343
2344 if (ret1 && ret2) {
2345 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to set client mode "
2346 "UAPSD parameters.");
2347 return -2;
2348 }
2349
2350 if (ath6kl_client_uapsd(dut, intf, dut->client_uapsd) < 0) {
2351 send_resp(dut, conn, SIGMA_ERROR,
2352 "ErrorCode,Failed to set ath6kl QoS parameters");
2353 return 0;
2354 }
2355
2356 return 1;
2357}
2358
2359
2360static int cmd_sta_set_wmm(struct sigma_dut *dut, struct sigma_conn *conn,
2361 struct sigma_cmd *cmd)
2362{
2363 char buf[1000];
2364 const char *intf = get_param(cmd, "Interface");
2365 const char *grp = get_param(cmd, "Group");
2366 const char *act = get_param(cmd, "Action");
2367 const char *tid = get_param(cmd, "Tid");
2368 const char *dir = get_param(cmd, "Direction");
2369 const char *psb = get_param(cmd, "Psb");
2370 const char *up = get_param(cmd, "Up");
2371 const char *fixed = get_param(cmd, "Fixed");
2372 const char *size = get_param(cmd, "Size");
2373 const char *msize = get_param(cmd, "Maxsize");
2374 const char *minsi = get_param(cmd, "Min_srvc_intrvl");
2375 const char *maxsi = get_param(cmd, "Max_srvc_intrvl");
2376 const char *inact = get_param(cmd, "Inactivity");
2377 const char *sus = get_param(cmd, "Suspension");
2378 const char *mindr = get_param(cmd, "Mindatarate");
2379 const char *meandr = get_param(cmd, "Meandatarate");
2380 const char *peakdr = get_param(cmd, "Peakdatarate");
2381 const char *phyrate = get_param(cmd, "Phyrate");
2382 const char *burstsize = get_param(cmd, "Burstsize");
2383 const char *sba = get_param(cmd, "Sba");
2384 int direction;
2385 int handle;
Peng Xu93319622017-10-04 17:58:16 -07002386 float sba_fv = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002387 int fixed_int;
2388 int psb_ts;
2389
2390 if (intf == NULL || grp == NULL || act == NULL )
2391 return -1;
2392
2393 if (strcasecmp(act, "addts") == 0) {
2394 if (tid == NULL || dir == NULL || psb == NULL ||
2395 up == NULL || fixed == NULL || size == NULL)
2396 return -1;
2397
2398 /*
2399 * Note: Sigma CAPI spec lists uplink, downlink, and bidi as the
2400 * possible values, but WMM-AC and V-E test scripts use "UP,
2401 * "DOWN", and "BIDI".
2402 */
2403 if (strcasecmp(dir, "uplink") == 0 ||
2404 strcasecmp(dir, "up") == 0) {
2405 direction = 0;
2406 } else if (strcasecmp(dir, "downlink") == 0 ||
2407 strcasecmp(dir, "down") == 0) {
2408 direction = 1;
2409 } else if (strcasecmp(dir, "bidi") == 0) {
2410 direction = 2;
2411 } else {
2412 sigma_dut_print(dut, DUT_MSG_ERROR,
2413 "Direction %s not supported", dir);
2414 return -1;
2415 }
2416
2417 if (strcasecmp(psb, "legacy") == 0) {
2418 psb_ts = 0;
2419 } else if (strcasecmp(psb, "uapsd") == 0) {
2420 psb_ts = 1;
2421 } else {
2422 sigma_dut_print(dut, DUT_MSG_ERROR,
2423 "PSB %s not supported", psb);
2424 return -1;
2425 }
2426
2427 if (atoi(tid) < 0 || atoi(tid) > 7) {
2428 sigma_dut_print(dut, DUT_MSG_ERROR,
2429 "TID %s not supported", tid);
2430 return -1;
2431 }
2432
2433 if (strcasecmp(fixed, "true") == 0) {
2434 fixed_int = 1;
2435 } else {
2436 fixed_int = 0;
2437 }
2438
Peng Xu93319622017-10-04 17:58:16 -07002439 if (sba)
2440 sba_fv = atof(sba);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002441
2442 dut->dialog_token++;
2443 handle = 7000 + dut->dialog_token;
2444
2445 /*
2446 * size: convert to hex
2447 * maxsi: convert to hex
2448 * mindr: convert to hex
2449 * meandr: convert to hex
2450 * peakdr: convert to hex
2451 * burstsize: convert to hex
2452 * phyrate: convert to hex
2453 * sba: convert to hex with modification
2454 * minsi: convert to integer
2455 * sus: convert to integer
2456 * inact: convert to integer
2457 * maxsi: convert to integer
2458 */
2459
2460 /*
2461 * The Nominal MSDU Size field is 2 octets long and contains an
2462 * unsigned integer that specifies the nominal size, in octets,
2463 * of MSDUs belonging to the traffic under this traffic
2464 * specification and is defined in Figure 16. If the Fixed
2465 * subfield is set to 1, then the size of the MSDU is fixed and
2466 * is indicated by the Size Subfield. If the Fixed subfield is
2467 * set to 0, then the size of the MSDU might not be fixed and
2468 * the Size indicates the nominal MSDU size.
2469 *
2470 * The Surplus Bandwidth Allowance Factor field is 2 octets long
2471 * and specifies the excess allocation of time (and bandwidth)
2472 * over and above the stated rates required to transport an MSDU
2473 * belonging to the traffic in this TSPEC. This field is
2474 * represented as an unsigned binary number with an implicit
2475 * binary point after the leftmost 3 bits. For example, an SBA
2476 * of 1.75 is represented as 0x3800. This field is included to
2477 * account for retransmissions. As such, the value of this field
2478 * must be greater than unity.
2479 */
2480
2481 snprintf(buf, sizeof(buf),
2482 "iwpriv %s addTspec %d %s %d %d %s 0x%X"
2483 " 0x%X 0x%X 0x%X"
2484 " 0x%X 0x%X 0x%X"
2485 " 0x%X %d %d %d %d"
2486 " %d %d",
2487 intf, handle, tid, direction, psb_ts, up,
2488 (unsigned int) ((fixed_int << 15) | atoi(size)),
2489 msize ? atoi(msize) : 0,
2490 mindr ? atoi(mindr) : 0,
2491 meandr ? atoi(meandr) : 0,
2492 peakdr ? atoi(peakdr) : 0,
2493 burstsize ? atoi(burstsize) : 0,
2494 phyrate ? atoi(phyrate) : 0,
2495 sba ? ((unsigned int) (((int) sba_fv << 13) |
2496 (int)((sba_fv - (int) sba_fv) *
2497 8192))) : 0,
2498 minsi ? atoi(minsi) : 0,
2499 sus ? atoi(sus) : 0,
2500 0, 0,
2501 inact ? atoi(inact) : 0,
2502 maxsi ? atoi(maxsi) : 0);
2503
2504 if (system(buf) != 0) {
2505 sigma_dut_print(dut, DUT_MSG_ERROR,
2506 "iwpriv addtspec request failed");
2507 send_resp(dut, conn, SIGMA_ERROR,
2508 "errorCode,Failed to execute addTspec command");
2509 return 0;
2510 }
2511
2512 sigma_dut_print(dut, DUT_MSG_INFO,
2513 "iwpriv addtspec request send");
2514
2515 /* Mapping handle to a TID */
2516 dut->tid_to_handle[atoi(tid)] = handle;
2517 } else if (strcasecmp(act, "delts") == 0) {
2518 if (tid == NULL)
2519 return -1;
2520
2521 if (atoi(tid) < 0 || atoi(tid) > 7) {
2522 sigma_dut_print(dut, DUT_MSG_ERROR,
2523 "TID %s not supported", tid);
2524 send_resp(dut, conn, SIGMA_ERROR,
2525 "errorCode,Unsupported TID");
2526 return 0;
2527 }
2528
2529 handle = dut->tid_to_handle[atoi(tid)];
2530
2531 if (handle < 7000 || handle > 7255) {
2532 /* Invalid handle ie no mapping for that TID */
2533 sigma_dut_print(dut, DUT_MSG_ERROR,
2534 "handle-> %d not found", handle);
2535 }
2536
2537 snprintf(buf, sizeof(buf), "iwpriv %s delTspec %d",
2538 intf, handle);
2539
2540 if (system(buf) != 0) {
2541 sigma_dut_print(dut, DUT_MSG_ERROR,
2542 "iwpriv deltspec request failed");
2543 send_resp(dut, conn, SIGMA_ERROR,
2544 "errorCode,Failed to execute delTspec command");
2545 return 0;
2546 }
2547
2548 sigma_dut_print(dut, DUT_MSG_INFO,
2549 "iwpriv deltspec request send");
2550
2551 dut->tid_to_handle[atoi(tid)] = 0;
2552 } else {
2553 sigma_dut_print(dut, DUT_MSG_ERROR,
2554 "Action type %s not supported", act);
2555 send_resp(dut, conn, SIGMA_ERROR,
2556 "errorCode,Unsupported Action");
2557 return 0;
2558 }
2559
2560 return 1;
2561}
2562
2563
vamsi krishna52e16f92017-08-29 12:37:34 +05302564static int find_network(struct sigma_dut *dut, const char *ssid)
2565{
2566 char list[4096];
2567 char *pos;
2568
2569 sigma_dut_print(dut, DUT_MSG_DEBUG,
2570 "Search for profile based on SSID: '%s'", ssid);
2571 if (wpa_command_resp(get_station_ifname(), "LIST_NETWORKS",
2572 list, sizeof(list)) < 0)
2573 return -1;
2574 pos = strstr(list, ssid);
2575 if (!pos || pos == list || pos[-1] != '\t' || pos[strlen(ssid)] != '\t')
2576 return -1;
2577
2578 while (pos > list && pos[-1] != '\n')
2579 pos--;
2580 dut->infra_network_id = atoi(pos);
2581 snprintf(dut->infra_ssid, sizeof(dut->infra_ssid), "%s", ssid);
2582 return 0;
2583}
2584
2585
Sunil Dutt44595082018-02-12 19:41:45 +05302586#ifdef NL80211_SUPPORT
2587static int sta_config_rsnie(struct sigma_dut *dut, int val)
2588{
2589 struct nl_msg *msg;
2590 int ret;
2591 struct nlattr *params;
2592 int ifindex;
2593
2594 ifindex = if_nametoindex("wlan0");
2595 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
2596 NL80211_CMD_VENDOR)) ||
2597 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
2598 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
2599 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
2600 QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION) ||
2601 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
2602 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE, val)) {
2603 sigma_dut_print(dut, DUT_MSG_ERROR,
2604 "%s: err in adding vendor_cmd and vendor_data",
2605 __func__);
2606 nlmsg_free(msg);
2607 return -1;
2608 }
2609 nla_nest_end(msg, params);
2610
2611 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
2612 if (ret) {
2613 sigma_dut_print(dut, DUT_MSG_ERROR,
2614 "%s: err in send_and_recv_msgs, ret=%d",
2615 __func__, ret);
2616 return ret;
2617 }
2618
2619 return 0;
2620}
2621#endif /* NL80211_SUPPORT */
2622
2623
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002624static int cmd_sta_associate(struct sigma_dut *dut, struct sigma_conn *conn,
2625 struct sigma_cmd *cmd)
2626{
2627 /* const char *intf = get_param(cmd, "Interface"); */
2628 const char *ssid = get_param(cmd, "ssid");
2629 const char *wps_param = get_param(cmd, "WPS");
2630 const char *bssid = get_param(cmd, "bssid");
Jouni Malinen46a19b62017-06-23 14:31:27 +03002631 const char *chan = get_param(cmd, "channel");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002632 int wps = 0;
Jouni Malinen3c367e82017-06-23 17:01:47 +03002633 char buf[1000], extra[50];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002634
2635 if (ssid == NULL)
2636 return -1;
2637
Jouni Malinen3c367e82017-06-23 17:01:47 +03002638 if (dut->rsne_override) {
Sunil Dutt44595082018-02-12 19:41:45 +05302639#ifdef NL80211_SUPPORT
2640 if (get_driver_type() == DRIVER_WCN) {
2641 sta_config_rsnie(dut, 1);
2642 dut->config_rsnie = 1;
2643 }
2644#endif /* NL80211_SUPPORT */
Jouni Malinen3c367e82017-06-23 17:01:47 +03002645 snprintf(buf, sizeof(buf), "TEST_ASSOC_IE %s",
2646 dut->rsne_override);
2647 if (wpa_command(get_station_ifname(), buf) < 0) {
2648 send_resp(dut, conn, SIGMA_ERROR,
2649 "ErrorCode,Failed to set DEV_CONFIGURE_IE RSNE override");
2650 return 0;
2651 }
2652 }
2653
Jouni Malinen68143132017-09-02 02:34:08 +03002654 if (dut->sae_commit_override) {
2655 snprintf(buf, sizeof(buf), "SET sae_commit_override %s",
2656 dut->sae_commit_override);
2657 if (wpa_command(get_station_ifname(), buf) < 0) {
2658 send_resp(dut, conn, SIGMA_ERROR,
2659 "ErrorCode,Failed to set SAE commit override");
2660 return 0;
2661 }
2662 }
Ankita Bajaj1bde7942018-01-09 19:15:01 +05302663#ifdef ANDROID
2664 if (dut->fils_hlp)
2665 process_fils_hlp(dut);
2666#endif /* ANDROID */
Jouni Malinen68143132017-09-02 02:34:08 +03002667
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002668 if (wps_param &&
2669 (strcmp(wps_param, "1") == 0 || strcasecmp(wps_param, "On") == 0))
2670 wps = 1;
2671
2672 if (wps) {
2673 if (dut->wps_method == WFA_CS_WPS_NOT_READY) {
2674 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,WPS "
2675 "parameters not yet set");
2676 return 0;
2677 }
2678 if (dut->wps_method == WFA_CS_WPS_PBC) {
2679 if (wpa_command(get_station_ifname(), "WPS_PBC") < 0)
2680 return -2;
2681 } else {
2682 snprintf(buf, sizeof(buf), "WPS_PIN any %s",
2683 dut->wps_pin);
2684 if (wpa_command(get_station_ifname(), buf) < 0)
2685 return -2;
2686 }
2687 } else {
vamsi krishna52e16f92017-08-29 12:37:34 +05302688 if (strcmp(ssid, dut->infra_ssid) == 0) {
2689 sigma_dut_print(dut, DUT_MSG_DEBUG,
2690 "sta_associate for the most recently added network");
2691 } else if (find_network(dut, ssid) < 0) {
2692 sigma_dut_print(dut, DUT_MSG_DEBUG,
2693 "sta_associate for a previously stored network profile");
2694 send_resp(dut, conn, SIGMA_ERROR,
2695 "ErrorCode,Profile not found");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002696 return 0;
2697 }
2698
2699 if (bssid &&
2700 set_network(get_station_ifname(), dut->infra_network_id,
2701 "bssid", bssid) < 0) {
2702 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
2703 "Invalid bssid argument");
2704 return 0;
2705 }
2706
Jouni Malinen46a19b62017-06-23 14:31:27 +03002707 extra[0] = '\0';
2708 if (chan)
2709 snprintf(extra, sizeof(extra), " freq=%u",
2710 channel_to_freq(atoi(chan)));
2711 snprintf(buf, sizeof(buf), "SELECT_NETWORK %d%s",
2712 dut->infra_network_id, extra);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002713 if (wpa_command(get_station_ifname(), buf) < 0) {
2714 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to select "
2715 "network id %d on %s",
2716 dut->infra_network_id,
2717 get_station_ifname());
2718 return -2;
2719 }
2720 }
2721
2722 return 1;
2723}
2724
2725
2726static int run_hs20_osu(struct sigma_dut *dut, const char *params)
2727{
2728 char buf[500], cmd[200];
2729 int res;
2730
2731 /* Use hs20-osu-client file at the current dir, if found; otherwise use
2732 * default path */
2733 res = snprintf(cmd, sizeof(cmd),
2734 "%s -w \"%s\" -r hs20-osu-client.res %s%s -dddKt -f Logs/hs20-osu-client.txt",
2735 file_exists("./hs20-osu-client") ?
2736 "./hs20-osu-client" : "hs20-osu-client",
2737 sigma_wpas_ctrl,
2738 dut->summary_log ? "-s " : "",
2739 dut->summary_log ? dut->summary_log : "");
2740 if (res < 0 || res >= (int) sizeof(cmd))
2741 return -1;
2742
2743 res = snprintf(buf, sizeof(buf), "%s %s", cmd, params);
2744 if (res < 0 || res >= (int) sizeof(buf))
2745 return -1;
2746 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
2747
2748 if (system(buf) != 0) {
2749 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to run: %s", buf);
2750 return -1;
2751 }
2752 sigma_dut_print(dut, DUT_MSG_DEBUG,
2753 "Completed hs20-osu-client operation");
2754
2755 return 0;
2756}
2757
2758
2759static int download_ppsmo(struct sigma_dut *dut,
2760 struct sigma_conn *conn,
2761 const char *intf,
2762 struct sigma_cmd *cmd)
2763{
2764 const char *name, *path, *val;
2765 char url[500], buf[600], fbuf[100];
2766 char *fqdn = NULL;
2767
2768 name = get_param(cmd, "FileName");
2769 path = get_param(cmd, "FilePath");
2770 if (name == NULL || path == NULL)
2771 return -1;
2772
2773 if (strcasecmp(path, "VendorSpecific") == 0) {
2774 snprintf(url, sizeof(url), "PPS/%s", name);
2775 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured PPS MO "
2776 "from the device (%s)", url);
2777 if (!file_exists(url)) {
2778 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
2779 "PPS MO file does not exist");
2780 return 0;
2781 }
2782 snprintf(buf, sizeof(buf), "cp %s pps-tnds.xml", url);
2783 if (system(buf) != 0) {
2784 send_resp(dut, conn, SIGMA_ERROR,
2785 "errorCode,Failed to copy PPS MO");
2786 return 0;
2787 }
2788 } else if (strncasecmp(path, "http:", 5) != 0 &&
2789 strncasecmp(path, "https:", 6) != 0) {
2790 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
2791 "Unsupported FilePath value");
2792 return 0;
2793 } else {
2794 snprintf(url, sizeof(url), "%s/%s", path, name);
2795 sigma_dut_print(dut, DUT_MSG_INFO, "Downloading PPS MO from %s",
2796 url);
2797 snprintf(buf, sizeof(buf), "wget -T 10 -t 3 -O pps-tnds.xml '%s'", url);
2798 remove("pps-tnds.xml");
2799 if (system(buf) != 0) {
2800 send_resp(dut, conn, SIGMA_ERROR,
2801 "errorCode,Failed to download PPS MO");
2802 return 0;
2803 }
2804 }
2805
2806 if (run_hs20_osu(dut, "from_tnds pps-tnds.xml pps.xml") < 0) {
2807 send_resp(dut, conn, SIGMA_ERROR,
2808 "errorCode,Failed to parse downloaded PPSMO");
2809 return 0;
2810 }
2811 unlink("pps-tnds.xml");
2812
2813 val = get_param(cmd, "managementTreeURI");
2814 if (val) {
2815 const char *pos, *end;
2816 sigma_dut_print(dut, DUT_MSG_DEBUG, "managementTreeURI: %s",
2817 val);
2818 if (strncmp(val, "./Wi-Fi/", 8) != 0) {
2819 send_resp(dut, conn, SIGMA_ERROR,
2820 "errorCode,Invalid managementTreeURI prefix");
2821 return 0;
2822 }
2823 pos = val + 8;
2824 end = strchr(pos, '/');
2825 if (end == NULL ||
2826 strcmp(end, "/PerProviderSubscription") != 0) {
2827 send_resp(dut, conn, SIGMA_ERROR,
2828 "errorCode,Invalid managementTreeURI postfix");
2829 return 0;
2830 }
2831 if (end - pos >= (int) sizeof(fbuf)) {
2832 send_resp(dut, conn, SIGMA_ERROR,
2833 "errorCode,Too long FQDN in managementTreeURI");
2834 return 0;
2835 }
2836 memcpy(fbuf, pos, end - pos);
2837 fbuf[end - pos] = '\0';
2838 fqdn = fbuf;
2839 sigma_dut_print(dut, DUT_MSG_INFO,
2840 "FQDN from managementTreeURI: %s", fqdn);
2841 } else if (run_hs20_osu(dut, "get_fqdn pps.xml") == 0) {
2842 FILE *f = fopen("pps-fqdn", "r");
2843 if (f) {
2844 if (fgets(fbuf, sizeof(fbuf), f)) {
2845 fbuf[sizeof(fbuf) - 1] = '\0';
2846 fqdn = fbuf;
2847 sigma_dut_print(dut, DUT_MSG_DEBUG,
2848 "Use FQDN %s", fqdn);
2849 }
2850 fclose(f);
2851 }
2852 }
2853
2854 if (fqdn == NULL) {
2855 send_resp(dut, conn, SIGMA_ERROR,
2856 "errorCode,No FQDN specified");
2857 return 0;
2858 }
2859
2860 mkdir("SP", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
2861 snprintf(buf, sizeof(buf), "SP/%s", fqdn);
2862 mkdir(buf, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
2863
2864 snprintf(buf, sizeof(buf), "SP/%s/pps.xml", fqdn);
2865 if (rename("pps.xml", buf) < 0) {
2866 send_resp(dut, conn, SIGMA_ERROR,
2867 "errorCode,Could not move PPS MO");
2868 return 0;
2869 }
2870
2871 if (strcasecmp(path, "VendorSpecific") == 0) {
2872 snprintf(buf, sizeof(buf), "cp Certs/ca.pem SP/%s/ca.pem",
2873 fqdn);
2874 if (system(buf)) {
2875 send_resp(dut, conn, SIGMA_ERROR,
2876 "errorCode,Failed to copy OSU CA cert");
2877 return 0;
2878 }
2879
2880 snprintf(buf, sizeof(buf),
2881 "cp Certs/aaa-ca.pem SP/%s/aaa-ca.pem",
2882 fqdn);
2883 if (system(buf)) {
2884 send_resp(dut, conn, SIGMA_ERROR,
2885 "errorCode,Failed to copy AAA CA cert");
2886 return 0;
2887 }
2888 } else {
2889 snprintf(buf, sizeof(buf),
2890 "dl_osu_ca SP/%s/pps.xml SP/%s/ca.pem",
2891 fqdn, fqdn);
2892 if (run_hs20_osu(dut, buf) < 0) {
2893 send_resp(dut, conn, SIGMA_ERROR,
2894 "errorCode,Failed to download OSU CA cert");
2895 return 0;
2896 }
2897
2898 snprintf(buf, sizeof(buf),
2899 "dl_aaa_ca SP/%s/pps.xml SP/%s/aaa-ca.pem",
2900 fqdn, fqdn);
2901 if (run_hs20_osu(dut, buf) < 0) {
2902 sigma_dut_print(dut, DUT_MSG_INFO,
2903 "Failed to download AAA CA cert");
2904 }
2905 }
2906
2907 if (file_exists("next-client-cert.pem")) {
2908 snprintf(buf, sizeof(buf), "SP/%s/client-cert.pem", fqdn);
2909 if (rename("next-client-cert.pem", buf) < 0) {
2910 send_resp(dut, conn, SIGMA_ERROR,
2911 "errorCode,Could not move client certificate");
2912 return 0;
2913 }
2914 }
2915
2916 if (file_exists("next-client-key.pem")) {
2917 snprintf(buf, sizeof(buf), "SP/%s/client-key.pem", fqdn);
2918 if (rename("next-client-key.pem", buf) < 0) {
2919 send_resp(dut, conn, SIGMA_ERROR,
2920 "errorCode,Could not move client key");
2921 return 0;
2922 }
2923 }
2924
2925 snprintf(buf, sizeof(buf), "set_pps SP/%s/pps.xml", fqdn);
2926 if (run_hs20_osu(dut, buf) < 0) {
2927 send_resp(dut, conn, SIGMA_ERROR,
2928 "errorCode,Failed to configure credential from "
2929 "PPSMO");
2930 return 0;
2931 }
2932
2933 return 1;
2934}
2935
2936
2937static int download_cert(struct sigma_dut *dut,
2938 struct sigma_conn *conn,
2939 const char *intf,
2940 struct sigma_cmd *cmd)
2941{
2942 const char *name, *path;
2943 char url[500], buf[600];
2944
2945 name = get_param(cmd, "FileName");
2946 path = get_param(cmd, "FilePath");
2947 if (name == NULL || path == NULL)
2948 return -1;
2949
2950 if (strcasecmp(path, "VendorSpecific") == 0) {
2951 snprintf(url, sizeof(url), "Certs/%s-cert.pem", name);
2952 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured client "
2953 "certificate from the device (%s)", url);
2954 if (!file_exists(url)) {
2955 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
2956 "certificate file does not exist");
2957 return 0;
2958 }
2959 snprintf(buf, sizeof(buf), "cp %s next-client-cert.pem", url);
2960 if (system(buf) != 0) {
2961 send_resp(dut, conn, SIGMA_ERROR,
2962 "errorCode,Failed to copy client "
2963 "certificate");
2964 return 0;
2965 }
2966
2967 snprintf(url, sizeof(url), "Certs/%s-key.pem", name);
2968 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured client "
2969 "private key from the device (%s)", url);
2970 if (!file_exists(url)) {
2971 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
2972 "private key file does not exist");
2973 return 0;
2974 }
2975 snprintf(buf, sizeof(buf), "cp %s next-client-key.pem", url);
2976 if (system(buf) != 0) {
2977 send_resp(dut, conn, SIGMA_ERROR,
2978 "errorCode,Failed to copy client key");
2979 return 0;
2980 }
2981 } else if (strncasecmp(path, "http:", 5) != 0 &&
2982 strncasecmp(path, "https:", 6) != 0) {
2983 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
2984 "Unsupported FilePath value");
2985 return 0;
2986 } else {
2987 snprintf(url, sizeof(url), "%s/%s.pem", path, name);
2988 sigma_dut_print(dut, DUT_MSG_INFO, "Downloading client "
2989 "certificate/key from %s", url);
2990 snprintf(buf, sizeof(buf),
2991 "wget -T 10 -t 3 -O next-client-cert.pem '%s'", url);
2992 if (system(buf) != 0) {
2993 send_resp(dut, conn, SIGMA_ERROR,
2994 "errorCode,Failed to download client "
2995 "certificate");
2996 return 0;
2997 }
2998
2999 if (system("cp next-client-cert.pem next-client-key.pem") != 0)
3000 {
3001 send_resp(dut, conn, SIGMA_ERROR,
3002 "errorCode,Failed to copy client key");
3003 return 0;
3004 }
3005 }
3006
3007 return 1;
3008}
3009
3010
3011static int cmd_sta_preset_testparameters_hs2_r2(struct sigma_dut *dut,
3012 struct sigma_conn *conn,
3013 const char *intf,
3014 struct sigma_cmd *cmd)
3015{
3016 const char *val;
3017
3018 val = get_param(cmd, "FileType");
3019 if (val && strcasecmp(val, "PPSMO") == 0)
3020 return download_ppsmo(dut, conn, intf, cmd);
3021 if (val && strcasecmp(val, "CERT") == 0)
3022 return download_cert(dut, conn, intf, cmd);
3023 if (val) {
3024 send_resp(dut, conn, SIGMA_ERROR,
3025 "ErrorCode,Unsupported FileType");
3026 return 0;
3027 }
3028
3029 return 1;
3030}
3031
3032
Ankita Bajaja2cb5672017-10-25 16:08:28 +05303033static int cmd_sta_preset_testparameters_oce(struct sigma_dut *dut,
3034 struct sigma_conn *conn,
3035 const char *intf,
3036 struct sigma_cmd *cmd)
3037{
3038 const char *val;
Ankita Bajaj1bde7942018-01-09 19:15:01 +05303039 char buf[1000];
3040 char text[20];
3041 unsigned char addr[ETH_ALEN];
Ankita Bajaja2cb5672017-10-25 16:08:28 +05303042
3043 val = get_param(cmd, "OCESupport");
3044 if (val && strcasecmp(val, "Disable") == 0) {
3045 if (wpa_command(intf, "SET oce 0") < 0) {
3046 send_resp(dut, conn, SIGMA_ERROR,
3047 "ErrorCode,Failed to disable OCE");
3048 return 0;
3049 }
3050 } else if (val && strcasecmp(val, "Enable") == 0) {
3051 if (wpa_command(intf, "SET oce 1") < 0) {
3052 send_resp(dut, conn, SIGMA_ERROR,
3053 "ErrorCode,Failed to enable OCE");
3054 return 0;
3055 }
3056 }
3057
vamsi krishnaa2799492017-12-05 14:28:01 +05303058 val = get_param(cmd, "FILScap");
3059 if (val && (atoi(val) == 1)) {
3060 if (wpa_command(intf, "SET disable_fils 0") < 0) {
3061 send_resp(dut, conn, SIGMA_ERROR,
3062 "ErrorCode,Failed to enable FILS");
3063 return 0;
3064 }
3065 } else if (val && (atoi(val) == 0)) {
3066 if (wpa_command(intf, "SET disable_fils 1") < 0) {
3067 send_resp(dut, conn, SIGMA_ERROR,
3068 "ErrorCode,Failed to disable FILS");
3069 return 0;
3070 }
3071 }
3072
Ankita Bajaj1bde7942018-01-09 19:15:01 +05303073 val = get_param(cmd, "FILSHLP");
3074 if (val && strcasecmp(val, "Enable") == 0) {
3075 if (get_wpa_status(get_station_ifname(), "address", text,
3076 sizeof(text)) < 0)
3077 return -2;
3078 hwaddr_aton(text, addr);
3079 snprintf(buf, sizeof(buf),
3080 "FILS_HLP_REQ_ADD ff:ff:ff:ff:ff:ff "
3081 "080045100140000040004011399e00000000ffffffff00440043"
3082 "012cb30001010600fd4f46410000000000000000000000000000"
3083 "000000000000"
3084 "%02x%02x%02x%02x%02x%02x"
3085 "0000000000000000000000000000000000000000000000000000"
3086 "0000000000000000000000000000000000000000000000000000"
3087 "0000000000000000000000000000000000000000000000000000"
3088 "0000000000000000000000000000000000000000000000000000"
3089 "0000000000000000000000000000000000000000000000000000"
3090 "0000000000000000000000000000000000000000000000000000"
3091 "0000000000000000000000000000000000000000000000000000"
3092 "0000000000000000000000000000000000000000638253633501"
3093 "013d0701000af549d29b390205dc3c12616e64726f69642d6468"
3094 "63702d382e302e30370a0103060f1a1c333a3b2b5000ff00",
3095 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
3096 if (wpa_command(intf, buf)) {
3097 send_resp(dut, conn, SIGMA_ERROR,
3098 "ErrorCode,Failed to add HLP");
3099 return 0;
3100 }
3101 dut->fils_hlp = 1;
3102 }
3103
Ankita Bajaja2cb5672017-10-25 16:08:28 +05303104 return 1;
3105}
3106
3107
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003108static void ath_sta_set_noack(struct sigma_dut *dut, const char *intf,
3109 const char *val)
3110{
3111 int counter = 0;
3112 char token[50];
3113 char *result;
3114 char buf[100];
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05303115 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003116
Peng Xub8fc5cc2017-05-10 17:27:28 -07003117 strlcpy(token, val, sizeof(token));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003118 token[sizeof(token) - 1] = '\0';
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05303119 result = strtok_r(token, ":", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003120 while (result) {
3121 if (strcmp(result, "disable") == 0) {
3122 snprintf(buf, sizeof(buf),
3123 "iwpriv %s noackpolicy %d 1 0",
3124 intf, counter);
3125 } else {
3126 snprintf(buf, sizeof(buf),
3127 "iwpriv %s noackpolicy %d 1 1",
3128 intf, counter);
3129 }
3130 if (system(buf) != 0) {
3131 sigma_dut_print(dut, DUT_MSG_ERROR,
3132 "iwpriv noackpolicy failed");
3133 }
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05303134 result = strtok_r(NULL, ":", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003135 counter++;
3136 }
3137}
3138
3139
3140static void ath_sta_set_rts(struct sigma_dut *dut, const char *intf,
3141 const char *val)
3142{
3143 char buf[100];
3144
3145 snprintf(buf, sizeof(buf), "iwconfig %s rts %s", intf, val);
3146 if (system(buf) != 0) {
3147 sigma_dut_print(dut, DUT_MSG_ERROR, "iwconfig RTS failed");
3148 }
3149}
3150
3151
3152static void ath_sta_set_wmm(struct sigma_dut *dut, const char *intf,
3153 const char *val)
3154{
3155 char buf[100];
3156
3157 if (strcasecmp(val, "off") == 0) {
3158 snprintf(buf, sizeof(buf), "iwpriv %s wmm 0", intf);
3159 if (system(buf) != 0) {
3160 sigma_dut_print(dut, DUT_MSG_ERROR,
3161 "Failed to turn off WMM");
3162 }
3163 }
3164}
3165
3166
3167static void ath_sta_set_sgi(struct sigma_dut *dut, const char *intf,
3168 const char *val)
3169{
3170 char buf[100];
3171 int sgi20;
3172
3173 sgi20 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
3174
3175 snprintf(buf, sizeof(buf), "iwpriv %s shortgi %d", intf, sgi20);
3176 if (system(buf) != 0)
3177 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv shortgi failed");
3178}
3179
3180
3181static void ath_sta_set_11nrates(struct sigma_dut *dut, const char *intf,
3182 const char *val)
3183{
3184 char buf[100];
Pradeep Reddy POTTETI67376b72016-10-25 20:08:17 +05303185 int rate_code, v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003186
3187 /* Disable Tx Beam forming when using a fixed rate */
3188 ath_disable_txbf(dut, intf);
3189
Pradeep Reddy POTTETI67376b72016-10-25 20:08:17 +05303190 v = atoi(val);
3191 if (v < 0 || v > 32) {
3192 sigma_dut_print(dut, DUT_MSG_ERROR,
3193 "Invalid Fixed MCS rate: %d", v);
3194 return;
3195 }
3196 rate_code = 0x80 + v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003197
3198 snprintf(buf, sizeof(buf), "iwpriv %s set11NRates 0x%x",
3199 intf, rate_code);
3200 if (system(buf) != 0) {
3201 sigma_dut_print(dut, DUT_MSG_ERROR,
3202 "iwpriv set11NRates failed");
3203 }
3204
3205 /* Channel width gets messed up, fix this */
3206 snprintf(buf, sizeof(buf), "iwpriv %s chwidth %d", intf, dut->chwidth);
3207 if (system(buf) != 0)
3208 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv chwidth failed");
3209}
3210
3211
3212static void ath_sta_set_amsdu(struct sigma_dut *dut, const char *intf,
3213 const char *val)
3214{
3215 char buf[60];
3216
3217 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)
3218 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 2", intf);
3219 else
3220 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 1", intf);
3221
3222 if (system(buf) != 0)
3223 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv amsdu failed");
3224}
3225
3226
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07003227static int iwpriv_sta_set_ampdu(struct sigma_dut *dut, const char *intf,
3228 int ampdu)
3229{
3230 char buf[60];
3231
3232 snprintf(buf, sizeof(buf), "iwpriv %s ampdu %d", intf, ampdu);
3233 if (system(buf) != 0) {
3234 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv ampdu failed");
3235 return -1;
3236 }
3237
3238 return 0;
3239}
3240
3241
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003242static void ath_sta_set_stbc(struct sigma_dut *dut, const char *intf,
3243 const char *val)
3244{
3245 char buf[60];
3246
3247 snprintf(buf, sizeof(buf), "iwpriv %s tx_stbc %s", intf, val);
3248 if (system(buf) != 0) {
3249 sigma_dut_print(dut, DUT_MSG_ERROR,
3250 "iwpriv tx_stbc failed");
3251 }
3252
3253 snprintf(buf, sizeof(buf), "iwpriv %s rx_stbc %s", intf, val);
3254 if (system(buf) != 0) {
3255 sigma_dut_print(dut, DUT_MSG_ERROR,
3256 "iwpriv rx_stbc failed");
3257 }
3258}
3259
3260
3261static int wcn_sta_set_cts_width(struct sigma_dut *dut, const char *intf,
3262 const char *val)
3263{
3264 char buf[60];
3265
Peng Xucc317ed2017-05-18 16:44:37 -07003266 if (strcmp(val, "160") == 0) {
3267 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 5", intf);
3268 } else if (strcmp(val, "80") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003269 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 3", intf);
3270 } else if (strcmp(val, "40") == 0) {
3271 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 2", intf);
3272 } else if (strcmp(val, "20") == 0) {
3273 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 1", intf);
3274 } else if (strcasecmp(val, "Auto") == 0) {
3275 buf[0] = '\0';
3276 } else {
3277 sigma_dut_print(dut, DUT_MSG_ERROR,
3278 "WIDTH/CTS_WIDTH value not supported");
3279 return -1;
3280 }
3281
3282 if (buf[0] != '\0' && system(buf) != 0) {
3283 sigma_dut_print(dut, DUT_MSG_ERROR,
3284 "Failed to set WIDTH/CTS_WIDTH");
3285 return -1;
3286 }
3287
3288 return 0;
3289}
3290
3291
3292int ath_set_width(struct sigma_dut *dut, struct sigma_conn *conn,
3293 const char *intf, const char *val)
3294{
3295 char buf[60];
3296
3297 if (strcasecmp(val, "Auto") == 0) {
3298 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 0", intf);
3299 dut->chwidth = 0;
3300 } else if (strcasecmp(val, "20") == 0) {
3301 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 0", intf);
3302 dut->chwidth = 0;
3303 } else if (strcasecmp(val, "40") == 0) {
3304 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 1", intf);
3305 dut->chwidth = 1;
3306 } else if (strcasecmp(val, "80") == 0) {
3307 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 2", intf);
3308 dut->chwidth = 2;
3309 } else if (strcasecmp(val, "160") == 0) {
3310 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 3", intf);
3311 dut->chwidth = 3;
3312 } else {
3313 send_resp(dut, conn, SIGMA_ERROR,
3314 "ErrorCode,WIDTH not supported");
3315 return -1;
3316 }
3317
3318 if (system(buf) != 0) {
3319 sigma_dut_print(dut, DUT_MSG_ERROR,
3320 "iwpriv chwidth failed");
3321 }
3322
3323 return 0;
3324}
3325
3326
3327static int wcn_sta_set_sp_stream(struct sigma_dut *dut, const char *intf,
3328 const char *val)
3329{
3330 char buf[60];
3331
3332 if (strcmp(val, "1SS") == 0) {
3333 snprintf(buf, sizeof(buf), "iwpriv %s nss 1", intf);
3334 } else if (strcmp(val, "2SS") == 0) {
3335 snprintf(buf, sizeof(buf), "iwpriv %s nss 2", intf);
3336 } else {
3337 sigma_dut_print(dut, DUT_MSG_ERROR,
3338 "SP_STREAM value not supported");
3339 return -1;
3340 }
3341
3342 if (system(buf) != 0) {
3343 sigma_dut_print(dut, DUT_MSG_ERROR,
3344 "Failed to set SP_STREAM");
3345 return -1;
3346 }
3347
3348 return 0;
3349}
3350
3351
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05303352static void wcn_sta_set_stbc(struct sigma_dut *dut, const char *intf,
3353 const char *val)
3354{
3355 char buf[60];
3356
3357 snprintf(buf, sizeof(buf), "iwpriv %s tx_stbc %s", intf, val);
3358 if (system(buf) != 0)
3359 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv tx_stbc failed");
3360
3361 snprintf(buf, sizeof(buf), "iwpriv %s rx_stbc %s", intf, val);
3362 if (system(buf) != 0)
3363 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv rx_stbc failed");
3364}
3365
3366
Ashwini Patil68d02cd2017-01-10 15:39:16 +05303367static int mbo_set_cellular_data_capa(struct sigma_dut *dut,
3368 struct sigma_conn *conn,
3369 const char *intf, int capa)
3370{
3371 char buf[32];
3372
3373 if (capa > 0 && capa < 4) {
3374 snprintf(buf, sizeof(buf), "SET mbo_cell_capa %d", capa);
3375 if (wpa_command(intf, buf) < 0) {
3376 send_resp(dut, conn, SIGMA_ERROR,
3377 "ErrorCode, Failed to set cellular data capability");
3378 return 0;
3379 }
3380 return 1;
3381 }
3382
3383 sigma_dut_print(dut, DUT_MSG_ERROR,
3384 "Invalid Cellular data capability: %d", capa);
3385 send_resp(dut, conn, SIGMA_INVALID,
3386 "ErrorCode,Invalid cellular data capability");
3387 return 0;
3388}
3389
3390
Ashwini Patil9183fdb2017-04-13 16:58:25 +05303391static int mbo_set_roaming(struct sigma_dut *dut, struct sigma_conn *conn,
3392 const char *intf, const char *val)
3393{
3394 if (strcasecmp(val, "Disable") == 0) {
3395 if (wpa_command(intf, "SET roaming 0") < 0) {
3396 send_resp(dut, conn, SIGMA_ERROR,
3397 "ErrorCode,Failed to disable roaming");
3398 return 0;
3399 }
3400 return 1;
3401 }
3402
3403 if (strcasecmp(val, "Enable") == 0) {
3404 if (wpa_command(intf, "SET roaming 1") < 0) {
3405 send_resp(dut, conn, SIGMA_ERROR,
3406 "ErrorCode,Failed to enable roaming");
3407 return 0;
3408 }
3409 return 1;
3410 }
3411
3412 sigma_dut_print(dut, DUT_MSG_ERROR,
3413 "Invalid value provided for roaming: %s", val);
3414 send_resp(dut, conn, SIGMA_INVALID,
3415 "ErrorCode,Unknown value provided for Roaming");
3416 return 0;
3417}
3418
3419
Ashwini Patila75de5a2017-04-13 16:35:05 +05303420static int mbo_set_assoc_disallow(struct sigma_dut *dut,
3421 struct sigma_conn *conn,
3422 const char *intf, const char *val)
3423{
3424 if (strcasecmp(val, "Disable") == 0) {
3425 if (wpa_command(intf, "SET ignore_assoc_disallow 1") < 0) {
3426 send_resp(dut, conn, SIGMA_ERROR,
3427 "ErrorCode,Failed to disable Assoc_disallow");
3428 return 0;
3429 }
3430 return 1;
3431 }
3432
3433 if (strcasecmp(val, "Enable") == 0) {
3434 if (wpa_command(intf, "SET ignore_assoc_disallow 0") < 0) {
3435 send_resp(dut, conn, SIGMA_ERROR,
3436 "ErrorCode,Failed to enable Assoc_disallow");
3437 return 0;
3438 }
3439 return 1;
3440 }
3441
3442 sigma_dut_print(dut, DUT_MSG_ERROR,
3443 "Invalid value provided for Assoc_disallow: %s", val);
3444 send_resp(dut, conn, SIGMA_INVALID,
3445 "ErrorCode,Unknown value provided for Assoc_disallow");
3446 return 0;
3447}
3448
3449
Ashwini Patilc63161e2017-04-13 16:30:23 +05303450static int mbo_set_bss_trans_req(struct sigma_dut *dut, struct sigma_conn *conn,
3451 const char *intf, const char *val)
3452{
3453 if (strcasecmp(val, "Reject") == 0) {
3454 if (wpa_command(intf, "SET reject_btm_req_reason 1") < 0) {
3455 send_resp(dut, conn, SIGMA_ERROR,
3456 "ErrorCode,Failed to Reject BTM Request");
3457 return 0;
3458 }
3459 return 1;
3460 }
3461
3462 if (strcasecmp(val, "Accept") == 0) {
3463 if (wpa_command(intf, "SET reject_btm_req_reason 0") < 0) {
3464 send_resp(dut, conn, SIGMA_ERROR,
3465 "ErrorCode,Failed to Accept BTM Request");
3466 return 0;
3467 }
3468 return 1;
3469 }
3470
3471 sigma_dut_print(dut, DUT_MSG_ERROR,
3472 "Invalid value provided for BSS_Transition: %s", val);
3473 send_resp(dut, conn, SIGMA_INVALID,
3474 "ErrorCode,Unknown value provided for BSS_Transition");
3475 return 0;
3476}
3477
3478
Ashwini Patil00402582017-04-13 12:29:39 +05303479static int mbo_set_non_pref_ch_list(struct sigma_dut *dut,
3480 struct sigma_conn *conn,
3481 const char *intf,
3482 struct sigma_cmd *cmd)
3483{
3484 const char *ch, *pref, *op_class, *reason;
3485 char buf[120];
3486 int len, ret;
3487
3488 pref = get_param(cmd, "Ch_Pref");
3489 if (!pref)
3490 return 1;
3491
3492 if (strcasecmp(pref, "clear") == 0) {
3493 free(dut->non_pref_ch_list);
3494 dut->non_pref_ch_list = NULL;
3495 } else {
3496 op_class = get_param(cmd, "Ch_Op_Class");
3497 if (!op_class) {
3498 send_resp(dut, conn, SIGMA_INVALID,
3499 "ErrorCode,Ch_Op_Class not provided");
3500 return 0;
3501 }
3502
3503 ch = get_param(cmd, "Ch_Pref_Num");
3504 if (!ch) {
3505 send_resp(dut, conn, SIGMA_INVALID,
3506 "ErrorCode,Ch_Pref_Num not provided");
3507 return 0;
3508 }
3509
3510 reason = get_param(cmd, "Ch_Reason_Code");
3511 if (!reason) {
3512 send_resp(dut, conn, SIGMA_INVALID,
3513 "ErrorCode,Ch_Reason_Code not provided");
3514 return 0;
3515 }
3516
3517 if (!dut->non_pref_ch_list) {
3518 dut->non_pref_ch_list =
3519 calloc(1, NON_PREF_CH_LIST_SIZE);
3520 if (!dut->non_pref_ch_list) {
3521 send_resp(dut, conn, SIGMA_ERROR,
3522 "ErrorCode,Failed to allocate memory for non_pref_ch_list");
3523 return 0;
3524 }
3525 }
3526 len = strlen(dut->non_pref_ch_list);
3527 ret = snprintf(dut->non_pref_ch_list + len,
3528 NON_PREF_CH_LIST_SIZE - len,
3529 " %s:%s:%s:%s", op_class, ch, pref, reason);
3530 if (ret > 0 && ret < NON_PREF_CH_LIST_SIZE - len) {
3531 sigma_dut_print(dut, DUT_MSG_DEBUG, "non_pref_list: %s",
3532 dut->non_pref_ch_list);
3533 } else {
3534 sigma_dut_print(dut, DUT_MSG_ERROR,
3535 "snprintf failed for non_pref_list, ret = %d",
3536 ret);
3537 send_resp(dut, conn, SIGMA_ERROR,
3538 "ErrorCode,snprintf failed");
3539 free(dut->non_pref_ch_list);
3540 dut->non_pref_ch_list = NULL;
3541 return 0;
3542 }
3543 }
3544
3545 ret = snprintf(buf, sizeof(buf), "SET non_pref_chan%s",
3546 dut->non_pref_ch_list ? dut->non_pref_ch_list : " ");
3547 if (ret < 0 || ret >= (int) sizeof(buf)) {
3548 sigma_dut_print(dut, DUT_MSG_DEBUG,
3549 "snprintf failed for set non_pref_chan, ret: %d",
3550 ret);
3551 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,snprint failed");
3552 return 0;
3553 }
3554
3555 if (wpa_command(intf, buf) < 0) {
3556 send_resp(dut, conn, SIGMA_ERROR,
3557 "ErrorCode,Failed to set non-preferred channel list");
3558 return 0;
3559 }
3560
3561 return 1;
3562}
3563
3564
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003565static int cmd_sta_preset_testparameters(struct sigma_dut *dut,
3566 struct sigma_conn *conn,
3567 struct sigma_cmd *cmd)
3568{
3569 const char *intf = get_param(cmd, "Interface");
3570 const char *val;
3571
3572 val = get_param(cmd, "Program");
Peng Xue9fa7952017-05-09 15:59:49 -07003573 if (val && strcasecmp(val, "HS2-R2") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003574 return cmd_sta_preset_testparameters_hs2_r2(dut, conn, intf,
3575 cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003576
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07003577 if (val && strcasecmp(val, "LOC") == 0)
3578 return loc_cmd_sta_preset_testparameters(dut, conn, cmd);
3579
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003580#ifdef ANDROID_NAN
3581 if (val && strcasecmp(val, "NAN") == 0)
3582 return nan_cmd_sta_preset_testparameters(dut, conn, cmd);
3583#endif /* ANDROID_NAN */
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07003584#ifdef MIRACAST
3585 if (val && (strcasecmp(val, "WFD") == 0 ||
3586 strcasecmp(val, "DisplayR2") == 0))
3587 return miracast_preset_testparameters(dut, conn, cmd);
3588#endif /* MIRACAST */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003589
Ashwini Patil68d02cd2017-01-10 15:39:16 +05303590 if (val && strcasecmp(val, "MBO") == 0) {
3591 val = get_param(cmd, "Cellular_Data_Cap");
3592 if (val &&
3593 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
3594 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +05303595
3596 val = get_param(cmd, "Ch_Pref");
3597 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
3598 return 0;
3599
Ashwini Patilc63161e2017-04-13 16:30:23 +05303600 val = get_param(cmd, "BSS_Transition");
3601 if (val && mbo_set_bss_trans_req(dut, conn, intf, val) == 0)
3602 return 0;
3603
Ashwini Patila75de5a2017-04-13 16:35:05 +05303604 val = get_param(cmd, "Assoc_Disallow");
3605 if (val && mbo_set_assoc_disallow(dut, conn, intf, val) == 0)
3606 return 0;
3607
Ashwini Patil9183fdb2017-04-13 16:58:25 +05303608 val = get_param(cmd, "Roaming");
3609 if (val && mbo_set_roaming(dut, conn, intf, val) == 0)
3610 return 0;
3611
Ashwini Patil68d02cd2017-01-10 15:39:16 +05303612 return 1;
3613 }
3614
Ankita Bajaja2cb5672017-10-25 16:08:28 +05303615 if (val && strcasecmp(val, "OCE") == 0)
3616 return cmd_sta_preset_testparameters_oce(dut, conn, intf, cmd);
3617
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003618#if 0
3619 val = get_param(cmd, "Supplicant");
3620 if (val && strcasecmp(val, "Default") != 0) {
3621 send_resp(dut, conn, SIGMA_ERROR,
3622 "ErrorCode,Only default(Vendor) supplicant "
3623 "supported");
3624 return 0;
3625 }
3626#endif
3627
3628 val = get_param(cmd, "RTS");
3629 if (val) {
3630 switch (get_driver_type()) {
3631 case DRIVER_ATHEROS:
3632 ath_sta_set_rts(dut, intf, val);
3633 break;
3634 default:
3635#if 0
3636 send_resp(dut, conn, SIGMA_ERROR,
3637 "ErrorCode,Setting RTS not supported");
3638 return 0;
3639#else
3640 sigma_dut_print(dut, DUT_MSG_DEBUG,
3641 "Setting RTS not supported");
3642 break;
3643#endif
3644 }
3645 }
3646
3647#if 0
3648 val = get_param(cmd, "FRGMNT");
3649 if (val) {
3650 /* TODO */
3651 send_resp(dut, conn, SIGMA_ERROR,
3652 "ErrorCode,Setting FRGMNT not supported");
3653 return 0;
3654 }
3655#endif
3656
3657#if 0
3658 val = get_param(cmd, "Preamble");
3659 if (val) {
3660 /* TODO: Long/Short */
3661 send_resp(dut, conn, SIGMA_ERROR,
3662 "ErrorCode,Setting Preamble not supported");
3663 return 0;
3664 }
3665#endif
3666
3667 val = get_param(cmd, "Mode");
3668 if (val) {
3669 if (strcmp(val, "11b") == 0 ||
3670 strcmp(val, "11g") == 0 ||
3671 strcmp(val, "11a") == 0 ||
3672 strcmp(val, "11n") == 0 ||
3673 strcmp(val, "11ng") == 0 ||
3674 strcmp(val, "11nl") == 0 ||
3675 strcmp(val, "11nl(nabg)") == 0 ||
3676 strcmp(val, "AC") == 0 ||
3677 strcmp(val, "11AC") == 0 ||
3678 strcmp(val, "11ac") == 0 ||
3679 strcmp(val, "11na") == 0 ||
3680 strcmp(val, "11an") == 0) {
3681 /* STA supports all modes by default */
3682 } else {
3683 send_resp(dut, conn, SIGMA_ERROR,
3684 "ErrorCode,Setting Mode not supported");
3685 return 0;
3686 }
3687 }
3688
3689 val = get_param(cmd, "wmm");
3690 if (val) {
3691 switch (get_driver_type()) {
3692 case DRIVER_ATHEROS:
3693 ath_sta_set_wmm(dut, intf, val);
3694 break;
3695 default:
3696 sigma_dut_print(dut, DUT_MSG_DEBUG,
3697 "Setting wmm not supported");
3698 break;
3699 }
3700 }
3701
3702 val = get_param(cmd, "Powersave");
3703 if (val) {
3704 if (strcmp(val, "0") == 0 || strcasecmp(val, "off") == 0) {
3705 if (wpa_command(get_station_ifname(),
3706 "P2P_SET ps 0") < 0)
3707 return -2;
3708 /* Make sure test modes are disabled */
3709 wpa_command(get_station_ifname(), "P2P_SET ps 98");
3710 wpa_command(get_station_ifname(), "P2P_SET ps 96");
3711 } else if (strcmp(val, "1") == 0 ||
3712 strcasecmp(val, "PSPoll") == 0 ||
3713 strcasecmp(val, "on") == 0) {
3714 /* Disable default power save mode */
3715 wpa_command(get_station_ifname(), "P2P_SET ps 0");
3716 /* Enable PS-Poll test mode */
3717 if (wpa_command(get_station_ifname(),
3718 "P2P_SET ps 97") < 0 ||
3719 wpa_command(get_station_ifname(),
3720 "P2P_SET ps 99") < 0)
3721 return -2;
3722 } else if (strcmp(val, "2") == 0 ||
3723 strcasecmp(val, "Fast") == 0) {
3724 /* TODO */
3725 send_resp(dut, conn, SIGMA_ERROR,
3726 "ErrorCode,Powersave=Fast not supported");
3727 return 0;
3728 } else if (strcmp(val, "3") == 0 ||
3729 strcasecmp(val, "PSNonPoll") == 0) {
3730 /* Make sure test modes are disabled */
3731 wpa_command(get_station_ifname(), "P2P_SET ps 98");
3732 wpa_command(get_station_ifname(), "P2P_SET ps 96");
3733
3734 /* Enable default power save mode */
3735 if (wpa_command(get_station_ifname(),
3736 "P2P_SET ps 1") < 0)
3737 return -2;
3738 } else
3739 return -1;
3740 }
3741
3742 val = get_param(cmd, "NoAck");
3743 if (val) {
3744 switch (get_driver_type()) {
3745 case DRIVER_ATHEROS:
3746 ath_sta_set_noack(dut, intf, val);
3747 break;
3748 default:
3749 send_resp(dut, conn, SIGMA_ERROR,
3750 "ErrorCode,Setting NoAck not supported");
3751 return 0;
3752 }
3753 }
3754
3755 val = get_param(cmd, "IgnoreChswitchProhibit");
3756 if (val) {
3757 /* TODO: Enabled/disabled */
3758 if (strcasecmp(val, "Enabled") == 0) {
3759 send_resp(dut, conn, SIGMA_ERROR,
3760 "ErrorCode,Enabling IgnoreChswitchProhibit "
3761 "not supported");
3762 return 0;
3763 }
3764 }
3765
3766 val = get_param(cmd, "TDLS");
3767 if (val) {
3768 if (strcasecmp(val, "Disabled") == 0) {
3769 if (wpa_command(intf, "SET tdls_disabled 1")) {
3770 send_resp(dut, conn, SIGMA_ERROR,
3771 "ErrorCode,Failed to disable TDLS");
3772 return 0;
3773 }
3774 } else if (strcasecmp(val, "Enabled") == 0) {
3775 if (wpa_command(intf, "SET tdls_disabled 0")) {
3776 send_resp(dut, conn, SIGMA_ERROR,
3777 "ErrorCode,Failed to enable TDLS");
3778 return 0;
3779 }
3780 } else {
3781 send_resp(dut, conn, SIGMA_ERROR,
3782 "ErrorCode,Unsupported TDLS value");
3783 return 0;
3784 }
3785 }
3786
3787 val = get_param(cmd, "TDLSmode");
3788 if (val) {
3789 if (strcasecmp(val, "Default") == 0) {
3790 wpa_command(intf, "SET tdls_testing 0");
3791 } else if (strcasecmp(val, "APProhibit") == 0) {
3792 if (wpa_command(intf, "SET tdls_testing 0x400")) {
3793 send_resp(dut, conn, SIGMA_ERROR,
3794 "ErrorCode,Failed to enable ignore "
3795 "APProhibit TDLS mode");
3796 return 0;
3797 }
3798 } else if (strcasecmp(val, "HiLoMac") == 0) {
3799 /* STA should respond with TDLS setup req for a TDLS
3800 * setup req */
3801 if (wpa_command(intf, "SET tdls_testing 0x80")) {
3802 send_resp(dut, conn, SIGMA_ERROR,
3803 "ErrorCode,Failed to enable HiLoMac "
3804 "TDLS mode");
3805 return 0;
3806 }
3807 } else if (strcasecmp(val, "WeakSecurity") == 0) {
3808 /*
3809 * Since all security modes are enabled by default when
3810 * Sigma control is used, there is no need to do
3811 * anything here.
3812 */
3813 } else if (strcasecmp(val, "ExistLink") == 0) {
3814 /*
3815 * Since we allow new TDLS Setup Request even if there
3816 * is an existing link, nothing needs to be done for
3817 * this.
3818 */
3819 } else {
3820 /* TODO:
3821 * ExistLink: STA should send TDLS setup req even if
3822 * direct link already exists
3823 */
3824 send_resp(dut, conn, SIGMA_ERROR,
3825 "ErrorCode,Unsupported TDLSmode value");
3826 return 0;
3827 }
3828 }
3829
3830 val = get_param(cmd, "FakePubKey");
3831 if (val && atoi(val) && wpa_command(intf, "SET wps_corrupt_pkhash 1")) {
3832 send_resp(dut, conn, SIGMA_ERROR,
3833 "ErrorCode,Failed to enable FakePubKey");
3834 return 0;
3835 }
3836
3837 return 1;
3838}
3839
3840
3841static const char * ath_get_radio_name(const char *radio_name)
3842{
3843 if (radio_name == NULL)
3844 return "wifi0";
3845 if (strcmp(radio_name, "wifi1") == 0)
3846 return "wifi1";
3847 if (strcmp(radio_name, "wifi2") == 0)
3848 return "wifi2";
3849 return "wifi0";
3850}
3851
3852
3853static void ath_sta_set_txsp_stream(struct sigma_dut *dut, const char *intf,
3854 const char *val)
3855{
3856 char buf[60];
3857 unsigned int vht_mcsmap = 0;
3858 int txchainmask = 0;
3859 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
3860
3861 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
3862 if (dut->testbed_flag_txsp == 1) {
3863 vht_mcsmap = 0xfffc;
3864 dut->testbed_flag_txsp = 0;
3865 } else {
3866 vht_mcsmap = 0xfffe;
3867 }
3868 txchainmask = 1;
3869 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
3870 if (dut->testbed_flag_txsp == 1) {
3871 vht_mcsmap = 0xfff0;
3872 dut->testbed_flag_txsp = 0;
3873 } else {
3874 vht_mcsmap = 0xfffa;
3875 }
3876 txchainmask = 3;
3877 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
3878 if (dut->testbed_flag_txsp == 1) {
3879 vht_mcsmap = 0xffc0;
3880 dut->testbed_flag_txsp = 0;
3881 } else {
3882 vht_mcsmap = 0xffea;
3883 }
3884 txchainmask = 7;
3885 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
3886 if (dut->testbed_flag_txsp == 1) {
3887 vht_mcsmap = 0xff00;
3888 dut->testbed_flag_txsp = 0;
3889 } else {
3890 vht_mcsmap = 0xffaa;
3891 }
3892 txchainmask = 15;
3893 } else {
3894 if (dut->testbed_flag_txsp == 1) {
3895 vht_mcsmap = 0xffc0;
3896 dut->testbed_flag_txsp = 0;
3897 } else {
3898 vht_mcsmap = 0xffea;
3899 }
3900 }
3901
3902 if (txchainmask) {
3903 snprintf(buf, sizeof(buf), "iwpriv %s txchainmask %d",
3904 basedev, txchainmask);
3905 if (system(buf) != 0) {
3906 sigma_dut_print(dut, DUT_MSG_ERROR,
3907 "iwpriv txchainmask failed");
3908 }
3909 }
3910
3911 snprintf(buf, sizeof(buf), "iwpriv %s vht_mcsmap 0x%04x",
3912 intf, vht_mcsmap);
3913 if (system(buf) != 0) {
3914 sigma_dut_print(dut, DUT_MSG_ERROR,
3915 "iwpriv %s vht_mcsmap 0x%04x failed",
3916 intf, vht_mcsmap);
3917 }
3918}
3919
3920
3921static void ath_sta_set_rxsp_stream(struct sigma_dut *dut, const char *intf,
3922 const char *val)
3923{
3924 char buf[60];
3925 unsigned int vht_mcsmap = 0;
3926 int rxchainmask = 0;
3927 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
3928
3929 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
3930 if (dut->testbed_flag_rxsp == 1) {
3931 vht_mcsmap = 0xfffc;
3932 dut->testbed_flag_rxsp = 0;
3933 } else {
3934 vht_mcsmap = 0xfffe;
3935 }
3936 rxchainmask = 1;
3937 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
3938 if (dut->testbed_flag_rxsp == 1) {
3939 vht_mcsmap = 0xfff0;
3940 dut->testbed_flag_rxsp = 0;
3941 } else {
3942 vht_mcsmap = 0xfffa;
3943 }
3944 rxchainmask = 3;
3945 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
3946 if (dut->testbed_flag_rxsp == 1) {
3947 vht_mcsmap = 0xffc0;
3948 dut->testbed_flag_rxsp = 0;
3949 } else {
3950 vht_mcsmap = 0xffea;
3951 }
3952 rxchainmask = 7;
3953 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
3954 if (dut->testbed_flag_rxsp == 1) {
3955 vht_mcsmap = 0xff00;
3956 dut->testbed_flag_rxsp = 0;
3957 } else {
3958 vht_mcsmap = 0xffaa;
3959 }
3960 rxchainmask = 15;
3961 } else {
3962 if (dut->testbed_flag_rxsp == 1) {
3963 vht_mcsmap = 0xffc0;
3964 dut->testbed_flag_rxsp = 0;
3965 } else {
3966 vht_mcsmap = 0xffea;
3967 }
3968 }
3969
3970 if (rxchainmask) {
3971 snprintf(buf, sizeof(buf), "iwpriv %s rxchainmask %d",
3972 basedev, rxchainmask);
3973 if (system(buf) != 0) {
3974 sigma_dut_print(dut, DUT_MSG_ERROR,
3975 "iwpriv rxchainmask failed");
3976 }
3977 }
3978
3979 snprintf(buf, sizeof(buf), "iwpriv %s vht_mcsmap 0x%04x",
3980 intf, vht_mcsmap);
3981 if (system(buf) != 0) {
3982 sigma_dut_print(dut, DUT_MSG_ERROR,
3983 "iwpriv %s vht_mcsmap 0x%04x",
3984 intf, vht_mcsmap);
3985 }
3986}
3987
3988
3989void ath_set_zero_crc(struct sigma_dut *dut, const char *val)
3990{
3991 if (strcasecmp(val, "enable") == 0) {
3992 if (system("athdiag --set --address=0x2a204 --and=0xbfffffff")
3993 != 0) {
3994 sigma_dut_print(dut, DUT_MSG_ERROR,
3995 "Disable BB_VHTSIGB_CRC_CALC failed");
3996 }
3997
3998 if (system("athdiag --set --address=0x2a204 --or=0x80000000")
3999 != 0) {
4000 sigma_dut_print(dut, DUT_MSG_ERROR,
4001 "Enable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
4002 }
4003 } else {
4004 if (system("athdiag --set --address=0x2a204 --and=0x7fffffff")
4005 != 0) {
4006 sigma_dut_print(dut, DUT_MSG_ERROR,
4007 "Disable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
4008 }
4009
4010 if (system("athdiag --set --address=0x2a204 --or=0x40000000")
4011 != 0) {
4012 sigma_dut_print(dut, DUT_MSG_ERROR,
4013 "Enable BB_VHTSIGB_CRC_CALC failed");
4014 }
4015 }
4016}
4017
4018
4019static int cmd_sta_set_wireless_common(const char *intf, struct sigma_dut *dut,
4020 struct sigma_conn *conn,
4021 struct sigma_cmd *cmd)
4022{
4023 const char *val;
4024 int ampdu = -1;
4025 char buf[30];
4026
4027 val = get_param(cmd, "40_INTOLERANT");
4028 if (val) {
4029 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
4030 /* TODO: iwpriv ht40intol through wpa_supplicant */
4031 send_resp(dut, conn, SIGMA_ERROR,
4032 "ErrorCode,40_INTOLERANT not supported");
4033 return 0;
4034 }
4035 }
4036
4037 val = get_param(cmd, "ADDBA_REJECT");
4038 if (val) {
4039 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
4040 /* reject any ADDBA with status "decline" */
4041 ampdu = 0;
4042 } else {
4043 /* accept ADDBA */
4044 ampdu = 1;
4045 }
4046 }
4047
4048 val = get_param(cmd, "AMPDU");
4049 if (val) {
4050 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
4051 /* enable AMPDU Aggregation */
4052 if (ampdu == 0) {
4053 send_resp(dut, conn, SIGMA_ERROR,
4054 "ErrorCode,Mismatch in "
4055 "addba_reject/ampdu - "
4056 "not supported");
4057 return 0;
4058 }
4059 ampdu = 1;
4060 } else {
4061 /* disable AMPDU Aggregation */
4062 if (ampdu == 1) {
4063 send_resp(dut, conn, SIGMA_ERROR,
4064 "ErrorCode,Mismatch in "
4065 "addba_reject/ampdu - "
4066 "not supported");
4067 return 0;
4068 }
4069 ampdu = 0;
4070 }
4071 }
4072
4073 if (ampdu >= 0) {
4074 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s A-MPDU aggregation",
4075 ampdu ? "Enabling" : "Disabling");
4076 snprintf(buf, sizeof(buf), "SET ampdu %d", ampdu);
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07004077 if (wpa_command(intf, buf) < 0 &&
4078 iwpriv_sta_set_ampdu(dut, intf, ampdu) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004079 send_resp(dut, conn, SIGMA_ERROR,
4080 "ErrorCode,set aggr failed");
4081 return 0;
4082 }
4083 }
4084
4085 val = get_param(cmd, "AMSDU");
4086 if (val) {
4087 switch (get_driver_type()) {
4088 case DRIVER_ATHEROS:
4089 ath_sta_set_amsdu(dut, intf, val);
4090 break;
4091 default:
4092 if (strcmp(val, "1") == 0 ||
4093 strcasecmp(val, "Enable") == 0) {
4094 /* Enable AMSDU Aggregation */
4095 send_resp(dut, conn, SIGMA_ERROR,
4096 "ErrorCode,AMSDU aggregation not supported");
4097 return 0;
4098 }
4099 break;
4100 }
4101 }
4102
4103 val = get_param(cmd, "STBC_RX");
4104 if (val) {
4105 switch (get_driver_type()) {
4106 case DRIVER_ATHEROS:
4107 ath_sta_set_stbc(dut, intf, val);
4108 break;
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05304109 case DRIVER_WCN:
4110 wcn_sta_set_stbc(dut, intf, val);
4111 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004112 default:
4113 send_resp(dut, conn, SIGMA_ERROR,
4114 "ErrorCode,STBC_RX not supported");
4115 return 0;
4116 }
4117 }
4118
4119 val = get_param(cmd, "WIDTH");
4120 if (val) {
4121 switch (get_driver_type()) {
4122 case DRIVER_WCN:
4123 if (wcn_sta_set_cts_width(dut, intf, val) < 0) {
4124 send_resp(dut, conn, SIGMA_ERROR,
4125 "ErrorCode,Failed to set WIDTH");
4126 return 0;
4127 }
4128 break;
4129 case DRIVER_ATHEROS:
4130 if (ath_set_width(dut, conn, intf, val) < 0)
4131 return 0;
4132 break;
4133 default:
4134 sigma_dut_print(dut, DUT_MSG_ERROR,
4135 "Setting WIDTH not supported");
4136 break;
4137 }
4138 }
4139
4140 val = get_param(cmd, "SMPS");
4141 if (val) {
4142 /* TODO: Dynamic/0, Static/1, No Limit/2 */
4143 send_resp(dut, conn, SIGMA_ERROR,
4144 "ErrorCode,SMPS not supported");
4145 return 0;
4146 }
4147
4148 val = get_param(cmd, "TXSP_STREAM");
4149 if (val) {
4150 switch (get_driver_type()) {
4151 case DRIVER_WCN:
4152 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
4153 send_resp(dut, conn, SIGMA_ERROR,
4154 "ErrorCode,Failed to set TXSP_STREAM");
4155 return 0;
4156 }
4157 break;
4158 case DRIVER_ATHEROS:
4159 ath_sta_set_txsp_stream(dut, intf, val);
4160 break;
4161 default:
4162 sigma_dut_print(dut, DUT_MSG_ERROR,
4163 "Setting TXSP_STREAM not supported");
4164 break;
4165 }
4166 }
4167
4168 val = get_param(cmd, "RXSP_STREAM");
4169 if (val) {
4170 switch (get_driver_type()) {
4171 case DRIVER_WCN:
4172 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
4173 send_resp(dut, conn, SIGMA_ERROR,
4174 "ErrorCode,Failed to set RXSP_STREAM");
4175 return 0;
4176 }
4177 break;
4178 case DRIVER_ATHEROS:
4179 ath_sta_set_rxsp_stream(dut, intf, val);
4180 break;
4181 default:
4182 sigma_dut_print(dut, DUT_MSG_ERROR,
4183 "Setting RXSP_STREAM not supported");
4184 break;
4185 }
4186 }
4187
4188 val = get_param(cmd, "DYN_BW_SGNL");
4189 if (val) {
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08004190 switch (get_driver_type()) {
4191 case DRIVER_WCN:
Peng Xuc59afd32016-11-21 15:01:11 -08004192 if (strcasecmp(val, "enable") == 0) {
4193 snprintf(buf, sizeof(buf),
4194 "iwpriv %s cwmenable 1", intf);
4195 if (system(buf) != 0) {
4196 sigma_dut_print(dut, DUT_MSG_ERROR,
4197 "iwpriv cwmenable 1 failed");
4198 return 0;
4199 }
4200 } else if (strcasecmp(val, "disable") == 0) {
4201 snprintf(buf, sizeof(buf),
4202 "iwpriv %s cwmenable 0", intf);
4203 if (system(buf) != 0) {
4204 sigma_dut_print(dut, DUT_MSG_ERROR,
4205 "iwpriv cwmenable 0 failed");
4206 return 0;
4207 }
4208 } else {
4209 sigma_dut_print(dut, DUT_MSG_ERROR,
4210 "Unsupported DYN_BW_SGL");
4211 }
4212
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004213 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 3", intf);
4214 if (system(buf) != 0) {
4215 sigma_dut_print(dut, DUT_MSG_ERROR,
4216 "Failed to set cts_cbw in DYN_BW_SGNL");
4217 return 0;
4218 }
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08004219 break;
4220 case DRIVER_ATHEROS:
priyadharshini gowthamane5e25172015-12-08 14:53:48 -08004221 novap_reset(dut, intf);
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08004222 ath_config_dyn_bw_sig(dut, intf, val);
4223 break;
4224 default:
4225 sigma_dut_print(dut, DUT_MSG_ERROR,
4226 "Failed to set DYN_BW_SGNL");
4227 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004228 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004229 }
4230
4231 val = get_param(cmd, "RTS_FORCE");
4232 if (val) {
priyadharshini gowthamane5e25172015-12-08 14:53:48 -08004233 novap_reset(dut, intf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004234 if (strcasecmp(val, "Enable") == 0) {
4235 snprintf(buf, sizeof(buf), "iwconfig %s rts 64", intf);
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02004236 if (system(buf) != 0) {
4237 sigma_dut_print(dut, DUT_MSG_ERROR,
4238 "Failed to set RTS_FORCE 64");
4239 }
priyadharshini gowthaman270870e2015-12-09 10:10:23 -08004240 snprintf(buf, sizeof(buf),
4241 "wifitool %s beeliner_fw_test 100 1", intf);
4242 if (system(buf) != 0) {
4243 sigma_dut_print(dut, DUT_MSG_ERROR,
4244 "wifitool beeliner_fw_test 100 1 failed");
4245 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004246 } else if (strcasecmp(val, "Disable") == 0) {
4247 snprintf(buf, sizeof(buf), "iwconfig %s rts 2347",
4248 intf);
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02004249 if (system(buf) != 0) {
4250 sigma_dut_print(dut, DUT_MSG_ERROR,
4251 "Failed to set RTS_FORCE 2347");
4252 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004253 } else {
4254 send_resp(dut, conn, SIGMA_ERROR,
4255 "ErrorCode,RTS_FORCE value not supported");
4256 return 0;
4257 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004258 }
4259
4260 val = get_param(cmd, "CTS_WIDTH");
4261 if (val) {
4262 switch (get_driver_type()) {
4263 case DRIVER_WCN:
4264 if (wcn_sta_set_cts_width(dut, intf, val) < 0) {
4265 send_resp(dut, conn, SIGMA_ERROR,
4266 "ErrorCode,Failed to set CTS_WIDTH");
4267 return 0;
4268 }
4269 break;
4270 case DRIVER_ATHEROS:
4271 ath_set_cts_width(dut, intf, val);
4272 break;
4273 default:
4274 sigma_dut_print(dut, DUT_MSG_ERROR,
4275 "Setting CTS_WIDTH not supported");
4276 break;
4277 }
4278 }
4279
4280 val = get_param(cmd, "BW_SGNL");
4281 if (val) {
4282 if (strcasecmp(val, "Enable") == 0) {
4283 snprintf(buf, sizeof(buf), "iwpriv %s cwmenable 1",
4284 intf);
4285 } else if (strcasecmp(val, "Disable") == 0) {
4286 /* TODO: Disable */
4287 buf[0] = '\0';
4288 } else {
4289 send_resp(dut, conn, SIGMA_ERROR,
4290 "ErrorCode,BW_SGNL value not supported");
4291 return 0;
4292 }
4293
4294 if (buf[0] != '\0' && system(buf) != 0) {
4295 sigma_dut_print(dut, DUT_MSG_ERROR,
4296 "Failed to set BW_SGNL");
4297 }
4298 }
4299
4300 val = get_param(cmd, "Band");
4301 if (val) {
4302 if (strcmp(val, "2.4") == 0 || strcmp(val, "5") == 0) {
4303 /* STA supports all bands by default */
4304 } else {
4305 send_resp(dut, conn, SIGMA_ERROR,
4306 "ErrorCode,Unsupported Band");
4307 return 0;
4308 }
4309 }
4310
4311 val = get_param(cmd, "zero_crc");
4312 if (val) {
4313 switch (get_driver_type()) {
4314 case DRIVER_ATHEROS:
4315 ath_set_zero_crc(dut, val);
4316 break;
4317 default:
4318 break;
4319 }
4320 }
4321
4322 return 1;
4323}
4324
4325
4326static int sta_set_60g_common(struct sigma_dut *dut, struct sigma_conn *conn,
4327 struct sigma_cmd *cmd)
4328{
4329 const char *val;
4330 char buf[100];
4331
4332 val = get_param(cmd, "MSDUSize");
4333 if (val) {
4334 int mtu;
4335
4336 dut->amsdu_size = atoi(val);
4337 if (dut->amsdu_size > IEEE80211_MAX_DATA_LEN_DMG ||
4338 dut->amsdu_size < IEEE80211_SNAP_LEN_DMG) {
4339 sigma_dut_print(dut, DUT_MSG_ERROR,
4340 "MSDUSize %d is above max %d or below min %d",
4341 dut->amsdu_size,
4342 IEEE80211_MAX_DATA_LEN_DMG,
4343 IEEE80211_SNAP_LEN_DMG);
4344 dut->amsdu_size = 0;
4345 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4346 }
4347
4348 mtu = dut->amsdu_size - IEEE80211_SNAP_LEN_DMG;
4349 sigma_dut_print(dut, DUT_MSG_DEBUG,
4350 "Setting amsdu_size to %d", mtu);
4351 snprintf(buf, sizeof(buf), "ifconfig %s mtu %d",
4352 get_station_ifname(), mtu);
4353
4354 if (system(buf) != 0) {
4355 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
4356 buf);
4357 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4358 }
4359 }
4360
4361 val = get_param(cmd, "BAckRcvBuf");
4362 if (val) {
4363 dut->back_rcv_buf = atoi(val);
4364 if (dut->back_rcv_buf == 0) {
4365 sigma_dut_print(dut, DUT_MSG_ERROR,
4366 "Failed to convert %s or value is 0",
4367 val);
4368 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4369 }
4370
4371 sigma_dut_print(dut, DUT_MSG_DEBUG,
4372 "Setting BAckRcvBuf to %s", val);
4373 }
4374
4375 return SIGMA_DUT_SUCCESS_CALLER_SEND_STATUS;
4376}
4377
4378
4379static int sta_pcp_start(struct sigma_dut *dut, struct sigma_conn *conn,
4380 struct sigma_cmd *cmd)
4381{
4382 int net_id;
4383 char *ifname;
4384 const char *val;
4385 char buf[100];
4386
4387 dut->mode = SIGMA_MODE_STATION;
4388 ifname = get_main_ifname();
4389 if (wpa_command(ifname, "PING") != 0) {
4390 sigma_dut_print(dut, DUT_MSG_ERROR, "Supplicant not running");
4391 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4392 }
4393
4394 wpa_command(ifname, "FLUSH");
4395 net_id = add_network_common(dut, conn, ifname, cmd);
4396 if (net_id < 0) {
4397 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add network");
4398 return net_id;
4399 }
4400
4401 /* TODO: mode=2 for the AP; in the future, replace for mode PCP */
4402 if (set_network(ifname, net_id, "mode", "2") < 0) {
4403 sigma_dut_print(dut, DUT_MSG_ERROR,
4404 "Failed to set supplicant network mode");
4405 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4406 }
4407
4408 sigma_dut_print(dut, DUT_MSG_DEBUG,
4409 "Supplicant set network with mode 2");
4410
4411 val = get_param(cmd, "Security");
4412 if (val && strcasecmp(val, "OPEN") == 0) {
4413 dut->ap_key_mgmt = AP_OPEN;
4414 if (set_network(ifname, net_id, "key_mgmt", "NONE") < 0) {
4415 sigma_dut_print(dut, DUT_MSG_ERROR,
4416 "Failed to set supplicant to %s security",
4417 val);
4418 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4419 }
4420 } else if (val && strcasecmp(val, "WPA2-PSK") == 0) {
4421 dut->ap_key_mgmt = AP_WPA2_PSK;
4422 if (set_network(ifname, net_id, "key_mgmt", "WPA-PSK") < 0) {
4423 sigma_dut_print(dut, DUT_MSG_ERROR,
4424 "Failed to set supplicant to %s security",
4425 val);
4426 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4427 }
4428
4429 if (set_network(ifname, net_id, "proto", "RSN") < 0) {
4430 sigma_dut_print(dut, DUT_MSG_ERROR,
4431 "Failed to set supplicant to proto RSN");
4432 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4433 }
4434 } else if (val) {
4435 sigma_dut_print(dut, DUT_MSG_ERROR,
4436 "Requested Security %s is not supported on 60GHz",
4437 val);
4438 return SIGMA_DUT_INVALID_CALLER_SEND_STATUS;
4439 }
4440
4441 val = get_param(cmd, "Encrypt");
4442 if (val && strcasecmp(val, "AES-GCMP") == 0) {
4443 if (set_network(ifname, net_id, "pairwise", "GCMP") < 0) {
4444 sigma_dut_print(dut, DUT_MSG_ERROR,
4445 "Failed to set supplicant to pairwise GCMP");
4446 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4447 }
4448 if (set_network(ifname, net_id, "group", "GCMP") < 0) {
4449 sigma_dut_print(dut, DUT_MSG_ERROR,
4450 "Failed to set supplicant to group GCMP");
4451 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4452 }
4453 } else if (val) {
4454 sigma_dut_print(dut, DUT_MSG_ERROR,
4455 "Requested Encrypt %s is not supported on 60 GHz",
4456 val);
4457 return SIGMA_DUT_INVALID_CALLER_SEND_STATUS;
4458 }
4459
4460 val = get_param(cmd, "PSK");
4461 if (val && set_network_quoted(ifname, net_id, "psk", val) < 0) {
4462 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set psk %s",
4463 val);
4464 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4465 }
4466
4467 /* Convert 60G channel to freq */
4468 switch (dut->ap_channel) {
4469 case 1:
4470 val = "58320";
4471 break;
4472 case 2:
4473 val = "60480";
4474 break;
4475 case 3:
4476 val = "62640";
4477 break;
4478 default:
4479 sigma_dut_print(dut, DUT_MSG_ERROR,
4480 "Failed to configure channel %d. Not supported",
4481 dut->ap_channel);
4482 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4483 }
4484
4485 if (set_network(ifname, net_id, "frequency", val) < 0) {
4486 sigma_dut_print(dut, DUT_MSG_ERROR,
4487 "Failed to set supplicant network frequency");
4488 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4489 }
4490
4491 sigma_dut_print(dut, DUT_MSG_DEBUG,
4492 "Supplicant set network with frequency");
4493
4494 snprintf(buf, sizeof(buf), "SELECT_NETWORK %d", net_id);
4495 if (wpa_command(ifname, buf) < 0) {
4496 sigma_dut_print(dut, DUT_MSG_INFO,
4497 "Failed to select network id %d on %s",
4498 net_id, ifname);
4499 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4500 }
4501
4502 sigma_dut_print(dut, DUT_MSG_DEBUG, "Selected network");
4503
4504 return SIGMA_DUT_SUCCESS_CALLER_SEND_STATUS;
4505}
4506
4507
Lior David67543f52017-01-03 19:04:22 +02004508static int wil6210_set_abft_len(struct sigma_dut *dut, int abft_len)
4509{
4510 char buf[128], fname[128];
4511 FILE *f;
4512
4513 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
4514 sigma_dut_print(dut, DUT_MSG_ERROR,
4515 "failed to get wil6210 debugfs dir");
4516 return -1;
4517 }
4518
4519 snprintf(fname, sizeof(fname), "%s/abft_len", buf);
4520 f = fopen(fname, "w");
4521 if (!f) {
4522 sigma_dut_print(dut, DUT_MSG_ERROR,
4523 "failed to open: %s", fname);
4524 return -1;
4525 }
4526
4527 fprintf(f, "%d\n", abft_len);
4528 fclose(f);
4529
4530 return 0;
4531}
4532
4533
4534static int sta_set_60g_abft_len(struct sigma_dut *dut, struct sigma_conn *conn,
4535 int abft_len)
4536{
4537 switch (get_driver_type()) {
4538 case DRIVER_WIL6210:
4539 return wil6210_set_abft_len(dut, abft_len);
4540 default:
4541 sigma_dut_print(dut, DUT_MSG_ERROR,
4542 "set abft_len not supported");
4543 return -1;
4544 }
4545}
4546
4547
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004548static int sta_set_60g_pcp(struct sigma_dut *dut, struct sigma_conn *conn,
4549 struct sigma_cmd *cmd)
4550{
4551 const char *val;
Lior David67543f52017-01-03 19:04:22 +02004552 unsigned int abft_len = 1; /* default is one slot */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004553
4554 if (dut->dev_role != DEVROLE_PCP) {
4555 send_resp(dut, conn, SIGMA_INVALID,
4556 "ErrorCode,Invalid DevRole");
4557 return 0;
4558 }
4559
4560 val = get_param(cmd, "SSID");
4561 if (val) {
4562 if (strlen(val) > sizeof(dut->ap_ssid) - 1) {
4563 send_resp(dut, conn, SIGMA_INVALID,
4564 "ErrorCode,Invalid SSID");
4565 return -1;
4566 }
4567
Peng Xub8fc5cc2017-05-10 17:27:28 -07004568 strlcpy(dut->ap_ssid, val, sizeof(dut->ap_ssid));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004569 }
4570
4571 val = get_param(cmd, "CHANNEL");
4572 if (val) {
4573 const char *pos;
4574
4575 dut->ap_channel = atoi(val);
4576 pos = strchr(val, ';');
4577 if (pos) {
4578 pos++;
4579 dut->ap_channel_1 = atoi(pos);
4580 }
4581 }
4582
4583 switch (dut->ap_channel) {
4584 case 1:
4585 case 2:
4586 case 3:
4587 break;
4588 default:
4589 sigma_dut_print(dut, DUT_MSG_ERROR,
4590 "Channel %d is not supported", dut->ap_channel);
4591 send_resp(dut, conn, SIGMA_ERROR,
4592 "Requested channel is not supported");
4593 return -1;
4594 }
4595
4596 val = get_param(cmd, "BCNINT");
4597 if (val)
4598 dut->ap_bcnint = atoi(val);
4599
4600
4601 val = get_param(cmd, "ExtSchIE");
4602 if (val) {
4603 send_resp(dut, conn, SIGMA_ERROR,
4604 "ErrorCode,ExtSchIE is not supported yet");
4605 return -1;
4606 }
4607
4608 val = get_param(cmd, "AllocType");
4609 if (val) {
4610 send_resp(dut, conn, SIGMA_ERROR,
4611 "ErrorCode,AllocType is not supported yet");
4612 return -1;
4613 }
4614
4615 val = get_param(cmd, "PercentBI");
4616 if (val) {
4617 send_resp(dut, conn, SIGMA_ERROR,
4618 "ErrorCode,PercentBI is not supported yet");
4619 return -1;
4620 }
4621
4622 val = get_param(cmd, "CBAPOnly");
4623 if (val) {
4624 send_resp(dut, conn, SIGMA_ERROR,
4625 "ErrorCode,CBAPOnly is not supported yet");
4626 return -1;
4627 }
4628
4629 val = get_param(cmd, "AMPDU");
4630 if (val) {
4631 if (strcasecmp(val, "Enable") == 0)
4632 dut->ap_ampdu = 1;
4633 else if (strcasecmp(val, "Disable") == 0)
4634 dut->ap_ampdu = 2;
4635 else {
4636 send_resp(dut, conn, SIGMA_ERROR,
4637 "ErrorCode,AMPDU value is not Enable nor Disabled");
4638 return -1;
4639 }
4640 }
4641
4642 val = get_param(cmd, "AMSDU");
4643 if (val) {
4644 if (strcasecmp(val, "Enable") == 0)
4645 dut->ap_amsdu = 1;
4646 else if (strcasecmp(val, "Disable") == 0)
4647 dut->ap_amsdu = 2;
4648 }
4649
4650 val = get_param(cmd, "NumMSDU");
4651 if (val) {
4652 send_resp(dut, conn, SIGMA_ERROR,
4653 "ErrorCode, NumMSDU is not supported yet");
4654 return -1;
4655 }
4656
4657 val = get_param(cmd, "ABFTLRang");
4658 if (val) {
4659 sigma_dut_print(dut, DUT_MSG_DEBUG,
Lior David67543f52017-01-03 19:04:22 +02004660 "ABFTLRang parameter %s", val);
4661 if (strcmp(val, "Gt1") == 0)
4662 abft_len = 2; /* 2 slots in this case */
4663 }
4664
4665 if (sta_set_60g_abft_len(dut, conn, abft_len)) {
4666 send_resp(dut, conn, SIGMA_ERROR,
4667 "ErrorCode, Can't set ABFT length");
4668 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004669 }
4670
4671 if (sta_pcp_start(dut, conn, cmd) < 0) {
4672 send_resp(dut, conn, SIGMA_ERROR,
4673 "ErrorCode, Can't start PCP role");
4674 return -1;
4675 }
4676
4677 return sta_set_60g_common(dut, conn, cmd);
4678}
4679
4680
4681static int sta_set_60g_sta(struct sigma_dut *dut, struct sigma_conn *conn,
4682 struct sigma_cmd *cmd)
4683{
4684 const char *val = get_param(cmd, "DiscoveryMode");
4685
4686 if (dut->dev_role != DEVROLE_STA) {
4687 send_resp(dut, conn, SIGMA_INVALID,
4688 "ErrorCode,Invalid DevRole");
4689 return 0;
4690 }
4691
4692 if (val) {
4693 sigma_dut_print(dut, DUT_MSG_DEBUG, "Discovery: %s", val);
4694 /* Ignore Discovery mode till Driver expose API. */
4695#if 0
4696 if (strcasecmp(val, "1") == 0) {
4697 send_resp(dut, conn, SIGMA_INVALID,
4698 "ErrorCode,DiscoveryMode 1 not supported");
4699 return 0;
4700 }
4701
4702 if (strcasecmp(val, "0") == 0) {
4703 /* OK */
4704 } else {
4705 send_resp(dut, conn, SIGMA_INVALID,
4706 "ErrorCode,DiscoveryMode not supported");
4707 return 0;
4708 }
4709#endif
4710 }
4711
4712 if (start_sta_mode(dut) != 0)
4713 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4714 return sta_set_60g_common(dut, conn, cmd);
4715}
4716
4717
4718static int cmd_sta_disconnect(struct sigma_dut *dut, struct sigma_conn *conn,
4719 struct sigma_cmd *cmd)
4720{
4721 const char *intf = get_param(cmd, "Interface");
Jouni Malinened77e672018-01-10 16:45:13 +02004722 const char *val = get_param(cmd, "maintain_profile");
vamsi krishnad605c422017-09-20 14:56:31 +05304723
Jouni Malinened77e672018-01-10 16:45:13 +02004724 if (dut->program == PROGRAM_OCE ||
4725 (val && atoi(val) == 1)) {
vamsi krishnad605c422017-09-20 14:56:31 +05304726 wpa_command(intf, "DISCONNECT");
4727 return 1;
4728 }
4729
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004730 disconnect_station(dut);
4731 /* Try to ignore old scan results to avoid HS 2.0R2 test case failures
4732 * due to cached results. */
4733 wpa_command(intf, "SET ignore_old_scan_res 1");
4734 wpa_command(intf, "BSS_FLUSH");
4735 return 1;
4736}
4737
4738
4739static int cmd_sta_reassoc(struct sigma_dut *dut, struct sigma_conn *conn,
4740 struct sigma_cmd *cmd)
4741{
4742 const char *intf = get_param(cmd, "Interface");
4743 const char *bssid = get_param(cmd, "bssid");
4744 const char *val = get_param(cmd, "CHANNEL");
4745 struct wpa_ctrl *ctrl;
4746 char buf[100];
Sunil Duttd30ce092018-01-11 23:56:29 +05304747 char result[32];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004748 int res;
4749 int chan = 0;
Ashwini Patil467efef2017-05-25 12:18:27 +05304750 int status = 0;
Sunil Duttd30ce092018-01-11 23:56:29 +05304751 int fastreassoc = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004752
4753 if (bssid == NULL) {
4754 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing bssid "
4755 "argument");
4756 return 0;
4757 }
4758
4759 if (val)
4760 chan = atoi(val);
4761
4762 if (wifi_chip_type != DRIVER_WCN && wifi_chip_type != DRIVER_AR6003) {
4763 /* The current network may be from sta_associate or
4764 * sta_hs2_associate
4765 */
4766 if (set_network(intf, dut->infra_network_id, "bssid", bssid) <
4767 0 ||
4768 set_network(intf, 0, "bssid", bssid) < 0)
4769 return -2;
4770 }
4771
4772 ctrl = open_wpa_mon(intf);
4773 if (ctrl == NULL) {
4774 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
4775 "wpa_supplicant monitor connection");
4776 return -1;
4777 }
4778
Sunil Duttd30ce092018-01-11 23:56:29 +05304779 if (get_wpa_status(get_station_ifname(), "wpa_state", result,
4780 sizeof(result)) < 0 ||
4781 strncmp(result, "COMPLETED", 9) != 0) {
4782 sigma_dut_print(dut, DUT_MSG_DEBUG,
4783 "sta_reassoc: Not connected");
4784 fastreassoc = 0;
4785 }
4786
4787 if (wifi_chip_type == DRIVER_WCN && fastreassoc) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004788#ifdef ANDROID
Ashwini Patil4c8158f2017-05-25 12:49:21 +05304789 if (chan) {
4790 unsigned int freq;
4791
4792 freq = channel_to_freq(chan);
4793 if (!freq) {
4794 sigma_dut_print(dut, DUT_MSG_ERROR,
4795 "Invalid channel number provided: %d",
4796 chan);
4797 send_resp(dut, conn, SIGMA_INVALID,
4798 "ErrorCode,Invalid channel number");
4799 goto close_mon_conn;
4800 }
4801 res = snprintf(buf, sizeof(buf),
4802 "SCAN TYPE=ONLY freq=%d", freq);
4803 } else {
4804 res = snprintf(buf, sizeof(buf), "SCAN TYPE=ONLY");
4805 }
4806 if (res < 0 || res >= (int) sizeof(buf)) {
4807 send_resp(dut, conn, SIGMA_ERROR,
4808 "ErrorCode,snprintf failed");
4809 goto close_mon_conn;
4810 }
4811 if (wpa_command(intf, buf) < 0) {
4812 sigma_dut_print(dut, DUT_MSG_INFO,
4813 "Failed to start scan");
4814 send_resp(dut, conn, SIGMA_ERROR,
4815 "ErrorCode,scan failed");
4816 goto close_mon_conn;
4817 }
4818
4819 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
4820 buf, sizeof(buf));
4821 if (res < 0) {
4822 sigma_dut_print(dut, DUT_MSG_INFO,
4823 "Scan did not complete");
4824 send_resp(dut, conn, SIGMA_ERROR,
4825 "ErrorCode,scan did not complete");
4826 goto close_mon_conn;
4827 }
4828
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004829 if (set_network(intf, dut->infra_network_id, "bssid", "any")
4830 < 0) {
4831 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
4832 "bssid to any during FASTREASSOC");
Ashwini Patil467efef2017-05-25 12:18:27 +05304833 status = -2;
4834 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004835 }
4836 res = snprintf(buf, sizeof(buf), "DRIVER FASTREASSOC %s %d",
4837 bssid, chan);
4838 if (res > 0 && res < (int) sizeof(buf))
4839 res = wpa_command(intf, buf);
4840
4841 if (res < 0 || res >= (int) sizeof(buf)) {
4842 send_resp(dut, conn, SIGMA_ERROR,
4843 "errorCode,Failed to run DRIVER FASTREASSOC");
Ashwini Patil467efef2017-05-25 12:18:27 +05304844 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004845 }
4846#else /* ANDROID */
4847 sigma_dut_print(dut, DUT_MSG_DEBUG,
4848 "Reassoc using iwpriv - skip chan=%d info",
4849 chan);
4850 snprintf(buf, sizeof(buf), "iwpriv %s reassoc", intf);
4851 if (system(buf) != 0) {
4852 sigma_dut_print(dut, DUT_MSG_ERROR, "%s failed", buf);
Ashwini Patil467efef2017-05-25 12:18:27 +05304853 status = -2;
4854 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004855 }
4856#endif /* ANDROID */
4857 sigma_dut_print(dut, DUT_MSG_INFO,
4858 "sta_reassoc: Run %s successful", buf);
4859 } else if (wpa_command(intf, "REASSOCIATE")) {
4860 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
4861 "request reassociation");
Ashwini Patil467efef2017-05-25 12:18:27 +05304862 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004863 }
4864
4865 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
4866 buf, sizeof(buf));
Ashwini Patil467efef2017-05-25 12:18:27 +05304867 if (res < 0) {
4868 sigma_dut_print(dut, DUT_MSG_INFO, "Connection did not complete");
4869 status = -1;
4870 goto close_mon_conn;
4871 }
4872 status = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004873
Ashwini Patil467efef2017-05-25 12:18:27 +05304874close_mon_conn:
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004875 wpa_ctrl_detach(ctrl);
4876 wpa_ctrl_close(ctrl);
Ashwini Patil467efef2017-05-25 12:18:27 +05304877 return status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004878}
4879
4880
4881static void hs2_clear_credentials(const char *intf)
4882{
4883 wpa_command(intf, "REMOVE_CRED all");
4884}
4885
4886
Lior Davidcc88b562017-01-03 18:52:09 +02004887#ifdef __linux__
4888static int wil6210_get_aid(struct sigma_dut *dut, const char *bssid,
4889 unsigned int *aid)
4890{
Lior David0fe101e2017-03-09 16:09:50 +02004891 const char *pattern = "AID[ \t]+([0-9]+)";
Lior Davidcc88b562017-01-03 18:52:09 +02004892
Lior David0fe101e2017-03-09 16:09:50 +02004893 return wil6210_get_sta_info_field(dut, bssid, pattern, aid);
Lior Davidcc88b562017-01-03 18:52:09 +02004894}
4895#endif /* __linux__ */
4896
4897
4898static int sta_get_aid_60g(struct sigma_dut *dut, const char *bssid,
4899 unsigned int *aid)
4900{
4901 switch (get_driver_type()) {
4902#ifdef __linux__
4903 case DRIVER_WIL6210:
4904 return wil6210_get_aid(dut, bssid, aid);
4905#endif /* __linux__ */
4906 default:
4907 sigma_dut_print(dut, DUT_MSG_ERROR, "get AID not supported");
4908 return -1;
4909 }
4910}
4911
4912
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004913static int sta_get_parameter_60g(struct sigma_dut *dut, struct sigma_conn *conn,
4914 struct sigma_cmd *cmd)
4915{
4916 char buf[MAX_CMD_LEN];
4917 char bss_list[MAX_CMD_LEN];
4918 const char *parameter = get_param(cmd, "Parameter");
4919
4920 if (parameter == NULL)
4921 return -1;
4922
Lior Davidcc88b562017-01-03 18:52:09 +02004923 if (strcasecmp(parameter, "AID") == 0) {
4924 unsigned int aid = 0;
4925 char bssid[20];
4926
4927 if (get_wpa_status(get_station_ifname(), "bssid",
4928 bssid, sizeof(bssid)) < 0) {
4929 sigma_dut_print(dut, DUT_MSG_ERROR,
4930 "could not get bssid");
4931 return -2;
4932 }
4933
4934 if (sta_get_aid_60g(dut, bssid, &aid))
4935 return -2;
4936
4937 snprintf(buf, sizeof(buf), "aid,%d", aid);
4938 sigma_dut_print(dut, DUT_MSG_INFO, "%s", buf);
4939 send_resp(dut, conn, SIGMA_COMPLETE, buf);
4940 return 0;
4941 }
4942
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004943 if (strcasecmp(parameter, "DiscoveredDevList") == 0) {
4944 char *bss_line;
4945 char *bss_id = NULL;
4946 const char *ifname = get_param(cmd, "Interface");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05304947 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004948
4949 if (ifname == NULL) {
4950 sigma_dut_print(dut, DUT_MSG_INFO,
4951 "For get DiscoveredDevList need Interface name.");
4952 return -1;
4953 }
4954
4955 /*
4956 * Use "BSS RANGE=ALL MASK=0x2" which provides a list
4957 * of BSSIDs in "bssid=<BSSID>\n"
4958 */
4959 if (wpa_command_resp(ifname, "BSS RANGE=ALL MASK=0x2",
4960 bss_list,
4961 sizeof(bss_list)) < 0) {
4962 sigma_dut_print(dut, DUT_MSG_ERROR,
4963 "Failed to get bss list");
4964 return -1;
4965 }
4966
4967 sigma_dut_print(dut, DUT_MSG_DEBUG,
4968 "bss list for ifname:%s is:%s",
4969 ifname, bss_list);
4970
4971 snprintf(buf, sizeof(buf), "DeviceList");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05304972 bss_line = strtok_r(bss_list, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004973 while (bss_line) {
4974 if (sscanf(bss_line, "bssid=%ms", &bss_id) > 0 &&
4975 bss_id) {
4976 int len;
4977
4978 len = snprintf(buf + strlen(buf),
4979 sizeof(buf) - strlen(buf),
4980 ",%s", bss_id);
4981 free(bss_id);
4982 bss_id = NULL;
4983 if (len < 0) {
4984 sigma_dut_print(dut,
4985 DUT_MSG_ERROR,
4986 "Failed to read BSSID");
4987 send_resp(dut, conn, SIGMA_ERROR,
4988 "ErrorCode,Failed to read BSS ID");
4989 return 0;
4990 }
4991
4992 if ((size_t) len >= sizeof(buf) - strlen(buf)) {
4993 sigma_dut_print(dut,
4994 DUT_MSG_ERROR,
4995 "Response buf too small for list");
4996 send_resp(dut, conn,
4997 SIGMA_ERROR,
4998 "ErrorCode,Response buf too small for list");
4999 return 0;
5000 }
5001 }
5002
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05305003 bss_line = strtok_r(NULL, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005004 }
5005
5006 sigma_dut_print(dut, DUT_MSG_INFO, "DiscoveredDevList is %s",
5007 buf);
5008 send_resp(dut, conn, SIGMA_COMPLETE, buf);
5009 return 0;
5010 }
5011
5012 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
5013 return 0;
5014}
5015
5016
5017static int cmd_sta_get_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
5018 struct sigma_cmd *cmd)
5019{
5020 const char *program = get_param(cmd, "Program");
5021
5022 if (program == NULL)
5023 return -1;
5024
5025 if (strcasecmp(program, "P2PNFC") == 0)
5026 return p2p_cmd_sta_get_parameter(dut, conn, cmd);
5027
5028 if (strcasecmp(program, "60ghz") == 0)
5029 return sta_get_parameter_60g(dut, conn, cmd);
5030
5031#ifdef ANDROID_NAN
5032 if (strcasecmp(program, "NAN") == 0)
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07005033 return nan_cmd_sta_get_parameter(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005034#endif /* ANDROID_NAN */
5035
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07005036#ifdef MIRACAST
5037 if (strcasecmp(program, "WFD") == 0 ||
5038 strcasecmp(program, "DisplayR2") == 0)
5039 return miracast_cmd_sta_get_parameter(dut, conn, cmd);
5040#endif /* MIRACAST */
5041
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005042 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
5043 return 0;
5044}
5045
5046
5047static void sta_reset_default_ath(struct sigma_dut *dut, const char *intf,
5048 const char *type)
5049{
5050 char buf[100];
5051
5052 if (dut->program == PROGRAM_VHT) {
5053 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 2", intf);
5054 if (system(buf) != 0) {
5055 sigma_dut_print(dut, DUT_MSG_ERROR,
5056 "iwpriv %s chwidth failed", intf);
5057 }
5058
5059 snprintf(buf, sizeof(buf), "iwpriv %s mode 11ACVHT80", intf);
5060 if (system(buf) != 0) {
5061 sigma_dut_print(dut, DUT_MSG_ERROR,
5062 "iwpriv %s mode 11ACVHT80 failed",
5063 intf);
5064 }
5065
5066 snprintf(buf, sizeof(buf), "iwpriv %s vhtmcs -1", intf);
5067 if (system(buf) != 0) {
5068 sigma_dut_print(dut, DUT_MSG_ERROR,
5069 "iwpriv %s vhtmcs -1 failed", intf);
5070 }
5071 }
5072
5073 if (dut->program == PROGRAM_HT) {
5074 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 0", intf);
5075 if (system(buf) != 0) {
5076 sigma_dut_print(dut, DUT_MSG_ERROR,
5077 "iwpriv %s chwidth failed", intf);
5078 }
5079
5080 snprintf(buf, sizeof(buf), "iwpriv %s mode 11naht40", intf);
5081 if (system(buf) != 0) {
5082 sigma_dut_print(dut, DUT_MSG_ERROR,
5083 "iwpriv %s mode 11naht40 failed",
5084 intf);
5085 }
5086
5087 snprintf(buf, sizeof(buf), "iwpriv %s set11NRates 0", intf);
5088 if (system(buf) != 0) {
5089 sigma_dut_print(dut, DUT_MSG_ERROR,
5090 "iwpriv set11NRates failed");
5091 }
5092 }
5093
5094 if (dut->program == PROGRAM_VHT || dut->program == PROGRAM_HT) {
5095 snprintf(buf, sizeof(buf), "iwpriv %s powersave 0", intf);
5096 if (system(buf) != 0) {
5097 sigma_dut_print(dut, DUT_MSG_ERROR,
5098 "disabling powersave failed");
5099 }
5100
5101 /* Reset CTS width */
5102 snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 54 0",
5103 intf);
5104 if (system(buf) != 0) {
5105 sigma_dut_print(dut, DUT_MSG_ERROR,
5106 "wifitool %s beeliner_fw_test 54 0 failed",
5107 intf);
5108 }
5109
5110 /* Enable Dynamic Bandwidth signalling by default */
5111 snprintf(buf, sizeof(buf), "iwpriv %s cwmenable 1", intf);
5112 if (system(buf) != 0) {
5113 sigma_dut_print(dut, DUT_MSG_ERROR,
5114 "iwpriv %s cwmenable 1 failed", intf);
5115 }
5116
5117 snprintf(buf, sizeof(buf), "iwconfig %s rts 2347", intf);
5118 if (system(buf) != 0) {
5119 sigma_dut_print(dut, DUT_MSG_ERROR,
5120 "iwpriv rts failed");
5121 }
5122 }
5123
5124 if (type && strcasecmp(type, "Testbed") == 0) {
5125 dut->testbed_flag_txsp = 1;
5126 dut->testbed_flag_rxsp = 1;
5127 /* STA has to set spatial stream to 2 per Appendix H */
5128 snprintf(buf, sizeof(buf), "iwpriv %s vht_mcsmap 0xfff0", intf);
5129 if (system(buf) != 0) {
5130 sigma_dut_print(dut, DUT_MSG_ERROR,
5131 "iwpriv vht_mcsmap failed");
5132 }
5133
5134 /* Disable LDPC per Appendix H */
5135 snprintf(buf, sizeof(buf), "iwpriv %s ldpc 0", intf);
5136 if (system(buf) != 0) {
5137 sigma_dut_print(dut, DUT_MSG_ERROR,
5138 "iwpriv %s ldpc 0 failed", intf);
5139 }
5140
5141 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 1", intf);
5142 if (system(buf) != 0) {
5143 sigma_dut_print(dut, DUT_MSG_ERROR,
5144 "iwpriv amsdu failed");
5145 }
5146
5147 /* TODO: Disable STBC 2x1 transmit and receive */
5148 snprintf(buf, sizeof(buf), "iwpriv %s tx_stbc 0", intf);
5149 if (system(buf) != 0) {
5150 sigma_dut_print(dut, DUT_MSG_ERROR,
5151 "Disable tx_stbc 0 failed");
5152 }
5153
5154 snprintf(buf, sizeof(buf), "iwpriv %s rx_stbc 0", intf);
5155 if (system(buf) != 0) {
5156 sigma_dut_print(dut, DUT_MSG_ERROR,
5157 "Disable rx_stbc 0 failed");
5158 }
5159
5160 /* STA has to disable Short GI per Appendix H */
5161 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 0", intf);
5162 if (system(buf) != 0) {
5163 sigma_dut_print(dut, DUT_MSG_ERROR,
5164 "iwpriv %s shortgi 0 failed", intf);
5165 }
5166 }
5167
5168 if (type && strcasecmp(type, "DUT") == 0) {
5169 snprintf(buf, sizeof(buf), "iwpriv %s nss 3", intf);
5170 if (system(buf) != 0) {
5171 sigma_dut_print(dut, DUT_MSG_ERROR,
5172 "iwpriv %s nss 3 failed", intf);
5173 }
5174
5175 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 1", intf);
5176 if (system(buf) != 0) {
5177 sigma_dut_print(dut, DUT_MSG_ERROR,
5178 "iwpriv %s shortgi 1 failed", intf);
5179 }
5180 }
5181}
5182
5183
5184static int cmd_sta_reset_default(struct sigma_dut *dut,
5185 struct sigma_conn *conn,
5186 struct sigma_cmd *cmd)
5187{
5188 int cmd_sta_p2p_reset(struct sigma_dut *dut, struct sigma_conn *conn,
5189 struct sigma_cmd *cmd);
5190 const char *intf = get_param(cmd, "Interface");
5191 const char *type;
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07005192 const char *program = get_param(cmd, "program");
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05305193 const char *dev_role = get_param(cmd, "DevRole");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005194
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07005195 if (!program)
5196 program = get_param(cmd, "prog");
5197 dut->program = sigma_program_to_enum(program);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005198 dut->device_type = STA_unknown;
5199 type = get_param(cmd, "type");
5200 if (type && strcasecmp(type, "Testbed") == 0)
5201 dut->device_type = STA_testbed;
5202 if (type && strcasecmp(type, "DUT") == 0)
5203 dut->device_type = STA_dut;
5204
5205 if (dut->program == PROGRAM_TDLS) {
5206 /* Clear TDLS testing mode */
5207 wpa_command(intf, "SET tdls_disabled 0");
5208 wpa_command(intf, "SET tdls_testing 0");
5209 dut->no_tpk_expiration = 0;
Pradeep Reddy POTTETI8ce2a232016-10-28 12:17:32 +05305210 if (get_driver_type() == DRIVER_WCN) {
5211 /* Enable the WCN driver in TDLS Explicit trigger mode
5212 */
5213 wpa_command(intf, "SET tdls_external_control 0");
5214 wpa_command(intf, "SET tdls_trigger_control 0");
5215 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005216 }
5217
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07005218#ifdef MIRACAST
5219 if (dut->program == PROGRAM_WFD ||
5220 dut->program == PROGRAM_DISPLAYR2)
5221 miracast_sta_reset_default(dut, conn, cmd);
5222#endif /* MIRACAST */
5223
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005224 switch (get_driver_type()) {
5225 case DRIVER_ATHEROS:
5226 sta_reset_default_ath(dut, intf, type);
5227 break;
5228 default:
5229 break;
5230 }
5231
5232#ifdef ANDROID_NAN
5233 if (dut->program == PROGRAM_NAN)
5234 nan_cmd_sta_reset_default(dut, conn, cmd);
5235#endif /* ANDROID_NAN */
5236
5237 if (dut->program == PROGRAM_HS2_R2) {
5238 unlink("SP/wi-fi.org/pps.xml");
5239 if (system("rm -r SP/*") != 0) {
5240 }
5241 unlink("next-client-cert.pem");
5242 unlink("next-client-key.pem");
5243 }
5244
5245 if (dut->program == PROGRAM_60GHZ) {
5246 const char *dev_role = get_param(cmd, "DevRole");
5247
5248 if (!dev_role) {
5249 send_resp(dut, conn, SIGMA_ERROR,
5250 "errorCode,Missing DevRole argument");
5251 return 0;
5252 }
5253
5254 if (strcasecmp(dev_role, "STA") == 0)
5255 dut->dev_role = DEVROLE_STA;
5256 else if (strcasecmp(dev_role, "PCP") == 0)
5257 dut->dev_role = DEVROLE_PCP;
5258 else {
5259 send_resp(dut, conn, SIGMA_ERROR,
5260 "errorCode,Unknown DevRole");
5261 return 0;
5262 }
5263
5264 if (dut->device_type == STA_unknown) {
5265 sigma_dut_print(dut, DUT_MSG_ERROR,
5266 "Device type is not STA testbed or DUT");
5267 send_resp(dut, conn, SIGMA_ERROR,
5268 "errorCode,Unknown device type");
5269 return 0;
5270 }
5271 }
5272
5273 wpa_command(intf, "WPS_ER_STOP");
5274 wpa_command(intf, "FLUSH");
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05305275 wpa_command(intf, "ERP_FLUSH");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005276 wpa_command(intf, "SET radio_disabled 0");
5277
5278 if (dut->tmp_mac_addr && dut->set_macaddr) {
5279 dut->tmp_mac_addr = 0;
5280 if (system(dut->set_macaddr) != 0) {
5281 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to clear "
5282 "temporary MAC address");
5283 }
5284 }
5285
5286 set_ps(intf, dut, 0);
5287
5288 if (dut->program == PROGRAM_HS2 || dut->program == PROGRAM_HS2_R2) {
5289 wpa_command(intf, "SET interworking 1");
5290 wpa_command(intf, "SET hs20 1");
5291 }
5292
Deepak Dhamdhere0fe0e452017-12-18 14:52:09 -08005293 if (dut->program == PROGRAM_HS2_R2 ||
5294 dut->program == PROGRAM_OCE) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005295 wpa_command(intf, "SET pmf 1");
5296 } else {
5297 wpa_command(intf, "SET pmf 0");
5298 }
5299
5300 hs2_clear_credentials(intf);
5301 wpa_command(intf, "SET hessid 00:00:00:00:00:00");
5302 wpa_command(intf, "SET access_network_type 15");
5303
5304 static_ip_file(0, NULL, NULL, NULL);
5305 kill_dhcp_client(dut, intf);
5306 clear_ip_addr(dut, intf);
5307
5308 dut->er_oper_performed = 0;
5309 dut->er_oper_bssid[0] = '\0';
5310
priyadharshini gowthamanad6cbba2016-10-04 10:39:58 -07005311 if (dut->program == PROGRAM_LOC) {
5312 /* Disable Interworking by default */
5313 wpa_command(get_station_ifname(), "SET interworking 0");
5314 }
5315
Ashwini Patil00402582017-04-13 12:29:39 +05305316 if (dut->program == PROGRAM_MBO) {
5317 free(dut->non_pref_ch_list);
5318 dut->non_pref_ch_list = NULL;
Ashwini Patil5acd7382017-04-13 15:55:04 +05305319 free(dut->btm_query_cand_list);
5320 dut->btm_query_cand_list = NULL;
Ashwini Patilc63161e2017-04-13 16:30:23 +05305321 wpa_command(intf, "SET reject_btm_req_reason 0");
Ashwini Patila75de5a2017-04-13 16:35:05 +05305322 wpa_command(intf, "SET ignore_assoc_disallow 0");
Ashwini Patild174f2c2017-04-13 16:49:46 +05305323 wpa_command(intf, "SET gas_address3 0");
Ashwini Patil9183fdb2017-04-13 16:58:25 +05305324 wpa_command(intf, "SET roaming 1");
Ashwini Patil00402582017-04-13 12:29:39 +05305325 }
5326
Jouni Malinen3c367e82017-06-23 17:01:47 +03005327 free(dut->rsne_override);
5328 dut->rsne_override = NULL;
5329
Jouni Malinen68143132017-09-02 02:34:08 +03005330 free(dut->sae_commit_override);
5331 dut->sae_commit_override = NULL;
5332
Jouni Malinend86e5822017-08-29 03:55:32 +03005333 dut->dpp_conf_id = -1;
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02005334 free(dut->dpp_peer_uri);
5335 dut->dpp_peer_uri = NULL;
Jouni Malinen63d50412017-11-24 11:55:38 +02005336 dut->dpp_local_bootstrap = -1;
Jouni Malinen5011fb52017-12-05 21:00:15 +02005337 wpa_command(intf, "SET dpp_config_processing 2");
Jouni Malinend86e5822017-08-29 03:55:32 +03005338
Jouni Malinenfac9cad2017-10-10 18:35:55 +03005339 wpa_command(intf, "VENDOR_ELEM_REMOVE 13 *");
5340
vamsi krishnaa2799492017-12-05 14:28:01 +05305341 if (dut->program == PROGRAM_OCE) {
Ankita Bajaja2cb5672017-10-25 16:08:28 +05305342 wpa_command(intf, "SET oce 1");
vamsi krishnaa2799492017-12-05 14:28:01 +05305343 wpa_command(intf, "SET disable_fils 0");
Ankita Bajaj1bde7942018-01-09 19:15:01 +05305344 wpa_command(intf, "FILS_HLP_REQ_FLUSH");
5345 dut->fils_hlp = 0;
5346#ifdef ANDROID
5347 hlp_thread_cleanup(dut);
5348#endif /* ANDROID */
vamsi krishnaa2799492017-12-05 14:28:01 +05305349 }
Ankita Bajaja2cb5672017-10-25 16:08:28 +05305350
Sunil Dutt076081f2018-02-05 19:45:50 +05305351#ifdef NL80211_SUPPORT
Sunil Dutt44595082018-02-12 19:41:45 +05305352 if (get_driver_type() == DRIVER_WCN &&
5353 dut->config_rsnie == 1) {
5354 dut->config_rsnie = 0;
5355 sta_config_rsnie(dut, 0);
Sunil Dutt076081f2018-02-05 19:45:50 +05305356 }
5357#endif /* NL80211_SUPPORT */
5358
Sunil Duttfebf8a82018-02-09 18:50:13 +05305359 if (dev_role && strcasecmp(dev_role, "STA-CFON") == 0) {
5360 dut->dev_role = DEVROLE_STA_CFON;
5361 return sta_cfon_reset_default(dut, conn, cmd);
5362 }
5363
5364 if (dut->program != PROGRAM_VHT)
5365 return cmd_sta_p2p_reset(dut, conn, cmd);
5366
Priyadharshini Gowthamana7dfd492015-11-09 14:34:08 -08005367 return 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005368}
5369
5370
5371static int cmd_sta_get_events(struct sigma_dut *dut, struct sigma_conn *conn,
5372 struct sigma_cmd *cmd)
5373{
5374 const char *program = get_param(cmd, "Program");
5375
5376 if (program == NULL)
5377 return -1;
5378#ifdef ANDROID_NAN
5379 if (strcasecmp(program, "NAN") == 0)
5380 return nan_cmd_sta_get_events(dut, conn, cmd);
5381#endif /* ANDROID_NAN */
5382 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
5383 return 0;
5384}
5385
5386
5387static int cmd_sta_exec_action(struct sigma_dut *dut, struct sigma_conn *conn,
5388 struct sigma_cmd *cmd)
5389{
5390 const char *program = get_param(cmd, "Prog");
5391
5392 if (program == NULL)
5393 return -1;
5394#ifdef ANDROID_NAN
5395 if (strcasecmp(program, "NAN") == 0)
5396 return nan_cmd_sta_exec_action(dut, conn, cmd);
5397#endif /* ANDROID_NAN */
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07005398 if (strcasecmp(program, "Loc") == 0)
5399 return loc_cmd_sta_exec_action(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005400 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
5401 return 0;
5402}
5403
5404
5405static int cmd_sta_set_11n(struct sigma_dut *dut, struct sigma_conn *conn,
5406 struct sigma_cmd *cmd)
5407{
5408 const char *intf = get_param(cmd, "Interface");
5409 const char *val, *mcs32, *rate;
5410
5411 val = get_param(cmd, "GREENFIELD");
5412 if (val) {
5413 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
5414 /* Enable GD */
5415 send_resp(dut, conn, SIGMA_ERROR,
5416 "ErrorCode,GF not supported");
5417 return 0;
5418 }
5419 }
5420
5421 val = get_param(cmd, "SGI20");
5422 if (val) {
5423 switch (get_driver_type()) {
5424 case DRIVER_ATHEROS:
5425 ath_sta_set_sgi(dut, intf, val);
5426 break;
5427 default:
5428 send_resp(dut, conn, SIGMA_ERROR,
5429 "ErrorCode,SGI20 not supported");
5430 return 0;
5431 }
5432 }
5433
5434 mcs32 = get_param(cmd, "MCS32"); /* HT Duplicate Mode Enable/Disable */
5435 rate = get_param(cmd, "MCS_FIXEDRATE"); /* Fixed MCS rate (0..31) */
5436 if (mcs32 && rate) {
5437 /* TODO */
5438 send_resp(dut, conn, SIGMA_ERROR,
5439 "ErrorCode,MCS32,MCS_FIXEDRATE not supported");
5440 return 0;
5441 } else if (mcs32 && !rate) {
5442 /* TODO */
5443 send_resp(dut, conn, SIGMA_ERROR,
5444 "ErrorCode,MCS32 not supported");
5445 return 0;
5446 } else if (!mcs32 && rate) {
5447 switch (get_driver_type()) {
5448 case DRIVER_ATHEROS:
priyadharshini gowthamane5e25172015-12-08 14:53:48 -08005449 novap_reset(dut, intf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005450 ath_sta_set_11nrates(dut, intf, rate);
5451 break;
5452 default:
5453 send_resp(dut, conn, SIGMA_ERROR,
5454 "ErrorCode,MCS32_FIXEDRATE not supported");
5455 return 0;
5456 }
5457 }
5458
5459 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
5460}
5461
5462
5463static int cmd_sta_set_wireless_vht(struct sigma_dut *dut,
5464 struct sigma_conn *conn,
5465 struct sigma_cmd *cmd)
5466{
5467 const char *intf = get_param(cmd, "Interface");
5468 const char *val;
5469 char buf[30];
5470 int tkip = -1;
5471 int wep = -1;
5472
5473 val = get_param(cmd, "SGI80");
5474 if (val) {
5475 int sgi80;
5476
5477 sgi80 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
5478 snprintf(buf, sizeof(buf), "iwpriv %s shortgi %d", intf, sgi80);
5479 if (system(buf) != 0) {
5480 sigma_dut_print(dut, DUT_MSG_ERROR,
5481 "iwpriv shortgi failed");
5482 }
5483 }
5484
5485 val = get_param(cmd, "TxBF");
5486 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
5487 snprintf(buf, sizeof(buf), "iwpriv %s vhtsubfee 1", intf);
5488 if (system(buf) != 0) {
5489 sigma_dut_print(dut, DUT_MSG_ERROR,
5490 "iwpriv vhtsubfee failed");
5491 }
5492 snprintf(buf, sizeof(buf), "iwpriv %s vhtsubfer 1", intf);
5493 if (system(buf) != 0) {
5494 sigma_dut_print(dut, DUT_MSG_ERROR,
5495 "iwpriv vhtsubfer failed");
5496 }
5497 }
5498
5499 val = get_param(cmd, "MU_TxBF");
5500 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
5501 switch (get_driver_type()) {
5502 case DRIVER_ATHEROS:
5503 ath_sta_set_txsp_stream(dut, intf, "1SS");
5504 ath_sta_set_rxsp_stream(dut, intf, "1SS");
5505 case DRIVER_WCN:
5506 if (wcn_sta_set_sp_stream(dut, intf, "1SS") < 0) {
5507 send_resp(dut, conn, SIGMA_ERROR,
5508 "ErrorCode,Failed to set RX/TXSP_STREAM");
5509 return 0;
5510 }
5511 default:
5512 sigma_dut_print(dut, DUT_MSG_ERROR,
5513 "Setting SP_STREAM not supported");
5514 break;
5515 }
5516 snprintf(buf, sizeof(buf), "iwpriv %s vhtmubfee 1", intf);
5517 if (system(buf) != 0) {
5518 sigma_dut_print(dut, DUT_MSG_ERROR,
5519 "iwpriv vhtmubfee failed");
5520 }
5521 snprintf(buf, sizeof(buf), "iwpriv %s vhtmubfer 1", intf);
5522 if (system(buf) != 0) {
5523 sigma_dut_print(dut, DUT_MSG_ERROR,
5524 "iwpriv vhtmubfer failed");
5525 }
5526 }
5527
5528 val = get_param(cmd, "LDPC");
5529 if (val) {
5530 int ldpc;
5531
5532 ldpc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
5533 snprintf(buf, sizeof(buf), "iwpriv %s ldpc %d", intf, ldpc);
5534 if (system(buf) != 0) {
5535 sigma_dut_print(dut, DUT_MSG_ERROR,
5536 "iwpriv ldpc failed");
5537 }
5538 }
5539
5540 val = get_param(cmd, "opt_md_notif_ie");
5541 if (val) {
5542 char *result = NULL;
5543 char delim[] = ";";
5544 char token[30];
5545 int value, config_val = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05305546 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005547
Peng Xub8fc5cc2017-05-10 17:27:28 -07005548 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05305549 result = strtok_r(token, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005550
5551 /* Extract the NSS information */
5552 if (result) {
5553 value = atoi(result);
5554 switch (value) {
5555 case 1:
5556 config_val = 1;
5557 break;
5558 case 2:
5559 config_val = 3;
5560 break;
5561 case 3:
5562 config_val = 7;
5563 break;
5564 case 4:
5565 config_val = 15;
5566 break;
5567 default:
5568 config_val = 3;
5569 break;
5570 }
5571
5572 snprintf(buf, sizeof(buf), "iwpriv %s rxchainmask %d",
5573 intf, config_val);
5574 if (system(buf) != 0) {
5575 sigma_dut_print(dut, DUT_MSG_ERROR,
5576 "iwpriv rxchainmask failed");
5577 }
5578
5579 snprintf(buf, sizeof(buf), "iwpriv %s txchainmask %d",
5580 intf, config_val);
5581 if (system(buf) != 0) {
5582 sigma_dut_print(dut, DUT_MSG_ERROR,
5583 "iwpriv txchainmask failed");
5584 }
5585 }
5586
5587 /* Extract the channel width information */
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05305588 result = strtok_r(NULL, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005589 if (result) {
5590 value = atoi(result);
5591 switch (value) {
5592 case 20:
5593 config_val = 0;
5594 break;
5595 case 40:
5596 config_val = 1;
5597 break;
5598 case 80:
5599 config_val = 2;
5600 break;
5601 case 160:
5602 config_val = 3;
5603 break;
5604 default:
5605 config_val = 2;
5606 break;
5607 }
5608
5609 dut->chwidth = config_val;
5610
5611 snprintf(buf, sizeof(buf), "iwpriv %s chwidth %d",
5612 intf, config_val);
5613 if (system(buf) != 0) {
5614 sigma_dut_print(dut, DUT_MSG_ERROR,
5615 "iwpriv chwidth failed");
5616 }
5617 }
5618
5619 snprintf(buf, sizeof(buf), "iwpriv %s opmode_notify 1", intf);
5620 if (system(buf) != 0) {
5621 sigma_dut_print(dut, DUT_MSG_ERROR,
5622 "iwpriv opmode_notify failed");
5623 }
5624 }
5625
5626 val = get_param(cmd, "nss_mcs_cap");
5627 if (val) {
5628 int nss, mcs;
5629 char token[20];
5630 char *result = NULL;
5631 unsigned int vht_mcsmap = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05305632 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005633
Peng Xub8fc5cc2017-05-10 17:27:28 -07005634 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05305635 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05305636 if (!result) {
5637 sigma_dut_print(dut, DUT_MSG_ERROR,
5638 "VHT NSS not specified");
5639 return 0;
5640 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005641 nss = atoi(result);
5642
5643 snprintf(buf, sizeof(buf), "iwpriv %s nss %d", intf, nss);
5644 if (system(buf) != 0) {
5645 sigma_dut_print(dut, DUT_MSG_ERROR,
5646 "iwpriv nss failed");
5647 }
5648
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05305649 result = strtok_r(NULL, ";", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005650 if (result == NULL) {
5651 sigma_dut_print(dut, DUT_MSG_ERROR,
5652 "VHTMCS NOT SPECIFIED!");
5653 return 0;
5654 }
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05305655 result = strtok_r(result, "-", &saveptr);
5656 result = strtok_r(NULL, "-", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05305657 if (!result) {
5658 sigma_dut_print(dut, DUT_MSG_ERROR,
5659 "VHT MCS not specified");
5660 return 0;
5661 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005662 mcs = atoi(result);
5663
5664 snprintf(buf, sizeof(buf), "iwpriv %s vhtmcs %d", intf, mcs);
5665 if (system(buf) != 0) {
5666 sigma_dut_print(dut, DUT_MSG_ERROR,
5667 "iwpriv mcs failed");
5668 }
5669
5670 switch (nss) {
5671 case 1:
5672 switch (mcs) {
5673 case 7:
5674 vht_mcsmap = 0xfffc;
5675 break;
5676 case 8:
5677 vht_mcsmap = 0xfffd;
5678 break;
5679 case 9:
5680 vht_mcsmap = 0xfffe;
5681 break;
5682 default:
5683 vht_mcsmap = 0xfffe;
5684 break;
5685 }
5686 break;
5687 case 2:
5688 switch (mcs) {
5689 case 7:
5690 vht_mcsmap = 0xfff0;
5691 break;
5692 case 8:
5693 vht_mcsmap = 0xfff5;
5694 break;
5695 case 9:
5696 vht_mcsmap = 0xfffa;
5697 break;
5698 default:
5699 vht_mcsmap = 0xfffa;
5700 break;
5701 }
5702 break;
5703 case 3:
5704 switch (mcs) {
5705 case 7:
5706 vht_mcsmap = 0xffc0;
5707 break;
5708 case 8:
5709 vht_mcsmap = 0xffd5;
5710 break;
5711 case 9:
5712 vht_mcsmap = 0xffea;
5713 break;
5714 default:
5715 vht_mcsmap = 0xffea;
5716 break;
5717 }
5718 break;
5719 default:
5720 vht_mcsmap = 0xffea;
5721 break;
5722 }
5723 snprintf(buf, sizeof(buf), "iwpriv %s vht_mcsmap 0x%04x",
5724 intf, vht_mcsmap);
5725 if (system(buf) != 0) {
5726 sigma_dut_print(dut, DUT_MSG_ERROR,
5727 "iwpriv vht_mcsmap failed");
5728 }
5729 }
5730
5731 /* UNSUPPORTED: val = get_param(cmd, "Tx_lgi_rate"); */
5732
5733 val = get_param(cmd, "Vht_tkip");
5734 if (val)
5735 tkip = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
5736
5737 val = get_param(cmd, "Vht_wep");
5738 if (val)
5739 wep = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
5740
5741 if (tkip != -1 || wep != -1) {
5742 if ((tkip == 1 && wep != 0) || (wep == 1 && tkip != 0)) {
5743 snprintf(buf, sizeof(buf), "iwpriv %s htweptkip 1",
5744 intf);
5745 } else if ((tkip == 0 && wep != 1) || (wep == 0 && tkip != 1)) {
5746 snprintf(buf, sizeof(buf), "iwpriv %s htweptkip 0",
5747 intf);
5748 } else {
5749 sigma_dut_print(dut, DUT_MSG_ERROR,
5750 "ErrorCode,mixed mode of VHT TKIP/WEP not supported");
5751 return 0;
5752 }
5753
5754 if (system(buf) != 0) {
5755 sigma_dut_print(dut, DUT_MSG_ERROR,
5756 "iwpriv htweptkip failed");
5757 }
5758 }
5759
5760 val = get_param(cmd, "txBandwidth");
5761 if (val) {
5762 switch (get_driver_type()) {
5763 case DRIVER_ATHEROS:
5764 if (ath_set_width(dut, conn, intf, val) < 0) {
5765 send_resp(dut, conn, SIGMA_ERROR,
5766 "ErrorCode,Failed to set txBandwidth");
5767 return 0;
5768 }
5769 break;
5770 default:
5771 sigma_dut_print(dut, DUT_MSG_ERROR,
5772 "Setting txBandwidth not supported");
5773 break;
5774 }
5775 }
5776
5777 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
5778}
5779
5780
5781static int sta_set_wireless_60g(struct sigma_dut *dut,
5782 struct sigma_conn *conn,
5783 struct sigma_cmd *cmd)
5784{
5785 const char *dev_role = get_param(cmd, "DevRole");
5786
5787 if (!dev_role) {
5788 send_resp(dut, conn, SIGMA_INVALID,
5789 "ErrorCode,DevRole not specified");
5790 return 0;
5791 }
5792
5793 if (strcasecmp(dev_role, "PCP") == 0)
5794 return sta_set_60g_pcp(dut, conn, cmd);
5795 if (strcasecmp(dev_role, "STA") == 0)
5796 return sta_set_60g_sta(dut, conn, cmd);
5797 send_resp(dut, conn, SIGMA_INVALID,
5798 "ErrorCode,DevRole not supported");
5799 return 0;
5800}
5801
5802
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05305803static int sta_set_wireless_oce(struct sigma_dut *dut, struct sigma_conn *conn,
5804 struct sigma_cmd *cmd)
5805{
5806 int status;
5807 const char *intf = get_param(cmd, "Interface");
5808 const char *val = get_param(cmd, "DevRole");
5809
5810 if (val && strcasecmp(val, "STA-CFON") == 0) {
5811 status = sta_cfon_set_wireless(dut, conn, cmd);
5812 if (status)
5813 return status;
5814 }
5815 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
5816}
5817
5818
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005819static int cmd_sta_set_wireless(struct sigma_dut *dut, struct sigma_conn *conn,
5820 struct sigma_cmd *cmd)
5821{
5822 const char *val;
5823
5824 val = get_param(cmd, "Program");
5825 if (val) {
5826 if (strcasecmp(val, "11n") == 0)
5827 return cmd_sta_set_11n(dut, conn, cmd);
5828 if (strcasecmp(val, "VHT") == 0)
5829 return cmd_sta_set_wireless_vht(dut, conn, cmd);
5830 if (strcasecmp(val, "60ghz") == 0)
5831 return sta_set_wireless_60g(dut, conn, cmd);
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05305832 if (strcasecmp(val, "OCE") == 0)
5833 return sta_set_wireless_oce(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005834 send_resp(dut, conn, SIGMA_ERROR,
5835 "ErrorCode,Program value not supported");
5836 } else {
5837 send_resp(dut, conn, SIGMA_ERROR,
5838 "ErrorCode,Program argument not available");
5839 }
5840
5841 return 0;
5842}
5843
5844
5845static void ath_sta_inject_frame(struct sigma_dut *dut, const char *intf,
5846 int tid)
5847{
5848 char buf[100];
5849 int tid_to_dscp [] = { 0x00, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0 };
5850
Pradeep Reddy POTTETId31d1322016-10-13 17:22:03 +05305851 if (tid < 0 ||
5852 tid >= (int) (sizeof(tid_to_dscp) / sizeof(tid_to_dscp[0]))) {
5853 sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported TID: %d", tid);
5854 return;
5855 }
5856
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005857 /*
5858 * Two ways to ensure that addba request with a
5859 * non zero TID could be sent out. EV 117296
5860 */
5861 snprintf(buf, sizeof(buf),
5862 "ping -c 8 -Q %d `arp -a | grep wlan0 | awk '{print $2}' | tr -d '()'`",
5863 tid);
5864 if (system(buf) != 0) {
5865 sigma_dut_print(dut, DUT_MSG_ERROR,
5866 "Ping did not send out");
5867 }
5868
5869 snprintf(buf, sizeof(buf),
5870 "iwconfig %s | grep Access | awk '{print $6}' > %s",
5871 intf, VI_QOS_TMP_FILE);
5872 if (system(buf) != 0)
5873 return;
5874
5875 snprintf(buf, sizeof(buf),
5876 "ifconfig %s | grep HWaddr | cut -b 39-56 >> %s",
5877 intf, VI_QOS_TMP_FILE);
5878 if (system(buf) != 0)
5879 sigma_dut_print(dut, DUT_MSG_ERROR, "HWaddr matching failed");
5880
5881 snprintf(buf,sizeof(buf), "sed -n '3,$p' %s >> %s",
5882 VI_QOS_REFFILE, VI_QOS_TMP_FILE);
5883 if (system(buf) != 0) {
5884 sigma_dut_print(dut, DUT_MSG_ERROR,
5885 "VI_QOS_TEMP_FILE generation error failed");
5886 }
5887 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
5888 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
5889 if (system(buf) != 0) {
5890 sigma_dut_print(dut, DUT_MSG_ERROR,
5891 "VI_QOS_FILE generation failed");
5892 }
5893
5894 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
5895 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
5896 if (system(buf) != 0) {
5897 sigma_dut_print(dut, DUT_MSG_ERROR,
5898 "VI_QOS_FILE generation failed");
5899 }
5900
5901 snprintf(buf, sizeof(buf), "ethinject %s %s", intf, VI_QOS_FILE);
5902 if (system(buf) != 0) {
5903 }
5904}
5905
5906
5907static int ath_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
5908 struct sigma_cmd *cmd)
5909{
5910 const char *intf = get_param(cmd, "Interface");
5911 const char *val;
5912 int tid = 0;
5913 char buf[100];
5914
5915 val = get_param(cmd, "TID");
5916 if (val) {
5917 tid = atoi(val);
5918 if (tid)
5919 ath_sta_inject_frame(dut, intf, tid);
5920 }
5921
5922 /* Command sequence for ADDBA request on Peregrine based devices */
5923 snprintf(buf, sizeof(buf), "iwpriv %s setaddbaoper 1", intf);
5924 if (system(buf) != 0) {
5925 sigma_dut_print(dut, DUT_MSG_ERROR,
5926 "iwpriv setaddbaoper failed");
5927 }
5928
5929 snprintf(buf, sizeof(buf), "wifitool %s senddelba 1 %d 1 4", intf, tid);
5930 if (system(buf) != 0) {
5931 sigma_dut_print(dut, DUT_MSG_ERROR,
5932 "wifitool senddelba failed");
5933 }
5934
5935 snprintf(buf, sizeof(buf), "wifitool %s sendaddba 1 %d 64", intf, tid);
5936 if (system(buf) != 0) {
5937 sigma_dut_print(dut, DUT_MSG_ERROR,
5938 "wifitool sendaddba failed");
5939 }
5940
5941 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
5942
5943 return 1;
5944}
5945
5946
Lior David9981b512017-01-20 13:16:40 +02005947#ifdef __linux__
5948
5949static int wil6210_send_addba(struct sigma_dut *dut, const char *dest_mac,
5950 int agg_size)
5951{
5952 char dir[128], buf[128];
5953 FILE *f;
5954 regex_t re;
5955 regmatch_t m[2];
5956 int rc, ret = -1, vring_id, found;
5957
5958 if (wil6210_get_debugfs_dir(dut, dir, sizeof(dir))) {
5959 sigma_dut_print(dut, DUT_MSG_ERROR,
5960 "failed to get wil6210 debugfs dir");
5961 return -1;
5962 }
5963
5964 snprintf(buf, sizeof(buf), "%s/vrings", dir);
5965 f = fopen(buf, "r");
5966 if (!f) {
5967 sigma_dut_print(dut, DUT_MSG_ERROR, "failed to open: %s", buf);
5968 return -1;
5969 }
5970
5971 if (regcomp(&re, "VRING tx_[ \t]*([0-9]+)", REG_EXTENDED)) {
5972 sigma_dut_print(dut, DUT_MSG_ERROR, "regcomp failed");
5973 goto out;
5974 }
5975
5976 /* find TX VRING for the mac address */
5977 found = 0;
5978 while (fgets(buf, sizeof(buf), f)) {
5979 if (strcasestr(buf, dest_mac)) {
5980 found = 1;
5981 break;
5982 }
5983 }
5984
5985 if (!found) {
5986 sigma_dut_print(dut, DUT_MSG_ERROR,
5987 "no TX VRING for %s", dest_mac);
5988 goto out;
5989 }
5990
5991 /* extract VRING ID, "VRING tx_<id> = {" */
5992 if (!fgets(buf, sizeof(buf), f)) {
5993 sigma_dut_print(dut, DUT_MSG_ERROR,
5994 "no VRING start line for %s", dest_mac);
5995 goto out;
5996 }
5997
5998 rc = regexec(&re, buf, 2, m, 0);
5999 regfree(&re);
6000 if (rc || m[1].rm_so < 0) {
6001 sigma_dut_print(dut, DUT_MSG_ERROR,
6002 "no VRING TX ID for %s", dest_mac);
6003 goto out;
6004 }
6005 buf[m[1].rm_eo] = 0;
6006 vring_id = atoi(&buf[m[1].rm_so]);
6007
6008 /* send the addba command */
6009 fclose(f);
6010 snprintf(buf, sizeof(buf), "%s/back", dir);
6011 f = fopen(buf, "w");
6012 if (!f) {
6013 sigma_dut_print(dut, DUT_MSG_ERROR,
6014 "failed to open: %s", buf);
6015 return -1;
6016 }
6017
6018 fprintf(f, "add %d %d\n", vring_id, agg_size);
6019
6020 ret = 0;
6021
6022out:
6023 fclose(f);
6024
6025 return ret;
6026}
6027
6028
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006029static int send_addba_60g(struct sigma_dut *dut, struct sigma_conn *conn,
6030 struct sigma_cmd *cmd)
6031{
6032 const char *val;
6033 int tid = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006034
6035 val = get_param(cmd, "TID");
6036 if (val) {
6037 tid = atoi(val);
6038 if (tid != 0) {
6039 sigma_dut_print(dut, DUT_MSG_ERROR,
6040 "Ignore TID %d for send_addba use TID 0 for 60g since only 0 required on TX",
6041 tid);
6042 }
6043 }
6044
6045 val = get_param(cmd, "Dest_mac");
6046 if (!val) {
6047 sigma_dut_print(dut, DUT_MSG_ERROR,
6048 "Currently not supporting addba for 60G without Dest_mac");
6049 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
6050 }
6051
Lior David9981b512017-01-20 13:16:40 +02006052 if (wil6210_send_addba(dut, val, dut->back_rcv_buf))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006053 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006054
6055 return 1;
6056}
6057
Lior David9981b512017-01-20 13:16:40 +02006058#endif /* __linux__ */
6059
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006060
6061static int cmd_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
6062 struct sigma_cmd *cmd)
6063{
6064 switch (get_driver_type()) {
6065 case DRIVER_ATHEROS:
6066 return ath_sta_send_addba(dut, conn, cmd);
Lior David9981b512017-01-20 13:16:40 +02006067#ifdef __linux__
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006068 case DRIVER_WIL6210:
6069 return send_addba_60g(dut, conn, cmd);
Lior David9981b512017-01-20 13:16:40 +02006070#endif /* __linux__ */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006071 default:
6072 /*
6073 * There is no driver specific implementation for other drivers.
6074 * Ignore the command and report COMPLETE since the following
6075 * throughput test operation will end up sending ADDBA anyway.
6076 */
6077 return 1;
6078 }
6079}
6080
6081
6082int inject_eth_frame(int s, const void *data, size_t len,
6083 unsigned short ethtype, char *dst, char *src)
6084{
6085 struct iovec iov[4] = {
6086 {
6087 .iov_base = dst,
6088 .iov_len = ETH_ALEN,
6089 },
6090 {
6091 .iov_base = src,
6092 .iov_len = ETH_ALEN,
6093 },
6094 {
6095 .iov_base = &ethtype,
6096 .iov_len = sizeof(unsigned short),
6097 },
6098 {
6099 .iov_base = (void *) data,
6100 .iov_len = len,
6101 }
6102 };
6103 struct msghdr msg = {
6104 .msg_name = NULL,
6105 .msg_namelen = 0,
6106 .msg_iov = iov,
6107 .msg_iovlen = 4,
6108 .msg_control = NULL,
6109 .msg_controllen = 0,
6110 .msg_flags = 0,
6111 };
6112
6113 return sendmsg(s, &msg, 0);
6114}
6115
6116#if defined(__linux__) || defined(__QNXNTO__)
6117
6118int inject_frame(int s, const void *data, size_t len, int encrypt)
6119{
6120#define IEEE80211_RADIOTAP_F_WEP 0x04
6121#define IEEE80211_RADIOTAP_F_FRAG 0x08
6122 unsigned char rtap_hdr[] = {
6123 0x00, 0x00, /* radiotap version */
6124 0x0e, 0x00, /* radiotap length */
6125 0x02, 0xc0, 0x00, 0x00, /* bmap: flags, tx and rx flags */
6126 IEEE80211_RADIOTAP_F_FRAG, /* F_FRAG (fragment if required) */
6127 0x00, /* padding */
6128 0x00, 0x00, /* RX and TX flags to indicate that */
6129 0x00, 0x00, /* this is the injected frame directly */
6130 };
6131 struct iovec iov[2] = {
6132 {
6133 .iov_base = &rtap_hdr,
6134 .iov_len = sizeof(rtap_hdr),
6135 },
6136 {
6137 .iov_base = (void *) data,
6138 .iov_len = len,
6139 }
6140 };
6141 struct msghdr msg = {
6142 .msg_name = NULL,
6143 .msg_namelen = 0,
6144 .msg_iov = iov,
6145 .msg_iovlen = 2,
6146 .msg_control = NULL,
6147 .msg_controllen = 0,
6148 .msg_flags = 0,
6149 };
6150
6151 if (encrypt)
6152 rtap_hdr[8] |= IEEE80211_RADIOTAP_F_WEP;
6153
6154 return sendmsg(s, &msg, 0);
6155}
6156
6157
6158int open_monitor(const char *ifname)
6159{
6160#ifdef __QNXNTO__
6161 struct sockaddr_dl ll;
6162 int s;
6163
6164 memset(&ll, 0, sizeof(ll));
6165 ll.sdl_family = AF_LINK;
6166 ll.sdl_index = if_nametoindex(ifname);
6167 if (ll.sdl_index == 0) {
6168 perror("if_nametoindex");
6169 return -1;
6170 }
6171 s = socket(PF_INET, SOCK_RAW, 0);
6172#else /* __QNXNTO__ */
6173 struct sockaddr_ll ll;
6174 int s;
6175
6176 memset(&ll, 0, sizeof(ll));
6177 ll.sll_family = AF_PACKET;
6178 ll.sll_ifindex = if_nametoindex(ifname);
6179 if (ll.sll_ifindex == 0) {
6180 perror("if_nametoindex");
6181 return -1;
6182 }
6183 s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
6184#endif /* __QNXNTO__ */
6185 if (s < 0) {
6186 perror("socket[PF_PACKET,SOCK_RAW]");
6187 return -1;
6188 }
6189
6190 if (bind(s, (struct sockaddr *) &ll, sizeof(ll)) < 0) {
6191 perror("monitor socket bind");
6192 close(s);
6193 return -1;
6194 }
6195
6196 return s;
6197}
6198
6199
6200static int hex2num(char c)
6201{
6202 if (c >= '0' && c <= '9')
6203 return c - '0';
6204 if (c >= 'a' && c <= 'f')
6205 return c - 'a' + 10;
6206 if (c >= 'A' && c <= 'F')
6207 return c - 'A' + 10;
6208 return -1;
6209}
6210
6211
6212int hwaddr_aton(const char *txt, unsigned char *addr)
6213{
6214 int i;
6215
6216 for (i = 0; i < 6; i++) {
6217 int a, b;
6218
6219 a = hex2num(*txt++);
6220 if (a < 0)
6221 return -1;
6222 b = hex2num(*txt++);
6223 if (b < 0)
6224 return -1;
6225 *addr++ = (a << 4) | b;
6226 if (i < 5 && *txt++ != ':')
6227 return -1;
6228 }
6229
6230 return 0;
6231}
6232
6233#endif /* defined(__linux__) || defined(__QNXNTO__) */
6234
6235enum send_frame_type {
6236 DISASSOC, DEAUTH, SAQUERY, AUTH, ASSOCREQ, REASSOCREQ, DLS_REQ
6237};
6238enum send_frame_protection {
6239 CORRECT_KEY, INCORRECT_KEY, UNPROTECTED
6240};
6241
6242
6243static int sta_inject_frame(struct sigma_dut *dut, struct sigma_conn *conn,
6244 enum send_frame_type frame,
6245 enum send_frame_protection protected,
6246 const char *dest)
6247{
6248#ifdef __linux__
6249 unsigned char buf[1000], *pos;
6250 int s, res;
6251 char bssid[20], addr[20];
6252 char result[32], ssid[100];
6253 size_t ssid_len;
6254
6255 if (get_wpa_status(get_station_ifname(), "wpa_state", result,
6256 sizeof(result)) < 0 ||
6257 strncmp(result, "COMPLETED", 9) != 0) {
6258 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Not connected");
6259 return 0;
6260 }
6261
6262 if (get_wpa_status(get_station_ifname(), "bssid", bssid, sizeof(bssid))
6263 < 0) {
6264 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
6265 "current BSSID");
6266 return 0;
6267 }
6268
6269 if (get_wpa_status(get_station_ifname(), "address", addr, sizeof(addr))
6270 < 0) {
6271 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
6272 "own MAC address");
6273 return 0;
6274 }
6275
6276 if (get_wpa_status(get_station_ifname(), "ssid", ssid, sizeof(ssid))
6277 < 0) {
6278 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
6279 "current SSID");
6280 return 0;
6281 }
6282 ssid_len = strlen(ssid);
6283
6284 pos = buf;
6285
6286 /* Frame Control */
6287 switch (frame) {
6288 case DISASSOC:
6289 *pos++ = 0xa0;
6290 break;
6291 case DEAUTH:
6292 *pos++ = 0xc0;
6293 break;
6294 case SAQUERY:
6295 *pos++ = 0xd0;
6296 break;
6297 case AUTH:
6298 *pos++ = 0xb0;
6299 break;
6300 case ASSOCREQ:
6301 *pos++ = 0x00;
6302 break;
6303 case REASSOCREQ:
6304 *pos++ = 0x20;
6305 break;
6306 case DLS_REQ:
6307 *pos++ = 0xd0;
6308 break;
6309 }
6310
6311 if (protected == INCORRECT_KEY)
6312 *pos++ = 0x40; /* Set Protected field to 1 */
6313 else
6314 *pos++ = 0x00;
6315
6316 /* Duration */
6317 *pos++ = 0x00;
6318 *pos++ = 0x00;
6319
6320 /* addr1 = DA (current AP) */
6321 hwaddr_aton(bssid, pos);
6322 pos += 6;
6323 /* addr2 = SA (own address) */
6324 hwaddr_aton(addr, pos);
6325 pos += 6;
6326 /* addr3 = BSSID (current AP) */
6327 hwaddr_aton(bssid, pos);
6328 pos += 6;
6329
6330 /* Seq# (to be filled by driver/mac80211) */
6331 *pos++ = 0x00;
6332 *pos++ = 0x00;
6333
6334 if (protected == INCORRECT_KEY) {
6335 /* CCMP parameters */
6336 memcpy(pos, "\x61\x01\x00\x20\x00\x10\x00\x00", 8);
6337 pos += 8;
6338 }
6339
6340 if (protected == INCORRECT_KEY) {
6341 switch (frame) {
6342 case DEAUTH:
6343 /* Reason code (encrypted) */
6344 memcpy(pos, "\xa7\x39", 2);
6345 pos += 2;
6346 break;
6347 case DISASSOC:
6348 /* Reason code (encrypted) */
6349 memcpy(pos, "\xa7\x39", 2);
6350 pos += 2;
6351 break;
6352 case SAQUERY:
6353 /* Category|Action|TransID (encrypted) */
6354 memcpy(pos, "\x6f\xbd\xe9\x4d", 4);
6355 pos += 4;
6356 break;
6357 default:
6358 return -1;
6359 }
6360
6361 /* CCMP MIC */
6362 memcpy(pos, "\xc8\xd8\x3b\x06\x5d\xb7\x25\x68", 8);
6363 pos += 8;
6364 } else {
6365 switch (frame) {
6366 case DEAUTH:
6367 /* reason code = 8 */
6368 *pos++ = 0x08;
6369 *pos++ = 0x00;
6370 break;
6371 case DISASSOC:
6372 /* reason code = 8 */
6373 *pos++ = 0x08;
6374 *pos++ = 0x00;
6375 break;
6376 case SAQUERY:
6377 /* Category - SA Query */
6378 *pos++ = 0x08;
6379 /* SA query Action - Request */
6380 *pos++ = 0x00;
6381 /* Transaction ID */
6382 *pos++ = 0x12;
6383 *pos++ = 0x34;
6384 break;
6385 case AUTH:
6386 /* Auth Alg (Open) */
6387 *pos++ = 0x00;
6388 *pos++ = 0x00;
6389 /* Seq# */
6390 *pos++ = 0x01;
6391 *pos++ = 0x00;
6392 /* Status code */
6393 *pos++ = 0x00;
6394 *pos++ = 0x00;
6395 break;
6396 case ASSOCREQ:
6397 /* Capability Information */
6398 *pos++ = 0x31;
6399 *pos++ = 0x04;
6400 /* Listen Interval */
6401 *pos++ = 0x0a;
6402 *pos++ = 0x00;
6403 /* SSID */
6404 *pos++ = 0x00;
6405 *pos++ = ssid_len;
6406 memcpy(pos, ssid, ssid_len);
6407 pos += ssid_len;
6408 /* Supported Rates */
6409 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
6410 10);
6411 pos += 10;
6412 /* Extended Supported Rates */
6413 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
6414 pos += 6;
6415 /* RSN */
6416 memcpy(pos, "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00"
6417 "\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x02\xc0"
6418 "\x00\x00\x00\x00\x0f\xac\x06", 28);
6419 pos += 28;
6420 break;
6421 case REASSOCREQ:
6422 /* Capability Information */
6423 *pos++ = 0x31;
6424 *pos++ = 0x04;
6425 /* Listen Interval */
6426 *pos++ = 0x0a;
6427 *pos++ = 0x00;
6428 /* Current AP */
6429 hwaddr_aton(bssid, pos);
6430 pos += 6;
6431 /* SSID */
6432 *pos++ = 0x00;
6433 *pos++ = ssid_len;
6434 memcpy(pos, ssid, ssid_len);
6435 pos += ssid_len;
6436 /* Supported Rates */
6437 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
6438 10);
6439 pos += 10;
6440 /* Extended Supported Rates */
6441 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
6442 pos += 6;
6443 /* RSN */
6444 memcpy(pos, "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00"
6445 "\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x02\xc0"
6446 "\x00\x00\x00\x00\x0f\xac\x06", 28);
6447 pos += 28;
6448 break;
6449 case DLS_REQ:
6450 /* Category - DLS */
6451 *pos++ = 0x02;
6452 /* DLS Action - Request */
6453 *pos++ = 0x00;
6454 /* Destination MACAddress */
6455 if (dest)
6456 hwaddr_aton(dest, pos);
6457 else
6458 memset(pos, 0, 6);
6459 pos += 6;
6460 /* Source MACAddress */
6461 hwaddr_aton(addr, pos);
6462 pos += 6;
6463 /* Capability Information */
6464 *pos++ = 0x10; /* Privacy */
6465 *pos++ = 0x06; /* QoS */
6466 /* DLS Timeout Value */
6467 *pos++ = 0x00;
6468 *pos++ = 0x01;
6469 /* Supported rates */
6470 *pos++ = 0x01;
6471 *pos++ = 0x08;
6472 *pos++ = 0x0c; /* 6 Mbps */
6473 *pos++ = 0x12; /* 9 Mbps */
6474 *pos++ = 0x18; /* 12 Mbps */
6475 *pos++ = 0x24; /* 18 Mbps */
6476 *pos++ = 0x30; /* 24 Mbps */
6477 *pos++ = 0x48; /* 36 Mbps */
6478 *pos++ = 0x60; /* 48 Mbps */
6479 *pos++ = 0x6c; /* 54 Mbps */
6480 /* TODO: Extended Supported Rates */
6481 /* TODO: HT Capabilities */
6482 break;
6483 }
6484 }
6485
6486 s = open_monitor("sigmadut");
6487 if (s < 0) {
6488 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
6489 "monitor socket");
6490 return 0;
6491 }
6492
6493 res = inject_frame(s, buf, pos - buf, protected == CORRECT_KEY);
6494 if (res < 0) {
6495 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
6496 "inject frame");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05306497 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006498 return 0;
6499 }
6500 if (res < pos - buf) {
6501 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Only partial "
6502 "frame sent");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05306503 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006504 return 0;
6505 }
6506
6507 close(s);
6508
6509 return 1;
6510#else /* __linux__ */
6511 send_resp(dut, conn, SIGMA_ERROR, "errorCode,sta_send_frame not "
6512 "yet supported");
6513 return 0;
6514#endif /* __linux__ */
6515}
6516
6517
6518static int cmd_sta_send_frame_tdls(struct sigma_dut *dut,
6519 struct sigma_conn *conn,
6520 struct sigma_cmd *cmd)
6521{
6522 const char *intf = get_param(cmd, "Interface");
6523 const char *sta, *val;
6524 unsigned char addr[ETH_ALEN];
6525 char buf[100];
6526
6527 sta = get_param(cmd, "peer");
6528 if (sta == NULL)
6529 sta = get_param(cmd, "station");
6530 if (sta == NULL) {
6531 send_resp(dut, conn, SIGMA_ERROR,
6532 "ErrorCode,Missing peer address");
6533 return 0;
6534 }
6535 if (hwaddr_aton(sta, addr) < 0) {
6536 send_resp(dut, conn, SIGMA_ERROR,
6537 "ErrorCode,Invalid peer address");
6538 return 0;
6539 }
6540
6541 val = get_param(cmd, "type");
6542 if (val == NULL)
6543 return -1;
6544
6545 if (strcasecmp(val, "DISCOVERY") == 0) {
6546 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", sta);
6547 if (wpa_command(intf, buf) < 0) {
6548 send_resp(dut, conn, SIGMA_ERROR,
6549 "ErrorCode,Failed to send TDLS discovery");
6550 return 0;
6551 }
6552 return 1;
6553 }
6554
6555 if (strcasecmp(val, "SETUP") == 0) {
6556 int status = 0, timeout = 0;
6557
6558 val = get_param(cmd, "Status");
6559 if (val)
6560 status = atoi(val);
6561
6562 val = get_param(cmd, "Timeout");
6563 if (val)
6564 timeout = atoi(val);
6565
6566 if (status != 0 && status != 37) {
6567 send_resp(dut, conn, SIGMA_ERROR,
6568 "ErrorCode,Unsupported status value");
6569 return 0;
6570 }
6571
6572 if (timeout != 0 && timeout != 301) {
6573 send_resp(dut, conn, SIGMA_ERROR,
6574 "ErrorCode,Unsupported timeout value");
6575 return 0;
6576 }
6577
6578 if (status && timeout) {
6579 send_resp(dut, conn, SIGMA_ERROR,
6580 "ErrorCode,Unsupported timeout+status "
6581 "combination");
6582 return 0;
6583 }
6584
6585 if (status == 37 &&
6586 wpa_command(intf, "SET tdls_testing 0x200")) {
6587 send_resp(dut, conn, SIGMA_ERROR,
6588 "ErrorCode,Failed to enable "
6589 "decline setup response test mode");
6590 return 0;
6591 }
6592
6593 if (timeout == 301) {
6594 int res;
6595 if (dut->no_tpk_expiration)
6596 res = wpa_command(intf,
6597 "SET tdls_testing 0x108");
6598 else
6599 res = wpa_command(intf,
6600 "SET tdls_testing 0x8");
6601 if (res) {
6602 send_resp(dut, conn, SIGMA_ERROR,
6603 "ErrorCode,Failed to set short TPK "
6604 "lifetime");
6605 return 0;
6606 }
6607 }
6608
6609 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", sta);
6610 if (wpa_command(intf, buf) < 0) {
6611 send_resp(dut, conn, SIGMA_ERROR,
6612 "ErrorCode,Failed to send TDLS setup");
6613 return 0;
6614 }
6615 return 1;
6616 }
6617
6618 if (strcasecmp(val, "TEARDOWN") == 0) {
6619 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", sta);
6620 if (wpa_command(intf, buf) < 0) {
6621 send_resp(dut, conn, SIGMA_ERROR,
6622 "ErrorCode,Failed to send TDLS teardown");
6623 return 0;
6624 }
6625 return 1;
6626 }
6627
6628 send_resp(dut, conn, SIGMA_ERROR,
6629 "ErrorCode,Unsupported TDLS frame");
6630 return 0;
6631}
6632
6633
6634static int sta_ap_known(const char *ifname, const char *bssid)
6635{
6636 char buf[4096];
6637
6638 snprintf(buf, sizeof(buf), "BSS %s", bssid);
6639 if (wpa_command_resp(ifname, buf, buf, sizeof(buf)) < 0)
6640 return 0;
6641 if (strncmp(buf, "id=", 3) != 0)
6642 return 0;
6643 return 1;
6644}
6645
6646
6647static int sta_scan_ap(struct sigma_dut *dut, const char *ifname,
6648 const char *bssid)
6649{
6650 int res;
6651 struct wpa_ctrl *ctrl;
6652 char buf[256];
6653
6654 if (sta_ap_known(ifname, bssid))
6655 return 0;
6656 sigma_dut_print(dut, DUT_MSG_DEBUG,
6657 "AP not in BSS table - start scan");
6658
6659 ctrl = open_wpa_mon(ifname);
6660 if (ctrl == NULL) {
6661 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
6662 "wpa_supplicant monitor connection");
6663 return -1;
6664 }
6665
6666 if (wpa_command(ifname, "SCAN") < 0) {
6667 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to start scan");
6668 wpa_ctrl_detach(ctrl);
6669 wpa_ctrl_close(ctrl);
6670 return -1;
6671 }
6672
6673 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
6674 buf, sizeof(buf));
6675
6676 wpa_ctrl_detach(ctrl);
6677 wpa_ctrl_close(ctrl);
6678
6679 if (res < 0) {
6680 sigma_dut_print(dut, DUT_MSG_INFO, "Scan did not complete");
6681 return -1;
6682 }
6683
6684 if (sta_ap_known(ifname, bssid))
6685 return 0;
6686 sigma_dut_print(dut, DUT_MSG_INFO, "AP not in BSS table");
6687 return -1;
6688}
6689
6690
6691static int cmd_sta_send_frame_hs2_neighadv(struct sigma_dut *dut,
6692 struct sigma_conn *conn,
6693 struct sigma_cmd *cmd,
6694 const char *intf)
6695{
6696 char buf[200];
6697
6698 snprintf(buf, sizeof(buf), "ndsend 2001:DB8::1 %s", intf);
6699 if (system(buf) != 0) {
6700 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Failed to run "
6701 "ndsend");
6702 return 0;
6703 }
6704
6705 return 1;
6706}
6707
6708
6709static int cmd_sta_send_frame_hs2_neighsolreq(struct sigma_dut *dut,
6710 struct sigma_conn *conn,
6711 struct sigma_cmd *cmd,
6712 const char *intf)
6713{
6714 char buf[200];
6715 const char *ip = get_param(cmd, "SenderIP");
6716
Peng Xu26b356d2017-10-04 17:58:16 -07006717 if (!ip)
6718 return 0;
6719
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006720 snprintf(buf, sizeof(buf), "ndisc6 -nm %s %s -r 4", ip, intf);
6721 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
6722 if (system(buf) == 0) {
6723 sigma_dut_print(dut, DUT_MSG_INFO,
6724 "Neighbor Solicitation got a response "
6725 "for %s@%s", ip, intf);
6726 }
6727
6728 return 1;
6729}
6730
6731
6732static int cmd_sta_send_frame_hs2_arpprobe(struct sigma_dut *dut,
6733 struct sigma_conn *conn,
6734 struct sigma_cmd *cmd,
6735 const char *ifname)
6736{
6737 char buf[200];
6738 const char *ip = get_param(cmd, "SenderIP");
6739
6740 if (ip == NULL) {
6741 send_resp(dut, conn, SIGMA_ERROR,
6742 "ErrorCode,Missing SenderIP parameter");
6743 return 0;
6744 }
6745 snprintf(buf, sizeof(buf), "arping -I %s -D %s -c 4", ifname, ip);
6746 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
6747 if (system(buf) != 0) {
6748 sigma_dut_print(dut, DUT_MSG_INFO, "arping DAD got a response "
6749 "for %s@%s", ip, ifname);
6750 }
6751
6752 return 1;
6753}
6754
6755
6756static int cmd_sta_send_frame_hs2_arpannounce(struct sigma_dut *dut,
6757 struct sigma_conn *conn,
6758 struct sigma_cmd *cmd,
6759 const char *ifname)
6760{
6761 char buf[200];
6762 char ip[16];
6763 int s;
Peng Xub3756882017-10-04 14:39:09 -07006764 struct ifreq ifr;
6765 struct sockaddr_in saddr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006766
6767 s = socket(PF_INET, SOCK_DGRAM, 0);
Peng Xub3756882017-10-04 14:39:09 -07006768 if (s < 0) {
6769 perror("socket");
6770 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006771 }
6772
Peng Xub3756882017-10-04 14:39:09 -07006773 memset(&ifr, 0, sizeof(ifr));
6774 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
6775 if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
6776 sigma_dut_print(dut, DUT_MSG_INFO,
6777 "Failed to get %s IP address: %s",
6778 ifname, strerror(errno));
6779 close(s);
6780 return -1;
6781 }
6782 close(s);
6783
6784 memcpy(&saddr, &ifr.ifr_addr, sizeof(struct sockaddr_in));
6785 strlcpy(ip, inet_ntoa(saddr.sin_addr), sizeof(ip));
6786
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006787 snprintf(buf, sizeof(buf), "arping -I %s -s %s %s -c 4", ifname, ip,
6788 ip);
6789 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
6790 if (system(buf) != 0) {
6791 }
6792
6793 return 1;
6794}
6795
6796
6797static int cmd_sta_send_frame_hs2_arpreply(struct sigma_dut *dut,
6798 struct sigma_conn *conn,
6799 struct sigma_cmd *cmd,
6800 const char *ifname)
6801{
6802 char buf[200], addr[20];
6803 char dst[ETH_ALEN], src[ETH_ALEN];
6804 short ethtype = htons(ETH_P_ARP);
6805 char *pos;
6806 int s, res;
6807 const char *val;
6808 struct sockaddr_in taddr;
6809
6810 val = get_param(cmd, "dest");
6811 if (val)
6812 hwaddr_aton(val, (unsigned char *) dst);
6813
6814 val = get_param(cmd, "DestIP");
6815 if (val)
6816 inet_aton(val, &taddr.sin_addr);
Peng Xu151c9e12017-10-04 14:39:09 -07006817 else
6818 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006819
6820 if (get_wpa_status(get_station_ifname(), "address", addr,
6821 sizeof(addr)) < 0)
6822 return -2;
6823 hwaddr_aton(addr, (unsigned char *) src);
6824
6825 pos = buf;
6826 *pos++ = 0x00;
6827 *pos++ = 0x01;
6828 *pos++ = 0x08;
6829 *pos++ = 0x00;
6830 *pos++ = 0x06;
6831 *pos++ = 0x04;
6832 *pos++ = 0x00;
6833 *pos++ = 0x02;
6834 memcpy(pos, src, ETH_ALEN);
6835 pos += ETH_ALEN;
6836 memcpy(pos, &taddr.sin_addr, 4);
6837 pos += 4;
6838 memcpy(pos, dst, ETH_ALEN);
6839 pos += ETH_ALEN;
6840 memcpy(pos, &taddr.sin_addr, 4);
6841 pos += 4;
6842
6843 s = open_monitor(get_station_ifname());
6844 if (s < 0) {
6845 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
6846 "monitor socket");
6847 return 0;
6848 }
6849
6850 res = inject_eth_frame(s, buf, pos - buf, ethtype, dst, src);
6851 if (res < 0) {
6852 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
6853 "inject frame");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05306854 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006855 return 0;
6856 }
6857
6858 close(s);
6859
6860 return 1;
6861}
6862
6863
6864static int cmd_sta_send_frame_hs2_dls_req(struct sigma_dut *dut,
6865 struct sigma_conn *conn,
6866 struct sigma_cmd *cmd,
6867 const char *intf, const char *dest)
6868{
6869 char buf[100];
6870
6871 if (if_nametoindex("sigmadut") == 0) {
6872 snprintf(buf, sizeof(buf),
6873 "iw dev %s interface add sigmadut type monitor",
6874 get_station_ifname());
6875 if (system(buf) != 0 ||
6876 if_nametoindex("sigmadut") == 0) {
6877 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
6878 "monitor interface with '%s'", buf);
6879 return -2;
6880 }
6881 }
6882
6883 if (system("ifconfig sigmadut up") != 0) {
6884 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
6885 "monitor interface up");
6886 return -2;
6887 }
6888
6889 return sta_inject_frame(dut, conn, DLS_REQ, UNPROTECTED, dest);
6890}
6891
6892
6893static int cmd_sta_send_frame_hs2(struct sigma_dut *dut,
6894 struct sigma_conn *conn,
6895 struct sigma_cmd *cmd)
6896{
6897 const char *intf = get_param(cmd, "Interface");
6898 const char *dest = get_param(cmd, "Dest");
6899 const char *type = get_param(cmd, "FrameName");
6900 const char *val;
6901 char buf[200], *pos, *end;
6902 int count, count2;
6903
6904 if (type == NULL)
6905 type = get_param(cmd, "Type");
6906
6907 if (intf == NULL || dest == NULL || type == NULL)
6908 return -1;
6909
6910 if (strcasecmp(type, "NeighAdv") == 0)
6911 return cmd_sta_send_frame_hs2_neighadv(dut, conn, cmd, intf);
6912
6913 if (strcasecmp(type, "NeighSolicitReq") == 0)
6914 return cmd_sta_send_frame_hs2_neighsolreq(dut, conn, cmd, intf);
6915
6916 if (strcasecmp(type, "ARPProbe") == 0)
6917 return cmd_sta_send_frame_hs2_arpprobe(dut, conn, cmd, intf);
6918
6919 if (strcasecmp(type, "ARPAnnounce") == 0)
6920 return cmd_sta_send_frame_hs2_arpannounce(dut, conn, cmd, intf);
6921
6922 if (strcasecmp(type, "ARPReply") == 0)
6923 return cmd_sta_send_frame_hs2_arpreply(dut, conn, cmd, intf);
6924
6925 if (strcasecmp(type, "DLS-request") == 0 ||
6926 strcasecmp(type, "DLSrequest") == 0)
6927 return cmd_sta_send_frame_hs2_dls_req(dut, conn, cmd, intf,
6928 dest);
6929
6930 if (strcasecmp(type, "ANQPQuery") != 0 &&
6931 strcasecmp(type, "Query") != 0) {
6932 send_resp(dut, conn, SIGMA_ERROR,
6933 "ErrorCode,Unsupported HS 2.0 send frame type");
6934 return 0;
6935 }
6936
6937 if (sta_scan_ap(dut, intf, dest) < 0) {
6938 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not find "
6939 "the requested AP");
6940 return 0;
6941 }
6942
6943 pos = buf;
6944 end = buf + sizeof(buf);
6945 count = 0;
6946 pos += snprintf(pos, end - pos, "ANQP_GET %s ", dest);
6947
6948 val = get_param(cmd, "ANQP_CAP_LIST");
6949 if (val && atoi(val)) {
6950 pos += snprintf(pos, end - pos, "%s257", count > 0 ? "," : "");
6951 count++;
6952 }
6953
6954 val = get_param(cmd, "VENUE_NAME");
6955 if (val && atoi(val)) {
6956 pos += snprintf(pos, end - pos, "%s258", count > 0 ? "," : "");
6957 count++;
6958 }
6959
6960 val = get_param(cmd, "NETWORK_AUTH_TYPE");
6961 if (val && atoi(val)) {
6962 pos += snprintf(pos, end - pos, "%s260", count > 0 ? "," : "");
6963 count++;
6964 }
6965
6966 val = get_param(cmd, "ROAMING_CONS");
6967 if (val && atoi(val)) {
6968 pos += snprintf(pos, end - pos, "%s261", count > 0 ? "," : "");
6969 count++;
6970 }
6971
6972 val = get_param(cmd, "IP_ADDR_TYPE_AVAILABILITY");
6973 if (val && atoi(val)) {
6974 pos += snprintf(pos, end - pos, "%s262", count > 0 ? "," : "");
6975 count++;
6976 }
6977
6978 val = get_param(cmd, "NAI_REALM_LIST");
6979 if (val && atoi(val)) {
6980 pos += snprintf(pos, end - pos, "%s263", count > 0 ? "," : "");
6981 count++;
6982 }
6983
6984 val = get_param(cmd, "3GPP_INFO");
6985 if (val && atoi(val)) {
6986 pos += snprintf(pos, end - pos, "%s264", count > 0 ? "," : "");
6987 count++;
6988 }
6989
6990 val = get_param(cmd, "DOMAIN_LIST");
6991 if (val && atoi(val)) {
6992 pos += snprintf(pos, end - pos, "%s268", count > 0 ? "," : "");
6993 count++;
6994 }
6995
6996 if (count && wpa_command(intf, buf)) {
6997 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,ANQP_GET failed");
6998 return 0;
6999 }
7000
7001 pos = buf;
7002 end = buf + sizeof(buf);
7003 count2 = 0;
7004 pos += snprintf(pos, end - pos, "HS20_ANQP_GET %s ", dest);
7005
7006 val = get_param(cmd, "HS_CAP_LIST");
7007 if (val && atoi(val)) {
7008 pos += snprintf(pos, end - pos, "%s2", count2 > 0 ? "," : "");
7009 count2++;
7010 }
7011
7012 val = get_param(cmd, "OPER_NAME");
7013 if (val && atoi(val)) {
7014 pos += snprintf(pos, end - pos, "%s3", count2 > 0 ? "," : "");
7015 count2++;
7016 }
7017
7018 val = get_param(cmd, "WAN_METRICS");
7019 if (!val)
7020 val = get_param(cmd, "WAN_MAT");
7021 if (!val)
7022 val = get_param(cmd, "WAN_MET");
7023 if (val && atoi(val)) {
7024 pos += snprintf(pos, end - pos, "%s4", count2 > 0 ? "," : "");
7025 count2++;
7026 }
7027
7028 val = get_param(cmd, "CONNECTION_CAPABILITY");
7029 if (val && atoi(val)) {
7030 pos += snprintf(pos, end - pos, "%s5", count2 > 0 ? "," : "");
7031 count2++;
7032 }
7033
7034 val = get_param(cmd, "OP_CLASS");
7035 if (val && atoi(val)) {
7036 pos += snprintf(pos, end - pos, "%s7", count2 > 0 ? "," : "");
7037 count2++;
7038 }
7039
7040 val = get_param(cmd, "OSU_PROVIDER_LIST");
7041 if (val && atoi(val)) {
7042 pos += snprintf(pos, end - pos, "%s8", count2 > 0 ? "," : "");
7043 count2++;
7044 }
7045
7046 if (count && count2) {
7047 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before sending out "
7048 "second query");
7049 sleep(1);
7050 }
7051
7052 if (count2 && wpa_command(intf, buf)) {
7053 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,HS20_ANQP_GET "
7054 "failed");
7055 return 0;
7056 }
7057
7058 val = get_param(cmd, "NAI_HOME_REALM_LIST");
7059 if (val) {
7060 if (count || count2) {
7061 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
7062 "sending out second query");
7063 sleep(1);
7064 }
7065
7066 if (strcmp(val, "1") == 0)
7067 val = "mail.example.com";
7068 snprintf(buf, end - pos,
7069 "HS20_GET_NAI_HOME_REALM_LIST %s realm=%s",
7070 dest, val);
7071 if (wpa_command(intf, buf)) {
7072 send_resp(dut, conn, SIGMA_ERROR,
7073 "ErrorCode,HS20_GET_NAI_HOME_REALM_LIST "
7074 "failed");
7075 return 0;
7076 }
7077 }
7078
7079 val = get_param(cmd, "ICON_REQUEST");
7080 if (val) {
7081 if (count || count2) {
7082 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
7083 "sending out second query");
7084 sleep(1);
7085 }
7086
7087 snprintf(buf, end - pos,
7088 "HS20_ICON_REQUEST %s %s", dest, val);
7089 if (wpa_command(intf, buf)) {
7090 send_resp(dut, conn, SIGMA_ERROR,
7091 "ErrorCode,HS20_ICON_REQUEST failed");
7092 return 0;
7093 }
7094 }
7095
7096 return 1;
7097}
7098
7099
7100static int ath_sta_send_frame_vht(struct sigma_dut *dut,
7101 struct sigma_conn *conn,
7102 struct sigma_cmd *cmd)
7103{
7104 const char *val;
7105 char *ifname;
7106 char buf[100];
7107 int chwidth, nss;
7108
7109 val = get_param(cmd, "framename");
7110 if (!val)
7111 return -1;
7112 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
7113
7114 /* Command sequence to generate Op mode notification */
7115 if (val && strcasecmp(val, "Op_md_notif_frm") == 0) {
7116 ifname = get_station_ifname();
7117
7118 /* Disable STBC */
7119 snprintf(buf, sizeof(buf),
7120 "iwpriv %s tx_stbc 0", ifname);
7121 if (system(buf) != 0) {
7122 sigma_dut_print(dut, DUT_MSG_ERROR,
7123 "iwpriv tx_stbc 0 failed!");
7124 }
7125
7126 /* Extract Channel width */
7127 val = get_param(cmd, "Channel_width");
7128 if (val) {
7129 switch (atoi(val)) {
7130 case 20:
7131 chwidth = 0;
7132 break;
7133 case 40:
7134 chwidth = 1;
7135 break;
7136 case 80:
7137 chwidth = 2;
7138 break;
7139 case 160:
7140 chwidth = 3;
7141 break;
7142 default:
7143 chwidth = 2;
7144 break;
7145 }
7146
7147 snprintf(buf, sizeof(buf), "iwpriv %s chwidth %d",
7148 ifname, chwidth);
7149 if (system(buf) != 0) {
7150 sigma_dut_print(dut, DUT_MSG_ERROR,
7151 "iwpriv chwidth failed!");
7152 }
7153 }
7154
7155 /* Extract NSS */
7156 val = get_param(cmd, "NSS");
7157 if (val) {
7158 switch (atoi(val)) {
7159 case 1:
7160 nss = 1;
7161 break;
7162 case 2:
7163 nss = 3;
7164 break;
7165 case 3:
7166 nss = 7;
7167 break;
7168 default:
7169 /* We do not support NSS > 3 */
7170 nss = 3;
7171 break;
7172 }
7173 snprintf(buf, sizeof(buf),
7174 "iwpriv %s rxchainmask %d", ifname, nss);
7175 if (system(buf) != 0) {
7176 sigma_dut_print(dut, DUT_MSG_ERROR,
7177 "iwpriv rxchainmask failed!");
7178 }
7179 }
7180
7181 /* Opmode notify */
7182 snprintf(buf, sizeof(buf), "iwpriv %s opmode_notify 1", ifname);
7183 if (system(buf) != 0) {
7184 sigma_dut_print(dut, DUT_MSG_ERROR,
7185 "iwpriv opmode_notify failed!");
7186 } else {
7187 sigma_dut_print(dut, DUT_MSG_INFO,
7188 "Sent out the notify frame!");
7189 }
7190 }
7191
7192 return 1;
7193}
7194
7195
7196static int cmd_sta_send_frame_vht(struct sigma_dut *dut,
7197 struct sigma_conn *conn,
7198 struct sigma_cmd *cmd)
7199{
7200 switch (get_driver_type()) {
7201 case DRIVER_ATHEROS:
7202 return ath_sta_send_frame_vht(dut, conn, cmd);
7203 default:
7204 send_resp(dut, conn, SIGMA_ERROR,
7205 "errorCode,Unsupported sta_set_frame(VHT) with the current driver");
7206 return 0;
7207 }
7208}
7209
7210
Lior David0fe101e2017-03-09 16:09:50 +02007211#ifdef __linux__
7212int wil6210_send_frame_60g(struct sigma_dut *dut, struct sigma_conn *conn,
7213 struct sigma_cmd *cmd)
7214{
7215 const char *frame_name = get_param(cmd, "framename");
7216 const char *mac = get_param(cmd, "dest_mac");
7217
7218 if (!frame_name || !mac) {
7219 sigma_dut_print(dut, DUT_MSG_ERROR,
7220 "framename and dest_mac must be provided");
7221 return -1;
7222 }
7223
7224 if (strcasecmp(frame_name, "brp") == 0) {
7225 const char *l_rx = get_param(cmd, "L-RX");
7226 int l_rx_i;
7227
7228 if (!l_rx) {
7229 sigma_dut_print(dut, DUT_MSG_ERROR,
7230 "L-RX must be provided");
7231 return -1;
7232 }
7233 l_rx_i = atoi(l_rx);
7234
7235 sigma_dut_print(dut, DUT_MSG_INFO,
7236 "dev_send_frame: BRP-RX, dest_mac %s, L-RX %s",
7237 mac, l_rx);
7238 if (l_rx_i != 16) {
7239 sigma_dut_print(dut, DUT_MSG_ERROR,
7240 "unsupported L-RX: %s", l_rx);
7241 return -1;
7242 }
7243
7244 if (wil6210_send_brp_rx(dut, mac, l_rx_i))
7245 return -1;
7246 } else if (strcasecmp(frame_name, "ssw") == 0) {
7247 sigma_dut_print(dut, DUT_MSG_INFO,
7248 "dev_send_frame: SLS, dest_mac %s", mac);
7249 if (wil6210_send_sls(dut, mac))
7250 return -1;
7251 } else {
7252 sigma_dut_print(dut, DUT_MSG_ERROR,
7253 "unsupported frame type: %s", frame_name);
7254 return -1;
7255 }
7256
7257 return 1;
7258}
7259#endif /* __linux__ */
7260
7261
7262static int cmd_sta_send_frame_60g(struct sigma_dut *dut,
7263 struct sigma_conn *conn,
7264 struct sigma_cmd *cmd)
7265{
7266 switch (get_driver_type()) {
7267#ifdef __linux__
7268 case DRIVER_WIL6210:
7269 return wil6210_send_frame_60g(dut, conn, cmd);
7270#endif /* __linux__ */
7271 default:
7272 send_resp(dut, conn, SIGMA_ERROR,
7273 "errorCode,Unsupported sta_set_frame(60G) with the current driver");
7274 return 0;
7275 }
7276}
7277
7278
Ashwini Patildb59b3c2017-04-13 15:19:23 +05307279static int mbo_send_anqp_query(struct sigma_dut *dut, struct sigma_conn *conn,
7280 const char *intf, struct sigma_cmd *cmd)
7281{
7282 const char *val, *addr;
7283 char buf[100];
7284
7285 addr = get_param(cmd, "DestMac");
7286 if (!addr) {
7287 send_resp(dut, conn, SIGMA_INVALID,
7288 "ErrorCode,AP MAC address is missing");
7289 return 0;
7290 }
7291
7292 val = get_param(cmd, "ANQPQuery_ID");
7293 if (!val) {
7294 send_resp(dut, conn, SIGMA_INVALID,
7295 "ErrorCode,Missing ANQPQuery_ID");
7296 return 0;
7297 }
7298
7299 if (strcasecmp(val, "NeighborReportReq") == 0) {
7300 snprintf(buf, sizeof(buf), "ANQP_GET %s 272", addr);
7301 } else if (strcasecmp(val, "QueryListWithCellPref") == 0) {
7302 snprintf(buf, sizeof(buf), "ANQP_GET %s 272,mbo:2", addr);
7303 } else {
7304 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid ANQPQuery_ID: %s",
7305 val);
7306 send_resp(dut, conn, SIGMA_INVALID,
7307 "ErrorCode,Invalid ANQPQuery_ID");
7308 return 0;
7309 }
7310
Ashwini Patild174f2c2017-04-13 16:49:46 +05307311 /* Set gas_address3 field to IEEE 802.11-2012 standard compliant form
7312 * (Address3 = Wildcard BSSID when sent to not-associated AP;
7313 * if associated, AP BSSID).
7314 */
7315 if (wpa_command(intf, "SET gas_address3 1") < 0) {
7316 send_resp(dut, conn, SIGMA_ERROR,
7317 "ErrorCode,Failed to set gas_address3");
7318 return 0;
7319 }
7320
Ashwini Patildb59b3c2017-04-13 15:19:23 +05307321 if (wpa_command(intf, buf) < 0) {
7322 send_resp(dut, conn, SIGMA_ERROR,
7323 "ErrorCode,Failed to send ANQP query");
7324 return 0;
7325 }
7326
7327 return 1;
7328}
7329
7330
7331static int mbo_cmd_sta_send_frame(struct sigma_dut *dut,
7332 struct sigma_conn *conn,
7333 const char *intf,
7334 struct sigma_cmd *cmd)
7335{
7336 const char *val = get_param(cmd, "FrameName");
7337
7338 if (val && strcasecmp(val, "ANQPQuery") == 0)
7339 return mbo_send_anqp_query(dut, conn, intf, cmd);
7340
7341 return 2;
7342}
7343
7344
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007345int cmd_sta_send_frame(struct sigma_dut *dut, struct sigma_conn *conn,
7346 struct sigma_cmd *cmd)
7347{
7348 const char *intf = get_param(cmd, "Interface");
7349 const char *val;
7350 enum send_frame_type frame;
7351 enum send_frame_protection protected;
7352 char buf[100];
7353 unsigned char addr[ETH_ALEN];
7354 int res;
7355
7356 val = get_param(cmd, "program");
7357 if (val == NULL)
7358 val = get_param(cmd, "frame");
7359 if (val && strcasecmp(val, "TDLS") == 0)
7360 return cmd_sta_send_frame_tdls(dut, conn, cmd);
7361 if (val && (strcasecmp(val, "HS2") == 0 ||
7362 strcasecmp(val, "HS2-R2") == 0))
7363 return cmd_sta_send_frame_hs2(dut, conn, cmd);
7364 if (val && strcasecmp(val, "VHT") == 0)
7365 return cmd_sta_send_frame_vht(dut, conn, cmd);
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07007366 if (val && strcasecmp(val, "LOC") == 0)
7367 return loc_cmd_sta_send_frame(dut, conn, cmd);
Lior David0fe101e2017-03-09 16:09:50 +02007368 if (val && strcasecmp(val, "60GHz") == 0)
7369 return cmd_sta_send_frame_60g(dut, conn, cmd);
Ashwini Patildb59b3c2017-04-13 15:19:23 +05307370 if (val && strcasecmp(val, "MBO") == 0) {
7371 res = mbo_cmd_sta_send_frame(dut, conn, intf, cmd);
7372 if (res != 2)
7373 return res;
7374 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007375
7376 val = get_param(cmd, "TD_DISC");
7377 if (val) {
7378 if (hwaddr_aton(val, addr) < 0)
7379 return -1;
7380 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", val);
7381 if (wpa_command(intf, buf) < 0) {
7382 send_resp(dut, conn, SIGMA_ERROR,
7383 "ErrorCode,Failed to send TDLS discovery");
7384 return 0;
7385 }
7386 return 1;
7387 }
7388
7389 val = get_param(cmd, "TD_Setup");
7390 if (val) {
7391 if (hwaddr_aton(val, addr) < 0)
7392 return -1;
7393 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", val);
7394 if (wpa_command(intf, buf) < 0) {
7395 send_resp(dut, conn, SIGMA_ERROR,
7396 "ErrorCode,Failed to start TDLS setup");
7397 return 0;
7398 }
7399 return 1;
7400 }
7401
7402 val = get_param(cmd, "TD_TearDown");
7403 if (val) {
7404 if (hwaddr_aton(val, addr) < 0)
7405 return -1;
7406 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", val);
7407 if (wpa_command(intf, buf) < 0) {
7408 send_resp(dut, conn, SIGMA_ERROR,
7409 "ErrorCode,Failed to tear down TDLS link");
7410 return 0;
7411 }
7412 return 1;
7413 }
7414
7415 val = get_param(cmd, "TD_ChannelSwitch");
7416 if (val) {
7417 /* TODO */
7418 send_resp(dut, conn, SIGMA_ERROR,
7419 "ErrorCode,TD_ChannelSwitch not yet supported");
7420 return 0;
7421 }
7422
7423 val = get_param(cmd, "TD_NF");
7424 if (val) {
7425 /* TODO */
7426 send_resp(dut, conn, SIGMA_ERROR,
7427 "ErrorCode,TD_NF not yet supported");
7428 return 0;
7429 }
7430
7431 val = get_param(cmd, "PMFFrameType");
7432 if (val == NULL)
7433 val = get_param(cmd, "FrameName");
7434 if (val == NULL)
7435 val = get_param(cmd, "Type");
7436 if (val == NULL)
7437 return -1;
7438 if (strcasecmp(val, "disassoc") == 0)
7439 frame = DISASSOC;
7440 else if (strcasecmp(val, "deauth") == 0)
7441 frame = DEAUTH;
7442 else if (strcasecmp(val, "saquery") == 0)
7443 frame = SAQUERY;
7444 else if (strcasecmp(val, "auth") == 0)
7445 frame = AUTH;
7446 else if (strcasecmp(val, "assocreq") == 0)
7447 frame = ASSOCREQ;
7448 else if (strcasecmp(val, "reassocreq") == 0)
7449 frame = REASSOCREQ;
7450 else if (strcasecmp(val, "neigreq") == 0) {
7451 sigma_dut_print(dut, DUT_MSG_INFO, "Got neighbor request");
7452
7453 val = get_param(cmd, "ssid");
7454 if (val == NULL)
7455 return -1;
7456
7457 res = send_neighbor_request(dut, intf, val);
7458 if (res) {
7459 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
7460 "Failed to send neighbor report request");
7461 return 0;
7462 }
7463
7464 return 1;
Ashwini Patil5acd7382017-04-13 15:55:04 +05307465 } else if (strcasecmp(val, "transmgmtquery") == 0 ||
7466 strcasecmp(val, "BTMQuery") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007467 sigma_dut_print(dut, DUT_MSG_DEBUG,
7468 "Got Transition Management Query");
7469
Ashwini Patil5acd7382017-04-13 15:55:04 +05307470 res = send_trans_mgmt_query(dut, intf, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007471 if (res) {
7472 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
7473 "Failed to send Transition Management Query");
7474 return 0;
7475 }
7476
7477 return 1;
7478 } else {
7479 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
7480 "PMFFrameType");
7481 return 0;
7482 }
7483
7484 val = get_param(cmd, "PMFProtected");
7485 if (val == NULL)
7486 val = get_param(cmd, "Protected");
7487 if (val == NULL)
7488 return -1;
7489 if (strcasecmp(val, "Correct-key") == 0 ||
7490 strcasecmp(val, "CorrectKey") == 0)
7491 protected = CORRECT_KEY;
7492 else if (strcasecmp(val, "IncorrectKey") == 0)
7493 protected = INCORRECT_KEY;
7494 else if (strcasecmp(val, "Unprotected") == 0)
7495 protected = UNPROTECTED;
7496 else {
7497 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
7498 "PMFProtected");
7499 return 0;
7500 }
7501
7502 if (protected != UNPROTECTED &&
7503 (frame == AUTH || frame == ASSOCREQ || frame == REASSOCREQ)) {
7504 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Impossible "
7505 "PMFProtected for auth/assocreq/reassocreq");
7506 return 0;
7507 }
7508
7509 if (if_nametoindex("sigmadut") == 0) {
7510 snprintf(buf, sizeof(buf),
7511 "iw dev %s interface add sigmadut type monitor",
7512 get_station_ifname());
7513 if (system(buf) != 0 ||
7514 if_nametoindex("sigmadut") == 0) {
7515 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
7516 "monitor interface with '%s'", buf);
7517 return -2;
7518 }
7519 }
7520
7521 if (system("ifconfig sigmadut up") != 0) {
7522 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
7523 "monitor interface up");
7524 return -2;
7525 }
7526
7527 return sta_inject_frame(dut, conn, frame, protected, NULL);
7528}
7529
7530
7531static int cmd_sta_set_parameter_hs2(struct sigma_dut *dut,
7532 struct sigma_conn *conn,
7533 struct sigma_cmd *cmd,
7534 const char *ifname)
7535{
7536 char buf[200];
7537 const char *val;
7538
7539 val = get_param(cmd, "ClearARP");
7540 if (val && atoi(val) == 1) {
7541 snprintf(buf, sizeof(buf), "ip neigh flush dev %s", ifname);
7542 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
7543 if (system(buf) != 0) {
7544 send_resp(dut, conn, SIGMA_ERROR,
7545 "errorCode,Failed to clear ARP cache");
7546 return 0;
7547 }
7548 }
7549
7550 return 1;
7551}
7552
7553
7554int cmd_sta_set_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
7555 struct sigma_cmd *cmd)
7556{
7557 const char *intf = get_param(cmd, "Interface");
7558 const char *val;
7559
7560 if (intf == NULL)
7561 return -1;
7562
7563 val = get_param(cmd, "program");
7564 if (val && (strcasecmp(val, "HS2") == 0 ||
7565 strcasecmp(val, "HS2-R2") == 0))
7566 return cmd_sta_set_parameter_hs2(dut, conn, cmd, intf);
7567
7568 return -1;
7569}
7570
7571
7572static int cmd_sta_set_macaddr(struct sigma_dut *dut, struct sigma_conn *conn,
7573 struct sigma_cmd *cmd)
7574{
7575 const char *intf = get_param(cmd, "Interface");
7576 const char *mac = get_param(cmd, "MAC");
7577
7578 if (intf == NULL || mac == NULL)
7579 return -1;
7580
7581 sigma_dut_print(dut, DUT_MSG_INFO, "Change local MAC address for "
7582 "interface %s to %s", intf, mac);
7583
7584 if (dut->set_macaddr) {
7585 char buf[128];
7586 int res;
7587 if (strcasecmp(mac, "default") == 0) {
7588 res = snprintf(buf, sizeof(buf), "%s",
7589 dut->set_macaddr);
7590 dut->tmp_mac_addr = 0;
7591 } else {
7592 res = snprintf(buf, sizeof(buf), "%s %s",
7593 dut->set_macaddr, mac);
7594 dut->tmp_mac_addr = 1;
7595 }
7596 if (res < 0 || res >= (int) sizeof(buf))
7597 return -1;
7598 if (system(buf) != 0) {
7599 send_resp(dut, conn, SIGMA_ERROR,
7600 "errorCode,Failed to set MAC "
7601 "address");
7602 return 0;
7603 }
7604 return 1;
7605 }
7606
7607 if (strcasecmp(mac, "default") == 0)
7608 return 1;
7609
7610 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
7611 "command");
7612 return 0;
7613}
7614
7615
7616static int iwpriv_tdlsoffchnmode(struct sigma_dut *dut,
7617 struct sigma_conn *conn, const char *intf,
7618 int val)
7619{
7620 char buf[200];
7621 int res;
7622
7623 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchnmode %d",
7624 intf, val);
7625 if (res < 0 || res >= (int) sizeof(buf))
7626 return -1;
7627 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
7628 if (system(buf) != 0) {
7629 send_resp(dut, conn, SIGMA_ERROR,
7630 "errorCode,Failed to configure offchannel mode");
7631 return 0;
7632 }
7633
7634 return 1;
7635}
7636
7637
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007638static int off_chan_val(enum sec_ch_offset off)
7639{
7640 switch (off) {
7641 case SEC_CH_NO:
7642 return 0;
7643 case SEC_CH_40ABOVE:
7644 return 40;
7645 case SEC_CH_40BELOW:
7646 return -40;
7647 }
7648
7649 return 0;
7650}
7651
7652
7653static int iwpriv_set_offchan(struct sigma_dut *dut, struct sigma_conn *conn,
7654 const char *intf, int off_ch_num,
7655 enum sec_ch_offset sec)
7656{
7657 char buf[200];
7658 int res;
7659
7660 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchan %d",
7661 intf, off_ch_num);
7662 if (res < 0 || res >= (int) sizeof(buf))
7663 return -1;
7664 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
7665 if (system(buf) != 0) {
7666 send_resp(dut, conn, SIGMA_ERROR,
7667 "errorCode,Failed to set offchan");
7668 return 0;
7669 }
7670
7671 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsecchnoffst %d",
7672 intf, off_chan_val(sec));
7673 if (res < 0 || res >= (int) sizeof(buf))
7674 return -1;
7675 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
7676 if (system(buf) != 0) {
7677 send_resp(dut, conn, SIGMA_ERROR,
7678 "errorCode,Failed to set sec chan offset");
7679 return 0;
7680 }
7681
7682 return 1;
7683}
7684
7685
7686static int tdls_set_offchannel_offset(struct sigma_dut *dut,
7687 struct sigma_conn *conn,
7688 const char *intf, int off_ch_num,
7689 enum sec_ch_offset sec)
7690{
7691 char buf[200];
7692 int res;
7693
7694 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNEL %d",
7695 off_ch_num);
7696 if (res < 0 || res >= (int) sizeof(buf))
7697 return -1;
7698 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
7699
7700 if (wpa_command(intf, buf) < 0) {
7701 send_resp(dut, conn, SIGMA_ERROR,
7702 "ErrorCode,Failed to set offchan");
7703 return 0;
7704 }
7705 res = snprintf(buf, sizeof(buf), "DRIVER TDLSSECONDARYCHANNELOFFSET %d",
7706 off_chan_val(sec));
7707 if (res < 0 || res >= (int) sizeof(buf))
7708 return -1;
7709
7710 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
7711
7712 if (wpa_command(intf, buf) < 0) {
7713 send_resp(dut, conn, SIGMA_ERROR,
7714 "ErrorCode,Failed to set sec chan offset");
7715 return 0;
7716 }
7717
7718 return 1;
7719}
7720
7721
7722static int tdls_set_offchannel_mode(struct sigma_dut *dut,
7723 struct sigma_conn *conn,
7724 const char *intf, int val)
7725{
7726 char buf[200];
7727 int res;
7728
7729 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNELMODE %d",
7730 val);
7731 if (res < 0 || res >= (int) sizeof(buf))
7732 return -1;
7733 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
7734
7735 if (wpa_command(intf, buf) < 0) {
7736 send_resp(dut, conn, SIGMA_ERROR,
7737 "ErrorCode,Failed to configure offchannel mode");
7738 return 0;
7739 }
7740
7741 return 1;
7742}
7743
7744
7745static int cmd_sta_set_rfeature_tdls(const char *intf, struct sigma_dut *dut,
7746 struct sigma_conn *conn,
7747 struct sigma_cmd *cmd)
7748{
7749 const char *val;
7750 enum {
7751 CHSM_NOT_SET,
7752 CHSM_ENABLE,
7753 CHSM_DISABLE,
7754 CHSM_REJREQ,
7755 CHSM_UNSOLRESP
7756 } chsm = CHSM_NOT_SET;
7757 int off_ch_num = -1;
7758 enum sec_ch_offset sec_ch = SEC_CH_NO;
7759 int res;
7760
7761 val = get_param(cmd, "Uapsd");
7762 if (val) {
7763 char buf[100];
7764 if (strcasecmp(val, "Enable") == 0)
7765 snprintf(buf, sizeof(buf), "SET ps 99");
7766 else if (strcasecmp(val, "Disable") == 0)
7767 snprintf(buf, sizeof(buf), "SET ps 98");
7768 else {
7769 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
7770 "Unsupported uapsd parameter value");
7771 return 0;
7772 }
7773 if (wpa_command(intf, buf)) {
7774 send_resp(dut, conn, SIGMA_ERROR,
7775 "ErrorCode,Failed to change U-APSD "
7776 "powersave mode");
7777 return 0;
7778 }
7779 }
7780
7781 val = get_param(cmd, "TPKTIMER");
7782 if (val && strcasecmp(val, "DISABLE") == 0) {
7783 if (wpa_command(intf, "SET tdls_testing 0x100")) {
7784 send_resp(dut, conn, SIGMA_ERROR,
7785 "ErrorCode,Failed to enable no TPK "
7786 "expiration test mode");
7787 return 0;
7788 }
7789 dut->no_tpk_expiration = 1;
7790 }
7791
7792 val = get_param(cmd, "ChSwitchMode");
7793 if (val) {
7794 if (strcasecmp(val, "Enable") == 0 ||
7795 strcasecmp(val, "Initiate") == 0)
7796 chsm = CHSM_ENABLE;
7797 else if (strcasecmp(val, "Disable") == 0 ||
7798 strcasecmp(val, "passive") == 0)
7799 chsm = CHSM_DISABLE;
7800 else if (strcasecmp(val, "RejReq") == 0)
7801 chsm = CHSM_REJREQ;
7802 else if (strcasecmp(val, "UnSolResp") == 0)
7803 chsm = CHSM_UNSOLRESP;
7804 else {
7805 send_resp(dut, conn, SIGMA_ERROR,
7806 "ErrorCode,Unknown ChSwitchMode value");
7807 return 0;
7808 }
7809 }
7810
7811 val = get_param(cmd, "OffChNum");
7812 if (val) {
7813 off_ch_num = atoi(val);
7814 if (off_ch_num == 0) {
7815 send_resp(dut, conn, SIGMA_ERROR,
7816 "ErrorCode,Invalid OffChNum");
7817 return 0;
7818 }
7819 }
7820
7821 val = get_param(cmd, "SecChOffset");
7822 if (val) {
7823 if (strcmp(val, "20") == 0)
7824 sec_ch = SEC_CH_NO;
7825 else if (strcasecmp(val, "40above") == 0)
7826 sec_ch = SEC_CH_40ABOVE;
7827 else if (strcasecmp(val, "40below") == 0)
7828 sec_ch = SEC_CH_40BELOW;
7829 else {
7830 send_resp(dut, conn, SIGMA_ERROR,
7831 "ErrorCode,Unknown SecChOffset value");
7832 return 0;
7833 }
7834 }
7835
7836 if (chsm == CHSM_NOT_SET) {
7837 /* no offchannel changes requested */
7838 return 1;
7839 }
7840
7841 if (strcmp(intf, get_main_ifname()) != 0 &&
7842 strcmp(intf, get_station_ifname()) != 0) {
7843 send_resp(dut, conn, SIGMA_ERROR,
7844 "ErrorCode,Unknown interface");
7845 return 0;
7846 }
7847
7848 switch (chsm) {
7849 case CHSM_NOT_SET:
Jouni Malinen280f5ba2016-08-29 21:33:10 +03007850 res = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007851 break;
7852 case CHSM_ENABLE:
7853 if (off_ch_num < 0) {
7854 send_resp(dut, conn, SIGMA_ERROR,
7855 "ErrorCode,Missing OffChNum argument");
7856 return 0;
7857 }
7858 if (wifi_chip_type == DRIVER_WCN) {
7859 res = tdls_set_offchannel_offset(dut, conn, intf,
7860 off_ch_num, sec_ch);
7861 } else {
7862 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
7863 sec_ch);
7864 }
7865 if (res != 1)
7866 return res;
7867 if (wifi_chip_type == DRIVER_WCN)
7868 res = tdls_set_offchannel_mode(dut, conn, intf, 1);
7869 else
7870 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 1);
7871 break;
7872 case CHSM_DISABLE:
7873 if (wifi_chip_type == DRIVER_WCN)
7874 res = tdls_set_offchannel_mode(dut, conn, intf, 2);
7875 else
7876 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 2);
7877 break;
7878 case CHSM_REJREQ:
7879 if (wifi_chip_type == DRIVER_WCN)
7880 res = tdls_set_offchannel_mode(dut, conn, intf, 3);
7881 else
7882 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 3);
7883 break;
7884 case CHSM_UNSOLRESP:
7885 if (off_ch_num < 0) {
7886 send_resp(dut, conn, SIGMA_ERROR,
7887 "ErrorCode,Missing OffChNum argument");
7888 return 0;
7889 }
7890 if (wifi_chip_type == DRIVER_WCN) {
7891 res = tdls_set_offchannel_offset(dut, conn, intf,
7892 off_ch_num, sec_ch);
7893 } else {
7894 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
7895 sec_ch);
7896 }
7897 if (res != 1)
7898 return res;
7899 if (wifi_chip_type == DRIVER_WCN)
7900 res = tdls_set_offchannel_mode(dut, conn, intf, 4);
7901 else
7902 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 4);
7903 break;
7904 }
7905
7906 return res;
7907}
7908
7909
7910static int ath_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
7911 struct sigma_conn *conn,
7912 struct sigma_cmd *cmd)
7913{
7914 const char *val;
7915 char *token, *result;
7916
priyadharshini gowthamane5e25172015-12-08 14:53:48 -08007917 novap_reset(dut, intf);
7918
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007919 val = get_param(cmd, "nss_mcs_opt");
7920 if (val) {
7921 /* String (nss_operating_mode; mcs_operating_mode) */
7922 int nss, mcs;
7923 char buf[50];
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307924 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007925
7926 token = strdup(val);
7927 if (!token)
7928 return 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307929 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +05307930 if (!result) {
7931 sigma_dut_print(dut, DUT_MSG_ERROR,
7932 "VHT NSS not specified");
7933 goto failed;
7934 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007935 if (strcasecmp(result, "def") != 0) {
7936 nss = atoi(result);
7937 if (nss == 4)
7938 ath_disable_txbf(dut, intf);
7939 snprintf(buf, sizeof(buf), "iwpriv %s nss %d",
7940 intf, nss);
7941 if (system(buf) != 0) {
7942 sigma_dut_print(dut, DUT_MSG_ERROR,
7943 "iwpriv nss failed");
7944 goto failed;
7945 }
7946 }
7947
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307948 result = strtok_r(NULL, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +05307949 if (!result) {
7950 sigma_dut_print(dut, DUT_MSG_ERROR,
7951 "VHT MCS not specified");
7952 goto failed;
7953 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007954 if (strcasecmp(result, "def") == 0) {
7955 snprintf(buf, sizeof(buf), "iwpriv %s set11NRates 0",
7956 intf);
7957 if (system(buf) != 0) {
7958 sigma_dut_print(dut, DUT_MSG_ERROR,
7959 "iwpriv set11NRates failed");
7960 goto failed;
7961 }
7962
7963 } else {
7964 mcs = atoi(result);
7965 snprintf(buf, sizeof(buf), "iwpriv %s vhtmcs %d",
7966 intf, mcs);
7967 if (system(buf) != 0) {
7968 sigma_dut_print(dut, DUT_MSG_ERROR,
7969 "iwpriv vhtmcs failed");
7970 goto failed;
7971 }
7972 }
7973 /* Channel width gets messed up, fix this */
7974 snprintf(buf, sizeof(buf), "iwpriv %s chwidth %d",
7975 intf, dut->chwidth);
7976 if (system(buf) != 0) {
7977 sigma_dut_print(dut, DUT_MSG_ERROR,
7978 "iwpriv chwidth failed");
7979 }
7980 }
7981
7982 return 1;
7983failed:
7984 free(token);
7985 return 0;
7986}
7987
7988
7989static int cmd_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
7990 struct sigma_conn *conn,
7991 struct sigma_cmd *cmd)
7992{
7993 switch (get_driver_type()) {
7994 case DRIVER_ATHEROS:
7995 return ath_sta_set_rfeature_vht(intf, dut, conn, cmd);
7996 default:
7997 send_resp(dut, conn, SIGMA_ERROR,
7998 "errorCode,Unsupported sta_set_rfeature(VHT) with the current driver");
7999 return 0;
8000 }
8001}
8002
8003
Ashwini Patil5acd7382017-04-13 15:55:04 +05308004static int btm_query_candidate_list(struct sigma_dut *dut,
8005 struct sigma_conn *conn,
8006 struct sigma_cmd *cmd)
8007{
8008 const char *bssid, *info, *op_class, *ch, *phy_type, *pref;
8009 int len, ret;
8010 char buf[10];
8011
8012 /*
8013 * Neighbor Report elements format:
8014 * neighbor=<BSSID>,<BSSID Information>,<Operating Class>,
8015 * <Channel Number>,<PHY Type>[,<hexdump of Optional Subelements>]
8016 * eg: neighbor=aa:bb:cc:dd:ee:ff,17,81,6,1,030101
8017 */
8018
8019 bssid = get_param(cmd, "Nebor_BSSID");
8020 if (!bssid) {
8021 send_resp(dut, conn, SIGMA_INVALID,
8022 "errorCode,Nebor_BSSID is missing");
8023 return 0;
8024 }
8025
8026 info = get_param(cmd, "Nebor_Bssid_Info");
8027 if (!info) {
8028 sigma_dut_print(dut, DUT_MSG_INFO,
8029 "Using default value for Nebor_Bssid_Info: %s",
8030 DEFAULT_NEIGHBOR_BSSID_INFO);
8031 info = DEFAULT_NEIGHBOR_BSSID_INFO;
8032 }
8033
8034 op_class = get_param(cmd, "Nebor_Op_Class");
8035 if (!op_class) {
8036 send_resp(dut, conn, SIGMA_INVALID,
8037 "errorCode,Nebor_Op_Class is missing");
8038 return 0;
8039 }
8040
8041 ch = get_param(cmd, "Nebor_Op_Ch");
8042 if (!ch) {
8043 send_resp(dut, conn, SIGMA_INVALID,
8044 "errorCode,Nebor_Op_Ch is missing");
8045 return 0;
8046 }
8047
8048 phy_type = get_param(cmd, "Nebor_Phy_Type");
8049 if (!phy_type) {
8050 sigma_dut_print(dut, DUT_MSG_INFO,
8051 "Using default value for Nebor_Phy_Type: %s",
8052 DEFAULT_NEIGHBOR_PHY_TYPE);
8053 phy_type = DEFAULT_NEIGHBOR_PHY_TYPE;
8054 }
8055
8056 /* Parse optional subelements */
8057 buf[0] = '\0';
8058 pref = get_param(cmd, "Nebor_Pref");
8059 if (pref) {
8060 /* hexdump for preferrence subelement */
8061 ret = snprintf(buf, sizeof(buf), ",0301%02x", atoi(pref));
8062 if (ret < 0 || ret >= (int) sizeof(buf)) {
8063 sigma_dut_print(dut, DUT_MSG_ERROR,
8064 "snprintf failed for optional subelement ret: %d",
8065 ret);
8066 send_resp(dut, conn, SIGMA_ERROR,
8067 "errorCode,snprintf failed for subelement");
8068 return 0;
8069 }
8070 }
8071
8072 if (!dut->btm_query_cand_list) {
8073 dut->btm_query_cand_list = calloc(1, NEIGHBOR_REPORT_SIZE);
8074 if (!dut->btm_query_cand_list) {
8075 send_resp(dut, conn, SIGMA_ERROR,
8076 "errorCode,Failed to allocate memory for btm_query_cand_list");
8077 return 0;
8078 }
8079 }
8080
8081 len = strlen(dut->btm_query_cand_list);
8082 ret = snprintf(dut->btm_query_cand_list + len,
8083 NEIGHBOR_REPORT_SIZE - len, " neighbor=%s,%s,%s,%s,%s%s",
8084 bssid, info, op_class, ch, phy_type, buf);
8085 if (ret < 0 || ret >= NEIGHBOR_REPORT_SIZE - len) {
8086 sigma_dut_print(dut, DUT_MSG_ERROR,
8087 "snprintf failed for neighbor report list ret: %d",
8088 ret);
8089 send_resp(dut, conn, SIGMA_ERROR,
8090 "errorCode,snprintf failed for neighbor report");
8091 free(dut->btm_query_cand_list);
8092 dut->btm_query_cand_list = NULL;
8093 return 0;
8094 }
8095
8096 return 1;
8097}
8098
8099
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008100static int cmd_sta_set_rfeature(struct sigma_dut *dut, struct sigma_conn *conn,
8101 struct sigma_cmd *cmd)
8102{
8103 const char *intf = get_param(cmd, "Interface");
8104 const char *prog = get_param(cmd, "Prog");
Ashwini Patil68d02cd2017-01-10 15:39:16 +05308105 const char *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008106
8107 if (intf == NULL || prog == NULL)
8108 return -1;
8109
Ashwini Patil5acd7382017-04-13 15:55:04 +05308110 /* BSS Transition candidate list for BTM query */
8111 val = get_param(cmd, "Nebor_BSSID");
8112 if (val && btm_query_candidate_list(dut, conn, cmd) == 0)
8113 return 0;
8114
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008115 if (strcasecmp(prog, "TDLS") == 0)
8116 return cmd_sta_set_rfeature_tdls(intf, dut, conn, cmd);
8117
8118 if (strcasecmp(prog, "VHT") == 0)
8119 return cmd_sta_set_rfeature_vht(intf, dut, conn, cmd);
8120
Ashwini Patil68d02cd2017-01-10 15:39:16 +05308121 if (strcasecmp(prog, "MBO") == 0) {
8122 val = get_param(cmd, "Cellular_Data_Cap");
8123 if (val &&
8124 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
8125 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +05308126
8127 val = get_param(cmd, "Ch_Pref");
8128 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
8129 return 0;
8130
Ashwini Patil68d02cd2017-01-10 15:39:16 +05308131 return 1;
8132 }
8133
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008134 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported Prog");
8135 return 0;
8136}
8137
8138
8139static int cmd_sta_set_radio(struct sigma_dut *dut, struct sigma_conn *conn,
8140 struct sigma_cmd *cmd)
8141{
8142 const char *intf = get_param(cmd, "Interface");
8143 const char *mode = get_param(cmd, "Mode");
8144 int res;
8145
8146 if (intf == NULL || mode == NULL)
8147 return -1;
8148
8149 if (strcasecmp(mode, "On") == 0)
8150 res = wpa_command(intf, "SET radio_disabled 0");
8151 else if (strcasecmp(mode, "Off") == 0)
8152 res = wpa_command(intf, "SET radio_disabled 1");
8153 else
8154 return -1;
8155
8156 if (res) {
8157 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
8158 "radio mode");
8159 return 0;
8160 }
8161
8162 return 1;
8163}
8164
8165
8166static int cmd_sta_set_pwrsave(struct sigma_dut *dut, struct sigma_conn *conn,
8167 struct sigma_cmd *cmd)
8168{
8169 const char *intf = get_param(cmd, "Interface");
8170 const char *mode = get_param(cmd, "Mode");
8171 int res;
8172
8173 if (intf == NULL || mode == NULL)
8174 return -1;
8175
8176 if (strcasecmp(mode, "On") == 0)
8177 res = set_ps(intf, dut, 1);
8178 else if (strcasecmp(mode, "Off") == 0)
8179 res = set_ps(intf, dut, 0);
8180 else
8181 return -1;
8182
8183 if (res) {
8184 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
8185 "power save mode");
8186 return 0;
8187 }
8188
8189 return 1;
8190}
8191
8192
8193static int cmd_sta_bssid_pool(struct sigma_dut *dut, struct sigma_conn *conn,
8194 struct sigma_cmd *cmd)
8195{
8196 const char *intf = get_param(cmd, "Interface");
8197 const char *val, *bssid;
8198 int res;
8199 char *buf;
8200 size_t buf_len;
8201
8202 val = get_param(cmd, "BSSID_FILTER");
8203 if (val == NULL)
8204 return -1;
8205
8206 bssid = get_param(cmd, "BSSID_List");
8207 if (atoi(val) == 0 || bssid == NULL) {
8208 /* Disable BSSID filter */
8209 if (wpa_command(intf, "SET bssid_filter ")) {
8210 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed "
8211 "to disable BSSID filter");
8212 return 0;
8213 }
8214
8215 return 1;
8216 }
8217
8218 buf_len = 100 + strlen(bssid);
8219 buf = malloc(buf_len);
8220 if (buf == NULL)
8221 return -1;
8222
8223 snprintf(buf, buf_len, "SET bssid_filter %s", bssid);
8224 res = wpa_command(intf, buf);
8225 free(buf);
8226 if (res) {
8227 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to enable "
8228 "BSSID filter");
8229 return 0;
8230 }
8231
8232 return 1;
8233}
8234
8235
8236static int cmd_sta_reset_parm(struct sigma_dut *dut, struct sigma_conn *conn,
8237 struct sigma_cmd *cmd)
8238{
8239 const char *intf = get_param(cmd, "Interface");
8240 const char *val;
8241
8242 /* TODO: ARP */
8243
8244 val = get_param(cmd, "HS2_CACHE_PROFILE");
8245 if (val && strcasecmp(val, "All") == 0)
8246 hs2_clear_credentials(intf);
8247
8248 return 1;
8249}
8250
8251
8252static int cmd_sta_get_key(struct sigma_dut *dut, struct sigma_conn *conn,
8253 struct sigma_cmd *cmd)
8254{
8255 const char *intf = get_param(cmd, "Interface");
8256 const char *key_type = get_param(cmd, "KeyType");
8257 char buf[100], resp[200];
8258
8259 if (key_type == NULL)
8260 return -1;
8261
8262 if (strcasecmp(key_type, "GTK") == 0) {
8263 if (wpa_command_resp(intf, "GET gtk", buf, sizeof(buf)) < 0 ||
8264 strncmp(buf, "FAIL", 4) == 0) {
8265 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
8266 "not fetch current GTK");
8267 return 0;
8268 }
8269 snprintf(resp, sizeof(resp), "KeyValue,%s", buf);
8270 send_resp(dut, conn, SIGMA_COMPLETE, resp);
8271 return 0;
8272 } else {
8273 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
8274 "KeyType");
8275 return 0;
8276 }
8277
8278 return 1;
8279}
8280
8281
8282static int hs2_set_policy(struct sigma_dut *dut)
8283{
8284#ifdef ANDROID
8285 system("ip rule del prio 23000");
8286 if (system("ip rule add from all lookup main prio 23000") != 0) {
8287 sigma_dut_print(dut, DUT_MSG_ERROR,
8288 "Failed to run:ip rule add from all lookup main prio");
8289 return -1;
8290 }
8291 if (system("ip route flush cache") != 0) {
8292 sigma_dut_print(dut, DUT_MSG_ERROR,
8293 "Failed to run ip route flush cache");
8294 return -1;
8295 }
8296 return 1;
8297#else /* ANDROID */
8298 return 0;
8299#endif /* ANDROID */
8300}
8301
8302
8303static int cmd_sta_hs2_associate(struct sigma_dut *dut,
8304 struct sigma_conn *conn,
8305 struct sigma_cmd *cmd)
8306{
8307 const char *intf = get_param(cmd, "Interface");
8308 const char *val = get_param(cmd, "Ignore_blacklist");
8309 struct wpa_ctrl *ctrl;
8310 int res;
8311 char bssid[20], ssid[40], resp[100], buf[100], blacklisted[100];
8312 int tries = 0;
8313 int ignore_blacklist = 0;
8314 const char *events[] = {
8315 "CTRL-EVENT-CONNECTED",
8316 "INTERWORKING-BLACKLISTED",
8317 "INTERWORKING-NO-MATCH",
8318 NULL
8319 };
8320
8321 start_sta_mode(dut);
8322
8323 blacklisted[0] = '\0';
8324 if (val && atoi(val))
8325 ignore_blacklist = 1;
8326
8327try_again:
8328 ctrl = open_wpa_mon(intf);
8329 if (ctrl == NULL) {
8330 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
8331 "wpa_supplicant monitor connection");
8332 return -2;
8333 }
8334
8335 tries++;
8336 if (wpa_command(intf, "INTERWORKING_SELECT auto")) {
8337 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start "
8338 "Interworking connection");
8339 wpa_ctrl_detach(ctrl);
8340 wpa_ctrl_close(ctrl);
8341 return 0;
8342 }
8343
8344 buf[0] = '\0';
8345 while (1) {
8346 char *pos;
8347 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
8348 pos = strstr(buf, "INTERWORKING-BLACKLISTED");
8349 if (!pos)
8350 break;
8351 pos += 25;
8352 sigma_dut_print(dut, DUT_MSG_DEBUG, "Found blacklisted AP: %s",
8353 pos);
8354 if (!blacklisted[0])
8355 memcpy(blacklisted, pos, strlen(pos) + 1);
8356 }
8357
8358 if (ignore_blacklist && blacklisted[0]) {
8359 char *end;
8360 end = strchr(blacklisted, ' ');
8361 if (end)
8362 *end = '\0';
8363 sigma_dut_print(dut, DUT_MSG_DEBUG, "Try to connect to a blacklisted network: %s",
8364 blacklisted);
8365 snprintf(buf, sizeof(buf), "INTERWORKING_CONNECT %s",
8366 blacklisted);
8367 if (wpa_command(intf, buf)) {
8368 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start Interworking connection to blacklisted network");
8369 wpa_ctrl_detach(ctrl);
8370 wpa_ctrl_close(ctrl);
8371 return 0;
8372 }
8373 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
8374 buf, sizeof(buf));
8375 }
8376
8377 wpa_ctrl_detach(ctrl);
8378 wpa_ctrl_close(ctrl);
8379
8380 if (res < 0) {
8381 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
8382 "connect");
8383 return 0;
8384 }
8385
8386 if (strstr(buf, "INTERWORKING-NO-MATCH") ||
8387 strstr(buf, "INTERWORKING-BLACKLISTED")) {
8388 if (tries < 2) {
8389 sigma_dut_print(dut, DUT_MSG_INFO, "No match found - try again to verify no APs were missed in the scan");
8390 goto try_again;
8391 }
8392 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,No network with "
8393 "matching credentials found");
8394 return 0;
8395 }
8396
8397 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
8398 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
8399 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
8400 "get current BSSID/SSID");
8401 return 0;
8402 }
8403
8404 snprintf(resp, sizeof(resp), "SSID,%s,BSSID,%s", ssid, bssid);
8405 send_resp(dut, conn, SIGMA_COMPLETE, resp);
8406 hs2_set_policy(dut);
8407 return 0;
8408}
8409
8410
8411static int sta_add_credential_uname_pwd(struct sigma_dut *dut,
8412 struct sigma_conn *conn,
8413 const char *ifname,
8414 struct sigma_cmd *cmd)
8415{
8416 const char *val;
8417 int id;
8418
8419 id = add_cred(ifname);
8420 if (id < 0)
8421 return -2;
8422 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
8423
8424 val = get_param(cmd, "prefer");
8425 if (val && atoi(val) > 0)
8426 set_cred(ifname, id, "priority", "1");
8427
8428 val = get_param(cmd, "REALM");
8429 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
8430 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
8431 "realm");
8432 return 0;
8433 }
8434
8435 val = get_param(cmd, "HOME_FQDN");
8436 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
8437 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
8438 "home_fqdn");
8439 return 0;
8440 }
8441
8442 val = get_param(cmd, "Username");
8443 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
8444 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
8445 "username");
8446 return 0;
8447 }
8448
8449 val = get_param(cmd, "Password");
8450 if (val && set_cred_quoted(ifname, id, "password", val) < 0) {
8451 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
8452 "password");
8453 return 0;
8454 }
8455
8456 val = get_param(cmd, "ROOT_CA");
8457 if (val) {
8458 char fname[200];
8459 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
8460#ifdef __linux__
8461 if (!file_exists(fname)) {
8462 char msg[300];
8463 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
8464 "file (%s) not found", fname);
8465 send_resp(dut, conn, SIGMA_ERROR, msg);
8466 return 0;
8467 }
8468#endif /* __linux__ */
8469 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
8470 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
8471 "not set root CA");
8472 return 0;
8473 }
8474 }
8475
8476 return 1;
8477}
8478
8479
8480static int update_devdetail_imsi(struct sigma_dut *dut, const char *imsi)
8481{
8482 FILE *in, *out;
8483 char buf[500];
8484 int found = 0;
8485
8486 in = fopen("devdetail.xml", "r");
8487 if (in == NULL)
8488 return -1;
8489 out = fopen("devdetail.xml.tmp", "w");
8490 if (out == NULL) {
8491 fclose(in);
8492 return -1;
8493 }
8494
8495 while (fgets(buf, sizeof(buf), in)) {
8496 char *pos = strstr(buf, "<IMSI>");
8497 if (pos) {
8498 sigma_dut_print(dut, DUT_MSG_INFO, "Updated DevDetail IMSI to %s",
8499 imsi);
8500 pos += 6;
8501 *pos = '\0';
8502 fprintf(out, "%s%s</IMSI>\n", buf, imsi);
8503 found++;
8504 } else {
8505 fprintf(out, "%s", buf);
8506 }
8507 }
8508
8509 fclose(out);
8510 fclose(in);
8511 if (found)
8512 rename("devdetail.xml.tmp", "devdetail.xml");
8513 else
8514 unlink("devdetail.xml.tmp");
8515
8516 return 0;
8517}
8518
8519
8520static int sta_add_credential_sim(struct sigma_dut *dut,
8521 struct sigma_conn *conn,
8522 const char *ifname, struct sigma_cmd *cmd)
8523{
8524 const char *val, *imsi = NULL;
8525 int id;
8526 char buf[200];
8527 int res;
8528 const char *pos;
8529 size_t mnc_len;
8530 char plmn_mcc[4];
8531 char plmn_mnc[4];
8532
8533 id = add_cred(ifname);
8534 if (id < 0)
8535 return -2;
8536 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
8537
8538 val = get_param(cmd, "prefer");
8539 if (val && atoi(val) > 0)
8540 set_cred(ifname, id, "priority", "1");
8541
8542 val = get_param(cmd, "PLMN_MCC");
8543 if (val == NULL) {
8544 send_resp(dut, conn, SIGMA_ERROR,
8545 "errorCode,Missing PLMN_MCC");
8546 return 0;
8547 }
8548 if (strlen(val) != 3) {
8549 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MCC");
8550 return 0;
8551 }
8552 snprintf(plmn_mcc, sizeof(plmn_mcc), "%s", val);
8553
8554 val = get_param(cmd, "PLMN_MNC");
8555 if (val == NULL) {
8556 send_resp(dut, conn, SIGMA_ERROR,
8557 "errorCode,Missing PLMN_MNC");
8558 return 0;
8559 }
8560 if (strlen(val) != 2 && strlen(val) != 3) {
8561 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MNC");
8562 return 0;
8563 }
8564 snprintf(plmn_mnc, sizeof(plmn_mnc), "%s", val);
8565
8566 val = get_param(cmd, "IMSI");
8567 if (val == NULL) {
8568 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing SIM "
8569 "IMSI");
8570 return 0;
8571 }
8572
8573 imsi = pos = val;
8574
8575 if (strncmp(plmn_mcc, pos, 3) != 0) {
8576 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MCC mismatch");
8577 return 0;
8578 }
8579 pos += 3;
8580
8581 mnc_len = strlen(plmn_mnc);
8582 if (mnc_len < 2) {
8583 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC not set");
8584 return 0;
8585 }
8586
8587 if (strncmp(plmn_mnc, pos, mnc_len) != 0) {
8588 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC mismatch");
8589 return 0;
8590 }
8591 pos += mnc_len;
8592
8593 res = snprintf(buf, sizeof(buf), "%s%s-%s",plmn_mcc, plmn_mnc, pos);
8594 if (res < 0 || res >= (int) sizeof(buf))
8595 return -1;
8596 if (set_cred_quoted(ifname, id, "imsi", buf) < 0) {
8597 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
8598 "not set IMSI");
8599 return 0;
8600 }
8601
8602 val = get_param(cmd, "Password");
8603 if (val && set_cred_quoted(ifname, id, "milenage", val) < 0) {
8604 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
8605 "not set password");
8606 return 0;
8607 }
8608
8609 if (dut->program == PROGRAM_HS2_R2) {
8610 /*
8611 * Set provisioning_sp for the test cases where SIM/USIM
8612 * provisioning is used.
8613 */
8614 if (val && set_cred_quoted(ifname, id, "provisioning_sp",
8615 "wi-fi.org") < 0) {
8616 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
8617 "not set provisioning_sp");
8618 return 0;
8619 }
8620
8621 update_devdetail_imsi(dut, imsi);
8622 }
8623
8624 return 1;
8625}
8626
8627
8628static int sta_add_credential_cert(struct sigma_dut *dut,
8629 struct sigma_conn *conn,
8630 const char *ifname,
8631 struct sigma_cmd *cmd)
8632{
8633 const char *val;
8634 int id;
8635
8636 id = add_cred(ifname);
8637 if (id < 0)
8638 return -2;
8639 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
8640
8641 val = get_param(cmd, "prefer");
8642 if (val && atoi(val) > 0)
8643 set_cred(ifname, id, "priority", "1");
8644
8645 val = get_param(cmd, "REALM");
8646 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
8647 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
8648 "realm");
8649 return 0;
8650 }
8651
8652 val = get_param(cmd, "HOME_FQDN");
8653 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
8654 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
8655 "home_fqdn");
8656 return 0;
8657 }
8658
8659 val = get_param(cmd, "Username");
8660 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
8661 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
8662 "username");
8663 return 0;
8664 }
8665
8666 val = get_param(cmd, "clientCertificate");
8667 if (val) {
8668 char fname[200];
8669 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
8670#ifdef __linux__
8671 if (!file_exists(fname)) {
8672 char msg[300];
8673 snprintf(msg, sizeof(msg),
8674 "ErrorCode,clientCertificate "
8675 "file (%s) not found", fname);
8676 send_resp(dut, conn, SIGMA_ERROR, msg);
8677 return 0;
8678 }
8679#endif /* __linux__ */
8680 if (set_cred_quoted(ifname, id, "client_cert", fname) < 0) {
8681 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
8682 "not set client_cert");
8683 return 0;
8684 }
8685 if (set_cred_quoted(ifname, id, "private_key", fname) < 0) {
8686 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
8687 "not set private_key");
8688 return 0;
8689 }
8690 }
8691
8692 val = get_param(cmd, "ROOT_CA");
8693 if (val) {
8694 char fname[200];
8695 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
8696#ifdef __linux__
8697 if (!file_exists(fname)) {
8698 char msg[300];
8699 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
8700 "file (%s) not found", fname);
8701 send_resp(dut, conn, SIGMA_ERROR, msg);
8702 return 0;
8703 }
8704#endif /* __linux__ */
8705 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
8706 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
8707 "not set root CA");
8708 return 0;
8709 }
8710 }
8711
8712 return 1;
8713}
8714
8715
8716static int cmd_sta_add_credential(struct sigma_dut *dut,
8717 struct sigma_conn *conn,
8718 struct sigma_cmd *cmd)
8719{
8720 const char *intf = get_param(cmd, "Interface");
8721 const char *type;
8722
8723 start_sta_mode(dut);
8724
8725 type = get_param(cmd, "Type");
8726 if (!type)
8727 return -1;
8728
8729 if (strcasecmp(type, "uname_pwd") == 0)
8730 return sta_add_credential_uname_pwd(dut, conn, intf, cmd);
8731
8732 if (strcasecmp(type, "sim") == 0)
8733 return sta_add_credential_sim(dut, conn, intf, cmd);
8734
8735 if (strcasecmp(type, "cert") == 0)
8736 return sta_add_credential_cert(dut, conn, intf, cmd);
8737
8738 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported credential "
8739 "type");
8740 return 0;
8741}
8742
8743
8744static int cmd_sta_scan(struct sigma_dut *dut, struct sigma_conn *conn,
8745 struct sigma_cmd *cmd)
8746{
8747 const char *intf = get_param(cmd, "Interface");
vamsi krishna89ad8c62017-09-19 12:51:18 +05308748 const char *val, *bssid, *ssid;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008749 char buf[100];
vamsi krishna89ad8c62017-09-19 12:51:18 +05308750 char ssid_hex[65];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008751 int res;
8752
8753 val = get_param(cmd, "HESSID");
8754 if (val) {
8755 res = snprintf(buf, sizeof(buf), "SET hessid %s", val);
8756 if (res < 0 || res >= (int) sizeof(buf))
8757 return -1;
8758 wpa_command(intf, buf);
8759 }
8760
8761 val = get_param(cmd, "ACCS_NET_TYPE");
8762 if (val) {
8763 res = snprintf(buf, sizeof(buf), "SET access_network_type %s",
8764 val);
8765 if (res < 0 || res >= (int) sizeof(buf))
8766 return -1;
8767 wpa_command(intf, buf);
8768 }
8769
vamsi krishna89ad8c62017-09-19 12:51:18 +05308770 bssid = get_param(cmd, "Bssid");
8771 ssid = get_param(cmd, "Ssid");
8772
8773 if (ssid) {
8774 if (2 * strlen(ssid) >= sizeof(ssid_hex)) {
8775 send_resp(dut, conn, SIGMA_ERROR,
8776 "ErrorCode,Too long SSID");
8777 return 0;
8778 }
8779 ascii2hexstr(ssid, ssid_hex);
8780 }
8781
8782 res = snprintf(buf, sizeof(buf), "SCAN%s%s%s%s",
8783 bssid ? " bssid=": "",
8784 bssid ? bssid : "",
8785 ssid ? " ssid " : "",
8786 ssid ? ssid_hex : "");
8787 if (res < 0 || res >= (int) sizeof(buf))
8788 return -1;
8789
8790 if (wpa_command(intf, buf)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008791 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not start "
8792 "scan");
8793 return 0;
8794 }
8795
8796 return 1;
8797}
8798
8799
Jouni Malinen5e5d43d2018-01-10 17:29:33 +02008800static int cmd_sta_scan_bss(struct sigma_dut *dut, struct sigma_conn *conn,
8801 struct sigma_cmd *cmd)
8802{
8803 const char *intf = get_param(cmd, "Interface");
8804 const char *bssid;
8805 char buf[4096], *pos;
8806 int freq, chan;
8807 char *ssid;
8808 char resp[100];
8809 int res;
8810 struct wpa_ctrl *ctrl;
8811
8812 bssid = get_param(cmd, "BSSID");
8813 if (!bssid) {
8814 send_resp(dut, conn, SIGMA_INVALID,
8815 "errorCode,BSSID argument is missing");
8816 return 0;
8817 }
8818
8819 ctrl = open_wpa_mon(intf);
8820 if (!ctrl) {
8821 sigma_dut_print(dut, DUT_MSG_ERROR,
8822 "Failed to open wpa_supplicant monitor connection");
8823 return -1;
8824 }
8825
8826 if (wpa_command(intf, "SCAN TYPE=ONLY")) {
8827 send_resp(dut, conn, SIGMA_ERROR,
8828 "errorCode,Could not start scan");
8829 wpa_ctrl_detach(ctrl);
8830 wpa_ctrl_close(ctrl);
8831 return 0;
8832 }
8833
8834 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
8835 buf, sizeof(buf));
8836
8837 wpa_ctrl_detach(ctrl);
8838 wpa_ctrl_close(ctrl);
8839
8840 if (res < 0) {
8841 send_resp(dut, conn, SIGMA_ERROR,
8842 "errorCode,Scan did not complete");
8843 return 0;
8844 }
8845
8846 snprintf(buf, sizeof(buf), "BSS %s", bssid);
8847 if (wpa_command_resp(intf, buf, buf, sizeof(buf)) < 0 ||
8848 strncmp(buf, "id=", 3) != 0) {
8849 send_resp(dut, conn, SIGMA_ERROR,
8850 "errorCode,Specified BSSID not found");
8851 return 0;
8852 }
8853
8854 pos = strstr(buf, "\nfreq=");
8855 if (!pos) {
8856 send_resp(dut, conn, SIGMA_ERROR,
8857 "errorCode,Channel not found");
8858 return 0;
8859 }
8860 freq = atoi(pos + 6);
8861 chan = freq_to_channel(freq);
8862
8863 pos = strstr(buf, "\nssid=");
8864 if (!pos) {
8865 send_resp(dut, conn, SIGMA_ERROR,
8866 "errorCode,SSID not found");
8867 return 0;
8868 }
8869 ssid = pos + 6;
8870 pos = strchr(ssid, '\n');
8871 if (pos)
8872 *pos = '\0';
8873 snprintf(resp, sizeof(resp), "ssid,%s,bsschannel,%d", ssid, chan);
8874 send_resp(dut, conn, SIGMA_COMPLETE, resp);
8875 return 0;
8876}
8877
8878
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008879static int cmd_sta_set_systime(struct sigma_dut *dut, struct sigma_conn *conn,
8880 struct sigma_cmd *cmd)
8881{
8882#ifdef __linux__
8883 struct timeval tv;
8884 struct tm tm;
8885 time_t t;
8886 const char *val;
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +05308887 int v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008888
8889 wpa_command(get_station_ifname(), "PMKSA_FLUSH");
8890
8891 memset(&tm, 0, sizeof(tm));
8892 val = get_param(cmd, "seconds");
8893 if (val)
8894 tm.tm_sec = atoi(val);
8895 val = get_param(cmd, "minutes");
8896 if (val)
8897 tm.tm_min = atoi(val);
8898 val = get_param(cmd, "hours");
8899 if (val)
8900 tm.tm_hour = atoi(val);
8901 val = get_param(cmd, "date");
8902 if (val)
8903 tm.tm_mday = atoi(val);
8904 val = get_param(cmd, "month");
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +05308905 if (val) {
8906 v = atoi(val);
8907 if (v < 1 || v > 12) {
8908 send_resp(dut, conn, SIGMA_INVALID,
8909 "errorCode,Invalid month");
8910 return 0;
8911 }
8912 tm.tm_mon = v - 1;
8913 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008914 val = get_param(cmd, "year");
8915 if (val) {
8916 int year = atoi(val);
8917#ifdef ANDROID
8918 if (year > 2035)
8919 year = 2035; /* years beyond 2035 not supported */
8920#endif /* ANDROID */
8921 tm.tm_year = year - 1900;
8922 }
8923 t = mktime(&tm);
8924 if (t == (time_t) -1) {
8925 send_resp(dut, conn, SIGMA_ERROR,
8926 "errorCode,Invalid date or time");
8927 return 0;
8928 }
8929
8930 memset(&tv, 0, sizeof(tv));
8931 tv.tv_sec = t;
8932
8933 if (settimeofday(&tv, NULL) < 0) {
8934 sigma_dut_print(dut, DUT_MSG_INFO, "settimeofday failed: %s",
8935 strerror(errno));
8936 send_resp(dut, conn, SIGMA_ERROR,
8937 "errorCode,Failed to set time");
8938 return 0;
8939 }
8940
8941 return 1;
8942#endif /* __linux__ */
8943
8944 return -1;
8945}
8946
8947
8948static int cmd_sta_osu(struct sigma_dut *dut, struct sigma_conn *conn,
8949 struct sigma_cmd *cmd)
8950{
8951 const char *intf = get_param(cmd, "Interface");
8952 const char *name, *val;
8953 int prod_ess_assoc = 1;
8954 char buf[200], bssid[100], ssid[100];
8955 int res;
8956 struct wpa_ctrl *ctrl;
8957
8958 name = get_param(cmd, "osuFriendlyName");
8959
8960 val = get_param(cmd, "ProdESSAssoc");
8961 if (val)
8962 prod_ess_assoc = atoi(val);
8963
8964 kill_dhcp_client(dut, intf);
8965 if (start_dhcp_client(dut, intf) < 0)
8966 return -2;
8967
8968 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger OSU");
8969 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
8970 res = snprintf(buf, sizeof(buf),
8971 "%s %s%s%s signup osu-ca.pem",
8972 prod_ess_assoc ? "" : "-N",
8973 name ? "-O'" : "", name ? name : "",
8974 name ? "'" : "");
8975
Kanchanapally, Vidyullatha12b66762015-12-31 16:46:42 +05308976 hs2_set_policy(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008977 if (run_hs20_osu(dut, buf) < 0) {
8978 FILE *f;
8979
8980 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to complete OSU");
8981
8982 f = fopen("hs20-osu-client.res", "r");
8983 if (f) {
8984 char resp[400], res[300], *pos;
8985 if (!fgets(res, sizeof(res), f))
8986 res[0] = '\0';
8987 pos = strchr(res, '\n');
8988 if (pos)
8989 *pos = '\0';
8990 fclose(f);
8991 sigma_dut_summary(dut, "hs20-osu-client provisioning failed: %s",
8992 res);
8993 snprintf(resp, sizeof(resp), "notify-send '%s'", res);
8994 if (system(resp) != 0) {
8995 }
8996 snprintf(resp, sizeof(resp),
8997 "SSID,,BSSID,,failureReason,%s", res);
8998 send_resp(dut, conn, SIGMA_COMPLETE, resp);
8999 return 0;
9000 }
9001
9002 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
9003 return 0;
9004 }
9005
9006 if (!prod_ess_assoc)
9007 goto report;
9008
9009 ctrl = open_wpa_mon(intf);
9010 if (ctrl == NULL) {
9011 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
9012 "wpa_supplicant monitor connection");
9013 return -1;
9014 }
9015
9016 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
9017 buf, sizeof(buf));
9018
9019 wpa_ctrl_detach(ctrl);
9020 wpa_ctrl_close(ctrl);
9021
9022 if (res < 0) {
9023 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to connect to "
9024 "network after OSU");
9025 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
9026 return 0;
9027 }
9028
9029report:
9030 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
9031 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
9032 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to get BSSID/SSID");
9033 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
9034 return 0;
9035 }
9036
9037 snprintf(buf, sizeof(buf), "SSID,%s,BSSID,%s", ssid, bssid);
9038 send_resp(dut, conn, SIGMA_COMPLETE, buf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009039 return 0;
9040}
9041
9042
9043static int cmd_sta_policy_update(struct sigma_dut *dut, struct sigma_conn *conn,
9044 struct sigma_cmd *cmd)
9045{
9046 const char *val;
9047 int timeout = 120;
9048
9049 val = get_param(cmd, "PolicyUpdate");
9050 if (val == NULL || atoi(val) == 0)
9051 return 1; /* No operation requested */
9052
9053 val = get_param(cmd, "Timeout");
9054 if (val)
9055 timeout = atoi(val);
9056
9057 if (timeout) {
9058 /* TODO: time out the command and return
9059 * PolicyUpdateStatus,TIMEOUT if needed. */
9060 }
9061
9062 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger policy update");
9063 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
9064 if (run_hs20_osu(dut, "pol_upd fqdn=wi-fi.org") < 0) {
9065 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,FAIL");
9066 return 0;
9067 }
9068
9069 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,SUCCESS");
9070 return 0;
9071}
9072
9073
9074static int cmd_sta_er_config(struct sigma_dut *dut, struct sigma_conn *conn,
9075 struct sigma_cmd *cmd)
9076{
9077 struct wpa_ctrl *ctrl;
9078 const char *intf = get_param(cmd, "Interface");
9079 const char *bssid = get_param(cmd, "Bssid");
9080 const char *ssid = get_param(cmd, "SSID");
9081 const char *security = get_param(cmd, "Security");
9082 const char *passphrase = get_param(cmd, "Passphrase");
9083 const char *pin = get_param(cmd, "PIN");
9084 char buf[1000];
9085 char ssid_hex[200], passphrase_hex[200];
9086 const char *keymgmt, *cipher;
9087
9088 if (intf == NULL)
9089 intf = get_main_ifname();
9090
9091 if (!bssid) {
9092 send_resp(dut, conn, SIGMA_ERROR,
9093 "ErrorCode,Missing Bssid argument");
9094 return 0;
9095 }
9096
9097 if (!ssid) {
9098 send_resp(dut, conn, SIGMA_ERROR,
9099 "ErrorCode,Missing SSID argument");
9100 return 0;
9101 }
9102
9103 if (!security) {
9104 send_resp(dut, conn, SIGMA_ERROR,
9105 "ErrorCode,Missing Security argument");
9106 return 0;
9107 }
9108
9109 if (!passphrase) {
9110 send_resp(dut, conn, SIGMA_ERROR,
9111 "ErrorCode,Missing Passphrase argument");
9112 return 0;
9113 }
9114
9115 if (!pin) {
9116 send_resp(dut, conn, SIGMA_ERROR,
9117 "ErrorCode,Missing PIN argument");
9118 return 0;
9119 }
9120
vamsi krishna8c9c1562017-05-12 15:51:46 +05309121 if (2 * strlen(ssid) >= sizeof(ssid_hex) ||
9122 2 * strlen(passphrase) >= sizeof(passphrase_hex)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009123 send_resp(dut, conn, SIGMA_ERROR,
9124 "ErrorCode,Too long SSID/passphrase");
9125 return 0;
9126 }
9127
9128 ctrl = open_wpa_mon(intf);
9129 if (ctrl == NULL) {
9130 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
9131 "wpa_supplicant monitor connection");
9132 return -2;
9133 }
9134
9135 if (strcasecmp(security, "wpa2-psk") == 0) {
9136 keymgmt = "WPA2PSK";
9137 cipher = "CCMP";
9138 } else {
9139 wpa_ctrl_detach(ctrl);
9140 wpa_ctrl_close(ctrl);
9141 send_resp(dut, conn, SIGMA_ERROR,
9142 "ErrorCode,Unsupported Security value");
9143 return 0;
9144 }
9145
9146 ascii2hexstr(ssid, ssid_hex);
9147 ascii2hexstr(passphrase, passphrase_hex);
9148 snprintf(buf, sizeof(buf), "WPS_REG %s %s %s %s %s %s",
9149 bssid, pin, ssid_hex, keymgmt, cipher, passphrase_hex);
9150
9151 if (wpa_command(intf, buf) < 0) {
9152 wpa_ctrl_detach(ctrl);
9153 wpa_ctrl_close(ctrl);
9154 send_resp(dut, conn, SIGMA_ERROR,
9155 "ErrorCode,Failed to start registrar");
9156 return 0;
9157 }
9158
9159 snprintf(dut->er_oper_bssid, sizeof(dut->er_oper_bssid), "%s", bssid);
9160 dut->er_oper_performed = 1;
9161
9162 return wps_connection_event(dut, conn, ctrl, intf, 0);
9163}
9164
9165
9166static int cmd_sta_wps_connect_pw_token(struct sigma_dut *dut,
9167 struct sigma_conn *conn,
9168 struct sigma_cmd *cmd)
9169{
9170 struct wpa_ctrl *ctrl;
9171 const char *intf = get_param(cmd, "Interface");
9172 const char *bssid = get_param(cmd, "Bssid");
9173 char buf[100];
9174
9175 if (!bssid) {
9176 send_resp(dut, conn, SIGMA_ERROR,
9177 "ErrorCode,Missing Bssid argument");
9178 return 0;
9179 }
9180
9181 ctrl = open_wpa_mon(intf);
9182 if (ctrl == NULL) {
9183 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
9184 "wpa_supplicant monitor connection");
9185 return -2;
9186 }
9187
9188 snprintf(buf, sizeof(buf), "WPS_NFC %s", bssid);
9189
9190 if (wpa_command(intf, buf) < 0) {
9191 wpa_ctrl_detach(ctrl);
9192 wpa_ctrl_close(ctrl);
9193 send_resp(dut, conn, SIGMA_ERROR,
9194 "ErrorCode,Failed to start registrar");
9195 return 0;
9196 }
9197
9198 return wps_connection_event(dut, conn, ctrl, intf, 0);
9199}
9200
9201
vamsi krishna9b144002017-09-20 13:28:13 +05309202static int cmd_start_wps_registration(struct sigma_dut *dut,
9203 struct sigma_conn *conn,
9204 struct sigma_cmd *cmd)
9205{
9206 struct wpa_ctrl *ctrl;
9207 const char *intf = get_param(cmd, "Interface");
9208 const char *role, *method;
9209 int res;
9210 char buf[256];
9211 const char *events[] = {
9212 "CTRL-EVENT-CONNECTED",
9213 "WPS-OVERLAP-DETECTED",
9214 "WPS-TIMEOUT",
9215 "WPS-FAIL",
9216 NULL
9217 };
9218
9219 ctrl = open_wpa_mon(intf);
9220 if (!ctrl) {
9221 sigma_dut_print(dut, DUT_MSG_ERROR,
9222 "Failed to open wpa_supplicant monitor connection");
9223 return -2;
9224 }
9225
9226 role = get_param(cmd, "WpsRole");
9227 if (!role) {
9228 send_resp(dut, conn, SIGMA_INVALID,
9229 "ErrorCode,WpsRole not provided");
9230 goto fail;
9231 }
9232
9233 if (strcasecmp(role, "Enrollee") == 0) {
9234 method = get_param(cmd, "WpsConfigMethod");
9235 if (!method) {
9236 send_resp(dut, conn, SIGMA_INVALID,
9237 "ErrorCode,WpsConfigMethod not provided");
9238 goto fail;
9239 }
9240 if (strcasecmp(method, "PBC") == 0) {
9241 if (wpa_command(intf, "WPS_PBC") < 0) {
9242 send_resp(dut, conn, SIGMA_ERROR,
9243 "ErrorCode,Failed to enable PBC");
9244 goto fail;
9245 }
9246 } else {
9247 /* TODO: PIN method */
9248 send_resp(dut, conn, SIGMA_ERROR,
9249 "ErrorCode,Unsupported WpsConfigMethod value");
9250 goto fail;
9251 }
9252 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
9253 if (res < 0) {
9254 send_resp(dut, conn, SIGMA_ERROR,
9255 "ErrorCode,WPS connection did not complete");
9256 goto fail;
9257 }
9258 if (strstr(buf, "WPS-TIMEOUT")) {
9259 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,NoPeer");
9260 } else if (strstr(buf, "WPS-OVERLAP-DETECTED")) {
9261 send_resp(dut, conn, SIGMA_ERROR,
9262 "ErrorCode,OverlapSession");
9263 } else if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
9264 send_resp(dut, conn, SIGMA_COMPLETE, "Successful");
9265 } else {
9266 send_resp(dut, conn, SIGMA_ERROR,
9267 "ErrorCode,WPS operation failed");
9268 }
9269 } else {
9270 /* TODO: Registrar role */
9271 send_resp(dut, conn, SIGMA_ERROR,
9272 "ErrorCode,Unsupported WpsRole value");
9273 }
9274
9275fail:
9276 wpa_ctrl_detach(ctrl);
9277 wpa_ctrl_close(ctrl);
9278 return 0;
9279}
9280
9281
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009282static int req_intf(struct sigma_cmd *cmd)
9283{
9284 return get_param(cmd, "interface") == NULL ? -1 : 0;
9285}
9286
9287
9288void sta_register_cmds(void)
9289{
9290 sigma_dut_reg_cmd("sta_get_ip_config", req_intf,
9291 cmd_sta_get_ip_config);
9292 sigma_dut_reg_cmd("sta_set_ip_config", req_intf,
9293 cmd_sta_set_ip_config);
9294 sigma_dut_reg_cmd("sta_get_info", req_intf, cmd_sta_get_info);
9295 sigma_dut_reg_cmd("sta_get_mac_address", req_intf,
9296 cmd_sta_get_mac_address);
9297 sigma_dut_reg_cmd("sta_is_connected", req_intf, cmd_sta_is_connected);
9298 sigma_dut_reg_cmd("sta_verify_ip_connection", req_intf,
9299 cmd_sta_verify_ip_connection);
9300 sigma_dut_reg_cmd("sta_get_bssid", req_intf, cmd_sta_get_bssid);
9301 sigma_dut_reg_cmd("sta_set_encryption", req_intf,
9302 cmd_sta_set_encryption);
9303 sigma_dut_reg_cmd("sta_set_psk", req_intf, cmd_sta_set_psk);
9304 sigma_dut_reg_cmd("sta_set_eaptls", req_intf, cmd_sta_set_eaptls);
9305 sigma_dut_reg_cmd("sta_set_eapttls", req_intf, cmd_sta_set_eapttls);
9306 sigma_dut_reg_cmd("sta_set_eapsim", req_intf, cmd_sta_set_eapsim);
9307 sigma_dut_reg_cmd("sta_set_peap", req_intf, cmd_sta_set_peap);
9308 sigma_dut_reg_cmd("sta_set_eapfast", req_intf, cmd_sta_set_eapfast);
9309 sigma_dut_reg_cmd("sta_set_eapaka", req_intf, cmd_sta_set_eapaka);
9310 sigma_dut_reg_cmd("sta_set_eapakaprime", req_intf,
9311 cmd_sta_set_eapakaprime);
9312 sigma_dut_reg_cmd("sta_set_security", req_intf, cmd_sta_set_security);
9313 sigma_dut_reg_cmd("sta_set_uapsd", req_intf, cmd_sta_set_uapsd);
9314 /* TODO: sta_set_ibss */
9315 /* TODO: sta_set_mode */
9316 sigma_dut_reg_cmd("sta_set_wmm", req_intf, cmd_sta_set_wmm);
9317 sigma_dut_reg_cmd("sta_associate", req_intf, cmd_sta_associate);
9318 /* TODO: sta_up_load */
9319 sigma_dut_reg_cmd("sta_preset_testparameters", req_intf,
9320 cmd_sta_preset_testparameters);
9321 /* TODO: sta_set_system */
9322 sigma_dut_reg_cmd("sta_set_11n", req_intf, cmd_sta_set_11n);
9323 /* TODO: sta_set_rifs_test */
9324 sigma_dut_reg_cmd("sta_set_wireless", req_intf, cmd_sta_set_wireless);
9325 sigma_dut_reg_cmd("sta_send_addba", req_intf, cmd_sta_send_addba);
9326 /* TODO: sta_send_coexist_mgmt */
9327 sigma_dut_reg_cmd("sta_disconnect", req_intf, cmd_sta_disconnect);
9328 sigma_dut_reg_cmd("sta_reassoc", req_intf, cmd_sta_reassoc);
9329 sigma_dut_reg_cmd("sta_reassociate", req_intf, cmd_sta_reassoc);
9330 sigma_dut_reg_cmd("sta_reset_default", req_intf,
9331 cmd_sta_reset_default);
9332 sigma_dut_reg_cmd("sta_send_frame", req_intf, cmd_sta_send_frame);
9333 sigma_dut_reg_cmd("sta_set_macaddr", req_intf, cmd_sta_set_macaddr);
9334 sigma_dut_reg_cmd("sta_set_rfeature", req_intf, cmd_sta_set_rfeature);
9335 sigma_dut_reg_cmd("sta_set_radio", req_intf, cmd_sta_set_radio);
9336 sigma_dut_reg_cmd("sta_set_pwrsave", req_intf, cmd_sta_set_pwrsave);
9337 sigma_dut_reg_cmd("sta_bssid_pool", req_intf, cmd_sta_bssid_pool);
9338 sigma_dut_reg_cmd("sta_reset_parm", req_intf, cmd_sta_reset_parm);
9339 sigma_dut_reg_cmd("sta_get_key", req_intf, cmd_sta_get_key);
9340 sigma_dut_reg_cmd("sta_hs2_associate", req_intf,
9341 cmd_sta_hs2_associate);
9342 sigma_dut_reg_cmd("sta_add_credential", req_intf,
9343 cmd_sta_add_credential);
9344 sigma_dut_reg_cmd("sta_scan", req_intf, cmd_sta_scan);
Jouni Malinen5e5d43d2018-01-10 17:29:33 +02009345 sigma_dut_reg_cmd("sta_scan_bss", req_intf, cmd_sta_scan_bss);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009346 sigma_dut_reg_cmd("sta_set_systime", NULL, cmd_sta_set_systime);
9347 sigma_dut_reg_cmd("sta_osu", req_intf, cmd_sta_osu);
9348 sigma_dut_reg_cmd("sta_policy_update", req_intf, cmd_sta_policy_update);
9349 sigma_dut_reg_cmd("sta_er_config", NULL, cmd_sta_er_config);
9350 sigma_dut_reg_cmd("sta_wps_connect_pw_token", req_intf,
9351 cmd_sta_wps_connect_pw_token);
9352 sigma_dut_reg_cmd("sta_exec_action", req_intf, cmd_sta_exec_action);
9353 sigma_dut_reg_cmd("sta_get_events", req_intf, cmd_sta_get_events);
9354 sigma_dut_reg_cmd("sta_get_parameter", req_intf, cmd_sta_get_parameter);
vamsi krishna9b144002017-09-20 13:28:13 +05309355 sigma_dut_reg_cmd("start_wps_registration", req_intf,
9356 cmd_start_wps_registration);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009357}