diff options
-rw-r--r-- | src/mm-broadband-modem-mbim.c | 33 | ||||
-rw-r--r-- | src/mm-broadband-modem-qmi.c | 38 | ||||
-rw-r--r-- | src/mm-broadband-modem.c | 11 | ||||
-rw-r--r-- | src/mm-iface-modem.c | 102 | ||||
-rw-r--r-- | src/mm-iface-modem.h | 29 |
5 files changed, 143 insertions, 70 deletions
diff --git a/src/mm-broadband-modem-mbim.c b/src/mm-broadband-modem-mbim.c index b46dce72..2bf032f8 100644 --- a/src/mm-broadband-modem-mbim.c +++ b/src/mm-broadband-modem-mbim.c @@ -1518,12 +1518,12 @@ load_unlock_required_context_free (LoadUnlockRequiredContext *ctx) } static MMModemLock -modem_load_unlock_required_finish (MMIfaceModem *self, - GAsyncResult *res, - GError **error) +modem_load_unlock_required_finish (MMIfaceModem *self, + GAsyncResult *res, + GError **error) { GError *inner_error = NULL; - gssize value; + gssize value; value = g_task_propagate_int (G_TASK (res), &inner_error); if (inner_error) { @@ -1534,9 +1534,9 @@ modem_load_unlock_required_finish (MMIfaceModem *self, } static void -pin_query_ready (MbimDevice *device, +pin_query_ready (MbimDevice *device, GAsyncResult *res, - GTask *task) + GTask *task) { MbimMessage *response; GError *error = NULL; @@ -1575,8 +1575,6 @@ pin_query_ready (MbimDevice *device, mbim_message_unref (response); } -static gboolean wait_for_sim_ready (GTask *task); - static void unlock_required_subscriber_ready_state_ready (MbimDevice *device, GAsyncResult *res, @@ -1714,7 +1712,7 @@ unlock_required_subscriber_ready_state_ready (MbimDevice *device, mbim_device_command (device, message, 10, - NULL, + g_task_get_cancellable (task), (GAsyncReadyCallback)pin_query_ready, task); mbim_message_unref (message); @@ -1740,7 +1738,7 @@ wait_for_sim_ready (GTask *task) mbim_device_command (ctx->device, message, 10, - NULL, + g_task_get_cancellable (task), (GAsyncReadyCallback)unlock_required_subscriber_ready_state_ready, task); mbim_message_unref (message); @@ -1748,14 +1746,15 @@ wait_for_sim_ready (GTask *task) } static void -modem_load_unlock_required (MMIfaceModem *self, - gboolean last_attempt, - GAsyncReadyCallback callback, - gpointer user_data) +modem_load_unlock_required (MMIfaceModem *self, + gboolean last_attempt, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) { LoadUnlockRequiredContext *ctx; - MbimDevice *device; - GTask *task; + MbimDevice *device; + GTask *task; if (!peek_device (self, &device, callback, user_data)) return; @@ -1764,7 +1763,7 @@ modem_load_unlock_required (MMIfaceModem *self, ctx->device = g_object_ref (device); ctx->last_attempt = last_attempt; - task = g_task_new (self, NULL, callback, user_data); + task = g_task_new (self, cancellable, callback, user_data); g_task_set_task_data (task, ctx, (GDestroyNotify)load_unlock_required_context_free); wait_for_sim_ready (task); diff --git a/src/mm-broadband-modem-qmi.c b/src/mm-broadband-modem-qmi.c index 239834bd..ecdfbbc0 100644 --- a/src/mm-broadband-modem-qmi.c +++ b/src/mm-broadband-modem-qmi.c @@ -863,9 +863,9 @@ typedef struct { } LoadUnlockRequiredContext; static MMModemLock -modem_load_unlock_required_finish (MMIfaceModem *self, - GAsyncResult *res, - GError **error) +modem_load_unlock_required_finish (MMIfaceModem *self, + GAsyncResult *res, + GError **error) { GError *inner_error = NULL; gssize value; @@ -883,7 +883,7 @@ static void load_unlock_required_context_step (GTask *task); static void unlock_required_uim_get_card_status_ready (QmiClientUim *client, GAsyncResult *res, - GTask *task) + GTask *task) { MMBroadbandModemQmi *self; LoadUnlockRequiredContext *ctx; @@ -928,7 +928,7 @@ unlock_required_uim_get_card_status_ready (QmiClientUim *client, static void dms_uim_get_pin_status_ready (QmiClientDms *client, GAsyncResult *res, - GTask *task) + GTask *task) { MMBroadbandModemQmi *self; LoadUnlockRequiredContext *ctx; @@ -1025,14 +1025,19 @@ dms_uim_get_pin_status_ready (QmiClientDms *client, static void load_unlock_required_context_step (GTask *task) { - MMBroadbandModemQmi *self; + MMBroadbandModemQmi *self; LoadUnlockRequiredContext *ctx; - GError *error = NULL; - QmiClient *client; + GError *error = NULL; + QmiClient *client; self = g_task_get_source_object (task); ctx = g_task_get_task_data (task); + if (g_task_return_error_if_cancelled (task)) { + g_object_unref (task); + return; + } + switch (ctx->step) { case LOAD_UNLOCK_REQUIRED_STEP_FIRST: ctx->step++; @@ -1066,7 +1071,7 @@ load_unlock_required_context_step (GTask *task) qmi_client_dms_uim_get_pin_status (QMI_CLIENT_DMS (client), NULL, 5, - NULL, + g_task_get_cancellable (task), (GAsyncReadyCallback) dms_uim_get_pin_status_ready, task); return; @@ -1090,7 +1095,7 @@ load_unlock_required_context_step (GTask *task) qmi_client_uim_get_card_status (QMI_CLIENT_UIM (client), NULL, 5, - NULL, + g_task_get_cancellable (task), (GAsyncReadyCallback) unlock_required_uim_get_card_status_ready, task); return; @@ -1101,19 +1106,20 @@ load_unlock_required_context_step (GTask *task) } static void -modem_load_unlock_required (MMIfaceModem *self, - gboolean last_attempt, - GAsyncReadyCallback callback, - gpointer user_data) +modem_load_unlock_required (MMIfaceModem *self, + gboolean last_attempt, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) { LoadUnlockRequiredContext *ctx; - GTask *task; + GTask *task; ctx = g_new0 (LoadUnlockRequiredContext, 1); ctx->step = LOAD_UNLOCK_REQUIRED_STEP_FIRST; ctx->last_attempt = last_attempt; - task = g_task_new (self, NULL, callback, user_data); + task = g_task_new (self, cancellable, callback, user_data); g_task_set_task_data (task, ctx, g_free); load_unlock_required_context_step (task); diff --git a/src/mm-broadband-modem.c b/src/mm-broadband-modem.c index 4f7e5cf8..7335e500 100644 --- a/src/mm-broadband-modem.c +++ b/src/mm-broadband-modem.c @@ -1529,14 +1529,15 @@ cpin_query_ready (MMIfaceModem *self, } static void -modem_load_unlock_required (MMIfaceModem *self, - gboolean last_attempt, - GAsyncReadyCallback callback, - gpointer user_data) +modem_load_unlock_required (MMIfaceModem *self, + gboolean last_attempt, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) { GTask *task; - task = g_task_new (self, NULL, callback, user_data); + task = g_task_new (self, cancellable, callback, user_data); /* CDMA-only modems don't need this */ if (mm_iface_modem_is_cdma_only (self)) { diff --git a/src/mm-iface-modem.c b/src/mm-iface-modem.c index fb8fb9c5..bc3f9a86 100644 --- a/src/mm-iface-modem.c +++ b/src/mm-iface-modem.c @@ -571,11 +571,20 @@ mm_iface_modem_abort_invocation_if_state_not_reached (MMIfaceModem *sel #define UNLOAD_REQUIRED_RETRY_TIMEOUT_SECS 2 typedef struct { - guint retries; - guint max_retries; - guint timeout_id; + guint retries; + guint max_retries; + guint timeout_id; + gulong cancellable_id; } InternalLoadUnlockRequiredContext; +static void +internal_load_unlock_required_context_free (InternalLoadUnlockRequiredContext *ctx) +{ + g_assert (!ctx->timeout_id); + g_assert (!ctx->cancellable_id); + g_slice_free (InternalLoadUnlockRequiredContext, ctx); +} + static MMModemLock internal_load_unlock_required_finish (MMIfaceModem *self, GAsyncResult *res, @@ -601,12 +610,41 @@ load_unlock_required_again (GTask *task) ctx = g_task_get_task_data (task); ctx->timeout_id = 0; + + g_assert (ctx->cancellable_id); + g_cancellable_disconnect (g_task_get_cancellable (task), ctx->cancellable_id); + ctx->cancellable_id = 0; + /* Retry the step */ internal_load_unlock_required_context_step (task); return G_SOURCE_REMOVE; } static void +load_unlock_required_again_cancelled (GCancellable *cancellable, + GTask *task) +{ + InternalLoadUnlockRequiredContext *ctx; + MMIfaceModem *self; + + self = g_task_get_source_object (task); + ctx = g_task_get_task_data (task); + + ctx->cancellable_id = 0; + + if (ctx->timeout_id) { + g_source_remove (ctx->timeout_id); + ctx->timeout_id = 0; + } + + mm_obj_dbg (self, "unlock required check retries cancelled"); + + if (!g_task_return_error_if_cancelled (task)) + g_assert_not_reached (); + g_object_unref (task); +} + +static void load_unlock_required_ready (MMIfaceModem *self, GAsyncResult *res, GTask *task) @@ -655,6 +693,18 @@ load_unlock_required_ready (MMIfaceModem *self, else mm_obj_info (self, "retrying (%u/%u) unlock required check", ctx->retries, ctx->max_retries); + /* Ownership of the task will be shared between the timeout and the cancellable. As soon as one + * of them is triggered, it should cancel the other. */ + + g_assert (ctx->cancellable_id == 0); + ctx->cancellable_id = g_cancellable_connect (g_task_get_cancellable (task), + (GCallback) load_unlock_required_again_cancelled, + task, + NULL); + /* Do nothing if already cancelled, the callback will already be called */ + if (!ctx->cancellable_id) + return; + g_assert (ctx->timeout_id == 0); ctx->timeout_id = g_timeout_add_seconds (UNLOAD_REQUIRED_RETRY_TIMEOUT_SECS, (GSourceFunc)load_unlock_required_again, @@ -686,10 +736,18 @@ internal_load_unlock_required_context_step (GTask *task) self = g_task_get_source_object (task); ctx = g_task_get_task_data (task); + /* Don't run a new check if we were already cancelled */ + if (g_task_return_error_if_cancelled (task)) { + g_object_unref (task); + return; + } + + g_assert (ctx->cancellable_id == 0); g_assert (ctx->timeout_id == 0); MM_IFACE_MODEM_GET_INTERFACE (self)->load_unlock_required ( self, (ctx->retries >= ctx->max_retries), /* last_attempt? */ + g_task_get_cancellable (task), (GAsyncReadyCallback) load_unlock_required_ready, task); } @@ -708,17 +766,18 @@ load_unlock_required_max_retries (MMIfaceModem *self) static void internal_load_unlock_required (MMIfaceModem *self, + GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { InternalLoadUnlockRequiredContext *ctx; GTask *task; - ctx = g_new0 (InternalLoadUnlockRequiredContext, 1); - ctx->max_retries = load_unlock_required_max_retries (self); + task = g_task_new (self, cancellable, callback, user_data); - task = g_task_new (self, NULL, callback, user_data); - g_task_set_task_data (task, ctx, g_free); + ctx = g_slice_new0 (InternalLoadUnlockRequiredContext); + ctx->max_retries = load_unlock_required_max_retries (self); + g_task_set_task_data (task, ctx, (GDestroyNotify)internal_load_unlock_required_context_free); if (!MM_IFACE_MODEM_GET_INTERFACE (self)->load_unlock_required || !MM_IFACE_MODEM_GET_INTERFACE (self)->load_unlock_required_finish) { @@ -3725,10 +3784,9 @@ typedef struct { static void update_lock_info_context_free (UpdateLockInfoContext *ctx) { - g_assert (ctx->saved_error == NULL); - - if (ctx->skeleton) - g_object_unref (ctx->skeleton); + /* saved error may exist if we were cancelled */ + g_clear_pointer (&ctx->saved_error, g_error_free); + g_clear_object (&ctx->skeleton); g_slice_free (UpdateLockInfoContext, ctx); } @@ -3855,12 +3913,18 @@ internal_load_unlock_required_ready (MMIfaceModem *self, static void update_lock_info_context_step (GTask *task) { - MMIfaceModem *self; + MMIfaceModem *self; UpdateLockInfoContext *ctx; self = g_task_get_source_object (task); ctx = g_task_get_task_data (task); + if (g_task_return_error_if_cancelled (task)) { + mm_obj_dbg (self, "lock info update cancelled"); + g_object_unref (task); + return; + } + switch (ctx->step) { case UPDATE_LOCK_INFO_CONTEXT_STEP_FIRST: /* We need the skeleton around */ @@ -3881,6 +3945,7 @@ update_lock_info_context_step (GTask *task) /* If we're already unlocked, we're done */ internal_load_unlock_required ( self, + g_task_get_cancellable (task), (GAsyncReadyCallback)internal_load_unlock_required_ready, task); return; @@ -3946,20 +4011,20 @@ update_lock_info_context_step (GTask *task) } void -mm_iface_modem_update_lock_info (MMIfaceModem *self, - MMModemLock known_lock, - GAsyncReadyCallback callback, - gpointer user_data) +mm_iface_modem_update_lock_info (MMIfaceModem *self, + MMModemLock known_lock, + GAsyncReadyCallback callback, + gpointer user_data) { UpdateLockInfoContext *ctx; - GTask *task; + GTask *task; ctx = g_slice_new0 (UpdateLockInfoContext); /* If the given lock is known, we will avoid re-asking for it */ ctx->lock = known_lock; - task = g_task_new (self, NULL, callback, user_data); + task = g_task_new (self, mm_base_modem_peek_cancellable (MM_BASE_MODEM (self)), callback, user_data); g_task_set_task_data (task, ctx, (GDestroyNotify)update_lock_info_context_free); g_object_get (self, @@ -4683,6 +4748,7 @@ interface_syncing_step (GTask *task) MM_IFACE_MODEM_GET_INTERFACE (self)->load_unlock_required ( self, FALSE, + NULL, (GAsyncReadyCallback)sync_sim_lock_ready, task); return; diff --git a/src/mm-iface-modem.h b/src/mm-iface-modem.h index 37c961d8..daf3404d 100644 --- a/src/mm-iface-modem.h +++ b/src/mm-iface-modem.h @@ -122,13 +122,14 @@ struct _MMIfaceModem { GError **error); /* Loading of the UnlockRequired property */ - void (*load_unlock_required) (MMIfaceModem *self, - gboolean last_attempt, - GAsyncReadyCallback callback, - gpointer user_data); - MMModemLock (*load_unlock_required_finish) (MMIfaceModem *self, - GAsyncResult *res, - GError **error); + void (*load_unlock_required) (MMIfaceModem *self, + gboolean last_attempt, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + MMModemLock (*load_unlock_required_finish) (MMIfaceModem *self, + GAsyncResult *res, + GError **error); /* Loading of the UnlockRetries property */ void (*load_unlock_retries) (MMIfaceModem *self, @@ -516,13 +517,13 @@ gboolean mm_iface_modem_set_power_state_finish (MMIfaceModem *self, * It will not only return the lock status, but also set the property values * in the DBus interface. If 'known_lock' is given, that lock status will be * assumed. */ -void mm_iface_modem_update_lock_info (MMIfaceModem *self, - MMModemLock known_lock, - GAsyncReadyCallback callback, - gpointer user_data); -MMModemLock mm_iface_modem_update_lock_info_finish (MMIfaceModem *self, - GAsyncResult *res, - GError **error); +void mm_iface_modem_update_lock_info (MMIfaceModem *self, + MMModemLock known_lock, + GAsyncReadyCallback callback, + gpointer user_data); +MMModemLock mm_iface_modem_update_lock_info_finish (MMIfaceModem *self, + GAsyncResult *res, + GError **error); MMModemLock mm_iface_modem_get_unlock_required (MMIfaceModem *self); MMUnlockRetries *mm_iface_modem_get_unlock_retries (MMIfaceModem *self); |