[PATCH 4/4] hostapd: Use channel switch fallback on error

Otcheretianski, Andrei andrei.otcheretianski at intel.com
Wed Jun 25 09:52:49 EDT 2014


Hi,
See my inline comments.

Andrei

> -----Original Message-----
> From: hostap-bounces at lists.shmoo.com [mailto:hostap-
> bounces at lists.shmoo.com] On Behalf Of Michal Kazior
> Sent: Wednesday, June 25, 2014 14:20
> To: j at w1.fi
> Cc: hostap at lists.shmoo.com
> Subject: [PATCH 4/4] hostapd: Use channel switch fallback on error
> 
> It's worth giving a try to fallback to re-starting BSSes at least once hoping it
> works out instead of just leaving BSSes disabled.
> 
> Signed-off-by: Michal Kazior <michal.kazior at tieto.com>
> ---
>  src/ap/drv_callbacks.c | 11 +++++++++++
>  src/ap/hostapd.c       | 51
> +++++++++++++++++++++++++++++++++++++++++++++-----
>  src/ap/hostapd.h       |  8 ++++++++
>  src/drivers/driver.h   |  3 ++-
>  4 files changed, 67 insertions(+), 6 deletions(-)
> 
> diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c index
> ac5732c..561cbf9 100644
> --- a/src/ap/drv_callbacks.c
> +++ b/src/ap/drv_callbacks.c
> @@ -885,6 +885,14 @@ static void hostapd_event_get_survey(struct
> hostapd_data *hapd,
> 
>  #ifdef NEED_AP_MLME
> 
> +
> +static void hostapd_event_iface_unavailable(struct hostapd_data *hapd)
> +{
> +	wpa_printf(MSG_DEBUG, "Interface is unavailable -- stopped");

check csa_in_progress here maybe before calling to fallback?

> +	hostapd_switch_channel_fallback(hapd);
> +}
> +
> +
>  static void hostapd_event_dfs_radar_detected(struct hostapd_data *hapd,
>  					     struct dfs_event *radar)
>  {
> @@ -1072,6 +1080,9 @@ void wpa_supplicant_event(void *ctx, enum
> wpa_event_type event,
>  		hostapd_event_get_survey(hapd, &data->survey_results);
>  		break;
>  #ifdef NEED_AP_MLME
> +	case EVENT_INTERFACE_UNAVAILABLE:
> +		hostapd_event_iface_unavailable(hapd);
> +		break;
>  	case EVENT_DFS_RADAR_DETECTED:
>  		if (!data)
>  			break;
> diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c index 4da5a3d..c504364
> 100644
> --- a/src/ap/hostapd.c
> +++ b/src/ap/hostapd.c
> @@ -2280,13 +2280,13 @@ static int hostapd_change_config_freq(struct
> hostapd_data *hapd,
> 
>  	if (!params->channel) {
>  		/* check if the new channel is supported by hw */
> -		channel = hostapd_hw_get_channel(hapd, params->freq);
> -		if (!channel)
> -			return -1;
> -	} else {
> -		channel = params->channel;
> +		params->channel = hostapd_hw_get_channel(hapd, params-
> >freq);
>  	}
> 
> +	channel = params->channel;
> +	if (!channel)
> +		return -1;
> +
>  	/* if a pointer to old_params is provided we save previous state */
>  	if (old_params) {
>  		old_params->channel = conf->channel;
> @@ -2363,11 +2363,25 @@ void hostapd_cleanup_cs_params(struct
> hostapd_data *hapd)  int hostapd_switch_channel(struct hostapd_data
> *hapd,
>  			   struct csa_settings *settings)
>  {
> +	struct hostapd_iface *iface = hapd->iface;
>  	int ret;
> +
>  	ret = hostapd_fill_csa_settings(hapd, settings);
>  	if (ret)
>  		return ret;
> 
> +	iface->csa_freq = settings->freq_params.freq;
> +	iface->csa_channel = settings->freq_params.channel;
> +	iface->csa_secondary_channel =
> +settings->freq_params.sec_channel_offset;
> +
> +	if (settings->freq_params.center_freq1)
> +		iface->csa_vht_oper_centr_freq_seg0_idx =
> +			36 + (settings->freq_params.center_freq1 - 5180) / 5;
> +
> +	if (settings->freq_params.center_freq2)
> +		iface->csa_vht_oper_centr_freq_seg1_idx =
> +			36 + (settings->freq_params.center_freq2 - 5180) / 5;
> +

You have the entire freq_params inside hostapd_data.. Why do you need to copy?

>  	ret = hostapd_drv_switch_channel(hapd, settings);
>  	free_beacon_data(&settings->beacon_csa);
>  	free_beacon_data(&settings->beacon_after);
> @@ -2382,4 +2396,31 @@ int hostapd_switch_channel(struct hostapd_data
> *hapd,
>  	return 0;
>  }
> 
> +void hostapd_switch_channel_fallback(struct hostapd_data *hapd) {

I think this function should receive hostapd_iface as param, otherwise it's quite confusing that all the iface is restarted.

> +	struct hostapd_iface *iface = hapd->iface;
> +	int i;
> +
> +	if (!hapd->csa_in_progress)
> +		return;

And then this if should be outside

> +
> +	for (i = 0; i < iface->num_bss; i++) {
> +		iface->bss[i]->csa_in_progress = 0;
> +		iface->bss[i]->cs_freq_params.freq = 0;

hostapd_cleanup_cs_params(iface->bss[i])

> +	}
> +
> +	wpa_printf(MSG_WARNING, "CSA failed, trying fallback by toggling
> +interface");
> +
> +	iface->freq = iface->csa_freq;
> +	iface->conf->channel = iface->csa_channel;
> +	iface->conf->secondary_channel = iface->csa_secondary_channel;
> +	iface->conf->vht_oper_centr_freq_seg0_idx =
> +		iface->csa_vht_oper_centr_freq_seg0_idx;
> +	iface->conf->vht_oper_centr_freq_seg1_idx =
> +		iface->csa_vht_oper_centr_freq_seg1_idx;

It's possible to get all this info from hostapd_data->csa_freq_params and pass it as argument to this function.

> +
> +	hostapd_disable_iface(iface);
> +	hostapd_enable_iface(iface);
> +}
> +
>  #endif /* NEED_AP_MLME */
> diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h index d413f7e..011dc51
> 100644
> --- a/src/ap/hostapd.h
> +++ b/src/ap/hostapd.h
> @@ -362,6 +362,13 @@ struct hostapd_iface {
>  	unsigned int acs_num_completed_scans;
>  #endif /* CONFIG_ACS */
> 
> +	/* channel switch parameters - used for fallback if CSA itself fails */
> +	int csa_freq;
> +	short csa_channel;
> +	int csa_secondary_channel;
> +	u8 csa_vht_oper_centr_freq_seg0_idx;
> +	u8 csa_vht_oper_centr_freq_seg1_idx;
> +
>  	void (*scan_cb)(struct hostapd_iface *iface);
>  	int num_ht40_scan_tries;
>  };
> @@ -397,6 +404,7 @@ void hostapd_set_state(struct hostapd_iface *iface,
> enum hostapd_iface_state s);  const char * hostapd_state_text(enum
> hostapd_iface_state s);  int hostapd_switch_channel(struct hostapd_data
> *hapd,
>  			   struct csa_settings *settings);
> +void hostapd_switch_channel_fallback(struct hostapd_data *hapd);
>  void hostapd_cleanup_cs_params(struct hostapd_data *hapd);
> 
>  /* utils.c */
> diff --git a/src/drivers/driver.h b/src/drivers/driver.h index 33f53af..352c163
> 100644
> --- a/src/drivers/driver.h
> +++ b/src/drivers/driver.h
> @@ -3316,7 +3316,8 @@ enum wpa_event_type {
>  	 * the driver does not support radar detection and another virtual
>  	 * interfaces caused the operating channel to change. Other similar
>  	 * resource conflicts could also trigger this for station mode
> -	 * interfaces.
> +	 * interfaces. This event can be propagated when channel switching
> +	 * fails.
>  	 */
>  	EVENT_INTERFACE_UNAVAILABLE,
> 
> --
> 1.8.5.3
> 
> _______________________________________________
> HostAP mailing list
> HostAP at lists.shmoo.com
> http://lists.shmoo.com/mailman/listinfo/hostap
---------------------------------------------------------------------
A member of the Intel Corporation group of companies

This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.



More information about the HostAP mailing list