Version 4 : IPv6 addressing added, 64-bit time values, sourcestats
and tracking reports extended, added flags to NTP source request,
trimmed source report, replaced fixed-point format with floating-point
+ and used also instead of integer microseconds
*/
uint16_t state;
uint16_t mode;
uint32_t since_sample;
- int32_t orig_latest_meas;
- int32_t latest_meas;
- uint32_t latest_meas_err;
- int32_t est_offset;
- uint32_t est_offset_err;
+ Float orig_latest_meas;
+ Float latest_meas;
+ Float latest_meas_err;
+ Float est_offset;
+ Float est_offset_err;
int32_t EOR;
} RPY_Source_Data;
IPAddr ip_addr;
uint32_t stratum;
Timeval ref_time;
- uint32_t current_correction_s;
- uint32_t current_correction_us;
+ Float current_correction;
Float freq_ppm;
Float resid_freq_ppm;
Float skew_ppm;
uint32_t n_samples;
uint32_t n_runs;
uint32_t span_seconds;
- uint32_t sd_us;
+ Float sd;
Float resid_freq_ppm;
Float skew_ppm;
int32_t EOR;
@item Last sample
This column shows the offset between the local clock and the source at
the last measurement. The number in the square brackets shows the
-actual measured offset. This may be suffixed by @code{us} (indicating
+actual measured offset. This may be suffixed by @code{ns} (indicating
+nanoseconds), @code{us} (indicating
microseconds), @code{ms} (indicating milliseconds), or @code{s}
(indicating seconds). The number to the left of the square brackets
shows the original measurement, adjusted to allow for any slews applied
Reference ID : 1.2.3.4 (a.b.c)
Stratum : 3
Ref time (UTC) : Sun May 17 06:13:11 1998
-System time : 0.000000 seconds fast of NTP time
+System time : 0.000000000 seconds fast of NTP time
Frequency : 331.898 ppm fast
Residual freq : 0.004 ppm
Skew : 0.154 ppm
/* ================================================== */
static void
-print_microseconds(unsigned long us)
-{
- if (us <= 9999) {
- printf("%4ldus", us);
- } else if (us <= 9999999) {
- printf("%4ldms", us / 1000);
- } else if (us <= 999999999) {
- printf("%3ld.%01lds", us / 1000000, (us/100000) % 10);
+print_nanoseconds(double s)
+{
+ unsigned long ms, ns;
+
+ ns = s * 1e9 + 0.5;
+ ms = s * 1e3 + 0.5;
+
+ if (ns <= 9999) {
+ printf("%4ldns", ns);
+ } else if (ns <= 9999499) {
+ printf("%4ldus", (ns + 500) / 1000);
+ } else if (ms <= 9999) {
+ printf("%4ldms", ms);
+ } else if (ms <= 999949) {
+ printf("%3ld.%01lds", (ms + 50) / 1000, ((ms + 50) / 100) % 10);
} else {
- printf("%5lds", us / 1000000);
+ printf("%5lds", (ms + 500) / 1000);
}
}
/* ================================================== */
static void
-print_signed_microseconds(long us)
+print_signed_nanoseconds(double s)
{
- long x = abs(us);
- if (x <= 9999) {
- printf("%+5ldus", us);
- } else if (x <= 9999999) {
- printf("%+5ldms", us / 1000);
+ long ms, ns, sign;
+
+ if (s >= 0.0) {
+ ns = s * 1e9 + 0.5;
+ ms = s * 1e3 + 0.5;
+ sign = 1;
+ } else {
+ ns = -s * 1e9 + 0.5;
+ ms = -s * 1e3 + 0.5;
+ sign = -1;
+ }
+
+ if (ns <= 9999) {
+ printf("%+5ldns", ns * sign);
+ } else if (ns <= 9999499) {
+ printf("%+5ldus", (ns + 500) / 1000 * sign);
+ } else if (ms <= 9999) {
+ printf("%+5ldms", ms * sign);
} else {
- printf("%+6lds", us / 1000000);
+ printf("%+6lds", (ms + 500) / 1000 * sign);
}
}
int n_sources, i;
int verbose = 0;
- int32_t orig_latest_meas, latest_meas, est_offset;
+ double orig_latest_meas, latest_meas, est_offset;
IPAddr ip_addr;
- uint32_t latest_meas_err, est_offset_err;
+ double latest_meas_err, est_offset_err;
uint32_t latest_meas_ago;
uint16_t poll, stratum;
uint16_t state, mode;
state = ntohs(reply.data.source_data.state);
mode = ntohs(reply.data.source_data.mode);
latest_meas_ago = ntohl(reply.data.source_data.since_sample);
- orig_latest_meas = ntohl(reply.data.source_data.orig_latest_meas);
- latest_meas = ntohl(reply.data.source_data.latest_meas);
- latest_meas_err = ntohl(reply.data.source_data.latest_meas_err);
- est_offset = ntohl(reply.data.source_data.est_offset);
- est_offset_err = ntohl(reply.data.source_data.est_offset_err);
+ orig_latest_meas = UTI_FloatNetworkToHost(reply.data.source_data.orig_latest_meas);
+ latest_meas = UTI_FloatNetworkToHost(reply.data.source_data.latest_meas);
+ latest_meas_err = UTI_FloatNetworkToHost(reply.data.source_data.latest_meas_err);
+ est_offset = UTI_FloatNetworkToHost(reply.data.source_data.est_offset);
+ est_offset_err = UTI_FloatNetworkToHost(reply.data.source_data.est_offset_err);
if (mode == RPY_SD_MD_REF) {
snprintf(hostname_buf, sizeof(hostname_buf), "%s", UTI_RefidToString(ip_addr.addr.in4));
printf(" %-25s %2d %2d ", hostname_buf, stratum, poll);
print_seconds(latest_meas_ago);
printf(" ");
- print_signed_microseconds(latest_meas);
+ print_signed_nanoseconds(latest_meas);
printf("[");
- print_signed_microseconds(orig_latest_meas);
+ print_signed_nanoseconds(orig_latest_meas);
printf("]");
printf(" +/- ");
- print_microseconds(latest_meas_err);
+ print_nanoseconds(latest_meas_err);
printf("\n");
} else {
return 0;
char hostname_buf[32];
unsigned long n_samples, n_runs, span_seconds;
- double resid_freq_ppm, skew_ppm;
- unsigned long sd_us;
+ double resid_freq_ppm, skew_ppm, sd;
unsigned long ref_id;
IPAddr ip_addr;
n_samples = ntohl(reply.data.sourcestats.n_samples);
n_runs = ntohl(reply.data.sourcestats.n_runs);
span_seconds = ntohl(reply.data.sourcestats.span_seconds);
- sd_us = ntohl(reply.data.sourcestats.sd_us);
resid_freq_ppm = UTI_FloatNetworkToHost(reply.data.sourcestats.resid_freq_ppm);
skew_ppm = UTI_FloatNetworkToHost(reply.data.sourcestats.skew_ppm);
+ sd = UTI_FloatNetworkToHost(reply.data.sourcestats.sd);
if (ip_addr.family == IPADDR_UNSPEC)
snprintf(hostname_buf, sizeof(hostname_buf), "%s", UTI_RefidToString(ref_id));
printf("%-25s %2lu %2lu ", hostname_buf, n_samples, n_runs);
print_seconds(span_seconds);
printf(" %10.3f %10.3f ", resid_freq_ppm, skew_ppm);
- print_microseconds(sd_us);
+ print_nanoseconds(sd);
printf("\n");
} else {
return 0;
struct timeval ref_time;
struct tm ref_time_tm;
unsigned long a, b, c, d;
- struct timeval correction_tv;
double correction;
double freq_ppm;
double resid_freq_ppm;
UTI_TimevalNetworkToHost(&reply.data.tracking.ref_time, &ref_time);
ref_time_tm = *gmtime((time_t *)&ref_time.tv_sec);
printf("Ref time (UTC) : %s", asctime(&ref_time_tm));
- correction_tv.tv_sec = (int32_t)ntohl(reply.data.tracking.current_correction_s);
- correction_tv.tv_usec = ntohl(reply.data.tracking.current_correction_us);
- correction = (double) correction_tv.tv_sec + 1.0e-6 * correction_tv.tv_usec;
- printf("System time : %.6f seconds %s of NTP time\n", fabs(correction),
+ correction = UTI_FloatNetworkToHost(reply.data.tracking.current_correction);
+ printf("System time : %.9f seconds %s of NTP time\n", fabs(correction),
(correction > 0.0) ? "slow" : "fast");
freq_ppm = UTI_FloatNetworkToHost(reply.data.tracking.freq_ppm);
resid_freq_ppm = UTI_FloatNetworkToHost(reply.data.tracking.resid_freq_ppm);
break;
}
tx_message->data.source_data.since_sample = htonl(report.latest_meas_ago);
- tx_message->data.source_data.orig_latest_meas = htonl(report.orig_latest_meas);
- tx_message->data.source_data.latest_meas = htonl(report.latest_meas);
- tx_message->data.source_data.latest_meas_err = htonl(report.latest_meas_err);
- tx_message->data.source_data.est_offset = htonl(report.est_offset);
- tx_message->data.source_data.est_offset_err = htonl(report.est_offset_err);
-
+ tx_message->data.source_data.orig_latest_meas = UTI_FloatHostToNetwork(report.orig_latest_meas);
+ tx_message->data.source_data.latest_meas = UTI_FloatHostToNetwork(report.latest_meas);
+ tx_message->data.source_data.latest_meas_err = UTI_FloatHostToNetwork(report.latest_meas_err);
+ tx_message->data.source_data.est_offset = UTI_FloatHostToNetwork(report.est_offset);
+ tx_message->data.source_data.est_offset_err = UTI_FloatHostToNetwork(report.est_offset_err);
} else {
tx_message->status = htons(STT_NOSUCHSOURCE);
}
UTI_IPHostToNetwork(&rpt.ip_addr, &tx_message->data.tracking.ip_addr);
tx_message->data.tracking.stratum = htonl(rpt.stratum);
UTI_TimevalHostToNetwork(&rpt.ref_time, &tx_message->data.tracking.ref_time);
- tx_message->data.tracking.current_correction_s = htonl(rpt.current_correction.tv_sec);
- tx_message->data.tracking.current_correction_us = htonl(rpt.current_correction.tv_usec);
+ tx_message->data.tracking.current_correction = UTI_FloatHostToNetwork(rpt.current_correction);
tx_message->data.tracking.freq_ppm = UTI_FloatHostToNetwork(rpt.freq_ppm);
tx_message->data.tracking.resid_freq_ppm = UTI_FloatHostToNetwork(rpt.resid_freq_ppm);
tx_message->data.tracking.skew_ppm = UTI_FloatHostToNetwork(rpt.skew_ppm);
tx_message->data.sourcestats.n_samples = htonl(report.n_samples);
tx_message->data.sourcestats.n_runs = htonl(report.n_runs);
tx_message->data.sourcestats.span_seconds = htonl(report.span_seconds);
- tx_message->data.sourcestats.sd_us = htonl((unsigned long) (0.5 + report.sd_us));
tx_message->data.sourcestats.resid_freq_ppm = UTI_FloatHostToNetwork(report.resid_freq_ppm);
tx_message->data.sourcestats.skew_ppm = UTI_FloatHostToNetwork(report.skew_ppm);
+ tx_message->data.sourcestats.sd = UTI_FloatHostToNetwork(report.sd);
} else {
tx_message->status = htons(STT_NOSUCHSOURCE);
}
rep->ip_addr = our_ref_ip;
rep->stratum = our_stratum;
rep->ref_time = our_ref_time;
- UTI_DoubleToTimeval(correction, &rep->current_correction);
+ rep->current_correction = correction;
rep->freq_ppm = LCL_ReadAbsoluteFrequency();
rep->resid_freq_ppm = 1.0e6 * our_residual_freq;
rep->skew_ppm = 1.0e6 * our_skew;
rep->ip_addr.family = IPADDR_UNSPEC;
rep->stratum = local_stratum;
rep->ref_time = now_cooked;
- UTI_DoubleToTimeval(correction, &rep->current_correction);
+ rep->current_correction = correction;
rep->freq_ppm = LCL_ReadAbsoluteFrequency();
rep->resid_freq_ppm = 0.0;
rep->skew_ppm = 0.0;
rep->stratum = 0;
rep->ref_time.tv_sec = 0;
rep->ref_time.tv_usec = 0;
- UTI_DoubleToTimeval(correction, &rep->current_correction);
+ rep->current_correction = correction;
rep->freq_ppm = LCL_ReadAbsoluteFrequency();
rep->resid_freq_ppm = 0.0;
rep->skew_ppm = 0.0;
enum {RPT_SYNC, RPT_UNREACH, RPT_FALSETICKER, RPT_JITTERY, RPT_OTHER} state;
unsigned long latest_meas_ago; /* seconds */
- long orig_latest_meas; /* microseconds (us) */
- long latest_meas; /* us */
- unsigned long latest_meas_err; /* us */
- long est_offset; /* us */
- unsigned long est_offset_err; /* us */
+ double orig_latest_meas; /* seconds */
+ double latest_meas; /* seconds */
+ double latest_meas_err; /* seconds */
+ double est_offset; /* seconds */
+ double est_offset_err; /* seconds */
} RPT_SourceReport ;
typedef struct {
IPAddr ip_addr;
unsigned long stratum;
struct timeval ref_time;
- struct timeval current_correction;
+ double current_correction;
double freq_ppm;
double resid_freq_ppm;
double skew_ppm;
unsigned long span_seconds;
double resid_freq_ppm;
double skew_ppm;
- double sd_us;
+ double sd;
} RPT_SourcestatsReport;
typedef struct {
SST_DoSourceReport(SST_Stats inst, RPT_SourceReport *report, struct timeval *now)
{
int n, nb;
- double est_offset, est_err, elapsed, sample_elapsed;
+ double elapsed, sample_elapsed;
struct timeval ago;
if (inst->n_samples > 0) {
n = inst->n_samples - 1;
- report->orig_latest_meas = (long)(0.5 + 1.0e6 * inst->orig_offsets[n]);
- report->latest_meas = (long)(0.5 + 1.0e6 * inst->offsets[n]);
- report->latest_meas_err = (unsigned long)(0.5 + 1.0e6 * (0.5*inst->root_delays[n] + inst->root_dispersions[n]));
+ report->orig_latest_meas = inst->orig_offsets[n];
+ report->latest_meas = inst->offsets[n];
+ report->latest_meas_err = 0.5*inst->root_delays[n] + inst->root_dispersions[n];
report->stratum = inst->strata[n];
UTI_DiffTimevals(&ago, now, &inst->sample_times[n]);
UTI_DiffTimevalsToDouble(&elapsed, now, &inst->offset_time);
nb = inst->best_single_sample;
UTI_DiffTimevalsToDouble(&sample_elapsed, now, &(inst->sample_times[nb]));
- est_offset = inst->estimated_offset + elapsed * inst->estimated_frequency;
- est_err = (inst->estimated_offset_sd +
+ report->est_offset = inst->estimated_offset + elapsed * inst->estimated_frequency;
+ report->est_offset_err = (inst->estimated_offset_sd +
sample_elapsed * inst->skew +
(0.5*inst->root_delays[nb] + inst->root_dispersions[nb]));
- report->est_offset = (long)(0.5 + 1.0e6 * est_offset);
- report->est_offset_err = (unsigned long) (0.5 + 1.0e6 * est_err);
} else {
report->est_offset = report->latest_meas;
report->est_offset_err = report->latest_meas_err;
report->resid_freq_ppm = 1.0e6 * inst->estimated_frequency;
report->skew_ppm = 1.0e6 * inst->skew;
- report->sd_us = 1.0e6 * sqrt(inst->variance);
+ report->sd = sqrt(inst->variance);
}
/* ================================================== */