1 /* $NetBSD: ntp_refclock.c,v 1.5 2013/12/28 03:20:14 christos Exp $ */ 2 3 /* 4 * ntp_refclock - processing support for reference clocks 5 */ 6 #ifdef HAVE_CONFIG_H 7 # include <config.h> 8 #endif 9 10 #include "ntpd.h" 11 #include "ntp_io.h" 12 #include "ntp_unixtime.h" 13 #include "ntp_tty.h" 14 #include "ntp_refclock.h" 15 #include "ntp_stdlib.h" 16 #include "ntp_assert.h" 17 18 #include <stdio.h> 19 20 #ifdef HAVE_SYS_IOCTL_H 21 # include <sys/ioctl.h> 22 #endif /* HAVE_SYS_IOCTL_H */ 23 24 #ifdef REFCLOCK 25 26 #ifdef KERNEL_PLL 27 #include "ntp_syscall.h" 28 #endif /* KERNEL_PLL */ 29 30 #ifdef HAVE_PPSAPI 31 #include "ppsapi_timepps.h" 32 #include "refclock_atom.h" 33 #endif /* HAVE_PPSAPI */ 34 35 /* 36 * Reference clock support is provided here by maintaining the fiction 37 * that the clock is actually a peer. As no packets are exchanged with 38 * a reference clock, however, we replace the transmit, receive and 39 * packet procedures with separate code to simulate them. Routines 40 * refclock_transmit() and refclock_receive() maintain the peer 41 * variables in a state analogous to an actual peer and pass reference 42 * clock data on through the filters. Routines refclock_peer() and 43 * refclock_unpeer() are called to initialize and terminate reference 44 * clock associations. A set of utility routines is included to open 45 * serial devices, process sample data, and to perform various debugging 46 * functions. 47 * 48 * The main interface used by these routines is the refclockproc 49 * structure, which contains for most drivers the decimal equivalants 50 * of the year, day, month, hour, second and millisecond/microsecond 51 * decoded from the ASCII timecode. Additional information includes 52 * the receive timestamp, exception report, statistics tallies, etc. 53 * In addition, there may be a driver-specific unit structure used for 54 * local control of the device. 55 * 56 * The support routines are passed a pointer to the peer structure, 57 * which is used for all peer-specific processing and contains a 58 * pointer to the refclockproc structure, which in turn contains a 59 * pointer to the unit structure, if used. The peer structure is 60 * identified by an interface address in the dotted quad form 61 * 127.127.t.u, where t is the clock type and u the unit. 62 */ 63 #define FUDGEFAC .1 /* fudge correction factor */ 64 #define LF 0x0a /* ASCII LF */ 65 66 int cal_enable; /* enable refclock calibrate */ 67 68 /* 69 * Forward declarations 70 */ 71 static int refclock_cmpl_fp (const void *, const void *); 72 static int refclock_sample (struct refclockproc *); 73 static int refclock_ioctl(int, u_int); 74 75 76 /* 77 * refclock_report - note the occurance of an event 78 * 79 * This routine presently just remembers the report and logs it, but 80 * does nothing heroic for the trap handler. It tries to be a good 81 * citizen and bothers the system log only if things change. 82 */ 83 void 84 refclock_report( 85 struct peer *peer, 86 int code 87 ) 88 { 89 struct refclockproc *pp; 90 91 pp = peer->procptr; 92 if (pp == NULL) 93 return; 94 95 switch (code) { 96 97 case CEVNT_TIMEOUT: 98 pp->noreply++; 99 break; 100 101 case CEVNT_BADREPLY: 102 pp->badformat++; 103 break; 104 105 case CEVNT_FAULT: 106 break; 107 108 case CEVNT_BADDATE: 109 case CEVNT_BADTIME: 110 pp->baddata++; 111 break; 112 113 default: 114 /* ignore others */ 115 break; 116 } 117 if (pp->lastevent < 15) 118 pp->lastevent++; 119 if (pp->currentstatus != code) { 120 pp->currentstatus = (u_char)code; 121 report_event(PEVNT_CLOCK, peer, ceventstr(code)); 122 } 123 } 124 125 126 /* 127 * init_refclock - initialize the reference clock drivers 128 * 129 * This routine calls each of the drivers in turn to initialize internal 130 * variables, if necessary. Most drivers have nothing to say at this 131 * point. 132 */ 133 void 134 init_refclock(void) 135 { 136 int i; 137 138 for (i = 0; i < (int)num_refclock_conf; i++) 139 if (refclock_conf[i]->clock_init != noentry) 140 (refclock_conf[i]->clock_init)(); 141 } 142 143 144 /* 145 * refclock_newpeer - initialize and start a reference clock 146 * 147 * This routine allocates and initializes the interface structure which 148 * supports a reference clock in the form of an ordinary NTP peer. A 149 * driver-specific support routine completes the initialization, if 150 * used. Default peer variables which identify the clock and establish 151 * its reference ID and stratum are set here. It returns one if success 152 * and zero if the clock address is invalid or already running, 153 * insufficient resources are available or the driver declares a bum 154 * rap. 155 */ 156 int 157 refclock_newpeer( 158 struct peer *peer /* peer structure pointer */ 159 ) 160 { 161 struct refclockproc *pp; 162 u_char clktype; 163 int unit; 164 165 /* 166 * Check for valid clock address. If already running, shut it 167 * down first. 168 */ 169 if (!ISREFCLOCKADR(&peer->srcadr)) { 170 msyslog(LOG_ERR, 171 "refclock_newpeer: clock address %s invalid", 172 stoa(&peer->srcadr)); 173 return (0); 174 } 175 clktype = (u_char)REFCLOCKTYPE(&peer->srcadr); 176 unit = REFCLOCKUNIT(&peer->srcadr); 177 if (clktype >= num_refclock_conf || 178 refclock_conf[clktype]->clock_start == noentry) { 179 msyslog(LOG_ERR, 180 "refclock_newpeer: clock type %d invalid\n", 181 clktype); 182 return (0); 183 } 184 185 /* 186 * Allocate and initialize interface structure 187 */ 188 pp = emalloc_zero(sizeof(*pp)); 189 peer->procptr = pp; 190 191 /* 192 * Initialize structures 193 */ 194 peer->refclktype = clktype; 195 peer->refclkunit = (u_char)unit; 196 peer->flags |= FLAG_REFCLOCK; 197 peer->leap = LEAP_NOTINSYNC; 198 peer->stratum = STRATUM_REFCLOCK; 199 peer->ppoll = peer->maxpoll; 200 pp->type = clktype; 201 pp->conf = refclock_conf[clktype]; 202 pp->timestarted = current_time; 203 pp->io.fd = -1; 204 205 /* 206 * Set peer.pmode based on the hmode. For appearances only. 207 */ 208 switch (peer->hmode) { 209 case MODE_ACTIVE: 210 peer->pmode = MODE_PASSIVE; 211 break; 212 213 default: 214 peer->pmode = MODE_SERVER; 215 break; 216 } 217 218 /* 219 * Do driver dependent initialization. The above defaults 220 * can be wiggled, then finish up for consistency. 221 */ 222 if (!((refclock_conf[clktype]->clock_start)(unit, peer))) { 223 refclock_unpeer(peer); 224 return (0); 225 } 226 peer->refid = pp->refid; 227 return (1); 228 } 229 230 231 /* 232 * refclock_unpeer - shut down a clock 233 */ 234 void 235 refclock_unpeer( 236 struct peer *peer /* peer structure pointer */ 237 ) 238 { 239 u_char clktype; 240 int unit; 241 242 /* 243 * Wiggle the driver to release its resources, then give back 244 * the interface structure. 245 */ 246 if (NULL == peer->procptr) 247 return; 248 249 clktype = peer->refclktype; 250 unit = peer->refclkunit; 251 if (refclock_conf[clktype]->clock_shutdown != noentry) 252 (refclock_conf[clktype]->clock_shutdown)(unit, peer); 253 free(peer->procptr); 254 peer->procptr = NULL; 255 } 256 257 258 /* 259 * refclock_timer - called once per second for housekeeping. 260 */ 261 void 262 refclock_timer( 263 struct peer *p 264 ) 265 { 266 struct refclockproc * pp; 267 int unit; 268 269 unit = p->refclkunit; 270 pp = p->procptr; 271 if (pp->conf->clock_timer != noentry) 272 (*pp->conf->clock_timer)(unit, p); 273 if (pp->action != NULL && pp->nextaction <= current_time) 274 (*pp->action)(p); 275 } 276 277 278 /* 279 * refclock_transmit - simulate the transmit procedure 280 * 281 * This routine implements the NTP transmit procedure for a reference 282 * clock. This provides a mechanism to call the driver at the NTP poll 283 * interval, as well as provides a reachability mechanism to detect a 284 * broken radio or other madness. 285 */ 286 void 287 refclock_transmit( 288 struct peer *peer /* peer structure pointer */ 289 ) 290 { 291 u_char clktype; 292 int unit; 293 294 clktype = peer->refclktype; 295 unit = peer->refclkunit; 296 peer->sent++; 297 get_systime(&peer->xmt); 298 299 /* 300 * This is a ripoff of the peer transmit routine, but 301 * specialized for reference clocks. We do a little less 302 * protocol here and call the driver-specific transmit routine. 303 */ 304 if (peer->burst == 0) { 305 u_char oreach; 306 #ifdef DEBUG 307 if (debug) 308 printf("refclock_transmit: at %ld %s\n", 309 current_time, stoa(&(peer->srcadr))); 310 #endif 311 312 /* 313 * Update reachability and poll variables like the 314 * network code. 315 */ 316 oreach = peer->reach & 0xfe; 317 peer->reach <<= 1; 318 if (!(peer->reach & 0x0f)) 319 clock_filter(peer, 0., 0., MAXDISPERSE); 320 peer->outdate = current_time; 321 if (!peer->reach) { 322 if (oreach) { 323 report_event(PEVNT_UNREACH, peer, NULL); 324 peer->timereachable = current_time; 325 } 326 } else { 327 if (peer->flags & FLAG_BURST) 328 peer->burst = NSTAGE; 329 } 330 } else { 331 peer->burst--; 332 } 333 if (refclock_conf[clktype]->clock_poll != noentry) 334 (refclock_conf[clktype]->clock_poll)(unit, peer); 335 poll_update(peer, peer->hpoll); 336 } 337 338 339 /* 340 * Compare two doubles - used with qsort() 341 */ 342 static int 343 refclock_cmpl_fp( 344 const void *p1, 345 const void *p2 346 ) 347 { 348 const double *dp1 = (const double *)p1; 349 const double *dp2 = (const double *)p2; 350 351 if (*dp1 < *dp2) 352 return -1; 353 if (*dp1 > *dp2) 354 return 1; 355 return 0; 356 } 357 358 359 /* 360 * refclock_process_offset - update median filter 361 * 362 * This routine uses the given offset and timestamps to construct a new 363 * entry in the median filter circular buffer. Samples that overflow the 364 * filter are quietly discarded. 365 */ 366 void 367 refclock_process_offset( 368 struct refclockproc *pp, /* refclock structure pointer */ 369 l_fp lasttim, /* last timecode timestamp */ 370 l_fp lastrec, /* last receive timestamp */ 371 double fudge 372 ) 373 { 374 l_fp lftemp; 375 double doffset; 376 377 pp->lastrec = lastrec; 378 lftemp = lasttim; 379 L_SUB(&lftemp, &lastrec); 380 LFPTOD(&lftemp, doffset); 381 SAMPLE(doffset + fudge); 382 } 383 384 385 /* 386 * refclock_process - process a sample from the clock 387 * refclock_process_f - refclock_process with other than time1 fudge 388 * 389 * This routine converts the timecode in the form days, hours, minutes, 390 * seconds and milliseconds/microseconds to internal timestamp format, 391 * then constructs a new entry in the median filter circular buffer. 392 * Return success (1) if the data are correct and consistent with the 393 * converntional calendar. 394 * 395 * Important for PPS users: Normally, the pp->lastrec is set to the 396 * system time when the on-time character is received and the pp->year, 397 * ..., pp->second decoded and the seconds fraction pp->nsec in 398 * nanoseconds). When a PPS offset is available, pp->nsec is forced to 399 * zero and the fraction for pp->lastrec is set to the PPS offset. 400 */ 401 int 402 refclock_process_f( 403 struct refclockproc *pp, /* refclock structure pointer */ 404 double fudge 405 ) 406 { 407 l_fp offset, ltemp; 408 409 /* 410 * Compute the timecode timestamp from the days, hours, minutes, 411 * seconds and milliseconds/microseconds of the timecode. Use 412 * clocktime() for the aggregate seconds and the msec/usec for 413 * the fraction, when present. Note that this code relies on the 414 * filesystem time for the years and does not use the years of 415 * the timecode. 416 */ 417 if (!clocktime(pp->day, pp->hour, pp->minute, pp->second, GMT, 418 pp->lastrec.l_ui, &pp->yearstart, &offset.l_ui)) 419 return (0); 420 421 offset.l_uf = 0; 422 DTOLFP(pp->nsec / 1e9, <emp); 423 L_ADD(&offset, <emp); 424 refclock_process_offset(pp, offset, pp->lastrec, fudge); 425 return (1); 426 } 427 428 429 int 430 refclock_process( 431 struct refclockproc *pp /* refclock structure pointer */ 432 ) 433 { 434 return refclock_process_f(pp, pp->fudgetime1); 435 } 436 437 438 /* 439 * refclock_sample - process a pile of samples from the clock 440 * 441 * This routine implements a recursive median filter to suppress spikes 442 * in the data, as well as determine a performance statistic. It 443 * calculates the mean offset and RMS jitter. A time adjustment 444 * fudgetime1 can be added to the final offset to compensate for various 445 * systematic errors. The routine returns the number of samples 446 * processed, which could be zero. 447 */ 448 static int 449 refclock_sample( 450 struct refclockproc *pp /* refclock structure pointer */ 451 ) 452 { 453 size_t i, j, k, m, n; 454 double off[MAXSTAGE]; 455 double offset; 456 457 /* 458 * Copy the raw offsets and sort into ascending order. Don't do 459 * anything if the buffer is empty. 460 */ 461 n = 0; 462 while (pp->codeproc != pp->coderecv) { 463 pp->codeproc = (pp->codeproc + 1) % MAXSTAGE; 464 off[n] = pp->filter[pp->codeproc]; 465 n++; 466 } 467 if (n == 0) 468 return (0); 469 470 if (n > 1) 471 qsort(off, n, sizeof(off[0]), refclock_cmpl_fp); 472 473 /* 474 * Reject the furthest from the median of the samples until 475 * approximately 60 percent of the samples remain. 476 */ 477 i = 0; j = n; 478 m = n - (n * 4) / 10; 479 while ((j - i) > m) { 480 offset = off[(j + i) / 2]; 481 if (off[j - 1] - offset < offset - off[i]) 482 i++; /* reject low end */ 483 else 484 j--; /* reject high end */ 485 } 486 487 /* 488 * Determine the offset and jitter. 489 */ 490 pp->offset = 0; 491 pp->jitter = 0; 492 for (k = i; k < j; k++) { 493 pp->offset += off[k]; 494 if (k > i) 495 pp->jitter += SQUARE(off[k] - off[k - 1]); 496 } 497 pp->offset /= m; 498 pp->jitter = max(SQRT(pp->jitter / m), LOGTOD(sys_precision)); 499 #ifdef DEBUG 500 if (debug) 501 printf( 502 "refclock_sample: n %d offset %.6f disp %.6f jitter %.6f\n", 503 (int)n, pp->offset, pp->disp, pp->jitter); 504 #endif 505 return (int)n; 506 } 507 508 509 /* 510 * refclock_receive - simulate the receive and packet procedures 511 * 512 * This routine simulates the NTP receive and packet procedures for a 513 * reference clock. This provides a mechanism in which the ordinary NTP 514 * filter, selection and combining algorithms can be used to suppress 515 * misbehaving radios and to mitigate between them when more than one is 516 * available for backup. 517 */ 518 void 519 refclock_receive( 520 struct peer *peer /* peer structure pointer */ 521 ) 522 { 523 struct refclockproc *pp; 524 525 #ifdef DEBUG 526 if (debug) 527 printf("refclock_receive: at %lu %s\n", 528 current_time, stoa(&peer->srcadr)); 529 #endif 530 531 /* 532 * Do a little sanity dance and update the peer structure. Groom 533 * the median filter samples and give the data to the clock 534 * filter. 535 */ 536 pp = peer->procptr; 537 peer->leap = pp->leap; 538 if (peer->leap == LEAP_NOTINSYNC) 539 return; 540 541 peer->received++; 542 peer->timereceived = current_time; 543 if (!peer->reach) { 544 report_event(PEVNT_REACH, peer, NULL); 545 peer->timereachable = current_time; 546 } 547 peer->reach |= 1; 548 peer->reftime = pp->lastref; 549 peer->aorg = pp->lastrec; 550 peer->rootdisp = pp->disp; 551 get_systime(&peer->dst); 552 if (!refclock_sample(pp)) 553 return; 554 555 clock_filter(peer, pp->offset, 0., pp->jitter); 556 if (cal_enable && fabs(last_offset) < sys_mindisp && sys_peer != 557 NULL) { 558 if (sys_peer->refclktype == REFCLK_ATOM_PPS && 559 peer->refclktype != REFCLK_ATOM_PPS) 560 pp->fudgetime1 -= pp->offset * FUDGEFAC; 561 } 562 } 563 564 565 /* 566 * refclock_gtlin - groom next input line and extract timestamp 567 * 568 * This routine processes the timecode received from the clock and 569 * strips the parity bit and control characters. It returns the number 570 * of characters in the line followed by a NULL character ('\0'), which 571 * is not included in the count. In case of an empty line, the previous 572 * line is preserved. 573 */ 574 int 575 refclock_gtlin( 576 struct recvbuf *rbufp, /* receive buffer pointer */ 577 char *lineptr, /* current line pointer */ 578 int bmax, /* remaining characters in line */ 579 l_fp *tsptr /* pointer to timestamp returned */ 580 ) 581 { 582 const char *sp, *spend; 583 char *dp, *dpend; 584 int dlen; 585 586 if (bmax <= 0) 587 return (0); 588 589 dp = lineptr; 590 dpend = dp + bmax - 1; /* leave room for NUL pad */ 591 sp = (const char *)rbufp->recv_buffer; 592 spend = sp + rbufp->recv_length; 593 594 while (sp != spend && dp != dpend) { 595 char c; 596 597 c = *sp++ & 0x7f; 598 if (c >= 0x20 && c < 0x7f) 599 *dp++ = c; 600 } 601 /* Get length of data written to the destination buffer. If 602 * zero, do *not* place a NUL byte to preserve the previous 603 * buffer content. 604 */ 605 dlen = dp - lineptr; 606 if (dlen) 607 *dp = '\0'; 608 *tsptr = rbufp->recv_time; 609 DPRINTF(2, ("refclock_gtlin: fd %d time %s timecode %d %s\n", 610 rbufp->fd, ulfptoa(&rbufp->recv_time, 6), dlen, 611 (dlen != 0) 612 ? lineptr 613 : "")); 614 return (dlen); 615 } 616 617 618 /* 619 * refclock_gtraw - get next line/chunk of data 620 * 621 * This routine returns the raw data received from the clock in both 622 * canonical or raw modes. The terminal interface routines map CR to LF. 623 * In canonical mode this results in two lines, one containing data 624 * followed by LF and another containing only LF. In raw mode the 625 * interface routines can deliver arbitraty chunks of data from one 626 * character to a maximum specified by the calling routine. In either 627 * mode the routine returns the number of characters in the line 628 * followed by a NULL character ('\0'), which is not included in the 629 * count. 630 * 631 * *tsptr receives a copy of the buffer timestamp. 632 */ 633 int 634 refclock_gtraw( 635 struct recvbuf *rbufp, /* receive buffer pointer */ 636 char *lineptr, /* current line pointer */ 637 int bmax, /* remaining characters in line */ 638 l_fp *tsptr /* pointer to timestamp returned */ 639 ) 640 { 641 if (bmax <= 0) 642 return (0); 643 bmax -= 1; /* leave room for trailing NUL */ 644 if (bmax > rbufp->recv_length) 645 bmax = rbufp->recv_length; 646 memcpy(lineptr, rbufp->recv_buffer, bmax); 647 lineptr[bmax] = '\0'; 648 649 *tsptr = rbufp->recv_time; 650 DPRINTF(2, ("refclock_gtraw: fd %d time %s timecode %d %s\n", 651 rbufp->fd, ulfptoa(&rbufp->recv_time, 6), bmax, 652 lineptr)); 653 return (bmax); 654 } 655 656 657 /* 658 * indicate_refclock_packet() 659 * 660 * Passes a fragment of refclock input read from the device to the 661 * driver direct input routine, which may consume it (batch it for 662 * queuing once a logical unit is assembled). If it is not so 663 * consumed, queue it for the driver's receive entrypoint. 664 * 665 * The return value is TRUE if the data has been consumed as a fragment 666 * and should not be counted as a received packet. 667 */ 668 int 669 indicate_refclock_packet( 670 struct refclockio * rio, 671 struct recvbuf * rb 672 ) 673 { 674 /* Does this refclock use direct input routine? */ 675 if (rio->io_input != NULL && (*rio->io_input)(rb) == 0) { 676 /* 677 * data was consumed - nothing to pass up 678 * into block input machine 679 */ 680 freerecvbuf(rb); 681 682 return TRUE; 683 } 684 add_full_recv_buffer(rb); 685 686 return FALSE; 687 } 688 689 690 /* 691 * process_refclock_packet() 692 * 693 * Used for deferred processing of 'io_input' on systems where threading 694 * is used (notably Windows). This is acting as a trampoline to make the 695 * real calls to the refclock functions. 696 */ 697 #ifdef HAVE_IO_COMPLETION_PORT 698 void 699 process_refclock_packet( 700 struct recvbuf * rb 701 ) 702 { 703 struct refclockio * rio; 704 705 /* get the refclockio structure from the receive buffer */ 706 rio = &rb->recv_peer->procptr->io; 707 708 /* call 'clock_recv' if either there is no input function or the 709 * raw input function tells us to feed the packet to the 710 * receiver. 711 */ 712 if (rio->io_input == NULL || (*rio->io_input)(rb) != 0) { 713 rio->recvcount++; 714 packets_received++; 715 handler_pkts++; 716 (*rio->clock_recv)(rb); 717 } 718 } 719 #endif /* HAVE_IO_COMPLETION_PORT */ 720 721 722 /* 723 * The following code does not apply to WINNT & VMS ... 724 */ 725 #if !defined(SYS_VXWORKS) && !defined(SYS_WINNT) 726 #if defined(HAVE_TERMIOS) || defined(HAVE_SYSV_TTYS) || defined(HAVE_BSD_TTYS) 727 728 /* 729 * refclock_open - open serial port for reference clock 730 * 731 * This routine opens a serial port for I/O and sets default options. It 732 * returns the file descriptor if successful, or logs an error and 733 * returns -1. 734 */ 735 int 736 refclock_open( 737 char *dev, /* device name pointer */ 738 u_int speed, /* serial port speed (code) */ 739 u_int lflags /* line discipline flags */ 740 ) 741 { 742 int fd; 743 int omode; 744 #ifdef O_NONBLOCK 745 char trash[128]; /* litter bin for old input data */ 746 #endif 747 748 /* 749 * Open serial port and set default options 750 */ 751 omode = O_RDWR; 752 #ifdef O_NONBLOCK 753 omode |= O_NONBLOCK; 754 #endif 755 #ifdef O_NOCTTY 756 omode |= O_NOCTTY; 757 #endif 758 759 fd = open(dev, omode, 0777); 760 /* refclock_open() long returned 0 on failure, avoid it. */ 761 if (0 == fd) { 762 fd = dup(0); 763 SAVE_ERRNO( 764 close(0); 765 ) 766 } 767 if (fd < 0) { 768 SAVE_ERRNO( 769 msyslog(LOG_ERR, "refclock_open %s: %m", dev); 770 ) 771 return -1; 772 } 773 if (!refclock_setup(fd, speed, lflags)) { 774 close(fd); 775 return -1; 776 } 777 if (!refclock_ioctl(fd, lflags)) { 778 close(fd); 779 return -1; 780 } 781 #ifdef O_NONBLOCK 782 /* 783 * We want to make sure there is no pending trash in the input 784 * buffer. Since we have non-blocking IO available, this is a 785 * good moment to read and dump all available outdated stuff 786 * that might have become toxic for the driver. 787 */ 788 while (read(fd, trash, sizeof(trash)) > 0 || errno == EINTR) 789 /*NOP*/; 790 #endif 791 return fd; 792 } 793 794 795 /* 796 * refclock_setup - initialize terminal interface structure 797 */ 798 int 799 refclock_setup( 800 int fd, /* file descriptor */ 801 u_int speed, /* serial port speed (code) */ 802 u_int lflags /* line discipline flags */ 803 ) 804 { 805 int i; 806 TTY ttyb, *ttyp; 807 808 /* 809 * By default, the serial line port is initialized in canonical 810 * (line-oriented) mode at specified line speed, 8 bits and no 811 * parity. LF ends the line and CR is mapped to LF. The break, 812 * erase and kill functions are disabled. There is a different 813 * section for each terminal interface, as selected at compile 814 * time. The flag bits can be used to set raw mode and echo. 815 */ 816 ttyp = &ttyb; 817 #ifdef HAVE_TERMIOS 818 819 /* 820 * POSIX serial line parameters (termios interface) 821 */ 822 if (tcgetattr(fd, ttyp) < 0) { 823 SAVE_ERRNO( 824 msyslog(LOG_ERR, 825 "refclock_setup fd %d tcgetattr: %m", 826 fd); 827 ) 828 return FALSE; 829 } 830 831 /* 832 * Set canonical mode and local connection; set specified speed, 833 * 8 bits and no parity; map CR to NL; ignore break. 834 */ 835 if (speed) { 836 u_int ltemp = 0; 837 838 ttyp->c_iflag = IGNBRK | IGNPAR | ICRNL; 839 ttyp->c_oflag = 0; 840 ttyp->c_cflag = CS8 | CLOCAL | CREAD; 841 if (lflags & LDISC_7O1) { 842 /* HP Z3801A needs 7-bit, odd parity */ 843 ttyp->c_cflag = CS7 | PARENB | PARODD | CLOCAL | CREAD; 844 } 845 cfsetispeed(&ttyb, speed); 846 cfsetospeed(&ttyb, speed); 847 for (i = 0; i < NCCS; ++i) 848 ttyp->c_cc[i] = '\0'; 849 850 #if defined(TIOCMGET) && !defined(SCO5_CLOCK) 851 852 /* 853 * If we have modem control, check to see if modem leads 854 * are active; if so, set remote connection. This is 855 * necessary for the kernel pps mods to work. 856 */ 857 if (ioctl(fd, TIOCMGET, (char *)<emp) < 0) 858 msyslog(LOG_ERR, 859 "refclock_setup fd %d TIOCMGET: %m", fd); 860 #ifdef DEBUG 861 if (debug) 862 printf("refclock_setup fd %d modem status: 0x%x\n", 863 fd, ltemp); 864 #endif 865 if (ltemp & TIOCM_DSR && lflags & LDISC_REMOTE) 866 ttyp->c_cflag &= ~CLOCAL; 867 #endif /* TIOCMGET */ 868 } 869 870 /* 871 * Set raw and echo modes. These can be changed on-fly. 872 */ 873 ttyp->c_lflag = ICANON; 874 if (lflags & LDISC_RAW) { 875 ttyp->c_lflag = 0; 876 ttyp->c_iflag = 0; 877 ttyp->c_cc[VMIN] = 1; 878 } 879 if (lflags & LDISC_ECHO) 880 ttyp->c_lflag |= ECHO; 881 if (tcsetattr(fd, TCSANOW, ttyp) < 0) { 882 SAVE_ERRNO( 883 msyslog(LOG_ERR, 884 "refclock_setup fd %d TCSANOW: %m", 885 fd); 886 ) 887 return FALSE; 888 } 889 890 /* 891 * flush input and output buffers to discard any outdated stuff 892 * that might have become toxic for the driver. Failing to do so 893 * is logged, but we keep our fingers crossed otherwise. 894 */ 895 if (tcflush(fd, TCIOFLUSH) < 0) 896 msyslog(LOG_ERR, "refclock_setup fd %d tcflush(): %m", 897 fd); 898 #endif /* HAVE_TERMIOS */ 899 900 #ifdef HAVE_SYSV_TTYS 901 902 /* 903 * System V serial line parameters (termio interface) 904 * 905 */ 906 if (ioctl(fd, TCGETA, ttyp) < 0) { 907 SAVE_ERRNO( 908 msyslog(LOG_ERR, 909 "refclock_setup fd %d TCGETA: %m", 910 fd); 911 ) 912 return FALSE; 913 } 914 915 /* 916 * Set canonical mode and local connection; set specified speed, 917 * 8 bits and no parity; map CR to NL; ignore break. 918 */ 919 if (speed) { 920 u_int ltemp = 0; 921 922 ttyp->c_iflag = IGNBRK | IGNPAR | ICRNL; 923 ttyp->c_oflag = 0; 924 ttyp->c_cflag = speed | CS8 | CLOCAL | CREAD; 925 for (i = 0; i < NCCS; ++i) 926 ttyp->c_cc[i] = '\0'; 927 928 #if defined(TIOCMGET) && !defined(SCO5_CLOCK) 929 930 /* 931 * If we have modem control, check to see if modem leads 932 * are active; if so, set remote connection. This is 933 * necessary for the kernel pps mods to work. 934 */ 935 if (ioctl(fd, TIOCMGET, (char *)<emp) < 0) 936 msyslog(LOG_ERR, 937 "refclock_setup fd %d TIOCMGET: %m", fd); 938 #ifdef DEBUG 939 if (debug) 940 printf("refclock_setup fd %d modem status: %x\n", 941 fd, ltemp); 942 #endif 943 if (ltemp & TIOCM_DSR) 944 ttyp->c_cflag &= ~CLOCAL; 945 #endif /* TIOCMGET */ 946 } 947 948 /* 949 * Set raw and echo modes. These can be changed on-fly. 950 */ 951 ttyp->c_lflag = ICANON; 952 if (lflags & LDISC_RAW) { 953 ttyp->c_lflag = 0; 954 ttyp->c_iflag = 0; 955 ttyp->c_cc[VMIN] = 1; 956 } 957 if (ioctl(fd, TCSETA, ttyp) < 0) { 958 SAVE_ERRNO( 959 msyslog(LOG_ERR, 960 "refclock_setup fd %d TCSETA: %m", fd); 961 ) 962 return FALSE; 963 } 964 #endif /* HAVE_SYSV_TTYS */ 965 966 #ifdef HAVE_BSD_TTYS 967 968 /* 969 * 4.3bsd serial line parameters (sgttyb interface) 970 */ 971 if (ioctl(fd, TIOCGETP, (char *)ttyp) < 0) { 972 SAVE_ERRNO( 973 msyslog(LOG_ERR, 974 "refclock_setup fd %d TIOCGETP: %m", 975 fd); 976 ) 977 return FALSE; 978 } 979 if (speed) 980 ttyp->sg_ispeed = ttyp->sg_ospeed = speed; 981 ttyp->sg_flags = EVENP | ODDP | CRMOD; 982 if (ioctl(fd, TIOCSETP, (char *)ttyp) < 0) { 983 SAVE_ERRNO( 984 msyslog(LOG_ERR, "refclock_setup TIOCSETP: %m"); 985 ) 986 return FALSE; 987 } 988 #endif /* HAVE_BSD_TTYS */ 989 return(1); 990 } 991 #endif /* HAVE_TERMIOS || HAVE_SYSV_TTYS || HAVE_BSD_TTYS */ 992 993 994 /* 995 * refclock_ioctl - set serial port control functions 996 * 997 * This routine attempts to hide the internal, system-specific details 998 * of serial ports. It can handle POSIX (termios), SYSV (termio) and BSD 999 * (sgtty) interfaces with varying degrees of success. The routine sets 1000 * up optional features such as tty_clk. The routine returns TRUE if 1001 * successful. 1002 */ 1003 int 1004 refclock_ioctl( 1005 int fd, /* file descriptor */ 1006 u_int lflags /* line discipline flags */ 1007 ) 1008 { 1009 /* 1010 * simply return TRUE if no UNIX line discipline is supported 1011 */ 1012 DPRINTF(1, ("refclock_ioctl: fd %d flags 0x%x\n", fd, lflags)); 1013 1014 return TRUE; 1015 } 1016 #endif /* !defined(SYS_VXWORKS) && !defined(SYS_WINNT) */ 1017 1018 1019 /* 1020 * refclock_control - set and/or return clock values 1021 * 1022 * This routine is used mainly for debugging. It returns designated 1023 * values from the interface structure that can be displayed using 1024 * ntpdc and the clockstat command. It can also be used to initialize 1025 * configuration variables, such as fudgetimes, fudgevalues, reference 1026 * ID and stratum. 1027 */ 1028 void 1029 refclock_control( 1030 sockaddr_u *srcadr, 1031 const struct refclockstat *in, 1032 struct refclockstat *out 1033 ) 1034 { 1035 struct peer *peer; 1036 struct refclockproc *pp; 1037 u_char clktype; 1038 int unit; 1039 1040 /* 1041 * Check for valid address and running peer 1042 */ 1043 if (!ISREFCLOCKADR(srcadr)) 1044 return; 1045 1046 clktype = (u_char)REFCLOCKTYPE(srcadr); 1047 unit = REFCLOCKUNIT(srcadr); 1048 1049 peer = findexistingpeer(srcadr, NULL, NULL, -1, 0); 1050 1051 if (NULL == peer) 1052 return; 1053 1054 NTP_INSIST(peer->procptr != NULL); 1055 pp = peer->procptr; 1056 1057 /* 1058 * Initialize requested data 1059 */ 1060 if (in != NULL) { 1061 if (in->haveflags & CLK_HAVETIME1) 1062 pp->fudgetime1 = in->fudgetime1; 1063 if (in->haveflags & CLK_HAVETIME2) 1064 pp->fudgetime2 = in->fudgetime2; 1065 if (in->haveflags & CLK_HAVEVAL1) 1066 peer->stratum = pp->stratum = (u_char)in->fudgeval1; 1067 if (in->haveflags & CLK_HAVEVAL2) 1068 peer->refid = pp->refid = in->fudgeval2; 1069 if (in->haveflags & CLK_HAVEFLAG1) { 1070 pp->sloppyclockflag &= ~CLK_FLAG1; 1071 pp->sloppyclockflag |= in->flags & CLK_FLAG1; 1072 } 1073 if (in->haveflags & CLK_HAVEFLAG2) { 1074 pp->sloppyclockflag &= ~CLK_FLAG2; 1075 pp->sloppyclockflag |= in->flags & CLK_FLAG2; 1076 } 1077 if (in->haveflags & CLK_HAVEFLAG3) { 1078 pp->sloppyclockflag &= ~CLK_FLAG3; 1079 pp->sloppyclockflag |= in->flags & CLK_FLAG3; 1080 } 1081 if (in->haveflags & CLK_HAVEFLAG4) { 1082 pp->sloppyclockflag &= ~CLK_FLAG4; 1083 pp->sloppyclockflag |= in->flags & CLK_FLAG4; 1084 } 1085 } 1086 1087 /* 1088 * Readback requested data 1089 */ 1090 if (out != NULL) { 1091 out->fudgeval1 = pp->stratum; 1092 out->fudgeval2 = pp->refid; 1093 out->haveflags = CLK_HAVEVAL1 | CLK_HAVEVAL2; 1094 out->fudgetime1 = pp->fudgetime1; 1095 if (0.0 != out->fudgetime1) 1096 out->haveflags |= CLK_HAVETIME1; 1097 out->fudgetime2 = pp->fudgetime2; 1098 if (0.0 != out->fudgetime2) 1099 out->haveflags |= CLK_HAVETIME2; 1100 out->flags = (u_char) pp->sloppyclockflag; 1101 if (CLK_FLAG1 & out->flags) 1102 out->haveflags |= CLK_HAVEFLAG1; 1103 if (CLK_FLAG2 & out->flags) 1104 out->haveflags |= CLK_HAVEFLAG2; 1105 if (CLK_FLAG3 & out->flags) 1106 out->haveflags |= CLK_HAVEFLAG3; 1107 if (CLK_FLAG4 & out->flags) 1108 out->haveflags |= CLK_HAVEFLAG4; 1109 1110 out->timereset = current_time - pp->timestarted; 1111 out->polls = pp->polls; 1112 out->noresponse = pp->noreply; 1113 out->badformat = pp->badformat; 1114 out->baddata = pp->baddata; 1115 1116 out->lastevent = pp->lastevent; 1117 out->currentstatus = pp->currentstatus; 1118 out->type = pp->type; 1119 out->clockdesc = pp->clockdesc; 1120 out->lencode = (u_short)pp->lencode; 1121 out->p_lastcode = pp->a_lastcode; 1122 } 1123 1124 /* 1125 * Give the stuff to the clock 1126 */ 1127 if (refclock_conf[clktype]->clock_control != noentry) 1128 (refclock_conf[clktype]->clock_control)(unit, in, out, peer); 1129 } 1130 1131 1132 /* 1133 * refclock_buginfo - return debugging info 1134 * 1135 * This routine is used mainly for debugging. It returns designated 1136 * values from the interface structure that can be displayed using 1137 * ntpdc and the clkbug command. 1138 */ 1139 void 1140 refclock_buginfo( 1141 sockaddr_u *srcadr, /* clock address */ 1142 struct refclockbug *bug /* output structure */ 1143 ) 1144 { 1145 struct peer *peer; 1146 struct refclockproc *pp; 1147 int clktype; 1148 int unit; 1149 unsigned u; 1150 1151 /* 1152 * Check for valid address and peer structure 1153 */ 1154 if (!ISREFCLOCKADR(srcadr)) 1155 return; 1156 1157 clktype = (u_char) REFCLOCKTYPE(srcadr); 1158 unit = REFCLOCKUNIT(srcadr); 1159 1160 peer = findexistingpeer(srcadr, NULL, NULL, -1, 0); 1161 1162 if (NULL == peer || NULL == peer->procptr) 1163 return; 1164 1165 pp = peer->procptr; 1166 1167 /* 1168 * Copy structure values 1169 */ 1170 bug->nvalues = 8; 1171 bug->svalues = 0x0000003f; 1172 bug->values[0] = pp->year; 1173 bug->values[1] = pp->day; 1174 bug->values[2] = pp->hour; 1175 bug->values[3] = pp->minute; 1176 bug->values[4] = pp->second; 1177 bug->values[5] = pp->nsec; 1178 bug->values[6] = pp->yearstart; 1179 bug->values[7] = pp->coderecv; 1180 bug->stimes = 0xfffffffc; 1181 bug->times[0] = pp->lastref; 1182 bug->times[1] = pp->lastrec; 1183 for (u = 2; u < bug->ntimes; u++) 1184 DTOLFP(pp->filter[u - 2], &bug->times[u]); 1185 1186 /* 1187 * Give the stuff to the clock 1188 */ 1189 if (refclock_conf[clktype]->clock_buginfo != noentry) 1190 (refclock_conf[clktype]->clock_buginfo)(unit, bug, peer); 1191 } 1192 1193 1194 #ifdef HAVE_PPSAPI 1195 /* 1196 * refclock_ppsapi - initialize/update ppsapi 1197 * 1198 * This routine is called after the fudge command to open the PPSAPI 1199 * interface for later parameter setting after the fudge command. 1200 */ 1201 int 1202 refclock_ppsapi( 1203 int fddev, /* fd device */ 1204 struct refclock_atom *ap /* atom structure pointer */ 1205 ) 1206 { 1207 if (ap->handle == 0) { 1208 if (time_pps_create(fddev, &ap->handle) < 0) { 1209 msyslog(LOG_ERR, 1210 "refclock_ppsapi: time_pps_create: %m"); 1211 return (0); 1212 } 1213 } 1214 return (1); 1215 } 1216 1217 1218 /* 1219 * refclock_params - set ppsapi parameters 1220 * 1221 * This routine is called to set the PPSAPI parameters after the fudge 1222 * command. 1223 */ 1224 int 1225 refclock_params( 1226 int mode, /* mode bits */ 1227 struct refclock_atom *ap /* atom structure pointer */ 1228 ) 1229 { 1230 ZERO(ap->pps_params); 1231 ap->pps_params.api_version = PPS_API_VERS_1; 1232 1233 /* 1234 * Solaris serial ports provide PPS pulse capture only on the 1235 * assert edge. FreeBSD serial ports provide capture on the 1236 * clear edge, while FreeBSD parallel ports provide capture 1237 * on the assert edge. Your mileage may vary. 1238 */ 1239 if (mode & CLK_FLAG2) 1240 ap->pps_params.mode = PPS_TSFMT_TSPEC | PPS_CAPTURECLEAR; 1241 else 1242 ap->pps_params.mode = PPS_TSFMT_TSPEC | PPS_CAPTUREASSERT; 1243 if (time_pps_setparams(ap->handle, &ap->pps_params) < 0) { 1244 msyslog(LOG_ERR, 1245 "refclock_params: time_pps_setparams: %m"); 1246 return (0); 1247 } 1248 1249 /* 1250 * If flag3 is lit, select the kernel PPS. 1251 */ 1252 if (mode & CLK_FLAG3) { 1253 if (time_pps_kcbind(ap->handle, PPS_KC_HARDPPS, 1254 ap->pps_params.mode & ~PPS_TSFMT_TSPEC, 1255 PPS_TSFMT_TSPEC) < 0) { 1256 if (errno != EOPNOTSUPP) { 1257 msyslog(LOG_ERR, 1258 "refclock_params: time_pps_kcbind: %m"); 1259 return (0); 1260 } 1261 } 1262 pps_enable = 1; 1263 } 1264 return (1); 1265 } 1266 1267 1268 /* 1269 * refclock_pps - called once per second 1270 * 1271 * This routine is called once per second. It snatches the PPS 1272 * timestamp from the kernel and saves the sign-extended fraction in 1273 * a circular buffer for processing at the next poll event. 1274 */ 1275 int 1276 refclock_pps( 1277 struct peer *peer, /* peer structure pointer */ 1278 struct refclock_atom *ap, /* atom structure pointer */ 1279 int mode /* mode bits */ 1280 ) 1281 { 1282 struct refclockproc *pp; 1283 pps_info_t pps_info; 1284 struct timespec timeout; 1285 double dtemp; 1286 1287 /* 1288 * We require the clock to be synchronized before setting the 1289 * parameters. When the parameters have been set, fetch the 1290 * most recent PPS timestamp. 1291 */ 1292 pp = peer->procptr; 1293 if (ap->handle == 0) 1294 return (0); 1295 1296 if (ap->pps_params.mode == 0 && sys_leap != LEAP_NOTINSYNC) { 1297 if (refclock_params(pp->sloppyclockflag, ap) < 1) 1298 return (0); 1299 } 1300 timeout.tv_sec = 0; 1301 timeout.tv_nsec = 0; 1302 ZERO(pps_info); 1303 if (time_pps_fetch(ap->handle, PPS_TSFMT_TSPEC, &pps_info, 1304 &timeout) < 0) { 1305 refclock_report(peer, CEVNT_FAULT); 1306 return (0); 1307 } 1308 timeout = ap->ts; 1309 if (ap->pps_params.mode & PPS_CAPTUREASSERT) 1310 ap->ts = pps_info.assert_timestamp; 1311 else if (ap->pps_params.mode & PPS_CAPTURECLEAR) 1312 ap->ts = pps_info.clear_timestamp; 1313 else 1314 return (0); 1315 1316 if (0 == memcmp(&timeout, &ap->ts, sizeof(timeout))) 1317 return (0); 1318 1319 /* 1320 * Convert to signed fraction offset and stuff in median filter. 1321 */ 1322 pp->lastrec.l_ui = (u_int32)ap->ts.tv_sec + JAN_1970; 1323 dtemp = ap->ts.tv_nsec / 1e9; 1324 pp->lastrec.l_uf = (u_int32)(dtemp * FRAC); 1325 if (dtemp > .5) 1326 dtemp -= 1.; 1327 SAMPLE(-dtemp + pp->fudgetime1); 1328 #ifdef DEBUG 1329 if (debug > 1) 1330 printf("refclock_pps: %lu %f %f\n", current_time, 1331 dtemp, pp->fudgetime1); 1332 #endif 1333 return (1); 1334 } 1335 #endif /* HAVE_PPSAPI */ 1336 #endif /* REFCLOCK */ 1337