summaryrefslogtreecommitdiffstats
path: root/contrib/ntp/ntpd/refclock_palisade.c
diff options
context:
space:
mode:
authorroberto <roberto@FreeBSD.org>1999-12-09 13:01:21 +0000
committerroberto <roberto@FreeBSD.org>1999-12-09 13:01:21 +0000
commitef64b99e8412f2273dd2e8b3291c2f78ffc4667f (patch)
treefc0cfa1aab0ff6b228f511b410733ef4f35d1ead /contrib/ntp/ntpd/refclock_palisade.c
downloadFreeBSD-src-ef64b99e8412f2273dd2e8b3291c2f78ffc4667f.zip
FreeBSD-src-ef64b99e8412f2273dd2e8b3291c2f78ffc4667f.tar.gz
Virgin import of ntpd 4.0.98f
Diffstat (limited to 'contrib/ntp/ntpd/refclock_palisade.c')
-rw-r--r--contrib/ntp/ntpd/refclock_palisade.c880
1 files changed, 880 insertions, 0 deletions
diff --git a/contrib/ntp/ntpd/refclock_palisade.c b/contrib/ntp/ntpd/refclock_palisade.c
new file mode 100644
index 0000000..b9a0e2a
--- /dev/null
+++ b/contrib/ntp/ntpd/refclock_palisade.c
@@ -0,0 +1,880 @@
+/*
+ * This software was developed by the Software and Component Technologies
+ * group of Trimble Navigation, Ltd.
+ *
+ * Copyright (c) 1997, 1998, 1999 Trimble Navigation Ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Trimble Navigation, Ltd.
+ * 4. The name of Trimble Navigation Ltd. may not be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TRIMBLE NAVIGATION LTD. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL TRIMBLE NAVIGATION LTD. BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * refclock_palisade - clock driver for the Trimble Palisade GPS
+ * timing receiver
+ *
+ * For detailed information on this program, please refer to the html
+ * Refclock 29 page accompanying the NTP distribution.
+ *
+ * for questions / bugs / comments, contact:
+ * sven_dietrich@trimble.com
+ *
+ * Sven-Thorsten Dietrich
+ * 645 North Mary Avenue
+ * Post Office Box 3642
+ * Sunnyvale, CA 94088-3642
+ *
+ * Version 2.45; July 14, 1999
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#if defined(REFCLOCK) && (defined(PALISADE) || defined(CLOCK_PALISADE))
+
+#include "refclock_palisade.h"
+/* Table to get from month to day of the year */
+const int days_of_year [12] = {
+ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
+};
+
+#ifdef DEBUG
+const char * Tracking_Status[15][15] = {
+ { "Doing Fixes\0" }, { "Good 1SV\0" }, { "Approx. 1SV\0" },
+ {"Need Time\0" }, { "Need INIT\0" }, { "PDOP too High\0" },
+ { "Bad 1SV\0" }, { "0SV Usable\0" }, { "1SV Usable\0" },
+ { "2SV Usable\0" }, { "3SV Usable\0" }, { "No Integrity\0" },
+ { "Diff Corr\0" }, { "Overdet Clock\0" }, { "Invalid\0" } };
+#endif
+
+/*
+ * Transfer vector
+ */
+struct refclock refclock_palisade = {
+ palisade_start, /* start up driver */
+ palisade_shutdown, /* shut down driver */
+ palisade_poll, /* transmit poll message */
+ noentry, /* not used */
+ noentry, /* initialize driver (not used) */
+ noentry, /* not used */
+ NOFLAGS /* not used */
+};
+
+
+/*
+ * palisade_start - open the devices and initialize data for processing
+ */
+static int
+palisade_start (
+#ifdef PALISADE
+ unit, peer
+ )
+ int unit;
+ struct peer *peer;
+#else /* ANSI */
+ int unit,
+ struct peer *peer
+ )
+#endif
+{
+ struct palisade_unit *up;
+ struct refclockproc *pp;
+ int fd;
+ char gpsdev[20];
+
+ struct termios tio;
+#ifdef SYS_WINNT
+ (void) sprintf(gpsdev, "COM%d:", unit);
+#else
+ (void) sprintf(gpsdev, DEVICE, unit);
+#endif
+ /*
+ * Open serial port.
+ */
+#if defined PALISADE
+ fd = open(gpsdev, O_RDWR
+#ifdef O_NONBLOCK
+ | O_NONBLOCK
+#endif
+ );
+#else /* NTP 4.x */
+ fd = refclock_open(gpsdev, SPEED232, LDISC_RAW);
+#endif
+ if (fd <= 0) {
+#ifdef DEBUG
+ printf("Palisade(%d) start: open %s failed\n", unit, gpsdev);
+#endif
+ return 0;
+ }
+
+ msyslog(LOG_NOTICE, "Palisade(%d) fd: %d dev: %s", unit, fd,
+ gpsdev);
+
+#if defined PALISADE
+ tio.c_cflag = (CS8|CLOCAL|CREAD|PARENB|PARODD);
+ tio.c_iflag = (IGNBRK);
+ tio.c_oflag = (0);
+ tio.c_lflag = (0);
+
+ if (cfsetispeed(&tio, SPEED232) == -1) {
+ msyslog(LOG_ERR,"Palisade(%d) cfsetispeed(fd, &tio): %m",unit);
+#ifdef DEBUG
+ printf("Palisade(%d) cfsetispeed(fd, &tio)\n",unit);
+#endif
+ return 0;
+ }
+ if (cfsetospeed(&tio, SPEED232) == -1) {
+#ifdef DEBUG
+ printf("Palisade(%d) cfsetospeed(fd, &tio)\n",unit);
+#endif
+ msyslog(LOG_ERR,"Palisade(%d) cfsetospeed(fd, &tio): %m",unit);
+ return 0;
+ }
+#else /* NTP 4.x */
+ if (tcgetattr(fd, &tio) < 0) {
+ msyslog(LOG_ERR,
+ "Palisade(%d) tcgetattr(fd, &tio): %m",unit);
+#ifdef DEBUG
+ printf("Palisade(%d) tcgetattr(fd, &tio)\n",unit);
+#endif
+ return (0);
+ }
+
+ tio.c_cflag |= (PARENB|PARODD);
+ tio.c_iflag &= ~ICRNL;
+#endif /* NTP 4.x */
+
+ if (tcsetattr(fd, TCSANOW, &tio) == -1) {
+ msyslog(LOG_ERR, "Palisade(%d) tcsetattr(fd, &tio): %m",unit);
+#ifdef DEBUG
+ printf("Palisade(%d) tcsetattr(fd, &tio)\n",unit);
+#endif
+ return 0;
+ }
+
+ /*
+ * Allocate and initialize unit structure
+ */
+ up = (struct palisade_unit *) emalloc(sizeof(struct palisade_unit));
+
+ if (!(up)) {
+ msyslog(LOG_ERR, "Palisade(%d) emalloc: %m",unit);
+#ifdef DEBUG
+ printf("Palisade(%d) emalloc\n",unit);
+#endif
+ (void) close(fd);
+ return (0);
+ }
+
+ memset((char *)up, 0, sizeof(struct palisade_unit));
+
+ pp = peer->procptr;
+ pp->io.clock_recv = palisade_io;
+ pp->io.srcclock = (caddr_t)peer;
+ pp->io.datalen = 0;
+ pp->io.fd = fd;
+ if (!io_addclock(&pp->io)) {
+#ifdef DEBUG
+ printf("Palisade(%d) io_addclock\n",unit);
+#endif
+ (void) close(fd);
+ free(up);
+ return (0);
+ }
+
+ /*
+ * Initialize miscellaneous variables
+ */
+ pp->unitptr = (caddr_t)up;
+ pp->clockdesc = DESCRIPTION;
+
+ peer->precision = PRECISION;
+ peer->sstclktype = CTL_SST_TS_UHF;
+ peer->minpoll = TRMB_MINPOLL;
+ peer->maxpoll = TRMB_MAXPOLL;
+ memcpy((char *)&pp->refid, REFID, 4);
+
+ up->leap_status = 0;
+ up->unit = (short) unit;
+ up->rpt_status = TSIP_PARSED_EMPTY;
+ up->rpt_cnt = 0;
+
+ return 1;
+}
+
+
+/*
+ * palisade_shutdown - shut down the clock
+ */
+static void
+palisade_shutdown (
+#ifdef PALISADE
+ unit, peer
+ )
+ int unit;
+ struct peer *peer;
+#else /* ANSI */
+ int unit,
+ struct peer *peer
+ )
+#endif
+{
+ struct palisade_unit *up;
+ struct refclockproc *pp;
+ pp = peer->procptr;
+ up = (struct palisade_unit *)pp->unitptr;
+ io_closeclock(&pp->io);
+ free(up);
+}
+
+
+
+/*
+ * unpack_date - get day and year from date
+ */
+int
+day_of_year (
+#ifdef PALISADE
+ dt
+ )
+ char * dt;
+#else
+ char * dt
+ )
+#endif
+{
+ int day, mon, year;
+
+ mon = dt[1];
+ /* Check month is inside array bounds */
+ if ((mon < 1) || (mon > 12))
+ return -1;
+
+ day = dt[0] + days_of_year[mon - 1];
+ year = getint((u_char *) (dt + 2));
+
+ if ( !(year % 4) && ((year % 100) ||
+ (!(year % 100) && !(year%400)))
+ &&(mon > 2))
+ day ++; /* leap year and March or later */
+
+ return day;
+}
+
+
+/*
+ * TSIP_decode - decode the TSIP data packets
+ */
+int
+TSIP_decode (
+#ifdef PALISADE
+ peer
+ )
+ struct peer *peer;
+#else
+ struct peer *peer
+ )
+#endif
+{
+ int st;
+ long secint;
+ double secs;
+ double secfrac;
+ unsigned short event = 0;
+
+ struct palisade_unit *up;
+ struct refclockproc *pp;
+
+ pp = peer->procptr;
+ up = (struct palisade_unit *)pp->unitptr;
+
+ /*
+ * Check the time packet, decode its contents.
+ * If the timecode has invalid length or is not in
+ * proper format, declare bad format and exit.
+ */
+
+ if ((up->rpt_buf[0] == (char) 0x41) ||
+ (up->rpt_buf[0] == (char) 0x46) ||
+ (up->rpt_buf[0] == (char) 0x54) ||
+ (up->rpt_buf[0] == (char) 0x4B) ||
+ (up->rpt_buf[0] == (char) 0x6D)) {
+
+ /* standard time packet - GPS time and GPS week number */
+#ifdef DEBUG
+ printf("Palisade Port B packets detected. Connect to Port A\n");
+#endif
+
+ return 0;
+ }
+
+ if (up->rpt_buf[0] == (char) 0x8f) {
+ /*
+ * Superpackets
+ */
+ event = (unsigned short) (getint((u_char *) &mb(1)) & 0xffff);
+ if (!((pp->sloppyclockflag & CLK_FLAG2) || event))
+ /* Ignore Packet */
+ return 0;
+
+ switch (mb(0) & 0xff) {
+ int GPS_UTC_Offset;
+ case PACKET_8F0B:
+
+ if (up->polled <= 0)
+ return 0;
+
+ if (up->rpt_cnt != LENCODE_8F0B) /* check length */
+ break;
+
+#ifdef DEBUG
+if (debug > 1) {
+ int ts;
+ double lat, lon, alt;
+ lat = getdbl((u_char *) &mb(42)) * R2D;
+ lon = getdbl((u_char *) &mb(50)) * R2D;
+ alt = getdbl((u_char *) &mb(58));
+
+ printf("TSIP_decode: unit %d: Latitude: %03.4f Longitude: %03.4f Alt: %05.2f m\n",
+ up->unit, lat,lon,alt);
+ printf("TSIP_decode: unit %d: Sats:", up->unit);
+ for (st = 66, ts = 0; st <= 73; st++) if (mb(st)) {
+ if (mb(st) > 0) ts++;
+ printf(" %02d", mb(st));
+ }
+ printf(" : Tracking %d\n", ts);
+ }
+#endif
+
+ GPS_UTC_Offset = getint((u_char *) &mb(16));
+ if (GPS_UTC_Offset == 0) { /* Check UTC offset */
+#ifdef DEBUG
+ printf("TSIP_decode: UTC Offset Unknown\n");
+#endif
+ break;
+ }
+
+ secs = getdbl((u_char *) &mb(3));
+ secint = (long) secs;
+ secfrac = secs - secint; /* 0.0 <= secfrac < 1.0 */
+
+ pp->usec = (long) (secfrac * 1000000);
+
+ secint %= 86400; /* Only care about today */
+ pp->hour = secint / 3600;
+ secint %= 3600;
+ pp->minute = secint / 60;
+ secint %= 60;
+ pp->second = secint % 60;
+
+ if ((pp->day = day_of_year(&mb(11))) < 0) break;
+
+ pp->year = getint((u_char *) &mb(13));
+
+#ifdef DEBUG
+ if (debug > 1)
+ printf("TSIP_decode: unit %d: %02X #%d %02d:%02d:%02d.%06ld %02d/%02d/%04d UTC %02d\n",
+ up->unit, mb(0) & 0xff, event, pp->hour, pp->minute,
+ pp->second, pp->usec, mb(12), mb(11), pp->year, GPS_UTC_Offset);
+#endif
+ /* Only use this packet when no
+ * 8F-AD's are being received
+ */
+
+ if (up->leap_status) {
+ up->leap_status = 0;
+ return 0;
+ }
+
+ return 2;
+ break;
+
+ case PACKET_NTP:
+ /* Palisade-NTP Packet */
+
+ if (up->rpt_cnt != LENCODE_NTP) /* check length */
+ break;
+
+ up->leap_status = mb(19);
+
+ if (up->polled <= 0)
+ return 0;
+
+ /* Check Tracking Status */
+ st = mb(18);
+ if (st < 0 || st > 14) st = 14;
+ if ((st >= 2 && st <= 7) || st == 11 || st == 12) {
+#ifdef DEBUG
+ printf("TSIP_decode: Not Tracking Sats : %s\n",
+ *Tracking_Status[st]);
+#endif
+ refclock_report(peer, CEVNT_BADTIME);
+ up->polled = -1;
+ return 0;
+ break;
+ }
+
+ if (up->leap_status & PALISADE_LEAP_PENDING) {
+ if (up->leap_status & PALISADE_UTC_TIME)
+ pp->leap = LEAP_ADDSECOND;
+ else
+ pp->leap = LEAP_DELSECOND;
+ }
+ else if (up->leap_status)
+ pp->leap = LEAP_NOWARNING;
+
+ else { /* UTC flag is not set:
+ * Receiver may have been reset, and lost
+ * its UTC almanac data */
+ pp->leap = LEAP_NOTINSYNC;
+#ifdef DEBUG
+ printf("TSIP_decode: UTC Almanac unavailable: %d\n",
+ mb(19));
+#endif
+ refclock_report(peer, CEVNT_BADTIME);
+ up->polled = -1;
+ return 0;
+ }
+
+ pp->usec = (long) (getdbl((u_char *) &mb(3)) * 1000000);
+
+ if ((pp->day = day_of_year(&mb(14))) < 0)
+ break;
+ pp->year = getint((u_char *) &mb(16));
+ pp->hour = mb(11);
+ pp->minute = mb(12);
+ pp->second = mb(13);
+
+#ifdef DEBUG
+ if (debug > 1)
+printf("TSIP_decode: unit %d: %02X #%d %02d:%02d:%02d.%06ld %02d/%02d/%04d UTC %02x %s\n",
+ up->unit, mb(0) & 0xff, event, pp->hour, pp->minute,
+ pp->second, pp->usec, mb(15), mb(14), pp->year,
+ mb(19), *Tracking_Status[st]);
+#endif
+ return 1;
+ break;
+
+ default:
+ /* Ignore Packet */
+ return 0;
+ } /* switch */
+ }/* if 8F packets */
+
+ refclock_report(peer, CEVNT_BADREPLY);
+ up->polled = -1;
+#ifdef DEBUG
+ printf("TSIP_decode: unit %d: bad packet %02x-%02x event %d len %d\n",
+ up->unit, up->rpt_buf[0] & 0xff, mb(0) & 0xff,
+ event, up->rpt_cnt);
+#endif
+ return 0;
+}
+
+/*
+ * palisade__receive - receive data from the serial interface
+ */
+
+static void
+palisade_receive (
+#ifdef PALISADE
+ peer
+ )
+ struct peer * peer;
+#else /* ANSI */
+ struct peer * peer
+ )
+#endif
+{
+ struct palisade_unit *up;
+ struct refclockproc *pp;
+
+ /*
+ * Initialize pointers and read the timecode and timestamp.
+ */
+ pp = peer->procptr;
+ up = (struct palisade_unit *)pp->unitptr;
+
+ if (! TSIP_decode(peer)) return;
+
+ if (up->polled <= 0)
+ return; /* no poll pending, already received or timeout */
+
+ up->polled = 0; /* Poll reply received */
+ pp->lencode = 0; /* clear time code */
+#ifdef DEBUG
+ if (debug)
+ printf(
+ "palisade_receive: unit %d: %4d %03d %02d:%02d:%02d.%06ld\n",
+ up->unit, pp->year, pp->day, pp->hour, pp->minute,
+ pp->second, pp->usec);
+#endif
+
+ /*
+ * Process the sample
+ * Generate timecode: YYYY DoY HH:MM:SS.microsec
+ * report and process
+ */
+
+ (void) sprintf(pp->a_lastcode,"%4d %03d %02d:%02d:%02d.%06ld",
+ pp->year,pp->day,pp->hour,pp->minute, pp->second,pp->usec);
+ pp->lencode = 24;
+
+#ifdef PALISADE
+ pp->lasttime = current_time;
+#endif
+ if (!refclock_process(pp
+#ifdef PALISADE
+ , PALISADE_SAMPLES, PALISADE_SAMPLES * 3 / 5
+#endif
+ )) {
+ refclock_report(peer, CEVNT_BADTIME);
+
+#ifdef DEBUG
+ printf("palisade_receive: unit %d: refclock_process failed!\n",
+ up->unit);
+#endif
+ return;
+ }
+
+ record_clock_stats(&peer->srcadr, pp->a_lastcode);
+
+#ifdef DEBUG
+ if (debug)
+ printf("palisade_receive: unit %d: %s\n",
+ up->unit, prettydate(&pp->lastrec));
+#endif
+
+ refclock_receive(peer
+#ifdef PALISADE
+ , &pp->offset, 0, pp->dispersion,
+ &pp->lastrec, &pp->lastrec, pp->leap
+#endif
+ );
+}
+
+
+/*
+ * palisade_poll - called by the transmit procedure
+ *
+ */
+static void
+palisade_poll (
+#ifdef PALISADE
+ unit, peer
+ )
+ int unit;
+ struct peer *peer;
+#else
+ int unit,
+ struct peer *peer
+ )
+#endif
+{
+ struct palisade_unit *up;
+ struct refclockproc *pp;
+
+ pp = peer->procptr;
+ up = (struct palisade_unit *)pp->unitptr;
+
+ pp->polls++;
+ if (up->polled > 0) /* last reply never arrived or error */
+ refclock_report(peer, CEVNT_TIMEOUT);
+
+ up->polled = 2; /* synchronous packet + 1 event */
+
+#ifdef DEBUG
+ if (debug)
+ printf("palisade_poll: unit %d: polling %s\n", unit,
+ (pp->sloppyclockflag & CLK_FLAG2) ?
+ "synchronous packet" : "event");
+#endif
+
+ if (pp->sloppyclockflag & CLK_FLAG2)
+ return; /* using synchronous packet input */
+
+ if (HW_poll(pp) < 0)
+ refclock_report(peer, CEVNT_FAULT);
+}
+
+
+static void
+palisade_io (
+#ifdef PALISADE
+ rbufp
+ )
+ struct recvbuf *rbufp;
+#else /* ANSI */
+ struct recvbuf *rbufp
+ )
+#endif
+{
+ /*
+ * Initialize pointers and read the timecode and timestamp.
+ */
+ struct palisade_unit *up;
+ struct refclockproc *pp;
+ struct peer *peer;
+
+ char * c, * d;
+
+ peer = (struct peer *)rbufp->recv_srcclock;
+ pp = peer->procptr;
+ up = (struct palisade_unit *)pp->unitptr;
+
+ c = (char *) &rbufp->recv_space;
+ d = c + rbufp->recv_length;
+
+ while (c != d) {
+
+ /* Build time packet */
+ switch (up->rpt_status) {
+
+ case TSIP_PARSED_DLE_1:
+ switch (*c)
+ {
+ case 0:
+ case DLE:
+ case ETX:
+ up->rpt_status = TSIP_PARSED_EMPTY;
+ break;
+
+ default:
+ up->rpt_status = TSIP_PARSED_DATA;
+ /* save packet ID */
+ up->rpt_buf[0] = *c;
+ break;
+ }
+ break;
+
+ case TSIP_PARSED_DATA:
+ if (*c == DLE)
+ up->rpt_status = TSIP_PARSED_DLE_2;
+ else
+ mb(up->rpt_cnt++) = *c;
+ break;
+
+ case TSIP_PARSED_DLE_2:
+ if (*c == DLE) {
+ up->rpt_status = TSIP_PARSED_DATA;
+ mb(up->rpt_cnt++) =
+ *c;
+ }
+ else if (*c == ETX)
+ up->rpt_status = TSIP_PARSED_FULL;
+ else {
+ /* error: start new report packet */
+ up->rpt_status = TSIP_PARSED_DLE_1;
+ up->rpt_buf[0] = *c;
+ }
+ break;
+
+ case TSIP_PARSED_FULL:
+ case TSIP_PARSED_EMPTY:
+ default:
+ if ( *c != DLE)
+ up->rpt_status = TSIP_PARSED_EMPTY;
+ else
+ up->rpt_status = TSIP_PARSED_DLE_1;
+ break;
+ }
+
+ c++;
+
+ if (up->rpt_status == TSIP_PARSED_DLE_1) {
+ up->rpt_cnt = 0;
+ if (pp->sloppyclockflag & CLK_FLAG2)
+ /* stamp it */
+ get_systime(&pp->lastrec);
+ }
+ else if (up->rpt_status == TSIP_PARSED_EMPTY)
+ up->rpt_cnt = 0;
+
+ else if (up->rpt_cnt > BMAX)
+ up->rpt_status =TSIP_PARSED_EMPTY;
+
+ if (up->rpt_status == TSIP_PARSED_FULL)
+ palisade_receive(peer);
+
+ } /* while chars in buffer */
+}
+
+
+/*
+ * Trigger the Palisade's event input, which is driven off the RTS
+ *
+ * Take a system time stamp to match the GPS time stamp.
+ *
+ */
+long
+HW_poll (
+#ifdef PALISADE
+ pp /* pointer to unit structure */
+ )
+ struct refclockproc * pp; /* pointer to unit structure */
+#else
+ struct refclockproc * pp /* pointer to unit structure */
+ )
+#endif
+{
+ int x; /* state before & after RTS set */
+ struct palisade_unit *up;
+
+ up = (struct palisade_unit *) pp->unitptr;
+
+ /* read the current status, so we put things back right */
+ if (ioctl(pp->io.fd, TIOCMGET, &x) < 0) {
+#ifdef DEBUG
+ if (debug)
+ printf("Palisade HW_poll: unit %d: GET %s\n", up->unit, strerror(errno));
+#endif
+ msyslog(LOG_ERR, "Palisade(%d) HW_poll: ioctl(fd,GET): %m",
+ up->unit);
+ return -1;
+ }
+
+ x |= TIOCM_RTS; /* turn on RTS */
+
+ /* Edge trigger */
+ if (ioctl(pp->io.fd, TIOCMSET, &x) < 0) {
+#ifdef DEBUG
+ if (debug)
+ printf("Palisade HW_poll: unit %d: SET \n", up->unit);
+#endif
+ msyslog(LOG_ERR,
+ "Palisade(%d) HW_poll: ioctl(fd, SET, RTS_on): %m",
+ up->unit);
+ return -1;
+ }
+
+ x &= ~TIOCM_RTS; /* turn off RTS */
+
+ /* poll timestamp */
+ get_systime(&pp->lastrec);
+
+ if (ioctl(pp->io.fd, TIOCMSET, &x) == -1) {
+#ifdef DEBUG
+ if (debug)
+ printf("Palisade HW_poll: unit %d: UNSET \n", up->unit);
+#endif
+ msyslog(LOG_ERR,
+ "Palisade(%d) HW_poll: ioctl(fd, UNSET, RTS_off): %m",
+ up->unit);
+ return -1;
+ }
+
+ return 0;
+}
+
+#if 0 /* unused */
+/*
+ * this 'casts' a character array into a float
+ */
+float
+getfloat (
+#ifdef PALISADE
+ bp
+ )
+ u_char *bp;
+#else
+ u_char *bp
+ )
+#endif
+{
+ float sval;
+#ifdef WORDS_BIGENDIAN
+ ((char *) &sval)[0] = *bp++;
+ ((char *) &sval)[1] = *bp++;
+ ((char *) &sval)[2] = *bp++;
+ ((char *) &sval)[3] = *bp++;
+#else
+ ((char *) &sval)[3] = *bp++;
+ ((char *) &sval)[2] = *bp++;
+ ((char *) &sval)[1] = *bp++;
+ ((char *) &sval)[0] = *bp;
+#endif /* ! XNTP_BIG_ENDIAN */
+ return sval;
+}
+#endif
+
+/*
+ * this 'casts' a character array into a double
+ */
+double
+getdbl (
+#ifdef PALISADE
+ bp
+ )
+ u_char *bp;
+#else
+ u_char *bp
+ )
+#endif
+{
+ double dval;
+#ifdef WORDS_BIGENDIAN
+ ((char *) &dval)[0] = *bp++;
+ ((char *) &dval)[1] = *bp++;
+ ((char *) &dval)[2] = *bp++;
+ ((char *) &dval)[3] = *bp++;
+ ((char *) &dval)[4] = *bp++;
+ ((char *) &dval)[5] = *bp++;
+ ((char *) &dval)[6] = *bp++;
+ ((char *) &dval)[7] = *bp;
+#else
+ ((char *) &dval)[7] = *bp++;
+ ((char *) &dval)[6] = *bp++;
+ ((char *) &dval)[5] = *bp++;
+ ((char *) &dval)[4] = *bp++;
+ ((char *) &dval)[3] = *bp++;
+ ((char *) &dval)[2] = *bp++;
+ ((char *) &dval)[1] = *bp++;
+ ((char *) &dval)[0] = *bp;
+#endif /* ! XNTP_BIG_ENDIAN */
+ return dval;
+}
+
+/*
+ * cast a 16 bit character array into a short (16 bit) int
+ */
+short
+getint (
+#ifdef PALISADE
+ bp
+ )
+ u_char *bp;
+#else
+ u_char *bp
+ )
+#endif
+{
+return (short) (bp[1] + (bp[0] << 8));
+}
+
+#endif /* REFCLOCK */
OpenPOWER on IntegriCloud