]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
Make channel switch started event available over control interface
authorOmer Dagan <omer.dagan@tandemg.com>
Mon, 8 Apr 2019 06:44:57 +0000 (06:44 +0000)
committerJouni Malinen <j@w1.fi>
Mon, 22 Apr 2019 19:08:07 +0000 (22:08 +0300)
This makes it easier to upper layer components to manage operating
channels in cases where the same radio is shared for both station and AP
mode virtual interfaces.

Signed-off-by: Omer Dagan <omer.dagan@tandemg.com>
src/ap/drv_callbacks.c
src/ap/hostapd.h
src/common/wpa_ctrl.h
src/drivers/driver.h
src/drivers/driver_common.c
src/drivers/driver_nl80211_event.c
wpa_supplicant/ap.c
wpa_supplicant/ap.h
wpa_supplicant/events.c

index 8ddf754f60a740b0638766ebf49f71e92a91cebd..58753e55ae1b18d90f189c144b3b0fc86987f2bf 100644 (file)
@@ -772,7 +772,8 @@ void hostapd_event_sta_opmode_changed(struct hostapd_data *hapd, const u8 *addr,
 
 
 void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht,
-                            int offset, int width, int cf1, int cf2)
+                            int offset, int width, int cf1, int cf2,
+                            int finished)
 {
        /* TODO: If OCV is enabled deauth STAs that don't perform a SA Query */
 
@@ -783,7 +784,8 @@ void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht,
 
        hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
                       HOSTAPD_LEVEL_INFO,
-                      "driver had channel switch: freq=%d, ht=%d, vht_ch=0x%x, offset=%d, width=%d (%s), cf1=%d, cf2=%d",
+                      "driver %s channel switch: freq=%d, ht=%d, vht_ch=0x%x, offset=%d, width=%d (%s), cf1=%d, cf2=%d",
+                      finished ? "had" : "starting",
                       freq, ht, hapd->iconf->ch_switch_vht_config, offset,
                       width, channel_width_to_string(width), cf1, cf2);
 
@@ -851,6 +853,15 @@ void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht,
        is_dfs = ieee80211_is_dfs(freq, hapd->iface->hw_features,
                                  hapd->iface->num_hw_features);
 
+       wpa_msg(hapd->msg_ctx, MSG_INFO,
+               "%sfreq=%d ht_enabled=%d ch_offset=%d ch_width=%s cf1=%d cf2=%d dfs=%d",
+               finished ? WPA_EVENT_CHANNEL_SWITCH :
+               WPA_EVENT_CHANNEL_SWITCH_STARTED,
+               freq, ht, offset, channel_width_to_string(width),
+               cf1, cf2, is_dfs);
+       if (!finished)
+               return;
+
        if (hapd->csa_in_progress &&
            freq == hapd->cs_freq_params.freq) {
                hostapd_cleanup_cs_params(hapd);
@@ -1689,6 +1700,7 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
        case EVENT_AUTH:
                hostapd_notif_auth(hapd, &data->auth);
                break;
+       case EVENT_CH_SWITCH_STARTED:
        case EVENT_CH_SWITCH:
                if (!data)
                        break;
@@ -1697,7 +1709,8 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
                                        data->ch_switch.ch_offset,
                                        data->ch_switch.ch_width,
                                        data->ch_switch.cf1,
-                                       data->ch_switch.cf2);
+                                       data->ch_switch.cf2,
+                                       event == EVENT_CH_SWITCH);
                break;
        case EVENT_CONNECT_FAILED_REASON:
                if (!data)
index 790d3775487020f96ceee3241fdf9e525ce7a77d..0f76cd6c8f2f324c05ca3e7feae9f501147add62 100644 (file)
@@ -607,7 +607,8 @@ int hostapd_probe_req_rx(struct hostapd_data *hapd, const u8 *sa, const u8 *da,
                         const u8 *bssid, const u8 *ie, size_t ie_len,
                         int ssi_signal);
 void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht,
-                            int offset, int width, int cf1, int cf2);
+                            int offset, int width, int cf1, int cf2,
+                            int finished);
 struct survey_results;
 void hostapd_event_get_survey(struct hostapd_iface *iface,
                              struct survey_results *survey_results);
index f65077e04282e8d9783b4f7b2fe05a2378696677..b24ae63e59ea1ba1a604efb764a40b2f19603ca5 100644 (file)
@@ -87,6 +87,9 @@ extern "C" {
 #define WPA_EVENT_BEACON_LOSS "CTRL-EVENT-BEACON-LOSS "
 /** Regulatory domain channel */
 #define WPA_EVENT_REGDOM_CHANGE "CTRL-EVENT-REGDOM-CHANGE "
+/** Channel switch started (followed by freq=<MHz> and other channel parameters)
+ */
+#define WPA_EVENT_CHANNEL_SWITCH_STARTED "CTRL-EVENT-STARTED-CHANNEL-SWITCH "
 /** Channel switch (followed by freq=<MHz> and other channel parameters) */
 #define WPA_EVENT_CHANNEL_SWITCH "CTRL-EVENT-CHANNEL-SWITCH "
 /** SAE authentication failed due to unknown password identifier */
index cb561acba1aaaa1664c11610230ef4397a52f51a..095bfd96ae5d6ce8bb019e45b67f5bedfc3d1620 100644 (file)
@@ -1122,6 +1122,11 @@ enum hide_ssid {
        HIDDEN_SSID_ZERO_CONTENTS
 };
 
+enum ch_switch_state {
+       CH_SW_STARTED,
+       CH_SW_FINISHED
+};
+
 struct wowlan_triggers {
        u8 any;
        u8 disconnect;
@@ -4540,6 +4545,15 @@ enum wpa_event_type {
         * */
        EVENT_CH_SWITCH,
 
+       /**
+        * EVENT_CH_SWITCH_STARTED - AP or GO started to switch channels
+        *
+        * This is a pre-switch event indicating the shortly following switch
+        * of operating channels.
+        *
+        * Described in wpa_event_data.ch_switch
+        */
+       EVENT_CH_SWITCH_STARTED,
        /**
         * EVENT_WNM - Request WNM operation
         *
index e55e6cd2b795a2d9716ec85aa4bceea8c9e1b425..b52e8baba7ce1fc84b10c08236547fa4b6c799b1 100644 (file)
@@ -67,6 +67,7 @@ const char * event_to_string(enum wpa_event_type event)
        E2S(DRIVER_CLIENT_POLL_OK);
        E2S(EAPOL_TX_STATUS);
        E2S(CH_SWITCH);
+       E2S(CH_SWITCH_STARTED);
        E2S(WNM);
        E2S(CONNECT_FAILED_REASON);
        E2S(DFS_RADAR_DETECTED);
index ee7b4da38d8705675f2bbfc0c073ab3e5cb3424c..7abbafcd826b0853fe594719c68d6e8f27827885 100644 (file)
@@ -534,7 +534,8 @@ static int calculate_chan_offset(int width, int freq, int cf1, int cf2)
 static void mlme_event_ch_switch(struct wpa_driver_nl80211_data *drv,
                                 struct nlattr *ifindex, struct nlattr *freq,
                                 struct nlattr *type, struct nlattr *bw,
-                                struct nlattr *cf1, struct nlattr *cf2)
+                                struct nlattr *cf1, struct nlattr *cf2,
+                                int finished)
 {
        struct i802_bss *bss;
        union wpa_event_data data;
@@ -542,7 +543,8 @@ static void mlme_event_ch_switch(struct wpa_driver_nl80211_data *drv,
        int chan_offset = 0;
        int ifidx;
 
-       wpa_printf(MSG_DEBUG, "nl80211: Channel switch event");
+       wpa_printf(MSG_DEBUG, "nl80211: Channel switch%s event",
+                  finished ? "" : " started");
 
        if (!freq)
                return;
@@ -596,7 +598,8 @@ static void mlme_event_ch_switch(struct wpa_driver_nl80211_data *drv,
        bss->freq = data.ch_switch.freq;
        drv->assoc_freq = data.ch_switch.freq;
 
-       wpa_supplicant_event(bss->ctx, EVENT_CH_SWITCH, &data);
+       wpa_supplicant_event(bss->ctx, finished ?
+                            EVENT_CH_SWITCH : EVENT_CH_SWITCH_STARTED, &data);
 }
 
 
@@ -2508,6 +2511,16 @@ static void do_process_drv_event(struct i802_bss *bss, int cmd,
                                   tb[NL80211_ATTR_PMK],
                                   tb[NL80211_ATTR_PMKID]);
                break;
+       case NL80211_CMD_CH_SWITCH_STARTED_NOTIFY:
+               mlme_event_ch_switch(drv,
+                                    tb[NL80211_ATTR_IFINDEX],
+                                    tb[NL80211_ATTR_WIPHY_FREQ],
+                                    tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE],
+                                    tb[NL80211_ATTR_CHANNEL_WIDTH],
+                                    tb[NL80211_ATTR_CENTER_FREQ1],
+                                    tb[NL80211_ATTR_CENTER_FREQ2],
+                                    0);
+               break;
        case NL80211_CMD_CH_SWITCH_NOTIFY:
                mlme_event_ch_switch(drv,
                                     tb[NL80211_ATTR_IFINDEX],
@@ -2515,7 +2528,8 @@ static void do_process_drv_event(struct i802_bss *bss, int cmd,
                                     tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE],
                                     tb[NL80211_ATTR_CHANNEL_WIDTH],
                                     tb[NL80211_ATTR_CENTER_FREQ1],
-                                    tb[NL80211_ATTR_CENTER_FREQ2]);
+                                    tb[NL80211_ATTR_CENTER_FREQ2],
+                                    1);
                break;
        case NL80211_CMD_DISCONNECT:
                mlme_event_disconnect(drv, tb[NL80211_ATTR_REASON_CODE],
index 4e191694296bbb7d7b2ae814d84e29cd7e775544..7a3ec30677b2e3eadcc158ecd1b4e28890268d45 100644 (file)
@@ -1387,7 +1387,7 @@ int ap_ctrl_iface_chanswitch(struct wpa_supplicant *wpa_s, const char *pos)
 
 
 void wpas_ap_ch_switch(struct wpa_supplicant *wpa_s, int freq, int ht,
-                      int offset, int width, int cf1, int cf2)
+                      int offset, int width, int cf1, int cf2, int finished)
 {
        struct hostapd_iface *iface = wpa_s->ap_iface;
 
@@ -1399,7 +1399,7 @@ void wpas_ap_ch_switch(struct wpa_supplicant *wpa_s, int freq, int ht,
        if (wpa_s->current_ssid)
                wpa_s->current_ssid->frequency = freq;
        hostapd_event_ch_switch(iface->bss[0], freq, ht,
-                               offset, width, cf1, cf2);
+                               offset, width, cf1, cf2, finished);
 }
 
 
index 447b551863a3d22722103ee53d9b7bdb3a86d83b..6c6e94cdf6a28d60da3a7912ce898de9bf2f5b1e 100644 (file)
@@ -54,7 +54,7 @@ int ap_switch_channel(struct wpa_supplicant *wpa_s,
                      struct csa_settings *settings);
 int ap_ctrl_iface_chanswitch(struct wpa_supplicant *wpa_s, const char *txtaddr);
 void wpas_ap_ch_switch(struct wpa_supplicant *wpa_s, int freq, int ht,
-                      int offset, int width, int cf1, int cf2);
+                      int offset, int width, int cf1, int cf2, int finished);
 struct wpabuf * wpas_ap_wps_nfc_config_token(struct wpa_supplicant *wpa_s,
                                             int ndef);
 #ifdef CONFIG_AP
index 3ff8ba92d89691f845357897d05b3cd825479116..cab0a6d9ace388734bb68b1f76bf481b3d5b61e8 100644 (file)
@@ -4462,18 +4462,24 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
                                       data->rx_from_unknown.wds);
                break;
 #endif /* CONFIG_AP */
+
+       case EVENT_CH_SWITCH_STARTED:
        case EVENT_CH_SWITCH:
                if (!data || !wpa_s->current_ssid)
                        break;
 
-               wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_CHANNEL_SWITCH
-                       "freq=%d ht_enabled=%d ch_offset=%d ch_width=%s cf1=%d cf2=%d",
+               wpa_msg(wpa_s, MSG_INFO,
+                       "%sfreq=%d ht_enabled=%d ch_offset=%d ch_width=%s cf1=%d cf2=%d",
+                       event == EVENT_CH_SWITCH ? WPA_EVENT_CHANNEL_SWITCH :
+                       WPA_EVENT_CHANNEL_SWITCH_STARTED,
                        data->ch_switch.freq,
                        data->ch_switch.ht_enabled,
                        data->ch_switch.ch_offset,
                        channel_width_to_string(data->ch_switch.ch_width),
                        data->ch_switch.cf1,
                        data->ch_switch.cf2);
+               if (event == EVENT_CH_SWITCH_STARTED)
+                       break;
 
                wpa_s->assoc_freq = data->ch_switch.freq;
                wpa_s->current_ssid->frequency = data->ch_switch.freq;
@@ -4489,7 +4495,8 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
                                          data->ch_switch.ch_offset,
                                          data->ch_switch.ch_width,
                                          data->ch_switch.cf1,
-                                         data->ch_switch.cf2);
+                                         data->ch_switch.cf2,
+                                         1);
                }
 #endif /* CONFIG_AP */