From a5fbe4a34b831f5b994391f2e1daee8850b7748c Mon Sep 17 00:00:00 2001 From: Mike Brady <4265913+mikebrady@users.noreply.github.com> Date: Sun, 18 Apr 2021 11:43:14 +0100 Subject: [PATCH] remove all the public clock information except for the master clock. amalgamate each clock's public and private information --- nqptp-clock-sources.c | 39 ++++---------- nqptp-clock-sources.h | 25 ++++++--- nqptp-message-handlers.c | 111 +++++++++++++++------------------------ nqptp-message-handlers.h | 11 ++-- nqptp-shm-structures.h | 36 +++---------- nqptp.c | 36 ++++++++----- nqptp.h | 18 ++----- 7 files changed, 108 insertions(+), 168 deletions(-) diff --git a/nqptp-clock-sources.c b/nqptp-clock-sources.c index 7a97db7..14443a1 100644 --- a/nqptp-clock-sources.c +++ b/nqptp-clock-sources.c @@ -31,7 +31,7 @@ clock_source_private_data clocks_private[MAX_CLOCKS]; -int find_clock_source_record(char *sender_string, clock_source *clocks_shared_info, +int find_clock_source_record(char *sender_string, clock_source_private_data *clocks_private_info) { // return the index of the clock in the clock information arrays or -1 int response = -1; @@ -39,7 +39,7 @@ int find_clock_source_record(char *sender_string, clock_source *clocks_shared_in int found = 0; while ((found == 0) && (i < MAX_CLOCKS)) { if ((clocks_private_info[i].in_use != 0) && - (strcasecmp(sender_string, (const char *)&clocks_shared_info[i].ip) == 0)) + (strcasecmp(sender_string, (const char *)&clocks_private_info[i].ip) == 0)) found = 1; else i++; @@ -49,8 +49,8 @@ int find_clock_source_record(char *sender_string, clock_source *clocks_shared_in return response; } -int create_clock_source_record(char *sender_string, clock_source *clocks_shared_info, - clock_source_private_data *clocks_private_info, int use_lock) { +int create_clock_source_record(char *sender_string, + clock_source_private_data *clocks_private_info) { // sometimes, the mutex will already be locked // return the index of a clock entry in the clock information arrays or -1 if full // initialise the entries in the shared and private arrays @@ -66,30 +66,21 @@ int create_clock_source_record(char *sender_string, clock_source *clocks_shared_ if (found == 1) { response = i; - if (use_lock != 0) { - if (pthread_mutex_lock(&shared_memory->shm_mutex) != 0) - warn("Can't acquire mutex to activate a new clock!"); - } - memset(&clocks_shared_info[i], 0, sizeof(clock_source)); - strncpy((char *)&clocks_shared_info[i].ip, sender_string, FIELD_SIZEOF(clock_source, ip) - 1); - if (use_lock != 0) { - if (pthread_mutex_unlock(&shared_memory->shm_mutex) != 0) - warn("Can't release mutex after activating a new clock!"); - } memset(&clocks_private_info[i], 0, sizeof(clock_source_private_data)); + strncpy((char *)&clocks_private_info[i].ip, sender_string, FIELD_SIZEOF(clock_source_private_data, ip) - 1); clocks_private_info[i].in_use = 1; clocks_private_info[i].t2 = 0; clocks_private_info[i].current_stage = waiting_for_sync; clocks_private_info[i].vacant_samples = MAX_TIMING_SAMPLES; debug(2, "activated source %d with clock_id %" PRIx64 " on ip: %s.", i, - clocks_shared_info[i].clock_id, &clocks_shared_info[i].ip); + clocks_private_info[i].clock_id, &clocks_private_info[i].ip); } else { die("Clock tables full!"); } return response; } -void manage_clock_sources(uint64_t reception_time, clock_source *clocks_shared_info, +void manage_clock_sources(uint64_t reception_time, clock_source_private_data *clocks_private_info) { debug(3, "manage_clock_sources"); int i; @@ -97,7 +88,7 @@ void manage_clock_sources(uint64_t reception_time, clock_source *clocks_shared_i for (i = 0; i < MAX_CLOCKS; i++) { // only if its in use and not a timing peer... don't need a mutex to check if ((clocks_private_info[i].in_use != 0) && - ((clocks_shared_info[i].flags & (1 << clock_is_a_timing_peer)) == 0)) { + ((clocks_private_info[i].flags & (1 << clock_is_a_timing_peer)) == 0)) { int64_t time_since_last_use = reception_time - clocks_private_info[i].time_of_last_use; // using a sync timeout to determine when to drop the record... // the following give the sync receipt time in whole seconds @@ -109,14 +100,7 @@ void manage_clock_sources(uint64_t reception_time, clock_source *clocks_shared_i syncTimeout = syncTimeout * 1000000000; if (time_since_last_use > syncTimeout) { debug(2, "deactivated source %d with clock_id %" PRIx64 " on ip: %s.", i, - clocks_shared_info[i].clock_id, &clocks_shared_info[i].ip); - int rc = pthread_mutex_lock(&shared_memory->shm_mutex); - if (rc != 0) - warn("Can't acquire mutex to deactivate a clock!"); - memset(&clocks_shared_info[i], 0, sizeof(clock_source)); - rc = pthread_mutex_unlock(&shared_memory->shm_mutex); - if (rc != 0) - warn("Can't release mutex after deactivating a clock!"); + clocks_private_info[i].clock_id, &clocks_private_info[i].ip); memset(&clocks_private_info[i], 0, sizeof(clock_source_private_data)); } } @@ -126,8 +110,7 @@ void manage_clock_sources(uint64_t reception_time, clock_source *clocks_shared_i // check all the entries in the clock array and mark all those that // belong to ourselves -void update_clock_self_identifications(clock_source *clocks_shared_info, - clock_source_private_data *clocks_private_info) { +void update_clock_self_identifications(clock_source_private_data *clocks_private_info) { // first, turn off all the self-id flags int i; for (i = 0; i < MAX_CLOCKS; i++) { @@ -157,7 +140,7 @@ void update_clock_self_identifications(clock_source *clocks_shared_info, if (strlen(ip_string) != 0) { // now set the is_one_of_ours flag of any clock with this ip for (i = 0; i < MAX_CLOCKS; i++) { - if (strcasecmp(ip_string, clocks_shared_info[i].ip) == 0) { + if (strcasecmp(ip_string, clocks_private_info[i].ip) == 0) { debug(2, "found an entry for one of our clocks"); clocks_private_info[i].is_one_of_ours = 1; } diff --git a/nqptp-clock-sources.h b/nqptp-clock-sources.h index 3521366..8a4f18b 100644 --- a/nqptp-clock-sources.h +++ b/nqptp-clock-sources.h @@ -28,14 +28,26 @@ enum stage { sync_seen, }; +typedef enum { + clock_is_valid, + clock_is_a_timing_peer, + clock_is_qualified, + clock_is_master +} clock_flags; + #define MAX_TIMING_SAMPLES 11 typedef struct { uint16_t sequence_number; uint64_t local, local_to_remote_offset; } timing_samples; -// private information -- not for putting in shared memory -- about each clock source +// information about each clock source typedef struct { + char ip[64]; // 64 is nicely aligned and bigger than INET6_ADDRSTRLEN (46) + uint64_t clock_id; + uint64_t local_time; // the local time when the offset was calculated + uint64_t local_to_source_time_offset; // add this to the local time to get source time + uint32_t flags; uint16_t sequence_number; uint16_t in_use; enum stage current_stage; @@ -66,16 +78,15 @@ typedef struct { } clock_source_private_data; -int find_clock_source_record(char *sender_string, clock_source *clocks_shared_info, +int find_clock_source_record(char *sender_string, clock_source_private_data *clocks_private_info); -int create_clock_source_record(char *sender_string, clock_source *clocks_shared_info, - clock_source_private_data *clocks_private_info, int use_lock); +int create_clock_source_record(char *sender_string, + clock_source_private_data *clocks_private_info); -void update_clock_self_identifications(clock_source *clocks_shared_info, - clock_source_private_data *clocks_private_info); +void update_clock_self_identifications(clock_source_private_data *clocks_private_info); -void manage_clock_sources(uint64_t reception_time, clock_source *clocks_shared_info, +void manage_clock_sources(uint64_t reception_time, clock_source_private_data *clocks_private_info); extern clock_source_private_data clocks_private[MAX_CLOCKS]; diff --git a/nqptp-message-handlers.c b/nqptp-message-handlers.c index 43d9f1a..447ee17 100644 --- a/nqptp-message-handlers.c +++ b/nqptp-message-handlers.c @@ -24,15 +24,15 @@ #include "debug.h" #include "general-utilities.h" -void update_master_old(clock_source *clock_info, clock_source_private_data *clock_private_info) { +void update_master_old(clock_source_private_data *clock_private_info) { int old_master = -1; // find the current master clock if there is one and turn off all mastership int i; for (i = 0; i < MAX_CLOCKS; i++) { - if ((clock_info[i].flags & (1 << clock_is_master)) != 0) + if ((clock_private_info[i].flags & (1 << clock_is_master)) != 0) if (old_master == -1) old_master = i; // find old master - clock_info[i].flags &= ~(1 << clock_is_master); // turn them all off + clock_private_info[i].flags &= ~(1 << clock_is_master); // turn them all off } int best_so_far = -1; @@ -40,7 +40,7 @@ void update_master_old(clock_source *clock_info, clock_source_private_data *cloc uint32_t acceptance_mask = (1 << clock_is_valid) | (1 << clock_is_qualified) | (1 << clock_is_a_timing_peer); for (i = 0; i < MAX_CLOCKS; i++) { - if ((clock_info[i].flags & acceptance_mask) == acceptance_mask) { + if ((clock_private_info[i].flags & acceptance_mask) == acceptance_mask) { // found a possible clock candidate timing_peer_count++; if (best_so_far == -1) { @@ -74,11 +74,12 @@ void update_master_old(clock_source *clock_info, clock_source_private_data *cloc } if (best_so_far != -1) { // we found a master clock - clock_info[best_so_far].flags |= (1 << clock_is_master); + clock_private_info[best_so_far].flags |= (1 << clock_is_master); // master_clock_index = best_so_far; - if (old_master != best_so_far) - debug(1, "Master clock is now: %" PRIx64 " at: %s, index: %d.", clock_info[best_so_far].clock_id, &clock_info[best_so_far].ip, best_so_far); - } else { + if (old_master != best_so_far) { + update_master_clock_info(clock_private_info[best_so_far].clock_id, clock_private_info[best_so_far].local_time, clock_private_info[best_so_far].local_to_source_time_offset); + } + } else { if (timing_peer_count == 0) debug(1, "No timing peer list found"); else @@ -87,64 +88,56 @@ void update_master_old(clock_source *clock_info, clock_source_private_data *cloc // check for (i = 0; i < MAX_CLOCKS; i++) { - if ((clock_info[i].flags & (1 << clock_is_master)) != 0) + if ((clock_private_info[i].flags & (1 << clock_is_master)) != 0) debug(2,"leaving with %d as master", i); } } void update_master() { - update_master_old((clock_source *) &shared_memory->clocks, clocks_private); + update_master_old(clocks_private); } -void handle_control_port_messages(char *buf, ssize_t recv_len, clock_source *clock_info, +void handle_control_port_messages(char *buf, ssize_t recv_len, 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,"Received a new timing peer list message: \"%s\".", buf); - if ((buf[0] == new_timing_peer_list) || (buf[0] == update_timing_peer_list)){ + if (buf[0] == 'T') { char *ip_list = buf + 1; if (*ip_list == ' ') ip_list++; - int rc = pthread_mutex_lock(&shared_memory->shm_mutex); - if (rc != 0) - warn("Can't acquire mutex to set timing peers!"); - // turn off all is_timing_peer + // turn off all is_timing_peer flags int i; for (i = 0; i < MAX_CLOCKS; i++) { - clock_info[i].flags &= ~(1 << clock_is_a_timing_peer); // turn off peer flag (but not the master flag!) + clock_private_info[i].flags &= ~(1 << clock_is_a_timing_peer); // turn off peer flag (but not the master flag!) } while (ip_list != NULL) { char *new_ip = strsep(&ip_list, " "); // look for the IP in the list of clocks, and create an inert entry if not there if ((new_ip != NULL) && (new_ip[0] != 0)) { - int t = find_clock_source_record(new_ip, clock_info, clock_private_info); + int t = find_clock_source_record(new_ip, clock_private_info); if (t == -1) - t = create_clock_source_record(new_ip, clock_info, clock_private_info, - 0); // don't use the mutex + t = create_clock_source_record(new_ip, clock_private_info); // if it is just about to become a timing peer, reset its sample count clock_private_info[t].vacant_samples = MAX_TIMING_SAMPLES; clock_private_info[t].next_sample_goes_here = 0; - clock_info[t].flags |= (1 << clock_is_a_timing_peer); + clock_private_info[t].flags |= (1 << clock_is_a_timing_peer); } } // now find and mark the best clock in the timing peer list as the master update_master(); - rc = pthread_mutex_unlock(&shared_memory->shm_mutex); - - if (rc != 0) - warn("Can't release mutex after set timing peers!"); debug(2, "Timing group start"); for (i = 0; i < MAX_CLOCKS; i++) { - if ((clock_info[i].flags & (1 << clock_is_a_timing_peer)) != 0) - debug(2, "%s.", &clock_info[i].ip); + if ((clock_private_info[i].flags & (1 << clock_is_a_timing_peer)) != 0) + debug(2, "%s.", &clock_private_info[i].ip); } debug(2, "Timing group end"); @@ -156,7 +149,7 @@ void handle_control_port_messages(char *buf, ssize_t recv_len, clock_source *clo } } -void handle_announce(char *buf, ssize_t recv_len, clock_source *clock_info, +void handle_announce(char *buf, ssize_t recv_len, clock_source_private_data *clock_private_info, uint64_t reception_time) { // reject Announce messages from self if (clock_private_info->is_one_of_ours == 0) { @@ -205,7 +198,7 @@ void handle_announce(char *buf, ssize_t recv_len, clock_source *clock_info, uint8_t clockAccuracy = (clockQuality >> 16) & 0xff; uint16_t offsetScaledLogVariance = clockQuality & 0xffff; int best_clock_update_needed = 0; - if (((clock_info->flags & (1 << clock_is_qualified)) == 0) && + if (((clock_private_info->flags & (1 << clock_is_qualified)) == 0) && (msg->announce.stepsRemoved < 255)) { // if it's just becoming qualified clock_private_info->grandmasterIdentity = grandmaster_clock_id; @@ -259,7 +252,7 @@ void handle_announce(char *buf, ssize_t recv_len, clock_source *clock_info, debug(2, "clock_id %" PRIx64 " at: %s, \"Announce\" message is %sQualified -- See 9.3.2.5.", - clock_info->clock_id, clock_info->ip, + 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); @@ -272,35 +265,27 @@ void handle_announce(char *buf, ssize_t recv_len, clock_source *clock_info, debug(2, " grandmasterPriority2: %u.", msg->announce.grandmasterPriority2); debug(2, " stepsRemoved: %u.", msg->announce.stepsRemoved); - if (pthread_mutex_lock(&shared_memory->shm_mutex) != 0) - warn("Can't acquire mutex to mark best clock!"); // 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_info->flags &= ~(1 << clock_is_qualified); + clock_private_info->flags &= ~(1 << clock_is_qualified); else - clock_info->flags |= (1 << clock_is_qualified); + clock_private_info->flags |= (1 << clock_is_qualified); update_master(); - if (pthread_mutex_unlock(&shared_memory->shm_mutex) != 0) - warn("Can't release mutex after marking best clock!"); } } else { - if ((clock_info->flags & (1 << clock_is_qualified)) != + if ((clock_private_info->flags & (1 << clock_is_qualified)) != 0) // if it was qualified, but now isn't debug(2, "clock_id %" PRIx64 " on ip: %s \"Announce\" message is not Qualified -- See 9.3.2.5.", - clock_info->clock_id, clock_info->ip); - if (pthread_mutex_lock(&shared_memory->shm_mutex) != 0) - warn("Can't acquire mutex to mark unqualified clock!"); - clock_info->flags &= ~(1 << clock_is_qualified); - if (pthread_mutex_unlock(&shared_memory->shm_mutex) != 0) - warn("Can't release mutex after marking unqualified clock!"); + clock_private_info->clock_id, clock_private_info->ip); + clock_private_info->flags &= ~(1 << clock_is_qualified); } } } } -void handle_sync(char *buf, __attribute__((unused)) ssize_t recv_len, __attribute__((unused)) clock_source *clock_info, +void handle_sync(char *buf, __attribute__((unused)) ssize_t recv_len, clock_source_private_data *clock_private_info, uint64_t reception_time) { struct ptp_sync_message *msg = (struct ptp_sync_message *)buf; @@ -369,9 +354,8 @@ void handle_sync(char *buf, __attribute__((unused)) ssize_t recv_len, __attribut } } -void handle_follow_up(char *buf, __attribute__((unused)) ssize_t recv_len, clock_source *clock_info, - clock_source_private_data *clock_private_info, __attribute__((unused)) uint64_t reception_time, - pthread_mutex_t *shm_mutex) { +void handle_follow_up(char *buf, __attribute__((unused)) ssize_t recv_len, + clock_source_private_data *clock_private_info, __attribute__((unused)) uint64_t reception_time) { struct ptp_follow_up_message *msg = (struct ptp_follow_up_message *)buf; if ((clock_private_info->current_stage == sync_seen) && @@ -402,7 +386,7 @@ void handle_follow_up(char *buf, __attribute__((unused)) ssize_t recv_len, clock // now, if there was a valid offset previously, // check if the offset should be clamped - if ((clock_info->flags & (1 << clock_is_valid)) && + if ((clock_private_info->flags & (1 << clock_is_valid)) && (clock_private_info->vacant_samples != MAX_TIMING_SAMPLES)) { /* @@ -531,28 +515,15 @@ void handle_follow_up(char *buf, __attribute__((unused)) ssize_t recv_len, clock clock_private_info->previous_estimated_offset = estimated_offset; - int rc = pthread_mutex_lock(shm_mutex); - if (rc != 0) - warn("Can't acquire mutex to update a clock!"); - // update/set the clock_id - - clock_info->clock_id = packet_clock_id; - clock_info->flags |= (1 << clock_is_valid); - clock_info->local_time = clock_private_info->t2; - clock_info->local_to_source_time_offset = estimated_offset; - - if ((clock_info->flags & (1 << clock_is_master)) != 0) { - shared_memory->clock_id = clock_info->clock_id; - shared_memory->local_time = clock_info->local_time; - //uint64_t new_ptp_offset = clock_info->local_to_source_time_offset; - //new_ptp_offset += master_clock_to_ptp_offset; - //shared_memory->local_to_ptp_time_offset = new_ptp_offset; - shared_memory->local_to_ptp_time_offset = clock_info->local_to_source_time_offset; - debug(1,"clock: %" PRIx64 ", local_to_ptp_time_offset: %" PRIx64 ".", shared_memory->clock_id, shared_memory->local_to_ptp_time_offset); + + clock_private_info->clock_id = packet_clock_id; + clock_private_info->flags |= (1 << clock_is_valid); + clock_private_info->local_time = clock_private_info->t2; + clock_private_info->local_to_source_time_offset = estimated_offset; + + if ((clock_private_info->flags & (1 << clock_is_master)) != 0) { + update_master_clock_info(clock_private_info->clock_id, clock_private_info->local_time, clock_private_info->local_to_source_time_offset); } - rc = pthread_mutex_unlock(shm_mutex); - if (rc != 0) - warn("Can't release mutex after updating a clock!"); clock_private_info->next_sample_goes_here++; @@ -565,6 +536,6 @@ void handle_follow_up(char *buf, __attribute__((unused)) ssize_t recv_len, clock "Follow_Up %u expecting to be in state sync_seen (%u). Stage error -- " "current state is %u, sequence %u. Ignoring it. %s", ntohs(msg->header.sequenceId), sync_seen, clock_private_info->current_stage, - clock_private_info->sequence_number, clock_info->ip); + clock_private_info->sequence_number, clock_private_info->ip); } } \ No newline at end of file diff --git a/nqptp-message-handlers.h b/nqptp-message-handlers.h index 4460c95..0e6700e 100644 --- a/nqptp-message-handlers.h +++ b/nqptp-message-handlers.h @@ -23,17 +23,16 @@ #include "nqptp-clock-sources.h" #include "nqptp-shm-structures.h" -void handle_announce(char *buf, ssize_t recv_len, clock_source *clock_info, +void handle_announce(char *buf, ssize_t recv_len, clock_source_private_data *clock_private_info, uint64_t reception_time); -void handle_sync(char *buf, ssize_t recv_len, clock_source *clock_info, +void handle_sync(char *buf, ssize_t recv_len, clock_source_private_data *clock_private_info, uint64_t reception_time); -void handle_follow_up(char *buf, ssize_t recv_len, clock_source *clock_info, - clock_source_private_data *clock_private_info, uint64_t reception_time, - pthread_mutex_t *shm_mutex); +void handle_follow_up(char *buf, ssize_t recv_len, + clock_source_private_data *clock_private_info, uint64_t reception_time); -void handle_control_port_messages(char *buf, ssize_t recv_len, clock_source *clock_info, +void handle_control_port_messages(char *buf, ssize_t recv_len, clock_source_private_data *clock_private_info); #endif \ No newline at end of file diff --git a/nqptp-shm-structures.h b/nqptp-shm-structures.h index 7cadb7f..b5cf7e0 100644 --- a/nqptp-shm-structures.h +++ b/nqptp-shm-structures.h @@ -22,50 +22,26 @@ #define STORAGE_ID "/nqptp" #define MAX_CLOCKS 32 -#define NQPTP_SHM_STRUCTURES_VERSION 2 +#define NQPTP_SHM_STRUCTURES_VERSION 3 #define NQPTP_CONTROL_PORT 9000 -// the control port will accept a packet with the first letter being: -// "N" or "U" followed by a space and then a space-delimited +// the control port will accept a UDP packet with the first letter being: +// "T", followed by a space and then a space-delimited // list of ip numbers, either IPv4 or IPv6 // the whole not to exceed 4096 characters in total +// The IPs will become the new list of timing peers, replacing any previous #include #include #include -// most of this will probably become private when -// the master clock selection stuff works automatically - -typedef enum { - clock_is_valid, - clock_is_a_timing_peer, - clock_is_qualified, - clock_is_master -} clock_flags; - -typedef enum { - new_timing_peer_list = 'N', // followed by a (possibly empty) space-separated list of IPs - update_timing_peer_list = 'U' -} control_port_command; - -typedef struct { - char ip[64]; // 64 is nicely aligned and bigger than INET6_ADDRSTRLEN (46) - uint64_t clock_id; - uint64_t local_time; // the local time when the offset was calculated - uint64_t local_to_source_time_offset; // add this to the local time to get source time - uint32_t flags; -} clock_source; - struct shm_structure { pthread_mutex_t shm_mutex; // for safely accessing the structure - uint16_t size_of_clock_array; // deprecated -- check this is equal to MAX_SHARED_CLOCKS uint16_t version; // deprecated -- check this is equal to NQPTP_SHM_STRUCTURES_VERSION uint32_t flags; // unused + uint64_t master_clock_id; // the current master clock uint64_t local_time; // the time when the offset was calculated - uint64_t local_to_ptp_time_offset; // add this to the local time to get PTP time - uint64_t clock_id; // for information only - clock_source clocks[MAX_CLOCKS]; // deprecated + uint64_t local_to_master_time_offset; // add this to the local time to get master clock time }; #endif diff --git a/nqptp.c b/nqptp.c index d1219ad..98271fc 100644 --- a/nqptp.c +++ b/nqptp.c @@ -71,6 +71,20 @@ int master_clock_index = -1; struct shm_structure *shared_memory = NULL; // this is where public clock info is available int epoll_fd; +void update_master_clock_info(uint64_t master_clock_id, uint64_t local_time, uint64_t local_to_master_offset) { + if (shared_memory->master_clock_id != master_clock_id) + debug(1,"Master clock is: %" PRIx64 ", local_to_ptp_time_offset: %" PRIx64 ".", shared_memory->master_clock_id, shared_memory->local_to_master_time_offset); + int rc = pthread_mutex_lock(&shared_memory->shm_mutex); + if (rc != 0) + warn("Can't acquire mutex to update master clock!"); + shared_memory->master_clock_id = master_clock_id; + shared_memory->local_time = local_time; + shared_memory->local_to_master_time_offset = local_to_master_offset; + rc = pthread_mutex_unlock(&shared_memory->shm_mutex); + if (rc != 0) + warn("Can't release mutex after updating master clock!"); +} + void goodbye(void) { // close any open sockets unsigned int i; @@ -172,7 +186,6 @@ int main(void) { // zero it memset(shared_memory, 0, sizeof(struct shm_structure)); - shared_memory->size_of_clock_array = MAX_CLOCKS; shared_memory->version = NQPTP_SHM_STRUCTURES_VERSION; /*create mutex attr */ @@ -265,7 +278,7 @@ int main(void) { } // check if it's a control port message before checking for the length of the message. } else if (receiver_port == NQPTP_CONTROL_PORT) { - handle_control_port_messages(buf, recv_len, (clock_source *)&shared_memory->clocks, + handle_control_port_messages(buf, recv_len, (clock_source_private_data *)&clocks_private); } else if (recv_len >= (ssize_t)sizeof(struct ptp_common_message_header)) { debug_print_buffer(2, buf, recv_len); @@ -328,13 +341,13 @@ int main(void) { inet_ntop(connection_ip_family, sender_addr, sender_string, sizeof(sender_string)); // now, find or create a record for this ip int the_clock = - find_clock_source_record(sender_string, (clock_source *)&shared_memory->clocks, + find_clock_source_record(sender_string, (clock_source_private_data *)&clocks_private); // not sure about requiring a Sync before creating it... if ((the_clock == -1) && ((buf[0] & 0xF) == Sync)) { the_clock = create_clock_source_record( - sender_string, (clock_source *)&shared_memory->clocks, - (clock_source_private_data *)&clocks_private, 1); // the "1" means use mutexes + sender_string, + (clock_source_private_data *)&clocks_private); } if (the_clock != -1) { clocks_private[the_clock].time_of_last_use = @@ -342,20 +355,19 @@ int main(void) { switch (buf[0] & 0xF) { case Announce: // needed to reject messages coming from self - update_clock_self_identifications((clock_source *)&shared_memory->clocks, + update_clock_self_identifications( (clock_source_private_data *)&clocks_private); - handle_announce(buf, recv_len, &shared_memory->clocks[the_clock], + handle_announce(buf, recv_len, &clocks_private[the_clock], reception_time); break; case Sync: { // if it's a sync - handle_sync(buf, recv_len, &shared_memory->clocks[the_clock], + handle_sync(buf, recv_len, &clocks_private[the_clock], reception_time); } break; case Follow_Up: { - handle_follow_up(buf, recv_len, &shared_memory->clocks[the_clock], - &clocks_private[the_clock], reception_time, - &shared_memory->shm_mutex); + handle_follow_up(buf, recv_len, + &clocks_private[the_clock], reception_time); } break; default: break; @@ -365,7 +377,7 @@ int main(void) { } } } - manage_clock_sources(reception_time, (clock_source *)&shared_memory->clocks, + manage_clock_sources(reception_time, (clock_source_private_data *)&clocks_private); } } diff --git a/nqptp.h b/nqptp.h index 4b0552b..b3e3dcd 100644 --- a/nqptp.h +++ b/nqptp.h @@ -29,24 +29,12 @@ // When a new timing peer group is created, one of the clocks in the -// group becomes the master and its "native" time becomes the clock's "PTP time". +// group becomes the master and its native time becomes the "master time". // This is what is provided to the client. -// If another clock becomes the new master, then its "native" time will -// generally be different from PTP time. -// The offset from the new master's time to PTP time -// will be added to the master's time to translate it to PTP time. - -// You can create a _new_ timing peer group, which starts with a zero -// master_clock_to_ptp_offset and thus sets the PTP time to the native time -// of the first clock master of the group, as nature intended. - -// Alternatively, you can _update_ an existing timing peer group, which calculates an -// appropriate master_clock_to_ptp_offset to preserve timing relative to -// the existing PTP time, ensuring that PTP time remain consistent even -// when the clock master changes. - extern int master_clock_index; extern struct shm_structure *shared_memory; +void update_master_clock_info(uint64_t master_clock_id, uint64_t local_time, uint64_t local_to_master_offset); + #endif \ No newline at end of file -- 2.47.2