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[];
extern void bmc_set_default_device_attributes (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 int bmc_is_erbest(struct pp_instance *ppi, struct PortIdentity *srcPortIdentity);
......
......@@ -29,6 +29,7 @@ static int wrh_tracking_enabled = 1;
/* prototypes */
static int __wrh_servo_update(struct pp_instance *ppi);
static void setState(struct pp_instance *ppi, int newState);
/* External data */
extern struct wrs_shm_head *ppsi_head;
......@@ -92,7 +93,7 @@ int wrh_servo_init(struct pp_instance *ppi)
gs->flags |= PP_SERVO_FLAG_VALID;
TOPS(ppi)->get(ppi, &gs->update_time);
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]);
}
......@@ -111,7 +112,7 @@ void wrh_servo_reset(struct pp_instance *ppi)
WRH_SERVO_RESET_DATA(WRH_SRV(ppi));
SRV(ppi)->state = WRH_UNINITIALIZED;
setState(ppi,WRH_UNINITIALIZED);
/* shmem unlock */
wrs_shm_write(ppsi_head, WRS_SHM_WRITE_END);
......@@ -217,8 +218,10 @@ static int __wrh_servo_update(struct pp_instance *ppi)
struct pp_time offsetMS ;
int32_t offset_ps;
if ( gs->state==WRH_UNINITIALIZED )
if ( gs->state==WRH_UNINITIALIZED ) {
pp_error("%s : Servo not initialized !!!!\n",__FUNCTION__);
return 0;
}
prev_delayMM_ps = s->delayMM_ps;
......
......@@ -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)
{
MsgHeader *hdr = &ppi->received_ptp_header;
int msg_len = ntohs(*(UInteger16 *) (buf + 2));
Boolean parentIsWRnode=FALSE;
Boolean resetWrProtocol=FALSE;
......@@ -128,6 +129,11 @@ static void wr_unpack_announce(struct pp_instance *ppi,void *buf, MsgAnnounce *a
struct wr_dsport *wrp = WR_DSPOR(ppi);
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) {
UInteger16 wr_flags;
MsgHeader *hdr = &ppi->received_ptp_header;
......@@ -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);
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
// - ptp state=(slave|uncalibrated|listening)
// - 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
parentIsWRnode=FALSE;
resetWrProtocol=ppi->extState==PP_EXSTATE_ACTIVE && slaveUncalState;
}
memcpy(&wrp->parentAnnPortIdentity,pid,sizeof(struct PortIdentity));
wrp->parentAnnSequenceId=hdr->sequenceId;
/* Update the WR parent state */
if ( !parentIsWRnode )
/* Not a WR node */
......
......@@ -1172,6 +1172,15 @@ static struct pp_instance *bmc_any_port_initializing(struct pp_globals *ppg)
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) {
struct pp_frgn_master *frgn_master;
......
......@@ -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 */
Boolean uncalibrated = (ppi->state == PPS_UNCALIBRATED);
MsgHeader *hdr = &ppi->received_ptp_header;
int newState=ppi->is_new_state;
/* upgrade from uncalibrated to slave or back*/
if (uncalibrated) {
......@@ -256,7 +255,7 @@ int pp_slave(struct pp_instance *ppi, void *buf, int len)
} else {
ppi->next_state = PPS_SLAVE;
}
}
} else {
/* Check if the foreign master has changed */
if ( DSPAR(ppi)->newGrandmaster ) {
......@@ -264,16 +263,14 @@ int pp_slave(struct pp_instance *ppi, void *buf, int len)
DSPAR(ppi)->newGrandmaster=FALSE; // Clear it
if ( !uncalibrated )
// State must transition from SLAVE to UNCALIBRATED
ppi->next_state =PPS_UNCALIBRATED;
else
newState=1;// If already in uncalibrated state, force to see it as a new state
ppi->next_state = PPS_UNCALIBRATED;
Octet *id=DSPAR(ppi)->parentPortIdentity.clockIdentity.id;
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]);
}
}
/* Force to stay on desired state if externalPortConfiguration option is enabled */
if (is_externalPortConfigurationEnabled(DSDEF(ppi)) &&
......@@ -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
/* when entering uncalibrated init servo */
if (uncalibrated && newState) {
if (uncalibrated && ppi->is_new_state) {
memset(&ppi->t1, 0, sizeof(ppi->t1));
pp_diag(ppi, bmc, 2, "Entered to uncalibrated, reset servo\n");
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