Commit 59838a0d authored by Jean-Claude BAU's avatar Jean-Claude BAU

WR/PTP protocol detection + WR protocol improvement

- Simplify how an instance switch from WR to PTP protocol and vice-versa
- Change the WR state machine: When an unexpected WR signaling message
is received, the state is forced to IDLE. Solve handshake issue when
instance is waiting for an answer with a long time-out and in the other
side the PPSi process is restarted. In this use case the handshake will
fail.
parent 65f9d293
......@@ -277,19 +277,13 @@ int pp_state_machine(struct pp_instance *ppi, void *buf, int len)
return pp_leave_current_state(ppi);
if (len) {
if ( ppi->ext_enabled && !ppi->ptp_msg_received ) {
if ( ppi->pdstate == PP_PDSTATE_WAIT_MSG ) {
/* First frame received since instance initialization */
int tmo;
ppi->ptp_msg_received=TRUE;
if (is_ext_hook_available(ppi,get_tmo_lstate_detection) )
tmo=(*ppi->ext_hooks->get_tmo_lstate_detection)(ppi);
else
tmo= is_externalPortConfigurationEnabled(DSDEF(ppi)) ?
6000 /* JCB: Default value. Is it correct ? */
: pp_timeout_get(ppi,PP_TO_ANN_RECEIPT);
int tmo=is_ext_hook_available(ppi,get_tmo_lstate_detection) ?
(*ppi->ext_hooks->get_tmo_lstate_detection)(ppi)
: 20000; // 20s per default
pp_timeout_set(ppi,PP_TO_PROT_STATE, tmo);
lstate_set_link_pdetection(ppi);
pdstate_set_state_pdetection(ppi);
}
} else
ppi->received_ptp_header.messageType = PPM_NO_MESSAGE;
......@@ -304,20 +298,10 @@ int pp_state_machine(struct pp_instance *ppi, void *buf, int len)
return pp_leave_current_state(ppi);
/* Check protocol state */
if ( ppi->protocol_extension == PPSI_EXT_NONE ) {
lstate_set_link_none(ppi);
} else {
if ( ppi->ext_enabled ) {
if ( ppi->link_state==PP_LSTATE_PROTOCOL_ERROR ||
( ppi->link_state!=PP_LSTATE_LINKED && ppi->ptp_msg_received && pp_timeout(ppi, PP_TO_PROT_STATE)) ) {
if ( ppi->ptp_support )
lstate_disable_extension(ppi);
else
lstate_set_link_failure(ppi);
}
} else {
lstate_set_link_failure(ppi);
}
if ( ppi->ext_enabled &&
(ppi->pdstate==PP_PDSTATE_PDETECTION || ppi->pdstate==PP_PDSTATE_PDETECTED) &&
pp_timeout(ppi, PP_TO_PROT_STATE) ) {
pdstate_disable_extension(ppi);
}
/* run bmc independent of state, and since not message driven do this
......@@ -338,13 +322,6 @@ int pp_state_machine(struct pp_instance *ppi, void *buf, int len)
if ( is_ext_hook_available(ppi,run_ext_state_machine) ) {
int delay = ppi->ext_hooks->run_ext_state_machine(ppi,buf,len);
if ( ppi->ext_enabled && ppi->link_state==PP_LSTATE_PROTOCOL_ERROR) {
if (ppi->ptp_support ) {
lstate_disable_extension(ppi);
}
else
lstate_set_link_failure(ppi);
}
/* if new state mark it, and enter it now (0 ms) */
if (ppi->state != ppi->next_state)
return pp_leave_current_state(ppi);
......
......@@ -126,15 +126,15 @@ struct pp_servo {
struct pp_time offsetFromMaster; /* Shared with extension servo */
unsigned long flags; /* PP_SERVO_FLAG_INVALID, PP_SERVO_FLAG_VALID, ...*/
/* Data used only by extensions */
int state;
char servo_state_name[32]; /* Updated by the servo itself */
/*
* ----- All data after this line will be cleared during by a servo initialization
*/
int reset_address;
/* Data used only by extensions */
int state;
char servo_state_name[32]; /* Updated by the servo itself */
/* Data shared with extension servo */
uint32_t update_count; /* incremented each time the servo is running */
struct pp_time update_time; /* Last updated time of the servo */
......@@ -186,17 +186,16 @@ struct pp_instance_cfg {
};
/*
* This enumeration correspond to the protocol state of a pp_instance.
* It is used to decide which instance must be active on a given port.
* This enumeration correspond to the protocol detection state of a pp_instance.
* It is used to decide which instance/protocol must be active on a given port.
*/
typedef enum {
PP_LSTATE_NONE, /* Link state not applied : No extension */
PP_LSTATE_PROTOCOL_DETECTION, /* Checking if the peer instance is using the same protocol */
PP_LSTATE_IN_PROGRESS, /* Right protocol detected. Try to establish the link with peer instance */
PP_LSTATE_LINKED, /* Link with peer well established */
PP_LSTATE_PROTOCOL_ERROR, /* The extension has detected a problem. */
PP_LSTATE_FAILURE, /* Impossible to connect correctly to a peer instance - extension disabled */
} pp_link_state;
PP_PDSTATE_NONE, /* Link state not applied : No extension */
PP_PDSTATE_WAIT_MSG, /* Waiting fist message */
PP_PDSTATE_PDETECTION, /* Checking if the peer instance is using the same protocol */
PP_PDSTATE_PDETECTED, /* Expected protocol detected*/
PP_PDSTATE_FAILURE, /* Impossible to connect correctly to a peer instance - extension disabled */
} pp_pdstate_t;
/*
* Structure for the individual ppsi link
......@@ -277,10 +276,9 @@ struct pp_instance {
unsigned long ptp_rx_count;
Boolean received_dresp; /* Count the number of delay response messages received for a given delay request */
Boolean received_dresp_fup; /* Count the number of delay response follow up messages received for a given delay request */
Boolean ptp_msg_received; /* Use to detect reception of a ptp message after an ppsi instance initialization */
Boolean ptp_support; /* True if allow pure PTP support */
Boolean ext_enabled; /* True if the extension is enabled */
pp_link_state link_state;
pp_pdstate_t pdstate; /* Protocol detection state */
Boolean bmca_execute; /* True: Ask fsm to run bmca state decision */
};
......
......@@ -200,6 +200,7 @@ struct pp_ext_hooks {
int (*handle_preq) (struct pp_instance * ppi);
int (*handle_presp) (struct pp_instance * ppi);
int (*handle_signaling) (struct pp_instance * ppi, void *buf, int len);
int (*handle_dreq)(struct pp_instance *ppi);
int (*pack_announce)(struct pp_instance *ppi);
void (*unpack_announce)(struct pp_instance *ppi,void *buf, MsgAnnounce *ann);
int (*ready_for_slave)(struct pp_instance *ppi); /* returns: 0=Not ready 1=ready */
......@@ -424,43 +425,38 @@ extern int ppsi_drop_rx(void);
extern int ppsi_drop_tx(void);
/* link state functions to manage the extension (Enable/disable) */
static inline void lstate_enable_extension(struct pp_instance * ppi) {
pp_timeout_reset(ppi,PP_TO_PROT_STATE);
ppi->link_state=PP_LSTATE_PROTOCOL_DETECTION;
ppi->ptp_msg_received=FALSE;
ppi->ext_enabled=TRUE;
static inline void pdstate_disable_extension(struct pp_instance * ppi) {
ppi->pdstate=PP_PDSTATE_FAILURE;
if ( ppi->ptp_support && ppi->ext_enabled) {
ppi->ext_enabled=FALSE;
pp_servo_init(ppi); // Reinitialize the servo
}
}
/* link state functions to manage the extension (Enable/disable) */
static inline void lstate_disable_extension(struct pp_instance * ppi) {
ppi->link_state=PP_LSTATE_FAILURE;
ppi->ptp_msg_received=FALSE;
ppi->ext_enabled=FALSE;
}
static inline void lstate_set_link_established(struct pp_instance * ppi) {
ppi->link_state=PP_LSTATE_LINKED;
}
static inline void lstate_set_link_failure(struct pp_instance * ppi) {
ppi->link_state=PP_LSTATE_FAILURE;
static inline void pdstate_set_state_pdetection(struct pp_instance * ppi) {
if (ppi->pdstate != PP_PDSTATE_NONE ) {
ppi->pdstate=PP_PDSTATE_PDETECTION;
pp_timeout_reset(ppi,PP_TO_PROT_STATE);
}
}
static inline void lstate_set_link_in_progress(struct pp_instance * ppi) {
ppi->link_state=PP_LSTATE_IN_PROGRESS;
static inline void pdstate_set_state_pdetected(struct pp_instance * ppi) {
if (ppi->pdstate != PP_PDSTATE_NONE ) {
ppi->pdstate=PP_PDSTATE_PDETECTED;
pp_timeout_reset(ppi,PP_TO_PROT_STATE);
}
}
static inline void lstate_set_link_none(struct pp_instance * ppi) {
ppi->link_state=PP_LSTATE_NONE;
/* link state functions to manage the extension (Enable/disable) */
static inline void pdstate_enable_extension(struct pp_instance * ppi) {
if (ppi->pdstate != PP_PDSTATE_NONE ) {
ppi->pdstate=PP_PDSTATE_PDETECTED;
pp_timeout_reset(ppi,PP_TO_PROT_STATE);
ppi->ext_enabled=TRUE;
}
}
static inline void lstate_set_link_perror(struct pp_instance * ppi) {
ppi->link_state=PP_LSTATE_PROTOCOL_ERROR;
}
static inline void lstate_set_link_pdetection(struct pp_instance * ppi) {
ppi->link_state=PP_LSTATE_PROTOCOL_DETECTION;
pp_timeout_reset(ppi,PP_TO_PROT_STATE);
}
#include <ppsi/faults.h>
#include <ppsi/timeout_prot.h>
......
......@@ -31,7 +31,6 @@ void wr_handshake_fail(struct pp_instance *ppi)
wrp->next_state=WRS_IDLE;
wr_reset_process(ppi,WR_ROLE_NONE);
wr_servo_reset(ppi);
lstate_set_link_perror(ppi);
}
......
......@@ -12,6 +12,7 @@ static int wr_init(struct pp_instance *ppi, void *buf, int len)
wrTmoIdx=pp_timeout_get_timer(ppi,"WR_EXT_0",TO_RAND_NONE, TMO_CF_INSTANCE_DEPENDENT);
wr_reset_process(ppi,WR_ROLE_NONE);
ppi->pdstate = PP_PDSTATE_WAIT_MSG;
#ifdef CONFIG_ABSCAL
/* absolute calibration only exists in arch-wrpc, so far */
......@@ -50,6 +51,8 @@ static int wr_handle_resp(struct pp_instance *ppi)
/* This correction_field we received is already part of t4 */
if ( ppi->ext_enabled ) {
wr_servo_got_resp(ppi);
if ( ppi->pdstate==PP_PDSTATE_PDETECTED)
pdstate_set_state_pdetected(ppi); // Maintain state Protocol detected on MASTER side
}
else {
pp_servo_got_resp(ppi,OPTS(ppi)->ptpFallbackPpsGen);
......@@ -57,6 +60,18 @@ static int wr_handle_resp(struct pp_instance *ppi)
return 0;
}
static int wr_handle_dreq(struct pp_instance *ppi)
{
pp_diag(ppi, ext, 2, "hook: %s\n", __func__);
if ( ppi->ext_enabled ) {
if ( ppi->pdstate==PP_PDSTATE_PDETECTED)
pdstate_set_state_pdetected(ppi); // Maintain state Protocol detected on MASTER side
}
return 0;
}
static int wr_sync_followup(struct pp_instance *ppi) {
......@@ -85,31 +100,16 @@ static int wr_handle_followup(struct pp_instance *ppi)
static int wr_handle_presp(struct pp_instance *ppi)
{
/* FIXME: verify that last-received cField is already accounted for */
if ( ppi->ext_enabled )
if ( ppi->ext_enabled ) {
wr_servo_got_presp(ppi);
if ( ppi->pdstate==PP_PDSTATE_PDETECTED)
pdstate_set_state_pdetected(ppi); // Maintain state Protocol detected on MASTER side
}
else
pp_servo_got_presp(ppi);
return 0;
}
/* Used only in MASTER state to re-enable the extension if needed */
static int wr_handle_signaling(struct pp_instance *ppi, void *buf, int len) {
if ( !ppi->ext_enabled && ppi->state==PPS_MASTER ) {
/* Check if WR_PRESENT message is received */
MsgSignaling wrsig_msg;
Enumeration16 msgId;
msg_unpack_wrsig(ppi, buf, &wrsig_msg, &msgId);
if (msgId==SLAVE_PRESENT) {
/* Re-enable the extension */
lstate_enable_extension(ppi);
}
}
return 0;
}
static int wr_pack_announce(struct pp_instance *ppi)
{
pp_diag(ppi, ext, 2, "hook: %s\n", __func__);
......@@ -136,29 +136,31 @@ 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 we need to re-enable the extension
if ( !ppi->ext_enabled ) {
// The extension must be re-enabled only if :
// - 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)
// - The port identity is different
if ( parentIsWRnode &&
(ppi->state==PPS_SLAVE ||
ppi->state==PPS_UNCALIBRATED ||
ppi->state==PPS_LISTENING)) {
Boolean samePid=!bmc_pidcmp(pid, &wrp->parentAnnPortIdentity);
if ( !samePid ||
(samePid &&
(hdr->sequenceId!=wrp->parentAnnSequenceId+1 &&
hdr->sequenceId!=wrp->parentAnnSequenceId+2)
)) {
lstate_enable_extension(ppi);
// Check if a new parent is detected
// - 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)
// - The port identity is different
if ( parentIsWRnode &&
(ppi->state==PPS_SLAVE ||
ppi->state==PPS_UNCALIBRATED ||
ppi->state==PPS_LISTENING)) {
Boolean samePid=!bmc_pidcmp(pid, &wrp->parentAnnPortIdentity);
if ( !samePid ||
(samePid &&
(hdr->sequenceId!=wrp->parentAnnSequenceId+1 &&
hdr->sequenceId!=wrp->parentAnnSequenceId+2)
)) {
if ( ppi->state==PPS_UNCALIBRATED && wrp->state==WRS_IDLE) {
/* For other states, it is done in the state_change hook */
wrp->next_state=WRS_PRESENT;
wrp->wrMode=WR_SLAVE;
}
} else {
parentIsWRnode=FALSE;
pdstate_enable_extension(ppi);
}
} else {
parentIsWRnode=FALSE;
}
memcpy(&wrp->parentAnnPortIdentity,pid,sizeof(struct PortIdentity));
......@@ -186,7 +188,6 @@ static void wr_state_change(struct pp_instance *ppi)
(ppi->state == PPS_MASTER))) {
/* if we are leaving the MASTER or SLAVE state */
wr_reset_process(ppi,WR_ROLE_NONE);
lstate_set_link_pdetection(ppi);
if (ppi->state == PPS_SLAVE)
//* We are leaving SLAVE state
WRH_OPER()->locking_reset(ppi);
......@@ -199,12 +200,6 @@ static void wr_state_change(struct pp_instance *ppi)
case PPS_UNCALIBRATED : /* Enter in UNCALIBRATED state */
wrp->next_state=WRS_PRESENT;
wrp->wrMode=WR_SLAVE;
lstate_set_link_pdetection(ppi);
break;
case PPS_SLAVE : /* Enter in SLAVE state */
if ( wrp->wrModeOn && wrp->parentWrModeOn ) {
lstate_set_link_established(ppi);
}
break;
case PPS_LISTENING : /* Enter in LISTENING state */
wr_reset_process(ppi,WR_ROLE_NONE);
......@@ -257,8 +252,9 @@ struct pp_ext_hooks wr_ext_hooks = {
.init = wr_init,
.open = wr_open,
.handle_resp = wr_handle_resp,
.handle_dreq = wr_handle_dreq,
.handle_sync = wr_handle_sync,
.handle_signaling=wr_handle_signaling,
// .handle_signaling=wr_handle_signaling,
.handle_followup = wr_handle_followup,
.ready_for_slave = wr_ready_for_slave,
.run_ext_state_machine = wr_run_state_machine,
......
......@@ -18,7 +18,6 @@
int wr_calibrated(struct pp_instance *ppi, void *buf, int len, int new_state)
{
struct wr_dsport *wrp = WR_DSPOR(ppi);
MsgSignaling wrsig_msg;
int sendmsg = 0;
if (new_state) {
......@@ -28,18 +27,22 @@ int wr_calibrated(struct pp_instance *ppi, void *buf, int len, int new_state)
} else {
if (ppi->received_ptp_header.messageType == PPM_SIGNALING) {
msg_unpack_wrsig(ppi, buf, &wrsig_msg,
&(wrp->msgTmpWrMessageID));
Enumeration16 wrMsgId;
MsgSignaling wrsig_msg;
if ((wrp->msgTmpWrMessageID == CALIBRATE) &&
(wrp->wrMode == WR_MASTER)) {
wrp->next_state = WRS_RESP_CALIB_REQ;
return 0;
}
else if ((wrp->msgTmpWrMessageID == WR_MODE_ON) &&
(wrp->wrMode == WR_SLAVE)) {
wrp->next_state = WRS_WR_LINK_ON;
if ( msg_unpack_wrsig(ppi, buf, &wrsig_msg, &wrMsgId) ) {
if ((wrMsgId == CALIBRATE) &&
(wrp->wrMode == WR_MASTER)) {
wrp->next_state = WRS_RESP_CALIB_REQ;
}
else if ((wrMsgId == WR_MODE_ON) &&
(wrp->wrMode == WR_SLAVE)) {
wrp->next_state = WRS_WR_LINK_ON;
} else
wrp->next_state = WRS_IDLE; // Unexpected msg: abort handshake
return 0;
}
}
{
......
......@@ -9,55 +9,40 @@
#include <ppsi/ppsi.h>
/*
* WRS_PRESENT is the entry point for a WR slave
*
* Here we send SLAVE_PRESENT and wait for LOCK. If timeout,
* re-send SLAVE_PRESENT from WR_STATE_RETRY times
* WRS_IDLE is the entry point for the IDLE state
*/
int wr_idle(struct pp_instance *ppi, void *buf, int len, int new_state)
{
int delay=1000;//INT_MAX;
int delay=1000;// default delay
struct wr_dsport *wrp = WR_DSPOR(ppi);
if ( ppi->ext_enabled ) {
/* While the extension is enabled, we expect to have
* a working WR connection.
if ( ppi->state==PPS_MASTER ) {
/* Check the reception of a slave present message.
* If it arrives we must restart the WR handshake
*/
struct wr_dsport *wrp = WR_DSPOR(ppi);
switch (ppi->state) {
case PPS_MASTER :
{
/* Check the reception of a slave present message.
* If it arrives we must restart the WR handshake
*/
if (ppi->received_ptp_header.messageType == PPM_SIGNALING) {
Enumeration16 wrMsgId;
MsgSignaling wrsig_msg;
if (ppi->received_ptp_header.messageType == PPM_SIGNALING) {
msg_unpack_wrsig(ppi, buf, &wrsig_msg,
&(wrp->msgTmpWrMessageID));
if (wrp->msgTmpWrMessageID == SLAVE_PRESENT) {
lstate_set_link_in_progress(ppi);
if ( msg_unpack_wrsig(ppi, buf, &wrsig_msg, &wrMsgId) ) {
if ( wrMsgId == SLAVE_PRESENT) {
// Start handshake
wrp->next_state = WRS_M_LOCK;
delay=0;
}
pdstate_enable_extension(ppi); // Enable extension in all cases
}
if ( wrp->wrModeOn && wrp->parentWrModeOn )
lstate_set_link_established(ppi);
break;
}
case PPS_SLAVE :
} else {
if ( ppi->ext_enabled && ppi->state==PPS_SLAVE ) {
if ( !(wrp->wrModeOn && wrp->parentWrModeOn) ) {
/* Failure detected in the protocol */
ppi->next_state=PPS_UNCALIBRATED;
wr_reset_process(ppi,WR_ROLE_NONE);
lstate_set_link_pdetection(ppi);
}
break;
case PPS_UNCALIBRATED :
break;
}
}
return delay;
}
......@@ -18,7 +18,6 @@
int wr_locked(struct pp_instance *ppi, void *buf, int len, int new_state)
{
int sendmsg = 0;
MsgSignaling wrsig_msg;
struct wr_dsport *wrp = WR_DSPOR(ppi);
if (new_state) {
......@@ -28,12 +27,13 @@ int wr_locked(struct pp_instance *ppi, void *buf, int len, int new_state)
sendmsg = 1;
} else {
if (ppi->received_ptp_header.messageType == PPM_SIGNALING) {
Enumeration16 wrMsgId;
MsgSignaling wrsig_msg;
msg_unpack_wrsig(ppi, buf, &wrsig_msg,
&(wrp->msgTmpWrMessageID));
if (wrp->msgTmpWrMessageID == CALIBRATE) {
wrp->next_state = WRS_RESP_CALIB_REQ;
if ( msg_unpack_wrsig(ppi, buf, &wrsig_msg, &wrMsgId) ) {
wrp->next_state= wrMsgId == CALIBRATE ?
WRS_RESP_CALIB_REQ :
WRS_IDLE;
return 0;
}
}
......
......@@ -18,7 +18,6 @@
int wr_m_lock(struct pp_instance *ppi, void *buf, int len, int new_state)
{
int sendmsg = 0;
MsgSignaling wrsig_msg;
struct wr_dsport *wrp = WR_DSPOR(ppi);
if (new_state) {
......@@ -28,11 +27,13 @@ int wr_m_lock(struct pp_instance *ppi, void *buf, int len, int new_state)
sendmsg = 1;
} else {
if (ppi->received_ptp_header.messageType == PPM_SIGNALING) {
msg_unpack_wrsig(ppi, buf, &wrsig_msg,
&(wrp->msgTmpWrMessageID));
Enumeration16 wrMsgId;
MsgSignaling wrsig_msg;
if (wrp->msgTmpWrMessageID == LOCKED) {
wrp->next_state = WRS_CALIBRATION;
if ( msg_unpack_wrsig(ppi, buf, &wrsig_msg,&wrMsgId) ) {
wrp->next_state = wrMsgId == LOCKED ?
WRS_CALIBRATION :
WRS_IDLE;
return 0;
}
}
......
......@@ -22,8 +22,6 @@ int wr_present(struct pp_instance *ppi, void *buf, int len, int new_state)
int sendmsg = 0;
struct wr_dsport *wrp = WR_DSPOR(ppi);
MsgSignaling wrsig_msg;
if (new_state) {
wr_servo_init(ppi);
wrp->wrStateRetry = WR_STATE_RETRY;
......@@ -31,12 +29,13 @@ int wr_present(struct pp_instance *ppi, void *buf, int len, int new_state)
sendmsg = 1;
} else {
if (ppi->received_ptp_header.messageType == PPM_SIGNALING) {
msg_unpack_wrsig(ppi, buf, &wrsig_msg,
&(wrp->msgTmpWrMessageID));
Enumeration16 wrMsgId;
MsgSignaling wrsig_msg;
if (wrp->msgTmpWrMessageID == LOCK) {
wrp->next_state = WRS_S_LOCK;
lstate_set_link_in_progress(ppi);
if ( msg_unpack_wrsig(ppi, buf, &wrsig_msg, &wrMsgId) ) {
wrp->next_state = wrMsgId == LOCK ?
WRS_S_LOCK :
WRS_IDLE;
return 0;
}
}
......
......@@ -14,7 +14,6 @@
int wr_resp_calib_req(struct pp_instance *ppi, void *buf, int len, int new_state)
{
struct wr_dsport *wrp = WR_DSPOR(ppi);
MsgSignaling wrsig_msg;
if (new_state) {
wrp->wrStateRetry = WR_STATE_RETRY;
......@@ -22,11 +21,11 @@ int wr_resp_calib_req(struct pp_instance *ppi, void *buf, int len, int new_state
} else {
if (ppi->received_ptp_header.messageType == PPM_SIGNALING) {
Enumeration16 wrMsgId;
MsgSignaling wrsig_msg;
msg_unpack_wrsig(ppi, buf, &wrsig_msg,
&(wrp->msgTmpWrMessageID));
if (wrp->msgTmpWrMessageID == CALIBRATED) {
if ( msg_unpack_wrsig(ppi, buf, &wrsig_msg, &wrMsgId) ) {
if ( wrMsgId == CALIBRATED) {
/* Update servo */
wr_servo_ext_t *se =WRE_SRV(ppi);
......@@ -36,6 +35,8 @@ int wr_resp_calib_req(struct pp_instance *ppi, void *buf, int len, int new_state
wrp->next_state = (wrp->wrMode == WR_MASTER) ?
WRS_WR_LINK_ON :
WRS_CALIBRATION;
} else
wrp->next_state = WRS_IDLE;
return 0;
}
}
......
......@@ -43,7 +43,6 @@ struct wr_dsport {
Enumeration8 parentWrConfig;
Boolean parentIsWRnode; /* FIXME Not in the doc */
/* FIXME check doc: (parentWrMode?) */
Enumeration16 msgTmpWrMessageID; /* FIXME Not in the doc */
Boolean parentCalibrated;
/* FIXME: are they in the doc? */
......@@ -81,7 +80,7 @@ void msg_unpack_announce_wr_tlv(void *buf, MsgAnnounce *ann, UInteger16 *wrFlags
/* Pack/Unkpack/Issue White rabbit message signaling msg */
int msg_pack_wrsig(struct pp_instance *ppi, Enumeration16 wr_msg_id);
void msg_unpack_wrsig(struct pp_instance *ppi, void *buf,
int msg_unpack_wrsig(struct pp_instance *ppi, void *buf,
MsgSignaling *wrsig_msg, Enumeration16 *wr_msg_id);
int msg_issue_wrsig(struct pp_instance *ppi, Enumeration16 wr_msg_id);
......
......@@ -183,7 +183,8 @@ int msg_pack_wrsig(struct pp_instance *ppi, Enumeration16 wr_msg_id)
}
/* White Rabbit: unpacking wr signaling messages */
void msg_unpack_wrsig(struct pp_instance *ppi, void *buf,
/* Returns 1 if WR message */
int msg_unpack_wrsig(struct pp_instance *ppi, void *buf,
MsgSignaling *wrsig_msg, Enumeration16 *pwr_msg_id)
{
UInteger16 tlv_type;
......@@ -209,25 +210,25 @@ void msg_unpack_wrsig(struct pp_instance *ppi, void *buf,
if (tlv_type != TLV_TYPE_ORG_EXTENSION) {
pp_diag(ppi, frames, 1, "handle Signaling msg, failed, This is not "
"organization extension TLV = 0x%x\n", tlv_type);
return;
return 1;
}
if (tlv_organizationID != WR_TLV_ORGANIZATION_ID) {
pp_diag(ppi, frames, 1, "handle Signaling msg, failed, not CERN's "
"OUI = 0x%x\n", tlv_organizationID);
return;
return 0;
}
if (tlv_magicNumber != WR_TLV_MAGIC_NUMBER) {
pp_diag(ppi, frames, 1, "handle Signaling msg, failed, "
"not White Rabbit magic number = 0x%x\n", tlv_magicNumber);
return;
return 0;
}
if (tlv_versionNumber != WR_TLV_WR_VERSION_NUMBER ) {
pp_diag(ppi, frames, 1, "handle Signaling msg, failed, not supported "
"version number = 0x%x\n", tlv_versionNumber);
return;
return 0;
}
wr_msg_id = ntohs(*(UInteger16 *)(buf + 54));
......@@ -268,7 +269,9 @@ void msg_unpack_wrsig(struct pp_instance *ppi, void *buf,
/* no data */
break;
}
/* FIXME diagnostic */
if ( ppi->pdstate==PP_PDSTATE_PDETECTION)
pdstate_set_state_pdetected(ppi);
return 1;
}
/* Pack and send a White Rabbit signalling message */
......
......@@ -69,27 +69,22 @@ static wr_state_machine_t wr_state_actions[] ={
*/
int wr_run_state_machine(struct pp_instance *ppi, void *buf, int len) {
struct wr_dsport * wrp=WR_DSPOR(ppi);
wr_state_t nextState=wrp->next_state;
Boolean newState=nextState!=wrp->state;
Boolean newState;
int delay;
if ( !ppi->ext_enabled || ppi->state==PPS_INITIALIZING || nextState>=MAX_STATE_ACTIONS) {
if ( wrp->state!=WRS_IDLE ) {
nextState=wrp->next_state=WRS_IDLE;
/* Force to IDLE state when extension is disabled */
} else
return INT_MAX; /* Return a big delay. fsm will then not use it */
if ( wrp->next_state>=MAX_STATE_ACTIONS || ppi->state==PPS_INITIALIZING || !ppi->ext_enabled ) {
wrp->next_state=WRS_IDLE; // Force to IDLE state
}
/*
* Evaluation of events common to all states
*/
newState=wrp->state!=wrp->next_state;
if ( newState ) {
pp_diag(ppi, ext, 2, "WR state: LEAVE=%s, ENTER=%s\n",
wr_state_actions[wrp->state].name,
wr_state_actions[nextState].name);
wrp->state=nextState;
wr_state_actions[wrp->next_state].name);
wrp->state=wrp->next_state;
}
delay=(*wr_state_actions[wrp->state].action) (ppi, buf,len, newState);
......
......@@ -23,9 +23,7 @@ static int presp_call_servo(struct pp_instance *ppi)
if (is_ext_hook_available(ppi,handle_presp))
ret = ppi->ext_hooks->handle_presp(ppi);
else {
if ( pp_servo_got_presp(ppi) && !ppi->ext_enabled ) {
ppi->link_state=PP_LSTATE_LINKED;
}
pp_servo_got_presp(ppi);
}
if ( ppi->state==PPS_MASTER) {
/* Called to update meanLinkDelay
......@@ -174,10 +172,6 @@ int st_com_peer_handle_preq(struct pp_instance *ppi, void *buf,
msg_issue_pdelay_resp(ppi, &ppi->last_rcv_time);
msg_issue_pdelay_resp_followup(ppi, &ppi->last_snt_time);
if ( !ppi->ext_enabled ) {
ppi->link_state=PP_LSTATE_LINKED;
}
return 0;
}
......
......@@ -134,8 +134,7 @@ int pp_initializing(struct pp_instance *ppi, void *buf, int len)
pp_timeout_init(ppi);
pp_timeout_setall(ppi);
ppi->link_state=PP_LSTATE_PROTOCOL_DETECTION;