use common structure for NTP samples

Define a structure for NTP samples and use it to pass samples from
the ntp_core and refclock code to sources and sourcestats.
This commit is contained in:
Miroslav Lichvar 2018-08-01 16:28:26 +02:00
parent 108d112272
commit 6bef8aa0e9
8 changed files with 97 additions and 147 deletions

15
ntp.h
View file

@ -121,4 +121,19 @@ typedef struct {
#define NTP_REFID_LOCAL 0x7F7F0101UL /* 127.127.1.1 */ #define NTP_REFID_LOCAL 0x7F7F0101UL /* 127.127.1.1 */
#define NTP_REFID_SMOOTH 0x7F7F01FFUL /* 127.127.1.255 */ #define NTP_REFID_SMOOTH 0x7F7F01FFUL /* 127.127.1.255 */
/* Structure used to save NTP measurements. time is the local time at which
the sample is to be considered to have been made and offset is the offset at
the time (positive indicates that the local clock is slow relative to the
source). root_delay/root_dispersion include peer_delay/peer_dispersion. */
typedef struct {
struct timespec time;
double offset;
double peer_delay;
double peer_dispersion;
double root_delay;
double root_dispersion;
int stratum;
NTP_Leap leap;
} NTP_Sample;
#endif /* GOT_NTP_H */ #endif /* GOT_NTP_H */

View file

@ -1455,6 +1455,7 @@ static int
receive_packet(NCR_Instance inst, NTP_Local_Address *local_addr, receive_packet(NCR_Instance inst, NTP_Local_Address *local_addr,
NTP_Local_Timestamp *rx_ts, NTP_Packet *message, int length) NTP_Local_Timestamp *rx_ts, NTP_Packet *message, int length)
{ {
NTP_Sample sample;
SST_Stats stats; SST_Stats stats;
int pkt_leap, pkt_version; int pkt_leap, pkt_version;
@ -1463,24 +1464,6 @@ receive_packet(NCR_Instance inst, NTP_Local_Address *local_addr,
double pkt_root_dispersion; double pkt_root_dispersion;
AuthenticationMode pkt_auth_mode; AuthenticationMode pkt_auth_mode;
/* The local time to which the (offset, delay, dispersion) triple will
be taken to relate. For client/server operation this is practically
the same as either the transmit or receive time. The difference comes
in symmetric active mode, when the receive may come minutes after the
transmit, and this time will be midway between the two */
struct timespec sample_time;
/* The estimated offset in seconds, a positive value indicates that the local
clock is SLOW of the remote source and a negative value indicates that the
local clock is FAST of the remote source */
double offset;
/* The estimated peer delay, dispersion and distance */
double delay, dispersion, distance;
/* The total root delay and dispersion */
double root_delay, root_dispersion;
/* The skew and estimated frequency offset relative to the remote source */ /* The skew and estimated frequency offset relative to the remote source */
double skew, source_freq_lo, source_freq_hi; double skew, source_freq_lo, source_freq_hi;
@ -1622,23 +1605,23 @@ receive_packet(NCR_Instance inst, NTP_Local_Address *local_addr,
precision = LCL_GetSysPrecisionAsQuantum() + UTI_Log2ToDouble(message->precision); precision = LCL_GetSysPrecisionAsQuantum() + UTI_Log2ToDouble(message->precision);
/* Calculate delay */ /* Calculate delay */
delay = fabs(local_interval - remote_interval); sample.peer_delay = fabs(local_interval - remote_interval);
if (delay < precision) if (sample.peer_delay < precision)
delay = precision; sample.peer_delay = precision;
/* Calculate offset. Following the NTP definition, this is negative /* Calculate offset. Following the NTP definition, this is negative
if we are fast of the remote source. */ if we are fast of the remote source. */
offset = UTI_DiffTimespecsToDouble(&remote_average, &local_average); sample.offset = UTI_DiffTimespecsToDouble(&remote_average, &local_average);
/* Apply configured correction */ /* Apply configured correction */
offset += inst->offset_correction; sample.offset += inst->offset_correction;
/* We treat the time of the sample as being midway through the local /* We treat the time of the sample as being midway through the local
measurement period. An analysis assuming constant relative measurement period. An analysis assuming constant relative
frequency and zero network delay shows this is the only possible frequency and zero network delay shows this is the only possible
choice to estimate the frequency difference correctly for every choice to estimate the frequency difference correctly for every
sample pair. */ sample pair. */
sample_time = local_average; sample.time = local_average;
SST_GetFrequencyRange(stats, &source_freq_lo, &source_freq_hi); SST_GetFrequencyRange(stats, &source_freq_lo, &source_freq_hi);
@ -1646,7 +1629,7 @@ receive_packet(NCR_Instance inst, NTP_Local_Address *local_addr,
skew = (source_freq_hi - source_freq_lo) / 2.0; skew = (source_freq_hi - source_freq_lo) / 2.0;
/* and then calculate peer dispersion */ /* and then calculate peer dispersion */
dispersion = MAX(precision, MAX(local_transmit.err, local_receive.err)) + sample.peer_dispersion = MAX(precision, MAX(local_transmit.err, local_receive.err)) +
skew * fabs(local_interval); skew * fabs(local_interval);
/* If the source is an active peer, this is the minimum assumed interval /* If the source is an active peer, this is the minimum assumed interval
@ -1661,10 +1644,11 @@ receive_packet(NCR_Instance inst, NTP_Local_Address *local_addr,
processing time is sane, and in interleaved symmetric mode that the processing time is sane, and in interleaved symmetric mode that the
measured delay and intervals between remote timestamps don't indicate measured delay and intervals between remote timestamps don't indicate
a missed response */ a missed response */
testA = delay - dispersion <= inst->max_delay && precision <= inst->max_delay && testA = sample.peer_delay - sample.peer_dispersion <= inst->max_delay &&
precision <= inst->max_delay &&
!(inst->mode == MODE_CLIENT && response_time > MAX_SERVER_INTERVAL) && !(inst->mode == MODE_CLIENT && response_time > MAX_SERVER_INTERVAL) &&
!(inst->mode == MODE_ACTIVE && interleaved_packet && !(inst->mode == MODE_ACTIVE && interleaved_packet &&
(delay > 0.5 * prev_remote_poll_interval || (sample.peer_delay > 0.5 * prev_remote_poll_interval ||
UTI_CompareNtp64(&message->receive_ts, &message->transmit_ts) <= 0 || UTI_CompareNtp64(&message->receive_ts, &message->transmit_ts) <= 0 ||
(inst->remote_poll <= inst->prev_local_poll && (inst->remote_poll <= inst->prev_local_poll &&
UTI_DiffTimespecsToDouble(&remote_transmit, &prev_remote_transmit) > UTI_DiffTimespecsToDouble(&remote_transmit, &prev_remote_transmit) >
@ -1673,14 +1657,14 @@ receive_packet(NCR_Instance inst, NTP_Local_Address *local_addr,
/* Test B requires in client mode that the ratio of the round trip delay /* Test B requires in client mode that the ratio of the round trip delay
to the minimum one currently in the stats data register is less than an to the minimum one currently in the stats data register is less than an
administrator-defined value */ administrator-defined value */
testB = check_delay_ratio(inst, stats, &sample_time, delay); testB = check_delay_ratio(inst, stats, &sample.time, sample.peer_delay);
/* Test C requires that the ratio of the increase in delay from the minimum /* Test C requires that the ratio of the increase in delay from the minimum
one in the stats data register to the standard deviation of the offsets one in the stats data register to the standard deviation of the offsets
in the register is less than an administrator-defined value or the in the register is less than an administrator-defined value or the
difference between measured offset and predicted offset is larger than difference between measured offset and predicted offset is larger than
the increase in delay */ the increase in delay */
testC = check_delay_dev_ratio(inst, stats, &sample_time, offset, delay); testC = check_delay_dev_ratio(inst, stats, &sample.time, sample.offset, sample.peer_delay);
/* Test D requires that the remote peer is not synchronised to us to /* Test D requires that the remote peer is not synchronised to us to
prevent a synchronisation loop */ prevent a synchronisation loop */
@ -1688,8 +1672,8 @@ receive_packet(NCR_Instance inst, NTP_Local_Address *local_addr,
pkt_refid != UTI_IPToRefid(&local_addr->ip_addr); pkt_refid != UTI_IPToRefid(&local_addr->ip_addr);
} else { } else {
remote_interval = local_interval = response_time = 0.0; remote_interval = local_interval = response_time = 0.0;
offset = delay = dispersion = 0.0; sample.offset = sample.peer_delay = sample.peer_dispersion = 0.0;
sample_time = rx_ts->ts; sample.time = rx_ts->ts;
local_receive = *rx_ts; local_receive = *rx_ts;
local_transmit = inst->local_tx; local_transmit = inst->local_tx;
testA = testB = testC = testD = 0; testA = testB = testC = testD = 0;
@ -1699,9 +1683,10 @@ receive_packet(NCR_Instance inst, NTP_Local_Address *local_addr,
the additional tests passed */ the additional tests passed */
good_packet = testA && testB && testC && testD; good_packet = testA && testB && testC && testD;
root_delay = pkt_root_delay + delay; sample.root_delay = pkt_root_delay + sample.peer_delay;
root_dispersion = pkt_root_dispersion + dispersion; sample.root_dispersion = pkt_root_dispersion + sample.peer_dispersion;
distance = dispersion + 0.5 * delay; sample.stratum = MAX(message->stratum, inst->min_stratum);
sample.leap = (NTP_Leap)pkt_leap;
/* Update the NTP timestamps. If it's a valid packet from a synchronised /* Update the NTP timestamps. If it's a valid packet from a synchronised
source, the timestamps may be used later when processing a packet in the source, the timestamps may be used later when processing a packet in the
@ -1770,7 +1755,8 @@ receive_packet(NCR_Instance inst, NTP_Local_Address *local_addr,
UTI_Ntp64ToString(&message->receive_ts), UTI_Ntp64ToString(&message->receive_ts),
UTI_Ntp64ToString(&message->transmit_ts)); UTI_Ntp64ToString(&message->transmit_ts));
DEBUG_LOG("offset=%.9f delay=%.9f dispersion=%f root_delay=%f root_dispersion=%f", DEBUG_LOG("offset=%.9f delay=%.9f dispersion=%f root_delay=%f root_dispersion=%f",
offset, delay, dispersion, root_delay, root_dispersion); sample.offset, sample.peer_delay, sample.peer_dispersion,
sample.root_delay, sample.root_dispersion);
DEBUG_LOG("remote_interval=%.9f local_interval=%.9f response_time=%.9f txs=%c rxs=%c", DEBUG_LOG("remote_interval=%.9f local_interval=%.9f response_time=%.9f txs=%c rxs=%c",
remote_interval, local_interval, response_time, remote_interval, local_interval, response_time,
tss_chars[local_transmit.source], tss_chars[local_receive.source]); tss_chars[local_transmit.source], tss_chars[local_receive.source]);
@ -1793,25 +1779,20 @@ receive_packet(NCR_Instance inst, NTP_Local_Address *local_addr,
if (good_packet) { if (good_packet) {
/* Do this before we accumulate a new sample into the stats registers, obviously */ /* Do this before we accumulate a new sample into the stats registers, obviously */
estimated_offset = SST_PredictOffset(stats, &sample_time); estimated_offset = SST_PredictOffset(stats, &sample.time);
SRC_AccumulateSample(inst->source,
&sample_time,
offset, delay, dispersion,
root_delay, root_dispersion,
MAX(message->stratum, inst->min_stratum),
(NTP_Leap) pkt_leap);
SRC_AccumulateSample(inst->source, &sample);
SRC_SelectSource(inst->source); SRC_SelectSource(inst->source);
/* Now examine the registers. First though, if the prediction is /* Now examine the registers. First though, if the prediction is
not even within +/- the peer distance of the peer, we are clearly not even within +/- the peer distance of the peer, we are clearly
not tracking the peer at all well, so we back off the sampling not tracking the peer at all well, so we back off the sampling
rate depending on just how bad the situation is. */ rate depending on just how bad the situation is. */
error_in_estimate = fabs(-offset - estimated_offset); error_in_estimate = fabs(-sample.offset - estimated_offset);
/* Now update the polling interval */ /* Now update the polling interval */
adjust_poll(inst, get_poll_adj(inst, error_in_estimate, distance)); adjust_poll(inst, get_poll_adj(inst, error_in_estimate,
sample.peer_dispersion + 0.5 * sample.peer_delay));
/* If we're in burst mode, check whether the burst is completed and /* If we're in burst mode, check whether the burst is completed and
revert to the previous mode */ revert to the previous mode */
@ -1878,9 +1859,9 @@ receive_packet(NCR_Instance inst, NTP_Local_Address *local_addr,
inst->report.root_dispersion = pkt_root_dispersion; inst->report.root_dispersion = pkt_root_dispersion;
inst->report.ref_id = pkt_refid; inst->report.ref_id = pkt_refid;
UTI_Ntp64ToTimespec(&message->reference_ts, &inst->report.ref_time); UTI_Ntp64ToTimespec(&message->reference_ts, &inst->report.ref_time);
inst->report.offset = offset; inst->report.offset = sample.offset;
inst->report.peer_delay = delay; inst->report.peer_delay = sample.peer_delay;
inst->report.peer_dispersion = dispersion; inst->report.peer_dispersion = sample.peer_dispersion;
inst->report.response_time = response_time; inst->report.response_time = response_time;
inst->report.jitter_asymmetry = SST_GetJitterAsymmetry(stats); inst->report.jitter_asymmetry = SST_GetJitterAsymmetry(stats);
inst->report.tests = ((((((((test1 << 1 | test2) << 1 | test3) << 1 | inst->report.tests = ((((((((test1 << 1 | test2) << 1 | test3) << 1 |
@ -1897,14 +1878,14 @@ receive_packet(NCR_Instance inst, NTP_Local_Address *local_addr,
/* Do measurement logging */ /* Do measurement logging */
if (logfileid != -1 && (log_raw_measurements || synced_packet)) { if (logfileid != -1 && (log_raw_measurements || synced_packet)) {
LOG_FileWrite(logfileid, "%s %-15s %1c %2d %1d%1d%1d %1d%1d%1d %1d%1d%1d%d %2d %2d %4.2f %10.3e %10.3e %10.3e %10.3e %10.3e %08"PRIX32" %1d%1c %1c %1c", LOG_FileWrite(logfileid, "%s %-15s %1c %2d %1d%1d%1d %1d%1d%1d %1d%1d%1d%d %2d %2d %4.2f %10.3e %10.3e %10.3e %10.3e %10.3e %08"PRIX32" %1d%1c %1c %1c",
UTI_TimeToLogForm(sample_time.tv_sec), UTI_TimeToLogForm(sample.time.tv_sec),
UTI_IPToString(&inst->remote_addr.ip_addr), UTI_IPToString(&inst->remote_addr.ip_addr),
leap_chars[pkt_leap], leap_chars[pkt_leap],
message->stratum, message->stratum,
test1, test2, test3, test5, test6, test7, testA, testB, testC, testD, test1, test2, test3, test5, test6, test7, testA, testB, testC, testD,
inst->local_poll, message->poll, inst->local_poll, message->poll,
inst->poll_score, inst->poll_score,
offset, delay, dispersion, sample.offset, sample.peer_delay, sample.peer_dispersion,
pkt_root_delay, pkt_root_dispersion, pkt_refid, pkt_root_delay, pkt_root_dispersion, pkt_refid,
NTP_LVM_TO_MODE(message->lvm), interleaved_packet ? 'I' : 'B', NTP_LVM_TO_MODE(message->lvm), interleaved_packet ? 'I' : 'B',
tss_chars[local_transmit.source], tss_chars[local_transmit.source],

View file

@ -651,26 +651,30 @@ poll_timeout(void *arg)
} }
if (!(inst->driver->poll && inst->driver_polled < (1 << (inst->poll - inst->driver_poll)))) { if (!(inst->driver->poll && inst->driver_polled < (1 << (inst->poll - inst->driver_poll)))) {
double offset, dispersion; NTP_Sample sample;
struct timespec sample_time; int sample_ok;
int sample_ok, stratum;
sample_ok = filter_get_sample(&inst->filter, &sample_time, &offset, &dispersion); sample_ok = filter_get_sample(&inst->filter, &sample.time,
&sample.offset, &sample.peer_dispersion);
inst->driver_polled = 0; inst->driver_polled = 0;
if (sample_ok) { if (sample_ok) {
sample.peer_delay = inst->delay;
sample.root_delay = sample.peer_delay;
sample.root_dispersion = sample.peer_dispersion;
sample.leap = inst->leap_status;
if (inst->pps_active && inst->lock_ref == -1) if (inst->pps_active && inst->lock_ref == -1)
/* Handle special case when PPS is used with local stratum */ /* Handle special case when PPS is used with local stratum */
stratum = pps_stratum(inst, &sample_time); sample.stratum = pps_stratum(inst, &sample.time);
else else
stratum = inst->stratum; sample.stratum = inst->stratum;
SRC_UpdateReachability(inst->source, 1); SRC_UpdateReachability(inst->source, 1);
SRC_AccumulateSample(inst->source, &sample_time, offset, SRC_AccumulateSample(inst->source, &sample);
inst->delay, dispersion, inst->delay, dispersion, stratum, inst->leap_status);
SRC_SelectSource(inst->source); SRC_SelectSource(inst->source);
log_sample(inst, &sample_time, 1, 0, 0.0, offset, dispersion); log_sample(inst, &sample.time, 1, 0, 0.0, sample.offset, sample.peer_dispersion);
} else { } else {
SRC_UpdateReachability(inst->source, 0); SRC_UpdateReachability(inst->source, 0);
} }

View file

@ -329,38 +329,24 @@ SRC_GetSourcestats(SRC_Instance instance)
This function causes the frequency estimation to be re-run for the This function causes the frequency estimation to be re-run for the
designated source, and the clock selection procedure to be re-run designated source, and the clock selection procedure to be re-run
afterwards. afterwards.
Parameters are described in sources.h
*/ */
void SRC_AccumulateSample void
(SRC_Instance inst, SRC_AccumulateSample(SRC_Instance inst, NTP_Sample *sample)
struct timespec *sample_time,
double offset,
double peer_delay,
double peer_dispersion,
double root_delay,
double root_dispersion,
int stratum,
NTP_Leap leap_status)
{ {
assert(initialised); assert(initialised);
DEBUG_LOG("ip=[%s] t=%s ofs=%f del=%f disp=%f str=%d", DEBUG_LOG("ip=[%s] t=%s ofs=%f del=%f disp=%f str=%d",
source_to_string(inst), UTI_TimespecToString(sample_time), -offset, source_to_string(inst), UTI_TimespecToString(&sample->time), -sample->offset,
root_delay, root_dispersion, stratum); sample->root_delay, sample->root_dispersion, sample->stratum);
if (REF_IsLeapSecondClose()) { if (REF_IsLeapSecondClose()) {
LOG(LOGS_INFO, "Dropping sample around leap second"); LOG(LOGS_INFO, "Dropping sample around leap second");
return; return;
} }
/* WE HAVE TO NEGATE OFFSET IN THIS CALL, IT IS HERE THAT THE SENSE OF OFFSET SST_AccumulateSample(inst->stats, sample);
IS FLIPPED */
SST_AccumulateSample(inst->stats, sample_time, -offset, peer_delay, peer_dispersion,
root_delay, root_dispersion, stratum, leap_status);
SST_DoNewRegression(inst->stats); SST_DoNewRegression(inst->stats);
} }

View file

@ -80,34 +80,8 @@ extern void SRC_SetRefid(SRC_Instance instance, uint32_t ref_id, IPAddr *addr);
extern SST_Stats SRC_GetSourcestats(SRC_Instance instance); extern SST_Stats SRC_GetSourcestats(SRC_Instance instance);
/* This function is called by one of the source drivers when it has /* This function is called by one of the source drivers when it has
a new sample that is to be accumulated. a new sample that is to be accumulated */
extern void SRC_AccumulateSample(SRC_Instance instance, NTP_Sample *sample);
This function causes the frequency estimation to be re-run for the
designated source, and the clock selection procedure to be re-run
afterwards.
sample_time is the local time at which the sample is to be
considered to have been made, in terms of doing a regression fit of
offset against local time.
offset is the offset at the time, in seconds. Positive indicates
that the local clock is SLOW relative to the source, negative
indicates that the local clock is FAST relative to it.
root_delay and root_dispersion are in seconds, and are as per
RFC 5905. root_dispersion only includes the peer's root dispersion
+ local sampling precision + skew dispersion accrued during the
measurement. It is the job of the source statistics algorithms +
track.c to add on the extra dispersion due to the residual standard
deviation of the offsets from this source after regression, to form
the root_dispersion field in the packets transmitted to clients or
peers.
stratum is the stratum of the source that supplied the sample.
*/
extern void SRC_AccumulateSample(SRC_Instance instance, struct timespec *sample_time, double offset, double peer_delay, double peer_dispersion, double root_delay, double root_dispersion, int stratum, NTP_Leap leap_status);
/* This routine sets the source as receiving reachability updates */ /* This routine sets the source as receiving reachability updates */
extern void SRC_SetActive(SRC_Instance inst); extern void SRC_SetActive(SRC_Instance inst);

View file

@ -289,11 +289,7 @@ prune_register(SST_Stats inst, int new_oldest)
/* ================================================== */ /* ================================================== */
void void
SST_AccumulateSample(SST_Stats inst, struct timespec *sample_time, SST_AccumulateSample(SST_Stats inst, NTP_Sample *sample)
double offset,
double peer_delay, double peer_dispersion,
double root_delay, double root_dispersion,
int stratum, NTP_Leap leap)
{ {
int n, m; int n, m;
@ -305,7 +301,7 @@ SST_AccumulateSample(SST_Stats inst, struct timespec *sample_time,
/* Make sure it's newer than the last sample */ /* Make sure it's newer than the last sample */
if (inst->n_samples && if (inst->n_samples &&
UTI_CompareTimespecs(&inst->sample_times[inst->last_sample], sample_time) >= 0) { UTI_CompareTimespecs(&inst->sample_times[inst->last_sample], &sample->time) >= 0) {
LOG(LOGS_WARN, "Out of order sample detected, discarding history for %s", LOG(LOGS_WARN, "Out of order sample detected, discarding history for %s",
inst->ip_addr ? UTI_IPToString(inst->ip_addr) : UTI_RefidToString(inst->refid)); inst->ip_addr ? UTI_IPToString(inst->ip_addr) : UTI_RefidToString(inst->refid));
SST_ResetInstance(inst); SST_ResetInstance(inst);
@ -315,15 +311,17 @@ SST_AccumulateSample(SST_Stats inst, struct timespec *sample_time,
(MAX_SAMPLES * REGRESS_RUNS_RATIO); (MAX_SAMPLES * REGRESS_RUNS_RATIO);
m = n % MAX_SAMPLES; m = n % MAX_SAMPLES;
inst->sample_times[n] = *sample_time; /* WE HAVE TO NEGATE OFFSET IN THIS CALL, IT IS HERE THAT THE SENSE OF OFFSET
inst->offsets[n] = offset; IS FLIPPED */
inst->orig_offsets[m] = offset; inst->sample_times[n] = sample->time;
inst->peer_delays[n] = peer_delay; inst->offsets[n] = -sample->offset;
inst->peer_dispersions[m] = peer_dispersion; inst->orig_offsets[m] = -sample->offset;
inst->root_delays[m] = root_delay; inst->peer_delays[n] = sample->peer_delay;
inst->root_dispersions[m] = root_dispersion; inst->peer_dispersions[m] = sample->peer_dispersion;
inst->stratum = stratum; inst->root_delays[m] = sample->root_delay;
inst->leap = leap; inst->root_dispersions[m] = sample->root_dispersion;
inst->stratum = sample->stratum;
inst->leap = sample->leap;
if (inst->peer_delays[n] < inst->fixed_min_delay) if (inst->peer_delays[n] < inst->fixed_min_delay)
inst->peer_delays[n] = 2.0 * inst->fixed_min_delay - inst->peer_delays[n]; inst->peer_delays[n] = 2.0 * inst->fixed_min_delay - inst->peer_delays[n];

View file

@ -51,19 +51,8 @@ extern void SST_ResetInstance(SST_Stats inst);
/* This function changes the reference ID and IP address */ /* This function changes the reference ID and IP address */
extern void SST_SetRefid(SST_Stats inst, uint32_t refid, IPAddr *addr); extern void SST_SetRefid(SST_Stats inst, uint32_t refid, IPAddr *addr);
/* This function accumulates a single sample into the statistics handler /* This function accumulates a single sample into the statistics handler */
extern void SST_AccumulateSample(SST_Stats inst, NTP_Sample *sample);
sample_time is the epoch at which the sample is to be considered to
have been made.
offset is the offset of the local clock relative to the source in
seconds. Positive indicates that the local clock if FAST (contrary
to the NTP parts of the software)
stratum is the stratum of the source from which the sample came.
*/
extern void SST_AccumulateSample(SST_Stats inst, struct timespec *sample_time, double offset, double peer_delay, double peer_dispersion, double root_delay, double root_dispersion, int stratum, NTP_Leap leap);
/* This function runs the linear regression operation on the data. It /* This function runs the linear regression operation on the data. It
finds the set of most recent samples that give the tightest finds the set of most recent samples that give the tightest

View file

@ -26,10 +26,9 @@ test_unit(void)
{ {
SRC_Instance srcs[16]; SRC_Instance srcs[16];
RPT_SourceReport report; RPT_SourceReport report;
NTP_Sample sample;
IPAddr addr; IPAddr addr;
int i, j, k, l, samples, sel_options; int i, j, k, l, samples, sel_options;
double offset, delay, disp;
struct timespec ts;
CNF_Initialise(0, 0); CNF_Initialise(0, 0);
LCL_Initialise(); LCL_Initialise();
@ -59,21 +58,25 @@ test_unit(void)
samples = (i + j) % 5 + 3; samples = (i + j) % 5 + 3;
offset = TST_GetRandomDouble(-1.0, 1.0); sample.offset = TST_GetRandomDouble(-1.0, 1.0);
for (k = 0; k < samples; k++) { for (k = 0; k < samples; k++) {
SCH_GetLastEventTime(&ts, NULL, NULL); SCH_GetLastEventTime(&sample.time, NULL, NULL);
UTI_AddDoubleToTimespec(&ts, TST_GetRandomDouble(k - samples, k - samples + 1), &ts); UTI_AddDoubleToTimespec(&sample.time, TST_GetRandomDouble(k - samples, k - samples + 1),
&sample.time);
offset += TST_GetRandomDouble(-1.0e-2, 1.0e-2); sample.offset += TST_GetRandomDouble(-1.0e-2, 1.0e-2);
delay = TST_GetRandomDouble(1.0e-6, 1.0e-1); sample.peer_delay = TST_GetRandomDouble(1.0e-6, 1.0e-1);
disp = TST_GetRandomDouble(1.0e-6, 1.0e-1); sample.peer_dispersion = TST_GetRandomDouble(1.0e-6, 1.0e-1);
sample.root_delay = sample.peer_delay;
sample.root_dispersion = sample.peer_dispersion;
sample.stratum = 1;
sample.leap = LEAP_Normal;
DEBUG_LOG("source %d sample %d offset %f delay %f disp %f", j, k, DEBUG_LOG("source %d sample %d offset %f delay %f disp %f", j, k,
offset, delay, disp); sample.offset, sample.peer_delay, sample.peer_dispersion);
SRC_AccumulateSample(srcs[j], &ts, offset, delay, disp, delay, disp, SRC_AccumulateSample(srcs[j], &sample);
1, LEAP_Normal);
} }
for (k = 0; k <= j; k++) { for (k = 0; k <= j; k++) {
@ -125,7 +128,7 @@ test_unit(void)
} }
for (j = 0; j < sizeof (srcs) / sizeof (srcs[0]); j++) { for (j = 0; j < sizeof (srcs) / sizeof (srcs[0]); j++) {
SRC_ReportSource(j, &report, &ts); SRC_ReportSource(j, &report, &sample.time);
SRC_DestroyInstance(srcs[j]); SRC_DestroyInstance(srcs[j]);
} }
} }