diff options
-rw-r--r-- | cli/mmcli-modem-location.c | 162 | ||||
-rw-r--r-- | docs/reference/api/ModemManager-sections.txt | 1 | ||||
-rw-r--r-- | docs/reference/libmm-glib/libmm-glib-sections.txt | 14 | ||||
-rw-r--r-- | include/ModemManager-enums.h | 12 | ||||
-rw-r--r-- | introspection/org.freedesktop.ModemManager1.Modem.Location.xml | 34 | ||||
-rw-r--r-- | libmm-glib/mm-modem-location.c | 153 | ||||
-rw-r--r-- | libmm-glib/mm-modem-location.h | 20 | ||||
-rw-r--r-- | src/mm-iface-modem-location.c | 188 | ||||
-rw-r--r-- | src/mm-iface-modem-location.h | 26 |
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); |