aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mm-broadband-modem-mbim.c33
-rw-r--r--src/mm-broadband-modem-qmi.c38
-rw-r--r--src/mm-broadband-modem.c11
-rw-r--r--src/mm-iface-modem.c102
-rw-r--r--src/mm-iface-modem.h29
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);