### Line Disciplines and Streams Modules

#### Description

Most radio and modem clocks used for a primary (stratum-1) NTP server utilize serial ports operating at speeds of 9600 baud or greater. The intrinsic delay and jitter contributed by the serial port hardware and software driver can accumulate up to a millisecond in newer Unix systems and tens of milliseconds in older ones. In order to reduce the effects of delay and jitter, a set of special line disciplines, stream modules and operating system calls (ioctls) can be configured in some Unix kernels. These routines intercept special characters or signals provided by the radio or modem clock and save a timestamp for later processing.

The routines provide two important functions. Some insert a timestamp in the receive data stream upon occurance of a designated character or characters at the serial interface. This can be used to timestamp an on-time character produced by a radio clock, for example. Other routines support an application program interface for pulse-per-second (PPS) signals generated by some radio clocks and laboratory instruments. These routines are normally accessed through the PPSAPI application program interface described below.

The routines can be compiled in the kernel in older BSD-derived systems, or installed as System V streams modules and either compiled in the kernel or dynamically loaded when required. In either case, they require minor changes in some kernel files and in the NTP daemon `ntpd`. The streams modules can be pushed and popped from the streams stack using conventional System V streams program primitives. Note that some Unix kernels do not support line disciplines and some do not support System V streams. The routines described here are known to work correctly with the Unix kernels called out in the descriptions, but have not been tested for other kernels.

#### PPSAPI Application Program Interface

Pulse-per-second (PPS) signals are normally processed as described in the Pulse-per-second (PPS) Signal Interfacing page. The PPS Clock Discipline driver uses the PPSAPI application program interface to capture PPS signal transitions used to fine-tune the system clock. This interface, defined in RFC-2783, is the only PPS interface supported in NTP. While older PPS interfaces based on the ioctls described below continue to be supported, they are used only in the special header file /usr/include/sys/timepps.h, which implements the PPSAPI specific to each archeticture and operating system.

It is the intent of the evolving design to remove all PPS support from the various clock drivers and utilize only the PPS driver for PPS support. This allows the required sanity checks and signal grooming to be provided and maintained in one place and avoids cluttering up the drivers with duplicate functionality. Since the PPS signal samples are processed by the entire suite of NTP grooming, selection and clustering algorithms, noisy PPS signals and signals outside specific time and frequency tolerances are excluded.

The PPSAPI interface provides the following functions:

`time_pps_create`
  Creates a PPS interface instance and returns a handle to it.
`time_pps_destroy`
  Destroys a PPS interface and returns the resources used.
`time_pps_setparams`
  Sets the parameters associated with a PPS interface instance, including offsets to be automatically added to captured timestamps.
`time_pps_getparams`
  Returns the parameters associated with a PPS interface instance.
`time_pps_getcap`
  Returns the capabilities of the current interface and kernel implementation.
`time_pps_fetch`
  Returns the current timestamps associated with a PPS interface instance in either nanoseconds and nanoseconds (Unix `timespec`) or seconds and fraction (NTP) format.
`time_pps_kcbind`
  If kernel PPS processing is supported, this binds the support to the associated PPS interface instance.

The entire PPS interface functionality is currently provided by inline code in the `timepps.h` header files implemented for SunOS, Solaris, FreeBSD, Linux and Tru64. While not all implementations support the full PPSAPI specification, they do support all the functions required for the PPS driver. The FreeBSD, Linux and Solaris implementations can be used with the stock kernels provided with those systems; however, the Tru64 and SunOS kernels require additional functions not provided in the stock kernels. Solaris users are cautioned that these ioctls function improperly in Solaris versions prior to 2.8 with patch Generic_108528-02.

#### `tty_clk` Line Discipline/Streams Module

This routine intercepts characters received from the serial port and passes unchanged all except a set of designated characters to the generic serial port discipline. For each of the exception characters, the character is inserted in the receiver buffer followed by a local timestamp in Unix `timeval` format. Both `select()` and `SIGIO` are supported by the routine. Support for this routine is automatically detected during the NTP build process and interface code compiled as necessary.

There are two versions of the `tty_clk` routine. The `tty_clk.c` line discipline is designed for older BSD systems and is compiled in the kernel. The `tty_clk_STREAMS.c` is designed for System V streams, in which case it can be either compiled in the kernel or dynamically loaded. Since these programs are small, unobtrusive, and do nothing unless specifically enabled by an application program, it probably doesn't matter which version is chosen. Instructions on how to configure and build a kernel supporting either of these routines is in the `README` file in the `./kernel` directory.

The `tty_clk` routine defines a new ioctl `CLK_SETSTR`, which takes a pointer to a string of no more than 32 characters. Until the first `CLK_SETSTR` is performed, the routine will simply pass through characters. Once it is passed a string by `CLK_SETSTR`, any character in that string will be immediately followed by a timestamp in Unix `timeval` format. You can change the string whenever you want by doing another `CLK_SETSTR`. The character must be an exact, 8 bit match. The character '\000' cannot, be used, as it is the string terminator. Passing an empty string to `CLK_SETSTR` turns off timestamping. Passing `NULL` may produce surprising results.

#### `TIOCDCDTIMESTAMP` ioctl in FreeBSD

This ioctl is included in FreeBSD 2.2 and later. It causes a timestamp to be inserted in the serial port receive data stream when the data carrier detect (DCD) signal is asserted. This is useful for those radio clocks that indicate the on-time epoch by means of a modem control signal. It is not recommended that this be used for PPS timestamps, as this function is available using the PPS application program interface included in FreeBSD 3.4 and later.

The `TIOCDCDTIMESTAMP` ioctl() is detected and compiled automatically on FreeBSD systems if available. With FreeBSD 2.2 the measured delay between activation of the DCD signal and the time the timestamp is captured on a 66MHz 486DX2 is 19 ms and on a 100MHz Pentium is 6 ms.

#### `ppsclock`Streams Module

This routine is a streams module which causes a timestamp to be captured when the DCD signal is asserted. It is normally used in connection with a PPS signal generated by some radio clocks. However, it is normally used only by the PPSAPI interface and should be avoided in other contexts. Instructions on how to configure and build a kernel supporting either of these routines is in the `README` file in the `./kernel` directory.

The ppsclock streams module implements the `CIOGETEV` ioctl, which takes a pointer to the structure

    struct ppsclockev {
         struct timeval tv;
         u_int serial;
    };

The `ppsclock` module is pushed on the streams stack of the serial port connected to the DCD line. At each positive-going edge of the PPS signal, the routine latches the current local timestamp and increments a counter. At each `CIOGETEV` ioctl call, the current values of the timestamp and counter are returned in the `ppsclockev` structure.

#### `TIOCSPPS` and `TIOCGETPPSEV` ioctls in Solaris

These ioctls are included in Solaris 2.4 and later. They implement the same function as the `ppsclock` streams module, but are implemented as integrated system calls independent of the streams facility. They are normally used in connection with a pulse-per-second (PPS) signal generated by some radio clocks. However, these ioctls are normally used only by the PPSAPI interface and should be avoided in other contexts. See the Sun documentation for the calling sequence and return values.

Users are cautioned that these ioctls function improperly in Solaris versions prior to 2.8 with patch Generic_108528-02.

#### `tty_chu` Line Discipline/Streams Module (depredated)

This routine is a special purpose line discipline for receiving a special timecode broadcast by Canadian time and frequency standard station CHU. It has been removed from the distribution since its function has been replaced by the Radio CHU Audio Demodulator/Decoder (type 7) clock driver.