SatCat5
ptp_client.h
1 // Copyright 2023-2025 The Aerospace Corporation.
3 // This file is a part of SatCat5, licensed under CERN-OHL-W v2 or later.
5 // Client for the IEEE 1588-2019 Precision Time Protocol (PTP)
6 
7 #pragma once
8 
9 #include <satcat5/igmp_client.h>
10 #include <satcat5/io_readable.h>
11 #include <satcat5/list.h>
12 #include <satcat5/polling.h>
13 #include <satcat5/ptp_dispatch.h>
14 #include <satcat5/ptp_header.h>
16 #include <satcat5/ptp_source.h>
17 
18 namespace satcat5 {
19  namespace ptp {
21  enum class ClientMode {
22  DISABLED, // Complete shutdown (Section 9.2.5)
23  MASTER_L2, // Master only, Ethernet mode (Section 9.2.2.1)
24  MASTER_L3, // Master only, UDP mode (Section 9.2.2.1)
25  SLAVE_ONLY, // Slave only, ordinary mode (Section 9.2.2.2)
26  SLAVE_SPTP, // Slave only, SPTP mode
27  PASSIVE, // Passive mode (for Pdelay) (Section 9.2.5)
28  };
29 
35  enum class ClientState {
36  DISABLED, // Manual shutdown
37  LISTENING, // Waiting for ANNOUNCE to select a master
38  MASTER, // Actively providing time to other clients
39  PASSIVE, // Passively responding to peer requests
40  SLAVE, // Actively synchronizing local clock to master
41  };
42 
44  const char* to_string(satcat5::ptp::ClientMode mode);
46  const char* to_string(satcat5::ptp::ClientState state);
47 
64  class Client
65  : public satcat5::poll::Timer
66  , public satcat5::ptp::Source
67  {
68  public:
70  Client(
71  satcat5::ptp::Interface* ptp_iface,
72  satcat5::ip::Dispatch* ip_dispatch,
73  satcat5::ptp::ClientMode mode = ClientMode::DISABLED);
74  ~Client() SATCAT5_OPTIONAL_DTOR;
75 
77  inline void set_clock(const satcat5::ptp::ClockInfo& clk)
78  { m_clock_local = clk; }
81  { return m_clock_local; }
84  { return m_clock_remote; }
87  { return m_iface.ptp_time_now(); }
88 
93  inline s16 get_utc_offset() const
94  { return m_utc_offset; }
95 
102  inline void set_utc_offset(s16 offset)
103  { m_utc_offset = offset; }
104 
107  void set_mode(satcat5::ptp::ClientMode mode);
108  inline satcat5::ip::Dispatch* get_iface() const {return m_iface.iface();}
109  inline satcat5::ptp::ClientMode get_mode() const {return m_mode;}
110  inline satcat5::ptp::ClientState get_state() const {return m_state;}
111  inline satcat5::ptp::PortId get_source() const {return m_current_source;}
113 
117  void set_announce_rate(int rate);
118 
122  void set_sync_rate(int rate);
123 
127  void set_pdelay_rate(int rate);
128 
132  bool send_sync_unicast(
133  const satcat5::eth::MacAddr& mac,
134  const satcat5::ip::Addr& ip = satcat5::ip::ADDR_NONE,
135  const satcat5::eth::VlanTag& vtag = satcat5::eth::VTAG_NONE);
136 
139 
140  protected:
141  // Timer event handler.
142  void timer_event() override;
143 
144  // Timer setup based on current state.
145  void timer_reset();
146 
147  // Handling for various error events.
148  void cache_miss();
149  void client_timeout();
150 
151  // Handlers for TLV and measurement events.
152  unsigned tlv_send(
153  const satcat5::ptp::Header& hdr,
155  void notify_if_complete(
156  const satcat5::ptp::Measurement* meas);
157 
158  // Handlers for specific incoming messages.
159  void rcvd_announce(
160  const satcat5::ptp::Header& hdr,
162  void rcvd_delay_req(
163  const satcat5::ptp::Header& hdr,
165  void rcvd_pdelay_req(
166  const Header& hdr,
168  void rcvd_delay_resp(
169  const satcat5::ptp::Header& hdr,
171  void rcvd_pdelay_resp(
172  const satcat5::ptp::Header& hdr,
174  void rcvd_follow_up(
175  const satcat5::ptp::Header& hdr,
177  void rcvd_pdelay_follow_up(
178  const satcat5::ptp::Header& hdr,
180  void rcvd_sync(
181  const satcat5::ptp::Header& hdr,
183  void rcvd_unexpected(
184  const satcat5::ptp::Header& hdr);
185 
186  // Create PTP message header of the given type.
187  satcat5::ptp::Header make_header(u8 type, u16 seq_id);
188 
189  // Generate and send specific outgoing messages.
190  bool send_announce();
191  bool send_sync(
192  satcat5::ptp::DispatchTo addr,
193  u16 seq_id, u16 flags = 0, u64 tref = 0);
194  bool send_sync_bcast();
195  bool send_follow_up(
196  satcat5::ptp::DispatchTo addr,
197  u16 seq_id, u16 flags = 0, u64 tref = 0);
198  void send_delay_req_sptp();
199  bool send_delay_req(u16 seq_id, u16 flags = 0);
200  bool send_delay_resp(const satcat5::ptp::Header& ref);
201  bool send_pdelay_req();
202  bool send_pdelay_resp(const satcat5::ptp::Header& ref);
203  bool send_pdelay_follow_up(const satcat5::ptp::Header& ref);
204 
205  // PTP dispatch object.
206  satcat5::ptp::Dispatch m_iface;
207 
208  // Bind to required PTP multicast addresses.
209  satcat5::igmp::Address m_mcast_primary;
210  satcat5::igmp::Address m_mcast_pdelay;
211 
212  // List of registered TLV handlers (see "ptp_tlv.h").
215 
216  // Other working state.
217  satcat5::ptp::ClientMode m_mode;
218  satcat5::ptp::ClientState m_state;
220  satcat5::ptp::ClockInfo m_clock_local;
221  satcat5::ptp::ClockInfo m_clock_remote;
222  satcat5::ptp::PortId m_current_source;
223  unsigned m_announce_count;
224  unsigned m_announce_every;
225  unsigned m_sync_count;
226  unsigned m_sync_every;
227  unsigned m_cache_wdog;
228  unsigned m_request_wdog;
229  int m_announce_rate;
230  int m_sync_rate;
231  int m_pdelay_rate;
232  u16 m_announce_id;
233  u16 m_sync_id;
234  u16 m_pdelay_id;
235  s16 m_utc_offset;
236  };
237 
243  public:
245  explicit SyncUnicastL2(satcat5::ptp::Client* client);
246 
248  inline void connect(const satcat5::eth::MacAddr& addr)
249  { m_dstmac = addr; }
250 
251  protected:
252  // Call inherited method timer_every(...) to set message rate.
253  void timer_event();
254 
255  satcat5::ptp::Client* const m_client;
256  satcat5::eth::MacAddr m_dstmac;
257  };
258 
262  public:
264  explicit SyncUnicastL3(satcat5::ptp::Client* client);
265 
267  inline void connect(const satcat5::ip::Addr& dstaddr)
268  { m_addr.connect(dstaddr); }
269 
271  inline void close()
272  { m_addr.close(); }
273 
274  protected:
275  // Call inherited method timer_every(...) to set message rate.
276  void timer_event();
277  satcat5::ptp::Client* const m_client;
278  satcat5::ip::Address m_addr;
279  };
280  }
281 }
Ephemeral Readable interface for a simple array.
Definition: io_readable.h:206
Limited read of next N bytes.
Definition: io_readable.h:255
Abstract API for writing byte-streams and packets.
Definition: io_writeable.h:24
Connection metadata for an IPv4 address.
Definition: ip_address.h:38
void connect(const satcat5::ip::Addr &dstaddr, const satcat5::eth::VlanTag &vtag=satcat5::eth::VTAG_NONE)
Automatic address resolution using routing table + ARP.
Definition: ip_address.cc:54
void close() override
Close any open connections and revert to idle.
Definition: ip_address.cc:108
Protocol handler and dispatch unit for Internet Protocol v4 (IPv4).
Definition: ip_dispatch.h:43
Timer objects are polled after a fixed delay or at a regular interval.
Definition: polling.h:213
Client for the IEEE 1588-2019 Precision Time Protocol (PTP)
Definition: ptp_client.h:67
satcat5::ip::Dispatch * get_iface() const
Mode and state accessors.
Definition: ptp_client.h:108
void set_utc_offset(s16 offset)
Immediately adjust the UTC vs.
Definition: ptp_client.h:102
satcat5::ptp::ClientState get_state() const
Mode and state accessors.
Definition: ptp_client.h:110
satcat5::ptp::ClockInfo get_clock() const
Get local clock information.
Definition: ptp_client.h:80
void timer_event() override
Child class MUST override this method.
Definition: ptp_client.cc:277
void set_announce_rate(int rate)
Set the ANNOUNCE message rate to 2^N / sec.
Definition: ptp_client.cc:187
void set_sync_rate(int rate)
Set the SYNC message rate to 2^N / sec.
Definition: ptp_client.cc:193
satcat5::ptp::ClockInfo get_remote() const
Get grandmaster clock information.
Definition: ptp_client.h:83
void set_pdelay_rate(int rate)
Set the pdelay message rate to 0.9 x 2^N / sec.
Definition: ptp_client.cc:199
satcat5::ptp::ClientMode get_mode() const
Mode and state accessors.
Definition: ptp_client.h:109
satcat5::ptp::PortId get_source() const
Mode and state accessors.
Definition: ptp_client.h:111
s16 get_utc_offset() const
Query the current UTC vs.
Definition: ptp_client.h:93
satcat5::ptp::Time get_time_now()
Read the current time from the network interface.
Definition: ptp_client.h:86
bool send_sync_unicast(const satcat5::eth::MacAddr &mac, const satcat5::ip::Addr &ip=satcat5::ip::ADDR_NONE, const satcat5::eth::VlanTag &vtag=satcat5::eth::VTAG_NONE)
Send a unicast SYNC message to the designated address.
Definition: ptp_client.cc:209
Client(satcat5::ptp::Interface *ptp_iface, satcat5::ip::Dispatch *ip_dispatch, satcat5::ptp::ClientMode mode=ClientMode::DISABLED)
Set the network interface for this client.
Definition: ptp_client.cc:113
void ptp_rcvd(satcat5::io::LimitedRead &rd)
Dispatch calls this method for each incoming packet.
Definition: ptp_client.cc:223
void set_mode(satcat5::ptp::ClientMode mode)
Mode and state accessors.
Definition: ptp_client.cc:154
void set_clock(const satcat5::ptp::ClockInfo &clk)
Set clock information for outgoing ANNOUNCE messages.
Definition: ptp_client.h:77
Dispatch and formatting for L2 and L3 PTP messages.
Definition: ptp_dispatch.h:46
satcat5::ptp::Time ptp_time_now()
Accessors for one-step and two-step timestamps.
Definition: ptp_dispatch.h:69
Generic API for network ports that support PTP.
Definition: ptp_interface.h:27
Searchable cache of recent Measurement objects.
A source for ptp::Measurement events, usually a ptp::Client.
Definition: ptp_source.h:19
Helper class for sending unicast Sync messages to an L2 client.
Definition: ptp_client.h:242
void connect(const satcat5::eth::MacAddr &addr)
Set the destination for outgoing SYNC messages.
Definition: ptp_client.h:248
void timer_event()
Child class MUST override this method.
Definition: ptp_client.cc:896
SyncUnicastL2(satcat5::ptp::Client *client)
Create this object.
Definition: ptp_client.cc:889
Helper class for sending unicast Sync messages to an L3 client.
Definition: ptp_client.h:261
SyncUnicastL3(satcat5::ptp::Client *client)
Create this object.
Definition: ptp_client.cc:902
void timer_event()
Child class MUST override this method.
Definition: ptp_client.cc:909
void close()
Close the connection to the remote client.
Definition: ptp_client.h:271
void connect(const satcat5::ip::Addr &dstaddr)
Set the destination for outgoing SYNC messages.
Definition: ptp_client.h:267
High-precision timestamp for use with PTP / IEEE1588.
Definition: ptp_time.h:41
Users should derive custom TLV objects from this base class.
Definition: ptp_tlv.h:111
Client-side implementation of the Internet Group Management Protocol (IGMP)
"Readable" I/O interface core definitions
Templated functions for manipulating singly-linked lists.
Core event-processing loop for SatCat5 software.
Define the data structure for a two-way time transfer handshake.
Define the API for generating ptp::Measurement events.
An Ethernet MAC address (with serializable interface).
Definition: eth_header.h:29
Header contents for an 802.1Q Virtual-LAN tag.
Definition: eth_header.h:124
Client state for an IGMP multicast subscription.
Definition: igmp_client.h:145
IPv4 address is a 32-bit unsigned integer.
Definition: ip_core.h:15
Clock configuration metadata for the ANNOUNCE message.
Definition: ptp_header.h:117
Struct representing the PTP header used for all message types.
Definition: ptp_header.h:46
Timestamps and metadata for a two-way time-transfer handshake.
Struct used for sourcePortIdentity and requestingPortIdentity.
Definition: ptp_header.h:17