From 9fee37a994bd89c4ce14df8a8bb14266dd39f643 Mon Sep 17 00:00:00 2001 From: Andreas Schultz Date: Mon, 29 Feb 2016 14:26:13 +0100 Subject: [PATCH] rework wifi type and rate logic Hard coding basic rates is wrong. Each Wifi types does expect some default basic rates. However those rates are not set in stone and the AC is permited to set then to whatever it deems ok. This might prevent client from connecting, but it still is the AC decission to do so. This is first step towards a more flexible basic rate handling. --- src/common/binding/ieee80211/ieee80211.h | 3 +- src/wtp/binding/ieee80211/wifi_drivers.c | 79 +++++++++++++++--------- src/wtp/wtp.c | 2 +- 3 files changed, 53 insertions(+), 31 deletions(-) diff --git a/src/common/binding/ieee80211/ieee80211.h b/src/common/binding/ieee80211/ieee80211.h index 718b483..649c071 100644 --- a/src/common/binding/ieee80211/ieee80211.h +++ b/src/common/binding/ieee80211/ieee80211.h @@ -48,7 +48,8 @@ #define IEEE80211_BASICRATE 128 #define IS_IEEE80211_BASICRATE_B(x) ((x == IEEE80211_RATE_1M) || (x == IEEE80211_RATE_2M)) -#define IS_IEEE80211_BASICRATE_G(x) ((x == IEEE80211_RATE_1M) || (x == IEEE80211_RATE_2M) || (x == IEEE80211_RATE_5_5M) || (x == IEEE80211_RATE_11M)) +#define IS_IEEE80211_BASICRATE_G(x) ((x == IEEE80211_RATE_6M) || (x == IEEE80211_RATE_9M) || (x == IEEE80211_RATE_12M) || (x == IEEE80211_RATE_18M)) +#define IS_IEEE80211_BASICRATE_BG(x) ((x == IEEE80211_RATE_1M) || (x == IEEE80211_RATE_2M) || (x == IEEE80211_RATE_5_5M) || (x == IEEE80211_RATE_11M)) #define IS_IEEE80211_BASICRATE_A(x) ((x == IEEE80211_RATE_6M) || (x == IEEE80211_RATE_12M) || (x == IEEE80211_RATE_24M)) /* Frame control type */ diff --git a/src/wtp/binding/ieee80211/wifi_drivers.c b/src/wtp/binding/ieee80211/wifi_drivers.c index 67f8658..7965f76 100644 --- a/src/wtp/binding/ieee80211/wifi_drivers.c +++ b/src/wtp/binding/ieee80211/wifi_drivers.c @@ -81,56 +81,75 @@ static void wifi_wlan_getrates(struct wifi_device* device, uint8_t* rates, int r capwap_logging_debug("getrates: Mode %d", mode); +#if 0 + /* WTF: the AC should know what it's doing and set those rate when it want's them */ + /* Add implicit 802.11b rate with only 802.11g rate */ - if ((device->currentfrequency.band == WIFI_BAND_2GHZ) && !(mode & CAPWAP_RADIO_TYPE_80211B) && (device->currentfrequency.mode & CAPWAP_RADIO_TYPE_80211B)) { + if ((device->currentfrequency.band == WIFI_BAND_2GHZ) && + !(mode & CAPWAP_RADIO_TYPE_80211B) && + (device->currentfrequency.mode & CAPWAP_RADIO_TYPE_80211B)) { device_params->supportedrates[device_params->supportedratescount++] = IEEE80211_RATE_1M; device_params->supportedrates[device_params->supportedratescount++] = IEEE80211_RATE_2M; device_params->supportedrates[device_params->supportedratescount++] = IEEE80211_RATE_5_5M; device_params->supportedrates[device_params->supportedratescount++] = IEEE80211_RATE_11M; } +#endif capwap_logging_debug("getrates: Bands Count %d", capability->bands->count); /* Filter band */ for (i = 0; i < capability->bands->count; i++) { - struct wifi_band_capability* bandcap = (struct wifi_band_capability*)capwap_array_get_item_pointer(capability->bands, i); + struct wifi_band_capability* bandcap = + (struct wifi_band_capability*)capwap_array_get_item_pointer(capability->bands, i); capwap_logging_debug("getrates: Bandcap Band %d", bandcap->band); - if (bandcap->band == device->currentfrequency.band) { - for (j = 0; j < bandcap->rate->count; j++) { - struct wifi_rate_capability* ratecapability = (struct wifi_rate_capability*)capwap_array_get_item_pointer(bandcap->rate, j); + if (bandcap->band != device->currentfrequency.band) + continue; - /* Validate rate */ - for (w = 0; w < ratescount; w++) { - if (rates[w] == ratecapability->bitrate) { - device_params->supportedrates[device_params->supportedratescount++] = ratecapability->bitrate; - break; - } + for (j = 0; j < bandcap->rate->count; j++) { + struct wifi_rate_capability* ratecapability = + (struct wifi_rate_capability*)capwap_array_get_item_pointer(bandcap->rate, j); + + /* Validate rate */ + for (w = 0; w < ratescount; w++) { + log_printf(LOG_DEBUG, "getrates: cmp %d .. %d", + rates[w], ratecapability->bitrate); + if (rates[w] == ratecapability->bitrate) { + device_params->supportedrates[device_params->supportedratescount++] = ratecapability->bitrate; + break; } } - - break; } + break; } /* Apply basic rate */ for (i = 0; i < device_params->supportedratescount; i++) { - if (radiotype == CAPWAP_RADIO_TYPE_80211A) { - if (IS_IEEE80211_BASICRATE_A(device_params->supportedrates[i])) { - device_params->basicrates[device_params->basicratescount++] = device_params->supportedrates[i]; - device_params->supportedrates[i] |= IEEE80211_BASICRATE; - } - } else if (radiotype == CAPWAP_RADIO_TYPE_80211B) { - if (IS_IEEE80211_BASICRATE_B(device_params->supportedrates[i])) { - device_params->basicrates[device_params->basicratescount++] = device_params->supportedrates[i]; - device_params->supportedrates[i] |= IEEE80211_BASICRATE; - } - } else if (radiotype == CAPWAP_RADIO_TYPE_80211G) { - if (IS_IEEE80211_BASICRATE_G(device_params->supportedrates[i])) { - device_params->basicrates[device_params->basicratescount++] = device_params->supportedrates[i]; - device_params->supportedrates[i] |= IEEE80211_BASICRATE; - } + int is_basic = 0; + + switch (mode) { + case CAPWAP_RADIO_TYPE_80211A: + is_basic = IS_IEEE80211_BASICRATE_A(device_params->supportedrates[i]); + break; + + case CAPWAP_RADIO_TYPE_80211B: + is_basic = IS_IEEE80211_BASICRATE_B(device_params->supportedrates[i]); + break; + + case CAPWAP_RADIO_TYPE_80211G: + is_basic = IS_IEEE80211_BASICRATE_G(device_params->supportedrates[i]); + break; + + case CAPWAP_RADIO_TYPE_80211B | CAPWAP_RADIO_TYPE_80211G: + is_basic = IS_IEEE80211_BASICRATE_BG(device_params->supportedrates[i]); + break; + } + + if (is_basic) { + device_params->basicrates[device_params->basicratescount++] = + device_params->supportedrates[i]; + device_params->supportedrates[i] |= IEEE80211_BASICRATE; } } @@ -143,7 +162,9 @@ static void wifi_wlan_getrates(struct wifi_device* device, uint8_t* rates, int r capwap_logging_debug("getrates: Basic Rate %d: %d", i, device_params->basicrates[i]); } for (i = 0; i < device_params->supportedratescount; i++) { - capwap_logging_debug("getrates: Supported Rate %d: %d", i, device_params->supportedrates[i]); + log_printf(LOG_DEBUG, "getrates: Supported Rate %d: %.1f Mbit (%d)", + i, (device_params->supportedrates[i] * 5) / 10.0, + device_params->supportedrates[i]); } } diff --git a/src/wtp/wtp.c b/src/wtp/wtp.c index 014a602..a25b172 100644 --- a/src/wtp/wtp.c +++ b/src/wtp/wtp.c @@ -364,7 +364,7 @@ static int wtp_parsing_radio_configuration(config_setting_t* configElement, stru if ((count >= CAPWAP_SUPPORTEDRATES_MINLENGTH) && (count <= CAPWAP_SUPPORTEDRATES_MAXLENGTH)) { radio->supportedrates.supportedratescount = (uint8_t)count; for (i = 0; i < count; i++) { - int value = config_setting_get_int_elem(configItems, i); + int value = (config_setting_get_float_elem(configItems, i) * 10) / 5; if ((value >= 2) && (value <= 127)) { radio->supportedrates.supportedrates[i] = (uint8_t)value; } else {