Esempio n. 1
0
void EtherPort::syncDone() {
	GPTP_LOG_VERBOSE("Sync complete");

	if (automotive_profile && getPortState() == PTP_SLAVE) {
		if (avbSyncState > 0) {
			avbSyncState--;
			if (avbSyncState == 0) {
				setStationState(STATION_STATE_AVB_SYNC);
				if (getTestMode()) {
					APMessageTestStatus *testStatusMsg =
						new APMessageTestStatus(this);
					if (testStatusMsg) {
						testStatusMsg->sendPort(this);
						delete testStatusMsg;
					}
				}
			}
		}
	}

	if (automotive_profile) {
		if (!sync_rate_interval_timer_started) {
			if ( getSyncInterval() != operLogSyncInterval )
			{
				startSyncRateIntervalTimer();
			}
		}
	}

	if( !pdelay_started ) {
		startPDelay();
	}
}
Esempio n. 2
0
void printHeader()
{

    std::cout
        << std::string( 5, '*' )
        << " "
        << getTestMode()
        << " * "
        << getCompilerName()
        << " * "
        << getRandomMode()
        << " "
        << std::string( 5, '*' )
        << "\n"
        << std::endl;
}
Esempio n. 3
0
EtherPort::EtherPort( PortInit_t *portInit ) :
	CommonPort( portInit )
{
	automotive_profile = portInit->automotive_profile;
	linkUp = portInit->linkUp;
	setTestMode( portInit->testMode );

	pdelay_sequence_id = 0;

	pdelay_started = false;
	pdelay_halted = false;
	sync_rate_interval_timer_started = false;

	duplicate_resp_counter = 0;
	last_invalid_seqid = 0;

	initialLogPdelayReqInterval = portInit->initialLogPdelayReqInterval;
	operLogPdelayReqInterval = portInit->operLogPdelayReqInterval;
	operLogSyncInterval = portInit->operLogSyncInterval;

	if (automotive_profile) {
		setAsCapable( true );

		if (getInitSyncInterval() == LOG2_INTERVAL_INVALID)
			setInitSyncInterval( -5 );     // 31.25 ms
		if (initialLogPdelayReqInterval == LOG2_INTERVAL_INVALID)
			initialLogPdelayReqInterval = 0;  // 1 second
		if (operLogPdelayReqInterval == LOG2_INTERVAL_INVALID)
			operLogPdelayReqInterval = 0;      // 1 second
		if (operLogSyncInterval == LOG2_INTERVAL_INVALID)
			operLogSyncInterval = 0;           // 1 second
	}
	else {
		setAsCapable( false );

		if ( getInitSyncInterval() == LOG2_INTERVAL_INVALID )
			setInitSyncInterval( -3 );       // 125 ms
		if (initialLogPdelayReqInterval == LOG2_INTERVAL_INVALID)
			initialLogPdelayReqInterval = 0;   // 1 second
		if (operLogPdelayReqInterval == LOG2_INTERVAL_INVALID)
			operLogPdelayReqInterval = 0;      // 1 second
		if (operLogSyncInterval == LOG2_INTERVAL_INVALID)
			operLogSyncInterval = 0;           // 1 second
	}

	/*TODO: Add intervals below to a config interface*/
	log_min_mean_pdelay_req_interval = initialLogPdelayReqInterval;

	last_sync = NULL;
	last_pdelay_req = NULL;
	last_pdelay_resp = NULL;
	last_pdelay_resp_fwup = NULL;

	setPdelayCount(0);
	setSyncCount(0);

	if (automotive_profile) {
		if (isGM) {
			avbSyncState = 1;
		}
		else {
			avbSyncState = 2;
		}
		if (getTestMode())
		{
			linkUpCount = 1;  // TODO : really should check the current linkup status http://stackoverflow.com/questions/15723061/how-to-check-if-interface-is-up
			linkDownCount = 0;
		}
		setStationState(STATION_STATE_RESERVED);
	}
}
Esempio n. 4
0
bool EtherPort::_processEvent( Event e )
{
	bool ret;

	switch (e) {
	case POWERUP:
	case INITIALIZE:
		if (!automotive_profile) {
			if ( getPortState() != PTP_SLAVE &&
			     getPortState() != PTP_MASTER )
			{
				GPTP_LOG_STATUS("Starting PDelay");
				startPDelay();
			}
		}
		else {
			startPDelay();
		}

		port_ready_condition->wait_prelock();

		if( !linkWatch(watchNetLinkWrapper, (void *)this) )
		{
			GPTP_LOG_ERROR("Error creating port link thread");
			ret = false;
			break;
		}

		if( !linkOpen(openPortWrapper, (void *)this) )
		{
			GPTP_LOG_ERROR("Error creating port thread");
			ret = false;
			break;
		}

		port_ready_condition->wait();

		if (automotive_profile) {
			setStationState(STATION_STATE_ETHERNET_READY);
			if (getTestMode())
			{
				APMessageTestStatus *testStatusMsg = new APMessageTestStatus(this);
				if (testStatusMsg) {
					testStatusMsg->sendPort(this);
					delete testStatusMsg;
				}
			}
			if (!isGM) {
				// Send an initial signalling message
				PTPMessageSignalling *sigMsg = new PTPMessageSignalling(this);
				if (sigMsg) {
					sigMsg->setintervals(PTPMessageSignalling::sigMsgInterval_NoSend, getSyncInterval(), PTPMessageSignalling::sigMsgInterval_NoSend);
					sigMsg->sendPort(this, NULL);
					delete sigMsg;
				}

				startSyncReceiptTimer((unsigned long long)
					 (SYNC_RECEIPT_TIMEOUT_MULTIPLIER *
					  ((double) pow((double)2, getSyncInterval()) *
					   1000000000.0)));
			}
		}

		ret = true;
		break;
	case STATE_CHANGE_EVENT:
		// If the automotive profile is enabled, handle the event by
		// doing nothing and returning true, preventing the default
		// action from executing
		if( automotive_profile )
			ret = true;
		else
			ret = false;

		break;
	case LINKUP:
		haltPdelay(false);
		startPDelay();
		if (automotive_profile) {
			GPTP_LOG_EXCEPTION("LINKUP");
		}
		else {
			GPTP_LOG_STATUS("LINKUP");
		}

		if( clock->getPriority1() == 255 || getPortState() == PTP_SLAVE ) {
			becomeSlave( true );
		} else if( getPortState() == PTP_MASTER ) {
			becomeMaster( true );
		} else {
			startAnnounce();
		}

		if (automotive_profile) {
			setAsCapable( true );

			setStationState(STATION_STATE_ETHERNET_READY);
			if (getTestMode())
			{
				APMessageTestStatus *testStatusMsg = new APMessageTestStatus(this);
				if (testStatusMsg) {
					testStatusMsg->sendPort(this);
					delete testStatusMsg;
				}
			}

			resetInitSyncInterval();
			setAnnounceInterval( 0 );
			log_min_mean_pdelay_req_interval = initialLogPdelayReqInterval;

			if (!isGM) {
				// Send an initial signaling message
				PTPMessageSignalling *sigMsg = new PTPMessageSignalling(this);
				if (sigMsg) {
					sigMsg->setintervals(PTPMessageSignalling::sigMsgInterval_NoSend, getSyncInterval(), PTPMessageSignalling::sigMsgInterval_NoSend);
					sigMsg->sendPort(this, NULL);
					delete sigMsg;
				}

				startSyncReceiptTimer((unsigned long long)
					 (SYNC_RECEIPT_TIMEOUT_MULTIPLIER *
					  ((double) pow((double)2, getSyncInterval()) *
					   1000000000.0)));
			}

			// Reset Sync count and pdelay count
			setPdelayCount(0);
			setSyncCount(0);

			// Start AVB SYNC at 2. It will decrement after each sync. When it reaches 0 the Test Status message
			// can be sent
			if (isGM) {
				avbSyncState = 1;
			}
			else {
				avbSyncState = 2;
			}

			if (getTestMode())
			{
				linkUpCount++;
			}
		}
		this->timestamper_reset();

		ret = true;
		break;
	case LINKDOWN:
		stopPDelay();
		if (automotive_profile) {
			GPTP_LOG_EXCEPTION("LINK DOWN");
		}
		else {
			setAsCapable(false);
			GPTP_LOG_STATUS("LINK DOWN");
		}
		if (getTestMode())
		{
			linkDownCount++;
		}

		ret = true;
		break;
	case ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES:
	case SYNC_RECEIPT_TIMEOUT_EXPIRES:
		if( !automotive_profile )
		{
			ret = false;
			break;
		}

		// Automotive Profile specific action
		if (e == SYNC_RECEIPT_TIMEOUT_EXPIRES) {
			GPTP_LOG_EXCEPTION("SYNC receipt timeout");

			startSyncReceiptTimer((unsigned long long)
					      (SYNC_RECEIPT_TIMEOUT_MULTIPLIER *
					       ((double) pow((double)2, getSyncInterval()) *
						1000000000.0)));
		}
		ret = true;
		break;
	case PDELAY_INTERVAL_TIMEOUT_EXPIRES:
		GPTP_LOG_DEBUG("PDELAY_INTERVAL_TIMEOUT_EXPIRES occured");
		{
			Timestamp req_timestamp;

			PTPMessagePathDelayReq *pdelay_req =
			    new PTPMessagePathDelayReq(this);
			PortIdentity dest_id;
			getPortIdentity(dest_id);
			pdelay_req->setPortIdentity(&dest_id);

			{
				Timestamp pending =
				    PDELAY_PENDING_TIMESTAMP;
				pdelay_req->setTimestamp(pending);
			}

			if (last_pdelay_req != NULL) {
				delete last_pdelay_req;
			}
			setLastPDelayReq(pdelay_req);

			getTxLock();
			pdelay_req->sendPort(this, NULL);
			GPTP_LOG_DEBUG("*** Sent PDelay Request message");
			putTxLock();

			{
				long long timeout;
				long long interval;

				timeout = PDELAY_RESP_RECEIPT_TIMEOUT_MULTIPLIER *
					((long long)
					 (pow((double)2,getPDelayInterval())*1000000000.0));

				timeout = timeout > EVENT_TIMER_GRANULARITY ?
					timeout : EVENT_TIMER_GRANULARITY;
				clock->addEventTimerLocked
					(this, PDELAY_RESP_RECEIPT_TIMEOUT_EXPIRES, timeout );
				GPTP_LOG_DEBUG("Schedule PDELAY_RESP_RECEIPT_TIMEOUT_EXPIRES, "
					"PDelay interval %d, timeout %lld",
					getPDelayInterval(), timeout);

				interval =
					((long long)
					 (pow((double)2,getPDelayInterval())*1000000000.0));
				interval = interval > EVENT_TIMER_GRANULARITY ?
					interval : EVENT_TIMER_GRANULARITY;
				startPDelayIntervalTimer(interval);
			}
		}
		break;
	case SYNC_INTERVAL_TIMEOUT_EXPIRES:
		{
			/* Set offset from master to zero, update device vs
			   system time offset */

			// Send a sync message and then a followup to broadcast
			PTPMessageSync *sync = new PTPMessageSync(this);
			PortIdentity dest_id;
			bool tx_succeed;
			getPortIdentity(dest_id);
			sync->setPortIdentity(&dest_id);
			getTxLock();
			tx_succeed = sync->sendPort(this, NULL);
			GPTP_LOG_DEBUG("Sent SYNC message");

			if ( automotive_profile &&
			     getPortState() == PTP_MASTER )
			{
				if (avbSyncState > 0) {
					avbSyncState--;
					if (avbSyncState == 0) {
						// Send Avnu Automotive Profile status message
						setStationState(STATION_STATE_AVB_SYNC);
						if (getTestMode()) {
							APMessageTestStatus *testStatusMsg = new APMessageTestStatus(this);
							if (testStatusMsg) {
								testStatusMsg->sendPort(this);
								delete testStatusMsg;
							}
						}
					}
				}
			}
			putTxLock();

			if ( tx_succeed )
			{
				Timestamp sync_timestamp = sync->getTimestamp();

				GPTP_LOG_VERBOSE("Successful Sync timestamp");
				GPTP_LOG_VERBOSE("Seconds: %u",
						 sync_timestamp.seconds_ls);
				GPTP_LOG_VERBOSE("Nanoseconds: %u",
						 sync_timestamp.nanoseconds);

				PTPMessageFollowUp *follow_up = new PTPMessageFollowUp(this);
				PortIdentity dest_id;
				getPortIdentity(dest_id);

				follow_up->setClockSourceTime(getClock()->getFUPInfo());
				follow_up->setPortIdentity(&dest_id);
				follow_up->setSequenceId(sync->getSequenceId());
				follow_up->setPreciseOriginTimestamp
					(sync_timestamp);
				follow_up->sendPort(this, NULL);
				delete follow_up;
			} else {
				GPTP_LOG_ERROR
					("*** Unsuccessful Sync timestamp");
			}
			delete sync;
		}
		break;
	case FAULT_DETECTED:
		GPTP_LOG_ERROR("Received FAULT_DETECTED event");
		if (!automotive_profile) {
			setAsCapable(false);
		}
		break;
	case PDELAY_DEFERRED_PROCESSING:
		GPTP_LOG_DEBUG("PDELAY_DEFERRED_PROCESSING occured");
		pdelay_rx_lock->lock();
		if (last_pdelay_resp_fwup == NULL) {
			GPTP_LOG_ERROR("PDelay Response Followup is NULL!");
			abort();
		}
		last_pdelay_resp_fwup->processMessage(this);
		if (last_pdelay_resp_fwup->garbage()) {
			delete last_pdelay_resp_fwup;
			this->setLastPDelayRespFollowUp(NULL);
		}
		pdelay_rx_lock->unlock();
		break;
	case PDELAY_RESP_RECEIPT_TIMEOUT_EXPIRES:
		if (!automotive_profile) {
			GPTP_LOG_EXCEPTION("PDelay Response Receipt Timeout");
			setAsCapable(false);
		}
		setPdelayCount( 0 );
		break;

	case PDELAY_RESP_PEER_MISBEHAVING_TIMEOUT_EXPIRES:
		GPTP_LOG_EXCEPTION("PDelay Resp Peer Misbehaving timeout expired! Restarting PDelay");

		haltPdelay(false);
		if( getPortState() != PTP_SLAVE &&
		    getPortState() != PTP_MASTER )
		{
			GPTP_LOG_STATUS("Starting PDelay" );
			startPDelay();
		}
		break;
	case SYNC_RATE_INTERVAL_TIMEOUT_EXPIRED:
		{
			GPTP_LOG_INFO("SYNC_RATE_INTERVAL_TIMEOUT_EXPIRED occured");

			sync_rate_interval_timer_started = false;

			bool sendSignalMessage = false;
			if ( getSyncInterval() != operLogSyncInterval )
			{
				setSyncInterval( operLogSyncInterval );
				sendSignalMessage = true;
			}

			if (log_min_mean_pdelay_req_interval != operLogPdelayReqInterval) {
				log_min_mean_pdelay_req_interval = operLogPdelayReqInterval;
				sendSignalMessage = true;
			}

			if (sendSignalMessage) {
				if (!isGM) {
				// Send operational signalling message
					PTPMessageSignalling *sigMsg = new PTPMessageSignalling(this);
					if (sigMsg) {
						if (automotive_profile)
							sigMsg->setintervals(PTPMessageSignalling::sigMsgInterval_NoChange, getSyncInterval(), PTPMessageSignalling::sigMsgInterval_NoChange);
						else
							sigMsg->setintervals(log_min_mean_pdelay_req_interval, getSyncInterval(), PTPMessageSignalling::sigMsgInterval_NoChange);
						sigMsg->sendPort(this, NULL);
						delete sigMsg;
					}

					startSyncReceiptTimer((unsigned long long)
						 (SYNC_RECEIPT_TIMEOUT_MULTIPLIER *
						  ((double) pow((double)2, getSyncInterval()) *
						   1000000000.0)));
				}
			}
		}

		break;
	default:
		GPTP_LOG_ERROR
		  ( "Unhandled event type in "
		    "EtherPort::processEvent(), %d", e );
		ret = false;
		break;
	}

	return ret;
}