diff options
author | Aleksander Morgado <aleksander@lanedo.com> | 2012-01-17 23:43:20 +0100 |
---|---|---|
committer | Aleksander Morgado <aleksander@lanedo.com> | 2012-03-15 14:14:52 +0100 |
commit | 71125777d38126f41c18a2b04a0dbfdb6b2628d6 (patch) | |
tree | 8b125822fea8b1787ddb17a12009185731e1d9d1 /src/mm-iface-modem-location.c | |
parent | 5fa8918847fffa7f373c2f863ed765091db659d3 (diff) | |
download | ModemManager-71125777d38126f41c18a2b04a0dbfdb6b2628d6.tar.gz |
iface-modem-location: handle 3GPP location
Diffstat (limited to 'src/mm-iface-modem-location.c')
-rw-r--r-- | src/mm-iface-modem-location.c | 208 |
1 files changed, 181 insertions, 27 deletions
diff --git a/src/mm-iface-modem-location.c b/src/mm-iface-modem-location.c index 51ffea354..96af97e35 100644 --- a/src/mm-iface-modem-location.c +++ b/src/mm-iface-modem-location.c @@ -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) { - LocationContext *ctx; - - ctx = get_location_context (self); - /* Enabling */ if (enable) { + LocationContext *ctx; + + ctx = get_location_context (self); 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, |