[PATCH] add UnlockRetries property to the modem dbus interface
- From: Torgny Johansson <torgny johansson ericsson com>
- To: <networkmanager-list gnome org>
- Subject: [PATCH] add UnlockRetries property to the modem dbus interface
- Date: Thu, 27 May 2010 12:06:54 +0200
Hi!
This is a new patch that fixes the issues from your comments.
Now only a property containing the UnlockRetries for the currently locked pin type is added and no extra dbus method.
I also removed the change in send_pin_done, but as mentioned in a previously mail that will still have to be addressed somehow as the UnlockRequired
and UnlockRetries properties do not properly update on failed SendPin attempts.
Regards
Torgny
---
introspection/mm-modem.xml | 7 +++
plugins/mm-modem-mbm.c | 93 +++++++++++++++++++++++++++++++++++++++++++-
src/mm-generic-gsm.c | 38 ++++++++++++++++++
src/mm-modem-base.c | 46 ++++++++++++++++++++++
src/mm-modem-base.h | 6 +++
src/mm-modem-gsm-card.c | 28 +++++++++++++
src/mm-modem-gsm-card.h | 17 ++++++++
src/mm-modem.c | 8 ++++
src/mm-modem.h | 4 +-
9 files changed, 245 insertions(+), 2 deletions(-)
diff --git a/introspection/mm-modem.xml b/introspection/mm-modem.xml
index da7635b..2810db0 100644
--- a/introspection/mm-modem.xml
+++ b/introspection/mm-modem.xml
@@ -125,6 +125,13 @@
</tp:docstring>
</property>
+ <property name="UnlockRetries" type="u" access="read">
+ <tp:docstring>
+ The number of unlock retries for the unlock code given by the property UnlockRequired, or 999 if
+ the device does not support reporting unlock retries.
+ </tp:docstring>
+ </property>
+
<property name="IpMethod" type="u" access="read" tp:type="MM_MODEM_IP_METHOD">
<tp:docstring>
The IP configuration method.
diff --git a/plugins/mm-modem-mbm.c b/plugins/mm-modem-mbm.c
index 10be0be..8441d96 100644
--- a/plugins/mm-modem-mbm.c
+++ b/plugins/mm-modem-mbm.c
@@ -28,17 +28,20 @@
#include "mm-modem-mbm.h"
#include "mm-modem-simple.h"
+#include "mm-modem-gsm-card.h"
#include "mm-errors.h"
#include "mm-callback-info.h"
static void modem_init (MMModem *modem_class);
static void modem_gsm_network_init (MMModemGsmNetwork *gsm_network_class);
static void modem_simple_init (MMModemSimple *class);
+static void modem_gsm_card_init (MMModemGsmCard *class);
G_DEFINE_TYPE_EXTENDED (MMModemMbm, mm_modem_mbm, MM_TYPE_GENERIC_GSM, 0,
G_IMPLEMENT_INTERFACE (MM_TYPE_MODEM, modem_init)
G_IMPLEMENT_INTERFACE (MM_TYPE_MODEM_GSM_NETWORK, modem_gsm_network_init)
- G_IMPLEMENT_INTERFACE (MM_TYPE_MODEM_SIMPLE, modem_simple_init))
+ G_IMPLEMENT_INTERFACE (MM_TYPE_MODEM_SIMPLE, modem_simple_init)
+ G_IMPLEMENT_INTERFACE (MM_TYPE_MODEM_GSM_CARD, modem_gsm_card_init))
#define MM_MODEM_MBM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), MM_TYPE_MODEM_MBM, MMModemMbmPrivate))
@@ -736,6 +739,88 @@ mbm_modem_authenticate (MMModemMbm *self,
/*****************************************************************************/
+static void
+send_epin_done (MMAtSerialPort *port,
+ GString *response,
+ GError *error,
+ gpointer user_data)
+{
+ MMCallbackInfo *info = (MMCallbackInfo *) user_data;
+ const char *pin_type;
+ int attempts_left = 0;
+
+ if (error) {
+ info->error = g_error_copy (error);
+ goto done;
+ }
+
+ pin_type = ((char *)mm_callback_info_get_data (info, "pin_type"));
+
+ if (strstr (pin_type, MM_MODEM_GSM_CARD_SIM_PIN))
+ sscanf (response->str, "*EPIN: %d", &attempts_left);
+ else if (strstr (pin_type, MM_MODEM_GSM_CARD_SIM_PUK))
+ sscanf (response->str, "*EPIN: %*d, %d", &attempts_left);
+ else if (strstr (pin_type, MM_MODEM_GSM_CARD_SIM_PIN2))
+ sscanf (response->str, "*EPIN: %*d, %*d, %d", &attempts_left);
+ else if (strstr (pin_type, MM_MODEM_GSM_CARD_SIM_PUK2))
+ sscanf (response->str, "*EPIN: %*d, %*d, %*d, %d", &attempts_left);
+ else {
+ g_debug ("%s unknown pin type: %s", __FUNCTION__, pin_type);
+
+ info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL, "Unknown PIN type");
+ }
+
+ mm_callback_info_set_result (info, GUINT_TO_POINTER (attempts_left), NULL);
+
+done:
+ mm_serial_port_close (MM_SERIAL_PORT (port));
+ mm_callback_info_schedule (info);
+}
+
+static void
+mbm_get_unlock_retries (MMModemGsmCard *modem,
+ const char *pin_type,
+ MMModemUIntFn callback,
+ gpointer user_data)
+{
+ MMAtSerialPort *port;
+ char *command;
+ MMCallbackInfo *info = mm_callback_info_uint_new (MM_MODEM (modem), callback, user_data);
+
+ g_debug ("%s pin type: %s", __FUNCTION__, pin_type);
+
+ /* Ensure we have a usable port to use for the command */
+ port = mm_generic_gsm_get_best_at_port (MM_GENERIC_GSM (modem), &info->error);
+ if (!port) {
+ mm_callback_info_schedule (info);
+ return;
+ }
+
+ /* Modem may not be enabled yet, which sometimes can't be done until
+ * the device has been unlocked. In this case we have to open the port
+ * ourselves.
+ */
+ if (!mm_serial_port_open (MM_SERIAL_PORT (port), &info->error)) {
+ mm_callback_info_schedule (info);
+ return;
+ }
+
+ /* if the modem have not yet been enabled we need to make sure echoing is turned off */
+ command = g_strdup_printf ("E0");
+ mm_at_serial_port_queue_command (port, command, 3, NULL, NULL);
+ g_free (command);
+
+ mm_callback_info_set_data (info, "pin_type", g_strdup (pin_type), g_free);
+
+ command = g_strdup_printf ("*EPIN?");
+
+ mm_at_serial_port_queue_command (port, command, 3, send_epin_done, info);
+
+ g_free (command);
+}
+
+/*****************************************************************************/
+
static gboolean
grab_port (MMModem *modem,
const char *subsys,
@@ -805,6 +890,12 @@ grab_port (MMModem *modem,
/*****************************************************************************/
static void
+modem_gsm_card_init (MMModemGsmCard *class)
+{
+ class->get_unlock_retries = mbm_get_unlock_retries;
+}
+
+static void
modem_gsm_network_init (MMModemGsmNetwork *class)
{
class->do_register = do_register;
diff --git a/src/mm-generic-gsm.c b/src/mm-generic-gsm.c
index 8c155e2..141d1ea 100644
--- a/src/mm-generic-gsm.c
+++ b/src/mm-generic-gsm.c
@@ -206,6 +206,18 @@ error_for_unlock_required (const char *unlock)
}
static void
+get_unlock_retries_cb (MMModem *modem,
+ guint32 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);
+}
+
+static void
pin_check_done (MMAtSerialPort *port,
GString *response,
GError *error,
@@ -221,6 +233,11 @@ 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);
parsed = TRUE;
} else {
CPinResult *iter = &unlock_results[0];
@@ -230,6 +247,10 @@ pin_check_done (MMAtSerialPort *port,
if (g_str_has_prefix (str, iter->result)) {
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;
break;
}
@@ -241,6 +262,7 @@ 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);
if (!info->error) {
info->error = g_error_new (MM_MODEM_ERROR,
@@ -1380,6 +1402,21 @@ change_pin (MMModemGsmCard *modem,
}
static void
+get_unlock_retries (MMModemGsmCard *modem,
+ const char *pin_type,
+ MMModemUIntFn 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);
+
+ mm_callback_info_schedule (info);
+}
+
+static void
reg_info_updated (MMGenericGsm *self,
gboolean update_rs,
MMModemGsmNetworkRegStatus status,
@@ -3539,6 +3576,7 @@ modem_gsm_card_init (MMModemGsmCard *class)
class->send_puk = send_puk;
class->enable_pin = enable_pin;
class->change_pin = change_pin;
+ class->get_unlock_retries = get_unlock_retries;
}
static void
diff --git a/src/mm-modem-base.c b/src/mm-modem-base.c
index 0a91d3f..611b1a1 100644
--- a/src/mm-modem-base.c
+++ b/src/mm-modem-base.c
@@ -43,6 +43,7 @@ typedef struct {
char *plugin;
char *device;
char *unlock_required;
+ guint32 unlock_retries;
guint32 ip_method;
gboolean valid;
MMModemState state;
@@ -232,6 +233,40 @@ 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)
+{
+ MMModemBasePrivate *priv;
+ const char *dbus_path;
+
+ 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)
+ return;
+
+ priv->unlock_retries = unlock_retries;
+
+ dbus_path = (const char *) g_object_get_data (G_OBJECT (self), DBUS_PATH_TAG);
+ if (dbus_path) {
+ g_message ("Modem %s: unlock retries is %d", dbus_path, priv->unlock_retries);
+ }
+
+ g_object_notify (G_OBJECT (self), MM_MODEM_UNLOCK_RETRIES);
+}
+
const char *
mm_modem_base_get_manf (MMModemBase *self)
{
@@ -490,6 +525,9 @@ mm_modem_base_init (MMModemBase *self)
mm_properties_changed_signal_register_property (G_OBJECT (self),
MM_MODEM_UNLOCK_REQUIRED,
MM_MODEM_DBUS_INTERFACE);
+ mm_properties_changed_signal_register_property (G_OBJECT (self),
+ MM_MODEM_UNLOCK_RETRIES,
+ MM_MODEM_DBUS_INTERFACE);
}
static void
@@ -539,6 +577,7 @@ set_property (GObject *object, guint prop_id,
case MM_MODEM_PROP_TYPE:
case MM_MODEM_PROP_ENABLED:
case MM_MODEM_PROP_UNLOCK_REQUIRED:
+ case MM_MODEM_PROP_UNLOCK_RETRIES:
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -583,6 +622,9 @@ get_property (GObject *object, guint prop_id,
case MM_MODEM_PROP_UNLOCK_REQUIRED:
g_value_set_string (value, priv->unlock_required);
break;
+ case MM_MODEM_PROP_UNLOCK_RETRIES:
+ g_value_set_uint (value, priv->unlock_retries);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -658,6 +700,10 @@ mm_modem_base_class_init (MMModemBaseClass *klass)
MM_MODEM_PROP_UNLOCK_REQUIRED,
MM_MODEM_UNLOCK_REQUIRED);
+ g_object_class_override_property (object_class,
+ MM_MODEM_PROP_UNLOCK_RETRIES,
+ MM_MODEM_UNLOCK_RETRIES);
+
mm_properties_changed_signal_new (object_class);
}
diff --git a/src/mm-modem-base.h b/src/mm-modem-base.h
index 516af2e..8eec0e4 100644
--- a/src/mm-modem-base.h
+++ b/src/mm-modem-base.h
@@ -67,6 +67,12 @@ 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);
+
+
const char *mm_modem_base_get_manf (MMModemBase *self);
void mm_modem_base_set_manf (MMModemBase *self, const char *manf);
diff --git a/src/mm-modem-gsm-card.c b/src/mm-modem-gsm-card.c
index 432a4a3..1023743 100644
--- a/src/mm-modem-gsm-card.c
+++ b/src/mm-modem-gsm-card.c
@@ -77,6 +77,19 @@ str_call_not_supported (MMModemGsmCard *self,
}
static void
+uint_call_not_supported (MMModemGsmCard *self,
+ MMModemUIntFn callback,
+ gpointer user_data)
+{
+ MMCallbackInfo *info;
+
+ info = mm_callback_info_uint_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);
+}
+
+static void
async_call_done (MMModem *modem, GError *error, gpointer user_data)
{
DBusGMethodInvocation *context = (DBusGMethodInvocation *) user_data;
@@ -130,6 +143,21 @@ mm_modem_gsm_card_get_imsi (MMModemGsmCard *self,
str_call_not_supported (self, callback, user_data);
}
+void mm_modem_gsm_card_get_unlock_retries (MMModemGsmCard *self,
+ const char *pin_type,
+ MMModemUIntFn 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);
+ else
+ uint_call_not_supported (self, callback, user_data);
+}
+
void
mm_modem_gsm_card_send_puk (MMModemGsmCard *self,
const char *puk,
diff --git a/src/mm-modem-gsm-card.h b/src/mm-modem-gsm-card.h
index 4d690e6..71371df 100644
--- a/src/mm-modem-gsm-card.h
+++ b/src/mm-modem-gsm-card.h
@@ -27,6 +27,13 @@
#define MM_MODEM_GSM_CARD_SUPPORTED_BANDS "supported-bands"
#define MM_MODEM_GSM_CARD_SUPPORTED_MODES "supported-modes"
+#define MM_MODEM_GSM_CARD_SIM_PIN "sim-pin"
+#define MM_MODEM_GSM_CARD_SIM_PIN2 "sim-pin2"
+#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 {
@@ -41,6 +48,11 @@ struct _MMModemGsmCard {
MMModemStringFn callback,
gpointer user_data);
+ void (*get_unlock_retries) (MMModemGsmCard *self,
+ const char *pin_type,
+ MMModemUIntFn callback,
+ gpointer user_data);
+
void (*send_puk) (MMModemGsmCard *self,
const char *puk,
const char *pin,
@@ -75,6 +87,11 @@ void mm_modem_gsm_card_get_imsi (MMModemGsmCard *self,
MMModemStringFn callback,
gpointer user_data);
+void mm_modem_gsm_card_get_unlock_retries (MMModemGsmCard *self,
+ const char *pin_type,
+ MMModemUIntFn callback,
+ gpointer user_data);
+
void mm_modem_gsm_card_send_puk (MMModemGsmCard *self,
const char *puk,
const char *pin,
diff --git a/src/mm-modem.c b/src/mm-modem.c
index 35e3b07..b378fff 100644
--- a/src/mm-modem.c
+++ b/src/mm-modem.c
@@ -812,6 +812,14 @@ mm_modem_init (gpointer g_iface)
NULL,
G_PARAM_READABLE));
+ g_object_interface_install_property
+ (g_iface,
+ g_param_spec_uint (MM_MODEM_UNLOCK_RETRIES,
+ "UnlockRetries",
+ "The remaining number of unlock attempts",
+ 0, G_MAXUINT32, 0,
+ G_PARAM_READABLE));
+
/* Signals */
g_signal_new ("state-changed",
iface_type,
diff --git a/src/mm-modem.h b/src/mm-modem.h
index 6eeb4de..d2863e4 100644
--- a/src/mm-modem.h
+++ b/src/mm-modem.h
@@ -59,6 +59,7 @@ typedef enum {
#define MM_MODEM_IP_METHOD "ip-method"
#define MM_MODEM_ENABLED "enabled"
#define MM_MODEM_UNLOCK_REQUIRED "unlock-required"
+#define MM_MODEM_UNLOCK_RETRIES "unlock-retries"
#define MM_MODEM_VALID "valid" /* not exported */
#define MM_MODEM_PLUGIN "plugin" /* not exported */
#define MM_MODEM_STATE "state" /* not exported */
@@ -83,7 +84,8 @@ typedef enum {
MM_MODEM_PROP_PLUGIN, /* Not exported */
MM_MODEM_PROP_STATE, /* Not exported */
MM_MODEM_PROP_ENABLED,
- MM_MODEM_PROP_UNLOCK_REQUIRED
+ MM_MODEM_PROP_UNLOCK_REQUIRED,
+ MM_MODEM_PROP_UNLOCK_RETRIES
} MMModemProp;
typedef struct _MMModem MMModem;
--
1.7.0.4
From 0b1d4508e701abcb38105393c9eb54f4496cf75b Mon Sep 17 00:00:00 2001
From: Torgny Johansson <torgny johansson ericsson com>
Date: Thu, 27 May 2010 11:12:18 +0200
Subject: [PATCH 1/2] Added UnlockRetries property to the modem interface.
---
introspection/mm-modem.xml | 7 +++
plugins/mm-modem-mbm.c | 93 +++++++++++++++++++++++++++++++++++++++++++-
src/mm-generic-gsm.c | 38 ++++++++++++++++++
src/mm-modem-base.c | 46 ++++++++++++++++++++++
src/mm-modem-base.h | 6 +++
src/mm-modem-gsm-card.c | 28 +++++++++++++
src/mm-modem-gsm-card.h | 17 ++++++++
src/mm-modem.c | 8 ++++
src/mm-modem.h | 4 +-
9 files changed, 245 insertions(+), 2 deletions(-)
diff --git a/introspection/mm-modem.xml b/introspection/mm-modem.xml
index da7635b..2810db0 100644
--- a/introspection/mm-modem.xml
+++ b/introspection/mm-modem.xml
@@ -125,6 +125,13 @@
</tp:docstring>
</property>
+ <property name="UnlockRetries" type="u" access="read">
+ <tp:docstring>
+ The number of unlock retries for the unlock code given by the property UnlockRequired, or 999 if
+ the device does not support reporting unlock retries.
+ </tp:docstring>
+ </property>
+
<property name="IpMethod" type="u" access="read" tp:type="MM_MODEM_IP_METHOD">
<tp:docstring>
The IP configuration method.
diff --git a/plugins/mm-modem-mbm.c b/plugins/mm-modem-mbm.c
index 10be0be..8441d96 100644
--- a/plugins/mm-modem-mbm.c
+++ b/plugins/mm-modem-mbm.c
@@ -28,17 +28,20 @@
#include "mm-modem-mbm.h"
#include "mm-modem-simple.h"
+#include "mm-modem-gsm-card.h"
#include "mm-errors.h"
#include "mm-callback-info.h"
static void modem_init (MMModem *modem_class);
static void modem_gsm_network_init (MMModemGsmNetwork *gsm_network_class);
static void modem_simple_init (MMModemSimple *class);
+static void modem_gsm_card_init (MMModemGsmCard *class);
G_DEFINE_TYPE_EXTENDED (MMModemMbm, mm_modem_mbm, MM_TYPE_GENERIC_GSM, 0,
G_IMPLEMENT_INTERFACE (MM_TYPE_MODEM, modem_init)
G_IMPLEMENT_INTERFACE (MM_TYPE_MODEM_GSM_NETWORK, modem_gsm_network_init)
- G_IMPLEMENT_INTERFACE (MM_TYPE_MODEM_SIMPLE, modem_simple_init))
+ G_IMPLEMENT_INTERFACE (MM_TYPE_MODEM_SIMPLE, modem_simple_init)
+ G_IMPLEMENT_INTERFACE (MM_TYPE_MODEM_GSM_CARD, modem_gsm_card_init))
#define MM_MODEM_MBM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), MM_TYPE_MODEM_MBM, MMModemMbmPrivate))
@@ -736,6 +739,88 @@ mbm_modem_authenticate (MMModemMbm *self,
/*****************************************************************************/
+static void
+send_epin_done (MMAtSerialPort *port,
+ GString *response,
+ GError *error,
+ gpointer user_data)
+{
+ MMCallbackInfo *info = (MMCallbackInfo *) user_data;
+ const char *pin_type;
+ int attempts_left = 0;
+
+ if (error) {
+ info->error = g_error_copy (error);
+ goto done;
+ }
+
+ pin_type = ((char *)mm_callback_info_get_data (info, "pin_type"));
+
+ if (strstr (pin_type, MM_MODEM_GSM_CARD_SIM_PIN))
+ sscanf (response->str, "*EPIN: %d", &attempts_left);
+ else if (strstr (pin_type, MM_MODEM_GSM_CARD_SIM_PUK))
+ sscanf (response->str, "*EPIN: %*d, %d", &attempts_left);
+ else if (strstr (pin_type, MM_MODEM_GSM_CARD_SIM_PIN2))
+ sscanf (response->str, "*EPIN: %*d, %*d, %d", &attempts_left);
+ else if (strstr (pin_type, MM_MODEM_GSM_CARD_SIM_PUK2))
+ sscanf (response->str, "*EPIN: %*d, %*d, %*d, %d", &attempts_left);
+ else {
+ g_debug ("%s unknown pin type: %s", __FUNCTION__, pin_type);
+
+ info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL, "Unknown PIN type");
+ }
+
+ mm_callback_info_set_result (info, GUINT_TO_POINTER (attempts_left), NULL);
+
+done:
+ mm_serial_port_close (MM_SERIAL_PORT (port));
+ mm_callback_info_schedule (info);
+}
+
+static void
+mbm_get_unlock_retries (MMModemGsmCard *modem,
+ const char *pin_type,
+ MMModemUIntFn callback,
+ gpointer user_data)
+{
+ MMAtSerialPort *port;
+ char *command;
+ MMCallbackInfo *info = mm_callback_info_uint_new (MM_MODEM (modem), callback, user_data);
+
+ g_debug ("%s pin type: %s", __FUNCTION__, pin_type);
+
+ /* Ensure we have a usable port to use for the command */
+ port = mm_generic_gsm_get_best_at_port (MM_GENERIC_GSM (modem), &info->error);
+ if (!port) {
+ mm_callback_info_schedule (info);
+ return;
+ }
+
+ /* Modem may not be enabled yet, which sometimes can't be done until
+ * the device has been unlocked. In this case we have to open the port
+ * ourselves.
+ */
+ if (!mm_serial_port_open (MM_SERIAL_PORT (port), &info->error)) {
+ mm_callback_info_schedule (info);
+ return;
+ }
+
+ /* if the modem have not yet been enabled we need to make sure echoing is turned off */
+ command = g_strdup_printf ("E0");
+ mm_at_serial_port_queue_command (port, command, 3, NULL, NULL);
+ g_free (command);
+
+ mm_callback_info_set_data (info, "pin_type", g_strdup (pin_type), g_free);
+
+ command = g_strdup_printf ("*EPIN?");
+
+ mm_at_serial_port_queue_command (port, command, 3, send_epin_done, info);
+
+ g_free (command);
+}
+
+/*****************************************************************************/
+
static gboolean
grab_port (MMModem *modem,
const char *subsys,
@@ -805,6 +890,12 @@ grab_port (MMModem *modem,
/*****************************************************************************/
static void
+modem_gsm_card_init (MMModemGsmCard *class)
+{
+ class->get_unlock_retries = mbm_get_unlock_retries;
+}
+
+static void
modem_gsm_network_init (MMModemGsmNetwork *class)
{
class->do_register = do_register;
diff --git a/src/mm-generic-gsm.c b/src/mm-generic-gsm.c
index 8c155e2..141d1ea 100644
--- a/src/mm-generic-gsm.c
+++ b/src/mm-generic-gsm.c
@@ -206,6 +206,18 @@ error_for_unlock_required (const char *unlock)
}
static void
+get_unlock_retries_cb (MMModem *modem,
+ guint32 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);
+}
+
+static void
pin_check_done (MMAtSerialPort *port,
GString *response,
GError *error,
@@ -221,6 +233,11 @@ 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);
parsed = TRUE;
} else {
CPinResult *iter = &unlock_results[0];
@@ -230,6 +247,10 @@ pin_check_done (MMAtSerialPort *port,
if (g_str_has_prefix (str, iter->result)) {
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;
break;
}
@@ -241,6 +262,7 @@ 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);
if (!info->error) {
info->error = g_error_new (MM_MODEM_ERROR,
@@ -1380,6 +1402,21 @@ change_pin (MMModemGsmCard *modem,
}
static void
+get_unlock_retries (MMModemGsmCard *modem,
+ const char *pin_type,
+ MMModemUIntFn 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);
+
+ mm_callback_info_schedule (info);
+}
+
+static void
reg_info_updated (MMGenericGsm *self,
gboolean update_rs,
MMModemGsmNetworkRegStatus status,
@@ -3539,6 +3576,7 @@ modem_gsm_card_init (MMModemGsmCard *class)
class->send_puk = send_puk;
class->enable_pin = enable_pin;
class->change_pin = change_pin;
+ class->get_unlock_retries = get_unlock_retries;
}
static void
diff --git a/src/mm-modem-base.c b/src/mm-modem-base.c
index 0a91d3f..611b1a1 100644
--- a/src/mm-modem-base.c
+++ b/src/mm-modem-base.c
@@ -43,6 +43,7 @@ typedef struct {
char *plugin;
char *device;
char *unlock_required;
+ guint32 unlock_retries;
guint32 ip_method;
gboolean valid;
MMModemState state;
@@ -232,6 +233,40 @@ 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)
+{
+ MMModemBasePrivate *priv;
+ const char *dbus_path;
+
+ 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)
+ return;
+
+ priv->unlock_retries = unlock_retries;
+
+ dbus_path = (const char *) g_object_get_data (G_OBJECT (self), DBUS_PATH_TAG);
+ if (dbus_path) {
+ g_message ("Modem %s: unlock retries is %d", dbus_path, priv->unlock_retries);
+ }
+
+ g_object_notify (G_OBJECT (self), MM_MODEM_UNLOCK_RETRIES);
+}
+
const char *
mm_modem_base_get_manf (MMModemBase *self)
{
@@ -490,6 +525,9 @@ mm_modem_base_init (MMModemBase *self)
mm_properties_changed_signal_register_property (G_OBJECT (self),
MM_MODEM_UNLOCK_REQUIRED,
MM_MODEM_DBUS_INTERFACE);
+ mm_properties_changed_signal_register_property (G_OBJECT (self),
+ MM_MODEM_UNLOCK_RETRIES,
+ MM_MODEM_DBUS_INTERFACE);
}
static void
@@ -539,6 +577,7 @@ set_property (GObject *object, guint prop_id,
case MM_MODEM_PROP_TYPE:
case MM_MODEM_PROP_ENABLED:
case MM_MODEM_PROP_UNLOCK_REQUIRED:
+ case MM_MODEM_PROP_UNLOCK_RETRIES:
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -583,6 +622,9 @@ get_property (GObject *object, guint prop_id,
case MM_MODEM_PROP_UNLOCK_REQUIRED:
g_value_set_string (value, priv->unlock_required);
break;
+ case MM_MODEM_PROP_UNLOCK_RETRIES:
+ g_value_set_uint (value, priv->unlock_retries);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -658,6 +700,10 @@ mm_modem_base_class_init (MMModemBaseClass *klass)
MM_MODEM_PROP_UNLOCK_REQUIRED,
MM_MODEM_UNLOCK_REQUIRED);
+ g_object_class_override_property (object_class,
+ MM_MODEM_PROP_UNLOCK_RETRIES,
+ MM_MODEM_UNLOCK_RETRIES);
+
mm_properties_changed_signal_new (object_class);
}
diff --git a/src/mm-modem-base.h b/src/mm-modem-base.h
index 516af2e..8eec0e4 100644
--- a/src/mm-modem-base.h
+++ b/src/mm-modem-base.h
@@ -67,6 +67,12 @@ 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);
+
+
const char *mm_modem_base_get_manf (MMModemBase *self);
void mm_modem_base_set_manf (MMModemBase *self, const char *manf);
diff --git a/src/mm-modem-gsm-card.c b/src/mm-modem-gsm-card.c
index 432a4a3..1023743 100644
--- a/src/mm-modem-gsm-card.c
+++ b/src/mm-modem-gsm-card.c
@@ -77,6 +77,19 @@ str_call_not_supported (MMModemGsmCard *self,
}
static void
+uint_call_not_supported (MMModemGsmCard *self,
+ MMModemUIntFn callback,
+ gpointer user_data)
+{
+ MMCallbackInfo *info;
+
+ info = mm_callback_info_uint_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);
+}
+
+static void
async_call_done (MMModem *modem, GError *error, gpointer user_data)
{
DBusGMethodInvocation *context = (DBusGMethodInvocation *) user_data;
@@ -130,6 +143,21 @@ mm_modem_gsm_card_get_imsi (MMModemGsmCard *self,
str_call_not_supported (self, callback, user_data);
}
+void mm_modem_gsm_card_get_unlock_retries (MMModemGsmCard *self,
+ const char *pin_type,
+ MMModemUIntFn 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);
+ else
+ uint_call_not_supported (self, callback, user_data);
+}
+
void
mm_modem_gsm_card_send_puk (MMModemGsmCard *self,
const char *puk,
diff --git a/src/mm-modem-gsm-card.h b/src/mm-modem-gsm-card.h
index 4d690e6..71371df 100644
--- a/src/mm-modem-gsm-card.h
+++ b/src/mm-modem-gsm-card.h
@@ -27,6 +27,13 @@
#define MM_MODEM_GSM_CARD_SUPPORTED_BANDS "supported-bands"
#define MM_MODEM_GSM_CARD_SUPPORTED_MODES "supported-modes"
+#define MM_MODEM_GSM_CARD_SIM_PIN "sim-pin"
+#define MM_MODEM_GSM_CARD_SIM_PIN2 "sim-pin2"
+#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 {
@@ -41,6 +48,11 @@ struct _MMModemGsmCard {
MMModemStringFn callback,
gpointer user_data);
+ void (*get_unlock_retries) (MMModemGsmCard *self,
+ const char *pin_type,
+ MMModemUIntFn callback,
+ gpointer user_data);
+
void (*send_puk) (MMModemGsmCard *self,
const char *puk,
const char *pin,
@@ -75,6 +87,11 @@ void mm_modem_gsm_card_get_imsi (MMModemGsmCard *self,
MMModemStringFn callback,
gpointer user_data);
+void mm_modem_gsm_card_get_unlock_retries (MMModemGsmCard *self,
+ const char *pin_type,
+ MMModemUIntFn callback,
+ gpointer user_data);
+
void mm_modem_gsm_card_send_puk (MMModemGsmCard *self,
const char *puk,
const char *pin,
diff --git a/src/mm-modem.c b/src/mm-modem.c
index 35e3b07..b378fff 100644
--- a/src/mm-modem.c
+++ b/src/mm-modem.c
@@ -812,6 +812,14 @@ mm_modem_init (gpointer g_iface)
NULL,
G_PARAM_READABLE));
+ g_object_interface_install_property
+ (g_iface,
+ g_param_spec_uint (MM_MODEM_UNLOCK_RETRIES,
+ "UnlockRetries",
+ "The remaining number of unlock attempts",
+ 0, G_MAXUINT32, 0,
+ G_PARAM_READABLE));
+
/* Signals */
g_signal_new ("state-changed",
iface_type,
diff --git a/src/mm-modem.h b/src/mm-modem.h
index 6eeb4de..d2863e4 100644
--- a/src/mm-modem.h
+++ b/src/mm-modem.h
@@ -59,6 +59,7 @@ typedef enum {
#define MM_MODEM_IP_METHOD "ip-method"
#define MM_MODEM_ENABLED "enabled"
#define MM_MODEM_UNLOCK_REQUIRED "unlock-required"
+#define MM_MODEM_UNLOCK_RETRIES "unlock-retries"
#define MM_MODEM_VALID "valid" /* not exported */
#define MM_MODEM_PLUGIN "plugin" /* not exported */
#define MM_MODEM_STATE "state" /* not exported */
@@ -83,7 +84,8 @@ typedef enum {
MM_MODEM_PROP_PLUGIN, /* Not exported */
MM_MODEM_PROP_STATE, /* Not exported */
MM_MODEM_PROP_ENABLED,
- MM_MODEM_PROP_UNLOCK_REQUIRED
+ MM_MODEM_PROP_UNLOCK_REQUIRED,
+ MM_MODEM_PROP_UNLOCK_RETRIES
} MMModemProp;
typedef struct _MMModem MMModem;
--
1.7.0.4
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]