diff --git a/ChangeLog b/ChangeLog index de4fd9375e..1319bc8a8c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2008-04-07 Dan Williams + + * src/nm-gsm-device.c + src/nm-cdma-device.c + - (state_changed_cb): when entering UNAVAILABLE state, schedule an idle + handler to transition to DISCONNECTED + 2008-04-07 Dan Williams Patch from Bill Nottingham diff --git a/src/nm-cdma-device.c b/src/nm-cdma-device.c index 2941832eaa..10344ad875 100644 --- a/src/nm-cdma-device.c +++ b/src/nm-cdma-device.c @@ -19,6 +19,7 @@ typedef struct { NMSerialDevice *monitor_device; guint pending_id; + guint state_to_disconnected_id; } NMCdmaDevicePrivate; enum { @@ -333,6 +334,33 @@ nm_cdma_device_init (NMCdmaDevice *self) nm_device_set_device_type (NM_DEVICE (self), DEVICE_TYPE_CDMA); } +static gboolean +unavailable_to_disconnected (gpointer user_data) +{ + nm_device_state_changed (NM_DEVICE (user_data), NM_DEVICE_STATE_DISCONNECTED); + return FALSE; +} + +static void +device_state_changed (NMDeviceInterface *device, NMDeviceState state, gpointer user_data) +{ + NMCdmaDevice *self = NM_CDMA_DEVICE (user_data); + NMCdmaDevicePrivate *priv = NM_CDMA_DEVICE_GET_PRIVATE (self); + + /* Remove any previous delayed transition to disconnected */ + if (priv->state_to_disconnected_id) { + g_source_remove (priv->state_to_disconnected_id); + priv->state_to_disconnected_id = 0; + } + + /* If transitioning to UNAVAILBLE and we have a carrier, transition to + * DISCONNECTED because the device is ready to use. Otherwise the carrier-on + * handler will handle the transition to DISCONNECTED when the carrier is detected. + */ + if (state == NM_DEVICE_STATE_UNAVAILABLE) + priv->state_to_disconnected_id = g_idle_add (unavailable_to_disconnected, self); +} + static GObject* constructor (GType type, guint n_construct_params, @@ -355,6 +383,9 @@ constructor (GType type, } #endif + g_signal_connect (NM_DEVICE (object), "state-changed", + G_CALLBACK (device_state_changed), NM_CDMA_DEVICE (object)); + return object; } @@ -401,6 +432,11 @@ finalize (GObject *object) g_free (priv->monitor_iface); + if (priv->state_to_disconnected_id) { + g_source_remove (priv->state_to_disconnected_id); + priv->state_to_disconnected_id = 0; + } + G_OBJECT_CLASS (nm_cdma_device_parent_class)->finalize (object); } diff --git a/src/nm-gsm-device.c b/src/nm-gsm-device.c index ba623cbb4d..fc31103090 100644 --- a/src/nm-gsm-device.c +++ b/src/nm-gsm-device.c @@ -26,6 +26,7 @@ typedef struct { NMGsmSecret need_secret; guint pending_id; + guint state_to_disconnected_id; } NMGsmDevicePrivate; enum { @@ -639,6 +640,33 @@ nm_gsm_device_init (NMGsmDevice *self) nm_device_set_device_type (NM_DEVICE (self), DEVICE_TYPE_GSM); } +static gboolean +unavailable_to_disconnected (gpointer user_data) +{ + nm_device_state_changed (NM_DEVICE (user_data), NM_DEVICE_STATE_DISCONNECTED); + return FALSE; +} + +static void +device_state_changed (NMDeviceInterface *device, NMDeviceState state, gpointer user_data) +{ + NMGsmDevice *self = NM_GSM_DEVICE (user_data); + NMGsmDevicePrivate *priv = NM_GSM_DEVICE_GET_PRIVATE (self); + + /* Remove any previous delayed transition to disconnected */ + if (priv->state_to_disconnected_id) { + g_source_remove (priv->state_to_disconnected_id); + priv->state_to_disconnected_id = 0; + } + + /* If transitioning to UNAVAILBLE and we have a carrier, transition to + * DISCONNECTED because the device is ready to use. Otherwise the carrier-on + * handler will handle the transition to DISCONNECTED when the carrier is detected. + */ + if (state == NM_DEVICE_STATE_UNAVAILABLE) + priv->state_to_disconnected_id = g_idle_add (unavailable_to_disconnected, self); +} + static GObject* constructor (GType type, guint n_construct_params, @@ -661,6 +689,9 @@ constructor (GType type, } #endif + g_signal_connect (NM_DEVICE (object), "state-changed", + G_CALLBACK (device_state_changed), NM_GSM_DEVICE (object)); + return object; } @@ -707,6 +738,11 @@ finalize (GObject *object) g_free (priv->monitor_iface); + if (priv->state_to_disconnected_id) { + g_source_remove (priv->state_to_disconnected_id); + priv->state_to_disconnected_id = 0; + } + G_OBJECT_CLASS (nm_gsm_device_parent_class)->finalize (object); }