Add station timer. Fix multiple bug.

This commit is contained in:
vemax78
2014-04-15 21:59:35 +02:00
parent 3e06393469
commit 21661277a0
6 changed files with 123 additions and 67 deletions

View File

@ -22,6 +22,32 @@ static void ac_stations_delete_station_from_global_cache(struct ac_session_data_
capwap_rwlock_exit(&g_ac.stationslock);
}
/* */
static void ac_stations_reset_station(struct ac_session_data_t* sessiondata, struct ac_station* station, struct ac_wlan* wlan) {
ASSERT(sessiondata != NULL);
ASSERT(station != NULL);
/* Remove reference from current WLAN */
if (station->wlan) {
capwap_itemlist_remove(station->wlan->stations, station->wlanitem);
}
/* Remove timers */
if (station->idtimeout != CAPWAP_TIMEOUT_INDEX_NO_SET) {
capwap_timeout_deletetimer(sessiondata->timeout, station->idtimeout);
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);
}
}
/* */
static void ac_stations_destroy_station(struct ac_session_data_t* sessiondata, struct ac_station* station) {
char buffer[CAPWAP_MACADDRESS_EUI48_BUFFER];
@ -36,9 +62,7 @@ static void ac_stations_destroy_station(struct ac_session_data_t* sessiondata, s
ac_stations_delete_station_from_global_cache(sessiondata, station->address);
/* Remove reference from WLAN */
if (station->wlan) {
capwap_itemlist_remove(station->wlan->stations, station->wlanitem);
}
ac_stations_reset_station(sessiondata, station, NULL);
/* */
capwap_hash_delete(sessiondata->wlans->stations, station->address);
@ -56,24 +80,6 @@ static unsigned long ac_wlans_item_gethash(const void* key, unsigned long keysiz
return (unsigned long)(macaddress[3] ^ macaddress[4] ^ macaddress[5]);
}
/* */
static void ac_stations_reset_station(struct ac_station* station, struct ac_wlan* wlan) {
ASSERT(station != NULL);
ASSERT(wlan != NULL);
/* Remove reference from current WLAN */
if (station->wlan) {
capwap_itemlist_remove(station->wlan->stations, station->wlanitem);
}
/* */
station->flags = 0;
/* Set WLAN */
station->wlan = wlan;
capwap_itemlist_insert_after(wlan->stations, NULL, station->wlanitem);
}
/* */
void ac_wlans_init(struct ac_session_data_t* sessiondata) {
ASSERT(sessiondata != NULL);
@ -308,7 +314,7 @@ struct ac_station* ac_stations_get_station(struct ac_session_data_t* sessiondata
/* Get station */
station = (struct ac_station*)capwap_hash_search(sessiondata->wlans->stations, address);
if (station && ((radioid == RADIOID_ANY) || (radioid == station->wlan->radioid)) && (!bssid || !memcmp(bssid, station->wlan->bssid, MACADDRESS_EUI48_LENGTH))) {
if (station && (station->flags & AC_STATION_FLAGS_ENABLED) && ((radioid == RADIOID_ANY) || (radioid == station->wlan->radioid)) && (!bssid || !memcmp(bssid, station->wlan->bssid, MACADDRESS_EUI48_LENGTH))) {
return station;
}
@ -355,13 +361,14 @@ struct ac_station* ac_stations_create_station(struct ac_session_data_t* sessiond
/* */
wlan = ac_wlans_get_bssid(sessiondata, radioid, bssid);
station = ac_stations_get_station(sessiondata, RADIOID_ANY, NULL, address);
station = (struct ac_station*)capwap_hash_search(sessiondata->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));
/* */
station->idtimeout = CAPWAP_TIMEOUT_INDEX_NO_SET;
memcpy(station->address, address, MACADDRESS_EUI48_LENGTH);
station->wlanitem = stationitem;
@ -370,7 +377,8 @@ struct ac_station* ac_stations_create_station(struct ac_session_data_t* sessiond
}
/* Set station to WLAN */
ac_stations_reset_station(station, wlan);
ac_stations_reset_station(sessiondata, station, wlan);
station->flags |= AC_STATION_FLAGS_ENABLED;
return station;
}
@ -422,16 +430,19 @@ void ac_stations_deauthorize_station(struct ac_session_data_t* sessiondata, stru
ASSERT(sessiondata->wlans != NULL);
ASSERT(station != NULL);
/* Delete Station only if Authrizated */
/* Deauthorize station */
if (station->flags & AC_STATION_FLAGS_AUTHORIZED) {
memset(&notify, 0, sizeof(struct ac_notify_station_configuration_ieee8011_delete_station));
notify.radioid = station->wlan->radioid;
memcpy(notify.address, station->address, MACADDRESS_EUI48_LENGTH);
/* Request recall ac_stations_deauthorize_station for deauthentication the station */
/* */
station->flags &= ~AC_STATION_FLAGS_AUTHORIZED;
ac_session_send_action(sessiondata->session, AC_SESSION_ACTION_STATION_CONFIGURATION_IEEE80211_DELETE_STATION, 0, &notify, sizeof(struct ac_notify_station_configuration_ieee8011_delete_station));
} else if (station->flags & AC_STATION_FLAGS_AUTHENTICATED) {
}
/* Deauthenticate station */
if (station->flags & AC_STATION_FLAGS_AUTHENTICATED) {
/* Create deauthentication packet */
memset(&ieee80211_params, 0, sizeof(struct ieee80211_deauthentication_params));
memcpy(ieee80211_params.bssid, station->wlan->bssid, MACADDRESS_EUI48_LENGTH);
@ -446,3 +457,24 @@ void ac_stations_deauthorize_station(struct ac_session_data_t* sessiondata, stru
}
}
}
/* */
void ac_stations_timeout(struct capwap_timeout* timeout, unsigned long index, void* context, void* param) {
char stationaddress[CAPWAP_MACADDRESS_EUI48_BUFFER];
struct ac_station* station = (struct ac_station*)context;
ASSERT(station != NULL);
/* */
capwap_printf_macaddress(stationaddress, station->address, MACADDRESS_EUI48_LENGTH);
if (station->idtimeout == index) {
switch (station->timeoutaction) {
case AC_STATION_TIMEOUT_ACTION_DEAUTHENTICATE: {
capwap_logging_warning("The %s station has not completed the association in time", stationaddress);
ac_stations_delete_station((struct ac_session_data_t*)param, station);
break;
}
}
}
}