xref: /freebsd/contrib/ntp/include/ntp_refclock.h (revision a466cc55373fc3cf86837f09da729535b57e69a1)
1c0b746e5SOllivier Robert /*
2c0b746e5SOllivier Robert  * ntp_refclock.h - definitions for reference clock support
3c0b746e5SOllivier Robert  */
4c0b746e5SOllivier Robert 
5c0b746e5SOllivier Robert #ifndef NTP_REFCLOCK_H
6c0b746e5SOllivier Robert #define NTP_REFCLOCK_H
7c0b746e5SOllivier Robert 
8c0b746e5SOllivier Robert #if defined(HAVE_SYS_MODEM_H)
9c0b746e5SOllivier Robert #include <sys/modem.h>
10c0b746e5SOllivier Robert #endif
11c0b746e5SOllivier Robert 
122b15cb3dSCy Schubert #include "ntp_types.h"
132b15cb3dSCy Schubert #include "ntp_tty.h"
14c0b746e5SOllivier Robert #include "recvbuff.h"
15c0b746e5SOllivier Robert 
16c0b746e5SOllivier Robert 
17c0b746e5SOllivier Robert /*
18c0b746e5SOllivier Robert  * Macros to determine the clock type and unit numbers from a
19c0b746e5SOllivier Robert  * 127.127.t.u address
20c0b746e5SOllivier Robert  */
21c0b746e5SOllivier Robert #define	REFCLOCKTYPE(srcadr)	((SRCADR(srcadr) >> 8) & 0xff)
22c0b746e5SOllivier Robert #define REFCLOCKUNIT(srcadr)	(SRCADR(srcadr) & 0xff)
23c0b746e5SOllivier Robert 
24c0b746e5SOllivier Robert /*
25c0b746e5SOllivier Robert  * List of reference clock names and descriptions. These must agree with
26c0b746e5SOllivier Robert  * lib/clocktypes.c and ntpd/refclock_conf.c.
27c0b746e5SOllivier Robert  */
28c0b746e5SOllivier Robert struct clktype {
29c0b746e5SOllivier Robert 	int code;		/* driver "major" number */
30c0b746e5SOllivier Robert 	const char *clocktype;	/* long description */
31c0b746e5SOllivier Robert 	const char *abbrev;	/* short description */
32c0b746e5SOllivier Robert };
33ea906c41SOllivier Robert extern struct clktype clktypes[];
34c0b746e5SOllivier Robert 
35c0b746e5SOllivier Robert /*
36c0b746e5SOllivier Robert  * Configuration flag values
37c0b746e5SOllivier Robert  */
38c0b746e5SOllivier Robert #define	CLK_HAVETIME1	0x1
39c0b746e5SOllivier Robert #define	CLK_HAVETIME2	0x2
40c0b746e5SOllivier Robert #define	CLK_HAVEVAL1	0x4
41c0b746e5SOllivier Robert #define	CLK_HAVEVAL2	0x8
42c0b746e5SOllivier Robert 
43c0b746e5SOllivier Robert #define	CLK_FLAG1	0x1
44c0b746e5SOllivier Robert #define	CLK_FLAG2	0x2
45c0b746e5SOllivier Robert #define	CLK_FLAG3	0x4
46c0b746e5SOllivier Robert #define	CLK_FLAG4	0x8
47c0b746e5SOllivier Robert 
48c0b746e5SOllivier Robert #define	CLK_HAVEFLAG1	0x10
49c0b746e5SOllivier Robert #define	CLK_HAVEFLAG2	0x20
50c0b746e5SOllivier Robert #define	CLK_HAVEFLAG3	0x40
51c0b746e5SOllivier Robert #define	CLK_HAVEFLAG4	0x80
522d4e511cSCy Schubert #define	CLK_HAVEMINJIT	0x100
53c0b746e5SOllivier Robert 
54c0b746e5SOllivier Robert /*
55c0b746e5SOllivier Robert  * Constant for disabling event reporting in
56c0b746e5SOllivier Robert  * refclock_receive. ORed in leap
57c0b746e5SOllivier Robert  * parameter
58c0b746e5SOllivier Robert  */
59c0b746e5SOllivier Robert #define REFCLOCK_OWN_STATES	0x80
60c0b746e5SOllivier Robert 
61c0b746e5SOllivier Robert /*
62c0b746e5SOllivier Robert  * Structure for returning clock status
63c0b746e5SOllivier Robert  */
64c0b746e5SOllivier Robert struct refclockstat {
65c0b746e5SOllivier Robert 	u_char	type;		/* clock type */
66c0b746e5SOllivier Robert 	u_char	flags;		/* clock flags */
672d4e511cSCy Schubert 	u_short	haveflags;	/* bit array of valid flags */
68c0b746e5SOllivier Robert 	u_short	lencode;	/* length of last timecode */
69c0b746e5SOllivier Robert 	const char *p_lastcode;	/* last timecode received */
70c0b746e5SOllivier Robert 	u_int32	polls;		/* transmit polls */
71c0b746e5SOllivier Robert 	u_int32	noresponse;	/* no response to poll */
72c0b746e5SOllivier Robert 	u_int32	badformat;	/* bad format timecode received */
73c0b746e5SOllivier Robert 	u_int32	baddata;	/* invalid data timecode received */
74c0b746e5SOllivier Robert 	u_int32	timereset;	/* driver resets */
75c0b746e5SOllivier Robert 	const char *clockdesc;	/* ASCII description */
762d4e511cSCy Schubert 	double	fudgeminjitter;	/* configure fudge minjitter */
77c0b746e5SOllivier Robert 	double	fudgetime1;	/* configure fudge time1 */
78c0b746e5SOllivier Robert 	double	fudgetime2;	/* configure fudge time2 */
79c0b746e5SOllivier Robert 	int32	fudgeval1;	/* configure fudge value1 */
802b15cb3dSCy Schubert 	u_int32	fudgeval2;	/* configure fudge value2 */
81c0b746e5SOllivier Robert 	u_char	currentstatus;	/* clock status */
82c0b746e5SOllivier Robert 	u_char	lastevent;	/* last exception event */
83c0b746e5SOllivier Robert 	u_char	leap;		/* leap bits */
84c0b746e5SOllivier Robert 	struct	ctl_var *kv_list; /* additional variables */
85c0b746e5SOllivier Robert };
86c0b746e5SOllivier Robert 
87c0b746e5SOllivier Robert /*
88c0b746e5SOllivier Robert  * Reference clock I/O structure.  Used to provide an interface between
89c0b746e5SOllivier Robert  * the reference clock drivers and the I/O module.
90c0b746e5SOllivier Robert  */
91c0b746e5SOllivier Robert struct refclockio {
92c0b746e5SOllivier Robert 	struct	refclockio *next; /* link to next structure */
932b15cb3dSCy Schubert 	void	(*clock_recv) (struct recvbuf *); /* completion routine */
942b15cb3dSCy Schubert 	int 	(*io_input)   (struct recvbuf *); /* input routine -
95c0b746e5SOllivier Robert 				to avoid excessive buffer use
96c0b746e5SOllivier Robert 				due to small bursts
97c0b746e5SOllivier Robert 				of refclock input data */
982b15cb3dSCy Schubert 	struct peer *srcclock;	/* refclock peer */
992b15cb3dSCy Schubert 	int	datalen;	/* length of data */
1002b15cb3dSCy Schubert 	int	fd;		/* file descriptor */
101c0b746e5SOllivier Robert 	u_long	recvcount;	/* count of receive completions */
1022b15cb3dSCy Schubert 	int	active;		/* nonzero when in use */
1032b15cb3dSCy Schubert 
1042b15cb3dSCy Schubert #ifdef HAVE_IO_COMPLETION_PORT
1054990d495SXin LI 	void *	ioreg_ctx;	/* IO registration context */
1064990d495SXin LI 	void *	device_ctx;	/* device-related data for i/o subsystem */
1072b15cb3dSCy Schubert #endif
108c0b746e5SOllivier Robert };
109c0b746e5SOllivier Robert 
110c0b746e5SOllivier Robert /*
111c0b746e5SOllivier Robert  * Structure for returning debugging info
112c0b746e5SOllivier Robert  */
113c0b746e5SOllivier Robert #define	NCLKBUGVALUES	16
114c0b746e5SOllivier Robert #define	NCLKBUGTIMES	32
115c0b746e5SOllivier Robert 
116c0b746e5SOllivier Robert struct refclockbug {
117c0b746e5SOllivier Robert 	u_char	nvalues;	/* values following */
118c0b746e5SOllivier Robert 	u_char	ntimes;		/* times following */
119c0b746e5SOllivier Robert 	u_short	svalues;	/* values format sign array */
120c0b746e5SOllivier Robert 	u_int32	stimes;		/* times format sign array */
121c0b746e5SOllivier Robert 	u_int32	values[NCLKBUGVALUES]; /* real values */
122c0b746e5SOllivier Robert 	l_fp	times[NCLKBUGTIMES]; /* real times */
123c0b746e5SOllivier Robert };
124c0b746e5SOllivier Robert 
1252b15cb3dSCy Schubert #ifdef HAVE_IO_COMPLETION_PORT
1262b15cb3dSCy Schubert extern	HANDLE	WaitableIoEventHandle;
1272b15cb3dSCy Schubert #endif
1282b15cb3dSCy Schubert 
129c0b746e5SOllivier Robert /*
130c0b746e5SOllivier Robert  * Structure interface between the reference clock support
131c0b746e5SOllivier Robert  * ntp_refclock.c and the driver utility routines
132c0b746e5SOllivier Robert  */
1332d4e511cSCy Schubert #define MAXSTAGE	64	/* max median filter stages  */
134c0b746e5SOllivier Robert #define NSTAGE		5	/* default median filter stages */
135c0b746e5SOllivier Robert #define BMAX		128	/* max timecode length */
136c0b746e5SOllivier Robert #define GMT		0	/* I hope nobody sees this */
137c0b746e5SOllivier Robert #define MAXDIAL		60	/* max length of modem dial strings */
138c0b746e5SOllivier Robert 
139c0b746e5SOllivier Robert struct refclockproc {
1402b15cb3dSCy Schubert 	void *	unitptr;	/* pointer to unit structure */
1412b15cb3dSCy Schubert 	struct refclock * conf;	/* refclock_conf[type] */
142c0b746e5SOllivier Robert 	struct refclockio io;	/* I/O handler structure */
143c0b746e5SOllivier Robert 	u_char	leap;		/* leap/synchronization code */
144c0b746e5SOllivier Robert 	u_char	currentstatus;	/* clock status */
145c0b746e5SOllivier Robert 	u_char	lastevent;	/* last exception event */
146c0b746e5SOllivier Robert 	u_char	type;		/* clock type */
1472d4e511cSCy Schubert 	u_char	inpoll;		/* waiting for 'refclock_receive()' */
148c0b746e5SOllivier Robert 	const char *clockdesc;	/* clock description */
1492b15cb3dSCy Schubert 	u_long	nextaction;	/* local activity timeout */
1502b15cb3dSCy Schubert 	void	(*action)(struct peer *); /* timeout callback */
151c0b746e5SOllivier Robert 
152c0b746e5SOllivier Robert 	char	a_lastcode[BMAX]; /* last timecode received */
1532b15cb3dSCy Schubert 	int	lencode;	/* length of last timecode */
154c0b746e5SOllivier Robert 
155c0b746e5SOllivier Robert 	int	year;		/* year of eternity */
156c0b746e5SOllivier Robert 	int	day;		/* day of year */
157c0b746e5SOllivier Robert 	int	hour;		/* hour of day */
158c0b746e5SOllivier Robert 	int	minute;		/* minute of hour */
159c0b746e5SOllivier Robert 	int	second;		/* second of minute */
1609c2daa00SOllivier Robert 	long	nsec;		/* nanosecond of second */
161c0b746e5SOllivier Robert 	u_long	yearstart;	/* beginning of year */
1622d4e511cSCy Schubert 	u_int	coderecv;	/* put pointer */
1632d4e511cSCy Schubert 	u_int	codeproc;	/* get pointer */
1649c2daa00SOllivier Robert 	l_fp	lastref;	/* reference timestamp */
1659c2daa00SOllivier Robert 	l_fp	lastrec;	/* receive timestamp */
166c0b746e5SOllivier Robert 	double	offset;		/* mean offset */
167c0b746e5SOllivier Robert 	double	disp;		/* sample dispersion */
168224ba2bdSOllivier Robert 	double	jitter;		/* jitter (mean squares) */
169c0b746e5SOllivier Robert 	double	filter[MAXSTAGE]; /* median filter */
170c0b746e5SOllivier Robert 
171c0b746e5SOllivier Robert 	/*
172c0b746e5SOllivier Robert 	 * Configuration data
173c0b746e5SOllivier Robert 	 */
174c0b746e5SOllivier Robert 	double	fudgetime1;	/* fudge time1 */
175c0b746e5SOllivier Robert 	double	fudgetime2;	/* fudge time2 */
1762d4e511cSCy Schubert 	double	fudgeminjitter;	/* manually set lower bound for jitter */
1779c2daa00SOllivier Robert 	u_char	stratum;	/* server stratum */
178c0b746e5SOllivier Robert 	u_int32	refid;		/* reference identifier */
179c0b746e5SOllivier Robert 	u_char	sloppyclockflag; /* fudge flags */
180c0b746e5SOllivier Robert 
181c0b746e5SOllivier Robert 	/*
182c0b746e5SOllivier Robert 	 * Status tallies
183c0b746e5SOllivier Robert  	 */
184c0b746e5SOllivier Robert 	u_long	timestarted;	/* time we started this */
185c0b746e5SOllivier Robert 	u_long	polls;		/* polls sent */
186c0b746e5SOllivier Robert 	u_long	noreply;	/* no replies to polls */
187c0b746e5SOllivier Robert 	u_long	badformat;	/* bad format reply */
188c0b746e5SOllivier Robert 	u_long	baddata;	/* bad data reply */
189c0b746e5SOllivier Robert };
190c0b746e5SOllivier Robert 
191c0b746e5SOllivier Robert /*
192c0b746e5SOllivier Robert  * Structure interface between the reference clock support
193c0b746e5SOllivier Robert  * ntp_refclock.c and particular clock drivers. This must agree with the
194c0b746e5SOllivier Robert  * structure defined in the driver.
195c0b746e5SOllivier Robert  */
196c0b746e5SOllivier Robert #define	noentry	0		/* flag for null routine */
197c0b746e5SOllivier Robert #define	NOFLAGS	0		/* flag for null flags */
198c0b746e5SOllivier Robert 
199c0b746e5SOllivier Robert struct refclock {
2002b15cb3dSCy Schubert 	int (*clock_start)	(int, struct peer *);
2012b15cb3dSCy Schubert 	void (*clock_shutdown)	(int, struct peer *);
2022b15cb3dSCy Schubert 	void (*clock_poll)	(int, struct peer *);
2032b15cb3dSCy Schubert 	void (*clock_control)	(int, const struct refclockstat *,
2042b15cb3dSCy Schubert 				 struct refclockstat *, struct peer *);
2052b15cb3dSCy Schubert 	void (*clock_init)	(void);
2062b15cb3dSCy Schubert 	void (*clock_buginfo)	(int, struct refclockbug *, struct peer *);
2072b15cb3dSCy Schubert 	void (*clock_timer)	(int, struct peer *);
208c0b746e5SOllivier Robert };
209c0b746e5SOllivier Robert 
210c0b746e5SOllivier Robert /*
211c0b746e5SOllivier Robert  * Function prototypes
212c0b746e5SOllivier Robert  */
2132b15cb3dSCy Schubert extern	int	io_addclock	(struct refclockio *);
2142b15cb3dSCy Schubert extern	void	io_closeclock	(struct refclockio *);
215c0b746e5SOllivier Robert 
216*a466cc55SCy Schubert #define FDWRITE_ERROR	((size_t)-1)
217*a466cc55SCy Schubert 
218c0b746e5SOllivier Robert #ifdef REFCLOCK
2192b15cb3dSCy Schubert extern	void	refclock_buginfo(sockaddr_u *,
2202b15cb3dSCy Schubert 				 struct refclockbug *);
2212b15cb3dSCy Schubert extern	void	refclock_control(sockaddr_u *,
2222b15cb3dSCy Schubert 				 const struct refclockstat *,
2232b15cb3dSCy Schubert 				 struct refclockstat *);
224*a466cc55SCy Schubert extern	int	refclock_open	(const sockaddr_u *srcadr, const char *, u_int, u_int);
2252b15cb3dSCy Schubert extern	int	refclock_setup	(int, u_int, u_int);
2262b15cb3dSCy Schubert extern	void	refclock_timer	(struct peer *);
2272b15cb3dSCy Schubert extern	void	refclock_transmit(struct peer *);
2282b15cb3dSCy Schubert extern 	int	refclock_process(struct refclockproc *);
2292b15cb3dSCy Schubert extern 	int	refclock_process_f(struct refclockproc *, double);
2302b15cb3dSCy Schubert extern 	void	refclock_process_offset(struct refclockproc *, l_fp,
2312b15cb3dSCy Schubert 					l_fp, double);
2322d4e511cSCy Schubert extern	int	refclock_samples_avail(struct refclockproc const *);
2332d4e511cSCy Schubert extern	int	refclock_samples_expire(struct refclockproc *, int);
2342b15cb3dSCy Schubert extern	void	refclock_report	(struct peer *, int);
2352b15cb3dSCy Schubert extern	int	refclock_gtlin	(struct recvbuf *, char *, int, l_fp *);
2362b15cb3dSCy Schubert extern	int	refclock_gtraw	(struct recvbuf *, char *, int, l_fp *);
237*a466cc55SCy Schubert extern	size_t	refclock_write  (const struct peer *, const void *, size_t,
238*a466cc55SCy Schubert 				 const char * what);
239*a466cc55SCy Schubert extern	size_t	refclock_fdwrite(const struct peer *, int, const void *, size_t,
240*a466cc55SCy Schubert 				 const char * what);
2412b15cb3dSCy Schubert extern	int	indicate_refclock_packet(struct refclockio *,
2422b15cb3dSCy Schubert 					 struct recvbuf *);
2432b15cb3dSCy Schubert extern	void	process_refclock_packet(struct recvbuf *);
2442d4e511cSCy Schubert 
2452d4e511cSCy Schubert /* save string as la_code, size==(size_t)-1 ==> ASCIIZ string */
2462d4e511cSCy Schubert extern	void	refclock_save_lcode(
2472d4e511cSCy Schubert 			struct refclockproc *, char const *, size_t);
2482d4e511cSCy Schubert /* format data into la_code */
2492d4e511cSCy Schubert extern	void	refclock_format_lcode(
2502d4e511cSCy Schubert 			struct refclockproc *, char const *, ...);
2512d4e511cSCy Schubert extern	void	refclock_vformat_lcode(
2522d4e511cSCy Schubert 			struct refclockproc *, char const *, va_list);
2532d4e511cSCy Schubert 
2542d4e511cSCy Schubert struct refclock_atom;
2552d4e511cSCy Schubert extern int	refclock_ppsaugment(
2562d4e511cSCy Schubert     const struct refclock_atom*, l_fp *rcvtime ,
2572d4e511cSCy Schubert     double rcvfudge, double ppsfudge);
2582d4e511cSCy Schubert 
259*a466cc55SCy Schubert extern int ppsdev_reopen(const sockaddr_u *srcadr,
260*a466cc55SCy Schubert 			 int ttyfd, int ppsfd, const char *ppspath,
261*a466cc55SCy Schubert 			 int mode, int flags);
262*a466cc55SCy Schubert extern void ppsdev_close(int ttyfd, int ppsfd);
263*a466cc55SCy Schubert 
264c0b746e5SOllivier Robert #endif /* REFCLOCK */
265c0b746e5SOllivier Robert 
266c0b746e5SOllivier Robert #endif /* NTP_REFCLOCK_H */
267