From: Tomasz Bursztyka <tomasz.bursztyka@xxxxxxxxxxxxxxx> Let's reuse hostapd code for such handling. This will be useful to get ACS support into wpa_supplicant where this one needs to handle the survey event so it fills in the result ACS subsystem will require. Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@xxxxxxxxxxxxxxx> [u.oelmann@xxxxxxxxxxxxxx: rebased series from hostap_2_1~944 to master] Signed-off-by: Ulrich Ölmann <u.oelmann@xxxxxxxxxxxxxx> --- src/ap/drv_callbacks.c | 216 ++++++++++++++++++++++++------------------------ src/ap/hostapd.h | 4 + wpa_supplicant/events.c | 7 ++ 3 files changed, 119 insertions(+), 108 deletions(-) diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c index fd07201..c4846a0 100644 --- a/src/ap/drv_callbacks.c +++ b/src/ap/drv_callbacks.c @@ -659,6 +659,114 @@ int hostapd_probe_req_rx(struct hostapd_data *hapd, const u8 *sa, const u8 *da, } +static struct hostapd_channel_data * hostapd_get_mode_channel( + struct hostapd_iface *iface, unsigned int freq) +{ + int i; + struct hostapd_channel_data *chan; + + for (i = 0; i < iface->current_mode->num_channels; i++) { + chan = &iface->current_mode->channels[i]; + if (!chan) + return NULL; + if ((unsigned int) chan->freq == freq) + return chan; + } + + return NULL; +} + + +static void hostapd_update_nf(struct hostapd_iface *iface, + struct hostapd_channel_data *chan, + struct freq_survey *survey) +{ + if (!iface->chans_surveyed) { + chan->min_nf = survey->nf; + iface->lowest_nf = survey->nf; + } else { + if (dl_list_empty(&chan->survey_list)) + chan->min_nf = survey->nf; + else if (survey->nf < chan->min_nf) + chan->min_nf = survey->nf; + if (survey->nf < iface->lowest_nf) + iface->lowest_nf = survey->nf; + } +} + + +static void hostapd_single_channel_get_survey(struct hostapd_iface *iface, + struct survey_results *survey_res) +{ + struct hostapd_channel_data *chan; + struct freq_survey *survey; + u64 divisor, dividend; + + survey = dl_list_first(&survey_res->survey_list, struct freq_survey, + list); + if (!survey || !survey->freq) + return; + + chan = hostapd_get_mode_channel(iface, survey->freq); + if (!chan || chan->flag & HOSTAPD_CHAN_DISABLED) + return; + + wpa_printf(MSG_DEBUG, + "Single Channel Survey: (freq=%d channel_time=%ld channel_time_busy=%ld)", + survey->freq, + (unsigned long int) survey->channel_time, + (unsigned long int) survey->channel_time_busy); + + if (survey->channel_time > iface->last_channel_time && + survey->channel_time > survey->channel_time_busy) { + dividend = survey->channel_time_busy - + iface->last_channel_time_busy; + divisor = survey->channel_time - iface->last_channel_time; + + iface->channel_utilization = dividend * 255 / divisor; + wpa_printf(MSG_DEBUG, "Channel Utilization: %d", + iface->channel_utilization); + } + iface->last_channel_time = survey->channel_time; + iface->last_channel_time_busy = survey->channel_time_busy; +} + + +void hostapd_event_get_survey(struct hostapd_data *hapd, + struct survey_results *survey_results) +{ + struct hostapd_iface *iface = hapd->iface; + struct freq_survey *survey, *tmp; + struct hostapd_channel_data *chan; + + if (dl_list_empty(&survey_results->survey_list)) { + wpa_printf(MSG_DEBUG, "No survey data received"); + return; + } + + if (survey_results->freq_filter) { + hostapd_single_channel_get_survey(iface, survey_results); + return; + } + + dl_list_for_each_safe(survey, tmp, &survey_results->survey_list, + struct freq_survey, list) { + chan = hostapd_get_mode_channel(iface, survey->freq); + if (!chan) + continue; + if (chan->flag & HOSTAPD_CHAN_DISABLED) + continue; + + dl_list_del(&survey->list); + dl_list_add_tail(&chan->survey_list, &survey->list); + + hostapd_update_nf(iface, chan, survey); + + iface->chans_surveyed++; + } +} + + #ifdef HOSTAPD #ifdef CONFIG_IEEE80211R @@ -946,114 +1054,6 @@ static void hostapd_event_eapol_rx(struct hostapd_data *hapd, const u8 *src, } -static struct hostapd_channel_data * hostapd_get_mode_channel( - struct hostapd_iface *iface, unsigned int freq) -{ - int i; - struct hostapd_channel_data *chan; - - for (i = 0; i < iface->current_mode->num_channels; i++) { - chan = &iface->current_mode->channels[i]; - if (!chan) - return NULL; - if ((unsigned int) chan->freq == freq) - return chan; - } - - return NULL; -} - - -static void hostapd_update_nf(struct hostapd_iface *iface, - struct hostapd_channel_data *chan, - struct freq_survey *survey) -{ - if (!iface->chans_surveyed) { - chan->min_nf = survey->nf; - iface->lowest_nf = survey->nf; - } else { - if (dl_list_empty(&chan->survey_list)) - chan->min_nf = survey->nf; - else if (survey->nf < chan->min_nf) - chan->min_nf = survey->nf; - if (survey->nf < iface->lowest_nf) - iface->lowest_nf = survey->nf; - } -} - - -static void hostapd_single_channel_get_survey(struct hostapd_iface *iface, - struct survey_results *survey_res) -{ - struct hostapd_channel_data *chan; - struct freq_survey *survey; - u64 divisor, dividend; - - survey = dl_list_first(&survey_res->survey_list, struct freq_survey, - list); - if (!survey || !survey->freq) - return; - - chan = hostapd_get_mode_channel(iface, survey->freq); - if (!chan || chan->flag & HOSTAPD_CHAN_DISABLED) - return; - - wpa_printf(MSG_DEBUG, - "Single Channel Survey: (freq=%d channel_time=%ld channel_time_busy=%ld)", - survey->freq, - (unsigned long int) survey->channel_time, - (unsigned long int) survey->channel_time_busy); - - if (survey->channel_time > iface->last_channel_time && - survey->channel_time > survey->channel_time_busy) { - dividend = survey->channel_time_busy - - iface->last_channel_time_busy; - divisor = survey->channel_time - iface->last_channel_time; - - iface->channel_utilization = dividend * 255 / divisor; - wpa_printf(MSG_DEBUG, "Channel Utilization: %d", - iface->channel_utilization); - } - iface->last_channel_time = survey->channel_time; - iface->last_channel_time_busy = survey->channel_time_busy; -} - - -static void hostapd_event_get_survey(struct hostapd_data *hapd, - struct survey_results *survey_results) -{ - struct hostapd_iface *iface = hapd->iface; - struct freq_survey *survey, *tmp; - struct hostapd_channel_data *chan; - - if (dl_list_empty(&survey_results->survey_list)) { - wpa_printf(MSG_DEBUG, "No survey data received"); - return; - } - - if (survey_results->freq_filter) { - hostapd_single_channel_get_survey(iface, survey_results); - return; - } - - dl_list_for_each_safe(survey, tmp, &survey_results->survey_list, - struct freq_survey, list) { - chan = hostapd_get_mode_channel(iface, survey->freq); - if (!chan) - continue; - if (chan->flag & HOSTAPD_CHAN_DISABLED) - continue; - - dl_list_del(&survey->list); - dl_list_add_tail(&chan->survey_list, &survey->list); - - hostapd_update_nf(iface, chan, survey); - - iface->chans_surveyed++; - } -} - - #ifdef NEED_AP_MLME static void hostapd_event_iface_unavailable(struct hostapd_data *hapd) diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h index 8161a59..4548f65 100644 --- a/src/ap/hostapd.h +++ b/src/ap/hostapd.h @@ -506,4 +506,8 @@ void fst_hostapd_fill_iface_obj(struct hostapd_data *hapd, struct fst_wpa_obj *iface_obj); #endif /* CONFIG_FST */ +struct survey_results; +void hostapd_event_get_survey(struct hostapd_data *hapd, + struct survey_results *survey_results); + #endif /* HOSTAPD_H */ diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index 5afe94f..4f57d6c 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -3924,6 +3924,13 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event, data->mesh_peer.ie_len); #endif /* CONFIG_MESH */ break; + case EVENT_SURVEY: { + struct hostapd_data hapd = {}; + hapd.iface = wpa_s->ap_iface; + + hostapd_event_get_survey(&hapd, &data->survey_results); + break; + } default: wpa_msg(wpa_s, MSG_INFO, "Unknown event %d", event); break; -- 2.1.4 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap