[MM] [PATCH v3] iface-modem, novatel-lte: disable network scan in LTE mode
- From: Ben Chan <benchan chromium org>
- To: networkmanager-list gnome org
- Cc: Aleksander Morgado <aleksander lanedo com>
- Subject: [MM] [PATCH v3] iface-modem, novatel-lte: disable network scan in LTE mode
- Date: Thu, 3 Jan 2013 18:50:40 -0800
---
plugins/novatel/mm-broadband-modem-novatel-lte.c | 102 +++++++++++++++++++++-
src/mm-iface-modem.c | 20 ++++
src/mm-iface-modem.h | 3 +
3 files changed, 124 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..08954b5 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,96 @@ reset (MMIfaceModem *self,
}
/*****************************************************************************/
+/* Scan networks (3GPP interface) */
+
+static GList *
+scan_networks_finish (MMIfaceModem3gpp *self,
+ GAsyncResult *res,
+ GError **error)
+{
+ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
+ return NULL;
+
+ return g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res));
+}
+
+static void
+cops_query_ready (MMBroadbandModemNovatelLte *self,
+ GAsyncResult *res,
+ GSimpleAsyncResult *operation_result)
+{
+ const gchar *response;
+ GError *error = NULL;
+ GList *scan_result;
+
+ response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
+ if (error) {
+ g_simple_async_result_take_error (operation_result, error);
+ g_simple_async_result_complete (operation_result);
+ g_object_unref (operation_result);
+ return;
+ }
+
+ scan_result = mm_3gpp_parse_cops_test_response (response, &error);
+ if (error) {
+ g_simple_async_result_take_error (operation_result, error);
+ g_simple_async_result_complete (operation_result);
+ g_object_unref (operation_result);
+ return;
+ }
+
+ g_simple_async_result_set_op_res_gpointer (operation_result,
+ scan_result,
+ NULL);
+ g_simple_async_result_complete (operation_result);
+ g_object_unref (operation_result);
+}
+
+static void
+scan_networks (MMIfaceModem3gpp *self,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *result;
+ MMModemAccessTechnology access_tech;
+
+ mm_dbg ("scanning for networks (Novatel LTE)...");
+
+ result = g_simple_async_result_new (G_OBJECT (self),
+ callback,
+ user_data,
+ scan_networks);
+
+ 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.
+ */
+ if (access_tech & MM_MODEM_ACCESS_TECHNOLOGY_LTE) {
+ 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);
+ g_simple_async_result_set_error (result,
+ 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 (result);
+ g_object_unref (result);
+ g_free (access_tech_string);
+ return;
+ }
+
+ mm_base_modem_at_command (MM_BASE_MODEM (self),
+ "+COPS=?",
+ 120,
+ FALSE,
+ (GAsyncReadyCallback)cops_query_ready,
+ result);
+}
+
+/*****************************************************************************/
MMBroadbandModemNovatelLte *
mm_broadband_modem_novatel_lte_new (const gchar *device,
@@ -564,6 +657,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]