diff options
author | Eric Shienbrood <ers@chromium.org> | 2011-11-16 17:42:50 -0600 |
---|---|---|
committer | Dan Williams <dcbw@redhat.com> | 2011-11-16 17:42:50 -0600 |
commit | e7b6b2dc1c709ae877e3cd472d4134b918bb5fb7 (patch) | |
tree | 00307c0559926bddad575ca85f1bffab43105b56 /src | |
parent | 71598a628987162196b98124486ad8e728852ec5 (diff) |
core: keep track of all PIN retry counts
Added a PinRetryCounts property on org.freedesktop.ModemManager.Modem.
This is dictionary that records the number of PIN tries remaining
for each of the possible PIN code types for which the modem is
capable of reporting the count. Also, these counts are kept up
to date across ChangePin and EnablePin operations, not just when
an unlock is attempted.
Diffstat (limited to 'src')
-rw-r--r-- | src/mm-callback-info.c | 20 | ||||
-rw-r--r-- | src/mm-callback-info.h | 4 | ||||
-rw-r--r-- | src/mm-generic-gsm.c | 62 | ||||
-rw-r--r-- | src/mm-modem-base.c | 98 | ||||
-rw-r--r-- | src/mm-modem-base.h | 11 | ||||
-rw-r--r-- | src/mm-modem-gsm-card.c | 16 | ||||
-rw-r--r-- | src/mm-modem-gsm-card.h | 10 | ||||
-rw-r--r-- | src/mm-modem.c | 10 | ||||
-rw-r--r-- | src/mm-modem.h | 9 |
9 files changed, 177 insertions, 63 deletions
diff --git a/src/mm-callback-info.c b/src/mm-callback-info.c index 302a8160..c738b704 100644 --- a/src/mm-callback-info.c +++ b/src/mm-callback-info.c @@ -48,6 +48,16 @@ invoke_mm_modem_string_fn (MMCallbackInfo *info) } static void +invoke_mm_modem_array_fn (MMCallbackInfo *info) +{ + MMModemArrayFn callback = (MMModemArrayFn) info->callback; + + callback (info->modem, + (GArray *) mm_callback_info_get_data (info, CALLBACK_INFO_RESULT), + info->error, info->user_data); +} + +static void modem_destroyed_cb (gpointer data, GObject *destroyed) { MMCallbackInfo *info = data; @@ -151,6 +161,16 @@ mm_callback_info_string_new (MMModem *modem, return mm_callback_info_new_full (modem, invoke_mm_modem_string_fn, (GCallback) callback, user_data); } +MMCallbackInfo * +mm_callback_info_array_new (MMModem *modem, + MMModemArrayFn callback, + gpointer user_data) +{ + g_return_val_if_fail (modem != NULL, NULL); + + return mm_callback_info_new_full (modem, invoke_mm_modem_array_fn, (GCallback) callback, user_data); +} + gpointer mm_callback_info_get_result (MMCallbackInfo *info) { diff --git a/src/mm-callback-info.h b/src/mm-callback-info.h index a00181c1..67fea8d5 100644 --- a/src/mm-callback-info.h +++ b/src/mm-callback-info.h @@ -57,6 +57,10 @@ MMCallbackInfo *mm_callback_info_string_new (MMModem *modem, MMModemStringFn callback, gpointer user_data); +MMCallbackInfo *mm_callback_info_array_new (MMModem *modem, + MMModemArrayFn callback, + gpointer user_data); + void mm_callback_info_schedule (MMCallbackInfo *info); gpointer mm_callback_info_get_result (MMCallbackInfo *info); void mm_callback_info_set_result (MMCallbackInfo *info, diff --git a/src/mm-generic-gsm.c b/src/mm-generic-gsm.c index 436c07c0..da0bf5cb 100644 --- a/src/mm-generic-gsm.c +++ b/src/mm-generic-gsm.c @@ -265,17 +265,24 @@ error_for_unlock_required (const char *unlock) MM_MOBILE_ERROR_UNKNOWN, "Unknown unlock request '%s'", unlock); } +typedef void (*MMModemArrayFn) (MMModem *modem, + GArray *items, + GError *error, + gpointer user_data); static void get_unlock_retries_cb (MMModem *modem, - guint32 result, + GArray *result, GError *error, gpointer user_data) { if (!error) - mm_modem_base_set_unlock_retries (MM_MODEM_BASE (modem), result); - else - mm_modem_base_set_unlock_retries (MM_MODEM_BASE (modem), MM_MODEM_GSM_CARD_UNLOCK_RETRIES_NOT_SUPPORTED); + mm_modem_base_set_pin_retry_counts (MM_MODEM_BASE (modem), result); + else { + if (result) + g_array_unref (result); + mm_modem_base_set_pin_retry_counts (MM_MODEM_BASE (modem), NULL); + } } static void @@ -303,11 +310,9 @@ pin_check_done (MMAtSerialPort *port, if (g_str_has_prefix (str, "READY")) { mm_modem_base_set_unlock_required (MM_MODEM_BASE (info->modem), NULL); - if (MM_MODEM_GSM_CARD_GET_INTERFACE (info->modem)->get_unlock_retries) - mm_modem_base_set_unlock_retries (MM_MODEM_BASE (info->modem), 0); - else - mm_modem_base_set_unlock_retries (MM_MODEM_BASE (info->modem), - MM_MODEM_GSM_CARD_UNLOCK_RETRIES_NOT_SUPPORTED); + mm_modem_gsm_card_get_unlock_retries (MM_MODEM_GSM_CARD (info->modem), + get_unlock_retries_cb, + NULL); parsed = TRUE; } else { CPinResult *iter = &unlock_results[0]; @@ -318,7 +323,6 @@ pin_check_done (MMAtSerialPort *port, info->error = mm_mobile_error_for_code (iter->code); mm_modem_base_set_unlock_required (MM_MODEM_BASE (info->modem), iter->normalized); mm_modem_gsm_card_get_unlock_retries (MM_MODEM_GSM_CARD (info->modem), - iter->normalized, get_unlock_retries_cb, NULL); parsed = TRUE; @@ -332,8 +336,8 @@ pin_check_done (MMAtSerialPort *port, if (!parsed) { /* Assume unlocked if we don't recognize the pin request result */ mm_modem_base_set_unlock_required (MM_MODEM_BASE (info->modem), NULL); - mm_modem_base_set_unlock_retries (MM_MODEM_BASE (info->modem), 0); - + mm_modem_gsm_card_get_unlock_retries (MM_MODEM_GSM_CARD (info->modem), + get_unlock_retries_cb, NULL); if (!info->error) { info->error = g_error_new (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL, @@ -2490,6 +2494,28 @@ pin_puk_recheck_done (MMModem *modem, GError *error, gpointer user_data) mm_callback_info_schedule (info); } +/* Following an operation other than unlock that requires + * a pin, refetch the retry count, which may have changed + * if an incorrect PIN was supplied. Check also for a SIM_PUK + * error, which occurs if PIN retries has reached zero. */ +static void +update_pin_puk_status (MMModem *modem, GError *error) +{ + if (error) { + if (error->domain != MM_MOBILE_ERROR) + return; + if (error->code == MM_MOBILE_ERROR_SIM_PUK) { + mm_modem_base_set_unlock_required (MM_MODEM_BASE (modem), + "sim-puk"); + } else if (error->code != MM_MOBILE_ERROR_WRONG_PASSWORD) { + return; + } + } + mm_modem_gsm_card_get_unlock_retries (MM_MODEM_GSM_CARD (modem), + get_unlock_retries_cb, + NULL); +} + static void send_puk_done (MMAtSerialPort *port, GString *response, @@ -2640,6 +2666,7 @@ enable_pin_done (MMAtSerialPort *port, if (mm_callback_info_check_modem_removed (info)) return; + update_pin_puk_status (info->modem, error); if (error) info->error = g_error_copy (error); mm_callback_info_schedule (info); @@ -2675,6 +2702,7 @@ change_pin_done (MMAtSerialPort *port, if (mm_callback_info_check_modem_removed (info)) return; + update_pin_puk_status (info->modem, error); if (error) info->error = g_error_copy (error); mm_callback_info_schedule (info); @@ -2699,16 +2727,12 @@ change_pin (MMModemGsmCard *modem, static void get_unlock_retries (MMModemGsmCard *modem, - const char *pin_type, - MMModemUIntFn callback, + MMModemArrayFn callback, gpointer user_data) { - MMCallbackInfo *info = mm_callback_info_uint_new (MM_MODEM (modem), callback, user_data); - - mm_callback_info_set_result (info, - GUINT_TO_POINTER (MM_MODEM_GSM_CARD_UNLOCK_RETRIES_NOT_SUPPORTED), - NULL); + MMCallbackInfo *info = mm_callback_info_array_new (MM_MODEM (modem), callback, user_data); + mm_callback_info_set_result (info, NULL, NULL); mm_callback_info_schedule (info); } diff --git a/src/mm-modem-base.c b/src/mm-modem-base.c index a065681e..526eb51e 100644 --- a/src/mm-modem-base.c +++ b/src/mm-modem-base.c @@ -55,6 +55,7 @@ typedef struct { char *device_ident; char *unlock_required; guint32 unlock_retries; + GArray *pin_retry_counts; guint32 ip_method; gboolean valid; MMModemState state; @@ -354,44 +355,64 @@ mm_modem_base_set_unlock_required (MMModemBase *self, const char *unlock_require g_object_notify (G_OBJECT (self), MM_MODEM_UNLOCK_REQUIRED); } -guint32 -mm_modem_base_get_unlock_retries (MMModemBase *self) -{ - g_return_val_if_fail (self != NULL, 0); - g_return_val_if_fail (MM_IS_MODEM_BASE (self), 0); - - return MM_MODEM_BASE_GET_PRIVATE (self)->unlock_retries; -} - void -mm_modem_base_set_unlock_retries (MMModemBase *self, guint unlock_retries) +mm_modem_base_set_pin_retry_counts (MMModemBase *self, GArray *pin_retries) { MMModemBasePrivate *priv; - const char *dbus_path; + GArray *old_retries; + gboolean same; + PinRetryCount *active = NULL; + guint i, j; + guint old_unlock_retries; g_return_if_fail (self != NULL); g_return_if_fail (MM_IS_MODEM_BASE (self)); priv = MM_MODEM_BASE_GET_PRIVATE (self); - - /* Only do something if the value changes */ - if (priv->unlock_retries == unlock_retries) + if (!pin_retries) { + priv->unlock_retries = MM_MODEM_UNLOCK_RETRIES_NOT_SUPPORTED; return; + } - priv->unlock_retries = unlock_retries; + old_retries = priv->pin_retry_counts; + old_unlock_retries = priv->unlock_retries; - dbus_path = (const char *) g_object_get_data (G_OBJECT (self), DBUS_PATH_TAG); - if (dbus_path) { - if (priv->unlock_required) { - mm_info ("Modem %s: # unlock retries for %s is %d", - dbus_path, priv->unlock_required, priv->unlock_retries); - } else { - mm_info ("Modem %s: # unlock retries is %d", - dbus_path, priv->unlock_retries); + /* Only do something if one of the values changes */ + same = (old_retries != NULL) && (pin_retries->len == old_retries->len); + for (i = 0; i < pin_retries->len; ++i) { + PinRetryCount *newur = &g_array_index (pin_retries, PinRetryCount, i); + + if (!g_strcmp0 (newur->name, priv->unlock_required)) + active = newur; + + if (old_retries) { + for (j = 0; j < old_retries->len; ++j) { + PinRetryCount *oldur = &g_array_index (old_retries, PinRetryCount, i); + + if (!g_strcmp0 (oldur->name, newur->name)) { + if (oldur->count != newur->count) + same = FALSE; + break; + } + } } } - g_object_notify (G_OBJECT (self), MM_MODEM_UNLOCK_RETRIES); + if (priv->pin_retry_counts) + g_array_unref (priv->pin_retry_counts); + + priv->pin_retry_counts = pin_retries; + + if (priv->unlock_required) { + g_assert (active); + priv->unlock_retries = active->count; + } else + priv->unlock_retries = 0; + + if (old_unlock_retries != priv->unlock_retries) + g_object_notify (G_OBJECT (self), MM_MODEM_UNLOCK_RETRIES); + if (!same) + g_object_notify (G_OBJECT (self), MM_MODEM_PIN_RETRY_COUNTS); } const char * @@ -700,6 +721,10 @@ mm_modem_base_init (MMModemBase *self) NULL, MM_DBUS_INTERFACE_MODEM); mm_properties_changed_signal_register_property (G_OBJECT (self), + MM_MODEM_PIN_RETRY_COUNTS, + NULL, + MM_DBUS_INTERFACE_MODEM); + mm_properties_changed_signal_register_property (G_OBJECT (self), MM_MODEM_IP_METHOD, NULL, MM_DBUS_INTERFACE_MODEM); @@ -760,6 +785,7 @@ set_property (GObject *object, guint prop_id, case MM_MODEM_PROP_DEVICE_IDENTIFIER: case MM_MODEM_PROP_UNLOCK_REQUIRED: case MM_MODEM_PROP_UNLOCK_RETRIES: + case MM_MODEM_PROP_PIN_RETRY_COUNTS: break; case MM_MODEM_PROP_HW_VID: /* Construct only */ @@ -778,6 +804,23 @@ set_property (GObject *object, guint prop_id, } } +static GHashTable * +get_retry_counts (GArray *counts) +{ + GHashTable *map; + int i; + + map = g_hash_table_new (g_str_hash, g_str_equal); + + if (counts) { + for (i = 0; i < counts->len; ++i) { + PinRetryCount *ur = (PinRetryCount *) &g_array_index (counts, PinRetryCount, i); + g_hash_table_insert (map, (char *) ur->name, GUINT_TO_POINTER (ur->count)); + } + } + return map; +} + static void get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) @@ -824,6 +867,9 @@ get_property (GObject *object, guint prop_id, case MM_MODEM_PROP_UNLOCK_RETRIES: g_value_set_uint (value, priv->unlock_retries); break; + case MM_MODEM_PROP_PIN_RETRY_COUNTS: + g_value_set_boxed (value, get_retry_counts (priv->pin_retry_counts)); + break; case MM_MODEM_PROP_HW_VID: g_value_set_uint (value, priv->vid); break; @@ -929,6 +975,10 @@ mm_modem_base_class_init (MMModemBaseClass *klass) MM_MODEM_UNLOCK_RETRIES); g_object_class_override_property (object_class, + MM_MODEM_PROP_PIN_RETRY_COUNTS, + MM_MODEM_PIN_RETRY_COUNTS); + + g_object_class_override_property (object_class, MM_MODEM_PROP_HW_VID, MM_MODEM_HW_VID); diff --git a/src/mm-modem-base.h b/src/mm-modem-base.h index be11af64..33bba397 100644 --- a/src/mm-modem-base.h +++ b/src/mm-modem-base.h @@ -73,10 +73,8 @@ const char *mm_modem_base_get_unlock_required (MMModemBase *self); void mm_modem_base_set_unlock_required (MMModemBase *self, const char *unlock_required); -guint mm_modem_base_get_unlock_retries (MMModemBase *self); - -void mm_modem_base_set_unlock_retries (MMModemBase *self, - guint unlock_retries); +void mm_modem_base_set_pin_retry_counts (MMModemBase *self, + GArray *pin_retries); const char *mm_modem_base_get_manf (MMModemBase *self); @@ -94,5 +92,10 @@ void mm_modem_base_get_card_info (MMModemBase *self, MMModemInfoFn callback, gpointer user_data); +typedef struct { + const char *name; + guint count; +} PinRetryCount; + #endif /* MM_MODEM_BASE_H */ diff --git a/src/mm-modem-gsm-card.c b/src/mm-modem-gsm-card.c index 9b1fd77d..35360db5 100644 --- a/src/mm-modem-gsm-card.c +++ b/src/mm-modem-gsm-card.c @@ -84,13 +84,13 @@ str_call_not_supported (MMModemGsmCard *self, } static void -uint_call_not_supported (MMModemGsmCard *self, - MMModemUIntFn callback, - gpointer user_data) +array_call_not_supported (MMModemGsmCard *self, + MMModemArrayFn callback, + gpointer user_data) { MMCallbackInfo *info; - info = mm_callback_info_uint_new (MM_MODEM (self), callback, user_data); + info = mm_callback_info_array_new (MM_MODEM (self), callback, user_data); info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_OPERATION_NOT_SUPPORTED, "Operation not supported"); mm_callback_info_schedule (info); @@ -151,18 +151,16 @@ mm_modem_gsm_card_get_imsi (MMModemGsmCard *self, } void mm_modem_gsm_card_get_unlock_retries (MMModemGsmCard *self, - const char *pin_type, - MMModemUIntFn callback, + MMModemArrayFn callback, gpointer user_data) { g_return_if_fail (MM_IS_MODEM_GSM_CARD (self)); - g_return_if_fail (pin_type != NULL); g_return_if_fail (callback != NULL); if (MM_MODEM_GSM_CARD_GET_INTERFACE (self)->get_unlock_retries) - MM_MODEM_GSM_CARD_GET_INTERFACE (self)->get_unlock_retries (self, pin_type, callback, user_data); + MM_MODEM_GSM_CARD_GET_INTERFACE (self)->get_unlock_retries (self, callback, user_data); else - uint_call_not_supported (self, callback, user_data); + array_call_not_supported (self, callback, user_data); } void diff --git a/src/mm-modem-gsm-card.h b/src/mm-modem-gsm-card.h index 9716bf73..34a5d5b7 100644 --- a/src/mm-modem-gsm-card.h +++ b/src/mm-modem-gsm-card.h @@ -33,8 +33,6 @@ #define MM_MODEM_GSM_CARD_SIM_PUK "sim-puk" #define MM_MODEM_GSM_CARD_SIM_PUK2 "sim-puk2" -#define MM_MODEM_GSM_CARD_UNLOCK_RETRIES_NOT_SUPPORTED 999 - typedef struct _MMModemGsmCard MMModemGsmCard; struct _MMModemGsmCard { @@ -50,9 +48,8 @@ struct _MMModemGsmCard { gpointer user_data); void (*get_unlock_retries) (MMModemGsmCard *self, - const char *pin_type, - MMModemUIntFn callback, - gpointer user_data); + MMModemArrayFn callback, + gpointer user_data); void (*get_operator_id) (MMModemGsmCard *self, MMModemStringFn callback, @@ -97,8 +94,7 @@ void mm_modem_gsm_card_get_imsi (MMModemGsmCard *self, gpointer user_data); void mm_modem_gsm_card_get_unlock_retries (MMModemGsmCard *self, - const char *pin_type, - MMModemUIntFn callback, + MMModemArrayFn callback, gpointer user_data); void mm_modem_gsm_card_get_operator_id (MMModemGsmCard *self, diff --git a/src/mm-modem.c b/src/mm-modem.c index 4447a360..0b31108b 100644 --- a/src/mm-modem.c +++ b/src/mm-modem.c @@ -33,6 +33,8 @@ static void impl_modem_factory_reset (MMModem *modem, const char *code, DBusGMet #include "mm-modem-glue.h" +#define MM_MODEM_PIN_RETRY_COUNTS_PROP_TYPE (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_UINT)) + static void async_op_not_supported (MMModem *self, MMModemFn callback, @@ -915,6 +917,14 @@ mm_modem_init (gpointer g_iface) g_object_interface_install_property (g_iface, + g_param_spec_boxed (MM_MODEM_PIN_RETRY_COUNTS, + "PinRetryCounts", + "The remaining number of attempts for each PIN type", + MM_MODEM_PIN_RETRY_COUNTS_PROP_TYPE, + G_PARAM_READABLE)); + + g_object_interface_install_property + (g_iface, g_param_spec_uint (MM_MODEM_HW_VID, "Hardware vendor ID", "Hardware vendor ID", diff --git a/src/mm-modem.h b/src/mm-modem.h index da39ff5d..8fb662b7 100644 --- a/src/mm-modem.h +++ b/src/mm-modem.h @@ -43,12 +43,15 @@ #define MM_MODEM_DEVICE_IDENTIFIER "device-identifier" #define MM_MODEM_UNLOCK_REQUIRED "unlock-required" #define MM_MODEM_UNLOCK_RETRIES "unlock-retries" +#define MM_MODEM_PIN_RETRY_COUNTS "pin-retry-counts" #define MM_MODEM_VALID "valid" /* not exported */ #define MM_MODEM_PLUGIN "plugin" /* not exported */ #define MM_MODEM_STATE "state" /* not exported */ #define MM_MODEM_HW_VID "hw-vid" /* not exported */ #define MM_MODEM_HW_PID "hw-pid" /* not exported */ +#define MM_MODEM_UNLOCK_RETRIES_NOT_SUPPORTED 999 + typedef enum { MM_MODEM_PROP_FIRST = 0x1000, @@ -64,6 +67,7 @@ typedef enum { MM_MODEM_PROP_EQUIPMENT_IDENTIFIER, MM_MODEM_PROP_UNLOCK_REQUIRED, MM_MODEM_PROP_UNLOCK_RETRIES, + MM_MODEM_PROP_PIN_RETRY_COUNTS, MM_MODEM_PROP_DEVICE_IDENTIFIER, MM_MODEM_PROP_HW_VID, /* Not exported */ MM_MODEM_PROP_HW_PID /* Not exported */ @@ -98,6 +102,11 @@ typedef void (*MMModemInfoFn) (MMModem *modem, GError *error, gpointer user_data); +typedef void (*MMModemArrayFn) (MMModem *modem, + GArray *items, + GError *error, + gpointer user_data); + struct _MMModem { GTypeInterface g_iface; |