2014-04-02 22:40:04 +02:00
# include "ac.h"
# include "ac_session.h"
# include "ac_wlans.h"
2014-04-14 22:33:12 +02:00
# include "ac_backend.h"
2014-04-02 22:40:04 +02:00
/* */
2014-04-25 22:05:36 +02:00
static void ac_stations_delete_station_from_global_cache ( struct ac_session_t * session , uint8_t * address ) {
struct ac_session_t * ownersession ;
2014-04-06 17:02:31 +02:00
2014-04-25 22:05:36 +02:00
ASSERT ( session ! = NULL ) ;
2014-04-06 17:02:31 +02:00
ASSERT ( address ! = NULL ) ;
2014-04-02 22:40:04 +02:00
/* */
2014-04-06 17:02:31 +02:00
capwap_rwlock_wrlock ( & g_ac . stationslock ) ;
/* Can delete global reference only if match session handler */
2014-04-25 22:05:36 +02:00
ownersession = ( struct ac_session_t * ) capwap_hash_search ( g_ac . stations , address ) ;
if ( ownersession = = session ) {
2014-04-06 17:02:31 +02:00
capwap_hash_delete ( g_ac . stations , address ) ;
}
2014-04-02 22:40:04 +02:00
2014-04-06 17:02:31 +02:00
capwap_rwlock_exit ( & g_ac . stationslock ) ;
2014-04-02 22:40:04 +02:00
}
2014-04-15 21:59:35 +02:00
/* */
2014-04-25 22:05:36 +02:00
static void ac_stations_reset_station ( struct ac_session_t * session , struct ac_station * station , struct ac_wlan * wlan ) {
ASSERT ( session ! = NULL ) ;
2014-04-15 21:59:35 +02:00
ASSERT ( station ! = NULL ) ;
if ( station - > wlan ) {
2014-04-25 22:05:36 +02:00
if ( station - > aid ) {
if ( station - > wlan - > macmode = = CAPWAP_ADD_WLAN_MACMODE_SPLIT ) {
ieee80211_aid_free ( station - > wlan - > aidbitfield , station - > aid ) ;
}
station - > aid = 0 ;
}
/* Remove reference from current WLAN */
2014-04-15 21:59:35 +02:00
capwap_itemlist_remove ( station - > wlan - > stations , station - > wlanitem ) ;
}
/* Remove timers */
if ( station - > idtimeout ! = CAPWAP_TIMEOUT_INDEX_NO_SET ) {
2014-09-10 21:58:23 +02:00
capwap_timeout_deletetimer ( session - > timeout , station - > idtimeout ) ;
2014-04-15 21:59:35 +02:00
station - > idtimeout = CAPWAP_TIMEOUT_INDEX_NO_SET ;
}
/* */
station - > flags = 0 ;
/* Set WLAN */
station - > wlan = wlan ;
if ( station - > wlan ) {
capwap_itemlist_insert_after ( wlan - > stations , NULL , station - > wlanitem ) ;
}
}
2014-04-02 22:40:04 +02:00
/* */
2014-04-25 22:05:36 +02:00
static void ac_stations_destroy_station ( struct ac_session_t * session , struct ac_station * station ) {
ASSERT ( session ! = NULL ) ;
2014-04-06 17:02:31 +02:00
ASSERT ( station ! = NULL ) ;
/* */
2014-04-23 22:39:19 +02:00
capwap_logging_info ( " Destroy station: %s " , station - > addrtext ) ;
2014-04-06 17:02:31 +02:00
/* Remove reference from Global Cache Stations List */
2014-04-25 22:05:36 +02:00
ac_stations_delete_station_from_global_cache ( session , station - > address ) ;
2014-04-06 17:02:31 +02:00
/* Remove reference from WLAN */
2014-04-25 22:05:36 +02:00
ac_stations_reset_station ( session , station , NULL ) ;
2014-04-06 17:02:31 +02:00
/* */
2014-04-25 22:05:36 +02:00
capwap_hash_delete ( session - > wlans - > stations , station - > address ) ;
2014-04-06 17:02:31 +02:00
/* Free station reference with itemlist */
capwap_itemlist_free ( station - > wlanitem ) ;
}
/* */
static unsigned long ac_wlans_item_gethash ( const void * key , unsigned long keysize , unsigned long hashsize ) {
uint8_t * macaddress = ( uint8_t * ) key ;
ASSERT ( keysize = = MACADDRESS_EUI48_LENGTH ) ;
return ( unsigned long ) ( macaddress [ 3 ] ^ macaddress [ 4 ] ^ macaddress [ 5 ] ) ;
}
/* */
2014-04-25 22:05:36 +02:00
void ac_wlans_init ( struct ac_session_t * session ) {
int i ;
ASSERT ( session ! = NULL ) ;
ASSERT ( session - > wlans = = NULL ) ;
2014-04-06 17:02:31 +02:00
/* */
2014-04-25 22:05:36 +02:00
session - > wlans = ( struct ac_wlans * ) capwap_alloc ( sizeof ( struct ac_wlans ) ) ;
memset ( session - > wlans , 0 , sizeof ( struct ac_wlans ) ) ;
2014-04-06 17:02:31 +02:00
/* */
2014-04-25 22:05:36 +02:00
session - > wlans - > stations = capwap_hash_create ( AC_WLANS_STATIONS_HASH_SIZE , AC_WLANS_STATIONS_KEY_SIZE , ac_wlans_item_gethash , NULL , NULL ) ;
for ( i = 0 ; i < RADIOID_MAX_COUNT ; i + + ) {
session - > wlans - > devices [ i ] . radioid = i + 1 ;
}
2014-04-06 17:02:31 +02:00
}
/* */
2014-04-25 22:05:36 +02:00
void ac_wlans_destroy ( struct ac_session_t * session ) {
2014-04-02 22:40:04 +02:00
int i ;
2014-04-06 17:02:31 +02:00
struct capwap_list * items ;
2014-04-02 22:40:04 +02:00
2014-04-25 22:05:36 +02:00
ASSERT ( session ! = NULL ) ;
ASSERT ( session - > wlans ! = NULL ) ;
2014-04-02 22:40:04 +02:00
/* */
for ( i = 0 ; i < RADIOID_MAX_COUNT ; i + + ) {
2014-04-25 22:05:36 +02:00
if ( session - > wlans - > devices [ i ] . wlans ) {
items = session - > wlans - > devices [ i ] . wlans ;
2014-04-02 22:40:04 +02:00
2014-04-06 17:02:31 +02:00
/* Delete WLANS */
while ( items - > first ) {
2014-04-25 22:05:36 +02:00
ac_wlans_delete_bssid ( session , i + 1 , ( ( struct ac_wlan * ) items - > first - > item ) - > address ) ;
2014-04-02 22:40:04 +02:00
}
2014-04-06 17:02:31 +02:00
/* */
capwap_list_free ( items ) ;
}
2014-04-02 22:40:04 +02:00
}
2014-04-06 17:02:31 +02:00
/* */
2014-04-25 22:05:36 +02:00
ASSERT ( session - > wlans - > stations - > count = = 0 ) ;
2014-04-06 17:02:31 +02:00
/* */
2014-04-25 22:05:36 +02:00
capwap_hash_free ( session - > wlans - > stations ) ;
capwap_free ( session - > wlans ) ;
2014-04-02 22:40:04 +02:00
}
/* */
2014-04-25 22:05:36 +02:00
int ac_wlans_assign_bssid ( struct ac_session_t * session , struct ac_wlan * wlan ) {
2014-04-14 22:33:12 +02:00
char buffer [ CAPWAP_MACADDRESS_EUI48_BUFFER ] ;
2014-04-25 22:05:36 +02:00
ASSERT ( session ! = NULL ) ;
ASSERT ( session - > wlans ! = NULL ) ;
2014-04-14 22:33:12 +02:00
ASSERT ( wlan ! = NULL ) ;
2014-04-25 22:05:36 +02:00
ASSERT ( wlan - > device ! = NULL ) ;
ASSERT ( IS_VALID_RADIOID ( wlan - > device - > radioid ) ) ;
2014-04-14 22:33:12 +02:00
ASSERT ( IS_VALID_WLANID ( wlan - > wlanid ) ) ;
/* */
2014-04-25 22:05:36 +02:00
if ( ac_wlans_get_bssid ( session , wlan - > device - > radioid , wlan - > address ) ) {
2014-04-14 22:33:12 +02:00
return 0 ;
}
/* */
2014-04-25 22:05:36 +02:00
wlan - > session = session ;
2014-04-14 22:33:12 +02:00
/* Create WLAN list */
2014-04-25 22:05:36 +02:00
if ( ! session - > wlans - > devices [ wlan - > device - > radioid - 1 ] . wlans ) {
session - > wlans - > devices [ wlan - > device - > radioid - 1 ] . wlans = capwap_list_create ( ) ;
2014-04-14 22:33:12 +02:00
}
/* Append WLAN to list */
2014-04-25 22:05:36 +02:00
capwap_itemlist_insert_after ( session - > wlans - > devices [ wlan - > device - > radioid - 1 ] . wlans , NULL , wlan - > wlanitem ) ;
2014-04-14 22:33:12 +02:00
/* */
2014-04-25 22:05:36 +02:00
capwap_logging_info ( " Added new wlan with radioid: %d, wlanid: %d, bssid: %s " , ( int ) wlan - > device - > radioid , ( int ) wlan - > wlanid , capwap_printf_macaddress ( buffer , wlan - > address , MACADDRESS_EUI48_LENGTH ) ) ;
2014-04-14 22:33:12 +02:00
return 1 ;
}
/* */
2014-04-25 22:05:36 +02:00
struct ac_wlan * ac_wlans_create_bssid ( struct ac_device * device , uint8_t wlanid , const uint8_t * bssid , struct capwap_80211_addwlan_element * addwlan ) {
2014-04-02 22:40:04 +02:00
struct ac_wlan * wlan ;
struct capwap_list_item * wlanitem ;
2014-04-25 22:05:36 +02:00
ASSERT ( device ! = NULL ) ;
2014-04-02 22:40:04 +02:00
ASSERT ( IS_VALID_WLANID ( wlanid ) ) ;
ASSERT ( bssid ! = NULL ) ;
/* */
wlanitem = capwap_itemlist_create ( sizeof ( struct ac_wlan ) ) ;
wlan = ( struct ac_wlan * ) wlanitem - > item ;
memset ( wlan , 0 , sizeof ( struct ac_wlan ) ) ;
/* Init WLAN */
2014-04-14 22:33:12 +02:00
wlan - > wlanitem = wlanitem ;
2014-04-25 22:05:36 +02:00
memcpy ( wlan - > address , bssid , MACADDRESS_EUI48_LENGTH ) ;
wlan - > device = device ;
2014-04-02 22:40:04 +02:00
wlan - > wlanid = wlanid ;
wlan - > stations = capwap_list_create ( ) ;
2014-04-14 22:33:12 +02:00
/* Set capability */
wlan - > capability = addwlan - > capability ;
wlan - > keyindex = addwlan - > keyindex ;
wlan - > keystatus = addwlan - > keystatus ;
wlan - > keylength = addwlan - > keylength ;
if ( addwlan - > key & & ( addwlan - > keylength > 0 ) ) {
wlan - > key = ( uint8_t * ) capwap_clone ( addwlan - > key , wlan - > keylength ) ;
2014-04-02 22:40:04 +02:00
}
2014-04-14 22:33:12 +02:00
memcpy ( wlan - > grouptsc , addwlan - > grouptsc , CAPWAP_ADD_WLAN_GROUPTSC_LENGTH ) ;
wlan - > qos = addwlan - > qos ;
wlan - > authmode = addwlan - > authmode ;
wlan - > macmode = addwlan - > macmode ;
wlan - > tunnelmode = addwlan - > tunnelmode ;
wlan - > suppressssid = addwlan - > suppressssid ;
2014-04-25 22:05:36 +02:00
strcpy ( wlan - > ssid , ( const char * ) addwlan - > ssid ) ;
2014-04-02 22:40:04 +02:00
return wlan ;
}
/* */
2014-04-25 22:05:36 +02:00
struct ac_wlan * ac_wlans_get_bssid ( struct ac_session_t * session , uint8_t radioid , const uint8_t * bssid ) {
2014-04-02 22:40:04 +02:00
struct capwap_list_item * search ;
struct ac_wlan * wlan = NULL ;
2014-04-25 22:05:36 +02:00
ASSERT ( session ! = NULL ) ;
ASSERT ( session - > wlans ! = NULL ) ;
2014-04-02 22:40:04 +02:00
ASSERT ( IS_VALID_RADIOID ( radioid ) ) ;
ASSERT ( bssid ! = NULL ) ;
/* */
2014-04-25 22:05:36 +02:00
if ( session - > wlans - > devices [ radioid - 1 ] . wlans ) {
for ( search = session - > wlans - > devices [ radioid - 1 ] . wlans - > first ; search ; search = search - > next ) {
2014-04-02 22:40:04 +02:00
struct ac_wlan * item = ( struct ac_wlan * ) search - > item ;
2014-04-25 22:05:36 +02:00
if ( ! memcmp ( bssid , item - > address , MACADDRESS_EUI48_LENGTH ) ) {
2014-04-02 22:40:04 +02:00
wlan = item ;
break ;
}
}
}
return wlan ;
}
/* */
2014-04-25 22:05:36 +02:00
struct ac_wlan * ac_wlans_get_bssid_with_wlanid ( struct ac_session_t * session , uint8_t radioid , uint8_t wlanid ) {
2014-04-02 22:40:04 +02:00
struct capwap_list_item * search ;
struct ac_wlan * wlan = NULL ;
2014-04-25 22:05:36 +02:00
ASSERT ( session ! = NULL ) ;
ASSERT ( session - > wlans ! = NULL ) ;
2014-04-02 22:40:04 +02:00
ASSERT ( IS_VALID_RADIOID ( radioid ) ) ;
ASSERT ( IS_VALID_WLANID ( wlanid ) ) ;
/* */
2014-04-25 22:05:36 +02:00
if ( session - > wlans - > devices [ radioid - 1 ] . wlans ) {
for ( search = session - > wlans - > devices [ radioid - 1 ] . wlans - > first ; search ; search = search - > next ) {
2014-04-02 22:40:04 +02:00
struct ac_wlan * item = ( struct ac_wlan * ) search - > item ;
if ( wlanid = = item - > wlanid ) {
wlan = item ;
break ;
}
}
}
return wlan ;
}
/* */
2014-04-25 22:05:36 +02:00
static void ac_wlans_destroy_bssid ( struct ac_session_t * session , struct ac_wlan * wlan ) {
ASSERT ( session ! = NULL ) ;
ASSERT ( session - > wlans ! = NULL ) ;
ASSERT ( wlan ! = NULL ) ;
2014-04-02 22:40:04 +02:00
/* Free capability */
if ( wlan - > key ) {
capwap_free ( wlan - > key ) ;
}
/* Remove stations */
2014-04-06 17:02:31 +02:00
while ( wlan - > stations - > first ) {
2014-04-25 22:05:36 +02:00
ac_stations_destroy_station ( session , ( struct ac_station * ) wlan - > stations - > first - > item ) ;
2014-04-06 17:02:31 +02:00
}
/* */
2014-04-02 22:40:04 +02:00
capwap_list_free ( wlan - > stations ) ;
}
/* */
2014-04-25 22:05:36 +02:00
void ac_wlans_delete_bssid ( struct ac_session_t * session , uint8_t radioid , const uint8_t * bssid ) {
2014-04-02 22:40:04 +02:00
struct capwap_list_item * search ;
2014-04-25 22:05:36 +02:00
ASSERT ( session ! = NULL ) ;
ASSERT ( session - > wlans ! = NULL ) ;
2014-04-02 22:40:04 +02:00
ASSERT ( IS_VALID_RADIOID ( radioid ) ) ;
ASSERT ( bssid ! = NULL ) ;
/* */
2014-04-25 22:05:36 +02:00
if ( session - > wlans - > devices [ radioid - 1 ] . wlans ) {
for ( search = session - > wlans - > devices [ radioid - 1 ] . wlans - > first ; search ; search = search - > next ) {
2014-04-02 22:40:04 +02:00
struct ac_wlan * item = ( struct ac_wlan * ) search - > item ;
2014-04-25 22:05:36 +02:00
if ( ! memcmp ( bssid , item - > address , MACADDRESS_EUI48_LENGTH ) ) {
ac_wlans_destroy_bssid ( session , item ) ;
capwap_itemlist_free ( capwap_itemlist_remove ( session - > wlans - > devices [ radioid - 1 ] . wlans , search ) ) ;
2014-04-02 22:40:04 +02:00
break ;
}
}
}
}
/* */
2014-04-25 22:05:36 +02:00
struct ac_station * ac_stations_get_station ( struct ac_session_t * session , uint8_t radioid , const uint8_t * bssid , const uint8_t * address ) {
2014-04-06 17:02:31 +02:00
struct ac_station * station ;
2014-04-25 22:05:36 +02:00
ASSERT ( session ! = NULL ) ;
ASSERT ( session - > wlans ! = NULL ) ;
2014-04-06 17:02:31 +02:00
ASSERT ( address ! = NULL ) ;
/* Get station */
2014-04-25 22:05:36 +02:00
station = ( struct ac_station * ) capwap_hash_search ( session - > wlans - > stations , address ) ;
if ( station & & ( station - > flags & AC_STATION_FLAGS_ENABLED ) & & ( ( radioid = = RADIOID_ANY ) | | ( radioid = = station - > wlan - > device - > radioid ) ) & & ( ! bssid | | ! memcmp ( bssid , station - > wlan - > address , MACADDRESS_EUI48_LENGTH ) ) ) {
2014-04-06 17:02:31 +02:00
return station ;
}
return NULL ;
}
/* */
2014-04-25 22:05:36 +02:00
struct ac_station * ac_stations_create_station ( struct ac_session_t * session , uint8_t radioid , const uint8_t * bssid , const uint8_t * address ) {
2014-04-06 17:02:31 +02:00
char buffer1 [ CAPWAP_MACADDRESS_EUI48_BUFFER ] ;
char buffer2 [ CAPWAP_MACADDRESS_EUI48_BUFFER ] ;
struct ac_wlan * wlan ;
2014-04-25 22:05:36 +02:00
struct ac_session_t * ownersession ;
2014-04-06 17:02:31 +02:00
struct capwap_list_item * stationitem ;
2014-04-25 22:05:36 +02:00
struct ac_station * station = NULL ;
2014-04-06 17:02:31 +02:00
2014-04-25 22:05:36 +02:00
ASSERT ( session ! = NULL ) ;
ASSERT ( session - > wlans ! = NULL ) ;
2014-04-06 17:02:31 +02:00
ASSERT ( IS_VALID_RADIOID ( radioid ) ) ;
ASSERT ( bssid ! = NULL ) ;
ASSERT ( address ! = NULL ) ;
/* */
capwap_printf_macaddress ( buffer1 , bssid , MACADDRESS_EUI48_LENGTH ) ;
capwap_printf_macaddress ( buffer2 , address , MACADDRESS_EUI48_LENGTH ) ;
capwap_logging_info ( " Create station to radioid: %d, bssid: %s, station address: %s " , ( int ) radioid , buffer1 , buffer2 ) ;
2014-04-25 22:05:36 +02:00
/* */
wlan = ac_wlans_get_bssid ( session , radioid , bssid ) ;
if ( wlan ) {
/* Get session that owns the station */
capwap_rwlock_rdlock ( & g_ac . stationslock ) ;
ownersession = ( struct ac_session_t * ) capwap_hash_search ( g_ac . stations , address ) ;
capwap_rwlock_exit ( & g_ac . stationslock ) ;
/* If request change owner of station */
if ( ownersession ! = session ) {
/* Release station from old owner */
if ( ownersession ) {
2014-09-10 21:58:23 +02:00
ac_session_send_action ( ownersession , AC_SESSION_ACTION_STATION_ROAMING , 0 , ( void * ) address , MACADDRESS_EUI48_LENGTH ) ;
2014-04-25 22:05:36 +02:00
}
2014-04-06 17:02:31 +02:00
2014-04-25 22:05:36 +02:00
/* Set station into Global Cache Stations List */
capwap_rwlock_wrlock ( & g_ac . stationslock ) ;
capwap_hash_add ( g_ac . stations , address , session ) ;
capwap_rwlock_exit ( & g_ac . stationslock ) ;
2014-04-06 17:02:31 +02:00
}
2014-04-25 22:05:36 +02:00
/* */
station = ( struct ac_station * ) capwap_hash_search ( session - > wlans - > stations , address ) ;
if ( ! station ) {
stationitem = capwap_itemlist_create ( sizeof ( struct ac_station ) ) ;
station = ( struct ac_station * ) stationitem - > item ;
memset ( station , 0 , sizeof ( struct ac_station ) ) ;
2014-04-06 17:02:31 +02:00
2014-04-25 22:05:36 +02:00
/* */
station - > idtimeout = CAPWAP_TIMEOUT_INDEX_NO_SET ;
memcpy ( station - > address , address , MACADDRESS_EUI48_LENGTH ) ;
capwap_printf_macaddress ( station - > addrtext , address , MACADDRESS_EUI48_LENGTH ) ;
station - > wlanitem = stationitem ;
2014-04-06 17:02:31 +02:00
2014-04-25 22:05:36 +02:00
/* */
capwap_hash_add ( session - > wlans - > stations , address , station ) ;
}
2014-04-06 17:02:31 +02:00
2014-04-25 22:05:36 +02:00
/* Set station to WLAN */
ac_stations_reset_station ( session , station , wlan ) ;
station - > flags | = AC_STATION_FLAGS_ENABLED ;
} else {
capwap_logging_warning ( " Unable to find radioid: %d, bssid: %s " , ( int ) radioid , buffer1 ) ;
2014-04-06 17:02:31 +02:00
}
return station ;
}
/* */
2014-04-25 22:05:36 +02:00
void ac_stations_delete_station ( struct ac_session_t * session , struct ac_station * station ) {
ASSERT ( session ! = NULL ) ;
ASSERT ( session - > wlans ! = NULL ) ;
2014-04-14 22:33:12 +02:00
ASSERT ( station ! = NULL ) ;
2014-04-06 17:02:31 +02:00
2014-04-14 22:33:12 +02:00
/* Deauthorize station */
2014-04-25 22:05:36 +02:00
ac_stations_deauthorize_station ( session , station ) ;
2014-04-14 22:33:12 +02:00
/* Destroy station reference */
2014-04-25 22:05:36 +02:00
ac_stations_destroy_station ( session , station ) ;
2014-04-14 22:33:12 +02:00
}
/* */
2014-04-25 22:05:36 +02:00
void ac_stations_authorize_station ( struct ac_session_t * session , struct ac_station * station ) {
2014-04-14 22:33:12 +02:00
struct ac_notify_station_configuration_ieee8011_add_station notify ;
2014-04-25 22:05:36 +02:00
ASSERT ( session ! = NULL ) ;
ASSERT ( session - > wlans ! = NULL ) ;
2014-04-14 22:33:12 +02:00
ASSERT ( station ! = NULL ) ;
2014-09-10 21:58:23 +02:00
/* Active Station only if Authenticated, Associated and not Authorizated */
2014-04-14 22:33:12 +02:00
if ( ( station - > flags & AC_STATION_FLAGS_AUTHENTICATED ) & & ( station - > flags & AC_STATION_FLAGS_ASSOCIATE ) & & ! ( station - > flags & AC_STATION_FLAGS_AUTHORIZED ) ) {
memset ( & notify , 0 , sizeof ( struct ac_notify_station_configuration_ieee8011_add_station ) ) ;
2014-04-25 22:05:36 +02:00
notify . radioid = station - > wlan - > device - > radioid ;
2014-04-14 22:33:12 +02:00
memcpy ( notify . address , station - > address , MACADDRESS_EUI48_LENGTH ) ;
notify . wlanid = station - > wlan - > wlanid ;
notify . associationid = station - > aid ;
notify . capabilities = station - > capability ;
notify . supportedratescount = station - > supportedratescount ;
memcpy ( notify . supportedrates , station - > supportedrates , station - > supportedratescount ) ;
2014-04-25 22:05:36 +02:00
ac_session_send_action ( session , AC_SESSION_ACTION_STATION_CONFIGURATION_IEEE80211_ADD_STATION , 0 , & notify , sizeof ( struct ac_notify_station_configuration_ieee8011_add_station ) ) ;
2014-04-14 22:33:12 +02:00
}
}
/* */
2014-04-25 22:05:36 +02:00
void ac_stations_deauthorize_station ( struct ac_session_t * session , struct ac_station * station ) {
2014-04-14 22:33:12 +02:00
int responselength ;
uint8_t buffer [ IEEE80211_MTU ] ;
struct ieee80211_deauthentication_params ieee80211_params ;
struct ac_notify_station_configuration_ieee8011_delete_station notify ;
2014-04-25 22:05:36 +02:00
ASSERT ( session ! = NULL ) ;
ASSERT ( session - > wlans ! = NULL ) ;
2014-04-14 22:33:12 +02:00
ASSERT ( station ! = NULL ) ;
if ( station - > flags & AC_STATION_FLAGS_AUTHORIZED ) {
2014-04-23 22:11:24 +02:00
/* Deauthorize station */
2014-04-14 22:33:12 +02:00
memset ( & notify , 0 , sizeof ( struct ac_notify_station_configuration_ieee8011_delete_station ) ) ;
2014-04-25 22:05:36 +02:00
notify . radioid = station - > wlan - > device - > radioid ;
2014-04-14 22:33:12 +02:00
memcpy ( notify . address , station - > address , MACADDRESS_EUI48_LENGTH ) ;
2014-04-15 21:59:35 +02:00
/* */
2014-04-23 22:11:24 +02:00
station - > flags & = ~ ( AC_STATION_FLAGS_AUTHENTICATED | AC_STATION_FLAGS_ASSOCIATE | AC_STATION_FLAGS_AUTHORIZED ) ;
2014-04-25 22:05:36 +02:00
ac_session_send_action ( session , AC_SESSION_ACTION_STATION_CONFIGURATION_IEEE80211_DELETE_STATION , 0 , & notify , sizeof ( struct ac_notify_station_configuration_ieee8011_delete_station ) ) ;
2014-04-23 22:11:24 +02:00
} else if ( station - > flags & AC_STATION_FLAGS_AUTHENTICATED ) {
2014-04-14 22:33:12 +02:00
/* Create deauthentication packet */
memset ( & ieee80211_params , 0 , sizeof ( struct ieee80211_deauthentication_params ) ) ;
2014-04-25 22:05:36 +02:00
memcpy ( ieee80211_params . bssid , station - > wlan - > address , MACADDRESS_EUI48_LENGTH ) ;
2014-04-14 22:33:12 +02:00
memcpy ( ieee80211_params . station , station - > address , MACADDRESS_EUI48_LENGTH ) ;
ieee80211_params . reasoncode = IEEE80211_REASON_PREV_AUTH_NOT_VALID ;
2014-04-06 17:02:31 +02:00
2014-04-14 22:33:12 +02:00
/* */
responselength = ieee80211_create_deauthentication ( buffer , IEEE80211_MTU , & ieee80211_params ) ;
if ( responselength > 0 ) {
station - > flags & = ~ ( AC_STATION_FLAGS_AUTHENTICATED | AC_STATION_FLAGS_ASSOCIATE ) ;
2014-09-10 21:58:23 +02:00
ac_kmod_send_data ( & session - > sockaddrdata . ss , station - > wlan - > device - > radioid , session - > binding , buffer , responselength ) ;
2014-04-14 22:33:12 +02:00
}
2014-04-06 17:02:31 +02:00
}
}
2014-04-15 21:59:35 +02:00
/* */
void ac_stations_timeout ( struct capwap_timeout * timeout , unsigned long index , void * context , void * param ) {
struct ac_station * station = ( struct ac_station * ) context ;
ASSERT ( station ! = NULL ) ;
if ( station - > idtimeout = = index ) {
switch ( station - > timeoutaction ) {
case AC_STATION_TIMEOUT_ACTION_DEAUTHENTICATE : {
2014-04-23 22:39:19 +02:00
capwap_logging_warning ( " The %s station has not completed the association in time " , station - > addrtext ) ;
2014-04-25 22:05:36 +02:00
ac_stations_delete_station ( ( struct ac_session_t * ) param , station ) ;
2014-04-15 21:59:35 +02:00
break ;
}
}
}
}