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