For some modem like ZTE MF180/190, we need to do some
polling to check SIM state when it returns +CME ERROR: 14 busy.
---
 drivers/atmodem/sim.c |   59 +++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 48 insertions(+), 11 deletions(-)

diff --git a/drivers/atmodem/sim.c b/drivers/atmodem/sim.c
index c51b1d4..a23738b 100644
--- a/drivers/atmodem/sim.c
+++ b/drivers/atmodem/sim.c
@@ -51,6 +51,8 @@ struct sim_data {
        GAtChat *chat;
        unsigned int vendor;
        guint ready_id;
+       guint poll_source;
+       guint poll_count;
 };
 
 static const char *crsm_prefix[] = { "+CRSM:", NULL };
@@ -856,6 +858,8 @@ static void at_pin_retries_query(struct ofono_sim *sim,
        CALLBACK_WITH_FAILURE(cb, NULL, data);
 }
 
+static gboolean sim_state_check(gpointer user_data);
+
 static void at_cpin_cb(gboolean ok, GAtResult *result, gpointer user_data)
 {
        struct cb_data *cbd = user_data;
@@ -874,9 +878,22 @@ static void at_cpin_cb(gboolean ok, GAtResult *result, 
gpointer user_data)
        else
                decode_at_error(&error, final);
 
-       if (!ok) {
+       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 (sd->poll_count++ < 12) {
+                               sd->poll_source = g_timeout_add_seconds(2,
+                                               sim_state_check, cbd);
+                               return;
+                       }
+               }
+               /* fall through */
+       default:
                cb(&error, -1, cbd->data);
-               return;
+               goto done;
        }
 
        if (sd->vendor == OFONO_VENDOR_WAVECOM) {
@@ -887,7 +904,7 @@ static void at_cpin_cb(gboolean ok, GAtResult *result, 
gpointer user_data)
 
                if (!g_at_result_iter_next(&iter, "+CPIN:")) {
                        CALLBACK_WITH_FAILURE(cb, -1, cbd->data);
-                       return;
+                       goto done;
                }
 
                g_at_result_iter_next_unquoted_string(&iter, &pin_required);
@@ -903,12 +920,34 @@ static void at_cpin_cb(gboolean ok, GAtResult *result, 
gpointer user_data)
 
        if (pin_type == OFONO_SIM_PASSWORD_INVALID) {
                CALLBACK_WITH_FAILURE(cb, -1, cbd->data);
-               return;
+               goto done;
        }
 
        DBG("crsm_pin_cb: %s", pin_required);
 
        cb(&error, pin_type, cbd->data);
+
+done:
+       g_free(cbd);
+}
+
+static gboolean sim_state_check(gpointer user_data)
+{
+       struct cb_data *cbd = user_data;
+       struct sim_data *sd = ofono_sim_get_data(cbd->user);
+       ofono_sim_passwd_cb_t cb = cbd->cb;
+
+       sd->poll_source = 0;
+
+       if (g_at_chat_send(sd->chat, "AT+CPIN?", cpin_prefix,
+                               at_cpin_cb, cbd, NULL) > 0)
+               return FALSE;
+
+       CALLBACK_WITH_FAILURE(cb, -1, cbd->data);
+
+       g_free(cbd);
+
+       return FALSE;
 }
 
 static void at_pin_query(struct ofono_sim *sim, ofono_sim_passwd_cb_t cb,
@@ -919,13 +958,8 @@ static void at_pin_query(struct ofono_sim *sim, 
ofono_sim_passwd_cb_t cb,
 
        cbd->user = sim;
 
-       if (g_at_chat_send(sd->chat, "AT+CPIN?", cpin_prefix,
-                               at_cpin_cb, cbd, g_free) > 0)
-               return;
-
-       g_free(cbd);
-
-       CALLBACK_WITH_FAILURE(cb, -1, data);
+       sd->poll_count = 0;
+       sim_state_check(cbd);
 }
 
 static void at_xsim_notify(GAtResult *result, gpointer user_data)
@@ -1246,6 +1280,9 @@ static void at_sim_remove(struct ofono_sim *sim)
 {
        struct sim_data *sd = ofono_sim_get_data(sim);
 
+       if (sd->poll_source > 0)
+               g_source_remove(sd->poll_source);
+
        ofono_sim_set_data(sim, NULL);
 
        g_at_chat_unref(sd->chat);
-- 
1.7.4.1

_______________________________________________
ofono mailing list
[email protected]
http://lists.ofono.org/listinfo/ofono

Reply via email to