summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Williams <dcbw@redhat.com>2015-04-13 17:16:55 -0500
committerDan Williams <dcbw@redhat.com>2015-04-13 17:21:40 -0500
commit9a38277085a5e7c8fff1308af175813ec1ab1f17 (patch)
treefce2ceefa0bed5ae8eaf611a57259ff8a852c04e
parent5c539d84d6c5e03208499c9eda7a3f2904383272 (diff)
downloadNetworkManager-9a38277085a5e7c8fff1308af175813ec1ab1f17.tar.gz
core: add generic NMDevice function to recheck availability
And use it everywhere.
-rw-r--r--src/devices/bluetooth/nm-device-bt.c64
-rw-r--r--src/devices/nm-device-private.h3
-rw-r--r--src/devices/nm-device.c57
-rw-r--r--src/devices/wifi/nm-device-olpc-mesh.c12
-rw-r--r--src/devices/wifi/nm-device-wifi.c30
-rw-r--r--src/devices/wimax/nm-device-wimax.c56
-rw-r--r--src/devices/wwan/nm-device-modem.c16
7 files changed, 106 insertions, 132 deletions
diff --git a/src/devices/bluetooth/nm-device-bt.c b/src/devices/bluetooth/nm-device-bt.c
index 61371dddec..db7089fd07 100644
--- a/src/devices/bluetooth/nm-device-bt.c
+++ b/src/devices/bluetooth/nm-device-bt.c
@@ -479,6 +479,13 @@ device_state_changed (NMDevice *device,
if (priv->modem)
nm_modem_device_state_changed (priv->modem, new_state, old_state, reason);
+
+ /* Need to recheck available connections whenever MM appears or disappears,
+ * since the device could be both DUN and NAP capable and thus may not
+ * change state (which rechecks available connections) when MM comes and goes.
+ */
+ if (priv->mm_running && (priv->capabilities & NM_BT_CAPABILITY_DUN))
+ nm_device_recheck_available_connections (device);
}
static void
@@ -944,60 +951,19 @@ is_available (NMDevice *dev, NMDeviceCheckDevAvailableFlags flags)
}
static void
-handle_availability_change (NMDeviceBt *self,
- gboolean old_available,
- NMDeviceStateReason unavailable_reason)
-{
- NMDevice *device = NM_DEVICE (self);
- NMDeviceState state;
- gboolean available;
-
- state = nm_device_get_state (device);
- if (state < NM_DEVICE_STATE_UNAVAILABLE) {
- _LOGD (LOGD_BT, "availability blocked by UNMANAGED state");
- return;
- }
-
- available = nm_device_is_available (device, NM_DEVICE_CHECK_DEV_AVAILABLE_NONE);
- if (available == old_available)
- return;
-
- if (available) {
- if (state != NM_DEVICE_STATE_UNAVAILABLE)
- _LOGW (LOGD_CORE | LOGD_BT, "not in expected unavailable state!");
-
- nm_device_state_changed (device,
- NM_DEVICE_STATE_DISCONNECTED,
- NM_DEVICE_STATE_REASON_NONE);
- } else {
- nm_device_state_changed (device,
- NM_DEVICE_STATE_UNAVAILABLE,
- unavailable_reason);
- }
-}
-
-static void
set_mm_running (NMDeviceBt *self, gboolean running)
{
NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (self);
- gboolean old_available;
- if (priv->mm_running == running)
- return;
+ if (priv->mm_running != running) {
+ _LOGD (LOGD_BT, "ModemManager now %s",
+ running ? "available" : "unavailable");
- _LOGD (LOGD_BT, "ModemManager now %s",
- running ? "available" : "unavailable");
-
- old_available = nm_device_is_available (NM_DEVICE (self), NM_DEVICE_CHECK_DEV_AVAILABLE_NONE);
- priv->mm_running = running;
- handle_availability_change (self, old_available, NM_DEVICE_STATE_REASON_MODEM_MANAGER_UNAVAILABLE);
-
- /* Need to recheck available connections whenever MM appears or disappears,
- * since the device could be both DUN and NAP capable and thus may not
- * change state (which rechecks available connections) when MM comes and goes.
- */
- if (priv->capabilities & NM_BT_CAPABILITY_DUN)
- nm_device_recheck_available_connections (NM_DEVICE (self));
+ priv->mm_running = running;
+ nm_device_queue_recheck_available (NM_DEVICE (self),
+ NM_DEVICE_STATE_REASON_NONE,
+ NM_DEVICE_STATE_REASON_MODEM_MANAGER_UNAVAILABLE);
+ }
}
static void
diff --git a/src/devices/nm-device-private.h b/src/devices/nm-device-private.h
index 1f781bbc05..f34969ac3d 100644
--- a/src/devices/nm-device-private.h
+++ b/src/devices/nm-device-private.h
@@ -97,6 +97,9 @@ void nm_device_set_carrier (NMDevice *self, gboolean carrier);
void nm_device_emit_recheck_auto_activate (NMDevice *device);
void nm_device_queue_recheck_assume (NMDevice *device);
+void nm_device_queue_recheck_available (NMDevice *device,
+ NMDeviceStateReason available_reason,
+ NMDeviceStateReason unavailable_reason);
void nm_device_set_wwan_ip4_config (NMDevice *device, NMIP4Config *config);
void nm_device_set_wwan_ip6_config (NMDevice *device, NMIP6Config *config);
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index 4735753366..432612682a 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -220,6 +220,11 @@ typedef struct {
gpointer act_source6_func;
guint recheck_assume_id;
struct {
+ guint call_id;
+ NMDeviceStateReason available_reason;
+ NMDeviceStateReason unavailable_reason;
+ } recheck_available;
+ struct {
guint call_id;
NMDeviceState post_state;
NMDeviceStateReason post_state_reason;
@@ -2295,6 +2300,48 @@ nm_device_queue_recheck_assume (NMDevice *self)
priv->recheck_assume_id = g_idle_add (nm_device_emit_recheck_assume, self);
}
+static gboolean
+recheck_available (gpointer user_data)
+{
+ NMDevice *self = NM_DEVICE (user_data);
+ NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
+ gboolean now_available = nm_device_is_available (self, NM_DEVICE_CHECK_DEV_AVAILABLE_NONE);
+ NMDeviceState state = nm_device_get_state (self);
+
+ priv->recheck_available.call_id = 0;
+
+ _LOGD (LOGD_DEVICE, "rechecking availability");
+ if (state == NM_DEVICE_STATE_UNAVAILABLE && now_available) {
+ _LOGD (LOGD_DEVICE, "device is available, will transition to DISCONNECTED");
+ nm_device_queue_state (self,
+ NM_DEVICE_STATE_DISCONNECTED,
+ priv->recheck_available.available_reason);
+ } else if (state >= NM_DEVICE_STATE_DISCONNECTED && !now_available) {
+ _LOGD (LOGD_DEVICE, "device no longer available, will transition to UNAVAILABLE");
+ nm_device_queue_state (self,
+ NM_DEVICE_STATE_UNAVAILABLE,
+ priv->recheck_available.unavailable_reason);
+ }
+
+ priv->recheck_available.available_reason = NM_DEVICE_STATE_REASON_NONE;
+ priv->recheck_available.unavailable_reason = NM_DEVICE_STATE_REASON_NONE;
+ return G_SOURCE_REMOVE;
+}
+
+void
+nm_device_queue_recheck_available (NMDevice *self,
+ NMDeviceStateReason available_reason,
+ NMDeviceStateReason unavailable_reason)
+{
+ NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
+
+ if (!priv->recheck_available.call_id) {
+ priv->recheck_available.available_reason = available_reason;
+ priv->recheck_available.unavailable_reason = unavailable_reason;
+ priv->recheck_available.call_id = g_idle_add (recheck_available, self);
+ }
+}
+
void
nm_device_emit_recheck_auto_activate (NMDevice *self)
{
@@ -7976,8 +8023,9 @@ _set_state_full (NMDevice *self,
* reasons.
*/
if (nm_device_is_available (self, NM_DEVICE_CHECK_DEV_AVAILABLE_NONE)) {
- _LOGD (LOGD_DEVICE, "device is available, will transition to DISCONNECTED");
- nm_device_queue_state (self, NM_DEVICE_STATE_DISCONNECTED, NM_DEVICE_STATE_REASON_NONE);
+ nm_device_queue_recheck_available (self,
+ NM_DEVICE_STATE_REASON_NONE,
+ NM_DEVICE_STATE_REASON_NONE);
} else {
if (old_state == NM_DEVICE_STATE_UNMANAGED)
_LOGD (LOGD_DEVICE, "device not yet available for transition to DISCONNECTED");
@@ -8584,6 +8632,11 @@ dispose (GObject *object)
priv->recheck_assume_id = 0;
}
+ if (priv->recheck_available.call_id) {
+ g_source_remove (priv->recheck_available.call_id);
+ priv->recheck_available.call_id = 0;
+ }
+
link_disconnect_action_cancel (self);
if (priv->con_provider) {
diff --git a/src/devices/wifi/nm-device-olpc-mesh.c b/src/devices/wifi/nm-device-olpc-mesh.c
index dc3dfbc659..27fef07028 100644
--- a/src/devices/wifi/nm-device-olpc-mesh.c
+++ b/src/devices/wifi/nm-device-olpc-mesh.c
@@ -368,10 +368,10 @@ device_added_cb (NMManager *manager, NMDevice *other, gpointer user_data)
NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (self);
if (!priv->companion && check_companion (self, other)) {
- nm_device_state_changed (NM_DEVICE (self),
- NM_DEVICE_STATE_DISCONNECTED,
- NM_DEVICE_STATE_REASON_NONE);
nm_device_remove_pending_action (NM_DEVICE (self), "waiting for companion", TRUE);
+ nm_device_queue_recheck_available (NM_DEVICE (self),
+ NM_DEVICE_STATE_REASON_NONE,
+ NM_DEVICE_STATE_REASON_NONE);
}
}
@@ -398,9 +398,9 @@ find_companion (NMDeviceOlpcMesh *self)
/* Try to find the companion if it's already known to the NMManager */
for (list = nm_manager_get_devices (nm_manager_get ()); list ; list = g_slist_next (list)) {
if (check_companion (self, NM_DEVICE (list->data))) {
- nm_device_queue_state (NM_DEVICE (self),
- NM_DEVICE_STATE_DISCONNECTED,
- NM_DEVICE_STATE_REASON_NONE);
+ nm_device_queue_recheck_available (NM_DEVICE (self),
+ NM_DEVICE_STATE_REASON_NONE,
+ NM_DEVICE_STATE_REASON_NONE);
nm_device_remove_pending_action (NM_DEVICE (self), "waiting for companion", TRUE);
break;
}
diff --git a/src/devices/wifi/nm-device-wifi.c b/src/devices/wifi/nm-device-wifi.c
index 1361bd89dd..48fd208ea0 100644
--- a/src/devices/wifi/nm-device-wifi.c
+++ b/src/devices/wifi/nm-device-wifi.c
@@ -1940,6 +1940,7 @@ supplicant_iface_state_cb (NMSupplicantInterface *iface,
NMDevice *device = NM_DEVICE (self);
NMDeviceState devstate;
gboolean scanning;
+ gboolean recheck_available = FALSE;
if (new_state == old_state)
return;
@@ -1959,23 +1960,9 @@ supplicant_iface_state_cb (NMSupplicantInterface *iface,
switch (new_state) {
case NM_SUPPLICANT_INTERFACE_STATE_READY:
+ _LOGD (LOGD_WIFI_SCAN, "supplicant ready");
+ recheck_available = TRUE;
priv->scan_interval = SCAN_INTERVAL_MIN;
-
- /* If the interface can now be activated because the supplicant is now
- * available, transition to DISCONNECTED.
- */
- if ((devstate == NM_DEVICE_STATE_UNAVAILABLE) && nm_device_is_available (device, NM_DEVICE_CHECK_DEV_AVAILABLE_NONE)) {
- nm_device_state_changed (device,
- NM_DEVICE_STATE_DISCONNECTED,
- NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE);
- }
-
- _LOGD (LOGD_WIFI_SCAN, "supplicant ready, requesting initial scan");
-
- /* Request a scan to get latest results */
- cancel_pending_scan (self);
- request_wireless_scan (self);
-
if (old_state < NM_SUPPLICANT_INTERFACE_STATE_READY)
nm_device_remove_pending_action (device, "waiting for supplicant", TRUE);
break;
@@ -2035,6 +2022,7 @@ supplicant_iface_state_cb (NMSupplicantInterface *iface,
}
break;
case NM_SUPPLICANT_INTERFACE_STATE_DOWN:
+ recheck_available = TRUE;
cleanup_association_attempt (self, FALSE);
if (old_state < NM_SUPPLICANT_INTERFACE_STATE_READY)
@@ -2047,15 +2035,17 @@ supplicant_iface_state_cb (NMSupplicantInterface *iface,
*/
supplicant_interface_release (self);
supplicant_interface_acquire (self);
-
- nm_device_state_changed (device,
- NM_DEVICE_STATE_UNAVAILABLE,
- NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
break;
default:
break;
}
+ if (recheck_available) {
+ nm_device_queue_recheck_available (NM_DEVICE (device),
+ NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE,
+ NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
+ }
+
/* Signal scanning state changes */
if ( new_state == NM_SUPPLICANT_INTERFACE_STATE_SCANNING
|| old_state == NM_SUPPLICANT_INTERFACE_STATE_SCANNING)
diff --git a/src/devices/wimax/nm-device-wimax.c b/src/devices/wimax/nm-device-wimax.c
index 0c8f1cbbe3..13d9f44e56 100644
--- a/src/devices/wimax/nm-device-wimax.c
+++ b/src/devices/wimax/nm-device-wimax.c
@@ -232,37 +232,6 @@ get_nsp_by_path (NMDeviceWimax *self, const char *path)
return NULL;
}
-static gboolean
-update_availability (NMDeviceWimax *self, gboolean old_available)
-{
- NMDevice *device = NM_DEVICE (self);
- NMDeviceState state;
- gboolean new_available, changed = FALSE;
-
- new_available = nm_device_is_available (device, NM_DEVICE_CHECK_DEV_AVAILABLE_NONE);
- if (new_available == old_available)
- return FALSE;
-
- state = nm_device_get_state (device);
- if (state == NM_DEVICE_STATE_UNAVAILABLE) {
- if (new_available == TRUE) {
- nm_device_state_changed (device,
- NM_DEVICE_STATE_DISCONNECTED,
- NM_DEVICE_STATE_REASON_NONE);
- changed = TRUE;
- }
- } else if (state >= NM_DEVICE_STATE_DISCONNECTED) {
- if (new_available == FALSE) {
- nm_device_state_changed (device,
- NM_DEVICE_STATE_UNAVAILABLE,
- NM_DEVICE_STATE_REASON_NONE);
- changed = TRUE;
- }
- }
-
- return changed;
-}
-
/* NMDeviceInterface interface */
static void
@@ -270,7 +239,6 @@ set_enabled (NMDevice *device, gboolean enabled)
{
NMDeviceWimax *self = NM_DEVICE_WIMAX (device);
NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self);
- gboolean old_available;
int ret;
const char *iface;
@@ -281,7 +249,6 @@ set_enabled (NMDevice *device, gboolean enabled)
if (priv->enabled == enabled)
return;
- old_available = nm_device_is_available (NM_DEVICE (device), NM_DEVICE_CHECK_DEV_AVAILABLE_NONE);
priv->enabled = enabled;
nm_log_dbg (LOGD_WIMAX, "(%s): radio now %s",
@@ -297,7 +264,9 @@ set_enabled (NMDevice *device, gboolean enabled)
}
}
- update_availability (self, old_available);
+ nm_device_queue_recheck_available (NM_DEVICE (self),
+ NM_DEVICE_STATE_REASON_NONE,
+ NM_DEVICE_STATE_REASON_NONE);
}
/* NMDevice methods */
@@ -692,7 +661,6 @@ wmx_state_change_cb (struct wmxsdk *wmxsdk,
NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self);
NMDeviceState state;
const char *iface;
- gboolean old_available = FALSE;
const char *nsp_name = NULL;
iface = nm_device_get_iface (NM_DEVICE (self));
@@ -707,7 +675,6 @@ wmx_state_change_cb (struct wmxsdk *wmxsdk,
return;
state = nm_device_get_state (NM_DEVICE (self));
- old_available = nm_device_is_available (NM_DEVICE (self), NM_DEVICE_CHECK_DEV_AVAILABLE_NONE);
priv->status = new_status;
if (priv->current_nsp)
@@ -720,8 +687,10 @@ wmx_state_change_cb (struct wmxsdk *wmxsdk,
case WIMAX_API_DEVICE_STATUS_RF_OFF_SW:
if (priv->wimaxd_enabled) {
priv->wimaxd_enabled = FALSE;
- if (update_availability (self, old_available))
- return;
+ nm_device_queue_recheck_available (NM_DEVICE (self),
+ NM_DEVICE_STATE_REASON_NONE,
+ NM_DEVICE_STATE_REASON_NONE);
+ return;
}
break;
case WIMAX_API_DEVICE_STATUS_Connecting:
@@ -734,8 +703,10 @@ wmx_state_change_cb (struct wmxsdk *wmxsdk,
case WIMAX_API_DEVICE_STATUS_Scanning:
if (priv->wimaxd_enabled == FALSE) {
priv->wimaxd_enabled = TRUE;
- if (update_availability (self, old_available))
- return;
+ nm_device_queue_recheck_available (NM_DEVICE (self),
+ NM_DEVICE_STATE_REASON_NONE,
+ NM_DEVICE_STATE_REASON_NONE);
+ return;
}
break;
default:
@@ -1148,10 +1119,11 @@ static gboolean
sdk_action_defer_cb (gpointer user_data)
{
NMDeviceWimax *self = NM_DEVICE_WIMAX (user_data);
- gboolean old_available = nm_device_is_available (NM_DEVICE (self), NM_DEVICE_CHECK_DEV_AVAILABLE_NONE);
NM_DEVICE_WIMAX_GET_PRIVATE (self)->sdk_action_defer_id = 0;
- update_availability (self, old_available);
+ nm_device_queue_recheck_available (NM_DEVICE (self),
+ NM_DEVICE_STATE_REASON_NONE,
+ NM_DEVICE_STATE_REASON_NONE);
return FALSE;
}
diff --git a/src/devices/wwan/nm-device-modem.c b/src/devices/wwan/nm-device-modem.c
index f819d1d774..6015c9ca49 100644
--- a/src/devices/wwan/nm-device-modem.c
+++ b/src/devices/wwan/nm-device-modem.c
@@ -300,19 +300,9 @@ modem_state_cb (NMModem *modem,
nm_device_recheck_available_connections (device);
}
- if ((dev_state >= NM_DEVICE_STATE_DISCONNECTED) && !nm_device_is_available (device, NM_DEVICE_CHECK_DEV_AVAILABLE_NONE)) {
- nm_device_state_changed (device,
- NM_DEVICE_STATE_UNAVAILABLE,
- NM_DEVICE_STATE_REASON_MODEM_FAILED);
- return;
- }
-
- if ((dev_state == NM_DEVICE_STATE_UNAVAILABLE) && nm_device_is_available (device, NM_DEVICE_CHECK_DEV_AVAILABLE_NONE)) {
- nm_device_state_changed (device,
- NM_DEVICE_STATE_DISCONNECTED,
- NM_DEVICE_STATE_REASON_MODEM_AVAILABLE);
- return;
- }
+ nm_device_queue_recheck_available (device,
+ NM_DEVICE_STATE_REASON_MODEM_AVAILABLE,
+ NM_DEVICE_STATE_REASON_MODEM_FAILED);
}
static void