--- 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 _______________________________________________ networkmanager-list mailing list networkmanager-list@gnome.org https://mail.gnome.org/mailman/listinfo/networkmanager-list