⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 refclock_msfees.c

📁 网络时间协议NTP 源码 版本v4.2.0b 该源码用于linux平台下
💻 C
📖 第 1 页 / 共 4 页
字号:
	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 + -