154359Sroberto/*
2290001Sglebius * /src/NTP/REPOSITORY/ntp4-dev/libparse/clk_trimtsip.c,v 4.19 2009/11/01 10:47:49 kardel RELEASE_20091101_A
354359Sroberto *
4290001Sglebius * clk_trimtsip.c,v 4.19 2009/11/01 10:47:49 kardel RELEASE_20091101_A
554359Sroberto *
6182007Sroberto * Trimble TSIP support
7182007Sroberto * Thanks to Sven Dietrich for providing test hardware
8182007Sroberto *
9290001Sglebius * Copyright (c) 1995-2009 by Frank Kardel <kardel <AT> ntp.org>
10290001Sglebius * Copyright (c) 1989-1994 by Frank Kardel, Friedrich-Alexander Universitaet Erlangen-Nuernberg, Germany
11182007Sroberto *
12182007Sroberto * Redistribution and use in source and binary forms, with or without
13182007Sroberto * modification, are permitted provided that the following conditions
14182007Sroberto * are met:
15182007Sroberto * 1. Redistributions of source code must retain the above copyright
16182007Sroberto *    notice, this list of conditions and the following disclaimer.
17182007Sroberto * 2. Redistributions in binary form must reproduce the above copyright
18182007Sroberto *    notice, this list of conditions and the following disclaimer in the
19182007Sroberto *    documentation and/or other materials provided with the distribution.
20182007Sroberto * 3. Neither the name of the author nor the names of its contributors
21182007Sroberto *    may be used to endorse or promote products derived from this software
22182007Sroberto *    without specific prior written permission.
23182007Sroberto *
24182007Sroberto * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
25182007Sroberto * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26182007Sroberto * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27182007Sroberto * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
28182007Sroberto * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29182007Sroberto * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30182007Sroberto * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31182007Sroberto * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32182007Sroberto * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33182007Sroberto * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34182007Sroberto * SUCH DAMAGE.
35182007Sroberto *
3654359Sroberto */
3754359Sroberto
3854359Sroberto#ifdef HAVE_CONFIG_H
3954359Sroberto# include <config.h>
4054359Sroberto#endif
4154359Sroberto
4254359Sroberto#if defined(REFCLOCK) && defined(CLOCK_PARSE) && defined(CLOCK_TRIMTSIP)
4354359Sroberto
4454359Sroberto#include "ntp_syslog.h"
4554359Sroberto#include "ntp_types.h"
4654359Sroberto#include "ntp_fp.h"
47290001Sglebius#include "timevalops.h"
4854359Sroberto#include "ntp_calendar.h"
4954359Sroberto#include "ntp_machine.h"
5054359Sroberto#include "ntp_stdlib.h"
5154359Sroberto
5254359Sroberto#include "parse.h"
5354359Sroberto
5454359Sroberto#ifndef PARSESTREAM
5582498Sroberto# include <stdio.h>
5654359Sroberto#else
5782498Sroberto# include "sys/parsestreams.h"
5882498Sroberto#endif
5954359Sroberto
6054359Sroberto#include "ascii.h"
6154359Sroberto#include "binio.h"
6254359Sroberto#include "ieee754io.h"
6354359Sroberto#include "trimble.h"
6454359Sroberto
6554359Sroberto/*
6654359Sroberto * Trimble low level TSIP parser / time converter
6754359Sroberto *
6854359Sroberto * The receiver uses a serial message protocol called Trimble Standard
6954359Sroberto * Interface Protocol (it can support others but this driver only supports
7054359Sroberto * TSIP). Messages in this protocol have the following form:
7154359Sroberto *
7254359Sroberto * <DLE><id> ... <data> ... <DLE><ETX>
7354359Sroberto *
7454359Sroberto * Any bytes within the <data> portion of value 10 hex (<DLE>) are doubled
7554359Sroberto * on transmission and compressed back to one on reception. Otherwise
7654359Sroberto * the values of data bytes can be anything. The serial interface is RS-422
7754359Sroberto * asynchronous using 9600 baud, 8 data bits with odd party (**note** 9 bits
7854359Sroberto * in total!), and 1 stop bit. The protocol supports byte, integer, single,
7954359Sroberto * and double datatypes. Integers are two bytes, sent most significant first.
8054359Sroberto * Singles are IEEE754 single precision floating point numbers (4 byte) sent
8154359Sroberto * sign & exponent first. Doubles are IEEE754 double precision floating point
8254359Sroberto * numbers (8 byte) sent sign & exponent first.
8354359Sroberto * The receiver supports a large set of messages, only a very small subset of
8454359Sroberto * which is used here.
8554359Sroberto *
8654359Sroberto * From this module the following are recognised:
8754359Sroberto *
8854359Sroberto *  ID    Description
8954359Sroberto *
9054359Sroberto *  41    GPS Time
9154359Sroberto *  46    Receiver health
9254359Sroberto *  4F    UTC correction data (used to get leap second warnings)
9354359Sroberto *
9454359Sroberto * All others are accepted but ignored for time conversion - they are passed up to higher layers.
9554359Sroberto *
9654359Sroberto */
9754359Sroberto
9854359Srobertostatic offsets_t trim_offsets = { 0, 1, 2, 3, 4, 5, 6, 7 };
9954359Sroberto
10054359Srobertostruct trimble
10154359Sroberto{
10254359Sroberto	u_char  t_in_pkt;	/* first DLE received */
10354359Sroberto	u_char  t_dle;		/* subsequent DLE received */
10454359Sroberto	u_short t_week;		/* GPS week */
10554359Sroberto	u_short t_weekleap;	/* GPS week of next/last week */
10654359Sroberto	u_short t_dayleap;	/* day in week */
10754359Sroberto	u_short t_gpsutc;	/* GPS - UTC offset */
10854359Sroberto	u_short t_gpsutcleap;	/* offset at next/last leap */
10954359Sroberto	u_char  t_operable;	/* receiver feels OK */
11054359Sroberto	u_char  t_mode;		/* actual operating mode */
11154359Sroberto	u_char  t_leap;		/* possible leap warning */
11254359Sroberto        u_char  t_utcknown;	/* utc offset known */
11354359Sroberto};
11454359Sroberto
11554359Sroberto#define STATUS_BAD    0		/* BAD or UNINITIALIZED receiver status */
11654359Sroberto#define STATUS_UNSAFE 1		/* not enough receivers for full precision */
11754359Sroberto#define STATUS_SYNC   2		/* enough information for good operation */
11854359Sroberto
119290001Sglebiusstatic unsigned long inp_tsip (parse_t *, char, timestamp_t *);
120290001Sglebiusstatic unsigned long cvt_trimtsip (unsigned char *, int, struct format *, clocktime_t *, void *);
12154359Sroberto
12254359Srobertostruct clockformat clock_trimtsip =
12354359Sroberto{
12454359Sroberto	inp_tsip,		/* Trimble TSIP input handler */
12554359Sroberto	cvt_trimtsip,		/* Trimble TSIP conversion */
12654359Sroberto	pps_one,		/* easy PPS monitoring */
12754359Sroberto	0,			/* no configuration data */
12854359Sroberto	"Trimble TSIP",
12954359Sroberto	400,			/* input buffer */
13054359Sroberto	sizeof(struct trimble)	/* private data */
13154359Sroberto};
13254359Sroberto
13354359Sroberto#define ADDSECOND	0x01
13454359Sroberto#define DELSECOND	0x02
13554359Sroberto
13654359Srobertostatic unsigned long
13754359Srobertoinp_tsip(
13854359Sroberto	 parse_t      *parseio,
139290001Sglebius	 char         ch,
14054359Sroberto	 timestamp_t  *tstamp
14154359Sroberto	)
14254359Sroberto{
14354359Sroberto	struct trimble *t = (struct trimble *)parseio->parse_pdata;
14454359Sroberto
14554359Sroberto	if (!t)
14654359Sroberto	    return PARSE_INP_SKIP;		/* local data not allocated - sigh! */
14754359Sroberto
14854359Sroberto	if (!t->t_in_pkt && ch != DLE) {
14954359Sroberto		/* wait for start of packet */
15054359Sroberto		return PARSE_INP_SKIP;
15154359Sroberto	}
15254359Sroberto
15354359Sroberto	if ((parseio->parse_index >= (parseio->parse_dsize - 2)) ||
15454359Sroberto	    (parseio->parse_dtime.parse_msglen >= (sizeof(parseio->parse_dtime.parse_msg) - 2)))
15554359Sroberto		{		/* OVERFLOW - DROP! */
15654359Sroberto			t->t_in_pkt = t->t_dle = 0;
15754359Sroberto			parseio->parse_index = 0;
15854359Sroberto			parseio->parse_dtime.parse_msglen = 0;
15954359Sroberto		return PARSE_INP_SKIP;
16054359Sroberto	}
16154359Sroberto
16254359Sroberto	switch (ch) {
16354359Sroberto	    case DLE:
16454359Sroberto		if (!t->t_in_pkt) {
16554359Sroberto			t->t_dle = 0;
16654359Sroberto			t->t_in_pkt = 1;
16754359Sroberto			parseio->parse_index = 0;
16854359Sroberto			parseio->parse_data[parseio->parse_index++] = ch;
16954359Sroberto			parseio->parse_dtime.parse_msglen = 0;
17054359Sroberto			parseio->parse_dtime.parse_msg[parseio->parse_dtime.parse_msglen++] = ch;
17154359Sroberto			parseio->parse_dtime.parse_stime = *tstamp; /* pick up time stamp at packet start */
17254359Sroberto		} else if (t->t_dle) {
17354359Sroberto			/* Double DLE -> insert a DLE */
17454359Sroberto			t->t_dle = 0;
17554359Sroberto			parseio->parse_data[parseio->parse_index++] = DLE;
17654359Sroberto			parseio->parse_dtime.parse_msg[parseio->parse_dtime.parse_msglen++] = DLE;
17754359Sroberto		} else
17854359Sroberto		    t->t_dle = 1;
17954359Sroberto		break;
18054359Sroberto
18154359Sroberto	    case ETX:
18254359Sroberto		if (t->t_dle) {
18354359Sroberto			/* DLE,ETX -> end of packet */
18454359Sroberto			parseio->parse_data[parseio->parse_index++] = DLE;
18554359Sroberto			parseio->parse_data[parseio->parse_index] = ch;
186290001Sglebius			parseio->parse_ldsize = (u_short) (parseio->parse_index + 1);
18754359Sroberto			memcpy(parseio->parse_ldata, parseio->parse_data, parseio->parse_ldsize);
18854359Sroberto			parseio->parse_dtime.parse_msg[parseio->parse_dtime.parse_msglen++] = DLE;
18954359Sroberto			parseio->parse_dtime.parse_msg[parseio->parse_dtime.parse_msglen++] = ch;
19054359Sroberto			t->t_in_pkt = t->t_dle = 0;
19154359Sroberto			return PARSE_INP_TIME|PARSE_INP_DATA;
19254359Sroberto		}
193290001Sglebius		/*FALLTHROUGH*/
19454359Sroberto
19554359Sroberto	    default:		/* collect data */
19654359Sroberto		t->t_dle = 0;
19754359Sroberto		parseio->parse_data[parseio->parse_index++] = ch;
19854359Sroberto		parseio->parse_dtime.parse_msg[parseio->parse_dtime.parse_msglen++] = ch;
19954359Sroberto	}
20054359Sroberto
20154359Sroberto  return PARSE_INP_SKIP;
20254359Sroberto}
203290001Sglebius
204290001Sglebiusstatic short
20554359Srobertogetshort(
20654359Sroberto	 unsigned char *p
20754359Sroberto	 )
20854359Sroberto{
209290001Sglebius	return (short) get_msb_short(&p);
21054359Sroberto}
21154359Sroberto
21254359Sroberto/*
21354359Sroberto * cvt_trimtsip
21454359Sroberto *
21554359Sroberto * convert TSIP type format
21654359Sroberto */
21754359Srobertostatic unsigned long
21854359Srobertocvt_trimtsip(
21954359Sroberto	     unsigned char *buffer,
22054359Sroberto	     int            size,
22154359Sroberto	     struct format *format,
22254359Sroberto	     clocktime_t   *clock_time,
22354359Sroberto	     void          *local
22454359Sroberto	     )
22554359Sroberto{
22654359Sroberto        register struct trimble *t = (struct trimble *)local; /* get local data space */
22754359Sroberto#define mb(_X_) (buffer[2+(_X_)]) /* shortcut for buffer access */
22854359Sroberto	register u_char cmd;
22954359Sroberto
23054359Sroberto	clock_time->flags = 0;
23154359Sroberto
23254359Sroberto	if (!t) {
23354359Sroberto		return CVT_NONE;		/* local data not allocated - sigh! */
23454359Sroberto	}
23554359Sroberto
23654359Sroberto	if ((size < 4) ||
23754359Sroberto	    (buffer[0]      != DLE) ||
23854359Sroberto	    (buffer[size-1] != ETX) ||
23954359Sroberto	    (buffer[size-2] != DLE))
24054359Sroberto	{
24154359Sroberto		printf("TRIMBLE BAD packet, size %d:\n", size);
24254359Sroberto		return CVT_NONE;
24354359Sroberto	}
24454359Sroberto	else
24554359Sroberto	{
24654359Sroberto		unsigned char *bp;
24754359Sroberto		cmd = buffer[1];
248290001Sglebius
24954359Sroberto		    switch(cmd)
25054359Sroberto		    {
25154359Sroberto		    case CMD_RCURTIME:
25254359Sroberto			    {			/* GPS time */
25354359Sroberto				    l_fp secs;
25454359Sroberto				    int   week = getshort((unsigned char *)&mb(4));
25554359Sroberto				    l_fp utcoffset;
25654359Sroberto				    l_fp gpstime;
25754359Sroberto
25854359Sroberto				    bp = &mb(0);
25954359Sroberto				    if (fetch_ieee754(&bp, IEEE_SINGLE, &secs, trim_offsets) != IEEE_OK)
26054359Sroberto					    return CVT_FAIL|CVT_BADFMT;
261290001Sglebius
26254359Sroberto				    if ((secs.l_i <= 0) ||
26354359Sroberto					(t->t_utcknown == 0))
26454359Sroberto				    {
26554359Sroberto					    clock_time->flags = PARSEB_POWERUP;
26654359Sroberto					    return CVT_OK;
26754359Sroberto				    }
268290001Sglebius				    if (week < GPSWRAP) {
269290001Sglebius					    week += GPSWEEKS;
27054359Sroberto				    }
27154359Sroberto
27254359Sroberto				    /* time OK */
27354359Sroberto
27454359Sroberto				    /* fetch UTC offset */
27554359Sroberto				    bp = &mb(6);
27654359Sroberto				    if (fetch_ieee754(&bp, IEEE_SINGLE, &utcoffset, trim_offsets) != IEEE_OK)
27754359Sroberto					    return CVT_FAIL|CVT_BADFMT;
278290001Sglebius
27954359Sroberto				    L_SUB(&secs, &utcoffset); /* adjust GPS time to UTC time */
28054359Sroberto
28154359Sroberto				    gpstolfp((unsigned short)week, (unsigned short)0,
28254359Sroberto					     secs.l_ui, &gpstime);
28354359Sroberto
28454359Sroberto				    gpstime.l_uf = secs.l_uf;
28554359Sroberto
28654359Sroberto				    clock_time->utctime = gpstime.l_ui - JAN_1970;
28754359Sroberto
28854359Sroberto				    TSFTOTVU(gpstime.l_uf, clock_time->usecond);
28954359Sroberto
29054359Sroberto				    if (t->t_leap == ADDSECOND)
29154359Sroberto					clock_time->flags |= PARSEB_LEAPADD;
292290001Sglebius
29354359Sroberto				    if (t->t_leap == DELSECOND)
29454359Sroberto					clock_time->flags |= PARSEB_LEAPDEL;
295290001Sglebius
29654359Sroberto				    switch (t->t_operable)
29754359Sroberto				      {
29854359Sroberto				      case STATUS_SYNC:
29954359Sroberto					clock_time->flags &= ~(PARSEB_POWERUP|PARSEB_NOSYNC);
30054359Sroberto					break;
30154359Sroberto
30254359Sroberto				      case STATUS_UNSAFE:
30354359Sroberto					clock_time->flags |= PARSEB_NOSYNC;
30454359Sroberto					break;
30554359Sroberto
30654359Sroberto				      case STATUS_BAD:
30754359Sroberto					clock_time->flags |= PARSEB_NOSYNC|PARSEB_POWERUP;
30854359Sroberto					break;
30954359Sroberto				      }
310290001Sglebius
31154359Sroberto				    if (t->t_mode == 0)
31254359Sroberto					    clock_time->flags |= PARSEB_POSITION;
313290001Sglebius
31454359Sroberto				    clock_time->flags |= PARSEB_S_LEAP|PARSEB_S_POSITION;
315290001Sglebius
31654359Sroberto				    return CVT_OK;
31754359Sroberto
31854359Sroberto			    } /* case 0x41 */
31954359Sroberto
32054359Sroberto		    case CMD_RRECVHEALTH:
32154359Sroberto			    {
32254359Sroberto				    /* TRIMBLE health */
32354359Sroberto				    u_char status = mb(0);
32454359Sroberto
32554359Sroberto				    switch (status)
32654359Sroberto				    {
32754359Sroberto				      case 0x00: /* position fixes */
32854359Sroberto					t->t_operable = STATUS_SYNC;
32954359Sroberto					break;
33054359Sroberto
33154359Sroberto				      case 0x09: /* 1 satellite */
33254359Sroberto				      case 0x0A: /* 2 satellites */
33354359Sroberto				      case 0x0B: /* 3 satellites */
33454359Sroberto					t->t_operable = STATUS_UNSAFE;
33554359Sroberto					break;
33654359Sroberto
33754359Sroberto				      default:
33854359Sroberto					t->t_operable = STATUS_BAD;
33954359Sroberto					break;
34054359Sroberto				    }
34154359Sroberto				    t->t_mode = status;
34254359Sroberto			    }
34354359Sroberto			    break;
34454359Sroberto
34554359Sroberto		    case CMD_RUTCPARAM:
34654359Sroberto			    {
34754359Sroberto			            l_fp t0t;
34854359Sroberto				    unsigned char *lbp;
349290001Sglebius
35054359Sroberto				    /* UTC correction data - derive a leap warning */
351290001Sglebius				    int tls   = t->t_gpsutc     = (u_short) getshort((unsigned char *)&mb(12)); /* current leap correction (GPS-UTC) */
352290001Sglebius				    int tlsf  = t->t_gpsutcleap = (u_short) getshort((unsigned char *)&mb(24)); /* new leap correction */
35354359Sroberto
354290001Sglebius				    t->t_weekleap   = (u_short) getshort((unsigned char *)&mb(20)); /* week no of leap correction */
355290001Sglebius				    if (t->t_weekleap < GPSWRAP)
356290001Sglebius				      t->t_weekleap = (u_short)(t->t_weekleap + GPSWEEKS);
35754359Sroberto
358290001Sglebius				    t->t_dayleap    = (u_short) getshort((unsigned char *)&mb(22)); /* day in week of leap correction */
359290001Sglebius				    t->t_week = (u_short) getshort((unsigned char *)&mb(18)); /* current week no */
360290001Sglebius				    if (t->t_week < GPSWRAP)
361290001Sglebius				      t->t_week = (u_short)(t->t_weekleap + GPSWEEKS);
362290001Sglebius
36354359Sroberto				    lbp = (unsigned char *)&mb(14); /* last update time */
36454359Sroberto				    if (fetch_ieee754(&lbp, IEEE_SINGLE, &t0t, trim_offsets) != IEEE_OK)
36554359Sroberto					    return CVT_FAIL|CVT_BADFMT;
36654359Sroberto
36754359Sroberto				    t->t_utcknown = t0t.l_ui != 0;
368290001Sglebius
36954359Sroberto				    if ((t->t_utcknown) && /* got UTC information */
37054359Sroberto					(tlsf != tls)   && /* something will change */
37154359Sroberto					((t->t_weekleap - t->t_week) < 5)) /* and close in the future */
37254359Sroberto				    {
37354359Sroberto					    /* generate a leap warning */
37454359Sroberto					    if (tlsf > tls)
37554359Sroberto						t->t_leap = ADDSECOND;
37654359Sroberto					    else
37754359Sroberto						t->t_leap = DELSECOND;
37854359Sroberto				    }
37954359Sroberto				    else
38054359Sroberto				    {
38154359Sroberto					    t->t_leap = 0;
38254359Sroberto				    }
38354359Sroberto			    }
38454359Sroberto			    break;
38554359Sroberto
38654359Sroberto		    default:
38754359Sroberto			    /* it's validly formed, but we don't care about it! */
38854359Sroberto			    break;
38954359Sroberto		}
39054359Sroberto	}
39154359Sroberto	return CVT_SKIP;
39254359Sroberto}
39354359Sroberto
39454359Sroberto#else /* not (REFCLOCK && CLOCK_PARSE && CLOCK_TRIMTSIP && !PARSESTREAM) */
39554359Srobertoint clk_trimtsip_bs;
39654359Sroberto#endif /* not (REFCLOCK && CLOCK_PARSE && CLOCK_TRIMTSIP && !PARSESTREAM) */
39754359Sroberto
39854359Sroberto/*
39954359Sroberto * History:
40054359Sroberto *
40154359Sroberto * clk_trimtsip.c,v
402290001Sglebius * Revision 4.19  2009/11/01 10:47:49  kardel
403290001Sglebius * de-P()
404290001Sglebius *
405290001Sglebius * Revision 4.18  2009/11/01 08:46:46  kardel
406290001Sglebius * clarify case FALLTHROUGH
407290001Sglebius *
408182007Sroberto * Revision 4.17  2005/04/16 17:32:10  kardel
409182007Sroberto * update copyright
410182007Sroberto *
411182007Sroberto * Revision 4.16  2004/11/14 15:29:41  kardel
412182007Sroberto * support PPSAPI, upgrade Copyright to Berkeley style
413182007Sroberto *
41456746Sroberto * Revision 4.13  1999/11/28 09:13:51  kardel
41556746Sroberto * RECON_4_0_98F
41656746Sroberto *
41754359Sroberto * Revision 4.12  1999/02/28 13:00:08  kardel
41854359Sroberto * *** empty log message ***
41954359Sroberto *
42054359Sroberto * Revision 4.11  1999/02/28 11:47:54  kardel
42154359Sroberto * (struct trimble): new member t_utcknown
42254359Sroberto * (cvt_trimtsip): fixed status monitoring, bad receiver states are
42354359Sroberto * now recognized
42454359Sroberto *
42554359Sroberto * Revision 4.10  1999/02/27 15:57:15  kardel
42654359Sroberto * use mmemcpy instead of bcopy
42754359Sroberto *
42854359Sroberto * Revision 4.9  1999/02/21 12:17:42  kardel
42954359Sroberto * 4.91f reconcilation
43054359Sroberto *
43154359Sroberto * Revision 4.8  1998/11/15 20:27:58  kardel
43254359Sroberto * Release 4.0.73e13 reconcilation
43354359Sroberto *
43454359Sroberto * Revision 4.7  1998/08/16 18:49:20  kardel
43554359Sroberto * (cvt_trimtsip): initial kernel capable version (no more floats)
43654359Sroberto * (clock_trimtsip =): new format name
43754359Sroberto *
43854359Sroberto * Revision 4.6  1998/08/09 22:26:05  kardel
43954359Sroberto * Trimble TSIP support
44054359Sroberto *
44154359Sroberto * Revision 4.5  1998/08/02 10:37:05  kardel
44254359Sroberto * working TSIP parser
44354359Sroberto *
44454359Sroberto * Revision 4.4  1998/06/28 16:50:40  kardel
44554359Sroberto * (getflt): fixed ENDIAN issue
44654359Sroberto * (getdbl): fixed ENDIAN issue
44754359Sroberto * (getint): use get_msb_short()
44854359Sroberto * (cvt_trimtsip): use gpstolfp() for conversion
44954359Sroberto *
45054359Sroberto * Revision 4.3  1998/06/13 12:07:31  kardel
45154359Sroberto * fix SYSV clock name clash
45254359Sroberto *
45354359Sroberto * Revision 4.2  1998/06/12 15:22:30  kardel
45454359Sroberto * fix prototypes
45554359Sroberto *
45654359Sroberto * Revision 4.1  1998/05/24 09:39:54  kardel
45754359Sroberto * implementation of the new IO handling model
45854359Sroberto *
45954359Sroberto * Revision 4.0  1998/04/10 19:45:32  kardel
46054359Sroberto * Start 4.0 release version numbering
46154359Sroberto *
46254359Sroberto * from V3 1.8 loginfo deleted 1998/04/11 kardel
46354359Sroberto */
464