commit a3d3f4687f25688140f5a391b437af1dca8e0d5c Author: Miroslav Lichvar Date: Tue Jun 11 16:17:37 2024 +0200 nmea: Fix conversion of leap second. When a leap second is inserted, the RMC message reports time of 23:59:60, which overflows in mktime() to 0:00:00 after the leap second with an incremented TAI-UTC offset. This causes a one-second error in the offset meaured by ts2phc. Check the seconds field of the RMC message and convert 60 to 59 to make the timestamp ambiguous per is_utc_ambiguous() and ignored by ts2phc to avoid updating the clock with the one-second error. Signed-off-by: Miroslav Lichvar Reviewed-by: Jacob Keller diff --git a/nmea.c b/nmea.c index 7f1d9a2..b84b42e 100644 --- a/nmea.c +++ b/nmea.c @@ -155,6 +155,9 @@ static int nmea_scan_rmc(struct nmea_parser *np, struct nmea_rmc *result) if (cnt != 3) { return -1; } + /* Convert an inserted leap second to ambiguous 23:59:59 */ + if (tm.tm_sec == 60) + tm.tm_sec = 59; tm.tm_year += 100; tm.tm_mon--; tm.tm_isdst = 0; commit 6dcb8eda9fa7b2e3d486a3903c5c7b2568b30605 Author: Miroslav Lichvar Date: Tue Jun 11 16:17:38 2024 +0200 ts2phc: Fix timestamp conversion for leap seconds. The UTC timestamp parsed from the RMC message needs to be converted to TAI in order to calculate the PHC offset. This conversion was done after adjusting the timestamp for the measured delay between the reception of the message and the following pulse, which caused the offset measured by ts2phc to have a one-second error if the message expected during or after a leap second was missed. Apply the TAI-UTC offset to the timestamp parsed from the RMC message before any adjustments are made to avoid the error. Signed-off-by: Miroslav Lichvar Reviewed-by: Jacob Keller diff --git a/ts2phc_nmea_pps_source.c b/ts2phc_nmea_pps_source.c index 3385e39..e345969 100644 --- a/ts2phc_nmea_pps_source.c +++ b/ts2phc_nmea_pps_source.c @@ -187,11 +187,9 @@ static int ts2phc_nmea_pps_source_getppstime(struct ts2phc_pps_source *src, pr_err("nmea: rmc time stamp stale"); return -1; } - rmc = tmv_add(rmc, duration_since_rmc); - rmc = tmv_add(rmc, m->delay_correction); + utc_time = tmv_to_nanoseconds(rmc); utc_time /= (int64_t) 1000000000; - *ts = tmv_to_timespec(rmc); result = lstab_utc2tai(m->lstab, utc_time, &tai_offset); switch (result) { @@ -208,6 +206,10 @@ static int ts2phc_nmea_pps_source_getppstime(struct ts2phc_pps_source *src, pr_err("nmea: utc time stamp is ambiguous"); break; } + + rmc = tmv_add(rmc, duration_since_rmc); + rmc = tmv_add(rmc, m->delay_correction); + *ts = tmv_to_timespec(rmc); ts->tv_sec += tai_offset; return lstab_error;