And print the estimated offset in sourcestats output.
Float orig_latest_meas;
Float latest_meas;
Float latest_meas_err;
- Float est_offset;
- Float est_offset_err;
int32_t EOR;
} RPY_Source_Data;
Float sd;
Float resid_freq_ppm;
Float skew_ppm;
+ Float est_offset;
+ Float est_offset_err;
int32_t EOR;
} RPY_Sourcestats;
@example
@group
210 Number of sources = 1
-Name/IP Address NP NR Span Frequency Freq Skew Std Dev
-========================================================================
-abc.def.ghi 11 5 46m -0.001 0.045 25us
+Name/IP Address NP NR Span Frequency Freq Skew Offset Std Dev
+===============================================================================
+abc.def.ghi 11 5 46m -0.001 0.045 1us 25us
@end group
@end example
This is the estimated error bounds on @code{Freq} (again in parts per
million).
+@item Offset
+This is the estimated offset of the source.
+
@item Std Dev
This is the estimated sample standard deviation.
int n_sources, i;
int verbose = 0;
- double orig_latest_meas, latest_meas, est_offset;
+ double orig_latest_meas, latest_meas, latest_meas_err;
IPAddr ip_addr;
- double latest_meas_err, est_offset_err;
uint32_t latest_meas_ago;
uint16_t poll, stratum;
uint16_t state, mode;
printf("MS Name/IP address Stratum Poll LastRx Last sample\n");
printf("============================================================================\n");
- /* "MS NNNNNNNNNNNNNNNNNNNNNNNNN SS PP RRRR SSSSSSS[SSSSSSS] +/- SSSSSS" */
+ /* "MS NNNNNNNNNNNNNNNNNNNNNNNNN SS PP RRRR SSSSSSS[SSSSSSS] +/- SSSSSS" */
for (i=0; i<n_sources; i++) {
request.command = htons(REQ_SOURCE_DATA);
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));
char hostname_buf[32];
unsigned long n_samples, n_runs, span_seconds;
- double resid_freq_ppm, skew_ppm, sd;
+ double resid_freq_ppm, skew_ppm, sd, est_offset, est_offset_err;
unsigned long ref_id;
IPAddr ip_addr;
printf(" / .- Number of residual runs with same sign.\n");
printf(" | / .- Length of measurement set (time).\n");
printf(" | | / .- Est. clock freq error (ppm).\n");
- printf(" | | | / .- Est error in freq.\n");
- printf(" | | | | / .- On the\n");
- printf(" | | | | | / samples.\n");
- printf(" | | | | | |\n");
+ printf(" | | | / .- Est. error in freq.\n");
+ printf(" | | | | / .- Est. offset.\n");
+ printf(" | | | | | | On the -.\n");
+ printf(" | | | | | | samples. \\\n");
+ printf(" | | | | | | |\n");
}
- printf("Name/IP Address NP NR Span Frequency Freq Skew Std Dev\n");
- printf("========================================================================\n");
+ printf("Name/IP Address NP NR Span Frequency Freq Skew Offset Std Dev\n");
+ printf("==============================================================================\n");
- /* NNNNNNNNNNNNNNNNNNNNNNNNN NP NR SSSS FFFFFFFFFF SSSSSSSSSS SSSSSSS */
+ /* NNNNNNNNNNNNNNNNNNNNNNNNN NP NR SSSS FFFFFFFFFF SSSSSSSSSS SSSSSSS SSSSSS*/
for (i=0; i<n_sources; i++) {
request.command = htons(REQ_SOURCESTATS);
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);
+ est_offset = UTI_FloatNetworkToHost(reply.data.sourcestats.est_offset);
+ est_offset_err = UTI_FloatNetworkToHost(reply.data.sourcestats.est_offset_err);
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);
+ printf(" %10.3f %10.3f ", resid_freq_ppm, skew_ppm);
+ print_signed_nanoseconds(est_offset);
+ printf(" ");
print_nanoseconds(sd);
printf("\n");
} else {
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);
}
{
int status;
RPT_SourcestatsReport report;
+ struct timeval now_corr;
+ double local_clock_err;
+
+ LCL_ReadCookedTime(&now_corr, &local_clock_err);
status = SRC_ReportSourcestats(ntohl(rx_message->data.sourcestats.index),
- &report);
+ &report, &now_corr);
if (status) {
tx_message->status = htons(STT_SUCCESS);
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);
+ tx_message->data.sourcestats.est_offset = UTI_FloatHostToNetwork(report.est_offset);
+ tx_message->data.sourcestats.est_offset_err = UTI_FloatHostToNetwork(report.est_offset_err);
} else {
tx_message->status = htons(STT_NOSUCHSOURCE);
}
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 {
double resid_freq_ppm;
double skew_ppm;
double sd;
+ double est_offset;
+ double est_offset_err;
} RPT_SourcestatsReport;
typedef struct {
/* ================================================== */
int
-SRC_ReportSourcestats(int index, RPT_SourcestatsReport *report)
+SRC_ReportSourcestats(int index, RPT_SourcestatsReport *report, struct timeval *now)
{
SRC_Instance src;
report->ip_addr = *src->ip_addr;
else
report->ip_addr.family = IPADDR_UNSPEC;
- SST_DoSourcestatsReport(src->stats, report);
+ SST_DoSourcestatsReport(src->stats, report, now);
return 1;
}
}
extern int SRC_ReadNumberOfSources(void);
extern int SRC_ReportSource(int index, RPT_SourceReport *report, struct timeval *now);
-extern int SRC_ReportSourcestats(int index, RPT_SourcestatsReport *report);
+extern int SRC_ReportSourcestats(int index, RPT_SourcestatsReport *report, struct timeval *now);
extern SRC_Type SRC_GetType(int index);
void
SST_DoSourceReport(SST_Stats inst, RPT_SourceReport *report, struct timeval *now)
{
- int n, nb;
- double elapsed, sample_elapsed;
+ int n;
struct timeval ago;
if (inst->n_samples > 0) {
UTI_DiffTimevals(&ago, now, &inst->sample_times[n]);
report->latest_meas_ago = ago.tv_sec;
-
- if (inst->n_samples > 3) {
- UTI_DiffTimevalsToDouble(&elapsed, now, &inst->offset_time);
- nb = inst->best_single_sample;
- UTI_DiffTimevalsToDouble(&sample_elapsed, now, &(inst->sample_times[nb]));
- 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]));
- } else {
- report->est_offset = report->latest_meas;
- report->est_offset_err = report->latest_meas_err;
- }
} else {
report->latest_meas_ago = 86400 * 365 * 10;
report->orig_latest_meas = 0;
report->latest_meas = 0;
report->latest_meas_err = 0;
report->stratum = 0;
- report->est_offset = 0;
- report->est_offset_err = 0;
}
}
/* ================================================== */
void
-SST_DoSourcestatsReport(SST_Stats inst, RPT_SourcestatsReport *report)
+SST_DoSourcestatsReport(SST_Stats inst, RPT_SourcestatsReport *report, struct timeval *now)
{
double dspan;
- int n;
+ double elapsed, sample_elapsed;
+ int n, nb;
report->n_samples = inst->n_samples;
report->n_runs = inst->nruns;
n = inst->n_samples - 1;
UTI_DiffTimevalsToDouble(&dspan, &inst->sample_times[n], &inst->sample_times[0]);
report->span_seconds = (unsigned long) (dspan + 0.5);
+
+ if (inst->n_samples > 3) {
+ UTI_DiffTimevalsToDouble(&elapsed, now, &inst->offset_time);
+ nb = inst->best_single_sample;
+ UTI_DiffTimevalsToDouble(&sample_elapsed, now, &(inst->sample_times[nb]));
+ 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]));
+ } else {
+ report->est_offset = inst->offsets[n];
+ report->est_offset_err = 0.5*inst->root_delays[n] + inst->root_dispersions[n];
+ }
} else {
report->span_seconds = 0;
+ report->est_offset = 0;
+ report->est_offset_err = 0;
}
report->resid_freq_ppm = 1.0e6 * inst->estimated_frequency;
extern void SST_DoSourceReport(SST_Stats inst, RPT_SourceReport *report, struct timeval *now);
-extern void SST_DoSourcestatsReport(SST_Stats inst, RPT_SourcestatsReport *report);
+extern void SST_DoSourcestatsReport(SST_Stats inst, RPT_SourcestatsReport *report, struct timeval *now);
typedef enum {
SST_Skew_Decrease,