@ -2,7 +2,7 @@
* hostapd / Hardware feature query and different modes
* Copyright 2002 - 2003 , Instant802 Networks , Inc .
* Copyright 2005 - 2006 , Devicescape Software , Inc .
* Copyright ( c ) 2008 - 201 1 , Jouni Malinen < j @ w1 . fi >
* Copyright ( c ) 2008 - 201 2 , Jouni Malinen < j @ w1 . fi >
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License version 2 as
@ -416,7 +416,7 @@ static void ieee80211n_check_scan(struct hostapd_iface *iface)
int res ;
/* Check list of neighboring BSSes (from scan) to see whether 40 MHz is
* allowed per IEEE 802.11 n / D7 .0 , 11.14 .3 .2 */
* allowed per IEEE Std 802.11 - 2012 , 10.15 .3 .2 */
iface - > scan_cb = NULL ;
@ -447,6 +447,46 @@ static void ieee80211n_check_scan(struct hostapd_iface *iface)
}
static void ieee80211n_scan_channels_2g4 ( struct hostapd_iface * iface ,
struct wpa_driver_scan_params * params )
{
/* Scan only the affected frequency range */
int pri_freq , sec_freq ;
int affected_start , affected_end ;
int i , pos ;
struct hostapd_hw_modes * mode ;
if ( iface - > current_mode = = NULL )
return ;
pri_freq = hostapd_hw_get_freq ( iface - > bss [ 0 ] , iface - > conf - > channel ) ;
if ( iface - > conf - > secondary_channel > 0 )
sec_freq = pri_freq + 20 ;
else
sec_freq = pri_freq - 20 ;
affected_start = ( pri_freq + sec_freq ) / 2 - 25 ;
affected_end = ( pri_freq + sec_freq ) / 2 + 25 ;
wpa_printf ( MSG_DEBUG , " 40 MHz affected channel range: [%d,%d] MHz " ,
affected_start , affected_end ) ;
mode = iface - > current_mode ;
params - > freqs = os_zalloc ( ( mode - > num_channels + 1 ) * sizeof ( int ) ) ;
if ( params - > freqs = = NULL )
return ;
pos = 0 ;
for ( i = 0 ; i < mode - > num_channels ; i + + ) {
struct hostapd_channel_data * chan = & mode - > channels [ i ] ;
if ( chan - > flag & HOSTAPD_CHAN_DISABLED )
continue ;
if ( chan - > freq < affected_start | |
chan - > freq > affected_end )
continue ;
params - > freqs [ pos + + ] = chan - > freq ;
}
}
static int ieee80211n_check_40mhz ( struct hostapd_iface * iface )
{
struct wpa_driver_scan_params params ;
@ -457,12 +497,15 @@ static int ieee80211n_check_40mhz(struct hostapd_iface *iface)
wpa_printf ( MSG_DEBUG , " Scan for neighboring BSSes prior to enabling "
" 40 MHz channel " ) ;
os_memset ( & params , 0 , sizeof ( params ) ) ;
/* TODO: scan only the needed frequency */
if ( iface - > current_mode - > mode = = HOSTAPD_MODE_IEEE80211G )
ieee80211n_scan_channels_2g4 ( iface , & params ) ;
if ( hostapd_driver_scan ( iface - > bss [ 0 ] , & params ) < 0 ) {
wpa_printf ( MSG_ERROR , " Failed to request a scan of "
" neighboring BSSes " ) ;
os_free ( params . freqs ) ;
return - 1 ;
}
os_free ( params . freqs ) ;
iface - > scan_cb = ieee80211n_check_scan ;
return 1 ;