1 /*        $NetBSD: clk_dcf7000.c,v 1.7 2024/08/18 20:47:17 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"
56 extern int printf (const char *, ...);
57 #endif
58 
59 static 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 
70 static parse_cvt_fnc_t cvt_dcf7000;
71 static parse_inp_fnc_t inp_dcf7000;
72 
73 clockformat_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  */
89 static u_long
cvt_dcf7000(unsigned char * buffer,int size,struct format * format,clocktime_t * clock_time,void * local)90 cvt_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  */
154 static u_long
inp_dcf7000(parse_t * parseio,char ch,timestamp_t * tstamp)155 inp_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) */
181 NONEMPTY_TRANSLATION_UNIT
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