DEBUG_LOG("Updated RX timestamp delay=%.9f tss=%u",
UTI_DiffTimespecsToDouble(&sched_ts, &local_ts.ts), local_ts.source);
- if (!NIO_UnwrapMessage(message, sock_fd))
+ if (!NIO_UnwrapMessage(message, sock_fd, &local_ts.net_correction))
return;
/* Just ignore the packet if it's not of a recognized length */
/* ================================================== */
int
-NIO_UnwrapMessage(SCK_Message *message, int sock_fd)
+NIO_UnwrapMessage(SCK_Message *message, int sock_fd, double *net_correction)
{
+ double ptp_correction;
PTP_NtpMessage *msg;
if (!is_ptp_socket(sock_fd))
message->data = (char *)message->data + PTP_NTP_PREFIX_LENGTH;
message->length -= PTP_NTP_PREFIX_LENGTH;
- DEBUG_LOG("Unwrapped PTP->NTP len=%d", message->length);
+ ptp_correction = UTI_Integer64NetworkToHost(*(Integer64 *)msg->header.correction) /
+ ((1 << 16) * 1.0e9);
+
+ /* Use the correction only if the RX duration is known (i.e. HW timestamp) */
+ if (*net_correction > 0.0)
+ *net_correction += ptp_correction;
+
+ DEBUG_LOG("Unwrapped PTP->NTP len=%d corr=%.9f", message->length, ptp_correction);
return 1;
}
extern int NIO_IsServerConnectable(NTP_Remote_Address *remote_addr);
/* Function to unwrap an NTP message from non-native transport (e.g. PTP) */
-extern int NIO_UnwrapMessage(SCK_Message *message, int sock_fd);
+extern int NIO_UnwrapMessage(SCK_Message *message, int sock_fd, double *net_correction);
/* Function to transmit a packet */
extern int NIO_SendPacket(NTP_Packet *packet, NTP_Remote_Address *remote_addr,
NTP_Local_Timestamp *local_ts, int rx_ntp_length, int family,
int l2_length)
{
- double rx_correction, ts_delay, local_err;
+ double rx_correction = 0.0, ts_delay, local_err;
struct timespec ts;
poll_phc(iface, &local_ts->ts);
local_ts->ts = ts;
local_ts->err = local_err;
local_ts->source = NTP_TS_HARDWARE;
+ local_ts->rx_duration = rx_correction;
+ /* Network correction needs to include the RX duration to avoid
+ asymmetric correction with asymmetric link speeds */
+ local_ts->net_correction = rx_correction;
}
/* ================================================== */
{
struct Interface *iface;
int is_tx, ts_if_index, l2_length;
+ double c;
is_tx = event == SCH_FILE_EXCEPTION;
iface = NULL;
return 1;
}
- if (!NIO_UnwrapMessage(message, local_addr->sock_fd))
+ if (!NIO_UnwrapMessage(message, local_addr->sock_fd, &c))
return 1;
if (message->length < NTP_HEADER_LENGTH || message->length > sizeof (NTP_Packet))