scan: parse BSS_SIGNAL_UNSPEC, fix potential zero signal

A select few drivers send this instead of SIGNAL_MBM. The docs say this
value is the signal 'in unspecified units, scaled to 0..100'. The range
for SIGNAL_MBM is -10000..0 so this can be scaled to the MBM range easy
enough...

Now, this isn't exactly correct because this value ultimately gets
returned from GetOrderedNetworks() and is documented as 100 * dBm where
in reality its just a unit-less signal strength value. Its not ideal, but
this patch at least will fix BSS ranking for these few drivers.
This commit is contained in:
James Prestwood 2022-01-25 10:02:06 -08:00 committed by Denis Kenzior
parent 1284a6ca9f
commit 6ff99f1766
1 changed files with 23 additions and 0 deletions

View File

@ -1372,6 +1372,22 @@ static bool scan_parse_bss_information_elements(struct scan_bss *bss,
return have_ssid;
}
/*
* Maps 0..100 values to -10000..0
*
* This isn't really mapping to mBm since the input is unit-less and we have no
* idea what the driver itself does to come up with this 'strength' value but
* this is really the best that can be done for these drivers (its only 4 in
* tree drivers after all).
*/
static int32_t signal_unspec_to_mbm(uint8_t strength)
{
if (L_WARN_ON(strength > 100))
return 0;
return ((int32_t)strength * 100) - 10000;
}
static struct scan_bss *scan_parse_attr_bss(struct l_genl_attr *attr,
struct wiphy *wiphy,
uint32_t *out_seen_ms_ago)
@ -1414,6 +1430,13 @@ static struct scan_bss *scan_parse_attr_bss(struct l_genl_attr *attr,
bss->signal_strength = *((int32_t *) data);
break;
case NL80211_BSS_SIGNAL_UNSPEC:
if (len != 1)
goto fail;
bss->signal_strength =
signal_unspec_to_mbm(l_get_u8(data));
break;
case NL80211_BSS_INFORMATION_ELEMENTS:
ies = data;
ies_len = len;