2005-01-31 Dan Williams <dcbw@redhat.com>

* info-daemon/NetworkManagerInfoDbus.c
		- (nmi_dbus_nmi_message_handler): make sure 'dialog' exists before using it

	* src/NetworkManagerDevice.c
		- (nm_device_new): Don't store the entire range struct, use only what we need
			(which is currently avg_quality, max_quality, and frequencies).  Also
			zero device structure when we've free'd it to maybe expose errors down
			the line.
		- (nm_device_update_signal_strength): grab the scan mutex before getting
			quality data from the card since quality will be useless during a scan.
			Call updated wireless qual-to-percent function with values stored in
			nm_device_new() earlier.
		- Remove some unused functions (nm_device_get_max_quality(), nm_device_get_noise(),
			nm_device_get_bad_crypt_packets())
		- (nm_device_activate_wireless_adhoc): use new frequency values we go in
			nm_device_new()
		- (get_initial_auth_method): always use the Auth method that's in the allowed
			list if available.  Problem was this: when the WEP key is wrong, NM will
			try OS then SK modes, and then get stuck in SK mode after that.  This
			should reset it.
		- (nm_device_wireless_process_scan_results): work with new qual-to-percent
			function

	* src/NetworkManagerWireless.c
		- (nm_wireless_qual_to_percent): try to make this function actually work and
			mimic iwlib behavior.  Use card's idea of quality divided by max_qual
			if that's all present, otherwise fall back to signal-to-noise ratios.


git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@402 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
This commit is contained in:
Dan Williams
2005-01-31 19:53:38 +00:00
parent 2827e5129c
commit 4f28a1ce27
8 changed files with 136 additions and 138 deletions

View File

@@ -1,3 +1,33 @@
2005-01-31 Dan Williams <dcbw@redhat.com>
* info-daemon/NetworkManagerInfoDbus.c
- (nmi_dbus_nmi_message_handler): make sure 'dialog' exists before using it
* src/NetworkManagerDevice.c
- (nm_device_new): Don't store the entire range struct, use only what we need
(which is currently avg_quality, max_quality, and frequencies). Also
zero device structure when we've free'd it to maybe expose errors down
the line.
- (nm_device_update_signal_strength): grab the scan mutex before getting
quality data from the card since quality will be useless during a scan.
Call updated wireless qual-to-percent function with values stored in
nm_device_new() earlier.
- Remove some unused functions (nm_device_get_max_quality(), nm_device_get_noise(),
nm_device_get_bad_crypt_packets())
- (nm_device_activate_wireless_adhoc): use new frequency values we go in
nm_device_new()
- (get_initial_auth_method): always use the Auth method that's in the allowed
list if available. Problem was this: when the WEP key is wrong, NM will
try OS then SK modes, and then get stuck in SK mode after that. This
should reset it.
- (nm_device_wireless_process_scan_results): work with new qual-to-percent
function
* src/NetworkManagerWireless.c
- (nm_wireless_qual_to_percent): try to make this function actually work and
mimic iwlib behavior. Use card's idea of quality divided by max_qual
if that's all present, otherwise fall back to signal-to-noise ratios.
2005-01-29 Dan Williams <dcbw@redhat.com> 2005-01-29 Dan Williams <dcbw@redhat.com>
* initscript/RedHat/NetworkManager * initscript/RedHat/NetworkManager

View File

@@ -665,13 +665,13 @@ static DBusHandlerResult nmi_dbus_nmi_message_handler (DBusConnection *connectio
if (strcmp ("getKeyForNetwork", method) == 0) if (strcmp ("getKeyForNetwork", method) == 0)
{ {
GtkWidget *dialog = glade_xml_get_widget (info->passphrase_dialog, "passphrase_dialog"); GtkWidget *dialog = glade_xml_get_widget (info->passphrase_dialog, "passphrase_dialog");
if (!GTK_WIDGET_VISIBLE (dialog)) if (dialog && !GTK_WIDGET_VISIBLE (dialog))
nmi_dbus_get_key_for_network (info, message); nmi_dbus_get_key_for_network (info, message);
} }
else if (strcmp ("cancelGetKeyForNetwork", method) == 0) else if (strcmp ("cancelGetKeyForNetwork", method) == 0)
{ {
GtkWidget *dialog = glade_xml_get_widget (info->passphrase_dialog, "passphrase_dialog"); GtkWidget *dialog = glade_xml_get_widget (info->passphrase_dialog, "passphrase_dialog");
if (GTK_WIDGET_VISIBLE (dialog)) if (dialog && GTK_WIDGET_VISIBLE (dialog))
nmi_passphrase_dialog_cancel (info); nmi_passphrase_dialog_cancel (info);
} }
else if (strcmp ("getVPNUserPass", method) == 0) else if (strcmp ("getVPNUserPass", method) == 0)

View File

@@ -102,6 +102,7 @@ NMDevice * nm_create_device_and_add_to_list (NMData *data, const char *udi, cons
g_return_val_if_fail (data != NULL, NULL); g_return_val_if_fail (data != NULL, NULL);
g_return_val_if_fail (udi != NULL, NULL); g_return_val_if_fail (udi != NULL, NULL);
g_return_val_if_fail (iface != NULL, NULL); g_return_val_if_fail (iface != NULL, NULL);
g_return_val_if_fail (strlen (iface) > 0, NULL);
/* If we are called to create a test devices, but test devices weren't enabled /* If we are called to create a test devices, but test devices weren't enabled
* on the command-line, don't create the device. * on the command-line, don't create the device.

View File

@@ -225,7 +225,7 @@ NMDevice *nm_device_new (const char *iface, const char *udi, gboolean test_dev,
return (NULL); return (NULL);
} }
dev = g_new0 (NMDevice, 1); dev = g_malloc0 (sizeof (NMDevice));
if (!dev) if (!dev)
{ {
syslog (LOG_ERR, "nm_device_new() could not allocate a new device... Not enough memory?"); syslog (LOG_ERR, "nm_device_new() could not allocate a new device... Not enough memory?");
@@ -253,7 +253,6 @@ NMDevice *nm_device_new (const char *iface, const char *udi, gboolean test_dev,
/* Initialize wireless-specific options */ /* Initialize wireless-specific options */
if (nm_device_is_wireless (dev)) if (nm_device_is_wireless (dev))
{ {
iwrange range;
int sk; int sk;
dev->options.wireless.scan_interval = 20; dev->options.wireless.scan_interval = 20;
@@ -286,8 +285,25 @@ NMDevice *nm_device_new (const char *iface, const char *udi, gboolean test_dev,
if ((sk = iw_sockets_open ()) >= 0) if ((sk = iw_sockets_open ()) >= 0)
{ {
if (iw_get_range_info (sk, nm_device_get_iface (dev), &(dev->options.wireless.range_info)) == -1) iwrange range;
memset (&(dev->options.wireless.range_info), 0, sizeof (struct iw_range)); if (iw_get_range_info (sk, nm_device_get_iface (dev), &range) >= 0)
{
int i;
dev->options.wireless.max_qual.qual = range.max_qual.qual;
dev->options.wireless.max_qual.level = range.max_qual.level;
dev->options.wireless.max_qual.noise = range.max_qual.noise;
dev->options.wireless.max_qual.updated = range.max_qual.updated;
dev->options.wireless.avg_qual.qual = range.avg_qual.qual;
dev->options.wireless.avg_qual.level = range.avg_qual.level;
dev->options.wireless.avg_qual.noise = range.avg_qual.noise;
dev->options.wireless.avg_qual.updated = range.avg_qual.updated;
dev->options.wireless.num_freqs = MIN (range.num_frequency, IW_MAX_FREQUENCIES);
for (i = 0; i < dev->options.wireless.num_freqs; i++)
dev->options.wireless.freqs[i] = iw_freq2float (&(range.freq[i]));
}
close (sk); close (sk);
} }
} }
@@ -365,7 +381,6 @@ gboolean nm_device_unref (NMDevice *dev)
if (nm_device_is_wireless (dev)) if (nm_device_is_wireless (dev))
{ {
nm_device_ap_list_clear (dev); nm_device_ap_list_clear (dev);
dev->options.wireless.ap_list = NULL;
g_mutex_free (dev->options.wireless.scan_mutex); g_mutex_free (dev->options.wireless.scan_mutex);
if (dev->options.wireless.ap_list) if (dev->options.wireless.ap_list)
@@ -376,9 +391,8 @@ gboolean nm_device_unref (NMDevice *dev)
} }
g_free (dev->udi); g_free (dev->udi);
dev->udi = NULL;
g_free (dev->iface); g_free (dev->iface);
dev->iface = NULL; memset (dev, 0, sizeof (NMDevice));
g_free (dev); g_free (dev);
deleted = TRUE; deleted = TRUE;
} }
@@ -525,7 +539,7 @@ gint nm_device_get_association_pause_value (NMDevice *dev)
* has to scan all channels to find our requested AP (which can take a long time * has to scan all channels to find our requested AP (which can take a long time
* if it is an A/B/G chipset like the Atheros 5212, for example). * if it is an A/B/G chipset like the Atheros 5212, for example).
*/ */
if (dev->options.wireless.range_info.num_frequency > 14) if (dev->options.wireless.num_freqs > 14)
return 10; return 10;
else else
return 5; return 5;
@@ -1049,7 +1063,7 @@ int nm_device_get_bitrate (NMDevice *dev)
g_return_val_if_fail (dev != NULL, 0); g_return_val_if_fail (dev != NULL, 0);
g_return_val_if_fail (nm_device_is_wireless (dev), 0); g_return_val_if_fail (nm_device_is_wireless (dev), 0);
/* Test devices don't really have a frequency, they always succeed */ /* Test devices don't really have a bitrate, they always succeed */
if (dev->test_device) if (dev->test_device)
return 11; return 11;
@@ -1275,36 +1289,32 @@ void nm_device_update_signal_strength (NMDevice *dev)
g_return_if_fail (nm_device_is_wireless (dev)); g_return_if_fail (nm_device_is_wireless (dev));
g_return_if_fail (dev->app_data != NULL); g_return_if_fail (dev->app_data != NULL);
/* Grab the scan lock since our strength is meaningless during a scan. */
if (!nm_try_acquire_mutex (dev->options.wireless.scan_mutex, __FUNCTION__))
return;
/* If we aren't the active device, we don't really have a signal strength /* If we aren't the active device, we don't really have a signal strength
* that would mean anything. * that would mean anything.
*/ */
if (dev != dev->app_data->active_device) if (dev != dev->app_data->active_device)
{ {
dev->options.wireless.strength = -1; dev->options.wireless.strength = -1;
return; goto out;
} }
/* Fake a value for test devices */ /* Fake a value for test devices */
if (dev->test_device) if (dev->test_device)
{ {
dev->options.wireless.strength = 75; dev->options.wireless.strength = 75;
return; goto out;
} }
sk = iw_sockets_open (); sk = iw_sockets_open ();
has_range = (iw_get_range_info (sk, nm_device_get_iface (dev), &range) >= 0); has_range = (iw_get_range_info (sk, nm_device_get_iface (dev), &range) >= 0);
if (iw_get_stats (sk, nm_device_get_iface (dev), &stats, &range, has_range) == 0) if (iw_get_stats (sk, nm_device_get_iface (dev), &stats, &range, has_range) == 0)
{ {
/* Update our max quality while we're at it */ percent = nm_wireless_qual_to_percent (&stats.qual, (const iwqual *)(&dev->options.wireless.max_qual),
dev->options.wireless.max_quality = range.max_qual.level; (const iwqual *)(&dev->options.wireless.avg_qual));
dev->options.wireless.noise = stats.qual.noise;
percent = nm_wireless_qual_to_percent (dev, &(stats.qual));
}
else
{
dev->options.wireless.max_quality = -1;
dev->options.wireless.noise = -1;
percent = -1;
} }
close (sk); close (sk);
@@ -1317,59 +1327,9 @@ void nm_device_update_signal_strength (NMDevice *dev)
dev->options.wireless.invalid_strength_counter = 0; dev->options.wireless.invalid_strength_counter = 0;
dev->options.wireless.strength = percent; dev->options.wireless.strength = percent;
}
out:
/* nm_unlock_mutex (dev->options.wireless.scan_mutex, __FUNCTION__);
* nm_device_get_noise
*
* Get the current noise level of a wireless device.
*
*/
guint8 nm_device_get_noise (NMDevice *dev)
{
g_return_val_if_fail (dev != NULL, 0);
g_return_val_if_fail (nm_device_is_wireless (dev), 0);
return (dev->options.wireless.noise);
}
/*
* nm_device_get_max_quality
*
* Get the quality maximum of a wireless device.
*
*/
guint8 nm_device_get_max_quality (NMDevice *dev)
{
g_return_val_if_fail (dev != NULL, 0);
g_return_val_if_fail (nm_device_is_wireless (dev), 0);
return (dev->options.wireless.max_quality);
}
/*
* nm_device_get_bad_crypt_packets
*
* Return the number of packets the card has dropped because
* they could not be successfully decrypted.
*
*/
guint32 nm_device_get_bad_crypt_packets (NMDevice *dev)
{
iwstats stats;
int sk;
int err;
g_return_val_if_fail (dev != NULL, 0);
g_return_val_if_fail (nm_device_is_wireless (dev), 0);
sk = iw_sockets_open ();
err = iw_get_stats (sk, nm_device_get_iface (dev), &stats, NULL, FALSE);
close (sk);
return (err == 0 ? stats.discard.code : 0);
} }
@@ -1936,6 +1896,8 @@ static gboolean nm_device_activate_wireless_adhoc (NMDevice *dev, NMAccessPoint
double card_freqs[IW_MAX_FREQUENCIES]; double card_freqs[IW_MAX_FREQUENCIES];
int num_freqs = 0, i; int num_freqs = 0, i;
double freq_to_use = 0; double freq_to_use = 0;
iwrange range;
int sk;
g_return_val_if_fail (dev != NULL, FALSE); g_return_val_if_fail (dev != NULL, FALSE);
g_return_val_if_fail (ap != NULL, FALSE); g_return_val_if_fail (ap != NULL, FALSE);
@@ -1945,9 +1907,9 @@ static gboolean nm_device_activate_wireless_adhoc (NMDevice *dev, NMAccessPoint
/* Build our local list of frequencies to whittle down until we find a free one */ /* Build our local list of frequencies to whittle down until we find a free one */
memset (&card_freqs, 0, sizeof (card_freqs)); memset (&card_freqs, 0, sizeof (card_freqs));
num_freqs = MIN (dev->options.wireless.range_info.num_frequency, IW_MAX_FREQUENCIES); num_freqs = MIN (dev->options.wireless.num_freqs, IW_MAX_FREQUENCIES);
for (i = 0; i < num_freqs; i++) for (i = 0; i < num_freqs; i++)
card_freqs[i] = iw_freq2float (&(dev->options.wireless.range_info.freq[i])); card_freqs[i] = dev->options.wireless.freqs[i];
/* We need to find a clear wireless channel to use. We will /* We need to find a clear wireless channel to use. We will
* only use 802.11b channels for now. * only use 802.11b channels for now.
@@ -1964,13 +1926,23 @@ static gboolean nm_device_activate_wireless_adhoc (NMDevice *dev, NMAccessPoint
} }
nm_ap_list_iter_free (iter); nm_ap_list_iter_free (iter);
if ((sk = iw_sockets_open ()) < 0)
return FALSE;
if (iw_get_range_info (sk, nm_device_get_iface (dev), &range) < 0)
{
close (sk);
return FALSE;
}
close (sk);
/* Ok, find the first non-zero freq in our table and use it. /* Ok, find the first non-zero freq in our table and use it.
* For now we only try to use a channel in the 802.11b channel * For now we only try to use a channel in the 802.11b channel
* space so that most everyone can see it. * space so that most everyone can see it.
*/ */
for (i = 0; i < num_freqs; i++) for (i = 0; i < num_freqs; i++)
{ {
int channel = iw_freq_to_channel (card_freqs[i], &(dev->options.wireless.range_info)); int channel = iw_freq_to_channel (card_freqs[i], &range);
if (card_freqs[i] && (channel > 0) && (channel < 15)) if (card_freqs[i] && (channel > 0) && (channel < 15))
{ {
freq_to_use = card_freqs[i]; freq_to_use = card_freqs[i];
@@ -1985,7 +1957,7 @@ static gboolean nm_device_activate_wireless_adhoc (NMDevice *dev, NMAccessPoint
int channel = (int)(random () % 14); int channel = (int)(random () % 14);
int err; int err;
err = iw_channel_to_freq (channel, &pfreq, &(dev->options.wireless.range_info)); err = iw_channel_to_freq (channel, &pfreq, &range);
if (err == channel) if (err == channel)
freq_to_use = pfreq; freq_to_use = pfreq;
} }
@@ -2039,20 +2011,26 @@ static gboolean AP_NEED_KEY (NMDevice *dev, NMAccessPoint *ap)
/* /*
* get_initial_auth_method * get_initial_auth_method
* *
* Ensure the auth method the AP reports is valid for its encryption mode. * Update the auth method of the AP from the last-known-good one saved in the allowed list
* (which is found from NMI) and ensure that its valid with the encryption status of the AP.
* *
*/ */
static NMDeviceAuthMethod get_initial_auth_method (NMAccessPoint *ap) static NMDeviceAuthMethod get_initial_auth_method (NMAccessPoint *ap, NMAccessPointList *allowed_list)
{ {
g_return_val_if_fail (ap != NULL, NM_DEVICE_AUTH_METHOD_OPEN_SYSTEM); g_return_val_if_fail (ap != NULL, NM_DEVICE_AUTH_METHOD_OPEN_SYSTEM);
if (nm_ap_get_encrypted (ap)) if (nm_ap_get_encrypted (ap))
{ {
NMDeviceAuthMethod auth = nm_ap_get_auth_method (ap); NMDeviceAuthMethod auth = nm_ap_get_auth_method (ap);
NMAccessPoint *allowed_ap = nm_ap_list_get_ap_by_essid (allowed_list, nm_ap_get_essid (ap));
/* Prefer default auth method if we found one for this AP in our allowed list. */
if (allowed_ap)
auth = nm_ap_get_auth_method (allowed_ap);
if ( (auth == NM_DEVICE_AUTH_METHOD_OPEN_SYSTEM) if ( (auth == NM_DEVICE_AUTH_METHOD_OPEN_SYSTEM)
|| (auth == NM_DEVICE_AUTH_METHOD_SHARED_KEY)) || (auth == NM_DEVICE_AUTH_METHOD_SHARED_KEY))
return (nm_ap_get_auth_method (ap)); return (auth);
else else
return (NM_DEVICE_AUTH_METHOD_OPEN_SYSTEM); return (NM_DEVICE_AUTH_METHOD_OPEN_SYSTEM);
} }
@@ -2207,7 +2185,7 @@ need_key:
try_connect: try_connect:
/* Initial authentication method */ /* Initial authentication method */
nm_ap_set_auth_method (best_ap, get_initial_auth_method (best_ap)); nm_ap_set_auth_method (best_ap, get_initial_auth_method (best_ap, dev->app_data->allowed_ap_list));
while (success == FALSE) while (success == FALSE)
{ {
@@ -3289,6 +3267,7 @@ static gboolean nm_device_wireless_process_scan_results (gpointer user_data)
if (tmp_ap->b.has_essid || tmp_ap->has_ap_addr) if (tmp_ap->b.has_essid || tmp_ap->has_ap_addr)
{ {
NMAccessPoint *nm_ap = nm_ap_new (); NMAccessPoint *nm_ap = nm_ap_new ();
int percent;
/* Copy over info from scan to local structure */ /* Copy over info from scan to local structure */
@@ -3339,7 +3318,10 @@ static gboolean nm_device_wireless_process_scan_results (gpointer user_data)
else else
nm_ap_set_mode (nm_ap, NETWORK_MODE_INFRA); nm_ap_set_mode (nm_ap, NETWORK_MODE_INFRA);
nm_ap_set_strength (nm_ap, nm_wireless_qual_to_percent (dev, &(tmp_ap->stats.qual))); percent = nm_wireless_qual_to_percent (&(tmp_ap->stats.qual),
(const iwqual *)(&dev->options.wireless.max_qual),
(const iwqual *)(&dev->options.wireless.avg_qual));
nm_ap_set_strength (nm_ap, percent);
if (tmp_ap->b.has_freq) if (tmp_ap->b.has_freq)
nm_ap_set_freq (nm_ap, tmp_ap->b.freq); nm_ap_set_freq (nm_ap, tmp_ap->b.freq);

View File

@@ -83,9 +83,6 @@ gboolean nm_device_set_mode (NMDevice *dev, const NMNetworkMode mode);
gint8 nm_device_get_signal_strength (NMDevice *dev); gint8 nm_device_get_signal_strength (NMDevice *dev);
void nm_device_update_signal_strength (NMDevice *dev); void nm_device_update_signal_strength (NMDevice *dev);
guint8 nm_device_get_noise (NMDevice *dev);
guint8 nm_device_get_max_quality (NMDevice *dev);
guint32 nm_device_get_bad_crypt_packets (NMDevice *dev);
NMAccessPoint *nm_device_get_best_ap (NMDevice *dev); NMAccessPoint *nm_device_get_best_ap (NMDevice *dev);
void nm_device_set_best_ap (NMDevice *dev, NMAccessPoint *ap); void nm_device_set_best_ap (NMDevice *dev, NMAccessPoint *ap);

View File

@@ -36,13 +36,15 @@
/* Wireless device specific options */ /* Wireless device specific options */
typedef struct NMDeviceWirelessOptions typedef struct NMDeviceWirelessOptions
{ {
char *cur_essid; char *cur_essid; /* Mainly for test devices */
gboolean supports_wireless_scan; gboolean supports_wireless_scan;
guint8 max_quality;
guint8 noise;
gint8 strength; gint8 strength;
gint8 invalid_strength_counter; gint8 invalid_strength_counter;
struct iw_range range_info; iwqual max_qual;
iwqual avg_qual;
gint8 num_freqs;
double freqs[IW_MAX_FREQUENCIES];
GMutex *scan_mutex; GMutex *scan_mutex;
NMAccessPointList *ap_list; NMAccessPointList *ap_list;
@@ -59,7 +61,8 @@ typedef struct NMDeviceWirelessOptions
/* Wired device specific options */ /* Wired device specific options */
typedef struct NMDeviceWiredOptions typedef struct NMDeviceWiredOptions
{ {
int foo; guint link_watch_id;
guint foo;
} NMDeviceWiredOptions; } NMDeviceWiredOptions;
typedef union NMDeviceOptions typedef union NMDeviceOptions

View File

@@ -130,64 +130,47 @@ char *nm_wireless_128bit_key_from_passphrase (const char *passphrase)
* a magical signal strength percentage. * a magical signal strength percentage.
* *
*/ */
int nm_wireless_qual_to_percent (NMDevice *dev, const struct iw_quality *qual) int nm_wireless_qual_to_percent (const struct iw_quality *qual, const struct iw_quality *max_qual, const struct iw_quality *avg_qual)
{ {
int percent = -1; int percent = -1;
g_return_val_if_fail (dev != NULL, -1);
g_return_val_if_fail (qual != NULL, -1); g_return_val_if_fail (qual != NULL, -1);
g_return_val_if_fail (max_qual != NULL, -1);
g_return_val_if_fail (avg_qual != NULL, -1);
/* Try using the card's idea of the signal quality first */ /* Try using the card's idea of the signal quality first as long as it tells us what the max quality is */
if ((nm_device_get_max_quality (dev) == 100) && (qual->qual < 100)) if ((max_qual->qual != 0) && !(max_qual->updated & IW_QUAL_QUAL_INVALID) && !(qual->updated & IW_QUAL_QUAL_INVALID))
{ {
/* Atmel driver seems to use qual->qual is the percentage value */ percent = (int)(100 * ((double)qual->qual / (double)max_qual->qual));
percent = qual->qual;
} }
else if (qual->qual == (qual->level - qual->noise)) else
{ {
/* Ok, simple signal : noise ratio. Prism54 for example. */ if((qual->level > max_qual->level) && (qual->noise != 0))
//fprintf (stderr, "20 * log (level / noise) = 20 * log (%d / %d) = %f\n", qual->level, qual->noise, log ((255-qual->level) / (255-qual->noise)) * 100);
percent = (int)rint ((log (qual->qual) / log (96)) * 100.0);
percent = CLAMP (percent, 0, 100);
}
else if (qual->qual >= 1)
{
/* Try it the Gnome Wireless Applet way */
percent = (int)rint ((log (qual->qual) / log (94)) * 100.0);
percent = CLAMP (percent, 0, 100);
}
/* If that failed, try to calculate the signal quality based on other
* values, like Signal-to-Noise ratio.
*/
if (((percent == -1) || (percent == 0)))
{
/* If the statistics are in dBm or relative */
if(qual->level > nm_device_get_max_quality (dev))
{ {
#define BEST_SIGNAL 85 /* In dBm, stuck card next to AP, this is what I got */ int level = -1;
int noise = -1;
/* Values in dBm (absolute power measurement) */ /* Signal level is in dBm (absolute power measurement) */
if (qual->level > 0) if (!(qual->updated & IW_QUAL_LEVEL_INVALID))
percent = (int)rint ((double)(((256 - qual->level) / (double)BEST_SIGNAL) * 100)); level = qual->level - 0x100;
/* Deal with noise level in dBm (absolute power measurement) */
if (!(qual->updated & IW_QUAL_NOISE_INVALID))
noise = qual->noise - 0x100;
/* Try a sort of signal-to-noise ratio */
percent = abs((int)rint(10 * log ((double)level / ((double)level + (double)noise))));
} }
else else if (!(max_qual->level & IW_QUAL_LEVEL_INVALID) && (max_qual->level != 0))
{ {
/* FIXME /* Signal level is relavtive (0 -> max) */
* Not quite sure what to do here... Above we have a "100% strength" number if (!(qual->updated & IW_QUAL_LEVEL_INVALID))
* empirically derived, but I don't have any cards that trigger this code below... {
*/ percent = (int)(100 * ((double)qual->level / (double)max_qual->level));
#if 0 }
/* Relative values (0 -> max) */
qual_rel = qual->level;
qual_max_rel = range->max_qual.level;
noise_rel = qual->noise;
noise_max_rel = range->max_qual.noise;
#else
percent = -1;
#endif
} }
} }
percent = CLAMP (percent, 0, 100);
return (percent); return (percent);
} }

View File

@@ -32,6 +32,8 @@ char * nm_wireless_64bit_ascii_to_hex (const unsigned char *ascii);
char * nm_wireless_128bit_ascii_to_hex (const unsigned char *ascii); char * nm_wireless_128bit_ascii_to_hex (const unsigned char *ascii);
char * nm_wireless_128bit_key_from_passphrase (const char *passphrase); char * nm_wireless_128bit_key_from_passphrase (const char *passphrase);
int nm_wireless_qual_to_percent (NMDevice *dev, const struct iw_quality *qual); int nm_wireless_qual_to_percent (const struct iw_quality *qual,
const struct iw_quality *max_qual,
const struct iw_quality *avg_qual);
#endif #endif