else
i++;
}
-
+
if (response == -1) { // no match, so create one
i = 0;
while ((response == -1) && (i < MAX_CLIENTS)) {
memset(&clocks_private_info[i], 0, sizeof(clock_source_private_data));
if (old_flags != 0) {
update_master(0); // TODO -- won't be needed
- } else {
- debug_log_nqptp_status(2);
}
}
}
}
}
-void debug_log_nqptp_status(__attribute__((unused)) int level) {
- /*
- int records_in_use = 0;
- int i;
- for (i = 0; i < MAX_CLOCKS; i++)
- if ((clocks_private[i].flags & (1 << clock_is_in_use)) != 0)
- records_in_use++;
- debug(level, "");
- if (records_in_use > 0) {
- debug(level, "Current NQPTP Status:");
- uint32_t peer_mask = (1 << clock_is_a_timing_peer);
- uint32_t peer_clock_mask = peer_mask | (1 << clock_is_valid);
- uint32_t peer_master_mask = peer_clock_mask | (1 << clock_is_master);
- uint32_t peer_becoming_master_mask = peer_clock_mask | (1 << clock_is_becoming_master);
- uint32_t non_peer_clock_mask = (1 << clock_is_valid);
- uint32_t non_peer_master_mask = non_peer_clock_mask | (1 << clock_is_master);
- for (i = 0; i < MAX_CLOCKS; i++) {
- if ((clocks_private[i].flags & (1 << clock_is_in_use)) != 0) {
- if ((clocks_private[i].flags & peer_master_mask) == peer_master_mask) {
- debug(level, " Peer Master: %" PRIx64 " %s.", clocks_private[i].clock_id,
- clocks_private[i].ip);
- } else if ((clocks_private[i].flags & peer_becoming_master_mask) ==
- peer_becoming_master_mask) {
- debug(level, " Peer Becoming Master: %" PRIx64 " %s.", clocks_private[i].clock_id,
- clocks_private[i].ip);
- } else if ((clocks_private[i].flags & peer_clock_mask) == peer_clock_mask) {
- debug(level, " Peer Clock: %" PRIx64 " %s.", clocks_private[i].clock_id,
- clocks_private[i].ip);
- } else if ((clocks_private[i].flags & peer_mask) == peer_mask) {
- debug(level, " Peer: %s.", clocks_private[i].ip);
- } else if ((clocks_private[i].flags & non_peer_master_mask) == non_peer_master_mask) {
- debug(level, " Non Peer Master: %" PRIx64 " %s.", clocks_private[i].clock_id,
- clocks_private[i].ip);
- } else if ((clocks_private[i].flags & non_peer_clock_mask) == non_peer_clock_mask) {
- debug(level, " Non Peer Clock: %16" PRIx64 " %s.", clocks_private[i].clock_id,
- clocks_private[i].ip);
- } else {
- debug(level, " Non Peer Record: %s.", clocks_private[i].ip);
- }
- }
- }
- } else {
- debug(level, "Current NQPTP Status: no records in use.");
- }
- */
-}
-
int uint32_cmp(uint32_t a, uint32_t b, const char *cause) {
// returns -1 if a is less than b, 0 if a = b, +1 if a is greater than b
if (a == b) {
if (old_master == -1)
old_master = i; // find old master
clocks_private[i].client_flags[client_id] &= ~(1 << clock_is_master); // turn them all off
- clocks_private[i].client_flags[client_id] &=
- ~(1 << clock_is_becoming_master); // turn them all off
}
int best_so_far = -1;
int timing_peer_count = 0;
- // uint32_t clock_specific_acceptance_mask = (1 << clock_is_qualified) | (1 << clock_is_valid);
- uint32_t clock_specific_acceptance_mask = (1 << clock_is_qualified);
+ uint32_t clock_specific_acceptance_mask = (1 << clock_is_announced);
uint32_t client_specific_acceptance_mask = (1 << clock_is_a_timing_peer);
for (i = 0; i < MAX_CLOCKS; i++) {
if (((clocks_private[i].flags & clock_specific_acceptance_mask) ==
update_master_clock_info(client_id, 0, NULL, 0, 0, 0);
//}
if (timing_peer_count == 0)
- debug(2, "no valid qualified clocks ");
+ debug(2, "empty timing peer group ");
else
debug(1, "no master clock!");
} else {
- // we found a master clock
-
- if (old_master != best_so_far) {
- // if the master is a new one
- // now, if it's already a master somewhere, it doesn't need to resync
- int clock_is_a_master_somewhere = 0;
- int temp_client_id;
- for (temp_client_id = 0; temp_client_id < MAX_CLIENTS; temp_client_id++) {
- if ((clocks_private[best_so_far].client_flags[temp_client_id] & (1 << clock_is_master)) !=
- 0) {
- clock_is_a_master_somewhere = 1;
- }
- }
- if (clock_is_a_master_somewhere == 0) {
- clocks_private[best_so_far].client_flags[client_id] |= (1 << clock_is_master);
-// clocks_private[best_so_far].client_flags[client_id] |= (1 << clock_is_becoming_master);
-// clocks_private[best_so_far].last_sync_time = 0; // declare it was never synced before
-
- } else {
- clocks_private[best_so_far].client_flags[client_id] |= (1 << clock_is_master);
- }
- } else {
- // if it's the same one as before
- clocks_private[best_so_far].client_flags[client_id] |= (1 << clock_is_master);
- }
+ // we mark the master clock we found
+ clocks_private[best_so_far].client_flags[client_id] |= (1 << clock_is_master);
}
- debug_log_nqptp_status(2);
}
void update_master_clock_info(int client_id, uint64_t master_clock_id, const char *ip,
uint64_t mastership_start_time) {
if (clients[client_id].shm_interface_name[0] != '\0') {
// debug(1,"update_master_clock_info start");
- if (clients[client_id].shared_memory->master_clock_id != master_clock_id)
- debug_log_nqptp_status(1);
int rc = pthread_mutex_lock(&clients[client_id].shared_memory->shm_mutex);
if (rc != 0)
warn("Can't acquire mutex to update master clock!");
/*
* This file is part of the nqptp distribution (https://github.com/mikebrady/nqptp).
- * Copyright (c) 2021 Mike Brady.
+ * Copyright (c) 2021-2022 Mike Brady.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
clock_source_private_data *clock_private_info) {
if (recv_len != -1) {
buf[recv_len - 1] = 0; // make sure there's a null in it!
- debug(1, "New control port message: \"%s\".", buf);
+ debug(2, "New control port message: \"%s\".", buf);
// we need to get the client shared memory interface name from the front
char *ip_list = buf;
char *smi_name = strsep(&ip_list, " ");
}
}
} else {
- debug(2,"get or create new record for \"%s\".",smi_name);
+ debug(2, "get or create new record for \"%s\".", smi_name);
client_id = get_client_id(smi_name); // create the record if it doesn't exist
if (client_id != -1) {
if (strcmp(command, "T") == 0) {
}
void handle_announce(char *buf, ssize_t recv_len, clock_source_private_data *clock_private_info,
- uint64_t reception_time) {
+ __attribute__((unused)) uint64_t reception_time) {
// only process Announce messages that do not come from self
if ((clock_private_info->flags & (1 << clock_is_one_of_ours)) == 0) {
// debug_print_buffer(1, buf, (size_t) recv_len);
uint64_t packet_clock_id_low = nctohl(&msg->header.clockIdentity[4]);
packet_clock_id = packet_clock_id << 32;
packet_clock_id = packet_clock_id + packet_clock_id_low;
+ clock_private_info->flags |= (1 << clock_is_announced);
clock_private_info->clock_id = packet_clock_id;
clock_private_info->grandmasterPriority1 =
msg->announce.grandmasterPriority1; // need this for possibly pinging it later...
// it has seen three, poked the clock and doesn't want to do any more.
clock_private_info->announcements_without_followups++;
- int i;
- // number of elements in the array is 4, hence the 4-1 stuff
- for (i = 4 - 1; i > 1 - 1; i--) {
- clock_private_info->announce_times[i] = clock_private_info->announce_times[i - 1];
- };
- clock_private_info->announce_times[0] = reception_time;
-
- // so, we have added a new element and assumed that
- // now we need to walk down the array checking that non of the elements are too old
- i = 0;
- int valid_count = 0;
- int finished = 0;
-
- // see 9.3.2.4.4 and 9.3.2.5
- uint64_t foreign_master_time_window = 1;
- foreign_master_time_window = foreign_master_time_window
- << (32 + aPTPinitialLogAnnounceInterval);
- foreign_master_time_window = foreign_master_time_window * 4;
- foreign_master_time_window = foreign_master_time_window >> 32; // should be 4 seconds
-
- uint64_t cutoff_time = reception_time + foreign_master_time_window;
- int foreign_master_threshold = 2;
- while ((i < 4) && (finished == 0)) {
- int64_t delta = cutoff_time - clock_private_info->announce_times[i];
- if (delta > 0)
- valid_count++;
- else
- finished = 1;
- i++;
+ uint64_t grandmaster_clock_id = nctohl(&msg->announce.grandmasterIdentity[0]);
+ uint64_t grandmaster_clock_id_low = nctohl(&msg->announce.grandmasterIdentity[4]);
+ grandmaster_clock_id = grandmaster_clock_id << 32;
+ grandmaster_clock_id = grandmaster_clock_id + grandmaster_clock_id_low;
+ uint32_t clockQuality = ntohl(msg->announce.grandmasterClockQuality);
+ uint8_t clockClass = (clockQuality >> 24) & 0xff;
+ uint8_t clockAccuracy = (clockQuality >> 16) & 0xff;
+ uint16_t offsetScaledLogVariance = clockQuality & 0xffff;
+ uint16_t stepsRemoved = ntohs(msg->announce.stepsRemoved);
+ uint16_t sourcePortID = ntohs(msg->header.sourcePortID);
+
+ // something in might have changed that
+ // affects its status as a possible master clock.
+ int best_clock_update_needed = 0;
+ if (clock_private_info->grandmasterIdentity != grandmaster_clock_id) {
+ clock_private_info->grandmasterIdentity = grandmaster_clock_id;
+ best_clock_update_needed = 1;
+ }
+ if (clock_private_info->grandmasterPriority1 != msg->announce.grandmasterPriority1) {
+ clock_private_info->grandmasterPriority1 = msg->announce.grandmasterPriority1;
+ best_clock_update_needed = 1;
+ }
+ if (clock_private_info->grandmasterQuality != clockQuality) {
+ clock_private_info->grandmasterQuality = clockQuality;
+ best_clock_update_needed = 1;
+ }
+ if (clock_private_info->grandmasterClass != clockClass) {
+ clock_private_info->grandmasterClass = clockClass;
+ best_clock_update_needed = 1;
+ }
+ if (clock_private_info->grandmasterAccuracy != clockAccuracy) {
+ clock_private_info->grandmasterAccuracy = clockAccuracy;
+ best_clock_update_needed = 1;
+ }
+ if (clock_private_info->grandmasterVariance != offsetScaledLogVariance) {
+ clock_private_info->grandmasterVariance = offsetScaledLogVariance;
+ best_clock_update_needed = 1;
+ }
+ if (clock_private_info->grandmasterPriority2 != msg->announce.grandmasterPriority2) {
+ clock_private_info->grandmasterPriority2 = msg->announce.grandmasterPriority2;
+ best_clock_update_needed = 1;
+ }
+ if (clock_private_info->stepsRemoved != stepsRemoved) {
+ clock_private_info->stepsRemoved = stepsRemoved;
+ best_clock_update_needed = 1;
+ }
+ if (clock_private_info->clock_port_number != sourcePortID) {
+ clock_private_info->clock_port_number = sourcePortID;
+ best_clock_update_needed = 1;
}
- if (valid_count >= foreign_master_threshold) {
- uint64_t grandmaster_clock_id = nctohl(&msg->announce.grandmasterIdentity[0]);
- uint64_t grandmaster_clock_id_low = nctohl(&msg->announce.grandmasterIdentity[4]);
- grandmaster_clock_id = grandmaster_clock_id << 32;
- grandmaster_clock_id = grandmaster_clock_id + grandmaster_clock_id_low;
- uint32_t clockQuality = ntohl(msg->announce.grandmasterClockQuality);
- uint8_t clockClass = (clockQuality >> 24) & 0xff;
- uint8_t clockAccuracy = (clockQuality >> 16) & 0xff;
- uint16_t offsetScaledLogVariance = clockQuality & 0xffff;
- uint16_t stepsRemoved = ntohs(msg->announce.stepsRemoved);
- uint16_t sourcePortID = ntohs(msg->header.sourcePortID);
- int best_clock_update_needed = 0;
- if (((clock_private_info->flags & (1 << clock_is_qualified)) == 0) &&
- (stepsRemoved < 255)) {
- // if it's just becoming qualified
- clock_private_info->grandmasterIdentity = grandmaster_clock_id;
- clock_private_info->grandmasterPriority1 = msg->announce.grandmasterPriority1;
- clock_private_info->grandmasterQuality = clockQuality; // class/accuracy/variance
- clock_private_info->grandmasterClass = clockClass;
- clock_private_info->grandmasterAccuracy = clockAccuracy;
- clock_private_info->grandmasterVariance = offsetScaledLogVariance;
- clock_private_info->grandmasterPriority2 = msg->announce.grandmasterPriority2;
- clock_private_info->stepsRemoved = stepsRemoved;
- clock_private_info->clock_port_number = sourcePortID;
- best_clock_update_needed = 1;
- } else {
- // otherwise, something in it might have changed, I guess, that
- // affects its status as a possible master clock.
- if (clock_private_info->grandmasterIdentity != grandmaster_clock_id) {
- clock_private_info->grandmasterIdentity = grandmaster_clock_id;
- best_clock_update_needed = 1;
- }
- if (clock_private_info->grandmasterPriority1 != msg->announce.grandmasterPriority1) {
- clock_private_info->grandmasterPriority1 = msg->announce.grandmasterPriority1;
- best_clock_update_needed = 1;
- }
- if (clock_private_info->grandmasterQuality != clockQuality) {
- clock_private_info->grandmasterQuality = clockQuality;
- best_clock_update_needed = 1;
- }
- if (clock_private_info->grandmasterClass != clockClass) {
- clock_private_info->grandmasterClass = clockClass;
- best_clock_update_needed = 1;
- }
- if (clock_private_info->grandmasterAccuracy != clockAccuracy) {
- clock_private_info->grandmasterAccuracy = clockAccuracy;
- best_clock_update_needed = 1;
- }
- if (clock_private_info->grandmasterVariance != offsetScaledLogVariance) {
- clock_private_info->grandmasterVariance = offsetScaledLogVariance;
- best_clock_update_needed = 1;
- }
- if (clock_private_info->grandmasterPriority2 != msg->announce.grandmasterPriority2) {
- clock_private_info->grandmasterPriority2 = msg->announce.grandmasterPriority2;
- best_clock_update_needed = 1;
- }
- if (clock_private_info->stepsRemoved != stepsRemoved) {
- clock_private_info->stepsRemoved = stepsRemoved;
- best_clock_update_needed = 1;
- }
- }
- if (best_clock_update_needed) {
- debug(2, "best clock update needed");
- debug(2,
- "clock_id %" PRIx64
- " at: %s, \"Announce\" message is %sQualified -- See 9.3.2.5.",
- clock_private_info->clock_id, clock_private_info->ip,
- clock_private_info->stepsRemoved < 255 ? "" : "not ");
- debug(2, " grandmasterIdentity: %" PRIx64 ".", grandmaster_clock_id);
- debug(2, " grandmasterPriority1: %u.", msg->announce.grandmasterPriority1);
- debug(2, " grandmasterClockQuality: 0x%x.", clockQuality);
- debug(2, " clockClass: %u.", clockClass); // See 7.6.2.4 clockClass
- debug(2, " clockAccuracy: 0x%x.",
- clockAccuracy); // See 7.6.2.5 clockAccuracy
- debug(2, " offsetScaledLogVariance: 0x%x.",
- offsetScaledLogVariance); // See 7.6.3 PTP variance
- debug(2, " grandmasterPriority2: %u.", msg->announce.grandmasterPriority2);
- debug(2, " stepsRemoved: %u.", stepsRemoved);
- debug(2, " portNumber: %u.", sourcePortID);
-
- // now go and re-mark the best clock in the timing peer list
- if (clock_private_info->stepsRemoved >= 255) // 9.3.2.5 (d)
- clock_private_info->flags &= ~(1 << clock_is_qualified);
- else
- clock_private_info->flags |= (1 << clock_is_qualified);
- // check/update the mastership of any clients that might be affected
- int temp_client_id;
- for (temp_client_id = 0; temp_client_id < MAX_CLIENTS; temp_client_id++) {
- if ((clock_private_info->client_flags[temp_client_id] &
- (1 << clock_is_a_timing_peer)) != 0) {
- debug(2,
- "best_clock_update_needed because %" PRIx64
- " on ip %s has changed -- updating clock mastership for client \"%s\"",
- clock_private_info->clock_id, clock_private_info->ip,
- get_client_name(temp_client_id));
- update_master(temp_client_id);
- }
+ if (best_clock_update_needed) {
+ debug(2, "best clock update needed");
+ debug(2, " grandmasterIdentity: %" PRIx64 ".", grandmaster_clock_id);
+ debug(2, " grandmasterPriority1: %u.", msg->announce.grandmasterPriority1);
+ debug(2, " grandmasterClockQuality: 0x%x.", clockQuality);
+ debug(2, " clockClass: %u.", clockClass); // See 7.6.2.4 clockClass
+ debug(2, " clockAccuracy: 0x%x.",
+ clockAccuracy); // See 7.6.2.5 clockAccuracy
+ debug(2, " offsetScaledLogVariance: 0x%x.",
+ offsetScaledLogVariance); // See 7.6.3 PTP variance
+ debug(2, " grandmasterPriority2: %u.", msg->announce.grandmasterPriority2);
+ debug(2, " stepsRemoved: %u.", stepsRemoved);
+ debug(2, " portNumber: %u.", sourcePortID);
+
+ // check/update the mastership of any clients that might be affected
+ int temp_client_id;
+ for (temp_client_id = 0; temp_client_id < MAX_CLIENTS; temp_client_id++) {
+ if ((clock_private_info->client_flags[temp_client_id] & (1 << clock_is_a_timing_peer)) !=
+ 0) {
+ debug(2,
+ "best_clock_update_needed because %" PRIx64
+ " on ip %s has changed -- updating clock mastership for client \"%s\"",
+ clock_private_info->clock_id, clock_private_info->ip,
+ get_client_name(temp_client_id));
+ update_master(temp_client_id);
}
}
- } else {
- if ((clock_private_info->flags & (1 << clock_is_qualified)) !=
- 0) // if it was qualified, but now isn't
- debug(1,
- "clock_id %" PRIx64
- " on ip: %s \"Announce\" message is not Qualified -- See 9.3.2.5.",
- clock_private_info->clock_id, clock_private_info->ip);
- clock_private_info->flags &= ~(1 << clock_is_qualified);
}
}
}
preciseOriginTimestamp = preciseOriginTimestamp + nanoseconds;
// update our sample information
-
+
if (clock_private_info->follow_up_number < 100)
clock_private_info->follow_up_number++;
debug(2, "FOLLOWUP from %" PRIx64 ", %s.", clock_private_info->clock_id, &clock_private_info->ip);
uint64_t offset = preciseOriginTimestamp - reception_time;
- clock_private_info->local_time = reception_time;
- clock_private_info->source_time = preciseOriginTimestamp;
- clock_private_info->local_to_source_time_offset = offset;
-
int64_t jitter = 0;
int64_t time_since_previous_offset = 0;
time_since_previous_offset = reception_time - clock_private_info->previous_offset_time;
}
-/*
- int clock_is_becoming_master_somewhere = 0;
- {
- int temp_client_id;
- for (temp_client_id = 0; temp_client_id < MAX_CLIENTS; temp_client_id++) {
- if ((clock_private_info->client_flags[temp_client_id] & (1 << clock_is_becoming_master)) !=
- 0) {
- clock_is_becoming_master_somewhere = 1;
- }
- }
- }
- if ((clock_private_info->flags & (1 << clock_is_becoming_master)) != 0)
- clock_is_becoming_master_somewhere = 1;
-
- if (clock_is_becoming_master_somewhere != 0) {
- // we now definitely have at least one sample since a request was made to
- // designate this clock a master, so we assume it is legitimate. That is, we assume
- // that the clock originator knows that it a clock master by now.
- clock_private_info->mastership_start_time = clock_private_info->local_time;
-
- // designate the clock as master wherever is was becoming a master
- {
- int temp_client_id;
- for (temp_client_id = 0; temp_client_id < MAX_CLIENTS; temp_client_id++) {
- if ((clock_private_info->client_flags[temp_client_id] & (1 << clock_is_becoming_master)) !=
- 0) {
- debug(2,
- "clock_is_becoming_master %" PRIx64
- " at %s -- changing to clock_is_master for client \"%s\"",
- clock_private_info->clock_id, clock_private_info->ip,
- get_client_name(temp_client_id));
- clock_private_info->client_flags[temp_client_id] &= ~(1 << clock_is_becoming_master);
- clock_private_info->client_flags[temp_client_id] |= (1 << clock_is_master);
- }
- }
- }
-
- clock_private_info->previous_offset_time = 0;
- debug_log_nqptp_status(2);
- } else
-
-
- if ((clock_private_info->previous_offset_time != 0) &&
- (time_since_previous_offset < 300000000000)) {
- // i.e. if it's not becoming a master and there has been a previous follow_up
- // i.e. if there has been a previous follow_up
- int64_t time_since_last_sync = reception_time - clock_private_info->last_sync_time;
- int64_t sync_timeout = 300000000000; // nanoseconds
- if (clock_private_info->last_sync_time == 0)
- debug(2, "Never synced.");
+ // Do acceptance checking and smoothing.
+
+ // Positive changes in the offset are much more likely to be
+ // legitimate, since they could only occur due to a shorter
+ // propagation time or less of a delay sending or receiving the packet.
+ // (Actually, this is not quite true --
+ // it is possible that the remote clock could be adjusted forward
+ // and this would increase the offset too.)
+ // Anyway, when the clock is new, we give extra preferential weighting to
+ // positive changes in the offset.
+
+ // If the new offset is greater, by any amount, than the old offset,
+ // or if it is less by up to 10 mS, accept it.
+ // Otherwise, drop it if the last sample was fairly recent
+ // If the last sample was long ago, take this as a discontinuity and
+ // accept it as the start of a new period of mastership.
+
+ // This seems to be quite stable
+
+ if (clock_private_info->previous_offset_time != 0)
+ jitter = offset - clock_private_info->previous_offset;
+
+ // We take any positive or a limited negative jitter as a sync event in
+ // a continuous synchronisation sequence.
+ // This works well with PTP sources that sleep, as when they sleep
+ // their clock stops. When they awaken, the offset from
+ // the local clock to them must be smaller than before, triggering the
+ // timing discontinuity below and allowing an immediate readjustment.
+
+ // The full value of a positive offset jitter is accepted for a
+ // number of follow_ups at the start.
+ // After that, the weight of the jitter is reduced.
+ // Follow-ups don't always come in at 125 ms intervals, especially after a discontinuity
+ // Delays makes the offsets smaller than they should be, which is quickly
+ // allowed for.
+
+ if ((clock_private_info->previous_offset_time != 0) && (jitter > -10000000)) {
+
+ if (jitter < 0) {
+ if (clock_private_info->follow_up_number < (5 * 8)) // at the beginning (8 samples per second)
+ smoothed_offset = clock_private_info->previous_offset + jitter / 16;
+ else
+ smoothed_offset = clock_private_info->previous_offset + jitter / 64;
+ } else if (clock_private_info->follow_up_number <
+ (5 * 8)) // at the beginning (8 samples per second)
+ smoothed_offset =
+ clock_private_info->previous_offset + jitter / 1; // accept positive changes quickly
else
- debug(2, "Sync interval: %f seconds.", 0.000000001 * time_since_last_sync);
- if ((clock_private_info->last_sync_time != 0) && (time_since_last_sync < sync_timeout)) {
-*/
- // Do acceptance checking.
-
- // Positive changes in the offset are much more likely to be
- // legitimate, since they could only occur due to a shorter
- // propagation time. (Actually, this is not quite true --
- // it is possible that the remote clock could be adjusted forward
- // and this would increase the offset too.)
- // Anyway, when the clock is new, we give preferential weighting to
- // positive changes in the offset.
-
- // If the new offset is greater, by any amount, than the old offset,
- // or if it is less by up to 10 mS,
- // accept it.
- // Otherwise, drop it
-
- // This seems to be quite stable
-
- if (clock_private_info->previous_offset_time != 0)
- jitter = offset - clock_private_info->previous_offset;
-
- // We take any positive or a limited negative jitter as a sync event in
- // a continuous synchronisation sequence.
- // This works well with PTP sources that sleep, as when they sleep
- // their clock stops. When they awaken, the offset from
- // the local clock to them must be a lot smaller, triggering the
- // timing discontinuity below and allowing a rapid readjustment
-
- // The full value of positive the offset jitter is accepted for a
- // number of follow_ups at the start.
- // After that, the weight of the jitter is reduced.
- // Follow-ups don't always come in at 125 ms intervals, especially after a discontinuity
- // Delays makes the offsets smaller than they should be, which is quickly
- // allowed for.
-
- if ((clock_private_info->previous_offset_time != 0) && (jitter > -10000000)) {
-
- if (jitter < 0) {
- if (clock_private_info->follow_up_number <
- (5 * 8)) // at the beginning (8 samples per second)
- smoothed_offset = clock_private_info->previous_offset + jitter / 16;
- else
- smoothed_offset = clock_private_info->previous_offset + jitter / 64;
- } else if (clock_private_info->follow_up_number <
- (5 * 8)) // at the beginning (8 samples per second)
- smoothed_offset =
- clock_private_info->previous_offset + jitter / 1; // accept positive changes quickly
- else
- smoothed_offset = clock_private_info->previous_offset + jitter / 64;
- clock_private_info->last_sync_time = reception_time;
- } else {
- // allow samples to disappear for up to a second
- if ((time_since_previous_offset != 0) && (time_since_previous_offset < 1000000000)) {
- smoothed_offset = clock_private_info->previous_offset; // if we have recent samples, forget the present sample...
- } else {
- if (clock_private_info->previous_offset_time == 0)
- debug(1,"New clock %" PRIx64 " at %s.", clock_private_info->clock_id, clock_private_info->ip);
- else
- debug(1,"Timing discontinuity on clock %" PRIx64 " at %s: time_since_previous_offset: %.3f seconds.", clock_private_info->clock_id, clock_private_info->ip, 0.000000001 * time_since_previous_offset);
- smoothed_offset = offset;
- clock_private_info->follow_up_number = 0;
- clock_private_info->mastership_start_time =
- reception_time; // mastership is reset to this time...
- }
- }
-/*
+ smoothed_offset = clock_private_info->previous_offset + jitter / 64;
+ } else {
+ // allow samples to disappear for up to a second
+ if ((time_since_previous_offset != 0) && (time_since_previous_offset < 1000000000)) {
+ smoothed_offset =
+ clock_private_info
+ ->previous_offset; // if we have recent samples, forget the present sample...
} else {
- debug(1, "Time since last sync: %.3f seconds.", 0.000000001 * time_since_last_sync);
- int clock_is_a_master_somewhere = 0;
- int temp_client_id;
- for (temp_client_id = 0; temp_client_id < MAX_CLIENTS; temp_client_id++) {
- if ((clock_private_info->client_flags[temp_client_id] & (1 << clock_is_master)) != 0) {
- clock_is_a_master_somewhere = 1;
- }
- }
-
- if ((clock_is_a_master_somewhere != 0) && (clock_private_info->last_sync_time == 0))
- debug(2, "Synchronising master clock %" PRIx64 " at %s.", clock_private_info->clock_id,
+ if (clock_private_info->previous_offset_time == 0)
+ debug(2, "New clock %" PRIx64 " at %s.", clock_private_info->clock_id,
clock_private_info->ip);
- if ((clock_is_a_master_somewhere != 0) && (clock_private_info->last_sync_time != 0))
- debug(1, "Resynchronising master clock %" PRIx64 " at %s.", clock_private_info->clock_id,
- clock_private_info->ip);
- // leave the offset as it was coming in and take it as a sync time
- clock_private_info->last_sync_time = reception_time;
- clock_private_info->mastership_start_time =
- reception_time; // mastership is reset to this time...
- clock_private_info->previous_offset_time = 0;
- }
- } else {
- clock_private_info->last_sync_time = reception_time;
- if (time_since_previous_offset >= 300000000000) {
- debug(1, "Long interval: %f seconds since previous follow_up",
- time_since_previous_offset * 1E-9);
+ else
+ debug(2,
+ "Timing discontinuity on clock %" PRIx64
+ " at %s: time_since_previous_offset: %.3f seconds.",
+ clock_private_info->clock_id, clock_private_info->ip,
+ 0.000000001 * time_since_previous_offset);
+ smoothed_offset = offset;
+ clock_private_info->follow_up_number = 0;
clock_private_info->mastership_start_time =
reception_time; // mastership is reset to this time...
- clock_private_info->previous_offset_time = 0;
}
}
-*/
clock_private_info->previous_offset = smoothed_offset;
clock_private_info->previous_offset_time = reception_time;
if ((clock_private_info->client_flags[temp_client_id] & (1 << clock_is_master)) != 0) {
debug(2, "clock_is_master -- updating master clock info for client \"%s\"",
get_client_name(temp_client_id));
- debug(1, "Clock %" PRIx64 " at %s. Offset: %" PRIx64 ", smoothed offset: %" PRIx64 ". Precise Origin Timestamp: %" PRIx64 ". Time since previous offset: %.3f milliseconds.", clock_private_info->clock_id, clock_private_info->ip, offset, smoothed_offset, preciseOriginTimestamp, 0.000001 * time_since_previous_offset);
+ debug(2,
+ "Clock %" PRIx64 " at %s. Offset: %" PRIx64 ", smoothed offset: %" PRIx64
+ ". Precise Origin Timestamp: %" PRIx64
+ ". Time since previous offset: %.3f milliseconds.",
+ clock_private_info->clock_id, clock_private_info->ip, offset, smoothed_offset,
+ preciseOriginTimestamp, 0.000001 * time_since_previous_offset);
update_master_clock_info(temp_client_id, clock_private_info->clock_id,
- (const char *)&clock_private_info->ip, reception_time, smoothed_offset,
- clock_private_info->mastership_start_time);
+ (const char *)&clock_private_info->ip, reception_time,
+ smoothed_offset, clock_private_info->mastership_start_time);
}
}
}