gPTP Engine Design#
Overview#
The GptpEngine is the core protocol engine of TimeSlave. It implements the IEEE 802.1AS
gPTP slave clock functionality by managing two dedicated threads for network I/O and peer
delay measurement.
Class view#
Threading model#
The GptpEngine operates with two background threads:
RxThread#
The RxThread is the primary receive path. It runs a continuous loop:
Recv — Blocks on
IRawSocket::Recv()with a configurable timeout, receiving raw Ethernet frames with hardware timestamps from the NIC.Decode —
FrameCodec::ParseEthernetHeader()strips the Ethernet header (with VLAN support) and validates the EtherType (0x88F7).Parse —
MessageParser::Parse()decodes the PTP payload into aPTPMessagestructure, identifying the message type (Sync, FollowUp, PdelayResp, PdelayRespFollowUp).Dispatch — Based on message type:
Sync →
SyncStateMachine::OnSync()stores the Sync timestampFollowUp →
SyncStateMachine::OnFollowUp()correlates with the preceding Sync, computesoffset_nsandneighborRateRatio, and detects time jumpsPdelayResp →
PeerDelayMeasurer::OnResponse()PdelayRespFollowUp →
PeerDelayMeasurer::OnResponseFollowUp()
Snapshot — After processing, the latest
PtpTimeInfosnapshot is updated under mutex protection.
PdelayThread#
The PdelayThread performs IEEE 802.1AS peer delay measurement on a periodic interval
(configurable via GptpEngineOptions::pdelay_interval_ms):
Send —
PeerDelayMeasurer::SendRequest()transmits aPDelayReqframe via the raw socket, capturing the hardware transmit timestamp (t1).Receive — The RxThread dispatches incoming
PDelayResp(providingt2) andPDelayRespFollowUp(providingt3c) to thePeerDelayMeasurer.Compute — The peer delay is computed using the IEEE 802.1AS formula:
path_delay = ((t2 - t1) + (t4 - t3c)) / 2
where
t4is the local hardware receive timestamp of the PDelayResp frame.
Thread safety is ensured via a mutex in PeerDelayMeasurer, as SendRequest() runs on
the PdelayThread while OnResponse()/OnResponseFollowUp() are called from the
RxThread.
Core components#
FrameCodec#
Handles raw Ethernet frame encoding and decoding:
ParseEthernetHeader()— Parses source/destination MAC, handles 802.1Q VLAN tags, extracts EtherType and payload offset.AddEthernetHeader()— Constructs Ethernet headers for outgoing PDelayReq frames using the standard PTP multicast destination MAC (01:80:C2:00:00:0E).
MessageParser#
Parses the PTP wire format (IEEE 1588-v2) from raw payload bytes:
Validates the PTP header (version, domain, message length).
Decodes message-type-specific bodies:
SyncBody,FollowUpBody,PdelayReqBody,PdelayRespBody,PdelayRespFollowUpBody.All wire structures are packed (
__attribute__((packed))) for direct memory mapping.
SyncStateMachine#
Implements the two-step Sync/FollowUp correlation logic:
OnSync(msg) — Stores the Sync message and its hardware receive timestamp.
OnFollowUp(msg) — Matches with the preceding Sync by sequence ID, then computes:
offset_ns= master_time - slave_receive_time - path_delayneighborRateRatiofrom successive Sync intervals (master vs. slave clock progression)Time jump detection (forward/backward) against configurable thresholds
Timeout detection — Uses
std::atomic<bool>for thread-safe timeout status, set when no Sync is received withinsync_timeout_ms.
PeerDelayMeasurer#
Implements the IEEE 802.1AS two-step peer delay measurement protocol:
Manages the four timestamps (
t1,t2,t3c,t4) across two threads.SendRequest()— Builds and sends a PDelayReq frame, recordst1from the hardware transmit timestamp.OnResponse()/OnResponseFollowUp()— Recordst2,t3c,t4and computes the path delay when all timestamps are available.Returns
PDelayResultwithpath_delay_nsand avalidflag.
PhcAdjuster#
Synchronizes the PTP Hardware Clock (PHC) on the NIC:
Step correction — For large offsets exceeding
step_threshold_ns, applies an immediate time step to the PHC.Frequency slew — For smaller offsets, adjusts the clock frequency (in ppb) for smooth convergence.
Platform-specific: Linux uses
clock_adjtime(), QNX uses EMAC PTP ioctls.Configured via
PhcConfig(device path, step threshold, enable/disable flag).
Instrumentation#
ProbeManager#
A singleton that records probe events at key processing points. Probe points include:
RxPacketReceived— Raw frame received from socketSyncFrameParsed— Sync message successfully parsedFollowUpProcessed— Offset computed from Sync/FollowUp pairOffsetComputed— Final offset value availablePdelayReqSent— PDelayReq frame transmittedPdelayCompleted— Peer delay measurement completedPhcAdjusted— PHC adjustment applied
The GPTP_PROBE() macro provides zero-overhead when probing is disabled.
Recorder#
Thread-safe CSV file writer that persists probe events and other diagnostic data. Each
RecordEntry contains a timestamp, event type, offset, peer delay, sequence ID, and
status flags.
Configuration#
The GptpEngineOptions struct provides all configurable parameters:
Parameter |
Type |
Description |
|---|---|---|
|
string |
Network interface for gPTP frames (e.g., |
|
uint32_t |
Interval between PDelayReq transmissions |
|
uint32_t |
Timeout for Sync message reception before declaring timeout state |
|
int64_t |
Threshold for forward time jump detection |
|
int64_t |
Threshold for backward time jump detection |
|
PhcConfig |
PHC device path, step threshold, and enable flag |