1/*	$NetBSD: clk_dcf7000.c,v 1.6 2020/05/25 20:47:25 christos Exp $	*/
2
3/*
4 * /src/NTP/ntp4-dev/libparse/clk_dcf7000.c,v 4.10 2005/04/16 17:32:10 kardel RELEASE_20050508_A
5 *
6 * clk_dcf7000.c,v 4.10 2005/04/16 17:32:10 kardel RELEASE_20050508_A
7 *
8 * ELV DCF7000 module
9 *
10 * Copyright (c) 1995-2005 by Frank Kardel <kardel <AT> ntp.org>
11 * Copyright (c) 1989-1994 by Frank Kardel, Friedrich-Alexander Universitaet Erlangen-Nuernberg, Germany
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 * 1. Redistributions of source code must retain the above copyright
17 *    notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 *    notice, this list of conditions and the following disclaimer in the
20 *    documentation and/or other materials provided with the distribution.
21 * 3. Neither the name of the author nor the names of its contributors
22 *    may be used to endorse or promote products derived from this software
23 *    without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
36 *
37 */
38
39#ifdef HAVE_CONFIG_H
40# include <config.h>
41#endif
42
43#if defined(REFCLOCK) && defined(CLOCK_PARSE) && defined(CLOCK_DCF7000)
44
45#include "ntp_fp.h"
46#include "ntp_unixtime.h"
47#include "ntp_calendar.h"
48
49#include "parse.h"
50
51#ifndef PARSESTREAM
52#include "ntp_stdlib.h"
53#include <stdio.h>
54#else
55#include "sys/parsestreams.h"
56extern int printf (const char *, ...);
57#endif
58
59static struct format dcf7000_fmt =
60{				/* ELV DCF7000 */
61	{
62		{  6, 2}, {  3, 2}, {  0, 2},
63		{ 12, 2}, { 15, 2}, { 18, 2},
64		{  9, 2}, { 21, 2},
65	},
66	(const unsigned char *)"  -  -  -  -  -  -  -  \r",
67	0
68};
69
70static parse_cvt_fnc_t cvt_dcf7000;
71static parse_inp_fnc_t inp_dcf7000;
72
73clockformat_t clock_dcf7000 =
74{
75  inp_dcf7000,			/* DCF7000 input handling */
76  cvt_dcf7000,			/* ELV DCF77 conversion */
77  0,				/* no direct PPS monitoring */
78  (void *)&dcf7000_fmt,		/* conversion configuration */
79  "ELV DCF7000",		/* ELV clock */
80  24,				/* string buffer */
81  0				/* no private data (complete packets) */
82};
83
84/*
85 * parse_cvt_fnc_t cvt_dcf7000
86 *
87 * convert dcf7000 type format
88 */
89static u_long
90cvt_dcf7000(
91	    unsigned char *buffer,
92	    int            size,
93	    struct format *format,
94	    clocktime_t   *clock_time,
95	    void          *local
96	    )
97{
98	if (!Strok(buffer, format->fixed_string))
99	{
100		return CVT_NONE;
101	}
102	else
103	{
104		if (Stoi(&buffer[format->field_offsets[O_DAY].offset], &clock_time->day,
105			 format->field_offsets[O_DAY].length) ||
106		    Stoi(&buffer[format->field_offsets[O_MONTH].offset], &clock_time->month,
107			 format->field_offsets[O_MONTH].length) ||
108		    Stoi(&buffer[format->field_offsets[O_YEAR].offset], &clock_time->year,
109			 format->field_offsets[O_YEAR].length) ||
110		    Stoi(&buffer[format->field_offsets[O_HOUR].offset], &clock_time->hour,
111			 format->field_offsets[O_HOUR].length) ||
112		    Stoi(&buffer[format->field_offsets[O_MIN].offset], &clock_time->minute,
113			 format->field_offsets[O_MIN].length) ||
114		    Stoi(&buffer[format->field_offsets[O_SEC].offset], &clock_time->second,
115			 format->field_offsets[O_SEC].length))
116		{
117			return CVT_FAIL|CVT_BADFMT;
118		}
119		else
120		{
121			unsigned char *f = &buffer[format->field_offsets[O_FLAGS].offset];
122			long flags;
123
124			clock_time->flags = 0;
125			clock_time->usecond = 0;
126
127			if (Stoi(f, &flags, format->field_offsets[O_FLAGS].length))
128			{
129				return CVT_FAIL|CVT_BADFMT;
130			}
131			else
132			{
133				if (flags & 0x1)
134				    clock_time->utcoffset = -2*60*60;
135				else
136				    clock_time->utcoffset = -1*60*60;
137
138				if (flags & 0x2)
139				    clock_time->flags |= PARSEB_ANNOUNCE;
140
141				if (flags & 0x4)
142				    clock_time->flags |= PARSEB_NOSYNC;
143			}
144			return CVT_OK;
145		}
146	}
147}
148
149/*
150 * parse_inp_fnc_t inp_dcf700
151 *
152 * grab data from input stream
153 */
154static u_long
155inp_dcf7000(
156	  parse_t      *parseio,
157	  char         ch,
158	  timestamp_t  *tstamp
159	  )
160{
161	unsigned int rtc;
162
163	parseprintf(DD_PARSE, ("inp_dcf7000(0x%p, 0x%x, ...)\n", (void*)parseio, ch));
164
165	switch (ch)
166	{
167	case '\r':
168		parseprintf(DD_PARSE, ("inp_dcf7000: EOL seen\n"));
169		parseio->parse_dtime.parse_stime = *tstamp; /* collect timestamp */
170		if ((rtc = parse_addchar(parseio, ch)) == PARSE_INP_SKIP)
171			return parse_end(parseio);
172		else
173			return rtc;
174
175	default:
176		return parse_addchar(parseio, ch);
177	}
178}
179
180#else /* not (REFCLOCK && CLOCK_PARSE && CLOCK_DCF7000) */
181int clk_dcf7000_bs;
182#endif /* not (REFCLOCK && CLOCK_PARSE && CLOCK_DCF7000) */
183
184/*
185 * History:
186 *
187 * clk_dcf7000.c,v
188 * Revision 4.10  2005/04/16 17:32:10  kardel
189 * update copyright
190 *
191 * Revision 4.9  2004/11/14 15:29:41  kardel
192 * support PPSAPI, upgrade Copyright to Berkeley style
193 *
194 * Revision 4.6  1999/11/28 09:13:49  kardel
195 * RECON_4_0_98F
196 *
197 * Revision 4.5  1998/06/14 21:09:34  kardel
198 * Sun acc cleanup
199 *
200 * Revision 4.4  1998/06/13 12:01:59  kardel
201 * fix SYSV clock name clash
202 *
203 * Revision 4.3  1998/06/12 15:22:27  kardel
204 * fix prototypes
205 *
206 * Revision 4.2  1998/06/12 09:13:24  kardel
207 * conditional compile macros fixed
208 * printf prototype
209 *
210 * Revision 4.1  1998/05/24 09:39:51  kardel
211 * implementation of the new IO handling model
212 *
213 * Revision 4.0  1998/04/10 19:45:28  kardel
214 * Start 4.0 release version numbering
215 *
216 * from V3 3.18 log info deleted 1998/04/11 kardel
217 */
218