6966 lines
181 KiB
C
6966 lines
181 KiB
C
/*
|
|
* 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);
|
|
}
|