Files
eden-sim/contrib/tsn/model/gPTP.h

220 lines
7.4 KiB
C
Raw Normal View History

2025-12-01 15:56:02 +01:00
#ifndef GPTP_H
#define GPTP_H
#include "ns3/application.h"
#include "ns3/clock.h"
#include "ns3/tsn-net-device.h"
#include "ns3/gPTP-header.h"
#define NANOINSECOND 1000000000
namespace ns3
{
class GPTP : public Application
{
public:
/**
* \brief Get the type ID.
* \return the object TypeId
*/
static TypeId GetTypeId();
GPTP();
~GPTP() override;
/**
* Enumeration of the states of the PTP port.
*/
enum GPTPportState
{
MASTER,
SLAVE,
PASSIVE,
};
void SetMainClock(Ptr<Clock> c);
void AddDomain(uint8_t domainId);
void AddDomain(uint8_t domainId, Ptr<Clock> clock);
void AddPort(Ptr<TsnNetDevice> net, GPTPportState state, uint8_t domainId);
protected:
void DoDispose() override;
TracedCallback<Ptr<TsnNetDevice>,
double> m_NrTrace;
TracedCallback<Ptr<TsnNetDevice>,
double> m_PdelayTrace;
TracedCallback<Time> m_OffsetTrace;
TracedCallback<Time> m_ClockBeforeCorrectionTrace;
TracedCallback<Time> m_ClockAfterCorrectionTrace;
private:
struct syncPtrStruc
{
uint64_t correctionField = 0;
uint64_t sourceClockIndentity = 0;
uint16_t sourcePortIndentity = 0;
uint16_t sequenceId = 0;
uint64_t preciseOriginTimestampSecond = 0;
uint32_t preciseOriginTimestampNanoSecond = 0;
uint64_t syncOriginTimestampSecond = 0;
uint32_t syncOriginTimestampNanoSecond = 0;
uint64_t pktUid = 0;
bool pktSent = false;
uint64_t syncReceiptTimestampSecond = 0;
uint32_t syncReceiptTimestampNanoSecond = 0;
uint32_t cumulativeScaledRateOffset = 0;
};
struct pdelayReqPtrStruc
{
uint64_t correctionField = 0;
uint64_t sourceClockIndentity = 0;
uint16_t sourcePortIndentity = 0;
uint16_t sequenceId = 0;
uint64_t requestOriginTimestampSecond = 0;
uint32_t requestOriginTimestampNanoSecond = 0;
uint64_t pktUid = 0;
bool pktSent = false;
};
struct pdelayRespStruc
{
uint64_t correctionField = 0;
uint64_t sourceClockIndentity = 0;
uint16_t sourcePortIndentity = 0;
uint16_t sequenceId = 0;
uint64_t requestReceiptTimestampSecond = 0;
uint32_t requestReceiptTimestampNanoSecond = 0;
uint64_t requestingClockIdentity = 0;
uint16_t requestingPortIdentity = 0;
uint64_t responseReceiptTimestampSecond = 0;
uint32_t responseReceiptTimestampNanoSecond = 0;
uint64_t pktUid = 0;
bool pktSent = false;
};
struct pdelayRespFollowUpStruc
{
uint64_t correctionField = 0;
uint64_t sourceClockIndentity = 0;
uint16_t sourcePortIndentity = 0;
uint16_t sequenceId = 0;
uint64_t responseOriginTimestampSecond = 0;
uint32_t responseOriginTimestampNanoSecond = 0;
uint64_t requestingClockIdentity = 0;
uint16_t requestingPortIdentity = 0;
};
struct GPTPPortPerDomainStruc
{
uint8_t domainId;
GPTPportState state;
syncPtrStruc syncPtr;
};
/**
* \ingroup tsn
* Structure holding port, there states and the PTPinstance datas.
*/
struct GPTPPort
{
Ptr<TsnNetDevice> net;
std::vector<GPTPPortPerDomainStruc> domains = {};
bool rcvdPdelayResp = false; //STD 802.1AS-2020 : 11.2.19.2.2
pdelayRespStruc rcvdPdelayRespPtr; //STD 802.1AS-2020 : 11.2.19.2.3
bool rcvdPdelayRespFollowUp = false; //STD 802.1AS-2020 : 11.2.19.2.4
pdelayRespFollowUpStruc rcvdPdelayRespFollowUpPtr; //STD 802.1AS-2020 : 11.2.19.2.5
pdelayReqPtrStruc txPdelayReqPtr; //STD 802.1AS-2020 : 11.2.19.2.6
uint16_t lostResponses; //STD 802.1AS-2020 : 11.2.19.2.9
bool neighborRateRatioValid = false; //STD 802.1AS-2020 : 11.2.19.2.10
pdelayRespStruc txPdelayRespPtr;
Time t3_prime = Time(0);
Time t4_prime = Time(0);
double neighborRateRatio = 1;
double meanLinkDelay = 0;
bool asCapableAcrossDomains = false;
};
struct domainStruc
{
uint8_t domainId;
Ptr<Clock> clock;
};
void StartApplication() override;
void StopApplication() override;
void StartPdelayMechanism();
void StartSyncDistributionMechanism(uint8_t domainId);
bool RXCallback(Ptr<TsnNetDevice> dev, Ptr<const Packet> pkt, uint16_t mode, const Address& sender, Time rxTimestamp);
bool TXCallback(Ptr<const Packet> pkt, Time txTimestamp);
void SendSync(uint8_t domainId);
void SendFollowUp(GPTPPort port, uint16_t portId, uint8_t id);
void SendPdelayRequest(GPTPPort port, uint16_t portId);
void SendPdelayResp(Ptr<TsnNetDevice> dev, GptpHeader rxHeader, Time rxTimestamp);
void SendPdelayRespFup(Ptr<TsnNetDevice> dev, Time txTimestamp);
void handleSync(Ptr<TsnNetDevice> dev, GptpHeader header, Ptr<Packet> pkt, Time rxTimestamp);
void handleFollowUp(Ptr<TsnNetDevice> dev, GptpHeader header, Ptr<Packet> pkt, Time rxTimestamp);
void handlePdelayResp(Ptr<TsnNetDevice> dev, GptpHeader header, Ptr<Packet> pkt, Time rxTimestamp);
void handlePdelayRespFup(Ptr<TsnNetDevice> dev, GptpHeader header, Ptr<Packet> pkt);
void ResetPdelay(uint16_t portId);
double computePdelayRateRatio(uint16_t portId); //STD 802.1AS-2020 : 11.2.19.3.2
double computePropTime(uint16_t portId); //STD 802.1AS-2020 : 11.2.19.3.3
Time computeOffset(uint16_t portId, uint16_t id, double r);
uint16_t GetPortIdFromNetDev(Ptr<TsnNetDevice> dev);
int GetDomainKeyFromNetDev(Ptr<TsnNetDevice> dev, uint16_t portId, uint8_t domainId);
Ptr<Clock> getClockFromDomainId(uint8_t domainId);
bool IsGm(uint8_t domainId);
void readPledayPayload(uint8_t* payload, uint64_t& timestampSecond, uint32_t& timestampNanoSecond, uint64_t& clockIdentity, uint16_t& portIdentity);
void readFollowUpPayload(uint8_t* payload, uint64_t& timestampSecond, uint32_t& timestampNanoSecond, uint32_t& cumulativeScaledRateOffset);
uint16_t m_pdelaySequenceId = 0;
double m_meanLinkDelayThresh = 800;
Ptr<Clock> m_mainClock = nullptr;
uint64_t m_baseClockIndentity;
Time m_pdelayInterval;
Time m_syncInterval;
uint8_t m_priority;
std::vector<domainStruc> m_domains = {};
const Mac48Address GPTP_MULTICASTMAC = Mac48Address("01:80:C2:00:00:0E");
static const uint16_t GPTP_ETHERTYPE = 0x88F7;
static const uint8_t MESSAGETYPE_SYNC = 0; //STD 802.1AS-2020 : Table 11-5
static const uint8_t MESSAGETYPE_PDELAYREQ = 2; //STD 802.1AS-2020 : Table 11-5
static const uint8_t MESSAGETYPE_PDELAYRESP = 3; //STD 802.1AS-2020 : Table 11-5
static const uint8_t MESSAGETYPE_FOLLOWUP = 8; //STD 802.1AS-2020 : Table 11-5
static const uint8_t MESSAGETYPE_PDELAYRESPFOLLOWUP = 10; //STD 802.1AS-2020 : Table 11-5
EventId m_pdelayReqTxEvent;
EventId m_syncTxEvent;
std::vector<GPTPPort> m_ports;
Time m_pktProcessingTime = Time(MicroSeconds(20));
Time m_TimestampProcessingTime = Time(MicroSeconds(20));
};
} // namespace ns3
#endif /* GPTP_H */