diff --git a/ChangeLog b/ChangeLog index d9acee5c9..9176c3385 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2006-1-3 Dan Williams + + * src/NetworkManager.c + - Move link-checking/probing into the device subclasses + themselves + + * src/nm-device.[ch] + src/nm-device-802-11-wireless.c + src/nm-device-802-3-ethernet.c + - Do periodic link checking in device subclasses rather + than being triggered from NetworkManager.c + - discover_wireless_capabilities -> get_wireless_capabilities + - discover_generic_capabilities -> get_generic_capabilities + - Device subclass activation routines now return a value of type + NMActStageReturn to indicate what step to perform next + - Devices now override stage4_get_ip4_config if they choose + 2006-1-1 Dan Williams * src/nm-device-802-11-wireless.c diff --git a/src/NetworkManager.c b/src/NetworkManager.c index 77156c20f..df5575342 100644 --- a/src/NetworkManager.c +++ b/src/NetworkManager.c @@ -165,8 +165,7 @@ void nm_remove_device (NMData *data, NMDevice *dev) g_return_if_fail (dev != NULL); nm_device_set_removed (dev, TRUE); - nm_device_deactivate (dev); - nm_device_worker_thread_stop (dev); + nm_device_stop (dev); nm_dbus_schedule_device_status_change_signal (data, dev, NULL, DEVICE_REMOVED); g_object_unref (G_OBJECT (dev)); @@ -531,77 +530,15 @@ static void nm_print_usage (void) "\n"); } -/* - * nm_poll_and_update_wireless_link_state - * - * Called every 2s to poll wireless cards and determine if they have a link - * or not. - * - */ -static gboolean nm_poll_and_update_wireless_link_state (NMData *data) -{ - GSList * elt; - GSList * copy = NULL; - NMDevice * dev; - - g_return_val_if_fail (data != NULL, TRUE); - - if ((data->wireless_enabled == FALSE) || (data->asleep == TRUE)) - return (TRUE); - - /* Copy device list and ref devices to keep them around */ - if (nm_try_acquire_mutex (data->dev_list_mutex, __FUNCTION__)) - { - for (elt = data->dev_list; elt; elt = g_slist_next (elt)) - { - if ((dev = (NMDevice *)(elt->data))) - { - g_object_ref (G_OBJECT (dev)); - copy = g_slist_append (copy, dev); - } - } - nm_unlock_mutex (data->dev_list_mutex, __FUNCTION__); - } - - for (elt = copy; elt; elt = g_slist_next (elt)) - { - if ((dev = (NMDevice *)(elt->data))) - { - if (nm_device_is_802_11_wireless (dev) && !nm_device_is_activating (dev)) - { - NMDevice80211Wireless *wdev = NM_DEVICE_802_11_WIRELESS (dev); - nm_device_set_active_link (dev, nm_device_probe_link_state (dev)); - nm_device_802_11_wireless_update_signal_strength (wdev); - } - g_object_unref (G_OBJECT (dev)); - } - } - - g_slist_free (copy); - - return TRUE; -} - -static void nm_monitor_wireless_link_state (NMData *data) -{ - GSource *link_source; - link_source = g_timeout_source_new (NM_WIRELESS_LINK_STATE_POLL_INTERVAL); - g_source_set_callback (link_source, - (GSourceFunc) nm_poll_and_update_wireless_link_state, - data, NULL); - g_source_attach (link_source, nm_data->main_context); - g_source_unref (link_source); -} - static void nm_device_link_activated (NmNetlinkMonitor *monitor, const gchar *interface_name, NMData *data) { NMDevice *dev = NULL; - if (nm_try_acquire_mutex (data->dev_list_mutex, __FUNCTION__)) + if (nm_try_acquire_mutex (data->dev_list_mutex, __func__)) { if ((dev = nm_get_device_by_iface (data, interface_name))) g_object_ref (G_OBJECT (dev)); - nm_unlock_mutex (data->dev_list_mutex, __FUNCTION__); + nm_unlock_mutex (data->dev_list_mutex, __func__); } /* Don't do anything if we already have a link */ @@ -620,11 +557,11 @@ static void nm_device_link_deactivated (NmNetlinkMonitor *monitor, const gchar * { NMDevice *dev = NULL; - if (nm_try_acquire_mutex (data->dev_list_mutex, __FUNCTION__)) + if (nm_try_acquire_mutex (data->dev_list_mutex, __func__)) { if ((dev = nm_get_device_by_iface (data, interface_name))) g_object_ref (G_OBJECT (dev)); - nm_unlock_mutex (data->dev_list_mutex, __FUNCTION__); + nm_unlock_mutex (data->dev_list_mutex, __func__); } if (dev) @@ -940,7 +877,6 @@ int main( int argc, char *argv[] ) nm_system_enable_loopback (); /* Create watch functions that monitor cards for link status. */ - nm_monitor_wireless_link_state (nm_data); nm_monitor_wired_link_state (nm_data); /* Get modems, ISDN, and so on's configuration from the system */ diff --git a/src/nm-device-802-11-wireless.c b/src/nm-device-802-11-wireless.c index dfee98b0b..d12a94285 100644 --- a/src/nm-device-802-11-wireless.c +++ b/src/nm-device-802-11-wireless.c @@ -114,9 +114,13 @@ static int wireless_qual_to_percent (const struct iw_quality *qual, static gboolean is_associated (NMDevice80211Wireless *self); +static gboolean link_to_specific_ap (NMDevice80211Wireless *self, + NMAccessPoint *ap, + gboolean default_link); + static guint32 -real_discover_generic_capabilities (NMDevice *dev) +real_get_generic_capabilities (NMDevice *dev) { NMDevice80211Wireless * wdev; NMSock * sk; @@ -154,9 +158,9 @@ out: } static guint32 -discover_wireless_capabilities (NMDevice80211Wireless *self, - iwrange * range, - guint32 data_len) +get_wireless_capabilities (NMDevice80211Wireless *self, + iwrange * range, + guint32 data_len) { int minlen; guint32 caps = NM_802_11_CAP_NONE; @@ -265,35 +269,86 @@ real_init (NMDevice *dev) self->priv->we_version = range.we_version_compiled; /* 802.11 wireless-specific capabilities */ - self->priv->capabilities = discover_wireless_capabilities (self, &range, wrq.u.data.length); + self->priv->capabilities = get_wireless_capabilities (self, &range, wrq.u.data.length); } nm_dev_sock_close (sk); } } + +static gboolean +probe_link (NMDevice80211Wireless *self) +{ + gboolean link = FALSE; + NMActRequest * req; + + if ((req = nm_device_get_act_request (NM_DEVICE (self)))) + { + NMAccessPoint * ap; + if ((ap = nm_act_request_get_ap (req))) + link = link_to_specific_ap (self, ap, TRUE); + } + + return link; +} + + +static void +real_update_link (NMDevice *dev) +{ + NMDevice80211Wireless * self = NM_DEVICE_802_11_WIRELESS (dev); + + nm_device_set_active_link (NM_DEVICE (self), probe_link (self)); +} + + +/* + * nm_device_802_11_periodic_update + * + * Periodically update device statistics and link state. + * + */ +static gboolean +nm_device_802_11_periodic_update (gpointer data) +{ + NMDevice80211Wireless * self = NM_DEVICE_802_11_WIRELESS (data); + + g_return_val_if_fail (self != NULL, TRUE); + + nm_device_802_11_wireless_update_signal_strength (self); + nm_device_set_active_link (NM_DEVICE (self), probe_link (self)); + + return TRUE; +} + + static void real_start (NMDevice *dev) { NMDevice80211Wireless * self = NM_DEVICE_802_11_WIRELESS (dev); - guint32 caps; + GSource * source; + guint source_id; /* Start the scanning timeout for devices that can do scanning */ - caps = nm_device_get_capabilities (dev); - if (caps & NM_DEVICE_CAP_WIRELESS_SCAN) + if (nm_device_get_capabilities (dev) & NM_DEVICE_CAP_WIRELESS_SCAN) { - GSource *source = g_idle_source_new (); - guint source_id = 0; - NMWirelessScanCB *scan_cb; + NMWirelessScanCB * scan_cb; scan_cb = g_malloc0 (sizeof (NMWirelessScanCB)); scan_cb->dev = self; scan_cb->force = TRUE; + source = g_idle_source_new (); g_source_set_callback (source, nm_device_802_11_wireless_scan, scan_cb, NULL); source_id = g_source_attach (source, nm_device_get_main_context (dev)); g_source_unref (source); } + /* Peridoically update link status and signal strength */ + source = g_timeout_source_new (2000); + g_source_set_callback (source, nm_device_802_11_periodic_update, self, NULL); + source_id = g_source_attach (source, nm_device_get_main_context (dev)); + g_source_unref (source); } static void @@ -875,12 +930,14 @@ nm_device_802_11_wireless_set_mode (NMDevice80211Wireless *self, else { if (errno != ENODEV) + { nm_warning ("nm_device_set_mode (%s): error setting card to %s mode: %s", iface, mode == IW_MODE_INFRA ? "Infrastructure" : \ (mode == IW_MODE_ADHOC ? "Ad-Hoc" : \ (mode == IW_MODE_AUTO ? "Auto" : "unknown")), strerror (errno)); + } } nm_dev_sock_close (sk); } @@ -1938,7 +1995,7 @@ set_wireless_config (NMDevice80211Wireless *self, * Create an ad-hoc network (rather than associating with one). * */ -static gboolean +static NMActStageReturn wireless_configure_adhoc (NMDevice80211Wireless *self, NMAccessPoint *ap, NMActRequest *req) @@ -1955,8 +2012,7 @@ wireless_configure_adhoc (NMDevice80211Wireless *self, int err; const char * iface; - g_return_val_if_fail (req != NULL, FALSE); - + g_assert (req); data = nm_act_request_get_data (req); g_assert (data); @@ -1969,9 +2025,7 @@ wireless_configure_adhoc (NMDevice80211Wireless *self, for (i = 0; i < num_freqs; i++) card_freqs[i] = self->priv->freqs[i]; - /* We need to find a clear wireless channel to use. We will - * only use 802.11b channels for now. - */ + /* Compile a list of wireless channels that are currently in use */ iter = nm_ap_list_iter_new (nm_device_802_11_wireless_ap_list_get (self)); while ((tmp_ap = nm_ap_list_iter_next (iter))) { @@ -1985,13 +2039,13 @@ wireless_configure_adhoc (NMDevice80211Wireless *self, nm_ap_list_iter_free (iter); if ((sk = nm_dev_sock_open (NM_DEVICE (self), DEV_WIRELESS, __func__, NULL)) == NULL) - return FALSE; + return NM_ACT_STAGE_RETURN_FAILURE; iface = nm_device_get_iface (NM_DEVICE (self)); err = iw_get_range_info (nm_dev_sock_get_fd (sk), iface, &range); nm_dev_sock_close (sk); if (err < 0) - return FALSE; + return NM_ACT_STAGE_RETURN_FAILURE; /* Ok, find the first non-zero freq in our table and use it. * For now we only try to use a channel in the 802.11b channel @@ -2020,14 +2074,14 @@ wireless_configure_adhoc (NMDevice80211Wireless *self, } if (!freq_to_use) - return FALSE; + return NM_ACT_STAGE_RETURN_FAILURE; nm_ap_set_freq (ap, freq_to_use); nm_info ("Will create network '%s' with frequency %f.", nm_ap_get_essid (ap), nm_ap_get_freq (ap)); set_wireless_config (self, ap); - return TRUE; + return NM_ACT_STAGE_RETURN_SUCCESS; } @@ -2233,21 +2287,21 @@ ap_need_key (NMDevice80211Wireless *self, NMAccessPoint *ap) * Configure a wireless device for association with a particular access point. * */ -static gboolean +static NMActStageReturn wireless_configure_infra (NMDevice80211Wireless *self, NMAccessPoint *ap, NMActRequest *req) { - NMData * data; - gboolean success = FALSE; - const char * iface; - - g_return_val_if_fail (req != NULL, FALSE); + NMData * data; + NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE; + const char * iface; + gboolean link = FALSE; + g_assert (req); data = nm_act_request_get_data (req); g_assert (data); - nm_device_bring_up_wait (NM_DEVICE (self), 1); + nm_device_bring_up_wait (NM_DEVICE (self), TRUE); iface = nm_device_get_iface (NM_DEVICE (self)); nm_info ("Activation (%s/wireless) Stage 2 (Device Configure) will connect to access point '%s'.", @@ -2256,64 +2310,81 @@ wireless_configure_infra (NMDevice80211Wireless *self, if (ap_need_key (self, ap)) { nm_dbus_get_user_key_for_network (data->dbus_connection, req, FALSE); -/* FIXME */ -/* Deal with stuff like this */ - return FALSE; + return NM_ACT_STAGE_RETURN_POSTPONE; } - while (success == FALSE) - { - gboolean link = FALSE; + set_wireless_config (self, ap); + if (nm_device_wireless_wait_for_link (self, nm_ap_get_essid (ap))) + ret = NM_ACT_STAGE_RETURN_SUCCESS; - if (nm_device_activation_should_cancel (NM_DEVICE (self))) - break; + if (nm_device_activation_should_cancel (NM_DEVICE (self))) + return NM_ACT_STAGE_RETURN_SUCCESS; - set_wireless_config (self, ap); - - success = link = nm_device_wireless_wait_for_link (self, nm_ap_get_essid (ap)); - - if (nm_device_activation_should_cancel (NM_DEVICE (self))) - break; - - if (!link) - { - nm_info ("Activation (%s/wireless): no hardware link to '%s'.", - iface, nm_ap_get_essid (ap) ? nm_ap_get_essid (ap) : "(none)"); - break; - } - } - - if (success) + if (ret == NM_ACT_STAGE_RETURN_SUCCESS) { nm_info ("Activation (%s/wireless) Stage 2 (Device Configure) successful. Connected to access point '%s'.", iface, nm_ap_get_essid (ap) ? nm_ap_get_essid (ap) : "(none)"); } -/* -What's this for again? - else if (!nm_device_activation_should_cancel (NM_DEVICE (self)) && (nm_act_request_get_stage (req) != NM_ACT_STAGE_NEED_USER_KEY)) -*/ + else + { + nm_info ("Activation (%s/wireless): no hardware link to '%s'.", + iface, nm_ap_get_essid (ap) ? nm_ap_get_essid (ap) : "(none)"); + } - return success; + return ret; } -static gboolean -real_activation_config (NMDevice *dev, NMActRequest *req) +static NMActStageReturn +real_act_stage2_config (NMDevice *dev, + NMActRequest *req) { NMDevice80211Wireless * self = NM_DEVICE_802_11_WIRELESS (dev); NMAccessPoint * ap = nm_act_request_get_ap (req); - gboolean success = FALSE; + NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE; g_assert (ap); if (nm_ap_get_user_created (ap)) - success = wireless_configure_adhoc (self, ap, req); + ret = wireless_configure_adhoc (self, ap, req); else - success = wireless_configure_infra (self, ap, req); + ret = wireless_configure_infra (self, ap, req); - return success; + return ret; } + +static NMActStageReturn +real_act_stage4_get_ip4_config (NMDevice *dev, + NMActRequest *req, + NMIP4Config **config) +{ + NMDevice80211Wireless * self = NM_DEVICE_802_11_WIRELESS (dev); + NMAccessPoint * ap = nm_act_request_get_ap (req); + NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE; + NMIP4Config * real_config = NULL; + + g_assert (ap); + if (nm_ap_get_user_created (ap)) + { + real_config = nm_device_new_ip4_autoip_config (NM_DEVICE (self)); + ret = NM_ACT_STAGE_RETURN_SUCCESS; + } + else + { + NMDevice80211WirelessClass * klass; + NMDeviceClass * parent_class; + + /* Chain up to parent */ + klass = NM_DEVICE_802_11_WIRELESS_GET_CLASS (self); + parent_class = NM_DEVICE_CLASS (g_type_class_peek_parent (klass)); + ret = parent_class->act_stage4_get_ip4_config (dev, req, &real_config); + } + + return ret; +} + + static guint32 real_get_type_capabilities (NMDevice *dev) { @@ -2323,26 +2394,6 @@ real_get_type_capabilities (NMDevice *dev) } -static gboolean -real_probe_link (NMDevice *dev) -{ - NMDevice80211Wireless * self = NM_DEVICE_802_11_WIRELESS (dev); - gboolean link = FALSE; - NMAccessPoint * ap; - NMActRequest * req; - - if ((req = nm_device_get_act_request (dev))) - { - if ((ap = nm_act_request_get_ap (req))) - link = link_to_specific_ap (self, ap, TRUE); - } - - nm_device_802_11_wireless_update_signal_strength (self); - - return link; -} - - static void nm_device_802_11_wireless_dispose (GObject *object) { @@ -2397,12 +2448,12 @@ nm_device_802_11_wireless_class_init (NMDevice80211WirelessClass *klass) object_class->finalize = nm_device_802_11_wireless_finalize; parent_class->get_type_capabilities = real_get_type_capabilities; - parent_class->discover_generic_capabilities = real_discover_generic_capabilities; + parent_class->get_generic_capabilities = real_get_generic_capabilities; parent_class->init = real_init; parent_class->start = real_start; parent_class->deactivate = real_deactivate; - parent_class->activation_config = real_activation_config; - parent_class->probe_link = real_probe_link; + parent_class->act_stage2_config = real_act_stage2_config; + parent_class->update_link = real_update_link; g_type_class_add_private (object_class, sizeof (NMDevice80211WirelessPrivate)); } diff --git a/src/nm-device-802-3-ethernet.c b/src/nm-device-802-3-ethernet.c index ab560056e..3dc738ef2 100644 --- a/src/nm-device-802-3-ethernet.c +++ b/src/nm-device-802-3-ethernet.c @@ -41,6 +41,7 @@ struct _NMDevice8023EthernetPrivate gboolean dispose_has_run; struct ether_addr hw_addr; + char * carrier_file_path; }; static gboolean supports_mii_carrier_detect (NMDevice8023Ethernet *dev); @@ -57,6 +58,81 @@ nm_device_802_3_ethernet_init (NMDevice8023Ethernet * self) } +static gboolean +probe_link (NMDevice8023Ethernet *self) +{ + gboolean link = FALSE; + gchar * contents; + gsize length; + guint32 caps; + + if (nm_device_get_removed (NM_DEVICE (self))) + return FALSE; + + if (g_file_get_contents (self->priv->carrier_file_path, &contents, &length, NULL)) + { + link = (gboolean) atoi (contents); + g_free (contents); + } + + /* We say that non-carrier-detect devices always have a link, because + * they never get auto-selected by NM. User has to force them on us, + * so we just hope the user knows whether or not the cable's plugged in. + */ + caps = nm_device_get_capabilities (NM_DEVICE (self)); + if (!(caps & NM_DEVICE_CAP_CARRIER_DETECT)) + link = TRUE; + + return link; +} + + +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_802_3_periodic_update + * + * Periodically update device statistics and link state. + * + */ +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)); + + return TRUE; +} + + +static void +real_start (NMDevice *dev) +{ + NMDevice8023Ethernet * self = NM_DEVICE_802_3_ETHERNET (dev); + GSource * source; + guint source_id; + + self->priv->carrier_file_path = g_strdup_printf ("/sys/class/net/%s/carrier", + nm_device_get_iface (NM_DEVICE (dev))); + + /* Peridoically update link status and signal strength */ + source = g_timeout_source_new (2000); + g_source_set_callback (source, nm_device_802_3_periodic_update, self, NULL); + source_id = g_source_attach (source, nm_device_get_main_context (dev)); + g_source_unref (source); +} + + /* * nm_device_get_hw_address * @@ -74,7 +150,7 @@ nm_device_802_3_ethernet_get_address (NMDevice8023Ethernet *self, struct ether_a static guint32 -real_discover_generic_capabilities (NMDevice *dev) +real_get_generic_capabilities (NMDevice *dev) { NMDevice8023Ethernet * self = NM_DEVICE_802_3_ETHERNET (dev); guint32 caps = NM_DEVICE_CAP_NONE; @@ -102,13 +178,12 @@ real_discover_generic_capabilities (NMDevice *dev) return caps; } -static gboolean -real_activation_config (NMDevice *dev, NMActRequest *req) +static NMActStageReturn +real_act_stage2_config (NMDevice *dev, NMActRequest *req) { NMData * data; - g_return_val_if_fail (req != NULL, FALSE); - + g_assert (req); data = nm_act_request_get_data (req); g_assert (data); @@ -116,39 +191,6 @@ real_activation_config (NMDevice *dev, NMActRequest *req) } -static gboolean -real_probe_link (NMDevice *dev) -{ - NMDevice8023Ethernet * self = NM_DEVICE_802_3_ETHERNET (dev); - gboolean link = FALSE; - gchar * contents; - gchar * carrier_path; - gsize length; - guint32 caps; - - if (nm_device_get_removed (dev)) - return FALSE; - - carrier_path = g_strdup_printf ("/sys/class/net/%s/carrier", nm_device_get_iface (dev)); - if (g_file_get_contents (carrier_path, &contents, &length, NULL)) - { - link = (gboolean) atoi (contents); - g_free (contents); - } - g_free (carrier_path); - - /* We say that non-carrier-detect devices always have a link, because - * they never get auto-selected by NM. User has to force them on us, - * so we just hope the user knows whether or not the cable's plugged in. - */ - caps = nm_device_get_capabilities (dev); - if (!(caps & NM_DEVICE_CAP_CARRIER_DETECT)) - link = TRUE; - - return link; - -} - static void nm_device_802_3_ethernet_dispose (GObject *object) { @@ -182,6 +224,8 @@ nm_device_802_3_ethernet_finalize (GObject *object) NMDevice8023EthernetClass * klass = NM_DEVICE_802_3_ETHERNET_GET_CLASS (object); NMDeviceClass * parent_class; + g_free (self->priv->carrier_file_path); + /* Chain up to the parent class */ parent_class = NM_DEVICE_CLASS (g_type_class_peek_parent (klass)); G_OBJECT_CLASS (parent_class)->finalize (object); @@ -197,9 +241,10 @@ nm_device_802_3_ethernet_class_init (NMDevice8023EthernetClass *klass) object_class->dispose = nm_device_802_3_ethernet_dispose; object_class->finalize = nm_device_802_3_ethernet_finalize; - parent_class->activation_config = real_activation_config; - parent_class->discover_generic_capabilities = real_discover_generic_capabilities; - parent_class->probe_link = real_probe_link; + parent_class->act_stage2_config = real_act_stage2_config; + parent_class->get_generic_capabilities = real_get_generic_capabilities; + parent_class->start = real_start; + parent_class->update_link = real_update_link; g_type_class_add_private (object_class, sizeof (NMDevice8023EthernetPrivate)); } diff --git a/src/nm-device-private.h b/src/nm-device-private.h index 67c1d4d7c..edf2edf78 100644 --- a/src/nm-device-private.h +++ b/src/nm-device-private.h @@ -24,15 +24,10 @@ #include "nm-device.h" - -void nm_device_set_udi (NMDevice *dev, - const char *udi); - -void nm_device_set_device_type (NMDevice *self, - const NMDeviceType type); - gboolean nm_device_is_activated (NMDevice *dev); GMainContext * nm_device_get_main_context (NMDevice *dev); +NMIP4Config * nm_device_new_ip4_autoip_config (NMDevice *self); + #endif /* NM_DEVICE_PRIVATE_H */ diff --git a/src/nm-device.c b/src/nm-device.c index 0c6de06bd..d7b5bdf11 100644 --- a/src/nm-device.c +++ b/src/nm-device.c @@ -177,17 +177,21 @@ nm_device_new (const char *iface, dev->priv->app_data = app_data; dev->priv->type = type; - dev->priv->capabilities |= NM_DEVICE_GET_CLASS (dev)->discover_generic_capabilities (dev); + dev->priv->capabilities |= NM_DEVICE_GET_CLASS (dev)->get_generic_capabilities (dev); + if (!(dev->priv->capabilities & NM_DEVICE_CAP_NM_SUPPORTED)) + { + g_object_unref (G_OBJECT (dev)); + return NULL; + } /* Device thread's main loop */ dev->priv->context = g_main_context_new (); dev->priv->loop = g_main_loop_new (dev->priv->context, FALSE); /* Have to bring the device up before checking link status and other stuff */ - nm_device_bring_up_wait (dev, 0); + nm_device_bring_up_wait (dev, FALSE); -// nm_device_set_active_link (dev, nm_device_probe_link_state (dev)); -// nm_device_update_ip4_address (dev); + nm_device_update_ip4_address (dev); /* FIXME */ #if 0 nm_device_update_hw_address (dev); @@ -252,7 +256,7 @@ nm_device_init (NMDevice * self) } static guint32 -real_discover_generic_capabilities (NMDevice *dev) +real_get_generic_capabilities (NMDevice *dev) { return 0; } @@ -295,10 +299,13 @@ nm_device_worker (gpointer user_data) void -nm_device_worker_thread_stop (NMDevice *self) +nm_device_stop (NMDevice *self) { g_return_if_fail (self != NULL); + nm_device_deactivate (self); + nm_device_bring_down (self); + if (self->priv->loop) g_main_loop_quit (self->priv->loop); if (self->priv->worker) @@ -392,19 +399,6 @@ nm_device_get_udi (NMDevice *self) return self->priv->udi; } -void -nm_device_set_udi (NMDevice *self, - const char *udi) -{ - g_return_if_fail (self != NULL); - g_return_if_fail (udi != NULL); - - if (self->priv->udi) - g_free (self->priv->udi); - self->priv->udi = g_strdup (udi); -} - - /* * Get/set functions for iface */ @@ -440,14 +434,6 @@ nm_device_get_device_type (NMDevice *self) return self->priv->type; } -void -nm_device_set_device_type (NMDevice *self, const NMDeviceType type) -{ - g_return_if_fail (self != NULL); - - self->priv->type = type; -} - static gboolean real_is_test_device (NMDevice *dev) @@ -604,44 +590,6 @@ nm_device_set_active_link (NMDevice *self, } -static gboolean -real_probe_link (NMDevice *dev) -{ - return FALSE; -} - -/* - * nm_device_probe_link_state - * - * Return the current link state of the device. - * - */ -gboolean -nm_device_probe_link_state (NMDevice *self) -{ - gboolean link = FALSE; - - g_return_val_if_fail (self != NULL, FALSE); - - if (!nm_device_is_up (self)) - nm_device_bring_up (self); - - link = NM_DEVICE_GET_CLASS (self)->probe_link (self); - -#if 0 - if (nm_device_is_802_11_wireless (dev)) - { - link = nm_device_probe_wireless_link_state (dev); - nm_device_update_signal_strength (dev); - } - else if (nm_device_is_802_3_ethernet (dev)) - link = nm_device_probe_wired_link_state (dev); -#endif - - return link; -} - - /* * nm_device_activation_start * @@ -697,6 +645,7 @@ nm_device_activate_stage1_device_prepare (NMActRequest *req) NMAccessPoint *ap; NMAPSecurity * security; const char * iface; + NMActStageReturn ret; g_return_val_if_fail (req != NULL, FALSE); @@ -709,13 +658,25 @@ nm_device_activate_stage1_device_prepare (NMActRequest *req) iface = nm_device_get_iface (self); nm_info ("Activation (%s) Stage 1 (Device Prepare) started...", iface); - NM_DEVICE_GET_CLASS (self)->activation_prepare (self, req); + ret = NM_DEVICE_GET_CLASS (self)->act_stage1_prepare (self, req); + if (ret == NM_ACT_STAGE_RETURN_POSTPONE) + goto out; + else if (ret == NM_ACT_STAGE_RETURN_FAILURE) + { + nm_policy_schedule_activation_failed (req); + goto out; + } + g_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS); if (nm_device_activation_should_cancel (self)) + { nm_device_schedule_activation_handle_cancel (req); - else - nm_device_activate_schedule_stage2_device_config (req); + goto out; + } + nm_device_activate_schedule_stage2_device_config (req); + +out: nm_info ("Activation (%s) Stage 1 (Device Prepare) complete.", iface); return FALSE; } @@ -747,18 +708,54 @@ nm_device_activate_schedule_stage1_device_prepare (NMActRequest *req) g_source_unref (source); } -static gboolean -real_activation_prepare (NMDevice *dev, NMActRequest *req) +static NMActStageReturn +real_act_stage1_prepare (NMDevice *dev, NMActRequest *req) { /* Nothing to do */ - return TRUE; + return NM_ACT_STAGE_RETURN_SUCCESS; } -static gboolean -real_activation_config (NMDevice *dev, NMActRequest *req) +static NMActStageReturn +real_act_stage2_config (NMDevice *dev, NMActRequest *req) { /* Nothing to do */ - return TRUE; + return NM_ACT_STAGE_RETURN_SUCCESS; +} + +static NMActStageReturn +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; + + g_return_val_if_fail (config != NULL, NM_ACT_STAGE_RETURN_FAILURE); + 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 (data->dhcp_manager, req); + else + real_config = nm_system_device_new_ip4_system_config (self); + + if (real_config) + { + *config = real_config; + ret = NM_ACT_STAGE_RETURN_SUCCESS; + } + else + { + /* Make sure device is up even if config fails */ + if (!nm_device_is_up (self)) + nm_device_bring_up (self); + } + + return ret; } @@ -775,6 +772,7 @@ nm_device_activate_stage2_device_config (NMActRequest *req) NMDevice * self; NMData * data; const char * iface; + NMActStageReturn ret; g_return_val_if_fail (req != NULL, FALSE); @@ -797,17 +795,25 @@ nm_device_activate_stage2_device_config (NMActRequest *req) goto out; } - if (!NM_DEVICE_GET_CLASS (self)->activation_config (self, req)) + ret = NM_DEVICE_GET_CLASS (self)->act_stage2_config (self, req); + if (ret == NM_ACT_STAGE_RETURN_POSTPONE) + goto out; + else if (ret == NM_ACT_STAGE_RETURN_FAILURE) { nm_policy_schedule_activation_failed (req); goto out; } + g_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS); nm_info ("Activation (%s) Stage 2 (Device Configure) successful.", iface); - nm_device_activate_schedule_stage3_ip_config_start (req); if (nm_device_activation_should_cancel (self)) + { nm_device_schedule_activation_handle_cancel (req); + goto out; + } + + nm_device_activate_schedule_stage3_ip_config_start (req); out: nm_info ("Activation (%s) Stage 2 (Device Configure) complete.", iface); @@ -931,7 +937,7 @@ nm_device_activate_schedule_stage3_ip_config_start (NMActRequest *req) * Build up an IP config with a Link Local address * */ -static NMIP4Config * +NMIP4Config * nm_device_new_ip4_autoip_config (NMDevice *self) { struct in_addr ip; @@ -968,6 +974,7 @@ nm_device_activate_stage4_ip_config_get (NMActRequest *req) NMDevice * self = NULL; NMAccessPoint * ap = NULL; NMIP4Config * ip4_config = NULL; + NMActStageReturn ret; g_return_val_if_fail (req != NULL, FALSE); @@ -977,12 +984,6 @@ nm_device_activate_stage4_ip_config_get (NMActRequest *req) self = nm_act_request_get_dev (req); g_assert (self); - if (nm_device_is_802_11_wireless (self)) - { - ap = nm_act_request_get_ap (req); - g_assert (ap); - } - nm_info ("Activation (%s) Stage 4 (IP Configure Get) started...", nm_device_get_iface (self)); if (nm_device_activation_should_cancel (self)) @@ -991,12 +992,15 @@ nm_device_activate_stage4_ip_config_get (NMActRequest *req) goto out; } - if (ap && nm_ap_get_user_created (ap)) - ip4_config = nm_device_new_ip4_autoip_config (self); - else if (nm_device_get_use_dhcp (self)) - ip4_config = nm_dhcp_manager_get_ip4_config (data->dhcp_manager, req); - else - ip4_config = nm_system_device_new_ip4_system_config (self); + ret = NM_DEVICE_GET_CLASS (self)->act_stage4_get_ip4_config (self, req, &ip4_config); + if (ret == NM_ACT_STAGE_RETURN_POSTPONE) + goto out; + else if (!ip4_config || (ret == NM_ACT_STAGE_RETURN_FAILURE)) + { + nm_policy_schedule_activation_failed (req); + goto out; + } + g_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS); if (nm_device_activation_should_cancel (self)) { @@ -1004,29 +1008,8 @@ nm_device_activate_stage4_ip_config_get (NMActRequest *req) goto out; } - if (ip4_config) - { - nm_act_request_set_ip4_config (req, ip4_config); - nm_device_activate_schedule_stage5_ip_config_commit (req); - } - else - { - /* Interfaces cannot be down if they are the active interface, - * otherwise we cannot use them for scanning or link detection. - */ - if (nm_device_is_802_11_wireless (self)) - { - NMDevice80211Wireless *wdev = NM_DEVICE_802_11_WIRELESS (self); - - nm_device_802_11_wireless_set_essid (wdev, ""); - nm_device_802_11_wireless_set_wep_enc_key (wdev, NULL, 0); - } - - if (!nm_device_is_up (self)) - nm_device_bring_up (self); - - nm_policy_schedule_activation_failed (req); - } + nm_act_request_set_ip4_config (req, ip4_config); + nm_device_activate_schedule_stage5_ip_config_commit (req); out: nm_info ("Activation (%s) Stage 4 (IP Configure Get) complete.", nm_device_get_iface (self)); @@ -1206,7 +1189,8 @@ nm_device_activate_stage5_ip_config_commit (NMActRequest *req) nm_system_device_add_ip6_link_address (self); nm_system_restart_mdns_responder (); nm_system_activate_nis (self->priv->ip4_config); - nm_device_set_active_link (self, nm_device_probe_link_state (self)); + if (NM_DEVICE_GET_CLASS (self)->update_link) + NM_DEVICE_GET_CLASS (self)->update_link (self); nm_policy_schedule_activation_finish (req); } else @@ -1644,14 +1628,7 @@ nm_device_update_ip4_address (NMDevice *self) g_return_if_fail (self->priv->app_data != NULL); g_return_if_fail (nm_device_get_iface (self) != NULL); - /* Test devices get a nice, bogus IP address */ - if (nm_device_is_test_device (self)) - { - self->priv->ip4_address = 0x07030703; - return; - } - - if ((sk = nm_dev_sock_open (self, DEV_GENERAL, __FUNCTION__, NULL)) == NULL) + if ((sk = nm_dev_sock_open (self, DEV_GENERAL, __func__, NULL)) == NULL) return; iface = nm_device_get_iface (self); @@ -1693,7 +1670,7 @@ nm_device_set_up_down (NMDevice *self, */ /* FIXME */ #if 0 - if (!nm_ethernet_address_is_valid (&(self->priv->hw_addr))) + if (up && !nm_ethernet_address_is_valid (&(self->priv->hw_addr))) nm_device_update_hw_address (self); #endif } @@ -1876,8 +1853,7 @@ nm_device_dispose (GObject *object) * reference. */ - nm_device_worker_thread_stop (self); - nm_device_bring_down (self); + nm_device_stop (self); nm_system_device_free_system_config (self, self->priv->system_config_data); if (self->priv->ip4_config) @@ -1927,11 +1903,11 @@ nm_device_class_init (NMDeviceClass *klass) klass->is_test_device = real_is_test_device; klass->cancel_activation = real_cancel_activation; klass->get_type_capabilities = real_get_type_capabilities; - klass->discover_generic_capabilities = real_discover_generic_capabilities; + klass->get_generic_capabilities = real_get_generic_capabilities; klass->start = real_start; - klass->activation_prepare = real_activation_prepare; - klass->activation_config = real_activation_config; - klass->probe_link = real_probe_link; + klass->act_stage1_prepare = real_act_stage1_prepare; + klass->act_stage2_config = real_act_stage2_config; + klass->act_stage4_get_ip4_config = real_act_stage4_get_ip4_config; g_type_class_add_private (object_class, sizeof (NMDevicePrivate)); } diff --git a/src/nm-device.h b/src/nm-device.h index 1d55793f7..e7f377cf5 100644 --- a/src/nm-device.h +++ b/src/nm-device.h @@ -40,6 +40,13 @@ typedef enum NMWirelessScanInterval NM_WIRELESS_SCAN_INTERVAL_INACTIVE } NMWirelessScanInterval; +typedef enum NMActStageReturn +{ + NM_ACT_STAGE_RETURN_FAILURE = 0, + NM_ACT_STAGE_RETURN_SUCCESS, + NM_ACT_STAGE_RETURN_POSTPONE +} NMActStageReturn; + G_BEGIN_DECLS @@ -73,22 +80,21 @@ struct _NMDeviceClass const char * (* has_active_link) (NMDevice *self); void (* set_active_link) (NMDevice *self, gboolean active); - gboolean (* probe_link) (NMDevice *self); - - guint32 (* get_ip4_address) (NMDevice *self); - struct in6_addr * (* get_ip6_address) (NMDevice *self); + void (* update_link) (NMDevice *self); void (* bring_up) (NMDevice *self); void (* bring_down) (NMDevice *self); - gboolean (* is_up) (NMDevice *self); - guint32 (* get_type_capabilities) (NMDevice *self); - guint32 (* discover_generic_capabilities) (NMDevice *self); + guint32 (* get_type_capabilities) (NMDevice *self); + guint32 (* get_generic_capabilities) (NMDevice *self); void (* init) (NMDevice *self); void (* start) (NMDevice *self); - gboolean (* activation_prepare) (NMDevice *self, struct NMActRequest * req); - gboolean (* activation_config) (NMDevice *self, struct NMActRequest * req); + NMActStageReturn (* act_stage1_prepare) (NMDevice *self, struct NMActRequest * req); + NMActStageReturn (* act_stage2_config) (NMDevice *self, struct NMActRequest * req); + NMActStageReturn (* act_stage4_get_ip4_config) (NMDevice *self, + struct NMActRequest * req, + NMIP4Config **config); void (* deactivate) (NMDevice *self); void (* cancel_activation) (NMDevice *self); }; @@ -102,7 +108,7 @@ NMDevice * nm_device_new (const char *iface, NMDeviceType test_dev_type, struct NMData *app_data); -void nm_device_worker_thread_stop (NMDevice *self); +void nm_device_stop (NMDevice *self); const char * nm_device_get_udi (NMDevice *dev);