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

📄 ntp_refclock.c

📁 Unix/Linux 网络时间协议版本3 Network Time Protocol Version 3 (NTP) distribution for Unix systems
💻 C
📖 第 1 页 / 共 3 页
字号:
#endif /* HAVE_TERMIOS || HAVE_SYSV_TTYS || HAVE_BSD_TTYS *//* * refclock_ioctl - set serial port control functions * * This routine attempts to hide the internal, system-specific details * of serial ports. It can handle POSIX (termios), SYSV (termio) and BSD * (sgtty) interfaces with varying degrees of success. The routine sets * up the tty_clk, chu_clk and ppsclock streams module/line discipline, * if compiled in the daemon and requested in the call. The routine * returns one if success and zero if failure. */intrefclock_ioctl(fd, flags)	int fd;			/* file descriptor */	int flags;		/* line discipline flags */{	/* simply return 1 if no UNIX line discipline is supported */#if defined(HAVE_TERMIOS) || defined(HAVE_SYSV_TTYS) || defined(HAVE_BSD_TTYS)#ifdef HAVE_TERMIOS	struct termios ttyb, *ttyp;#endif /* HAVE_TERMIOS */#ifdef HAVE_SYSV_TTYS        struct termio ttyb, *ttyp;#endif /* HAVE_SYSV_TTYS */#ifdef HAVE_BSD_TTYS	struct sgttyb ttyb, *ttyp;#endif /* HAVE_BSD_TTYS */#ifdef DEBUG	if (debug)		printf("refclock_ioctl: fd %d flags %x\n",		    fd, flags);#endif	/*	 * The following sections select optional features, such as	 * modem control, line discipline and so forth. Some require	 * specific operating system support in the form of streams	 * modules, which can be loaded and unloaded at run time without	 * rebooting the kernel, or line discipline modules, which must	 * be compiled in the kernel. The streams modules require System	 * V STREAMS support, while the line discipline modules require	 * 4.3bsd or later. The checking frenzy is attenuated here,	 * since the device is already open.	 *	 * Note that both the clk and ppsclock modules are optional; the	 * dang thing still works, but the accuracy improvement using	 * them will not be available. The ppsclock module is associated	 * with a specific, declared line and should be used only once.	 * If requested, the chu module is mandatory, since the driver	 * will not work without it.	 *	 * Use the LDISC_PPS option ONLY with Sun baseboard ttya or	 * ttyb. Using it with the SPIF multipexor crashes the kernel.	 */	if (flags == 0)		return (1);#if !(defined(HAVE_TERMIOS) || defined(HAVE_BSD_TTYS))	if (flags & (LDISC_CLK | LDISC_CHU | LDISC_PPS | LDISC_ACTS))		msyslog(LOG_ERR,	    "refclock_ioctl: unsupported terminal interface");		return (0);#endif /* HAVE_TERMIOS HAVE_BSD_TTYS */	ttyp = &ttyb;#ifdef STREAM#ifdef TTYCLK	/*	 * The TTYCLK option provides timestamping at the driver level. 	 * It requires the tty_clk streams module and System V STREAMS	 * support. 	 */	if (flags & (LDISC_CLK | LDISC_CLKPPS | LDISC_ACTS))	  {	    if (ioctl(fd, I_PUSH, "clk") < 0)	      {		msyslog(LOG_NOTICE,			"refclock_ioctl: optional clk streams module unavailable: %m");	      }	    else	      {		char *str;		if (flags & LDISC_PPS)		  str = "\377";		else if (flags & LDISC_ACTS)		  str = "*";		else		  str = "\n";		if (ioctl(fd, CLK_SETSTR, str) < 0)		  msyslog(LOG_ERR,			  "refclock_ioctl: CLK_SETSTR failed: %m");	      }	  }	/*	 * The ACTS line discipline requires additional line-ending	 * character '*'.	 */	if (flags & LDISC_ACTS) {		(void)tcgetattr(fd, ttyp);		ttyp->c_cc[VEOL] = '*';		(void)tcsetattr(fd, TCSANOW, ttyp);	}#else	if (flags & LDISC_CLK)	  msyslog(LOG_NOTICE,		  "refclock_ioctl: optional clk streams module unsupported");#endif /* TTYCLK */#ifdef CHUCLK	/*	 * The CHUCLK option provides timestamping and decoding for the CHU	 * timecode. It requires the tty_chu streams module and System V	 * STREAMS support.	 */	if (flags & LDISC_CHU)	  {	    (void)tcgetattr(fd, ttyp);	    ttyp->c_lflag = 0;	    ttyp->c_cc[VERASE] = ttyp->c_cc[VKILL] = '\0';	    ttyp->c_cc[VMIN] = 1;	    ttyp->c_cc[VTIME] = 0;	    (void)tcsetattr(fd, TCSANOW, ttyp);	    (void)tcflush(fd, TCIOFLUSH);	    while (ioctl(fd, I_POP, 0) >= 0);	    if (ioctl(fd, I_PUSH, "chu") < 0)	      {		msyslog(LOG_ERR,			"refclock_ioctl: required chu streams module unavailable");		return (0);	      }	  }#else	if (flags & LDISC_CHU)	  {	    msyslog(LOG_ERR,		    "refclock_ioctl: required chu streams module unsupported");	    return (0);	  }#endif /* CHUCLK */#ifdef PPS	/*	 * The PPS option provides timestamping at the driver level.	 * It uses a 1-pps signal and level converter (gadget box) and	 * requires the ppsclock streams module and System V STREAMS	 * support.	 */	if (flags & LDISC_PPS)	  {	    if (fdpps != -1)	      {		msyslog(LOG_ERR,			"refclock_ioctl: ppsclock already configured");		return (0);	      }	    if (#ifdef SYS_SOLARIS		(ioctl(fd, TIOCSPPS, (char *)&pps_enable) < 0)#else		(ioctl(fd, I_PUSH, "ppsclock") < 0)#endif /* SYS_SOLARIS */		)	      {		msyslog(LOG_NOTICE,			"refclock_ioctl: optional ppsclock streams module unavailable");	      }	    else	      {		fdpps = fd;	      }	  }#else	if (flags & LDISC_PPS)		msyslog(LOG_NOTICE,	    "refclock_ioctl: optional ppsclock streams module unsupported");#endif /* PPS */#else /* not STREAM */#ifdef HAVE_TERMIOS#ifdef TTYCLK	/*	 * The TTYCLK option provides timestamping at the driver level. It	 * requires the tty_clk line discipline and 4.3bsd or later.	 */	if (flags & (LDISC_CLK | LDISC_CLKPPS | LDISC_ACTS)) {		(void)tcgetattr(fd, ttyp);		ttyp->c_lflag = 0;		if (flags & LDISC_CLKPPS)			ttyp->c_cc[VERASE] = ttyp->c_cc[VKILL] = '\377';		else if (flags & LDISC_ACTS) {			ttyp->c_cc[VERASE] = '*';			ttyp->c_cc[VKILL] = '#';		} else			ttyp->c_cc[VERASE] = ttyp->c_cc[VKILL] = '\n';		ttyp->c_cc[VMIN] = 1;		ttyp->c_cc[VTIME] = 0;		ttyp->c_line = CLKLDISC;		(void)tcsetattr(fd, TCSANOW, ttyp);		(void)tcflush(fd, TCIOFLUSH);	}#else	if (flags & LDISC_CLK)		msyslog(LOG_NOTICE,		"refclock_ioctl: optional clk line discipline unsupported");#endif /* TTYCLK */#ifdef CHUCLK	/*	 * The CHUCLK option provides timestamping and decoding for the CHU	 * timecode. It requires the tty_chu line disciplne and 4.3bsd	 * or later.	 */	if (flags & LDISC_CHU) {		(void)tcgetattr(fd, ttyp);		ttyp->c_lflag = 0;		ttyp->c_cc[VERASE] = ttyp->c_cc[VKILL] = '\r';		ttyp->c_cc[VMIN] = 1;		ttyp->c_cc[VTIME] = 0;		ttyp->c_line = CHULDISC;		(void)tcsetattr(fd, TCSANOW, ttyp) < 0);		(void)tcflush(fd, TCIOFLUSH);	}#else	if (flags & LDISC_CHU) {		msyslog(LOG_ERR,		"refclock_ioctl: required chu line discipline unsupported");		return (0);	}#endif /* CHUCLK */#endif /* HAVE_TERMIOS */#ifdef HAVE_BSD_TTYS#ifdef TTYCLK	/*	 * The TTYCLK option provides timestamping at the driver level. It	 * requires the tty_clk line discipline and 4.3bsd or later.	 */	if (flags & (LDISC_CLK | LDISC_CLKPPS | LDISC_ACTS)) {		int ldisc = CLKLDISC;		(void)ioctl(fd, TIOCGETP, (char *)ttyp);		if (flags & LDISC_CLKPPS)			ttyp->sg_erase = ttyp->sg_kill = '\377';		else if (flags & LDISC_ACTS) {			ttyp->sg_erase = '*';			ttyp->sg_kill = '#';		} else			ttyp->sg_erase = ttyp->sg_kill = '\r';		ttyp->sg_flags = RAW;		(void)ioctl(fd, TIOCSETP, ttyp);		if (ioctl(fd, TIOCSETD, (char *)&ldisc) < 0)			msyslog(LOG_NOTICE,	    "refclock_ioctl: optional clk line discipline unavailable");	}#else	if (flags & LDISC_CLK)		msyslog(LOG_NOTICE,	    "refclock_ioctl: optional clk line discipline unsupported");#endif /* TTYCLK */#ifdef CHUCLK	/*	 * The CHUCLK option provides timestamping and decoding for the CHU	 * timecode. It requires the tty_chu line disciplne and 4.3bsd	 * or later.	 */	if (flags & LDISC_CHU) {		int ldisc = CHULDISC;		(void)ioctl(fd, TIOCGETP, (char *)ttyp);		ttyp->sg_erase = ttyp->sg_kill = '\r';		ttyp->sg_flags = RAW;		(void)ioctl(fd, TIOCSETP, (char *)ttyp);		if (ioctl(fd, TIOCSETD, (char *)&ldisc) < 0) {			msyslog(LOG_ERR,	    "refclock_ioctl: required chu line discipline unavailable");			return (0);		}	}#else	if (flags & LDISC_CHU) {		msyslog(LOG_ERR,	    "refclock_ioctl: required chu line discipline unsupported");		return (0);	}#endif /* CHUCLK */#endif /* HAVE_BSD_TTYS */#endif /* STREAM */#endif /* HAVE_TERMIOS || HAVE_SYSV_TTYS || HAVE_BSD_TTYS */	return (1);}/* * refclock_control - set and/or return clock values * * This routine is used mainly for debugging. It returns designated * values from the interface structure that can be displayed using * xntpdc and the clockstat command. It can also be used to initialize * configuration variables, such as fudgetimes, fudgevalues, reference * ID and stratum. */voidrefclock_control(srcadr, in, out)	struct sockaddr_in *srcadr;	struct refclockstat *in;	struct refclockstat *out;{	struct peer *peer;	struct refclockproc *pp;	u_char clktype;	int unit;	/*	 * Check for valid address and running peer	 */	if (!ISREFCLOCKADR(srcadr))		return;	clktype = (u_char)REFCLOCKTYPE(srcadr);	unit = REFCLOCKUNIT(srcadr);	if (clktype >= num_refclock_conf || unit > MAXUNIT)		return;	if (!(peer = typeunit[clktype][unit]))		return;	pp = peer->procptr;	/*	 * Initialize requested data	 */	if (in != 0) {		if (in->haveflags & CLK_HAVETIME1)			pp->fudgetime1 = in->fudgetime1;		if (in->haveflags & CLK_HAVETIME2)			pp->fudgetime2 = in->fudgetime2;		if (in->haveflags & CLK_HAVEVAL1)			peer->stratum = (u_char) in->fudgeval1;		if (in->haveflags & CLK_HAVEVAL2)			pp->refid = in->fudgeval2;		if (peer->stratum <= 1)			peer->refid = pp->refid;		else			peer->refid = peer->srcadr.sin_addr.s_addr;		if (in->haveflags & CLK_HAVEFLAG1) {			pp->sloppyclockflag &= ~CLK_FLAG1;			pp->sloppyclockflag |= in->flags & CLK_FLAG1;		}		if (in->haveflags & CLK_HAVEFLAG2) {			pp->sloppyclockflag &= ~CLK_FLAG2;			pp->sloppyclockflag |= in->flags & CLK_FLAG2;          		}		if (in->haveflags & CLK_HAVEFLAG3) {			pp->sloppyclockflag &= ~CLK_FLAG3;			pp->sloppyclockflag |= in->flags & CLK_FLAG3;          		}		if (in->haveflags & CLK_HAVEFLAG4) {			pp->sloppyclockflag &= ~CLK_FLAG4;			pp->sloppyclockflag |= in->flags & CLK_FLAG4;          		}		if (in->flags & CLK_FLAG3)			(void)refclock_ioctl(pp->io.fd, LDISC_PPS);	}	/*	 * Readback requested data	 */	if (out != 0) {		out->haveflags = CLK_HAVETIME1 | CLK_HAVEVAL1 |		    CLK_HAVEVAL2 | CLK_HAVEFLAG4;		out->fudgetime1 = pp->fudgetime1;		out->fudgetime2 = pp->fudgetime2;		out->fudgeval1 = peer->stratum;		out->fudgeval2 = pp->refid;		out->flags = (u_char) pp->sloppyclockflag;		out->timereset = current_time - pp->timestarted;		out->polls = pp->polls;		out->noresponse = pp->noreply;		out->badformat = pp->badformat;		out->baddata = pp->baddata;		out->lastevent = pp->lastevent;		out->currentstatus = pp->currentstatus;		out->type = pp->type;		out->clockdesc = pp->clockdesc;		out->lencode = pp->lencode;		out->lastcode = pp->lastcode;	}	/*	 * Give the stuff to the clock	 */	if (refclock_conf[clktype]->clock_control != noentry)		(refclock_conf[clktype]->clock_control)(unit, in, out);}/* * refclock_buginfo - return debugging info * * This routine is used mainly for debugging. It returns designated * values from the interface structure that can be displayed using * xntpdc and the clkbug command. */voidrefclock_buginfo(srcadr, bug)	struct sockaddr_in *srcadr; /* clock address */	struct refclockbug *bug; /* output structure */{	struct peer *peer;	struct refclockproc *pp;	u_char clktype;	int unit;	int i;	/*	 * Check for valid address and peer structure	 */	if (!ISREFCLOCKADR(srcadr))		return;	clktype = (u_char) REFCLOCKTYPE(srcadr);	unit = REFCLOCKUNIT(srcadr);	if (clktype >= num_refclock_conf || unit > MAXUNIT)		return;	if (!(peer = typeunit[clktype][unit]))		return;	pp = peer->procptr;	/*	 * Copy structure values	 */	bug->nvalues = 8;	bug->values[0] = pp->year;	bug->values[1] = pp->day;	bug->values[2] = pp->hour;	bug->values[3] = pp->minute;	bug->values[4] = pp->second;	bug->values[5] = pp->msec;	bug->values[6] = pp->yearstart;	bug->values[7] = pp->coderecv;	bug->ntimes = pp->nstages + 3;	if (bug->ntimes > NCLKBUGTIMES)		bug->ntimes = NCLKBUGTIMES;	bug->stimes = 0xfffffffc;	bug->times[0] = pp->lastref;	bug->times[1] = pp->lastrec;	UFPTOLFP(pp->dispersion, &bug->times[2]);	for (i = 0; i < (int)bug->ntimes; i++)		bug->times[i + 3] = pp->filter[i];	/*	 * Give the stuff to the clock	 */	if (refclock_conf[clktype]->clock_buginfo != noentry)		(refclock_conf[clktype]->clock_buginfo)(unit, bug);}#endif /* REFCLOCK */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -