Commit cfdfcf9d authored by Jean-Claude BAU's avatar Jean-Claude BAU

Fix issues detected with BTrain switch

parents e273fea7 18d76f2f
...@@ -55,6 +55,9 @@ extern defaultDeviceAttributes_t defaultDeviceAttributes[]; ...@@ -55,6 +55,9 @@ extern defaultDeviceAttributes_t defaultDeviceAttributes[];
extern void bmc_set_default_device_attributes (struct pp_globals *ppg); extern void bmc_set_default_device_attributes (struct pp_globals *ppg);
extern void bmc_update_clock_quality(struct pp_globals *ppg); extern void bmc_update_clock_quality(struct pp_globals *ppg);
extern void bmc_apply_configured_device_attributes(struct pp_globals *ppg); extern void bmc_apply_configured_device_attributes(struct pp_globals *ppg);
extern int bmc_is_erbest(struct pp_instance *ppi, struct PortIdentity *srcPortIdentity);
......
...@@ -29,6 +29,7 @@ static int wrh_tracking_enabled = 1; ...@@ -29,6 +29,7 @@ static int wrh_tracking_enabled = 1;
/* prototypes */ /* prototypes */
static int __wrh_servo_update(struct pp_instance *ppi); static int __wrh_servo_update(struct pp_instance *ppi);
static void setState(struct pp_instance *ppi, int newState);
/* External data */ /* External data */
extern struct wrs_shm_head *ppsi_head; extern struct wrs_shm_head *ppsi_head;
...@@ -92,7 +93,7 @@ int wrh_servo_init(struct pp_instance *ppi) ...@@ -92,7 +93,7 @@ int wrh_servo_init(struct pp_instance *ppi)
gs->flags |= PP_SERVO_FLAG_VALID; gs->flags |= PP_SERVO_FLAG_VALID;
TOPS(ppi)->get(ppi, &gs->update_time); TOPS(ppi)->get(ppi, &gs->update_time);
s->tracking_enabled = wrh_tracking_enabled; s->tracking_enabled = wrh_tracking_enabled;
gs->state = WRH_SYNC_TAI; setState(ppi,WRH_SYNC_TAI);
strcpy(gs->servo_state_name, wrh_servo_state_name[gs->state]); strcpy(gs->servo_state_name, wrh_servo_state_name[gs->state]);
} }
...@@ -111,7 +112,7 @@ void wrh_servo_reset(struct pp_instance *ppi) ...@@ -111,7 +112,7 @@ void wrh_servo_reset(struct pp_instance *ppi)
WRH_SERVO_RESET_DATA(WRH_SRV(ppi)); WRH_SERVO_RESET_DATA(WRH_SRV(ppi));
SRV(ppi)->state = WRH_UNINITIALIZED; setState(ppi,WRH_UNINITIALIZED);
/* shmem unlock */ /* shmem unlock */
wrs_shm_write(ppsi_head, WRS_SHM_WRITE_END); wrs_shm_write(ppsi_head, WRS_SHM_WRITE_END);
...@@ -217,8 +218,10 @@ static int __wrh_servo_update(struct pp_instance *ppi) ...@@ -217,8 +218,10 @@ static int __wrh_servo_update(struct pp_instance *ppi)
struct pp_time offsetMS ; struct pp_time offsetMS ;
int32_t offset_ps; int32_t offset_ps;
if ( gs->state==WRH_UNINITIALIZED ) if ( gs->state==WRH_UNINITIALIZED ) {
pp_error("%s : Servo not initialized !!!!\n",__FUNCTION__);
return 0; return 0;
}
prev_delayMM_ps = s->delayMM_ps; prev_delayMM_ps = s->delayMM_ps;
......
...@@ -121,6 +121,7 @@ static int wr_pack_announce(struct pp_instance *ppi) ...@@ -121,6 +121,7 @@ static int wr_pack_announce(struct pp_instance *ppi)
static void wr_unpack_announce(struct pp_instance *ppi,void *buf, MsgAnnounce *ann) static void wr_unpack_announce(struct pp_instance *ppi,void *buf, MsgAnnounce *ann)
{ {
MsgHeader *hdr = &ppi->received_ptp_header;
int msg_len = ntohs(*(UInteger16 *) (buf + 2)); int msg_len = ntohs(*(UInteger16 *) (buf + 2));
Boolean parentIsWRnode=FALSE; Boolean parentIsWRnode=FALSE;
Boolean resetWrProtocol=FALSE; Boolean resetWrProtocol=FALSE;
...@@ -128,6 +129,11 @@ static void wr_unpack_announce(struct pp_instance *ppi,void *buf, MsgAnnounce *a ...@@ -128,6 +129,11 @@ static void wr_unpack_announce(struct pp_instance *ppi,void *buf, MsgAnnounce *a
struct wr_dsport *wrp = WR_DSPOR(ppi); struct wr_dsport *wrp = WR_DSPOR(ppi);
pp_diag(NULL, ext, 2, "hook: %s\n", __func__); pp_diag(NULL, ext, 2, "hook: %s\n", __func__);
// If the message is not coming from erbest, it must be discarded
if ( !bmc_is_erbest(ppi,&hdr->sourcePortIdentity))
return;
if (msg_len >= WR_ANNOUNCE_LENGTH) { if (msg_len >= WR_ANNOUNCE_LENGTH) {
UInteger16 wr_flags; UInteger16 wr_flags;
MsgHeader *hdr = &ppi->received_ptp_header; MsgHeader *hdr = &ppi->received_ptp_header;
...@@ -137,7 +143,12 @@ static void wr_unpack_announce(struct pp_instance *ppi,void *buf, MsgAnnounce *a ...@@ -137,7 +143,12 @@ static void wr_unpack_announce(struct pp_instance *ppi,void *buf, MsgAnnounce *a
msg_unpack_announce_wr_tlv(buf, ann, &wr_flags); msg_unpack_announce_wr_tlv(buf, ann, &wr_flags);
parentIsWRnode=(wr_flags & WR_NODE_MODE)!=NON_WR; parentIsWRnode=(wr_flags & WR_NODE_MODE)!=NON_WR;
// Check if a new parent is detected // Check if a new parent is detected.
// This part is needed to cover the following use case :
// on the master side, the WR extension is disabled (WR calibration failure or PTP profile selected)
// then the PPSi process is restarted using the WR profile. On the slave side, if the timeout ANN_RECEIPT has not fired,
// we must detect that the PPSi process has been restarted and then replay the calibration protocol.
// Checked parameters :
// - The parent is a WR node // - The parent is a WR node
// - ptp state=(slave|uncalibrated|listening) // - ptp state=(slave|uncalibrated|listening)
// - Same parent port ID but with a not continuous sequence ID (With a margin of 1) // - Same parent port ID but with a not continuous sequence ID (With a margin of 1)
...@@ -159,10 +170,10 @@ static void wr_unpack_announce(struct pp_instance *ppi,void *buf, MsgAnnounce *a ...@@ -159,10 +170,10 @@ static void wr_unpack_announce(struct pp_instance *ppi,void *buf, MsgAnnounce *a
parentIsWRnode=FALSE; parentIsWRnode=FALSE;
resetWrProtocol=ppi->extState==PP_EXSTATE_ACTIVE && slaveUncalState; resetWrProtocol=ppi->extState==PP_EXSTATE_ACTIVE && slaveUncalState;
} }
memcpy(&wrp->parentAnnPortIdentity,pid,sizeof(struct PortIdentity)); memcpy(&wrp->parentAnnPortIdentity,pid,sizeof(struct PortIdentity));
wrp->parentAnnSequenceId=hdr->sequenceId; wrp->parentAnnSequenceId=hdr->sequenceId;
/* Update the WR parent state */ /* Update the WR parent state */
if ( !parentIsWRnode ) if ( !parentIsWRnode )
/* Not a WR node */ /* Not a WR node */
......
...@@ -1172,6 +1172,15 @@ static struct pp_instance *bmc_any_port_initializing(struct pp_globals *ppg) ...@@ -1172,6 +1172,15 @@ static struct pp_instance *bmc_any_port_initializing(struct pp_globals *ppg)
return NULL; return NULL;
} }
int bmc_is_erbest(struct pp_instance *ppi, PortIdentity *srcPortIdentity) {
if (ppi->frgn_rec_num > 0 && ppi->frgn_rec_best != -1) {
return bmc_pidcmp(&ppi->frgn_master[ppi->frgn_rec_best].sourcePortIdentity,
srcPortIdentity)==0;
}
return 0;
}
static void bmc_update_erbest_inst(struct pp_instance *ppi) { static void bmc_update_erbest_inst(struct pp_instance *ppi) {
struct pp_frgn_master *frgn_master; struct pp_frgn_master *frgn_master;
......
...@@ -245,7 +245,6 @@ int pp_slave(struct pp_instance *ppi, void *buf, int len) ...@@ -245,7 +245,6 @@ int pp_slave(struct pp_instance *ppi, void *buf, int len)
int ret = PP_SEND_OK; /* error var, to check errors in msg handling */ int ret = PP_SEND_OK; /* error var, to check errors in msg handling */
Boolean uncalibrated = (ppi->state == PPS_UNCALIBRATED); Boolean uncalibrated = (ppi->state == PPS_UNCALIBRATED);
MsgHeader *hdr = &ppi->received_ptp_header; MsgHeader *hdr = &ppi->received_ptp_header;
int newState=ppi->is_new_state;
/* upgrade from uncalibrated to slave or back*/ /* upgrade from uncalibrated to slave or back*/
if (uncalibrated) { if (uncalibrated) {
...@@ -256,23 +255,21 @@ int pp_slave(struct pp_instance *ppi, void *buf, int len) ...@@ -256,23 +255,21 @@ int pp_slave(struct pp_instance *ppi, void *buf, int len)
} else { } else {
ppi->next_state = PPS_SLAVE; ppi->next_state = PPS_SLAVE;
} }
} } else {
/* Check if the foreign master has changed */ /* Check if the foreign master has changed */
if ( DSPAR(ppi)->newGrandmaster ) { if ( DSPAR(ppi)->newGrandmaster ) {
// New grandmaster detected // New grandmaster detected
DSPAR(ppi)->newGrandmaster=FALSE; // Clear it DSPAR(ppi)->newGrandmaster=FALSE; // Clear it
if ( !uncalibrated )
// State must transition from SLAVE to UNCALIBRATED // State must transition from SLAVE to UNCALIBRATED
ppi->next_state =PPS_UNCALIBRATED; ppi->next_state = PPS_UNCALIBRATED;
else
newState=1;// If already in uncalibrated state, force to see it as a new state
Octet *id=DSPAR(ppi)->parentPortIdentity.clockIdentity.id; Octet *id=DSPAR(ppi)->parentPortIdentity.clockIdentity.id;
pp_info("New grandmaster detected: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", pp_info("New grandmaster detected: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
id[0],id[1],id[2],id[3],id[4],id[5],id[6],id[7]); id[0],id[1],id[2],id[3],id[4],id[5],id[6],id[7]);
}
} }
/* Force to stay on desired state if externalPortConfiguration option is enabled */ /* Force to stay on desired state if externalPortConfiguration option is enabled */
...@@ -282,7 +279,7 @@ int pp_slave(struct pp_instance *ppi, void *buf, int len) ...@@ -282,7 +279,7 @@ int pp_slave(struct pp_instance *ppi, void *buf, int len)
ppi->next_state = PPS_UNCALIBRATED; //Force to stay in uncalibrated state ppi->next_state = PPS_UNCALIBRATED; //Force to stay in uncalibrated state
/* when entering uncalibrated init servo */ /* when entering uncalibrated init servo */
if (uncalibrated && newState) { if (uncalibrated && ppi->is_new_state) {
memset(&ppi->t1, 0, sizeof(ppi->t1)); memset(&ppi->t1, 0, sizeof(ppi->t1));
pp_diag(ppi, bmc, 2, "Entered to uncalibrated, reset servo\n"); pp_diag(ppi, bmc, 2, "Entered to uncalibrated, reset servo\n");
pp_servo_init(ppi); pp_servo_init(ppi);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment