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

📄 refclock_ripencc.c

📁 网络时间协议NTP 源码 版本v4.2.0b 该源码用于linux平台下
💻 C
📖 第 1 页 / 共 5 页
字号:
	up->unit = unit;	up->leapdelta = 0;	up->utcflags = 0;	/*	 * Initialize the Clock	 */	/* query software versions */	cmd_0x1F(&spt);				ripencc_send(peer, spt);          	/* query receiver health */	cmd_0x26(&spt);				ripencc_send(peer, spt);	/* query serial numbers */		cmd_0x8E42q(&spt);			ripencc_send(peer, spt);  		/* query manuf params */	cmd_0x8E41q(&spt);			ripencc_send(peer, spt); 	/* i/o opts */ /* trimble manual page A30 */	cmd_0x35s(&spt, 		0x1C, 	/* position */		0x00, 	/* velocity */		0x05, 	/* timing */		0x0a); 	/* auxilary */	ripencc_send(peer, spt);		/* turn off port A */	cmd_0x3Ds (&spt,		0x0B, /* baud_out */		0x0B, /* baud_inp */		0x07, /* char_code */		0x07, /* stopbitcode */		0x01, /* output_mode */		0x00); /* input_mode */	ripencc_send(peer, spt);	/* set i/o options */	cmd_0x8E4As (&spt,		0x01, 		/* PPS on */		0x01, 		/* Timebase UTC */		0x00, 		/* polarity positive */		0., 		/* 100 ft. cable XXX make flag */		1e-6 * GPS_C); 	/* turn of biasuncert. > (1us) */	ripencc_send(peer,spt);	/* all outomatic packet output off */	cmd_0x8E4Ds(&spt,		0x00000000); /* AutoOutputMask */	ripencc_send(peer, spt);	cmd_0xBBq (&spt,		0x00); /* query primary configuration */	ripencc_send(peer,spt);	/* query PPS parameters */	cmd_0x8E4Aq (&spt); /* query PPS params */	ripencc_send(peer,spt);	/* query survey limit */	cmd_0x8E4Bq (&spt); /* query survey limit */	ripencc_send(peer,spt);#ifdef DEBUG_NCC	if (debug)		printf("ripencc_start: success\n");#endif /* DEBUG_NCC */	/*	 * Start the PPSAPI interface if it is there. Default to use	 * the assert edge and do not enable the kernel hardpps.	 */	if (time_pps_create(fd, &up->handle) < 0) {		up->handle = 0;		msyslog(LOG_ERR, "refclock_ripencc: time_pps_create failed: %m");		return (1);	}	return(ripencc_ppsapi(peer, 0, 0));}/* * ripencc_control - fudge control */static voidripencc_control(	int unit,		/* unit (not used) */	struct refclockstat *in, /* input parameters (not used) */	struct refclockstat *out, /* output parameters (not used) */	struct peer *peer	/* peer structure pointer */	){	struct refclockproc *pp;#ifdef DEBUG_NCC	msyslog(LOG_INFO,"%s()",__FUNCTION__);#endif /* DEBUG_NCC */	pp = peer->procptr;	ripencc_ppsapi(peer, pp->sloppyclockflag & CLK_FLAG2,	    pp->sloppyclockflag & CLK_FLAG3);}/* * Initialize PPSAPI */intripencc_ppsapi(	struct peer *peer,	/* peer structure pointer */	int enb_clear,		/* clear enable */	int enb_hardpps		/* hardpps enable */	){	struct refclockproc *pp;	struct ripencc_unit *up;	int capability;	pp = peer->procptr;	up = (struct ripencc_unit *)pp->unitptr;	if (time_pps_getcap(up->handle, &capability) < 0) {		msyslog(LOG_ERR,		    "refclock_ripencc: time_pps_getcap failed: %m");		return (0);	}	memset(&up->pps_params, 0, sizeof(pps_params_t));	if (enb_clear)		up->pps_params.mode = capability & PPS_CAPTURECLEAR;	else		up->pps_params.mode = capability & PPS_CAPTUREASSERT;	if (!up->pps_params.mode) {		msyslog(LOG_ERR,		    "refclock_ripencc: invalid capture edge %d",		    !enb_clear);		return (0);	}	up->pps_params.mode |= PPS_TSFMT_TSPEC;	if (time_pps_setparams(up->handle, &up->pps_params) < 0) {		msyslog(LOG_ERR,		    "refclock_ripencc: time_pps_setparams failed: %m");		return (0);	}	if (enb_hardpps) {		if (time_pps_kcbind(up->handle, PPS_KC_HARDPPS,				    up->pps_params.mode & ~PPS_TSFMT_TSPEC,				    PPS_TSFMT_TSPEC) < 0) {			msyslog(LOG_ERR,			    "refclock_ripencc: time_pps_kcbind failed: %m");			return (0);		}		pps_enable = 1;	}	peer->precision = PPS_PRECISION;#if DEBUG_NCC	if (debug) {		time_pps_getparams(up->handle, &up->pps_params);		printf(		    "refclock_ripencc: capability 0x%x version %d mode 0x%x kern %d\n",		    capability, up->pps_params.api_version,		    up->pps_params.mode, enb_hardpps);	}#endif /* DEBUG_NCC */	return (1);}/* * This function is called every 64 seconds from ripencc_receive * It will fetch the pps time  * * Return 0 on failure and 1 on success. */static intripencc_get_pps_ts(	struct ripencc_unit *up,	l_fp *tsptr	){	pps_info_t pps_info;	struct timespec timeout, ts;	double dtemp;	l_fp tstmp;#ifdef DEBUG_PPS	msyslog(LOG_INFO,"ripencc_get_pps_ts\n");#endif /* DEBUG_PPS */	/*	 * Convert the timespec nanoseconds field to ntp l_fp units.	 */ 	if (up->handle == 0)		return (0);	timeout.tv_sec = 0;	timeout.tv_nsec = 0;	memcpy(&pps_info, &up->pps_info, sizeof(pps_info_t));	if (time_pps_fetch(up->handle, PPS_TSFMT_TSPEC, &up->pps_info,	    &timeout) < 0)		return (0);	if (up->pps_params.mode & PPS_CAPTUREASSERT) {		if (pps_info.assert_sequence ==		    up->pps_info.assert_sequence)			return (0);		ts = up->pps_info.assert_timestamp;	} else if (up->pps_params.mode & PPS_CAPTURECLEAR) {		if (pps_info.clear_sequence ==		    up->pps_info.clear_sequence)			return (0);		ts = up->pps_info.clear_timestamp;	} else {		return (0);	}	if ((up->ts.tv_sec == ts.tv_sec) && (up->ts.tv_nsec == ts.tv_nsec))		return (0);	up->ts = ts;	tstmp.l_ui = ts.tv_sec + JAN_1970;	dtemp = ts.tv_nsec * FRAC / 1e9;	tstmp.l_uf = (u_int32)dtemp;#ifdef DEBUG_PPS	msyslog(LOG_INFO,"ts.tv_sec: %d\n",(int)ts.tv_sec);	msyslog(LOG_INFO,"ts.tv_nsec: %ld\n",ts.tv_nsec);#endif /* DEBUG_PPS */	*tsptr = tstmp;	return (1);}/* * ripencc_shutdown - shut down a GPS clock */static voidripencc_shutdown(int unit, struct peer *peer){	register struct ripencc_unit *up;	struct refclockproc *pp;	pp = peer->procptr;	up = (struct ripencc_unit *)pp->unitptr;	if (up->handle != 0)		time_pps_destroy(up->handle);	io_closeclock(&pp->io);	free(up);}/* * ripencc_poll - called by the transmit procedure */static voidripencc_poll(int unit, struct peer *peer){	register struct ripencc_unit *up;	struct refclockproc *pp;	TSIPPKT spt;#ifdef DEBUG_NCC	if (debug)		fprintf(stderr, "ripencc_poll(%d)\n", unit);#endif /* DEBUG_NCC */	pp = peer->procptr;	up = (struct ripencc_unit *)pp->unitptr;	if (up->pollcnt == 0)		refclock_report(peer, CEVNT_TIMEOUT);	else		up->pollcnt--;	pp->polls++;	up->polled = 1;	/* poll for UTC superpacket */	cmd_0x8EADq (&spt);	ripencc_send(peer,spt);}/* * ripencc_send - send message to clock * use the structures being created by the trimble functions! * makes the code more readable/clean */static voidripencc_send(struct peer *peer, TSIPPKT spt){	unsigned char *ip, *op;	unsigned char obuf[512];#ifdef DEBUG_RAW	{		register struct ripencc_unit *up;		register struct refclockproc *pp;			pp = peer->procptr;		up = (struct ripencc_unit *)pp->unitptr;		if (debug)			printf("ripencc_send(%d, %02X)\n", up->unit, cmd);	}#endif /* DEBUG_RAW */	ip = spt.buf;	op = obuf;	*op++ = 0x10;	*op++ = spt.code;	while (spt.len--) {		if (op-obuf > sizeof(obuf)-5) {			msyslog(LOG_ERR, "ripencc_send obuf overflow!");			refclock_report(peer, CEVNT_FAULT);			return;		}					if (*ip == 0x10)  /* byte stuffing */			*op++ = 0x10;		*op++ = *ip++;	}		*op++ = 0x10;	*op++ = 0x03;#ifdef DEBUG_RAW	if (debug) { /* print raw packet */		unsigned char *cp;		int i;		printf("ripencc_send: len %d\n", op-obuf);		for (i=1, cp=obuf; cp<op; i++, cp++) {			printf(" %02X", *cp);			if (i%10 == 0) 				printf("\n");		}		printf("\n");	}#endif /* DEBUG_RAW */	if (write(peer->procptr->io.fd, obuf, op-obuf) == -1) {			refclock_report(peer, CEVNT_FAULT);	}}/* * ripencc_receive() * * called when a packet is received on the serial port * takes care of further processing * */static voidripencc_receive(struct recvbuf *rbufp){	register struct ripencc_unit *up;	register struct refclockproc *pp;		struct peer *peer;	static TSIPPKT rpt; /* structure for current incoming TSIP report  */ 	TSIPPKT spt; /* send packet */	int ns_since_pps;				int i;	char *cp;	/* Use these variables to hold data until we decide its worth keeping */	char    rd_lastcode[BMAX];	l_fp    rd_tmp;	u_short rd_lencode;	/* msyslog(LOG_INFO, "%s",__FUNCTION__); */	/*	 * Initialize pointers and read the timecode and timestamp	 */	peer = (struct peer *)rbufp->recv_srcclock;	pp = peer->procptr;	up = (struct ripencc_unit *)pp->unitptr;	rd_lencode = refclock_gtlin(rbufp, rd_lastcode, BMAX, &rd_tmp);#ifdef DEBUG_RAW	if (debug)		fprintf(stderr, "ripencc_receive(%d)\n", up->unit);#endif /* DEBUG_RAW */#ifdef DEBUG_RAW	if (debug) { /* print raw packet */		int i;		unsigned char *cp;		printf("ripencc_receive: len %d\n", rbufp->recv_length);		for (i=1, cp=(char*)&rbufp->recv_space; i <= rbufp->recv_length; i++, cp++) {			printf(" %02X", *cp);			if (i%10 == 0) 				printf("\n");		}		printf("\n");	}#endif /* DEBUG_RAW */	cp = (char*) &rbufp->recv_space;	i=rbufp->recv_length;	while (i--) { /* loop over received chars */		tsip_input_proc(&rpt, (unsigned char) *cp++);		if (rpt.status != TSIP_PARSED_FULL)			continue;		switch (rpt.code) {		case 0x8F:	/* superpacket */			switch (rpt.buf[0]) {			case 0xAD:	/* UTC Time */				/*				 * When polling on port B the timecode 				 * is the time of the previous PPS.				 * If we completed receiving the packet 				 * less than 150ms after the turn of the second, 				 * it may have the code of the previous second.				 * We do not trust that and simply poll again				 * without even parsing it.				 *				 * More elegant would be to re-schedule the poll,				 * but I do not know (yet) how to do that cleanly.				 *				 */				/* BLA ns_since_pps = ncc_tstmp(rbufp, &trtmp); *//*   if (up->polled && ns_since_pps > -1 && ns_since_pps < 150) { */				ns_since_pps=200;				if (up->polled && ns_since_pps < 150) {					msyslog(LOG_INFO, "%s(): up->polled",__FUNCTION__);					ripencc_poll(up->unit, peer);					break;				}			        /* 				 * Parse primary utc time packet				 * and fill refclock structure 				 * from results. 				 */				if (parse0x8FAD(&rpt, peer) < 0) {						msyslog(LOG_INFO, "%s(): parse0x8FAD < 0",__FUNCTION__);						refclock_report(peer, CEVNT_BADREPLY);						break;				}				/*				 * If the PPSAPI is working, rather use its 				 * timestamps.				 * assume that the PPS occurs on the second 				 * so blow any msec				 */				if (ripencc_get_pps_ts(up, &rd_tmp) == 1) {					pp->lastrec = up->tstamp = rd_tmp;					pp->nsec = 0;				}				else					msyslog(LOG_INFO, "%s(): ripencc_get_pps_ts returns failure\n",__FUNCTION__);				if (!up->polled) { 					msyslog(LOG_INFO, "%s(): unrequested packet\n",__FUNCTION__);					/* unrequested packet */					break;				}				/* we have been polled ! */				up->polled = 0;				up->pollcnt = 2;				/* poll for next packet */				cmd_0x8E0Bq(&spt);				ripencc_send(peer,spt);								if (ns_since_pps < 0) { /* no PPS */					msyslog(LOG_INFO, "%s(): ns_since_pps < 0",__FUNCTION__);					refclock_report(peer, CEVNT_BADTIME);					break;				}				/*				 * Process the new sample in the median filter and determine the				 * reference clock offset and dispersion.  				 */				if (!refclock_process(pp)) {					msyslog(LOG_INFO, "%s(): !refclock_process",__FUNCTION__);					refclock_report(peer, CEVNT_BADTIME);					break;				}				refclock_receive(peer);				break;						case 0x0B: /* comprehensive time packet */				parse0x8F0B(&rpt, peer);				break;			default: /* other superpackets */#ifdef DEBUG_NCC				msyslog(LOG_INFO, "%s(): calling parseany",__FUNCTION__);#endif /* DEBUG_NCC */#ifdef TRIMBLE_OUTPUT_FUNC				parseany(&rpt, peer);#endif /* TRIMBLE_OUTPUT_FUNC */				break;			}			break;		case 0x4F:	/* UTC parameters, for leap info */			parse0x4F(&rpt, peer);			break;		case 0x5C:	/* sat tracking data */			parse0x5C(&rpt, peer);			break;		default: /* other packets */#ifdef TRIMBLE_OUTPUT_FUNC

⌨️ 快捷键说明

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