220 lines
7.4 KiB
C++
220 lines
7.4 KiB
C++
#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 */
|