154359Sroberto/*
2182007Sroberto * /src/NTP/ntp4-dev/libparse/clk_dcf7000.c,v 4.10 2005/04/16 17:32:10 kardel RELEASE_20050508_A
3282408Scy *
4182007Sroberto * clk_dcf7000.c,v 4.10 2005/04/16 17:32:10 kardel RELEASE_20050508_A
554359Sroberto *
654359Sroberto * ELV DCF7000 module
754359Sroberto *
8182007Sroberto * Copyright (c) 1995-2005 by Frank Kardel <kardel <AT> ntp.org>
9282408Scy * Copyright (c) 1989-1994 by Frank Kardel, Friedrich-Alexander Universitaet Erlangen-Nuernberg, Germany
1054359Sroberto *
11182007Sroberto * Redistribution and use in source and binary forms, with or without
12182007Sroberto * modification, are permitted provided that the following conditions
13182007Sroberto * are met:
14182007Sroberto * 1. Redistributions of source code must retain the above copyright
15182007Sroberto *    notice, this list of conditions and the following disclaimer.
16182007Sroberto * 2. Redistributions in binary form must reproduce the above copyright
17182007Sroberto *    notice, this list of conditions and the following disclaimer in the
18182007Sroberto *    documentation and/or other materials provided with the distribution.
19182007Sroberto * 3. Neither the name of the author nor the names of its contributors
20182007Sroberto *    may be used to endorse or promote products derived from this software
21182007Sroberto *    without specific prior written permission.
22182007Sroberto *
23182007Sroberto * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
24182007Sroberto * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25182007Sroberto * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26182007Sroberto * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
27182007Sroberto * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28182007Sroberto * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29182007Sroberto * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30182007Sroberto * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31182007Sroberto * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32182007Sroberto * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33182007Sroberto * SUCH DAMAGE.
34182007Sroberto *
3554359Sroberto */
3654359Sroberto
3754359Sroberto#ifdef HAVE_CONFIG_H
3854359Sroberto# include <config.h>
3954359Sroberto#endif
4054359Sroberto
4154359Sroberto#if defined(REFCLOCK) && defined(CLOCK_PARSE) && defined(CLOCK_DCF7000)
4254359Sroberto
4354359Sroberto#include "ntp_fp.h"
4454359Sroberto#include "ntp_unixtime.h"
4554359Sroberto#include "ntp_calendar.h"
4654359Sroberto
4754359Sroberto#include "parse.h"
4854359Sroberto
4954359Sroberto#ifndef PARSESTREAM
5054359Sroberto#include "ntp_stdlib.h"
5154359Sroberto#include <stdio.h>
5254359Sroberto#else
5354359Sroberto#include "sys/parsestreams.h"
54280849Scyextern int printf (const char *, ...);
5554359Sroberto#endif
5654359Sroberto
5754359Srobertostatic struct format dcf7000_fmt =
5854359Sroberto{				/* ELV DCF7000 */
5954359Sroberto	{
6054359Sroberto		{  6, 2}, {  3, 2}, {  0, 2},
6154359Sroberto		{ 12, 2}, { 15, 2}, { 18, 2},
6254359Sroberto		{  9, 2}, { 21, 2},
6354359Sroberto	},
6454359Sroberto	(const unsigned char *)"  -  -  -  -  -  -  -  \r",
6554359Sroberto	0
66282408Scy};
6754359Sroberto
68282408Scystatic parse_cvt_fnc_t cvt_dcf7000;
69282408Scystatic parse_inp_fnc_t inp_dcf7000;
70282408Scy
7154359Srobertoclockformat_t clock_dcf7000 =
7254359Sroberto{
7354359Sroberto  inp_dcf7000,			/* DCF7000 input handling */
7454359Sroberto  cvt_dcf7000,			/* ELV DCF77 conversion */
7554359Sroberto  0,				/* no direct PPS monitoring */
7654359Sroberto  (void *)&dcf7000_fmt,		/* conversion configuration */
7754359Sroberto  "ELV DCF7000",		/* ELV clock */
7854359Sroberto  24,				/* string buffer */
79282408Scy  0				/* no private data (complete packets) */
8054359Sroberto};
8154359Sroberto
8254359Sroberto/*
83282408Scy * parse_cvt_fnc_t cvt_dcf7000
8454359Sroberto *
8554359Sroberto * convert dcf7000 type format
8654359Sroberto */
8754359Srobertostatic u_long
8854359Srobertocvt_dcf7000(
8954359Sroberto	    unsigned char *buffer,
9054359Sroberto	    int            size,
9154359Sroberto	    struct format *format,
9254359Sroberto	    clocktime_t   *clock_time,
9354359Sroberto	    void          *local
9454359Sroberto	    )
9554359Sroberto{
9654359Sroberto	if (!Strok(buffer, format->fixed_string))
9754359Sroberto	{
9854359Sroberto		return CVT_NONE;
9954359Sroberto	}
10054359Sroberto	else
10154359Sroberto	{
10254359Sroberto		if (Stoi(&buffer[format->field_offsets[O_DAY].offset], &clock_time->day,
10354359Sroberto			 format->field_offsets[O_DAY].length) ||
10454359Sroberto		    Stoi(&buffer[format->field_offsets[O_MONTH].offset], &clock_time->month,
10554359Sroberto			 format->field_offsets[O_MONTH].length) ||
10654359Sroberto		    Stoi(&buffer[format->field_offsets[O_YEAR].offset], &clock_time->year,
10754359Sroberto			 format->field_offsets[O_YEAR].length) ||
10854359Sroberto		    Stoi(&buffer[format->field_offsets[O_HOUR].offset], &clock_time->hour,
10954359Sroberto			 format->field_offsets[O_HOUR].length) ||
11054359Sroberto		    Stoi(&buffer[format->field_offsets[O_MIN].offset], &clock_time->minute,
11154359Sroberto			 format->field_offsets[O_MIN].length) ||
11254359Sroberto		    Stoi(&buffer[format->field_offsets[O_SEC].offset], &clock_time->second,
11354359Sroberto			 format->field_offsets[O_SEC].length))
11454359Sroberto		{
11554359Sroberto			return CVT_FAIL|CVT_BADFMT;
11654359Sroberto		}
11754359Sroberto		else
11854359Sroberto		{
11954359Sroberto			unsigned char *f = &buffer[format->field_offsets[O_FLAGS].offset];
12054359Sroberto			long flags;
121282408Scy
12254359Sroberto			clock_time->flags = 0;
12354359Sroberto			clock_time->usecond = 0;
12454359Sroberto
12554359Sroberto			if (Stoi(f, &flags, format->field_offsets[O_FLAGS].length))
12654359Sroberto			{
12754359Sroberto				return CVT_FAIL|CVT_BADFMT;
12854359Sroberto			}
12954359Sroberto			else
13054359Sroberto			{
13154359Sroberto				if (flags & 0x1)
13254359Sroberto				    clock_time->utcoffset = -2*60*60;
13354359Sroberto				else
13454359Sroberto				    clock_time->utcoffset = -1*60*60;
13554359Sroberto
13654359Sroberto				if (flags & 0x2)
13754359Sroberto				    clock_time->flags |= PARSEB_ANNOUNCE;
13854359Sroberto
13954359Sroberto				if (flags & 0x4)
14054359Sroberto				    clock_time->flags |= PARSEB_NOSYNC;
14154359Sroberto			}
14254359Sroberto			return CVT_OK;
14354359Sroberto		}
14454359Sroberto	}
14554359Sroberto}
14654359Sroberto
14754359Sroberto/*
148282408Scy * parse_inp_fnc_t inp_dcf700
14954359Sroberto *
150282408Scy * grab data from input stream
15154359Sroberto */
15254359Srobertostatic u_long
15354359Srobertoinp_dcf7000(
15454359Sroberto	  parse_t      *parseio,
155282408Scy	  char         ch,
15654359Sroberto	  timestamp_t  *tstamp
15754359Sroberto	  )
15854359Sroberto{
15954359Sroberto	unsigned int rtc;
160282408Scy
161293423Sdelphij	parseprintf(DD_PARSE, ("inp_dcf7000(0x%p, 0x%x, ...)\n", (void*)parseio, ch));
162282408Scy
16354359Sroberto	switch (ch)
16454359Sroberto	{
16554359Sroberto	case '\r':
16654359Sroberto		parseprintf(DD_PARSE, ("inp_dcf7000: EOL seen\n"));
16754359Sroberto		parseio->parse_dtime.parse_stime = *tstamp; /* collect timestamp */
16854359Sroberto		if ((rtc = parse_addchar(parseio, ch)) == PARSE_INP_SKIP)
16954359Sroberto			return parse_end(parseio);
17054359Sroberto		else
17154359Sroberto			return rtc;
17254359Sroberto
17354359Sroberto	default:
17454359Sroberto		return parse_addchar(parseio, ch);
17554359Sroberto	}
17654359Sroberto}
17754359Sroberto
17854359Sroberto#else /* not (REFCLOCK && CLOCK_PARSE && CLOCK_DCF7000) */
17954359Srobertoint clk_dcf7000_bs;
18054359Sroberto#endif /* not (REFCLOCK && CLOCK_PARSE && CLOCK_DCF7000) */
18154359Sroberto
18254359Sroberto/*
18354359Sroberto * History:
18454359Sroberto *
18554359Sroberto * clk_dcf7000.c,v
186182007Sroberto * Revision 4.10  2005/04/16 17:32:10  kardel
187182007Sroberto * update copyright
188182007Sroberto *
189182007Sroberto * Revision 4.9  2004/11/14 15:29:41  kardel
190182007Sroberto * support PPSAPI, upgrade Copyright to Berkeley style
191182007Sroberto *
19256746Sroberto * Revision 4.6  1999/11/28 09:13:49  kardel
19356746Sroberto * RECON_4_0_98F
19456746Sroberto *
19554359Sroberto * Revision 4.5  1998/06/14 21:09:34  kardel
19654359Sroberto * Sun acc cleanup
19754359Sroberto *
19854359Sroberto * Revision 4.4  1998/06/13 12:01:59  kardel
19954359Sroberto * fix SYSV clock name clash
20054359Sroberto *
20154359Sroberto * Revision 4.3  1998/06/12 15:22:27  kardel
20254359Sroberto * fix prototypes
20354359Sroberto *
20454359Sroberto * Revision 4.2  1998/06/12 09:13:24  kardel
20554359Sroberto * conditional compile macros fixed
20654359Sroberto * printf prototype
20754359Sroberto *
20854359Sroberto * Revision 4.1  1998/05/24 09:39:51  kardel
20954359Sroberto * implementation of the new IO handling model
21054359Sroberto *
21154359Sroberto * Revision 4.0  1998/04/10 19:45:28  kardel
21254359Sroberto * Start 4.0 release version numbering
21354359Sroberto *
21454359Sroberto * from V3 3.18 log info deleted 1998/04/11 kardel
21554359Sroberto */
216