summaryrefslogtreecommitdiff
path: root/src/devices/wwan/nm-device-modem.c
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2019-08-22 10:43:22 +0200
committerThomas Haller <thaller@redhat.com>2019-08-28 16:27:00 +0200
commit29562a9751d97eb56bb5b56f3d36a96345559a5f (patch)
tree43027ed681c41ca57e440f671eae766ca09b57c5 /src/devices/wwan/nm-device-modem.c
parent86f8f5a71c52af36e8e8d73e27612d6588d828c3 (diff)
downloadNetworkManager-29562a9751d97eb56bb5b56f3d36a96345559a5f.tar.gz
device: let devices call stage1 again after being ready to proceed
I am about to change the when stage1 gets postponed, then the way to proceed it is to schedule stage1 again (instead of scheduling stage2). The reason is that stage1 handling should be reentrant and we should keep entering it until there is no more reason to postpone it. If a subclass postpones stage1 and then later progresses it by directly scheduling stage2, then only the subclass is in control over postponing stage 2. Instead, anybody should be able to delay stage2 independently. That can only work if everybody signals readyness to proceed by scheduling stage1 again.
Diffstat (limited to 'src/devices/wwan/nm-device-modem.c')
-rw-r--r--src/devices/wwan/nm-device-modem.c52
1 files changed, 37 insertions, 15 deletions
diff --git a/src/devices/wwan/nm-device-modem.c b/src/devices/wwan/nm-device-modem.c
index be0993916d..7ba664394a 100644
--- a/src/devices/wwan/nm-device-modem.c
+++ b/src/devices/wwan/nm-device-modem.c
@@ -48,10 +48,11 @@ typedef struct {
NMModem *modem;
NMDeviceModemCapabilities caps;
NMDeviceModemCapabilities current_caps;
- gboolean rf_enabled;
char *device_id;
char *operator_code;
char *apn;
+ bool rf_enabled:1;
+ NMDeviceStageState stage1_state:3;
} NMDeviceModemPrivate;
struct _NMDeviceModem {
@@ -119,16 +120,17 @@ modem_prepare_result (NMModem *modem,
gpointer user_data)
{
NMDeviceModem *self = NM_DEVICE_MODEM (user_data);
+ NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (self);
NMDevice *device = NM_DEVICE (self);
- NMDeviceState state;
NMDeviceStateReason reason = i_reason;
- state = nm_device_get_state (device);
- g_return_if_fail (state == NM_DEVICE_STATE_PREPARE);
+ if ( nm_device_get_state (device) != NM_DEVICE_STATE_PREPARE
+ || priv->stage1_state != NM_DEVICE_STAGE_STATE_PENDING) {
+ nm_assert_not_reached ();
+ success = FALSE;
+ }
- if (success)
- nm_device_activate_schedule_stage2_device_config (device);
- else {
+ if (!success) {
/* There are several reasons to block autoconnection at device level:
*
* - Wrong SIM-PIN: The device won't autoconnect because it doesn't make sense
@@ -164,7 +166,11 @@ modem_prepare_result (NMModem *modem,
break;
}
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, reason);
+ return;
}
+
+ priv->stage1_state = NM_DEVICE_STAGE_STATE_COMPLETED;
+ nm_device_activate_schedule_stage1_device_prepare (device);
}
static void
@@ -187,16 +193,19 @@ static void
modem_auth_result (NMModem *modem, GError *error, gpointer user_data)
{
NMDevice *device = NM_DEVICE (user_data);
+ NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (device);
+
+ g_return_if_fail (nm_device_get_state (device) == NM_DEVICE_STATE_NEED_AUTH);
if (error) {
nm_device_state_changed (device,
NM_DEVICE_STATE_FAILED,
NM_DEVICE_STATE_REASON_NO_SECRETS);
- } else {
- /* Otherwise, on success for modem secrets we need to schedule stage1 again */
- g_return_if_fail (nm_device_get_state (device) == NM_DEVICE_STATE_NEED_AUTH);
- nm_device_activate_schedule_stage1_device_prepare (device);
+ return;
}
+
+ priv->stage1_state = NM_DEVICE_STAGE_STATE_INIT;
+ nm_device_activate_schedule_stage1_device_prepare (device);
}
static void
@@ -542,7 +551,10 @@ complete_connection (NMDevice *device,
static void
deactivate (NMDevice *device)
{
- nm_modem_deactivate (NM_DEVICE_MODEM_GET_PRIVATE (device)->modem, device);
+ NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (device);
+
+ nm_modem_deactivate (priv->modem, device);
+ priv->stage1_state = NM_DEVICE_STAGE_STATE_INIT;
}
/*****************************************************************************/
@@ -583,14 +595,24 @@ deactivate_async (NMDevice *self,
static NMActStageReturn
act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason)
{
+ NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (device);
NMActRequest *req;
req = nm_device_get_act_request (device);
g_return_val_if_fail (req, NM_ACT_STAGE_RETURN_FAILURE);
- return nm_modem_act_stage1_prepare (NM_DEVICE_MODEM_GET_PRIVATE (device)->modem,
- req,
- out_failure_reason);
+ if (priv->stage1_state == NM_DEVICE_STAGE_STATE_INIT) {
+ priv->stage1_state = NM_DEVICE_STAGE_STATE_PENDING;
+ return nm_modem_act_stage1_prepare (NM_DEVICE_MODEM_GET_PRIVATE (device)->modem,
+ req,
+ out_failure_reason);
+ }
+
+ if (priv->stage1_state == NM_DEVICE_STAGE_STATE_PENDING)
+ return NM_ACT_STAGE_RETURN_POSTPONE;
+
+ nm_assert (priv->stage1_state == NM_DEVICE_STAGE_STATE_COMPLETED);
+ return NM_ACT_STAGE_RETURN_SUCCESS;
}
static NMActStageReturn