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