#include <arpa/inet.h>
#include <errno.h>
#include <ifaddrs.h>
+#include <netdb.h>
#include <string.h>
-#include <sys/types.h>
#include <sys/socket.h>
-#include <netdb.h>
+#include <sys/types.h>
#ifdef CONFIG_FOR_FREEBSD
#include <netinet/in.h>
if (found == 1) {
int family = 0;
- // check its ipv4/6 family -- derived froom https://stackoverflow.com/a/3736377, with thanks.
+ // check its ipv4/6 family -- derived from https://stackoverflow.com/a/3736377, with thanks.
struct addrinfo hint, *res = NULL;
memset(&hint, '\0', sizeof hint);
hint.ai_family = PF_UNSPEC;
clocks_private_info[i].family = family;
clocks_private_info[i].vacant_samples = MAX_TIMING_SAMPLES;
clocks_private_info[i].in_use = 1;
- debug(1, "create record for ip: %s, family: %s.", &clocks_private_info[i].ip, clocks_private_info[i].family == AF_INET6 ? "IPv6" : "IPv4");
+ debug(2, "create record for ip: %s, family: %s.", &clocks_private_info[i].ip,
+ clocks_private_info[i].family == AF_INET6 ? "IPv6" : "IPv4");
} else {
die("cannot getaddrinfo for ip: %s.", &clocks_private_info[i].ip);
}
memset(&clocks_private_info[i], 0, sizeof(clock_source_private_data));
if (old_flags != 0)
update_master();
+ else
+ debug_log_nqptp_status(1);
}
}
}
for (i = 0; i < MAX_CLOCKS; i++)
if (clocks_private[i].in_use != 0)
records_in_use++;
+ debug(level, "");
if (records_in_use > 0) {
- debug(level, "");
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);
}
}
}
+ } else {
+ debug(level, "Current NQPTP Status: no records in use.");
}
}
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 timing peer list: \"%s\".", buf);
+ debug(2, "New timing peer list: \"%s\".", buf);
if (buf[0] == 'T') {
char *ip_list = buf + 1;
if (t == -1)
t = create_clock_source_record(new_ip, clock_private_info);
clock_private_info[t].flags |= (1 << clock_is_a_timing_peer);
+ clock_private_info[t].announcements_sent = 0;
+ clock_private_info[t].followup_seen = 0; // no followup seen while a timing peer
}
}
debug(2, "%s.", &clock_private_info[i].ip);
}
debug(2, "Timing group end");
-
- announce_messages_sent_to_timing_peers = 0;
-
} else {
warn("Unrecognised string on the control port.");
}
packet_clock_id = packet_clock_id + packet_clock_id_low;
clock_private_info->clock_id = packet_clock_id;
+ debug(2, "announcement seen from %" PRIx64 " at %s.", clock_private_info->clock_id,
+ clock_private_info->ip);
+
int i;
// number of elements in the array is 4, hence the 4-1 stuff
for (i = 4 - 1; i > 1 - 1; i--) {
uint16_t sourcePortID = ntohs(msg->header.sourcePortID);
int best_clock_update_needed = 0;
if (((clock_private_info->flags & (1 << clock_is_qualified)) == 0) &&
- (msg->announce.stepsRemoved < 255)) {
+ (stepsRemoved < 255)) {
// if it's just becoming qualified
clock_private_info->grandmasterIdentity = grandmaster_clock_id;
clock_private_info->grandmasterPriority1 = msg->announce.grandmasterPriority1;
void handle_follow_up(char *buf, __attribute__((unused)) ssize_t recv_len,
clock_source_private_data *clock_private_info, uint64_t reception_time) {
- clock_private_info->flags |= (1 << clock_is_valid); // valid because it has at least one follow_up
struct ptp_follow_up_message *msg = (struct ptp_follow_up_message *)buf;
uint16_t seconds_hi = nctohs(&msg->follow_up.preciseOriginTimestamp[0]);
// update our sample information
+ clock_private_info->followup_seen =
+ 1; // say we've seen a follow_up -- suppresses announcements_sent
+
clock_private_info->samples[clock_private_info->next_sample_goes_here].local_time =
reception_time;
clock_private_info->samples[clock_private_info->next_sample_goes_here].clock_time =
clock_private_info->flags &= ~(1 << clock_is_becoming_master);
clock_private_info->flags |= 1 << clock_is_master;
clock_private_info->previous_offset_time = 0;
+ debug_log_nqptp_status(1);
} else if (clock_private_info->previous_offset_time != 0) {
// i.e. if it's not becoming a master and there has been a previous follow_up
int64_t time_since_last_sync = reception_time - clock_private_info->last_sync_time;
clock_private_info->last_sync_time = reception_time;
}
+ clock_private_info->previous_offset = offset;
+ clock_private_info->previous_offset_time = reception_time;
+
if ((clock_private_info->flags & (1 << clock_is_master)) != 0) {
update_master_clock_info(clock_private_info->clock_id, (const char *)&clock_private_info->ip,
reception_time, offset, clock_private_info->mastership_start_time);
clock_private_info->clock_id, reception_time, offset, 0.000001 * jitter);
}
- clock_private_info->previous_offset = offset;
- clock_private_info->previous_offset_time = reception_time;
+ if ((clock_private_info->flags & (1 << clock_is_valid)) == 0) {
+ debug(2, "follow_up seen from %" PRIx64 " at %s.", clock_private_info->clock_id,
+ clock_private_info->ip);
+ clock_private_info->flags |=
+ (1 << clock_is_valid); // valid because it has at least one follow_up
+ update_master();
+ }
}
#define BUFLEN 4096 // Max length of buffer
-int announce_messages_sent_to_timing_peers; // used to stop sending Announce messages
-
sockets_open_bundle sockets_open_stuff;
int master_clock_index = -1;
// (1 << clock_is_qualified) | (1 << clock_is_a_timing_peer) | (1 << clock_is_valid);
// (1 << clock_is_a_timing_peer) | (1 << clock_is_valid);
(1 << clock_is_a_timing_peer);
- if (announce_messages_sent_to_timing_peers < 3) {
- announce_messages_sent_to_timing_peers++;
- for (i = 0; i < MAX_CLOCKS; i++) {
- if ((clocks_private[i].flags & acceptance_mask) == acceptance_mask) {
-
- // create the message
- struct ptp_announce_message msg;
- memset((void *)&msg, 0, sizeof(msg));
- uint64_t my_clock_id = get_self_clock_id();
- msg.header.transportSpecificAndMessageID = 0x10 + Announce;
- msg.header.reservedAndVersionPTP = 0x02;
- msg.header.messageLength = htons(sizeof(struct ptp_announce_message));
- msg.header.flags = htons(0x0408);
- hcton64(my_clock_id, &msg.header.clockIdentity[0]);
- msg.header.sourcePortID = htons(32776);
- msg.header.controlOtherMessage = 0x05;
- msg.header.logMessagePeriod = 0xFE;
- msg.announce.currentUtcOffset = htons(37);
- hcton64(my_clock_id, &msg.announce.grandmasterIdentity[0]);
- uint32_t my_clock_quality = 0xf8fe436a;
- msg.announce.grandmasterClockQuality = htonl(my_clock_quality);
- msg.announce.grandmasterPriority1 = 248;
- msg.announce.grandmasterPriority2 = 248;
- msg.announce.timeSource = 160;
- // show it
- // debug_print_buffer(1, (char *)&msg, sizeof(struct ptp_announce_message));
- // get the socket for the correct port -- 320 -- and family -- IPv4 or IPv6 -- to send it
- // from.
-
- int s = 0;
- unsigned t;
- for (t = 0; t < sockets_open_stuff.sockets_open; t++) {
- if ((sockets_open_stuff.sockets[t].port == 320) &&
- (sockets_open_stuff.sockets[t].family == clocks_private[i].family))
- s = sockets_open_stuff.sockets[t].number;
- }
- if (s == 0) {
- debug(1, "sending socket not found!");
+ for (i = 0; i < MAX_CLOCKS; i++) {
+ if (((clocks_private[i].flags & acceptance_mask) == acceptance_mask) &&
+ (clocks_private[i].is_one_of_ours == 0) && (clocks_private[i].announcements_sent < 1) &&
+ (clocks_private[i].followup_seen == 0)) {
+
+ // create the message
+ struct ptp_announce_message msg;
+ memset((void *)&msg, 0, sizeof(msg));
+ uint64_t my_clock_id = get_self_clock_id();
+ msg.header.transportSpecificAndMessageID = 0x10 + Announce;
+ msg.header.reservedAndVersionPTP = 0x02;
+ msg.header.messageLength = htons(sizeof(struct ptp_announce_message));
+ msg.header.flags = htons(0x0408);
+ hcton64(my_clock_id, &msg.header.clockIdentity[0]);
+ msg.header.sourcePortID = htons(32776);
+ msg.header.controlOtherMessage = 0x05;
+ msg.header.logMessagePeriod = 0xFE;
+ msg.announce.currentUtcOffset = htons(37);
+ hcton64(my_clock_id, &msg.announce.grandmasterIdentity[0]);
+ uint32_t my_clock_quality = 0xf8fe436a;
+ msg.announce.grandmasterClockQuality = htonl(my_clock_quality);
+ msg.announce.grandmasterPriority1 = 100;
+ msg.announce.grandmasterPriority2 = 248;
+ msg.announce.timeSource = 160;
+ // show it
+ // debug_print_buffer(1, (char *)&msg, sizeof(struct ptp_announce_message));
+ // get the socket for the correct port -- 320 -- and family -- IPv4 or IPv6 -- to send it
+ // from.
+
+ int s = 0;
+ unsigned t;
+ for (t = 0; t < sockets_open_stuff.sockets_open; t++) {
+ if ((sockets_open_stuff.sockets[t].port == 320) &&
+ (sockets_open_stuff.sockets[t].family == clocks_private[i].family))
+ s = sockets_open_stuff.sockets[t].number;
+ }
+ if (s == 0) {
+ debug(1, "sending socket not found!");
+ } else {
+ // debug(1, "Send message from socket %d.", s);
+
+ const char *portname = "320";
+ struct addrinfo hints;
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_protocol = 0;
+ hints.ai_flags = AI_ADDRCONFIG;
+ struct addrinfo *res = NULL;
+ int err = getaddrinfo(clocks_private[i].ip, portname, &hints, &res);
+ if (err != 0) {
+ debug(1, "failed to resolve remote socket address (err=%d)", err);
} else {
- // debug(1, "Send message from socket %d.", s);
-
- const char *portname = "320";
- struct addrinfo hints;
- memset(&hints, 0, sizeof(hints));
- hints.ai_family = AF_UNSPEC;
- hints.ai_socktype = SOCK_DGRAM;
- hints.ai_protocol = 0;
- hints.ai_flags = AI_ADDRCONFIG;
- struct addrinfo *res = NULL;
- int err = getaddrinfo(clocks_private[i].ip, portname, &hints, &res);
- if (err != 0) {
- debug(1, "failed to resolve remote socket address (err=%d)", err);
- } else {
- // here, we have the destination, so send it
-
- // if (clocks_private[i].family == AF_INET6) {
- debug(1, "message clock \"%" PRIx64 "\" at %s on %s, iteration: %d.",
- clocks_private[i].clock_id, clocks_private[i].ip,
- clocks_private[i].family == AF_INET6 ? "IPv6" : "IPv4",
- announce_messages_sent_to_timing_peers);
- int ret = sendto(s, &msg, sizeof(msg), 0, res->ai_addr, res->ai_addrlen);
- if (ret == -1)
- debug(1, "result of sendto is %d.", ret);
- // }
- freeaddrinfo(res);
- }
+ // here, we have the destination, so send it
+
+ // if (clocks_private[i].family == AF_INET6) {
+ int ret = sendto(s, &msg, sizeof(msg), 0, res->ai_addr, res->ai_addrlen);
+ if (ret == -1)
+ debug(1, "result of sendto is %d.", ret);
+ clocks_private[i].announcements_sent++;
+ debug(2, "message clock \"%" PRIx64 "\" at %s on %s, iteration: %d.",
+ clocks_private[i].clock_id, clocks_private[i].ip,
+ clocks_private[i].family == AF_INET6 ? "IPv6" : "IPv4",
+ clocks_private[i].announcements_sent);
+ // }
+ freeaddrinfo(res);
}
}
}
announce_interval = announce_interval << (8 + aPTPinitialLogAnnounceInterval);
announce_interval = announce_interval * 1000000000;
announce_interval = announce_interval >> 8; // nanoseconds
- return call_time + 250000000;
+ return call_time + 1000000000;
// return call_time + announce_interval;
}