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(); } }
void printHeader() { std::cout << std::string( 5, '*' ) << " " << getTestMode() << " * " << getCompilerName() << " * " << getRandomMode() << " " << std::string( 5, '*' ) << "\n" << std::endl; }
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); } }
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; }