xref: /netbsd-src/external/bsd/ntp/dist/include/ntp_refclock.h (revision eabc0478de71e4e011a5b4e0392741e01d491794)
1*eabc0478Schristos /*	$NetBSD: ntp_refclock.h,v 1.9 2024/08/18 20:46:50 christos Exp $	*/
2abb0f93cSkardel 
3abb0f93cSkardel /*
4abb0f93cSkardel  * ntp_refclock.h - definitions for reference clock support
5abb0f93cSkardel  */
6abb0f93cSkardel 
7abb0f93cSkardel #ifndef NTP_REFCLOCK_H
8abb0f93cSkardel #define NTP_REFCLOCK_H
9abb0f93cSkardel 
10abb0f93cSkardel #if defined(HAVE_SYS_MODEM_H)
11abb0f93cSkardel #include <sys/modem.h>
12abb0f93cSkardel #endif
13abb0f93cSkardel 
148585484eSchristos #include "ntp_types.h"
158585484eSchristos #include "ntp_tty.h"
16f0574a0eSchristos #include "ntp_stdlib.h"
17abb0f93cSkardel #include "recvbuff.h"
18abb0f93cSkardel 
19abb0f93cSkardel 
20abb0f93cSkardel /*
21abb0f93cSkardel  * Macros to determine the clock type and unit numbers from a
22abb0f93cSkardel  * 127.127.t.u address
23abb0f93cSkardel  */
24abb0f93cSkardel #define	REFCLOCKTYPE(srcadr)	((SRCADR(srcadr) >> 8) & 0xff)
25abb0f93cSkardel #define REFCLOCKUNIT(srcadr)	(SRCADR(srcadr) & 0xff)
26abb0f93cSkardel 
27abb0f93cSkardel /*
28abb0f93cSkardel  * List of reference clock names and descriptions. These must agree with
29abb0f93cSkardel  * lib/clocktypes.c and ntpd/refclock_conf.c.
30abb0f93cSkardel  */
31abb0f93cSkardel struct clktype {
32abb0f93cSkardel 	int code;		/* driver "major" number */
33abb0f93cSkardel 	const char *clocktype;	/* long description */
34abb0f93cSkardel 	const char *abbrev;	/* short description */
35abb0f93cSkardel };
36abb0f93cSkardel extern struct clktype clktypes[];
37abb0f93cSkardel 
38abb0f93cSkardel /*
39abb0f93cSkardel  * Configuration flag values
40abb0f93cSkardel  */
41abb0f93cSkardel #define	CLK_HAVETIME1	0x1
42abb0f93cSkardel #define	CLK_HAVETIME2	0x2
43abb0f93cSkardel #define	CLK_HAVEVAL1	0x4
44abb0f93cSkardel #define	CLK_HAVEVAL2	0x8
45abb0f93cSkardel 
46abb0f93cSkardel #define	CLK_FLAG1	0x1
47abb0f93cSkardel #define	CLK_FLAG2	0x2
48abb0f93cSkardel #define	CLK_FLAG3	0x4
49abb0f93cSkardel #define	CLK_FLAG4	0x8
50abb0f93cSkardel 
51abb0f93cSkardel #define	CLK_HAVEFLAG1	0x10
52abb0f93cSkardel #define	CLK_HAVEFLAG2	0x20
53abb0f93cSkardel #define	CLK_HAVEFLAG3	0x40
54abb0f93cSkardel #define	CLK_HAVEFLAG4	0x80
55cdfa2a7eSchristos #define	CLK_HAVEMINJIT	0x100
56abb0f93cSkardel 
57abb0f93cSkardel /*
58abb0f93cSkardel  * Constant for disabling event reporting in
59abb0f93cSkardel  * refclock_receive. ORed in leap
60abb0f93cSkardel  * parameter
61abb0f93cSkardel  */
62abb0f93cSkardel #define REFCLOCK_OWN_STATES	0x80
63abb0f93cSkardel 
64abb0f93cSkardel /*
65abb0f93cSkardel  * Structure for returning clock status
66abb0f93cSkardel  */
67abb0f93cSkardel struct refclockstat {
68abb0f93cSkardel 	u_char	type;		/* clock type */
69abb0f93cSkardel 	u_char	flags;		/* clock flags */
70cdfa2a7eSchristos 	u_short	haveflags;	/* bit array of valid flags */
71abb0f93cSkardel 	u_short	lencode;	/* length of last timecode */
72abb0f93cSkardel 	const char *p_lastcode;	/* last timecode received */
73abb0f93cSkardel 	u_int32	polls;		/* transmit polls */
74abb0f93cSkardel 	u_int32	noresponse;	/* no response to poll */
75abb0f93cSkardel 	u_int32	badformat;	/* bad format timecode received */
76abb0f93cSkardel 	u_int32	baddata;	/* invalid data timecode received */
77abb0f93cSkardel 	u_int32	timereset;	/* driver resets */
78abb0f93cSkardel 	const char *clockdesc;	/* ASCII description */
79cdfa2a7eSchristos 	double	fudgeminjitter;	/* configure fudge minjitter */
80abb0f93cSkardel 	double	fudgetime1;	/* configure fudge time1 */
81abb0f93cSkardel 	double	fudgetime2;	/* configure fudge time2 */
82abb0f93cSkardel 	int32	fudgeval1;	/* configure fudge value1 */
83f003fb54Skardel 	u_int32	fudgeval2;	/* configure fudge value2 */
84abb0f93cSkardel 	u_char	currentstatus;	/* clock status */
85abb0f93cSkardel 	u_char	lastevent;	/* last exception event */
86abb0f93cSkardel 	u_char	leap;		/* leap bits */
87abb0f93cSkardel 	struct	ctl_var *kv_list; /* additional variables */
88abb0f93cSkardel };
89abb0f93cSkardel 
90abb0f93cSkardel /*
91abb0f93cSkardel  * Reference clock I/O structure.  Used to provide an interface between
92abb0f93cSkardel  * the reference clock drivers and the I/O module.
93abb0f93cSkardel  */
94abb0f93cSkardel struct refclockio {
95abb0f93cSkardel 	struct	refclockio *next; /* link to next structure */
96abb0f93cSkardel 	void	(*clock_recv) (struct recvbuf *); /* completion routine */
97abb0f93cSkardel 	int 	(*io_input)   (struct recvbuf *); /* input routine -
98abb0f93cSkardel 				to avoid excessive buffer use
99abb0f93cSkardel 				due to small bursts
100abb0f93cSkardel 				of refclock input data */
1018585484eSchristos 	struct peer *srcclock;	/* refclock peer */
1028585484eSchristos 	int	datalen;	/* length of data */
103abb0f93cSkardel 	int	fd;		/* file descriptor */
104abb0f93cSkardel 	u_long	recvcount;	/* count of receive completions */
1058585484eSchristos 	int	active;		/* nonzero when in use */
1068585484eSchristos 
1078585484eSchristos #ifdef HAVE_IO_COMPLETION_PORT
10868dbbb44Schristos 	void *	ioreg_ctx;	/* IO registration context */
10968dbbb44Schristos 	void *	device_ctx;	/* device-related data for i/o subsystem */
1108585484eSchristos #endif
111abb0f93cSkardel };
112abb0f93cSkardel 
113abb0f93cSkardel /*
114abb0f93cSkardel  * Structure for returning debugging info
115abb0f93cSkardel  */
116abb0f93cSkardel #define	NCLKBUGVALUES	16
117abb0f93cSkardel #define	NCLKBUGTIMES	32
118abb0f93cSkardel 
119abb0f93cSkardel struct refclockbug {
120abb0f93cSkardel 	u_char	nvalues;	/* values following */
121abb0f93cSkardel 	u_char	ntimes;		/* times following */
122abb0f93cSkardel 	u_short	svalues;	/* values format sign array */
123abb0f93cSkardel 	u_int32	stimes;		/* times format sign array */
124abb0f93cSkardel 	u_int32	values[NCLKBUGVALUES]; /* real values */
125abb0f93cSkardel 	l_fp	times[NCLKBUGTIMES]; /* real times */
126abb0f93cSkardel };
127abb0f93cSkardel 
1288585484eSchristos #ifdef HAVE_IO_COMPLETION_PORT
1298585484eSchristos extern	HANDLE	WaitableIoEventHandle;
1308585484eSchristos #endif
1318585484eSchristos 
132abb0f93cSkardel /*
133abb0f93cSkardel  * Structure interface between the reference clock support
134abb0f93cSkardel  * ntp_refclock.c and the driver utility routines
135abb0f93cSkardel  */
136cdfa2a7eSchristos #define MAXSTAGE	64	/* max median filter stages  */
137abb0f93cSkardel #define NSTAGE		5	/* default median filter stages */
138abb0f93cSkardel #define BMAX		128	/* max timecode length */
139abb0f93cSkardel #define GMT		0	/* I hope nobody sees this */
140abb0f93cSkardel #define MAXDIAL		60	/* max length of modem dial strings */
141abb0f93cSkardel 
142abb0f93cSkardel struct refclockproc {
143f003fb54Skardel 	void *	unitptr;	/* pointer to unit structure */
1448585484eSchristos 	struct refclock * conf;	/* refclock_conf[type] */
1458585484eSchristos 	struct refclockio io;	/* I/O handler structure */
146abb0f93cSkardel 	u_char	leap;		/* leap/synchronization code */
147abb0f93cSkardel 	u_char	currentstatus;	/* clock status */
148abb0f93cSkardel 	u_char	lastevent;	/* last exception event */
149abb0f93cSkardel 	u_char	type;		/* clock type */
150cdfa2a7eSchristos 	u_char	inpoll;		/* waiting for 'refclock_receive()' */
151abb0f93cSkardel 	const char *clockdesc;	/* clock description */
1528585484eSchristos 	u_long	nextaction;	/* local activity timeout */
1538585484eSchristos 	void	(*action)(struct peer *); /* timeout callback */
154abb0f93cSkardel 
155abb0f93cSkardel 	char	a_lastcode[BMAX]; /* last timecode received */
156abb0f93cSkardel 	int	lencode;	/* length of last timecode */
157abb0f93cSkardel 
158abb0f93cSkardel 	int	year;		/* year of eternity */
159abb0f93cSkardel 	int	day;		/* day of year */
160abb0f93cSkardel 	int	hour;		/* hour of day */
161abb0f93cSkardel 	int	minute;		/* minute of hour */
162abb0f93cSkardel 	int	second;		/* second of minute */
163abb0f93cSkardel 	long	nsec;		/* nanosecond of second */
164abb0f93cSkardel 	u_long	yearstart;	/* beginning of year */
165cdfa2a7eSchristos 	u_int	coderecv;	/* put pointer */
166cdfa2a7eSchristos 	u_int	codeproc;	/* get pointer */
167abb0f93cSkardel 	l_fp	lastref;	/* reference timestamp */
168abb0f93cSkardel 	l_fp	lastrec;	/* receive timestamp */
169abb0f93cSkardel 	double	offset;		/* mean offset */
170abb0f93cSkardel 	double	disp;		/* sample dispersion */
171abb0f93cSkardel 	double	jitter;		/* jitter (mean squares) */
172abb0f93cSkardel 	double	filter[MAXSTAGE]; /* median filter */
173abb0f93cSkardel 
174abb0f93cSkardel 	/*
175abb0f93cSkardel 	 * Configuration data
176abb0f93cSkardel 	 */
177abb0f93cSkardel 	double	fudgetime1;	/* fudge time1 */
178abb0f93cSkardel 	double	fudgetime2;	/* fudge time2 */
179cdfa2a7eSchristos 	double	fudgeminjitter;	/* manually set lower bound for jitter */
180abb0f93cSkardel 	u_char	stratum;	/* server stratum */
181abb0f93cSkardel 	u_int32	refid;		/* reference identifier */
182abb0f93cSkardel 	u_char	sloppyclockflag; /* fudge flags */
183abb0f93cSkardel 
184abb0f93cSkardel 	/*
185abb0f93cSkardel 	 * Status tallies
186abb0f93cSkardel  	 */
187abb0f93cSkardel 	u_long	timestarted;	/* time we started this */
188abb0f93cSkardel 	u_long	polls;		/* polls sent */
189abb0f93cSkardel 	u_long	noreply;	/* no replies to polls */
190abb0f93cSkardel 	u_long	badformat;	/* bad format reply */
191abb0f93cSkardel 	u_long	baddata;	/* bad data reply */
192abb0f93cSkardel };
193abb0f93cSkardel 
194abb0f93cSkardel /*
195abb0f93cSkardel  * Structure interface between the reference clock support
196abb0f93cSkardel  * ntp_refclock.c and particular clock drivers. This must agree with the
197abb0f93cSkardel  * structure defined in the driver.
198abb0f93cSkardel  */
199abb0f93cSkardel #define	noentry	0		/* flag for null routine */
200abb0f93cSkardel #define	NOFLAGS	0		/* flag for null flags */
201abb0f93cSkardel 
202abb0f93cSkardel struct refclock {
203abb0f93cSkardel 	int (*clock_start)	(int, struct peer *);
204abb0f93cSkardel 	void (*clock_shutdown)	(int, struct peer *);
205abb0f93cSkardel 	void (*clock_poll)	(int, struct peer *);
2068585484eSchristos 	void (*clock_control)	(int, const struct refclockstat *,
207abb0f93cSkardel 				 struct refclockstat *, struct peer *);
208abb0f93cSkardel 	void (*clock_init)	(void);
209abb0f93cSkardel 	void (*clock_buginfo)	(int, struct refclockbug *, struct peer *);
210abb0f93cSkardel 	void (*clock_timer)	(int, struct peer *);
211abb0f93cSkardel };
212abb0f93cSkardel 
213abb0f93cSkardel /*
214abb0f93cSkardel  * Function prototypes
215abb0f93cSkardel  */
216abb0f93cSkardel extern	int	io_addclock	(struct refclockio *);
217abb0f93cSkardel extern	void	io_closeclock	(struct refclockio *);
218abb0f93cSkardel 
219*eabc0478Schristos #define FDWRITE_ERROR	((size_t)-1)
220*eabc0478Schristos 
221abb0f93cSkardel #ifdef REFCLOCK
222abb0f93cSkardel extern	void	refclock_buginfo(sockaddr_u *,
223abb0f93cSkardel 				 struct refclockbug *);
224abb0f93cSkardel extern	void	refclock_control(sockaddr_u *,
2258585484eSchristos 				 const struct refclockstat *,
226abb0f93cSkardel 				 struct refclockstat *);
227*eabc0478Schristos extern	int	refclock_open	(const sockaddr_u *srcadr, const char *, u_int, u_int);
228abb0f93cSkardel extern	int	refclock_setup	(int, u_int, u_int);
229abb0f93cSkardel extern	void	refclock_timer	(struct peer *);
230abb0f93cSkardel extern	void	refclock_transmit(struct peer *);
231abb0f93cSkardel extern 	int	refclock_process(struct refclockproc *);
232abb0f93cSkardel extern 	int	refclock_process_f(struct refclockproc *, double);
2338585484eSchristos extern 	void	refclock_process_offset(struct refclockproc *, l_fp,
2348585484eSchristos 					l_fp, double);
235cdfa2a7eSchristos extern	int	refclock_samples_avail(struct refclockproc const *);
236cdfa2a7eSchristos extern	int	refclock_samples_expire(struct refclockproc *, int);
237abb0f93cSkardel extern	void	refclock_report	(struct peer *, int);
238abb0f93cSkardel extern	int	refclock_gtlin	(struct recvbuf *, char *, int, l_fp *);
239abb0f93cSkardel extern	int	refclock_gtraw	(struct recvbuf *, char *, int, l_fp *);
240*eabc0478Schristos extern	size_t	refclock_write  (const struct peer *, const void *, size_t,
241*eabc0478Schristos 				 const char * what);
242*eabc0478Schristos extern	size_t	refclock_fdwrite(const struct peer *, int, const void *, size_t,
243*eabc0478Schristos 				 const char * what);
2448585484eSchristos extern	int	indicate_refclock_packet(struct refclockio *,
2458585484eSchristos 					 struct recvbuf *);
2468585484eSchristos extern	void	process_refclock_packet(struct recvbuf *);
247cdfa2a7eSchristos 
248cdfa2a7eSchristos /* save string as la_code, size==(size_t)-1 ==> ASCIIZ string */
249cdfa2a7eSchristos extern	void	refclock_save_lcode(
250cdfa2a7eSchristos 			struct refclockproc *, char const *, size_t);
251cdfa2a7eSchristos /* format data into la_code */
252cdfa2a7eSchristos extern	void	refclock_format_lcode(
2535b7d12e4Schristos 			struct refclockproc *, char const *, ...)
2545b7d12e4Schristos 			NTP_PRINTF(2, 3);
255cdfa2a7eSchristos extern	void	refclock_vformat_lcode(
256f0574a0eSchristos 			struct refclockproc *, char const *, va_list)
2575b7d12e4Schristos 			NTP_PRINTF(2, 0);
258cdfa2a7eSchristos 
259cdfa2a7eSchristos struct refclock_atom;
260cdfa2a7eSchristos extern int	refclock_ppsaugment(
261cdfa2a7eSchristos     const struct refclock_atom*, l_fp *rcvtime ,
262cdfa2a7eSchristos     double rcvfudge, double ppsfudge);
263cdfa2a7eSchristos 
264*eabc0478Schristos extern int ppsdev_reopen(const sockaddr_u *srcadr,
265*eabc0478Schristos 			 int ttyfd, int ppsfd, const char *ppspath,
266*eabc0478Schristos 			 int mode, int flags);
267*eabc0478Schristos extern void ppsdev_close(int ttyfd, int ppsfd);
268*eabc0478Schristos 
269abb0f93cSkardel #endif /* REFCLOCK */
270abb0f93cSkardel 
271abb0f93cSkardel #endif /* NTP_REFCLOCK_H */
272