Commit 621c3372 authored by baujc's avatar baujc

Make correction fields sent in messages compliant with the IEEE standard

- For WR extension, we keep the old way to stay compliant with previous
version of WR
- The changes are applied to HA extension and compliant now with the
IEEE standard (delayAsymmetry sent in the CField of [P]DelayReq msg,
...)
parent 765c661b
...@@ -211,6 +211,9 @@ struct pp_ext_hooks { ...@@ -211,6 +211,9 @@ struct pp_ext_hooks {
void (*state_change)(struct pp_instance *ppi); void (*state_change)(struct pp_instance *ppi);
int (*run_ext_state_machine) (struct pp_instance *ppi); int (*run_ext_state_machine) (struct pp_instance *ppi);
void (*servo_reset)(struct pp_instance *ppi); void (*servo_reset)(struct pp_instance *ppi);
TimeInterval (*get_ingress_latency)(struct pp_instance *ppi);
TimeInterval (*get_egress_latency)(struct pp_instance *ppi);
int (*is_correction_field_compliant)(struct pp_instance *ppi); /* If not defined, it is assumed to be compliant */
/* If the extension requires hardware support for precise time stamp, returns 1 */ /* If the extension requires hardware support for precise time stamp, returns 1 */
int (*require_precise_timestamp)(struct pp_instance *ppi); int (*require_precise_timestamp)(struct pp_instance *ppi);
int (*get_tmo_lstate_detection) (struct pp_instance *ppi); int (*get_tmo_lstate_detection) (struct pp_instance *ppi);
......
...@@ -299,6 +299,25 @@ static int wr_require_precise_timestamp(struct pp_instance *ppi) { ...@@ -299,6 +299,25 @@ static int wr_require_precise_timestamp(struct pp_instance *ppi) {
return WR_DSPOR(ppi)->wrModeOn; return WR_DSPOR(ppi)->wrModeOn;
} }
static int wr_get_tmo_lstate_detection(struct pp_instance *ppi) {
/* The WR protocol detection comes :
* - for a SLAVE: from the announce message (WR TLV)
* - for a MASTER: from the reception of the WR_PRESENT message
* To cover this 2 cases we will use 2 times the announce receipt time-out
*/
return is_externalPortConfigurationEnabled(DSDEF(ppi)) ?
10000 : /* 10s: externalPortConfiguration enable means no ANN_RECEIPT timeout */
pp_timeout_get(ppi,PP_TO_ANN_RECEIPT)<<1;
}
static TimeInterval wr_get_latency (struct pp_instance *ppi) {
return 0;
}
/* WR extension is not compliant with the standard concerning the contents of the correction fields */
static int wr_is_correction_field_compliant (struct pp_instance *ppi) {
return 0;
}
struct pp_ext_hooks wr_ext_hooks = { struct pp_ext_hooks wr_ext_hooks = {
.init = wr_init, .init = wr_init,
.open = wr_open, .open = wr_open,
...@@ -320,4 +339,8 @@ struct pp_ext_hooks wr_ext_hooks = { ...@@ -320,4 +339,8 @@ struct pp_ext_hooks wr_ext_hooks = {
.state_change = wr_state_change, .state_change = wr_state_change,
.servo_reset= wr_servo_reset, .servo_reset= wr_servo_reset,
.require_precise_timestamp=wr_require_precise_timestamp, .require_precise_timestamp=wr_require_precise_timestamp,
.get_tmo_lstate_detection=wr_get_tmo_lstate_detection,
.get_ingress_latency=wr_get_latency,
.get_egress_latency=wr_get_latency,
.is_correction_field_compliant=wr_is_correction_field_compliant,
}; };
#######################################
# J-C Bau, 29 March 2019
# - Correction bring to PPSI to make it compliant with the standard
First, I have added an hook is_correction_field_compliant() to stay
compliant with the old version of WR extension. So modifications I made
impacts only the HA extension.
Improvements for E2E and P2P:
1. When a [P]DelayReq is issue, the correction field contains
the value of -delayAsymmetry (-ppi->portDs->delayAsymmetry)
2. When a [P]DelayReq is received, a [P]DelayResp is sent. It contains on
its correction field, the received correction field (from [P]DelayReq msg)
minus the sub-ns part of the sent time stamp:
txCF=RxCF-sub_ns(timestamp)
3. On reception of [P]DelayResp, the calculated timestamp (t4) is calculated by :
t4=rxTimeStamp-rxCF-delayAsymmetry where
rxTimeStamp= receiveTimestamp(E2) or requestReceiptTimestamp (P2P
rxCF= Received correction field in the [P]DelayResp message
delayAsymmetry= last calculated delayAsymmetry (ppi->portDs->delayAsymmetry)
# End JCB corrections
#######################################
The correctionField makes me mad. We used to have ppi->cField, that The correctionField makes me mad. We used to have ppi->cField, that
nobody knows which frame it refers to. I now keep it for reference, nobody knows which frame it refers to. I now keep it for reference,
associated to the sync message, so we know what the overall TC delay is. associated to the sync message, so we know what the overall TC delay is.
......
...@@ -74,7 +74,20 @@ int st_com_peer_handle_pres(struct pp_instance *ppi, void *buf, ...@@ -74,7 +74,20 @@ int st_com_peer_handle_pres(struct pp_instance *ppi, void *buf,
} }
ppi->received_dresp=1; ppi->received_dresp=1;
ppi->t4 = resp.requestReceiptTimestamp; ppi->t4 = resp.requestReceiptTimestamp;
pp_time_add(&ppi->t4, &hdr->cField); if ( is_ext_hook_available(ppi,is_correction_field_compliant) &&
!ppi->ext_hooks->is_correction_field_compliant(ppi) ) {
/* Not compliant with CF */
pp_time_add(&ppi->t4, &hdr->cField);
} else{
/* We subtract the received CF and the current delayAsymmetry */
struct pp_time delayAsym={
.secs=0,
.scaled_nsecs=ppi->portDS->delayAsymmetry
};
pp_time_sub(&ppi->t4, &hdr->cField);
pp_time_sub(&ppi->t4, &delayAsym);
}
/* WARNING: should be "sub" (see README-cfield::BUG) */ /* WARNING: should be "sub" (see README-cfield::BUG) */
ppi->t6 = ppi->last_rcv_time; ppi->t6 = ppi->last_rcv_time;
if ((hdr->flagField[0] & PP_TWO_STEP_FLAG) != 0) if ((hdr->flagField[0] & PP_TWO_STEP_FLAG) != 0)
......
...@@ -64,10 +64,18 @@ static int msg_pack_pdelay_req(struct pp_instance *ppi, ...@@ -64,10 +64,18 @@ static int msg_pack_pdelay_req(struct pp_instance *ppi,
void *buf = ppi->tx_ptp; void *buf = ppi->tx_ptp;
struct pp_msgtype_info *mf = pp_msgtype_info + PPM_PDELAY_REQ_FMT; struct pp_msgtype_info *mf = pp_msgtype_info + PPM_PDELAY_REQ_FMT;
int len= __msg_pack_header(ppi, mf); int len= __msg_pack_header(ppi, mf);
Integer64 correction_field;
/* Header */ /* Header */
__msg_set_seq_id(ppi,mf); __msg_set_seq_id(ppi,mf);
correction_field=
is_ext_hook_available(ppi,is_correction_field_compliant) &&
!ppi->ext_hooks->is_correction_field_compliant(ppi) ?
0 :
-ppi->portDS->delayAsymmetry; /* Set -delayAsymmetry in CF */
*(Integer64 *) (buf + 8) = htonll(correction_field);
/* PDelay_req message - we may send zero instead */ /* PDelay_req message - we may send zero instead */
__pack_origin_timestamp(buf,now); __pack_origin_timestamp(buf,now);
memset((buf + 44), 0, 10); memset((buf + 44), 0, 10);
...@@ -82,15 +90,18 @@ static int msg_pack_pdelay_resp(struct pp_instance *ppi, ...@@ -82,15 +90,18 @@ static int msg_pack_pdelay_resp(struct pp_instance *ppi,
UInteger8 *flags8 = buf + 6;; UInteger8 *flags8 = buf + 6;;
struct pp_msgtype_info *mf = pp_msgtype_info + PPM_PDELAY_RESP_FMT; struct pp_msgtype_info *mf = pp_msgtype_info + PPM_PDELAY_RESP_FMT;
int len= __msg_pack_header(ppi, mf); int len= __msg_pack_header(ppi, mf);
Integer64 correction_field, sub_ns;
/* Header */ /* Header */
sub_ns=rcv_tstamp->scaled_nsecs & 0xffff;
correction_field=is_ext_hook_available(ppi,is_correction_field_compliant) &&
!ppi->ext_hooks->is_correction_field_compliant(ppi) ?
sub_ns : /* None compliant CF */
pp_time_to_interval(&hdr->cField)-sub_ns; /* Set rxCF-sub_ns */
*(Integer64 *) (buf + 8) = htonll(correction_field);
flags8[0] = PP_TWO_STEP_FLAG; /* Table 20) */ flags8[0] = PP_TWO_STEP_FLAG; /* Table 20) */
*(UInteger16 *) (buf + 30) = htons(hdr->sequenceId); *(UInteger16 *) (buf + 30) = htons(hdr->sequenceId);
/* cField: shdould be the fractional negated (see README-cfield) */
*(UInteger64 *)(buf + 8) =
htonll(rcv_tstamp->scaled_nsecs & 0xffff);
/* requestReceiptTimestamp */ /* requestReceiptTimestamp */
__pack_origin_timestamp(buf,rcv_tstamp); __pack_origin_timestamp(buf,rcv_tstamp);
......
...@@ -306,10 +306,18 @@ static int msg_pack_delay_req(struct pp_instance *ppi, ...@@ -306,10 +306,18 @@ static int msg_pack_delay_req(struct pp_instance *ppi,
void *buf = ppi->tx_ptp; void *buf = ppi->tx_ptp;
struct pp_msgtype_info *mf = pp_msgtype_info + PPM_DELAY_REQ_FMT; struct pp_msgtype_info *mf = pp_msgtype_info + PPM_DELAY_REQ_FMT;
int len= __msg_pack_header(ppi, mf); int len= __msg_pack_header(ppi, mf);
Integer64 correction_field;
/* Header */ /* Header */
__msg_set_seq_id(ppi,mf); __msg_set_seq_id(ppi,mf);
correction_field=
is_ext_hook_available(ppi,is_correction_field_compliant) &&
!ppi->ext_hooks->is_correction_field_compliant(ppi) ?
0 :
-ppi->portDS->delayAsymmetry; /* Set -delayAsymmetry in CF */
*(Integer64 *) (buf + 8) = htonll(correction_field);
/* Delay_req message - we may send zero instead */ /* Delay_req message - we may send zero instead */
memset((buf + 34), 0, 10); memset((buf + 34), 0, 10);
/* Adjust time stamp */ /* Adjust time stamp */
...@@ -325,13 +333,15 @@ static int msg_pack_delay_resp(struct pp_instance *ppi, ...@@ -325,13 +333,15 @@ static int msg_pack_delay_resp(struct pp_instance *ppi,
void *buf = ppi->tx_ptp; void *buf = ppi->tx_ptp;
struct pp_msgtype_info *mf = pp_msgtype_info + PPM_DELAY_RESP_FMT; struct pp_msgtype_info *mf = pp_msgtype_info + PPM_DELAY_RESP_FMT;
int len= __msg_pack_header(ppi, mf); int len= __msg_pack_header(ppi, mf);
Integer64 correction_field, sub_ns;
/* Header */ /* Header */
/* sub_ns=rcv_tstamp->scaled_nsecs & 0xffff;
* We should copy the cField of the request, and then subract correction_field=is_ext_hook_available(ppi,is_correction_field_compliant) &&
* our fractional part. However, we add it (see README-cfield::BUG) !ppi->ext_hooks->is_correction_field_compliant(ppi) ?
*/ sub_ns : /* None compliant CF */
*(Integer64 *) (buf + 8) = htonll(rcv_tstamp->scaled_nsecs & 0xffff); pp_time_to_interval(&hdr->cField)-sub_ns; /* Set rxCF-sub_ns */
*(Integer64 *) (buf + 8) = htonll(correction_field);
*(UInteger16 *) (buf + 30) = htons(hdr->sequenceId); *(UInteger16 *) (buf + 30) = htons(hdr->sequenceId);
/* Delay_resp message */ /* Delay_resp message */
......
...@@ -156,8 +156,20 @@ static int slave_handle_response(struct pp_instance *ppi, void *buf, ...@@ -156,8 +156,20 @@ static int slave_handle_response(struct pp_instance *ppi, void *buf,
} }
ppi->t4 = resp.receiveTimestamp; ppi->t4 = resp.receiveTimestamp;
pp_time_add(&ppi->t4, &hdr->cField); if ( is_ext_hook_available(ppi,is_correction_field_compliant) &&
/* WARNING: should be "sub" (see README-cfield::BUG) */ !ppi->ext_hooks->is_correction_field_compliant(ppi) ) {
/* Not compliant with CF */
pp_time_add(&ppi->t4, &hdr->cField);
} else{
/* We subtract the received CF and the current delayAsymmetry */
struct pp_time delayAsym={
.secs=0,
.scaled_nsecs=ppi->portDS->delayAsymmetry
};
pp_time_sub(&ppi->t4, &hdr->cField);
pp_time_sub(&ppi->t4, &delayAsym);
}
if (is_ext_hook_available(ppi,handle_resp)) { if (is_ext_hook_available(ppi,handle_resp)) {
ret=ppi->ext_hooks->handle_resp(ppi); ret=ppi->ext_hooks->handle_resp(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