diff options
-rw-r--r-- | plugins/Makefile.am | 4 | ||||
-rw-r--r-- | plugins/cinterion/mm-broadband-modem-cinterion.c | 43 | ||||
-rw-r--r-- | plugins/cinterion/mm-broadband-modem-qmi-cinterion.c | 34 | ||||
-rw-r--r-- | plugins/cinterion/mm-shared-cinterion.c (renamed from plugins/cinterion/mm-common-cinterion.c) | 498 | ||||
-rw-r--r-- | plugins/cinterion/mm-shared-cinterion.h (renamed from plugins/cinterion/mm-common-cinterion.h) | 46 |
5 files changed, 343 insertions, 282 deletions
diff --git a/plugins/Makefile.am b/plugins/Makefile.am index c8b2501a..9b9de477 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -650,8 +650,8 @@ pkglib_LTLIBRARIES += libmm-plugin-cinterion.la libmm_plugin_cinterion_la_SOURCES = \ cinterion/mm-plugin-cinterion.c \ cinterion/mm-plugin-cinterion.h \ - cinterion/mm-common-cinterion.c \ - cinterion/mm-common-cinterion.h \ + cinterion/mm-shared-cinterion.c \ + cinterion/mm-shared-cinterion.h \ cinterion/mm-broadband-modem-cinterion.c \ cinterion/mm-broadband-modem-cinterion.h \ cinterion/mm-broadband-bearer-cinterion.c \ diff --git a/plugins/cinterion/mm-broadband-modem-cinterion.c b/plugins/cinterion/mm-broadband-modem-cinterion.c index 64c5e08a..0ca083ed 100644 --- a/plugins/cinterion/mm-broadband-modem-cinterion.c +++ b/plugins/cinterion/mm-broadband-modem-cinterion.c @@ -37,22 +37,25 @@ #include "mm-base-modem-at.h" #include "mm-broadband-modem-cinterion.h" #include "mm-modem-helpers-cinterion.h" -#include "mm-common-cinterion.h" +#include "mm-shared-cinterion.h" #include "mm-broadband-bearer-cinterion.h" -static void iface_modem_init (MMIfaceModem *iface); -static void iface_modem_3gpp_init (MMIfaceModem3gpp *iface); +static void iface_modem_init (MMIfaceModem *iface); +static void iface_modem_3gpp_init (MMIfaceModem3gpp *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 MMIfaceModem3gpp *iface_modem_3gpp_parent; +static MMIfaceModem *iface_modem_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_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_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 { FEATURE_SUPPORT_UNKNOWN, @@ -1905,14 +1908,26 @@ iface_modem_messaging_init (MMIfaceModemMessaging *iface) static void 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_finish = mm_common_cinterion_location_load_capabilities_finish; - iface->enable_location_gathering = mm_common_cinterion_enable_location_gathering; - iface->enable_location_gathering_finish = mm_common_cinterion_enable_location_gathering_finish; - iface->disable_location_gathering = mm_common_cinterion_disable_location_gathering; - iface->disable_location_gathering_finish = mm_common_cinterion_disable_location_gathering_finish; + iface->load_capabilities = mm_shared_cinterion_location_load_capabilities; + iface->load_capabilities_finish = mm_shared_cinterion_location_load_capabilities_finish; + iface->enable_location_gathering = mm_shared_cinterion_enable_location_gathering; + iface->enable_location_gathering_finish = mm_shared_cinterion_enable_location_gathering_finish; + iface->disable_location_gathering = mm_shared_cinterion_disable_location_gathering; + 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 diff --git a/plugins/cinterion/mm-broadband-modem-qmi-cinterion.c b/plugins/cinterion/mm-broadband-modem-qmi-cinterion.c index 2410d091..6048ccac 100644 --- a/plugins/cinterion/mm-broadband-modem-qmi-cinterion.c +++ b/plugins/cinterion/mm-broadband-modem-qmi-cinterion.c @@ -27,12 +27,16 @@ #include "mm-errors-types.h" #include "mm-iface-modem-location.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 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_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 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_shared_cinterion_location_load_capabilities; + iface->load_capabilities_finish = mm_shared_cinterion_location_load_capabilities_finish; + iface->enable_location_gathering = mm_shared_cinterion_enable_location_gathering; + iface->enable_location_gathering_finish = mm_shared_cinterion_enable_location_gathering_finish; + iface->disable_location_gathering = mm_shared_cinterion_disable_location_gathering; + 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; +} - iface->load_capabilities = mm_common_cinterion_location_load_capabilities; - iface->load_capabilities_finish = mm_common_cinterion_location_load_capabilities_finish; - iface->enable_location_gathering = mm_common_cinterion_enable_location_gathering; - iface->enable_location_gathering_finish = mm_common_cinterion_enable_location_gathering_finish; - iface->disable_location_gathering = mm_common_cinterion_disable_location_gathering; - iface->disable_location_gathering_finish = mm_common_cinterion_disable_location_gathering_finish; +static void +shared_cinterion_init (MMSharedCinterion *iface) +{ + iface->peek_parent_location_interface = peek_parent_location_interface; } static void diff --git a/plugins/cinterion/mm-common-cinterion.c b/plugins/cinterion/mm-shared-cinterion.c index 67bc5b3b..ab95140a 100644 --- a/plugins/cinterion/mm-common-cinterion.c +++ b/plugins/cinterion/mm-shared-cinterion.c @@ -11,21 +11,29 @@ * GNU General Public License for more details: * * 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 "mm-base-modem-at.h" -#include "mm-log.h" +#include <config.h> -static MMIfaceModemLocation *iface_modem_location_parent; +#include <glib-object.h> +#include <gio/gio.h> -/*****************************************************************************/ +#define _LIBMM_INSIDE_MM +#include <libmm-glib.h> -#define CINTERION_LOCATION_CONTEXT_TAG "cinterion-location-tag" -static GQuark cinterion_location_context_quark; +#include "mm-log.h" +#include "mm-iface-modem.h" +#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 PRIVATE_TAG "shared-cinterion-private-tag" +static GQuark private_quark; typedef enum { FEATURE_SUPPORT_UNKNOWN, @@ -34,42 +42,44 @@ typedef enum { } FeatureSupport; typedef struct { - MMModemLocationSource enabled_sources; - FeatureSupport sgpss_support; - FeatureSupport sgpsc_support; -} LocationContext; + MMIfaceModemLocation *iface_modem_location_parent; + MMModemLocationSource supported_sources; + MMModemLocationSource enabled_sources; + FeatureSupport sgpss_support; + FeatureSupport sgpsc_support; +} Private; static void -location_context_free (LocationContext *ctx) +private_free (Private *ctx) { - g_slice_free (LocationContext, ctx); + g_slice_free (Private, ctx); } -static LocationContext * -get_location_context (MMBaseModem *self) +static Private * +get_private (MMSharedCinterion *self) { - LocationContext *ctx; - - if (G_UNLIKELY (!cinterion_location_context_quark)) - cinterion_location_context_quark = (g_quark_from_static_string ( - CINTERION_LOCATION_CONTEXT_TAG)); - - ctx = g_object_get_qdata (G_OBJECT (self), cinterion_location_context_quark); - if (!ctx) { - /* Create context and keep it as object data */ - 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 ( - G_OBJECT (self), - cinterion_location_context_quark, - ctx, - (GDestroyNotify)location_context_free); + Private *priv; + + if (G_UNLIKELY (!private_quark)) + private_quark = (g_quark_from_static_string (PRIVATE_TAG)); + + priv = g_object_get_qdata (G_OBJECT (self), private_quark); + if (!priv) { + priv = g_slice_new (Private); + + priv->supported_sources = MM_MODEM_LOCATION_SOURCE_NONE; + priv->enabled_sources = MM_MODEM_LOCATION_SOURCE_NONE; + priv->sgpss_support = FEATURE_SUPPORT_UNKNOWN; + priv->sgpsc_support = FEATURE_SUPPORT_UNKNOWN; + + /* 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) */ -typedef struct { - MMModemLocationSource sources; -} LoadCapabilitiesContext; - -static void -load_capabilities_context_free (LoadCapabilitiesContext *ctx) -{ - g_slice_free (LoadCapabilitiesContext, ctx); -} - MMModemLocationSource -mm_common_cinterion_location_load_capabilities_finish (MMIfaceModemLocation *self, +mm_shared_cinterion_location_load_capabilities_finish (MMIfaceModemLocation *self, GAsyncResult *res, GError **error) { @@ -140,14 +140,15 @@ sgpsc_test_ready (MMBaseModem *self, GAsyncResult *res, 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)) - location_ctx->sgpsc_support = FEATURE_NOT_SUPPORTED; + priv->sgpsc_support = FEATURE_NOT_SUPPORTED; else { /* ^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 * maybe ModemManager got rebooted and it was left enabled before. We'll * make sure that it is disabled when we initialize the modem. */ @@ -164,18 +165,19 @@ sgpss_test_ready (MMBaseModem *self, GAsyncResult *res, 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)) - location_ctx->sgpss_support = FEATURE_NOT_SUPPORTED; + priv->sgpss_support = FEATURE_NOT_SUPPORTED; else { /* ^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 * 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 * maybe ModemManager got rebooted and it was left enabled before. We'll @@ -189,32 +191,43 @@ sgpss_test_ready (MMBaseModem *self, static void probe_gps_features (GTask *task) { - LoadCapabilitiesContext *ctx; - MMBaseModem *self; - LocationContext *location_ctx; + MMSharedCinterion *self; + MMModemLocationSource sources; + Private *priv; - ctx = (LoadCapabilitiesContext *) g_task_get_task_data (task); - self = MM_BASE_MODEM (g_task_get_source_object (task)); - location_ctx = get_location_context (self); + self = MM_SHARED_CINTERION (g_task_get_source_object (task)); + priv = get_private (self); /* Need to check if SGPSS supported... */ - if (location_ctx->sgpss_support == FEATURE_SUPPORT_UNKNOWN) { - mm_base_modem_at_command (self, "AT^SGPSS=?", 3, TRUE, (GAsyncReadyCallback) sgpss_test_ready, task); + if (priv->sgpss_support == FEATURE_SUPPORT_UNKNOWN) { + mm_base_modem_at_command (MM_BASE_MODEM (self), "AT^SGPSS=?", 3, TRUE, (GAsyncReadyCallback) sgpss_test_ready, task); return; } /* Need to check if SGPSC supported... */ - if (location_ctx->sgpsc_support == FEATURE_SUPPORT_UNKNOWN) { - mm_base_modem_at_command (self, "AT^SGPSC=?", 3, TRUE, (GAsyncReadyCallback) sgpsc_test_ready, task); + if (priv->sgpsc_support == FEATURE_SUPPORT_UNKNOWN) { + mm_base_modem_at_command (MM_BASE_MODEM (self), "AT^SGPSC=?", 3, TRUE, (GAsyncReadyCallback) sgpsc_test_ready, task); return; } - /* All GPS features probed, check if GPS supported */ - if (location_ctx->sgpss_support == FEATURE_SUPPORTED || location_ctx->sgpsc_support == FEATURE_SUPPORTED) { + /* All GPS features probed */ + + /* 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"); - ctx->sources |= (MM_MODEM_LOCATION_SOURCE_GPS_NMEA | - MM_MODEM_LOCATION_SOURCE_GPS_RAW | - MM_MODEM_LOCATION_SOURCE_GPS_UNMANAGED); + + /* We only flag as supported by this implementation those sources not already + * 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 */ 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 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); } @@ -233,12 +246,13 @@ parent_load_capabilities_ready (MMIfaceModemLocation *self, GAsyncResult *res, GTask *task) { - LoadCapabilitiesContext *ctx; - GError *error = NULL; + MMModemLocationSource sources; + 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) { g_task_return_error (task, error); g_object_unref (task); @@ -248,34 +262,36 @@ parent_load_capabilities_ready (MMIfaceModemLocation *self, /* 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))) { 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); return; } + /* Cache sources supported by the parent */ + g_task_set_task_data (task, GUINT_TO_POINTER (sources), NULL); + /* Probe all GPS features */ probe_gps_features (task); } void -mm_common_cinterion_location_load_capabilities (MMIfaceModemLocation *self, +mm_shared_cinterion_location_load_capabilities (MMIfaceModemLocation *self, GAsyncReadyCallback callback, gpointer user_data) { - GTask *task; - LoadCapabilitiesContext *ctx; + Private *priv; + GTask *task; + priv = get_private (MM_SHARED_CINTERION (self)); task = g_task_new (self, NULL, callback, user_data); - ctx = g_slice_new0 (LoadCapabilitiesContext); - ctx->sources = MM_MODEM_LOCATION_SOURCE_NONE; - g_task_set_task_data (task, ctx, (GDestroyNotify) load_capabilities_context_free); + g_assert (priv->iface_modem_location_parent); + g_assert (priv->iface_modem_location_parent->load_capabilities); + g_assert (priv->iface_modem_location_parent->load_capabilities_finish); - /* Chain up parent's setup */ - iface_modem_location_parent->load_capabilities ( - self, - (GAsyncReadyCallback)parent_load_capabilities_ready, - task); + priv->iface_modem_location_parent->load_capabilities (self, + (GAsyncReadyCallback)parent_load_capabilities_ready, + task); } /*****************************************************************************/ @@ -308,7 +324,7 @@ disable_location_gathering_context_free (DisableLocationGatheringContext *ctx) } gboolean -mm_common_cinterion_disable_location_gathering_finish (MMIfaceModemLocation *self, +mm_shared_cinterion_disable_location_gathering_finish (MMIfaceModemLocation *self, GAsyncResult *res, GError **error) { @@ -360,16 +376,16 @@ static void disable_location_gathering_context_gps_step (GTask *task) { DisableLocationGatheringContext *ctx; - MMBaseModem *self; - LocationContext *location_ctx; + MMSharedCinterion *self; + 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); - location_ctx = get_location_context (MM_BASE_MODEM (self)); /* Only one of both supported */ - g_assert ((location_ctx->sgpss_support == FEATURE_SUPPORTED) || (location_ctx->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)); + g_assert (!((priv->sgpss_support == FEATURE_SUPPORTED) && (priv->sgpsc_support == FEATURE_SUPPORTED))); switch (ctx->gps_step) { case DISABLE_LOCATION_GATHERING_GPS_STEP_FIRST: @@ -377,7 +393,7 @@ disable_location_gathering_context_gps_step (GTask *task) /* Fall down to next step */ 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), "AT^SGPSS=0", 3, FALSE, (GAsyncReadyCallback) disable_sgpss_ready, task); @@ -387,7 +403,7 @@ disable_location_gathering_context_gps_step (GTask *task) /* Fall down to next step */ case DISABLE_LOCATION_GATHERING_GPS_STEP_SGPSC_ENGINE: - if (location_ctx->sgpsc_support == FEATURE_SUPPORTED) { + if (priv->sgpsc_support == FEATURE_SUPPORTED) { /* Engine off */ mm_base_modem_at_command (MM_BASE_MODEM (self), "AT^SGPSC=\"Engine\",\"0\"", @@ -398,7 +414,7 @@ disable_location_gathering_context_gps_step (GTask *task) /* Fall down to next step */ case DISABLE_LOCATION_GATHERING_GPS_STEP_SGPSC_ANTENNA: - if (location_ctx->sgpsc_support == FEATURE_SUPPORTED) { + if (priv->sgpsc_support == FEATURE_SUPPORTED) { /* Antenna off */ mm_base_modem_at_command (MM_BASE_MODEM (self), "AT^SGPSC=\"Power/Antenna\",\"off\"", @@ -409,7 +425,7 @@ disable_location_gathering_context_gps_step (GTask *task) /* Fall down to next step */ case DISABLE_LOCATION_GATHERING_GPS_STEP_SGPSC_OUTPUT: - if (location_ctx->sgpsc_support == FEATURE_SUPPORTED) { + if (priv->sgpsc_support == FEATURE_SUPPORTED) { /* NMEA output off */ mm_base_modem_at_command (MM_BASE_MODEM (self), "AT^SGPSC=\"NMEA/Output\",\"off\"", @@ -425,7 +441,7 @@ disable_location_gathering_context_gps_step (GTask *task) MMPortSerialGps *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) 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) { g_task_return_error (task, ctx->sgpsc_error); g_clear_error (&ctx->sgpsc_error); - } else + } else { + priv->enabled_sources &= ~ctx->source; g_task_return_boolean (task, TRUE); + } g_object_unref (task); 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 parent_disable_location_gathering_ready (MMIfaceModemLocation *self, GAsyncResult *res, GTask *task) { - DisableLocationGatheringContext *ctx; - GError *error = NULL; - - ctx = (DisableLocationGatheringContext *) g_task_get_task_data (task); - - if (!iface_modem_location_parent->disable_location_gathering_finish (self, res, &error)) { - /* Errors when disabling non-GPS sources are fatal */ - 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_object_unref (task); - return; - } + GError *error; + Private *priv; - /* Ignore errors when disabling GPS, we can try with AT commands */ - g_error_free (error); - } + priv = get_private (MM_SHARED_CINTERION (self)); - internal_disable_location_gathering (task); + g_assert (priv->iface_modem_location_parent); + if (!priv->iface_modem_location_parent->disable_location_gathering_finish (self, res, &error)) + g_task_return_error (task, error); + else + g_task_return_boolean (task, TRUE); + g_object_unref (task); } void -mm_common_cinterion_disable_location_gathering (MMIfaceModemLocation *self, +mm_shared_cinterion_disable_location_gathering (MMIfaceModemLocation *self, MMModemLocationSource source, GAsyncReadyCallback callback, gpointer user_data) { - GTask *task; DisableLocationGatheringContext *ctx; + MMModemLocationSource enabled_sources; + Private *priv; + GTask *task; task = g_task_new (self, NULL, callback, user_data); - 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); + priv = get_private (MM_SHARED_CINTERION (self)); + g_assert (priv->iface_modem_location_parent); + + /* Only consider request if it applies to one of the sources we are + * supporting, otherwise run parent disable */ + if (!(priv->supported_sources & source)) { + /* 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, + (GAsyncReadyCallback)parent_disable_location_gathering_ready, + task); + return; + } + /* Otherwise, we're done */ + g_task_return_boolean (task, TRUE); + g_object_unref (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)); - /* Chain up parent's gathering enable */ - if (iface_modem_location_parent->disable_location_gathering) { - iface_modem_location_parent->disable_location_gathering ( - self, - source, - (GAsyncReadyCallback)parent_disable_location_gathering_ready, - task); + /* 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; } - internal_disable_location_gathering (task); + /* 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 -mm_common_cinterion_enable_location_gathering_finish (MMIfaceModemLocation *self, +mm_shared_cinterion_enable_location_gathering_finish (MMIfaceModemLocation *self, GAsyncResult *res, GError **error) { @@ -622,16 +629,16 @@ static void enable_location_gathering_context_gps_step (GTask *task) { EnableLocationGatheringContext *ctx; - MMBaseModem *self; - LocationContext *location_ctx; + MMSharedCinterion *self; + 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); - location_ctx = get_location_context (MM_BASE_MODEM (self)); /* Only one of both supported */ - g_assert ((location_ctx->sgpss_support == FEATURE_SUPPORTED) || (location_ctx->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)); + g_assert (!((priv->sgpss_support == FEATURE_SUPPORTED) && (priv->sgpsc_support == FEATURE_SUPPORTED))); switch (ctx->gps_step) { case ENABLE_LOCATION_GATHERING_GPS_STEP_FIRST: @@ -639,7 +646,7 @@ enable_location_gathering_context_gps_step (GTask *task) /* Fall down to next step */ 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), "AT^SGPSS=4", 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 */ case ENABLE_LOCATION_GATHERING_GPS_STEP_SGPSC_OUTPUT: - if (location_ctx->sgpsc_support == FEATURE_SUPPORTED) { + if (priv->sgpsc_support == FEATURE_SUPPORTED) { /* NMEA output off */ mm_base_modem_at_command (MM_BASE_MODEM (self), "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: - if (location_ctx->sgpsc_support == FEATURE_SUPPORTED) { + if (priv->sgpsc_support == FEATURE_SUPPORTED) { /* Antenna off */ mm_base_modem_at_command (MM_BASE_MODEM (self), "AT^SGPSC=\"Power/Antenna\",\"on\"", @@ -672,7 +679,7 @@ enable_location_gathering_context_gps_step (GTask *task) /* Fall down to next step */ case ENABLE_LOCATION_GATHERING_GPS_STEP_SGPSC_ENGINE: - if (location_ctx->sgpsc_support == FEATURE_SUPPORTED) { + if (priv->sgpsc_support == FEATURE_SUPPORTED) { /* Engine off */ mm_base_modem_at_command (MM_BASE_MODEM (self), "AT^SGPSC=\"Engine\",\"1\"", @@ -689,7 +696,7 @@ enable_location_gathering_context_gps_step (GTask *task) MMPortSerialGps *gps_port; 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 (error) g_task_return_error (task, error); @@ -702,6 +709,7 @@ enable_location_gathering_context_gps_step (GTask *task) } /* Success */ + priv->enabled_sources |= ctx->source; g_task_return_boolean (task, TRUE); g_object_unref (task); return; @@ -709,94 +717,96 @@ enable_location_gathering_context_gps_step (GTask *task) } 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 parent_enable_location_gathering_ready (MMIfaceModemLocation *self, GAsyncResult *res, GTask *task) { - EnableLocationGatheringContext *ctx; - GError *error = NULL; + GError *error; + Private *priv; - ctx = (EnableLocationGatheringContext *) g_task_get_task_data (task); - - if (!iface_modem_location_parent->enable_location_gathering_finish (self, res, &error)) { - /* Errors when enabling non-GPS sources are fatal */ - 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_object_unref (task); - return; - } + priv = get_private (MM_SHARED_CINTERION (self)); - /* Ignore errors when enabling GPS, we can try with AT commands */ - g_error_free (error); - } - - /* Now our own enabling */ - internal_enable_location_gathering (task); + g_assert (priv->iface_modem_location_parent); + if (!priv->iface_modem_location_parent->enable_location_gathering_finish (self, res, &error)) + g_task_return_error (task, error); + else + g_task_return_boolean (task, TRUE); + g_object_unref (task); } void -mm_common_cinterion_enable_location_gathering (MMIfaceModemLocation *self, - MMModemLocationSource source, - GAsyncReadyCallback callback, - gpointer user_data) +mm_shared_cinterion_enable_location_gathering (MMIfaceModemLocation *self, + MMModemLocationSource source, + GAsyncReadyCallback callback, + gpointer user_data) { + Private *priv; GTask *task; EnableLocationGatheringContext *ctx; + 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->source = source; ctx->gps_step = ENABLE_LOCATION_GATHERING_GPS_STEP_FIRST; g_task_set_task_data (task, ctx, (GDestroyNotify) enable_location_gathering_context_free); - /* Chain up parent's gathering enable */ - iface_modem_location_parent->enable_location_gathering ( - self, - source, - (GAsyncReadyCallback)parent_enable_location_gathering_ready, - task); + enable_location_gathering_context_gps_step (task); } /*****************************************************************************/ -void -mm_common_cinterion_peek_parent_location_interface (MMIfaceModemLocation *iface) +static void +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; } diff --git a/plugins/cinterion/mm-common-cinterion.h b/plugins/cinterion/mm-shared-cinterion.h index 47a4a97d..310a5383 100644 --- a/plugins/cinterion/mm-common-cinterion.h +++ b/plugins/cinterion/mm-shared-cinterion.h @@ -11,39 +11,59 @@ * GNU General Public License for more details: * * 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 -#define MM_COMMON_CINTERION_H +#ifndef MM_SHARED_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-iface-modem.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, 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, GError **error); -void mm_common_cinterion_enable_location_gathering (MMIfaceModemLocation *self, +void mm_shared_cinterion_enable_location_gathering (MMIfaceModemLocation *self, MMModemLocationSource source, GAsyncReadyCallback callback, 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, GError **error); -void mm_common_cinterion_disable_location_gathering (MMIfaceModemLocation *self, +void mm_shared_cinterion_disable_location_gathering (MMIfaceModemLocation *self, MMModemLocationSource source, GAsyncReadyCallback callback, 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, GError **error); -void mm_common_cinterion_peek_parent_location_interface (MMIfaceModemLocation *iface); - -#endif /* MM_COMMON_CINTERION_H */ +#endif /* MM_SHARED_CINTERION_H */ |