]> git.ipfire.org Git - thirdparty/nqptp.git/commitdiff
remove all the public clock information except for the master clock. amalgamate each...
authorMike Brady <4265913+mikebrady@users.noreply.github.com>
Sun, 18 Apr 2021 10:43:14 +0000 (11:43 +0100)
committerMike Brady <4265913+mikebrady@users.noreply.github.com>
Sun, 18 Apr 2021 10:43:14 +0000 (11:43 +0100)
nqptp-clock-sources.c
nqptp-clock-sources.h
nqptp-message-handlers.c
nqptp-message-handlers.h
nqptp-shm-structures.h
nqptp.c
nqptp.h

index 7a97db739f68bc5816d7bfdf5ec030be8f9dc7bd..14443a18154d9d3ad6e1e17f815eb09a768dc03b 100644 (file)
@@ -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;
         }
index 3521366ba0cea9d2a2217e24410bf6dc91462e2c..8a4f18be9a84af076d3c22bba17a2fe3275622ce 100644 (file)
@@ -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];
index 43d9f1ae349030e8d59973e021b0384435c05bc3..447ee175bb4dabdcdb351a0e404b77a410fd1809 100644 (file)
 #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
index 4460c95e8dd4a238a65ed187e9bebb03b7c1c35e..0e6700ecab134bece8a0e7b700a061e4ba312fcf 100644 (file)
 #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
index 7cadb7f2a6a64e5810c9812d6f0538bf3ed059f6..b5cf7e05c1498c71f475a9320d4a6b0c2b2eefe9 100644 (file)
 
 #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 <inttypes.h>
 #include <netinet/in.h>
 #include <pthread.h>
 
-// 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 d1219ad2e9932398289b8502cb4c85084e195cb4..98271fc85e50a6e9035731df682df20cb95798af 100644 (file)
--- 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 4b0552bf765200b0dd6254b848fae19527d7a571..b3e3dcdd7cbe1a3ca899c52c37806b976aa0ac4a 100644 (file)
--- a/nqptp.h
+++ b/nqptp.h
 
 
 // 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