From: Dave Hart Date: Sat, 24 Oct 2009 05:55:49 +0000 (+0000) Subject: [Bug 610] NMEA support for using PPSAPI on a different device. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8e207d712bcf23088a8faead132285fec7cc34ce;p=thirdparty%2Fntp.git [Bug 610] NMEA support for using PPSAPI on a different device. [Bug 1238] use only fudge time2 to offset NMEA serial timestamp. bk: 4ae296e51E9BP3gbTOlzvXQ8VTvvNA --- diff --git a/ChangeLog b/ChangeLog index 11d623c2ea..301621304f 100644 --- 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 * Cleanup from Dave Mills. * [Bug 1343] ntpd/ntp_io.c close_fd() does not compile on Solaris 7. diff --git a/include/ntp_refclock.h b/include/ntp_refclock.h index d98eb841c5..7c89af9966 100644 --- a/include/ntp_refclock.h +++ b/include/ntp_refclock.h @@ -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 *); diff --git a/ntpd/ntp_refclock.c b/ntpd/ntp_refclock.c index 00fc68c533..f6eca8d4ea 100644 --- a/ntpd/ntp_refclock.c +++ b/ntpd/ntp_refclock.c @@ -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, <emp); L_ADD(&offset, <emp); - 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) diff --git a/ntpd/refclock_nmea.c b/ntpd/refclock_nmea.c index e9645942f9..30e14261b9 100644 --- a/ntpd/refclock_nmea.c +++ b/ntpd/refclock_nmea.c @@ -21,6 +21,7 @@ #if defined(REFCLOCK) && defined(CLOCK_NMEA) +#include #include #include @@ -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); }