📄 refclock_msfees.c
字号:
noentry, /* not used */ NOFLAGS /* not used */};static voiddump_buf( l_fp *coffs, int from, int to, char *text ){ char buff[DUMP_BUF_SIZE + 80]; int i; register char *ptr = buff; sprintf(ptr, text); for (i=from; i<to; i++) { while (*ptr) ptr++; if ((ptr-buff) > DUMP_BUF_SIZE) msyslog(LOG_DEBUG, "D: %s", ptr=buff); sprintf(ptr, " %06d", ((int)coffs[i].l_f) / 4295); } msyslog(LOG_DEBUG, "D: %s", buff);}/* msfees_init - initialize internal ees driver data */static voidmsfees_init(void){ register int i; /* Just zero the data arrays */ memset((char *)eesunits, 0, sizeof eesunits); memset((char *)unitinuse, 0, sizeof unitinuse); acceptable_slop.l_ui = 0; acceptable_slop.l_uf = 1 << (FRACTION_PREC -2); onesec.l_ui = 1; onesec.l_uf = 0; /* Initialize fudge factors to default. */ for (i = 0; i < MAXUNITS; i++) { fudgefactor[i].l_ui = 0; fudgefactor[i].l_uf = DEFFUDGETIME; os_delay[i].l_ui = 0; os_delay[i].l_uf = DEFOSTIME; inherent_delay[i].l_ui = 0; inherent_delay[i].l_uf = DEFINHTIME; offset_fudge[i] = os_delay[i]; L_ADD(&offset_fudge[i], &fudgefactor[i]); L_ADD(&offset_fudge[i], &inherent_delay[i]); stratumtouse[i] = 0; sloppyclockflag[i] = 0; }}/* msfees_start - open the EES devices and initialize data for processing */static intmsfees_start( int unit, struct peer *peer ){ register struct eesunit *ees; register int i; int fd232 = -1; char eesdev[20]; struct termios ttyb, *ttyp; struct refclockproc *pp; pp = peer->procptr; if (unit >= MAXUNITS) { msyslog(LOG_ERR, "ees clock: unit number %d invalid (max %d)", unit, MAXUNITS-1); return 0; } if (unitinuse[unit]) { msyslog(LOG_ERR, "ees clock: unit number %d in use", unit); return 0; } /* Unit okay, attempt to open the devices. We do them both at * once to make sure we can */ (void) sprintf(eesdev, EES232, unit); fd232 = open(eesdev, O_RDWR, 0777); if (fd232 == -1) { msyslog(LOG_ERR, "ees clock: open of %s failed: %m", eesdev); return 0; }#ifdef TIOCEXCL /* Set for exclusive use */ if (ioctl(fd232, TIOCEXCL, (char *)0) < 0) { msyslog(LOG_ERR, "ees clock: ioctl(%s, TIOCEXCL): %m", eesdev); goto screwed; }#endif /* STRIPPED DOWN VERSION: Only PPS CD is supported at the moment */ /* Set port characteristics. If we don't have a STREAMS module or * a clock line discipline, cooked mode is just usable, even though it * strips the top bit. The only EES byte which uses the top * bit is the year, and we don't use that anyway. If we do * have the line discipline, we choose raw mode, and the * line discipline code will block up the messages. */ /* STIPPED DOWN VERSION: Only PPS CD is supported at the moment */ ttyp = &ttyb; if (tcgetattr(fd232, ttyp) < 0) { msyslog(LOG_ERR, "msfees_start: tcgetattr(%s): %m", eesdev); goto screwed; } ttyp->c_iflag = IGNBRK|IGNPAR|ICRNL; ttyp->c_cflag = SPEED232|CS8|CLOCAL|CREAD; ttyp->c_oflag = 0; ttyp->c_lflag = ICANON; ttyp->c_cc[VERASE] = ttyp->c_cc[VKILL] = '\0'; if (tcsetattr(fd232, TCSANOW, ttyp) < 0) { msyslog(LOG_ERR, "msfees_start: tcsetattr(%s): %m", eesdev); goto screwed; } if (tcflush(fd232, TCIOFLUSH) < 0) { msyslog(LOG_ERR, "msfees_start: tcflush(%s): %m", eesdev); goto screwed; } inherent_delay[unit].l_uf = INH_DELAY_PPS; /* offset fudge (how *late* the timestamp is) = fudge + os delays */ offset_fudge[unit] = os_delay[unit]; L_ADD(&offset_fudge[unit], &fudgefactor[unit]); L_ADD(&offset_fudge[unit], &inherent_delay[unit]); /* Looks like this might succeed. Find memory for the structure. * Look to see if there are any unused ones, if not we malloc() one. */ if (eesunits[unit] != 0) /* The one we want is okay */ ees = eesunits[unit]; else { /* Look for an unused, but allocated struct */ for (i = 0; i < MAXUNITS; i++) { if (!unitinuse[i] && eesunits[i] != 0) break; } if (i < MAXUNITS) { /* Reclaim this one */ ees = eesunits[i]; eesunits[i] = 0; } /* no spare -- make a new one */ else ees = (struct eesunit *) emalloc(sizeof(struct eesunit)); } memset((char *)ees, 0, sizeof(struct eesunit)); eesunits[unit] = ees; /* Set up the structures */ ees->peer = peer; ees->unit = (u_char)unit; ees->timestarted= current_time; ees->ttytype = 0; ees->io.clock_recv= ees_receive; ees->io.srcclock= (caddr_t)ees; ees->io.datalen = 0; ees->io.fd = fd232; /* Okay. Push one of the two (linked into the kernel, or dynamically * loaded) STREAMS module, and give it to the I/O code to start * receiving stuff. */#ifdef STREAM { int rc1; /* Pop any existing onews first ... */ while (ioctl(fd232, I_POP, 0 ) >= 0) ; /* Now try pushing either of the possible modules */ if ((rc1=ioctl(fd232, I_PUSH, STREAM_PP1)) < 0 && ioctl(fd232, I_PUSH, STREAM_PP2) < 0) { msyslog(LOG_ERR, "ees clock: Push of `%s' and `%s' to %s failed %m", STREAM_PP1, STREAM_PP2, eesdev); goto screwed; } else { NLOG(NLOG_CLOCKINFO) /* conditional if clause for conditional syslog */ msyslog(LOG_INFO, "I: ees clock: PUSHed %s on %s", (rc1 >= 0) ? STREAM_PP1 : STREAM_PP2, eesdev); ees->ttytype |= T_PPS; } }#endif /* STREAM */ /* Add the clock */ if (!io_addclock(&ees->io)) { /* Oh shit. Just close and return. */ msyslog(LOG_ERR, "ees clock: io_addclock(%s): %m", eesdev); goto screwed; } /* All done. Initialize a few random peer variables, then * return success. */ peer->precision = sys_precision; peer->stratum = stratumtouse[unit]; if (stratumtouse[unit] <= 1) { memcpy((char *)&pp->refid, EESREFID, 4); if (unit > 0 && unit < 10) ((char *)&pp->refid)[3] = '0' + unit; } else { peer->refid = htonl(EESHSREFID); } unitinuse[unit] = 1; pp->unitptr = (caddr_t) &eesunits[unit]; pp->clockdesc = EESDESCRIPTION; msyslog(LOG_ERR, "ees clock: %s OK on %d", eesdev, unit); return (1); screwed: if (fd232 != -1) (void) close(fd232); return (0);}/* msfees_shutdown - shut down a EES clock */static voidmsfees_shutdown( int unit, struct peer *peer ){ register struct eesunit *ees; if (unit >= MAXUNITS) { msyslog(LOG_ERR, "ees clock: INTERNAL ERROR, unit number %d invalid (max %d)", unit, MAXUNITS); return; } if (!unitinuse[unit]) { msyslog(LOG_ERR, "ees clock: INTERNAL ERROR, unit number %d not in use", unit); return; } /* Tell the I/O module to turn us off. We're history. */ ees = eesunits[unit]; io_closeclock(&ees->io); unitinuse[unit] = 0;}/* ees_report_event - note the occurance of an event */static voidees_report_event( struct eesunit *ees, int code ){ if (ees->status != (u_char)code) { ees->status = (u_char)code; if (code != CEVNT_NOMINAL) ees->lastevent = (u_char)code; /* Should report event to trap handler in here. * Soon... */ }}/* ees_receive - receive data from the serial interface on an EES clock */static voidees_receive( struct recvbuf *rbufp ){ register int n_sample; register int day; register struct eesunit *ees; register u_char *dpt; /* Data PoinTeR: move along ... */ register u_char *dpend; /* Points just *after* last data char */ register char *cp; l_fp tmp; int call_pps_sample = 0; l_fp pps_arrvstamp; int sincelast; int pps_step = 0; int suspect_4ms_step = 0; struct ppsclockev ppsclockev; long *ptr = (long *) &ppsclockev; int rc; int request;#ifdef HAVE_CIOGETEV request = CIOGETEV;#endif#ifdef HAVE_TIOCGPPSEV request = TIOCGPPSEV;#endif /* Get the clock this applies to and a pointer to the data */ ees = (struct eesunit *)rbufp->recv_srcclock; dpt = (u_char *)&rbufp->recv_space; dpend = dpt + rbufp->recv_length; if ((debug & DB_LOG_AWAITMORE) && (rbufp->recv_length != LENEESCODE)) printf("[%d] ", rbufp->recv_length); /* Check out our state and process appropriately */ switch (ees->codestate) { case EESCS_WAIT: /* Set an initial guess at the timestamp as the recv time. * If just running in CBREAK mode, we can't improve this. * If we have the CLOCK Line Discipline, PPSCD, or sime such, * then we will do better later .... */ ees->arrvtime = rbufp->recv_time; ees->codestate = EESCS_GOTSOME; ees->lencode = 0; /*FALLSTHROUGH*/ case EESCS_GOTSOME: cp = &(ees->lastcode[ees->lencode]); /* Gobble the bytes until the final (possibly stripped) 0xff */ while (dpt < dpend && (*dpt & 0x7f) != 0x7f) { *cp++ = (char)*dpt++; ees->lencode++; /* Oh dear -- too many bytes .. */ if (ees->lencode > LENEESPRT) { NLOG(NLOG_CLOCKINFO) /* conditional if clause for conditional syslog */ msyslog(LOG_INFO, "I: ees clock: %d + %d > %d [%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x]", ees->lencode, dpend - dpt, LENEESPRT,#define D(x) (ees->lastcode[x]) D(0), D(1), D(2), D(3), D(4), D(5), D(6), D(7), D(8), D(9), D(10), D(11), D(12));#undef D ees->badformat++; ees->reason = CODEREASON + 1; ees_event(ees, CEVNT_BADREPLY); ees_reset(ees); return; } } /* Gave up because it was end of the buffer, rather than ff */ if (dpt == dpend) { /* Incomplete. Wait for more. */ if (debug & DB_LOG_AWAITMORE) msyslog(LOG_INFO, "I: ees clock %d: %p == %p: await more", ees->unit, dpt, dpend); return; } /* This shouldn't happen ... ! */ if ((*dpt & 0x7f) != 0x7f) { msyslog(LOG_INFO, "I: ees clock: %0x & 0x7f != 0x7f", *dpt); ees->badformat++; ees->reason = CODEREASON + 2;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -