diff options
author | Dan Williams <dcbw@redhat.com> | 2010-04-09 17:10:57 -0700 |
---|---|---|
committer | Dan Williams <dcbw@redhat.com> | 2010-04-09 17:11:56 -0700 |
commit | da74f6d8ec1c6dbec227f3c0679eb3e25a510277 (patch) | |
tree | e2849895a87dfaa6b4ed668f6cf03a154f4a2218 /src | |
parent | 0d381e2f11cbc3bdb7c7e69bc4c7169a9d247d3c (diff) |
gsm: recheck modem lock status a few times after sending unlock request (bgo #613490)
Some devices (ZTE MF110 for example) respond immediately to the unlock
request, but in reality take a bit of time before they are actually
unlocked. Check PIN status a few times after sending the unlock.
Diffstat (limited to 'src')
-rw-r--r-- | src/mm-generic-gsm.c | 54 |
1 files changed, 53 insertions, 1 deletions
diff --git a/src/mm-generic-gsm.c b/src/mm-generic-gsm.c index 003ee2ac..e5957b24 100644 --- a/src/mm-generic-gsm.c +++ b/src/mm-generic-gsm.c @@ -1043,6 +1043,11 @@ disable (MMModem *modem, priv->signal_quality_id = 0; } + if (priv->pin_check_timeout) { + g_source_remove (priv->pin_check_timeout); + priv->pin_check_timeout = 0; + } + priv->lac[0] = 0; priv->lac[1] = 0; priv->cell_id[0] = 0; @@ -1129,16 +1134,59 @@ get_card_info (MMModem *modem, #define PIN_PORT_TAG "pin-port" static void +pin_puk_recheck_done (MMModem *modem, GError *error, gpointer user_data); + +static gboolean +pin_puk_recheck_again (gpointer user_data) +{ + MMCallbackInfo *info = (MMCallbackInfo *) user_data; + + MM_GENERIC_GSM_GET_PRIVATE (info->modem)->pin_check_timeout = 0; + check_pin (MM_GENERIC_GSM (info->modem), pin_puk_recheck_done, info); + return FALSE; +} + +static void pin_puk_recheck_done (MMModem *modem, GError *error, gpointer user_data) { MMCallbackInfo *info = (MMCallbackInfo *) user_data; gboolean close_port = !!mm_callback_info_get_data (info, PIN_CLOSE_PORT_TAG); + /* Clear the pin check timeout to ensure that it won't ever get a + * stale MMCallbackInfo if the modem got removed. We'll reschedule it here + * anyway if needed. + */ + if (info->modem) { + MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem); + + if (priv->pin_check_timeout) + g_source_remove (priv->pin_check_timeout); + priv->pin_check_timeout = 0; + } + /* modem could have been removed before we get here, in which case * 'modem' will be NULL. */ info->error = mm_modem_check_removed (modem, error); + /* If the modem wasn't removed, and the modem isn't ready yet, ask it for + * the current PIN status a few times since some devices take a bit to fully + * enable themselves after a SIM PIN/PUK unlock. + */ + if ( info->modem + && info->error + && !g_error_matches (info->error, MM_MODEM_ERROR, MM_MODEM_ERROR_REMOVED)) { + MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem); + + if (priv->pin_check_tries < 4) { + g_clear_error (&info->error); + priv->pin_check_tries++; + priv->pin_check_timeout = g_timeout_add_seconds (2, pin_puk_recheck_again, info); + return; + } + } + + /* Otherwise, clean up and return the PIN check error */ if (modem && close_port) { MMSerialPort *port = mm_callback_info_get_data (info, PIN_PORT_TAG); @@ -1167,6 +1215,7 @@ send_puk_done (MMAtSerialPort *port, } /* Get latest PIN status */ + MM_GENERIC_GSM_GET_PRIVATE (info->modem)->pin_check_tries = 0; check_pin (MM_GENERIC_GSM (info->modem), pin_puk_recheck_done, info); } @@ -1227,6 +1276,7 @@ send_pin_done (MMAtSerialPort *port, } /* Get latest PIN status */ + MM_GENERIC_GSM_GET_PRIVATE (info->modem)->pin_check_tries = 0; check_pin (MM_GENERIC_GSM (info->modem), pin_puk_recheck_done, info); } @@ -3504,8 +3554,10 @@ finalize (GObject *object) mm_generic_gsm_pending_registration_stop (MM_GENERIC_GSM (object)); - if (priv->pin_check_timeout) + if (priv->pin_check_timeout) { g_source_remove (priv->pin_check_timeout); + priv->pin_check_timeout = 0; + } if (priv->poll_id) { g_source_remove (priv->poll_id); |