aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Williams <dcbw@redhat.com>2012-07-20 09:37:23 -0500
committerDan Williams <dcbw@redhat.com>2012-07-20 09:37:23 -0500
commit87cc698b002a371a17c224a858cb2a575eba9169 (patch)
treeafd200e5ad7384bc1d5ddf874a9da9cfca5651ea
parent0c759d407d505272267eb6acf4a31062868bf106 (diff)
longcheer: implement unlock retries checking
-rw-r--r--plugins/mm-modem-longcheer-gsm.c92
1 files changed, 91 insertions, 1 deletions
diff --git a/plugins/mm-modem-longcheer-gsm.c b/plugins/mm-modem-longcheer-gsm.c
index 610ec777..10e7205a 100644
--- a/plugins/mm-modem-longcheer-gsm.c
+++ b/plugins/mm-modem-longcheer-gsm.c
@@ -20,12 +20,16 @@
#include <string.h>
#include <unistd.h>
#include "mm-modem-longcheer-gsm.h"
+#include "mm-modem-gsm-card.h"
#include "mm-at-serial-port.h"
#include "mm-errors.h"
#include "mm-callback-info.h"
#include "mm-modem-helpers.h"
-G_DEFINE_TYPE (MMModemLongcheerGsm, mm_modem_longcheer_gsm, MM_TYPE_GENERIC_GSM)
+static void modem_gsm_card_init (MMModemGsmCard *class);
+
+G_DEFINE_TYPE_EXTENDED (MMModemLongcheerGsm, mm_modem_longcheer_gsm, MM_TYPE_GENERIC_GSM, 0,
+ G_IMPLEMENT_INTERFACE (MM_TYPE_MODEM_GSM_CARD, modem_gsm_card_init))
MMModem *
mm_modem_longcheer_gsm_new (const char *device,
@@ -50,6 +54,86 @@ mm_modem_longcheer_gsm_new (const char *device,
/*****************************************************************************/
static void
+send_retries_done (MMAtSerialPort *port,
+ GString *response,
+ GError *error,
+ gpointer user_data)
+{
+ MMCallbackInfo *info = (MMCallbackInfo *) user_data;
+ GArray *retry_counts;
+ PinRetryCount ur[4] = {
+ {"sim-pin", 0}, {"sim-puk", 0}, {"sim-pin2", 0}, {"sim-puk2", 0}
+ };
+
+ /* If the modem has already been removed, return without
+ * scheduling callback */
+ if (mm_callback_info_check_modem_removed (info))
+ return;
+
+ if (error) {
+ info->error = g_error_copy (error);
+ goto done;
+ }
+
+ /* That's right; no +CPNNUM: prefix, it looks like this:
+ *
+ * AT+CPNNUM
+ * PIN1=3; PUK1=10; PIN2=3; PUK2=10
+ * OK
+ */
+ if (sscanf (response->str, "PIN1=%d; PUK1=%d; PIN2=%d; PUK2=%d",
+ &ur[0].count, &ur[1].count, &ur[2].count, &ur[3].count) == 4) {
+ if (ur[0].count > 998) {
+ info->error = g_error_new (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL,
+ "Invalid PIN attempts left %d", ur[0].count);
+ ur[0].count = 0;
+ }
+
+ retry_counts = g_array_sized_new (FALSE, TRUE, sizeof (PinRetryCount), 4);
+ g_array_append_vals (retry_counts, &ur, 4);
+ mm_callback_info_set_result (info, retry_counts, NULL);
+ } else {
+ info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL,
+ "Could not parse PIN retries results");
+ }
+
+done:
+ mm_serial_port_close (MM_SERIAL_PORT (port));
+ mm_callback_info_schedule (info);
+}
+
+static void
+get_unlock_retries (MMModemGsmCard *modem,
+ MMModemArrayFn callback,
+ gpointer user_data)
+{
+ MMAtSerialPort *port;
+ MMCallbackInfo *info = mm_callback_info_array_new (MM_MODEM (modem), callback, user_data);
+
+ /* 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 */
+ mm_at_serial_port_queue_command (port, "E0", 3, NULL, NULL);
+ mm_at_serial_port_queue_command (port, "+CPNNUM", 3, send_retries_done, info);
+}
+
+/*****************************************************************************/
+
+static void
get_allowed_mode_done (MMAtSerialPort *port,
GString *response,
GError *error,
@@ -229,6 +313,12 @@ mm_modem_longcheer_gsm_init (MMModemLongcheerGsm *self)
}
static void
+modem_gsm_card_init (MMModemGsmCard *class)
+{
+ class->get_unlock_retries = get_unlock_retries;
+}
+
+static void
mm_modem_longcheer_gsm_class_init (MMModemLongcheerGsmClass *klass)
{
MMGenericGsmClass *gsm_class = MM_GENERIC_GSM_CLASS (klass);