$NWQMISTATUS sometimes returns 'ERROR'. This patch modifies the Novatel
LTE plugin to retry $NWQMISTATUS (up to 5 times) to determine if the
disconnect operation succeeds. It also changes the plugin to assume that
the disconnect operation succeeds if $NWQMISTATUS fails to report the
current connection status.
---
 plugins/novatel/mm-broadband-bearer-novatel-lte.c | 68 +++++++++++++++++------
 1 file changed, 51 insertions(+), 17 deletions(-)

diff --git a/plugins/novatel/mm-broadband-bearer-novatel-lte.c 
b/plugins/novatel/mm-broadband-bearer-novatel-lte.c
index 80c7464..4b67cd6 100644
--- a/plugins/novatel/mm-broadband-bearer-novatel-lte.c
+++ b/plugins/novatel/mm-broadband-bearer-novatel-lte.c
@@ -325,6 +325,7 @@ typedef struct {
     MMAtSerialPort *secondary;
     MMPort *data;
     GSimpleAsyncResult *result;
+    gint retries;
 } DetailedDisconnectContext;
 
 static DetailedDisconnectContext *
@@ -348,6 +349,7 @@ detailed_disconnect_context_new (MMBroadbandBearer *self,
                                              callback,
                                              user_data,
                                              detailed_disconnect_context_new);
+    ctx->retries = 4;
     return ctx;
 }
 
@@ -373,34 +375,72 @@ disconnect_3gpp_finish (MMBroadbandBearer *self,
     return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT 
(res), error);
 }
 
+static gboolean disconnect_3gpp_qmistatus (DetailedDisconnectContext *ctx);
+
 static void
-disconnect_3gpp_status_complete (MMBaseModem *modem,
-                                 GAsyncResult *res,
-                                 DetailedDisconnectContext *ctx)
+disconnect_3gpp_status_ready (MMBaseModem *modem,
+                              GAsyncResult *res,
+                              DetailedDisconnectContext *ctx)
 {
     const gchar *result;
     GError *error = NULL;
+    gboolean is_connected = FALSE;
 
     result = mm_base_modem_at_command_finish (MM_BASE_MODEM (modem),
                                               res,
                                               &error);
-    if (error) {
-        mm_dbg("QMI connection status failed: %s", error->message);
+    if (result) {
+        mm_dbg ("QMI connection status: %s", result);
+        if (is_qmistatus_disconnected (result)) {
+            g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
+            detailed_disconnect_context_complete_and_free (ctx);
+            return;
+        } else if (is_qmistatus_connected (result)) {
+            is_connected = TRUE;
+        }
+    } else {
+        mm_dbg ("QMI connection status failed: %s", error->message);
         g_error_free (error);
     }
 
-    if (result && is_qmistatus_disconnected (result))
-        g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
-    else
+    if (ctx->retries > 0) {
+        ctx->retries--;
+        mm_dbg ("Retrying status check in a second. %d retries left.",
+                ctx->retries);
+        g_timeout_add_seconds (1, (GSourceFunc)disconnect_3gpp_qmistatus, ctx);
+        return;
+    }
+
+    /* If $NWQMISTATUS reports a CONNECTED QMI state, returns an error such 
that
+     * the modem state remains 'connected'. Otherwise, assumes the modem is
+     * disconnected from the network successfully. */
+    if (is_connected)
         g_simple_async_result_set_error (ctx->result,
                                          MM_CORE_ERROR,
                                          MM_CORE_ERROR_FAILED,
-                                         "Error checking if disconnected (%s)",
-                                         result ? result : "no result");
+                                         "QMI disconnect failed: %s",
+                                         result);
+    else
+        g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
 
     detailed_disconnect_context_complete_and_free (ctx);
 }
 
+static gboolean
+disconnect_3gpp_qmistatus (DetailedDisconnectContext *ctx)
+{
+    mm_base_modem_at_command (
+        ctx->modem,
+        "$NWQMISTATUS",
+        3, /* timeout */
+        FALSE, /* allow_cached */
+        (GAsyncReadyCallback)disconnect_3gpp_status_ready, /* callback */
+        ctx); /* user_data */
+
+    return FALSE;
+}
+
+
 static void
 disconnect_3gpp_check_status (MMBaseModem *modem,
                               GAsyncResult *res,
@@ -416,13 +456,7 @@ disconnect_3gpp_check_status (MMBaseModem *modem,
         g_error_free (error);
     }
 
-    mm_base_modem_at_command (
-        ctx->modem,
-        "$NWQMISTATUS",
-        3, /* timeout */
-        FALSE, /* allow_cached */
-        (GAsyncReadyCallback)disconnect_3gpp_status_complete,
-        ctx); /* user_data */
+    disconnect_3gpp_qmistatus (ctx);
 }
 
 static void
-- 
1.8.1

_______________________________________________
networkmanager-list mailing list
networkmanager-list@gnome.org
https://mail.gnome.org/mailman/listinfo/networkmanager-list

Reply via email to