diff options
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; |