merge: Wi-Fi band/channel locking fixes (bgo #627571)

- fixes value for 'freq_list' wpa_supplicant option
 - allows locking to a channel within a band
 - adds utility functions for getting Wi-Fi frequencies

https://bugzilla.gnome.org/show_bug.cgi?id=627571
This commit is contained in:
Jiří Klimeš 2015-08-21 09:58:44 +02:00
commit 7b47b5e740
4 changed files with 110 additions and 15 deletions

View file

@ -2692,6 +2692,61 @@ nm_utils_wifi_is_channel_valid (guint32 channel, const char *band)
return FALSE;
}
static const guint *
_wifi_freqs (gboolean bg_band)
{
static guint *freqs_2ghz = NULL;
static guint *freqs_5ghz = NULL;
guint *freqs;
freqs = bg_band ? freqs_2ghz : freqs_5ghz;
if (G_UNLIKELY (freqs == NULL)) {
struct cf_pair *table;
int i;
table = bg_band ? bg_table : a_table;
freqs = g_new0 (guint, bg_band ? G_N_ELEMENTS (bg_table) : G_N_ELEMENTS (a_table));
for (i = 0; table[i].chan; i++)
freqs[i] = table[i].freq;
freqs[i] = 0;
if (bg_band)
freqs_2ghz = freqs;
else
freqs_5ghz = freqs;
}
return freqs;
}
/**
* nm_utils_wifi_2ghz_freqs:
*
* Utility function to return 2.4 GHz Wi-Fi frequencies (802.11bg band).
*
* Returns: zero-terminated array of frequencies numbers (in MHz)
*
* Since: 1.0.6
**/
const guint *
nm_utils_wifi_2ghz_freqs (void)
{
return _wifi_freqs (TRUE);
}
/**
* nm_utils_wifi_5ghz_freqs:
*
* Utility function to return 5 GHz Wi-Fi frequencies (802.11a band).
*
* Returns: zero-terminated array of frequencies numbers (in MHz)
*
* Since: 1.0.6
**/
const guint *
nm_utils_wifi_5ghz_freqs (void)
{
return _wifi_freqs (FALSE);
}
/**
* nm_utils_wifi_strength_bars:
* @strength: the access point strength, from 0 to 100

View file

@ -140,6 +140,10 @@ guint32 nm_utils_wifi_freq_to_channel (guint32 freq);
guint32 nm_utils_wifi_channel_to_freq (guint32 channel, const char *band);
guint32 nm_utils_wifi_find_next_channel (guint32 channel, int direction, char *band);
gboolean nm_utils_wifi_is_channel_valid (guint32 channel, const char *band);
NM_AVAILABLE_IN_1_0_6
const guint *nm_utils_wifi_2ghz_freqs (void);
NM_AVAILABLE_IN_1_0_6
const guint *nm_utils_wifi_5ghz_freqs (void);
const char *nm_utils_wifi_strength_bars (guint8 strength);

View file

@ -859,5 +859,7 @@ global:
nm_device_wifi_request_scan_options_async;
nm_metered_get_type;
nm_setting_connection_get_metered;
nm_utils_wifi_2ghz_freqs;
nm_utils_wifi_5ghz_freqs;
} libnm_1_0_4;

View file

@ -308,12 +308,32 @@ nm_supplicant_config_get_blobs (NMSupplicantConfig * self)
return NM_SUPPLICANT_CONFIG_GET_PRIVATE (self)->blobs;
}
#define TWO_GHZ_FREQS "2412,2417,2422,2427,2432,2437,2442,2447,2452,2457,2462,2467,2472,2484"
#define FIVE_GHZ_FREQS "4915,4920,4925,4935,4940,4945,4960,4980,5035,5040,5045,5055,5060,5080," \
"5170,5180,5190,5200,5210,5220,5230,5240,5260,5280,5300,5320,5500," \
"5520,5540,5560,5580,5600,5620,5640,5660,5680,5700,5745,5765,5785," \
"5805,5825"
static const char *
wifi_freqs_to_string (gboolean bg_band)
{
static const char *str_2ghz = NULL;
static const char *str_5ghz = NULL;
const char *str;
str = bg_band ? str_2ghz : str_5ghz;
if (G_UNLIKELY (str == NULL)) {
GString *tmp;
const guint *freqs;
int i;
freqs = bg_band ? nm_utils_wifi_2ghz_freqs () : nm_utils_wifi_5ghz_freqs ();
tmp = g_string_sized_new (bg_band ? 70 : 225);
for (i = 0; freqs[i]; i++)
g_string_append_printf (tmp, i == 0 ? "%d" : " %d", freqs[i]);
str = g_string_free (tmp, FALSE);
if (bg_band)
str_2ghz = str;
else
str_5ghz = str;
}
return str;
}
gboolean
nm_supplicant_config_add_setting_wireless (NMSupplicantConfig * self,
@ -323,6 +343,7 @@ nm_supplicant_config_add_setting_wireless (NMSupplicantConfig * self,
NMSupplicantConfigPrivate *priv;
gboolean is_adhoc, is_ap;
const char *mode, *band;
guint32 channel;
GBytes *ssid;
const char *bssid;
@ -393,22 +414,35 @@ nm_supplicant_config_add_setting_wireless (NMSupplicantConfig * self,
}
band = nm_setting_wireless_get_band (setting);
channel = nm_setting_wireless_get_channel (setting);
if (band) {
const char *freqs = NULL;
if (channel) {
guint32 freq;
char *str_freq;
if (!strcmp (band, "a"))
freqs = FIVE_GHZ_FREQS;
else if (!strcmp (band, "bg"))
freqs = TWO_GHZ_FREQS;
freq = nm_utils_wifi_channel_to_freq (channel, band);
str_freq = g_strdup_printf ("%u", freq);
if (!nm_supplicant_config_add_option (self, "freq_list", str_freq, -1, FALSE)) {
g_free (str_freq);
nm_log_warn (LOGD_SUPPLICANT, "Error adding frequency list to supplicant config.");
return FALSE;
}
g_free (str_freq);
} else {
const char *freqs = NULL;
if (freqs && !nm_supplicant_config_add_option (self, "freq_list", freqs, strlen (freqs), FALSE)) {
nm_log_warn (LOGD_SUPPLICANT, "Error adding frequency list/band to supplicant config.");
return FALSE;
if (!strcmp (band, "a"))
freqs = wifi_freqs_to_string (FALSE);
else if (!strcmp (band, "bg"))
freqs = wifi_freqs_to_string (TRUE);
if (freqs && !nm_supplicant_config_add_option (self, "freq_list", freqs, strlen (freqs), FALSE)) {
nm_log_warn (LOGD_SUPPLICANT, "Error adding frequency list/band to supplicant config.");
return FALSE;
}
}
}
// FIXME: channel config item
return TRUE;
}