void initClock(RunTimeOpts * rtOpts, PtpClock * ptpClock) { DBG("initClock\n"); #ifdef PTPD_NTPDC /* If we've been suppressing ntpdc error messages, show them once again */ ptpClock->ntpControl.requestFailed = FALSE; #endif /* PTPD_NTPDC */ /* do not reset frequency here - restoreDrift will do it if necessary */ #ifdef HAVE_SYS_TIMEX_H ptpClock->servo.observedDrift = 0; #endif /* HAVE_SYS_TIMEX_H */ /* clear vars */ /* clean more original filter variables */ clearTime(&ptpClock->offsetFromMaster); clearTime(&ptpClock->meanPathDelay); clearTime(&ptpClock->delaySM); clearTime(&ptpClock->delayMS); FilterClear(ptpClock->owd_filt); /* clears one-way delay filter */ FilterClear(ptpClock->ofm_filt); /* clears offset from master filter */ rtOpts->offset_first_updated = FALSE; ptpClock->char_last_msg='I'; reset_operator_messages(rtOpts, ptpClock); /* For Hybrid mode */ ptpClock->masterAddr = 0; }
/* handle actions and events for 'port_state' */ void doState(RunTimeOpts *rtOpts, PtpClock *ptpClock) { UInteger8 state; ptpClock->message_activity = FALSE; /* Process record_update (BMC algorithm) before everything else */ switch (ptpClock->portState) { case PTP_LISTENING: case PTP_PASSIVE: case PTP_SLAVE: case PTP_MASTER: /*State decision Event*/ /* If we received a valid Announce message, and can use it (record_update), then run the BMC algorithm */ if(ptpClock->record_update) { DBG2("event STATE_DECISION_EVENT\n"); ptpClock->record_update = FALSE; state = bmc(ptpClock->foreign, rtOpts, ptpClock); if(state != ptpClock->portState) toState(state, rtOpts, ptpClock); } break; default: break; } switch (ptpClock->portState) { case PTP_FAULTY: /* imaginary troubleshooting */ DBG("event FAULT_CLEARED\n"); toState(PTP_INITIALIZING, rtOpts, ptpClock); return; case PTP_LISTENING: case PTP_UNCALIBRATED: case PTP_SLAVE: // passive mode behaves like the SLAVE state, in order to wait for the announce timeout of the current active master case PTP_PASSIVE: handle(rtOpts, ptpClock); /* * handle SLAVE timers: * - No Announce message was received * - Time to send new delayReq (miss of delayResp is not monitored explicitelly) */ if (timerExpired(ANNOUNCE_RECEIPT_TIMER, ptpClock->itimer)) { DBG("event ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES\n"); ptpClock->number_foreign_records = 0; ptpClock->foreign_record_i = 0; if(!ptpClock->slaveOnly && ptpClock->clockQuality.clockClass != 255) { m1(rtOpts,ptpClock); toState(PTP_MASTER, rtOpts, ptpClock); } else { /* * Force a reset when getting a timeout in state listening, that will lead to an IGMP reset * previously this was not the case when we were already in LISTENING mode */ toState(PTP_LISTENING, rtOpts, ptpClock); } } if (timerExpired(OPERATOR_MESSAGES_TIMER, ptpClock->itimer)) { reset_operator_messages(rtOpts, ptpClock); } if (ptpClock->delayMechanism == E2E) { if(timerExpired(DELAYREQ_INTERVAL_TIMER, ptpClock->itimer)) { DBG2("event DELAYREQ_INTERVAL_TIMEOUT_EXPIRES\n"); issueDelayReq(rtOpts,ptpClock); } } else if (ptpClock->delayMechanism == P2P) { if (timerExpired(PDELAYREQ_INTERVAL_TIMER, ptpClock->itimer)) { DBGV("event PDELAYREQ_INTERVAL_TIMEOUT_EXPIRES\n"); issuePDelayReq(rtOpts,ptpClock); } /* FIXME: Path delay should also rearm its timer with the value received from the Master */ } break; case PTP_MASTER: /* * handle SLAVE timers: * - Time to send new Sync * - Time to send new Announce * - Time to send new PathDelay * (DelayResp has no timer - as these are sent and retransmitted by the slaves) */ if (timerExpired(SYNC_INTERVAL_TIMER, ptpClock->itimer)) { DBGV("event SYNC_INTERVAL_TIMEOUT_EXPIRES\n"); issueSync(rtOpts, ptpClock); } if (timerExpired(ANNOUNCE_INTERVAL_TIMER, ptpClock->itimer)) { DBGV("event ANNOUNCE_INTERVAL_TIMEOUT_EXPIRES\n"); issueAnnounce(rtOpts, ptpClock); } if (ptpClock->delayMechanism == P2P) { if (timerExpired(PDELAYREQ_INTERVAL_TIMER, ptpClock->itimer)) { DBGV("event PDELAYREQ_INTERVAL_TIMEOUT_EXPIRES\n"); issuePDelayReq(rtOpts,ptpClock); } } // TODO: why is handle() below expiretimer, while in slave is the opposite handle(rtOpts, ptpClock); if (ptpClock->slaveOnly || ptpClock->clockQuality.clockClass == 255) toState(PTP_LISTENING, rtOpts, ptpClock); break; case PTP_DISABLED: handle(rtOpts, ptpClock); break; default: DBG("(doState) do unrecognized state\n"); break; } }