Home | History | Annotate | Line # | Download | only in parseutil
      1  1.6  christos /*	$NetBSD: testdcf.c,v 1.6 2020/05/25 20:47:26 christos Exp $	*/
      2  1.1    kardel 
      3  1.1    kardel /*
      4  1.1    kardel  * /src/NTP/ntp4-dev/parseutil/testdcf.c,v 4.10 2005/08/06 14:18:43 kardel RELEASE_20050806_A
      5  1.1    kardel  *
      6  1.1    kardel  * testdcf.c,v 4.10 2005/08/06 14:18:43 kardel RELEASE_20050806_A
      7  1.3  christos  *
      8  1.1    kardel  * simple DCF77 100/200ms pulse test program (via 50Baud serial line)
      9  1.1    kardel  *
     10  1.4  christos  * Copyright (c) 1995-2015 by Frank Kardel <kardel <AT> ntp.org>
     11  1.3  christos  * Copyright (c) 1989-1994 by Frank Kardel, Friedrich-Alexander Universitaet Erlangen-Nuernberg, Germany
     12  1.1    kardel  *
     13  1.1    kardel  * Redistribution and use in source and binary forms, with or without
     14  1.1    kardel  * modification, are permitted provided that the following conditions
     15  1.1    kardel  * are met:
     16  1.1    kardel  * 1. Redistributions of source code must retain the above copyright
     17  1.1    kardel  *    notice, this list of conditions and the following disclaimer.
     18  1.1    kardel  * 2. Redistributions in binary form must reproduce the above copyright
     19  1.1    kardel  *    notice, this list of conditions and the following disclaimer in the
     20  1.1    kardel  *    documentation and/or other materials provided with the distribution.
     21  1.1    kardel  * 3. Neither the name of the author nor the names of its contributors
     22  1.1    kardel  *    may be used to endorse or promote products derived from this software
     23  1.1    kardel  *    without specific prior written permission.
     24  1.1    kardel  *
     25  1.1    kardel  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     26  1.1    kardel  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     27  1.1    kardel  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     28  1.1    kardel  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     29  1.1    kardel  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     30  1.1    kardel  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     31  1.1    kardel  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     32  1.1    kardel  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     33  1.1    kardel  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     34  1.1    kardel  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     35  1.1    kardel  * SUCH DAMAGE.
     36  1.1    kardel  *
     37  1.1    kardel  */
     38  1.1    kardel 
     39  1.2  christos #include <config.h>
     40  1.1    kardel #include "ntp_stdlib.h"
     41  1.1    kardel 
     42  1.1    kardel #include <sys/ioctl.h>
     43  1.1    kardel #include <unistd.h>
     44  1.1    kardel #include <stdio.h>
     45  1.1    kardel #include <fcntl.h>
     46  1.1    kardel #include <termios.h>
     47  1.1    kardel 
     48  1.1    kardel /*
     49  1.1    kardel  * state flags
     50  1.1    kardel  */
     51  1.3  christos #define DCFB_ANNOUNCE   0x0001 /* switch time zone warning (DST switch) */
     52  1.3  christos #define DCFB_DST        0x0002 /* DST in effect */
     53  1.3  christos #define DCFB_LEAP       0x0004 /* LEAP warning (1 hour prior to occurrence) */
     54  1.3  christos #define DCFB_CALLBIT    0x0008 /* "call bit" used to signalize irregularities in the control facilities */
     55  1.1    kardel 
     56  1.1    kardel struct clocktime		/* clock time broken up from time code */
     57  1.1    kardel {
     58  1.1    kardel 	long wday;
     59  1.1    kardel 	long day;
     60  1.1    kardel 	long month;
     61  1.1    kardel 	long year;
     62  1.1    kardel 	long hour;
     63  1.1    kardel 	long minute;
     64  1.1    kardel 	long second;
     65  1.1    kardel 	long usecond;
     66  1.1    kardel 	long utcoffset;	/* in minutes */
     67  1.1    kardel 	long flags;		/* current clock status */
     68  1.1    kardel };
     69  1.1    kardel 
     70  1.1    kardel typedef struct clocktime clocktime_t;
     71  1.1    kardel 
     72  1.1    kardel static char type(unsigned int);
     73  1.1    kardel 
     74  1.1    kardel #define TIMES10(_X_) (((_X_) << 3) + ((_X_) << 1))
     75  1.1    kardel 
     76  1.1    kardel /*
     77  1.1    kardel  * parser related return/error codes
     78  1.1    kardel  */
     79  1.1    kardel #define CVT_MASK	0x0000000F /* conversion exit code */
     80  1.1    kardel #define   CVT_NONE	0x00000001 /* format not applicable */
     81  1.1    kardel #define   CVT_FAIL	0x00000002 /* conversion failed - error code returned */
     82  1.1    kardel #define   CVT_OK	0x00000004 /* conversion succeeded */
     83  1.1    kardel #define CVT_BADFMT	0x00000010 /* general format error - (unparsable) */
     84  1.1    kardel 
     85  1.1    kardel /*
     86  1.1    kardel  * DCF77 raw time code
     87  1.1    kardel  *
     88  1.1    kardel  * From "Zur Zeit", Physikalisch-Technische Bundesanstalt (PTB), Braunschweig
     89  1.1    kardel  * und Berlin, Maerz 1989
     90  1.1    kardel  *
     91  1.1    kardel  * Timecode transmission:
     92  1.1    kardel  * AM:
     93  1.1    kardel  *	time marks are send every second except for the second before the
     94  1.1    kardel  *	next minute mark
     95  1.1    kardel  *	time marks consist of a reduction of transmitter power to 25%
     96  1.1    kardel  *	of the nominal level
     97  1.1    kardel  *	the falling edge is the time indication (on time)
     98  1.1    kardel  *	time marks of a 100ms duration constitute a logical 0
     99  1.1    kardel  *	time marks of a 200ms duration constitute a logical 1
    100  1.1    kardel  * FM:
    101  1.1    kardel  *	see the spec. (basically a (non-)inverted psuedo random phase shift)
    102  1.1    kardel  *
    103  1.1    kardel  * Encoding:
    104  1.1    kardel  * Second	Contents
    105  1.1    kardel  * 0  - 10	AM: free, FM: 0
    106  1.1    kardel  * 11 - 14	free
    107  1.3  christos  * 15		R     - "call bit" used to signalize irregularities in the control facilities
    108  1.3  christos  *		        (until 2003 indicated transmission via alternate antenna)
    109  1.1    kardel  * 16		A1    - expect zone change (1 hour before)
    110  1.1    kardel  * 17 - 18	Z1,Z2 - time zone
    111  1.1    kardel  *		 0  0 illegal
    112  1.1    kardel  *		 0  1 MEZ  (MET)
    113  1.1    kardel  *		 1  0 MESZ (MED, MET DST)
    114  1.1    kardel  *		 1  1 illegal
    115  1.1    kardel  * 19		A2    - expect leap insertion/deletion (1 hour before)
    116  1.1    kardel  * 20		S     - start of time code (1)
    117  1.1    kardel  * 21 - 24	M1    - BCD (lsb first) Minutes
    118  1.1    kardel  * 25 - 27	M10   - BCD (lsb first) 10 Minutes
    119  1.1    kardel  * 28		P1    - Minute Parity (even)
    120  1.1    kardel  * 29 - 32	H1    - BCD (lsb first) Hours
    121  1.1    kardel  * 33 - 34      H10   - BCD (lsb first) 10 Hours
    122  1.1    kardel  * 35		P2    - Hour Parity (even)
    123  1.1    kardel  * 36 - 39	D1    - BCD (lsb first) Days
    124  1.1    kardel  * 40 - 41	D10   - BCD (lsb first) 10 Days
    125  1.1    kardel  * 42 - 44	DW    - BCD (lsb first) day of week (1: Monday -> 7: Sunday)
    126  1.1    kardel  * 45 - 49	MO    - BCD (lsb first) Month
    127  1.1    kardel  * 50           MO0   - 10 Months
    128  1.1    kardel  * 51 - 53	Y1    - BCD (lsb first) Years
    129  1.1    kardel  * 54 - 57	Y10   - BCD (lsb first) 10 Years
    130  1.1    kardel  * 58 		P3    - Date Parity (even)
    131  1.1    kardel  * 59		      - usually missing (minute indication), except for leap insertion
    132  1.1    kardel  */
    133  1.1    kardel 
    134  1.1    kardel static char revision[] = "4.10";
    135  1.1    kardel 
    136  1.3  christos static struct rawdcfcode
    137  1.1    kardel {
    138  1.1    kardel 	char offset;			/* start bit */
    139  1.1    kardel } rawdcfcode[] =
    140  1.1    kardel {
    141  1.1    kardel 	{  0 }, { 15 }, { 16 }, { 17 }, { 19 }, { 20 }, { 21 }, { 25 }, { 28 }, { 29 },
    142  1.1    kardel 	{ 33 }, { 35 }, { 36 }, { 40 }, { 42 }, { 45 }, { 49 }, { 50 }, { 54 }, { 58 }, { 59 }
    143  1.1    kardel };
    144  1.1    kardel 
    145  1.1    kardel #define DCF_M	0
    146  1.1    kardel #define DCF_R	1
    147  1.1    kardel #define DCF_A1	2
    148  1.1    kardel #define DCF_Z	3
    149  1.1    kardel #define DCF_A2	4
    150  1.1    kardel #define DCF_S	5
    151  1.1    kardel #define DCF_M1	6
    152  1.1    kardel #define DCF_M10	7
    153  1.1    kardel #define DCF_P1	8
    154  1.1    kardel #define DCF_H1	9
    155  1.1    kardel #define DCF_H10	10
    156  1.1    kardel #define DCF_P2	11
    157  1.1    kardel #define DCF_D1	12
    158  1.1    kardel #define DCF_D10	13
    159  1.1    kardel #define DCF_DW	14
    160  1.1    kardel #define DCF_MO	15
    161  1.1    kardel #define DCF_MO0	16
    162  1.1    kardel #define DCF_Y1	17
    163  1.1    kardel #define DCF_Y10	18
    164  1.1    kardel #define DCF_P3	19
    165  1.1    kardel 
    166  1.1    kardel static struct partab
    167  1.1    kardel {
    168  1.1    kardel 	char offset;			/* start bit of parity field */
    169  1.1    kardel } partab[] =
    170  1.1    kardel {
    171  1.1    kardel 	{ 21 }, { 29 }, { 36 }, { 59 }
    172  1.1    kardel };
    173  1.1    kardel 
    174  1.1    kardel #define DCF_P_P1	0
    175  1.1    kardel #define DCF_P_P2	1
    176  1.1    kardel #define DCF_P_P3	2
    177  1.1    kardel 
    178  1.1    kardel #define DCF_Z_MET 0x2
    179  1.1    kardel #define DCF_Z_MED 0x1
    180  1.1    kardel 
    181  1.1    kardel static unsigned long
    182  1.1    kardel ext_bf(
    183  1.1    kardel 	register unsigned char *buf,
    184  1.1    kardel 	register int   idx
    185  1.1    kardel 	)
    186  1.1    kardel {
    187  1.1    kardel 	register unsigned long sum = 0;
    188  1.1    kardel 	register int i, first;
    189  1.1    kardel 
    190  1.1    kardel 	first = rawdcfcode[idx].offset;
    191  1.3  christos 
    192  1.1    kardel 	for (i = rawdcfcode[idx+1].offset - 1; i >= first; i--)
    193  1.1    kardel 	{
    194  1.1    kardel 		sum <<= 1;
    195  1.1    kardel 		sum |= (buf[i] != '-');
    196  1.1    kardel 	}
    197  1.1    kardel 	return sum;
    198  1.1    kardel }
    199  1.1    kardel 
    200  1.1    kardel static unsigned
    201  1.1    kardel pcheck(
    202  1.1    kardel 	register unsigned char *buf,
    203  1.1    kardel 	register int   idx
    204  1.1    kardel 	)
    205  1.1    kardel {
    206  1.1    kardel 	register int i,last;
    207  1.1    kardel 	register unsigned psum = 1;
    208  1.1    kardel 
    209  1.1    kardel 	last = partab[idx+1].offset;
    210  1.1    kardel 
    211  1.1    kardel 	for (i = partab[idx].offset; i < last; i++)
    212  1.1    kardel 	    psum ^= (buf[i] != '-');
    213  1.1    kardel 
    214  1.1    kardel 	return psum;
    215  1.1    kardel }
    216  1.1    kardel 
    217  1.1    kardel static unsigned long
    218  1.1    kardel convert_rawdcf(
    219  1.1    kardel 	register unsigned char   *buffer,
    220  1.1    kardel 	register int              size,
    221  1.1    kardel 	register clocktime_t     *clock_time
    222  1.1    kardel 	)
    223  1.1    kardel {
    224  1.1    kardel 	if (size < 57)
    225  1.1    kardel 	{
    226  1.1    kardel 		printf("%-30s", "*** INCOMPLETE");
    227  1.1    kardel 		return CVT_NONE;
    228  1.1    kardel 	}
    229  1.3  christos 
    230  1.1    kardel 	/*
    231  1.1    kardel 	 * check Start and Parity bits
    232  1.1    kardel 	 */
    233  1.1    kardel 	if ((ext_bf(buffer, DCF_S) == 1) &&
    234  1.1    kardel 	    pcheck(buffer, DCF_P_P1) &&
    235  1.1    kardel 	    pcheck(buffer, DCF_P_P2) &&
    236  1.1    kardel 	    pcheck(buffer, DCF_P_P3))
    237  1.1    kardel 	{
    238  1.1    kardel 		/*
    239  1.1    kardel 		 * buffer OK
    240  1.1    kardel 		 */
    241  1.1    kardel 
    242  1.1    kardel 		clock_time->flags  = 0;
    243  1.1    kardel 		clock_time->usecond= 0;
    244  1.1    kardel 		clock_time->second = 0;
    245  1.1    kardel 		clock_time->minute = ext_bf(buffer, DCF_M10);
    246  1.1    kardel 		clock_time->minute = TIMES10(clock_time->minute) + ext_bf(buffer, DCF_M1);
    247  1.1    kardel 		clock_time->hour   = ext_bf(buffer, DCF_H10);
    248  1.1    kardel 		clock_time->hour   = TIMES10(clock_time->hour) + ext_bf(buffer, DCF_H1);
    249  1.1    kardel 		clock_time->day    = ext_bf(buffer, DCF_D10);
    250  1.1    kardel 		clock_time->day    = TIMES10(clock_time->day) + ext_bf(buffer, DCF_D1);
    251  1.1    kardel 		clock_time->month  = ext_bf(buffer, DCF_MO0);
    252  1.1    kardel 		clock_time->month  = TIMES10(clock_time->month) + ext_bf(buffer, DCF_MO);
    253  1.1    kardel 		clock_time->year   = ext_bf(buffer, DCF_Y10);
    254  1.1    kardel 		clock_time->year   = TIMES10(clock_time->year) + ext_bf(buffer, DCF_Y1);
    255  1.1    kardel 		clock_time->wday   = ext_bf(buffer, DCF_DW);
    256  1.1    kardel 
    257  1.1    kardel 		switch (ext_bf(buffer, DCF_Z))
    258  1.1    kardel 		{
    259  1.1    kardel 		    case DCF_Z_MET:
    260  1.1    kardel 			clock_time->utcoffset = -60;
    261  1.1    kardel 			break;
    262  1.1    kardel 
    263  1.1    kardel 		    case DCF_Z_MED:
    264  1.1    kardel 			clock_time->flags     |= DCFB_DST;
    265  1.1    kardel 			clock_time->utcoffset  = -120;
    266  1.1    kardel 			break;
    267  1.1    kardel 
    268  1.1    kardel 		    default:
    269  1.1    kardel 			printf("%-30s", "*** BAD TIME ZONE");
    270  1.1    kardel 			return CVT_FAIL|CVT_BADFMT;
    271  1.1    kardel 		}
    272  1.1    kardel 
    273  1.1    kardel 		if (ext_bf(buffer, DCF_A1))
    274  1.1    kardel 		    clock_time->flags |= DCFB_ANNOUNCE;
    275  1.1    kardel 
    276  1.1    kardel 		if (ext_bf(buffer, DCF_A2))
    277  1.1    kardel 		    clock_time->flags |= DCFB_LEAP;
    278  1.1    kardel 
    279  1.1    kardel 		if (ext_bf(buffer, DCF_R))
    280  1.3  christos 		    clock_time->flags |= DCFB_CALLBIT;
    281  1.1    kardel 
    282  1.1    kardel 		return CVT_OK;
    283  1.1    kardel 	}
    284  1.1    kardel 	else
    285  1.1    kardel 	{
    286  1.1    kardel 		/*
    287  1.1    kardel 		 * bad format - not for us
    288  1.1    kardel 		 */
    289  1.1    kardel 		printf("%-30s", "*** BAD FORMAT (invalid/parity)");
    290  1.1    kardel 		return CVT_FAIL|CVT_BADFMT;
    291  1.1    kardel 	}
    292  1.1    kardel }
    293  1.1    kardel 
    294  1.1    kardel static char
    295  1.1    kardel type(
    296  1.1    kardel 	unsigned int c
    297  1.1    kardel 	)
    298  1.1    kardel {
    299  1.1    kardel 	c ^= 0xFF;
    300  1.1    kardel 	return (c >= 0xF);
    301  1.1    kardel }
    302  1.1    kardel 
    303  1.1    kardel static const char *wday[8] =
    304  1.1    kardel {
    305  1.1    kardel 	"??",
    306  1.1    kardel 	"Mo",
    307  1.1    kardel 	"Tu",
    308  1.1    kardel 	"We",
    309  1.1    kardel 	"Th",
    310  1.1    kardel 	"Fr",
    311  1.1    kardel 	"Sa",
    312  1.1    kardel 	"Su"
    313  1.1    kardel };
    314  1.1    kardel 
    315  1.1    kardel static char pat[] = "-\\|/";
    316  1.1    kardel 
    317  1.1    kardel #define LINES (24-2)	/* error lines after which the two headlines are repeated */
    318  1.1    kardel 
    319  1.1    kardel int
    320  1.1    kardel main(
    321  1.1    kardel 	int argc,
    322  1.1    kardel 	char *argv[]
    323  1.1    kardel 	)
    324  1.1    kardel {
    325  1.1    kardel 	if ((argc != 2) && (argc != 3))
    326  1.1    kardel 	{
    327  1.1    kardel 		fprintf(stderr, "usage: %s [-f|-t|-ft|-tf] <device>\n", argv[0]);
    328  1.1    kardel 		exit(1);
    329  1.1    kardel 	}
    330  1.1    kardel 	else
    331  1.1    kardel 	{
    332  1.1    kardel 		unsigned char c;
    333  1.1    kardel 		char *file;
    334  1.1    kardel 		int fd;
    335  1.1    kardel 		int offset = 15;
    336  1.1    kardel 		int trace = 0;
    337  1.1    kardel 		int errs = LINES+1;
    338  1.1    kardel 
    339  1.1    kardel 		/*
    340  1.1    kardel 		 * SIMPLE(!) argument "parser"
    341  1.1    kardel 		 */
    342  1.1    kardel 		if (argc == 3)
    343  1.1    kardel 		{
    344  1.1    kardel 			if (strcmp(argv[1], "-f") == 0)
    345  1.1    kardel 			    offset = 0;
    346  1.1    kardel 			if (strcmp(argv[1], "-t") == 0)
    347  1.1    kardel 			    trace = 1;
    348  1.1    kardel 			if ((strcmp(argv[1], "-ft") == 0) ||
    349  1.1    kardel 			    (strcmp(argv[1], "-tf") == 0))
    350  1.1    kardel 			{
    351  1.1    kardel 				offset = 0;
    352  1.1    kardel 				trace = 1;
    353  1.1    kardel 			}
    354  1.1    kardel 			file = argv[2];
    355  1.1    kardel 		}
    356  1.1    kardel 		else
    357  1.1    kardel 		{
    358  1.1    kardel 			file = argv[1];
    359  1.1    kardel 		}
    360  1.1    kardel 
    361  1.1    kardel 		fd = open(file, O_RDONLY);
    362  1.1    kardel 		if (fd == -1)
    363  1.1    kardel 		{
    364  1.1    kardel 			perror(file);
    365  1.1    kardel 			exit(1);
    366  1.1    kardel 		}
    367  1.1    kardel 		else
    368  1.1    kardel 		{
    369  1.1    kardel 			int i;
    370  1.1    kardel #ifdef TIOCM_RTS
    371  1.1    kardel 			int on = TIOCM_RTS;
    372  1.1    kardel #endif
    373  1.1    kardel 			struct timeval t, tt, tlast;
    374  1.1    kardel 			char buf[61];
    375  1.1    kardel 			clocktime_t clock_time;
    376  1.1    kardel 			struct termios term;
    377  1.1    kardel 			int rtc = CVT_NONE;
    378  1.1    kardel 
    379  1.1    kardel 			if (tcgetattr(fd,  &term) == -1)
    380  1.1    kardel 			{
    381  1.1    kardel 				perror("tcgetattr");
    382  1.1    kardel 				exit(1);
    383  1.1    kardel 			}
    384  1.1    kardel 
    385  1.1    kardel 			memset(term.c_cc, 0, sizeof(term.c_cc));
    386  1.1    kardel 			term.c_cc[VMIN] = 1;
    387  1.1    kardel #ifdef NO_PARENB_IGNPAR /* Was: defined(SYS_IRIX4) || defined (SYS_IRIX5) */
    388  1.1    kardel 			/* somehow doesn't grok PARENB & IGNPAR (mj) */
    389  1.1    kardel 			term.c_cflag = CS8|CREAD|CLOCAL;
    390  1.1    kardel #else
    391  1.1    kardel 			term.c_cflag = CS8|CREAD|CLOCAL|PARENB;
    392  1.1    kardel #endif
    393  1.1    kardel 			term.c_iflag = IGNPAR;
    394  1.1    kardel 			term.c_oflag = 0;
    395  1.1    kardel 			term.c_lflag = 0;
    396  1.1    kardel 
    397  1.1    kardel 			cfsetispeed(&term, B50);
    398  1.1    kardel 			cfsetospeed(&term, B50);
    399  1.1    kardel 
    400  1.1    kardel 			if (tcsetattr(fd, TCSANOW, &term) == -1)
    401  1.1    kardel 			{
    402  1.1    kardel 				perror("tcsetattr");
    403  1.1    kardel 				exit(1);
    404  1.1    kardel 			}
    405  1.1    kardel 
    406  1.1    kardel #ifdef I_POP
    407  1.1    kardel 			while (ioctl(fd, I_POP, 0) == 0)
    408  1.1    kardel 			    ;
    409  1.1    kardel #endif
    410  1.1    kardel #if defined(TIOCMBIC) && defined(TIOCM_RTS)
    411  1.1    kardel 			if (ioctl(fd, TIOCMBIC, (caddr_t)&on) == -1)
    412  1.1    kardel 			{
    413  1.1    kardel 				perror("TIOCM_RTS");
    414  1.1    kardel 			}
    415  1.1    kardel #endif
    416  1.1    kardel 
    417  1.1    kardel 			printf("  DCF77 monitor %s - Copyright (C) 1993-2005, Frank Kardel\n\n", revision);
    418  1.1    kardel 
    419  1.1    kardel 			clock_time.hour = 0;
    420  1.1    kardel 			clock_time.minute = 0;
    421  1.1    kardel 			clock_time.day = 0;
    422  1.1    kardel 			clock_time.wday = 0;
    423  1.1    kardel 			clock_time.month = 0;
    424  1.1    kardel 			clock_time.year = 0;
    425  1.1    kardel 			clock_time.flags = 0;
    426  1.1    kardel 			buf[60] = '\0';
    427  1.1    kardel 			for ( i = 0; i < 60; i++)
    428  1.1    kardel 			    buf[i] = '.';
    429  1.1    kardel 
    430  1.1    kardel 			gettimeofday(&tlast, 0L);
    431  1.1    kardel 			i = 0;
    432  1.1    kardel 			while (read(fd, &c, 1) == 1)
    433  1.1    kardel 			{
    434  1.1    kardel 				gettimeofday(&t, 0L);
    435  1.1    kardel 				tt = t;
    436  1.1    kardel 				t.tv_sec -= tlast.tv_sec;
    437  1.1    kardel 				t.tv_usec -= tlast.tv_usec;
    438  1.1    kardel 				if (t.tv_usec < 0)
    439  1.1    kardel 				{
    440  1.1    kardel 					t.tv_usec += 1000000;
    441  1.1    kardel 					t.tv_sec  -= 1;
    442  1.1    kardel 				}
    443  1.1    kardel 
    444  1.1    kardel 				if (errs > LINES)
    445  1.1    kardel 				{
    446  1.1    kardel 					printf("  %s", &"PTB private....RADMLSMin....PHour..PMDay..DayMonthYear....P\n"[offset]);
    447  1.1    kardel 					printf("  %s", &"---------------RADMLS1248124P124812P1248121241248112481248P\n"[offset]);
    448  1.1    kardel 					errs = 0;
    449  1.1    kardel 				}
    450  1.1    kardel 
    451  1.1    kardel 				if (t.tv_sec > 1 ||
    452  1.1    kardel 				    (t.tv_sec == 1 &&
    453  1.1    kardel 				     t.tv_usec > 500000))
    454  1.1    kardel 				{
    455  1.1    kardel 					printf("%c %.*s ", pat[i % (sizeof(pat)-1)], 59 - offset, &buf[offset]);
    456  1.1    kardel 
    457  1.1    kardel 					if ((rtc = convert_rawdcf((unsigned char *)buf, i, &clock_time)) != CVT_OK)
    458  1.1    kardel 					{
    459  1.1    kardel 						printf("\n");
    460  1.1    kardel 						clock_time.hour = 0;
    461  1.1    kardel 						clock_time.minute = 0;
    462  1.1    kardel 						clock_time.day = 0;
    463  1.1    kardel 						clock_time.wday = 0;
    464  1.1    kardel 						clock_time.month = 0;
    465  1.1    kardel 						clock_time.year = 0;
    466  1.1    kardel 						clock_time.flags = 0;
    467  1.1    kardel 						errs++;
    468  1.1    kardel 					}
    469  1.1    kardel 
    470  1.1    kardel 					if (((c^0xFF)+1) & (c^0xFF))
    471  1.1    kardel 					    buf[0] = '?';
    472  1.1    kardel 					else
    473  1.1    kardel 					    buf[0] = type(c) ? '#' : '-';
    474  1.1    kardel 
    475  1.1    kardel 					for ( i = 1; i < 60; i++)
    476  1.1    kardel 					    buf[i] = '.';
    477  1.1    kardel 
    478  1.1    kardel 					i = 0;
    479  1.1    kardel 				}
    480  1.1    kardel 				else
    481  1.1    kardel 				{
    482  1.1    kardel 					if (((c^0xFF)+1) & (c^0xFF))
    483  1.1    kardel 					    buf[i] = '?';
    484  1.1    kardel 					else
    485  1.1    kardel 					    buf[i] = type(c) ? '#' : '-';
    486  1.1    kardel 
    487  1.1    kardel 					printf("%c %.*s ", pat[i % (sizeof(pat)-1)], 59 - offset, &buf[offset]);
    488  1.1    kardel 				}
    489  1.1    kardel 
    490  1.1    kardel 				if (rtc == CVT_OK)
    491  1.1    kardel 				{
    492  1.1    kardel 					printf("%s, %2d:%02d:%02d, %d.%02d.%02d, <%s%s%s%s>",
    493  1.1    kardel 					       wday[clock_time.wday],
    494  1.1    kardel 					       (int)clock_time.hour, (int)clock_time.minute, (int)i, (int)clock_time.day, (int)clock_time.month,
    495  1.1    kardel 					       (int)clock_time.year,
    496  1.3  christos 					       (clock_time.flags & DCFB_CALLBIT) ? "R" : "_",
    497  1.1    kardel 					       (clock_time.flags & DCFB_ANNOUNCE) ? "A" : "_",
    498  1.1    kardel 					       (clock_time.flags & DCFB_DST) ? "D" : "_",
    499  1.1    kardel 					       (clock_time.flags & DCFB_LEAP) ? "L" : "_"
    500  1.1    kardel 					       );
    501  1.1    kardel 					if (trace && (i == 0))
    502  1.1    kardel 					{
    503  1.1    kardel 						printf("\n");
    504  1.1    kardel 						errs++;
    505  1.1    kardel 					}
    506  1.1    kardel 				}
    507  1.1    kardel 
    508  1.1    kardel 				printf("\r");
    509  1.1    kardel 
    510  1.1    kardel 				if (i < 60)
    511  1.1    kardel 				{
    512  1.1    kardel 					i++;
    513  1.1    kardel 				}
    514  1.1    kardel 
    515  1.1    kardel 				tlast = tt;
    516  1.1    kardel 
    517  1.1    kardel 				fflush(stdout);
    518  1.1    kardel 			}
    519  1.1    kardel 			close(fd);
    520  1.1    kardel 		}
    521  1.1    kardel 	}
    522  1.1    kardel 	return 0;
    523  1.1    kardel }
    524  1.1    kardel 
    525  1.1    kardel /*
    526  1.1    kardel  * History:
    527  1.1    kardel  *
    528  1.1    kardel  * testdcf.c,v
    529  1.1    kardel  * Revision 4.10  2005/08/06 14:18:43  kardel
    530  1.1    kardel  * cleanup warnings
    531  1.1    kardel  *
    532  1.1    kardel  * Revision 4.9  2005/08/06 14:14:38  kardel
    533  1.1    kardel  * document revision on startup
    534  1.1    kardel  *
    535  1.1    kardel  * Revision 4.8  2005/08/06 14:10:08  kardel
    536  1.1    kardel  * fix setting of baud rate
    537  1.1    kardel  *
    538  1.1    kardel  * Revision 4.7  2005/04/16 17:32:10  kardel
    539  1.1    kardel  * update copyright
    540  1.1    kardel  *
    541  1.1    kardel  * Revision 4.6  2004/11/14 15:29:42  kardel
    542  1.1    kardel  * support PPSAPI, upgrade Copyright to Berkeley style
    543  1.1    kardel  *
    544  1.1    kardel  */
    545