iface-modem-location: handle 3GPP location

This commit is contained in:
Aleksander Morgado
2012-01-17 23:43:20 +01:00
parent 5fa8918847
commit 71125777d3
2 changed files with 190 additions and 27 deletions

View File

@@ -18,6 +18,7 @@
#include "mm-iface-modem.h"
#include "mm-iface-modem-location.h"
#include "mm-common-location-3gpp.h"
#include "mm-log.h"
#define LOCATION_CONTEXT_TAG "location-context-tag"
@@ -66,9 +67,31 @@ dbus_call_context_new (MmGdbusModemLocation *skeleton,
/*****************************************************************************/
typedef struct {
gboolean interface_enabled;
/* 3GPP location */
MMCommonLocation3gpp *location_3gpp;
} LocationContext;
static void
location_context_free (LocationContext *ctx)
{
if (ctx->location_3gpp)
g_object_unref (ctx->location_3gpp);
g_free (ctx);
}
static void
clear_location_context (MMIfaceModemLocation *self)
{
if (G_UNLIKELY (!location_context_quark))
location_context_quark = (g_quark_from_static_string (
LOCATION_CONTEXT_TAG));
/* Clear all location data */
g_object_set_qdata (G_OBJECT (self),
location_context_quark,
NULL);
}
static LocationContext *
get_location_context (MMIfaceModemLocation *self)
{
@@ -87,7 +110,7 @@ get_location_context (MMIfaceModemLocation *self)
G_OBJECT (self),
location_context_quark,
ctx,
(GDestroyNotify)g_free);
(GDestroyNotify)location_context_free);
}
return ctx;
@@ -95,6 +118,138 @@ get_location_context (MMIfaceModemLocation *self)
/*****************************************************************************/
static GVariant *
build_location_dictionary (MMCommonLocation3gpp *location_3gpp)
{
GVariant *location_3gpp_value = NULL;
GVariantBuilder builder;
if (location_3gpp)
location_3gpp_value = mm_common_location_3gpp_get_string_variant (location_3gpp);
g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{uv}"));
if (location_3gpp_value)
g_variant_builder_add (&builder,
"{uv}",
MM_MODEM_LOCATION_SOURCE_3GPP_LAC_CI,
location_3gpp_value);
return g_variant_builder_end (&builder);
}
static void
notify_location_update (MMIfaceModemLocation *self,
MmGdbusModemLocation *skeleton,
MMCommonLocation3gpp *location_3gpp)
{
const gchar *dbus_path;
dbus_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (self));
mm_info ("Modem %s: 3GPP location updated "
"(MCC: '%u', MNC: '%u', Location area code: '%lX', Cell ID: '%lX')",
dbus_path,
mm_common_location_3gpp_get_mobile_country_code (location_3gpp),
mm_common_location_3gpp_get_mobile_network_code (location_3gpp),
mm_common_location_3gpp_get_location_area_code (location_3gpp),
mm_common_location_3gpp_get_cell_id (location_3gpp));
/* We only update the property if we are supposed to signal
* location */
if (mm_gdbus_modem_location_get_signals_location (skeleton))
mm_gdbus_modem_location_set_location (
skeleton,
build_location_dictionary (location_3gpp));
}
void
mm_iface_modem_location_3gpp_update_mcc_mnc (MMIfaceModemLocation *self,
guint mobile_country_code,
guint mobile_network_code)
{
MmGdbusModemLocation *skeleton;
LocationContext *ctx;
ctx = get_location_context (self);
g_object_get (self,
MM_IFACE_MODEM_LOCATION_DBUS_SKELETON, &skeleton,
NULL);
if (mm_gdbus_modem_location_get_enabled (skeleton)) {
guint changed = 0;
if (G_UNLIKELY (!ctx->location_3gpp))
ctx->location_3gpp = mm_common_location_3gpp_new ();
changed += mm_common_location_3gpp_set_mobile_country_code (ctx->location_3gpp,
mobile_country_code);
changed += mm_common_location_3gpp_set_mobile_network_code (ctx->location_3gpp,
mobile_network_code);
if (changed)
notify_location_update (self, skeleton, ctx->location_3gpp);
}
g_object_unref (skeleton);
}
void
mm_iface_modem_location_3gpp_update_lac_ci (MMIfaceModemLocation *self,
gulong location_area_code,
gulong cell_id)
{
MmGdbusModemLocation *skeleton;
LocationContext *ctx;
ctx = get_location_context (self);
g_object_get (self,
MM_IFACE_MODEM_LOCATION_DBUS_SKELETON, &skeleton,
NULL);
if (mm_gdbus_modem_location_get_enabled (skeleton)) {
guint changed = 0;
if (G_UNLIKELY (!ctx->location_3gpp))
ctx->location_3gpp = mm_common_location_3gpp_new ();
changed += mm_common_location_3gpp_set_location_area_code (ctx->location_3gpp,
location_area_code);
changed += mm_common_location_3gpp_set_cell_id (ctx->location_3gpp,
cell_id);
if (changed)
notify_location_update (self, skeleton, ctx->location_3gpp);
}
g_object_unref (skeleton);
}
void
mm_iface_modem_location_3gpp_clear (MMIfaceModemLocation *self)
{
MmGdbusModemLocation *skeleton;
LocationContext *ctx;
ctx = get_location_context (self);
g_object_get (self,
MM_IFACE_MODEM_LOCATION_DBUS_SKELETON, &skeleton,
NULL);
if (mm_gdbus_modem_location_get_enabled (skeleton)) {
guint changed = 0;
if (G_UNLIKELY (!ctx->location_3gpp))
ctx->location_3gpp = mm_common_location_3gpp_new ();
changed += mm_common_location_3gpp_set_location_area_code (ctx->location_3gpp, 0);
changed += mm_common_location_3gpp_set_cell_id (ctx->location_3gpp, 0);
changed += mm_common_location_3gpp_set_mobile_country_code (ctx->location_3gpp, 0);
changed += mm_common_location_3gpp_set_mobile_network_code (ctx->location_3gpp, 0);
if (changed)
notify_location_update (self, skeleton, ctx->location_3gpp);
}
g_object_unref (skeleton);
}
/*****************************************************************************/
static void
enable_location_gathering_ready (MMIfaceModemLocation *self,
GAsyncResult *res,
@@ -127,6 +282,7 @@ disable_location_gathering_ready (MMIfaceModemLocation *self,
&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);
@@ -142,12 +298,11 @@ handle_enable (MmGdbusModemLocation *skeleton,
gboolean signal_location,
MMIfaceModemLocation *self)
{
/* Enabling */
if (enable) {
LocationContext *ctx;
ctx = get_location_context (self);
/* Enabling */
if (enable) {
mm_dbg ("Enabling location gathering%s...",
signal_location ? " (with signaling)" : "");
@@ -155,18 +310,19 @@ handle_enable (MmGdbusModemLocation *skeleton,
if (mm_gdbus_modem_location_get_signals_location (skeleton) != signal_location) {
mm_dbg ("%s location signaling",
signal_location ? "Enabling" : "Disabling");
mm_gdbus_modem_location_set_signals_location (skeleton, signal_location);
if (!signal_location)
/* If disabling, cleanup currently available value */
mm_gdbus_modem_location_set_location (skeleton, NULL);
mm_gdbus_modem_location_set_signals_location (skeleton,
signal_location);
mm_gdbus_modem_location_set_location (skeleton,
build_location_dictionary (signal_location ?
ctx->location_3gpp :
NULL));
}
/* If already enabled, just done */
if (mm_gdbus_modem_location_get_enabled (skeleton))
mm_gdbus_modem_location_complete_enable (skeleton, invocation);
/* Plugins can run custom actions to enable location gathering */
else if (ctx->interface_enabled &&
MM_IFACE_MODEM_LOCATION_GET_INTERFACE (self)->enable_location_gathering &&
else 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 (
self,
@@ -188,8 +344,7 @@ handle_enable (MmGdbusModemLocation *skeleton,
if (!mm_gdbus_modem_location_get_enabled (skeleton))
mm_gdbus_modem_location_complete_enable (skeleton, invocation);
/* Plugins can run custom actions to disable location gathering */
else if (ctx->interface_enabled &&
MM_IFACE_MODEM_LOCATION_GET_INTERFACE (self)->disable_location_gathering &&
else 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 (
self,
@@ -199,6 +354,7 @@ handle_enable (MmGdbusModemLocation *skeleton,
self));
else {
/* If no plugin-specific setup needed, or interface not yet enabled, just done */
clear_location_context (self);
mm_gdbus_modem_location_set_enabled (skeleton, FALSE);
mm_gdbus_modem_location_complete_enable (skeleton, invocation);
}
@@ -210,11 +366,18 @@ handle_enable (MmGdbusModemLocation *skeleton,
/*****************************************************************************/
static gboolean
handle_get_location (MmGdbusModemLocation *object,
handle_get_location (MmGdbusModemLocation *skeleton,
GDBusMethodInvocation *invocation,
MMIfaceModemLocation *self)
{
return FALSE;
LocationContext *ctx;
ctx = get_location_context (self);
mm_gdbus_modem_location_complete_get_location (
skeleton,
invocation,
build_location_dictionary (ctx->location_3gpp));
return TRUE;
}
/*****************************************************************************/
@@ -303,10 +466,6 @@ disabling_location_gathering_ready (MMIfaceModemLocation *self,
static void
interface_disabling_step (DisablingContext *ctx)
{
LocationContext *location_context;
location_context = get_location_context (ctx->self);
switch (ctx->step) {
case DISABLING_STEP_FIRST:
/* Fall down to next step */
@@ -327,7 +486,6 @@ interface_disabling_step (DisablingContext *ctx)
case DISABLING_STEP_LAST:
/* We are done without errors! */
location_context->interface_enabled = FALSE;
g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
disabling_context_complete_and_free (ctx);
return;
@@ -430,10 +588,6 @@ enabling_location_gathering_ready (MMIfaceModemLocation *self,
static void
interface_enabling_step (EnablingContext *ctx)
{
LocationContext *location_context;
location_context = get_location_context (ctx->self);
switch (ctx->step) {
case ENABLING_STEP_FIRST:
/* Fall down to next step */
@@ -454,7 +608,6 @@ interface_enabling_step (EnablingContext *ctx)
case ENABLING_STEP_LAST:
/* We are done without errors! */
location_context->interface_enabled = TRUE;
g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
enabling_context_complete_and_free (ctx);
return;
@@ -644,7 +797,8 @@ mm_iface_modem_location_initialize (MMIfaceModemLocation *self,
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_signals_location (skeleton, FALSE);
mm_gdbus_modem_location_set_location (skeleton, NULL);
mm_gdbus_modem_location_set_location (skeleton,
build_location_dictionary (NULL));
g_object_set (self,
MM_IFACE_MODEM_LOCATION_DBUS_SKELETON, skeleton,

View File

@@ -88,6 +88,15 @@ gboolean mm_iface_modem_location_disable_finish (MMIfaceModemLocation *self,
/* Shutdown Location interface */
void mm_iface_modem_location_shutdown (MMIfaceModemLocation *self);
/* Update 3GPP (LAC/CI) location */
void mm_iface_modem_location_3gpp_clear (MMIfaceModemLocation *self);
void mm_iface_modem_location_3gpp_update_mcc_mnc (MMIfaceModemLocation *self,
guint mobile_country_code,
guint mobile_network_code);
void mm_iface_modem_location_3gpp_update_lac_ci (MMIfaceModemLocation *self,
gulong location_area_code,
gulong cell_id);
/* Bind properties for simple GetStatus() */
void mm_iface_modem_location_bind_simple_status (MMIfaceModemLocation *self,
MMCommonSimpleProperties *status);