Blob Blame History Raw
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));
 		}
 	}
 }