1c0b746e5SOllivier Robert /* 2a151a66cSOllivier Robert * /src/NTP/ntp-4/libparse/clk_rcc8000.c,v 4.6 1999/11/28 09:13:51 kardel RELEASE_19991128_A 3c0b746e5SOllivier Robert * 4a151a66cSOllivier Robert * clk_rcc8000.c,v 4.6 1999/11/28 09:13:51 kardel RELEASE_19991128_A 5c0b746e5SOllivier Robert * 6c0b746e5SOllivier Robert * Radiocode Clocks Ltd RCC 8000 Intelligent Off-Air Master Clock support 7c0b746e5SOllivier Robert * 8c0b746e5SOllivier Robert * Created by R.E.Broughton from clk_trimtaip.c 9c0b746e5SOllivier Robert * 10c0b746e5SOllivier Robert * This program is distributed in the hope that it will be useful, 11c0b746e5SOllivier Robert * but WITHOUT ANY WARRANTY; without even the implied warranty of 12c0b746e5SOllivier Robert * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 13c0b746e5SOllivier Robert * 14c0b746e5SOllivier Robert */ 15c0b746e5SOllivier Robert 16c0b746e5SOllivier Robert #if HAVE_CONFIG_H 17c0b746e5SOllivier Robert # include <config.h> 18c0b746e5SOllivier Robert #endif 19c0b746e5SOllivier Robert 20c0b746e5SOllivier Robert #if defined(REFCLOCK) && defined(CLOCK_PARSE) && defined(CLOCK_RCC8000) 21c0b746e5SOllivier Robert 22c0b746e5SOllivier Robert #include <sys/types.h> 23c0b746e5SOllivier Robert #include <sys/time.h> 24c0b746e5SOllivier Robert 25c0b746e5SOllivier Robert #include "ntp_fp.h" 26c0b746e5SOllivier Robert #include "ntp_unixtime.h" 27c0b746e5SOllivier Robert #include "ntp_calendar.h" 28c0b746e5SOllivier Robert 29c0b746e5SOllivier Robert #include "parse.h" 30c0b746e5SOllivier Robert 31c0b746e5SOllivier Robert #ifndef PARSESTREAM 32c0b746e5SOllivier Robert #include "ntp_stdlib.h" 33c0b746e5SOllivier Robert #include <stdio.h> 34c0b746e5SOllivier Robert #else 35c0b746e5SOllivier Robert #include "sys/parsestreams.h" 36c0b746e5SOllivier Robert extern void printf P((const char *, ...)); 37c0b746e5SOllivier Robert #endif 38c0b746e5SOllivier Robert 39c0b746e5SOllivier Robert /* Type II Serial Output format 40c0b746e5SOllivier Robert * 41c0b746e5SOllivier Robert * 0000000000111111111122222222223 / char 42c0b746e5SOllivier Robert * 0123456789012345678901234567890 \ posn 43c0b746e5SOllivier Robert * HH:MM:SS.XYZ DD/MM/YY DDD W Prn Actual 44c0b746e5SOllivier Robert * 33 44 55 666 00 11 22 7 Parse 45c0b746e5SOllivier Robert * : : . / / rn Check 46c0b746e5SOllivier Robert * "15:50:36.534 30/09/94 273 5 A\x0d\x0a" 47c0b746e5SOllivier Robert * 48c0b746e5SOllivier Robert * DDD - Day of year number 49c0b746e5SOllivier Robert * W - Day of week number (Sunday is 0) 50c0b746e5SOllivier Robert * P is the Status. See comment below for details. 51c0b746e5SOllivier Robert */ 52c0b746e5SOllivier Robert 53c0b746e5SOllivier Robert #define O_USEC O_WDAY 54c0b746e5SOllivier Robert static struct format rcc8000_fmt = 55c0b746e5SOllivier Robert { { { 13, 2 }, {16, 2}, { 19, 2}, /* Day, Month, Year */ 56c0b746e5SOllivier Robert { 0, 2 }, { 3, 2}, { 6, 2}, /* Hour, Minute, Second */ 57c0b746e5SOllivier Robert { 9, 3 }, {28, 1}, { 0, 0}, /* uSec, Status (Valid,Reject,BST,Leapyear) */ }, 58c0b746e5SOllivier Robert (const unsigned char *)" : : . / / \r\n", 59c0b746e5SOllivier Robert /*"15:50:36.534 30/09/94 273 5 A\x0d\x0a" */ 60c0b746e5SOllivier Robert 0 61c0b746e5SOllivier Robert }; 62c0b746e5SOllivier Robert 63c0b746e5SOllivier Robert static unsigned long cvt_rcc8000 P((unsigned char *, int, struct format *, clocktime_t *, void *)); 64c0b746e5SOllivier Robert static unsigned long inp_rcc8000 P((parse_t *, unsigned int, timestamp_t *)); 65c0b746e5SOllivier Robert 66c0b746e5SOllivier Robert clockformat_t clock_rcc8000 = 67c0b746e5SOllivier Robert { 68c0b746e5SOllivier Robert inp_rcc8000, /* no input handling */ 69c0b746e5SOllivier Robert cvt_rcc8000, /* Radiocode clock conversion */ 70c0b746e5SOllivier Robert 0, /* no direct PPS monitoring */ 71c0b746e5SOllivier Robert (void *)&rcc8000_fmt, /* conversion configuration */ 72c0b746e5SOllivier Robert "Radiocode RCC8000", 73c0b746e5SOllivier Robert 31, /* string buffer */ 74c0b746e5SOllivier Robert 0 /* no private data */ 75c0b746e5SOllivier Robert }; 76c0b746e5SOllivier Robert 77c0b746e5SOllivier Robert static unsigned long 78c0b746e5SOllivier Robert cvt_rcc8000( 79c0b746e5SOllivier Robert unsigned char *buffer, 80c0b746e5SOllivier Robert int size, 81c0b746e5SOllivier Robert struct format *format, 82c0b746e5SOllivier Robert clocktime_t *clock_time, 83c0b746e5SOllivier Robert void *local 84c0b746e5SOllivier Robert ) 85c0b746e5SOllivier Robert { 86c0b746e5SOllivier Robert if (!Strok(buffer, format->fixed_string)) return CVT_NONE; 87c0b746e5SOllivier Robert #define OFFS(x) format->field_offsets[(x)].offset 88c0b746e5SOllivier Robert #define STOI(x, y) Stoi(&buffer[OFFS(x)], y, format->field_offsets[(x)].length) 89c0b746e5SOllivier Robert if ( STOI(O_DAY, &clock_time->day) || 90c0b746e5SOllivier Robert STOI(O_MONTH, &clock_time->month) || 91c0b746e5SOllivier Robert STOI(O_YEAR, &clock_time->year) || 92c0b746e5SOllivier Robert STOI(O_HOUR, &clock_time->hour) || 93c0b746e5SOllivier Robert STOI(O_MIN, &clock_time->minute) || 94c0b746e5SOllivier Robert STOI(O_SEC, &clock_time->second) || 95c0b746e5SOllivier Robert STOI(O_USEC, &clock_time->usecond) 96c0b746e5SOllivier Robert ) return CVT_FAIL|CVT_BADFMT; 97c0b746e5SOllivier Robert clock_time->usecond *= 1000; 98c0b746e5SOllivier Robert 99c0b746e5SOllivier Robert clock_time->utcoffset = 0; 100c0b746e5SOllivier Robert 101c0b746e5SOllivier Robert #define RCCP buffer[28] 102c0b746e5SOllivier Robert /* 103c0b746e5SOllivier Robert * buffer[28] is the ASCII representation of a hex character ( 0 through F ) 104c0b746e5SOllivier Robert * The four bits correspond to: 105c0b746e5SOllivier Robert * 8 - Valid Time 106c0b746e5SOllivier Robert * 4 - Reject Code 107c0b746e5SOllivier Robert * 2 - British Summer Time (receiver set to emit GMT all year.) 108c0b746e5SOllivier Robert * 1 - Leap year 109c0b746e5SOllivier Robert */ 110c0b746e5SOllivier Robert #define RCC8000_VALID 0x8 111c0b746e5SOllivier Robert #define RCC8000_REJECT 0x4 112c0b746e5SOllivier Robert #define RCC8000_BST 0x2 113c0b746e5SOllivier Robert #define RCC8000_LEAPY 0x1 114c0b746e5SOllivier Robert 115c0b746e5SOllivier Robert clock_time->flags = 0; 116c0b746e5SOllivier Robert 117c0b746e5SOllivier Robert if ( (RCCP >= '0' && RCCP <= '9') || (RCCP >= 'A' && RCCP <= 'F') ) 118c0b746e5SOllivier Robert { 119c0b746e5SOllivier Robert register int flag; 120c0b746e5SOllivier Robert 121c0b746e5SOllivier Robert flag = (RCCP >= '0' && RCCP <= '9' ) ? RCCP - '0' : RCCP - 'A' + 10; 122c0b746e5SOllivier Robert 123c0b746e5SOllivier Robert if (!(flag & RCC8000_VALID)) 124c0b746e5SOllivier Robert clock_time->flags |= PARSEB_POWERUP; 125c0b746e5SOllivier Robert 126c0b746e5SOllivier Robert clock_time->flags |= PARSEB_UTC; /* British special - guess why 8-) */ 127c0b746e5SOllivier Robert 128c0b746e5SOllivier Robert /* other flags not used */ 129c0b746e5SOllivier Robert } 130c0b746e5SOllivier Robert return CVT_OK; 131c0b746e5SOllivier Robert } 132c0b746e5SOllivier Robert /* 133c0b746e5SOllivier Robert * inp_rcc8000 134c0b746e5SOllivier Robert * 135c0b746e5SOllivier Robert * grep data from input stream 136c0b746e5SOllivier Robert */ 137c0b746e5SOllivier Robert static u_long 138c0b746e5SOllivier Robert inp_rcc8000( 139c0b746e5SOllivier Robert parse_t *parseio, 140c0b746e5SOllivier Robert unsigned int ch, 141c0b746e5SOllivier Robert timestamp_t *tstamp 142c0b746e5SOllivier Robert ) 143c0b746e5SOllivier Robert { 144c0b746e5SOllivier Robert unsigned int rtc; 145c0b746e5SOllivier Robert 146c0b746e5SOllivier Robert parseprintf(DD_PARSE, ("inp_rcc8000(0x%x, 0x%x, ...)\n", (int)parseio, (int)ch)); 147c0b746e5SOllivier Robert 148c0b746e5SOllivier Robert switch (ch) 149c0b746e5SOllivier Robert { 150c0b746e5SOllivier Robert case '\n': 151c0b746e5SOllivier Robert parseprintf(DD_PARSE, ("inp_rcc8000: EOL seen\n")); 152c0b746e5SOllivier Robert if ((rtc = parse_addchar(parseio, ch)) == PARSE_INP_SKIP) 153c0b746e5SOllivier Robert return parse_end(parseio); 154c0b746e5SOllivier Robert else 155c0b746e5SOllivier Robert return rtc; 156c0b746e5SOllivier Robert 157c0b746e5SOllivier Robert 158c0b746e5SOllivier Robert default: 159c0b746e5SOllivier Robert if (parseio->parse_index == 0) /* take sample at start of message */ 160c0b746e5SOllivier Robert { 161c0b746e5SOllivier Robert parseio->parse_dtime.parse_stime = *tstamp; /* collect timestamp */ 162c0b746e5SOllivier Robert } 163c0b746e5SOllivier Robert return parse_addchar(parseio, ch); 164c0b746e5SOllivier Robert } 165c0b746e5SOllivier Robert } 166c0b746e5SOllivier Robert 167c0b746e5SOllivier Robert #else /* not (REFCLOCK && CLOCK_PARSE && CLOCK_RCC8000) */ 168c0b746e5SOllivier Robert int clk_rcc8000_bs; 169c0b746e5SOllivier Robert #endif /* not (REFCLOCK && CLOCK_PARSE && CLOCK_RCC8000) */ 170c0b746e5SOllivier Robert 171c0b746e5SOllivier Robert /* 172c0b746e5SOllivier Robert * History: 173c0b746e5SOllivier Robert * 174c0b746e5SOllivier Robert * clk_rcc8000.c,v 175a151a66cSOllivier Robert * Revision 4.6 1999/11/28 09:13:51 kardel 176a151a66cSOllivier Robert * RECON_4_0_98F 177a151a66cSOllivier Robert * 178c0b746e5SOllivier Robert * Revision 4.5 1998/06/14 21:09:38 kardel 179c0b746e5SOllivier Robert * Sun acc cleanup 180c0b746e5SOllivier Robert * 181c0b746e5SOllivier Robert * Revision 4.4 1998/06/13 12:05:02 kardel 182c0b746e5SOllivier Robert * fix SYSV clock name clash 183c0b746e5SOllivier Robert * 184c0b746e5SOllivier Robert * Revision 4.3 1998/06/12 15:22:29 kardel 185c0b746e5SOllivier Robert * fix prototypes 186c0b746e5SOllivier Robert * 187c0b746e5SOllivier Robert * Revision 4.2 1998/06/12 09:13:25 kardel 188c0b746e5SOllivier Robert * conditional compile macros fixed 189c0b746e5SOllivier Robert * printf prototype 190c0b746e5SOllivier Robert * 191c0b746e5SOllivier Robert * Revision 4.1 1998/05/24 09:39:53 kardel 192c0b746e5SOllivier Robert * implementation of the new IO handling model 193c0b746e5SOllivier Robert * 194c0b746e5SOllivier Robert * Revision 4.0 1998/04/10 19:45:30 kardel 195c0b746e5SOllivier Robert * Start 4.0 release version numbering 196c0b746e5SOllivier Robert * 197c0b746e5SOllivier Robert * from V3 3.5 log info deleted 1998/04/11 kardel 198c0b746e5SOllivier Robert */ 199