1/* $NetBSD: clk_schmid.c,v 1.6 2020/05/25 20:47:25 christos Exp $ */ 2 3/* 4 * /src/NTP/ntp4-dev/libparse/clk_schmid.c,v 4.9 2005/04/16 17:32:10 kardel RELEASE_20050508_A 5 * 6 * clk_schmid.c,v 4.9 2005/04/16 17:32:10 kardel RELEASE_20050508_A 7 * 8 * Schmid clock support 9 * based on information and testing from Adam W. Feigin et. al (Swisstime iis.ethz.ch) 10 * 11 * Copyright (c) 1995-2015 by Frank Kardel <kardel <AT> ntp.org> 12 * Copyright (c) 1989-1994 by Frank Kardel, Friedrich-Alexander Universitaet Erlangen-Nuernberg, Germany 13 * 14 * Redistribution and use in source and binary forms, with or without 15 * modification, are permitted provided that the following conditions 16 * are met: 17 * 1. Redistributions of source code must retain the above copyright 18 * notice, this list of conditions and the following disclaimer. 19 * 2. Redistributions in binary form must reproduce the above copyright 20 * notice, this list of conditions and the following disclaimer in the 21 * documentation and/or other materials provided with the distribution. 22 * 3. Neither the name of the author nor the names of its contributors 23 * may be used to endorse or promote products derived from this software 24 * without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * SUCH DAMAGE. 37 * 38 */ 39 40#if HAVE_CONFIG_H 41# include <config.h> 42#endif 43 44#if defined(REFCLOCK) && defined(CLOCK_PARSE) && defined(CLOCK_SCHMID) 45 46#include "ntp_fp.h" 47#include "ntp_unixtime.h" 48#include "ntp_calendar.h" 49 50#include "parse.h" 51 52#ifndef PARSESTREAM 53#include "ntp_stdlib.h" 54#include <stdio.h> 55#else 56#include "sys/parsestreams.h" 57extern int printf (const char *, ...); 58#endif 59 60/* 61 * Description courtesy of Adam W. Feigin et. al (Swisstime iis.ethz.ch) 62 * 63 * The command to Schmid's DCF77 clock is a single byte; each bit 64 * allows the user to select some part of the time string, as follows (the 65 * output for the lsb is sent first). 66 * 67 * Bit 0: time in MEZ, 4 bytes *binary, not BCD*; hh.mm.ss.tenths 68 * Bit 1: date 3 bytes *binary, not BCD: dd.mm.yy 69 * Bit 2: week day, 1 byte (unused here) 70 * Bit 3: time zone, 1 byte, 0=MET, 1=MEST. (unused here) 71 * Bit 4: clock status, 1 byte, 0=time invalid, 72 * 1=time from crystal backup, 73 * 3=time from DCF77 74 * Bit 5: transmitter status, 1 byte, 75 * bit 0: backup antenna 76 * bit 1: time zone change within 1h 77 * bit 3,2: TZ 01=MEST, 10=MET 78 * bit 4: leap second will be 79 * added within one hour 80 * bits 5-7: Zero 81 * Bit 6: time in backup mode, units of 5 minutes (unused here) 82 * 83 */ 84#define WS_TIME 0x01 85#define WS_SIGNAL 0x02 86 87#define WS_CALLBIT 0x01 /* "call bit" used to signalize irregularities in the control facilities */ 88#define WS_ANNOUNCE 0x02 89#define WS_TZ 0x0c 90#define WS_MET 0x08 91#define WS_MEST 0x04 92#define WS_LEAP 0x10 93 94static parse_cvt_fnc_t cvt_schmid; 95static parse_inp_fnc_t inp_schmid; 96 97clockformat_t clock_schmid = 98{ 99 inp_schmid, /* no input handling */ 100 cvt_schmid, /* Schmid conversion */ 101 0, /* not direct PPS monitoring */ 102 0, /* conversion configuration */ 103 "Schmid", /* Schmid receiver */ 104 12, /* binary data buffer */ 105 0, /* no private data (complete messages) */ 106}; 107 108/* parse_cvt_fnc_t */ 109static u_long 110cvt_schmid( 111 unsigned char *buffer, 112 int size, 113 struct format *format, 114 clocktime_t *clock_time, 115 void *local 116 ) 117{ 118 if ((size != 11) || (buffer[10] != (unsigned char)'\375')) 119 { 120 return CVT_NONE; 121 } 122 else 123 { 124 if (buffer[0] > 23 || buffer[1] > 59 || buffer[2] > 59 || buffer[3] > 9) /* Time */ 125 { 126 return CVT_FAIL|CVT_BADTIME; 127 } 128 else 129 if (buffer[4] < 1 || buffer[4] > 31 || buffer[5] < 1 || buffer[5] > 12 130 || buffer[6] > 99) 131 { 132 return CVT_FAIL|CVT_BADDATE; 133 } 134 else 135 { 136 clock_time->hour = buffer[0]; 137 clock_time->minute = buffer[1]; 138 clock_time->second = buffer[2]; 139 clock_time->usecond = buffer[3] * 100000; 140 clock_time->day = buffer[4]; 141 clock_time->month = buffer[5]; 142 clock_time->year = buffer[6]; 143 144 clock_time->flags = 0; 145 146 switch (buffer[8] & WS_TZ) 147 { 148 case WS_MET: 149 clock_time->utcoffset = -1*60*60; 150 break; 151 152 case WS_MEST: 153 clock_time->utcoffset = -2*60*60; 154 clock_time->flags |= PARSEB_DST; 155 break; 156 157 default: 158 return CVT_FAIL|CVT_BADFMT; 159 } 160 161 if (!(buffer[7] & WS_TIME)) 162 { 163 clock_time->flags |= PARSEB_POWERUP; 164 } 165 166 if (!(buffer[7] & WS_SIGNAL)) 167 { 168 clock_time->flags |= PARSEB_NOSYNC; 169 } 170 171 if (buffer[7] & WS_SIGNAL) 172 { 173 if (buffer[8] & WS_CALLBIT) 174 { 175 clock_time->flags |= PARSEB_CALLBIT; 176 } 177 178 if (buffer[8] & WS_ANNOUNCE) 179 { 180 clock_time->flags |= PARSEB_ANNOUNCE; 181 } 182 183 if (buffer[8] & WS_LEAP) 184 { 185 clock_time->flags |= PARSEB_LEAPADD; /* default: DCF77 data format deficiency */ 186 } 187 } 188 189 clock_time->flags |= PARSEB_S_LEAP|PARSEB_S_CALLBIT; 190 191 return CVT_OK; 192 } 193 } 194} 195 196/* 197 * parse_inp_fnc_t inp_schmid 198 * 199 * grab data from input stream 200 */ 201static u_long 202inp_schmid( 203 parse_t *parseio, 204 char ch, 205 timestamp_t *tstamp 206 ) 207{ 208 unsigned int rtc; 209 210 parseprintf(DD_PARSE, ("inp_schmid(0x%p, 0x%x, ...)\n", (void*)parseio, ch)); 211 212 switch ((uint8_t)ch) 213 { 214 case 0xFD: /* */ 215 parseprintf(DD_PARSE, ("inp_schmid: 0xFD seen\n")); 216 if ((rtc = parse_addchar(parseio, ch)) == PARSE_INP_SKIP) 217 return parse_end(parseio); 218 else 219 return rtc; 220 221 default: 222 return parse_addchar(parseio, ch); 223 } 224} 225 226#else /* not (REFCLOCK && CLOCK_PARSE && CLOCK_SCHMID) */ 227int clk_schmid_bs; 228#endif /* not (REFCLOCK && CLOCK_PARSE && CLOCK_SCHMID) */ 229 230/* 231 * History: 232 * 233 * clk_schmid.c,v 234 * Revision 4.9 2005/04/16 17:32:10 kardel 235 * update copyright 236 * 237 * Revision 4.8 2004/11/14 15:29:41 kardel 238 * support PPSAPI, upgrade Copyright to Berkeley style 239 * 240 * Revision 4.5 1999/11/28 09:13:51 kardel 241 * RECON_4_0_98F 242 * 243 * Revision 4.4 1998/06/13 12:06:03 kardel 244 * fix SYSV clock name clash 245 * 246 * Revision 4.3 1998/06/12 15:22:29 kardel 247 * fix prototypes 248 * 249 * Revision 4.2 1998/06/12 09:13:26 kardel 250 * conditional compile macros fixed 251 * printf prototype 252 * 253 * Revision 4.1 1998/05/24 09:39:53 kardel 254 * implementation of the new IO handling model 255 * 256 * Revision 4.0 1998/04/10 19:45:31 kardel 257 * Start 4.0 release version numbering 258 * 259 * from V3 3.22 log info deleted 1998/04/11 kardel 260 */ 261