📄 chutest.c
字号:
/* chutest.c,v 3.1 1993/07/06 01:05:21 jbj Exp * chutest - test the CHU clock */#include <stdio.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <sys/ioctl.h>#include <sys/time.h>#include <sys/file.h>#include <sgtty.h>#include "../include/ntp_fp.h"#include "../include/ntp.h"#include "../include/ntp_unixtime.h"#ifdef CHULDISC#ifdef STREAM# ifdef HAVE_SYS_CHUDEFS_H#include <sys/chudefs.h>#endif#include <stropts.h>#endif#endif#ifdef CHULDISC# ifdef HAVE_SYS_CHUDEFS_H#include <sys/chudefs.h>#endif#endif#ifndef CHULDISC#ifndef STREAM#define NCHUCHARS (10)struct chucode { u_char codechars[NCHUCHARS]; /* code characters */ u_char ncodechars; /* number of code characters */ u_char chustatus; /* not used currently */ struct timeval codetimes[NCHUCHARS]; /* arrival times */};#endif#endif#define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0)char *progname;int debug;int dofilter = 0; /* set to 1 when we should run filter algorithm */int showtimes = 0; /* set to 1 when we should show char arrival times */int doprocess = 0; /* set to 1 when we do processing analogous to driver */#ifdef CHULDISCint usechuldisc = 0; /* set to 1 when CHU line discipline should be used */#endif#ifdef STREAMint usechuldisc = 0; /* set to 1 when CHU line discipline should be used */#endifstruct timeval lasttv;struct chucode chudata;extern u_long ustotslo[];extern u_long ustotsmid[];extern u_long ustotshi[];/* * main - parse arguments and handle options */intmain( int argc, char *argv[] ){ int c; int errflg = 0; extern int ntp_optind; extern char *ntp_optarg; void init_chu(); progname = argv[0]; while ((c = ntp_getopt(argc, argv, "cdfpt")) != EOF) switch (c) { case 'c':#ifdef STREAM usechuldisc = 1; break;#endif#ifdef CHULDISC usechuldisc = 1; break;#endif#ifndef STREAM#ifndef CHULDISC (void) fprintf(stderr, "%s: CHU line discipline not available on this machine\n", progname); exit(2);#endif#endif case 'd': ++debug; break; case 'f': dofilter = 1; break; case 'p': doprocess = 1; case 't': showtimes = 1; break; default: errflg++; break; } if (errflg || ntp_optind+1 != argc) {#ifdef STREAM (void) fprintf(stderr, "usage: %s [-dft] tty_device\n", progname);#endif#ifdef CHULDISC (void) fprintf(stderr, "usage: %s [-dft] tty_device\n", progname);#endif#ifndef STREAM#ifndef CHULDISC (void) fprintf(stderr, "usage: %s [-cdft] tty_device\n", progname);#endif#endif exit(2); } (void) gettimeofday(&lasttv, (struct timezone *)0); c = openterm(argv[ntp_optind]); init_chu();#ifdef STREAM if (usechuldisc) process_ldisc(c); else#endif#ifdef CHULDISC if (usechuldisc) process_ldisc(c); else#endif process_raw(c); /*NOTREACHED*/}/* * openterm - open a port to the CHU clock */intopenterm( char *dev ){ int s; struct sgttyb ttyb; if (debug) (void) fprintf(stderr, "Doing open..."); if ((s = open(dev, O_RDONLY, 0777)) < 0) error("open(%s)", dev, ""); if (debug) (void) fprintf(stderr, "open okay\n"); if (debug) (void) fprintf(stderr, "Setting exclusive use..."); if (ioctl(s, TIOCEXCL, (char *)0) < 0) error("ioctl(TIOCEXCL)", "", ""); if (debug) (void) fprintf(stderr, "done\n"); ttyb.sg_ispeed = ttyb.sg_ospeed = B300; ttyb.sg_erase = ttyb.sg_kill = 0; ttyb.sg_flags = EVENP|ODDP|RAW; if (debug) (void) fprintf(stderr, "Setting baud rate et al..."); if (ioctl(s, TIOCSETP, (char *)&ttyb) < 0) error("ioctl(TIOCSETP, raw)", "", ""); if (debug) (void) fprintf(stderr, "done\n");#ifdef CHULDISC if (usechuldisc) { int ldisc; if (debug) (void) fprintf(stderr, "Switching to CHU ldisc..."); ldisc = CHULDISC; if (ioctl(s, TIOCSETD, (char *)&ldisc) < 0) error("ioctl(TIOCSETD, CHULDISC)", "", ""); if (debug) (void) fprintf(stderr, "okay\n"); }#endif#ifdef STREAM if (usechuldisc) { if (debug) (void) fprintf(stderr, "Poping off streams..."); while (ioctl(s, I_POP, 0) >=0) ; if (debug) (void) fprintf(stderr, "okay\n"); if (debug) (void) fprintf(stderr, "Pushing CHU stream..."); if (ioctl(s, I_PUSH, "chu") < 0) error("ioctl(I_PUSH, \"chu\")", "", ""); if (debug) (void) fprintf(stderr, "okay\n"); }#endif return s;}/* * process_raw - process characters in raw mode */intprocess_raw( int s ){ u_char c; int n; struct timeval tv; struct timeval difftv; while ((n = read(s, &c, sizeof(char))) > 0) { (void) gettimeofday(&tv, (struct timezone *)0); if (dofilter) raw_filter((unsigned int)c, &tv); else { difftv.tv_sec = tv.tv_sec - lasttv.tv_sec; difftv.tv_usec = tv.tv_usec - lasttv.tv_usec; if (difftv.tv_usec < 0) { difftv.tv_sec--; difftv.tv_usec += 1000000; } (void) printf("%02x\t%lu.%06lu\t%lu.%06lu\n", c, tv.tv_sec, tv.tv_usec, difftv.tv_sec, difftv.tv_usec); lasttv = tv; } } if (n == 0) { (void) fprintf(stderr, "%s: zero returned on read\n", progname); exit(1); } else error("read()", "", "");}/* * raw_filter - run the line discipline filter over raw data */intraw_filter( unsigned int c, struct timeval *tv ){ static struct timeval diffs[10] = { 0 }; struct timeval diff; l_fp ts; void chufilter(); if ((c & 0xf) > 9 || ((c>>4)&0xf) > 9) { if (debug) (void) fprintf(stderr, "character %02x failed BCD test\n"); chudata.ncodechars = 0; return; } if (chudata.ncodechars > 0) { diff.tv_sec = tv->tv_sec - chudata.codetimes[chudata.ncodechars].tv_sec; diff.tv_usec = tv->tv_usec - chudata.codetimes[chudata.ncodechars].tv_usec; if (diff.tv_usec < 0) { diff.tv_sec--; diff.tv_usec += 1000000; } /* if (diff.tv_sec != 0 || diff.tv_usec > 900000) { if (debug) (void) fprintf(stderr, "character %02x failed time test\n"); chudata.ncodechars = 0; return; } */ } chudata.codechars[chudata.ncodechars] = c; chudata.codetimes[chudata.ncodechars] = *tv; if (chudata.ncodechars > 0) diffs[chudata.ncodechars] = diff; if (++chudata.ncodechars == 10) { if (doprocess) { TVTOTS(&chudata.codetimes[NCHUCHARS-1], &ts); ts.l_ui += JAN_1970; chufilter(&chudata, &chudata.codetimes[NCHUCHARS-1]); } else { register int i; for (i = 0; i < chudata.ncodechars; i++) { (void) printf("%x%x\t%lu.%06lu\t%lu.%06lu\n", chudata.codechars[i] & 0xf, (chudata.codechars[i] >>4 ) & 0xf, chudata.codetimes[i].tv_sec, chudata.codetimes[i].tv_usec, diffs[i].tv_sec, diffs[i].tv_usec); } } chudata.ncodechars = 0; }}/* #ifdef CHULDISC*//* * process_ldisc - process line discipline */intprocess_ldisc( int s ){ struct chucode chu; int n; register int i; struct timeval diff; l_fp ts; void chufilter(); while ((n = read(s, (char *)&chu, sizeof chu)) > 0) { if (n != sizeof chu) { (void) fprintf(stderr, "Expected %d, got %d\n", sizeof chu, n); continue; } if (doprocess) { TVTOTS(&chu.codetimes[NCHUCHARS-1], &ts); ts.l_ui += JAN_1970; chufilter(&chu, &ts); } else { for (i = 0; i < NCHUCHARS; i++) { if (i == 0) diff.tv_sec = diff.tv_usec = 0; else { diff.tv_sec = chu.codetimes[i].tv_sec - chu.codetimes[i-1].tv_sec; diff.tv_usec = chu.codetimes[i].tv_usec - chu.codetimes[i-1].tv_usec; if (diff.tv_usec < 0) { diff.tv_sec--; diff.tv_usec += 1000000; } } (void) printf("%x%x\t%lu.%06lu\t%lu.%06lu\n", chu.codechars[i] & 0xf, (chu.codechars[i]>>4)&0xf, chu.codetimes[i].tv_sec, chu.codetimes[i].tv_usec, diff.tv_sec, diff.tv_usec); } } } if (n == 0) { (void) fprintf(stderr, "%s: zero returned on read\n", progname); exit(1); } else error("read()", "", "");}/*#endif*//* * error - print an error message */voiderror( char *fmt, char *s1, char *s2 ){ (void) fprintf(stderr, "%s: ", progname); (void) fprintf(stderr, fmt, s1, s2); (void) fprintf(stderr, ": "); perror(""); exit(1);}/* * Definitions */#define MAXUNITS 4 /* maximum number of CHU units permitted */#define CHUDEV "/dev/chu%d" /* device we open. %d is unit number */#define NCHUCODES 9 /* expect 9 CHU codes per minute *//* * When CHU is operating optimally we want the primary clock distance
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -