summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrzej Zaborowski <andrew.zaborowski@intel.com>2010-06-17 15:42:13 +0200
committerDenis Kenzior <denkenz@gmail.com>2010-06-18 14:14:39 -0500
commita2dc7dfee0071cfdc8e44500b4bc422ffd595a23 (patch)
tree0e894b67cce6b5ad8cf8becdf8ce6dc63e564b28
parent56c8033f9f62672ef5fbb2c52721bce8d070869f (diff)
downloadofono-a2dc7dfee0071cfdc8e44500b4bc422ffd595a23.tar.bz2
atmodem: Add PIN entry quirk for mbm.
Wait for *EPEV unsolicited response after PIN entered, otherwise the next AT+CPIN? query still returns the old value for a fraction of a second and ofono gets stuck until the next PIN entry attempt.
-rw-r--r--drivers/atmodem/sim.c46
1 files changed, 45 insertions, 1 deletions
diff --git a/drivers/atmodem/sim.c b/drivers/atmodem/sim.c
index e722fbba..8d5a9fa0 100644
--- a/drivers/atmodem/sim.c
+++ b/drivers/atmodem/sim.c
@@ -44,6 +44,7 @@
struct sim_data {
GAtChat *chat;
unsigned int vendor;
+ guint epev_id;
};
static const char *crsm_prefix[] = { "+CRSM:", NULL };
@@ -509,6 +510,45 @@ error:
CALLBACK_WITH_FAILURE(cb, -1, data);
}
+static void at_epev_notify(GAtResult *result, gpointer user_data)
+{
+ struct cb_data *cbd = user_data;
+ struct sim_data *sd = cbd->user;
+ ofono_sim_lock_unlock_cb_t cb = cbd->cb;
+ struct ofono_error error = { .type = OFONO_ERROR_TYPE_NO_ERROR };
+
+ cb(&error, cbd->data);
+
+ g_at_chat_unregister(sd->chat, sd->epev_id);
+ sd->epev_id = 0;
+}
+
+static void at_pin_send_cb(gboolean ok, GAtResult *result,
+ gpointer user_data)
+{
+ struct cb_data *cbd = user_data;
+ struct sim_data *sd = cbd->user;
+ ofono_sim_lock_unlock_cb_t cb = cbd->cb;
+ struct ofono_error error;
+
+ decode_at_error(&error, g_at_result_final_response(result));
+
+ /*
+ * On the MBM modem, AT+CPIN? keeps returning SIM PIN for a moment
+ * after successful AT+CPIN="..", but sends *EPEV when that changes.
+ */
+ if (ok && sd->vendor == OFONO_VENDOR_MBM) {
+ sd->epev_id = g_at_chat_register(sd->chat, "*EPEV",
+ at_epev_notify,
+ FALSE, cbd, g_free);
+ return;
+ }
+
+ cb(&error, cbd->data);
+
+ g_free(cbd);
+}
+
static void at_lock_unlock_cb(gboolean ok, GAtResult *result,
gpointer user_data)
{
@@ -532,10 +572,12 @@ static void at_pin_send(struct ofono_sim *sim, const char *passwd,
if (!cbd)
goto error;
+ cbd->user = sd;
+
snprintf(buf, sizeof(buf), "AT+CPIN=\"%s\"", passwd);
ret = g_at_chat_send(sd->chat, buf, none_prefix,
- at_lock_unlock_cb, cbd, g_free);
+ at_pin_send_cb, cbd, NULL);
memset(buf, 0, sizeof(buf));
@@ -740,6 +782,8 @@ static int at_sim_probe(struct ofono_sim *sim, unsigned int vendor,
if (sd->vendor == OFONO_VENDOR_WAVECOM)
g_at_chat_add_terminator(chat, "+CPIN:", 6, TRUE);
+ if (sd->vendor == OFONO_VENDOR_MBM)
+ g_at_chat_send(chat, "AT*EPEE=1", NULL, NULL, NULL, NULL);
ofono_sim_set_data(sim, sd);
g_idle_add(at_sim_register, sim);