From 2b45e011ca352ce509bc83ae148230aeee0c7e0d Mon Sep 17 00:00:00 2001 From: Ollivier Robert Date: Wed, 4 Dec 2013 21:33:17 +0000 Subject: Virgin import of ntpd 4.2.6p5. When the series of commits is complete, things like https://cert.litnet.lt/en/docs/ntp-distributed-reflection-dos-attacks should be fixed. PR: bin/148836 (except that we import a newer version) Asked by: Too many MFC after: 2 weeks --- ntpd/refclock_palisade.c | 977 +++++++++++++++++++++++++++++++---------------- 1 file changed, 649 insertions(+), 328 deletions(-) (limited to 'ntpd/refclock_palisade.c') diff --git a/ntpd/refclock_palisade.c b/ntpd/refclock_palisade.c index adb4659f97bb..ffe520d01d40 100644 --- a/ntpd/refclock_palisade.c +++ b/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 *) malloc(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 *) malloc(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,75 +289,56 @@ 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); - } + close(fd); + 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; - } + 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->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\n" + ,unit); + break; + case CLK_THUNDERBOLT: + msyslog(LOG_NOTICE, "Palisade(%d) Thunderbolt mode enabled\n" + ,unit); + tio.c_cflag = (CS8|CLOCAL|CREAD); + break; + case CLK_ACUTIME: + msyslog(LOG_NOTICE, "Palisade(%d) Acutime Gold mode enabled\n" + ,unit); + break; + default: + msyslog(LOG_NOTICE, "Palisade(%d) mode unknown\n",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; @@ -231,9 +348,10 @@ palisade_start ( 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); } @@ -253,7 +371,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 +387,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); + if (-1 != pp->io.fd) + io_closeclock(&pp->io); + if (NULL != up) + free(up); } @@ -290,29 +408,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 +435,8 @@ day_of_year ( */ int TSIP_decode ( -#ifdef PALISADE - peer - ) - struct peer *peer; -#else struct peer *peer ) -#endif { int st; long secint; @@ -350,182 +456,430 @@ 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.%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); #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; + 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; + 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); + +#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]); +#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) + 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; - pp->nsec = (long) (getdbl((u_char *) &mb(3)) * 1000000000); + GPS_UTC_Offset = getint((u_char *) &mb(7)); - if ((pp->day = day_of_year(&mb(14))) < 0) + if (GPS_UTC_Offset == 0){ /* Check UTC Offset */ +#ifdef DEBUG + printf("TSIP_decode: UTC Offset Unknown\n"); +#endif + break; + } + + + 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.%06ld %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", getlong((u_char *) &mb(0))); + printf("GPS WN: %d\n", getint((u_char *) &mb(4))); + printf("GPS UTC-GPS Offser: %ld\n", 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 +890,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; @@ -557,14 +905,14 @@ palisade_receive ( 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.%06ld\n", up->unit, pp->year, pp->day, pp->hour, pp->minute, pp->second, pp->nsec); #endif @@ -575,23 +923,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.%06ld", + 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 +943,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,16 +957,9 @@ 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; @@ -638,19 +969,19 @@ palisade_poll ( 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 +993,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 +1026,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. @@ -748,21 +1076,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 +1099,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,14 +1135,8 @@ 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; @@ -824,8 +1146,8 @@ HW_poll ( /* 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)); + 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); @@ -835,10 +1157,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 +1178,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", @@ -871,14 +1196,8 @@ HW_poll ( */ float getfloat ( -#ifdef PALISADE - bp - ) - u_char *bp; -#else u_char *bp ) -#endif { float sval; #ifdef WORDS_BIGENDIAN @@ -901,14 +1220,8 @@ getfloat ( */ double getdbl ( -#ifdef PALISADE - bp - ) - u_char *bp; -#else u_char *bp ) -#endif { double dval; #ifdef WORDS_BIGENDIAN @@ -938,18 +1251,26 @@ getdbl ( */ short getint ( -#ifdef PALISADE - bp + u_char *bp ) - u_char *bp; -#else +{ + return (short) (bp[1] + (bp[0] << 8)); +} + +/* + * cast a 32 bit character array into a long (32 bit) int + */ +long +getlong( u_char *bp ) -#endif { -return (short) (bp[1] + (bp[0] << 8)); + return (long) (bp[0] << 24) | + (bp[1] << 16) | + (bp[2] << 8) | + bp[3]; } -#else -int refclock_palisade_bs; -#endif /* REFCLOCK */ +#else /* REFCLOCK && CLOCK_PALISADE*/ +int refclock_palisade_c_notempty; +#endif -- cgit v1.2.3