aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mm-callback-info.c20
-rw-r--r--src/mm-callback-info.h4
-rw-r--r--src/mm-generic-gsm.c62
-rw-r--r--src/mm-modem-base.c98
-rw-r--r--src/mm-modem-base.h11
-rw-r--r--src/mm-modem-gsm-card.c16
-rw-r--r--src/mm-modem-gsm-card.h10
-rw-r--r--src/mm-modem.c10
-rw-r--r--src/mm-modem.h9
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;