From d41b584de51a534ac09303a957f3492eab34753e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 29 Jul 2011 17:33:22 +0200 Subject: [PATCH] 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. --- drivers/atmodem/phonebook.c | 53 ++++++++++++++++++++++++++++++------- 1 file changed, 44 insertions(+), 9 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,6 +393,22 @@ static void phonebook_not_supported(struct ofono_phonebook *pb) static void at_list_storages_cb(gboolean ok, 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); + + pbd->poll_source = 0; + + if (g_at_chat_send(pbd->chat, "AT+CPBS=?", cpbs_prefix, + at_list_storages_cb, pb, NULL) > 0) + return FALSE; + + phonebook_not_supported(pb); + + return FALSE; +} + static void ifx_pbready_notify(GAtResult *result, gpointer user_data) { struct ofono_phonebook *pb = user_data; @@ -399,11 +417,7 @@ static void ifx_pbready_notify(GAtResult *result, gpointer user_data) g_at_chat_unregister(pbd->chat, pbd->ready_id); pbd->ready_id = 0; - if (g_at_chat_send(pbd->chat, "AT+CPBS=?", cpbs_prefix, - at_list_storages_cb, pb, NULL) > 0) - return; - - phonebook_not_supported(pb); + 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);