Expand PMF_FN_* macros.
[netbsd-mini2440.git] / dist / ntp / ntpd / refclock_palisade.c
blob23e38d4dca75ee924f3057da148e1b6c81ab40bf
1 /* $NetBSD: refclock_palisade.c,v 1.3 2005/05/21 01:47:09 riz Exp $ */
3 /*
4 * This software was developed by the Software and Component Technologies
5 * group of Trimble Navigation, Ltd.
7 * Copyright (c) 1997, 1998, 1999, 2000 Trimble Navigation Ltd.
8 * All rights reserved.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by Trimble Navigation, Ltd.
21 * 4. The name of Trimble Navigation Ltd. may not be used to endorse or
22 * promote products derived from this software without specific prior
23 * written permission.
25 * THIS SOFTWARE IS PROVIDED BY TRIMBLE NAVIGATION LTD. ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL TRIMBLE NAVIGATION LTD. BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
39 * refclock_palisade - clock driver for the Trimble Palisade GPS
40 * timing receiver
42 * For detailed information on this program, please refer to the html
43 * Refclock 29 page accompanying the NTP distribution.
45 * for questions / bugs / comments, contact:
46 * sven_dietrich@trimble.com
48 * Sven-Thorsten Dietrich
49 * 645 North Mary Avenue
50 * Post Office Box 3642
51 * Sunnyvale, CA 94088-3642
53 * Version 2.45; July 14, 1999
57 #ifdef HAVE_CONFIG_H
58 #include "config.h"
59 #endif
61 #if defined(REFCLOCK) && (defined(PALISADE) || defined(CLOCK_PALISADE))
63 #ifdef SYS_WINNT
64 extern int async_write(int, const void *, unsigned int);
65 #undef write
66 #define write(fd, data, octets) async_write(fd, data, octets)
67 #endif
69 #include "refclock_palisade.h"
70 /* Table to get from month to day of the year */
71 const int days_of_year [12] = {
72 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
75 #ifdef DEBUG
76 const char * Tracking_Status[15][15] = {
77 { "Doing Fixes\0" }, { "Good 1SV\0" }, { "Approx. 1SV\0" },
78 {"Need Time\0" }, { "Need INIT\0" }, { "PDOP too High\0" },
79 { "Bad 1SV\0" }, { "0SV Usable\0" }, { "1SV Usable\0" },
80 { "2SV Usable\0" }, { "3SV Usable\0" }, { "No Integrity\0" },
81 { "Diff Corr\0" }, { "Overdet Clock\0" }, { "Invalid\0" } };
82 #endif
85 * Transfer vector
87 struct refclock refclock_palisade = {
88 palisade_start, /* start up driver */
89 palisade_shutdown, /* shut down driver */
90 palisade_poll, /* transmit poll message */
91 noentry, /* not used */
92 noentry, /* initialize driver (not used) */
93 noentry, /* not used */
94 NOFLAGS /* not used */
97 int day_of_year P((char *dt));
99 /* Extract the clock type from the mode setting */
100 #define CLK_TYPE(x) ((int)(((x)->ttl) & 0x7F))
102 /* Supported clock types */
103 #define CLK_TRIMBLE 0 /* Trimble Palisade */
104 #define CLK_PRAECIS 1 /* Endrun Technologies Praecis */
106 int praecis_msg;
107 static void praecis_parse(struct recvbuf *rbufp, struct peer *peer);
110 * palisade_start - open the devices and initialize data for processing
112 static int
113 palisade_start (
114 #ifdef PALISADE
115 unit, peer
117 int unit;
118 struct peer *peer;
119 #else /* ANSI */
120 int unit,
121 struct peer *peer
123 #endif
125 struct palisade_unit *up;
126 struct refclockproc *pp;
127 int fd;
128 char gpsdev[20];
130 struct termios tio;
131 #ifdef SYS_WINNT
132 (void) sprintf(gpsdev, "COM%d:", unit);
133 #else
134 (void) sprintf(gpsdev, DEVICE, unit);
135 #endif
137 * Open serial port.
139 #if defined PALISADE
140 fd = open(gpsdev, O_RDWR
141 #ifdef O_NONBLOCK
142 | O_NONBLOCK
143 #endif
145 #else /* NTP 4.x */
146 fd = refclock_open(gpsdev, SPEED232, LDISC_RAW);
147 #endif
148 if (fd <= 0) {
149 #ifdef DEBUG
150 printf("Palisade(%d) start: open %s failed\n", unit, gpsdev);
151 #endif
152 return 0;
155 msyslog(LOG_NOTICE, "Palisade(%d) fd: %d dev: %s", unit, fd,
156 gpsdev);
158 #if defined PALISADE
159 tio.c_cflag = (CS8|CLOCAL|CREAD|PARENB|PARODD);
160 tio.c_iflag = (IGNBRK);
161 tio.c_oflag = (0);
162 tio.c_lflag = (0);
164 if (cfsetispeed(&tio, SPEED232) == -1) {
165 msyslog(LOG_ERR,"Palisade(%d) cfsetispeed(fd, &tio): %m",unit);
166 #ifdef DEBUG
167 printf("Palisade(%d) cfsetispeed(fd, &tio)\n",unit);
168 #endif
169 return 0;
171 if (cfsetospeed(&tio, SPEED232) == -1) {
172 #ifdef DEBUG
173 printf("Palisade(%d) cfsetospeed(fd, &tio)\n",unit);
174 #endif
175 msyslog(LOG_ERR,"Palisade(%d) cfsetospeed(fd, &tio): %m",unit);
176 return 0;
178 #else /* NTP 4.x */
179 if (tcgetattr(fd, &tio) < 0) {
180 msyslog(LOG_ERR,
181 "Palisade(%d) tcgetattr(fd, &tio): %m",unit);
182 #ifdef DEBUG
183 printf("Palisade(%d) tcgetattr(fd, &tio)\n",unit);
184 #endif
185 return (0);
188 tio.c_cflag |= (PARENB|PARODD);
189 tio.c_iflag &= ~ICRNL;
190 #endif /* NTP 4.x */
192 if (tcsetattr(fd, TCSANOW, &tio) == -1) {
193 msyslog(LOG_ERR, "Palisade(%d) tcsetattr(fd, &tio): %m",unit);
194 #ifdef DEBUG
195 printf("Palisade(%d) tcsetattr(fd, &tio)\n",unit);
196 #endif
197 return 0;
201 * Allocate and initialize unit structure
203 up = (struct palisade_unit *) emalloc(sizeof(struct palisade_unit));
205 if (!(up)) {
206 msyslog(LOG_ERR, "Palisade(%d) emalloc: %m",unit);
207 #ifdef DEBUG
208 printf("Palisade(%d) emalloc\n",unit);
209 #endif
210 (void) close(fd);
211 return (0);
214 memset((char *)up, 0, sizeof(struct palisade_unit));
216 up->type = CLK_TYPE(peer);
217 switch (up->type) {
218 case CLK_TRIMBLE:
219 /* Normal mode, do nothing */
220 break;
221 case CLK_PRAECIS:
222 msyslog(LOG_NOTICE, "Palisade(%d) Praecis mode enabled\n",unit);
223 break;
224 default:
225 msyslog(LOG_NOTICE, "Palisade(%d) mode unknown\n",unit);
226 break;
229 pp = peer->procptr;
230 pp->io.clock_recv = palisade_io;
231 pp->io.srcclock = (caddr_t)peer;
232 pp->io.datalen = 0;
233 pp->io.fd = fd;
234 if (!io_addclock(&pp->io)) {
235 #ifdef DEBUG
236 printf("Palisade(%d) io_addclock\n",unit);
237 #endif
238 (void) close(fd);
239 free(up);
240 return (0);
244 * Initialize miscellaneous variables
246 pp->unitptr = (caddr_t)up;
247 pp->clockdesc = DESCRIPTION;
249 peer->precision = PRECISION;
250 peer->sstclktype = CTL_SST_TS_UHF;
251 peer->minpoll = TRMB_MINPOLL;
252 peer->maxpoll = TRMB_MAXPOLL;
253 memcpy((char *)&pp->refid, REFID, 4);
255 up->leap_status = 0;
256 up->unit = (short) unit;
257 up->rpt_status = TSIP_PARSED_EMPTY;
258 up->rpt_cnt = 0;
260 return 1;
265 * palisade_shutdown - shut down the clock
267 static void
268 palisade_shutdown (
269 #ifdef PALISADE
270 unit, peer
272 int unit;
273 struct peer *peer;
274 #else /* ANSI */
275 int unit,
276 struct peer *peer
278 #endif
280 struct palisade_unit *up;
281 struct refclockproc *pp;
282 pp = peer->procptr;
283 up = (struct palisade_unit *)pp->unitptr;
284 io_closeclock(&pp->io);
285 free(up);
291 * unpack_date - get day and year from date
294 day_of_year (
295 #ifdef PALISADE
298 char * dt;
299 #else
300 char * dt
302 #endif
304 int day, mon, year;
306 mon = dt[1];
307 /* Check month is inside array bounds */
308 if ((mon < 1) || (mon > 12))
309 return -1;
311 day = dt[0] + days_of_year[mon - 1];
312 year = getint((u_char *) (dt + 2));
314 if ( !(year % 4) && ((year % 100) ||
315 (!(year % 100) && !(year%400)))
316 &&(mon > 2))
317 day ++; /* leap year and March or later */
319 return day;
324 * TSIP_decode - decode the TSIP data packets
327 TSIP_decode (
328 #ifdef PALISADE
329 peer
331 struct peer *peer;
332 #else
333 struct peer *peer
335 #endif
337 int st;
338 long secint;
339 double secs;
340 double secfrac;
341 unsigned short event = 0;
343 struct palisade_unit *up;
344 struct refclockproc *pp;
346 pp = peer->procptr;
347 up = (struct palisade_unit *)pp->unitptr;
350 * Check the time packet, decode its contents.
351 * If the timecode has invalid length or is not in
352 * proper format, declare bad format and exit.
355 if ((up->rpt_buf[0] == (char) 0x41) ||
356 (up->rpt_buf[0] == (char) 0x46) ||
357 (up->rpt_buf[0] == (char) 0x54) ||
358 (up->rpt_buf[0] == (char) 0x4B) ||
359 (up->rpt_buf[0] == (char) 0x6D)) {
361 /* standard time packet - GPS time and GPS week number */
362 #ifdef DEBUG
363 printf("Palisade Port B packets detected. Connect to Port A\n");
364 #endif
366 return 0;
370 * We cast both to u_char to as 0x8f uses the sign bit on a char
372 if ((u_char) up->rpt_buf[0] == (u_char) 0x8f) {
374 * Superpackets
376 event = (unsigned short) (getint((u_char *) &mb(1)) & 0xffff);
377 if (!((pp->sloppyclockflag & CLK_FLAG2) || event))
378 /* Ignore Packet */
379 return 0;
381 switch (mb(0) & 0xff) {
382 int GPS_UTC_Offset;
383 case PACKET_8F0B:
385 if (up->polled <= 0)
386 return 0;
388 if (up->rpt_cnt != LENCODE_8F0B) /* check length */
389 break;
391 #ifdef DEBUG
392 if (debug > 1) {
393 int ts;
394 double lat, lon, alt;
395 lat = getdbl((u_char *) &mb(42)) * R2D;
396 lon = getdbl((u_char *) &mb(50)) * R2D;
397 alt = getdbl((u_char *) &mb(58));
399 printf("TSIP_decode: unit %d: Latitude: %03.4f Longitude: %03.4f Alt: %05.2f m\n",
400 up->unit, lat,lon,alt);
401 printf("TSIP_decode: unit %d: Sats:", up->unit);
402 for (st = 66, ts = 0; st <= 73; st++) if (mb(st)) {
403 if (mb(st) > 0) ts++;
404 printf(" %02d", mb(st));
406 printf(" : Tracking %d\n", ts);
408 #endif
410 GPS_UTC_Offset = getint((u_char *) &mb(16));
411 if (GPS_UTC_Offset == 0) { /* Check UTC offset */
412 #ifdef DEBUG
413 printf("TSIP_decode: UTC Offset Unknown\n");
414 #endif
415 break;
418 secs = getdbl((u_char *) &mb(3));
419 secint = (long) secs;
420 secfrac = secs - secint; /* 0.0 <= secfrac < 1.0 */
422 pp->nsec = (long) (secfrac * 1000000000);
424 secint %= 86400; /* Only care about today */
425 pp->hour = secint / 3600;
426 secint %= 3600;
427 pp->minute = secint / 60;
428 secint %= 60;
429 pp->second = secint % 60;
431 if ((pp->day = day_of_year(&mb(11))) < 0) break;
433 pp->year = getint((u_char *) &mb(13));
435 #ifdef DEBUG
436 if (debug > 1)
437 printf("TSIP_decode: unit %d: %02X #%d %02d:%02d:%02d.%06ld %02d/%02d/%04d UTC %02d\n",
438 up->unit, mb(0) & 0xff, event, pp->hour, pp->minute,
439 pp->second, pp->nsec, mb(12), mb(11), pp->year, GPS_UTC_Offset);
440 #endif
441 /* Only use this packet when no
442 * 8F-AD's are being received
445 if (up->leap_status) {
446 up->leap_status = 0;
447 return 0;
450 return 2;
451 break;
453 case PACKET_NTP:
454 /* Palisade-NTP Packet */
456 if (up->rpt_cnt != LENCODE_NTP) /* check length */
457 break;
459 up->leap_status = mb(19);
461 if (up->polled <= 0)
462 return 0;
464 /* Check Tracking Status */
465 st = mb(18);
466 if (st < 0 || st > 14) st = 14;
467 if ((st >= 2 && st <= 7) || st == 11 || st == 12) {
468 #ifdef DEBUG
469 printf("TSIP_decode: Not Tracking Sats : %s\n",
470 *Tracking_Status[st]);
471 #endif
472 refclock_report(peer, CEVNT_BADTIME);
473 up->polled = -1;
474 return 0;
475 break;
478 if (up->leap_status & PALISADE_LEAP_PENDING) {
479 if (up->leap_status & PALISADE_UTC_TIME)
480 pp->leap = LEAP_ADDSECOND;
481 else
482 pp->leap = LEAP_DELSECOND;
484 else if (up->leap_status)
485 pp->leap = LEAP_NOWARNING;
487 else { /* UTC flag is not set:
488 * Receiver may have been reset, and lost
489 * its UTC almanac data */
490 pp->leap = LEAP_NOTINSYNC;
491 #ifdef DEBUG
492 printf("TSIP_decode: UTC Almanac unavailable: %d\n",
493 mb(19));
494 #endif
495 refclock_report(peer, CEVNT_BADTIME);
496 up->polled = -1;
497 return 0;
500 pp->nsec = (long) (getdbl((u_char *) &mb(3)) * 1000000000);
502 if ((pp->day = day_of_year(&mb(14))) < 0)
503 break;
504 pp->year = getint((u_char *) &mb(16));
505 pp->hour = mb(11);
506 pp->minute = mb(12);
507 pp->second = mb(13);
509 #ifdef DEBUG
510 if (debug > 1)
511 printf("TSIP_decode: unit %d: %02X #%d %02d:%02d:%02d.%06ld %02d/%02d/%04d UTC %02x %s\n",
512 up->unit, mb(0) & 0xff, event, pp->hour, pp->minute,
513 pp->second, pp->nsec, mb(15), mb(14), pp->year,
514 mb(19), *Tracking_Status[st]);
515 #endif
516 return 1;
517 break;
519 default:
520 /* Ignore Packet */
521 return 0;
522 } /* switch */
523 }/* if 8F packets */
525 refclock_report(peer, CEVNT_BADREPLY);
526 up->polled = -1;
527 #ifdef DEBUG
528 printf("TSIP_decode: unit %d: bad packet %02x-%02x event %d len %d\n",
529 up->unit, up->rpt_buf[0] & 0xff, mb(0) & 0xff,
530 event, up->rpt_cnt);
531 #endif
532 return 0;
536 * palisade__receive - receive data from the serial interface
539 static void
540 palisade_receive (
541 #ifdef PALISADE
542 peer
544 struct peer * peer;
545 #else /* ANSI */
546 struct peer * peer
548 #endif
550 struct palisade_unit *up;
551 struct refclockproc *pp;
554 * Initialize pointers and read the timecode and timestamp.
556 pp = peer->procptr;
557 up = (struct palisade_unit *)pp->unitptr;
559 if (! TSIP_decode(peer)) return;
561 if (up->polled <= 0)
562 return; /* no poll pending, already received or timeout */
564 up->polled = 0; /* Poll reply received */
565 pp->lencode = 0; /* clear time code */
566 #ifdef DEBUG
567 if (debug)
568 printf(
569 "palisade_receive: unit %d: %4d %03d %02d:%02d:%02d.%06ld\n",
570 up->unit, pp->year, pp->day, pp->hour, pp->minute,
571 pp->second, pp->nsec);
572 #endif
575 * Process the sample
576 * Generate timecode: YYYY DoY HH:MM:SS.microsec
577 * report and process
580 (void) sprintf(pp->a_lastcode,"%4d %03d %02d:%02d:%02d.%06ld",
581 pp->year,pp->day,pp->hour,pp->minute, pp->second,pp->nsec);
582 pp->lencode = 24;
584 #ifdef PALISADE
585 pp->lasttime = current_time;
586 #endif
587 if (!refclock_process(pp
588 #ifdef PALISADE
589 , PALISADE_SAMPLES, PALISADE_SAMPLES * 3 / 5
590 #endif
591 )) {
592 refclock_report(peer, CEVNT_BADTIME);
594 #ifdef DEBUG
595 printf("palisade_receive: unit %d: refclock_process failed!\n",
596 up->unit);
597 #endif
598 return;
601 record_clock_stats(&peer->srcadr, pp->a_lastcode);
603 #ifdef DEBUG
604 if (debug)
605 printf("palisade_receive: unit %d: %s\n",
606 up->unit, prettydate(&pp->lastrec));
607 #endif
608 pp->lastref = pp->lastrec;
609 refclock_receive(peer
610 #ifdef PALISADE
611 , &pp->offset, 0, pp->dispersion,
612 &pp->lastrec, &pp->lastrec, pp->leap
613 #endif
619 * palisade_poll - called by the transmit procedure
622 static void
623 palisade_poll (
624 #ifdef PALISADE
625 unit, peer
627 int unit;
628 struct peer *peer;
629 #else
630 int unit,
631 struct peer *peer
633 #endif
635 struct palisade_unit *up;
636 struct refclockproc *pp;
638 pp = peer->procptr;
639 up = (struct palisade_unit *)pp->unitptr;
641 pp->polls++;
642 if (up->polled > 0) /* last reply never arrived or error */
643 refclock_report(peer, CEVNT_TIMEOUT);
645 up->polled = 2; /* synchronous packet + 1 event */
647 #ifdef DEBUG
648 if (debug)
649 printf("palisade_poll: unit %d: polling %s\n", unit,
650 (pp->sloppyclockflag & CLK_FLAG2) ?
651 "synchronous packet" : "event");
652 #endif
654 if (pp->sloppyclockflag & CLK_FLAG2)
655 return; /* using synchronous packet input */
657 if(up->type == CLK_PRAECIS) {
658 if(write(peer->procptr->io.fd,"SPSTAT\r\n",8) < 0)
659 msyslog(LOG_ERR, "Palisade(%d) write: %m:",unit);
660 else {
661 praecis_msg = 1;
662 return;
666 if (HW_poll(pp) < 0)
667 refclock_report(peer, CEVNT_FAULT);
670 static void
671 praecis_parse(struct recvbuf *rbufp, struct peer *peer)
673 static char buf[100];
674 static int p = 0;
675 struct refclockproc *pp;
677 pp = peer->procptr;
679 memcpy(buf+p,rbufp->recv_space.X_recv_buffer, rbufp->recv_length);
680 p += rbufp->recv_length;
682 if(buf[p-2] == '\r' && buf[p-1] == '\n') {
683 buf[p-2] = '\0';
684 record_clock_stats(&peer->srcadr, buf);
686 p = 0;
687 praecis_msg = 0;
689 if (HW_poll(pp) < 0)
690 refclock_report(peer, CEVNT_FAULT);
695 static void
696 palisade_io (
697 #ifdef PALISADE
698 rbufp
700 struct recvbuf *rbufp;
701 #else /* ANSI */
702 struct recvbuf *rbufp
704 #endif
707 * Initialize pointers and read the timecode and timestamp.
709 struct palisade_unit *up;
710 struct refclockproc *pp;
711 struct peer *peer;
713 char * c, * d;
715 peer = (struct peer *)rbufp->recv_srcclock;
716 pp = peer->procptr;
717 up = (struct palisade_unit *)pp->unitptr;
719 if(up->type == CLK_PRAECIS) {
720 if(praecis_msg) {
721 praecis_parse(rbufp,peer);
722 return;
726 c = (char *) &rbufp->recv_space;
727 d = c + rbufp->recv_length;
729 while (c != d) {
731 /* Build time packet */
732 switch (up->rpt_status) {
734 case TSIP_PARSED_DLE_1:
735 switch (*c)
737 case 0:
738 case DLE:
739 case ETX:
740 up->rpt_status = TSIP_PARSED_EMPTY;
741 break;
743 default:
744 up->rpt_status = TSIP_PARSED_DATA;
745 /* save packet ID */
746 up->rpt_buf[0] = *c;
747 break;
749 break;
751 case TSIP_PARSED_DATA:
752 if (*c == DLE)
753 up->rpt_status = TSIP_PARSED_DLE_2;
754 else
755 mb(up->rpt_cnt++) = *c;
756 break;
758 case TSIP_PARSED_DLE_2:
759 if (*c == DLE) {
760 up->rpt_status = TSIP_PARSED_DATA;
761 mb(up->rpt_cnt++) =
764 else if (*c == ETX)
765 up->rpt_status = TSIP_PARSED_FULL;
766 else {
767 /* error: start new report packet */
768 up->rpt_status = TSIP_PARSED_DLE_1;
769 up->rpt_buf[0] = *c;
771 break;
773 case TSIP_PARSED_FULL:
774 case TSIP_PARSED_EMPTY:
775 default:
776 if ( *c != DLE)
777 up->rpt_status = TSIP_PARSED_EMPTY;
778 else
779 up->rpt_status = TSIP_PARSED_DLE_1;
780 break;
783 c++;
785 if (up->rpt_status == TSIP_PARSED_DLE_1) {
786 up->rpt_cnt = 0;
787 if (pp->sloppyclockflag & CLK_FLAG2)
788 /* stamp it */
789 get_systime(&pp->lastrec);
791 else if (up->rpt_status == TSIP_PARSED_EMPTY)
792 up->rpt_cnt = 0;
794 else if (up->rpt_cnt > BMAX)
795 up->rpt_status =TSIP_PARSED_EMPTY;
797 if (up->rpt_status == TSIP_PARSED_FULL)
798 palisade_receive(peer);
800 } /* while chars in buffer */
805 * Trigger the Palisade's event input, which is driven off the RTS
807 * Take a system time stamp to match the GPS time stamp.
810 long
811 HW_poll (
812 #ifdef PALISADE
813 pp /* pointer to unit structure */
815 struct refclockproc * pp; /* pointer to unit structure */
816 #else
817 struct refclockproc * pp /* pointer to unit structure */
819 #endif
821 int x; /* state before & after RTS set */
822 struct palisade_unit *up;
824 up = (struct palisade_unit *) pp->unitptr;
826 /* read the current status, so we put things back right */
827 if (ioctl(pp->io.fd, TIOCMGET, &x) < 0) {
828 #ifdef DEBUG
829 if (debug)
830 printf("Palisade HW_poll: unit %d: GET %s\n", up->unit, strerror(errno));
831 #endif
832 msyslog(LOG_ERR, "Palisade(%d) HW_poll: ioctl(fd,GET): %m",
833 up->unit);
834 return -1;
837 x |= TIOCM_RTS; /* turn on RTS */
839 /* Edge trigger */
840 if (ioctl(pp->io.fd, TIOCMSET, &x) < 0) {
841 #ifdef DEBUG
842 if (debug)
843 printf("Palisade HW_poll: unit %d: SET \n", up->unit);
844 #endif
845 msyslog(LOG_ERR,
846 "Palisade(%d) HW_poll: ioctl(fd, SET, RTS_on): %m",
847 up->unit);
848 return -1;
851 x &= ~TIOCM_RTS; /* turn off RTS */
853 /* poll timestamp */
854 get_systime(&pp->lastrec);
856 if (ioctl(pp->io.fd, TIOCMSET, &x) == -1) {
857 #ifdef DEBUG
858 if (debug)
859 printf("Palisade HW_poll: unit %d: UNSET \n", up->unit);
860 #endif
861 msyslog(LOG_ERR,
862 "Palisade(%d) HW_poll: ioctl(fd, UNSET, RTS_off): %m",
863 up->unit);
864 return -1;
867 return 0;
870 #if 0 /* unused */
872 * this 'casts' a character array into a float
874 float
875 getfloat (
876 #ifdef PALISADE
879 u_char *bp;
880 #else
881 u_char *bp
883 #endif
885 float sval;
886 #ifdef WORDS_BIGENDIAN
887 ((char *) &sval)[0] = *bp++;
888 ((char *) &sval)[1] = *bp++;
889 ((char *) &sval)[2] = *bp++;
890 ((char *) &sval)[3] = *bp++;
891 #else
892 ((char *) &sval)[3] = *bp++;
893 ((char *) &sval)[2] = *bp++;
894 ((char *) &sval)[1] = *bp++;
895 ((char *) &sval)[0] = *bp;
896 #endif /* ! XNTP_BIG_ENDIAN */
897 return sval;
899 #endif
902 * this 'casts' a character array into a double
904 double
905 getdbl (
906 #ifdef PALISADE
909 u_char *bp;
910 #else
911 u_char *bp
913 #endif
915 double dval;
916 #ifdef WORDS_BIGENDIAN
917 ((char *) &dval)[0] = *bp++;
918 ((char *) &dval)[1] = *bp++;
919 ((char *) &dval)[2] = *bp++;
920 ((char *) &dval)[3] = *bp++;
921 ((char *) &dval)[4] = *bp++;
922 ((char *) &dval)[5] = *bp++;
923 ((char *) &dval)[6] = *bp++;
924 ((char *) &dval)[7] = *bp;
925 #else
926 ((char *) &dval)[7] = *bp++;
927 ((char *) &dval)[6] = *bp++;
928 ((char *) &dval)[5] = *bp++;
929 ((char *) &dval)[4] = *bp++;
930 ((char *) &dval)[3] = *bp++;
931 ((char *) &dval)[2] = *bp++;
932 ((char *) &dval)[1] = *bp++;
933 ((char *) &dval)[0] = *bp;
934 #endif /* ! XNTP_BIG_ENDIAN */
935 return dval;
939 * cast a 16 bit character array into a short (16 bit) int
941 short
942 getint (
943 #ifdef PALISADE
946 u_char *bp;
947 #else
948 u_char *bp
950 #endif
952 return (short) (bp[1] + (bp[0] << 8));
955 #else
956 int refclock_palisade_bs;
957 #endif /* REFCLOCK */