aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cli/mmcli-modem-location.c162
-rw-r--r--docs/reference/api/ModemManager-sections.txt1
-rw-r--r--docs/reference/libmm-glib/libmm-glib-sections.txt14
-rw-r--r--include/ModemManager-enums.h12
-rw-r--r--introspection/org.freedesktop.ModemManager1.Modem.Location.xml34
-rw-r--r--libmm-glib/mm-modem-location.c153
-rw-r--r--libmm-glib/mm-modem-location.h20
-rw-r--r--src/mm-iface-modem-location.c188
-rw-r--r--src/mm-iface-modem-location.h26
9 files changed, 596 insertions, 14 deletions
diff --git a/cli/mmcli-modem-location.c b/cli/mmcli-modem-location.c
index 0568b513..997e1a84 100644
--- a/cli/mmcli-modem-location.c
+++ b/cli/mmcli-modem-location.c
@@ -66,6 +66,8 @@ static gboolean set_enable_signal_flag;
static gboolean set_disable_signal_flag;
static gboolean get_all_flag;
static gchar *set_supl_server_str;
+static gchar *set_supl_server_str;
+static gchar *inject_assistance_data_str;
static gchar *set_gps_refresh_rate_str;
static GOptionEntry entries[] = {
@@ -145,6 +147,10 @@ static GOptionEntry entries[] = {
"Set SUPL server address",
"[IP:PORT] or [URL]"
},
+ { "location-inject-assistance-data", 0, 0, G_OPTION_ARG_FILENAME, &inject_assistance_data_str,
+ "Inject assistance data in the GNSS module",
+ "[PATH]"
+ },
{ "location-set-gps-refresh-rate", 0, 0, G_OPTION_ARG_STRING, &set_gps_refresh_rate_str,
"Set GPS refresh rate in seconds, or 0 disable the explicit rate.",
"[RATE]"
@@ -226,6 +232,7 @@ mmcli_modem_location_options_enabled (void)
get_gps_raw_flag +
get_cdma_bs_flag) +
!!set_supl_server_str +
+ !!inject_assistance_data_str +
!!set_gps_refresh_rate_str);
if (n_actions > 1) {
@@ -300,27 +307,52 @@ print_location_status (void)
enabled_str,
mm_modem_location_signals_location (ctx->modem_location) ? "yes" : "no");
- /* If A-GPS supported, show SUPL server setup */
- if (mm_modem_location_get_capabilities (ctx->modem_location) & MM_MODEM_LOCATION_SOURCE_AGPS) {
- const gchar *supl_server;
-
- supl_server = mm_modem_location_get_supl_server (ctx->modem_location);
- g_print (" ----------------------------\n"
- " A-GPS | SUPL server: '%s'\n",
- supl_server ? supl_server : "unset");
- }
-
- /* If GPS supported, show GPS refresh rate */
+ /* If GPS supported, show GPS refresh rate and supported assistance data */
if (mm_modem_location_get_capabilities (ctx->modem_location) & (MM_MODEM_LOCATION_SOURCE_GPS_RAW |
MM_MODEM_LOCATION_SOURCE_GPS_NMEA)) {
- guint rate;
+ guint rate;
+ MMModemLocationAssistanceDataType mask;
+ gchar *mask_str;
rate = mm_modem_location_get_gps_refresh_rate (ctx->modem_location);
g_print (" ----------------------------\n");
if (rate > 0)
- g_print (" GPS | refresh rate: '%u'\n", rate);
+ g_print (" GPS | refresh rate: '%u'\n", rate);
else
- g_print (" GPS | refresh rate: disabled\n");
+ g_print (" GPS | refresh rate: disabled\n");
+
+ /* If A-GPS supported, show SUPL server setup */
+ if (mm_modem_location_get_capabilities (ctx->modem_location) & MM_MODEM_LOCATION_SOURCE_AGPS) {
+ const gchar *supl_server;
+
+ supl_server = mm_modem_location_get_supl_server (ctx->modem_location);
+ g_print (" | A-GPS SUPL server: '%s'\n",
+ supl_server ? supl_server : "unset");
+ }
+
+ mask = mm_modem_location_get_supported_assistance_data (ctx->modem_location);
+ mask_str = mm_modem_location_assistance_data_type_build_string_from_mask (mask);
+ g_print (" | supported assistance data: '%s'\n", mask_str);
+ g_free (mask_str);
+
+ /* If any assistance data supported, show server list */
+ if (mask != MM_MODEM_LOCATION_ASSISTANCE_DATA_TYPE_NONE) {
+ const gchar **servers;
+
+ servers = mm_modem_location_get_assistance_data_servers (ctx->modem_location);
+ if (!servers)
+ g_print (" | assistance data servers: 'n/a'\n");
+ else {
+ guint server_i;
+
+ for (server_i = 0; servers[server_i]; server_i++) {
+ if (server_i == 0)
+ g_print (" | assistance data servers: '%s'\n", servers[server_i]);
+ else
+ g_print (" | '%s'\n", servers[server_i]);
+ }
+ }
+ }
}
g_free (capabilities_str);
@@ -379,6 +411,65 @@ set_supl_server_ready (MMModemLocation *modem_location,
mmcli_async_operation_done ();
}
+static gboolean
+parse_inject_assistance_data (guint8 **o_data,
+ gsize *o_data_size)
+{
+ gboolean result = FALSE;
+ GFile *file = NULL;
+ gchar *data;
+ gsize data_size;
+ GError *error = NULL;
+
+ file = g_file_new_for_commandline_arg (inject_assistance_data_str);
+
+ if (!g_file_load_contents (file, NULL, &data, &data_size, NULL, &error)) {
+ g_printerr ("error: cannot load file contents: %s\n", error->message);
+ goto out;
+ }
+
+ if (data_size == 0) {
+ g_printerr ("error: file is empty\n");
+ goto out;
+ }
+
+ *o_data = (guint8 *)data;
+ *o_data_size = data_size;
+ result = TRUE;
+
+out:
+ if (error)
+ g_error_free (error);
+ g_object_unref (file);
+ return result;
+}
+
+static void
+inject_assistance_data_process_reply (gboolean result,
+ const GError *error)
+{
+ if (!result) {
+ g_printerr ("error: couldn't inject assistance data: '%s'\n",
+ error ? error->message : "unknown error");
+ exit (EXIT_FAILURE);
+ }
+
+ g_print ("successfully injected assistance data\n");
+}
+
+static void
+inject_assistance_data_ready (MMModemLocation *modem_location,
+ GAsyncResult *result)
+{
+ gboolean operation_result;
+ GError *error = NULL;
+
+ operation_result = mm_modem_location_inject_assistance_data_finish (modem_location, result, &error);
+ inject_assistance_data_process_reply (operation_result, error);
+
+ mmcli_async_operation_done ();
+}
+
static void
set_gps_refresh_rate_process_reply (gboolean result,
const GError *error)
@@ -667,6 +758,27 @@ get_modem_ready (GObject *source,
return;
}
+ /* Request to inject assistance data? */
+ if (inject_assistance_data_str) {
+ guint8 *data;
+ gsize data_size;
+
+ if (!parse_inject_assistance_data (&data, &data_size)) {
+ g_printerr ("error: couldn't inject assistance data: invalid parameters given: '%s'\n",
+ inject_assistance_data_str);
+ exit (EXIT_FAILURE);
+ }
+
+ g_debug ("Asynchronously injecting assistance data...");
+ mm_modem_location_inject_assistance_data (ctx->modem_location,
+ data, data_size,
+ ctx->cancellable,
+ (GAsyncReadyCallback)inject_assistance_data_ready,
+ NULL);
+ g_free (data);
+ return;
+ }
+
/* Request to set GPS refresh rate? */
if (set_gps_refresh_rate_str) {
guint rate;
@@ -792,6 +904,28 @@ mmcli_modem_location_run_synchronous (GDBusConnection *connection)
return;
}
+ /* Request to inject assistance data? */
+ if (inject_assistance_data_str) {
+ gboolean result;
+ guint8 *data;
+ gsize data_size;
+
+ if (!parse_inject_assistance_data (&data, &data_size)) {
+ g_printerr ("error: couldn't inject assistance data: invalid parameters given: '%s'\n",
+ inject_assistance_data_str);
+ exit (EXIT_FAILURE);
+ }
+
+ g_debug ("Synchronously setting assistance data...");
+ result = mm_modem_location_inject_assistance_data_sync (ctx->modem_location,
+ data, data_size,
+ NULL,
+ &error);
+ inject_assistance_data_process_reply (result, error);
+ g_free (data);
+ return;
+ }
+
/* Request to set GPS refresh rate? */
if (set_gps_refresh_rate_str) {
gboolean result;
diff --git a/docs/reference/api/ModemManager-sections.txt b/docs/reference/api/ModemManager-sections.txt
index 497f6e38..5ec728db 100644
--- a/docs/reference/api/ModemManager-sections.txt
+++ b/docs/reference/api/ModemManager-sections.txt
@@ -31,6 +31,7 @@ MMModemCdmaRegistrationState
MMModemCdmaRmProtocol
MMModemContactsStorage
MMModemLocationSource
+MMModemLocationAssistanceDataType
MMModemLock
MMModemMode
MMModemState
diff --git a/docs/reference/libmm-glib/libmm-glib-sections.txt b/docs/reference/libmm-glib/libmm-glib-sections.txt
index 3cd3364d..f41f4a7e 100644
--- a/docs/reference/libmm-glib/libmm-glib-sections.txt
+++ b/docs/reference/libmm-glib/libmm-glib-sections.txt
@@ -423,6 +423,7 @@ mm_modem_location_get_enabled
mm_modem_location_signals_location
mm_modem_location_dup_supl_server
mm_modem_location_get_supl_server
+mm_modem_location_get_supported_assistance_data
mm_modem_location_get_gps_refresh_rate
<SUBSECTION Methods>
mm_modem_location_setup
@@ -431,6 +432,9 @@ mm_modem_location_setup_sync
mm_modem_location_set_supl_server
mm_modem_location_set_supl_server_finish
mm_modem_location_set_supl_server_sync
+mm_modem_location_inject_assistance_data
+mm_modem_location_inject_assistance_data_finish
+mm_modem_location_inject_assistance_data_sync
mm_modem_location_set_gps_refresh_rate
mm_modem_location_set_gps_refresh_rate_finish
mm_modem_location_set_gps_refresh_rate_sync
@@ -1363,6 +1367,7 @@ mm_modem_cdma_registration_state_get_string
mm_modem_cdma_activation_state_get_string
mm_modem_cdma_rm_protocol_get_string
mm_modem_location_source_build_string_from_mask
+mm_modem_location_assistance_data_type_build_string_from_mask
mm_modem_contacts_storage_get_string
mm_sms_pdu_type_get_string
mm_sms_state_get_string
@@ -1397,6 +1402,7 @@ mm_sms_validity_type_build_string_from_mask
mm_sms_cdma_teleservice_id_build_string_from_mask
mm_sms_cdma_service_category_build_string_from_mask
mm_modem_location_source_get_string
+mm_modem_location_assistance_data_type_get_string
mm_modem_contacts_storage_build_string_from_mask
mm_bearer_ip_family_build_string_from_mask
mm_bearer_ip_method_build_string_from_mask
@@ -1438,6 +1444,7 @@ MM_TYPE_MODEM_CDMA_REGISTRATION_STATE
MM_TYPE_MODEM_CDMA_RM_PROTOCOL
MM_TYPE_MODEM_CONTACTS_STORAGE
MM_TYPE_MODEM_LOCATION_SOURCE
+MM_TYPE_MODEM_LOCATION_ASSISTANCE_DATA_TYPE
MM_TYPE_MODEM_LOCK
MM_TYPE_MODEM_MODE
MM_TYPE_MODEM_STATE
@@ -1477,6 +1484,7 @@ mm_modem_cdma_registration_state_get_type
mm_modem_cdma_rm_protocol_get_type
mm_modem_contacts_storage_get_type
mm_modem_location_source_get_type
+mm_modem_location_assistance_data_type_get_type
mm_modem_lock_get_type
mm_modem_mode_get_type
mm_modem_state_change_reason_get_type
@@ -2152,6 +2160,10 @@ mm_gdbus_modem_location_call_setup_sync
mm_gdbus_modem_location_call_set_supl_server
mm_gdbus_modem_location_call_set_supl_server_finish
mm_gdbus_modem_location_call_set_supl_server_sync
+mm_gdbus_modem_location_call_inject_assistance_data
+mm_gdbus_modem_location_call_inject_assistance_data_finish
+mm_gdbus_modem_location_call_inject_assistance_data_sync
+mm_gdbus_modem_location_get_supported_assistance_data
mm_gdbus_modem_location_call_set_gps_refresh_rate
mm_gdbus_modem_location_call_set_gps_refresh_rate_finish
mm_gdbus_modem_location_call_set_gps_refresh_rate_sync
@@ -2161,10 +2173,12 @@ mm_gdbus_modem_location_set_enabled
mm_gdbus_modem_location_set_location
mm_gdbus_modem_location_set_signals_location
mm_gdbus_modem_location_set_supl_server
+mm_gdbus_modem_location_set_supported_assistance_data
mm_gdbus_modem_location_set_gps_refresh_rate
mm_gdbus_modem_location_complete_get_location
mm_gdbus_modem_location_complete_setup
mm_gdbus_modem_location_complete_set_supl_server
+mm_gdbus_modem_location_complete_inject_assistance_data
mm_gdbus_modem_location_complete_set_gps_refresh_rate
mm_gdbus_modem_location_interface_info
mm_gdbus_modem_location_override_properties
diff --git a/include/ModemManager-enums.h b/include/ModemManager-enums.h
index 10166d24..60bbb027 100644
--- a/include/ModemManager-enums.h
+++ b/include/ModemManager-enums.h
@@ -911,6 +911,18 @@ typedef enum { /*< underscore_name=mm_modem_location_source >*/
} MMModemLocationSource;
/**
+ * MMModemLocationAssistanceDataType:
+ * @MM_MODEM_LOCATION_ASSISTANCE_DATA_TYPE_NONE: None.
+ * @MM_MODEM_LOCATION_ASSISTANCE_DATA_TYPE_XTRA: Qualcomm gpsOneXTRA.
+ *
+ * Type of assistance data that may be injected to the GNSS module.
+ */
+typedef enum { /*< underscore_name=mm_modem_location_assistance_data_type >*/
+ MM_MODEM_LOCATION_ASSISTANCE_DATA_TYPE_NONE = 0,
+ MM_MODEM_LOCATION_ASSISTANCE_DATA_TYPE_XTRA = 1 << 0,
+} MMModemLocationAssistanceDataType;
+
+/**
* MMModemContactsStorage:
* @MM_MODEM_CONTACTS_STORAGE_UNKNOWN: Unknown location.
* @MM_MODEM_CONTACTS_STORAGE_ME: Device's local memory.
diff --git a/introspection/org.freedesktop.ModemManager1.Modem.Location.xml b/introspection/org.freedesktop.ModemManager1.Modem.Location.xml
index fa51a6e2..7c490c6a 100644
--- a/introspection/org.freedesktop.ModemManager1.Modem.Location.xml
+++ b/introspection/org.freedesktop.ModemManager1.Modem.Location.xml
@@ -80,6 +80,24 @@
</method>
<!--
+ InjectAssistanceData:
+ @data: assistance data to be injected to the GNSS module.
+
+ Inject assistance data to the GNSS module.
+ The data files should be downloaded using external means from the URLs specified in
+ the <link linkend="AssistanceDataServers">AssistanceDataServers</link> property.
+
+ The user does not need to specify the assistance data type being given.
+
+ There is no maximum @data size limit specified, default DBus system bus limits apply.
+ -->
+ <method name="InjectAssistanceData">
+ <arg name="data" type="ay" direction="in">
+ <annotation name="org.gtk.GDBus.C.ForceGVariant" value="true"/>
+ </arg>
+ </method>
+
+ <!--
SetGpsRefreshRate:
@rate: Rate, in seconds.
@@ -102,6 +120,14 @@
<property name="Capabilities" type="u" access="read" />
<!--
+ SupportedAssistanceData:
+
+ Bitmask of <link linkend="MMModemLocationAssistanceDataType">MMModemLocationAssistanceDataType</link>
+ values, specifying the supported types of assistance data.
+ -->
+ <property name="SupportedAssistanceData" type="u" access="read" />
+
+ <!--
Enabled:
Bitmask specifying which of the supported
@@ -313,6 +339,14 @@
<property name="SuplServer" type="s" access="read" />
<!--
+ AssistanceDataServers:
+
+ URLs from where the user can download assistance data files to inject with
+ <link linkend="gdbus-method-org-freedesktop-ModemManager1-Modem-Location.InjectAssistanceData">InjectAssistanceData()</link>.
+ -->
+ <property name="AssistanceDataServers" type="as" access="read" />
+
+ <!--
GpsRefreshRate:
Rate of refresh of the GPS information in the interface.
diff --git a/libmm-glib/mm-modem-location.c b/libmm-glib/mm-modem-location.c
index d3343d20..8d97bf78 100644
--- a/libmm-glib/mm-modem-location.c
+++ b/libmm-glib/mm-modem-location.c
@@ -101,6 +101,24 @@ mm_modem_location_get_capabilities (MMModemLocation *self)
/*****************************************************************************/
/**
+ * mm_modem_location_get_supported_assistance_data:
+ * @self: A #MMModemLocation.
+ *
+ * Gets a bitmask of the supported assistance data types.
+ *
+ * Returns: A #MMModemLocationAssistanceDataType.
+ */
+MMModemLocationAssistanceDataType
+mm_modem_location_get_supported_assistance_data (MMModemLocation *self)
+{
+ g_return_val_if_fail (MM_IS_MODEM_LOCATION (self), MM_MODEM_LOCATION_ASSISTANCE_DATA_TYPE_NONE);
+
+ return (MMModemLocationAssistanceDataType) mm_gdbus_modem_location_get_supported_assistance_data (MM_GDBUS_MODEM_LOCATION (self));
+}
+
+/*****************************************************************************/
+
+/**
* mm_modem_location_get_enabled:
* @self: A #MMModemLocation.
*
@@ -307,6 +325,91 @@ mm_modem_location_set_supl_server_sync (MMModemLocation *self,
/*****************************************************************************/
/**
+ * mm_modem_location_inject_assistance_data_finish:
+ * @self: A #MMModemLocation.
+ * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to mm_modem_location_inject_assistance_data().
+ * @error: Return location for error or %NULL.
+ *
+ * Finishes an operation started with mm_modem_location_inject_assistance_data().
+ *
+ * Returns: %TRUE if the injection was successful, %FALSE if @error is set.
+ */
+gboolean
+mm_modem_location_inject_assistance_data_finish (MMModemLocation *self,
+ GAsyncResult *res,
+ GError **error)
+{
+ g_return_val_if_fail (MM_IS_MODEM_LOCATION (self), FALSE);
+
+ return mm_gdbus_modem_location_call_inject_assistance_data_finish (MM_GDBUS_MODEM_LOCATION (self), res, error);
+}
+
+/**
+ * mm_modem_location_inject_assistance_data:
+ * @self: A #MMModemLocation.
+ * @data: (array length=data_size): Data to inject.
+ * @data_size: size of @data.
+ * @cancellable: (allow-none): A #GCancellable or %NULL.
+ * @callback: A #GAsyncReadyCallback to call when the request is satisfied or %NULL.
+ * @user_data: User data to pass to @callback.
+ *
+ * Aynchronously injects assistance data to the GNSS module.
+ *
+ * When the operation is finished, @callback will be invoked in the <link linkend="g-main-context-push-thread-default">thread-default main loop</link> of the thread you are calling this method from.
+ * You can then call mm_modem_location_inject_assistance_data_finish() to get the result of the operation.
+ *
+ * See mm_modem_location_inject_assistance_data_sync() for the synchronous, blocking version of this method.
+ */
+void
+mm_modem_location_inject_assistance_data (MMModemLocation *self,
+ const guint8 *data,
+ gsize data_size,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_return_if_fail (MM_IS_MODEM_LOCATION (self));
+
+ mm_gdbus_modem_location_call_inject_assistance_data (MM_GDBUS_MODEM_LOCATION (self),
+ g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, data, data_size, sizeof (guint8)),
+ cancellable,
+ callback,
+ user_data);
+}
+
+/**
+ * mm_modem_location_inject_assistance_data_sync:
+ * @self: A #MMModemLocation.
+ * @data: (array length=data_size): Data to inject.
+ * @data_size: size of @data.
+ * @cancellable: (allow-none): A #GCancellable or %NULL.
+ * @error: Return location for error or %NULL.
+ *
+ * Synchronously injects assistance data to the GNSS module.
+ *
+ * The calling thread is blocked until a reply is received. See mm_modem_location_inject_assistance_data()
+ * for the asynchronous version of this method.
+ *
+ * Returns: %TRUE if the injection was successful, %FALSE if @error is set.
+ */
+gboolean
+mm_modem_location_inject_assistance_data_sync (MMModemLocation *self,
+ const guint8 *data,
+ gsize data_size,
+ GCancellable *cancellable,
+ GError **error)
+{
+ g_return_val_if_fail (MM_IS_MODEM_LOCATION (self), FALSE);
+
+ return mm_gdbus_modem_location_call_inject_assistance_data_sync (MM_GDBUS_MODEM_LOCATION (self),
+ g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, data, data_size, sizeof (guint8)),
+ cancellable,
+ error);
+}
+
+/*****************************************************************************/
+
+/**
* mm_modem_location_set_gps_refresh_rate_finish:
* @self: A #MMModemLocation.
* @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to mm_modem_location_set_gps_refresh_rate().
@@ -877,6 +980,56 @@ mm_modem_location_dup_supl_server (MMModemLocation *self)
/*****************************************************************************/
/**
+ * mm_modem_location_get_assistance_data_servers:
+ * @self: A #MMModemLocation.
+ *
+ * Gets the list of assistance data servers.
+ *
+ * <warning>The returned value is only valid until the property changes so
+ * it is only safe to use this function on the thread where
+ * @self was constructed. Use mm_modem_location_dup_assistance_data_servers() if on another
+ * thread.</warning>
+ *
+ * Returns: (transfer none): a %NULL-terminated array of server addresses, or %NULL if none available. Do not free the returned value, it belongs to @self.
+ */
+const gchar **
+mm_modem_location_get_assistance_data_servers (MMModemLocation *self)
+{
+ const gchar **tmp;
+
+ g_return_val_if_fail (MM_IS_MODEM_LOCATION (self), NULL);
+
+ tmp = (const gchar **) mm_gdbus_modem_location_get_assistance_data_servers (MM_GDBUS_MODEM_LOCATION (self));
+
+ return ((tmp && tmp[0]) ? tmp : NULL);
+}
+
+/**
+ * mm_modem_location_dup_assistance_data_servers:
+ * @self: A #MMModemLocation.
+ *
+ * Gets the list of assistance data servers.
+ *
+ * Returns: (transfer full): a %NULL-terminated array of server addresses, or %NULL if none available. The returned value should be freed with g_strfreev().
+ */
+gchar **
+mm_modem_location_dup_assistance_data_servers (MMModemLocation *self)
+{
+ gchar **tmp;
+
+ g_return_val_if_fail (MM_IS_MODEM_LOCATION (self), NULL);
+
+ tmp = mm_gdbus_modem_location_dup_assistance_data_servers (MM_GDBUS_MODEM_LOCATION (self));
+ if (tmp && tmp[0])
+ return tmp;
+
+ g_strfreev (tmp);
+ return NULL;
+}
+
+/*****************************************************************************/
+
+/**
* mm_modem_location_get_gps_refresh_rate:
* @self: A #MMModemLocation.
*
diff --git a/libmm-glib/mm-modem-location.h b/libmm-glib/mm-modem-location.h
index 2d806bef..e9ab9ea0 100644
--- a/libmm-glib/mm-modem-location.h
+++ b/libmm-glib/mm-modem-location.h
@@ -76,9 +76,14 @@ MMModemLocationSource mm_modem_location_get_enabled (MMModemLocation *self)
gboolean mm_modem_location_signals_location (MMModemLocation *self);
+MMModemLocationAssistanceDataType mm_modem_location_get_supported_assistance_data (MMModemLocation *self);
+
const gchar *mm_modem_location_get_supl_server (MMModemLocation *self);
gchar *mm_modem_location_dup_supl_server (MMModemLocation *self);
+const gchar **mm_modem_location_get_assistance_data_servers (MMModemLocation *self);
+gchar **mm_modem_location_dup_assistance_data_servers (MMModemLocation *self);
+
guint mm_modem_location_get_gps_refresh_rate (MMModemLocation *self);
void mm_modem_location_setup (MMModemLocation *self,
@@ -109,6 +114,21 @@ gboolean mm_modem_location_set_supl_server_sync (MMModemLocation *self,
GCancellable *cancellable,
GError **error);
+void mm_modem_location_inject_assistance_data (MMModemLocation *self,
+ const guint8 *data,
+ gsize data_size,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean mm_modem_location_inject_assistance_data_finish (MMModemLocation *self,
+ GAsyncResult *res,
+ GError **error);
+gboolean mm_modem_location_inject_assistance_data_sync (MMModemLocation *self,
+ const guint8 *data,
+ gsize data_size,
+ GCancellable *cancellable,
+ GError **error);
+
void mm_modem_location_set_gps_refresh_rate (MMModemLocation *self,
guint rate,
GCancellable *cancellable,
diff --git a/src/mm-iface-modem-location.c b/src/mm-iface-modem-location.c
index 4c45ab11..e5aaa43d 100644
--- a/src/mm-iface-modem-location.c
+++ b/src/mm-iface-modem-location.c
@@ -1035,6 +1035,108 @@ handle_set_supl_server (MmGdbusModemLocation *skeleton,
/*****************************************************************************/
typedef struct {
+ MmGdbusModemLocation *skeleton;
+ GDBusMethodInvocation *invocation;
+ MMIfaceModemLocation *self;
+ GVariant *datav;
+} HandleInjectAssistanceDataContext;
+
+static void
+handle_inject_assistance_data_context_free (HandleInjectAssistanceDataContext *ctx)
+{
+ g_object_unref (ctx->skeleton);
+ g_object_unref (ctx->invocation);
+ g_object_unref (ctx->self);
+ g_variant_unref (ctx->datav);
+ g_slice_free (HandleInjectAssistanceDataContext, ctx);
+}
+
+static void
+inject_assistance_data_ready (MMIfaceModemLocation *self,
+ GAsyncResult *res,
+ HandleInjectAssistanceDataContext *ctx)
+{
+ GError *error = NULL;
+
+ if (!MM_IFACE_MODEM_LOCATION_GET_INTERFACE (self)->inject_assistance_data_finish (self, res, &error))
+ g_dbus_method_invocation_take_error (ctx->invocation, error);
+ else
+ mm_gdbus_modem_location_complete_inject_assistance_data (ctx->skeleton, ctx->invocation);
+
+ handle_inject_assistance_data_context_free (ctx);
+}
+
+static void
+handle_inject_assistance_data_auth_ready (MMBaseModem *self,
+ GAsyncResult *res,
+ HandleInjectAssistanceDataContext *ctx)
+{
+ GError *error = NULL;
+ const guint8 *data;
+ gsize data_size;
+
+ if (!mm_base_modem_authorize_finish (self, res, &error)) {
+ g_dbus_method_invocation_take_error (ctx->invocation, error);
+ handle_inject_assistance_data_context_free (ctx);
+ return;
+ }
+
+ /* If the type is NOT supported, set error */
+ if (mm_gdbus_modem_location_get_supported_assistance_data (ctx->skeleton) == MM_MODEM_LOCATION_ASSISTANCE_DATA_TYPE_NONE) {
+ g_dbus_method_invocation_return_error (ctx->invocation,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_UNSUPPORTED,
+ "Cannot inject assistance data: ununsupported");
+ handle_inject_assistance_data_context_free (ctx);
+ return;
+ }
+
+ /* Check if plugin implements it */
+ if (!MM_IFACE_MODEM_LOCATION_GET_INTERFACE (self)->inject_assistance_data ||
+ !MM_IFACE_MODEM_LOCATION_GET_INTERFACE (self)->inject_assistance_data_finish) {
+ g_dbus_method_invocation_return_error (ctx->invocation,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_UNSUPPORTED,
+ "Cannot inject assistance data: not implemented");
+ handle_inject_assistance_data_context_free (ctx);
+ return;
+ }
+
+ data = (const guint8 *) g_variant_get_fixed_array (ctx->datav, &data_size, sizeof (guint8));
+
+ /* Request to inject assistance data */
+ MM_IFACE_MODEM_LOCATION_GET_INTERFACE (self)->inject_assistance_data (ctx->self,
+ data,
+ data_size,
+ (GAsyncReadyCallback)inject_assistance_data_ready,
+ ctx);
+}
+
+static gboolean
+handle_inject_assistance_data (MmGdbusModemLocation *skeleton,
+ GDBusMethodInvocation *invocation,
+ GVariant *datav,
+ MMIfaceModemLocation *self)
+{
+ HandleInjectAssistanceDataContext *ctx;
+
+ ctx = g_slice_new (HandleInjectAssistanceDataContext);
+ ctx->skeleton = g_object_ref (skeleton);
+ ctx->invocation = g_object_ref (invocation);
+ ctx->self = g_object_ref (self);
+ ctx->datav = g_variant_ref (datav);
+
+ mm_base_modem_authorize (MM_BASE_MODEM (self),
+ invocation,
+ MM_AUTHORIZATION_DEVICE_CONTROL,
+ (GAsyncReadyCallback)handle_inject_assistance_data_auth_ready,
+ ctx);
+ return TRUE;
+}
+
+/*****************************************************************************/
+
+typedef struct {
MmGdbusModemLocation *skeleton;
GDBusMethodInvocation *invocation;
MMIfaceModemLocation *self;
@@ -1447,6 +1549,8 @@ typedef enum {
INITIALIZATION_STEP_CAPABILITIES,
INITIALIZATION_STEP_VALIDATE_CAPABILITIES,
INITIALIZATION_STEP_SUPL_SERVER,
+ INITIALIZATION_STEP_SUPPORTED_ASSISTANCE_DATA,
+ INITIALIZATION_STEP_ASSISTANCE_DATA_SERVERS,
INITIALIZATION_STEP_GPS_REFRESH_RATE,
INITIALIZATION_STEP_LAST
} InitializationStep;
@@ -1465,6 +1569,55 @@ initialization_context_free (InitializationContext *ctx)
}
static void
+load_assistance_data_servers_ready (MMIfaceModemLocation *self,
+ GAsyncResult *res,
+ GTask *task)
+{
+ GError *error = NULL;
+ InitializationContext *ctx;
+ gchar **servers;
+
+ ctx = g_task_get_task_data (task);
+
+ servers = MM_IFACE_MODEM_LOCATION_GET_INTERFACE (self)->load_assistance_data_servers_finish (self, res, &error);
+ if (error) {
+ mm_warn ("couldn't load assistance data servers: '%s'", error->message);
+ g_error_free (error);
+ }
+
+ mm_gdbus_modem_location_set_assistance_data_servers (ctx->skeleton, (const gchar *const *)servers);
+ g_strfreev (servers);
+
+ /* Go on to next step */
+ ctx->step++;
+ interface_initialization_step (task);
+}
+
+static void
+load_supported_assistance_data_ready (MMIfaceModemLocation *self,
+ GAsyncResult *res,
+ GTask *task)
+{
+ GError *error = NULL;
+ MMModemLocationAssistanceDataType mask;
+ InitializationContext *ctx;
+
+ ctx = g_task_get_task_data (task);
+
+ mask = MM_IFACE_MODEM_LOCATION_GET_INTERFACE (self)->load_supported_assistance_data_finish (self, res, &error);
+ if (error) {
+ mm_warn ("couldn't load supported assistance data types: '%s'", error->message);
+ g_error_free (error);
+ }
+
+ mm_gdbus_modem_location_set_supported_assistance_data (ctx->skeleton, (guint32) mask);
+
+ /* Go on to next step */
+ ctx->step++;
+ interface_initialization_step (task);
+}
+
+static void
load_supl_server_ready (MMIfaceModemLocation *self,
GAsyncResult *res,
GTask *task)
@@ -1576,6 +1729,36 @@ interface_initialization_step (GTask *task)
/* Fall down to next step */
ctx->step++;
+ case INITIALIZATION_STEP_SUPPORTED_ASSISTANCE_DATA:
+ /* If the modem supports any GPS-related technology, check assistance data types supported */
+ if ((ctx->capabilities & (MM_MODEM_LOCATION_SOURCE_AGPS |
+ MM_MODEM_LOCATION_SOURCE_GPS_RAW |
+ MM_MODEM_LOCATION_SOURCE_GPS_NMEA)) &&
+ MM_IFACE_MODEM_LOCATION_GET_INTERFACE (self)->load_supported_assistance_data &&
+ MM_IFACE_MODEM_LOCATION_GET_INTERFACE (self)->load_supported_assistance_data_finish) {
+ MM_IFACE_MODEM_LOCATION_GET_INTERFACE (self)->load_supported_assistance_data (
+ self,
+ (GAsyncReadyCallback)load_supported_assistance_data_ready,
+ task);
+ return;
+ }
+ /* Fall down to next step */
+ ctx->step++;
+
+ case INITIALIZATION_STEP_ASSISTANCE_DATA_SERVERS:
+ /* If any assistance data supported, load servers */
+ if ((mm_gdbus_modem_location_get_supported_assistance_data (ctx->skeleton) != MM_MODEM_LOCATION_ASSISTANCE_DATA_TYPE_NONE) &&
+ MM_IFACE_MODEM_LOCATION_GET_INTERFACE (self)->load_assistance_data_servers &&
+ MM_IFACE_MODEM_LOCATION_GET_INTERFACE (self)->load_assistance_data_servers_finish) {
+ MM_IFACE_MODEM_LOCATION_GET_INTERFACE (self)->load_assistance_data_servers (
+ self,
+ (GAsyncReadyCallback)load_assistance_data_servers_ready,
+ task);
+ return;
+ }
+ /* Fall down to next step */
+ ctx->step++;
+
case INITIALIZATION_STEP_GPS_REFRESH_RATE:
/* If we have GPS capabilities, expose the GPS refresh rate */
if (ctx->capabilities & ((MM_MODEM_LOCATION_SOURCE_GPS_RAW |
@@ -1599,6 +1782,10 @@ interface_initialization_step (GTask *task)
G_CALLBACK (handle_set_supl_server),
self);
g_signal_connect (ctx->skeleton,
+ "handle-inject-assistance-data",
+ G_CALLBACK (handle_inject_assistance_data),
+ self);
+ g_signal_connect (ctx->skeleton,
"handle-set-gps-refresh-rate",
G_CALLBACK (handle_set_gps_refresh_rate),
self);
@@ -1646,6 +1833,7 @@ mm_iface_modem_location_initialize (MMIfaceModemLocation *self,
/* Set all initial property defaults */
mm_gdbus_modem_location_set_capabilities (skeleton, MM_MODEM_LOCATION_SOURCE_NONE);
+ mm_gdbus_modem_location_set_supported_assistance_data (skeleton, MM_MODEM_LOCATION_ASSISTANCE_DATA_TYPE_NONE);
mm_gdbus_modem_location_set_enabled (skeleton, MM_MODEM_LOCATION_SOURCE_NONE);
mm_gdbus_modem_location_set_signals_location (skeleton, FALSE);
mm_gdbus_modem_location_set_location (skeleton,
diff --git a/src/mm-iface-modem-location.h b/src/mm-iface-modem-location.h
index e49fd79c..9128f1e2 100644
--- a/src/mm-iface-modem-location.h
+++ b/src/mm-iface-modem-location.h
@@ -50,6 +50,22 @@ struct _MMIfaceModemLocation {
GAsyncResult *res,
GError **error);
+ /* Loading of the AssistanceDataServers property */
+ void (* load_assistance_data_servers) (MMIfaceModemLocation *self,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ gchar ** (* load_assistance_data_servers_finish) (MMIfaceModemLocation *self,
+ GAsyncResult *res,
+ GError **error);
+
+ /* Loading of the SupportedAssistanceData property */
+ void (* load_supported_assistance_data) (MMIfaceModemLocation *self,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ MMModemLocationAssistanceDataType (* load_supported_assistance_data_finish) (MMIfaceModemLocation *self,
+ GAsyncResult *res,
+ GError **error);
+
/* Enable location gathering (async) */
void (* enable_location_gathering) (MMIfaceModemLocation *self,
MMModemLocationSource source,
@@ -76,6 +92,16 @@ struct _MMIfaceModemLocation {
gboolean (*set_supl_server_finish) (MMIfaceModemLocation *self,
GAsyncResult *res,
GError **error);
+
+ /* Inject assistance data (async) */
+ void (* inject_assistance_data) (MMIfaceModemLocation *self,
+ const guint8 *data,
+ gsize data_size,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ gboolean (*inject_assistance_data_finish) (MMIfaceModemLocation *self,
+ GAsyncResult *res,
+ GError **error);
};
GType mm_iface_modem_location_get_type (void);