diff options
author | Marcel Holtmann <marcel@holtmann.org> | 2011-07-29 17:33:22 +0200 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2011-07-29 17:35:44 +0200 |
commit | d41b584de51a534ac09303a957f3492eab34753e (patch) | |
tree | 1dddad28e58e76223e707fdaf5b22ca5607d5dd3 | |
parent | 5029b906aa215c3e8edd7c7df63cbc2605b218d9 (diff) | |
download | ofono-d41b584de51a534ac09303a957f3492eab34753e.tar.bz2 |
atmodem: Handle SIM busy condition gracefully for phonebooks
Before the phonebook is ready, the SIM card needs certain amount of
time. Something between 20-30 seconds in general. So if the modem
returns an error indicating the SIM is busy, then try again in
regular intervals.
-rw-r--r-- | drivers/atmodem/phonebook.c | 51 |
1 files changed, 43 insertions, 8 deletions
diff --git a/drivers/atmodem/phonebook.c b/drivers/atmodem/phonebook.c index ebac5637..ccb73caa 100644 --- a/drivers/atmodem/phonebook.c +++ b/drivers/atmodem/phonebook.c @@ -60,6 +60,8 @@ struct pb_data { int supported; GAtChat *chat; unsigned int vendor; + guint poll_source; + guint poll_count; guint ready_id; }; @@ -391,19 +393,31 @@ static void phonebook_not_supported(struct ofono_phonebook *pb) static void at_list_storages_cb(gboolean ok, GAtResult *result, gpointer user_data); -static void ifx_pbready_notify(GAtResult *result, gpointer user_data) +static gboolean cpbs_support_check(gpointer user_data) { struct ofono_phonebook *pb = user_data; struct pb_data *pbd = ofono_phonebook_get_data(pb); - g_at_chat_unregister(pbd->chat, pbd->ready_id); - pbd->ready_id = 0; + pbd->poll_source = 0; if (g_at_chat_send(pbd->chat, "AT+CPBS=?", cpbs_prefix, at_list_storages_cb, pb, NULL) > 0) - return; + return FALSE; phonebook_not_supported(pb); + + return FALSE; +} + +static void ifx_pbready_notify(GAtResult *result, gpointer user_data) +{ + struct ofono_phonebook *pb = user_data; + struct pb_data *pbd = ofono_phonebook_get_data(pb); + + g_at_chat_unregister(pbd->chat, pbd->ready_id); + pbd->ready_id = 0; + + cpbs_support_check(pb); } static void at_list_storages_cb(gboolean ok, GAtResult *result, @@ -411,14 +425,31 @@ static void at_list_storages_cb(gboolean ok, GAtResult *result, { struct ofono_phonebook *pb = user_data; struct pb_data *pbd = ofono_phonebook_get_data(pb); + struct ofono_error error; gboolean sm_supported = FALSE; gboolean me_supported = FALSE; gboolean in_list = FALSE; GAtResultIter iter; const char *storage; - if (!ok) + decode_at_error(&error, g_at_result_final_response(result)); + + switch (error.type) { + case OFONO_ERROR_TYPE_NO_ERROR: + break; + case OFONO_ERROR_TYPE_CME: + /* Check for SIM busy - try again later */ + if (error.error == 14) { + if (pbd->poll_count++ < 12) { + pbd->poll_source = g_timeout_add_seconds(5, + cpbs_support_check, pb); + return; + } + } + /* fall through */ + default: goto error; + } g_at_result_iter_init(&iter, result); if (!g_at_result_iter_next(&iter, "+CPBS:")) @@ -506,9 +537,10 @@ static void at_list_charsets_cb(gboolean ok, GAtResult *result, } } - if (g_at_chat_send(pbd->chat, "AT+CPBS=?", cpbs_prefix, - at_list_storages_cb, pb, NULL) > 0) - return; + pbd->poll_count = 0; + + cpbs_support_check(pb); + return; error: phonebook_not_supported(pb); @@ -549,6 +581,9 @@ static void at_phonebook_remove(struct ofono_phonebook *pb) { struct pb_data *pbd = ofono_phonebook_get_data(pb); + if (pbd->poll_source > 0) + g_source_remove(pbd->poll_source); + if (pbd->old_charset) g_free(pbd->old_charset); |