diff --git a/unicast_client.c b/unicast_client.c index 71dd18e..a7efef6 100644 --- a/unicast_client.c +++ b/unicast_client.c @@ -339,11 +339,16 @@ int unicast_client_cancel(struct port *p, struct ptp_message *m, if (cancel->message_type_flags & CANCEL_UNICAST_MAINTAIN_GRANT) { return 0; } + pr_warning("%s: server unilaterally canceled unicast %s grant", p->log_name, msg_type_string(mtype)); + int state = ucma->state; ucma->state = unicast_fsm(ucma->state, UC_EV_CANCEL); + pr_notice("unicast client state change CANCEL, ucma = %s->%s, id=%s", ustate2str(state), ustate2str(ucma->state), cid2str(&ucma->portIdentity.clockIdentity)); ucma->granted &= ~(1 << mtype); + // trigger clock state change event + clock_set_sde(p->clock, 1); /* Respond with ACK. */ msg = port_signaling_uc_construct(p, &ucma->address, &ucma->portIdentity); @@ -446,6 +451,8 @@ void unicast_client_grant(struct port *p, struct ptp_message *m, p->log_name, msg_type_string(mtype)); if (mtype != PDELAY_RESP) { ucma->state = UC_WAIT; + // trigger clock state change event + clock_set_sde(p->clock, 1); } return; } @@ -473,10 +480,30 @@ void unicast_client_grant(struct port *p, struct ptp_message *m, switch (ucma->state) { case UC_HAVE_ANN: + if (mtype == ANNOUNCE) { + int state = ucma->state; + struct PortIdentity pid; + pid = clock_parent_identity(p->clock); + // if we are current master and stuck in HAVE_ANN state, + // kick the state up to NEED_SYDY, this will either trigger + // master re-election after sync timeout, or fix things. + if (pid_eq(&ucma->portIdentity, &pid)) { + pr_warning("received ANNOUNCE grant for current master in UC_HAVE_ANN state, unblocking"); + ucma->state = UC_NEED_SYDY; + } else { + ucma->state = unicast_fsm(ucma->state, UC_EV_GRANT_ANN); + } + ucma->portIdentity = m->header.sourcePortIdentity; + pr_notice("unicast client state change GRANT_ANN, ucma = %s->%s, id=%s", ustate2str(state), ustate2str(ucma->state), cid2str(&ucma->portIdentity.clockIdentity)); + unicast_client_set_renewal(p, ucma, g->durationField); + } + break; case UC_WAIT: if (mtype == ANNOUNCE) { + int state = ucma->state; ucma->state = unicast_fsm(ucma->state, UC_EV_GRANT_ANN); ucma->portIdentity = m->header.sourcePortIdentity; + pr_notice("unicast client state change GRANT_ANN, ucma = %s->%s, id=%s", ustate2str(state), ustate2str(ucma->state), cid2str(&ucma->portIdentity.clockIdentity)); unicast_client_set_renewal(p, ucma, g->durationField); } break; @@ -484,16 +511,20 @@ void unicast_client_grant(struct port *p, struct ptp_message *m, switch (mtype) { case DELAY_RESP: if ((ucma->granted & ucma->sydymsk) == ucma->sydymsk) { + int state = ucma->state; ucma->state = unicast_fsm(ucma->state, UC_EV_GRANT_SYDY); + pr_notice("unicast client state change GRANT_SYDY DELAY_RESP, ucma = %s->%s, id=%s", ustate2str(state), ustate2str(ucma->state), cid2str(&ucma->portIdentity.clockIdentity)); } unicast_client_set_renewal(p, ucma, g->durationField); p->logMinDelayReqInterval = g->logInterMessagePeriod; break; case SYNC: if ((ucma->granted & ucma->sydymsk) == ucma->sydymsk) { + int state = ucma->state; ucma->state = unicast_fsm(ucma->state, UC_EV_GRANT_SYDY); + pr_notice("unicast client state change GRANT_SYDY SYNC, ucma = %s->%s, id=%s", ustate2str(state), ustate2str(ucma->state), cid2str(&ucma->portIdentity.clockIdentity)); } unicast_client_set_renewal(p, ucma, g->durationField); clock_sync_interval(p->clock, g->logInterMessagePeriod); @@ -529,10 +560,13 @@ void unicast_client_state_changed(struct port *p) pid = clock_parent_identity(p->clock); STAILQ_FOREACH(ucma, &p->unicast_master_table->addrs, list) { + int state = ucma->state; if (pid_eq(&ucma->portIdentity, &pid)) { ucma->state = unicast_fsm(ucma->state, UC_EV_SELECTED); + pr_notice("unicast client state change SELECTED, ucma = %s->%s, id=%s, pid=%s", ustate2str(state), ustate2str(ucma->state), cid2str(&ucma->portIdentity.clockIdentity), cid2str(&pid.clockIdentity)); } else { ucma->state = unicast_fsm(ucma->state, UC_EV_UNSELECTED); + pr_notice("unicast client state change UNSELECTED, ucma = %s->%s, id=%s, pid=%s", ustate2str(state), ustate2str(ucma->state), cid2str(&ucma->portIdentity.clockIdentity), cid2str(&pid.clockIdentity)); } } }