option-tester: Add many changes
[ntpsec.git] / docs / generic_howto.adoc
blob1456b76e387bebcb65527468d1c1424d26b180cd
1 = How to build new GENERIC clocks
2 include::include-html.ad[]
4 Here is an attempt to sketch out what you need to do to add
5 another clock to the generic driver: Currently the implementation is being
6 cleaned up - so not all information in here is completely correct. Refer
7 to the included code where in doubt.
9 == Prerequisites
11 * Does the system you want the clock connect to have the include file
12 termios.h? (You need that for the generic driver)
14 What to do:
16 Make a conversion module (libparse/clk_*.c)
18 == What is the time code format?
20 Find year, month, day, hour, minute, second, status (synchronised or
21 not), possibly time zone information (you need to give the offset to
22 UTC) You will have to convert the data from a string into a struct
23 clocktime:
25 -------------------------------------------------------------------------------
26 struct clocktime                /* clock time broken up from time code */
28         long day;
29         long month;
30         long year;
31         long hour;
32         long minute;
33         long second;
34         long usecond;
35         long utcoffset;       /* in seconds */
36         time_t utcoffset;     /* true utc time instead of date/time */
37         long flags;           /* current clock status */
39 -------------------------------------------------------------------------------
41 Conversion is usually simple and straightforward. For the flags
42 following values can be OR'ed together:
44 |-------------------------------------------------------------------------------
45 | PARSEB_ANNOUNCE  | Switch time zone warning (informational only)
46 | PARSEB_POWERUP   | No synchronisation - clock confused (must set then)
47 | PARSEB_NOSYNC    | Timecode currently not confirmed (must set then),
48                      usually on reception error when there is still a
49                      chance the generated time is still ok.
50 | PARSEB_DST       | DST in effect (informational only)
51 | PARSEB_UTC       | Timecode contains UTC time (informational only)
52 | PARSEB_LEAPADD   | LEAP addition warning (prior to leap happening -
53                      must set when imminent)
54                      Also used for time code that do not encode the
55                      direction (as this is currently the default).
56 | PARSEB_LEAPDEL   | LEAP deletion warning (prior to leap happening -
57                      must set when imminent)
58 | PARSEB_ALTERNATE | Backup transmitter (informational only)
59 | PARSEB_POSITION  | Geographic position available (informational only)
60 | PARSEB_LEAPSECOND| Actual leap second (this time code is the leap
61                      second - informational only)
62 |-------------------------------------------------------------------------------
64 These are feature flags denoting items that are supported by the clock:
66 |----------------------------------------------------------------------------
67 | PARSEB_S_LEAP      | supports LEAP - might set PARSEB_LEAP
68 | PARSEB_S_ANTENNA   | supports ANTENNA - might set PARSEB_ALTERNATE
69 | PARSEB_S_PPS       | supports PPS time stamping
70 | PARSEB_S_POSITION  | supports position information (GPS)
71 |----------------------------------------------------------------------------
73 If the utctime field is non-zero this value will be take as time code
74 value. This allows for conversion routines that already have the utc
75 time value. The utctime field gives the seconds since Jan 1st 1970,
76 0:00:00. The useconds field gives the respective usec value. The fields
77 for date and time (down to second resolution) will be ignored.
79 Conversion is done in the cvt_* routine in parse/clk_*.c files. Look in
80 them for examples. The basic structure is:
82 -----------------------------------------------------
83      struct clockformat <yourclock>_format = {
84        lots of fields for you to fill out (see below)
85      };
87      static cvt_<yourclock>()
88        ...
89      {
90        if (<I do not recognize my time code>) {
91          return CVT_NONE;
92        } else {
93          if (<conversion into clockformat is ok>) {
94            <set all necessary flags>;
95            return CVT_OK;
96          } else {
97            return CVT_FAIL|CVT_BADFMT;
98          }
99        }
100 -----------------------------------------------------
102 The struct clockformat is the interface to the rest of the generic
103 driver - it holds all information necessary for finding the clock
104 message and doing the appropriate time stamping.
106 --------------------------------------------------------------------------------
107 struct clockformat
109   unsigned long (*input)();
110   /* input routine - your routine - cvt_<yourclock> */
111   unsigned long (*convert)();
112   /* conversion routine - your routine - cvt_<yourclock> */
113   /* routine for handling RS232 sync events (time stamps) - usually sync_simple */
114   unsigned long (*syncpps)();
115   /* PPS input routine - usually pps_one */
116   void           *data;
117   /* local parameters - any parameters/data/configuration info your conversion
118      routine might need */
119   char           *name;
120   /* clock format name - Name of the time code */
121   unsigned short  length;
122   /* maximum length of data packet for your clock format */
123   unsigned long   flags;
124  /* information for the parser what to look for */
126 --------------------------------------------------------------------------------
128 The above should have given you some hints on how to build a clk_*.c
129 file with the time code conversion. See the examples and pick a clock
130 closest to yours and tweak the code to match your clock.
132 In order to make your clk_*.c file usable, a reference to the clockformat
133 structure must be put into parse_conf.c.
135 == Driver initialization
137 TTY setup and initialization/configuration will be done in
138 ntpd/refclock_generic.c.
140 * Find out the exact tty settings for your clock (baud rate, parity,
141 stop bits, character size, ...) and note them in terms of termio*.h
142 c_cflag macros.
144 * in ntpd/refclock_generic.c fill out a new the struct clockinfo element
145 (that allocates a new "IP" address - see comments) (see all the other
146 clocks for example)
148 --------------------------------------------------------------------------------
149 struct clockinfo {
150         unsigned long  cl_flags;  /* operation flags (io modes) */
151          PARSE_F_PPSPPS       use loopfilter PPS code
152          PARSE_F_PPSONSECOND  PPS pulses are on second
153          usually flags stay 0 as they are used only for special setups
155         void  (*cl_poll)();       /* active poll routine */
156          The routine to call when the clock needs data sent to it in order to
157          get a time code from the clock (e.g., Trimble clock)
159         int   (*cl_init)();      /* active poll init routine */
160          The routine to call for very special initializations.
162         void  (*cl_event)();     /* special event handling (e.g., reset clock) */
163          What to do, when an event happens - used to re-initialize clocks on timeout.
165         void  (*cl_end)();       /* active poll end routine */
166          The routine to call to undo any special initialization (free memory/timers)
168         void   *cl_data;        /* local data area for "poll" mechanism */
169          local data for polling routines
171         u_fp    cl_rootdelay;         /* rootdelay */
172          NTP rootdelay estimate (usually 0)
174         unsigned long  cl_basedelay;  /* current offset - unsigned l_fp
175                                       fractional part (fraction) by
176                                       which the RS232 time code is
177                                       delayed from the actual time. */
179         unsigned long  cl_ppsdelay;   /* current PPS offset - unsigned
180                                       l_fp fractional time (fraction)
181                                       by which the PPS time stamp is
182                                       delayed (usually 0) */
184         char   *cl_id;                /* ID code */
185          Refclock id - (max 4 chars)
187         char   *cl_description;       /* device name */
188          Name of this device.
190         char   *cl_format;            /* fixed format */
191          If the data format can not be detected automatically this is the name
192          as in clk_*.c clockformat.
194         unsigned char  cl_type;       /* clock type (ntp control) */
195          Type if clock as in clock status word (ntp control messages) - usually 0
197         unsigned long  cl_maxunsync;  /* time to trust oscillator after
198                                          losing synch --  seconds a clock
199                                          can be trusted after losing
200                                          synchronisation. */
201         unsigned long  cl_speed;      /* terminal input & output baudrate */
202         unsigned long  cl_cflag;      /* terminal io flags */
203         unsigned long  cl_iflag;      /* terminal io flags */
204         unsigned long  cl_oflag;      /* terminal io flags */
205         unsigned long  cl_lflag;      /* terminal io flags */
207         unsigned long  cl_samples;    /* samples for median filter */
208         unsigned long  cl_keep;       /* samples for median filter to keep */
209          median filter parameters - smoothing and rejection of bad samples
210   } clockinfo[] = {
211   ...,<other clocks>,...
212   { < your parameters> },
213   };
214 --------------------------------------------------------------------------------
216 Well, this is very sketchy, I know. But I hope it helps a little bit.
217 The best way is to look which clock comes closest to yours and tweak that
218 code.
220 Two sorts of clocks are used with parse. Clocks that automatically send
221 their time code (once a second) do not need entries in the poll routines
222 because they send the data all the time. The second sort are the clocks
223 that need a command sent to them in order to reply with a time code
224 (like the Trimble clock).
226 For questions: mailto:kardel@acm.org[kardel@acm.org].
228 Please include an exact description on how your clock works.
229 (initialization, TTY modes, strings to be sent to it, responses received
230 from the clock).
232 '''''
234 include::includes/footer.adoc[]