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