ppsapitest.c revision 123303
1/*-
2 * Copyright (c) 1998-2003 Poul-Henning Kamp
3 *
4 * Please see src/share/examples/etc/bsd-style-copyright.
5 *
6 */
7
8#include <sys/cdefs.h>
9__FBSDID("$FreeBSD: head/tools/test/ppsapi/ppsapitest.c 123303 2003-12-08 20:49:40Z phk $");
10
11#include <stdio.h>
12#include <stdint.h>
13#include <stdlib.h>
14#include <unistd.h>
15#include <fcntl.h>
16#include <err.h>
17#include <sys/timepps.h>
18
19static int aflag, Aflag, cflag, Cflag, eflag, uflag, vflag;
20
21static void
22Chew(struct timespec *tsa, struct timespec *tsc, unsigned sa, unsigned sc)
23{
24	printf("%jd .%09ld %u", (intmax_t)tsa->tv_sec, tsa->tv_nsec, sa);
25	printf(" %jd .%09ld %u\n", (intmax_t)tsc->tv_sec, tsc->tv_nsec, sc);
26	if (uflag)
27		fflush(stdout);
28}
29
30int
31main(int argc, char **argv)
32{
33	int fd;
34	pps_info_t pi;
35	pps_params_t pp;
36	pps_handle_t ph;
37	int i, mode;
38	u_int olda, oldc;
39	struct timespec to;
40
41	while ((i = getopt(argc, argv, "aAbBcCeuv")) != -1) {
42		switch (i) {
43		case 'a': aflag = 1; break;
44		case 'A': Aflag = 1; break;
45		case 'b': aflag = 1; cflag = 1; break;
46		case 'B': Aflag = 1; Cflag = 1; break;
47		case 'c': cflag = 1; break;
48		case 'C': Cflag = 1; break;
49		case 'e': eflag = 1; break;
50		case 'u': uflag = 1; break;
51		case 'v': vflag = 1; break;
52		case '?':
53		default:
54			fprintf(stderr,
55			    "Usage: ppsapitest [-aAcC] device\n");
56			exit (1);
57		}
58	}
59	argc -= optind;
60	argv += optind;
61	if (argc > 0) {
62		fd = open(argv[0], O_RDONLY);
63		if (fd < 0)
64			err(1, argv[0]);
65	} else {
66		fd = 0;
67	}
68	i = time_pps_create(fd, &ph);
69	if (i < 0)
70		err(1, "time_pps_create");
71
72	i = time_pps_getcap(ph, &mode);
73	if (i < 0)
74		err(1, "time_pps_getcap");
75	if (vflag) {
76		fprintf(stderr, "Supported modebits:");
77		if (mode & PPS_CAPTUREASSERT)
78			fprintf(stderr, " CAPTUREASSERT");
79		if (mode & PPS_CAPTURECLEAR)
80			fprintf(stderr, " CAPTURECLEAR");
81		if (mode & PPS_OFFSETASSERT)
82			fprintf(stderr, " OFFSETASSERT");
83		if (mode & PPS_OFFSETCLEAR)
84			fprintf(stderr, " OFFSETCLEAR");
85		if (mode & PPS_ECHOASSERT)
86			fprintf(stderr, " ECHOASSERT");
87		if (mode & PPS_ECHOCLEAR)
88			fprintf(stderr, " ECHOCLEAR");
89		if (mode & PPS_CANWAIT)
90			fprintf(stderr, " CANWAIT");
91		if (mode & PPS_CANPOLL)
92			fprintf(stderr, " CANPOLL");
93		if (mode & PPS_TSFMT_TSPEC)
94			fprintf(stderr, " TSPEC");
95		if (mode & PPS_TSFMT_NTPFP)
96			fprintf(stderr, " NTPFP");
97		fprintf(stderr, "\n");
98	}
99
100	if (!aflag && !cflag) {
101		if (mode & PPS_CAPTUREASSERT)
102			aflag = 1;
103		if (mode & PPS_CAPTURECLEAR)
104			cflag = 1;
105	}
106	if (!Aflag && !Cflag) {
107		Aflag = aflag;
108		Cflag = cflag;
109	}
110
111	if (Cflag && !(mode & PPS_CAPTURECLEAR))
112		errx(1, "-C but cannot capture on clear flank");
113
114	if (Aflag && !(mode & PPS_CAPTUREASSERT))
115		errx(1, "-A but cannot capture on assert flank");
116
117	i = time_pps_getparams(ph, &pp);
118	if (i < 0)
119		err(1, "time_pps_getparams():");
120
121	if (aflag)
122		pp.mode |= PPS_CAPTUREASSERT;
123	if (cflag)
124		pp.mode |= PPS_CAPTURECLEAR;
125
126	if (eflag & aflag)
127		pp.mode |= PPS_ECHOASSERT;
128
129	if (eflag & cflag)
130		pp.mode |= PPS_ECHOCLEAR;
131
132	if (!(pp.mode & PPS_TSFMT_TSPEC))
133		pp.mode |= PPS_TSFMT_TSPEC;
134
135	i = time_pps_setparams(ph, &pp);
136	if (i < 0) {
137		err(1, "time_pps_setparams(mode %x):", pp.mode);
138	}
139
140	/*
141	 * Pick up first event outside the loop in order to not
142	 * get something ancient into the outfile.
143	 */
144	to.tv_nsec = 0;
145	to.tv_sec = 0;
146	i = time_pps_fetch(ph, PPS_TSFMT_TSPEC, &pi, &to);
147	if (i < 0)
148		err(1, "time_pps_fetch()");
149	olda = pi.assert_sequence;
150	oldc = pi.clear_sequence;
151
152	while (1) {
153		to.tv_nsec = 0;
154		to.tv_sec = 0;
155		i = time_pps_fetch(ph, PPS_TSFMT_TSPEC, &pi, &to);
156		if (i < 0)
157			err(1, "time_pps_fetch()");
158		if (oldc != pi.clear_sequence && Cflag)
159			;
160		else if (olda != pi.assert_sequence && Aflag)
161			;
162		else {
163			usleep(10000);
164			continue;
165		}
166		Chew(&pi.assert_timestamp, &pi.clear_timestamp,
167			pi.assert_sequence, pi.clear_sequence);
168		olda = pi.assert_sequence;
169		oldc = pi.clear_sequence;
170	}
171	return(0);
172}
173