/* ================================================== */
+static int
+check_delay_dev_ratio(NCR_Instance inst, SST_Stats stats,
+ struct timespec *sample_time, double offset, double delay)
+{
+ double last_sample_ago, predicted_offset, min_delay, skew, std_dev;
+ double delta, max_delta, error_in_estimate;
+
+ if (!SST_GetDelayTestData(stats, sample_time, &last_sample_ago,
+ &predicted_offset, &min_delay, &skew, &std_dev))
+ return 1;
+
+ /* Require that the ratio of the increase in delay from the minimum to the
+ standard deviation is less than max_delay_dev_ratio. In the allowed
+ increase in delay include also dispersion. */
+
+ max_delta = std_dev * inst->max_delay_dev_ratio +
+ last_sample_ago * (skew + LCL_GetMaxClockError());
+ delta = (delay - min_delay) / 2.0;
+
+ if (delta <= max_delta)
+ return 1;
+
+ error_in_estimate = offset + predicted_offset;
+
+ /* Before we decide to drop the sample, make sure the difference between
+ measured offset and predicted offset is not significantly larger than
+ the increase in delay */
+ if (fabs(error_in_estimate) - delta > max_delta)
+ return 1;
+
+ DEBUG_LOG("maxdelaydevratio: error=%e delay=%e delta=%e max_delta=%e",
+ error_in_estimate, delay, delta, max_delta);
+ return 0;
+}
+
+/* ================================================== */
+
static int
receive_packet(NCR_Instance inst, NTP_Local_Address *local_addr,
NTP_Local_Timestamp *rx_ts, NTP_Packet *message, int length)
in the register is less than an administrator-defined value or the
difference between measured offset and predicted offset is larger than
the increase in delay */
- testC = SST_IsGoodSample(stats, -offset, delay, inst->max_delay_dev_ratio,
- LCL_GetMaxClockError(), &sample_time);
+ testC = check_delay_dev_ratio(inst, stats, &sample_time, offset, delay);
/* Test D requires that the remote peer is not synchronised to us to
prevent a synchronisation loop */
/* ================================================== */
int
-SST_IsGoodSample(SST_Stats inst, double offset, double delay,
- double max_delay_dev_ratio, double clock_error, struct timespec *when)
+SST_GetDelayTestData(SST_Stats inst, struct timespec *sample_time,
+ double *last_sample_ago, double *predicted_offset,
+ double *min_delay, double *skew, double *std_dev)
{
- double elapsed, allowed_increase, delay_increase;
-
if (inst->n_samples < 6)
- return 1;
-
- elapsed = UTI_DiffTimespecsToDouble(when, &inst->offset_time);
-
- /* Require that the ratio of the increase in delay from the minimum to the
- standard deviation is less than max_delay_dev_ratio. In the allowed
- increase in delay include also skew and clock_error. */
-
- allowed_increase = inst->std_dev * max_delay_dev_ratio +
- elapsed * (inst->skew + clock_error);
- delay_increase = (delay - SST_MinRoundTripDelay(inst)) / 2.0;
-
- if (delay_increase < allowed_increase)
- return 1;
-
- offset -= inst->estimated_offset + elapsed * inst->estimated_frequency;
-
- /* Before we decide to drop the sample, make sure the difference between
- measured offset and predicted offset is not significantly larger than
- the increase in delay */
- if (fabs(offset) - delay_increase > allowed_increase)
- return 1;
+ return 0;
- DEBUG_LOG("Bad sample: offset=%f delay=%f incr_delay=%f allowed=%f",
- offset, delay, delay_increase, allowed_increase);
+ *last_sample_ago = UTI_DiffTimespecsToDouble(sample_time, &inst->offset_time);
+ *predicted_offset = inst->estimated_offset +
+ *last_sample_ago * inst->estimated_frequency;
+ *min_delay = SST_MinRoundTripDelay(inst);
+ *skew = inst->skew;
+ *std_dev = inst->std_dev;
- return 0;
+ return 1;
}
/* ================================================== */
/* Find the minimum round trip delay in the register */
extern double SST_MinRoundTripDelay(SST_Stats inst);
-/* This routine determines if a new sample is good enough that it should be
- accumulated */
-extern int SST_IsGoodSample(SST_Stats inst, double offset, double delay,
- double max_delay_dev_ratio, double clock_error, struct timespec *when);
+/* Get data needed for testing NTP delay */
+extern int SST_GetDelayTestData(SST_Stats inst, struct timespec *sample_time,
+ double *last_sample_ago, double *predicted_offset,
+ double *min_delay, double *skew, double *std_dev);
extern void SST_SaveToFile(SST_Stats inst, FILE *out);