From: Mike Brady <4265913+mikebrady@users.noreply.github.com> Date: Sun, 4 Apr 2021 10:44:20 +0000 (+0100) Subject: reorganise to make it a bit easier to get around. X-Git-Tag: 1.1-dev~49 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=68cae7402c25f8a17ab0e7bfbb309584b9f5dd12;p=thirdparty%2Fnqptp.git reorganise to make it a bit easier to get around. --- diff --git a/Makefile.am b/Makefile.am index 0ad0307..87e67b1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -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 index 0000000..21acc56 --- /dev/null +++ b/general-utilities.c @@ -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 . + * + * Commercial licensing is also available. + */ + +#include +#include +#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 index 0000000..0662445 --- /dev/null +++ b/general-utilities.h @@ -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 . + * + * 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 +#include + +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 index 0000000..1001127 --- /dev/null +++ b/nqptp-clock-sources.c @@ -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 . + * + * Commercial licensing is also available. + */ + +#include +#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 index 0000000..84aad55 --- /dev/null +++ b/nqptp-clock-sources.h @@ -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 . + * + * 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 index 0000000..bb6a3db --- /dev/null +++ b/nqptp-ptp-definitions.h @@ -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 . + * + * 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 diff --git a/nqptp-shm-structures.h b/nqptp-shm-structures.h index c6d60e9..8832906 100644 --- a/nqptp-shm-structures.h +++ b/nqptp-shm-structures.h @@ -28,7 +28,7 @@ #include #include -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 index 0000000..1151a02 --- /dev/null +++ b/nqptp-utilities.c @@ -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 . + * + * Commercial licensing is also available. + */ + +#include +#include +#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 index 0000000..28e9922 --- /dev/null +++ b/nqptp-utilities.h @@ -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 . + * + * Commercial licensing is also available. + */ + +#ifndef NQPTP_UTILITIES_H +#define NQPTP_UTILITIES_H +#include +// 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 b58e7a1..4d71b5f 100644 --- a/nqptp.c +++ b/nqptp.c @@ -19,10 +19,14 @@ // 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 #include //printf @@ -72,69 +76,22 @@ #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 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 . + * + * 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