libnm-util: add nm_utils_wifi_* functions to handle frequencies/channels

This commit is contained in:
Jiří Klimeš 2010-05-31 15:32:13 +02:00
parent 6810ef1422
commit 12d26643e9
7 changed files with 236 additions and 152 deletions

View file

@ -59,7 +59,7 @@ libnm_util_la_SOURCES= \
libnm_util_la_LIBADD = $(GLIB_LIBS) $(DBUS_LIBS) $(UUID_LIBS)
libnm_util_la_LDFLAGS = -Wl,--version-script=$(srcdir)/libnm-util.ver \
-version-info "4:4:3"
-version-info "5:0:4"
if WITH_GNUTLS
libnm_util_la_SOURCES += crypto_gnutls.c

View file

@ -365,6 +365,10 @@ global:
nm_utils_ssid_to_utf8;
nm_utils_uuid_generate;
nm_utils_uuid_generate_from_string;
nm_utils_wifi_freq_to_channel;
nm_utils_wifi_channel_to_freq;
nm_utils_wifi_find_next_channel;
nm_utils_wifi_is_channel_valid;
nm_ip4_address_compare;
nm_ip4_address_dup;
nm_ip4_address_get_address;

View file

@ -19,7 +19,7 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
* (C) Copyright 2007 - 2008 Red Hat, Inc.
* (C) Copyright 2007 - 2010 Red Hat, Inc.
* (C) Copyright 2007 - 2008 Novell, Inc.
*/
@ -480,31 +480,11 @@ verify (NMSetting *setting, GSList *all_settings, GError **error)
}
if (priv->channel) {
if (!strcmp (priv->band, "a")) {
int i;
int valid_channels[] = { 7, 8, 9, 11, 12, 16, 34, 36, 40, 44, 48,
52, 56, 60, 64, 100, 104, 108, 112, 116,
120, 124, 128, 132, 136, 140, 149, 153,
157, 161, 165, 183, 184, 185, 187, 188,
192, 196, 0 };
for (i = 0; valid_channels[i]; i++) {
if (priv->channel == valid_channels[i])
break;
}
if (valid_channels[i] == 0) {
g_set_error (error,
NM_SETTING_WIRELESS_ERROR,
NM_SETTING_WIRELESS_ERROR_INVALID_PROPERTY,
NM_SETTING_WIRELESS_CHANNEL);
return FALSE;
}
} else if (!strcmp (priv->band, "bg") && priv->channel > 14) {
g_set_error (error,
NM_SETTING_WIRELESS_ERROR,
NM_SETTING_WIRELESS_ERROR_INVALID_PROPERTY,
NM_SETTING_WIRELESS_CHANNEL);
if (!nm_utils_wifi_is_channel_valid (priv->channel, priv->band)) {
g_set_error (error,
NM_SETTING_WIRELESS_ERROR,
NM_SETTING_WIRELESS_ERROR_INVALID_PROPERTY,
NM_SETTING_WIRELESS_CHANNEL);
return FALSE;
}
}

View file

@ -117,7 +117,7 @@ static const struct IsoLangToEncodings isoLangEntries2[] =
/* Arabic */
{ "ar", {"iso-8859-6", "windows-1256", NULL} },
/* Balitc */
/* Baltic */
{ "et", {"iso-8859-4", "windows-1257", NULL} }, /* Estonian */
{ "lt", {"iso-8859-4", "windows-1257", NULL} }, /* Lithuanian */
{ "lv", {"iso-8859-4", "windows-1257", NULL} }, /* Latvian */
@ -2102,3 +2102,212 @@ out:
return ret;
}
/* Band, channel/frequency stuff for wireless */
struct cf_pair {
guint32 chan;
guint32 freq;
};
static struct cf_pair a_table[] = {
/* A band */
{ 7, 5035 },
{ 8, 5040 },
{ 9, 5045 },
{ 11, 5055 },
{ 12, 5060 },
{ 16, 5080 },
{ 34, 5170 },
{ 36, 5180 },
{ 38, 5190 },
{ 40, 5200 },
{ 42, 5210 },
{ 44, 5220 },
{ 46, 5230 },
{ 48, 5240 },
{ 50, 5250 },
{ 52, 5260 },
{ 56, 5280 },
{ 58, 5290 },
{ 60, 5300 },
{ 64, 5320 },
{ 100, 5500 },
{ 104, 5520 },
{ 108, 5540 },
{ 112, 5560 },
{ 116, 5580 },
{ 120, 5600 },
{ 124, 5620 },
{ 128, 5640 },
{ 132, 5660 },
{ 136, 5680 },
{ 140, 5700 },
{ 149, 5745 },
{ 152, 5760 },
{ 153, 5765 },
{ 157, 5785 },
{ 160, 5800 },
{ 161, 5805 },
{ 165, 5825 },
{ 183, 4915 },
{ 184, 4920 },
{ 185, 4925 },
{ 187, 4935 },
{ 188, 4945 },
{ 192, 4960 },
{ 196, 4980 },
{ 0, -1 }
};
static struct cf_pair bg_table[] = {
/* B/G band */
{ 1, 2412 },
{ 2, 2417 },
{ 3, 2422 },
{ 4, 2427 },
{ 5, 2432 },
{ 6, 2437 },
{ 7, 2442 },
{ 8, 2447 },
{ 9, 2452 },
{ 10, 2457 },
{ 11, 2462 },
{ 12, 2467 },
{ 13, 2472 },
{ 14, 2484 },
{ 0, -1 }
};
/**
* nm_utils_wifi_freq_to_channel:
* @freq: frequency
*
* Utility function to translate a WiFi frequency to its corresponding channel.
*
* Returns: the channel represented by the frequency or 0
**/
guint32
nm_utils_wifi_freq_to_channel (guint32 freq)
{
int i = 0;
if (freq > 4900) {
while (a_table[i].chan && (a_table[i].freq != freq))
i++;
return a_table[i].chan;
} else {
while (bg_table[i].chan && (bg_table[i].freq != freq))
i++;
return bg_table[i].chan;
}
return 0;
}
/**
* nm_utils_wifi_channel_to_freq:
* @channel: channel
* @band: frequency band for wireless ("a" or "bg")
*
* Utility function to translate a WiFi channel to its corresponding frequency.
*
* Returns: the frequency represented by the channel of the band,
* or -1 when the freq is invalid, or 0 when the band
* is invalid
**/
guint32
nm_utils_wifi_channel_to_freq (guint32 channel, const char *band)
{
int i = 0;
if (!strcmp (band, "a")) {
while (a_table[i].chan && (a_table[i].chan != channel))
i++;
return a_table[i].freq;
} else if (!strcmp (band, "bg")) {
while (bg_table[i].chan && (bg_table[i].chan != channel))
i++;
return bg_table[i].freq;
}
return 0;
}
/**
* nm_utils_wifi_find_next_channel:
* @channel: current channel
* @direction: whether going downward (0 or less) or upward (1 or more)
* @band: frequency band for wireless ("a" or "bg")
*
* Utility function to find out next/previous WiFi channel for a channel.
*
* Returns: the next channel in the specified direction or 0
**/
guint32
nm_utils_wifi_find_next_channel (guint32 channel, int direction, char *band)
{
size_t a_size = sizeof (a_table) / sizeof (struct cf_pair);
size_t bg_size = sizeof (bg_table) / sizeof (struct cf_pair);
struct cf_pair *pair = NULL;
if (!strcmp (band, "a")) {
if (channel < a_table[0].chan)
return a_table[0].chan;
if (channel > a_table[a_size - 2].chan)
return a_table[a_size - 2].chan;
pair = &a_table[0];
} else if (!strcmp (band, "bg")) {
if (channel < bg_table[0].chan)
return bg_table[0].chan;
if (channel > bg_table[bg_size - 2].chan)
return bg_table[bg_size - 2].chan;
pair = &bg_table[0];
} else {
g_assert_not_reached ();
return 0;
}
while (pair->chan) {
if (channel == pair->chan)
return channel;
if ((channel < (pair+1)->chan) && (channel > pair->chan)) {
if (direction > 0)
return (pair+1)->chan;
else
return pair->chan;
}
pair++;
}
return 0;
}
/**
* nm_utils_wifi_is_channel_valid:
* @channel: channel
* @band: frequency band for wireless ("a" or "bg")
*
* Utility function to verify WiFi channel validity.
*
* Returns: TRUE or FALSE
**/
gboolean
nm_utils_wifi_is_channel_valid (guint32 channel, const char *band)
{
struct cf_pair *table = NULL;
int i = 0;
if (!strcmp (band, "a"))
table = a_table;
else if (!strcmp (band, "bg"))
table = bg_table;
else
return FALSE;
while (table[i].chan && (table[i].chan != channel))
i++;
if (table[i].chan != 0)
return TRUE;
else
return FALSE;
}

View file

@ -215,4 +215,9 @@ GByteArray *nm_utils_rsa_key_encrypt (const GByteArray *data,
G_END_DECLS
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);
#endif /* NM_UTILS_H */

View file

@ -15,7 +15,7 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright (C) 2004 - 2008 Red Hat, Inc.
* Copyright (C) 2004 - 2010 Red Hat, Inc.
* Copyright (C) 2006 - 2008 Novell, Inc.
*/
@ -604,7 +604,7 @@ nm_ap_new_fake_from_connection (NMConnection *connection)
channel = nm_setting_wireless_get_channel (s_wireless);
if (band && channel) {
guint32 freq = channel_to_freq (channel, band);
guint32 freq = nm_utils_wifi_channel_to_freq (channel, band);
if (freq == 0)
goto error;
@ -1256,21 +1256,21 @@ nm_ap_check_compatible (NMAccessPoint *self,
channel = nm_setting_wireless_get_channel (s_wireless);
if (channel) {
guint32 ap_chan = freq_to_channel (priv->freq);
guint32 ap_chan = nm_utils_wifi_freq_to_channel (priv->freq);
if (channel != ap_chan)
return FALSE;
}
s_wireless_sec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection,
NM_TYPE_SETTING_WIRELESS_SECURITY);
NM_TYPE_SETTING_WIRELESS_SECURITY);
return nm_setting_wireless_ap_security_compatible (s_wireless,
s_wireless_sec,
nm_ap_get_flags (self),
nm_ap_get_wpa_flags (self),
nm_ap_get_rsn_flags (self),
nm_ap_get_mode (self));
s_wireless_sec,
nm_ap_get_flags (self),
nm_ap_get_wpa_flags (self),
nm_ap_get_rsn_flags (self),
nm_ap_get_mode (self));
}
static gboolean
@ -1364,114 +1364,3 @@ nm_ap_match_in_list (NMAccessPoint *find_ap,
return NULL;
}
struct cf_pair {
guint32 chan;
guint32 freq;
};
static struct cf_pair a_table[] = {
/* A band */
{ 7, 5035 },
{ 8, 5040 },
{ 9, 5045 },
{ 11, 5055 },
{ 12, 5060 },
{ 16, 5080 },
{ 34, 5170 },
{ 36, 5180 },
{ 38, 5190 },
{ 40, 5200 },
{ 42, 5210 },
{ 44, 5220 },
{ 46, 5230 },
{ 48, 5240 },
{ 50, 5250 },
{ 52, 5260 },
{ 56, 5280 },
{ 58, 5290 },
{ 60, 5300 },
{ 64, 5320 },
{ 100, 5500 },
{ 104, 5520 },
{ 108, 5540 },
{ 112, 5560 },
{ 116, 5580 },
{ 120, 5600 },
{ 124, 5620 },
{ 128, 5640 },
{ 132, 5660 },
{ 136, 5680 },
{ 140, 5700 },
{ 149, 5745 },
{ 152, 5760 },
{ 153, 5765 },
{ 157, 5785 },
{ 160, 5800 },
{ 161, 5805 },
{ 165, 5825 },
{ 183, 4915 },
{ 184, 4920 },
{ 185, 4925 },
{ 187, 4935 },
{ 188, 4945 },
{ 192, 4960 },
{ 196, 4980 },
{ 0, -1 }
};
static struct cf_pair bg_table[] = {
/* B/G band */
{ 1, 2412 },
{ 2, 2417 },
{ 3, 2422 },
{ 4, 2427 },
{ 5, 2432 },
{ 6, 2437 },
{ 7, 2442 },
{ 8, 2447 },
{ 9, 2452 },
{ 10, 2457 },
{ 11, 2462 },
{ 12, 2467 },
{ 13, 2472 },
{ 14, 2484 },
{ 0, -1 }
};
guint32
freq_to_channel (guint32 freq)
{
int i = 0;
if (freq > 4900) {
while (a_table[i].chan && (a_table[i].freq != freq))
i++;
return a_table[i].chan;
} else {
while (bg_table[i].chan && (bg_table[i].freq != freq))
i++;
return bg_table[i].chan;
}
return 0;
}
guint32
channel_to_freq (guint32 channel, const char *band)
{
int i = 0;
if (!strcmp (band, "a")) {
while (a_table[i].chan && (a_table[i].chan != channel))
i++;
return a_table[i].freq;
} else if (!strcmp (band, "bg")) {
while (bg_table[i].chan && (bg_table[i].chan != channel))
i++;
return bg_table[i].freq;
}
return 0;
}

View file

@ -15,7 +15,7 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright (C) 2004 - 2008 Red Hat, Inc.
* Copyright (C) 2004 - 2010 Red Hat, Inc.
* Copyright (C) 2006 - 2008 Novell, Inc.
*/
@ -123,7 +123,4 @@ NMAccessPoint * nm_ap_match_in_list (NMAccessPoint *find_ap,
void nm_ap_print_self (NMAccessPoint *ap, const char * prefix);
guint32 freq_to_channel (guint32 freq);
guint32 channel_to_freq (guint32 channel, const char *band);
#endif /* NM_ACCESS_POINT_H */