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


git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@156 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
This commit is contained in:
Dan Williams 2004-09-13 17:43:16 +00:00
parent 30a3c10262
commit ee710f0377
15 changed files with 571 additions and 187 deletions

View file

@ -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

2
TODO
View file

@ -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

View 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

View 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);
}

View 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

View 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);
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++;
}
/*
* 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);
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)
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)
{
applet->applet_state = APPLET_STATE_NO_CONNECTION;
goto out;
}
else if (dev_type == DEVICE_TYPE_WIRED_ETHERNET)
/* If the device is not 802.x, we don't show state for it (yet) */
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 (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;

View 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;
}

View 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

View 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++;
}

View 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)
{

View 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 */

View 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);

View 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
*

View 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

View 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;
const char *name = get_network_name (connection, networks[i]);
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);
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);