aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@lanedo.com>2012-03-26 19:24:25 +0200
committerAleksander Morgado <aleksander@lanedo.com>2012-03-29 09:17:53 +0200
commitceefa2c356ae270c7dda4b5e771d225502d4913d (patch)
tree5caa9ef50a9d633d00a91a371f165b0af72acd86
parent090e3492095cf6d663bfb3f83b3ed0cb19121f1a (diff)
location: rework to allow multiple location sources
Location sources can now be enabled or disabled by using the mask of sources given in Setup() (similar previous Enable()).
-rw-r--r--cli/mmcli-modem-location.c77
-rw-r--r--introspection/org.freedesktop.ModemManager1.Modem.Location.xml25
-rw-r--r--libmm-glib/mm-modem-location.c87
-rw-r--r--libmm-glib/mm-modem-location.h39
-rw-r--r--src/mm-iface-modem-location.c515
-rw-r--r--src/mm-iface-modem-location.h2
6 files changed, 478 insertions, 267 deletions
diff --git a/cli/mmcli-modem-location.c b/cli/mmcli-modem-location.c
index 22e7aa1a..d4f8b171 100644
--- a/cli/mmcli-modem-location.c
+++ b/cli/mmcli-modem-location.c
@@ -16,6 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright (C) 2012 Google, Inc.
+ * Copyright (C) 2012 Lanedo GmbH <aleksander@lanedo.com>
*/
#include "config.h"
@@ -43,17 +44,17 @@ typedef struct {
static Context *ctx;
/* Options */
-static gboolean enable_flag;
-static gboolean disable_flag;
+static gboolean enable_3gpp_flag;
+static gboolean disable_3gpp_flag;
static gboolean get_3gpp_flag;
static GOptionEntry entries[] = {
- { "location-enable", 0, 0, G_OPTION_ARG_NONE, &enable_flag,
- "Enable location gathering.",
+ { "location-enable-3gpp", 0, 0, G_OPTION_ARG_NONE, &enable_3gpp_flag,
+ "Enable 3GPP location gathering.",
NULL
},
- { "location-disable", 0, 0, G_OPTION_ARG_NONE, &disable_flag,
- "Disable location gathering.",
+ { "location-disable-3gpp", 0, 0, G_OPTION_ARG_NONE, &disable_3gpp_flag,
+ "Disable 3GPP location gathering.",
NULL
},
{ "location-get-3gpp", 0, 0, G_OPTION_ARG_NONE, &get_3gpp_flag,
@@ -87,8 +88,8 @@ mmcli_modem_location_options_enabled (void)
if (checked)
return !!n_actions;
- n_actions = (enable_flag +
- disable_flag +
+ n_actions = (enable_3gpp_flag +
+ disable_3gpp_flag +
get_3gpp_flag);
if (n_actions > 1) {
@@ -159,7 +160,7 @@ enable_ready (MMModemLocation *modem_location,
gboolean operation_result;
GError *error = NULL;
- operation_result = mm_modem_location_enable_finish (modem_location, result, &error);
+ operation_result = mm_modem_location_setup_finish (modem_location, result, &error);
enable_process_reply (operation_result, error);
mmcli_async_operation_done ();
@@ -185,7 +186,7 @@ disable_ready (MMModemLocation *modem_location,
gboolean operation_result;
GError *error = NULL;
- operation_result = mm_modem_location_disable_finish (modem_location, result, &error);
+ operation_result = mm_modem_location_setup_finish (modem_location, result, &error);
disable_process_reply (operation_result, error);
mmcli_async_operation_done ();
@@ -238,24 +239,28 @@ get_modem_ready (GObject *source,
ensure_modem_location ();
/* Request to enable location gathering? */
- if (enable_flag) {
- g_debug ("Asynchronously enabling location gathering...");
-
- mm_modem_location_enable (ctx->modem_location,
- ctx->cancellable,
- (GAsyncReadyCallback)enable_ready,
- NULL);
+ if (enable_3gpp_flag) {
+ g_debug ("Asynchronously enabling 3GPP location gathering...");
+
+ mm_modem_location_setup (ctx->modem_location,
+ mm_modem_location_get_capabilities (ctx->modem_location) | MM_MODEM_LOCATION_SOURCE_3GPP_LAC_CI,
+ mm_modem_location_signals_location (ctx->modem_location),
+ ctx->cancellable,
+ (GAsyncReadyCallback)enable_ready,
+ NULL);
return;
}
/* Request to disable location gathering? */
- if (disable_flag) {
- g_debug ("Asynchronously enabling location gathering...");
-
- mm_modem_location_disable (ctx->modem_location,
- ctx->cancellable,
- (GAsyncReadyCallback)disable_ready,
- NULL);
+ if (disable_3gpp_flag) {
+ g_debug ("Asynchronously disabling 3GPP location gathering...");
+
+ mm_modem_location_setup (ctx->modem_location,
+ mm_modem_location_get_capabilities (ctx->modem_location) & ~MM_MODEM_LOCATION_SOURCE_3GPP_LAC_CI,
+ mm_modem_location_signals_location (ctx->modem_location),
+ ctx->cancellable,
+ (GAsyncReadyCallback)disable_ready,
+ NULL);
return;
}
@@ -305,27 +310,31 @@ mmcli_modem_location_run_synchronous (GDBusConnection *connection)
ensure_modem_location ();
/* Request to enable location gathering? */
- if (enable_flag) {
+ if (enable_3gpp_flag) {
gboolean result;
- g_debug ("Asynchronously enabling location gathering...");
+ g_debug ("Asynchronously enabling 3GPP location gathering...");
- result = mm_modem_location_enable_sync (ctx->modem_location,
- NULL,
- &error);
+ result = mm_modem_location_setup_sync (ctx->modem_location,
+ mm_modem_location_get_capabilities (ctx->modem_location) | MM_MODEM_LOCATION_SOURCE_3GPP_LAC_CI,
+ mm_modem_location_signals_location (ctx->modem_location),
+ NULL,
+ &error);
enable_process_reply (result, error);
return;
}
/* Request to disable location gathering? */
- if (disable_flag) {
+ if (disable_3gpp_flag) {
gboolean result;
- g_debug ("Asynchronously enabling location gathering...");
+ g_debug ("Asynchronously disabling 3GPP location gathering...");
- result = mm_modem_location_disable_sync (ctx->modem_location,
- NULL,
- &error);
+ result = mm_modem_location_setup_sync (ctx->modem_location,
+ mm_modem_location_get_capabilities (ctx->modem_location) & ~MM_MODEM_LOCATION_SOURCE_3GPP_LAC_CI,
+ mm_modem_location_signals_location (ctx->modem_location),
+ NULL,
+ &error);
disable_process_reply (result, error);
return;
}
diff --git a/introspection/org.freedesktop.ModemManager1.Modem.Location.xml b/introspection/org.freedesktop.ModemManager1.Modem.Location.xml
index 4673a28a..b19283e1 100644
--- a/introspection/org.freedesktop.ModemManager1.Modem.Location.xml
+++ b/introspection/org.freedesktop.ModemManager1.Modem.Location.xml
@@ -23,12 +23,13 @@
<interface name="org.freedesktop.ModemManager1.Modem.Location">
<!--
- Enable:
- @enable: %TRUE to enable location information gathering, %FALSE to disable.
+ Setup:
+ @sources: Bitmask of <link linkend="MMModemLocationSource">MMModemLocationSource</link> flags, specifying which sources should get enabled or disabled. <link linkend="MM-MODEM-LOCATION-SOURCE-NONE:CAPS">MM_MODEM_LOCATION_SOURCE_NONE</link> will disable all location gathering.
@signal_location: Flag to control whether the device emits signals with the new location information. This argument is ignored when disabling location information gathering.
- Enable or disable location information gathering. This method may
- require the client to authenticate itself.
+ Configure the location sources to use when gathering location
+ information. Also enable or disable location information gathering.
+ This method may require the client to authenticate itself.
When signals are emitted, any client application (including malicious
ones!) can listen for location updates unless D-Bus permissions restrict
@@ -40,8 +41,8 @@
) to get
location information.
-->
- <method name="Enable">
- <arg name="enable" type="b" direction="in" />
+ <method name="Setup">
+ <arg name="sources" type="u" direction="in" />
<arg name="signal_location" type="b" direction="in" />
</method>
@@ -64,18 +65,18 @@
Capabilities:
Bitmask of <link linkend="MMModemLocationSource">MMModemLocationSource</link>
- values, specifying the location retrieval capabilities of the device.
+ values, specifying the supported location sources.
-->
<property name="Capabilities" type="u" access="read" />
<!--
Enabled:
- %TRUE if location information gathering is enabled for this device,
- %FALSE if it is disabled. When disabled, the device will not provide
- location information.
+ Bitmask specifying which of the supported
+ <link linkend="MMModemLocationSource">MMModemLocationSource</link>
+ location sources is currently enabled in the device.
-->
- <property name="Enabled" type="b" access="read" />
+ <property name="Enabled" type="u" access="read" />
<!--
SignalsLocation:
@@ -84,7 +85,7 @@
location updates will not be emitted.
See the
- <link linkend="gdbus-method-org-freedesktop-ModemManager1-Modem-Location.Enable">Enable()</link>
+ <link linkend="gdbus-method-org-freedesktop-ModemManager1-Modem-Location.Setup">Setup()</link>
method for more information.
-->
<property name="SignalsLocation" type="b" access="read" />
diff --git a/libmm-glib/mm-modem-location.c b/libmm-glib/mm-modem-location.c
index c800fa3b..4f88d7ee 100644
--- a/libmm-glib/mm-modem-location.c
+++ b/libmm-glib/mm-modem-location.c
@@ -18,6 +18,7 @@
* Boston, MA 02110-1301 USA.
*
* Copyright (C) 2012 Google, Inc.
+ * Copyright (C) 2012 Lanedo GmbH <aleksander@lanedo.com>
*/
#include <gio/gio.h>
@@ -72,92 +73,64 @@ mm_modem_location_get_capabilities (MMModemLocation *self)
return (MMModemLocationSource) mm_gdbus_modem_location_get_capabilities (self);
}
-gboolean
+MMModemLocationSource
mm_modem_location_get_enabled (MMModemLocation *self)
{
g_return_val_if_fail (MM_GDBUS_IS_MODEM_LOCATION (self), FALSE);
- return mm_gdbus_modem_location_get_enabled (self);
+ return (MMModemLocationSource) mm_gdbus_modem_location_get_enabled (self);
}
gboolean
-mm_modem_location_disable_finish (MMModemLocation *self,
- GAsyncResult *res,
- GError **error)
+mm_modem_location_signals_location (MMModemLocation *self)
{
g_return_val_if_fail (MM_GDBUS_IS_MODEM_LOCATION (self), FALSE);
- return mm_gdbus_modem_location_call_enable_finish (self, res, error);
-}
-
-void
-mm_modem_location_disable (MMModemLocation *self,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- g_return_if_fail (MM_GDBUS_IS_MODEM_LOCATION (self));
-
- mm_gdbus_modem_location_call_enable (self,
- FALSE,
- FALSE,
- cancellable,
- callback,
- user_data);
+ return mm_gdbus_modem_location_get_signals_location (self);
}
gboolean
-mm_modem_location_disable_sync (MMModemLocation *self,
- GCancellable *cancellable,
+mm_modem_location_setup_finish (MMModemLocation *self,
+ GAsyncResult *res,
GError **error)
{
g_return_val_if_fail (MM_GDBUS_IS_MODEM_LOCATION (self), FALSE);
- return mm_gdbus_modem_location_call_enable_sync (self,
- FALSE,
- FALSE,
- cancellable,
- error);
-}
-
-gboolean
-mm_modem_location_enable_finish (MMModemLocation *self,
- GAsyncResult *res,
- GError **error)
-{
- g_return_val_if_fail (MM_GDBUS_IS_MODEM_LOCATION (self), FALSE);
-
- return mm_gdbus_modem_location_call_enable_finish (self, res, error);
+ return mm_gdbus_modem_location_call_setup_finish (self, res, error);
}
void
-mm_modem_location_enable (MMModemLocation *self,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
+mm_modem_location_setup (MMModemLocation *self,
+ MMModemLocationSource sources,
+ gboolean signal_location,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
g_return_if_fail (MM_GDBUS_IS_MODEM_LOCATION (self));
- mm_gdbus_modem_location_call_enable (self,
- TRUE,
- FALSE /* signal_location */,
- cancellable,
- callback,
- user_data);
+ mm_gdbus_modem_location_call_setup (self,
+ sources,
+ signal_location,
+ cancellable,
+ callback,
+ user_data);
}
gboolean
-mm_modem_location_enable_sync (MMModemLocation *self,
- GCancellable *cancellable,
- GError **error)
+mm_modem_location_setup_sync (MMModemLocation *self,
+ MMModemLocationSource sources,
+ gboolean signal_location,
+ GCancellable *cancellable,
+ GError **error)
{
g_return_val_if_fail (MM_GDBUS_IS_MODEM_LOCATION (self), FALSE);
- return mm_gdbus_modem_location_call_enable_sync (self,
- TRUE,
- FALSE /* signal_location */,
- cancellable,
- error);
+ return mm_gdbus_modem_location_call_setup_sync (self,
+ sources,
+ signal_location,
+ cancellable,
+ error);
}
static MMLocation3gpp *
diff --git a/libmm-glib/mm-modem-location.h b/libmm-glib/mm-modem-location.h
index b92040db..216704c0 100644
--- a/libmm-glib/mm-modem-location.h
+++ b/libmm-glib/mm-modem-location.h
@@ -18,6 +18,7 @@
* Boston, MA 02110-1301 USA.
*
* Copyright (C) 2012 Google, Inc.
+ * Copyright (C) 2012 Lanedo GmbH <aleksander@lanedo.com>
*/
#ifndef _MM_MODEM_LOCATION_H_
@@ -37,29 +38,23 @@ const gchar *mm_modem_location_get_path (MMModemLocation *self);
gchar *mm_modem_location_dup_path (MMModemLocation *self);
MMModemLocationSource mm_modem_location_get_capabilities (MMModemLocation *self);
-gboolean mm_modem_location_get_enabled (MMModemLocation *self);
+MMModemLocationSource mm_modem_location_get_enabled (MMModemLocation *self);
+gboolean mm_modem_location_signals_location (MMModemLocation *self);
-void mm_modem_location_enable (MMModemLocation *self,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-gboolean mm_modem_location_enable_finish (MMModemLocation *self,
- GAsyncResult *res,
- GError **error);
-gboolean mm_modem_location_enable_sync (MMModemLocation *self,
- GCancellable *cancellable,
- GError **error);
-
-void mm_modem_location_disable (MMModemLocation *self,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-gboolean mm_modem_location_disable_finish (MMModemLocation *self,
- GAsyncResult *res,
- GError **error);
-gboolean mm_modem_location_disable_sync (MMModemLocation *self,
- GCancellable *cancellable,
- GError **error);
+void mm_modem_location_setup (MMModemLocation *self,
+ MMModemLocationSource sources,
+ gboolean signal_location,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean mm_modem_location_setup_finish (MMModemLocation *self,
+ GAsyncResult *res,
+ GError **error);
+gboolean mm_modem_location_setup_sync (MMModemLocation *self,
+ MMModemLocationSource sources,
+ gboolean signal_location,
+ GCancellable *cancellable,
+ GError **error);
void mm_modem_location_get_3gpp (MMModemLocation *self,
GCancellable *cancellable,
diff --git a/src/mm-iface-modem-location.c b/src/mm-iface-modem-location.c
index 2003943d..dc5e0805 100644
--- a/src/mm-iface-modem-location.c
+++ b/src/mm-iface-modem-location.c
@@ -11,6 +11,7 @@
* GNU General Public License for more details:
*
* Copyright (C) 2012 Google, Inc.
+ * Copyright (C) 2012 Lanedo GmbH <aleksander@lanedo.com>
*/
#include <ModemManager.h>
@@ -141,12 +142,10 @@ mm_iface_modem_location_3gpp_update_mcc_mnc (MMIfaceModemLocation *self,
MM_IFACE_MODEM_LOCATION_DBUS_SKELETON, &skeleton,
NULL);
- if (mm_gdbus_modem_location_get_enabled (skeleton)) {
+ if (mm_gdbus_modem_location_get_enabled (skeleton) & MM_MODEM_LOCATION_SOURCE_3GPP_LAC_CI) {
guint changed = 0;
- if (G_UNLIKELY (!ctx->location_3gpp))
- ctx->location_3gpp = mm_location_3gpp_new ();
-
+ g_assert (ctx->location_3gpp != NULL);
changed += mm_location_3gpp_set_mobile_country_code (ctx->location_3gpp,
mobile_country_code);
changed += mm_location_3gpp_set_mobile_network_code (ctx->location_3gpp,
@@ -171,12 +170,10 @@ mm_iface_modem_location_3gpp_update_lac_ci (MMIfaceModemLocation *self,
MM_IFACE_MODEM_LOCATION_DBUS_SKELETON, &skeleton,
NULL);
- if (mm_gdbus_modem_location_get_enabled (skeleton)) {
+ if (mm_gdbus_modem_location_get_enabled (skeleton) & MM_MODEM_LOCATION_SOURCE_3GPP_LAC_CI) {
guint changed = 0;
- if (G_UNLIKELY (!ctx->location_3gpp))
- ctx->location_3gpp = mm_location_3gpp_new ();
-
+ g_assert (ctx->location_3gpp != NULL);
changed += mm_location_3gpp_set_location_area_code (ctx->location_3gpp,
location_area_code);
changed += mm_location_3gpp_set_cell_id (ctx->location_3gpp,
@@ -199,12 +196,10 @@ mm_iface_modem_location_3gpp_clear (MMIfaceModemLocation *self)
MM_IFACE_MODEM_LOCATION_DBUS_SKELETON, &skeleton,
NULL);
- if (mm_gdbus_modem_location_get_enabled (skeleton)) {
+ if (mm_gdbus_modem_location_get_enabled (skeleton) & MM_MODEM_LOCATION_SOURCE_3GPP_LAC_CI) {
guint changed = 0;
- if (G_UNLIKELY (!ctx->location_3gpp))
- ctx->location_3gpp = mm_location_3gpp_new ();
-
+ g_assert (ctx->location_3gpp != NULL);
changed += mm_location_3gpp_set_location_area_code (ctx->location_3gpp, 0);
changed += mm_location_3gpp_set_cell_id (ctx->location_3gpp, 0);
changed += mm_location_3gpp_set_mobile_country_code (ctx->location_3gpp, 0);
@@ -218,164 +213,394 @@ mm_iface_modem_location_3gpp_clear (MMIfaceModemLocation *self)
/*****************************************************************************/
+static void
+update_location_source_status (MMIfaceModemLocation *self,
+ MMModemLocationSource source,
+ gboolean enabled)
+{
+ MMModemLocationSource mask;
+ MmGdbusModemLocation *skeleton = NULL;
+ LocationContext *ctx;
+
+ g_object_get (self,
+ MM_IFACE_MODEM_LOCATION_DBUS_SKELETON, &skeleton,
+ NULL);
+ g_assert (skeleton != NULL);
+
+ /* Update status in the interface */
+ mask = mm_gdbus_modem_location_get_enabled (skeleton);
+ if (enabled)
+ mask |= source;
+ else
+ mask &= ~source;
+
+ /* Update status in the context */
+ ctx = get_location_context (self);
+
+ switch (source) {
+ case MM_MODEM_LOCATION_SOURCE_3GPP_LAC_CI:
+ if (enabled) {
+ if (!ctx->location_3gpp)
+ ctx->location_3gpp = mm_location_3gpp_new ();
+ } else
+ g_clear_object (&ctx->location_3gpp);
+ break;
+ default:
+ break;
+ }
+
+ mm_gdbus_modem_location_set_enabled (skeleton, mask);
+
+ g_object_unref (skeleton);
+}
+
+/*****************************************************************************/
+
typedef struct {
- MmGdbusModemLocation *skeleton;
- GDBusMethodInvocation *invocation;
MMIfaceModemLocation *self;
- gboolean enable;
- gboolean signal_location;
-} HandleEnableContext;
+ MmGdbusModemLocation *skeleton;
+ GSimpleAsyncResult *result;
+ MMModemLocationSource to_enable;
+ MMModemLocationSource to_disable;
+ MMModemLocationSource current;
+} SetupGatheringContext;
+
+static void setup_gathering_step (SetupGatheringContext *ctx);
static void
-handle_enable_context_free (HandleEnableContext *ctx)
+setup_gathering_context_complete_and_free (SetupGatheringContext *ctx)
{
+ g_simple_async_result_complete_in_idle (ctx->result);
+ g_object_unref (ctx->result);
g_object_unref (ctx->skeleton);
- g_object_unref (ctx->invocation);
g_object_unref (ctx->self);
g_free (ctx);
}
+static gboolean
+setup_gathering_finish (MMIfaceModemLocation *self,
+ GAsyncResult *res,
+ GError **error)
+{
+ return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
+}
+
static void
enable_location_gathering_ready (MMIfaceModemLocation *self,
GAsyncResult *res,
- HandleEnableContext *ctx)
+ SetupGatheringContext *ctx)
{
GError *error = NULL;
- if (!MM_IFACE_MODEM_LOCATION_GET_INTERFACE (self)->enable_location_gathering_finish (self, res, &error))
- g_dbus_method_invocation_take_error (ctx->invocation, error);
- else {
- mm_gdbus_modem_location_set_enabled (ctx->skeleton, TRUE);
- mm_gdbus_modem_location_complete_enable (ctx->skeleton,
- ctx->invocation);
+ if (!MM_IFACE_MODEM_LOCATION_GET_INTERFACE (self)->enable_location_gathering_finish (self, res, &error)) {
+ gchar *str;
+
+ str = mm_modem_location_source_build_string_from_mask (ctx->current);
+ g_prefix_error (&error,
+ "Couldn't enable location '%s' gathering: ",
+ str);
+ g_simple_async_result_take_error (ctx->result, error);
+ setup_gathering_context_complete_and_free (ctx);
+ g_free (str);
+ return;
}
- handle_enable_context_free (ctx);
+ update_location_source_status (self, ctx->current, TRUE);
+
+ /* Keep on with next ones... */
+ ctx->current = ctx->current << 1;
+ setup_gathering_step (ctx);
}
static void
disable_location_gathering_ready (MMIfaceModemLocation *self,
GAsyncResult *res,
- HandleEnableContext *ctx)
+ SetupGatheringContext *ctx)
{
GError *error = NULL;
- if (!MM_IFACE_MODEM_LOCATION_GET_INTERFACE (self)->disable_location_gathering_finish (self, res, &error))
- g_dbus_method_invocation_take_error (ctx->invocation, error);
- else {
- clear_location_context (self);
- mm_gdbus_modem_location_set_enabled (ctx->skeleton, FALSE);
- mm_gdbus_modem_location_complete_enable (ctx->skeleton,
- ctx->invocation);
+ if (!MM_IFACE_MODEM_LOCATION_GET_INTERFACE (self)->disable_location_gathering_finish (self, res, &error)) {
+ gchar *str;
+
+ str = mm_modem_location_source_build_string_from_mask (ctx->current);
+ g_prefix_error (&error,
+ "Couldn't disable location '%s' gathering: ",
+ str);
+ g_simple_async_result_take_error (ctx->result, error);
+ setup_gathering_context_complete_and_free (ctx);
+ g_free (str);
+ return;
}
- handle_enable_context_free (ctx);
+ update_location_source_status (self, ctx->current, FALSE);
+
+ /* Keep on with next ones... */
+ ctx->current = ctx->current << 1;
+ setup_gathering_step (ctx);
}
static void
-handle_enable_auth_ready (MMBaseModem *self,
- GAsyncResult *res,
- HandleEnableContext *ctx)
+setup_gathering_step (SetupGatheringContext *ctx)
{
- GError *error = NULL;
-
- if (!mm_base_modem_authorize_finish (self, res, &error)) {
- g_dbus_method_invocation_take_error (ctx->invocation, error);
- handle_enable_context_free (ctx);
+ /* Are we done? */
+ if (ctx->to_enable == MM_MODEM_LOCATION_SOURCE_NONE &&
+ ctx->to_disable == MM_MODEM_LOCATION_SOURCE_NONE) {
+ g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
+ setup_gathering_context_complete_and_free (ctx);
return;
}
- /* Enabling */
- if (ctx->enable) {
- LocationContext *location_ctx;
-
- location_ctx = get_location_context (ctx->self);
- mm_dbg ("Enabling location gathering%s...",
- ctx->signal_location ? " (with signaling)" : "");
-
- /* Update the new signal location value */
- if (mm_gdbus_modem_location_get_signals_location (ctx->skeleton) != ctx->signal_location) {
- mm_dbg ("%s location signaling",
- ctx->signal_location ? "Enabling" : "Disabling");
- mm_gdbus_modem_location_set_signals_location (ctx->skeleton,
- ctx->signal_location);
- mm_gdbus_modem_location_set_location (ctx->skeleton,
- build_location_dictionary (ctx->signal_location ?
- location_ctx->location_3gpp :
- NULL));
+ while (ctx->current <= MM_MODEM_LOCATION_SOURCE_GPS_NMEA) {
+ gchar *source_str;
+
+ if (ctx->to_enable & ctx->current) {
+ /* Remove from mask */
+ ctx->to_enable &= ~ctx->current;
+
+ /* Plugins can run custom actions to enable location gathering */
+ if (MM_IFACE_MODEM_LOCATION_GET_INTERFACE (ctx->self)->enable_location_gathering &&
+ MM_IFACE_MODEM_LOCATION_GET_INTERFACE (ctx->self)->enable_location_gathering_finish) {
+ MM_IFACE_MODEM_LOCATION_GET_INTERFACE (ctx->self)->enable_location_gathering (
+ MM_IFACE_MODEM_LOCATION (ctx->self),
+ ctx->current,
+ (GAsyncReadyCallback)enable_location_gathering_ready,
+ ctx);
+ return;
+ }
+
+ update_location_source_status (ctx->self, ctx->current, TRUE);
+
+ source_str = mm_modem_location_source_build_string_from_mask (ctx->current);
+ mm_dbg ("Enabled location '%s' gathering...", source_str);
+ g_free (source_str);
+ } else if (ctx->to_disable & ctx->current) {
+ /* Remove from mask */
+ ctx->to_disable &= ~ctx->current;
+
+ /* Plugins can run custom actions to disable location gathering */
+ if (MM_IFACE_MODEM_LOCATION_GET_INTERFACE (ctx->self)->disable_location_gathering &&
+ MM_IFACE_MODEM_LOCATION_GET_INTERFACE (ctx->self)->disable_location_gathering_finish) {
+ MM_IFACE_MODEM_LOCATION_GET_INTERFACE (ctx->self)->disable_location_gathering (
+ MM_IFACE_MODEM_LOCATION (ctx->self),
+ ctx->current,
+ (GAsyncReadyCallback)disable_location_gathering_ready,
+ ctx);
+ return;
+ }
+
+ update_location_source_status (ctx->self, ctx->current, FALSE);
+
+ source_str = mm_modem_location_source_build_string_from_mask (ctx->current);
+ mm_dbg ("Disabled location '%s' gathering...", source_str);
+ g_free (source_str);
}
- /* If already enabled, just done */
- if (mm_gdbus_modem_location_get_enabled (ctx->skeleton)) {
- mm_gdbus_modem_location_complete_enable (ctx->skeleton, ctx->invocation);
- handle_enable_context_free (ctx);
- return;
- }
+ /* go on... */
+ ctx->current = ctx->current << 1;
+ }
- /* Plugins can run custom actions to enable location gathering */
- if (MM_IFACE_MODEM_LOCATION_GET_INTERFACE (self)->enable_location_gathering &&
- MM_IFACE_MODEM_LOCATION_GET_INTERFACE (self)->enable_location_gathering_finish) {
- MM_IFACE_MODEM_LOCATION_GET_INTERFACE (self)->enable_location_gathering (
- MM_IFACE_MODEM_LOCATION (self),
- (GAsyncReadyCallback)enable_location_gathering_ready,
- ctx);
- return;
+ /* We just need to finish now */
+ g_assert (ctx->to_enable == MM_MODEM_LOCATION_SOURCE_NONE);
+ g_assert (ctx->to_disable == MM_MODEM_LOCATION_SOURCE_NONE);
+ setup_gathering_step (ctx);
+}
+
+static void
+setup_gathering (MMIfaceModemLocation *self,
+ MMModemLocationSource mask,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ SetupGatheringContext *ctx;
+ MMModemLocationSource currently_enabled;
+ MMModemLocationSource source;
+ gchar *str;
+
+ ctx = g_new (SetupGatheringContext, 1);
+ ctx->self = g_object_ref (self);
+ ctx->result = g_simple_async_result_new (G_OBJECT (self),
+ callback,
+ user_data,
+ setup_gathering);
+ g_object_get (self,
+ MM_IFACE_MODEM_LOCATION_DBUS_SKELETON, &ctx->skeleton,
+ NULL);
+ g_assert (ctx->skeleton != NULL);
+
+ /* Get current list of enabled sources */
+ currently_enabled = mm_gdbus_modem_location_get_enabled (ctx->skeleton);
+
+ /* Reset the list of sources to enable or disable */
+ ctx->to_enable = MM_MODEM_LOCATION_SOURCE_NONE;
+ ctx->to_disable = MM_MODEM_LOCATION_SOURCE_NONE;
+
+ /* Loop through all known bits in the bitmask to enable/disable specific location sources */
+ for (source = MM_MODEM_LOCATION_SOURCE_3GPP_LAC_CI;
+ source <= MM_MODEM_LOCATION_SOURCE_GPS_NMEA;
+ source = source << 1) {
+ /* skip unsupported sources */
+ if (!(mm_gdbus_modem_location_get_capabilities (ctx->skeleton) & source))
+ continue;
+
+ str = mm_modem_location_source_build_string_from_mask (source);
+
+ if (mask & source) {
+ /* Source set in mask, need to enable if disabled */
+ if (currently_enabled & source)
+ mm_dbg ("Location '%s' gathering is already enabled...", str);
+ else
+ ctx->to_enable |= source;
+ } else {
+ /* Source unset in mask, need to disable if enabled */
+ if (currently_enabled & source)
+ ctx->to_disable |= source;
+ else
+ mm_dbg ("Location '%s' gathering is already disabled...", str);
}
- /* If no plugin-specific setup needed or interface not yet enabled, just done */
- mm_gdbus_modem_location_set_enabled (ctx->skeleton, TRUE);
- mm_gdbus_modem_location_complete_enable (ctx->skeleton, ctx->invocation);
- handle_enable_context_free (ctx);
- return;
+ g_free (str);
+ }
+
+ if (ctx->to_enable != MM_MODEM_LOCATION_SOURCE_NONE) {
+ str = mm_modem_location_source_build_string_from_mask (ctx->to_enable);
+ mm_dbg ("Need to enable the following location sources: '%s'", str);
+ g_free (str);
+ }
+
+ if (ctx->to_disable != MM_MODEM_LOCATION_SOURCE_NONE) {
+ str = mm_modem_location_source_build_string_from_mask (ctx->to_disable);
+ mm_dbg ("Need to disable the following location sources: '%s'", str);
+ g_free (str);
}
- /* Disabling */
- mm_dbg ("Disabling location gathering...");
+ /* Start enabling/disabling location sources */
+ ctx->current = MM_MODEM_LOCATION_SOURCE_3GPP_LAC_CI;
+ setup_gathering_step (ctx);
+}
+
+/*****************************************************************************/
+
+typedef struct {
+ MmGdbusModemLocation *skeleton;
+ GDBusMethodInvocation *invocation;
+ MMIfaceModemLocation *self;
+ guint32 sources;
+ gboolean signal_location;
+} HandleSetupContext;
+
+static void
+handle_setup_context_free (HandleSetupContext *ctx)
+{
+ g_object_unref (ctx->skeleton);
+ g_object_unref (ctx->invocation);
+ g_object_unref (ctx->self);
+ g_free (ctx);
+}
+
+static void
+setup_gathering_ready (MMIfaceModemLocation *self,
+ GAsyncResult *res,
+ HandleSetupContext *ctx)
+{
+ GError *error = NULL;
+
+ if (!setup_gathering_finish (self, res, &error))
+ g_dbus_method_invocation_take_error (ctx->invocation, error);
+ else
+ mm_gdbus_modem_location_complete_setup (ctx->skeleton, ctx->invocation);
+
+ handle_setup_context_free (ctx);
+}
+
+static void
+handle_setup_auth_ready (MMBaseModem *self,
+ GAsyncResult *res,
+ HandleSetupContext *ctx)
+{
+ GError *error = NULL;
+ MMModemState modem_state;
+ MMModemLocationSource not_supported;
+ LocationContext *location_ctx;
+ gchar *str;
- /* If already disabled, just done */
- if (!mm_gdbus_modem_location_get_enabled (ctx->skeleton)) {
- mm_gdbus_modem_location_complete_enable (ctx->skeleton, ctx->invocation);
- handle_enable_context_free (ctx);
+ if (!mm_base_modem_authorize_finish (self, res, &error)) {
+ g_dbus_method_invocation_take_error (ctx->invocation, error);
+ handle_setup_context_free (ctx);
return;
}
- /* Plugins can run custom actions to disable location gathering */
- if (MM_IFACE_MODEM_LOCATION_GET_INTERFACE (self)->disable_location_gathering &&
- MM_IFACE_MODEM_LOCATION_GET_INTERFACE (self)->disable_location_gathering_finish) {
- MM_IFACE_MODEM_LOCATION_GET_INTERFACE (self)->disable_location_gathering (
- MM_IFACE_MODEM_LOCATION (self),
- (GAsyncReadyCallback)disable_location_gathering_ready,
- ctx);
+ modem_state = MM_MODEM_STATE_UNKNOWN;
+ g_object_get (self,
+ MM_IFACE_MODEM_STATE, &modem_state,
+ NULL);
+ if (modem_state < MM_MODEM_STATE_ENABLED) {
+ g_dbus_method_invocation_return_error (ctx->invocation,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_WRONG_STATE,
+ "Cannot setup location: "
+ "device not yet enabled");
+ handle_setup_context_free (ctx);
return;
}
- /* If no plugin-specific setup needed, or interface not yet enabled, just done */
- clear_location_context (ctx->self);
- mm_gdbus_modem_location_set_enabled (ctx->skeleton, FALSE);
- mm_gdbus_modem_location_complete_enable (ctx->skeleton, ctx->invocation);
- handle_enable_context_free (ctx);
+ /* If any of the location sources being enabled is NOT supported, set error */
+ not_supported = ((mm_gdbus_modem_location_get_capabilities (ctx->skeleton) ^ ctx->sources) & ctx->sources);
+ if (not_supported != MM_MODEM_LOCATION_SOURCE_NONE) {
+ str = mm_modem_location_source_build_string_from_mask (not_supported);
+ g_dbus_method_invocation_return_error (ctx->invocation,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_UNSUPPORTED,
+ "Cannot enable unsupported location sources: '%s'",
+ str);
+ handle_setup_context_free (ctx);
+ g_free (str);
+ return;
+ }
+
+ /* Enable/disable location signaling */
+ location_ctx = get_location_context (ctx->self);
+ if (mm_gdbus_modem_location_get_signals_location (ctx->skeleton) != ctx->signal_location) {
+ mm_dbg ("%s location signaling",
+ ctx->signal_location ? "Enabling" : "Disabling");
+ mm_gdbus_modem_location_set_signals_location (ctx->skeleton,
+ ctx->signal_location);
+ mm_gdbus_modem_location_set_location (ctx->skeleton,
+ build_location_dictionary (ctx->signal_location ?
+ location_ctx->location_3gpp :
+ NULL));
+ }
+
+ str = mm_modem_location_source_build_string_from_mask (ctx->sources);
+ mm_dbg ("Setting up location sources: '%s'", str);
+ g_free (str);
+
+ /* Go on to enable or disable the requested sources */
+ setup_gathering (ctx->self,
+ ctx->sources,
+ (GAsyncReadyCallback)setup_gathering_ready,
+ ctx);
}
static gboolean
-handle_enable (MmGdbusModemLocation *skeleton,
- GDBusMethodInvocation *invocation,
- gboolean enable,
- gboolean signal_location,
- MMIfaceModemLocation *self)
+handle_setup (MmGdbusModemLocation *skeleton,
+ GDBusMethodInvocation *invocation,
+ guint32 sources,
+ gboolean signal_location,
+ MMIfaceModemLocation *self)
{
- HandleEnableContext *ctx;
+ HandleSetupContext *ctx;
- ctx = g_new (HandleEnableContext, 1);
+ ctx = g_new (HandleSetupContext, 1);
ctx->skeleton = g_object_ref (skeleton);
ctx->invocation = g_object_ref (invocation);
ctx->self = g_object_ref (self);
- ctx->enable = enable;
+ ctx->sources = sources;
ctx->signal_location = signal_location;
mm_base_modem_authorize (MM_BASE_MODEM (self),
invocation,
MM_AUTHORIZATION_DEVICE_CONTROL,
- (GAsyncReadyCallback)handle_enable_auth_ready,
+ (GAsyncReadyCallback)handle_setup_auth_ready,
ctx);
return TRUE;
}
@@ -402,6 +627,7 @@ handle_get_location_auth_ready (MMBaseModem *self,
GAsyncResult *res,
HandleGetLocationContext *ctx)
{
+ MMModemState modem_state;
LocationContext *location_ctx;
GError *error = NULL;
@@ -411,6 +637,20 @@ handle_get_location_auth_ready (MMBaseModem *self,
return;
}
+ modem_state = MM_MODEM_STATE_UNKNOWN;
+ g_object_get (self,
+ MM_IFACE_MODEM_STATE, &modem_state,
+ NULL);
+ if (modem_state < MM_MODEM_STATE_ENABLED) {
+ g_dbus_method_invocation_return_error (ctx->invocation,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_WRONG_STATE,
+ "Cannot get location: "
+ "device not yet enabled");
+ handle_get_location_context_free (ctx);
+ return;
+ }
+
location_ctx = get_location_context (ctx->self);
mm_gdbus_modem_location_complete_get_location (
ctx->skeleton,
@@ -503,16 +743,12 @@ disabling_location_gathering_ready (MMIfaceModemLocation *self,
{
GError *error = NULL;
- if (!MM_IFACE_MODEM_LOCATION_GET_INTERFACE (self)->disable_location_gathering_finish (self,
- res,
- &error)) {
+ if (!setup_gathering_finish (self, res, &error)) {
g_simple_async_result_take_error (ctx->result, error);
disabling_context_complete_and_free (ctx);
return;
}
- mm_gdbus_modem_location_set_enabled (ctx->skeleton, FALSE);
-
/* Go on to next step */
ctx->step++;
interface_disabling_step (ctx);
@@ -527,20 +763,15 @@ interface_disabling_step (DisablingContext *ctx)
ctx->step++;
case DISABLING_STEP_DISABLE_GATHERING:
- if (mm_gdbus_modem_location_get_enabled (ctx->skeleton) &&
- MM_IFACE_MODEM_LOCATION_GET_INTERFACE (ctx->self)->disable_location_gathering &&
- MM_IFACE_MODEM_LOCATION_GET_INTERFACE (ctx->self)->disable_location_gathering_finish) {
- MM_IFACE_MODEM_LOCATION_GET_INTERFACE (ctx->self)->disable_location_gathering (
- ctx->self,
- (GAsyncReadyCallback)disabling_location_gathering_ready,
- ctx);
- return;
- }
- /* Fall down to next step */
- ctx->step++;
+ setup_gathering (ctx->self,
+ MM_MODEM_LOCATION_SOURCE_NONE,
+ (GAsyncReadyCallback)disabling_location_gathering_ready,
+ ctx);
+ return;
case DISABLING_STEP_LAST:
/* We are done without errors! */
+ clear_location_context (ctx->self);
g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
disabling_context_complete_and_free (ctx);
return;
@@ -642,9 +873,7 @@ enabling_location_gathering_ready (MMIfaceModemLocation *self,
{
GError *error = NULL;
- if (!MM_IFACE_MODEM_LOCATION_GET_INTERFACE (self)->enable_location_gathering_finish (self,
- res,
- &error)) {
+ if (!setup_gathering_finish (self, res, &error)) {
g_simple_async_result_take_error (ctx->result, error);
enabling_context_complete_and_free (ctx);
return;
@@ -667,18 +896,20 @@ interface_enabling_step (EnablingContext *ctx)
/* Fall down to next step */
ctx->step++;
- case ENABLING_STEP_ENABLE_GATHERING:
- if (mm_gdbus_modem_location_get_enabled (ctx->skeleton) &&
- MM_IFACE_MODEM_LOCATION_GET_INTERFACE (ctx->self)->enable_location_gathering &&
- MM_IFACE_MODEM_LOCATION_GET_INTERFACE (ctx->self)->enable_location_gathering_finish) {
- MM_IFACE_MODEM_LOCATION_GET_INTERFACE (ctx->self)->enable_location_gathering (
- ctx->self,
- (GAsyncReadyCallback)enabling_location_gathering_ready,
- ctx);
- return;
- }
- /* Fall down to next step */
- ctx->step++;
+ case ENABLING_STEP_ENABLE_GATHERING: {
+ MMModemLocationSource default_sources;
+
+ /* By default, we'll enable all NON-GPS sources
+ * (so, only 3GPP-LAC-CI if available) */
+ default_sources = mm_gdbus_modem_location_get_capabilities (ctx->skeleton);
+ default_sources &= ~(MM_MODEM_LOCATION_SOURCE_GPS_RAW | MM_MODEM_LOCATION_SOURCE_GPS_NMEA);
+
+ setup_gathering (ctx->self,
+ default_sources,
+ (GAsyncReadyCallback)enabling_location_gathering_ready,
+ ctx);
+ return;
+ }
case ENABLING_STEP_LAST:
/* We are done without errors! */
@@ -839,8 +1070,8 @@ interface_initialization_step (InitializationContext *ctx)
/* Handle method invocations */
g_signal_connect (ctx->skeleton,
- "handle-enable",
- G_CALLBACK (handle_enable),
+ "handle-setup",
+ G_CALLBACK (handle_setup),
ctx->self);
g_signal_connect (ctx->skeleton,
"handle-get-location",
@@ -889,7 +1120,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_enabled (skeleton, TRUE);
+ 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,
build_location_dictionary (NULL));
diff --git a/src/mm-iface-modem-location.h b/src/mm-iface-modem-location.h
index 2346c0f4..19f760e4 100644
--- a/src/mm-iface-modem-location.h
+++ b/src/mm-iface-modem-location.h
@@ -43,6 +43,7 @@ struct _MMIfaceModemLocation {
/* Enable location gathering (async) */
void (* enable_location_gathering) (MMIfaceModemLocation *self,
+ MMModemLocationSource source,
GAsyncReadyCallback callback,
gpointer user_data);
gboolean (*enable_location_gathering_finish) (MMIfaceModemLocation *self,
@@ -51,6 +52,7 @@ struct _MMIfaceModemLocation {
/* Disable location gathering (async) */
void (* disable_location_gathering) (MMIfaceModemLocation *self,
+ MMModemLocationSource source,
GAsyncReadyCallback callback,
gpointer user_data);
gboolean (*disable_location_gathering_finish) (MMIfaceModemLocation *self,