Here's another patch that attempts to add leap second parsing to gpsd for
the thunderbolt. I used the 0X58 UTC_INFO packet and calculated a
the leap second adjustment from delta t LS and delta T LSF store in the
current almanac. Then use the presence of the leap second pending
alarm and the delta to send ntp a leap second warning.
Ignore the parity none stuff unless you own a thunderbolt.
The 0x58 trick will probably work with devices that use the 0x41 timing packet,
but I don't have a device to test that with. There are other ways to get
leap second information that may be more straight forward on these devices, but
not on the thunderbolt. You just get a leap second alarm and then have to
poll the UTC_INFO out of the almanac to get the leap second delta.
The 0x38 poll every 5 seconds is probably overkill, I was just
too impatient to wait to see if the receiver automatically sent a 0x58
packet after an almanac change. Probably, the 0x38 needs to run
exactly once at startup and then future 0x58 packets will be sent automatically
given the 0x8E-A5 mask, but it doesn't seem to hurt anything.
This was tested with ntp-4.2.4p4 refclock_shm (no changes needed to ntpd).
Scott
Chris Kuethe wrote:
On Sun, Aug 10, 2008 at 1:42 PM, Scott Mace <[EMAIL PROTECTED]> wrote:
ntpshm_put() needs to be called in the 0xab case as well for ntp to work.
done.
--- gpsd/trunk/tsip.c 2008-08-08 23:38:27.000000000 -0500
+++ ../gpsd/trunk/tsip.c 2008-08-09 04:14:09.000000000 -0500
@@ -65,7 +65,7 @@
/* XXX clever heuristic to decide if the parity change is required.
*/
session->driver.tsip.parity = session->gpsdata.parity;
session->driver.tsip.stopbits = session->gpsdata.stopbits;
- gpsd_set_speed(session, session->gpsdata.baudrate, 'O', 1);
+ gpsd_set_speed(session, session->gpsdata.baudrate, 'N', 1);
break;
case 1:
not committing this - i'd prefer a heuristic to autodetect the parity.
i'm open to suggestions on how to do that.
@@ -674,6 +674,10 @@
session->gpsdata.fix.time = session->gpsdata.sentence_time =
gpstime_to_unix((int)s1, f1) - (double)u1;
+#ifdef NTPSHM_ENABLE
+ if (session->context->enable_ntpshm)
+
(void)ntpshm_put(session,session->gpsdata.sentence_time+0.075);
+#endif
mask |= TIME_SET;
}
just committed this part...
diff -ru gpsd.orig/trunk/drivers.c gpsd/trunk/drivers.c
--- gpsd.orig/trunk/drivers.c 2008-08-08 23:38:27.000000000 -0500
+++ gpsd/trunk/drivers.c 2008-08-26 22:33:26.000000000 -0500
@@ -108,7 +108,7 @@
if (session->context->enable_ntpshm &&
(st & TIME_SET) != 0 &&
(session->gpsdata.fix.time!=session->last_fixtime)) {
- (void)ntpshm_put(session, session->gpsdata.fix.time);
+ (void)ntpshm_put(session, session->gpsdata.fix.time, LEAP_NOWARNING);
session->last_fixtime = session->gpsdata.fix.time;
}
#endif /* NTPSHM_ENABLE */
diff -ru gpsd.orig/trunk/garmin.c gpsd/trunk/garmin.c
--- gpsd.orig/trunk/garmin.c 2008-08-08 23:38:27.000000000 -0500
+++ gpsd/trunk/garmin.c 2008-08-26 22:33:00.000000000 -0500
@@ -403,7 +403,7 @@
}
#ifdef NTPSHM_ENABLE
if (session->context->enable_ntpshm && session->gpsdata.fix.mode > MODE_NO_FIX)
- (void) ntpshm_put(session, session->gpsdata.fix.time);
+ (void) ntpshm_put(session, session->gpsdata.fix.time, LEAP_NOWARNING);
#endif /* NTPSHM_ENABLE */
gpsd_report(LOG_PROG, "Appl, mode %d, status %d\n"
diff -ru gpsd.orig/trunk/gpsd.h gpsd/trunk/gpsd.h
--- gpsd.orig/trunk/gpsd.h 2008-08-26 22:39:01.000000000 -0500
+++ gpsd/trunk/gpsd.h 2008-08-26 23:01:06.000000000 -0500
@@ -173,6 +173,11 @@
#define NTPSHMSEGS 4 /* number of NTP SHM segments */
+#define LEAP_NOWARNING 0x0 /* normal, no leap second warning */
+#define LEAP_ADDSECOND 0x1 /* last minute of day has 61 seconds */
+#define LEAP_DELSECOND 0x2 /* last minute of day has 59 seconds */
+#define LEAP_NOTINSYNC 0x3 /* overload, clock is free running */
+
/* Some internal capabilities depend on which drivers we're compiling. */
#ifdef EARTHMATE_ENABLE
#define ZODIAC_ENABLE
@@ -199,6 +204,8 @@
double rtcmtime; /* timestamp of last RTCM104 report */
/* timekeeping */
int leap_seconds; /* Unix seconds to UTC */
+ u_char leap_warn; /* Leap Second Warning for NTP */
+ int leap_delta; /* Leap Second Delta */
int century; /* for NMEA-only devices without ZDA */
#ifdef NTPSHM_ENABLE
bool enable_ntpshm;
@@ -324,6 +331,7 @@
time_t last_5c;
time_t last_6d;
time_t last_46;
+ time_t last_58;
unsigned int parity, stopbits; /* saved RS232 link parameters */
} tsip;
#endif /* TSIP_ENABLE */
@@ -446,7 +454,7 @@
extern void ntpshm_init(struct gps_context_t *, bool);
extern int ntpshm_alloc(struct gps_context_t *);
extern bool ntpshm_free(struct gps_context_t *, int);
-extern int ntpshm_put(struct gps_device_t *, double);
+extern int ntpshm_put(struct gps_device_t *, double, u_char);
extern int ntpshm_pps(struct gps_device_t *,struct timeval *);
extern void ecef_to_wgs84fix(struct gps_data_t *,
diff -ru gpsd.orig/trunk/ntpshm.c gpsd/trunk/ntpshm.c
--- gpsd.orig/trunk/ntpshm.c 2008-08-08 23:38:27.000000000 -0500
+++ gpsd/trunk/ntpshm.c 2008-08-26 21:55:49.000000000 -0500
@@ -114,7 +114,7 @@
}
-int ntpshm_put(struct gps_device_t *session, double fixtime)
+int ntpshm_put(struct gps_device_t *session, double fixtime, u_char leap_warn)
/* put a received fix time into shared memory for NTP */
{
struct shmTime *shmTime = NULL;
@@ -140,10 +140,11 @@
*/
shmTime->count++;
shmTime->valid = 1;
+ shmTime->leap = leap_warn;
- gpsd_report(LOG_RAW, "ntpshm_put: Clock: %lu @ %lu.%06lu\n"
+ gpsd_report(LOG_RAW, "ntpshm_put: Clock: %lu @ %lu.%06lu %u\n"
, (unsigned long)seconds, (unsigned long)tv.tv_sec
- , (unsigned long)tv.tv_usec);
+ , (unsigned long)tv.tv_usec, leap_warn);
return 1;
}
diff -ru gpsd.orig/trunk/packet.c gpsd/trunk/packet.c
--- gpsd.orig/trunk/packet.c 2008-08-08 23:38:27.000000000 -0500
+++ gpsd/trunk/packet.c 2008-08-26 17:05:20.000000000 -0500
@@ -1055,6 +1055,8 @@
/* pass */;
else if ((0x8f == pkt_id))
/* pass */;
+ else if ((0x58 == pkt_id))
+ /* pass */;
else if ((0xbb == pkt_id) && (0x2c == packetlen))
/* pass */;
else {
diff -ru gpsd.orig/trunk/sirf.c gpsd/trunk/sirf.c
--- gpsd.orig/trunk/sirf.c 2008-08-08 23:38:27.000000000 -0500
+++ gpsd/trunk/sirf.c 2008-08-26 21:57:01.000000000 -0500
@@ -339,7 +339,7 @@
session->driver.sirf.time_seen);
session->driver.sirf.time_seen |= TIME_SEEN_GPS_1;
if (session->context->enable_ntpshm && IS_HIGHEST_BIT(session->driver.sirf.time_seen,TIME_SEEN_GPS_1))
- (void)ntpshm_put(session,session->gpsdata.sentence_time+0.8);
+ (void)ntpshm_put(session,session->gpsdata.sentence_time+0.8,LEAP_NOWARNING);
}
#endif /* NTPSHM_ENABLE */
/*
@@ -400,7 +400,7 @@
session->driver.sirf.time_seen);
session->driver.sirf.time_seen |= TIME_SEEN_GPS_2;
if (session->context->enable_ntpshm && IS_HIGHEST_BIT(session->driver.sirf.time_seen,TIME_SEEN_GPS_2))
- (void)ntpshm_put(session, session->gpsdata.fix.time + 0.8);
+ (void)ntpshm_put(session, session->gpsdata.fix.time + 0.8,LEAP_NOWARNING);
}
#endif /* NTPSHM_ENABLE */
/* fix quality data */
@@ -484,7 +484,7 @@
session->driver.sirf.time_seen);
session->driver.sirf.time_seen |= TIME_SEEN_UTC_1;
if (session->context->enable_ntpshm && IS_HIGHEST_BIT(session->driver.sirf.time_seen,TIME_SEEN_UTC_1))
- (void)ntpshm_put(session, session->gpsdata.fix.time + 0.8);
+ (void)ntpshm_put(session, session->gpsdata.fix.time + 0.8,LEAP_NOWARNING);
}
#endif /* NTPSHM_ENABLE */
/* skip 4 bytes of satellite map */
@@ -582,7 +582,7 @@
session->driver.sirf.time_seen);
session->driver.sirf.time_seen |= TIME_SEEN_UTC_2;
if (session->context->enable_ntpshm && IS_HIGHEST_BIT(session->driver.sirf.time_seen,TIME_SEEN_UTC_2))
- (void)ntpshm_put(session, session->gpsdata.fix.time + 0.8);
+ (void)ntpshm_put(session, session->gpsdata.fix.time + 0.8,LEAP_NOWARNING);
#endif /* NTPSHM_ENABLE */
session->context->valid |= LEAP_SECOND_VALID;
}
@@ -624,7 +624,7 @@
session->driver.sirf.time_seen);
session->driver.sirf.time_seen |= TIME_SEEN_UTC_2;
if (session->context->enable_ntpshm && IS_HIGHEST_BIT(session->driver.sirf.time_seen,TIME_SEEN_UTC_2))
- (void)ntpshm_put(session, session->gpsdata.fix.time + 0.3);
+ (void)ntpshm_put(session, session->gpsdata.fix.time + 0.3,LEAP_NOWARNING);
#endif /* NTPSHM_ENABLE */
mask |= TIME_SET;
}
diff -ru gpsd.orig/trunk/tsip.c gpsd/trunk/tsip.c
--- gpsd.orig/trunk/tsip.c 2008-08-08 23:38:27.000000000 -0500
+++ gpsd/trunk/tsip.c 2008-08-26 23:02:05.000000000 -0500
@@ -65,7 +65,7 @@
/* XXX clever heuristic to decide if the parity change is required. */
session->driver.tsip.parity = session->gpsdata.parity;
session->driver.tsip.stopbits = session->gpsdata.stopbits;
- gpsd_set_speed(session, session->gpsdata.baudrate, 'O', 1);
+ gpsd_set_speed(session, session->gpsdata.baudrate, 'N', 1);
break;
case 1:
@@ -81,6 +81,15 @@
/* Request Navigation Configuration */
putbyte(buf,0,0x03);
(void)tsip_write(session->gpsdata.gps_fd, 0xbb, buf, 1);
+
+
+ /* Make sure the Device is in 8f-a5 mode */
+ putbyte(buf,0,0xa5);
+ putbyte(buf,1,0x00);
+ putbyte(buf,2,0x45);
+ putbyte(buf,3,0x00);
+ putbyte(buf,4,0x00);
+ (void)tsip_write(session->gpsdata.gps_fd, 0x8e, buf, 5);
break;
}
}
@@ -208,7 +217,7 @@
#ifdef NTPSHM_ENABLE
if (session->context->enable_ntpshm)
- (void)ntpshm_put(session,session->gpsdata.sentence_time+0.075);
+ (void)ntpshm_put(session,session->gpsdata.sentence_time+0.075,LEAP_NOWARNING);
#endif
mask |= TIME_SET;
}
@@ -381,6 +390,13 @@
gpsd_report(LOG_INF, "Fix info %02x %02x %d %f\n",u1,u2,s1,f1);
break;
case 0x58: /* Satellite System Data/Acknowledge from Receiver */
+ session->driver.tsip.last_58 = now; /* keep timestamp for request */
+ if (getub(buf,1) == 0x05) {
+ s1 = getbesw(buf,29);
+ s2 = getbesw(buf,41);
+ gpsd_report(4, "UTC info %d %d\n",s1,s2);
+ session->context->leap_delta = s2 - s1;
+ }
break;
case 0x59: /* Status of Satellite Disable or Ignore Health */
break;
@@ -666,6 +682,8 @@
f1 = getbeul(buf,1); /* gpstime */
s1 = getbeuw(buf,5); /* week */
u1 = getbesw(buf,7); /* leap seconds */
+ u2 = getub(buf,13); /* day on month */
+ u3 = getub(buf,14); /* month of year */
session->driver.tsip.gps_week = s1;
if ((int)u1 > 10) {
@@ -674,6 +692,17 @@
session->gpsdata.fix.time = session->gpsdata.sentence_time =
gpstime_to_unix((int)s1, f1) - (double)u1;
+
+ if (u3 != 6 || u3 != 12) {
+ session->context->leap_warn = LEAP_NOWARNING;
+ gpsd_report(4, "LEAP_WARN canceled month=%d\n",u3);
+ }
+
+
+#ifdef NTPSHM_ENABLE
+ if (session->context->enable_ntpshm)
+ (void)ntpshm_put(session,session->gpsdata.sentence_time+0.075,session->context->leap_warn);
+#endif
mask |= TIME_SET;
}
@@ -692,6 +721,16 @@
session->gpsdata.fix.altitude = getbed(buf,52);
f1 = getbef(buf,16); /* clock bias */
+ if ((getbeuw(buf,10) & 0x80) && session->context->leap_delta != 0) {
+ session->context->leap_warn = (session->context->leap_delta > 0 ? LEAP_ADDSECOND : LEAP_DELSECOND);
+ gpsd_report(4, "LEAP_WARN %d\n",session->context->leap_delta);
+ }
+ else {
+ session->context->leap_delta = LEAP_NOWARNING;
+ gpsd_report(4, "LEAP_NOWARN\n");
+ }
+
+
u1 = getub(buf, 12); /* GPS Decoding Status */
u2 = getub(buf, 1); /* Reciever Mode */
if (u1 != (u_int8_t)0) {
@@ -783,6 +822,15 @@
session->driver.tsip.last_46 = now;
}
+ if ((now - session->driver.tsip.last_58) > 5) {
+ /* Request UTC INFO Almanac Data From Receiver */
+ putbyte(buf,0,0x01);
+ putbyte(buf,1,0x05);
+ putbyte(buf,2,0x00);
+ (void)tsip_write(session->gpsdata.gps_fd, 0x38, buf, 3);
+ session->driver.tsip.last_58 = now;
+ }
+
return mask;
}
diff -ru gpsd.orig/trunk/ubx.c gpsd/trunk/ubx.c
--- gpsd.orig/trunk/ubx.c 2008-08-08 23:38:27.000000000 -0500
+++ gpsd/trunk/ubx.c 2008-08-26 22:02:12.000000000 -0500
@@ -69,7 +69,7 @@
#ifdef NTPSHM_ENABLE
/* TODO overhead */
if (session->context->enable_ntpshm)
- (void)ntpshm_put(session, session->gpsdata.sentence_time);
+ (void)ntpshm_put(session, session->gpsdata.sentence_time,LEAP_NOWARNING);
#endif
}
diff -ru gpsd.orig/trunk/zodiac.c gpsd/trunk/zodiac.c
--- gpsd.orig/trunk/zodiac.c 2008-08-08 23:38:27.000000000 -0500
+++ gpsd/trunk/zodiac.c 2008-08-26 22:02:39.000000000 -0500
@@ -182,7 +182,7 @@
* tests and simple gps applications do not detect this. A live test
* with the 1pps signal active is required. */
if (session->context->enable_ntpshm && session->gpsdata.fix.mode > MODE_NO_FIX)
- (void)ntpshm_put(session, session->gpsdata.fix.time + 1.1);
+ (void)ntpshm_put(session, session->gpsdata.fix.time + 1.1,LEAP_NOWARNING);
#endif
/*@ -type @*/
session->gpsdata.fix.latitude = ((long)getzlong(27)) * RAD_2_DEG * 1e-8;
_______________________________________________
time-nuts mailing list -- [email protected]
To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts
and follow the instructions there.