aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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
-rw-r--r--wpa_supplicant/ap.c4
-rw-r--r--wpa_supplicant/ap.h2
-rw-r--r--wpa_supplicant/events.c13
9 files changed, 67 insertions, 14 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],
diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c
index 4e19169..7a3ec30 100644
--- a/wpa_supplicant/ap.c
+++ b/wpa_supplicant/ap.c
@@ -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);
}
diff --git a/wpa_supplicant/ap.h b/wpa_supplicant/ap.h
index 447b551..6c6e94c 100644
--- a/wpa_supplicant/ap.h
+++ b/wpa_supplicant/ap.h
@@ -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
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 3ff8ba9..cab0a6d 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -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 */