@ -17,13 +17,14 @@ struct nl80211_channel_block {
char * phyname ;
int nfreqs ;
int * channel_list ;
int * disabled_list ;
int * passive_list ;
int * radar_list ;
int * txpower_list ;
} ;
typedef struct nl80211_channel_block nl80211_channel_block_t ;
// why is this necessary? I get "SupportedBands does not name a type" if I only declare the typedef in the class definition
typedef QFlags < Wireless : : Bands > SupportedBands ;
int IEEE80211Freq [ ] [ 2 ] = {
{ 1 , 2412 } ,
{ 2 , 2417 } ,
@ -93,7 +94,8 @@ m_channels(),
m_isValid ( false ) ,
m_isNL80211 ( false )
{
void * handle , * family = NULL ;
void * handle = NULL ;
struct genl_family * family = NULL ;
struct nl_cache * cache = NULL ;
struct nl_msg * msg = nlmsg_alloc ( ) ;
struct nl_cb * cb = nl_cb_alloc ( NL_CB_DEFAULT ) ;
@ -130,70 +132,137 @@ m_isNL80211(false)
if ( nl_send_auto_complete ( ( struct nl_sock * ) handle , msg ) < 0 ) {
fprintf ( stderr , " %s: Failed to write nl80211 message \n " ,
__FUNCTION__ ) ;
nl80211_disconnect ( handle , cache ) ;
nl80211_disconnect ( handle , cache , family ) ;
return ;
}
while ( err )
nl_recvmsgs ( ( struct nl_sock * ) handle , cb ) ;
nl80211_disconnect ( handle , cache ) ;
nl80211_disconnect ( handle , cache , family ) ;
for ( int i = 0 ; i < cblock . nfreqs ; + + i ) {
m_channels . insert ( cblock . channel_list [ i ] , ChanToFreq ( cblock . channel_list [ i ] ) ) ;
ChannelInfo info ;
info . chan = cblock . channel_list [ i ] ;
info . freq = ChanToFreq ( cblock . channel_list [ i ] ) ;
info . disabled = cblock . disabled_list [ i ] ;
info . passive = cblock . passive_list [ i ] ;
info . radar = cblock . radar_list [ i ] ;
info . max_txpower = cblock . txpower_list [ i ] ;
m_channels . append ( info ) ;
// check supported channels to see what bands we support (only makes sense for A and B)
// is there a better way to do this?
if ( ! ( ( m_supportedBands & BAND_80211_A ) = = BAND_80211_A ) ) {
if ( cblock . channel_list [ i ] > = 36 ) { // first US 5GHz channel
m_supportedBands | = BAND_80211_A ;
m_supportedBands = static_cast < Bands > ( m_supportedBands | BAND_80211_A ) ;
}
}
if ( ! ( ( m_supportedBands & BAND_80211_B ) = = BAND_80211_B ) ) {
if ( cblock . channel_list [ i ] > = 1 ) { // first 2.4GHz channel
m_supportedBands | = BAND_80211_B ;
m_supportedBands = static_cast < Bands > ( m_supportedBands | BAND_80211_B ) ;
}
}
}
free ( cblock . channel_list ) ;
free ( cblock . disabled_list ) ;
free ( cblock . passive_list ) ;
free ( cblock . radar_list ) ;
free ( cblock . txpower_list ) ;
free ( cblock . phyname ) ;
m_isValid = true ;
}
const SupportedBands Wireless : : supportedBands ( ) const {
Wireless : : ~ Wireless ( ) {
std : : cerr < < " del wireless " < < std : : endl ;
m_channels . clear ( ) ;
}
Wireless : : Bands Wireless : : supportedBands ( ) {
return m_supportedBands ;
}
QList < int > Wireless : : channels ( ) const {
QList < int > channels = m_channels . keys ( ) ;
QList < int > Wireless : : allChannels ( ) const {
QList < int > channels ;
foreach ( ChannelInfo info , m_channels ) {
channels . append ( info . chan ) ;
}
return channels ;
}
QList < int > Wireless : : frequencies ( ) const {
QList < int > freqs = m_channels . values ( ) ;
QList < int > Wireless : : allowedChannels ( Direction dir ) const {
QList < int > channels ;
foreach ( ChannelInfo info , m_channels ) {
if ( ! info . disabled ) {
if ( ( ( dir & Direction_Both ) = = Direction_Both ) & & ( ! info . passive ) ) {
channels . append ( info . chan ) ;
} else if ( ( ( dir & Direction_RX ) = = Direction_RX ) ) {
channels . append ( info . chan ) ;
}
}
}
return channels ;
}
QList < int > Wireless : : allFrequencies ( ) const {
QList < int > freqs ;
foreach ( ChannelInfo info , m_channels ) {
freqs . append ( info . freq ) ;
}
return freqs ;
}
QList < int > Wireless : : allowedFrequencies ( Direction dir ) const {
QList < int > freqs ;
foreach ( ChannelInfo info , m_channels ) {
if ( ! info . disabled ) {
if ( ( ( dir & Direction_Both ) = = Direction_Both ) & & ( ! info . passive ) ) {
freqs . append ( info . freq ) ;
} else if ( ( ( dir & Direction_RX ) = = Direction_RX ) ) {
freqs . append ( info . freq ) ;
}
}
}
return freqs ;
}
bool Wireless : : channelSupported ( int chan ) const {
if ( m_channels . contains ( chan ) ) {
return true ;
} else {
return false ;
bool found = false ;
foreach ( ChannelInfo info , m_channels ) {
if ( info . chan = = chan ) {
found = true ;
break ;
}
}
return found ;
}
bool Wireless : : frequencySupported ( int freq ) const {
QList < int > channels = m_channels . values ( ) ;
bool found = false ;
if ( channels . contains ( freq ) ) {
return true ;
} else {
return false ;
foreach ( ChannelInfo info , m_channels ) {
if ( info . freq = = freq ) {
found = true ;
break ;
}
}
return found ;
}
bool Wireless : : isValid ( ) const {
@ -276,7 +345,7 @@ QString Wireless::FreqToChan(QString in_freq, QString outputFormat) {
return chan ;
}
int Wireless : : nl80211_connect ( const char * /*interface*/ , void * * handle , struct nl_cache * * cache , void * * family ) {
int Wireless : : nl80211_connect ( const char * /*interface*/ , void * * handle , struct nl_cache * * cache , struct genl_family * * family ) const {
struct nl_sock * nl_handle ;
struct nl_cache * nl_cache ;
struct genl_family * nl80211 ;
@ -310,12 +379,13 @@ int Wireless::nl80211_connect(const char * /*interface*/, void **handle, struct
( * handle ) = ( void * ) nl_handle ;
( * cache ) = nl_cache ;
( * family ) = ( void * ) nl80211 ;
( * family ) = nl80211 ;
return 1 ;
}
void Wireless : : nl80211_disconnect ( void * handle , struct nl_cache * cache ) {
void Wireless : : nl80211_disconnect ( void * handle , struct nl_cache * cache , struct genl_family * family ) const {
genl_family_put ( family ) ;
nl_cache_free ( cache ) ;
nl_socket_free ( ( struct nl_sock * ) handle ) ;
}
@ -365,15 +435,16 @@ int Wireless::nl80211_freqlist_cb(struct nl_msg *msg, void *arg) {
if ( ! tb_freq [ NL80211_FREQUENCY_ATTR_FREQ ] )
continue ;
if ( tb_freq [ NL80211_FREQUENCY_ATTR_DISABLED ] )
continue ;
num_freq + + ;
}
}
chanb - > nfreqs = num_freq ;
chanb - > channel_list = ( int * ) malloc ( sizeof ( int ) * num_freq ) ;
chanb - > disabled_list = ( int * ) malloc ( sizeof ( int ) * num_freq ) ;
chanb - > passive_list = ( int * ) malloc ( sizeof ( int ) * num_freq ) ;
chanb - > radar_list = ( int * ) malloc ( sizeof ( int ) * num_freq ) ;
chanb - > txpower_list = ( int * ) malloc ( sizeof ( int ) * num_freq ) ;
num_freq = 0 ;
// Assemble a return
@ -397,12 +468,15 @@ int Wireless::nl80211_freqlist_cb(struct nl_msg *msg, void *arg) {
if ( ! tb_freq [ NL80211_FREQUENCY_ATTR_FREQ ] )
continue ;
if ( tb_freq [ NL80211_FREQUENCY_ATTR_DISABLED ] )
continue ;
freq = nla_get_u32 ( tb_freq [ NL80211_FREQUENCY_ATTR_FREQ ] ) ;
chanb - > channel_list [ num_freq + + ] = FreqToChan ( freq ) ;
int index = num_freq + + ;
chanb - > channel_list [ index ] = FreqToChan ( freq ) ;
chanb - > disabled_list [ index ] = ( tb_freq [ NL80211_FREQUENCY_ATTR_DISABLED ] ) ? 1 : 0 ;
chanb - > passive_list [ index ] = ( tb_freq [ NL80211_FREQUENCY_ATTR_PASSIVE_SCAN ] ) ? 1 : 0 ;
chanb - > radar_list [ index ] = ( tb_freq [ NL80211_FREQUENCY_ATTR_RADAR ] ) ? 1 : 0 ;
chanb - > txpower_list [ index ] = nla_get_u32 ( tb_freq [ NL80211_FREQUENCY_ATTR_MAX_TX_POWER ] ) ;
}
}
@ -421,7 +495,7 @@ int Wireless::nl80211_finish_cb(struct nl_msg * /*msg*/, void *arg) {
return NL_SKIP ;
}
char * Wireless : : nl80211_find_parent ( const char * interface ) {
char * Wireless : : nl80211_find_parent ( const char * interface ) const {
DIR * devdir ;
struct dirent * devfile ;
char dirpath [ 1024 ] ;
@ -445,6 +519,6 @@ char* Wireless::nl80211_find_parent(const char *interface) {
return NULL ;
}
const QMap < int , int > & Wireless : : channelMap ( ) const {
const QList < ChannelInfo > & Wireless : : channelMap ( ) const {
return m_channels ;
}