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