summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2011-07-29 17:33:22 +0200
committerMarcel Holtmann <marcel@holtmann.org>2011-07-29 17:35:44 +0200
commitd41b584de51a534ac09303a957f3492eab34753e (patch)
tree1dddad28e58e76223e707fdaf5b22ca5607d5dd3
parent5029b906aa215c3e8edd7c7df63cbc2605b218d9 (diff)
downloadofono-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.c51
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);