[MM] [PATCH] iface-modem, novatel-lte: disable network scan in LTE mode



---
 plugins/novatel/mm-broadband-modem-novatel-lte.c |   73 +++++++++++++++++++++-
 src/mm-iface-modem.c                             |   20 ++++++
 src/mm-iface-modem.h                             |    3 +
 3 files changed, 95 insertions(+), 1 deletions(-)

diff --git a/plugins/novatel/mm-broadband-modem-novatel-lte.c b/plugins/novatel/mm-broadband-modem-novatel-lte.c
index 249a4a1..5b1a63b 100644
--- a/plugins/novatel/mm-broadband-modem-novatel-lte.c
+++ b/plugins/novatel/mm-broadband-modem-novatel-lte.c
@@ -29,15 +29,18 @@
 #include "mm-sim-novatel-lte.h"
 #include "mm-errors-types.h"
 #include "mm-iface-modem.h"
+#include "mm-iface-modem-3gpp.h"
 #include "mm-iface-modem-messaging.h"
 #include "mm-log.h"
 #include "mm-modem-helpers.h"
 #include "mm-serial-parsers.h"
 
 static void iface_modem_init (MMIfaceModem *iface);
+static void iface_modem_3gpp_init (MMIfaceModem3gpp *iface);
 
 G_DEFINE_TYPE_EXTENDED (MMBroadbandModemNovatelLte, mm_broadband_modem_novatel_lte, MM_TYPE_BROADBAND_MODEM, 0,
-                        G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM, iface_modem_init));
+                        G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM, iface_modem_init)
+                        G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_3GPP, iface_modem_3gpp_init));
 
 /*****************************************************************************/
 /* Create Bearer (Modem interface) */
@@ -519,6 +522,67 @@ reset (MMIfaceModem *self,
 }
 
 /*****************************************************************************/
+/* Scan networks (3GPP interface) */
+
+static GList *
+scan_networks_finish (MMIfaceModem3gpp *self,
+                      GAsyncResult *res,
+                      GError **error)
+{
+    const gchar *result;
+
+    result = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, error);
+    if (!result)
+        return NULL;
+
+    return mm_3gpp_parse_cops_test_response (result, error);
+}
+
+static void
+scan_networks (MMIfaceModem3gpp *self,
+               GAsyncReadyCallback callback,
+               gpointer user_data)
+{
+    MMModemAccessTechnology access_tech;
+
+    mm_dbg ("scanning for networks (Novatel LTE)...");
+
+    access_tech = mm_iface_modem_get_access_technologies (MM_IFACE_MODEM (self));
+    /* The Novatel LTE modem does not properly support AT+COPS=? in LTE mode.
+     * Thus, do not try to scan networks when the current access technologies
+     * include LTE or cannot be determined.
+     */
+    if ((access_tech == MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN) ||
+        (access_tech & MM_MODEM_ACCESS_TECHNOLOGY_LTE)) {
+        GSimpleAsyncResult *simple;
+        gchar *access_tech_string;
+
+        access_tech_string = mm_modem_access_technology_build_string_from_mask (access_tech);
+        mm_warn ("Couldn't scan for networks with access technologies: %s", access_tech_string);
+        simple = g_simple_async_result_new (G_OBJECT (self),
+                                            callback,
+                                            user_data,
+                                            scan_networks);
+        g_simple_async_result_set_error (simple,
+                                         MM_CORE_ERROR,
+                                         MM_CORE_ERROR_UNSUPPORTED,
+                                         "Couldn't scan for networks with access technologies: %s",
+                                         access_tech_string);
+        g_simple_async_result_complete_in_idle (simple);
+        g_object_unref (simple);
+        g_free (access_tech_string);
+        return;
+    }
+
+    mm_base_modem_at_command (MM_BASE_MODEM (self),
+                              "+COPS=?",
+                              120,
+                              FALSE,
+                              callback,
+                              user_data);
+}
+
+/*****************************************************************************/
 
 MMBroadbandModemNovatelLte *
 mm_broadband_modem_novatel_lte_new (const gchar *device,
@@ -564,6 +628,13 @@ iface_modem_init (MMIfaceModem *iface)
 }
 
 static void
+iface_modem_3gpp_init (MMIfaceModem3gpp *iface)
+{
+    iface->scan_networks = scan_networks;
+    iface->scan_networks_finish = scan_networks_finish;
+}
+
+static void
 mm_broadband_modem_novatel_lte_class_init (MMBroadbandModemNovatelLteClass *klass)
 {
 }
diff --git a/src/mm-iface-modem.c b/src/mm-iface-modem.c
index d25b03d..e94bc42 100644
--- a/src/mm-iface-modem.c
+++ b/src/mm-iface-modem.c
@@ -3930,6 +3930,26 @@ mm_iface_modem_shutdown (MMIfaceModem *self)
 
 /*****************************************************************************/
 
+MMModemAccessTechnology
+mm_iface_modem_get_access_technologies (MMIfaceModem *self)
+{
+    MMModemAccessTechnology access_tech = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN;
+    MmGdbusModem *skeleton;
+
+    g_object_get (self,
+                  MM_IFACE_MODEM_DBUS_SKELETON, &skeleton,
+                  NULL);
+
+    if (skeleton) {
+        access_tech = mm_gdbus_modem_get_access_technologies (skeleton);
+        g_object_unref (skeleton);
+    }
+
+    return access_tech;
+}
+
+/*****************************************************************************/
+
 MMModemMode
 mm_iface_modem_get_supported_modes (MMIfaceModem *self)
 {
diff --git a/src/mm-iface-modem.h b/src/mm-iface-modem.h
index a6bd904..52b0d8e 100644
--- a/src/mm-iface-modem.h
+++ b/src/mm-iface-modem.h
@@ -315,6 +315,9 @@ struct _MMIfaceModem {
 
 GType mm_iface_modem_get_type (void);
 
+/* Helpers to query access technologies */
+MMModemAccessTechnology mm_iface_modem_get_access_technologies (MMIfaceModem *self);
+
 /* Helpers to query capabilities */
 MMModemCapability mm_iface_modem_get_current_capabilities (MMIfaceModem *self);
 gboolean          mm_iface_modem_is_3gpp                  (MMIfaceModem *self);
-- 
1.7.7.3



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