diff --git a/ChangeLog b/ChangeLog index 954aa12ca..8c9e607b6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,89 @@ +2005-03-31 Dan Williams + + Tighten up handling of wireless devices that don't support wireless + scanning (ie, Orinoco). Due to restructuring of code, these devices + hadn't been doing pseudo-scanning for a while either and would just + spin waiting for an access point. They are now manual devices where + the user must choose the access point from the menu every time. All + "allowed" access points are listed in the applet's menu regardless + of whether or not they can be seen by the card, since it can't scan + anyway. + + * src/NetworkManager.c + - (nm_wireless_link_state_handle): new function, but only update + the "best" ap for non-scanning devices when its not activating, + and when no device is being forced on the card + - (nm_link_state_monitor): split wireless link state handling out + into separate function + + * src/NetworkManagerDevice.c + - (nm_device_copy_allowed_to_dev_list): new function + - (nm_device_new): populate non-scanning cards' AP lists with + access points from the "allowed" list + - (nm_device_new): don't start a scanning timeout for devices that + can't scan + - (nm_device_activation_schedule_finish): new parameter, should be + the AP that failed to be connected to, pass it on to the + activation finish function in NetworkManagerPolicy.c + - (nm_device_activate_wireless): don't ever try to get a new AP + for non-scanning devices, just fail. The user must choose + a new access point manually. + - (nm_device_activate): grab the AP that failed connection and + pass it on + - (nm_device_update_best_ap): Clear the best AP if we don't have + a link to it, user must manually choose a new one + - (nm_device_do_pseudo_scan): remove function + - (nm_device_wireless_process_scan_results): remove bits for non- + scanning cards since they never get here + - (nm_device_wireless_scan): remove bits for non-scanning devices, + and fake the scan list for test devices a bit earlier + + * src/NetworkManagerPolicy.c + - (nm_policy_activation_finish): use the failed_ap that we get + passed rather than getting the best_ap from the card, which + may have changed since we were scheduled + - (nm_policy_allowed_ap_list_update): for non-scanning devices, + update their scan list directly from the allowed list when + we get updates to the allowed list from NetworkManagerInfo + + * src/NetworkManagerPolicy.h + - New member for failed access point in NMActivationResult + + ------------------------------------- + + Driver Notification patch: notifies the user when their driver + sucks. Gives them the option to ignore further insertions + of the card that has the sucky driver. + + * NetworkManager.h + - Remove the SEMI_SUPPORTED member from the NMDriverSupportLevel + enum and replace it with NO_CARRIER_DETECT and + NO_WIRELESS_SCAN + + * panel-applet/NMWirelessApplet.[ch] + - Merge essid.glade -> wireless-applet.glade + - Implement the "Your driver sucks" notification dialog + + * panel-applet/NMWirelessAppletDbus.c + - Change stuff from getSupportsCarrierDetect->getDriverSupportLevel + - Grab hardware address for each device from NM too + - Check whether the driver for each device sucks or not whenever + a new device is noticed + + * panel-applet/NMWirelessAppletOtherNetworkDialog.c + - Deal with stuff being in wireless-applet.glade now rather than essid.glade + + * src/NetworkManager.c + - Fix a double-unref on device removal + + * src/NetworkManagerUtils.c + - Set appropriate driver support level on a device that doesn't + support scanning or carrier detection + + * src/nm-dbus-device.c + - New "getHWAddress" dbus method on devices + - getSupportsCarrierDetect -> getDriverSupportLevel + 2005-03-31 Dan Williams * src/NetworkManagerDevice.c diff --git a/NetworkManager.h b/NetworkManager.h index 992849f91..06cdfc3cb 100644 --- a/NetworkManager.h +++ b/NetworkManager.h @@ -78,7 +78,8 @@ typedef enum NMEncKeyType typedef enum NMDriverSupportLevel { NM_DRIVER_UNSUPPORTED = 0, - NM_DRIVER_SEMI_SUPPORTED, + NM_DRIVER_NO_CARRIER_DETECT, + NM_DRIVER_NO_WIRELESS_SCAN, NM_DRIVER_FULLY_SUPPORTED } NMDriverSupportLevel; diff --git a/panel-applet/Makefile.am b/panel-applet/Makefile.am index 7e8958e0a..962c3073c 100644 --- a/panel-applet/Makefile.am +++ b/panel-applet/Makefile.am @@ -8,7 +8,7 @@ INCLUDES = -I${top_srcdir} -I${top_srcdir}/utils noinst_LTLIBRARIES = libnm_notification_applet.la gladedir = $(datadir)/NetworkManagerNotification -glade_DATA = essid.glade +glade_DATA = wireless-applet.glade libnm_notification_applet_la_CPPFLAGS = \ $(DBUS_CFLAGS) \ diff --git a/panel-applet/NMWirelessApplet.c b/panel-applet/NMWirelessApplet.c index 86447e01c..cd28cfde6 100644 --- a/panel-applet/NMWirelessApplet.c +++ b/panel-applet/NMWirelessApplet.c @@ -58,6 +58,7 @@ #include "menu-info.h" #define CFG_UPDATE_INTERVAL 1 +#define NMWA_GCONF_PATH "/apps/NetworkManagerNotification" /* Compat for GTK 2.4 and lower... */ #if (GTK_MAJOR_VERSION <= 2 && GTK_MINOR_VERSION < 6) @@ -175,6 +176,247 @@ void nmwa_about_cb (NMWirelessApplet *applet) #endif } +/* + * nmwa_driver_notify_get_ignored_list + * + * Return list of devices for which we are supposed to ignore driver + * notifications for from GConf. + * + */ +GSList *nmwa_driver_notify_get_ignored_list (NMWirelessApplet *applet) +{ + char *key; + GConfValue *value; + GSList *mac_list = NULL; + + g_return_val_if_fail (applet != NULL, NULL); + g_return_val_if_fail (applet->gconf_client != NULL, NULL); + + /* Get current list of access point MAC addresses for this AP from GConf */ + key = g_strdup_printf ("%s/non_notify_cards", NMWA_GCONF_PATH); + value = gconf_client_get (applet->gconf_client, key, NULL); + + if (value && (value->type == GCONF_VALUE_LIST) && (gconf_value_get_list_type (value) == GCONF_VALUE_STRING)) + mac_list = gconf_client_get_list (applet->gconf_client, key, GCONF_VALUE_STRING, NULL); + + if (value) + gconf_value_free (value); + g_free (key); + + return (mac_list); +} + + +/* + * nmwa_driver_notify_is_device_ignored + * + * Look in GConf and determine whether or not we are supposed to + * ignore driver notifications for a particular device. + * + */ +gboolean nmwa_driver_notify_is_device_ignored (NMWirelessApplet *applet, NetworkDevice *dev) +{ + gboolean found = FALSE; + GSList *mac_list = NULL; + GSList *elt; + + g_return_val_if_fail (applet != NULL, TRUE); + g_return_val_if_fail (applet->gconf_client != NULL, TRUE); + g_return_val_if_fail (dev != NULL, TRUE); + g_return_val_if_fail (dev->addr != NULL, TRUE); + g_return_val_if_fail (strlen (dev->addr) > 0, TRUE); + + mac_list = nmwa_driver_notify_get_ignored_list (applet); + + /* Ensure that the MAC isn't already in the list */ + for (elt = mac_list; elt; elt = g_slist_next (elt)) + { + if (elt->data && !strcmp (dev->addr, elt->data)) + { + found = TRUE; + break; + } + } + + /* Free the list, since gconf_client_set_list deep-copies it */ + g_slist_foreach (mac_list, (GFunc)g_free, NULL); + g_slist_free (mac_list); + + return found; +} + + +/* + * nmwa_driver_notify_ignore_device + * + * Add a device's MAC address to the list of ones that we ignore + * in GConf. Stores user's pref for "Don't remind me". + * + */ +void nmwa_driver_notify_ignore_device (NMWirelessApplet *applet, NetworkDevice *dev) +{ + gboolean found = FALSE; + GSList *new_mac_list = NULL; + GSList *elt; + + g_return_if_fail (applet != NULL); + g_return_if_fail (applet->gconf_client != NULL); + g_return_if_fail (dev != NULL); + g_return_if_fail (dev->addr != NULL); + g_return_if_fail (strlen (dev->addr) > 0); + + new_mac_list = nmwa_driver_notify_get_ignored_list (applet); + + /* Ensure that the MAC isn't already in the list */ + for (elt = new_mac_list; elt; elt = g_slist_next (elt)) + { + if (elt->data && !strcmp (dev->addr, elt->data)) + { + found = TRUE; + break; + } + } + + /* Add the new MAC address to the end of the list */ + if (!found) + { + char *key = g_strdup_printf ("%s/non_notify_cards", NMWA_GCONF_PATH); + + new_mac_list = g_slist_append (new_mac_list, g_strdup (dev->addr)); + gconf_client_set_list (applet->gconf_client, key, GCONF_VALUE_STRING, new_mac_list, NULL); + g_free (key); + } + + /* Free the list, since gconf_client_set_list deep-copies it */ + g_slist_foreach (new_mac_list, (GFunc)g_free, NULL); + g_slist_free (new_mac_list); +} + +gboolean nmwa_driver_notify_dialog_delete_cb (GtkWidget *widget, GdkEvent *event, gpointer user_data) +{ + gtk_widget_destroy (widget); + return FALSE; +} + +gboolean nmwa_driver_notify_dialog_destroy_cb (GtkWidget *widget, GdkEvent *event, gpointer user_data) +{ + DriverNotifyCBData *cb_data = (DriverNotifyCBData *)(user_data); + NetworkDevice *dev; + + g_return_val_if_fail (cb_data != NULL, FALSE); + g_return_val_if_fail (cb_data->xml != NULL, FALSE); + + dev = cb_data->dev; + g_return_val_if_fail (dev != NULL, FALSE); + + network_device_unref (dev); + + g_object_unref (cb_data->xml); + g_free (cb_data); + + return FALSE; +} + + +gboolean nmwa_driver_notify_ok_cb (GtkButton *button, gpointer user_data) +{ + DriverNotifyCBData *cb_data = (DriverNotifyCBData *)(user_data); + NetworkDevice *dev; + NMWirelessApplet *applet; + GtkWidget *dialog; + GtkWidget *checkbox; + + g_return_val_if_fail (cb_data != NULL, FALSE); + g_return_val_if_fail (cb_data->xml != NULL, FALSE); + + dev = cb_data->dev; + g_return_val_if_fail (dev != NULL, FALSE); + + applet = cb_data->applet; + g_return_val_if_fail (applet != NULL, FALSE); + + checkbox = glade_xml_get_widget (cb_data->xml, "dont_remind_checkbox"); + if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbox))) + nmwa_driver_notify_ignore_device (applet, dev); + + dialog = glade_xml_get_widget (cb_data->xml, "driver_sucks_dialog"); + gtk_widget_destroy (dialog); + + return FALSE; +} + + +/* + * nmwa_driver_notify + * + * Notify the user if there's some problem with the driver + * of a specific network device. + * + */ +gboolean nmwa_driver_notify (gpointer user_data) +{ + DriverNotifyCBData *cb_data = (DriverNotifyCBData *)(user_data); + NetworkDevice *dev; + NMWirelessApplet *applet; + GtkDialog *dialog; + GtkLabel *label; + char *label_text = NULL; + GtkButton *button; + + g_return_val_if_fail (cb_data != NULL, FALSE); + + dev = cb_data->dev; + g_return_val_if_fail (dev != NULL, FALSE); + + applet = cb_data->applet; + g_return_val_if_fail (applet != NULL, FALSE); + g_return_val_if_fail (applet->glade_file != NULL, FALSE); + + /* If the user has already requested that we ignore notifications for + * this device, don't do anything. + */ + if (nmwa_driver_notify_is_device_ignored (applet, dev)) + return FALSE; + + cb_data->xml = glade_xml_new (applet->glade_file, "driver_sucks_dialog", NULL); + if (cb_data->xml == NULL) + { + show_warning_dialog (TRUE, _("The NetworkManager Applet could not find some required resources (the glade file was not found).")); + return FALSE; + } + + dialog = GTK_DIALOG (glade_xml_get_widget (cb_data->xml, "driver_sucks_dialog")); + g_signal_connect (G_OBJECT (dialog), "destroy-event", GTK_SIGNAL_FUNC (nmwa_driver_notify_dialog_destroy_cb), cb_data); + g_signal_connect (G_OBJECT (dialog), "delete-event", GTK_SIGNAL_FUNC (nmwa_driver_notify_dialog_delete_cb), cb_data); + + label = GTK_LABEL (glade_xml_get_widget (cb_data->xml, "driver_sucks_label")); + if (dev->driver_support_level == NM_DRIVER_NO_WIRELESS_SCAN) + { + char *temp = g_strdup_printf (_("The network device \"%s (%s)\" does not support wireless scanning."), + dev->hal_name, dev->nm_name); + + label_text = g_strdup_printf (gtk_label_get_label (label), temp); + g_free (temp); + } + if (dev->driver_support_level == NM_DRIVER_NO_CARRIER_DETECT) + { + char *temp = g_strdup_printf (_("The network device \"%s (%s)\" does not support link detection."), + dev->hal_name, dev->nm_name); + + label_text = g_strdup_printf (gtk_label_get_label (label), temp); + g_free (temp); + } + if (label_text) + gtk_label_set_markup (label, label_text); + + button = GTK_BUTTON (glade_xml_get_widget (cb_data->xml, "ok_button")); + g_signal_connect (G_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (nmwa_driver_notify_ok_cb), cb_data); + + gtk_widget_show_all (GTK_WIDGET (dialog)); + + return (FALSE); +} + /* * nmwa_update_network_state @@ -1274,6 +1516,14 @@ static void nmwa_setup_widgets (NMWirelessApplet *applet) applet->context_menu = nmwa_context_menu_create (applet); applet->encryption_size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); + + applet->glade_file = g_build_filename (GLADEDIR, "wireless-applet.glade", NULL); + if (!applet->glade_file || !g_file_test (applet->glade_file, G_FILE_TEST_IS_REGULAR)) + { + show_warning_dialog (TRUE, _("The NetworkManager Applet could not find some required resources (the glade file was not found).")); + g_free (applet->glade_file); + applet->glade_file = NULL; + } } @@ -1307,6 +1557,8 @@ static void nmwa_destroy (NMWirelessApplet *applet, gpointer user_data) nmwa_free_gui_data_model (applet); nmwa_free_dbus_data_model (applet); + + g_free (applet->glade_file); } diff --git a/panel-applet/NMWirelessApplet.h b/panel-applet/NMWirelessApplet.h index 00382c3c2..d6d2cdd21 100644 --- a/panel-applet/NMWirelessApplet.h +++ b/panel-applet/NMWirelessApplet.h @@ -32,6 +32,7 @@ #else #include "eggtrayicon.h" #endif +#include typedef enum { @@ -70,7 +71,8 @@ typedef struct char *nm_device; int type; gboolean link; - gboolean supports_carrier_detect; + guint32 driver_support_level; + char *addr; char *nm_name; char *hal_name; char *udi; @@ -78,8 +80,6 @@ typedef struct GSList *networks; } NetworkDevice; - - #ifdef BUILD_NOTIFICATION_ICON #define NM_TYPE_WIRELESS_APPLET (nmwa_get_type()) @@ -107,8 +107,10 @@ typedef struct DBusConnection *connection; GConfClient *gconf_client; - GladeXML *ui_resources; + char *glade_file; guint redraw_timeout_id; + + /* dbus thread stuff */ GThread *dbus_thread; GMainContext *thread_context; GMainLoop *thread_loop; @@ -163,11 +165,18 @@ typedef struct } NMWirelessApplet; +typedef struct +{ + NMWirelessApplet *applet; + NetworkDevice *dev; + GladeXML *xml; +} DriverNotifyCBData; 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, ...); +gboolean nmwa_driver_notify (gpointer user_data); #endif diff --git a/panel-applet/NMWirelessAppletDbus.c b/panel-applet/NMWirelessAppletDbus.c index ff39aaba4..ac3bd139a 100644 --- a/panel-applet/NMWirelessAppletDbus.c +++ b/panel-applet/NMWirelessAppletDbus.c @@ -34,6 +34,24 @@ #define DBUS_NO_SERVICE_ERROR "org.freedesktop.DBus.Error.ServiceDoesNotExist" +/* + * nm_null_safe_strcmp + * + * Doesn't freaking segfault if s1/s2 are NULL + * + */ +int nm_null_safe_strcmp (const char *s1, const char *s2) +{ + if (!s1 && !s2) + return 0; + if (!s1 && s2) + return -1; + if (s1 && !s2) + return 1; + + return (strcmp (s1, s2)); +} + /* FIXME: This just seems like a bad idea. The call_nm_method function * interface should just be changed to handle arrays better. @@ -302,7 +320,7 @@ static gboolean nmwa_dbus_get_device_link_active (NMWirelessApplet *applet, char break; default: - break; + break; } return (link); @@ -310,17 +328,17 @@ static gboolean nmwa_dbus_get_device_link_active (NMWirelessApplet *applet, char /* - * nmwa_dbus_get_device_supports_carrier_detect + * nmwa_dbus_get_device_driver_support_level * * Returns whether or not the device supports carrier detection. * */ -static gboolean nmwa_dbus_get_device_supports_carrier_detect (NMWirelessApplet *applet, char *net_path) +static gboolean nmwa_dbus_get_device_driver_support_level (NMWirelessApplet *applet, char *net_path) { - gboolean supports_carrier_detect = FALSE; + guint32 driver_support_level = FALSE; - switch (nmwa_dbus_call_nm_method (applet->connection, net_path, "getSupportsCarrierDetect", - DBUS_TYPE_BOOLEAN, (void **)(&supports_carrier_detect), NULL)) + switch (nmwa_dbus_call_nm_method (applet->connection, net_path, "getDriverSupportLevel", + DBUS_TYPE_UINT32, (void **)(&driver_support_level), NULL)) { case (RETURN_NO_NM): applet->applet_state = APPLET_STATE_NO_NM; @@ -330,7 +348,31 @@ static gboolean nmwa_dbus_get_device_supports_carrier_detect (NMWirelessApplet * break; } - return (supports_carrier_detect); + return (driver_support_level); +} + + +/* + * nmwa_dbus_get_hw_addr + * + * Return the hardware address of a given device + * + */ +static char * nmwa_dbus_get_hw_addr (NMWirelessApplet *applet, char *dev_path) +{ + char *addr = NULL; + + switch (nmwa_dbus_call_nm_method (applet->connection, dev_path, "getHWAddress", DBUS_TYPE_STRING, (void **)(&addr), NULL)) + { + case (RETURN_NO_NM): + applet->applet_state = APPLET_STATE_NO_NM; + break; + + default: + break; + } + + return (addr); } @@ -953,6 +995,7 @@ void network_device_unref (NetworkDevice *dev) g_free (dev->nm_name); g_free (dev->udi); g_free (dev->hal_name); + g_free (dev->addr); g_free (dev); memset (dev, 0, sizeof (NetworkDevice)); } @@ -998,7 +1041,8 @@ NetworkDevice *network_device_copy (NetworkDevice *src) 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->addr = g_strdup (src->addr); + dev->driver_support_level = src->driver_support_level; dev->nm_name = g_strdup (src->nm_name); dev->hal_name = g_strdup (src->hal_name); dev->udi = g_strdup (src->udi); @@ -1231,6 +1275,10 @@ 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->applet_state == APPLET_STATE_NO_NM) + return TRUE; + 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); @@ -1354,6 +1402,73 @@ static void nmwa_dbus_device_update_one_network (NMWirelessApplet *applet, DBusM } +/* + * nmwa_dbus_schedule_driver_notification + * + * Schedule the driver notification routine to run in the main loop. + * + */ +void nmwa_dbus_schedule_driver_notification (NMWirelessApplet *applet, NetworkDevice *dev) +{ + DriverNotifyCBData *cb_data; + + g_return_if_fail (applet != NULL); + g_return_if_fail (dev != NULL); + + cb_data = g_malloc0 (sizeof (DriverNotifyCBData)); + cb_data->applet = applet; + cb_data->dev = dev; + + g_idle_add (nmwa_driver_notify, (gpointer)cb_data); +} + + +/* + * nmwa_dbus_check_drivers + * + * If a device got added, we notify the user if the device's driver + * has any problems (no carrier detect, no wireless scanning, etc). + * + */ +void nmwa_dbus_check_drivers (NMWirelessApplet *applet) +{ + GSList *elt; + + g_return_if_fail (applet != NULL); + + /* For every device that's in the dbus data model but not in + * the gui data model, signal the user. + */ + for (elt = applet->dbus_device_list; elt; elt = g_slist_next (elt)) + { + NetworkDevice *dbus_dev = (NetworkDevice *)(elt->data); + GSList *elt2; + gboolean found = FALSE; + + for (elt2 = applet->gui_device_list; elt2; elt2 = g_slist_next (elt2)) + { + NetworkDevice *gui_dev = (NetworkDevice *)(elt2->data); + + if ( !nm_null_safe_strcmp (dbus_dev->nm_device, gui_dev->nm_device) + && !nm_null_safe_strcmp (dbus_dev->addr, gui_dev->addr) + && !nm_null_safe_strcmp (dbus_dev->udi, gui_dev->udi)) + { + found = TRUE; + break; + } + } + + if ( !found + && ( (dbus_dev->driver_support_level == NM_DRIVER_NO_CARRIER_DETECT) + || (dbus_dev->driver_support_level == NM_DRIVER_NO_WIRELESS_SCAN))) + { + network_device_ref (dbus_dev); + nmwa_dbus_schedule_driver_notification (applet, dbus_dev); + } + } +} + + /* * sort_devices_function * @@ -1454,8 +1569,8 @@ static void nmwa_dbus_update_devices (NMWirelessApplet *applet) { dev->nm_device = g_strdup (devices[i]); dev->type = nmwa_dbus_get_device_type (applet, devices[i], APPLET_STATE_NO_CONNECTION); - if (dev->type == DEVICE_TYPE_WIRED_ETHERNET) - dev->supports_carrier_detect = nmwa_dbus_get_device_supports_carrier_detect (applet, devices[i]); + dev->driver_support_level = nmwa_dbus_get_device_driver_support_level (applet, devices[i]); + dev->addr = nmwa_dbus_get_hw_addr (applet, devices[i]); dev->link = nmwa_dbus_get_device_link_active (applet, devices[i]); dev->nm_name = g_strdup (name); dev->udi = nmwa_dbus_get_device_udi (applet, devices[i]); @@ -1487,6 +1602,9 @@ static void nmwa_dbus_update_devices (NMWirelessApplet *applet) /* Sort the devices for display */ applet->dbus_device_list = g_slist_sort (applet->dbus_device_list, sort_devices_function); + /* Notify user of issues with certain cards/drivers */ + nmwa_dbus_check_drivers (applet); + /* Now copy the data over to the GUI side */ g_mutex_lock (applet->data_mutex); diff --git a/panel-applet/NMWirelessAppletOtherNetworkDialog.c b/panel-applet/NMWirelessAppletOtherNetworkDialog.c index a6ebea9ed..3b440c57e 100644 --- a/panel-applet/NMWirelessAppletOtherNetworkDialog.c +++ b/panel-applet/NMWirelessAppletOtherNetworkDialog.c @@ -215,6 +215,9 @@ static GtkDialog *nmwa_other_network_dialog_init (GladeXML *xml, NMWirelessApple /* Set up the dialog */ dialog = GTK_DIALOG (glade_xml_get_widget (xml, "custom_essid_dialog")); + if (!dialog) + return NULL; + essid_entry = glade_xml_get_widget (xml, "essid_entry"); button = glade_xml_get_widget (xml, "ok_button"); @@ -302,26 +305,17 @@ static GtkDialog *nmwa_other_network_dialog_init (GladeXML *xml, NMWirelessApple void nmwa_other_network_dialog_run (NMWirelessApplet *applet, gboolean create_network) { gchar *glade_file; - GtkDialog *dialog; - GladeXML *xml; - gint response; + GtkDialog *dialog; + gint response; NetworkDevice *def_dev = NULL; + GladeXML *xml; g_return_if_fail (applet != NULL); + g_return_if_fail (applet->glade_file != NULL); - glade_file = g_build_filename (GLADEDIR, "essid.glade", NULL); - - if (!glade_file || !g_file_test (glade_file, G_FILE_TEST_IS_REGULAR)) - { - show_warning_dialog (TRUE, _("The NetworkManager Applet could not find some required resources (the glade file was not found).")); - return; - } - - xml = glade_xml_new (glade_file, NULL, NULL); - g_free (glade_file); + xml = glade_xml_new (applet->glade_file, NULL, NULL); if (xml == NULL) { - /* Reuse the above string to make the translators less angry. */ show_warning_dialog (TRUE, _("The NetworkManager Applet could not find some required resources (the glade file was not found).")); return; } diff --git a/panel-applet/menu-info.c b/panel-applet/menu-info.c index 81229b176..65f593451 100644 --- a/panel-applet/menu-info.c +++ b/panel-applet/menu-info.c @@ -97,7 +97,7 @@ void wired_menu_item_update (NMWiredMenuItem *item, NetworkDevice *dev, const gi /* Only dim the item if the device supports carrier detection AND * we know it doesn't have a link. */ - if (dev->supports_carrier_detect == TRUE) + if (dev->driver_support_level != NM_DRIVER_NO_CARRIER_DETECT) gtk_widget_set_sensitive (GTK_WIDGET (item->check_item), dev->link); } diff --git a/panel-applet/wireless-applet.glade b/panel-applet/wireless-applet.glade index 43dbdead3..f06f48204 100644 --- a/panel-applet/wireless-applet.glade +++ b/panel-applet/wireless-applet.glade @@ -153,4 +153,518 @@ You have chosen log in to the wireless network '%s'. If you are sure this wirel + + 6 + + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_CENTER_ALWAYS + True + True + False + True + False + False + GDK_WINDOW_TYPE_HINT_DIALOG + GDK_GRAVITY_NORTH_WEST + False + + + + True + False + 12 + + + + True + GTK_BUTTONBOX_END + + + + True + True + True + True + _OK + True + GTK_RELIEF_NORMAL + True + -5 + + + + + 0 + False + True + GTK_PACK_END + + + + + + 6 + True + False + 12 + + + + True + gtk-dialog-warning + 6 + 0.5 + 0 + 0 + 0 + + + 0 + False + True + + + + + + True + False + 12 + + + + True + <span weight="bold" size="larger">Reduced Network Functionality</span> + +%s It will not be completely functional. + False + True + GTK_JUSTIFY_LEFT + True + False + 0 + 0.5 + 0 + 0 + + + 0 + False + False + + + + + + True + True + Don't remind me again + True + GTK_RELIEF_NORMAL + True + False + False + True + + + 0 + False + False + + + + + 0 + True + True + + + + + 0 + True + True + + + + + + + + 6 + True + + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_NONE + False + 488 + False + False + True + False + False + GDK_WINDOW_TYPE_HINT_DIALOG + GDK_GRAVITY_NORTH_WEST + False + + + + True + False + 4 + + + + True + GTK_BUTTONBOX_END + + + + True + True + True + gtk-cancel + True + GTK_RELIEF_NORMAL + True + -6 + + + + + + True + True + True + True + C_onnect + True + GTK_RELIEF_NORMAL + True + -5 + + + + + 0 + False + True + GTK_PACK_END + + + + + + 6 + True + False + 12 + + + + True + gtk-dialog-question + 6 + 0.5 + 0 + 0 + 0 + + + 0 + False + True + + + + + + True + False + 12 + + + + True + + False + True + GTK_JUSTIFY_LEFT + True + False + 0 + 0.5 + 0 + 0 + + + 0 + True + True + + + + + + True + 3 + 2 + False + 12 + 6 + + + + True + Wireless _adapter: + True + False + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + wireless_adapter_combo + + + 0 + 1 + 0 + 1 + fill + + + + + + + True + + + + 1 + 2 + 0 + 1 + fill + fill + + + + + + True + Wireless _network: + True + False + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + essid_entry + + + 0 + 1 + 1 + 2 + fill + + + + + + + True + True + True + True + 0 + + True + * + True + + + 1 + 2 + 1 + 2 + + + + + + + True + 0 + 0.5 + GTK_SHADOW_ETCHED_IN + + + + True + 0.5 + 0.5 + 1 + 1 + 3 + 6 + 6 + 6 + + + + True + 2 + 3 + False + 12 + 6 + + + + True + Key type: + False + False + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + + + 0 + 1 + 0 + 1 + fill + + + + + + + True + Passphrase: + False + False + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + + + 0 + 1 + 1 + 2 + fill + + + + + + + True + True + True + True + 0 + + True + * + False + + + 1 + 3 + 1 + 2 + + + + + + + True + 128-bit passphrase (WEP) +Ascii key (WEP) +Hex key (WEP) + + + 1 + 2 + 0 + 1 + fill + fill + + + + + + + + + + True + True + Connect with encryption enabled + True + GTK_RELIEF_NORMAL + True + False + False + True + + + label_item + + + + + 0 + 2 + 2 + 3 + fill + + + + + 0 + True + True + + + + + 0 + True + True + + + + + 0 + True + True + + + + + + diff --git a/src/NetworkManager.c b/src/NetworkManager.c index cd1812b0a..045d1ca20 100644 --- a/src/NetworkManager.c +++ b/src/NetworkManager.c @@ -184,14 +184,13 @@ void nm_remove_device_from_list (NMData *data, const char *udi) nm_device_set_removed (dev, TRUE); nm_device_deactivate (dev, FALSE); nm_device_worker_thread_stop (dev); + nm_dbus_signal_device_status_change (data->dbus_connection, dev, DEVICE_LIST_CHANGE); nm_device_unref (dev); /* Remove the device entry from the device list and free its data */ data->dev_list = g_slist_remove_link (data->dev_list, elt); - nm_device_unref (elt->data); g_slist_free (elt); nm_policy_schedule_state_update (data); - nm_dbus_signal_device_status_change (data->dbus_connection, dev, DEVICE_LIST_CHANGE); break; } } @@ -407,9 +406,19 @@ gboolean nm_poll_and_update_wireless_link_state (NMData *data) * an active link. If it lost the link, * find a better access point. */ - if ((dev == data->active_device) && - !nm_device_has_active_link (dev)) - nm_device_update_best_ap (dev); + if ( (dev == data->active_device) + && !nm_device_has_active_link (dev)) + { + if (nm_device_get_supports_wireless_scan (dev)) + nm_device_update_best_ap (dev); + else + { + if ( !nm_device_is_activating (dev) + && !data->forcing_device + && data->state_modified_idle_id == 0) + nm_device_update_best_ap (dev); + } + } } } nm_unlock_mutex (data->dev_list_mutex, __FUNCTION__); diff --git a/src/NetworkManagerDevice.c b/src/NetworkManagerDevice.c index 61ecdb76c..54c419413 100644 --- a/src/NetworkManagerDevice.c +++ b/src/NetworkManagerDevice.c @@ -193,6 +193,50 @@ NMDevice *nm_get_device_by_iface (NMData *data, const char *iface) /* NMDevice object routines */ /*****************************************************************************/ + +/* + * nm_device_copy_allowed_to_dev_list + * + * For devices that don't support wireless scanning, copy + * the allowed AP list to the device's ap list. + * + */ +void nm_device_copy_allowed_to_dev_list (NMDevice *dev, NMAccessPointList *allowed_list) +{ + NMAPListIter *iter; + NMAccessPoint *src_ap; + NMAccessPointList *dev_list; + + g_return_if_fail (dev != NULL); + + if (allowed_list == NULL) + return; + + nm_device_ap_list_clear (dev); + dev->options.wireless.ap_list = nm_ap_list_new (NETWORK_TYPE_ALLOWED); + + if (!(iter = nm_ap_list_iter_new (allowed_list))) + return; + + dev_list = nm_device_ap_list_get (dev); + while ((src_ap = nm_ap_list_iter_next (iter))) + { + NMAccessPoint *dst_ap = nm_ap_new_from_ap (src_ap); + + /* Assume that if the allowed list AP has a saved encryption + * key that the AP is encrypted. + */ + if ( (nm_ap_get_auth_method (src_ap) == NM_DEVICE_AUTH_METHOD_OPEN_SYSTEM) + || (nm_ap_get_auth_method (src_ap) == NM_DEVICE_AUTH_METHOD_SHARED_KEY)) + nm_ap_set_encrypted (dst_ap, TRUE); + + nm_ap_list_append_ap (dev_list, dst_ap); + nm_ap_unref (dst_ap); + } + nm_ap_list_iter_free (iter); +} + + /* * nm_device_new * @@ -279,6 +323,12 @@ NMDevice *nm_device_new (const char *iface, const char *udi, gboolean test_dev, opts->supports_wireless_scan = nm_device_supports_wireless_scan (dev); + /* Non-scanning devices show the entire allowed AP list as their + * available networks. + */ + if (opts->supports_wireless_scan == FALSE) + nm_device_copy_allowed_to_dev_list (dev, app_data->allowed_ap_list); + if ((sk = iw_sockets_open ()) >= 0) { iwrange range; @@ -309,6 +359,9 @@ NMDevice *nm_device_new (const char *iface, const char *udi, gboolean test_dev, dev->options.wired.has_carrier_detect = TRUE; } + /* Must be called after carrier detect or wireless scan detect. */ + dev->driver_support_level = nm_get_driver_support_level (dev->app_data->hal_ctx, dev); + if (nm_device_get_driver_support_level (dev) != NM_DRIVER_UNSUPPORTED) { if (nm_device_is_wireless (dev)) @@ -423,8 +476,8 @@ static gpointer nm_device_worker (gpointer user_data) exit (1); } - /* Do an initial wireless scan */ - if (nm_device_is_wireless (dev)) + /* Start the scanning timeout for devices that can do scanning */ + if (nm_device_is_wireless (dev) && nm_device_get_supports_wireless_scan (dev)) { GSource *source = g_idle_source_new (); guint source_id = 0; @@ -1427,11 +1480,12 @@ void nm_device_get_ip6_address(NMDevice *dev) * Get a device's hardware address * */ -void nm_device_get_hw_address(NMDevice *dev, unsigned char hw_addr[ETH_ALEN]) +void nm_device_get_hw_address(NMDevice *dev, unsigned char *eth_addr) { + g_return_if_fail (eth_addr != NULL); g_return_if_fail (dev != NULL); - memcpy (hw_addr, dev->hw_addr, ETH_ALEN); + memcpy (eth_addr, dev->hw_addr, ETH_ALEN); } void nm_device_update_hw_address (NMDevice *dev) @@ -1461,7 +1515,7 @@ void nm_device_update_hw_address (NMDevice *dev) if (err != 0) return; - memcpy (dev->hw_addr, req.ifr_hwaddr.sa_data, ETH_ALEN); + memcpy (dev->hw_addr, req.ifr_hwaddr.sa_data, ETH_ALEN); } @@ -1592,7 +1646,7 @@ gboolean nm_device_bring_up_wait (NMDevice *dev, gboolean cancelable) nm_completion_device_is_up_test, dev, &err, cancelable); if (err) - syslog (LOG_INFO, "failed to bring device up"); + nm_info ("failed to bring device up"); return err; } @@ -1633,7 +1687,7 @@ gboolean nm_device_bring_down_wait (NMDevice *dev, gboolean cancelable) nm_completion_device_is_down_test, dev, &err, cancelable); if (err) - syslog (LOG_INFO, "failed to bring device down"); + nm_info ("failed to bring device down"); return err; } @@ -1747,7 +1801,7 @@ gboolean nm_device_set_mode (NMDevice *dev, const NMNetworkMode mode) * Schedule an idle routine in the main thread to finish the activation. * */ -void nm_device_activation_schedule_finish (NMDevice *dev, DeviceStatus activation_result) +void nm_device_activation_schedule_finish (NMDevice *dev, NMAccessPoint *failed_ap, DeviceStatus activation_result) { GSource *source = NULL; NMActivationResult *result = NULL; @@ -1758,6 +1812,7 @@ void nm_device_activation_schedule_finish (NMDevice *dev, DeviceStatus activatio result = g_malloc0 (sizeof (NMActivationResult)); nm_device_ref (dev); /* Ref device for idle handler */ result->dev = dev; + result->failed_ap = failed_ap; result->result = activation_result; source = g_idle_source_new (); @@ -2435,6 +2490,12 @@ try_connect: nm_device_get_iface (dev), nm_ap_get_essid (best_ap) ? nm_ap_get_essid (best_ap) : "(none)"); } + /* Don't try other APs for non-scanning devices. + * User must pick a new one manually. + */ + if (!nm_device_get_supports_wireless_scan (dev)) + goto out; + /* All applicable modes failed, invalidate current best_ap and get a new one */ invalidate_ap (dev, best_ap); goto get_ap; @@ -2481,6 +2542,12 @@ try_connect: } else { + /* Don't try other APs for non-scanning devices. + * User must pick a new one manually. + */ + if (!nm_device_get_supports_wireless_scan (dev)) + goto out; + /* All applicable modes failed, invalidate current best_ap and get a new one */ invalidate_ap (dev, best_ap); goto get_ap; @@ -2578,6 +2645,7 @@ static gboolean nm_device_activate (gpointer user_data) NMDevice *dev = (NMDevice *)user_data; gboolean success = FALSE; gboolean finished = FALSE; + NMAccessPoint *failed_best_ap = NULL; g_return_val_if_fail (dev != NULL, FALSE); g_return_val_if_fail (dev->app_data != NULL, FALSE); @@ -2625,10 +2693,15 @@ static gboolean nm_device_activate (gpointer user_data) out: nm_info ("Activation (%s) ended.", nm_device_get_iface (dev)); + if (finished) + { + if (nm_device_is_wireless (dev) && !success) + failed_best_ap = nm_device_get_best_ap (dev); + } dev->activating = FALSE; dev->quit_activation = FALSE; if (finished) - nm_device_activation_schedule_finish (dev, success ? DEVICE_NOW_ACTIVE : DEVICE_ACTIVATION_FAILED); + nm_device_activation_schedule_finish (dev, failed_best_ap, success ? DEVICE_NOW_ACTIVE : DEVICE_ACTIVATION_FAILED); return FALSE; } @@ -3084,6 +3157,22 @@ void nm_device_update_best_ap (NMDevice *dev) g_return_if_fail (dev->app_data != NULL); g_return_if_fail (nm_device_is_wireless (dev)); + /* Devices that can't scan don't do anything automatic. + * The user must choose the access point from the menu. + */ + if (!nm_device_get_supports_wireless_scan (dev)) + { + /* If we lost a link to the AP, clear it out. + * + * FIXME: take samples over 5 seconds or so of the + * whether or not the link is active and only blow away + * the best_ap if its been down for 5 seconds or more. + */ + if (!nm_device_has_active_link (dev)) + nm_device_set_best_ap (dev, NULL); + return; + } + if (!(ap_list = nm_device_ap_list_get (dev))) return; @@ -3293,86 +3382,6 @@ void nm_device_schedule_force_use (NMDevice *dev, const char *network, const cha } -/* - * nm_device_do_pseudo_scan - * - * Brute-force the allowed access point list to find one that works, if any. - * - * FIXME - * There's probably a better way to do the non-scanning access point discovery - * than brute forcing it like this, but that makes the state machine here oh so - * much more complicated. - */ -static void nm_device_do_pseudo_scan (NMDevice *dev) -{ - NMAPListIter *iter; - NMAccessPoint *ap; - - g_return_if_fail (dev != NULL); - g_return_if_fail (dev->app_data != NULL); - - /* Test devices shouldn't get here since we fake the AP list earlier */ - g_return_if_fail (!dev->test_device); - - nm_device_ref (dev); - - if (!(iter = nm_ap_list_iter_new (dev->app_data->allowed_ap_list))) - return; - - nm_device_set_essid (dev, ""); - while ((ap = nm_ap_list_iter_next (iter))) - { - gboolean valid = FALSE; - struct ether_addr save_ap_addr; - struct ether_addr cur_ap_addr; - - if (!nm_device_is_up (dev)); - nm_device_bring_up (dev); - - /* Save the MAC address */ - nm_device_get_ap_address (dev, &save_ap_addr); - - if (nm_ap_get_enc_key_source (ap)) - { - char *hashed_key = nm_ap_get_enc_key_hashed (ap); - nm_device_set_enc_key (dev, hashed_key, NM_DEVICE_AUTH_METHOD_SHARED_KEY); - g_free (hashed_key); - } - else - nm_device_set_enc_key (dev, NULL, NM_DEVICE_AUTH_METHOD_NONE); - nm_device_set_essid (dev, nm_ap_get_essid (ap)); - - /* Wait a bit for association */ - nm_device_is_up_and_associated_wait (dev, 2, 100); - - /* Do we have a valid MAC address? */ - nm_device_get_ap_address (dev, &cur_ap_addr); - valid = nm_ethernet_address_is_valid (&cur_ap_addr); - - /* If the ap address we had before, and the ap address we - * have now, are the same, AP is invalid. Certain cards (orinoco) - * will let the essid change, but the the card won't actually de-associate - * from the previous access point if it can't associate with the new one - * (ie signal too weak, etc). - */ - if (valid && (memcmp (&save_ap_addr, &cur_ap_addr, sizeof (struct ether_addr)) == 0)) - valid = FALSE; - - if (valid) - { - nm_info ("%s: setting AP '%s' best", nm_device_get_iface (dev), nm_ap_get_essid (ap)); - - nm_device_set_best_ap (dev, ap); - nm_policy_schedule_state_update (dev->app_data); - break; - } - } - - nm_ap_list_iter_free (iter); - nm_device_unref (dev); -} - - /* * nm_device_fake_ap_list * @@ -3476,26 +3485,9 @@ static gboolean nm_device_wireless_process_scan_results (gpointer user_data) g_return_val_if_fail (results != NULL, FALSE); dev = results->dev; - if (!dev || !results->scan_head.result) return FALSE; - /* Test devices get their info faked */ - if (dev->test_device) - { - nm_device_fake_ap_list (dev); - return FALSE; - } - - /* Devices that don't support scanning have their pseudo-scanning done in - * the main thread anyway. - */ - if (!nm_device_get_supports_wireless_scan (dev)) - { - nm_device_do_pseudo_scan (dev); - return FALSE; - } - g_get_current_time (&cur_time); /* Translate iwlib scan results to NM access point list */ @@ -3704,10 +3696,6 @@ static gboolean nm_device_wireless_scan (gpointer user_data) g_return_val_if_fail (dev != NULL, FALSE); g_return_val_if_fail (dev->app_data != NULL, FALSE); - /* We don't scan on test devices or devices that don't have scanning support */ - if (dev->test_device || !nm_device_get_supports_wireless_scan (dev)) - return FALSE; - /* Just reschedule ourselves if scanning or all wireless is disabled */ if ( (dev->app_data->scanning_enabled == FALSE) || (dev->app_data->wireless_enabled == FALSE) @@ -3717,6 +3705,14 @@ static gboolean nm_device_wireless_scan (gpointer user_data) goto reschedule; } + /* Test devices get a fake ap list */ + if (dev->test_device) + { + nm_device_fake_ap_list (dev); + dev->options.wireless.scan_interval = 20; + goto reschedule; + } + /* Grab the scan mutex */ if (nm_try_acquire_mutex (dev->options.wireless.scan_mutex, __FUNCTION__)) { diff --git a/src/NetworkManagerDevice.h b/src/NetworkManagerDevice.h index 9058abf35..820755f7a 100644 --- a/src/NetworkManagerDevice.h +++ b/src/NetworkManagerDevice.h @@ -70,7 +70,7 @@ NMNetworkMode nm_device_get_mode (NMDevice *dev); guint32 nm_device_get_ip4_address (NMDevice *dev); void nm_device_update_ip4_address (NMDevice *dev); -void nm_device_get_hw_address (NMDevice *dev, unsigned char hw_addr[ETH_ALEN]); +void nm_device_get_hw_address (NMDevice *dev, unsigned char *eth_addr); void nm_device_update_hw_address (NMDevice *dev); void nm_device_get_ip6_address (NMDevice *dev); @@ -121,6 +121,7 @@ void nm_device_ap_list_clear (NMDevice *dev); struct NMAccessPointList *nm_device_ap_list_get (NMDevice *dev); NMAccessPoint *nm_device_ap_list_get_ap_by_essid (NMDevice *dev, const char *essid); NMAccessPoint *nm_device_ap_list_get_ap_by_address(NMDevice *dev, const struct ether_addr *addr); +void nm_device_copy_allowed_to_dev_list (NMDevice *dev, struct NMAccessPointList *allowed_list); /* System config data accessors */ gboolean nm_device_config_get_use_dhcp (NMDevice *dev); diff --git a/src/NetworkManagerPolicy.c b/src/NetworkManagerPolicy.c index 7a59d754d..7fa21ade3 100644 --- a/src/NetworkManagerPolicy.c +++ b/src/NetworkManagerPolicy.c @@ -234,6 +234,7 @@ gboolean nm_policy_activation_finish (gpointer user_data) { NMActivationResult *result = (NMActivationResult *)user_data; NMDevice *dev = NULL; + NMAccessPoint *failed_ap = NULL; NMData *data = NULL; g_return_val_if_fail (result != NULL, FALSE); @@ -241,6 +242,8 @@ gboolean nm_policy_activation_finish (gpointer user_data) if (!(dev = result->dev)) goto out; + failed_ap = result->failed_ap; + if (!(data = nm_device_get_app_data (dev))) goto out; @@ -275,22 +278,29 @@ gboolean nm_policy_activation_finish (gpointer user_data) nm_dbus_signal_device_status_change (data->dbus_connection, dev, result->result); if (nm_device_is_wireless (dev)) { - NMAccessPoint *ap = nm_device_get_best_ap (dev); - if (ap) + if (failed_ap) { /* Add the AP to the invalid list and force a best ap update */ - nm_ap_list_append_ap (data->invalid_ap_list, ap); + nm_ap_list_append_ap (data->invalid_ap_list, failed_ap); nm_device_update_best_ap (dev); - - /* Unref because nm_device_get_best_ap() refs it before returning. */ - nm_ap_unref (ap); } - nm_info ("Activation (%s) failed for access point (%s)", nm_device_get_iface (dev), ap ? nm_ap_get_essid (ap) : "(none)"); + + nm_info ("Activation (%s) failed for access point (%s)", nm_device_get_iface (dev), + failed_ap ? nm_ap_get_essid (failed_ap) : "(none)"); + + /* Failed AP got reffed by nm_device_get_best_ap() during activation, + * must unref it here. + */ + if (failed_ap) + nm_ap_unref (failed_ap); } else nm_info ("Activation (%s) failed.", nm_device_get_iface (dev)); if (data->active_device == dev) + { + nm_device_unref (dev); data->active_device = NULL; + } nm_device_deactivate (dev, FALSE); break; @@ -494,12 +504,17 @@ static gboolean nm_policy_allowed_ap_list_update (gpointer user_data) NMDevice *dev = (NMDevice *)(elt->data); if (nm_device_is_wireless (dev)) { - /* Once we have the list, copy in any relevant information from our Allowed list and fill - * in the ESSID of base stations that aren't broadcasting their ESSID, if we have their - * MAC address in our allowed list. - */ - nm_ap_list_copy_essids_by_address (nm_device_ap_list_get (dev), data->allowed_ap_list); - nm_ap_list_copy_properties (nm_device_ap_list_get (dev), data->allowed_ap_list); + if (nm_device_get_supports_wireless_scan (dev)) + { + /* Once we have the list, copy in any relevant information from our Allowed list and fill + * in the ESSID of base stations that aren't broadcasting their ESSID, if we have their + * MAC address in our allowed list. + */ + nm_ap_list_copy_essids_by_address (nm_device_ap_list_get (dev), data->allowed_ap_list); + nm_ap_list_copy_properties (nm_device_ap_list_get (dev), data->allowed_ap_list); + } + else + nm_device_copy_allowed_to_dev_list (dev, data->allowed_ap_list); } } diff --git a/src/NetworkManagerPolicy.h b/src/NetworkManagerPolicy.h index 3a6524118..c34781293 100644 --- a/src/NetworkManagerPolicy.h +++ b/src/NetworkManagerPolicy.h @@ -29,6 +29,7 @@ typedef struct { NMDevice *dev; + NMAccessPoint *failed_ap; DeviceStatus result; } NMActivationResult; diff --git a/src/NetworkManagerUtils.c b/src/NetworkManagerUtils.c index a4bad39a3..f4863565d 100644 --- a/src/NetworkManagerUtils.c +++ b/src/NetworkManagerUtils.c @@ -173,7 +173,6 @@ int nm_null_safe_strcmp (const char *s1, const char *s2) } - /* * nm_ethernet_address_is_valid * @@ -337,6 +336,10 @@ NMDriverSupportLevel nm_get_wireless_driver_support_level (LibHalContext *ctx, N g_free (driver_name); } + /* Check for carrier detection support */ + if ((level != NM_DRIVER_UNSUPPORTED) && !nm_device_get_supports_wireless_scan (dev)) + level = NM_DRIVER_NO_WIRELESS_SCAN; + return (level); } @@ -387,6 +390,10 @@ NMDriverSupportLevel nm_get_wired_driver_support_level (LibHalContext *ctx, NMDe level = NM_DRIVER_UNSUPPORTED; } + /* Check for carrier detection support */ + if ((level != NM_DRIVER_UNSUPPORTED) && !nm_device_get_supports_carrier_detect(dev)) + level = NM_DRIVER_NO_CARRIER_DETECT; + return (level); } @@ -412,9 +419,14 @@ NMDriverSupportLevel nm_get_driver_support_level (LibHalContext *ctx, NMDevice * switch (level) { - case NM_DRIVER_SEMI_SUPPORTED: - nm_info ("%s: Driver support level for '%s' is semi-supported", - nm_device_get_iface (dev), driver); + case NM_DRIVER_NO_CARRIER_DETECT: + nm_info ("%s: Driver '%s' does not support carrier detection.\n" + "\tYou must switch to it manually.", nm_device_get_iface (dev), driver); + break; + case NM_DRIVER_NO_WIRELESS_SCAN: + nm_info ("%s: Driver '%s' does not support wireless scanning.\n" + "\tNetworkManager will not be able to fully use the card.", + nm_device_get_iface (dev), driver); break; case NM_DRIVER_FULLY_SUPPORTED: nm_info ("%s: Driver support level for '%s' is fully-supported", diff --git a/src/autoip.c b/src/autoip.c index 746de4bf9..d06bfb2c0 100644 --- a/src/autoip.c +++ b/src/autoip.c @@ -179,6 +179,7 @@ gboolean get_autoip (NMDevice *dev, struct in_addr *out_ip) int nprobes = 0; int nannounce = 0; gboolean success = FALSE; + char *temp_addr; g_return_val_if_fail (dev != NULL, FALSE); g_return_val_if_fail (out_ip != NULL, FALSE); @@ -203,7 +204,7 @@ gboolean get_autoip (NMDevice *dev, struct in_addr *out_ip) goto out; } - nm_device_get_hw_address (dev, addr.ether_addr_octet); + nm_device_get_hw_address (dev, &(addr.ether_addr_octet[0])); /* initialize pseudo random selection of IP addresses */ srandom ( (addr.ether_addr_octet[ETHER_ADDR_LEN-4] << 24) | diff --git a/src/backends/NetworkManagerDebian.c b/src/backends/NetworkManagerDebian.c index 86d39f205..b39adebaf 100644 --- a/src/backends/NetworkManagerDebian.c +++ b/src/backends/NetworkManagerDebian.c @@ -334,9 +334,10 @@ void nm_system_restart_mdns_responder (void) void nm_system_device_add_ip6_link_address (NMDevice *dev) { char *buf; + char *addr; unsigned char eui[8]; - nm_device_get_hw_address(dev, eui); + nm_device_get_hw_address(dev, &eui[0]); memmove(eui+5, eui+3, 3); eui[3] = 0xff; diff --git a/src/backends/NetworkManagerRedHat.c b/src/backends/NetworkManagerRedHat.c index 847db5d74..d7900778f 100644 --- a/src/backends/NetworkManagerRedHat.c +++ b/src/backends/NetworkManagerRedHat.c @@ -349,9 +349,10 @@ void nm_system_restart_mdns_responder (void) void nm_system_device_add_ip6_link_address (NMDevice *dev) { char *buf; + char *addr; unsigned char eui[8]; - nm_device_get_hw_address(dev, eui); + nm_device_get_hw_address(dev, &eui[0]); memmove(eui+5, eui+3, 3); eui[3] = 0xff; diff --git a/src/nm-dbus-device.c b/src/nm-dbus-device.c index 41ead4238..74fe90155 100644 --- a/src/nm-dbus-device.c +++ b/src/nm-dbus-device.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "nm-utils.h" #include "NetworkManagerDevice.h" @@ -102,6 +103,29 @@ static DBusMessage *nm_dbus_device_get_ip4_address (DBusConnection *connection, return reply; } +static DBusMessage *nm_dbus_device_get_hw_address (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data) +{ + DBusMessage *reply = NULL; + NMDevice *dev; + + g_return_val_if_fail (data && data->data && data->dev && connection && message, NULL); + + dev = data->dev; + if ((reply = dbus_message_new_method_return (message))) + { + struct ether_addr addr; + char char_addr[20]; + char *ptr = &char_addr[0]; + + nm_device_get_hw_address (dev, (unsigned char *)&(addr.ether_addr_octet)); + memset (char_addr, 0, 20); + ether_ntoa_r (&addr, &char_addr[0]); + dbus_message_append_args (reply, DBUS_TYPE_STRING, &ptr, DBUS_TYPE_INVALID); + } + + return reply; +} + static DBusMessage *nm_dbus_device_get_mode (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data) { DBusMessage *reply = NULL; @@ -279,25 +303,19 @@ static DBusMessage *nm_dbus_device_get_networks (DBusConnection *connection, DBu return reply; } -static DBusMessage *nm_dbus_device_get_supports_carrier_detect (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data) +static DBusMessage *nm_dbus_device_get_driver_support_level (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data) { DBusMessage *reply = NULL; NMDevice *dev; g_return_val_if_fail (data && data->data && data->dev && connection && message, NULL); - /* Wired devices only for now */ dev = data->dev; - if (!nm_device_is_wired (dev)) + if ((reply = dbus_message_new_method_return (message))) { - reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "DeviceNotWired", - "Carrier detection is only supported for wired devices."); + dbus_uint32_t driver_support_level = nm_device_get_driver_support_level (dev); + dbus_message_append_args (reply, DBUS_TYPE_UINT32, &driver_support_level, DBUS_TYPE_INVALID); } - else if ((reply = dbus_message_new_method_return (message))) { - dbus_bool_t supports_carrier_detect; - supports_carrier_detect = nm_device_get_supports_carrier_detect (dev); - dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &supports_carrier_detect, DBUS_TYPE_INVALID); - } return reply; } @@ -343,17 +361,18 @@ NMDbusMethodList *nm_dbus_device_methods_setup (void) { NMDbusMethodList *list = nm_dbus_method_list_new (NULL); - nm_dbus_method_list_add_method (list, "getName", nm_dbus_device_get_name); - nm_dbus_method_list_add_method (list, "getType", nm_dbus_device_get_type); - nm_dbus_method_list_add_method (list, "getHalUdi", nm_dbus_device_get_hal_udi); - nm_dbus_method_list_add_method (list, "getIP4Address", nm_dbus_device_get_ip4_address); - nm_dbus_method_list_add_method (list, "getMode", nm_dbus_device_get_mode); - nm_dbus_method_list_add_method (list, "getStrength", nm_dbus_device_get_strength); - nm_dbus_method_list_add_method (list, "getActiveNetwork", nm_dbus_device_get_active_network); - nm_dbus_method_list_add_method (list, "getNetworks", nm_dbus_device_get_networks); - nm_dbus_method_list_add_method (list, "getLinkActive", nm_dbus_device_get_link_active); - nm_dbus_method_list_add_method (list, "setLinkActive", nm_dbus_device_set_link_active); - nm_dbus_method_list_add_method (list, "getSupportsCarrierDetect", nm_dbus_device_get_supports_carrier_detect); + nm_dbus_method_list_add_method (list, "getName", nm_dbus_device_get_name); + nm_dbus_method_list_add_method (list, "getType", nm_dbus_device_get_type); + nm_dbus_method_list_add_method (list, "getHalUdi", nm_dbus_device_get_hal_udi); + nm_dbus_method_list_add_method (list, "getIP4Address", nm_dbus_device_get_ip4_address); + nm_dbus_method_list_add_method (list, "getHWAddress", nm_dbus_device_get_hw_address); + nm_dbus_method_list_add_method (list, "getMode", nm_dbus_device_get_mode); + nm_dbus_method_list_add_method (list, "getStrength", nm_dbus_device_get_strength); + nm_dbus_method_list_add_method (list, "getActiveNetwork", nm_dbus_device_get_active_network); + nm_dbus_method_list_add_method (list, "getNetworks", nm_dbus_device_get_networks); + nm_dbus_method_list_add_method (list, "getLinkActive", nm_dbus_device_get_link_active); + nm_dbus_method_list_add_method (list, "setLinkActive", nm_dbus_device_set_link_active); + nm_dbus_method_list_add_method (list, "getDriverSupportLevel", nm_dbus_device_get_driver_support_level); return (list); }