aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--plugins/cinterion/mm-common-cinterion.c534
1 files changed, 350 insertions, 184 deletions
diff --git a/plugins/cinterion/mm-common-cinterion.c b/plugins/cinterion/mm-common-cinterion.c
index 6e4da70c..91af530f 100644
--- a/plugins/cinterion/mm-common-cinterion.c
+++ b/plugins/cinterion/mm-common-cinterion.c
@@ -26,8 +26,15 @@ 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;
} LocationContext;
static void
@@ -50,6 +57,7 @@ get_location_context (MMBaseModem *self)
/* 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;
g_object_set_qdata_full (
G_OBJECT (self),
@@ -61,133 +69,234 @@ get_location_context (MMBaseModem *self)
return ctx;
}
-
/*****************************************************************************/
/* 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)
+mm_common_cinterion_location_load_capabilities_finish (MMIfaceModemLocation *self,
+ GAsyncResult *res,
+ GError **error)
{
- if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
+ gssize aux;
+
+ if ((aux = g_task_propagate_int (G_TASK (res), error)) < 0)
return MM_MODEM_LOCATION_SOURCE_NONE;
- return (MMModemLocationSource) GPOINTER_TO_UINT (g_simple_async_result_get_op_res_gpointer (
- G_SIMPLE_ASYNC_RESULT (res)));
+ return (MMModemLocationSource) aux;
+}
+
+static void probe_gps_features (GTask *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
+ location_ctx->sgpss_support = FEATURE_SUPPORTED;
+ 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;
+ }
+
+ /* All GPS features probed, check if GPS supported */
+ if (location_ctx->sgpss_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);
+ } 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,
- GSimpleAsyncResult *simple)
+ GAsyncResult *res,
+ GTask *task)
{
- MMModemLocationSource sources;
- GError *error = NULL;
+ LoadCapabilitiesContext *ctx;
+ GError *error = NULL;
+
+ ctx = (LoadCapabilitiesContext *) g_task_get_task_data (task);
- sources = iface_modem_location_parent->load_capabilities_finish (self, res, &error);
+ ctx->sources = iface_modem_location_parent->load_capabilities_finish (self, res, &error);
if (error) {
- g_simple_async_result_take_error (simple, error);
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
+ 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;
}
- /* Now our own check. */
- if (mm_base_modem_peek_port_gps (MM_BASE_MODEM (self)))
- sources |= (MM_MODEM_LOCATION_SOURCE_GPS_NMEA |
- MM_MODEM_LOCATION_SOURCE_GPS_RAW |
- MM_MODEM_LOCATION_SOURCE_GPS_UNMANAGED);
-
- /* So we're done, complete */
- g_simple_async_result_set_op_res_gpointer (simple,
- GUINT_TO_POINTER (sources),
- NULL);
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
+ /* Probe all GPS features */
+ probe_gps_features (task);
}
void
mm_common_cinterion_location_load_capabilities (MMIfaceModemLocation *self,
- GAsyncReadyCallback callback,
- gpointer user_data)
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
- GSimpleAsyncResult *result;
+ GTask *task;
+ LoadCapabilitiesContext *ctx;
+
+ task = g_task_new (self, NULL, callback, user_data);
- result = g_simple_async_result_new (G_OBJECT (self),
- callback,
- user_data,
- mm_common_cinterion_location_load_capabilities);
+ 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,
- result);
+ task);
}
/*****************************************************************************/
-/* Enable/Disable location gathering (Location interface) */
+/* Disable location gathering (Location interface) */
+
+typedef enum {
+ DISABLE_LOCATION_GATHERING_GPS_STEP_FIRST,
+ DISABLE_LOCATION_GATHERING_GPS_STEP_SGPSS,
+ DISABLE_LOCATION_GATHERING_GPS_STEP_LAST,
+} DisableLocationGatheringGpsStep;
typedef struct {
- MMBaseModem *self;
- GSimpleAsyncResult *result;
- MMModemLocationSource source;
-} LocationGatheringContext;
+ MMModemLocationSource source;
+ DisableLocationGatheringGpsStep gps_step;
+ GError *sgpss_error;
+} DisableLocationGatheringContext;
static void
-location_gathering_context_complete_and_free (LocationGatheringContext *ctx)
+disable_location_gathering_context_free (DisableLocationGatheringContext *ctx)
{
- g_simple_async_result_complete_in_idle (ctx->result);
- g_object_unref (ctx->result);
- g_object_unref (ctx->self);
- g_slice_free (LocationGatheringContext, ctx);
+ if (ctx->sgpss_error)
+ g_error_free (ctx->sgpss_error);
+ g_slice_free (DisableLocationGatheringContext, ctx);
}
-/******************************/
-/* Disable location gathering */
-
gboolean
-mm_common_cinterion_disable_location_gathering_finish (MMIfaceModemLocation *self,
- GAsyncResult *res,
- GError **error)
+mm_common_cinterion_disable_location_gathering_finish (MMIfaceModemLocation *self,
+ GAsyncResult *res,
+ GError **error)
{
- return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
+ return g_task_propagate_boolean (G_TASK (res), error);
}
+static void disable_location_gathering_context_gps_step (GTask *task);
+
static void
-gps_disabled_ready (MMBaseModem *self,
- GAsyncResult *res,
- LocationGatheringContext *ctx)
+disable_sgpss_ready (MMBaseModem *self,
+ GAsyncResult *res,
+ GTask *task)
{
- GError *error = NULL;
+ DisableLocationGatheringContext *ctx;
- if (!mm_base_modem_at_command_full_finish (self, res, &error))
- g_simple_async_result_take_error (ctx->result, error);
- else
- g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
+ ctx = (DisableLocationGatheringContext *) g_task_get_task_data (task);
- /* 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;
+ /* Store error, if any, and continue */
+ g_assert (!ctx->sgpss_error);
+ mm_base_modem_at_command_finish (self, res, &ctx->sgpss_error);
- /* 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));
- }
+ ctx->gps_step++;
+ disable_location_gathering_context_gps_step (task);
+}
- location_gathering_context_complete_and_free (ctx);
+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));
+
+ 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:
+ g_assert (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;
+
+ 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
+ g_task_return_boolean (task, TRUE);
+ g_object_unref (task);
+ return;
+ }
}
static void
-internal_disable_location_gathering (LocationGatheringContext *ctx)
+internal_disable_location_gathering (GTask *task)
{
- LocationContext *location_ctx;
- gboolean stop_gps = FALSE;
+ 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 (ctx->self));
+ 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 |
@@ -201,64 +310,59 @@ internal_disable_location_gathering (LocationGatheringContext *ctx)
stop_gps = TRUE;
}
+ /* Run GPS stop sequence only if required to do so */
if (stop_gps) {
- /* We disable continuous GPS fixes */
- mm_base_modem_at_command_full (MM_BASE_MODEM (ctx->self),
- mm_base_modem_peek_best_at_port (MM_BASE_MODEM (ctx->self), NULL),
- "AT^SGPSS=0",
- 3,
- FALSE,
- FALSE, /* raw */
- NULL, /* cancellable */
- (GAsyncReadyCallback)gps_disabled_ready,
- ctx);
+ disable_location_gathering_context_gps_step (task);
return;
}
/* For any other location (e.g. 3GPP), or if still some GPS needed, just return */
- g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
- location_gathering_context_complete_and_free (ctx);
+ g_task_return_boolean (task, TRUE);
+ g_object_unref (task);
}
static void
parent_disable_location_gathering_ready (MMIfaceModemLocation *self,
- GAsyncResult *res,
- LocationGatheringContext *ctx)
+ GAsyncResult *res,
+ GTask *task)
{
- GError *error = NULL;
+ 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)) {
- if (ctx->source & (MM_MODEM_LOCATION_SOURCE_GPS_NMEA |
- MM_MODEM_LOCATION_SOURCE_GPS_RAW |
- MM_MODEM_LOCATION_SOURCE_GPS_UNMANAGED)) {
- /* Ignore errors when disabling GPS, we can try with AT commands */
- g_error_free (error);
- } else {
- /* Fatal */
- g_simple_async_result_take_error (ctx->result, error);
- location_gathering_context_complete_and_free (ctx);
+ /* 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 (ctx);
+ internal_disable_location_gathering (task);
}
void
-mm_common_cinterion_disable_location_gathering (MMIfaceModemLocation *self,
- MMModemLocationSource source,
- GAsyncReadyCallback callback,
- gpointer user_data)
+mm_common_cinterion_disable_location_gathering (MMIfaceModemLocation *self,
+ MMModemLocationSource source,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
- LocationGatheringContext *ctx;
-
- ctx = g_slice_new (LocationGatheringContext);
- ctx->self = g_object_ref (self);
- ctx->result = g_simple_async_result_new (G_OBJECT (self),
- callback,
- user_data,
- mm_common_cinterion_disable_location_gathering);
+ 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) {
@@ -266,86 +370,129 @@ mm_common_cinterion_disable_location_gathering (MMIfaceModemLocation *self,
self,
source,
(GAsyncReadyCallback)parent_disable_location_gathering_ready,
- ctx);
+ task);
return;
}
- internal_disable_location_gathering (ctx);
+ internal_disable_location_gathering (task);
}
/*****************************************************************************/
/* Enable location gathering (Location interface) */
+typedef enum {
+ ENABLE_LOCATION_GATHERING_GPS_STEP_FIRST,
+ ENABLE_LOCATION_GATHERING_GPS_STEP_SGPSS,
+ ENABLE_LOCATION_GATHERING_GPS_STEP_LAST,
+} EnableLocationGatheringGpsStep;
+
+typedef struct {
+ MMModemLocationSource source;
+ EnableLocationGatheringGpsStep gps_step;
+ gboolean sgpss_success;
+} 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)
+mm_common_cinterion_enable_location_gathering_finish (MMIfaceModemLocation *self,
+ GAsyncResult *res,
+ GError **error)
{
- return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
+ return g_task_propagate_boolean (G_TASK (res), error);
}
+static void enable_location_gathering_context_gps_step (GTask *task);
+
static void
-gps_enabled_ready (MMBaseModem *self,
- GAsyncResult *res,
- LocationGatheringContext *ctx)
+enable_sgpss_ready (MMBaseModem *self,
+ GAsyncResult *res,
+ GTask *task)
{
- GError *error = NULL;
+ EnableLocationGatheringContext *ctx;
+ GError *error = NULL;
- if (!mm_base_modem_at_command_full_finish (self, res, &error)) {
- g_simple_async_result_take_error (ctx->result, error);
- location_gathering_context_complete_and_free (ctx);
+ ctx = (EnableLocationGatheringContext *) g_task_get_task_data (task);
+
+ if (!mm_base_modem_at_command_finish (self, res, &error)) {
+ g_task_return_error (task, error);
+ g_object_unref (task);
return;
}
- /* 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;
-
- 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_simple_async_result_take_error (ctx->result, error);
- else
- g_simple_async_result_set_error (ctx->result,
- MM_CORE_ERROR,
- MM_CORE_ERROR_FAILED,
- "Couldn't open raw GPS serial port");
- } else
- g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
- } else
- g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
+ /* Flag as success with this method */
+ ctx->sgpss_success = TRUE;
- location_gathering_context_complete_and_free (ctx);
+ /* And jump to last step */
+ ctx->gps_step = ENABLE_LOCATION_GATHERING_GPS_STEP_LAST;
+ enable_location_gathering_context_gps_step (task);
}
static void
-parent_enable_location_gathering_ready (MMIfaceModemLocation *self,
- GAsyncResult *res,
- LocationGatheringContext *ctx)
+enable_location_gathering_context_gps_step (GTask *task)
{
- gboolean start_gps = FALSE;
- GError *error = NULL;
- LocationContext *location_ctx;
+ EnableLocationGatheringContext *ctx;
+ MMBaseModem *self;
+ LocationContext *location_ctx;
- if (!iface_modem_location_parent->enable_location_gathering_finish (self, res, &error)) {
+ 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));
+
+ 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:
+ g_assert (location_ctx->sgpss_support == FEATURE_SUPPORTED);
+ mm_base_modem_at_command (MM_BASE_MODEM (self),
+ "AT^SGPSS=4",
+ 3, FALSE, (GAsyncReadyCallback) enable_sgpss_ready, task);
+ return;
+
+ case ENABLE_LOCATION_GATHERING_GPS_STEP_LAST:
+ g_assert (ctx->sgpss_success);
+
+ /* Only use the GPS port in NMEA/RAW setups */
if (ctx->source & (MM_MODEM_LOCATION_SOURCE_GPS_NMEA |
- MM_MODEM_LOCATION_SOURCE_GPS_RAW |
- MM_MODEM_LOCATION_SOURCE_GPS_UNMANAGED)) {
- /* Ignore errors when enabling GPS, we can try with AT commands */
- g_error_free (error);
- } else {
- /* Fatal */
- g_simple_async_result_take_error (ctx->result, error);
- location_gathering_context_complete_and_free (ctx);
- return;
+ 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;
}
+}
- /* Now our own enabling */
+static void
+internal_enable_location_gathering (GTask *task)
+{
+ EnableLocationGatheringContext *ctx;
+ LocationContext *location_ctx;
+ gboolean start_gps = FALSE;
- location_ctx = get_location_context (MM_BASE_MODEM (self));
+ 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 |
@@ -360,22 +507,41 @@ parent_enable_location_gathering_ready (MMIfaceModemLocation *self,
}
if (start_gps) {
- /* We enable continuous GPS fixes */
- mm_base_modem_at_command_full (MM_BASE_MODEM (self),
- mm_base_modem_peek_best_at_port (MM_BASE_MODEM (self), NULL),
- "AT^SGPSS=4",
- 3,
- FALSE,
- FALSE, /* raw */
- NULL, /* cancellable */
- (GAsyncReadyCallback)gps_enabled_ready,
- ctx);
+ enable_location_gathering_context_gps_step (task);
return;
}
/* For any other location (e.g. 3GPP), or if GPS already running just return */
- g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
- location_gathering_context_complete_and_free (ctx);
+ 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
@@ -384,22 +550,22 @@ mm_common_cinterion_enable_location_gathering (MMIfaceModemLocation *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
- LocationGatheringContext *ctx;
-
- ctx = g_slice_new (LocationGatheringContext);
- ctx->self = g_object_ref (self);
- ctx->result = g_simple_async_result_new (G_OBJECT (self),
- callback,
- user_data,
- mm_common_cinterion_enable_location_gathering);
- ctx->source = source;
+ 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,
- ctx);
+ task);
}
/*****************************************************************************/