diff options
author | Maciej S. Szmigiero <mail@maciej.szmigiero.name> | 2021-11-19 14:00:16 +0100 |
---|---|---|
committer | Maciej S. Szmigiero <mail@maciej.szmigiero.name> | 2022-08-07 02:38:56 +0200 |
commit | 4ec74b6554f3f8439f023ab490ee4f4fac96b6b7 (patch) | |
tree | a6cd8bd2caee375689e302b1ef66824f15ce4dba | |
parent | 5b4f09f78d152cf06e4a887b103daa257845f931 (diff) | |
download | geoclue-4ec74b6554f3f8439f023ab490ee4f4fac96b6b7.tar.gz |
modem-manager: Emit a NO_FIX location signal from modem handler when 3G tower data is lost
And make sure that we emit tower data unconditionally when 3G source is
started in order to prime it.
-rw-r--r-- | src/gclue-3g-tower.h | 1 | ||||
-rw-r--r-- | src/gclue-3g.c | 10 | ||||
-rw-r--r-- | src/gclue-modem-manager.c | 26 |
3 files changed, 33 insertions, 4 deletions
diff --git a/src/gclue-3g-tower.h b/src/gclue-3g-tower.h index 4333245..15d8c87 100644 --- a/src/gclue-3g-tower.h +++ b/src/gclue-3g-tower.h @@ -28,6 +28,7 @@ typedef enum { GCLUE_TOWER_TEC_UNKNOWN = 0, GCLUE_TOWER_TEC_3G = 1, GCLUE_TOWER_TEC_4G = 2, + GCLUE_TOWER_TEC_NO_FIX = 99, } GClueTowerTec; typedef struct _GClue3GTower GClue3GTower; diff --git a/src/gclue-3g.c b/src/gclue-3g.c index bbcb791..0f33dcd 100644 --- a/src/gclue-3g.c +++ b/src/gclue-3g.c @@ -92,11 +92,15 @@ on_is_3g_available_notify (GObject *gobject, { GClue3G *source = GCLUE_3G (user_data); GClue3GPrivate *priv = source->priv; + gboolean available_3g; + + available_3g = gclue_modem_get_is_3g_available (priv->modem); + g_debug ("3G available notify %d", (int)available_3g); gclue_web_source_refresh (GCLUE_WEB_SOURCE (source)); if (gclue_location_source_get_active (GCLUE_LOCATION_SOURCE (source)) && - gclue_modem_get_is_3g_available (priv->modem)) + available_3g) gclue_modem_enable_3g (priv->modem, priv->cancellable, on_3g_enabled, @@ -259,6 +263,9 @@ on_fix_3g (GClueModem *modem, { GClue3GPrivate *priv = GCLUE_3G (user_data)->priv; + if (tec == GCLUE_TOWER_TEC_NO_FIX) + return; + if (priv->tower == NULL) priv->tower = g_slice_new0 (GClue3GTower); g_strlcpy (priv->tower->opc, opc, @@ -296,6 +303,7 @@ gclue_3g_start (GClueLocationSource *source) G_CALLBACK (on_fix_3g), source); + /* Emits fix-3g signal even if the location hasn't actually changed to prime us */ if (gclue_modem_get_is_3g_available (priv->modem)) gclue_modem_enable_3g (priv->modem, priv->cancellable, diff --git a/src/gclue-modem-manager.c b/src/gclue-modem-manager.c index 3aec411..b81f553 100644 --- a/src/gclue-modem-manager.c +++ b/src/gclue-modem-manager.c @@ -45,6 +45,7 @@ struct _GClueModemManagerPrivate { MMModem *modem; MMModemLocation *modem_location; MMLocation3gpp *location_3gpp; + gboolean location_3gpp_ignore_previous; MMLocationGpsNmea *location_nmea; GCancellable *cancellable; @@ -295,7 +296,7 @@ is_location_3gpp_same (GClueModemManager *manager, gchar opc_buf[GCLUE_3G_TOWER_OPERATOR_CODE_STR_LEN + 1]; #endif - if (priv->location_3gpp == NULL) + if (priv->location_3gpp == NULL || priv->location_3gpp_ignore_previous) return FALSE; #if MM_CHECK_VERSION(1, 18, 0) @@ -321,6 +322,18 @@ is_location_3gpp_same (GClueModemManager *manager, cell_id == new_cell_id); } +static void clear_3gpp_location (GClueModemManager *manager) +{ + GClueModemManagerPrivate *priv = manager->priv; + + if (!priv->location_3gpp && !priv->location_3gpp_ignore_previous) { + return; + } + + g_clear_object (&priv->location_3gpp); + g_signal_emit (manager, signals[FIX_3G], 0, NULL, 0, 0, GCLUE_TOWER_TEC_NO_FIX); +} + static void on_get_3gpp_ready (GObject *source_object, GAsyncResult *res, @@ -353,6 +366,8 @@ on_get_3gpp_ready (GObject *source_object, if (location_3gpp == NULL) { g_debug ("No 3GPP"); + clear_3gpp_location (manager); + priv->location_3gpp_ignore_previous = FALSE; return; } @@ -384,6 +399,7 @@ on_get_3gpp_ready (GObject *source_object, } g_clear_object (&priv->location_3gpp); priv->location_3gpp = g_steal_pointer (&location_3gpp); + priv->location_3gpp_ignore_previous = FALSE; g_signal_emit (manager, signals[FIX_3G], 0, opc, lac, cell_id, tec); } @@ -574,6 +590,8 @@ on_modem_location_setup (GObject *modem_object, priv = manager->priv; g_debug ("Modem '%s' setup.", mm_object_get_path (priv->mm_object)); + /* Make sure that we actually emit that signal */ + priv->location_3gpp_ignore_previous = TRUE; on_location_changed (modem_object, NULL, manager); g_task_return_boolean (task, TRUE); @@ -779,6 +797,8 @@ on_mm_object_removed (GDBusObjectManager *object_manager, return; g_debug ("Modem '%s' removed.", mm_object_get_path (priv->mm_object)); + clear_3gpp_location (manager); + g_signal_handlers_disconnect_by_func (G_OBJECT (priv->modem_location), G_CALLBACK (on_location_changed), user_data); @@ -1086,7 +1106,7 @@ gclue_modem_manager_disable_3g (GClueModem *modem, g_return_val_if_fail (gclue_modem_manager_get_is_3g_available (modem), FALSE); manager = GCLUE_MODEM_MANAGER (modem); - g_clear_object (&manager->priv->location_3gpp); + clear_3gpp_location (manager); g_debug ("Clearing 3GPP location caps from modem"); return clear_caps (manager, MM_MODEM_LOCATION_SOURCE_3GPP_LAC_CI, @@ -1105,7 +1125,7 @@ gclue_modem_manager_disable_cdma (GClueModem *modem, g_return_val_if_fail (gclue_modem_manager_get_is_cdma_available (modem), FALSE); manager = GCLUE_MODEM_MANAGER (modem); - g_clear_object (&manager->priv->location_3gpp); + clear_3gpp_location (manager); g_debug ("Clearing CDMA location caps from modem"); return clear_caps (manager, MM_MODEM_LOCATION_SOURCE_CDMA_BS, |