diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mm-iface-modem-simple.c | 15 | ||||
-rw-r--r-- | src/mm-iface-modem.c | 447 | ||||
-rw-r--r-- | src/mm-iface-modem.h | 26 | ||||
-rw-r--r-- | src/mm-sim.c | 119 |
4 files changed, 310 insertions, 297 deletions
diff --git a/src/mm-iface-modem-simple.c b/src/mm-iface-modem-simple.c index 2c2c58ff..12aa1520 100644 --- a/src/mm-iface-modem-simple.c +++ b/src/mm-iface-modem-simple.c @@ -437,15 +437,15 @@ send_pin_ready (MMSim *sim, } static void -unlock_check_ready (MMIfaceModem *self, - GAsyncResult *res, - ConnectionContext *ctx) +update_lock_info_ready (MMIfaceModem *self, + GAsyncResult *res, + ConnectionContext *ctx) { GError *error = NULL; MMModemLock lock; MMSim *sim; - lock = mm_iface_modem_unlock_check_finish (self, res, &error); + lock = mm_iface_modem_update_lock_info_finish (self, res, &error); if (error) { g_dbus_method_invocation_take_error (ctx->invocation, error); connection_context_free (ctx); @@ -524,9 +524,10 @@ connection_step (ConnectionContext *ctx) case CONNECTION_STEP_UNLOCK_CHECK: mm_info ("Simple connect state (%d/%d): Unlock check", ctx->step, CONNECTION_STEP_LAST); - mm_iface_modem_unlock_check (MM_IFACE_MODEM (ctx->self), - (GAsyncReadyCallback)unlock_check_ready, - ctx); + mm_iface_modem_update_lock_info (MM_IFACE_MODEM (ctx->self), + MM_MODEM_LOCK_UNKNOWN, /* ask */ + (GAsyncReadyCallback)update_lock_info_ready, + ctx); return; case CONNECTION_STEP_WAIT_FOR_INITIALIZED: diff --git a/src/mm-iface-modem.c b/src/mm-iface-modem.c index e94bc42a..9b5f8dcd 100644 --- a/src/mm-iface-modem.c +++ b/src/mm-iface-modem.c @@ -2225,26 +2225,6 @@ handle_set_allowed_modes (MmGdbusModem *skeleton, /*****************************************************************************/ -typedef struct { - MMIfaceModem *self; - guint pin_check_tries; - guint pin_check_timeout_id; - GSimpleAsyncResult *result; - MmGdbusModem *skeleton; - MMModemLock lock; -} UnlockCheckContext; - -static void -unlock_check_context_complete_and_free (UnlockCheckContext *ctx) -{ - g_simple_async_result_complete_in_idle (ctx->result); - g_object_unref (ctx->result); - g_object_unref (ctx->self); - if (ctx->skeleton) - g_object_unref (ctx->skeleton); - g_free (ctx); -} - static void reinitialize_ready (MMBaseModem *self, GAsyncResult *res) @@ -2303,10 +2283,78 @@ set_lock_status (MMIfaceModem *self, } } +static void +update_unlock_retries (MMIfaceModem *self, + MMUnlockRetries *unlock_retries) +{ + MmGdbusModem *skeleton = NULL; + GError *error = NULL; + GVariant *previous_dictionary; + MMUnlockRetries *previous_unlock_retries; + + g_object_get (self, + MM_IFACE_MODEM_DBUS_SKELETON, &skeleton, + NULL); + if (!skeleton) + return; + + previous_dictionary = mm_gdbus_modem_get_unlock_retries (skeleton); + previous_unlock_retries = mm_unlock_retries_new_from_dictionary (previous_dictionary); + + if (error) { + mm_warn ("Couldn't build previous unlock retries: '%s'", error->message); + g_error_free (error); + } else { + /* If they are different, update */ + if (!mm_unlock_retries_cmp (unlock_retries, previous_unlock_retries)) { + GVariant *new_dictionary; + + new_dictionary = mm_unlock_retries_get_dictionary (unlock_retries); + mm_gdbus_modem_set_unlock_retries (skeleton, new_dictionary); + g_variant_unref (new_dictionary); + } + } + + g_object_unref (previous_unlock_retries); + g_object_unref (skeleton); +} + +typedef enum { + UPDATE_LOCK_INFO_CONTEXT_STEP_FIRST = 0, + UPDATE_LOCK_INFO_CONTEXT_STEP_LOCK, + UPDATE_LOCK_INFO_CONTEXT_STEP_RETRIES, + UPDATE_LOCK_INFO_CONTEXT_STEP_AFTER_UNLOCK, + UPDATE_LOCK_INFO_CONTEXT_STEP_LAST +} UpdateLockInfoContextStep; + +typedef struct { + MMIfaceModem *self; + UpdateLockInfoContextStep step; + guint pin_check_tries; + guint pin_check_timeout_id; + GSimpleAsyncResult *result; + MmGdbusModem *skeleton; + MMModemLock lock; + GError *saved_error; +} UpdateLockInfoContext; + +static void +update_lock_info_context_complete_and_free (UpdateLockInfoContext *ctx) +{ + g_assert (ctx->saved_error == NULL); + + g_simple_async_result_complete_in_idle (ctx->result); + g_object_unref (ctx->result); + g_object_unref (ctx->self); + if (ctx->skeleton) + g_object_unref (ctx->skeleton); + g_slice_free (UpdateLockInfoContext, ctx); +} + MMModemLock -mm_iface_modem_unlock_check_finish (MMIfaceModem *self, - GAsyncResult *res, - GError **error) +mm_iface_modem_update_lock_info_finish (MMIfaceModem *self, + GAsyncResult *res, + GError **error) { if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error)) return MM_MODEM_LOCK_UNKNOWN; @@ -2314,48 +2362,61 @@ mm_iface_modem_unlock_check_finish (MMIfaceModem *self, return (MMModemLock) GPOINTER_TO_UINT (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res))); } -static void unlock_check_ready (MMIfaceModem *self, - GAsyncResult *res, - UnlockCheckContext *ctx); +static void update_lock_info_context_step (UpdateLockInfoContext *ctx); -static gboolean -unlock_check_again (UnlockCheckContext *ctx) +static void +load_unlock_retries_ready (MMIfaceModem *self, + GAsyncResult *res, + UpdateLockInfoContext *ctx) { - ctx->pin_check_timeout_id = 0; + GError *error = NULL; + MMUnlockRetries *unlock_retries; - MM_IFACE_MODEM_GET_INTERFACE (ctx->self)->load_unlock_required ( - ctx->self, - (GAsyncReadyCallback)unlock_check_ready, - ctx); - return FALSE; + unlock_retries = MM_IFACE_MODEM_GET_INTERFACE (self)->load_unlock_retries_finish (self, res, &error); + if (!unlock_retries) { + mm_warn ("Couldn't load unlock retries: '%s'", error->message); + g_error_free (error); + } else { + /* Update the dictionary in the DBus interface */ + update_unlock_retries (self, unlock_retries); + g_object_unref (unlock_retries); + } + + /* Go on to next step */ + ctx->step++; + update_lock_info_context_step (ctx); } static void modem_after_sim_unlock_ready (MMIfaceModem *self, GAsyncResult *res, - UnlockCheckContext *ctx) + UpdateLockInfoContext *ctx) { GError *error = NULL; if (!MM_IFACE_MODEM_GET_INTERFACE (self)->modem_after_sim_unlock_finish (self, res, &error)) { - /* Complete anyway */ mm_warn ("After SIM unlock failed setup: '%s'", error->message); g_error_free (error); } - /* Update lock status and modem status if needed */ - set_lock_status (self, ctx->skeleton, ctx->lock); + /* Go on to next step */ + ctx->step++; + update_lock_info_context_step (ctx); +} - g_simple_async_result_set_op_res_gpointer (ctx->result, - GUINT_TO_POINTER (ctx->lock), - NULL); - unlock_check_context_complete_and_free (ctx); +static gboolean +load_unlock_required_again (UpdateLockInfoContext *ctx) +{ + ctx->pin_check_timeout_id = 0; + /* Retry the step */ + update_lock_info_context_step (ctx); + return FALSE; } static void -unlock_check_ready (MMIfaceModem *self, - GAsyncResult *res, - UnlockCheckContext *ctx) +load_unlock_required_ready (MMIfaceModem *self, + GAsyncResult *res, + UpdateLockInfoContext *ctx) { GError *error = NULL; @@ -2377,13 +2438,13 @@ unlock_check_ready (MMIfaceModem *self, g_error_matches (error, MM_MOBILE_EQUIPMENT_ERROR, MM_MOBILE_EQUIPMENT_ERROR_SIM_WRONG)) { - g_simple_async_result_take_error (ctx->result, error); - unlock_check_context_complete_and_free (ctx); + ctx->saved_error = error; + ctx->step = UPDATE_LOCK_INFO_CONTEXT_STEP_LAST; + update_lock_info_context_step (ctx); return; } - mm_dbg ("Couldn't check if unlock required: '%s'", - error->message); + mm_dbg ("Couldn't check if unlock required: '%s'", error->message); g_error_free (error); /* Retry up to 6 times */ @@ -2394,7 +2455,7 @@ unlock_check_ready (MMIfaceModem *self, g_source_remove (ctx->pin_check_timeout_id); ctx->pin_check_timeout_id = g_timeout_add_seconds ( 2, - (GSourceFunc)unlock_check_again, + (GSourceFunc)load_unlock_required_again, ctx); return; } @@ -2403,177 +2464,131 @@ unlock_check_ready (MMIfaceModem *self, ctx->lock = MM_MODEM_LOCK_UNKNOWN; } - /* If we get that no lock is required, run the after SIM unlock step - * in order to wait for the SIM to get ready */ - if (ctx->lock == MM_MODEM_LOCK_NONE || - ctx->lock == MM_MODEM_LOCK_SIM_PIN2 || - ctx->lock == MM_MODEM_LOCK_SIM_PUK2) { - if (MM_IFACE_MODEM_GET_INTERFACE (self)->modem_after_sim_unlock != NULL && - MM_IFACE_MODEM_GET_INTERFACE (self)->modem_after_sim_unlock_finish != NULL) { - mm_dbg ("SIM is ready, running after SIM unlock step..."); - MM_IFACE_MODEM_GET_INTERFACE (self)->modem_after_sim_unlock( - self, - (GAsyncReadyCallback)modem_after_sim_unlock_ready, - ctx); - return; - } - - /* If no way to run after SIM unlock step, we're done */ - mm_dbg ("SIM is ready, and no need for the after SIM unlock step..."); - } - - /* Update lock status and modem status if needed */ - set_lock_status (self, ctx->skeleton, ctx->lock); - - g_simple_async_result_set_op_res_gpointer (ctx->result, - GUINT_TO_POINTER (ctx->lock), - NULL); - unlock_check_context_complete_and_free (ctx); + /* Go on to next step */ + ctx->step++; + update_lock_info_context_step (ctx); } -void -mm_iface_modem_unlock_check (MMIfaceModem *self, - GAsyncReadyCallback callback, - gpointer user_data) +static void +update_lock_info_context_step (UpdateLockInfoContext *ctx) { - UnlockCheckContext *ctx; + switch (ctx->step) { + case UPDATE_LOCK_INFO_CONTEXT_STEP_FIRST: + /* We need the skeleton around */ + if (!ctx->skeleton) { + ctx->saved_error = g_error_new (MM_CORE_ERROR, + MM_CORE_ERROR_FAILED, + "Couldn't get interface skeleton"); + ctx->step = UPDATE_LOCK_INFO_CONTEXT_STEP_LAST; + update_lock_info_context_step (ctx); + return; + } - ctx = g_new0 (UnlockCheckContext, 1); - ctx->self = g_object_ref (self); - ctx->result = g_simple_async_result_new (G_OBJECT (self), - callback, - user_data, - mm_iface_modem_unlock_check); - g_object_get (ctx->self, - MM_IFACE_MODEM_DBUS_SKELETON, &ctx->skeleton, - NULL); - if (!ctx->skeleton) { - g_simple_async_result_set_error (ctx->result, - MM_CORE_ERROR, - MM_CORE_ERROR_FAILED, - "Couldn't get interface skeleton"); - unlock_check_context_complete_and_free (ctx); - return; - } + /* Fall down to next step */ + ctx->step++; - /* If we're already unlocked, we're done */ - if (mm_gdbus_modem_get_unlock_required (ctx->skeleton) != MM_MODEM_LOCK_NONE && - MM_IFACE_MODEM_GET_INTERFACE (ctx->self)->load_unlock_required && - MM_IFACE_MODEM_GET_INTERFACE (ctx->self)->load_unlock_required_finish) { - MM_IFACE_MODEM_GET_INTERFACE (ctx->self)->load_unlock_required ( - self, - (GAsyncReadyCallback)unlock_check_ready, - ctx); - return; - } + case UPDATE_LOCK_INFO_CONTEXT_STEP_LOCK: + /* Don't re-ask if already known */ + if (ctx->lock == MM_MODEM_LOCK_UNKNOWN) { + /* If we're already unlocked, we're done */ + if (mm_gdbus_modem_get_unlock_required (ctx->skeleton) != MM_MODEM_LOCK_NONE && + MM_IFACE_MODEM_GET_INTERFACE (ctx->self)->load_unlock_required && + MM_IFACE_MODEM_GET_INTERFACE (ctx->self)->load_unlock_required_finish) { + MM_IFACE_MODEM_GET_INTERFACE (ctx->self)->load_unlock_required ( + ctx->self, + (GAsyncReadyCallback)load_unlock_required_ready, + ctx); + return; + } - /* Just assume that no lock is required */ - g_simple_async_result_set_op_res_gpointer (ctx->result, - GUINT_TO_POINTER (MM_MODEM_LOCK_NONE), - NULL); - unlock_check_context_complete_and_free (ctx); -} + /* Just assume that no lock is required */ + ctx->lock = MM_MODEM_LOCK_NONE; + } -/*****************************************************************************/ -/* Unlock retry count */ + /* Fall down to next step */ + ctx->step++; -gboolean -mm_iface_modem_update_unlock_retries_finish (MMIfaceModem *self, - GAsyncResult *res, - GError **error) -{ - if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error)) - return FALSE; + case UPDATE_LOCK_INFO_CONTEXT_STEP_RETRIES: + /* Load unlock retries if possible */ + if (MM_IFACE_MODEM_GET_INTERFACE (ctx->self)->load_unlock_retries && + MM_IFACE_MODEM_GET_INTERFACE (ctx->self)->load_unlock_retries_finish) { + MM_IFACE_MODEM_GET_INTERFACE (ctx->self)->load_unlock_retries ( + ctx->self, + (GAsyncReadyCallback)load_unlock_retries_ready, + ctx); + return; + } - return g_simple_async_result_get_op_res_gboolean (G_SIMPLE_ASYNC_RESULT (res)); -} + /* Fall down to next step */ + ctx->step++; -static void -update_unlock_retries (MMIfaceModem *self, - MMUnlockRetries *unlock_retries) -{ - MmGdbusModem *skeleton = NULL; - GError *error = NULL; - GVariant *previous_dictionary; - MMUnlockRetries *previous_unlock_retries; + case UPDATE_LOCK_INFO_CONTEXT_STEP_AFTER_UNLOCK: + /* If we get that no lock is required, run the after SIM unlock step + * in order to wait for the SIM to get ready */ + if (ctx->lock == MM_MODEM_LOCK_NONE || + ctx->lock == MM_MODEM_LOCK_SIM_PIN2 || + ctx->lock == MM_MODEM_LOCK_SIM_PUK2) { + if (MM_IFACE_MODEM_GET_INTERFACE (ctx->self)->modem_after_sim_unlock != NULL && + MM_IFACE_MODEM_GET_INTERFACE (ctx->self)->modem_after_sim_unlock_finish != NULL) { + mm_dbg ("SIM is ready, running after SIM unlock step..."); + MM_IFACE_MODEM_GET_INTERFACE (ctx->self)->modem_after_sim_unlock ( + ctx->self, + (GAsyncReadyCallback)modem_after_sim_unlock_ready, + ctx); + return; + } - g_object_get (self, - MM_IFACE_MODEM_DBUS_SKELETON, &skeleton, - NULL); - if (!skeleton) - return; + /* If no way to run after SIM unlock step, we're done */ + mm_dbg ("SIM is ready, and no need for the after SIM unlock step..."); + } - previous_dictionary = mm_gdbus_modem_get_unlock_retries (skeleton); - previous_unlock_retries = mm_unlock_retries_new_from_dictionary (previous_dictionary); + /* Fall down to next step */ + ctx->step++; - if (error) { - mm_warn ("Couldn't build previous unlock retries: '%s'", error->message); - g_error_free (error); - } else { - /* If they are different, update */ - if (!mm_unlock_retries_cmp (unlock_retries, previous_unlock_retries)) { - GVariant *new_dictionary; + case UPDATE_LOCK_INFO_CONTEXT_STEP_LAST: + if (ctx->saved_error) { + /* Return saved error */ + g_simple_async_result_take_error (ctx->result, ctx->saved_error); + ctx->saved_error = NULL; + } else { + /* Update lock status and modem status if needed */ + set_lock_status (ctx->self, ctx->skeleton, ctx->lock); - new_dictionary = mm_unlock_retries_get_dictionary (unlock_retries); - mm_gdbus_modem_set_unlock_retries (skeleton, new_dictionary); - g_variant_unref (new_dictionary); + g_simple_async_result_set_op_res_gpointer (ctx->result, + GUINT_TO_POINTER (ctx->lock), + NULL); } - } - - g_object_unref (previous_unlock_retries); - g_object_unref (skeleton); -} - -static void -unlock_retries_ready (MMIfaceModem *self, - GAsyncResult *res, - GSimpleAsyncResult *simple) -{ - GError *error = NULL; - MMUnlockRetries *unlock_retries; - unlock_retries = MM_IFACE_MODEM_GET_INTERFACE (self)->load_unlock_retries_finish (self, res, &error); - if (!unlock_retries) { - g_simple_async_result_take_error (simple, error); - g_simple_async_result_complete (simple); - g_object_unref (simple); + update_lock_info_context_complete_and_free (ctx); return; - } - - /* Update the dictionary in the DBus interface */ - update_unlock_retries (self, unlock_retries); - g_object_unref (unlock_retries); - g_simple_async_result_set_op_res_gboolean (simple, TRUE); - g_simple_async_result_complete (simple); - g_object_unref (simple); + default: + g_assert_not_reached(); + } } void -mm_iface_modem_update_unlock_retries (MMIfaceModem *self, - GAsyncReadyCallback callback, - gpointer user_data) +mm_iface_modem_update_lock_info (MMIfaceModem *self, + MMModemLock known_lock, + GAsyncReadyCallback callback, + gpointer user_data) { - GSimpleAsyncResult *result; + UpdateLockInfoContext *ctx; - result = g_simple_async_result_new (G_OBJECT (self), - callback, - user_data, - mm_iface_modem_update_unlock_retries); + ctx = g_slice_new0 (UpdateLockInfoContext); + ctx->self = g_object_ref (self); + ctx->result = g_simple_async_result_new (G_OBJECT (self), + callback, + user_data, + mm_iface_modem_update_lock_info); + g_object_get (ctx->self, + MM_IFACE_MODEM_DBUS_SKELETON, &ctx->skeleton, + NULL); - if (MM_IFACE_MODEM_GET_INTERFACE (self)->load_unlock_retries && - MM_IFACE_MODEM_GET_INTERFACE (self)->load_unlock_retries_finish) { - MM_IFACE_MODEM_GET_INTERFACE (self)->load_unlock_retries ( - self, - (GAsyncReadyCallback)unlock_retries_ready, - result); - return; - } + /* If the given lock is known, we will avoid re-asking for it */ + ctx->lock = known_lock; - /* Return FALSE when we cannot load unlock retries */ - g_simple_async_result_set_op_res_gboolean (result, FALSE); - g_simple_async_result_complete_in_idle (result); - g_object_unref (result); + update_lock_info_context_step (ctx); } /*****************************************************************************/ @@ -3129,7 +3144,6 @@ typedef enum { INITIALIZATION_STEP_EQUIPMENT_ID, INITIALIZATION_STEP_DEVICE_ID, INITIALIZATION_STEP_UNLOCK_REQUIRED, - INITIALIZATION_STEP_UNLOCK_RETRIES, INITIALIZATION_STEP_SIM, INITIALIZATION_STEP_OWN_NUMBERS, INITIALIZATION_STEP_SUPPORTED_MODES, @@ -3333,12 +3347,12 @@ load_supported_bands_ready (MMIfaceModem *self, } static void -load_unlock_required_ready (MMIfaceModem *self, - GAsyncResult *res, - InitializationContext *ctx) +modem_update_lock_info_ready (MMIfaceModem *self, + GAsyncResult *res, + InitializationContext *ctx) { /* NOTE: we already propagated the lock state, no need to do it again */ - mm_iface_modem_unlock_check_finish (self, res, &ctx->fatal_error); + mm_iface_modem_update_lock_info_finish (self, res, &ctx->fatal_error); if (ctx->fatal_error) { g_prefix_error (&ctx->fatal_error, "Couldn't check unlock status: "); @@ -3352,24 +3366,6 @@ load_unlock_required_ready (MMIfaceModem *self, } static void -update_unlock_retries_ready (MMIfaceModem *self, - GAsyncResult *res, - InitializationContext *ctx) -{ - GError *error = NULL; - - mm_iface_modem_update_unlock_retries_finish (self, res, &error); - if (error) { - mm_warn ("couldn't update unlock retries: '%s'", error->message); - g_error_free (error); - } - - /* Go on to next step */ - ctx->step++; - interface_initialization_step (ctx); -} - -static void sim_new_ready (GAsyncInitable *initable, GAsyncResult *res, InitializationContext *ctx) @@ -3652,20 +3648,15 @@ interface_initialization_step (InitializationContext *ctx) case INITIALIZATION_STEP_UNLOCK_REQUIRED: /* Only check unlock required if we were previously not unlocked */ if (mm_gdbus_modem_get_unlock_required (ctx->skeleton) != MM_MODEM_LOCK_NONE) { - mm_iface_modem_unlock_check (ctx->self, - (GAsyncReadyCallback)load_unlock_required_ready, - ctx); + mm_iface_modem_update_lock_info (ctx->self, + MM_MODEM_LOCK_UNKNOWN, /* ask */ + (GAsyncReadyCallback)modem_update_lock_info_ready, + ctx); return; } /* Fall down to next step */ ctx->step++; - case INITIALIZATION_STEP_UNLOCK_RETRIES: - mm_iface_modem_update_unlock_retries (ctx->self, - (GAsyncReadyCallback)update_unlock_retries_ready, - ctx); - return; - case INITIALIZATION_STEP_SIM: /* If the modem doesn't need any SIM, skip */ if (MM_IFACE_MODEM_GET_INTERFACE (ctx->self)->create_sim && diff --git a/src/mm-iface-modem.h b/src/mm-iface-modem.h index 52b0d8eb..23dac75b 100644 --- a/src/mm-iface-modem.h +++ b/src/mm-iface-modem.h @@ -365,23 +365,17 @@ gboolean mm_iface_modem_disable_finish (MMIfaceModem *self, /* Shutdown Modem interface */ void mm_iface_modem_shutdown (MMIfaceModem *self); -/* Request unlock recheck. +/* Request lock info update. * It will not only return the lock status, but also set the property values - * in the DBus interface. */ -void mm_iface_modem_unlock_check (MMIfaceModem *self, - GAsyncReadyCallback callback, - gpointer user_data); -MMModemLock mm_iface_modem_unlock_check_finish (MMIfaceModem *self, - GAsyncResult *res, - GError **error); - -/* Check unlock retries */ -void mm_iface_modem_update_unlock_retries (MMIfaceModem *self, - GAsyncReadyCallback callback, - gpointer user_data); -gboolean mm_iface_modem_update_unlock_retries_finish (MMIfaceModem *self, - GAsyncResult *res, - GError **error); + * 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); /* Request signal quality check update. * It will not only return the signal quality status, but also set the property diff --git a/src/mm-sim.c b/src/mm-sim.c index 8f50edd7..436c15d8 100644 --- a/src/mm-sim.c +++ b/src/mm-sim.c @@ -143,11 +143,14 @@ typedef struct { GDBusMethodInvocation *invocation; gchar *old_pin; gchar *new_pin; + GError *save_error; } HandleChangePinContext; static void handle_change_pin_context_free (HandleChangePinContext *ctx) { + g_assert (ctx->save_error == NULL); + g_object_unref (ctx->invocation); g_object_unref (ctx->self); g_free (ctx->old_pin); @@ -156,15 +159,21 @@ handle_change_pin_context_free (HandleChangePinContext *ctx) } static void -after_change_unlock_retries_ready (MMIfaceModem *self, - GAsyncResult *res, - HandleChangePinContext *ctx) +after_change_update_lock_info_ready (MMIfaceModem *self, + GAsyncResult *res, + HandleChangePinContext *ctx) { /* We just want to ensure that we tried to update the unlock * retries, no big issue if it failed */ - mm_iface_modem_update_unlock_retries_finish (self, res, NULL); + mm_iface_modem_update_lock_info_finish (self, res, NULL); + + if (ctx->save_error) { + g_dbus_method_invocation_take_error (ctx->invocation, ctx->save_error); + ctx->save_error = NULL; + } else { + mm_gdbus_sim_complete_change_pin (MM_GDBUS_SIM (ctx->self), ctx->invocation); + } - mm_gdbus_sim_complete_change_pin (MM_GDBUS_SIM (ctx->self), ctx->invocation); handle_change_pin_context_free (ctx); } @@ -173,20 +182,20 @@ handle_change_pin_ready (MMSim *self, GAsyncResult *res, HandleChangePinContext *ctx) { - GError *error = NULL; + MMModemLock known_lock = MM_MODEM_LOCK_UNKNOWN; - MM_SIM_GET_CLASS (self)->change_pin_finish (self, res, &error); - if (error) { - g_dbus_method_invocation_take_error (ctx->invocation, error); - handle_change_pin_context_free (ctx); - return; + if (!MM_SIM_GET_CLASS (self)->change_pin_finish (self, res, &ctx->save_error)) { + if (g_error_matches (ctx->save_error, + MM_MOBILE_EQUIPMENT_ERROR, + MM_MOBILE_EQUIPMENT_ERROR_SIM_PUK)) + known_lock = MM_MODEM_LOCK_SIM_PUK; } - /* Before returning success, ensure that we get the unlock retry - * counts updated properly. */ - mm_iface_modem_update_unlock_retries (MM_IFACE_MODEM (self->priv->modem), - (GAsyncReadyCallback)after_change_unlock_retries_ready, - ctx); + mm_iface_modem_update_lock_info ( + MM_IFACE_MODEM (self->priv->modem), + known_lock, + (GAsyncReadyCallback)after_change_update_lock_info_ready, + ctx); } static void @@ -306,11 +315,14 @@ typedef struct { GDBusMethodInvocation *invocation; gchar *pin; gboolean enabled; + GError *save_error; } HandleEnablePinContext; static void handle_enable_pin_context_free (HandleEnablePinContext *ctx) { + g_assert (ctx->save_error == NULL); + g_object_unref (ctx->invocation); g_object_unref (ctx->self); g_free (ctx->pin); @@ -318,15 +330,23 @@ handle_enable_pin_context_free (HandleEnablePinContext *ctx) } static void -after_enable_unlock_retries_ready (MMIfaceModem *self, - GAsyncResult *res, - HandleEnablePinContext *ctx) +after_enable_update_lock_info_ready (MMIfaceModem *self, + GAsyncResult *res, + HandleEnablePinContext *ctx) { /* We just want to ensure that we tried to update the unlock * retries, no big issue if it failed */ - mm_iface_modem_update_unlock_retries_finish (self, res, NULL); + mm_iface_modem_update_lock_info_finish (self, res, NULL); + + if (ctx->save_error) { + g_dbus_method_invocation_take_error (ctx->invocation, ctx->save_error); + ctx->save_error = NULL; + } else { + /* Signal about the new lock state */ + g_signal_emit (self, signals[SIGNAL_PIN_LOCK_ENABLED], 0, ctx->enabled); + mm_gdbus_sim_complete_enable_pin (MM_GDBUS_SIM (ctx->self), ctx->invocation); + } - mm_gdbus_sim_complete_enable_pin (MM_GDBUS_SIM (ctx->self), ctx->invocation); handle_enable_pin_context_free (ctx); } @@ -335,23 +355,20 @@ handle_enable_pin_ready (MMSim *self, GAsyncResult *res, HandleEnablePinContext *ctx) { - GError *error = NULL; + MMModemLock known_lock = MM_MODEM_LOCK_UNKNOWN; - MM_SIM_GET_CLASS (self)->enable_pin_finish (self, res, &error); - if (error) { - g_dbus_method_invocation_take_error (ctx->invocation, error); - handle_enable_pin_context_free (ctx); - return; + if (!MM_SIM_GET_CLASS (self)->enable_pin_finish (self, res, &ctx->save_error)) { + if (g_error_matches (ctx->save_error, + MM_MOBILE_EQUIPMENT_ERROR, + MM_MOBILE_EQUIPMENT_ERROR_SIM_PUK)) + known_lock = MM_MODEM_LOCK_SIM_PUK; } - /* Signal about the new lock state */ - g_signal_emit (self, signals[SIGNAL_PIN_LOCK_ENABLED], 0, ctx->enabled); - - /* Before returning success, ensure that we get the unlock retry - * counts updated properly. */ - mm_iface_modem_update_unlock_retries (MM_IFACE_MODEM (self->priv->modem), - (GAsyncReadyCallback)after_enable_unlock_retries_ready, - ctx); + mm_iface_modem_update_lock_info ( + MM_IFACE_MODEM (self->priv->modem), + known_lock, + (GAsyncReadyCallback)after_enable_update_lock_info_ready, + ctx); } static void @@ -555,14 +572,14 @@ mm_sim_send_puk_finish (MMSim *self, } static void -unlock_check_ready (MMIfaceModem *modem, - GAsyncResult *res, - SendPinPukContext *ctx) +update_lock_info_ready (MMIfaceModem *modem, + GAsyncResult *res, + SendPinPukContext *ctx) { GError *error = NULL; MMModemLock lock; - lock = mm_iface_modem_unlock_check_finish (modem, res, &error); + lock = mm_iface_modem_update_lock_info_finish (modem, res, &error); /* Even if we may be SIM-PIN2/PUK2 locked, we don't consider this an error * in the PIN/PUK sending */ if (lock != MM_MODEM_LOCK_NONE && @@ -595,12 +612,21 @@ send_pin_ready (MMSim *self, GAsyncResult *res, SendPinPukContext *ctx) { - MM_SIM_GET_CLASS (self)->send_pin_finish (self, res, &ctx->save_error); + MMModemLock known_lock = MM_MODEM_LOCK_UNKNOWN; + + if (!MM_SIM_GET_CLASS (self)->send_pin_finish (self, res, &ctx->save_error)) { + if (g_error_matches (ctx->save_error, + MM_MOBILE_EQUIPMENT_ERROR, + MM_MOBILE_EQUIPMENT_ERROR_SIM_PUK)) + known_lock = MM_MODEM_LOCK_SIM_PUK; + } /* Once pin/puk has been sent, recheck lock */ - mm_iface_modem_unlock_check (MM_IFACE_MODEM (self->priv->modem), - (GAsyncReadyCallback)unlock_check_ready, - ctx); + mm_iface_modem_update_lock_info ( + MM_IFACE_MODEM (self->priv->modem), + known_lock, + (GAsyncReadyCallback)update_lock_info_ready, + ctx); } static void @@ -611,9 +637,10 @@ send_puk_ready (MMSim *self, MM_SIM_GET_CLASS (self)->send_puk_finish (self, res, &ctx->save_error); /* Once pin/puk has been sent, recheck lock */ - mm_iface_modem_unlock_check (MM_IFACE_MODEM (self->priv->modem), - (GAsyncReadyCallback)unlock_check_ready, - ctx); + mm_iface_modem_update_lock_info (MM_IFACE_MODEM (self->priv->modem), + MM_MODEM_LOCK_UNKNOWN, /* ask */ + (GAsyncReadyCallback)update_lock_info_ready, + ctx); } void |