diff -Nru gpsd-3.20/debian/changelog gpsd-3.20/debian/changelog --- gpsd-3.20/debian/changelog 2020-05-20 06:23:02.000000000 +0000 +++ gpsd-3.20/debian/changelog 2021-08-04 15:34:28.000000000 +0000 @@ -1,3 +1,16 @@ +gpsd (3.20-8ubuntu0.4) focal-security; urgency=medium + + * SECURITY UPDATE: incorrect time jump (LP: #1938730) + - debian/patches/fix_wrong_gps_rollover.patch: don't compute wrong GPS + rollover after 2020-10-23. + - debian/control*: add python3-matplotlib, python3-gps, python3-gi, + python3-cairo, gir1.2-gtk-3.0, python3-serial, python3-gi-cairo to + Build-Depends so tests run. + - debian/source/include-binaries: include some updated binary tests. + - No CVE number + + -- Marc Deslauriers Wed, 04 Aug 2021 11:34:28 -0400 + gpsd (3.20-8ubuntu0.2) focal; urgency=medium * fix json missing quotes on device add (LP: #1879272) diff -Nru gpsd-3.20/debian/control gpsd-3.20/debian/control --- gpsd-3.20/debian/control 2020-05-20 06:23:02.000000000 +0000 +++ gpsd-3.20/debian/control 2021-08-04 15:34:28.000000000 +0000 @@ -13,6 +13,7 @@ libusb-1.0-0-dev, libdbus-1-dev, libglib2.0-dev, libdbus-glib-1-dev, makedev, libbluetooth-dev [linux-any], + python3-matplotlib, python3-gps, python3-gi, python3-cairo, gir1.2-gtk-3.0, python3-serial, python3-gi-cairo, qtbase5-dev, lsb-release, bc, dpkg-dev (>= 1.15.6), diff -Nru gpsd-3.20/debian/control.in gpsd-3.20/debian/control.in --- gpsd-3.20/debian/control.in 2020-05-20 06:23:02.000000000 +0000 +++ gpsd-3.20/debian/control.in 2021-08-04 15:34:28.000000000 +0000 @@ -13,6 +13,7 @@ libusb-1.0-0-dev, libdbus-1-dev, libglib2.0-dev, libdbus-glib-1-dev, makedev, libbluetooth-dev [linux-any], + python3-matplotlib, python3-gps, python3-gi, python3-cairo, gir1.2-gtk-3.0, python3-serial, python3-gi-cairo, qtbase5-dev, lsb-release, bc, dpkg-dev (>= 1.15.6), diff -Nru gpsd-3.20/debian/patches/fix_wrong_gps_rollover.patch gpsd-3.20/debian/patches/fix_wrong_gps_rollover.patch --- gpsd-3.20/debian/patches/fix_wrong_gps_rollover.patch 1970-01-01 00:00:00.000000000 +0000 +++ gpsd-3.20/debian/patches/fix_wrong_gps_rollover.patch 2021-08-04 15:34:28.000000000 +0000 @@ -0,0 +1,490 @@ +Description: fix incorrect time jump issue +Origin: backported from Debian's 3.22-4 package + +#Index: pkg-gpsd/NEWS +#=================================================================== +#--- pkg-gpsd.orig/NEWS +#+++ pkg-gpsd/NEWS +#@@ -1,6 +1,9 @@ +# GPSD project news +# +#-3.22: 2020-01-08 +#+3.22.1~dev: unreleased +#+ (gpsd/timebase.c" Don't compute wrong GPS rollover after 2020-10-23.) +#+ +#+3.22: 2021-01-08 +# Added client/gpscsv to convert gpsd JSON to csv. +# Added client/gpsplot to dynamically plot gpsd JSON. +# Added client/gpssubframe to decode gpsd SUBFRAME JSON. +--- a/drivers.c ++++ b/drivers.c +@@ -23,15 +23,17 @@ ssize_t generic_get(struct gps_device_t + return packet_get(session->gpsdata.gps_fd, &session->lexer); + } + ++// This handles only bad, comment, and maybe NMEA packets. + gps_mask_t generic_parse_input(struct gps_device_t *session) + { +- if (session->lexer.type == BAD_PACKET) +- return 0; +- else if (session->lexer.type == COMMENT_PACKET) { +- gpsd_set_century(session); ++ if (BAD_PACKET == session->lexer.type || ++ COMMENT_PACKET == session->lexer.type) { ++ // ignore bad packets and comment packets + return 0; ++ } ++ + #ifdef NMEA0183_ENABLE +- } else if (session->lexer.type == NMEA_PACKET) { ++ if (NMEA_PACKET == session->lexer.type) { + const struct gps_type_t **dp; + gps_mask_t st = 0; + char *sentence = (char *)session->lexer.outbuffer; +@@ -64,13 +66,13 @@ gps_mask_t generic_parse_input(struct gp + } + } + return st; +-#endif /* NMEA0183_ENABLE */ +- } else { +- GPSD_LOG(LOG_SHOUT, &session->context->errout, +- "packet type %d fell through (should never happen): %s.\n", +- session->lexer.type, gpsd_prettydump(session)); +- return 0; + } ++#endif /* NMEA0183_ENABLE */ ++ ++ GPSD_LOG(LOG_SHOUT, &session->context->errout, ++ "packet type %d fell through (should never happen): %s.\n", ++ session->lexer.type, gpsd_prettydump(session)); ++ return 0; + } + + /************************************************************************** +--- a/gps/fake.py ++++ b/gps/fake.py +@@ -169,7 +169,7 @@ class TestLoad(object): + commentlen += len(packet) + # Some comments are magic + if b"Serial:" in packet: +- # Change serial parameters ++ # "#Serial:' -- Change serial parameters + packet = packet[1:].strip() + try: + (_xx, baud, params) = packet.split() +@@ -191,10 +191,13 @@ class TestLoad(object): + self.name) + self.serial = (baud, databits, parity, stopbits) + elif b"Transport: UDP" in packet: ++ # "#Transport:' + self.sourcetype = "UDP" + elif b"Transport: TCP" in packet: ++ # "#Transport:' + self.sourcetype = "TCP" + elif b"Delay-Cookie:" in packet: ++ # "#Delay-Cookie:' + if packet.startswith(b"#"): + packet = packet[1:] + try: +@@ -205,6 +208,10 @@ class TestLoad(object): + raise TestLoadError("bad Delay-Cookie line in %s" % + self.name) + self.resplit = True ++ elif b"Date:" in packet: ++ # "# Date: yyyy-mm-dd' -- preset date ++ self.sentences.append(packet) ++ # drop all other comments silently + else: + if type_latch is None: + type_latch = ptype +--- a/libgpsd_core.c ++++ b/libgpsd_core.c +@@ -1462,69 +1462,84 @@ gps_mask_t gpsd_poll(struct gps_device_t + session->gpsdata.online.tv_nsec = 0; + } + return NODATA_IS; +- } else /* (newlen > 0) */ { +- GPSD_LOG(LOG_RAW, &session->context->errout, +- "packet sniff on %s finds type %d\n", +- session->gpsdata.dev.path, session->lexer.type); +- if (session->lexer.type == COMMENT_PACKET) { +- if (strcmp((const char *)session->lexer.outbuffer, "# EOF\n") == 0) { +- GPSD_LOG(LOG_PROG, &session->context->errout, +- "synthetic EOF\n"); +- return EOF_IS; +- } +- else +- GPSD_LOG(LOG_PROG, &session->context->errout, +- "comment, sync lock deferred\n"); +- /* FALL THROUGH */ +- } else if (session->lexer.type > COMMENT_PACKET) { +- if (session->device_type == NULL) +- driver_change = true; +- else { +- int newtype = session->lexer.type; +- /* +- * Are we seeing a new packet type? Then we probably +- * want to change drivers. +- */ +- bool new_packet_type = +- (newtype != session->device_type->packet_type); +- /* +- * Possibly the old driver has a mode-switcher method, in +- * which case we know it can handle NMEA itself and may +- * want to do special things (like tracking whether a +- * previous mode switch to binary succeeded in suppressing +- * NMEA). +- */ ++ } ++ // else (0 < newlen) ++ ++ GPSD_LOG(LOG_RAW, &session->context->errout, ++ "packet sniff on %s finds type %d\n", ++ session->gpsdata.dev.path, session->lexer.type); ++ if (COMMENT_PACKET == session->lexer.type) { ++ // deal with regression test helper macros ++ const char date_str[] = "# Date: "; ++ if (0 == strcmp((const char *)session->lexer.outbuffer, ++ "# EOF\n")) { ++ // undocumented, used by gpsfake to signal EOF ++ GPSD_LOG(LOG_PROG, &session->context->errout, ++ "synthetic EOF\n"); ++ return EOF_IS; ++ } ++ if (0 == strncmp((const char *)session->lexer.outbuffer, ++ date_str, sizeof(date_str) - 1)) { ++ // # Date: yyyy-mm-dd ++ // used by regression tests to correct ++ // change start time, gps weeks, etc. ++ gpsd_set_century(session); ++ ++ GPSD_LOG(LOG_PROG, &session->context->errout, ++ "start_time %lld\n", ++ (long long)session->context->start_time); ++ } ++ GPSD_LOG(LOG_PROG, &session->context->errout, ++ "comment, sync lock deferred: >%s<\n", ++ session->lexer.outbuffer); ++ } else if (COMMENT_PACKET < session->lexer.type) { ++ if (NULL == session->device_type) { ++ driver_change = true; ++ } else { ++ int newtype = session->lexer.type; ++ /* ++ * Are we seeing a new packet type? Then we probably ++ * want to change drivers. ++ */ ++ bool new_packet_type = ++ (newtype != session->device_type->packet_type); ++ /* ++ * Possibly the old driver has a mode-switcher method, in ++ * which case we know it can handle NMEA itself and may ++ * want to do special things (like tracking whether a ++ * previous mode switch to binary succeeded in suppressing ++ * NMEA). ++ */ + #ifdef RECONFIGURE_ENABLE +- bool dependent_nmea = (newtype == NMEA_PACKET && +- session->device_type->mode_switcher != NULL); ++ bool dependent_nmea = (NMEA_PACKET == newtype && ++ NULL != session->device_type->mode_switcher); + #else +- bool dependent_nmea = false; ++ bool dependent_nmea = false; + #endif /* RECONFIGURE_ENABLE */ + +- /* +- * Compute whether to switch drivers. +- * If the previous driver type was sticky and this one +- * isn't, we'll revert after processing the packet. +- */ +- driver_change = new_packet_type && !dependent_nmea; +- } +- if (driver_change) { +- const struct gps_type_t **dp; ++ /* ++ * Compute whether to switch drivers. ++ * If the previous driver type was sticky and this one ++ * isn't, we'll revert after processing the packet. ++ */ ++ driver_change = new_packet_type && !dependent_nmea; ++ } ++ if (driver_change) { ++ const struct gps_type_t **dp; + +- for (dp = gpsd_drivers; *dp; dp++) +- if (session->lexer.type == (*dp)->packet_type) { +- GPSD_LOG(LOG_PROG, &session->context->errout, +- "switching to match packet type %d: %s\n", +- session->lexer.type, gpsd_prettydump(session)); +- (void)gpsd_switch_driver(session, (*dp)->type_name); +- break; +- } +- } +- session->badcount = 0; +- session->gpsdata.dev.driver_mode = +- (session->lexer.type > NMEA_PACKET) ? MODE_BINARY : MODE_NMEA; +- /* FALL THROUGH */ +- } else if (hunt_failure(session) && !gpsd_next_hunt_setting(session)) { ++ for (dp = gpsd_drivers; *dp; dp++) ++ if (session->lexer.type == (*dp)->packet_type) { ++ GPSD_LOG(LOG_PROG, &session->context->errout, ++ "switching to match packet type %d: %s\n", ++ session->lexer.type, gpsd_prettydump(session)); ++ (void)gpsd_switch_driver(session, (*dp)->type_name); ++ break; ++ } ++ } ++ session->badcount = 0; ++ session->gpsdata.dev.driver_mode = ++ (session->lexer.type > NMEA_PACKET) ? MODE_BINARY : MODE_NMEA; ++ } else if (hunt_failure(session) && !gpsd_next_hunt_setting(session)) { + (void)clock_gettime(CLOCK_REALTIME, &ts_now); + TS_SUB(&delta, &ts_now, &session->gpsdata.online); + GPSD_LOG(LOG_INF, &session->context->errout, +@@ -1532,7 +1547,6 @@ gps_mask_t gpsd_poll(struct gps_device_t + session->gpsdata.dev.path, + timespec_str(&delta, ts_buf, sizeof(ts_buf))); + return ERROR_SET; +- } + } + + if (session->lexer.outbuflen == 0) { /* got new data, but no packet */ +--- a/timebase.c ++++ b/timebase.c +@@ -199,8 +199,8 @@ SPDX-License-Identifier: BSD-2-clause + + #include "gpsd.h" + ++// initialize the GPS context's time fields + void gpsd_time_init(struct gps_context_t *context, time_t starttime) +-/* initialize the GPS context's time fields */ + { + /* + * gpsd can't work with 'right' timezones (leapseconds inserted in +@@ -220,7 +220,8 @@ void gpsd_time_init(struct gps_context_t + context->century = BUILD_CENTURY; + context->start_time = starttime; + +- context->rollovers = (int)((context->start_time-GPS_EPOCH) / GPS_ROLLOVER); ++ context->rollovers = (int)((context->start_time - GPS_EPOCH) / ++ GPS_ROLLOVER); + + if (GPS_EPOCH > context->start_time) { + GPSD_LOG(LOG_ERROR, &context->errout, +@@ -246,27 +247,56 @@ void gpsd_time_init(struct gps_context_t + } + } + +-void gpsd_set_century(struct gps_device_t *session) + /* +- * Interpret "Date: yyyy-mm-dd", setting the session context +- * century from the year. We do this so the behavior of the +- * regression tests won't depend on what century the daemon +- * started up in. ++ * Interpret "#Date: yyyy-mm-dd", setting the session context ++ * start time. We do this so the behavior of the ++ * regression tests won't depend on current system time. + */ ++void gpsd_set_century(struct gps_device_t *session) + { +- char *end; +- if (strstr((char *)session->lexer.outbuffer, "Date:") != NULL) { +- int year; +- unsigned char *cp = session->lexer.outbuffer + 5; +- while (isspace(*cp)) +- ++cp; +- year = (int)strtol((char *)cp, &end, 10); +- session->context->century = year - (year % 100); ++ int ret; ++ unsigned year = 0; ++ unsigned month = 0; ++ unsigned day = 0; ++ struct gps_context_t *context = session->context; ++ struct tm date = {0}; ++ ++ ret = sscanf((const char *)session->lexer.outbuffer, "# Date: %u-%u-%u", ++ &year, &month, &day); ++ if (1 > ret) { ++ // give up unless we at least got a year ++ return; ++ } ++ ++ if (1968 > year || 2200 < year) { ++ // bad year ++ return; + } ++ ++ context->century = year - (year % 100); ++ ++ date.tm_year = year - 1900; // year, 1999..2099 ++ if (1 > month || 12 < month) { ++ month = 1; ++ } ++ date.tm_mon = month; // month 1..12 ++ if (1 > day || 31 < day) { ++ day = 1; ++ } ++ date.tm_mday = day; // day 1..31 ++ context->start_time = mkgmtime(&date); ++ context->rollovers = (int)((context->start_time - GPS_EPOCH) / ++ GPS_ROLLOVER); ++ ++ GPSD_LOG(LOG_PROG, &context->errout, ++ "Setting century: %d rollovers %d %d-%d-%d\n", ++ context->century, context->rollovers, year, month, day); ++ ++ gpsd_time_init(context, context->start_time); + } + + #ifdef NMEA0183_ENABLE +-/* resolve a UTC date, checking for rollovers */ ++// resolve a UTC date, checking for rollovers + timespec_t gpsd_utc_resolve(struct gps_device_t *session) + { + /* +@@ -308,19 +338,9 @@ timespec_t gpsd_utc_resolve(struct gps_d + } + + /* +- * If the GPS is reporting a time from before the daemon started, we've +- * had a rollover event while the daemon was running. ++ * If the GPS is reporting a time from before the daemon started, ++ * maybe we've had a rollover event while the daemon was running. + */ +-#ifdef __UNUSED__ +- // 5 Dec 2019 +- // This fails ALL regression tests as start time after regression added +- if (t.tv_sec < (time_t)session->context->start_time) { +- (void)timespec_to_iso8601(t, scr, sizeof(scr)); +- GPSD_LOG(LOG_WARN, &session->context->errout, +- "GPS week rollover makes time %s (%lld) invalid\n", +- scr, (long long)t.tv_sec); +- } +-#endif // __UNUSED__ + + return t; + } +@@ -351,8 +371,7 @@ void gpsd_century_update(struct gps_devi + } + #endif /* NMEA0183_ENABLE */ + +-/* gpsd_gpstime_resolv() convert week/tow to UTC as a timespec +- */ ++// gpsd_gpstime_resolv() convert GPS week/tow to UTC as a timespec + timespec_t gpsd_gpstime_resolv(struct gps_device_t *session, + unsigned short week, timespec_t tow) + { +@@ -382,19 +401,12 @@ timespec_t gpsd_gpstime_resolv(struct gp + if (week < 1024) + week += session->context->rollovers * 1024; + +- /* sanity check week number, GPS epoch, against leap seconds +- * Does not work well with regressions because the leap_sconds +- * could be from the receiver, or from BUILD_LEAPSECONDS. */ +- if (0 < session->context->leap_seconds && +- 19 > session->context->leap_seconds && +- 2180 < week) { +- /* assume leap second = 19 by 31 Dec 2022 +- * so week > 2180 is way in the future, do not allow it */ +- week -= 1024; +- GPSD_LOG(LOG_WARN, &session->context->errout, +- "GPS week confusion. Adjusted week %u for leap %d\n", +- week, session->context->leap_seconds); +- } ++ /* This used to sanity check week number, GPS epoch, against leap ++ * seconds. Did not work well with regressions because the leap_sconds ++ * could be from the receiver, or from BUILD_LEAPSECONDS. ++ * Maybe if the regressions files provided BUILD_LEAPSECONDS this ++ * could be tried again. ++ */ + + // gcc needs the (time_t)week to not overflow. clang got it right. + // if time_t is 32-bits, then still 2038 issues +--- a/test/daemon/trimble-lassen_iq-playacar.log.chk ++++ b/test/daemon/trimble-lassen_iq-playacar.log.chk +@@ -1,26 +1,26 @@ +-$GPRMC,040929.00,V,,S,,W,0.0000,0.000,120419,,*22 ++$GPRMC,040929.00,V,,S,,W,0.0000,0.000,270899,,*20 + $GPGSA,A,1,,,,,,,,,,,,,,,,*32 +-{"class":"TPV","mode":1,"time":"2019-04-12T04:09:29.000Z","ept":0.005} +-$GPRMC,040930.00,V,2037.7075,N,08704.0535,W,,,120419,-2.0,W*6A +-{"class":"TPV","mode":0,"time":"2019-04-12T04:09:30.000Z","ept":0.005} ++{"class":"TPV","mode":1,"time":"1999-08-27T04:09:29.000Z","ept":0.005} ++$GPRMC,040930.00,V,2037.7075,N,08704.0535,W,,,270899,-2.0,W*68 ++{"class":"TPV","mode":0,"time":"1999-08-27T04:09:30.000Z","ept":0.005} + $GPGGA,040930.00,2037.7075,N,08704.0535,W,1,05,2.34,27.90,M,-15.010,M,,*6F +-$GPRMC,040930.00,A,2037.7075,N,08704.0535,W,0.0000,0.000,120419,-2.0,W*4D ++$GPRMC,040930.00,A,2037.7075,N,08704.0535,W,0.0000,0.000,270899,-2.0,W*4F + $GPGSA,A,3,,,,,,,,,,,,,2.9,2.3,1.7*3E +-{"class":"TPV","mode":3,"time":"2019-04-12T04:09:30.000Z","ept":0.005,"lat":20.628457567,"lon":-87.067558169,"altHAE":12.892,"altMSL":27.902,"alt":27.902,"epv":39.373,"track":0.0000,"magtrack":358.0076,"magvar":-2.0,"speed":0.000,"climb":0.000,"velN":0.000,"velE":0.000,"velD":-0.000,"geoidSep":-15.010,"eph":44.377,"sep":55.020} +-$GPRMC,040931.00,A,2037.7075,N,08704.0535,W,,,120419,-2.0,W*7C +-{"class":"TPV","mode":0,"time":"2019-04-12T04:09:31.000Z","ept":0.005} ++{"class":"TPV","mode":3,"time":"1999-08-27T04:09:30.000Z","ept":0.005,"lat":20.628457567,"lon":-87.067558169,"altHAE":12.892,"altMSL":27.902,"alt":27.902,"epv":39.373,"track":0.0000,"magtrack":358.0076,"magvar":-2.0,"speed":0.000,"climb":0.000,"velN":0.000,"velE":0.000,"velD":-0.000,"geoidSep":-15.010,"eph":44.377,"sep":55.020} ++$GPRMC,040931.00,A,2037.7075,N,08704.0535,W,,,270899,-2.0,W*7E ++{"class":"TPV","mode":0,"time":"1999-08-27T04:09:31.000Z","ept":0.005} + $GPGGA,040931.00,2037.7075,N,08704.0535,W,1,05,2.34,27.90,M,-15.010,M,,*6E +-$GPRMC,040931.00,A,2037.7075,N,08704.0535,W,0.0000,0.000,120419,-2.0,W*4C ++$GPRMC,040931.00,A,2037.7075,N,08704.0535,W,0.0000,0.000,270899,-2.0,W*4E + $GPGSA,A,3,,,,,,,,,,,,,2.9,2.3,1.7*3E +-{"class":"TPV","mode":3,"time":"2019-04-12T04:09:31.000Z","ept":0.005,"lat":20.628457697,"lon":-87.067558187,"altHAE":12.894,"altMSL":27.904,"alt":27.904,"epv":39.384,"track":0.0000,"magtrack":358.0076,"magvar":-2.0,"speed":0.000,"climb":0.000,"epc":78.76,"velN":0.000,"velE":0.000,"velD":-0.000,"geoidSep":-15.010,"eph":44.392,"sep":55.038} +-$GPRMC,040932.00,A,2037.7075,N,08704.0535,W,,,120419,-2.0,W*7F +-{"class":"TPV","mode":0,"time":"2019-04-12T04:09:32.000Z","ept":0.005} ++{"class":"TPV","mode":3,"time":"1999-08-27T04:09:31.000Z","ept":0.005,"lat":20.628457697,"lon":-87.067558187,"altHAE":12.894,"altMSL":27.904,"alt":27.904,"epv":39.384,"track":0.0000,"magtrack":358.0076,"magvar":-2.0,"speed":0.000,"climb":0.000,"epc":78.76,"velN":0.000,"velE":0.000,"velD":-0.000,"geoidSep":-15.010,"eph":44.392,"sep":55.038} ++$GPRMC,040932.00,A,2037.7075,N,08704.0535,W,,,270899,-2.0,W*7D ++{"class":"TPV","mode":0,"time":"1999-08-27T04:09:32.000Z","ept":0.005} + $GPGGA,040932.00,2037.7075,N,08704.0535,W,1,05,2.34,27.91,M,-15.010,M,,*6C +-$GPRMC,040932.00,A,2037.7075,N,08704.0535,W,0.0000,0.000,120419,-2.0,W*4F ++$GPRMC,040932.00,A,2037.7075,N,08704.0535,W,0.0000,0.000,270899,-2.0,W*4D + $GPGSA,A,3,,,,,,,,,,,,,2.9,2.3,1.7*3E +-{"class":"TPV","mode":3,"time":"2019-04-12T04:09:32.000Z","ept":0.005,"lat":20.628457840,"lon":-87.067558197,"altHAE":12.896,"altMSL":27.906,"alt":27.906,"epv":39.384,"track":0.0000,"magtrack":358.0076,"magvar":-2.0,"speed":0.000,"climb":0.000,"epc":78.77,"velN":0.000,"velE":0.000,"velD":-0.000,"geoidSep":-15.010,"eph":44.392,"sep":55.038} +-$GPRMC,040933.00,A,2037.7075,N,08704.0535,W,,,120419,-2.0,W*7E +-{"class":"TPV","mode":0,"time":"2019-04-12T04:09:33.000Z","ept":0.005} ++{"class":"TPV","mode":3,"time":"1999-08-27T04:09:32.000Z","ept":0.005,"lat":20.628457840,"lon":-87.067558197,"altHAE":12.896,"altMSL":27.906,"alt":27.906,"epv":39.384,"track":0.0000,"magtrack":358.0076,"magvar":-2.0,"speed":0.000,"climb":0.000,"epc":78.77,"velN":0.000,"velE":0.000,"velD":-0.000,"geoidSep":-15.010,"eph":44.392,"sep":55.038} ++$GPRMC,040933.00,A,2037.7075,N,08704.0535,W,,,270899,-2.0,W*7C ++{"class":"TPV","mode":0,"time":"1999-08-27T04:09:33.000Z","ept":0.005} + $GPGGA,040937.53,2037.7075,N,08704.0535,W,1,05,2.34,27.91,M,-15.010,M,,*6F + $GPRMC,040937.53,A,2037.7075,N,08704.0535,W,0.0000,0.000,221206,-2.0,W*46 + $GPGSA,A,3,,,,,,,,,,,,,2.9,2.3,1.7*3E +--- a/test/daemon/trimble-lassen_iq-3dfix.log.chk ++++ b/test/daemon/trimble-lassen_iq-3dfix.log.chk +@@ -8,22 +8,22 @@ $GPRMC,,V,,S,,W,,,,,*35 + $GPGSA,A,1,,,,,,,,,,,,,,,,*32 + {"class":"TPV","mode":1} + $GPGSV,1,1,01,19,26,250,29*48 +-{"class":"SKY","time":"2019-04-07T06:57:22.584Z","vdop":2.56,"tdop":1.47,"hdop":1.43,"gdop":3.28,"pdop":2.93,"satellites":[]} ++{"class":"SKY","time":"1999-08-22T06:57:22.584Z","vdop":2.56,"tdop":1.47,"hdop":1.43,"gdop":3.28,"pdop":2.93,"satellites":[]} + $GPGSV,1,1,02,19,26,250,29,18,26,096,35*7F +-{"class":"SKY","time":"2019-04-07T06:57:22.584Z","vdop":2.56,"tdop":1.47,"hdop":1.43,"gdop":3.28,"pdop":2.93,"satellites":[{"PRN":19,"el":26.0,"az":249.7,"ss":29.0,"used":true,"gnssid":0,"svid":19}]} ++{"class":"SKY","time":"1999-08-22T06:57:22.584Z","vdop":2.56,"tdop":1.47,"hdop":1.43,"gdop":3.28,"pdop":2.93,"satellites":[{"PRN":19,"el":26.0,"az":249.7,"ss":29.0,"used":true,"gnssid":0,"svid":19}]} + $GPGSV,1,1,03,19,26,250,29,18,26,096,35,01,29,221,26*41 +-{"class":"SKY","time":"2019-04-07T06:57:22.584Z","vdop":2.56,"tdop":1.47,"hdop":1.43,"gdop":3.28,"pdop":2.93,"satellites":[{"PRN":19,"el":26.0,"az":249.7,"ss":29.0,"used":true,"gnssid":0,"svid":19}]} ++{"class":"SKY","time":"1999-08-22T06:57:22.584Z","vdop":2.56,"tdop":1.47,"hdop":1.43,"gdop":3.28,"pdop":2.93,"satellites":[{"PRN":19,"el":26.0,"az":249.7,"ss":29.0,"used":true,"gnssid":0,"svid":19}]} + $GPGSV,1,1,04,19,26,250,29,18,26,096,35,01,29,221,26,11,24,307,29*7F +-{"class":"SKY","time":"2019-04-07T06:57:22.584Z","xdop":0.72,"ydop":2.76,"vdop":2.56,"tdop":1.47,"hdop":1.43,"gdop":3.28,"pdop":2.93,"satellites":[{"PRN":19,"el":26.0,"az":249.7,"ss":29.0,"used":true,"gnssid":0,"svid":19},{"PRN":18,"el":26.3,"az":95.6,"ss":35.0,"used":true,"gnssid":0,"svid":18}]} ++{"class":"SKY","time":"1999-08-22T06:57:22.584Z","xdop":0.72,"ydop":2.76,"vdop":2.56,"tdop":1.47,"hdop":1.43,"gdop":3.28,"pdop":2.93,"satellites":[{"PRN":19,"el":26.0,"az":249.7,"ss":29.0,"used":true,"gnssid":0,"svid":19},{"PRN":18,"el":26.3,"az":95.6,"ss":35.0,"used":true,"gnssid":0,"svid":18}]} + $GPGSV,2,1,05,19,26,250,29,18,26,096,35,01,29,221,26,11,24,307,29*7D + $GPGSV,2,2,05,03,08,225,28*48 +-{"class":"SKY","time":"2019-04-07T06:57:22.584Z","xdop":0.72,"ydop":2.76,"vdop":2.56,"tdop":1.47,"hdop":1.43,"gdop":3.28,"pdop":2.93,"satellites":[{"PRN":19,"el":26.0,"az":249.7,"ss":29.0,"used":true,"gnssid":0,"svid":19},{"PRN":18,"el":26.3,"az":95.6,"ss":35.0,"used":true,"gnssid":0,"svid":18},{"PRN":1,"el":29.1,"az":221.2,"ss":26.0,"used":true,"gnssid":0,"svid":1}]} ++{"class":"SKY","time":"1999-08-22T06:57:22.584Z","xdop":0.72,"ydop":2.76,"vdop":2.56,"tdop":1.47,"hdop":1.43,"gdop":3.28,"pdop":2.93,"satellites":[{"PRN":19,"el":26.0,"az":249.7,"ss":29.0,"used":true,"gnssid":0,"svid":19},{"PRN":18,"el":26.3,"az":95.6,"ss":35.0,"used":true,"gnssid":0,"svid":18},{"PRN":1,"el":29.1,"az":221.2,"ss":26.0,"used":true,"gnssid":0,"svid":1}]} + $GPGSV,2,1,06,19,26,250,29,18,26,096,35,01,29,221,26,11,24,307,29*7E + $GPGSV,2,2,06,03,08,225,28,22,65,094,38*7E +-{"class":"SKY","time":"2019-04-07T06:57:22.584Z","xdop":0.72,"ydop":2.76,"vdop":2.56,"tdop":1.47,"hdop":1.43,"gdop":3.28,"pdop":2.93,"satellites":[{"PRN":19,"el":26.0,"az":249.7,"ss":29.0,"used":true,"gnssid":0,"svid":19},{"PRN":18,"el":26.3,"az":95.6,"ss":35.0,"used":true,"gnssid":0,"svid":18},{"PRN":1,"el":29.1,"az":221.2,"ss":26.0,"used":true,"gnssid":0,"svid":1},{"PRN":11,"el":24.4,"az":307.3,"ss":29.0,"used":true,"gnssid":0,"svid":11}]} ++{"class":"SKY","time":"1999-08-22T06:57:22.584Z","xdop":0.72,"ydop":2.76,"vdop":2.56,"tdop":1.47,"hdop":1.43,"gdop":3.28,"pdop":2.93,"satellites":[{"PRN":19,"el":26.0,"az":249.7,"ss":29.0,"used":true,"gnssid":0,"svid":19},{"PRN":18,"el":26.3,"az":95.6,"ss":35.0,"used":true,"gnssid":0,"svid":18},{"PRN":1,"el":29.1,"az":221.2,"ss":26.0,"used":true,"gnssid":0,"svid":1},{"PRN":11,"el":24.4,"az":307.3,"ss":29.0,"used":true,"gnssid":0,"svid":11}]} + $GPGSV,2,1,07,19,26,250,29,18,26,096,35,01,29,221,26,11,24,307,29*7F + $GPGSV,2,2,07,03,08,225,28,22,65,094,38,09,24,045,38*4A +-{"class":"SKY","time":"2019-04-07T06:57:22.584Z","xdop":0.72,"ydop":2.76,"vdop":2.56,"tdop":1.47,"hdop":1.43,"gdop":3.28,"pdop":2.93,"satellites":[{"PRN":19,"el":26.0,"az":249.7,"ss":29.0,"used":true,"gnssid":0,"svid":19},{"PRN":18,"el":26.3,"az":95.6,"ss":35.0,"used":true,"gnssid":0,"svid":18},{"PRN":1,"el":29.1,"az":221.2,"ss":26.0,"used":true,"gnssid":0,"svid":1},{"PRN":11,"el":24.4,"az":307.3,"ss":29.0,"used":true,"gnssid":0,"svid":11},{"PRN":3,"el":7.9,"az":225.4,"ss":28.0,"used":true,"gnssid":0,"svid":3}]} ++{"class":"SKY","time":"1999-08-22T06:57:22.584Z","xdop":0.72,"ydop":2.76,"vdop":2.56,"tdop":1.47,"hdop":1.43,"gdop":3.28,"pdop":2.93,"satellites":[{"PRN":19,"el":26.0,"az":249.7,"ss":29.0,"used":true,"gnssid":0,"svid":19},{"PRN":18,"el":26.3,"az":95.6,"ss":35.0,"used":true,"gnssid":0,"svid":18},{"PRN":1,"el":29.1,"az":221.2,"ss":26.0,"used":true,"gnssid":0,"svid":1},{"PRN":11,"el":24.4,"az":307.3,"ss":29.0,"used":true,"gnssid":0,"svid":11},{"PRN":3,"el":7.9,"az":225.4,"ss":28.0,"used":true,"gnssid":0,"svid":3}]} + $GPRMC,,V,,S,,W,,,,,*35 + $GPGSA,A,1,19,18,1,11,3,22,9,,,,,,,,,*08 + {"class":"TPV","mode":1} +--- a/test/daemon/trimble-lasseniq-bin2d.log.chk ++++ b/test/daemon/trimble-lasseniq-bin2d.log.chk +@@ -1,5 +1,5 @@ +-$GPRMC,233739.00,V,4404.1298,N,12118.8428,W,,,120419,14.4,E*67 +-{"class":"TPV","mode":0,"time":"2019-04-12T23:37:39.000Z","ept":0.005} ++$GPRMC,233739.00,V,4404.1298,N,12118.8428,W,,,270899,14.4,E*65 ++{"class":"TPV","mode":0,"time":"1999-08-27T23:37:39.000Z","ept":0.005} + $GPZDA,233739.00,01,11,2019,00,00*62 + $GPGGA,233739.00,4404.1299,N,12118.8429,W,1,03,,1126.37,M,-22.154,M,,*7A + $GPRMC,233739.00,A,4404.1299,N,12118.8429,W,0.0000,0.000,011119,14.4,E*46 diff -Nru gpsd-3.20/debian/patches/series gpsd-3.20/debian/patches/series --- gpsd-3.20/debian/patches/series 2020-05-20 06:23:02.000000000 +0000 +++ gpsd-3.20/debian/patches/series 2021-08-04 15:34:28.000000000 +0000 @@ -6,3 +6,4 @@ ignore-test-xgps_deps_check fix-soname lp-1879272-gpsd-Quote-the-activated-timestamp-in-the-json-paylo.patch +fix_wrong_gps_rollover.patch diff -Nru gpsd-3.20/debian/source/include-binaries gpsd-3.20/debian/source/include-binaries --- gpsd-3.20/debian/source/include-binaries 1970-01-01 00:00:00.000000000 +0000 +++ gpsd-3.20/debian/source/include-binaries 2021-08-04 15:34:28.000000000 +0000 @@ -0,0 +1 @@ +test/daemon/sirfstarv.log Binary files /tmp/tmp5gty_b8n/gRPhbOLEyA/gpsd-3.20/test/daemon/sirfstarv.log and /tmp/tmp5gty_b8n/nCvxyBDJ2k/gpsd-3.20/test/daemon/sirfstarv.log differ