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