3
0
mirror of https://git.kernel.org/pub/scm/network/wireless/iwd.git synced 2024-10-04 02:18:49 +02:00

scan: rework BSS ranking

It was observed that IWD's ranking for BSS's did not always
end up with the fastest being chosen. This was due to IWD's
heavy weight on signal strength. This is a decent way of ranking
but even better is calculating a theoretical data rate which
was also done and factored in. The problem is the data rate
factor was always outdone by the signal strength.

Intead remove signal strength entirely as this is already taken
into account with the data rate calculation. This also removes
the check for rate IEs. If no IEs are found the parser will
base the data rate soley on RSSI.

There were a few other factors removed which will be added back
when ranking *networks* rather than BSS's. WPA version (or open)
was removed as well as the privacy capability. These values really
should not differ between BSS's in the same SSID and as such
should be used for network ranking instead.
This commit is contained in:
James Prestwood 2021-05-07 13:26:15 -07:00 committed by Denis Kenzior
parent 2ecf5ff0d7
commit 3fde169001

View File

@ -1326,39 +1326,31 @@ static struct scan_bss *scan_parse_result(struct l_genl_msg *msg,
static void scan_bss_compute_rank(struct scan_bss *bss)
{
static const double RANK_RSNE_FACTOR = 1.2;
static const double RANK_WPA_FACTOR = 1.0;
static const double RANK_OPEN_FACTOR = 0.5;
static const double RANK_NO_PRIVACY_FACTOR = 0.5;
static const double RANK_HIGH_UTILIZATION_FACTOR = 0.8;
static const double RANK_LOW_UTILIZATION_FACTOR = 1.2;
static const double RANK_MIN_SUPPORTED_RATE_FACTOR = 0.6;
static const double RANK_MAX_SUPPORTED_RATE_FACTOR = 1.3;
double rank;
uint32_t irank;
uint64_t data_rate;
/*
* Maximum rate is 2340Mbps (VHT)
*/
uint64_t max_rate = 2340000000U;
/*
* Signal strength is in mBm (100 * dBm) and is negative.
* WiFi range is -0 to -100 dBm
* If parsing fails choose a very low data rate as its unknown what
* this AP supports or why its IEs did not parse. Likely not an AP
* we should prefer to connect to.
*/
if (ie_parse_data_rates(bss->has_sup_rates ?
bss->supp_rates_ie : NULL,
bss->ext_supp_rates_ie,
bss->ht_capable ? bss->ht_ie : NULL,
bss->vht_capable ? bss->vht_ie : NULL,
bss->signal_strength / 100,
&data_rate) != 0)
data_rate = 2000000;
/* Heavily slanted towards signal strength */
rank = 10000 + bss->signal_strength;
/*
* Prefer RSNE first, WPA second. Open networks are much less
* desirable.
*/
if (bss->rsne)
rank *= RANK_RSNE_FACTOR;
else if (bss->wpa)
rank *= RANK_WPA_FACTOR;
else
rank *= RANK_OPEN_FACTOR;
/* We prefer networks with CAP PRIVACY */
if (!(bss->capability & IE_BSS_CAP_PRIVACY))
rank *= RANK_NO_PRIVACY_FACTOR;
rank = (double)data_rate / (double)max_rate * USHRT_MAX;
/* Prefer 5G networks over 2.4G */
if (bss->frequency > 4000)
@ -1370,29 +1362,6 @@ static void scan_bss_compute_rank(struct scan_bss *bss)
else if (bss->utilization <= 63)
rank *= RANK_LOW_UTILIZATION_FACTOR;
if (bss->has_sup_rates || bss->ext_supp_rates_ie) {
uint64_t data_rate;
if (ie_parse_data_rates(bss->has_sup_rates ?
bss->supp_rates_ie : NULL,
bss->ext_supp_rates_ie,
bss->ht_capable ? bss->ht_ie : NULL,
bss->vht_capable ? bss->vht_ie : NULL,
bss->signal_strength / 100,
&data_rate) == 0) {
double factor = RANK_MAX_SUPPORTED_RATE_FACTOR -
RANK_MIN_SUPPORTED_RATE_FACTOR;
/*
* Maximum rate is 2340Mbps (VHT)
*/
factor = factor * data_rate / 2340000000U +
RANK_MIN_SUPPORTED_RATE_FACTOR;
rank *= factor;
} else
rank *= RANK_MIN_SUPPORTED_RATE_FACTOR;
}
irank = rank;
if (irank > USHRT_MAX)