aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mm-shared-qmi.c746
1 files changed, 390 insertions, 356 deletions
diff --git a/src/mm-shared-qmi.c b/src/mm-shared-qmi.c
index 8bcfe55f..62ca26c6 100644
--- a/src/mm-shared-qmi.c
+++ b/src/mm-shared-qmi.c
@@ -40,14 +40,14 @@ typedef struct {
MMIfaceModemLocation *iface_modem_location_parent;
MMModemLocationSource enabled_sources;
QmiClient *pds_client;
- gulong location_event_report_indication_id;
+ gulong pds_location_event_report_indication_id;
} Private;
static void
private_free (Private *priv)
{
- if (priv->location_event_report_indication_id)
- g_signal_handler_disconnect (priv->pds_client, priv->location_event_report_indication_id);
+ if (priv->pds_location_event_report_indication_id)
+ g_signal_handler_disconnect (priv->pds_client, priv->pds_location_event_report_indication_id);
if (priv->pds_client)
g_object_unref (priv->pds_client);
g_slice_free (Private, priv);
@@ -311,37 +311,23 @@ mm_shared_qmi_location_load_supl_server (MMIfaceModemLocation *self,
}
/*****************************************************************************/
-/* Location: disable */
-
-typedef struct {
- QmiClientPds *client;
- MMModemLocationSource source;
-} DisableLocationGatheringContext;
+/* Location: internal helper: stop gps engine */
-static void
-disable_location_gathering_context_free (DisableLocationGatheringContext *ctx)
-{
- if (ctx->client)
- g_object_unref (ctx->client);
- g_slice_free (DisableLocationGatheringContext, ctx);
-}
-
-gboolean
-mm_shared_qmi_disable_location_gathering_finish (MMIfaceModemLocation *self,
- GAsyncResult *res,
- GError **error)
+static gboolean
+stop_gps_engine_finish (MMSharedQmi *self,
+ GAsyncResult *res,
+ GError **error)
{
return g_task_propagate_boolean (G_TASK (res), error);
}
static void
-gps_service_state_stop_ready (QmiClientPds *client,
- GAsyncResult *res,
- GTask *task)
+pds_gps_service_state_stop_ready (QmiClientPds *client,
+ GAsyncResult *res,
+ GTask *task)
{
MMSharedQmi *self;
Private *priv;
- DisableLocationGatheringContext *ctx;
QmiMessagePdsSetGpsServiceStateOutput *output;
GError *error = NULL;
@@ -354,9 +340,7 @@ gps_service_state_stop_ready (QmiClientPds *client,
}
if (!qmi_message_pds_set_gps_service_state_output_get_result (output, &error)) {
- if (!g_error_matches (error,
- QMI_PROTOCOL_ERROR,
- QMI_PROTOCOL_ERROR_NO_EFFECT)) {
+ if (!g_error_matches (error, QMI_PROTOCOL_ERROR, QMI_PROTOCOL_ERROR_NO_EFFECT)) {
g_prefix_error (&error, "Couldn't set GPS service state: ");
g_task_return_error (task, error);
g_object_unref (task);
@@ -371,228 +355,59 @@ gps_service_state_stop_ready (QmiClientPds *client,
self = g_task_get_source_object (task);
priv = get_private (self);
- ctx = g_task_get_task_data (task);
-
- g_assert (priv->location_event_report_indication_id != 0);
- g_assert (priv->pds_client);
-
- g_signal_handler_disconnect (priv->pds_client, priv->location_event_report_indication_id);
- priv->location_event_report_indication_id = 0;
- g_clear_object (&priv->pds_client);
-
- mm_dbg ("GPS stopped");
- priv->enabled_sources &= ~ctx->source;
- g_task_return_boolean (task, TRUE);
- g_object_unref (task);
-}
-
-static void
-set_default_tracking_session_stop_ready (QmiClientPds *client,
- GAsyncResult *res,
- GTask *task)
-{
- MMSharedQmi *self;
- Private *priv;
- DisableLocationGatheringContext *ctx;
- QmiMessagePdsSetDefaultTrackingSessionOutput *output;
- GError *error = NULL;
-
- output = qmi_client_pds_set_default_tracking_session_finish (client, res, &error);
- if (!output) {
- g_prefix_error (&error, "QMI operation failed: ");
- g_task_return_error (task, error);
- g_object_unref (task);
- return;
- }
- if (!qmi_message_pds_set_default_tracking_session_output_get_result (output, &error)) {
- g_prefix_error (&error, "Couldn't set default tracking session: ");
- g_task_return_error (task, error);
- g_object_unref (task);
- qmi_message_pds_set_default_tracking_session_output_unref (output);
- return;
+ if (priv->pds_client) {
+ if (priv->pds_location_event_report_indication_id != 0) {
+ g_signal_handler_disconnect (priv->pds_client, priv->pds_location_event_report_indication_id);
+ priv->pds_location_event_report_indication_id = 0;
+ }
+ g_clear_object (&priv->pds_client);
}
- qmi_message_pds_set_default_tracking_session_output_unref (output);
-
- self = g_task_get_source_object (task);
- priv = get_private (self);
- ctx = g_task_get_task_data (task);
-
- /* Done */
- mm_dbg ("A-GPS disabled");
- priv->enabled_sources &= ~ctx->source;
g_task_return_boolean (task, TRUE);
g_object_unref (task);
}
static void
-get_default_tracking_session_stop_ready (QmiClientPds *client,
- GAsyncResult *res,
- GTask *task)
+stop_gps_engine (MMSharedQmi *self,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
- MMSharedQmi *self;
- Private *priv;
- DisableLocationGatheringContext *ctx;
- QmiMessagePdsSetDefaultTrackingSessionInput *input;
- QmiMessagePdsGetDefaultTrackingSessionOutput *output;
- GError *error = NULL;
- QmiPdsOperatingMode session_operation;
- guint8 data_timeout;
- guint32 interval;
- guint32 accuracy_threshold;
-
- output = qmi_client_pds_get_default_tracking_session_finish (client, res, &error);
- if (!output) {
- g_prefix_error (&error, "QMI operation failed: ");
- g_task_return_error (task, error);
- g_object_unref (task);
- return;
- }
-
- if (!qmi_message_pds_get_default_tracking_session_output_get_result (output, &error)) {
- g_prefix_error (&error, "Couldn't get default tracking session: ");
- g_task_return_error (task, error);
- g_object_unref (task);
- qmi_message_pds_get_default_tracking_session_output_unref (output);
- return;
- }
-
- qmi_message_pds_get_default_tracking_session_output_get_info (
- output,
- &session_operation,
- &data_timeout,
- &interval,
- &accuracy_threshold,
- NULL);
-
- qmi_message_pds_get_default_tracking_session_output_unref (output);
-
- self = g_task_get_source_object (task);
- priv = get_private (self);
- ctx = g_task_get_task_data (task);
-
- if (session_operation == QMI_PDS_OPERATING_MODE_STANDALONE) {
- /* Done */
- mm_dbg ("A-GPS already disabled");
- priv->enabled_sources &= ~ctx->source;
- g_task_return_boolean (task, TRUE);
- g_object_unref (task);
- return;
- }
-
- input = qmi_message_pds_set_default_tracking_session_input_new ();
- qmi_message_pds_set_default_tracking_session_input_set_info (
- input,
- QMI_PDS_OPERATING_MODE_STANDALONE,
- data_timeout,
- interval,
- accuracy_threshold,
- NULL);
- qmi_client_pds_set_default_tracking_session (
- ctx->client,
- input,
- 10,
- NULL, /* cancellable */
- (GAsyncReadyCallback)set_default_tracking_session_stop_ready,
- task);
- qmi_message_pds_set_default_tracking_session_input_unref (input);
-}
-
-void
-mm_shared_qmi_disable_location_gathering (MMIfaceModemLocation *_self,
- MMModemLocationSource source,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- MMSharedQmi *self;
- Private *priv;
- GTask *task;
- DisableLocationGatheringContext *ctx;
+ GTask *task;
+ Private *priv;
- self = MM_SHARED_QMI (_self);
priv = get_private (self);
task = g_task_new (self, NULL, callback, user_data);
- /* NOTE: no parent disable_location_gathering() implementation */
-
- if (!(source & (MM_MODEM_LOCATION_SOURCE_GPS_NMEA |
- MM_MODEM_LOCATION_SOURCE_GPS_RAW |
- MM_MODEM_LOCATION_SOURCE_AGPS))) {
- g_task_return_boolean (task, TRUE);
- g_object_unref (task);
- return;
- }
-
- if (!priv->pds_client) {
- g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
- "missing QMI PDS client");
- g_object_unref (task);
- return;
- }
-
- ctx = g_slice_new0 (DisableLocationGatheringContext);
- ctx->source = source;
- ctx->client = g_object_ref (priv->pds_client);
- g_task_set_task_data (task, ctx, (GDestroyNotify)disable_location_gathering_context_free);
+ if (priv->pds_client) {
+ QmiMessagePdsSetGpsServiceStateInput *input;
- /* Disable A-GPS? */
- if (source == MM_MODEM_LOCATION_SOURCE_AGPS) {
- qmi_client_pds_get_default_tracking_session (
- ctx->client,
- NULL,
+ input = qmi_message_pds_set_gps_service_state_input_new ();
+ qmi_message_pds_set_gps_service_state_input_set_state (input, FALSE, NULL);
+ qmi_client_pds_set_gps_service_state (
+ QMI_CLIENT_PDS (priv->pds_client),
+ input,
10,
NULL, /* cancellable */
- (GAsyncReadyCallback)get_default_tracking_session_stop_ready,
+ (GAsyncReadyCallback)pds_gps_service_state_stop_ready,
task);
+ qmi_message_pds_set_gps_service_state_input_unref (input);
return;
}
- /* Only stop GPS engine if no GPS-related sources enabled */
- if (source & (MM_MODEM_LOCATION_SOURCE_GPS_NMEA | MM_MODEM_LOCATION_SOURCE_GPS_RAW)) {
- MMModemLocationSource tmp;
-
- /* If no more GPS sources enabled, stop GPS */
- tmp = priv->enabled_sources;
- tmp &= ~source;
- if (!(tmp & (MM_MODEM_LOCATION_SOURCE_GPS_NMEA | MM_MODEM_LOCATION_SOURCE_GPS_RAW))) {
- QmiMessagePdsSetGpsServiceStateInput *input;
-
- input = qmi_message_pds_set_gps_service_state_input_new ();
- qmi_message_pds_set_gps_service_state_input_set_state (input, FALSE, NULL);
- qmi_client_pds_set_gps_service_state (
- ctx->client,
- input,
- 10,
- NULL, /* cancellable */
- (GAsyncReadyCallback)gps_service_state_stop_ready,
- task);
- qmi_message_pds_set_gps_service_state_input_unref (input);
- return;
- }
-
- /* Otherwise, we have more GPS sources enabled, we shouldn't stop GPS, just
- * return */
- priv->enabled_sources &= ~source;
- g_task_return_boolean (task, TRUE);
- g_object_unref (task);
- return;
- }
-
- /* The QMI implementation has a fixed set of capabilities supported. Arriving
- * here means we tried to disable one which wasn't set as supported, which should
- * not happen */
- g_assert_not_reached ();
+ g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
+ "Couldn't find any PDS client");
+ g_object_unref (task);
}
/*****************************************************************************/
-/* Location: enable */
+/* Location: internal helper: NMEA indication callback */
static void
-location_event_report_indication_cb (QmiClientPds *client,
- QmiIndicationPdsEventReportOutput *output,
- MMSharedQmi *self)
+pds_location_event_report_indication_cb (QmiClientPds *client,
+ QmiIndicationPdsEventReportOutput *output,
+ MMSharedQmi *self)
{
QmiPdsPositionSessionStatus session_status;
const gchar *nmea;
@@ -614,35 +429,24 @@ location_event_report_indication_cb (QmiClientPds *client,
}
}
-typedef struct {
- QmiClientPds *client;
- MMModemLocationSource source;
-} EnableLocationGatheringContext;
-
-static void
-enable_location_gathering_context_free (EnableLocationGatheringContext *ctx)
-{
- if (ctx->client)
- g_object_unref (ctx->client);
- g_slice_free (EnableLocationGatheringContext, ctx);
-}
+/*****************************************************************************/
+/* Location: internal helper: start gps engine */
-gboolean
-mm_shared_qmi_enable_location_gathering_finish (MMIfaceModemLocation *self,
- GAsyncResult *res,
- GError **error)
+static gboolean
+start_gps_engine_finish (MMSharedQmi *self,
+ GAsyncResult *res,
+ GError **error)
{
return g_task_propagate_boolean (G_TASK (res), error);
}
static void
-ser_location_ready (QmiClientPds *client,
- GAsyncResult *res,
- GTask *task)
+pds_ser_location_ready (QmiClientPds *client,
+ GAsyncResult *res,
+ GTask *task)
{
MMSharedQmi *self;
Private *priv;
- EnableLocationGatheringContext *ctx;
QmiMessagePdsSetEventReportOutput *output;
GError *error = NULL;
@@ -666,28 +470,24 @@ ser_location_ready (QmiClientPds *client,
self = g_task_get_source_object (task);
priv = get_private (self);
- ctx = g_task_get_task_data (task);
- mm_dbg ("Adding location event report indication handling");
g_assert (!priv->pds_client);
- g_assert (priv->location_event_report_indication_id == 0);
+ g_assert (priv->pds_location_event_report_indication_id == 0);
priv->pds_client = g_object_ref (client);
- priv->location_event_report_indication_id =
+ priv->pds_location_event_report_indication_id =
g_signal_connect (priv->pds_client,
"event-report",
- G_CALLBACK (location_event_report_indication_cb),
+ G_CALLBACK (pds_location_event_report_indication_cb),
self);
- mm_dbg ("GPS started");
- priv->enabled_sources |= ctx->source;
g_task_return_boolean (task, TRUE);
g_object_unref (task);
}
static void
-auto_tracking_state_start_ready (QmiClientPds *client,
- GAsyncResult *res,
- GTask *task)
+pds_auto_tracking_state_start_ready (QmiClientPds *client,
+ GAsyncResult *res,
+ GTask *task)
{
QmiMessagePdsSetEventReportInput *input;
QmiMessagePdsSetAutoTrackingStateOutput *output = NULL;
@@ -702,9 +502,7 @@ auto_tracking_state_start_ready (QmiClientPds *client,
}
if (!qmi_message_pds_set_auto_tracking_state_output_get_result (output, &error)) {
- if (!g_error_matches (error,
- QMI_PROTOCOL_ERROR,
- QMI_PROTOCOL_ERROR_NO_EFFECT)) {
+ if (!g_error_matches (error, QMI_PROTOCOL_ERROR, QMI_PROTOCOL_ERROR_NO_EFFECT)) {
g_prefix_error (&error, "Couldn't set auto-tracking state: ");
g_task_return_error (task, error);
g_object_unref (task);
@@ -724,15 +522,15 @@ auto_tracking_state_start_ready (QmiClientPds *client,
input,
5,
NULL,
- (GAsyncReadyCallback)ser_location_ready,
+ (GAsyncReadyCallback)pds_ser_location_ready,
task);
qmi_message_pds_set_event_report_input_unref (input);
}
static void
-gps_service_state_start_ready (QmiClientPds *client,
- GAsyncResult *res,
- GTask *task)
+pds_gps_service_state_start_ready (QmiClientPds *client,
+ GAsyncResult *res,
+ GTask *task)
{
QmiMessagePdsSetAutoTrackingStateInput *input;
QmiMessagePdsSetGpsServiceStateOutput *output;
@@ -747,9 +545,7 @@ gps_service_state_start_ready (QmiClientPds *client,
}
if (!qmi_message_pds_set_gps_service_state_output_get_result (output, &error)) {
- if (!g_error_matches (error,
- QMI_PROTOCOL_ERROR,
- QMI_PROTOCOL_ERROR_NO_EFFECT)) {
+ if (!g_error_matches (error, QMI_PROTOCOL_ERROR, QMI_PROTOCOL_ERROR_NO_EFFECT)) {
g_prefix_error (&error, "Couldn't set GPS service state: ");
g_task_return_error (task, error);
g_object_unref (task);
@@ -769,22 +565,87 @@ gps_service_state_start_ready (QmiClientPds *client,
input,
10,
NULL, /* cancellable */
- (GAsyncReadyCallback)auto_tracking_state_start_ready,
+ (GAsyncReadyCallback)pds_auto_tracking_state_start_ready,
task);
qmi_message_pds_set_auto_tracking_state_input_unref (input);
}
static void
-set_default_tracking_session_start_ready (QmiClientPds *client,
- GAsyncResult *res,
- GTask *task)
+start_gps_engine (MMSharedQmi *self,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
- MMSharedQmi *self;
- Private *priv;
- EnableLocationGatheringContext *ctx;
+ QmiClient *client;
+ GTask *task;
+
+ task = g_task_new (self, NULL, callback, user_data);
+
+ client = mm_shared_qmi_peek_client (MM_SHARED_QMI (self),
+ QMI_SERVICE_PDS,
+ MM_PORT_QMI_FLAG_DEFAULT,
+ NULL);
+ if (client) {
+ QmiMessagePdsSetGpsServiceStateInput *input;
+
+ input = qmi_message_pds_set_gps_service_state_input_new ();
+ qmi_message_pds_set_gps_service_state_input_set_state (input, TRUE, NULL);
+ qmi_client_pds_set_gps_service_state (
+ QMI_CLIENT_PDS (client),
+ input,
+ 10,
+ NULL, /* cancellable */
+ (GAsyncReadyCallback)pds_gps_service_state_start_ready,
+ task);
+ qmi_message_pds_set_gps_service_state_input_unref (input);
+ return;
+ }
+
+ g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
+ "Couldn't find any PDS client");
+ g_object_unref (task);
+}
+
+/*****************************************************************************/
+/* Location: internal helper: select operation mode (assisted/standalone) */
+
+typedef enum {
+ GPS_OPERATION_MODE_UNKNOWN,
+ GPS_OPERATION_MODE_STANDALONE,
+ GPS_OPERATION_MODE_ASSISTED,
+} GpsOperationMode;
+
+typedef struct {
+ QmiClient *client;
+ GpsOperationMode mode;
+} SetGpsOperationModeContext;
+
+static void
+set_gps_operation_mode_context_free (SetGpsOperationModeContext *ctx)
+{
+ if (ctx->client)
+ g_object_unref (ctx->client);
+ g_slice_free (SetGpsOperationModeContext, ctx);
+}
+
+static gboolean
+set_gps_operation_mode_finish (MMSharedQmi *self,
+ GAsyncResult *res,
+ GError **error)
+{
+ return g_task_propagate_boolean (G_TASK (res), error);
+}
+
+static void
+pds_set_default_tracking_session_ready (QmiClientPds *client,
+ GAsyncResult *res,
+ GTask *task)
+{
+ SetGpsOperationModeContext *ctx;
QmiMessagePdsSetDefaultTrackingSessionOutput *output;
GError *error = NULL;
+ ctx = g_task_get_task_data (task);
+
output = qmi_client_pds_set_default_tracking_session_finish (client, res, &error);
if (!output) {
g_prefix_error (&error, "QMI operation failed: ");
@@ -803,25 +664,18 @@ set_default_tracking_session_start_ready (QmiClientPds *client,
qmi_message_pds_set_default_tracking_session_output_unref (output);
- self = g_task_get_source_object (task);
- priv = get_private (self);
- ctx = g_task_get_task_data (task);
-
- /* Done */
- mm_dbg ("A-GPS enabled");
- priv->enabled_sources |= ctx->source;
+ mm_dbg ("A-GPS %s", ctx->mode == GPS_OPERATION_MODE_ASSISTED ? "enabled" : "disabled");
g_task_return_boolean (task, TRUE);
g_object_unref (task);
}
static void
-get_default_tracking_session_start_ready (QmiClientPds *client,
- GAsyncResult *res,
- GTask *task)
+pds_get_default_tracking_session_ready (QmiClientPds *client,
+ GAsyncResult *res,
+ GTask *task)
{
MMSharedQmi *self;
- Private *priv;
- EnableLocationGatheringContext *ctx;
+ SetGpsOperationModeContext *ctx;
QmiMessagePdsSetDefaultTrackingSessionInput *input;
QmiMessagePdsGetDefaultTrackingSessionOutput *output;
GError *error = NULL;
@@ -847,7 +701,6 @@ get_default_tracking_session_start_ready (QmiClientPds *client,
}
self = g_task_get_source_object (task);
- priv = get_private (self);
ctx = g_task_get_task_data (task);
qmi_message_pds_get_default_tracking_session_output_get_info (
@@ -860,116 +713,301 @@ get_default_tracking_session_start_ready (QmiClientPds *client,
qmi_message_pds_get_default_tracking_session_output_unref (output);
- if (session_operation == QMI_PDS_OPERATING_MODE_MS_ASSISTED) {
- mm_dbg ("A-GPS already enabled");
- priv->enabled_sources |= ctx->source;
- g_task_return_boolean (task, TRUE);
- g_object_unref (task);
- return;
- }
+ if (ctx->mode == GPS_OPERATION_MODE_ASSISTED) {
+ if (session_operation == QMI_PDS_OPERATING_MODE_MS_ASSISTED) {
+ mm_dbg ("A-GPS already enabled");
+ g_task_return_boolean (task, TRUE);
+ g_object_unref (task);
+ return;
+ }
+ mm_dbg ("Need to enable A-GPS");
+ session_operation = QMI_PDS_OPERATING_MODE_MS_ASSISTED;
+ } else if (ctx->mode == GPS_OPERATION_MODE_STANDALONE) {
+ if (session_operation == QMI_PDS_OPERATING_MODE_STANDALONE) {
+ mm_dbg ("A-GPS already disabled");
+ g_task_return_boolean (task, TRUE);
+ g_object_unref (task);
+ return;
+ }
+ mm_dbg ("Need to disable A-GPS");
+ session_operation = QMI_PDS_OPERATING_MODE_STANDALONE;
+ } else
+ g_assert_not_reached ();
input = qmi_message_pds_set_default_tracking_session_input_new ();
qmi_message_pds_set_default_tracking_session_input_set_info (
input,
- QMI_PDS_OPERATING_MODE_MS_ASSISTED,
+ session_operation,
data_timeout,
interval,
accuracy_threshold,
NULL);
qmi_client_pds_set_default_tracking_session (
- ctx->client,
+ client,
input,
10,
NULL, /* cancellable */
- (GAsyncReadyCallback)set_default_tracking_session_start_ready,
+ (GAsyncReadyCallback)pds_set_default_tracking_session_ready,
task);
qmi_message_pds_set_default_tracking_session_input_unref (input);
}
static void
-parent_enable_location_gathering_ready (MMIfaceModemLocation *_self,
- GAsyncResult *res,
- GTask *task)
+set_gps_operation_mode (MMSharedQmi *self,
+ GpsOperationMode mode,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
- MMSharedQmi *self = MM_SHARED_QMI (_self);
- Private *priv;
- EnableLocationGatheringContext *ctx;
- GError *error = NULL;
- QmiClient *client;
+ SetGpsOperationModeContext *ctx;
+ GTask *task;
+ QmiClient *client;
+
+ task = g_task_new (self, NULL, callback, user_data);
+ ctx = g_slice_new0 (SetGpsOperationModeContext);
+ ctx->mode = mode;
+ g_task_set_task_data (task, ctx, (GDestroyNotify)set_gps_operation_mode_context_free);
+
+ client = mm_shared_qmi_peek_client (MM_SHARED_QMI (self),
+ QMI_SERVICE_PDS,
+ MM_PORT_QMI_FLAG_DEFAULT,
+ NULL);
+ if (client) {
+ ctx->client = g_object_ref (client);
+ qmi_client_pds_get_default_tracking_session (
+ QMI_CLIENT_PDS (ctx->client),
+ NULL,
+ 10,
+ NULL, /* cancellable */
+ (GAsyncReadyCallback)pds_get_default_tracking_session_ready,
+ task);
+ return;
+ }
+
+ g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
+ "Couldn't find any PDS client");
+ g_object_unref (task);
+}
+
+/*****************************************************************************/
+/* Location: disable */
+
+gboolean
+mm_shared_qmi_disable_location_gathering_finish (MMIfaceModemLocation *self,
+ GAsyncResult *res,
+ GError **error)
+{
+ return g_task_propagate_boolean (G_TASK (res), error);
+}
+
+static void
+stop_gps_engine_ready (MMSharedQmi *self,
+ GAsyncResult *res,
+ GTask *task)
+{
+ MMModemLocationSource source;
+ Private *priv;
+ GError *error = NULL;
+
+ if (!stop_gps_engine_finish (self, res, &error)) {
+ g_task_return_error (task, error);
+ g_object_unref (task);
+ return;
+ }
+
+ source = (MMModemLocationSource) GPOINTER_TO_UINT (g_task_get_task_data (task));
priv = get_private (self);
- if (!priv->iface_modem_location_parent->enable_location_gathering_finish (_self, res, &error)) {
+ priv->enabled_sources &= ~source;
+
+ g_task_return_boolean (task, TRUE);
+ g_object_unref (task);
+}
+
+static void
+set_gps_operation_mode_standalone_ready (MMSharedQmi *self,
+ GAsyncResult *res,
+ GTask *task)
+{
+ GError *error = NULL;
+ Private *priv;
+
+ if (!set_gps_operation_mode_finish (self, res, &error)) {
g_task_return_error (task, error);
g_object_unref (task);
return;
}
- ctx = g_task_get_task_data (task);
+ priv = get_private (self);
- /* We only consider GPS related sources in this shared QMI implementation */
- if (!(ctx->source & (MM_MODEM_LOCATION_SOURCE_GPS_NMEA |
- MM_MODEM_LOCATION_SOURCE_GPS_RAW |
- MM_MODEM_LOCATION_SOURCE_AGPS))) {
+ priv->enabled_sources &= ~MM_MODEM_LOCATION_SOURCE_AGPS;
+
+ g_task_return_boolean (task, TRUE);
+ g_object_unref (task);
+}
+
+void
+mm_shared_qmi_disable_location_gathering (MMIfaceModemLocation *_self,
+ MMModemLocationSource source,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ MMSharedQmi *self;
+ Private *priv;
+ GTask *task;
+ MMModemLocationSource tmp;
+
+ self = MM_SHARED_QMI (_self);
+ priv = get_private (self);
+
+ task = g_task_new (self, NULL, callback, user_data);
+ g_task_set_task_data (task, GUINT_TO_POINTER (source), NULL);
+
+ /* NOTE: no parent disable_location_gathering() implementation */
+
+ if (!(source & (MM_MODEM_LOCATION_SOURCE_GPS_NMEA |
+ MM_MODEM_LOCATION_SOURCE_GPS_RAW |
+ MM_MODEM_LOCATION_SOURCE_AGPS))) {
g_task_return_boolean (task, TRUE);
g_object_unref (task);
return;
}
- /* Setup context and client */
- client = mm_shared_qmi_peek_client (MM_SHARED_QMI (self),
- QMI_SERVICE_PDS,
- MM_PORT_QMI_FLAG_DEFAULT,
- &error);
- if (!client) {
+ g_assert (!priv->pds_client);
+
+ /* Disable A-GPS? */
+ if (source == MM_MODEM_LOCATION_SOURCE_AGPS) {
+ set_gps_operation_mode (self,
+ GPS_OPERATION_MODE_STANDALONE,
+ (GAsyncReadyCallback)set_gps_operation_mode_standalone_ready,
+ task);
+ return;
+ }
+
+ /* If no more GPS sources enabled, stop GPS */
+ tmp = priv->enabled_sources;
+ tmp &= ~source;
+ if (!(tmp & (MM_MODEM_LOCATION_SOURCE_GPS_NMEA | MM_MODEM_LOCATION_SOURCE_GPS_RAW))) {
+ stop_gps_engine (self,
+ (GAsyncReadyCallback)stop_gps_engine_ready,
+ task);
+ return;
+ }
+
+ /* Otherwise, we have more GPS sources enabled, we shouldn't stop GPS, just
+ * return */
+ priv->enabled_sources &= ~source;
+ g_task_return_boolean (task, TRUE);
+ g_object_unref (task);
+}
+
+/*****************************************************************************/
+/* Location: enable */
+
+gboolean
+mm_shared_qmi_enable_location_gathering_finish (MMIfaceModemLocation *self,
+ GAsyncResult *res,
+ GError **error)
+{
+ return g_task_propagate_boolean (G_TASK (res), error);
+}
+
+static void
+start_gps_engine_ready (MMSharedQmi *self,
+ GAsyncResult *res,
+ GTask *task)
+{
+ MMModemLocationSource source;
+ Private *priv;
+ GError *error = NULL;
+
+ if (!start_gps_engine_finish (self, res, &error)) {
g_task_return_error (task, error);
g_object_unref (task);
return;
}
- ctx->client = g_object_ref (client);
- /* Enabling A-GPS? */
- if (ctx->source == MM_MODEM_LOCATION_SOURCE_AGPS) {
- qmi_client_pds_get_default_tracking_session (
- ctx->client,
- NULL,
- 10,
- NULL, /* cancellable */
- (GAsyncReadyCallback)get_default_tracking_session_start_ready,
- task);
+ source = (MMModemLocationSource) GPOINTER_TO_UINT (g_task_get_task_data (task));
+ priv = get_private (self);
+
+ priv->enabled_sources |= source;
+
+ g_task_return_boolean (task, TRUE);
+ g_object_unref (task);
+}
+
+static void
+set_gps_operation_mode_assisted_ready (MMSharedQmi *self,
+ GAsyncResult *res,
+ GTask *task)
+{
+ GError *error = NULL;
+ Private *priv;
+
+ if (!set_gps_operation_mode_finish (self, res, &error)) {
+ g_task_return_error (task, error);
+ g_object_unref (task);
return;
}
- /* 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)) {
- /* Only start GPS engine if not done already */
- if (!(priv->enabled_sources & (MM_MODEM_LOCATION_SOURCE_GPS_NMEA | MM_MODEM_LOCATION_SOURCE_GPS_RAW))) {
- QmiMessagePdsSetGpsServiceStateInput *input;
-
- input = qmi_message_pds_set_gps_service_state_input_new ();
- qmi_message_pds_set_gps_service_state_input_set_state (input, TRUE, NULL);
- qmi_client_pds_set_gps_service_state (
- ctx->client,
- input,
- 10,
- NULL, /* cancellable */
- (GAsyncReadyCallback)gps_service_state_start_ready,
- task);
- qmi_message_pds_set_gps_service_state_input_unref (input);
- return;
- }
+ priv = get_private (self);
+
+ priv->enabled_sources |= MM_MODEM_LOCATION_SOURCE_AGPS;
+
+ g_task_return_boolean (task, TRUE);
+ g_object_unref (task);
+}
+
+static void
+parent_enable_location_gathering_ready (MMIfaceModemLocation *_self,
+ GAsyncResult *res,
+ GTask *task)
+{
+ MMSharedQmi *self = MM_SHARED_QMI (_self);
+ Private *priv;
+ MMModemLocationSource source;
+ GError *error = NULL;
+
+ priv = get_private (self);
- /* GPS already started, we're done */
- priv->enabled_sources |= ctx->source;
+ if (!priv->iface_modem_location_parent->enable_location_gathering_finish (_self, res, &error)) {
+ g_task_return_error (task, error);
+ g_object_unref (task);
+ return;
+ }
+
+ source = (MMModemLocationSource) GPOINTER_TO_UINT (g_task_get_task_data (task));
+
+ /* We only consider GPS related sources in this shared QMI implementation */
+ if (!(source & (MM_MODEM_LOCATION_SOURCE_GPS_NMEA |
+ MM_MODEM_LOCATION_SOURCE_GPS_RAW |
+ MM_MODEM_LOCATION_SOURCE_AGPS))) {
g_task_return_boolean (task, TRUE);
g_object_unref (task);
return;
}
- /* The shared QMI implementation has a fixed set of capabilities supported. Arriving
- * here means we tried to enable one which wasn't set as supported, which should
- * not happen */
- g_assert_not_reached ();
+ /* Enabling A-GPS? */
+ if (source == MM_MODEM_LOCATION_SOURCE_AGPS) {
+ set_gps_operation_mode (self,
+ GPS_OPERATION_MODE_ASSISTED,
+ (GAsyncReadyCallback)set_gps_operation_mode_assisted_ready,
+ task);
+ return;
+ }
+
+ /* Only start GPS engine if not done already */
+ if (!(priv->enabled_sources & (MM_MODEM_LOCATION_SOURCE_GPS_NMEA | MM_MODEM_LOCATION_SOURCE_GPS_RAW))) {
+ start_gps_engine (self,
+ (GAsyncReadyCallback)start_gps_engine_ready,
+ task);
+ return;
+ }
+
+ /* GPS already started, we're done */
+ priv->enabled_sources |= source;
+ g_task_return_boolean (task, TRUE);
+ g_object_unref (task);
}
void
@@ -978,15 +1016,11 @@ mm_shared_qmi_enable_location_gathering (MMIfaceModemLocation *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
- EnableLocationGatheringContext *ctx;
- GTask *task;
- Private *priv;
-
- ctx = g_slice_new0 (EnableLocationGatheringContext);
- ctx->source = source;
+ GTask *task;
+ Private *priv;
task = g_task_new (self, NULL, callback, user_data);
- g_task_set_task_data (task, ctx, (GDestroyNotify)enable_location_gathering_context_free);
+ g_task_set_task_data (task, GUINT_TO_POINTER (source), NULL);
priv = get_private (MM_SHARED_QMI (self));
g_assert (priv->iface_modem_location_parent);
@@ -996,7 +1030,7 @@ mm_shared_qmi_enable_location_gathering (MMIfaceModemLocation *self,
/* Chain up parent's gathering enable */
priv->iface_modem_location_parent->enable_location_gathering (
self,
- ctx->source,
+ source,
(GAsyncReadyCallback)parent_enable_location_gathering_ready,
task);
}