clk_schmid.c revision 56746
1169691Skan/* 2169691Skan * /src/NTP/ntp-4/libparse/clk_schmid.c,v 4.5 1999/11/28 09:13:51 kardel RELEASE_19991128_A 3169691Skan * 4169691Skan * clk_schmid.c,v 4.5 1999/11/28 09:13:51 kardel RELEASE_19991128_A 5169691Skan * 6169691Skan * Schmid clock support 7169691Skan * 8169691Skan * Copyright (C) 1992-1998 by Frank Kardel 9169691Skan * Friedrich-Alexander Universit�t Erlangen-N�rnberg, Germany 10169691Skan * 11169691Skan * This program is distributed in the hope that it will be useful, 12169691Skan * but WITHOUT ANY WARRANTY; without even the implied warranty of 13169691Skan * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 14169691Skan * 15169691Skan */ 16169691Skan 17169691Skan#if HAVE_CONFIG_H 18169691Skan# include <config.h> 19169691Skan#endif 20169691Skan 21169691Skan#if defined(REFCLOCK) && defined(CLOCK_PARSE) && defined(CLOCK_SCHMID) 22169691Skan 23169691Skan#include <sys/types.h> 24169691Skan#include <sys/time.h> 25169691Skan 26169691Skan#include "ntp_fp.h" 27169691Skan#include "ntp_unixtime.h" 28169691Skan#include "ntp_calendar.h" 29169691Skan 30169691Skan#include "parse.h" 31169691Skan 32169691Skan#ifndef PARSESTREAM 33169691Skan#include "ntp_stdlib.h" 34169691Skan#include <stdio.h> 35169691Skan#else 36169691Skan#include "sys/parsestreams.h" 37169691Skanextern void printf P((const char *, ...)); 38169691Skan#endif 39169691Skan 40169691Skan/* 41169691Skan * Description courtesy of Adam W. Feigin et. al (Swisstime iis.ethz.ch) 42169691Skan * 43169691Skan * The command to Schmid's DCF77 clock is a single byte; each bit 44169691Skan * allows the user to select some part of the time string, as follows (the 45228780Spfg * output for the lsb is sent first). 46169691Skan * 47169691Skan * Bit 0: time in MEZ, 4 bytes *binary, not BCD*; hh.mm.ss.tenths 48169691Skan * Bit 1: date 3 bytes *binary, not BCD: dd.mm.yy 49169691Skan * Bit 2: week day, 1 byte (unused here) 50169691Skan * Bit 3: time zone, 1 byte, 0=MET, 1=MEST. (unused here) 51169691Skan * Bit 4: clock status, 1 byte, 0=time invalid, 52169691Skan * 1=time from crystal backup, 53169691Skan * 3=time from DCF77 54169691Skan * Bit 5: transmitter status, 1 byte, 55169691Skan * bit 0: backup antenna 56169691Skan * bit 1: time zone change within 1h 57169691Skan * bit 3,2: TZ 01=MEST, 10=MET 58169691Skan * bit 4: leap second will be 59169691Skan * added within one hour 60169691Skan * bits 5-7: Zero 61169691Skan * Bit 6: time in backup mode, units of 5 minutes (unused here) 62169691Skan * 63169691Skan */ 64169691Skan#define WS_TIME 0x01 65169691Skan#define WS_SIGNAL 0x02 66169691Skan 67169691Skan#define WS_ALTERNATE 0x01 68169691Skan#define WS_ANNOUNCE 0x02 69169691Skan#define WS_TZ 0x0c 70169691Skan#define WS_MET 0x08 71169691Skan#define WS_MEST 0x04 72169691Skan#define WS_LEAP 0x10 73169691Skan 74169691Skanstatic u_long cvt_schmid P((unsigned char *, int, struct format *, clocktime_t *, void *)); 75169691Skanstatic unsigned long inp_schmid P((parse_t *, unsigned int, timestamp_t *)); 76169691Skan 77169691Skanclockformat_t clock_schmid = 78169691Skan{ 79169691Skan inp_schmid, /* no input handling */ 80169691Skan cvt_schmid, /* Schmid conversion */ 81169691Skan 0, /* not direct PPS monitoring */ 82169691Skan 0, /* conversion configuration */ 83169691Skan "Schmid", /* Schmid receiver */ 84169691Skan 12, /* binary data buffer */ 85169691Skan 0, /* no private data (complete messages) */ 86169691Skan}; 87169691Skan 88169691Skan 89169691Skanstatic u_long 90169691Skancvt_schmid( 91169691Skan unsigned char *buffer, 92169691Skan int size, 93169691Skan struct format *format, 94169691Skan clocktime_t *clock_time, 95169691Skan void *local 96169691Skan ) 97169691Skan{ 98169691Skan if ((size != 11) || (buffer[10] != (unsigned char)'\375')) 99169691Skan { 100169691Skan return CVT_NONE; 101169691Skan } 102169691Skan else 103169691Skan { 104169691Skan if (buffer[0] > 23 || buffer[1] > 59 || buffer[2] > 59 || buffer[3] > 9) /* Time */ 105169691Skan { 106169691Skan return CVT_FAIL|CVT_BADTIME; 107169691Skan } 108169691Skan else 109169691Skan if (buffer[4] < 1 || buffer[4] > 31 || buffer[5] < 1 || buffer[5] > 12 110169691Skan || buffer[6] > 99) 111169691Skan { 112169691Skan return CVT_FAIL|CVT_BADDATE; 113169691Skan } 114169691Skan else 115169691Skan { 116169691Skan clock_time->hour = buffer[0]; 117169691Skan clock_time->minute = buffer[1]; 118169691Skan clock_time->second = buffer[2]; 119 clock_time->usecond = buffer[3] * 100000; 120 clock_time->day = buffer[4]; 121 clock_time->month = buffer[5]; 122 clock_time->year = buffer[6]; 123 124 clock_time->flags = 0; 125 126 switch (buffer[8] & WS_TZ) 127 { 128 case WS_MET: 129 clock_time->utcoffset = -1*60*60; 130 break; 131 132 case WS_MEST: 133 clock_time->utcoffset = -2*60*60; 134 clock_time->flags |= PARSEB_DST; 135 break; 136 137 default: 138 return CVT_FAIL|CVT_BADFMT; 139 } 140 141 if (!(buffer[7] & WS_TIME)) 142 { 143 clock_time->flags |= PARSEB_POWERUP; 144 } 145 146 if (!(buffer[7] & WS_SIGNAL)) 147 { 148 clock_time->flags |= PARSEB_NOSYNC; 149 } 150 151 if (buffer[7] & WS_SIGNAL) 152 { 153 if (buffer[8] & WS_ALTERNATE) 154 { 155 clock_time->flags |= PARSEB_ALTERNATE; 156 } 157 158 if (buffer[8] & WS_ANNOUNCE) 159 { 160 clock_time->flags |= PARSEB_ANNOUNCE; 161 } 162 163 if (buffer[8] & WS_LEAP) 164 { 165 clock_time->flags |= PARSEB_LEAPADD; /* default: DCF77 data format deficiency */ 166 } 167 } 168 169 clock_time->flags |= PARSEB_S_LEAP|PARSEB_S_ANTENNA; 170 171 return CVT_OK; 172 } 173 } 174} 175 176/* 177 * inp_schmid 178 * 179 * grep data from input stream 180 */ 181static u_long 182inp_schmid( 183 parse_t *parseio, 184 unsigned int ch, 185 timestamp_t *tstamp 186 ) 187{ 188 unsigned int rtc; 189 190 parseprintf(DD_PARSE, ("inp_schmid(0x%x, 0x%x, ...)\n", (int)parseio, (int)ch)); 191 192 switch (ch) 193 { 194 case 0xFD: /* */ 195 parseprintf(DD_PARSE, ("mbg_input: ETX seen\n")); 196 if ((rtc = parse_addchar(parseio, ch)) == PARSE_INP_SKIP) 197 return parse_end(parseio); 198 else 199 return rtc; 200 201 default: 202 return parse_addchar(parseio, ch); 203 } 204} 205 206#else /* not (REFCLOCK && CLOCK_PARSE && CLOCK_SCHMID) */ 207int clk_schmid_bs; 208#endif /* not (REFCLOCK && CLOCK_PARSE && CLOCK_SCHMID) */ 209 210/* 211 * History: 212 * 213 * clk_schmid.c,v 214 * Revision 4.5 1999/11/28 09:13:51 kardel 215 * RECON_4_0_98F 216 * 217 * Revision 4.4 1998/06/13 12:06:03 kardel 218 * fix SYSV clock name clash 219 * 220 * Revision 4.3 1998/06/12 15:22:29 kardel 221 * fix prototypes 222 * 223 * Revision 4.2 1998/06/12 09:13:26 kardel 224 * conditional compile macros fixed 225 * printf prototype 226 * 227 * Revision 4.1 1998/05/24 09:39:53 kardel 228 * implementation of the new IO handling model 229 * 230 * Revision 4.0 1998/04/10 19:45:31 kardel 231 * Start 4.0 release version numbering 232 * 233 * from V3 3.22 log info deleted 1998/04/11 kardel 234 */ 235