SatCat5
ptp_header.h
1 // Copyright 2023-2026 The Aerospace Corporation.
3 // This file is a part of SatCat5, licensed under CERN-OHL-W v2 or later.
5 // Shared message header for the Precision Time Protocol (PTP / IEEE-1588)
6 
7 #pragma once
8 
9 #include <satcat5/io_readable.h>
10 #include <satcat5/io_writeable.h>
11 
12 namespace satcat5 {
13  namespace ptp {
17  struct PortId {
18  u64 clock_id;
19  u16 port_num;
20 
21  // Explicitly declare default constructor and copy methods.
22  PortId() = default;
23  PortId(const PortId& t) = default;
24  PortId& operator=(const PortId& t) = default;
25 
27  inline bool operator==(const PortId& other) const {
28  return (clock_id == other.clock_id)
29  && (port_num == other.port_num);
30  }
31 
33  void log_to(satcat5::log::LogBuffer& wr) const;
37  void write_to(satcat5::io::Writeable* wr) const;
38  };
39 
40  constexpr satcat5::ptp::PortId PORT_NONE = {0, 0};
41 
46  struct Header {
47  // Message header fields (Section 13.3)
48  u8 type;
49  u8 version;
50  u16 length;
51  u8 domain;
52  u16 sdo_id;
53  u16 flags;
54  u64 correction;
55  u32 subtype;
57  u16 seq_id;
58  u8 control;
60 
62  static constexpr unsigned HEADER_LEN = 34;
63 
65  static constexpr u8
66  TYPE_SYNC = 0x0,
67  TYPE_DELAY_REQ = 0x1,
68  TYPE_PDELAY_REQ = 0x2,
69  TYPE_PDELAY_RESP = 0x3,
70  TYPE_FOLLOW_UP = 0x8,
71  TYPE_DELAY_RESP = 0x9,
72  TYPE_PDELAY_RFU = 0xA,
73  TYPE_ANNOUNCE = 0xB,
74  TYPE_SIGNALING = 0xC,
75  TYPE_MANAGEMENT = 0xD;
76 
78  static constexpr u16
79  FLAG_LEAP61 = (1u << 0),
80  FLAG_LEAP59 = (1u << 1),
81  FLAG_UTC_VALID = (1u << 2),
82  FLAG_PTP_TIMESCALE = (1u << 3),
83  FLAG_TIME_TRACEABLE = (1u << 4),
84  FLAG_FREQ_TRACEABLE = (1u << 5),
85  FLAG_UNCERTAIN = (1u << 6),
86  FLAG_ALT_MASTER = (1u << 8),
87  FLAG_TWO_STEP = (1u << 9),
88  FLAG_UNICAST = (1u << 10),
89  FLAG_PROFILE1 = (1u << 13),
90  FLAG_PROFILE2 = (1u << 14);
91 
93  static constexpr u16 FLAG_SPTP = FLAG_PROFILE1;
94 
95  // Explicitly declare default constructor and copy methods.
96  Header() = default;
97  Header(const Header& t) = default;
98  Header& operator=(const Header& t) = default;
99 
102  unsigned msglen() const;
103  static constexpr unsigned MAX_MSGLEN = 30;
104 
106  void log_to(satcat5::log::LogBuffer& wr) const;
110  void write_to(satcat5::io::Writeable* wr) const;
111  };
112 
113  constexpr satcat5::ptp::Header HEADER_NULL =
114  {0, 0, 0, 0, 0, 0, 0, 0, {0, 0}, 0, 0, 0};
115 
117  struct ClockInfo {
121  u8 grandmasterPriority1; // Note: Lower takes priority
122  u8 grandmasterClass; // Traceability to reference?
123  u8 grandmasterAccuracy; // Approximate accuracy
124  u16 grandmasterVariance; // Fixed-point variance
125  u8 grandmasterPriority2; // Note: Lower takes priority
126  u64 grandmasterIdentity; // Unique identifier
127  u16 stepsRemoved; // Number of hops to grandmaster
128  u8 timeSource; // Reference type
130 
132  static constexpr u8
134  PRIORITY_MID = 128,
135  PRIORITY_MAX = 0;
136 
139  static constexpr u8
140  CLASS_PRIMARY = 6, // Primary reference
141  CLASS_PRIMARY_HOLDOVER = 7, // Primary (hold-over mode)
142  CLASS_APP_SPEC = 13, // Application-specific reference
143  CLASS_APP_SPEC_HOLDOVER = 14, // App-specific (hold-over mode)
144  CLASS_PRIMARY_DEG_A = 52, // Primary (degraded)
145  CLASS_APP_SPEC_DEG_A = 58, // App-specific (degraded)
146  CLASS_PRIMARY_DEG_B = 187, // Primary (degraded)
147  CLASS_APP_SPEC_DEG_B = 193, // App-specific (degraded)
148  CLASS_DEFAULT = 248, // Any other clock
149  CLASS_SLAVE = 255; // Any slave-only clock
150 
152  static constexpr u8
154  ACCURACY_2PSEC = 0x18,
155  ACCURACY_10PSEC = 0x19,
156  ACCURACY_25PSEC = 0x1A,
157  ACCURACY_100PSEC = 0x1B,
158  ACCURACY_250PSEC = 0x1C,
159  ACCURACY_1NSEC = 0x1D,
160  ACCURACY_2NSEC = 0x1E,
161  ACCURACY_10NSEC = 0x1F,
162  ACCURACY_25NSEC = 0x20,
163  ACCURACY_100NSEC = 0x21,
164  ACCURACY_250NSEC = 0x22,
165  ACCURACY_1USEC = 0x23,
166  ACCURACY_2USEC = 0x24,
167  ACCURACY_10USEC = 0x25,
168  ACCURACY_25USEC = 0x26,
169  ACCURACY_100USEC = 0x27,
170  ACCURACY_250USEC = 0x28,
171  ACCURACY_1MSEC = 0x29,
172  ACCURACY_2MSEC = 0x2A,
173  ACCURACY_10MSEC = 0x2B,
174  ACCURACY_25MSEC = 0x2C,
175  ACCURACY_100MSEC = 0x2D,
176  ACCURACY_250MSEC = 0x2E,
177  ACCURACY_1SEC = 0x2F,
178  ACCURACY_10SEC = 0x30,
179  ACCURACY_LOW = 0x31,
180  ACCURACY_UNK = 0xFE;
181 
188  static constexpr u16
189  VARIANCE_1PSEC = 0x3046,
190  VARIANCE_10PSEC = 0x36EB,
191  VARIANCE_100PSEC = 0x3D90,
192  VARIANCE_1NSEC = 0x4435,
193  VARIANCE_10NSEC = 0x4AD9,
194  VARIANCE_100NSEC = 0x517E,
195  VARIANCE_1USEC = 0x5823,
196  VARIANCE_10USEC = 0x5EC8,
197  VARIANCE_100USEC = 0x656D,
198  VARIANCE_1MSEC = 0x6C12,
199  VARIANCE_10MSEC = 0x72B6,
200  VARIANCE_100MSEC = 0x795B,
201  VARIANCE_1SEC = 0x8000,
202  VARIANCE_MAX = 0xFFFF;
203 
205  static constexpr u8
206  SRC_ATOMIC = 0x10, // Local atomic clock
207  SRC_GNSS = 0x20, // GPS, Galileo, etc.
208  SRC_RADIO = 0x30, // Terrestrial radio
209  SRC_SERIAL = 0x39, // IRIG-B or similar
210  SRC_PTP = 0x40, // Another PTP domain
211  SRC_NTP = 0x50, // Network time protocol
212  SRC_MANUAL = 0x60, // Human-provided
213  SRC_OTHER = 0x90, // Any other source
214  SRC_INTERNAL = 0xA0; // Internal oscillator
215 
216  // Explicitly declare default constructor and copy methods.
217  ClockInfo() = default;
218  ClockInfo(const ClockInfo& t) = default;
219  ClockInfo& operator=(const ClockInfo& t) = default;
220 
224  void write_to(satcat5::io::Writeable* wr) const;
225  };
226 
229  u16 calc_log_variance(u64 variance_ps);
230 
231 
233  constexpr satcat5::ptp::ClockInfo DEFAULT_CLOCK = {
234  ClockInfo::PRIORITY_MIN, // Lowest possible priority
235  ClockInfo::CLASS_DEFAULT, // Unspecified traceability
236  ClockInfo::ACCURACY_UNK,
237  ClockInfo::VARIANCE_MAX,
239  0, // User should replace source-ID
240  0, // Grandmaster = self
241  ClockInfo::SRC_INTERNAL,
242  };
243 
245  constexpr satcat5::ptp::ClockInfo VERY_GOOD_CLOCK = {
246  ClockInfo::PRIORITY_MID, // Mid-priority
247  ClockInfo::CLASS_PRIMARY, // Directly traceable to GPS
248  ClockInfo::ACCURACY_25NSEC,
249  ClockInfo::VARIANCE_10NSEC,
250  ClockInfo::PRIORITY_MID,
251  0, // User should replace source-ID
252  0, // Grandmaster = self
253  ClockInfo::SRC_INTERNAL,
254  };
255  }
256 }
Abstract API for reading byte-streams and packets.
Definition: io_readable.h:68
Abstract API for writing byte-streams and packets.
Definition: io_writeable.h:24
Internal buffer used by the Log class.
Definition: log.h:134
"Readable" I/O interface core definitions
"Writeable" I/O interface core definitions
Clock configuration metadata for the ANNOUNCE message.
Definition: ptp_header.h:117
static constexpr u8 PRIORITY_MIN
Priority index: Lower values take priority.
Definition: ptp_header.h:133
u16 stepsRemoved
Fields defined in Section 13.5.1, Table 43.
Definition: ptp_header.h:127
u8 grandmasterPriority1
Fields defined in Section 13.5.1, Table 43.
Definition: ptp_header.h:121
static constexpr u16 VARIANCE_1PSEC
The "offsetScaledLogVariance" metric.
Definition: ptp_header.h:189
u64 grandmasterIdentity
Fields defined in Section 13.5.1, Table 43.
Definition: ptp_header.h:126
u8 timeSource
Fields defined in Section 13.5.1, Table 43.
Definition: ptp_header.h:128
static constexpr u8 ACCURACY_1PSEC
Accuracy enumeration from Section 7.6.2.6, Table 5.
Definition: ptp_header.h:153
bool read_from(satcat5::io::Readable *rd)
Read clock information from a given source.
Definition: ptp_header.cc:117
static constexpr u8 CLASS_PRIMARY
ClockClass values from Section 7.6.2.5, Table 4.
Definition: ptp_header.h:140
u8 grandmasterClass
Fields defined in Section 13.5.1, Table 43.
Definition: ptp_header.h:122
u8 grandmasterAccuracy
Fields defined in Section 13.5.1, Table 43.
Definition: ptp_header.h:123
u16 grandmasterVariance
Fields defined in Section 13.5.1, Table 43.
Definition: ptp_header.h:124
static constexpr u8 SRC_ATOMIC
TimeSource values from Section 7.6.2.8, Table 6.
Definition: ptp_header.h:206
void write_to(satcat5::io::Writeable *wr) const
Write clock information to the given sink.
Definition: ptp_header.cc:134
u8 grandmasterPriority2
Fields defined in Section 13.5.1, Table 43.
Definition: ptp_header.h:125
Struct representing the PTP header used for all message types.
Definition: ptp_header.h:46
u8 control
controlField
Definition: ptp_header.h:58
u32 subtype
messageTypeSpecific
Definition: ptp_header.h:55
u64 correction
correctionField
Definition: ptp_header.h:54
void write_to(satcat5::io::Writeable *wr) const
Write header contents to the given sink.
Definition: ptp_header.cc:101
static constexpr u16 FLAG_LEAP61
Flag definitions (Section 13.3.2.8 / Table 37)
Definition: ptp_header.h:79
u16 flags
flagField
Definition: ptp_header.h:53
u8 version
versionPTP only
Definition: ptp_header.h:49
satcat5::ptp::PortId src_port
sourcePortIdentity
Definition: ptp_header.h:56
s8 log_interval
logMessageInterval
Definition: ptp_header.h:59
static constexpr u16 FLAG_SPTP
SPTP uses the PROFILE1 flag, so define an alias.
Definition: ptp_header.h:93
u16 sdo_id
majorSdoId + minorSdoId
Definition: ptp_header.h:52
bool read_from(satcat5::io::Readable *rd)
Read header contents from a given source.
Definition: ptp_header.cc:78
void log_to(satcat5::log::LogBuffer &wr) const
Log human-readable information about this header.
Definition: ptp_header.cc:62
u16 length
messageLength
Definition: ptp_header.h:50
static constexpr unsigned HEADER_LEN
Header itself is exactly 34 bytes.
Definition: ptp_header.h:62
unsigned msglen() const
Expected length of message fields, not including header.
Definition: ptp_header.cc:43
u8 type
messageType (0-15)
Definition: ptp_header.h:48
u8 domain
domainNumber
Definition: ptp_header.h:51
static constexpr u8 TYPE_SYNC
Message types (Section 13.3.2.3 / Table 36)
Definition: ptp_header.h:66
u16 seq_id
sequenceId
Definition: ptp_header.h:57
Struct used for sourcePortIdentity and requestingPortIdentity.
Definition: ptp_header.h:17
bool operator==(const PortId &other) const
Equality check.
Definition: ptp_header.h:27
bool read_from(satcat5::io::Readable *rd)
Read port-identifier from a given source.
Definition: ptp_header.cc:26
u64 clock_id
Clock identifier.
Definition: ptp_header.h:18
u16 port_num
Port number.
Definition: ptp_header.h:19
void write_to(satcat5::io::Writeable *wr) const
Write port-identifier to the given sink.
Definition: ptp_header.cc:37
void log_to(satcat5::log::LogBuffer &wr) const
Log human-readable information about this port-identity.
Definition: ptp_header.cc:16