Use common get_hw_feature_data for hostapd and wpa_supplicant

This merges the driver wrapper implementations to use the same
implementation both for hostapd and wpa_supplicant operations to avoid
code duplication.
This commit is contained in:
Jouni Malinen 2009-04-09 14:11:39 +03:00 committed by Jouni Malinen
parent c51218372f
commit c3965310e6
9 changed files with 149 additions and 460 deletions

View file

@ -453,11 +453,10 @@ hostapd_get_hw_feature_data(struct hostapd_data *hapd, u16 *num_modes,
u16 *flags) u16 *flags)
{ {
if (hapd->driver == NULL || if (hapd->driver == NULL ||
hapd->driver->hapd_get_hw_feature_data == NULL) hapd->driver->get_hw_feature_data == NULL)
return NULL; return NULL;
return hapd->driver->hapd_get_hw_feature_data(hapd->drv_priv, return hapd->driver->get_hw_feature_data(hapd->drv_priv, num_modes,
num_modes, flags);
flags);
} }
static inline int static inline int

View file

@ -1297,9 +1297,6 @@ struct wpa_driver_ops {
int (*passive_scan)(void *priv, int now, int our_mode_only, int (*passive_scan)(void *priv, int now, int our_mode_only,
int interval, int _listen, int *channel, int interval, int _listen, int *channel,
int *last_rx); int *last_rx);
struct hostapd_hw_modes * (*hapd_get_hw_feature_data)(void *priv,
u16 *num_modes,
u16 *flags);
int (*if_add)(const char *iface, void *priv, int (*if_add)(const char *iface, void *priv,
enum hostapd_driver_if_type type, char *ifname, enum hostapd_driver_if_type type, char *ifname,
const u8 *addr); const u8 *addr);
@ -1714,8 +1711,6 @@ void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr,
void wpa_supplicant_sta_rx(void *ctx, const u8 *buf, size_t len, void wpa_supplicant_sta_rx(void *ctx, const u8 *buf, size_t len,
struct ieee80211_rx_status *rx_status); struct ieee80211_rx_status *rx_status);
void wpa_supplicant_sta_free_hw_features(struct hostapd_hw_modes *hw_features,
size_t num_hw_features);
const u8 * wpa_scan_get_ie(const struct wpa_scan_res *res, u8 ie); const u8 * wpa_scan_get_ie(const struct wpa_scan_res *res, u8 ie);
#define WPA_IE_VENDOR_TYPE 0x0050f201 #define WPA_IE_VENDOR_TYPE 0x0050f201

View file

@ -3257,7 +3257,6 @@ const struct wpa_driver_ops wpa_driver_ndis_ops = {
NULL /* bss_remove */, NULL /* bss_remove */,
NULL /* valid_bss_mask */, NULL /* valid_bss_mask */,
NULL /* passive_scan */, NULL /* passive_scan */,
NULL /* hapd_get_hw_feature_data */,
NULL /* if_add */, NULL /* if_add */,
NULL /* if_update */, NULL /* if_update */,
NULL /* if_remove */, NULL /* if_remove */,

View file

@ -1622,7 +1622,7 @@ nla_put_failure:
} }
#ifdef CONFIG_AP #if defined(CONFIG_AP) || defined(HOSTAPD)
struct phy_info_arg { struct phy_info_arg {
u16 *num_modes; u16 *num_modes;
@ -1887,6 +1887,10 @@ wpa_driver_nl80211_get_hw_feature_data(void *priv, u16 *num_modes, u16 *flags)
return NULL; return NULL;
} }
#endif /* CONFIG_AP || HOSTAPD */
#ifdef CONFIG_AP
static int wpa_driver_nl80211_send_frame(struct wpa_driver_nl80211_data *drv, static int wpa_driver_nl80211_send_frame(struct wpa_driver_nl80211_data *drv,
const void *data, size_t len, const void *data, size_t len,
@ -3869,270 +3873,6 @@ static int i802_if_remove(void *priv, enum hostapd_driver_if_type type,
} }
struct phy_info_arg {
u16 *num_modes;
struct hostapd_hw_modes *modes;
};
static int phy_info_handler(struct nl_msg *msg, void *arg)
{
struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];
struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
struct phy_info_arg *phy_info = arg;
struct nlattr *tb_band[NL80211_BAND_ATTR_MAX + 1];
struct nlattr *tb_freq[NL80211_FREQUENCY_ATTR_MAX + 1];
static struct nla_policy freq_policy[NL80211_FREQUENCY_ATTR_MAX + 1] = {
[NL80211_FREQUENCY_ATTR_FREQ] = { .type = NLA_U32 },
[NL80211_FREQUENCY_ATTR_DISABLED] = { .type = NLA_FLAG },
[NL80211_FREQUENCY_ATTR_PASSIVE_SCAN] = { .type = NLA_FLAG },
[NL80211_FREQUENCY_ATTR_NO_IBSS] = { .type = NLA_FLAG },
[NL80211_FREQUENCY_ATTR_RADAR] = { .type = NLA_FLAG },
[NL80211_FREQUENCY_ATTR_MAX_TX_POWER] = { .type = NLA_U32 },
};
struct nlattr *tb_rate[NL80211_BITRATE_ATTR_MAX + 1];
static struct nla_policy rate_policy[NL80211_BITRATE_ATTR_MAX + 1] = {
[NL80211_BITRATE_ATTR_RATE] = { .type = NLA_U32 },
[NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE] = { .type = NLA_FLAG },
};
struct nlattr *nl_band;
struct nlattr *nl_freq;
struct nlattr *nl_rate;
int rem_band, rem_freq, rem_rate;
struct hostapd_hw_modes *mode;
int idx, mode_is_set;
nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
genlmsg_attrlen(gnlh, 0), NULL);
if (!tb_msg[NL80211_ATTR_WIPHY_BANDS])
return NL_SKIP;
nla_for_each_nested(nl_band, tb_msg[NL80211_ATTR_WIPHY_BANDS], rem_band) {
mode = realloc(phy_info->modes, (*phy_info->num_modes + 1) * sizeof(*mode));
if (!mode)
return NL_SKIP;
phy_info->modes = mode;
mode_is_set = 0;
mode = &phy_info->modes[*(phy_info->num_modes)];
memset(mode, 0, sizeof(*mode));
*(phy_info->num_modes) += 1;
nla_parse(tb_band, NL80211_BAND_ATTR_MAX, nla_data(nl_band),
nla_len(nl_band), NULL);
if (tb_band[NL80211_BAND_ATTR_HT_CAPA]) {
mode->ht_capab = nla_get_u16(
tb_band[NL80211_BAND_ATTR_HT_CAPA]);
}
nla_for_each_nested(nl_freq, tb_band[NL80211_BAND_ATTR_FREQS], rem_freq) {
nla_parse(tb_freq, NL80211_FREQUENCY_ATTR_MAX, nla_data(nl_freq),
nla_len(nl_freq), freq_policy);
if (!tb_freq[NL80211_FREQUENCY_ATTR_FREQ])
continue;
mode->num_channels++;
}
mode->channels = calloc(mode->num_channels, sizeof(struct hostapd_channel_data));
if (!mode->channels)
return NL_SKIP;
idx = 0;
nla_for_each_nested(nl_freq, tb_band[NL80211_BAND_ATTR_FREQS], rem_freq) {
nla_parse(tb_freq, NL80211_FREQUENCY_ATTR_MAX, nla_data(nl_freq),
nla_len(nl_freq), freq_policy);
if (!tb_freq[NL80211_FREQUENCY_ATTR_FREQ])
continue;
mode->channels[idx].freq = nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_FREQ]);
mode->channels[idx].flag = 0;
if (!mode_is_set) {
/* crude heuristic */
if (mode->channels[idx].freq < 4000)
mode->mode = HOSTAPD_MODE_IEEE80211B;
else
mode->mode = HOSTAPD_MODE_IEEE80211A;
mode_is_set = 1;
}
/* crude heuristic */
if (mode->channels[idx].freq < 4000)
if (mode->channels[idx].freq == 2848)
mode->channels[idx].chan = 14;
else
mode->channels[idx].chan = (mode->channels[idx].freq - 2407) / 5;
else
mode->channels[idx].chan = mode->channels[idx].freq/5 - 1000;
if (tb_freq[NL80211_FREQUENCY_ATTR_DISABLED])
mode->channels[idx].flag |=
HOSTAPD_CHAN_DISABLED;
if (tb_freq[NL80211_FREQUENCY_ATTR_PASSIVE_SCAN])
mode->channels[idx].flag |=
HOSTAPD_CHAN_PASSIVE_SCAN;
if (tb_freq[NL80211_FREQUENCY_ATTR_NO_IBSS])
mode->channels[idx].flag |=
HOSTAPD_CHAN_NO_IBSS;
if (tb_freq[NL80211_FREQUENCY_ATTR_RADAR])
mode->channels[idx].flag |=
HOSTAPD_CHAN_RADAR;
if (tb_freq[NL80211_FREQUENCY_ATTR_MAX_TX_POWER] &&
!tb_freq[NL80211_FREQUENCY_ATTR_DISABLED])
mode->channels[idx].max_tx_power =
nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_MAX_TX_POWER]) / 100;
idx++;
}
nla_for_each_nested(nl_rate, tb_band[NL80211_BAND_ATTR_RATES], rem_rate) {
nla_parse(tb_rate, NL80211_BITRATE_ATTR_MAX, nla_data(nl_rate),
nla_len(nl_rate), rate_policy);
if (!tb_rate[NL80211_BITRATE_ATTR_RATE])
continue;
mode->num_rates++;
}
mode->rates = calloc(mode->num_rates, sizeof(struct hostapd_rate_data));
if (!mode->rates)
return NL_SKIP;
idx = 0;
nla_for_each_nested(nl_rate, tb_band[NL80211_BAND_ATTR_RATES], rem_rate) {
nla_parse(tb_rate, NL80211_BITRATE_ATTR_MAX, nla_data(nl_rate),
nla_len(nl_rate), rate_policy);
if (!tb_rate[NL80211_BITRATE_ATTR_RATE])
continue;
mode->rates[idx].rate = nla_get_u32(tb_rate[NL80211_BITRATE_ATTR_RATE]);
/* crude heuristic */
if (mode->mode == HOSTAPD_MODE_IEEE80211B &&
mode->rates[idx].rate > 200)
mode->mode = HOSTAPD_MODE_IEEE80211G;
if (tb_rate[NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE])
mode->rates[idx].flags |= HOSTAPD_RATE_PREAMBLE2;
idx++;
}
}
return NL_SKIP;
}
static struct hostapd_hw_modes *i802_add_11b(struct hostapd_hw_modes *modes,
u16 *num_modes)
{
u16 m;
struct hostapd_hw_modes *mode11g = NULL, *nmodes, *mode;
int i, mode11g_idx = -1;
/* If only 802.11g mode is included, use it to construct matching
* 802.11b mode data. */
for (m = 0; m < *num_modes; m++) {
if (modes[m].mode == HOSTAPD_MODE_IEEE80211B)
return modes; /* 802.11b already included */
if (modes[m].mode == HOSTAPD_MODE_IEEE80211G)
mode11g_idx = m;
}
if (mode11g_idx < 0)
return modes; /* 2.4 GHz band not supported at all */
nmodes = os_realloc(modes, (*num_modes + 1) * sizeof(*nmodes));
if (nmodes == NULL)
return modes; /* Could not add 802.11b mode */
mode = &nmodes[*num_modes];
os_memset(mode, 0, sizeof(*mode));
(*num_modes)++;
modes = nmodes;
mode->mode = HOSTAPD_MODE_IEEE80211B;
mode11g = &modes[mode11g_idx];
mode->num_channels = mode11g->num_channels;
mode->channels = os_malloc(mode11g->num_channels *
sizeof(struct hostapd_channel_data));
if (mode->channels == NULL) {
(*num_modes)--;
return modes; /* Could not add 802.11b mode */
}
os_memcpy(mode->channels, mode11g->channels,
mode11g->num_channels * sizeof(struct hostapd_channel_data));
mode->num_rates = 0;
mode->rates = os_malloc(4 * sizeof(struct hostapd_rate_data));
if (mode->rates == NULL) {
os_free(mode->channels);
(*num_modes)--;
return modes; /* Could not add 802.11b mode */
}
for (i = 0; i < mode11g->num_rates; i++) {
if (mode11g->rates[i].rate > 110 ||
mode11g->rates[i].flags &
(HOSTAPD_RATE_ERP | HOSTAPD_RATE_OFDM))
continue;
mode->rates[mode->num_rates] = mode11g->rates[i];
mode->num_rates++;
if (mode->num_rates == 4)
break;
}
if (mode->num_rates == 0) {
os_free(mode->channels);
os_free(mode->rates);
(*num_modes)--;
return modes; /* No 802.11b rates */
}
wpa_printf(MSG_DEBUG, "nl80211: Added 802.11b mode based on 802.11g "
"information");
return modes;
}
static struct hostapd_hw_modes *i802_get_hw_feature_data(void *priv,
u16 *num_modes,
u16 *flags)
{
struct wpa_driver_nl80211_data *drv = priv;
struct nl_msg *msg;
struct phy_info_arg result = {
.num_modes = num_modes,
.modes = NULL,
};
*num_modes = 0;
*flags = 0;
msg = nlmsg_alloc();
if (!msg)
return NULL;
genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
0, NL80211_CMD_GET_WIPHY, 0);
NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(drv->ifname));
if (send_and_recv_msgs(drv, msg, phy_info_handler, &result) == 0)
return i802_add_11b(result.modes, num_modes);
nla_put_failure:
return NULL;
}
static int i802_set_sta_vlan(void *priv, const u8 *addr, static int i802_set_sta_vlan(void *priv, const u8 *addr,
const char *ifname, int vlan_id) const char *ifname, int vlan_id)
{ {
@ -5490,6 +5230,7 @@ static void *i802_init_bssid(struct hostapd_data *hapd, const u8 *bssid)
drv->hapd = hapd; drv->hapd = hapd;
memcpy(drv->ifname, hapd->conf->iface, sizeof(drv->ifname)); memcpy(drv->ifname, hapd->conf->iface, sizeof(drv->ifname));
memcpy(drv->bss.ifname, hapd->conf->iface, sizeof(drv->bss.ifname)); memcpy(drv->bss.ifname, hapd->conf->iface, sizeof(drv->bss.ifname));
drv->ifindex = if_nametoindex(drv->ifname);
drv->num_if_indices = sizeof(drv->default_if_indices) / sizeof(int); drv->num_if_indices = sizeof(drv->default_if_indices) / sizeof(int);
drv->if_indices = drv->default_if_indices; drv->if_indices = drv->default_if_indices;
@ -5597,8 +5338,10 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
.set_beacon = wpa_driver_nl80211_set_beacon, .set_beacon = wpa_driver_nl80211_set_beacon,
.set_beacon_int = wpa_driver_nl80211_set_beacon_int, .set_beacon_int = wpa_driver_nl80211_set_beacon_int,
.send_mlme = wpa_driver_nl80211_send_mlme, .send_mlme = wpa_driver_nl80211_send_mlme,
.get_hw_feature_data = wpa_driver_nl80211_get_hw_feature_data,
#endif /* CONFIG_AP */ #endif /* CONFIG_AP */
#if defined(CONFIG_AP) || defined(HOSTAPD)
.get_hw_feature_data = wpa_driver_nl80211_get_hw_feature_data,
#endif /* CONFIG_AP || HOSTAPD */
#ifdef HOSTAPD #ifdef HOSTAPD
.hapd_init = i802_init, .hapd_init = i802_init,
.init_bssid = i802_init_bssid, .init_bssid = i802_init_bssid,
@ -5632,7 +5375,6 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
.if_add = i802_if_add, .if_add = i802_if_add,
.if_update = i802_if_update, .if_update = i802_if_update,
.if_remove = i802_if_remove, .if_remove = i802_if_remove,
.hapd_get_hw_feature_data = i802_get_hw_feature_data,
.set_sta_vlan = i802_set_sta_vlan, .set_sta_vlan = i802_set_sta_vlan,
.hapd_set_country = i802_set_country, .hapd_set_country = i802_set_country,
.get_neighbor_bss = i802_get_neighbor_bss, .get_neighbor_bss = i802_get_neighbor_bss,

View file

@ -853,7 +853,6 @@ struct wpa_driver_ops wpa_driver_privsep_ops = {
NULL /* bss_remove */, NULL /* bss_remove */,
NULL /* valid_bss_mask */, NULL /* valid_bss_mask */,
NULL /* passive_scan */, NULL /* passive_scan */,
NULL /* hapd_get_hw_feature_data */,
NULL /* if_add */, NULL /* if_add */,
NULL /* if_update */, NULL /* if_update */,
NULL /* if_remove */, NULL /* if_remove */,

View file

@ -77,6 +77,46 @@ struct test_driver_data {
int udp_port; int udp_port;
}; };
#else /* HOSTAPD */
struct wpa_driver_test_global {
int dummy;
};
struct wpa_driver_test_data {
struct wpa_driver_test_global *global;
void *ctx;
u8 own_addr[ETH_ALEN];
int test_socket;
#ifdef DRIVER_TEST_UNIX
struct sockaddr_un hostapd_addr;
#endif /* DRIVER_TEST_UNIX */
int hostapd_addr_set;
struct sockaddr_in hostapd_addr_udp;
int hostapd_addr_udp_set;
char *own_socket_path;
char *test_dir;
u8 bssid[ETH_ALEN];
u8 ssid[32];
size_t ssid_len;
#define MAX_SCAN_RESULTS 30
struct wpa_scan_res *scanres[MAX_SCAN_RESULTS];
size_t num_scanres;
int use_associnfo;
u8 assoc_wpa_ie[80];
size_t assoc_wpa_ie_len;
int use_mlme;
int associated;
u8 *probe_req_ie;
size_t probe_req_ie_len;
int ibss;
int privacy;
};
#endif /* HOSTAPD */
#ifdef HOSTAPD
static void test_driver_free_bss(struct test_driver_bss *bss) static void test_driver_free_bss(struct test_driver_bss *bss)
{ {
@ -821,68 +861,6 @@ static int test_driver_sta_disassoc(void *priv, const u8 *addr, int reason)
} }
static struct hostapd_hw_modes *
test_driver_get_hw_feature_data(void *priv, u16 *num_modes, u16 *flags)
{
struct hostapd_hw_modes *modes;
*num_modes = 3;
*flags = 0;
modes = os_zalloc(*num_modes * sizeof(struct hostapd_hw_modes));
if (modes == NULL)
return NULL;
modes[0].mode = HOSTAPD_MODE_IEEE80211G;
modes[0].num_channels = 1;
modes[0].num_rates = 1;
modes[0].channels = os_zalloc(sizeof(struct hostapd_channel_data));
modes[0].rates = os_zalloc(sizeof(struct hostapd_rate_data));
if (modes[0].channels == NULL || modes[0].rates == NULL) {
hostapd_free_hw_features(modes, *num_modes);
return NULL;
}
modes[0].channels[0].chan = 1;
modes[0].channels[0].freq = 2412;
modes[0].channels[0].flag = 0;
modes[0].rates[0].rate = 10;
modes[0].rates[0].flags = HOSTAPD_RATE_BASIC | HOSTAPD_RATE_SUPPORTED |
HOSTAPD_RATE_CCK | HOSTAPD_RATE_MANDATORY;
modes[1].mode = HOSTAPD_MODE_IEEE80211B;
modes[1].num_channels = 1;
modes[1].num_rates = 1;
modes[1].channels = os_zalloc(sizeof(struct hostapd_channel_data));
modes[1].rates = os_zalloc(sizeof(struct hostapd_rate_data));
if (modes[1].channels == NULL || modes[1].rates == NULL) {
hostapd_free_hw_features(modes, *num_modes);
return NULL;
}
modes[1].channels[0].chan = 1;
modes[1].channels[0].freq = 2412;
modes[1].channels[0].flag = 0;
modes[1].rates[0].rate = 10;
modes[1].rates[0].flags = HOSTAPD_RATE_BASIC | HOSTAPD_RATE_SUPPORTED |
HOSTAPD_RATE_CCK | HOSTAPD_RATE_MANDATORY;
modes[2].mode = HOSTAPD_MODE_IEEE80211A;
modes[2].num_channels = 1;
modes[2].num_rates = 1;
modes[2].channels = os_zalloc(sizeof(struct hostapd_channel_data));
modes[2].rates = os_zalloc(sizeof(struct hostapd_rate_data));
if (modes[2].channels == NULL || modes[2].rates == NULL) {
hostapd_free_hw_features(modes, *num_modes);
return NULL;
}
modes[2].channels[0].chan = 60;
modes[2].channels[0].freq = 5300;
modes[2].channels[0].flag = 0;
modes[2].rates[0].rate = 60;
modes[2].rates[0].flags = HOSTAPD_RATE_BASIC | HOSTAPD_RATE_SUPPORTED |
HOSTAPD_RATE_MANDATORY;
return modes;
}
static int test_driver_bss_add(void *priv, const char *ifname, const u8 *bssid) static int test_driver_bss_add(void *priv, const char *ifname, const u8 *bssid)
{ {
struct test_driver_data *drv = priv; struct test_driver_data *drv = priv;
@ -1215,70 +1193,8 @@ static void test_driver_deinit(void *priv)
test_driver_free_priv(drv); test_driver_free_priv(drv);
} }
const struct wpa_driver_ops wpa_driver_test_ops = {
.name = "test",
.hapd_init = test_driver_init,
.hapd_deinit = test_driver_deinit,
.hapd_send_eapol = test_driver_send_eapol,
.send_mgmt_frame = test_driver_send_mgmt_frame,
.set_generic_elem = test_driver_set_generic_elem,
.sta_deauth = test_driver_sta_deauth,
.sta_disassoc = test_driver_sta_disassoc,
.get_hw_feature_data = test_driver_get_hw_feature_data,
.bss_add = test_driver_bss_add,
.bss_remove = test_driver_bss_remove,
.if_add = test_driver_if_add,
.if_update = test_driver_if_update,
.if_remove = test_driver_if_remove,
.valid_bss_mask = test_driver_valid_bss_mask,
.hapd_set_ssid = test_driver_set_ssid,
.set_privacy = test_driver_set_privacy,
.hapd_set_key = test_driver_set_key,
.set_sta_vlan = test_driver_set_sta_vlan,
.sta_add = test_driver_sta_add,
.send_ether = test_driver_send_ether,
.set_wps_beacon_ie = test_driver_set_wps_beacon_ie,
.set_wps_probe_resp_ie = test_driver_set_wps_probe_resp_ie,
};
#else /* HOSTAPD */ #else /* HOSTAPD */
struct wpa_driver_test_global {
int dummy;
};
struct wpa_driver_test_data {
struct wpa_driver_test_global *global;
void *ctx;
u8 own_addr[ETH_ALEN];
int test_socket;
#ifdef DRIVER_TEST_UNIX
struct sockaddr_un hostapd_addr;
#endif /* DRIVER_TEST_UNIX */
int hostapd_addr_set;
struct sockaddr_in hostapd_addr_udp;
int hostapd_addr_udp_set;
char *own_socket_path;
char *test_dir;
u8 bssid[ETH_ALEN];
u8 ssid[32];
size_t ssid_len;
#define MAX_SCAN_RESULTS 30
struct wpa_scan_res *scanres[MAX_SCAN_RESULTS];
size_t num_scanres;
int use_associnfo;
u8 assoc_wpa_ie[80];
size_t assoc_wpa_ie_len;
int use_mlme;
int associated;
u8 *probe_req_ie;
size_t probe_req_ie_len;
int ibss;
int privacy;
};
static void wpa_driver_test_poll(void *eloop_ctx, void *timeout_ctx) static void wpa_driver_test_poll(void *eloop_ctx, void *timeout_ctx)
{ {
struct wpa_driver_test_data *drv = eloop_ctx; struct wpa_driver_test_data *drv = eloop_ctx;
@ -2256,36 +2172,6 @@ static int wpa_driver_test_mlme_setprotection(void *priv, const u8 *addr,
#ifdef CONFIG_CLIENT_MLME #ifdef CONFIG_CLIENT_MLME
static struct hostapd_hw_modes *
wpa_driver_test_get_hw_feature_data(void *priv, u16 *num_modes, u16 *flags)
{
struct hostapd_hw_modes *modes;
*num_modes = 1;
*flags = 0;
modes = os_zalloc(*num_modes * sizeof(struct hostapd_hw_modes));
if (modes == NULL)
return NULL;
modes[0].mode = HOSTAPD_MODE_IEEE80211G;
modes[0].num_channels = 1;
modes[0].num_rates = 1;
modes[0].channels = os_zalloc(sizeof(struct hostapd_channel_data));
modes[0].rates = os_zalloc(sizeof(struct hostapd_rate_data));
if (modes[0].channels == NULL || modes[0].rates == NULL) {
wpa_supplicant_sta_free_hw_features(modes, *num_modes);
return NULL;
}
modes[0].channels[0].chan = 1;
modes[0].channels[0].freq = 2412;
modes[0].channels[0].flag = 0;
modes[0].rates[0].rate = 10;
modes[0].rates[0].flags = HOSTAPD_RATE_BASIC | HOSTAPD_RATE_SUPPORTED |
HOSTAPD_RATE_CCK | HOSTAPD_RATE_MANDATORY;
return modes;
}
static int wpa_driver_test_set_channel(void *priv, hostapd_hw_mode phymode, static int wpa_driver_test_set_channel(void *priv, hostapd_hw_mode phymode,
int chan, int freq) int chan, int freq)
{ {
@ -2479,10 +2365,105 @@ wpa_driver_test_get_interfaces(void *global_priv)
return iface; return iface;
} }
#endif /* HOSTAPD */
#if defined(HOSTAPD) || defined(CONFIG_CLIENT_MLME)
static struct hostapd_hw_modes *
wpa_driver_test_get_hw_feature_data(void *priv, u16 *num_modes, u16 *flags)
{
struct hostapd_hw_modes *modes;
*num_modes = 3;
*flags = 0;
modes = os_zalloc(*num_modes * sizeof(struct hostapd_hw_modes));
if (modes == NULL)
return NULL;
modes[0].mode = HOSTAPD_MODE_IEEE80211G;
modes[0].num_channels = 1;
modes[0].num_rates = 1;
modes[0].channels = os_zalloc(sizeof(struct hostapd_channel_data));
modes[0].rates = os_zalloc(sizeof(struct hostapd_rate_data));
if (modes[0].channels == NULL || modes[0].rates == NULL)
goto fail;
modes[0].channels[0].chan = 1;
modes[0].channels[0].freq = 2412;
modes[0].channels[0].flag = 0;
modes[0].rates[0].rate = 10;
modes[0].rates[0].flags = HOSTAPD_RATE_BASIC | HOSTAPD_RATE_SUPPORTED |
HOSTAPD_RATE_CCK | HOSTAPD_RATE_MANDATORY;
modes[1].mode = HOSTAPD_MODE_IEEE80211B;
modes[1].num_channels = 1;
modes[1].num_rates = 1;
modes[1].channels = os_zalloc(sizeof(struct hostapd_channel_data));
modes[1].rates = os_zalloc(sizeof(struct hostapd_rate_data));
if (modes[1].channels == NULL || modes[1].rates == NULL)
goto fail;
modes[1].channels[0].chan = 1;
modes[1].channels[0].freq = 2412;
modes[1].channels[0].flag = 0;
modes[1].rates[0].rate = 10;
modes[1].rates[0].flags = HOSTAPD_RATE_BASIC | HOSTAPD_RATE_SUPPORTED |
HOSTAPD_RATE_CCK | HOSTAPD_RATE_MANDATORY;
modes[2].mode = HOSTAPD_MODE_IEEE80211A;
modes[2].num_channels = 1;
modes[2].num_rates = 1;
modes[2].channels = os_zalloc(sizeof(struct hostapd_channel_data));
modes[2].rates = os_zalloc(sizeof(struct hostapd_rate_data));
if (modes[2].channels == NULL || modes[2].rates == NULL)
goto fail;
modes[2].channels[0].chan = 60;
modes[2].channels[0].freq = 5300;
modes[2].channels[0].flag = 0;
modes[2].rates[0].rate = 60;
modes[2].rates[0].flags = HOSTAPD_RATE_BASIC | HOSTAPD_RATE_SUPPORTED |
HOSTAPD_RATE_MANDATORY;
return modes;
fail:
if (modes) {
size_t i;
for (i = 0; i < *num_modes; i++) {
os_free(modes[i].channels);
os_free(modes[i].rates);
}
os_free(modes);
}
return NULL;
}
#endif /* HOSTAPD || CONFIG_CLIENT_MLME */
const struct wpa_driver_ops wpa_driver_test_ops = { const struct wpa_driver_ops wpa_driver_test_ops = {
"test", "test",
"wpa_supplicant test driver", "wpa_supplicant test driver",
#ifdef HOSTAPD
.hapd_init = test_driver_init,
.hapd_deinit = test_driver_deinit,
.hapd_send_eapol = test_driver_send_eapol,
.send_mgmt_frame = test_driver_send_mgmt_frame,
.set_generic_elem = test_driver_set_generic_elem,
.sta_deauth = test_driver_sta_deauth,
.sta_disassoc = test_driver_sta_disassoc,
.get_hw_feature_data = wpa_driver_test_get_hw_feature_data,
.bss_add = test_driver_bss_add,
.bss_remove = test_driver_bss_remove,
.if_add = test_driver_if_add,
.if_update = test_driver_if_update,
.if_remove = test_driver_if_remove,
.valid_bss_mask = test_driver_valid_bss_mask,
.hapd_set_ssid = test_driver_set_ssid,
.set_privacy = test_driver_set_privacy,
.hapd_set_key = test_driver_set_key,
.set_sta_vlan = test_driver_set_sta_vlan,
.sta_add = test_driver_sta_add,
.send_ether = test_driver_send_ether,
.set_wps_beacon_ie = test_driver_set_wps_beacon_ie,
.set_wps_probe_resp_ie = test_driver_set_wps_probe_resp_ie,
#else /* HOSTAPD */
wpa_driver_test_get_bssid, wpa_driver_test_get_bssid,
wpa_driver_test_get_ssid, wpa_driver_test_get_ssid,
wpa_driver_test_set_wpa, wpa_driver_test_set_wpa,
@ -2581,7 +2562,6 @@ const struct wpa_driver_ops wpa_driver_test_ops = {
NULL /* bss_remove */, NULL /* bss_remove */,
NULL /* valid_bss_mask */, NULL /* valid_bss_mask */,
NULL /* passive_scan */, NULL /* passive_scan */,
NULL /* hapd_get_hw_feature_data */,
NULL /* if_add */, NULL /* if_add */,
NULL /* if_update */, NULL /* if_update */,
NULL /* if_remove */, NULL /* if_remove */,
@ -2594,6 +2574,5 @@ const struct wpa_driver_ops wpa_driver_test_ops = {
NULL /* set_wps_beacon_ie */, NULL /* set_wps_beacon_ie */,
NULL /* set_wps_probe_resp_ie */, NULL /* set_wps_probe_resp_ie */,
NULL /* get_neighbor_bss */ NULL /* get_neighbor_bss */
};
#endif /* HOSTAPD */ #endif /* HOSTAPD */
};

View file

@ -268,7 +268,7 @@ struct wpa_driver_ops ap_driver_ops =
.set_preamble = ap_driver_set_preamble, .set_preamble = ap_driver_set_preamble,
.set_short_slot_time = ap_driver_set_short_slot_time, .set_short_slot_time = ap_driver_set_short_slot_time,
.set_tx_queue_params = ap_driver_set_tx_queue_params, .set_tx_queue_params = ap_driver_set_tx_queue_params,
.hapd_get_hw_feature_data = ap_driver_get_hw_feature_data, .get_hw_feature_data = ap_driver_get_hw_feature_data,
}; };

View file

@ -1050,23 +1050,6 @@ void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr,
#ifdef CONFIG_CLIENT_MLME #ifdef CONFIG_CLIENT_MLME
void wpa_supplicant_sta_free_hw_features(struct hostapd_hw_modes *hw_features,
size_t num_hw_features)
{
size_t i;
if (hw_features == NULL)
return;
for (i = 0; i < num_hw_features; i++) {
os_free(hw_features[i].channels);
os_free(hw_features[i].rates);
}
os_free(hw_features);
}
void wpa_supplicant_sta_rx(void *ctx, const u8 *buf, size_t len, void wpa_supplicant_sta_rx(void *ctx, const u8 *buf, size_t len,
struct ieee80211_rx_status *rx_status) struct ieee80211_rx_status *rx_status)
{ {

View file

@ -1631,13 +1631,6 @@ void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr,
} }
void wpa_supplicant_sta_free_hw_features(struct hostapd_hw_modes *hw_features,
size_t num_hw_features)
{
ieee80211_sta_free_hw_features(hw_features, num_hw_features);
}
void wpa_supplicant_sta_rx(void *ctx, const u8 *buf, size_t len, void wpa_supplicant_sta_rx(void *ctx, const u8 *buf, size_t len,
struct ieee80211_rx_status *rx_status) struct ieee80211_rx_status *rx_status)
{ {