Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package geoclue2 for openSUSE:Factory checked in at 2023-10-04 22:30:36 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/geoclue2 (Old) and /work/SRC/openSUSE:Factory/.geoclue2.new.28202 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "geoclue2" Wed Oct 4 22:30:36 2023 rev:46 rq:1114952 version:2.7.1 Changes: -------- --- /work/SRC/openSUSE:Factory/geoclue2/geoclue2.changes 2023-03-08 14:51:16.714253259 +0100 +++ /work/SRC/openSUSE:Factory/.geoclue2.new.28202/geoclue2.changes 2023-10-04 22:31:00.654685790 +0200 @@ -1,0 +2,19 @@ +Fri Sep 29 18:38:36 UTC 2023 - Bjørn Lie <[email protected]> + +- Update to version 2.7.1: + + Add 'age' field to MLS locate queries + + Location updates now always have an accuracy value + + Improvements to NMEA parsing: + - Parse NMEA timestamps with sub-second accuracy + - Add default accuracy to NMEA RMC locations + - Ignore locations from GGA and RMC sentences if the GNSS fix + is not valid + + Prioritize GNSS sources with a recent fix over other sources, + preventing location jumps + + Install D-Bus policy in /usr/share, not /etc + + Upgrade GLib / Gio dependency to version 2.68.0 + + Correct gi annotations in GClueSimple + + Various small fixes +- Use ldconfig_scriptlets macro for post(un) handling. + +------------------------------------------------------------------- Old: ---- geoclue-2.7.0.tar.bz2 New: ---- geoclue-2.7.1.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ geoclue2.spec ++++++ --- /var/tmp/diff_new_pack.m7eZga/_old 2023-10-04 22:31:01.762725838 +0200 +++ /var/tmp/diff_new_pack.m7eZga/_new 2023-10-04 22:31:01.762725838 +0200 @@ -19,7 +19,7 @@ %define _name geoclue Name: geoclue2 -Version: 2.7.0 +Version: 2.7.1 Release: 0 Summary: GeoLocation Framework License: GPL-2.0-or-later @@ -38,9 +38,9 @@ BuildRequires: perl(XML::Parser) BuildRequires: pkgconfig(avahi-client) >= 0.6.10 BuildRequires: pkgconfig(avahi-glib) >= 0.6.10 -BuildRequires: pkgconfig(gio-2.0) >= 2.44.0 -BuildRequires: pkgconfig(gio-unix-2.0) >= 2.44.0 -BuildRequires: pkgconfig(glib-2.0) >= 2.44.0 +BuildRequires: pkgconfig(gio-2.0) >= 2.68.0 +BuildRequires: pkgconfig(gio-unix-2.0) >= 2.68.0 +BuildRequires: pkgconfig(glib-2.0) >= 2.68.0 BuildRequires: pkgconfig(gobject-introspection-1.0) BuildRequires: pkgconfig(json-glib-1.0) >= 0.14 BuildRequires: pkgconfig(libnotify) @@ -112,8 +112,7 @@ # note: do not use systemd macros for geoclue2.service, they are not meant for dbus unit files. %pre -n system-user-srvGeoClue -f srvGeoClue.pre -%post -p /sbin/ldconfig -%postun -p /sbin/ldconfig +%ldconfig_scriptlets %files %license COPYING ++++++ geoclue-2.7.0.tar.bz2 -> geoclue-2.7.1.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/geoclue-2.7.0/.gitlab-ci.yml new/geoclue-2.7.1/.gitlab-ci.yml --- old/geoclue-2.7.0/.gitlab-ci.yml 2023-01-22 21:37:05.000000000 +0100 +++ new/geoclue-2.7.1/.gitlab-ci.yml 2023-09-03 10:27:30.000000000 +0200 @@ -7,8 +7,10 @@ - DEBIAN_FRONTEND=noninteractive apt-get install --yes libsoup-3.0 - pip3 install meson==0.60.0 -# Ubuntu 14.04 is not supported, see README for details -# +workflow: + rules: + - if: $CI_PIPELINE_SOURCE == 'merge_request_event' + - if: $CI_PIPELINE_SOURCE == 'push' ubuntu-22.04: image: ubuntu:22.04 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/geoclue-2.7.0/HACKING.md new/geoclue-2.7.1/HACKING.md --- old/geoclue-2.7.0/HACKING.md 2023-01-22 21:37:05.000000000 +0100 +++ new/geoclue-2.7.1/HACKING.md 2023-09-03 10:27:30.000000000 +0200 @@ -4,7 +4,7 @@ is already included in your distro/OS, you should be able to use the package manager's command to install all build depedndancies. - * gio (>= 2.44.0) + * gio * gobject-introspection * json-glib * libsoup3.0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/geoclue-2.7.0/NEWS new/geoclue-2.7.1/NEWS --- old/geoclue-2.7.0/NEWS 2023-01-22 21:37:05.000000000 +0100 +++ new/geoclue-2.7.1/NEWS 2023-09-03 10:27:30.000000000 +0200 @@ -1,3 +1,24 @@ +2.7.1 +===== + +- Add 'age' field to MLS locate queries +- Location updates now always have an accuracy value +- Improvements to NMEA parsing: + - Parse NMEA timestamps with sub-second accuracy + - Add default accuracy to NMEA RMC locations + - Ignore locations from GGA and RMC sentences if the GNSS fix is not valid +- Prioritize GNSS sources with a recent fix over other sources, preventing location jumps +- Install D-Bus policy in /usr/share, not /etc +- Upgrade GLib / Gio dependency to version 2.68.0 +- Correct gi annotations in GClueSimple +- Various small fixes + +Contributors: +- Chris Talbot +- Gioele Barabucci +- Philipp Hörist +- Teemu Ikonen + 2.7.0 ===== diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/geoclue-2.7.0/data/meson.build new/geoclue-2.7.1/data/meson.build --- old/geoclue-2.7.0/data/meson.build 2023-01-22 21:37:05.000000000 +0100 +++ new/geoclue-2.7.1/data/meson.build 2023-09-03 10:27:30.000000000 +0200 @@ -37,7 +37,7 @@ # DBus Service policy file dbus_service_dir = get_option('dbus-sys-dir') if dbus_service_dir == '' - dbus_service_dir = join_paths(sysconfdir, 'dbus-1', 'system.d') + dbus_service_dir = join_paths(datadir, 'dbus-1', 'system.d') endif configure_file(output: 'org.freedesktop.GeoClue2.conf', input: 'org.freedesktop.GeoClue2.conf.in', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/geoclue-2.7.0/libgeoclue/gclue-simple.c new/geoclue-2.7.1/libgeoclue/gclue-simple.c --- old/geoclue-2.7.0/libgeoclue/gclue-simple.c 2023-01-22 21:37:05.000000000 +0100 +++ new/geoclue-2.7.1/libgeoclue/gclue-simple.c 2023-09-03 10:27:30.000000000 +0200 @@ -974,7 +974,7 @@ * Gets the client proxy, or %NULL if @simple is not using a client proxy (i-e * when inside the Flatpak sandbox). * - * Returns: (transfer none) (type GClueClientProxy): The client object. + * Returns: (nullable) (transfer none) (type GClueClientProxy): The client object. */ GClueClient * gclue_simple_get_client (GClueSimple *simple) @@ -990,7 +990,7 @@ * * Gets the current location. * - * Returns: (transfer none) (type GClueLocation): The last known location + * Returns: (nullable) (transfer none) (type GClueLocation): The last known location * as #GClueLocation. */ GClueLocation * diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/geoclue-2.7.0/meson.build new/geoclue-2.7.1/meson.build --- old/geoclue-2.7.0/meson.build 2023-01-22 21:37:05.000000000 +0100 +++ new/geoclue-2.7.1/meson.build 2023-09-03 10:27:30.000000000 +0200 @@ -1,4 +1,4 @@ -project('geoclue', 'c', version: '2.7.0', meson_version : '>= 0.60.0') +project('geoclue', 'c', version: '2.7.1', meson_version : '>= 0.60.0') gclue_version = meson.project_version() ver_arr = gclue_version.split('.') @@ -43,9 +43,9 @@ gnome = import('gnome') cc = meson.get_compiler('c') -base_deps = [ dependency('glib-2.0', version: '>= 2.44.0'), - dependency('gio-2.0', version: '>= 2.44.0'), - dependency('gio-unix-2.0', version: '>= 2.44.0') ] +base_deps = [ dependency('glib-2.0', version: '>= 2.68.0'), + dependency('gio-2.0', version: '>= 2.68.0'), + dependency('gio-unix-2.0', version: '>= 2.68.0') ] libm = cc.find_library('m', required: false) if libm.found() base_deps += [ libm ] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/geoclue-2.7.0/src/gclue-location-source.c new/geoclue-2.7.1/src/gclue-location-source.c --- old/geoclue-2.7.0/src/gclue-location-source.c 2023-01-22 21:37:05.000000000 +0100 +++ new/geoclue-2.7.1/src/gclue-location-source.c 2023-09-03 10:27:30.000000000 +0200 @@ -52,6 +52,7 @@ gboolean compute_movement; gboolean scramble_location; + gboolean priority_source; #if GCLUE_USE_COMPASS GClueCompass *compass; @@ -74,6 +75,7 @@ PROP_AVAILABLE_ACCURACY_LEVEL, PROP_COMPUTE_MOVEMENT, PROP_SCRAMBLE_LOCATION, + PROP_PRIORITY_SOURCE, LAST_PROP }; @@ -156,6 +158,10 @@ g_value_set_boolean (value, source->priv->scramble_location); break; + case PROP_PRIORITY_SOURCE: + g_value_set_boolean (value, source->priv->priority_source); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } @@ -190,6 +196,10 @@ source->priv->scramble_location = g_value_get_boolean (value); break; + case PROP_PRIORITY_SOURCE: + source->priv->priority_source = g_value_get_boolean (value); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } @@ -281,6 +291,18 @@ g_object_class_install_property (object_class, PROP_SCRAMBLE_LOCATION, gParamSpecs[PROP_SCRAMBLE_LOCATION]); + + gParamSpecs[PROP_PRIORITY_SOURCE] = + g_param_spec_boolean ("priority-source", + "PrioritySource", + "Whether source is priority or not", + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property (object_class, + PROP_PRIORITY_SOURCE, + gParamSpecs[PROP_PRIORITY_SOURCE]); + } static void @@ -289,6 +311,7 @@ source->priv = gclue_location_source_get_instance_private (source); source->priv->compute_movement = TRUE; source->priv->time_threshold = gclue_min_uint_new (); + source->priv->priority_source = FALSE; } static GClueLocationSourceStartResult @@ -499,6 +522,21 @@ } /** + * gclue_location_source_get_priority_source: + * @source: a #GClueLocationSource + * + * Returns: Returns: TRUE if source (e.g. GPS) has priority over other + * sources, FALSE otherwise. + **/ +gboolean +gclue_location_source_get_priority_source (GClueLocationSource *source) +{ + g_return_val_if_fail (GCLUE_IS_LOCATION_SOURCE (source), FALSE); + + return source->priv->priority_source; +} + +/** * gclue_location_source_get_available_accuracy_level: * @source: a #GClueLocationSource * diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/geoclue-2.7.0/src/gclue-location-source.h new/geoclue-2.7.1/src/gclue-location-source.h --- old/geoclue-2.7.0/src/gclue-location-source.h 2023-01-22 21:37:05.000000000 +0100 +++ new/geoclue-2.7.1/src/gclue-location-source.h 2023-09-03 10:27:30.000000000 +0200 @@ -84,6 +84,8 @@ GClueLocation *location); gboolean gclue_location_source_get_active (GClueLocationSource *source); +gboolean gclue_location_source_get_priority_source + (GClueLocationSource *source); GClueAccuracyLevel gclue_location_source_get_available_accuracy_level (GClueLocationSource *source); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/geoclue-2.7.0/src/gclue-location.c new/geoclue-2.7.1/src/gclue-location.c --- old/geoclue-2.7.0/src/gclue-location.c 2023-01-22 21:37:05.000000000 +0100 +++ new/geoclue-2.7.1/src/gclue-location.c 2023-09-03 10:27:30.000000000 +0200 @@ -29,9 +29,11 @@ #include <string.h> #include <stdlib.h> -#define TIME_DIFF_THRESHOLD 60000000 /* 60 seconds */ +#define TIME_DIFF_THRESHOLD (60 * G_USEC_PER_SEC) /* 60 seconds */ #define EARTH_RADIUS_KM 6372.795 #define KNOTS_IN_METERS_PER_SECOND 0.51444 +#define RMC_TIME_DIFF_THRESHOLD 5 /* 5 seconds */ +#define RMC_DEFAULT_ACCURACY 5 /* 5 meters */ struct _GClueLocationPrivate { char *description; @@ -479,14 +481,20 @@ return g_ascii_strtod (altitude, NULL); } +/* Return a timestamp derived from the NMEA timestamp and system date as + * seconds since epoch. + * If system time cannot be retrieved, return 0. + * If timestamp parsing fails, return system time. + * If the parsed time is in the future when compared to the system time, + * return the parsed time yesterday. + */ static gint64 parse_nmea_timestamp (const char *nmea_ts) { - char parts[3][3]; - int i, hours, minutes, seconds; g_autoptr(GDateTime) now = NULL; + g_autoptr(GDateTime) midnight = NULL; g_autoptr(GDateTime) ts = NULL; - guint64 ret; + GTimeSpan timespan; now = g_date_time_new_now_utc (); if (now == NULL) { @@ -494,51 +502,32 @@ return 0; } - ret = g_date_time_to_unix (now); + if (!nmea_ts || !*nmea_ts) { /* Empty timestamp, no warning */ + return g_date_time_to_unix (now); + } - if (strlen (nmea_ts) < 6) { - if (strlen (nmea_ts) >= 1) - /* Empty string just means no ts, so no warning */ - g_warning ("Failed to parse NMEA timestamp '%s'", - nmea_ts); - - goto parse_error; - } - - for (i = 0; i < 3; i++) { - memmove (parts[i], nmea_ts + (i * 2), 2); - parts[i][2] = '\0'; - } - hours = atoi (parts[0]); - minutes = atoi (parts[1]); - seconds = atoi (parts[2]); - - ts = g_date_time_new_utc (g_date_time_get_year (now), - g_date_time_get_month (now), - g_date_time_get_day_of_month (now), - hours, - minutes, - seconds); - if (ts == NULL) - goto parse_error; + timespan = gclue_nmea_timestamp_to_timespan (nmea_ts); + if (timespan < 0) { + g_warning ("Failed to parse NMEA timestamp '%s'", nmea_ts); + return g_date_time_to_unix (now); + } + + midnight = g_date_time_new_utc (g_date_time_get_year (now), + g_date_time_get_month (now), + g_date_time_get_day_of_month (now), + 0, + 0, + 0); + ts = g_date_time_add (midnight, timespan); if (g_date_time_difference (ts, now) > TIME_DIFF_THRESHOLD) { g_debug ("NMEA timestamp '%s' in future. Assuming yesterday's.", nmea_ts); - g_clear_pointer (&ts, g_date_time_unref); - ts = g_date_time_new_utc (g_date_time_get_year (now), - g_date_time_get_month (now), - g_date_time_get_day_of_month (now) - 1, - hours, - minutes, - seconds); + ts = g_date_time_add (midnight, timespan - G_TIME_SPAN_DAY); } - ret = g_date_time_to_unix (ts); - -parse_error: - return ret; + return g_date_time_to_unix (ts); } /** @@ -604,7 +593,7 @@ } static GClueLocation * -gclue_location_create_from_gga (const char *gga, GError **error) +gclue_location_create_from_gga (const char *gga) { GClueLocation *location; gdouble latitude, longitude, accuracy, altitude; @@ -614,10 +603,12 @@ parts = g_strsplit (gga, ",", -1); if (g_strv_length (parts) < 14) { - g_set_error_literal (error, - G_IO_ERROR, - G_IO_ERROR_INVALID_ARGUMENT, - "Invalid NMEA GGA sentence"); + g_warning ("Invalid NMEA GGA sentence."); + return NULL; + } + + if (g_ascii_strtoll (parts[6], NULL, 10) == 0) { + /* No fix, ignore. */ return NULL; } @@ -628,10 +619,7 @@ latitude = parse_coordinate_string (parts[2], parts[3]); longitude = parse_coordinate_string (parts[4], parts[5]); if (latitude == INVALID_COORDINATE || longitude == INVALID_COORDINATE) { - g_set_error_literal (error, - G_IO_ERROR, - G_IO_ERROR_INVALID_ARGUMENT, - "Invalid NMEA GGA sentence"); + g_warning ("Invalid coordinate on NMEA GGA sentence."); return NULL; } @@ -655,22 +643,32 @@ static GClueLocation * gclue_location_create_from_rmc (const char *rmc, - GClueLocation *prev_location, - GError **error) + GClueLocation *prev_location) { GClueLocation *location; g_auto(GStrv) parts = NULL; + gdouble accuracy; + gdouble altitude; parts = g_strsplit (rmc, ",", -1); - if (g_strv_length (parts) < 13) - goto error; + if (g_strv_length (parts) < 13) { + g_warning ("Invalid NMEA RMC sentence."); + return NULL; + } + + /* RMC sentence is invalid */ + if (g_strcmp0 (parts[2], "A") != 0) { + return NULL; + } guint64 timestamp = parse_nmea_timestamp (parts[1]); gdouble lat = parse_coordinate_string (parts[3], parts[4]); gdouble lon = parse_coordinate_string (parts[5], parts[6]); - if (lat == INVALID_COORDINATE || lon == INVALID_COORDINATE) - goto error; + if (lat == INVALID_COORDINATE || lon == INVALID_COORDINATE) { + g_warning ("Invalid coordinate on NMEA RMC sentence."); + return NULL; + } gdouble speed = GCLUE_LOCATION_SPEED_UNKNOWN; if (parts[7][0] != '\0') @@ -686,6 +684,23 @@ heading = GCLUE_LOCATION_HEADING_UNKNOWN; } + accuracy = RMC_DEFAULT_ACCURACY; + altitude = GCLUE_LOCATION_ALTITUDE_UNKNOWN; + if (prev_location != NULL) { + guint64 prev_loc_timestamp; + + prev_loc_timestamp = gclue_location_get_timestamp (prev_location); + + /* Sentence is older then previous location, reject */ + if (timestamp < prev_loc_timestamp) + return NULL; + + if (timestamp - prev_loc_timestamp < RMC_TIME_DIFF_THRESHOLD) { + accuracy = gclue_location_get_accuracy (prev_location); + altitude = gclue_location_get_altitude (prev_location); + } + } + location = g_object_new (GCLUE_TYPE_LOCATION, "latitude", lat, "longitude", lon, @@ -693,34 +708,17 @@ "speed", speed, "heading", heading, "description", "GPS RMC", + "accuracy", accuracy, + "altitude", altitude, NULL); - if (prev_location != NULL) { - g_object_set (location, - "accuracy", - gclue_location_get_accuracy (prev_location), - NULL); - g_object_set (location, - "altitude", - gclue_location_get_altitude (prev_location), - NULL); - } - return location; - -error: - g_set_error_literal (error, - G_IO_ERROR, - G_IO_ERROR_INVALID_ARGUMENT, - "Invalid NMEA RMC sentence"); - return NULL; } /** * gclue_location_create_from_nmeas: * @nmea: A NULL terminated array NMEA sentence strings * @prev_location: Previous location provided from the location source - * @error: Place-holder for errors. * * Creates a new #GClueLocation object by combining data from multiple NMEA * sentences. @@ -731,8 +729,7 @@ **/ GClueLocation * gclue_location_create_from_nmeas (const char *nmeas[], - GClueLocation *prev_location, - GError **error) + GClueLocation *prev_location) { GClueLocation *gga_loc = NULL; GClueLocation *rmc_loc = NULL; @@ -740,10 +737,10 @@ for (iter = nmeas; *iter != NULL; iter++) { if (!gga_loc && gclue_nmea_type_is (*iter, "GGA")) - gga_loc = gclue_location_create_from_gga (*iter, NULL); + gga_loc = gclue_location_create_from_gga (*iter); if (!rmc_loc && gclue_nmea_type_is (*iter, "RMC")) rmc_loc = gclue_location_create_from_rmc - (*iter, prev_location, NULL); + (*iter, prev_location); if (gga_loc && rmc_loc) break; } @@ -753,6 +750,7 @@ (gga_loc, gclue_location_get_speed(rmc_loc)); gclue_location_set_heading (gga_loc, gclue_location_get_heading(rmc_loc)); + g_object_set (gga_loc, "description", "GPS GGA+RMC", NULL); g_object_unref (rmc_loc); return gga_loc; @@ -762,10 +760,7 @@ if (rmc_loc) return rmc_loc; - g_set_error_literal (error, - G_IO_ERROR, - G_IO_ERROR_INVALID_ARGUMENT, - "Valid NMEA GGA or RMC sentence not found"); + g_debug ("Valid NMEA GGA or RMC sentence not found"); return NULL; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/geoclue-2.7.0/src/gclue-location.h new/geoclue-2.7.1/src/gclue-location.h --- old/geoclue-2.7.0/src/gclue-location.h 2023-01-22 21:37:05.000000000 +0100 +++ new/geoclue-2.7.1/src/gclue-location.h 2023-09-03 10:27:30.000000000 +0200 @@ -160,8 +160,7 @@ GClueLocation *gclue_location_create_from_nmeas (const char *nmeas[], - GClueLocation *prev_location, - GError **error); + GClueLocation *prev_location); GClueLocation *gclue_location_duplicate (GClueLocation *location); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/geoclue-2.7.0/src/gclue-locator.c new/geoclue-2.7.1/src/gclue-locator.c --- old/geoclue-2.7.0/src/gclue-locator.c 2023-01-22 21:37:05.000000000 +0100 +++ new/geoclue-2.7.1/src/gclue-locator.c 2023-09-03 10:27:30.000000000 +0200 @@ -54,7 +54,7 @@ static GClueLocationSourceStartResult gclue_locator_start (GClueLocationSource *source); -static GClueLocationSourceStopResult +static GClueLocationSourceStopResult gclue_locator_stop (GClueLocationSource *source); struct _GClueLocatorPrivate @@ -63,6 +63,8 @@ GList *active_sources; GClueAccuracyLevel accuracy_level; + gboolean priority_source_lock; + guint64 priority_source_lock_timestamp; }; G_DEFINE_TYPE_WITH_CODE (GClueLocator, @@ -81,13 +83,28 @@ #define MAX_SPEED 500 /* Meters per second */ #define MAX_LOCATION_AGE (30 * 60) /* Seconds. */ +#define MAX_PRIORITY_SOURCE_AGE 30 /* Seconds. */ +#define PRIORITY_ACCURACY_THRESHOLD 20 /* Meters */ static void set_location (GClueLocator *locator, - GClueLocation *location, - const char *src_name) + GClueLocationSource *source) { GClueLocation *cur_location; + GClueLocation *location; + const char *src_name = NULL; + gboolean update_priority_source = FALSE; + + location = gclue_location_source_get_location (source); + src_name = G_OBJECT_TYPE_NAME (source); + + if (gclue_location_get_accuracy (location) == + GCLUE_LOCATION_ACCURACY_UNKNOWN) { + /* If we do not know the accuracy, discard the update */ + g_debug ("Discarding %s location with unknown accuracy", + src_name); + return; + } cur_location = gclue_location_source_get_location (GCLUE_LOCATION_SOURCE (locator)); @@ -120,10 +137,34 @@ speed = G_MAXDOUBLE; } - if ((dist <= gclue_location_get_accuracy (location) || - speed > MAX_SPEED) && - gclue_location_get_accuracy (location) > - gclue_location_get_accuracy (cur_location)) { + update_priority_source = gclue_location_source_get_priority_source (source) && + (gclue_location_get_accuracy (location) < PRIORITY_ACCURACY_THRESHOLD); + + if (update_priority_source) { + if (!locator->priv->priority_source_lock) + g_debug ("Enabling Priority Source Lock"); + locator->priv->priority_source_lock = TRUE; + locator->priv->priority_source_lock_timestamp = new_timestamp; + } else if (locator->priv->priority_source_lock && + (new_timestamp - locator->priv->priority_source_lock_timestamp) >= MAX_PRIORITY_SOURCE_AGE) { + g_debug ("Priority Source Lock no longer active"); + locator->priv->priority_source_lock = FALSE; + } + + if (locator->priv->priority_source_lock && + !gclue_location_source_get_priority_source (source)) { + g_debug ("Priority Source Lock (age %lu) active, ignoring new %s location", + new_timestamp - locator->priv->priority_source_lock_timestamp, src_name); + return; + } + + if (update_priority_source) { + /* A priority source is updating, let it though */ + g_debug ("Priority Source Lock Active"); + } else if ((dist <= gclue_location_get_accuracy (location) || + speed > MAX_SPEED) && + gclue_location_get_accuracy (location) > + gclue_location_get_accuracy (cur_location)) { /* We only take the new location if either the previous one * lies outside its accuracy circle and was reachable with * a reasonable speed, OR it is more or as accurate as @@ -184,10 +225,8 @@ { GClueLocator *locator = GCLUE_LOCATOR (user_data); GClueLocationSource *source = GCLUE_LOCATION_SOURCE (gobject); - GClueLocation *location; - location = gclue_location_source_get_location (source); - set_location (locator, location, G_OBJECT_TYPE_NAME (source)); + set_location (locator, source); } static gboolean @@ -210,7 +249,7 @@ location = gclue_location_source_get_location (src); if (gclue_location_source_get_active (src) && location != NULL) - set_location (locator, location, G_OBJECT_TYPE_NAME (src)); + set_location (locator, src); gclue_location_source_start (src); } @@ -476,6 +515,8 @@ gclue_locator_init (GClueLocator *locator) { locator->priv = gclue_locator_get_instance_private (locator); + locator->priv->priority_source_lock = FALSE; + locator->priv->priority_source_lock_timestamp = 0; } static GClueLocationSourceStartResult diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/geoclue-2.7.0/src/gclue-modem-gps.c new/geoclue-2.7.1/src/gclue-modem-gps.c --- old/geoclue-2.7.0/src/gclue-modem-gps.c 2023-01-22 21:37:05.000000000 +0100 +++ new/geoclue-2.7.1/src/gclue-modem-gps.c 2023-09-03 10:27:30.000000000 +0200 @@ -198,7 +198,9 @@ static GClueModemGPS *source = NULL; if (source == NULL) { - source = g_object_new (GCLUE_TYPE_MODEM_GPS, NULL); + source = g_object_new (GCLUE_TYPE_MODEM_GPS, + "priority-source", TRUE, + NULL); g_object_weak_ref (G_OBJECT (source), on_modem_gps_destroyed, &source); @@ -216,21 +218,13 @@ GClueLocationSource *source = GCLUE_LOCATION_SOURCE (user_data); GClueLocation *prev_location; g_autoptr(GClueLocation) location = NULL; - g_autoptr(GError) error = NULL; prev_location = gclue_location_source_get_location (source); - location = gclue_location_create_from_nmeas (nmeas, - prev_location, - &error); + location = gclue_location_create_from_nmeas (nmeas, prev_location); - if (error != NULL) { - g_warning ("Error: %s", error->message); - - return; + if (location) { + gclue_location_source_set_location (source, location); } - - gclue_location_source_set_location (source, - location); } static GClueLocationSourceStartResult diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/geoclue-2.7.0/src/gclue-mozilla.c new/geoclue-2.7.1/src/gclue-mozilla.c --- old/geoclue-2.7.0/src/gclue-mozilla.c 2023-01-22 21:37:05.000000000 +0100 +++ new/geoclue-2.7.1/src/gclue-mozilla.c 2023-09-03 10:27:30.000000000 +0200 @@ -255,11 +255,13 @@ WPABSS *bss = WPA_BSS (iter->data); char mac[BSSID_STR_LEN + 1] = { 0 }; gint16 strength_dbm; + guint age_ms; if (gclue_mozilla_should_ignore_bss (bss)) continue; json_builder_begin_object (builder); + json_builder_set_member_name (builder, "macAddress"); get_bssid_from_bss (bss, mac); json_builder_add_string_value (builder, mac); @@ -267,8 +269,12 @@ json_builder_set_member_name (builder, "signalStrength"); strength_dbm = wpa_bss_get_signal (bss); json_builder_add_int_value (builder, strength_dbm); - json_builder_end_object (builder); + json_builder_set_member_name (builder, "age"); + age_ms = 1000 * wpa_bss_get_age (bss); + json_builder_add_int_value (builder, age_ms); + + json_builder_end_object (builder); has_bss = TRUE; } json_builder_end_array (builder); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/geoclue-2.7.0/src/gclue-nmea-source.c new/geoclue-2.7.1/src/gclue-nmea-source.c --- old/geoclue-2.7.0/src/gclue-nmea-source.c 2023-01-22 21:37:05.000000000 +0100 +++ new/geoclue-2.7.1/src/gclue-nmea-source.c 2023-09-03 10:27:30.000000000 +0200 @@ -730,13 +730,18 @@ g_warning ("Error when receiving message: %s", error->message); } + service_broken (source); + return; } else { - g_debug ("NMEA nothing to read"); + g_debug ("NMEA empty read"); + /* GLib has a bug where g_data_input_stream_read_upto_finish + * returns NULL when reading a line with only stop chars. + * Convert this NULL to a zero-length message. See: + * https://gitlab.gnome.org/GNOME/glib/-/issues/655 + */ + message = g_strdup (""); } - service_broken (source); - - return; } g_debug ("Network source sent: \"%s\"", message); @@ -744,8 +749,6 @@ g_strlcpy (gga, message, NMEA_STR_LEN); } else if (gclue_nmea_type_is (message, "RMC")) { g_strlcpy (rmc, message, NMEA_STR_LEN); - } else { - g_debug ("Ignoring NMEA sentence, as it's neither GGA or RMC: %s", message); } nmea_skip_delim (G_BUFFERED_INPUT_STREAM (data_input_stream), @@ -773,12 +776,8 @@ prev_location = gclue_location_source_get_location (GCLUE_LOCATION_SOURCE (source)); location = gclue_location_create_from_nmeas (sentences, - prev_location, - &error); - - if (error != NULL) { - g_warning ("Error: %s", error->message); - } else { + prev_location); + if (location) { gclue_location_source_set_location (GCLUE_LOCATION_SOURCE (source), location); } @@ -1071,7 +1070,9 @@ static GClueNMEASource *source = NULL; if (source == NULL) { - source = g_object_new (GCLUE_TYPE_NMEA_SOURCE, NULL); + source = g_object_new (GCLUE_TYPE_NMEA_SOURCE, + "priority-source", TRUE, + NULL); g_object_add_weak_pointer (G_OBJECT (source), (gpointer) &source); } else { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/geoclue-2.7.0/src/gclue-nmea-utils.c new/geoclue-2.7.1/src/gclue-nmea-utils.c --- old/geoclue-2.7.0/src/gclue-nmea-utils.c 2023-01-22 21:37:05.000000000 +0100 +++ new/geoclue-2.7.1/src/gclue-nmea-utils.c 2023-09-03 10:27:30.000000000 +0200 @@ -36,3 +36,39 @@ g_str_has_prefix (msg+3, nmeatype); } +/** + * gclue_nmea_timestamp_to_timespan + * @timestamp: NMEA timestamp string + * + * Parse the NMEA timestamp string, which is a field in NMEA sentences + * like GGA and RMC. + * + * Returns: a GTimeSpan (gint64) value of microseconds since midnight, + * or -1, if reading fails. + */ +GTimeSpan +gclue_nmea_timestamp_to_timespan (const gchar *timestamp) +{ + gint its, hours, minutes; + gdouble ts, seconds_f; + gchar *endptr; + + if (!timestamp || !*timestamp) + return -1; + + ts = g_ascii_strtod (timestamp, &endptr); + if (endptr != timestamp + g_utf8_strlen(timestamp, 12) || + ts < 0.0 || + ts >= 235960.0) + return -1; + + its = (gint) ts; /* Truncate towards zero */ + hours = its / 10000; + minutes = (its - 10000 * hours) / 100; + seconds_f = ts - 10000 * hours - 100 * minutes; /* Seconds plus fraction */ + + return (GTimeSpan) G_USEC_PER_SEC * (3600 * hours + + 60 * minutes + + seconds_f); +} + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/geoclue-2.7.0/src/gclue-nmea-utils.h new/geoclue-2.7.1/src/gclue-nmea-utils.h --- old/geoclue-2.7.0/src/gclue-nmea-utils.h 2023-01-22 21:37:05.000000000 +0100 +++ new/geoclue-2.7.1/src/gclue-nmea-utils.h 2023-09-03 10:27:30.000000000 +0200 @@ -24,6 +24,7 @@ G_BEGIN_DECLS gboolean gclue_nmea_type_is (const char *msg, const char *nmeatype); +GTimeSpan gclue_nmea_timestamp_to_timespan (const gchar *timestamp); G_END_DECLS diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/geoclue-2.7.0/src/gclue-web-source.c new/geoclue-2.7.1/src/gclue-web-source.c --- old/geoclue-2.7.0/src/gclue-web-source.c 2023-01-22 21:37:05.000000000 +0100 +++ new/geoclue-2.7.1/src/gclue-web-source.c 2023-09-03 10:27:30.000000000 +0200 @@ -565,6 +565,8 @@ if (location == NULL || gclue_location_get_accuracy (location) > SUBMISSION_ACCURACY_THRESHOLD || + gclue_location_get_accuracy (location) == + GCLUE_LOCATION_ACCURACY_UNKNOWN || gclue_location_get_timestamp (location) < web->priv->last_submitted + SUBMISSION_TIME_THRESHOLD) return;
