iface-modem, novatel-lte: disable network scan in LTE mode

This commit is contained in:
Ben Chan
2013-01-03 18:50:40 -08:00
committed by Aleksander Morgado
parent bc399d9cf8
commit e939221975
3 changed files with 124 additions and 1 deletions

View File

@@ -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) */
@@ -518,6 +521,96 @@ reset (MMIfaceModem *self,
user_data);
}
/*****************************************************************************/
/* 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 *
@@ -563,6 +656,13 @@ iface_modem_init (MMIfaceModem *iface)
iface->reset_finish = reset_finish;
}
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)
{

View File

@@ -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)
{

View File

@@ -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);