diff --git a/ChangeLog b/ChangeLog index fdf12deb8..1fbf4585f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,57 @@ +2007-03-02 Tambet Ingo + + * libnm-glib/nm-device-802-11-wireless.c: Cache networks (bssids) list. + We get signalled when it changes. + + * libnm-glib/nm-client.c: Cache NMState and device list, we get signalled + when it changes. + + * libnm-glib/nm-device.c: Cache the device state property. + + * libnm-glib/nm-access-point.c: Cache the strength property. + + * src/nm-device-802-11-wireless.c: Fix wireless device scanning scheduler. + The new algorithm is to start from SCAN_INTERVAL_MIN (currently defined as 0) + and add a SCAN_INTERVAL_STEP (currently 20 seconds) with each successful scan + until SCAN_INTERVAL_MAX (currently 120 seconds) is reached. Do not scan while + the device is down, activating, or activated (in case of A/B/G cards). + Remove some old dead ifdef'ed out code that used to configure wireless devices, + it's all done through supplicant now. + + * src/supplicant-manager/nm-supplicant-interface.c: Fix the reference + counting issues with pending calls which caused leaks and crashes when + interface was removed (now that the interface actually gets removed). + + * src/nm-call-store.c: Make a copy of data before running a foreach + with user callback on it - The most common usage pattern is to cancel + (and thus remove) all pending calls with foreach which would modify + the hash table we're iterating over. + + * src/nm-manager.c: When a device is added, make sure it is "up". When + it's removed or disabled due to disabling wireless or networking, bring + it down. + + * include/NetworkManager.h: Add new device state NM_DEVICE_STATE_DOWN. + + * src/nm-device-802-11-wireless.c: + * src/nm-device-802-3-ethernet.c: + * src/nm-device.c: + - Remove "init" virtual function, all gobjects have a place for that + already (constructor). + - Replace "start" virtual function with "bring_up", devices can be + brought up and down more than just on startup now. + - Add "is_up" virtual function. + - Implement one way to bring a device down instead of previous 4 different + ways, each of witch did something different. + + * src/NetworkManagerUtils.c (nm_dev_sock_open): This doesn't need an NMDevice, + all it needs is the device interface. + + Get rid of NMData.dev_list (3 members to go). + Get rif of NMData in a lot of places. + + * gnome/libnm_glib/libnm_glib.c: Make it compile again. + 2007-02-23 Dan Williams Patch from Andy Whitcroft (Gnome.org #410426) diff --git a/gnome/libnm_glib/libnm_glib.c b/gnome/libnm_glib/libnm_glib.c index a70a54821..763acf61e 100644 --- a/gnome/libnm_glib/libnm_glib.c +++ b/gnome/libnm_glib/libnm_glib.c @@ -30,6 +30,8 @@ #include "libnm_glib.h" #define DBUS_NO_SERVICE_ERROR "org.freedesktop.DBus.Error.ServiceDoesNotExist" +#define NM_DBUS_SIGNAL_STATE_CHANGE "StateChange" + struct libnm_glib_ctx { diff --git a/include/NetworkManager.h b/include/NetworkManager.h index dd7eb98c0..eac883729 100644 --- a/include/NetworkManager.h +++ b/include/NetworkManager.h @@ -138,6 +138,7 @@ typedef enum NMNetworkType typedef enum { NM_DEVICE_STATE_UNKNOWN = 0, + NM_DEVICE_STATE_DOWN, NM_DEVICE_STATE_DISCONNECTED, NM_DEVICE_STATE_PREPARE, NM_DEVICE_STATE_CONFIG, diff --git a/libnm-glib/libnm-glib-test.c b/libnm-glib/libnm-glib-test.c index 5c0b2c599..4bd657016 100644 --- a/libnm-glib/libnm-glib-test.c +++ b/libnm-glib/libnm-glib-test.c @@ -226,7 +226,6 @@ test_devices (NMClient *client) g_print ("\n"); } - g_slist_foreach (list, (GFunc) g_object_unref, NULL); g_slist_free (list); return TRUE; @@ -288,15 +287,12 @@ do_stuff (gpointer user_data) g_signal_connect (device, "state-changed", G_CALLBACK (device_state_changed), NULL); - /* FIXME: This ref is never released */ - g_object_ref (device); nm_device_802_3_ethernet_activate (device, TRUE); break; } } - g_slist_foreach (list, (GFunc) g_object_unref, NULL); g_slist_free (list); return FALSE; diff --git a/libnm-glib/nm-access-point.c b/libnm-glib/nm-access-point.c index ef6c8e53b..c6f5c80ac 100644 --- a/libnm-glib/nm-access-point.c +++ b/libnm-glib/nm-access-point.c @@ -6,6 +6,12 @@ G_DEFINE_TYPE (NMAccessPoint, nm_access_point, DBUS_TYPE_G_PROXY) +#define NM_ACCESS_POINT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_ACCESS_POINT, NMAccessPointPrivate)) + +typedef struct { + int strength; +} NMAccessPointPrivate; + enum { STRENGTH_CHANGED, @@ -26,6 +32,8 @@ nm_access_point_class_init (NMAccessPointClass *ap_class) { GObjectClass *object_class = G_OBJECT_CLASS (ap_class); + g_type_class_add_private (ap_class, sizeof (NMAccessPointPrivate)); + /* signals */ signals[STRENGTH_CHANGED] = g_signal_new ("strength-changed", @@ -64,7 +72,12 @@ nm_access_point_new (DBusGConnection *connection, const char *path) static void strength_changed_proxy (NMAccessPoint *ap, guchar strength) { - g_signal_emit (ap, signals[STRENGTH_CHANGED], 0, strength); + NMAccessPointPrivate *priv = NM_ACCESS_POINT_GET_PRIVATE (ap); + + if (priv->strength != strength) { + priv->strength = strength; + g_signal_emit (ap, signals[STRENGTH_CHANGED], 0, strength); + } } guint32 @@ -190,16 +203,21 @@ nm_access_point_get_rate (NMAccessPoint *ap) int nm_access_point_get_strength (NMAccessPoint *ap) { - GValue value = {0,}; - int strength = 0; + NMAccessPointPrivate *priv; g_return_val_if_fail (NM_IS_ACCESS_POINT (ap), 0); - if (nm_dbus_get_property (DBUS_G_PROXY (ap), - NM_DBUS_INTERFACE_ACCESS_POINT, - "Strength", - &value)) - strength = g_value_get_int (&value); + priv = NM_ACCESS_POINT_GET_PRIVATE (ap); - return strength; + if (priv->strength == 0) { + GValue value = {0,}; + + if (nm_dbus_get_property (DBUS_G_PROXY (ap), + NM_DBUS_INTERFACE_ACCESS_POINT, + "Strength", + &value)) + priv->strength = g_value_get_int (&value); + } + + return priv->strength; } diff --git a/libnm-glib/nm-client.c b/libnm-glib/nm-client.c index 71a3bdc1a..c214cf496 100644 --- a/libnm-glib/nm-client.c +++ b/libnm-glib/nm-client.c @@ -8,6 +8,14 @@ G_DEFINE_TYPE (NMClient, nm_client, DBUS_TYPE_G_PROXY) +#define NM_CLIENT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_CLIENT, NMClientPrivate)) + +typedef struct { + NMState state; + gboolean have_device_list; + GHashTable *devices; +} NMClientPrivate; + enum { DEVICE_ADDED, DEVICE_REMOVED, @@ -25,6 +33,20 @@ static void client_device_removed_proxy (DBusGProxy *proxy, char *path, gpointer static void nm_client_init (NMClient *client) { + NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (client); + + priv->state = NM_STATE_UNKNOWN; + priv->devices = g_hash_table_new_full (g_str_hash, g_str_equal, + (GDestroyNotify) g_free, + (GDestroyNotify) g_object_unref); +} + +static void +finalize (GObject *object) +{ + NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (object); + + g_hash_table_destroy (priv->devices); } static void @@ -32,6 +54,11 @@ nm_client_class_init (NMClientClass *client_class) { GObjectClass *object_class = G_OBJECT_CLASS (client_class); + g_type_class_add_private (client_class, sizeof (NMClientPrivate)); + + /* virtual methods */ + object_class->finalize = finalize; + /* signals */ signals[DEVICE_ADDED] = g_signal_new ("device-added", @@ -117,8 +144,44 @@ static void client_state_change_proxy (DBusGProxy *proxy, guint state, gpointer user_data) { NMClient *client = NM_CLIENT (proxy); + NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (client); - g_signal_emit (client, signals[STATE_CHANGE], 0, state); + if (priv->state != state) { + priv->state = state; + g_signal_emit (client, signals[STATE_CHANGE], 0, state); + } +} + +static NMDevice * +get_device (NMClient *client, const char *path, gboolean create_if_not_found) +{ + NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (client); + NMDevice *device; + + device = g_hash_table_lookup (priv->devices, path); + if (!device && create_if_not_found) { + DBusGConnection *connection = NULL; + NMDeviceType type; + + g_object_get (client, "connection", &connection, NULL); + type = nm_device_type_for_path (connection, path); + + switch (type) { + case DEVICE_TYPE_802_3_ETHERNET: + device = NM_DEVICE (nm_device_802_3_ethernet_new (connection, path)); + break; + case DEVICE_TYPE_802_11_WIRELESS: + device = NM_DEVICE (nm_device_802_11_wireless_new (connection, path)); + break; + default: + device = nm_device_new (connection, path); + } + + if (device) + g_hash_table_insert (priv->devices, g_strdup (path), device); + } + + return device; } static void @@ -126,12 +189,10 @@ client_device_added_proxy (DBusGProxy *proxy, char *path, gpointer user_data) { NMClient *client = NM_CLIENT (proxy); NMDevice *device; - DBusGConnection *connection = NULL; - g_object_get (client, "connection", &connection, NULL); - device = nm_device_new (connection, path); - g_signal_emit (client, signals[DEVICE_ADDED], 0, device); - g_object_unref (device); + device = get_device (client, path, TRUE); + if (device) + g_signal_emit (client, signals[DEVICE_ADDED], 0, device); } static void @@ -139,54 +200,56 @@ client_device_removed_proxy (DBusGProxy *proxy, char *path, gpointer user_data) { NMClient *client = NM_CLIENT (proxy); NMDevice *device; - DBusGConnection *connection = NULL; - g_object_get (client, "connection", &connection, NULL); - device = nm_device_new (connection, path); - g_signal_emit (client, signals[DEVICE_REMOVED], 0, device); - g_object_unref (device); + device = get_device (client, path, FALSE); + if (device) { + g_signal_emit (client, signals[DEVICE_REMOVED], 0, device); + g_hash_table_remove (NM_CLIENT_GET_PRIVATE (client)->devices, path); + } } +static void +devices_to_slist (gpointer key, gpointer value, gpointer user_data) +{ + GSList **list = (GSList **) user_data; + + *list = g_slist_prepend (*list, value); +} GSList * nm_client_get_devices (NMClient *client) { + NMClientPrivate *priv; GSList *list = NULL; GPtrArray *array = NULL; GError *err = NULL; g_return_val_if_fail (NM_IS_CLIENT (client), NULL); + priv = NM_CLIENT_GET_PRIVATE (client); + + if (priv->have_device_list) { + g_hash_table_foreach (priv->devices, devices_to_slist, &list); + return list; + } + if (!org_freedesktop_NetworkManager_get_devices (DBUS_G_PROXY (client), &array, &err)) { g_warning ("Error in get_devices: %s", err->message); g_error_free (err); } else { - DBusGConnection *connection = NULL; int i; - g_object_get (client, "connection", &connection, NULL); - for (i = 0; i < array->len; i++) { NMDevice *device; - const char *path = g_ptr_array_index (array, i); - NMDeviceType type = nm_device_type_for_path (connection, path); - switch (type) { - case DEVICE_TYPE_802_3_ETHERNET: - device = NM_DEVICE (nm_device_802_3_ethernet_new (connection, path)); - break; - case DEVICE_TYPE_802_11_WIRELESS: - device = NM_DEVICE (nm_device_802_11_wireless_new (connection, path)); - break; - default: - device = nm_device_new (connection, path); - break; - } - - list = g_slist_append (list, device); + device = get_device (client, (const char *) g_ptr_array_index (array, i), TRUE); + if (device) + list = g_slist_append (list, device); } g_ptr_array_free (array, TRUE); + + priv->have_device_list = TRUE; } return list; @@ -227,16 +290,21 @@ nm_client_wireless_set_enabled (NMClient *client, gboolean enabled) NMState nm_client_get_state (NMClient *client) { - GValue value = {0,}; - NMState state = NM_STATE_UNKNOWN; + NMClientPrivate *priv; - g_return_val_if_fail (NM_IS_CLIENT (client), state); + g_return_val_if_fail (NM_IS_CLIENT (client), NM_STATE_UNKNOWN); - if (nm_dbus_get_property (DBUS_G_PROXY (client), - NM_DBUS_INTERFACE, - "State", - &value)) - state = g_value_get_uint (&value); + priv = NM_CLIENT_GET_PRIVATE (client); - return state; + if (priv->state == NM_STATE_UNKNOWN) { + GValue value = {0,}; + + if (nm_dbus_get_property (DBUS_G_PROXY (client), + NM_DBUS_INTERFACE, + "State", + &value)) + priv->state = g_value_get_uint (&value); + } + + return priv->state; } diff --git a/libnm-glib/nm-device-802-11-wireless.c b/libnm-glib/nm-device-802-11-wireless.c index 8e963cd4a..4e6a1e4f2 100644 --- a/libnm-glib/nm-device-802-11-wireless.c +++ b/libnm-glib/nm-device-802-11-wireless.c @@ -6,6 +6,13 @@ G_DEFINE_TYPE (NMDevice80211Wireless, nm_device_802_11_wireless, NM_TYPE_DEVICE) +#define NM_DEVICE_802_11_WIRELESS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_802_11_WIRELESS, NMDevice80211WirelessPrivate)) + +typedef struct { + gboolean have_network_list; + GHashTable *networks; +} NMDevice80211WirelessPrivate; + enum { NETWORK_ADDED, NETWORK_REMOVED, @@ -21,6 +28,19 @@ static void network_removed_proxy (DBusGProxy *proxy, char *path, gpointer user_ static void nm_device_802_11_wireless_init (NMDevice80211Wireless *device) { + NMDevice80211WirelessPrivate *priv = NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (device); + + priv->networks = g_hash_table_new_full (g_str_hash, g_str_equal, + (GDestroyNotify) g_free, + (GDestroyNotify) g_object_unref); +} + +static void +finalize (GObject *object) +{ + NMDevice80211WirelessPrivate *priv = NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (object); + + g_hash_table_destroy (priv->networks); } static void @@ -28,6 +48,11 @@ nm_device_802_11_wireless_class_init (NMDevice80211WirelessClass *device_class) { GObjectClass *object_class = G_OBJECT_CLASS (device_class); + g_type_class_add_private (device_class, sizeof (NMDevice80211WirelessPrivate)); + + /* virtual methods */ + object_class->finalize = finalize; + /* signals */ signals[NETWORK_ADDED] = g_signal_new ("network-added", @@ -136,6 +161,26 @@ nm_device_802_11_wireless_get_bitrate (NMDevice80211Wireless *device) return bitrate; } +static NMAccessPoint * +get_network (NMDevice80211Wireless *device, const char *path, gboolean create_if_not_found) +{ + NMDevice80211WirelessPrivate *priv = NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (device); + NMAccessPoint *ap; + + ap = g_hash_table_lookup (priv->networks, path); + if (!ap && create_if_not_found) { + DBusGConnection *connection = NULL; + + g_object_get (device, "connection", &connection, NULL); + ap = nm_access_point_new (connection, path); + + if (ap) + g_hash_table_insert (priv->networks, g_strdup (path), ap); + } + + return ap; +} + NMAccessPoint * nm_device_802_11_wireless_get_active_network (NMDevice80211Wireless *device) { @@ -148,41 +193,54 @@ nm_device_802_11_wireless_get_active_network (NMDevice80211Wireless *device) NM_DBUS_INTERFACE_DEVICE_WIRELESS, "ActiveNetwork", &value)) { - DBusGConnection *connection = NULL; - g_assert (G_VALUE_TYPE (&value) == DBUS_TYPE_G_OBJECT_PATH); - - g_object_get (device, "connection", &connection, NULL); - ap = nm_access_point_new (connection, (const char *) g_value_get_boxed (&value)); + ap = get_network (device, (const char *) g_value_get_boxed (&value), TRUE); } return ap; } +static void +networks_to_slist (gpointer key, gpointer value, gpointer user_data) +{ + GSList **list = (GSList **) user_data; + + *list = g_slist_prepend (*list, value); +} + GSList * nm_device_802_11_wireless_get_networks (NMDevice80211Wireless *device) { + NMDevice80211WirelessPrivate *priv; GSList *list = NULL; GPtrArray *array = NULL; GError *err = NULL; g_return_val_if_fail (NM_IS_DEVICE_802_11_WIRELESS (device), NULL); + priv = NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (device); + + if (priv->have_network_list) { + g_hash_table_foreach (priv->networks, networks_to_slist, &list); + return list; + } + if (!org_freedesktop_NetworkManager_Device_Wireless_get_active_networks (DBUS_G_PROXY (device), &array, &err)) { g_warning ("Error in get_networks: %s", err->message); g_error_free (err); } else { - DBusGConnection *connection = NULL; int i; - g_object_get (device, "connection", &connection, NULL); for (i = 0; i < array->len; i++) { - NMAccessPoint *ap = nm_access_point_new (connection, g_ptr_array_index (array, i)); - list = g_slist_prepend (list, ap); + NMAccessPoint *ap = get_network (device, (const char *) g_ptr_array_index (array, i), TRUE); + if (ap) + list = g_slist_prepend (list, ap); } - list = g_slist_reverse (list); g_ptr_array_free (array, TRUE); + list = g_slist_reverse (list); + + priv->have_network_list = TRUE; } return list; @@ -212,12 +270,10 @@ network_added_proxy (DBusGProxy *proxy, char *path, gpointer user_data) { NMDevice80211Wireless *device = NM_DEVICE_802_11_WIRELESS (proxy); NMAccessPoint *ap; - DBusGConnection *connection = NULL; - g_object_get (proxy, "connection", &connection, NULL); - ap = nm_access_point_new (connection, path); - g_signal_emit (device, signals[NETWORK_ADDED], 0, ap); - g_object_unref (ap); + ap = get_network (device, path, TRUE); + if (device) + g_signal_emit (device, signals[NETWORK_ADDED], 0, ap); } static void @@ -225,10 +281,10 @@ network_removed_proxy (DBusGProxy *proxy, char *path, gpointer user_data) { NMDevice80211Wireless *device = NM_DEVICE_802_11_WIRELESS (proxy); NMAccessPoint *ap; - DBusGConnection *connection = NULL; - g_object_get (proxy, "connection", &connection, NULL); - ap = nm_access_point_new (connection, path); - g_signal_emit (device, signals[NETWORK_REMOVED], 0, ap); - g_object_unref (ap); + ap = get_network (device, path, FALSE); + if (device) { + g_signal_emit (device, signals[NETWORK_REMOVED], 0, ap); + g_hash_table_remove (NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (device)->networks, path); + } } diff --git a/libnm-glib/nm-device.c b/libnm-glib/nm-device.c index 6517ecb54..b130b8f02 100644 --- a/libnm-glib/nm-device.c +++ b/libnm-glib/nm-device.c @@ -6,6 +6,12 @@ G_DEFINE_TYPE (NMDevice, nm_device, DBUS_TYPE_G_PROXY) +#define NM_DEVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE, NMDevicePrivate)) + +typedef struct { + NMDeviceState state; +} NMDevicePrivate; + enum { STATE_CHANGED, @@ -49,6 +55,8 @@ nm_device_class_init (NMDeviceClass *device_class) { GObjectClass *object_class = G_OBJECT_CLASS (device_class); + g_type_class_add_private (device_class, sizeof (NMDevicePrivate)); + /* virtual methods */ object_class->constructor = constructor; @@ -69,8 +77,12 @@ static void device_state_change_proxy (DBusGProxy *proxy, guint state, gpointer user_data) { NMDevice *device = NM_DEVICE (user_data); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); - g_signal_emit (device, signals[STATE_CHANGED], 0, state); + if (priv->state != state) { + priv->state = state; + g_signal_emit (device, signals[STATE_CHANGED], 0, state); + } } NMDevice * @@ -192,18 +204,23 @@ nm_device_get_ip4_config (NMDevice *device) NMDeviceState nm_device_get_state (NMDevice *device) { - NMDeviceState state = NM_DEVICE_STATE_UNKNOWN; - GValue value = {0,}; + NMDevicePrivate *priv; - g_return_val_if_fail (NM_IS_DEVICE (device), 0); + g_return_val_if_fail (NM_IS_DEVICE (device), NM_DEVICE_STATE_UNKNOWN); - if (nm_dbus_get_property (DBUS_G_PROXY (device), - NM_DBUS_INTERFACE_DEVICE, - "State", - &value)) - state = g_value_get_uint (&value); + priv = NM_DEVICE_GET_PRIVATE (device); - return state; + if (priv->state == NM_DEVICE_STATE_UNKNOWN) { + GValue value = {0,}; + + if (nm_dbus_get_property (DBUS_G_PROXY (device), + NM_DBUS_INTERFACE_DEVICE, + "State", + &value)) + priv->state = g_value_get_uint (&value); + } + + return priv->state; } NMDeviceType diff --git a/src/NetworkManager.c b/src/NetworkManager.c index 272b86168..a90ed5700 100644 --- a/src/NetworkManager.c +++ b/src/NetworkManager.c @@ -403,14 +403,15 @@ main (int argc, char *argv[]) G_CALLBACK (nm_name_owner_changed_handler), nm_data); + manager = nm_manager_new (); + g_object_set_data (manager, "NM_DATA_HACK", nm_data); + policy = nm_policy_new (manager); + nm_dbus_manager_register_signal_handler (dbus_mgr, NMI_DBUS_INTERFACE, NULL, nm_dbus_nmi_signal_handler, - nm_data); - - manager = nm_manager_new (); - policy = nm_policy_new (manager); + manager); /* Initialize the supplicant manager */ sup_mgr = nm_supplicant_manager_get (); diff --git a/src/NetworkManagerDbus.c b/src/NetworkManagerDbus.c index d5ad2fef0..43d5d6d63 100644 --- a/src/NetworkManagerDbus.c +++ b/src/NetworkManagerDbus.c @@ -135,11 +135,11 @@ nm_dbus_nmi_signal_handler (DBusConnection *connection, DBusMessage *message, gpointer user_data) { - NMData * data = (NMData *) user_data; + NMManager *manager = NM_MANAGER (user_data); const char * object_path; gboolean handled = FALSE; - g_return_val_if_fail (data != NULL, FALSE); + g_return_val_if_fail (manager != NULL, FALSE); if (!(object_path = dbus_message_get_path (message))) return FALSE; @@ -155,16 +155,21 @@ nm_dbus_nmi_signal_handler (DBusConnection *connection, DBUS_TYPE_STRING, &network, DBUS_TYPE_INVALID)) { /* Update a single wireless network's data */ - nm_debug ("NetworkManagerInfo triggered update of wireless network " - "'%s'", - network); - nm_dbus_update_one_allowed_network (network, data); + nm_debug ("NetworkManagerInfo triggered update of wireless network '%s'", network); + nm_dbus_update_one_allowed_network (network, + (NMData *) g_object_get_data (manager, "NM_DATA_HACK")); handled = TRUE; } } else if (dbus_message_is_signal (message, NMI_DBUS_INTERFACE, "UserInterfaceActivated")) { - nm_device_802_11_wireless_set_scan_interval (data, - NULL, - NM_WIRELESS_SCAN_INTERVAL_ACTIVE); + GSList *iter; + + for (iter = nm_manager_get_devices (manager); iter; iter = iter-> next) { + NMDevice *device = NM_DEVICE (iter->data); + + if (NM_IS_DEVICE_802_11_WIRELESS (device)) + nm_device_802_11_wireless_reset_scan_interval (NM_DEVICE_802_11_WIRELESS (device)); + } + handled = TRUE; } diff --git a/src/NetworkManagerMain.h b/src/NetworkManagerMain.h index a3f39cf62..b4cb25e81 100644 --- a/src/NetworkManagerMain.h +++ b/src/NetworkManagerMain.h @@ -37,8 +37,6 @@ typedef struct NMData { NMNamedManager * named_manager; - GSList * dev_list; - struct NMAccessPointList *allowed_ap_list; struct NMAccessPointList *invalid_ap_list; } NMData; diff --git a/src/NetworkManagerPolicy.c b/src/NetworkManagerPolicy.c index 1a1f260d5..a3d854e2d 100644 --- a/src/NetworkManagerPolicy.c +++ b/src/NetworkManagerPolicy.c @@ -427,20 +427,15 @@ nm_policy_device_list_update_from_allowed_list (gpointer user_data) void nm_policy_schedule_device_ap_lists_update_from_allowed (NMData *app_data) { - GSource * source; - guint id; - g_return_if_fail (app_data != NULL); if (device_list_update_id > 0) return; - id = g_idle_add (nm_policy_device_list_update_from_allowed_list, app_data); - device_list_update_id = id; - source = g_main_context_find_source_by_id (NULL, id); - if (source) { - g_source_set_priority (source, G_PRIORITY_HIGH_IDLE); - } + device_list_update_id = g_idle_add_full (G_PRIORITY_HIGH_IDLE, + nm_policy_device_list_update_from_allowed_list, + app_data, + NULL); } /*****************************************************************************/ @@ -502,12 +497,6 @@ device_added (NMManager *manager, NMDevice *device, gpointer user_data) G_CALLBACK (device_carrier_changed), policy); - /* FIXME: */ - { - NMData *nm_data = nm_device_get_app_data (device); - nm_data->dev_list = g_slist_append (nm_data->dev_list, device); - } - if (NM_IS_DEVICE_802_11_WIRELESS (device)) { g_signal_connect (device, "network-added", G_CALLBACK (wireless_networks_changed), @@ -525,12 +514,6 @@ device_removed (NMManager *manager, NMDevice *device, gpointer user_data) { NMPolicy *policy = (NMPolicy *) user_data; - /* FIXME: */ - { - NMData *nm_data = nm_device_get_app_data (device); - nm_data->dev_list = g_slist_remove (nm_data->dev_list, device); - } - schedule_change_check (policy); } diff --git a/src/NetworkManagerUtils.c b/src/NetworkManagerUtils.c index 3f7cfc181..76d4e9f60 100644 --- a/src/NetworkManagerUtils.c +++ b/src/NetworkManagerUtils.c @@ -49,7 +49,7 @@ struct NMSock int fd; char *func; char *desc; - NMDevice *dev; + char *iface; }; static GSList * sock_list = NULL; @@ -61,12 +61,12 @@ static GSList * sock_list = NULL; * Open a socket to a network device and store some debug info about it. * */ -NMSock *nm_dev_sock_open (NMDevice *dev, SockType type, const char *func_name, const char *desc) +NMSock * +nm_dev_sock_open (const char *iface, SockType type, const char *func_name, const char *desc) { NMSock *sock = NULL; - sock = g_malloc0 (sizeof (NMSock)); - + sock = g_slice_new (NMSock); sock->fd = -1; switch (type) @@ -91,19 +91,17 @@ NMSock *nm_dev_sock_open (NMDevice *dev, SockType type, const char *func_name, c if (sock->fd < 0) { - g_free (sock); - nm_warning ("Could not open control socket for device '%s'.", dev ? nm_device_get_iface (dev) : "none"); + g_slice_free (NMSock, sock); + nm_warning ("Could not open control socket for device '%s'.", iface ? iface : "none"); return NULL; } sock->func = func_name ? g_strdup (func_name) : NULL; sock->desc = desc ? g_strdup (desc) : NULL; - sock->dev = dev; - if (sock->dev) - g_object_ref (G_OBJECT (sock->dev)); + sock->iface = iface ? g_strdup (iface) : NULL; /* Add the sock to our global sock list for tracking */ - sock_list = g_slist_append (sock_list, sock); + sock_list = g_slist_prepend (sock_list, sock); return sock; } @@ -124,8 +122,7 @@ void nm_dev_sock_close (NMSock *sock) close (sock->fd); g_free (sock->func); g_free (sock->desc); - if (sock->dev) - g_object_unref (G_OBJECT (sock->dev)); + g_free (sock->iface); memset (sock, 0, sizeof (NMSock)); @@ -138,7 +135,7 @@ void nm_dev_sock_close (NMSock *sock) } } - g_free (sock); + g_slice_free (NMSock, sock); } @@ -172,8 +169,8 @@ void nm_print_open_socks (void) NMSock *sock = (NMSock *)(elt->data); if (sock) { i++; - nm_debug (" %d: %s fd:%d F:'%s' D:'%s'", i, sock->dev ? nm_device_get_iface (sock->dev) : "", - sock->fd, sock->func, sock->desc); + nm_debug (" %d: %s fd:%d F:'%s' D:'%s'", i, sock->iface ? sock->iface : "", + sock->fd, sock->func, sock->desc); } } nm_debug ("Open Sockets List Done."); diff --git a/src/NetworkManagerUtils.h b/src/NetworkManagerUtils.h index 67626f8b0..bdbb8b9a3 100644 --- a/src/NetworkManagerUtils.h +++ b/src/NetworkManagerUtils.h @@ -44,7 +44,11 @@ typedef enum SockType typedef struct NMSock NMSock; -NMSock * nm_dev_sock_open (NMDevice *dev, SockType type, const char *func_name, const char *desc); +NMSock * nm_dev_sock_open (const char *iface, + SockType type, + const char *func_name, + const char *desc); + void nm_dev_sock_close (NMSock *sock); int nm_dev_sock_get_fd (NMSock *sock); void nm_print_open_socks (void); diff --git a/src/autoip.c b/src/autoip.c index 3ae1b747e..5ea6cfcd0 100644 --- a/src/autoip.c +++ b/src/autoip.c @@ -214,15 +214,17 @@ gboolean get_autoip (NMDevice *dev, struct in_addr *out_ip) int nprobes = 0; int nannounce = 0; gboolean success = FALSE; + const char *iface; g_return_val_if_fail (dev != NULL, FALSE); g_return_val_if_fail (out_ip != NULL, FALSE); out_ip->s_addr = 0; + iface = nm_device_get_iface (dev); /* initialize saddr */ memset (&saddr, 0, sizeof (saddr)); - strncpy (saddr.sa_data, nm_device_get_iface (dev), sizeof (saddr.sa_data)); + strncpy (saddr.sa_data, iface, sizeof (saddr.sa_data)); if (NM_IS_DEVICE_802_3_ETHERNET (dev)) nm_device_802_3_ethernet_get_address (NM_DEVICE_802_3_ETHERNET (dev), &addr); @@ -232,16 +234,16 @@ gboolean get_autoip (NMDevice *dev, struct in_addr *out_ip) goto out; /* open an ARP socket */ - if ((sk = nm_dev_sock_open (dev, NETWORK_CONTROL, __FUNCTION__, NULL)) == NULL) + if ((sk = nm_dev_sock_open (iface, NETWORK_CONTROL, __FUNCTION__, NULL)) == NULL) { - nm_warning ("%s: Couldn't open network control socket.", nm_device_get_iface (dev)); + nm_warning ("%s: Couldn't open network control socket.", iface); goto out; } /* bind to the ARP socket */ if (bind (nm_dev_sock_get_fd (sk), &saddr, sizeof (saddr)) < 0) { - nm_warning ("%s: Couldn't bind to the device.", nm_device_get_iface (dev)); + nm_warning ("%s: Couldn't bind to the device.", iface); goto out; } @@ -317,7 +319,7 @@ gboolean get_autoip (NMDevice *dev, struct in_addr *out_ip) } #ifdef ARP_DEBUG - nm_warning ("autoip: (%s) recv arp type=%d, op=%d, ", nm_device_get_iface (dev), ntohs(p.ethhdr.ether_type), ntohs(p.operation)); + nm_warning ("autoip: (%s) recv arp type=%d, op=%d, ", iface, ntohs(p.ethhdr.ether_type), ntohs(p.operation)); { struct in_addr a; memcpy (&(a.s_addr), &(p.sInaddr), sizeof (a.s_addr)); @@ -335,7 +337,7 @@ gboolean get_autoip (NMDevice *dev, struct in_addr *out_ip) && (memcmp (&addr, &p.tHaddr, ETH_ALEN) != 0)) { #ifdef ARP_DEBUG - nm_warning ("autoip: (%s) ARP conflict for IP address %s.\n", nm_device_get_iface (dev), inet_ntoa(ip)); + nm_warning ("autoip: (%s) ARP conflict for IP address %s.\n", iface, inet_ntoa(ip)); #endif /* Ok, start all over again */ diff --git a/src/nm-call-store.c b/src/nm-call-store.c index 4019e8321..fa8db6400 100644 --- a/src/nm-call-store.c +++ b/src/nm-call-store.c @@ -69,25 +69,55 @@ typedef struct { } StoreForeachInfo; static void -call_callback (gpointer key, gpointer value, gpointer user_data) +call_callback (gpointer call_id, gpointer user_data) { StoreForeachInfo *info = (StoreForeachInfo *) user_data; if (info->count >= 0) { - if (info->callback (info->object, key, info->user_data)) + if (info->callback (info->object, call_id, info->user_data)) info->count++; else info->count = -1; } } +static void +prepend_id (gpointer key, gpointer value, gpointer user_data) +{ + GSList **list = (GSList **) user_data; + + *list = g_slist_prepend (*list, key); +} + +static GSList * +get_call_ids (GHashTable *hash) +{ + GSList *ids = NULL; + + g_hash_table_foreach (hash, prepend_id, &ids); + + return ids; +} + static void call_all_callbacks (gpointer key, gpointer value, gpointer user_data) { StoreForeachInfo *info = (StoreForeachInfo *) user_data; + GSList *ids; info->object = G_OBJECT (key); - g_hash_table_foreach ((GHashTable *) value, call_callback, info); + + /* Create a copy of the hash keys (call_ids) so that the callback is + free to modify the store */ + ids = get_call_ids ((GHashTable *) value); + g_slist_foreach (ids, call_callback, info); + g_slist_free (ids); +} + +static void +duplicate_hash (gpointer key, gpointer value, gpointer user_data) +{ + g_hash_table_insert ((GHashTable *) user_data, key, value); } int @@ -108,6 +138,7 @@ nm_call_store_foreach (NMCallStore *store, if (object) { GHashTable *call_ids_hash; + GSList *ids; call_ids_hash = g_hash_table_lookup (store, object); if (!call_ids_hash) { @@ -115,9 +146,19 @@ nm_call_store_foreach (NMCallStore *store, return -1; } - g_hash_table_foreach (call_ids_hash, call_callback, &info); + /* Create a copy of the hash keys (call_ids) so that the callback is + free to modify the store */ + ids = get_call_ids (call_ids_hash); + g_slist_foreach (ids, call_callback, &info); + g_slist_free (ids); } else { - g_hash_table_foreach (store, call_all_callbacks, &info); + GHashTable *copy; + + /* Create a copy of the main store so that callbacks can modify it */ + copy = g_hash_table_new (NULL, NULL); + g_hash_table_foreach (store, duplicate_hash, copy); + g_hash_table_foreach (copy, call_all_callbacks, &info); + g_hash_table_destroy (copy); } return info.count; diff --git a/src/nm-device-802-11-wireless.c b/src/nm-device-802-11-wireless.c index 2b36c2018..93efa47ab 100644 --- a/src/nm-device-802-11-wireless.c +++ b/src/nm-device-802-11-wireless.c @@ -62,6 +62,12 @@ static gboolean impl_device_get_active_networks (NMDevice80211Wireless *device, /* #define IW_QUAL_DEBUG */ +/* All of these are in seconds */ +#define SCAN_INTERVAL_MIN 0 +#define SCAN_INTERVAL_STEP 20 +#define SCAN_INTERVAL_MAX 120 + + G_DEFINE_TYPE (NMDevice80211Wireless, nm_device_802_11_wireless, NM_TYPE_DEVICE) #define NM_DEVICE_802_11_WIRELESS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_802_11_WIRELESS, NMDevice80211WirelessPrivate)) @@ -103,12 +109,10 @@ typedef struct Supplicant { struct _NMDevice80211WirelessPrivate { gboolean dispose_has_run; - gboolean is_initialized; struct ether_addr hw_addr; char * cur_essid; - gint8 strength; gint8 invalid_strength_counter; iwqual max_qual; iwqual avg_qual; @@ -118,8 +122,8 @@ struct _NMDevice80211WirelessPrivate gboolean scanning; NMAccessPointList * ap_list; + GTimeVal scheduled_scan_time; guint8 scan_interval; /* seconds */ - guint32 last_scan; guint pending_scan_id; Supplicant supplicant; @@ -136,8 +140,6 @@ struct _NMDevice80211WirelessPrivate static void nm_device_802_11_wireless_ap_list_clear (NMDevice80211Wireless *self); -static gboolean request_wireless_scan (gpointer user_data); - static void schedule_scan (NMDevice80211Wireless *self); static void cancel_pending_scan (NMDevice80211Wireless *self); @@ -206,42 +208,25 @@ network_removed (NMDevice80211Wireless *device, NMAccessPoint *ap) * */ static void -nm_device_802_11_wireless_update_bssid (NMDevice80211Wireless *self) +nm_device_802_11_wireless_update_bssid (NMDevice80211Wireless *self, + NMAccessPoint *ap) { - NMAccessPoint * ap; - NMActRequest * req; struct ether_addr new_bssid; const struct ether_addr *old_bssid; const char * new_essid; const char * old_essid; - g_return_if_fail (self != NULL); - - /* The current BSSID is pretty meaningless during a scan */ - if (self->priv->scanning) - return; - - /* If we aren't the active device with an active AP, there is no meaningful BSSID value */ - req = nm_device_get_act_request (NM_DEVICE (self)); - if (!req) - return; - - ap = nm_act_request_get_ap (req); - if (!ap) - return; - /* Get the current BSSID. If it is valid but does not match the stored value, * and the ESSID is the same as what we think its supposed to be, update it. */ nm_device_802_11_wireless_get_bssid (self, &new_bssid); old_bssid = nm_ap_get_address (ap); - new_essid = nm_device_802_11_wireless_get_essid(self); - old_essid = nm_ap_get_essid(ap); + new_essid = nm_device_802_11_wireless_get_essid (self); + old_essid = nm_ap_get_essid (ap); if ( nm_ethernet_address_is_valid (&new_bssid) && nm_ethernet_address_is_valid (old_bssid) && !nm_ethernet_addresses_are_equal (&new_bssid, old_bssid) && !nm_null_safe_strcmp (old_essid, new_essid)) { - NMData * app_data; gboolean automatic; gchar new_addr[20]; gchar old_addr[20]; @@ -254,9 +239,7 @@ nm_device_802_11_wireless_update_bssid (NMDevice80211Wireless *self) nm_ap_set_address (ap, &new_bssid); - automatic = !nm_act_request_get_user_requested (req); - app_data = nm_device_get_app_data (NM_DEVICE (self)); - g_assert (app_data); + automatic = !nm_act_request_get_user_requested (nm_device_get_act_request (NM_DEVICE (self))); nm_dbus_update_network_info (ap, automatic); } } @@ -270,39 +253,18 @@ nm_device_802_11_wireless_update_bssid (NMDevice80211Wireless *self) * */ static void -nm_device_802_11_wireless_update_signal_strength (NMDevice80211Wireless *self) +nm_device_802_11_wireless_update_signal_strength (NMDevice80211Wireless *self, + NMAccessPoint *ap) { gboolean has_range = FALSE; NMSock * sk; iwrange range; iwstats stats; - NMActRequest *req; - NMAccessPoint *ap = NULL; int percent = -1; + const char *iface = nm_device_get_iface (NM_DEVICE (self)); - g_return_if_fail (self != NULL); - - /* Signal strength is pretty meaningless during a scan */ - if (self->priv->scanning) - return; - - /* If we aren't the active device, we don't really have a signal strength - * that would mean anything. - */ - - req = nm_device_get_act_request (NM_DEVICE (self)); - if (req) - ap = nm_act_request_get_ap (req); - - if (!ap) { - self->priv->strength = -1; - return; - } - - if ((sk = nm_dev_sock_open (NM_DEVICE (self), DEV_WIRELESS, __FUNCTION__, NULL))) + if ((sk = nm_dev_sock_open (iface, DEV_WIRELESS, __FUNCTION__, NULL))) { - const char *iface = nm_device_get_iface (NM_DEVICE (self)); - memset (&range, 0, sizeof (iwrange)); memset (&stats, 0, sizeof (iwstats)); @@ -321,39 +283,11 @@ nm_device_802_11_wireless_update_signal_strength (NMDevice80211Wireless *self) /* Try to smooth out the strength. Atmel cards, for example, will give no strength * one second and normal strength the next. */ - if ((percent == -1) && (++self->priv->invalid_strength_counter <= 3)) - percent = self->priv->strength; - else - self->priv->invalid_strength_counter = 0; - if (percent != self->priv->strength) + if (percent >= 0 || ++self->priv->invalid_strength_counter > 3) { nm_ap_set_strength (ap, (gint8) percent); - - self->priv->strength = percent; -} - - -static guint nm_wireless_scan_interval_to_seconds (NMWirelessScanInterval interval) -{ - guint seconds; - - switch (interval) - { - case NM_WIRELESS_SCAN_INTERVAL_INIT: - seconds = 15; - break; - - case NM_WIRELESS_SCAN_INTERVAL_INACTIVE: - seconds = 120; - break; - - case NM_WIRELESS_SCAN_INTERVAL_ACTIVE: - default: - seconds = 20; - break; + self->priv->invalid_strength_counter = 0; } - - return seconds; } @@ -365,10 +299,11 @@ real_get_generic_capabilities (NMDevice *dev) guint32 caps = NM_DEVICE_CAP_NONE; iwrange range; struct iwreq wrq; + const char *iface = nm_device_get_iface (dev); /* Check for Wireless Extensions support >= 16 for wireless devices */ - if (!(sk = nm_dev_sock_open (dev, DEV_WIRELESS, __func__, NULL))) + if (!(sk = nm_dev_sock_open (iface, DEV_WIRELESS, __func__, NULL))) goto out; if (iw_get_range_info (nm_dev_sock_get_fd (sk), nm_device_get_iface (dev), &range) < 0) @@ -377,7 +312,7 @@ real_get_generic_capabilities (NMDevice *dev) if (range.we_version_compiled < 16) { nm_warning ("%s: driver's Wireless Extensions version (%d) is too old. Can't use device.", - nm_device_get_iface (dev), range.we_version_compiled); + iface, range.we_version_compiled); } else caps |= NM_DEVICE_CAP_NM_SUPPORTED; @@ -439,16 +374,91 @@ get_wireless_capabilities (NMDevice80211Wireless *self, static void nm_device_802_11_wireless_init (NMDevice80211Wireless * self) { - self->priv = NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (self); - self->priv->dispose_has_run = FALSE; - self->priv->is_initialized = FALSE; - self->priv->supplicant.iface_error_id = 0; + NMDevice80211WirelessPrivate *priv = NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (self); + + self->priv = priv; + priv->dispose_has_run = FALSE; + priv->supplicant.iface_error_id = 0; + priv->scanning = FALSE; + priv->ap_list = nm_ap_list_new (NETWORK_TYPE_DEVICE); + priv->we_version = 0; memset (&(self->priv->hw_addr), 0, sizeof (struct ether_addr)); nm_device_set_device_type (NM_DEVICE (self), DEVICE_TYPE_802_11_WIRELESS); } +static GObject* +constructor (GType type, + guint n_construct_params, + GObjectConstructParam *construct_params) +{ + GObject *object; + NMDevice80211Wireless *self; + NMDevice80211WirelessPrivate *priv; + NMData *app_data; + const char *iface; + guint32 caps; + NMSock *sk; + + object = G_OBJECT_CLASS (nm_device_802_11_wireless_parent_class)->constructor (type, + n_construct_params, + construct_params); + if (!object) + return NULL; + + self = NM_DEVICE_802_11_WIRELESS (object); + priv = NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (self); + + app_data = nm_device_get_app_data (NM_DEVICE (self)); + + /* Non-scanning devices show the entire allowed AP list as their + * available networks. + */ + caps = nm_device_get_capabilities (NM_DEVICE (self)); + if (!(caps & NM_DEVICE_CAP_WIRELESS_SCAN)) + nm_device_802_11_wireless_copy_allowed_to_dev_list (self, app_data->allowed_ap_list); + + iface = nm_device_get_iface (NM_DEVICE (self)); + + if ((sk = nm_dev_sock_open (iface, DEV_WIRELESS, __FUNCTION__, NULL))) { + struct iw_range range; + struct iwreq wrq; + + memset (&wrq, 0, sizeof (wrq)); + strncpy (wrq.ifr_name, iface, IFNAMSIZ); + wrq.u.data.pointer = (caddr_t) ⦥ + wrq.u.data.length = sizeof (struct iw_range); + + if (ioctl (nm_dev_sock_get_fd (sk), SIOCGIWRANGE, &wrq) >= 0) + { + int i; + + priv->max_qual.qual = range.max_qual.qual; + priv->max_qual.level = range.max_qual.level; + priv->max_qual.noise = range.max_qual.noise; + priv->max_qual.updated = range.max_qual.updated; + + priv->avg_qual.qual = range.avg_qual.qual; + priv->avg_qual.level = range.avg_qual.level; + priv->avg_qual.noise = range.avg_qual.noise; + priv->avg_qual.updated = range.avg_qual.updated; + + priv->num_freqs = MIN (range.num_frequency, IW_MAX_FREQUENCIES); + for (i = 0; i < priv->num_freqs; i++) + priv->freqs[i] = iw_freq2float (&(range.freq[i])); + + priv->we_version = range.we_version_compiled; + + /* 802.11 wireless-specific capabilities */ + priv->capabilities = get_wireless_capabilities (self, &range, wrq.u.data.length); + } + nm_dev_sock_close (sk); + } + + return object; +} + static void init_supplicant_interface (NMDevice80211Wireless * self) { @@ -465,25 +475,25 @@ init_supplicant_interface (NMDevice80211Wireless * self) nm_warning ("Couldn't initialize supplicant interface for %s.", nm_device_get_iface (NM_DEVICE (self))); } else { - id = g_signal_connect (G_OBJECT (sup->iface), + id = g_signal_connect (sup->iface, "state", G_CALLBACK (supplicant_iface_state_cb), self); sup->iface_state_id = id; - id = g_signal_connect (G_OBJECT (sup->iface), + id = g_signal_connect (sup->iface, "scanned-ap", G_CALLBACK (supplicant_iface_scanned_ap_cb), self); sup->iface_scanned_ap_id = id; - id = g_signal_connect (G_OBJECT (sup->iface), + id = g_signal_connect (sup->iface, "scan-result", G_CALLBACK (supplicant_iface_scan_result_cb), self); sup->iface_scan_result_id = id; - id = g_signal_connect (G_OBJECT (sup->iface), + id = g_signal_connect (sup->iface, "connection-state", G_CALLBACK (supplicant_iface_connection_state_cb), self); @@ -491,77 +501,6 @@ init_supplicant_interface (NMDevice80211Wireless * self) } } -static void -real_init (NMDevice *dev) -{ - NMDevice80211Wireless * self = NM_DEVICE_802_11_WIRELESS (dev); - NMData * app_data; - guint32 caps; - NMSock * sk; - - self->priv->is_initialized = TRUE; - self->priv->scanning = FALSE; - self->priv->ap_list = nm_ap_list_new (NETWORK_TYPE_DEVICE); - - app_data = nm_device_get_app_data (NM_DEVICE (self)); - nm_device_802_11_wireless_set_scan_interval (app_data, self, NM_WIRELESS_SCAN_INTERVAL_ACTIVE); - - nm_device_802_11_wireless_set_mode (self, IW_MODE_INFRA); - - /* Non-scanning devices show the entire allowed AP list as their - * available networks. - */ - caps = nm_device_get_capabilities (NM_DEVICE (self)); - if (!(caps & NM_DEVICE_CAP_WIRELESS_SCAN)) - nm_device_802_11_wireless_copy_allowed_to_dev_list (self, app_data->allowed_ap_list); - - self->priv->we_version = 0; - if ((sk = nm_dev_sock_open (NM_DEVICE (self), DEV_WIRELESS, __FUNCTION__, NULL))) - { - struct iw_range range; - struct iwreq wrq; - - memset (&wrq, 0, sizeof (wrq)); - strncpy (wrq.ifr_name, nm_device_get_iface (NM_DEVICE (self)), IFNAMSIZ); - wrq.u.data.pointer = (caddr_t) ⦥ - wrq.u.data.length = sizeof (struct iw_range); - - if (ioctl (nm_dev_sock_get_fd (sk), SIOCGIWRANGE, &wrq) >= 0) - { - int i; - - self->priv->max_qual.qual = range.max_qual.qual; - self->priv->max_qual.level = range.max_qual.level; - self->priv->max_qual.noise = range.max_qual.noise; - self->priv->max_qual.updated = range.max_qual.updated; - - self->priv->avg_qual.qual = range.avg_qual.qual; - self->priv->avg_qual.level = range.avg_qual.level; - self->priv->avg_qual.noise = range.avg_qual.noise; - self->priv->avg_qual.updated = range.avg_qual.updated; - - self->priv->num_freqs = MIN (range.num_frequency, IW_MAX_FREQUENCIES); - for (i = 0; i < self->priv->num_freqs; i++) - self->priv->freqs[i] = iw_freq2float (&(range.freq[i])); - - self->priv->we_version = range.we_version_compiled; - - /* 802.11 wireless-specific capabilities */ - self->priv->capabilities = get_wireless_capabilities (self, &range, wrq.u.data.length); - } - nm_dev_sock_close (sk); - } - - self->priv->supplicant.mgr = nm_supplicant_manager_get (); - g_signal_connect (G_OBJECT (self->priv->supplicant.mgr), - "state", - G_CALLBACK (supplicant_mgr_state_cb), - self); - if (nm_supplicant_manager_get_state (self->priv->supplicant.mgr) == NM_SUPPLICANT_MANAGER_STATE_IDLE) { - init_supplicant_interface (self); - } -} - static void real_update_link (NMDevice *dev) { @@ -603,24 +542,74 @@ nm_device_802_11_periodic_update (gpointer data) { NMDevice80211Wireless * self = NM_DEVICE_802_11_WIRELESS (data); - g_return_val_if_fail (self != NULL, TRUE); + /* BSSID and signal strength have meaningful values only if the device + is activated and not scanning */ + if (nm_device_get_state (NM_DEVICE (self)) == NM_DEVICE_STATE_ACTIVATED && + !NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (self)->scanning) { - nm_device_802_11_wireless_update_signal_strength (self); - nm_device_802_11_wireless_update_bssid (self); + NMActRequest *req; + NMAccessPoint *ap; + + req = nm_device_get_act_request (NM_DEVICE (self)); + if (req && (ap = nm_act_request_get_ap (req))) { + nm_device_802_11_wireless_update_signal_strength (self, ap); + nm_device_802_11_wireless_update_bssid (self, ap); + } + } return TRUE; } +static gboolean +real_is_up (NMDevice *device) +{ + if (!NM_DEVICE_CLASS (nm_device_802_11_wireless_parent_class)->is_up (device)) + return FALSE; + + return NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (device)->periodic_source_id != 0; +} static void -real_start (NMDevice *dev) +real_bring_up (NMDevice *dev) { - NMDevice80211Wireless * self = NM_DEVICE_802_11_WIRELESS (dev); - guint id; + NMDevice80211Wireless *self = NM_DEVICE_802_11_WIRELESS (dev); + NMDevice80211WirelessPrivate *priv = NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (self); + + nm_device_802_11_wireless_set_mode (self, IW_MODE_INFRA); + + priv->supplicant.mgr = nm_supplicant_manager_get (); + g_signal_connect (priv->supplicant.mgr, + "state", + G_CALLBACK (supplicant_mgr_state_cb), + self); + if (nm_supplicant_manager_get_state (priv->supplicant.mgr) == NM_SUPPLICANT_MANAGER_STATE_IDLE) { + init_supplicant_interface (self); + } /* Peridoically update link status and signal strength */ - id = g_timeout_add (2000, nm_device_802_11_periodic_update, self); - self->priv->periodic_source_id = id; + priv->periodic_source_id = g_timeout_add (2000, nm_device_802_11_periodic_update, self); +} + +static void +real_bring_down (NMDevice *dev) +{ + NMDevice80211Wireless *self = NM_DEVICE_802_11_WIRELESS (dev); + NMDevice80211WirelessPrivate *priv = NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (self); + + if (priv->periodic_source_id) { + g_source_remove (priv->periodic_source_id); + priv->periodic_source_id = 0; + } + + cancel_pending_scan (self); + + cleanup_supplicant_interface (self); + + if (priv->supplicant.mgr) { + g_object_unref (priv->supplicant.mgr); + priv->supplicant.mgr = NULL; + } + } static void @@ -640,13 +629,10 @@ static void real_deactivate (NMDevice *dev) { NMDevice80211Wireless * self = NM_DEVICE_802_11_WIRELESS (dev); - NMData * app_data; - - app_data = nm_device_get_app_data (dev); - g_assert (app_data); nm_device_802_11_wireless_set_mode (self, IW_MODE_INFRA); - nm_device_802_11_wireless_set_scan_interval (app_data, self, NM_WIRELESS_SCAN_INTERVAL_ACTIVE); + /* FIXME: Should we reset the scan interval here? */ +/* nm_device_802_11_wireless_set_scan_interval (app_data, self, NM_WIRELESS_SCAN_INTERVAL_ACTIVE); */ } @@ -1226,58 +1212,19 @@ nm_device_802_11_wireless_can_activate (NMDevice80211Wireless * self) } -static gboolean -set_scan_interval_cb (gpointer user_data) -{ - NMData *data = (NMData*) user_data; - - nm_device_802_11_wireless_set_scan_interval (data, NULL, NM_WIRELESS_SCAN_INTERVAL_INACTIVE); - - return FALSE; -} - void -nm_device_802_11_wireless_set_scan_interval (NMData *data, - NMDevice80211Wireless *self, - NMWirelessScanInterval interval) +nm_device_802_11_wireless_reset_scan_interval (NMDevice80211Wireless *self) { - static guint source_id = 0; - GSList * elt; - gboolean found = FALSE; - guint8 seconds = nm_wireless_scan_interval_to_seconds (interval); + NMDevice80211WirelessPrivate *priv = NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (self); - g_return_if_fail (data != NULL); + g_return_if_fail (NM_IS_DEVICE_802_11_WIRELESS (self)); - if (source_id != 0) { - g_source_remove (source_id); - source_id = 0; - } + priv->scan_interval = SCAN_INTERVAL_MIN; - for (elt = data->dev_list; elt; elt = g_slist_next (elt)) { - NMDevice *d = (NMDevice *)(elt->data); - if (self && (NM_DEVICE (self) != d)) - continue; - - if (d && NM_IS_DEVICE_802_11_WIRELESS (d)) { - NM_DEVICE_802_11_WIRELESS (d)->priv->scan_interval = seconds; - if (self && (NM_DEVICE (self) == d)) - found = TRUE; - } - } - - /* In case the scan interval didn't get set (which can happen during card - * initialization where the device gets set up before being added to the - * device list), set interval here - */ - if (self && !found) - self->priv->scan_interval = seconds; - - if (interval != NM_WIRELESS_SCAN_INTERVAL_INACTIVE) { - source_id = g_timeout_add (120000, set_scan_interval_cb, data); - } + if (priv->pending_scan_id) + schedule_scan (self); } - /* * nm_device_get_mode * @@ -1289,17 +1236,20 @@ nm_device_802_11_wireless_get_mode (NMDevice80211Wireless *self) { NMSock * sk; int mode = IW_MODE_AUTO; + const char *iface; g_return_val_if_fail (self != NULL, -1); + iface = nm_device_get_iface (NM_DEVICE (self)); + /* Force the card into Managed/Infrastructure mode */ - if ((sk = nm_dev_sock_open (NM_DEVICE (self), DEV_WIRELESS, __FUNCTION__, NULL))) + if ((sk = nm_dev_sock_open (iface, DEV_WIRELESS, __FUNCTION__, NULL))) { struct iwreq wrq; memset (&wrq, 0, sizeof (struct iwreq)); - nm_ioctl_info ("%s: About to GET IWMODE.", nm_device_get_iface (NM_DEVICE (self))); + nm_ioctl_info ("%s: About to GET IWMODE.", iface); if (iw_get_ext (nm_dev_sock_get_fd (sk), nm_device_get_iface (NM_DEVICE (self)), SIOCGIWMODE, &wrq) == 0) { @@ -1308,8 +1258,7 @@ nm_device_802_11_wireless_get_mode (NMDevice80211Wireless *self) } else { - nm_warning ("error getting card mode on %s: %s", - nm_device_get_iface (NM_DEVICE (self)), strerror (errno)); + nm_warning ("error getting card mode on %s: %s", iface, strerror (errno)); } nm_dev_sock_close (sk); } @@ -1329,6 +1278,7 @@ nm_device_802_11_wireless_set_mode (NMDevice80211Wireless *self, const int mode) { NMSock * sk; + const char *iface; gboolean success = FALSE; g_return_val_if_fail (self != NULL, FALSE); @@ -1337,12 +1287,12 @@ nm_device_802_11_wireless_set_mode (NMDevice80211Wireless *self, if (nm_device_802_11_wireless_get_mode (self) == mode) return TRUE; - /* Force the card into Managed/Infrastructure mode */ - if ((sk = nm_dev_sock_open (NM_DEVICE (self), DEV_WIRELESS, __FUNCTION__, NULL))) - { - const char * iface = nm_device_get_iface (NM_DEVICE (self)); - struct iwreq wreq; + iface = nm_device_get_iface (NM_DEVICE (self)); + /* Force the card into Managed/Infrastructure mode */ + if ((sk = nm_dev_sock_open (iface, DEV_WIRELESS, __FUNCTION__, NULL))) + { + struct iwreq wreq; nm_ioctl_info ("%s: About to SET IWMODE.", iface); @@ -1368,26 +1318,6 @@ nm_device_802_11_wireless_set_mode (NMDevice80211Wireless *self, } -/* - * nm_device_802_11_wireless_get_signal_strength - * - * Get the current signal strength of a wireless device. This only works when - * the card is associated with an access point, so will only work for the - * active device. - * - * Returns: -1 on error - * 0 - 100 strength percentage of the connection to the current access point - * - */ -gint8 -nm_device_802_11_wireless_get_signal_strength (NMDevice80211Wireless *self) -{ - g_return_val_if_fail (self != NULL, -1); - - return (self->priv->strength); -} - - /* * wireless_stats_to_percent * @@ -1520,7 +1450,7 @@ nm_device_802_11_wireless_get_essid (NMDevice80211Wireless *self) g_return_val_if_fail (self != NULL, NULL); iface = nm_device_get_iface (NM_DEVICE (self)); - if ((sk = nm_dev_sock_open (NM_DEVICE (self), DEV_WIRELESS, __FUNCTION__, NULL))) + if ((sk = nm_dev_sock_open (iface, DEV_WIRELESS, __FUNCTION__, NULL))) { wireless_config info; @@ -1576,7 +1506,7 @@ nm_device_802_11_wireless_set_essid (NMDevice80211Wireless *self, } iface = nm_device_get_iface (NM_DEVICE (self)); - if ((sk = nm_dev_sock_open (NM_DEVICE (self), DEV_WIRELESS, __FUNCTION__, NULL))) + if ((sk = nm_dev_sock_open (iface, DEV_WIRELESS, __FUNCTION__, NULL))) { wreq.u.essid.pointer = (caddr_t) safe_essid; wreq.u.essid.length = len + 1; @@ -1608,122 +1538,6 @@ nm_device_802_11_wireless_set_essid (NMDevice80211Wireless *self, } -#if 0 -/* - * nm_device_get_frequency - * - * For wireless devices, get the frequency we broadcast/receive on. - * - */ -static double -nm_device_802_11_wireless_get_frequency (NMDevice80211Wireless *self) -{ - NMSock * sk; - int err; - double freq = 0; - const char * iface; - - g_return_val_if_fail (self != NULL, 0); - - iface = nm_device_get_iface (NM_DEVICE (self)); - if ((sk = nm_dev_sock_open (NM_DEVICE (self), DEV_WIRELESS, __FUNCTION__, NULL))) - { - struct iwreq wrq; - - nm_ioctl_info ("%s: About to GET IWFREQ.", iface); - - err = iw_get_ext (nm_dev_sock_get_fd (sk), iface, SIOCGIWFREQ, &wrq); - if (err >= 0) - freq = iw_freq2float (&wrq.u.freq); - if (err == -1) - { - nm_warning ("error getting frequency for device %s: %s", - iface, strerror (errno)); - } - - nm_dev_sock_close (sk); - } - - return freq; -} - -/* - * nm_device_set_frequency - * - * For wireless devices, set the frequency to broadcast/receive on. - * A frequency <= 0 means "auto". - * - */ -static void -nm_device_802_11_wireless_set_frequency (NMDevice80211Wireless *self, - const double freq) -{ - NMSock * sk; - int err; - const char * iface; - - /* HACK FOR NOW */ - if (freq <= 0) - return; - - g_return_if_fail (self != NULL); - - if (fabs (nm_device_802_11_wireless_get_frequency (self) - freq) <= DBL_EPSILON) - return; - - iface = nm_device_get_iface (NM_DEVICE (self)); - if ((sk = nm_dev_sock_open (NM_DEVICE (self), DEV_WIRELESS, __FUNCTION__, NULL))) - { - struct iwreq wrq; - - if (freq <= 0) - { - /* Auto */ - /* People like to make things hard for us. Even though iwlib/iwconfig say - * that wrq.u.freq.m should be -1 for "auto" mode, nobody actually supports - * that. Madwifi actually uses "0" to mean "auto". So, we'll try 0 first - * and if that doesn't work, fall back to the iwconfig method and use -1. - * - * As a further note, it appears that Atheros/Madwifi cards can't go back to - * any-channel operation once you force set the channel on them. For example, - * if you set a prism54 card to a specific channel, but then set the ESSID to - * something else later, it will scan for the ESSID and switch channels just fine. - * Atheros cards, however, just stay at the channel you previously set and don't - * budge, no matter what you do to them, until you tell them to go back to - * any-channel operation. - */ - wrq.u.freq.m = 0; - wrq.u.freq.e = 0; - wrq.u.freq.flags = 0; - } - else - { - /* Fixed */ - wrq.u.freq.flags = IW_FREQ_FIXED; - iw_float2freq (freq, &wrq.u.freq); - } - - nm_ioctl_info ("%s: About to SET IWFREQ.", iface); - - if ((err = iw_set_ext (nm_dev_sock_get_fd (sk), iface, SIOCSIWFREQ, &wrq)) == -1) - { - gboolean success = FALSE; - if ((freq <= 0) && ((errno == EINVAL) || (errno == EOPNOTSUPP))) - { - /* Ok, try "auto" the iwconfig way if the Atheros way didn't work */ - wrq.u.freq.m = -1; - wrq.u.freq.e = 0; - wrq.u.freq.flags = 0; - if (iw_set_ext (nm_dev_sock_get_fd (sk), iface, SIOCSIWFREQ, &wrq) != -1) - success = TRUE; - } - } - - nm_dev_sock_close (sk); - } -} -#endif - /* * nm_device_get_bitrate * @@ -1742,7 +1556,7 @@ nm_device_802_11_wireless_get_bitrate (NMDevice80211Wireless *self) g_return_val_if_fail (self != NULL, 0); iface = nm_device_get_iface (NM_DEVICE (self)); - if ((sk = nm_dev_sock_open (NM_DEVICE (self), DEV_WIRELESS, __FUNCTION__, NULL))) + if ((sk = nm_dev_sock_open (iface, DEV_WIRELESS, __FUNCTION__, NULL))) { nm_ioctl_info ("%s: About to GET IWRATE.", iface); err = iw_get_ext (nm_dev_sock_get_fd (sk), iface, SIOCGIWRATE, &wrq); @@ -1752,52 +1566,6 @@ nm_device_802_11_wireless_get_bitrate (NMDevice80211Wireless *self) return ((err >= 0) ? wrq.u.bitrate.value / 1000000 : 0); } -#if 0 -/* - * nm_device_set_bitrate - * - * For wireless devices, set the bitrate to broadcast/receive at. - * Rate argument should be in Mbps (mega-bits per second), or 0 for automatic. - * - */ -static void -nm_device_802_11_wireless_set_bitrate (NMDevice80211Wireless *self, - const int Mbps) -{ - NMSock * sk; - const char * iface; - - g_return_if_fail (self != NULL); - - if (nm_device_802_11_wireless_get_bitrate (self) == Mbps) - return; - - iface = nm_device_get_iface (NM_DEVICE (self)); - if ((sk = nm_dev_sock_open (NM_DEVICE (self), DEV_WIRELESS, __FUNCTION__, NULL))) - { - struct iwreq wrq; - - if (Mbps != 0) - { - wrq.u.bitrate.value = Mbps * 1000; - wrq.u.bitrate.fixed = 1; - } - else - { - /* Auto bitrate */ - wrq.u.bitrate.value = -1; - wrq.u.bitrate.fixed = 0; - } - /* Silently fail as not all drivers support setting bitrate yet (ipw2x00 for example) */ - nm_ioctl_info ("%s: About to SET IWRATE.", iface); - iw_set_ext (nm_dev_sock_get_fd (sk), iface, SIOCSIWRATE, &wrq); - - nm_dev_sock_close (sk); - } -} -#endif - - /* * nm_device_get_bssid * @@ -1818,7 +1586,7 @@ nm_device_802_11_wireless_get_bssid (NMDevice80211Wireless *self, memset (bssid, 0, sizeof (struct ether_addr)); iface = nm_device_get_iface (NM_DEVICE (self)); - if ((sk = nm_dev_sock_open (NM_DEVICE (self), DEV_WIRELESS, __FUNCTION__, NULL))) + if ((sk = nm_dev_sock_open (iface, DEV_WIRELESS, __FUNCTION__, NULL))) { nm_ioctl_info ("%s: About to GET IWAP.", iface); if (iw_get_ext (nm_dev_sock_get_fd (sk), iface, SIOCGIWAP, &wrq) >= 0) @@ -1842,7 +1610,7 @@ nm_device_802_11_wireless_disable_encryption (NMDevice80211Wireless *self) g_return_if_fail (self != NULL); - if ((sk = nm_dev_sock_open (NM_DEVICE (self), DEV_WIRELESS, __FUNCTION__, NULL))) + if ((sk = nm_dev_sock_open (iface, DEV_WIRELESS, __FUNCTION__, NULL))) { struct iwreq wreq = { .u.data.pointer = (caddr_t) NULL, @@ -1864,112 +1632,94 @@ nm_device_802_11_wireless_disable_encryption (NMDevice80211Wireless *self) } else nm_warning ("could not get wireless control socket for device %s", iface); } -static void supplicant_iface_scan_result_cb (NMSupplicantInterface * iface, - gboolean result, - NMDevice80211Wireless * self) +static gboolean +can_scan (NMDevice80211Wireless *self) { - g_return_if_fail (self != NULL); + NMDevice80211WirelessPrivate *priv = NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (self); + guint32 state; + gboolean scan = FALSE; - schedule_scan (self); + state = nm_supplicant_interface_get_connection_state (priv->supplicant.iface); + + if (priv->num_freqs >= 14) { + /* A/B/G cards should only scan if they are disconnected. */ + if (state == NM_SUPPLICANT_INTERFACE_CON_STATE_DISCONNECTED || + state == NM_SUPPLICANT_INTERFACE_CON_STATE_INACTIVE) + scan = TRUE; + } else if (state == NM_SUPPLICANT_INTERFACE_CON_STATE_DISCONNECTED || + state == NM_SUPPLICANT_INTERFACE_CON_STATE_INACTIVE || + state == NM_SUPPLICANT_INTERFACE_CON_STATE_COMPLETED) + scan = TRUE; + + return scan; +} + +static void +supplicant_iface_scan_result_cb (NMSupplicantInterface * iface, + gboolean result, + NMDevice80211Wireless * self) +{ + if (can_scan (self)) + schedule_scan (self); } -/* - * request_wireless_scan - * - * Reqeust a wireless scan from the supplicant - * - */ static gboolean request_wireless_scan (gpointer user_data) { - NMDevice80211Wireless * self = NM_DEVICE_802_11_WIRELESS (user_data); - guint32 caps; - NMData * app_data; + NMDevice80211Wireless *self = NM_DEVICE_802_11_WIRELESS (user_data); + NMDevice80211WirelessPrivate *priv = NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (self); + gboolean success = TRUE; - g_return_val_if_fail (self != NULL, FALSE); + if (can_scan (self)) { + nm_debug ("Starting wireless scan for device %s.", + nm_device_get_iface (NM_DEVICE (user_data))); - if (!(app_data = nm_device_get_app_data (NM_DEVICE (self)))) - goto out; - - caps = nm_device_get_capabilities (NM_DEVICE (self)); - if (!(caps & NM_DEVICE_CAP_NM_SUPPORTED) || !(caps & NM_DEVICE_CAP_WIRELESS_SCAN)) - goto out; - - if (self->priv->pending_scan_id) { - g_source_remove (self->priv->pending_scan_id); - self->priv->pending_scan_id = 0; + success = nm_supplicant_interface_request_scan (priv->supplicant.iface); + if (success) + priv->pending_scan_id = 0; } - /* Reschedule ourselves if all wireless is disabled, we're asleep, - * or we are currently activating. - */ - /* FIXME: Make sure we're allowed to scan: is networking enabled? is wireless enabled? */ - if (nm_device_is_activating (NM_DEVICE (self))) - { - nm_device_802_11_wireless_set_scan_interval (app_data, self, NM_WIRELESS_SCAN_INTERVAL_INIT); - schedule_scan (self); - goto out; - } - - /* - * A/B/G cards should only scan if they are disconnected. Set the timeout to active - * for the case we lose this connection shortly, it will reach this point and then - * nm_device_is_activated will return FALSE, letting the scan proceed. - */ - if (self->priv->num_freqs > 14 && nm_device_get_state (NM_DEVICE (self)) == NM_DEVICE_STATE_ACTIVATED) - { - nm_device_802_11_wireless_set_scan_interval (app_data, self, NM_WIRELESS_SCAN_INTERVAL_ACTIVE); - schedule_scan (self); - goto out; - } - - /* Make sure we have a valid supplicant interface */ - if ( !self->priv->supplicant.iface - || nm_supplicant_interface_get_state (self->priv->supplicant.iface) != NM_SUPPLICANT_INTERFACE_STATE_READY) { - schedule_scan (self); - goto out; - } - - if (!nm_supplicant_interface_request_scan (self->priv->supplicant.iface)) { - /* If some sort of error occurred, just try again later */ - schedule_scan (self); - } - -out: - return FALSE; /* Balance g_source_attach(), destroyed on return */ + return !success; } /* * schedule_scan * - * Schedule a wireless scan in the /device's/ thread. + * Schedule a wireless scan. * */ static void schedule_scan (NMDevice80211Wireless *self) { - guint id; + NMDevice80211WirelessPrivate *priv = NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (self); + GTimeVal current_time; - g_return_if_fail (self != NULL); + g_get_current_time (¤t_time); - cancel_pending_scan (self); + /* Cancel the pending scan only if it would happen later than what is scheduled right now */ + if (priv->pending_scan_id && (current_time.tv_sec + priv->scan_interval < priv->scheduled_scan_time.tv_sec)) + cancel_pending_scan (self); - id = g_timeout_add (self->priv->scan_interval * 1000, - request_wireless_scan, - self); - self->priv->pending_scan_id = id; + if (!priv->pending_scan_id) + priv->pending_scan_id = g_timeout_add (priv->scan_interval * 1000, + request_wireless_scan, + self); + + priv->scheduled_scan_time.tv_sec = current_time.tv_sec + priv->scan_interval; + if (priv->scan_interval < SCAN_INTERVAL_MAX) + priv->scan_interval += SCAN_INTERVAL_STEP; } static void cancel_pending_scan (NMDevice80211Wireless *self) { - g_return_if_fail (self != NULL); + NMDevice80211WirelessPrivate *priv = NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (self); - if (self->priv->pending_scan_id) { - g_source_remove (self->priv->pending_scan_id); - self->priv->pending_scan_id = 0; + if (priv->pending_scan_id) { + g_source_remove (priv->pending_scan_id); + priv->pending_scan_id = 0; } } @@ -1985,20 +1735,17 @@ is_associated (NMDevice80211Wireless *self) struct iwreq wrq; NMSock * sk; gboolean associated = FALSE; - NMData * app_data; const char * iface; - app_data = nm_device_get_app_data (NM_DEVICE (self)); - g_assert (app_data); + iface = nm_device_get_iface (NM_DEVICE (self)); - if ((sk = nm_dev_sock_open (NM_DEVICE (self), DEV_WIRELESS, __FUNCTION__, NULL)) == NULL) + if ((sk = nm_dev_sock_open (iface, DEV_WIRELESS, __FUNCTION__, NULL)) == NULL) return FALSE; /* Some cards, for example ipw2x00 cards, can short-circuit the MAC * address check using this check on IWNAME. Its faster. */ memset (&wrq, 0, sizeof (struct iwreq)); - iface = nm_device_get_iface (NM_DEVICE (self)); nm_ioctl_info ("%s: About to GET IWNAME.", iface); if (iw_get_ext (nm_dev_sock_get_fd (sk), iface, SIOCGIWNAME, &wrq) >= 0) { @@ -2283,7 +2030,6 @@ cull_scan_list (NMDevice80211Wireless * self) while ((outdated_ap = nm_ap_list_iter_next (iter))) { const GTimeVal * ap_time = nm_ap_get_last_seen (outdated_ap); gboolean keep_around = FALSE; - guint inactive_interval_s; guint prune_interval_s; const char * ssid; @@ -2294,8 +2040,7 @@ cull_scan_list (NMDevice80211Wireless * self) keep_around = TRUE; } - inactive_interval_s = nm_wireless_scan_interval_to_seconds (NM_WIRELESS_SCAN_INTERVAL_INACTIVE); - prune_interval_s = inactive_interval_s * 3; + prune_interval_s = SCAN_INTERVAL_MAX * 3; if (!keep_around && (ap_time->tv_sec + prune_interval_s < cur_time.tv_sec)) outdated_list = g_slist_append (outdated_list, outdated_ap); @@ -2356,7 +2101,6 @@ supplicant_iface_scanned_ap_cb (NMSupplicantInterface * iface, NMDevice80211Wireless * self) { NMAccessPoint *ap; - GTimeVal *last_seen; NMData *app_data; g_return_if_fail (self != NULL); @@ -2372,9 +2116,6 @@ supplicant_iface_scanned_ap_cb (NMSupplicantInterface * iface, set_ap_strength_from_properties (self, ap, properties); - last_seen = (GTimeVal *) nm_ap_get_last_seen (ap); - self->priv->last_scan = last_seen->tv_sec; - /* If the AP is not broadcasting its ESSID, try to fill it in here from our * allowed list where we cache known MAC->ESSID associations. */ @@ -2543,9 +2284,10 @@ supplicant_iface_state_cb_handler (gpointer user_data) old_state); if (new_state == NM_SUPPLICANT_INTERFACE_STATE_READY) { - /* Start the scanning timeout for devices that can do scanning */ + /* Schedule scanning for devices that can do scanning */ if (nm_device_get_capabilities (NM_DEVICE (self)) & NM_DEVICE_CAP_WIRELESS_SCAN) { - self->priv->pending_scan_id = g_idle_add (request_wireless_scan, self); + nm_device_802_11_wireless_reset_scan_interval (self); + schedule_scan (self); } } else if (new_state == NM_SUPPLICANT_INTERFACE_STATE_DOWN) { cancel_pending_scan (self); @@ -2929,7 +2671,7 @@ build_supplicant_config (NMDevice80211Wireless *self, /* Use "AP_SCAN 2" if the wireless network is non-broadcast or Ad-Hoc */ is_adhoc = (nm_ap_get_mode(ap) == IW_MODE_ADHOC); - if (!nm_ap_get_broadcast (ap) || (nm_ap_get_mode(ap) == IW_MODE_ADHOC)) { + if (!nm_ap_get_broadcast (ap) || is_adhoc) { nm_supplicant_config_set_ap_scan (config, 2); } @@ -2973,7 +2715,7 @@ real_set_hw_address (NMDevice *dev) NMSock *sk; int ret; - sk = nm_dev_sock_open (dev, DEV_GENERAL, __FUNCTION__, NULL); + sk = nm_dev_sock_open (nm_device_get_iface (dev), DEV_GENERAL, __FUNCTION__, NULL); if (!sk) return; @@ -3019,7 +2761,7 @@ real_act_stage2_config (NMDevice *dev, } /* Hook up error signal handler to capture association errors */ - id = g_signal_connect (G_OBJECT (self->priv->supplicant.iface), + id = g_signal_connect (self->priv->supplicant.iface, "connection-error", G_CALLBACK (supplicant_iface_connection_error_cb), self); @@ -3127,7 +2869,6 @@ real_act_stage4_ip_config_timeout (NMDevice *dev, NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE; NMIP4Config * real_config = NULL; NMAPSecurity * security; - NMData * data; gboolean has_key; g_return_val_if_fail (config != NULL, NM_ACT_STAGE_RETURN_FAILURE); @@ -3135,9 +2876,6 @@ real_act_stage4_ip_config_timeout (NMDevice *dev, g_assert (ap); - data = nm_device_get_app_data (dev); - g_assert (data); - security = nm_ap_get_security (ap); g_assert (security); @@ -3184,14 +2922,10 @@ activation_success_handler (NMDevice *dev) struct ether_addr addr; NMAccessPoint * ap; gboolean automatic; - NMData * app_data; req = nm_device_get_act_request (dev); ap = nm_act_request_get_ap (req); - app_data = nm_act_request_get_data (req); - g_assert (app_data); - /* Cache details in the info-daemon since the connect was successful */ automatic = !nm_act_request_get_user_requested (req); @@ -3292,60 +3026,21 @@ real_get_type_capabilities (NMDevice *dev) static void nm_device_802_11_wireless_dispose (GObject *object) { - NMDevice80211Wireless * self = NM_DEVICE_802_11_WIRELESS (object); - NMDevice80211WirelessClass * klass = NM_DEVICE_802_11_WIRELESS_GET_CLASS (object); - NMDeviceClass * parent_class; + NMDevice80211Wireless *self = NM_DEVICE_802_11_WIRELESS (object); + NMDevice80211WirelessPrivate *priv = NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (self); /* Make sure dispose does not run twice. */ - if (self->priv->dispose_has_run) + if (priv->dispose_has_run) return; - self->priv->dispose_has_run = TRUE; - - /* Only do this part of the cleanup if the object is initialized */ - if (!self->priv->is_initialized) - goto out; - - self->priv->is_initialized = FALSE; + priv->dispose_has_run = TRUE; /* General cleanup, free references to other objects */ nm_device_802_11_wireless_ap_list_clear (self); - if (self->priv->ap_list) - nm_ap_list_unref (self->priv->ap_list); + if (priv->ap_list) + nm_ap_list_unref (priv->ap_list); - cancel_pending_scan (self); - - if (self->priv->supplicant.iface) { - nm_supplicant_manager_release_iface (self->priv->supplicant.mgr, - self->priv->supplicant.iface); - self->priv->supplicant.iface = NULL; - } - - if (self->priv->supplicant.mgr) { - g_object_unref (self->priv->supplicant.mgr); - self->priv->supplicant.mgr = NULL; - } - - if (self->priv->periodic_source_id) { - g_source_remove (self->priv->periodic_source_id); - self->priv->periodic_source_id = 0; - } - -out: - /* Chain up to the parent class */ - parent_class = NM_DEVICE_CLASS (g_type_class_peek_parent (klass)); - G_OBJECT_CLASS (parent_class)->dispose (object); -} - -static void -nm_device_802_11_wireless_finalize (GObject *object) -{ - NMDevice80211WirelessClass * klass = NM_DEVICE_802_11_WIRELESS_GET_CLASS (object); - NMDeviceClass * parent_class; - - /* Chain up to the parent class */ - parent_class = NM_DEVICE_CLASS (g_type_class_peek_parent (klass)); - G_OBJECT_CLASS (parent_class)->finalize (object); + G_OBJECT_CLASS (nm_device_802_11_wireless_parent_class)->dispose (object); } static void @@ -3394,14 +3089,15 @@ nm_device_802_11_wireless_class_init (NMDevice80211WirelessClass *klass) g_type_class_add_private (object_class, sizeof (NMDevice80211WirelessPrivate)); + object_class->constructor = constructor; object_class->get_property = get_property; object_class->dispose = nm_device_802_11_wireless_dispose; - object_class->finalize = nm_device_802_11_wireless_finalize; parent_class->get_type_capabilities = real_get_type_capabilities; parent_class->get_generic_capabilities = real_get_generic_capabilities; - parent_class->init = real_init; - parent_class->start = real_start; + parent_class->is_up = real_is_up; + parent_class->bring_up = real_bring_up; + parent_class->bring_down = real_bring_down; parent_class->update_link = real_update_link; parent_class->set_hw_address = real_set_hw_address; diff --git a/src/nm-device-802-11-wireless.h b/src/nm-device-802-11-wireless.h index b8e696dc0..9aef92e3b 100644 --- a/src/nm-device-802-11-wireless.h +++ b/src/nm-device-802-11-wireless.h @@ -48,14 +48,6 @@ G_BEGIN_DECLS #define NM_DEVICE_802_11_WIRELESS_BITRATE "bitrate" #define NM_DEVICE_802_11_WIRELESS_ACTIVE_NETWORK "active-network" -typedef enum NMWirelessScanInterval -{ - NM_WIRELESS_SCAN_INTERVAL_INIT = 0, - NM_WIRELESS_SCAN_INTERVAL_ACTIVE, - NM_WIRELESS_SCAN_INTERVAL_INACTIVE -} NMWirelessScanInterval; - - #ifndef NM_DEVICE_802_11_WIRELESS_DEFINED #define NM_DEVICE_802_11_WIRELESS_DEFINED typedef struct _NMDevice80211Wireless NMDevice80211Wireless; @@ -116,9 +108,7 @@ NMAccessPoint * nm_device_802_11_wireless_get_activation_ap (NMDevice80211Wirele const char *essid, NMAPSecurity *security); -void nm_device_802_11_wireless_set_scan_interval (struct NMData *data, - NMDevice80211Wireless *dev, - NMWirelessScanInterval interval); +void nm_device_802_11_wireless_reset_scan_interval (NMDevice80211Wireless *dev); void nm_device_802_11_wireless_copy_allowed_to_dev_list (NMDevice80211Wireless *self, struct NMAccessPointList *allowed_list); @@ -136,8 +126,6 @@ NMAccessPoint * nm_device_802_11_wireless_ap_list_get_ap_by_essid (NMDevice80211 int nm_device_802_11_wireless_get_mode (NMDevice80211Wireless *self); -gint8 nm_device_802_11_wireless_get_signal_strength (NMDevice80211Wireless *self); - gboolean nm_device_802_11_wireless_can_activate (NMDevice80211Wireless * self); diff --git a/src/nm-device-802-3-ethernet.c b/src/nm-device-802-3-ethernet.c index e1f3b9edd..2bab165f7 100644 --- a/src/nm-device-802-3-ethernet.c +++ b/src/nm-device-802-3-ethernet.c @@ -21,7 +21,6 @@ #include #include -#include #include #include #include @@ -30,14 +29,11 @@ #include "nm-device-802-3-ethernet.h" #include "nm-device-interface.h" #include "nm-device-private.h" -#include "NetworkManagerMain.h" #include "nm-activation-request.h" #include "NetworkManagerUtils.h" -#include "NetworkManagerPolicy.h" #include "nm-supplicant-manager.h" #include "nm-netlink-monitor.h" #include "nm-utils.h" -#include "kernel-types.h" static gboolean impl_device_802_3_ethernet_activate (NMDevice8023Ethernet *device, gboolean user_requested, @@ -50,8 +46,7 @@ G_DEFINE_TYPE (NMDevice8023Ethernet, nm_device_802_3_ethernet, NM_TYPE_DEVICE) #define NM_DEVICE_802_3_ETHERNET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_802_3_ETHERNET, NMDevice8023EthernetPrivate)) -struct _NMDevice8023EthernetPrivate -{ +typedef struct { gboolean dispose_has_run; struct ether_addr hw_addr; @@ -61,7 +56,7 @@ struct _NMDevice8023EthernetPrivate guint link_source_id; NMSupplicantInterface * sup_iface; -}; +} NMDevice8023EthernetPrivate; enum { PROP_0, @@ -74,63 +69,42 @@ enum { static gboolean supports_mii_carrier_detect (NMDevice8023Ethernet *dev); static gboolean supports_ethtool_carrier_detect (NMDevice8023Ethernet *dev); -static void nm_device_802_3_ethernet_link_activated (NMNetlinkMonitor *monitor, - const char *iface, - gpointer user_data); -static void nm_device_802_3_ethernet_link_deactivated (NMNetlinkMonitor *monitor, - const char *iface, - gpointer user_data); - static void supplicant_iface_state_cb (NMSupplicantInterface * iface, guint32 new_state, guint32 old_state, NMDevice80211Wireless *self); -static void -nm_device_802_3_ethernet_init (NMDevice8023Ethernet * self) +static GObject* +constructor (GType type, + guint n_construct_params, + GObjectConstructParam *construct_params) { - self->priv = NM_DEVICE_802_3_ETHERNET_GET_PRIVATE (self); - self->priv->dispose_has_run = FALSE; - self->priv->link_source_id = 0; + GObject *object; - memset (&(self->priv->hw_addr), 0, sizeof (struct ether_addr)); + object = G_OBJECT_CLASS (nm_device_802_3_ethernet_parent_class)->constructor (type, + n_construct_params, + construct_params); + if (!object) + return NULL; - nm_device_set_device_type (NM_DEVICE (self), DEVICE_TYPE_802_3_ETHERNET); + NM_DEVICE_802_3_ETHERNET_GET_PRIVATE (object)->carrier_file_path = + g_strdup_printf ("/sys/class/net/%s/carrier", nm_device_get_iface (NM_DEVICE (object))); + + return object; } static void -real_init (NMDevice *dev) +nm_device_802_3_ethernet_init (NMDevice8023Ethernet * self) { - NMDevice8023Ethernet * self = NM_DEVICE_802_3_ETHERNET (dev); - NMData * app_data; - NMNetlinkMonitor * monitor; - NMSupplicantManager * sup_mgr; + NMDevice8023EthernetPrivate *priv = NM_DEVICE_802_3_ETHERNET_GET_PRIVATE (self); - app_data = nm_device_get_app_data (NM_DEVICE (self)); - monitor = nm_netlink_monitor_get (); + priv->dispose_has_run = FALSE; + priv->link_source_id = 0; - self->priv->link_connected_id = g_signal_connect (monitor, "interface-connected", - G_CALLBACK (nm_device_802_3_ethernet_link_activated), self); + memset (&(priv->hw_addr), 0, sizeof (struct ether_addr)); - self->priv->link_disconnected_id = g_signal_connect (monitor, "interface-disconnected", - G_CALLBACK (nm_device_802_3_ethernet_link_deactivated), self); - g_object_unref (monitor); - - sup_mgr = nm_supplicant_manager_get (); - self->priv->sup_iface = nm_supplicant_manager_get_iface (sup_mgr, - nm_device_get_iface (NM_DEVICE (self)), - FALSE); - if (self->priv->sup_iface == NULL) { - nm_warning ("Couldn't initialize supplicant interface for %s.", - nm_device_get_iface (NM_DEVICE (self))); - } else { - g_signal_connect (G_OBJECT (self->priv->sup_iface), - "state", - G_CALLBACK (supplicant_iface_state_cb), - self); - } - g_object_unref (sup_mgr); + nm_device_set_device_type (NM_DEVICE (self), DEVICE_TYPE_802_3_ETHERNET); } static void @@ -165,10 +139,8 @@ probe_link (NMDevice8023Ethernet *self) gchar * contents; gsize length; - if (nm_device_get_removed (NM_DEVICE (self))) - return FALSE; - - if (g_file_get_contents (self->priv->carrier_file_path, &contents, &length, NULL)) + if (g_file_get_contents (NM_DEVICE_802_3_ETHERNET_GET_PRIVATE (self)->carrier_file_path, + &contents, &length, NULL)) { have_link = (gboolean) atoi (contents); g_free (contents); @@ -188,9 +160,7 @@ probe_link (NMDevice8023Ethernet *self) static void real_update_link (NMDevice *dev) { - NMDevice8023Ethernet * self = NM_DEVICE_802_3_ETHERNET (dev); - - nm_device_set_active_link (NM_DEVICE (self), probe_link (self)); + nm_device_set_active_link (dev, probe_link NM_DEVICE_802_3_ETHERNET (dev)); } @@ -203,28 +173,76 @@ real_update_link (NMDevice *dev) static gboolean nm_device_802_3_periodic_update (gpointer data) { - NMDevice8023Ethernet * self = NM_DEVICE_802_3_ETHERNET (data); - - g_return_val_if_fail (self != NULL, TRUE); - - nm_device_set_active_link (NM_DEVICE (self), probe_link (self)); + nm_device_set_active_link (NM_DEVICE (data), + probe_link NM_DEVICE_802_3_ETHERNET (data)); return TRUE; } +static gboolean +real_is_up (NMDevice *device) +{ + if (!NM_DEVICE_CLASS (nm_device_802_3_ethernet_parent_class)->is_up (device)) + return FALSE; + + return NM_DEVICE_802_3_ETHERNET_GET_PRIVATE (device)->link_source_id != 0; +} static void -real_start (NMDevice *dev) +real_bring_up (NMDevice *dev) { - NMDevice8023Ethernet * self = NM_DEVICE_802_3_ETHERNET (dev); - guint id; + NMDevice8023EthernetPrivate *priv = NM_DEVICE_802_3_ETHERNET_GET_PRIVATE (dev); + NMNetlinkMonitor *monitor; + NMSupplicantManager *sup_mgr; + const char *iface; - self->priv->carrier_file_path = g_strdup_printf ("/sys/class/net/%s/carrier", - nm_device_get_iface (NM_DEVICE (dev))); + monitor = nm_netlink_monitor_get (); + priv->link_connected_id = g_signal_connect (monitor, "interface-connected", + G_CALLBACK (nm_device_802_3_ethernet_link_activated), + dev); + priv->link_disconnected_id = g_signal_connect (monitor, "interface-disconnected", + G_CALLBACK (nm_device_802_3_ethernet_link_deactivated), + dev); + g_object_unref (monitor); + + iface = nm_device_get_iface (dev); + sup_mgr = nm_supplicant_manager_get (); + priv->sup_iface = nm_supplicant_manager_get_iface (sup_mgr, iface, FALSE); + if (priv->sup_iface) + g_signal_connect (priv->sup_iface, + "state", + G_CALLBACK (supplicant_iface_state_cb), + dev); + else + nm_warning ("Couldn't initialize supplicant interface for %s.", iface); + g_object_unref (sup_mgr); /* Peridoically update link status */ - id = g_timeout_add (2000, nm_device_802_3_periodic_update, self); - self->priv->link_source_id = id; + priv->link_source_id = g_timeout_add (2000, nm_device_802_3_periodic_update, dev); +} + + +static void +real_bring_down (NMDevice *dev) +{ + NMDevice8023EthernetPrivate *priv = NM_DEVICE_802_3_ETHERNET_GET_PRIVATE (dev); + NMSupplicantManager *sup_mgr; + NMNetlinkMonitor *monitor; + + if (priv->link_source_id) { + g_source_remove (priv->link_source_id); + priv->link_source_id = 0; + } + + sup_mgr = nm_supplicant_manager_get (); + nm_supplicant_manager_release_iface (sup_mgr, priv->sup_iface); + priv->sup_iface = NULL; + g_object_unref (sup_mgr); + + monitor = nm_netlink_monitor_get (); + g_signal_handler_disconnect (monitor, priv->link_connected_id); + g_signal_handler_disconnect (monitor, priv->link_disconnected_id); + g_object_unref (monitor); } @@ -296,7 +314,7 @@ nm_device_802_3_ethernet_get_address (NMDevice8023Ethernet *self, struct ether_a g_return_if_fail (self != NULL); g_return_if_fail (addr != NULL); - memcpy (addr, &(self->priv->hw_addr), sizeof (struct ether_addr)); + memcpy (addr, &(NM_DEVICE_802_3_ETHERNET_GET_PRIVATE (self)->hw_addr), sizeof (struct ether_addr)); } @@ -308,7 +326,7 @@ real_set_hw_address (NMDevice *dev) NMSock *sk; int ret; - sk = nm_dev_sock_open (dev, DEV_GENERAL, __FUNCTION__, NULL); + sk = nm_dev_sock_open (nm_device_get_iface (dev), DEV_GENERAL, __FUNCTION__, NULL); if (!sk) return; @@ -317,7 +335,8 @@ real_set_hw_address (NMDevice *dev) ret = ioctl (nm_dev_sock_get_fd (sk), SIOCGIFHWADDR, &req); if (ret == 0) - memcpy (&(self->priv->hw_addr), &(req.ifr_hwaddr.sa_data), sizeof (struct ether_addr)); + memcpy (&(NM_DEVICE_802_3_ETHERNET_GET_PRIVATE (self)->hw_addr), + &(req.ifr_hwaddr.sa_data), sizeof (struct ether_addr)); nm_dev_sock_close (sk); } @@ -357,46 +376,6 @@ real_can_interrupt_activation (NMDevice *dev) return interrupt; } -static void -nm_device_802_3_ethernet_dispose (GObject *object) -{ - NMDevice8023Ethernet * self = NM_DEVICE_802_3_ETHERNET (object); - NMSupplicantManager * sup_mgr; - NMNetlinkMonitor *monitor; - - if (self->priv->dispose_has_run) - /* If dispose did already run, return. */ - return; - - /* Make sure dispose does not run twice. */ - self->priv->dispose_has_run = TRUE; - - /* - * In dispose, you are supposed to free all types referenced from this - * object which might themselves hold a reference to self. Generally, - * the most simple solution is to unref all members on which you own a - * reference. - */ - sup_mgr = nm_supplicant_manager_get (); - nm_supplicant_manager_release_iface (sup_mgr, self->priv->sup_iface); - self->priv->sup_iface = NULL; - g_object_unref (sup_mgr); - - monitor = nm_netlink_monitor_get (); - g_signal_handler_disconnect (monitor, - self->priv->link_connected_id); - g_signal_handler_disconnect (monitor, - self->priv->link_disconnected_id); - g_object_unref (monitor); - - if (self->priv->link_source_id) { - g_source_remove (self->priv->link_source_id); - self->priv->link_source_id = 0; - } - - G_OBJECT_CLASS (nm_device_802_3_ethernet_parent_class)->dispose (object); -} - static void nm_device_802_3_ethernet_finalize (GObject *object) { @@ -441,13 +420,14 @@ nm_device_802_3_ethernet_class_init (NMDevice8023EthernetClass *klass) g_type_class_add_private (object_class, sizeof (NMDevice8023EthernetPrivate)); /* virtual methods */ + object_class->constructor = constructor; object_class->get_property = get_property; - object_class->dispose = nm_device_802_3_ethernet_dispose; object_class->finalize = nm_device_802_3_ethernet_finalize; parent_class->get_generic_capabilities = real_get_generic_capabilities; - parent_class->init = real_init; - parent_class->start = real_start; + parent_class->is_up = real_is_up; + parent_class->bring_up = real_bring_up; + parent_class->bring_down = real_bring_down; parent_class->update_link = real_update_link; parent_class->can_interrupt_activation = real_can_interrupt_activation; parent_class->set_hw_address = real_set_hw_address; @@ -511,7 +491,7 @@ supports_ethtool_carrier_detect (NMDevice8023Ethernet *self) g_return_val_if_fail (self != NULL, FALSE); iface = nm_device_get_iface (NM_DEVICE (self)); - if ((sk = nm_dev_sock_open (NM_DEVICE (self), DEV_GENERAL, __func__, NULL)) == NULL) + if ((sk = nm_dev_sock_open (iface, DEV_GENERAL, __func__, NULL)) == NULL) { nm_warning ("cannot open socket on interface %s for ethtool detect: %s", iface, strerror (errno)); @@ -547,7 +527,7 @@ nm_device_802_3_ethernet_get_speed (NMDevice8023Ethernet *self) g_return_val_if_fail (self != NULL, FALSE); iface = nm_device_get_iface (NM_DEVICE (self)); - if ((sk = nm_dev_sock_open (NM_DEVICE (self), DEV_GENERAL, __func__, NULL)) == NULL) + if ((sk = nm_dev_sock_open (iface, DEV_GENERAL, __func__, NULL)) == NULL) { nm_warning ("cannot open socket on interface %s for ethtool: %s", iface, strerror (errno)); @@ -608,7 +588,7 @@ supports_mii_carrier_detect (NMDevice8023Ethernet *self) g_return_val_if_fail (self != NULL, FALSE); iface = nm_device_get_iface (NM_DEVICE (self)); - if ((sk = nm_dev_sock_open (NM_DEVICE (self), DEV_GENERAL, __FUNCTION__, NULL)) == NULL) + if ((sk = nm_dev_sock_open (iface, DEV_GENERAL, __FUNCTION__, NULL)) == NULL) { nm_warning ("cannot open socket on interface %s for MII detect; errno=%d", iface, errno); diff --git a/src/nm-device-802-3-ethernet.h b/src/nm-device-802-3-ethernet.h index 291771793..98510d408 100644 --- a/src/nm-device-802-3-ethernet.h +++ b/src/nm-device-802-3-ethernet.h @@ -23,7 +23,6 @@ #define NM_DEVICE_802_3_ETHERNET_H #include -#include #include #include "nm-device.h" @@ -38,25 +37,16 @@ G_BEGIN_DECLS #define NM_IS_DEVICE_802_3_ETHERNET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_802_3_ETHERNET)) #define NM_DEVICE_802_3_ETHERNET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_802_3_ETHERNET, NMDevice8023EthernetClass)) -typedef struct _NMDevice8023Ethernet NMDevice8023Ethernet; -typedef struct _NMDevice8023EthernetClass NMDevice8023EthernetClass; -typedef struct _NMDevice8023EthernetPrivate NMDevice8023EthernetPrivate; - #define NM_DEVICE_802_3_ETHERNET_HW_ADDRESS "hw-address" #define NM_DEVICE_802_3_ETHERNET_SPEED "speed" -struct _NMDevice8023Ethernet -{ +typedef struct { NMDevice parent; +} NMDevice8023Ethernet; - /*< private >*/ - NMDevice8023EthernetPrivate *priv; -}; - -struct _NMDevice8023EthernetClass -{ +typedef struct { NMDeviceClass parent; -}; +} NMDevice8023EthernetClass; GType nm_device_802_3_ethernet_get_type (void); diff --git a/src/nm-device-private.h b/src/nm-device-private.h index 7289fafa1..f17aeef96 100644 --- a/src/nm-device-private.h +++ b/src/nm-device-private.h @@ -25,15 +25,8 @@ #include "nm-device.h" #include "NetworkManagerMain.h" -typedef struct NMDbusCBData { - NMDevice * dev; - NMAccessPoint * ap; - NMData * data; -} NMDbusCBData; - - void nm_device_set_device_type (NMDevice *dev, NMDeviceType type); - +void nm_device_set_active_link (NMDevice *dev, const gboolean active); NMIP4Config * nm_device_new_ip4_autoip_config (NMDevice *self); void nm_device_activate_schedule_stage3_ip_config_start (struct NMActRequest *req); diff --git a/src/nm-device.c b/src/nm-device.c index 529c50940..3f7aca506 100644 --- a/src/nm-device.c +++ b/src/nm-device.c @@ -28,8 +28,6 @@ #include "nm-device.h" #include "nm-device-interface.h" #include "nm-device-private.h" -#include "nm-device-802-3-ethernet.h" -#include "nm-device-802-11-wireless.h" #include "NetworkManagerDbus.h" #include "NetworkManagerPolicy.h" #include "NetworkManagerUtils.h" @@ -60,7 +58,6 @@ struct _NMDevicePrivate NMDeviceType type; guint32 capabilities; char * driver; - gboolean removed; gboolean link_active; guint32 ip4_address; @@ -79,9 +76,6 @@ struct _NMDevicePrivate static void nm_device_activate_schedule_stage5_ip_config_commit (NMActRequest *req); static void nm_device_deactivate (NMDeviceInterface *device); -void nm_device_bring_up (NMDevice *dev); -gboolean nm_device_bring_up_wait (NMDevice *self, gboolean cancelable); - static void nm_device_set_address (NMDevice *device) @@ -108,7 +102,6 @@ nm_device_init (NMDevice * self) self->priv->type = DEVICE_TYPE_UNKNOWN; self->priv->capabilities = NM_DEVICE_CAP_NONE; self->priv->driver = NULL; - self->priv->removed = FALSE; self->priv->link_active = FALSE; self->priv->ip4_address = 0; @@ -131,6 +124,7 @@ constructor (GType type, { GObject *object; NMDevice *dev; + NMDevicePrivate *priv; NMDBusManager *manager; char *path; @@ -142,24 +136,17 @@ constructor (GType type, return NULL; dev = NM_DEVICE (object); + priv = NM_DEVICE_GET_PRIVATE (dev); - dev->priv->capabilities |= NM_DEVICE_GET_CLASS (dev)->get_generic_capabilities (dev); - if (!(dev->priv->capabilities & NM_DEVICE_CAP_NM_SUPPORTED)) + priv->capabilities |= NM_DEVICE_GET_CLASS (dev)->get_generic_capabilities (dev); + if (!(priv->capabilities & NM_DEVICE_CAP_NM_SUPPORTED)) { g_object_unref (G_OBJECT (dev)); return NULL; } - /* Have to bring the device up before checking link status and other stuff */ - nm_device_bring_up_wait (dev, FALSE); - - nm_device_update_ip4_address (dev); - - /* Update the device's hardware address */ - nm_device_set_address (dev); - /* Grab IP config data for this device from the system configuration files */ - dev->priv->system_config_data = nm_system_device_get_system_config (dev, dev->priv->app_data); + priv->system_config_data = nm_system_device_get_system_config (dev, priv->app_data); nm_device_set_use_dhcp (dev, nm_system_device_get_use_dhcp (dev)); /* Allow distributions to flag devices as disabled */ @@ -171,12 +158,6 @@ constructor (GType type, nm_print_device_capabilities (dev); - /* Call type-specific initialization */ - if (NM_DEVICE_GET_CLASS (dev)->init) - NM_DEVICE_GET_CLASS (dev)->init (dev); - - NM_DEVICE_GET_CLASS (dev)->start (dev); - manager = nm_dbus_manager_get (); path = nm_dbus_get_object_path_for_device (dev); @@ -188,6 +169,37 @@ constructor (GType type, } +static gboolean +real_is_up (NMDevice *self) +{ + NMSock * sk; + struct ifreq ifr; + int err; + const char *iface; + + iface = nm_device_get_iface (self); + if ((sk = nm_dev_sock_open (iface, DEV_GENERAL, __FUNCTION__, NULL)) == NULL) + return FALSE; + + /* Get device's flags */ + strncpy (ifr.ifr_name, iface, sizeof (ifr.ifr_name) - 1); + + nm_ioctl_info ("%s: About to GET IFFLAGS.", iface); + err = ioctl (nm_dev_sock_get_fd (sk), SIOCGIFFLAGS, &ifr); + nm_ioctl_info ("%s: Done with GET IFFLAGS.", iface); + + nm_dev_sock_close (sk); + if (!err) + return (!((ifr.ifr_flags^IFF_UP) & IFF_UP)); + + if (errno != ENODEV) + { + nm_warning ("nm_device_is_up() could not get flags for device %s. errno = %d", iface, errno); + } + + return FALSE; +} + static guint32 real_get_generic_capabilities (NMDevice *dev) { @@ -195,22 +207,6 @@ real_get_generic_capabilities (NMDevice *dev) } -static void -real_start (NMDevice *dev) -{ -} - - -void -nm_device_stop (NMDevice *self) -{ - g_return_if_fail (self != NULL); - - nm_device_interface_deactivate (NM_DEVICE_INTERFACE (self)); - nm_device_bring_down (self); -} - - /* * Get/set functions for UDI */ @@ -310,27 +306,6 @@ nm_device_get_app_data (NMDevice *self) } -/* - * Get/Set for "removed" flag - */ -gboolean -nm_device_get_removed (NMDevice *self) -{ - g_return_val_if_fail (self != NULL, TRUE); - - return self->priv->removed; -} - -void -nm_device_set_removed (NMDevice *self, - const gboolean removed) -{ - g_return_if_fail (self != NULL); - - self->priv->removed = removed; -} - - /* * nm_device_get_act_request * @@ -383,7 +358,6 @@ nm_device_activate (NMDevice *device, NMActRequest *req) { NMDevicePrivate *priv; - NMData *data = NULL; g_return_if_fail (NM_IS_DEVICE (device)); g_return_if_fail (req != NULL); @@ -396,9 +370,6 @@ nm_device_activate (NMDevice *device, nm_info ("Activation (%s) started...", nm_device_get_iface (device)); - data = nm_act_request_get_data (req); - g_assert (data); - nm_act_request_ref (req); priv->act_request = req; @@ -417,15 +388,11 @@ nm_device_activate_stage1_device_prepare (gpointer user_data) { NMActRequest * req = (NMActRequest *) user_data; NMDevice * self; - NMData * data; const char * iface; NMActStageReturn ret; g_return_val_if_fail (req != NULL, FALSE); - data = nm_act_request_get_data (req); - g_assert (data); - self = nm_act_request_get_dev (req); g_assert (self); @@ -504,15 +471,11 @@ nm_device_activate_stage2_device_config (gpointer user_data) { NMActRequest * req = (NMActRequest *) user_data; NMDevice * self; - NMData * data; const char * iface; NMActStageReturn ret; g_return_val_if_fail (req != NULL, FALSE); - data = nm_act_request_get_data (req); - g_assert (data); - self = nm_act_request_get_dev (req); g_assert (self); @@ -524,9 +487,7 @@ nm_device_activate_stage2_device_config (gpointer user_data) nm_info ("Activation (%s) Stage 2 of 5 (Device Configure) starting...", iface); nm_device_state_changed (self, NM_DEVICE_STATE_CONFIG); - /* Bring the device up */ - if (!nm_device_is_up (self)) - nm_device_bring_up (self); + nm_device_bring_up (self, FALSE); ret = NM_DEVICE_GET_CLASS (self)->act_stage2_config (self, req); if (ret == NM_ACT_STAGE_RETURN_POSTPONE) @@ -577,12 +538,8 @@ static NMActStageReturn real_act_stage3_ip_config_start (NMDevice *self, NMActRequest *req) { - NMData * data = NULL; NMActStageReturn ret = NM_ACT_STAGE_RETURN_SUCCESS; - data = nm_act_request_get_data (req); - g_assert (data); - /* DHCP devices try DHCP, non-DHCP default to SUCCESS */ if (nm_device_get_use_dhcp (self)) { @@ -622,16 +579,12 @@ static gboolean nm_device_activate_stage3_ip_config_start (gpointer user_data) { NMActRequest * req = (NMActRequest *) user_data; - NMData * data = NULL; NMDevice * self = NULL; const char * iface; NMActStageReturn ret; g_return_val_if_fail (req != NULL, FALSE); - data = nm_act_request_get_data (req); - g_assert (data); - self = nm_act_request_get_dev (req); g_assert (self); @@ -719,7 +672,6 @@ real_act_stage4_get_ip4_config (NMDevice *self, NMActRequest *req, NMIP4Config **config) { - NMData * data; NMIP4Config * real_config = NULL; NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE; @@ -727,8 +679,6 @@ real_act_stage4_get_ip4_config (NMDevice *self, g_return_val_if_fail (*config == NULL, NM_ACT_STAGE_RETURN_FAILURE); g_assert (req); - data = nm_act_request_get_data (req); - g_assert (data); if (nm_device_get_use_dhcp (self)) { real_config = nm_dhcp_manager_get_ip4_config (NM_DEVICE_GET_PRIVATE (self)->dhcp_manager, @@ -748,8 +698,7 @@ real_act_stage4_get_ip4_config (NMDevice *self, else { /* Make sure device is up even if config fails */ - if (!nm_device_is_up (self)) - nm_device_bring_up (self); + nm_device_bring_up (self, FALSE); } return ret; @@ -766,7 +715,6 @@ static gboolean nm_device_activate_stage4_ip_config_get (gpointer user_data) { NMActRequest * req = (NMActRequest *) user_data; - NMData * data = NULL; NMDevice * self = NULL; NMIP4Config * ip4_config = NULL; NMActStageReturn ret; @@ -774,9 +722,6 @@ nm_device_activate_stage4_ip_config_get (gpointer user_data) g_return_val_if_fail (req != NULL, FALSE); - data = nm_act_request_get_data (req); - g_assert (data); - self = nm_act_request_get_dev (req); g_assert (self); @@ -859,7 +804,6 @@ static gboolean nm_device_activate_stage4_ip_config_timeout (gpointer user_data) { NMActRequest * req = (NMActRequest *) user_data; - NMData * data = NULL; NMDevice * self = NULL; NMIP4Config * ip4_config = NULL; const char * iface; @@ -867,9 +811,6 @@ nm_device_activate_stage4_ip_config_timeout (gpointer user_data) g_return_val_if_fail (req != NULL, FALSE); - data = nm_act_request_get_data (req); - g_assert (data); - self = nm_act_request_get_dev (req); g_assert (self); @@ -934,16 +875,12 @@ static gboolean nm_device_activate_stage5_ip_config_commit (gpointer user_data) { NMActRequest * req = (NMActRequest *) user_data; - NMData * data = NULL; NMDevice * self = NULL; NMIP4Config * ip4_config = NULL; const char * iface; g_return_val_if_fail (req != NULL, FALSE); - data = nm_act_request_get_data (req); - g_assert (data); - self = nm_act_request_get_dev (req); g_assert (self); @@ -1035,8 +972,6 @@ nm_device_activation_cancel (NMDevice *self) if (!nm_device_is_activating (self)) return; - g_assert (self->priv->app_data); - nm_info ("Activation (%s): cancelling...", nm_device_get_iface (self)); /* Break the activation chain */ @@ -1105,22 +1040,18 @@ static void nm_device_deactivate (NMDeviceInterface *device) { NMDevice *self = NM_DEVICE (device); - NMData * app_data; NMIP4Config * config; g_return_if_fail (self != NULL); - g_return_if_fail (self->priv->app_data != NULL); nm_info ("Deactivating device %s.", nm_device_get_iface (self)); nm_device_deactivate_quickly (self); - app_data = self->priv->app_data; - /* Remove any device nameservers and domains */ if ((config = nm_device_get_ip4_config (self))) { - nm_named_manager_remove_ip4_config (app_data->named_manager, config); + nm_named_manager_remove_ip4_config (self->priv->app_data->named_manager, config); nm_device_set_ip4_config (self, NULL); } @@ -1296,13 +1227,13 @@ nm_device_update_ip4_address (NMDevice *self) const char * iface; g_return_if_fail (self != NULL); - g_return_if_fail (self->priv->app_data != NULL); - g_return_if_fail (nm_device_get_iface (self) != NULL); - - if ((sk = nm_dev_sock_open (self, DEV_GENERAL, __func__, NULL)) == NULL) - return; iface = nm_device_get_iface (self); + g_return_if_fail (iface != NULL); + + if ((sk = nm_dev_sock_open (iface, DEV_GENERAL, __func__, NULL)) == NULL) + return; + memset (&req, 0, sizeof (struct ifreq)); strncpy (req.ifr_name, iface, sizeof (req.ifr_name) - 1); @@ -1320,62 +1251,15 @@ nm_device_update_ip4_address (NMDevice *self) } -/* - * nm_device_set_up_down - * - * Set the up flag on the device on or off - * - */ -static void -nm_device_set_up_down (NMDevice *self, - gboolean up) -{ - g_return_if_fail (self != NULL); - - nm_system_device_set_up_down (self, up); - - /* - * Make sure that we have a valid MAC address, some cards reload firmware when they - * are brought up. - */ - nm_device_set_address (self); -} - - -/* - * Interface state functions: bring up, down, check - * - */ gboolean nm_device_is_up (NMDevice *self) { - NMSock * sk; - struct ifreq ifr; - int err; + g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); - g_return_val_if_fail (self != NULL, FALSE); + if (NM_DEVICE_GET_CLASS (self)->is_up) + return NM_DEVICE_GET_CLASS (self)->is_up (self); - if ((sk = nm_dev_sock_open (self, DEV_GENERAL, __FUNCTION__, NULL)) == NULL) - return (FALSE); - - /* Get device's flags */ - strncpy (ifr.ifr_name, nm_device_get_iface (self), sizeof (ifr.ifr_name) - 1); - - nm_ioctl_info ("%s: About to GET IFFLAGS.", nm_device_get_iface (self)); - err = ioctl (nm_dev_sock_get_fd (sk), SIOCGIFFLAGS, &ifr); - nm_ioctl_info ("%s: Done with GET IFFLAGS.", nm_device_get_iface (self)); - - nm_dev_sock_close (sk); - if (!err) - return (!((ifr.ifr_flags^IFF_UP) & IFF_UP)); - - if (errno != ENODEV) - { - nm_warning ("nm_device_is_up() could not get flags for device %s. errno = %d", - nm_device_get_iface (self), errno ); - } - - return FALSE; + return TRUE; } /* I really wish nm_v_wait_for_completion_or_timeout could translate these @@ -1386,56 +1270,65 @@ nm_completion_device_is_up_test (int tries, nm_completion_args args) { NMDevice *self = NM_DEVICE (args[0]); - gboolean *err = args[1]; - gboolean cancelable = GPOINTER_TO_INT (args[2]); - g_return_val_if_fail (self != NULL, TRUE); - g_return_val_if_fail (err != NULL, TRUE); - - *err = FALSE; - if (cancelable /* && nm_device_activation_should_cancel (self) */) { - *err = TRUE; - return TRUE; - } if (nm_device_is_up (self)) return TRUE; return FALSE; } void -nm_device_bring_up (NMDevice *self) +nm_device_bring_up (NMDevice *self, gboolean wait) { - g_return_if_fail (self != NULL); + g_return_if_fail (NM_IS_DEVICE (self)); - nm_device_set_up_down (self, TRUE); -} + if (nm_device_is_up (self)) + return; -gboolean -nm_device_bring_up_wait (NMDevice *self, - gboolean cancelable) -{ - gboolean err = FALSE; - nm_completion_args args; + nm_info ("Bringing up device %s", nm_device_get_iface (self)); - g_return_val_if_fail (self != NULL, TRUE); + nm_system_device_set_up_down (self, TRUE); + nm_device_update_ip4_address (self); + nm_device_set_address (self); - nm_device_bring_up (self); + if (NM_DEVICE_GET_CLASS (self)->bring_up) + NM_DEVICE_GET_CLASS (self)->bring_up (self); - args[0] = self; - args[1] = &err; - args[2] = GINT_TO_POINTER (cancelable); - nm_wait_for_completion (400, G_USEC_PER_SEC / 200, NULL, nm_completion_device_is_up_test, args); - if (err) - nm_info ("failed to bring up device %s", self->priv->iface); - return err; + if (wait) { + nm_completion_args args; + + args[0] = self; + nm_wait_for_completion (400, G_USEC_PER_SEC / 200, NULL, nm_completion_device_is_up_test, args); + } + + nm_device_state_changed (self, NM_DEVICE_STATE_DISCONNECTED); } void -nm_device_bring_down (NMDevice *self) +nm_device_bring_down (NMDevice *self, gboolean wait) { - g_return_if_fail (self != NULL); + g_return_if_fail (NM_IS_DEVICE (self)); - nm_device_set_up_down (self, FALSE); + if (!nm_device_is_up (self)) + return; + + nm_info ("Bringing down device %s", nm_device_get_iface (self)); + + if (nm_device_get_state (self) == NM_DEVICE_STATE_ACTIVATED) + nm_device_interface_deactivate (NM_DEVICE_INTERFACE (self)); + + if (NM_DEVICE_GET_CLASS (self)->bring_down) + NM_DEVICE_GET_CLASS (self)->bring_down (self); + + nm_system_device_set_up_down (self, FALSE); + + if (wait) { + nm_completion_args args; + + args[0] = self; + nm_wait_for_completion (400, G_USEC_PER_SEC / 200, NULL, nm_completion_device_is_up_test, args); + } + + nm_device_state_changed (self, NM_DEVICE_STATE_DOWN); } /* @@ -1472,6 +1365,8 @@ nm_device_dispose (GObject *object) * reference. */ + nm_device_bring_down (self, FALSE); + nm_system_device_free_system_config (self, self->priv->system_config_data); nm_device_set_ip4_config (self, NULL); @@ -1591,10 +1486,10 @@ nm_device_class_init (NMDeviceClass *klass) object_class->get_property = get_property; object_class->constructor = constructor; + klass->is_up = real_is_up; klass->activation_cancel_handler = real_activation_cancel_handler; klass->get_type_capabilities = real_get_type_capabilities; klass->get_generic_capabilities = real_get_generic_capabilities; - klass->start = real_start; klass->act_stage1_prepare = real_act_stage1_prepare; klass->act_stage2_config = real_act_stage2_config; klass->act_stage3_ip_config_start = real_act_stage3_ip_config_start; @@ -1643,13 +1538,22 @@ nm_device_class_init (NMDeviceClass *klass) void nm_device_state_changed (NMDevice *device, NMDeviceState state) { + const char *iface; + NMDeviceState old_state; + g_return_if_fail (NM_IS_DEVICE (device)); + iface = nm_device_get_iface (device); + old_state = device->priv->state; device->priv->state = state; switch (state) { + case NM_DEVICE_STATE_DOWN: + if (old_state == NM_DEVICE_STATE_ACTIVATED) + nm_device_interface_deactivate (NM_DEVICE_INTERFACE (device)); + break; case NM_DEVICE_STATE_ACTIVATED: - nm_info ("Activation (%s) successful, device activated.", nm_device_get_iface (device)); + nm_info ("Activation (%s) successful, device activated.", iface); break; case NM_DEVICE_STATE_FAILED: nm_info ("Activation (%s) failed.", nm_device_get_iface (device)); diff --git a/src/nm-device.h b/src/nm-device.h index 2b06c72a1..e67fcfd64 100644 --- a/src/nm-device.h +++ b/src/nm-device.h @@ -82,6 +82,7 @@ struct _NMDeviceClass void (* set_active_link) (NMDevice *self, gboolean active); void (* update_link) (NMDevice *self); + gboolean (* is_up) (NMDevice *self); void (* bring_up) (NMDevice *self); void (* bring_down) (NMDevice *self); @@ -90,8 +91,6 @@ struct _NMDeviceClass guint32 (* get_type_capabilities) (NMDevice *self); guint32 (* get_generic_capabilities) (NMDevice *self); - void (* init) (NMDevice *self); - void (* start) (NMDevice *self); NMActStageReturn (* act_stage1_prepare) (NMDevice *self, struct NMActRequest *req); NMActStageReturn (* act_stage2_config) (NMDevice *self, struct NMActRequest *req); NMActStageReturn (* act_stage3_ip_config_start)(NMDevice *self, @@ -114,8 +113,6 @@ struct _NMDeviceClass GType nm_device_get_type (void); -void nm_device_stop (NMDevice *self); - const char * nm_device_get_udi (NMDevice *dev); const char * nm_device_get_iface (NMDevice *dev); @@ -128,14 +125,7 @@ guint32 nm_device_get_type_capabilities (NMDevice *dev); struct NMData * nm_device_get_app_data (NMDevice *dev); -gboolean nm_device_get_removed (NMDevice *dev); -void nm_device_set_removed (NMDevice *dev, - const gboolean removed); - gboolean nm_device_has_active_link (NMDevice *dev); -void nm_device_set_active_link (NMDevice *dev, - const gboolean active); - guint32 nm_device_get_ip4_address (NMDevice *dev); void nm_device_update_ip4_address (NMDevice *dev); struct in6_addr * nm_device_get_ip6_address (NMDevice *dev); @@ -148,8 +138,10 @@ NMIP4Config * nm_device_get_ip4_config (NMDevice *dev); void nm_device_set_ip4_config (NMDevice *dev, NMIP4Config *config); -void nm_device_bring_down (NMDevice *dev); -gboolean nm_device_is_up (NMDevice *dev); +gboolean nm_device_is_up (NMDevice *dev); +void nm_device_bring_up (NMDevice *dev, gboolean wait); +void nm_device_bring_down (NMDevice *dev, gboolean wait); + void * nm_device_get_system_config_data (NMDevice *dev); diff --git a/src/nm-manager.c b/src/nm-manager.c index 1b3ca575b..a43eda6b3 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -58,7 +58,6 @@ device_stop_and_free (gpointer data, gpointer user_data) { NMDevice *device = NM_DEVICE (data); - nm_device_set_removed (device, TRUE); nm_device_interface_deactivate (NM_DEVICE_INTERFACE (device)); g_object_unref (device); } @@ -209,12 +208,10 @@ manager_set_wireless_enabled (NMManager *manager, gboolean enabled) /* Tear down all wireless devices */ for (iter = priv->devices; iter; iter = iter->next) { if (NM_IS_DEVICE_802_11_WIRELESS (iter->data)) { - NMDevice *dev = NM_DEVICE (iter->data); - - if (nm_device_get_state (dev) == NM_DEVICE_STATE_ACTIVATED) { - nm_device_interface_deactivate (NM_DEVICE_INTERFACE (dev)); - nm_device_bring_down (dev); - } + if (enabled) + nm_device_bring_up (NM_DEVICE (iter->data), FALSE); + else + nm_device_bring_down (NM_DEVICE (iter->data), FALSE); } } } @@ -252,6 +249,12 @@ nm_manager_add_device (NMManager *manager, NMDevice *device) g_signal_connect (device, "state-changed", G_CALLBACK (manager_device_state_changed), manager); + + if (!priv->sleeping) { + if (!NM_IS_DEVICE_802_11_WIRELESS (device) || priv->wireless_enabled) + nm_device_bring_up (device, TRUE); + } + nm_device_interface_deactivate (NM_DEVICE_INTERFACE (device)); manager_device_added (manager, device); @@ -280,9 +283,6 @@ nm_manager_remove_device (NMManager *manager, NMDevice *device) g_signal_handlers_disconnect_by_func (device, manager_device_state_changed, manager); - nm_device_set_removed (device, TRUE); - nm_device_stop (device); - manager_device_removed (manager, device); g_object_unref (device); break; @@ -407,13 +407,8 @@ nm_manager_sleep (NMManager *manager, gboolean sleep) /* Just deactivate and down all devices from the device list, * we'll remove them in 'wake' for speed's sake. */ - for (iter = priv->devices; iter; iter = iter->next) { - NMDevice *dev = NM_DEVICE (iter->data); - - nm_device_set_removed (dev, TRUE); - nm_device_deactivate_quickly (dev); - nm_system_device_set_up_down (dev, FALSE); - } + for (iter = priv->devices; iter; iter = iter->next) + nm_device_bring_down (NM_DEVICE (iter->data), FALSE); } else { nm_info ("Waking up from sleep."); diff --git a/src/supplicant-manager/nm-supplicant-interface.c b/src/supplicant-manager/nm-supplicant-interface.c index 3f8c0f4d0..b3cba5762 100644 --- a/src/supplicant-manager/nm-supplicant-interface.c +++ b/src/supplicant-manager/nm-supplicant-interface.c @@ -149,7 +149,7 @@ nm_supplicant_info_new (NMSupplicantInterface *interface, NMSupplicantInfo *info; info = g_slice_new0 (NMSupplicantInfo); - info->interface = interface; + info->interface = g_object_ref (interface); info->proxy = g_object_ref (proxy); info->store = store; @@ -160,7 +160,7 @@ static void nm_supplicant_info_set_call (NMSupplicantInfo *info, DBusGProxyCall *call) { if (call) { - nm_call_store_add (info->store, g_object_ref (info->proxy), (gpointer) call); + nm_call_store_add (info->store, info->proxy, (gpointer) call); info->call = call; } } @@ -174,6 +174,7 @@ nm_supplicant_info_destroy (gpointer user_data) nm_call_store_remove (info->store, G_OBJECT (info->proxy), info->call); g_object_unref (info->proxy); + g_object_unref (info->interface); g_slice_free (NMSupplicantInfo, info); }