cinterion: new 'MMSharedCinterion' interface
Implement a new interface to keep the code shared between the QMI and non-QMI modem implementations. While doing that, also fix the parent interface pointer handling, so that it isn't a static pointer applicable to all modems, and make it a per-modem specific pointer. Without this fix, ModemManager would crash if e.g. running with both a QMI and non-QMI Cinterion modem at the same time. The new shared Cinterion logic will be in charge of managing all GPS sources not already managed by the parent interface. E.g. if the parent implementation already supports QMI-based GPS location (using the LOC service for example) prefer that to the custom AT-based logic.
This commit is contained in:

committed by
Dan Williams

parent
6e9bf39ecf
commit
59e79c996b
@@ -650,8 +650,8 @@ pkglib_LTLIBRARIES += libmm-plugin-cinterion.la
|
|||||||
libmm_plugin_cinterion_la_SOURCES = \
|
libmm_plugin_cinterion_la_SOURCES = \
|
||||||
cinterion/mm-plugin-cinterion.c \
|
cinterion/mm-plugin-cinterion.c \
|
||||||
cinterion/mm-plugin-cinterion.h \
|
cinterion/mm-plugin-cinterion.h \
|
||||||
cinterion/mm-common-cinterion.c \
|
cinterion/mm-shared-cinterion.c \
|
||||||
cinterion/mm-common-cinterion.h \
|
cinterion/mm-shared-cinterion.h \
|
||||||
cinterion/mm-broadband-modem-cinterion.c \
|
cinterion/mm-broadband-modem-cinterion.c \
|
||||||
cinterion/mm-broadband-modem-cinterion.h \
|
cinterion/mm-broadband-modem-cinterion.h \
|
||||||
cinterion/mm-broadband-bearer-cinterion.c \
|
cinterion/mm-broadband-bearer-cinterion.c \
|
||||||
|
@@ -37,22 +37,25 @@
|
|||||||
#include "mm-base-modem-at.h"
|
#include "mm-base-modem-at.h"
|
||||||
#include "mm-broadband-modem-cinterion.h"
|
#include "mm-broadband-modem-cinterion.h"
|
||||||
#include "mm-modem-helpers-cinterion.h"
|
#include "mm-modem-helpers-cinterion.h"
|
||||||
#include "mm-common-cinterion.h"
|
#include "mm-shared-cinterion.h"
|
||||||
#include "mm-broadband-bearer-cinterion.h"
|
#include "mm-broadband-bearer-cinterion.h"
|
||||||
|
|
||||||
static void iface_modem_init (MMIfaceModem *iface);
|
static void iface_modem_init (MMIfaceModem *iface);
|
||||||
static void iface_modem_3gpp_init (MMIfaceModem3gpp *iface);
|
static void iface_modem_3gpp_init (MMIfaceModem3gpp *iface);
|
||||||
static void iface_modem_messaging_init (MMIfaceModemMessaging *iface);
|
static void iface_modem_messaging_init (MMIfaceModemMessaging *iface);
|
||||||
static void iface_modem_location_init (MMIfaceModemLocation *iface);
|
static void iface_modem_location_init (MMIfaceModemLocation *iface);
|
||||||
|
static void shared_cinterion_init (MMSharedCinterion *iface);
|
||||||
|
|
||||||
static MMIfaceModem *iface_modem_parent;
|
static MMIfaceModem *iface_modem_parent;
|
||||||
static MMIfaceModem3gpp *iface_modem_3gpp_parent;
|
static MMIfaceModem3gpp *iface_modem_3gpp_parent;
|
||||||
|
static MMIfaceModemLocation *iface_modem_location_parent;
|
||||||
|
|
||||||
G_DEFINE_TYPE_EXTENDED (MMBroadbandModemCinterion, mm_broadband_modem_cinterion, MM_TYPE_BROADBAND_MODEM, 0,
|
G_DEFINE_TYPE_EXTENDED (MMBroadbandModemCinterion, mm_broadband_modem_cinterion, 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)
|
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_3GPP, iface_modem_3gpp_init)
|
||||||
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_MESSAGING, iface_modem_messaging_init)
|
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_MESSAGING, iface_modem_messaging_init)
|
||||||
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_LOCATION, iface_modem_location_init))
|
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_LOCATION, iface_modem_location_init)
|
||||||
|
G_IMPLEMENT_INTERFACE (MM_TYPE_SHARED_CINTERION, shared_cinterion_init))
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
FEATURE_SUPPORT_UNKNOWN,
|
FEATURE_SUPPORT_UNKNOWN,
|
||||||
@@ -1905,14 +1908,26 @@ iface_modem_messaging_init (MMIfaceModemMessaging *iface)
|
|||||||
static void
|
static void
|
||||||
iface_modem_location_init (MMIfaceModemLocation *iface)
|
iface_modem_location_init (MMIfaceModemLocation *iface)
|
||||||
{
|
{
|
||||||
mm_common_cinterion_peek_parent_location_interface (iface);
|
iface_modem_location_parent = g_type_interface_peek_parent (iface);
|
||||||
|
|
||||||
iface->load_capabilities = mm_common_cinterion_location_load_capabilities;
|
iface->load_capabilities = mm_shared_cinterion_location_load_capabilities;
|
||||||
iface->load_capabilities_finish = mm_common_cinterion_location_load_capabilities_finish;
|
iface->load_capabilities_finish = mm_shared_cinterion_location_load_capabilities_finish;
|
||||||
iface->enable_location_gathering = mm_common_cinterion_enable_location_gathering;
|
iface->enable_location_gathering = mm_shared_cinterion_enable_location_gathering;
|
||||||
iface->enable_location_gathering_finish = mm_common_cinterion_enable_location_gathering_finish;
|
iface->enable_location_gathering_finish = mm_shared_cinterion_enable_location_gathering_finish;
|
||||||
iface->disable_location_gathering = mm_common_cinterion_disable_location_gathering;
|
iface->disable_location_gathering = mm_shared_cinterion_disable_location_gathering;
|
||||||
iface->disable_location_gathering_finish = mm_common_cinterion_disable_location_gathering_finish;
|
iface->disable_location_gathering_finish = mm_shared_cinterion_disable_location_gathering_finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
static MMIfaceModemLocation *
|
||||||
|
peek_parent_location_interface (MMSharedCinterion *self)
|
||||||
|
{
|
||||||
|
return iface_modem_location_parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
shared_cinterion_init (MMSharedCinterion *iface)
|
||||||
|
{
|
||||||
|
iface->peek_parent_location_interface = peek_parent_location_interface;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@@ -27,12 +27,16 @@
|
|||||||
#include "mm-errors-types.h"
|
#include "mm-errors-types.h"
|
||||||
#include "mm-iface-modem-location.h"
|
#include "mm-iface-modem-location.h"
|
||||||
#include "mm-broadband-modem-qmi-cinterion.h"
|
#include "mm-broadband-modem-qmi-cinterion.h"
|
||||||
#include "mm-common-cinterion.h"
|
#include "mm-shared-cinterion.h"
|
||||||
|
|
||||||
static void iface_modem_location_init (MMIfaceModemLocation *iface);
|
static void iface_modem_location_init (MMIfaceModemLocation *iface);
|
||||||
|
static void shared_cinterion_init (MMSharedCinterion *iface);
|
||||||
|
|
||||||
|
static MMIfaceModemLocation *iface_modem_location_parent;
|
||||||
|
|
||||||
G_DEFINE_TYPE_EXTENDED (MMBroadbandModemQmiCinterion, mm_broadband_modem_qmi_cinterion, MM_TYPE_BROADBAND_MODEM_QMI, 0,
|
G_DEFINE_TYPE_EXTENDED (MMBroadbandModemQmiCinterion, mm_broadband_modem_qmi_cinterion, MM_TYPE_BROADBAND_MODEM_QMI, 0,
|
||||||
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_LOCATION, iface_modem_location_init))
|
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_LOCATION, iface_modem_location_init)
|
||||||
|
G_IMPLEMENT_INTERFACE (MM_TYPE_SHARED_CINTERION, shared_cinterion_init))
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
@@ -60,14 +64,26 @@ mm_broadband_modem_qmi_cinterion_init (MMBroadbandModemQmiCinterion *self)
|
|||||||
static void
|
static void
|
||||||
iface_modem_location_init (MMIfaceModemLocation *iface)
|
iface_modem_location_init (MMIfaceModemLocation *iface)
|
||||||
{
|
{
|
||||||
mm_common_cinterion_peek_parent_location_interface (iface);
|
iface_modem_location_parent = g_type_interface_peek_parent (iface);
|
||||||
|
|
||||||
iface->load_capabilities = mm_common_cinterion_location_load_capabilities;
|
iface->load_capabilities = mm_shared_cinterion_location_load_capabilities;
|
||||||
iface->load_capabilities_finish = mm_common_cinterion_location_load_capabilities_finish;
|
iface->load_capabilities_finish = mm_shared_cinterion_location_load_capabilities_finish;
|
||||||
iface->enable_location_gathering = mm_common_cinterion_enable_location_gathering;
|
iface->enable_location_gathering = mm_shared_cinterion_enable_location_gathering;
|
||||||
iface->enable_location_gathering_finish = mm_common_cinterion_enable_location_gathering_finish;
|
iface->enable_location_gathering_finish = mm_shared_cinterion_enable_location_gathering_finish;
|
||||||
iface->disable_location_gathering = mm_common_cinterion_disable_location_gathering;
|
iface->disable_location_gathering = mm_shared_cinterion_disable_location_gathering;
|
||||||
iface->disable_location_gathering_finish = mm_common_cinterion_disable_location_gathering_finish;
|
iface->disable_location_gathering_finish = mm_shared_cinterion_disable_location_gathering_finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
static MMIfaceModemLocation *
|
||||||
|
peek_parent_location_interface (MMSharedCinterion *self)
|
||||||
|
{
|
||||||
|
return iface_modem_location_parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
shared_cinterion_init (MMSharedCinterion *iface)
|
||||||
|
{
|
||||||
|
iface->peek_parent_location_interface = peek_parent_location_interface;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@@ -11,21 +11,29 @@
|
|||||||
* GNU General Public License for more details:
|
* GNU General Public License for more details:
|
||||||
*
|
*
|
||||||
* Copyright (C) 2014 Ammonit Measurement GmbH
|
* Copyright (C) 2014 Ammonit Measurement GmbH
|
||||||
* Author: Aleksander Morgado <aleksander@aleksander.es>
|
* Copyright (C) 2014 - 2018 Aleksander Morgado <aleksander@aleksander.es>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "mm-common-cinterion.h"
|
#include <config.h>
|
||||||
#include "mm-base-modem-at.h"
|
|
||||||
|
#include <glib-object.h>
|
||||||
|
#include <gio/gio.h>
|
||||||
|
|
||||||
|
#define _LIBMM_INSIDE_MM
|
||||||
|
#include <libmm-glib.h>
|
||||||
|
|
||||||
#include "mm-log.h"
|
#include "mm-log.h"
|
||||||
|
#include "mm-iface-modem.h"
|
||||||
static MMIfaceModemLocation *iface_modem_location_parent;
|
#include "mm-iface-modem-location.h"
|
||||||
|
#include "mm-base-modem.h"
|
||||||
|
#include "mm-base-modem-at.h"
|
||||||
|
#include "mm-shared-cinterion.h"
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
/* Private data context */
|
||||||
|
|
||||||
#define CINTERION_LOCATION_CONTEXT_TAG "cinterion-location-tag"
|
#define PRIVATE_TAG "shared-cinterion-private-tag"
|
||||||
static GQuark cinterion_location_context_quark;
|
static GQuark private_quark;
|
||||||
|
|
||||||
/*****************************************************************************/
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
FEATURE_SUPPORT_UNKNOWN,
|
FEATURE_SUPPORT_UNKNOWN,
|
||||||
@@ -34,42 +42,44 @@ typedef enum {
|
|||||||
} FeatureSupport;
|
} FeatureSupport;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
MMIfaceModemLocation *iface_modem_location_parent;
|
||||||
|
MMModemLocationSource supported_sources;
|
||||||
MMModemLocationSource enabled_sources;
|
MMModemLocationSource enabled_sources;
|
||||||
FeatureSupport sgpss_support;
|
FeatureSupport sgpss_support;
|
||||||
FeatureSupport sgpsc_support;
|
FeatureSupport sgpsc_support;
|
||||||
} LocationContext;
|
} Private;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
location_context_free (LocationContext *ctx)
|
private_free (Private *ctx)
|
||||||
{
|
{
|
||||||
g_slice_free (LocationContext, ctx);
|
g_slice_free (Private, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
static LocationContext *
|
static Private *
|
||||||
get_location_context (MMBaseModem *self)
|
get_private (MMSharedCinterion *self)
|
||||||
{
|
{
|
||||||
LocationContext *ctx;
|
Private *priv;
|
||||||
|
|
||||||
if (G_UNLIKELY (!cinterion_location_context_quark))
|
if (G_UNLIKELY (!private_quark))
|
||||||
cinterion_location_context_quark = (g_quark_from_static_string (
|
private_quark = (g_quark_from_static_string (PRIVATE_TAG));
|
||||||
CINTERION_LOCATION_CONTEXT_TAG));
|
|
||||||
|
|
||||||
ctx = g_object_get_qdata (G_OBJECT (self), cinterion_location_context_quark);
|
priv = g_object_get_qdata (G_OBJECT (self), private_quark);
|
||||||
if (!ctx) {
|
if (!priv) {
|
||||||
/* Create context and keep it as object data */
|
priv = g_slice_new (Private);
|
||||||
ctx = g_slice_new (LocationContext);
|
|
||||||
ctx->enabled_sources = MM_MODEM_LOCATION_SOURCE_NONE;
|
|
||||||
ctx->sgpss_support = FEATURE_SUPPORT_UNKNOWN;
|
|
||||||
ctx->sgpsc_support = FEATURE_SUPPORT_UNKNOWN;
|
|
||||||
|
|
||||||
g_object_set_qdata_full (
|
priv->supported_sources = MM_MODEM_LOCATION_SOURCE_NONE;
|
||||||
G_OBJECT (self),
|
priv->enabled_sources = MM_MODEM_LOCATION_SOURCE_NONE;
|
||||||
cinterion_location_context_quark,
|
priv->sgpss_support = FEATURE_SUPPORT_UNKNOWN;
|
||||||
ctx,
|
priv->sgpsc_support = FEATURE_SUPPORT_UNKNOWN;
|
||||||
(GDestroyNotify)location_context_free);
|
|
||||||
|
/* Setup parent class' MMIfaceModemLocation */
|
||||||
|
g_assert (MM_SHARED_CINTERION_GET_INTERFACE (self)->peek_parent_location_interface);
|
||||||
|
priv->iface_modem_location_parent = MM_SHARED_CINTERION_GET_INTERFACE (self)->peek_parent_location_interface (self);
|
||||||
|
|
||||||
|
g_object_set_qdata_full (G_OBJECT (self), private_quark, priv, (GDestroyNotify)private_free);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ctx;
|
return priv;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@@ -107,18 +117,8 @@ trace_received (MMPortSerialGps *port,
|
|||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Location capabilities loading (Location interface) */
|
/* Location capabilities loading (Location interface) */
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
MMModemLocationSource sources;
|
|
||||||
} LoadCapabilitiesContext;
|
|
||||||
|
|
||||||
static void
|
|
||||||
load_capabilities_context_free (LoadCapabilitiesContext *ctx)
|
|
||||||
{
|
|
||||||
g_slice_free (LoadCapabilitiesContext, ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
MMModemLocationSource
|
MMModemLocationSource
|
||||||
mm_common_cinterion_location_load_capabilities_finish (MMIfaceModemLocation *self,
|
mm_shared_cinterion_location_load_capabilities_finish (MMIfaceModemLocation *self,
|
||||||
GAsyncResult *res,
|
GAsyncResult *res,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
@@ -140,14 +140,15 @@ sgpsc_test_ready (MMBaseModem *self,
|
|||||||
GAsyncResult *res,
|
GAsyncResult *res,
|
||||||
GTask *task)
|
GTask *task)
|
||||||
{
|
{
|
||||||
LocationContext *location_ctx;
|
Private *priv;
|
||||||
|
|
||||||
|
priv = get_private (MM_SHARED_CINTERION (self));
|
||||||
|
|
||||||
location_ctx = get_location_context (self);
|
|
||||||
if (!mm_base_modem_at_command_finish (self, res, NULL))
|
if (!mm_base_modem_at_command_finish (self, res, NULL))
|
||||||
location_ctx->sgpsc_support = FEATURE_NOT_SUPPORTED;
|
priv->sgpsc_support = FEATURE_NOT_SUPPORTED;
|
||||||
else {
|
else {
|
||||||
/* ^SGPSC supported! */
|
/* ^SGPSC supported! */
|
||||||
location_ctx->sgpsc_support = FEATURE_SUPPORTED;
|
priv->sgpsc_support = FEATURE_SUPPORTED;
|
||||||
/* It may happen that the modem was started with GPS already enabled, or
|
/* It may happen that the modem was started with GPS already enabled, or
|
||||||
* maybe ModemManager got rebooted and it was left enabled before. We'll
|
* maybe ModemManager got rebooted and it was left enabled before. We'll
|
||||||
* make sure that it is disabled when we initialize the modem. */
|
* make sure that it is disabled when we initialize the modem. */
|
||||||
@@ -164,18 +165,19 @@ sgpss_test_ready (MMBaseModem *self,
|
|||||||
GAsyncResult *res,
|
GAsyncResult *res,
|
||||||
GTask *task)
|
GTask *task)
|
||||||
{
|
{
|
||||||
LocationContext *location_ctx;
|
Private *priv;
|
||||||
|
|
||||||
|
priv = get_private (MM_SHARED_CINTERION (self));
|
||||||
|
|
||||||
location_ctx = get_location_context (self);
|
|
||||||
if (!mm_base_modem_at_command_finish (self, res, NULL))
|
if (!mm_base_modem_at_command_finish (self, res, NULL))
|
||||||
location_ctx->sgpss_support = FEATURE_NOT_SUPPORTED;
|
priv->sgpss_support = FEATURE_NOT_SUPPORTED;
|
||||||
else {
|
else {
|
||||||
/* ^SGPSS supported! */
|
/* ^SGPSS supported! */
|
||||||
location_ctx->sgpss_support = FEATURE_SUPPORTED;
|
priv->sgpss_support = FEATURE_SUPPORTED;
|
||||||
|
|
||||||
/* Flag ^SGPSC as unsupported, even if it may be supported, so that we
|
/* Flag ^SGPSC as unsupported, even if it may be supported, so that we
|
||||||
* only use one set of commands to enable/disable GPS. */
|
* only use one set of commands to enable/disable GPS. */
|
||||||
location_ctx->sgpsc_support = FEATURE_NOT_SUPPORTED;
|
priv->sgpsc_support = FEATURE_NOT_SUPPORTED;
|
||||||
|
|
||||||
/* It may happen that the modem was started with GPS already enabled, or
|
/* It may happen that the modem was started with GPS already enabled, or
|
||||||
* maybe ModemManager got rebooted and it was left enabled before. We'll
|
* maybe ModemManager got rebooted and it was left enabled before. We'll
|
||||||
@@ -189,32 +191,43 @@ sgpss_test_ready (MMBaseModem *self,
|
|||||||
static void
|
static void
|
||||||
probe_gps_features (GTask *task)
|
probe_gps_features (GTask *task)
|
||||||
{
|
{
|
||||||
LoadCapabilitiesContext *ctx;
|
MMSharedCinterion *self;
|
||||||
MMBaseModem *self;
|
MMModemLocationSource sources;
|
||||||
LocationContext *location_ctx;
|
Private *priv;
|
||||||
|
|
||||||
ctx = (LoadCapabilitiesContext *) g_task_get_task_data (task);
|
self = MM_SHARED_CINTERION (g_task_get_source_object (task));
|
||||||
self = MM_BASE_MODEM (g_task_get_source_object (task));
|
priv = get_private (self);
|
||||||
location_ctx = get_location_context (self);
|
|
||||||
|
|
||||||
/* Need to check if SGPSS supported... */
|
/* Need to check if SGPSS supported... */
|
||||||
if (location_ctx->sgpss_support == FEATURE_SUPPORT_UNKNOWN) {
|
if (priv->sgpss_support == FEATURE_SUPPORT_UNKNOWN) {
|
||||||
mm_base_modem_at_command (self, "AT^SGPSS=?", 3, TRUE, (GAsyncReadyCallback) sgpss_test_ready, task);
|
mm_base_modem_at_command (MM_BASE_MODEM (self), "AT^SGPSS=?", 3, TRUE, (GAsyncReadyCallback) sgpss_test_ready, task);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Need to check if SGPSC supported... */
|
/* Need to check if SGPSC supported... */
|
||||||
if (location_ctx->sgpsc_support == FEATURE_SUPPORT_UNKNOWN) {
|
if (priv->sgpsc_support == FEATURE_SUPPORT_UNKNOWN) {
|
||||||
mm_base_modem_at_command (self, "AT^SGPSC=?", 3, TRUE, (GAsyncReadyCallback) sgpsc_test_ready, task);
|
mm_base_modem_at_command (MM_BASE_MODEM (self), "AT^SGPSC=?", 3, TRUE, (GAsyncReadyCallback) sgpsc_test_ready, task);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* All GPS features probed, check if GPS supported */
|
/* All GPS features probed */
|
||||||
if (location_ctx->sgpss_support == FEATURE_SUPPORTED || location_ctx->sgpsc_support == FEATURE_SUPPORTED) {
|
|
||||||
|
/* Recover parent sources */
|
||||||
|
sources = GPOINTER_TO_UINT (g_task_get_task_data (task));
|
||||||
|
|
||||||
|
if (priv->sgpss_support == FEATURE_SUPPORTED || priv->sgpsc_support == FEATURE_SUPPORTED) {
|
||||||
mm_dbg ("GPS commands supported: GPS capabilities enabled");
|
mm_dbg ("GPS commands supported: GPS capabilities enabled");
|
||||||
ctx->sources |= (MM_MODEM_LOCATION_SOURCE_GPS_NMEA |
|
|
||||||
MM_MODEM_LOCATION_SOURCE_GPS_RAW |
|
/* We only flag as supported by this implementation those sources not already
|
||||||
MM_MODEM_LOCATION_SOURCE_GPS_UNMANAGED);
|
* supported by the parent implementation */
|
||||||
|
if (!(sources & MM_MODEM_LOCATION_SOURCE_GPS_NMEA))
|
||||||
|
priv->supported_sources |= MM_MODEM_LOCATION_SOURCE_GPS_NMEA;
|
||||||
|
if (!(sources & MM_MODEM_LOCATION_SOURCE_GPS_RAW))
|
||||||
|
priv->supported_sources |= MM_MODEM_LOCATION_SOURCE_GPS_RAW;
|
||||||
|
if (!(sources & MM_MODEM_LOCATION_SOURCE_GPS_UNMANAGED))
|
||||||
|
priv->supported_sources |= MM_MODEM_LOCATION_SOURCE_GPS_UNMANAGED;
|
||||||
|
|
||||||
|
sources |= priv->supported_sources;
|
||||||
|
|
||||||
/* Add handler for the NMEA traces in the GPS data port */
|
/* Add handler for the NMEA traces in the GPS data port */
|
||||||
mm_port_serial_gps_add_trace_handler (mm_base_modem_peek_port_gps (MM_BASE_MODEM (self)),
|
mm_port_serial_gps_add_trace_handler (mm_base_modem_peek_port_gps (MM_BASE_MODEM (self)),
|
||||||
@@ -224,7 +237,7 @@ probe_gps_features (GTask *task)
|
|||||||
} else
|
} else
|
||||||
mm_dbg ("No GPS command supported: no GPS capabilities");
|
mm_dbg ("No GPS command supported: no GPS capabilities");
|
||||||
|
|
||||||
g_task_return_int (task, (gssize) ctx->sources);
|
g_task_return_int (task, (gssize) sources);
|
||||||
g_object_unref (task);
|
g_object_unref (task);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -233,12 +246,13 @@ parent_load_capabilities_ready (MMIfaceModemLocation *self,
|
|||||||
GAsyncResult *res,
|
GAsyncResult *res,
|
||||||
GTask *task)
|
GTask *task)
|
||||||
{
|
{
|
||||||
LoadCapabilitiesContext *ctx;
|
MMModemLocationSource sources;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
Private *priv;
|
||||||
|
|
||||||
ctx = (LoadCapabilitiesContext *) g_task_get_task_data (task);
|
priv = get_private (MM_SHARED_CINTERION (self));
|
||||||
|
|
||||||
ctx->sources = iface_modem_location_parent->load_capabilities_finish (self, res, &error);
|
sources = priv->iface_modem_location_parent->load_capabilities_finish (self, res, &error);
|
||||||
if (error) {
|
if (error) {
|
||||||
g_task_return_error (task, error);
|
g_task_return_error (task, error);
|
||||||
g_object_unref (task);
|
g_object_unref (task);
|
||||||
@@ -248,32 +262,34 @@ parent_load_capabilities_ready (MMIfaceModemLocation *self,
|
|||||||
/* Now our own check. If we don't have any GPS port, we're done */
|
/* Now our own check. If we don't have any GPS port, we're done */
|
||||||
if (!mm_base_modem_peek_port_gps (MM_BASE_MODEM (self))) {
|
if (!mm_base_modem_peek_port_gps (MM_BASE_MODEM (self))) {
|
||||||
mm_dbg ("No GPS data port found: no GPS capabilities");
|
mm_dbg ("No GPS data port found: no GPS capabilities");
|
||||||
g_task_return_boolean (task, TRUE);
|
g_task_return_int (task, sources);
|
||||||
g_object_unref (task);
|
g_object_unref (task);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Cache sources supported by the parent */
|
||||||
|
g_task_set_task_data (task, GUINT_TO_POINTER (sources), NULL);
|
||||||
|
|
||||||
/* Probe all GPS features */
|
/* Probe all GPS features */
|
||||||
probe_gps_features (task);
|
probe_gps_features (task);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
mm_common_cinterion_location_load_capabilities (MMIfaceModemLocation *self,
|
mm_shared_cinterion_location_load_capabilities (MMIfaceModemLocation *self,
|
||||||
GAsyncReadyCallback callback,
|
GAsyncReadyCallback callback,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
|
Private *priv;
|
||||||
GTask *task;
|
GTask *task;
|
||||||
LoadCapabilitiesContext *ctx;
|
|
||||||
|
|
||||||
|
priv = get_private (MM_SHARED_CINTERION (self));
|
||||||
task = g_task_new (self, NULL, callback, user_data);
|
task = g_task_new (self, NULL, callback, user_data);
|
||||||
|
|
||||||
ctx = g_slice_new0 (LoadCapabilitiesContext);
|
g_assert (priv->iface_modem_location_parent);
|
||||||
ctx->sources = MM_MODEM_LOCATION_SOURCE_NONE;
|
g_assert (priv->iface_modem_location_parent->load_capabilities);
|
||||||
g_task_set_task_data (task, ctx, (GDestroyNotify) load_capabilities_context_free);
|
g_assert (priv->iface_modem_location_parent->load_capabilities_finish);
|
||||||
|
|
||||||
/* Chain up parent's setup */
|
priv->iface_modem_location_parent->load_capabilities (self,
|
||||||
iface_modem_location_parent->load_capabilities (
|
|
||||||
self,
|
|
||||||
(GAsyncReadyCallback)parent_load_capabilities_ready,
|
(GAsyncReadyCallback)parent_load_capabilities_ready,
|
||||||
task);
|
task);
|
||||||
}
|
}
|
||||||
@@ -308,7 +324,7 @@ disable_location_gathering_context_free (DisableLocationGatheringContext *ctx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
mm_common_cinterion_disable_location_gathering_finish (MMIfaceModemLocation *self,
|
mm_shared_cinterion_disable_location_gathering_finish (MMIfaceModemLocation *self,
|
||||||
GAsyncResult *res,
|
GAsyncResult *res,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
@@ -360,16 +376,16 @@ static void
|
|||||||
disable_location_gathering_context_gps_step (GTask *task)
|
disable_location_gathering_context_gps_step (GTask *task)
|
||||||
{
|
{
|
||||||
DisableLocationGatheringContext *ctx;
|
DisableLocationGatheringContext *ctx;
|
||||||
MMBaseModem *self;
|
MMSharedCinterion *self;
|
||||||
LocationContext *location_ctx;
|
Private *priv;
|
||||||
|
|
||||||
self = MM_BASE_MODEM (g_task_get_source_object (task));
|
self = MM_SHARED_CINTERION (g_task_get_source_object (task));
|
||||||
|
priv = get_private (self);
|
||||||
ctx = (DisableLocationGatheringContext *) g_task_get_task_data (task);
|
ctx = (DisableLocationGatheringContext *) g_task_get_task_data (task);
|
||||||
location_ctx = get_location_context (MM_BASE_MODEM (self));
|
|
||||||
|
|
||||||
/* Only one of both supported */
|
/* Only one of both supported */
|
||||||
g_assert ((location_ctx->sgpss_support == FEATURE_SUPPORTED) || (location_ctx->sgpsc_support == FEATURE_SUPPORTED));
|
g_assert ((priv->sgpss_support == FEATURE_SUPPORTED) || (priv->sgpsc_support == FEATURE_SUPPORTED));
|
||||||
g_assert (!((location_ctx->sgpss_support == FEATURE_SUPPORTED) && (location_ctx->sgpsc_support == FEATURE_SUPPORTED)));
|
g_assert (!((priv->sgpss_support == FEATURE_SUPPORTED) && (priv->sgpsc_support == FEATURE_SUPPORTED)));
|
||||||
|
|
||||||
switch (ctx->gps_step) {
|
switch (ctx->gps_step) {
|
||||||
case DISABLE_LOCATION_GATHERING_GPS_STEP_FIRST:
|
case DISABLE_LOCATION_GATHERING_GPS_STEP_FIRST:
|
||||||
@@ -377,7 +393,7 @@ disable_location_gathering_context_gps_step (GTask *task)
|
|||||||
/* Fall down to next step */
|
/* Fall down to next step */
|
||||||
|
|
||||||
case DISABLE_LOCATION_GATHERING_GPS_STEP_SGPSS:
|
case DISABLE_LOCATION_GATHERING_GPS_STEP_SGPSS:
|
||||||
if (location_ctx->sgpss_support == FEATURE_SUPPORTED) {
|
if (priv->sgpss_support == FEATURE_SUPPORTED) {
|
||||||
mm_base_modem_at_command (MM_BASE_MODEM (self),
|
mm_base_modem_at_command (MM_BASE_MODEM (self),
|
||||||
"AT^SGPSS=0",
|
"AT^SGPSS=0",
|
||||||
3, FALSE, (GAsyncReadyCallback) disable_sgpss_ready, task);
|
3, FALSE, (GAsyncReadyCallback) disable_sgpss_ready, task);
|
||||||
@@ -387,7 +403,7 @@ disable_location_gathering_context_gps_step (GTask *task)
|
|||||||
/* Fall down to next step */
|
/* Fall down to next step */
|
||||||
|
|
||||||
case DISABLE_LOCATION_GATHERING_GPS_STEP_SGPSC_ENGINE:
|
case DISABLE_LOCATION_GATHERING_GPS_STEP_SGPSC_ENGINE:
|
||||||
if (location_ctx->sgpsc_support == FEATURE_SUPPORTED) {
|
if (priv->sgpsc_support == FEATURE_SUPPORTED) {
|
||||||
/* Engine off */
|
/* Engine off */
|
||||||
mm_base_modem_at_command (MM_BASE_MODEM (self),
|
mm_base_modem_at_command (MM_BASE_MODEM (self),
|
||||||
"AT^SGPSC=\"Engine\",\"0\"",
|
"AT^SGPSC=\"Engine\",\"0\"",
|
||||||
@@ -398,7 +414,7 @@ disable_location_gathering_context_gps_step (GTask *task)
|
|||||||
/* Fall down to next step */
|
/* Fall down to next step */
|
||||||
|
|
||||||
case DISABLE_LOCATION_GATHERING_GPS_STEP_SGPSC_ANTENNA:
|
case DISABLE_LOCATION_GATHERING_GPS_STEP_SGPSC_ANTENNA:
|
||||||
if (location_ctx->sgpsc_support == FEATURE_SUPPORTED) {
|
if (priv->sgpsc_support == FEATURE_SUPPORTED) {
|
||||||
/* Antenna off */
|
/* Antenna off */
|
||||||
mm_base_modem_at_command (MM_BASE_MODEM (self),
|
mm_base_modem_at_command (MM_BASE_MODEM (self),
|
||||||
"AT^SGPSC=\"Power/Antenna\",\"off\"",
|
"AT^SGPSC=\"Power/Antenna\",\"off\"",
|
||||||
@@ -409,7 +425,7 @@ disable_location_gathering_context_gps_step (GTask *task)
|
|||||||
/* Fall down to next step */
|
/* Fall down to next step */
|
||||||
|
|
||||||
case DISABLE_LOCATION_GATHERING_GPS_STEP_SGPSC_OUTPUT:
|
case DISABLE_LOCATION_GATHERING_GPS_STEP_SGPSC_OUTPUT:
|
||||||
if (location_ctx->sgpsc_support == FEATURE_SUPPORTED) {
|
if (priv->sgpsc_support == FEATURE_SUPPORTED) {
|
||||||
/* NMEA output off */
|
/* NMEA output off */
|
||||||
mm_base_modem_at_command (MM_BASE_MODEM (self),
|
mm_base_modem_at_command (MM_BASE_MODEM (self),
|
||||||
"AT^SGPSC=\"NMEA/Output\",\"off\"",
|
"AT^SGPSC=\"NMEA/Output\",\"off\"",
|
||||||
@@ -425,7 +441,7 @@ disable_location_gathering_context_gps_step (GTask *task)
|
|||||||
MMPortSerialGps *gps_port;
|
MMPortSerialGps *gps_port;
|
||||||
|
|
||||||
/* Even if we get an error here, we try to close the GPS port */
|
/* Even if we get an error here, we try to close the GPS port */
|
||||||
gps_port = mm_base_modem_peek_port_gps (self);
|
gps_port = mm_base_modem_peek_port_gps (MM_BASE_MODEM (self));
|
||||||
if (gps_port)
|
if (gps_port)
|
||||||
mm_port_serial_close (MM_PORT_SERIAL (gps_port));
|
mm_port_serial_close (MM_PORT_SERIAL (gps_port));
|
||||||
}
|
}
|
||||||
@@ -436,101 +452,92 @@ disable_location_gathering_context_gps_step (GTask *task)
|
|||||||
} else if (ctx->sgpsc_error) {
|
} else if (ctx->sgpsc_error) {
|
||||||
g_task_return_error (task, ctx->sgpsc_error);
|
g_task_return_error (task, ctx->sgpsc_error);
|
||||||
g_clear_error (&ctx->sgpsc_error);
|
g_clear_error (&ctx->sgpsc_error);
|
||||||
} else
|
} else {
|
||||||
|
priv->enabled_sources &= ~ctx->source;
|
||||||
g_task_return_boolean (task, TRUE);
|
g_task_return_boolean (task, TRUE);
|
||||||
|
}
|
||||||
g_object_unref (task);
|
g_object_unref (task);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
internal_disable_location_gathering (GTask *task)
|
|
||||||
{
|
|
||||||
DisableLocationGatheringContext *ctx;
|
|
||||||
LocationContext *location_ctx;
|
|
||||||
gboolean stop_gps = FALSE;
|
|
||||||
|
|
||||||
ctx = (DisableLocationGatheringContext *) g_task_get_task_data (task);
|
|
||||||
|
|
||||||
location_ctx = get_location_context (MM_BASE_MODEM (g_task_get_source_object (task)));
|
|
||||||
|
|
||||||
/* Only stop GPS engine if no GPS-related sources enabled */
|
|
||||||
if (ctx->source & (MM_MODEM_LOCATION_SOURCE_GPS_NMEA |
|
|
||||||
MM_MODEM_LOCATION_SOURCE_GPS_RAW |
|
|
||||||
MM_MODEM_LOCATION_SOURCE_GPS_UNMANAGED)) {
|
|
||||||
location_ctx->enabled_sources &= ~ctx->source;
|
|
||||||
|
|
||||||
if (!(location_ctx->enabled_sources & (MM_MODEM_LOCATION_SOURCE_GPS_NMEA |
|
|
||||||
MM_MODEM_LOCATION_SOURCE_GPS_RAW |
|
|
||||||
MM_MODEM_LOCATION_SOURCE_GPS_UNMANAGED)))
|
|
||||||
stop_gps = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Run GPS stop sequence only if required to do so */
|
|
||||||
if (stop_gps) {
|
|
||||||
disable_location_gathering_context_gps_step (task);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* For any other location (e.g. 3GPP), or if still some GPS needed, just return */
|
|
||||||
g_task_return_boolean (task, TRUE);
|
|
||||||
g_object_unref (task);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
parent_disable_location_gathering_ready (MMIfaceModemLocation *self,
|
parent_disable_location_gathering_ready (MMIfaceModemLocation *self,
|
||||||
GAsyncResult *res,
|
GAsyncResult *res,
|
||||||
GTask *task)
|
GTask *task)
|
||||||
{
|
{
|
||||||
DisableLocationGatheringContext *ctx;
|
GError *error;
|
||||||
GError *error = NULL;
|
Private *priv;
|
||||||
|
|
||||||
ctx = (DisableLocationGatheringContext *) g_task_get_task_data (task);
|
priv = get_private (MM_SHARED_CINTERION (self));
|
||||||
|
|
||||||
if (!iface_modem_location_parent->disable_location_gathering_finish (self, res, &error)) {
|
g_assert (priv->iface_modem_location_parent);
|
||||||
/* Errors when disabling non-GPS sources are fatal */
|
if (!priv->iface_modem_location_parent->disable_location_gathering_finish (self, res, &error))
|
||||||
if (!(ctx->source & (MM_MODEM_LOCATION_SOURCE_GPS_NMEA |
|
|
||||||
MM_MODEM_LOCATION_SOURCE_GPS_RAW |
|
|
||||||
MM_MODEM_LOCATION_SOURCE_GPS_UNMANAGED))) {
|
|
||||||
g_task_return_error (task, error);
|
g_task_return_error (task, error);
|
||||||
|
else
|
||||||
|
g_task_return_boolean (task, TRUE);
|
||||||
g_object_unref (task);
|
g_object_unref (task);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Ignore errors when disabling GPS, we can try with AT commands */
|
|
||||||
g_error_free (error);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal_disable_location_gathering (task);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
mm_common_cinterion_disable_location_gathering (MMIfaceModemLocation *self,
|
mm_shared_cinterion_disable_location_gathering (MMIfaceModemLocation *self,
|
||||||
MMModemLocationSource source,
|
MMModemLocationSource source,
|
||||||
GAsyncReadyCallback callback,
|
GAsyncReadyCallback callback,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
GTask *task;
|
|
||||||
DisableLocationGatheringContext *ctx;
|
DisableLocationGatheringContext *ctx;
|
||||||
|
MMModemLocationSource enabled_sources;
|
||||||
|
Private *priv;
|
||||||
|
GTask *task;
|
||||||
|
|
||||||
task = g_task_new (self, NULL, callback, user_data);
|
task = g_task_new (self, NULL, callback, user_data);
|
||||||
|
|
||||||
ctx = g_slice_new0 (DisableLocationGatheringContext);
|
priv = get_private (MM_SHARED_CINTERION (self));
|
||||||
ctx->source = source;
|
g_assert (priv->iface_modem_location_parent);
|
||||||
ctx->gps_step = DISABLE_LOCATION_GATHERING_GPS_STEP_FIRST;
|
|
||||||
g_task_set_task_data (task, ctx, (GDestroyNotify) disable_location_gathering_context_free);
|
|
||||||
|
|
||||||
/* Chain up parent's gathering enable */
|
/* Only consider request if it applies to one of the sources we are
|
||||||
if (iface_modem_location_parent->disable_location_gathering) {
|
* supporting, otherwise run parent disable */
|
||||||
iface_modem_location_parent->disable_location_gathering (
|
if (!(priv->supported_sources & source)) {
|
||||||
self,
|
/* If disabling implemented by the parent, run it. */
|
||||||
|
if (priv->iface_modem_location_parent->disable_location_gathering &&
|
||||||
|
priv->iface_modem_location_parent->disable_location_gathering_finish) {
|
||||||
|
priv->iface_modem_location_parent->disable_location_gathering (self,
|
||||||
source,
|
source,
|
||||||
(GAsyncReadyCallback)parent_disable_location_gathering_ready,
|
(GAsyncReadyCallback)parent_disable_location_gathering_ready,
|
||||||
task);
|
task);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
/* Otherwise, we're done */
|
||||||
|
g_task_return_boolean (task, TRUE);
|
||||||
|
g_object_unref (task);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
internal_disable_location_gathering (task);
|
/* We only expect GPS sources here */
|
||||||
|
g_assert (source & (MM_MODEM_LOCATION_SOURCE_GPS_NMEA |
|
||||||
|
MM_MODEM_LOCATION_SOURCE_GPS_RAW |
|
||||||
|
MM_MODEM_LOCATION_SOURCE_GPS_UNMANAGED));
|
||||||
|
|
||||||
|
/* Flag as disabled to see how many others we would have left enabled */
|
||||||
|
enabled_sources = priv->enabled_sources;
|
||||||
|
enabled_sources &= ~source;
|
||||||
|
|
||||||
|
/* If there are still GPS-related sources enabled, do nothing else */
|
||||||
|
if (enabled_sources & (MM_MODEM_LOCATION_SOURCE_GPS_NMEA |
|
||||||
|
MM_MODEM_LOCATION_SOURCE_GPS_RAW |
|
||||||
|
MM_MODEM_LOCATION_SOURCE_GPS_UNMANAGED)) {
|
||||||
|
priv->enabled_sources &= ~source;
|
||||||
|
g_task_return_boolean (task, TRUE);
|
||||||
|
g_object_unref (task);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Stop GPS engine if all GPS-related sources are disabled */
|
||||||
|
ctx = g_slice_new0 (DisableLocationGatheringContext);
|
||||||
|
ctx->source = source;
|
||||||
|
ctx->gps_step = DISABLE_LOCATION_GATHERING_GPS_STEP_FIRST;
|
||||||
|
g_task_set_task_data (task, ctx, (GDestroyNotify) disable_location_gathering_context_free);
|
||||||
|
disable_location_gathering_context_gps_step (task);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@@ -567,7 +574,7 @@ enable_location_gathering_context_free (EnableLocationGatheringContext *ctx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
mm_common_cinterion_enable_location_gathering_finish (MMIfaceModemLocation *self,
|
mm_shared_cinterion_enable_location_gathering_finish (MMIfaceModemLocation *self,
|
||||||
GAsyncResult *res,
|
GAsyncResult *res,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
@@ -622,16 +629,16 @@ static void
|
|||||||
enable_location_gathering_context_gps_step (GTask *task)
|
enable_location_gathering_context_gps_step (GTask *task)
|
||||||
{
|
{
|
||||||
EnableLocationGatheringContext *ctx;
|
EnableLocationGatheringContext *ctx;
|
||||||
MMBaseModem *self;
|
MMSharedCinterion *self;
|
||||||
LocationContext *location_ctx;
|
Private *priv;
|
||||||
|
|
||||||
self = MM_BASE_MODEM (g_task_get_source_object (task));
|
self = MM_SHARED_CINTERION (g_task_get_source_object (task));
|
||||||
|
priv = get_private (self);
|
||||||
ctx = (EnableLocationGatheringContext *) g_task_get_task_data (task);
|
ctx = (EnableLocationGatheringContext *) g_task_get_task_data (task);
|
||||||
location_ctx = get_location_context (MM_BASE_MODEM (self));
|
|
||||||
|
|
||||||
/* Only one of both supported */
|
/* Only one of both supported */
|
||||||
g_assert ((location_ctx->sgpss_support == FEATURE_SUPPORTED) || (location_ctx->sgpsc_support == FEATURE_SUPPORTED));
|
g_assert ((priv->sgpss_support == FEATURE_SUPPORTED) || (priv->sgpsc_support == FEATURE_SUPPORTED));
|
||||||
g_assert (!((location_ctx->sgpss_support == FEATURE_SUPPORTED) && (location_ctx->sgpsc_support == FEATURE_SUPPORTED)));
|
g_assert (!((priv->sgpss_support == FEATURE_SUPPORTED) && (priv->sgpsc_support == FEATURE_SUPPORTED)));
|
||||||
|
|
||||||
switch (ctx->gps_step) {
|
switch (ctx->gps_step) {
|
||||||
case ENABLE_LOCATION_GATHERING_GPS_STEP_FIRST:
|
case ENABLE_LOCATION_GATHERING_GPS_STEP_FIRST:
|
||||||
@@ -639,7 +646,7 @@ enable_location_gathering_context_gps_step (GTask *task)
|
|||||||
/* Fall down to next step */
|
/* Fall down to next step */
|
||||||
|
|
||||||
case ENABLE_LOCATION_GATHERING_GPS_STEP_SGPSS:
|
case ENABLE_LOCATION_GATHERING_GPS_STEP_SGPSS:
|
||||||
if (location_ctx->sgpss_support == FEATURE_SUPPORTED) {
|
if (priv->sgpss_support == FEATURE_SUPPORTED) {
|
||||||
mm_base_modem_at_command (MM_BASE_MODEM (self),
|
mm_base_modem_at_command (MM_BASE_MODEM (self),
|
||||||
"AT^SGPSS=4",
|
"AT^SGPSS=4",
|
||||||
3, FALSE, (GAsyncReadyCallback) enable_sgpsc_or_sgpss_ready, task);
|
3, FALSE, (GAsyncReadyCallback) enable_sgpsc_or_sgpss_ready, task);
|
||||||
@@ -649,7 +656,7 @@ enable_location_gathering_context_gps_step (GTask *task)
|
|||||||
/* Fall down to next step */
|
/* Fall down to next step */
|
||||||
|
|
||||||
case ENABLE_LOCATION_GATHERING_GPS_STEP_SGPSC_OUTPUT:
|
case ENABLE_LOCATION_GATHERING_GPS_STEP_SGPSC_OUTPUT:
|
||||||
if (location_ctx->sgpsc_support == FEATURE_SUPPORTED) {
|
if (priv->sgpsc_support == FEATURE_SUPPORTED) {
|
||||||
/* NMEA output off */
|
/* NMEA output off */
|
||||||
mm_base_modem_at_command (MM_BASE_MODEM (self),
|
mm_base_modem_at_command (MM_BASE_MODEM (self),
|
||||||
"AT^SGPSC=\"NMEA/Output\",\"on\"",
|
"AT^SGPSC=\"NMEA/Output\",\"on\"",
|
||||||
@@ -661,7 +668,7 @@ enable_location_gathering_context_gps_step (GTask *task)
|
|||||||
|
|
||||||
|
|
||||||
case ENABLE_LOCATION_GATHERING_GPS_STEP_SGPSC_ANTENNA:
|
case ENABLE_LOCATION_GATHERING_GPS_STEP_SGPSC_ANTENNA:
|
||||||
if (location_ctx->sgpsc_support == FEATURE_SUPPORTED) {
|
if (priv->sgpsc_support == FEATURE_SUPPORTED) {
|
||||||
/* Antenna off */
|
/* Antenna off */
|
||||||
mm_base_modem_at_command (MM_BASE_MODEM (self),
|
mm_base_modem_at_command (MM_BASE_MODEM (self),
|
||||||
"AT^SGPSC=\"Power/Antenna\",\"on\"",
|
"AT^SGPSC=\"Power/Antenna\",\"on\"",
|
||||||
@@ -672,7 +679,7 @@ enable_location_gathering_context_gps_step (GTask *task)
|
|||||||
/* Fall down to next step */
|
/* Fall down to next step */
|
||||||
|
|
||||||
case ENABLE_LOCATION_GATHERING_GPS_STEP_SGPSC_ENGINE:
|
case ENABLE_LOCATION_GATHERING_GPS_STEP_SGPSC_ENGINE:
|
||||||
if (location_ctx->sgpsc_support == FEATURE_SUPPORTED) {
|
if (priv->sgpsc_support == FEATURE_SUPPORTED) {
|
||||||
/* Engine off */
|
/* Engine off */
|
||||||
mm_base_modem_at_command (MM_BASE_MODEM (self),
|
mm_base_modem_at_command (MM_BASE_MODEM (self),
|
||||||
"AT^SGPSC=\"Engine\",\"1\"",
|
"AT^SGPSC=\"Engine\",\"1\"",
|
||||||
@@ -689,7 +696,7 @@ enable_location_gathering_context_gps_step (GTask *task)
|
|||||||
MMPortSerialGps *gps_port;
|
MMPortSerialGps *gps_port;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
|
||||||
gps_port = mm_base_modem_peek_port_gps (self);
|
gps_port = mm_base_modem_peek_port_gps (MM_BASE_MODEM (self));
|
||||||
if (!gps_port || !mm_port_serial_open (MM_PORT_SERIAL (gps_port), &error)) {
|
if (!gps_port || !mm_port_serial_open (MM_PORT_SERIAL (gps_port), &error)) {
|
||||||
if (error)
|
if (error)
|
||||||
g_task_return_error (task, error);
|
g_task_return_error (task, error);
|
||||||
@@ -702,101 +709,104 @@ enable_location_gathering_context_gps_step (GTask *task)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Success */
|
/* Success */
|
||||||
|
priv->enabled_sources |= ctx->source;
|
||||||
g_task_return_boolean (task, TRUE);
|
g_task_return_boolean (task, TRUE);
|
||||||
g_object_unref (task);
|
g_object_unref (task);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
internal_enable_location_gathering (GTask *task)
|
|
||||||
{
|
|
||||||
EnableLocationGatheringContext *ctx;
|
|
||||||
LocationContext *location_ctx;
|
|
||||||
gboolean start_gps = FALSE;
|
|
||||||
|
|
||||||
ctx = (EnableLocationGatheringContext *) g_task_get_task_data (task);
|
|
||||||
|
|
||||||
location_ctx = get_location_context (MM_BASE_MODEM (g_task_get_source_object (task)));
|
|
||||||
|
|
||||||
/* NMEA and RAW are both enabled in the same way */
|
|
||||||
if (ctx->source & (MM_MODEM_LOCATION_SOURCE_GPS_NMEA |
|
|
||||||
MM_MODEM_LOCATION_SOURCE_GPS_RAW |
|
|
||||||
MM_MODEM_LOCATION_SOURCE_GPS_UNMANAGED)) {
|
|
||||||
/* Only start GPS engine if not done already */
|
|
||||||
if (!(location_ctx->enabled_sources & (MM_MODEM_LOCATION_SOURCE_GPS_NMEA |
|
|
||||||
MM_MODEM_LOCATION_SOURCE_GPS_RAW |
|
|
||||||
MM_MODEM_LOCATION_SOURCE_GPS_UNMANAGED)))
|
|
||||||
start_gps = TRUE;
|
|
||||||
location_ctx->enabled_sources |= ctx->source;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (start_gps) {
|
|
||||||
enable_location_gathering_context_gps_step (task);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* For any other location (e.g. 3GPP), or if GPS already running just return */
|
|
||||||
g_task_return_boolean (task, TRUE);
|
|
||||||
g_object_unref (task);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
parent_enable_location_gathering_ready (MMIfaceModemLocation *self,
|
parent_enable_location_gathering_ready (MMIfaceModemLocation *self,
|
||||||
GAsyncResult *res,
|
GAsyncResult *res,
|
||||||
GTask *task)
|
GTask *task)
|
||||||
{
|
{
|
||||||
EnableLocationGatheringContext *ctx;
|
GError *error;
|
||||||
GError *error = NULL;
|
Private *priv;
|
||||||
|
|
||||||
ctx = (EnableLocationGatheringContext *) g_task_get_task_data (task);
|
priv = get_private (MM_SHARED_CINTERION (self));
|
||||||
|
|
||||||
if (!iface_modem_location_parent->enable_location_gathering_finish (self, res, &error)) {
|
g_assert (priv->iface_modem_location_parent);
|
||||||
/* Errors when enabling non-GPS sources are fatal */
|
if (!priv->iface_modem_location_parent->enable_location_gathering_finish (self, res, &error))
|
||||||
if (!(ctx->source & (MM_MODEM_LOCATION_SOURCE_GPS_NMEA |
|
|
||||||
MM_MODEM_LOCATION_SOURCE_GPS_RAW |
|
|
||||||
MM_MODEM_LOCATION_SOURCE_GPS_UNMANAGED))) {
|
|
||||||
g_task_return_error (task, error);
|
g_task_return_error (task, error);
|
||||||
|
else
|
||||||
|
g_task_return_boolean (task, TRUE);
|
||||||
g_object_unref (task);
|
g_object_unref (task);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Ignore errors when enabling GPS, we can try with AT commands */
|
|
||||||
g_error_free (error);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now our own enabling */
|
|
||||||
internal_enable_location_gathering (task);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
mm_common_cinterion_enable_location_gathering (MMIfaceModemLocation *self,
|
mm_shared_cinterion_enable_location_gathering (MMIfaceModemLocation *self,
|
||||||
MMModemLocationSource source,
|
MMModemLocationSource source,
|
||||||
GAsyncReadyCallback callback,
|
GAsyncReadyCallback callback,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
|
Private *priv;
|
||||||
GTask *task;
|
GTask *task;
|
||||||
EnableLocationGatheringContext *ctx;
|
EnableLocationGatheringContext *ctx;
|
||||||
|
|
||||||
|
|
||||||
task = g_task_new (self, NULL, callback, user_data);
|
task = g_task_new (self, NULL, callback, user_data);
|
||||||
|
|
||||||
|
priv = get_private (MM_SHARED_CINTERION (self));
|
||||||
|
g_assert (priv->iface_modem_location_parent);
|
||||||
|
g_assert (priv->iface_modem_location_parent->enable_location_gathering);
|
||||||
|
g_assert (priv->iface_modem_location_parent->enable_location_gathering_finish);
|
||||||
|
|
||||||
|
/* Only consider request if it applies to one of the sources we are
|
||||||
|
* supporting, otherwise run parent enable */
|
||||||
|
if (!(priv->supported_sources & source)) {
|
||||||
|
priv->iface_modem_location_parent->enable_location_gathering (self,
|
||||||
|
source,
|
||||||
|
(GAsyncReadyCallback)parent_enable_location_gathering_ready,
|
||||||
|
task);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We only expect GPS sources here */
|
||||||
|
g_assert (source & (MM_MODEM_LOCATION_SOURCE_GPS_NMEA |
|
||||||
|
MM_MODEM_LOCATION_SOURCE_GPS_RAW |
|
||||||
|
MM_MODEM_LOCATION_SOURCE_GPS_UNMANAGED));
|
||||||
|
|
||||||
|
/* If GPS already started, store new flag and we're done */
|
||||||
|
if (priv->enabled_sources & (MM_MODEM_LOCATION_SOURCE_GPS_NMEA |
|
||||||
|
MM_MODEM_LOCATION_SOURCE_GPS_RAW |
|
||||||
|
MM_MODEM_LOCATION_SOURCE_GPS_UNMANAGED)) {
|
||||||
|
priv->enabled_sources |= source;
|
||||||
|
g_task_return_boolean (task, TRUE);
|
||||||
|
g_object_unref (task);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ctx = g_slice_new0 (EnableLocationGatheringContext);
|
ctx = g_slice_new0 (EnableLocationGatheringContext);
|
||||||
ctx->source = source;
|
ctx->source = source;
|
||||||
ctx->gps_step = ENABLE_LOCATION_GATHERING_GPS_STEP_FIRST;
|
ctx->gps_step = ENABLE_LOCATION_GATHERING_GPS_STEP_FIRST;
|
||||||
g_task_set_task_data (task, ctx, (GDestroyNotify) enable_location_gathering_context_free);
|
g_task_set_task_data (task, ctx, (GDestroyNotify) enable_location_gathering_context_free);
|
||||||
|
|
||||||
/* Chain up parent's gathering enable */
|
enable_location_gathering_context_gps_step (task);
|
||||||
iface_modem_location_parent->enable_location_gathering (
|
|
||||||
self,
|
|
||||||
source,
|
|
||||||
(GAsyncReadyCallback)parent_enable_location_gathering_ready,
|
|
||||||
task);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
void
|
static void
|
||||||
mm_common_cinterion_peek_parent_location_interface (MMIfaceModemLocation *iface)
|
shared_cinterion_init (gpointer g_iface)
|
||||||
{
|
{
|
||||||
iface_modem_location_parent = g_type_interface_peek_parent (iface);
|
}
|
||||||
|
|
||||||
|
GType
|
||||||
|
mm_shared_cinterion_get_type (void)
|
||||||
|
{
|
||||||
|
static GType shared_cinterion_type = 0;
|
||||||
|
|
||||||
|
if (!G_UNLIKELY (shared_cinterion_type)) {
|
||||||
|
static const GTypeInfo info = {
|
||||||
|
sizeof (MMSharedCinterion), /* class_size */
|
||||||
|
shared_cinterion_init, /* base_init */
|
||||||
|
NULL, /* base_finalize */
|
||||||
|
};
|
||||||
|
|
||||||
|
shared_cinterion_type = g_type_register_static (G_TYPE_INTERFACE, "MMSharedCinterion", &info, 0);
|
||||||
|
g_type_interface_add_prerequisite (shared_cinterion_type, MM_TYPE_IFACE_MODEM_LOCATION);
|
||||||
|
}
|
||||||
|
|
||||||
|
return shared_cinterion_type;
|
||||||
}
|
}
|
@@ -11,39 +11,59 @@
|
|||||||
* GNU General Public License for more details:
|
* GNU General Public License for more details:
|
||||||
*
|
*
|
||||||
* Copyright (C) 2014 Ammonit Measurement GmbH
|
* Copyright (C) 2014 Ammonit Measurement GmbH
|
||||||
* Author: Aleksander Morgado <aleksander@aleksander.es>
|
* Copyright (C) 2014 - 2018 Aleksander Morgado <aleksander@aleksander.es>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef MM_COMMON_CINTERION_H
|
#ifndef MM_SHARED_CINTERION_H
|
||||||
#define MM_COMMON_CINTERION_H
|
#define MM_SHARED_CINTERION_H
|
||||||
|
|
||||||
|
#include <glib-object.h>
|
||||||
|
#include <gio/gio.h>
|
||||||
|
|
||||||
|
#define _LIBMM_INSIDE_MM
|
||||||
|
#include <libmm-glib.h>
|
||||||
|
|
||||||
#include "glib.h"
|
|
||||||
#include "mm-broadband-modem.h"
|
#include "mm-broadband-modem.h"
|
||||||
|
#include "mm-iface-modem.h"
|
||||||
#include "mm-iface-modem-location.h"
|
#include "mm-iface-modem-location.h"
|
||||||
|
|
||||||
void mm_common_cinterion_location_load_capabilities (MMIfaceModemLocation *self,
|
#define MM_TYPE_SHARED_CINTERION (mm_shared_cinterion_get_type ())
|
||||||
|
#define MM_SHARED_CINTERION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_SHARED_CINTERION, MMSharedCinterion))
|
||||||
|
#define MM_IS_SHARED_CINTERION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_SHARED_CINTERION))
|
||||||
|
#define MM_SHARED_CINTERION_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), MM_TYPE_SHARED_CINTERION, MMSharedCinterion))
|
||||||
|
|
||||||
|
typedef struct _MMSharedCinterion MMSharedCinterion;
|
||||||
|
|
||||||
|
struct _MMSharedCinterion {
|
||||||
|
GTypeInterface g_iface;
|
||||||
|
|
||||||
|
/* Peek location interface of the parent class of the object */
|
||||||
|
MMIfaceModemLocation * (* peek_parent_location_interface) (MMSharedCinterion *self);
|
||||||
|
};
|
||||||
|
|
||||||
|
GType mm_shared_cinterion_get_type (void);
|
||||||
|
|
||||||
|
void mm_shared_cinterion_location_load_capabilities (MMIfaceModemLocation *self,
|
||||||
GAsyncReadyCallback callback,
|
GAsyncReadyCallback callback,
|
||||||
gpointer user_data);
|
gpointer user_data);
|
||||||
MMModemLocationSource mm_common_cinterion_location_load_capabilities_finish (MMIfaceModemLocation *self,
|
MMModemLocationSource mm_shared_cinterion_location_load_capabilities_finish (MMIfaceModemLocation *self,
|
||||||
GAsyncResult *res,
|
GAsyncResult *res,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
void mm_common_cinterion_enable_location_gathering (MMIfaceModemLocation *self,
|
void mm_shared_cinterion_enable_location_gathering (MMIfaceModemLocation *self,
|
||||||
MMModemLocationSource source,
|
MMModemLocationSource source,
|
||||||
GAsyncReadyCallback callback,
|
GAsyncReadyCallback callback,
|
||||||
gpointer user_data);
|
gpointer user_data);
|
||||||
gboolean mm_common_cinterion_enable_location_gathering_finish (MMIfaceModemLocation *self,
|
gboolean mm_shared_cinterion_enable_location_gathering_finish (MMIfaceModemLocation *self,
|
||||||
GAsyncResult *res,
|
GAsyncResult *res,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
void mm_common_cinterion_disable_location_gathering (MMIfaceModemLocation *self,
|
void mm_shared_cinterion_disable_location_gathering (MMIfaceModemLocation *self,
|
||||||
MMModemLocationSource source,
|
MMModemLocationSource source,
|
||||||
GAsyncReadyCallback callback,
|
GAsyncReadyCallback callback,
|
||||||
gpointer user_data);
|
gpointer user_data);
|
||||||
gboolean mm_common_cinterion_disable_location_gathering_finish (MMIfaceModemLocation *self,
|
gboolean mm_shared_cinterion_disable_location_gathering_finish (MMIfaceModemLocation *self,
|
||||||
GAsyncResult *res,
|
GAsyncResult *res,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
void mm_common_cinterion_peek_parent_location_interface (MMIfaceModemLocation *iface);
|
#endif /* MM_SHARED_CINTERION_H */
|
||||||
|
|
||||||
#endif /* MM_COMMON_CINTERION_H */
|
|
Reference in New Issue
Block a user