aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorOmer Dagan <omer.dagan@tandemg.com>2019-04-08 06:44:57 (GMT)
committerJouni Malinen <j@w1.fi>2019-04-22 19:08:07 (GMT)
commit95f556f3c77d32c46fb98437bf929ffe39a41ce8 (patch)
tree2c927fbc89a4cbf76a9b07cf3ef8d7fff4ed586b /src
parent9c951244185784066a50facf468ecd1905afdbe5 (diff)
downloadhostap-95f556f3c77d32c46fb98437bf929ffe39a41ce8.zip
hostap-95f556f3c77d32c46fb98437bf929ffe39a41ce8.tar.gz
hostap-95f556f3c77d32c46fb98437bf929ffe39a41ce8.tar.bz2
Make channel switch started event available over control interface
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>
Diffstat (limited to 'src')
-rw-r--r--src/ap/drv_callbacks.c19
-rw-r--r--src/ap/hostapd.h3
-rw-r--r--src/common/wpa_ctrl.h3
-rw-r--r--src/drivers/driver.h14
-rw-r--r--src/drivers/driver_common.c1
-rw-r--r--src/drivers/driver_nl80211_event.c22
6 files changed, 54 insertions, 8 deletions
diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c
index 8ddf754..58753e5 100644
--- a/src/ap/drv_callbacks.c
+++ b/src/ap/drv_callbacks.c
@@ -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)
diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h
index 790d377..0f76cd6 100644
--- a/src/ap/hostapd.h
+++ b/src/ap/hostapd.h
@@ -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);
diff --git a/src/common/wpa_ctrl.h b/src/common/wpa_ctrl.h
index f65077e..b24ae63 100644
--- a/src/common/wpa_ctrl.h
+++ b/src/common/wpa_ctrl.h
@@ -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 */
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index cb561ac..095bfd9 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -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;
@@ -4541,6 +4546,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
*
* This event can be used to request a WNM operation to be performed.
diff --git a/src/drivers/driver_common.c b/src/drivers/driver_common.c
index e55e6cd..b52e8ba 100644
--- a/src/drivers/driver_common.c
+++ b/src/drivers/driver_common.c
@@ -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);
diff --git a/src/drivers/driver_nl80211_event.c b/src/drivers/driver_nl80211_event.c
index ee7b4da..7abbafc 100644
--- a/src/drivers/driver_nl80211_event.c
+++ b/src/drivers/driver_nl80211_event.c
@@ -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],