From patchwork Thu Dec 24 20:17:29 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jouni Malinen X-Patchwork-Id: 560968 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2001:1868:205::9]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 815D0140C1F for ; Fri, 25 Dec 2015 07:18:03 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1aCCKi-0006E3-Ez; Thu, 24 Dec 2015 20:17:56 +0000 Received: from mail.w1.fi ([2a01:7e00::f03c:91ff:fedb:30e2] helo=li674-96.members.linode.com) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1aCCKf-0006Bi-Jg for hostap@lists.infradead.org; Thu, 24 Dec 2015 20:17:55 +0000 Received: from jm (178-55-77-165.bb.dnainternet.fi [178.55.77.165]) by li674-96.members.linode.com (Postfix) with ESMTPSA id 8518911512; Thu, 24 Dec 2015 20:17:30 +0000 (UTC) Received: by jm (sSMTP sendmail emulation); Thu, 24 Dec 2015 22:17:29 +0200 Date: Thu, 24 Dec 2015 22:17:29 +0200 From: Jouni Malinen To: Ulrich =?utf-8?Q?=C3=96lmann?= Subject: Re: [RFC v2 PATCH 2/2] wpa_supplicant: Enable Automatic Channel Selection support for AP mode Message-ID: <20151224201729.GI27050@w1.fi> References: <1448624437-11250-1-git-send-email-u.oelmann@pengutronix.de> <1448624437-11250-3-git-send-email-u.oelmann@pengutronix.de> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <1448624437-11250-3-git-send-email-u.oelmann@pengutronix.de> User-Agent: Mutt/1.5.21 (2010-09-15) X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20151224_121753_968311_672B4596 X-CRM114-Status: GOOD ( 25.25 ) X-Spam-Score: -1.9 (-) X-Spam-Report: SpamAssassin version 3.4.0 on bombadil.infradead.org summary: Content analysis details: (-1.9 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RP_MATCHES_RCVD Envelope sender domain matches handover relay domain -0.0 SPF_PASS SPF: sender matches SPF record -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] X-BeenThere: hostap@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: hostap@lists.infradead.org, Tomasz Bursztyka Sender: "Hostap" Errors-To: hostap-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org On Fri, Nov 27, 2015 at 12:40:37PM +0100, Ulrich Ölmann wrote: > Since hostapd supports ACS now, let's enable its support into > wpa_supplicant when going on AP mode. This needs some more rebasing to build cleanly on top of the current tree to address the new hostapd_acs_channel_selected() function and event. > diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile > +ifdef CONFIG_ACS > +CFLAGS += -DCONFIG_ACS > +OBJS += ../src/ap/acs.o > +LIBS += -lm > +endif Android.mk should have same changes. > diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c > @@ -210,6 +210,12 @@ static int wpa_supplicant_conf_ap(struct wpa_supplicant *wpa_s, > +#ifdef CONFIG_ACS > + /* Setting channel to 0 in order to enable ACS */ > + if (ssid->acs) > + conf->channel = 0; > +#endif > + > if (wpa_supplicant_conf_ap_ht(wpa_s, ssid, conf)) > return -1; This does not work at least when HT support is enabled. That clearing of conf->channel needs to be moved after this call to wpa_supplicant_conf_ap_ht(). > diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c > @@ -1920,6 +1920,9 @@ static const struct parse_data ssid_fields[] = { > +#ifdef CONFIG_ACS > + { INT_RANGE(acs, 0, 1) }, > +#endif /* CONFIG_ACS */ This is missing a matching change in config_file.c to write the new network profile parameter. > diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h > @@ -431,6 +431,18 @@ struct wpa_ssid { > + /** > + * ACS - Automatic Channel Selection for AP mode > + * > + * If present, it will be handled together with frequency. > + * frequency will be used to determine hardware mode only, when it is > + * used for both hardware mode and channel when used alone. This will > + * force the channel to be set to 0, thus enabling ACS. > + */ > + int acs; This does not really sound like the cleanest way of configuring hw mode.. Maybe something with the new acs parameter could do than assuming frequency is used in a way that get replaced by ACS.. Anyway, I guess I'm going to go with this for now. This is what I currently have in my pending branch: src/ap/drv_callbacks.c | 4 ++-- src/ap/hostapd.h | 2 ++ wpa_supplicant/Android.mk | 6 ++++++ wpa_supplicant/Makefile | 6 ++++++ wpa_supplicant/ap.c | 10 ++++++++++ wpa_supplicant/config.c | 3 +++ wpa_supplicant/config_file.c | 3 +++ wpa_supplicant/config_ssid.h | 12 ++++++++++++ wpa_supplicant/defconfig | 26 ++++++++++++++++++++++++++ wpa_supplicant/events.c | 8 ++++++++ 10 files changed, 78 insertions(+), 2 deletions(-) diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c index 9208569..aad0d81 100644 --- a/src/ap/drv_callbacks.c +++ b/src/ap/drv_callbacks.c @@ -549,8 +549,8 @@ void hostapd_event_connect_failed_reason(struct hostapd_data *hapd, #ifdef CONFIG_ACS -static void hostapd_acs_channel_selected(struct hostapd_data *hapd, - struct acs_selected_channels *acs_res) +void hostapd_acs_channel_selected(struct hostapd_data *hapd, + struct acs_selected_channels *acs_res) { int ret, i; diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h index a664644..7b59f80 100644 --- a/src/ap/hostapd.h +++ b/src/ap/hostapd.h @@ -496,6 +496,8 @@ void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht, struct survey_results; void hostapd_event_get_survey(struct hostapd_iface *iface, struct survey_results *survey_results); +void hostapd_acs_channel_selected(struct hostapd_data *hapd, + struct acs_selected_channels *acs_res); const struct hostapd_eap_user * hostapd_get_eap_user(struct hostapd_data *hapd, const u8 *identity, diff --git a/wpa_supplicant/Android.mk b/wpa_supplicant/Android.mk index a558bbe..72af838 100644 --- a/wpa_supplicant/Android.mk +++ b/wpa_supplicant/Android.mk @@ -857,6 +857,12 @@ OBJS += src/ap/peerkey_auth.c endif endif +ifdef CONFIG_ACS +L_CFLAGS += -DCONFIG_ACS +OBJS += src/ap/acs.c +LIBS += -lm +endif + ifdef CONFIG_PCSC # PC/SC interface for smartcards (USIM, GSM SIM) L_CFLAGS += -DPCSC_FUNCS -I/usr/include/PCSC diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile index 6bab7d1..1d85958 100644 --- a/wpa_supplicant/Makefile +++ b/wpa_supplicant/Makefile @@ -884,6 +884,12 @@ OBJS += ../src/ap/peerkey_auth.o endif endif +ifdef CONFIG_ACS +CFLAGS += -DCONFIG_ACS +OBJS += ../src/ap/acs.o +LIBS += -lm +endif + ifdef CONFIG_PCSC # PC/SC interface for smartcards (USIM, GSM SIM) CFLAGS += -DPCSC_FUNCS -I/usr/include/PCSC diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c index 27fa2a9..29eeb49 100644 --- a/wpa_supplicant/ap.c +++ b/wpa_supplicant/ap.c @@ -213,6 +213,14 @@ static int wpa_supplicant_conf_ap(struct wpa_supplicant *wpa_s, if (wpa_supplicant_conf_ap_ht(wpa_s, ssid, conf)) return -1; +#ifdef CONFIG_ACS + if (ssid->acs) { + /* Setting channel to 0 in order to enable ACS */ + conf->channel = 0; + wpa_printf(MSG_DEBUG, "Use automatic channel selection"); + } +#endif /* CONFIG_ACS */ + if (ieee80211_is_dfs(ssid->frequency) && wpa_s->conf->country[0]) { conf->ieee80211h = 1; conf->ieee80211d = 1; @@ -559,6 +567,8 @@ static void wpas_ap_configured_cb(void *ctx) struct wpa_supplicant *wpa_s = ctx; wpa_supplicant_set_state(wpa_s, WPA_COMPLETED); + if (wpa_s->current_ssid && wpa_s->current_ssid->acs) + wpa_s->assoc_freq = wpa_s->ap_iface->freq; if (wpa_s->ap_configured_cb) wpa_s->ap_configured_cb(wpa_s->ap_configured_cb_ctx, diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c index f2ae4fd..85717e9 100644 --- a/wpa_supplicant/config.c +++ b/wpa_supplicant/config.c @@ -1920,6 +1920,9 @@ static const struct parse_data ssid_fields[] = { { INT_RANGE(mixed_cell, 0, 1) }, { INT_RANGE(frequency, 0, 65000) }, { INT_RANGE(fixed_freq, 0, 1) }, +#ifdef CONFIG_ACS + { INT_RANGE(acs, 0, 1) }, +#endif /* CONFIG_ACS */ #ifdef CONFIG_MESH { FUNC(mesh_basic_rates) }, { INT(dot11MeshMaxRetries) }, diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c index 80e3e56..6ea113e 100644 --- a/wpa_supplicant/config_file.c +++ b/wpa_supplicant/config_file.c @@ -747,6 +747,9 @@ static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid) INT(no_auto_peer); INT(frequency); INT(fixed_freq); +#ifdef CONFIG_ACS + INT(acs); +#endif /* CONFIG_ACS */ write_int(f, "proactive_key_caching", ssid->proactive_key_caching, -1); INT(disabled); INT(peerkey); diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h index de8157a..b296826 100644 --- a/wpa_supplicant/config_ssid.h +++ b/wpa_supplicant/config_ssid.h @@ -431,6 +431,18 @@ struct wpa_ssid { */ int fixed_freq; +#ifdef CONFIG_ACS + /** + * ACS - Automatic Channel Selection for AP mode + * + * If present, it will be handled together with frequency. + * frequency will be used to determine hardware mode only, when it is + * used for both hardware mode and channel when used alone. This will + * force the channel to be set to 0, thus enabling ACS. + */ + int acs; +#endif /* CONFIG_ACS */ + /** * mesh_basic_rates - BSS Basic rate set for mesh network * diff --git a/wpa_supplicant/defconfig b/wpa_supplicant/defconfig index e2e4bdc..8b1d121 100644 --- a/wpa_supplicant/defconfig +++ b/wpa_supplicant/defconfig @@ -513,3 +513,29 @@ CONFIG_PEERKEY=y # OS X builds. This is only for building eapol_test. #CONFIG_OSX=y + +# Automatic Channel Selection +# This will allow wpa_supplicant to pick the channel automatically when channel +# is set to "0". +# +# TODO: Extend parser to be able to parse "channel=acs_survey" as an alternative +# to "channel=0". This would enable us to eventually add other ACS algorithms in +# similar way. +# +# Automatic selection is currently only done through initialization, later on +# we hope to do background checks to keep us moving to more ideal channels as +# time goes by. ACS is currently only supported through the nl80211 driver and +# your driver must have survey dump capability that is filled by the driver +# during scanning. +# +# TODO: In analogy to hostapd be able to customize the ACS survey algorithm with +# a newly to create wpa_supplicant.conf variable acs_num_scans. +# +# Supported ACS drivers: +# * ath9k +# * ath5k +# * ath10k +# +# For more details refer to: +# http://wireless.kernel.org/en/users/Documentation/acs +#CONFIG_ACS=y diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index 43f3d9b..2870e89 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -3946,6 +3946,14 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event, &data->survey_results); #endif /* CONFIG_AP */ break; + case EVENT_ACS_CHANNEL_SELECTED: +#ifdef CONFIG_ACS + if (!wpa_s->ap_iface) + break; + hostapd_acs_channel_selected(wpa_s->ap_iface->bss[0], + &data->acs_selected_channels); +#endif /* CONFIG_ACS */ + break; default: wpa_msg(wpa_s, MSG_INFO, "Unknown event %d", event); break;