diff options
author | Andrzej Zaborowski <andrew.zaborowski@intel.com> | 2010-06-17 15:42:13 +0200 |
---|---|---|
committer | Denis Kenzior <denkenz@gmail.com> | 2010-06-18 14:14:39 -0500 |
commit | a2dc7dfee0071cfdc8e44500b4bc422ffd595a23 (patch) | |
tree | 0e894b67cce6b5ad8cf8becdf8ce6dc63e564b28 | |
parent | 56c8033f9f62672ef5fbb2c52721bce8d070869f (diff) | |
download | ofono-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.c | 46 |
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); |