aboutsummaryrefslogtreecommitdiff
path: root/plugins/cinterion/mm-common-cinterion.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/cinterion/mm-common-cinterion.c')
-rw-r--r--plugins/cinterion/mm-common-cinterion.c802
1 files changed, 0 insertions, 802 deletions
diff --git a/plugins/cinterion/mm-common-cinterion.c b/plugins/cinterion/mm-common-cinterion.c
deleted file mode 100644
index 67bc5b3b..00000000
--- a/plugins/cinterion/mm-common-cinterion.c
+++ /dev/null
@@ -1,802 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details:
- *
- * Copyright (C) 2014 Ammonit Measurement GmbH
- * Author: Aleksander Morgado <aleksander@aleksander.es>
- */
-
-#include "mm-common-cinterion.h"
-#include "mm-base-modem-at.h"
-#include "mm-log.h"
-
-static MMIfaceModemLocation *iface_modem_location_parent;
-
-/*****************************************************************************/
-
-#define CINTERION_LOCATION_CONTEXT_TAG "cinterion-location-tag"
-static GQuark cinterion_location_context_quark;
-
-/*****************************************************************************/
-
-typedef enum {
- FEATURE_SUPPORT_UNKNOWN,
- FEATURE_NOT_SUPPORTED,
- FEATURE_SUPPORTED,
-} FeatureSupport;
-
-typedef struct {
- MMModemLocationSource enabled_sources;
- FeatureSupport sgpss_support;
- FeatureSupport sgpsc_support;
-} LocationContext;
-
-static void
-location_context_free (LocationContext *ctx)
-{
- g_slice_free (LocationContext, ctx);
-}
-
-static LocationContext *
-get_location_context (MMBaseModem *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);
- }
-
- return ctx;
-}
-
-/*****************************************************************************/
-/* GPS trace received */
-
-static void
-trace_received (MMPortSerialGps *port,
- const gchar *trace,
- MMIfaceModemLocation *self)
-{
- /* Helper to debug GPS location related issues. Don't depend on a real GPS
- * fix for debugging, just use some random values to update */
-#if 0
- if (g_str_has_prefix (trace, "$GPGGA")) {
- GString *str;
- GDateTime *now;
-
- now = g_date_time_new_now_utc ();
- str = g_string_new ("");
- g_string_append_printf (str,
- "$GPGGA,%02u%02u%02u,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47",
- g_date_time_get_hour (now),
- g_date_time_get_minute (now),
- g_date_time_get_second (now));
- mm_iface_modem_location_gps_update (self, str->str);
- g_string_free (str, TRUE);
- g_date_time_unref (now);
- return;
- }
-#endif
-
- mm_iface_modem_location_gps_update (self, trace);
-}
-
-/*****************************************************************************/
-/* 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,
- GAsyncResult *res,
- GError **error)
-{
- GError *inner_error = NULL;
- gssize aux;
-
- aux = g_task_propagate_int (G_TASK (res), &inner_error);
- if (inner_error) {
- g_propagate_error (error, inner_error);
- return MM_MODEM_LOCATION_SOURCE_NONE;
- }
- return (MMModemLocationSource) aux;
-}
-
-static void probe_gps_features (GTask *task);
-
-static void
-sgpsc_test_ready (MMBaseModem *self,
- GAsyncResult *res,
- GTask *task)
-{
- LocationContext *location_ctx;
-
- location_ctx = get_location_context (self);
- if (!mm_base_modem_at_command_finish (self, res, NULL))
- location_ctx->sgpsc_support = FEATURE_NOT_SUPPORTED;
- else {
- /* ^SGPSC supported! */
- location_ctx->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. */
- mm_base_modem_at_command (MM_BASE_MODEM (self), "AT^SGPSC=\"Engine\",\"0\"", 3, FALSE, NULL, NULL);
- mm_base_modem_at_command (MM_BASE_MODEM (self), "AT^SGPSC=\"Power/Antenna\",\"off\"", 3, FALSE, NULL, NULL);
- mm_base_modem_at_command (MM_BASE_MODEM (self), "AT^SGPSC=\"NMEA/Output\",\"off\"", 3, FALSE, NULL, NULL);
- }
-
- probe_gps_features (task);
-}
-
-static void
-sgpss_test_ready (MMBaseModem *self,
- GAsyncResult *res,
- GTask *task)
-{
- LocationContext *location_ctx;
-
- location_ctx = get_location_context (self);
- if (!mm_base_modem_at_command_finish (self, res, NULL))
- location_ctx->sgpss_support = FEATURE_NOT_SUPPORTED;
- else {
- /* ^SGPSS supported! */
- location_ctx->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;
-
- /* 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. */
- mm_base_modem_at_command (MM_BASE_MODEM (self), "AT^SGPSS=0", 3, FALSE, NULL, NULL);
- }
-
- probe_gps_features (task);
-}
-
-static void
-probe_gps_features (GTask *task)
-{
- LoadCapabilitiesContext *ctx;
- MMBaseModem *self;
- LocationContext *location_ctx;
-
- ctx = (LoadCapabilitiesContext *) g_task_get_task_data (task);
- self = MM_BASE_MODEM (g_task_get_source_object (task));
- location_ctx = get_location_context (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);
- 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);
- return;
- }
-
- /* All GPS features probed, check if GPS supported */
- if (location_ctx->sgpss_support == FEATURE_SUPPORTED || location_ctx->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);
-
- /* 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)),
- (MMPortSerialGpsTraceFn)trace_received,
- self,
- NULL);
- } else
- mm_dbg ("No GPS command supported: no GPS capabilities");
-
- g_task_return_int (task, (gssize) ctx->sources);
- g_object_unref (task);
-}
-
-static void
-parent_load_capabilities_ready (MMIfaceModemLocation *self,
- GAsyncResult *res,
- GTask *task)
-{
- LoadCapabilitiesContext *ctx;
- GError *error = NULL;
-
- ctx = (LoadCapabilitiesContext *) g_task_get_task_data (task);
-
- ctx->sources = iface_modem_location_parent->load_capabilities_finish (self, res, &error);
- if (error) {
- g_task_return_error (task, error);
- g_object_unref (task);
- return;
- }
-
- /* 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_object_unref (task);
- return;
- }
-
- /* Probe all GPS features */
- probe_gps_features (task);
-}
-
-void
-mm_common_cinterion_location_load_capabilities (MMIfaceModemLocation *self,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GTask *task;
- LoadCapabilitiesContext *ctx;
-
- 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);
-
- /* Chain up parent's setup */
- iface_modem_location_parent->load_capabilities (
- self,
- (GAsyncReadyCallback)parent_load_capabilities_ready,
- task);
-}
-
-/*****************************************************************************/
-/* Disable location gathering (Location interface) */
-
-typedef enum {
- DISABLE_LOCATION_GATHERING_GPS_STEP_FIRST,
- DISABLE_LOCATION_GATHERING_GPS_STEP_SGPSS,
- DISABLE_LOCATION_GATHERING_GPS_STEP_SGPSC_ENGINE,
- DISABLE_LOCATION_GATHERING_GPS_STEP_SGPSC_ANTENNA,
- DISABLE_LOCATION_GATHERING_GPS_STEP_SGPSC_OUTPUT,
- DISABLE_LOCATION_GATHERING_GPS_STEP_LAST,
-} DisableLocationGatheringGpsStep;
-
-typedef struct {
- MMModemLocationSource source;
- DisableLocationGatheringGpsStep gps_step;
- GError *sgpss_error;
- GError *sgpsc_error;
-} DisableLocationGatheringContext;
-
-static void
-disable_location_gathering_context_free (DisableLocationGatheringContext *ctx)
-{
- if (ctx->sgpss_error)
- g_error_free (ctx->sgpss_error);
- if (ctx->sgpsc_error)
- g_error_free (ctx->sgpsc_error);
- g_slice_free (DisableLocationGatheringContext, ctx);
-}
-
-gboolean
-mm_common_cinterion_disable_location_gathering_finish (MMIfaceModemLocation *self,
- GAsyncResult *res,
- GError **error)
-{
- return g_task_propagate_boolean (G_TASK (res), error);
-}
-
-static void disable_location_gathering_context_gps_step (GTask *task);
-
-static void
-disable_sgpsc_ready (MMBaseModem *self,
- GAsyncResult *res,
- GTask *task)
-{
- DisableLocationGatheringContext *ctx;
- GError *error = NULL;
-
- ctx = (DisableLocationGatheringContext *) g_task_get_task_data (task);
-
- /* Store error, if not one available already, and continue */
- if (!mm_base_modem_at_command_finish (self, res, &error)) {
- if (!ctx->sgpsc_error)
- ctx->sgpsc_error = error;
- else
- g_error_free (error);
- }
-
- ctx->gps_step++;
- disable_location_gathering_context_gps_step (task);
-}
-
-static void
-disable_sgpss_ready (MMBaseModem *self,
- GAsyncResult *res,
- GTask *task)
-{
- DisableLocationGatheringContext *ctx;
-
- ctx = (DisableLocationGatheringContext *) g_task_get_task_data (task);
-
- /* Store error, if any, and continue */
- g_assert (!ctx->sgpss_error);
- mm_base_modem_at_command_finish (self, res, &ctx->sgpss_error);
-
- ctx->gps_step++;
- disable_location_gathering_context_gps_step (task);
-}
-
-static void
-disable_location_gathering_context_gps_step (GTask *task)
-{
- DisableLocationGatheringContext *ctx;
- MMBaseModem *self;
- LocationContext *location_ctx;
-
- self = MM_BASE_MODEM (g_task_get_source_object (task));
- 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)));
-
- switch (ctx->gps_step) {
- case DISABLE_LOCATION_GATHERING_GPS_STEP_FIRST:
- ctx->gps_step++;
- /* Fall down to next step */
-
- case DISABLE_LOCATION_GATHERING_GPS_STEP_SGPSS:
- if (location_ctx->sgpss_support == FEATURE_SUPPORTED) {
- mm_base_modem_at_command (MM_BASE_MODEM (self),
- "AT^SGPSS=0",
- 3, FALSE, (GAsyncReadyCallback) disable_sgpss_ready, task);
- return;
- }
- ctx->gps_step++;
- /* Fall down to next step */
-
- case DISABLE_LOCATION_GATHERING_GPS_STEP_SGPSC_ENGINE:
- if (location_ctx->sgpsc_support == FEATURE_SUPPORTED) {
- /* Engine off */
- mm_base_modem_at_command (MM_BASE_MODEM (self),
- "AT^SGPSC=\"Engine\",\"0\"",
- 3, FALSE, (GAsyncReadyCallback) disable_sgpsc_ready, task);
- return;
- }
- ctx->gps_step++;
- /* Fall down to next step */
-
- case DISABLE_LOCATION_GATHERING_GPS_STEP_SGPSC_ANTENNA:
- if (location_ctx->sgpsc_support == FEATURE_SUPPORTED) {
- /* Antenna off */
- mm_base_modem_at_command (MM_BASE_MODEM (self),
- "AT^SGPSC=\"Power/Antenna\",\"off\"",
- 3, FALSE, (GAsyncReadyCallback) disable_sgpsc_ready, task);
- return;
- }
- ctx->gps_step++;
- /* Fall down to next step */
-
- case DISABLE_LOCATION_GATHERING_GPS_STEP_SGPSC_OUTPUT:
- if (location_ctx->sgpsc_support == FEATURE_SUPPORTED) {
- /* NMEA output off */
- mm_base_modem_at_command (MM_BASE_MODEM (self),
- "AT^SGPSC=\"NMEA/Output\",\"off\"",
- 3, FALSE, (GAsyncReadyCallback) disable_sgpsc_ready, task);
- return;
- }
- ctx->gps_step++;
- /* Fall down to next step */
-
- case DISABLE_LOCATION_GATHERING_GPS_STEP_LAST:
- /* Only use the GPS port in NMEA/RAW setups */
- if (ctx->source & (MM_MODEM_LOCATION_SOURCE_GPS_NMEA | MM_MODEM_LOCATION_SOURCE_GPS_RAW)) {
- 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);
- if (gps_port)
- mm_port_serial_close (MM_PORT_SERIAL (gps_port));
- }
-
- if (ctx->sgpss_error) {
- g_task_return_error (task, ctx->sgpss_error);
- g_clear_error (&ctx->sgpss_error);
- } else if (ctx->sgpsc_error) {
- g_task_return_error (task, ctx->sgpsc_error);
- g_clear_error (&ctx->sgpsc_error);
- } else
- 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;
- }
-
- /* Ignore errors when disabling GPS, we can try with AT commands */
- g_error_free (error);
- }
-
- internal_disable_location_gathering (task);
-}
-
-void
-mm_common_cinterion_disable_location_gathering (MMIfaceModemLocation *self,
- MMModemLocationSource source,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GTask *task;
- DisableLocationGatheringContext *ctx;
-
- 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);
-
- /* 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);
- return;
- }
-
- internal_disable_location_gathering (task);
-}
-
-/*****************************************************************************/
-/* Enable location gathering (Location interface) */
-
-/* We will retry the SGPSC command that enables the Engine */
-#define MAX_SGPSC_ENGINE_RETRIES 3
-
-/* Cinterion asks for 100ms some time between GPS commands, but we'll give up
- * to 2000ms before setting the Engine configuration as 100ms didn't seem always
- * enough (we would get +CME ERROR: 767 errors reported). */
-#define GPS_COMMAND_TIMEOUT_DEFAULT_MS 100
-#define GPS_COMMAND_TIMEOUT_ENGINE_MS 2000
-
-typedef enum {
- ENABLE_LOCATION_GATHERING_GPS_STEP_FIRST,
- ENABLE_LOCATION_GATHERING_GPS_STEP_SGPSS,
- ENABLE_LOCATION_GATHERING_GPS_STEP_SGPSC_OUTPUT,
- ENABLE_LOCATION_GATHERING_GPS_STEP_SGPSC_ANTENNA,
- ENABLE_LOCATION_GATHERING_GPS_STEP_SGPSC_ENGINE,
- ENABLE_LOCATION_GATHERING_GPS_STEP_LAST,
-} EnableLocationGatheringGpsStep;
-
-typedef struct {
- MMModemLocationSource source;
- EnableLocationGatheringGpsStep gps_step;
- guint sgpsc_engine_retries;
-} EnableLocationGatheringContext;
-
-static void
-enable_location_gathering_context_free (EnableLocationGatheringContext *ctx)
-{
- g_slice_free (EnableLocationGatheringContext, ctx);
-}
-
-gboolean
-mm_common_cinterion_enable_location_gathering_finish (MMIfaceModemLocation *self,
- GAsyncResult *res,
- GError **error)
-{
- return g_task_propagate_boolean (G_TASK (res), error);
-}
-
-static void enable_location_gathering_context_gps_step (GTask *task);
-
-static gboolean
-enable_location_gathering_context_gps_step_schedule_cb (GTask *task)
-{
- /* Run the scheduled step */
- enable_location_gathering_context_gps_step (task);
- return G_SOURCE_REMOVE;
-}
-
-static void
-enable_sgpsc_or_sgpss_ready (MMBaseModem *self,
- GAsyncResult *res,
- GTask *task)
-{
- EnableLocationGatheringContext *ctx;
- GError *error = NULL;
-
- ctx = (EnableLocationGatheringContext *) g_task_get_task_data (task);
-
- if (!mm_base_modem_at_command_finish (self, res, &error)) {
- /* The GPS setup may sometimes report "+CME ERROR 767" when enabling the
- * Engine; so we'll run some retries of the same command ourselves. */
- if (ctx->gps_step == ENABLE_LOCATION_GATHERING_GPS_STEP_SGPSC_ENGINE) {
- ctx->sgpsc_engine_retries++;
- mm_dbg ("GPS Engine setup failed (%u/%u)", ctx->sgpsc_engine_retries, MAX_SGPSC_ENGINE_RETRIES);
- if (ctx->sgpsc_engine_retries < MAX_SGPSC_ENGINE_RETRIES) {
- g_clear_error (&error);
- goto schedule;
- }
- }
- g_task_return_error (task, error);
- g_object_unref (task);
- return;
- }
-
- /* Go on to next step */
- ctx->gps_step++;
-
-schedule:
- g_timeout_add (ctx->gps_step == ENABLE_LOCATION_GATHERING_GPS_STEP_SGPSC_ENGINE ? GPS_COMMAND_TIMEOUT_ENGINE_MS : GPS_COMMAND_TIMEOUT_DEFAULT_MS,
- (GSourceFunc) enable_location_gathering_context_gps_step_schedule_cb, task);
-}
-
-static void
-enable_location_gathering_context_gps_step (GTask *task)
-{
- EnableLocationGatheringContext *ctx;
- MMBaseModem *self;
- LocationContext *location_ctx;
-
- self = MM_BASE_MODEM (g_task_get_source_object (task));
- 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)));
-
- switch (ctx->gps_step) {
- case ENABLE_LOCATION_GATHERING_GPS_STEP_FIRST:
- ctx->gps_step++;
- /* Fall down to next step */
-
- case ENABLE_LOCATION_GATHERING_GPS_STEP_SGPSS:
- if (location_ctx->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);
- return;
- }
- ctx->gps_step++;
- /* Fall down to next step */
-
- case ENABLE_LOCATION_GATHERING_GPS_STEP_SGPSC_OUTPUT:
- if (location_ctx->sgpsc_support == FEATURE_SUPPORTED) {
- /* NMEA output off */
- mm_base_modem_at_command (MM_BASE_MODEM (self),
- "AT^SGPSC=\"NMEA/Output\",\"on\"",
- 3, FALSE, (GAsyncReadyCallback) enable_sgpsc_or_sgpss_ready, task);
- return;
- }
- ctx->gps_step++;
- /* Fall down to next step */
-
-
- case ENABLE_LOCATION_GATHERING_GPS_STEP_SGPSC_ANTENNA:
- if (location_ctx->sgpsc_support == FEATURE_SUPPORTED) {
- /* Antenna off */
- mm_base_modem_at_command (MM_BASE_MODEM (self),
- "AT^SGPSC=\"Power/Antenna\",\"on\"",
- 3, FALSE, (GAsyncReadyCallback) enable_sgpsc_or_sgpss_ready, task);
- return;
- }
- ctx->gps_step++;
- /* Fall down to next step */
-
- case ENABLE_LOCATION_GATHERING_GPS_STEP_SGPSC_ENGINE:
- if (location_ctx->sgpsc_support == FEATURE_SUPPORTED) {
- /* Engine off */
- mm_base_modem_at_command (MM_BASE_MODEM (self),
- "AT^SGPSC=\"Engine\",\"1\"",
- 3, FALSE, (GAsyncReadyCallback) enable_sgpsc_or_sgpss_ready, task);
- return;
- }
- ctx->gps_step++;
- /* Fall down to next step */
-
- case ENABLE_LOCATION_GATHERING_GPS_STEP_LAST:
- /* Only use the GPS port in NMEA/RAW setups */
- if (ctx->source & (MM_MODEM_LOCATION_SOURCE_GPS_NMEA |
- MM_MODEM_LOCATION_SOURCE_GPS_RAW)) {
- MMPortSerialGps *gps_port;
- GError *error = NULL;
-
- gps_port = mm_base_modem_peek_port_gps (self);
- if (!gps_port || !mm_port_serial_open (MM_PORT_SERIAL (gps_port), &error)) {
- if (error)
- g_task_return_error (task, error);
- else
- g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
- "Couldn't open raw GPS serial port");
- g_object_unref (task);
- return;
- }
- }
-
- /* Success */
- g_task_return_boolean (task, TRUE);
- g_object_unref (task);
- 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
-parent_enable_location_gathering_ready (MMIfaceModemLocation *self,
- GAsyncResult *res,
- GTask *task)
-{
- EnableLocationGatheringContext *ctx;
- GError *error = NULL;
-
- 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;
- }
-
- /* 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
-mm_common_cinterion_enable_location_gathering (MMIfaceModemLocation *self,
- MMModemLocationSource source,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GTask *task;
- EnableLocationGatheringContext *ctx;
-
- task = g_task_new (self, NULL, callback, user_data);
-
- 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);
-}
-
-/*****************************************************************************/
-
-void
-mm_common_cinterion_peek_parent_location_interface (MMIfaceModemLocation *iface)
-{
- iface_modem_location_parent = g_type_interface_peek_parent (iface);
-}