void Slave::HandleWriteTimeDate(HeaderReadIterator& arHWI)
{
	if (!mIIN.GetNeedTime()) {
		LOG_BLOCK(LEV_WARNING, "Master is attempting to write time but slave is not requesting time sync");
		return;
	}

	ObjectReadIterator obj = arHWI.BeginRead();

	if (obj.Count() != 1) {
		mRspIIN.SetParameterError(true);
		return;
	}

	millis_t val = Group50Var1::Inst()->mTime.Get(*obj);
	mpTime->SetTime(val);

	mIIN.SetNeedTime(false);

	if(mpLogger->IsEnabled(LEV_EVENT)) {
		LogEntry le(LEV_EVENT, mpLogger->GetName(), LOCATION,
		            "Time synchronized with master", TIME_SYNC_UPDATED);
		le.AddValue("MILLISEC_SINCE_EPOCH", val);
		mpLogger->Log(le);
	}
}
예제 #2
0
TaskResult TimeSync::_OnFinalResponse(const APDU& arAPDU)
{
	if(mDelay < 0) {
		ptime now = mpTimeSrc->GetUTC();

		HeaderReadIterator hri = arAPDU.BeginRead();
		if(hri.Count() != 1) {
			LOG_BLOCK(LEV_WARNING, "DelayMeas response w/ unexcpected header count");
			return TR_FAIL;
		}
		
		if(!hri->GetBaseObject()->Equals(Group52Var2::Inst())) {
			LOG_BLOCK(LEV_WARNING, "DelayMeas response w/ unexpected object: " << hri->GetBaseObject()->Name());
			return TR_FAIL;
		}

		ObjectReadIterator ori = hri.BeginRead();
		if(ori.Count() != 1) {
			LOG_BLOCK(LEV_WARNING, "DelayMeas got more than 1 object in response");
			return TR_FAIL;
		}

		millis_t send_rcv_time = (now - mStart).total_milliseconds();
		millis_t rtu_turn_around = Group52Var2::Inst()->mTime.Get(*ori);

		// The later shouldn't happen, but could cause a negative delay which would
		// result in a weird time setting
		mDelay = (send_rcv_time >= rtu_turn_around) ? (send_rcv_time - rtu_turn_around)/2 : 0;

		return TR_CONTINUE;
	}
	else {

		return TR_SUCCESS;
	}	
}