blob: 70f7f8b296777500b54407bd56ccde73d311ea48 [file] [log] [blame]
/*
* Sigma Control API DUT (station/AP)
* Copyright (c) 2010-2011, Atheros Communications, Inc.
* Copyright (c) 2011-2017, Qualcomm Atheros, Inc.
* Copyright (c) 2018-2019, The Linux Foundation
* All Rights Reserved.
* Licensed under the Clear BSD license. See README for more details.
*/
#include "sigma_dut.h"
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/utsname.h>
#include <sys/ioctl.h>
#ifdef __linux__
#include <limits.h>
#include <dirent.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#endif /* __linux__ */
#ifdef __QNXNTO__
#include <ifaddrs.h>
#include <net/if_dl.h>
#endif /* __QNXNTO__ */
#include "wpa_ctrl.h"
#include "wpa_helpers.h"
#ifdef ANDROID
#include <hardware_legacy/wifi.h>
#include <grp.h>
#include <pwd.h>
#endif /* ANDROID */
/* Temporary files for ap_send_addba_req */
#define VI_QOS_TMP_FILE "/tmp/vi-qos.tmp"
#define VI_QOS_FILE "/tmp/vi-qos.txt"
#define VI_QOS_REFFILE "/etc/vi-qos.txt"
/* Configuration file name on Android */
#ifndef ANDROID_CONFIG_FILE
#define ANDROID_CONFIG_FILE "/data/misc/wifi/hostapd.conf"
#endif /* ANDROID_CONFIG_FILE */
/* Maximum length of the line in the configuration file */
#define MAX_CONF_LINE_LEN (156)
#ifndef SIGMA_DUT_HOSTAPD_PID_FILE
#define SIGMA_DUT_HOSTAPD_PID_FILE "/tmp/sigma_dut-ap-hostapd.pid"
#endif /* SIGMA_DUT_HOSTAPD_PID_FILE */
/* The following is taken from Hotspot 2.0 testplan Appendix B.1 */
#define ANQP_VENUE_NAME_1 "02019c0002083d656e6757692d466920416c6c69616e63650a3239383920436f7070657220526f61640a53616e746120436c6172612c2043412039353035312c205553415b63686957692d4669e88194e79b9fe5ae9ee9aa8ce5aea40ae4ba8ce4b99de585abe4b99de5b9b4e5ba93e69f8fe8b7af0ae59ca3e5858be68b89e68b892c20e58aa0e588a9e7a68fe5b0bce4ba9a39353035312c20e7be8ee59bbd"
#define ANQP_VENUE_NAME_1_CHI "P\"\x63\x68\x69\x3a\x57\x69\x2d\x46\x69\xe8\x81\x94\xe7\x9b\x9f\xe5\xae\x9e\xe9\xaa\x8c\xe5\xae\xa4\\n\xe4\xba\x8c\xe4\xb9\x9d\xe5\x85\xab\xe4\xb9\x9d\xe5\xb9\xb4\xe5\xba\x93\xe6\x9f\x8f\xe8\xb7\xaf\\n\xe5\x9c\xa3\xe5\x85\x8b\xe6\x8b\x89\xe6\x8b\x89\x2c\x20\xe5\x8a\xa0\xe5\x88\xa9\xe7\xa6\x8f\xe5\xb0\xbc\xe4\xba\x9a\x39\x35\x30\x35\x31\x2c\x20\xe7\xbe\x8e\xe5\x9b\xbd\""
#define ANQP_IP_ADDR_TYPE_1 "060101000c"
#define ANQP_HS20_OPERATOR_FRIENDLY_NAME_1 "dddd2700506f9a11030011656e6757692d466920416c6c69616e63650e63686957692d4669e88194e79b9f"
#define ANQP_HS20_WAN_METRICS_1 "dddd1300506f9a11040001c40900008001000000000000"
#define ANQP_HS20_CONNECTION_CAPABILITY_1 "dddd3200506f9a1105000100000006140001061600000650000106bb010106bb060006c4130011f4010111c413001194110132000001"
#define QOS_MAP_SET_1 "53,2,22,6,8,15,0,7,255,255,16,31,32,39,255,255,40,47,255,255"
#define QOS_MAP_SET_2 "8,15,0,7,255,255,16,31,32,39,255,255,40,47,48,63"
#define ADV_OF_CHARGE_1 \
"bc01000000d200454e475553443c3f786d6c2076657273696f6e3d22312e30222065" \
"6e636f64696e673d225554462d38223f3e3c506c616e20786d6c6e733d22687474703a2f2f77" \
"77772e77692d66692e6f72672f73706563696669636174696f6e732f686f7473706f7432646f" \
"74302f76312e302f616f637069223e3c4465736372697074696f6e3e57692d46692061636365" \
"737320666f72203120686f75722c207768696c6520796f752077616974206174207468652067" \
"6174652c2024302e39393c2f4465736372697074696f6e3e3c2f506c616e3ee3004652414341" \
"443c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d38223f" \
"3e3c506c616e20786d6c6e733d22687474703a2f2f7777772e77692d66692e6f72672f737065" \
"63696669636174696f6e732f686f7473706f7432646f74302f76312e302f616f637069223e3c" \
"4465736372697074696f6e3e416363c3a8732057692d46692070656e64616e74203120686575" \
"72652c2070656e64616e742071756520766f757320617474656e64657a20c3a0206c6120706f" \
"7274652c20302c393920243c2f4465736372697074696f6e3e3c2f506c616e3ea101010000c7" \
"00454e475553443c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d2255" \
"54462d38223f3e3c506c616e20786d6c6e733d22687474703a2f2f7777772e77692d66692e6f" \
"72672f73706563696669636174696f6e732f686f7473706f7432646f74302f76312e302f616f" \
"637069223e3c4465736372697074696f6e3e446f776e6c6f616420766964656f7320666f7220" \
"796f757220666c696768742c2024322e393920666f7220313047423c2f446573637269707469" \
"6f6e3e3c2f506c616e3ed3004652414341443c3f786d6c2076657273696f6e3d22312e302220" \
"656e636f64696e673d225554462d38223f3e3c506c616e20786d6c6e733d22687474703a2f2f" \
"7777772e77692d66692e6f72672f73706563696669636174696f6e732f686f7473706f743264" \
"6f74302f76312e302f616f637069223e3c4465736372697074696f6e3e54c3a96cc3a9636861" \
"7267657a2064657320766964c3a96f7320706f757220766f74726520766f6c2c20322c393920" \
"2420706f757220313020476f3c2f4465736372697074696f6e3e3c2f506c616e3ee40003002b" \
"736572766963652d70726f76696465722e636f6d3b66656465726174696f6e2e6578616d706c" \
"652e636f6db400454e475553443c3f786d6c2076657273696f6e3d22312e302220656e636f64" \
"696e673d225554462d38223f3e3c506c616e20786d6c6e733d22687474703a2f2f7777772e77" \
"692d66692e6f72672f73706563696669636174696f6e732f686f7473706f7432646f74302f76" \
"312e302f616f637069223e3c4465736372697074696f6e3e46726565207769746820796f7572" \
"20737562736372697074696f6e213c2f4465736372697074696f6e3e3c2f506c616e3e"
/*
* MTU for Ethernet need to take into account 8-byte SNAP header
* to be added when encapsulating Ethernet frame into 802.11.
*/
#ifndef IEEE80211_MAX_DATA_LEN_DMG
#define IEEE80211_MAX_DATA_LEN_DMG 7920
#endif /* IEEE80211_MAX_DATA_LEN_DMG */
#ifndef IEEE80211_SNAP_LEN_DMG
#define IEEE80211_SNAP_LEN_DMG 8
#endif /* IEEE80211_SNAP_LEN_DMG */
extern char *sigma_main_ifname;
extern char *sigma_wpas_ctrl;
extern char *sigma_hapd_ctrl;
extern char *ap_inet_addr;
extern char *ap_inet_mask;
extern char *sigma_radio_ifname[];
static int ath_ap_start_hostapd(struct sigma_dut *dut);
static void ath_ap_set_params(struct sigma_dut *dut);
static int kill_process(struct sigma_dut *dut, char *proc_name,
unsigned char is_proc_instance_one, int sig);
static int ap_ft_enabled(struct sigma_dut *dut)
{
return dut->ap_ft_oa == 1 ||
dut->ap_key_mgmt == AP_WPA2_FT_EAP ||
dut->ap_key_mgmt == AP_WPA2_FT_PSK ||
dut->ap_key_mgmt == AP_WPA2_ENT_FT_EAP ||
(dut->ap_akm_values &
((1 << AKM_FT_EAP) |
(1 << AKM_FT_PSK) |
(1 << AKM_FT_SAE) |
(1 << AKM_FT_SUITE_B) |
(1 << AKM_FT_FILS_SHA256) |
(1 << AKM_FT_FILS_SHA384)));
}
static int cmd_ap_ca_version(struct sigma_dut *dut, struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
/* const char *name = get_param(cmd, "NAME"); */
send_resp(dut, conn, SIGMA_COMPLETE, "version,1.0");
return 0;
}
static void kill_hostapd_process_pid(struct sigma_dut *dut)
{
FILE *f;
int pid, res;
char path[100];
int count;
f = fopen(SIGMA_DUT_HOSTAPD_PID_FILE, "r");
if (!f)
return;
res = fscanf(f, "%d", &pid);
fclose(f);
if (res != 1)
return;
sigma_dut_print(dut, DUT_MSG_INFO, "Killing hostapd pid %d", pid);
kill(pid, SIGTERM);
snprintf(path, sizeof(path), "/proc/%d", pid);
for (count = 0; count < 20 && file_exists(path); count++)
usleep(100000);
}
int get_hwaddr(const char *ifname, unsigned char *hwaddr)
{
#ifndef __QNXNTO__
struct ifreq ifr;
int s;
s = socket(AF_INET, SOCK_DGRAM, 0);
if (s < 0)
return -1;
memset(&ifr, 0, sizeof(ifr));
strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) {
perror("ioctl");
close(s);
return -1;
}
close(s);
memcpy(hwaddr, ifr.ifr_hwaddr.sa_data, 6);
#else /* __QNXNTO__ */
struct ifaddrs *ifaddrshead = NULL;
int found = 0;
struct ifaddrs *temp_ifap = NULL;
struct sockaddr_dl *sdl = NULL;
if (getifaddrs(&ifaddrshead) != 0) {
perror("getifaddrs failed");
return -1;
}
for (temp_ifap = ifaddrshead; ifaddrshead && !found;
ifaddrshead = ifaddrshead->ifa_next) {
if (ifaddrshead->ifa_addr->sa_family == AF_LINK &&
strcmp(ifaddrshead->ifa_name, ifname) == 0) {
found = 1;
sdl = (struct sockaddr_dl *) ifaddrshead->ifa_addr;
if (sdl)
memcpy(hwaddr, LLADDR(sdl), sdl->sdl_alen);
}
}
if (temp_ifap)
freeifaddrs(temp_ifap);
if (!found) {
perror("Failed to get the interface");
return -1;
}
#endif /* __QNXNTO__ */
return 0;
}
static void ath_ap_set_group_id(struct sigma_dut *dut, const char *ifname,
const char *val)
{
char buf[60];
snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 55 %d",
ifname, atoi(val));
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"wifitool ap_group_id failed");
}
}
void ath_set_cts_width(struct sigma_dut *dut, const char *ifname,
const char *val)
{
char buf[60];
/* TODO: Enable support for other values */
if (strcasecmp(val, "40") == 0) {
snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 54 1",
ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"wifitool cts_width failed");
}
snprintf(buf, sizeof(buf),
"athdiag --set --address=0x10024 --val=0xd90b8a14");
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"disabling phy restart failed");
}
} else {
sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported CTS_WIDTH");
}
}
void ath_config_dyn_bw_sig(struct sigma_dut *dut, const char *ifname,
const char *val)
{
char buf[60];
if (strcasecmp(val, "enable") == 0) {
dut->ap_dyn_bw_sig = VALUE_ENABLED;
snprintf(buf, sizeof(buf), "iwpriv %s cwmenable 1", ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"iwpriv cwmenable 1 failed");
}
snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 96 1",
ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"disabling RTS from rate control logic failed");
}
} else if (strcasecmp(val, "disable") == 0) {
dut->ap_dyn_bw_sig = VALUE_DISABLED;
snprintf(buf, sizeof(buf), "iwpriv %s cwmenable 0", ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"iwpriv cwmenable 0 failed");
}
} else {
sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported DYN_BW_SGL");
}
}
static void ath_config_rts_force(struct sigma_dut *dut, const char *ifname,
const char *val)
{
char buf[60];
if (strcasecmp(val, "enable") == 0) {
dut->ap_sig_rts = VALUE_ENABLED;
snprintf(buf, sizeof(buf), "iwconfig %s rts 64", ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"iwconfig rts 64 failed");
}
snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 100 1",
ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"wifitool beeliner_fw_test 100 1 failed");
}
} else if (strcasecmp(val, "disable") == 0) {
dut->ap_sig_rts = VALUE_DISABLED;
snprintf(buf, sizeof(buf), "iwconfig %s rts 2347", ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"iwpriv rts 2347 failed");
}
} else {
sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported RTS_FORCE");
}
}
static void ath_radio(struct sigma_dut *dut, const char *val)
{
if (strcasecmp(val, "on") == 0) {
if (dut->ap_interface_5g == 1) {
run_system(dut, "uci set wireless.wifi0.disabled=0");
} else if (dut->ap_interface_2g == 1) {
run_system(dut, "uci set wireless.wifi1.disabled=0");
} else {
run_system(dut, "uci set wireless.wifi0.disabled=0");
run_system(dut, "uci set wireless.wifi1.disabled=0");
}
run_system(dut, "uci commit");
run_system(dut, "wifi down");
run_system(dut, "wifi up");
} else if (strcasecmp(val, "off") == 0) {
if (dut->ap_interface_5g == 1) {
run_system(dut, "uci set wireless.wifi0.disabled=1");
} else if (dut->ap_interface_2g == 1) {
run_system(dut, "uci set wireless.wifi1.disabled=1");
} else {
run_system(dut, "uci set wireless.wifi0.disabled=1");
run_system(dut, "uci set wireless.wifi1.disabled=1");
}
run_system(dut, "uci commit");
run_system(dut, "wifi down");
run_system(dut, "wifi up");
}
}
static void deauth_disassoc(struct sigma_dut *dut, const char *ifname,
const char *val)
{
char buf[60];
if (strcasecmp(val, "disable") == 0) {
snprintf(buf, sizeof(buf), "iwpriv %s stealthdown 1", ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"disable deauthdisassoctx failed");
}
}
}
static void ath_set_txpower(struct sigma_dut *dut, const char *ifname,
const char *val)
{
char buf[60];
if (strcasecmp(val, "high") == 0)
snprintf(buf, sizeof(buf), "iwconfig %s txpower 29", ifname);
else if (strcasecmp(val, "low") == 0)
snprintf(buf, sizeof(buf), "iwconfig %s txpower 1", ifname);
else
sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported txpower");
if (system(buf) != 0)
sigma_dut_print(dut, DUT_MSG_ERROR, "setting txpower failed");
}
static enum ap_mode get_mode(const char *str)
{
if (strcasecmp(str, "11a") == 0)
return AP_11a;
else if (strcasecmp(str, "11g") == 0)
return AP_11g;
else if (strcasecmp(str, "11b") == 0)
return AP_11b;
else if (strcasecmp(str, "11na") == 0)
return AP_11na;
else if (strcasecmp(str, "11ng") == 0)
return AP_11ng;
else if (strcasecmp(str, "11ac") == 0 || strcasecmp(str, "ac") == 0)
return AP_11ac;
else if (strcasecmp(str, "11ad") == 0)
return AP_11ad;
else
return AP_inval;
}
static int run_hostapd_cli(struct sigma_dut *dut, char *buf)
{
char command[1000];
const char *bin;
enum driver_type drv = get_driver_type();
char *sigma_hapd_file = sigma_hapd_ctrl;
if (file_exists("hostapd_cli"))
bin = "./hostapd_cli";
else if (file_exists("../../hostapd/hostapd_cli"))
bin = "../../hostapd/hostapd_cli";
else
bin = "hostapd_cli";
if (drv == DRIVER_OPENWRT && sigma_hapd_ctrl == NULL) {
sigma_hapd_file = "/var/run/hostapd-wifi0";
if (sigma_radio_ifname[0] &&
strcmp(sigma_radio_ifname[0], "wifi1") == 0)
sigma_hapd_file = "/var/run/hostapd-wifi1";
else if (sigma_radio_ifname[0] &&
strcmp(sigma_radio_ifname[0], "wifi2") == 0)
sigma_hapd_file = "/var/run/hostapd-wifi2";
}
if (sigma_hapd_file)
snprintf(command, sizeof(command), "%s -p %s %s",
bin, sigma_hapd_file, buf);
else
snprintf(command, sizeof(command), "%s %s", bin, buf);
return run_system(dut, command);
}
static int ath_set_lci_config(struct sigma_dut *dut, const char *val,
struct sigma_cmd *cmd)
{
FILE *f;
int i;
f = fopen("/tmp/lci_cfg.txt", "w");
if (!f) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Failed to open /tmp/lci_cfg.txt");
return -1;
}
for (i = 2; i < cmd->count; i++)
fprintf(f, "%s = %s \n", cmd->params[i], cmd->values[i]);
fprintf(f, "\n");
fclose(f);
return 0;
}
static int cmd_ap_set_wireless(struct sigma_dut *dut, struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
/* const char *name = get_param(cmd, "NAME"); */
/* const char *ifname = get_param(cmd, "INTERFACE"); */
const char *val;
unsigned int wlan_tag = 1;
char *ifname = get_main_ifname();
char buf[128];
/* Allow program to be overridden if specified in the ap_set_wireless
* to support some 60 GHz test scripts where the program may be 60 GHz
* or WPS. */
val = get_param(cmd, "PROGRAM");
if (val)
dut->program = sigma_program_to_enum(val);
val = get_param(cmd, "WLAN_TAG");
if (val) {
wlan_tag = atoi(val);
if (wlan_tag < 1 || wlan_tag > 3) {
/*
* The only valid WLAN Tags as of now as per the latest
* WFA scripts are 1, 2, and 3.
*/
send_resp(dut, conn, SIGMA_INVALID,
"errorCode,Invalid WLAN_TAG");
return 0;
}
}
val = get_param(cmd, "Interface");
if (val) {
if (strcasecmp(val, "5G") == 0)
dut->ap_interface_5g = 1;
else
dut->ap_interface_2g = 1;
if (dut->ap_interface_5g && dut->ap_interface_2g)
dut->ap_is_dual = 1;
}
val = get_param(cmd, "CountryCode");
if (val) {
if (strlen(val) > sizeof(dut->ap_countrycode) - 1)
return -1;
snprintf(dut->ap_countrycode, sizeof(dut->ap_countrycode),
"%s", val);
}
val = get_param(cmd, "regulatory_mode");
if (val) {
if (strcasecmp(val, "11d") == 0 || strcasecmp(val, "11h") == 0)
dut->ap_regulatory_mode = AP_80211D_MODE_ENABLED;
}
val = get_param(cmd, "SSID");
if (val) {
if (strlen(val) > sizeof(dut->ap_ssid) - 1)
return -1;
if (wlan_tag == 1) {
/*
* If tag is not specified, it is deemed to be 1.
* Hence tag of 1 is a special case and the values
* corresponding to wlan-tag=1 are stored separately
* from the values corresponding tags 2 and 3.
* This approach minimises the changes to existing code
* since most of the sigma_dut code does not deal with
* WLAN-TAG CAPI variable.
*/
snprintf(dut->ap_ssid,
sizeof(dut->ap_ssid), "%s", val);
} else {
snprintf(dut->ap_tag_ssid[wlan_tag - 2],
sizeof(dut->ap_tag_ssid[wlan_tag - 2]),
"%s", val);
}
}
val = get_param(cmd, "CHANNEL");
if (val) {
const char *pos;
dut->ap_channel = atoi(val);
pos = strchr(val, ';');
if (pos) {
pos++;
dut->ap_channel_1 = atoi(pos);
}
}
/* Overwrite the AP channel with DFS channel if configured */
val = get_param(cmd, "dfs_chan");
if (val) {
dut->ap_channel = atoi(val);
}
val = get_param(cmd, "dfs_mode");
if (val) {
if (strcasecmp(val, "Enable") == 0)
dut->ap_dfs_mode = AP_DFS_MODE_ENABLED;
else if (strcasecmp(val, "Disable") == 0)
dut->ap_dfs_mode = AP_DFS_MODE_DISABLED;
else
sigma_dut_print(dut, DUT_MSG_ERROR,
"Unsupported dfs_mode value: %s", val);
}
val = get_param(cmd, "MODE");
if (val) {
char *str, *pos;
str = strdup(val);
if (str == NULL)
return -1;
pos = strchr(str, ';');
if (pos)
*pos++ = '\0';
dut->ap_is_dual = 0;
dut->ap_mode = get_mode(str);
if (dut->ap_mode == AP_inval) {
send_resp(dut, conn, SIGMA_INVALID,
"errorCode,Unsupported MODE");
free(str);
return 0;
}
if (dut->ap_mode == AP_11ac && dut->ap_80plus80 != 1)
dut->ap_chwidth = AP_80;
if (pos) {
dut->ap_mode_1 = get_mode(pos);
if (dut->ap_mode_1 == AP_inval) {
send_resp(dut, conn, SIGMA_INVALID,
"errorCode,Unsupported MODE");
free(str);
return 0;
}
if (dut->ap_mode_1 == AP_11ac)
dut->ap_chwidth_1 = AP_80;
dut->ap_is_dual = 1;
}
free(str);
} else if (dut->ap_mode == AP_inval) {
if (dut->ap_channel <= 11)
dut->ap_mode = AP_11ng;
else if (dut->program == PROGRAM_VHT)
dut->ap_mode = AP_11ac;
else
dut->ap_mode = AP_11na;
}
/* Override the AP mode in case of 60 GHz */
if (dut->program == PROGRAM_60GHZ) {
dut->ap_mode = AP_11ad;
/* Workaround to force channel 2 if not specified */
if (!dut->ap_channel)
dut->ap_channel = 2;
}
val = get_param(cmd, "WME");
if (val) {
if (strcasecmp(val, "on") == 0)
dut->ap_wme = AP_WME_ON;
else if (strcasecmp(val, "off") == 0)
dut->ap_wme = AP_WME_OFF;
else
sigma_dut_print(dut, DUT_MSG_ERROR,
"Unsupported WME value: %s", val);
}
val = get_param(cmd, "WMMPS");
if (val) {
if (strcasecmp(val, "on") == 0)
dut->ap_wmmps = AP_WMMPS_ON;
else if (strcasecmp(val, "off") == 0)
dut->ap_wmmps = AP_WMMPS_OFF;
else
sigma_dut_print(dut, DUT_MSG_ERROR,
"Unsupported WMMPS value: %s", val);
}
val = get_param(cmd, "RTS");
if (val)
dut->ap_rts = atoi(val);
val = get_param(cmd, "FRGMNT");
if (val)
dut->ap_frgmnt = atoi(val);
/* TODO: PWRSAVE */
val = get_param(cmd, "BCNINT");
if (val)
dut->ap_bcnint = atoi(val);
val = get_param(cmd, "RADIO");
if (val) {
enum driver_type drv = get_driver_type();
if (strcasecmp(val, "on") == 0) {
if (drv == DRIVER_OPENWRT)
ath_radio(dut, val);
if (drv == DRIVER_ATHEROS)
ath_ap_start_hostapd(dut);
else if (cmd_ap_config_commit(dut, conn, cmd) <= 0)
return 0;
} else if (strcasecmp(val, "off") == 0) {
if (drv == DRIVER_OPENWRT) {
ath_radio(dut, val);
} else if (dut->use_hostapd_pid_file) {
kill_hostapd_process_pid(dut);
} else if (kill_process(dut, "(hostapd)", 1,
SIGTERM) == 0 ||
system("killall hostapd") == 0) {
sigma_dut_print(dut, DUT_MSG_INFO,
"Killed hostapd on radio,off");
}
} else {
send_resp(dut, conn, SIGMA_INVALID,
"errorCode,Unsupported RADIO value");
return 0;
}
}
val = get_param(cmd, "P2PMgmtBit");
if (val)
dut->ap_p2p_mgmt = atoi(val);
/* TODO: ChannelUsage */
/* TODO: 40_INTOLERANT */
val = get_param(cmd, "ADDBA_REJECT");
if (val) {
if (strcasecmp(val, "Enable") == 0)
dut->ap_addba_reject = VALUE_ENABLED;
else if (strcasecmp(val, "Disable") == 0)
dut->ap_addba_reject = VALUE_DISABLED;
}
val = get_param(cmd, "AMPDU");
if (val) {
if (strcasecmp(val, "Enable") == 0)
dut->ap_ampdu = VALUE_ENABLED;
else if (strcasecmp(val, "Disable") == 0)
dut->ap_ampdu = VALUE_DISABLED;
}
val = get_param(cmd, "AMPDU_EXP");
if (val)
dut->ap_ampdu_exp = atoi(val);
val = get_param(cmd, "AMSDU");
if (val) {
if (strcasecmp(val, "Enable") == 0)
dut->ap_amsdu = VALUE_ENABLED;
else if (strcasecmp(val, "Disable") == 0)
dut->ap_amsdu = VALUE_DISABLED;
}
val = get_param(cmd, "NoAck");
if (val) {
if (strcasecmp(val, "on") == 0)
dut->ap_noack = VALUE_ENABLED;
else if (strcasecmp(val, "off") == 0)
dut->ap_noack = VALUE_DISABLED;
}
/* TODO: GREENFIELD */
/* TODO: MCS_32 */
val = get_param(cmd, "OFFSET");
if (val) {
if (strcasecmp(val, "Above") == 0)
dut->ap_chwidth_offset = SEC_CH_40ABOVE;
else if (strcasecmp(val, "Below") == 0)
dut->ap_chwidth_offset = SEC_CH_40BELOW;
}
val = get_param(cmd, "MCS_FIXEDRATE");
if (val) {
dut->ap_fixed_rate = 1;
dut->ap_mcs = atoi(val);
}
val = get_param(cmd, "SPATIAL_RX_STREAM");
if (val) {
if (strcasecmp(val, "1SS") == 0 || strcasecmp(val, "1") == 0) {
dut->ap_rx_streams = 1;
if (dut->device_type == AP_testbed)
dut->ap_vhtmcs_map = 0xfffc;
} else if (strcasecmp(val, "2SS") == 0 ||
strcasecmp(val, "2") == 0) {
dut->ap_rx_streams = 2;
if (dut->device_type == AP_testbed)
dut->ap_vhtmcs_map = 0xfff0;
} else if (strcasecmp(val, "3SS") == 0 ||
strcasecmp(val, "3") == 0) {
dut->ap_rx_streams = 3;
if (dut->device_type == AP_testbed)
dut->ap_vhtmcs_map = 0xffc0;
} else if (strcasecmp(val, "4SS") == 0 ||
strcasecmp(val, "4") == 0) {
dut->ap_rx_streams = 4;
}
}
val = get_param(cmd, "SPATIAL_TX_STREAM");
if (val) {
if (strcasecmp(val, "1SS") == 0 ||
strcasecmp(val, "1") == 0) {
dut->ap_tx_streams = 1;
if (dut->device_type == AP_testbed)
dut->ap_vhtmcs_map = 0xfffc;
} else if (strcasecmp(val, "2SS") == 0 ||
strcasecmp(val, "2") == 0) {
dut->ap_tx_streams = 2;
if (dut->device_type == AP_testbed)
dut->ap_vhtmcs_map = 0xfff0;
} else if (strcasecmp(val, "3SS") == 0 ||
strcasecmp(val, "3") == 0) {
dut->ap_tx_streams = 3;
if (dut->device_type == AP_testbed)
dut->ap_vhtmcs_map = 0xffc0;
} else if (strcasecmp(val, "4SS") == 0 ||
strcasecmp(val, "4") == 0) {
dut->ap_tx_streams = 4;
}
}
val = get_param(cmd, "BSS_max_idle");
if (val) {
if (strncasecmp(val, "Enable", 7) == 0) {
dut->wnm_bss_max_feature = VALUE_ENABLED;
} else if (strncasecmp(val, "Disable", 8) == 0) {
dut->wnm_bss_max_feature = VALUE_DISABLED;
} else {
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Invalid value for BSS_max_Feature");
return 0;
}
}
val = get_param(cmd, "BSS_Idle_Protection_options");
if (val) {
int protection = (int) strtol(val, (char **) NULL, 10);
if (protection != 1 && protection != 0) {
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Invalid value for BSS_Idle_Protection_options");
return 0;
}
dut->wnm_bss_max_protection = protection ?
VALUE_ENABLED : VALUE_DISABLED;
}
val = get_param(cmd, "BSS_max_Idle_period");
if (val) {
long int idle_time = strtol(val, (char **) NULL, 10);
if (idle_time == LONG_MIN || idle_time == LONG_MAX) {
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Invalid value for BSS_max_Idle_period");
return 0;
}
dut->wnm_bss_max_idle_time = (int) idle_time;
}
val = get_param(cmd, "PROXY_ARP");
if (val)
dut->ap_proxy_arp = (int) strtol(val, (char **) NULL, 10);
val = get_param(cmd, "nss_mcs_cap");
if (val) {
int nss, mcs;
char token[20];
char *result = NULL;
char *saveptr;
if (strlen(val) >= sizeof(token))
return -1;
strlcpy(token, val, sizeof(token));
result = strtok_r(token, ";", &saveptr);
if (!result) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"VHT NSS not specified");
return 0;
}
nss = atoi(result);
result = strtok_r(NULL, ";", &saveptr);
if (result == NULL) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"VHTMCS NOT SPECIFIED!");
return 0;
}
result = strtok_r(result, "-", &saveptr);
result = strtok_r(NULL, "-", &saveptr);
if (!result) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"VHT MCS not specified");
return 0;
}
mcs = atoi(result);
switch (nss) {
case 1:
switch (mcs) {
case 7:
dut->ap_vhtmcs_map = 0xfffc;
break;
case 8:
dut->ap_vhtmcs_map = 0xfffd;
break;
case 9:
dut->ap_vhtmcs_map = 0xfffe;
break;
default:
dut->ap_vhtmcs_map = 0xfffe;
break;
}
break;
case 2:
switch (mcs) {
case 7:
dut->ap_vhtmcs_map = 0xfff0;
break;
case 8:
dut->ap_vhtmcs_map = 0xfff5;
break;
case 9:
dut->ap_vhtmcs_map = 0xfffa;
break;
default:
dut->ap_vhtmcs_map = 0xfffa;
break;
}
break;
case 3:
switch (mcs) {
case 7:
dut->ap_vhtmcs_map = 0xffc0;
break;
case 8:
dut->ap_vhtmcs_map = 0xffd5;
break;
case 9:
dut->ap_vhtmcs_map = 0xffea;
break;
default:
dut->ap_vhtmcs_map = 0xffea;
break;
}
break;
default:
dut->ap_vhtmcs_map = 0xffea;
break;
}
}
/* TODO: MPDU_MIN_START_SPACING */
/* TODO: RIFS_TEST */
/* TODO: SGI20 */
val = get_param(cmd, "STBC_TX");
if (val)
dut->ap_tx_stbc = atoi(val);
val = get_param(cmd, "WIDTH");
if (val) {
if (strcasecmp(val, "20") == 0)
dut->ap_chwidth = AP_20;
else if (strcasecmp(val, "40") == 0)
dut->ap_chwidth = AP_40;
else if (strcasecmp(val, "80") == 0)
dut->ap_chwidth = AP_80;
else if (strcasecmp(val, "160") == 0)
dut->ap_chwidth = AP_160;
else if (strcasecmp(val, "80plus80") == 0) {
dut->ap_80plus80 = 1;
dut->ap_chwidth = AP_80_80;
} else if (strcasecmp(val, "Auto") == 0)
dut->ap_chwidth = AP_AUTO;
else {
send_resp(dut, conn, SIGMA_INVALID,
"errorCode,Unsupported WIDTH");
return 0;
}
}
/* TODO: WIDTH_SCAN */
val = get_param(cmd, "TDLSProhibit");
dut->ap_tdls_prohibit = val && strcasecmp(val, "Enabled") == 0;
val = get_param(cmd, "TDLSChswitchProhibit");
dut->ap_tdls_prohibit_chswitch =
val && strcasecmp(val, "Enabled") == 0;
val = get_param(cmd, "HS2");
if (val && wlan_tag == 1)
dut->ap_hs2 = atoi(val);
val = get_param(cmd, "P2P_CROSS_CONNECT");
if (val)
dut->ap_p2p_cross_connect = strcasecmp(val, "Enabled") == 0;
val = get_param(cmd, "FakePubKey");
dut->ap_fake_pkhash = val && atoi(val);
val = get_param(cmd, "vht_tkip");
dut->ap_allow_vht_tkip = val && strcasecmp(val, "Enable") == 0;
val = get_param(cmd, "vht_wep");
dut->ap_allow_vht_wep = val && strcasecmp(val, "Enable") == 0;
val = get_param(cmd, "Protect_mode");
dut->ap_disable_protection = val && strcasecmp(val, "Disable") == 0;
val = get_param(cmd, "DYN_BW_SGNL");
if (val) {
switch (get_driver_type()) {
case DRIVER_OPENWRT:
switch (get_openwrt_driver_type()) {
case OPENWRT_DRIVER_ATHEROS:
ath_config_dyn_bw_sig(dut, ifname, val);
break;
default:
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Unsupported DYN_BW_SGNL with OpenWrt driver");
return 0;
}
break;
case DRIVER_WCN:
case DRIVER_LINUX_WCN:
ath_config_dyn_bw_sig(dut, ifname, val);
break;
default:
sigma_dut_print(dut, DUT_MSG_ERROR,
"Unsupported DYN_BW_SGL with the current driver");
break;
}
}
val = get_param(cmd, "SGI80");
if (val) {
if (strcasecmp(val, "enable") == 0)
dut->ap_sgi80 = 1;
else if (strcasecmp(val, "disable") == 0)
dut->ap_sgi80 = 0;
else {
send_resp(dut, conn, SIGMA_INVALID,
"errorCode,Unsupported SGI80");
return 0;
}
}
val = get_param(cmd, "LDPC");
if (val) {
if (strcasecmp(val, "enable") == 0)
dut->ap_ldpc = VALUE_ENABLED;
else if (strcasecmp(val, "disable") == 0)
dut->ap_ldpc = VALUE_DISABLED;
else {
send_resp(dut, conn, SIGMA_INVALID,
"errorCode,Unsupported LDPC");
return 0;
}
}
val = get_param(cmd, "BW_SGNL");
if (val) {
/*
* With dynamic bandwidth signaling enabled we should see
* RTS if the threshold is met.
*/
if (strcasecmp(val, "enable") == 0) {
dut->ap_sig_rts = VALUE_ENABLED;
} else if (strcasecmp(val, "disable") == 0) {
dut->ap_sig_rts = VALUE_DISABLED;
} else {
send_resp(dut, conn, SIGMA_INVALID,
"errorCode,Unsupported BW_SGNL");
return 0;
}
}
val = get_param(cmd, "RTS_FORCE");
if (val) {
switch (get_driver_type()) {
case DRIVER_OPENWRT:
switch (get_openwrt_driver_type()) {
case OPENWRT_DRIVER_ATHEROS:
ath_config_rts_force(dut, ifname, val);
break;
default:
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Unsupported RTS_FORCE with OpenWrt driver");
return 0;
}
break;
default:
sigma_dut_print(dut, DUT_MSG_ERROR,
"Unsupported RTS_FORCE with the current driver");
break;
}
}
val = get_param(cmd, "Zero_crc");
if (val) {
switch (get_driver_type()) {
case DRIVER_ATHEROS:
ath_set_zero_crc(dut, val);
break;
case DRIVER_OPENWRT:
switch (get_openwrt_driver_type()) {
case OPENWRT_DRIVER_ATHEROS:
ath_set_zero_crc(dut, val);
break;
default:
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Unsupported zero_crc with the current driver");
return 0;
}
break;
default:
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Unsupported zero_crc with the current driver");
return 0;
}
}
val = get_param(cmd, "TxBF");
if (val)
dut->ap_txBF = strcasecmp(val, "enable") == 0;
val = get_param(cmd, "MU_TxBF");
if (val) {
if (strcasecmp(val, "enable") == 0) {
dut->ap_txBF = 1;
dut->ap_mu_txBF = 1;
} else if (strcasecmp(val, "disable") == 0) {
dut->ap_txBF = 0;
dut->ap_mu_txBF = 0;
} else {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Unsupported MU_TxBF");
}
}
/* UNSUPPORTED: tx_lgi_rate */
val = get_param(cmd, "wpsnfc");
if (val)
dut->ap_wpsnfc = atoi(val);
val = get_param(cmd, "GROUP_ID");
if (val) {
switch (get_driver_type()) {
case DRIVER_OPENWRT:
switch (get_openwrt_driver_type()) {
case OPENWRT_DRIVER_ATHEROS:
ath_ap_set_group_id(dut, ifname, val);
break;
default:
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Unsupported group_id with the current driver");
return 0;
}
break;
default:
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Unsupported group_id with the current driver");
return 0;
}
}
val = get_param(cmd, "CTS_WIDTH");
if (val) {
switch (get_driver_type()) {
case DRIVER_OPENWRT:
switch (get_openwrt_driver_type()) {
case OPENWRT_DRIVER_ATHEROS:
ath_set_cts_width(dut, ifname, val);
break;
default:
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Unsupported cts_width with the current driver");
return 0;
}
break;
default:
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Unsupported cts_width with the current driver");
return 0;
}
}
val = get_param(cmd, "MU_NDPA_FrameFormat");
if (val)
dut->ap_ndpa_frame = atoi(val);
val = get_param(cmd, "interworking");
if (val && strcmp(val, "1") == 0)
dut->ap_interworking = 1;
val = get_param(cmd, "GAS_CB_DELAY");
if (val)
dut->ap_gas_cb_delay = atoi(val);
val = get_param(cmd, "LCI");
if (val) {
if (strlen(val) > sizeof(dut->ap_val_lci) - 1)
return -1;
dut->ap_lci = 1;
snprintf(dut->ap_val_lci, sizeof(dut->ap_val_lci), "%s", val);
ath_set_lci_config(dut, val, cmd);
}
val = get_param(cmd, "InfoZ");
if (val) {
if (strlen(val) > sizeof(dut->ap_infoz) - 1)
return -1;
snprintf(dut->ap_infoz, sizeof(dut->ap_infoz), "%s", val);
}
val = get_param(cmd, "LocCivicAddr");
if (val) {
if (strlen(val) > sizeof(dut->ap_val_lcr) - 1)
return -1;
dut->ap_lcr = 1;
snprintf(dut->ap_val_lcr, sizeof(dut->ap_val_lcr), "%s", val);
if (dut->ap_lci == 0)
ath_set_lci_config(dut, val, cmd);
}
val = get_param(cmd, "NeighAPBSSID");
if (val) {
if (dut->ap_neighap < 3) {
if (parse_mac_address(
dut, val,
dut->ap_val_neighap[dut->ap_neighap]) < 0) {
send_resp(dut, conn, SIGMA_INVALID,
"Failed to parse MAC address");
return 0;
}
dut->ap_neighap++;
if (dut->ap_lci == 1)
dut->ap_scan = 1;
}
}
val = get_param(cmd, "OpChannel");
if (val) {
if (dut->ap_opchannel < 3) {
dut->ap_val_opchannel[dut->ap_opchannel] = atoi(val);
dut->ap_opchannel++;
}
}
val = get_param(cmd, "URI-FQDNdescriptor");
if (val) {
if (strcasecmp(val, "HELD") == 0) {
dut->ap_fqdn_held = 1;
} else if (strcasecmp(val, "SUPL") == 0) {
dut->ap_fqdn_supl = 1;
} else {
send_resp(dut, conn, SIGMA_INVALID,
"errorCode,Unsupported URI-FQDNdescriptor");
return 0;
}
}
val = get_param(cmd, "Reg_Domain");
if (val) {
if (strcasecmp(val, "Local") == 0) {
dut->ap_reg_domain = REG_DOMAIN_LOCAL;
} else if (strcasecmp(val, "Global") == 0) {
dut->ap_reg_domain = REG_DOMAIN_GLOBAL;
} else {
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Wrong value for Reg_Domain");
return 0;
}
}
val = get_param(cmd, "NAME");
if (val) {
if (strcasecmp(val, "ap1mbo") == 0)
dut->ap_name = 1;
else if (strcasecmp(val, "ap2mbo") == 0)
dut->ap_name = 2;
else
dut->ap_name = 0;
}
val = get_param(cmd, "FT_OA");
if (val) {
if (strcasecmp(val, "Enable") == 0) {
dut->ap_ft_oa = 1;
} else if (strcasecmp(val, "Disable") == 0) {
dut->ap_ft_oa = 0;
} else {
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Wrong value for FT_OA");
return 0;
}
}
val = get_param(cmd, "Cellular_Cap_Pref");
if (val)
dut->ap_cell_cap_pref = atoi(val);
val = get_param(cmd, "DOMAIN");
if (val) {
if (strlen(val) >= sizeof(dut->ap_mobility_domain)) {
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Too long DOMAIN");
return 0;
}
snprintf(dut->ap_mobility_domain,
sizeof(dut->ap_mobility_domain), "%s", val);
}
val = get_param(cmd, "ft_bss_list");
if (val) {
char *mac_str;
int i;
char *saveptr;
char *mac_list_str;
mac_list_str = strdup(val);
if (!mac_list_str)
return -1;
mac_str = strtok_r(mac_list_str, " ", &saveptr);
for (i = 0; mac_str && i < MAX_FT_BSS_LIST; i++) {
if (parse_mac_address(dut, mac_str,
dut->ft_bss_mac_list[i]) < 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"MAC Address not in proper format");
break;
}
dut->ft_bss_mac_cnt++;
mac_str = strtok_r(NULL, " ", &saveptr);
}
sigma_dut_print(dut, DUT_MSG_DEBUG,
"Storing the following FT BSS MAC List");
for (i = 0; i < dut->ft_bss_mac_cnt; i++) {
sigma_dut_print(dut, DUT_MSG_DEBUG,
"MAC[%d] %02x:%02x:%02x:%02x:%02x:%02x",
i,
dut->ft_bss_mac_list[i][0],
dut->ft_bss_mac_list[i][1],
dut->ft_bss_mac_list[i][2],
dut->ft_bss_mac_list[i][3],
dut->ft_bss_mac_list[i][4],
dut->ft_bss_mac_list[i][5]);
}
free(mac_list_str);
}
val = get_param(cmd, "OCESupport");
if (val) {
if (strcasecmp(val, "enable") == 0) {
dut->ap_oce = VALUE_ENABLED;
} else if (strcasecmp(val, "disable") == 0) {
dut->ap_oce = VALUE_DISABLED;
dut->ap_filsdscv = VALUE_DISABLED;
} else {
send_resp(dut, conn, SIGMA_INVALID,
"errorCode,Unsupported OCE");
return 0;
}
}
val = get_param(cmd, "FILSDscvInterval");
if (val)
dut->ap_fils_dscv_int = atoi(val);
val = get_param(cmd, "BroadcastSSID");
if (val) {
if (strcasecmp(val, "enable") == 0) {
dut->ap_broadcast_ssid = VALUE_ENABLED;
} else if (strcasecmp(val, "disable") == 0) {
dut->ap_broadcast_ssid = VALUE_DISABLED;
} else {
send_resp(dut, conn, SIGMA_INVALID,
"errorCode,Unsupported hidden SSID");
return 0;
}
}
val = get_param(cmd, "FILSDscv");
if (val) {
if (strcasecmp(val, "enable") == 0) {
dut->ap_filsdscv = VALUE_ENABLED;
} else if (strcasecmp(val, "disable") == 0) {
dut->ap_filsdscv = VALUE_DISABLED;
} else {
send_resp(dut, conn, SIGMA_INVALID,
"errorCode,Unsupported FILSDscv");
return 0;
}
}
val = get_param(cmd, "FILSHLP");
if (val) {
if (strcasecmp(val, "enable") == 0) {
dut->ap_filshlp = VALUE_ENABLED;
} else if (strcasecmp(val, "disable") == 0) {
dut->ap_filshlp = VALUE_DISABLED;
} else {
send_resp(dut, conn, SIGMA_INVALID,
"errorCode,Unsupported FILSHLP");
return 0;
}
}
val = get_param(cmd, "NAIRealm");
if (val) {
dut->ap_nairealm_int = 1;
if (strlen(val) > sizeof(dut->ap_nairealm) - 1)
return -1;
snprintf(dut->ap_nairealm, sizeof(dut->ap_nairealm), "%s", val);
}
val = get_param(cmd, "DeauthDisassocTx");
if (val) {
if (strcasecmp(val, "disable") == 0) {
deauth_disassoc(dut, ifname, val);
} else {
send_resp(dut, conn, SIGMA_INVALID,
"errorCode,Unsupported DeauthDisassocTx");
return 0;
}
}
val = get_param(cmd, "RNR");
if (val) {
if (strcasecmp(val, "enable") == 0) {
dut->ap_rnr = VALUE_ENABLED;
} else if (strcasecmp(val, "disable") == 0) {
dut->ap_rnr = VALUE_DISABLED;
} else {
send_resp(dut, conn, SIGMA_INVALID,
"errorCode,Unsupported RNR");
return 0;
}
}
val = get_param(cmd, "BLEChannelUtil");
if (val)
dut->ap_blechanutil = atoi(val);
val = get_param(cmd, "BLEAvailAdminCap");
if (val)
dut->ap_ble_admit_cap = atoi(val);
val = get_param(cmd, "DataPPDUDuration");
if (val)
dut->ap_datappdudura = atoi(val);
val = get_param(cmd, "AirTimeFract");
if (val)
dut->ap_airtimefract = atoi(val);
val = get_param(cmd, "dhcpServIPADDR");
if (val) {
if (strlen(val) > sizeof(dut->ap_dhcpserv_ipaddr) - 1)
return -1;
snprintf(dut->ap_dhcpserv_ipaddr,
sizeof(dut->ap_dhcpserv_ipaddr), "%s", val);
dut->ap_dhcp_stop = 1;
}
val = get_param(cmd, "ESP_IE");
if (val) {
if (strcasecmp(val, "enable") == 0) {
dut->ap_esp = VALUE_ENABLED;
} else if (strcasecmp(val, "disable") == 0) {
dut->ap_esp = VALUE_DISABLED;
} else {
send_resp(dut, conn, SIGMA_INVALID,
"errorCode,Unsupported ESP_IE");
return 0;
}
}
val = get_param(cmd, "BAWinSize");
if (val)
dut->ap_bawinsize = atoi(val);
val = get_param(cmd, "BLEStaCount");
if (val)
dut->ap_blestacnt = atoi(val);
val = get_param(cmd, "PPDUTxType");
if (val) {
if (strcasecmp(val, "MU") == 0) {
dut->ap_he_ppdu = PPDU_MU;
} else {
send_resp(dut, conn, SIGMA_INVALID,
"errorCode,Unsupported PPDUTxType");
return 0;
}
}
val = get_param(cmd, "WscIEFragment");
if (val && strcasecmp(val, "enable") == 0) {
sigma_dut_print(dut, DUT_MSG_DEBUG,
"Enable WSC IE fragmentation");
dut->wsc_fragment = 1;
}
val = get_param(cmd, "WpsVersion");
if (val)
dut->wps_forced_version = get_wps_forced_version(dut, val);
val = get_param(cmd, "WscEAPFragment");
if (val && strcasecmp(val, "enable") == 0)
dut->eap_fragment = 1;
val = get_param(cmd, "MSDUSize");
if (val) {
int mtu;
dut->amsdu_size = atoi(val);
if (dut->amsdu_size > IEEE80211_MAX_DATA_LEN_DMG ||
dut->amsdu_size < IEEE80211_SNAP_LEN_DMG) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"MSDUSize %d is above max %d or below min %d",
dut->amsdu_size,
IEEE80211_MAX_DATA_LEN_DMG,
IEEE80211_SNAP_LEN_DMG);
dut->amsdu_size = 0;
return ERROR_SEND_STATUS;
}
mtu = dut->amsdu_size - IEEE80211_SNAP_LEN_DMG;
sigma_dut_print(dut, DUT_MSG_DEBUG,
"Setting amsdu_size to %d", mtu);
snprintf(buf, sizeof(buf), "ifconfig %s mtu %d",
get_station_ifname(), mtu);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
buf);
return ERROR_SEND_STATUS;
}
}
val = get_param(cmd, "BAckRcvBuf");
if (val) {
dut->back_rcv_buf = atoi(val);
if (dut->back_rcv_buf == 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Failed to convert %s or value is 0",
val);
return ERROR_SEND_STATUS;
}
sigma_dut_print(dut, DUT_MSG_DEBUG,
"Setting BAckRcvBuf to %s", val);
}
val = get_param(cmd, "ExtSchIE");
if (val && !strcasecmp(val, "Enable")) {
int num_allocs = MAX_ESE_ALLOCS;
if (sta_extract_60g_ese(dut, cmd, dut->ap_ese_allocs,
&num_allocs)) {
send_resp(dut, conn, SIGMA_INVALID,
"errorCode,Invalid ExtSchIE");
return 0;
}
dut->ap_num_ese_allocs = num_allocs;
}
if (is_60g_sigma_dut(dut)) {
unsigned int abft_len = 1; /* default is one slot */
val = get_param(cmd, "ABFTLRang");
if (val) {
sigma_dut_print(dut, DUT_MSG_DEBUG,
"ABFTLRang parameter %s", val);
if (strcasecmp(val, "Gt1") == 0)
abft_len = 2; /* 2 slots in this case */
}
if (sta_set_60g_abft_len(dut, conn, abft_len)) {
send_resp(dut, conn, SIGMA_ERROR,
"ErrorCode,Can't set ABFT length");
return STATUS_SENT;
}
}
return 1;
}
static void ath_inject_frame(struct sigma_dut *dut, const char *ifname, int tid)
{
char buf[256];
int tid_to_dscp[] = { 0x00, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0 };
if (tid < 0 ||
tid >= (int) (sizeof(tid_to_dscp) / sizeof(tid_to_dscp[0]))) {
sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported TID: %d", tid);
return;
}
snprintf(buf, sizeof(buf),
"wlanconfig %s list sta | grep : | cut -b 1-17 > %s",
ifname, VI_QOS_TMP_FILE);
if (system(buf) != 0)
return;
snprintf(buf, sizeof(buf),
"ifconfig %s | grep HWaddr | cut -b 39-56 >> %s",
ifname, VI_QOS_TMP_FILE);
if (system(buf) != 0)
sigma_dut_print(dut, DUT_MSG_ERROR, "Retrieve HWaddr failed");
snprintf(buf, sizeof(buf), "sed -n '3,$p' %s >> %s",
VI_QOS_REFFILE, VI_QOS_TMP_FILE);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Output redirection to VI_QOS_TMP_FILE failed");
}
snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Append TID to VI_QOS_FILE failed ");
}
snprintf(buf, sizeof(buf), "ethinject %s %s", ifname, VI_QOS_FILE);
if (system(buf) != 0)
sigma_dut_print(dut, DUT_MSG_ERROR, "Ethinject frame failed");
}
static int ath_ap_send_addba_req(struct sigma_dut *dut, struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
const char *val;
char *ifname;
char buf[256];
int tid = 0;
ifname = get_main_ifname();
val = get_param(cmd, "TID");
if (val) {
tid = atoi(val);
if (tid)
ath_inject_frame(dut, ifname, tid);
}
/* NOTE: This is the command sequence on Peregrine for ADDBA */
snprintf(buf, sizeof(buf), "iwpriv %s setaddbaoper 1", ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"iwpriv setaddbaoper failed");
}
snprintf(buf, sizeof(buf), "wifitool %s senddelba 1 %d 1 4",
ifname, tid);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"wifitool senddelba failed");
}
snprintf(buf, sizeof(buf), "wifitool %s sendaddba 1 %d 64",
ifname, tid);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"wifitool sendaddba failed");
}
return 1;
}
static int ath10k_debug_enable_addba_req(struct sigma_dut *dut, int tid,
const char *sta_mac,
const char *dir_path)
{
DIR *dir;
struct dirent *entry;
char buf[128], path[128];
int ret = 0;
dir = opendir(dir_path);
if (!dir)
return 0;
while ((entry = readdir(dir))) {
ret = 1;
if (strcmp(entry->d_name, ".") == 0 ||
strcmp(entry->d_name, "..") == 0)
continue;
snprintf(path, sizeof(path) - 1, "%s/%s",
dir_path, entry->d_name);
path[sizeof(path) - 1] = 0;
if (strcmp(entry->d_name, sta_mac) == 0) {
snprintf(buf, sizeof(buf), "echo 1 > %s/aggr_mode",
path);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Failed to set aggr mode for ath10k");
}
snprintf(buf, sizeof(buf), "echo %d 32 > %s/addba",
tid, path);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Failed to set addbareq for ath10k");
}
break;
}
/* Recursively search subdirectories */
ath10k_debug_enable_addba_req(dut, tid, sta_mac, path);
}
closedir(dir);
return ret;
}
static int ath10k_ap_send_addba_req(struct sigma_dut *dut,
struct sigma_cmd *cmd)
{
const char *val;
int tid = 0;
val = get_param(cmd, "TID");
if (val)
tid = atoi(val);
val = get_param(cmd, "sta_mac_address");
if (!val) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Failed to parse station MAC address");
return 0;
}
return ath10k_debug_enable_addba_req(dut, tid, val,
"/sys/kernel/debug/ieee80211");
}
static int cmd_ap_send_addba_req(struct sigma_dut *dut, struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
/* const char *name = get_param(cmd, "NAME"); */
/* const char *ifname = get_param(cmd, "INTERFACE"); */
struct stat s;
switch (get_driver_type()) {
case DRIVER_ATHEROS:
return ath_ap_send_addba_req(dut, conn, cmd);
#ifdef __linux__
case DRIVER_WIL6210:
return send_addba_60g(dut, conn, cmd, "sta_mac_address");
#endif /* __linux__ */
case DRIVER_OPENWRT:
switch (get_openwrt_driver_type()) {
case OPENWRT_DRIVER_ATHEROS:
return ath_ap_send_addba_req(dut, conn, cmd);
default:
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,ap_send_addba_req not supported with this driver");
return 0;
}
case DRIVER_WCN:
case DRIVER_LINUX_WCN:
/* AP automatically sends ADDBA request after association. */
sigma_dut_print(dut, DUT_MSG_INFO,
"ap_send_addba_req command ignored");
return 1;
case DRIVER_MAC80211:
if (stat("/sys/module/ath10k_core", &s) == 0)
return ath10k_ap_send_addba_req(dut, cmd);
/* fall through */
default:
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,ap_send_addba_req not supported with this driver");
return 0;
}
}
static int cmd_ap_set_security(struct sigma_dut *dut, struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
/* const char *name = get_param(cmd, "NAME"); */
const char *val;
unsigned int wlan_tag = 1;
const char *security;
val = get_param(cmd, "WLAN_TAG");
if (val)
wlan_tag = atoi(val);
security = get_param(cmd, "Security");
if (wlan_tag > 1) {
val = get_param(cmd, "KEYMGNT");
if (!val)
val = get_param(cmd, "KeyMgmtType");
if (val) {
if (strcasecmp(val, "NONE") == 0) {
dut->ap_tag_key_mgmt[wlan_tag - 2] = AP2_OPEN;
} else if (strcasecmp(val, "OSEN") == 0 &&
wlan_tag == 2) {
/*
* OSEN only supported on WLAN_TAG = 2 for now
*/
dut->ap_tag_key_mgmt[wlan_tag - 2] = AP2_OSEN;
} else if (strcasecmp(val, "WPA2-PSK") == 0 ||
(security &&
strcasecmp(security, "PSK") == 0 &&
strcasecmp(val, "WPA2") == 0)) {
dut->ap_tag_key_mgmt[wlan_tag - 2] =
AP2_WPA2_PSK;
} else if (strcasecmp(val, "OWE") == 0 &&
wlan_tag == 2) {
dut->ap_tag_key_mgmt[wlan_tag - 2] =
AP2_WPA2_OWE;
} else {
send_resp(dut, conn, SIGMA_INVALID,
"errorCode,Unsupported KEYMGNT");
return 0;
}
return 1;
}
}
val = get_param(cmd, "KEYMGNT");
if (!val)
val = get_param(cmd,"KeyMgmtType");
if (val) {
if (strcasecmp(val, "WPA2-PSK") == 0 ||
(security && strcasecmp(security, "PSK") == 0 &&
strcasecmp(val, "WPA2") == 0)) {
dut->ap_key_mgmt = AP_WPA2_PSK;
dut->ap_cipher = AP_CCMP;
} else if (strcasecmp(val, "WPA2-EAP") == 0 ||
strcasecmp(val, "WPA2-Ent") == 0) {
dut->ap_key_mgmt = AP_WPA2_EAP;
dut->ap_cipher = AP_CCMP;
} else if (strcasecmp(val, "SuiteB") == 0) {
dut->ap_key_mgmt = AP_SUITEB;
dut->ap_cipher = AP_GCMP_256;
dut->ap_pmf = AP_PMF_REQUIRED;
} else if (strcasecmp(val, "WPA-PSK") == 0) {
dut->ap_key_mgmt = AP_WPA_PSK;
dut->ap_cipher = AP_TKIP;
} else if (strcasecmp(val, "WPA-EAP") == 0 ||
strcasecmp(val, "WPA-Ent") == 0) {
dut->ap_key_mgmt = AP_WPA_EAP;
dut->ap_cipher = AP_TKIP;
} else if (strcasecmp(val, "WPA2-Mixed") == 0) {
dut->ap_key_mgmt = AP_WPA2_EAP_MIXED;
dut->ap_cipher = AP_CCMP_TKIP;
} else if (strcasecmp(val, "WPA2-PSK-Mixed") == 0) {
dut->ap_key_mgmt = AP_WPA2_PSK_MIXED;
dut->ap_cipher = AP_CCMP_TKIP;
} else if (strcasecmp(val, "WPA2-SAE") == 0 ||
strcasecmp(val, "SAE") == 0) {
dut->ap_key_mgmt = AP_WPA2_SAE;
dut->ap_cipher = AP_CCMP;
dut->ap_pmf = AP_PMF_REQUIRED;
} else if (strcasecmp(val, "WPA2-PSK-SAE") == 0) {
dut->ap_key_mgmt = AP_WPA2_PSK_SAE;
dut->ap_cipher = AP_CCMP;
dut->ap_pmf = AP_PMF_OPTIONAL;
} else if (strcasecmp(val, "OWE") == 0) {
dut->ap_key_mgmt = AP_WPA2_OWE;
dut->ap_cipher = AP_CCMP;
dut->ap_pmf = AP_PMF_REQUIRED;
} else if (strcasecmp(val, "WPA2-ENT-OSEN") == 0) {
dut->ap_key_mgmt = AP_WPA2_EAP_OSEN;
dut->ap_cipher = AP_CCMP;
dut->ap_pmf = AP_PMF_OPTIONAL;
} else if (strcasecmp(val, "OSEN") == 0) {
dut->ap_key_mgmt = AP_OSEN;
dut->ap_cipher = AP_CCMP;
} else if (strcasecmp(val, "FT-EAP") == 0) {
dut->ap_key_mgmt = AP_WPA2_FT_EAP;
dut->ap_cipher = AP_CCMP;
dut->ap_pmf = AP_PMF_OPTIONAL;
} else if (strcasecmp(val, "FT-PSK") == 0) {
dut->ap_key_mgmt = AP_WPA2_FT_PSK;
dut->ap_cipher = AP_CCMP;
dut->ap_pmf = AP_PMF_OPTIONAL;
} else if (strcasecmp(val, "WPA2-ENT-256") == 0) {
dut->ap_key_mgmt = AP_WPA2_EAP_SHA256;
dut->ap_cipher = AP_CCMP;
dut->ap_pmf = AP_PMF_OPTIONAL;
} else if (strcasecmp(val, "WPA2-PSK-256") == 0) {
dut->ap_key_mgmt = AP_WPA2_PSK_SHA256;
dut->ap_cipher = AP_CCMP;
dut->ap_pmf = AP_PMF_OPTIONAL;
} else if (strcasecmp(val, "WPA2-ENT-FT-EAP") == 0) {
dut->ap_key_mgmt = AP_WPA2_ENT_FT_EAP;
dut->ap_cipher = AP_CCMP;
dut->ap_pmf = AP_PMF_OPTIONAL;
} else if (strcasecmp(val, "NONE") == 0) {
dut->ap_key_mgmt = AP_OPEN;
dut->ap_cipher = AP_PLAIN;
} else {
send_resp(dut, conn, SIGMA_INVALID,
"errorCode,Unsupported KEYMGNT");
return 0;
}
}
val = get_param(cmd, "ECGroupID");
if (val) {
free(dut->ap_sae_groups);
dut->ap_sae_groups = strdup(val);
}
val = get_param(cmd, "AntiCloggingThreshold");
if (val)
dut->sae_anti_clogging_threshold = atoi(val);
val = get_param(cmd, "Reflection");
if (val)
dut->sae_reflection = strcasecmp(val, "SAE") == 0;
val = get_param(cmd, "InvalidSAEElement");
if (val) {
free(dut->sae_commit_override);
dut->sae_commit_override = strdup(val);
}
val = get_param(cmd, "SAEPasswords");
if (val) {
free(dut->ap_sae_passwords);
dut->ap_sae_passwords = strdup(val);
}
val = get_param(cmd, "ENCRYPT");
if (!val)
val = get_param(cmd, "EncpType");
if (val) {
if (strcasecmp(val, "WEP") == 0) {
dut->ap_cipher = AP_WEP;
} else if (strcasecmp(val, "TKIP") == 0) {
dut->ap_cipher = AP_TKIP;
} else if (strcasecmp(val, "AES") == 0 ||
strcasecmp(val, "AES-CCMP") == 0) {
dut->ap_cipher = AP_CCMP;
} else if (strcasecmp(val, "AES-GCMP") == 0) {
dut->ap_cipher = AP_GCMP_128;
} else {
send_resp(dut, conn, SIGMA_INVALID,
"errorCode,Unsupported ENCRYPT");
return 0;
}
}
val = get_param(cmd, "PairwiseCipher");
if (val) {
if (strcasecmp(val, "AES-GCMP-256") == 0) {
dut->ap_cipher = AP_GCMP_256;
} else if (strcasecmp(val, "AES-CCMP-256") == 0) {
dut->ap_cipher = AP_CCMP_256;
} else if (strcasecmp(val, "AES-GCMP-128") == 0) {
dut->ap_cipher = AP_GCMP_128;
} else if (strcasecmp(val, "AES-CCMP-128") == 0) {
dut->ap_cipher = AP_CCMP;
} else if (strcasecmp(val, "AES-CCMP-128 AES-GCMP-256") == 0 ||
strcasecmp(val, "AES-GCMP-256 AES-CCMP-128") == 0) {
dut->ap_cipher = AP_CCMP_128_GCMP_256;
} else {
send_resp(dut, conn, SIGMA_INVALID,
"errorCode,Unsupported PairwiseCipher");
return 0;
}
}
val = get_param(cmd, "GroupCipher");
if (val) {
if (strcasecmp(val, "AES-GCMP-256") == 0) {
dut->ap_group_cipher = AP_GCMP_256;
} else if (strcasecmp(val, "AES-CCMP-256") == 0) {
dut->ap_group_cipher = AP_CCMP_256;
} else if (strcasecmp(val, "AES-GCMP-128") == 0) {
dut->ap_group_cipher = AP_GCMP_128;
} else if (strcasecmp(val, "AES-CCMP-128") == 0) {
dut->ap_group_cipher = AP_CCMP;
} else {
send_resp(dut, conn, SIGMA_INVALID,
"errorCode,Unsupported GroupCipher");
return 0;
}
}
val = get_param(cmd, "GroupMgntCipher");
if (val) {
if (strcasecmp(val, "BIP-GMAC-256") == 0) {
dut->ap_group_mgmt_cipher = AP_BIP_GMAC_256;
} else if (strcasecmp(val, "BIP-CMAC-256") == 0) {
dut->ap_group_mgmt_cipher = AP_BIP_CMAC_256;
} else if (strcasecmp(val, "BIP-GMAC-128") == 0) {
dut->ap_group_mgmt_cipher = AP_BIP_GMAC_128;
} else if (strcasecmp(val, "BIP-CMAC-128") == 0) {
dut->ap_group_mgmt_cipher = AP_BIP_CMAC_128;
} else {
send_resp(dut, conn, SIGMA_INVALID,
"errorCode,Unsupported GroupMgntCipher");
return 0;
}
}
val = get_param(cmd, "WEPKEY");
if (val) {
size_t len;
if (dut->ap_cipher != AP_WEP) {
send_resp(dut, conn, SIGMA_INVALID,
"errorCode,Unexpected WEPKEY without WEP "
"configuration");
return 0;
}
len = strlen(val);
if (len != 10 && len != 26) {
send_resp(dut, conn, SIGMA_INVALID,
"errorCode,Unexpected WEPKEY length");
return 0;
}
snprintf(dut->ap_wepkey, sizeof(dut->ap_wepkey), "%s", val);
}
val = get_param(cmd, "PSK");
if (!val)
val = get_param(cmd, "passphrase");
if (val) {
if (dut->ap_key_mgmt != AP_WPA2_SAE &&
(dut->ap_akm_values & (AKM_WPA_PSK | AKM_SAE)) !=
AKM_SAE &&
strlen(val) > 64) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Too long PSK/passphtase");
return -1;
}
if (strlen(val) > sizeof(dut->ap_passphrase) - 1)
return -1;
snprintf(dut->ap_passphrase, sizeof(dut->ap_passphrase),
"%s", val);
}
val = get_param(cmd, "PSKHEX");
if (val) {
if (strlen(val) != 64)
return -1;
strlcpy(dut->ap_psk, val, sizeof(dut->ap_psk));
}
if (dut->program == PROGRAM_OCE && dut->dev_role == DEVROLE_STA_CFON)
dut->ap_pmf = AP_PMF_OPTIONAL;
val = get_param(cmd, "PMF");
if (val) {
if (strcasecmp(val, "Disabled") == 0) {
dut->ap_pmf = AP_PMF_DISABLED;
} else if (strcasecmp(val, "Optional") == 0) {
dut->ap_pmf = AP_PMF_OPTIONAL;
} else if (strcasecmp(val, "Required") == 0) {
dut->ap_pmf = AP_PMF_REQUIRED;
} else {
send_resp(dut, conn, SIGMA_INVALID,
"errorCode,Unsupported PMF");
return 0;
}
}
dut->ap_add_sha256 = 0;
val = get_param(cmd, "SHA256AD");
if (val == NULL)
val = get_param(cmd, "SHA256");
if (val) {
if (strcasecmp(val, "Disabled") == 0) {
} else if (strcasecmp(val, "Enabled") == 0) {
dut->ap_add_sha256 = 1;
} else {
send_resp(dut, conn, SIGMA_INVALID,
"errorCode,Unsupported SHA256");
return 0;
}
}
val = get_param(cmd, "PreAuthentication");
if (val) {
if (strcasecmp(val, "disabled") == 0) {
dut->ap_rsn_preauth = 0;
} else if (strcasecmp(val, "enabled") == 0) {
dut->ap_rsn_preauth = 1;
} else {
send_resp(dut, conn, SIGMA_INVALID,
"errorCode,Unsupported PreAuthentication value");
return 0;
}
}
val = get_param(cmd, "AKMSuiteType");
if (val) {
const char *in_pos = val;
dut->ap_akm_values = 0;
while (*in_pos) {
int akm = atoi(in_pos);
if (akm < 0 || akm >= 32) {
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Unsupported AKMSuiteType value");
return STATUS_SENT;
}
dut->ap_akm_values |= 1 << akm;
in_pos = strchr(in_pos, ';');
if (!in_pos)
break;
while (*in_pos == ';')
in_pos++;
}
dut->ap_akm = 1;
if (dut->ap_akm_values & (1 << 14))
dut->ap_add_sha384 = 1;
if (dut->ap_akm_values & (1 << 15))
dut->ap_add_sha384 = 1;
}
if (dut->ap_key_mgmt == AP_OPEN && !dut->ap_akm_values) {
dut->ap_hs2 = 0;
dut->ap_pmf = AP_PMF_DISABLED;
}
val = get_param(cmd, "PMKSACaching");
if (val) {
dut->ap_pmksa = 1;
if (strcasecmp(val, "disabled") == 0) {
dut->ap_pmksa_caching = 1;
} else if (strcasecmp(val, "enabled") == 0) {
dut->ap_pmksa_caching = 0;
} else {
send_resp(dut, conn, SIGMA_INVALID,
"errorCode,Unsupported PMKSACaching value");
return 0;
}
}
return 1;
}
int sta_cfon_set_wireless(struct sigma_dut *dut, struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
int status;
status = cmd_ap_set_wireless(dut, conn, cmd);
if (status != 1)
return status;
status = cmd_ap_set_security(dut, conn, cmd);
if (status != 1)
return status;
return cmd_ap_config_commit(dut, conn, cmd);
}
static int cmd_ap_set_radius(struct sigma_dut *dut, struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
/* const char *name = get_param(cmd, "NAME"); */
const char *val;
unsigned int wlan_tag = 1, radius_port = 0;
char *radius_ipaddr = NULL, *radius_password = NULL;
val = get_param(cmd, "WLAN_TAG");
if (val) {
wlan_tag = atoi(val);
if (wlan_tag != 1 && wlan_tag != 2) {
send_resp(dut, conn, SIGMA_INVALID,
"errorCode,Invalid WLAN_TAG");
return 0;
}
}
val = get_param(cmd, "PORT");
if (val)
radius_port = atoi(val);
if (wlan_tag == 1) {
if (radius_port)
dut->ap_radius_port = radius_port;
radius_ipaddr = dut->ap_radius_ipaddr;
radius_password = dut->ap_radius_password;
} else if (wlan_tag == 2) {
if (radius_port)
dut->ap2_radius_port = radius_port;
radius_ipaddr = dut->ap2_radius_ipaddr;
radius_password = dut->ap2_radius_password;
}
val = get_param(cmd, "IPADDR");
if (val) {
if (strlen(val) > sizeof(dut->ap_radius_ipaddr) - 1)
return -1;
snprintf(radius_ipaddr, sizeof(dut->ap_radius_ipaddr),
"%s", val);
}
val = get_param(cmd, "PASSWORD");
if (val) {
if (strlen(val) > sizeof(dut->ap_radius_password) - 1)
return -1;
snprintf(radius_password,
sizeof(dut->ap_radius_password), "%s", val);
}
return 1;
}
static void owrt_ap_set_radio(struct sigma_dut *dut, int id,
const char *key, const char *val)
{
char buf[100];
if (val == NULL) {
snprintf(buf, sizeof(buf),
"uci delete wireless.wifi%d.%s", id, key);
run_system(dut, buf);
return;
}
snprintf(buf, sizeof(buf), "uci set wireless.wifi%d.%s=%s",
id, key, val);
run_system(dut, buf);
}
static void owrt_ap_set_list_radio(struct sigma_dut *dut, int id,
const char *key, const char *val)
{
char buf[256];
if (val == NULL) {
snprintf(buf, sizeof(buf),
"uci del_list wireless.wifi%d.%s", id, key);
run_system(dut, buf);
return;
}
snprintf(buf, sizeof(buf), "uci add_list wireless.wifi%d.%s=%s",
id, key, val);
run_system(dut, buf);
}
static void owrt_ap_set_vap(struct sigma_dut *dut, int id, const char *key,
const char *val)
{
char buf[256];
if (val == NULL) {
snprintf(buf, sizeof(buf),
"uci delete wireless.@wifi-iface[%d].%s", id, key);
run_system(dut, buf);
return;
}
snprintf(buf, sizeof(buf), "uci set wireless.@wifi-iface[%d].%s=%s",
id, key, val);
run_system(dut, buf);
}
static void owrt_ap_set_list_vap(struct sigma_dut *dut, int id,
const char *key, const char *val)
{
char buf[1024];
if (val == NULL) {
snprintf(buf, sizeof(buf),
"uci del_list wireless.@wifi-iface[%d].%s", id, key);
run_system(dut, buf);
return;
}
snprintf(buf, sizeof(buf),
"uci add_list wireless.@wifi-iface[%d].%s=%s",
id, key, val);
run_system(dut, buf);
}
static void owrt_ap_add_vap(struct sigma_dut *dut, int id, const char *key,
const char *val)
{
char buf[256];
if (val == NULL) {
snprintf(buf, sizeof(buf),
"uci delete wireless.@wifi-iface[%d].%s", id, key);
run_system(dut, buf);
return;
}
snprintf(buf, sizeof(buf), "uci add wireless wifi-iface");
run_system(dut, buf);
snprintf(buf, sizeof(buf), "uci set wireless.@wifi-iface[%d].%s=%s",
id, key, val);
run_system(dut, buf);
snprintf(buf, sizeof(buf), "uci set wireless.@wifi-iface[%d].%s=%s",
id, "network", "lan");
run_system(dut, buf);
snprintf(buf, sizeof(buf), "uci set wireless.@wifi-iface[%d].%s=%s",
id, "mode", "ap");
run_system(dut, buf);
snprintf(buf, sizeof(buf), "uci set wireless.@wifi-iface[%d].%s=%s",
id, "encryption", "none");
run_system(dut, buf);
}
#define OPENWRT_MAX_NUM_RADIOS (MAX_RADIO + 1)
static void owrt_ap_config_radio(struct sigma_dut *dut)
{
int radio_id[MAX_RADIO] = { 0, 1, 2 };
int radio_count, radio_no;
char buf[64];
for (radio_count = 0; radio_count < OPENWRT_MAX_NUM_RADIOS;
radio_count++) {
snprintf(buf, sizeof(buf), "%s%d", "wifi", radio_count);
for (radio_no = 0; radio_no < MAX_RADIO; radio_no++) {
if (!sigma_radio_ifname[radio_no] ||
strcmp(sigma_radio_ifname[radio_no], buf) != 0)
continue;
owrt_ap_set_radio(dut, radio_count, "disabled", "0");
owrt_ap_set_vap(dut, radio_count, "device", buf);
radio_id[radio_no] = radio_count;
}
}
/* Hardware mode (11a/b/g/n/ac) & HT mode selection */
switch (dut->ap_mode) {
case AP_11g:
owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11g");
break;
case AP_11b:
owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11b");
break;
case AP_11ng:
owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11ng");
owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT20");
break;
case AP_11a:
owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11a");
break;
case AP_11na:
owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11na");
owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT20");
break;
case AP_11ac:
owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11ac");
owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT80");
break;
case AP_inval:
sigma_dut_print(dut, DUT_MSG_ERROR,
"MODE NOT SPECIFIED!");
return;
default:
owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11ng");
owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT20");
break;
}
if (dut->ap_is_dual) {
/* Hardware mode (11a/b/g/n/ac) & HT mode selection */
switch (dut->ap_mode_1) {
case AP_11g:
owrt_ap_set_radio(dut, radio_id[1], "hwmode", "11g");
break;
case AP_11b:
owrt_ap_set_radio(dut, radio_id[1], "hwmode", "11b");
break;
case AP_11ng:
owrt_ap_set_radio(dut, radio_id[1], "hwmode", "11ng");
owrt_ap_set_radio(dut, radio_id[1], "htmode", "HT20");
break;
case AP_11a:
owrt_ap_set_radio(dut, radio_id[1], "hwmode", "11a");
break;
case AP_11na:
owrt_ap_set_radio(dut, radio_id[1], "hwmode", "11na");
owrt_ap_set_radio(dut, radio_id[1], "htmode", "HT20");
break;
case AP_11ac:
owrt_ap_set_radio(dut, radio_id[1], "hwmode", "11ac");
owrt_ap_set_radio(dut, radio_id[1], "htmode", "HT80");
break;
case AP_inval:
sigma_dut_print(dut, DUT_MSG_ERROR,
"MODE NOT SPECIFIED!");
return;
default:
owrt_ap_set_radio(dut, radio_id[1], "hwmode", "11ng");
owrt_ap_set_radio(dut, radio_id[1], "htmode", "HT20");
break;
}
}
/* Channel */
snprintf(buf, sizeof(buf), "%d", dut->ap_channel);
owrt_ap_set_radio(dut, radio_id[0], "channel", buf);
switch (dut->ap_chwidth) {
case AP_20:
owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT20");
break;
case AP_40:
owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT40");
break;
case AP_80:
owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT80");
break;
case AP_160:
owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT160");
break;
case AP_80_80:
owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT80_80");
break;
case AP_AUTO:
default:
break;
}
if (dut->ap_channel == 140 || dut->ap_channel == 144) {
if (get_openwrt_driver_type() == OPENWRT_DRIVER_ATHEROS)
owrt_ap_set_radio(dut, radio_id[0], "set_ch_144", "3");
}
if (dut->ap_is_dual) {
snprintf(buf, sizeof(buf), "%d", dut->ap_channel_1);
owrt_ap_set_radio(dut, radio_id[1], "channel", buf);
}
/* Country Code */
if (dut->ap_reg_domain == REG_DOMAIN_GLOBAL) {
const char *country;
country = dut->ap_countrycode[0] ? dut->ap_countrycode : "US";
snprintf(buf, sizeof(buf), "%s4", country);
owrt_ap_set_radio(dut, radio_id[0], "country", buf);
if (dut->ap_is_dual)
owrt_ap_set_radio(dut, radio_id[1], "country", buf);
} else if (dut->ap_countrycode[0]) {
owrt_ap_set_radio(dut, radio_id[0], "country",
dut->ap_countrycode);
}
if (dut->ap_disable_protection == 1) {
owrt_ap_set_list_radio(dut, radio_id[0], "aggr_burst", "'0 0'");
owrt_ap_set_list_radio(dut, radio_id[0], "aggr_burst", "'1 0'");
owrt_ap_set_list_radio(dut, radio_id[0], "aggr_burst", "'2 0'");
owrt_ap_set_list_radio(dut, radio_id[0], "aggr_burst", "'3 0'");
}
if (dut->ap_oce == VALUE_ENABLED &&
get_driver_type() == DRIVER_OPENWRT)
owrt_ap_set_radio(dut, radio_id[0], "bcnburst", "1");
}
static int owrt_ap_config_vap_hs2(struct sigma_dut *dut, int vap_id)
{
char buf[256];
snprintf(buf, sizeof(buf), "%d", dut->ap_hs2);
owrt_ap_set_vap(dut, vap_id, "hs20", buf);
owrt_ap_set_vap(dut, vap_id, "qbssload", "1");
owrt_ap_set_vap(dut, vap_id, "hs20_deauth_req_timeout","3");
owrt_ap_set_list_vap(dut, vap_id, "hs20_oper_friendly_name",
"'eng:Wi-Fi Alliance'");
owrt_ap_set_list_vap(dut, vap_id, "hs20_oper_friendly_name",
"'chi:Wi-Fi\xe8\x81\x94\xe7\x9b\x9f'");
if (dut->ap_wan_metrics == 1)
owrt_ap_set_vap(dut, vap_id, "hs20_wan_metrics",
"'01:2500:384:0:0:10'");
else if (dut->ap_wan_metrics == 1)
owrt_ap_set_vap(dut, vap_id, "hs20_wan_metrics",
"'01:1500:384:20:20:10'");
else if (dut->ap_wan_metrics == 2)
owrt_ap_set_vap(dut, vap_id, "hs20_wan_metrics",
"'01:1500:384:20:20:10'");
else if (dut->ap_wan_metrics == 3)
owrt_ap_set_vap(dut, vap_id, "hs20_wan_metrics",
"'01:2000:1000:20:20:10'");
else if (dut->ap_wan_metrics == 4)
owrt_ap_set_vap(dut, vap_id, "hs20_wan_metrics",
"'01:8000:1000:20:20:10'");
else if (dut->ap_wan_metrics == 5)
owrt_ap_set_vap(dut, vap_id, "hs20_wan_metrics",
"'01:9000:5000:20:20:10'");
if (dut->ap_conn_capab == 1) {
owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab", "'1:0:0'");
owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
"'6:20:1'");
owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
"'6:22:0'");
owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
"'6:80:1'");
owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
"'6:443:1'");
owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
"'6:1723:0'");
owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
"'6:5060:0'");
owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
"'17:500:1'");
owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
"'17:5060:0'");
owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
"'17:4500:1'");
owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
"'50:0:1'");
} else if (dut->ap_conn_capab == 2) {
owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
"'6:80:1'");
owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
"'6:443:1'");
owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
"'17:5060:1'");
owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
"'6:5060:1'");
} else if (dut->ap_conn_capab == 3) {
owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
"'6:80:1'");
owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
"'6:443:1'");
}
if (dut->ap_oper_class == 1)
snprintf(buf, sizeof(buf), "%s", "51");
else if (dut->ap_oper_class == 2)
snprintf(buf, sizeof(buf), "%s", "73");
else if (dut->ap_oper_class == 3)
snprintf(buf, sizeof(buf), "%s", "5173");
if (dut->ap_oper_class)
owrt_ap_set_vap(dut, vap_id, "hs20_operating_class", buf);
if (dut->ap_osu_provider_list) {
char *osu_friendly_name = NULL;
char *osu_icon = NULL;
char *osu_ssid = NULL;
char *osu_nai = NULL;
char *osu_service_desc = NULL;
char *hs20_icon_filename = NULL;
char hs20_icon[150];
int osu_method;
hs20_icon_filename = "icon_red_zxx.png";
if (dut->ap_osu_icon_tag == 2)
hs20_icon_filename = "wifi-abgn-logo_270x73.png";
snprintf(hs20_icon, sizeof(hs20_icon),
"'128:61:zxx:image/png:icon_red_zxx.png:/etc/ath/%s'",
hs20_icon_filename);
osu_icon = "icon_red_zxx.png";
osu_ssid = "OSU";
osu_friendly_name = "'kor:SP 빨강 테스트 전용'";
osu_service_desc = "'kor:테스트 목적으로 무료 서비스'";
osu_method = (dut->ap_osu_method[0] == 0xFF) ? 1 :
dut->ap_osu_method[0];
if (strlen(dut->ap_osu_server_uri[0]))
owrt_ap_set_list_vap(dut, vap_id, "osu_server_uri",
dut->ap_osu_server_uri[0]);
else
owrt_ap_set_list_vap(dut, vap_id, "osu_server_uri",
"'https://osu-server.r2-testbed.wi-fi.org/'");
switch (dut->ap_osu_provider_list) {
case 1:
case 101:
owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name",
"'eng:SP Red Test Only'");
owrt_ap_set_list_vap(dut, vap_id, "osu_service_desc",
"'eng:Free service for test purpose'");
owrt_ap_set_list_vap(dut, vap_id, "hs20_icon",
hs20_icon);
hs20_icon_filename = "icon_red_eng.png";
if (dut->ap_osu_icon_tag == 2)
hs20_icon_filename = "wifi-abgn-logo_270x73.png";
snprintf(hs20_icon, sizeof(hs20_icon),
"'160:76:eng:image/png:icon_red_eng.png:/etc/ath/%s'",
hs20_icon_filename);
owrt_ap_set_list_vap(dut, vap_id, "osu_icon",
"icon_red_eng.png");
break;
case 2:
case 102:
owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name",
"'eng:Wireless Broadband Alliance'");
owrt_ap_set_list_vap(dut, vap_id, "osu_service_desc",
"'eng:Free service for test purpose'");
hs20_icon_filename = "icon_orange_zxx.png";
if (dut->ap_osu_icon_tag == 2)
hs20_icon_filename = "wifi-abgn-logo_270x73.png";
snprintf(hs20_icon, sizeof(hs20_icon),
"'128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s'",
hs20_icon_filename);
osu_icon = "icon_orange_zxx.png";
osu_friendly_name = "'kor:와이어리스 브로드밴드 얼라이언스'";
break;
case 3:
case 103:
osu_friendly_name = "'spa:SP Red Test Only'";
osu_service_desc = "'spa:Free service for test purpose'";
break;
case 4:
case 104:
owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name",
"'eng:SP Orange Test Only'");
owrt_ap_set_list_vap(dut, vap_id, "osu_service_desc",
"'eng:Free service for test purpose'");
hs20_icon_filename = "icon_orange_eng.png";
if (dut->ap_osu_icon_tag == 2)
hs20_icon_filename = "wifi-abgn-logo_270x73.png";
snprintf(hs20_icon, sizeof(hs20_icon),
"'160:76:eng:image/png:icon_orange_eng.png:/etc/ath/%s'",
hs20_icon_filename);
owrt_ap_set_list_vap(dut, vap_id, "hs20_icon",
hs20_icon);
osu_friendly_name = "'kor:SP 오렌지 테스트 전용'";
hs20_icon_filename = "icon_orange_zxx.png";
if (dut->ap_osu_icon_tag == 2)
hs20_icon_filename = "wifi-abgn-logo_270x73.png";
snprintf(hs20_icon, sizeof(hs20_icon),
"'128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s'",
hs20_icon_filename);
osu_icon = "icon_orange_zxx.png";
break;
case 5:
case 105:
owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name",
"'eng:SP Orange Test Only'");
owrt_ap_set_list_vap(dut, vap_id, "osu_service_desc",
"'eng:Free service for test purpose'");
osu_friendly_name = "'kor:SP 오렌지 테스트 전용'";
hs20_icon_filename = "icon_orange_zxx.png";
if (dut->ap_osu_icon_tag == 2)
hs20_icon_filename = "wifi-abgn-logo_270x73.png";
snprintf(hs20_icon, sizeof(hs20_icon),
"'128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s'",
hs20_icon_filename);
osu_icon = "icon_orange_zxx.png";
break;
case 6:
case 106:
owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name",
"'eng:SP Green Test Only'");
owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name",
"'kor:SP 초록 테스트 전용'");
hs20_icon_filename = "icon_green_zxx.png";
if (dut->ap_osu_icon_tag == 2)
hs20_icon_filename = "wifi-abgn-logo_270x73.png";
snprintf(hs20_icon, sizeof(hs20_icon),
"'128:61:zxx:image/png:icon_green_zxx.png:/etc/ath/%s'",
hs20_icon_filename);
owrt_ap_set_list_vap(dut, vap_id, "hs20_icon",
hs20_icon);
owrt_ap_set_list_vap(dut, vap_id, "osu_icon",
"'icon_green_zxx.png'");
osu_method = (dut->ap_osu_method[0] == 0xFF) ? 0 :
dut->ap_osu_method[0];
snprintf(buf, sizeof(buf), "%d", osu_method);
owrt_ap_set_vap(dut, vap_id, "osu_method_list", buf);
if (strlen(dut->ap_osu_server_uri[1]))
owrt_ap_set_list_vap(dut, vap_id,
"osu_server_uri",
dut->ap_osu_server_uri[1]);
else
owrt_ap_set_list_vap(dut, vap_id,
"osu_server_uri",
"'https://osu-server.r2-testbed.wi-fi.org/'");
owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name",
"'eng:SP Orange Test Only'");
hs20_icon_filename = "icon_orange_zxx.png";
if (dut->ap_osu_icon_tag == 2)
hs20_icon_filename = "wifi-abgn-logo_270x73.png";
snprintf(hs20_icon, sizeof(hs20_icon),
"'128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s'",
hs20_icon_filename);
osu_icon = "icon_orange_zxx.png";
osu_friendly_name = "'kor:SP 오렌지 테스트 전용'";
osu_method = (dut->ap_osu_method[1] == 0xFF) ? 0 :
dut->ap_osu_method[1];
osu_service_desc = NULL;
break;
case 7:
case 107:
owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name",
"'eng:SP Green Test Only'");
owrt_ap_set_list_vap(dut, vap_id, "osu_service_desc",
"'eng:Free service for test purpose'");
hs20_icon_filename = "icon_green_eng.png";
if (dut->ap_osu_icon_tag == 2)
hs20_icon_filename = "wifi-abgn-logo_270x73.png";
snprintf(hs20_icon, sizeof(hs20_icon),
"'160:76:eng:image/png:icon_green_eng.png:/etc/ath/%s'",
hs20_icon_filename);
owrt_ap_set_list_vap(dut, vap_id, "hs20_icon",
hs20_icon);
owrt_ap_set_list_vap(dut, vap_id, "osu_icon",
"'icon_green_eng.png'");
osu_friendly_name = "'kor:SP 초록 테스트 전용'";
hs20_icon_filename = "icon_green_zxx.png";
if (dut->ap_osu_icon_tag == 2)
hs20_icon_filename = "wifi-abgn-logo_270x73.png";
snprintf(hs20_icon, sizeof(hs20_icon),
"'128:61:zxx:image/png:icon_green_zxx.png:/etc/ath/%s'",
hs20_icon_filename);
osu_icon = "icon_green_zxx.png";
break;
case 8:
case 108:
owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name",
"'eng:SP Red Test Only'");
owrt_ap_set_list_vap(dut, vap_id, "osu_service_desc",
"'eng:Free service for test purpose'");
osu_ssid = "OSU-Encrypted";
osu_nai = "'anonymous@hotspot.net'";
break;
case 9:
case 109:
osu_ssid = "OSU-OSEN";
osu_nai = "'test-anonymous@wi-fi.org'";
osu_friendly_name = "'eng:SP Orange Test Only'";
hs20_icon_filename = "icon_orange_zxx.png";
if (dut->ap_osu_icon_tag == 2)
hs20_icon_filename = "wifi-abgn-logo_270x73.png";
snprintf(hs20_icon, sizeof(hs20_icon),
"'128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s'",
hs20_icon_filename);
osu_icon = "icon_orange_zxx.png";
osu_method = (dut->ap_osu_method[0] == 0xFF) ? 1 :
dut->ap_osu_method[0];
osu_service_desc = NULL;
break;
default:
break;
}
if (strlen(dut->ap_osu_ssid)) {
if (dut->ap_tag_ssid[0][0] &&
strcmp(dut->ap_tag_ssid[0],
dut->ap_osu_ssid) != 0 &&
strcmp(dut->ap_tag_ssid[0], osu_ssid) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"OSU_SSID and WLAN_TAG2 SSID differ");
return -2;
}
snprintf(buf, sizeof(buf), "'\"%s\"'",
dut->ap_osu_ssid);
} else {
snprintf(buf, sizeof(buf), "'\"%s\"'", osu_ssid);
}
owrt_ap_set_vap(dut, vap_id, "osu_ssid", buf);
if (osu_friendly_name)
owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name",
osu_friendly_name);
if (osu_service_desc)
owrt_ap_set_list_vap(dut, vap_id, "osu_service_desc",
osu_service_desc);
if (osu_nai)
owrt_ap_set_vap(dut, vap_id, "osu_nai", osu_nai);
owrt_ap_set_list_vap(dut, vap_id, "hs20_icon", hs20_icon);
if (osu_icon)
owrt_ap_set_list_vap(dut, vap_id, "osu_icon",
osu_icon);
if (dut->ap_osu_provider_list > 100) {
owrt_ap_set_list_vap(dut, vap_id, "osu_method_list",
"0");
} else {
snprintf(buf, sizeof(buf), "%d", osu_method);
owrt_ap_set_list_vap(dut, vap_id, "osu_method_list",
buf);
}
}
return 0;
}
static int set_anqp_elem_value(struct sigma_dut *dut, const char *ifname,
char *anqp_string, size_t str_size)
{
unsigned char bssid[ETH_ALEN];
unsigned char dummy_mac[] = { 0x00, 0x10, 0x20, 0x30, 0x40, 0x50 };
int preference = 0xff;
if (get_hwaddr(ifname, bssid) < 0)
return -1;
snprintf(anqp_string, str_size,
"272:3410%02x%02x%02x%02x%02x%02xf70000007330000301%02x3410%02x%02x%02x%02x%02x%02xf70000007330000301%02x",
bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5],
preference,
dummy_mac[0], dummy_mac[1], dummy_mac[2],
dummy_mac[3], dummy_mac[4], dummy_mac[5],
preference - 1);
return 0;
}
static void get_if_name(struct sigma_dut *dut, char *ifname_str,
size_t str_size, int wlan_tag)
{
const char *ifname;
enum driver_type drv;
drv = get_driver_type();
if (dut->hostapd_ifname && if_nametoindex(dut->hostapd_ifname) > 0) {
ifname = dut->hostapd_ifname;
} else if (drv == DRIVER_ATHEROS) {
if ((dut->ap_mode == AP_11a || dut->ap_mode == AP_11na ||
dut->ap_mode == AP_11ac) &&
if_nametoindex("ath1") > 0)
ifname = "ath1";
else
ifname = "ath0";
} else if (drv == DRIVER_OPENWRT) {
if (sigma_radio_ifname[0] &&
strcmp(sigma_radio_ifname[0], "wifi2") == 0)
ifname = "ath2";
else if (sigma_radio_ifname[0] &&
strcmp(sigma_radio_ifname[0], "wifi1") == 0)
ifname = "ath1";
else
ifname = "ath0";
} else if (drv == DRIVER_WIL6210) {
ifname = get_main_ifname();
} else {
if ((dut->ap_mode == AP_11a || dut->ap_mode == AP_11na ||
dut->ap_mode == AP_11ac) &&
if_nametoindex("wlan1") > 0)
ifname = "wlan1";
else
ifname = "wlan0";
}
if (drv == DRIVER_OPENWRT && wlan_tag > 1) {
/* Handle tagged-ifname only on OPENWRT for now */
snprintf(ifname_str, str_size, "%s%d", ifname, wlan_tag - 1);
} else if ((drv == DRIVER_MAC80211 || drv == DRIVER_LINUX_WCN) &&
wlan_tag == 2) {
snprintf(ifname_str, str_size, "%s_1", ifname);
} else {
snprintf(ifname_str, str_size, "%s", ifname);
}
}
static int owrt_ap_config_vap(struct sigma_dut *dut)
{
char buf[256], *temp;
int vap_id = 0, vap_count, i, j;
const char *ifname;
char ifname2[50];
if (sigma_radio_ifname[0] &&
strcmp(sigma_radio_ifname[0], "wifi2") == 0)
ifname = "ath2";
else if (sigma_radio_ifname[0] &&
strcmp(sigma_radio_ifname[0], "wifi1") == 0)
ifname = "ath1";
else
ifname = "ath0";
for (vap_count = 0; vap_count < OPENWRT_MAX_NUM_RADIOS; vap_count++) {
snprintf(buf, sizeof(buf), "wifi%d", vap_count);
for (vap_id = 0; vap_id < MAX_RADIO; vap_id++) {
if (sigma_radio_ifname[vap_id] &&
strcmp(sigma_radio_ifname[vap_id], buf) == 0)
break;
}
if (vap_id == MAX_RADIO)
continue;
/* Single VAP configuration */
if (!dut->ap_is_dual)
vap_id = vap_count;
for (j = 0; j < MAX_WLAN_TAGS - 1; j++) {
/*
* We keep a separate array of ap_tag_ssid and
* ap_tag_key_mgmt for tags starting from WLAN_TAG=2.
* So j=0 => WLAN_TAG = 2
*/
int wlan_tag = j + 2;
if (wlan_tag == 2 && dut->program == PROGRAM_WPA3 &&
(dut->ap_interface_5g || dut->ap_interface_2g)) {
snprintf(dut->ap_tag_ssid[wlan_tag - 2],
sizeof(dut->ap_tag_ssid[wlan_tag - 2]),
"%s-owe", dut->ap_ssid);
}
if (dut->ap_tag_ssid[j][0] == '\0')
continue;
snprintf(buf, sizeof(buf), "%s%d", "wifi", vap_count);
owrt_ap_add_vap(dut, vap_count + (wlan_tag - 1),
"device", buf);
/* SSID */
snprintf(buf, sizeof(buf), "\"%s\"",
dut->ap_tag_ssid[j]);
owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
"ssid", buf);
if (dut->ap_key_mgmt == AP_WPA2_OWE &&
dut->ap_tag_ssid[0][0] &&
dut->ap_tag_key_mgmt[0] == AP2_OPEN) {
/* OWE transition mode */
snprintf(buf, sizeof(buf), "%s", ifname);
owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
"owe_transition_ifname", buf);
}
if (dut->ap_key_mgmt == AP_OPEN &&
dut->ap_tag_key_mgmt[0] == AP2_WPA2_OWE) {
/* OWE transition mode */
snprintf(buf, sizeof(buf), "%s", ifname);
owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
"owe_transition_ifname", buf);
owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
"hidden", "1");
}
if (ap_ft_enabled(dut)) {
unsigned char self_mac[ETH_ALEN];
char mac_str[20];
owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
"mobility_domain",
dut->ap_mobility_domain);
owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
"ft_over_ds", "0");
owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
"ieee80211r", "1");
owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
"nasid", "nas1.example.com");
if (get_hwaddr(sigma_radio_ifname[0],
self_mac) < 0)
return -1;
snprintf(mac_str, sizeof(mac_str),
"%02x:%02x:%02x:%02x:%02x:%02x",
self_mac[0], self_mac[1], self_mac[2],
self_mac[3], self_mac[4], self_mac[5]);
owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
"ap_macaddr", mac_str);
snprintf(mac_str, sizeof(mac_str),
"%02x%02x%02x%02x%02x%02x",
self_mac[0], self_mac[1], self_mac[2],
self_mac[3], self_mac[4], self_mac[5]);
owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
"r1_key_holder", mac_str);
owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
"ft_psk_generate_local", "1");
owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
"kh_key_hex",
"000102030405060708090a0b0c0d0e0f");
snprintf(mac_str, sizeof(mac_str),
"%02x:%02x:%02x:%02x:%02x:%02x",
dut->ft_bss_mac_list[0][0],
dut->ft_bss_mac_list[0][1],
dut->ft_bss_mac_list[0][2],
dut->ft_bss_mac_list[0][3],
dut->ft_bss_mac_list[0][4],
dut->ft_bss_mac_list[0][5]);
owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
"ap2_macaddr", mac_str);
owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
"ap2_r1_key_holder", mac_str);
owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
"nasid2", "nas2.example.com");
}
if (dut->ap_tag_key_mgmt[j] == AP2_OSEN &&
wlan_tag == 2) {
/* Only supported for WLAN_TAG=2 */
owrt_ap_set_vap(dut, vap_count + 1, "osen",
"1");
snprintf(buf, sizeof(buf), "wpa2");
owrt_ap_set_vap(dut, vap_count + 1,
"encryption", buf);
snprintf(buf, sizeof(buf), "%s",
dut->ap2_radius_ipaddr);
owrt_ap_set_vap(dut, vap_count + 1,
"auth_server", buf);
snprintf(buf, sizeof(buf), "%d",
dut->ap2_radius_port);
owrt_ap_set_vap(dut, vap_count + 1,
"auth_port", buf);
snprintf(buf, sizeof(buf), "%s",
dut->ap2_radius_password);
owrt_ap_set_vap(dut, vap_count + 1,
"auth_secret", buf);
} else if (dut->ap_tag_key_mgmt[j] == AP2_WPA2_PSK) {
owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
"encryption", "psk2+ccmp");
snprintf(buf, sizeof(buf), "\"%s\"",
dut->ap_passphrase);
owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
"key", buf);
snprintf(buf, sizeof(buf), "%d", dut->ap_pmf);
owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
"ieee80211w", buf);
} else if (dut->ap_tag_key_mgmt[0] == AP2_WPA2_OWE) {
owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
"owe", "1");
snprintf(buf, sizeof(buf), "ccmp");
owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
"encryption", buf);
owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
"ieee80211w", "2");
if (dut->ap_sae_groups) {
snprintf(buf, sizeof(buf), "\'%s\'",
dut->ap_sae_groups);
owrt_ap_set_list_vap(dut, vap_count +
(wlan_tag - 1),
"owe_groups", buf);
}
}
}
/* Now set anqp_elem and ft_oa for wlan_tag = 1 */
if (dut->program == PROGRAM_MBO &&
get_driver_type() == DRIVER_OPENWRT) {
unsigned char self_mac[ETH_ALEN];
char mac_str[20];
char anqp_string[200];
if (set_anqp_elem_value(dut, sigma_radio_ifname[0],
anqp_string,
sizeof(anqp_string)) < 0)
return -1;
owrt_ap_set_list_vap(dut, vap_count, "anqp_elem",
anqp_string);
if (ap_ft_enabled(dut)) {
owrt_ap_set_vap(dut, vap_count,
"mobility_domain",
dut->ap_mobility_domain);
owrt_ap_set_vap(dut, vap_count,
"ft_over_ds", "0");
owrt_ap_set_vap(dut, vap_count,
"ieee80211r", "1");
owrt_ap_set_vap(dut, vap_count,
"nasid", "nas1.example.com");
get_hwaddr(sigma_radio_ifname[0], self_mac);
snprintf(mac_str, sizeof(mac_str),
"%02x:%02x:%02x:%02x:%02x:%02x",
self_mac[0], self_mac[1], self_mac[2],
self_mac[3], self_mac[4], self_mac[5]);
owrt_ap_set_vap(dut, vap_count,
"ap_macaddr", mac_str);
snprintf(mac_str, sizeof(mac_str),
"%02x%02x%02x%02x%02x%02x",
self_mac[0], self_mac[1], self_mac[2],
self_mac[3], self_mac[4], self_mac[5]);
owrt_ap_set_vap(dut, vap_count,
"r1_key_holder", mac_str);
owrt_ap_set_vap(dut, vap_count,
"ft_psk_generate_local", "1");
owrt_ap_set_vap(dut, vap_count,
"kh_key_hex",
"000102030405060708090a0b0c0d0e0f");
snprintf(mac_str, sizeof(mac_str),
"%02x:%02x:%02x:%02x:%02x:%02x",
dut->ft_bss_mac_list[0][0],
dut->ft_bss_mac_list[0][1],
dut->ft_bss_mac_list[0][2],
dut->ft_bss_mac_list[0][3],
dut->ft_bss_mac_list[0][4],
dut->ft_bss_mac_list[0][5]);
owrt_ap_set_vap(dut, vap_count,
"ap2_macaddr", mac_str);
owrt_ap_set_vap(dut, vap_count,
"ap2_r1_key_holder", mac_str);
owrt_ap_set_vap(dut, vap_count,
"nasid2", "nas2.example.com");
}
}
if (dut->ap_oce == VALUE_ENABLED &&
get_driver_type() == DRIVER_OPENWRT) {
owrt_ap_set_vap(dut, vap_id, "oce", "1");
owrt_ap_set_vap(dut, vap_id, "qbssload", "1");
owrt_ap_set_vap(dut, vap_id, "bpr_enable", "1");
if (dut->ap_80plus80 == 1)
owrt_ap_set_vap(dut, vap_id, "cfreq2", "5775");
if (dut->ap_akm == 1) {
owrt_ap_set_vap(dut, vap_id, "wpa_group_rekey",
"3600");
owrt_ap_set_vap(dut, vap_id, "key", "12345678");
owrt_ap_set_vap(dut, vap_id, "ieee80211ai",
"1");
owrt_ap_set_vap(dut, vap_id, "fils_cache_id",
"1234");
owrt_ap_set_vap(dut, vap_id,
"erp_send_reauth_start", "1");
}
if (dut->ap_filshlp == VALUE_ENABLED) {
struct ifreq ifr;
char *ifname;
int s;
struct sockaddr_in *ipaddr;
s = socket(AF_INET, SOCK_DGRAM, 0);
if (s < 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Failed to open socket");
return -1;
}
ifr.ifr_addr.sa_family = AF_INET;
memset(&ifr, 0, sizeof(ifr));
ifname = "br-lan";
strlcpy(ifr.ifr_name, ifname,
sizeof(ifr.ifr_name));
if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
perror("ioctl");
close(s);
return -1;
}
ipaddr = (struct sockaddr_in*)&ifr.ifr_addr;
snprintf(buf, sizeof(buf), "%s",
inet_ntoa(ipaddr->sin_addr));
owrt_ap_set_vap(dut, vap_id, "own_ip_addr",
buf);
snprintf(buf, sizeof(buf), "%s",
dut->ap_dhcpserv_ipaddr);
owrt_ap_set_vap(dut, vap_id, "dhcp_server",
buf);
owrt_ap_set_vap(dut, vap_id,
"dhcp_rapid_commit_proxy", "1");
owrt_ap_set_vap(dut, vap_id,
"fils_hlp_wait_time", "300");
}
if (dut->ap_filsdscv == VALUE_ENABLED) {
owrt_ap_set_vap(dut, vap_id, "ieee80211ai",
"1");
owrt_ap_set_vap(dut, vap_id, "fils_fd_period",
"20");
}
}
if (dut->ap_filsdscv == VALUE_DISABLED) {
owrt_ap_set_vap(dut, vap_id, "ieee80211ai", "0");
owrt_ap_set_vap(dut, vap_id, "fils_fd_period", "0");
}
if (dut->ap_oce == VALUE_DISABLED &&
get_driver_type() == DRIVER_OPENWRT) {
owrt_ap_set_vap(dut, vap_id, "oce", "0");
owrt_ap_set_vap(dut, vap_id, "qbssload", "0");
owrt_ap_set_vap(dut, vap_id, "bpr_enable", "0");
if (dut->ap_filsdscv == VALUE_DISABLED) {
owrt_ap_set_vap(dut, vap_id, "ieee80211ai",
"0");
owrt_ap_set_vap(dut, vap_id, "fils_fd_period",
"0");
}
if (dut->device_type == AP_testbed)
owrt_ap_set_vap(dut, vap_id, "mbo", "1");
}
/* NAIRealm */
if (dut->ap_nairealm_int == 1) {
snprintf(buf, sizeof(buf), "\"%s\"", dut->ap_nairealm);
owrt_ap_set_vap(dut, vap_id, "fils_realm", buf);
owrt_ap_set_vap(dut, vap_id, "erp_domain", buf);
}
/* SSID */
snprintf(buf, sizeof(buf), "\"%s\"", dut->ap_ssid);
owrt_ap_set_vap(dut, vap_count, "ssid", buf);
/* Encryption */
switch (dut->ap_key_mgmt) {
case AP_OPEN:
if (dut->ap_cipher == AP_WEP) {
owrt_ap_set_vap(dut, vap_count, "encryption",
"wep-mixed");
owrt_ap_set_vap(dut, vap_count, "key",
dut->ap_wepkey);
} else {
owrt_ap_set_vap(dut, vap_count, "encryption",
"none");
}
if (dut->ap_key_mgmt == AP_OPEN &&
dut->ap_tag_key_mgmt[0] == AP2_WPA2_OWE) {
/* OWE transition mode */
snprintf(ifname2, sizeof(ifname2), "%s1",
ifname);
owrt_ap_set_vap(dut, vap_count,
"owe_transition_ifname",
ifname2);
}
break;
case AP_WPA2_PSK:
case AP_WPA2_PSK_MIXED:
case AP_WPA_PSK:
case AP_WPA2_SAE:
case AP_WPA2_PSK_SAE:
if (dut->ap_key_mgmt == AP_WPA2_PSK ||
dut->ap_key_mgmt == AP_WPA2_PSK_SAE) {
snprintf(buf, sizeof(buf), "psk2");
} else if (dut->ap_key_mgmt == AP_WPA2_PSK_MIXED) {
snprintf(buf, sizeof(buf), "psk-mixed");
} else if (dut->ap_key_mgmt == AP_WPA2_SAE) {
snprintf(buf, sizeof(buf), "ccmp");
} else {
snprintf(buf, sizeof(buf), "psk");
}
if (dut->ap_key_mgmt != AP_WPA2_SAE) {
if (dut->ap_cipher == AP_CCMP_TKIP)
strlcat(buf, "+ccmp+tkip", sizeof(buf));
else if (dut->ap_cipher == AP_TKIP)
strlcat(buf, "+tkip", sizeof(buf));
else if (dut->ap_cipher == AP_GCMP_128)
strlcat(buf, "+gcmp", sizeof(buf));
else
strlcat(buf, "+ccmp", sizeof(buf));
}
owrt_ap_set_vap(dut, vap_count, "encryption", buf);
if (!dut->ap_passphrase[0] && dut->ap_psk[0]) {
snprintf(buf, sizeof(buf), "\"%s\"",
dut->ap_psk);
owrt_ap_set_vap(dut, vap_count, "key", buf);
} else {
snprintf(buf, sizeof(buf), "\"%s\"",
dut->ap_passphrase);
owrt_ap_set_vap(dut, vap_count, "key", buf);
}
if (dut->ap_key_mgmt == AP_WPA2_SAE ||
dut->ap_key_mgmt == AP_WPA2_PSK_SAE)
owrt_ap_set_vap(dut, vap_count, "sae", "1");
else
owrt_ap_set_vap(dut, vap_count, "sae", "0");
if (dut->ap_key_mgmt == AP_WPA2_SAE) {
snprintf(buf, sizeof(buf), "%s",
dut->ap_passphrase);
owrt_ap_set_vap(dut, vap_count, "sae_password",
buf);
} else {
snprintf(buf, sizeof(buf), "%s",
dut->ap_passphrase);
owrt_ap_set_vap(dut, vap_count,
"wpa_passphrase", buf);
}
break;
case AP_WPA2_EAP:
case AP_WPA2_EAP_MIXED:
case AP_WPA_EAP:
if (dut->ap_key_mgmt == AP_WPA2_EAP) {
snprintf(buf, sizeof(buf), "wpa2");
} else if (dut->ap_key_mgmt == AP_WPA2_EAP_MIXED) {
snprintf(buf, sizeof(buf), "wpa-mixed");
} else {
snprintf(buf, sizeof(buf), "wpa");
}
if (dut->ap_cipher == AP_CCMP_TKIP)
strlcat(buf, "+ccmp+tkip", sizeof(buf));
else if (dut->ap_cipher == AP_TKIP)
strlcat(buf, "+tkip", sizeof(buf));
else
strlcat(buf, "+ccmp", sizeof(buf));
owrt_ap_set_vap(dut, vap_count, "encryption", buf);
snprintf(buf, sizeof(buf), "%s", dut->ap_radius_ipaddr);
owrt_ap_set_vap(dut, vap_count, "auth_server", buf);
snprintf(buf, sizeof(buf), "%d", dut->ap_radius_port);
owrt_ap_set_vap(dut, vap_count, "auth_port", buf);
snprintf(buf, sizeof(buf), "%s",
dut->ap_radius_password);
owrt_ap_set_vap(dut, vap_count, "auth_secret", buf);
break;
case AP_WPA2_EAP_OSEN:
case AP_OSEN:
case AP_WPA2_FT_EAP:
case AP_WPA2_FT_PSK:
case AP_WPA2_EAP_SHA256:
case AP_WPA2_PSK_SHA256:
case AP_WPA2_ENT_FT_EAP:
/* TODO */
break;
case AP_SUITEB:
owrt_ap_set_vap(dut, vap_count, "suite_b", "192");
snprintf(buf, sizeof(buf), "gcmp");
owrt_ap_set_vap(dut, vap_count, "encryption", buf);
snprintf(buf, sizeof(buf), "%s", dut->ap_radius_ipaddr);
owrt_ap_set_vap(dut, vap_count, "auth_server", buf);
snprintf(buf, sizeof(buf), "%d", dut->ap_radius_port);
owrt_ap_set_vap(dut, vap_count, "auth_port", buf);
snprintf(buf, sizeof(buf), "%s",
dut->ap_radius_password);
owrt_ap_set_vap(dut, vap_count, "auth_secret", buf);
snprintf(buf, sizeof(buf), "%d",
dut->ap_group_mgmt_cipher);
owrt_ap_set_vap(dut, vap_count, "group_mgmt_cipher",
buf);
break;
case AP_WPA2_OWE:
owrt_ap_set_vap(dut, vap_count, "owe", "1");
snprintf(buf, sizeof(buf), "ccmp");
owrt_ap_set_vap(dut, vap_count, "encryption", buf);
if (dut->ap_sae_groups) {
snprintf(buf, sizeof(buf), "\'%s\'",
dut->ap_sae_groups);
owrt_ap_set_list_vap(dut, vap_count,
"owe_groups", buf);
}
if (dut->ap_key_mgmt == AP_WPA2_OWE &&
dut->ap_tag_ssid[0][0] &&
dut->ap_tag_key_mgmt[0] == AP2_OPEN) {
/* OWE transition mode */
snprintf(ifname2, sizeof(ifname2), "%s1",
ifname);
owrt_ap_set_vap(dut, vap_count,
"owe_transition_ifname",
ifname2);
owrt_ap_set_vap(dut, vap_count, "hidden", "1");
}
break;
}
if (!dut->ap_is_dual)
break;
}
if (dut->ap_is_dual)
return 1;
/* PMF */
snprintf(buf, sizeof(buf), "%d", dut->ap_pmf);
owrt_ap_set_vap(dut, vap_id, "ieee80211w", buf);
/* Add SHA256 */
snprintf(buf, sizeof(buf), "%d", dut->ap_add_sha256);
owrt_ap_set_vap(dut, vap_id, "add_sha256", buf);
/* Add SHA384 for akmsuitetype 15 */
if (dut->ap_akm == 1) {
snprintf(buf, sizeof(buf), "%d", dut->ap_add_sha384);
owrt_ap_set_vap(dut, vap_id, "add_sha384", buf);
}
/* Enable RSN preauthentication, if asked to */
snprintf(buf, sizeof(buf), "%d", dut->ap_rsn_preauth);
owrt_ap_set_vap(dut, vap_id, "rsn_preauth", buf);
/* Hotspot 2.0 */
if (dut->ap_hs2) {
int ret;
ret = owrt_ap_config_vap_hs2(dut, vap_id);
if (ret)
return ret;
}
/* Interworking */
if (dut->ap_interworking) {
snprintf(buf, sizeof(buf), "%d", dut->ap_access_net_type);
owrt_ap_set_vap(dut, vap_id, "access_network_type", buf);
snprintf(buf, sizeof(buf), "%d", dut->ap_internet);
owrt_ap_set_vap(dut, vap_id, "internet", buf);
snprintf(buf, sizeof(buf), "%d", dut->ap_venue_group);
owrt_ap_set_vap(dut, vap_id, "venue_group", buf);
snprintf(buf, sizeof(buf), "%d", dut->ap_venue_type);
owrt_ap_set_vap(dut, vap_id, "venue_type", buf);
snprintf(buf, sizeof(buf), "%s", dut->ap_hessid);
owrt_ap_set_vap(dut, vap_id, "hessid", buf);
if (dut->ap_gas_cb_delay > 0) {
snprintf(buf, sizeof(buf), "%d", dut->ap_gas_cb_delay);
owrt_ap_set_vap(dut, vap_id, "gas_comeback_delay", buf);
}
if (dut->ap_roaming_cons[0]) {
char *rcons, *temp_ptr;
rcons = strdup(dut->ap_roaming_cons);
if (rcons == NULL)
return -1;
temp_ptr = strchr(rcons, ';');
if (temp_ptr)
*temp_ptr++ = '\0';
owrt_ap_set_list_vap(dut, vap_id, "roaming_consortium",
rcons);
if (temp_ptr)
owrt_ap_set_list_vap(dut, vap_id,
"roaming_consortium",
temp_ptr);
free(rcons);
}
}
if (dut->ap_venue_name) {
owrt_ap_set_list_vap(dut, vap_id, "venue_name",
"'P\"eng:Wi-Fi Alliance\\n2989 Copper Road\\nSanta Clara, CA 95051, USA\"'");
owrt_ap_set_list_vap(dut, vap_id, "venue_name",
"\'"ANQP_VENUE_NAME_1_CHI"\'");
}
if (dut->ap_net_auth_type == 1) {
owrt_ap_set_list_vap(dut, vap_id, "network_auth_type",
"'00https://tandc-server.wi-fi.org'");
} else if (dut->ap_net_auth_type == 2) {
owrt_ap_set_list_vap(dut, vap_id, "network_auth_type", "'01'");
}
if (dut->ap_nai_realm_list == 1) {
owrt_ap_set_list_vap(dut, vap_id, "nai_realm",
"'0,mail.example.com;cisco.com;wi-fi.org,21[2:4][5:7]'");
owrt_ap_set_list_vap(dut, vap_id, "nai_realm",
"'0,wi-fi.org;example.com,13[5:6]'");
} else if (dut->ap_nai_realm_list == 2) {
owrt_ap_set_list_vap(dut, vap_id, "nai_realm",
"'0,wi-fi.org,21[2:4][5:7]'");
} else if (dut->ap_nai_realm_list == 3) {
owrt_ap_set_list_vap(dut, vap_id, "nai_realm",
"'0,cisco.com;wi-fi.org,21[2:4][5:7]'");
owrt_ap_set_list_vap(dut, vap_id, "nai_realm",
"'0,wi-fi.org;example.com,13[5:6]'");
} else if (dut->ap_nai_realm_list == 4) {
owrt_ap_set_list_vap(dut, vap_id, "nai_realm",
"'0,mail.example.com,21[2:4][5:7],13[5:6]'");
} else if (dut->ap_nai_realm_list == 5) {
owrt_ap_set_list_vap(dut, vap_id, "nai_realm",
"'0,wi-fi.org;ruckuswireless.com,21[2:4][5:7]'");
} else if (dut->ap_nai_realm_list == 6) {
owrt_ap_set_list_vap(dut, vap_id, "nai_realm",
"'0,wi-fi.org;mail.example.com,21[2:4][5:7]'");
} else if (dut->ap_nai_realm_list == 7) {
owrt_ap_set_list_vap(dut, vap_id, "nai_realm",
"'0,wi-fi.org,13[5:6]'");
owrt_ap_set_list_vap(dut, vap_id, "nai_realm",
"'0,wi-fi.org,21[2:4][5:7]'");
}
if (dut->ap_domain_name_list[0])
owrt_ap_set_list_vap(dut, vap_id, "domain_name",
dut->ap_domain_name_list);
if (dut->ap_ip_addr_type_avail)
owrt_ap_set_vap(dut, vap_id, "ipaddr_type_availability",
"'0c'");
temp = buf;
*temp++ = '\'';
for (i = 0; dut->ap_plmn_mcc[i][0] && dut->ap_plmn_mnc[i][0]; i++) {
if (i)
*temp++ = ';';
snprintf(temp,
sizeof(dut->ap_plmn_mcc[i]) +
sizeof(dut->ap_plmn_mnc[i]) + 1,
"%s,%s",
dut->ap_plmn_mcc[i],
dut->ap_plmn_mnc[i]);
temp += strlen(dut->ap_plmn_mcc[i]) +
strlen(dut->ap_plmn_mnc[i]) + 1;
}
*temp++ = '\'';
*temp++ = '\0';
if (i)
owrt_ap_set_vap(dut, vap_id, "anqp_3gpp_cell_net", buf);
if (dut->ap_qos_map_set == 1)
owrt_ap_set_vap(dut, vap_id, "qos_map_set", QOS_MAP_SET_1);
else if (dut->ap_qos_map_set == 2)
owrt_ap_set_vap(dut, vap_id, "qos_map_set", QOS_MAP_SET_2);
/* Proxy-ARP */
snprintf(buf, sizeof(buf), "%d", dut->ap_proxy_arp);
owrt_ap_set_vap(dut, vap_id, "proxyarp", buf);
/* DGAF */
snprintf(buf, sizeof(buf), "%d", dut->ap_dgaf_disable);
/* parse to hostapd */
owrt_ap_set_vap(dut, vap_id, "disable_dgaf", buf);
/* parse to wifi driver */
owrt_ap_set_vap(dut, vap_id, "dgaf_disable", buf);
/* HCBSSLoad */
if (dut->ap_bss_load) {
unsigned int bssload = 0;
if (dut->ap_bss_load == 1) {
/* STA count: 1, CU: 50, AAC: 65535 */
bssload = 0x0132ffff;
} else if (dut->ap_bss_load == 2) {
/* STA count: 1, CU: 200, AAC: 65535 */
bssload = 0x01c8ffff;
} else if (dut->ap_bss_load == 3) {
/* STA count: 1, CU: 75, AAC: 65535 */
bssload = 0x014bffff;
}
snprintf(buf, sizeof(buf), "%d", bssload);
owrt_ap_set_vap(dut, vap_id, "hcbssload", buf);
}
/* L2TIF */
if (dut->ap_l2tif)
owrt_ap_set_vap(dut, vap_id, "l2tif", "1");
if (dut->ap_disable_protection == 1)
owrt_ap_set_vap(dut, vap_id, "enablertscts", "0");
if (dut->ap_txBF) {
owrt_ap_set_vap(dut, vap_id, "vhtsubfee", "1");
owrt_ap_set_vap(dut, vap_id, "vhtsubfer", "1");
}
if (dut->ap_mu_txBF)
owrt_ap_set_vap(dut, vap_id, "vhtmubfer", "1");
if (dut->ap_tx_stbc) {
/* STBC and beamforming are mutually exclusive features */
owrt_ap_set_vap(dut, vap_id, "implicitbf", "0");
}
/* enable dfsmode */
snprintf(buf, sizeof(buf), "%d", dut->ap_dfs_mode);
owrt_ap_set_vap(dut, vap_id, "doth", buf);
if (dut->program == PROGRAM_LOC && dut->ap_interworking) {
char anqpval[1024];
owrt_ap_set_vap(dut, vap_id, "interworking", "1");
if (dut->ap_lci == 1 && strlen(dut->ap_tag_ssid[0]) == 0) {
snprintf(anqpval, sizeof(anqpval),
"'265:0010%s%s060101'",
dut->ap_val_lci, dut->ap_infoz);
owrt_ap_set_list_vap(dut, vap_id, "anqp_elem", anqpval);
}
if (dut->ap_lcr == 1) {
snprintf(anqpval, sizeof(anqpval),
"'266:0000b2555302ae%s'",
dut->ap_val_lcr);
owrt_ap_set_list_vap(dut, vap_id, "anqp_elem", anqpval);
}
if (dut->ap_fqdn_held == 1 && dut->ap_fqdn_supl == 1)
owrt_ap_set_list_vap(dut, vap_id, "anqp_elem",
"'267:00110168656c642e6578616d706c652e636f6d0011027375706c2e6578616d706c652e636f6d'");
}
if (dut->program == PROGRAM_MBO) {
owrt_ap_set_vap(dut, vap_id, "interworking", "1");
owrt_ap_set_vap(dut, vap_id, "mbo", "1");
owrt_ap_set_vap(dut, vap_id, "rrm", "1");
owrt_ap_set_vap(dut, vap_id, "mbo_cell_conn_pref", "1");
owrt_ap_set_list_vap(dut, vap_id, "anqp_elem",
"'272:34108cfdf0020df1f7000000733000030101'");
snprintf(buf, sizeof(buf), "%d", dut->ap_gas_cb_delay);
owrt_ap_set_vap(dut, vap_id, "gas_comeback_delay", buf);
}
if (ap_ft_enabled(dut)) {
unsigned char self_mac[ETH_ALEN];
char mac_str[20];
owrt_ap_set_vap(dut, vap_id, "ft_over_ds", "0");
owrt_ap_set_vap(dut, vap_id, "ieee80211r", "1");
if (get_hwaddr(sigma_radio_ifname[0], self_mac) < 0)
return -1;
snprintf(mac_str, sizeof(mac_str),
"%02x:%02x:%02x:%02x:%02x:%02x",
self_mac[0], self_mac[1], self_mac[2],
self_mac[3], self_mac[4], self_mac[5]);
owrt_ap_set_vap(dut, vap_id, "ap_macaddr", mac_str);
snprintf(mac_str, sizeof(mac_str),
"%02x:%02x:%02x:%02x:%02x:%02x",
self_mac[0], self_mac[1], self_mac[2],
self_mac[3], self_mac[4], self_mac[5]);
owrt_ap_set_vap(dut, vap_id, "r1_key_holder", mac_str);
owrt_ap_set_vap(dut, vap_id, "ft_psk_generate_local", "1");
owrt_ap_set_vap(dut, vap_id, "kh_key_hex",
"000102030405060708090a0b0c0d0e0f");
snprintf(mac_str, sizeof(mac_str),
"%02x:%02x:%02x:%02x:%02x:%02x",
dut->ft_bss_mac_list[0][0],
dut->ft_bss_mac_list[0][1],
dut->ft_bss_mac_list[0][2],
dut->ft_bss_mac_list[0][3],
dut->ft_bss_mac_list[0][4],
dut->ft_bss_mac_list[0][5]);
owrt_ap_set_vap(dut, vap_id, "ap2_macaddr", mac_str);
owrt_ap_set_vap(dut, vap_id, "mobility_domain",
dut->ap_mobility_domain);
owrt_ap_set_vap(dut, vap_id, "ap2_r1_key_holder", mac_str);
}
if ((ap_ft_enabled(dut) && dut->ap_name == 0) ||
(ap_ft_enabled(dut) && dut->ap_name == 2)) {
owrt_ap_set_vap(dut, vap_id, "nasid2", "nas2.example.com");
owrt_ap_set_vap(dut, vap_id, "nasid", "nas1.example.com");
}
if (ap_ft_enabled(dut) && dut->ap_name == 1) {
owrt_ap_set_vap(dut, vap_id, "nasid2", "nas1.example.com");
owrt_ap_set_vap(dut, vap_id, "nasid", "nas2.example.com");
}
if (dut->ap_broadcast_ssid == VALUE_DISABLED)
owrt_ap_set_vap(dut, vap_id, "hidden", "1");
/* Enable/disable PMKSA caching, if asked to */
if (dut->ap_pmksa == 1) {
snprintf(buf, sizeof(buf), "%d", dut->ap_pmksa_caching);
owrt_ap_set_vap(dut, vap_id, "disable_pmksa_caching", buf);
}
if (dut->rsne_override) {
snprintf(buf, sizeof(buf), "%s", dut->rsne_override);
owrt_ap_set_vap(dut, vap_count, "own_ie_override", buf);
}
if (dut->sae_commit_override) {
snprintf(buf, sizeof(buf), "%s", dut->sae_commit_override);
owrt_ap_set_vap(dut, vap_count, "sae_commit_override", buf);
}
if (dut->ap_sae_groups) {
snprintf(buf, sizeof(buf), "\'%s\'", dut->ap_sae_groups);
owrt_ap_set_list_vap(dut, vap_count, "sae_groups", buf);
}
if (dut->sae_anti_clogging_threshold >= 0) {
snprintf(buf, sizeof(buf), "%d",
dut->sae_anti_clogging_threshold);
owrt_ap_set_vap(dut, vap_count, "sae_anti_clogging_threshold",
buf);
}
if (dut->sae_reflection)
owrt_ap_set_vap(dut, vap_count, "sae_reflection_attack", "1");
return 1;
}
static int owrt_ap_config_vap_anqp(struct sigma_dut *dut)
{
char anqpval[1024];
unsigned char addr[6];
unsigned char addr2[6];
struct ifreq ifr;
char *ifname;
int s;
int vap_id = 0;
s = socket(AF_INET, SOCK_DGRAM, 0);
if (s < 0) {
sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open socket");
return -1;
}
memset(&ifr, 0, sizeof(ifr));
ifname = "ath0";
strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) {
perror("ioctl");
close(s);
return -1;
}
memcpy(addr, ifr.ifr_hwaddr.sa_data, 6);
memset(&ifr, 0, sizeof(ifr));
ifname = "ath01";
strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) {
perror("ioctl");
close(s);
return -1;
}
close(s);
memcpy(addr2, ifr.ifr_hwaddr.sa_data, 6);
snprintf(anqpval, sizeof(anqpval),
"'265:0010%s%s060101070d00%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x'",
dut->ap_val_lci, dut->ap_infoz,
addr[0], addr[1], addr[2], addr[3], addr[4], addr[5],
addr2[0], addr2[1], addr2[2], addr2[3], addr2[4], addr2[5]);
owrt_ap_set_list_vap(dut, vap_id, "anqp_elem", anqpval);
return 0;
}
static int owrt_ap_post_config_commit(struct sigma_dut *dut,
struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
int ap_security = 0;
int i;
for (i = 0; i < MAX_WLAN_TAGS - 1; i++) {
if (dut->ap_tag_key_mgmt[i] != AP2_OPEN)
ap_security = 1;
}
if (dut->ap_key_mgmt != AP_OPEN)
ap_security = 1;
if (ap_security) {
/* allow some time for hostapd to start before returning
* success */
usleep(500000);
if (run_hostapd_cli(dut, "ping") != 0) {
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Failed to talk to hostapd");
return 0;
}
}
if (get_openwrt_driver_type() == OPENWRT_DRIVER_ATHEROS)
ath_ap_set_params(dut);
/* Send response */
return 1;
}
static int cmd_owrt_ap_config_commit(struct sigma_dut *dut,
struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
if (dut->program == PROGRAM_DPP &&
get_driver_type() == DRIVER_OPENWRT) {
wpa_command(dut->hostapd_ifname, "DPP_BOOTSTRAP_REMOVE *");
wpa_command(dut->hostapd_ifname, "DPP_PKEX_REMOVE *");
}
/* Stop the AP */
run_system(dut, "wifi down");
/* Reset the wireless configuration */
run_system(dut, "rm -rf /etc/config/wireless");
switch (get_openwrt_driver_type()) {
case OPENWRT_DRIVER_ATHEROS:
run_system(dut, "wifi detect qcawifi > /etc/config/wireless");
break;
default:
run_system(dut, "wifi detect > /etc/config/wireless");
break;
}
/* Configure Radio & VAP, commit the config */
owrt_ap_config_radio(dut);
if (owrt_ap_config_vap(dut) < 0)
return ERROR_SEND_STATUS;
run_system(dut, "uci commit");
/* Start AP */
run_system(dut, "wifi up");
if (dut->program != PROGRAM_MBO &&
dut->ap_lci == 1 && dut->ap_interworking &&
strlen(dut->ap_tag_ssid[0]) > 0) {
/*
* MBO has a different ANQP element value which is set in
* owrt_ap_config_vap().
*/
owrt_ap_config_vap_anqp(dut);
run_system(dut, "uci commit");
run_system(dut, "wifi");
}
return owrt_ap_post_config_commit(dut, conn, cmd);
}
static void cmd_owrt_ap_hs2_reset(struct sigma_dut *dut)
{
unsigned char bssid[6];
char buf[100];
char *ifname, *radio_name;
int vap_id = 0;
if (sigma_radio_ifname[0] &&
strcmp(sigma_radio_ifname[0], "wifi2") == 0) {
ifname = "ath2";
radio_name = "wifi2";
vap_id = 2;
} else if (sigma_radio_ifname[0] &&
strcmp(sigma_radio_ifname[0], "wifi1") == 0) {
ifname = "ath1";
radio_name = "wifi1";
vap_id = 1;
} else {
ifname = "ath0";
radio_name = "wifi0";
vap_id = 0;
}
if (!get_hwaddr(ifname, bssid)) {
snprintf(buf, sizeof(buf), "%s", bssid);
owrt_ap_set_vap(dut, vap_id, "hessid", buf);
snprintf(dut->ap_hessid, sizeof(dut->ap_hessid),
"%02x:%02x:%02x:%02x:%02x:%02x",
bssid[0], bssid[1], bssid[2], bssid[3],
bssid[4], bssid[5]);
} else {
if (!get_hwaddr(radio_name, bssid)) {
snprintf(buf, sizeof(buf), "%s", dut->ap_hessid);
owrt_ap_set_vap(dut, vap_id, "hessid", buf);
snprintf(dut->ap_hessid, sizeof(dut->ap_hessid),
"%02x:%02x:%02x:%02x:%02x:%02x",
bssid[0], bssid[1], bssid[2], bssid[3],
bssid[4], bssid[5]);
} else {
/* Select & enable/disable radios */
if (sigma_radio_ifname[0] &&
strcmp(sigma_radio_ifname[0], "wifi2") == 0) {
/* We want to use wifi2 */
owrt_ap_set_radio(dut, 0, "disabled", "1");
owrt_ap_set_radio(dut, 1, "disabled", "1");
owrt_ap_set_radio(dut, 2, "disabled", "0");
owrt_ap_set_vap(dut, vap_id, "device", "wifi2");
} else if (sigma_radio_ifname[0] &&
strcmp(sigma_radio_ifname[0], "wifi1") == 0) {
/* We want to use wifi1 */
owrt_ap_set_radio(dut, 0, "disabled", "1");
owrt_ap_set_radio(dut, 1, "disabled", "0");
owrt_ap_set_vap(dut, vap_id, "device", "wifi1");
} else {
/* We want to use wifi0 */
owrt_ap_set_radio(dut, 0, "disabled", "0");
owrt_ap_set_radio(dut, 1, "disabled", "1");
owrt_ap_set_vap(dut, vap_id, "device", "wifi0");
}
run_system(dut, "uci commit");
run_system(dut, "wifi up");
if (!get_hwaddr(radio_name, bssid)) {
snprintf(buf, sizeof(buf), "%s",
dut->ap_hessid);
owrt_ap_set_vap(dut, vap_id, "hessid", buf);
snprintf(dut->ap_hessid, sizeof(dut->ap_hessid),
"%02x:%02x:%02x:%02x:%02x:%02x",
bssid[0], bssid[1], bssid[2], bssid[3],
bssid[4], bssid[5]);
}
}
}
}
static int cmd_ap_reboot(struct sigma_dut *dut, struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
switch (get_driver_type()) {
case DRIVER_ATHEROS:
run_system(dut, "apdown");
sleep(1);
run_system(dut, "reboot");
break;
case DRIVER_OPENWRT:
run_system(dut, "wifi down");
sleep(1);
run_system(dut, "reboot");
break;
default:
sigma_dut_print(dut, DUT_MSG_INFO, "Ignore ap_reboot command");
break;
}
return 1;
}
int ascii2hexstr(const char *str, char *hex)
{
int i, length;
length = strlen(str);
for (i = 0; i < length; i++)
snprintf(hex + i * 2, 3, "%X", str[i]);
hex[length * 2] = '\0';
return 1;
}
static int kill_process(struct sigma_dut *dut, char *proc_name,
unsigned char is_proc_instance_one, int sig)
{
#ifdef __linux__
struct dirent *dp, *dp_in;
const char *direc = "/proc/";
char buf[100];
DIR *dir = opendir(direc);
DIR *dir_in;
FILE *fp;
char *pid, *temp;
char *saveptr;
int ret = -1;
if (dir == NULL)
return ret;
while ((dp = readdir(dir)) != NULL) {
if (dp->d_type != DT_DIR)
continue;
snprintf(buf, sizeof(buf), "%s%s", direc, dp->d_name);
dir_in = opendir(buf);
if (dir_in == NULL)
continue;
dp_in = readdir(dir_in);
closedir(dir_in);
if (dp_in == NULL)
continue;
snprintf(buf, sizeof(buf), "%s%s/stat", direc, dp->d_name);
fp = fopen(buf, "r");
if (fp == NULL)
continue;
if (fgets(buf, 100, fp) == NULL)
buf[0] = '\0';
fclose(fp);
pid = strtok_r(buf, " ", &saveptr);
temp = strtok_r(NULL, " ", &saveptr);
if (pid && temp &&
strncmp(temp, proc_name, strlen(proc_name)) == 0) {
sigma_dut_print(dut, DUT_MSG_INFO,
"killing %s process with PID %s",
proc_name, pid);
snprintf(buf, sizeof(buf), "kill -%d %d", sig,
atoi(pid));
run_system(dut, buf);
ret = 0;
if (is_proc_instance_one)
break;
}
}
closedir(dir);
return ret;
#else /* __linux__ */
return -1;
#endif /* __linux__ */
}
static int run_ndc(struct sigma_dut *dut, char *buf)
{
sigma_dut_print(dut, DUT_MSG_INFO, "CMD NDC:: %s", buf);
sleep(2);
return run_system(dut, buf);
}
static int sigma_write_cfg(struct sigma_dut *dut, const char *pfile,
const char *field, const char *value)
{
FILE *fcfg, *ftmp;
char buf[MAX_CONF_LINE_LEN + 1];
int len, found = 0, res;
/* Open the configuration file */
fcfg = fopen(pfile, "r");
if (!fcfg) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Failed to open hostapd conf file");
return -1;
}
snprintf(buf, sizeof(buf), "%s~", pfile);
/* Open a temporary file */
ftmp = fopen(buf, "w+");
if (!ftmp) {
fclose(fcfg);
sigma_dut_print(dut, DUT_MSG_ERROR,
"Failed to open temp buf");
return -1;
}
/* Read the values from the configuration file */
len = strlen(field);
while (fgets(buf, MAX_CONF_LINE_LEN, fcfg)) {
char *pline = buf;
/* commented line */
if (buf[0] == '#')
pline++;
/* Identify the configuration parameter to be updated */
if (!found && strncmp(pline, field, len) == 0 &&
pline[len] == '=') {
snprintf(buf, sizeof(buf), "%s=%s\n", field, value);
found = 1;
sigma_dut_print(dut, DUT_MSG_INFO,
"Updated hostapd conf file");
}
fprintf(ftmp, "%s", buf);
}
if (!found) {
/* Configuration line not found */
/* Add the new line at the end of file */
fprintf(ftmp, "%s=%s\n", field, value);
sigma_dut_print(dut, DUT_MSG_INFO,
"Adding a new line in hostapd conf file");
}
fclose(fcfg);
fclose(ftmp);
snprintf(buf, sizeof(buf), "%s~", pfile);
/* Restore the updated configuration file */
res = rename(buf, pfile);
/* Remove the temporary file. Ignore the return value */
unlink(buf);
/* chmod is needed because open() may not set permissions properly
* depending on the current umask */
if (chmod(pfile, 0660) < 0) {
unlink(pfile);
sigma_dut_print(dut, DUT_MSG_ERROR,
"Error changing permissions");
return -1;
}
if (res < 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Error restoring conf file");
return -1;
}
return 0;
}
static int cmd_wcn_ap_config_commit(struct sigma_dut *dut,
struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
char buf[100];
struct stat s;
int num_tries = 0, ret;
if (kill_process(dut, "(netd)", 1, SIGKILL) == 0 ||
system("killall netd") == 0) {
/* Avoid Error: Error connecting (Connection refused)
* Wait some time to allow netd to reinitialize.
*/
usleep(1500000);
}
while (num_tries < 10) {
ret = run_ndc(dut, "ndc softap stopap");
num_tries++;
if (WIFEXITED(ret))
ret = WEXITSTATUS(ret);
/* On success, NDC exits with 0 */
if (ret == 0)
break;
sigma_dut_print(dut, DUT_MSG_INFO,
"Try No. %d: ndc softap stopap failed, exit code %d",
num_tries, ret);
}
if (ret != 0)
sigma_dut_print(dut, DUT_MSG_ERROR,
"ndc softap stopap command failed for 10 times - giving up");
#ifdef ANDROID
/* Unload/Load driver to cleanup the state of the driver */
system("rmmod -f wlan");
usleep(500000);
system("insmod /system/lib/modules/wlan.ko");
#else /* ANDROID */
run_ndc(dut, "ndc softap qccmd set enable_softap=0");
run_ndc(dut, "ndc softap qccmd set enable_softap=1");
#endif /* ANDROID */
switch (dut->ap_mode) {
case AP_11g:
run_ndc(dut, "ndc softap qccmd set hw_mode=g-only");
break;
case AP_11b:
run_ndc(dut, "ndc softap qccmd set hw_mode=b-only");
break;
case AP_11ng:
run_ndc(dut, "ndc softap qccmd set hw_mode=n");
break;
case AP_11a:
run_ndc(dut, "ndc softap qccmd set hw_mode=a-only");
break;
case AP_11na:
run_ndc(dut, "ndc softap qccmd set hw_mode=n");
break;
case AP_11ac:
run_ndc(dut, "ndc softap qccmd set hw_mode=ac");
break;
default:
break;
}
snprintf(buf, sizeof(buf), "ndc softap qccmd set channel=%d",
dut->ap_channel);
run_ndc(dut, buf);
/*
* ndc doesn't support double quotes as SSID string, so re-write
* hostapd configuration file to update SSID.
*/
if (dut->ap_ssid[0] != '\0')
sigma_write_cfg(dut, ANDROID_CONFIG_FILE, "ssid", dut->ap_ssid);
switch (dut->ap_key_mgmt) {
case AP_OPEN:
if (dut->ap_cipher == AP_WEP) {
run_ndc(dut, "ndc softap qccmd set security_mode=1");
snprintf(buf, sizeof(buf),
"ndc softap qccmd set wep_key0=%s",
dut->ap_wepkey);
run_ndc(dut, buf);
} else {
run_ndc(dut, "ndc softap qccmd set security_mode=0");
}
break;
case AP_WPA2_PSK:
case AP_WPA2_PSK_MIXED:
case AP_WPA_PSK:
if (dut->ap_key_mgmt == AP_WPA2_PSK)
run_ndc(dut, "ndc softap qccmd set security_mode=3");
else if (dut->ap_key_mgmt == AP_WPA2_PSK_MIXED)
run_ndc(dut, "ndc softap qccmd set security_mode=4");
else
run_ndc(dut, "ndc softap qccmd set security_mode=2");
/*
* ndc doesn't support some special characters as passphrase,
* so re-write hostapd configuration file to update Passphrase.
*/
if (dut->ap_passphrase[0] != '\0')
sigma_write_cfg(dut, ANDROID_CONFIG_FILE,
"wpa_passphrase", dut->ap_passphrase);
if (dut->ap_cipher == AP_CCMP_TKIP)
run_ndc(dut, "ndc softap qccmd set wpa_pairwise="
"TKIP CCMP");
else if (dut->ap_cipher == AP_TKIP)
run_ndc(dut, "ndc softap qccmd set wpa_pairwise="
"TKIP");
else
run_ndc(dut, "ndc softap qccmd set wpa_pairwise="
"CCMP &");
break;
case AP_WPA2_SAE:
case AP_WPA2_PSK_SAE:
case AP_WPA2_EAP:
case AP_WPA2_EAP_MIXED:
case AP_WPA_EAP:
case AP_SUITEB:
case AP_WPA2_OWE:
case AP_WPA2_EAP_OSEN:
case AP_OSEN:
case AP_WPA2_FT_EAP:
case AP_WPA2_FT_PSK:
case AP_WPA2_EAP_SHA256:
case AP_WPA2_PSK_SHA256:
case AP_WPA2_ENT_FT_EAP:
/* Not supported */
break;
}
switch (dut->ap_pmf) {
case AP_PMF_DISABLED:
run_ndc(dut, "ndc softap qccmd set ieee80211w=0");
break;
case AP_PMF_OPTIONAL:
run_ndc(dut, "ndc softap qccmd set ieee80211w=1");
if (dut->ap_add_sha256)
run_ndc(dut, "ndc softap qccmd set wpa_key_mgmt=WPA-PSK WPA-PSK-SHA256");
else
run_ndc(dut, "ndc softap qccmd set wpa_key_mgmt=WPA-PSK");
break;
case AP_PMF_REQUIRED:
run_ndc(dut, "ndc softap qccmd set ieee80211w=2");
run_ndc(dut, "ndc softap qccmd set wpa_key_mgmt=WPA-PSK-SHA256");
break;
}
if (dut->ap_countrycode[0]) {
snprintf(buf, sizeof(buf),
"ndc softap qccmd set country_code=%s",
dut->ap_countrycode);
run_ndc(dut, buf);
}
if (dut->ap_regulatory_mode == AP_80211D_MODE_ENABLED)
run_ndc(dut, "ndc softap qccmd set ieee80211d=1");
if (dut->ap_dfs_mode == AP_DFS_MODE_ENABLED)
run_ndc(dut, "ndc softap qccmd set ieee80211h=1");
run_ndc(dut, "ndc softap startap");
snprintf(buf, sizeof(buf), "%s%s", sigma_wpas_ctrl, sigma_main_ifname);
num_tries = 0;
while (num_tries < 10 && (ret = stat(buf, &s) != 0)) {
run_ndc(dut, "ndc softap stopap");
run_ndc(dut, "ndc softap startap");
num_tries++;
}
if (num_tries == 10) {
sigma_dut_print(dut, DUT_MSG_INFO, "Tried 10 times with ctrl "
"iface %s :: reboot the APDUT", buf);
return ret;
}
sigma_dut_print(dut, DUT_MSG_INFO, "setting ip addr %s mask %s",
ap_inet_addr, ap_inet_mask);
snprintf(buf, sizeof(buf), "ifconfig %s %s netmask %s up",
sigma_main_ifname, ap_inet_addr, ap_inet_mask);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Failed to intialize the interface");
return -1;
}
return 1;
}
static int append_hostapd_conf_hs2(struct sigma_dut *dut, FILE *f)
{
fprintf(f, "hs20=1\nhs20_deauth_req_timeout=3\n"
"disable_dgaf=%d\n", dut->ap_dgaf_disable);
if (dut->ap_oper_name) {
fprintf(f, "hs20_oper_friendly_name=eng:Wi-Fi Alliance\n");
fprintf(f, "hs20_oper_friendly_name=chi:Wi-Fi\xe8\x81\x94\xe7\x9b\x9f\n");
}
if (dut->ap_wan_metrics == 1)
fprintf(f, "hs20_wan_metrics=01:2500:384:0:0:10\n");
else if (dut->ap_wan_metrics == 2)
fprintf(f, "hs20_wan_metrics=01:1500:384:20:20:10\n");
else if (dut->ap_wan_metrics == 3)
fprintf(f, "hs20_wan_metrics=01:2000:1000:20:20:10\n");
else if (dut->ap_wan_metrics == 4)
fprintf(f, "hs20_wan_metrics=01:8000:1000:20:20:10\n");
else if (dut->ap_wan_metrics == 5)
fprintf(f, "hs20_wan_metrics=01:9000:5000:20:20:10\n");
if (dut->ap_conn_capab == 1) {
fprintf(f, "hs20_conn_capab=1:0:0\n");
fprintf(f, "hs20_conn_capab=6:20:1\n");
fprintf(f, "hs20_conn_capab=6:22:0\n");
fprintf(f, "hs20_conn_capab=6:80:1\n");
fprintf(f, "hs20_conn_capab=6:443:1\n");
fprintf(f, "hs20_conn_capab=6:1723:0\n");
fprintf(f, "hs20_conn_capab=6:5060:0\n");
fprintf(f, "hs20_conn_capab=17:500:1\n");
fprintf(f, "hs20_conn_capab=17:5060:0\n");
fprintf(f, "hs20_conn_capab=17:4500:1\n");
fprintf(f, "hs20_conn_capab=50:0:1\n");
} else if (dut->ap_conn_capab == 2) {
fprintf(f, "hs20_conn_capab=6:80:1\n");
fprintf(f, "hs20_conn_capab=6:443:1\n");
fprintf(f, "hs20_conn_capab=17:5060:1\n");
fprintf(f, "hs20_conn_capab=6:5060:1\n");
} else if (dut->ap_conn_capab == 3) {
fprintf(f, "hs20_conn_capab=6:80:1\n");
fprintf(f, "hs20_conn_capab=6:443:1\n");
} else if (dut->ap_conn_capab == 4) {
fprintf(f, "hs20_conn_capab=6:80:1\n");
fprintf(f, "hs20_conn_capab=6:443:1\n");
fprintf(f, "hs20_conn_capab=6:5060:1\n");
fprintf(f, "hs20_conn_capab=17:5060:1\n");
}
if (dut->ap_oper_class == 1)
fprintf(f, "hs20_operating_class=51\n");
else if (dut->ap_oper_class == 2)
fprintf(f, "hs20_operating_class=73\n");
else if (dut->ap_oper_class == 3)
fprintf(f, "hs20_operating_class=5173\n");
if (dut->ap_osu_provider_list) {
char *osu_friendly_name = NULL;
char *osu_icon = NULL;
char *osu_ssid = NULL;
char *osu_nai = NULL;
char *osu_nai2 = NULL;
char *osu_service_desc = NULL;
char *hs20_icon_filename = NULL;
char hs20_icon[150];
int osu_method;
hs20_icon_filename = "icon_red_zxx.png";
if (dut->ap_osu_icon_tag == 2)
hs20_icon_filename = "wifi-abgn-logo_270x73.png";
snprintf(hs20_icon, sizeof(hs20_icon),
"128:61:zxx:image/png:icon_red_zxx.png:/etc/ath/%s",
hs20_icon_filename);
osu_icon = "icon_red_zxx.png";
osu_ssid = "OSU";
osu_friendly_name = "kor:SP 빨강 테스트 전용";
osu_service_desc = "kor:테스트 목적으로 무료 서비스";
osu_method = (dut->ap_osu_method[0] == 0xFF) ? 1 : dut->ap_osu_method[0];
if (strlen(dut->ap_osu_server_uri[0]))
fprintf(f, "osu_server_uri=%s\n", dut->ap_osu_server_uri[0]);
else
fprintf(f, "osu_server_uri=https://osu-server.r2-testbed.wi-fi.org/\n");
switch (dut->ap_osu_provider_list) {
case 1:
case 101:
fprintf(f, "osu_friendly_name=eng:SP Red Test Only\n");
fprintf(f, "osu_service_desc=eng:Free service for test purpose\n");
hs20_icon_filename = "icon_red_eng.png";
if (dut->ap_osu_icon_tag == 2)
hs20_icon_filename = "wifi-abgn-logo_270x73.png";
fprintf(f, "hs20_icon=160:76:eng:image/png:icon_red_eng.png:/etc/ath/%s\n",
hs20_icon_filename);
fprintf(f, "osu_icon=icon_red_eng.png\n");
break;
case 2:
case 102:
fprintf(f, "osu_friendly_name=eng:Wireless Broadband Alliance\n");
fprintf(f, "osu_service_desc=eng:Free service for test purpose\n");
hs20_icon_filename = "icon_orange_zxx.png";
if (dut->ap_osu_icon_tag == 2)
hs20_icon_filename = "wifi-abgn-logo_270x73.png";
snprintf(hs20_icon, sizeof(hs20_icon),
"128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s",
hs20_icon_filename);
osu_icon = "icon_orange_zxx.png";
osu_friendly_name = "kor:와이어리스 브로드밴드 얼라이언스";
break;
case 3:
case 103:
osu_friendly_name = "spa:SP Red Test Only";
osu_service_desc = "spa:Free service for test purpose";
break;
case 4:
case 104:
fprintf(f, "osu_friendly_name=eng:SP Orange Test Only\n");
fprintf(f, "osu_service_desc=eng:Free service for test purpose\n");
hs20_icon_filename = "icon_orange_eng.png";
if (dut->ap_osu_icon_tag == 2)
hs20_icon_filename = "wifi-abgn-logo_270x73.png";
fprintf(f, "hs20_icon=160:76:eng:image/png:icon_orange_eng.png:/etc/ath/%s\n",
hs20_icon_filename);
fprintf(f, "osu_icon=icon_orange_eng.png\n");
osu_friendly_name = "kor:SP 오렌지 테스트 전용";
hs20_icon_filename = "icon_orange_zxx.png";
if (dut->ap_osu_icon_tag == 2)
hs20_icon_filename = "wifi-abgn-logo_270x73.png";
snprintf(hs20_icon, sizeof(hs20_icon),
"128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s",
hs20_icon_filename);
osu_icon = "icon_orange_zxx.png";
break;
case 5:
case 105:
fprintf(f, "osu_friendly_name=eng:SP Orange Test Only\n");
fprintf(f, "osu_service_desc=eng:Free service for test purpose\n");
osu_friendly_name = "kor:SP 오렌지 테스트 전용";
hs20_icon_filename = "icon_orange_zxx.png";
if (dut->ap_osu_icon_tag == 2)
hs20_icon_filename = "wifi-abgn-logo_270x73.png";
snprintf(hs20_icon, sizeof(hs20_icon),
"128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s",
hs20_icon_filename);
osu_icon = "icon_orange_zxx.png";
break;
case 6:
case 106:
fprintf(f, "osu_friendly_name=eng:SP Green Test Only\n");
fprintf(f, "osu_friendly_name=kor:SP 초록 테스트 전용\n");
hs20_icon_filename = "icon_green_zxx.png";
if (dut->ap_osu_icon_tag == 2)
hs20_icon_filename = "wifi-abgn-logo_270x73.png";
fprintf(f, "hs20_icon=128:61:zxx:image/png:icon_green_zxx.png:/etc/ath/%s\n",
hs20_icon_filename);
fprintf(f, "osu_icon=icon_green_zxx.png\n");
osu_method = (dut->ap_osu_method[0] == 0xFF) ? 0 : dut->ap_osu_method[0];
fprintf(f, "osu_method_list=%d\n", osu_method);
if (strlen(dut->ap_osu_server_uri[1]))
fprintf(f, "osu_server_uri=%s\n", dut->ap_osu_server_uri[1]);
else
fprintf(f, "osu_server_uri=https://osu-server.r2-testbed.wi-fi.org/\n");
fprintf(f, "osu_friendly_name=eng:SP Orange Test Only\n");
hs20_icon_filename = "icon_orange_zxx.png";
if (dut->ap_osu_icon_tag == 2)
hs20_icon_filename = "wifi-abgn-logo_270x73.png";
snprintf(hs20_icon, sizeof(hs20_icon),
"128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s",
hs20_icon_filename);
osu_icon = "icon_orange_zxx.png";
osu_friendly_name = "kor:SP 오렌지 테스트 전용";
osu_method = (dut->ap_osu_method[1] == 0xFF) ? 0 : dut->ap_osu_method[1];
osu_service_desc = NULL;
break;
case 7:
case 107:
fprintf(f, "osu_friendly_name=eng:SP Green Test Only\n");
fprintf(f, "osu_service_desc=eng:Free service for test purpose\n");
hs20_icon_filename = "icon_green_eng.png";
if (dut->ap_osu_icon_tag == 2)
hs20_icon_filename = "wifi-abgn-logo_270x73.png";
fprintf(f, "hs20_icon=160:76:eng:image/png:icon_green_eng.png:/etc/ath/%s\n",
hs20_icon_filename);
fprintf(f, "osu_icon=icon_green_eng.png\n");
osu_friendly_name = "kor:SP 초록 테스트 전용";
hs20_icon_filename = "icon_green_zxx.png";
if (dut->ap_osu_icon_tag == 2)
hs20_icon_filename = "wifi-abgn-logo_270x73.png";
snprintf(hs20_icon, sizeof(hs20_icon),
"128:61:zxx:image/png:icon_green_zxx.png:/etc/ath/%s",
hs20_icon_filename);
osu_icon = "icon_green_zxx.png";
break;
case 8:
case 108:
fprintf(f, "osu_friendly_name=eng:SP Red Test Only\n");
fprintf(f, "osu_service_desc=eng:Free service for test purpose\n");
osu_ssid = "OSU-Encrypted";
osu_nai = "anonymous@hotspot.net";
break;
case 9:
case 109:
osu_ssid = "OSU-OSEN";
osu_nai = "test-anonymous@wi-fi.org";
osu_friendly_name = "eng:SP Orange Test Only";
hs20_icon_filename = "icon_orange_zxx.png";
if (dut->ap_osu_icon_tag == 2)
hs20_icon_filename = "wifi-abgn-logo_270x73.png";
snprintf(hs20_icon, sizeof(hs20_icon),
"128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s",
hs20_icon_filename);
osu_icon = "icon_orange_zxx.png";
osu_method = (dut->ap_osu_method[0] == 0xFF) ? 1 : dut->ap_osu_method[0];
osu_service_desc = NULL;
break;
case 10:
case 110:
/* OSU Provider #1 */
fprintf(f, "osu_friendly_name=eng:SP Orange Test Only\n");
fprintf(f, "osu_friendly_name=kor:SP 오렌지 테스트 전용\n");
fprintf(f, "hs20_icon=128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/icon_orange_zxx.png\n");
fprintf(f, "osu_icon=icon_orange_zxx.png\n");
osu_method = (dut->ap_osu_method[0] == 0xFF) ?
1 : dut->ap_osu_method[0];
fprintf(f, "osu_method_list=%d\n", osu_method);
fprintf(f, "osu_nai=test-anonymous@wi-fi.org\n");
switch (dut->ap_osu_provider_nai_list) {
case 3:
fprintf(f,
"osu_nai2=test-anonymous@wi-fi.org\n");
break;
case 4:
fprintf(f, "osu_nai2=random@hotspot.net\n");
break;
}
/* OSU Provider #2 */
/* SP Red from defaults */
if (strlen(dut->ap_osu_server_uri[1]))
fprintf(f, "osu_server_uri=%s\n", dut->ap_osu_server_uri[1]);
else
fprintf(f, "osu_server_uri=https://osu-server.r2-testbed.wi-fi.org/\n");
fprintf(f, "osu_friendly_name=eng:SP Red Test Only\n");
snprintf(hs20_icon, sizeof(hs20_icon),
"128:61:zxx:image/png:icon_red_zxx.png:/etc/ath/icon_red_zxx.png");
osu_method = (dut->ap_osu_method[1] == 0xFF) ?
1 : dut->ap_osu_method[1];
osu_service_desc = NULL;
osu_nai = "anonymous@hotspot.net";
break;
default:
break;
}
switch (dut->ap_osu_provider_nai_list) {
case 1:
osu_nai2 = "anonymous@hotspot.net";
break;
case 2:
osu_nai2 = "test-anonymous@wi-fi.org";
break;
case 3:
/* OSU Provider NAI #1 written above */
/* OSU Provider NAI #2 */
osu_nai2 = "anonymous@hotspot.net";
break;
case 4:
/* OSU Provider NAI #1 written above */
/* OSU Provider NAI #2 */
osu_nai2 = "anonymous@hotspot.net";
break;
}
if (strlen(dut->ap_osu_ssid)) {
if (dut->ap_tag_ssid[0][0] &&
strcmp(dut->ap_tag_ssid[0], dut->ap_osu_ssid) &&
strcmp(dut->ap_tag_ssid[0], osu_ssid)) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"OSU_SSID and "
"WLAN_TAG2 SSID differ");
return -2;
}
fprintf(f, "osu_ssid=\"%s\"\n", dut->ap_osu_ssid);
} else
fprintf(f, "osu_ssid=\"%s\"\n", osu_ssid);
if (osu_friendly_name)
fprintf(f, "osu_friendly_name=%s\n", osu_friendly_name);
if (osu_service_desc)
fprintf(f, "osu_service_desc=%s\n", osu_service_desc);
if (osu_nai)
fprintf(f, "osu_nai=%s\n", osu_nai);
if (osu_nai2)
fprintf(f, "osu_nai2=%s\n", osu_nai2);
fprintf(f, "hs20_icon=%s\n", hs20_icon);
if (osu_icon)
fprintf(f, "osu_icon=%s\n", osu_icon);
if (dut->ap_osu_provider_list > 100)
fprintf(f, "osu_method_list=0\n");
else
fprintf(f, "osu_method_list=%d\n", osu_method);
}
switch (dut->ap_venue_url) {
case 1:
fprintf(f,
"venue_url=1:https://venue-server.r2m-testbed.wi-fi.org/floorplans/index.html\n"
"venue_url=1:https://venue-server.r2m-testbed.wi-fi.org/directory/index.html\n");
break;
case 2:
fprintf(f,
"venue_url=1:https://the-great-mall.r2m-testbed.wi-fi.org/floorplans/index.html\n"
"venue_url=2:https://abercrombie.r2m-testbed.wi-fi.org/floorplans/index.html\n"
"venue_url=3:https://adidas.r2m-testbed.wi-fi.org/floorplans/index.html\n"
"venue_url=4:https://aeropostale.r2m-testbed.wi-fi.org/floorplans/index.html\n"
"venue_url=5:https://agaci.r2m-testbed.wi-fi.org/floorplans/index.html\n"
"venue_url=6:https://aldo-shoes.r2m-testbed.wi-fi.org/floorplans/index.html\n"
"venue_url=7:https://american-eagle-outfitters.r2m-testbed.wi-fi.org/floorplans/index.html\n"
"venue_url=8:https://anderson-bakery.r2m-testbed.wi-fi.org/floorplans/index.html\n"
"venue_url=9:https://banana-republic-factory-store.r2m-testbed.wi-fi.org/floorplans/index.html\n"
"venue_url=10:https://bed-bath-and-beyond.r2m-testbed.wi-fi.org/floorplans/index.html\n"
);
break;
}
switch (dut->ap_advice_of_charge) {
case 1:
fprintf(f, "anqp_elem=278:" ADV_OF_CHARGE_1 "\n");
break;
}
switch (dut->ap_oper_icon_metadata) {
case 1:
fprintf(f,
"hs20_icon=160:76:eng:image/png:icon_red_eng.png:/etc/ath/icon_red_eng.png\n"
"operator_icon=icon_red_eng.png\n");
break;
}
switch (dut->ap_tnc_file_name) {
case 1:
fprintf(f, "hs20_t_c_filename=tandc-id1-content.txt\n");
break;
}
if (dut->ap_tnc_time_stamp)
fprintf(f, "hs20_t_c_timestamp=%u\n", dut->ap_tnc_time_stamp);
return 0;
}
static void write_ap_roaming_cons(FILE *f, const char *list)
{
char *buf, *pos, *end;
if (list == NULL || list[0] == '\0')
return;
buf = strdup(list);
if (buf == NULL)
return;
pos = buf;
while (pos && *pos) {
end = strchr(pos, ';');
if (end)
*end++ = '\0';
fprintf(f, "roaming_consortium=%s\n", pos);
pos = end;
}
free(buf);
}
static int append_hostapd_conf_interworking(struct sigma_dut *dut, FILE *f)
{
int i;
char buf[100], *temp;
if (dut->ap_gas_cb_delay > 0)
fprintf(f, "gas_comeback_delay=%d\n",
dut->ap_gas_cb_delay);
fprintf(f, "interworking=1\n"
"access_network_type=%d\n"
"internet=%d\n"
"asra=0\n"
"esr=0\n"
"uesa=0\n"
"venue_group=%d\n"
"venue_type=%d\n",
dut->ap_access_net_type,
dut->ap_internet,
dut->ap_venue_group,
dut->ap_venue_type);
if (dut->ap_hessid[0])
fprintf(f, "hessid=%s\n", dut->ap_hessid);
write_ap_roaming_cons(f, dut->ap_roaming_cons);
if (dut->ap_venue_name) {
fprintf(f, "venue_name=P\"eng:Wi-Fi Alliance\\n2989 Copper Road\\nSanta Clara, CA 95051, USA\"\n");
fprintf(f, "venue_name=%s\n", ANQP_VENUE_NAME_1_CHI);
}
if (dut->ap_net_auth_type == 1)
fprintf(f, "network_auth_type=00https://tandc-server.wi-fi.org\n");
else if (dut->ap_net_auth_type == 2)
fprintf(f, "network_auth_type=01\n");
if (dut->ap_nai_realm_list == 1) {
fprintf(f, "nai_realm=0,mail.example.com;cisco.com;wi-fi.org,21[2:4][5:7]\n");
fprintf(f, "nai_realm=0,wi-fi.org;example.com,13[5:6]\n");
} else if (dut->ap_nai_realm_list == 2) {
fprintf(f, "nai_realm=0,wi-fi.org,21[2:4][5:7]\n");
} else if (dut->ap_nai_realm_list == 3) {
fprintf(f, "nai_realm=0,cisco.com;wi-fi.org,21[2:4][5:7]\n");
fprintf(f, "nai_realm=0,wi-fi.org;example.com,13[5:6]\n");
} else if (dut->ap_nai_realm_list == 4) {
fprintf(f, "nai_realm=0,mail.example.com,21[2:4][5:7],13[5:6]\n");
} else if (dut->ap_nai_realm_list == 5) {
fprintf(f, "nai_realm=0,wi-fi.org;ruckuswireless.com,21[2:4][5:7]\n");
} else if (dut->ap_nai_realm_list == 6) {
fprintf(f, "nai_realm=0,wi-fi.org;mail.example.com,21[2:4][5:7]\n");
} else if (dut->ap_nai_realm_list == 7) {
fprintf(f, "nai_realm=0,wi-fi.org,13[5:6]\n");
fprintf(f, "nai_realm=0,wi-fi.org,21[2:4][5:7]\n");
}
if (dut->ap_domain_name_list[0]) {
fprintf(f, "domain_name=%s\n",
dut->ap_domain_name_list);
}
if (dut->ap_ip_addr_type_avail == 1) {
fprintf(f, "ipaddr_type_availability=0c\n");
}
temp = buf;
for (i = 0; dut->ap_plmn_mcc[i][0] && dut->ap_plmn_mnc[i][0];
i++) {
if (i)
*temp++ = ';';
snprintf(temp,
sizeof(dut->ap_plmn_mcc[i]) +
sizeof(dut->ap_plmn_mnc[i]) + 1,
"%s,%s",
dut->ap_plmn_mcc[i],
dut->ap_plmn_mnc[i]);
temp += strlen(dut->ap_plmn_mcc[i]) +
strlen(dut->ap_plmn_mnc[i]) + 1;
}
if (i)
fprintf(f, "anqp_3gpp_cell_net=%s\n", buf);
if (dut->ap_qos_map_set == 1)
fprintf(f, "qos_map_set=%s\n", QOS_MAP_SET_1);
else if (dut->ap_qos_map_set == 2)
fprintf(f, "qos_map_set=%s\n", QOS_MAP_SET_2);
return 0;
}
static int ath_ap_append_hostapd_conf(struct sigma_dut *dut)
{
FILE *f;
if (kill_process(dut, "(hostapd)", 1, SIGTERM) == 0 ||
system("killall hostapd") == 0) {
int i;
/* Wait some time to allow hostapd to complete cleanup before
* starting a new process */
for (i = 0; i < 10; i++) {
usleep(500000);
if (system("pidof hostapd") != 0)
break;
}
}
f = fopen("/tmp/secath0", "a");
if (f == NULL)
return -2;
if (dut->ap_hs2 && append_hostapd_conf_hs2(dut, f)) {
fclose(f);
return -2;
}
if (dut->ap_interworking && append_hostapd_conf_interworking(dut, f)) {
fclose(f);
return -2;
}
fflush(f);
fclose(f);
return ath_ap_start_hostapd(dut);
}
static int ath_ap_start_hostapd(struct sigma_dut *dut)
{
if (dut->ap_tag_key_mgmt[0] == AP2_OSEN)
run_system(dut, "hostapd -B /tmp/secath0 /tmp/secath1 -e /etc/wpa2/entropy");
else
run_system(dut, "hostapd -B /tmp/secath0 -e /etc/wpa2/entropy");
return 0;
}
#define LE16(a) ((((a) & 0xff) << 8) | (((a) >> 8) & 0xff))
static int cmd_ath_ap_anqpserver_start(struct sigma_dut *dut)
{
FILE *f;
int nai_realm = 0, domain_name = 0, oper_name = 0, venue_name = 0,
wan_metrics = 0, conn_cap = 0, ipaddr_avail = 0, cell_net = 0;
char buf[100];
int i;
f = fopen("/root/anqpserver.conf", "w");
if (f == NULL)
return -1;
if (dut->ap_nai_realm_list == 1) {
nai_realm = 1;
fprintf(f, "dyn_nai_home_realm=encoding=00realm=mail.example.com;eap_method=15auth_id=02auth_val=04auth_id=05auth_val=07encoding=00realm=cisco.com;eap_method=15auth_id=02auth_val=04auth_id=05auth_val=07encoding=00realm=wi-fi.org;eap_method=15auth_id=02auth_val=04auth_id=05auth_val=07encoding=00realm=example.com;eap_method=0Dauth_id=05auth_val=06encoding=00realm=wi-fi.org;eap_method=0Dauth_id=05auth_val=06\n");
} else if (dut->ap_nai_realm_list == 2) {
nai_realm = 1;
fprintf(f, "dyn_nai_home_realm=encoding=00realm=wi-fi.org;eap_method=0Dauth_id=05auth_val=06\n");
} else if (dut->ap_nai_realm_list == 3) {
nai_realm = 1;
fprintf(f, "dyn_nai_home_realm=encoding=00realm=cisco.com;eap_method=15auth_id=02auth_val=04auth_id=05auth_val=07encoding=00realm=wi-fi.org;eap_method=15auth_id=02auth_val=04auth_id=05auth_val=07encoding=00realm=example.com;eap_method=0Dauth_id=05auth_val=06encoding=00realm=wi-fi.org;eap_method=0Dauth_id=05auth_val=06\n");
} else if (dut->ap_nai_realm_list == 4) {
nai_realm = 1;
fprintf(f, "dyn_nai_home_realm=encoding=00realm=mail.example.com;eap_method=15auth_id=02auth_val=04auth_id=05auth_val=07encoding=00realm=mail.example.com;eap_method=0Dauth_id=05auth_val=06\n");
} else
sigma_dut_print(dut, DUT_MSG_INFO, "not setting nai_realm");
if (dut->ap_domain_name_list[0]) {
char *next, *start, *dnbuf, *dn1, *anqp_dn;
int len, dn_len_max;
dnbuf = strdup(dut->ap_domain_name_list);
if (dnbuf == NULL) {
fclose(f);
return 0;
}
len = strlen(dnbuf);
dn_len_max = 50 + len*2;
anqp_dn = malloc(dn_len_max);
if (anqp_dn == NULL) {
free(dnbuf);
fclose(f);
return -1;
}
start = dnbuf;
dn1 = anqp_dn;
while (start && *start) {
char *hexstr;
next = strchr(start, ',');
if (next)
*next++ = '\0';
len = strlen(start);
hexstr = malloc(len * 2 + 1);
if (hexstr == NULL) {
free(dnbuf);
free(anqp_dn);
fclose(f);
return -1;
}
ascii2hexstr(start, hexstr);
snprintf(dn1, dn_len_max, "%02x%s", len, hexstr);
free(hexstr);
dn1 += 2 + len * 2;
dn_len_max -= 2 + len * 2;
start = next;
}
free(dnbuf);
if (dut->ap_gas_cb_delay) {
fprintf(f, "dyn_domain_name=0c01%04x%s",
LE16((unsigned int) strlen(anqp_dn)), anqp_dn);
domain_name = 1;
} else
fprintf(f, "domain_name=0c01%04x%s",
LE16((unsigned int) strlen(anqp_dn)), anqp_dn);
free(anqp_dn);
} else
sigma_dut_print(dut, DUT_MSG_INFO, "not setting domain_name");
sigma_dut_print(dut, DUT_MSG_INFO, "not setting roaming_consortium");
if (dut->ap_oper_name) {
if (dut->ap_gas_cb_delay) {
fprintf(f, "dyn_oper_friendly_name="
ANQP_HS20_OPERATOR_FRIENDLY_NAME_1 "\n");
oper_name = 1;
} else
fprintf(f, "oper_friendly_name="
ANQP_HS20_OPERATOR_FRIENDLY_NAME_1 "\n");
} else
sigma_dut_print(dut, DUT_MSG_INFO, "not setting oper_name");
if (dut->ap_venue_name) {
if (dut->ap_gas_cb_delay) {
fprintf(f, "dyn_venue_name=" ANQP_VENUE_NAME_1 "\n");
venue_name = 1;
} else
fprintf(f, "venue_name=" ANQP_VENUE_NAME_1 "\n");
} else
sigma_dut_print(dut, DUT_MSG_ERROR, "not setting venue_name");
if (dut->ap_wan_metrics) {
if (dut->ap_gas_cb_delay) {
fprintf(f, "dyn_wan_metrics=" ANQP_HS20_WAN_METRICS_1 "\n");
wan_metrics = 1;
} else
fprintf(f, "wan_metrics=" ANQP_HS20_WAN_METRICS_1
"\n");
} else
sigma_dut_print(dut, DUT_MSG_ERROR, "not setting wan_metrics");
if (dut->ap_conn_capab) {
if (dut->ap_gas_cb_delay) {
fprintf(f, "dyn_conn_capability="
ANQP_HS20_CONNECTION_CAPABILITY_1 "\n");
conn_cap = 1;
} else
fprintf(f, "conn_capability="
ANQP_HS20_CONNECTION_CAPABILITY_1 "\n");
} else
sigma_dut_print(dut, DUT_MSG_ERROR,
"not setting conn_capability");
if (dut->ap_ip_addr_type_avail) {
if (dut->ap_gas_cb_delay) {
fprintf(f, "dyn_ipaddr_type=" ANQP_IP_ADDR_TYPE_1
"\n");
ipaddr_avail = 1;
} else
fprintf(f, "ipaddr_type=" ANQP_IP_ADDR_TYPE_1 "\n");
} else
sigma_dut_print(dut, DUT_MSG_ERROR,
"not setting ipaddr_type_avail");
for (i = 0; dut->ap_plmn_mcc[i][0] && dut->ap_plmn_mnc[i][0]; i++) {
snprintf(buf + i * 6, sizeof(buf) - i * 6, "%c%c%c%c%c%c",
dut->ap_plmn_mcc[i][1],
dut->ap_plmn_mcc[i][0],
dut->ap_plmn_mnc[i][2] == '\0' ?
'f' : dut->ap_plmn_mnc[i][2],
dut->ap_plmn_mcc[i][2],
dut->ap_plmn_mnc[i][1],
dut->ap_plmn_mnc[i][0]);
}
if (i) {
uint16_t ie_len = (i * 3) + 5;
if (dut->ap_gas_cb_delay) {
fprintf(f, "dyn_cell_net=0801");
cell_net = 1;
} else
fprintf(f, "cell_net=0801");
fprintf(f, "%04x", LE16(ie_len));
fprintf(f, "00"); /* version */
fprintf(f, "%02x", (i * 3) + 3); /* user data hdr length */
fprintf(f, "00"); /* plmn list */
fprintf(f, "%02x", (i * 3) + 1); /* length of plmn list */
fprintf(f, "%02x", i); /* number of plmns */
fprintf(f, "%s\n", buf); /* plmns */
} else
sigma_dut_print(dut, DUT_MSG_ERROR,
"not setting 3gpp_cellular_network");
if (nai_realm || domain_name || oper_name || venue_name ||
wan_metrics || conn_cap || ipaddr_avail || cell_net) {
fprintf(f, "anqp_attach=");
if (venue_name)
fprintf(f, "00000104%4.4x", dut->ap_gas_cb_delay);
if (nai_realm)
fprintf(f, "00000107%4.4x", dut->ap_gas_cb_delay);
if (cell_net)
fprintf(f, "00000108%4.4x", dut->ap_gas_cb_delay);
if (domain_name)
fprintf(f, "0000010c%4.4x", dut->ap_gas_cb_delay);
if (oper_name)
fprintf(f, "00010003%4.4x", dut->ap_gas_cb_delay);
if (wan_metrics)
fprintf(f, "00010004%4.4x", dut->ap_gas_cb_delay);
if (conn_cap)
fprintf(f, "00010005%4.4x", dut->ap_gas_cb_delay);
fprintf(f, "00010006%4.4x", dut->ap_gas_cb_delay);
fprintf(f, "\n");
}
fclose(f);
run_system(dut, "anqpserver -i ath0 &");
if (!dut->ap_anqpserver_on)
run_system(dut, "killall anqpserver");
return 1;
}
static void cmd_ath_ap_radio_config(struct sigma_dut *dut)
{
char buf[100];
run_system(dut, "cfg -a AP_STARTMODE=standard");
if (sigma_radio_ifname[0] &&
strcmp(sigma_radio_ifname[0], "wifi1") == 0) {
run_system(dut, "cfg -a AP_RADIO_ID=1");
switch (dut->ap_mode) {
case AP_11g:
run_system(dut, "cfg -a AP_CHMODE_2=11G");
break;
case AP_11b:
run_system(dut, "cfg -a AP_CHMODE_2=11B");
break;
case AP_11ng:
run_system(dut, "cfg -a AP_CHMODE_2=11NGHT20");
break;
case AP_11a:
run_system(dut, "cfg -a AP_CHMODE_2=11A");
break;
case AP_11na:
run_system(dut, "cfg -a AP_CHMODE_2=11NAHT20");
break;
case AP_11ac:
run_system(dut, "cfg -a AP_CHMODE_2=11ACVHT80");
break;
default:
run_system(dut, "cfg -a AP_CHMODE_2=11ACVHT80");
break;
}
switch (dut->ap_rx_streams) {
case 1:
run_system(dut, "cfg -a RX_CHAINMASK_2=1");
break;
case 2:
run_system(dut, "cfg -a RX_CHAINMASK_2=3");
break;
case 3:
run_system(dut, "cfg -a RX_CHAINMASK_2=7");
break;
}
switch (dut->ap_tx_streams) {
case 1:
run_system(dut, "cfg -a TX_CHAINMASK_2=1");
break;
case 2:
run_system(dut, "cfg -a TX_CHAINMASK_2=3");
break;
case 3:
run_system(dut, "cfg -a TX_CHAINMASK_2=7");
break;
}
switch (dut->ap_chwidth) {
case AP_20:
run_system(dut, "cfg -a AP_CHMODE_2=11ACVHT20");
break;
case AP_40:
run_system(dut, "cfg -a AP_CHMODE_2=11ACVHT40");
break;
case AP_80:
run_system(dut, "cfg -a AP_CHMODE_2=11ACVHT80");
break;
case AP_160:
case AP_AUTO:
default:
run_system(dut, "cfg -a AP_CHMODE_2=11ACVHT80");
break;
}
if (dut->ap_tx_stbc) {
run_system(dut, "cfg -a TX_STBC_2=1");
}
snprintf(buf, sizeof(buf), "cfg -a AP_PRIMARY_CH_2=%d",
dut->ap_channel);
if (dut->ap_is_dual) {
switch (dut->ap_mode_1) {
case AP_11g:
run_system(dut, "cfg -a AP_CHMODE=11G");
break;
case AP_11b:
run_system(dut, "cfg -a AP_CHMODE=11B");
break;
case AP_11ng:
run_system(dut, "cfg -a AP_CHMODE=11NGHT20");
break;
case AP_11a:
run_system(dut, "cfg -a AP_CHMODE=11A");
break;
case AP_11na:
run_system(dut, "cfg -a AP_CHMODE=11NAHT20");
break;
case AP_11ac:
run_system(dut, "cfg -a AP_CHMODE=11ACVHT80");
break;
default:
run_system(dut, "cfg -a AP_CHMODE=11NGHT20");
break;
}
snprintf(buf, sizeof(buf), "cfg -a AP_PRIMARY_CH=%d",
dut->ap_channel_1);
}
run_system(dut, buf);
} else {
run_system(dut, "cfg -a AP_RADIO_ID=0");
switch (dut->ap_mode) {
case AP_11g:
run_system(dut, "cfg -a AP_CHMODE=11G");
break;
case AP_11b:
run_system(dut, "cfg -a AP_CHMODE=11B");
break;
case AP_11ng:
run_system(dut, "cfg -a AP_CHMODE=11NGHT20");
break;
case AP_11a:
run_system(dut, "cfg -a AP_CHMODE=11A");
break;
case AP_11na:
run_system(dut, "cfg -a AP_CHMODE=11NAHT20");
break;
case AP_11ac:
run_system(dut, "cfg -a AP_CHMODE=11ACVHT80");
break;
default:
run_system(dut, "cfg -a AP_CHMODE=11NGHT20");
break;
}
snprintf(buf, sizeof(buf), "cfg -a AP_PRIMARY_CH=%d",
dut->ap_channel);
run_system(dut, buf);
}
if (dut->ap_sgi80 == 1) {
run_system(dut, "cfg -a SHORTGI=1");
run_system(dut, "cfg -a SHORTGI_2=1");
} else if (dut->ap_sgi80 == 0) {
run_system(dut, "cfg -a SHORTGI=0");
run_system(dut, "cfg -a SHORTGI_2=0");
}
if (dut->ap_ldpc == VALUE_ENABLED)
run_system(dut, "cfg -a LDPC=1");
else if (dut->ap_ldpc == VALUE_DISABLED)
run_system(dut, "cfg -a LDPC=0");
}
void ath_disable_txbf(struct sigma_dut *dut, const char *intf)
{
char buf[50];
snprintf(buf, sizeof(buf), "iwpriv %s vhtsubfee 0", intf);
if (system(buf) != 0)
sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv vhtsubfee failed");
snprintf(buf, sizeof(buf), "iwpriv %s vhtsubfer 0", intf);
if (system(buf) != 0)
sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv vhtsubfer failed");
snprintf(buf, sizeof(buf), "iwpriv %s vhtmubfee 0", intf);
if (system(buf) != 0)
sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv vhtmubfee failed");
snprintf(buf, sizeof(buf), "iwpriv %s vhtmubfer 0", intf);
if (system(buf) != 0)
sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv vhtmubfer failed");
}
static void ath_set_assoc_disallow(struct sigma_dut *dut, const char *ifname,
const char *val)
{
if (strcasecmp(val, "enable") == 0) {
run_system_wrapper(dut, "iwpriv %s mbo_asoc_dis 1", ifname);
} else if (strcasecmp(val, "disable") == 0) {
run_system_wrapper(dut, "iwpriv %s mbo_asoc_dis 0", ifname);
} else {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Unsupported assoc_disallow");
}
}
static void apply_mbo_pref_ap_list(struct sigma_dut *dut)
{
int i;
int least_pref = 1 << 8;
char ifname[20];
uint8_t self_mac[ETH_ALEN];
char buf[200];
int ap_ne_class, ap_ne_pref, ap_ne_op_ch;
get_if_name(dut, ifname, sizeof(ifname), 1);
get_hwaddr(ifname, self_mac);
/* Clear off */
snprintf(buf, sizeof(buf),
"wifitool %s setbssidpref 00:00:00:00:00:00 0 0 0",
ifname);
run_system(dut, buf);
/* Find the least preference number */
for (i = 0; i < dut->mbo_pref_ap_cnt; i++) {
unsigned char *mac_addr = dut->mbo_pref_aps[i].mac_addr;
ap_ne_class = 1;
ap_ne_pref = 255;
ap_ne_op_ch = 1;
if (dut->mbo_pref_aps[i].ap_ne_pref != -1)
ap_ne_pref = dut->mbo_pref_aps[i].ap_ne_pref;
if (dut->mbo_pref_aps[i].ap_ne_class != -1)
ap_ne_class = dut->mbo_pref_aps[i].ap_ne_class;
if (dut->mbo_pref_aps[i].ap_ne_op_ch != -1)
ap_ne_op_ch = dut->mbo_pref_aps[i].ap_ne_op_ch;
if (ap_ne_pref < least_pref)
least_pref = ap_ne_pref;
snprintf(buf, sizeof(buf),
"wifitool %s setbssidpref %02x:%02x:%02x:%02x:%02x:%02x %d %d %d",
ifname, mac_addr[0], mac_addr[1], mac_addr[2],
mac_addr[3], mac_addr[4], mac_addr[5],
ap_ne_pref, ap_ne_class, ap_ne_op_ch);
run_system(dut, buf);
}
/* Now add the self AP Address */
if (dut->mbo_self_ap_tuple.ap_ne_class == -1) {
if (dut->ap_channel <= 11)
ap_ne_class = 81;
else
ap_ne_class = 115;
} else {
ap_ne_class = dut->mbo_self_ap_tuple.ap_ne_class;
}
if (dut->mbo_self_ap_tuple.ap_ne_op_ch == -1)
ap_ne_op_ch = dut->ap_channel;
else
ap_ne_op_ch = dut->mbo_self_ap_tuple.ap_ne_op_ch;
if (dut->mbo_self_ap_tuple.ap_ne_pref == -1)
ap_ne_pref = least_pref - 1;
else
ap_ne_pref = dut->mbo_self_ap_tuple.ap_ne_pref;
snprintf(buf, sizeof(buf),
"wifitool %s setbssidpref %02x:%02x:%02x:%02x:%02x:%02x %d %d %d",
ifname, self_mac[0], self_mac[1], self_mac[2],
self_mac[3], self_mac[4], self_mac[5],
ap_ne_pref,
ap_ne_class,
ap_ne_op_ch);
run_system(dut, buf);
}
static void ath_ap_set_params(struct sigma_dut *dut)
{
const char *basedev = "wifi0";
const char *basedev_radio = "wifi1";
char *ifname = get_main_ifname();
char *ifname_dual;
int i;
char buf[300];
if (sigma_radio_ifname[0])
basedev = sigma_radio_ifname[0];
if (dut->ap_is_dual == 1) {
basedev = sigma_radio_ifname[0];
basedev_radio = sigma_radio_ifname[1];
if (sigma_radio_ifname[0] &&
strcmp(sigma_radio_ifname[0], "wifi0") == 0) {
ifname = "ath0";
ifname_dual = "ath1";
} else {
ifname = "ath1";
ifname_dual = "ath0";
}
}
if (dut->ap_countrycode[0]) {
snprintf(buf, sizeof(buf), "iwpriv %s setCountry %s",
basedev, dut->ap_countrycode);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"iwpriv setCountry failed");
}
sigma_dut_print(dut, DUT_MSG_INFO, "Set countrycode");
}
for (i = 0; i < NUM_AP_AC; i++) {
if (dut->ap_qos[i].ac) {
snprintf(buf, sizeof(buf), "iwpriv %s cwmin %d 0 %d",
ifname, i, dut->ap_qos[i].cwmin);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"iwpriv cwmin failed");
}
snprintf(buf, sizeof(buf), "iwpriv %s cwmax %d 0 %d",
ifname, i, dut->ap_qos[i].cwmax);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"iwpriv cwmax failed");
}
snprintf(buf, sizeof(buf), "iwpriv %s aifs %d 0 %d",
ifname, i, dut->ap_qos[i].aifs);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"iwpriv aifs failed");
}
snprintf(buf, sizeof(buf),
"iwpriv %s txoplimit %d 0 %d",
ifname, i, dut->ap_qos[i].txop);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"iwpriv txoplimit failed");
}
snprintf(buf, sizeof(buf), "iwpriv %s acm %d 0 %d",
ifname, i, dut->ap_qos[i].acm);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"iwpriv acm failed");
}
}
}
for (i = 0; i < NUM_AP_AC; i++) {
if (dut->ap_sta_qos[i].ac) {
snprintf(buf, sizeof(buf), "iwpriv %s cwmin %d 1 %d",
ifname, i, dut->ap_sta_qos[i].cwmin);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"iwpriv cwmin failed");
}
snprintf(buf, sizeof(buf), "iwpriv %s cwmax %d 1 %d",
ifname, i, dut->ap_sta_qos[i].cwmax);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"iwpriv cwmax failed");
}
snprintf(buf, sizeof(buf), "iwpriv %s aifs %d 1 %d",
ifname, i, dut->ap_sta_qos[i].aifs);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"iwpriv aifs failed");
}
snprintf(buf, sizeof(buf),
"iwpriv %s txoplimit %d 1 %d",
ifname, i, dut->ap_sta_qos[i].txop);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"iwpriv txoplimit failed");
}
snprintf(buf, sizeof(buf), "iwpriv %s acm %d 1 %d",
ifname, i, dut->ap_sta_qos[i].acm);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"iwpriv acm failed");
}
}
}
if (dut->ap_disable_protection == 1) {
snprintf(buf, sizeof(buf), "iwpriv %s enablertscts 0", ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"iwpriv enablertscts failed");
}
sigma_dut_print(dut, DUT_MSG_INFO, "Disabled rtscts");
}
if (dut->ap_ldpc == VALUE_ENABLED) {
snprintf(buf, sizeof(buf), "iwpriv %s ldpc 3", ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"iwpriv ldpc 3 failed");
}
} else if (dut->ap_ldpc == VALUE_DISABLED) {
snprintf(buf, sizeof(buf), "iwpriv %s ldpc 0", ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"iwpriv ldpc 0 failed");
}
}
if (dut->ap_ampdu == VALUE_ENABLED) {
snprintf(buf, sizeof(buf), "iwpriv %s ampdu 1", ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"iwpriv ampdu 1 failed");
}
} else if (dut->ap_ampdu == VALUE_DISABLED) {
snprintf(buf, sizeof(buf), "iwpriv %s ampdu 0", ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"iwpriv ampdu 0 failed");
}
}
if (dut->ap_ampdu_exp) {
if (dut->program == PROGRAM_VHT) {
snprintf(buf, sizeof(buf), "iwpriv %s vhtmaxampdu %d",
ifname, dut->ap_ampdu_exp);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"iwpriv vhtmaxampdu failed");
}
} else {
/* 11N */
snprintf(buf, sizeof(buf), "iwpriv %s maxampdu %d",
ifname, dut->ap_ampdu_exp);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv maxampdu failed");
}
}
}
if (dut->ap_noack == VALUE_ENABLED) {
snprintf(buf, sizeof(buf), "iwpriv %s noackpolicy 0 0 1", ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv noackpolicy 0 0 1 failed");
}
snprintf(buf, sizeof(buf), "iwpriv %s noackpolicy 1 0 1", ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv noackpolicy 1 0 1 failed");
}
snprintf(buf, sizeof(buf), "iwpriv %s noackpolicy 2 0 1", ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv noackpolicy 2 0 1 failed");
}
snprintf(buf, sizeof(buf), "iwpriv %s noackpolicy 3 0 1", ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv noackpolicy 3 0 1 failed");
}
} else if (dut->ap_noack == VALUE_DISABLED) {
snprintf(buf, sizeof(buf), "iwpriv %s noackpolicy 0 0 0", ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv noackpolicy 0 0 0 failed");
}
snprintf(buf, sizeof(buf), "iwpriv %s noackpolicy 1 0 0", ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv noackpolicy 1 0 0 failed");
}
snprintf(buf, sizeof(buf), "iwpriv %s noackpolicy 2 0 0", ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv noackpolicy 2 0 0 failed");
}
snprintf(buf, sizeof(buf), "iwpriv %s noackpolicy 3 0 0", ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv noackpolicy 3 0 0 failed");
}
}
if (dut->device_type == AP_testbed && dut->ap_vhtmcs_map) {
snprintf(buf, sizeof(buf), "iwpriv %s vht_mcsmap 0x%04x",
ifname, dut->ap_vhtmcs_map);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"iwpriv vht_mcsmap failed");
}
}
if (dut->ap_amsdu == VALUE_ENABLED) {
snprintf(buf, sizeof(buf), "iwpriv %s amsdu 2", ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv amsdu 2 failed");
}
} else if (dut->ap_amsdu == VALUE_DISABLED) {
snprintf(buf, sizeof(buf), "iwpriv %s amsdu 1", ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv amsdu 1 failed");
}
}
if (dut->ap_rx_amsdu == VALUE_ENABLED) {
snprintf(buf, sizeof(buf), "iwpriv wifi1 rx_amsdu 1");
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv rx_amsdu 1 failed");
}
} else if (dut->ap_rx_amsdu == VALUE_DISABLED) {
snprintf(buf, sizeof(buf), "iwpriv wifi1 rx_amsdu 0");
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv rx_amsdu 0 failed");
}
}
/* Command sequence to generate single VHT AMSDU and MPDU */
if (dut->ap_addba_reject != VALUE_NOT_SET &&
dut->ap_ampdu == VALUE_DISABLED &&
dut->ap_amsdu == VALUE_ENABLED) {
snprintf(buf, sizeof(buf), "iwpriv %s setaddbaoper 1", ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"iwpriv setaddbaoper 1 failed");
}
snprintf(buf, sizeof(buf),
"wifitool %s senddelba 1 0 1 4", ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"wifitool senddelba failed");
}
snprintf(buf, sizeof(buf), "wifitool %s sendsingleamsdu 1 0",
ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"wifitool sendsingleamsdu failed");
}
snprintf(buf, sizeof(buf), "iwpriv %s amsdu 10", ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"iwpriv amsdu failed");
}
}
if (dut->ap_mode == AP_11ac) {
int chwidth, nss;
switch (dut->ap_chwidth) {
case AP_20:
chwidth = 0;
break;
case AP_40:
chwidth = 1;
break;
case AP_80:
chwidth = 2;
break;
case AP_160:
chwidth = 3;
break;
case AP_80_80:
chwidth = 3;
break;
default:
chwidth = 0;
break;
}
switch (dut->ap_tx_streams) {
case 1:
nss = 1;
break;
case 2:
nss = 2;
break;
case 3:
nss = 3;
break;
case 4:
nss = 4;
break;
default:
nss = 3;
break;
}
if (dut->ap_fixed_rate) {
if (nss == 4)
ath_disable_txbf(dut, ifname);
/* Set the nss */
snprintf(buf, sizeof(buf), "iwpriv %s nss %d",
ifname, nss);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"iwpriv nss failed");
}
/* Set the channel width */
snprintf(buf, sizeof(buf), "iwpriv %s chwidth %d",
ifname, chwidth);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"iwpriv chwidth failed");
}
/* Set the VHT MCS */
snprintf(buf, sizeof(buf), "iwpriv %s vhtmcs %d",
ifname, dut->ap_mcs);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"iwpriv vhtmcs failed");
}
}
}
if (dut->ap_dyn_bw_sig == VALUE_ENABLED) {
snprintf(buf, sizeof(buf), "iwpriv %s cwmenable 1", ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"iwpriv cwmenable 1 failed");
}
} else if (dut->ap_dyn_bw_sig == VALUE_DISABLED) {
snprintf(buf, sizeof(buf), "iwpriv %s cwmenable 0", ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"iwpriv cwmenable 0 failed");
}
}
if (dut->ap_sig_rts == VALUE_ENABLED) {
snprintf(buf, sizeof(buf), "iwconfig %s rts 64", ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"iwconfig rts 64 failed");
}
} else if (dut->ap_sig_rts == VALUE_DISABLED) {
snprintf(buf, sizeof(buf), "iwconfig %s rts 2347", ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"iwpriv rts 2347 failed");
}
}
if (dut->ap_hs2) {
snprintf(buf, sizeof(buf), "iwpriv %s qbssload 1", ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"iwpriv qbssload failed");
}
sigma_dut_print(dut, DUT_MSG_INFO, "Enabled qbssload");
}
if (dut->ap_bss_load && dut->ap_bss_load != -1) {
unsigned int bssload = 0;
if (dut->ap_bss_load == 1) {
/* STA count: 1, CU: 50, AAC: 65535 */
bssload = 0x0132ffff;
} else if (dut->ap_bss_load == 2) {
/* STA count: 1, CU: 200, AAC: 65535 */
bssload = 0x01c8ffff;
} else if (dut->ap_bss_load == 3) {
/* STA count: 1, CU: 75, AAC: 65535 */
bssload = 0x014bffff;
}
snprintf(buf, sizeof(buf), "iwpriv %s hcbssload %u",
ifname, bssload);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"iwpriv hcbssload failed");
}
} else if (dut->ap_bss_load == 0) {
snprintf(buf, sizeof(buf), "iwpriv %s qbssload 0", ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"iwpriv qbssload failed");
}
sigma_dut_print(dut, DUT_MSG_INFO, "Disabled qbssload");
}
if (dut->ap_dgaf_disable) {
snprintf(buf, sizeof(buf), "iwpriv %s dgaf_disable 1", ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"iwpriv dgaf_disable failed");
}
sigma_dut_print(dut, DUT_MSG_INFO, "Enabled dgaf_disable");
}
if (dut->ap_l2tif) {
snprintf(buf, sizeof(buf), "iwpriv %s l2tif 1", ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"iwpriv l2tif failed");
}
snprintf(buf, sizeof(buf),
"echo 1 > /sys/class/net/br0/brif/ath0/hotspot_l2tif");
if (system(buf) != 0)
sigma_dut_print(dut, DUT_MSG_ERROR,
"l2tif br failed");
snprintf(buf, sizeof(buf),
"echo 1 > /sys/class/net/br0/brif/eth0/hotspot_wan");
if (system(buf) != 0)
sigma_dut_print(dut, DUT_MSG_ERROR,
"l2tif brif failed");
sigma_dut_print(dut, DUT_MSG_INFO, "Enabled l2tif");
}
if (dut->ap_ndpa_frame == 0) {
snprintf(buf, sizeof(buf),
"wifitool %s beeliner_fw_test 117 192", ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"wifitool beeliner_fw_test 117 192 failed");
}
snprintf(buf, sizeof(buf),
"wifitool %s beeliner_fw_test 118 192", ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"wifitool beeliner_fw_test 117 192 failed");
}
} else if (dut->ap_ndpa_frame == 1) {
/* Driver default - no changes needed */
} else if (dut->ap_ndpa_frame == 2) {
snprintf(buf, sizeof(buf),
"wifitool %s beeliner_fw_test 115 1", ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"wifitool beeliner_fw_test 117 192 failed");
}
snprintf(buf, sizeof(buf),
"wifitool %s beeliner_fw_test 116 1", ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"wifitool beeliner_fw_test 117 192 failed");
}
}
if (dut->ap_rtt == 1) {
snprintf(buf, sizeof(buf), "iwpriv %s enable_rtt 1", ifname);
run_system(dut, buf);
}
if (dut->ap_lci == 1) {
snprintf(buf, sizeof(buf), "iwpriv %s enable_lci 1", ifname);
run_system(dut, buf);
}
if (dut->ap_lcr == 1) {
snprintf(buf, sizeof(buf), "iwpriv %s enable_lcr 1", ifname);
run_system(dut, buf);
}
if (dut->ap_rrm == 1) {
snprintf(buf, sizeof(buf), "iwpriv %s rrm 1", ifname);
run_system(dut, buf);
}
if (dut->ap_lci == 1 || dut->ap_lcr == 1) {
run_system(dut, "wpc -l /tmp/lci_cfg.txt");
}
if (dut->ap_neighap >= 1 && dut->ap_lci == 0) {
FILE *f;
f = fopen("/tmp/nbr_report.txt", "w");
if (!f) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Failed to open /tmp/nbr_report.txt");
return;
}
fprintf(f,
"ap_1 = 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x00 0x3c 0x00 0x00 0x80 0x%x 0x09 0x06 0x03 0x02 0x2a 0x00\n",
dut->ap_val_neighap[0][0], dut->ap_val_neighap[0][1],
dut->ap_val_neighap[0][2], dut->ap_val_neighap[0][3],
dut->ap_val_neighap[0][4], dut->ap_val_neighap[0][5],
dut->ap_val_opchannel[0]);
fclose(f);
f = fopen("/tmp/ftmrr.txt", "w");
if (!f) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Failed to open /tmp/ftmrr.txt");
return;
}
fprintf(f,
"ap_1 = 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x00 0x3c 0x00 0x00 0x80 0x%x 0x09 0x06 0x03 0x02 0x2a 0x00\n",
dut->ap_val_neighap[0][0], dut->ap_val_neighap[0][1],
dut->ap_val_neighap[0][2], dut->ap_val_neighap[0][3],
dut->ap_val_neighap[0][4], dut->ap_val_neighap[0][5],
dut->ap_val_opchannel[0]);
fclose(f);
}
if (dut->ap_neighap >= 2 && dut->ap_lci == 0) {
FILE *f;
f = fopen("/tmp/nbr_report.txt", "a");
if (!f) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Failed to open /tmp/nbr_report.txt");
return;
}
fprintf(f,
"ap_2 = 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x00 0x3c 0x00 0x00 0x80 0x%x 0x09 0x06 0x03 0x02 0x6a 0x00\n",
dut->ap_val_neighap[1][0], dut->ap_val_neighap[1][1],
dut->ap_val_neighap[1][2], dut->ap_val_neighap[1][3],
dut->ap_val_neighap[1][4], dut->ap_val_neighap[1][5],
dut->ap_val_opchannel[1]);
fclose(f);
f = fopen("/tmp/ftmrr.txt", "a");
if (!f) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Failed to open /tmp/ftmrr.txt");
return;
}
fprintf(f,
"ap_2 = 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x00 0x3c 0x00 0x00 0x80 0x%x 0x09 0x06 0x03 0x02 0x6a 0x00\n",
dut->ap_val_neighap[1][0], dut->ap_val_neighap[1][1],
dut->ap_val_neighap[1][2], dut->ap_val_neighap[1][3],
dut->ap_val_neighap[1][4], dut->ap_val_neighap[1][5],
dut->ap_val_opchannel[1]);
fclose(f);
}
if (dut->ap_neighap >= 3 && dut->ap_lci == 0) {
FILE *f;
f = fopen("/tmp/nbr_report.txt", "a");
if (!f) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Failed to open /tmp/nbr_report.txt");
return;
}
fprintf(f,
"ap_3 = 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x00 0x3c 0x00 0x00 0x80 0x%x 0x09 0x06 0x03 0x02 0x9b 0x00\n",
dut->ap_val_neighap[2][0], dut->ap_val_neighap[2][1],
dut->ap_val_neighap[2][2], dut->ap_val_neighap[2][3],
dut->ap_val_neighap[2][4], dut->ap_val_neighap[2][5],
dut->ap_val_opchannel[2]);
fclose(f);
f = fopen("/tmp/ftmrr.txt", "a");
if (!f) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Failed to open /tmp/ftmrr.txt");
return;
}
fprintf(f,
"ap_3 = 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x00 0x3c 0x00 0x00 0x80 0x%x 0x09 0x06 0x03 0x02 0x9b 0x00\n",
dut->ap_val_neighap[2][0], dut->ap_val_neighap[2][1],
dut->ap_val_neighap[2][2], dut->ap_val_neighap[2][3],
dut->ap_val_neighap[2][4], dut->ap_val_neighap[2][5],
dut->ap_val_opchannel[2]);
fclose(f);
}
if (dut->ap_neighap) {
snprintf(buf, sizeof(buf), "iwpriv %s enable_rtt 1", ifname);
run_system(dut, buf);
snprintf(buf, sizeof(buf), "iwpriv %s enable_lci 1", ifname);
run_system(dut, buf);
snprintf(buf, sizeof(buf), "iwpriv %s enable_lcr 1", ifname);
run_system(dut, buf);
snprintf(buf, sizeof(buf), "iwpriv %s rrm 1", ifname);
run_system(dut, buf);
}
if (dut->ap_scan == 1) {
snprintf(buf, sizeof(buf), "iwpriv %s scanentryage 600",
ifname);
run_system(dut, buf);
snprintf(buf, sizeof(buf), "iwlist %s scan", ifname);
run_system(dut, buf);
}
if (dut->ap_set_bssidpref) {
snprintf(buf, sizeof(buf),
"wifitool %s setbssidpref 00:00:00:00:00:00 0 00 00",
ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"wifitool clear bssidpref failed");
}
}
if (dut->wnm_bss_max_feature != VALUE_NOT_SET) {
int feature_enable;
feature_enable = dut->wnm_bss_max_feature == VALUE_ENABLED;
snprintf(buf, sizeof(buf), "iwpriv %s wnm %d",
ifname, feature_enable);
run_system(dut, buf);
snprintf(buf, sizeof(buf), "iwpriv %s wnm_bss %d",
ifname, feature_enable);
run_system(dut, buf);
if (feature_enable) {
const char *extra = "";
if (dut->wnm_bss_max_protection != VALUE_NOT_SET) {
if (dut->wnm_bss_max_protection ==
VALUE_ENABLED)
extra = " 1";
else
extra = " 0";
}
snprintf(buf, sizeof(buf),
"wlanconfig %s wnm setbssmax %d%s",
ifname, dut->wnm_bss_max_idle_time, extra);
run_system(dut, buf);
}
}
if (dut->program == PROGRAM_MBO) {
apply_mbo_pref_ap_list(dut);
snprintf(buf, sizeof(buf), "iwpriv %s mbo_cel_pref %d",
ifname, dut->ap_cell_cap_pref);
run_system(dut, buf);
snprintf(buf, sizeof(buf), "iwpriv %s mbocap 0x40", ifname);
run_system(dut, buf);
ath_set_assoc_disallow(dut, ifname, "disable");
}
if (dut->ap_oce == VALUE_ENABLED) {
snprintf(buf, sizeof(buf), "iwpriv %s set_bpr_enable 1",
ifname);
run_system(dut, buf);
}
if (dut->ap_oce == VALUE_ENABLED && dut->ap_channel <= 11) {
snprintf(buf, sizeof(buf), "iwpriv %s prb_rate 5500", ifname);
run_system(dut, buf);
snprintf(buf, sizeof(buf), "iwpriv %s set_bcn_rate 5500",
ifname);
run_system(dut, buf);
}
if (dut->ap_oce == VALUE_DISABLED) {
snprintf(buf, sizeof(buf), "iwpriv %s set_bpr_enable 0",
ifname);
run_system(dut, buf);
}
if (dut->ap_oce == VALUE_DISABLED && dut->ap_channel <= 11) {
snprintf(buf, sizeof(buf), "iwpriv %s mgmt_rate 1000", ifname);
run_system(dut, buf);
snprintf(buf, sizeof(buf), "iwpriv %s set_bcn_rate 1000",
ifname);
run_system(dut, buf);
}
if (dut->ap_bcnint) {
snprintf(buf, sizeof(buf), "iwpriv %s bintval %d", ifname,
dut->ap_bcnint);
run_system(dut, buf);
}
if (dut->ap_filsdscv == VALUE_DISABLED) {
snprintf(buf, sizeof(buf), "iwpriv %s enable_fils 0 0", ifname);
run_system(dut, buf);
}
if (dut->ap_filshlp == VALUE_ENABLED) {
snprintf(buf, sizeof(buf), "iwpriv %s oce_hlp 1", ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"iwpriv filshlp enable failed");
}
} else if (dut->ap_filshlp == VALUE_DISABLED) {
snprintf(buf, sizeof(buf), "iwpriv %s oce_hlp 0", ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"iwpriv filshlp disable failed");
}
}
/* When RNR is enabled, also enable apchannelreport, background scan */
if (dut->ap_rnr == VALUE_ENABLED) {
snprintf(buf, sizeof(buf), "iwpriv %s rnr 1", ifname);
run_system(dut, buf);
snprintf(buf, sizeof(buf), "iwpriv %s rnr_tbtt 1", ifname);
run_system(dut, buf);
snprintf(buf, sizeof(buf), "iwpriv %s apchanrpt 1", ifname);
run_system(dut, buf);
snprintf(buf, sizeof(buf), "iwpriv %s acs_ctrlflags 0x4",
basedev);
run_system(dut, buf);
snprintf(buf, sizeof(buf), "iwpriv %s acs_scanintvl 60",
basedev);
run_system(dut, buf);
snprintf(buf, sizeof(buf), "iwpriv %s acs_bkscanen 1", basedev);
run_system(dut, buf);
if (dut->ap_is_dual == 1) {
snprintf(buf, sizeof(buf), "iwpriv %s rnr 1",
ifname_dual);
run_system(dut, buf);
snprintf(buf, sizeof(buf), "iwpriv %s rnr_tbtt 1",
ifname_dual);
run_system(dut, buf);
snprintf(buf, sizeof(buf), "iwpriv %s apchanrpt 1",
ifname_dual);
run_system(dut, buf);
snprintf(buf, sizeof(buf),
"iwpriv %s acs_ctrlflags 0x4", basedev_radio);
run_system(dut, buf);
snprintf(buf, sizeof(buf), "iwpriv %s acs_scanintvl 60",
basedev_radio);
run_system(dut, buf);
snprintf(buf, sizeof(buf), "iwpriv %s acs_bkscanen 1",
basedev_radio);
run_system(dut, buf);
}
}
if (dut->ap_blechanutil || dut->ap_ble_admit_cap || dut->ap_blestacnt) {
snprintf(buf, sizeof(buf), "iwpriv %s qbssload 0", ifname);
run_system(dut, buf);
snprintf(buf, sizeof(buf),
"wlanconfig %s addie ftype 0 len 7 data 0b05%02x%02x%02x%02x%02x ",
ifname, dut->ap_blestacnt & 0xFF,
dut->ap_blestacnt >> 8, dut->ap_blechanutil,
dut->ap_ble_admit_cap & 0xFF,
dut->ap_ble_admit_cap >> 8);
run_system(dut, buf);
snprintf(buf, sizeof(buf),
"wlanconfig %s addie ftype 2 len 7 data 0b05%02x%02x%02x%02x%02x ",
ifname, dut->ap_blestacnt & 0xFF,
dut->ap_blestacnt >> 8, dut->ap_blechanutil,
dut->ap_ble_admit_cap & 0xFF,
dut->ap_ble_admit_cap >> 8);
run_system(dut, buf);
}
if (dut->ap_esp == VALUE_ENABLED) {
snprintf(buf, sizeof(buf), "iwpriv %s esp_period 5", basedev);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"iwpriv esp enable failed");
}
} else if (dut->ap_esp == VALUE_DISABLED) {
snprintf(buf, sizeof(buf), "iwpriv %s esp_period 0", basedev);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"iwpriv esp disable failed");
}
}
if (dut->ap_datappdudura) {
snprintf(buf, sizeof(buf), "iwpriv %s esp_ppdu_dur %d", basedev,
dut->ap_datappdudura);
run_system(dut, buf);
}
if (dut->ap_airtimefract) {
snprintf(buf, sizeof(buf), "iwpriv %s esp_airtime %d", basedev,
dut->ap_airtimefract);
run_system(dut, buf);
}
if (dut->ap_dhcp_stop) {
snprintf(buf, sizeof(buf), "/etc/init.d/dnsmasq stop");
run_system(dut, buf);
}
if (dut->ap_bawinsize) {
snprintf(buf, sizeof(buf), "iwpriv %s esp_ba_window %d",
basedev, dut->ap_bawinsize);
run_system(dut, buf);
}
if (dut->program == PROGRAM_DPP) {
if (dut->ap_interface_2g == 1) {
snprintf(buf, sizeof(buf),
"iwpriv %s set_bcn_rate 5500", ifname);
run_system(dut, buf);
snprintf(buf, sizeof(buf),
"iwpriv %s prb_rate 5500", ifname);
run_system(dut, buf);
snprintf(buf, sizeof(buf),
"iwpriv %s mgmt_rate 5500", ifname);
run_system(dut, buf);
}
snprintf(buf, sizeof(buf), "iwpriv %s set_rxfilter 0xffffffff",
basedev);
run_system(dut, buf);
dut->hostapd_running = 1;
}
if (dut->ap_he_ppdu == PPDU_MU) {
run_system_wrapper(
dut, "wifitool %s setUnitTestCmd 0x47 2 11 1000000",
ifname);
run_system_wrapper(
dut, "wifitool %s setUnitTestCmd 0x47 2 17 1000000",
ifname);
run_system_wrapper(dut,
"wifitool %s setUnitTestCmd 0x47 2 8 0",
ifname);
run_system_wrapper(dut,
"wifitool %s setUnitTestCmd 0x47 2 29 0",
ifname);
}
}
static int cmd_ath_ap_config_commit(struct sigma_dut *dut,
struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
/* const char *name = get_param(cmd, "NAME"); */
char buf[100];
struct stat s;
const char *ifname = dut->ap_is_dual ? "ath1" : "ath0";
if (stat("/proc/athversion", &s) == 0) {
sigma_dut_print(dut, DUT_MSG_INFO, "Run apdown");
run_system(dut, "apdown");
}
cmd_ath_ap_radio_config(dut);
snprintf(buf, sizeof(buf), "cfg -a 'AP_SSID=%s'", dut->ap_ssid);
run_system(dut, buf);
switch (dut->ap_key_mgmt) {
case AP_OPEN:
if (dut->ap_cipher == AP_WEP) {
run_system(dut, "cfg -a AP_SECMODE=WEP");
run_system(dut, "cfg -a AP_SECFILE=NONE");
/* shared auth mode not supported */
run_system(dut, "cfg -a AP_WEP_MODE_0=1");
run_system(dut, "cfg -a AP_WEP_MODE_1=1");
snprintf(buf, sizeof(buf),
"cfg -a WEP_RADIO_NUM0_KEY_1=%s",
dut->ap_wepkey);
run_system(dut, buf);
snprintf(buf, sizeof(buf),
"cfg -a WEP_RADIO_NUM1_KEY_1=%s",
dut->ap_wepkey);
run_system(dut, buf);
} else {
run_system(dut, "cfg -a AP_SECMODE=None");
}
break;
case AP_WPA2_PSK:
case AP_WPA2_PSK_MIXED:
case AP_WPA_PSK:
case AP_WPA2_SAE:
case AP_WPA2_PSK_SAE:
if (dut->ap_key_mgmt == AP_WPA2_PSK ||
dut->ap_key_mgmt == AP_WPA2_SAE ||
dut->ap_key_mgmt == AP_WPA2_PSK_SAE)
run_system(dut, "cfg -a AP_WPA=2");
else if (dut->ap_key_mgmt == AP_WPA2_PSK_MIXED)
run_system(dut, "cfg -a AP_WPA=3");
else
run_system(dut, "cfg -a AP_WPA=1");
/* TODO: SAE configuration */
run_system(dut, "cfg -a AP_SECMODE=WPA");
run_system(dut, "cfg -a AP_SECFILE=PSK");
snprintf(buf, sizeof(buf), "cfg -a 'PSK_KEY=%s'",
dut->ap_passphrase);
run_system(dut, buf);
if (dut->ap_cipher == AP_CCMP_TKIP)
run_system(dut, "cfg -a AP_CYPHER=\"CCMP TKIP\"");
else if (dut->ap_cipher == AP_TKIP)
run_system(dut, "cfg -a AP_CYPHER=TKIP");
else
run_system(dut, "cfg -a AP_CYPHER=CCMP");
break;
case AP_WPA2_EAP:
case AP_WPA2_EAP_MIXED:
case AP_WPA_EAP:
if (dut->ap_key_mgmt == AP_WPA2_EAP)
run_system(dut, "cfg -a AP_WPA=2");
else if (dut->ap_key_mgmt == AP_WPA2_EAP_MIXED)
run_system(dut, "cfg -a AP_WPA=3");
else
run_system(dut, "cfg -a AP_WPA=1");
run_system(dut, "cfg -a AP_SECMODE=WPA");
run_system(dut, "cfg -a AP_SECFILE=EAP");
if (dut->ap_cipher == AP_CCMP_TKIP)
run_system(dut, "cfg -a AP_CYPHER=\"CCMP TKIP\"");
else if (dut->ap_cipher == AP_TKIP)
run_system(dut, "cfg -a AP_CYPHER=TKIP");
else
run_system(dut, "cfg -a AP_CYPHER=CCMP");
snprintf(buf, sizeof(buf), "cfg -a AP_AUTH_SERVER=%s",
dut->ap_radius_ipaddr);
run_system(dut, buf);
snprintf(buf, sizeof(buf), "cfg -a AP_AUTH_PORT=%d",
dut->ap_radius_port);
run_system(dut, buf);
snprintf(buf, sizeof(buf), "cfg -a AP_AUTH_SECRET=%s",
dut->ap_radius_password);
run_system(dut, buf);
break;
case AP_WPA2_EAP_OSEN:
/* TODO */
sigma_dut_print(dut, DUT_MSG_ERROR, "EAP+OSEN not supported");
break;
case AP_SUITEB:
/* TODO */
sigma_dut_print(dut, DUT_MSG_ERROR, "SuiteB not supported");
break;
case AP_WPA2_OWE:
/* TODO */
sigma_dut_print(dut, DUT_MSG_ERROR, "OWE not supported");
break;
case AP_WPA2_FT_EAP:
case AP_WPA2_FT_PSK:
case AP_WPA2_EAP_SHA256:
case AP_WPA2_PSK_SHA256:
case AP_WPA2_ENT_FT_EAP:
case AP_OSEN:
/* TODO */
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Unsupported KeyMgnt value");
return 0;
}
if (dut->ap_is_dual) {
/* ath1 settings in case of dual */
snprintf(buf, sizeof(buf), "cfg -a 'AP_SSID_2=%s'",
dut->ap_ssid);
run_system(dut, buf);
switch (dut->ap_key_mgmt) {
case AP_OPEN:
if (dut->ap_cipher == AP_WEP) {
run_system(dut, "cfg -a AP_SECMODE_2=WEP");
run_system(dut, "cfg -a AP_SECFILE_2=NONE");
/* shared auth mode not supported */
run_system(dut, "cfg -a AP_WEP_MODE_0=1");
run_system(dut, "cfg -a AP_WEP_MODE_1=1");
snprintf(buf, sizeof(buf),
"cfg -a WEP_RADIO_NUM0_KEY_1=%s",
dut->ap_wepkey);
run_system(dut, buf);
snprintf(buf, sizeof(buf),
"cfg -a WEP_RADIO_NUM1_KEY_1=%s",
dut->ap_wepkey);
run_system(dut, buf);
} else {
run_system(dut, "cfg -a AP_SECMODE_2=None");
}
break;
case AP_WPA2_PSK:
case AP_WPA2_PSK_MIXED:
case AP_WPA_PSK:
case AP_WPA2_SAE:
case AP_WPA2_PSK_SAE:
if (dut->ap_key_mgmt == AP_WPA2_PSK ||
dut->ap_key_mgmt == AP_WPA2_SAE ||
dut->ap_key_mgmt == AP_WPA2_PSK_SAE)
run_system(dut, "cfg -a AP_WPA_2=2");
else if (dut->ap_key_mgmt == AP_WPA2_PSK_MIXED)
run_system(dut, "cfg -a AP_WPA_2=3");
else
run_system(dut, "cfg -a AP_WPA_2=1");
// run_system(dut, "cfg -a AP_WPA_2=2");
/* TODO: SAE configuration */
run_system(dut, "cfg -a AP_SECMODE_2=WPA");
run_system(dut, "cfg -a AP_SECFILE_2=PSK");
snprintf(buf, sizeof(buf), "cfg -a 'PSK_KEY_2=%s'",
dut->ap_passphrase);
run_system(dut, buf);
if (dut->ap_cipher == AP_CCMP_TKIP)
run_system(dut, "cfg -a AP_CYPHER_2=\"CCMP TKIP\"");
else if (dut->ap_cipher == AP_TKIP)
run_system(dut, "cfg -a AP_CYPHER_2=TKIP");
else
run_system(dut, "cfg -a AP_CYPHER_2=CCMP");
break;
case AP_WPA2_EAP:
case AP_WPA2_EAP_MIXED:
case AP_WPA_EAP:
if (dut->ap_key_mgmt == AP_WPA2_EAP)
run_system(dut, "cfg -a AP_WPA_2=2");
else if (dut->ap_key_mgmt == AP_WPA2_EAP_MIXED)
run_system(dut, "cfg -a AP_WPA_2=3");
else
run_system(dut, "cfg -a AP_WPA_2=1");
run_system(dut, "cfg -a AP_SECMODE_2=WPA");
run_system(dut, "cfg -a AP_SECFILE_2=EAP");
if (dut->ap_cipher == AP_CCMP_TKIP)
run_system(dut, "cfg -a AP_CYPHER_2=\"CCMP TKIP\"");
else if (dut->ap_cipher == AP_TKIP)
run_system(dut, "cfg -a AP_CYPHER_2=TKIP");
else
run_system(dut, "cfg -a AP_CYPHER_2=CCMP");
snprintf(buf, sizeof(buf), "cfg -a AP_AUTH_SERVER_2=%s",
dut->ap_radius_ipaddr);
run_system(dut, buf);
snprintf(buf, sizeof(buf), "cfg -a AP_AUTH_PORT_2=%d",
dut->ap_radius_port);
run_system(dut, buf);
snprintf(buf, sizeof(buf), "cfg -a AP_AUTH_SECRET_2=%s",
dut->ap_radius_password);
run_system(dut, buf);
break;
case AP_WPA2_EAP_OSEN:
/* TODO */
sigma_dut_print(dut, DUT_MSG_ERROR,
"EAP+OSEN not supported");
break;
case AP_SUITEB:
/* TODO */
sigma_dut_print(dut, DUT_MSG_ERROR,
"SuiteB not supported");
break;
case AP_WPA2_OWE:
/* TODO */
sigma_dut_print(dut, DUT_MSG_ERROR,
"OWE not supported");
break;
case AP_WPA2_FT_EAP:
case AP_WPA2_FT_PSK:
case AP_WPA2_EAP_SHA256:
case AP_WPA2_PSK_SHA256:
case AP_WPA2_ENT_FT_EAP:
case AP_OSEN:
/* TODO */
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Unsupported KeyMgnt value");
return 0;
}
/* wifi0 settings in case of dual */
run_system(dut, "cfg -a AP_RADIO_ID=0");
run_system(dut, "cfg -a AP_PRIMARY_CH=6");
run_system(dut, "cfg -a AP_STARTMODE=dual");
run_system(dut, "cfg -a AP_CHMODE=11NGHT40PLUS");
run_system(dut, "cfg -a TX_CHAINMASK=7");
run_system(dut, "cfg -a RX_CHAINMASK=7");
}
switch (dut->ap_pmf) {
case AP_PMF_DISABLED:
snprintf(buf, sizeof(buf), "cfg -a AP_PMF=0");
run_system(dut, buf);
break;
case AP_PMF_OPTIONAL:
snprintf(buf, sizeof(buf), "cfg -a AP_PMF=1");
run_system(dut, buf);
break;
case AP_PMF_REQUIRED:
snprintf(buf, sizeof(buf), "cfg -a AP_PMF=2");
run_system(dut, buf);
break;
}
if (dut->ap_add_sha256) {
snprintf(buf, sizeof(buf), "cfg -a AP_WPA_SHA256=1");
run_system(dut, buf);
} else {
snprintf(buf, sizeof(buf), "cfg -r AP_WPA_SHA256");
run_system(dut, buf);
}
if (dut->ap_hs2)
run_system(dut, "cfg -a AP_HOTSPOT=1");
else
run_system(dut, "cfg -r AP_HOTSPOT");
if (dut->ap_interworking) {
snprintf(buf, sizeof(buf), "cfg -a AP_HOTSPOT_ANT=%d",
dut->ap_access_net_type);
run_system(dut, buf);
snprintf(buf, sizeof(buf), "cfg -a AP_HOTSPOT_INTERNET=%d",
dut->ap_internet);
run_system(dut, buf);
snprintf(buf, sizeof(buf), "cfg -a AP_HOTSPOT_VENUEGROUP=%d",
dut->ap_venue_group);
run_system(dut, buf);
snprintf(buf, sizeof(buf), "cfg -a AP_HOTSPOT_VENUETYPE=%d",
dut->ap_venue_type);
run_system(dut, buf);
snprintf(buf, sizeof(buf), "cfg -a AP_HOTSPOT_HESSID=%s",
dut->ap_hessid);
run_system(dut, buf);
if (dut->ap_roaming_cons[0]) {
char *second, *rc;
rc = strdup(dut->ap_roaming_cons);
if (rc == NULL)
return 0;
second = strchr(rc, ';');
if (second)
*second++ = '\0';
snprintf(buf, sizeof(buf),
"cfg -a AP_HOTSPOT_ROAMINGCONSORTIUM=%s", rc);
run_system(dut, buf);
if (second) {
snprintf(buf, sizeof(buf),
"cfg -a AP_HOTSPOT_ROAMINGCONSORTIUM2"
"=%s", second);
run_system(dut, buf);
}
free(rc);
} else {
run_system(dut, "cfg -r AP_HOTSPOT_ROAMINGCONSORTIUM");
run_system(dut,
"cfg -r AP_HOTSPOT_ROAMINGCONSORTIUM2");
}
} else {
run_system(dut, "cfg -r AP_HOTSPOT_ANT");
run_system(dut, "cfg -r AP_HOTSPOT_INTERNET");
run_system(dut, "cfg -r AP_HOTSPOT_VENUEGROUP");
run_system(dut, "cfg -r AP_HOTSPOT_VENUETYPE");
run_system(dut, "cfg -r AP_HOTSPOT_HESSID");
run_system(dut, "cfg -r AP_HOTSPOT_ROAMINGCONSORTIUM");
run_system(dut, "cfg -r AP_HOTSPOT_ROAMINGCONSORTIUM2");
}
if (dut->ap_proxy_arp)
run_system(dut, "cfg -a IEEE80211V_PROXYARP=1");
else
run_system(dut, "cfg -a IEEE80211V_PROXYARP=0");
if (dut->ap_dgaf_disable)
run_system(dut, "cfg -a AP_HOTSPOT_DISABLE_DGAF=1");
else
run_system(dut, "cfg -r AP_HOTSPOT_DISABLE_DGAF");
if (strlen(dut->ap_tag_ssid[0])) {
snprintf(buf, sizeof(buf),
"cfg -a AP_SSID_2=%s", dut->ap_tag_ssid[0]);
run_system(dut, buf);
if (dut->ap_tag_key_mgmt[0] == AP2_OSEN) {
run_system(dut, "cfg -a AP_SECMODE_2=WPA");
run_system(dut, "cfg -a AP_SECFILE_2=OSEN");
snprintf(buf, sizeof(buf), "cfg -a AP_AUTH_SERVER_2=%s",
dut->ap2_radius_ipaddr);
run_system(dut, buf);
snprintf(buf, sizeof(buf), "cfg -a AP_AUTH_PORT_2=%d",
dut->ap2_radius_port);
run_system(dut, buf);
snprintf(buf, sizeof(buf), "cfg -a AP_AUTH_SECRET_2=%s",
dut->ap2_radius_password);
run_system(dut, buf);
} else {
run_system(dut, "cfg -a AP_SECMODE_2=None");
run_system(dut, "cfg -r AP_AUTH_SERVER_2");
run_system(dut, "cfg -r AP_AUTH_PORT_2");
run_system(dut, "cfg -r AP_AUTH_SECRET_2");
}
run_system(dut, "cfg -a AP_STARTMODE=multi");
}
run_system(dut, "cfg -c");
sigma_dut_print(dut, DUT_MSG_INFO, "Starting AP");
if (system("apup") != 0) {
/* to be debugged why apup returns error
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,apup failed");
return 0;
*/
}
sigma_dut_print(dut, DUT_MSG_INFO, "AP started");
if (dut->ap_key_mgmt != AP_OPEN) {
int res;
/* allow some time for hostapd to start before returning
* success */
usleep(500000);
if (run_hostapd_cli(dut, "ping") != 0) {
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Failed to talk to hostapd");
return 0;
}
if (dut->ap_hs2 && !dut->ap_anqpserver) {
/* the cfg app doesn't like ";" in the variables */
res = ath_ap_append_hostapd_conf(dut);
if (res < 0)
return res;
/* wait for hostapd to be ready */
usleep(500000);
if (run_hostapd_cli(dut, "ping") != 0) {
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Failed to talk to "
"hostapd");
return 0;
}
}
}
ath_ap_set_params(dut);
if (dut->ap_anqpserver)
return cmd_ath_ap_anqpserver_start(dut);
if (dut->ap2_proxy_arp)
run_system(dut, "iwpriv ath1 proxy_arp 1");
if (dut->ap_allow_vht_wep || dut->ap_allow_vht_tkip) {
snprintf(buf, sizeof(buf), "iwpriv %s htweptkip 1", ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"iwpriv htweptkip failed");
}
}
return 1;
}
static int set_ebtables_proxy_arp(struct sigma_dut *dut, const char *chain,
const char *ifname)
{
char buf[200];
if (!chain || !ifname)
return -2;
snprintf(buf, sizeof(buf), "ebtables -P %s ACCEPT", chain);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Failed to set ebtables rules, RULE-1, %s",
chain);
return -2;
}
snprintf(buf, sizeof(buf),
"ebtables -A %s -p ARP -d Broadcast -o %s -j DROP",
chain, ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Failed to set ebtables rules, RULE-2, %s",
chain);
return -2;
}
snprintf(buf, sizeof(buf),
"ebtables -A %s -d Multicast -p IPv6 --ip6-protocol ipv6-icmp --ip6-icmp-type neighbor-solicitation -o %s -j DROP",
chain, ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Failed to set ebtables rules, RULE-3, %s",
chain);
return -2;
}
snprintf(buf, sizeof(buf),
"ebtables -A %s -d Multicast -p IPv6 --ip6-protocol ipv6-icmp --ip6-icmp-type neighbor-advertisement -o %s -j DROP",
chain, ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Failed to set ebtables rules, RULE-4, %s",
chain);
return -2;
}
return 0;
}
static int set_ebtables_disable_dgaf(struct sigma_dut *dut,
const char *chain,
const char *ifname)
{
char buf[200];
if (!chain || !ifname)
return -2;
snprintf(buf, sizeof(buf), "ebtables -P %s ACCEPT", chain);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Failed to set ebtables rules, RULE-5, %s",
chain);
return -2;
}
snprintf(buf, sizeof(buf),
"ebtables -A %s -p ARP -d Broadcast -o %s -j DROP",
chain, ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Failed to set ebtables rules, RULE-6, %s",
chain);
return -2;
}
snprintf(buf, sizeof(buf),
"ebtables -A %s -p IPv4 -d Multicast -o %s -j DROP",
chain, ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Failed to set ebtables rules, RULE-7, %s",
chain);
return -2;
}
snprintf(buf, sizeof(buf),
"ebtables -A %s -p IPv6 -d Multicast -o %s -j DROP",
chain, ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Failed to set ebtables rules, RULE-8, %s",
chain);
return -2;
}
return 0;
}
static void set_ebtables_forward_drop(struct sigma_dut *dut,
const char *ifname, const char *ifname2)
{
char buf[128];
snprintf(buf, sizeof(buf), "ebtables -A FORWARD -i %s -o %s -j DROP",
ifname, ifname2);
if (system(buf) != 0)
sigma_dut_print(dut, DUT_MSG_ERROR,
"Failed to set ebtables rule");
snprintf(buf, sizeof(buf), "ebtables -A FORWARD -i %s -o %s -j DROP",
ifname2, ifname);
if (system(buf) != 0)
sigma_dut_print(dut, DUT_MSG_ERROR,
"Failed to set ebtables rule");
}
static int check_channel(int channel)
{
int channel_list[] = { 36, 40, 44, 48, 52, 60, 64, 100, 104, 108, 112,
116, 120, 124, 128, 132, 140, 144, 149, 153, 157,
161, 165 };
int num_chan = sizeof(channel_list) / sizeof(int);
int i;
for (i = 0; i < num_chan; i++) {
if (channel == channel_list[i])
return i;
}
return -1;
}
static int get_oper_centr_freq_seq_idx(int chwidth, int channel)
{
int ch_base;
int period;
if (check_channel(channel) < 0)
return -1;
if (channel >= 36 && channel <= 64)
ch_base = 36;
else if (channel >= 100 && channel <= 144)
ch_base = 100;
else
ch_base = 149;
period = channel % ch_base * 5 / chwidth;
return ch_base + period * chwidth / 5 + (chwidth - 20) / 10;
}
static int is_ht40plus_chan(int chan)
{
return chan == 36 || chan == 44 || chan == 52 || chan == 60 ||
chan == 100 || chan == 108 || chan == 116 || chan == 124 ||
chan == 132 || chan == 149 || chan == 157;
}
static int is_ht40minus_chan(int chan)
{
return chan == 40 || chan == 48 || chan == 56 || chan == 64 ||
chan == 104 || chan == 112 || chan == 120 || chan == 128 ||
chan == 136 || chan == 153 || chan == 161;
}
static int get_5g_channel_freq(int chan)
{
return 5000 + chan * 5;
}
static const char * hostapd_cipher_name(enum ap_cipher cipher)
{
switch (cipher) {
case AP_CCMP:
return "CCMP";
case AP_TKIP:
return "TKIP";
case AP_CCMP_TKIP:
return "CCMP TKIP";
case AP_GCMP_256:
return "GCMP-256";
case AP_GCMP_128:
return "GCMP";
case AP_CCMP_256:
return "CCMP-256";
case AP_CCMP_128_GCMP_256:
return "CCMP GCMP-256";
default:
return "UNKNOWN";
}
}
static const char *
hostapd_group_mgmt_cipher_name(enum ap_group_mgmt_cipher cipher)
{
switch (cipher) {
case AP_BIP_GMAC_256:
return "BIP-GMAC-256";
case AP_BIP_CMAC_256:
return "BIP-CMAC-256";
case AP_BIP_GMAC_128:
return "BIP-GMAC-128";
case AP_BIP_CMAC_128:
return "AES-128-CMAC";
default:
return "UNKNOWN";
}
}
static int ap_set_60g_ese(struct sigma_dut *dut, int count,
struct sigma_ese_alloc *allocs)
{
switch (get_driver_type()) {
#ifdef __linux__
case DRIVER_WIL6210:
return wil6210_set_ese(dut, count, allocs);
#endif /* __linux__ */
default:
sigma_dut_print(dut, DUT_MSG_ERROR,
"Unsupported ap_set_60g_ese with the current driver");
return -1;
}
}
static int ap_set_force_mcs(struct sigma_dut *dut, int force, int mcs)
{
switch (get_driver_type()) {
#ifdef __linux__
case DRIVER_WIL6210:
return wil6210_set_force_mcs(dut, force, mcs);
#endif /* __linux__ */
default:
sigma_dut_print(dut, DUT_MSG_ERROR,
"Unsupported ap_set_force_mcs with the current driver");
return -1;
}
}
int cmd_ap_config_commit(struct sigma_dut *dut, struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
/* const char *name = get_param(cmd, "NAME"); */
FILE *f;
const char *ifname;
char buf[500];
char path[100];
enum driver_type drv;
const char *key_mgmt;
#ifdef ANDROID
struct group *gr;
#endif /* ANDROID */
drv = get_driver_type();
if (dut->mode == SIGMA_MODE_STATION) {
stop_sta_mode(dut);
sleep(1);
}
if (dut->mode == SIGMA_MODE_SNIFFER && dut->sniffer_ifname) {
snprintf(buf, sizeof(buf), "ifconfig %s down",
dut->sniffer_ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_INFO,
"Failed to run '%s'", buf);
}
snprintf(buf, sizeof(buf), "iw dev %s set type station",
dut->sniffer_ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_INFO,
"Failed to run '%s'", buf);
}
}
dut->mode = SIGMA_MODE_AP;
if (drv == DRIVER_ATHEROS)
return cmd_ath_ap_config_commit(dut, conn, cmd);
if (drv == DRIVER_WCN)
return cmd_wcn_ap_config_commit(dut, conn, cmd);
if (drv == DRIVER_OPENWRT)
return cmd_owrt_ap_config_commit(dut, conn, cmd);
f = fopen(SIGMA_TMPDIR "/sigma_dut-ap.conf", "w");
if (f == NULL) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"%s: Failed to open sigma_dut-ap.conf",
__func__);
return -2;
}
switch (dut->ap_mode) {
case AP_11g:
case AP_11b:
case AP_11ng:
ifname = (drv == DRIVER_MAC80211) ? "wlan0" : "ath0";
if ((drv == DRIVER_QNXNTO || drv == DRIVER_LINUX_WCN) &&
sigma_main_ifname)
ifname = sigma_main_ifname;
fprintf(f, "hw_mode=g\n");
break;
case AP_11a:
case AP_11na:
case AP_11ac:
if (drv == DRIVER_QNXNTO || drv == DRIVER_LINUX_WCN) {
if (sigma_main_ifname)
ifname = sigma_main_ifname;
else
ifname = "wlan0";
} else if (drv == DRIVER_MAC80211) {
if (if_nametoindex("wlan1") > 0)
ifname = "wlan1";
else
ifname = "wlan0";
} else {
ifname = get_main_ifname();
}
fprintf(f, "hw_mode=a\n");
break;
case AP_11ad:
ifname = get_main_ifname();
fprintf(f, "hw_mode=ad\n");
break;
default:
fclose(f);
return -1;
}
if (dut->hostapd_ifname)
ifname = dut->hostapd_ifname;
if (drv == DRIVER_MAC80211 || drv == DRIVER_LINUX_WCN)
fprintf(f, "driver=nl80211\n");
if ((drv == DRIVER_MAC80211 || drv == DRIVER_QNXNTO ||
drv == DRIVER_LINUX_WCN) &&
(dut->ap_mode == AP_11ng || dut->ap_mode == AP_11na)) {
int ht40plus = 0, ht40minus = 0, tx_stbc = 0;
fprintf(f, "ieee80211n=1\n");
if (dut->ap_mode == AP_11ng &&
(dut->ap_chwidth == AP_40 ||
(dut->ap_chwidth == AP_AUTO &&
dut->default_11ng_ap_chwidth == AP_40))) {
if (dut->ap_channel >= 1 && dut->ap_channel <= 7)
ht40plus = 1;
else if (dut->ap_channel >= 8 && dut->ap_channel <= 11)
ht40minus = 1;
fprintf(f, "obss_interval=300\n");
}
/* configure ht_capab based on channel width */
if (dut->ap_mode == AP_11na &&
(dut->ap_chwidth == AP_40 ||
(dut->ap_chwidth == AP_AUTO &&
dut->default_11na_ap_chwidth == AP_40))) {
if (is_ht40plus_chan(dut->ap_channel))
ht40plus = 1;
else if (is_ht40minus_chan(dut->ap_channel))
ht40minus = 1;
}
if (dut->ap_tx_stbc)
tx_stbc = 1;
/* Overwrite the ht_capab with offset value if configured */
if (dut->ap_chwidth == AP_40 &&
dut->ap_chwidth_offset == SEC_CH_40ABOVE) {
ht40plus = 1;
ht40minus = 0;
} else if (dut->ap_chwidth == AP_40 &&
dut->ap_chwidth_offset == SEC_CH_40BELOW) {
ht40minus = 1;
ht40plus = 0;
}
fprintf(f, "ht_capab=%s%s%s\n",
ht40plus ? "[HT40+]" : "",
ht40minus ? "[HT40-]" : "",
tx_stbc ? "[TX-STBC]" : "");
}
if ((drv == DRIVER_MAC80211 || drv == DRIVER_QNXNTO ||
drv == DRIVER_LINUX_WCN) &&
dut->ap_mode == AP_11ac) {
fprintf(f, "ieee80211ac=1\n"
"ieee80211n=1\n"
"ht_capab=[HT40+]\n");
}
if ((drv == DRIVER_MAC80211 || drv == DRIVER_QNXNTO ||
drv == DRIVER_LINUX_WCN) &&
(dut->ap_mode == AP_11ac || dut->ap_mode == AP_11na)) {
if (dut->ap_countrycode[0]) {
fprintf(f, "country_code=%s\n", dut->ap_countrycode);
fprintf(f, "ieee80211d=1\n");
fprintf(f, "ieee80211h=1\n");
}
}
fprintf(f, "interface=%s\n", ifname);
if (dut->bridge)
fprintf(f, "bridge=%s\n", dut->bridge);
fprintf(f, "channel=%d\n", dut->ap_channel);
if (sigma_hapd_ctrl)
fprintf(f, "ctrl_interface=%s\n", sigma_hapd_ctrl);
else
fprintf(f, "ctrl_interface=/var/run/hostapd\n");
if (dut->ap_ssid[0])
fprintf(f, "ssid=%s\n", dut->ap_ssid);
else
fprintf(f, "ssid=QCA AP OOB\n");
if (dut->ap_bcnint)
fprintf(f, "beacon_int=%d\n", dut->ap_bcnint);
if (dut->ap_akm_values) {
struct {
int akm;
const char *str;
} akms[] = {
{ AKM_WPA_EAP, "WPA-EAP" },
{ AKM_WPA_PSK, "WPA-PSK" },
{ AKM_FT_EAP, "FT-EAP" },
{ AKM_FT_PSK, "FT-PSK" },
{ AKM_EAP_SHA256, "WPA-EAP-SHA256" },
{ AKM_PSK_SHA256, "WPA-PSK-SHA256" },
{ AKM_SAE, "SAE" },
{ AKM_FT_SAE, "FT-SAE" },
{ AKM_SUITE_B, "WPA-EAP-SUITE-B-192" },
{ AKM_FT_SUITE_B, "FT-EAP-SHA384" },
{ AKM_FILS_SHA256, "FILS-SHA256" },
{ AKM_FILS_SHA384, "FILS-SHA384" },
{ AKM_FT_FILS_SHA256, "FT-FILS-SHA256" },
{ AKM_FT_FILS_SHA384, "FT-FILS-SHA384" },
};
int first = 1, i;
fprintf(f, "wpa_key_mgmt=");
for (i = 0; i < ARRAY_SIZE(akms); i++) {
if (dut->ap_akm_values & (1 << akms[i].akm)) {
fprintf(f, "%s%s", first ? "" : " ",
akms[i].str);
first = 0;
}
}
fprintf(f, "\n");
/* TODO: mixed mode and WPAv1 only */
fprintf(f, "wpa=2\n");
fprintf(f, "wpa_pairwise=%s\n",
hostapd_cipher_name(dut->ap_cipher));
if (dut->ap_group_cipher != AP_NO_GROUP_CIPHER_SET)
fprintf(f, "group_cipher=%s\n",
hostapd_cipher_name(dut->ap_group_cipher));
if ((dut->ap_akm_values & (1 << 8 /* SAE */)) &&
dut->ap_passphrase[0])
fprintf(f, "sae_password=%s\n", dut->ap_passphrase);
else if (!dut->ap_passphrase[0] && dut->ap_psk[0])
fprintf(f, "wpa_psk=%s", dut->ap_psk);
else if (dut->ap_passphrase[0])
fprintf(f, "wpa_passphrase=%s\n", dut->ap_passphrase);
goto skip_key_mgmt;
}
switch (dut->ap_key_mgmt) {
case AP_OPEN:
if (dut->ap_cipher == AP_WEP)
fprintf(f, "wep_key0=%s\n", dut->ap_wepkey);
break;
case AP_WPA2_PSK:
case AP_WPA2_PSK_MIXED:
case AP_WPA_PSK:
case AP_WPA2_SAE:
case AP_WPA2_PSK_SAE:
case AP_WPA2_PSK_SHA256:
case AP_WPA2_FT_PSK:
if (dut->ap_key_mgmt == AP_WPA2_PSK ||
dut->ap_key_mgmt == AP_WPA2_SAE ||
dut->ap_key_mgmt == AP_WPA2_PSK_SAE ||
dut->ap_key_mgmt == AP_WPA2_PSK_SHA256 ||
dut->ap_key_mgmt == AP_WPA2_FT_PSK)
fprintf(f, "wpa=2\n");
else if (dut->ap_key_mgmt == AP_WPA2_PSK_MIXED)
fprintf(f, "wpa=3\n");
else
fprintf(f, "wpa=1\n");
if (dut->ap_key_mgmt == AP_WPA2_SAE)
key_mgmt = "SAE";
else if (dut->ap_key_mgmt == AP_WPA2_PSK_SAE)
key_mgmt = "WPA-PSK SAE";
else
key_mgmt = "WPA-PSK";
switch (dut->ap_pmf) {
case AP_PMF_DISABLED:
fprintf(f, "wpa_key_mgmt=%s%s\n", key_mgmt,
dut->ap_add_sha256 ? " WPA-PSK-SHA256" : "");
break;
case AP_PMF_OPTIONAL:
fprintf(f, "wpa_key_mgmt=%s%s\n", key_mgmt,
dut->ap_add_sha256 ? " WPA-PSK-SHA256" : "");
break;
case AP_PMF_REQUIRED:
if (dut->ap_key_mgmt == AP_WPA2_SAE)
key_mgmt = "SAE";
else if (dut->ap_key_mgmt == AP_WPA2_PSK_SAE)
key_mgmt = "WPA-PSK-SHA256 SAE";
else
key_mgmt = "WPA-PSK-SHA256";
fprintf(f, "wpa_key_mgmt=%s\n", key_mgmt);
break;
}
if (dut->ap_key_mgmt == AP_WPA2_PSK_SHA256)
fprintf(f, "wpa_key_mgmt=WPA-PSK-SHA256\n");
else if (dut->ap_key_mgmt == AP_WPA2_FT_PSK)
fprintf(f, "wpa_key_mgmt=FT-PSK\n");
fprintf(f, "wpa_pairwise=%s\n",
hostapd_cipher_name(dut->ap_cipher));
if (dut->ap_group_cipher != AP_NO_GROUP_CIPHER_SET)
fprintf(f, "group_cipher=%s\n",
hostapd_cipher_name(dut->ap_group_cipher));
if (dut->ap_key_mgmt == AP_WPA2_SAE)
fprintf(f, "sae_password=%s\n", dut->ap_passphrase);
else if (!dut->ap_passphrase[0] && dut->ap_psk[0])
fprintf(f, "wpa_psk=%s", dut->ap_psk);
else
fprintf(f, "wpa_passphrase=%s\n", dut->ap_passphrase);
break;
case AP_WPA2_EAP:
case AP_WPA2_EAP_MIXED:
case AP_WPA_EAP:
case AP_WPA2_EAP_OSEN:
case AP_WPA2_EAP_SHA256:
case AP_WPA2_FT_EAP:
case AP_WPA2_ENT_FT_EAP:
fprintf(f, "ieee8021x=1\n");
if (dut->ap_key_mgmt == AP_WPA2_EAP ||
dut->ap_key_mgmt == AP_WPA2_EAP_OSEN ||
dut->ap_key_mgmt == AP_WPA2_EAP_SHA256 ||
dut->ap_key_mgmt == AP_WPA2_FT_EAP ||
dut->ap_key_mgmt == AP_WPA2_ENT_FT_EAP)
fprintf(f, "wpa=2\n");
else if (dut->ap_key_mgmt == AP_WPA2_EAP_MIXED)
fprintf(f, "wpa=3\n");
else
fprintf(f, "wpa=1\n");
switch (dut->ap_pmf) {
case AP_PMF_DISABLED:
fprintf(f, "wpa_key_mgmt=WPA-EAP%s\n",
dut->ap_add_sha256 ? " WPA-EAP-SHA256" : "");
break;
case AP_PMF_OPTIONAL:
fprintf(f, "wpa_key_mgmt=WPA-EAP%s%s\n",
dut->ap_add_sha256 ? " WPA-EAP-SHA256" : "",
dut->ap_key_mgmt == AP_WPA2_EAP_OSEN ? " OSEN" :
"");
break;
case AP_PMF_REQUIRED:
fprintf(f, "wpa_key_mgmt=WPA-EAP-SHA256%s\n",
dut->ap_key_mgmt == AP_WPA2_EAP_OSEN ? " OSEN" :
"");
break;
}
if (dut->ap_key_mgmt == AP_WPA2_EAP_SHA256)
fprintf(f, "wpa_key_mgmt=WPA-EAP-SHA256\n");
else if (dut->ap_key_mgmt == AP_WPA2_FT_EAP)
fprintf(f, "wpa_key_mgmt=FT-EAP\n");
else if (dut->ap_key_mgmt == AP_WPA2_ENT_FT_EAP)
fprintf(f, "wpa_key_mgmt=FT-EAP WPA-EAP\n");
fprintf(f, "wpa_pairwise=%s\n",
hostapd_cipher_name(dut->ap_cipher));
if (dut->ap_group_cipher != AP_NO_GROUP_CIPHER_SET)
fprintf(f, "group_cipher=%s\n",
hostapd_cipher_name(dut->ap_group_cipher));
fprintf(f, "auth_server_addr=%s\n", dut->ap_radius_ipaddr);
if (dut->ap_radius_port)
fprintf(f, "auth_server_port=%d\n",
dut->ap_radius_port);
fprintf(f, "auth_server_shared_secret=%s\n",
dut->ap_radius_password);
if (dut->program == PROGRAM_HS2_R3) {
fprintf(f, "radius_das_port=3799\n");
fprintf(f, "radius_das_client=0.0.0.0 %s\n",
dut->ap_radius_password);
fprintf(f, "radius_das_require_event_timestamp=1\n");
}
break;
case AP_SUITEB:
fprintf(f, "ieee8021x=1\n");
fprintf(f, "wpa=2\n");
fprintf(f, "wpa_key_mgmt=WPA-EAP-SUITE-B-192\n");
fprintf(f, "wpa_pairwise=%s\n",
hostapd_cipher_name(dut->ap_cipher));
if (dut->ap_group_cipher != AP_NO_GROUP_CIPHER_SET)
fprintf(f, "group_cipher=%s\n",
hostapd_cipher_name(dut->ap_group_cipher));
if (dut->ap_group_mgmt_cipher != AP_NO_GROUP_MGMT_CIPHER_SET)
fprintf(f, "group_mgmt_cipher=%s\n",
hostapd_group_mgmt_cipher_name(
dut->ap_group_mgmt_cipher));
fprintf(f, "auth_server_addr=%s\n", dut->ap_radius_ipaddr);
if (dut->ap_radius_port)
fprintf(f, "auth_server_port=%d\n",
dut->ap_radius_port);
fprintf(f, "auth_server_shared_secret=%s\n",
dut->ap_radius_password);
break;
case AP_WPA2_OWE:
fprintf(f, "wpa=2\n");
fprintf(f, "wpa_key_mgmt=OWE\n");
fprintf(f, "rsn_pairwise=%s\n",
hostapd_cipher_name(dut->ap_cipher));
if (dut->ap_sae_groups)
fprintf(f, "owe_groups=%s\n", dut->ap_sae_groups);
break;
case AP_OSEN:
fprintf(f, "osen=1\n");
fprintf(f, "disable_dgaf=1\n");
fprintf(f, "wpa_pairwise=%s\n",
hostapd_cipher_name(dut->ap_cipher));
if (dut->ap_group_cipher != AP_NO_GROUP_CIPHER_SET)
fprintf(f, "group_cipher=%s\n",
hostapd_cipher_name(dut->ap_group_cipher));
fprintf(f, "auth_server_addr=%s\n", dut->ap_radius_ipaddr);
if (dut->ap_radius_port)
fprintf(f, "auth_server_port=%d\n",
dut->ap_radius_port);
fprintf(f, "auth_server_shared_secret=%s\n",
dut->ap_radius_password);
break;
}
skip_key_mgmt:
if (dut->ap_sae_passwords) {
char *tmp, *pos, *end, *id;
tmp = strdup(dut->ap_sae_passwords);
if (!tmp) {
fclose(f);
return ERROR_SEND_STATUS;
}
pos = tmp;
while (*pos) {
end = strchr(pos, ';');
if (end)
*end = '\0';
id = strchr(pos, ':');
if (id)
*id++ = '\0';
fprintf(f, "sae_password=%s%s%s\n",
pos, id ? "|id=" : "", id ? id : "");
if (!end)
break;
pos = end + 1;
}
free(tmp);
}
if (dut->ap_rsn_preauth)
fprintf(f, "rsn_preauth=1\n");
switch (dut->ap_pmf) {
case AP_PMF_DISABLED:
break;
case AP_PMF_OPTIONAL:
fprintf(f, "ieee80211w=1\n");
if (dut->ap_key_mgmt == AP_WPA2_PSK_SAE ||
(dut->ap_akm_values & (AKM_SAE | AKM_WPA_PSK)) ==
(AKM_SAE | AKM_WPA_PSK))
fprintf(f, "sae_require_mfp=1\n");
break;
case AP_PMF_REQUIRED:
fprintf(f, "ieee80211w=2\n");
break;
}
if (ap_ft_enabled(dut)) {
unsigned char own_addr[ETH_ALEN];
fprintf(f, "mobility_domain=%s\n", dut->ap_mobility_domain);
fprintf(f, "ft_over_ds=0\n");
if (get_hwaddr(ifname, own_addr) < 0) {
memset(own_addr, 0, ETH_ALEN);
own_addr[0] = 0x02;
}
fprintf(f,
"nas_identifier=%02x%02x%02x%02x%02x%02x.nas.example.com\n",
own_addr[0], own_addr[1], own_addr[2],
own_addr[3], own_addr[4], own_addr[5]);
fprintf(f, "r1_key_holder=%02x%02x%02x%02x%02x%02x\n",
own_addr[0], own_addr[1], own_addr[2],
own_addr[3], own_addr[4], own_addr[5]);
fprintf(f, "ft_psk_generate_local=1\n");
fprintf(f, "pmk_r1_push=0\n");
fprintf(f,
"r0kh=ff:ff:ff:ff:ff:ff * 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff\n");
fprintf(f,
"r1kh=00:00:00:00:00:00 00:00:00:00:00:00 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff\n");
}
if (dut->rsne_override)
fprintf(f, "own_ie_override=%s\n", dut->rsne_override);
if (dut->sae_commit_override)
fprintf(f, "sae_commit_override=%s\n",
dut->sae_commit_override);
if (dut->ap_sae_groups)
fprintf(f, "sae_groups=%s\n", dut->ap_sae_groups);
if (dut->sae_anti_clogging_threshold >= 0)
fprintf(f, "sae_anti_clogging_threshold=%d\n",
dut->sae_anti_clogging_threshold);
if (dut->sae_reflection)
fprintf(f, "sae_reflection_attack=1\n");
if (dut->ap_p2p_mgmt)
fprintf(f, "manage_p2p=1\n");
if (dut->ap_tdls_prohibit || dut->ap_l2tif)
fprintf(f, "tdls_prohibit=1\n");
if (dut->ap_tdls_prohibit_chswitch || dut->ap_l2tif)
fprintf(f, "tdls_prohibit_chan_switch=1\n");
if (dut->ap_p2p_cross_connect >= 0) {
fprintf(f, "manage_p2p=1\n"
"allow_cross_connection=%d\n",
dut->ap_p2p_cross_connect);
}
if (dut->ap_l2tif || dut->ap_proxy_arp ||
dut->ap_key_mgmt == AP_WPA2_EAP_OSEN) {
if (!dut->bridge) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Bridge must be configured. Run with -b <brname>.");
fclose(f);
return -2;
}
fprintf(f, "ap_isolate=1\n");
}
if (dut->ap_proxy_arp)
fprintf(f, "proxy_arp=1\n");
if (dut->ap_wme)
fprintf(f, "wmm_enabled=1\n");
if (dut->ap_wmmps == AP_WMMPS_ON)
fprintf(f, "uapsd_advertisement_enabled=1\n");
if (dut->ap_hs2) {
if (dut->ap_bss_load) {
char *bss_load;
switch (dut->ap_bss_load) {
case -1:
bss_load = "bss_load_update_period=10";
break;
case 1:
/* STA count: 1, CU: 50, AAC: 65535 */
bss_load = "bss_load_test=1:50:65535";
break;
case 2:
/* STA count: 1, CU: 200, AAC: 65535 */
bss_load = "bss_load_test=1:200:65535";
break;
case 3:
/* STA count: 1, CU: 75, AAC: 65535 */
bss_load = "bss_load_test=1:75:65535";
break;
default:
bss_load = NULL;
break;
}
if (!bss_load) {
fclose(f);
return -2;
}
fprintf(f, "%s\n", bss_load);
}
if (append_hostapd_conf_hs2(dut, f)) {
fclose(f);
return -2;
}
}
if (dut->ap_interworking && append_hostapd_conf_interworking(dut, f)) {
fclose(f);
return -2;
}
if (dut->ap_hs2 && strlen(dut->ap_tag_ssid[0])) {
unsigned char bssid[6];
char ifname2[50];
if (get_hwaddr(ifname, bssid)) {
fclose(f);
return -2;
}
if (bssid[0] & 0x02)
bssid[5] ^= 0x01;
else
bssid[0] |= 0x02;
snprintf(ifname2, sizeof(ifname2), "%s_1", ifname);
fprintf(f, "bss=%s\n", ifname2);
fprintf(f, "ssid=%s\n", dut->ap_tag_ssid[0]);
if (dut->bridge)
fprintf(f, "bridge=%s\n", dut->bridge);
if (drv == DRIVER_LINUX_WCN)
fprintf(f, "use_driver_iface_addr=1\n");
else
fprintf(f, "bssid=%02x:%02x:%02x:%02x:%02x:%02x\n",
bssid[0], bssid[1], bssid[2], bssid[3],
bssid[4], bssid[5]);
if (dut->ap_tag_key_mgmt[0] == AP2_OSEN) {
fprintf(f, "osen=1\n");
/* Disable DGAF for OSEN BSS */
fprintf(f, "disable_dgaf=1\n");
fprintf(f, "ap_isolate=1\n");
if (strlen(dut->ap2_radius_ipaddr))
fprintf(f, "auth_server_addr=%s\n",
dut->ap2_radius_ipaddr);
if (dut->ap2_radius_port)
fprintf(f, "auth_server_port=%d\n",
dut->ap2_radius_port);
if (strlen(dut->ap2_radius_password))
fprintf(f, "auth_server_shared_secret=%s\n",
dut->ap2_radius_password);
set_ebtables_forward_drop(dut, ifname, ifname2);
} else if (dut->ap2_osu) {
fprintf(f, "ap_isolate=1\n");
set_ebtables_forward_drop(dut, ifname, ifname2);
}
if (dut->ap2_proxy_arp) {
if (!dut->bridge) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Bridge must be configured. Run with -b <brname>.");
fclose(f);
return -2;
}
fprintf(f, "ap_isolate=1\n");
fprintf(f, "proxy_arp=1\n");
if (set_ebtables_proxy_arp(dut, "FORWARD", ifname2) ||
set_ebtables_proxy_arp(dut, "OUTPUT", ifname2)) {
fclose(f);
return -2;
}
}
}
if (dut->program == PROGRAM_WPS) {
/* 60G WPS tests requires wps_state of 2 (configured) */
int wps_state = is_60g_sigma_dut(dut) ? 2 : 1;
fprintf(f, "eap_server=1\n"
"wps_state=%d\n"
"device_name=QCA AP\n"
"manufacturer=QCA\n"
"device_type=6-0050F204-1\n"
"config_methods=label virtual_display %s"
"virtual_push_button keypad%s\n"
"ap_pin=12345670\n"
"friendly_name=QCA Access Point\n"
"upnp_iface=%s\n",
wps_state,
is_60g_sigma_dut(dut) ? "physical_display " : "",
dut->ap_wpsnfc ? " nfc_interface ext_nfc_token" : "",
dut->bridge ? dut->bridge : ifname);
if (dut->wsc_fragment) {
fprintf(f, "device_name=%s\n"
"manufacturer=%s\n"
"model_name=%s\n"
"model_number=%s\n"
"serial_number=%s\n",
WPS_LONG_DEVICE_NAME,
WPS_LONG_MANUFACTURER,
WPS_LONG_MODEL_NAME,
WPS_LONG_MODEL_NUMBER,
WPS_LONG_SERIAL_NUMBER);
} else {
fprintf(f, "device_name=QCA AP\n"
"manufacturer=QCA\n");
}
if (dut->eap_fragment)
fprintf(f, "fragment_size=128\n");
}
if (dut->program == PROGRAM_VHT) {
int vht_oper_centr_freq_idx;
if (check_channel(dut->ap_channel) < 0) {
send_resp(dut, conn, SIGMA_INVALID,
"errorCode,Invalid channel");
fclose(f);
return 0;
}
switch (dut->ap_chwidth) {
case AP_20:
dut->ap_vht_chwidth = AP_20_40_VHT_OPER_CHWIDTH;
vht_oper_centr_freq_idx =
get_oper_centr_freq_seq_idx(20,
dut->ap_channel);
break;
case AP_40:
dut->ap_vht_chwidth = AP_20_40_VHT_OPER_CHWIDTH;
vht_oper_centr_freq_idx =
get_oper_centr_freq_seq_idx(40,
dut->ap_channel);
break;
case AP_80:
dut->ap_vht_chwidth = AP_80_VHT_OPER_CHWIDTH;
vht_oper_centr_freq_idx =
get_oper_centr_freq_seq_idx(80,
dut->ap_channel);
break;
case AP_160:
dut->ap_vht_chwidth = AP_160_VHT_OPER_CHWIDTH;
vht_oper_centr_freq_idx =
get_oper_centr_freq_seq_idx(160,
dut->ap_channel);
break;
default:
dut->ap_vht_chwidth = VHT_DEFAULT_OPER_CHWIDTH;
vht_oper_centr_freq_idx =
get_oper_centr_freq_seq_idx(80,
dut->ap_channel);
break;
}
fprintf(f, "vht_oper_centr_freq_seg0_idx=%d\n",
vht_oper_centr_freq_idx);
fprintf(f, "vht_oper_chwidth=%d\n", dut->ap_vht_chwidth);
if (dut->ap_sgi80 || dut->ap_txBF ||
dut->ap_ldpc != VALUE_NOT_SET ||
dut->ap_tx_stbc || dut->ap_mu_txBF) {
fprintf(f, "vht_capab=%s%s%s%s%s\n",
dut->ap_sgi80 ? "[SHORT-GI-80]" : "",
dut->ap_txBF ?
"[SU-BEAMFORMER][SU-BEAMFORMEE][BF-ANTENNA-2][SOUNDING-DIMENSION-2]" : "",
(dut->ap_ldpc == VALUE_ENABLED) ?
"[RXLDPC]" : "",
dut->ap_tx_stbc ? "[TX-STBC-2BY1]" : "",
dut->ap_mu_txBF ? "[MU-BEAMFORMER]" : "");
}
}
if (dut->ap_key_mgmt == AP_WPA2_OWE && dut->ap_tag_ssid[0][0] &&
dut->ap_tag_key_mgmt[0] == AP2_OPEN) {
/* OWE transition mode */
unsigned char bssid[6];
char ifname2[50];
unsigned long val;
FILE *f2;
snprintf(ifname2, sizeof(ifname2), "%s_1", ifname);
fprintf(f, "owe_transition_ifname=%s\n", ifname2);
val = 0x12345678; /* default to something */
f2 = fopen("/dev/urandom", "r");
if (f2) {
if (fread(&val, 1, sizeof(val), f2) != sizeof(val)) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Could not read /dev/urandom");
}
fclose(f2);
}
fprintf(f, "ssid=owe-%lx\n", val);
fprintf(f, "ignore_broadcast_ssid=1\n");
if (get_hwaddr(ifname, bssid)) {
fclose(f);
return -2;
}
if (bssid[0] & 0x02)
bssid[5] ^= 0x01;
else
bssid[0] |= 0x02;
fprintf(f, "bss=%s\n", ifname2);
fprintf(f, "ssid=%s\n", dut->ap_ssid);
if (dut->bridge)
fprintf(f, "bridge=%s\n", dut->bridge);
if (drv == DRIVER_LINUX_WCN)
fprintf(f, "use_driver_iface_addr=1\n");
else
fprintf(f, "bssid=%02x:%02x:%02x:%02x:%02x:%02x\n",
bssid[0], bssid[1], bssid[2], bssid[3],
bssid[4], bssid[5]);
fprintf(f, "owe_transition_ifname=%s\n", ifname);
}
if (dut->ap_key_mgmt == AP_OPEN &&
dut->ap_tag_key_mgmt[0] == AP2_WPA2_OWE) {
/* OWE transition mode */
unsigned char bssid[6];
char ifname2[50];
unsigned long val;
FILE *f2;
snprintf(ifname2, sizeof(ifname2), "%s_1", ifname);
fprintf(f, "owe_transition_ifname=%s\n", ifname2);
fprintf(f, "ssid=%s\n", dut->ap_ssid);
if (get_hwaddr(ifname, bssid)) {
fclose(f);
return -2;
}
if (bssid[0] & 0x02)
bssid[5] ^= 0x01;
else
bssid[0] |= 0x02;
fprintf(f, "bss=%s\n", ifname2);
val = 0x12345678; /* default to something */
f2 = fopen("/dev/urandom", "r");
if (f2) {
if (fread(&val, 1, sizeof(val), f2) != sizeof(val)) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Could not read /dev/urandom");
}
fclose(f2);
}
fprintf(f, "ssid=owe-%lx\n", val);
if (dut->bridge)
fprintf(f, "bridge=%s\n", dut->bridge);
if (drv == DRIVER_LINUX_WCN)
fprintf(f, "use_driver_iface_addr=1\n");
else
fprintf(f, "bssid=%02x:%02x:%02x:%02x:%02x:%02x\n",
bssid[0], bssid[1], bssid[2], bssid[3],
bssid[4], bssid[5]);
fprintf(f, "owe_transition_ifname=%s\n", ifname);
fprintf(f, "wpa=2\n");
fprintf(f, "wpa_key_mgmt=OWE\n");
fprintf(f, "rsn_pairwise=CCMP\n");
fprintf(f, "ieee80211w=2\n");
fprintf(f, "ignore_broadcast_ssid=1\n");
if (dut->ap_sae_groups)
fprintf(f, "owe_groups=%s\n", dut->ap_sae_groups);
}
if (dut->program == PROGRAM_OCE) {
fprintf(f, "oce=%d\n",
dut->dev_role == DEVROLE_STA_CFON ? 2 : 1);
}
fclose(f);
if (dut->use_hostapd_pid_file)
kill_hostapd_process_pid(dut);
#ifdef __QNXNTO__
if (system("slay hostapd") == 0)
#else /* __QNXNTO__ */
if (!dut->use_hostapd_pid_file &&
(kill_process(dut, "(hostapd)", 1, SIGTERM) == 0 ||
system("killall hostapd") == 0))
#endif /* __QNXNTO__ */
{
int i;
/* Wait some time to allow hostapd to complete cleanup before
* starting a new process */
for (i = 0; i < 10; i++) {
usleep(500000);
#ifdef __QNXNTO__
if (system("pidin | grep hostapd") != 0)
break;
#else /* __QNXNTO__ */
if (system("pidof hostapd") != 0)
break;
#endif /* __QNXNTO__ */
}
}
dut->hostapd_running = 0;
#ifdef ANDROID
/* Set proper conf file permissions so that hostapd process
* can access it.
*/
if (chmod(SIGMA_TMPDIR "/sigma_dut-ap.conf",
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP) < 0)
sigma_dut_print(dut, DUT_MSG_ERROR,
"Error changing permissions");
gr = getgrnam("wifi");
if (!gr ||
chown(SIGMA_TMPDIR "/sigma_dut-ap.conf", -1, gr->gr_gid) < 0)
sigma_dut_print(dut, DUT_MSG_ERROR, "Error changing groupid");
#endif /* ANDROID */
if (drv == DRIVER_QNXNTO) {
snprintf(buf, sizeof(buf),
"hostapd -B %s%s %s%s" SIGMA_TMPDIR
"/sigma_dut-ap.conf",
dut->hostapd_debug_log ? "-ddKt -f " : "",
dut->hostapd_debug_log ? dut->hostapd_debug_log : "",
dut->hostapd_entropy_log ? " -e" : "",
dut->hostapd_entropy_log ? dut->hostapd_entropy_log :
"");
} else {
/*
* It looks like a monitor interface can cause some issues for
* beaconing, so remove it (if injection was used) before
* starting hostapd.
*/
if (if_nametoindex("sigmadut") > 0 &&
system("iw dev sigmadut del") != 0)
sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to remove "
"monitor interface");
snprintf(path, sizeof(path), "%shostapd",
file_exists("hostapd") ? "./" : "");
snprintf(buf, sizeof(buf), "%s -B%s%s%s%s%s " SIGMA_TMPDIR
"/sigma_dut-ap.conf",
dut->hostapd_bin ? dut->hostapd_bin : path,
dut->hostapd_debug_log ? " -ddKt -f" : "",
dut->hostapd_debug_log ? dut->hostapd_debug_log : "",
dut->hostapd_entropy_log ? " -e" : "",
dut->hostapd_entropy_log ? dut->hostapd_entropy_log :
"",
dut->use_hostapd_pid_file ?
" -P " SIGMA_DUT_HOSTAPD_PID_FILE : "");
}
sigma_dut_print(dut, DUT_MSG_DEBUG, "hostapd command: %s", buf);
if (system(buf) != 0) {
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Failed to start hostapd");
return 0;
}
/* allow some time for hostapd to start before returning success */
usleep(500000);
if (run_hostapd_cli(dut, "ping") != 0) {
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Failed to talk to hostapd");
return 0;
}
if (drv == DRIVER_LINUX_WCN) {
sigma_dut_print(dut, DUT_MSG_INFO, "setting ip addr %s mask %s",
ap_inet_addr, ap_inet_mask);
snprintf(buf, sizeof(buf), "ifconfig %s %s netmask %s up",
ifname, ap_inet_addr, ap_inet_mask);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Failed to initialize the interface");
return -1;
}
}
if (dut->ap_l2tif) {
snprintf(path, sizeof(path),
"/sys/class/net/%s/brport/hairpin_mode",
ifname);
if (!file_exists(path)) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"%s must be binded to the bridge for L2TIF",
ifname);
return -2;
}
snprintf(buf, sizeof(buf), "echo 1 > %s", path);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Failed to enable hairpin_mode for L2TIF");
return -2;
}
snprintf(buf, sizeof(buf), "ebtables -P FORWARD ACCEPT");
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Failed to set ebtables rules, RULE-9");
return -2;
}
snprintf(buf, sizeof(buf),
"ebtables -A FORWARD -p IPv4 --ip-proto icmp -i %s -j DROP",
ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Failed to set ebtables rules, RULE-11");
return -2;
}
}
if (dut->ap_proxy_arp) {
if (dut->ap_dgaf_disable) {
if (set_ebtables_disable_dgaf(dut, "FORWARD", ifname) ||
set_ebtables_disable_dgaf(dut, "OUTPUT", ifname))
return -2;
} else {
if (set_ebtables_proxy_arp(dut, "FORWARD", ifname) ||
set_ebtables_proxy_arp(dut, "OUTPUT", ifname))
return -2;
}
/* For 4.5-(c) */
snprintf(buf, sizeof(buf),
"ebtables -A FORWARD -p ARP --arp-opcode 2 -i %s -j DROP",
ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Failed to set ebtables rules, RULE-10");
return -2;
}
}
if (dut->ap_tdls_prohibit || dut->ap_l2tif) {
/* Drop TDLS frames */
snprintf(buf, sizeof(buf),
"ebtables -A FORWARD -p 0x890d -i %s -j DROP", ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Failed to set ebtables rules, RULE-13");
return -2;
}
}
if (dut->ap_fake_pkhash &&
run_hostapd_cli(dut, "set wps_corrupt_pkhash 1") != 0) {
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Could not enable FakePubKey");
return 0;
}
if (dut->program == PROGRAM_60GHZ && dut->ap_num_ese_allocs > 0) {
/* wait extra time for AP to start */
sleep(2);
if (ap_set_60g_ese(dut, dut->ap_num_ese_allocs,
dut->ap_ese_allocs)) {
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Could not set ExtSch");
return 0;
}
if (dut->ap_fixed_rate) {
sigma_dut_print(dut, DUT_MSG_DEBUG,
"forcing TX MCS index %d",
dut->ap_mcs);
if (ap_set_force_mcs(dut, 1, dut->ap_mcs)) {
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Could not force MCS");
return -2;
}
}
}
if (dut->wps_forced_version) {
snprintf(buf, sizeof(buf), "SET wps_version_number %d",
dut->wps_forced_version);
if (hapd_command(ifname, buf) < 0) {
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Fail to set wps_version_number");
return STATUS_SENT;
}
}
dut->hostapd_running = 1;
return 1;
}
static int parse_qos_params(struct sigma_dut *dut, struct sigma_conn *conn,
struct qos_params *qos, const char *cwmin,
const char *cwmax, const char *aifs,
const char *txop, const char *acm)
{
int val;
if (cwmin) {
qos->ac = 1;
val = atoi(cwmin);
if (val < 0 || val > 15) {
send_resp(dut, conn, SIGMA_INVALID,
"errorCode,Invalid cwMin");
return 0;
}
qos->cwmin = val;
}
if (cwmax) {
qos->ac = 1;
val = atoi(cwmax);
if (val < 0 || val > 15) {
send_resp(dut, conn, SIGMA_INVALID,
"errorCode,Invalid cwMax");
return 0;
}
qos->cwmax = val;
}
if (aifs) {
qos->ac = 1;
val = atoi(aifs);
if (val < 1 || val > 255) {
send_resp(dut, conn, SIGMA_INVALID,
"errorCode,Invalid AIFS");
return 0;
}
qos->aifs = val;
}
if (txop) {
qos->ac = 1;
val = atoi(txop);
if (val < 0 || val > 0xffff) {
send_resp(dut, conn, SIGMA_INVALID,
"errorCode,Invalid txop");
return 0;
}
qos->txop = val * 32;
}
if (acm) {
qos->ac = 1;
qos->acm = strcasecmp(acm, "on") == 0;
}
return 1;
}
static int cmd_ap_set_apqos(struct sigma_dut *dut, struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
/* TXOP: The values provided here for VHT5G only */
if (!parse_qos_params(dut, conn, &dut->ap_qos[AP_AC_VO],
get_param(cmd, "cwmin_VO"),
get_param(cmd, "cwmax_VO"),
get_param(cmd, "AIFS_VO"),
get_param(cmd, "TXOP_VO"),
get_param(cmd, "ACM_VO")) ||
!parse_qos_params(dut, conn, &dut->ap_qos[AP_AC_VI],
get_param(cmd, "cwmin_VI"),
get_param(cmd, "cwmax_VI"),
get_param(cmd, "AIFS_VI"),
get_param(cmd, "TXOP_VI"),
get_param(cmd, "ACM_VI")) ||
!parse_qos_params(dut, conn, &dut->ap_qos[AP_AC_BE],
get_param(cmd, "cwmin_BE"),
get_param(cmd, "cwmax_BE"),
get_param(cmd, "AIFS_BE"),
get_param(cmd, "TXOP_BE"),
get_param(cmd, "ACM_BE")) ||
!parse_qos_params(dut, conn, &dut->ap_qos[AP_AC_BK],
get_param(cmd, "cwmin_BK"),
get_param(cmd, "cwmax_BK"),
get_param(cmd, "AIFS_BK"),
get_param(cmd, "TXOP_BK"),
get_param(cmd, "ACM_BK")))
return 0;
return 1;
}
static int cmd_ap_set_staqos(struct sigma_dut *dut, struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
if (!parse_qos_params(dut, conn, &dut->ap_sta_qos[AP_AC_VO],
get_param(cmd, "cwmin_VO"),
get_param(cmd, "cwmax_VO"),
get_param(cmd, "AIFS_VO"),
get_param(cmd, "TXOP_VO"),
get_param(cmd, "ACM_VO")) ||
!parse_qos_params(dut, conn, &dut->ap_sta_qos[AP_AC_VI],
get_param(cmd, "cwmin_VI"),
get_param(cmd, "cwmax_VI"),
get_param(cmd, "AIFS_VI"),
get_param(cmd, "TXOP_VI"),
get_param(cmd, "ACM_VI")) ||
!parse_qos_params(dut, conn, &dut->ap_sta_qos[AP_AC_BE],
get_param(cmd, "cwmin_BE"),
get_param(cmd, "cwmax_BE"),
get_param(cmd, "AIFS_BE"),
get_param(cmd, "TXOP_BE"),
get_param(cmd, "ACM_BE")) ||
!parse_qos_params(dut, conn, &dut->ap_sta_qos[AP_AC_BK],
get_param(cmd, "cwmin_BK"),
get_param(cmd, "cwmax_BK"),
get_param(cmd, "AIFS_BK"),
get_param(cmd, "TXOP_BK"),
get_param(cmd, "ACM_BK")))
return 0;
return 1;
}
static void cmd_ath_ap_hs2_reset(struct sigma_dut *dut)
{
unsigned char bssid[6];
char buf[100];
run_system(dut, "cfg -a AP_SSID=\"Hotspot 2.0\"");
run_system(dut, "cfg -a AP_PRIMARY_CH=1");
run_system(dut, "cfg -a AP_SECMODE=WPA");
run_system(dut, "cfg -a AP_SECFILE=EAP");
run_system(dut, "cfg -a AP_WPA=2");
run_system(dut, "cfg -a AP_CYPHER=CCMP");
run_system(dut, "cfg -a AP_HOTSPOT=1");
run_system(dut, "cfg -a AP_HOTSPOT_ANT=2");
run_system(dut, "cfg -a AP_HOTSPOT_INTERNET=0");
run_system(dut, "cfg -a AP_HOTSPOT_VENUEGROUP=2");
run_system(dut, "cfg -a AP_HOTSPOT_VENUETYPE=8");
run_system(dut, "cfg -a AP_HOTSPOT_ROAMINGCONSORTIUM=506f9a");
run_system(dut, "cfg -a AP_HOTSPOT_ROAMINGCONSORTIUM2=001bc504bd");
if (!get_hwaddr("ath0", bssid)) {
snprintf(buf, sizeof(buf), "cfg -a AP_HOTSPOT_HESSID="
"%02x:%02x:%02x:%02x:%02x:%02x",
bssid[0], bssid[1], bssid[2], bssid[3],
bssid[4], bssid[5]);
run_system(dut, buf);
snprintf(dut->ap_hessid, sizeof(dut->ap_hessid),
"%02x:%02x:%02x:%02x:%02x:%02x",
bssid[0], bssid[1], bssid[2], bssid[3],
bssid[4], bssid[5]);
} else {
if (!get_hwaddr("wifi0", bssid)) {
snprintf(buf, sizeof(buf), "cfg -a AP_HOTSPOT_HESSID="
"%02x:%02x:%02x:%02x:%02x:%02x",
bssid[0], bssid[1], bssid[2], bssid[3],
bssid[4], bssid[5]);
run_system(dut, buf);
snprintf(dut->ap_hessid, sizeof(dut->ap_hessid),
"%02x:%02x:%02x:%02x:%02x:%02x",
bssid[0], bssid[1], bssid[2], bssid[3],
bssid[4], bssid[5]);
} else {
/* load the driver and try again */
run_system(dut, "/etc/rc.d/rc.wlan up");
if (!get_hwaddr("wifi0", bssid)) {
snprintf(buf, sizeof(buf),
"cfg -a AP_HOTSPOT_HESSID="
"%02x:%02x:%02x:%02x:%02x:%02x",
bssid[0], bssid[1], bssid[2],
bssid[3], bssid[4], bssid[5]);
run_system(dut, buf);
snprintf(dut->ap_hessid,
sizeof(dut->ap_hessid),
"%02x:%02x:%02x:%02x:%02x:%02x",
bssid[0], bssid[1], bssid[2],
bssid[3], bssid[4], bssid[5]);
}
}
}
run_system(dut, "cfg -r AP_SSID_2");
run_system(dut, "cfg -c");
/* run_system(dut, "cfg -s"); */
}
static void ath_reset_vht_defaults(struct sigma_dut *dut)
{
run_system(dut, "cfg -x");
run_system(dut, "cfg -a AP_RADIO_ID=1");
run_system(dut, "cfg -a AP_PRIMARY_CH_2=36");
run_system(dut, "cfg -a AP_STARTMODE=standard");
run_system(dut, "cfg -a AP_CHMODE_2=11ACVHT80");
run_system(dut, "cfg -a TX_CHAINMASK_2=7");
run_system(dut, "cfg -a RX_CHAINMASK_2=7");
run_system(dut, "cfg -a ATH_countrycode=0x348");
/* NOTE: For Beeliner we have to turn off MU-MIMO */
if (system("rm /tmp/secath*") != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Failed to remove secath file");
}
}
static int cmd_ap_reset_default(struct sigma_dut *dut, struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
const char *type, *program;
enum driver_type drv;
char buf[128];
int i;
for (i = 0; i < MAX_WLAN_TAGS - 1; i++) {
/*
* Reset all tagged SSIDs to NULL-string and all key management
* to open.
*/
dut->ap_tag_ssid[i][0] = '\0';
dut->ap_tag_key_mgmt[i] = AP2_OPEN;
}
drv = get_driver_type();
program = get_param(cmd, "program");
if (!program)
program = get_param(cmd, "prog");
dut->program = sigma_program_to_enum(program);
dut->device_type = AP_unknown;
type = get_param(cmd, "type");
if (type && strcasecmp(type, "Testbed") == 0)
dut->device_type = AP_testbed;
if (type && strcasecmp(type, "DUT") == 0)
dut->device_type = AP_dut;
dut->ap_rts = 0;
dut->ap_frgmnt = 0;
dut->ap_bcnint = 0;
dut->ap_key_mgmt = AP_OPEN;
dut->ap_ssid[0] = '\0';
dut->ap_fake_pkhash = 0;
memset(dut->ap_qos, 0, sizeof(dut->ap_qos));
memset(dut->ap_sta_qos, 0, sizeof(dut->ap_sta_qos));
dut->ap_addba_reject = VALUE_NOT_SET;
dut->ap_noack = VALUE_NOT_SET;
dut->ap_is_dual = 0;
dut->ap_mode = AP_inval;
dut->ap_mode_1 = AP_inval;
dut->ap_allow_vht_wep = 0;
dut->ap_allow_vht_tkip = 0;
dut->ap_disable_protection = 0;
memset(dut->ap_countrycode, 0, sizeof(dut->ap_countrycode));
dut->ap_dyn_bw_sig = VALUE_NOT_SET;
dut->ap_ldpc = VALUE_NOT_SET;
dut->ap_sig_rts = VALUE_NOT_SET;
dut->ap_rx_amsdu = VALUE_NOT_SET;
dut->ap_txBF = 0;
dut->ap_mu_txBF = 0;
dut->ap_chwidth = AP_AUTO;
dut->ap_rsn_preauth = 0;
dut->ap_wpsnfc = 0;
dut->ap_bss_load = -1;
dut->ap_p2p_cross_connect = -1;
dut->ap_regulatory_mode = AP_80211D_MODE_DISABLED;
dut->ap_dfs_mode = AP_DFS_MODE_DISABLED;
dut->ap_chwidth_offset = SEC_CH_NO;
dut->mbo_pref_ap_cnt = 0;
dut->ft_bss_mac_cnt = 0;
dut->ap_interface_5g = 0;
dut->ap_interface_2g = 0;
dut->ap_pmf = AP_PMF_DISABLED;
dut->wsc_fragment = 0;
dut->eap_fragment = 0;
dut->wps_forced_version = 0;
if (dut->program == PROGRAM_HT || dut->program == PROGRAM_VHT) {
dut->ap_wme = AP_WME_ON;
dut->ap_wmmps = AP_WMMPS_ON;
} else {
dut->ap_wme = AP_WME_OFF;
dut->ap_wmmps = AP_WMMPS_OFF;
}
dut->ap_venue_url = 0;
dut->ap_advice_of_charge = 0;
dut->ap_oper_icon_metadata = 0;
dut->ap_tnc_file_name = 0;
dut->ap_tnc_time_stamp = 0;
dut->ap_akm_values = 0;
free(dut->ap_sae_passwords);
dut->ap_sae_passwords = NULL;
if (dut->program == PROGRAM_HS2 || dut->program == PROGRAM_HS2_R2 ||
dut->program == PROGRAM_HS2_R3 ||
dut->program == PROGRAM_IOTLP) {
int i;
if (drv == DRIVER_ATHEROS)
cmd_ath_ap_hs2_reset(dut);
else if (drv == DRIVER_OPENWRT)
cmd_owrt_ap_hs2_reset(dut);
dut->ap_interworking = 1;
dut->ap_access_net_type = 2;
dut->ap_internet = 0;
dut->ap_venue_group = 2;
dut->ap_venue_type = 8;
dut->ap_domain_name_list[0] = '\0';
dut->ap_hs2 = 1;
snprintf(dut->ap_roaming_cons, sizeof(dut->ap_roaming_cons),
"506f9a;001bc504bd");
dut->ap_l2tif = 0;
dut->ap_proxy_arp = 0;
if (dut->bridge) {
char buf[50];
snprintf(buf, sizeof(buf), "ip neigh flush dev %s",
dut->bridge);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_DEBUG,
"%s ip neigh table flushing failed",
dut->bridge);
}
snprintf(buf, sizeof(buf), "ebtables -F");
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_DEBUG,
"%s ebtables flushing failed",
dut->bridge);
}
}
dut->ap_dgaf_disable = 0;
dut->ap_p2p_cross_connect = 0;
dut->ap_gas_cb_delay = 0;
dut->ap_nai_realm_list = 0;
dut->ap_oper_name = 0;
dut->ap_venue_name = 0;
for (i = 0; i < 10; i++) {
dut->ap_plmn_mcc[i][0] = '\0';
dut->ap_plmn_mnc[i][0] = '\0';
}
dut->ap_wan_metrics = 0;
dut->ap_conn_capab = 0;
dut->ap_ip_addr_type_avail = 0;
dut->ap_net_auth_type = 0;
dut->ap_oper_class = 0;
dut->ap_pmf = 0;
dut->ap_add_sha256 = 0;
}
if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3 ||
dut->program == PROGRAM_IOTLP) {
int i;
const char hessid[] = "50:6f:9a:00:11:22";
memcpy(dut->ap_hessid, hessid, strlen(hessid) + 1);
dut->ap_osu_ssid[0] = '\0';
dut->ap_pmf = 1;
dut->ap_osu_provider_list = 0;
dut->ap_osu_provider_nai_list = 0;
for (i = 0; i < 10; i++) {
dut->ap_osu_server_uri[i][0] = '\0';
dut->ap_osu_method[i] = 0xFF;
}
dut->ap_qos_map_set = 0;
dut->ap_tag_key_mgmt[0] = AP2_OPEN;
dut->ap2_proxy_arp = 0;
dut->ap2_osu = 0;
dut->ap_osu_icon_tag = 0;
}
if (dut->program == PROGRAM_VHT) {
/* Set up the defaults */
dut->ap_mode = AP_11ac;
dut->ap_channel = 36;
dut->ap_ampdu = VALUE_NOT_SET;
dut->ap_ndpa_frame = 1;
if (dut->device_type == AP_testbed) {
dut->ap_amsdu = VALUE_DISABLED;
dut->ap_ldpc = VALUE_DISABLED;
dut->ap_rx_amsdu = VALUE_DISABLED;
dut->ap_sgi80 = 0;
} else {
dut->ap_amsdu = VALUE_ENABLED;
/*
* As LDPC is optional, don't enable this by default
* for LINUX-WCN driver. The ap_set_wireless command
* can be used to enable LDPC, when needed.
*/
if (drv != DRIVER_LINUX_WCN)
dut->ap_ldpc = VALUE_ENABLED;
dut->ap_rx_amsdu = VALUE_ENABLED;
dut->ap_sgi80 = 1;
}
dut->ap_fixed_rate = 0;
dut->ap_rx_streams = 3;
dut->ap_tx_streams = 3;
dut->ap_vhtmcs_map = 0;
dut->ap_chwidth = AP_80;
dut->ap_tx_stbc = 1;
dut->ap_dyn_bw_sig = VALUE_ENABLED;
if (get_openwrt_driver_type() == OPENWRT_DRIVER_ATHEROS)
dut->ap_dfs_mode = AP_DFS_MODE_ENABLED;
if (get_driver_type() == DRIVER_ATHEROS)
ath_reset_vht_defaults(dut);
}
if (dut->program == PROGRAM_IOTLP) {
dut->wnm_bss_max_feature = VALUE_DISABLED;
dut->wnm_bss_max_idle_time = 0;
dut->wnm_bss_max_protection = VALUE_NOT_SET;
dut->ap_proxy_arp = 1;
} else {
/*
* Do not touch the BSS-MAX Idle time feature
* if the program is not IOTLP.
*/
dut->wnm_bss_max_feature = VALUE_NOT_SET;
dut->wnm_bss_max_idle_time = 0;
dut->wnm_bss_max_protection = VALUE_NOT_SET;
}
if (dut->program == PROGRAM_LOC) {
dut->ap_rrm = 1;
dut->ap_rtt = 1;
dut->ap_lci = 0;
dut->ap_val_lci[0] = '\0';
dut->ap_infoz[0] = '\0';
dut->ap_lcr = 0;
dut->ap_val_lcr[0] = '\0';
dut->ap_neighap = 0;
dut->ap_opchannel = 0;
dut->ap_scan = 0;
dut->ap_fqdn_held = 0;
dut->ap_fqdn_supl = 0;
dut->ap_interworking = 0;
dut->ap_gas_cb_delay = 0;
dut->ap_msnt_type = 0;
}
dut->ap_ft_oa = 0;
dut->ap_reg_domain = REG_DOMAIN_NOT_SET;
dut->ap_mobility_domain[0] = '\0';
if (dut->program == PROGRAM_MBO) {
dut->ap_mbo = 1;
dut->ap_interworking = 1;
dut->ap_ne_class = 0;
dut->ap_ne_op_ch = 0;
dut->ap_set_bssidpref = 1;
dut->ap_btmreq_disassoc_imnt = 0;
dut->ap_btmreq_term_bit = 0;
dut->ap_disassoc_timer = 0;
dut->ap_btmreq_bss_term_dur = 0;
dut->ap_channel = 36;
dut->ap_chwidth = AP_20;
dut->ap_cell_cap_pref = 0;
dut->ap_gas_cb_delay = 0;
dut->mbo_self_ap_tuple.ap_ne_class = -1;
dut->mbo_self_ap_tuple.ap_ne_pref = -1; /* Not set */
dut->mbo_self_ap_tuple.ap_ne_op_ch = -1;
dut->ap_btmreq_bss_term_tsf = 0;
dut->ap_assoc_delay = 0;
}
if (dut->program == PROGRAM_OCE) {
if (dut->ap_dhcp_stop)
run_system(dut, "/etc/init.d/dnsmasq start");
dut->ap_dhcp_stop = 0;
dut->ap_oce = VALUE_ENABLED;
dut->ap_broadcast_ssid = VALUE_ENABLED;
dut->ap_fils_dscv_int = 20;
dut->ap_filsdscv = VALUE_ENABLED;
dut->ap_filshlp = VALUE_DISABLED;
dut->ap_rnr = VALUE_DISABLED;
dut->ap_nairealm[0] = '\0';
dut->ap_nairealm_int = 0;
dut->ap_blechanutil = 0;
dut->ap_ble_admit_cap = 0;
dut->ap_esp = VALUE_ENABLED;
dut->ap_datappdudura = 0;
dut->ap_airtimefract = 0;
dut->ap_blestacnt = 0;
dut->ap_ul_availcap = 0;
dut->ap_dl_availcap = 0;
dut->ap_akm = 0;
dut->ap_add_sha256 = 0;
dut->ap_add_sha384 = 0;
dut->ap_pmksa = 0;
dut->ap_pmksa_caching = 0;
dut->ap_80plus80 = 0;
}
dut->ap_he_ppdu = PPDU_NOT_SET;
dut->ap_oper_chn = 0;
free(dut->rsne_override);
dut->rsne_override = NULL;
free(dut->sae_commit_override);
dut->sae_commit_override = NULL;
free(dut->ap_sae_groups);
dut->ap_sae_groups = NULL;
dut->sae_anti_clogging_threshold = -1;
dut->sae_reflection = 0;
dut->ap_cipher = AP_CCMP;
dut->ap_group_cipher = AP_NO_GROUP_CIPHER_SET;
dut->ap_group_mgmt_cipher = AP_NO_GROUP_MGMT_CIPHER_SET;
dut->ap_passphrase[0] = '\0';
dut->ap_psk[0] = '\0';
dut->dpp_conf_id = -1;
if (is_60g_sigma_dut(dut)) {
dut->ap_mode = AP_11ad;
dut->ap_channel = 2;
dut->wps_disable = 0; /* WPS is enabled */
dut->ap_pmf = 0;
dut->ap_num_ese_allocs = 0;
dut->ap_fixed_rate = 0;
dut->dev_role = DEVROLE_AP;
sigma_dut_print(dut, DUT_MSG_DEBUG,
"Setting msdu_size to MAX: 7912");
snprintf(buf, sizeof(buf), "ifconfig %s mtu 7912",
get_main_ifname());
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
buf);
return ERROR_SEND_STATUS;
}
if (ap_set_force_mcs(dut, 0, 1)) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Failed to reset force MCS");
return ERROR_SEND_STATUS;
}
if (set_ps(get_main_ifname(), dut, 1)) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Failed to enable power save");
return ERROR_SEND_STATUS;
}
}
if (dut->program == PROGRAM_WPS &&
get_driver_type() == DRIVER_WIL6210) {
/*
* In 60 GHz WPS tests, we configure the AP OOB to
* secure connection with a random passphrase.
*/
char r[16], passphrase[65];
if (random_get_bytes(r, sizeof(r))) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Failed to get random bytes");
return ERROR_SEND_STATUS;
}
if (base64_encode(r, sizeof(r),
passphrase, sizeof(passphrase))) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Failed to generate random passphrase");
return ERROR_SEND_STATUS;
}
dut->ap_key_mgmt = AP_WPA2_PSK;
dut->ap_cipher = AP_GCMP_128;
strlcpy(dut->ap_passphrase, passphrase,
sizeof(dut->ap_passphrase));
sigma_dut_print(dut, DUT_MSG_DEBUG,
"60G WPS: configure secure AP with random passphrase");
}
dut->hostapd_running = 0;
if (get_openwrt_driver_type() == OPENWRT_DRIVER_ATHEROS)
return 1;
if (dut->use_hostapd_pid_file) {
kill_hostapd_process_pid(dut);
} else if (kill_process(dut, "(hostapd)", 1, SIGTERM) == 0 ||
system("killall hostapd") == 0) {
int i;
/* Wait some time to allow hostapd to complete cleanup before
* starting a new process */
for (i = 0; i < 10; i++) {
usleep(500000);
if (system("pidof hostapd") != 0)
break;
}
}
if (if_nametoindex("sigmadut") > 0 &&
system("iw dev sigmadut del") != 0)
sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to remove "
"monitor interface");
return 1;
}
int sta_cfon_reset_default(struct sigma_dut *dut, struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
return cmd_ap_reset_default(dut, conn, cmd);
}
static int cmd_ap_get_info(struct sigma_dut *dut, struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
/* const char *name = get_param(cmd, "NAME"); */
struct stat s;
char resp[200];
FILE *f;
enum driver_type drv = get_driver_type();
switch (drv) {
case DRIVER_ATHEROS: {
/* Atheros AP */
struct utsname uts;
char *version, athver[100];
if (stat("/proc/athversion", &s) != 0) {
if (system("/etc/rc.d/rc.wlan up") != 0) {
}
}
athver[0] = '\0';
f = fopen("/proc/athversion", "r");
if (f) {
if (fgets(athver, sizeof(athver), f)) {
char *pos = strchr(athver, '\n');
if (pos)
*pos = '\0';
}
fclose(f);
}
if (uname(&uts) == 0)
version = uts.release;
else
version = "Unknown";
if (if_nametoindex("ath1") > 0)
snprintf(resp, sizeof(resp), "interface,ath0_24G "
"ath1_5G,agent,1.0,version,%s/drv:%s",
version, athver);
else
snprintf(resp, sizeof(resp), "interface,ath0_24G,"
"agent,1.0,version,%s/drv:%s",
version, athver);
send_resp(dut, conn, SIGMA_COMPLETE, resp);
return 0;
}
case DRIVER_LINUX_WCN:
case DRIVER_MAC80211: {
struct utsname uts;
char *version;
if (uname(&uts) == 0)
version = uts.release;
else
version = "Unknown";
if (if_nametoindex("wlan1") > 0)
snprintf(resp, sizeof(resp), "interface,wlan0_24G "
"wlan1_5G,agent,1.0,version,%s", version);
else
snprintf(resp, sizeof(resp), "interface,wlan0_any,"
"agent,1.0,version,%s", version);
send_resp(dut, conn, SIGMA_COMPLETE, resp);
return 0;
}
case DRIVER_QNXNTO: {
struct utsname uts;
char *version;
if (uname(&uts) == 0)
version = uts.release;
else
version = "Unknown";
snprintf(resp, sizeof(resp),
"interface,%s_any,agent,1.0,version,%s",
sigma_main_ifname ? sigma_main_ifname : "NA",
version);
send_resp(dut, conn, SIGMA_COMPLETE, resp);
return 0;
}
case DRIVER_OPENWRT: {
switch (get_openwrt_driver_type()) {
case OPENWRT_DRIVER_ATHEROS: {
struct utsname uts;
char *version;
if (uname(&uts) == 0)
version = uts.release;
else
version = "Unknown";
if (if_nametoindex("ath1") > 0)
snprintf(resp, sizeof(resp),
"interface,ath0_5G ath1_24G,agent,1.0,version,%s",
version);
else
snprintf(resp, sizeof(resp),
"interface,ath0_any,agent,1.0,version,%s",
version);
send_resp(dut, conn, SIGMA_COMPLETE, resp);
return 0;
}
default:
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Unsupported openwrt driver");
return 0;
}
}
default:
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Unsupported driver");
return 0;
}
}
static int cmd_ap_deauth_sta(struct sigma_dut *dut, struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
/* const char *name = get_param(cmd, "NAME"); */
/* const char *ifname = get_param(cmd, "INTERFACE"); */
const char *val;
char buf[100];
val = get_param(cmd, "MinorCode");
if (val) {
/* TODO: add support for P2P minor code */
send_resp(dut, conn, SIGMA_ERROR, "errorCode,MinorCode not "
"yet supported");
return 0;
}
val = get_param(cmd, "STA_MAC_ADDRESS");
if (val == NULL)
return -1;
snprintf(buf, sizeof(buf), "deauth %s", val);
if (run_hostapd_cli(dut, buf) != 0)
return -2;
return 1;
}
#ifdef __linux__
int inject_frame(int s, const void *data, size_t len, int encrypt);
int open_monitor(const char *ifname);
#endif /* __linux__ */
enum send_frame_type {
DISASSOC, DEAUTH, SAQUERY
};
enum send_frame_protection {
CORRECT_KEY, INCORRECT_KEY, UNPROTECTED
};
static int ap_inject_frame(struct sigma_dut *dut, struct sigma_conn *conn,
enum send_frame_type frame,
enum send_frame_protection protected,
const char *sta_addr)
{
#ifdef __linux__
unsigned char buf[1000], *pos;
int s, res;
unsigned char addr_sta[6], addr_own[6];
char *ifname;
char cbuf[100];
struct ifreq ifr;
if ((dut->ap_mode == AP_11a || dut->ap_mode == AP_11na ||
dut->ap_mode == AP_11ac) &&
if_nametoindex("wlan1") > 0)
ifname = "wlan1";
else
ifname = "wlan0";
if (hwaddr_aton(sta_addr, addr_sta) < 0)
return -1;
s = socket(AF_INET, SOCK_DGRAM, 0);
if (s < 0)
return -1;
memset(&ifr, 0, sizeof(ifr));
strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) {
perror("ioctl");
close(s);
return -1;
}
close(s);
memcpy(addr_own, ifr.ifr_hwaddr.sa_data, 6);
if (if_nametoindex("sigmadut") == 0) {
snprintf(cbuf, sizeof(cbuf),
"iw dev %s interface add sigmadut type monitor",
ifname);
if (system(cbuf) != 0 ||
if_nametoindex("sigmadut") == 0) {
sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
"monitor interface with '%s'", cbuf);
return -2;
}
}
if (system("ifconfig sigmadut up") != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
"monitor interface up");
return -2;
}
pos = buf;
/* Frame Control */
switch (frame) {
case DISASSOC:
*pos++ = 0xa0;
break;
case DEAUTH:
*pos++ = 0xc0;
break;
case SAQUERY:
*pos++ = 0xd0;
break;
}
if (protected == INCORRECT_KEY)
*pos++ = 0x40; /* Set Protected field to 1 */
else
*pos++ = 0x00;
/* Duration */
*pos++ = 0x00;
*pos++ = 0x00;
/* addr1 = DA (station) */
memcpy(pos, addr_sta, 6);
pos += 6;
/* addr2 = SA (own address) */
memcpy(pos, addr_own, 6);
pos += 6;
/* addr3 = BSSID (own address) */
memcpy(pos, addr_own, 6);
pos += 6;
/* Seq# (to be filled by driver/mac80211) */
*pos++ = 0x00;
*pos++ = 0x00;
if (protected == INCORRECT_KEY) {
/* CCMP parameters */
memcpy(pos, "\x61\x01\x00\x20\x00\x10\x00\x00", 8);
pos += 8;
}
if (protected == INCORRECT_KEY) {
switch (frame) {
case DEAUTH:
/* Reason code (encrypted) */
memcpy(pos, "\xa7\x39", 2);
pos += 2;
break;
case DISASSOC:
/* Reason code (encrypted) */
memcpy(pos, "\xa7\x39", 2);
pos += 2;
break;
case SAQUERY:
/* Category|Action|TransID (encrypted) */
memcpy(pos, "\x6f\xbd\xe9\x4d", 4);
pos += 4;
break;
default:
return -1;
}
/* CCMP MIC */
memcpy(pos, "\xc8\xd8\x3b\x06\x5d\xb7\x25\x68", 8);
pos += 8;
} else {
switch (frame) {
case DEAUTH:
/* reason code = 8 */
*pos++ = 0x08;
*pos++ = 0x00;
break;
case DISASSOC:
/* reason code = 8 */
*pos++ = 0x08;
*pos++ = 0x00;
break;
case SAQUERY:
/* Category - SA Query */
*pos++ = 0x08;
/* SA query Action - Request */
*pos++ = 0x00;
/* Transaction ID */
*pos++ = 0x12;
*pos++ = 0x34;
break;
}
}
s = open_monitor("sigmadut");
if (s < 0) {
send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
"monitor socket");
return 0;
}
res = inject_frame(s, buf, pos - buf, protected == CORRECT_KEY);
if (res < 0) {
send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
"inject frame");
close(s);
return 0;
}
if (res < pos - buf) {
send_resp(dut, conn, SIGMA_ERROR, "errorCode,Only partial "
"frame sent");
close(s);
return 0;
}
close(s);
return 1;
#else /* __linux__ */
send_resp(dut, conn, SIGMA_ERROR, "errorCode,ap_send_frame not "
"yet supported");
return 0;
#endif /* __linux__ */
}
int ap_send_frame_hs2(struct sigma_dut *dut, struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
const char *val, *dest;
char buf[100];
val = get_param(cmd, "FrameName");
if (val == NULL)
return -1;
if (strcasecmp(val, "QoSMapConfigure") == 0) {
dest = get_param(cmd, "Dest");
if (!dest)
return -1;
val = get_param(cmd, "QoS_MAP_SET");
if (val) {
dut->ap_qos_map_set = atoi(val);
sigma_dut_print(dut, DUT_MSG_INFO, "ap_qos_map_set %d",
dut->ap_qos_map_set);
}
if (dut->ap_qos_map_set == 1)
run_hostapd_cli(dut, "set_qos_map_set " QOS_MAP_SET_1);
else if (dut->ap_qos_map_set == 2)
run_hostapd_cli(dut, "set_qos_map_set " QOS_MAP_SET_2);
snprintf(buf, sizeof(buf), "send_qos_map_conf %s", dest);
if (run_hostapd_cli(dut, buf) != 0)
return -1;
}
return 1;
}
static int ath_ap_send_frame_vht(struct sigma_dut *dut, struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
const char *val;
char *ifname;
char buf[100];
int chwidth, nss;
val = get_param(cmd, "FrameName");
if (!val || strcasecmp(val, "op_md_notif_frm") != 0) {
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Unsupported FrameName");
return 0;
}
/*
* Sequence of commands for Opmode notification on
* Peregrine based products
*/
ifname = get_main_ifname();
/* Disable STBC */
snprintf(buf, sizeof(buf), "iwpriv %s tx_stbc 0", ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"iwpriv tx_stbc 0 failed!");
}
/* Check whether optional arg channel width was passed */
val = get_param(cmd, "Channel_width");
if (val) {
switch (atoi(val)) {
case 20:
chwidth = 0;
break;
case 40:
chwidth = 1;
break;
case 80:
chwidth = 2;
break;
case 160:
chwidth = 3;
break;
default:
chwidth = 2;
break;
}
snprintf(buf, sizeof(buf), "iwpriv %s chwidth %d",
ifname, chwidth);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"iwpriv chwidth failed!");
}
}
/* Check whether optional arg NSS was passed */
val = get_param(cmd, "NSS");
if (val) {
/* Convert nss to chainmask */
switch (atoi(val)) {
case 1:
nss = 1;
break;
case 2:
nss = 3;
break;
case 3:
nss = 7;
break;
default:
/* We do not support NSS > 3 */
nss = 3;
break;
}
snprintf(buf, sizeof(buf), "iwpriv %s rxchainmask %d",
ifname, nss);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"iwpriv rxchainmask failed!");
}
}
/* Send the opmode notification */
snprintf(buf, sizeof(buf), "iwpriv %s opmode_notify 1", ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"iwpriv opmode_notify failed!");
}
return 1;
}
static int ath_ap_send_frame_loc(struct sigma_dut *dut, struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
const char *val;
FILE *f;
int rand_int = 0;
val = get_param(cmd, "MsntType");
if (val) {
if (dut->ap_msnt_type == 0)
dut->ap_msnt_type = atoi(val);
if (dut->ap_msnt_type != 5 && dut->ap_msnt_type != 2) {
dut->ap_msnt_type = atoi(val);
if (dut->ap_msnt_type == 1) {
val = get_param(cmd, "RandInterval");
if (val)
rand_int = atoi(val);
f = fopen("/tmp/ftmrr.txt", "a");
if (!f) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Failed to open /tmp/ftmrr.txt");
return -1;
}
fprintf(f, "sta_mac = %s\n", cmd->values[3]);
fprintf(f, "meas_type = 0x10\nrand_inter = 0x%x\nmin_ap_count = 0x%s\ndialogtoken = 0x1\nnum_repetitions = 0x0\nmeas_token = 0xf\nmeas_req_mode = 0x00\n",
rand_int, cmd->values[7]);
fclose(f);
dut->ap_msnt_type = 5;
run_system(dut, "wpc -f /tmp/ftmrr.txt");
}
} else if (dut->ap_msnt_type == 5) {
run_system(dut, "wpc -f /tmp/ftmrr.txt");
} else if (dut->ap_msnt_type == 2) {
f = fopen("/tmp/wru.txt", "w");
if (!f) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Failed to open /tmp/wru.txt");
return -1;
}
fprintf(f, "sta_mac = %s\n", cmd->values[3]);
fprintf(f, "meas_type = 0x08\ndialogtoken = 0x1\nnum_repetitions = 0x0\nmeas_token = 0x1\nmeas_req_mode = 0x00\nloc_subject = 0x01\n");
fclose(f);
run_system(dut, "wpc -w /tmp/wru.txt");
}
}
return 1;
}
/*
* The following functions parse_send_frame_params_int(),
* parse_send_frame_params_str(), and parse_send_frame_params_mac()
* are used by ath_ap_send_frame_bcn_rpt_req().
* Beacon Report Request is a frame used as part of the MBO program.
* The command for sending beacon report has a lot of
* arguments and having these functions reduces code size.
*
*/
static int parse_send_frame_params_int(char *param, struct sigma_cmd *cmd,
struct sigma_dut *dut,
char *buf, size_t buf_size)
{
const char *str_val;
int int_val;
char temp[100];
str_val = get_param(cmd, param);
if (!str_val) {
sigma_dut_print(dut, DUT_MSG_ERROR, "%s not given", param);
return -1;
}
int_val = atoi(str_val);
snprintf(temp, sizeof(temp), " %d", int_val);
strlcat(buf, temp, buf_size);
return 0;
}
static int parse_send_frame_params_str(char *param, struct sigma_cmd *cmd,
struct sigma_dut *dut,
char *buf, size_t buf_size)
{
const char *str_val;
char temp[100];
str_val = get_param(cmd, param);
if (!str_val) {
sigma_dut_print(dut, DUT_MSG_ERROR, "%s not given", param);
return -1;
}
snprintf(temp, sizeof(temp), " %s", str_val);
temp[sizeof(temp) - 1] = '\0';
strlcat(buf, temp, buf_size);
return 0;
}
static int parse_send_frame_params_mac(char *param, struct sigma_cmd *cmd,
struct sigma_dut *dut,
char *buf, size_t buf_size)
{
const char *str_val;
unsigned char mac[6];
char temp[100];
str_val = get_param(cmd, param);
if (!str_val) {
sigma_dut_print(dut, DUT_MSG_ERROR, "%s not given", param);
return -1;
}
if (parse_mac_address(dut, str_val, mac) < 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"MAC Address not in proper format");
return -1;
}
snprintf(temp, sizeof(temp), " %02x:%02x:%02x:%02x:%02x:%02x",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
strlcat(buf, temp, buf_size);
return 0;
}
static void fill_1_or_0_based_on_presence(struct sigma_cmd *cmd, char *param,
char *buf, size_t buf_size)
{
const char *str_val;
char *value = " 1";
str_val = get_param(cmd, param);
if (!str_val || str_val[0] == '\0')
value = " 0";
strlcat(buf, value, buf_size);
}
/*
* wifitool athN sendbcnrpt
* <STA MAC - Plugs in from Dest_MAC>
* <regclass - Plugs in from RegClass - int>
* <channum - Plugs in from Channel PARAM of dev_send_frame - int>
* <rand_ivl - Plugs in from RandInt - string>
* <duration - Plugs in from MeaDur - integer>
* <mode - Plugs in from MeaMode - string>
* <req_ssid - Plugs in from SSID PARAM of dev_send_frame - string>
* <rep_cond - Plugs in from RptCond - integer>
* <rpt_detail - Plugs in from RptDet - integer>
* <req_ie - Plugs in from ReqInfo PARAM of dev_send_frame - string>
* <chanrpt_mode - Plugs in from APChanRpt - integer>
* <specific_bssid - Plugs in from BSSID PARAM of dev_send_frame>
* [AP channel numbers]
*/
static int ath_ap_send_frame_bcn_rpt_req(struct sigma_dut *dut,
struct sigma_cmd *cmd,
const char *ifname)
{
char buf[100];
int rpt_det;
const char *str_val;
const char *mea_mode;
snprintf(buf, sizeof(buf), "wifitool %s sendbcnrpt", ifname);
if (parse_send_frame_params_mac("Dest_MAC", cmd, dut, buf, sizeof(buf)))
return -1;
if (parse_send_frame_params_int("RegClass", cmd, dut, buf, sizeof(buf)))
return -1;
if (parse_send_frame_params_int("Channel", cmd, dut, buf, sizeof(buf)))
return -1;
if (parse_send_frame_params_str("RandInt", cmd, dut, buf, sizeof(buf)))
return -1;
if (parse_send_frame_params_int("MeaDur", cmd, dut, buf, sizeof(buf)))
return -1;
str_val = get_param(cmd, "MeaMode");
if (!str_val) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"MeaMode parameter not present in send bcn-rpt-req");
return -1;
}
if (strcasecmp(str_val, "passive") == 0) {
mea_mode = " 0";
} else if (strcasecmp(str_val, "active") == 0) {
mea_mode = " 1";
} else if (strcasecmp(str_val, "table") == 0) {
mea_mode = " 2";
} else {
sigma_dut_print(dut, DUT_MSG_ERROR,
"MEA-MODE Value not correctly given");
return -1;
}
strlcat(buf, mea_mode, sizeof(buf));
fill_1_or_0_based_on_presence(cmd, "SSID", buf, sizeof(buf));
if (parse_send_frame_params_int("RptCond", cmd, dut, buf, sizeof(buf)))
return -1;
if (parse_send_frame_params_int("RptDet", cmd, dut, buf, sizeof(buf)))
return -1;
str_val = get_param(cmd, "RptDet");
rpt_det = str_val ? atoi(str_val) : 0;
if (rpt_det)
fill_1_or_0_based_on_presence(cmd, "ReqInfo", buf, sizeof(buf));
else
strlcat(buf, " 0", sizeof(buf));
if (rpt_det)
fill_1_or_0_based_on_presence(cmd, "APChanRpt", buf,
sizeof(buf));
else
strlcat(buf, " 0", sizeof(buf));
if (parse_send_frame_params_mac("BSSID", cmd, dut, buf, sizeof(buf)))
return -1;
str_val = get_param(cmd, "APChanRpt");
if (str_val) {
const char *pos;
int ap_chanrpt;
int ap_chanrpt_2 = 0;
char chanrpt[100];
ap_chanrpt = atoi(str_val);
pos = strchr(str_val, '_');
if (pos) {
pos++;
ap_chanrpt_2 = atoi(pos);
}
if (ap_chanrpt) {
snprintf(chanrpt, sizeof(chanrpt), " %d", ap_chanrpt);
strlcat(buf, chanrpt, sizeof(buf));
}
if (ap_chanrpt_2) {
snprintf(chanrpt, sizeof(chanrpt), " %d", ap_chanrpt_2);
strlcat(buf, chanrpt, sizeof(buf));
}
}
run_system(dut, buf);
return 0;
}
static void inform_and_sleep(struct sigma_dut *dut, int seconds)
{
sigma_dut_print(dut, DUT_MSG_DEBUG, "sleeping for %d seconds", seconds);
sleep(seconds);
sigma_dut_print(dut, DUT_MSG_DEBUG, "woke up after %d seconds",
seconds);
}
static int ath_ap_send_frame_btm_req(struct sigma_dut *dut,
struct sigma_cmd *cmd, const char *ifname)
{
unsigned char mac_addr[ETH_ALEN];
int disassoc_timer;
char buf[100];
const char *val;
int cand_list = 1;
val = get_param(cmd, "Dest_MAC");
if (!val || parse_mac_address(dut, val, mac_addr) < 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"MAC Address not in proper format");
return -1;
}
val = get_param(cmd, "Disassoc_Timer");
if (val)
disassoc_timer = atoi(val);
else
disassoc_timer = dut->ap_disassoc_timer;
if (disassoc_timer < 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Invalid Disassoc_Timer value %d",
disassoc_timer);
return -1;
}
val = get_param(cmd, "Cand_List");
if (val && val[0])
cand_list = atoi(val);
val = get_param(cmd, "BTMQuery_Reason_Code");
if (val) {
snprintf(buf, sizeof(buf), "iwpriv %s mbo_trans_rs %s",
ifname, val);
run_system(dut, buf);
}
if (dut->ap_btmreq_disassoc_imnt && !dut->ap_assoc_delay) {
snprintf(buf, sizeof(buf), "iwpriv %s mbo_asoc_ret 1", ifname);
run_system(dut, buf);
}
snprintf(buf, sizeof(buf),
"wifitool %s sendbstmreq %02x:%02x:%02x:%02x:%02x:%02x %d %d 15 %d %d %d %d",
ifname, mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3],
mac_addr[4], mac_addr[5], cand_list, disassoc_timer,
dut->ap_btmreq_disassoc_imnt,
dut->ap_btmreq_term_bit,
dut->ap_btmreq_bss_term_tsf,
dut->ap_btmreq_bss_term_dur);
run_system(dut, buf);
if (dut->ap_btmreq_term_bit) {
if (dut->ap_btmreq_bss_term_tsf >= 2)
inform_and_sleep(dut, dut->ap_btmreq_bss_term_tsf - 2);
run_system_wrapper(
dut, "iwpriv %s kickmac %02x:%02x:%02x:%02x:%02x:%02x",
ifname,
mac_addr[0], mac_addr[1], mac_addr[2],
mac_addr[3], mac_addr[4], mac_addr[5]);
inform_and_sleep(dut, 2);
run_system_wrapper(dut, "ifconfig %s down", ifname);
inform_and_sleep(dut, 5);
run_system_wrapper(dut, "ifconfig %s up", ifname);
} else if (dut->ap_btmreq_disassoc_imnt) {
inform_and_sleep(dut, (disassoc_timer / 1000) + 1);
run_system_wrapper(dut,
"iwpriv %s kickmac %02x:%02x:%02x:%02x:%02x:%02x",
ifname,
mac_addr[0], mac_addr[1], mac_addr[2],
mac_addr[3], mac_addr[4], mac_addr[5]);
}
return 0;
}
static int ath_ap_send_frame_disassoc(struct sigma_dut *dut,
struct sigma_cmd *cmd, const char *ifname)
{
unsigned char mac_addr[ETH_ALEN];
const char *val;
val = get_param(cmd, "Dest_MAC");
if (!val || parse_mac_address(dut, val, mac_addr) < 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"MAC Address not in proper format");
return -1;
}
run_system_wrapper(dut,
"iwpriv %s kickmac %02x:%02x:%02x:%02x:%02x:%02x",
ifname, mac_addr[0], mac_addr[1], mac_addr[2],
mac_addr[3], mac_addr[4], mac_addr[5]);
return 0;
}
static int ath_ap_send_frame_mbo(struct sigma_dut *dut, struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
const char *val;
char *ifname;
ifname = get_main_ifname();
val = get_param(cmd, "FrameName");
if (!val)
return -1;
if (strcasecmp(val, "BTMReq") == 0)
ath_ap_send_frame_btm_req(dut, cmd, ifname);
else if (strcasecmp(val, "BcnRptReq") == 0)
ath_ap_send_frame_bcn_rpt_req(dut, cmd, ifname);
else if (strcasecmp(val, "disassoc") == 0)
ath_ap_send_frame_disassoc(dut, cmd, ifname);
else
return -1;
return 1;
}
static int ap_send_frame_vht(struct sigma_dut *dut, struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
switch (get_driver_type()) {
case DRIVER_ATHEROS:
return ath_ap_send_frame_vht(dut, conn, cmd);
break;
case DRIVER_OPENWRT:
switch (get_openwrt_driver_type()) {
case OPENWRT_DRIVER_ATHEROS:
return ath_ap_send_frame_vht(dut, conn, cmd);
default:
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Unsupported ap_send_frame with the current openwrt driver");
return 0;
}
default:
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Unsupported ap_send_frame with the current driver");
return 0;
}
}
static int ap_send_frame_loc(struct sigma_dut *dut, struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
switch (get_driver_type()) {
case DRIVER_ATHEROS:
return ath_ap_send_frame_loc(dut, conn, cmd);
case DRIVER_OPENWRT:
switch (get_openwrt_driver_type()) {
case OPENWRT_DRIVER_ATHEROS:
return ath_ap_send_frame_loc(dut, conn, cmd);
default:
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Unsupported ap_send_frame_loc with the current openwrt driver");
return 0;
}
default:
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Unsupported ap_send_frame_loc with the current driver");
return 0;
}
}
static int ap_send_frame_mbo(struct sigma_dut *dut, struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
switch (get_driver_type()) {
case DRIVER_ATHEROS:
return ath_ap_send_frame_mbo(dut, conn, cmd);
case DRIVER_OPENWRT:
switch (get_openwrt_driver_type()) {
case OPENWRT_DRIVER_ATHEROS:
return ath_ap_send_frame_mbo(dut, conn, cmd);
default:
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Unsupported ap_send_frame with the current openwrt driver");
return 0;
}
default:
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Unsupported ap_send_frame with the current driver");
return 0;
}
}
static int ap_send_frame_60g(struct sigma_dut *dut,
struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
switch (get_driver_type()) {
#ifdef __linux__
case DRIVER_WIL6210:
return wil6210_send_frame_60g(dut, conn, cmd);
#endif /* __linux__ */
default:
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Unsupported sta_set_frame(60G) with the current driver");
return 0;
}
}
int cmd_ap_send_frame(struct sigma_dut *dut, struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
/* const char *name = get_param(cmd, "NAME"); */
/* const char *ifname = get_param(cmd, "INTERFACE"); */
const char *val;
enum send_frame_type frame;
enum send_frame_protection protected;
char buf[100];
val = get_param(cmd, "Program");
if (val) {
if (strcasecmp(val, "HS2") == 0 ||
strcasecmp(val, "HS2-R2") == 0 ||
strcasecmp(val, "IOTLP") == 0)
return ap_send_frame_hs2(dut, conn, cmd);
if (strcasecmp(val, "VHT") == 0)
return ap_send_frame_vht(dut, conn, cmd);
if (strcasecmp(val, "LOC") == 0)
return ap_send_frame_loc(dut, conn, cmd);
if (strcasecmp(val, "MBO") == 0)
return ap_send_frame_mbo(dut, conn, cmd);
if (strcasecmp(val, "60GHz") == 0)
return ap_send_frame_60g(dut, conn, cmd);
}
val = get_param(cmd, "PMFFrameType");
if (val == NULL)
val = get_param(cmd, "FrameName");
if (val == NULL)
val = get_param(cmd, "Type");
if (val == NULL)
return -1;
if (strcasecmp(val, "disassoc") == 0)
frame = DISASSOC;
else if (strcasecmp(val, "deauth") == 0)
frame = DEAUTH;
else if (strcasecmp(val, "saquery") == 0)
frame = SAQUERY;
else {
send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
"PMFFrameType");
return 0;
}
val = get_param(cmd, "PMFProtected");
if (val == NULL)
val = get_param(cmd, "Protected");
if (val == NULL)
return -1;
if (strcasecmp(val, "Correct-key") == 0 ||
strcasecmp(val, "CorrectKey") == 0)
protected = CORRECT_KEY;
else if (strcasecmp(val, "IncorrectKey") == 0)
protected = INCORRECT_KEY;
else if (strcasecmp(val, "Unprotected") == 0)
protected = UNPROTECTED;
else {
send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
"PMFProtected");
return 0;
}
val = get_param(cmd, "stationID");
if (val == NULL)
return -1;
if (protected == INCORRECT_KEY ||
(protected == UNPROTECTED && frame == SAQUERY))
return ap_inject_frame(dut, conn, frame, protected, val);
switch (frame) {
case DISASSOC:
snprintf(buf, sizeof(buf), "disassoc %s test=%d",
val, protected == CORRECT_KEY);
break;
case DEAUTH:
snprintf(buf, sizeof(buf), "deauth %s test=%d",
val, protected == CORRECT_KEY);
break;
case SAQUERY:
snprintf(buf, sizeof(buf), "sa_query %s", val);
break;
}
if (run_hostapd_cli(dut, buf) != 0)
return -2;
return 1;
}
static int cmd_ap_get_mac_address(struct sigma_dut *dut,
struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
#if defined( __linux__)
/* const char *name = get_param(cmd, "NAME"); */
/* const char *ifname = get_param(cmd, "INTERFACE"); */
char resp[100];
unsigned char addr[6];
char ifname[50];
struct ifreq ifr;
int s, wlan_tag = 1;
const char *val;
val = get_param(cmd, "WLAN_TAG");
if (val) {
wlan_tag = atoi(val);
if (wlan_tag < 1 || wlan_tag > 3) {
/*
* The only valid WLAN Tags as of now as per the latest
* WFA scripts are 1, 2, and 3.
*/
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Unsupported WLAN_TAG");
return 0;
}
}
get_if_name(dut, ifname, sizeof(ifname), wlan_tag);
s = socket(AF_INET, SOCK_DGRAM, 0);
if (s < 0)
return -1;
memset(&ifr, 0, sizeof(ifr));
strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) {
perror("ioctl");
close(s);
snprintf(resp, sizeof(resp),
"errorCode,Could not find interface %s", ifname);
send_resp(dut, conn, SIGMA_ERROR, resp);
return 0;
}
close(s);
memcpy(addr, ifr.ifr_hwaddr.sa_data, 6);
snprintf(resp, sizeof(resp), "mac,%02x:%02x:%02x:%02x:%02x:%02x",
addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
send_resp(dut, conn, SIGMA_COMPLETE, resp);
return 0;
#elif defined( __QNXNTO__)
char resp[50];
unsigned char addr[6];
if (!sigma_main_ifname) {
send_resp(dut, conn, SIGMA_ERROR, "ifname is null");
return 0;
}
if (get_hwaddr(sigma_main_ifname, addr) != 0) {
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Failed to get address");
return 0;
}
snprintf(resp, sizeof(resp), "mac,%02x:%02x:%02x:%02x:%02x:%02x",
addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
send_resp(dut, conn, SIGMA_COMPLETE, resp);
return 0;
#else /* __linux__ */
send_resp(dut, conn, SIGMA_ERROR, "errorCode,ap_get_mac_address not "
"yet supported");
return 0;
#endif /* __linux__ */
}
int sta_cfon_get_mac_address(struct sigma_dut *dut, struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
return cmd_ap_get_mac_address(dut, conn, cmd);
}
static int cmd_ap_set_pmf(struct sigma_dut *dut, struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
/*
* Ignore the command since the parameters are already handled through
* ap_set_security.
*/
return 1;
}
static int cmd_ap_set_hs2(struct sigma_dut *dut, struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
/* const char *name = get_param(cmd, "NAME"); */
/* const char *ifname = get_param(cmd, "INTERFACE"); */
const char *val, *dest;
char *pos, buf[100];
int i, wlan_tag = 1;
sigma_dut_print(dut, DUT_MSG_INFO, "ap_set_hs2: Processing the "
"following parameters");
for (i = 0; i < cmd->count; i++) {
sigma_dut_print(dut, DUT_MSG_INFO, "%s %s", cmd->params[i],
(cmd->values[i] ? cmd->values[i] : "NULL"));
}
val = get_param(cmd, "ICMPv4_ECHO");
if (val && atoi(val)) {
snprintf(buf, sizeof(buf), "ebtables -F");
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Failed to set ebtables rules, RULE-12");
}
return 1;
}
val = get_param(cmd, "WLAN_TAG");
if (val) {
wlan_tag = atoi(val);
if (wlan_tag != 1 && wlan_tag != 2) {
send_resp(dut, conn, SIGMA_INVALID,
"errorCode,Invalid WLAN_TAG");
return 0;
}
}
if (wlan_tag == 2) {
val = get_param(cmd, "PROXY_ARP");
if (val)
dut->ap2_proxy_arp = atoi(val);
val = get_param(cmd, "OSU");
if (val)
dut->ap2_osu = atoi(val);
return 1;
}
dest = get_param(cmd, "STA_MAC");
if (dest) {
/* This is a special/ugly way of using this command.
* If "Dest" MAC is included, assume that this command
* is being issued after ap_config_commit for dynamically
* setting the QoS Map Set.
*/
val = get_param(cmd, "QoS_MAP_SET");
if (val) {
dut->ap_qos_map_set = atoi(val);
sigma_dut_print(dut, DUT_MSG_INFO, "ap_qos_map_set %d",
dut->ap_qos_map_set);
}
if (dut->ap_qos_map_set == 1)
run_hostapd_cli(dut, "set_qos_map_set " QOS_MAP_SET_1);
else if (dut->ap_qos_map_set == 2)
run_hostapd_cli(dut, "set_qos_map_set " QOS_MAP_SET_2);
snprintf(buf, sizeof(buf), "send_qos_map_conf %s", dest);
if (run_hostapd_cli(dut, buf) != 0)
return -1;
}
val = get_param(cmd, "DGAF_DISABLE");
if (val)
dut->ap_dgaf_disable = atoi(val);
dut->ap_interworking = 1;
val = get_param(cmd, "INTERWORKING");
if (val == NULL)
val = get_param(cmd, "INTERNETWORKING");
if (val != NULL && atoi(val) == 0) {
dut->ap_interworking = 0;
dut->ap_hs2 = 0;
return 1;
}
val = get_param(cmd, "ACCS_NET_TYPE");
if (val) {
if (strcasecmp(val, "Chargeable_Public_Network") == 0 ||
strcasecmp(val, "Chargable_Public_Network") == 0 ||
strcasecmp(val, "Chargable Public Network") == 0)
dut->ap_access_net_type = 2;
else
dut->ap_access_net_type = atoi(val);
}
val = get_param(cmd, "INTERNET");
if (val)
dut->ap_internet = atoi(val);
val = get_param(cmd, "VENUE_GRP");
if (val) {
if (strcasecmp(val, "Business") == 0)
dut->ap_venue_group = 2;
else
dut->ap_venue_group = atoi(val);
sigma_dut_print(dut, DUT_MSG_INFO, "ap_venue_name %d",
dut->ap_venue_name);
}
val = get_param(cmd, "VENUE_TYPE");
if (val) {
if (strcasecmp(val, "R&D") == 0)
dut->ap_venue_type = 8;
else
dut->ap_venue_type = atoi(val);
sigma_dut_print(dut, DUT_MSG_INFO, "ap_venue_type %d",
dut->ap_venue_type);
}
val = get_param(cmd, "HESSID");
if (val) {
if (strlen(val) >= sizeof(dut->ap_hessid)) {
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Invalid HESSID");
return 0;
}
snprintf(dut->ap_hessid, sizeof(dut->ap_hessid), "%s", val);
sigma_dut_print(dut, DUT_MSG_INFO, "ap_hessid %s",
dut->ap_hessid);
}
val = get_param(cmd, "ROAMING_CONS");
if (val) {
if (strlen(val) >= sizeof(dut->ap_roaming_cons)) {
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Invalid ROAMING_CONS");
return 0;
}
if (strcasecmp(val, "Disabled") == 0) {
dut->ap_roaming_cons[0] = '\0';
} else {
snprintf(dut->ap_roaming_cons,
sizeof(dut->ap_roaming_cons), "%s", val);
}
sigma_dut_print(dut, DUT_MSG_INFO, "ap_roaming_cons %s",
dut->ap_roaming_cons);
}
val = get_param(cmd, "ANQP");
if (val)
dut->ap_anqpserver_on = atoi(val);
val = get_param(cmd, "NAI_REALM_LIST");
if (val) {
dut->ap_nai_realm_list = atoi(val);
sigma_dut_print(dut, DUT_MSG_INFO, "ap_nai_realm_list %d",
dut->ap_nai_realm_list);
}
val = get_param(cmd, "3GPP_INFO");
if (val) {
/* What kind of encoding format is used?! */
send_resp(dut, conn, SIGMA_ERROR, "errorCode,3GPP_INFO "
"not yet supported (contents not fully defined)");
return 0;
}
val = get_param(cmd, "DOMAIN_LIST");
if (val) {
if (strlen(val) >= sizeof(dut->ap_domain_name_list)) {
send_resp(dut, conn, SIGMA_ERROR, "errorCode,Too long "
"DOMAIN_LIST");
return 0;
}
snprintf(dut->ap_domain_name_list,
sizeof(dut->ap_domain_name_list), "%s", val);
pos = dut->ap_domain_name_list;
while (*pos) {
if (*pos == ';')
*pos = ',';
pos++;
}
sigma_dut_print(dut, DUT_MSG_INFO, "ap_domain_name_list %s",
dut->ap_domain_name_list);
}
val = get_param(cmd, "OPER_NAME");
if (val) {
dut->ap_oper_name = atoi(val);
sigma_dut_print(dut, DUT_MSG_INFO, "ap_oper_name %d",
dut->ap_oper_name);
}
val = get_param(cmd, "VENUE_NAME");
if (val) {
dut->ap_venue_name = atoi(val);
sigma_dut_print(dut, DUT_MSG_INFO, "ap_venue_name %d",
dut->ap_venue_name);
}
val = get_param(cmd, "GAS_CB_DELAY");
if (val) {
dut->ap_gas_cb_delay = atoi(val);
sigma_dut_print(dut, DUT_MSG_INFO, "ap_gas_cb_delay %d",
dut->ap_gas_cb_delay);
}
val = get_param(cmd, "MIH");
if (val && atoi(val) > 0) {
send_resp(dut, conn, SIGMA_ERROR, "errorCode,MIH not "
"supported");
return 0;
}
val = get_param(cmd, "L2_TRAFFIC_INSPECT");
if (val) {
dut->ap_l2tif = atoi(val);
sigma_dut_print(dut, DUT_MSG_INFO, "ap_l2tif %d",
dut->ap_l2tif);
}
val = get_param(cmd, "BCST_UNCST");
if (val) {
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,BCST_UNCST not yet supported");
return 0;
}
val = get_param(cmd, "PLMN_MCC");
if (val) {
char mcc[100], *start, *end;
int i = 0;
if (strlen(val) >= sizeof(mcc)) {
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,PLMN_MCC too long");
return 0;
}
strlcpy(mcc, val, sizeof(mcc));
start = mcc;
while ((end = strchr(start, ';'))) {
/* process all except the last */
*end = '\0';
if (strlen(start) != 3) {
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Invalid PLMN_MCC");
return 0;
}
snprintf(dut->ap_plmn_mcc[i],
sizeof(dut->ap_plmn_mcc[i]), "%s", start);
sigma_dut_print(dut, DUT_MSG_INFO, "ap_plmn_mcc %s",
dut->ap_plmn_mcc[i]);
i++;
start = end + 1;
*end = ';';
}
if (strlen(start) != 3) {
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Invalid PLMN_MCC");
return 0;
}
/* process last or only one */
snprintf(dut->ap_plmn_mcc[i],
sizeof(dut->ap_plmn_mcc[i]), "%s", start);
sigma_dut_print(dut, DUT_MSG_INFO, "ap_plmn_mcc %s",
dut->ap_plmn_mcc[i]);
}
val = get_param(cmd, "PLMN_MNC");
if (val) {
char mnc[100], *start, *end;
int i = 0;
if (strlen(val) >= sizeof(mnc)) {
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,PLMN_MNC too long");
return 0;
}
strlcpy(mnc, val, sizeof(mnc));
start = mnc;
while ((end = strchr(start, ';'))) {
*end = '\0';
if (strlen(start) != 2 && strlen(start) != 3) {
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Invalid PLMN_MNC");
return 0;
}
snprintf(dut->ap_plmn_mnc[i],
sizeof(dut->ap_plmn_mnc[i]), "%s", start);
sigma_dut_print(dut, DUT_MSG_INFO, "ap_plmn_mnc %s",
dut->ap_plmn_mnc[i]);
i++;
start = end + 1;
*end = ';';
}
if (strlen(start) != 2 && strlen(start) != 3) {
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Invalid PLMN_MNC");
return 0;
}
snprintf(dut->ap_plmn_mnc[i],
sizeof(dut->ap_plmn_mnc[i]), "%s", start);
sigma_dut_print(dut, DUT_MSG_INFO, "ap_plmn_mnc %s",
dut->ap_plmn_mnc[i]);
}
val = get_param(cmd, "PROXY_ARP");
if (val) {
dut->ap_proxy_arp = atoi(val);
sigma_dut_print(dut, DUT_MSG_INFO, "ap_proxy_arp %d",
dut->ap_proxy_arp);
}
val = get_param(cmd, "WAN_METRICS");
if (val) {
dut->ap_wan_metrics = atoi(val);
sigma_dut_print(dut, DUT_MSG_INFO, "ap_wan_metrics %d",
dut->ap_wan_metrics);
}
val = get_param(cmd, "CONN_CAP");
if (val) {
dut->ap_conn_capab = atoi(val);
sigma_dut_print(dut, DUT_MSG_INFO, "ap_conn_capab %d",
dut->ap_conn_capab);
}
val = get_param(cmd, "IP_ADD_TYPE_AVAIL");
if (val) {
dut->ap_ip_addr_type_avail = atoi(val);
sigma_dut_print(dut, DUT_MSG_INFO, "ap_ip_addr_type_avail %d",
dut->ap_ip_addr_type_avail);
}
val = get_param(cmd, "NET_AUTH_TYPE");
if (val) {
dut->ap_net_auth_type = atoi(val);
sigma_dut_print(dut, DUT_MSG_INFO, "ap_net_auth_type %d",
dut->ap_net_auth_type);
}
val = get_param(cmd, "OP_CLASS");
if (val == NULL)
val = get_param(cmd, "OPER_CLASS");
if (val) {
dut->ap_oper_class = atoi(val);
sigma_dut_print(dut, DUT_MSG_INFO, "ap_oper_class %d",
dut->ap_oper_class);
}
val = get_param(cmd, "OSU_PROVIDER_LIST");
if (val) {
dut->ap_osu_provider_list = atoi(val);
sigma_dut_print(dut, DUT_MSG_INFO, "ap_osu_provider_list %d",
dut->ap_osu_provider_list);
}
val = get_param(cmd, "OSU_PROVIDER_NAI_LIST");
if (val) {
dut->ap_osu_provider_nai_list = atoi(val);
sigma_dut_print(dut, DUT_MSG_INFO,
"ap_osu_provider_nai_list %d",
dut->ap_osu_provider_nai_list);
}
val = get_param(cmd, "OSU_SERVER_URI");
if (val) {
i = 0;
do {
int len;
const char *uri = val;
val = strchr(val, ' ');
len = val ? (val++ - uri) : (int) strlen(uri);
if (len > 0 && len < 256) {
memcpy(dut->ap_osu_server_uri[i], uri, len);
dut->ap_osu_server_uri[i][len] = '\0';
sigma_dut_print(dut, DUT_MSG_INFO,
"ap_osu_server_uri[%d] %s", i,
dut->ap_osu_server_uri[i]);
}
} while (val && ++i < 10);
}
val = get_param(cmd, "OSU_METHOD");
if (val) {
i = 0;
do {
int len;
const char *method = val;
val = strchr(val, ' ');
len = val ? (val++ - method) : (int) strlen(method);
if (len > 0) {
if (strncasecmp(method, "SOAP", len) == 0)
dut->ap_osu_method[i] = 1;
else if (strncasecmp(method, "OMADM", len) == 0)
dut->ap_osu_method[i] = 0;
else
return -2;
}
} while (val && ++i < 10);
}
val = get_param(cmd, "OSU_SSID");
if (val) {
if (strlen(val) > 0 && strlen(val) <= 32) {
strlcpy(dut->ap_osu_ssid, val,
sizeof(dut->ap_osu_ssid));
sigma_dut_print(dut, DUT_MSG_INFO,
"ap_osu_ssid %s",
dut->ap_osu_ssid);
}
}
val = get_param(cmd, "OSU_ICON_TAG");
if (val)
dut->ap_osu_icon_tag = atoi(val);
val = get_param(cmd, "QoS_MAP_SET");
if (val) {
dut->ap_qos_map_set = atoi(val);
sigma_dut_print(dut, DUT_MSG_INFO, "ap_qos_map_set %d",
dut->ap_qos_map_set);
}
val = get_param(cmd, "BSS_LOAD");
if (val) {
dut->ap_bss_load = atoi(val);
sigma_dut_print(dut, DUT_MSG_INFO, "ap_bss_load %d",
dut->ap_bss_load);
}
val = get_param(cmd, "Venue_URL");
if (val)
dut->ap_venue_url = atoi(val);
val = get_param(cmd, "Advice_of_Charge");
if (val)
dut->ap_advice_of_charge = atoi(val);
val = get_param(cmd, "Operator_Icon_Metadata");
if (val)
dut->ap_oper_icon_metadata = atoi(val);
val = get_param(cmd, "TnC_File_Name");
if (val)
dut->ap_tnc_file_name = atoi(val);
val = get_param(cmd, "TnC_File_Time_Stamp");
if (val)
dut->ap_tnc_time_stamp = strtol(val, NULL, 10);
return 1;
}
void nfc_status(struct sigma_dut *dut, const char *state, const char *oper)
{
char buf[100];
if (!file_exists("nfc-status"))
return;
snprintf(buf, sizeof(buf), "./nfc-status %s %s", state, oper);
run_system(dut, buf);
}
static int run_nfc_command(struct sigma_dut *dut, const char *cmd,
const char *info)
{
int res;
printf("\n\n\n=====[ NFC operation ]=========================\n\n");
printf("%s\n\n", info);
nfc_status(dut, "START", info);
res = run_system(dut, cmd);
nfc_status(dut, res ? "FAIL" : "SUCCESS", info);
if (res) {
sigma_dut_print(dut, DUT_MSG_INFO, "Failed to run '%s': %d",
cmd, res);
return res;
}
return 0;
}
static int ap_nfc_write_config_token(struct sigma_dut *dut,
struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
int res;
char buf[300];
run_system(dut, "killall wps-ap-nfc.py");
unlink("nfc-success");
snprintf(buf, sizeof(buf),
"./wps-ap-nfc.py --no-wait %s%s --success nfc-success write-config",
dut->summary_log ? "--summary " : "",
dut->summary_log ? dut->summary_log : "");
res = run_nfc_command(dut, buf,
"Touch NFC Tag to write WPS configuration token");
if (res || !file_exists("nfc-success")) {
send_resp(dut, conn, SIGMA_ERROR,
"ErrorCode,Failed to write tag");
return 0;
}
return 1;
}
static int ap_nfc_wps_read_passwd(struct sigma_dut *dut,
struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
int res;
char buf[300];
run_system(dut, "killall wps-ap-nfc.py");
unlink("nfc-success");
snprintf(buf, sizeof(buf),
"./wps-ap-nfc.py -1 --no-wait %s%s --success nfc-success",
dut->summary_log ? "--summary " : "",
dut->summary_log ? dut->summary_log : "");
res = run_nfc_command(dut, buf, "Touch NFC Tag to read it");
if (res || !file_exists("nfc-success")) {
send_resp(dut, conn, SIGMA_ERROR,
"ErrorCode,Failed to read tag");
return 0;
}
return 1;
}
static int ap_nfc_write_password_token(struct sigma_dut *dut,
struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
int res;
char buf[300];
run_system(dut, "killall wps-ap-nfc.py");
unlink("nfc-success");
snprintf(buf, sizeof(buf),
"./wps-ap-nfc.py --no-wait %s%s --success nfc-success write-password",
dut->summary_log ? "--summary " : "",
dut->summary_log ? dut->summary_log : "");
res = run_nfc_command(dut, buf,
"Touch NFC Tag to write WPS password token");
if (res || !file_exists("nfc-success")) {
send_resp(dut, conn, SIGMA_ERROR,
"ErrorCode,Failed to write tag");
return 0;
}
if (run_hostapd_cli(dut, "wps_nfc_token enable") != 0) {
send_resp(dut, conn, SIGMA_ERROR,
"ErrorCode,Failed to enable NFC password token");
return 0;
}
return 1;
}
static int ap_nfc_wps_connection_handover(struct sigma_dut *dut,
struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
int res;
char buf[300];
run_system(dut, "killall wps-ap-nfc.py");
unlink("nfc-success");
snprintf(buf, sizeof(buf),
"./wps-ap-nfc.py -1 --no-wait %s%s --success nfc-success",
dut->summary_log ? "--summary " : "",
dut->summary_log ? dut->summary_log : "");
res = run_nfc_command(dut, buf,
"Touch NFC Device to respond to WPS connection handover");
if (res) {
send_resp(dut, conn, SIGMA_ERROR,
"ErrorCode,Failed to enable NFC for connection "
"handover");
return 0;
}
if (!file_exists("nfc-success")) {
send_resp(dut, conn, SIGMA_ERROR,
"ErrorCode,Failed to complete NFC connection handover");
return 0;
}
return 1;
}
static int cmd_ap_nfc_action(struct sigma_dut *dut, struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
/* const char *name = get_param(cmd, "Name"); */
/* const char *intf = get_param(cmd, "Interface"); */
const char *oper = get_param(cmd, "Operation");
if (oper == NULL)
return -1;
if (strcasecmp(oper, "WRITE_CONFIG") == 0)
return ap_nfc_write_config_token(dut, conn, cmd);
if (strcasecmp(oper, "WRITE_PASSWD") == 0)
return ap_nfc_write_password_token(dut, conn, cmd);
if (strcasecmp(oper, "WPS_READ_PASSWD") == 0)
return ap_nfc_wps_read_passwd(dut, conn, cmd);
if (strcasecmp(oper, "WPS_CONN_HNDOVR") == 0)
return ap_nfc_wps_connection_handover(dut, conn, cmd);
send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported operation");
return 0;
}
static int cmd_ap_wps_read_pin(struct sigma_dut *dut, struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
char *pin = "12345670"; /* TODO: use random PIN */
char resp[100];
snprintf(resp, sizeof(resp), "PIN,%s", pin);
send_resp(dut, conn, SIGMA_COMPLETE, resp);
return 0;
}
static int cmd_ap_wps_enter_pin(struct sigma_dut *dut, struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
const char *pin = get_param(cmd, "PIN");
char wps_pin[11];
if (!pin)
return -1;
sigma_dut_print(dut, DUT_MSG_DEBUG,
"Authorize a client to join with WPS PIN %s", pin);
strlcpy(wps_pin, pin, sizeof(wps_pin));
/* we need to tolerate extra '-' characters entered */
str_remove_chars(wps_pin, '-');
strlcpy(dut->wps_pin, wps_pin, sizeof(dut->wps_pin));
dut->wps_method = WFA_CS_WPS_PIN_KEYPAD;
return 1;
}
static int cmd_ap_wps_set_pbc(struct sigma_dut *dut, struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
sigma_dut_print(dut, DUT_MSG_DEBUG,
"Selecting the push button configuration method");
dut->wps_method = WFA_CS_WPS_PBC;
return 1;
}
int ap_wps_registration(struct sigma_dut *dut, struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
char buf[100], resp[256];
const char *intf = get_param(cmd, "interface");
const char *config_method = get_param(cmd, "WPSConfigMethod");
if (config_method && strcasecmp(config_method, "PBC") == 0)
dut->wps_method = WFA_CS_WPS_PBC;
if (!intf)
intf = get_main_ifname();
if (dut->wps_method == WFA_CS_WPS_NOT_READY) {
send_resp(dut, conn, SIGMA_ERROR,
"ErrorCode,WPS parameters not yet set");
return STATUS_SENT;
}
if (dut->wps_method == WFA_CS_WPS_PBC)
snprintf(buf, sizeof(buf), "WPS_PBC");
else /* WFA_CS_WPS_PIN_KEYPAD */
snprintf(buf, sizeof(buf), "WPS_PIN any %s", dut->wps_pin);
/* Run WPS command */
if (hapd_command(intf, buf) < 0) {
/* command fails immediately if overlapped session detected */
snprintf(resp, sizeof(resp), "WpsState,OverlapSession");
send_resp(dut, conn, SIGMA_COMPLETE, resp);
return STATUS_SENT;
}
/* In AP mode return immediately and do not wait for WPS registration */
return SUCCESS_SEND_STATUS;
}
static int cmd_ap_get_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
char value[256], resp[512];
const char *param = get_param(cmd, "parameter");
const char *ifname = get_param(cmd, "Interface");
if (!ifname)
ifname = get_main_ifname();
if (!param) {
send_resp(dut, conn, SIGMA_ERROR,
"ErrorCode,Parameter not specified");
return 0;
}
if (strcasecmp(param, "SSID") == 0) {
if (get_hapd_config(ifname, "ssid", value, sizeof(value))) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Failed to get SSID");
return -2;
}
snprintf(resp, sizeof(resp), "SSID,%s", value);
} else if (strcasecmp(param, "PSK") == 0) {
if (get_hapd_config(ifname, "passphrase", value,
sizeof(value))) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Failed to get PSK");
return -2;
}
snprintf(resp, sizeof(resp), "PSK,%s", value);
} else {
send_resp(dut, conn, SIGMA_ERROR,
"ErrorCode,Unsupported parameter");
return 0;
}
send_resp(dut, conn, SIGMA_COMPLETE, resp);
return 0;
}
static int ath_vht_op_mode_notif(struct sigma_dut *dut, const char *ifname,
const char *val)
{
char *token, *result;
int nss = 0, chwidth = 0;
char buf[100];
char *saveptr;
/*
* The following commands should be invoked to generate
* VHT op mode notification
*/
/* Extract the NSS info */
token = strdup(val);
if (!token)
return -1;
result = strtok_r(token, ";", &saveptr);
if (result) {
int count = atoi(result);
/* We do not support NSS > 3 */
if (count < 0 || count > 3) {
free(token);
return -1;
}
/* Convert nss to chainmask */
while (count--)
nss = (nss << 1) | 1;
snprintf(buf, sizeof(buf), "iwpriv %s rxchainmask %d",
ifname, nss);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"iwpriv wifi1 rxchainmask failed!");
}
}
/* Extract the Channel width info */
result = strtok_r(NULL, ";", &saveptr);
if (result) {
switch (atoi(result)) {
case 20:
chwidth = 0;
break;
case 40:
chwidth = 1;
break;
case 80:
chwidth = 2;
break;
case 160:
chwidth = 3;
break;
default:
chwidth = 2;
break;
}
snprintf(buf, sizeof(buf), "iwpriv %s chwidth %d",
ifname, chwidth);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"iwpriv chwidth failed!");
}
}
/* Send the opmode notification */
snprintf(buf, sizeof(buf), "iwpriv %s opmode_notify 1", ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"iwpriv opmode_notify failed!");
}
free(token);
return 0;
}
static int ath_vht_nss_mcs(struct sigma_dut *dut, const char *ifname,
const char *val)
{
/* String (nss_operating_mode; mcs_operating_mode) */
int nss, mcs;
char *token, *result;
char buf[100];
char *saveptr;
token = strdup(val);
if (!token)
return -1;
result = strtok_r(token, ";", &saveptr);
if (!result) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"VHT NSS not specified");
goto end;
}
if (strcasecmp(result, "def") != 0) {
nss = atoi(result);
if (nss == 4)
ath_disable_txbf(dut, ifname);
snprintf(buf, sizeof(buf), "iwpriv %s nss %d", ifname, nss);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"iwpriv nss failed");
}
} else {
if (dut->device_type == AP_testbed && dut->ap_sgi80 == 1) {
snprintf(buf, sizeof(buf), "iwpriv %s nss 1", ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"iwpriv nss failed");
}
}
}
result = strtok_r(NULL, ";", &saveptr);
if (!result) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"VHT MCS not specified");
goto end;
}
if (strcasecmp(result, "def") == 0) {
if (dut->device_type == AP_testbed && dut->ap_sgi80 == 1) {
snprintf(buf, sizeof(buf), "iwpriv %s vhtmcs 7",
ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"iwpriv vhtmcs failed");
}
} else {
snprintf(buf, sizeof(buf),
"iwpriv %s set11NRates 0", ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"iwpriv set11NRates failed");
}
}
} else {
mcs = atoi(result);
snprintf(buf, sizeof(buf), "iwpriv %s vhtmcs %d", ifname, mcs);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"iwpriv vhtmcs failed");
}
}
end:
free(token);
return 0;
}
static int ath_vht_chnum_band(struct sigma_dut *dut, const char *ifname,
const char *val)
{
char *token, *result;
int channel = 36;
int chwidth = 80;
char buf[100];
char *saveptr;
/* Extract the channel info */
token = strdup(val);
if (!token)
return -1;
result = strtok_r(token, ";", &saveptr);
if (result)
channel = atoi(result);
/* Extract the channel width info */
result = strtok_r(NULL, ";", &saveptr);
if (result)
chwidth = atoi(result);
/* Issue the channel switch command */
snprintf(buf, sizeof(buf), "iwpriv %s doth_ch_chwidth %d 10 %d",
ifname, channel, chwidth);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"iwpriv doth_ch_chwidth failed!");
}
free(token);
return 0;
}
static int ath_ndpa_stainfo_mac(struct sigma_dut *dut, const char *ifname,
const char *val)
{
char buf[80];
unsigned char mac_addr[6];
if (parse_mac_address(dut, val, mac_addr) < 0)
return -1;
snprintf(buf, sizeof(buf),
"wifitool %s beeliner_fw_test 92 0x%02x%02x%02x%02x",
ifname, mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3]);
run_system(dut, buf);
snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 93 0x%02x%02x",
ifname, mac_addr[4], mac_addr[5]);
run_system(dut, buf);
snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 94 1", ifname);
run_system(dut, buf);
return 0;
}
void novap_reset(struct sigma_dut *dut, const char *ifname)
{
char buf[60];
snprintf(buf, sizeof(buf), "iwpriv %s novap_reset 1", ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"disabling novap reset failed");
}
}
struct mbo_pref_ap * mbo_find_nebor_ap_entry(struct sigma_dut *dut,
const uint8_t *mac_addr)
{
int i;
for (i = 0; i < dut->mbo_pref_ap_cnt; i++) {
if (memcmp(mac_addr, dut->mbo_pref_aps[i].mac_addr,
ETH_ALEN) == 0)
return &dut->mbo_pref_aps[i];
}
return NULL;
}
static void mbo_add_nebor_entry(struct sigma_dut *dut, const uint8_t *mac_addr,
int ap_ne_class, int ap_ne_op_ch,
int ap_ne_pref)
{
struct mbo_pref_ap *entry;
uint8_t self_mac[ETH_ALEN];
char ifname[50];
get_if_name(dut, ifname, sizeof(ifname), 1);
get_hwaddr(ifname, self_mac);
if (memcmp(mac_addr, self_mac, ETH_ALEN) == 0)
entry = &dut->mbo_self_ap_tuple;
else
entry = mbo_find_nebor_ap_entry(dut, mac_addr);
if (!entry) {
if (dut->mbo_pref_ap_cnt >= MBO_MAX_PREF_BSSIDS) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Nebor AP List is full. Not adding");
return;
}
entry = &dut->mbo_pref_aps[dut->mbo_pref_ap_cnt];
dut->mbo_pref_ap_cnt++;
memcpy(entry->mac_addr, mac_addr, ETH_ALEN);
entry->ap_ne_class = -1;
entry->ap_ne_op_ch = -1;
entry->ap_ne_pref = -1;
}
if (ap_ne_class != -1)
entry->ap_ne_class = ap_ne_class;
if (ap_ne_op_ch != -1)
entry->ap_ne_op_ch = ap_ne_op_ch;
if (ap_ne_pref != -1)
entry->ap_ne_pref = ap_ne_pref;
}
static int ath_set_nebor_bssid(struct sigma_dut *dut, const char *ifname,
struct sigma_cmd *cmd)
{
unsigned char mac_addr[ETH_ALEN];
const char *val;
/*
* -1 is invalid value for the following
* to differentiate between unset and set values
* -1 => implies not set by CAPI
*/
int ap_ne_class = -1, ap_ne_op_ch = -1, ap_ne_pref = -1;
int list_offset = dut->mbo_pref_ap_cnt;
if (list_offset >= MBO_MAX_PREF_BSSIDS) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"AP Pref Entry list is full");
return -1;
}
val = get_param(cmd, "Nebor_Op_Class");
if (val)
ap_ne_class = atoi(val);
val = get_param(cmd, "Nebor_Op_Ch");
if (val)
ap_ne_op_ch = atoi(val);
val = get_param(cmd, "Nebor_Pref");
if (val)
ap_ne_pref = atoi(val);
val = get_param(cmd, "Nebor_BSSID");
if (!val || parse_mac_address(dut, val, mac_addr) < 0)
return -1;
mbo_add_nebor_entry(dut, mac_addr, ap_ne_class, ap_ne_op_ch,
ap_ne_pref);
apply_mbo_pref_ap_list(dut);
return 0;
}
static int ath_ap_set_rfeature(struct sigma_dut *dut, struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
const char *val;
char *ifname;
ifname = get_main_ifname();
/* Disable vap reset between the commands */
novap_reset(dut, ifname);
val = get_param(cmd, "Opt_md_notif_ie");
if (val && ath_vht_op_mode_notif(dut, ifname, val) < 0)
return -1;
/* TODO: Optional arguments */
val = get_param(cmd, "nss_mcs_opt");
if (val && ath_vht_nss_mcs(dut, ifname, val) < 0)
return -1;
val = get_param(cmd, "chnum_band");
if (val && ath_vht_chnum_band(dut, ifname, val) < 0)
return -1;
val = get_param(cmd, "RTS_FORCE");
if (val)
ath_config_rts_force(dut, ifname, val);
val = get_param(cmd, "DYN_BW_SGNL");
if (val)
ath_config_dyn_bw_sig(dut, ifname, val);
val = get_param(cmd, "CTS_WIDTH");
if (val)
ath_set_cts_width(dut, ifname, val);
val = get_param(cmd, "Ndpa_stainfo_mac");
if (val && ath_ndpa_stainfo_mac(dut, ifname, val) < 0)
return -1;
val = get_param(cmd, "txBandwidth");
if (val && ath_set_width(dut, conn, ifname, val) < 0)
return -1;
val = get_param(cmd, "Assoc_Disallow");
if (val)
ath_set_assoc_disallow(dut, ifname, val);
ath_set_nebor_bssid(dut, ifname, cmd);
val = get_param(cmd, "BTMReq_DisAssoc_Imnt");
if (val) {
dut->ap_btmreq_disassoc_imnt = atoi(val);
dut->ap_disassoc_timer = 1000;
}
val = get_param(cmd, "BTMReq_Term_Bit");
if (val)
dut->ap_btmreq_term_bit = atoi(val);
val = get_param(cmd, "Assoc_Delay");
if (val) {
dut->ap_assoc_delay = 1;
run_system_wrapper(dut, "iwpriv %s mbo_asoc_ret %s",
ifname, val);
}
val = get_param(cmd, "Disassoc_Timer");
if (val)
dut->ap_disassoc_timer = atoi(val);
val = get_param(cmd, "BSS_Term_Duration");
if (val)
dut->ap_btmreq_bss_term_dur = atoi(val);
val = get_param(cmd, "BSS_Term_TSF");
if (val)
dut->ap_btmreq_bss_term_tsf = atoi(val);
val = get_param(cmd, "TxPower");
if (val)
ath_set_txpower(dut, ifname, val);
val = get_param(cmd, "DownlinkAvailCap");
if (val)
dut->ap_dl_availcap = atoi(val);
val = get_param(cmd, "UplinkAvailCap");
if (val) {
dut->ap_ul_availcap = atoi(val);
run_system_wrapper(dut, "iwpriv %s oce_wan_mtr %d %d", ifname,
dut->ap_dl_availcap, dut->ap_ul_availcap);
}
val = get_param(cmd, "RSSIthreshold");
if (val) {
int rssithreshold;
run_system_wrapper(dut, "iwpriv %s oce_asoc_rej 1", ifname);
rssithreshold = atoi(val);
run_system_wrapper(dut, "iwpriv %s oce_asoc_rssi %d", ifname,
rssithreshold);
}
val = get_param(cmd, "RetryDelay");
if (val) {
int retrydelay;
run_system_wrapper(dut, "iwpriv %s oce_asoc_rej 1", ifname);
retrydelay = atoi(val);
run_system_wrapper(dut, "iwpriv %s oce_asoc_dly %d", ifname,
retrydelay);
}
return 1;
}
static int wcn_vht_chnum_band(struct sigma_dut *dut, const char *ifname,
const char *val)
{
char *token, *result;
int channel = 36;
char buf[100];
char *saveptr;
/* Extract the channel info */
token = strdup(val);
if (!token)
return -1;
result = strtok_r(token, ";", &saveptr);
if (result)
channel = atoi(result);
/* Issue the channel switch command */
snprintf(buf, sizeof(buf), "iwpriv %s setChanChange %d",
ifname, channel);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"iwpriv setChanChange failed!");
}
free(token);
return 0;
}
static int wcn_ap_set_rfeature(struct sigma_dut *dut, struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
const char *val;
char *ifname;
ifname = get_main_ifname();
val = get_param(cmd, "chnum_band");
if (val && wcn_vht_chnum_band(dut, ifname, val) < 0)
return -1;
return 1;
}
static int mac80211_vht_chnum_band(struct sigma_dut *dut, const char *ifname,
const char *val)
{
char *token, *result;
int channel = 36, chwidth = 80, center_freq_idx, center_freq,
channel_freq;
char buf[100];
char *saveptr;
/* Extract the channel info */
token = strdup(val);
if (!token)
return -1;
result = strtok_r(token, ";", &saveptr);
if (result)
channel = atoi(result);
/* Extract the channel width info */
result = strtok_r(NULL, ";", &saveptr);
if (result)
chwidth = atoi(result);
center_freq_idx = get_oper_centr_freq_seq_idx(chwidth, channel);
if (center_freq_idx < 0) {
free(token);
return -1;
}
center_freq = get_5g_channel_freq(center_freq_idx);
channel_freq = get_5g_channel_freq(channel);
/* Issue the channel switch command */
snprintf(buf, sizeof(buf),
" -i %s chan_switch 10 %d sec_channel_offset=1 center_freq1=%d bandwidth=%d blocktx vht",
ifname, channel_freq, center_freq, chwidth);
if (run_hostapd_cli(dut,buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"hostapd_cli chan_switch failed");
}
free(token);
return 0;
}
static int mac80211_ap_set_rfeature(struct sigma_dut *dut,
struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
const char *val;
char *ifname;
ifname = get_main_ifname();
val = get_param(cmd, "chnum_band");
if (val && mac80211_vht_chnum_band(dut, ifname, val) < 0)
return -1;
return 1;
}
#ifdef __linux__
static int wil6210_ap_set_rfeature(struct sigma_dut *dut,
struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
const char *val;
val = get_param(cmd, "ExtSchIE");
if (val && !strcasecmp(val, "Enable")) {
struct sigma_ese_alloc allocs[MAX_ESE_ALLOCS];
int count = MAX_ESE_ALLOCS;
if (sta_extract_60g_ese(dut, cmd, allocs, &count))
return -1;
if (wil6210_set_ese(dut, count, allocs))
return -1;
return 1;
}
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Invalid ap_set_rfeature(60G)");
return 0;
}
#endif /* __linux__ */
static int cmd_ap_set_rfeature(struct sigma_dut *dut, struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
/* const char *name = get_param(cmd, "NAME"); */
/* const char *type = get_param(cmd, "Type"); */
switch (get_driver_type()) {
case DRIVER_ATHEROS:
return ath_ap_set_rfeature(dut, conn, cmd);
case DRIVER_OPENWRT:
switch (get_openwrt_driver_type()) {
case OPENWRT_DRIVER_ATHEROS:
return ath_ap_set_rfeature(dut, conn, cmd);
default:
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Unsupported ap_set_rfeature with the current openwrt driver");
return 0;
}
case DRIVER_LINUX_WCN:
case DRIVER_WCN:
return wcn_ap_set_rfeature(dut, conn, cmd);
case DRIVER_MAC80211:
return mac80211_ap_set_rfeature(dut, conn, cmd);
#ifdef __linux__
case DRIVER_WIL6210:
return wil6210_ap_set_rfeature(dut, conn, cmd);
#endif /* __linux__ */
default:
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Unsupported ap_set_rfeature with the current driver");
return 0;
}
}
static int cmd_accesspoint(struct sigma_dut *dut, struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
/* const char *name = get_param(cmd, "NAME"); */
return 1;
}
static int cmd_ap_preset_testparameters(struct sigma_dut *dut,
struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
const char *val;
val = get_param(cmd, "Oper_Chn");
if (val) {
dut->ap_oper_chn = 1;
dut->ap_channel = atoi(val);
}
return 1;
}
void ap_register_cmds(void)
{
sigma_dut_reg_cmd("ap_ca_version", NULL, cmd_ap_ca_version);
sigma_dut_reg_cmd("ap_set_wireless", NULL, cmd_ap_set_wireless);
sigma_dut_reg_cmd("ap_send_addba_req", NULL, cmd_ap_send_addba_req);
sigma_dut_reg_cmd("ap_set_11n_wireless", NULL, cmd_ap_set_wireless);
sigma_dut_reg_cmd("ap_set_11n", NULL, cmd_ap_set_wireless);
sigma_dut_reg_cmd("ap_set_11d", NULL, cmd_ap_set_wireless);
sigma_dut_reg_cmd("ap_set_11h", NULL, cmd_ap_set_wireless);
sigma_dut_reg_cmd("ap_set_security", NULL, cmd_ap_set_security);
sigma_dut_reg_cmd("ap_set_apqos", NULL, cmd_ap_set_apqos);
sigma_dut_reg_cmd("ap_set_staqos", NULL, cmd_ap_set_staqos);
sigma_dut_reg_cmd("ap_set_radius", NULL, cmd_ap_set_radius);
sigma_dut_reg_cmd("ap_reboot", NULL, cmd_ap_reboot);
sigma_dut_reg_cmd("ap_config_commit", NULL, cmd_ap_config_commit);
sigma_dut_reg_cmd("ap_reset_default", NULL, cmd_ap_reset_default);
sigma_dut_reg_cmd("ap_get_info", NULL, cmd_ap_get_info);
sigma_dut_reg_cmd("ap_deauth_sta", NULL, cmd_ap_deauth_sta);
sigma_dut_reg_cmd("ap_send_frame", NULL, cmd_ap_send_frame);
sigma_dut_reg_cmd("ap_get_mac_address", NULL, cmd_ap_get_mac_address);
sigma_dut_reg_cmd("ap_set_pmf", NULL, cmd_ap_set_pmf);
sigma_dut_reg_cmd("ap_set_hs2", NULL, cmd_ap_set_hs2);
sigma_dut_reg_cmd("ap_set_rfeature", NULL, cmd_ap_set_rfeature);
sigma_dut_reg_cmd("ap_nfc_action", NULL, cmd_ap_nfc_action);
sigma_dut_reg_cmd("ap_wps_read_pin", NULL, cmd_ap_wps_read_pin);
sigma_dut_reg_cmd("ap_wps_enter_pin", NULL, cmd_ap_wps_enter_pin);
sigma_dut_reg_cmd("ap_wps_set_pbc", NULL, cmd_ap_wps_set_pbc);
sigma_dut_reg_cmd("ap_get_parameter", NULL, cmd_ap_get_parameter);
sigma_dut_reg_cmd("AccessPoint", NULL, cmd_accesspoint);
sigma_dut_reg_cmd("ap_preset_testparameters", NULL,
cmd_ap_preset_testparameters);
}