Thu Aug 26 2004 Dan Williams <dcbw@redhat.com>

* panel-applet/NMWirelessApplet.[ch]
		- Rework menu code to add devices to menu, and to show
			signal strength for each access point.  Code cleanups
			too.

	* panel-applet/NMWirelessAppletDbus.c
		- Grab network devices from NetworkManager too
		- Grab quality information from NM for wireless networks

	* src/NetworkManagerDbus.[ch]
		- Add dbus methods for getting the HAL UDI from a device and
			for getting its base quality, if its wireless
		- Consolidate some functions (wireless network notifications,
			device notifications)
		- Add method for requesting NM to use a particular device

	* src/NetworkManager.c
		- Change for function consolidations from NetworkManagerDbus.c
		- Implement active device locking and user-requested devices
			(ie, tell NM to use a particular device instead of the one
			it autochose)

	* src/NetworkManagerDevice.c
		- Add method for getting the base quality of a device, if its
			wireless
		- Grab device base quailty info from iwlib during scans

	* src/NetworkManagerPolicy.c
		- Use a user-requested device rather than the auto-chosen device
			if we are told to


git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@81 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
This commit is contained in:
Dan Williams
2004-08-26 20:05:24 +00:00
parent d3aff52822
commit 305ff0adb0
14 changed files with 645 additions and 295 deletions

View File

@@ -1,3 +1,36 @@
Thu Aug 26 2004 Dan Williams <dcbw@redhat.com>
* panel-applet/NMWirelessApplet.[ch]
- Rework menu code to add devices to menu, and to show
signal strength for each access point. Code cleanups
too.
* panel-applet/NMWirelessAppletDbus.c
- Grab network devices from NetworkManager too
- Grab quality information from NM for wireless networks
* src/NetworkManagerDbus.[ch]
- Add dbus methods for getting the HAL UDI from a device and
for getting its base quality, if its wireless
- Consolidate some functions (wireless network notifications,
device notifications)
- Add method for requesting NM to use a particular device
* src/NetworkManager.c
- Change for function consolidations from NetworkManagerDbus.c
- Implement active device locking and user-requested devices
(ie, tell NM to use a particular device instead of the one
it autochose)
* src/NetworkManagerDevice.c
- Add method for getting the base quality of a device, if its
wireless
- Grab device base quailty info from iwlib during scans
* src/NetworkManagerPolicy.c
- Use a user-requested device rather than the auto-chosen device
if we are told to
Thu Aug 26 15:12:36 2004 Jonathan Blandford <jrb@redhat.com> Thu Aug 26 15:12:36 2004 Jonathan Blandford <jrb@redhat.com>
* Makefile.am: add po as a supdir * Makefile.am: add po as a supdir

View File

@@ -100,6 +100,7 @@ static void nmi_dbus_get_key_for_network (NMIAppInfo *info, DBusMessage *message
DBUS_TYPE_STRING, &network, DBUS_TYPE_STRING, &network,
DBUS_TYPE_INVALID)) DBUS_TYPE_INVALID))
{ {
fprintf( stderr, "getUserKey\n");
nmi_passphrase_dialog_show (device, network, info); nmi_passphrase_dialog_show (device, network, info);
dbus_free (device); dbus_free (device);

View File

@@ -46,6 +46,7 @@ glade_DATA = wireless-applet.glade
pixmapdir = $(datadir)/pixmaps/NMWirelessApplet pixmapdir = $(datadir)/pixmaps/NMWirelessApplet
pixmap_DATA = no-link-0.png \ pixmap_DATA = no-link-0.png \
wired.png \ wired.png \
wireless.png \
broken-0.png \ broken-0.png \
signal-1-40.png \ signal-1-40.png \
signal-41-60.png \ signal-41-60.png \

View File

@@ -211,6 +211,12 @@ static void nmwa_load_theme (NMWirelessApplet *applet)
pixmapname = g_build_filename (G_DIR_SEPARATOR_S, pixmapdir, "keyring.png", NULL); pixmapname = g_build_filename (G_DIR_SEPARATOR_S, pixmapdir, "keyring.png", NULL);
applet->key_pixbuf = gdk_pixbuf_new_from_file_at_size (pixmapname, 16, 16, &error); applet->key_pixbuf = gdk_pixbuf_new_from_file_at_size (pixmapname, 16, 16, &error);
g_free (pixmapname); g_free (pixmapname);
pixmapname = g_build_filename (G_DIR_SEPARATOR_S, pixmapdir, "wired.png", NULL);
applet->wired_icon = gdk_pixbuf_new_from_file_at_size (pixmapname, 16, 16, &error);
g_free (pixmapname);
pixmapname = g_build_filename (G_DIR_SEPARATOR_S, pixmapdir, "wireless.png", NULL);
applet->wireless_icon = gdk_pixbuf_new_from_file_at_size (pixmapname, 16, 16, &error);
g_free (pixmapname);
g_free (pixmapdir); g_free (pixmapdir);
} }
@@ -454,17 +460,132 @@ static void nmwa_toplevel_menu_activate (GtkWidget *menu, NMWirelessApplet *appl
/* /*
* nmwa_add_menu_item * nmwa_menu_add_separator_item
*
* Add a menu item
* *
*/ */
void nmwa_add_menu_item (NMWirelessApplet *applet, GtkWidget *menu, char *text, char *tag, gboolean current, void nmwa_menu_add_separator_item (GtkWidget *menu)
gboolean encrypted) {
GtkWidget *menu_item;
menu_item = gtk_separator_menu_item_new ();
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
gtk_widget_show (menu_item);
}
/*
* nmwa_menu_add_text_item
*
* Add a non-clickable text item to a menu
*
*/
void nmwa_menu_add_text_item (GtkWidget *menu, char *text)
{
GtkWidget *menu_item;
GtkWidget *label;
g_return_if_fail (text != NULL);
g_return_if_fail (menu != NULL);
menu_item = gtk_menu_item_new_with_label (text);
gtk_widget_set_sensitive (menu_item, FALSE);
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
gtk_widget_show (menu_item);
}
/*
* nmwa_menu_add_device_item
*
* Add a network device to the menu
*
*/
void nmwa_menu_add_device_item (GtkWidget *menu, GdkPixbuf *icon, char *name, char *nm_device, gpointer user_data)
{ {
GtkWidget *menu_item; GtkWidget *menu_item;
GtkWidget *label; GtkWidget *label;
GtkWidget *hbox; GtkWidget *hbox;
GtkWidget *image;
g_return_if_fail (menu != NULL);
g_return_if_fail (icon != NULL);
g_return_if_fail (name != NULL);
g_return_if_fail (nm_device != NULL);
menu_item = gtk_menu_item_new ();
hbox = gtk_hbox_new (FALSE, 5);
gtk_container_add (GTK_CONTAINER (menu_item), hbox);
gtk_widget_show (hbox);
if ((image = gtk_image_new_from_pixbuf (icon)))
{
gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 2);
gtk_widget_show (image);
}
label = gtk_label_new (name);
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 2);
gtk_widget_show (label);
g_object_set_data (G_OBJECT (menu_item), "device", g_strdup (nm_device));
g_signal_connect(G_OBJECT (menu_item), "activate", G_CALLBACK(nmwa_menu_item_activate), user_data);
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
gtk_widget_show (menu_item);
}
/*
* nmwa_menu_add_devices
*
*/
void nmwa_menu_add_devices (GtkWidget *menu, NMWirelessApplet *applet)
{
GSList *element;
g_return_if_fail (menu != NULL);
g_return_if_fail (applet != NULL);
g_mutex_lock (applet->data_mutex);
element = applet->devices;
if (!element)
nmwa_menu_add_text_item (menu, _("There are no network devices..."));
else
{
/* Add all devices in our device list to the menu */
while (element)
{
NetworkDevice *dev = (NetworkDevice *)(element->data);
if (dev && ((dev->type == DEVICE_TYPE_WIRED_ETHERNET) || (dev->type == DEVICE_TYPE_WIRELESS_ETHERNET)))
{
GdkPixbuf *icon = (dev->type == DEVICE_TYPE_WIRED_ETHERNET) ? applet->wired_icon : applet->wireless_icon;
nmwa_menu_add_device_item (menu, icon, dev->name, dev->nm_device, applet);
}
element = g_slist_next (element);
}
}
g_mutex_unlock (applet->data_mutex);
}
/*
* nmwa_menu_add_network
*
* Add a wireless network menu item
*
*/
void nmwa_menu_add_network (GtkWidget *menu, GdkPixbuf *key, char *text, char *network, gboolean current,
gboolean encrypted, guint8 quality, gpointer user_data)
{
GtkWidget *menu_item;
GtkWidget *label;
GtkWidget *hbox;
GtkWidget *progress;
float percent;
g_return_if_fail (text != NULL); g_return_if_fail (text != NULL);
g_return_if_fail (menu != NULL); g_return_if_fail (menu != NULL);
@@ -485,25 +606,64 @@ void nmwa_add_menu_item (NMWirelessApplet *applet, GtkWidget *menu, char *text,
gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 2); gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 2);
gtk_widget_show (label); gtk_widget_show (label);
progress = gtk_progress_bar_new ();
percent = ((float)quality / (float)0x100);
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);
gtk_widget_show (progress);
if (encrypted) if (encrypted)
{ {
GtkWidget *image; GtkWidget *image;
if ((image = gtk_image_new_from_pixbuf (applet->key_pixbuf))) if ((image = gtk_image_new_from_pixbuf (key)))
{ {
gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 2); gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 2);
gtk_widget_show (image); gtk_widget_show (image);
} }
} }
g_object_set_data (G_OBJECT (menu_item), "network", g_strdup (tag)); g_object_set_data (G_OBJECT (menu_item), "network", g_strdup (network));
g_signal_connect(G_OBJECT (menu_item), "activate", G_CALLBACK(nmwa_menu_item_activate), applet); g_signal_connect(G_OBJECT (menu_item), "activate", G_CALLBACK(nmwa_menu_item_activate), user_data);
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item); gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
gtk_widget_show (menu_item); gtk_widget_show (menu_item);
} }
/*
* nmwa_menu_add_networks
*
*/
void nmwa_menu_add_networks (GtkWidget *menu, NMWirelessApplet *applet)
{
GSList *element;
g_return_if_fail (menu != NULL);
g_return_if_fail (applet != NULL);
g_mutex_lock (applet->data_mutex);
element = applet->networks;
if (!element)
nmwa_menu_add_text_item (menu, _("There are no wireless networks..."));
else
{
/* Add all networks in our network list to the menu */
while (element)
{
WirelessNetwork *net = (WirelessNetwork *)(element->data);
if (net)
nmwa_menu_add_network (menu, applet->key_pixbuf, net->essid,
net->essid, net->active, net->encrypted, net->quality, applet);
element = g_slist_next (element);
}
}
g_mutex_unlock (applet->data_mutex);
}
/* /*
* nmwa_menu_item_data_free * nmwa_menu_item_data_free
* *
@@ -557,49 +717,30 @@ GtkWidget * nmwa_populate_menu (NMWirelessApplet *applet)
g_return_if_fail (applet != NULL); g_return_if_fail (applet != NULL);
fprintf( stderr, "populate_menu() state (%d)\n", applet->applet_state); fprintf( stderr, "populate_menu() state (%d)\n", applet->applet_state);
if (applet->applet_state == APPLET_STATE_NO_NM)
{
nmwa_menu_add_text_item (menu, _("NetworkManager is not running..."));
return;
}
nmwa_menu_add_devices (menu, applet);
nmwa_menu_add_separator_item (menu);
switch (applet->applet_state) switch (applet->applet_state)
{ {
case (APPLET_STATE_NO_NM):
nmwa_add_menu_item (applet, menu, _("NetworkManager is not running..."),
NULL, FALSE, FALSE);
break;
case (APPLET_STATE_NO_CONNECTION): case (APPLET_STATE_NO_CONNECTION):
nmwa_add_menu_item (applet, menu, _("No network connection is currently active..."), nmwa_menu_add_text_item (menu, _("No network connection is currently active..."));
NULL, FALSE, FALSE);
break; break;
case (APPLET_STATE_WIRED): case (APPLET_STATE_WIRED):
case (APPLET_STATE_WIRED_CONNECTING): case (APPLET_STATE_WIRED_CONNECTING):
nmwa_add_menu_item (applet, menu, _("A wired network connection is currently active..."), nmwa_menu_add_text_item (menu, _("A wired network connection is currently active..."));
NULL, FALSE, FALSE);
break; break;
case (APPLET_STATE_WIRELESS): case (APPLET_STATE_WIRELESS):
case (APPLET_STATE_WIRELESS_CONNECTING): case (APPLET_STATE_WIRELESS_CONNECTING):
{ nmwa_menu_add_networks (menu, applet);
GSList *element = applet->networks;
g_mutex_lock (applet->networks_mutex);
if (!element)
nmwa_add_menu_item (applet, menu, _("There are no wireless networks..."),
NULL, FALSE, FALSE);
else
{
/* Add all networks in our network list to the menu */
while (element)
{
WirelessNetwork *net = (WirelessNetwork *)(element->data);
if (net)
nmwa_add_menu_item (applet, menu, net->essid,
net->essid, net->active, net->encrypted);
element = g_slist_next (element);
}
}
g_mutex_unlock (applet->networks_mutex);
break; break;
}
default: default:
break; break;
@@ -746,7 +887,7 @@ static GtkWidget * nmwa_new (NMWirelessApplet *applet)
applet->applet_state = APPLET_STATE_NO_NM; applet->applet_state = APPLET_STATE_NO_NM;
/* Start our dbus thread */ /* Start our dbus thread */
if (!(applet->networks_mutex = g_mutex_new ())) if (!(applet->data_mutex = g_mutex_new ()))
{ {
g_object_unref (G_OBJECT (applet->gconf_client)); g_object_unref (G_OBJECT (applet->gconf_client));
/* FIXME: free glade file */ /* FIXME: free glade file */
@@ -754,7 +895,7 @@ static GtkWidget * nmwa_new (NMWirelessApplet *applet)
} }
if (!(applet->dbus_thread = g_thread_create (nmwa_dbus_worker, applet, FALSE, &error))) if (!(applet->dbus_thread = g_thread_create (nmwa_dbus_worker, applet, FALSE, &error)))
{ {
g_mutex_free (applet->networks_mutex); g_mutex_free (applet->data_mutex);
g_object_unref (G_OBJECT (applet->gconf_client)); g_object_unref (G_OBJECT (applet->gconf_client));
/* FIXME: free glade file */ /* FIXME: free glade file */
return (NULL); return (NULL);

View File

@@ -77,9 +77,12 @@ typedef struct
GdkPixbuf *pixmaps[PIX_NUMBER]; GdkPixbuf *pixmaps[PIX_NUMBER];
GdkPixbuf *current_pixbuf; GdkPixbuf *current_pixbuf;
GdkPixbuf *key_pixbuf; GdkPixbuf *key_pixbuf;
GdkPixbuf *wired_icon;
GdkPixbuf *wireless_icon;
/* Data model elements */ /* Data model elements */
GMutex *networks_mutex; GMutex *data_mutex;
GSList *devices;
GSList *networks; GSList *networks;
AppletState applet_state; AppletState applet_state;
@@ -101,6 +104,19 @@ typedef struct
char *essid; char *essid;
gboolean encrypted; gboolean encrypted;
gboolean active; gboolean active;
guint8 quality;
} WirelessNetwork; } WirelessNetwork;
/*
* Representation of network device
*
*/
typedef struct
{
char *nm_device;
int type;
char *name;
char *udi;
} NetworkDevice;
#endif #endif

View File

@@ -426,6 +426,30 @@ int nmwa_dbus_get_device_type (NMWirelessApplet *applet, char *path, AppletState
} }
/*
* nmwa_dbus_get_network_quality
*
* Returns the quality of a given wireless network
*
*/
guint8 nmwa_dbus_get_network_quality (NMWirelessApplet *applet, char *path)
{
int qual = 0;
switch (nmwa_dbus_get_int (applet->connection, path, "getQuality", &qual))
{
case (RETURN_NO_NM):
applet->applet_state = APPLET_STATE_NO_NM;
break;
default:
break;
}
return (qual);
}
/* /*
* nmwa_dbus_get_nm_status * nmwa_dbus_get_nm_status
* *
@@ -478,6 +502,54 @@ char * nmwa_dbus_get_network_name (NMWirelessApplet *applet, char *net_path)
} }
/*
* nmwa_dbus_get_device_name
*
* Returns the name of a specified network device
*
*/
char * nmwa_dbus_get_device_name (NMWirelessApplet *applet, char *dev_path)
{
char *name = NULL;
switch (nmwa_dbus_get_string (applet->connection, dev_path, "getName", &name))
{
case (RETURN_NO_NM):
applet->applet_state = APPLET_STATE_NO_NM;
break;
default:
break;
}
return (name);
}
/*
* nmwa_dbus_get_device_udi
*
* Returns the HAL udi of a network device
*
*/
char * nmwa_dbus_get_device_udi (NMWirelessApplet *applet, char *dev_path)
{
char *udi = NULL;
switch (nmwa_dbus_get_string (applet->connection, dev_path, "getHalUdi", &udi))
{
case (RETURN_NO_NM):
applet->applet_state = APPLET_STATE_NO_NM;
break;
default:
break;
}
return (udi);
}
/* /*
* nmwa_dbus_get_network_encrypted * nmwa_dbus_get_network_encrypted
* *
@@ -591,7 +663,7 @@ void nmwa_dbus_update_wireless_network_list (NMWirelessApplet *applet)
int i; int i;
/* Grab the lock for the network list. */ /* Grab the lock for the network list. */
g_mutex_lock (applet->networks_mutex); g_mutex_lock (applet->data_mutex);
/* Clear out existing entries in the list */ /* Clear out existing entries in the list */
if (applet->networks) if (applet->networks)
@@ -600,7 +672,7 @@ void nmwa_dbus_update_wireless_network_list (NMWirelessApplet *applet)
g_slist_free (applet->networks); g_slist_free (applet->networks);
applet->networks = NULL; applet->networks = NULL;
} }
g_mutex_unlock (applet->networks_mutex); g_mutex_unlock (applet->data_mutex);
if ( (applet->applet_state != APPLET_STATE_WIRELESS) if ( (applet->applet_state != APPLET_STATE_WIRELESS)
&& (applet->applet_state != APPLET_STATE_WIRELESS_CONNECTING)) && (applet->applet_state != APPLET_STATE_WIRELESS_CONNECTING))
@@ -625,7 +697,7 @@ void nmwa_dbus_update_wireless_network_list (NMWirelessApplet *applet)
if (!networks) if (!networks)
goto out; goto out;
g_mutex_lock (applet->networks_mutex); g_mutex_lock (applet->data_mutex);
for (i = 0; i < num_items; i++) for (i = 0; i < num_items; i++)
{ {
@@ -654,13 +726,14 @@ void nmwa_dbus_update_wireless_network_list (NMWirelessApplet *applet)
net->essid = g_strdup (name); net->essid = g_strdup (name);
net->active = active_network ? (strcmp (networks[i], active_network) == 0) : FALSE; net->active = active_network ? (strcmp (networks[i], active_network) == 0) : FALSE;
net->encrypted = nmwa_dbus_get_network_encrypted (applet, networks[i]); net->encrypted = nmwa_dbus_get_network_encrypted (applet, networks[i]);
net->quality = nmwa_dbus_get_network_quality (applet, networks[i]);
fprintf( stderr, "Adding '%s' active (%d), enc (%d)\n", name, net->active, net->encrypted); fprintf( stderr, "Adding '%s' active (%d), enc (%d)\n", name, net->active, net->encrypted);
applet->networks = g_slist_append (applet->networks, net); applet->networks = g_slist_append (applet->networks, net);
} }
dbus_free (name); dbus_free (name);
} }
g_mutex_unlock (applet->networks_mutex); g_mutex_unlock (applet->data_mutex);
out: out:
dbus_free (active_device); dbus_free (active_device);
@@ -726,6 +799,92 @@ out:
} }
/*
* network_device_free
*
* Frees the representation of a network device
*
*/
static void network_device_free (void *element, void *user_data)
{
NetworkDevice *dev = (NetworkDevice *)(element);
if (dev)
{
g_free (dev->nm_device);
g_free (dev->name);
g_free (dev->udi);
}
g_free (dev);
}
/*
* nmwa_dbus_update_devices
*
* Get a device list from NetworkManager
*
*/
void nmwa_dbus_update_devices (NMWirelessApplet *applet)
{
char **devices = NULL;
int num_items = 0;
int i;
g_return_if_fail (applet->data_mutex != NULL);
switch (nmwa_dbus_get_string_array (applet->connection, NM_DBUS_PATH, "getDevices", &num_items, &devices))
{
case (RETURN_NO_NM):
applet->applet_state = APPLET_STATE_NO_NM;
break;
default:
break;
}
if (!devices)
return;
/* Clear out existing device list */
g_mutex_lock (applet->data_mutex);
g_slist_foreach (applet->devices, network_device_free, NULL);
g_slist_free (applet->devices);
applet->devices = NULL;
for (i = 0; i < num_items; i++)
{
char *name = nmwa_dbus_get_device_name (applet, devices [i]);
if (name && strlen (name))
{
NetworkDevice *dev;
if ((dev = g_new0 (NetworkDevice, 1)))
{
dev->nm_device = g_strdup (devices[i]);
dev->type = nmwa_dbus_get_device_type (applet, devices[i], APPLET_STATE_NO_CONNECTION);
dev->name = g_strdup (name);
dev->udi = nmwa_dbus_get_device_udi (applet, devices[i]);
/* Ensure valid device information */
if (!dev->nm_device || !dev->name || !dev->udi || (dev->type == -1))
network_device_free (dev, NULL);
else
{
applet->devices = g_slist_append (applet->devices, dev);
fprintf( stderr, "Got device '%s', udi '%s'\n", dev->name, dev->udi);
}
}
}
dbus_free (name);
}
g_mutex_unlock (applet->data_mutex);
dbus_free_string_array (devices);
}
/* /*
* nmwa_dbus_filter * nmwa_dbus_filter
* *
@@ -773,6 +932,8 @@ fprintf( stderr, "ServiceCreate state = (%d)\n", applet->applet_state);
{ {
nmwa_dbus_update_network_state (applet); nmwa_dbus_update_network_state (applet);
} }
else if (dbus_message_is_signal (message, NM_DBUS_INTERFACE, "DevicesChanged"))
nmwa_dbus_update_devices (applet);
else else
handled = FALSE; handled = FALSE;
@@ -902,6 +1063,7 @@ gpointer nmwa_dbus_worker (gpointer user_data)
nmwa_dbus_update_network_state (applet); nmwa_dbus_update_network_state (applet);
if ((applet->applet_state == APPLET_STATE_WIRELESS) || (applet->applet_state == APPLET_STATE_WIRELESS_CONNECTING)) if ((applet->applet_state == APPLET_STATE_WIRELESS) || (applet->applet_state == APPLET_STATE_WIRELESS_CONNECTING))
nmwa_dbus_update_wireless_network_list (applet); nmwa_dbus_update_wireless_network_list (applet);
nmwa_dbus_update_devices (applet);
} }
else else
applet->applet_state = APPLET_STATE_NO_NM; applet->applet_state = APPLET_STATE_NO_NM;

View File

@@ -106,7 +106,10 @@ NMDevice * nm_create_device_and_add_to_list (NMData *data, const char *udi)
hal_free_string (iface_name); hal_free_string (iface_name);
if (success) if (success)
{
nm_data_set_state_modified (data, TRUE); nm_data_set_state_modified (data, TRUE);
nm_dbus_signal_device_status_change (data->dbus_connection, dev, DEVICE_LIST_CHANGE);
}
else else
{ {
/* If we couldn't add the device to our list, free its data. */ /* If we couldn't add the device to our list, free its data. */
@@ -143,24 +146,31 @@ void nm_remove_device_from_list (NMData *data, const char *udi)
{ {
NMDevice *dev = (NMDevice *)(element->data); NMDevice *dev = (NMDevice *)(element->data);
if (dev) if (dev && (nm_null_safe_strcmp (nm_device_get_udi (dev), udi) == 0))
{ {
if (nm_null_safe_strcmp (nm_device_get_udi (dev), udi) == 0) if (data->active_device && (dev == data->active_device))
{ {
if (data->active_device && (dev == data->active_device)) data->active_device = NULL;
data->active_device = NULL; data->active_device_locked = FALSE;
nm_device_activation_cancel (dev);
nm_device_unref (dev);
/* Remove the device entry from the device list and free its data */
data->dev_list = g_slist_remove_link (data->dev_list, element);
nm_device_unref (element->data);
g_slist_free (element);
nm_data_set_state_modified (data, TRUE);
break;
} }
if (data->user_device && (dev == data->user_device))
{
nm_device_unref (data->user_device);
data->user_device = NULL;
}
nm_device_activation_cancel (dev);
nm_device_unref (dev);
/* Remove the device entry from the device list and free its data */
data->dev_list = g_slist_remove_link (data->dev_list, element);
nm_device_unref (element->data);
g_slist_free (element);
nm_data_set_state_modified (data, TRUE);
nm_dbus_signal_device_status_change (data->dbus_connection, dev, DEVICE_LIST_CHANGE);
break;
} }
element = g_slist_next (element); element = g_slist_next (element);
} }
@@ -386,19 +396,12 @@ static NMData *nm_data_new (void)
/* Initialize the device list mutex to protect additions/deletions to it. */ /* Initialize the device list mutex to protect additions/deletions to it. */
data->dev_list_mutex = g_mutex_new (); data->dev_list_mutex = g_mutex_new ();
if (!data->dev_list_mutex) data->user_device_mutex = g_mutex_new ();
{
nm_data_free (data);
syslog( LOG_ERR, "Could not create device list mutex. Whacky shit going on?");
return (NULL);
}
/* Initialize the state modified mutex. */
data->state_modified_mutex = g_mutex_new (); data->state_modified_mutex = g_mutex_new ();
if (!data->state_modified_mutex) if (!data->dev_list_mutex || !data->user_device_mutex || !data->state_modified_mutex)
{ {
nm_data_free (data); nm_data_free (data);
syslog( LOG_ERR, "Could not create state_modified mutex. Whacky stuff going on?"); syslog( LOG_ERR, "Could not initialize data structure locks.");
return (NULL); return (NULL);
} }
@@ -420,19 +423,6 @@ static NMData *nm_data_new (void)
} }
/*
* nm_data_dev_list_element_free
*
* Frees each member of the device list before the list is
* disposed of.
*
*/
static void nm_data_dev_list_element_free (void *element, void *user_data)
{
nm_device_unref (element);
}
/* /*
* nm_data_free * nm_data_free
* *
@@ -445,9 +435,12 @@ static void nm_data_free (NMData *data)
nm_device_unref (data->active_device); nm_device_unref (data->active_device);
g_slist_foreach (data->dev_list, nm_data_dev_list_element_free, NULL); g_slist_foreach (data->dev_list, nm_device_unref, NULL);
g_slist_free (data->dev_list); g_slist_free (data->dev_list);
g_mutex_free (data->dev_list_mutex); g_mutex_free (data->dev_list_mutex);
g_mutex_free (data->user_device_mutex);
g_mutex_free (data->state_modified_mutex);
nm_ap_list_unref (data->trusted_ap_list); nm_ap_list_unref (data->trusted_ap_list);
nm_ap_list_unref (data->preferred_ap_list); nm_ap_list_unref (data->preferred_ap_list);

View File

@@ -38,6 +38,10 @@ struct NMData
GMutex *dev_list_mutex; GMutex *dev_list_mutex;
struct NMDevice *active_device; struct NMDevice *active_device;
gboolean active_device_locked;
struct NMDevice *user_device; /* Holds a device that the user requests NM to use. */
GMutex *user_device_mutex;
gboolean state_modified; gboolean state_modified;
GMutex *state_modified_mutex; GMutex *state_modified_mutex;

View File

@@ -328,7 +328,7 @@ void nm_ap_list_diff (NMData *data, NMDevice *dev, NMAccessPointList *old, NMAcc
nm_ap_set_enc_method (new_ap, nm_ap_get_enc_method (old_ap)); nm_ap_set_enc_method (new_ap, nm_ap_get_enc_method (old_ap));
} }
else else
nm_dbus_signal_wireless_network_disappeared (data->dbus_connection, dev, old_ap); nm_dbus_signal_wireless_network_change (data->dbus_connection, dev, old_ap, TRUE);
} }
nm_ap_list_iter_free (iter); nm_ap_list_iter_free (iter);
} }
@@ -341,7 +341,7 @@ void nm_ap_list_diff (NMData *data, NMDevice *dev, NMAccessPointList *old, NMAcc
while ((new_ap = nm_ap_list_iter_next (iter))) while ((new_ap = nm_ap_list_iter_next (iter)))
{ {
if (!nm_ap_get_matched (new_ap)) if (!nm_ap_get_matched (new_ap))
nm_dbus_signal_wireless_network_appeared (data->dbus_connection, dev, new_ap); nm_dbus_signal_wireless_network_change (data->dbus_connection, dev, new_ap, FALSE);
} }
nm_ap_list_iter_free (iter); nm_ap_list_iter_free (iter);
} }

View File

@@ -194,6 +194,61 @@ static DBusMessage *nm_dbus_nm_get_active_device (DBusConnection *connection, DB
} }
/*
* nm_dbus_nm_set_active_device
*
* Notify the state modification handler that we want to lock to a specific
* device.
*
*/
static DBusMessage *nm_dbus_nm_set_active_device (DBusConnection *connection, DBusMessage *message, NMData *data)
{
NMDevice *dev = NULL;
DBusMessage *reply_message = NULL;
char *dev_path = NULL;
DBusError error;
g_return_val_if_fail (connection != NULL, NULL);
g_return_val_if_fail (message != NULL, NULL);
g_return_val_if_fail (data != NULL, NULL);
dbus_error_init (&error);
if (!dbus_message_get_args (message, &error, DBUS_TYPE_STRING, &dev_path, DBUS_TYPE_INVALID))
{
reply_message = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "InvalidArguments",
"NetworkManager::setActiveDevice called with invalid arguments.");
return (reply_message);
}
dev = nm_dbus_get_device_from_object_path (data, dev_path);
dbus_free (dev_path);
if (!dev)
{
reply_message = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "DeviceNotFound",
"The requested network device does not exist.");
return (reply_message);
}
if (!(reply_message = dbus_message_new_method_return (message)))
return (NULL);
/* Notify the state modification handler that we'd like to lock on a specific device */
if (nm_try_acquire_mutex (data->user_device_mutex, __FUNCTION__))
{
if (data->user_device)
nm_device_unref (data->user_device);
nm_device_ref (dev);
data->user_device = dev;
nm_unlock_mutex (data->user_device_mutex, __FUNCTION__);
nm_data_set_state_modified (data, TRUE);
}
return (reply_message);
}
/* /*
* nm_dbus_nm_get_devices * nm_dbus_nm_get_devices
* *
@@ -266,15 +321,17 @@ static DBusMessage *nm_dbus_nm_get_devices (DBusConnection *connection, DBusMess
/* /*
* nm_dbus_signal_device_no_longer_active * nm_dbus_signal_device_status_change
* *
* Notifies the bus that a particular device is no longer active. * Notifies the bus that a particular device has had a status change, either
* active or no longer active
* *
*/ */
void nm_dbus_signal_device_no_longer_active (DBusConnection *connection, NMDevice *dev) void nm_dbus_signal_device_status_change (DBusConnection *connection, NMDevice *dev, DeviceStatus status)
{ {
DBusMessage *message; DBusMessage *message;
unsigned char *dev_path; unsigned char *dev_path;
unsigned char *signal = NULL;
g_return_if_fail (connection != NULL); g_return_if_fail (connection != NULL);
g_return_if_fail (dev != NULL); g_return_if_fail (dev != NULL);
@@ -282,10 +339,28 @@ void nm_dbus_signal_device_no_longer_active (DBusConnection *connection, NMDevic
if (!(dev_path = nm_dbus_get_object_path_from_device (dev))) if (!(dev_path = nm_dbus_get_object_path_from_device (dev)))
return; return;
message = dbus_message_new_signal (NM_DBUS_PATH, NM_DBUS_INTERFACE, "DeviceNoLongerActive"); switch (status)
if (!message)
{ {
syslog (LOG_ERR, "nm_dbus_signal_device_no_longer_active(): Not enough memory for new dbus message!"); case (DEVICE_NO_LONGER_ACTIVE):
signal = "DeviceNoLongerActive";
break;
case (DEVICE_NOW_ACTIVE):
signal = "DeviceNowActive";
break;
case (DEVICE_ACTIVATING):
signal = "DeviceActivating";
break;
case (DEVICE_LIST_CHANGE):
signal = "DevicesChanged";
break;
default:
syslog (LOG_ERR, "nm_dbus_signal_device_status_change(): got a bad signal name");
return;
}
if (!(message = dbus_message_new_signal (NM_DBUS_PATH, NM_DBUS_INTERFACE, signal)))
{
syslog (LOG_ERR, "nm_dbus_signal_device_status_change(): Not enough memory for new dbus message!");
g_free (dev_path); g_free (dev_path);
return; return;
} }
@@ -294,77 +369,7 @@ void nm_dbus_signal_device_no_longer_active (DBusConnection *connection, NMDevic
g_free (dev_path); g_free (dev_path);
if (!dbus_connection_send (connection, message, NULL)) if (!dbus_connection_send (connection, message, NULL))
syslog (LOG_WARNING, "nm_dbus_signal_device_no_longer_active(): Could not raise the DeviceNoLongerActive signal!"); syslog (LOG_WARNING, "nm_dbus_signal_device_status_change(): Could not raise the signal!");
dbus_message_unref (message);
}
/*
* nm_dbus_signal_device_now_active
*
* Notifies the bus that a particular device is newly active.
*
*/
void nm_dbus_signal_device_now_active (DBusConnection *connection, NMDevice *dev)
{
DBusMessage *message;
unsigned char *dev_path;
g_return_if_fail (connection != NULL);
g_return_if_fail (dev != NULL);
if (!(dev_path = nm_dbus_get_object_path_from_device (dev)))
return;
message = dbus_message_new_signal (NM_DBUS_PATH, NM_DBUS_INTERFACE, "DeviceNowActive");
if (!message)
{
syslog (LOG_ERR, "nm_dbus_signal_device_now_active(): Not enough memory for new dbus message!");
g_free (dev_path);
return;
}
dbus_message_append_args (message, DBUS_TYPE_STRING, dev_path, DBUS_TYPE_INVALID);
g_free (dev_path);
if (!dbus_connection_send (connection, message, NULL))
syslog (LOG_WARNING, "nm_dbus_signal_device_now_active(): Could not raise the DeviceNowActive signal!");
dbus_message_unref (message);
}
/*
* nm_dbus_signal_device_now_active
*
* Notifies the bus that a particular device is newly active.
*
*/
void nm_dbus_signal_device_activating (DBusConnection *connection, NMDevice *dev)
{
DBusMessage *message;
unsigned char *dev_path;
g_return_if_fail (connection != NULL);
g_return_if_fail (dev != NULL);
if (!(dev_path = nm_dbus_get_object_path_from_device (dev)))
return;
message = dbus_message_new_signal (NM_DBUS_PATH, NM_DBUS_INTERFACE, "DeviceActivating");
if (!message)
{
syslog (LOG_ERR, "nm_dbus_signal_device_activating(): Not enough memory for new dbus message!");
g_free (dev_path);
return;
}
dbus_message_append_args (message, DBUS_TYPE_STRING, dev_path, DBUS_TYPE_INVALID);
g_free (dev_path);
if (!dbus_connection_send (connection, message, NULL))
syslog (LOG_WARNING, "nm_dbus_signal_device_activating(): Could not raise the DeviceActivating signal!");
dbus_message_unref (message); dbus_message_unref (message);
} }
@@ -406,12 +411,12 @@ void nm_dbus_signal_device_ip4_address_change (DBusConnection *connection, NMDev
/* /*
* nm_dbus_signal_wireless_network_appeared * nm_dbus_signal_wireless_network_change
* *
* Notifies the bus that a new wireless network has come into range * Notifies the bus that a new wireless network has come into range
* *
*/ */
void nm_dbus_signal_wireless_network_appeared (DBusConnection *connection, NMDevice *dev, NMAccessPoint *ap) void nm_dbus_signal_wireless_network_change (DBusConnection *connection, NMDevice *dev, NMAccessPoint *ap, gboolean gone)
{ {
DBusMessage *message; DBusMessage *message;
char *dev_path; char *dev_path;
@@ -430,7 +435,8 @@ void nm_dbus_signal_wireless_network_appeared (DBusConnection *connection, NMDev
return; return;
} }
message = dbus_message_new_signal (NM_DBUS_PATH, NM_DBUS_INTERFACE, "WirelessNetworkAppeared"); message = dbus_message_new_signal (NM_DBUS_PATH, NM_DBUS_INTERFACE,
(gone ? "WirelessNetworkDisappeared" : "WirelessNetworkAppeared"));
if (!message) if (!message)
{ {
syslog (LOG_ERR, "nm_dbus_signal_wireless_network_appeared(): Not enough memory for new dbus message!"); syslog (LOG_ERR, "nm_dbus_signal_wireless_network_appeared(): Not enough memory for new dbus message!");
@@ -453,101 +459,6 @@ void nm_dbus_signal_wireless_network_appeared (DBusConnection *connection, NMDev
} }
/*
* nm_dbus_signal_wireless_network_disappeared
*
* Notifies the bus that a new wireless network is no longer in range
*
*/
void nm_dbus_signal_wireless_network_disappeared (DBusConnection *connection, NMDevice *dev, NMAccessPoint *ap)
{
DBusMessage *message;
unsigned char *dev_path;
unsigned char *ap_path;
g_return_if_fail (connection != NULL);
g_return_if_fail (dev != NULL);
g_return_if_fail (ap != NULL);
if (!(dev_path = nm_dbus_get_object_path_from_device (dev)))
return;
if (!(ap_path = nm_device_get_path_for_ap (dev, ap)))
{
g_free (dev_path);
return;
}
message = dbus_message_new_signal (NM_DBUS_PATH, NM_DBUS_INTERFACE, "WirelessNetworkDisappeared");
if (!message)
{
syslog (LOG_ERR, "nm_dbus_signal_wireless_network_disappeared(): Not enough memory for new dbus message!");
g_free (dev_path);
g_free (ap_path);
return;
}
dbus_message_append_args (message,
DBUS_TYPE_STRING, dev_path,
DBUS_TYPE_STRING, ap_path,
DBUS_TYPE_INVALID);
g_free (ap_path);
g_free (dev_path);
if (!dbus_connection_send (connection, message, NULL))
syslog (LOG_WARNING, "nnm_dbus_signal_wireless_network_disappeared(): Could not raise the WirelessNetworkDisappeared signal!");
dbus_message_unref (message);
}
#if 0
/*
* nm_dbus_get_user_key_for_network_callback
*
* Called from the DBus Pending Call upon receipt of a reply
* message from NetworkManagerInfo.
*
*/
void nm_dbus_get_user_key_for_network_callback (DBusPendingCall *pending, void *user_data)
{
char *key = NULL;
DBusMessage *reply;
NMDevice *dev = (NMDevice *)user_data;
g_return_if_fail (dev != NULL);
reply = dbus_pending_call_get_reply (pending);
if (reply && !dbus_message_is_error (reply, DBUS_ERROR_NO_REPLY))
{
DBusError error;
dbus_error_init (&error);
if (dbus_message_get_args (reply, &error, DBUS_TYPE_STRING, &key, DBUS_TYPE_INVALID))
{
nm_device_pending_action_set_user_key (dev, key);
syslog (LOG_DEBUG, "dbus user key callback got key '%s'", key );
dbus_free (key);
dbus_pending_call_unref (pending);
}
}
}
/*
* nm_dbus_get_user_key_for_network_data_free
*
* Frees data used during the user key pending action
*
*/
void nm_dbus_get_user_key_for_network_data_free (void *user_data)
{
g_return_if_fail (user_data != NULL);
nm_device_unref ((NMDevice *)user_data);
}
#endif
/* /*
* nm_dbus_get_user_key_for_network * nm_dbus_get_user_key_for_network
* *
@@ -575,24 +486,10 @@ void nm_dbus_get_user_key_for_network (DBusConnection *connection, NMDevice *dev
DBUS_TYPE_STRING, nm_ap_get_essid (ap), DBUS_TYPE_STRING, nm_ap_get_essid (ap),
DBUS_TYPE_INVALID); DBUS_TYPE_INVALID);
fprintf( stderr, "getUserKey\n");
if (!dbus_connection_send (connection, message, NULL)) if (!dbus_connection_send (connection, message, NULL))
syslog (LOG_WARNING, "nm_dbus_get_user_key_for_network(): could not send dbus message"); syslog (LOG_WARNING, "nm_dbus_get_user_key_for_network(): could not send dbus message");
/* For asynchronous replies, disabled for now */
#if 0
if (!dbus_connection_send_with_reply (connection, message, pending, -1))
{
syslog (LOG_ERR, "%s raised: %s", error.name, error.message);
dbus_message_unref (message);
return;
}
nm_device_ref (dev);
dbus_pending_call_ref (*pending);
dbus_pending_call_set_notify (*pending, &nm_dbus_get_user_key_for_network_callback,
(void *)dev, &nm_dbus_get_user_key_for_network_data_free);
#endif
dbus_message_unref (message); dbus_message_unref (message);
} }
@@ -1082,8 +979,12 @@ static DBusMessage *nm_dbus_devices_handle_request (DBusConnection *connection,
dbus_message_append_args (reply_message, DBUS_TYPE_STRING, nm_device_get_iface (dev), DBUS_TYPE_INVALID); dbus_message_append_args (reply_message, DBUS_TYPE_STRING, nm_device_get_iface (dev), DBUS_TYPE_INVALID);
else if (strcmp ("getType", request) == 0) else if (strcmp ("getType", request) == 0)
dbus_message_append_args (reply_message, DBUS_TYPE_INT32, nm_device_get_type (dev), DBUS_TYPE_INVALID); dbus_message_append_args (reply_message, DBUS_TYPE_INT32, nm_device_get_type (dev), DBUS_TYPE_INVALID);
else if (strcmp ("getHalUdi", request) == 0)
dbus_message_append_args (reply_message, DBUS_TYPE_STRING, nm_device_get_udi (dev), DBUS_TYPE_INVALID);
else if (strcmp ("getIP4Address", request) == 0) else if (strcmp ("getIP4Address", request) == 0)
dbus_message_append_args (reply_message, DBUS_TYPE_UINT32, nm_device_get_ip4_address (dev), DBUS_TYPE_INVALID); dbus_message_append_args (reply_message, DBUS_TYPE_UINT32, nm_device_get_ip4_address (dev), DBUS_TYPE_INVALID);
else if (strcmp ("getMaxQuality", request) == 0)
dbus_message_append_args (reply_message, DBUS_TYPE_UINT32, nm_device_get_max_quality (dev), DBUS_TYPE_INVALID);
else if (strcmp ("getActiveNetwork", request) == 0) else if (strcmp ("getActiveNetwork", request) == 0)
{ {
NMAccessPoint *ap; NMAccessPoint *ap;
@@ -1198,6 +1099,8 @@ static DBusHandlerResult nm_dbus_nm_message_handler (DBusConnection *connection,
reply_message = nm_dbus_nm_get_active_device (connection, message, data); reply_message = nm_dbus_nm_get_active_device (connection, message, data);
else if (strcmp ("getDevices", method) == 0) else if (strcmp ("getDevices", method) == 0)
reply_message = nm_dbus_nm_get_devices (connection, message, data); reply_message = nm_dbus_nm_get_devices (connection, message, data);
else if (strcmp ("setActiveDevice", method) == 0)
nm_dbus_nm_set_active_device (connection, message, data);
else if (strcmp ("setKeyForNetwork", method) == 0) else if (strcmp ("setKeyForNetwork", method) == 0)
nm_dbus_set_user_key_for_network (connection, message, data); nm_dbus_set_user_key_for_network (connection, message, data);
else if (strcmp ("setNetwork", method) == 0) else if (strcmp ("setNetwork", method) == 0)

View File

@@ -39,21 +39,26 @@
#define NMI_DBUS_INTERFACE "org.freedesktop.NetworkManagerInfo" #define NMI_DBUS_INTERFACE "org.freedesktop.NetworkManagerInfo"
typedef enum
{
DEVICE_NOW_ACTIVE,
DEVICE_NO_LONGER_ACTIVE,
DEVICE_ACTIVATING,
DEVICE_LIST_CHANGE
} DeviceStatus;
DBusConnection *nm_dbus_init (NMData *data); DBusConnection *nm_dbus_init (NMData *data);
gboolean nm_dbus_is_info_daemon_running (DBusConnection *connection); gboolean nm_dbus_is_info_daemon_running (DBusConnection *connection);
void nm_dbus_signal_device_no_longer_active (DBusConnection *connection, NMDevice *dev); void nm_dbus_signal_device_status_change (DBusConnection *connection, NMDevice *dev, DeviceStatus status);
void nm_dbus_signal_device_now_active (DBusConnection *connection, NMDevice *dev); void nm_dbus_signal_devices_changed (DBusConnection *connection);
void nm_dbus_signal_device_activating (DBusConnection *connection, NMDevice *dev);
void nm_dbus_signal_device_ip4_address_change(DBusConnection *connection, NMDevice *dev); void nm_dbus_signal_device_ip4_address_change(DBusConnection *connection, NMDevice *dev);
void nm_dbus_signal_wireless_network_appeared (DBusConnection *connection, NMDevice *dev, NMAccessPoint *ap); void nm_dbus_signal_wireless_network_change (DBusConnection *connection, NMDevice *dev, NMAccessPoint *ap, gboolean gone);
void nm_dbus_signal_wireless_network_disappeared (DBusConnection *connection, NMDevice *dev, NMAccessPoint *ap);
void nm_dbus_get_user_key_for_network (DBusConnection *connection, NMDevice *dev, NMAccessPoint *ap); void nm_dbus_get_user_key_for_network (DBusConnection *connection, NMDevice *dev, NMAccessPoint *ap);

View File

@@ -50,8 +50,9 @@ typedef struct NMDeviceWirelessOptions
{ {
gchar *cur_essid; gchar *cur_essid;
gboolean supports_wireless_scan; gboolean supports_wireless_scan;
GMutex *scan_mutex; guint8 max_quality;
GMutex *scan_mutex;
NMAccessPointList *ap_list; NMAccessPointList *ap_list;
NMAccessPoint *best_ap; NMAccessPoint *best_ap;
@@ -657,6 +658,21 @@ void nm_device_set_enc_key (NMDevice *dev, const char *key)
} }
/*
* nm_device_get_max_quality
*
* Get the quality baseline of a wireless device.
*
*/
guint8 nm_device_get_max_quality (NMDevice *dev)
{
g_return_val_if_fail (dev != NULL, 0);
g_return_val_if_fail (nm_device_is_wireless (dev), 0);
return (dev->options.wireless.max_quality);
}
/* /*
* nm_device_get_ip4_address * nm_device_get_ip4_address
* *
@@ -835,7 +851,7 @@ gboolean nm_device_activation_begin (NMDevice *dev)
return (FALSE); return (FALSE);
} }
nm_dbus_signal_device_activating (data->dbus_connection, dev); nm_dbus_signal_device_status_change (data->dbus_connection, dev, DEVICE_ACTIVATING);
return (TRUE); return (TRUE);
} }
@@ -1156,7 +1172,7 @@ gboolean nm_device_deactivate (NMDevice *dev, gboolean just_added)
dev->ip4_address = 0; dev->ip4_address = 0;
if (!just_added) if (!just_added)
nm_dbus_signal_device_no_longer_active (dev->app_data->dbus_connection, dev); nm_dbus_signal_device_status_change (dev->app_data->dbus_connection, dev, DEVICE_NO_LONGER_ACTIVE);
/* Clean up stuff, don't leave the card associated or up */ /* Clean up stuff, don't leave the card associated or up */
if (nm_device_is_wireless (dev)) if (nm_device_is_wireless (dev))
@@ -1538,6 +1554,13 @@ static void nm_device_do_normal_scan (NMDevice *dev)
wireless_scan *tmp_ap; wireless_scan *tmp_ap;
int err; int err;
NMAccessPointList *old_ap_list = nm_device_ap_list_get (dev); 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); err = iw_scan (iwlib_socket, nm_device_get_iface (dev), WIRELESS_EXT, &scan_results);
if ((err == -1) && (errno == ENODATA)) if ((err == -1) && (errno == ENODATA))

View File

@@ -70,6 +70,7 @@ void nm_device_get_ip6_address (NMDevice *dev);
gboolean nm_device_get_supports_wireless_scan (NMDevice *dev); gboolean nm_device_get_supports_wireless_scan (NMDevice *dev);
void nm_device_do_wireless_scan (NMDevice *dev); void nm_device_do_wireless_scan (NMDevice *dev);
guint8 nm_device_get_max_quality (NMDevice *dev);
NMAccessPoint *nm_device_get_best_ap (NMDevice *dev); NMAccessPoint *nm_device_get_best_ap (NMDevice *dev);
void nm_device_set_best_ap (NMDevice *dev, NMAccessPoint *ap); void nm_device_set_best_ap (NMDevice *dev, NMAccessPoint *ap);

View File

@@ -40,13 +40,13 @@ extern gboolean debug;
/* /*
* nm_policy_get_best_device * nm_policy_auto_get_best_device
* *
* Filter all the devices and find the best device to use as the * Find the best device to use, regardless of whether we are
* link. NOTE: caller must lock the device list if needed. * "locked" on one device at this time.
* *
*/ */
NMDevice * nm_policy_get_best_device (NMData *data) static NMDevice * nm_policy_auto_get_best_device (NMData *data)
{ {
GSList *element; GSList *element;
NMDevice *best_wired_dev = NULL; NMDevice *best_wired_dev = NULL;
@@ -126,8 +126,8 @@ NMDevice * nm_policy_get_best_device (NMData *data)
element = g_slist_next (element); element = g_slist_next (element);
} }
syslog (LOG_NOTICE, "Best wired device = %s", best_wired_dev ? nm_device_get_iface (best_wired_dev) : "(null)"); syslog (LOG_NOTICE, "AUTO: Best wired device = %s", best_wired_dev ? nm_device_get_iface (best_wired_dev) : "(null)");
syslog (LOG_NOTICE, "Best wireless device = %s (%s)", best_wireless_dev ? nm_device_get_iface (best_wireless_dev) : "(null)", syslog (LOG_NOTICE, "AUTO: Best wireless device = %s (%s)", best_wireless_dev ? nm_device_get_iface (best_wireless_dev) : "(null)",
best_wireless_dev ? nm_device_get_essid (best_wireless_dev) : "null" ); best_wireless_dev ? nm_device_get_essid (best_wireless_dev) : "null" );
if (best_wireless_dev || best_wired_dev) if (best_wireless_dev || best_wired_dev)
@@ -142,6 +142,73 @@ NMDevice * nm_policy_get_best_device (NMData *data)
} }
/*
* nm_policy_get_best_device
*
* Find the best device to use, taking into account if we are
* "locked" on one device or not. That lock may also be cleared
* under certain conditions.
*
*/
static NMDevice * nm_policy_get_best_device (NMData *data)
{
NMDevice *best_dev = NULL;
g_return_val_if_fail (data != NULL, NULL);
/* Can't lock the active device if you don't have one */
if (!data->active_device)
data->active_device_locked = FALSE;
/* If the user told us to switch to a particular device, do it now */
if (nm_try_acquire_mutex (data->user_device_mutex, __FUNCTION__))
{
if (data->user_device)
{
best_dev = data->user_device;
nm_device_unref (data->user_device);
data->user_device = NULL;
}
nm_unlock_mutex (data->user_device_mutex, __FUNCTION__);
}
/* Determine whether we need to clear the active device and unlock it. */
if (!best_dev && data->active_device_locked)
{
switch (nm_device_get_type (data->active_device))
{
/* If the active device was a wired device, and it no
* longer has a link, switch to auto mode.
*/
case (DEVICE_TYPE_WIRED_ETHERNET):
if (nm_device_get_link_active (data->active_device))
best_dev = data->active_device;
break;
/* For wireless devices, we only "unlock" them if they are
* removed from the system.
*/
case (DEVICE_TYPE_WIRELESS_ETHERNET):
best_dev = data->active_device;
break;
default:
break;
}
}
/* Fall back to automatic device picking */
if (!best_dev)
{
data->active_device_locked = FALSE;
best_dev = nm_policy_auto_get_best_device (data);
}
return (best_dev);
}
/* /*
* nm_state_modification_monitor * nm_state_modification_monitor
* *
@@ -232,7 +299,7 @@ gboolean nm_state_modification_monitor (gpointer user_data)
} }
else if (data->active_device && nm_device_just_activated (data->active_device)) else if (data->active_device && nm_device_just_activated (data->active_device))
{ {
nm_dbus_signal_device_now_active (data->dbus_connection, data->active_device); nm_dbus_signal_device_status_change (data->dbus_connection, data->active_device, DEVICE_NOW_ACTIVE);
syslog (LOG_INFO, "nm_state_modification_monitor() activated device %s", nm_device_get_iface (data->active_device)); syslog (LOG_INFO, "nm_state_modification_monitor() activated device %s", nm_device_get_iface (data->active_device));
} }