From ae6b5815cd01864ad10e7d26b3565b2af3aa938c Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 28 Jan 2019 21:35:25 +0100 Subject: [PATCH] hostapd: add support for passing CSA events from sta/mesh to AP interfaces Fixes handling CSA when using AP+STA or AP+Mesh Signed-off-by: Felix Fietkau --- .../hostapd/patches/370-ap_sta_support.patch | 181 ++++++++++++++++++ .../patches/380-disable_ctrl_iface_mib.patch | 4 +- 2 files changed, 183 insertions(+), 2 deletions(-) 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 ecb9460e95..d93984a172 100644 --- a/package/network/services/hostapd/patches/370-ap_sta_support.patch +++ b/package/network/services/hostapd/patches/370-ap_sta_support.patch @@ -244,3 +244,184 @@ char *confname; char *confanother; +--- a/hostapd/ctrl_iface.c ++++ b/hostapd/ctrl_iface.c +@@ -2328,6 +2328,11 @@ static int hostapd_ctrl_iface_chan_switc + if (ret) + return ret; + ++ if (os_strstr(pos, " auto-ht")) { ++ settings.freq_params.ht_enabled = iface->conf->ieee80211n; ++ settings.freq_params.vht_enabled = iface->conf->ieee80211ac; ++ } ++ + for (i = 0; i < iface->num_bss; i++) { + + /* Save CHAN_SWITCH VHT config */ +--- a/src/ap/beacon.c ++++ b/src/ap/beacon.c +@@ -1381,11 +1381,6 @@ int ieee802_11_set_beacon(struct hostapd + struct wpabuf *beacon, *proberesp, *assocresp; + int res, ret = -1; + +- if (hapd->csa_in_progress) { +- wpa_printf(MSG_ERROR, "Cannot set beacons during CSA period"); +- return -1; +- } +- + hapd->beacon_set_done = 1; + + if (ieee802_11_build_ap_params(hapd, ¶ms) < 0) +--- a/src/drivers/driver.h ++++ b/src/drivers/driver.h +@@ -4469,6 +4469,13 @@ enum wpa_event_type { + EVENT_CH_SWITCH, + + /** ++ * EVENT_CH_SWITCH - AP or GO will switch channels soon ++ * ++ * 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. +@@ -5306,6 +5313,7 @@ union wpa_event_data { + + /** + * struct ch_switch ++ * @count: countdown until channel switch + * @freq: Frequency of new channel in MHz + * @ht_enabled: Whether this is an HT channel + * @ch_offset: Secondary channel offset +@@ -5314,6 +5322,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 +@@ -526,7 +526,8 @@ static int calculate_chan_offset(int wid + 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, ++ struct nlattr *count) + { + struct i802_bss *bss; + union wpa_event_data data; +@@ -584,11 +585,15 @@ 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); + + 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, ++ count ? EVENT_CH_SWITCH_STARTED : EVENT_CH_SWITCH, ++ &data); + } + + +@@ -2446,6 +2451,7 @@ static void do_process_drv_event(struct + tb[NL80211_ATTR_PMK], + tb[NL80211_ATTR_PMKID]); + break; ++ case NL80211_CMD_CH_SWITCH_STARTED_NOTIFY: + case NL80211_CMD_CH_SWITCH_NOTIFY: + mlme_event_ch_switch(drv, + tb[NL80211_ATTR_IFINDEX], +@@ -2453,7 +2459,8 @@ static void do_process_drv_event(struct + 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], ++ tb[NL80211_ATTR_CH_SWITCH_COUNT]); + break; + case NL80211_CMD_DISCONNECT: + mlme_event_disconnect(drv, tb[NL80211_ATTR_REASON_CODE], +--- a/wpa_supplicant/events.c ++++ b/wpa_supplicant/events.c +@@ -4026,6 +4026,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) + { +@@ -4309,6 +4363,10 @@ void supplicant_event(void *ctx, enum wp + data->rx_from_unknown.wds); + break; + #endif /* CONFIG_AP */ ++ case EVENT_CH_SWITCH_STARTED: ++ supplicant_ch_switch_started(wpa_s, data); ++ break; ++ + case EVENT_CH_SWITCH: + if (!data || !wpa_s->current_ssid) + break; diff --git a/package/network/services/hostapd/patches/380-disable_ctrl_iface_mib.patch b/package/network/services/hostapd/patches/380-disable_ctrl_iface_mib.patch index e978fbc689..2fe03340a8 100644 --- a/package/network/services/hostapd/patches/380-disable_ctrl_iface_mib.patch +++ b/package/network/services/hostapd/patches/380-disable_ctrl_iface_mib.patch @@ -12,7 +12,7 @@ else --- a/hostapd/ctrl_iface.c +++ b/hostapd/ctrl_iface.c -@@ -2907,6 +2907,7 @@ static int hostapd_ctrl_iface_receive_pr +@@ -2912,6 +2912,7 @@ static int hostapd_ctrl_iface_receive_pr reply_size); } else if (os_strcmp(buf, "STATUS-DRIVER") == 0) { reply_len = hostapd_drv_status(hapd, reply, reply_size); @@ -20,7 +20,7 @@ } else if (os_strcmp(buf, "MIB") == 0) { reply_len = ieee802_11_get_mib(hapd, reply, reply_size); if (reply_len >= 0) { -@@ -2948,6 +2949,7 @@ static int hostapd_ctrl_iface_receive_pr +@@ -2953,6 +2954,7 @@ static int hostapd_ctrl_iface_receive_pr } else if (os_strncmp(buf, "STA-NEXT ", 9) == 0) { reply_len = hostapd_ctrl_iface_sta_next(hapd, buf + 9, reply, reply_size); -- 2.30.2