xref: /freebsd/contrib/ntp/libparse/clk_trimtaip.c (revision daf1cffce2e07931f27c6c6998652e90df6ba87e)
1 /*
2  * /src/NTP/ntp-4/libparse/clk_trimtaip.c,v 4.7 1999/11/28 09:13:51 kardel RELEASE_19991128_A
3  *
4  * clk_trimtaip.c,v 4.7 1999/11/28 09:13:51 kardel RELEASE_19991128_A
5  *
6  * Trimble SV6 clock support - several collected codepieces
7  */
8 
9 #ifdef HAVE_CONFIG_H
10 # include <config.h>
11 #endif
12 
13 #if defined(REFCLOCK) && defined(CLOCK_PARSE) && defined(CLOCK_TRIMTAIP)
14 #include <sys/types.h>
15 #include <sys/time.h>
16 
17 #include "ntp_fp.h"
18 #include "ntp_unixtime.h"
19 #include "ntp_calendar.h"
20 
21 #include "parse.h"
22 
23 #ifndef PARSESTREAM
24 #include "ntp_stdlib.h"
25 #include <stdio.h>
26 #else
27 #include "sys/parsestreams.h"
28 extern void printf P((const char *, ...));
29 #endif
30 
31 /*	0000000000111111111122222222223333333	/ char
32  *	0123456789012345678901234567890123456	\ posn
33  *	>RTMhhmmssdddDDMMYYYYoodnnvrrrrr;*xx<	Actual
34  *	----33445566600112222BB7__-_____--99-	Parse
35  *	>RTM                      1     ;*  <",	Check
36  */
37 
38 #define	hexval(x) (('0' <= (x) && (x) <= '9') ? (x) - '0' : \
39 		   ('a' <= (x) && (x) <= 'f') ? (x) - 'a' + 10 : \
40 		   ('A' <= (x) && (x) <= 'F') ? (x) - 'A' + 10 : \
41 		   -1)
42 #define	O_USEC		O_WDAY
43 #define	O_GPSFIX	O_FLAGS
44 #define	O_CHKSUM	O_UTCHOFFSET
45      static struct format trimsv6_fmt =
46 { { { 13, 2 }, {15, 2}, { 17, 4}, /* Day, Month, Year */
47     {  4, 2 }, { 6, 2}, {  8, 2}, /* Hour, Minute, Second */
48     { 10, 3 }, {23, 1}, {  0, 0}, /* uSec, FIXes (WeekDAY, FLAGS, ZONE) */
49     { 34, 2 }, { 0, 0}, { 21, 2}, /* cksum, -, utcS (UTC[HMS]OFFSET) */
50 },
51   (const unsigned char *)">RTM                      1     ;*  <",
52   0
53 };
54 
55 static unsigned long cvt_trimtaip P((unsigned char *, int, struct format *, clocktime_t *, void *));
56 static unsigned long inp_trimtaip P((parse_t *, unsigned int, timestamp_t *));
57 
58 clockformat_t clock_trimtaip =
59 {
60   inp_trimtaip,			/* no input handling */
61   cvt_trimtaip,			/* Trimble conversion */
62   pps_one,			/* easy PPS monitoring */
63   (void *)&trimsv6_fmt,		/* conversion configuration */
64   "Trimble TAIP",
65   37,				/* string buffer */
66   0				/* no private data */
67 };
68 
69 static unsigned long
70 cvt_trimtaip(
71 	     unsigned char *buffer,
72 	     int            size,
73 	     struct format *format,
74 	     clocktime_t   *clock_time,
75 	     void          *local
76 	     )
77 {
78 	long gpsfix;
79 	u_char calc_csum = 0;
80 	long   recv_csum;
81 	int	 i;
82 
83 	if (!Strok(buffer, format->fixed_string)) return CVT_NONE;
84 #define	OFFS(x) format->field_offsets[(x)].offset
85 #define	STOI(x, y) \
86 	Stoi(&buffer[OFFS(x)], y, \
87 	     format->field_offsets[(x)].length)
88 		if (	STOI(O_DAY,	&clock_time->day)	||
89 			STOI(O_MONTH,	&clock_time->month)	||
90 			STOI(O_YEAR,	&clock_time->year)	||
91 			STOI(O_HOUR,	&clock_time->hour)	||
92 			STOI(O_MIN,	&clock_time->minute)	||
93 			STOI(O_SEC,	&clock_time->second)	||
94 			STOI(O_USEC,	&clock_time->usecond)||
95 			STOI(O_GPSFIX,	&gpsfix)
96 			) return CVT_FAIL|CVT_BADFMT;
97 
98 	clock_time->usecond *= 1000;
99 	/* Check that the checksum is right */
100 	for (i=OFFS(O_CHKSUM)-1; i >= 0; i--) calc_csum ^= buffer[i];
101 	recv_csum =	(hexval(buffer[OFFS(O_CHKSUM)]) << 4) |
102 		hexval(buffer[OFFS(O_CHKSUM)+1]);
103 	if (recv_csum < 0) return CVT_FAIL|CVT_BADTIME;
104 	if (((u_char) recv_csum) != calc_csum) return CVT_FAIL|CVT_BADTIME;
105 
106 	clock_time->utcoffset = 0;
107 
108 	/* What should flags be set to ? */
109 	clock_time->flags = PARSEB_UTC;
110 
111 	/* if the current GPS fix is 9 (unknown), reject */
112 	if (0 > gpsfix || gpsfix > 9) clock_time->flags |= PARSEB_POWERUP;
113 
114 	return CVT_OK;
115 }
116 
117 /*
118  * inp_trimtaip
119  *
120  * grep data from input stream
121  */
122 static u_long
123 inp_trimtaip(
124 	     parse_t      *parseio,
125 	     unsigned int  ch,
126 	     timestamp_t  *tstamp
127 	  )
128 {
129 	unsigned int rtc;
130 
131 	parseprintf(DD_PARSE, ("inp_trimtaip(0x%x, 0x%x, ...)\n", (int)parseio, (int)ch));
132 
133 	switch (ch)
134 	{
135 	case '>':
136 		parseprintf(DD_PARSE, ("inp_trimptaip: START seen\n"));
137 
138 		parseio->parse_index = 1;
139 		parseio->parse_data[0] = ch;
140 		parseio->parse_dtime.parse_stime = *tstamp; /* collect timestamp */
141 		return PARSE_INP_SKIP;
142 
143 	case '<':
144 		parseprintf(DD_PARSE, ("inp_trimtaip: END seen\n"));
145 		if ((rtc = parse_addchar(parseio, ch)) == PARSE_INP_SKIP)
146 			return parse_end(parseio);
147 		else
148 			return rtc;
149 
150 
151 	default:
152 		return parse_addchar(parseio, ch);
153 	}
154 }
155 
156 #else /* not (REFCLOCK && CLOCK_PARSE && CLOCK_TRIMTAIP) */
157 int clk_trimtaip_bs;
158 #endif /* not (REFCLOCK && CLOCK_PARSE && CLOCK_TRIMTAIP) */
159 
160 /*
161  * History:
162  *
163  * clk_trimtaip.c,v
164  * Revision 4.7  1999/11/28 09:13:51  kardel
165  * RECON_4_0_98F
166  *
167  * Revision 4.6  1998/08/16 18:46:27  kardel
168  * (clock_trimtaip =): changed format name
169  *
170  * Revision 4.5  1998/06/14 21:09:38  kardel
171  * Sun acc cleanup
172  *
173  * Revision 4.4  1998/06/13 12:06:57  kardel
174  * fix SYSV clock name clash
175  *
176  * Revision 4.3  1998/06/12 15:22:29  kardel
177  * fix prototypes
178  *
179  * Revision 4.2  1998/06/12 09:13:26  kardel
180  * conditional compile macros fixed
181  * printf prototype
182  *
183  * Revision 4.1  1998/05/24 09:39:54  kardel
184  * implementation of the new IO handling model
185  *
186  * Revision 4.0  1998/04/10 19:45:31  kardel
187  * Start 4.0 release version numbering
188  *
189  * from V3 1.4 log info deleted 1998/04/11 kardel
190  */
191 
192