summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRatchanan Srirattanamet <ratchanan@ubports.com>2022-10-25 01:25:04 +0700
committerThomas Haller <thaller@redhat.com>2022-11-10 07:44:56 +0100
commitffbb8d2f510fceb32ef7c9a86a898cca051facee (patch)
treea8682028969e291eff22a5ef8dcffc05f1025186
parent9fc72bf75dbf2c453aa72bad22772d6b536f3d79 (diff)
downloadNetworkManager-ffbb8d2f510fceb32ef7c9a86a898cca051facee.tar.gz
wwan/ofono: when connect while searching, wait a bit
We don't have to outright refuse to connect if we're not registered. Instead, wait up to 60 seconds for modem to register.
-rw-r--r--src/core/devices/wwan/nm-modem-ofono.c48
1 files changed, 47 insertions, 1 deletions
diff --git a/src/core/devices/wwan/nm-modem-ofono.c b/src/core/devices/wwan/nm-modem-ofono.c
index c18c2778bc..5145fa4b6b 100644
--- a/src/core/devices/wwan/nm-modem-ofono.c
+++ b/src/core/devices/wwan/nm-modem-ofono.c
@@ -65,6 +65,8 @@ typedef struct {
/* unowned; reference held by 'contexts' above. */
OfonoContextData *current_octx;
+
+ GSource *deferred_connection_timeout_source;
} NMModemOfonoPrivate;
struct _NMModemOfono {
@@ -138,6 +140,8 @@ get_capabilities(NMModem *_self,
*current_caps = NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS;
}
+static void do_context_activate(NMModemOfono *self);
+
static void
update_modem_state(NMModemOfono *self)
{
@@ -163,8 +167,27 @@ update_modem_state(NMModemOfono *self)
reason = "modem ready";
}
- if (state != new_state)
+ if (state != new_state) {
+ if (new_state == NM_MODEM_STATE_DISABLED && priv->deferred_connection_timeout_source) {
+ /*
+ * Do this before set_state(), because we want the final device state
+ * to be "unavailable", not "failed" or "disconnected".
+ */
+ _LOGI("canceling deferred context activation");
+
+ nm_clear_g_source_inst(&priv->deferred_connection_timeout_source);
+ nm_modem_emit_prepare_result(NM_MODEM(self), FALSE, NM_DEVICE_STATE_REASON_MODEM_BUSY);
+ }
+
nm_modem_set_state(NM_MODEM(self), new_state, reason);
+
+ if (new_state == NM_MODEM_STATE_REGISTERED && priv->deferred_connection_timeout_source) {
+ _LOGI("resuming deferred context activation");
+
+ nm_clear_g_source_inst(&priv->deferred_connection_timeout_source);
+ do_context_activate(self);
+ }
+ }
}
/* Disconnect */
@@ -1450,6 +1473,20 @@ create_connect_properties(NMConnection *connection)
return properties;
}
+static gboolean
+wait_for_signal_timeout(gpointer user_data)
+{
+ NMModemOfono *self = NM_MODEM_OFONO(user_data);
+ NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE(self);
+
+ nm_modem_emit_prepare_result(NM_MODEM(self),
+ FALSE,
+ NM_DEVICE_STATE_REASON_GSM_REGISTRATION_TIMEOUT);
+
+ nm_clear_g_source_inst(&priv->deferred_connection_timeout_source);
+ return G_SOURCE_REMOVE;
+}
+
static NMActStageReturn
modem_act_stage1_prepare(NMModem *modem,
NMConnection *connection,
@@ -1476,6 +1513,13 @@ modem_act_stage1_prepare(NMModem *modem,
update_modem_state(self);
if (nm_modem_get_state(modem) == NM_MODEM_STATE_REGISTERED) {
do_context_activate(self);
+ } else if (nm_modem_get_state(modem) == NM_MODEM_STATE_SEARCHING) {
+ _LOGI("activation deferred while modem is searching for signal.");
+
+ nm_clear_g_source_inst(&priv->deferred_connection_timeout_source);
+ priv->deferred_connection_timeout_source =
+ nm_g_timeout_add_seconds_source(60 /* seconds */, wait_for_signal_timeout, self);
+ /* update_modem_state() will advance the next step. */
} else {
_LOGW("could not activate context: modem is not registered.");
NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER);
@@ -1640,6 +1684,8 @@ dispose(GObject *object)
g_free(priv->imsi);
priv->imsi = NULL;
+ nm_clear_g_source_inst(&priv->deferred_connection_timeout_source);
+
G_OBJECT_CLASS(nm_modem_ofono_parent_class)->dispose(object);
}