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 */
};
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 *);
/*
* 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,
* 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;
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
*
/*
* 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)
#if defined(REFCLOCK) && defined(CLOCK_NMEA)
+#include <sys/stat.h>
#include <stdio.h>
#include <ctype.h>
/*
* 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) */
#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
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 */
/*
* 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
* 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;
*/
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);
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);
}
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);
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;
}
* 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;
}
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;
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;
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);
}