2005-02-27 Dan Williams <dcbw@redhat.com>

* panel-applet/NMWirelessApplet.[ch]
	  panel-applet/NMWirelessAppletDbus.[ch]
		- Move to incremental network updates.  Instead of blowing away our list
			of devices every time we get a signal from NetworkManager, we now
			incrementally add/remove networks when NetworkManager notifies us that
			a new network has appeared or disappered.  Strength updates now happen
			on-the-fly for each access point as well.  There are now two copies of
			data from NetworkManager: one for the dbus side, and one for the gui side.
			When the dbus side data is modified, it is copied over to the gui side
			so we don't have to hold the data_mutex for long periods of time (and
			therefore block animation of the applet's icon).
		- Clean up some memleaks too

	* panel-applet/NMWirelessAppletOtherNetworkDialog.c
		- Minor code beautification

	* src/NetworkManagerAPList.c
		- (nm_ap_list_merge_scanned_ap): return whether or not the access point is
			completely new and whether or not an existing one's strength was updated.
			Try to fix multiple access points and signal strength by using the highest
			signal strength in each scan for any given ESSID.

	* src/NetworkManagerDbus.[ch]
		- (nm_dbus_signal_wireless_network_change): consolidate signals that deal with
			wireless networks; now we have only WirelessNetworkUpdate which includes
			a UINT32 for Appeared, Disappeared, or StrengthChanged (see NetworkManager.h).
		- Kill usage of DbusMessageIter

	* src/NetworkManagerDevice.c
		- (nm_device_wireless_process_scan_results): Use the same timestamp for all APs
			in the same scan result list.  Copy ESSIDs-by-address earlier on, for each
			AP rather than all-at-once.  Also don't ever remove the AP a card is
			currently associated with from the network list.
		- Update for new signals during scan, send out Appeared, Disappeared, or
			StrengthChanged when necessary.


git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@477 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
This commit is contained in:
Dan Williams
2005-02-27 06:11:16 +00:00
parent f8597bc3b6
commit bbbd00d4c5
11 changed files with 676 additions and 234 deletions

View File

@@ -1,3 +1,41 @@
2005-02-27 Dan Williams <dcbw@redhat.com>
* panel-applet/NMWirelessApplet.[ch]
panel-applet/NMWirelessAppletDbus.[ch]
- Move to incremental network updates. Instead of blowing away our list
of devices every time we get a signal from NetworkManager, we now
incrementally add/remove networks when NetworkManager notifies us that
a new network has appeared or disappered. Strength updates now happen
on-the-fly for each access point as well. There are now two copies of
data from NetworkManager: one for the dbus side, and one for the gui side.
When the dbus side data is modified, it is copied over to the gui side
so we don't have to hold the data_mutex for long periods of time (and
therefore block animation of the applet's icon).
- Clean up some memleaks too
* panel-applet/NMWirelessAppletOtherNetworkDialog.c
- Minor code beautification
* src/NetworkManagerAPList.c
- (nm_ap_list_merge_scanned_ap): return whether or not the access point is
completely new and whether or not an existing one's strength was updated.
Try to fix multiple access points and signal strength by using the highest
signal strength in each scan for any given ESSID.
* src/NetworkManagerDbus.[ch]
- (nm_dbus_signal_wireless_network_change): consolidate signals that deal with
wireless networks; now we have only WirelessNetworkUpdate which includes
a UINT32 for Appeared, Disappeared, or StrengthChanged (see NetworkManager.h).
- Kill usage of DbusMessageIter
* src/NetworkManagerDevice.c
- (nm_device_wireless_process_scan_results): Use the same timestamp for all APs
in the same scan result list. Copy ESSIDs-by-address earlier on, for each
AP rather than all-at-once. Also don't ever remove the AP a card is
currently associated with from the network list.
- Update for new signals during scan, send out Appeared, Disappeared, or
StrengthChanged when necessary.
2005-02-25 Dan Williams <dcbw@redhat.com>
* README

View File

@@ -69,6 +69,7 @@
static GObject * nmwa_constructor (GType type, guint n_props, GObjectConstructParam *construct_props);
static void setup_stock (void);
static void nmwa_icons_init (NMWirelessApplet *applet);
static void nmwa_icons_free (NMWirelessApplet *applet);
static gboolean nmwa_fill (NMWirelessApplet *applet);
static void nmwa_about_cb (NMWirelessApplet *applet);
static void nmwa_context_menu_update (NMWirelessApplet *applet);
@@ -190,48 +191,48 @@ static void nmwa_update_network_state (NMWirelessApplet *applet)
if (applet->applet_state == APPLET_STATE_NO_NM)
goto out;
if (!applet->nm_status)
if (!applet->gui_nm_status)
{
applet->applet_state = APPLET_STATE_NO_CONNECTION;
goto out;
}
if (strcmp (applet->nm_status, "scanning") == 0)
if (strcmp (applet->gui_nm_status, "scanning") == 0)
{
applet->applet_state = APPLET_STATE_WIRELESS_SCANNING;
goto out;
}
if (strcmp (applet->nm_status, "disconnected") == 0)
if (strcmp (applet->gui_nm_status, "disconnected") == 0)
{
applet->applet_state = APPLET_STATE_NO_CONNECTION;
goto out;
}
if (!applet->active_device)
if (!applet->gui_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 ( (applet->active_device->type != DEVICE_TYPE_WIRED_ETHERNET)
&& (applet->active_device->type != DEVICE_TYPE_WIRELESS_ETHERNET))
if ( (applet->gui_active_device->type != DEVICE_TYPE_WIRED_ETHERNET)
&& (applet->gui_active_device->type != DEVICE_TYPE_WIRELESS_ETHERNET))
{
applet->applet_state = APPLET_STATE_NO_CONNECTION;
}
else if (applet->active_device->type == DEVICE_TYPE_WIRED_ETHERNET)
else if (applet->gui_active_device->type == DEVICE_TYPE_WIRED_ETHERNET)
{
if (strcmp (applet->nm_status, "connecting") == 0)
if (strcmp (applet->gui_nm_status, "connecting") == 0)
applet->applet_state = APPLET_STATE_WIRED_CONNECTING;
else if (strcmp (applet->nm_status, "connected") == 0)
else if (strcmp (applet->gui_nm_status, "connected") == 0)
applet->applet_state = APPLET_STATE_WIRED;
}
else if (applet->active_device->type == DEVICE_TYPE_WIRELESS_ETHERNET)
else if (applet->gui_active_device->type == DEVICE_TYPE_WIRELESS_ETHERNET)
{
if (strcmp (applet->nm_status, "connecting") == 0)
if (strcmp (applet->gui_nm_status, "connecting") == 0)
applet->applet_state = APPLET_STATE_WIRELESS_CONNECTING;
else if (strcmp (applet->nm_status, "connected") == 0)
else if (strcmp (applet->gui_nm_status, "connected") == 0)
applet->applet_state = APPLET_STATE_WIRELESS;
}
@@ -244,8 +245,8 @@ out:
/* We can only do this because we are called with
* the applet->data_mutex locked.
*/
g_free (applet->nm_status);
applet->nm_status = NULL;
g_free (applet->gui_nm_status);
applet->gui_nm_status = NULL;
}
old_state = applet->applet_state;
}
@@ -342,13 +343,13 @@ nmwa_update_state (NMWirelessApplet *applet)
WirelessNetwork *active_network = NULL;
g_mutex_lock (applet->data_mutex);
if (applet->active_device
&& (applet->active_device->type == DEVICE_TYPE_WIRELESS_ETHERNET))
if (applet->gui_active_device
&& (applet->gui_active_device->type == DEVICE_TYPE_WIRELESS_ETHERNET))
{
GSList *list;
/* Grab a pointer the active network (for ESSID) */
for (list = applet->active_device->networks; list; list = list->next)
for (list = applet->gui_active_device->networks; list; list = list->next)
{
WirelessNetwork *network = (WirelessNetwork *) list->data;
@@ -356,14 +357,14 @@ nmwa_update_state (NMWirelessApplet *applet)
active_network = network;
}
strength = CLAMP ((int)applet->active_device->strength, 0, 100);
strength = CLAMP ((int)applet->gui_active_device->strength, 0, 100);
}
#if 0
/* Only show icon if there's more than one device and at least one is wireless */
if (g_slist_length (applet->device_list) == 1 && applet->applet_state != APPLET_STATE_NO_NM)
if (g_slist_length (applet->gui_device_list) == 1 && applet->applet_state != APPLET_STATE_NO_NM)
{
if (((NetworkDevice *)applet->device_list->data)->type == DEVICE_TYPE_WIRED_ETHERNET)
if (((NetworkDevice *)applet->gui_device_list->data)->type == DEVICE_TYPE_WIRED_ETHERNET)
show_applet = FALSE;
}
#endif
@@ -389,7 +390,7 @@ nmwa_update_state (NMWirelessApplet *applet)
break;
case (APPLET_STATE_WIRELESS):
if (applet->active_device)
if (applet->gui_active_device)
{
if (applet->is_adhoc)
{
@@ -574,33 +575,86 @@ WirelessNetwork *nmwa_get_device_network_for_essid (NMWirelessApplet *applet, Ne
* NetworkManager ID given.
*
*/
NetworkDevice *nmwa_get_device_for_nm_device (NMWirelessApplet *applet, const char *nm_dev)
NetworkDevice *nmwa_get_device_for_nm_device (GSList *dev_list, const char *nm_dev)
{
NetworkDevice *found_dev = NULL;
GSList *element;
GSList *elt;
g_return_val_if_fail (applet != NULL, NULL);
g_return_val_if_fail (nm_dev != NULL, NULL);
g_return_val_if_fail (strlen (nm_dev), NULL);
g_mutex_lock (applet->data_mutex);
element = applet->device_list;
while (element)
for (elt = dev_list; elt; elt = g_slist_next (elt))
{
NetworkDevice *dev = (NetworkDevice *)(element->data);
NetworkDevice *dev = (NetworkDevice *)(elt->data);
if (dev && (strcmp (dev->nm_device, nm_dev) == 0))
{
found_dev = dev;
break;
}
element = g_slist_next (element);
}
g_mutex_unlock (applet->data_mutex);
return (found_dev);
}
/*
* nmwa_get_net_for_nm_net
*
* Searches the network list of a device for a particular network
*
*/
WirelessNetwork *nmwa_get_net_for_nm_net (NetworkDevice *dev, const char *net_path)
{
WirelessNetwork *found_net = NULL;
GSList *elt;
g_return_val_if_fail (dev != NULL, NULL);
g_return_val_if_fail (net_path != NULL, NULL);
g_return_val_if_fail (strlen (net_path), NULL);
for (elt = dev->networks; elt; elt = g_slist_next (elt))
{
WirelessNetwork *net = (WirelessNetwork *)(elt->data);
if (net && (strcmp (net->nm_name, net_path) == 0))
{
found_net = net;
break;
}
}
return (found_net);
}
/*
* nmwa_get_net_by_essid
*
* Searches the network list of a device for a particular network
*
*/
WirelessNetwork *nmwa_get_net_by_essid (NetworkDevice *dev, const char *essid)
{
WirelessNetwork *found_net = NULL;
GSList *elt;
g_return_val_if_fail (dev != NULL, NULL);
g_return_val_if_fail (essid != NULL, NULL);
g_return_val_if_fail (strlen (essid), NULL);
for (elt = dev->networks; elt; elt = g_slist_next (elt))
{
WirelessNetwork *net = (WirelessNetwork *)(elt->data);
if (net && (strcmp (net->essid, essid) == 0))
{
found_net = net;
break;
}
}
return (found_net);
}
/*
* nmwa_menu_item_activate
*
@@ -621,15 +675,30 @@ static void nmwa_menu_item_activate (GtkMenuItem *item, gpointer user_data)
{
char *item_dev = g_object_get_data (G_OBJECT (item), "nm_device");
if (item_dev && (dev = nmwa_get_device_for_nm_device (applet, item_dev)))
g_mutex_lock (applet->data_mutex);
if (item_dev && (dev = nmwa_get_device_for_nm_device (applet->gui_device_list, item_dev)))
{
network_device_ref (dev);
g_mutex_unlock (applet->data_mutex);
if ((net = nmwa_get_device_network_for_essid (applet, dev, tag)))
nmwa_update_network_timestamp (applet, net);
}
else
g_mutex_unlock (applet->data_mutex);
}
else if ((tag = g_object_get_data (G_OBJECT (item), "device")))
dev = nmwa_get_device_for_nm_device (applet, tag);
{
g_mutex_lock (applet->data_mutex);
dev = nmwa_get_device_for_nm_device (applet->gui_device_list, tag);
network_device_ref (dev);
g_mutex_unlock (applet->data_mutex);
}
if (dev)
{
nmwa_dbus_set_device (applet->connection, dev, net, -1, NULL);
network_device_unref (dev);
}
}
@@ -686,7 +755,7 @@ static void nmwa_menu_add_device_item (GtkWidget *menu, NetworkDevice *device, g
gtk_item = wired_menu_item_get_check_item (item);
wired_menu_item_update (item, device, n_devices);
if (applet->active_device == device)
if (applet->gui_active_device == device)
gtk_check_menu_item_set_active (gtk_item, TRUE);
g_object_set_data (G_OBJECT (gtk_item), "device", g_strdup (device->nm_device));
@@ -793,7 +862,7 @@ static void nmwa_menu_device_add_networks (GtkWidget *menu, NetworkDevice *dev,
gtk_item = network_menu_item_get_check_item (item);
gtk_menu_shell_append (GTK_MENU_SHELL (menu), GTK_WIDGET (gtk_item));
if (applet->active_device == dev && net->active)
if (applet->gui_active_device == dev && net->active)
gtk_check_menu_item_set_active (gtk_item, TRUE);
network_menu_item_update (item, net, has_encrypted);
@@ -806,44 +875,6 @@ static void nmwa_menu_device_add_networks (GtkWidget *menu, NetworkDevice *dev,
}
}
static int
sort_networks_function (gconstpointer a, gconstpointer b)
{
NetworkDevice *dev_a = (NetworkDevice *) a;
NetworkDevice *dev_b = (NetworkDevice *) b;
char *name_a;
char *name_b;
if (dev_a->hal_name)
name_a = dev_a->hal_name;
else if (dev_a->nm_name)
name_a = dev_a->nm_name;
else
name_a = "";
if (dev_b->hal_name)
name_b = dev_b->hal_name;
else if (dev_b->nm_name)
name_b = dev_b->nm_name;
else
name_b = "";
if (dev_a->type == dev_b->type)
{
return strcmp (name_a, name_b);
}
if (dev_a->type == DEVICE_TYPE_WIRED_ETHERNET)
return -1;
if (dev_b->type == DEVICE_TYPE_WIRED_ETHERNET)
return 1;
if (dev_a->type == DEVICE_TYPE_WIRELESS_ETHERNET)
return -1;
if (dev_b->type == DEVICE_TYPE_WIRELESS_ETHERNET)
return 1;
/* Unknown device types. Sort by name only at this point. */
return strcmp (name_a, name_b);
}
/*
* nmwa_menu_add_devices
@@ -859,16 +890,14 @@ static void nmwa_menu_add_devices (GtkWidget *menu, NMWirelessApplet *applet)
g_return_if_fail (applet != NULL);
g_mutex_lock (applet->data_mutex);
if (! applet->device_list)
if (! applet->gui_device_list)
{
nmwa_menu_add_text_item (menu, _("No network devices have been found"));
g_mutex_unlock (applet->data_mutex);
return;
}
applet->device_list = g_slist_sort (applet->device_list, sort_networks_function);
for (element = applet->device_list; element; element = element->next)
for (element = applet->gui_device_list; element; element = element->next)
{
NetworkDevice *dev = (NetworkDevice *)(element->data);
@@ -888,13 +917,13 @@ static void nmwa_menu_add_devices (GtkWidget *menu, NMWirelessApplet *applet)
}
/* Add all devices in our device list to the menu */
for (element = applet->device_list; element; element = element->next)
for (element = applet->gui_device_list; element; element = element->next)
{
NetworkDevice *dev = (NetworkDevice *)(element->data);
if (dev && ((dev->type == DEVICE_TYPE_WIRED_ETHERNET) || (dev->type == DEVICE_TYPE_WIRELESS_ETHERNET)))
{
gboolean current = (dev == applet->active_device);
gboolean current = (dev == applet->gui_active_device);
gint n_devices = 0;
if (dev->type == DEVICE_TYPE_WIRED_ETHERNET)
@@ -968,6 +997,12 @@ static void nmwa_menu_item_data_free (GtkWidget *menu_item, gpointer data)
g_free (tag);
}
if ((tag = g_object_get_data (G_OBJECT (menu_item), "device")))
{
g_object_set_data (G_OBJECT (menu_item), "device", NULL);
g_free (tag);
}
gtk_widget_destroy (menu_item);
}
@@ -1251,14 +1286,23 @@ static void nmwa_destroy (NMWirelessApplet *applet, gpointer user_data)
if (applet->top_menu_item)
gtk_menu_item_remove_submenu (GTK_MENU_ITEM (applet->top_menu_item));
nmwa_icons_free (applet);
if (applet->redraw_timeout_id > 0)
{
gtk_timeout_remove (applet->redraw_timeout_id);
applet->redraw_timeout_id = 0;
}
g_main_loop_quit (applet->thread_loop);
while (applet->thread_done != TRUE)
g_usleep (G_USEC_PER_SEC / 4);
if (applet->gconf_client)
g_object_unref (G_OBJECT (applet->gconf_client));
nmwa_free_gui_data_model (applet);
nmwa_free_gui_data_model (applet);
}
@@ -1279,10 +1323,13 @@ static GtkWidget * nmwa_get_instance (NMWirelessApplet *applet)
return (NULL);
applet->applet_state = APPLET_STATE_NO_NM;
applet->device_list = NULL;
applet->active_device = NULL;
applet->nm_status = NULL;
applet->gui_device_list = NULL;
applet->gui_active_device = NULL;
applet->gui_nm_status = NULL;
applet->tooltips = NULL;
applet->thread_context = NULL;
applet->thread_loop = NULL;
applet->thread_done = FALSE;
/* Start our dbus thread */
if (!(applet->data_mutex = g_mutex_new ()))

View File

@@ -111,18 +111,24 @@ typedef struct
guint redraw_timeout_id;
GThread *dbus_thread;
GMainContext *thread_context;
GMainLoop *thread_loop;
gboolean thread_done;
/* Data model elements */
GMutex *data_mutex;
AppletState applet_state;
gboolean is_adhoc;
GSList *device_list;
NetworkDevice *active_device;
char *nm_status;
NetworkDevice *dbus_active_device;
gboolean scanning_enabled;
gboolean wireless_enabled;
GSList *gui_device_list;
NetworkDevice *gui_active_device;
char *gui_nm_status;
GSList *dbus_device_list;
NetworkDevice *dbus_active_device;
char *dbus_nm_status;
GdkPixbuf *no_nm_icon;
GdkPixbuf *wired_icon;
GdkPixbuf *adhoc_icon;
@@ -157,7 +163,9 @@ typedef struct
} NMWirelessApplet;
NetworkDevice *nmwa_get_device_for_nm_device (NMWirelessApplet *applet, const char *nm_dev);
NetworkDevice *nmwa_get_device_for_nm_device (GSList *dev_list, const char *nm_dev);
WirelessNetwork *nmwa_get_net_for_nm_net (NetworkDevice *dev, const char *net_path);
WirelessNetwork *nmwa_get_net_by_essid (NetworkDevice *dev, const char *essid);
NMWirelessApplet *nmwa_new (void);
void show_warning_dialog (gboolean error, gchar *mesg, ...);

View File

@@ -57,7 +57,6 @@ static int nmwa_dbus_call_nm_method (DBusConnection *con, const char *path, cons
char **dbus_string_array = NULL;
int num_items = 0;
dbus_bool_t ret = TRUE;
DBusMessageIter iter;
g_return_val_if_fail (con != NULL, RETURN_FAILURE);
g_return_val_if_fail (path != NULL, RETURN_FAILURE);
@@ -117,8 +116,7 @@ static int nmwa_dbus_call_nm_method (DBusConnection *con, const char *path, cons
ret = dbus_message_get_args (reply, &error, DBUS_TYPE_STRING, &dbus_string, DBUS_TYPE_INVALID);
break;
case DBUS_TYPE_STRING_ARRAY:
dbus_message_iter_init (reply, &iter);
ret = dbus_message_iter_get_string_array (&iter, &dbus_string_array, &num_items);
ret = dbus_message_get_args (reply, &error, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &dbus_string_array, &num_items, DBUS_TYPE_INVALID);
break;
case DBUS_TYPE_INT32:
ret = dbus_message_get_args (reply, &error, DBUS_TYPE_INT32, &dbus_int, DBUS_TYPE_INVALID);
@@ -143,15 +141,14 @@ static int nmwa_dbus_call_nm_method (DBusConnection *con, const char *path, cons
dbus_message_unref (reply);
return (RETURN_FAILURE);
}
dbus_message_unref (reply);
switch (arg_type)
{
case DBUS_TYPE_STRING:
*((char **)(arg)) = dbus_string;
*((char **)(arg)) = g_strdup (dbus_string);
break;
case DBUS_TYPE_STRING_ARRAY:
*((char ***)(arg)) = dbus_string_array;
*((char ***)(arg)) = g_strdupv (dbus_string_array);
*item_count = num_items;
break;
case DBUS_TYPE_INT32:
@@ -166,6 +163,7 @@ static int nmwa_dbus_call_nm_method (DBusConnection *con, const char *path, cons
break;
}
dbus_message_unref (reply);
return (RETURN_SUCCESS);
}
@@ -352,7 +350,6 @@ static char * nmwa_dbus_get_nm_status (NMWirelessApplet *applet, AppletState fai
default:
break;
}
return (status);
}
@@ -363,7 +360,7 @@ static char * nmwa_dbus_get_nm_status (NMWirelessApplet *applet, AppletState fai
* Returns the name of a specified object (wireless network, device, etc)
*
*/
static char * nmwa_dbus_get_object_name (NMWirelessApplet *applet, char *path)
static char * nmwa_dbus_get_object_name (NMWirelessApplet *applet, const char *path)
{
char *name = NULL;
@@ -538,6 +535,7 @@ static char *nmwa_dbus_get_hal_device_string_property (DBusConnection *connectio
DBusError error;
DBusMessage *message;
DBusMessage *reply;
char *dbus_property = NULL;
char *property = NULL;
g_return_val_if_fail (connection != NULL, NULL);
@@ -565,12 +563,14 @@ 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_message_get_args (reply, &error, DBUS_TYPE_STRING, &dbus_property, DBUS_TYPE_INVALID))
{
if (dbus_error_is_set (&error))
dbus_error_free (&error);
property = NULL;
dbus_property = NULL;
}
else
property = g_strdup (dbus_property);
dbus_message_unref (reply);
return (property);
@@ -857,6 +857,31 @@ static void network_device_free_wireless_network_list (NetworkDevice *dev)
}
/*
* network_device_remove_wireless_network
*
* Remove one wireless network from the wireless network list
*
*/
void network_device_remove_wireless_network (NetworkDevice *dev, WirelessNetwork *net)
{
GSList *elt;
g_return_if_fail (dev != NULL);
g_return_if_fail (net != NULL);
for (elt = dev->networks; elt; elt = g_slist_next (elt))
{
if (elt->data == net)
{
dev->networks = g_slist_remove_link (dev->networks, elt);
wireless_network_unref ((WirelessNetwork *)elt->data);
g_slist_free (elt);
break;
}
}
}
/*
* network_device_ref
*
@@ -887,9 +912,10 @@ void network_device_unref (NetworkDevice *dev)
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->udi);
g_free (dev->hal_name);
g_free (dev);
memset (dev, 0, sizeof (NetworkDevice));
}
}
@@ -904,7 +930,7 @@ NetworkDevice *network_device_new (void)
{
NetworkDevice *dev = NULL;
if ((dev = g_new0 (NetworkDevice, 1)))
if ((dev = g_malloc0 (sizeof (NetworkDevice))))
network_device_ref (dev);
return (dev);
@@ -925,29 +951,28 @@ NetworkDevice *network_device_copy (NetworkDevice *src)
g_return_val_if_fail (src != NULL, NULL);
if ((dev = g_new0 (NetworkDevice, 1)))
if ((dev = g_malloc0 (sizeof (NetworkDevice))))
{
GSList *elem;
GSList *elt;
network_device_ref (dev);
dev->nm_device = g_strdup (src->nm_device);
dev->type = src->type;
dev->link = src->link;
dev->supports_carrier_detect = src->supports_carrier_detect;
dev->nm_name = g_strdup (src->nm_name);
dev->hal_name = g_strdup (src->hal_name);
dev->udi = g_strdup (src->udi);
dev->strength = src->strength;
elem = src->networks;
while (elem)
for (elt = src->networks; elt; elt = g_slist_next (elt))
{
WirelessNetwork *net = (WirelessNetwork *)elem->data;
WirelessNetwork *net = (WirelessNetwork *)elt->data;
if (net)
{
WirelessNetwork *copy = wireless_network_copy (net);
dev->networks = g_slist_append (dev->networks, copy);
}
elem = g_slist_next (elem);
}
}
@@ -956,7 +981,59 @@ NetworkDevice *network_device_copy (NetworkDevice *src)
/*
* nmwa_dbus_update_device_wireless_networks
* network_device_add_wireless_network
*
* Adds a wireless network to the network device's network list
*
*/
void network_device_add_wireless_network (NetworkDevice *dev, WirelessNetwork *net)
{
g_return_if_fail (dev != NULL);
g_return_if_fail (net != NULL);
wireless_network_ref (net);
dev->networks = g_slist_append (dev->networks, net);
}
/*
* nmwa_dbus_get_one_wireless_network
*
* Returns a new wireless network filled with info from NM
*
*/
WirelessNetwork *nmwa_dbus_get_one_wireless_network (NMWirelessApplet *applet, NetworkDevice *dev,
const char *net_path, const char *active_network)
{
char *name = NULL;
WirelessNetwork *net = NULL;
g_return_val_if_fail (applet != NULL, NULL);
g_return_val_if_fail (dev != NULL, NULL);
g_return_val_if_fail (net_path != NULL, NULL);
if (!(name = nmwa_dbus_get_object_name (applet, net_path)))
goto out;
if (strlen (name))
{
if (!(net = wireless_network_new ()))
goto out;
net->nm_name = g_strdup (net_path);
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->strength = nmwa_dbus_get_object_strength (applet, net->nm_name);
}
out:
g_free (name);
return net;
}
/*
* nmwa_dbus_device_update_all_networks
*
* Query NetworkManager for the wireless networks a particular device
* knows about, if the active device is wireless.
@@ -964,7 +1041,7 @@ NetworkDevice *network_device_copy (NetworkDevice *src)
* NOTE: caller must lock device list if necessary
*
*/
static void nmwa_dbus_update_device_wireless_networks (NetworkDevice *dev, gboolean active_dev, NMWirelessApplet *applet)
static void nmwa_dbus_device_update_all_networks (NetworkDevice *dev, NMWirelessApplet *applet)
{
char *active_network = NULL;
char **networks = NULL;
@@ -979,56 +1056,235 @@ static void nmwa_dbus_update_device_wireless_networks (NetworkDevice *dev, gbool
if (dev->type != DEVICE_TYPE_WIRELESS_ETHERNET)
goto out;
if (active_dev)
if (dev == applet->dbus_active_device)
active_network = nmwa_dbus_get_active_network (applet, dev->nm_device, APPLET_STATE_IGNORE);
if (applet->applet_state == APPLET_STATE_NO_NM)
goto out; /* Don't proceed if NetworkManager died during the call to get the active network */
/* Get each of the networks in turn and add them to the menu */
networks = nmwa_dbus_get_device_networks (applet, dev->nm_device, &num_items, APPLET_STATE_NO_CONNECTION);
if (!networks || (applet->applet_state == APPLET_STATE_NO_NM))
goto out;
for (i = 0; i < num_items; i++)
{
char *name = NULL;
WirelessNetwork *tmp_net = nmwa_get_net_for_nm_net (dev, networks[i]);
if (!(name = nmwa_dbus_get_object_name (applet, networks[i])))
break;
if (strlen (name))
{
gboolean found = FALSE;
int j;
WirelessNetwork *net = NULL;
/* Only show one menu item per network. NetworkManager really passes back a list
* of access points, and there may be more than one that have the same ESSID. Filter
* them here.
/* Only add the network if its not already in the device's network list. We
* don't want duplicates.
*/
for (j = 0; j < i; j++)
if ((found = (networks[j] && (strcmp (networks[i], networks[j]) == 0))))
break;
if (found)
continue;
if (!tmp_net)
{
WirelessNetwork *net;
net = wireless_network_new ();
/* FIXME: what if net == NULL? */
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->strength = nmwa_dbus_get_object_strength (applet, net->nm_name);
dev->networks = g_slist_append (dev->networks, net);
if ((net = nmwa_dbus_get_one_wireless_network (applet, dev, networks[i], active_network)))
{
network_device_add_wireless_network (dev, net);
wireless_network_unref (net);
}
}
dbus_free (name);
}
out:
dbus_free (active_network);
dbus_free_string_array (networks);
g_free (active_network);
g_strfreev (networks);
}
void nmwa_free_gui_data_model (NMWirelessApplet *applet)
{
g_return_if_fail (applet != NULL);
if (applet->gui_device_list)
{
g_slist_foreach (applet->gui_device_list, (GFunc) network_device_unref, NULL);
g_slist_free (applet->gui_device_list);
applet->gui_device_list = NULL;
}
if (applet->gui_active_device)
{
network_device_unref (applet->gui_active_device);
applet->gui_active_device = NULL;
}
if (applet->gui_nm_status)
{
g_free (applet->gui_nm_status);
applet->gui_nm_status = NULL;
}
}
void nmwa_free_dbus_data_model (NMWirelessApplet *applet)
{
g_return_if_fail (applet != NULL);
if (applet->dbus_device_list)
{
g_slist_foreach (applet->dbus_device_list, (GFunc) network_device_unref, NULL);
g_slist_free (applet->dbus_device_list);
applet->dbus_device_list = NULL;
}
if (applet->dbus_active_device)
{
network_device_unref (applet->dbus_active_device);
applet->dbus_active_device = NULL;
}
if (applet->dbus_nm_status)
{
g_free (applet->dbus_nm_status);
applet->dbus_nm_status = NULL;
}
}
/*
* nmwa_copy_data_model
*
* Copy the dbus data model over to the gui data model
*
*/
void nmwa_copy_data_model (NMWirelessApplet *applet)
{
GSList *elt;
NetworkDevice *act_dev = NULL;
g_return_if_fail (applet != NULL);
/* Free the existing GUI data model. */
nmwa_free_gui_data_model (applet);
/* Deep-copy network devices to GUI data model */
for (elt = applet->dbus_device_list; elt; elt = g_slist_next (elt))
{
NetworkDevice *src = (NetworkDevice *)(elt->data);
NetworkDevice *dst = network_device_copy (src);
if (dst)
{
/* Transfer ownership of device to list, don't need to unref it */
applet->gui_device_list = g_slist_append (applet->gui_device_list, dst);
/* Make sure we get the right active device for the gui data model */
if (applet->dbus_active_device == src)
{
network_device_ref (dst);
act_dev = dst;
}
}
}
/* active_device is just a pointer into the device list, no need to deep-copy it */
applet->gui_active_device = act_dev;
applet->gui_nm_status = g_strdup (applet->dbus_nm_status);
}
/*
* nmwa_dbus_device_update_one_network
*
* Update one wireless network
*
*/
static void nmwa_dbus_device_update_one_network (NMWirelessApplet *applet, DBusMessage *message)
{
char *dev_path = NULL;
char *net_path = NULL;
NMNetworkStatus status;
guint8 strength = -1;
DBusError error;
gboolean success = TRUE;
g_return_if_fail (applet != NULL);
g_return_if_fail (message != NULL);
dbus_error_init (&error);
/* Try first time with strength, which is only passed for NETWORK_STATUS_STRENGTH_CHANGED */
if (!dbus_message_get_args (message, &error,
DBUS_TYPE_STRING, &dev_path,
DBUS_TYPE_STRING, &net_path,
DBUS_TYPE_UINT32, &status,
DBUS_TYPE_INT32, &strength,
DBUS_TYPE_INVALID))
{
if (dbus_error_is_set (&error))
dbus_error_free (&error);
dbus_error_init (&error);
/* Try without strength */
if (!dbus_message_get_args (message, &error,
DBUS_TYPE_STRING, &dev_path,
DBUS_TYPE_STRING, &net_path,
DBUS_TYPE_UINT32, &status,
DBUS_TYPE_INVALID))
{
if (dbus_error_is_set (&error))
dbus_error_free (&error);
success = FALSE;
}
/* If the signal is NETWORK_STATUS_STRENGTH_CHANGED but we didn't get passed
* a strength in the arguments, we can't use the signal.
*/
if (status == NETWORK_STATUS_STRENGTH_CHANGED)
success = FALSE;
}
if (success)
{
NetworkDevice *dev = nmwa_get_device_for_nm_device (applet->dbus_device_list, dev_path);
WirelessNetwork *net = dev ? nmwa_get_net_for_nm_net (dev, net_path) : NULL;
gboolean changed = FALSE;
switch (status)
{
case NETWORK_STATUS_DISAPPEARED:
if (!dev || !net)
break;
network_device_remove_wireless_network (dev, net);
changed = TRUE;
break;
case NETWORK_STATUS_APPEARED:
if (!dev)
break;
/* Add it if it doesn't already exist in the device's network list */
if (!net)
{
WirelessNetwork *tmp_net;
char *active_network = NULL;
if (dev == applet->dbus_active_device)
active_network = nmwa_dbus_get_active_network (applet, dev->nm_device, APPLET_STATE_IGNORE);
if (applet->applet_state == APPLET_STATE_NO_NM)
break;
if ((tmp_net = nmwa_dbus_get_one_wireless_network (applet, dev, net_path, active_network)))
{
network_device_add_wireless_network (dev, tmp_net);
wireless_network_unref (tmp_net);
changed = TRUE;
}
g_free (active_network);
}
break;
case NETWORK_STATUS_STRENGTH_CHANGED:
g_return_if_fail (net != NULL);
net->strength = strength;
changed = TRUE;
break;
default:
break;
}
if (changed)
{
/* Now move the data over to the GUI side */
g_mutex_lock (applet->data_mutex);
nmwa_copy_data_model (applet);
g_mutex_unlock (applet->data_mutex);
}
}
}
@@ -1045,13 +1301,65 @@ static gboolean nmwa_dbus_update_active_device_strength (gpointer user_data)
g_return_val_if_fail (user_data != NULL, FALSE);
applet = (NMWirelessApplet *)user_data;
if (applet->dbus_active_device && (applet->active_device->type == DEVICE_TYPE_WIRELESS_ETHERNET))
applet->dbus_active_device->strength = nmwa_dbus_get_object_strength (applet, applet->dbus_active_device->nm_device);
if (applet->gui_active_device && (applet->gui_active_device->type == DEVICE_TYPE_WIRELESS_ETHERNET))
{
guint8 strength = nmwa_dbus_get_object_strength (applet, applet->gui_active_device->nm_device);
applet->gui_active_device->strength = strength;
if (applet->gui_active_device == applet->dbus_active_device)
applet->dbus_active_device->strength = strength;
}
return (TRUE);
}
/*
* sort_devices_function
*
* Sort the devices for display... Wired devices at the top.
*
*/
static int
sort_devices_function (gconstpointer a, gconstpointer b)
{
NetworkDevice *dev_a = (NetworkDevice *) a;
NetworkDevice *dev_b = (NetworkDevice *) b;
char *name_a;
char *name_b;
if (dev_a->hal_name)
name_a = dev_a->hal_name;
else if (dev_a->nm_name)
name_a = dev_a->nm_name;
else
name_a = "";
if (dev_b->hal_name)
name_b = dev_b->hal_name;
else if (dev_b->nm_name)
name_b = dev_b->nm_name;
else
name_b = "";
if (dev_a->type == dev_b->type)
{
return strcmp (name_a, name_b);
}
if (dev_a->type == DEVICE_TYPE_WIRED_ETHERNET)
return -1;
if (dev_b->type == DEVICE_TYPE_WIRED_ETHERNET)
return 1;
if (dev_a->type == DEVICE_TYPE_WIRELESS_ETHERNET)
return -1;
if (dev_b->type == DEVICE_TYPE_WIRELESS_ETHERNET)
return 1;
/* Unknown device types. Sort by name only at this point. */
return strcmp (name_a, name_b);
}
/*
* nmwa_dbus_update_devices
*
@@ -1063,10 +1371,9 @@ static void nmwa_dbus_update_devices (NMWirelessApplet *applet)
char **devices = NULL;
int num_items = 0;
int i;
char *nm_act_dev = NULL;
GSList *device_list = NULL;
char *nm_status = NULL;
gboolean adhoc = FALSE;
char *nm_act_dev;
char *nm_status;
g_return_if_fail (applet->data_mutex != NULL);
@@ -1084,11 +1391,13 @@ static void nmwa_dbus_update_devices (NMWirelessApplet *applet)
}
if (!devices)
{
dbus_free (nm_status);
return;
}
if (applet->dbus_active_device)
network_device_unref (applet->dbus_active_device);
applet->dbus_active_device = NULL;
nmwa_free_dbus_data_model (applet);
applet->dbus_nm_status = nm_status;
nm_act_dev = nmwa_dbus_get_active_device (applet, APPLET_STATE_IGNORE);
@@ -1116,45 +1425,32 @@ static void nmwa_dbus_update_devices (NMWirelessApplet *applet)
network_device_unref (dev);
else
{
device_list = g_slist_append (device_list, dev);
if (nm_act_dev && !strcmp (nm_act_dev, devices[i]))
applet->dbus_device_list = g_slist_append (applet->dbus_device_list, dev);
if (nm_act_dev && (strcmp (nm_act_dev, devices[i]) == 0))
{
/* ref the current active device */
network_device_ref (dev);
applet->dbus_active_device = dev;
network_device_ref (dev);
if (dev->type == DEVICE_TYPE_WIRELESS_ETHERNET)
{
adhoc = (nmwa_dbus_get_object_mode (applet, nm_act_dev) == NETWORK_MODE_ADHOC);
nmwa_dbus_update_device_wireless_networks (dev, TRUE, applet);
}
}
else
nmwa_dbus_update_device_wireless_networks (dev, FALSE, applet);
nmwa_dbus_device_update_all_networks (dev, applet);
}
}
}
dbus_free (name);
}
dbus_free (nm_act_dev);
dbus_free_string_array (devices);
g_free (nm_act_dev);
g_strfreev (devices);
/* Now move the data over to the GUI side */
/* Sort the devices for display */
applet->dbus_device_list = g_slist_sort (applet->dbus_device_list, sort_devices_function);
/* Now copy the data over to the GUI side */
g_mutex_lock (applet->data_mutex);
if (applet->device_list)
{
g_slist_foreach (applet->device_list, (GFunc) network_device_unref, NULL);
g_slist_free (applet->device_list);
}
if (applet->active_device)
network_device_unref (applet->active_device);
if (applet->nm_status)
g_free (applet->nm_status);
applet->device_list = device_list;
applet->active_device = applet->dbus_active_device;
applet->nm_status = nm_status;
nmwa_copy_data_model (applet);
applet->is_adhoc = adhoc;
applet->scanning_enabled = nmwa_dbus_get_scanning_enabled (applet);
applet->wireless_enabled = nmwa_dbus_get_wireless_enabled (applet);
@@ -1236,11 +1532,8 @@ static DBusHandlerResult nmwa_dbus_filter (DBusConnection *connection, DBusMessa
#else
#error "Unrecognized version of DBUS."
#endif
else if ( dbus_message_is_signal (message, NM_DBUS_INTERFACE, "WirelessNetworkAppeared")
|| dbus_message_is_signal (message, NM_DBUS_INTERFACE, "WirelessNetworkDisappeared"))
{
nmwa_dbus_update_devices (applet);
}
else if (dbus_message_is_signal (message, NM_DBUS_INTERFACE, "WirelessNetworkUpdate"))
nmwa_dbus_device_update_one_network (applet, message);
else if ( dbus_message_is_signal (message, NM_DBUS_INTERFACE, "DeviceNowActive")
|| dbus_message_is_signal (message, NM_DBUS_INTERFACE, "DeviceNoLongerActive")
|| dbus_message_is_signal (message, NM_DBUS_INTERFACE, "DeviceActivating")
@@ -1368,7 +1661,6 @@ static gboolean nmwa_dbus_timeout_worker (gpointer user_data)
gpointer nmwa_dbus_worker (gpointer user_data)
{
NMWirelessApplet *applet = (NMWirelessApplet *)user_data;
GMainLoop *thread_loop;
guint timeout_id;
GSource *timeout_source;
guint strength_id;
@@ -1380,7 +1672,7 @@ gpointer nmwa_dbus_worker (gpointer user_data)
if (!(applet->thread_context = g_main_context_new ()))
return (NULL);
if (!(thread_loop = g_main_loop_new (applet->thread_context, FALSE)))
if (!(applet->thread_loop = g_main_loop_new (applet->thread_context, FALSE)))
return (NULL);
applet->connection = nmwa_dbus_init (applet, applet->thread_context);
@@ -1401,7 +1693,7 @@ gpointer nmwa_dbus_worker (gpointer user_data)
else
applet->applet_state = APPLET_STATE_NO_NM;
g_main_loop_run (thread_loop);
g_main_loop_run (applet->thread_loop);
g_source_destroy (timeout_source);
g_source_destroy (strength_source);

View File

@@ -56,4 +56,8 @@ void wireless_network_unref (WirelessNetwork *net);
void network_device_ref (NetworkDevice *dev);
void network_device_unref (NetworkDevice *dev);
void nmwa_free_gui_data_model (NMWirelessApplet *applet);
void nmwa_free_dbus_data_model (NMWirelessApplet *applet);
#endif

View File

@@ -104,7 +104,8 @@ static GtkTreeModel *create_wireless_adapter_model (NMWirelessApplet *applet)
GSList *element;
retval = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_POINTER);
for (element = applet->device_list; element; element = element->next)
/* We should have already locked applet->data_mutex */
for (element = applet->gui_device_list; element; element = element->next)
{
NetworkDevice *network = (NetworkDevice *)(element->data);
@@ -238,7 +239,7 @@ static GtkDialog *nmwa_other_network_dialog_init (GladeXML *xml, NMWirelessApple
/* Do we have multiple Network cards? */
g_mutex_lock (applet->data_mutex);
for (element = applet->device_list; element; element = element->next)
for (element = applet->gui_device_list; element; element = element->next)
{
NetworkDevice *dev = (NetworkDevice *)(element->data);

View File

@@ -377,32 +377,53 @@ void nm_ap_list_populate_from_nmi (NMAccessPointList *list, NMData *data)
* TRUE if the ap was completely new
*
*/
gboolean nm_ap_list_merge_scanned_ap (NMAccessPointList *list, NMAccessPoint *merge_ap)
gboolean nm_ap_list_merge_scanned_ap (NMAccessPointList *list, NMAccessPoint *merge_ap,
gboolean *new, gboolean *strength_changed)
{
NMAccessPoint *list_ap;
gboolean new = FALSE;
gboolean success = FALSE;
g_return_val_if_fail (list != NULL, FALSE);
g_return_val_if_fail (merge_ap != NULL, FALSE);
g_return_val_if_fail (new != NULL, FALSE);
g_return_val_if_fail (strength_changed != NULL, FALSE);
if (!(list_ap = nm_ap_list_get_ap_by_address (list, nm_ap_get_address (merge_ap))))
list_ap = nm_ap_list_get_ap_by_essid (list, nm_ap_get_essid (merge_ap));
if (list_ap)
{
const GTimeVal *merge_ap_seen = nm_ap_get_last_seen (merge_ap);
const GTimeVal *list_ap_seen = nm_ap_get_last_seen (list_ap);
/* Merge some properties on the AP that are new from scan to scan. */
nm_ap_set_encrypted (list_ap, nm_ap_get_encrypted (merge_ap));
nm_ap_set_auth_method (list_ap, nm_ap_get_auth_method (merge_ap));
nm_ap_set_last_seen (list_ap, nm_ap_get_last_seen (merge_ap));
/* Don't update the strength on the existing AP if the timestamp is
* the same as the AP we're going to merge (which means that they were
* found in the same scan, have the same ESSID, but are different APs)
* and the existing AP's strength is greater than the one we're about
* to merge. This helps keep the ESSID's reported strength that of the
* strongest AP we can see.
*/
if (!( (list_ap_seen->tv_sec == merge_ap_seen->tv_sec)
&& (nm_ap_get_strength (list_ap) > nm_ap_get_strength (merge_ap))))
{
nm_ap_set_strength (list_ap, nm_ap_get_strength (merge_ap));
*strength_changed = TRUE;
}
nm_ap_set_last_seen (list_ap, merge_ap_seen);
}
else
{
/* Add the whole AP, list takes ownership. */
nm_ap_list_append_ap (list, merge_ap);
new = TRUE;
*new = TRUE;
}
return new;
return TRUE;
}
@@ -450,6 +471,29 @@ void nm_ap_list_copy_properties (NMAccessPointList *dest, NMAccessPointList *sou
}
/*
* nm_ap_list_copy_one_essid_by_address
*
* If the access point doesn't have an ESSID, search through a list of access points
* and find one (if any) that has the MAC address of the access point we're looking for.
* If one is found, copy the essid over to the original access point.
*
*/
void nm_ap_list_copy_one_essid_by_address (NMAccessPoint *ap, NMAccessPointList *search_list)
{
NMAccessPoint *found_ap;
if (!ap || !search_list)
return;
if (!nm_ap_get_essid (ap) && (found_ap = nm_ap_list_get_ap_by_address (search_list, nm_ap_get_address (ap))))
{
if (nm_ap_get_essid (found_ap))
nm_ap_set_essid (ap, nm_ap_get_essid (found_ap));
}
}
/*
* nm_ap_list_copy_essids_by_address
*
@@ -469,15 +513,8 @@ void nm_ap_list_copy_essids_by_address (NMAccessPointList *dest, NMAccessPointLi
if ((iter = nm_ap_list_iter_new (dest)))
{
while ((dest_ap = nm_ap_list_iter_next (iter)))
{
NMAccessPoint *src_ap = NULL;
nm_ap_list_copy_one_essid_by_address (dest_ap, source);
if (!nm_ap_get_essid (dest_ap) && (src_ap = nm_ap_list_get_ap_by_address (source, nm_ap_get_address (dest_ap))))
{
if (nm_ap_get_essid (src_ap))
nm_ap_set_essid (dest_ap, nm_ap_get_essid (src_ap));
}
}
nm_ap_list_iter_free (iter);
}
}
@@ -523,7 +560,7 @@ void nm_ap_list_diff (NMData *data, NMDevice *dev, NMAccessPointList *old, NMAcc
nm_ap_set_matched (new_ap, TRUE);
}
else
nm_dbus_signal_wireless_network_change (data->dbus_connection, dev, old_ap, TRUE);
nm_dbus_signal_wireless_network_change (data->dbus_connection, dev, old_ap, NETWORK_STATUS_DISAPPEARED, -1);
}
}
nm_ap_list_iter_free (iter);
@@ -537,7 +574,7 @@ void nm_ap_list_diff (NMData *data, NMDevice *dev, NMAccessPointList *old, NMAcc
while ((new_ap = nm_ap_list_iter_next (iter)))
{
if (!nm_ap_get_matched (new_ap) && nm_ap_get_essid (new_ap))
nm_dbus_signal_wireless_network_change (data->dbus_connection, dev, new_ap, FALSE);
nm_dbus_signal_wireless_network_change (data->dbus_connection, dev, new_ap, NETWORK_STATUS_APPEARED, -1);
}
nm_ap_list_iter_free (iter);
}

View File

@@ -48,9 +48,10 @@ void nm_ap_list_populate_from_nmi (NMAccessPointList *list, NMData *data);
void nm_ap_list_copy_properties (NMAccessPointList *dest, NMAccessPointList *source);
void nm_ap_list_copy_essids_by_address (NMAccessPointList *dest, NMAccessPointList *source);
void nm_ap_list_copy_one_essid_by_address (NMAccessPoint *ap, NMAccessPointList *search_list);
void nm_ap_list_diff (NMData *data, NMDevice *dev, NMAccessPointList *old, NMAccessPointList *new);
gboolean nm_ap_list_merge_scanned_ap (NMAccessPointList *list, NMAccessPoint *merge_ap);
gboolean nm_ap_list_merge_scanned_ap (NMAccessPointList *list, NMAccessPoint *merge_ap, gboolean *new, gboolean *strength_changed);
gboolean nm_ap_list_lock (NMAccessPointList *list);
void nm_ap_list_unlock (NMAccessPointList *list);

View File

@@ -417,11 +417,12 @@ void nm_dbus_signal_device_ip4_address_change (DBusConnection *connection, NMDev
* Notifies the bus that a new wireless network has come into range
*
*/
void nm_dbus_signal_wireless_network_change (DBusConnection *connection, NMDevice *dev, NMAccessPoint *ap, gboolean gone)
void nm_dbus_signal_wireless_network_change (DBusConnection *connection, NMDevice *dev, NMAccessPoint *ap, NMNetworkStatus status, gint8 strength)
{
DBusMessage *message;
char *dev_path;
char *ap_path;
const char *signal;
g_return_if_fail (connection != NULL);
g_return_if_fail (dev != NULL);
@@ -436,8 +437,7 @@ void nm_dbus_signal_wireless_network_change (DBusConnection *connection, NMDevic
return;
}
message = dbus_message_new_signal (NM_DBUS_PATH, NM_DBUS_INTERFACE,
(gone ? "WirelessNetworkDisappeared" : "WirelessNetworkAppeared"));
message = dbus_message_new_signal (NM_DBUS_PATH, NM_DBUS_INTERFACE, "WirelessNetworkUpdate");
if (!message)
{
syslog (LOG_ERR, "nm_dbus_signal_wireless_network_appeared(): Not enough memory for new dbus message!");
@@ -449,10 +449,15 @@ void nm_dbus_signal_wireless_network_change (DBusConnection *connection, NMDevic
dbus_message_append_args (message,
DBUS_TYPE_STRING, dev_path,
DBUS_TYPE_STRING, ap_path,
DBUS_TYPE_UINT32, status,
DBUS_TYPE_INVALID);
g_free (ap_path);
g_free (dev_path);
/* Append signal-specific data */
if (status == NETWORK_STATUS_STRENGTH_CHANGED)
dbus_message_append_args (message, DBUS_TYPE_INT32, strength, DBUS_TYPE_INVALID);
if (!dbus_connection_send (connection, message, NULL))
syslog (LOG_WARNING, "nnm_dbus_signal_wireless_network_appeared(): Could not raise the WirelessNetworkAppeared signal!");
@@ -768,19 +773,20 @@ char ** nm_dbus_get_networks (DBusConnection *connection, NMNetworkType type, in
/* Send message and get essid back from NetworkManagerInfo */
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))
syslog (LOG_ERR, "nm_dbus_get_networks(): %s raised %s", error.name, error.message);
else if (!reply)
syslog (LOG_NOTICE, "nm_dbus_get_networks(): reply was NULL.");
else
{
DBusMessageIter iter;
dbus_message_iter_init (reply, &iter);
dbus_message_iter_get_string_array (&iter, &networks, num_networks);
dbus_error_init (&error);
dbus_message_get_args (reply, &error, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
&networks, num_networks, DBUS_TYPE_INVALID);
if (dbus_error_is_set (&error))
dbus_error_free (&error);
}
dbus_message_unref (message);
if (reply)
dbus_message_unref (reply);

View File

@@ -54,7 +54,7 @@ void nm_dbus_signal_network_status_change (DBusConnection *connection, NMData
void nm_dbus_signal_device_ip4_address_change(DBusConnection *connection, NMDevice *dev);
void nm_dbus_signal_wireless_network_change (DBusConnection *connection, NMDevice *dev, NMAccessPoint *ap, gboolean gone);
void nm_dbus_signal_wireless_network_change (DBusConnection *connection, NMDevice *dev, NMAccessPoint *ap, NMNetworkStatus status, gint8 strength);
void nm_dbus_get_user_key_for_network (DBusConnection *connection, NMDevice *dev, NMAccessPoint *ap, int attempt);

View File

@@ -3264,6 +3264,8 @@ static gboolean nm_device_wireless_process_scan_results (gpointer user_data)
return FALSE;
}
g_get_current_time (&cur_time);
/* Translate iwlib scan results to NM access point list */
for (tmp_ap = results->scan_head.result; tmp_ap; tmp_ap = tmp_ap->next)
{
@@ -3272,6 +3274,9 @@ static gboolean nm_device_wireless_process_scan_results (gpointer user_data)
{
NMAccessPoint *nm_ap = nm_ap_new ();
int percent;
gboolean new = FALSE;
gboolean strength_changed = FALSE;
gboolean success = FALSE;
/* Copy over info from scan to local structure */
@@ -3280,11 +3285,8 @@ static gboolean nm_device_wireless_process_scan_results (gpointer user_data)
*/
if ( !tmp_ap->b.has_essid
|| (tmp_ap->b.essid && !strlen (tmp_ap->b.essid))
|| (tmp_ap->b.essid && !strcmp (tmp_ap->b.essid, "<hidden>")))
{
|| (tmp_ap->b.essid && !strcmp (tmp_ap->b.essid, "<hidden>"))) /* Stupid ipw drivers use <hidden> */
nm_ap_set_essid (nm_ap, NULL);
have_blank_essids = TRUE;
}
else
nm_ap_set_essid (nm_ap, tmp_ap->b.essid);
@@ -3330,29 +3332,41 @@ static gboolean nm_device_wireless_process_scan_results (gpointer user_data)
if (tmp_ap->b.has_freq)
nm_ap_set_freq (nm_ap, tmp_ap->b.freq);
g_get_current_time (&cur_time);
nm_ap_set_last_seen (nm_ap, &cur_time);
/* If the AP is not broadcasting its ESSID, try to fill it in here from our
* allowed list where we cache known MAC->ESSID associations.
*/
if (!nm_ap_get_essid (nm_ap))
nm_ap_list_copy_one_essid_by_address (nm_ap, dev->app_data->allowed_ap_list);
/* Add the AP to the device's AP list */
if (nm_ap_list_merge_scanned_ap (nm_device_ap_list_get (dev), nm_ap))
success = nm_ap_list_merge_scanned_ap (nm_device_ap_list_get (dev), nm_ap, &new, &strength_changed);
if (success)
{
nm_dbus_signal_wireless_network_change (dev->app_data->dbus_connection, dev, nm_ap, FALSE);
/* Handle dbus signals that we need to broadcast when the AP is added to the list or changes
* strength.
*/
if (new)
{
nm_dbus_signal_wireless_network_change (dev->app_data->dbus_connection, dev, nm_ap,
NETWORK_STATUS_APPEARED, -1);
list_changed = TRUE;
}
else if (strength_changed)
{
nm_dbus_signal_wireless_network_change (dev->app_data->dbus_connection, dev, nm_ap,
NETWORK_STATUS_STRENGTH_CHANGED, nm_ap_get_strength (nm_ap));
}
}
nm_ap_unref (nm_ap);
}
}
/* If we detected any blank-ESSID access points (ie don't broadcast their ESSID), then try to
* merge in ESSIDs that we have addresses for from user preferences/NetworkManagerInfo.
*/
if (have_blank_essids)
nm_ap_list_copy_essids_by_address (nm_device_ap_list_get (dev), dev->app_data->allowed_ap_list);
/* Once we have the list, copy in any relevant information from our Allowed list. */
nm_ap_list_copy_properties (nm_device_ap_list_get (dev), dev->app_data->allowed_ap_list);
/* Walk the access point list and remove any access points older than 60s */
/* Walk the access point list and remove any access points older than 120s */
g_get_current_time (&cur_time);
if (nm_device_ap_list_get (dev) && (iter = nm_ap_list_iter_new (nm_device_ap_list_get (dev))))
{
@@ -3366,18 +3380,12 @@ static gboolean nm_device_wireless_process_scan_results (gpointer user_data)
const GTimeVal *ap_time = nm_ap_get_last_seen (outdated_ap);
gboolean keep_around = FALSE;
/* We don't add "artifical" APs to the outdated list if it is the
* one the card is currently associated with.
* Some Cisco cards don't report non-ESSID-broadcasting access points
* in their scans even though the card associates with that AP just fine.
*/
/* Don't ever get prune the AP we're currently associated with */
if ( nm_ap_get_essid (outdated_ap)
&& (best_ap && (nm_null_safe_strcmp (nm_ap_get_essid (best_ap), nm_ap_get_essid (outdated_ap))) == 0)
&& nm_ap_get_artificial (outdated_ap))
&& (best_ap && (nm_null_safe_strcmp (nm_ap_get_essid (best_ap), nm_ap_get_essid (outdated_ap))) == 0))
keep_around = TRUE;
/* Eh, we don't care about sub-second time resolution. */
if ((ap_time->tv_sec + 120 < cur_time.tv_sec) && !keep_around)
if (!keep_around && (ap_time->tv_sec + 120 < cur_time.tv_sec))
outdated_list = g_slist_append (outdated_list, outdated_ap);
}
nm_ap_list_iter_free (iter);
@@ -3393,7 +3401,7 @@ static gboolean nm_device_wireless_process_scan_results (gpointer user_data)
{
if ((outdated_ap = (NMAccessPoint *)(elt->data)))
{
nm_dbus_signal_wireless_network_change (dev->app_data->dbus_connection, dev, outdated_ap, TRUE);
nm_dbus_signal_wireless_network_change (dev->app_data->dbus_connection, dev, outdated_ap, NETWORK_STATUS_DISAPPEARED, -1);
nm_ap_list_remove_ap (nm_device_ap_list_get (dev), outdated_ap);
list_changed = TRUE;
}