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