summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaciej S. Szmigiero <mail@maciej.szmigiero.name>2021-11-19 14:00:16 +0100
committerMaciej S. Szmigiero <mail@maciej.szmigiero.name>2022-08-07 02:38:56 +0200
commit4ec74b6554f3f8439f023ab490ee4f4fac96b6b7 (patch)
treea6cd8bd2caee375689e302b1ef66824f15ce4dba
parent5b4f09f78d152cf06e4a887b103daa257845f931 (diff)
downloadgeoclue-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.h1
-rw-r--r--src/gclue-3g.c10
-rw-r--r--src/gclue-modem-manager.c26
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,