From: Juergen Perlinger Date: Mon, 13 May 2019 05:44:52 +0000 (+0200) Subject: [Bug 3590] Update refclock_oncore.c to the new GPS date API X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=87ed274b6e7b1dfd2673617cc6778913024ee01f;p=thirdparty%2Fntp.git [Bug 3590] Update refclock_oncore.c to the new GPS date API bk: 5cd90454wWo2XaX9L6hjBeqtbkILKg --- diff --git a/ChangeLog b/ChangeLog index 434054efe..fe0899336 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,5 @@ --- +* [Bug 3590] Update refclock_oncore.c to the new GPS date API * [Bug 3577] Update refclock_zyfer.c to the new GPS date API - also updates for refclock_nmea.c and refclock_jupiter.c * [Bug 3576] New GPS date function API diff --git a/libntp/ntp_calgps.c b/libntp/ntp_calgps.c index 20e1f103a..773cfe909 100644 --- a/libntp/ntp_calgps.c +++ b/libntp/ntp_calgps.c @@ -164,7 +164,7 @@ _gpsntp_fix_gps_era( - GPSNTP_DSHIFT; days = out.days; - sign = (uint32_t) -(days < base); + sign = (uint32_t)-(days < base); days = sign ^ (days - base); days %= clen; days = base + (sign & clen) + (sign ^ days); @@ -282,6 +282,7 @@ gpsntp_to_calendar( TcNtpDatum * nd ) { + memset(cd, 0, sizeof(*cd)); ntpcal_rd_to_date( cd, nd->days + DAY_NTP_STARTS + ntpcal_daysec_to_date( @@ -407,13 +408,33 @@ again: if (cal.month && cal.monthday) { /* use y/m/d civil date */ + (int32_t)cal.yearday - 1; /* both RDN and yearday start with '1'. */ } - if (days < DAY_GPS_STARTS) { + + /* Rebase to days after the GPS epoch. 'days' is positive here, + * but it might be less than the GPS epoch start. Depending on + * the input, we have to do different things to get the desired + * result. (Since we want to remap the era anyway, we only have + * to retain congruential identities....) + */ + + if (days >= DAY_GPS_STARTS) { + /* simply shift to days since GPS epoch */ + days -= DAY_GPS_STARTS; + } else if (jd->year < 100) { + /* Two-digit year on input: add another century and + * retry. This can happen only if the century expansion + * yielded a date between 1980-01-01 and 1980-01-05, + * both inclusive. We have at most one retry here. + */ cal.year += 100; goto again; + } else { + /* add the complement of DAY_GPS_STARTS (this is, use a + * congruential identity here) + */ + days += (7 * 1024) - DAY_GPS_STARTS % (7 * 1024); } - /* get GPS time since start of GPS */ - days -= DAY_GPS_STARTS; + /* Splitting to weeks is simple now: */ week = days / 7; days -= week * 7; @@ -436,7 +457,10 @@ gpscal_to_calendar( TcGpsDatum * wd ) { - TNtpDatum nd = gpsntp_from_gpscal(wd); + TNtpDatum nd; + + memset(cd, 0, sizeof(*cd)); + nd = gpsntp_from_gpscal(wd); gpsntp_to_calendar(cd, &nd); } diff --git a/ntpd/refclock_oncore.c b/ntpd/refclock_oncore.c index 2c82caeb6..17c8cbf29 100644 --- a/ntpd/refclock_oncore.c +++ b/ntpd/refclock_oncore.c @@ -162,6 +162,7 @@ #include "ntp_unixtime.h" #include "ntp_refclock.h" #include "ntp_calendar.h" +#include "ntp_calgps.h" #include "ntp_stdlib.h" #include @@ -388,6 +389,7 @@ static void oncore_set_traim (struct instance *); static void oncore_shmem_get_3D (struct instance *); static void oncore_ss (struct instance *); static int oncore_wait_almanac (struct instance *); +static void oncore_feed_clockproc (struct instance *); static void oncore_msg_any (struct instance *, u_char *, size_t, int); static void oncore_msg_Adef (struct instance *, u_char *, size_t); @@ -1872,12 +1874,16 @@ oncore_get_timestamp( /* and some things I dont understand (magic ntp things) */ +#if 1 + oncore_feed_clockproc(instance); +#else if (!refclock_process(instance->pp)) { - refclock_report(instance->peer, CEVNT_BADTIME); + refclock_report(peer, CEVNT_BADTIME); peer->flags &= ~FLAG_PPS; /* problem - clear PPS FLAG */ return; } - +#endif + oncore_log(instance, LOG_INFO, Msg); /* this is long message above */ instance->pollcnt = 2; @@ -4036,6 +4042,52 @@ oncore_wait_almanac( } +static void +oncore_feed_clockproc( + struct instance * instance + ) +{ + struct peer * const peer = instance->peer; + struct refclockproc * const pp = instance->pp; + + TCivilDate cd; /* calendar date + time */ + TGpsDatum gd; /* GPS datum, remapped into NTP epoch */ + l_fp fp; /* the reference time in NTP format */ + + if (pp->year >= 1980) { + /* There are oncore receivers that run in a fixed + * (possibly shifted) GPS era and fold back into that + * era on every GPS week rollover. + * + * We do not trust the date we get and remap to a GPS + * era defined by the GPS base date (derived from the + * build time stamp or a 'tos basedate' config option. + */ + ZERO(fp); /* has a zero to begin with */ + ZERO(cd); /* month == monthday == 0 -> use year+yearday */ + cd.year = pp->year; + cd.yearday = pp->day; + cd.hour = pp->hour; + cd.minute = pp->minute; + cd.second = pp->second; + + /* the magic happens in the next line: */ + gd = gpscal_from_calendar(&cd, fp); /* fp should be zero here */ + + /* To avoid the trouble the day-of-year calculations in + * 'refclock_process()' can cause we feed the time + * stamps we have now directly. This also saves us two + * full calendar calendar conversion cycles. + */ + fp = ntpfp_from_gpsdatum(&gd); + refclock_process_offset(pp, fp, pp->lastrec, pp->fudgetime1); + } else { + /* This is obviously a bad date/time... */ + refclock_report(peer, CEVNT_BADDATE); + peer->flags &= ~FLAG_PPS; /* problem - clear PPS FLAG */ + return; + } +} static void oncore_log ( diff --git a/tests/libntp/calendar.c b/tests/libntp/calendar.c index 5953b62c5..97778959f 100644 --- a/tests/libntp/calendar.c +++ b/tests/libntp/calendar.c @@ -43,6 +43,7 @@ void test_IsoCalWeeksToYearStart(void); void test_IsoCalWeeksToYearEnd(void); void test_DaySecToDate(void); void test_GpsRollOver(void); +void test_GpsRemapFunny(void); void test_GpsNtpFixpoints(void); void test_NtpToNtp(void); @@ -215,6 +216,28 @@ IsEqualDateIso( } } +static int/*BOOL*/ +strToCal( + struct calendar * jd, + const char * str + ) +{ + unsigned short y,m,d, H,M,S; + + if (6 == sscanf(str, "%hu-%2hu-%2huT%2hu:%2hu:%2hu", + &y, &m, &d, &H, &M, &S)) { + memset(jd, 0, sizeof(*jd)); + jd->year = y; + jd->month = (uint8_t)m; + jd->monthday = (uint8_t)d; + jd->hour = (uint8_t)H; + jd->minute = (uint8_t)M; + jd->second = (uint8_t)S; + + return TRUE; + } + return FALSE; +} /* * --------------------------------------------------------------------- @@ -821,51 +844,67 @@ test_GpsRollOver(void) */ basedate_set_day(2047 * 7 + NTP_TO_GPS_DAYS); - jd.year = 19; - jd.month = 4; - jd.monthday = 3; - jd.hour = 12; - jd.minute = 0; - jd.second = 0; - + strToCal(&jd, "19-04-03T12:00:00"); gps = gpscal_from_calendar(&jd, fpz); TEST_ASSERT_EQUAL_MESSAGE(week0, gps.weeks, "(week test 1))"); TEST_ASSERT_EQUAL_MESSAGE(wsec1, gps.wsecs, "(secs test 1)"); - jd.year = 19; - jd.month = 4; - jd.monthday = 6; - jd.hour = 23; - jd.minute = 59; - jd.second = 59; - + strToCal(&jd, "19-04-06T23:59:59"); gps = gpscal_from_calendar(&jd, fpz); TEST_ASSERT_EQUAL_MESSAGE(week0, gps.weeks, "(week test 2)"); TEST_ASSERT_EQUAL_MESSAGE(wsec2, gps.wsecs, "(secs test 2)"); - jd.year = 19; - jd.month = 4; - jd.monthday = 7; - jd.hour = 0; - jd.minute = 0; - jd.second = 0; - + strToCal(&jd, "19-04-07T00:00:00"); gps = gpscal_from_calendar(&jd, fpz); TEST_ASSERT_EQUAL_MESSAGE(week1, gps.weeks, "(week test 3)"); TEST_ASSERT_EQUAL_MESSAGE( 0 , gps.wsecs, "(secs test 3)"); - jd.year = 19; - jd.month = 4; - jd.monthday = 10; - jd.hour = 12; - jd.minute = 0; - jd.second = 0; - + strToCal(&jd, "19-04-10T12:00:00"); gps = gpscal_from_calendar(&jd, fpz); TEST_ASSERT_EQUAL_MESSAGE(week1, gps.weeks, "(week test 4)"); TEST_ASSERT_EQUAL_MESSAGE(wsec1, gps.wsecs, "(secs test 4)"); } +void +test_GpsRemapFunny(void) +{ + TCivilDate di, dc, de; + TGpsDatum gd; + + l_fp fpz; + + ZERO(fpz); + basedate_set_day(2048 * 7 + NTP_TO_GPS_DAYS); + + /* expand 2digit year to 2080, then fold back into 3rd GPS era: */ + strToCal(&di, "80-01-01T00:00:00"); + strToCal(&de, "2021-02-15T00:00:00"); + gd = gpscal_from_calendar(&di, fpz); + gpscal_to_calendar(&dc, &gd); + TEST_ASSERT_TRUE(IsEqualCal(&de, &dc)); + + /* expand 2digit year to 2080, then fold back into 3rd GPS era: */ + strToCal(&di, "80-01-05T00:00:00"); + strToCal(&de, "2021-02-19T00:00:00"); + gd = gpscal_from_calendar(&di, fpz); + gpscal_to_calendar(&dc, &gd); + TEST_ASSERT_TRUE(IsEqualCal(&de, &dc)); + + /* remap days before epoch into 3rd era: */ + strToCal(&di, "1980-01-05T00:00:00"); + strToCal(&de, "2038-11-20T00:00:00"); + gd = gpscal_from_calendar(&di, fpz); + gpscal_to_calendar(&dc, &gd); + TEST_ASSERT_TRUE(IsEqualCal(&de, &dc)); + + /* remap GPS epoch: */ + strToCal(&di, "1980-01-06T00:00:00"); + strToCal(&de, "2019-04-07T00:00:00"); + gd = gpscal_from_calendar(&di, fpz); + gpscal_to_calendar(&dc, &gd); + TEST_ASSERT_TRUE(IsEqualCal(&de, &dc)); +} + void test_GpsNtpFixpoints(void) { diff --git a/tests/libntp/run-calendar.c b/tests/libntp/run-calendar.c index 6988d1c0d..26089200e 100644 --- a/tests/libntp/run-calendar.c +++ b/tests/libntp/run-calendar.c @@ -51,6 +51,7 @@ extern void test_IsoCalWeeksToYearStart(void); extern void test_IsoCalWeeksToYearEnd(void); extern void test_DaySecToDate(void); extern void test_GpsRollOver(void); +extern void test_GpsRemapFunny(void); extern void test_GpsNtpFixpoints(void); extern void test_NtpToNtp(void); extern void test_NtpToTime(void); @@ -98,9 +99,10 @@ int main(int argc, char *argv[]) RUN_TEST(test_IsoCalWeeksToYearEnd, 43); RUN_TEST(test_DaySecToDate, 44); RUN_TEST(test_GpsRollOver, 45); - RUN_TEST(test_GpsNtpFixpoints, 47); - RUN_TEST(test_NtpToNtp, 48); - RUN_TEST(test_NtpToTime, 49); + RUN_TEST(test_GpsRemapFunny, 46); + RUN_TEST(test_GpsNtpFixpoints, 48); + RUN_TEST(test_NtpToNtp, 49); + RUN_TEST(test_NtpToTime, 50); return (UnityEnd()); }