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));
}
}
}