diff options
author | glebius <glebius@FreeBSD.org> | 2015-10-26 11:37:31 +0000 |
---|---|---|
committer | glebius <glebius@FreeBSD.org> | 2015-10-26 11:37:31 +0000 |
commit | 81511473d32294dc562d10f7b3e97630ccf0b64f (patch) | |
tree | 83f2b5fa5bca87e28ea638c9459aebb211698059 /contrib/ntp/ntpd/refclock_palisade.c | |
parent | a5a01b895b5c5a5a2f92fb611161c7c0f840a76a (diff) | |
download | FreeBSD-src-81511473d32294dc562d10f7b3e97630ccf0b64f.zip FreeBSD-src-81511473d32294dc562d10f7b3e97630ccf0b64f.tar.gz |
Upgrade NTP to 4.2.8p4.
Security: FreeBSD-SA-15:25.ntp
Security: CVE-2015-7871
Security: CVE-2015-7855
Security: CVE-2015-7854
Security: CVE-2015-7853
Security: CVE-2015-7852
Security: CVE-2015-7851
Security: CVE-2015-7850
Security: CVE-2015-7849
Security: CVE-2015-7848
Security: CVE-2015-7701
Security: CVE-2015-7703
Security: CVE-2015-7704, CVE-2015-7705
Security: CVE-2015-7691, CVE-2015-7692, CVE-2015-7702
Approved by: so
Diffstat (limited to 'contrib/ntp/ntpd/refclock_palisade.c')
-rw-r--r-- | contrib/ntp/ntpd/refclock_palisade.c | 1078 |
1 files changed, 691 insertions, 387 deletions
diff --git a/contrib/ntp/ntpd/refclock_palisade.c b/contrib/ntp/ntpd/refclock_palisade.c index adb4659..921c815 100644 --- a/contrib/ntp/ntpd/refclock_palisade.c +++ b/contrib/ntp/ntpd/refclock_palisade.c @@ -50,13 +50,28 @@ * * Version 2.45; July 14, 1999 * + * + * + * 31/03/06: Added support for Thunderbolt GPS Disciplined Clock. + * Contact: Fernando Pablo Hauscarriaga + * E-mail: fernandoph@iar.unlp.edu.ar + * Home page: www.iar.unlp.edu.ar/~fernandoph + * Instituto Argentino de Radioastronomia + * www.iar.unlp.edu.ar + * + * 14/01/07: Conditinal compilation for Thunderbolt support no longer needed + * now we use mode 2 for decode thunderbolt packets. + * Fernando P. Hauscarriaga + * + * 30/08/09: Added support for Trimble Acutime Gold Receiver. + * Fernando P. Hauscarriaga (fernandoph@iar.unlp.edu.ar) */ #ifdef HAVE_CONFIG_H -#include "config.h" +# include "config.h" #endif -#if defined(REFCLOCK) && (defined(PALISADE) || defined(CLOCK_PALISADE)) +#if defined(REFCLOCK) && defined(CLOCK_PALISADE) #ifdef SYS_WINNT extern int async_write(int, const void *, unsigned int); @@ -72,11 +87,11 @@ const int days_of_year [12] = { #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" } }; + { "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 /* @@ -92,7 +107,7 @@ struct refclock refclock_palisade = { NOFLAGS /* not used */ }; -int day_of_year P((char *dt)); +int day_of_year (char *dt); /* Extract the clock type from the mode setting */ #define CLK_TYPE(x) ((int)(((x)->ttl) & 0x7F)) @@ -100,49 +115,170 @@ int day_of_year P((char *dt)); /* Supported clock types */ #define CLK_TRIMBLE 0 /* Trimble Palisade */ #define CLK_PRAECIS 1 /* Endrun Technologies Praecis */ +#define CLK_THUNDERBOLT 2 /* Trimble Thunderbolt GPS Receiver */ +#define CLK_ACUTIME 3 /* Trimble Acutime Gold */ +#define CLK_ACUTIMEB 4 /* Trimble Actutime Gold Port B */ int praecis_msg; static void praecis_parse(struct recvbuf *rbufp, struct peer *peer); +/* These routines are for sending packets to the Thunderbolt receiver + * They are taken from Markus Prosch + */ + +#ifdef PALISADE_SENDCMD_RESURRECTED +/* + * sendcmd - Build data packet for sending + */ +static void +sendcmd ( + struct packettx *buffer, + int c + ) +{ + *buffer->data = DLE; + *(buffer->data + 1) = (unsigned char)c; + buffer->size = 2; +} +#endif /* PALISADE_SENDCMD_RESURRECTED */ + +/* + * sendsupercmd - Build super data packet for sending + */ +static void +sendsupercmd ( + struct packettx *buffer, + int c1, + int c2 + ) +{ + *buffer->data = DLE; + *(buffer->data + 1) = (unsigned char)c1; + *(buffer->data + 2) = (unsigned char)c2; + buffer->size = 3; +} + +/* + * sendbyte - + */ +static void +sendbyte ( + struct packettx *buffer, + int b + ) +{ + if (b == DLE) + *(buffer->data+buffer->size++) = DLE; + *(buffer->data+buffer->size++) = (unsigned char)b; +} + +/* + * sendint - + */ +static void +sendint ( + struct packettx *buffer, + int a + ) +{ + sendbyte(buffer, (unsigned char)((a>>8) & 0xff)); + sendbyte(buffer, (unsigned char)(a & 0xff)); +} + +/* + * sendetx - Send packet or super packet to the device + */ +static int +sendetx ( + struct packettx *buffer, + int fd + ) +{ + int result; + + *(buffer->data+buffer->size++) = DLE; + *(buffer->data+buffer->size++) = ETX; + result = write(fd, buffer->data, (unsigned long)buffer->size); + + if (result != -1) + return (result); + else + return (-1); +} + +/* + * init_thunderbolt - Prepares Thunderbolt receiver to be used with + * NTP (also taken from Markus Prosch). + */ +static void +init_thunderbolt ( + int fd + ) +{ + struct packettx tx; + + tx.size = 0; + tx.data = (u_char *) emalloc(100); + + /* set UTC time */ + sendsupercmd (&tx, 0x8E, 0xA2); + sendbyte (&tx, 0x3); + sendetx (&tx, fd); + + /* activate packets 0x8F-AB and 0x8F-AC */ + sendsupercmd (&tx, 0x8F, 0xA5); + sendint (&tx, 0x5); + sendetx (&tx, fd); + + free(tx.data); +} + +/* + * init_acutime - Prepares Acutime Receiver to be used with NTP + */ +static void +init_acutime ( + int fd + ) +{ + /* Disable all outputs, Enable Event-Polling on PortA so + we can ask for time packets */ + struct packettx tx; + + tx.size = 0; + tx.data = (u_char *) emalloc(100); + + sendsupercmd(&tx, 0x8E, 0xA5); + sendbyte(&tx, 0x02); + sendbyte(&tx, 0x00); + sendbyte(&tx, 0x00); + sendbyte(&tx, 0x00); + sendetx(&tx, fd); + + free(tx.data); +} + /* * 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 + + snprintf(gpsdev, sizeof(gpsdev), DEVICE, unit); + /* * 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); @@ -153,87 +289,67 @@ palisade_start ( 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, + 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); + printf("Palisade(%d) tcgetattr(fd, &tio)\n",unit); #endif - return (0); - } - - tio.c_cflag |= (PARENB|PARODD); - tio.c_iflag &= ~ICRNL; -#endif /* NTP 4.x */ + close(fd); + return (0); + } - 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; - } + tio.c_cflag |= (PARENB|PARODD); + tio.c_iflag &= ~ICRNL; /* * 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)); + up = emalloc_zero(sizeof(*up)); up->type = CLK_TYPE(peer); switch (up->type) { - case CLK_TRIMBLE: - /* Normal mode, do nothing */ - break; - case CLK_PRAECIS: - msyslog(LOG_NOTICE, "Palisade(%d) Praecis mode enabled\n",unit); - break; - default: - msyslog(LOG_NOTICE, "Palisade(%d) mode unknown\n",unit); - break; + case CLK_TRIMBLE: + /* Normal mode, do nothing */ + break; + case CLK_PRAECIS: + msyslog(LOG_NOTICE, "Palisade(%d) Praecis mode enabled" + ,unit); + break; + case CLK_THUNDERBOLT: + msyslog(LOG_NOTICE, "Palisade(%d) Thunderbolt mode enabled" + ,unit); + tio.c_cflag = (CS8|CLOCAL|CREAD); + break; + case CLK_ACUTIME: + msyslog(LOG_NOTICE, "Palisade(%d) Acutime Gold mode enabled" + ,unit); + break; + default: + msyslog(LOG_NOTICE, "Palisade(%d) mode unknown",unit); + break; + } + 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 + close(fd); + free(up); + return 0; } pp = peer->procptr; pp->io.clock_recv = palisade_io; - pp->io.srcclock = (caddr_t)peer; + pp->io.srcclock = peer; pp->io.datalen = 0; pp->io.fd = fd; if (!io_addclock(&pp->io)) { #ifdef DEBUG - printf("Palisade(%d) io_addclock\n",unit); + printf("Palisade(%d) io_addclock\n",unit); #endif - (void) close(fd); + close(fd); + pp->io.fd = -1; free(up); return (0); } @@ -241,7 +357,7 @@ palisade_start ( /* * Initialize miscellaneous variables */ - pp->unitptr = (caddr_t)up; + pp->unitptr = up; pp->clockdesc = DESCRIPTION; peer->precision = PRECISION; @@ -253,7 +369,12 @@ palisade_start ( up->leap_status = 0; up->unit = (short) unit; up->rpt_status = TSIP_PARSED_EMPTY; - up->rpt_cnt = 0; + up->rpt_cnt = 0; + + if (up->type == CLK_THUNDERBOLT) + init_thunderbolt(fd); + if (up->type == CLK_ACUTIME) + init_acutime(fd); return 1; } @@ -264,23 +385,18 @@ palisade_start ( */ 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); + up = pp->unitptr; + if (-1 != pp->io.fd) + io_closeclock(&pp->io); + if (NULL != up) + free(up); } @@ -290,29 +406,23 @@ palisade_shutdown ( */ 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)) + /* 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 */ + (!(year % 100) && !(year%400))) + &&(mon > 2)) + day ++; /* leap year and March or later */ return day; } @@ -323,14 +433,8 @@ day_of_year ( */ int TSIP_decode ( -#ifdef PALISADE - peer - ) - struct peer *peer; -#else struct peer *peer ) -#endif { int st; long secint; @@ -342,7 +446,7 @@ TSIP_decode ( struct refclockproc *pp; pp = peer->procptr; - up = (struct palisade_unit *)pp->unitptr; + up = pp->unitptr; /* * Check the time packet, decode its contents. @@ -350,182 +454,436 @@ TSIP_decode ( * 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)) { + if ((up->type != CLK_THUNDERBOLT) & (up->type != CLK_ACUTIME)){ + 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 */ + /* 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; + return 0; + } } /* * We cast both to u_char to as 0x8f uses the sign bit on a char */ if ((u_char) up->rpt_buf[0] == (u_char) 0x8f) { - /* - * Superpackets - */ - event = (unsigned short) (getint((u_char *) &mb(1)) & 0xffff); - if (!((pp->sloppyclockflag & CLK_FLAG2) || event)) - /* Ignore Packet */ + /* + * 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: + switch (mb(0) & 0xff) { + int GPS_UTC_Offset; + long tow; - if (up->polled <= 0) - return 0; + case PACKET_8F0B: - if (up->rpt_cnt != LENCODE_8F0B) /* check length */ - break; + 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); - } + 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 */ + 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"); + printf("TSIP_decode: UTC Offset Unknown\n"); #endif - break; - } + break; + } - secs = getdbl((u_char *) &mb(3)); - secint = (long) secs; - secfrac = secs - secint; /* 0.0 <= secfrac < 1.0 */ + secs = getdbl((u_char *) &mb(3)); + secint = (long) secs; + secfrac = secs - secint; /* 0.0 <= secfrac < 1.0 */ - pp->nsec = (long) (secfrac * 1000000000); + pp->nsec = (long) (secfrac * 1000000000); - secint %= 86400; /* Only care about today */ - pp->hour = secint / 3600; - secint %= 3600; - pp->minute = secint / 60; - secint %= 60; - pp->second = secint % 60; + 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; + if ((pp->day = day_of_year(&mb(11))) < 0) break; - pp->year = getint((u_char *) &mb(13)); + 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->nsec, mb(12), mb(11), pp->year, GPS_UTC_Offset); + if (debug > 1) + printf("TSIP_decode: unit %d: %02X #%d %02d:%02d:%02d.%09ld %02d/%02d/%04d UTC %02d\n", + up->unit, mb(0) & 0xff, event, pp->hour, pp->minute, + pp->second, pp->nsec, mb(12), mb(11), pp->year, GPS_UTC_Offset); #endif - /* Only use this packet when no - * 8F-AD's are being received - */ + /* Only use this packet when no + * 8F-AD's are being received + */ - if (up->leap_status) { - up->leap_status = 0; - return 0; - } + if (up->leap_status) { + up->leap_status = 0; + return 0; + } - return 2; - break; + return 2; + break; - case PACKET_NTP: - /* Palisade-NTP Packet */ + case PACKET_NTP: + /* Palisade-NTP Packet */ - if (up->rpt_cnt != LENCODE_NTP) /* check length */ - break; + if (up->rpt_cnt != LENCODE_NTP) /* check length */ + break; - up->leap_status = mb(19); + up->leap_status = mb(19); - if (up->polled <= 0) - return 0; + 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) { + /* 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]); + printf("TSIP_decode: Not Tracking Sats : %s\n", + *Tracking_Status[st]); #endif - refclock_report(peer, CEVNT_BADTIME); - up->polled = -1; - return 0; - break; - } + 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; + up->month = mb(15); + if ( (up->leap_status & PALISADE_LEAP_PENDING) && + /* Avoid early announce: https://bugs.ntp.org/2773 */ + (6 == up->month || 12 == up->month) ) { + 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; + 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)); + printf("TSIP_decode: UTC Almanac unavailable: %d\n", + mb(19)); #endif - refclock_report(peer, CEVNT_BADTIME); - up->polled = -1; + refclock_report(peer, CEVNT_BADTIME); + up->polled = -1; + return 0; + } + + pp->nsec = (long) (getdbl((u_char *) &mb(3)) + * 1000000000); + + 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); + up->month = mb(14); /* Save for LEAP check */ + +#ifdef DEBUG + if (debug > 1) + printf("TSIP_decode: unit %d: %02X #%d %02d:%02d:%02d.%09ld %02d/%02d/%04d UTC %02x %s\n", + up->unit, mb(0) & 0xff, event, pp->hour, pp->minute, + pp->second, pp->nsec, mb(15), mb(14), pp->year, + mb(19), *Tracking_Status[st]); +#endif + return 1; + break; + + case PACKET_8FAC: + if (up->polled <= 0) + return 0; + + if (up->rpt_cnt != LENCODE_8FAC)/* check length */ + break; + +#ifdef DEBUG + if (debug > 1) { + double lat, lon, alt; + lat = getdbl((u_char *) &mb(36)) * R2D; + lon = getdbl((u_char *) &mb(44)) * R2D; + alt = getdbl((u_char *) &mb(52)); + + 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\n", up->unit); + } +#endif + if ( (getint((u_char *) &mb(10)) & 0x80) && + /* Avoid early announce: https://bugs.ntp.org/2773 */ + (6 == up->month || 12 == up->month) ) + pp->leap = LEAP_ADDSECOND; /* we ASSUME addsecond */ + else + pp->leap = LEAP_NOWARNING; + +#ifdef DEBUG + if (debug > 1) + printf("TSIP_decode: unit %d: 0x%02x leap %d\n", + up->unit, mb(0) & 0xff, pp->leap); + if (debug > 1) { + printf("Receiver MODE: 0x%02X\n", (u_char)mb(1)); + if (mb(1) == 0x00) + printf(" AUTOMATIC\n"); + if (mb(1) == 0x01) + printf(" SINGLE SATELLITE\n"); + if (mb(1) == 0x03) + printf(" HORIZONTAL(2D)\n"); + if (mb(1) == 0x04) + printf(" FULL POSITION(3D)\n"); + if (mb(1) == 0x05) + printf(" DGPR REFERENCE\n"); + if (mb(1) == 0x06) + printf(" CLOCK HOLD(2D)\n"); + if (mb(1) == 0x07) + printf(" OVERDETERMINED CLOCK\n"); + + printf("\n** Disciplining MODE 0x%02X:\n", (u_char)mb(2)); + if (mb(2) == 0x00) + printf(" NORMAL\n"); + if (mb(2) == 0x01) + printf(" POWER-UP\n"); + if (mb(2) == 0x02) + printf(" AUTO HOLDOVER\n"); + if (mb(2) == 0x03) + printf(" MANUAL HOLDOVER\n"); + if (mb(2) == 0x04) + printf(" RECOVERY\n"); + if (mb(2) == 0x06) + printf(" DISCIPLINING DISABLED\n"); + } +#endif return 0; - } + break; + + case PACKET_8FAB: + /* Thunderbolt Primary Timing Packet */ + + if (up->rpt_cnt != LENCODE_8FAB) /* check length */ + break; + + if (up->polled <= 0) + return 0; + + GPS_UTC_Offset = getint((u_char *) &mb(7)); + + if (GPS_UTC_Offset == 0){ /* Check UTC Offset */ +#ifdef DEBUG + printf("TSIP_decode: UTC Offset Unknown\n"); +#endif + break; + } - pp->nsec = (long) (getdbl((u_char *) &mb(3)) * 1000000000); - if ((pp->day = day_of_year(&mb(14))) < 0) + if ((mb(9) & 0x1d) == 0x0) { + /* if we know the GPS time and the UTC offset, + we expect UTC timing information !!! */ + + pp->leap = LEAP_NOTINSYNC; + refclock_report(peer, CEVNT_BADTIME); + up->polled = -1; + return 0; + } + + pp->nsec = 0; +#ifdef DEBUG + printf("\nTiming Flags are:\n"); + printf("Timing flag value is: 0x%X\n", mb(9)); + if ((mb(9) & 0x01) != 0) + printf (" Getting UTC time\n"); + else + printf (" Getting GPS time\n"); + if ((mb(9) & 0x02) != 0) + printf (" PPS is from UTC\n"); + else + printf (" PPS is from GPS\n"); + if ((mb(9) & 0x04) != 0) + printf (" Time is not Set\n"); + else + printf (" Time is Set\n"); + if ((mb(9) & 0x08) != 0) + printf(" I dont have UTC info\n"); + else + printf (" I have UTC info\n"); + if ((mb(9) & 0x10) != 0) + printf (" Time is from USER\n\n"); + else + printf (" Time is from GPS\n\n"); +#endif + + if ((pp->day = day_of_year(&mb(13))) < 0) + break; + tow = getlong((u_char *) &mb(1)); +#ifdef DEBUG + if (debug > 1) { + printf("pp->day: %d\n", pp->day); + printf("TOW: %ld\n", tow); + printf("DAY: %d\n", mb(13)); + } +#endif + pp->year = getint((u_char *) &mb(15)); + pp->hour = mb(12); + pp->minute = mb(11); + pp->second = mb(10); + + +#ifdef DEBUG + if (debug > 1) + printf("TSIP_decode: unit %d: %02X #%d %02d:%02d:%02d.%09ld %02d/%02d/%04d ",up->unit, mb(0) & 0xff, event, pp->hour, pp->minute, pp->second, pp->nsec, mb(14), mb(13), pp->year); +#endif + return 1; break; - pp->year = getint((u_char *) &mb(16)); - pp->hour = mb(11); - pp->minute = mb(12); - pp->second = mb(13); + default: + /* Ignore Packet */ + return 0; + } /* switch */ + } /* if 8F packets */ + + else if (up->rpt_buf[0] == (u_char)0x42) { + printf("0x42\n"); + return 0; + } + else if (up->rpt_buf[0] == (u_char)0x43) { + printf("0x43\n"); + return 0; + } + else if ((up->rpt_buf[0] == PACKET_41) & (up->type == CLK_THUNDERBOLT)){ + printf("Undocumented 0x41 packet on Thunderbolt\n"); + return 0; + } + else if ((up->rpt_buf[0] == PACKET_41A) & (up->type == CLK_ACUTIME)) { #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->nsec, mb(15), mb(14), pp->year, - mb(19), *Tracking_Status[st]); + printf("GPS TOW: %ld\n", (long)getlong((u_char *) &mb(0))); + printf("GPS WN: %d\n", getint((u_char *) &mb(4))); + printf("GPS UTC-GPS Offser: %ld\n", (long)getlong((u_char *) &mb(6))); #endif - return 1; - break; + return 0; + } - default: - /* Ignore Packet */ + /* Health Status for Acutime Receiver */ + else if ((up->rpt_buf[0] == PACKET_46) & (up->type == CLK_ACUTIME)) { +#ifdef DEBUG + if (debug > 1) + /* Status Codes */ + switch (mb(0)) { + case 0x00: + printf ("Doing Position Fixes\n"); + break; + case 0x01: + printf ("Do no have GPS time yet\n"); + break; + case 0x03: + printf ("PDOP is too high\n"); + break; + case 0x08: + printf ("No usable satellites\n"); + break; + case 0x09: + printf ("Only 1 usable satellite\n"); + break; + case 0x0A: + printf ("Only 2 usable satellites\n"); + break; + case 0x0B: + printf ("Only 3 usable satellites\n"); + break; + case 0x0C: + printf("The Chosen satellite is unusable\n"); + break; + } +#endif + /* Error Codes */ + if (mb(1) != 0) { + + refclock_report(peer, CEVNT_BADTIME); + up->polled = -1; +#ifdef DEBUG + if (debug > 1) { + if (mb(1) & 0x01) + printf ("Signal Processor Error, reset unit.\n"); + if (mb(1) & 0x02) + printf ("Alignment error, channel or chip 1, reset unit.\n"); + if (mb(1) & 0x03) + printf ("Alignment error, channel or chip 2, reset unit.\n"); + if (mb(1) & 0x04) + printf ("Antenna feed line fault (open or short)\n"); + if (mb(1) & 0x05) + printf ("Excessive reference frequency error, refer to packet 0x2D and packet 0x4D documentation for further information\n"); + } +#endif + + return 0; + } + } + else if (up->rpt_buf[0] == 0x54) return 0; - } /* switch */ - }/* if 8F packets */ + else if (up->rpt_buf[0] == PACKET_6D) { +#ifdef DEBUG + int sats; + + if ((mb(0) & 0x01) && (mb(0) & 0x02)) + printf("2d Fix Dimension\n"); + if (mb(0) & 0x04) + printf("3d Fix Dimension\n"); + + if (mb(0) & 0x08) + printf("Fix Mode is MANUAL\n"); + else + printf("Fix Mode is AUTO\n"); + + sats = mb(0) & 0xF0; + sats = sats >> 4; + printf("Tracking %d Satellites\n", sats); +#endif + return 0; + } /* else if not super packet */ 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); + up->unit, up->rpt_buf[0] & 0xff, mb(0) & 0xff, + event, up->rpt_cnt); #endif return 0; } @@ -536,14 +894,8 @@ printf("TSIP_decode: unit %d: %02X #%d %02d:%02d:%02d.%06ld %02d/%02d/%04d UTC % static void palisade_receive ( -#ifdef PALISADE - peer - ) - struct peer * peer; -#else /* ANSI */ struct peer * peer ) -#endif { struct palisade_unit *up; struct refclockproc *pp; @@ -552,19 +904,19 @@ palisade_receive ( * Initialize pointers and read the timecode and timestamp. */ pp = peer->procptr; - up = (struct palisade_unit *)pp->unitptr; + up = pp->unitptr; if (! TSIP_decode(peer)) return; if (up->polled <= 0) - return; /* no poll pending, already received or timeout */ + 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", + "palisade_receive: unit %d: %4d %03d %02d:%02d:%02d.%09ld\n", up->unit, pp->year, pp->day, pp->hour, pp->minute, pp->second, pp->nsec); #endif @@ -575,23 +927,18 @@ palisade_receive ( * 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->nsec); + snprintf(pp->a_lastcode, sizeof(pp->a_lastcode), + "%4d %03d %02d:%02d:%02d.%09ld", + pp->year, pp->day, + pp->hour,pp->minute, pp->second, pp->nsec); pp->lencode = 24; -#ifdef PALISADE - pp->lasttime = current_time; -#endif - if (!refclock_process(pp -#ifdef PALISADE - , PALISADE_SAMPLES, PALISADE_SAMPLES * 3 / 5 -#endif - )) { + if (!refclock_process(pp)) { refclock_report(peer, CEVNT_BADTIME); #ifdef DEBUG printf("palisade_receive: unit %d: refclock_process failed!\n", - up->unit); + up->unit); #endif return; } @@ -600,16 +947,11 @@ palisade_receive ( #ifdef DEBUG if (debug) - printf("palisade_receive: unit %d: %s\n", - up->unit, prettydate(&pp->lastrec)); + printf("palisade_receive: unit %d: %s\n", + up->unit, prettydate(&pp->lastrec)); #endif pp->lastref = pp->lastrec; - refclock_receive(peer -#ifdef PALISADE - , &pp->offset, 0, pp->dispersion, - &pp->lastrec, &pp->lastrec, pp->leap -#endif - ); + refclock_receive(peer); } @@ -619,38 +961,31 @@ palisade_receive ( */ 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; + up = pp->unitptr; pp->polls++; if (up->polled > 0) /* last reply never arrived or error */ - refclock_report(peer, CEVNT_TIMEOUT); + 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"); + 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 */ + return; /* using synchronous packet input */ if(up->type == CLK_PRAECIS) { if(write(peer->procptr->io.fd,"SPSTAT\r\n",8) < 0) @@ -662,11 +997,14 @@ palisade_poll ( } if (HW_poll(pp) < 0) - refclock_report(peer, CEVNT_FAULT); + refclock_report(peer, CEVNT_FAULT); } static void -praecis_parse(struct recvbuf *rbufp, struct peer *peer) +praecis_parse ( + struct recvbuf *rbufp, + struct peer *peer + ) { static char buf[100]; static int p = 0; @@ -692,14 +1030,8 @@ praecis_parse(struct recvbuf *rbufp, struct peer *peer) static void palisade_io ( -#ifdef PALISADE - rbufp - ) - struct recvbuf *rbufp; -#else /* ANSI */ struct recvbuf *rbufp ) -#endif { /* * Initialize pointers and read the timecode and timestamp. @@ -710,9 +1042,9 @@ palisade_io ( char * c, * d; - peer = (struct peer *)rbufp->recv_srcclock; + peer = rbufp->recv_peer; pp = peer->procptr; - up = (struct palisade_unit *)pp->unitptr; + up = pp->unitptr; if(up->type == CLK_PRAECIS) { if(praecis_msg) { @@ -748,21 +1080,21 @@ palisade_io ( case TSIP_PARSED_DATA: if (*c == DLE) - up->rpt_status = TSIP_PARSED_DLE_2; + up->rpt_status = TSIP_PARSED_DLE_2; else - mb(up->rpt_cnt++) = *c; + 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; - } + *c; + } else if (*c == ETX) - up->rpt_status = TSIP_PARSED_FULL; + up->rpt_status = TSIP_PARSED_FULL; else { - /* error: start new report packet */ + /* error: start new report packet */ up->rpt_status = TSIP_PARSED_DLE_1; up->rpt_buf[0] = *c; } @@ -771,23 +1103,23 @@ palisade_io ( 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; + 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; + up->rpt_cnt = 0; if (pp->sloppyclockflag & CLK_FLAG2) - /* stamp it */ - get_systime(&pp->lastrec); + /* stamp it */ + get_systime(&pp->lastrec); } else if (up->rpt_status == TSIP_PARSED_EMPTY) - up->rpt_cnt = 0; + up->rpt_cnt = 0; else if (up->rpt_cnt > BMAX) up->rpt_status =TSIP_PARSED_EMPTY; @@ -807,26 +1139,18 @@ palisade_io ( */ 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; + up = 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 + DPRINTF(1, ("Palisade HW_poll: unit %d: GET %m\n", + up->unit)); msyslog(LOG_ERR, "Palisade(%d) HW_poll: ioctl(fd,GET): %m", up->unit); return -1; @@ -835,10 +1159,13 @@ HW_poll ( x |= TIOCM_RTS; /* turn on RTS */ /* Edge trigger */ + if (up->type == CLK_ACUTIME) + write (pp->io.fd, "", 1); + if (ioctl(pp->io.fd, TIOCMSET, &x) < 0) { #ifdef DEBUG - if (debug) - printf("Palisade HW_poll: unit %d: SET \n", up->unit); + 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", @@ -853,8 +1180,8 @@ HW_poll ( if (ioctl(pp->io.fd, TIOCMSET, &x) == -1) { #ifdef DEBUG - if (debug) - printf("Palisade HW_poll: unit %d: UNSET \n", up->unit); + 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", @@ -865,91 +1192,68 @@ HW_poll ( return 0; } -#if 0 /* unused */ /* - * this 'casts' a character array into a float + * copy/swap a big-endian palisade double into a host double */ -float -getfloat ( -#ifdef PALISADE - bp - ) - u_char *bp; -#else +static double +getdbl ( 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++; +#ifdef WORDS_BIGENDIAN + double out; + + memcpy(&out, bp, sizeof(out)); + return out; #else - ((char *) &sval)[3] = *bp++; - ((char *) &sval)[2] = *bp++; - ((char *) &sval)[1] = *bp++; - ((char *) &sval)[0] = *bp; -#endif /* ! XNTP_BIG_ENDIAN */ - return sval; -} + union { + u_char ch[8]; + u_int32 u32[2]; + } ui; + + union { + double out; + u_int32 u32[2]; + } uo; + + memcpy(ui.ch, bp, sizeof(ui.ch)); + /* least-significant 32 bits of double from swapped bp[4] to bp[7] */ + uo.u32[0] = ntohl(ui.u32[1]); + /* most-significant 32 bits from swapped bp[0] to bp[3] */ + uo.u32[1] = ntohl(ui.u32[0]); + + return uo.out; #endif +} /* - * this 'casts' a character array into a double + * copy/swap a big-endian palisade short into a host short */ -double -getdbl ( -#ifdef PALISADE - bp - ) - u_char *bp; -#else +static short +getint ( 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; + u_short us; + + memcpy(&us, bp, sizeof(us)); + return (short)ntohs(us); } /* - * cast a 16 bit character array into a short (16 bit) int + * copy/swap a big-endian palisade 32-bit int into a host 32-bit int */ -short -getint ( -#ifdef PALISADE - bp - ) - u_char *bp; -#else +static int32 +getlong( u_char *bp ) -#endif { -return (short) (bp[1] + (bp[0] << 8)); + u_int32 u32; + + memcpy(&u32, bp, sizeof(u32)); + return (int32)(u_int32)ntohl(u32); } -#else -int refclock_palisade_bs; -#endif /* REFCLOCK */ +#else /* REFCLOCK && CLOCK_PALISADE*/ +int refclock_palisade_c_notempty; +#endif |