diff options
-rw-r--r-- | plugins/telit/mm-broadband-modem-telit.c | 128 | ||||
-rw-r--r-- | src/mm-broadband-modem.c | 128 | ||||
-rw-r--r-- | src/mm-iface-modem.c | 32 | ||||
-rw-r--r-- | src/mm-iface-modem.h | 10 |
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, |