/* handle actions and events for 'port_state' */ void doState(PtpClock *ptpClock) { ptpClock->messageActivity = FALSE; switch (ptpClock->portDS.portState) { case PTP_LISTENING: case PTP_UNCALIBRATED: case PTP_SLAVE: case PTP_PRE_MASTER: case PTP_MASTER: case PTP_PASSIVE: /*State decision Event*/ if (getFlag(ptpClock->events, STATE_DECISION_EVENT)) { DBGV("event STATE_DECISION_EVENT\n"); clearFlag(ptpClock->events, STATE_DECISION_EVENT); ptpClock->recommendedState = bmc(ptpClock); switch (ptpClock->recommendedState) { case PTP_MASTER: case PTP_PASSIVE: if (ptpClock->defaultDS.slaveOnly || ptpClock->defaultDS.clockQuality.clockClass == 255) { ptpClock->recommendedState = PTP_LISTENING; } break; default: break; } } break; default: break; } switch (ptpClock->recommendedState) { case PTP_MASTER: switch (ptpClock->portDS.portState) { case PTP_PRE_MASTER: if (timerExpired(QUALIFICATION_TIMEOUT, ptpClock->itimer)) { toState(ptpClock, PTP_MASTER); } break; case PTP_MASTER: break; default: toState(ptpClock, PTP_PRE_MASTER); break; } break; case PTP_PASSIVE: if (ptpClock->portDS.portState != ptpClock->recommendedState) { toState(ptpClock, PTP_PASSIVE); } break; case PTP_SLAVE: switch (ptpClock->portDS.portState) { case PTP_UNCALIBRATED: if (getFlag(ptpClock->events, MASTER_CLOCK_SELECTED)) { DBG("event MASTER_CLOCK_SELECTED\n"); clearFlag(ptpClock->events, MASTER_CLOCK_SELECTED); toState(ptpClock, PTP_SLAVE); } if (getFlag(ptpClock->events, MASTER_CLOCK_CHANGED)) { DBG("event MASTER_CLOCK_CHANGED\n"); clearFlag(ptpClock->events, MASTER_CLOCK_CHANGED); } break; case PTP_SLAVE: if (getFlag(ptpClock->events, SYNCHRONIZATION_FAULT)) { DBG("event SYNCHRONIZATION_FAULT\n"); clearFlag(ptpClock->events, SYNCHRONIZATION_FAULT); toState(ptpClock, PTP_UNCALIBRATED); } if (getFlag(ptpClock->events, MASTER_CLOCK_CHANGED)) { DBG("event MASTER_CLOCK_CHANGED\n"); clearFlag(ptpClock->events, MASTER_CLOCK_CHANGED); toState(ptpClock, PTP_UNCALIBRATED); } break; default: toState(ptpClock, PTP_UNCALIBRATED); break; } break; case PTP_LISTENING: if (ptpClock->portDS.portState != ptpClock->recommendedState) { toState(ptpClock, PTP_LISTENING); } break; case PTP_INITIALIZING: break; default: DBG("doState: unrecognized recommended state %d\n", ptpClock->recommendedState); break; } switch (ptpClock->portDS.portState) { case PTP_INITIALIZING: if (TRUE == doInit(ptpClock)) { toState(ptpClock, PTP_LISTENING); } else { toState(ptpClock, PTP_FAULTY); } break; case PTP_FAULTY: /* imaginary troubleshooting */ DBG("event FAULT_CLEARED\n"); toState(ptpClock, PTP_INITIALIZING); return; case PTP_DISABLED: handle(ptpClock); break; case PTP_LISTENING: case PTP_UNCALIBRATED: case PTP_SLAVE: case PTP_PASSIVE: if (timerExpired(ANNOUNCE_RECEIPT_TIMER, ptpClock->itimer)) { DBGV("event ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES\n"); ptpClock->foreignMasterDS.count = 0; ptpClock->foreignMasterDS.i = 0; if (!(ptpClock->defaultDS.slaveOnly || ptpClock->defaultDS.clockQuality.clockClass == 255)) { m1(ptpClock); ptpClock->recommendedState = PTP_MASTER; toState(ptpClock, PTP_MASTER); } else if (ptpClock->portDS.portState != PTP_LISTENING) { toState(ptpClock, PTP_LISTENING); } break; } handle(ptpClock); break; case PTP_MASTER: if (timerExpired(SYNC_INTERVAL_TIMER, ptpClock->itimer)) { DBGV("event SYNC_INTERVAL_TIMEOUT_EXPIRES\n"); issueSync(ptpClock); } if (timerExpired(ANNOUNCE_INTERVAL_TIMER, ptpClock->itimer)) { DBGV("event ANNOUNCE_INTERVAL_TIMEOUT_EXPIRES\n"); issueAnnounce(ptpClock); } handle(ptpClock); issueDelayReqTimerExpired(ptpClock); break; default: DBG("doState: do unrecognized state %d\n", ptpClock->portDS.portState); break; } }
/* handle actions and events for 'port_state' */ void doState(PtpClock *ptpClock) { UInteger8 state; ptpClock->message_activity = FALSE; switch(ptpClock->port_state) { case PTP_LISTENING: case PTP_PASSIVE: case PTP_SLAVE: case PTP_MASTER: if(ptpClock->record_update) { ptpClock->record_update = FALSE; state = bmc(ptpClock->foreign, ptpClock); if(state != ptpClock->port_state) toState(state, ptpClock); } break; default: break; } switch(ptpClock->port_state) { case PTP_FAULTY: /* imaginary troubleshooting */ DBG("event FAULT_CLEARED\n"); toState(PTP_INITIALIZING, ptpClock); return; case PTP_LISTENING: case PTP_PASSIVE: case PTP_UNCALIBRATED: case PTP_SLAVE: handle(ptpClock); if(timerExpired(SYNC_RECEIPT_TIMER, ptpClock->itimer)) { DBG("event SYNC_RECEIPT_TIMEOUT_EXPIRES\n"); ptpClock->number_foreign_records = 0; ptpClock->foreign_record_i = 0; if(!ptpClock->runTimeOpts.slaveOnly && ptpClock->clock_stratum != 255) { m1(ptpClock); toState(PTP_MASTER, ptpClock); } else if(ptpClock->port_state != PTP_LISTENING) toState(PTP_LISTENING, ptpClock); } break; case PTP_MASTER: if(timerExpired(SYNC_INTERVAL_TIMER, ptpClock->itimer)) { DBGV("event SYNC_INTERVAL_TIMEOUT_EXPIRES\n"); issueSync(ptpClock); } handle(ptpClock); if(ptpClock->runTimeOpts.slaveOnly || ptpClock->clock_stratum == 255) toState(PTP_LISTENING, ptpClock); break; case PTP_DISABLED: handle(ptpClock); break; default: DBG("do unrecognized state\n"); break; } }
/* 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; } }