📄 clk_rawdcf.c
字号:
/* * /src/NTP/ntp4-dev/libparse/clk_rawdcf.c,v 4.15 2005/08/06 19:17:06 kardel RELEASE_20050806_B * * clk_rawdcf.c,v 4.15 2005/08/06 19:17:06 kardel RELEASE_20050806_B * * Raw DCF77 pulse clock support * * Copyright (c) 1995-2005 by Frank Kardel <kardel <AT> ntp.org> * Copyright (c) 1989-1994 by Frank Kardel, Friedrich-Alexander Universit鋞 Erlangen-N黵nberg, Germany * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the author nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */#ifdef HAVE_CONFIG_H# include <config.h>#endif#if defined(REFCLOCK) && defined(CLOCK_PARSE) && defined(CLOCK_RAWDCF)#include "ntp_fp.h"#include "ntp_unixtime.h"#include "ntp_calendar.h"#include "parse.h"#ifdef PARSESTREAM# include <sys/parsestreams.h>#endif#ifndef PARSEKERNEL# include "ntp_stdlib.h"#endif/* * DCF77 raw time code * * From "Zur Zeit", Physikalisch-Technische Bundesanstalt (PTB), Braunschweig * und Berlin, Maerz 1989 * * Timecode transmission: * AM: * time marks are send every second except for the second before the * next minute mark * time marks consist of a reduction of transmitter power to 25% * of the nominal level * the falling edge is the time indication (on time) * time marks of a 100ms duration constitute a logical 0 * time marks of a 200ms duration constitute a logical 1 * FM: * see the spec. (basically a (non-)inverted psuedo random phase shift) * * Encoding: * Second Contents * 0 - 10 AM: free, FM: 0 * 11 - 14 free * 15 R - alternate antenna * 16 A1 - expect zone change (1 hour before) * 17 - 18 Z1,Z2 - time zone * 0 0 illegal * 0 1 MEZ (MET) * 1 0 MESZ (MED, MET DST) * 1 1 illegal * 19 A2 - expect leap insertion/deletion (1 hour before) * 20 S - start of time code (1) * 21 - 24 M1 - BCD (lsb first) Minutes * 25 - 27 M10 - BCD (lsb first) 10 Minutes * 28 P1 - Minute Parity (even) * 29 - 32 H1 - BCD (lsb first) Hours * 33 - 34 H10 - BCD (lsb first) 10 Hours * 35 P2 - Hour Parity (even) * 36 - 39 D1 - BCD (lsb first) Days * 40 - 41 D10 - BCD (lsb first) 10 Days * 42 - 44 DW - BCD (lsb first) day of week (1: Monday -> 7: Sunday) * 45 - 49 MO - BCD (lsb first) Month * 50 MO0 - 10 Months * 51 - 53 Y1 - BCD (lsb first) Years * 54 - 57 Y10 - BCD (lsb first) 10 Years * 58 P3 - Date Parity (even) * 59 - usually missing (minute indication), except for leap insertion */static u_long pps_rawdcf P((parse_t *, int, timestamp_t *));static u_long cvt_rawdcf P((unsigned char *, int, struct format *, clocktime_t *, void *));static u_long inp_rawdcf P((parse_t *, unsigned int, timestamp_t *));typedef struct last_tcode { time_t tcode; /* last converted time code */} last_tcode_t;#define BUFFER_MAX 61clockformat_t clock_rawdcf ={ inp_rawdcf, /* DCF77 input handling */ cvt_rawdcf, /* raw dcf input conversion */ pps_rawdcf, /* examining PPS information */ 0, /* no private configuration data */ "RAW DCF77 Timecode", /* direct decoding / time synthesis */ BUFFER_MAX, /* bit buffer */ sizeof(last_tcode_t)};static struct dcfparam{ unsigned char *onebits; unsigned char *zerobits;} dcfparameter = { "###############RADMLS1248124P124812P1248121241248112481248P", /* 'ONE' representation */ "--------------------s-------p------p----------------------p" /* 'ZERO' representation */};static struct rawdcfcode { char offset; /* start bit */} rawdcfcode[] ={ { 0 }, { 15 }, { 16 }, { 17 }, { 19 }, { 20 }, { 21 }, { 25 }, { 28 }, { 29 }, { 33 }, { 35 }, { 36 }, { 40 }, { 42 }, { 45 }, { 49 }, { 50 }, { 54 }, { 58 }, { 59 }};#define DCF_M 0#define DCF_R 1#define DCF_A1 2#define DCF_Z 3#define DCF_A2 4#define DCF_S 5#define DCF_M1 6#define DCF_M10 7#define DCF_P1 8#define DCF_H1 9#define DCF_H10 10#define DCF_P2 11#define DCF_D1 12#define DCF_D10 13#define DCF_DW 14#define DCF_MO 15#define DCF_MO0 16#define DCF_Y1 17#define DCF_Y10 18#define DCF_P3 19static struct partab{ char offset; /* start bit of parity field */} partab[] ={ { 21 }, { 29 }, { 36 }, { 59 }};#define DCF_P_P1 0#define DCF_P_P2 1#define DCF_P_P3 2#define DCF_Z_MET 0x2#define DCF_Z_MED 0x1static u_longext_bf( unsigned char *buf, int idx, unsigned char *zero ){ u_long sum = 0; int i, first; first = rawdcfcode[idx].offset; for (i = rawdcfcode[idx+1].offset - 1; i >= first; i--) { sum <<= 1; sum |= (buf[i] != zero[i]); } return sum;}static unsignedpcheck( unsigned char *buf, int idx, unsigned char *zero ){ int i,last; unsigned psum = 1; last = partab[idx+1].offset; for (i = partab[idx].offset; i < last; i++) psum ^= (buf[i] != zero[i]); return psum;}static u_longconvert_rawdcf( unsigned char *buffer, int size, struct dcfparam *dcfprm, clocktime_t *clock_time ){ unsigned char *s = buffer; unsigned char *b = dcfprm->onebits; unsigned char *c = dcfprm->zerobits; int i; parseprintf(DD_RAWDCF,("parse: convert_rawdcf: \"%s\"\n", buffer)); if (size < 57) {#ifndef PARSEKERNEL msyslog(LOG_ERR, "parse: convert_rawdcf: INCOMPLETE DATA - time code only has %d bits\n", size);#endif return CVT_NONE; } for (i = 0; i < size; i++) { if ((*s != *b) && (*s != *c)) { /* * we only have two types of bytes (ones and zeros) */#ifndef PARSEKERNEL msyslog(LOG_ERR, "parse: convert_rawdcf: BAD DATA - no conversion");#endif return CVT_NONE; } if (*b) b++; if (*c) c++; s++; } /* * check Start and Parity bits */ if ((ext_bf(buffer, DCF_S, dcfprm->zerobits) == 1) && pcheck(buffer, DCF_P_P1, dcfprm->zerobits) && pcheck(buffer, DCF_P_P2, dcfprm->zerobits) && pcheck(buffer, DCF_P_P3, dcfprm->zerobits)) { /* * buffer OK */ parseprintf(DD_RAWDCF,("parse: convert_rawdcf: parity check passed\n")); clock_time->flags = PARSEB_S_ANTENNA|PARSEB_S_LEAP; clock_time->utctime= 0; clock_time->usecond= 0; clock_time->second = 0; clock_time->minute = ext_bf(buffer, DCF_M10, dcfprm->zerobits); clock_time->minute = TIMES10(clock_time->minute) + ext_bf(buffer, DCF_M1, dcfprm->zerobits); clock_time->hour = ext_bf(buffer, DCF_H10, dcfprm->zerobits); clock_time->hour = TIMES10(clock_time->hour) + ext_bf(buffer, DCF_H1, dcfprm->zerobits); clock_time->day = ext_bf(buffer, DCF_D10, dcfprm->zerobits); clock_time->day = TIMES10(clock_time->day) + ext_bf(buffer, DCF_D1, dcfprm->zerobits); clock_time->month = ext_bf(buffer, DCF_MO0, dcfprm->zerobits); clock_time->month = TIMES10(clock_time->month) + ext_bf(buffer, DCF_MO, dcfprm->zerobits); clock_time->year = ext_bf(buffer, DCF_Y10, dcfprm->zerobits); clock_time->year = TIMES10(clock_time->year) + ext_bf(buffer, DCF_Y1, dcfprm->zerobits); switch (ext_bf(buffer, DCF_Z, dcfprm->zerobits)) { case DCF_Z_MET: clock_time->utcoffset = -1*60*60; break; case DCF_Z_MED: clock_time->flags |= PARSEB_DST; clock_time->utcoffset = -2*60*60; break; default: parseprintf(DD_RAWDCF,("parse: convert_rawdcf: BAD TIME ZONE\n")); return CVT_FAIL|CVT_BADFMT; } if (ext_bf(buffer, DCF_A1, dcfprm->zerobits)) clock_time->flags |= PARSEB_ANNOUNCE; if (ext_bf(buffer, DCF_A2, dcfprm->zerobits)) clock_time->flags |= PARSEB_LEAPADD; /* default: DCF77 data format deficiency */ if (ext_bf(buffer, DCF_R, dcfprm->zerobits)) clock_time->flags |= PARSEB_ALTERNATE; parseprintf(DD_RAWDCF,("parse: convert_rawdcf: TIME CODE OK: %d:%d, %d.%d.%d, flags 0x%lx\n", (int)clock_time->hour, (int)clock_time->minute, (int)clock_time->day, (int)clock_time->month,(int) clock_time->year, (u_long)clock_time->flags)); return CVT_OK; } else { /* * bad format - not for us */#ifndef PARSEKERNEL msyslog(LOG_ERR, "parse: convert_rawdcf: parity check FAILED for \"%s\"\n", buffer);#endif return CVT_FAIL|CVT_BADFMT;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -