154359Sroberto/* 2182007Sroberto * /src/NTP/ntp4-dev/libparse/clk_schmid.c,v 4.9 2005/04/16 17:32:10 kardel RELEASE_20050508_A 354359Sroberto * 4182007Sroberto * clk_schmid.c,v 4.9 2005/04/16 17:32:10 kardel RELEASE_20050508_A 554359Sroberto * 654359Sroberto * Schmid clock support 7182007Sroberto * based on information and testing from Adam W. Feigin et. al (Swisstime iis.ethz.ch) 854359Sroberto * 9182007Sroberto * Copyright (c) 1995-2005 by Frank Kardel <kardel <AT> ntp.org> 10182007Sroberto * Copyright (c) 1989-1994 by Frank Kardel, Friedrich-Alexander Universit�t Erlangen-N�rnberg, Germany 1154359Sroberto * 12182007Sroberto * Redistribution and use in source and binary forms, with or without 13182007Sroberto * modification, are permitted provided that the following conditions 14182007Sroberto * are met: 15182007Sroberto * 1. Redistributions of source code must retain the above copyright 16182007Sroberto * notice, this list of conditions and the following disclaimer. 17182007Sroberto * 2. Redistributions in binary form must reproduce the above copyright 18182007Sroberto * notice, this list of conditions and the following disclaimer in the 19182007Sroberto * documentation and/or other materials provided with the distribution. 20182007Sroberto * 3. Neither the name of the author nor the names of its contributors 21182007Sroberto * may be used to endorse or promote products derived from this software 22182007Sroberto * without specific prior written permission. 23182007Sroberto * 24182007Sroberto * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 25182007Sroberto * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26182007Sroberto * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27182007Sroberto * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 28182007Sroberto * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29182007Sroberto * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30182007Sroberto * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31182007Sroberto * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32182007Sroberto * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33182007Sroberto * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34182007Sroberto * SUCH DAMAGE. 35182007Sroberto * 3654359Sroberto */ 3754359Sroberto 3854359Sroberto#if HAVE_CONFIG_H 3954359Sroberto# include <config.h> 4054359Sroberto#endif 4154359Sroberto 4254359Sroberto#if defined(REFCLOCK) && defined(CLOCK_PARSE) && defined(CLOCK_SCHMID) 4354359Sroberto 4454359Sroberto#include "ntp_fp.h" 4554359Sroberto#include "ntp_unixtime.h" 4654359Sroberto#include "ntp_calendar.h" 4754359Sroberto 4854359Sroberto#include "parse.h" 4954359Sroberto 5054359Sroberto#ifndef PARSESTREAM 5154359Sroberto#include "ntp_stdlib.h" 5254359Sroberto#include <stdio.h> 5354359Sroberto#else 5454359Sroberto#include "sys/parsestreams.h" 5554359Srobertoextern void printf P((const char *, ...)); 5654359Sroberto#endif 5754359Sroberto 5854359Sroberto/* 5954359Sroberto * Description courtesy of Adam W. Feigin et. al (Swisstime iis.ethz.ch) 6054359Sroberto * 6154359Sroberto * The command to Schmid's DCF77 clock is a single byte; each bit 6254359Sroberto * allows the user to select some part of the time string, as follows (the 6354359Sroberto * output for the lsb is sent first). 6454359Sroberto * 6554359Sroberto * Bit 0: time in MEZ, 4 bytes *binary, not BCD*; hh.mm.ss.tenths 6654359Sroberto * Bit 1: date 3 bytes *binary, not BCD: dd.mm.yy 6754359Sroberto * Bit 2: week day, 1 byte (unused here) 6854359Sroberto * Bit 3: time zone, 1 byte, 0=MET, 1=MEST. (unused here) 6954359Sroberto * Bit 4: clock status, 1 byte, 0=time invalid, 7054359Sroberto * 1=time from crystal backup, 7154359Sroberto * 3=time from DCF77 7254359Sroberto * Bit 5: transmitter status, 1 byte, 7354359Sroberto * bit 0: backup antenna 7454359Sroberto * bit 1: time zone change within 1h 7554359Sroberto * bit 3,2: TZ 01=MEST, 10=MET 7654359Sroberto * bit 4: leap second will be 7754359Sroberto * added within one hour 7854359Sroberto * bits 5-7: Zero 7954359Sroberto * Bit 6: time in backup mode, units of 5 minutes (unused here) 8054359Sroberto * 8154359Sroberto */ 8254359Sroberto#define WS_TIME 0x01 8354359Sroberto#define WS_SIGNAL 0x02 8454359Sroberto 8554359Sroberto#define WS_ALTERNATE 0x01 8654359Sroberto#define WS_ANNOUNCE 0x02 8754359Sroberto#define WS_TZ 0x0c 8854359Sroberto#define WS_MET 0x08 8954359Sroberto#define WS_MEST 0x04 9054359Sroberto#define WS_LEAP 0x10 9154359Sroberto 9254359Srobertostatic u_long cvt_schmid P((unsigned char *, int, struct format *, clocktime_t *, void *)); 9354359Srobertostatic unsigned long inp_schmid P((parse_t *, unsigned int, timestamp_t *)); 9454359Sroberto 9554359Srobertoclockformat_t clock_schmid = 9654359Sroberto{ 9754359Sroberto inp_schmid, /* no input handling */ 9854359Sroberto cvt_schmid, /* Schmid conversion */ 9954359Sroberto 0, /* not direct PPS monitoring */ 10054359Sroberto 0, /* conversion configuration */ 10154359Sroberto "Schmid", /* Schmid receiver */ 10254359Sroberto 12, /* binary data buffer */ 10354359Sroberto 0, /* no private data (complete messages) */ 10454359Sroberto}; 10554359Sroberto 10654359Sroberto 10754359Srobertostatic u_long 10854359Srobertocvt_schmid( 10954359Sroberto unsigned char *buffer, 11054359Sroberto int size, 11154359Sroberto struct format *format, 11254359Sroberto clocktime_t *clock_time, 11354359Sroberto void *local 11454359Sroberto ) 11554359Sroberto{ 11654359Sroberto if ((size != 11) || (buffer[10] != (unsigned char)'\375')) 11754359Sroberto { 11854359Sroberto return CVT_NONE; 11954359Sroberto } 12054359Sroberto else 12154359Sroberto { 12254359Sroberto if (buffer[0] > 23 || buffer[1] > 59 || buffer[2] > 59 || buffer[3] > 9) /* Time */ 12354359Sroberto { 12454359Sroberto return CVT_FAIL|CVT_BADTIME; 12554359Sroberto } 12654359Sroberto else 12754359Sroberto if (buffer[4] < 1 || buffer[4] > 31 || buffer[5] < 1 || buffer[5] > 12 12854359Sroberto || buffer[6] > 99) 12954359Sroberto { 13054359Sroberto return CVT_FAIL|CVT_BADDATE; 13154359Sroberto } 13254359Sroberto else 13354359Sroberto { 13454359Sroberto clock_time->hour = buffer[0]; 13554359Sroberto clock_time->minute = buffer[1]; 13654359Sroberto clock_time->second = buffer[2]; 13754359Sroberto clock_time->usecond = buffer[3] * 100000; 13854359Sroberto clock_time->day = buffer[4]; 13954359Sroberto clock_time->month = buffer[5]; 14054359Sroberto clock_time->year = buffer[6]; 14154359Sroberto 14254359Sroberto clock_time->flags = 0; 14354359Sroberto 14454359Sroberto switch (buffer[8] & WS_TZ) 14554359Sroberto { 14654359Sroberto case WS_MET: 14754359Sroberto clock_time->utcoffset = -1*60*60; 14854359Sroberto break; 14954359Sroberto 15054359Sroberto case WS_MEST: 15154359Sroberto clock_time->utcoffset = -2*60*60; 15254359Sroberto clock_time->flags |= PARSEB_DST; 15354359Sroberto break; 15454359Sroberto 15554359Sroberto default: 15654359Sroberto return CVT_FAIL|CVT_BADFMT; 15754359Sroberto } 15854359Sroberto 15954359Sroberto if (!(buffer[7] & WS_TIME)) 16054359Sroberto { 16154359Sroberto clock_time->flags |= PARSEB_POWERUP; 16254359Sroberto } 16354359Sroberto 16454359Sroberto if (!(buffer[7] & WS_SIGNAL)) 16554359Sroberto { 16654359Sroberto clock_time->flags |= PARSEB_NOSYNC; 16754359Sroberto } 16854359Sroberto 16954359Sroberto if (buffer[7] & WS_SIGNAL) 17054359Sroberto { 17154359Sroberto if (buffer[8] & WS_ALTERNATE) 17254359Sroberto { 17354359Sroberto clock_time->flags |= PARSEB_ALTERNATE; 17454359Sroberto } 17554359Sroberto 17654359Sroberto if (buffer[8] & WS_ANNOUNCE) 17754359Sroberto { 17854359Sroberto clock_time->flags |= PARSEB_ANNOUNCE; 17954359Sroberto } 18054359Sroberto 18154359Sroberto if (buffer[8] & WS_LEAP) 18254359Sroberto { 18354359Sroberto clock_time->flags |= PARSEB_LEAPADD; /* default: DCF77 data format deficiency */ 18454359Sroberto } 18554359Sroberto } 18654359Sroberto 18754359Sroberto clock_time->flags |= PARSEB_S_LEAP|PARSEB_S_ANTENNA; 18854359Sroberto 18954359Sroberto return CVT_OK; 19054359Sroberto } 19154359Sroberto } 19254359Sroberto} 19354359Sroberto 19454359Sroberto/* 19554359Sroberto * inp_schmid 19654359Sroberto * 19754359Sroberto * grep data from input stream 19854359Sroberto */ 19954359Srobertostatic u_long 20054359Srobertoinp_schmid( 20154359Sroberto parse_t *parseio, 20254359Sroberto unsigned int ch, 20354359Sroberto timestamp_t *tstamp 20454359Sroberto ) 20554359Sroberto{ 20654359Sroberto unsigned int rtc; 20754359Sroberto 20882498Sroberto parseprintf(DD_PARSE, ("inp_schmid(0x%lx, 0x%x, ...)\n", (long)parseio, ch)); 20954359Sroberto 21054359Sroberto switch (ch) 21154359Sroberto { 21254359Sroberto case 0xFD: /* */ 21354359Sroberto parseprintf(DD_PARSE, ("mbg_input: ETX seen\n")); 21454359Sroberto if ((rtc = parse_addchar(parseio, ch)) == PARSE_INP_SKIP) 21554359Sroberto return parse_end(parseio); 21654359Sroberto else 21754359Sroberto return rtc; 21854359Sroberto 21954359Sroberto default: 22054359Sroberto return parse_addchar(parseio, ch); 22154359Sroberto } 22254359Sroberto} 22354359Sroberto 22454359Sroberto#else /* not (REFCLOCK && CLOCK_PARSE && CLOCK_SCHMID) */ 22554359Srobertoint clk_schmid_bs; 22654359Sroberto#endif /* not (REFCLOCK && CLOCK_PARSE && CLOCK_SCHMID) */ 22754359Sroberto 22854359Sroberto/* 22954359Sroberto * History: 23054359Sroberto * 23154359Sroberto * clk_schmid.c,v 232182007Sroberto * Revision 4.9 2005/04/16 17:32:10 kardel 233182007Sroberto * update copyright 234182007Sroberto * 235182007Sroberto * Revision 4.8 2004/11/14 15:29:41 kardel 236182007Sroberto * support PPSAPI, upgrade Copyright to Berkeley style 237182007Sroberto * 23856746Sroberto * Revision 4.5 1999/11/28 09:13:51 kardel 23956746Sroberto * RECON_4_0_98F 24056746Sroberto * 24154359Sroberto * Revision 4.4 1998/06/13 12:06:03 kardel 24254359Sroberto * fix SYSV clock name clash 24354359Sroberto * 24454359Sroberto * Revision 4.3 1998/06/12 15:22:29 kardel 24554359Sroberto * fix prototypes 24654359Sroberto * 24754359Sroberto * Revision 4.2 1998/06/12 09:13:26 kardel 24854359Sroberto * conditional compile macros fixed 24954359Sroberto * printf prototype 25054359Sroberto * 25154359Sroberto * Revision 4.1 1998/05/24 09:39:53 kardel 25254359Sroberto * implementation of the new IO handling model 25354359Sroberto * 25454359Sroberto * Revision 4.0 1998/04/10 19:45:31 kardel 25554359Sroberto * Start 4.0 release version numbering 25654359Sroberto * 25754359Sroberto * from V3 3.22 log info deleted 1998/04/11 kardel 25854359Sroberto */ 259