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