hostapd: Move CSA parameters to hostapd_data
authorMichal Kazior <michal.kazior@tieto.com>
Fri, 27 Jun 2014 12:19:27 +0000 (14:19 +0200)
committerJouni Malinen <j@w1.fi>
Sat, 28 Jun 2014 08:02:39 +0000 (11:02 +0300)
This prepares CSA structure and logic in hostapd for multi-BSS channel
switching.

Signed-hostap: Michal Kazior <michal.kazior@tieto.com>

src/ap/beacon.c
src/ap/dfs.c
src/ap/drv_callbacks.c
src/ap/hostapd.c
src/ap/hostapd.h
src/drivers/driver_nl80211.c

index 73dffe2..b3b6149 100644 (file)
@@ -265,18 +265,18 @@ static u8 * hostapd_eid_csa(struct hostapd_data *hapd, u8 *eid)
 {
        u8 chan;
 
-       if (!hapd->iface->cs_freq_params.freq)
+       if (!hapd->cs_freq_params.freq)
                return eid;
 
-       if (ieee80211_freq_to_chan(hapd->iface->cs_freq_params.freq, &chan) ==
+       if (ieee80211_freq_to_chan(hapd->cs_freq_params.freq, &chan) ==
            NUM_HOSTAPD_MODES)
                return eid;
 
        *eid++ = WLAN_EID_CHANNEL_SWITCH;
        *eid++ = 3;
-       *eid++ = hapd->iface->cs_block_tx;
+       *eid++ = hapd->cs_block_tx;
        *eid++ = chan;
-       *eid++ = hapd->iface->cs_count;
+       *eid++ = hapd->cs_count;
 
        return eid;
 }
@@ -286,12 +286,12 @@ static u8 * hostapd_eid_secondary_channel(struct hostapd_data *hapd, u8 *eid)
 {
        u8 sec_ch;
 
-       if (!hapd->iface->cs_freq_params.sec_channel_offset)
+       if (!hapd->cs_freq_params.sec_channel_offset)
                return eid;
 
-       if (hapd->iface->cs_freq_params.sec_channel_offset == -1)
+       if (hapd->cs_freq_params.sec_channel_offset == -1)
                sec_ch = HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW;
-       else if (hapd->iface->cs_freq_params.sec_channel_offset == 1)
+       else if (hapd->cs_freq_params.sec_channel_offset == 1)
                sec_ch = HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE;
        else
                return eid;
@@ -409,7 +409,7 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
        pos = hostapd_eid_roaming_consortium(hapd, pos);
 
        pos = hostapd_add_csa_elems(hapd, pos, (u8 *)resp,
-                                   &hapd->iface->cs_c_off_proberesp);
+                                   &hapd->cs_c_off_proberesp);
 #ifdef CONFIG_IEEE80211AC
        pos = hostapd_eid_vht_capabilities(hapd, pos);
        pos = hostapd_eid_vht_operation(hapd, pos);
@@ -824,7 +824,7 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
        tailpos = hostapd_eid_adv_proto(hapd, tailpos);
        tailpos = hostapd_eid_roaming_consortium(hapd, tailpos);
        tailpos = hostapd_add_csa_elems(hapd, tailpos, tail,
-                                       &hapd->iface->cs_c_off_beacon);
+                                       &hapd->cs_c_off_beacon);
 #ifdef CONFIG_IEEE80211AC
        tailpos = hostapd_eid_vht_capabilities(hapd, tailpos);
        tailpos = hostapd_eid_vht_operation(hapd, tailpos);
@@ -957,7 +957,7 @@ int ieee802_11_set_beacon(struct hostapd_data *hapd)
        struct wpabuf *beacon, *proberesp, *assocresp;
        int res, ret = -1;
 
-       if (hapd->iface->csa_in_progress) {
+       if (hapd->csa_in_progress) {
                wpa_printf(MSG_ERROR, "Cannot set beacons during CSA period");
                return -1;
        }
index c30f6d6..9f42a77 100644 (file)
@@ -756,6 +756,16 @@ static int hostapd_dfs_start_channel_switch_cac(struct hostapd_iface *iface)
 }
 
 
+static int hostapd_csa_in_progress(struct hostapd_iface *iface)
+{
+       unsigned int i;
+       for (i = 0; i < iface->num_bss; i++)
+               if (iface->bss[i]->csa_in_progress)
+                       return 1;
+       return 0;
+}
+
+
 static int hostapd_dfs_start_channel_switch(struct hostapd_iface *iface)
 {
        struct hostapd_channel_data *channel;
@@ -769,10 +779,10 @@ static int hostapd_dfs_start_channel_switch(struct hostapd_iface *iface)
 
        wpa_printf(MSG_DEBUG, "%s called (CAC active: %s, CSA active: %s)",
                   __func__, iface->cac_started ? "yes" : "no",
-                  iface->csa_in_progress ? "yes" : "no");
+                  hostapd_csa_in_progress(iface) ? "yes" : "no");
 
        /* Check if CSA in progress */
-       if (iface->csa_in_progress)
+       if (hostapd_csa_in_progress(iface))
                return 0;
 
        /* Check if active CAC */
index fb095ef..ac5732c 100644 (file)
@@ -489,9 +489,10 @@ void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht,
        hapd->iconf->vht_oper_centr_freq_seg0_idx = seg0_idx;
        hapd->iconf->vht_oper_centr_freq_seg1_idx = seg1_idx;
 
-       if (hapd->iface->csa_in_progress &&
-           freq == hapd->iface->cs_freq_params.freq) {
+       if (hapd->csa_in_progress &&
+           freq == hapd->cs_freq_params.freq) {
                hostapd_cleanup_cs_params(hapd);
+               ieee802_11_set_beacon(hapd);
 
                wpa_msg(hapd->msg_ctx, MSG_INFO, AP_CSA_FINISHED "freq=%d",
                        freq);
index 4e09fa3..4c648b1 100644 (file)
@@ -2175,13 +2175,12 @@ static void free_beacon_data(struct beacon_data *beacon)
 }
 
 
-static int hostapd_build_beacon_data(struct hostapd_iface *iface,
+static int hostapd_build_beacon_data(struct hostapd_data *hapd,
                                     struct beacon_data *beacon)
 {
        struct wpabuf *beacon_extra, *proberesp_extra, *assocresp_extra;
        struct wpa_driver_ap_params params;
        int ret;
-       struct hostapd_data *hapd = iface->bss[0];
 
        os_memset(beacon, 0, sizeof(*beacon));
        ret = ieee802_11_build_ap_params(hapd, &params);
@@ -2305,14 +2304,15 @@ static int hostapd_change_config_freq(struct hostapd_data *hapd,
 }
 
 
-static int hostapd_fill_csa_settings(struct hostapd_iface *iface,
+static int hostapd_fill_csa_settings(struct hostapd_data *hapd,
                                     struct csa_settings *settings)
 {
+       struct hostapd_iface *iface = hapd->iface;
        struct hostapd_freq_params old_freq;
        int ret;
 
        os_memset(&old_freq, 0, sizeof(old_freq));
-       if (!iface || !iface->freq || iface->csa_in_progress)
+       if (!iface || !iface->freq || hapd->csa_in_progress)
                return -1;
 
        ret = hostapd_change_config_freq(iface->bss[0], iface->conf,
@@ -2321,7 +2321,7 @@ static int hostapd_fill_csa_settings(struct hostapd_iface *iface,
        if (ret)
                return ret;
 
-       ret = hostapd_build_beacon_data(iface, &settings->beacon_after);
+       ret = hostapd_build_beacon_data(hapd, &settings->beacon_after);
 
        /* change back the configuration */
        hostapd_change_config_freq(iface->bss[0], iface->conf,
@@ -2331,18 +2331,18 @@ static int hostapd_fill_csa_settings(struct hostapd_iface *iface,
                return ret;
 
        /* set channel switch parameters for csa ie */
-       iface->cs_freq_params = settings->freq_params;
-       iface->cs_count = settings->cs_count;
-       iface->cs_block_tx = settings->block_tx;
+       hapd->cs_freq_params = settings->freq_params;
+       hapd->cs_count = settings->cs_count;
+       hapd->cs_block_tx = settings->block_tx;
 
-       ret = hostapd_build_beacon_data(iface, &settings->beacon_csa);
+       ret = hostapd_build_beacon_data(hapd, &settings->beacon_csa);
        if (ret) {
                free_beacon_data(&settings->beacon_after);
                return ret;
        }
 
-       settings->counter_offset_beacon = iface->cs_c_off_beacon;
-       settings->counter_offset_presp = iface->cs_c_off_proberesp;
+       settings->counter_offset_beacon = hapd->cs_c_off_beacon;
+       settings->counter_offset_presp = hapd->cs_c_off_proberesp;
 
        return 0;
 }
@@ -2350,13 +2350,12 @@ static int hostapd_fill_csa_settings(struct hostapd_iface *iface,
 
 void hostapd_cleanup_cs_params(struct hostapd_data *hapd)
 {
-       os_memset(&hapd->iface->cs_freq_params, 0,
-                 sizeof(hapd->iface->cs_freq_params));
-       hapd->iface->cs_count = 0;
-       hapd->iface->cs_block_tx = 0;
-       hapd->iface->cs_c_off_beacon = 0;
-       hapd->iface->cs_c_off_proberesp = 0;
-       hapd->iface->csa_in_progress = 0;
+       os_memset(&hapd->cs_freq_params, 0, sizeof(hapd->cs_freq_params));
+       hapd->cs_count = 0;
+       hapd->cs_block_tx = 0;
+       hapd->cs_c_off_beacon = 0;
+       hapd->cs_c_off_proberesp = 0;
+       hapd->csa_in_progress = 0;
 }
 
 
@@ -2364,7 +2363,7 @@ int hostapd_switch_channel(struct hostapd_data *hapd,
                           struct csa_settings *settings)
 {
        int ret;
-       ret = hostapd_fill_csa_settings(hapd->iface, settings);
+       ret = hostapd_fill_csa_settings(hapd, settings);
        if (ret)
                return ret;
 
@@ -2378,7 +2377,7 @@ int hostapd_switch_channel(struct hostapd_data *hapd,
                return ret;
        }
 
-       hapd->iface->csa_in_progress = 1;
+       hapd->csa_in_progress = 1;
        return 0;
 }
 
index bd85c54..d413f7e 100644 (file)
@@ -210,6 +210,14 @@ struct hostapd_data {
                           size_t psk_len);
        void *new_psk_cb_ctx;
 
+       /* channel switch parameters */
+       struct hostapd_freq_params cs_freq_params;
+       u8 cs_count;
+       int cs_block_tx;
+       unsigned int cs_c_off_beacon;
+       unsigned int cs_c_off_proberesp;
+       int csa_in_progress;
+
 #ifdef CONFIG_P2P
        struct p2p_data *p2p;
        struct p2p_group *p2p_group;
@@ -343,14 +351,6 @@ struct hostapd_iface {
        /* lowest observed noise floor in dBm */
        s8 lowest_nf;
 
-       /* channel switch parameters */
-       struct hostapd_freq_params cs_freq_params;
-       u8 cs_count;
-       int cs_block_tx;
-       unsigned int cs_c_off_beacon;
-       unsigned int cs_c_off_proberesp;
-       int csa_in_progress;
-
        unsigned int dfs_cac_ms;
        struct os_reltime dfs_cac_start;
 
index c9fe8ef..4d5da94 100644 (file)
@@ -1680,7 +1680,7 @@ static void mlme_event_ch_switch(struct wpa_driver_nl80211_data *drv,
 
        bss->freq = data.ch_switch.freq;
 
-       wpa_supplicant_event(drv->ctx, EVENT_CH_SWITCH, &data);
+       wpa_supplicant_event(bss->ctx, EVENT_CH_SWITCH, &data);
 }
 
 
@@ -12118,7 +12118,7 @@ static int nl80211_switch_channel(void *priv, struct csa_settings *settings)
                return -ENOMEM;
 
        nl80211_cmd(drv, msg, 0, NL80211_CMD_CHANNEL_SWITCH);
-       NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
+       NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, bss->ifindex);
        NLA_PUT_U32(msg, NL80211_ATTR_CH_SWITCH_COUNT, settings->cs_count);
        ret = nl80211_put_freq_params(msg, &settings->freq_params);
        if (ret)