]> git.ipfire.org Git - thirdparty/ntp.git/commitdiff
[Bug 610] NMEA support for using PPSAPI on a different device.
authorDave Hart <hart@ntp.org>
Sat, 24 Oct 2009 05:55:49 +0000 (05:55 +0000)
committerDave Hart <hart@ntp.org>
Sat, 24 Oct 2009 05:55:49 +0000 (05:55 +0000)
[Bug 1238] use only fudge time2 to offset NMEA serial timestamp.

bk: 4ae296e51E9BP3gbTOlzvXQ8VTvvNA

ChangeLog
include/ntp_refclock.h
ntpd/ntp_refclock.c
ntpd/refclock_nmea.c

index 11d623c2ea0d358970c7b88a41765ca3dcb76010..301621304f9ce2f3685904ff8fe9a400c75eee26 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,5 @@
+* [Bug 610] NMEA support for using PPSAPI on a different device.
+* [Bug 1238] use only fudge time2 to offset NMEA serial timestamp.
 (4.2.5p236-RC) 2009/10/22 Released by Harlan Stenn <stenn@ntp.org>
 * Cleanup from Dave Mills.
 * [Bug 1343] ntpd/ntp_io.c close_fd() does not compile on Solaris 7.
index d98eb841c5a472029ec85a678b6857a1650849df..7c89af9966a0af8191fa8f4f9aee5c1ed1697c9d 100644 (file)
@@ -130,7 +130,7 @@ struct refclockio {
                                of refclock input data */
        caddr_t srcclock;       /* pointer to clock structure */
        int     datalen;        /* lenth of data */
-       SOCKET  fd;             /* file descriptor */
+       int     fd;             /* file descriptor */
        u_long  recvcount;      /* count of receive completions */
 };
 
@@ -264,6 +264,7 @@ extern      void    refclock_timer  (struct peer *);
 extern void    refclock_transmit (struct peer *);
 extern int     refclock_ioctl  (int, u_int);
 extern         int     refclock_process (struct refclockproc *);
+extern         int     refclock_process_f (struct refclockproc *, double);
 extern         void    refclock_process_offset (struct refclockproc *, l_fp, l_fp, double);
 extern void    refclock_report (struct peer *, int);
 extern int     refclock_gtlin  (struct recvbuf *, char *, int, l_fp *);
index 00fc68c533b5d4290d48e3592b3659c666df5dfa..f6eca8d4ea85453a4ef6021a78872a90e8bae2ee 100644 (file)
@@ -415,6 +415,7 @@ refclock_process_offset(
 
 /*
  * refclock_process - process a sample from the clock
+ * refclock_process_f - refclock_process with other than time1 fudge
  *
  * This routine converts the timecode in the form days, hours, minutes,
  * seconds and milliseconds/microseconds to internal timestamp format,
@@ -429,8 +430,9 @@ refclock_process_offset(
  * zero and the fraction for pp->lastrec is set to the PPS offset.
  */
 int
-refclock_process(
-       struct refclockproc *pp         /* refclock structure pointer */
+refclock_process_f(
+       struct refclockproc *pp,        /* refclock structure pointer */
+       double fudge
        )
 {
        l_fp offset, ltemp;
@@ -450,12 +452,20 @@ refclock_process(
        offset.l_uf = 0;
        DTOLFP(pp->nsec / 1e9, &ltemp);
        L_ADD(&offset, &ltemp);
-       refclock_process_offset(pp, offset, pp->lastrec,
-           pp->fudgetime1);
+       refclock_process_offset(pp, offset, pp->lastrec, fudge);
        return (1);
 }
 
 
+int
+refclock_process(
+       struct refclockproc *pp         /* refclock structure pointer */
+)
+{
+       return refclock_process_f(pp, pp->fudgetime1);
+}
+
+
 /*
  * refclock_sample - process a pile of samples from the clock
  *
@@ -1301,7 +1311,7 @@ refclock_pps(
        /*
         * Convert to signed fraction offset and stuff in median filter.
         */
-       pp->lastrec.l_ui = ap->ts.tv_sec + JAN_1970;
+       pp->lastrec.l_ui = (u_int32)ap->ts.tv_sec + JAN_1970;
        dtemp = ap->ts.tv_nsec / 1e9;
        pp->lastrec.l_uf = (u_int32)(dtemp * FRAC);
        if (dtemp > .5)
index e9645942f9342ea3158f3e0278b46f4812f25b0f..30e14261b9b8798423bfc63928c8d7136d5b8b18 100644 (file)
@@ -21,6 +21,7 @@
 
 #if defined(REFCLOCK) && defined(CLOCK_NMEA)
 
+#include <sys/stat.h>
 #include <stdio.h>
 #include <ctype.h>
 
@@ -89,7 +90,8 @@ extern int async_write(int, const void *, unsigned int);
 /*
  * Definitions
  */
-#define DEVICE    "/dev/gps%d" /* name of radio device */
+#define        DEVICE          "/dev/gps%d"    /* GPS serial device */
+#define        PPSDEV          "/dev/gpspps%d" /* PPSAPI device override */
 #define        SPEED232        B4800   /* uart speed (4800 bps) */
 #define        PRECISION       (-9)    /* precision assumed (about 2 ms) */
 #define        PPS_PRECISION   (-20)   /* precision assumed (about 1 us) */
@@ -97,6 +99,17 @@ extern int async_write(int, const void *, unsigned int);
 #define        DESCRIPTION     "NMEA GPS Clock" /* who we are */
 #define NANOSECOND     1000000000 /* one second (ns) */
 #define RANGEGATE      500000  /* range gate (ns) */
+#ifndef O_NOCTTY
+#define M_NOCTTY       0
+#else
+#define M_NOCTTY       O_NOCTTY
+#endif
+#ifndef O_NONBLOCK
+#define M_NONBLOCK     0
+#else
+#define M_NONBLOCK     O_NONBLOCK
+#endif
+#define PPSOPENMODE    (O_RDWR | M_NOCTTY | M_NONBLOCK)
 
 /*
  * Unit control structure
@@ -106,6 +119,7 @@ struct nmeaunit {
        struct refclock_atom atom; /* PPSAPI structure */
        int     ppsapi_tried;   /* attempt PPSAPI once */
        int     ppsapi_lit;     /* time_pps_create() worked */
+       int     ppsapi_fd;      /* fd used with PPSAPI */
        int     tcount;         /* timecode sample counter */
        int     pcount;         /* PPS sample counter */
 #endif /* HAVE_PPSAPI */
@@ -166,7 +180,7 @@ nmea_start(
        /*
         * Open serial port. Use CLK line discipline, if available.
         */
-       (void)sprintf(device, DEVICE, unit);
+       snprintf(device, sizeof(device), DEVICE, unit);
        
        /*
         * Opening the serial port with appropriate baudrate
@@ -266,10 +280,6 @@ nmea_start(
         * Allocate and initialize unit structure
         */
        up = emalloc(sizeof(*up));
-       if (NULL == up) {
-               close(fd);
-               return (0);
-       }
        memset(up, 0, sizeof(*up));
        pp = peer->procptr;
        pp->io.clock_recv = nmea_receive;
@@ -288,7 +298,7 @@ nmea_start(
         */
        peer->precision = PRECISION;
        pp->clockdesc = DESCRIPTION;
-       memcpy((char *)&pp->refid, REFID, 4);
+       memcpy(&pp->refid, REFID, 4);
 
        gps_send(fd,"$PMOTG,RMC,0000*1D\r\n", peer);
 
@@ -312,6 +322,13 @@ nmea_shutdown(
 
        pp = peer->procptr;
        up = (struct nmeaunit *)pp->unitptr;
+#ifdef HAVE_PPSAPI
+       if (up->ppsapi_lit) {
+               time_pps_destroy(up->atom.handle);
+               if (up->ppsapi_fd != pp->io.fd)
+                       close(up->ppsapi_fd);
+       }
+#endif
        io_closeclock(&pp->io);
        free(up);
 }
@@ -328,10 +345,11 @@ nmea_control(
        struct peer *peer
        )
 {
+       char device[32];
        register struct nmeaunit *up;
        struct refclockproc *pp;
+       int pps_fd;
        
-       UNUSED_ARG(unit);
        UNUSED_ARG(in_st);
        UNUSED_ARG(out_st);
 
@@ -347,8 +365,11 @@ nmea_control(
                peer->flags &= ~FLAG_PPS;
                peer->precision = PRECISION;
                time_pps_destroy(up->atom.handle);
+               if (up->ppsapi_fd != pp->io.fd)
+                       close(up->ppsapi_fd);
                up->atom.handle = 0;
                up->ppsapi_lit = 0;
+               up->ppsapi_fd = -1;
                return;
        }
 
@@ -358,8 +379,22 @@ nmea_control(
         * Light up the PPSAPI interface.
         */
        up->ppsapi_tried = 1;
-       if (refclock_ppsapi(pp->io.fd, &up->atom)) {
+
+       /*
+        * if /dev/gpspps$UNIT can be opened that will be used for
+        * PPSAPI.  Otherwise, the GPS serial device /dev/gps$UNIT
+        * already opened is used for PPSAPI as well.
+        */
+       snprintf(device, sizeof(device), PPSDEV, unit);
+
+       pps_fd = open(device, PPSOPENMODE, S_IRUSR | S_IWUSR);
+
+       if (-1 == pps_fd)
+               pps_fd = pp->io.fd;
+       
+       if (refclock_ppsapi(pps_fd, &up->atom)) {
                up->ppsapi_lit = 1;
+               up->ppsapi_fd = pps_fd;
                return;
        }
 
@@ -414,7 +449,6 @@ nmea_receive(
        char *cp, *dp, *msg;
        int cmdtype;
        int cmdtypezdg = 0;
-       l_fp lfp_fudgetime2;
        /* Use these variables to hold data until we decide its worth keeping */
        char    rd_lastcode[BMAX];
        l_fp    rd_timestamp;
@@ -524,8 +558,6 @@ nmea_receive(
        memcpy(pp->a_lastcode, rd_lastcode, pp->lencode + 1);
        cp = pp->a_lastcode;
 
-       DTOLFP(pp->fudgetime2, &lfp_fudgetime2);
-       L_ADD(&rd_timestamp, &lfp_fudgetime2);
        up->tstamp = rd_timestamp;
        pp->lastrec = up->tstamp;
 
@@ -798,7 +830,7 @@ nmea_receive(
        if (peer->flags & FLAG_PPS)
                return;
 #endif /* HAVE_PPSAPI */
-       if (!refclock_process(pp))
+       if (!refclock_process_f(pp, pp->fudgetime2))
                refclock_report(peer, CEVNT_BADTIME);
 }