diff --git a/ChangeLog b/ChangeLog index e2794eed99..dbc1f24eb9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,43 @@ +2004-09-09 Dan Williams + + NOTE: this commit changes the behavior of wireless devices in + NetworkManager. They are now up all the time, scanning all + the time. Only the active device has an IP address and routing + information set up however. Also, NetworkManager will no longer + opportunistically switch wireless networks when a better one + comes in range, it will remain associated with one wireless network + until that one drops out. + + * panel-applet/NMWirelessApplet.c + panel-applet/NMWirelessAppletDbus.c + - List all wireless cards and their respective networks + + * src/NMLoadModules + - Use full path to /sbin/ip + + * src/NetworkManager.c + - Keep wireless devices up all the time so they can scan + + * src/NetworkManagerDbus.c + - On a WirelessNetworkUpdate signal from NMI, don't update + the "best" AP + + * src/NetworkManagerDevice.c + - (nm_device_set_link_active): clear out the best ap for + wireless devices when the link is set to FALSE + - Scan on all wireless cards, all the time + - (nm_device_activation_worker): split out the wireless card + link-waiting code to a separate function + - Keep wireless cards up even if device activation fails + - Don't update the "best" ap as much + + * src/NetworkManagerPolicy.c + - Don't update the best ap when checking if its frozen, + let link checking clear out a frozen best ap for us + + * src/NetworkManagerWireless.c + - Scan on all wireless cards, all the time + 2004-09-09 Francisco Javier F. Serrador * configure.in: Added 'es' (Spanish) to ALL_LINGUAS. @@ -21,6 +61,7 @@ to look like. Also did a Airo card hack to make it show the correct AP quality +>>>>>>> 1.92 2004-09-08 Dan Williams * panel-applet/no-networkmanager.png diff --git a/panel-applet/NMWirelessApplet.c b/panel-applet/NMWirelessApplet.c index f555302772..1782e0a049 100644 --- a/panel-applet/NMWirelessApplet.c +++ b/panel-applet/NMWirelessApplet.c @@ -69,6 +69,7 @@ static char *glade_file; static void nmwa_about_cb (BonoboUIComponent *uic, NMWirelessApplet *applet); static GtkWidget * nmwa_populate_menu (NMWirelessApplet *applet); static void nmwa_dispose_menu_items (NMWirelessApplet *applet); +static gboolean do_not_eat_button_press (GtkWidget *widget, GdkEventButton *event); static const BonoboUIVerb nmwa_context_menu_verbs [] = { @@ -373,7 +374,7 @@ static void nmwa_get_menu_pos (GtkMenu *menu, gint *x, gint *y, gboolean *push_i * NetworkInfoManager that the networks list has changed, and it notifies * NetworkManager about those changes, triggering an AP switch. */ -void nmwa_handle_network_choice (NMWirelessApplet *applet, char *network) +static void nmwa_handle_network_choice (NMWirelessApplet *applet, char *network) { GConfEntry *gconf_entry; char *key; @@ -406,7 +407,7 @@ void nmwa_handle_network_choice (NMWirelessApplet *applet, char *network) * Signal function called when user clicks on a menu item * */ -void nmwa_menu_item_activate (GtkMenuItem *item, gpointer user_data) +static void nmwa_menu_item_activate (GtkMenuItem *item, gpointer user_data) { NMWirelessApplet *applet = (NMWirelessApplet *)user_data; char *tag; @@ -439,7 +440,7 @@ static void nmwa_toplevel_menu_activate (GtkWidget *menu, NMWirelessApplet *appl * nmwa_menu_add_separator_item * */ -void nmwa_menu_add_separator_item (GtkWidget *menu) +static void nmwa_menu_add_separator_item (GtkWidget *menu) { GtkWidget *menu_item; @@ -455,7 +456,7 @@ void nmwa_menu_add_separator_item (GtkWidget *menu) * Add a non-clickable text item to a menu * */ -void nmwa_menu_add_text_item (GtkWidget *menu, char *text) +static void nmwa_menu_add_text_item (GtkWidget *menu, char *text) { GtkWidget *menu_item; @@ -476,7 +477,7 @@ void nmwa_menu_add_text_item (GtkWidget *menu, char *text) * Add a network device to the menu * */ -void nmwa_menu_add_device_item (GtkWidget *menu, GdkPixbuf *icon, char *name, char *nm_device, gboolean current, gpointer user_data) +static void nmwa_menu_add_device_item (GtkWidget *menu, GdkPixbuf *icon, char *name, char *nm_device, gboolean current, gpointer user_data) { GtkWidget *menu_item; GtkWidget *label; @@ -518,58 +519,19 @@ void nmwa_menu_add_device_item (GtkWidget *menu, GdkPixbuf *icon, char *name, ch } -/* - * 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; - char *name_string; - gboolean current = applet->active_device ? (strcmp (applet->active_device, dev->nm_device) == 0) : FALSE; - - name_string = g_strdup_printf ("%s (%s)", (dev->hal_name ? dev->hal_name : dev->nm_name), - (dev->type == DEVICE_TYPE_WIRED_ETHERNET) ? "wired" : "wireless"); - nmwa_menu_add_device_item (menu, icon, name_string, dev->nm_device, current, applet); - } - - 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, +static 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 *foo; GtkWidget *progress; float percent; @@ -581,6 +543,12 @@ void nmwa_menu_add_network (GtkWidget *menu, GdkPixbuf *key, char *text, char *n gtk_container_add (GTK_CONTAINER (menu_item), hbox); gtk_widget_show (hbox); + /* Add spacing container */ + foo = gtk_hbox_new (FALSE, 5); + gtk_widget_set_size_request (foo, 7, -1); + gtk_box_pack_start (GTK_BOX (hbox), foo, FALSE, FALSE, 2); + gtk_widget_show (foo); + label = gtk_label_new (text); if (current) { @@ -619,10 +587,47 @@ void nmwa_menu_add_network (GtkWidget *menu, GdkPixbuf *key, char *text, char *n /* - * nmwa_menu_add_networks + * nmwa_menu_device_add_networks * */ -void nmwa_menu_add_networks (GtkWidget *menu, NMWirelessApplet *applet) +static void nmwa_menu_device_add_networks (GtkWidget *menu, NetworkDevice *dev, NMWirelessApplet *applet) +{ + GSList *element; + + g_return_if_fail (menu != NULL); + g_return_if_fail (applet != NULL); + g_return_if_fail (dev != NULL); + + if (dev->type != DEVICE_TYPE_WIRELESS_ETHERNET) + return; + + element = dev->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); + } + } +} + + +/* + * nmwa_menu_add_devices + * + */ +static void nmwa_menu_add_devices (GtkWidget *menu, NMWirelessApplet *applet) { GSList *element; @@ -630,28 +635,35 @@ void nmwa_menu_add_networks (GtkWidget *menu, NMWirelessApplet *applet) g_return_if_fail (applet != NULL); g_mutex_lock (applet->data_mutex); - element = applet->networks; + element = applet->devices; if (!element) - nmwa_menu_add_text_item (menu, _("There are no wireless networks...")); + nmwa_menu_add_text_item (menu, _("There are no network devices...")); else { - nmwa_menu_add_text_item (menu, _("Wireless Networks")); - - /* Add all networks in our network list to the menu */ + /* Add all devices in our device list to the menu */ while (element) { - WirelessNetwork *net = (WirelessNetwork *)(element->data); + NetworkDevice *dev = (NetworkDevice *)(element->data); - if (net) - nmwa_menu_add_network (menu, applet->key_pixbuf, net->essid, - net->essid, net->active, net->encrypted, net->quality, applet); + 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; + char *name_string; + gboolean current = applet->active_device ? (strcmp (applet->active_device, dev->nm_device) == 0) : FALSE; + name_string = g_strdup_printf ("%s (%s)", (dev->hal_name ? dev->hal_name : dev->nm_name), + (dev->type == DEVICE_TYPE_WIRED_ETHERNET) ? "wired" : "wireless"); + nmwa_menu_add_device_item (menu, icon, name_string, dev->nm_device, current, applet); + nmwa_menu_device_add_networks (menu, dev, applet); + nmwa_menu_add_separator_item (menu); + } element = g_slist_next (element); } } g_mutex_unlock (applet->data_mutex); } + /* * nmwa_menu_item_data_free * @@ -683,7 +695,7 @@ static void nmwa_menu_item_data_free (GtkWidget *menu_item, gpointer data) * Destroy the menu and each of its items data tags * */ -void nmwa_dispose_menu_items (NMWirelessApplet *applet) +static void nmwa_dispose_menu_items (NMWirelessApplet *applet) { g_return_if_fail (applet != NULL); @@ -698,7 +710,7 @@ void nmwa_dispose_menu_items (NMWirelessApplet *applet) * Set up our networks menu from scratch * */ -GtkWidget * nmwa_populate_menu (NMWirelessApplet *applet) +static GtkWidget * nmwa_populate_menu (NMWirelessApplet *applet) { GtkWidget *menu = applet->menu; @@ -712,27 +724,7 @@ GtkWidget * nmwa_populate_menu (NMWirelessApplet *applet) nmwa_menu_add_text_item (menu, _("Network Connections")); nmwa_menu_add_devices (menu, applet); - nmwa_menu_add_separator_item (menu); - - switch (applet->applet_state) - { - case (APPLET_STATE_NO_CONNECTION): - nmwa_menu_add_text_item (menu, _("No network connection is currently active...")); - break; - - case (APPLET_STATE_WIRED): - case (APPLET_STATE_WIRED_CONNECTING): - nmwa_menu_add_text_item (menu, _("A wired network connection is currently active...")); - break; - - case (APPLET_STATE_WIRELESS): - case (APPLET_STATE_WIRELESS_CONNECTING): - nmwa_menu_add_networks (menu, applet); - break; - - default: - break; - } + nmwa_menu_add_text_item (menu, _("Other Wireless Network...")); return (menu); } @@ -785,6 +777,7 @@ static void nmwa_setup_widgets (NMWirelessApplet *applet) applet->menu = gtk_menu_new(); gtk_menu_item_set_submenu (GTK_MENU_ITEM(applet->toplevel_menu), applet->menu); + g_signal_connect (applet->menu, "button_press_event", G_CALLBACK (do_not_eat_button_press), NULL); gtk_widget_show (menu_bar); gtk_widget_show (applet->toplevel_menu); @@ -810,10 +803,8 @@ static void change_orient_cb(PanelApplet *pa, gint s, NMWirelessApplet *applet) static gboolean do_not_eat_button_press (GtkWidget *widget, GdkEventButton *event) { - printf ("Getting button press\n"); - /*if (event->button != 1) + if (event->button != 1) g_signal_stop_emission_by_name (widget, "button_press_event"); - */ return (FALSE); } @@ -871,7 +862,6 @@ static GtkWidget * nmwa_new (NMWirelessApplet *applet) } applet->applet_state = APPLET_STATE_NO_NM; - applet->networks = NULL; applet->devices = NULL; applet->active_device = NULL; @@ -895,7 +885,6 @@ static GtkWidget * nmwa_new (NMWirelessApplet *applet) nmwa_setup_widgets (applet); g_signal_connect (applet,"destroy", G_CALLBACK (nmwa_destroy),NULL); - //g_signal_connect (applet->toplevel_menu, "button_press_event", G_CALLBACK (do_not_eat_button_press), NULL); panel_applet_setup_menu_from_file (PANEL_APPLET (applet), NULL, "NMWirelessApplet.xml", NULL, nmwa_context_menu_verbs, applet); diff --git a/panel-applet/NMWirelessApplet.h b/panel-applet/NMWirelessApplet.h index 0f9d063baa..6c0eba3542 100644 --- a/panel-applet/NMWirelessApplet.h +++ b/panel-applet/NMWirelessApplet.h @@ -84,7 +84,6 @@ typedef struct /* Data model elements */ GMutex *data_mutex; GSList *devices; - GSList *networks; char *active_device; AppletState applet_state; @@ -103,6 +102,7 @@ typedef struct */ typedef struct { + char *nm_name; char *essid; gboolean encrypted; gboolean active; @@ -120,6 +120,7 @@ typedef struct char *nm_name; char *hal_name; char *udi; + GSList *networks; } NetworkDevice; #endif diff --git a/panel-applet/NMWirelessAppletDbus.c b/panel-applet/NMWirelessAppletDbus.c index 406d648ae4..160b890dce 100644 --- a/panel-applet/NMWirelessAppletDbus.c +++ b/panel-applet/NMWirelessAppletDbus.c @@ -40,6 +40,10 @@ #define DBUS_NO_SERVICE_ERROR "org.freedesktop.DBus.Error.ServiceDoesNotExist" #define NM_DBUS_NO_ACTIVE_NET_ERROR "org.freedesktop.NetworkManager.NoActiveNetwork" + +static void wireless_network_free (void *element, void *user_data); + + /* * nmwa_dbus_get_string * @@ -50,7 +54,7 @@ * RETURN_NO_NM if NetworkManager service no longer exists * */ -int nmwa_dbus_get_string (DBusConnection *connection, const char *path, const char *method, char **string) +static int nmwa_dbus_get_string (DBusConnection *connection, const char *path, const char *method, char **string) { DBusMessage *message; DBusMessage *reply; @@ -82,6 +86,7 @@ int nmwa_dbus_get_string (DBusConnection *connection, const char *path, const ch else if (strcmp (error.name, NM_DBUS_NO_ACTIVE_NET_ERROR) == 0) ret = RETURN_SUCCESS; + dbus_error_free (&error); return (ret); } @@ -113,7 +118,7 @@ int nmwa_dbus_get_string (DBusConnection *connection, const char *path, const ch * RETURN_NO_NM if NetworkManager service no longer exists * */ -int nmwa_dbus_get_int (DBusConnection *connection, const char *path, const char *method, gint32 *num) +static int nmwa_dbus_get_int (DBusConnection *connection, const char *path, const char *method, gint32 *num) { DBusMessage *message; DBusMessage *reply; @@ -142,6 +147,7 @@ int nmwa_dbus_get_int (DBusConnection *connection, const char *path, const char if (strcmp (error.name, DBUS_NO_SERVICE_ERROR) == 0) ret = RETURN_NO_NM; + dbus_error_free (&error); return (ret); } @@ -172,7 +178,7 @@ int nmwa_dbus_get_int (DBusConnection *connection, const char *path, const char * RETURN_NO_NM if NetworkManager service no longer exists * */ -int nmwa_dbus_get_bool (DBusConnection *connection, const char *path, const char *method, gboolean *val) +static int nmwa_dbus_get_bool (DBusConnection *connection, const char *path, const char *method, gboolean *val) { DBusMessage *message; DBusMessage *reply; @@ -200,6 +206,7 @@ int nmwa_dbus_get_bool (DBusConnection *connection, const char *path, const char if (strcmp (error.name, DBUS_NO_SERVICE_ERROR) == 0) ret = RETURN_NO_NM; + dbus_error_free (&error); return (ret); } @@ -226,7 +233,7 @@ int nmwa_dbus_get_bool (DBusConnection *connection, const char *path, const char * nmwa_dbus_get_double * */ -double nmwa_dbus_get_double (DBusConnection *connection, const char *path, const char *method) +static double nmwa_dbus_get_double (DBusConnection *connection, const char *path, const char *method) { DBusMessage *message; DBusMessage *reply; @@ -249,6 +256,7 @@ double nmwa_dbus_get_double (DBusConnection *connection, const char *path, const { fprintf (stderr, "nmwa_dbus_get_double(): %s raised:\n %s\n\n", error.name, error.message); dbus_message_unref (message); + dbus_error_free (&error); return (0); } @@ -280,7 +288,7 @@ double nmwa_dbus_get_double (DBusConnection *connection, const char *path, const * RETURN_NO_NM if NetworkManager service no longer exists * */ -int nmwa_dbus_get_string_array (DBusConnection *connection, const char *path, const char *method, +static int nmwa_dbus_get_string_array (DBusConnection *connection, const char *path, const char *method, int *num_items, char ***string_array) { DBusMessage *message; @@ -319,6 +327,7 @@ int nmwa_dbus_get_string_array (DBusConnection *connection, const char *path, co ret = RETURN_SUCCESS; } + dbus_error_free (&error); return (ret); } @@ -349,7 +358,7 @@ int nmwa_dbus_get_string_array (DBusConnection *connection, const char *path, co * Returns the object_path of the currently active device, if any. * */ -char * nmwa_dbus_get_active_device (NMWirelessApplet *applet, AppletState failure_state) +static char * nmwa_dbus_get_active_device (NMWirelessApplet *applet, AppletState failure_state) { char *active_device = NULL; @@ -378,7 +387,7 @@ char * nmwa_dbus_get_active_device (NMWirelessApplet *applet, AppletState failur * Returns the object_path of the currently active network of the active device. * */ -char * nmwa_dbus_get_active_network (NMWirelessApplet *applet, char *dev_path, AppletState failure_state) +static char * nmwa_dbus_get_active_network (NMWirelessApplet *applet, char *dev_path, AppletState failure_state) { char *network = NULL; @@ -407,7 +416,7 @@ char * nmwa_dbus_get_active_network (NMWirelessApplet *applet, char *dev_path, A * Returns the device type of the specified device. * */ -int nmwa_dbus_get_device_type (NMWirelessApplet *applet, char *path, AppletState failure_state) +static int nmwa_dbus_get_device_type (NMWirelessApplet *applet, char *path, AppletState failure_state) { int type = -1; @@ -435,7 +444,7 @@ int nmwa_dbus_get_device_type (NMWirelessApplet *applet, char *path, AppletState * Returns the quality of a given wireless network * */ -guint8 nmwa_dbus_get_network_quality (NMWirelessApplet *applet, char *path) +static guint8 nmwa_dbus_get_network_quality (NMWirelessApplet *applet, char *path) { int qual = 0; @@ -459,7 +468,7 @@ guint8 nmwa_dbus_get_network_quality (NMWirelessApplet *applet, char *path) * Returns NetworkManager's status * */ -char * nmwa_dbus_get_nm_status (NMWirelessApplet *applet, AppletState failure_state) +static char * nmwa_dbus_get_nm_status (NMWirelessApplet *applet, AppletState failure_state) { char *status = NULL; @@ -487,7 +496,7 @@ char * nmwa_dbus_get_nm_status (NMWirelessApplet *applet, AppletState failure_st * Returns the name of a specified wireless network * */ -char * nmwa_dbus_get_network_name (NMWirelessApplet *applet, char *net_path) +static char * nmwa_dbus_get_network_name (NMWirelessApplet *applet, char *net_path) { char *name = NULL; @@ -511,7 +520,7 @@ char * nmwa_dbus_get_network_name (NMWirelessApplet *applet, char *net_path) * Returns the name of a specified network device * */ -char * nmwa_dbus_get_device_name (NMWirelessApplet *applet, char *dev_path) +static char * nmwa_dbus_get_device_name (NMWirelessApplet *applet, char *dev_path) { char *name = NULL; @@ -535,7 +544,7 @@ char * nmwa_dbus_get_device_name (NMWirelessApplet *applet, char *dev_path) * Returns the HAL udi of a network device * */ -char * nmwa_dbus_get_device_udi (NMWirelessApplet *applet, char *dev_path) +static char * nmwa_dbus_get_device_udi (NMWirelessApplet *applet, char *dev_path) { char *udi = NULL; @@ -559,7 +568,7 @@ char * nmwa_dbus_get_device_udi (NMWirelessApplet *applet, char *dev_path) * Returns whether or not the specified network is encrypted * */ -gboolean nmwa_dbus_get_network_encrypted (NMWirelessApplet *applet, char *net_path) +static gboolean nmwa_dbus_get_network_encrypted (NMWirelessApplet *applet, char *net_path) { gboolean enc = FALSE; @@ -583,7 +592,7 @@ gboolean nmwa_dbus_get_network_encrypted (NMWirelessApplet *applet, char *net_pa * Returns an array of wireless networks that the specified device knows about. * */ -char **nmwa_dbus_get_device_networks (NMWirelessApplet *applet, char *path, int *num_items, AppletState failure_state) +static char **nmwa_dbus_get_device_networks (NMWirelessApplet *applet, char *path, int *num_items, AppletState failure_state) { char **array = NULL; int items; @@ -616,7 +625,7 @@ char **nmwa_dbus_get_device_networks (NMWirelessApplet *applet, char *path, int * Get a string property from a device * */ -char *nmwa_dbus_get_hal_device_string_property (DBusConnection *connection, const char *udi, const char *property_name) +static char *nmwa_dbus_get_hal_device_string_property (DBusConnection *connection, const char *udi, const char *property_name) { DBusError error; DBusMessage *message; @@ -661,7 +670,7 @@ char *nmwa_dbus_get_hal_device_string_property (DBusConnection *connection, cons * Grab the info.product tag from hal for a specific UDI * */ -char *nmwa_dbus_get_hal_device_info (DBusConnection *connection, const char *udi) +static char *nmwa_dbus_get_hal_device_info (DBusConnection *connection, const char *udi) { DBusError error; DBusMessage *message; @@ -760,64 +769,85 @@ static void wireless_network_free (void *element, void *user_data) { WirelessNetwork *net = (WirelessNetwork *)(element); - if (net) g_free (net->essid); + g_return_if_fail (net != NULL); + + g_free (net->nm_name); + g_free (net->essid); g_free (net); } /* - * nmwa_dbus_update_wireless_network_list - * - * Query NetworkManager for the wireless networks the active device - * knows about, if the active device is wireless. + * network_device_free_wireless_network_list * */ -void nmwa_dbus_update_wireless_network_list (NMWirelessApplet *applet) +static void network_device_free_wireless_network_list (NetworkDevice *dev) +{ + g_return_if_fail (dev != NULL); + + g_slist_foreach (dev->networks, wireless_network_free, NULL); + g_slist_free (dev->networks); + dev->networks = NULL; +} + + +/* + * network_device_free + * + * Frees the representation of a network device + * + */ +static void network_device_free (void *element, void *user_data) +{ + NetworkDevice *dev = (NetworkDevice *)(element); + + g_return_if_fail (dev != NULL); + + network_device_free_wireless_network_list (dev); + g_free (dev->nm_device); + g_free (dev->nm_name); + dbus_free (dev->udi); + dbus_free (dev->hal_name); + g_free (dev); +} + + +/* + * nmwa_dbus_update_device_wireless_networks + * + * Query NetworkManager for the wireless networks a particular device + * knows about, if the active device is wireless. + * + * NOTE: caller must lock device list if necessary + * + */ +static void nmwa_dbus_update_device_wireless_networks (NetworkDevice *dev, NMWirelessApplet *applet) { - char *active_device = NULL; char *active_network = NULL; int dev_type; char **networks = NULL; int num_items = 0; int i; - /* Grab the lock for the network list. */ - g_mutex_lock (applet->data_mutex); + g_return_if_fail (dev != NULL); /* Clear out existing entries in the list */ - if (applet->networks) - { - g_slist_foreach (applet->networks, wireless_network_free, NULL); - g_slist_free (applet->networks); - applet->networks = NULL; - } - g_mutex_unlock (applet->data_mutex); + if (dev->networks) + network_device_free_wireless_network_list (dev); - if ( (applet->applet_state != APPLET_STATE_WIRELESS) - && (applet->applet_state != APPLET_STATE_WIRELESS_CONNECTING)) - return; - - if (!(active_device = nmwa_dbus_get_active_device (applet, APPLET_STATE_NO_CONNECTION))) - goto out; - - if ( ((dev_type = nmwa_dbus_get_device_type (applet, active_device, APPLET_STATE_NO_CONNECTION)) == -1) + if ( ((dev_type = nmwa_dbus_get_device_type (applet, dev->nm_device, APPLET_STATE_NO_CONNECTION)) == -1) || (dev_type != DEVICE_TYPE_WIRELESS_ETHERNET)) goto out; - active_network = nmwa_dbus_get_active_network (applet, active_device, APPLET_STATE_IGNORE); + 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, active_device, &num_items, APPLET_STATE_NO_CONNECTION); - if ((applet->applet_state != APPLET_STATE_WIRELESS) && (applet->applet_state != APPLET_STATE_WIRELESS_CONNECTING)) + 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; - if (!networks) - goto out; - - g_mutex_lock (applet->data_mutex); - for (i = 0; i < num_items; i++) { char *name = NULL; @@ -825,7 +855,7 @@ void nmwa_dbus_update_wireless_network_list (NMWirelessApplet *applet) if (!(name = nmwa_dbus_get_network_name (applet, networks[i]))) break; - if (name && strlen (name)) + if (strlen (name)) { gboolean found = FALSE; int j; @@ -842,20 +872,20 @@ void nmwa_dbus_update_wireless_network_list (NMWirelessApplet *applet) continue; net = g_new0 (WirelessNetwork, 1); + net->nm_name = g_strdup (networks[i]); net->essid = g_strdup (name); - net->active = active_network ? (strcmp (networks[i], active_network) == 0) : FALSE; - net->encrypted = nmwa_dbus_get_network_encrypted (applet, networks[i]); - net->quality = nmwa_dbus_get_network_quality (applet, networks[i]); + net->active = active_network ? (strcmp (net->nm_name, active_network) == 0) : FALSE; + net->encrypted = nmwa_dbus_get_network_encrypted (applet, net->nm_name); + net->quality = nmwa_dbus_get_network_quality (applet, net->nm_name); fprintf( stderr, "Adding '%s' active (%d), enc (%d)\n", name, net->active, net->encrypted); - applet->networks = g_slist_append (applet->networks, net); + dev->networks = g_slist_append (dev->networks, net); } dbus_free (name); } g_mutex_unlock (applet->data_mutex); out: - dbus_free (active_device); dbus_free (active_network); dbus_free_string_array (networks); } @@ -867,7 +897,7 @@ out: * Update our state based on what NetworkManager's network state is * */ -void nmwa_dbus_update_network_state (NMWirelessApplet *applet) +static void nmwa_dbus_update_network_state (NMWirelessApplet *applet) { char *active_device = NULL; char *nm_status = NULL; @@ -918,34 +948,13 @@ 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->nm_name); - dbus_free (dev->udi); - dbus_free (dev->hal_name); - } - g_free (dev); -} - - /* * nmwa_dbus_update_active_device * * Get the active device from NetworkManager * */ -void nmwa_dbus_update_active_device (NMWirelessApplet *applet) +static void nmwa_dbus_update_active_device (NMWirelessApplet *applet) { g_return_if_fail (applet != NULL); @@ -963,7 +972,7 @@ void nmwa_dbus_update_active_device (NMWirelessApplet *applet) * Get a device list from NetworkManager * */ -void nmwa_dbus_update_devices (NMWirelessApplet *applet) +static void nmwa_dbus_update_devices (NMWirelessApplet *applet) { char **devices = NULL; int num_items = 0; @@ -1013,6 +1022,7 @@ void nmwa_dbus_update_devices (NMWirelessApplet *applet) { applet->devices = g_slist_append (applet->devices, dev); fprintf( stderr, "Got device '%s', udi '%s'\n", dev->nm_name, dev->udi); + nmwa_dbus_update_device_wireless_networks (dev, applet); } } } @@ -1024,6 +1034,40 @@ void nmwa_dbus_update_devices (NMWirelessApplet *applet) } +/* + * nmwa_dbus_get_device_for_nm_device + * + * Searches the device list for a device that matches the + * NetworkManager ID given. + * + */ +static NetworkDevice *nmwa_dbus_get_device_for_nm_device (NMWirelessApplet *applet, const char *nm_dev) +{ + NetworkDevice *found_dev = NULL; + GSList *element; + + 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->devices; + while (element) + { + NetworkDevice *dev = (NetworkDevice *)(element->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_dbus_filter * @@ -1060,7 +1104,29 @@ static DBusHandlerResult nmwa_dbus_filter (DBusConnection *connection, DBusMessa else if ( dbus_message_is_signal (message, NM_DBUS_INTERFACE, "WirelessNetworkAppeared") || dbus_message_is_signal (message, NM_DBUS_INTERFACE, "WirelessNetworkDisappeared")) { - nmwa_dbus_update_wireless_network_list (applet); + char *nm_device = NULL; + char *network = NULL; + DBusError error; + + dbus_error_init (&error); + if (dbus_message_get_args (message, &error, DBUS_TYPE_STRING, &nm_device, + DBUS_TYPE_STRING, &network, DBUS_TYPE_INVALID)) + { + NetworkDevice *dev; + + if ((dev = nmwa_dbus_get_device_for_nm_device (applet, nm_device))) + { + g_mutex_lock (applet->data_mutex); + nmwa_dbus_update_device_wireless_networks (dev, applet); + g_mutex_unlock (applet->data_mutex); + } + } + + if (dbus_error_is_set (&error)) + dbus_error_free (&error); + + dbus_free (nm_device); + dbus_free (network); } else if ( dbus_message_is_signal (message, NM_DBUS_INTERFACE, "DeviceNowActive") || dbus_message_is_signal (message, NM_DBUS_INTERFACE, "DeviceNoLongerActive") @@ -1087,7 +1153,7 @@ static DBusHandlerResult nmwa_dbus_filter (DBusConnection *connection, DBusMessa * Ask dbus whether or not NetworkManager is running * */ -gboolean nmwa_dbus_nm_is_running (DBusConnection *connection) +static gboolean nmwa_dbus_nm_is_running (DBusConnection *connection) { DBusError error; gboolean exists; @@ -1201,8 +1267,6 @@ gpointer nmwa_dbus_worker (gpointer user_data) if (applet->connection && nmwa_dbus_nm_is_running (applet->connection)) { nmwa_dbus_update_network_state (applet); - if ((applet->applet_state == APPLET_STATE_WIRELESS) || (applet->applet_state == APPLET_STATE_WIRELESS_CONNECTING)) - nmwa_dbus_update_wireless_network_list (applet); nmwa_dbus_update_devices (applet); nmwa_dbus_update_active_device (applet); } diff --git a/panel-applet/NMWirelessAppletDbus.h b/panel-applet/NMWirelessAppletDbus.h index 087fb85217..4480e66385 100644 --- a/panel-applet/NMWirelessAppletDbus.h +++ b/panel-applet/NMWirelessAppletDbus.h @@ -48,6 +48,4 @@ void nmwa_dbus_set_network (DBusConnection *connection, char *network); void nmwa_dbus_set_device (DBusConnection *connection, char *device); -char * nmwa_dbus_get_active_device (NMWirelessApplet *applet, AppletState failure_state); - #endif diff --git a/src/NMLoadModules b/src/NMLoadModules index 3d1e6720f7..0dc6a486cc 100755 --- a/src/NMLoadModules +++ b/src/NMLoadModules @@ -48,7 +48,7 @@ for i in $interfaces; do unset DEVICE TYPE SLAVE BRIDGE # Load the module - LC_ALL= LANG= ip -o link | grep -q $i + LC_ALL= LANG= /sbin/ip -o link | grep -q $i if [ "$?" = "1" ]; then alias=`modprobe -c | awk "/^(alias|install)[[:space:]]+$i[[:space:]]/ { print \\$3 }"` if [ -n "$alias" -a "$alias" != "off" -a "$alias" != "/bin/true" ]; then diff --git a/src/NetworkManager.c b/src/NetworkManager.c index f11924d5ea..6632b08dbc 100644 --- a/src/NetworkManager.c +++ b/src/NetworkManager.c @@ -361,13 +361,14 @@ gboolean nm_link_state_monitor (gpointer user_data) switch (nm_device_get_type (dev)) { case DEVICE_TYPE_WIRELESS_ETHERNET: - if (dev != data->active_device) + nm_device_update_link_active (dev, FALSE); + if ((dev == data->active_device) && !nm_device_get_link_active (dev)) { - if (nm_device_is_up (dev)) - nm_device_bring_down (dev); + /* If we loose a link to the access point, then + * look for another access point to connect to. + */ + nm_device_update_best_ap (dev); } - else - nm_device_update_link_active (dev, FALSE); break; case DEVICE_TYPE_WIRED_ETHERNET: diff --git a/src/NetworkManagerDbus.c b/src/NetworkManagerDbus.c index 88d88c48f3..7f36d15841 100644 --- a/src/NetworkManagerDbus.c +++ b/src/NetworkManagerDbus.c @@ -856,7 +856,6 @@ static DBusHandlerResult nm_dbus_nmi_filter (DBusConnection *connection, DBusMes NMData *data = (NMData *)user_data; const char *object_path; const char *method; - NMAccessPointList *list = NULL; gboolean handled = FALSE; g_return_val_if_fail (data != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED); @@ -871,7 +870,19 @@ static DBusHandlerResult nm_dbus_nmi_filter (DBusConnection *connection, DBusMes if ( (strcmp (object_path, NMI_DBUS_PATH) == 0) && dbus_message_is_signal (message, NMI_DBUS_INTERFACE, "WirelessNetworkUpdate")) - list = data->allowed_ap_list; + { + char *network = NULL; + DBusError error; + + dbus_error_init (&error); + if (!dbus_message_get_args (message, &error, DBUS_TYPE_STRING, &network, DBUS_TYPE_INVALID)) + return (DBUS_HANDLER_RESULT_NOT_YET_HANDLED); + + syslog (LOG_DEBUG, "NetowrkManagerInfo triggered update of wireless network '%s'", network); + nm_ap_list_update_network (data->allowed_ap_list, network, data); + dbus_free (network); + handled = TRUE; + } else if (dbus_message_is_signal (message, DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS, "ServiceCreated")) { char *service; @@ -907,34 +918,6 @@ static DBusHandlerResult nm_dbus_nmi_filter (DBusConnection *connection, DBusMes */ } - if (list) - { - char *network = NULL; - DBusError error; - - dbus_error_init (&error); - if (!dbus_message_get_args (message, &error, DBUS_TYPE_STRING, &network, DBUS_TYPE_INVALID)) - return (DBUS_HANDLER_RESULT_NOT_YET_HANDLED); - - syslog( LOG_DEBUG, "update of network '%s'", network); - nm_ap_list_update_network (list, network, data); - dbus_free (network); - - /* Make sure the currently active device updates its "best" ap - * based on the new preferred/trusted network information. - */ - if ( data->active_device - && nm_device_is_wireless (data->active_device) - && !nm_device_activating (data->active_device)) - { - syslog( LOG_DEBUG, "updating active device's best ap"); - nm_device_update_best_ap (data->active_device); - nm_data_mark_state_changed (data); - syslog( LOG_DEBUG, "Device's best ap now '%s'", nm_ap_get_essid (nm_device_get_best_ap (data->active_device))); - } - handled = TRUE; - } - return (handled ? DBUS_HANDLER_RESULT_HANDLED : DBUS_HANDLER_RESULT_NOT_YET_HANDLED); } @@ -1062,15 +1045,16 @@ static DBusMessage *nm_dbus_devices_handle_request (DBusConnection *connection, return (reply_message); } - if ((ap = nm_device_ap_list_get_ap_by_essid (dev, nm_device_get_essid (dev)))) + /* Return the network associated with the ESSID the card is currently associated with, + * if any, and only if that network is the "best" network. + */ + if ( (ap = nm_device_ap_list_get_ap_by_essid (dev, nm_device_get_essid (dev))) + && (!nm_device_need_ap_switch (dev)) + && (object_path = nm_device_get_path_for_ap (dev, ap))) { - if ( (nm_null_safe_strcmp (nm_ap_get_essid (ap), nm_ap_get_essid (nm_device_get_best_ap (dev))) == 0) - && (object_path = nm_device_get_path_for_ap (dev, ap))) - { - dbus_message_append_args (reply_message, DBUS_TYPE_STRING, object_path, DBUS_TYPE_INVALID); - g_free (object_path); - success = TRUE; - } + dbus_message_append_args (reply_message, DBUS_TYPE_STRING, object_path, DBUS_TYPE_INVALID); + g_free (object_path); + success = TRUE; } if (!success) diff --git a/src/NetworkManagerDevice.c b/src/NetworkManagerDevice.c index 786e38e20b..89dc7fe126 100644 --- a/src/NetworkManagerDevice.c +++ b/src/NetworkManagerDevice.c @@ -326,8 +326,7 @@ NMDevice *nm_device_new (const char *iface, gboolean test_dev, NMDeviceType test nm_system_device_update_config_info (dev); /* Have to bring the device up before checking link status. */ - if (!nm_device_is_up (dev)) - nm_device_bring_up (dev); + nm_device_bring_up (dev); nm_device_update_link_active (dev, TRUE); return (dev); @@ -444,6 +443,8 @@ void nm_device_set_link_active (NMDevice *dev, const gboolean link_active) g_return_if_fail (dev != NULL); dev->link_active = link_active; + if (!link_active && nm_device_is_wireless (dev)) + nm_device_set_best_ap (dev, NULL); } @@ -476,24 +477,11 @@ static gboolean nm_device_wireless_link_active (NMDevice *dev) g_return_val_if_fail (dev != NULL, FALSE); g_return_val_if_fail (dev->app_data != NULL, FALSE); - /* Since non-active wireless cards are supposed to be powered off anyway, - * only scan for active/pending device and clear ap_list and best_ap for - * devices that aren't active/pending. - */ - if (dev != dev->app_data->active_device) - { - nm_ap_list_unref (dev->options.wireless.ap_list); - dev->options.wireless.ap_list = NULL; - if (dev->options.wireless.best_ap) - nm_ap_unref (dev->options.wireless.best_ap); - return (FALSE); - } - /* Test devices have their link state set through DBUS */ if (dev->test_device) return (nm_device_get_link_active (dev)); - /* FIXME + /* * For wireless cards, the best indicator of a "link" at this time * seems to be whether the card has a valid access point MAC address. * Is there a better way? @@ -1012,6 +1000,31 @@ gboolean nm_device_activation_begin (NMDevice *dev) } +/* + * nm_device_activation_cancel_if_needed + * + * Check whether we should stop activation, and if so clean up flags + * and other random things. + * + */ +gboolean nm_device_activation_cancel_if_needed (NMDevice *dev) +{ + g_return_val_if_fail (dev != NULL, TRUE); + + /* If we were told to quit activation, stop the thread and return */ + if (dev->quit_activation) + { + syslog (LOG_DEBUG, "nm_device_activation_worker(%s): activation canceled.", nm_device_get_iface (dev)); + dev->activating = FALSE; + dev->just_activated = FALSE; + nm_device_unref (dev); + return (TRUE); + } + + return (FALSE); +} + + /* * nm_device_activate_wireless * @@ -1029,15 +1042,8 @@ static gboolean nm_device_activate_wireless (NMDevice *dev) g_return_val_if_fail (dev != NULL, FALSE); g_return_val_if_fail (nm_device_is_wireless (dev), FALSE); - /* If the card is just inserted, we may not have had a chance to scan yet */ - if (!(best_ap = nm_device_get_best_ap (dev))) - { - nm_device_do_wireless_scan (dev); - best_ap = nm_device_get_best_ap (dev); - } - /* If there is a desired AP to connect to, use that essid and possible WEP key */ - if (best_ap && nm_ap_get_essid (best_ap)) + if ((best_ap = nm_device_get_best_ap (dev)) && nm_ap_get_essid (best_ap)) { nm_device_bring_down (dev); @@ -1048,7 +1054,6 @@ static gboolean nm_device_activate_wireless (NMDevice *dev) if (nm_ap_get_encrypted (best_ap) && nm_ap_get_enc_key_source (best_ap)) { char *hashed_key = nm_ap_get_enc_key_hashed (best_ap, nm_ap_get_enc_method (best_ap)); -fprintf( stderr, "hashed key = '%s'\n", hashed_key ); nm_device_set_enc_key (dev, hashed_key); g_free (hashed_key); } @@ -1071,27 +1076,117 @@ fprintf( stderr, "hashed key = '%s'\n", hashed_key ); /* - * nm_device_activation_cancel_if_needed + * nm_device_activate_wireless_wait_for_link * - * Check whether we should stop activation, and if so clean up flags - * and other random things. + * Spin until we have a wireless link, which may mean + * requesting a key from the user and trying various hashed + * iterations of that key. * */ -gboolean nm_device_activation_cancel_if_needed (NMDevice *dev) +void nm_device_activate_wireless_wait_for_link (NMDevice *dev) { - g_return_val_if_fail (dev != NULL, TRUE); + NMAccessPoint *best_ap; - /* If we were told to quit activation, stop the thread and return */ - if (dev->quit_activation) + g_return_if_fail (dev != NULL); + + /* If the card is just inserted, we may not have had a chance to scan yet */ + if (!(best_ap = nm_device_get_best_ap (dev))) { - syslog (LOG_DEBUG, "nm_device_activation_worker(%s): activation canceled.", nm_device_get_iface (dev)); - dev->activating = FALSE; - dev->just_activated = FALSE; - nm_device_unref (dev); - return (TRUE); + nm_device_do_wireless_scan (dev); + best_ap = nm_device_get_best_ap (dev); } - return (FALSE); + /* Try activating the device with the key and access point we have already */ + nm_device_activate_wireless (dev); + + /* Wait until we have a link. Some things that might block us from + * getting one: + * 1) Access point we want to associate with has encryption enabled and + * we don't have the right encryption key. If we have a key of some + * sort, try various passhprase->key hashes of it. If we don't have + * a key, ask the user for one and wait until we are canceled (wireless + * card was ejected or the user plugged the computer into a wired network) + * or until we get a key back. + * 2) We don't have any access points we wish to associate with yet. In that case + * wait for the wireless scan to complete in the other thread and to pick + * a "best" access point for us. + * + */ + while (!nm_device_get_link_active (dev)) + { + if ((best_ap = nm_device_get_best_ap (dev))) + { + fprintf( stderr, "is_enc (%d) && (!enc_source (%d) || !enc_method_good (%d)) && \n", + best_ap ? nm_ap_get_encrypted (best_ap) : FALSE, + !!nm_ap_get_enc_key_source (best_ap), + best_ap ? nm_ap_get_enc_method_good (best_ap) : FALSE); + + /* Since we don't have a link yet, something is bad with the + * encryption key, try falling back to a different method of + * encryption or asking the user for a new key. + */ + if ( nm_ap_get_encrypted (best_ap) + && (!nm_ap_get_enc_key_source (best_ap) || !nm_ap_get_enc_method_good (best_ap))) + { + gboolean ask_for_key = TRUE; + + /* If we have a key, try all the key/passphrase generation methods + * before asking the user for a key. + */ + if (nm_ap_get_enc_key_source (best_ap) && !nm_ap_get_enc_method_good (best_ap)) + { + /* Try another method, since the one set in a previous iteration obviously didn't work */ + switch (nm_ap_get_enc_method (best_ap)) + { + case (NM_AP_ENC_METHOD_UNKNOWN): + nm_ap_set_enc_method (best_ap, NM_AP_ENC_METHOD_104_BIT_PASSPHRASE); + ask_for_key = FALSE; + break; + case (NM_AP_ENC_METHOD_104_BIT_PASSPHRASE): + nm_ap_set_enc_method (best_ap, NM_AP_ENC_METHOD_40_BIT_PASSPHRASE); + ask_for_key = FALSE; + break; + case (NM_AP_ENC_METHOD_40_BIT_PASSPHRASE): + nm_ap_set_enc_method (best_ap, NM_AP_ENC_METHOD_HEX_KEY); + ask_for_key = FALSE; + break; + default: + break; + } + } + + /* If all fallbacks for encryption method fail, ask the user for a new WEP key */ + if (ask_for_key) + { + dev->options.wireless.user_key_received = FALSE; + nm_dbus_get_user_key_for_network (dev->app_data->dbus_connection, dev, best_ap); + + /* Wait for the key to come back */ + syslog (LOG_DEBUG, "nm_device_activation_worker(%s): asking for user key.", nm_device_get_iface (dev)); + while (!dev->options.wireless.user_key_received && !dev->quit_activation) + g_usleep (G_USEC_PER_SEC / 2); + + syslog (LOG_DEBUG, "nm_device_activation_worker(%s): user key received.", nm_device_get_iface (dev)); + } + + /* If we were told to quit activation, stop the thread and return */ + if (nm_device_activation_cancel_if_needed (dev)) + return; + } + + /* Try activating again with up-to-date access point and keys */ + nm_device_activate_wireless (dev); + } + else + { + syslog (LOG_DEBUG, "nm_device_activation_worker(%s): waiting for an access point.", nm_device_get_iface (dev)); + g_usleep (G_USEC_PER_SEC * 2); + } + + /* If we were told to quit activation, stop the thread and return */ + if (nm_device_activation_cancel_if_needed (dev)) + break; + } } @@ -1153,88 +1248,11 @@ static gpointer nm_device_activation_worker (gpointer user_data) /* If its a wireless device, set the ESSID and WEP key */ if (nm_device_is_wireless (dev)) { - nm_device_activate_wireless (dev); + nm_device_activate_wireless_wait_for_link (dev); - /* If we don't have a link, it probably means the access point has - * encryption enabled and we don't have the right WEP key, or we don't - * have a "best" access point. Sit around and wait for either the WEP key - * or a good "best" AP. - */ - while (!nm_device_get_link_active (dev)) - { - NMAccessPoint *best_ap; - - if ((best_ap = nm_device_get_best_ap (dev))) - { -fprintf( stderr, "(!switch (%d) || !enc_source (%d) || !enc_method_good (%d)) && is_enc (%d)\n", -!nm_device_need_ap_switch (dev), !nm_ap_get_enc_key_source (best_ap), -nm_ap_get_enc_method_good (best_ap), nm_ap_get_encrypted (best_ap)); - /* Something is bad with the encryption key, try falling back to a different - * method of encryption or asking the user for a new key. - */ - if ( nm_ap_get_encrypted (best_ap) - && ( !nm_device_need_ap_switch (dev) - || !nm_ap_get_enc_key_source (best_ap) - || !nm_ap_get_enc_method_good (best_ap))) - { - gboolean ask_for_key = TRUE; - - /* If we have a key, try all the key/passphrase generation methods - * before asking the user for a key. - */ - if (nm_ap_get_enc_key_source (best_ap) && !nm_ap_get_enc_method_good (best_ap)) - { - /* Try another method, since the one set in a previous iteration obviously didn't work */ - switch (nm_ap_get_enc_method (best_ap)) - { - case (NM_AP_ENC_METHOD_UNKNOWN): - nm_ap_set_enc_method (best_ap, NM_AP_ENC_METHOD_104_BIT_PASSPHRASE); - ask_for_key = FALSE; - break; - case (NM_AP_ENC_METHOD_104_BIT_PASSPHRASE): - nm_ap_set_enc_method (best_ap, NM_AP_ENC_METHOD_40_BIT_PASSPHRASE); - ask_for_key = FALSE; - break; - case (NM_AP_ENC_METHOD_40_BIT_PASSPHRASE): - nm_ap_set_enc_method (best_ap, NM_AP_ENC_METHOD_HEX_KEY); - ask_for_key = FALSE; - break; - default: - break; - } - } - - /* If all fallbacks for encryption method fail, ask the user for a new WEP key */ - if (ask_for_key) - { - dev->options.wireless.user_key_received = FALSE; - nm_dbus_get_user_key_for_network (dev->app_data->dbus_connection, dev, best_ap); - - /* Wait for the key to come back */ - syslog (LOG_DEBUG, "nm_device_activation_worker(%s): asking for user key.", nm_device_get_iface (dev)); - while (!dev->options.wireless.user_key_received && !dev->quit_activation) - g_usleep (G_USEC_PER_SEC / 2); - - syslog (LOG_DEBUG, "nm_device_activation_worker(%s): user key received.", nm_device_get_iface (dev)); - } - - /* If we were told to quit activation, stop the thread and return */ - if (nm_device_activation_cancel_if_needed (dev)) - return (NULL); - } - - nm_device_activate_wireless (dev); - } - else -{ -fprintf (stderr, "sleeping due to no access point\n"); - g_usleep (G_USEC_PER_SEC * 2); -} - - /* If we were told to quit activation, stop the thread and return */ - if (nm_device_activation_cancel_if_needed (dev)) - return (NULL); - } + /* If we were told to quit activation, stop the thread and return */ + if (nm_device_activation_cancel_if_needed (dev)) + return; /* Since we've got a link, the encryption method must be good */ nm_ap_set_enc_method_good (nm_device_get_best_ap (dev), TRUE); @@ -1362,12 +1380,11 @@ gboolean nm_device_deactivate (NMDevice *dev, gboolean just_added) if (!just_added) 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 */ if (nm_device_is_wireless (dev)) { nm_device_set_essid (dev, ""); nm_device_set_enc_key (dev, NULL); - nm_device_bring_down (dev); } return (TRUE); @@ -1415,9 +1432,9 @@ void nm_device_set_user_key_for_network (NMDevice *dev, NMAccessPointList *inval { nm_ap_set_enc_key_source (best_ap, key); nm_ap_set_enc_method (best_ap, NM_AP_ENC_METHOD_UNKNOWN); + nm_ap_set_enc_method_good (best_ap, FALSE); } } -fprintf( stderr, "Got user key\n"); dev->options.wireless.user_key_received = TRUE; } @@ -1528,6 +1545,7 @@ void nm_device_set_best_ap (NMDevice *dev, NMAccessPoint *ap) nm_ap_ref (ap); dev->options.wireless.best_ap = ap; + nm_device_unfreeze_best_ap (dev); g_mutex_unlock (dev->options.wireless.best_ap_mutex); } @@ -1607,7 +1625,10 @@ gboolean nm_device_need_ap_switch (NMDevice *dev) /* * nm_device_update_best_ap * - * Recalculate the "best" access point we should be associating with. + * Recalculate the "best" access point we should be associating with. This + * function may disrupt the current connection, so it should be called only + * when necessary, ie when the current access point is no longer in range + * or is for some other reason invalid and should no longer be used. * */ void nm_device_update_best_ap (NMDevice *dev) @@ -1782,6 +1803,7 @@ static void nm_device_do_normal_scan (NMDevice *dev) { nm_ap_set_encrypted (nm_ap, FALSE); nm_ap_set_enc_method (nm_ap, NM_AP_ENC_METHOD_NONE); + nm_ap_set_enc_method_good (nm_ap, TRUE); } else { @@ -1819,8 +1841,6 @@ static void nm_device_do_normal_scan (NMDevice *dev) nm_ap_list_diff (dev->app_data, dev, old_ap_list, nm_device_ap_list_get (dev)); if (old_ap_list) nm_ap_list_unref (old_ap_list); - - nm_device_update_best_ap (dev); } else syslog (LOG_ERR, "nm_device_do_normal_scan() could not get a control socket for the wireless card %s.", nm_device_get_iface (dev) ); diff --git a/src/NetworkManagerPolicy.c b/src/NetworkManagerPolicy.c index 7daa9393d7..9f25c175d8 100644 --- a/src/NetworkManagerPolicy.c +++ b/src/NetworkManagerPolicy.c @@ -207,10 +207,6 @@ static NMDevice * nm_policy_get_best_device (NMData *data) */ if (data->active_device && nm_device_is_wireless (data->active_device)) { - /* Give ourselves a chance to clear the "best" access point if - * its gone out of range and no longer in the device's ap list. - */ - nm_device_update_best_ap (data->active_device); if (nm_device_get_best_ap_frozen (data->active_device)) best_dev = data->active_device; } diff --git a/src/NetworkManagerWireless.c b/src/NetworkManagerWireless.c index 74ada8a8b0..9a49282483 100644 --- a/src/NetworkManagerWireless.c +++ b/src/NetworkManagerWireless.c @@ -109,24 +109,29 @@ char *nm_wireless_128bit_key_from_passphrase (char *passphrase) gboolean nm_wireless_scan_monitor (gpointer user_data) { NMData *data = (NMData *)user_data; + GSList *element; + NMDevice *dev; g_return_val_if_fail (data != NULL, TRUE); - if (!data->active_device) - return (TRUE); - /* Attempt to acquire mutex so that data->active_device sticks around. * If the acquire fails, just ignore the scan completely. */ - if (nm_try_acquire_mutex (data->dev_list_mutex, __FUNCTION__)) + if (!nm_try_acquire_mutex (data->dev_list_mutex, __FUNCTION__)) { - if (data->active_device && nm_device_is_wireless (data->active_device)) - nm_device_do_wireless_scan (data->active_device); - - nm_unlock_mutex (data->dev_list_mutex, __FUNCTION__); + syslog (LOG_ERR, "nm_wireless_scan_monitor() could not acquire device list mutex." ); + return (TRUE); } - else - syslog( LOG_ERR, "nm_wireless_scan_monitor() could not acquire device list mutex." ); + + element = data->dev_list; + while (element) + { + if ((dev = (NMDevice *)(element->data)) && nm_device_is_wireless (dev)) + nm_device_do_wireless_scan (dev); + element = g_slist_next (element); + } + + nm_unlock_mutex (data->dev_list_mutex, __FUNCTION__); return (TRUE); } diff --git a/test/nmclienttest.c b/test/nmclienttest.c index 6466e5a007..d0bd292d2a 100644 --- a/test/nmclienttest.c +++ b/test/nmclienttest.c @@ -198,7 +198,10 @@ void get_device_active_network (DBusConnection *connection, char *path) reply = dbus_connection_send_with_reply_and_block (connection, message, -1, &error); if (dbus_error_is_set (&error)) { - fprintf (stderr, "%s raised:\n %s\n\n", error.name, error.message); + if (strstr (error.name, "NoActiveNetwork")) + fprintf (stderr, " This device is not associated with a wireless network\n"); + else + fprintf (stderr, "%s raised:\n %s\n\n", error.name, error.message); dbus_message_unref (message); return; } @@ -305,7 +308,7 @@ int get_device_type (DBusConnection *connection, char *path) int type; type = dbus_message_iter_get_int32 (&iter); - fprintf (stderr, "Active device type: '%d'\n", type ); + fprintf (stderr, " Device type: '%d'\n", type ); dbus_message_unref (reply); dbus_message_unref (message); @@ -362,7 +365,7 @@ void get_device_networks (DBusConnection *connection, const char *path) dbus_message_unref (message); int i; - fprintf( stderr, "Networks:\n" ); + fprintf( stderr, " Networks:\n" ); for (i = 0; i < num_networks; i++) { DBusMessage *message2; @@ -408,7 +411,7 @@ void get_device_networks (DBusConnection *connection, const char *path) dbus_message_unref (reply2); dbus_message_unref (message2); - fprintf( stderr, " %s (%s)\n", networks[i], string2 ); + fprintf( stderr, " %s (%s)\n", networks[i], string2 ); } dbus_free_string_array (networks); @@ -465,7 +468,17 @@ void get_devices (DBusConnection *connection) int i; fprintf( stderr, "Devices:\n" ); for (i = 0; i < num_devices; i++) - fprintf( stderr, " %s\n", devices[i] ); + { + int type; + + fprintf (stderr, " %s\n", devices[i]); + if ((type = get_device_type (connection, devices[i])) == 2) + { + get_device_active_network (connection, devices[i]); + get_device_networks (connection, devices[i]); + } + fprintf (stderr, "\n"); + } dbus_free_string_array (devices); } @@ -488,18 +501,10 @@ int main( int argc, char *argv[] ) } char *path; - int type; get_nm_status (connection); path = get_active_device (connection); get_device_name (connection, path); - type = get_device_type (connection, path); - if (type == 2) - { - get_device_active_network (connection, path); - get_device_networks (connection, path); - } - get_devices (connection); g_free (path);