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

📄 refclock_nmea.c

📁 网络时间协议NTP 源码 版本v4.2.0b 该源码用于linux平台下
💻 C
📖 第 1 页 / 共 2 页
字号:
		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;	*tsptr = tstmp;	return (1);}#endif /* HAVE_PPSAPI *//* * nmea_receive - receive data from the serial interface */static voidnmea_receive(	struct recvbuf *rbufp	){	register struct nmeaunit *up;	struct refclockproc *pp;	struct peer *peer;	int month, day;	int i;	char *cp, *dp;	int cmdtype;	/* Use these variables to hold data until we decide its worth keeping */	char	rd_lastcode[BMAX];	l_fp	rd_tmp;	u_short	rd_lencode;	/*	 * Initialize pointers and read the timecode and timestamp	 */	peer = (struct peer *)rbufp->recv_srcclock;	pp = peer->procptr;	up = (struct nmeaunit *)pp->unitptr;	rd_lencode = (u_short)refclock_gtlin(rbufp, rd_lastcode, BMAX, &rd_tmp);	/*	 * There is a case that a <CR><LF> gives back a "blank" line	 */	if (rd_lencode == 0)	    return;#ifdef DEBUG	if (debug)	    printf("nmea: gpsread %d %s\n", rd_lencode,		   rd_lastcode);#endif	/*	 * We check the timecode format and decode its contents. The	 * we only care about a few of them.  The most important being	 * the $GPRMC format	 * $GPRMC,hhmmss,a,fddmm.xx,n,dddmmm.xx,w,zz.z,yyy.,ddmmyy,dd,v*CC	 * For Magellan (ColorTrak) GLL probably datum (order of sentences)	 * also mode (0,1,2,3) select sentence ANY/ALL, RMC, GGA, GLL	 * $GPGLL,3513.8385,S,14900.7851,E,232420.594,A*21  	 * $GPGGA,232420.59,3513.8385,S,14900.7851,E,1,05,3.4,00519,M,,,,*3F	 * $GPRMB,...	 * $GPRMC,232418.19,A,3513.8386,S,14900.7853,E,00.0,000.0,121199,12.,E*77	 * $GPAPB,...	 * $GPGSA,...	 * $GPGSV,...	 * $GPGSV,...	 */#define GPXXX	0#define GPRMC	1#define GPGGA	2#define GPGLL	4	cp = rd_lastcode;	cmdtype=0;	if(strncmp(cp,"$GPRMC",6)==0) {		cmdtype=GPRMC;	}	else if(strncmp(cp,"$GPGGA",6)==0) {		cmdtype=GPGGA;	}	else if(strncmp(cp,"$GPGLL",6)==0) {		cmdtype=GPGLL;	}	else if(strncmp(cp,"$GPXXX",6)==0) {		cmdtype=GPXXX;	}	else	    return;	/* See if I want to process this message type */	if ( ((peer->ttl == 0) && (cmdtype != GPRMC))           || ((peer->ttl != 0) && !(cmdtype & peer->ttl)) )		return;	pp->lencode = rd_lencode;	strcpy(pp->a_lastcode,rd_lastcode);	cp = pp->a_lastcode;	pp->lastrec = up->tstamp = rd_tmp;	up->pollcnt = 2;#ifdef DEBUG	if (debug)	    printf("nmea: timecode %d %s\n", pp->lencode,		   pp->a_lastcode);#endif	/* Grab field depending on clock string type */	switch( cmdtype ) {	    case GPRMC:		/*		 * Test for synchronization.  Check for quality byte.		 */		dp = field_parse(cp,2);		if( dp[0] != 'A')			pp->leap = LEAP_NOTINSYNC;		else			pp->leap = LEAP_NOWARNING;		/* Now point at the time field */		dp = field_parse(cp,1);		break;	    case GPGGA:		/*		 * Test for synchronization.  Check for quality byte.		 */		dp = field_parse(cp,6);		if( dp[0] == '0')			pp->leap = LEAP_NOTINSYNC;		else			pp->leap = LEAP_NOWARNING;		/* Now point at the time field */		dp = field_parse(cp,1);		break;	    case GPGLL:		/*		 * Test for synchronization.  Check for quality byte.		 */		dp = field_parse(cp,6);		if( dp[0] != 'A')			pp->leap = LEAP_NOTINSYNC;		else			pp->leap = LEAP_NOWARNING;		/* Now point at the time field */		dp = field_parse(cp,5);		break;	    case GPXXX:		return;	    default:		return;	}		/*		 *	Check time code format of NMEA		 */		if( !isdigit((int)dp[0]) ||		    !isdigit((int)dp[1]) ||		    !isdigit((int)dp[2]) ||		    !isdigit((int)dp[3]) ||		    !isdigit((int)dp[4]) ||		    !isdigit((int)dp[5])			    ) {			refclock_report(peer, CEVNT_BADREPLY);			return;		}	/*	 * Convert time and check values.	 */	pp->hour = ((dp[0] - '0') * 10) + dp[1] - '0';	pp->minute = ((dp[2] - '0') * 10) + dp[3] -  '0';	pp->second = ((dp[4] - '0') * 10) + dp[5] - '0';	/* Default to 0 milliseconds, if decimal convert milliseconds in	   one, two or three digits	*/	pp->nsec = 0; 	if (dp[6] == '.') {		if (isdigit((int)dp[7])) {			pp->nsec = (dp[7] - '0') * 100000000;			if (isdigit((int)dp[8])) {				pp->nsec += (dp[8] - '0') * 10000000;				if (isdigit((int)dp[9])) {					pp->nsec += (dp[9] - '0') * 1000000;				}			}		}	}	if (pp->hour > 23 || pp->minute > 59 || pp->second > 59	  || pp->nsec > 1000000000) {		refclock_report(peer, CEVNT_BADTIME);		return;	}	/*	 * Convert date and check values.	 */	if (cmdtype==GPRMC) {	    dp = field_parse(cp,9);	    day = dp[0] - '0';	    day = (day * 10) + dp[1] - '0';	    month = dp[2] - '0';	    month = (month * 10) + dp[3] - '0';	    pp->year = dp[4] - '0';	    pp->year = (pp->year * 10) + dp[5] - '0';	}	else {	/* only time */	    time_t tt = time(NULL);	    struct tm * t = gmtime(&tt);	    day = t->tm_mday;	    month = t->tm_mon + 1;	    pp->year= t->tm_year;	}	if (month < 1 || month > 12 || day < 1) {		refclock_report(peer, CEVNT_BADTIME);		return;	}        /* Hmmmm this will be a nono for 2100,2200,2300 but I don't think I'll be here */        /* good thing that 2000 is a leap year */	/* pp->year will be 00-99 if read from GPS, 00->  (years since 1900) from tm_year */	if (pp->year % 4) {		if (day > day1tab[month - 1]) {			refclock_report(peer, CEVNT_BADTIME);			return;		}		for (i = 0; i < month - 1; i++)		    day += day1tab[i];	} else {		if (day > day2tab[month - 1]) {			refclock_report(peer, CEVNT_BADTIME);			return;		}		for (i = 0; i < month - 1; i++)		    day += day2tab[i];	}	pp->day = day;#ifdef HAVE_PPSAPI	/*	 * If the PPSAPI is working, rather use its timestamps.	 * assume that the PPS occurs on the second so blow any msec	 */	if (nmea_pps(up, &rd_tmp) == 1) {		pp->lastrec = up->tstamp = rd_tmp;		pp->nsec = 0;	}#endif /* HAVE_PPSAPI */	/*	 * Process the new sample in the median filter and determine the	 * reference clock offset and dispersion. We use lastrec as both	 * the reference time and receive time, in order to avoid being	 * cute, like setting the reference time later than the receive	 * time, which may cause a paranoid protocol module to chuck out	 * the data.	 */	if (!refclock_process(pp)) {		refclock_report(peer, CEVNT_BADTIME);		return;	}	/*	 * Only go on if we had been polled.	 */	if (!up->polled)	    return;	up->polled = 0;	pp->lastref = pp->lastrec;	refclock_receive(peer);        /* If we get here - what we got from the clock is OK, so say so */         refclock_report(peer, CEVNT_NOMINAL);	record_clock_stats(&peer->srcadr, pp->a_lastcode);}/* * nmea_poll - called by the transmit procedure * * We go to great pains to avoid changing state here, since there may be * more than one eavesdropper receiving the same timecode. */static voidnmea_poll(	int unit,	struct peer *peer	){	register struct nmeaunit *up;	struct refclockproc *pp;	pp = peer->procptr;	up = (struct nmeaunit *)pp->unitptr;	if (up->pollcnt == 0)	    refclock_report(peer, CEVNT_TIMEOUT);	else	    up->pollcnt--;	pp->polls++;	up->polled = 1;	/*	 * usually nmea_receive can get a timestamp every second	 */	gps_send(pp->io.fd,"$PMOTG,RMC,0000*1D\r\n", peer);}/* * *	gps_send(fd,cmd, peer)  Sends a command to the GPS receiver. *	 as	gps_send(fd,"rqts,u\r", peer); * *	We don't currently send any data, but would like to send *	RTCM SC104 messages for differential positioning. It should *	also give us better time. Without a PPS output, we're *	Just fooling ourselves because of the serial code paths * */static voidgps_send(	int fd,	const char *cmd,	struct peer *peer	){	if (write(fd, cmd, strlen(cmd)) == -1) {		refclock_report(peer, CEVNT_FAULT);	}}static char *field_parse(	char *cp,	int fn	){	char *tp;	int i = fn;	for (tp = cp; *tp != '\0'; tp++) {		if (*tp == ',')		    i--;		if (i == 0)		    break;	}	return (++tp);}#elseint refclock_nmea_bs;#endif /* REFCLOCK */

⌨️ 快捷键说明

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