core: add generic NMDevice function to recheck availability

And use it everywhere.

(cherry picked from commit 3006df940c)
This commit is contained in:
Dan Williams 2015-04-13 17:16:55 -05:00 committed by Thomas Haller
parent e43bd9228c
commit fab106c912
6 changed files with 91 additions and 90 deletions

View file

@ -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
@ -943,61 +950,20 @@ is_available (NMDevice *dev, NMDeviceCheckDevAvailableFlags flags)
return priv->mm_running;
}
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

View file

@ -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);

View file

@ -219,6 +219,11 @@ typedef struct {
guint act_source6_id;
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;
@ -2302,6 +2307,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)
{
@ -7860,8 +7906,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");
@ -8496,6 +8543,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) {

View file

@ -369,9 +369,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);
}
}
@ -399,9 +399,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;
}

View file

@ -2149,6 +2149,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;
@ -2168,23 +2169,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;
@ -2244,6 +2231,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)
@ -2256,15 +2244,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)

View file

@ -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