M7350/wlan/utils/sigma-dut/ap.c

6966 lines
181 KiB
C
Raw Normal View History

2024-09-09 08:57:42 +00:00
/*
* Sigma Control API DUT (station/AP)
* Copyright (c) 2010-2011, Atheros Communications, Inc.
* Copyright (c) 2011-2015, Qualcomm Atheros, Inc.
* 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 <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_helpers.h"
#ifdef ANDROID
#include <hardware_legacy/wifi.h>
#include <private/android_filesystem_config.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)
/* 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"
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 cmd_ap_config_commit(struct sigma_dut *dut, struct sigma_conn *conn,
struct sigma_cmd *cmd);
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 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 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));
strncpy(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 = AP_DYN_BW_SGNL_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 = AP_DYN_BW_SGNL_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 = 1;
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 = 2;
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 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
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();
if (file_exists("hostapd_cli"))
bin = "./hostapd_cli";
else
bin = "hostapd_cli";
if (drv == DRIVER_OPENWRT && sigma_hapd_ctrl == NULL) {
sigma_hapd_ctrl = "/var/run/hostapd-wifi0";
if (sigma_radio_ifname[0] &&
strcmp(sigma_radio_ifname[0], "wifi1") == 0)
sigma_hapd_ctrl = "/var/run/hostapd-wifi1";
else if (sigma_radio_ifname[0] &&
strcmp(sigma_radio_ifname[0], "wifi2") == 0)
sigma_hapd_ctrl = "/var/run/hostapd-wifi2";
}
if (sigma_hapd_ctrl)
snprintf(command, sizeof(command), "%s -p %s %s",
bin, sigma_hapd_ctrl, buf);
else
snprintf(command, sizeof(command), "%s %s", bin, buf);
return run_system(dut, command);
}
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();
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, "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) {
snprintf(dut->ap_ssid,
sizeof(dut->ap_ssid), "%s", val);
} else if (wlan_tag == 2) {
snprintf(dut->ap2_ssid,
sizeof(dut->ap2_ssid), "%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_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;
}
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);
}
/* TODO: WMMPS */
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) {
if (strcasecmp(val, "on") == 0) {
enum driver_type drv = get_driver_type();
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 (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 = 1;
else if (strcasecmp(val, "Disable") == 0)
dut->ap_addba_reject = 2;
}
val = get_param(cmd, "AMPDU");
if (val) {
if (strcasecmp(val, "Enable") == 0)
dut->ap_ampdu = 1;
else if (strcasecmp(val, "Disable") == 0)
dut->ap_ampdu = 2;
}
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 = 1;
else if (strcasecmp(val, "Disable") == 0)
dut->ap_amsdu = 2;
}
val = get_param(cmd, "NoAck");
if (val) {
if (strcasecmp(val, "on") == 0)
dut->ap_noack = AP_NOACK_ENABLED;
else if (strcasecmp(val, "off") == 0)
dut->ap_noack = AP_NOACK_DISABLED;
}
/* TODO: GREENFIELD */
/* TODO: OFFSET */
/* TODO: MCS_32 */
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, "nss_mcs_cap");
if (val) {
int nss, mcs;
char token[20];
char *result = NULL;
char *saveptr;
if (strlen(val) >= sizeof(token))
return -1;
strcpy(token, val);
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, "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;
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 = 1;
else if (strcasecmp(val, "disable") == 0)
dut->ap_ldpc = 2;
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 = 1;
} else if (strcasecmp(val, "disable") == 0) {
dut->ap_sig_rts = 2;
} 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)
dut->ap_mu_txBF = strcasecmp(val, "enable") == 0;
/* 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);
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 };
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 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"); */
switch (get_driver_type()) {
case DRIVER_ATHEROS:
return ath_ap_send_addba_req(dut, conn, cmd);
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;
}
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;
val = get_param(cmd, "WLAN_TAG");
if (val)
wlan_tag = atoi(val);
if (wlan_tag == 2) {
val = get_param(cmd, "KEYMGNT");
if (val) {
if (strcasecmp(val, "NONE") == 0)
dut->ap2_key_mgmt = AP2_OPEN;
else if (strcasecmp(val, "OSEN") == 0)
dut->ap2_key_mgmt = AP2_OSEN;
else {
send_resp(dut, conn, SIGMA_INVALID,
"errorCode,Unsupported KEYMGNT");
return 0;
}
return 1;
}
}
val = get_param(cmd, "KEYMGNT");
if (val) {
if (strcasecmp(val, "WPA2-PSK") == 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, "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, "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, "ENCRYPT");
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 {
send_resp(dut, conn, SIGMA_INVALID,
"errorCode,Unsupported ENCRYPT");
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) {
if (strlen(val) > sizeof(dut->ap_passphrase) - 1)
return -1;
snprintf(dut->ap_passphrase, sizeof(dut->ap_passphrase),
"%s", val);
}
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;
}
}
if (dut->ap_key_mgmt == AP_OPEN) {
dut->ap_hs2 = 0;
dut->ap_pmf = AP_PMF_DISABLED;
}
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 PMF");
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;
}
}
return 1;
}
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[256];
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 3
static void owrt_ap_config_radio(struct sigma_dut *dut)
{
int radio_id[MAX_RADIO] = { 0, 1 };
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_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);
}
if (dut->ap_countrycode[0]) {
/* Country Code */
snprintf(buf, sizeof(buf), "%s", dut->ap_countrycode);
owrt_ap_set_radio(dut, radio_id[0], "country", buf);
}
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'");
}
}
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_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";
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 Blue Test Only'");
owrt_ap_set_list_vap(dut, vap_id, "osu_service_desc",
"'eng:Free service for test purpose'");
hs20_icon_filename = "icon_blue_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_blue_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_blue_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_blue_zxx.png:/etc/ath/%s'",
hs20_icon_filename);
osu_icon = "icon_blue_zxx.png";
break;
case 5:
case 105:
owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name",
"'eng:SP Blue 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_blue_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_blue_zxx.png:/etc/ath/%s'",
hs20_icon_filename);
osu_icon = "icon_blue_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 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);
owrt_ap_set_list_vap(dut, vap_id, "osu_icon",
"'icon_orange_eng.png'");
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 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 (strcmp(dut->ap2_ssid, dut->ap_osu_ssid) != 0 &&
strcmp(dut->ap2_ssid, 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 owrt_ap_config_vap(struct sigma_dut *dut)
{
char buf[256], *temp;
int vap_id = 0, vap_count, i;
for (vap_count = 0; vap_count < OPENWRT_MAX_NUM_RADIOS; vap_count++) {
snprintf(buf, sizeof(buf), "%s%d", "wifi", 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;
if (strlen(dut->ap2_ssid)) {
owrt_ap_add_vap(dut, vap_count + 1, "device", buf);
/* SSID */
snprintf(buf, sizeof(buf), "\"%s\"", dut->ap2_ssid);
owrt_ap_set_vap(dut, vap_count + 1, "ssid", buf);
if (dut->ap2_key_mgmt == AP2_OSEN) {
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);
}
}
/* 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");
}
break;
case AP_WPA2_PSK:
case AP_WPA2_PSK_MIXED:
case AP_WPA_PSK:
if (dut->ap_key_mgmt == AP_WPA2_PSK) {
snprintf(buf, sizeof(buf), "psk2");
} else if (dut->ap_key_mgmt == AP_WPA2_PSK_MIXED) {
snprintf(buf, sizeof(buf), "psk-mixed");
} else {
snprintf(buf, sizeof(buf), "psk");
}
if (dut->ap_cipher == AP_CCMP_TKIP) {
strncat(buf, "+ccmp+tkip",
sizeof(buf) - sizeof("+ccmp+tkip"));
} else if (dut->ap_cipher == AP_TKIP) {
strncat(buf, "+tkip",
sizeof(buf) - sizeof("+tkip"));
} else {
strncat(buf, "+ccmp",
sizeof(buf) - sizeof("+ccmp"));
}
owrt_ap_set_vap(dut, vap_count, "encryption", buf);
snprintf(buf, sizeof(buf), "\"%s\"",
dut->ap_passphrase);
owrt_ap_set_vap(dut, vap_count, "key", 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) {
strncat(buf, "+ccmp+tkip", sizeof(buf));
} else if (dut->ap_cipher == AP_TKIP) {
strncat(buf, "+tkip", sizeof(buf));
} else {
strncat(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;
}
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);
/* 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 0;
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_vap(dut, vap_id, "network_auth_type",
"'00https://tandc-server.wi-fi.org'");
} else if (dut->ap_net_auth_type == 2) {
owrt_ap_set_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);
return 1;
}
static int owrt_ap_post_config_commit(struct sigma_dut *dut,
struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
if (dut->ap_key_mgmt != AP_OPEN) {
/* 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)
{
/* 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);
owrt_ap_config_vap(dut);
run_system(dut, "uci commit");
/* Start AP */
run_system(dut, "wifi up");
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;
if (dir == NULL)
return -1;
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);
if (is_proc_instance_one)
break;
}
}
closedir(dir);
return 0;
#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;
kill_process(dut, "(netd)", 1, SIGKILL);
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 */
wifi_unload_driver();
wifi_load_driver();
#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_EAP:
case AP_WPA2_EAP_MIXED:
case AP_WPA_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_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;
default:
break;
}
if (strlen(dut->ap_osu_ssid)) {
if (strcmp(dut->ap2_ssid, dut->ap_osu_ssid) &&
strcmp(dut->ap2_ssid, 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);
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);
}
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->ap2_key_mgmt == 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)
return 0;
len = strlen(dnbuf);
dn_len_max = 50 + len*2;
anqp_dn = malloc(dn_len_max);
if (anqp_dn == NULL) {
free(dnbuf);
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);
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 == 1)
run_system(dut, "cfg -a LDPC=1");
else if (dut->ap_ldpc == 2)
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_ap_set_params(struct sigma_dut *dut)
{
const char *basedev = "wifi1";
const char *ifname = dut->ap_is_dual ? "ath1" : "ath0";
int i;
char buf[100];
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 == 1) {
snprintf(buf, sizeof(buf), "iwpriv %s ldpc 1", ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"iwpriv ldpc 1 failed");
}
} else if (dut->ap_ldpc == 2) {
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 == 1) {
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 == 2) {
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 == AP_NOACK_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 == AP_NOACK_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 == 1) {
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 == 2) {
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 == 1) {
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 == 2) {
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 && dut->ap_ampdu == 2 && dut->ap_amsdu == 1) {
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;
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 == AP_DYN_BW_SGNL_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 == AP_DYN_BW_SGNL_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 == 1) {
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 == 2) {
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");
}
}
}
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:
if (dut->ap_key_mgmt == AP_WPA2_PSK)
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");
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;
}
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:
if (dut->ap_key_mgmt == AP_WPA2_PSK)
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");
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;
}
/* 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->ap2_ssid)) {
snprintf(buf, sizeof(buf),
"cfg -a AP_SSID_2=%s", dut->ap2_ssid);
run_system(dut, buf);
if (dut->ap2_key_mgmt == 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 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 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;
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 || drv == DRIVER_LINUX_WCN) ?
"wlan0" : "ath0";
if (drv == DRIVER_QNXNTO && 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) {
if (sigma_main_ifname)
ifname = sigma_main_ifname;
else
ifname = "wlan0";
} else if (drv == DRIVER_MAC80211 || drv == DRIVER_LINUX_WCN) {
if (if_nametoindex("wlan1") > 0)
ifname = "wlan1";
else
ifname = "wlan0";
} else {
ifname = get_main_ifname();
}
fprintf(f, "hw_mode=a\n");
break;
default:
fclose(f);
return -1;
}
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)) {
fprintf(f, "ieee80211n=1\n");
fprintf(f, "ht_capab=");
if (dut->ap_mode == AP_11ng && dut->ap_chwidth == AP_40) {
if (dut->ap_channel >= 1 && dut->ap_channel <= 7)
fprintf(f, "[HT40+]");
else if (dut->ap_channel >= 8 && dut->ap_channel <= 11)
fprintf(f, "[HT40-]");
}
/* 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_ap_chwidth == AP_40))) {
if (is_ht40plus_chan(dut->ap_channel))
fprintf(f, "[HT40+]");
else if (is_ht40minus_chan(dut->ap_channel))
fprintf(f, "[HT40-]");
}
if (dut->ap_tx_stbc)
fprintf(f, "[TX-STBC]");
fprintf(f, "\n");
}
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);
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:
if (dut->ap_key_mgmt == AP_WPA2_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");
fprintf(f, "wpa_key_mgmt=WPA-PSK\n");
switch (dut->ap_pmf) {
case AP_PMF_DISABLED:
fprintf(f, "wpa_key_mgmt=WPA-PSK%s\n",
dut->ap_add_sha256 ? " WPA-PSK-SHA256" : "");
break;
case AP_PMF_OPTIONAL:
fprintf(f, "wpa_key_mgmt=WPA-PSK%s\n",
dut->ap_add_sha256 ? " WPA-PSK-SHA256" : "");
break;
case AP_PMF_REQUIRED:
fprintf(f, "wpa_key_mgmt=WPA-PSK-SHA256\n");
break;
}
if (dut->ap_cipher == AP_CCMP_TKIP)
fprintf(f, "wpa_pairwise=CCMP TKIP\n");
else if (dut->ap_cipher == AP_TKIP)
fprintf(f, "wpa_pairwise=TKIP\n");
else
fprintf(f, "wpa_pairwise=CCMP\n");
fprintf(f, "wpa_passphrase=%s\n", dut->ap_passphrase);
break;
case AP_WPA2_EAP:
case AP_WPA2_EAP_MIXED:
case AP_WPA_EAP:
fprintf(f, "ieee8021x=1\n");
if (dut->ap_key_mgmt == AP_WPA2_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\n",
dut->ap_add_sha256 ? " WPA-EAP-SHA256" : "");
break;
case AP_PMF_REQUIRED:
fprintf(f, "wpa_key_mgmt=WPA-EAP-SHA256\n");
break;
}
if (dut->ap_cipher == AP_CCMP_TKIP)
fprintf(f, "wpa_pairwise=CCMP TKIP\n");
else if (dut->ap_cipher == AP_TKIP)
fprintf(f, "wpa_pairwise=TKIP\n");
else
fprintf(f, "wpa_pairwise=CCMP\n");
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;
}
switch (dut->ap_pmf) {
case AP_PMF_DISABLED:
break;
case AP_PMF_OPTIONAL:
fprintf(f, "ieee80211w=1\n");
break;
case AP_PMF_REQUIRED:
fprintf(f, "ieee80211w=2\n");
break;
}
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) {
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_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->ap2_ssid)) {
unsigned char bssid[6];
char ifname2[50];
if (get_hwaddr(ifname, bssid))
return -2;
bssid[0] |= 0x02;
snprintf(ifname2, sizeof(ifname2), "%s_1", ifname);
fprintf(f, "bss=%s_1\n", ifname2);
fprintf(f, "ssid=%s\n", dut->ap2_ssid);
if (dut->bridge)
fprintf(f, "bridge=%s\n", dut->bridge);
fprintf(f, "bssid=%02x:%02x:%02x:%02x:%02x:%02x\n",
bssid[0], bssid[1], bssid[2], bssid[3],
bssid[4], bssid[5]);
if (dut->ap2_key_mgmt == AP2_OSEN) {
fprintf(f, "osen=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);
}
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) {
fprintf(f, "eap_server=1\n"
"wps_state=1\n"
"device_name=QCA AP\n"
"manufacturer=QCA\n"
"device_type=6-0050F204-1\n"
"config_methods=label virtual_display "
"virtual_push_button keypad%s\n"
"ap_pin=12345670\n"
"friendly_name=QCA Access Point\n"
"upnp_iface=%s\n",
dut->ap_wpsnfc ? " nfc_interface ext_nfc_token" : "",
dut->bridge ? dut->bridge : ifname);
}
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");
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 ||
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 ? "[RXLDPC]" : "",
dut->ap_tx_stbc ? "[TX-STBC-2BY1]" : "",
dut->ap_mu_txBF ? "[MU-BEAMFORMER]" : "");
}
}
fclose(f);
#ifdef __QNXNTO__
if (system("slay hostapd") == 0)
#else /* __QNXNTO__ */
if (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__ */
}
}
#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");
if (chown(SIGMA_TMPDIR "/sigma_dut-ap.conf", -1, AID_WIFI) < 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(buf, sizeof(buf), "%shostapd -B%s%s%s%s " SIGMA_TMPDIR
"/sigma_dut-ap.conf",
file_exists("hostapd") ? "./" : "",
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 :
"");
}
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 (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;
}
return 1;
}
static void parse_qos_params(struct qos_params *qos, const char *cwmin,
const char *cwmax, const char *aifs,
const char *txop, const char *acm)
{
if (cwmin) {
qos->ac = 1;
qos->cwmin = atoi(cwmin);
}
if (cwmax) {
qos->ac = 1;
qos->cwmax = atoi(cwmax);
}
if (aifs) {
qos->ac = 1;
qos->aifs = atoi(aifs);
}
if (txop) {
qos->ac = 1;
qos->txop = atoi(txop) * 32;
}
if (acm) {
qos->ac = 1;
qos->acm = strcasecmp(acm, "on") == 0;
}
}
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 */
parse_qos_params(&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->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->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->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 1;
}
static int cmd_ap_set_staqos(struct sigma_dut *dut, struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
parse_qos_params(&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->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->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->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 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;
dut->program = sigma_program_to_enum(get_param(cmd, "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 = 0;
dut->ap_noack = AP_NOACK_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 = AP_DYN_BW_SGNL_NOT_SET;
dut->ap_ldpc = 0;
dut->ap_sig_rts = 0;
dut->ap_rx_amsdu = 0;
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;
if (dut->program == PROGRAM_HT || dut->program == PROGRAM_VHT)
dut->ap_wme = AP_WME_ON;
else
dut->ap_wme = AP_WME_OFF;
if (dut->program == PROGRAM_HS2 || dut->program == PROGRAM_HS2_R2) {
int i;
enum driver_type drv;
drv = get_driver_type();
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) {
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->ap2_ssid[0] = '\0';
dut->ap_pmf = 1;
dut->ap_osu_provider_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->ap2_key_mgmt = AP2_OPEN;
dut->ap2_proxy_arp = 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 = 0;
dut->ap_ndpa_frame = 1;
if (dut->device_type == AP_testbed) {
dut->ap_amsdu = 2;
dut->ap_ldpc = 2;
dut->ap_rx_amsdu = 2;
dut->ap_sgi80 = 0;
} else {
dut->ap_amsdu = 1;
dut->ap_ldpc = 1;
dut->ap_rx_amsdu = 1;
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 = AP_DYN_BW_SGNL_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 (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;
}
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);
int hwaddr_aton(const char *txt, unsigned char *addr);
#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));
strncpy(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");
return 0;
}
if (res < pos - buf) {
send_resp(dut, conn, SIGMA_ERROR, "errorCode,Only partial "
"frame sent");
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 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;
}
}
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)
return ap_send_frame_hs2(dut, conn, cmd);
if (strcasecmp(val, "VHT") == 0)
return ap_send_frame_vht(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[50];
unsigned char addr[6];
char *ifname;
struct ifreq ifr;
int s;
enum driver_type drv;
drv = get_driver_type();
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 ((dut->ap_mode == AP_11a || dut->ap_mode == AP_11na ||
dut->ap_mode == AP_11ac) &&
if_nametoindex("wlan1") > 0)
ifname = "wlan1";
else
ifname = "wlan0";
}
s = socket(AF_INET, SOCK_DGRAM, 0);
if (s < 0)
return -1;
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) {
perror("ioctl");
close(s);
return -1;
}
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__ */
}
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);
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;
}
strncpy(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;
}
strncpy(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_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) {
strncpy(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);
}
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 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 parse_hex(char c)
{
if (c >= '0' && c <= '9')
return c - '0';
if (c >= 'a' && c <= 'f')
return c - 'a' + 10;
if (c >= 'A' && c <= 'F')
return c - 'A' + 10;
return -1;
}
static int hex_byte(const char *str)
{
int res1, res2;
res1 = parse_hex(str[0]);
if (res1 < 0)
return -1;
res2 = parse_hex(str[1]);
if (res2 < 0)
return -1;
return (res1 << 4) | res2;
}
static int parse_mac_address(struct sigma_dut *dut, const char *arg,
unsigned char *addr)
{
int i;
const char *pos = arg;
if (strlen(arg) != 17)
goto fail;
for (i = 0; i < ETH_ALEN; i++) {
int val;
val = hex_byte(pos);
if (val < 0)
goto fail;
addr[i] = val;
if (i + 1 < ETH_ALEN) {
pos += 2;
if (*pos != ':')
goto fail;
pos++;
}
}
return 0;
fail:
sigma_dut_print(dut, DUT_MSG_ERROR,
"Invalid MAC address %s (expected format xx:xx:xx:xx:xx:xx)",
arg);
return -1;
}
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");
}
}
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;
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 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);
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;
}
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("AccessPoint", NULL, cmd_accesspoint);
}