]> git.ipfire.org Git - thirdparty/nqptp.git/commitdiff
reorganise to make it a bit easier to get around.
authorMike Brady <4265913+mikebrady@users.noreply.github.com>
Sun, 4 Apr 2021 10:44:20 +0000 (11:44 +0100)
committerMike Brady <4265913+mikebrady@users.noreply.github.com>
Sun, 4 Apr 2021 10:44:20 +0000 (11:44 +0100)
Makefile.am
general-utilities.c [new file with mode: 0644]
general-utilities.h [new file with mode: 0644]
nqptp-clock-sources.c [new file with mode: 0644]
nqptp-clock-sources.h [new file with mode: 0644]
nqptp-ptp-definitions.h [new file with mode: 0644]
nqptp-shm-structures.h
nqptp-utilities.c [new file with mode: 0644]
nqptp-utilities.h [new file with mode: 0644]
nqptp.c
nqptp.h [new file with mode: 0644]

index 0ad0307577ca5abe9b8045d286200bba82c2b1ed..87e67b1ebe43510b9abba12be2498b9c5bf657da 100644 (file)
@@ -1,5 +1,5 @@
 bin_PROGRAMS = nqptp
-nqptp_SOURCES = nqptp.c debug.c
+nqptp_SOURCES = nqptp.c nqptp-clock-sources.c nqptp-utilities.c general-utilities.c debug.c
 
 AM_CFLAGS = -fno-common -Wno-multichar -Wall -Wextra -Wno-clobbered -Wno-psabi -pthread
 
diff --git a/general-utilities.c b/general-utilities.c
new file mode 100644 (file)
index 0000000..21acc56
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * This file is part of the nqptp distribution (https://github.com/mikebrady/nqptp).
+ * Copyright (c) 2021 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
+ * the Free Software Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Commercial licensing is also available.
+ */
+
+#include <string.h>
+#include <arpa/inet.h>
+#include "general-utilities.h"
+
+uint32_t nctohl(const uint8_t *p) { // read 4 characters from *p and do ntohl on them
+  // this is to avoid possible aliasing violations
+  uint32_t holder;
+  memcpy(&holder, p, sizeof(holder));
+  return ntohl(holder);
+}
+
+uint16_t nctohs(const uint8_t *p) { // read 2 characters from *p and do ntohs on them
+  // this is to avoid possible aliasing violations
+  uint16_t holder;
+  memcpy(&holder, p, sizeof(holder));
+  return ntohs(holder);
+}
+
+uint64_t timespec_to_ns(struct timespec *tn) {
+  uint64_t tnfpsec = tn->tv_sec;
+  uint64_t tnfpnsec = tn->tv_nsec;
+  tnfpsec = tnfpsec * 1000000000;
+  return tnfpsec + tnfpnsec;
+}
+
+uint64_t get_time_now() {
+  struct timespec tn;
+  clock_gettime(CLOCK_REALTIME, &tn); // this should be optionally CLOCK_MONOTONIC etc.
+  return timespec_to_ns(&tn);
+}
diff --git a/general-utilities.h b/general-utilities.h
new file mode 100644 (file)
index 0000000..0662445
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * This file is part of the nqptp distribution (https://github.com/mikebrady/nqptp).
+ * Copyright (c) 2021 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
+ * the Free Software Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Commercial licensing is also available.
+ */
+
+#ifndef GENERAL_UTILITIES_H
+#define GENERAL_UTILITIES_H
+
+// functions that are pretty generic
+// specialised stuff should go in the nqptp-utilities
+
+
+#include <inttypes.h>
+#include <time.h>
+
+uint32_t nctohl(const uint8_t *p); // read 4 characters from *p and do ntohl on them, avoiding aliasing
+uint16_t nctohs(const uint8_t *p);
+uint64_t timespec_to_ns(struct timespec *tn);
+uint64_t get_time_now();
+
+#endif
\ No newline at end of file
diff --git a/nqptp-clock-sources.c b/nqptp-clock-sources.c
new file mode 100644 (file)
index 0000000..1001127
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * This file is part of the nqptp distribution (https://github.com/mikebrady/nqptp).
+ * Copyright (c) 2021 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
+ * the Free Software Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Commercial licensing is also available.
+ */
+
+#include <string.h>
+#include "nqptp-clock-sources.h"
+#include "debug.h"
+
+#ifndef FIELD_SIZEOF
+#define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f))
+#endif
+
+int find_clock_source_record(char *sender_string, uint64_t packet_clock_id,
+                clock_source *clocks_shared_info,
+                clock_source_private_data *clocks_private_info) {
+  // return the index of the clock in the clock information arrays or -1
+  int response = -1;
+  int i = 0;
+  int found = 0;
+  while ((found == 0) && (i < MAX_CLOCKS)) {
+    if ((clocks_private_info[i].in_use != 0) &&
+        (clocks_shared_info[i].clock_id == packet_clock_id) &&
+        (strcasecmp(sender_string, (const char *)&clocks_shared_info[i].ip) == 0))
+      found = 1;
+    else
+      i++;
+  }
+  if (found == 1)
+    response = i;
+  return response;
+}
+
+int create_clock_source_record(char *sender_string, uint64_t packet_clock_id,
+                  clock_source *clocks_shared_info,
+                  clock_source_private_data *clocks_private_info) {
+  // 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
+  int response = -1;
+  int i = 0;
+  int found = 0;
+  while ((found == 0) && (i < MAX_CLOCKS)) {
+    if (clocks_private_info[i].in_use == 0)
+      found = 1;
+    else
+      i++;
+  }
+
+  if (found == 1) {
+    response = i;
+    int rc = pthread_mutex_lock(&shared_memory->shm_mutex);
+    if (rc != 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);
+    clocks_shared_info[i].clock_id = packet_clock_id;
+    rc = pthread_mutex_unlock(&shared_memory->shm_mutex);
+    if (rc != 0)
+      warn("Can't release mutex after activating a new clock!");
+
+    memset(&clocks_private_info[i], 0, sizeof(clock_source_private_data));
+    clocks_private_info[i].in_use = 1;
+    clocks_private_info[i].t2 = 0;
+    clocks_private_info[i].current_stage = waiting_for_sync;
+    debug(1, "activated source %d with clock_id %" PRIx64 " on ip: %s.", i,
+          clocks_shared_info[i].clock_id, &clocks_shared_info[i].ip);
+  } else {
+    die("Clock tables full!");
+  }
+  return response;
+}
+
+void manage_clock_sources(uint64_t reception_time, clock_source *clocks_shared_info,
+                            clock_source_private_data *clocks_private_info) {
+  debug(3, "manage_clock_sources");
+  int i;
+  for (i = 0; i < MAX_CLOCKS; i++) {
+    if (clocks_private_info[i].in_use != 0) {
+      int64_t time_since_last_sync = reception_time - clocks_private_info[i].t2;
+      if (time_since_last_sync > 60000000000) {
+        debug(1, "deactivating 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!");
+        memset(&clocks_private_info[i], 0, sizeof(clock_source_private_data));
+      }
+    }
+  }
+}
+
diff --git a/nqptp-clock-sources.h b/nqptp-clock-sources.h
new file mode 100644 (file)
index 0000000..84aad55
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * This file is part of the nqptp distribution (https://github.com/mikebrady/nqptp).
+ * Copyright (c) 2021 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
+ * the Free Software Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Commercial licensing is also available.
+ */
+
+#ifndef NQPTP_CLOCK_SOURCES_H
+#define NQPTP_CLOCK_SOURCES_H
+
+#include "nqptp.h"
+
+// transaction tracking
+enum stage {
+  waiting_for_sync,
+  sync_seen,
+};
+
+// private information -- not for putting in shared memory -- about each clock source
+typedef struct {
+  uint16_t sequence_number;
+  uint16_t in_use;
+  enum stage current_stage;
+  uint64_t t2;
+} clock_source_private_data;
+
+int find_clock_source_record(char *sender_string, uint64_t packet_clock_id,
+                clock_source *clocks_shared_info,
+                clock_source_private_data *clocks_private_info);
+
+int create_clock_source_record(char *sender_string, uint64_t packet_clock_id,
+                  clock_source *clocks_shared_info,
+                  clock_source_private_data *clocks_private_info);
+
+void manage_clock_sources(uint64_t reception_time, clock_source *clocks_shared_info,
+                            clock_source_private_data *clocks_private_info);
+
+
+#endif
diff --git a/nqptp-ptp-definitions.h b/nqptp-ptp-definitions.h
new file mode 100644 (file)
index 0000000..bb6a3db
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ * This file is part of the nqptp distribution (https://github.com/mikebrady/nqptp).
+ * Copyright (c) 2021 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
+ * the Free Software Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Commercial licensing is also available.
+ */
+
+#ifndef NQPTP_PTP_DEFINITIONS_H
+#define NQPTP_PTP_DEFINITIONS_H
+
+// References from the IEEE Document ISBN 978-0-7381-5400-8 STD95773.
+// "IEEE Standard for a Precision Clock Synchronization Protocol for Networked Measurement and
+// Control Systems" The IEEE Std 1588-2008 (Revision of IEEE Std 1588-2002)
+
+// Table 19
+enum messageType {
+  Sync,
+  Delay_Req,
+  Pdelay_Req,
+  Pdelay_Resp,
+  Reserved_4,
+  Reserved_5,
+  Reserved_6,
+  Reserved_7,
+  Follow_Up,
+  Delay_Resp,
+  Pdelay_Resp_Follow_Up,
+  Announce,
+  Signaling,
+  Management,
+  Reserved_E,
+  Reserved_F
+};
+
+ // this is the Common Message Header
+  struct __attribute__((__packed__)) ptp_common_message_header {
+    uint8_t transportSpecificAndMessageID; // 0x11
+    uint8_t reservedAndVersionPTP;         // 0x02
+    uint16_t messageLength;
+    uint8_t domainNumber;        // 0
+    uint8_t reserved_b;          // 0
+    uint16_t flags;              // 0x0608
+    uint64_t correctionField;    // 0
+    uint32_t reserved_l;         // 0
+    uint8_t clockIdentity[8];    // MAC
+    uint16_t sourcePortID;       // 1
+    uint16_t sequenceId;         // increments
+    uint8_t controlOtherMessage; // 5
+    uint8_t logMessagePeriod;    // 0
+  };
+
+  // this is the extra part for an Announce message
+  struct __attribute__((__packed__)) ptp_announce {
+    uint8_t originTimestamp[10];
+    uint16_t currentUtcOffset;
+    uint8_t reserved1;
+    uint8_t grandmasterPriority1;
+    uint32_t grandmasterClockQuality;
+    uint8_t grandmasterPriority2;
+    uint8_t grandmasterIdentity[8];
+    uint16_t stepsRemoved;
+    uint8_t timeSource;
+  };
+
+  // this is the extra part for a Sync or Delay_Req message
+  struct __attribute__((__packed__)) ptp_sync {
+    uint8_t originTimestamp[10];
+  };
+
+  // this is the extra part for a Sync or Delay_Req message
+  struct __attribute__((__packed__)) ptp_delay_req {
+    uint8_t originTimestamp[10];
+  };
+
+  // this is the extra part for a Follow_Up message
+  struct __attribute__((__packed__)) ptp_follow_up {
+    uint8_t preciseOriginTimestamp[10];
+  };
+
+  // this is the extra part for a Delay_Resp message
+  struct __attribute__((__packed__)) ptp_delay_resp {
+    uint8_t receiveTimestamp[10];
+    uint8_t requestingPortIdentity[10];
+  };
+
+  struct __attribute__((__packed__)) ptp_sync_message {
+    struct ptp_common_message_header header;
+    struct ptp_sync sync;
+  };
+
+  struct __attribute__((__packed__)) ptp_delay_req_message {
+    struct ptp_common_message_header header;
+    struct ptp_delay_req delay_req;
+  };
+
+  struct __attribute__((__packed__)) ptp_follow_up_message {
+    struct ptp_common_message_header header;
+    struct ptp_follow_up follow_up;
+  };
+
+  struct __attribute__((__packed__)) ptp_delay_resp_message {
+    struct ptp_common_message_header header;
+    struct ptp_delay_resp delay_resp;
+  };
+
+  struct __attribute__((__packed__)) ptp_announce_message {
+    struct ptp_common_message_header header;
+    struct ptp_announce announce;
+  };
+
+#endif
\ No newline at end of file
index c6d60e9cfdf558d9314ade6031310f10101fc32c..8832906ec60ebfdd83a4fa2583bebb30340f5173 100644 (file)
@@ -28,7 +28,7 @@
 #include <netinet/in.h>
 #include <pthread.h>
 
-struct clock_source {
+typedef struct {
   char ip[64]; // 64 is nicely aligned and bigger than INET6_ADDRSTRLEN (46)
   uint64_t clock_id;
   uint64_t reserved;
@@ -36,14 +36,14 @@ struct clock_source {
   uint64_t local_to_source_time_offset; // add this to the local time to get source time
   int flags;                            // not used yet
   int valid;                            // this entry is valid
-};
+} clock_source;
 
 struct shm_structure {
   pthread_mutex_t shm_mutex;    // for safely accessing the structure
   uint16_t size_of_clock_array; // check this is equal to MAX_SHARED_CLOCKS
   uint16_t version;             // check this is equal to NQPTP_SHM_STRUCTURES_VERSION
   uint32_t flags;
-  struct clock_source clocks[MAX_CLOCKS];
+  clock_source clocks[MAX_CLOCKS];
 };
 
 #endif
diff --git a/nqptp-utilities.c b/nqptp-utilities.c
new file mode 100644 (file)
index 0000000..1151a02
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * This file is part of the nqptp distribution (https://github.com/mikebrady/nqptp).
+ * Copyright (c) 2021 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
+ * the Free Software Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Commercial licensing is also available.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "nqptp-utilities.h"
+#include "debug.h"
+
+void debug_print_buffer(int level, char *buf, size_t buf_len) {
+  // printf("Received %u bytes in a packet from %s:%d\n", buf_len, inet_ntoa(si_other.sin_addr),
+  // ntohs(si_other.sin_port));
+  char *obf = malloc(buf_len * 4 + 1); // to be on the safe side -- 4 characters on average for each byte
+  if (obf != NULL) {
+  char *obfp = obf;
+  unsigned int obfc;
+  for (obfc = 0; obfc < buf_len; obfc++) {
+    snprintf(obfp, 3, "%02X", buf[obfc]);
+    obfp += 2;
+    if (obfc != buf_len - 1) {
+      if (obfc % 32 == 31) {
+        snprintf(obfp, 5, " || ");
+        obfp += 4;
+      } else if (obfc % 16 == 15) {
+        snprintf(obfp, 4, " | ");
+        obfp += 3;
+      } else if (obfc % 4 == 3) {
+        snprintf(obfp, 2, " ");
+        obfp += 1;
+      }
+    }
+  };
+  *obfp = 0;
+  switch (buf[0]) {
+
+  case 0x10:
+    debug(level, "SYNC: \"%s\".", obf);
+    break;
+  case 0x18:
+    debug(level, "FLUP: \"%s\".", obf);
+    break;
+  case 0x19:
+    debug(level, "DRSP: \"%s\".", obf);
+    break;
+  case 0x1B:
+    debug(level, "ANNC: \"%s\".", obf);
+    break;
+  case 0x1C:
+    debug(level, "SGNL: \"%s\".", obf);
+    break;
+  default:
+    debug(level, "      \"%s\".", obf);
+    break;
+  }
+  free(obf);
+  }
+}
+
diff --git a/nqptp-utilities.h b/nqptp-utilities.h
new file mode 100644 (file)
index 0000000..28e9922
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * This file is part of the nqptp distribution (https://github.com/mikebrady/nqptp).
+ * Copyright (c) 2021 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
+ * the Free Software Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Commercial licensing is also available.
+ */
+
+#ifndef NQPTP_UTILITIES_H
+#define NQPTP_UTILITIES_H
+#include <stddef.h>
+// functions that are specific to NQPTP
+// general stuff should go in the general-utilities
+
+void debug_print_buffer(int level, char *buf, size_t buf_len);
+
+#endif
\ No newline at end of file
diff --git a/nqptp.c b/nqptp.c
index b58e7a15675ae817bc6362becb686592079edf5d..4d71b5f949e70bd08e16001b2f31399683a1362a 100644 (file)
--- a/nqptp.c
+++ b/nqptp.c
 
 // 0 means no debug messages. 3 means lots!
 
-#define DEBUG_LEVEL 0
+#define DEBUG_LEVEL 1
 
+#include "nqptp.h"
+#include "nqptp-ptp-definitions.h"
+#include "nqptp-clock-sources.h"
+#include "nqptp-utilities.h"
+#include "general-utilities.h"
 #include "debug.h"
-#include "nqptp-shm-structures.h"
 
 #include <arpa/inet.h>
 #include <stdio.h>  //printf
 #define SIOCSHWTSTAMP 0x89b0
 #endif
 
-#ifndef FIELD_SIZEOF
-#define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f))
-#endif
-
-// References from the IEEE Document ISBN 978-0-7381-5400-8 STD95773.
-// "IEEE Standard for a Precision Clock Synchronization Protocol for Networked Measurement and
-// Control Systems" The IEEE Std 1588-2008 (Revision of IEEE Std 1588-2002)
-
-// transaction tracking
-enum stage {
-  waiting_for_sync,
-  sync_seen,
-};
-
-// Table 19
-enum messageType {
-  Sync,
-  Delay_Req,
-  Pdelay_Req,
-  Pdelay_Resp,
-  Reserved_4,
-  Reserved_5,
-  Reserved_6,
-  Reserved_7,
-  Follow_Up,
-  Delay_Resp,
-  Pdelay_Resp_Follow_Up,
-  Announce,
-  Signaling,
-  Management,
-  Reserved_E,
-  Reserved_F
-};
-
 // 8 samples per second
 
-#define MAX_TIMING_SAMPLES 1
-struct timing_samples {
-  uint64_t local, remote, local_to_remote_offset;
-} timing_samples;
-
-struct clock_private_info {
-  uint16_t sequence_number;
-  uint16_t in_use;
-  enum stage current_stage;
-  uint64_t t2;
-
-} clock_private_info;
-
 #define BUFLEN 4096 // Max length of buffer
-
 #define MAX_OPEN_SOCKETS 32 // up to 32 sockets open on ports 319 and 320
 
 struct socket_info {
   int number;
   uint16_t port;
 };
-struct clock_private_info clocks_private[MAX_CLOCKS];
+
+clock_source_private_data clocks_private[MAX_CLOCKS];
 
 struct socket_info sockets[MAX_OPEN_SOCKETS];
 unsigned int sockets_open =
     0; // also doubles as where to put next one, as sockets are never closed.
-struct shm_structure *shared_memory = NULL;
+struct shm_structure *shared_memory = NULL; // this is where public clock info is available
 int epoll_fd;
 
 // struct sockaddr_in6 is bigger than struct sockaddr.
@@ -148,161 +105,6 @@ int epoll_fd;
 
 uint64_t time_then = 0;
 
-uint32_t nctohl(const uint8_t *p) { // read 4 characters from *p and do ntohl on them
-  // this is to avoid possible aliasing violations
-  uint32_t holder;
-  memcpy(&holder, p, sizeof(holder));
-  return ntohl(holder);
-}
-
-uint16_t nctohs(const uint8_t *p) { // read 2 characters from *p and do ntohs on them
-  // this is to avoid possible aliasing violations
-  uint16_t holder;
-  memcpy(&holder, p, sizeof(holder));
-  return ntohs(holder);
-}
-
-uint64_t timespec_to_ns(struct timespec *tn) {
-  uint64_t tnfpsec = tn->tv_sec;
-  uint64_t tnfpnsec = tn->tv_nsec;
-  tnfpsec = tnfpsec * 1000000000;
-  return tnfpsec + tnfpnsec;
-}
-
-uint64_t get_time_now() {
-  struct timespec tn;
-  clock_gettime(CLOCK_REALTIME, &tn); // this should be optionally CLOCK_MONOTONIC etc.
-  return timespec_to_ns(&tn);
-}
-
-int find_source(char *sender_string, uint64_t packet_clock_id,
-                struct clock_source *clocks_shared_info,
-                struct clock_private_info *clocks_private_info) {
-  // return the index of the clock in the clock information arrays or -1
-  int response = -1;
-  int i = 0;
-  int found = 0;
-  while ((found == 0) && (i < MAX_CLOCKS)) {
-    if ((clocks_private_info[i].in_use != 0) &&
-        (clocks_shared_info[i].clock_id == packet_clock_id) &&
-        (strcasecmp(sender_string, (const char *)&clocks_shared_info[i].ip) == 0))
-      found = 1;
-    else
-      i++;
-  }
-  if (found == 1)
-    response = i;
-  return response;
-}
-
-int create_source(char *sender_string, uint64_t packet_clock_id,
-                  struct clock_source *clocks_shared_info,
-                  struct clock_private_info *clocks_private_info) {
-  // 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
-  int response = -1;
-  int i = 0;
-  int found = 0;
-  while ((found == 0) && (i < MAX_CLOCKS)) {
-    if (clocks_private_info[i].in_use == 0)
-      found = 1;
-    else
-      i++;
-  }
-
-  if (found == 1) {
-    response = i;
-    int rc = pthread_mutex_lock(&shared_memory->shm_mutex);
-    if (rc != 0)
-      warn("Can't acquire mutex to activate a new  clock!");
-    memset(&clocks_shared_info[i], 0, sizeof(struct clock_source));
-    strncpy((char *)&clocks_shared_info[i].ip, sender_string, FIELD_SIZEOF(struct clock_source,ip) - 1);
-    clocks_shared_info[i].clock_id = packet_clock_id;
-    rc = pthread_mutex_unlock(&shared_memory->shm_mutex);
-    if (rc != 0)
-      warn("Can't release mutex after activating a new clock!");
-
-    memset(&clocks_private_info[i], 0, sizeof(struct clock_private_info));
-    clocks_private_info[i].in_use = 1;
-    clocks_private_info[i].t2 = 0;
-    clocks_private_info[i].current_stage = waiting_for_sync;
-    debug(1, "activated source %d with clock_id %" PRIx64 " on ip: %s.", i,
-          clocks_shared_info[i].clock_id, &clocks_shared_info[i].ip);
-  } else {
-    die("Clock tables full!");
-  }
-  return response;
-}
-
-void deactivate_old_sources(uint64_t reception_time, struct clock_source *clocks_shared_info,
-                            struct clock_private_info *clocks_private_info) {
-  debug(3, "deactivate_old_sources");
-  int i;
-  for (i = 0; i < MAX_CLOCKS; i++) {
-    if (clocks_private_info[i].in_use != 0) {
-      int64_t time_since_last_sync = reception_time - clocks_private_info[i].t2;
-      if (time_since_last_sync > 60000000000) {
-        debug(1, "deactivating 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(struct clock_source));
-        rc = pthread_mutex_unlock(&shared_memory->shm_mutex);
-        if (rc != 0)
-          warn("Can't release mutex after deactivating a clock!");
-        memset(&clocks_private_info[i], 0, sizeof(struct clock_private_info));
-      }
-    }
-  }
-}
-
-void debug_print_buffer(int level, char *buf, size_t buf_len) {
-  // printf("Received %u bytes in a packet from %s:%d\n", buf_len, inet_ntoa(si_other.sin_addr),
-  // ntohs(si_other.sin_port));
-  char obf[BUFLEN * 2 + BUFLEN / 4 + 1 + 1];
-  char *obfp = obf;
-  unsigned int obfc;
-  for (obfc = 0; obfc < buf_len; obfc++) {
-    snprintf(obfp, 3, "%02X", buf[obfc]);
-    obfp += 2;
-    if (obfc != buf_len - 1) {
-      if (obfc % 32 == 31) {
-        snprintf(obfp, 5, " || ");
-        obfp += 4;
-      } else if (obfc % 16 == 15) {
-        snprintf(obfp, 4, " | ");
-        obfp += 3;
-      } else if (obfc % 4 == 3) {
-        snprintf(obfp, 2, " ");
-        obfp += 1;
-      }
-    }
-  };
-  *obfp = 0;
-  switch (buf[0]) {
-
-  case 0x10:
-    debug(level, "SYNC: \"%s\".", obf);
-    break;
-  case 0x18:
-    debug(level, "FLUP: \"%s\".", obf);
-    break;
-  case 0x19:
-    debug(level, "DRSP: \"%s\".", obf);
-    break;
-  case 0x1B:
-    debug(level, "ANNC: \"%s\".", obf);
-    break;
-  case 0x1C:
-    debug(level, "SGNL: \"%s\".", obf);
-    break;
-  default:
-    debug(level, "      \"%s\".", obf);
-    break;
-  }
-}
-
 void goodbye(void) {
   // close any open sockets
   unsigned int i;
@@ -358,81 +160,6 @@ int main(void) {
 
   char buf[BUFLEN];
 
-  struct __attribute__((__packed__)) ptp_common_message_header {
-    uint8_t transportSpecificAndMessageID; // 0x11
-    uint8_t reservedAndVersionPTP;         // 0x02
-    uint16_t messageLength;
-    uint8_t domainNumber;        // 0
-    uint8_t reserved_b;          // 0
-    uint16_t flags;              // 0x0608
-    uint64_t correctionField;    // 0
-    uint32_t reserved_l;         // 0
-    uint8_t clockIdentity[8];    // MAC
-    uint16_t sourcePortID;       // 1
-    uint16_t sequenceId;         // increments
-    uint8_t controlOtherMessage; // 5
-    uint8_t logMessagePeriod;    // 0
-  };
-
-  // this is the extra part for an Announce message
-  struct __attribute__((__packed__)) ptp_announce {
-    uint8_t originTimestamp[10];
-    uint16_t currentUtcOffset;
-    uint8_t reserved1;
-    uint8_t grandmasterPriority1;
-    uint32_t grandmasterClockQuality;
-    uint8_t grandmasterPriority2;
-    uint8_t grandmasterIdentity[8];
-    uint16_t stepsRemoved;
-    uint8_t timeSource;
-  };
-
-  // this is the extra part for a Sync or Delay_Req message
-  struct __attribute__((__packed__)) ptp_sync {
-    uint8_t originTimestamp[10];
-  };
-
-  // this is the extra part for a Sync or Delay_Req message
-  struct __attribute__((__packed__)) ptp_delay_req {
-    uint8_t originTimestamp[10];
-  };
-
-  // this is the extra part for a Follow_Up message
-  struct __attribute__((__packed__)) ptp_follow_up {
-    uint8_t preciseOriginTimestamp[10];
-  };
-
-  // this is the extra part for a Delay_Resp message
-  struct __attribute__((__packed__)) ptp_delay_resp {
-    uint8_t receiveTimestamp[10];
-    uint8_t requestingPortIdentity[10];
-  };
-
-  struct __attribute__((__packed__)) ptp_sync_message {
-    struct ptp_common_message_header header;
-    struct ptp_sync sync;
-  };
-
-  struct __attribute__((__packed__)) ptp_delay_req_message {
-    struct ptp_common_message_header header;
-    struct ptp_delay_req delay_req;
-  };
-
-  struct __attribute__((__packed__)) ptp_follow_up_message {
-    struct ptp_common_message_header header;
-    struct ptp_follow_up follow_up;
-  };
-
-  struct __attribute__((__packed__)) ptp_delay_resp_message {
-    struct ptp_common_message_header header;
-    struct ptp_delay_resp delay_resp;
-  };
-
-  struct __attribute__((__packed__)) ptp_announce_message {
-    struct ptp_common_message_header header;
-    struct ptp_announce announce;
-  };
-
   pthread_mutexattr_t shared;
   int err;
 
@@ -753,13 +480,13 @@ int main(void) {
               packet_clock_id = packet_clock_id << 32;
               packet_clock_id = packet_clock_id + packet_clock_id_low;
 
-              int the_clock = find_source(sender_string, packet_clock_id,
-                                          (struct clock_source *)&shared_memory->clocks,
-                                          (struct clock_private_info *)&clocks_private);
+              int the_clock = find_clock_source_record(sender_string, packet_clock_id,
+                                          (clock_source *)&shared_memory->clocks,
+                                          (clock_source_private_data *)&clocks_private);
               if ((the_clock == -1) && ((buf[0] & 0xF) == Sync)) {
-                the_clock = create_source(sender_string, packet_clock_id,
-                                          (struct clock_source *)&shared_memory->clocks,
-                                          (struct clock_private_info *)&clocks_private);
+                the_clock = create_clock_source_record(sender_string, packet_clock_id,
+                                          (clock_source *)&shared_memory->clocks,
+                                          (clock_source_private_data *)&clocks_private);
               }
               if (the_clock != -1) {
                 switch (buf[0] & 0xF) {
@@ -869,8 +596,8 @@ int main(void) {
           }
         }
       }
-      deactivate_old_sources(reception_time, (struct clock_source *)&shared_memory->clocks,
-                             (struct clock_private_info *)&clocks_private);
+      manage_clock_sources(reception_time, (clock_source *)&shared_memory->clocks,
+                             (clock_source_private_data *)&clocks_private);
     }
   }
 
diff --git a/nqptp.h b/nqptp.h
new file mode 100644 (file)
index 0000000..9f1ade3
--- /dev/null
+++ b/nqptp.h
@@ -0,0 +1,27 @@
+/*
+ * This file is part of the nqptp distribution (https://github.com/mikebrady/nqptp).
+ * Copyright (c) 2021 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
+ * the Free Software Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Commercial licensing is also available.
+ */
+
+#ifndef NQPTP_H
+#define NQPTP_H
+
+#include "nqptp-shm-structures.h"
+
+extern struct shm_structure *shared_memory;
+
+#endif
\ No newline at end of file