PageRenderTime 30ms CodeModel.GetById 19ms app.highlight 8ms RepoModel.GetById 1ms app.codeStats 0ms

/contrib/ntp/libparse/clk_rcc8000.c

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