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