2006-1-3 Dan Williams <dcbw@redhat.com>

* 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


git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@1249 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
This commit is contained in:
Dan Williams
2006-01-03 17:07:07 +00:00
parent d724f08c8a
commit d639dbeac0
7 changed files with 367 additions and 341 deletions

View File

@@ -1,3 +1,20 @@
2006-1-3 Dan Williams <dcbw@redhat.com>
* 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 <dcbw@redhat.com> 2006-1-1 Dan Williams <dcbw@redhat.com>
* src/nm-device-802-11-wireless.c * src/nm-device-802-11-wireless.c

View File

@@ -165,8 +165,7 @@ void nm_remove_device (NMData *data, NMDevice *dev)
g_return_if_fail (dev != NULL); g_return_if_fail (dev != NULL);
nm_device_set_removed (dev, TRUE); nm_device_set_removed (dev, TRUE);
nm_device_deactivate (dev); nm_device_stop (dev);
nm_device_worker_thread_stop (dev);
nm_dbus_schedule_device_status_change_signal (data, dev, NULL, DEVICE_REMOVED); nm_dbus_schedule_device_status_change_signal (data, dev, NULL, DEVICE_REMOVED);
g_object_unref (G_OBJECT (dev)); g_object_unref (G_OBJECT (dev));
@@ -531,77 +530,15 @@ static void nm_print_usage (void)
"\n"); "\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) static void nm_device_link_activated (NmNetlinkMonitor *monitor, const gchar *interface_name, NMData *data)
{ {
NMDevice *dev = NULL; 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))) if ((dev = nm_get_device_by_iface (data, interface_name)))
g_object_ref (G_OBJECT (dev)); 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 */ /* 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; 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))) if ((dev = nm_get_device_by_iface (data, interface_name)))
g_object_ref (G_OBJECT (dev)); g_object_ref (G_OBJECT (dev));
nm_unlock_mutex (data->dev_list_mutex, __FUNCTION__); nm_unlock_mutex (data->dev_list_mutex, __func__);
} }
if (dev) if (dev)
@@ -940,7 +877,6 @@ int main( int argc, char *argv[] )
nm_system_enable_loopback (); nm_system_enable_loopback ();
/* Create watch functions that monitor cards for link status. */ /* Create watch functions that monitor cards for link status. */
nm_monitor_wireless_link_state (nm_data);
nm_monitor_wired_link_state (nm_data); nm_monitor_wired_link_state (nm_data);
/* Get modems, ISDN, and so on's configuration from the system */ /* Get modems, ISDN, and so on's configuration from the system */

View File

@@ -114,9 +114,13 @@ static int wireless_qual_to_percent (const struct iw_quality *qual,
static gboolean is_associated (NMDevice80211Wireless *self); static gboolean is_associated (NMDevice80211Wireless *self);
static gboolean link_to_specific_ap (NMDevice80211Wireless *self,
NMAccessPoint *ap,
gboolean default_link);
static guint32 static guint32
real_discover_generic_capabilities (NMDevice *dev) real_get_generic_capabilities (NMDevice *dev)
{ {
NMDevice80211Wireless * wdev; NMDevice80211Wireless * wdev;
NMSock * sk; NMSock * sk;
@@ -154,9 +158,9 @@ out:
} }
static guint32 static guint32
discover_wireless_capabilities (NMDevice80211Wireless *self, get_wireless_capabilities (NMDevice80211Wireless *self,
iwrange * range, iwrange * range,
guint32 data_len) guint32 data_len)
{ {
int minlen; int minlen;
guint32 caps = NM_802_11_CAP_NONE; guint32 caps = NM_802_11_CAP_NONE;
@@ -265,35 +269,86 @@ real_init (NMDevice *dev)
self->priv->we_version = range.we_version_compiled; self->priv->we_version = range.we_version_compiled;
/* 802.11 wireless-specific capabilities */ /* 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); 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 static void
real_start (NMDevice *dev) real_start (NMDevice *dev)
{ {
NMDevice80211Wireless * self = NM_DEVICE_802_11_WIRELESS (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 */ /* Start the scanning timeout for devices that can do scanning */
caps = nm_device_get_capabilities (dev); if (nm_device_get_capabilities (dev) & NM_DEVICE_CAP_WIRELESS_SCAN)
if (caps & NM_DEVICE_CAP_WIRELESS_SCAN)
{ {
GSource *source = g_idle_source_new (); NMWirelessScanCB * scan_cb;
guint source_id = 0;
NMWirelessScanCB *scan_cb;
scan_cb = g_malloc0 (sizeof (NMWirelessScanCB)); scan_cb = g_malloc0 (sizeof (NMWirelessScanCB));
scan_cb->dev = self; scan_cb->dev = self;
scan_cb->force = TRUE; scan_cb->force = TRUE;
source = g_idle_source_new ();
g_source_set_callback (source, nm_device_802_11_wireless_scan, scan_cb, NULL); 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)); source_id = g_source_attach (source, nm_device_get_main_context (dev));
g_source_unref (source); 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 static void
@@ -875,12 +930,14 @@ nm_device_802_11_wireless_set_mode (NMDevice80211Wireless *self,
else else
{ {
if (errno != ENODEV) if (errno != ENODEV)
{
nm_warning ("nm_device_set_mode (%s): error setting card to %s mode: %s", nm_warning ("nm_device_set_mode (%s): error setting card to %s mode: %s",
iface, iface,
mode == IW_MODE_INFRA ? "Infrastructure" : \ mode == IW_MODE_INFRA ? "Infrastructure" : \
(mode == IW_MODE_ADHOC ? "Ad-Hoc" : \ (mode == IW_MODE_ADHOC ? "Ad-Hoc" : \
(mode == IW_MODE_AUTO ? "Auto" : "unknown")), (mode == IW_MODE_AUTO ? "Auto" : "unknown")),
strerror (errno)); strerror (errno));
}
} }
nm_dev_sock_close (sk); nm_dev_sock_close (sk);
} }
@@ -1938,7 +1995,7 @@ set_wireless_config (NMDevice80211Wireless *self,
* Create an ad-hoc network (rather than associating with one). * Create an ad-hoc network (rather than associating with one).
* *
*/ */
static gboolean static NMActStageReturn
wireless_configure_adhoc (NMDevice80211Wireless *self, wireless_configure_adhoc (NMDevice80211Wireless *self,
NMAccessPoint *ap, NMAccessPoint *ap,
NMActRequest *req) NMActRequest *req)
@@ -1955,8 +2012,7 @@ wireless_configure_adhoc (NMDevice80211Wireless *self,
int err; int err;
const char * iface; const char * iface;
g_return_val_if_fail (req != NULL, FALSE); g_assert (req);
data = nm_act_request_get_data (req); data = nm_act_request_get_data (req);
g_assert (data); g_assert (data);
@@ -1969,9 +2025,7 @@ wireless_configure_adhoc (NMDevice80211Wireless *self,
for (i = 0; i < num_freqs; i++) for (i = 0; i < num_freqs; i++)
card_freqs[i] = self->priv->freqs[i]; card_freqs[i] = self->priv->freqs[i];
/* We need to find a clear wireless channel to use. We will /* Compile a list of wireless channels that are currently in use */
* only use 802.11b channels for now.
*/
iter = nm_ap_list_iter_new (nm_device_802_11_wireless_ap_list_get (self)); iter = nm_ap_list_iter_new (nm_device_802_11_wireless_ap_list_get (self));
while ((tmp_ap = nm_ap_list_iter_next (iter))) while ((tmp_ap = nm_ap_list_iter_next (iter)))
{ {
@@ -1985,13 +2039,13 @@ wireless_configure_adhoc (NMDevice80211Wireless *self,
nm_ap_list_iter_free (iter); nm_ap_list_iter_free (iter);
if ((sk = nm_dev_sock_open (NM_DEVICE (self), DEV_WIRELESS, __func__, NULL)) == NULL) 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)); iface = nm_device_get_iface (NM_DEVICE (self));
err = iw_get_range_info (nm_dev_sock_get_fd (sk), iface, &range); err = iw_get_range_info (nm_dev_sock_get_fd (sk), iface, &range);
nm_dev_sock_close (sk); nm_dev_sock_close (sk);
if (err < 0) if (err < 0)
return FALSE; return NM_ACT_STAGE_RETURN_FAILURE;
/* Ok, find the first non-zero freq in our table and use it. /* 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 * 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) if (!freq_to_use)
return FALSE; return NM_ACT_STAGE_RETURN_FAILURE;
nm_ap_set_freq (ap, freq_to_use); 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)); nm_info ("Will create network '%s' with frequency %f.", nm_ap_get_essid (ap), nm_ap_get_freq (ap));
set_wireless_config (self, 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. * Configure a wireless device for association with a particular access point.
* *
*/ */
static gboolean static NMActStageReturn
wireless_configure_infra (NMDevice80211Wireless *self, wireless_configure_infra (NMDevice80211Wireless *self,
NMAccessPoint *ap, NMAccessPoint *ap,
NMActRequest *req) NMActRequest *req)
{ {
NMData * data; NMData * data;
gboolean success = FALSE; NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE;
const char * iface; const char * iface;
gboolean link = FALSE;
g_return_val_if_fail (req != NULL, FALSE);
g_assert (req);
data = nm_act_request_get_data (req); data = nm_act_request_get_data (req);
g_assert (data); 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)); iface = nm_device_get_iface (NM_DEVICE (self));
nm_info ("Activation (%s/wireless) Stage 2 (Device Configure) will connect to access point '%s'.", 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)) if (ap_need_key (self, ap))
{ {
nm_dbus_get_user_key_for_network (data->dbus_connection, req, FALSE); nm_dbus_get_user_key_for_network (data->dbus_connection, req, FALSE);
/* FIXME */ return NM_ACT_STAGE_RETURN_POSTPONE;
/* Deal with stuff like this */
return FALSE;
} }
while (success == FALSE) set_wireless_config (self, ap);
{ if (nm_device_wireless_wait_for_link (self, nm_ap_get_essid (ap)))
gboolean link = FALSE; ret = NM_ACT_STAGE_RETURN_SUCCESS;
if (nm_device_activation_should_cancel (NM_DEVICE (self))) if (nm_device_activation_should_cancel (NM_DEVICE (self)))
break; return NM_ACT_STAGE_RETURN_SUCCESS;
set_wireless_config (self, ap); if (ret == NM_ACT_STAGE_RETURN_SUCCESS)
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)
{ {
nm_info ("Activation (%s/wireless) Stage 2 (Device Configure) successful. Connected to access point '%s'.", 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)"); iface, nm_ap_get_essid (ap) ? nm_ap_get_essid (ap) : "(none)");
} }
/* else
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)) 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 static NMActStageReturn
real_activation_config (NMDevice *dev, NMActRequest *req) real_act_stage2_config (NMDevice *dev,
NMActRequest *req)
{ {
NMDevice80211Wireless * self = NM_DEVICE_802_11_WIRELESS (dev); NMDevice80211Wireless * self = NM_DEVICE_802_11_WIRELESS (dev);
NMAccessPoint * ap = nm_act_request_get_ap (req); NMAccessPoint * ap = nm_act_request_get_ap (req);
gboolean success = FALSE; NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE;
g_assert (ap); g_assert (ap);
if (nm_ap_get_user_created (ap)) if (nm_ap_get_user_created (ap))
success = wireless_configure_adhoc (self, ap, req); ret = wireless_configure_adhoc (self, ap, req);
else 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 static guint32
real_get_type_capabilities (NMDevice *dev) 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 static void
nm_device_802_11_wireless_dispose (GObject *object) 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; object_class->finalize = nm_device_802_11_wireless_finalize;
parent_class->get_type_capabilities = real_get_type_capabilities; 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->init = real_init;
parent_class->start = real_start; parent_class->start = real_start;
parent_class->deactivate = real_deactivate; parent_class->deactivate = real_deactivate;
parent_class->activation_config = real_activation_config; parent_class->act_stage2_config = real_act_stage2_config;
parent_class->probe_link = real_probe_link; parent_class->update_link = real_update_link;
g_type_class_add_private (object_class, sizeof (NMDevice80211WirelessPrivate)); g_type_class_add_private (object_class, sizeof (NMDevice80211WirelessPrivate));
} }

View File

@@ -41,6 +41,7 @@ struct _NMDevice8023EthernetPrivate
gboolean dispose_has_run; gboolean dispose_has_run;
struct ether_addr hw_addr; struct ether_addr hw_addr;
char * carrier_file_path;
}; };
static gboolean supports_mii_carrier_detect (NMDevice8023Ethernet *dev); 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 * nm_device_get_hw_address
* *
@@ -74,7 +150,7 @@ nm_device_802_3_ethernet_get_address (NMDevice8023Ethernet *self, struct ether_a
static guint32 static guint32
real_discover_generic_capabilities (NMDevice *dev) real_get_generic_capabilities (NMDevice *dev)
{ {
NMDevice8023Ethernet * self = NM_DEVICE_802_3_ETHERNET (dev); NMDevice8023Ethernet * self = NM_DEVICE_802_3_ETHERNET (dev);
guint32 caps = NM_DEVICE_CAP_NONE; guint32 caps = NM_DEVICE_CAP_NONE;
@@ -102,13 +178,12 @@ real_discover_generic_capabilities (NMDevice *dev)
return caps; return caps;
} }
static gboolean static NMActStageReturn
real_activation_config (NMDevice *dev, NMActRequest *req) real_act_stage2_config (NMDevice *dev, NMActRequest *req)
{ {
NMData * data; NMData * data;
g_return_val_if_fail (req != NULL, FALSE); g_assert (req);
data = nm_act_request_get_data (req); data = nm_act_request_get_data (req);
g_assert (data); 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 static void
nm_device_802_3_ethernet_dispose (GObject *object) 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); NMDevice8023EthernetClass * klass = NM_DEVICE_802_3_ETHERNET_GET_CLASS (object);
NMDeviceClass * parent_class; NMDeviceClass * parent_class;
g_free (self->priv->carrier_file_path);
/* Chain up to the parent class */ /* Chain up to the parent class */
parent_class = NM_DEVICE_CLASS (g_type_class_peek_parent (klass)); parent_class = NM_DEVICE_CLASS (g_type_class_peek_parent (klass));
G_OBJECT_CLASS (parent_class)->finalize (object); 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->dispose = nm_device_802_3_ethernet_dispose;
object_class->finalize = nm_device_802_3_ethernet_finalize; object_class->finalize = nm_device_802_3_ethernet_finalize;
parent_class->activation_config = real_activation_config; parent_class->act_stage2_config = real_act_stage2_config;
parent_class->discover_generic_capabilities = real_discover_generic_capabilities; parent_class->get_generic_capabilities = real_get_generic_capabilities;
parent_class->probe_link = real_probe_link; parent_class->start = real_start;
parent_class->update_link = real_update_link;
g_type_class_add_private (object_class, sizeof (NMDevice8023EthernetPrivate)); g_type_class_add_private (object_class, sizeof (NMDevice8023EthernetPrivate));
} }

View File

@@ -24,15 +24,10 @@
#include "nm-device.h" #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); gboolean nm_device_is_activated (NMDevice *dev);
GMainContext * nm_device_get_main_context (NMDevice *dev); GMainContext * nm_device_get_main_context (NMDevice *dev);
NMIP4Config * nm_device_new_ip4_autoip_config (NMDevice *self);
#endif /* NM_DEVICE_PRIVATE_H */ #endif /* NM_DEVICE_PRIVATE_H */

View File

@@ -177,17 +177,21 @@ nm_device_new (const char *iface,
dev->priv->app_data = app_data; dev->priv->app_data = app_data;
dev->priv->type = type; 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 */ /* Device thread's main loop */
dev->priv->context = g_main_context_new (); dev->priv->context = g_main_context_new ();
dev->priv->loop = g_main_loop_new (dev->priv->context, FALSE); dev->priv->loop = g_main_loop_new (dev->priv->context, FALSE);
/* Have to bring the device up before checking link status and other stuff */ /* 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 */ /* FIXME */
#if 0 #if 0
nm_device_update_hw_address (dev); nm_device_update_hw_address (dev);
@@ -252,7 +256,7 @@ nm_device_init (NMDevice * self)
} }
static guint32 static guint32
real_discover_generic_capabilities (NMDevice *dev) real_get_generic_capabilities (NMDevice *dev)
{ {
return 0; return 0;
} }
@@ -295,10 +299,13 @@ nm_device_worker (gpointer user_data)
void void
nm_device_worker_thread_stop (NMDevice *self) nm_device_stop (NMDevice *self)
{ {
g_return_if_fail (self != NULL); g_return_if_fail (self != NULL);
nm_device_deactivate (self);
nm_device_bring_down (self);
if (self->priv->loop) if (self->priv->loop)
g_main_loop_quit (self->priv->loop); g_main_loop_quit (self->priv->loop);
if (self->priv->worker) if (self->priv->worker)
@@ -392,19 +399,6 @@ nm_device_get_udi (NMDevice *self)
return self->priv->udi; 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 * Get/set functions for iface
*/ */
@@ -440,14 +434,6 @@ nm_device_get_device_type (NMDevice *self)
return self->priv->type; 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 static gboolean
real_is_test_device (NMDevice *dev) 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 * nm_device_activation_start
* *
@@ -697,6 +645,7 @@ nm_device_activate_stage1_device_prepare (NMActRequest *req)
NMAccessPoint *ap; NMAccessPoint *ap;
NMAPSecurity * security; NMAPSecurity * security;
const char * iface; const char * iface;
NMActStageReturn ret;
g_return_val_if_fail (req != NULL, FALSE); 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); iface = nm_device_get_iface (self);
nm_info ("Activation (%s) Stage 1 (Device Prepare) started...", iface); 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)) if (nm_device_activation_should_cancel (self))
{
nm_device_schedule_activation_handle_cancel (req); nm_device_schedule_activation_handle_cancel (req);
else goto out;
nm_device_activate_schedule_stage2_device_config (req); }
nm_device_activate_schedule_stage2_device_config (req);
out:
nm_info ("Activation (%s) Stage 1 (Device Prepare) complete.", iface); nm_info ("Activation (%s) Stage 1 (Device Prepare) complete.", iface);
return FALSE; return FALSE;
} }
@@ -747,18 +708,54 @@ nm_device_activate_schedule_stage1_device_prepare (NMActRequest *req)
g_source_unref (source); g_source_unref (source);
} }
static gboolean static NMActStageReturn
real_activation_prepare (NMDevice *dev, NMActRequest *req) real_act_stage1_prepare (NMDevice *dev, NMActRequest *req)
{ {
/* Nothing to do */ /* Nothing to do */
return TRUE; return NM_ACT_STAGE_RETURN_SUCCESS;
} }
static gboolean static NMActStageReturn
real_activation_config (NMDevice *dev, NMActRequest *req) real_act_stage2_config (NMDevice *dev, NMActRequest *req)
{ {
/* Nothing to do */ /* 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; NMDevice * self;
NMData * data; NMData * data;
const char * iface; const char * iface;
NMActStageReturn ret;
g_return_val_if_fail (req != NULL, FALSE); g_return_val_if_fail (req != NULL, FALSE);
@@ -797,17 +795,25 @@ nm_device_activate_stage2_device_config (NMActRequest *req)
goto out; 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); nm_policy_schedule_activation_failed (req);
goto out; goto out;
} }
g_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS);
nm_info ("Activation (%s) Stage 2 (Device Configure) successful.", iface); 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)) if (nm_device_activation_should_cancel (self))
{
nm_device_schedule_activation_handle_cancel (req); nm_device_schedule_activation_handle_cancel (req);
goto out;
}
nm_device_activate_schedule_stage3_ip_config_start (req);
out: out:
nm_info ("Activation (%s) Stage 2 (Device Configure) complete.", iface); 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 * Build up an IP config with a Link Local address
* *
*/ */
static NMIP4Config * NMIP4Config *
nm_device_new_ip4_autoip_config (NMDevice *self) nm_device_new_ip4_autoip_config (NMDevice *self)
{ {
struct in_addr ip; struct in_addr ip;
@@ -968,6 +974,7 @@ nm_device_activate_stage4_ip_config_get (NMActRequest *req)
NMDevice * self = NULL; NMDevice * self = NULL;
NMAccessPoint * ap = NULL; NMAccessPoint * ap = NULL;
NMIP4Config * ip4_config = NULL; NMIP4Config * ip4_config = NULL;
NMActStageReturn ret;
g_return_val_if_fail (req != NULL, FALSE); 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); self = nm_act_request_get_dev (req);
g_assert (self); 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)); nm_info ("Activation (%s) Stage 4 (IP Configure Get) started...", nm_device_get_iface (self));
if (nm_device_activation_should_cancel (self)) if (nm_device_activation_should_cancel (self))
@@ -991,12 +992,15 @@ nm_device_activate_stage4_ip_config_get (NMActRequest *req)
goto out; goto out;
} }
if (ap && nm_ap_get_user_created (ap)) ret = NM_DEVICE_GET_CLASS (self)->act_stage4_get_ip4_config (self, req, &ip4_config);
ip4_config = nm_device_new_ip4_autoip_config (self); if (ret == NM_ACT_STAGE_RETURN_POSTPONE)
else if (nm_device_get_use_dhcp (self)) goto out;
ip4_config = nm_dhcp_manager_get_ip4_config (data->dhcp_manager, req); else if (!ip4_config || (ret == NM_ACT_STAGE_RETURN_FAILURE))
else {
ip4_config = nm_system_device_new_ip4_system_config (self); nm_policy_schedule_activation_failed (req);
goto out;
}
g_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS);
if (nm_device_activation_should_cancel (self)) if (nm_device_activation_should_cancel (self))
{ {
@@ -1004,29 +1008,8 @@ nm_device_activate_stage4_ip_config_get (NMActRequest *req)
goto out; goto out;
} }
if (ip4_config) nm_act_request_set_ip4_config (req, ip4_config);
{ nm_device_activate_schedule_stage5_ip_config_commit (req);
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);
}
out: out:
nm_info ("Activation (%s) Stage 4 (IP Configure Get) complete.", nm_device_get_iface (self)); 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_device_add_ip6_link_address (self);
nm_system_restart_mdns_responder (); nm_system_restart_mdns_responder ();
nm_system_activate_nis (self->priv->ip4_config); 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); nm_policy_schedule_activation_finish (req);
} }
else 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 (self->priv->app_data != NULL);
g_return_if_fail (nm_device_get_iface (self) != NULL); g_return_if_fail (nm_device_get_iface (self) != NULL);
/* Test devices get a nice, bogus IP address */ if ((sk = nm_dev_sock_open (self, DEV_GENERAL, __func__, NULL)) == NULL)
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)
return; return;
iface = nm_device_get_iface (self); iface = nm_device_get_iface (self);
@@ -1693,7 +1670,7 @@ nm_device_set_up_down (NMDevice *self,
*/ */
/* FIXME */ /* FIXME */
#if 0 #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); nm_device_update_hw_address (self);
#endif #endif
} }
@@ -1876,8 +1853,7 @@ nm_device_dispose (GObject *object)
* reference. * reference.
*/ */
nm_device_worker_thread_stop (self); nm_device_stop (self);
nm_device_bring_down (self);
nm_system_device_free_system_config (self, self->priv->system_config_data); nm_system_device_free_system_config (self, self->priv->system_config_data);
if (self->priv->ip4_config) if (self->priv->ip4_config)
@@ -1927,11 +1903,11 @@ nm_device_class_init (NMDeviceClass *klass)
klass->is_test_device = real_is_test_device; klass->is_test_device = real_is_test_device;
klass->cancel_activation = real_cancel_activation; klass->cancel_activation = real_cancel_activation;
klass->get_type_capabilities = real_get_type_capabilities; 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->start = real_start;
klass->activation_prepare = real_activation_prepare; klass->act_stage1_prepare = real_act_stage1_prepare;
klass->activation_config = real_activation_config; klass->act_stage2_config = real_act_stage2_config;
klass->probe_link = real_probe_link; klass->act_stage4_get_ip4_config = real_act_stage4_get_ip4_config;
g_type_class_add_private (object_class, sizeof (NMDevicePrivate)); g_type_class_add_private (object_class, sizeof (NMDevicePrivate));
} }

View File

@@ -40,6 +40,13 @@ typedef enum NMWirelessScanInterval
NM_WIRELESS_SCAN_INTERVAL_INACTIVE NM_WIRELESS_SCAN_INTERVAL_INACTIVE
} NMWirelessScanInterval; } NMWirelessScanInterval;
typedef enum NMActStageReturn
{
NM_ACT_STAGE_RETURN_FAILURE = 0,
NM_ACT_STAGE_RETURN_SUCCESS,
NM_ACT_STAGE_RETURN_POSTPONE
} NMActStageReturn;
G_BEGIN_DECLS G_BEGIN_DECLS
@@ -73,22 +80,21 @@ struct _NMDeviceClass
const char * (* has_active_link) (NMDevice *self); const char * (* has_active_link) (NMDevice *self);
void (* set_active_link) (NMDevice *self, gboolean active); void (* set_active_link) (NMDevice *self, gboolean active);
gboolean (* probe_link) (NMDevice *self); void (* update_link) (NMDevice *self);
guint32 (* get_ip4_address) (NMDevice *self);
struct in6_addr * (* get_ip6_address) (NMDevice *self);
void (* bring_up) (NMDevice *self); void (* bring_up) (NMDevice *self);
void (* bring_down) (NMDevice *self); void (* bring_down) (NMDevice *self);
gboolean (* is_up) (NMDevice *self);
guint32 (* get_type_capabilities) (NMDevice *self); guint32 (* get_type_capabilities) (NMDevice *self);
guint32 (* discover_generic_capabilities) (NMDevice *self); guint32 (* get_generic_capabilities) (NMDevice *self);
void (* init) (NMDevice *self); void (* init) (NMDevice *self);
void (* start) (NMDevice *self); void (* start) (NMDevice *self);
gboolean (* activation_prepare) (NMDevice *self, struct NMActRequest * req); NMActStageReturn (* act_stage1_prepare) (NMDevice *self, struct NMActRequest * req);
gboolean (* activation_config) (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 (* deactivate) (NMDevice *self);
void (* cancel_activation) (NMDevice *self); void (* cancel_activation) (NMDevice *self);
}; };
@@ -102,7 +108,7 @@ NMDevice * nm_device_new (const char *iface,
NMDeviceType test_dev_type, NMDeviceType test_dev_type,
struct NMData *app_data); 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); const char * nm_device_get_udi (NMDevice *dev);