[PATCH 1/5] cinterion,location: refactor enable/disable and capabilities checks
Aleksander Morgado
aleksander at aleksander.es
Tue May 30 19:40:33 UTC 2017
On 17/05/17 15:24, Aleksander Morgado wrote:
> When checking for location capabilities, we will make sure AT^SGPSS is
> supported and if it isn't we won't report GPS capabilities.
>
> The location enable and disable paths are refactored to make it easier
> to add possible new GPS commands to use instead of AT^SGPSS, if this
> isn't supported (e.g. in the PLS8 devices).
This has been merged to git master.
> ---
> plugins/cinterion/mm-common-cinterion.c | 534 +++++++++++++++++++++-----------
> 1 file 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);
> }
>
> /*****************************************************************************/
>
--
Aleksander
https://aleksander.es
More information about the ModemManager-devel
mailing list