Ejemplo n.º 1
0
/*Local clock is becoming Master. Table 13 (9.3.5) of the spec.*/
void m1(RunTimeOpts *rtOpts, PtpClock *ptpClock)
{
	/*Current data set update*/
	ptpClock->stepsRemoved = 0;
	
	clearTime(&ptpClock->offsetFromMaster);
	clearTime(&ptpClock->meanPathDelay);

	/*Parent data set*/
	copyClockIdentity(ptpClock->parentPortIdentity.clockIdentity,
	       ptpClock->clockIdentity);
	ptpClock->parentPortIdentity.portNumber = 0;
	ptpClock->parentStats = DEFAULT_PARENTS_STATS;
	ptpClock->observedParentClockPhaseChangeRate = 0;
	ptpClock->observedParentOffsetScaledLogVariance = 0;
	copyClockIdentity(ptpClock->grandmasterIdentity,
			ptpClock->clockIdentity);
	ptpClock->grandmasterClockQuality.clockAccuracy = 
		ptpClock->clockQuality.clockAccuracy;
	ptpClock->grandmasterClockQuality.clockClass = 
		ptpClock->clockQuality.clockClass;
	ptpClock->grandmasterClockQuality.offsetScaledLogVariance = 
		ptpClock->clockQuality.offsetScaledLogVariance;
	ptpClock->grandmasterPriority1 = ptpClock->priority1;
	ptpClock->grandmasterPriority2 = ptpClock->priority2;

	/*Time Properties data set*/
	ptpClock->timeSource = INTERNAL_OSCILLATOR;

	/* UTC vs TAI timescales */
	ptpClock->currentUtcOffsetValid = DEFAULT_UTC_VALID;
	ptpClock->currentUtcOffset = rtOpts->currentUtcOffset;
	
}
Ejemplo n.º 2
0
/*Copy local data set into header and announce message. 9.3.4 table 12*/
void copyD0(MsgHeader *header, MsgAnnounce *announce, PtpClock *ptpClock)
{
	announce->grandmasterPriority1 = ptpClock->priority1;
	copyClockIdentity(announce->grandmasterIdentity,
			ptpClock->clockIdentity);
	announce->grandmasterClockQuality.clockClass = 
		ptpClock->clockQuality.clockClass;
	announce->grandmasterClockQuality.clockAccuracy = 
		ptpClock->clockQuality.clockAccuracy;
	announce->grandmasterClockQuality.offsetScaledLogVariance = 
		ptpClock->clockQuality.offsetScaledLogVariance;
	announce->grandmasterPriority2 = ptpClock->priority2;
	announce->stepsRemoved = 0;
	copyClockIdentity(header->sourcePortIdentity.clockIdentity,
	       ptpClock->clockIdentity);
}
Ejemplo n.º 3
0
Archivo: bmc.c Proyecto: zhlinh/ptpd2
/**
 * 本地时钟即将进入PTP_MASTER状态
 */
void m1(const RunTimeOpts *rtOpts, PtpClock *ptpClock)
{
	/*Current data set update*/
	ptpClock->stepsRemoved = 0;
	
	clearTime(&ptpClock->offsetFromMaster);
	clearTime(&ptpClock->meanPathDelay);

	copyClockIdentity(ptpClock->parentPortIdentity.clockIdentity,
	       ptpClock->clockIdentity);

	ptpClock->parentPortIdentity.portNumber = ptpClock->portIdentity.portNumber;
	ptpClock->parentStats = DEFAULT_PARENTS_STATS;
	ptpClock->observedParentClockPhaseChangeRate = 0;
	ptpClock->observedParentOffsetScaledLogVariance = 0;
	copyClockIdentity(ptpClock->grandmasterIdentity,
			ptpClock->clockIdentity);
	ptpClock->grandmasterClockQuality.clockAccuracy = 
		ptpClock->clockQuality.clockAccuracy;
	ptpClock->grandmasterClockQuality.clockClass = 
		ptpClock->clockQuality.clockClass;
	ptpClock->grandmasterClockQuality.offsetScaledLogVariance = 
		ptpClock->clockQuality.offsetScaledLogVariance;
	ptpClock->grandmasterPriority1 = ptpClock->priority1;
	ptpClock->grandmasterPriority2 = ptpClock->priority2;
        ptpClock->logMinDelayReqInterval = rtOpts->logMinDelayReqInterval;

	/*Time Properties data set*/
	ptpClock->timePropertiesDS.currentUtcOffsetValid = rtOpts->timeProperties.currentUtcOffsetValid;
	ptpClock->timePropertiesDS.currentUtcOffset = rtOpts->timeProperties.currentUtcOffset;
	ptpClock->timePropertiesDS.timeTraceable = rtOpts->timeProperties.timeTraceable;
	ptpClock->timePropertiesDS.frequencyTraceable = rtOpts->timeProperties.frequencyTraceable;
	ptpClock->timePropertiesDS.ptpTimescale = rtOpts->timeProperties.ptpTimescale;
	ptpClock->timePropertiesDS.timeSource = rtOpts->timeProperties.timeSource;

	if(ptpClock->timePropertiesDS.ptpTimescale &&
	    (secondsToMidnight() < rtOpts->leapSecondNoticePeriod)) {
	    ptpClock->timePropertiesDS.leap59 = ptpClock->clockStatus.leapDelete;
	    ptpClock->timePropertiesDS.leap61 = ptpClock->clockStatus.leapInsert;
	} else {
	    ptpClock->timePropertiesDS.leap59 = FALSE;
	    ptpClock->timePropertiesDS.leap61 = FALSE;
	}

}
Ejemplo n.º 4
0
/* Init ptpClock with run time values (initialization constants are in constants.h)*/
void initData(RunTimeOpts *rtOpts, PtpClock *ptpClock)
{
	int i,j;
	j=0;
	DBG("initData\n");
	
	/* Default data set */
	ptpClock->twoStepFlag = TWO_STEP_FLAG;

	/*
	 * init clockIdentity with MAC address and 0xFF and 0xFE. see
	 * spec 7.5.2.2.2
	 */
	for (i=0;i<CLOCK_IDENTITY_LENGTH;i++)
	{
		if (i==3) ptpClock->clockIdentity[i]=0xFF;
		else if (i==4) ptpClock->clockIdentity[i]=0xFE;
		else
		{
		  ptpClock->clockIdentity[i]=ptpClock->port_uuid_field[j];
		  j++;
		}
	}
	ptpClock->numberPorts = NUMBER_PORTS;

	ptpClock->clockQuality.clockAccuracy = 
		rtOpts->clockQuality.clockAccuracy;
	ptpClock->clockQuality.clockClass = rtOpts->clockQuality.clockClass;
	ptpClock->clockQuality.offsetScaledLogVariance = 
		rtOpts->clockQuality.offsetScaledLogVariance;

	ptpClock->priority1 = rtOpts->priority1;
	ptpClock->priority2 = rtOpts->priority2;

	ptpClock->domainNumber = rtOpts->domainNumber;
	ptpClock->slaveOnly = rtOpts->slaveOnly;
	if(rtOpts->slaveOnly)
		rtOpts->clockQuality.clockClass = SLAVE_ONLY_CLOCK_CLASS;

/* Port configuration data set */

	/*
	 * PortIdentity Init (portNumber = 1 for an ardinary clock spec
	 * 7.5.2.3)
	 */
	copyClockIdentity(ptpClock->portIdentity.clockIdentity,
			ptpClock->clockIdentity);
	ptpClock->portIdentity.portNumber = NUMBER_PORTS;

	/* select the initial rate of delayreqs until we receive the first announce message */
	ptpClock->logMinDelayReqInterval = rtOpts->initial_delayreq;

	clearTime(&ptpClock->peerMeanPathDelay);

	ptpClock->logAnnounceInterval = rtOpts->announceInterval;
	ptpClock->announceReceiptTimeout = rtOpts->announceReceiptTimeout;
	ptpClock->logSyncInterval = rtOpts->syncInterval;
	ptpClock->delayMechanism = rtOpts->delayMechanism;
	ptpClock->logMinPdelayReqInterval = DEFAULT_PDELAYREQ_INTERVAL;
	ptpClock->versionNumber = VERSION_PTP;

 	/*
	 *  Initialize random number generator using same method as ptpv1:
	 *  seed is now initialized from the last bytes of our mac addres (collected in net.c:findIface())
	 */
	srand((ptpClock->port_uuid_field[PTP_UUID_LENGTH - 1] << 8) + ptpClock->port_uuid_field[PTP_UUID_LENGTH - 2]);

	/*Init other stuff*/
	ptpClock->number_foreign_records = 0;
  	ptpClock->max_foreign_records = rtOpts->max_foreign_records;
}
Ejemplo n.º 5
0
/*Local clock is synchronized to Ebest Table 16 (9.3.5) of the spec*/
void s1(MsgHeader *header,MsgAnnounce *announce,PtpClock *ptpClock, RunTimeOpts *rtOpts)
{

	Boolean previousLeap59 = FALSE, previousLeap61 = FALSE;
	Integer16 previousUtcOffset = 0;

	if (ptpClock->portState == PTP_SLAVE) {
		previousLeap59 = ptpClock->leap59;
		previousLeap61 = ptpClock->leap61;
		previousUtcOffset = ptpClock->currentUtcOffset;
	}

	/* Current DS */
	ptpClock->stepsRemoved = announce->stepsRemoved + 1;

	/* Parent DS */
	copyClockIdentity(ptpClock->parentPortIdentity.clockIdentity,
	       header->sourcePortIdentity.clockIdentity);
	ptpClock->parentPortIdentity.portNumber = 
		header->sourcePortIdentity.portNumber;
	copyClockIdentity(ptpClock->grandmasterIdentity,
			announce->grandmasterIdentity);
	ptpClock->grandmasterClockQuality.clockAccuracy = 
		announce->grandmasterClockQuality.clockAccuracy;
	ptpClock->grandmasterClockQuality.clockClass = 
		announce->grandmasterClockQuality.clockClass;
	ptpClock->grandmasterClockQuality.offsetScaledLogVariance = 
		announce->grandmasterClockQuality.offsetScaledLogVariance;
	ptpClock->grandmasterPriority1 = announce->grandmasterPriority1;
	ptpClock->grandmasterPriority2 = announce->grandmasterPriority2;

	/* Timeproperties DS */
	ptpClock->currentUtcOffset = announce->currentUtcOffset;

        /* "Valid" is bit 2 in second octet of flagfield */
        ptpClock->currentUtcOffsetValid = IS_SET(header->flagField1, UTCV);

	/* set PTP_PASSIVE-specific state */
	p1(ptpClock, rtOpts);

	/* only set leap state in slave mode */
	if (ptpClock->portState == PTP_SLAVE) {
		ptpClock->leap59 = IS_SET(header->flagField1, LI59);
		ptpClock->leap61 = IS_SET(header->flagField1, LI61);
	}

        ptpClock->timeTraceable = IS_SET(header->flagField1, TTRA);
        ptpClock->frequencyTraceable = IS_SET(header->flagField1, FTRA);
        ptpClock->ptpTimescale = IS_SET(header->flagField1, PTPT);
        ptpClock->timeSource = announce->timeSource;

#if defined(MOD_TAI) &&  NTP_API == 4
	/*
	 * update kernel TAI offset, but only if timescale is
	 * PTP not ARB - spec section 7.2
	 */
        if (ptpClock->ptpTimescale &&
            (ptpClock->currentUtcOffset != previousUtcOffset)) {
		setKernelUtcOffset(ptpClock->currentUtcOffset);
        }
#endif /* MOD_TAI */

	/* Leap second handling */

        if (ptpClock->portState == PTP_SLAVE) {
		if(ptpClock->leap59 && ptpClock->leap61) {
			ERROR("Both Leap59 and Leap61 flags set!\n");
			toState(PTP_FAULTY, rtOpts, ptpClock);
			return;
		}

		/* one of the leap second flags has suddenly been unset */
		if(ptpClock->leapSecondPending && 
		    !ptpClock->leapSecondInProgress &&
		    ((previousLeap59 != ptpClock->leap59) || 
		     (previousLeap61 != ptpClock->leap61))) {
			WARNING("=== Leap second event aborted by GM!");
			ptpClock->leapSecondPending = FALSE;
			ptpClock->leapSecondInProgress = FALSE;
			timerStop(LEAP_SECOND_PAUSE_TIMER, ptpClock->itimer);
      /** FIXME dumblob */
#if !defined(__APPLE__) && !defined(__QNXNTO__)
			unsetTimexFlags(STA_INS | STA_DEL,TRUE);
#endif /* apple */
		}

		/*
		 * one of the leap second flags has been set
		 * or flags are lit but we have no event pending
		 */
		if( (ptpClock->leap59 || ptpClock->leap61) && (
		    (!ptpClock->leapSecondPending && 
		    !ptpClock->leapSecondInProgress ) ||
		    ((!previousLeap59 && ptpClock->leap59) ||
		    (!previousLeap61 && ptpClock->leap61)))) {
#if !defined(__APPLE__) && !defined(__QNXNTO__)
			WARNING("=== Leap second pending! Setting kernel to %s "
				"one second at midnight\n",
				ptpClock->leap61 ? "add" : "delete");
		    if (!checkTimexFlags(ptpClock->leap61 ? STA_INS : STA_DEL)) {
			    unsetTimexFlags(ptpClock->leap61 ? STA_DEL : STA_INS,
					    TRUE);
			    setTimexFlags(ptpClock->leap61 ? STA_INS : STA_DEL,
					  FALSE);
		    }
#else
			WARNING("=== Leap second pending! No kernel leap second "
				"API support - expect a clock jump at "
				"midnight!\n");
#endif /* apple */
			/* only set the flag, the rest happens in doState() */
			ptpClock->leapSecondPending = TRUE;
		}

		if((previousUtcOffset != ptpClock->currentUtcOffset) && 
		   !ptpClock->leapSecondPending && 
		   !ptpClock->leapSecondInProgress ) {
			WARNING("=== UTC offset changed from %d to %d with "
				"no leap second pending!\n",
				previousUtcOffset, ptpClock->currentUtcOffset);
		} else if( previousUtcOffset != ptpClock->currentUtcOffset) {
			WARNING("=== UTC offset changed from %d to %d\n",
				previousUtcOffset,ptpClock->currentUtcOffset);
		}
	}
}
Ejemplo n.º 6
0
Archivo: bmc.c Proyecto: zhlinh/ptpd2
/**
 * 本时钟同步到最佳主时钟Ebest
 */
void s1(MsgHeader *header,MsgAnnounce *announce,PtpClock *ptpClock, const RunTimeOpts *rtOpts)
{

	Boolean previousLeap59 = FALSE;
	Boolean previousLeap61 = FALSE;

	Boolean leapChange = FALSE;

	Integer16 previousUtcOffset = 0;

	/**
	 * Leap59: 为真时,上一分钟只有59秒(而不是60秒)
	 * Leap61: 为真时,上一分钟只有61秒(而不是60秒)
	 */
	previousLeap59 = ptpClock->timePropertiesDS.leap59;
	previousLeap61 = ptpClock->timePropertiesDS.leap61;

	/**
	* International Atomic Time (TAI)和Coordinated Universal Time (UTC)之间的差值
	* 2012年1月时,该值为34秒
	*/
	previousUtcOffset = ptpClock->timePropertiesDS.currentUtcOffset;

	/* Current DS */
	ptpClock->stepsRemoved = announce->stepsRemoved + 1;

	/* Parent DS */
	copyClockIdentity(ptpClock->parentPortIdentity.clockIdentity,
	       header->sourcePortIdentity.clockIdentity);
	ptpClock->parentPortIdentity.portNumber = 
		header->sourcePortIdentity.portNumber;
	copyClockIdentity(ptpClock->grandmasterIdentity,
			announce->grandmasterIdentity);
	ptpClock->grandmasterClockQuality.clockAccuracy = 
		announce->grandmasterClockQuality.clockAccuracy;
	ptpClock->grandmasterClockQuality.clockClass = 
		announce->grandmasterClockQuality.clockClass;
	ptpClock->grandmasterClockQuality.offsetScaledLogVariance = 
		announce->grandmasterClockQuality.offsetScaledLogVariance;
	ptpClock->grandmasterPriority1 = announce->grandmasterPriority1;
	ptpClock->grandmasterPriority2 = announce->grandmasterPriority2;

	/* use the granted interval if using signaling, otherwise we would try to arm a timer for 2^127! */
	if(rtOpts->unicastNegotiation && ptpClock->parentGrants != NULL && ptpClock->parentGrants->grantData[ANNOUNCE].granted) {
            ptpClock->logAnnounceInterval = ptpClock->parentGrants->grantData[ANNOUNCE].logInterval;
        } else if (header->logMessageInterval != UNICAST_MESSAGEINTERVAL) {
    	    ptpClock->logAnnounceInterval = header->logMessageInterval;
	}

	/* Timeproperties DS */
	ptpClock->timePropertiesDS.currentUtcOffset = announce->currentUtcOffset;

	if (ptpClock->portState != PTP_PASSIVE && ptpClock->timePropertiesDS.currentUtcOffsetValid && 
			!IS_SET(header->flagField1, UTCV)) {
		if(rtOpts->alwaysRespectUtcOffset)
			WARNING("UTC Offset no longer valid and ptpengine:always_respect_utc_offset is set: continuing as normal\n");
		else
			WARNING("UTC Offset no longer valid - clock jump expected\n");
	}

        /* "Valid" is bit 2 in second octet of flagfield */
        ptpClock->timePropertiesDS.currentUtcOffsetValid = IS_SET(header->flagField1, UTCV);

	/* set PTP_PASSIVE-specific state */
	/**
	 * 如果当前为PTP_PASSIVE状态,则重置@timePropertiesDS为初始化的设置值
	 */
	p1(ptpClock, rtOpts);

	/* only set leap flags in slave state - info from leap file takes priority*/
	/**
	 * 只有当前为PTP_SLAVE状态,才更新@leap59和@leap61
	 */
	if (ptpClock->portState == PTP_SLAVE) {
	    if(ptpClock->clockStatus.override) {
		ptpClock->timePropertiesDS.currentUtcOffset = ptpClock->clockStatus.utcOffset;
		ptpClock->timePropertiesDS.leap59 = ptpClock->clockStatus.leapDelete;
		ptpClock->timePropertiesDS.leap61 = ptpClock->clockStatus.leapInsert;
	    } else {
		ptpClock->timePropertiesDS.leap59 = IS_SET(header->flagField1, LI59);
		ptpClock->timePropertiesDS.leap61 = IS_SET(header->flagField1, LI61);
	    }
	}
Ejemplo n.º 7
0
Archivo: bmc.c Proyecto: da-phil/ptpd
/* Init ptpClock with run time values (initialization constants are in constants.h)*/
void initData(RunTimeOpts *rtOpts, PtpClock *ptpClock)
{
	int i,j;
	j=0;
	DBG("initData\n");
	
	/* Default data set */
	ptpClock->twoStepFlag = TWO_STEP_FLAG;

	/*
	 * init clockIdentity with MAC address and 0xFF and 0xFE. see
	 * spec 7.5.2.2.2
	 */
	for (i=0;i<CLOCK_IDENTITY_LENGTH;i++)
	{
		if (i==3) ptpClock->clockIdentity[i]=0xFF;
		else if (i==4) ptpClock->clockIdentity[i]=0xFE;
		else
		{
		  ptpClock->clockIdentity[i]=ptpClock->netPath.interfaceID[j];
		  j++;
		}
	}

	if(rtOpts->pidAsClockId) {
	    uint16_t pid = htons(getpid());
	    memcpy(ptpClock->clockIdentity + 3, &pid, 2);
	}

	ptpClock->bestMaster = NULL;
	ptpClock->numberPorts = NUMBER_PORTS;

	ptpClock->disabled = rtOpts->portDisabled;

	memset(ptpClock->userDescription, 0, sizeof(ptpClock->userDescription));
	memcpy(ptpClock->userDescription, rtOpts->portDescription, strlen(rtOpts->portDescription));

	memset(&ptpClock->profileIdentity,0,6);

	if(rtOpts->ipMode == IPMODE_UNICAST && rtOpts->unicastNegotiation) {
		memcpy(&ptpClock->profileIdentity, &PROFILE_ID_TELECOM,6);
	}

	if(rtOpts->ipMode == IPMODE_MULTICAST &&rtOpts->delayMechanism == E2E) {
		memcpy(&ptpClock->profileIdentity, &PROFILE_ID_DEFAULT_E2E,6);
	}

	if(rtOpts->ipMode == IPMODE_MULTICAST &&rtOpts->delayMechanism == P2P) {
		memcpy(&ptpClock->profileIdentity, &PROFILE_ID_DEFAULT_P2P,6);
	}

	if(rtOpts->dot1AS) {
		memcpy(&ptpClock->profileIdentity, &PROFILE_ID_802_1AS,6);
	}

	ptpClock->clockQuality.clockAccuracy = 
		rtOpts->clockQuality.clockAccuracy;
	ptpClock->clockQuality.clockClass = rtOpts->clockQuality.clockClass;
	ptpClock->clockQuality.offsetScaledLogVariance = 
		rtOpts->clockQuality.offsetScaledLogVariance;

	ptpClock->priority1 = rtOpts->priority1;
	ptpClock->priority2 = rtOpts->priority2;

	ptpClock->domainNumber = rtOpts->domainNumber;

	if(rtOpts->slaveOnly) {
		ptpClock->slaveOnly = TRUE;
		rtOpts->clockQuality.clockClass = SLAVE_ONLY_CLOCK_CLASS;
		ptpClock->clockQuality.clockClass = SLAVE_ONLY_CLOCK_CLASS;
	}

/* Port configuration data set */

	/*
	 * PortIdentity Init (portNumber = 1 for an ardinary clock spec
	 * 7.5.2.3)
	 */
	copyClockIdentity(ptpClock->portIdentity.clockIdentity,
			ptpClock->clockIdentity);
	ptpClock->portIdentity.portNumber = rtOpts->portNumber;

	/* select the initial rate of delayreqs until we receive the first announce message */

	ptpClock->logMinDelayReqInterval = rtOpts->initial_delayreq;

	clearTime(&ptpClock->peerMeanPathDelay);

	ptpClock->logAnnounceInterval = rtOpts->logAnnounceInterval;
	ptpClock->announceReceiptTimeout = rtOpts->announceReceiptTimeout;
	ptpClock->logSyncInterval = rtOpts->logSyncInterval;
	ptpClock->delayMechanism = rtOpts->delayMechanism;
	ptpClock->logMinPdelayReqInterval = rtOpts->logMinPdelayReqInterval;
	ptpClock->versionNumber = VERSION_PTP;

	if(rtOpts->dot1AS) {
	    ptpClock->transportSpecific = TSP_ETHERNET_AVB;
	} else {
	    ptpClock->transportSpecific = TSP_DEFAULT;
	}

 	/*
	 *  Initialize random number generator using same method as ptpv1:
	 *  seed is now initialized from the last bytes of our mac addres (collected in net.c:findIface())
	 */
	srand((ptpClock->netPath.interfaceID[PTP_UUID_LENGTH - 1] << 8) +
	    ptpClock->netPath.interfaceID[PTP_UUID_LENGTH - 2]);

	/*Init other stuff*/
	ptpClock->number_foreign_records = 0;
  	ptpClock->max_foreign_records = rtOpts->max_foreign_records;
}