clk_trimtaip.c revision 54359
154359Sroberto/* 254359Sroberto * /src/NTP/ntp-4/libparse/clk_trimtaip.c,v 4.6 1998/08/16 18:46:27 kardel RELEASE_19990228_A 354359Sroberto * 454359Sroberto * clk_trimtaip.c,v 4.6 1998/08/16 18:46:27 kardel RELEASE_19990228_A 554359Sroberto * 654359Sroberto * Trimble SV6 clock support - several collected codepieces 754359Sroberto */ 854359Sroberto 954359Sroberto#ifdef HAVE_CONFIG_H 1054359Sroberto# include <config.h> 1154359Sroberto#endif 1254359Sroberto 1354359Sroberto#if defined(REFCLOCK) && defined(CLOCK_PARSE) && defined(CLOCK_TRIMTAIP) 1454359Sroberto#include <sys/types.h> 1554359Sroberto#include <sys/time.h> 1654359Sroberto 1754359Sroberto#include "ntp_fp.h" 1854359Sroberto#include "ntp_unixtime.h" 1954359Sroberto#include "ntp_calendar.h" 2054359Sroberto 2154359Sroberto#include "parse.h" 2254359Sroberto 2354359Sroberto#ifndef PARSESTREAM 2454359Sroberto#include "ntp_stdlib.h" 2554359Sroberto#include <stdio.h> 2654359Sroberto#else 2754359Sroberto#include "sys/parsestreams.h" 2854359Srobertoextern void printf P((const char *, ...)); 2954359Sroberto#endif 3054359Sroberto 3154359Sroberto/* 0000000000111111111122222222223333333 / char 3254359Sroberto * 0123456789012345678901234567890123456 \ posn 3354359Sroberto * >RTMhhmmssdddDDMMYYYYoodnnvrrrrr;*xx< Actual 3454359Sroberto * ----33445566600112222BB7__-_____--99- Parse 3554359Sroberto * >RTM 1 ;* <", Check 3654359Sroberto */ 3754359Sroberto 3854359Sroberto#define hexval(x) (('0' <= (x) && (x) <= '9') ? (x) - '0' : \ 3954359Sroberto ('a' <= (x) && (x) <= 'f') ? (x) - 'a' + 10 : \ 4054359Sroberto ('A' <= (x) && (x) <= 'F') ? (x) - 'A' + 10 : \ 4154359Sroberto -1) 4254359Sroberto#define O_USEC O_WDAY 4354359Sroberto#define O_GPSFIX O_FLAGS 4454359Sroberto#define O_CHKSUM O_UTCHOFFSET 4554359Sroberto static struct format trimsv6_fmt = 4654359Sroberto{ { { 13, 2 }, {15, 2}, { 17, 4}, /* Day, Month, Year */ 4754359Sroberto { 4, 2 }, { 6, 2}, { 8, 2}, /* Hour, Minute, Second */ 4854359Sroberto { 10, 3 }, {23, 1}, { 0, 0}, /* uSec, FIXes (WeekDAY, FLAGS, ZONE) */ 4954359Sroberto { 34, 2 }, { 0, 0}, { 21, 2}, /* cksum, -, utcS (UTC[HMS]OFFSET) */ 5054359Sroberto}, 5154359Sroberto (const unsigned char *)">RTM 1 ;* <", 5254359Sroberto 0 5354359Sroberto}; 5454359Sroberto 5554359Srobertostatic unsigned long cvt_trimtaip P((unsigned char *, int, struct format *, clocktime_t *, void *)); 5654359Srobertostatic unsigned long inp_trimtaip P((parse_t *, unsigned int, timestamp_t *)); 5754359Sroberto 5854359Srobertoclockformat_t clock_trimtaip = 5954359Sroberto{ 6054359Sroberto inp_trimtaip, /* no input handling */ 6154359Sroberto cvt_trimtaip, /* Trimble conversion */ 6254359Sroberto pps_one, /* easy PPS monitoring */ 6354359Sroberto (void *)&trimsv6_fmt, /* conversion configuration */ 6454359Sroberto "Trimble TAIP", 6554359Sroberto 37, /* string buffer */ 6654359Sroberto 0 /* no private data */ 6754359Sroberto}; 6854359Sroberto 6954359Srobertostatic unsigned long 7054359Srobertocvt_trimtaip( 7154359Sroberto unsigned char *buffer, 7254359Sroberto int size, 7354359Sroberto struct format *format, 7454359Sroberto clocktime_t *clock_time, 7554359Sroberto void *local 7654359Sroberto ) 7754359Sroberto{ 7854359Sroberto long gpsfix; 7954359Sroberto u_char calc_csum = 0; 8054359Sroberto long recv_csum; 8154359Sroberto int i; 8254359Sroberto 8354359Sroberto if (!Strok(buffer, format->fixed_string)) return CVT_NONE; 8454359Sroberto#define OFFS(x) format->field_offsets[(x)].offset 8554359Sroberto#define STOI(x, y) \ 8654359Sroberto Stoi(&buffer[OFFS(x)], y, \ 8754359Sroberto format->field_offsets[(x)].length) 8854359Sroberto if ( STOI(O_DAY, &clock_time->day) || 8954359Sroberto STOI(O_MONTH, &clock_time->month) || 9054359Sroberto STOI(O_YEAR, &clock_time->year) || 9154359Sroberto STOI(O_HOUR, &clock_time->hour) || 9254359Sroberto STOI(O_MIN, &clock_time->minute) || 9354359Sroberto STOI(O_SEC, &clock_time->second) || 9454359Sroberto STOI(O_USEC, &clock_time->usecond)|| 9554359Sroberto STOI(O_GPSFIX, &gpsfix) 9654359Sroberto ) return CVT_FAIL|CVT_BADFMT; 9754359Sroberto 9854359Sroberto clock_time->usecond *= 1000; 9954359Sroberto /* Check that the checksum is right */ 10054359Sroberto for (i=OFFS(O_CHKSUM)-1; i >= 0; i--) calc_csum ^= buffer[i]; 10154359Sroberto recv_csum = (hexval(buffer[OFFS(O_CHKSUM)]) << 4) | 10254359Sroberto hexval(buffer[OFFS(O_CHKSUM)+1]); 10354359Sroberto if (recv_csum < 0) return CVT_FAIL|CVT_BADTIME; 10454359Sroberto if (((u_char) recv_csum) != calc_csum) return CVT_FAIL|CVT_BADTIME; 10554359Sroberto 10654359Sroberto clock_time->utcoffset = 0; 10754359Sroberto 10854359Sroberto /* What should flags be set to ? */ 10954359Sroberto clock_time->flags = PARSEB_UTC; 11054359Sroberto 11154359Sroberto /* if the current GPS fix is 9 (unknown), reject */ 11254359Sroberto if (0 > gpsfix || gpsfix > 9) clock_time->flags |= PARSEB_POWERUP; 11354359Sroberto 11454359Sroberto return CVT_OK; 11554359Sroberto} 11654359Sroberto 11754359Sroberto/* 11854359Sroberto * inp_trimtaip 11954359Sroberto * 12054359Sroberto * grep data from input stream 12154359Sroberto */ 12254359Srobertostatic u_long 12354359Srobertoinp_trimtaip( 12454359Sroberto parse_t *parseio, 12554359Sroberto unsigned int ch, 12654359Sroberto timestamp_t *tstamp 12754359Sroberto ) 12854359Sroberto{ 12954359Sroberto unsigned int rtc; 13054359Sroberto 13154359Sroberto parseprintf(DD_PARSE, ("inp_trimtaip(0x%x, 0x%x, ...)\n", (int)parseio, (int)ch)); 13254359Sroberto 13354359Sroberto switch (ch) 13454359Sroberto { 13554359Sroberto case '>': 13654359Sroberto parseprintf(DD_PARSE, ("inp_trimptaip: START seen\n")); 13754359Sroberto 13854359Sroberto parseio->parse_index = 1; 13954359Sroberto parseio->parse_data[0] = ch; 14054359Sroberto parseio->parse_dtime.parse_stime = *tstamp; /* collect timestamp */ 14154359Sroberto return PARSE_INP_SKIP; 14254359Sroberto 14354359Sroberto case '<': 14454359Sroberto parseprintf(DD_PARSE, ("inp_trimtaip: END seen\n")); 14554359Sroberto if ((rtc = parse_addchar(parseio, ch)) == PARSE_INP_SKIP) 14654359Sroberto return parse_end(parseio); 14754359Sroberto else 14854359Sroberto return rtc; 14954359Sroberto 15054359Sroberto 15154359Sroberto default: 15254359Sroberto return parse_addchar(parseio, ch); 15354359Sroberto } 15454359Sroberto} 15554359Sroberto 15654359Sroberto#else /* not (REFCLOCK && CLOCK_PARSE && CLOCK_TRIMTAIP) */ 15754359Srobertoint clk_trimtaip_bs; 15854359Sroberto#endif /* not (REFCLOCK && CLOCK_PARSE && CLOCK_TRIMTAIP) */ 15954359Sroberto 16054359Sroberto/* 16154359Sroberto * History: 16254359Sroberto * 16354359Sroberto * clk_trimtaip.c,v 16454359Sroberto * Revision 4.6 1998/08/16 18:46:27 kardel 16554359Sroberto * (clock_trimtaip =): changed format name 16654359Sroberto * 16754359Sroberto * Revision 4.5 1998/06/14 21:09:38 kardel 16854359Sroberto * Sun acc cleanup 16954359Sroberto * 17054359Sroberto * Revision 4.4 1998/06/13 12:06:57 kardel 17154359Sroberto * fix SYSV clock name clash 17254359Sroberto * 17354359Sroberto * Revision 4.3 1998/06/12 15:22:29 kardel 17454359Sroberto * fix prototypes 17554359Sroberto * 17654359Sroberto * Revision 4.2 1998/06/12 09:13:26 kardel 17754359Sroberto * conditional compile macros fixed 17854359Sroberto * printf prototype 17954359Sroberto * 18054359Sroberto * Revision 4.1 1998/05/24 09:39:54 kardel 18154359Sroberto * implementation of the new IO handling model 18254359Sroberto * 18354359Sroberto * Revision 4.0 1998/04/10 19:45:31 kardel 18454359Sroberto * Start 4.0 release version numbering 18554359Sroberto * 18654359Sroberto * from V3 1.4 log info deleted 1998/04/11 kardel 18754359Sroberto */ 18854359Sroberto 189