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.
This commit is contained in:
Andreas Schultz 2016-02-29 14:26:13 +01:00
parent 3bfd0c5642
commit 9fee37a994
3 changed files with 53 additions and 31 deletions

View File

@ -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 */

View File

@ -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]);
}
}

View File

@ -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 {