Add support for reference clocks
This commit is contained in:
parent
ef3669fe1b
commit
ac30bb06ef
14 changed files with 453 additions and 16 deletions
|
@ -41,7 +41,7 @@ OBJS = util.o sched.o regress.o local.o \
|
|||
logging.o conf.o cmdmon.o md5.o keys.o \
|
||||
nameserv.o acquire.o manual.o addrfilt.o \
|
||||
cmdparse.o mkdirpp.o rtc.o pktlength.o clientlog.o \
|
||||
broadcast.o
|
||||
broadcast.o refclock.o
|
||||
|
||||
EXTRA_OBJS=@EXTRA_OBJECTS@
|
||||
|
||||
|
|
17
client.c
17
client.c
|
@ -92,6 +92,19 @@ time_to_log_form(time_t t)
|
|||
|
||||
/* ================================================== */
|
||||
|
||||
static char *
|
||||
UTI_RefidToString(unsigned long ref_id)
|
||||
{
|
||||
unsigned int a, b, c, d;
|
||||
static char result[64];
|
||||
a = (ref_id>>24) & 0xff;
|
||||
b = (ref_id>>16) & 0xff;
|
||||
c = (ref_id>> 8) & 0xff;
|
||||
d = (ref_id>> 0) & 0xff;
|
||||
snprintf(result, sizeof(result), "%c%c%c%c", a, b, c, d);
|
||||
return result;
|
||||
}
|
||||
|
||||
static char *
|
||||
UTI_IPToDottedQuad(unsigned long ip)
|
||||
{
|
||||
|
@ -1462,7 +1475,9 @@ process_cmd_sources(char *line)
|
|||
resid_skew = (double) (ntohl(reply.data.source_data.resid_skew)) * 1.0e-3;
|
||||
|
||||
hostname_buf[25] = 0;
|
||||
if (no_dns) {
|
||||
if (mode == RPY_SD_MD_REF) {
|
||||
snprintf(hostname_buf, sizeof(hostname_buf), "%s", UTI_RefidToString(ip_addr));
|
||||
} else if (no_dns) {
|
||||
snprintf(hostname_buf, sizeof(hostname_buf), "%s", UTI_IPToDottedQuad(ip_addr));
|
||||
} else {
|
||||
dns_lookup = DNS_IPAddress2Name(ip_addr);
|
||||
|
|
10
cmdmon.c
10
cmdmon.c
|
@ -50,6 +50,7 @@
|
|||
#include "rtc.h"
|
||||
#include "pktlength.h"
|
||||
#include "clientlog.h"
|
||||
#include "refclock.h"
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
|
@ -871,7 +872,14 @@ handle_source_data(CMD_Request *rx_message, CMD_Reply *tx_message)
|
|||
/* Get data */
|
||||
LCL_ReadCookedTime(&now_corr, &local_clock_err);
|
||||
if (SRC_ReportSource(ntohl(rx_message->data.source_data.index), &report, &now_corr)) {
|
||||
NSR_ReportSource(&report, &now_corr);
|
||||
switch (SRC_GetType(ntohl(rx_message->data.source_data.index))) {
|
||||
case SRC_NTP:
|
||||
NSR_ReportSource(&report, &now_corr);
|
||||
break;
|
||||
case SRC_REFCLOCK:
|
||||
RCL_ReportSource(&report, &now_corr);
|
||||
break;
|
||||
}
|
||||
|
||||
tx_message->status = htons(STT_SUCCESS);
|
||||
tx_message->reply = htons(RPY_SOURCE_DATA);
|
||||
|
|
74
conf.c
74
conf.c
|
@ -44,6 +44,7 @@
|
|||
#include "conf.h"
|
||||
#include "ntp_sources.h"
|
||||
#include "ntp_core.h"
|
||||
#include "refclock.h"
|
||||
#include "cmdmon.h"
|
||||
#include "srcparams.h"
|
||||
#include "logging.h"
|
||||
|
@ -73,6 +74,7 @@ static void parse_peer(const char *);
|
|||
static void parse_acquisitionport(const char *);
|
||||
static void parse_port(const char *);
|
||||
static void parse_server(const char *);
|
||||
static void parse_refclock(const char *);
|
||||
static void parse_local(const char *);
|
||||
static void parse_manual(const char *);
|
||||
static void parse_initstepslew(const char *);
|
||||
|
@ -187,6 +189,7 @@ typedef struct {
|
|||
static const Command commands[] = {
|
||||
{"server", 6, parse_server},
|
||||
{"peer", 4, parse_peer},
|
||||
{"refclock", 8, parse_refclock},
|
||||
{"acquisitionport", 15, parse_acquisitionport},
|
||||
{"port", 4, parse_port},
|
||||
{"driftfile", 9, parse_driftfile},
|
||||
|
@ -250,6 +253,11 @@ typedef struct {
|
|||
static NTP_Source ntp_sources[MAX_NTP_SOURCES];
|
||||
static int n_ntp_sources = 0;
|
||||
|
||||
#define MAX_RCL_SOURCES 8
|
||||
|
||||
static RefclockParameters refclock_sources[MAX_RCL_SOURCES];
|
||||
static int n_refclock_sources = 0;
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
typedef struct _AllowDeny {
|
||||
|
@ -417,6 +425,61 @@ parse_peer(const char *line)
|
|||
|
||||
/* ================================================== */
|
||||
|
||||
static void
|
||||
parse_refclock(const char *line)
|
||||
{
|
||||
int i, n, param, poll;
|
||||
unsigned long ref_id;
|
||||
double offset;
|
||||
char name[5], cmd[10 + 1];
|
||||
unsigned char ref[5];
|
||||
|
||||
i = n_refclock_sources;
|
||||
if (i >= MAX_RCL_SOURCES)
|
||||
return;
|
||||
|
||||
poll = 4;
|
||||
offset = 0.0;
|
||||
ref_id = 0;
|
||||
|
||||
if (sscanf(line, "%4s %d%n", name, ¶m, &n) != 2) {
|
||||
LOG(LOGS_WARN, LOGF_Configure, "Could not read refclock driver name and parameter at line %d", line_number);
|
||||
return;
|
||||
}
|
||||
|
||||
line += n;
|
||||
|
||||
while (sscanf(line, "%10s%n", cmd, &n) == 1) {
|
||||
line += n;
|
||||
if (!strncasecmp(cmd, "refid", 5)) {
|
||||
if (sscanf(line, "%4s%n", (char *)ref, &n) != 1)
|
||||
break;
|
||||
ref_id = ref[0] << 24 | ref[1] << 16 | ref[2] << 8 | ref[3];
|
||||
} else if (!strncasecmp(cmd, "poll", 4)) {
|
||||
if (sscanf(line, "%d%n", &poll, &n) != 1) {
|
||||
break;
|
||||
}
|
||||
} else if (!strncasecmp(cmd, "offset", 6)) {
|
||||
if (sscanf(line, "%lf%n", &offset, &n) != 1)
|
||||
break;
|
||||
} else {
|
||||
LOG(LOGS_WARN, LOGF_Configure, "Unknown refclock parameter %s at line %d", cmd, line_number);
|
||||
break;
|
||||
}
|
||||
line += n;
|
||||
}
|
||||
|
||||
strncpy(refclock_sources[i].driver_name, name, 4);
|
||||
refclock_sources[i].driver_parameter = param;
|
||||
refclock_sources[i].poll = poll;
|
||||
refclock_sources[i].offset = offset;
|
||||
refclock_sources[i].ref_id = ref_id;
|
||||
|
||||
n_refclock_sources++;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
static void
|
||||
parse_some_port(const char *line, int *portvar)
|
||||
{
|
||||
|
@ -1004,6 +1067,17 @@ CNF_AddSources(void) {
|
|||
|
||||
/* ================================================== */
|
||||
|
||||
void
|
||||
CNF_AddRefclocks(void) {
|
||||
int i;
|
||||
|
||||
for (i=0; i<n_refclock_sources; i++) {
|
||||
RCL_AddRefclock(&refclock_sources[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
void
|
||||
CNF_AddBroadcasts(void)
|
||||
{
|
||||
|
|
1
conf.h
1
conf.h
|
@ -37,6 +37,7 @@ extern void CNF_ReadFile(const char *filename);
|
|||
|
||||
extern void CNF_AddSources(void);
|
||||
extern void CNF_AddBroadcasts(void);
|
||||
extern void CNF_AddRefclocks(void);
|
||||
|
||||
extern void CNF_ProcessInitStepSlew(void (*after_hook)(void *), void *anything);
|
||||
|
||||
|
|
|
@ -64,7 +64,8 @@ typedef enum {
|
|||
LOGF_SysSolaris,
|
||||
LOGF_SysSunOS,
|
||||
LOGF_SysWinnt,
|
||||
LOGF_RtcLinux
|
||||
LOGF_RtcLinux,
|
||||
LOGF_Refclock
|
||||
} LOG_Facility;
|
||||
|
||||
/* Init function */
|
||||
|
|
4
main.c
4
main.c
|
@ -58,6 +58,7 @@
|
|||
#include "manual.h"
|
||||
#include "version.h"
|
||||
#include "rtc.h"
|
||||
#include "refclock.h"
|
||||
#include "clientlog.h"
|
||||
#include "broadcast.h"
|
||||
|
||||
|
@ -103,6 +104,7 @@ MAI_CleanupAndExit(void)
|
|||
SRC_Finalise();
|
||||
SST_Finalise();
|
||||
REF_Finalise();
|
||||
RCL_Finalise();
|
||||
RTC_Finalise();
|
||||
CAM_Finalise();
|
||||
NIO_Finalise();
|
||||
|
@ -145,6 +147,7 @@ post_acquire_hook(void *anything)
|
|||
CNF_SetupAccessRestrictions();
|
||||
|
||||
RTC_StartMeasurements();
|
||||
RCL_StartRefclocks();
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
@ -309,6 +312,7 @@ int main
|
|||
NIO_Initialise();
|
||||
CAM_Initialise();
|
||||
RTC_Initialise();
|
||||
RCL_Initialise();
|
||||
|
||||
if (SchedPriority > 0) {
|
||||
SYS_SetScheduler(SchedPriority);
|
||||
|
|
|
@ -319,7 +319,7 @@ create_instance(NTP_Remote_Address *remote_addr, NTP_Mode mode, SourceParameters
|
|||
result->local_poll = params->minpoll;
|
||||
|
||||
/* Create a source instance for this NTP source */
|
||||
result->source = SRC_CreateNewInstance(remote_addr->ip_addr); /* Will need extra params eventually */
|
||||
result->source = SRC_CreateNewInstance(remote_addr->ip_addr, SRC_NTP);
|
||||
|
||||
result->local_rx.tv_sec = 0;
|
||||
result->local_rx.tv_usec = 0;
|
||||
|
|
213
refclock.c
Normal file
213
refclock.c
Normal file
|
@ -0,0 +1,213 @@
|
|||
/*
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
* Copyright (C) Richard P. Curnow 2009
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*
|
||||
**********************************************************************
|
||||
|
||||
=======================================================================
|
||||
|
||||
Routines implementing reference clocks.
|
||||
|
||||
*/
|
||||
|
||||
#include "refclock.h"
|
||||
#include "conf.h"
|
||||
#include "local.h"
|
||||
#include "util.h"
|
||||
#include "sources.h"
|
||||
#include "logging.h"
|
||||
#include "sched.h"
|
||||
|
||||
struct RCL_Instance_Record {
|
||||
RefclockDriver *driver;
|
||||
void *data;
|
||||
int driver_parameter;
|
||||
int poll;
|
||||
int missed_samples;
|
||||
unsigned long ref_id;
|
||||
double offset;
|
||||
SCH_TimeoutID timeout_id;
|
||||
SRC_Instance source;
|
||||
};
|
||||
|
||||
#define MAX_RCL_SOURCES 8
|
||||
|
||||
static struct RCL_Instance_Record refclocks[MAX_RCL_SOURCES];
|
||||
static int n_sources = 0;
|
||||
|
||||
static void poll_timeout(void *arg);
|
||||
|
||||
void
|
||||
RCL_Initialise(void)
|
||||
{
|
||||
CNF_AddRefclocks();
|
||||
}
|
||||
|
||||
void
|
||||
RCL_Finalise(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < n_sources; i++) {
|
||||
RCL_Instance inst = (RCL_Instance)&refclocks[i];
|
||||
|
||||
if (inst->driver->fini)
|
||||
inst->driver->fini(inst);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
RCL_AddRefclock(RefclockParameters *params)
|
||||
{
|
||||
RCL_Instance inst = &refclocks[n_sources];
|
||||
|
||||
if (n_sources == MAX_RCL_SOURCES)
|
||||
return 0;
|
||||
|
||||
if (0) {
|
||||
} else {
|
||||
LOG_FATAL(LOGF_Refclock, "unknown refclock driver %s", params->driver_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
inst->data = NULL;
|
||||
inst->driver_parameter = params->driver_parameter;
|
||||
inst->poll = params->poll;
|
||||
inst->missed_samples = 0;
|
||||
inst->offset = params->offset;
|
||||
inst->timeout_id = -1;
|
||||
inst->source = NULL;
|
||||
|
||||
if (params->ref_id)
|
||||
inst->ref_id = params->ref_id;
|
||||
else {
|
||||
unsigned char ref[5] = { 0, 0, 0, 0, 0 };
|
||||
|
||||
snprintf((char *)ref, 5, "%s%d", params->driver_name, params->driver_parameter);
|
||||
inst->ref_id = ref[0] << 24 | ref[1] << 16 | ref[2] << 8 | ref[3];
|
||||
}
|
||||
|
||||
if (inst->driver->init)
|
||||
if (!inst->driver->init(inst)) {
|
||||
LOG_FATAL(LOGF_Refclock, "refclock %s initialisation failed", params->driver_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
LOG(LOGS_INFO, LOGF_Refclock, "refclock added");
|
||||
#endif
|
||||
n_sources++;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
RCL_StartRefclocks(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < n_sources; i++) {
|
||||
RCL_Instance inst = &refclocks[i];
|
||||
|
||||
inst->source = SRC_CreateNewInstance(inst->ref_id, SRC_REFCLOCK);
|
||||
if (inst->driver->poll)
|
||||
inst->timeout_id = SCH_AddTimeoutByDelay(0.0, poll_timeout, (void *)inst);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RCL_ReportSource(RPT_SourceReport *report, struct timeval *now)
|
||||
{
|
||||
int i;
|
||||
unsigned long ref_id;
|
||||
|
||||
ref_id = report->ip_addr;
|
||||
|
||||
for (i = 0; i < n_sources; i++) {
|
||||
RCL_Instance inst = &refclocks[i];
|
||||
if (inst->ref_id == ref_id) {
|
||||
report->poll = inst->poll;
|
||||
report->mode = RPT_LOCAL_REFERENCE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RCL_SetDriverData(RCL_Instance instance, void *data)
|
||||
{
|
||||
instance->data = data;
|
||||
}
|
||||
|
||||
void *
|
||||
RCL_GetDriverData(RCL_Instance instance)
|
||||
{
|
||||
return instance->data;
|
||||
}
|
||||
|
||||
int
|
||||
RCL_GetDriverParameter(RCL_Instance instance)
|
||||
{
|
||||
return instance->driver_parameter;
|
||||
}
|
||||
|
||||
int
|
||||
RCL_AddSample(RCL_Instance instance, struct timeval *sample_time, double offset, NTP_Leap leap_status)
|
||||
{
|
||||
double correction;
|
||||
struct timeval cooked_time;
|
||||
SRC_Instance inst = instance->source;
|
||||
|
||||
#if 0
|
||||
LOG(LOGS_INFO, LOGF_Refclock, "refclock offset: %f", offset);
|
||||
#endif
|
||||
|
||||
SRC_SetReachable(inst);
|
||||
|
||||
correction = LCL_GetOffsetCorrection(sample_time);
|
||||
UTI_AddDoubleToTimeval(sample_time, correction, &cooked_time);
|
||||
|
||||
SRC_AccumulateSample(inst, &cooked_time, offset - correction + instance->offset,
|
||||
1e-6, 0.0, 0.0, 0.0, 0, leap_status);
|
||||
|
||||
instance->missed_samples = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
poll_timeout(void *arg)
|
||||
{
|
||||
double next;
|
||||
|
||||
RCL_Instance inst = (RCL_Instance)arg;
|
||||
|
||||
inst->missed_samples++;
|
||||
inst->driver->poll(inst);
|
||||
|
||||
if (inst->missed_samples > 9)
|
||||
SRC_UnsetReachable(inst->source);
|
||||
|
||||
if (inst->poll >= 0)
|
||||
next = 1 << inst->poll;
|
||||
else
|
||||
next = 1.0 / (1 << -inst->poll);
|
||||
|
||||
inst->timeout_id = SCH_AddTimeoutByDelay(next, poll_timeout, arg);
|
||||
}
|
||||
|
63
refclock.h
Normal file
63
refclock.h
Normal file
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
* Copyright (C) Richard P. Curnow 2009
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*
|
||||
**********************************************************************
|
||||
|
||||
=======================================================================
|
||||
|
||||
Header file for refclocks.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef GOT_REFCLOCK_H
|
||||
#define GOT_REFCLOCK_H
|
||||
|
||||
#include "srcparams.h"
|
||||
#include "sources.h"
|
||||
|
||||
typedef struct {
|
||||
char driver_name[4];
|
||||
int driver_parameter;
|
||||
int poll;
|
||||
unsigned long ref_id;
|
||||
double offset;
|
||||
} RefclockParameters;
|
||||
|
||||
typedef struct RCL_Instance_Record *RCL_Instance;
|
||||
|
||||
typedef struct {
|
||||
int (*init)(RCL_Instance instance);
|
||||
void (*fini)(RCL_Instance instance);
|
||||
int (*poll)(RCL_Instance instance);
|
||||
} RefclockDriver;
|
||||
|
||||
extern void RCL_Initialise(void);
|
||||
extern void RCL_Finalise(void);
|
||||
extern int RCL_AddRefclock(RefclockParameters *params);
|
||||
extern void RCL_StartRefclocks(void);
|
||||
extern void RCL_StartRefclocks(void);
|
||||
extern void RCL_ReportSource(RPT_SourceReport *report, struct timeval *now);
|
||||
|
||||
/* functions used by drivers */
|
||||
extern void RCL_SetDriverData(RCL_Instance instance, void *data);
|
||||
extern void *RCL_GetDriverData(RCL_Instance instance);
|
||||
extern int RCL_GetDriverParameter(RCL_Instance instance);
|
||||
extern int RCL_AddSample(RCL_Instance instance, struct timeval *sample_time, double offset, NTP_Leap leap_status);
|
||||
|
||||
#endif
|
52
sources.c
52
sources.c
|
@ -96,6 +96,9 @@ struct SRC_Instance_Record {
|
|||
/* Flag indicating the status of the source */
|
||||
SRC_Status status;
|
||||
|
||||
/* Type of the source */
|
||||
SRC_Type type;
|
||||
|
||||
struct SelectInfo sel_info;
|
||||
};
|
||||
|
||||
|
@ -126,6 +129,8 @@ static int selected_source_index; /* Which source index is currently
|
|||
static void
|
||||
slew_sources(struct timeval *raw, struct timeval *cooked, double dfreq, double afreq,
|
||||
double doffset, int is_step_change, void *anything);
|
||||
static char *
|
||||
source_to_string(SRC_Instance inst);
|
||||
|
||||
/* ================================================== */
|
||||
/* Initialisation function */
|
||||
|
@ -155,7 +160,7 @@ void SRC_Finalise(void)
|
|||
/* Function to create a new instance. This would be called by one of
|
||||
the individual source-type instance creation routines. */
|
||||
|
||||
SRC_Instance SRC_CreateNewInstance(unsigned long ref_id)
|
||||
SRC_Instance SRC_CreateNewInstance(unsigned long ref_id, SRC_Type type)
|
||||
{
|
||||
SRC_Instance result;
|
||||
|
||||
|
@ -186,6 +191,7 @@ SRC_Instance SRC_CreateNewInstance(unsigned long ref_id)
|
|||
result->ref_id = ref_id;
|
||||
result->reachable = 0;
|
||||
result->status = SRC_BAD_STATS;
|
||||
result->type = type;
|
||||
|
||||
n_sources++;
|
||||
|
||||
|
@ -280,7 +286,7 @@ void SRC_AccumulateSample
|
|||
|
||||
#ifdef TRACEON
|
||||
LOG(LOGS_INFO, LOGF_Sources, "ip=[%s] t=%s ofs=%f del=%f disp=%f str=%d",
|
||||
UTI_IPToDottedQuad(inst->ref_id), UTI_TimevalToString(sample_time), -offset, root_delay, root_dispersion, stratum);
|
||||
source_to_string(inst), UTI_TimevalToString(sample_time), -offset, root_delay, root_dispersion, stratum);
|
||||
#endif
|
||||
|
||||
/* WE HAVE TO NEGATE OFFSET IN THIS CALL, IT IS HERE THAT THE SENSE OF OFFSET
|
||||
|
@ -301,7 +307,7 @@ SRC_SetReachable(SRC_Instance inst)
|
|||
inst->reachable = 1;
|
||||
|
||||
#ifdef TRACEON
|
||||
LOG(LOGS_INFO, LOGF_Sources, "%s", UTI_IPToDottedQuad(inst->ref_id));
|
||||
LOG(LOGS_INFO, LOGF_Sources, "%s", source_to_string(inst));
|
||||
#endif
|
||||
|
||||
/* Don't do selection at this point, though - that will come about
|
||||
|
@ -316,7 +322,7 @@ SRC_UnsetReachable(SRC_Instance inst)
|
|||
inst->reachable = 0;
|
||||
|
||||
#ifdef TRACEON
|
||||
LOG(LOGS_INFO, LOGF_Sources, "%s%s", UTI_IPToDottedQuad(inst->ref_id),
|
||||
LOG(LOGS_INFO, LOGF_Sources, "%s%s", source_to_string(inst),
|
||||
(inst->index == selected_source_index) ? "(REF)":"");
|
||||
#endif
|
||||
|
||||
|
@ -349,6 +355,22 @@ compare_sort_elements(const void *a, const void *b)
|
|||
}
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
static char *
|
||||
source_to_string(SRC_Instance inst)
|
||||
{
|
||||
switch (inst->type) {
|
||||
case SRC_NTP:
|
||||
return UTI_IPToDottedQuad(inst->ref_id);
|
||||
case SRC_REFCLOCK:
|
||||
return UTI_RefidToString(inst->ref_id);
|
||||
default:
|
||||
CROAK("Unknown source type");
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
/* This function selects the current reference from amongst the pool
|
||||
of sources we are holding.
|
||||
|
@ -418,7 +440,7 @@ SRC_SelectSource(unsigned long match_addr)
|
|||
|
||||
#if 0
|
||||
LOG(LOGS_INFO, LOGF_Sources, "%s off=%f dist=%f lo=%f hi=%f",
|
||||
UTI_IPToDottedQuad(sources[i]->ref_id),
|
||||
source_to_string(sources[i]),
|
||||
si->best_offset, si->root_distance,
|
||||
si->lo_limit, si->hi_limit);
|
||||
#endif
|
||||
|
@ -491,7 +513,7 @@ SRC_SelectSource(unsigned long match_addr)
|
|||
for (i=0; i<n_endpoints; i++) {
|
||||
#if 0
|
||||
LOG(LOGS_INFO, LOGF_Sources, "i=%d t=%f tag=%d addr=%s", i, sort_list[i].offset, sort_list[i].tag,
|
||||
UTI_IPToDottedQuad(sources[sort_list[i].index]->ref_id));
|
||||
source_to_string(sources[sort_list[i].index]));
|
||||
#endif
|
||||
switch(sort_list[i].tag) {
|
||||
case LOW:
|
||||
|
@ -565,12 +587,12 @@ SRC_SelectSource(unsigned long match_addr)
|
|||
|
||||
sel_sources[n_sel_sources++] = i;
|
||||
#if 0
|
||||
LOG(LOGS_INFO, LOGF_Sources, "i=%d addr=%s is valid", i, UTI_IPToDottedQuad(sources[i]->ref_id));
|
||||
LOG(LOGS_INFO, LOGF_Sources, "i=%d addr=%s is valid", i, source_to_string(sources[i]));
|
||||
#endif
|
||||
} else {
|
||||
sources[i]->status = SRC_FALSETICKER;
|
||||
#if 0
|
||||
LOG(LOGS_INFO, LOGF_Sources, "i=%d addr=%s is a falseticker", i, UTI_IPToDottedQuad(sources[i]->ref_id));
|
||||
LOG(LOGS_INFO, LOGF_Sources, "i=%d addr=%s is a falseticker", i, source_to_string(sources[i]));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -603,7 +625,7 @@ SRC_SelectSource(unsigned long match_addr)
|
|||
sel_sources[i] = INVALID_SOURCE;
|
||||
sources[index]->status = SRC_JITTERY;
|
||||
#if 0
|
||||
LOG(LOGS_INFO, LOGF_Sources, "i=%d addr=%s has too much variance", i, UTI_IPToDottedQuad(sources[i]->ref_id));
|
||||
LOG(LOGS_INFO, LOGF_Sources, "i=%d addr=%s has too much variance", i, source_to_string(sources[i]));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -658,7 +680,7 @@ SRC_SelectSource(unsigned long match_addr)
|
|||
|
||||
selected_source_index = min_distance_index;
|
||||
LOG(LOGS_INFO, LOGF_Sources, "Selected source %s",
|
||||
UTI_IPToDottedQuad(sources[selected_source_index]->ref_id));
|
||||
source_to_string(sources[selected_source_index]));
|
||||
|
||||
|
||||
#if 0
|
||||
|
@ -935,6 +957,16 @@ SRC_ReportSourcestats(int index, RPT_SourcestatsReport *report)
|
|||
|
||||
/* ================================================== */
|
||||
|
||||
SRC_Type
|
||||
SRC_GetType(int index)
|
||||
{
|
||||
if ((index >= n_sources) || (index < 0))
|
||||
return -1;
|
||||
return sources[index]->type;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
SRC_Skew_Direction SRC_LastSkewChange(SRC_Instance inst)
|
||||
{
|
||||
SRC_Skew_Direction result = SRC_Skew_Nochange;
|
||||
|
|
|
@ -50,10 +50,15 @@ extern void SRC_Initialise(void);
|
|||
/* Finalisation function */
|
||||
extern void SRC_Finalise(void);
|
||||
|
||||
typedef enum {
|
||||
SRC_NTP, /* NTP client/peer */
|
||||
SRC_REFCLOCK /* Rerefence clock */
|
||||
} SRC_Type;
|
||||
|
||||
/* Function to create a new instance. This would be called by one of
|
||||
the individual source-type instance creation routines. */
|
||||
|
||||
extern SRC_Instance SRC_CreateNewInstance(unsigned long ref_id);
|
||||
extern SRC_Instance SRC_CreateNewInstance(unsigned long ref_id, SRC_Type type);
|
||||
|
||||
/* Function to get rid of a source when it is being unconfigured.
|
||||
This may cause the current reference source to be reselected, if this
|
||||
|
@ -143,6 +148,8 @@ extern int SRC_ReportSource(int index, RPT_SourceReport *report, struct timeval
|
|||
|
||||
extern int SRC_ReportSourcestats(int index, RPT_SourcestatsReport *report);
|
||||
|
||||
extern SRC_Type SRC_GetType(int index);
|
||||
|
||||
typedef enum {
|
||||
SRC_Skew_Decrease,
|
||||
SRC_Skew_Nochange,
|
||||
|
|
16
util.c
16
util.c
|
@ -247,6 +247,22 @@ UTI_TimestampToString(NTP_int64 *ts)
|
|||
|
||||
/* ================================================== */
|
||||
|
||||
char *
|
||||
UTI_RefidToString(unsigned long ref_id)
|
||||
{
|
||||
unsigned int a, b, c, d;
|
||||
char *result;
|
||||
a = (ref_id>>24) & 0xff;
|
||||
b = (ref_id>>16) & 0xff;
|
||||
c = (ref_id>> 8) & 0xff;
|
||||
d = (ref_id>> 0) & 0xff;
|
||||
result = NEXT_BUFFER;
|
||||
snprintf(result, BUFFER_LENGTH, "%c%c%c%c", a, b, c, d);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
char *
|
||||
UTI_IPToDottedQuad(unsigned long ip)
|
||||
{
|
||||
|
|
3
util.h
3
util.h
|
@ -72,6 +72,9 @@ extern char *UTI_TimevalToString(struct timeval *tv);
|
|||
diagnostic display */
|
||||
extern char *UTI_TimestampToString(NTP_int64 *ts);
|
||||
|
||||
/* Convert ref_id into a temporary string, for diagnostics */
|
||||
extern char *UTI_RefidToString(unsigned long ref_id);
|
||||
|
||||
/* Convert an IP address to dotted quad notation, for diagnostics */
|
||||
extern char *UTI_IPToDottedQuad(unsigned long ip);
|
||||
|
||||
|
|
Loading…
Reference in a new issue