From patchwork Mon Apr 23 09:01:07 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jouni Malinen X-Patchwork-Id: 154353 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from maxx.maxx.shmoo.com (maxx.shmoo.com [205.134.188.171]) by ozlabs.org (Postfix) with ESMTP id 5DE43B6FA3 for ; Mon, 23 Apr 2012 19:01:26 +1000 (EST) Received: from localhost (localhost [127.0.0.1]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id 182459C165; Mon, 23 Apr 2012 05:01:23 -0400 (EDT) X-Virus-Scanned: amavisd-new at maxx.shmoo.com Received: from maxx.maxx.shmoo.com ([127.0.0.1]) by localhost (maxx.shmoo.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id YQJpCErwA4n8; Mon, 23 Apr 2012 05:01:22 -0400 (EDT) Received: from maxx.shmoo.com (localhost [127.0.0.1]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id B256B9C1CB; Mon, 23 Apr 2012 05:01:17 -0400 (EDT) X-Original-To: mailman-post+hostap@maxx.shmoo.com Delivered-To: mailman-post+hostap@maxx.shmoo.com Received: from localhost (localhost [127.0.0.1]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id A45A79C1CB for ; Mon, 23 Apr 2012 05:01:15 -0400 (EDT) X-Virus-Scanned: amavisd-new at maxx.shmoo.com Received: from maxx.maxx.shmoo.com ([127.0.0.1]) by localhost (maxx.shmoo.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id i730y8O8-5n6 for ; Mon, 23 Apr 2012 05:01:11 -0400 (EDT) Received: from jmaline2.user.openhosting.com (kvm.w1.fi [128.177.28.162]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by maxx.maxx.shmoo.com (Postfix) with ESMTPS id E2F8F9C165 for ; Mon, 23 Apr 2012 05:01:11 -0400 (EDT) Received: from jm (a91-155-81-182.elisa-laajakaista.fi [91.155.81.182]) (authenticated bits=0) by jmaline2.user.openhosting.com (8.13.8/8.13.8) with ESMTP id q3N8o0FB028804 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Mon, 23 Apr 2012 04:50:02 -0400 Received: by jm (sSMTP sendmail emulation); Mon, 23 Apr 2012 12:01:07 +0300 Date: Mon, 23 Apr 2012 12:01:07 +0300 From: Jouni Malinen To: hostap@lists.shmoo.com Subject: Re: [RFC 2/3] wpa_supplicant: Add 2040 BSS intolerance support in station mode Message-ID: <20120423090107.GB6369@w1.fi> Mail-Followup-To: hostap@lists.shmoo.com References: <1334756650-10624-1-git-send-email-rmanohar@qca.qualcomm.com> <1334756650-10624-2-git-send-email-rmanohar@qca.qualcomm.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <1334756650-10624-2-git-send-email-rmanohar@qca.qualcomm.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-BeenThere: hostap@lists.shmoo.com X-Mailman-Version: 2.1.9 Precedence: list List-Id: HostAP Project List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: hostap-bounces@lists.shmoo.com Errors-To: hostap-bounces@lists.shmoo.com On Wed, Apr 18, 2012 at 07:14:09PM +0530, Rajkumar Manoharan wrote: > Add support for HT STA to report 40MHz intolerance to the associated AP. > A HT station generates a report (2040 BSS coexistence) of channel list > if it finds a non-HT capable AP or a HT AP which prohibits 40MHz > transmission (i.e 40MHz intolerant bit is set in HT capabilities IE) > from the scan results. This looks SME-specific, so it would be cleaner to keep the implementation within sme.c until some other uses show up for it. The below version does that and adds couple of TODO/FIX comments that should be addressed. The OBSS scan one could be left as a separate one for now, but the other comments should be addressed for the initial commit (well, apart from the special Country element cases with operating class triplets). diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index da9cf2b..f6e1622 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -1096,6 +1096,12 @@ static int _wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s, selected = wpa_supplicant_pick_network(wpa_s, scan_res, &ssid); + /* + * TODO: This should be done at the completion of OBSS scan operations + * which may or may not be identical to other scans.. + */ + sme_proc_40mhz_intolerant(wpa_s); + if (selected) { int skip; skip = !wpa_supplicant_need_to_roam(wpa_s, selected, ssid, diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c index b366847..f4aa006 100644 --- a/wpa_supplicant/sme.c +++ b/wpa_supplicant/sme.c @@ -609,6 +609,160 @@ void sme_deinit(struct wpa_supplicant *wpa_s) } +static void sme_send_2040_bss_coex(struct wpa_supplicant *wpa_s, + const u8 *chan_list, u8 num_channels) +{ + struct ieee80211_2040_bss_coex_ie *bc_ie; + struct ieee80211_2040_intol_chan_report *ic_report; + struct wpabuf *buf; + + wpa_printf(MSG_DEBUG, "SME: Send 20/40 BSS Coexistence to " MACSTR, + MAC2STR(wpa_s->bssid)); + + buf = wpabuf_alloc(2 + /* action.category + action_code */ + sizeof(struct ieee80211_2040_bss_coex_ie) + + sizeof(struct ieee80211_2040_intol_chan_report) + + num_channels); + if (buf == NULL) + return; + + wpabuf_put_u8(buf, WLAN_ACTION_PUBLIC); + wpabuf_put_u8(buf, WLAN_PA_20_40_BSS_COEX); + + bc_ie = wpabuf_put(buf, sizeof(*bc_ie)); + bc_ie->element_id = WLAN_EID_20_40_BSS_COEXISTENCE; + bc_ie->length = 1; + /* TODO: is this flag really supposed to be added uncontionally? + * Shouldn't this be added onyl if a trigger event TE-B has been + * detected? + */ + bc_ie->coex_info = WLAN_20_40_BSS_COEX_20MHZ_WIDTH_REQ; + + ic_report = wpabuf_put(buf, sizeof(*ic_report)); + ic_report->element_id = WLAN_EID_20_40_BSS_INTOLERANT; + ic_report->length = num_channels + 1; + /* FIX: set ic_report->op_class */ + + os_memcpy(wpabuf_put(buf, num_channels), chan_list, num_channels); + + if (wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid, + wpa_s->own_addr, wpa_s->bssid, + wpabuf_head(buf), wpabuf_len(buf), 0) < 0) { + wpa_msg(wpa_s, MSG_INFO, "SME: Failed to send 20/40 BSS " + "Coexistence frame"); + } + + wpabuf_free(buf); +} + + +/** + * enum wpas_band - Frequency band + * @WPAS_BAND_2GHZ: 2.4 GHz ISM band + * @WPAS_BAND_5GHZ: around 5 GHz band (4.9 - 5.7 GHz) + */ +enum wpas_band { + WPAS_BAND_2GHZ, + WPAS_BAND_5GHZ, + WPAS_BAND_INVALID +}; + +/** + * freq_to_channel - Convert frequency into channel info + * @channel: Buffer for returning channel number + * Returns: Band (2 or 5 GHz) + */ +static enum wpas_band freq_to_channel(int freq, u8 *channel) +{ + enum wpas_band band = (freq <= 2484) ? WPAS_BAND_2GHZ : WPAS_BAND_5GHZ; + u8 chan = 0; + + if (freq >= 2412 && freq <= 2472) + chan = (freq - 2407) / 5; + else if (freq == 2484) + chan = 14; + else if (freq >= 5180 && freq <= 5805) + chan = (freq - 5000) / 5; + + *channel = chan; + return band; +} + + +void sme_proc_40mhz_intolerant(struct wpa_supplicant *wpa_s) +{ + struct wpa_bss *bss; + enum wpas_band assoc_band; + const u8 *ie; + u16 ht_cap; + u8 chan_list[P2P_MAX_CHANNELS], channel; + u8 num_channels = 0, i; + + if (!wpa_s->current_bss || wpa_s->wpa_state != WPA_COMPLETED) + return; + + /* Check whether local driver supports HT40 */ + if (!wpa_s->hw.modes || + !(wpa_s->hw.modes->ht_capab & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET)) + return; + + /* Check whether AP supports HT40 */ + ie = wpa_bss_get_ie(wpa_s->current_bss, WLAN_EID_HT_OPERATION); + if (!ie || ie[1] < 2 || + !(ie[3] & HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH)) + return; + + /* + * Check whether AP uses regulatory triplet or channel triplet in + * country info. Right now the operating class of the BSS channel + * width trigger event is "unknown" (IEEE Std 802.11-2012 10.15.12), + * based on the assumption that operating class triplet is not used in + * beacon frame. If the First Channel Number/Operating Extension + * Identifier octet has a positive integer value of 201 or greater, + * then its operating class triplet. + * + * TODO: If Supported Operating Classes element is present in Beacon + * frame, have to lookup operating class in Annex E and fill them in + * 20/40 coex frame. + * + * TODO: Is it fine to skip this report if Country element is not + * included? + */ + ie = wpa_bss_get_ie(wpa_s->current_bss, WLAN_EID_COUNTRY); + if (!ie || ie[1] < 6 || (ie[5] > 201)) + return; + + assoc_band = freq_to_channel(wpa_s->current_bss->freq, &channel); + os_memset(chan_list, 0, sizeof(chan_list)); + + dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) { + /* Skip other band bss */ + if (freq_to_channel(bss->freq, &channel) != assoc_band) + continue; + + ie = wpa_bss_get_ie(bss, WLAN_EID_HT_CAP); + ht_cap = (ie && (ie[1] == 26)) ? WPA_GET_LE16(ie + 2) : 0; + + /* TODO: Shouldn't TE-B events be counted separately so that + * 20 MHz width request flag can be set correctly? */ + if (!ht_cap || (ht_cap & HT_CAP_INFO_40MHZ_INTOLERANT)) { + /* Check whether the channel is already considered */ + for (i = 0; i < num_channels; i++) { + if (channel == chan_list[i]) + break; + } + if (i != num_channels) + continue; + + chan_list[num_channels++] = channel; + } + } + + if (num_channels) + sme_send_2040_bss_coex(wpa_s, chan_list, num_channels); +} + + #ifdef CONFIG_IEEE80211W static const unsigned int sa_query_max_timeout = 1000; diff --git a/wpa_supplicant/sme.h b/wpa_supplicant/sme.h index 33530bb..f735832 100644 --- a/wpa_supplicant/sme.h +++ b/wpa_supplicant/sme.h @@ -35,6 +35,8 @@ void sme_disassoc_while_authenticating(struct wpa_supplicant *wpa_s, const u8 *prev_pending_bssid); void sme_deinit(struct wpa_supplicant *wpa_s); +void sme_proc_40mhz_intolerant(struct wpa_supplicant *wpa_s); + #else /* CONFIG_SME */ static inline void sme_authenticate(struct wpa_supplicant *wpa_s, @@ -95,6 +97,10 @@ static inline void sme_deinit(struct wpa_supplicant *wpa_s) { } +static inline void sme_proc_40mhz_intolerant(struct wpa_supplicant *wpa_s) +{ +} + #endif /* CONFIG_SME */ #endif /* SME_H */