File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / ntp / ntpd / refclock_palisade.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue May 29 12:08:38 2012 UTC (12 years, 1 month ago) by misho
Branches: ntp, MAIN
CVS tags: v4_2_6p5p0, v4_2_6p5, HEAD
ntp 4.2.6p5

    1: /*
    2:  * This software was developed by the Software and Component Technologies
    3:  * group of Trimble Navigation, Ltd.
    4:  *
    5:  * Copyright (c) 1997, 1998, 1999, 2000  Trimble Navigation Ltd.
    6:  * All rights reserved.
    7:  *
    8:  * Redistribution and use in source and binary forms, with or without
    9:  * modification, are permitted provided that the following conditions
   10:  * are met:
   11:  * 1. Redistributions of source code must retain the above copyright
   12:  *    notice, this list of conditions and the following disclaimer.
   13:  * 2. Redistributions in binary form must reproduce the above copyright
   14:  *    notice, this list of conditions and the following disclaimer in the
   15:  *    documentation and/or other materials provided with the distribution.
   16:  * 3. All advertising materials mentioning features or use of this software
   17:  *    must display the following acknowledgement:
   18:  *    This product includes software developed by Trimble Navigation, Ltd.
   19:  * 4. The name of Trimble Navigation Ltd. may not be used to endorse or
   20:  *    promote products derived from this software without specific prior
   21:  *    written permission.
   22:  *
   23:  * THIS SOFTWARE IS PROVIDED BY TRIMBLE NAVIGATION LTD. ``AS IS'' AND
   24:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   25:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   26:  * ARE DISCLAIMED.  IN NO EVENT SHALL TRIMBLE NAVIGATION LTD. BE LIABLE
   27:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   28:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   29:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   30:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   31:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   32:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   33:  * SUCH DAMAGE.
   34:  */
   35: 
   36: /*
   37:  * refclock_palisade - clock driver for the Trimble Palisade GPS
   38:  * timing receiver
   39:  *
   40:  * For detailed information on this program, please refer to the html 
   41:  * Refclock 29 page accompanying the NTP distribution.
   42:  *
   43:  * for questions / bugs / comments, contact:
   44:  * sven_dietrich@trimble.com
   45:  *
   46:  * Sven-Thorsten Dietrich
   47:  * 645 North Mary Avenue
   48:  * Post Office Box 3642
   49:  * Sunnyvale, CA 94088-3642
   50:  *
   51:  * Version 2.45; July 14, 1999
   52:  *
   53:  *
   54:  *
   55:  * 31/03/06: Added support for Thunderbolt GPS Disciplined Clock.
   56:  *	     Contact: Fernando Pablo Hauscarriaga
   57:  * 	     E-mail: fernandoph@iar.unlp.edu.ar
   58:  * 	     Home page: www.iar.unlp.edu.ar/~fernandoph
   59:  *		  Instituto Argentino de Radioastronomia
   60:  *			    www.iar.unlp.edu.ar
   61:  *
   62:  * 14/01/07: Conditinal compilation for Thunderbolt support no longer needed
   63:  *	     now we use mode 2 for decode thunderbolt packets.
   64:  *	     Fernando P. Hauscarriaga
   65:  *
   66:  * 30/08/09: Added support for Trimble Acutime Gold Receiver.
   67:  *	     Fernando P. Hauscarriaga (fernandoph@iar.unlp.edu.ar)
   68:  */
   69: 
   70: #ifdef HAVE_CONFIG_H
   71: # include "config.h"
   72: #endif
   73: 
   74: #if defined(REFCLOCK) && defined(CLOCK_PALISADE)
   75: 
   76: #ifdef SYS_WINNT
   77: extern int async_write(int, const void *, unsigned int);
   78: #undef write
   79: #define write(fd, data, octets)	async_write(fd, data, octets)
   80: #endif
   81: 
   82: #include "refclock_palisade.h"
   83: /* Table to get from month to day of the year */
   84: const int days_of_year [12] = {
   85: 	0,  31,  59,  90, 120, 151, 181, 212, 243, 273, 304, 334
   86: };
   87: 
   88: #ifdef DEBUG
   89: const char * Tracking_Status[15][15] = { 
   90: 	{ "Doing Fixes\0" }, { "Good 1SV\0" }, { "Approx. 1SV\0" },
   91: 	{"Need Time\0" }, { "Need INIT\0" }, { "PDOP too High\0" },
   92: 	{ "Bad 1SV\0" }, { "0SV Usable\0" }, { "1SV Usable\0" },
   93: 	{ "2SV Usable\0" }, { "3SV Usable\0" }, { "No Integrity\0" },
   94: 	{ "Diff Corr\0" }, { "Overdet Clock\0" }, { "Invalid\0" } };
   95: #endif
   96: 
   97: /*
   98:  * Transfer vector
   99:  */
  100: struct refclock refclock_palisade = {
  101: 	palisade_start,		/* start up driver */
  102: 	palisade_shutdown,	/* shut down driver */
  103: 	palisade_poll,		/* transmit poll message */
  104: 	noentry,		/* not used  */
  105: 	noentry,		/* initialize driver (not used) */
  106: 	noentry,		/* not used */
  107: 	NOFLAGS			/* not used */
  108: };
  109: 
  110: int day_of_year (char *dt);
  111: 
  112: /* Extract the clock type from the mode setting */
  113: #define CLK_TYPE(x) ((int)(((x)->ttl) & 0x7F))
  114: 
  115: /* Supported clock types */
  116: #define CLK_TRIMBLE	0	/* Trimble Palisade */
  117: #define CLK_PRAECIS	1	/* Endrun Technologies Praecis */
  118: #define CLK_THUNDERBOLT	2	/* Trimble Thunderbolt GPS Receiver */
  119: #define CLK_ACUTIME     3	/* Trimble Acutime Gold */
  120: #define CLK_ACUTIMEB    4	/* Trimble Actutime Gold Port B */
  121: 
  122: int praecis_msg;
  123: static void praecis_parse(struct recvbuf *rbufp, struct peer *peer);
  124: 
  125: /* These routines are for sending packets to the Thunderbolt receiver
  126:  * They are taken from Markus Prosch
  127:  */
  128: 
  129: #ifdef PALISADE_SENDCMD_RESURRECTED
  130: /*
  131:  * sendcmd - Build data packet for sending
  132:  */
  133: static void 
  134: sendcmd (
  135: 	struct packettx *buffer,
  136: 	int c
  137: 	)
  138: {
  139: 	*buffer->data = DLE;
  140: 	*(buffer->data + 1) = (unsigned char)c;
  141: 	buffer->size = 2;
  142: }
  143: #endif	/* PALISADE_SENDCMD_RESURRECTED */
  144: 
  145: /*
  146:  * sendsupercmd - Build super data packet for sending
  147:  */
  148: static void 
  149: sendsupercmd (
  150: 	struct packettx *buffer,
  151: 	int c1,
  152: 	int c2
  153: 	)
  154: {
  155: 	*buffer->data = DLE;
  156: 	*(buffer->data + 1) = (unsigned char)c1;
  157: 	*(buffer->data + 2) = (unsigned char)c2;
  158: 	buffer->size = 3;
  159: }
  160: 
  161: /*
  162:  * sendbyte -
  163:  */
  164: static void 
  165: sendbyte (
  166: 	struct packettx *buffer,
  167: 	int b
  168: 	)
  169: {
  170: 	if (b == DLE)
  171: 		*(buffer->data+buffer->size++) = DLE;
  172: 	*(buffer->data+buffer->size++) = (unsigned char)b;
  173: }
  174: 
  175: /*
  176:  * sendint -
  177:  */
  178: static void 
  179: sendint (
  180: 	struct packettx *buffer,
  181: 	int a
  182: 	)
  183: {
  184: 	sendbyte(buffer, (unsigned char)((a>>8) & 0xff));
  185: 	sendbyte(buffer, (unsigned char)(a & 0xff));
  186: }
  187: 
  188: /*
  189:  * sendetx - Send packet or super packet to the device
  190:  */
  191: static int 
  192: sendetx (
  193: 	struct packettx *buffer,
  194: 	int fd
  195: 	)
  196: {
  197: 	int result;
  198: 	
  199: 	*(buffer->data+buffer->size++) = DLE;
  200: 	*(buffer->data+buffer->size++) = ETX;
  201: 	result = write(fd, buffer->data, (unsigned long)buffer->size);
  202: 	
  203: 	if (result != -1)
  204: 		return (result);
  205: 	else
  206: 		return (-1);
  207: }
  208: 
  209: /*
  210:  * init_thunderbolt - Prepares Thunderbolt receiver to be used with
  211:  *		      NTP (also taken from Markus Prosch).
  212:  */
  213: static void
  214: init_thunderbolt (
  215: 	int fd
  216: 	)
  217: {
  218: 	struct packettx tx;
  219: 	
  220: 	tx.size = 0;
  221: 	tx.data = (u_char *) malloc(100);
  222: 
  223: 	/* set UTC time */
  224: 	sendsupercmd (&tx, 0x8E, 0xA2);
  225: 	sendbyte     (&tx, 0x3);
  226: 	sendetx      (&tx, fd);
  227: 	
  228: 	/* activate packets 0x8F-AB and 0x8F-AC */
  229: 	sendsupercmd (&tx, 0x8F, 0xA5);
  230: 	sendint      (&tx, 0x5);
  231: 	sendetx      (&tx, fd);
  232: 
  233: 	free(tx.data);
  234: }
  235: 
  236: /*
  237:  * init_acutime - Prepares Acutime Receiver to be used with NTP
  238:  */
  239: static void
  240: init_acutime (
  241: 	int fd
  242: 	)
  243: {
  244: 	/* Disable all outputs, Enable Event-Polling on PortA so
  245: 	   we can ask for time packets */
  246: 	struct packettx tx;
  247: 
  248: 	tx.size = 0;
  249: 	tx.data = (u_char *) malloc(100);
  250: 
  251: 	sendsupercmd(&tx, 0x8E, 0xA5);
  252: 	sendbyte(&tx, 0x02);
  253: 	sendbyte(&tx, 0x00);
  254: 	sendbyte(&tx, 0x00);
  255: 	sendbyte(&tx, 0x00);
  256: 	sendetx(&tx, fd);
  257: 
  258: 	free(tx.data);
  259: }
  260: 
  261: /*
  262:  * palisade_start - open the devices and initialize data for processing
  263:  */
  264: static int
  265: palisade_start (
  266: 	int unit,
  267: 	struct peer *peer
  268: 	)
  269: {
  270: 	struct palisade_unit *up;
  271: 	struct refclockproc *pp;
  272: 	int fd;
  273: 	char gpsdev[20];
  274: 	struct termios tio;
  275: 
  276: 	snprintf(gpsdev, sizeof(gpsdev), DEVICE, unit);
  277: 
  278: 	/*
  279: 	 * Open serial port. 
  280: 	 */
  281: 	fd = refclock_open(gpsdev, SPEED232, LDISC_RAW);
  282: 	if (fd <= 0) {
  283: #ifdef DEBUG
  284: 		printf("Palisade(%d) start: open %s failed\n", unit, gpsdev);
  285: #endif
  286: 		return 0;
  287: 	}
  288: 
  289: 	msyslog(LOG_NOTICE, "Palisade(%d) fd: %d dev: %s", unit, fd,
  290: 		gpsdev);
  291: 
  292: 	if (tcgetattr(fd, &tio) < 0) {
  293: 		msyslog(LOG_ERR, 
  294: 			"Palisade(%d) tcgetattr(fd, &tio): %m",unit);
  295: #ifdef DEBUG
  296: 		printf("Palisade(%d) tcgetattr(fd, &tio)\n",unit);
  297: #endif
  298: 		close(fd);
  299: 		return (0);
  300: 	}
  301: 
  302: 	tio.c_cflag |= (PARENB|PARODD);
  303: 	tio.c_iflag &= ~ICRNL;
  304: 
  305: 	/*
  306: 	 * Allocate and initialize unit structure
  307: 	 */
  308: 	up = (struct palisade_unit *) emalloc(sizeof(struct palisade_unit));
  309: 
  310: 	memset((char *)up, 0, sizeof(struct palisade_unit));
  311: 
  312: 	up->type = CLK_TYPE(peer);
  313: 	switch (up->type) {
  314: 	    case CLK_TRIMBLE:
  315: 		/* Normal mode, do nothing */
  316: 		break;
  317: 	    case CLK_PRAECIS:
  318: 		msyslog(LOG_NOTICE, "Palisade(%d) Praecis mode enabled\n"
  319: 			,unit);
  320: 		break;
  321: 	    case CLK_THUNDERBOLT:
  322: 		msyslog(LOG_NOTICE, "Palisade(%d) Thunderbolt mode enabled\n"
  323: 			,unit);
  324: 		tio.c_cflag = (CS8|CLOCAL|CREAD);
  325: 		break;
  326: 	    case CLK_ACUTIME:
  327: 		msyslog(LOG_NOTICE, "Palisade(%d) Acutime Gold mode enabled\n"
  328: 			,unit);
  329: 		break;
  330: 	    default:
  331: 		msyslog(LOG_NOTICE, "Palisade(%d) mode unknown\n",unit);
  332: 		break;
  333: 	}
  334: 	if (tcsetattr(fd, TCSANOW, &tio) == -1) {
  335: 		msyslog(LOG_ERR, "Palisade(%d) tcsetattr(fd, &tio): %m",unit);
  336: #ifdef DEBUG
  337: 		printf("Palisade(%d) tcsetattr(fd, &tio)\n",unit);
  338: #endif
  339: 		close(fd);
  340: 		free(up);
  341: 		return 0;
  342: 	}
  343: 
  344: 	pp = peer->procptr;
  345: 	pp->io.clock_recv = palisade_io;
  346: 	pp->io.srcclock = (caddr_t)peer;
  347: 	pp->io.datalen = 0;
  348: 	pp->io.fd = fd;
  349: 	if (!io_addclock(&pp->io)) {
  350: #ifdef DEBUG
  351: 		printf("Palisade(%d) io_addclock\n",unit);
  352: #endif
  353: 		close(fd);
  354: 		pp->io.fd = -1;
  355: 		free(up);
  356: 		return (0);
  357: 	}
  358: 
  359: 	/*
  360: 	 * Initialize miscellaneous variables
  361: 	 */
  362: 	pp->unitptr = (caddr_t)up;
  363: 	pp->clockdesc = DESCRIPTION;
  364: 
  365: 	peer->precision = PRECISION;
  366: 	peer->sstclktype = CTL_SST_TS_UHF;
  367: 	peer->minpoll = TRMB_MINPOLL;
  368: 	peer->maxpoll = TRMB_MAXPOLL;
  369: 	memcpy((char *)&pp->refid, REFID, 4);
  370: 	
  371: 	up->leap_status = 0;
  372: 	up->unit = (short) unit;
  373: 	up->rpt_status = TSIP_PARSED_EMPTY;
  374: 	up->rpt_cnt = 0;
  375: 
  376: 	if (up->type == CLK_THUNDERBOLT)
  377: 		init_thunderbolt(fd);
  378: 	if (up->type == CLK_ACUTIME)
  379: 		init_acutime(fd);
  380: 
  381: 	return 1;
  382: }
  383: 
  384: 
  385: /*
  386:  * palisade_shutdown - shut down the clock
  387:  */
  388: static void
  389: palisade_shutdown (
  390: 	int unit,
  391: 	struct peer *peer
  392: 	)
  393: {
  394: 	struct palisade_unit *up;
  395: 	struct refclockproc *pp;
  396: 	pp = peer->procptr;
  397: 	up = (struct palisade_unit *)pp->unitptr;
  398: 	if (-1 != pp->io.fd)
  399: 		io_closeclock(&pp->io);
  400: 	if (NULL != up)
  401: 		free(up);
  402: }
  403: 
  404: 
  405: 
  406: /* 
  407:  * unpack_date - get day and year from date
  408:  */
  409: int
  410: day_of_year (
  411: 	char * dt
  412: 	)
  413: {
  414: 	int day, mon, year;
  415: 
  416: 	mon = dt[1];
  417: 	/* Check month is inside array bounds */
  418: 	if ((mon < 1) || (mon > 12)) 
  419: 		return -1;
  420: 
  421: 	day = dt[0] + days_of_year[mon - 1];
  422: 	year = getint((u_char *) (dt + 2)); 
  423: 
  424: 	if ( !(year % 4) && ((year % 100) || 
  425: 			     (!(year % 100) && !(year%400)))
  426: 	     &&(mon > 2))
  427: 		day ++; /* leap year and March or later */
  428: 
  429: 	return day;
  430: }
  431: 
  432: 
  433: /* 
  434:  * TSIP_decode - decode the TSIP data packets 
  435:  */
  436: int
  437: TSIP_decode (
  438: 	struct peer *peer
  439: 	)
  440: {
  441: 	int st;
  442: 	long   secint;
  443: 	double secs;
  444: 	double secfrac;
  445: 	unsigned short event = 0;
  446: 
  447: 	struct palisade_unit *up;
  448: 	struct refclockproc *pp;
  449: 
  450: 	pp = peer->procptr;
  451: 	up = (struct palisade_unit *)pp->unitptr;
  452: 
  453: 	/*
  454: 	 * Check the time packet, decode its contents. 
  455: 	 * If the timecode has invalid length or is not in
  456: 	 * proper format, declare bad format and exit.
  457: 	 */
  458: 
  459: 	if ((up->type != CLK_THUNDERBOLT) & (up->type != CLK_ACUTIME)){
  460: 		if ((up->rpt_buf[0] == (char) 0x41) ||
  461: 		    (up->rpt_buf[0] == (char) 0x46) ||
  462: 		    (up->rpt_buf[0] == (char) 0x54) ||
  463: 		    (up->rpt_buf[0] == (char) 0x4B) ||
  464: 		    (up->rpt_buf[0] == (char) 0x6D)) {
  465: 
  466: 			/* standard time packet - GPS time and GPS week number */
  467: #ifdef DEBUG
  468: 			printf("Palisade Port B packets detected. Connect to Port A\n");
  469: #endif
  470: 
  471: 			return 0;	
  472: 		}
  473: 	}
  474: 
  475: 	/*
  476: 	 * We cast both to u_char to as 0x8f uses the sign bit on a char
  477: 	 */
  478: 	if ((u_char) up->rpt_buf[0] == (u_char) 0x8f) {
  479: 		/* 
  480: 		 * Superpackets
  481: 		 */
  482: 		event = (unsigned short) (getint((u_char *) &mb(1)) & 0xffff);
  483: 		if (!((pp->sloppyclockflag & CLK_FLAG2) || event)) 
  484: 			/* Ignore Packet */
  485: 			return 0;	   
  486: 	
  487: 		switch (mb(0) & 0xff) {
  488: 			int GPS_UTC_Offset;
  489: 			long tow;
  490: 
  491: 		    case PACKET_8F0B: 
  492: 
  493: 			if (up->polled <= 0)
  494: 				return 0;
  495: 
  496: 			if (up->rpt_cnt != LENCODE_8F0B)  /* check length */
  497: 				break;
  498: 		
  499: #ifdef DEBUG
  500: 			if (debug > 1) {
  501: 				int ts;
  502: 				double lat, lon, alt;
  503: 				lat = getdbl((u_char *) &mb(42)) * R2D;
  504: 				lon = getdbl((u_char *) &mb(50)) * R2D;
  505: 				alt = getdbl((u_char *) &mb(58));
  506: 
  507: 				printf("TSIP_decode: unit %d: Latitude: %03.4f Longitude: %03.4f Alt: %05.2f m\n",
  508: 				       up->unit, lat,lon,alt);
  509: 				printf("TSIP_decode: unit %d: Sats:",
  510: 				       up->unit);
  511: 				for (st = 66, ts = 0; st <= 73; st++)
  512: 					if (mb(st)) {
  513: 						if (mb(st) > 0) ts++;
  514: 						printf(" %02d", mb(st));
  515: 					}
  516: 				printf(" : Tracking %d\n", ts); 
  517: 			}
  518: #endif
  519: 
  520: 			GPS_UTC_Offset = getint((u_char *) &mb(16));  
  521: 			if (GPS_UTC_Offset == 0) { /* Check UTC offset */ 
  522: #ifdef DEBUG
  523: 				printf("TSIP_decode: UTC Offset Unknown\n");
  524: #endif
  525: 				break;
  526: 			}
  527: 
  528: 			secs = getdbl((u_char *) &mb(3));
  529: 			secint = (long) secs;
  530: 			secfrac = secs - secint; /* 0.0 <= secfrac < 1.0 */
  531: 
  532: 			pp->nsec = (long) (secfrac * 1000000000); 
  533: 
  534: 			secint %= 86400;    /* Only care about today */
  535: 			pp->hour = secint / 3600;
  536: 			secint %= 3600;
  537: 			pp->minute = secint / 60;
  538: 			secint %= 60;
  539: 			pp->second = secint % 60;
  540: 		
  541: 			if ((pp->day = day_of_year(&mb(11))) < 0) break;
  542: 
  543: 			pp->year = getint((u_char *) &mb(13)); 
  544: 
  545: #ifdef DEBUG
  546: 			if (debug > 1)
  547: 				printf("TSIP_decode: unit %d: %02X #%d %02d:%02d:%02d.%06ld %02d/%02d/%04d UTC %02d\n",
  548: 				       up->unit, mb(0) & 0xff, event, pp->hour, pp->minute, 
  549: 				       pp->second, pp->nsec, mb(12), mb(11), pp->year, GPS_UTC_Offset);
  550: #endif
  551: 			/* Only use this packet when no
  552: 			 * 8F-AD's are being received
  553: 			 */
  554: 
  555: 			if (up->leap_status) {
  556: 				up->leap_status = 0;
  557: 				return 0;
  558: 			}
  559: 
  560: 			return 2;
  561: 			break;
  562: 
  563: 		    case PACKET_NTP:
  564: 			/* Palisade-NTP Packet */
  565: 
  566: 			if (up->rpt_cnt != LENCODE_NTP) /* check length */
  567: 				break;
  568: 	
  569: 			up->leap_status = mb(19);
  570: 
  571: 			if (up->polled  <= 0) 
  572: 				return 0;
  573: 				
  574: 			/* Check Tracking Status */
  575: 			st = mb(18);
  576: 			if (st < 0 || st > 14)
  577: 				st = 14;
  578: 			if ((st >= 2 && st <= 7) || st == 11 || st == 12) {
  579: #ifdef DEBUG
  580: 				printf("TSIP_decode: Not Tracking Sats : %s\n",
  581: 				       *Tracking_Status[st]);
  582: #endif
  583: 				refclock_report(peer, CEVNT_BADTIME);
  584: 				up->polled = -1;
  585: 				return 0;
  586: 				break;
  587: 			}
  588: 
  589: 			if (up->leap_status & PALISADE_LEAP_PENDING) {
  590: 				if (up->leap_status & PALISADE_UTC_TIME)  
  591: 					pp->leap = LEAP_ADDSECOND;
  592: 				else
  593: 					pp->leap = LEAP_DELSECOND;
  594: 			}
  595: 			else if (up->leap_status)
  596: 				pp->leap = LEAP_NOWARNING;
  597: 		
  598: 			else {  /* UTC flag is not set:
  599: 				 * Receiver may have been reset, and lost
  600: 				 * its UTC almanac data */
  601: 				pp->leap = LEAP_NOTINSYNC;
  602: #ifdef DEBUG
  603: 				printf("TSIP_decode: UTC Almanac unavailable: %d\n",
  604: 				       mb(19));	
  605: #endif
  606: 				refclock_report(peer, CEVNT_BADTIME);
  607: 				up->polled = -1;
  608: 				return 0;
  609: 			}
  610: 
  611: 			pp->nsec = (long) (getdbl((u_char *) &mb(3))
  612: 					   * 1000000000);
  613: 
  614: 			if ((pp->day = day_of_year(&mb(14))) < 0) 
  615: 				break;
  616: 			pp->year = getint((u_char *) &mb(16)); 
  617: 			pp->hour = mb(11);
  618: 			pp->minute = mb(12);
  619: 			pp->second = mb(13);
  620: 
  621: #ifdef DEBUG
  622: 			if (debug > 1)
  623: 				printf("TSIP_decode: unit %d: %02X #%d %02d:%02d:%02d.%06ld %02d/%02d/%04d UTC %02x %s\n",
  624: 				       up->unit, mb(0) & 0xff, event, pp->hour, pp->minute, 
  625: 				       pp->second, pp->nsec, mb(15), mb(14), pp->year,
  626: 				       mb(19), *Tracking_Status[st]);
  627: #endif
  628: 			return 1;
  629: 			break;
  630: 
  631: 		    case PACKET_8FAC:   
  632: 			if (up->polled <= 0)
  633: 				return 0; 
  634: 
  635: 			if (up->rpt_cnt != LENCODE_8FAC)/* check length */
  636: 				break;
  637: 
  638: #ifdef DEBUG
  639: 			if (debug > 1) {
  640: 				double lat, lon, alt;
  641: 				lat = getdbl((u_char *) &mb(36)) * R2D;
  642: 				lon = getdbl((u_char *) &mb(44)) * R2D;
  643: 				alt = getdbl((u_char *) &mb(52));
  644: 
  645: 				printf("TSIP_decode: unit %d: Latitude: %03.4f Longitude: %03.4f Alt: %05.2f m\n",
  646: 				       up->unit, lat,lon,alt);
  647: 				printf("TSIP_decode: unit %d\n", up->unit);
  648: 			}
  649: #endif
  650: 			if (getint((u_char *) &mb(10)) & 0x80) 
  651: 				pp->leap = LEAP_ADDSECOND;  /* we ASSUME addsecond */
  652: 			else 
  653: 				pp->leap = LEAP_NOWARNING;
  654: 
  655: #ifdef DEBUG
  656: 			if (debug > 1) 
  657: 				printf("TSIP_decode: unit %d: 0x%02x leap %d\n",
  658: 				       up->unit, mb(0) & 0xff, pp->leap);
  659: 			if (debug > 1) {
  660: 				printf("Receiver MODE: 0x%02X\n", (u_char)mb(1));
  661: 				if (mb(1) == 0x00)
  662: 					printf("                AUTOMATIC\n");
  663: 				if (mb(1) == 0x01)
  664: 					printf("                SINGLE SATELLITE\n");   
  665: 				if (mb(1) == 0x03)
  666: 					printf("                HORIZONTAL(2D)\n");
  667: 				if (mb(1) == 0x04)
  668: 					printf("                FULL POSITION(3D)\n");
  669: 				if (mb(1) == 0x05)
  670: 					printf("                DGPR REFERENCE\n");
  671: 				if (mb(1) == 0x06)
  672: 					printf("                CLOCK HOLD(2D)\n");
  673: 				if (mb(1) == 0x07)
  674: 					printf("                OVERDETERMINED CLOCK\n");
  675: 
  676: 				printf("\n** Disciplining MODE 0x%02X:\n", (u_char)mb(2));
  677: 				if (mb(2) == 0x00)
  678: 					printf("                NORMAL\n");
  679: 				if (mb(2) == 0x01)
  680: 					printf("                POWER-UP\n");
  681: 				if (mb(2) == 0x02)
  682: 					printf("                AUTO HOLDOVER\n");
  683: 				if (mb(2) == 0x03)
  684: 					printf("                MANUAL HOLDOVER\n");
  685: 				if (mb(2) == 0x04)
  686: 					printf("                RECOVERY\n");
  687: 				if (mb(2) == 0x06)
  688: 					printf("                DISCIPLINING DISABLED\n");
  689: 			}
  690: #endif   
  691: 			return 0;
  692: 			break;
  693: 
  694: 		    case PACKET_8FAB:
  695: 			/* Thunderbolt Primary Timing Packet */
  696: 
  697: 			if (up->rpt_cnt != LENCODE_8FAB) /* check length */
  698: 				break;
  699: 
  700: 			if (up->polled  <= 0)
  701: 				return 0;
  702: 
  703: 			GPS_UTC_Offset = getint((u_char *) &mb(7));
  704: 
  705: 			if (GPS_UTC_Offset == 0){ /* Check UTC Offset */
  706: #ifdef DEBUG
  707: 				printf("TSIP_decode: UTC Offset Unknown\n");
  708: #endif
  709: 				break;
  710: 			}
  711: 
  712: 
  713: 			if ((mb(9) & 0x1d) == 0x0) {
  714: 				/* if we know the GPS time and the UTC offset,
  715: 				   we expect UTC timing information !!! */
  716: 
  717: 				pp->leap = LEAP_NOTINSYNC;
  718: 				refclock_report(peer, CEVNT_BADTIME);
  719: 				up->polled = -1;
  720: 				return 0;
  721: 			}
  722: 
  723: 			pp->nsec = 0;
  724: #ifdef DEBUG		
  725: 			printf("\nTiming Flags are:\n");
  726: 			printf("Timing flag value is: 0x%X\n", mb(9));
  727: 			if ((mb(9) & 0x01) != 0)
  728: 				printf ("	Getting UTC time\n");
  729: 			else
  730: 				printf ("	Getting GPS time\n");
  731: 			if ((mb(9) & 0x02) != 0)
  732: 				printf ("	PPS is from UTC\n");
  733: 			else
  734: 				printf ("	PPS is from GPS\n");
  735: 			if ((mb(9) & 0x04) != 0)
  736: 				printf ("	Time is not Set\n");
  737: 			else
  738: 				printf ("	Time is Set\n");
  739: 			if ((mb(9) & 0x08) != 0)
  740: 				printf("	I dont have UTC info\n");
  741: 			else
  742: 				printf ("	I have UTC info\n");
  743: 			if ((mb(9) & 0x10) != 0)
  744: 				printf ("	Time is from USER\n\n");
  745: 			else
  746: 				printf ("	Time is from GPS\n\n");	
  747: #endif		
  748: 
  749: 			if ((pp->day = day_of_year(&mb(13))) < 0)
  750: 				break;
  751: 			tow = getlong((u_char *) &mb(1));
  752: #ifdef DEBUG		
  753: 			if (debug > 1) {
  754: 				printf("pp->day: %d\n", pp->day); 
  755: 				printf("TOW: %ld\n", tow);
  756: 				printf("DAY: %d\n", mb(13));
  757: 			}
  758: #endif
  759: 			pp->year = getint((u_char *) &mb(15));
  760: 			pp->hour = mb(12);
  761: 			pp->minute = mb(11);
  762: 			pp->second = mb(10);
  763: 
  764: 
  765: #ifdef DEBUG
  766: 			if (debug > 1)
  767: 				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);
  768: #endif
  769: 			return 1;
  770: 			break;
  771: 
  772: 		    default:
  773: 			/* Ignore Packet */
  774: 			return 0;
  775: 		} /* switch */
  776: 	} /* if 8F packets */
  777: 
  778: 	else if (up->rpt_buf[0] == (u_char)0x42) {
  779: 		printf("0x42\n");
  780: 		return 0;
  781: 	}
  782: 	else if (up->rpt_buf[0] == (u_char)0x43) {
  783: 		printf("0x43\n");
  784: 		return 0;
  785: 	}
  786: 	else if ((up->rpt_buf[0] == PACKET_41) & (up->type == CLK_THUNDERBOLT)){
  787: 		printf("Undocumented 0x41 packet on Thunderbolt\n");
  788: 		return 0;
  789: 	}
  790: 	else if ((up->rpt_buf[0] == PACKET_41A) & (up->type == CLK_ACUTIME)) {
  791: #ifdef DEBUG
  792: 		printf("GPS TOW: %ld\n", getlong((u_char *) &mb(0)));
  793: 		printf("GPS WN: %d\n", getint((u_char *) &mb(4)));
  794: 		printf("GPS UTC-GPS Offser: %ld\n", getlong((u_char *) &mb(6)));
  795: #endif
  796: 		return 0;
  797: 	}
  798: 
  799: 	/* Health Status for Acutime Receiver */
  800: 	else if ((up->rpt_buf[0] == PACKET_46) & (up->type == CLK_ACUTIME)) {
  801: #ifdef DEBUG
  802: 		if (debug > 1)
  803: 		/* Status Codes */
  804: 			switch (mb(0)) {
  805: 			    case 0x00:
  806: 				printf ("Doing Position Fixes\n");
  807: 				break;
  808: 			    case 0x01:
  809: 				printf ("Do no have GPS time yet\n");
  810: 				break;
  811: 			    case 0x03:
  812: 				printf ("PDOP is too high\n");
  813: 				break;
  814: 			    case 0x08:
  815: 				printf ("No usable satellites\n");
  816: 				break;
  817: 			    case 0x09:
  818: 				printf ("Only 1 usable satellite\n");
  819: 				break;
  820: 			    case 0x0A:
  821: 				printf ("Only 2 usable satellites\n");
  822: 				break;
  823: 			    case 0x0B:
  824: 				printf ("Only 3 usable satellites\n");
  825: 				break;
  826: 			    case 0x0C:
  827: 				printf("The Chosen satellite is unusable\n");
  828: 				break;
  829: 			}
  830: #endif
  831: 		/* Error Codes */
  832: 		if (mb(1) != 0)	{
  833: 			
  834: 			refclock_report(peer, CEVNT_BADTIME);
  835: 			up->polled = -1;
  836: #ifdef DEBUG
  837: 			if (debug > 1) {
  838: 				if (mb(1) && 0x01)
  839: 					printf ("Signal Processor Error, reset unit.\n");
  840: 				if (mb(1) && 0x02)
  841: 					printf ("Alignment error, channel or chip 1, reset unit.\n");
  842: 				if (mb(1) && 0x03)
  843: 					printf ("Alignment error, channel or chip 2, reset unit.\n");
  844: 				if (mb(1) && 0x04)
  845: 					printf ("Antenna feed line fault (open or short)\n");
  846: 				if (mb(1) && 0x05)
  847: 					printf ("Excessive reference frequency error, refer to packet 0x2D and packet 0x4D documentation for further information\n");
  848: 			}
  849: #endif
  850: 		
  851: 		return 0;
  852: 		}
  853: 	}
  854: 	else if (up->rpt_buf[0] == 0x54)
  855: 		return 0;
  856: 
  857: 	else if (up->rpt_buf[0] == PACKET_6D) {
  858: #ifdef DEBUG
  859: 		int sats;
  860: 
  861: 		if ((mb(0) & 0x01) && (mb(0) & 0x02))
  862: 			printf("2d Fix Dimension\n");
  863: 		if (mb(0) & 0x04)
  864: 			printf("3d Fix Dimension\n");
  865: 
  866: 		if (mb(0) & 0x08)
  867: 			printf("Fix Mode is MANUAL\n");
  868: 		else
  869: 			printf("Fix Mode is AUTO\n");
  870: 	
  871: 		sats = mb(0) & 0xF0;
  872: 		sats = sats >> 4;
  873: 		printf("Tracking %d Satellites\n", sats);
  874: #endif
  875: 		return 0;
  876: 	} /* else if not super packet */
  877: 	refclock_report(peer, CEVNT_BADREPLY);
  878: 	up->polled = -1;
  879: #ifdef DEBUG
  880: 	printf("TSIP_decode: unit %d: bad packet %02x-%02x event %d len %d\n", 
  881: 	       up->unit, up->rpt_buf[0] & 0xff, mb(0) & 0xff, 
  882: 	       event, up->rpt_cnt);
  883: #endif
  884: 	return 0;
  885: }
  886: 
  887: /*
  888:  * palisade__receive - receive data from the serial interface
  889:  */
  890: 
  891: static void
  892: palisade_receive (
  893: 	struct peer * peer
  894: 	)
  895: {
  896: 	struct palisade_unit *up;
  897: 	struct refclockproc *pp;
  898: 
  899: 	/*
  900: 	 * Initialize pointers and read the timecode and timestamp.
  901: 	 */
  902: 	pp = peer->procptr;
  903: 	up = (struct palisade_unit *)pp->unitptr;
  904: 		
  905: 	if (! TSIP_decode(peer)) return;
  906: 	
  907: 	if (up->polled <= 0) 
  908: 		return;   /* no poll pending, already received or timeout */
  909: 
  910: 	up->polled = 0;  /* Poll reply received */
  911: 	pp->lencode = 0; /* clear time code */
  912: #ifdef DEBUG
  913: 	if (debug) 
  914: 		printf(
  915: 			"palisade_receive: unit %d: %4d %03d %02d:%02d:%02d.%06ld\n",
  916: 			up->unit, pp->year, pp->day, pp->hour, pp->minute, 
  917: 			pp->second, pp->nsec);
  918: #endif
  919: 
  920: 	/*
  921: 	 * Process the sample
  922: 	 * Generate timecode: YYYY DoY HH:MM:SS.microsec 
  923: 	 * report and process 
  924: 	 */
  925: 
  926: 	snprintf(pp->a_lastcode, sizeof(pp->a_lastcode),
  927: 		 "%4d %03d %02d:%02d:%02d.%06ld",
  928: 		 pp->year, pp->day,
  929: 		 pp->hour,pp->minute, pp->second, pp->nsec); 
  930: 	pp->lencode = 24;
  931: 
  932: 	if (!refclock_process(pp)) {
  933: 		refclock_report(peer, CEVNT_BADTIME);
  934: 
  935: #ifdef DEBUG
  936: 		printf("palisade_receive: unit %d: refclock_process failed!\n",
  937: 		       up->unit);
  938: #endif
  939: 		return;
  940: 	}
  941: 
  942: 	record_clock_stats(&peer->srcadr, pp->a_lastcode); 
  943: 
  944: #ifdef DEBUG
  945: 	if (debug)
  946: 		printf("palisade_receive: unit %d: %s\n",
  947: 		       up->unit, prettydate(&pp->lastrec));
  948: #endif
  949: 	pp->lastref = pp->lastrec;
  950: 	refclock_receive(peer);
  951: }
  952: 
  953: 
  954: /*
  955:  * palisade_poll - called by the transmit procedure
  956:  *
  957:  */
  958: static void
  959: palisade_poll (
  960: 	int unit,
  961: 	struct peer *peer
  962: 	)
  963: {
  964: 	struct palisade_unit *up;
  965: 	struct refclockproc *pp;
  966: 	
  967: 	pp = peer->procptr;
  968: 	up = (struct palisade_unit *)pp->unitptr;
  969: 
  970: 	pp->polls++;
  971: 	if (up->polled > 0) /* last reply never arrived or error */ 
  972: 		refclock_report(peer, CEVNT_TIMEOUT);
  973: 
  974: 	up->polled = 2; /* synchronous packet + 1 event */
  975: 	
  976: #ifdef DEBUG
  977: 	if (debug)
  978: 		printf("palisade_poll: unit %d: polling %s\n", unit,
  979: 		       (pp->sloppyclockflag & CLK_FLAG2) ? 
  980: 		       "synchronous packet" : "event");
  981: #endif 
  982: 
  983: 	if (pp->sloppyclockflag & CLK_FLAG2) 
  984: 		return;  /* using synchronous packet input */
  985: 
  986: 	if(up->type == CLK_PRAECIS) {
  987: 		if(write(peer->procptr->io.fd,"SPSTAT\r\n",8) < 0)
  988: 			msyslog(LOG_ERR, "Palisade(%d) write: %m:",unit);
  989: 		else {
  990: 			praecis_msg = 1;
  991: 			return;
  992: 		}
  993: 	}
  994: 
  995: 	if (HW_poll(pp) < 0) 
  996: 		refclock_report(peer, CEVNT_FAULT); 
  997: }
  998: 
  999: static void
 1000: praecis_parse (
 1001: 	struct recvbuf *rbufp,
 1002: 	struct peer *peer
 1003: 	)
 1004: {
 1005: 	static char buf[100];
 1006: 	static int p = 0;
 1007: 	struct refclockproc *pp;
 1008: 
 1009: 	pp = peer->procptr;
 1010: 
 1011: 	memcpy(buf+p,rbufp->recv_space.X_recv_buffer, rbufp->recv_length);
 1012: 	p += rbufp->recv_length;
 1013: 
 1014: 	if(buf[p-2] == '\r' && buf[p-1] == '\n') {
 1015: 		buf[p-2] = '\0';
 1016: 		record_clock_stats(&peer->srcadr, buf);
 1017: 
 1018: 		p = 0;
 1019: 		praecis_msg = 0;
 1020: 
 1021: 		if (HW_poll(pp) < 0)
 1022: 			refclock_report(peer, CEVNT_FAULT);
 1023: 
 1024: 	}
 1025: }
 1026: 
 1027: static void
 1028: palisade_io (
 1029: 	struct recvbuf *rbufp
 1030: 	)
 1031: {
 1032: 	/*
 1033: 	 * Initialize pointers and read the timecode and timestamp.
 1034: 	 */
 1035: 	struct palisade_unit *up;
 1036: 	struct refclockproc *pp;
 1037: 	struct peer *peer;
 1038: 
 1039: 	char * c, * d;
 1040: 
 1041: 	peer = (struct peer *)rbufp->recv_srcclock;
 1042: 	pp = peer->procptr;
 1043: 	up = (struct palisade_unit *)pp->unitptr;
 1044: 
 1045: 	if(up->type == CLK_PRAECIS) {
 1046: 		if(praecis_msg) {
 1047: 			praecis_parse(rbufp,peer);
 1048: 			return;
 1049: 		}
 1050: 	}
 1051: 
 1052: 	c = (char *) &rbufp->recv_space;
 1053: 	d = c + rbufp->recv_length;
 1054: 		
 1055: 	while (c != d) {
 1056: 
 1057: 		/* Build time packet */
 1058: 		switch (up->rpt_status) {
 1059: 
 1060: 		    case TSIP_PARSED_DLE_1:
 1061: 			switch (*c)
 1062: 			{
 1063: 			    case 0:
 1064: 			    case DLE:
 1065: 			    case ETX:
 1066: 				up->rpt_status = TSIP_PARSED_EMPTY;
 1067: 				break;
 1068: 
 1069: 			    default:
 1070: 				up->rpt_status = TSIP_PARSED_DATA;
 1071: 				/* save packet ID */
 1072: 				up->rpt_buf[0] = *c;
 1073: 				break;
 1074: 			}
 1075: 			break;
 1076: 
 1077: 		    case TSIP_PARSED_DATA:
 1078: 			if (*c == DLE)
 1079: 				up->rpt_status = TSIP_PARSED_DLE_2;
 1080: 			else 
 1081: 				mb(up->rpt_cnt++) = *c;
 1082: 			break;
 1083: 
 1084: 		    case TSIP_PARSED_DLE_2:
 1085: 			if (*c == DLE) {
 1086: 				up->rpt_status = TSIP_PARSED_DATA;
 1087: 				mb(up->rpt_cnt++) = 
 1088: 				    *c;
 1089: 			}
 1090: 			else if (*c == ETX) 
 1091: 				up->rpt_status = TSIP_PARSED_FULL;
 1092: 			else 	{
 1093: 				/* error: start new report packet */
 1094: 				up->rpt_status = TSIP_PARSED_DLE_1;
 1095: 				up->rpt_buf[0] = *c;
 1096: 			}
 1097: 			break;
 1098: 
 1099: 		    case TSIP_PARSED_FULL:
 1100: 		    case TSIP_PARSED_EMPTY:
 1101: 		    default:
 1102: 			if ( *c != DLE)
 1103: 				up->rpt_status = TSIP_PARSED_EMPTY;
 1104: 			else 
 1105: 				up->rpt_status = TSIP_PARSED_DLE_1;
 1106: 			break;
 1107: 		}
 1108: 		
 1109: 		c++;
 1110: 
 1111: 		if (up->rpt_status == TSIP_PARSED_DLE_1) {
 1112: 			up->rpt_cnt = 0;
 1113: 			if (pp->sloppyclockflag & CLK_FLAG2) 
 1114: 				/* stamp it */
 1115: 				get_systime(&pp->lastrec);
 1116: 		}
 1117: 		else if (up->rpt_status == TSIP_PARSED_EMPTY)
 1118: 			up->rpt_cnt = 0;
 1119: 
 1120: 		else if (up->rpt_cnt > BMAX) 
 1121: 			up->rpt_status =TSIP_PARSED_EMPTY;
 1122: 
 1123: 		if (up->rpt_status == TSIP_PARSED_FULL) 
 1124: 			palisade_receive(peer);
 1125: 
 1126: 	} /* while chars in buffer */
 1127: }
 1128: 
 1129: 
 1130: /*
 1131:  * Trigger the Palisade's event input, which is driven off the RTS
 1132:  *
 1133:  * Take a system time stamp to match the GPS time stamp.
 1134:  *
 1135:  */
 1136: long
 1137: HW_poll (
 1138: 	struct refclockproc * pp 	/* pointer to unit structure */
 1139: 	)
 1140: {	
 1141: 	int x;	/* state before & after RTS set */
 1142: 	struct palisade_unit *up;
 1143: 
 1144: 	up = (struct palisade_unit *) pp->unitptr;
 1145: 
 1146: 	/* read the current status, so we put things back right */
 1147: 	if (ioctl(pp->io.fd, TIOCMGET, &x) < 0) {
 1148: #ifdef DEBUG
 1149: 		if (debug)
 1150: 			printf("Palisade HW_poll: unit %d: GET %s\n", up->unit, strerror(errno));
 1151: #endif
 1152: 		msyslog(LOG_ERR, "Palisade(%d) HW_poll: ioctl(fd,GET): %m", 
 1153: 			up->unit);
 1154: 		return -1;
 1155: 	}
 1156:   
 1157: 	x |= TIOCM_RTS;        /* turn on RTS  */
 1158: 
 1159: 	/* Edge trigger */
 1160: 	if (up->type == CLK_ACUTIME)
 1161: 		write (pp->io.fd, "", 1);
 1162: 		
 1163: 	if (ioctl(pp->io.fd, TIOCMSET, &x) < 0) { 
 1164: #ifdef DEBUG
 1165: 		if (debug)
 1166: 			printf("Palisade HW_poll: unit %d: SET \n", up->unit);
 1167: #endif
 1168: 		msyslog(LOG_ERR,
 1169: 			"Palisade(%d) HW_poll: ioctl(fd, SET, RTS_on): %m", 
 1170: 			up->unit);
 1171: 		return -1;
 1172: 	}
 1173: 
 1174: 	x &= ~TIOCM_RTS;        /* turn off RTS  */
 1175: 	
 1176: 	/* poll timestamp */
 1177: 	get_systime(&pp->lastrec);
 1178: 
 1179: 	if (ioctl(pp->io.fd, TIOCMSET, &x) == -1) {
 1180: #ifdef DEBUG
 1181: 		if (debug)
 1182: 			printf("Palisade HW_poll: unit %d: UNSET \n", up->unit);
 1183: #endif
 1184: 		msyslog(LOG_ERR,
 1185: 			"Palisade(%d) HW_poll: ioctl(fd, UNSET, RTS_off): %m", 
 1186: 			up->unit);
 1187: 		return -1;
 1188: 	}
 1189: 
 1190: 	return 0;
 1191: }
 1192: 
 1193: #if 0 /* unused */
 1194: /*
 1195:  * this 'casts' a character array into a float
 1196:  */
 1197: float
 1198: getfloat (
 1199: 	u_char *bp
 1200: 	)
 1201: {
 1202: 	float sval;
 1203: #ifdef WORDS_BIGENDIAN 
 1204: 	((char *) &sval)[0] = *bp++;
 1205: 	((char *) &sval)[1] = *bp++;
 1206: 	((char *) &sval)[2] = *bp++;
 1207: 	((char *) &sval)[3] = *bp++;
 1208: #else
 1209: 	((char *) &sval)[3] = *bp++;
 1210: 	((char *) &sval)[2] = *bp++;
 1211: 	((char *) &sval)[1] = *bp++;
 1212: 	((char *) &sval)[0] = *bp;
 1213: #endif  /* ! XNTP_BIG_ENDIAN */ 
 1214: 	return sval;
 1215: }
 1216: #endif
 1217: 
 1218: /*
 1219:  * this 'casts' a character array into a double
 1220:  */
 1221: double
 1222: getdbl (
 1223: 	u_char *bp
 1224: 	)
 1225: {
 1226: 	double dval;
 1227: #ifdef WORDS_BIGENDIAN 
 1228: 	((char *) &dval)[0] = *bp++;
 1229: 	((char *) &dval)[1] = *bp++;
 1230: 	((char *) &dval)[2] = *bp++;
 1231: 	((char *) &dval)[3] = *bp++;
 1232: 	((char *) &dval)[4] = *bp++;
 1233: 	((char *) &dval)[5] = *bp++;
 1234: 	((char *) &dval)[6] = *bp++;
 1235: 	((char *) &dval)[7] = *bp;
 1236: #else
 1237: 	((char *) &dval)[7] = *bp++;
 1238: 	((char *) &dval)[6] = *bp++;
 1239: 	((char *) &dval)[5] = *bp++;
 1240: 	((char *) &dval)[4] = *bp++;
 1241: 	((char *) &dval)[3] = *bp++;
 1242: 	((char *) &dval)[2] = *bp++;
 1243: 	((char *) &dval)[1] = *bp++;
 1244: 	((char *) &dval)[0] = *bp;
 1245: #endif  /* ! XNTP_BIG_ENDIAN */ 
 1246: 	return dval;
 1247: }
 1248: 
 1249: /*
 1250:  * cast a 16 bit character array into a short (16 bit) int
 1251:  */
 1252: short
 1253: getint (
 1254: 	u_char *bp
 1255: 	)
 1256: {
 1257: 	return (short) (bp[1] + (bp[0] << 8));
 1258: }
 1259: 
 1260: /*
 1261:  * cast a 32 bit character array into a long (32 bit) int
 1262:  */
 1263: long
 1264: getlong(
 1265: 	u_char *bp
 1266: 	)
 1267: {
 1268: 	return (long) (bp[0] << 24) | 
 1269: 		      (bp[1] << 16) |
 1270: 		      (bp[2] << 8) |
 1271: 		       bp[3];
 1272: }
 1273: 
 1274: #else	/* REFCLOCK && CLOCK_PALISADE*/
 1275: int refclock_palisade_c_notempty;
 1276: #endif

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>