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