[PATCH] Delay full modem initialization until SIM is unlocked



Hi,

Some modems return ERROR to most AT commands when the SIM is still locked, specifically the "ATZ E0" in the initialization.

The attached patch modifies the initialization sequence to disable the local echo (the E0 part) first, perform the SIM check, and only then continue with the "ATZ" and further network registration, etc.

For me, on fresh boot (SIM locked), this NetworkManager now unlocks the SIM (it has my PIN in the keyring) and makes a perfect connection every time.

PS I imagine this might apply to CDMA as well.

Cheers,
Dennis



Index: src/nm-gsm-device.c
===================================================================
--- src/nm-gsm-device.c    (revision 3690)
+++ src/nm-gsm-device.c    (working copy)
@@ -311,6 +311,50 @@
 }
 
 static void
+init_full_done (NMSerialDevice *device,
+         int reply_index,
+         gpointer user_data)
+{
+    gsm_device_set_pending (NM_GSM_DEVICE (device), 0);
+
+    switch (reply_index) {
+    case 0:
+        do_register (device);
+        break;
+    case -1:
+        nm_warning ("Modem second stage initialization timed out");
+        nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED);
+        break;
+    default:
+        nm_warning ("Modem second stage initialization failed");
+        nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED);
+        return;
+    }
+}
+
+
+static void
+init_modem_full (NMSerialDevice *device)
+{
+    guint id;
+    char *responses[] = { "OK", "ERROR", "ERR", NULL };
+
+    /* At this point we know that SIM has been unlocked, and we can safely
+     * initialize the modem
+     */
+    if (!nm_serial_device_send_command_string (device, "ATZ")) {
+        nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED);
+        return;
+    }
+
+    id = nm_serial_device_wait_for_reply (device, 10, responses, responses, init_full_done, NULL);
+    if (id)
+        gsm_device_set_pending (NM_GSM_DEVICE (device), id);
+    else
+        nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED);
+}
+
+static void
 enter_pin_done (NMSerialDevice *device,
              int reply_index,
              gpointer user_data)
@@ -321,7 +365,7 @@
 
     switch (reply_index) {
     case 0:
-        do_register (device);
+        init_modem_full (device);
         break;
     case -1:
         nm_warning ("Did not receive response for secret");
@@ -485,7 +529,15 @@
     guint id;
     char *responses[] = { "OK", "ERROR", "ERR", NULL };
 
-    if (!nm_serial_device_send_command_string (device, "ATZ E0")) {
+    /* ATE0 = no local echo (i.e. echoing our own commands back to us)
+     * We do not do any further initialization here, since the SIM might
+     * still be locked, in which case some modems will just respond
+     * with ERROR to everything we try.
+     * Instead, after this step the PIN is checked, and entered if necessary,
+     * and then init_modem_full(...) continues the initialization
+     */
+
+    if (!nm_serial_device_send_command_string (device, "ATE0")) {
         nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED);
         return;
     }




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]