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

📄 refclock_msfees.c

📁 网络时间协议NTP 源码 版本v4.2.0b 该源码用于linux平台下
💻 C
📖 第 1 页 / 共 4 页
字号:
			ees_event(ees, CEVNT_BADREPLY);			ees_reset(ees);			return;		}		/* Skip the 0xff */		dpt++;		/* Finally, got a complete buffer.  Mainline code will		 * continue on. */		cp = ees->lastcode;		break;	    default:		msyslog(LOG_ERR, "ees clock: INTERNAL ERROR: %d state %d",			ees->unit, ees->codestate);		ees->reason = CODEREASON + 5;		ees_event(ees, CEVNT_FAULT);		ees_reset(ees);		return;	}	/* Boy!  After all that crap, the lastcode buffer now contains	 * something we hope will be a valid time code.  Do length	 * checks and sanity checks on constant data.	 */	ees->codestate = EESCS_WAIT;	ees->lasttime = current_time;	if (ees->lencode != LENEESPRT) {		ees->badformat++;		ees->reason = CODEREASON + 6;		ees_event(ees, CEVNT_BADREPLY);		ees_reset(ees);		return;	}	cp = ees->lastcode;	/* Check that centisecond is zero */	if (cp[EESM_CSEC] != 0) {		ees->baddata++;		ees->reason = CODEREASON + 7;		ees_event(ees, CEVNT_BADREPLY);		ees_reset(ees);		return;	}	/* Check flag formats */	if (cp[EESM_LEAP] != 0 && cp[EESM_LEAP] != 0x0f) {		ees->badformat++;		ees->reason = CODEREASON + 8;		ees_event(ees, CEVNT_BADREPLY);		ees_reset(ees);		return;	}	if (cp[EESM_BST] != 0 && cp[EESM_BST] != 0x03) {		ees->badformat++;		ees->reason = CODEREASON + 9;		ees_event(ees, CEVNT_BADREPLY);		ees_reset(ees);		return;	}	if (cp[EESM_MSFOK] != 0 && cp[EESM_MSFOK] != 0x3f) {		ees->badformat++;		ees->reason = CODEREASON + 10;		ees_event(ees, CEVNT_BADREPLY);		ees_reset(ees);		return;	}	/* So far, so good.  Compute day, hours, minutes, seconds,	 * time zone.  Do range checks on these.	 */#define bcdunpack(val)	( (((val)>>4) & 0x0f) * 10 + ((val) & 0x0f) )#define istrue(x)	((x)?1:0)	ees->second  = bcdunpack(cp[EESM_SEC]);  /* second       */	ees->minute  = bcdunpack(cp[EESM_MIN]);  /* minute       */	ees->hour    = bcdunpack(cp[EESM_HOUR]); /* hour         */	day          = bcdunpack(cp[EESM_DAY]);  /* day of month */	switch (bcdunpack(cp[EESM_MON])) {       /* month        */		/*  Add in lengths of all previous months.  Add one more		    if it is a leap year and after February.		*/	    case 12:	day += NOV;			  /*FALLSTHROUGH*/	    case 11:	day += OCT;			  /*FALLSTHROUGH*/	    case 10:	day += SEP;			  /*FALLSTHROUGH*/	    case  9:	day += AUG;			  /*FALLSTHROUGH*/	    case  8:	day += JUL;			  /*FALLSTHROUGH*/	    case  7:	day += JUN;			  /*FALLSTHROUGH*/	    case  6:	day += MAY;			  /*FALLSTHROUGH*/	    case  5:	day += APR;			  /*FALLSTHROUGH*/	    case  4:	day += MAR;			  /*FALLSTHROUGH*/	    case  3:	day += FEB;		if (istrue(cp[EESM_LEAP])) day++; /*FALLSTHROUGH*/	    case  2:	day += JAN;			  /*FALLSTHROUGH*/	    case  1:	break;	    default:	ees->baddata++;		ees->reason = CODEREASON + 11;		ees_event(ees, CEVNT_BADDATE);		ees_reset(ees);		return;	}	ees->day     = day;	/* Get timezone. The clocktime routine wants the number	 * of hours to add to the delivered time to get UT.	 * Currently -1 if BST flag set, 0 otherwise.  This	 * is the place to tweak things if double summer time	 * ever happens.	 */	ees->tz      = istrue(cp[EESM_BST]) ? -1 : 0;	if (ees->day > 366 || ees->day < 1 ||	    ees->hour > 23 || ees->minute > 59 || ees->second > 59) {		ees->baddata++;		ees->reason = CODEREASON + 12;		ees_event(ees, CEVNT_BADDATE);		ees_reset(ees);		return;	}	n_sample = ees->nsamples;	/* Now, compute the reference time value: text -> tmp.l_ui */	if (!clocktime(ees->day, ees->hour, ees->minute, ees->second,		       ees->tz, rbufp->recv_time.l_ui, &ees->yearstart,		       &tmp.l_ui)) {		ees->baddata++;		ees->reason = CODEREASON + 13;		ees_event(ees, CEVNT_BADDATE);		ees_reset(ees);		return;	}	tmp.l_uf = 0;	/*  DON'T use ees->arrvtime -- it may be < reftime */	ees->lastsampletime = tmp;	/* If we are synchronised to the radio, update the reference time.	 * Also keep a note of when clock was last good.	 */	if (istrue(cp[EESM_MSFOK])) {		ees->reftime = tmp;		ees->clocklastgood = current_time;	}	/* Compute the offset.  For the fractional part of the	 * offset we use the expected delay for the message.	 */	ees->codeoffsets[n_sample].l_ui = tmp.l_ui;	ees->codeoffsets[n_sample].l_uf = 0;	/* Number of seconds since the last step */	sincelast = this_uisec - ees->last_step;	memset((char *) &ppsclockev, 0, sizeof ppsclockev);	rc = ioctl(ees->io.fd, request, (char *) &ppsclockev);	if (debug & DB_PRINT_EV) fprintf(stderr,					 "[%x] CIOGETEV u%d %d (%x %d) gave %d (%d): %08lx %08lx %ld\n",					 DB_PRINT_EV, ees->unit, ees->io.fd, request, is_pps(ees),					 rc, errno, ptr[0], ptr[1], ptr[2]);	/* If we managed to get the time of arrival, process the info */	if (rc >= 0) {		int conv = -1;		pps_step = ppsclockev.serial - ees->last_pps_no;		/* Possible that PPS triggered, but text message didn't */		if (pps_step == 2) msyslog(LOG_ERR, "pps step = 2 @ %02d", ees->second);		if (pps_step == 2 && ees->second == 1) suspect_4ms_step |= 1;		if (pps_step == 2 && ees->second == 2) suspect_4ms_step |= 4;		/* allow for single loss of PPS only */		if (pps_step != 1 && pps_step != 2)		    fprintf(stderr, "PPS step: %d too far off %ld (%d)\n",			    ppsclockev.serial, ees->last_pps_no, pps_step);		else if (!buftvtots((char *) &(ppsclockev.tv), &pps_arrvstamp))		    fprintf(stderr, "buftvtots failed\n");		else {	/* if ((ABS(time difference) - 0.25) < 0)			 * then believe it ...			 */			l_fp diff;			diff = pps_arrvstamp;			conv = 0;			L_SUB(&diff, &ees->arrvtime);			if (debug & DB_PRINT_CDT)			    printf("[%x] Have %lx.%08lx and %lx.%08lx -> %lx.%08lx @ %s",				   DB_PRINT_CDT, (long)ees->arrvtime.l_ui, (long)ees->arrvtime.l_uf,				   (long)pps_arrvstamp.l_ui, (long)pps_arrvstamp.l_uf,				   (long)diff.l_ui, (long)diff.l_uf,				   ctime(&(ppsclockev.tv.tv_sec)));			if (L_ISNEG(&diff)) M_NEG(diff.l_ui, diff.l_uf);			L_SUB(&diff, &acceptable_slop);			if (L_ISNEG(&diff)) {	/* AOK -- pps_sample */				ees->arrvtime = pps_arrvstamp;				conv++;				call_pps_sample++;			}			/* Some loss of some signals around sec = 1 */			else if (ees->second == 1) {				diff = pps_arrvstamp;				L_ADD(&diff, &onesec);				L_SUB(&diff, &ees->arrvtime);				if (L_ISNEG(&diff)) M_NEG(diff.l_ui, diff.l_uf);				L_SUB(&diff, &acceptable_slop);				msyslog(LOG_ERR, "Have sec==1 slip %ds a=%08x-p=%08x -> %x.%08x (u=%d) %s",					pps_arrvstamp.l_ui - ees->arrvtime.l_ui,					pps_arrvstamp.l_uf,					ees->arrvtime.l_uf,					diff.l_ui, diff.l_uf,					(int)ppsclockev.tv.tv_usec,					ctime(&(ppsclockev.tv.tv_sec)));				if (L_ISNEG(&diff)) {	/* AOK -- pps_sample */					suspect_4ms_step |= 2;					ees->arrvtime = pps_arrvstamp;					L_ADD(&ees->arrvtime, &onesec);					conv++;					call_pps_sample++;				}			}		}		ees->last_pps_no = ppsclockev.serial;		if (debug & DB_PRINT_CDTC)		    printf(			    "[%x] %08lx %08lx %d u%d (%d %d)\n",			    DB_PRINT_CDTC, (long)pps_arrvstamp.l_ui,			    (long)pps_arrvstamp.l_uf, conv, ees->unit,			    call_pps_sample, pps_step);	}	/* See if there has been a 4ms jump at a minute boundry */	{	l_fp	delta;#define	delta_isec	delta.l_ui#define	delta_ssec	delta.l_i#define	delta_sfsec	delta.l_f	long	delta_f_abs;	delta.l_i = ees->arrvtime.l_i;	delta.l_f = ees->arrvtime.l_f;	L_SUB(&delta, &ees->last_l);	delta_f_abs = delta_sfsec;	if (delta_f_abs < 0) delta_f_abs = -delta_f_abs;	/* Dump the deltas each minute */	if (debug & DB_DUMP_DELTAS)	{	if (/*0 <= ees->second && */		ees->second < ((sizeof deltas) / (sizeof deltas[0]))) deltas[ees->second] = delta_sfsec;	/* Dump on second 1, as second 0 sometimes missed */	if (ees->second == 1) {		char text[16 * ((sizeof deltas) / (sizeof deltas[0]))];		char *cptr=text;		int i;		for (i=0; i<((sizeof deltas) / (sizeof deltas[0])); i++) {			sprintf(cptr, " %d.%04d",				msec(deltas[i]), subms(deltas[i]));			while (*cptr) cptr++;		}		msyslog(LOG_ERR, "Deltas: %d.%04d<->%d.%04d: %s",			msec(EES_STEP_F - EES_STEP_F_GRACE), subms(EES_STEP_F - EES_STEP_F_GRACE),			msec(EES_STEP_F + EES_STEP_F_GRACE), subms(EES_STEP_F + EES_STEP_F_GRACE),			text+1);		for (i=0; i<((sizeof deltas) / (sizeof deltas[0])); i++) deltas[i] = 0;	}	}	/* Lets see if we have a 4 mS step at a minute boundaary */	if (	((EES_STEP_F - EES_STEP_F_GRACE) < delta_f_abs) &&		(delta_f_abs < (EES_STEP_F + EES_STEP_F_GRACE)) &&		(ees->second == 0 || ees->second == 1 || ees->second == 2) &&		(sincelast < 0 || sincelast > 122)		) {	/* 4ms jump at min boundry */		int old_sincelast;		int count=0;		int sum = 0;		/* Yes -- so compute the ramp time */		if (ees->last_step == 0) sincelast = 0;		old_sincelast = sincelast;		/* First time in, just set "ees->last_step" */		if(ees->last_step) {			int other_step = 0;			int third_step = 0;			int this_step = (sincelast + (60 /2)) / 60;			int p_step = ees->this_step;			int p;			ees->last_steps[p_step] = this_step;			p= p_step;			p_step++;			if (p_step >= LAST_STEPS) p_step = 0;			ees->this_step = p_step;				/* Find the "average" interval */			while (p != p_step) {				int this = ees->last_steps[p];				if (this == 0) break;				if (this != this_step) {					if (other_step == 0 && (						this== (this_step +2) ||						this== (this_step -2) ||						this== (this_step +1) ||						this== (this_step -1)))					    other_step = this;					if (other_step != this) {						int idelta = (this_step - other_step);						if (idelta < 0) idelta = - idelta;						if (third_step == 0 && (							(idelta == 1) ? (								this == (other_step +1) ||								this == (other_step -1) ||								this == (this_step +1) ||								this == (this_step -1))							:							(								this == (this_step + other_step)/2								)							)) third_step = this;						if (third_step != this) break;					}				}				sum += this;				p--;				if (p < 0) p += LAST_STEPS;				count++;			}			msyslog(LOG_ERR, "MSF%d: %d: This=%d (%d), other=%d/%d, sum=%d, count=%d, pps_step=%d, suspect=%x", ees->unit, p, ees->last_steps[p], this_step, other_step, third_step, sum, count, pps_step, suspect_4ms_step);			if (count != 0) sum = ((sum * 60) + (count /2)) / count;#define	SV(x) (ees->last_steps[(x + p_step) % LAST_STEPS])			msyslog(LOG_ERR, "MSF%d: %x steps %d: %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d",				ees->unit, suspect_4ms_step, p_step, SV(0), SV(1), SV(2), SV(3), SV(4), SV(5), SV(6),				SV(7), SV(8), SV(9), SV(10), SV(11), SV(12), SV(13), SV(14), SV(15));			printf("MSF%d: steps %d: %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n",			       ees->unit, p_step, SV(0), SV(1), SV(2), SV(3), SV(4), SV(5), SV(6),			       SV(7), SV(8), SV(9), SV(10), SV(11), SV(12), SV(13), SV(14), SV(15));#undef SV			ees->jump_fsecs = delta_sfsec;			ees->using_ramp = 1;			if (sincelast > 170)			    ees->last_step_late += sincelast - ((sum) ? sum : ees->last_step_secs);			else ees->last_step_late = 30;			if (ees->last_step_late < -60 || ees->last_step_late > 120) ees->last_step_late = 30;			if (ees->last_step_late < 0) ees->last_step_late = 0;			if (ees->last_step_late >= 60) ees->last_step_late = 59;			sincelast = 0;		}		else {	/* First time in -- just save info */			ees->last_step_late = 30;			ees->jump_fsecs = delta_sfsec;			ees->using_ramp = 1;			sum = 4 * 60;		}		ees->last_step = this_uisec;		printf("MSF%d: d=%3ld.%04ld@%d :%d:%d:$%d:%d:%d\n",		       ees->unit, (long)msec(delta_sfsec), (long)subms(delta_sfsec),		       ees->second, old_sincelast, ees->last_step_late, count, sum,		       ees->last_step_secs);		msyslog(LOG_ERR, "MSF%d: d=%3d.%04d@%d :%d:%d:%d:%d:%d",

⌨️ 快捷键说明

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