void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht, int offset, int width, int cf1, int cf2) { #ifdef NEED_AP_MLME int channel, chwidth, is_dfs; u8 seg0_idx = 0, seg1_idx = 0; hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_INFO, "driver had channel switch: freq=%d, ht=%d, offset=%d, width=%d (%s), cf1=%d, cf2=%d", freq, ht, offset, width, channel_width_to_string(width), cf1, cf2); hapd->iface->freq = freq; channel = hostapd_hw_get_channel(hapd, freq); if (!channel) { hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_WARNING, "driver switched to bad channel!"); return; } switch (width) { case CHAN_WIDTH_80: chwidth = VHT_CHANWIDTH_80MHZ; break; case CHAN_WIDTH_80P80: chwidth = VHT_CHANWIDTH_80P80MHZ; break; case CHAN_WIDTH_160: chwidth = VHT_CHANWIDTH_160MHZ; break; case CHAN_WIDTH_20_NOHT: case CHAN_WIDTH_20: case CHAN_WIDTH_40: default: chwidth = VHT_CHANWIDTH_USE_HT; break; } switch (hapd->iface->current_mode->mode) { case HOSTAPD_MODE_IEEE80211A: if (cf1 > 5000) seg0_idx = (cf1 - 5000) / 5; if (cf2 > 5000) seg1_idx = (cf2 - 5000) / 5; break; default: ieee80211_freq_to_chan(cf1, &seg0_idx); ieee80211_freq_to_chan(cf2, &seg1_idx); break; } hapd->iconf->channel = channel; hapd->iconf->ieee80211n = ht; if (!ht) hapd->iconf->ieee80211ac = 0; hapd->iconf->secondary_channel = offset; hapd->iconf->vht_oper_chwidth = chwidth; hapd->iconf->vht_oper_centr_freq_seg0_idx = seg0_idx; hapd->iconf->vht_oper_centr_freq_seg1_idx = seg1_idx; is_dfs = ieee80211_is_dfs(freq); if (hapd->csa_in_progress && freq == hapd->cs_freq_params.freq) { hostapd_cleanup_cs_params(hapd); ieee802_11_set_beacon(hapd); wpa_msg(hapd->msg_ctx, MSG_INFO, AP_CSA_FINISHED "freq=%d dfs=%d", freq, is_dfs); } else if (hapd->iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) { wpa_msg(hapd->msg_ctx, MSG_INFO, AP_CSA_FINISHED "freq=%d dfs=%d", freq, is_dfs); } #endif /* NEED_AP_MLME */ }
void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht, int offset, int width, int cf1, int cf2) { /* TODO: If OCV is enabled deauth STAs that don't perform a SA Query */ #ifdef NEED_AP_MLME int channel, chwidth, is_dfs; u8 seg0_idx = 0, seg1_idx = 0; size_t i; 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", freq, ht, hapd->iconf->ch_switch_vht_config, offset, width, channel_width_to_string(width), cf1, cf2); hapd->iface->freq = freq; channel = hostapd_hw_get_channel(hapd, freq); if (!channel) { hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_WARNING, "driver switched to bad channel!"); return; } switch (width) { case CHAN_WIDTH_80: chwidth = VHT_CHANWIDTH_80MHZ; break; case CHAN_WIDTH_80P80: chwidth = VHT_CHANWIDTH_80P80MHZ; break; case CHAN_WIDTH_160: chwidth = VHT_CHANWIDTH_160MHZ; break; case CHAN_WIDTH_20_NOHT: case CHAN_WIDTH_20: case CHAN_WIDTH_40: default: chwidth = VHT_CHANWIDTH_USE_HT; break; } switch (hapd->iface->current_mode->mode) { case HOSTAPD_MODE_IEEE80211A: if (cf1 > 5000) seg0_idx = (cf1 - 5000) / 5; if (cf2 > 5000) seg1_idx = (cf2 - 5000) / 5; break; default: ieee80211_freq_to_chan(cf1, &seg0_idx); ieee80211_freq_to_chan(cf2, &seg1_idx); break; } hapd->iconf->channel = channel; hapd->iconf->ieee80211n = ht; if (!ht) { hapd->iconf->ieee80211ac = 0; } else if (hapd->iconf->ch_switch_vht_config) { /* CHAN_SWITCH VHT config */ if (hapd->iconf->ch_switch_vht_config & CH_SWITCH_VHT_ENABLED) hapd->iconf->ieee80211ac = 1; else if (hapd->iconf->ch_switch_vht_config & CH_SWITCH_VHT_DISABLED) hapd->iconf->ieee80211ac = 0; } hapd->iconf->ch_switch_vht_config = 0; hapd->iconf->secondary_channel = offset; hapd->iconf->vht_oper_chwidth = chwidth; hapd->iconf->vht_oper_centr_freq_seg0_idx = seg0_idx; hapd->iconf->vht_oper_centr_freq_seg1_idx = seg1_idx; is_dfs = ieee80211_is_dfs(freq, hapd->iface->hw_features, hapd->iface->num_hw_features); if (hapd->csa_in_progress && freq == hapd->cs_freq_params.freq) { hostapd_cleanup_cs_params(hapd); ieee802_11_set_beacon(hapd); wpa_msg(hapd->msg_ctx, MSG_INFO, AP_CSA_FINISHED "freq=%d dfs=%d", freq, is_dfs); } else if (hapd->iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) { wpa_msg(hapd->msg_ctx, MSG_INFO, AP_CSA_FINISHED "freq=%d dfs=%d", freq, is_dfs); } for (i = 0; i < hapd->iface->num_bss; i++) hostapd_neighbor_set_own_report(hapd->iface->bss[i]); #endif /* NEED_AP_MLME */ }