From b3e86cbb4f54d92eb4d145c62a7165067c6a7612 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 28 Jan 2020 16:27:53 +0100 Subject: [PATCH] hostapd: add back support for passing CSA events from sta/mesh to AP interfaces Fixes handling CSA when using AP+STA or AP+Mesh This change was accidentally dropped in commit 167028b75 ("hostapd: Update to version 2.9 (2019-08-08)") Signed-off-by: Felix Fietkau --- .../hostapd/patches/370-ap_sta_support.patch | 129 ++++++++++++++++++ 1 file changed, 129 insertions(+) diff --git a/package/network/services/hostapd/patches/370-ap_sta_support.patch b/package/network/services/hostapd/patches/370-ap_sta_support.patch index f8d4206529..a861ce4153 100644 --- a/package/network/services/hostapd/patches/370-ap_sta_support.patch +++ b/package/network/services/hostapd/patches/370-ap_sta_support.patch @@ -272,3 +272,132 @@ hapd->beacon_set_done = 1; if (ieee802_11_build_ap_params(hapd, ¶ms) < 0) +--- a/wpa_supplicant/events.c ++++ b/wpa_supplicant/events.c +@@ -4184,6 +4184,60 @@ static void wpas_event_assoc_reject(stru + } + + ++static void ++supplicant_ch_switch_started(struct wpa_supplicant *wpa_s, ++ union wpa_event_data *data) ++{ ++ char buf[256]; ++ size_t len = sizeof(buf); ++ char *cmd = NULL; ++ int width = 20; ++ int ret; ++ ++ if (!wpa_s->hostapd) ++ return; ++ ++ wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_CHANNEL_SWITCH ++ "count=%d freq=%d ht_enabled=%d ch_offset=%d ch_width=%s cf1=%d cf2=%d", ++ data->ch_switch.count, ++ 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); ++ ++ switch (data->ch_switch.ch_width) { ++ case CHAN_WIDTH_20_NOHT: ++ case CHAN_WIDTH_20: ++ width = 20; ++ break; ++ case CHAN_WIDTH_40: ++ width = 40; ++ break; ++ case CHAN_WIDTH_80: ++ width = 80; ++ break; ++ case CHAN_WIDTH_160: ++ case CHAN_WIDTH_80P80: ++ width = 160; ++ break; ++ } ++ ++ asprintf(&cmd, "CHAN_SWITCH %d %d sec_channel_offset=%d center_freq1=%d center_freq2=%d, bandwidth=%d auto-ht\n", ++ data->ch_switch.count - 1, ++ data->ch_switch.freq, ++ data->ch_switch.ch_offset, ++ data->ch_switch.cf1, ++ data->ch_switch.cf2, ++ width); ++ ret = wpa_ctrl_request(wpa_s->hostapd, cmd, os_strlen(cmd), buf, &len, NULL); ++ free(cmd); ++ ++ if (ret < 0) ++ wpa_printf(MSG_ERROR, "\nFailed to reload hostapd AP interfaces\n"); ++} ++ + void supplicant_event(void *ctx, enum wpa_event_type event, + union wpa_event_data *data) + { +@@ -4485,8 +4539,10 @@ void supplicant_event(void *ctx, enum wp + channel_width_to_string(data->ch_switch.ch_width), + data->ch_switch.cf1, + data->ch_switch.cf2); +- if (event == EVENT_CH_SWITCH_STARTED) ++ if (event == EVENT_CH_SWITCH_STARTED) { ++ supplicant_ch_switch_started(wpa_s, data); + break; ++ } + + wpa_s->assoc_freq = data->ch_switch.freq; + wpa_s->current_ssid->frequency = data->ch_switch.freq; +--- a/src/drivers/driver.h ++++ b/src/drivers/driver.h +@@ -5478,6 +5478,7 @@ union wpa_event_data { + + /** + * struct ch_switch ++ * @count: Count until channel switch activates + * @freq: Frequency of new channel in MHz + * @ht_enabled: Whether this is an HT channel + * @ch_offset: Secondary channel offset +@@ -5486,6 +5487,7 @@ union wpa_event_data { + * @cf2: Center frequency 2 + */ + struct ch_switch { ++ int count; + int freq; + int ht_enabled; + int ch_offset; +--- a/src/drivers/driver_nl80211_event.c ++++ b/src/drivers/driver_nl80211_event.c +@@ -536,7 +536,7 @@ static void mlme_event_ch_switch(struct + struct nlattr *ifindex, struct nlattr *freq, + struct nlattr *type, struct nlattr *bw, + struct nlattr *cf1, struct nlattr *cf2, +- int finished) ++ struct nlattr *count, int finished) + { + struct i802_bss *bss; + union wpa_event_data data; +@@ -595,6 +595,8 @@ static void mlme_event_ch_switch(struct + data.ch_switch.cf1 = nla_get_u32(cf1); + if (cf2) + data.ch_switch.cf2 = nla_get_u32(cf2); ++ if (count) ++ data.ch_switch.count = nla_get_u32(count); + + if (finished) + bss->freq = data.ch_switch.freq; +@@ -2544,6 +2546,7 @@ static void do_process_drv_event(struct + tb[NL80211_ATTR_CHANNEL_WIDTH], + tb[NL80211_ATTR_CENTER_FREQ1], + tb[NL80211_ATTR_CENTER_FREQ2], ++ tb[NL80211_ATTR_CH_SWITCH_COUNT], + 0); + break; + case NL80211_CMD_CH_SWITCH_NOTIFY: +@@ -2554,6 +2557,7 @@ static void do_process_drv_event(struct + tb[NL80211_ATTR_CHANNEL_WIDTH], + tb[NL80211_ATTR_CENTER_FREQ1], + tb[NL80211_ATTR_CENTER_FREQ2], ++ NULL, + 1); + break; + case NL80211_CMD_DISCONNECT: