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