summaryrefslogtreecommitdiff
path: root/ntpshm.c
diff options
context:
space:
mode:
authorGary E. Miller <gem@rellim.com>2013-10-28 23:26:00 -0700
committerGary E. Miller <gem@rellim.com>2013-10-28 23:26:00 -0700
commit57544427f539bb583b31834e065004354454a24e (patch)
tree2cf8eb6fff7b98e08f90bafbc050fc50b076290c /ntpshm.c
parente4a396cdd3a843314188ed22f73ffcb47fa8f207 (diff)
downloadgpsd-57544427f539bb583b31834e065004354454a24e.tar.gz
Make chrony_send() and ntpshm_pps() take the same arguments in the
same order.
Diffstat (limited to 'ntpshm.c')
-rw-r--r--ntpshm.c111
1 files changed, 53 insertions, 58 deletions
diff --git a/ntpshm.c b/ntpshm.c
index 75258f84..254d49fa 100644
--- a/ntpshm.c
+++ b/ntpshm.c
@@ -360,59 +360,26 @@ int ntpshm_put(struct gps_device_t *session, double fixtime, double fudge)
*
* good news is that kernel PPS gives us nSec resolution
* bad news is that ntpshm only has uSec resolution
+ *
+ * actual_tv is the actual time we think the PPS happened
+ * ts is the time we saw the pulse
*/
-static int ntpshm_pps(struct gps_device_t *session, struct timespec *ts)
+static int ntpshm_pps(struct gps_device_t *session, struct timeval *actual_tv,
+ struct timespec *ts, double edge_offset)
{
volatile struct shmTime *shmTime = NULL, *shmTimeP = NULL;
struct timeval tv;
- time_t seconds;
- /* FIX-ME, microseconds needs to be set for 5Hz PPS */
- int microseconds = 0;
int precision;
double offset;
- long l_offset;
if (0 > session->shmindex || 0 > session->shmTimeP ||
(shmTime = session->context->shmTime[session->shmindex]) == NULL ||
(shmTimeP = session->context->shmTime[session->shmTimeP]) == NULL)
return 0;
- /* PPS has no seconds attached to it.
- * check to see if we have a fresh timestamp from the
- * GPS serial input then use that */
-
- /* FIX-ME, does not handle 5Hz yet */
/* for now we use uSec, not nSec */
TSTOTV( &tv, ts );
-#ifdef S_SPLINT_S /* avoids an internal error in splint 3.1.1 */
- l_offset = 0;
-#else
- l_offset = tv.tv_sec - shmTime->receiveTimeStampSec;
-#endif
- /*@ -ignorequals @*/
- l_offset *= 1000000;
- l_offset += tv.tv_usec - shmTime->receiveTimeStampUSec;
- if (0 > l_offset || 1000000 < l_offset) {
- gpsd_report(session->context->debug, LOG_RAW,
- "PPS ntpshm_pps: no current GPS seconds: %ld\n",
- (long)l_offset);
- return -1;
- }
-
- /*
- * This innocuous-looking "+ 1" embodies a significant assumption:
- * that GPSes report time to the second over the serial stream *after*
- * emitting PPS for the top of second. Thus, when we see PPS our
- * available report is from the previous cycle and we must increment.
- */
- /*@+relaxtypes@*/
- seconds = shmTime->clockTimeStampSec + 1;
- offset = fabs((tv.tv_sec - seconds)
- + ((double)(tv.tv_usec - 0) / 1000000.0));
- /*@-relaxtypes@*/
-
-
/* we use the shmTime mode 1 protocol
*
* ntpd does this:
@@ -429,9 +396,9 @@ static int ntpshm_pps(struct gps_device_t *session, struct timespec *ts)
*/
shmTimeP->valid = 0;
shmTimeP->count++;
- shmTimeP->clockTimeStampSec = seconds;
- shmTimeP->clockTimeStampUSec = (int)microseconds;
- shmTimeP->receiveTimeStampSec = (time_t) tv.tv_sec;
+ shmTimeP->clockTimeStampSec = (time_t)actual_tv->tv_sec;
+ shmTimeP->clockTimeStampUSec = (int)actual_tv->tv_usec;
+ shmTimeP->receiveTimeStampSec = (time_t)tv.tv_sec;
shmTimeP->receiveTimeStampUSec = (int)tv.tv_usec;
shmTimeP->leap = session->context->leap_notify;
/* precision is a placebo, ntpd does not really use it
@@ -442,10 +409,13 @@ static int ntpshm_pps(struct gps_device_t *session, struct timespec *ts)
/* this is more an offset jitter/dispersion than precision,
* but still useful for debug */
+ offset = fabs((tv.tv_sec - actual_tv->tv_sec)
+ + ((double)(tv.tv_usec - actual_tv->tv_usec) / 1000000.0));
precision = offset != 0 ? (int)(ceil(log(offset) / M_LN2)) : -20;
gpsd_report(session->context->debug, LOG_RAW,
"PPS ntpshm_pps %lu.%03lu @ %lu.%09lu, preci %d\n",
- (unsigned long)seconds, (unsigned long)microseconds / 1000,
+ (unsigned long)actual_tv->tv_sec,
+ (unsigned long)actual_tv->tv_usec,
(unsigned long)ts->tv_sec, (unsigned long)ts->tv_nsec,
precision);
return 1;
@@ -499,8 +469,12 @@ static void chrony_init(struct gps_device_t *session)
}
+/* actual_tv is when we think the PPS pulse wass */
+/* ts is the local clocke time we saw the pulse */
+/* offset is actual_tv - tv */
static void chrony_send(struct gps_device_t *session,
- struct timeval *tv, double offset)
+ struct timeval *actual_tv,
+ struct timespec *ts, double offset)
{
struct sock_sample sample;
@@ -509,7 +483,7 @@ static void chrony_send(struct gps_device_t *session,
sample.pulse = 0;
sample.leap = session->context->leap_notify;
sample.magic = SOCK_MAGIC;
- sample.tv = *tv;
+ sample.tv = *actual_tv; /* structure copy */
sample.offset = offset;
send(session->chronyfd, &sample, sizeof (sample), 0);
@@ -706,7 +680,6 @@ volatile bool gpsd_ppsmonitor_stop = false;
/*@-mustfreefresh -type@ -unrecog*/
static /*@null@*/ void *gpsd_ppsmonitor(void *arg)
{
- unsigned long sec_pps;
struct gps_device_t *session = (struct gps_device_t *)arg;
struct timeval tv;
struct timespec ts;
@@ -1009,8 +982,11 @@ static /*@null@*/ void *gpsd_ppsmonitor(void *arg)
#endif /* TIOCMIWAIT */
if (ok) {
+ long l_offset;
char *log1 = NULL;
- struct timeval edge_tv;
+ /* actual_tv is the time we think the pulse represents */
+ struct timeval actual_tv;
+ /* edge_offset is the skew from expected to observed pulse time */
double edge_offset;
gpsd_report(session->context->debug, LOG_RAW,
"PPS edge accepted %.100s", log);
@@ -1023,38 +999,57 @@ static /*@null@*/ void *gpsd_ppsmonitor(void *arg)
} else {
ts = pi.clear_timestamp; /* structure copy */
}
- TSTOTV( &edge_tv, &ts);
} else
#endif
{
// use plain PPS
- edge_tv = tv; /* structure copy */
+ TVTOTS( &ts, &tv);
}
- /* FIXME!! this is wrong if signal is 5Hz or 10Hz instead of PPS */
- /* careful, Unix time to nSec is more precision than a double */
- /* FIXME, validate last_fixtime a bit better */
- edge_offset = 1 + session->last_fixtime - ts.tv_sec;
+
+ /* This innocuous-looking "+ 1" embodies a significant
+ * assumption: that GPSes report time to the second over the
+ * serial stream *after* * emitting PPS for the top of second.
+ * Thus, when we see PPS our available report is from the
+ * previous cycle and we must increment.
+ */
+
+ /*@+relaxtypes@*/
+ actual_tv.tv_sec = session->last_fixtime + 1;
+ actual_tv.tv_usec = 0; /* need to be fixed for 5Hz */
+ /*@-relaxtypes@*/
+
+ edge_offset = actual_tv.tv_sec - ts.tv_sec;
edge_offset -= ts.tv_nsec / 1e9;
+ /* check to see if we have a fresh timestamp from the
+ * GPS serial input then use that */
+ l_offset = (long)edge_offset;
+ if (0 > l_offset || 1000000 < l_offset) {
+ /* timestamp out of range */
+ gpsd_report(session->context->debug, LOG_RAW,
+ "PPS ntpshm_pps: no current GPS seconds: %ld\n",
+ (long)l_offset);
+ session->ship_to_ntpd = 0;
+ }
+
if (session->ship_to_ntpd) {
log1 = "accepted";
if ( 0 <= session->chronyfd ) {
log1 = "accepted chrony sock";
- chrony_send(session, &edge_tv, edge_offset);
+ chrony_send(session, &actual_tv, &ts, edge_offset);
}
- (void)ntpshm_pps(session, &ts);
+ (void)ntpshm_pps(session, &actual_tv, &ts, edge_offset);
} else {
log1 = "skipped ship_to_ntp=0";
}
gpsd_report(session->context->debug, LOG_RAW,
"PPS edge %.20s %lu.%06lu offset %.9f\n",
log1,
- (unsigned long)edge_tv.tv_sec,
- (unsigned long)edge_tv.tv_usec,
+ (unsigned long)ts.tv_sec,
+ (unsigned long)ts.tv_nsec,
edge_offset);
- sec_pps = 1 + session->last_fixtime;
if (session->context->pps_hook != NULL)
- session->context->pps_hook(session, sec_pps, &ts);
+ session->context->pps_hook(session, actual_tv.tv_sec, &ts);
} else {
gpsd_report(session->context->debug, LOG_RAW,
"PPS edge rejected %.100s", log);