2004-09-13 Dan Williams <dcbw@redhat.com>
authorDan Williams <dcbw@redhat.com>
Mon, 13 Sep 2004 17:43:16 +0000 (17:43 +0000)
committerDan Williams <dcbw@redhat.com>
Mon, 13 Sep 2004 17:43:16 +0000 (17:43 +0000)
* TODO: fix typo

* docs/NetworkManager DBUS API.txt
- Update for new signal strength changes

* panel-applet/NMWirelessApplet.c
- Make panel icon show strength of the current connection
- Cleanups and memleak fixes

* panel-applet/NMWirelessApplet.h
- Add data members for signal strength on devices and networks

* panel-applet/NMWirelessAppletDbus.c
- Free more DBusErrors
- Update for new signal strength changes
- Make devices and networks more like real objects, use ref/unref methods
- Actually unlock the mutex when updating the active device

* src/NetworkManagerAP.c
- Change AP functions and data members from "quality"->"strength"

* src/NetworkManagerDbus.c
- Kill "getMaxQuality" and "getQuality" methods
- Add "getStrength" methods for Networks and Devices

* src/NetworkManagerDevice.[ch]
- Add accessors for device strength
- Add functions to update strength for a device.  Note that not all drivers
actually support signal strength for scanned access points (Atmel drivers
being one)
- Calculate signal strength for each AP during scan

* src/NetworkManagerWireless.[ch]
- Add function to return signal strength % from a device and a raw quality struct

* test/nmclienttest.c
- Update for new signal strength changes

git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@156 4912f4e0-d625-0410-9fb7-b9a5a253dbdc

15 files changed:
ChangeLog
TODO
docs/NetworkManager DBUS API.txt
panel-applet/NMWirelessApplet.c
panel-applet/NMWirelessApplet.h
panel-applet/NMWirelessAppletDbus.c
src/NetworkManagerAP.c
src/NetworkManagerAP.h
src/NetworkManagerAPList.c
src/NetworkManagerDbus.c
src/NetworkManagerDevice.c
src/NetworkManagerDevice.h
src/NetworkManagerWireless.c
src/NetworkManagerWireless.h
test/nmclienttest.c

index 3e64803..0102962 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,43 @@
+2004-09-13  Dan Williams <dcbw@redhat.com>
+
+       * TODO: fix typo
+
+       * docs/NetworkManager DBUS API.txt
+               - Update for new signal strength changes
+
+       * panel-applet/NMWirelessApplet.c
+               - Make panel icon show strength of the current connection
+               - Cleanups and memleak fixes
+
+       * panel-applet/NMWirelessApplet.h
+               - Add data members for signal strength on devices and networks
+
+       * panel-applet/NMWirelessAppletDbus.c
+               - Free more DBusErrors
+               - Update for new signal strength changes
+               - Make devices and networks more like real objects, use ref/unref methods
+               - Actually unlock the mutex when updating the active device
+
+       * src/NetworkManagerAP.c
+               - Change AP functions and data members from "quality"->"strength"
+
+       * src/NetworkManagerDbus.c
+               - Kill "getMaxQuality" and "getQuality" methods
+               - Add "getStrength" methods for Networks and Devices
+
+       * src/NetworkManagerDevice.[ch]
+               - Add accessors for device strength
+               - Add functions to update strength for a device.  Note that not all drivers
+                       actually support signal strength for scanned access points (Atmel drivers
+                       being one)
+               - Calculate signal strength for each AP during scan
+
+       * src/NetworkManagerWireless.[ch]
+               - Add function to return signal strength % from a device and a raw quality struct
+
+       * test/nmclienttest.c
+               - Update for new signal strength changes
+
 2004-09-11  Dan Williams <dcbw@redhat.com>
 
        * src/NetworkManager.c
diff --git a/TODO b/TODO
index b6249fd..8fa712e 100644 (file)
--- a/TODO
+++ b/TODO
@@ -10,7 +10,7 @@ Currently, after each scan the list of access points is diffed against the previ
 
 - Access Point link checking thresholds
 
-Wireless link checking could be enhanced to check the signal strength of an access point and switch of the current access point a wireless card is associated with has dropped below say, 20%.
+Wireless link checking could be enhanced to check the signal strength of an access point and switch if the current access point a wireless card is associated with has dropped below say, 20%.
 
 
 - Gracefully recover from dbus and hal dropouts
index f2e3900..1081166 100644 (file)
@@ -122,11 +122,9 @@ Methods:
                                                                                                Wired: no cable plugged in
                                                                                                Wireless: no base station, or bad encryption key
 
-       Name:   getMaxQuality           (Wireless only) Returns the maximum quality level of the wireless device, from
-                                                               which a program may calculate a signal strength percentage based on this
-                                                               number and the quality of an individual Network object
+       Name:   getStrength             (Wireless only) Return the strength percentage of the current wireless network
        Args:   (none)
-       Returns:        DBUS_TYPE_UINT32                        The maximum quality any wireless network can have
+       Returns:        DBUS_TYPE_INT32                 The strength percentage of the current wireless network
 
 
        Name:   getActiveNetwork        (Wireless only) Returns the Network object indentifier of the wireless network
@@ -164,9 +162,9 @@ Methods:
        Returns:        DBUS_TYPE_STRING
 
 
-       Name:   getQuality              Returns the quality of this wirless network
+       Name:   getStrength             Return the strength percentage of the current wireless network
        Args:   (none)
-       Returns:        DBUS_TYPE_INT32                 A number between 0 and the device's Maximum Quality
+       Returns:        DBUS_TYPE_INT32                 The strength percentage of the current wireless network
 
 
        Name:   getFrequency            Returns the frequency/channel this wireless network
index 85d6ace..8f83482 100644 (file)
@@ -141,7 +141,21 @@ static void nmwa_update_state (NMWirelessApplet *applet)
                        break;
 
                case (APPLET_STATE_WIRELESS):
-                       applet->pix_state = PIX_WIRELESS_SIGNAL_4;
+                       g_mutex_lock (applet->data_mutex);
+                       if (applet->active_device)
+                       {
+                               if (applet->active_device->strength > 75)
+                                       applet->pix_state = PIX_WIRELESS_SIGNAL_4;
+                               else if (applet->active_device->strength > 50)
+                                       applet->pix_state = PIX_WIRELESS_SIGNAL_3;
+                               else if (applet->active_device->strength > 25)
+                                       applet->pix_state = PIX_WIRELESS_SIGNAL_2;
+                               else if (applet->active_device->strength > 0)
+                                       applet->pix_state = PIX_WIRELESS_SIGNAL_1;
+                               else
+                                       applet->pix_state = PIX_WIRELESS_NO_LINK;
+                       }
+                       g_mutex_unlock (applet->data_mutex);
                        break;
 
                case (APPLET_STATE_WIRELESS_CONNECTING):
@@ -302,7 +316,7 @@ static void nmwa_about_cb (BonoboUIComponent *uic, NMWirelessApplet *applet)
 static void nmwa_destroy (NMWirelessApplet *applet, gpointer user_data)
 {
        int i;
-       
+
        if (applet->menu)
                nmwa_dispose_menu_items (applet);
 
@@ -636,7 +650,7 @@ static void nmwa_menu_add_network (GtkWidget *menu, GdkPixbuf *key, NetworkDevic
        gtk_widget_show (label);
 
        progress = gtk_progress_bar_new ();
-       percent = ((float)net->quality / (float)0x100);
+       percent = ((float)net->strength / (float)100);
        percent = (percent < 0 ? 0 : (percent > 1.0 ? 1.0 : percent));
        gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (progress), percent);
        gtk_box_pack_start (GTK_BOX (hbox), progress, TRUE, TRUE, 0);
@@ -722,11 +736,12 @@ static void nmwa_menu_add_devices (GtkWidget *menu, NMWirelessApplet *applet)
                        {
                                GdkPixbuf       *icon = (dev->type == DEVICE_TYPE_WIRED_ETHERNET) ? applet->wired_icon : applet->wireless_icon;
                                char            *name_string;
-                               gboolean         current = applet->active_device ? (strcmp (applet->active_device, dev->nm_device) == 0) : FALSE;
+                               gboolean         current = (dev == applet->active_device);
 
                                name_string = g_strdup_printf ("%s (%s)", (dev->hal_name ? dev->hal_name : dev->nm_name),
                                                (dev->type == DEVICE_TYPE_WIRED_ETHERNET) ? "wired" : "wireless");
                                nmwa_menu_add_device_item (menu, icon, name_string, dev->nm_device, current, applet);
+                               g_free (name_string);
                                nmwa_menu_device_add_networks (menu, dev, applet);
                                nmwa_menu_add_separator_item (menu);    
                        }
index 25b71e4..9088713 100644 (file)
@@ -59,6 +59,37 @@ typedef enum
 } AppletState;
 
 
+/*
+ * Representation of a wireless network
+ *
+ */
+typedef struct
+{
+       int              refcount;
+       char            *nm_name;
+       char            *essid;
+       gboolean         encrypted;
+       gboolean         active;
+       gint8    strength;
+} WirelessNetwork;
+
+/*
+ * Representation of network device
+ *
+ */
+typedef struct
+{
+       int              refcount;
+       char            *nm_device;
+       int              type;
+       char            *nm_name;
+       char            *hal_name;
+       char            *udi;
+       gint             strength;
+       GSList  *networks;
+} NetworkDevice;
+
+
 /*
  * Applet instance data
  *
@@ -84,7 +115,7 @@ typedef struct
        /* Data model elements */
        GMutex                  *data_mutex;
        GSList                  *devices;
-       char                            *active_device;
+       NetworkDevice           *active_device;
        AppletState              applet_state;
 
        /* Direct UI elements */
@@ -96,34 +127,6 @@ typedef struct
 } NMWirelessApplet;
 
 
-/*
- * Representation of a wireless network
- *
- */
-typedef struct
-{
-       char            *nm_name;
-       char            *essid;
-       gboolean         encrypted;
-       gboolean         active;
-       guint8   quality;
-} WirelessNetwork;
-
-/*
- * Representation of network device
- *
- */
-typedef struct
-{
-       char            *nm_device;
-       int              type;
-       char            *nm_name;
-       char            *hal_name;
-       char            *udi;
-       GSList  *networks;
-} NetworkDevice;
-
-
 NetworkDevice *nmwa_get_device_for_nm_device (NMWirelessApplet *applet, const char *nm_dev);
 
 #endif
index 7223d44..a51cba5 100644 (file)
@@ -100,6 +100,8 @@ static int nmwa_dbus_get_string (DBusConnection *connection, const char *path, c
        if (!dbus_message_get_args (reply, &error, DBUS_TYPE_STRING, &dbus_string, DBUS_TYPE_INVALID))
        {
                fprintf (stderr, "nmwa_dbus_get_string(): error while getting args: name='%s' message='%s'\n", error.name, error.message);
+               if (dbus_error_is_set (&error))
+                       dbus_error_free (&error);
                dbus_message_unref (reply);
                return (RETURN_FAILURE);
        }
@@ -160,6 +162,8 @@ static int nmwa_dbus_get_int (DBusConnection *connection, const char *path, cons
        dbus_error_init (&error);
        if (!dbus_message_get_args (reply, &error, DBUS_TYPE_INT32, &dbus_num, DBUS_TYPE_INVALID))
        {
+               if (dbus_error_is_set (&error))
+                       dbus_error_free (&error);
                dbus_message_unref (reply);
                return (RETURN_FAILURE);
        }       
@@ -213,13 +217,14 @@ static int nmwa_dbus_get_bool (DBusConnection *connection, const char *path, con
        if (reply == NULL)
        {
                fprintf( stderr, "nmwa_dbus_get_bool(): dbus reply message was NULL\n" );
-               dbus_message_unref (message);
                return (RETURN_FAILURE);
        }
 
        dbus_error_init (&error);
        if (!dbus_message_get_args (reply, &error, DBUS_TYPE_BOOLEAN, val, DBUS_TYPE_INVALID))
        {
+               if (dbus_error_is_set (&error))
+                       dbus_error_free (&error);
                dbus_message_unref (reply);
                return (RETURN_FAILURE);
        }
@@ -252,6 +257,7 @@ static double nmwa_dbus_get_double (DBusConnection *connection, const char *path
 
        dbus_error_init (&error);
        reply = dbus_connection_send_with_reply_and_block (connection, message, -1, &error);
+       dbus_message_unref (message);
        if (dbus_error_is_set (&error))
        {
                fprintf (stderr, "nmwa_dbus_get_double(): %s raised:\n %s\n\n", error.name, error.message);
@@ -263,16 +269,18 @@ static double nmwa_dbus_get_double (DBusConnection *connection, const char *path
        if (reply == NULL)
        {
                fprintf( stderr, "nmwa_dbus_get_double(): dbus reply message was NULL\n" );
-               dbus_message_unref (message);
                return (0);
        }
 
        dbus_error_init (&error);
        if (!dbus_message_get_args (reply, &error, DBUS_TYPE_DOUBLE, &num, DBUS_TYPE_INVALID))
+       {
+               if (dbus_error_is_set (&error))
+                       dbus_error_free (&error);
                num = 0;
+       }
 
        dbus_message_unref (reply);
-       dbus_message_unref (message);
 
        return (num);
 }
@@ -439,16 +447,16 @@ static int nmwa_dbus_get_device_type (NMWirelessApplet *applet, char *path, Appl
 
 
 /*
- * nmwa_dbus_get_network_quality
+ * nmwa_dbus_get_object_strength
  *
- * Returns the quality of a given wireless network
+ * Returns the strength of a given object (device or wireless network)
  *
  */
-static guint8 nmwa_dbus_get_network_quality (NMWirelessApplet *applet, char *path)
+static gint8 nmwa_dbus_get_object_strength (NMWirelessApplet *applet, char *path)
 {
-       int     qual = 0;
+       int     strength = -1;
 
-       switch (nmwa_dbus_get_int (applet->connection, path, "getQuality", &qual))
+       switch (nmwa_dbus_get_int (applet->connection, path, "getStrength", &strength))
        {
                case (RETURN_NO_NM):
                        applet->applet_state = APPLET_STATE_NO_NM;
@@ -458,7 +466,7 @@ static guint8 nmwa_dbus_get_network_quality (NMWirelessApplet *applet, char *pat
                        break;                  
        }
 
-       return (qual);
+       return (strength);
 }
 
 
@@ -646,6 +654,7 @@ static char *nmwa_dbus_get_hal_device_string_property (DBusConnection *connectio
        if (dbus_error_is_set (&error))
        {
                fprintf (stderr, "nmwa_dbus_get_hal_device_string_property(): %s raised:\n %s\n\n", error.name, error.message);
+               dbus_error_free (&error);
                return (NULL);
        }
 
@@ -657,7 +666,11 @@ static char *nmwa_dbus_get_hal_device_string_property (DBusConnection *connectio
 
        dbus_error_init (&error);
        if (!dbus_message_get_args (reply, &error, DBUS_TYPE_STRING, &property, DBUS_TYPE_INVALID))
+       {
+               if (dbus_error_is_set (&error))
+                       dbus_error_free (&error);
                property = NULL;
+       }
 
        dbus_message_unref (reply);     
        return (property);
@@ -692,6 +705,7 @@ static char *nmwa_dbus_get_hal_device_info (DBusConnection *connection, const ch
        if (dbus_error_is_set (&error))
        {
                fprintf (stderr, "nmwa_dbus_get_hal_device_info(): %s raised:\n %s\n\n", error.name, error.message);
+               dbus_error_free (&error);
                return (NULL);
        }
 
@@ -703,7 +717,11 @@ static char *nmwa_dbus_get_hal_device_info (DBusConnection *connection, const ch
 
        dbus_error_init (&error);
        if (dbus_message_get_args (reply, &error, DBUS_TYPE_BOOLEAN, &exists, DBUS_TYPE_INVALID))
+       {
+               if (dbus_error_is_set (&error))
+                       dbus_error_free (&error);
                info = nmwa_dbus_get_hal_device_string_property (connection, udi, "info.product");
+       }
 
        dbus_message_unref (reply);
        
@@ -746,23 +764,38 @@ fprintf( stderr, "Forcing device '%s'\n", dev->nm_device);
 
 
 /*
- * wireless_network_free
+ * wireless_network_ref
  *
- * Frees the representation of a wireless network
+ * Increment the reference count of the wireless network
  *
  */
-static void wireless_network_free (void *element, void *user_data)
+static void wireless_network_ref (WirelessNetwork *net)
 {
-       WirelessNetwork *net = (WirelessNetwork *)(element);
-
        g_return_if_fail (net != NULL);
 
-       g_free (net->nm_name);
-       g_free (net->essid);
-       g_free (net);
+       net->refcount++;
 }
 
 
+/*
+ * wireless_network_unref
+ *
+ * Unrefs (and possibly frees) the representation of a wireless network
+ *
+ */
+static void wireless_network_unref (WirelessNetwork *net)
+{
+       g_return_if_fail (net != NULL);
+
+       net->refcount--;
+       if (net->refcount < 1)
+       {
+               g_free (net->nm_name);
+               g_free (net->essid);
+               g_free (net);
+       }
+}
+
 /*
  * network_device_free_wireless_network_list
  *
@@ -771,30 +804,46 @@ static void network_device_free_wireless_network_list (NetworkDevice *dev)
 {
        g_return_if_fail (dev != NULL);
 
-       g_slist_foreach (dev->networks, wireless_network_free, NULL);
+       g_slist_foreach (dev->networks, wireless_network_unref, NULL);
        g_slist_free (dev->networks);
        dev->networks = NULL;   
 }
 
 
 /*
- * network_device_free
+ * network_device_ref
  *
- * Frees the representation of a network device
+ * Increment the reference count of the network device
  *
  */
-static void network_device_free (void *element, void *user_data)
+static void network_device_ref (NetworkDevice *dev)
 {
-       NetworkDevice   *dev = (NetworkDevice *)(element);
+       g_return_if_fail (dev != NULL);
 
+       dev->refcount++;
+}
+
+
+/*
+ * network_device_unref
+ *
+ * Unrefs (and possibly frees) the representation of a network device
+ *
+ */
+static void network_device_unref (NetworkDevice *dev)
+{
        g_return_if_fail (dev != NULL);
 
-       network_device_free_wireless_network_list (dev);
-       g_free (dev->nm_device);
-       g_free (dev->nm_name);
-       dbus_free (dev->udi);
-       dbus_free (dev->hal_name);
-       g_free (dev);
+       dev->refcount--;
+       if (dev->refcount < 1)
+       {
+               network_device_free_wireless_network_list (dev);
+               g_free (dev->nm_device);
+               g_free (dev->nm_name);
+               dbus_free (dev->udi);
+               dbus_free (dev->hal_name);
+               g_free (dev);
+       }
 }
 
 
@@ -814,15 +863,13 @@ static void nmwa_dbus_update_device_wireless_networks (NetworkDevice *dev, NMWir
        char            **networks = NULL;
        int               num_items = 0;
        int               i;
-
        g_return_if_fail (dev != NULL);
 
        /* Clear out existing entries in the list */
        if (dev->networks)
                network_device_free_wireless_network_list (dev);
 
-       if (    ((dev_type = nmwa_dbus_get_device_type (applet, dev->nm_device, APPLET_STATE_NO_CONNECTION)) == -1)
-               || (dev_type != DEVICE_TYPE_WIRELESS_ETHERNET))
+       if (dev->type != DEVICE_TYPE_WIRELESS_ETHERNET)
                goto out;
 
        active_network = nmwa_dbus_get_active_network (applet, dev->nm_device, APPLET_STATE_IGNORE);
@@ -858,18 +905,17 @@ static void nmwa_dbus_update_device_wireless_networks (NetworkDevice *dev, NMWir
                                continue;
                                                
                        net = g_new0 (WirelessNetwork, 1);
+                       wireless_network_ref (net);
                        net->nm_name = g_strdup (networks[i]);
                        net->essid = g_strdup (name);
                        net->active = active_network ? (strcmp (net->nm_name, active_network) == 0) : FALSE;
                        net->encrypted = nmwa_dbus_get_network_encrypted (applet, net->nm_name);
-                       net->quality = nmwa_dbus_get_network_quality (applet, net->nm_name);
+                       net->strength = nmwa_dbus_get_object_strength (applet, net->nm_name);
 
-                       fprintf( stderr, "Adding '%s' active (%d), enc (%d)\n", name, net->active, net->encrypted);
                        dev->networks = g_slist_append (dev->networks, net);
                }
                dbus_free (name);
        }
-       g_mutex_unlock (applet->data_mutex);
 
 out:
        dbus_free (active_network);     
@@ -887,7 +933,6 @@ static void nmwa_dbus_update_network_state (NMWirelessApplet *applet)
 {
        char            *active_device = NULL;
        char            *nm_status = NULL;
-       int              dev_type = -1;
 
        g_return_if_fail (applet != NULL);
 
@@ -901,26 +946,27 @@ static void nmwa_dbus_update_network_state (NMWirelessApplet *applet)
                goto out;
        }
        
-       if (!(active_device = nmwa_dbus_get_active_device (applet, APPLET_STATE_NO_CONNECTION)))
-               goto out;
-
-       if ((dev_type = nmwa_dbus_get_device_type (applet, active_device, APPLET_STATE_NO_CONNECTION)) == -1)
+       if (!applet->active_device)
+       {
+               applet->applet_state = APPLET_STATE_NO_CONNECTION;
                goto out;
+       }
 
        /* If the device is not 802.x, we don't show state for it (yet) */
-       if ((dev_type != DEVICE_TYPE_WIRED_ETHERNET) && (dev_type != DEVICE_TYPE_WIRELESS_ETHERNET))
+       if (    (applet->active_device->type != DEVICE_TYPE_WIRED_ETHERNET)
+               && (applet->active_device->type != DEVICE_TYPE_WIRELESS_ETHERNET))
        {
                applet->applet_state = APPLET_STATE_NO_CONNECTION;
                goto out;
        }
-       else if (dev_type == DEVICE_TYPE_WIRED_ETHERNET)
+       else if (applet->active_device->type == DEVICE_TYPE_WIRED_ETHERNET)
        {
                if (strcmp (nm_status, "connecting") == 0)
                        applet->applet_state = APPLET_STATE_WIRED_CONNECTING;
                else if (strcmp (nm_status, "connected") == 0)
                        applet->applet_state = APPLET_STATE_WIRED;
        }
-       else if (dev_type == DEVICE_TYPE_WIRELESS_ETHERNET)
+       else if (applet->active_device->type == DEVICE_TYPE_WIRELESS_ETHERNET)
        {
                if (strcmp (nm_status, "connecting") == 0)
                        applet->applet_state = APPLET_STATE_WIRELESS_CONNECTING;
@@ -930,7 +976,6 @@ static void nmwa_dbus_update_network_state (NMWirelessApplet *applet)
 
 out:
        dbus_free (nm_status);
-       dbus_free (active_device);
 }
 
 
@@ -942,12 +987,62 @@ out:
  */
 static void nmwa_dbus_update_active_device (NMWirelessApplet *applet)
 {
+       GSList  *element;
+       char            *nm_act_dev;
+
        g_return_if_fail (applet != NULL);
 
+       nm_act_dev = nmwa_dbus_get_active_device (applet, APPLET_STATE_IGNORE);
+
        g_mutex_lock (applet->data_mutex);
        if (applet->active_device)
-               dbus_free (applet->active_device);
-       applet->active_device = nmwa_dbus_get_active_device (applet, APPLET_STATE_IGNORE);
+               network_device_unref (applet->active_device);
+       applet->active_device = NULL;
+
+       if (nm_act_dev)
+       {
+               element = applet->devices;
+               while (element)
+               {
+                       NetworkDevice   *dev = (NetworkDevice *)(element->data);
+                       if (dev)
+                       {
+                               if (strcmp (dev->nm_device, nm_act_dev) == 0)
+                               {
+                                       applet->active_device = dev;
+                                       network_device_ref (applet->active_device);
+                                       break;
+                               }
+                       }
+                       element = g_slist_next (element);
+               }
+       }
+
+       g_mutex_unlock (applet->data_mutex);
+       dbus_free (nm_act_dev);
+}
+
+
+/*
+ * nmwa_dbus_update_active_device_strength
+ *
+ * Update the active device's current wireless network strength
+ *
+ */
+void nmwa_dbus_update_active_device_strength (NMWirelessApplet *applet)
+{
+       g_return_if_fail (applet != NULL);
+
+       g_mutex_lock (applet->data_mutex);
+       if (!applet->active_device)
+       {
+               g_mutex_unlock (applet->data_mutex);
+               return;
+       }
+
+       if (applet->active_device->type == DEVICE_TYPE_WIRELESS_ETHERNET)
+               applet->active_device->strength = nmwa_dbus_get_object_strength (applet, applet->active_device->nm_device);
+
        g_mutex_unlock (applet->data_mutex);
 }
 
@@ -981,8 +1076,11 @@ static void nmwa_dbus_update_devices (NMWirelessApplet *applet)
 
        /* Clear out existing device list */
        g_mutex_lock (applet->data_mutex);
-       g_slist_foreach (applet->devices, network_device_free, NULL);
+       g_slist_foreach (applet->devices, network_device_unref, NULL);
        g_slist_free (applet->devices);
+       if (applet->active_device)
+               network_device_unref (applet->active_device);
+       applet->active_device = NULL;
        applet->devices = NULL;
 
        for (i = 0; i < num_items; i++)
@@ -995,6 +1093,7 @@ static void nmwa_dbus_update_devices (NMWirelessApplet *applet)
 
                        if ((dev = g_new0 (NetworkDevice, 1)))
                        {
+                               network_device_ref (dev);
                                dev->nm_device = g_strdup (devices[i]);
                                dev->type = nmwa_dbus_get_device_type (applet, devices[i], APPLET_STATE_NO_CONNECTION);
                                dev->nm_name = g_strdup (name);
@@ -1003,11 +1102,10 @@ static void nmwa_dbus_update_devices (NMWirelessApplet *applet)
 
                                /* Ensure valid device information */
                                if (!dev->nm_device || !dev->nm_name || !dev->udi || (dev->type == -1))
-                                       network_device_free (dev, NULL);
+                                       network_device_unref (dev);
                                else
                                {
                                        applet->devices = g_slist_append (applet->devices, dev);
-                                       fprintf( stderr, "Got device '%s', udi '%s'\n", dev->nm_name, dev->udi);
                                        nmwa_dbus_update_device_wireless_networks (dev, applet);
                                }
                        }
@@ -1042,6 +1140,8 @@ static DBusHandlerResult nmwa_dbus_filter (DBusConnection *connection, DBusMessa
                if (    dbus_message_get_args (message, &error, DBUS_TYPE_STRING, &service, DBUS_TYPE_INVALID)
                        && (strcmp (service, NM_DBUS_SERVICE) == 0) && (applet->applet_state == APPLET_STATE_NO_NM))
                        applet->applet_state = APPLET_STATE_NO_CONNECTION;
+               if (dbus_error_is_set (&error))
+                       dbus_error_free (&error);
        }
        else if (dbus_message_is_signal (message, DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS, "ServiceDeleted"))
        {
@@ -1052,6 +1152,8 @@ static DBusHandlerResult nmwa_dbus_filter (DBusConnection *connection, DBusMessa
                if (    dbus_message_get_args (message, &error, DBUS_TYPE_STRING, &service, DBUS_TYPE_INVALID)
                        && (strcmp (service, NM_DBUS_SERVICE) == 0))
                        applet->applet_state = APPLET_STATE_NO_NM;
+               if (dbus_error_is_set (&error))
+                       dbus_error_free (&error);
        }
        else if (    dbus_message_is_signal (message, NM_DBUS_INTERFACE, "WirelessNetworkAppeared")
                        || dbus_message_is_signal (message, NM_DBUS_INTERFACE, "WirelessNetworkDisappeared"))
@@ -1084,9 +1186,9 @@ static DBusHandlerResult nmwa_dbus_filter (DBusConnection *connection, DBusMessa
                        || dbus_message_is_signal (message, NM_DBUS_INTERFACE, "DeviceNoLongerActive")
                        || dbus_message_is_signal (message, NM_DBUS_INTERFACE, "DeviceActivating"))
        {
-               nmwa_dbus_update_network_state (applet);
                nmwa_dbus_update_devices (applet);
                nmwa_dbus_update_active_device (applet);
+               nmwa_dbus_update_network_state (applet);
        }
        else if (dbus_message_is_signal (message, NM_DBUS_INTERFACE, "DevicesChanged"))
        {
@@ -1115,6 +1217,8 @@ static gboolean nmwa_dbus_nm_is_running (DBusConnection *connection)
 
        dbus_error_init (&error);
        exists = dbus_bus_service_exists (connection, NM_DBUS_SERVICE, &error);
+       if (dbus_error_is_set (&error))
+               dbus_error_free (&error);
        return (exists);
 }
 
@@ -1138,6 +1242,7 @@ static DBusConnection * nmwa_dbus_init (NMWirelessApplet *applet, GMainContext *
        if (dbus_error_is_set (&error))
        {
                fprintf (stderr, "%s raised:\n %s\n\n", error.name, error.message);
+               dbus_error_free (&error);
                return (NULL);
        }
 
@@ -1152,6 +1257,8 @@ static DBusConnection * nmwa_dbus_init (NMWirelessApplet *applet, GMainContext *
                                "interface='" DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS "',"
                                "sender='" DBUS_SERVICE_ORG_FREEDESKTOP_DBUS "'",
                                &error);
+       if (dbus_error_is_set (&error))
+               dbus_error_free (&error);
 
        dbus_bus_add_match(connection,
                                "type='signal',"
@@ -1159,8 +1266,9 @@ static DBusConnection * nmwa_dbus_init (NMWirelessApplet *applet, GMainContext *
                                "path='" NM_DBUS_PATH "',"
                                "sender='" NM_DBUS_SERVICE "'",
                                &error);
+       if (dbus_error_is_set (&error))
+               dbus_error_free (&error);
 
-fprintf( stderr, "returning good DBUS connection\n");
        return (connection);
 }
 
@@ -1183,7 +1291,17 @@ static gboolean nmwa_dbus_timeout_worker (gpointer user_data)
                 * for signals from NetworkManager to trigger state updates.
                 */
                if ((applet->connection = nmwa_dbus_init (applet, applet->thread_context)))
+               {
+                       applet->applet_state = APPLET_STATE_NO_CONNECTION;
+                       nmwa_dbus_update_devices (applet);
+                       nmwa_dbus_update_active_device (applet);
                        nmwa_dbus_update_network_state (applet);
+               }
+       }
+       else
+       {
+               nmwa_dbus_update_active_device_strength (applet);
+               /* FIXME: update wireless networks strength in real-time */
        }
 
        return (TRUE);
@@ -1219,9 +1337,10 @@ gpointer nmwa_dbus_worker (gpointer user_data)
 
        if (applet->connection && nmwa_dbus_nm_is_running (applet->connection))
        {
-               nmwa_dbus_update_network_state (applet);
+               applet->applet_state = APPLET_STATE_NO_CONNECTION;
                nmwa_dbus_update_devices (applet);
                nmwa_dbus_update_active_device (applet);
+               nmwa_dbus_update_network_state (applet);
        }
        else
                applet->applet_state = APPLET_STATE_NO_NM;
index 727d47a..ed17a7f 100644 (file)
@@ -32,7 +32,7 @@ struct NMAccessPoint
        guint                    refcount;
        char                            *essid;
        struct ether_addr       *address;
-       guint8                   quality;
+       gint8                    strength;
        double                   freq;
        guint16                  rate;
        gboolean                         encrypted;
@@ -97,7 +97,7 @@ NMAccessPoint * nm_ap_new_from_ap (NMAccessPoint *src_ap)
                memcpy (new_addr, src_ap->address, sizeof (struct ether_addr));
                new_ap->address = new_addr;
        }
-       new_ap->quality = src_ap->quality;
+       new_ap->strength = src_ap->strength;
        new_ap->freq = src_ap->freq;
        new_ap->rate = src_ap->rate;
        new_ap->encrypted = src_ap->encrypted;
@@ -278,21 +278,21 @@ void nm_ap_set_address (NMAccessPoint *ap, const struct ether_addr * addr)
 
 
 /*
- * Get/set functions for quality
+ * Get/set functions for strength
  *
  */
-guint8 nm_ap_get_quality (NMAccessPoint *ap)
+gint8 nm_ap_get_strength (NMAccessPoint *ap)
 {
        g_return_val_if_fail (ap != NULL, 0);
 
-       return (ap->quality);
+       return (ap->strength);
 }
 
-void  nm_ap_set_quality (NMAccessPoint *ap, guint8 quality)
+void  nm_ap_set_strength (NMAccessPoint *ap, gint8 strength)
 {
        g_return_if_fail (ap != NULL);
 
-       ap->quality = quality;
+       ap->strength = strength;
 }
 
 
index d8a7a12..c80e908 100644 (file)
@@ -38,16 +38,16 @@ typedef enum NMAPEncMethod
 
 
 NMAccessPoint *        nm_ap_new                               (void);
-NMAccessPoint *        nm_ap_new_from_ap                       (NMAccessPoint *ap);
+NMAccessPoint *        nm_ap_new_from_ap               (NMAccessPoint *ap);
 
-void                           nm_ap_unref                             (NMAccessPoint *ap);
+void                           nm_ap_unref                     (NMAccessPoint *ap);
 void                           nm_ap_ref                               (NMAccessPoint *ap);
 
 const GTimeVal *       nm_ap_get_timestamp             (NMAccessPoint *ap);
 void                           nm_ap_set_timestamp             (NMAccessPoint *ap, const GTimeVal *timestamp);
 
-gchar *                        nm_ap_get_essid                 (NMAccessPoint *ap);
-void                           nm_ap_set_essid                 (NMAccessPoint *ap, gchar *essid);
+gchar *                        nm_ap_get_essid         (NMAccessPoint *ap);
+void                           nm_ap_set_essid         (NMAccessPoint *ap, gchar *essid);
 
 gchar *                        nm_ap_get_enc_key_source        (NMAccessPoint *ap);
 gchar *                        nm_ap_get_enc_key_hashed        (NMAccessPoint *ap, NMAPEncMethod method);
@@ -56,11 +56,11 @@ void                                nm_ap_set_enc_key_source        (NMAccessPoint *ap, gchar *key);
 gboolean                       nm_ap_get_encrypted             (NMAccessPoint *ap);
 void                           nm_ap_set_encrypted             (NMAccessPoint *ap, gboolean encrypted);
 
-struct ether_addr *    nm_ap_get_address                       (NMAccessPoint *ap);
-void                           nm_ap_set_address                       (NMAccessPoint *ap, const struct ether_addr *addr);
+struct ether_addr *    nm_ap_get_address               (NMAccessPoint *ap);
+void                           nm_ap_set_address               (NMAccessPoint *ap, const struct ether_addr *addr);
 
-guint8                 nm_ap_get_quality                       (NMAccessPoint *ap);
-void                           nm_ap_set_quality                       (NMAccessPoint *ap, guint8 quality);
+gint8                  nm_ap_get_strength              (NMAccessPoint *ap);
+void                           nm_ap_set_strength              (NMAccessPoint *ap, gint8 strength);
 
 double                 nm_ap_get_freq                  (NMAccessPoint *ap);
 void                           nm_ap_set_freq                  (NMAccessPoint *ap, double freq);
@@ -68,19 +68,19 @@ void                                nm_ap_set_freq                  (NMAccessPoint *ap, double freq);
 guint16                        nm_ap_get_rate                  (NMAccessPoint *ap);
 void                           nm_ap_set_rate                  (NMAccessPoint *ap, guint16 rate);
 
-gboolean                       nm_ap_get_invalid                       (NMAccessPoint *ap);
-void                           nm_ap_set_invalid                       (NMAccessPoint *ap, gboolean invalid);
+gboolean                       nm_ap_get_invalid               (NMAccessPoint *ap);
+void                           nm_ap_set_invalid               (NMAccessPoint *ap, gboolean invalid);
 
-gboolean                       nm_ap_get_matched                       (NMAccessPoint *ap);
-void                           nm_ap_set_matched                       (NMAccessPoint *ap, gboolean matched);
+gboolean                       nm_ap_get_matched               (NMAccessPoint *ap);
+void                           nm_ap_set_matched               (NMAccessPoint *ap, gboolean matched);
 
-NMAPEncMethod          nm_ap_get_enc_method            (NMAccessPoint *ap);
-void                           nm_ap_set_enc_method            (NMAccessPoint *ap, NMAPEncMethod enc_method);
+NMAPEncMethod          nm_ap_get_enc_method    (NMAccessPoint *ap);
+void                           nm_ap_set_enc_method    (NMAccessPoint *ap, NMAPEncMethod enc_method);
 
-gboolean                       nm_ap_get_enc_method_good       (NMAccessPoint *ap);
-void                           nm_ap_set_enc_method_good       (NMAccessPoint *ap, gboolean good);
+gboolean                       nm_ap_get_enc_method_good(NMAccessPoint *ap);
+void                           nm_ap_set_enc_method_good(NMAccessPoint *ap, gboolean good);
 
-gboolean                       nm_ap_get_trusted                       (NMAccessPoint *ap);
-void                           nm_ap_set_trusted                       (NMAccessPoint *ap, gboolean trusted);
+gboolean                       nm_ap_get_trusted               (NMAccessPoint *ap);
+void                           nm_ap_set_trusted               (NMAccessPoint *ap, gboolean trusted);
 
 #endif
index 6801d64..b00bbca 100644 (file)
@@ -469,9 +469,9 @@ void nm_ap_list_print_members (NMAccessPointList *list, const char *name)
        while ((ap = nm_ap_list_iter_next (iter)))
        {
                const GTimeVal *timestamp = nm_ap_get_timestamp (ap);
-               syslog (LOG_DEBUG, "\t%d)\tessid='%s', timestamp=%ld, key='%s', enc=%d, addr=%p, qual=%d, freq=%f, rate=%d, inval=%d",
+               syslog (LOG_DEBUG, "\t%d)\tessid='%s', timestamp=%ld, key='%s', enc=%d, addr=%p, strength=%d, freq=%f, rate=%d, inval=%d",
                                i, nm_ap_get_essid (ap), timestamp->tv_sec, nm_ap_get_enc_key_source (ap), nm_ap_get_encrypted (ap),
-                               nm_ap_get_address (ap), nm_ap_get_quality (ap), nm_ap_get_freq (ap), nm_ap_get_rate (ap),
+                               nm_ap_get_address (ap), nm_ap_get_strength (ap), nm_ap_get_freq (ap), nm_ap_get_rate (ap),
                                nm_ap_get_invalid (ap));
                i++;
        }
index 5576878..1d7f8eb 100644 (file)
@@ -995,8 +995,8 @@ static DBusMessage *nm_dbus_devices_handle_networks_request (DBusConnection *con
                iw_ether_ntop((const struct ether_addr *) (nm_ap_get_address (ap)), &buf[0]);
                dbus_message_append_args (reply_message, DBUS_TYPE_STRING, &buf[0], DBUS_TYPE_INVALID);
        }
-       else if (strcmp ("getQuality", request) == 0)
-               dbus_message_append_args (reply_message, DBUS_TYPE_INT32, nm_ap_get_quality (ap), DBUS_TYPE_INVALID);
+       else if (strcmp ("getStrength", request) == 0)
+               dbus_message_append_args (reply_message, DBUS_TYPE_INT32, nm_ap_get_strength (ap), DBUS_TYPE_INVALID);
        else if (strcmp ("getFrequency", request) == 0)
                dbus_message_append_args (reply_message, DBUS_TYPE_DOUBLE, nm_ap_get_freq (ap), DBUS_TYPE_INVALID);
        else if (strcmp ("getRate", request) == 0)
@@ -1063,18 +1063,18 @@ static DBusMessage *nm_dbus_devices_handle_request (DBusConnection *connection,
                dbus_message_append_args (reply_message, DBUS_TYPE_STRING, nm_device_get_udi (dev), DBUS_TYPE_INVALID);
        else if (strcmp ("getIP4Address", request) == 0)
                dbus_message_append_args (reply_message, DBUS_TYPE_UINT32, nm_device_get_ip4_address (dev), DBUS_TYPE_INVALID);
-       else if (strcmp ("getMaxQuality", request) == 0)
+       else if (strcmp ("getStrength", request) == 0)
        {
-               /* Only wireless devices have an active network */
+               /* Only wireless devices have signal strength */
                if (!nm_device_is_wireless (dev))
                {
                        dbus_message_unref (reply_message);
                        reply_message = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "DeviceNotWireless",
-                                       "Wired devices cannot have wireless networks.");
+                                       "Wired devices cannot have signal strength.");
                        return (reply_message);
                }
 
-               dbus_message_append_args (reply_message, DBUS_TYPE_UINT32, nm_device_get_max_quality (dev), DBUS_TYPE_INVALID);
+               dbus_message_append_args (reply_message, DBUS_TYPE_INT32, nm_device_get_signal_strength (dev), DBUS_TYPE_INVALID);
        }
        else if (strcmp ("getActiveNetwork", request) == 0)
        {
index 318de1a..9b44ab0 100644 (file)
@@ -51,6 +51,8 @@ typedef struct NMDeviceWirelessOptions
        gchar                   *cur_essid;
        gboolean                         supports_wireless_scan;
        guint8                   max_quality;
+       guint8                   noise;
+       gint8                    strength;
 
        GMutex                  *scan_mutex;
        NMAccessPointList       *ap_list;
@@ -548,6 +550,8 @@ void nm_device_update_link_active (NMDevice *dev, gboolean check_mii)
        {
                case DEVICE_TYPE_WIRELESS_ETHERNET:
                        link = nm_device_wireless_link_active (dev);
+                       /* Update our current signal strength too */
+                       nm_device_update_signal_strength (dev);
                        break;
 
                case DEVICE_TYPE_WIRED_ETHERNET:
@@ -785,10 +789,103 @@ void nm_device_set_enc_key (NMDevice *dev, const char *key)
 }
 
 
+/*
+ * nm_device_get_signal_strength
+ *
+ * Get the current signal strength of a wireless device.  This only works when
+ * the card is associated with an access point, so will only work for the
+ * active device.
+ *
+ * Returns:    -1 on error
+ *                     0 - 100  strength percentage of the connection to the current access point
+ *
+ */
+gint8 nm_device_get_signal_strength (NMDevice *dev)
+{
+       g_return_val_if_fail (dev != NULL, -1);
+       g_return_val_if_fail (nm_device_is_wireless (dev), -1);
+
+       return (dev->options.wireless.strength);
+}
+
+
+/*
+ * nm_device_update_signal_strength
+ *
+ * Update the device's idea of the strength of its connection to the
+ * current access point.
+ *
+ */
+void nm_device_update_signal_strength (NMDevice *dev)
+{
+       gboolean        has_range;
+       int             iwlib_socket;
+       iwrange range;
+       iwstats stats;
+       int             percent = -1;
+
+       g_return_if_fail (dev != NULL);
+       g_return_if_fail (nm_device_is_wireless (dev));
+       g_return_if_fail (dev->app_data != NULL);
+
+       /* If we aren't the active device, we don't really have a signal strength
+        * that would mean anything.
+        */
+#if 0
+       if (dev != dev->app_data->active_device)
+       {
+               dev->options.wireless.strength = -1;
+               return;
+       }
+#endif
+
+       /* Fake a value for test devices */
+       if (dev->test_device)
+       {
+               dev->options.wireless.strength = 75;
+               return;
+       }
+
+       iwlib_socket = iw_sockets_open ();
+       has_range = (iw_get_range_info (iwlib_socket, nm_device_get_iface (dev), &range) >= 0);
+       if (iw_get_stats (iwlib_socket, nm_device_get_iface (dev), &stats, &range, has_range) == 0)
+       {
+               /* Update our max quality while we're at it */
+               dev->options.wireless.max_quality = range.max_qual.level;
+               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 (iwlib_socket);
+
+       dev->options.wireless.strength = percent;
+}
+
+
+/*
+ * 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 baseline of a wireless device.
+ * Get the quality maximum of a wireless device.
  *
  */
 guint8 nm_device_get_max_quality (NMDevice *dev)
@@ -1762,13 +1859,6 @@ static void nm_device_do_normal_scan (NMDevice *dev)
                wireless_scan           *tmp_ap;
                int                              err;
                NMAccessPointList       *old_ap_list = nm_device_ap_list_get (dev);
-               gboolean                         has_range;
-               iwrange                  range;
-               iwstats                  stats;
-
-               has_range = (iw_get_range_info (iwlib_socket, nm_device_get_iface (dev), &range) < 0) ? FALSE : TRUE;
-               if (!iw_get_stats (iwlib_socket, nm_device_get_iface (dev), &stats, &range, has_range))
-                       dev->options.wireless.max_quality = range.max_qual.qual;
 
                err = iw_scan (iwlib_socket, nm_device_get_iface (dev), WIRELESS_EXT, &scan_results);
                if ((err == -1) && (errno == ENODATA))
@@ -1825,7 +1915,7 @@ static void nm_device_do_normal_scan (NMDevice *dev)
                                if (tmp_ap->has_ap_addr)
                                        nm_ap_set_address (nm_ap, (const struct ether_addr *)(tmp_ap->ap_addr.sa_data));
 
-                               nm_ap_set_quality (nm_ap, tmp_ap->stats.qual.qual);
+                               nm_ap_set_strength (nm_ap, nm_wireless_qual_to_percent (dev, &(tmp_ap->stats.qual)));
 
                                if (tmp_ap->b.has_freq)
                                        nm_ap_set_freq (nm_ap, tmp_ap->b.freq);
@@ -1985,7 +2075,7 @@ static void nm_device_fake_ap_list (NMDevice *dev)
                }
 
                nm_ap_set_address (nm_ap, (const struct ether_addr *)(&fake_addrs[i]));
-               nm_ap_set_quality (nm_ap, fake_qualities[i]);
+               nm_ap_set_strength (nm_ap, fake_qualities[i]);
                nm_ap_set_freq (nm_ap, fake_freqs[i]);
 
                /* Merge settings from wireless networks, mainly Keys */
index eeb029a..650a966 100644 (file)
@@ -59,6 +59,10 @@ void                 nm_device_get_ip6_address               (NMDevice *dev);
 
 gboolean               nm_device_get_supports_wireless_scan (NMDevice *dev);
 void                   nm_device_do_wireless_scan              (NMDevice *dev);
+
+gint8          nm_device_get_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);
 
 NMAccessPoint *nm_device_get_best_ap                   (NMDevice *dev);
index 9a49282..7d77f65 100644 (file)
@@ -100,6 +100,63 @@ char *nm_wireless_128bit_key_from_passphrase       (char *passphrase)
 }
 
 
+/*
+ * nm_wireless_stats_to_percent
+ *
+ * Convert an iw_stats structure from a scan or the card into
+ * a magical signal strength percentage.
+ *
+ */
+int nm_wireless_qual_to_percent (NMDevice *dev, const struct iw_quality *qual)
+{
+       int     percent = -1;
+
+       g_return_val_if_fail (dev != NULL, -1);
+       g_return_val_if_fail (qual != NULL, -1);
+
+       /* Try using the card's idea of the signal quality first */
+       if (qual->qual >= 1)
+       {
+               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 :) */
+
+                       /* Values in dBm  (absolute power measurement) */
+                       if (qual->level > 0)
+                               percent = (int)rint ((double)(((256 - qual->level) / (double)BEST_SIGNAL) * 100));
+               }
+               else
+               {
+/* FIXME
+ * Not quite sure what to do here...  Above we have a "100% strength" number
+ * empirically derived, but I don't have any cards that trigger this code below...
+ */
+#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
+               }
+       }
+
+       return (percent);
+}
+
+
 /*
  * nm_wireless_scan_monitor
  *
index 7e43fcc..b834725 100644 (file)
@@ -22,6 +22,7 @@
 #ifndef NETWORK_MANAGER_WIRELESS_H
 #define NETWORK_MANAGER_WIRELESS_H
 
+#include <iwlib.h>
 #include "NetworkManager.h"
 #include "NetworkManagerDevice.h"
 #include "NetworkManagerAPList.h"
@@ -30,4 +31,6 @@ char *        nm_wireless_128bit_key_from_passphrase  (char *passphrase);
 
 gboolean       nm_wireless_scan_monitor                                (gpointer user_data);
 
+int            nm_wireless_qual_to_percent                     (NMDevice *dev, const struct iw_quality *qual);
+
 #endif
index d0bd292..952e584 100644 (file)
@@ -128,6 +128,49 @@ void get_device_name (DBusConnection *connection, char *path)
        dbus_message_unref (message);
 }
 
+
+int get_object_signal_strength (DBusConnection *connection, char *path)
+{
+       DBusMessage     *message;
+       DBusMessage     *reply;
+       DBusMessageIter iter;
+       DBusError                error;
+
+       message = dbus_message_new_method_call ("org.freedesktop.NetworkManager",
+                                               path,
+                                               "org.freedesktop.NetworkManager.Devices",
+                                               "getStrength");
+       if (message == NULL)
+       {
+               fprintf (stderr, "Couldn't allocate the dbus message\n");
+               return (0);
+       }
+
+       dbus_error_init (&error);
+       reply = dbus_connection_send_with_reply_and_block (connection, message, -1, &error);
+       dbus_message_unref (message);
+       if (dbus_error_is_set (&error))
+       {
+               fprintf (stderr, "%s raised:\n %s\n\n", error.name, error.message);
+               return (0);
+       }
+
+       if (reply == NULL)
+       {
+               fprintf( stderr, "dbus reply message was NULL\n" );
+               return (0);
+       }
+
+       /* now analyze reply */
+       dbus_message_iter_init (reply, &iter);
+       int qual = dbus_message_iter_get_int32 (&iter);
+
+       dbus_message_unref (reply);
+
+       return (qual);
+}
+
+
 void get_nm_status (DBusConnection *connection)
 {
        DBusMessage     *message;
@@ -305,10 +348,7 @@ int get_device_type (DBusConnection *connection, char *path)
 
        /* now analyze reply */
        dbus_message_iter_init (reply, &iter);
-       int     type;
-       type = dbus_message_iter_get_int32 (&iter);
-
-       fprintf (stderr, "      Device type: '%d'\n", type );
+       int     type = dbus_message_iter_get_int32 (&iter);
 
        dbus_message_unref (reply);
        dbus_message_unref (message);
@@ -317,6 +357,53 @@ int get_device_type (DBusConnection *connection, char *path)
 }
 
 
+const char * get_network_name (DBusConnection *connection, const char *path)
+{
+       DBusMessage     *message2;
+       DBusMessage     *reply2;
+       DBusMessageIter iter2;
+       DBusError                error2;
+
+       message2 = dbus_message_new_method_call ("org.freedesktop.NetworkManager",
+                                               path,
+                                               "org.freedesktop.NetworkManager",
+                                               "getName");
+       if (message2 == NULL)
+       {
+               fprintf (stderr, "Couldn't allocate the dbus message\n");
+               return (NULL);
+       }
+
+       dbus_error_init (&error2);
+       reply2 = dbus_connection_send_with_reply_and_block (connection, message2, -1, &error2);
+       dbus_message_unref (message2);
+       if (dbus_error_is_set (&error2))
+       {
+               fprintf (stderr, "%s raised:\n %s\n\n", error2.name, error2.message);
+               return (NULL);
+       }
+
+       if (reply2 == NULL)
+       {
+               fprintf( stderr, "dbus reply message was NULL\n" );
+               return (NULL);
+       }
+
+       /* now analyze reply */
+       dbus_message_iter_init (reply2, &iter2);
+       const char *string2 = dbus_message_iter_get_string (&iter2);
+       if (!string2)
+       {
+               fprintf (stderr, "NetworkManager returned a NULL network name" );
+               return (NULL);
+       }
+
+       dbus_message_unref (reply2);
+
+       return (string2);
+}
+
+
 void get_device_networks (DBusConnection *connection, const char *path)
 {
        DBusMessage     *message;
@@ -368,50 +455,11 @@ void get_device_networks (DBusConnection *connection, const char *path)
        fprintf( stderr, "      Networks:\n" );
        for (i = 0; i < num_networks; i++)
        {
-               DBusMessage     *message2;
-               DBusMessage     *reply2;
-               DBusMessageIter iter2;
-               DBusError                error2;
-
-               message2 = dbus_message_new_method_call ("org.freedesktop.NetworkManager",
-                                                       networks[i],
-                                                       "org.freedesktop.NetworkManager",
-                                                       "getName");
-               if (message2 == NULL)
-               {
-                       fprintf (stderr, "Couldn't allocate the dbus message\n");
-                       return;
-               }
-
-               dbus_error_init (&error2);
-               reply2 = dbus_connection_send_with_reply_and_block (connection, message2, -1, &error2);
-               if (dbus_error_is_set (&error2))
-               {
-                       fprintf (stderr, "%s raised:\n %s\n\n", error2.name, error2.message);
-                       dbus_message_unref (message2);
-                       return;
-               }
-       
-               if (reply2 == NULL)
-               {
-                       fprintf( stderr, "dbus reply message was NULL\n" );
-                       dbus_message_unref (message2);
-                       return;
-               }
-       
-               /* now analyze reply */
-               dbus_message_iter_init (reply2, &iter2);
-               const char *string2 = dbus_message_iter_get_string (&iter2);
-               if (!string2)
-               {
-                       fprintf (stderr, "NetworkManager returned a NULL active device object path" );
-                       return;
-               }
-       
-               dbus_message_unref (reply2);
-               dbus_message_unref (message2);
+               const char *name = get_network_name (connection, networks[i]);
 
-               fprintf( stderr, "         %s (%s)\n", networks[i], string2 );
+               fprintf( stderr, "         %s (%s)  Strength: %d%%\n", networks[i], name,
+                               get_object_signal_strength (connection, networks[i]) );
+               dbus_free (name);
        }
 
        dbus_free_string_array (networks);
@@ -471,13 +519,20 @@ void get_devices (DBusConnection *connection)
        {
                int      type;
 
-               fprintf (stderr, "   %s\n", devices[i]);
+               fprintf (stderr, "   %s", devices[i]);
                if ((type = get_device_type (connection, devices[i])) == 2)
                {
+                       fprintf (stderr, "   Strength: %d%%\n", get_object_signal_strength (connection, devices[i]));
+                       fprintf (stderr, "      Device type: '%d'\n", type );
                        get_device_active_network (connection, devices[i]);
                        get_device_networks (connection, devices[i]);
+                       fprintf (stderr, "\n");
+               }
+               else
+               {
+                       fprintf (stderr, "\n      Device type: '%d'\n", type );
+                       fprintf (stderr, "\n");
                }
-               fprintf (stderr, "\n");
        }
 
        dbus_free_string_array (devices);