summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Williams <dcbw@redhat.com>2015-04-13 17:16:55 -0500
committerLubomir Rintel <lkundrak@v3.sk>2015-05-28 11:53:03 +0200
commitbc500c43fce04be102bc2775e1fd832e00097542 (patch)
treeeebe37160b3cb5d9778babada2bb9b865b3bf654
parentf71e5c27e0dd0f418f9dac18248d0a2f3d56b38a (diff)
downloadNetworkManager-bc500c43fce04be102bc2775e1fd832e00097542.tar.gz
core: add generic NMDevice function to recheck availability
And use it everywhere. (cherry picked from commit 3006df940ca254ed999e527a6e797fd016e7ebc9)
-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.c56
-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/wwan/nm-device-modem.c16
6 files changed, 91 insertions, 90 deletions
diff --git a/src/devices/bluetooth/nm-device-bt.c b/src/devices/bluetooth/nm-device-bt.c
index 852ca39971..88033e2e8e 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 e8f902dd40..b47f7b6a3e 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;
@@ -2288,6 +2293,47 @@ 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);
+ NMDeviceState new_state = NM_DEVICE_STATE_UNKNOWN;
+
+ priv->recheck_available.call_id = 0;
+
+ if (state == NM_DEVICE_STATE_UNAVAILABLE && now_available) {
+ new_state = NM_DEVICE_STATE_DISCONNECTED;
+ nm_device_queue_state (self, new_state, priv->recheck_available.available_reason);
+ } else if (state >= NM_DEVICE_STATE_DISCONNECTED && !now_available) {
+ new_state = NM_DEVICE_STATE_UNAVAILABLE;
+ nm_device_queue_state (self, new_state, priv->recheck_available.unavailable_reason);
+ }
+ _LOGD (LOGD_DEVICE, "device is %savailable, %s %s",
+ now_available ? "" : "not ",
+ new_state == NM_DEVICE_STATE_UNAVAILABLE ? "no change required for" : "will transition to",
+ state_to_string (new_state == NM_DEVICE_STATE_UNAVAILABLE ? state : new_state));
+
+ 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);
+
+ priv->recheck_available.available_reason = available_reason;
+ priv->recheck_available.unavailable_reason = unavailable_reason;
+ if (!priv->recheck_available.call_id)
+ priv->recheck_available.call_id = g_idle_add (recheck_available, self);
+}
+
void
nm_device_emit_recheck_auto_activate (NMDevice *self)
{
@@ -7838,8 +7884,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");
@@ -8438,6 +8485,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..e34f0aa343 100644
--- a/src/devices/wifi/nm-device-olpc-mesh.c
+++ b/src/devices/wifi/nm-device-olpc-mesh.c
@@ -368,9 +368,9 @@ 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_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);
}
}
@@ -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 ce9a3f7539..24fa8a140b 100644
--- a/src/devices/wifi/nm-device-wifi.c
+++ b/src/devices/wifi/nm-device-wifi.c
@@ -2148,6 +2148,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;
@@ -2167,23 +2168,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;
@@ -2243,6 +2230,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)
@@ -2255,15 +2243,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/wwan/nm-device-modem.c b/src/devices/wwan/nm-device-modem.c
index a429aa0396..c02f5def9b 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