xref: /freebsd/contrib/ntp/ntpd/refclock_nmea.c (revision 195ebc7e9e4b129de810833791a19dfb4349d6a9)
1 /*
2  * refclock_nmea.c - clock driver for an NMEA GPS CLOCK
3  *		Michael Petry Jun 20, 1994
4  *		 based on refclock_heathn.c
5  */
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9 
10 #if defined(SYS_WINNT)
11 #undef close
12 #define close closesocket
13 #endif
14 
15 #if defined(REFCLOCK) && defined(CLOCK_NMEA)
16 
17 #include <stdio.h>
18 #include <ctype.h>
19 
20 #include "ntpd.h"
21 #include "ntp_io.h"
22 #include "ntp_unixtime.h"
23 #include "ntp_refclock.h"
24 #include "ntp_stdlib.h"
25 
26 #ifdef HAVE_PPSAPI
27 # include "ppsapi_timepps.h"
28 #endif /* HAVE_PPSAPI */
29 
30 /*
31  * This driver supports the NMEA GPS Receiver with
32  *
33  * Protype was refclock_trak.c, Thanks a lot.
34  *
35  * The receiver used spits out the NMEA sentences for boat navigation.
36  * And you thought it was an information superhighway.  Try a raging river
37  * filled with rapids and whirlpools that rip away your data and warp time.
38  *
39  * If HAVE_PPSAPI is defined code to use the PPSAPI will be compiled in.
40  * On startup if initialization of the PPSAPI fails, it will fall back
41  * to the "normal" timestamps.
42  *
43  * The PPSAPI part of the driver understands fudge flag2 and flag3. If
44  * flag2 is set, it will use the clear edge of the pulse. If flag3 is
45  * set, kernel hardpps is enabled.
46  *
47  * GPS sentences other than RMC (the default) may be enabled by setting
48  * the relevent bits of 'mode' in the server configuration line
49  * server 127.127.20.x mode X
50  *
51  * bit 0 - enables RMC (1)
52  * bit 1 - enables GGA (2)
53  * bit 2 - enables GLL (4)
54  * multiple sentences may be selected
55  */
56 
57 /*
58  * Definitions
59  */
60 #ifdef SYS_WINNT
61 # define DEVICE "COM%d:" 	/* COM 1 - 3 supported */
62 #else
63 # define DEVICE	"/dev/gps%d"	/* name of radio device */
64 #endif
65 #define	SPEED232	B4800	/* uart speed (4800 bps) */
66 #define	PRECISION	(-9)	/* precision assumed (about 2 ms) */
67 #define	PPS_PRECISION	(-20)	/* precision assumed (about 1 us) */
68 #define	REFID		"GPS\0"	/* reference id */
69 #define	DESCRIPTION	"NMEA GPS Clock" /* who we are */
70 #define NANOSECOND	1000000000 /* one second (ns) */
71 #define RANGEGATE	500000	/* range gate (ns) */
72 
73 #define LENNMEA		75	/* min timecode length */
74 
75 /*
76  * Tables to compute the ddd of year form icky dd/mm timecode. Viva la
77  * leap.
78  */
79 static int day1tab[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
80 static int day2tab[] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
81 
82 /*
83  * Unit control structure
84  */
85 struct nmeaunit {
86 	int	pollcnt;	/* poll message counter */
87 	int	polled;		/* Hand in a sample? */
88 	l_fp	tstamp;		/* timestamp of last poll */
89 #ifdef HAVE_PPSAPI
90 	struct timespec ts;	/* last timestamp */
91 	pps_params_t pps_params; /* pps parameters */
92 	pps_info_t pps_info;	/* last pps data */
93 	pps_handle_t handle;	/* pps handlebars */
94 #endif /* HAVE_PPSAPI */
95 };
96 
97 /*
98  * Function prototypes
99  */
100 static	int	nmea_start	P((int, struct peer *));
101 static	void	nmea_shutdown	P((int, struct peer *));
102 #ifdef HAVE_PPSAPI
103 static	void	nmea_control	P((int, struct refclockstat *, struct
104 				    refclockstat *, struct peer *));
105 static	int	nmea_ppsapi	P((struct peer *, int, int));
106 static	int	nmea_pps	P((struct nmeaunit *, l_fp *));
107 #endif /* HAVE_PPSAPI */
108 static	void	nmea_receive	P((struct recvbuf *));
109 static	void	nmea_poll	P((int, struct peer *));
110 static	void	gps_send	P((int, const char *, struct peer *));
111 static	char	*field_parse	P((char *, int));
112 
113 /*
114  * Transfer vector
115  */
116 struct	refclock refclock_nmea = {
117 	nmea_start,		/* start up driver */
118 	nmea_shutdown,	/* shut down driver */
119 	nmea_poll,		/* transmit poll message */
120 #ifdef HAVE_PPSAPI
121 	nmea_control,		/* fudge control */
122 #else
123 	noentry,		/* fudge control */
124 #endif /* HAVE_PPSAPI */
125 	noentry,		/* initialize driver */
126 	noentry,		/* buginfo */
127 	NOFLAGS			/* not used */
128 };
129 
130 /*
131  * nmea_start - open the GPS devices and initialize data for processing
132  */
133 static int
134 nmea_start(
135 	int unit,
136 	struct peer *peer
137 	)
138 {
139 	register struct nmeaunit *up;
140 	struct refclockproc *pp;
141 	int fd;
142 	char device[20];
143 
144 	/*
145 	 * Open serial port. Use CLK line discipline, if available.
146 	 */
147 	(void)sprintf(device, DEVICE, unit);
148 
149 	fd = refclock_open(device, SPEED232, LDISC_CLK);
150 	if (fd <= 0) {
151 #ifdef HAVE_READLINK
152           /* nmead support added by Jon Miner (cp_n18@yahoo.com)
153            *
154            * See http://home.hiwaay.net/~taylorc/gps/nmea-server/
155            * for information about nmead
156            *
157            * To use this, you need to create a link from /dev/gpsX to
158            * the server:port where nmead is running.  Something like this:
159            *
160            * ln -s server:port /dev/gps1
161            */
162           char buffer[80];
163           char *nmea_host;
164           int   nmea_port;
165           int   len;
166           struct hostent *he;
167           struct protoent *p;
168           struct sockaddr_in so_addr;
169 
170           if ((len = readlink(device,buffer,sizeof(buffer))) == -1)
171             return(0);
172           buffer[len] = 0;
173 
174           if ((nmea_host = strtok(buffer,":")) == NULL)
175             return(0);
176 
177           nmea_port = atoi(strtok(NULL,":"));
178 
179           if ((he = gethostbyname(nmea_host)) == NULL)
180             return(0);
181           if ((p = getprotobyname("ip")) == NULL)
182             return(0);
183           so_addr.sin_family = AF_INET;
184           so_addr.sin_port = htons(nmea_port);
185           so_addr.sin_addr = *((struct in_addr *) he->h_addr);
186 
187           if ((fd = socket(PF_INET,SOCK_STREAM,p->p_proto)) == -1)
188             return(0);
189           if (connect(fd,(struct sockaddr *)&so_addr,SOCKLEN(&so_addr)) == -1) {
190             close(fd);
191             return (0);
192           }
193 #else
194             return (0);
195 #endif
196         }
197 
198 	/*
199 	 * Allocate and initialize unit structure
200 	 */
201 	up = (struct nmeaunit *)emalloc(sizeof(struct nmeaunit));
202 	if (up == NULL) {
203 		(void) close(fd);
204 		return (0);
205 	}
206 	memset((char *)up, 0, sizeof(struct nmeaunit));
207 	pp = peer->procptr;
208 	pp->io.clock_recv = nmea_receive;
209 	pp->io.srcclock = (caddr_t)peer;
210 	pp->io.datalen = 0;
211 	pp->io.fd = fd;
212 	if (!io_addclock(&pp->io)) {
213 		(void) close(fd);
214 		free(up);
215 		return (0);
216 	}
217 	pp->unitptr = (caddr_t)up;
218 
219 	/*
220 	 * Initialize miscellaneous variables
221 	 */
222 	peer->precision = PRECISION;
223 	pp->clockdesc = DESCRIPTION;
224 	memcpy((char *)&pp->refid, REFID, 4);
225 	up->pollcnt = 2;
226 	gps_send(pp->io.fd,"$PMOTG,RMC,0000*1D\r\n", peer);
227 
228 #ifdef HAVE_PPSAPI
229 	/*
230 	 * Start the PPSAPI interface if it is there. Default to use
231 	 * the assert edge and do not enable the kernel hardpps.
232 	 */
233 	if (time_pps_create(fd, &up->handle) < 0) {
234 		up->handle = 0;
235 		msyslog(LOG_ERR,
236 		    "refclock_nmea: time_pps_create failed: %m");
237 		return (1);
238 	}
239 	return(nmea_ppsapi(peer, 0, 0));
240 #else
241 	return (1);
242 #endif /* HAVE_PPSAPI */
243 }
244 
245 /*
246  * nmea_shutdown - shut down a GPS clock
247  */
248 static void
249 nmea_shutdown(
250 	int unit,
251 	struct peer *peer
252 	)
253 {
254 	register struct nmeaunit *up;
255 	struct refclockproc *pp;
256 
257 	pp = peer->procptr;
258 	up = (struct nmeaunit *)pp->unitptr;
259 #ifdef HAVE_PPSAPI
260 	if (up->handle != 0)
261 		time_pps_destroy(up->handle);
262 #endif /* HAVE_PPSAPI */
263 	io_closeclock(&pp->io);
264 	free(up);
265 }
266 
267 #ifdef HAVE_PPSAPI
268 /*
269  * nmea_control - fudge control
270  */
271 static void
272 nmea_control(
273 	int unit,		/* unit (not used */
274 	struct refclockstat *in, /* input parameters (not uded) */
275 	struct refclockstat *out, /* output parameters (not used) */
276 	struct peer *peer	/* peer structure pointer */
277 	)
278 {
279 	struct refclockproc *pp;
280 
281 	pp = peer->procptr;
282 	nmea_ppsapi(peer, pp->sloppyclockflag & CLK_FLAG2,
283 	    pp->sloppyclockflag & CLK_FLAG3);
284 }
285 
286 
287 /*
288  * Initialize PPSAPI
289  */
290 int
291 nmea_ppsapi(
292 	struct peer *peer,	/* peer structure pointer */
293 	int enb_clear,		/* clear enable */
294 	int enb_hardpps		/* hardpps enable */
295 	)
296 {
297 	struct refclockproc *pp;
298 	struct nmeaunit *up;
299 	int capability;
300 
301 	pp = peer->procptr;
302 	up = (struct nmeaunit *)pp->unitptr;
303 	if (time_pps_getcap(up->handle, &capability) < 0) {
304 		msyslog(LOG_ERR,
305 		    "refclock_nmea: time_pps_getcap failed: %m");
306 		return (0);
307 	}
308 	memset(&up->pps_params, 0, sizeof(pps_params_t));
309 	if (enb_clear)
310 		up->pps_params.mode = capability & PPS_CAPTURECLEAR;
311 	else
312 		up->pps_params.mode = capability & PPS_CAPTUREASSERT;
313 	if (!up->pps_params.mode) {
314 		msyslog(LOG_ERR,
315 		    "refclock_nmea: invalid capture edge %d",
316 		    !enb_clear);
317 		return (0);
318 	}
319 	up->pps_params.mode |= PPS_TSFMT_TSPEC;
320 	if (time_pps_setparams(up->handle, &up->pps_params) < 0) {
321 		msyslog(LOG_ERR,
322 		    "refclock_nmea: time_pps_setparams failed: %m");
323 		return (0);
324 	}
325 	if (enb_hardpps) {
326 		if (time_pps_kcbind(up->handle, PPS_KC_HARDPPS,
327 				    up->pps_params.mode & ~PPS_TSFMT_TSPEC,
328 				    PPS_TSFMT_TSPEC) < 0) {
329 			msyslog(LOG_ERR,
330 			    "refclock_nmea: time_pps_kcbind failed: %m");
331 			return (0);
332 		}
333 		pps_enable = 1;
334 	}
335 	peer->precision = PPS_PRECISION;
336 
337 #if DEBUG
338 	if (debug) {
339 		time_pps_getparams(up->handle, &up->pps_params);
340 		printf(
341 		    "refclock_ppsapi: capability 0x%x version %d mode 0x%x kern %d\n",
342 		    capability, up->pps_params.api_version,
343 		    up->pps_params.mode, enb_hardpps);
344 	}
345 #endif
346 
347 	return (1);
348 }
349 
350 /*
351  * Get PPSAPI timestamps.
352  *
353  * Return 0 on failure and 1 on success.
354  */
355 static int
356 nmea_pps(
357 	struct nmeaunit *up,
358 	l_fp *tsptr
359 	)
360 {
361 	pps_info_t pps_info;
362 	struct timespec timeout, ts;
363 	double dtemp;
364 	l_fp tstmp;
365 
366 	/*
367 	 * Convert the timespec nanoseconds field to ntp l_fp units.
368 	 */
369 	if (up->handle == 0)
370 		return (0);
371 	timeout.tv_sec = 0;
372 	timeout.tv_nsec = 0;
373 	memcpy(&pps_info, &up->pps_info, sizeof(pps_info_t));
374 	if (time_pps_fetch(up->handle, PPS_TSFMT_TSPEC, &up->pps_info,
375 	    &timeout) < 0)
376 		return (0);
377 	if (up->pps_params.mode & PPS_CAPTUREASSERT) {
378 		if (pps_info.assert_sequence ==
379 		    up->pps_info.assert_sequence)
380 			return (0);
381 		ts = up->pps_info.assert_timestamp;
382 	} else if (up->pps_params.mode & PPS_CAPTURECLEAR) {
383 		if (pps_info.clear_sequence ==
384 		    up->pps_info.clear_sequence)
385 			return (0);
386 		ts = up->pps_info.clear_timestamp;
387 	} else {
388 		return (0);
389 	}
390 	if ((up->ts.tv_sec == ts.tv_sec) && (up->ts.tv_nsec == ts.tv_nsec))
391 		return (0);
392 	up->ts = ts;
393 
394 	tstmp.l_ui = ts.tv_sec + JAN_1970;
395 	dtemp = ts.tv_nsec * FRAC / 1e9;
396 	tstmp.l_uf = (u_int32)dtemp;
397 	*tsptr = tstmp;
398 	return (1);
399 }
400 #endif /* HAVE_PPSAPI */
401 
402 /*
403  * nmea_receive - receive data from the serial interface
404  */
405 static void
406 nmea_receive(
407 	struct recvbuf *rbufp
408 	)
409 {
410 	register struct nmeaunit *up;
411 	struct refclockproc *pp;
412 	struct peer *peer;
413 	int month, day;
414 	int i;
415 	char *cp, *dp;
416 	int cmdtype;
417 	/* Use these variables to hold data until we decide its worth keeping */
418 	char	rd_lastcode[BMAX];
419 	l_fp	rd_tmp;
420 	u_short	rd_lencode;
421 
422 	/*
423 	 * Initialize pointers and read the timecode and timestamp
424 	 */
425 	peer = (struct peer *)rbufp->recv_srcclock;
426 	pp = peer->procptr;
427 	up = (struct nmeaunit *)pp->unitptr;
428 	rd_lencode = (u_short)refclock_gtlin(rbufp, rd_lastcode, BMAX, &rd_tmp);
429 
430 	/*
431 	 * There is a case that a <CR><LF> gives back a "blank" line
432 	 */
433 	if (rd_lencode == 0)
434 	    return;
435 
436 #ifdef DEBUG
437 	if (debug)
438 	    printf("nmea: gpsread %d %s\n", rd_lencode,
439 		   rd_lastcode);
440 #endif
441 
442 	/*
443 	 * We check the timecode format and decode its contents. The
444 	 * we only care about a few of them.  The most important being
445 	 * the $GPRMC format
446 	 * $GPRMC,hhmmss,a,fddmm.xx,n,dddmmm.xx,w,zz.z,yyy.,ddmmyy,dd,v*CC
447 	 * For Magellan (ColorTrak) GLL probably datum (order of sentences)
448 	 * also mode (0,1,2,3) select sentence ANY/ALL, RMC, GGA, GLL
449 	 * $GPGLL,3513.8385,S,14900.7851,E,232420.594,A*21
450   	 * $GPGGA,232420.59,3513.8385,S,14900.7851,E,1,05,3.4,00519,M,,,,*3F
451 	 * $GPRMB,...
452 	 * $GPRMC,232418.19,A,3513.8386,S,14900.7853,E,00.0,000.0,121199,12.,E*77
453 	 * $GPAPB,...
454 	 * $GPGSA,...
455 	 * $GPGSV,...
456 	 * $GPGSV,...
457 	 */
458 #define GPXXX	0
459 #define GPRMC	1
460 #define GPGGA	2
461 #define GPGLL	4
462 	cp = rd_lastcode;
463 	cmdtype=0;
464 	if(strncmp(cp,"$GPRMC",6)==0) {
465 		cmdtype=GPRMC;
466 	}
467 	else if(strncmp(cp,"$GPGGA",6)==0) {
468 		cmdtype=GPGGA;
469 	}
470 	else if(strncmp(cp,"$GPGLL",6)==0) {
471 		cmdtype=GPGLL;
472 	}
473 	else if(strncmp(cp,"$GPXXX",6)==0) {
474 		cmdtype=GPXXX;
475 	}
476 	else
477 	    return;
478 
479 
480 	/* See if I want to process this message type */
481 	if ( ((peer->ttl == 0) && (cmdtype != GPRMC))
482            || ((peer->ttl != 0) && !(cmdtype & peer->ttl)) )
483 		return;
484 
485 	pp->lencode = rd_lencode;
486 	strcpy(pp->a_lastcode,rd_lastcode);
487 	cp = pp->a_lastcode;
488 
489 	pp->lastrec = up->tstamp = rd_tmp;
490 	up->pollcnt = 2;
491 
492 #ifdef DEBUG
493 	if (debug)
494 	    printf("nmea: timecode %d %s\n", pp->lencode,
495 		   pp->a_lastcode);
496 #endif
497 
498 
499 	/* Grab field depending on clock string type */
500 	switch( cmdtype ) {
501 	    case GPRMC:
502 		/*
503 		 * Test for synchronization.  Check for quality byte.
504 		 */
505 		dp = field_parse(cp,2);
506 		if( dp[0] != 'A')
507 			pp->leap = LEAP_NOTINSYNC;
508 		else
509 			pp->leap = LEAP_NOWARNING;
510 
511 		/* Now point at the time field */
512 		dp = field_parse(cp,1);
513 		break;
514 
515 
516 	    case GPGGA:
517 		/*
518 		 * Test for synchronization.  Check for quality byte.
519 		 */
520 		dp = field_parse(cp,6);
521 		if( dp[0] == '0')
522 			pp->leap = LEAP_NOTINSYNC;
523 		else
524 			pp->leap = LEAP_NOWARNING;
525 
526 		/* Now point at the time field */
527 		dp = field_parse(cp,1);
528 		break;
529 
530 
531 	    case GPGLL:
532 		/*
533 		 * Test for synchronization.  Check for quality byte.
534 		 */
535 		dp = field_parse(cp,6);
536 		if( dp[0] != 'A')
537 			pp->leap = LEAP_NOTINSYNC;
538 		else
539 			pp->leap = LEAP_NOWARNING;
540 
541 		/* Now point at the time field */
542 		dp = field_parse(cp,5);
543 		break;
544 
545 
546 	    case GPXXX:
547 		return;
548 	    default:
549 		return;
550 
551 	}
552 
553 		/*
554 		 *	Check time code format of NMEA
555 		 */
556 
557 		if( !isdigit((int)dp[0]) ||
558 		    !isdigit((int)dp[1]) ||
559 		    !isdigit((int)dp[2]) ||
560 		    !isdigit((int)dp[3]) ||
561 		    !isdigit((int)dp[4]) ||
562 		    !isdigit((int)dp[5])
563 		    ) {
564 			refclock_report(peer, CEVNT_BADREPLY);
565 			return;
566 		}
567 
568 
569 	/*
570 	 * Convert time and check values.
571 	 */
572 	pp->hour = ((dp[0] - '0') * 10) + dp[1] - '0';
573 	pp->minute = ((dp[2] - '0') * 10) + dp[3] -  '0';
574 	pp->second = ((dp[4] - '0') * 10) + dp[5] - '0';
575 	/* Default to 0 milliseconds, if decimal convert milliseconds in
576 	   one, two or three digits
577 	*/
578 	pp->nsec = 0;
579 	if (dp[6] == '.') {
580 		if (isdigit((int)dp[7])) {
581 			pp->nsec = (dp[7] - '0') * 100000000;
582 			if (isdigit((int)dp[8])) {
583 				pp->nsec += (dp[8] - '0') * 10000000;
584 				if (isdigit((int)dp[9])) {
585 					pp->nsec += (dp[9] - '0') * 1000000;
586 				}
587 			}
588 		}
589 	}
590 
591 	if (pp->hour > 23 || pp->minute > 59 || pp->second > 59
592 	  || pp->nsec > 1000000000) {
593 		refclock_report(peer, CEVNT_BADTIME);
594 		return;
595 	}
596 
597 
598 	/*
599 	 * Convert date and check values.
600 	 */
601 	if (cmdtype==GPRMC) {
602 	    dp = field_parse(cp,9);
603 	    day = dp[0] - '0';
604 	    day = (day * 10) + dp[1] - '0';
605 	    month = dp[2] - '0';
606 	    month = (month * 10) + dp[3] - '0';
607 	    pp->year = dp[4] - '0';
608 	    pp->year = (pp->year * 10) + dp[5] - '0';
609 	}
610 	else {
611 	/* only time */
612 	    time_t tt = time(NULL);
613 	    struct tm * t = gmtime(&tt);
614 	    day = t->tm_mday;
615 	    month = t->tm_mon + 1;
616 	    pp->year= t->tm_year;
617 	}
618 
619 	if (month < 1 || month > 12 || day < 1) {
620 		refclock_report(peer, CEVNT_BADTIME);
621 		return;
622 	}
623 
624         /* Hmmmm this will be a nono for 2100,2200,2300 but I don't think I'll be here */
625         /* good thing that 2000 is a leap year */
626 	/* pp->year will be 00-99 if read from GPS, 00->  (years since 1900) from tm_year */
627 	if (pp->year % 4) {
628 		if (day > day1tab[month - 1]) {
629 			refclock_report(peer, CEVNT_BADTIME);
630 			return;
631 		}
632 		for (i = 0; i < month - 1; i++)
633 		    day += day1tab[i];
634 	} else {
635 		if (day > day2tab[month - 1]) {
636 			refclock_report(peer, CEVNT_BADTIME);
637 			return;
638 		}
639 		for (i = 0; i < month - 1; i++)
640 		    day += day2tab[i];
641 	}
642 	pp->day = day;
643 
644 
645 #ifdef HAVE_PPSAPI
646 	/*
647 	 * If the PPSAPI is working, rather use its timestamps.
648 	 * assume that the PPS occurs on the second so blow any msec
649 	 */
650 	if (nmea_pps(up, &rd_tmp) == 1) {
651 		pp->lastrec = up->tstamp = rd_tmp;
652 		pp->nsec = 0;
653 	}
654 #endif /* HAVE_PPSAPI */
655 
656 	/*
657 	 * Process the new sample in the median filter and determine the
658 	 * reference clock offset and dispersion. We use lastrec as both
659 	 * the reference time and receive time, in order to avoid being
660 	 * cute, like setting the reference time later than the receive
661 	 * time, which may cause a paranoid protocol module to chuck out
662 	 * the data.
663 	 */
664 
665 	if (!refclock_process(pp)) {
666 		refclock_report(peer, CEVNT_BADTIME);
667 		return;
668 	}
669 
670 
671 
672 	/*
673 	 * Only go on if we had been polled.
674 	 */
675 	if (!up->polled)
676 	    return;
677 	up->polled = 0;
678 	pp->lastref = pp->lastrec;
679 	refclock_receive(peer);
680 
681         /* If we get here - what we got from the clock is OK, so say so */
682          refclock_report(peer, CEVNT_NOMINAL);
683 
684 	record_clock_stats(&peer->srcadr, pp->a_lastcode);
685 
686 }
687 
688 /*
689  * nmea_poll - called by the transmit procedure
690  *
691  * We go to great pains to avoid changing state here, since there may be
692  * more than one eavesdropper receiving the same timecode.
693  */
694 static void
695 nmea_poll(
696 	int unit,
697 	struct peer *peer
698 	)
699 {
700 	register struct nmeaunit *up;
701 	struct refclockproc *pp;
702 
703 	pp = peer->procptr;
704 	up = (struct nmeaunit *)pp->unitptr;
705 	if (up->pollcnt == 0)
706 	    refclock_report(peer, CEVNT_TIMEOUT);
707 	else
708 	    up->pollcnt--;
709 	pp->polls++;
710 	up->polled = 1;
711 
712 	/*
713 	 * usually nmea_receive can get a timestamp every second
714 	 */
715 
716 	gps_send(pp->io.fd,"$PMOTG,RMC,0000*1D\r\n", peer);
717 }
718 
719 /*
720  *
721  *	gps_send(fd,cmd, peer)  Sends a command to the GPS receiver.
722  *	 as	gps_send(fd,"rqts,u\r", peer);
723  *
724  *	We don't currently send any data, but would like to send
725  *	RTCM SC104 messages for differential positioning. It should
726  *	also give us better time. Without a PPS output, we're
727  *	Just fooling ourselves because of the serial code paths
728  *
729  */
730 static void
731 gps_send(
732 	int fd,
733 	const char *cmd,
734 	struct peer *peer
735 	)
736 {
737 
738 	if (write(fd, cmd, strlen(cmd)) == -1) {
739 		refclock_report(peer, CEVNT_FAULT);
740 	}
741 }
742 
743 static char *
744 field_parse(
745 	char *cp,
746 	int fn
747 	)
748 {
749 	char *tp;
750 	int i = fn;
751 
752 	for (tp = cp; *tp != '\0'; tp++) {
753 		if (*tp == ',')
754 		    i--;
755 		if (i == 0)
756 		    break;
757 	}
758 	return (++tp);
759 }
760 #else
761 int refclock_nmea_bs;
762 #endif /* REFCLOCK */
763