SatCat5
ptp_header.cc
1 // Copyright 2023-2025 The Aerospace Corporation.
3 // This file is a part of SatCat5, licensed under CERN-OHL-W v2 or later.
5 
6 #include <satcat5/log.h>
7 #include <satcat5/ptp_header.h>
8 #include <satcat5/utils.h>
9 
15 
16 void PortId::log_to(satcat5::log::LogBuffer& wr) const
17 {
18  wr.wr_str("0x");
19  wr.wr_h32(u32(clock_id >> 32), 8);
20  wr.wr_str("-");
21  wr.wr_h32(u32(clock_id >> 0), 8);
22  wr.wr_str("-");
23  wr.wr_h32(port_num, 4);
24 }
25 
27 {
28  if (rd->get_read_ready() >= 10) {
29  clock_id = rd->read_u64();
30  port_num = rd->read_u16();
31  return true;
32  } else {
33  return false;
34  }
35 }
36 
38 {
39  wr->write_u64(clock_id);
40  wr->write_u16(port_num);
41 }
42 
43 unsigned Header::msglen() const
44 {
45  switch (type) {
46  // Defined PTP message types.
47  case TYPE_SYNC: return 10; // Section 13.6
48  case TYPE_DELAY_REQ: return 10; // Section 13.6
49  case TYPE_PDELAY_REQ: return 20; // Section 13.9
50  case TYPE_PDELAY_RESP: return 20; // Section 13.10
51  case TYPE_FOLLOW_UP: return 10; // Section 13.7
52  case TYPE_DELAY_RESP: return 20; // Section 13.8
53  case TYPE_PDELAY_RFU: return 20; // Section 13.11
54  case TYPE_ANNOUNCE: return 30; // Section 13.5
55  case TYPE_SIGNALING: return 10; // Section 13.12
56  case TYPE_MANAGEMENT: return 14; // Section 15.4.1
57  // All other message types are reserved.
58  default: return 0; // Unknown / invalid
59  }
60 }
61 
63 {
64  wr.wr_str("\r\n MsgType: 0x"); wr.wr_h32(type, 1);
65  wr.wr_str("\r\n Version: "); wr.wr_d32(version);
66  wr.wr_str("\r\n Length: "); wr.wr_d32(length);
67  wr.wr_str("\r\n Domain: "); wr.wr_d32(domain);
68  wr.wr_str("\r\n SdoID: 0x"); wr.wr_h32(sdo_id, 4);
69  wr.wr_str("\r\n Flags: 0x"); wr.wr_h32(flags, 4);
70  wr.wr_str("\r\n CorrFld: "); wr.wr_d64(correction);
71  wr.wr_str("\r\n Subtype: 0x"); wr.wr_h32(subtype, 8);
72  wr.wr_str("\r\n SrcPort: "); src_port.log_to(wr);
73  wr.wr_str("\r\n SeqID: 0x"); wr.wr_h32(seq_id, 4);
74  wr.wr_str("\r\n Control: 0x"); wr.wr_h32(control, 2);
75  wr.wr_str("\r\n Intrval: 0x"); wr.wr_h32(log_interval, 2);
76 }
77 
79 {
80  if (rd->get_read_ready() >= HEADER_LEN) {
81  u8 sdo_type = rd->read_u8();
82  version = rd->read_u8() & 0x0F; // Drop minor version
83  length = rd->read_u16();
84  domain = rd->read_u8();
85  u8 minor_sdo = rd->read_u8();
86  flags = rd->read_u16();
87  correction = rd->read_u64();
88  subtype = rd->read_u32();
89  rd->read_obj(src_port);
90  seq_id = rd->read_u16();
91  control = rd->read_u8();
92  log_interval = rd->read_u8();
93  type = sdo_type & 0x0F; // Lower nibble
94  sdo_id = ((sdo_type & 0xF0) << 8) | minor_sdo; // Combine major/minor
95  return true;
96  } else {
97  return false;
98  }
99 }
100 
102 {
103  wr->write_u8(((u8) (sdo_id >> 4) & 0xF0) | (type & 0x0F));
104  wr->write_u8(version);
105  wr->write_u16(length);
106  wr->write_u8(domain);
107  wr->write_u8((u8) sdo_id); // Truncate
108  wr->write_u16(flags);
109  wr->write_u64(correction);
110  wr->write_u32(subtype);
111  wr->write_obj(src_port);
112  wr->write_u16(seq_id);
113  wr->write_u8(control);
114  wr->write_u8(log_interval);
115 }
116 
118 {
119  if (rd->get_read_ready() >= 17) {
121  grandmasterClass = rd->read_u8();
123  grandmasterVariance = rd->read_u16();
125  grandmasterIdentity = rd->read_u64();
126  stepsRemoved = rd->read_u16();
127  timeSource = rd->read_u8();
128  return true;
129  } else {
130  return false;
131  }
132 }
133 
135 {
139  wr->write_u16(grandmasterVariance);
141  wr->write_u64(grandmasterIdentity);
142  wr->write_u16(stepsRemoved);
143  wr->write_u8(timeSource);
144 }
145 
146 u16 satcat5::ptp::calc_log_variance(u64 variance_ps) {
147  u64 log2_var = satcat5::util::log2_ceil<u64>(variance_ps);
148  u64 field = (log2_var << 8) + ClockInfo::VARIANCE_1PSEC;
149  return (u16) satcat5::util::min_u64(field, ClockInfo::VARIANCE_MAX);
150 }
Abstract API for reading byte-streams and packets.
Definition: io_readable.h:68
bool read_obj(T &t)
Templated wrapper for any object with the following method: bool read_from(satcat5::io::Readable* rd)...
Definition: io_readable.h:140
u8 read_u8()
One of many functions for reading integer/floating point values, see details.
Definition: io_readable.cc:44
virtual unsigned get_read_ready() const =0
How many bytes can be read without blocking?
Abstract API for writing byte-streams and packets.
Definition: io_writeable.h:24
void write_u8(u8 data)
One of many functions for writing integer/floating point values, see details.
Definition: io_writeable.cc:20
void write_obj(const T &obj)
Templated wrapper for any object with the following method: void write_to(satcat5::io::Writeable* wr)...
Definition: io_writeable.h:104
Internal buffer used by the Log class.
Definition: log.h:134
void wr_d64(u64 val, unsigned zpad=0)
Write an unsigned integer (u64) in decimal format.
Definition: log.cc:323
void wr_h32(u32 val, unsigned nhex=8)
Write an integer (u32) in hexadecimal format.
Definition: log.cc:303
void wr_str(const char *str)
Write a null-terminated UTF-8 string.
Definition: log.cc:297
void wr_d32(u32 val, unsigned zpad=0)
Write an unsigned integer (u32) in decimal format.
Definition: log.cc:317
Diagnostic logging to UART and/or Ethernet ports.
Clock configuration metadata for the ANNOUNCE message.
Definition: ptp_header.h:117
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
bool read_from(satcat5::io::Readable *rd)
Read clock information from a given source.
Definition: ptp_header.cc:117
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
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
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
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 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
Miscellaneous mathematical utility functions.
unsigned log2_ceil(T x)
Calculate log2(x), rounding up.
Definition: utils.h:209
constexpr u64 min_u64(u64 a, u64 b)
Min and max functions.
Definition: utils.h:105