idnits 2.17.1 draft-mogul-pps-api-03.txt: Checking boilerplate required by RFC 5378 and the IETF Trust (see https://trustee.ietf.org/license-info): ---------------------------------------------------------------------------- ** Looks like you're using RFC 2026 boilerplate. This must be updated to follow RFC 3978/3979, as updated by RFC 4748. Checking nits according to https://www.ietf.org/id-info/1id-guidelines.txt: ---------------------------------------------------------------------------- ** Missing expiration date. The document expiration date should appear on the first and last page. ** The document is more than 15 pages and seems to lack a Table of Contents. == No 'Intended status' indicated for this document; assuming Proposed Standard == It seems as if not all pages are separated by form feeds - found 0 form feeds but 28 pages Checking nits according to https://www.ietf.org/id-info/checklist : ---------------------------------------------------------------------------- ** The document seems to lack an IANA Considerations section. (See Section 2.2 of https://www.ietf.org/id-info/checklist for how to handle the case when there are no actions for IANA.) ** The document seems to lack separate sections for Informative/Normative References. All references will be assumed normative when checking for downward references. == There are 6 instances of lines with non-RFC2606-compliant FQDNs in the document. ** The document seems to lack a both a reference to RFC 2119 and the recommended RFC 2119 boilerplate, even if it appears to use RFC 2119 keywords -- however, there's a paragraph with a matching beginning. Boilerplate error? RFC 2119 keyword, line 257: '... However, these assignments SHOULD be...' RFC 2119 keyword, line 259: '... SHOULD document these assignments....' RFC 2119 keyword, line 279: '...e implementation SHOULD impose access ...' RFC 2119 keyword, line 292: '...ecification, but SHOULD be documented ...' RFC 2119 keyword, line 293: '... output pin MAY also undergo transit...' (28 more instances...) Miscellaneous warnings: ---------------------------------------------------------------------------- == Line 333 has weird spacing: '... long tv_...' == Line 341 has weird spacing: '...ned int int...' == Line 342 has weird spacing: '...ned int fra...' == Line 354 has weird spacing: '...ed long long...' == Line 381 has weird spacing: '...p_ntpfp asser...' == (3 more instances...) -- The document seems to lack a disclaimer for pre-RFC5378 work, but may have content which was first submitted before 10 November 2008. If you have contacted all the original authors and they are all willing to grant the BCP78 rights to the IETF Trust, then this is fine, and you can ignore this comment. If not, you may need to add the pre-RFC5378 disclaimer. (See the Legal Provisions document at https://trustee.ietf.org/license-info for more information.) -- The document date (7 June 1999) is 9084 days in the past. Is this intentional? -- Found something which looks like a code comment -- if you have code sections in the document, please surround them with '' and '' lines. Checking references for intended status: Proposed Standard ---------------------------------------------------------------------------- (See RFCs 3967 and 4897 for information about using normative references to lower-maturity documents in RFCs) -- Missing reference section? '4' on line 907 looks like a reference -- Missing reference section? '3' on line 577 looks like a reference -- Missing reference section? '5' on line 103 looks like a reference -- Missing reference section? 'EBADF' on line 987 looks like a reference -- Missing reference section? 'EOPNOTSUPP' on line 1000 looks like a reference -- Missing reference section? 'EPERM' on line 933 looks like a reference -- Missing reference section? 'EFAULT' on line 990 looks like a reference -- Missing reference section? 'EINVAL' on line 998 looks like a reference -- Missing reference section? 'EINTR' on line 992 looks like a reference -- Missing reference section? 'ETIMEDOUT' on line 1004 looks like a reference -- Missing reference section? '1' on line 1010 looks like a reference -- Missing reference section? '2' on line 1189 looks like a reference Summary: 6 errors (**), 0 flaws (~~), 9 warnings (==), 15 comments (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 1 Network Working Group Jeffrey Mogul, DECWRL 2 Internet-Draft David Mills, UDel 3 Expires: 31 December 1999 Jan Brittenson, Sun 4 Jonathan Stone, Stanford 5 Poul-Henning Kamp, FreeBSD 6 Ulrich Windl, Universitaet Regensburg 7 7 June 1999 9 Pulse-Per-Second API for UNIX-like Operating Systems, Version 1.0 11 draft-mogul-pps-api-03.txt 13 STATUS OF THIS MEMO 15 This document is an Internet-Draft and is in full 16 conformance with all provisions of Section 10 of RFC2026. 18 Internet-Drafts are working documents of the Internet 19 Engineering Task Force (IETF), its areas, and its working 20 groups. Note that other groups may also distribute working 21 documents as Internet-Drafts. 23 Internet-Drafts are draft documents valid for a maximum of 24 six months and may be updated, replaced, or obsoleted by 25 other documents at any time. It is inappropriate to use 26 Internet-Drafts as reference material or to cite them other 27 than as "work in progress." 29 The list of current Internet-Drafts can be accessed at 30 http://www.ietf.org/ietf/1id-abstracts.txt 32 The list of Internet-Draft Shadow Directories can be 33 accessed at http://www.ietf.org/shadow.html. 35 Distribution of this document is unlimited. Please send 36 comments to the authors. 38 ABSTRACT 40 RFC1589 describes a UNIX kernel implementation model for 41 high-precision time-keeping. This model is meant for use 42 in conjunction with the Network Time Protocol (NTP, 43 RFC1305), or similar time synchronization protocols. One 44 aspect of this model is an accurate interface to the 45 high-accuracy, one pulse-per-second (PPS) output typically 46 available from precise time sources (such as a GPS or GOES 47 receiver). RFC1589 did not define an API for managing the 48 PPS facility, leaving implementors without a portable means 49 for using PPS sources. This document specifies such an 50 API. 52 Internet-Draft Pulse-Per-Second API 7 June 1999 17:40 54 TABLE OF CONTENTS 56 1 Introduction 2 57 2 Data types for representing timestamps 4 58 2.1 Resolution 4 59 2.2 Time scale 4 60 3 API 5 61 3.1 PPS abstraction 5 62 3.2 New data structures 6 63 3.3 Mode bit definitions 9 64 3.4 New functions 12 65 3.4.1 New functions: obtaining PPS sources 12 66 3.4.2 New functions: setting PPS parameters 13 67 3.4.3 New functions: access to PPS timestamps 15 68 3.4.4 New functions: disciplining the kernel timebase 16 69 3.4.5 New functions: waiting for an event 18 70 3.5 Compliance rules 20 71 3.5.1 Functions 20 72 3.5.2 Mode bits 20 73 3.6 Examples 21 74 4 Security Considerations 23 75 5 Acknowledgements 23 76 6 References 23 77 7 Authors' addresses 24 79 A. Extensions and related APIs 25 80 A.1 Extension: Parameters for the ``echo'' mechanism 25 81 A.2 Extension: Obtaining information about external clocks 25 82 A.3 Extension: Finding a PPS source 26 84 B. Example implementation: PPSDISC Line discipline 27 85 B.1 Example 27 87 C. Available implementations 28 89 1 Introduction 91 RFC1589 [4] describes a model and programming interface for generic 92 operating system software that manages the system clock and timer 93 functions. The model provides improved accuracy and stability for 94 most workstations and servers using the Network Time Protocol 95 (NTP) [3] or similar time synchronization protocol. The model 96 supports the use of external timing sources, such as the precision 97 pulse-per-second (PPS) signals typically available from precise time 98 sources (such as a GPS or GOES receiver). 100 However, RFC1589 did not define an application programming interface 101 (API) for the PPS facility. This document specifies such an 102 interface, for use with UNIX (or UNIX-like) operating systems. Such 103 systems often conform to the ``Single UNIX Specification'' [5], 104 sometimes known as POSIX. 106 Internet-Draft Pulse-Per-Second API 7 June 1999 17:40 108 One convenient means to provide a PPS signal to a computer system is 109 to connect that signal to a modem-control pin on a serial-line 110 interface to the computer. The Data Carrier Detect (DCD) pin is 111 frequently used for this purpose. Typically, the time-code output of 112 the time source is transmitted to the computer over the same serial 113 line. The computer detects a signal transition on the DCD pin, 114 usually by receiving an interrupt, and records a timestamp as 115 immediately as possible. 117 Although existing practice has focussed on the use of serial lines 118 and DCD transitions, PPS signals might also be delivered by other 119 kinds of devices. The API specified in this document does not 120 require the use of a serial line, although it may be somewhat biased 121 in that direction. 123 The typical use of this facility is for the operating system to 124 record a high-resolution timestamp as soon as possible after it 125 detects a PPS signal transition (usually indicated by an interrupt). 126 This timestamp can then be made available, with less stringent delay 127 constraints, to timekeeping software. The software can compare the 128 captured timestamp to the received time-code to accurately determine 129 the absolute offset between the system clock and the precise time 130 source. 132 The operating system may also deliver the PPS event immediately to a 133 procedure used to discipline its internal timebase, called the 134 ``in-kernel PPS consumer.'' One example would be the ``hardpps()'' 135 procedure described in RFC1589. 137 The API specified in this document allows for one or more signal 138 sources attached to a computer system to provide PPS inputs, at the 139 option of user-level software. User-level software may obtain 140 signal-transition timestamps for any of these PPS sources. 141 User-level software may optionally specify at most one of these PPS 142 sources to be used to discipline the system's internal timebase. 144 Although the primary purpose of this API is for capturing true 145 pulse-per-second events, the API may also be used for accurately 146 timestamping events of other periods, or even aperiodic events, when 147 these can be expressed as signal transitions. 149 This document does not define internal details of how the API must be 150 implemented, and does not specify constraints on the accuracy, 151 resolution, or latency of the PPS feature. However, the utility of 152 this feature is inversely proportional to the delay (and variance of 153 delay), and implementors are encouraged to take this seriously. 155 In principle, the rate of events to be captured, or the frequency of 156 the signals, can range from once per day (or less often) to several 157 thousand per second. However, since in most implementations the 158 timestamping function will be implemented as a processor interrupt at 160 Internet-Draft Pulse-Per-Second API 7 June 1999 17:40 162 a relatively high priority, it is prudent to limit the rate of such 163 events. This may be done either by mechanisms in the hardware that 164 generates the signals, or by the operating system. 166 2 Data types for representing timestamps 168 Computer systems use various representations of time. Because this 169 API is concerned with the provision of high-accuracy, high-resolution 170 time information, the choice of representation is significant. (Here 171 we consider only binary representations, not human-format 172 representations.) 174 The two interesting questions are: 176 1. what is the resolution of the representation? 178 2. what time scale is represented? 180 These questions often lead to contentious arguments. Since this API 181 is intended for use with NTP and POSIX-compliant systems, however, we 182 can limit the choices to representations compatible with existing NTP 183 and POSIX practice, even if that practice is considered ``wrong'' in 184 some quarters. 186 2.1 Resolution 187 In the NTP protocol, ``timestamps are represented as a 64-bit 188 unsigned fixed-point number, in seconds relative to 0h on 1 January 189 1900. The integer part is in the first 32 bits and the fraction part 190 in the last 32 bits [...] The precision of this representation is 191 about 200 picoseconds'' [3]. 193 However, most computer systems cannot measure time to this resolution 194 (this represents a clock rate of 5 GHz). The POSIX gettimeofday() 195 function returns a ``struct timeval'' value, with a resolution of 1 196 microsecond. The POSIX clock_gettime() function returns a ``struct 197 timespec'' value, with a resolution of 1 nanosecond. 199 This API uses an extensible representation, but defaults to the 200 ``struct timespec'' representation, since in a general-purpose 201 computer system it is just barely feasible to measure time to a 202 resolution of a few microseconds. 204 2.2 Time scale 205 Several different time scales have been proposed for use in computer 206 systems. UTC and TAI are the two obvious candidates. 208 Some people would prefer the use of TAI, which is identical to UTC 209 except that it does not correct for leap seconds. Their preference 210 for TAI stems from the difficulty of computing precise time 211 differences when leap seconds are involved, especially when using 213 Internet-Draft Pulse-Per-Second API 7 June 1999 17:40 215 times in the future (for which the exact number of leap seconds is, 216 in general, unknowable). 218 However, POSIX and NTP both use UTC, albeit with different base 219 dates. Given that support for TAI would, in general, require other 220 changes to the POSIX specification, this API uses the POSIX base date 221 of 00:00 January 1, 1970 UTC, and conforms to the POSIX use of the 222 UTC time scale. 224 3 API 226 A PPS facility can be used in two different ways: 228 1. An application can obtain a timestamp, using the system's 229 internal timebase, for the most recent PPS event. 231 2. A kernel may directly utilize PPS events to discipline its 232 internal timebase, thereby providing highly accurate time 233 to all applications. 235 This API supports both uses, individually or in combination. The 236 timestamping feature may be used on any number of PPS sources 237 simultaneously; the timebase-disciplining feature may be used with at 238 most one PPS source. 240 Although the proper implementation of this API requires support from 241 the kernel of a UNIX system, this document defines the API in terms 242 of a set of library routines. This gives the implementor some 243 freedom to divide the effort between kernel code and library code 244 (different divisions might be appropriate on microkernels and 245 monolithic kernels, for example). 247 3.1 PPS abstraction 248 A PPS signal consists of a series of pulses, each with an 249 ``asserted'' (logical true) phase, and a ``clear'' (logical false) 250 phase. The two phases may be of different lengths. The API may 251 capture an ``assert timestamp'' at the moment of the transition into 252 the asserted phase, and a ``clear timestamp'' at the moment of the 253 transition into the clear phase. 255 The specific assignment of the logical values ``true'' and ``false'' 256 with specific voltages of a PPS signal, if applicable, is outside the 257 scope of this specification. However, these assignments SHOULD be 258 consistent with applicable standards. Implementors of PPS sources 259 SHOULD document these assignments. 261 --------- 262 Reminder to implementors of DCD-based PPS support: TTL and 263 RS-232C (V.24/V.28) interfaces both define the "true" state as 264 the one having the highest positive voltage. TTL defines a 266 Internet-Draft Pulse-Per-Second API 7 June 1999 17:40 268 nominal absence of voltage as the "false" state, but RS-232C 269 (V.24/V.28) defines the "false" state by the presence of a 270 negative voltage. 271 --------- 273 The API supports the direct provision of PPS events (and timestamps) 274 to an in-kernel PPS consumer. This could be the function called 275 ``hardpps()'', as described in RFC1589 [4], but the API does not 276 require the kernel implementation to use that function name 277 internally. The current version of the API supports at most one 278 in-kernel PPS consumer, and does not provide a way to explicitly name 279 it. The implementation SHOULD impose access controls on the use of 280 this feature. 282 The API optionally supports an ``echo'' feature, in which events on 283 the incoming PPS signal may be reflected through software, after the 284 capture of the corresponding timestamp, to an output signal pin. 285 This feature may be used to determine an upper bound on the actual 286 delay between the edges of the PPS signal and the capture of the 287 timestamps; such information may be useful in precise calibration of 288 the system. 290 The designation of an output pin for the echo signal, and sense and 291 shape of the output transition, is outside the scope of this 292 specification, but SHOULD be documented for each implementation. The 293 output pin MAY also undergo transitions at other times besides those 294 caused by PPS input events. 296 --------- 297 Note: this allows an implementation of the echo feature to 298 generate an output pulse per input pulse, or an output edge per 299 input pulse, or an output pulse per input edge. It also allows 300 the same signal pin to be used for several purposes 301 simultaneously. 302 --------- 304 Also, the API optionally provides an application with the ability to 305 specify an offset value to be applied to captured timestamps. This 306 can be used to correct for cable and/or radio-wave propagation 307 delays, or to compensate for systematic jitter in the external 308 signal. The implementation SHOULD impose access controls on the use 309 of this feature. 311 3.2 New data structures 312 The data structure declarations and symbol definitions for this API 313 will appear in the header file . 315 The API includes several implementation-specific types: 317 typedef ... pps_handle_t; /* represents a PPS source */ 319 Internet-Draft Pulse-Per-Second API 7 June 1999 17:40 321 typedef unsigned ... pps_seq_t; /* sequence number */ 323 The ``pps_handle_t'' type is an opaque scalar type used to represent 324 a PPS source within the API. 326 The ``pps_seq_t'' type is an unsigned integer data type of at least 327 32 bits. The precise declaration of this type is system-dependent. 329 The API imports the standard POSIX definition for this data type: 331 struct timespec { 332 time_t tv_sec; /* seconds */ 333 long tv_nsec; /* nanoseconds */ 334 }; 336 The API defines this structure as an internal (not ``on the wire'') 337 representation of the NTP ``64-bit unsigned fixed-point'' timestamp 338 format [3]: 340 typedef struct ntp_fp { 341 unsigned int integral; 342 unsigned int fractional; 343 } ntp_fp_t; 345 The two fields in this structure may be declared as any unsigned 346 integral type, each of at least 32 bits. 348 The API defines this new union as an extensible type for representing 349 times: 351 typedef union pps_timeu { 352 struct timespec tspec; 353 ntp_fp_t ntpfp; 354 unsigned long longpad[3]; 355 } pps_timeu_t; 357 Future revisions of this specification may add more fields to this 358 union. 360 --------- 361 Note: adding a field to this union that is larger than 362 3*sizeof(long) will break binary compatibility. 363 --------- 365 The API defines these new data structures: 367 typedef struct { 368 pps_seq_t assert_sequence; /* assert event seq # */ 369 pps_seq_t clear_sequence; /* clear event seq # */ 370 pps_timeu_t assert_tu; 372 Internet-Draft Pulse-Per-Second API 7 June 1999 17:40 374 pps_timeu_t clear_tu; 375 int current_mode; /* current mode bits */ 376 } pps_info_t; 378 #define assert_timestamp assert_tu.tspec 379 #define clear_timestamp clear_tu.tspec 381 #define assert_timestamp_ntpfp assert_tu.ntpfp 382 #define clear_timestamp_ntpfp clear_tu.ntpfp 384 typedef struct { 385 int api_version; /* API version # */ 386 int mode; /* mode bits */ 387 pps_timeu_t assert_off_tu; 388 pps_timeu_t clear_off_tu; 389 } pps_params_t; 391 #define assert_offset assert_off_tu.tspec 392 #define clear_offset clear_off_tu.tspec 394 #define assert_offset_ntpfp assert_off_tu.ntpfp 395 #define clear_offset_ntpfp clear_off_tu.ntpfp 397 The ``pps_info_t'' type is returned on an inquiry to PPS source. It 398 contains the timestamps for the most recent assert event, and the 399 most recent clear event. The order in which these events were 400 actually received is defined by the timetamps, not by any other 401 aspect of the specification. Each timestamp field represents the 402 value of the operating system's internal timebase when the 403 timestamped event occurred, or as close as possible to that time 404 (perhaps with the addition of a specified offset). The current_mode 405 field contains the value of the mode bits (see section 3.3) at the 406 time of the most recent transition was captured for this PPS source. 407 An application can use current_mode to determine the format of the 408 timestamps returned. 410 The assert_sequence number increases once per captured assert 411 timestamp. Its initial value is undefined. If incremented past the 412 largest unsigned long value, the next value is zero. The 413 clear_sequence number increases once per captured clear timestamp. 414 Its initial value is undefined, and may be different from the initial 415 value of assert_sequence. If incremented past the largest unsigned 416 long value, the next value is zero. Due to possible signal loss or 417 excessive signal noise, the assert-sequence number and the 418 clear-sequence number might not always increase in step with each 419 other. 421 --------- 422 Note that these sequence numbers are most useful in 423 applications where events other than PPS transitions are to be 424 captured, which might be involved in a precision stopwatch 426 Internet-Draft Pulse-Per-Second API 7 June 1999 17:40 428 application, for example. In such cases, the sequence numbers 429 may be used to detect overruns, where the application has 430 missed one or more events. They may also be used to detect an 431 excessive event rate, or to detect that an event has failed to 432 occur between two calls to the time_pps_fetch() function 433 (defined later). 435 In order to obtain an uninterrupted series of sequence numbers 436 (and hence of event timestamps), it may be necessary to sample 437 the pps_info_t values at a rate somewhat faster than the 438 underlying event rate. For example, an application interested 439 in both assert and clear timestamps may need to sample at least 440 twice per second. Proper use of the sequence numbers allows an 441 application to discover if it has missed any event timestamps 442 due to an insufficient sampling rate. 443 --------- 445 The pps_params_t data type is used to discover and modify parameters 446 of a PPS source. The data type includes a mode field, described in 447 section 3.3. It also includes an api_version field, a read-only 448 value giving the version of the API. Currently, the only defined 449 value is: 451 #define PPS_API_VERS_1 1 453 This field is present to enable binary compatibility with future 454 versions of the API. 456 As an OPTIONAL feature of the API, the implementation MAY support 457 adding offsets to the timestamps that are captured. (Values of type 458 ``struct timespec'' can represent negative offsets.) The 459 assert_offset field of a pps_params_t value specifies a value to be 460 added to generate a captured assert_timestamp. The clear_offset of a 461 pps_params_t value field specifies a value to be added to generate a 462 captured clear_timestamp. Since the offsets, if any, apply to all 463 users of a given PPS source, the implementation SHOULD impose access 464 controls on the use of this feature; for example, allowing only the 465 super-user to set the offset values. The default value for echo 466 offsets is zero. 468 3.3 Mode bit definitions 469 A set of mode bits is associated with each PPS source. 471 The bits in the mode field of the pps_params_t type are: 473 /* Device/implementation parameters */ 474 #define PPS_CAPTUREASSERT 0x01 475 #define PPS_CAPTURECLEAR 0x02 476 #define PPS_CAPTUREBOTH 0x03 478 Internet-Draft Pulse-Per-Second API 7 June 1999 17:40 480 #define PPS_OFFSETASSERT 0x10 481 #define PPS_OFFSETCLEAR 0x20 483 #define PPS_CANWAIT 0x100 485 /* Kernel actions */ 486 #define PPS_ECHOASSERT 0x40 487 #define PPS_ECHOCLEAR 0x80 489 /* Timestamp formats */ 490 #define PPS_TSFMT_TSPEC 0x1000 491 #define PPS_TSFMT_NTPFP 0x2000 493 These mode bits are divided into three categories: 495 1. Device/implementation parameters: These are parameters 496 either of the device or of the implementation. If the 497 implementation allows these to be changed, then these bits 498 are read/write for users with sufficient privilege (such 499 as the super-user), and read-only for other users. If the 500 implementation does not allow these bits to be changed, 501 they are read-only. 503 2. Kernel actions: These bits specify certain kernel actions 504 to be taken on arrival of a signal. If the implementation 505 supports one of these actions, then the corresponding bit 506 is read/write for users with sufficient privilege (such as 507 the super-user), and read-only for other users. If the 508 implementation does not support the action, the 509 corresponding bit is always zero. 511 3. Timestamp formats: These bits indicate the set of 512 timestamp formats available for the device. They are 513 always read-only. 515 In more detail, the meanings of the Device/implementation parameter 516 mode bits are: 518 PPS_CAPTUREASSERT 519 If this bit is set, the assert timestamp for the 520 associated PPS source will be captured. 522 PPS_CAPTURECLEAR 523 If this bit is set, the clear timestamp for the 524 associated PPS source will be captured. 526 PPS_CAPTUREBOTH Defined as the union of PPS_CAPTUREASSERT and 527 PPS_CAPTURECLEAR, for convenience. 529 PPS_OFFSETASSERT 530 If set, the assert_offset value is added to the 532 Internet-Draft Pulse-Per-Second API 7 June 1999 17:40 534 current value of the operating system's internal 535 timebase in order to generate the captured 536 assert_timestamp. 538 PPS_OFFSETCLEAR If set, the clear_offset value is added to the 539 current value of the operating system's internal 540 timebase in order to generate the captured 541 clear_timestamp. 543 PPS_CANWAIT If set, the time_pps_wait() function (see section 544 3.4.5) is available for use with this PPS source. 545 Otherwise, the time_pps_wait() function is a no-op. 546 Note: this mode bit cannot be set by an application; 547 it can only be read. 549 If neither PPS_CAPTUREASSERT nor PPS_CAPTURECLEAR is set, no valid 550 timestamp will be available via the API. 552 The meanings of the Kernel action mode bits are: 554 PPS_ECHOASSERT If set, after the capture of an assert timestamp, 555 the implementation generates a signal transition as 556 rapidly as possible on an output signal pin. This 557 MUST NOT affect the delay between the PPS source's 558 transition to the asserted phase and the capture of 559 the assert timestamp. 561 PPS_ECHOCLEAR If set, after the capture of a clear timestamp, the 562 implementation generates a signal transition as 563 rapidly as possible on an output signal pin. This 564 MUST NOT affect the delay between the PPS source's 565 transition to the clear phase and the capture of the 566 clear timestamp. 568 The timestamp formats are: 570 PPS_TSFMT_TSPEC Timestamps and offsets are represented as values of 571 type ``struct timespec''. All implementations MUST 572 support this format, and this format is the default 573 unless an application specifies otherwise. 575 PPS_TSFMT_NTPFP Timestamps and offsets are represented as values of 576 type ``ntp_fp_t'', which corresponds to the NTP 577 ``64-bit unsigned fixed-point'' timestamp format [3]. 578 Support for this format is OPTIONAL. 580 Other timestamp format bits may be defined as fields are added to the 581 ``pps_timeu_t'' union. 583 The operating system may implement all of these mode bits, or just a 584 subset of them. If an attempt is made to set an unsupported mode 586 Internet-Draft Pulse-Per-Second API 7 June 1999 17:40 588 bit, the API will return an error. If an attempt is made to modify a 589 read-only mode bit, the API will return an error. 591 3.4 New functions 592 In the description of functions that follows, we use the following 593 function parameters: 595 filedes A file descriptor (type: int), for a serial line or 596 other source of PPS events. 598 ppshandle A variable of type ``pps_handle_t'', as defined in 599 section 3.2. 601 ppsinfobuf A record of type ``pps_info_t'', as defined in 602 section 3.2. 604 ppsparams A record of type ``pps_params_t'', as defined in 605 section 3.2. 607 tsformat An integer with exactly one of the timestamp format 608 bits set. 610 3.4.1 New functions: obtaining PPS sources 611 The API includes a function to create and destroy PPS source 612 ``handles''. 614 SYNOPSIS 616 int time_pps_create(int filedes, pps_handle_t *handle); 617 int time_pps_destroy(pps_handle_t handle); 619 DESCRIPTION 621 All of the other functions in the PPS API operate on PPS handles 622 (type: pps_handle_t). The time_pps_create() is used to convert an 623 already-open UNIX file descriptor, for an appropriate special file, 624 into a PPS handle. 626 The definition of what special files are appropriate for use with the 627 PPS API is outside the scope of this specification, and may vary 628 based on both operating system implementation, and local system 629 configuration. One typical case is a serial line, whose DCD pin is 630 connected to a source of PPS events. 632 The mode in which the UNIX file descriptor was originally opened 633 affects what operations are allowed on the PPS handle. The 634 time_pps_setparams() and time_pps_kcbind() functions (see sections 635 3.4.2 and 3.4.4) SHOULD be prohibited by the implementation if the 636 descriptor is open only for reading (O_RDONLY). 638 Internet-Draft Pulse-Per-Second API 7 June 1999 17:40 640 --------- 641 Note: operations on a descriptor opened with an inappropriate 642 mode might fail with EBADF. 643 --------- 645 The time_pps_destroy() function makes the PPS handle unusable, and 646 frees any storage that might have been allocated for it. It does not 647 close the associated file descriptor, nor does it change any of the 648 parameter settings for the PPS source. 650 --------- 651 Note: If this API is adapted to an operating system that does 652 not follow UNIX conventions for representing an accessible PPS 653 source as an integer file descriptor, the time_pps_create() 654 function may take different parameters from those shown here. 655 --------- 657 RETURN VALUES 659 On successful completion, the time_pps_create() function returns 0. 660 Otherwise, a value of -1 is returned and errno is set to indicate the 661 error. 663 If called with a valid handle parameter, the time_pps_destroy() 664 function returns 0. Otherwise, it returns -1. 666 ERRORS 668 If the time_pps_create() function fails, errno may be set to one of 669 the following values: 671 [EBADF] The filedes parameter is not a valid file descriptor. 673 [EOPNOTSUPP] The use of the PPS API is not supported for the file 674 descriptor. 676 [EPERM] The process's effective user ID does not have the 677 required privileges to use the PPS API. 679 3.4.2 New functions: setting PPS parameters 680 The API includes several functions use to set or obtain the 681 parameters of a PPS source. 683 SYNOPSIS 685 int time_pps_setparams(pps_handle_t handle, 686 const pps_params_t *ppsparams); 688 Internet-Draft Pulse-Per-Second API 7 June 1999 17:40 690 int time_pps_getparams(pps_handle_t handle, 691 pps_params_t *ppsparams); 692 int time_pps_getcap(pps_handle_t handle, int *mode); 694 DESCRIPTION 696 A suitably privileged application may use time_pps_setparams() to set 697 the parameters (mode bits and timestamp offsets) for a PPS source. 698 The pps_params_t type is defined in section 3.2; mode bits are 699 defined in section 3.3. An application may use time_pps_getparams() 700 to discover the current settings of the PPS parameters. An 701 application that needs to change only a subset of the existing 702 parameters must first call time_pps_getparams() to obtain the current 703 parameter values, then set the new values using time_pps_setparams(). 705 --------- 706 Note: a call to time_pps_setparams() replaces the current 707 values of all mode bits with those specified via the ppsparams 708 argument, except those bits whose state cannot be changed. 709 Bits might be read-only due to access controls, or because they 710 are fixed by the implementation. 711 --------- 713 The timestamp format of the assert_offset and clear_offset fields is 714 defined by the mode field. That is, on a call to 715 time_pps_setparams(), the kernel interprets the supplied offset 716 values using the timestamp format given in the mode field of the 717 ppsparams argument. If the requested timestamp format is not 718 supported, the time_pps_setparams() function has no effect and 719 returns an error value. On a call to time_pps_getparams(), the 720 kernel provides the timestamp format of the offsets by setting one of 721 the timestamp format bits in the mode field. 723 --------- 724 Note: an application that uses time_pps_getparams() to read the 725 current offset values cannot specify which format is used. The 726 implementation SHOULD return the offsets using the same 727 timestamp format as was used when the offsets were set. 728 --------- 730 An application wishing to discover which mode bits it may set, with 731 its current effective user ID, may call time_pps_getcap(). This 732 function returns the set of mode bits that may be set by the 733 application, without generating an EINVAL or EPERM error, for the 734 specified PPS source. It does not return the current values for the 735 mode bits. A call to time_pps_getcap() returns the mode bits 736 corresponding to all supported timestamp formats. 738 The time_pps_getcap() function MAY ignore the mode in which the 739 associated UNIX file descriptor was opened, so the application might 741 Internet-Draft Pulse-Per-Second API 7 June 1999 17:40 743 still receive an EBADF error on a call to time_pps_setparams(), even 744 if time_pps_getcap() says that the chosen mode bits are allowed. 746 The mode bits returned by time_pps_getcap() for distinct PPS handles 747 may differ, reflecting the specific capabilities of the underlying 748 hardware connection to the PPS source, or of the source itself. 750 RETURN VALUES 752 On successful completion, the time_pps_setparams(), 753 time_pps_getparams(), and time_pps_getcap() functions return 0. 754 Otherwise, a value of -1 is returned and errno is set to indicate the 755 error. 757 ERRORS 759 If the time_pps_setparams(), time_pps_getparams(), or 760 time_pps_getcap() function fails, errno may be set to one of the 761 following values: 763 [EBADF] The handle parameter is not associated with a valid 764 file descriptor, or the descriptor is not open for 765 writing. 767 [EFAULT] A parameter points to an invalid address. 769 [EOPNOTSUPP] The use of the PPS API is not supported for the 770 associated file descriptor. 772 [EINVAL] The operating system does not support all of the 773 requested mode bits. 775 [EPERM] The process's effective user ID does not have the 776 required privileges to use the PPS API, or to set the 777 given mode bits. 779 3.4.3 New functions: access to PPS timestamps 780 The API includes one function that gives applications access to PPS 781 timestamps. 783 SYNOPSIS 785 int time_pps_fetch(pps_handle_t handle, 786 const int tsformat, 787 pps_info_t *ppsinfobuf); 789 Internet-Draft Pulse-Per-Second API 7 June 1999 17:40 791 DESCRIPTION 793 An application may use time_pps_fetch() to obtain the most recent 794 timestamps captured for the PPS source specified by the handle 795 parameter. The tsformat parameter specifies the desired timestamp 796 format; if the requested timestamp format is not supported, the call 797 fails and returns an error value. 799 The result is stored in the ppsinfobuf parameter, whose fields are 800 defined in section 3.2. 802 If this function is invoked before the system has captured a 803 timestamp for the signal source, the ppsinfobuf returned will have 804 its timestamp fields set to the time format's base date (e.g., for 805 PPS_TSFMT_TSPEC, both the tv_sec and tv_nsec fields will be zero). 807 RETURN VALUES 809 On successful completion, the time_pps_fetch() function returns 0. 810 Otherwise, a value of -1 is returned and errno is set to indicate the 811 error. 813 ERRORS 815 If the time_pps_fetch() function fails, errno may be set to one of 816 the following values: 818 [EBADF] The handle parameter is not associated with a valid 819 file descriptor. 821 [EFAULT] A parameter points to an invalid address. 823 [EINVAL] The requested timestamp format is not supported. 825 [EOPNOTSUPP] The use of the PPS API is not supported for the 826 associated file descriptor. 828 3.4.4 New functions: disciplining the kernel timebase 829 The API includes one OPTIONAL function to specify if and how a PPS 830 source is provided to a kernel consumer of PPS events, such as the 831 code used to discipline the operating system's internal timebase. 833 SYNOPSIS 835 int time_pps_kcbind(pps_handle_t handle, 836 const int kernel_consumer, 837 const int edge, 839 Internet-Draft Pulse-Per-Second API 7 June 1999 17:40 841 const int tsformat); 843 DESCRIPTION 845 An application with appropriate privileges may use time_pps_kcbind() 846 to bind a kernel consumer to the PPS source specified by the handle. 848 The kernel consumer is identified by the kernel_consumer parameter. 849 In the current version of the API, there is only one legal value for 850 this parameter: 852 #define PPS_KC_HARDPPS 0 854 which is the kernel's hardpps() function (or equivalent). 856 The edge parameter indicates which edge of the PPS signal causes a 857 timestamp to be delivered to the kernel consumer. It may have the 858 value PPS_CAPTUREASSERT, PPS_CAPTURECLEAR, or PPS_CAPTUREBOTH, 859 depending on particular characteristics of the PPS source. It may 860 also be zero, which removes any binding between the PPS source and 861 the kernel consumer. 863 The tsformat parameter specifies the format for the timestamps 864 delivered to the kernel consumer. If this value is zero, the 865 implementation MAY choose the appropriate format, or return EINVAL. 866 The implementation MAY ignore a non-zero value for this parameter. 868 The binding created by this call persists until it is changed by a 869 subsequent call specifying the same kernel_consumer. In particular, 870 a subsequent call to time_pps_destroy() for the specified handle does 871 not affect the binding. 873 The binding is independent of any prior or subsequent changes to the 874 PPS_CAPTUREASSERT and PPS_CAPTURECLEAR mode bits for the device. 875 However, if either the edge or the tsformat parameter values are 876 inconsistent with the capabilities of the PPS source, an error is 877 returned. The implementation MAY also return an error if the 878 tsformat value is unsupported for time_pps_kcbind(), even if it is 879 supported for other uses of the API. 881 The operating system will enforce two restrictions on the bindings 882 created by time_pps_kcbind(): 884 1. A kernel consumer may be bound to at most one PPS source 885 at any given time. 887 2. Bindings may only be set by a process with sufficient 888 privileges to modify the system's internal timebase. (On 889 UNIX systems, such modification is normally done using 890 settimeofday() and/or adjtime(), and is restricted to 891 users with superuser privilege.) 893 Internet-Draft Pulse-Per-Second API 7 June 1999 17:40 895 --------- 896 Warning: If this feature is configured for a PPS source that 897 does not have an accurate 1-pulse-per-second signal, or is 898 otherwise inappropriately configured, use of this feature may 899 result in seriously incorrect timekeeping for the entire 900 system. For best results, the 1-PPS signal should have much 901 better frequency stability than the system's internal clock 902 source (usually a crystal-controlled oscillator), and should 903 have jitter (variation in interarrival time) much less than the 904 system's clock-tick interval. 905 --------- 907 See RFC1589 [4] for more information about how the system's timebase 908 is disciplined using a PPS signal. 910 RETURN VALUES 912 On successful completion, the time_pps_kcbind() function returns 0. 913 Otherwise, a value of -1 is returned and errno is set to indicate the 914 error. 916 ERRORS 918 If the time_pps_kcbind() function fails, errno may be set to one of 919 the following values: 921 [EBADF] The handle parameter is not associated with a valid 922 file descriptor, or the descriptor is not open for 923 writing. 925 [EFAULT] A parameter points to an invalid address. 927 [EINVAL] The requested timestamp format is not supported. 929 [EOPNOTSUPP] The use of the PPS API is not supported for the 930 associated file descriptor, or this OPTIONAL function 931 is not supported. 933 [EPERM] The process's effective user ID does not have the 934 required privileges to set the binding. 936 3.4.5 New functions: waiting for an event 937 The API includes a function that allows an application to block until 938 the next timestamp is captured. (The API does not directly support 939 the use of the select() system call to wait for PPS events.) 941 This is an OPTIONAL feature of the API, and may be implemented as a 942 stub that always returns an error. An application can determine 943 whether the feature is implemented by using time_pps_getcap() to see 944 if the PPS_CANWAIT mode bit is set. 946 Internet-Draft Pulse-Per-Second API 7 June 1999 17:40 948 SYNOPSIS 950 int time_pps_wait(pps_handle_t handle, 951 const struct timespec *timeout, 952 const int tsformat, 953 pps_info_t *ppsinfobuf); 955 DESCRIPTION 957 This function blocks until either a timestamp is captured from the 958 PPS source, or until the specified timeout duration has expired. If 959 the timeout parameter is a NULL pointer, the function simply blocks 960 until a timestamp is captured. If the timeout parameter specifies a 961 delay of zero, this function is effectively identical to 962 time_pps_fetch(). The tsformat parameter specifies the desired 963 timestamp format; if the requested timestamp format is not supported, 964 the call fails and returns an error value. 966 If the function returns as the result of a timeout or error, the 967 contents of the ppsinfobuf are undefined. If the function returns 968 because a timestamp has been captured, the contents of the ppsinfobuf 969 are exactly as would have been returned by the time_pps_fetch() 970 function, had it been called immediately after the timestamp was 971 captured. 973 If the PPS_CANWAIT mode bit is clear, then this function is a no-op, 974 and always returns an error. 976 RETURN VALUES 978 On successful completion, the time_pps_wait() function returns 0. 979 Otherwise, a value of -1 is returned and errno is set to indicate the 980 error. 982 ERRORS 984 If the time_pps_wait() function fails, errno may be set to one of the 985 following values: 987 [EBADF] The handle parameter is not associated with a valid 988 file descriptor. 990 [EFAULT] A parameter points to an invalid address. 992 [EINTR] A signal was delivered before the time limit 993 specified by the timeout parameter expired and before 994 a timestamp has been captured. 996 Internet-Draft Pulse-Per-Second API 7 June 1999 17:40 998 [EINVAL] The requested timestamp format is not supported. 1000 [EOPNOTSUPP] The use of the PPS API is not supported for the 1001 associated file descriptor, or this OPTIONAL function 1002 is not supported. 1004 [ETIMEDOUT] The timeout duration has expired. 1006 3.5 Compliance rules 1007 The key words "MUST", "MUST NOT", "REQUIRED","SHOULD", SHOULD NOT", 1008 "MAY", and "OPTIONAL" in this document are to be interpreted as 1009 described in RFC2119 [1]. 1011 Some features of this specification are OPTIONAL, but others are 1012 REQUIRED. 1014 3.5.1 Functions 1015 An implementation MUST provide these functions: 1016 - time_pps_create() 1017 - time_pps_destroy() 1018 - time_pps_setparams() 1019 - time_pps_getparams() 1020 - time_pps_getcap() 1021 - time_pps_fetch() 1023 An implementation MUST provide these functions, but they may be 1024 implementation as functions that always return an EOPNOTSUPP error, 1025 possibly on a per-source basis: 1026 - time_pps_wait() 1027 - time_pps_kcbind() 1029 3.5.2 Mode bits 1030 An implementation MUST support at least one of these mode bits for 1031 each PPS source: 1032 - PPS_CAPTUREASSERT 1033 - PPS_CAPTURECLEAR 1034 and MAY support both of them. If an implementation supports both of 1035 these bits for a PPS source, it SHOULD allow them to be set 1036 simultaneously. 1038 An implementation MUST support this timestamp format: 1039 - PPS_TSFMT_TSPEC 1041 An implementation MAY support these mode bits: 1042 - PPS_ECHOASSERT 1043 - PPS_ECHOCLEAR 1044 - PPS_OFFSETASSERT 1045 - PPS_OFFSETCLEAR 1047 An implementation MAY support this timestamp format: 1049 Internet-Draft Pulse-Per-Second API 7 June 1999 17:40 1051 - PPS_TSFMT_NTPFP 1053 3.6 Examples 1054 A very simple use of this API might be: 1056 int fd; 1057 pps_handle_t handle; 1058 pps_params_t params; 1059 pps_info_t infobuf; 1061 /* Open a file descriptor and enable PPS on rising edges */ 1062 fd = open(PPSfilename, O_RDWR, 0); 1063 time_pps_create(fd, &handle); 1064 time_pps_getparams(handle, ¶ms); 1065 if ((params.mode & PPS_CAPTUREASSERT) == 0) { 1066 fprintf(stderr, "%s cannot currently CAPTUREASSERT\n", 1067 PPSfilename); 1068 exit(1); 1069 } 1071 /* loop, printing the most recent timestamp every second or so */ 1072 while (1) { 1073 sleep(1); 1074 time_pps_fetch(handle, PPS_TSFMT_TSPEC, &infobuf); 1075 printf("Assert timestamp: %d.%09d, sequence: %ld\n", 1076 infobuf.assert_timestamp.tv_sec, 1077 infobuf.assert_timestamp.tv_nsec, 1078 infobuf.assert_sequence); 1079 } 1081 Note that this example omits most of the error-checking that would be 1082 expected in a reliable program. 1084 Also note that, on a system that supports time_pps_wait(), the 1085 function of these lines: 1087 sleep(1); 1088 time_pps_fetch(handle, PPS_TSFMT_TSPEC, &infobuf); 1090 might be more reliably accomplished using: 1092 timeout.tv_sec = 100; 1093 timeout.tv_nsec = 0; 1094 time_pps_wait(handle, &timeout, PPS_TSFMT_TSPEC, &infobuf); 1096 The (arbitrary) timeout value is used to protect against the 1097 possibility that another application might disable PPS timestamps, or 1098 that the hardware generating the timestamps might fail. 1100 A slightly more elaborate use of this API might be: 1102 Internet-Draft Pulse-Per-Second API 7 June 1999 17:40 1104 int fd; 1105 pps_handle_t handle; 1106 pps_params_t params; 1107 pps_info_t infobuf; 1108 int avail_mode; 1110 /* Open a file descriptor */ 1111 fd = open(PPSfilename, O_RDWR, 0); 1112 time_pps_create(fd, &handle); 1114 /* 1115 * Find out what features are supported 1116 */ 1117 time_pps_getcap(handle, &avail_mode); 1118 if ((avail_mode & PPS_CAPTUREASSERT) == 0) { 1119 fprintf(stderr, "%s cannot CAPTUREASSERT\n", PPSfilename); 1120 exit(1); 1121 } 1122 if ((avail_mode & PPS_OFFSETASSERT) == 0) { 1123 fprintf(stderr, "%s cannot OFFSETASSERT\n", PPSfilename); 1124 exit(1); 1125 } 1127 /* 1128 * Capture assert timestamps, and 1129 * compensate for a 675 nsec propagation delay 1130 */ 1132 time_pps_getparams(handle, ¶ms); 1133 params.assert_offset.tv_sec = 0; 1134 params.assert_offset.tv_nsec = 675; 1135 params.mode |= PPS_CAPTUREASSERT | PPS_OFFSETASSERT | 1136 PPS_TSFMT_TSPEC; 1137 time_pps_setparams(handle, ¶ms); 1139 /* loop, printing the most recent timestamp every second or so */ 1140 while (1) { 1141 if (avail_mode & PPS_CANWAIT) { 1142 time_pps_wait(handle, NULL, PPS_TSFMT_TSPEC, &infobuf); 1143 } else { 1144 sleep(1); 1145 time_pps_fetch(handle, PPS_TSFMT_TSPEC, &infobuf); 1146 } 1147 printf("Assert timestamp: %d.%09d, sequence: %ld\n", 1148 infobuf.assert_timestamp.tv_sec, 1149 infobuf.assert_timestamp.tv_nsec, 1150 infobuf.assert_sequence); 1151 } 1153 Again, most of the necessary error-checking has been omitted from 1154 this example. 1156 Internet-Draft Pulse-Per-Second API 7 June 1999 17:40 1158 4 Security Considerations 1160 This API gives applications three capabilities: 1162 - Causing the system to capture timestamps on certain events. 1164 - Obtaining timestamps for certain events. 1166 - Affecting the system's internal timebase. 1168 The first capability should not affect security directly, but might 1169 cause a slight increase in interrupt latency and interrupt-handling 1170 overhead. 1172 The second capability might be useful in implementing certain kinds 1173 of covert communication channels. 1175 In most cases, neither of these first two issues is a significant 1176 security threat, because the traditional UNIX file protection 1177 facility may be used to to limit access to the relevant special 1178 files. Provision of the PPS API adds minimal additional risk. 1180 The final capability is reserved to highly privileged users. In UNIX 1181 systems, this means those with superuser privilege. Such users can 1182 evade protections based on file permissions; however, such users can 1183 in general cause unbounded havoc, and can set the internal timebase 1184 (and its rate of change), so this API creates no new vulnerabilities. 1186 5 Acknowledgements 1188 The API in this document draws some of its inspiration from the LBL 1189 ``ppsclock'' distribution [2], originally implemented in 1993 by 1190 Steve McCanne, Craig Leres, and Van Jacobson. We also thank Craig 1191 Leres, Judah Levine, and Harlan Stenn for helpful comments they 1192 contributed during the drafting of this document. 1194 6 References 1196 1. Scott Bradner. Key words for use in RFCs to Indicate Requirement 1197 Levels. RFC 2119, Harvard University, March, 1997. 1199 2. Steve McCanne, Craig Leres, and Van Jacobson. PPSCLOCK. 1200 ftp://ftp.ee.lbl.gov/ppsclock.tar.Z. 1202 3. David L. Mills. Network Time Protocol (Version 3): 1203 Specification, Implementation and Analysis. RFC 1305, IETF, March, 1204 1992. 1206 Internet-Draft Pulse-Per-Second API 7 June 1999 17:40 1208 4. David L. Mills. A Kernel Model for Precision Timekeeping. RFC 1209 1589, IETF, March, 1994. 1211 5. The Open Group. The Single UNIX Specification, Version 2 - 6 Vol 1212 Set for UNIX 98. Document number T912, The Open Group, February, 1213 1997. 1215 7 Authors' addresses 1217 Jeffrey C. Mogul 1218 Western Research Laboratory 1219 Digital Equipment Corporation 1220 250 University Avenue 1221 Palo Alto, California, 94305, U.S.A. 1222 Email: mogul@wrl.dec.com 1223 Phone: 1 650 617 3304 (email preferred) 1225 David L. Mills 1226 Electrical and Computer Engineering Department 1227 University of Delaware 1228 Newark, DE 19716 1229 Phone: (302) 831-8247 1230 EMail: mills@udel.edu 1232 Jan Brittenson 1233 Sun Microsystems, Inc. 1234 901 San Antonio Rd M/S MPK17-202 1235 Palo Alto, CA 94303 1236 Email: Jan.Brittenson@Eng.Sun.COM 1238 Jonathan Stone 1239 Stanford Distributed Systems Group 1240 Stanford, CA 94305 1241 Phone: (650) 723-2513 1242 Email: jonathan@dsg.stanford.edu 1244 Poul-Henning Kamp 1245 The FreeBSD Project 1246 Valbygaardsvej 8 1247 DK-4200 Slagelse 1248 Denmark 1249 Phone: +45 58 56 10 59 1250 Email: phk@FreeBSD.org 1252 Ulrich Windl 1253 Universitaet Regensburg, Klinikum 1254 Email: ulrich.windl@rz.uni-regensburg.de 1256 Internet-Draft Pulse-Per-Second API 7 June 1999 17:40 1258 A. Extensions and related APIs 1260 The API specified in the main body of this document could be more 1261 useful with the provision of several extensions or companion APIs. 1263 At present, the interfaces listed in this appendix are not part of 1264 the formal specification in this document. 1266 A.1 Extension: Parameters for the ``echo'' mechanism 1268 The ``echo'' mechanism described in the body of this specification 1269 leaves most of the details to the implementor, especially the 1270 designation of one or more output pins. 1272 It might be useful to extend this API to provide either or both of 1273 these features: 1275 - A means by which the application can discover which output 1276 pin is echoing the input pin. 1278 - A means by which the application can select which output 1279 pin is echoing the input pin. 1281 A.2 Extension: Obtaining information about external clocks 1283 The PPS API may be useful with a wide variety of reference clocks, 1284 connected via several different interface technologies (including 1285 serial lines, parallel interfaces, and bus-level interfaces). These 1286 reference clocks can have many features and parameters, some of which 1287 might not even have been invented yet. 1289 We believe that it would be useful to have a mechanism by which an 1290 application can discover arbitrary features and parameters of a 1291 reference clock. These might include: 1292 - Clock manufacturer, model number, and revision level 1293 - Whether the clock is synchronized to an absolute standard 1294 - For synchronized clocks, 1295 * The specific standard 1296 * The accuracy of the standard 1297 * The path used (direct connection, shortwave, longwave, 1298 satellite, etc.) 1299 * The distance (offset) and variability of this path 1301 - For PPS sources, 1302 * The pulse rate 1303 * The pulse shape 1304 * Which edge of the pulse corresponds to the epoch 1306 Internet-Draft Pulse-Per-Second API 7 June 1999 17:40 1308 - The time representation format 1310 This information might best be provided by an API analogous to the 1311 standard ``curses'' API, with a database analogous to the standard 1312 ``terminfo'' database. That is, a ``clockinfo'' database would 1313 contain a set of (attribute, value) pairs for each type of clock, and 1314 the API would provide a means to query this database. 1316 Additional mechanisms would allow an application to discover the 1317 clock or clocks connected to the local system, and to discover the 1318 clockinfo type of a specific clock device. 1320 A.3 Extension: Finding a PPS source 1322 Although the clockinfo database described in section A.2, together 1323 with the discover mechanisms described there, would allow an 1324 application to discover the PPS source (or sources) connected to a 1325 system, it might be more complex than necessary. 1327 A simpler approach would be to support a single function that 1328 provides the identity of one or more PPS sources. 1330 For example, the function might be declared as 1332 int time_pps_findsource(int index, 1333 char *path, int pathlen, 1334 char *idstring, int idlen); 1336 The index argument implicitly sets up an ordering on the PPS sources 1337 attached to the system. An application would use this function to 1338 inquire about the Nth source. The function would return -1 if no 1339 such source exists; otherwise, it would return 0, and would place the 1340 pathname of the associated special file in the path argument. It 1341 would also place an identification string in the idstring argument. 1342 The identification string could include the clock make, model, 1343 version, etc., which could then be used by the application to control 1344 its behavior. 1346 This function might simply read the Nth line from a simple database, 1347 containing lines such as: 1349 /dev/tty00 "TrueTime 468-DC" 1350 /dev/pps1 "Homebrew rubidium frequency standard" 1352 allowing the system administrator to describe the configuration of 1353 PPS sources. 1355 Internet-Draft Pulse-Per-Second API 7 June 1999 17:40 1357 B. Example implementation: PPSDISC Line discipline 1359 One possible implementation of the PPS API might be to define a new 1360 ``line discipline'' and then map the API onto a set of ioctl() 1361 commands. Here we sketch such an implementation; note that this is 1362 not part of the specification of the API, and applications should not 1363 expect this low-level interface to be available. 1365 In this approach, the set of line disciplines is augmented with one 1366 new line discipline, PPSDISC. This discipline will act exactly the 1367 same as the TTYDISC discipline, except for its handling of modem DCD 1368 interrupts. 1370 Once the TIOCSETD ioctl() has been used to select this line 1371 discipline, PPS-related operations on the serial line may be invoked 1372 using new ioctl() commands. For example (values used only for 1373 illustration): 1375 #define PPSFETCH _IOR('t', 75, pps_info_t) 1376 #define PPSSETPARAM _IOW('t', 76, pps_params_t) 1377 #define PPSGETPARAM _IOR('t', 77, pps_params_t) 1378 #define PPSGETCAP _IOR('t', 78, int) 1380 B.1 Example 1382 A typical use might be: 1384 int ldisc = PPSDISC; 1385 pps_params_t params; 1386 pps_info_t infobuf; 1388 ioctl(fd, TIOCSETD, &ldisc); /* set discipline */ 1390 /* 1391 * Check the capabilities of this PPS source to see 1392 * if it supports what we need. 1393 */ 1394 ioctl(fd, PPSGETCAP, ¶ms); 1395 if ((params.mode & PPS_CAPTUREASSERT) == 0) { 1396 fprintf(stderr, "PPS source is not suitable\n"); 1397 exit(1); 1398 } 1400 /* 1401 * Set this line to timestamp on a rising-edge interrupt 1402 */ 1403 ioctl(fd, PPSGETPARAMS, ¶ms); 1404 params.mode |= PPS_CAPTUREASSERT; 1405 ioctl(fd, PPSSETPARAMS, ¶ms); 1407 Internet-Draft Pulse-Per-Second API 7 June 1999 17:40 1409 sleep(2); /* allow time for the PPS pulse to happen */ 1411 /* obtain most recent timestamp and sequence # for this line */ 1412 ioctl(fd, PPSFETCH, &infobuf); 1414 Again, this example imprudently omits any error-checking. 1416 C. Available implementations 1418 Several available implementations of this API are listed at 1419 .