idnits 2.17.1 draft-mogul-pps-api-04.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: ---------------------------------------------------------------------------- ** 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 30 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 253: '... However, these assignments SHOULD be...' RFC 2119 keyword, line 255: '... SHOULD document these assignments....' RFC 2119 keyword, line 274: '...e implementation SHOULD impose access ...' RFC 2119 keyword, line 287: '...ecification, but SHOULD be documented ...' RFC 2119 keyword, line 288: '... output pin MAY also undergo transit...' (30 more instances...) Miscellaneous warnings: ---------------------------------------------------------------------------- == Line 331 has weird spacing: '... long tv_...' == Line 339 has weird spacing: '...ned int int...' == Line 340 has weird spacing: '...ned int fra...' == Line 352 has weird spacing: '...ed long long...' == Line 379 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 (23 July 1999) is 9016 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 947 looks like a reference -- Missing reference section? '3' on line 578 looks like a reference -- Missing reference section? '5' on line 102 looks like a reference -- Missing reference section? 'EBADF' on line 963 looks like a reference -- Missing reference section? 'EOPNOTSUPP' on line 971 looks like a reference -- Missing reference section? 'EPERM' on line 975 looks like a reference -- Missing reference section? 'EFAULT' on line 967 looks like a reference -- Missing reference section? 'EINVAL' on line 969 looks like a reference -- Missing reference section? 'EINTR' on line 843 looks like a reference -- Missing reference section? 'ETIMEDOUT' on line 852 looks like a reference -- Missing reference section? '1' on line 984 looks like a reference -- Missing reference section? '2' on line 1173 looks like a reference Summary: 5 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, Compaq WRL 2 Internet-Draft David Mills, UDel 3 Expires: 31 January 2000 Jan Brittenson, Sun 4 Jonathan Stone, Stanford 5 Poul-Henning Kamp, FreeBSD 6 Ulrich Windl, Universitaet Regensburg 7 23 July 1999 9 Pulse-Per-Second API for UNIX-like Operating Systems, Version 1.0 11 draft-mogul-pps-api-04.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 23 July 1999 16:36 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 13 66 3.4.2 New functions: setting PPS parameters 15 67 3.4.3 New functions: access to PPS timestamps 17 68 3.4.4 New functions: disciplining the kernel timebase 19 69 3.5 Compliance rules 22 70 3.5.1 Functions 22 71 3.5.2 Mode bits 22 72 3.6 Examples 23 73 4 Security Considerations 25 74 5 Acknowledgements 25 75 6 References 26 76 7 Authors' addresses 26 78 A. Extensions and related APIs 27 79 A.1 Extension: Parameters for the ``echo'' mechanism 27 80 A.2 Extension: Obtaining information about external clocks 27 81 A.3 Extension: Finding a PPS source 28 83 B. Example implementation: PPSDISC Line discipline 29 84 B.1 Example 29 86 C. Available implementations 30 88 1 Introduction 90 RFC1589 [4] describes a model and programming interface for generic 91 operating system software that manages the system clock and timer 92 functions. The model provides improved accuracy and stability for 93 most workstations and servers using the Network Time Protocol 94 (NTP) [3] or similar time synchronization protocol. The model 95 supports the use of external timing sources, such as the precision 96 pulse-per-second (PPS) signals typically available from precise time 97 sources (such as a GPS or GOES receiver). 99 However, RFC1589 did not define an application programming interface 100 (API) for the PPS facility. This document specifies such an 101 interface, for use with UNIX (or UNIX-like) operating systems. Such 102 systems often conform to the ``Single UNIX Specification'' [5], 103 sometimes known as POSIX. 105 Internet-Draft Pulse-Per-Second API 23 July 1999 16:36 107 One convenient means to provide a PPS signal to a computer system is 108 to connect that signal to a modem-control pin on a serial-line 109 interface to the computer. The Data Carrier Detect (DCD) pin is 110 frequently used for this purpose. Typically, the time-code output of 111 the time source is transmitted to the computer over the same serial 112 line. The computer detects a signal transition on the DCD pin, 113 usually by receiving an interrupt, and records a timestamp as soon as 114 possible. 116 Although existing practice has focussed on the use of serial lines 117 and DCD transitions, PPS signals might also be delivered by other 118 kinds of devices. The API specified in this document does not 119 require the use of a serial line, although it may be somewhat biased 120 in that direction. 122 The typical use of this facility is for the operating system to 123 record a high-resolution timestamp as soon as possible after it 124 detects a PPS signal transition (usually indicated by an interrupt). 125 This timestamp can then be made available, with less stringent delay 126 constraints, to timekeeping software. The software can compare the 127 captured timestamp to the received time-code to accurately determine 128 the absolute offset between the system clock and the precise time 129 source. 131 The operating system may also deliver the PPS event to a kernel 132 procedure, called the ``in-kernel PPS consumer.'' One example would 133 be the ``hardpps()'' procedure, described in RFC1589, which is used 134 to discipline the kernel's internal timebase. 136 The API specified in this document allows for one or more signal 137 sources attached to a computer system to provide PPS inputs, at the 138 option of user-level software. User-level software may obtain 139 signal-transition timestamps for any of these PPS sources. 140 User-level software may optionally specify at most one of these PPS 141 sources to be used to discipline the system's internal timebase. 143 Although the primary purpose of this API is for capturing true 144 pulse-per-second events, the API may also be used for accurately 145 timestamping events of other periods, or even aperiodic events, when 146 these can be expressed as signal transitions. 148 This document does not define internal details of how the API must be 149 implemented, and does not specify constraints on the accuracy, 150 resolution, or latency of the PPS feature. However, the utility of 151 this feature is inversely proportional to the delay (and variance of 152 delay), and implementors are encouraged to take this seriously. 154 In principle, the rate of events to be captured, or the frequency of 155 the signals, can range from once per day (or less often) to several 156 thousand per second. However, since in most implementations the 157 timestamping function will be implemented as a processor interrupt at 159 Internet-Draft Pulse-Per-Second API 23 July 1999 16:36 161 a relatively high priority, it is prudent to limit the rate of such 162 events. This may be done either by mechanisms in the hardware that 163 generates the signals, or by the operating system. 165 2 Data types for representing timestamps 167 Computer systems use various representations of time. Because this 168 API is concerned with the provision of high-accuracy, high-resolution 169 time information, the choice of representation is significant. (Here 170 we consider only binary representations, not human-format 171 representations.) 173 The two interesting questions are: 175 1. what is the resolution of the representation? 177 2. what time scale is represented? 179 These questions often lead to contentious arguments. Since this API 180 is intended for use with NTP and POSIX-compliant systems, however, we 181 can limit the choices to representations compatible with existing NTP 182 and POSIX practice, even if that practice is considered ``wrong'' in 183 some quarters. 185 2.1 Resolution 186 In the NTP protocol, ``timestamps are represented as a 64-bit 187 unsigned fixed-point number, in seconds relative to 0h on 1 January 188 1900. The integer part is in the first 32 bits and the fraction part 189 in the last 32 bits [...] The precision of this representation is 190 about 200 picoseconds'' [3]. 192 However, most computer systems cannot measure time to this resolution 193 (this represents a clock rate of 5 GHz). The POSIX gettimeofday() 194 function returns a ``struct timeval'' value, with a resolution of 1 195 microsecond. The POSIX clock_gettime() function returns a ``struct 196 timespec'' value, with a resolution of 1 nanosecond. 198 This API uses an extensible representation, but defaults to the 199 ``struct timespec'' representation. 201 2.2 Time scale 202 Several different time scales have been proposed for use in computer 203 systems. UTC and TAI are the two obvious candidates. 205 Some people would prefer the use of TAI, which is identical to UTC 206 except that it does not correct for leap seconds. Their preference 207 for TAI stems from the difficulty of computing precise time 208 differences when leap seconds are involved, especially when using 209 times in the future (for which the exact number of leap seconds is, 210 in general, unknowable). 212 Internet-Draft Pulse-Per-Second API 23 July 1999 16:36 214 However, POSIX and NTP both use UTC, albeit with different base 215 dates. Given that support for TAI would, in general, require other 216 changes to the POSIX specification, this API uses the POSIX base date 217 of 00:00 January 1, 1970 UTC, and conforms to the POSIX use of the 218 UTC time scale. 220 3 API 222 A PPS facility can be used in two different ways: 224 1. An application can obtain a timestamp, using the system's 225 internal timebase, for the most recent PPS event. 227 2. The kernel may directly utilize PPS events to discipline 228 its internal timebase, thereby providing highly accurate 229 time to all applications. 231 This API supports both uses, individually or in combination. The 232 timestamping feature may be used on any number of PPS sources 233 simultaneously; the timebase-disciplining feature may be used with at 234 most one PPS source. 236 Although the proper implementation of this API requires support from 237 the kernel of a UNIX system, this document defines the API in terms 238 of a set of library routines. This gives the implementor some 239 freedom to divide the effort between kernel code and library code 240 (different divisions might be appropriate on microkernels and 241 monolithic kernels, for example). 243 3.1 PPS abstraction 244 A PPS signal consists of a series of pulses, each with an 245 ``asserted'' (logical true) phase, and a ``clear'' (logical false) 246 phase. The two phases may be of different lengths. The API may 247 capture an ``assert timestamp'' at the moment of the transition into 248 the asserted phase, and a ``clear timestamp'' at the moment of the 249 transition into the clear phase. 251 The specific assignment of the logical values ``true'' and ``false'' 252 with specific voltages of a PPS signal, if applicable, is outside the 253 scope of this specification. However, these assignments SHOULD be 254 consistent with applicable standards. Implementors of PPS sources 255 SHOULD document these assignments. 257 --------- 258 Reminder to implementors of DCD-based PPS support: TTL and 259 RS-232C (V.24/V.28) interfaces both define the "true" state as 260 the one having the highest positive voltage. TTL defines a 261 nominal absence of voltage as the "false" state, but RS-232C 262 (V.24/V.28) defines the "false" state by the presence of a 263 negative voltage. 264 --------- 266 Internet-Draft Pulse-Per-Second API 23 July 1999 16:36 268 The API supports the direct provision of PPS events (and timestamps) 269 to an in-kernel PPS consumer. This could be the function called 270 ``hardpps()'', as described in RFC1589 [4], but the API does not 271 require the kernel implementation to use that function name 272 internally. The current version of the API supports at most one 273 in-kernel PPS consumer, and does not provide a way to explicitly name 274 it. The implementation SHOULD impose access controls on the use of 275 this feature. 277 The API optionally supports an ``echo'' feature, in which events on 278 the incoming PPS signal may be reflected through software, after the 279 capture of the corresponding timestamp, to an output signal pin. 280 This feature may be used to determine an upper bound on the actual 281 delay between the edges of the PPS signal and the capture of the 282 timestamps; such information may be useful in precise calibration of 283 the system. 285 The designation of an output pin for the echo signal, and sense and 286 shape of the output transition, is outside the scope of this 287 specification, but SHOULD be documented for each implementation. The 288 output pin MAY also undergo transitions at other times besides those 289 caused by PPS input events. 291 --------- 292 Note: this allows an implementation of the echo feature to 293 generate an output pulse per input pulse, or an output edge per 294 input pulse, or an output pulse per input edge. It also allows 295 the same signal pin to be used for several purposes 296 simultaneously. 297 --------- 299 Also, the API optionally provides an application with the ability to 300 specify an offset value to be applied to captured timestamps. This 301 can be used to correct for cable and/or radio-wave propagation 302 delays, or to compensate for systematic jitter in the external 303 signal. The implementation SHOULD impose access controls on the use 304 of this feature. 306 3.2 New data structures 307 The data structure declarations and symbol definitions for this API 308 will appear in the header file . 310 The API includes several implementation-specific types: 312 typedef ... pps_handle_t; /* represents a PPS source */ 314 typedef unsigned ... pps_seq_t; /* sequence number */ 316 The ``pps_handle_t'' type is an opaque scalar type used to represent 317 a PPS source within the API. 319 Internet-Draft Pulse-Per-Second API 23 July 1999 16:36 321 The ``pps_seq_t'' type is an unsigned integer data type of at least 322 32 bits. 324 The precise declaration of the pps_handle_t and pps_seq_t types is 325 system-dependent. 327 The API imports the standard POSIX definition for this data type: 329 struct timespec { 330 time_t tv_sec; /* seconds */ 331 long tv_nsec; /* nanoseconds */ 332 }; 334 The API defines this structure as an internal (not ``on the wire'') 335 representation of the NTP ``64-bit unsigned fixed-point'' timestamp 336 format [3]: 338 typedef struct ntp_fp { 339 unsigned int integral; 340 unsigned int fractional; 341 } ntp_fp_t; 343 The two fields in this structure may be declared as any unsigned 344 integral type, each of at least 32 bits. 346 The API defines this new union as an extensible type for representing 347 times: 349 typedef union pps_timeu { 350 struct timespec tspec; 351 ntp_fp_t ntpfp; 352 unsigned long longpad[3]; 353 } pps_timeu_t; 355 Future revisions of this specification may add more fields to this 356 union. 358 --------- 359 Note: adding a field to this union that is larger than 360 3*sizeof(long) will break binary compatibility. 361 --------- 363 The API defines these new data structures: 365 typedef struct { 366 pps_seq_t assert_sequence; /* assert event seq # */ 367 pps_seq_t clear_sequence; /* clear event seq # */ 368 pps_timeu_t assert_tu; 369 pps_timeu_t clear_tu; 370 int current_mode; /* current mode bits */ 372 Internet-Draft Pulse-Per-Second API 23 July 1999 16:36 374 } pps_info_t; 376 #define assert_timestamp assert_tu.tspec 377 #define clear_timestamp clear_tu.tspec 379 #define assert_timestamp_ntpfp assert_tu.ntpfp 380 #define clear_timestamp_ntpfp clear_tu.ntpfp 382 typedef struct { 383 int api_version; /* API version # */ 384 int mode; /* mode bits */ 385 pps_timeu_t assert_off_tu; 386 pps_timeu_t clear_off_tu; 387 } pps_params_t; 389 #define assert_offset assert_off_tu.tspec 390 #define clear_offset clear_off_tu.tspec 392 #define assert_offset_ntpfp assert_off_tu.ntpfp 393 #define clear_offset_ntpfp clear_off_tu.ntpfp 395 The ``pps_info_t'' type is returned on an inquiry to PPS source. It 396 contains the timestamps for the most recent assert event, and the 397 most recent clear event. The order in which these events were 398 actually received is defined by the timetamps, not by any other 399 aspect of the specification. Each timestamp field represents the 400 value of the operating system's internal timebase when the 401 timestamped event occurred, or as close as possible to that time 402 (with the optional addition of a specified offset). The current_mode 403 field contains the value of the mode bits (see section 3.3) at the 404 time of the most recent transition was captured for this PPS source. 405 An application can use current_mode to determine the format of the 406 timestamps returned. 408 The assert_sequence number increases once per captured assert 409 timestamp. Its initial value is undefined. If incremented past the 410 largest value for the type, the next value is zero. The 411 clear_sequence number increases once per captured clear timestamp. 412 Its initial value is undefined, and may be different from the initial 413 value of assert_sequence. If incremented past the largest value for 414 the type, the next value is zero. Due to possible signal loss or 415 excessive signal noise, the assert-sequence number and the 416 clear-sequence number might not always increase in step with each 417 other. 419 --------- 420 Note that these sequence numbers are most useful in 421 applications where events other than PPS transitions are to be 422 captured, which might be involved in a precision stopwatch 423 application, for example. In such cases, the sequence numbers 424 may be used to detect overruns, where the application has 426 Internet-Draft Pulse-Per-Second API 23 July 1999 16:36 428 missed one or more events. They may also be used to detect an 429 excessive event rate, or to detect that an event has failed to 430 occur between two calls to the time_pps_fetch() function 431 (defined later). 433 In order to obtain an uninterrupted series of sequence numbers 434 (and hence of event timestamps), it may be necessary to sample 435 the pps_info_t values at a rate somewhat faster than the 436 underlying event rate. For example, an application interested 437 in both assert and clear timestamps may need to sample at least 438 twice per second. Proper use of the sequence numbers allows an 439 application to discover if it has missed any event timestamps 440 due to an insufficient sampling rate. 441 --------- 443 The pps_params_t data type is used to discover and modify parameters 444 of a PPS source. The data type includes a mode field, described in 445 section 3.3. It also includes an api_version field, a read-only 446 value giving the version of the API. Currently, the only defined 447 value is: 449 #define PPS_API_VERS_1 1 451 This field is present to enable binary compatibility with future 452 versions of the API. 454 As an OPTIONAL feature of the API, the implementation MAY support 455 adding offsets to the timestamps that are captured. (Values of type 456 ``struct timespec'' can represent negative offsets.) The 457 assert_offset field of a pps_params_t value specifies a value to be 458 added to generate a captured assert_timestamp. The clear_offset of a 459 pps_params_t value field specifies a value to be added to generate a 460 captured clear_timestamp. Since the offsets, if any, apply to all 461 users of a given PPS source, the implementation SHOULD impose access 462 controls on the use of this feature; for example, allowing only the 463 super-user to set the offset values. The default value for both 464 offsets is zero. 466 3.3 Mode bit definitions 467 A set of mode bits is associated with each PPS source. 469 The bits in the mode field of the pps_params_t type are: 471 /* Device/implementation parameters */ 472 #define PPS_CAPTUREASSERT 0x01 473 #define PPS_CAPTURECLEAR 0x02 474 #define PPS_CAPTUREBOTH 0x03 476 #define PPS_OFFSETASSERT 0x10 477 #define PPS_OFFSETCLEAR 0x20 479 Internet-Draft Pulse-Per-Second API 23 July 1999 16:36 481 #define PPS_CANWAIT 0x100 482 #define PPS_CANPOLL 0x200 484 /* Kernel actions */ 485 #define PPS_ECHOASSERT 0x40 486 #define PPS_ECHOCLEAR 0x80 488 /* Timestamp formats */ 489 #define PPS_TSFMT_TSPEC 0x1000 490 #define PPS_TSFMT_NTPFP 0x2000 492 These mode bits are divided into three categories: 494 1. Device/implementation parameters: These are parameters 495 either of the device or of the implementation. If the 496 implementation allows these to be changed, then these bits 497 are read/write for users with sufficient privilege (such 498 as the super-user), and read-only for other users. If the 499 implementation does not allow these bits to be changed, 500 they are read-only. 502 2. Kernel actions: These bits specify certain kernel actions 503 to be taken on arrival of a signal. If the implementation 504 supports one of these actions, then the corresponding bit 505 is read/write for users with sufficient privilege (such as 506 the super-user), and read-only for other users. If the 507 implementation does not support the action, the 508 corresponding bit is always zero. 510 3. Timestamp formats: These bits indicate the set of 511 timestamp formats available for the device. They are 512 always read-only. 514 In more detail, the meanings of the Device/implementation parameter 515 mode bits are: 517 PPS_CAPTUREASSERT 518 If this bit is set, the assert timestamp for the 519 associated PPS source will be captured. 521 PPS_CAPTURECLEAR 522 If this bit is set, the clear timestamp for the 523 associated PPS source will be captured. 525 PPS_CAPTUREBOTH Defined as the union of PPS_CAPTUREASSERT and 526 PPS_CAPTURECLEAR, for convenience. 528 PPS_OFFSETASSERT 529 If set, the assert_offset value is added to the 530 current value of the operating system's internal 531 timebase in order to generate the captured 532 assert_timestamp. 534 Internet-Draft Pulse-Per-Second API 23 July 1999 16:36 536 PPS_OFFSETCLEAR If set, the clear_offset value is added to the 537 current value of the operating system's internal 538 timebase in order to generate the captured 539 clear_timestamp. 541 PPS_CANWAIT If set, the application may request that the 542 time_pps_fetch() function (see section 3.4.3) should 543 block until the next timestamp arrives. Note: this 544 mode bit is read-only. 546 PPS_CANPOLL This bit is reserved for future use. An application 547 SHOULD NOT depend on any functionality implied either 548 by its presence or by its absence. 550 If neither PPS_CAPTUREASSERT nor PPS_CAPTURECLEAR is set, no valid 551 timestamp will be available via the API. 553 The meanings of the Kernel action mode bits are: 555 PPS_ECHOASSERT If set, after the capture of an assert timestamp, 556 the implementation generates a signal transition as 557 rapidly as possible on an output signal pin. This 558 MUST NOT affect the delay between the PPS source's 559 transition to the asserted phase and the capture of 560 the assert timestamp. 562 PPS_ECHOCLEAR If set, after the capture of a clear timestamp, the 563 implementation generates a signal transition as 564 rapidly as possible on an output signal pin. This 565 MUST NOT affect the delay between the PPS source's 566 transition to the clear phase and the capture of the 567 clear timestamp. 569 The timestamp formats are: 571 PPS_TSFMT_TSPEC Timestamps and offsets are represented as values of 572 type ``struct timespec''. All implementations MUST 573 support this format, and this format is the default 574 unless an application specifies otherwise. 576 PPS_TSFMT_NTPFP Timestamps and offsets are represented as values of 577 type ``ntp_fp_t'', which corresponds to the NTP 578 ``64-bit unsigned fixed-point'' timestamp format [3]. 579 Support for this format is OPTIONAL. 581 Other timestamp format bits may be defined as fields are added to the 582 ``pps_timeu_t'' union. 584 The operating system may implement all of these mode bits, or just a 585 subset of them. If an attempt is made to set an unsupported mode 586 bit, the API will return an error. If an attempt is made to modify a 587 read-only mode bit, the API will return an error. 589 Internet-Draft Pulse-Per-Second API 23 July 1999 16:36 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 Internet-Draft Pulse-Per-Second API 23 July 1999 16:36 612 3.4.1 New functions: obtaining PPS sources 613 The API includes a function to create and destroy PPS source 614 ``handles''. 616 SYNOPSIS 618 int time_pps_create(int filedes, pps_handle_t *handle); 619 int time_pps_destroy(pps_handle_t handle); 621 DESCRIPTION 623 All of the other functions in the PPS API operate on PPS handles 624 (type: pps_handle_t). The time_pps_create() is used to convert an 625 already-open UNIX file descriptor, for an appropriate special file, 626 into a PPS handle. 628 The definition of what special files are appropriate for use with the 629 PPS API is outside the scope of this specification, and may vary 630 based on both operating system implementation, and local system 631 configuration. One typical case is a serial line, whose DCD pin is 632 connected to a source of PPS events. 634 The mode in which the UNIX file descriptor was originally opened 635 affects what operations are allowed on the PPS handle. The 636 time_pps_setparams() and time_pps_kcbind() functions (see sections 637 3.4.2 and 3.4.4) SHOULD be prohibited by the implementation if the 638 descriptor is open only for reading (O_RDONLY). 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 Internet-Draft Pulse-Per-Second API 23 July 1999 16:36 659 RETURN VALUES 661 On successful completion, the time_pps_create() function returns 0. 662 Otherwise, a value of -1 is returned and errno is set to indicate the 663 error. 665 If called with a valid handle parameter, the time_pps_destroy() 666 function returns 0. Otherwise, it returns -1. 668 ERRORS 670 If the time_pps_create() function fails, errno may be set to one of 671 the following values: 673 [EBADF] The filedes parameter is not a valid file descriptor. 675 [EOPNOTSUPP] The use of the PPS API is not supported for the file 676 descriptor. 678 [EPERM] The process's effective user ID does not have the 679 required privileges to use the PPS API. 681 Internet-Draft Pulse-Per-Second API 23 July 1999 16:36 683 3.4.2 New functions: setting PPS parameters 684 The API includes several functions use to set or obtain the 685 parameters of a PPS source. 687 SYNOPSIS 689 int time_pps_setparams(pps_handle_t handle, 690 const pps_params_t *ppsparams); 691 int time_pps_getparams(pps_handle_t handle, 692 pps_params_t *ppsparams); 693 int time_pps_getcap(pps_handle_t handle, int *mode); 695 DESCRIPTION 697 A suitably privileged application may use time_pps_setparams() to set 698 the parameters (mode bits and timestamp offsets) for a PPS source. 699 The pps_params_t type is defined in section 3.2; mode bits are 700 defined in section 3.3. An application may use time_pps_getparams() 701 to discover the current settings of the PPS parameters. An 702 application that needs to change only a subset of the existing 703 parameters must first call time_pps_getparams() to obtain the current 704 parameter values, then set the new values using time_pps_setparams(). 706 --------- 707 Note: a call to time_pps_setparams() replaces the current 708 values of all mode bits with those specified via the ppsparams 709 argument, except those bits whose state cannot be changed. 710 Bits might be read-only due to access controls, or because they 711 are fixed by the implementation. 712 --------- 714 The timestamp format of the assert_offset and clear_offset fields is 715 defined by the mode field. That is, on a call to 716 time_pps_setparams(), the kernel interprets the supplied offset 717 values using the timestamp format given in the mode field of the 718 ppsparams argument. If the requested timestamp format is not 719 supported, the time_pps_setparams() function has no effect and 720 returns an error value. On a call to time_pps_getparams(), the 721 kernel provides the timestamp format of the offsets by setting one of 722 the timestamp format bits in the mode field. 724 --------- 725 Note: an application that uses time_pps_getparams() to read the 726 current offset values cannot specify which format is used. The 727 implementation SHOULD return the offsets using the same 728 timestamp format as was used when the offsets were set. 729 --------- 731 Internet-Draft Pulse-Per-Second API 23 July 1999 16:36 733 An application wishing to discover which mode bits it may set, with 734 its current effective user ID, may call time_pps_getcap(). This 735 function returns the set of mode bits that may be set by the 736 application, without generating an EINVAL or EPERM error, for the 737 specified PPS source. It does not return the current values for the 738 mode bits. A call to time_pps_getcap() returns the mode bits 739 corresponding to all supported timestamp formats. 741 The time_pps_getcap() function MAY ignore the mode in which the 742 associated UNIX file descriptor was opened, so the application might 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 Internet-Draft Pulse-Per-Second API 23 July 1999 16:36 781 3.4.3 New functions: access to PPS timestamps 782 The API includes one function that gives applications access to PPS 783 timestamps. As an implementation option, the application may request 784 the API to block until the next timestamp is captured. (The API does 785 not directly support the use of the select() or poll() system calls 786 to wait for PPS events.) 788 SYNOPSIS 790 int time_pps_fetch(pps_handle_t handle, 791 const int tsformat, 792 pps_info_t *ppsinfobuf, 793 const struct timespec *timeout); 795 DESCRIPTION 797 An application may use time_pps_fetch() to obtain the most recent 798 timestamps captured for the PPS source specified by the handle 799 parameter. The tsformat parameter specifies the desired timestamp 800 format; if the requested timestamp format is not supported, the call 801 fails and returns an error value. 803 This function blocks until either a timestamp is captured from the 804 PPS source, or until the specified timeout duration has expired. If 805 the timeout parameter is a NULL pointer, the function simply blocks 806 until a timestamp is captured. If the timeout parameter specifies a 807 delay of zero, the function returns immediately. 809 Support for blocking behavior is an implementation option. If the 810 PPS_CANWAIT mode bit is clear, and the timeout parameter is either 811 NULL or points to a non-zero value, the function returns an 812 EOPNOTSUPP error. An application can determine whether the feature 813 is implemented by using time_pps_getcap() to see if the PPS_CANWAIT 814 mode bit is set. 816 The result is stored in the ppsinfobuf parameter, whose fields are 817 defined in section 3.2. If the function returns as the result of a 818 timeout or error, the contents of the ppsinfobuf are undefined. 820 If this function is invoked before the system has captured a 821 timestamp for the signal source, the ppsinfobuf returned will have 822 its timestamp fields set to the time format's base date (e.g., for 823 PPS_TSFMT_TSPEC, both the tv_sec and tv_nsec fields will be zero). 825 Internet-Draft Pulse-Per-Second API 23 July 1999 16:36 827 RETURN VALUES 829 On successful completion, the time_pps_fetch() function returns 0. 830 Otherwise, a value of -1 is returned and errno is set to indicate the 831 error. 833 ERRORS 835 If the time_pps_fetch() function fails, errno may be set to one of 836 the following values: 838 [EBADF] The handle parameter is not associated with a valid 839 file descriptor. 841 [EFAULT] A parameter points to an invalid address. 843 [EINTR] A signal was delivered before the time limit 844 specified by the timeout parameter expired and before 845 a timestamp has been captured. 847 [EINVAL] The requested timestamp format is not supported. 849 [EOPNOTSUPP] The use of the PPS API is not supported for the 850 associated file descriptor. 852 [ETIMEDOUT] The timeout duration has expired. 854 Internet-Draft Pulse-Per-Second API 23 July 1999 16:36 856 3.4.4 New functions: disciplining the kernel timebase 857 The API includes one OPTIONAL function to specify if and how a PPS 858 source is provided to a kernel consumer of PPS events, such as the 859 code used to discipline the operating system's internal timebase. 861 SYNOPSIS 863 int time_pps_kcbind(pps_handle_t handle, 864 const int kernel_consumer, 865 const int edge, 866 const int tsformat); 868 DESCRIPTION 870 An application with appropriate privileges may use time_pps_kcbind() 871 to bind a kernel consumer to the PPS source specified by the handle. 873 The kernel consumer is identified by the kernel_consumer parameter. 874 In the current version of the API, the possible values for this 875 parameter are: 877 #define PPS_KC_HARDPPS 0 878 #define PPS_KC_HARDPPS_PLL 1 879 #define PPS_KC_HARDPPS_FLL 2 881 with these meanings: 883 PPS_KC_HARDPPS The kernel's hardpps() function (or equivalent). 885 PPS_KC_HARDPPS_PLL 886 A variant of hardpps() constrained to use a 887 phase-locked loop. 889 PPS_KC_HARDPPS_FLL 890 A variant of hardpps() constrained to use a 891 frequency-locked loop. 893 Support for any or all of these values is OPTIONAL. 895 The edge parameter indicates which edge of the PPS signal causes a 896 timestamp to be delivered to the kernel consumer. It may have the 897 value PPS_CAPTUREASSERT, PPS_CAPTURECLEAR, or PPS_CAPTUREBOTH, 898 depending on particular characteristics of the PPS source. It may 899 also be zero, which removes any binding between the PPS source and 900 the kernel consumer. 902 The tsformat parameter specifies the format for the timestamps 903 delivered to the kernel consumer. If this value is zero, the 904 implementation MAY choose the appropriate format, or return EINVAL. 905 The implementation MAY ignore a non-zero value for this parameter. 907 Internet-Draft Pulse-Per-Second API 23 July 1999 16:36 909 The binding created by this call persists until it is changed by a 910 subsequent call specifying the same kernel_consumer. In particular, 911 a subsequent call to time_pps_destroy() for the specified handle does 912 not affect the binding. 914 The binding is independent of any prior or subsequent changes to the 915 PPS_CAPTUREASSERT and PPS_CAPTURECLEAR mode bits for the device. 916 However, if either the edge or the tsformat parameter values are 917 inconsistent with the capabilities of the PPS source, an error is 918 returned. The implementation MAY also return an error if the 919 tsformat value is unsupported for time_pps_kcbind(), even if it is 920 supported for other uses of the API. 922 The operating system may enforce two restrictions on the bindings 923 created by time_pps_kcbind(): 925 1. the kernel MAY return an error if an attempt is made to 926 bind a kernel consumer to more than one PPS source a time. 928 2. the kernel MAY restrict the ability to set bindings to 929 processes with sufficient privileges to modify the 930 system's internal timebase. (On UNIX systems, such 931 modification is normally done using settimeofday() and/or 932 adjtime(), and is restricted to users with superuser 933 privilege.) 935 --------- 936 Warning: If this feature is configured for a PPS source that 937 does not have an accurate 1-pulse-per-second signal, or is 938 otherwise inappropriately configured, use of this feature may 939 result in seriously incorrect timekeeping for the entire 940 system. For best results, the 1-PPS signal should have much 941 better frequency stability than the system's internal clock 942 source (usually a crystal-controlled oscillator), and should 943 have jitter (variation in interarrival time) much less than the 944 system's clock-tick interval. 945 --------- 947 See RFC1589 [4] for more information about how the system's timebase 948 may be disciplined using a PPS signal. 950 RETURN VALUES 952 On successful completion, the time_pps_kcbind() function returns 0. 953 Otherwise, a value of -1 is returned and errno is set to indicate the 954 error. 956 Internet-Draft Pulse-Per-Second API 23 July 1999 16:36 958 ERRORS 960 If the time_pps_kcbind() function fails, errno may be set to one of 961 the following values: 963 [EBADF] The handle parameter is not associated with a valid 964 file descriptor, or the descriptor is not open for 965 writing. 967 [EFAULT] A parameter points to an invalid address. 969 [EINVAL] The requested timestamp format is not supported. 971 [EOPNOTSUPP] The use of the PPS API is not supported for the 972 associated file descriptor, or this OPTIONAL function 973 is not supported. 975 [EPERM] The process's effective user ID does not have the 976 required privileges to set the binding. 978 Internet-Draft Pulse-Per-Second API 23 July 1999 16:36 980 3.5 Compliance rules 981 The key words "MUST", "MUST NOT", "REQUIRED","SHOULD", SHOULD NOT", 982 "MAY", and "OPTIONAL" in this document are to be interpreted as 983 described in RFC2119 [1]. 985 Some features of this specification are OPTIONAL, but others are 986 REQUIRED. 988 3.5.1 Functions 989 An implementation MUST provide these functions: 990 - time_pps_create() 991 - time_pps_destroy() 992 - time_pps_setparams() 993 - time_pps_getparams() 994 - time_pps_getcap() 995 - time_pps_fetch() 997 An implementation MUST provide this function, but it may be 998 implemented as a function that always return an EOPNOTSUPP error, 999 possibly on a per-source basis: 1000 - time_pps_kcbind() 1002 3.5.2 Mode bits 1003 An implementation MUST support at least one of these mode bits for 1004 each PPS source: 1005 - PPS_CAPTUREASSERT 1006 - PPS_CAPTURECLEAR 1007 and MAY support both of them. If an implementation supports both of 1008 these bits for a PPS source, it SHOULD allow them to be set 1009 simultaneously. 1011 An implementation MUST support this timestamp format: 1012 - PPS_TSFMT_TSPEC 1014 An implementation MAY support these mode bits: 1015 - PPS_ECHOASSERT 1016 - PPS_ECHOCLEAR 1017 - PPS_OFFSETASSERT 1018 - PPS_OFFSETCLEAR 1020 An implementation MAY support this timestamp format: 1021 - PPS_TSFMT_NTPFP 1023 Internet-Draft Pulse-Per-Second API 23 July 1999 16:36 1025 3.6 Examples 1026 A very simple use of this API might be: 1028 int fd; 1029 pps_handle_t handle; 1030 pps_params_t params; 1031 pps_info_t infobuf; 1032 struct timespec timeout; 1034 /* Open a file descriptor and enable PPS on rising edges */ 1035 fd = open(PPSfilename, O_RDWR, 0); 1036 time_pps_create(fd, &handle); 1037 time_pps_getparams(handle, ¶ms); 1038 if ((params.mode & PPS_CAPTUREASSERT) == 0) { 1039 fprintf(stderr, "%s cannot currently CAPTUREASSERT\n", 1040 PPSfilename); 1041 exit(1); 1042 } 1044 /* create a zero-valued timeout */ 1045 timeout.tv_sec = 0; 1046 timeout.tv_nsec = 0; 1048 /* loop, printing the most recent timestamp every second or so */ 1049 while (1) { 1050 sleep(1); 1051 time_pps_fetch(handle, PPS_TSFMT_TSPEC, &infobuf, &timeout); 1052 printf("Assert timestamp: %d.%09d, sequence: %ld\n", 1053 infobuf.assert_timestamp.tv_sec, 1054 infobuf.assert_timestamp.tv_nsec, 1055 infobuf.assert_sequence); 1056 } 1058 Note that this example omits most of the error-checking that would be 1059 expected in a reliable program. 1061 Also note that, on a system that supports PPS_CANWAIT, the function 1062 of these lines: 1064 sleep(1); 1065 time_pps_fetch(handle, PPS_TSFMT_TSPEC, &infobuf, &timeout); 1067 might be more reliably accomplished using: 1069 timeout.tv_sec = 100; 1070 timeout.tv_nsec = 0; 1071 time_pps_fetch(handle, PPS_TSFMT_TSPEC, &infobuf, &timeout); 1073 The (arbitrary) timeout value is used to protect against the 1074 possibility that another application might disable PPS timestamps, or 1075 that the hardware generating the timestamps might fail. 1077 Internet-Draft Pulse-Per-Second API 23 July 1999 16:36 1079 A slightly more elaborate use of this API might be: 1081 int fd; 1082 pps_handle_t handle; 1083 pps_params_t params; 1084 pps_info_t infobuf; 1085 int avail_mode; 1086 struct timespec timeout; 1088 /* Open a file descriptor */ 1089 fd = open(PPSfilename, O_RDWR, 0); 1090 time_pps_create(fd, &handle); 1092 /* 1093 * Find out what features are supported 1094 */ 1095 time_pps_getcap(handle, &avail_mode); 1096 if ((avail_mode & PPS_CAPTUREASSERT) == 0) { 1097 fprintf(stderr, "%s cannot CAPTUREASSERT\n", PPSfilename); 1098 exit(1); 1099 } 1100 if ((avail_mode & PPS_OFFSETASSERT) == 0) { 1101 fprintf(stderr, "%s cannot OFFSETASSERT\n", PPSfilename); 1102 exit(1); 1103 } 1105 /* 1106 * Capture assert timestamps, and 1107 * compensate for a 675 nsec propagation delay 1108 */ 1110 time_pps_getparams(handle, ¶ms); 1111 params.assert_offset.tv_sec = 0; 1112 params.assert_offset.tv_nsec = 675; 1113 params.mode |= PPS_CAPTUREASSERT | PPS_OFFSETASSERT; 1114 time_pps_setparams(handle, ¶ms); 1116 /* create a zero-valued timeout */ 1117 timeout.tv_sec = 0; 1118 timeout.tv_nsec = 0; 1120 /* loop, printing the most recent timestamp every second or so */ 1121 while (1) { 1122 if (avail_mode & PPS_CANWAIT) { 1123 time_pps_fetch(handle, PPS_TSFMT_TSPEC, &infobuf, NULL); 1124 /* waits for the next event */ 1125 } else { 1126 sleep(1); 1127 time_pps_fetch(handle, PPS_TSFMT_TSPEC, &infobuf, 1128 timeout); 1130 Internet-Draft Pulse-Per-Second API 23 July 1999 16:36 1132 } 1133 printf("Assert timestamp: %d.%09d, sequence: %ld\n", 1134 infobuf.assert_timestamp.tv_sec, 1135 infobuf.assert_timestamp.tv_nsec, 1136 infobuf.assert_sequence); 1137 } 1139 Again, most of the necessary error-checking has been omitted from 1140 this example. 1142 4 Security Considerations 1144 This API gives applications three capabilities: 1146 - Causing the system to capture timestamps on certain events. 1148 - Obtaining timestamps for certain events. 1150 - Affecting the system's internal timebase. 1152 The first capability should not affect security directly, but might 1153 cause a slight increase in interrupt latency and interrupt-handling 1154 overhead. 1156 The second capability might be useful in implementing certain kinds 1157 of covert communication channels. 1159 In most cases, neither of these first two issues is a significant 1160 security threat, because the traditional UNIX file protection 1161 facility may be used to to limit access to the relevant special 1162 files. Provision of the PPS API adds minimal additional risk. 1164 The final capability is reserved to highly privileged users. In UNIX 1165 systems, this means those with superuser privilege. Such users can 1166 evade protections based on file permissions; however, such users can 1167 in general cause unbounded havoc, and can set the internal timebase 1168 (and its rate of change), so this API creates no new vulnerabilities. 1170 5 Acknowledgements 1172 The API in this document draws some of its inspiration from the LBL 1173 ``ppsclock'' distribution [2], originally implemented in 1993 by 1174 Steve McCanne, Craig Leres, and Van Jacobson. We also thank Craig 1175 Leres, Judah Levine, and Harlan Stenn for helpful comments they 1176 contributed during the drafting of this document. 1178 Internet-Draft Pulse-Per-Second API 23 July 1999 16:36 1180 6 References 1182 1. Scott Bradner. Key words for use in RFCs to Indicate Requirement 1183 Levels. RFC 2119, Harvard University, March, 1997. 1185 2. Steve McCanne, Craig Leres, and Van Jacobson. PPSCLOCK. 1186 ftp://ftp.ee.lbl.gov/ppsclock.tar.Z. 1188 3. David L. Mills. Network Time Protocol (Version 3): 1189 Specification, Implementation and Analysis. RFC 1305, IETF, March, 1190 1992. 1192 4. David L. Mills. A Kernel Model for Precision Timekeeping. RFC 1193 1589, IETF, March, 1994. 1195 5. The Open Group. The Single UNIX Specification, Version 2 - 6 Vol 1196 Set for UNIX 98. Document number T912, The Open Group, February, 1197 1997. 1199 7 Authors' addresses 1201 Jeffrey C. Mogul 1202 Western Research Laboratory 1203 Compaq Computer Corporation 1204 250 University Avenue 1205 Palo Alto, California, 94305, U.S.A. 1206 Email: mogul@wrl.dec.com 1207 Phone: 1 650 617 3304 (email preferred) 1209 David L. Mills 1210 Electrical and Computer Engineering Department 1211 University of Delaware 1212 Newark, DE 19716 1213 Phone: (302) 831-8247 1214 EMail: mills@udel.edu 1216 Jan Brittenson 1217 Sun Microsystems, Inc. 1218 901 San Antonio Rd M/S MPK17-202 1219 Palo Alto, CA 94303 1220 Email: Jan.Brittenson@Eng.Sun.COM 1222 Jonathan Stone 1223 Stanford Distributed Systems Group 1224 Stanford, CA 94305 1225 Phone: (650) 723-2513 1226 Email: jonathan@dsg.stanford.edu 1228 Poul-Henning Kamp 1229 The FreeBSD Project 1231 Internet-Draft Pulse-Per-Second API 23 July 1999 16:36 1233 Valbygaardsvej 8 1234 DK-4200 Slagelse 1235 Denmark 1236 Phone: +45 58 56 10 59 1237 Email: phk@FreeBSD.org 1239 Ulrich Windl 1240 Universitaet Regensburg, Klinikum 1241 Email: ulrich.windl@rz.uni-regensburg.de 1243 A. Extensions and related APIs 1245 The API specified in the main body of this document could be more 1246 useful with the provision of several extensions or companion APIs. 1248 At present, the interfaces listed in this appendix are not part of 1249 the formal specification in this document. 1251 A.1 Extension: Parameters for the ``echo'' mechanism 1253 The ``echo'' mechanism described in the body of this specification 1254 leaves most of the details to the implementor, especially the 1255 designation of one or more output pins. 1257 It might be useful to extend this API to provide either or both of 1258 these features: 1260 - A means by which the application can discover which output 1261 pin is echoing the input pin. 1263 - A means by which the application can select which output 1264 pin is echoing the input pin. 1266 A.2 Extension: Obtaining information about external clocks 1268 The PPS API may be useful with a wide variety of reference clocks, 1269 connected via several different interface technologies (including 1270 serial lines, parallel interfaces, and bus-level interfaces). These 1271 reference clocks can have many features and parameters, some of which 1272 might not even have been invented yet. 1274 We believe that it would be useful to have a mechanism by which an 1275 application can discover arbitrary features and parameters of a 1276 reference clock. These might include: 1277 - Clock manufacturer, model number, and revision level 1278 - Whether the clock is synchronized to an absolute standard 1279 - For synchronized clocks, 1281 Internet-Draft Pulse-Per-Second API 23 July 1999 16:36 1283 * The specific standard 1284 * The accuracy of the standard 1285 * The path used (direct connection, shortwave, longwave, 1286 satellite, etc.) 1287 * The distance (offset) and variability of this path 1289 - For PPS sources, 1290 * The pulse rate 1291 * The pulse shape 1292 * Which edge of the pulse corresponds to the epoch 1294 - The time representation format 1296 This information might best be provided by an API analogous to the 1297 standard ``curses'' API, with a database analogous to the standard 1298 ``terminfo'' database. That is, a ``clockinfo'' database would 1299 contain a set of (attribute, value) pairs for each type of clock, and 1300 the API would provide a means to query this database. 1302 Additional mechanisms would allow an application to discover the 1303 clock or clocks connected to the local system, and to discover the 1304 clockinfo type of a specific clock device. 1306 A.3 Extension: Finding a PPS source 1308 Although the clockinfo database described in section A.2, together 1309 with the discover mechanisms described there, would allow an 1310 application to discover the PPS source (or sources) connected to a 1311 system, it might be more complex than necessary. 1313 A simpler approach would be to support a single function that 1314 provides the identity of one or more PPS sources. 1316 For example, the function might be declared as 1318 int time_pps_findsource(int index, 1319 char *path, int pathlen, 1320 char *idstring, int idlen); 1322 The index argument implicitly sets up an ordering on the PPS sources 1323 attached to the system. An application would use this function to 1324 inquire about the Nth source. The function would return -1 if no 1325 such source exists; otherwise, it would return 0, and would place the 1326 pathname of the associated special file in the path argument. It 1327 would also place an identification string in the idstring argument. 1328 The identification string could include the clock make, model, 1329 version, etc., which could then be used by the application to control 1330 its behavior. 1332 Internet-Draft Pulse-Per-Second API 23 July 1999 16:36 1334 This function might simply read the Nth line from a simple database, 1335 containing lines such as: 1337 /dev/tty00 "TrueTime 468-DC" 1338 /dev/pps1 "Homebrew rubidium frequency standard" 1340 allowing the system administrator to describe the configuration of 1341 PPS sources. 1343 B. Example implementation: PPSDISC Line discipline 1345 One possible implementation of the PPS API might be to define a new 1346 ``line discipline'' and then map the API onto a set of ioctl() 1347 commands. Here we sketch such an implementation; note that this is 1348 not part of the specification of the API, and applications should not 1349 expect this low-level interface to be available. 1351 In this approach, the set of line disciplines is augmented with one 1352 new line discipline, PPSDISC. This discipline will act exactly the 1353 same as the TTYDISC discipline, except for its handling of modem DCD 1354 interrupts. 1356 Once the TIOCSETD ioctl() has been used to select this line 1357 discipline, PPS-related operations on the serial line may be invoked 1358 using new ioctl() commands. For example (values used only for 1359 illustration): 1361 #define PPSFETCH _IOR('t', 75, pps_info_t) 1362 #define PPSSETPARAM _IOW('t', 76, pps_params_t) 1363 #define PPSGETPARAM _IOR('t', 77, pps_params_t) 1364 #define PPSGETCAP _IOR('t', 78, int) 1366 B.1 Example 1368 A typical use might be: 1370 int ldisc = PPSDISC; 1371 pps_params_t params; 1372 pps_info_t infobuf; 1374 ioctl(fd, TIOCSETD, &ldisc); /* set discipline */ 1376 /* 1377 * Check the capabilities of this PPS source to see 1378 * if it supports what we need. 1379 */ 1380 ioctl(fd, PPSGETCAP, ¶ms); 1381 if ((params.mode & PPS_CAPTUREASSERT) == 0) { 1383 Internet-Draft Pulse-Per-Second API 23 July 1999 16:36 1385 fprintf(stderr, "PPS source is not suitable\n"); 1386 exit(1); 1387 } 1389 /* 1390 * Set this line to timestamp on a rising-edge interrupt 1391 */ 1392 ioctl(fd, PPSGETPARAMS, ¶ms); 1393 params.mode |= PPS_CAPTUREASSERT; 1394 ioctl(fd, PPSSETPARAMS, ¶ms); 1396 sleep(2); /* allow time for the PPS pulse to happen */ 1398 /* obtain most recent timestamp and sequence # for this line */ 1399 ioctl(fd, PPSFETCH, &infobuf); 1401 Again, this example imprudently omits any error-checking. 1403 C. Available implementations 1405 Several available implementations of this API are listed at 1406 .