aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--plugins/telit/mm-broadband-modem-telit.c128
-rw-r--r--src/mm-broadband-modem.c128
-rw-r--r--src/mm-iface-modem.c32
-rw-r--r--src/mm-iface-modem.h10
4 files changed, 176 insertions, 122 deletions
diff --git a/plugins/telit/mm-broadband-modem-telit.c b/plugins/telit/mm-broadband-modem-telit.c
index 995ae6a9..08917ca4 100644
--- a/plugins/telit/mm-broadband-modem-telit.c
+++ b/plugins/telit/mm-broadband-modem-telit.c
@@ -911,20 +911,6 @@ modem_load_unlock_retries (MMIfaceModem *self,
/*****************************************************************************/
/* Modem after power up (Modem interface) */
-typedef enum {
- AFTER_POWER_UP_STEP_FIRST,
- AFTER_POWER_UP_STEP_GET_SIM_IDENTIFIER,
- AFTER_POWER_UP_STEP_ENABLE_QSS_PARSING,
- AFTER_POWER_UP_STEP_LAST
-} ModemAfterPowerUpStep;
-
-typedef struct {
- gboolean has_sim_changed;
- guint retries;
- ModemAfterPowerUpStep step;
-} AfterPowerUpContext;
-
-static void after_power_up_step (GTask *task);
static gboolean
modem_after_power_up_finish (MMIfaceModem *self,
@@ -935,122 +921,20 @@ modem_after_power_up_finish (MMIfaceModem *self,
}
static void
-load_sim_identifier_ready (MMBaseSim *sim,
- GAsyncResult *res,
- GTask *task)
-{
- AfterPowerUpContext *ctx;
- GError *error = NULL;
- gchar *current_simid;
- const gchar *cached_simid;
-
- ctx = g_task_get_task_data (task);
-
- cached_simid = (gchar *)mm_gdbus_sim_get_sim_identifier (MM_GDBUS_SIM (sim));
- current_simid = mm_base_sim_load_sim_identifier_finish (sim, res, &error);
-
- if (error) {
- if (g_error_matches (error, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED)) {
- mm_warn ("could not load SIM identifier: %s", error->message);
- g_clear_error (&error);
- goto out;
- }
-
- if (ctx->retries-- > 0) {
- mm_warn ("could not load SIM identifier: %s (%d retries left)",
- error->message, ctx->retries);
- g_clear_error (&error);
- g_timeout_add_seconds (1, (GSourceFunc) after_power_up_step, task);
- return;
- }
-
- mm_warn ("could not load SIM identifier: %s", error->message);
- g_clear_error (&error);
- goto out;
- }
-
- if (g_strcmp0 (current_simid, cached_simid) != 0) {
- mm_warn ("sim identifier has changed: possible SIM swap during power down/low");
- ctx->has_sim_changed = TRUE;
- }
-
-out:
- g_free (current_simid);
- ctx->step++;
- after_power_up_step (task);
-}
-
-static void
-after_power_up_step (GTask *task)
-{
- AfterPowerUpContext *ctx;
- MMBroadbandModemTelit *self;
-
- ctx = g_task_get_task_data (task);
- self = g_task_get_source_object (task);
-
- switch (ctx->step) {
- case AFTER_POWER_UP_STEP_FIRST:
- /* Fall back on next step */
- ctx->step++;
-
- case AFTER_POWER_UP_STEP_GET_SIM_IDENTIFIER: {
- MMBaseSim *sim = NULL;
-
- g_object_get (MM_BROADBAND_MODEM_TELIT (self),
- MM_IFACE_MODEM_SIM, &sim,
- NULL);
- if (!sim) {
- g_task_return_new_error (task,
- MM_CORE_ERROR,
- MM_CORE_ERROR_FAILED,
- "could not acquire sim object");
- g_object_unref (task);
- return;
- }
-
- mm_base_sim_load_sim_identifier (sim,
- (GAsyncReadyCallback)load_sim_identifier_ready,
- task);
- g_object_unref (sim);
- return;
- }
-
- case AFTER_POWER_UP_STEP_ENABLE_QSS_PARSING:
- mm_dbg ("Stop ignoring #QSS");
- self->priv->parse_qss = TRUE;
-
- /* Fall back on next step */
- ctx->step++;
- case AFTER_POWER_UP_STEP_LAST:
- if (ctx->has_sim_changed)
- mm_broadband_modem_update_sim_hot_swap_detected (MM_BROADBAND_MODEM (self));
-
- g_task_return_boolean (task, TRUE);
- g_object_unref (task);
- break;
- default:
- g_assert_not_reached ();
- }
-}
-
-static void
modem_after_power_up (MMIfaceModem *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
GTask *task;
- AfterPowerUpContext *ctx;
-
- ctx = g_new0 (AfterPowerUpContext, 1);
- ctx->step = AFTER_POWER_UP_STEP_FIRST;
- ctx->has_sim_changed = FALSE;
- ctx->retries = 3;
+ MMBroadbandModemTelit *modem = MM_BROADBAND_MODEM_TELIT (self);
task = g_task_new (self, NULL, callback, user_data);
- g_task_set_task_data (task, ctx, (GDestroyNotify) g_free);
- after_power_up_step (task);
+ mm_dbg ("Stop ignoring #QSS");
+ modem->priv->parse_qss = TRUE;
+
+ g_task_return_boolean (task, TRUE);
+ g_object_unref (task);
}
/*****************************************************************************/
diff --git a/src/mm-broadband-modem.c b/src/mm-broadband-modem.c
index c97afc13..f82122b1 100644
--- a/src/mm-broadband-modem.c
+++ b/src/mm-broadband-modem.c
@@ -3357,6 +3357,132 @@ modem_power_up (MMIfaceModem *self,
}
/*****************************************************************************/
+/* Reprobing the modem if the SIM changed across a power-off or power-down */
+
+typedef struct {
+ MMBaseSim *sim;
+ guint retries;
+} SimSwapContext;
+
+static gboolean load_sim_identifier (GTask *task);
+
+static void
+sim_swap_context_free (SimSwapContext *ctx)
+{
+ g_clear_object (&ctx->sim);
+ g_slice_free (SimSwapContext, ctx);
+}
+
+static gboolean
+modem_check_for_sim_swap_finish (MMIfaceModem *self,
+ GAsyncResult *res,
+ GError **error)
+{
+ return g_task_propagate_boolean (G_TASK (res), error);
+}
+
+static void
+load_sim_identifier_ready (MMBaseSim *sim,
+ GAsyncResult *res,
+ GTask *task)
+{
+ MMBroadbandModem *self;
+ SimSwapContext *ctx;
+ const gchar *cached_simid;
+ gchar *current_simid;
+ GError *error = NULL;
+
+ self = MM_BROADBAND_MODEM (g_task_get_source_object (task));
+ ctx = g_task_get_task_data (task);
+ cached_simid = mm_gdbus_sim_get_sim_identifier (MM_GDBUS_SIM (sim));
+ current_simid = MM_BASE_SIM_GET_CLASS (sim)->load_sim_identifier_finish (sim, res, &error);
+
+ if (error) {
+ if (g_error_matches (error, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED)) {
+ g_task_return_error (task, error);
+ goto out;
+ }
+
+ if (ctx->retries > 0) {
+ mm_warn ("could not load SIM identifier: %s (%d retries left)",
+ error->message, ctx->retries);
+ --ctx->retries;
+ g_clear_error (&error);
+ g_timeout_add_seconds (1, (GSourceFunc) load_sim_identifier, task);
+ return;
+ }
+
+ mm_warn ("could not load SIM identifier: %s", error->message);
+ g_task_return_error (task, error);
+ goto out;
+ }
+
+ if (g_strcmp0 (current_simid, cached_simid) != 0) {
+ mm_info ("sim identifier has changed: possible SIM swap during power down/low");
+ mm_broadband_modem_update_sim_hot_swap_detected (self);
+ }
+
+ g_task_return_boolean (task, TRUE);
+
+out:
+ g_free (current_simid);
+ g_object_unref (task);
+}
+
+static gboolean
+load_sim_identifier (GTask *task)
+{
+ SimSwapContext *ctx = g_task_get_task_data (task);
+
+ MM_BASE_SIM_GET_CLASS (ctx->sim)->load_sim_identifier (
+ ctx->sim,
+ (GAsyncReadyCallback)load_sim_identifier_ready,
+ task);
+
+ return G_SOURCE_REMOVE;
+}
+
+static void
+modem_check_for_sim_swap (MMIfaceModem *self,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GTask *task;
+ SimSwapContext *ctx;
+
+ mm_dbg ("Checking if SIM was swapped...");
+
+ task = g_task_new (self, NULL, callback, user_data);
+ ctx = g_slice_new0 (SimSwapContext);
+ ctx->retries = 3;
+ g_task_set_task_data (task, ctx, (GDestroyNotify)sim_swap_context_free);
+
+ g_object_get (self,
+ MM_IFACE_MODEM_SIM, &ctx->sim,
+ NULL);
+ if (!ctx->sim) {
+ g_task_return_new_error (task,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_FAILED,
+ "could not acquire sim object");
+ g_object_unref (task);
+ return;
+ }
+
+ if (!MM_BASE_SIM_GET_CLASS (ctx->sim)->load_sim_identifier ||
+ !MM_BASE_SIM_GET_CLASS (ctx->sim)->load_sim_identifier_finish) {
+ g_task_return_new_error (task,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_FAILED,
+ "sim identifier could not be loaded");
+ g_object_unref (task);
+ return;
+ }
+
+ load_sim_identifier (task);
+}
+
+/*****************************************************************************/
/* Sending a command to the modem (Modem interface) */
static const gchar *
@@ -10767,6 +10893,8 @@ iface_modem_init (MMIfaceModem *iface)
/* Enabling steps */
iface->modem_power_up = modem_power_up;
iface->modem_power_up_finish = modem_power_up_finish;
+ iface->check_for_sim_swap = modem_check_for_sim_swap;
+ iface->check_for_sim_swap_finish = modem_check_for_sim_swap_finish;
iface->setup_flow_control = modem_setup_flow_control;
iface->setup_flow_control_finish = modem_setup_flow_control_finish;
iface->load_supported_charsets = modem_load_supported_charsets;
diff --git a/src/mm-iface-modem.c b/src/mm-iface-modem.c
index afb3be32..7236e30b 100644
--- a/src/mm-iface-modem.c
+++ b/src/mm-iface-modem.c
@@ -3557,6 +3557,7 @@ static void interface_enabling_step (GTask *task);
typedef enum {
ENABLING_STEP_FIRST,
ENABLING_STEP_SET_POWER_STATE,
+ ENABLING_STEP_CHECK_FOR_SIM_SWAP,
ENABLING_STEP_FLOW_CONTROL,
ENABLING_STEP_SUPPORTED_CHARSETS,
ENABLING_STEP_CHARSET,
@@ -3607,6 +3608,25 @@ enabling_set_power_state_ready (MMIfaceModem *self,
}
static void
+check_for_sim_swap_ready (MMIfaceModem *self,
+ GAsyncResult *res,
+ GTask *task)
+{
+ EnablingContext *ctx;
+ GError *error = NULL;
+
+ if (!MM_IFACE_MODEM_GET_INTERFACE (self)->check_for_sim_swap_finish (self, res, &error)) {
+ mm_warn ("Error checking if SIM was swapped: '%s'", error->message);
+ g_error_free (error);
+ }
+
+ /* Go on to next step */
+ ctx = g_task_get_task_data (task);
+ ctx->step++;
+ interface_enabling_step (task);
+}
+
+static void
setup_flow_control_ready (MMIfaceModem *self,
GAsyncResult *res,
GTask *task)
@@ -3709,6 +3729,18 @@ interface_enabling_step (GTask *task)
task);
return;
+ case ENABLING_STEP_CHECK_FOR_SIM_SWAP:
+ if (MM_IFACE_MODEM_GET_INTERFACE (self)->check_for_sim_swap &&
+ MM_IFACE_MODEM_GET_INTERFACE (self)->check_for_sim_swap_finish) {
+ MM_IFACE_MODEM_GET_INTERFACE (self)->check_for_sim_swap (
+ self,
+ (GAsyncReadyCallback)check_for_sim_swap_ready,
+ task);
+ return;
+ }
+ /* Fall down to next step */
+ ctx->step++;
+
case ENABLING_STEP_FLOW_CONTROL:
if (MM_IFACE_MODEM_GET_INTERFACE (self)->setup_flow_control &&
MM_IFACE_MODEM_GET_INTERFACE (self)->setup_flow_control_finish) {
diff --git a/src/mm-iface-modem.h b/src/mm-iface-modem.h
index d25fbd49..177bf910 100644
--- a/src/mm-iface-modem.h
+++ b/src/mm-iface-modem.h
@@ -281,6 +281,16 @@ struct _MMIfaceModem {
GAsyncResult *res,
GError **error);
+ /* Asynchronous check to see if the SIM was swapped.
+ * Useful for when the modem changes power states since we might
+ * not get the relevant notifications from the modem. */
+ void (*check_for_sim_swap) (MMIfaceModem *self,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ gboolean (*check_for_sim_swap_finish) (MMIfaceModem *self,
+ GAsyncResult *res,
+ GError **error);
+
/* Asynchronous flow control setup */
void (*setup_flow_control) (MMIfaceModem *self,
GAsyncReadyCallback callback,