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>
This commit is contained in:
parent
9c95124418
commit
95f556f3c7
9 changed files with 67 additions and 14 deletions
|
@ -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,
|
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 */
|
/* 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_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
|
||||||
HOSTAPD_LEVEL_INFO,
|
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,
|
freq, ht, hapd->iconf->ch_switch_vht_config, offset,
|
||||||
width, channel_width_to_string(width), cf1, cf2);
|
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,
|
is_dfs = ieee80211_is_dfs(freq, hapd->iface->hw_features,
|
||||||
hapd->iface->num_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 &&
|
if (hapd->csa_in_progress &&
|
||||||
freq == hapd->cs_freq_params.freq) {
|
freq == hapd->cs_freq_params.freq) {
|
||||||
hostapd_cleanup_cs_params(hapd);
|
hostapd_cleanup_cs_params(hapd);
|
||||||
|
@ -1689,6 +1700,7 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
|
||||||
case EVENT_AUTH:
|
case EVENT_AUTH:
|
||||||
hostapd_notif_auth(hapd, &data->auth);
|
hostapd_notif_auth(hapd, &data->auth);
|
||||||
break;
|
break;
|
||||||
|
case EVENT_CH_SWITCH_STARTED:
|
||||||
case EVENT_CH_SWITCH:
|
case EVENT_CH_SWITCH:
|
||||||
if (!data)
|
if (!data)
|
||||||
break;
|
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_offset,
|
||||||
data->ch_switch.ch_width,
|
data->ch_switch.ch_width,
|
||||||
data->ch_switch.cf1,
|
data->ch_switch.cf1,
|
||||||
data->ch_switch.cf2);
|
data->ch_switch.cf2,
|
||||||
|
event == EVENT_CH_SWITCH);
|
||||||
break;
|
break;
|
||||||
case EVENT_CONNECT_FAILED_REASON:
|
case EVENT_CONNECT_FAILED_REASON:
|
||||||
if (!data)
|
if (!data)
|
||||||
|
|
|
@ -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,
|
const u8 *bssid, const u8 *ie, size_t ie_len,
|
||||||
int ssi_signal);
|
int ssi_signal);
|
||||||
void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht,
|
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;
|
struct survey_results;
|
||||||
void hostapd_event_get_survey(struct hostapd_iface *iface,
|
void hostapd_event_get_survey(struct hostapd_iface *iface,
|
||||||
struct survey_results *survey_results);
|
struct survey_results *survey_results);
|
||||||
|
|
|
@ -87,6 +87,9 @@ extern "C" {
|
||||||
#define WPA_EVENT_BEACON_LOSS "CTRL-EVENT-BEACON-LOSS "
|
#define WPA_EVENT_BEACON_LOSS "CTRL-EVENT-BEACON-LOSS "
|
||||||
/** Regulatory domain channel */
|
/** Regulatory domain channel */
|
||||||
#define WPA_EVENT_REGDOM_CHANGE "CTRL-EVENT-REGDOM-CHANGE "
|
#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) */
|
/** Channel switch (followed by freq=<MHz> and other channel parameters) */
|
||||||
#define WPA_EVENT_CHANNEL_SWITCH "CTRL-EVENT-CHANNEL-SWITCH "
|
#define WPA_EVENT_CHANNEL_SWITCH "CTRL-EVENT-CHANNEL-SWITCH "
|
||||||
/** SAE authentication failed due to unknown password identifier */
|
/** SAE authentication failed due to unknown password identifier */
|
||||||
|
|
|
@ -1122,6 +1122,11 @@ enum hide_ssid {
|
||||||
HIDDEN_SSID_ZERO_CONTENTS
|
HIDDEN_SSID_ZERO_CONTENTS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum ch_switch_state {
|
||||||
|
CH_SW_STARTED,
|
||||||
|
CH_SW_FINISHED
|
||||||
|
};
|
||||||
|
|
||||||
struct wowlan_triggers {
|
struct wowlan_triggers {
|
||||||
u8 any;
|
u8 any;
|
||||||
u8 disconnect;
|
u8 disconnect;
|
||||||
|
@ -4540,6 +4545,15 @@ enum wpa_event_type {
|
||||||
* */
|
* */
|
||||||
EVENT_CH_SWITCH,
|
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
|
* EVENT_WNM - Request WNM operation
|
||||||
*
|
*
|
||||||
|
|
|
@ -67,6 +67,7 @@ const char * event_to_string(enum wpa_event_type event)
|
||||||
E2S(DRIVER_CLIENT_POLL_OK);
|
E2S(DRIVER_CLIENT_POLL_OK);
|
||||||
E2S(EAPOL_TX_STATUS);
|
E2S(EAPOL_TX_STATUS);
|
||||||
E2S(CH_SWITCH);
|
E2S(CH_SWITCH);
|
||||||
|
E2S(CH_SWITCH_STARTED);
|
||||||
E2S(WNM);
|
E2S(WNM);
|
||||||
E2S(CONNECT_FAILED_REASON);
|
E2S(CONNECT_FAILED_REASON);
|
||||||
E2S(DFS_RADAR_DETECTED);
|
E2S(DFS_RADAR_DETECTED);
|
||||||
|
|
|
@ -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,
|
static void mlme_event_ch_switch(struct wpa_driver_nl80211_data *drv,
|
||||||
struct nlattr *ifindex, struct nlattr *freq,
|
struct nlattr *ifindex, struct nlattr *freq,
|
||||||
struct nlattr *type, struct nlattr *bw,
|
struct nlattr *type, struct nlattr *bw,
|
||||||
struct nlattr *cf1, struct nlattr *cf2)
|
struct nlattr *cf1, struct nlattr *cf2,
|
||||||
|
int finished)
|
||||||
{
|
{
|
||||||
struct i802_bss *bss;
|
struct i802_bss *bss;
|
||||||
union wpa_event_data data;
|
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 chan_offset = 0;
|
||||||
int ifidx;
|
int ifidx;
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "nl80211: Channel switch event");
|
wpa_printf(MSG_DEBUG, "nl80211: Channel switch%s event",
|
||||||
|
finished ? "" : " started");
|
||||||
|
|
||||||
if (!freq)
|
if (!freq)
|
||||||
return;
|
return;
|
||||||
|
@ -596,7 +598,8 @@ static void mlme_event_ch_switch(struct wpa_driver_nl80211_data *drv,
|
||||||
bss->freq = data.ch_switch.freq;
|
bss->freq = data.ch_switch.freq;
|
||||||
drv->assoc_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_PMK],
|
||||||
tb[NL80211_ATTR_PMKID]);
|
tb[NL80211_ATTR_PMKID]);
|
||||||
break;
|
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:
|
case NL80211_CMD_CH_SWITCH_NOTIFY:
|
||||||
mlme_event_ch_switch(drv,
|
mlme_event_ch_switch(drv,
|
||||||
tb[NL80211_ATTR_IFINDEX],
|
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_WIPHY_CHANNEL_TYPE],
|
||||||
tb[NL80211_ATTR_CHANNEL_WIDTH],
|
tb[NL80211_ATTR_CHANNEL_WIDTH],
|
||||||
tb[NL80211_ATTR_CENTER_FREQ1],
|
tb[NL80211_ATTR_CENTER_FREQ1],
|
||||||
tb[NL80211_ATTR_CENTER_FREQ2]);
|
tb[NL80211_ATTR_CENTER_FREQ2],
|
||||||
|
1);
|
||||||
break;
|
break;
|
||||||
case NL80211_CMD_DISCONNECT:
|
case NL80211_CMD_DISCONNECT:
|
||||||
mlme_event_disconnect(drv, tb[NL80211_ATTR_REASON_CODE],
|
mlme_event_disconnect(drv, tb[NL80211_ATTR_REASON_CODE],
|
||||||
|
|
|
@ -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,
|
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;
|
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)
|
if (wpa_s->current_ssid)
|
||||||
wpa_s->current_ssid->frequency = freq;
|
wpa_s->current_ssid->frequency = freq;
|
||||||
hostapd_event_ch_switch(iface->bss[0], freq, ht,
|
hostapd_event_ch_switch(iface->bss[0], freq, ht,
|
||||||
offset, width, cf1, cf2);
|
offset, width, cf1, cf2, finished);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,7 @@ int ap_switch_channel(struct wpa_supplicant *wpa_s,
|
||||||
struct csa_settings *settings);
|
struct csa_settings *settings);
|
||||||
int ap_ctrl_iface_chanswitch(struct wpa_supplicant *wpa_s, const char *txtaddr);
|
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,
|
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,
|
struct wpabuf * wpas_ap_wps_nfc_config_token(struct wpa_supplicant *wpa_s,
|
||||||
int ndef);
|
int ndef);
|
||||||
#ifdef CONFIG_AP
|
#ifdef CONFIG_AP
|
||||||
|
|
|
@ -4462,18 +4462,24 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
|
||||||
data->rx_from_unknown.wds);
|
data->rx_from_unknown.wds);
|
||||||
break;
|
break;
|
||||||
#endif /* CONFIG_AP */
|
#endif /* CONFIG_AP */
|
||||||
|
|
||||||
|
case EVENT_CH_SWITCH_STARTED:
|
||||||
case EVENT_CH_SWITCH:
|
case EVENT_CH_SWITCH:
|
||||||
if (!data || !wpa_s->current_ssid)
|
if (!data || !wpa_s->current_ssid)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_CHANNEL_SWITCH
|
wpa_msg(wpa_s, MSG_INFO,
|
||||||
"freq=%d ht_enabled=%d ch_offset=%d ch_width=%s cf1=%d cf2=%d",
|
"%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.freq,
|
||||||
data->ch_switch.ht_enabled,
|
data->ch_switch.ht_enabled,
|
||||||
data->ch_switch.ch_offset,
|
data->ch_switch.ch_offset,
|
||||||
channel_width_to_string(data->ch_switch.ch_width),
|
channel_width_to_string(data->ch_switch.ch_width),
|
||||||
data->ch_switch.cf1,
|
data->ch_switch.cf1,
|
||||||
data->ch_switch.cf2);
|
data->ch_switch.cf2);
|
||||||
|
if (event == EVENT_CH_SWITCH_STARTED)
|
||||||
|
break;
|
||||||
|
|
||||||
wpa_s->assoc_freq = data->ch_switch.freq;
|
wpa_s->assoc_freq = data->ch_switch.freq;
|
||||||
wpa_s->current_ssid->frequency = 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_offset,
|
||||||
data->ch_switch.ch_width,
|
data->ch_switch.ch_width,
|
||||||
data->ch_switch.cf1,
|
data->ch_switch.cf1,
|
||||||
data->ch_switch.cf2);
|
data->ch_switch.cf2,
|
||||||
|
1);
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_AP */
|
#endif /* CONFIG_AP */
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue