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