a1dcd3
commit c304dbe4060da421a9bf089188c5016ef97aacf1
a1dcd3
Author: Vadim Fedorenko <vadfed@meta.com>
a1dcd3
Date:   Fri Jan 13 12:34:34 2023 -0800
a1dcd3
a1dcd3
    unicast_client: further improve CANCEL logic
a1dcd3
    
a1dcd3
    bc_dispatch should work right after recieving CANCEL otherwise
a1dcd3
    state machine can stuck in HAVE_ANN state.
a1dcd3
    
a1dcd3
    Also another code to be safe on this side and recover selected
a1dcd3
    best master from being stuck in HAVE_ANN state.
a1dcd3
    
a1dcd3
    Signed-off-by: Vadim Fedorenko <vadfed@meta.com>
a1dcd3
a1dcd3
diff --git a/port.c b/port.c
a1dcd3
index 6b5483f..02b49a1 100644
a1dcd3
--- a/port.c
a1dcd3
+++ b/port.c
a1dcd3
@@ -2982,8 +2982,11 @@ static enum fsm_event bc_event(struct port *p, int fd_index)
a1dcd3
 			event = EV_STATE_DECISION_EVENT;
a1dcd3
 		break;
a1dcd3
 	case SIGNALING:
a1dcd3
-		if (process_signaling(p, msg)) {
a1dcd3
+		err = process_signaling(p, msg);
a1dcd3
+		if (err < 0) {
a1dcd3
 			event = EV_FAULT_DETECTED;
a1dcd3
+		} else if (err) {
a1dcd3
+			event = EV_STATE_DECISION_EVENT;
a1dcd3
 		}
a1dcd3
 		break;
a1dcd3
 	case MANAGEMENT:
a1dcd3
diff --git a/unicast_client.c b/unicast_client.c
a1dcd3
index 81113ae..633a4fe 100644
a1dcd3
--- a/unicast_client.c
a1dcd3
+++ b/unicast_client.c
a1dcd3
@@ -363,7 +363,7 @@ int unicast_client_cancel(struct port *p, struct ptp_message *m,
a1dcd3
 	}
a1dcd3
 out:
a1dcd3
 	msg_put(msg);
a1dcd3
-	return err;
a1dcd3
+	return err ? err : 1;
a1dcd3
 }
a1dcd3
 
a1dcd3
 int unicast_client_initialize(struct port *p)
a1dcd3
@@ -433,6 +433,7 @@ int unicast_client_enabled(struct port *p)
a1dcd3
 void unicast_client_grant(struct port *p, struct ptp_message *m,
a1dcd3
 			  struct tlv_extra *extra)
a1dcd3
 {
a1dcd3
+	struct PortIdentity pid = clock_parent_identity(p->clock);
a1dcd3
 	struct unicast_master_address *ucma;
a1dcd3
 	struct grant_unicast_xmit_tlv *g;
a1dcd3
 	int mtype;
a1dcd3
@@ -478,6 +479,15 @@ void unicast_client_grant(struct port *p, struct ptp_message *m,
a1dcd3
 
a1dcd3
 	switch (ucma->state) {
a1dcd3
 	case UC_HAVE_ANN:
a1dcd3
+		if (mtype == ANNOUNCE) {
a1dcd3
+			if (pid_eq(&ucma->portIdentity, &pid)) {
a1dcd3
+				ucma->state = UC_NEED_SYDY;
a1dcd3
+				pr_warning("received ANNOUNCE grant for current master in UC_HAVE_ANN state, unblocking");
a1dcd3
+			}
a1dcd3
+			ucma->portIdentity = m->header.sourcePortIdentity;
a1dcd3
+			unicast_client_set_renewal(p, ucma, g->durationField);
a1dcd3
+		}
a1dcd3
+		break;
a1dcd3
 	case UC_WAIT:
a1dcd3
 		if (mtype == ANNOUNCE) {
a1dcd3
 			ucma->state = unicast_fsm(ucma->state, UC_EV_GRANT_ANN);