int version = 3;
NTP_Mode my_mode = MODE_CLIENT;
struct timeval cooked;
- double local_time_err;
union sockaddr_in46 his_addr;
int sock_fd;
socklen_t addrlen;
}
- LCL_ReadCookedTime(&cooked, &local_time_err);
+ LCL_ReadCookedTime(&cooked, NULL);
UTI_TimevalToInt64(&cooked, &pkt.transmit_ts);
if (sendto(sock_fd, (void *) &pkt, NTP_NORMAL_PACKET_SIZE,
his_addr_len = sizeof(his_addr);
/* Get timestamp */
- SCH_GetFileReadyTime(&now);
+ SCH_GetFileReadyTime(&now, NULL);
sock_fd = (long)anything;
status = recvfrom (sock_fd, (char *)&msg, message_length, flags,
unsigned long our_ref_id;
struct timeval our_ref_time;
double our_root_delay, our_root_dispersion;
- double local_time_err;
struct timeval local_transmit;
version = 3;
- LCL_ReadCookedTime(&local_transmit, &local_time_err);
+ LCL_ReadCookedTime(&local_transmit, NULL);
REF_GetReferenceParams(&local_transmit,
&are_we_synchronised, &leap_status,
&our_stratum,
message.receive_ts.hi = 0UL;
message.receive_ts.lo = 0UL;
- LCL_ReadCookedTime(&local_transmit, &local_time_err);
+ LCL_ReadCookedTime(&local_transmit, NULL);
UTI_TimevalToInt64(&local_transmit, &message.transmit_ts);
NIO_SendNormalPacket(&message, &d->addr);
{
RPT_SourceReport report;
struct timeval now_corr;
- double local_clock_err;
/* Get data */
- LCL_ReadCookedTime(&now_corr, &local_clock_err);
+ LCL_ReadCookedTime(&now_corr, NULL);
if (SRC_ReportSource(ntohl(rx_message->data.source_data.index), &report, &now_corr)) {
switch (SRC_GetType(ntohl(rx_message->data.source_data.index))) {
case SRC_NTP:
int status;
RPT_SourcestatsReport report;
struct timeval now_corr;
- double local_clock_err;
- LCL_ReadCookedTime(&now_corr, &local_clock_err);
+ LCL_ReadCookedTime(&now_corr, NULL);
status = SRC_ReportSourcestats(ntohl(rx_message->data.sourcestats.index),
&report, &now_corr);
IPAddr ip;
int i;
struct timeval now;
- double local_time_error;
- LCL_ReadCookedTime(&now, &local_time_error);
+ LCL_ReadCookedTime(&now, NULL);
nc = ntohl(rx_message->data.client_accesses.n_clients);
tx_message->status = htons(STT_SUCCESS);
unsigned long first_index, n_indices, last_index, n_indices_in_table;
int i, j;
struct timeval now;
- double local_time_error;
- LCL_ReadCookedTime(&now, &local_time_error);
+ LCL_ReadCookedTime(&now, NULL);
first_index = ntohl(rx_message->data.client_accesses_by_index.first_index);
n_indices = ntohl(rx_message->data.client_accesses_by_index.n_indices);
unsigned long rx_attempt;
struct timeval now;
struct timeval cooked_now;
- double local_clock_err;
flags = 0;
rx_message_length = sizeof(rx_message);
expected_length = PKL_CommandLength(&rx_message);
LCL_ReadRawTime(&now);
- LCL_ReadCookedTime(&cooked_now, &local_clock_err);
+ LCL_CookTime(&now, &cooked_now, NULL);
tx_message.version = PROTO_VERSION_NUMBER;
tx_message.pkt_type = PKT_TYPE_CMD_REPLY;
if (!(gettimeofday(result, &tz) >= 0)) {
CROAK("Could not get time of day");
}
- return;
-
}
/* ================================================== */
LCL_ReadCookedTime(struct timeval *result, double *err)
{
struct timeval raw;
- double correction;
LCL_ReadRawTime(&raw);
+ LCL_CookTime(&raw, result, err);
+}
- /* For now, cheat and set the error to zero in all cases.
- */
-
- *err = 0.0;
+/* ================================================== */
- /* Call system specific driver to get correction */
- (*drv_offset_convert)(&raw, &correction);
- UTI_AddDoubleToTimeval(&raw, correction, result);
+void
+LCL_CookTime(struct timeval *raw, struct timeval *cooked, double *err)
+{
+ double correction;
- return;
+ LCL_GetOffsetCorrection(raw, &correction, err);
+ UTI_AddDoubleToTimeval(raw, correction, cooked);
}
/* ================================================== */
-double
-LCL_GetOffsetCorrection(struct timeval *raw)
+void
+LCL_GetOffsetCorrection(struct timeval *raw, double *correction, double *err)
{
- double correction;
- (*drv_offset_convert)(raw, &correction);
- return correction;
+ double e;
+
+ /* Call system specific driver to get correction */
+ (*drv_offset_convert)(raw, correction, &e);
+
+ if (err)
+ *err = e;
}
/* ================================================== */
{
ChangeListEntry *ptr;
struct timeval raw, cooked;
- double correction;
double dfreq;
/* Call the system-specific driver for setting the frequency */
dfreq = 1.0e-6 * (afreq_ppm - current_freq_ppm) / (1.0 - 1.0e-6 * current_freq_ppm);
LCL_ReadRawTime(&raw);
- (drv_offset_convert)(&raw, &correction);
- UTI_AddDoubleToTimeval(&raw, correction, &cooked);
+ LCL_CookTime(&raw, &cooked, NULL);
/* Dispatch to all handlers */
for (ptr = change_list.next; ptr != &change_list; ptr = ptr->next) {
{
ChangeListEntry *ptr;
struct timeval raw, cooked;
- double correction;
/* Work out new absolute frequency. Note that absolute frequencies
are handled in units of ppm, whereas the 'dfreq' argument is in
(*drv_set_freq)(current_freq_ppm);
LCL_ReadRawTime(&raw);
- (drv_offset_convert)(&raw, &correction);
- UTI_AddDoubleToTimeval(&raw, correction, &cooked);
+ LCL_CookTime(&raw, &cooked, NULL);
/* Dispatch to all handlers */
for (ptr = change_list.next; ptr != &change_list; ptr = ptr->next) {
{
ChangeListEntry *ptr;
struct timeval raw, cooked;
- double correction;
/* In this case, the cooked time to be passed to the notify clients
has to be the cooked time BEFORE the change was made */
LCL_ReadRawTime(&raw);
- (drv_offset_convert)(&raw, &correction);
- UTI_AddDoubleToTimeval(&raw, correction, &cooked);
+ LCL_CookTime(&raw, &cooked, NULL);
(*drv_accrue_offset)(offset);
{
ChangeListEntry *ptr;
struct timeval raw, cooked;
- double correction;
/* In this case, the cooked time to be passed to the notify clients
has to be the cooked time BEFORE the change was made */
LCL_ReadRawTime(&raw);
- (drv_offset_convert)(&raw, &correction);
- UTI_AddDoubleToTimeval(&raw, correction, &cooked);
+ LCL_CookTime(&raw, &cooked, NULL);
(*drv_apply_step_offset)(offset);
{
ChangeListEntry *ptr;
struct timeval raw, cooked;
- double correction;
double old_freq_ppm;
LCL_ReadRawTime(&raw);
- (drv_offset_convert)(&raw, &correction);
/* Due to modifying the offset, this has to be the cooked time prior
to the change we are about to make */
- UTI_AddDoubleToTimeval(&raw, correction, &cooked);
+ LCL_CookTime(&raw, &cooked, NULL);
old_freq_ppm = current_freq_ppm;
double correction;
LCL_ReadRawTime(&raw);
- correction = LCL_GetOffsetCorrection(&raw);
+ LCL_GetOffsetCorrection(&raw, &correction, NULL);
if (fabs(correction) <= threshold)
return 0;
extern void LCL_ReadCookedTime(struct timeval *t, double *err);
+/* Convert raw time to cooked. */
+extern void LCL_CookTime(struct timeval *raw, struct timeval *cooked, double *err);
+
/* Read the current offset between the system clock and true time
- (i.e. 'cooked' - 'raw') (in seconds). Only intended for use in
- status reporting, really. */
+ (i.e. 'cooked' - 'raw') (in seconds). */
-extern double LCL_GetOffsetCorrection(struct timeval *raw);
+extern void LCL_GetOffsetCorrection(struct timeval *raw, double *correction, double *err);
/* Type of routines that may be invoked as callbacks when there is a
change to the frequency or offset.
/* System driver to convert a raw time to an adjusted (cooked) time.
The number of seconds returned in 'corr' have to be added to the
raw time to get the corrected time */
-typedef void (*lcl_OffsetCorrectionDriver)(struct timeval *raw, double *corr);
+typedef void (*lcl_OffsetCorrectionDriver)(struct timeval *raw, double *corr, double *err);
/* System driver to schedule leap second */
typedef void (*lcl_SetLeapDriver)(int leap);
MNL_AcceptTimestamp(struct timeval *ts, long *offset_cs, double *dfreq_ppm, double *new_afreq_ppm)
{
struct timeval now;
- double local_clock_err;
double offset;
int i;
if (enabled) {
/* Check whether timestamp is within margin of old one */
- LCL_ReadCookedTime(&now, &local_clock_err);
+ LCL_ReadCookedTime(&now, NULL);
UTI_DiffTimevalsToDouble(&offset, &now, ts);
{
int i;
struct timeval now;
- double local_clock_err;
if ((index < 0) || (index >= n_samples)) {
return 0;
/* Now re-estimate. NULLs because we don't want the parameters back
in this case. */
- LCL_ReadCookedTime(&now, &local_clock_err);
+ LCL_ReadCookedTime(&now, NULL);
estimate_and_set_system(&now, 0, 0.0, NULL, NULL, NULL);
return 1;
NTP_Packet message;
int version;
int leap;
- double local_time_err;
struct timeval local_transmit;
/* Parameters read from reference module */
version = 3;
- LCL_ReadCookedTime(&local_transmit, &local_time_err);
+ LCL_ReadCookedTime(&local_transmit, NULL);
REF_GetReferenceParams(&local_transmit,
&are_we_synchronised, &leap_status,
&our_stratum,
/* Transmit - this our local time right now! Also, we might need to
store this for our own use later, next time we receive a message
from the source we're sending to now. */
- LCL_ReadCookedTime(&local_transmit, &local_time_err);
+ LCL_ReadCookedTime(&local_transmit, NULL);
/* Authenticate */
if (do_auth) {
union sockaddr_in46 where_from;
unsigned int flags = 0;
struct timeval now;
+ double now_err;
NTP_Remote_Address remote_addr;
char cmsgbuf[256];
struct msghdr msg;
assert(initialised);
- SCH_GetFileReadyTime(&now);
+ SCH_GetFileReadyTime(&now, &now_err);
iov.iov_base = message.arbitrary;
iov.iov_len = sizeof(message);
#ifdef SO_TIMESTAMP
if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SO_TIMESTAMP) {
struct timeval tv;
- double correction;
memcpy(&tv, CMSG_DATA(cmsg), sizeof(tv));
- correction = LCL_GetOffsetCorrection(&tv);
- UTI_AddDoubleToTimeval(&tv, correction, &tv);
-#if 0
- UTI_DiffTimevalsToDouble(&correction, &now, &tv);
- LOG(LOGS_INFO, LOGF_NtpIO, "timestamp diff: %f", correction);
-#endif
- now = tv;
+ LCL_CookTime(&tv, &now, &now_err);
}
#endif
}
int
RCL_AddSample(RCL_Instance instance, struct timeval *sample_time, double offset, NTP_Leap leap_status)
{
- double correction;
+ double correction, err;
struct timeval cooked_time;
- correction = LCL_GetOffsetCorrection(sample_time);
+ LCL_GetOffsetCorrection(sample_time, &correction, &err);
UTI_AddDoubleToTimeval(sample_time, correction, &cooked_time);
if (!valid_sample_time(instance, sample_time))
int
RCL_AddPulse(RCL_Instance instance, struct timeval *pulse_time, double second)
{
- double correction, offset;
+ double correction, err, offset;
struct timeval cooked_time;
int rate;
NTP_Leap leap;
unsigned long ref_id;
- correction = LCL_GetOffsetCorrection(pulse_time);
+ LCL_GetOffsetCorrection(pulse_time, &correction, &err);
UTI_AddDoubleToTimeval(pulse_time, correction, &cooked_time);
if (!valid_sample_time(instance, pulse_time))
{
/* Variables required for logging to statistics log */
struct timeval now;
- double local_clock_err;
assert(initialised);
- LCL_ReadCookedTime(&now, &local_clock_err);
+ LCL_ReadCookedTime(&now, NULL);
write_log(&now,
"0.0.0.0",
double correction;
LCL_ReadRawTime(&now_raw);
- correction = LCL_GetOffsetCorrection(&now_raw);
+ LCL_GetOffsetCorrection(&now_raw, &correction, NULL);
UTI_AddDoubleToTimeval(&now_raw, correction, &now_cooked);
if (are_we_synchronised) {
/* Read RTC time, sandwiched between two polls of the system clock
so we can bound any error. */
- SCH_GetFileReadyTime(&sys_time);
+ SCH_GetFileReadyTime(&sys_time, NULL);
status = ioctl(fd, RTC_RD_TIME, &rtc_raw);
if (status < 0) {
RTC_Linux_Trim(void)
{
struct timeval now;
- double local_clock_err;
/* Remember the slope coefficient - we won't be able to determine a
want |E| <= 0.5, which implies R <= S <= R+1, i.e. R is just
the rounded down part of S, i.e. the seconds part. */
- LCL_ReadCookedTime(&now, &local_clock_err);
+ LCL_ReadCookedTime(&now, NULL);
set_rtc(now.tv_sec);
/* Last timestamp when a file descriptor became readable */
static struct timeval last_fdready;
+static double last_fdready_err;
/* ================================================== */
/* ================================================== */
void
-SCH_GetFileReadyTime(struct timeval *tv)
+SCH_GetFileReadyTime(struct timeval *tv, double *err)
{
*tv = last_fdready;
+ if (err)
+ *err = last_fdready_err;
}
/* ================================================== */
int status;
struct timeval tv, *ptv;
struct timeval now;
- double err;
if (!initialised) {
CROAK("Should be initialised");
} else if (status > 0) {
/* A file descriptor is ready to read */
- LCL_ReadCookedTime(&last_fdready, &err);
+ LCL_ReadCookedTime(&last_fdready, &last_fdready_err);
dispatch_filehandlers(status, &rd);
} else {
/* Get the time (cooked) when file descriptor became ready, intended for use
in file handlers */
-extern void SCH_GetFileReadyTime(struct timeval *tv);
+extern void SCH_GetFileReadyTime(struct timeval *tv, double *err);
/* This queues a timeout to elapse at a given (raw) local time */
extern SCH_TimeoutID SCH_AddTimeout(struct timeval *tv, SCH_TimeoutHandler, SCH_ArbitraryArgument);
{
int i, j, index;
struct timeval now;
- double local_clock_err;
int src_select_ok;
double src_offset, src_offset_sd, src_frequency, src_skew;
double src_accrued_dispersion;
return;
}
- LCL_ReadCookedTime(&now, &local_clock_err);
+ LCL_ReadCookedTime(&now, NULL);
/* Step 1 - build intervals about each source */
n_endpoints = 0;
/* Now just use the statistics of the selected source for
trimming the local clock */
- LCL_ReadCookedTime(&now, &local_clock_err);
+ LCL_ReadCookedTime(&now, NULL);
SST_GetTrackingData(sources[selected_source_index]->stats, &now,
&src_offset, &src_offset_sd,
static void
get_offset_correction(struct timeval *raw,
- double *corr)
+ double *corr, double *err)
{
/* Correction is given by these things :
}
*corr = - (offset_register + fast_slew_remaining) + adjtime_left;
+ *err = 0.0;
return;
}
static void
get_offset_correction(struct timeval *raw,
- double *corr)
+ double *corr, double *err)
{
stop_adjust();
*corr = -offset_register;
start_adjust();
+ *err = 0.0;
}
/* ================================================== */
static void
get_offset_correction(struct timeval *raw,
- double *corr)
+ double *corr, double *err)
{
stop_adjust();
*corr = -offset_register;
start_adjust();
+ *err = 0.0;
return;
}
static void
get_offset_correction(struct timeval *raw,
- double *corr)
+ double *corr, double *err)
{
stop_adjust();
*corr = -offset_register;
start_adjust();
+ *err = 0.0;
return;
}