commit f3c742e24a40cf75272ec39789a2cba35389230d Author: Miroslav Lichvar Date: Tue Jun 11 15:25:54 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 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 b396d361b0d290ce83395851860c2dcd074e0f3b Author: Miroslav Lichvar Date: Tue Jun 11 15:32:55 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 diff --git a/ts2phc_nmea_pps_source.c b/ts2phc_nmea_pps_source.c index 7a28433..bdfaf19 100644 --- a/ts2phc_nmea_pps_source.c +++ b/ts2phc_nmea_pps_source.c @@ -186,10 +186,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); + 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) { @@ -206,6 +205,9 @@ 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); + *ts = tmv_to_timespec(rmc); ts->tv_sec += tai_offset; return lstab_error;