wl12xx: AP mode - support hidden SSID
If a hidden SSID is requested, generate a probe response template containing the real SSID. Depends on the patch "mac80211: add ssid config to bss information in AP-mode". Signed-off-by: Arik Nemtsov <arik@wizery.com> Signed-off-by: Luciano Coelho <coelho@ti.com>
This commit is contained in:
parent
df4c849f46
commit
68eaaf6ee5
2 changed files with 82 additions and 17 deletions
|
@ -661,12 +661,9 @@ int wl12xx_cmd_role_start_ap(struct wl1271 *wl)
|
|||
|
||||
wl1271_debug(DEBUG_CMD, "cmd role start ap %d", wl->role_id);
|
||||
|
||||
/*
|
||||
* We currently do not support hidden SSID. The real SSID
|
||||
* should be fetched from mac80211 first.
|
||||
*/
|
||||
if (wl->ssid_len == 0) {
|
||||
wl1271_warning("Hidden SSID currently not supported for AP");
|
||||
/* trying to use hidden SSID with an old hostapd version */
|
||||
if (wl->ssid_len == 0 && !bss_conf->hidden_ssid) {
|
||||
wl1271_error("got a null SSID from beacon/bss");
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
@ -695,9 +692,18 @@ int wl12xx_cmd_role_start_ap(struct wl1271 *wl)
|
|||
cmd->ap.dtim_interval = bss_conf->dtim_period;
|
||||
cmd->ap.beacon_expiry = WL1271_AP_DEF_BEACON_EXP;
|
||||
cmd->channel = wl->channel;
|
||||
cmd->ap.ssid_len = wl->ssid_len;
|
||||
|
||||
if (!bss_conf->hidden_ssid) {
|
||||
/* take the SSID from the beacon for backward compatibility */
|
||||
cmd->ap.ssid_type = WL12XX_SSID_TYPE_PUBLIC;
|
||||
cmd->ap.ssid_len = wl->ssid_len;
|
||||
memcpy(cmd->ap.ssid, wl->ssid, wl->ssid_len);
|
||||
} else {
|
||||
cmd->ap.ssid_type = WL12XX_SSID_TYPE_HIDDEN;
|
||||
cmd->ap.ssid_len = bss_conf->ssid_len;
|
||||
memcpy(cmd->ap.ssid, bss_conf->ssid, bss_conf->ssid_len);
|
||||
}
|
||||
|
||||
cmd->ap.local_rates = cpu_to_le32(0xffffffff);
|
||||
|
||||
switch (wl->band) {
|
||||
|
|
|
@ -3102,6 +3102,62 @@ static void wl12xx_remove_vendor_ie(struct sk_buff *skb,
|
|||
skb_trim(skb, skb->len - len);
|
||||
}
|
||||
|
||||
static int wl1271_ap_set_probe_resp_tmpl(struct wl1271 *wl,
|
||||
u8 *probe_rsp_data,
|
||||
size_t probe_rsp_len,
|
||||
u32 rates)
|
||||
{
|
||||
struct ieee80211_bss_conf *bss_conf = &wl->vif->bss_conf;
|
||||
u8 probe_rsp_templ[WL1271_CMD_TEMPL_MAX_SIZE];
|
||||
int ssid_ie_offset, ie_offset, templ_len;
|
||||
const u8 *ptr;
|
||||
|
||||
/* no need to change probe response if the SSID is set correctly */
|
||||
if (wl->ssid_len > 0)
|
||||
return wl1271_cmd_template_set(wl,
|
||||
CMD_TEMPL_AP_PROBE_RESPONSE,
|
||||
probe_rsp_data,
|
||||
probe_rsp_len, 0,
|
||||
rates);
|
||||
|
||||
if (probe_rsp_len + bss_conf->ssid_len > WL1271_CMD_TEMPL_MAX_SIZE) {
|
||||
wl1271_error("probe_rsp template too big");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* start searching from IE offset */
|
||||
ie_offset = offsetof(struct ieee80211_mgmt, u.probe_resp.variable);
|
||||
|
||||
ptr = cfg80211_find_ie(WLAN_EID_SSID, probe_rsp_data + ie_offset,
|
||||
probe_rsp_len - ie_offset);
|
||||
if (!ptr) {
|
||||
wl1271_error("No SSID in beacon!");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ssid_ie_offset = ptr - probe_rsp_data;
|
||||
ptr += (ptr[1] + 2);
|
||||
|
||||
memcpy(probe_rsp_templ, probe_rsp_data, ssid_ie_offset);
|
||||
|
||||
/* insert SSID from bss_conf */
|
||||
probe_rsp_templ[ssid_ie_offset] = WLAN_EID_SSID;
|
||||
probe_rsp_templ[ssid_ie_offset + 1] = bss_conf->ssid_len;
|
||||
memcpy(probe_rsp_templ + ssid_ie_offset + 2,
|
||||
bss_conf->ssid, bss_conf->ssid_len);
|
||||
templ_len = ssid_ie_offset + 2 + bss_conf->ssid_len;
|
||||
|
||||
memcpy(probe_rsp_templ + ssid_ie_offset + 2 + bss_conf->ssid_len,
|
||||
ptr, probe_rsp_len - (ptr - probe_rsp_data));
|
||||
templ_len += probe_rsp_len - (ptr - probe_rsp_data);
|
||||
|
||||
return wl1271_cmd_template_set(wl,
|
||||
CMD_TEMPL_AP_PROBE_RESPONSE,
|
||||
probe_rsp_templ,
|
||||
templ_len, 0,
|
||||
rates);
|
||||
}
|
||||
|
||||
static int wl1271_bss_erp_info_changed(struct wl1271 *wl,
|
||||
struct ieee80211_bss_conf *bss_conf,
|
||||
u32 changed)
|
||||
|
@ -3201,11 +3257,14 @@ static int wl1271_bss_beacon_info_changed(struct wl1271 *wl,
|
|||
hdr = (struct ieee80211_hdr *) beacon->data;
|
||||
hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
|
||||
IEEE80211_STYPE_PROBE_RESP);
|
||||
|
||||
tmpl_id = is_ap ? CMD_TEMPL_AP_PROBE_RESPONSE :
|
||||
CMD_TEMPL_PROBE_RESPONSE;
|
||||
if (is_ap)
|
||||
ret = wl1271_ap_set_probe_resp_tmpl(wl,
|
||||
beacon->data,
|
||||
beacon->len,
|
||||
wl1271_tx_min_rate_get(wl));
|
||||
else
|
||||
ret = wl1271_cmd_template_set(wl,
|
||||
tmpl_id,
|
||||
CMD_TEMPL_PROBE_RESPONSE,
|
||||
beacon->data,
|
||||
beacon->len, 0,
|
||||
wl1271_tx_min_rate_get(wl));
|
||||
|
|
Loading…
Reference in a new issue