wifi: fix scanned signal strength calculation for WEXT-based drivers
The new wpa_supplicant D-Bus interface only passes back the 'level' of the scanned BSS, which with nl80211 drivers is almost always dBm, which NM handled fine. But WEXT-based drivers (ipw2x00, other older ones, and some vendor drivers) use a mix of values for the 'level' parameter, including the old WEXT 8-bit signed-value-in-unsigned-int scheme. Handle that. Alternatively, we could have the supplicant expose the 'flags' value from its internal BSS list over the bus.
This commit is contained in:
@@ -18,7 +18,9 @@
|
||||
* (C) Copyright 2011 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "nm-wifi-ap-utils.h"
|
||||
|
||||
@@ -706,3 +708,24 @@ nm_ap_utils_complete_connection (const GByteArray *ap_ssid,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
guint32
|
||||
nm_ap_utils_level_to_quality (gint val)
|
||||
{
|
||||
if (val < 0) {
|
||||
/* Assume dBm already; rough conversion: best = -40, worst = -100 */
|
||||
val = abs (CLAMP (val, -100, -40) + 40); /* normalize to 0 */
|
||||
val = 100 - (int) ((100.0 * (double) val) / 60.0);
|
||||
} else if (val > 110 && val < 256) {
|
||||
/* assume old-style WEXT 8-bit unsigned signal level */
|
||||
val -= 256; /* subtract 256 to convert to dBm */
|
||||
val = abs (CLAMP (val, -100, -40) + 40); /* normalize to 0 */
|
||||
val = 100 - (int) ((100.0 * (double) val) / 60.0);
|
||||
} else {
|
||||
/* Assume signal is a "quality" percentage */
|
||||
val = CLAMP (val, 0, 100);
|
||||
}
|
||||
g_assert (val >= 0);
|
||||
|
||||
return (guint32) val;
|
||||
}
|
||||
|
||||
|
@@ -39,5 +39,7 @@ gboolean nm_ap_utils_complete_connection (const GByteArray *ssid,
|
||||
gboolean lock_bssid,
|
||||
GError **error);
|
||||
|
||||
guint32 nm_ap_utils_level_to_quality (gint val);
|
||||
|
||||
#endif /* NM_WIFI_AP_UTILS_H */
|
||||
|
||||
|
@@ -500,16 +500,8 @@ foreach_property_cb (gpointer key, gpointer value, gpointer user_data)
|
||||
} else if (G_VALUE_HOLDS_INT (variant)) {
|
||||
gint val = g_value_get_int (variant);
|
||||
|
||||
if (!strcmp (key, "Signal")) {
|
||||
if (val < 0) {
|
||||
/* Rough conversion: best = -40, worst = -100 */
|
||||
val = abs (CLAMP (val, -100, -40) + 40);
|
||||
val = 100 - (int) ((100.0 * (double) val) / 60.0);
|
||||
} else
|
||||
val /= 100;
|
||||
|
||||
nm_ap_set_strength (ap, val);
|
||||
}
|
||||
if (!strcmp (key, "Signal"))
|
||||
nm_ap_set_strength (ap, nm_ap_utils_level_to_quality (val));
|
||||
} else if (G_VALUE_HOLDS_STRING (variant)) {
|
||||
const char *val = g_value_get_string (variant);
|
||||
|
||||
|
@@ -1238,6 +1238,57 @@ test_wpa_ap_wpa_psk_connection_5 (guint idx)
|
||||
|
||||
/*******************************************/
|
||||
|
||||
static void
|
||||
test_strength_dbm (void)
|
||||
{
|
||||
/* boundary conditions first */
|
||||
g_assert_cmpint (nm_ap_utils_level_to_quality (-1), ==, 100);
|
||||
g_assert_cmpint (nm_ap_utils_level_to_quality (-40), ==, 100);
|
||||
g_assert_cmpint (nm_ap_utils_level_to_quality (-30), ==, 100);
|
||||
g_assert_cmpint (nm_ap_utils_level_to_quality (-100), ==, 0);
|
||||
g_assert_cmpint (nm_ap_utils_level_to_quality (-200), ==, 0);
|
||||
|
||||
g_assert_cmpint (nm_ap_utils_level_to_quality (-81), ==, 32);
|
||||
g_assert_cmpint (nm_ap_utils_level_to_quality (-92), ==, 14);
|
||||
g_assert_cmpint (nm_ap_utils_level_to_quality (-74), ==, 44);
|
||||
g_assert_cmpint (nm_ap_utils_level_to_quality (-81), ==, 32);
|
||||
g_assert_cmpint (nm_ap_utils_level_to_quality (-66), ==, 57);
|
||||
}
|
||||
|
||||
static void
|
||||
test_strength_percent (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* boundary conditions first */
|
||||
g_assert_cmpint (nm_ap_utils_level_to_quality (0), ==, 0);
|
||||
g_assert_cmpint (nm_ap_utils_level_to_quality (100), ==, 100);
|
||||
g_assert_cmpint (nm_ap_utils_level_to_quality (110), ==, 100);
|
||||
|
||||
for (i = 0; i <= 100; i++)
|
||||
g_assert_cmpint (nm_ap_utils_level_to_quality (i), ==, i);
|
||||
}
|
||||
|
||||
static void
|
||||
test_strength_wext (void)
|
||||
{
|
||||
/* boundary conditions that we assume aren't WEXT first */
|
||||
g_assert_cmpint (nm_ap_utils_level_to_quality (256), ==, 100);
|
||||
g_assert_cmpint (nm_ap_utils_level_to_quality (110), ==, 100);
|
||||
|
||||
/* boundary conditions that we assume are WEXT */
|
||||
g_assert_cmpint (nm_ap_utils_level_to_quality (111), ==, 0);
|
||||
g_assert_cmpint (nm_ap_utils_level_to_quality (150), ==, 0);
|
||||
g_assert_cmpint (nm_ap_utils_level_to_quality (225), ==, 100);
|
||||
g_assert_cmpint (nm_ap_utils_level_to_quality (255), ==, 100);
|
||||
|
||||
g_assert_cmpint (nm_ap_utils_level_to_quality (157), ==, 2);
|
||||
g_assert_cmpint (nm_ap_utils_level_to_quality (200), ==, 74);
|
||||
g_assert_cmpint (nm_ap_utils_level_to_quality (215), ==, 99);
|
||||
}
|
||||
|
||||
/*******************************************/
|
||||
|
||||
#if GLIB_CHECK_VERSION(2,25,12)
|
||||
typedef GTestFixtureFunc TCFunc;
|
||||
#else
|
||||
@@ -1339,6 +1390,11 @@ int main (int argc, char **argv)
|
||||
g_test_suite_add (suite, TESTCASE (test_ap_wpa_eap_connection_4, IDX_RSN_PSK));
|
||||
g_test_suite_add (suite, TESTCASE (test_ap_wpa_eap_connection_5, IDX_RSN_PSK));
|
||||
|
||||
/* Scanned signal strength conversion tests */
|
||||
g_test_suite_add (suite, TESTCASE (test_strength_dbm, NULL));
|
||||
g_test_suite_add (suite, TESTCASE (test_strength_percent, NULL));
|
||||
g_test_suite_add (suite, TESTCASE (test_strength_wext, NULL));
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user